Closed Bug 1286997 Opened 8 years ago Closed 3 years ago

Compound assignment calls ToPropertyKey before RequireObjectCoercible

Categories

(Core :: JavaScript Engine, defect, P3)

defect

Tracking

()

RESOLVED INVALID

People

(Reporter: bakkot, Assigned: yulia)

References

(Blocks 1 open bug)

Details

(Keywords: triage-deferred)

Attachments

(3 files, 7 obsolete files)

47 bytes, text/x-phabricator-request
Details | Review
47 bytes, text/x-phabricator-request
Details | Review
47 bytes, text/x-phabricator-request
Details | Review
User Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36

Steps to reproduce:

null[{ toString:()=>{throw 'not reached';} }] += 0


Actual results:

uncaught exception: not reached


Expected results:

TypeError.

12.3.2.1 of the spec specifies that the receiver is ensured to be object-coercible before the name is converted to a string.

I suspect this was introduced in https://bugzilla.mozilla.org/show_bug.cgi?id=1260577 . I'd cc :efaust if I were more familiar with Bugzilla.
Blocks: test262
Keywords: triage-deferred
Priority: -- → P3
Assignee: nobody → ystartsev
Status: NEW → ASSIGNED
Keywords: leave-open

There's an open spec issue about this type of bugs: https://github.com/tc39/ecma262/issues/467

Basically we never invested time to implement the exact spec algorithms, because it leads to regressions (bloats byte code; worse error messages). And the spec was never changed to follow the implementations, because it requires reworking the Reference type (and some folks still prefer strict left-to-right evaluation).

Those two reasons: bloats byte code and worse error messages, sounds like a good reason to change the spec. I understand that this might take some spec work, but since this is part of the stream this might be interesting for people to see. Is it worth the time investment to change the spec?

It'd be easier to convince TC39 to change the spec if implementations all had the exact same semantics, but they're also all slightly different. :-/


Just to expand on "bloats byte code and worse error messages", for dis(function(o, p, v){ o[p] = v }), we're currently emitting

GetArg 0                        # o
GetArg 1                        # o p
GetArg 2                        # o p v
SetElem                         # o[p]

which has the minimum number of operations.

Per spec and with our current set of byte code operations, we'd need to emit:

GetArg 0                        # o
GetArg 1                        # o p
Swap                            # p o
CheckObjCoercible               # p o
Swap                            # o p
ToPropertyKey                   # o p
GetArg 2                        # o p v
SetElem                         # o[p]

which doubles the amount of byte code operations, so that's not really acceptable. Furthermore CheckObjCoercible will report TypeError: null has no properties when o == null, whereas we're currently reporting TypeError: can't access property 0, o is null. The less informative error message is already today visible:

js> null[0]++
typein:1:1 TypeError: null has no properties
Stack:
  @typein:1:1
js> null[0]+=1
typein:2:1 TypeError: can't access property 0 of null
Stack:
  @typein:2:1

To reduce the byte code bloat and also still report a proper error message, we'd need to add a new operation which combines CheckObjCoercible and ToPropertyKey:

GetArg 0                        # o
GetArg 1                        # o p
PrepareSetElem                  # o p
GetArg 2                        # o p v
SetElem                         # o[p]

But that's still a 25% increase in the number of byte code operations.

I have the worst ideas for optimization

Depends on D86232

Attachment #9176565 - Attachment is obsolete: true
Attachment #9176566 - Attachment is obsolete: true
Attachment #9168523 - Attachment is obsolete: true
Attachment #9168524 - Attachment is obsolete: true
Attachment #9168526 - Attachment is obsolete: true
Attachment #9168527 - Attachment is obsolete: true
Attachment #9168739 - Attachment is obsolete: true

The leave-open keyword is there and there is no activity for 6 months.
:ystartsev, maybe it's time to close this bug?

Flags: needinfo?(ystartsev)

This has been addressed within the spec iirc (https://github.com/tc39/ecma262/pull/2267), so we can close this.

Status: ASSIGNED → RESOLVED
Closed: 3 years ago
Flags: needinfo?(ystartsev)
Resolution: --- → INVALID
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: