Open Bug 1166408 Opened 9 years ago Updated 2 years ago

Additional [[HasProperty]] call when checking object environment binding in call expression

Categories

(Core :: JavaScript Engine, defect)

defect

Tracking

()

Tracking Status
firefox41 --- affected

People

(Reporter: anba, Unassigned)

References

(Blocks 1 open bug)

Details

The HasBinding concrete method of the object environment record should only be called once in the following example, but it seems to be called twice. 


Expected output:
  trap:has
  has:Object

Actual output:
  trap:has
  has:Object
  trap:has
  has:Object

Test case:
---
with (new Proxy({}, new Proxy({
  has(t, pk) {
    print(`has:${String(pk)}`);
    return pk in t;
  }
}, {
  get(t, pk, r){
    print(`trap:${pk}`);
    return t[pk];
  }
}))) {
 Object();
}
---
Test case without proxies:
---
var outer = {method: true};
var inner = {
  get method() {
    delete this.method;
    return function() {
      assertEq(this, inner);
    };
  }
};
with (outer) with (inner) method("hello");
---

I guess this bug is caused by the |implicitthis| opcode.
Blocks: es6
Shu wants to take a look at this.
Flags: needinfo?(shu)
Flags: needinfo?(shu)

Actual bytecode for the method call in with (obj) { method(); }:

getname "method"        # method
implicitthis "method"   # method obj
call-ignores-rv 0       # result

The correct bytecode would have to be more like:

bindname "method"       # env
dup                     # env env
getboundname "method"   # env method
swap                    # method env
with-base-object        # method this
call-ignores-rv 0       # result

where JSOP_WITH_BASE_OBJECT is a replacement for JSOP_IMPLICITTHIS that implements the WithBaseObject method that EnvironmentRecords have in the spec: it always pushes undefined, unless the argument env is a WithEnvironmentObject (or, for us, a DebugEnvironmentProxy wrapping a WithEnvironmentObject). In that case it pushes the object.

Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.