Closed legendecas closed 2 years ago
Thanks, @legendecas!
Let me put this clear: I really appreciate the througout review you've been doing and the many PRs here. This PR is a bit confusing, I'm not sure it helps clarifying anything and I believe either the current draft or the proposed change from this PR will go through the editors review when we make the PR to ECMA-262.
Let's give a check with some other champions about this PR. cc @caridy @erights @rwaldron WDYT?
@leobalter the item I'm trying to clarify is in which realm are the errors created in GetWrappedValue
in WrappedFunction.[[Call]]
.
For example, in realmA:
const shadowRealm = new ShadowRealm()
const wrappedFunction = shadowRealm.eval('() => ({})')
Then we call the wrappedFunction
in realmB:
wrappedFunction({}) // call the wrapped function with un-wrappable value
// => TypeError from realmA or realmB?
For function objects, the spec handles the call in following steps:
F.[[Call]]
,And at this step the javascript functions takes a different spec steps from the WrappedFunction
. They should goes https://tc39.es/ecma262/#sec-ecmascript-function-objects-call-thisargument-argumentslist:
NOTE: Any exception objects produced after this point are associated with calleeRealm.
in step 13 of 10.2.1.1,But for WrappedFunction.[[Call]]
, there is only one such clarification on https://tc39.es/proposal-shadowrealm/#sec-wrapped-function-exotic-objects-call-thisargument-argumentslist: step 10.a. And for GetWrappedValue
of steps 6.a and step 7, there is no such clarification for that. So the TypeError created on step 2.a of GetWrappedValue
, I'd assume it is created in the realm of the current execution context, which can differ each time when the WrappedFunction
is been called. However, if I understand correctly, this should not be the expected behavior since it acts like dynamic scoping.
I don't think the current specification is unclear at all.
Then we call the wrappedFunction in realmB:
wrappedFunction({}) // call the wrapped function with un-wrappable value // => TypeError from realmA or realmB?
The validation of the arguments list occurs in the parent realm, not the child realm, which is what the current proposal spec describes at [[Call]] ( thisArgument, argumentsList ) Step 6.a.
// Realm A
const wrappedFunction = (new ShadowRealm()).eval(`
// Realm B
() => ({})
`);
// evaluation occurs in Realm A
wrappedFunction({}); // Throws a Realm A TypeError
After Step 8. Let result be the Completion Record of Call(target, wrappedThisArgument, wrappedArgs), the outcome of some operations executed in Realm B are stored in result
, and if the completions are not "normal" or "return", then the exception must be attributed Realm B (step 10.a), because that's where it occurred.
@rwaldron I'm afraid I'm not clear about the term realm
references here.
For example, in realmA:
const shadowRealm = new ShadowRealm() const wrappedFunction = shadowRealm.eval('() => ({})')
Then we call the wrappedFunction in realmB:
wrappedFunction({}) // call the wrapped function with un-wrappable value // => TypeError from realmA or realmB?
The realms involving in these examples are:
$262.createRealm
.So when the wrappedFunction
is been called in realmB
, an arbitrary realm, the TypeError for validation of argument list or validation of result in current spec is created in realmB
. This is the topic I'm trying to clarify with the PR.
Ok, I see now. I apologize: I thought were were discussing strictly shadow realms interactions. In that case, your changes actually make complete sense!
you're on roll, @legendecas, thank you!
GetWrappedValue
may throw TypeError when the value been wrapped is an object but not callable. WrappedFunctions may be called outside of the creation realm. This PR makes it clear that stepGetWrappedValue
inWrappedFunction.[[Call]]
should throw a TypeError associated with thecallerRealm
but not the current realm.WrappedFunction
is the only place in the proposal spec that defines exotic[[Call]]
and should clarify the throwing realm.