diff --git a/Jint.Tests.PublicInterface/ConstructorTests.cs b/Jint.Tests.PublicInterface/ConstructorTests.cs index c296bbf227..610aea03d3 100644 --- a/Jint.Tests.PublicInterface/ConstructorTests.cs +++ b/Jint.Tests.PublicInterface/ConstructorTests.cs @@ -79,17 +79,17 @@ public override ObjectInstance Construct(JsValue[] arguments, JsValue newTarget) var day = arguments.Length == 2 ? 0 : TypeConverter.ToNumber(arguments[2]) - 1; if (double.IsNaN(year)) { - throw new JavaScriptException(_engine.Realm.Intrinsics.TypeError, $"Invalid year {year.ToString(CultureInfo.InvariantCulture)}"); + throw new JavaScriptException(_engine.Intrinsics.TypeError, $"Invalid year {year.ToString(CultureInfo.InvariantCulture)}"); } if (double.IsNaN(month)) { - throw new JavaScriptException(_engine.Realm.Intrinsics.TypeError, $"Invalid month {month.ToString(CultureInfo.InvariantCulture)}"); + throw new JavaScriptException(_engine.Intrinsics.TypeError, $"Invalid month {month.ToString(CultureInfo.InvariantCulture)}"); } if (double.IsNaN(day)) { - throw new JavaScriptException(_engine.Realm.Intrinsics.TypeError, $"Invalid day {day.ToString(CultureInfo.InvariantCulture)}"); + throw new JavaScriptException(_engine.Intrinsics.TypeError, $"Invalid day {day.ToString(CultureInfo.InvariantCulture)}"); } var dt = new DateTime((int) year, 1, 1); diff --git a/Jint.Tests.PublicInterface/JavaScriptExceptionTests.cs b/Jint.Tests.PublicInterface/JavaScriptExceptionTests.cs index b54f6cdf0d..9ea9c1ba0b 100644 --- a/Jint.Tests.PublicInterface/JavaScriptExceptionTests.cs +++ b/Jint.Tests.PublicInterface/JavaScriptExceptionTests.cs @@ -13,7 +13,7 @@ public void CanCreateAndThrowJavaScriptException() engine.SetValue("throw1", () => { - throw new JavaScriptException(engine.Realm.Intrinsics.Error, "message 1"); + throw new JavaScriptException(engine.Intrinsics.Error, "message 1"); }); engine.SetValue("throw2", () => diff --git a/Jint.Tests.PublicInterface/PublicInterfaceTests.cs b/Jint.Tests.PublicInterface/PublicInterfaceTests.cs index 6fc3bd96c6..3dca962912 100644 --- a/Jint.Tests.PublicInterface/PublicInterfaceTests.cs +++ b/Jint.Tests.PublicInterface/PublicInterfaceTests.cs @@ -6,6 +6,14 @@ namespace Jint.Tests.PublicInterface; public class PublicInterfaceTests { + [Fact] + public void CanCallEval() + { + var engine = new Engine(); + var value = engine.Intrinsics.Eval.Call("1 + 1"); + Assert.Equal(2, value); + } + [Fact] public void BindFunctionInstancesArePublic() { diff --git a/Jint.Tests.PublicInterface/ShadowRealmTests.cs b/Jint.Tests.PublicInterface/ShadowRealmTests.cs index 9c7f7ba2ff..60a85cbe54 100644 --- a/Jint.Tests.PublicInterface/ShadowRealmTests.cs +++ b/Jint.Tests.PublicInterface/ShadowRealmTests.cs @@ -8,7 +8,7 @@ public class ShadowRealmTests public void CanUseViaEngineMethods() { var engine = new Engine(options => options.EnableModules(GetBasePath())); - var shadowRealm = engine.Realm.Intrinsics.ShadowRealm.Construct(); + var shadowRealm = engine.Intrinsics.ShadowRealm.Construct(); // lexically scoped (let/const) are visible during single call Assert.Equal(123, shadowRealm.Evaluate("const s = 123; const f = () => s; f();")); @@ -37,11 +37,11 @@ public void MultipleShadowRealmsDoNotInterfere() Assert.Equal("world", engine.Evaluate("hello();")); - var shadowRealm = engine.Realm.Intrinsics.ShadowRealm.Construct(); + var shadowRealm = engine.Intrinsics.ShadowRealm.Construct(); shadowRealm.SetValue("message", "realm 1"); shadowRealm.Evaluate("function hello() {return message}"); - var shadowRealm2 = engine.Realm.Intrinsics.ShadowRealm.Construct(); + var shadowRealm2 = engine.Intrinsics.ShadowRealm.Construct(); shadowRealm2.SetValue("message", "realm 2"); shadowRealm2.Evaluate("function hello() {return message}"); @@ -57,11 +57,11 @@ public void MultipleShadowRealm_SettingGlobalVariable_DoNotInterfere() engine.SetValue("message", "hello "); engine.Evaluate("(function hello() {message += \"engine\"})();"); - var shadowRealm = engine.Realm.Intrinsics.ShadowRealm.Construct(); + var shadowRealm = engine.Intrinsics.ShadowRealm.Construct(); shadowRealm.SetValue("message", "hello "); shadowRealm.Evaluate("(function hello() {message += \"realm 1\"})();"); - var shadowRealm2 = engine.Realm.Intrinsics.ShadowRealm.Construct(); + var shadowRealm2 = engine.Intrinsics.ShadowRealm.Construct(); shadowRealm2.SetValue("message", "hello "); shadowRealm2.Evaluate("(function hello() {message += \"realm 2\"})();"); @@ -77,10 +77,10 @@ public void CanReuseScriptWithShadowRealm() var engine = new Engine(options => options.EnableModules(GetBasePath())); engine.SetValue("message", "engine"); - var shadowRealm = engine.Realm.Intrinsics.ShadowRealm.Construct(); + var shadowRealm = engine.Intrinsics.ShadowRealm.Construct(); shadowRealm.SetValue("message", "realm 1"); - var shadowRealm2 = engine.Realm.Intrinsics.ShadowRealm.Construct(); + var shadowRealm2 = engine.Intrinsics.ShadowRealm.Construct(); shadowRealm2.SetValue("message", "realm 2"); var parser = new Esprima.JavaScriptParser(); diff --git a/Jint/Engine.Advanced.cs b/Jint/Engine.Advanced.cs index 4f5789eb72..c1c68d60ac 100644 --- a/Jint/Engine.Advanced.cs +++ b/Jint/Engine.Advanced.cs @@ -1,7 +1,4 @@ -using Jint.Native; -using Jint.Native.Function; using Jint.Native.Promise; -using Jint.Runtime; using Jint.Runtime.Environments; using Environment = Jint.Runtime.Environments.Environment; diff --git a/Jint/Engine.cs b/Jint/Engine.cs index 97766cf8aa..7e4628a042 100644 --- a/Jint/Engine.cs +++ b/Jint/Engine.cs @@ -174,7 +174,17 @@ internal ref readonly ExecutionContext ExecutionContext internal SyntaxElement? _lastSyntaxElement; - public Realm Realm => _realmInConstruction ?? ExecutionContext.Realm; + internal Realm Realm => _realmInConstruction ?? ExecutionContext.Realm; + + /// + /// The well-known intrinsics for this engine instance. + /// + public Intrinsics Intrinsics => Realm.Intrinsics; + + /// + /// The global object for this engine instance. + /// + public ObjectInstance Global => Realm.GlobalObject; internal GlobalSymbolRegistry GlobalSymbolRegistry { get; } = new(); diff --git a/Jint/JsValueExtensions.cs b/Jint/JsValueExtensions.cs index a569ebf5d6..dc7fddce8c 100644 --- a/Jint/JsValueExtensions.cs +++ b/Jint/JsValueExtensions.cs @@ -554,7 +554,6 @@ public static JsValue Call(this JsValue value, params JsValue[] arguments) return ThrowNotObject(value); } - [Pure] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static JsValue Call(this JsValue value, JsValue thisObj, JsValue[] arguments) { diff --git a/Jint/Native/Function/EvalFunction.cs b/Jint/Native/Function/EvalFunction.cs index 0f29681460..0002633092 100644 --- a/Jint/Native/Function/EvalFunction.cs +++ b/Jint/Native/Function/EvalFunction.cs @@ -9,14 +9,14 @@ namespace Jint.Native.Function; -internal sealed class EvalFunction : Function +public sealed class EvalFunction : Function { private static readonly JsString _functionName = new("eval"); private static readonly ParserOptions _parserOptions = ParserOptions.Default with { Tolerant = true }; private readonly JavaScriptParser _parser = new(_parserOptions); - public EvalFunction( + internal EvalFunction( Engine engine, Realm realm, FunctionPrototype functionPrototype) @@ -40,7 +40,7 @@ protected internal override JsValue Call(JsValue thisObject, JsValue[] arguments /// /// https://tc39.es/ecma262/#sec-performeval /// - public JsValue PerformEval(JsValue x, Realm callerRealm, bool strictCaller, bool direct) + internal JsValue PerformEval(JsValue x, Realm callerRealm, bool strictCaller, bool direct) { if (!x.IsString()) { diff --git a/Jint/Runtime/Intrinsics.cs b/Jint/Runtime/Intrinsics.cs index 1af685b5fe..6dbb9f67e9 100644 --- a/Jint/Runtime/Intrinsics.cs +++ b/Jint/Runtime/Intrinsics.cs @@ -254,7 +254,7 @@ internal Intrinsics(Engine engine, Realm realm) internal GeneratorFunctionConstructor GeneratorFunction => _generatorFunction ??= new GeneratorFunctionConstructor(_engine, _realm, Function.PrototypeObject, IteratorPrototype); - internal EvalFunction Eval => + public EvalFunction Eval => _eval ??= new EvalFunction(_engine, _realm, Function.PrototypeObject); public ErrorConstructor Error =>