Closed Bug 1760844 Opened 3 years ago Closed 3 years ago

Consider removing hasInstance proxy trap

Categories

(Core :: JavaScript Engine, task, P1)

task

Tracking

()

RESOLVED FIXED
101 Branch
Tracking Status
firefox101 --- fixed

People

(Reporter: jandem, Assigned: jandem)

References

(Blocks 1 open bug)

Details

Attachments

(2 files, 1 obsolete file)

Bug 1270746 removed the hasInstance JSClass hook, but we still have the non-standard hasInstance proxy trap. This trap makes it harder to optimize instanceof, because it means we can't easily desugar instanceof in the bytecode emitter for example.

The attached WIP patch is mostly green on try, but it exposes an issue with Xray waivers.

The behavior implemented in bug 1504660 is that xrayWrapper instanceof Cu.waiveXrays(..) returns false.

If we remove the hasInstance proxy trap, this changes: we now look up Symbol.hasInstance on the RHS object (the waiver) and call the hasInstance function that returns. See the changes to test_xray_instanceof.js in the WIP patch (I only made the changes necessary to make the test pass).

bholley/robwu: I see there was a lot of discussion in bug 1504660. Do you have any thoughts on this? Is a change in behavior here acceptable?

Flags: needinfo?(rob)
Flags: needinfo?(bholley)

I think it's acceptable. IIRC the problem we were trying to solve that |RHS instanceof LHS| could enter the compartment of LHS even if LHS was an XRayWrapper (to a scripted proxy). Entering the compartment is a more reasonable thing to do if RHS is a waiver. I don't fully recall why we made the waiver instanceof behavior match the Xray instanceof behavior in this case, but I suspect it was just easier to implement.

Rob, does that sound right to you?

Note that you'll also want to update the strings in the relevant tests.

Flags: needinfo?(bholley)

The new behavior is reasonable, but the messages that describe the test expectations should be updated to match the new behavior.

The original patch was meant to handle the scenario described at https://bugzilla.mozilla.org/show_bug.cgi?id=1504660#c14.

I implemented the current behavior because I had to choose a behavior, and evaluating to false is a safe default choice for mismatching wrappers.
One could argue that if the RHS is a waived XrayWrapper (in LHS instanceof RHS), that it's fine to trigger the underlying proxy traps if any. Anyone who expected sane behavior shouldn't have waived Xrays on the RHS.

With the proposed change here, I think that you can also undo the change here: https://hg.mozilla.org/mozilla-central/rev/c50c098e40c4#l9.1

Flags: needinfo?(rob)

This removes the non-standard hasInstance proxy trap.

All objects will now use the algorithm in JS::InstanceofOperator. That function
uses other primitives and proxy traps already available to JS code.

As discussed in the bug, there's a minor difference in behavior: for
xrayWrapper instanceof xrayWaiver we used to always return false but we can now
invoke xrayWaiver[Symbol.hasInstance]().

Assignee: nobody → jdemooij
Status: NEW → ASSIGNED
  • js::HasInstance now always forwards to JS::InstanceofOperator so call the latter directly.
  • Move InstanceofOperator to the js namespace and remove it from the API (JS_HasInstance already exists).

Depends on D142061

Attachment #9268926 - Attachment is obsolete: true
Priority: -- → P1
Pushed by jdemooij@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/34f5687c0372 part 1 - Remove hasInstance proxy trap. r=iain,peterv,robwu https://hg.mozilla.org/integration/autoland/rev/ff1e54abeb67 part 2 - Tidy up InstanceofOperator and HasInstance. r=iain
Status: ASSIGNED → RESOLVED
Closed: 3 years ago
Resolution: --- → FIXED
Target Milestone: --- → 101 Branch
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: