Open
      
        Bug 1297179
      
      
        Opened 9 years ago
          Updated 3 years ago
      
        
    
  
ES Proxies should use realm from caller context
Categories
(Core :: JavaScript Engine, defect, P3)
        Core
          
        
        
      
        
    
        JavaScript Engine
          
        
        
      
        
    Tracking
()
        NEW
        
        
    
  
| Tracking | Status | |
|---|---|---|
| firefox51 | --- | affected | 
People
(Reporter: anba, Unassigned)
References
(Blocks 1 open bug)
Details
(Keywords: triage-deferred)
Test case:
---
var g = newGlobal();
var {proxy, revoke} = g.eval(`Proxy.revocable(() => {}, {})`);
revoke();
var err;
try {
    proxy();
} catch (e) {
    err = e;
}
assertEq(err instanceof TypeError, true);
---
Expected: The assertEq call succeeds
Actual: The assertEq call fails
Proxy MOP methods don't create a new execution context, which means they simply reuse the current execution context, so step 2 in [1] throws a TypeError from the caller realm and not from the proxy's realm.
[1] https://tc39.github.io/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-call-thisargument-argumentslist
It's even possible to extend the test case using bound functions:
---
var g = newGlobal();
var {proxy, revoke} = g.eval(`Proxy.revocable(() => {}, {})`);
var g2 = newGlobal();
var bf = g2.Function.prototype.bind.call(proxy);
revoke();
var err;
try {
    bf();
} catch (e) {
    err = e;
}
assertEq(err instanceof TypeError, true);
---
Same deal in this case: Proxy MOP methods don't create a new execution context, and neither do bound function objects [2]. So the thrown TypeError is also from the original caller realm. 
[2] https://tc39.github.io/ecma262/#sec-bound-function-exotic-objects-call-thisargument-argumentslist
| Comment 1•8 years ago
           | ||
I do not dispute that this is what the current spec says. But if so, then the spec implies (shudder) dynamic scoping and must be fixed. The execution context must be a "lexically" captured part of the thing executing, not an additional hidden implicit parameter passed to it by its caller. In such hidden unreifiable parameters, madness lies.
This is indeed and interesting case, but I think the current spec. is probably right and hence this is indeed a SpiderMonkey implementation bug.
First regarding "dynamic scoping". That's not the case if you consider that the runtime operation that is trying to operate upon the proxy object (really any object) is part of the calling function. The fact that the operation in this case is a function invocation is just obscuring that fact.  So, let's think about a simpler MOP operation such as [[Set]].  For a proxy, the first fhree steps of [[Set]] (or any MOP operation) are exactly the same as for [[Call]] and concludes with a conditional throw of a TypeError.  So,  what Realm is available for accessing TypeError when [[Set]] is performed using a revoked proxy? There is no longer a target object or a collection of trap handler functions that could potentially supply a Realm (or otherwise be used to create a new execution context).  The only realm available for looking up TypeError is the realm of the current execution context. (keep in mind that in the ES spec, only functon objects have a "lexical" realm association). 
Another way to look at this that gets us to the same point is the second paragraph of https://tc39.github.io/ecma262/#sec-object-internal-methods-and-internal-slots which says "If, at runtime, the implementation of an algorithm attempts to use an internal method of an object that the object does not support, a TypeError exception is thrown." Implicitly, this means the TypeError of the active execution context that is performing the abstract operation. A revoked proxy is essentially an object that does not support any internal methods so throwing TypeError from the realm of the current execution context is consistent with this requirement.
| Updated•8 years ago
           | 
Keywords: triage-deferred
Priority: -- → P3
| Updated•3 years ago
           | 
Severity: normal → S3
          You need to log in
          before you can comment on or make changes to this bug.
        
Description
•