Skip to content

Commit

Permalink
sebastienros#1573 - implemented convenience methods for shadowrealm
Browse files Browse the repository at this point in the history
  • Loading branch information
gentledepp committed Aug 22, 2023
1 parent 1852e81 commit 657e64c
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 2 deletions.
55 changes: 53 additions & 2 deletions Jint.Tests.PublicInterface/ShadowRealmTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public void CanUseViaEngineMethods()
}

[Fact]
public void CanUseGlobalsDefinedInEngine()
public void MultipleShadowRealmsDoNotInterfere()
{
var engine = new Engine(options => options.EnableModules(GetBasePath()));
engine.SetValue("message", "world");
Expand All @@ -39,7 +39,58 @@ public void CanUseGlobalsDefinedInEngine()
Assert.Equal("world",engine.Evaluate("hello();"));

var shadowRealm = engine.Realm.Intrinsics.ShadowRealm.Construct();
Assert.Equal("world", shadowRealm.Evaluate("hello();"));
shadowRealm.SetValue("message", "realm 1");
shadowRealm.Evaluate("function hello() {return message}");

var shadowRealm2 = engine.Realm.Intrinsics.ShadowRealm.Construct();
shadowRealm2.SetValue("message", "realm 2");
shadowRealm2.Evaluate("function hello() {return message}");

// Act & Assert
Assert.Equal("realm 1", shadowRealm.Evaluate("hello();"));
Assert.Equal("realm 2", shadowRealm2.Evaluate("hello();"));
}

[Fact]
public void MultipleShadowRealm_SettingGlobalVariable_DoNotInterfere()
{
var engine = new Engine(options => options.EnableModules(GetBasePath()));
engine.SetValue("message", "hello ");
engine.Evaluate("(function hello() {message += \"engine\"})();");

var shadowRealm = engine.Realm.Intrinsics.ShadowRealm.Construct();
shadowRealm.SetValue("message", "hello ");
shadowRealm.Evaluate("(function hello() {message += \"realm 1\"})();");

var shadowRealm2 = engine.Realm.Intrinsics.ShadowRealm.Construct();
shadowRealm2.SetValue("message", "hello ");
shadowRealm2.Evaluate("(function hello() {message += \"realm 2\"})();");

// Act & Assert
Assert.Equal("hello engine", engine.Evaluate("message"));
Assert.Equal("hello realm 1", shadowRealm.Evaluate("message"));
Assert.Equal("hello realm 2", shadowRealm2.Evaluate("message"));
}

[Fact]
public void CanReuseScriptWithShadowRealm()
{
var engine = new Engine(options => options.EnableModules(GetBasePath()));
engine.SetValue("message", "engine");

var shadowRealm = engine.Realm.Intrinsics.ShadowRealm.Construct();
shadowRealm.SetValue("message", "realm 1");

var shadowRealm2 = engine.Realm.Intrinsics.ShadowRealm.Construct();
shadowRealm2.SetValue("message", "realm 2");

var parser = new Esprima.JavaScriptParser();
var script = parser.ParseScript("(function hello() {return \"hello \" + message})();");

// Act & Assert
Assert.Equal("hello engine", engine.Evaluate(script));
Assert.Equal("hello realm 1", shadowRealm.Evaluate(script));
Assert.Equal("hello realm 2", shadowRealm2.Evaluate(script));
}

private static string GetBasePath()
Expand Down
23 changes: 23 additions & 0 deletions Jint/Native/ShadowRealm/ShadowRealm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ public JsValue Evaluate(string sourceText)
return PerformShadowRealmEval(sourceText, callerRealm);
}

public JsValue Evaluate(Script script)
{
var callerRealm = _engine.Realm;
return PerformShadowRealmEval(script, callerRealm);
}

public JsValue ImportValue(string specifier, string exportName)
{
var callerRealm = _engine.Realm;
Expand Down Expand Up @@ -83,6 +89,7 @@ public ShadowRealm SetValue(string name, object obj)
return SetValue(name, value);
}


/// <summary>
/// https://tc39.es/proposal-shadowrealm/#sec-performshadowrealmeval
/// </summary>
Expand Down Expand Up @@ -111,6 +118,22 @@ internal JsValue PerformShadowRealmEval(string sourceText, Realm callerRealm)
return default;
}

return PerformShadowRealmEvalInternal(script, callerRealm);
}

internal JsValue PerformShadowRealmEval(Script script, Realm callerRealm)
{
var evalRealm = _shadowRealm;

_engine._host.EnsureCanCompileStrings(callerRealm, evalRealm);

return PerformShadowRealmEvalInternal(script, callerRealm);
}

internal JsValue PerformShadowRealmEvalInternal(Script script, Realm callerRealm)
{
var evalRealm = _shadowRealm;

ref readonly var body = ref script.Body;
if (body.Count == 0)
{
Expand Down

0 comments on commit 657e64c

Please sign in to comment.