Open mhofman opened 2 years ago
Let's discuss this next week at SES meeting. @erights and @nicolo-ribaudo might have opinions here as well.
Tomorrow's there is no SES meeting due to TG3. I've put it on the agenda for 2024-02-21.
We discussed this during today's SES meeting -- we didn't come to a conclusion, but there were to points in favor of the two different options.
To recap, the observable difference is that realm.evaluate("var foo = 1")
would create a global configurable property under PerformEval
semantics, and a global non-configurable property under ScriptEvaluation
semantics.
PerformEval
has the advantage that usually code written assuming a non-configurable property will also work if that property is configurable, while the other way around would break.ScriptEvaluation
has the advantage that today the majority of script code is being executed through <script>
tags and not through eval()
, so it matches the most common way of running code.In addition to this, @mhofman notes that const evaluate = shadowRealm.executeScript('eval')
doesn't actually work when considering TrustedTypes, because that eval
would be behind the callable boundary and thus it can only accept strings (while shadowRealm.executeScript(trustedTypesObject)
would work).
Also, I realized that there is another difference we didn't explicitly talk about during the SES meeting (but maybe it's a consequence of the configurability of properties). The following code:
realm.evaluate("var a = 1");
realm.evaluate("let a = 2");
will work under PerformEval
semantics, and throw under ScriptEvaluation
semantics.
Test cases:
<!-- ScriptEvaluation -->
<script>var a = 1;</script>
<script>let a = 2;</script>
<!-- PerformEval -->
<script>
eval("var a = 1;");
eval("let a = 1;");
</script>
I think more relevant is that
<!-- ScriptEvaluation -->
<script>let a = 1;</script>
<script>let b = a + 1;</script>
Does work as well, and that there is no way to do this with eval
It looks like
PerformShadowRealmEval
is based offPerformEval
, which means there is no way to have theScriptEvaluation
semantics in ShadowRealms, namely the behavior ofGlobalDeclarationInstantiation
to create global object properties forvar
andfunction
declarations.I'm wondering if this option was ever discussed. While it'd be easy to add a new API later (e.g.
ShadowRealm.prototype.executeScript()
) with theScriptEvaluation
semantics, I also don't think there'd be harm in changing the semantics ofPerformShadowRealmEval
before shipping. It's always possible to go fromScriptEvaluation
toPerformEval
(const evaluate = shadowRealm.executeScript('eval')
), but not the other way around.