Browse Source

Implement ShadowRealm (#1174)

Marko Lahma 3 years ago
parent
commit
6d2715448d

+ 2 - 2
Jint.Tests.Test262/Test262Harness.settings.json

@@ -22,7 +22,6 @@
     "generators",
     "hashbang",
     "import-assertions",
-    "numeric-separator-literal",
     "Promise.allSettled",
     "Promise.any",
     "regexp-match-indices",
@@ -30,7 +29,6 @@
     "regexp-lookbehind",
     "regexp-unicode-property-escapes",
     "resizable-arraybuffer",
-    "ShadowRealm",
     "SharedArrayBuffer",
     "tail-call-optimization",
     "top-level-await",
@@ -215,6 +213,8 @@
     "language/statements/async-function/*.js",
     "language/expressions/async-function/*.js",
     "language/expressions/async-generator/*.js",
+    "built-ins/ShadowRealm/prototype/evaluate/wrapped-functions-share-no-properties-extended.js",
+    "built-ins/ShadowRealm/prototype/evaluate/wrapped-function-from-return-values-share-no-identity.js",
 
     // special casing data
     "built-ins/**/special_casing*.js",

+ 2 - 2
Jint.Tests/Jint.Tests.csproj

@@ -1,7 +1,7 @@
 <Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
     <TargetFrameworks>net6.0</TargetFrameworks>
-    <TargetFrameworks Condition="'$(OS)' == 'Windows_NT'">$(TargetFrameworks);net461</TargetFrameworks>
+    <TargetFrameworks Condition="'$(OS)' == 'Windows_NT'">$(TargetFrameworks);net462</TargetFrameworks>
     <AssemblyOriginatorKeyFile>..\Jint\Jint.snk</AssemblyOriginatorKeyFile>
     <SignAssembly>true</SignAssembly>
     <IsPackable>false</IsPackable>
@@ -15,7 +15,7 @@
     <ProjectReference Include="..\Jint\Jint.csproj" />
   </ItemGroup>
   <ItemGroup>
-    <Reference Include="Microsoft.CSharp" Condition=" '$(TargetFramework)' == 'net461' " />
+    <Reference Include="Microsoft.CSharp" Condition=" '$(TargetFramework)' == 'net462' " />
   </ItemGroup>
   <ItemGroup>
     <PackageReference Include="Flurl.Http.Signed" Version="3.2.0" />

+ 18 - 16
Jint.Tests/Runtime/ModuleTests.cs

@@ -1,7 +1,5 @@
-#if(NET6_0_OR_GREATER)
 using System.IO;
 using System.Reflection;
-#endif
 using System;
 using System.Collections.Generic;
 using System.Linq;
@@ -302,18 +300,16 @@ export const count = globals.counter;
         Assert.Equal("a", nsA.Get("a").AsString());
         Assert.Equal("b", nsB.Get("b").AsString());
     }
-    
+
     [Fact]
     public void ShouldSupportConstraints()
     {
         var engine = new Engine(opts => opts.TimeoutInterval(TimeSpan.FromTicks(1)));
-        
+
         engine.AddModule("my-module", @"for(var i = 0; i < 100000; i++) { } export const result = 'ok';");
         Assert.Throws<TimeoutException>(() => engine.ImportModule("my-module"));
     }
 
-#if(NET6_0_OR_GREATER)
-
     [Fact]
     public void CanLoadModuleImportsFromFiles()
     {
@@ -333,16 +329,22 @@ export const count = globals.counter;
 
         Assert.Equal("John Doe", result);
     }
-    
-    private static string GetBasePath()
+
+    internal static string GetBasePath()
     {
-        var assemblyPath = new Uri(typeof(ModuleTests).GetTypeInfo().Assembly.Location).LocalPath;
-        var assemblyDirectory = new FileInfo(assemblyPath).Directory;
-        return Path.Combine(
-            assemblyDirectory?.Parent?.Parent?.Parent?.FullName ?? throw new NullReferenceException("Could not find tests base path"),
-            "Runtime",
-            "Scripts");
-    }
+        var assemblyDirectory = new DirectoryInfo(AppDomain.CurrentDomain.RelativeSearchPath ?? AppDomain.CurrentDomain.BaseDirectory);
+
+        var current = assemblyDirectory;
+        while (current is not null && current.Name != "Jint.Tests")
+        {
+            current = current.Parent;
+        }
 
-#endif
+        if (current is null)
+        {
+            throw new NullReferenceException($"Could not find tests base path, assemblyPath: {assemblyDirectory}");
+        }
+
+        return Path.Combine(current.FullName, "Runtime", "Scripts");
+    }
 }

+ 32 - 0
Jint.Tests/Runtime/ShadowRealmTests.cs

@@ -0,0 +1,32 @@
+using Jint.Native;
+using Jint.Native.Object;
+using Xunit;
+
+namespace Jint.Tests.Runtime;
+
+public class ShadowRealmTests
+{
+    [Fact]
+    public void CanUseViaEngineMethods()
+    {
+        var engine = new Engine(options => options.EnableModules(ModuleTests.GetBasePath()));
+        var shadowRealm1 = engine.Realm.Intrinsics.ShadowRealm.Construct();
+
+        // lexically scoped (let/const) are visible during single call
+        Assert.Equal(123, shadowRealm1.Evaluate("const s = 123; const f = () => s; f();"));
+        Assert.Equal(true, shadowRealm1.Evaluate("typeof f === 'undefined'"));
+
+        // vars hold longer
+        Assert.Equal(456, shadowRealm1.Evaluate("function foo() { return 456; }; foo();"));
+        Assert.Equal(456, shadowRealm1.Evaluate("foo();"));
+
+        // not visible in global engine though
+        Assert.Equal(true, engine.Evaluate("typeof foo === 'undefined'"));
+
+        // modules
+        var importValue = shadowRealm1.ImportValue("./modules/format-name.js", "formatName");
+        var formatName = (ObjectInstance) importValue.UnwrapIfPromise();
+        var result = engine.Invoke(formatName, "John", "Doe").AsString();
+        Assert.Equal("John Doe", result);
+    }
+}

+ 1 - 1
Jint/Jint.csproj

@@ -1,7 +1,7 @@
 <Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
     <NeutralLanguage>en-US</NeutralLanguage>
-    <TargetFrameworks>net461;netstandard2.0;netstandard2.1</TargetFrameworks>
+    <TargetFrameworks>net462;netstandard2.0;netstandard2.1</TargetFrameworks>
     <AssemblyOriginatorKeyFile>Jint.snk</AssemblyOriginatorKeyFile>
     <SignAssembly>true</SignAssembly>
     <LangVersion>latest</LangVersion>

+ 3 - 20
Jint/Native/Array/ArrayInstance.cs

@@ -83,8 +83,8 @@ namespace Jint.Native.Array
                     // could be a mutating property for example, length might change, not safe anymore
                     return false;
                 }
-                
-                if (_prototype is not ArrayPrototype arrayPrototype 
+
+                if (_prototype is not ArrayPrototype arrayPrototype
                     || !ReferenceEquals(_prototype, _engine.Realm.Intrinsics.Array.PrototypeObject))
                 {
                     // somebody has switched prototype
@@ -97,7 +97,7 @@ namespace Jint.Native.Array
                     return false;
                 }
 
-                if (arrayPrototype.Prototype is not ObjectPrototype arrayPrototypePrototype 
+                if (arrayPrototype.Prototype is not ObjectPrototype arrayPrototypePrototype
                     || !ReferenceEquals(arrayPrototypePrototype, _engine.Realm.Intrinsics.Array.PrototypeObject.Prototype))
                 {
                     return false;
@@ -493,23 +493,6 @@ namespace Jint.Native.Array
             }
         }
 
-        public sealed override bool HasOwnProperty(JsValue p)
-        {
-            if (IsArrayIndex(p, out var index))
-            {
-                return index < GetLength()
-                       && (_sparse == null || _sparse.ContainsKey(index))
-                       && (_dense == null || (index < (uint) _dense.Length && _dense[index] != null));
-            }
-
-            if (p == CommonProperties.Length)
-            {
-                return _length != null;
-            }
-
-            return base.HasOwnProperty(p);
-        }
-
         public sealed override void RemoveOwnProperty(JsValue p)
         {
             if (IsArrayIndex(p, out var index))

+ 1 - 1
Jint/Native/Function/EvalFunctionInstance.cs

@@ -9,7 +9,7 @@ namespace Jint.Native.Function
 {
     public sealed class EvalFunctionInstance : FunctionInstance
     {
-        private static readonly ParserOptions ParserOptions = new ParserOptions { AdaptRegexp = true, Tolerant = false };
+        private static readonly ParserOptions ParserOptions = new ParserOptions { Tolerant = false };
         private static readonly JsString _functionName = new JsString("eval");
 
         public EvalFunctionInstance(

+ 1 - 1
Jint/Native/Function/FunctionConstructor.cs

@@ -14,7 +14,7 @@ namespace Jint.Native.Function
     /// </summary>
     public sealed class FunctionConstructor : FunctionInstance, IConstructor
     {
-        private static readonly ParserOptions ParserOptions = new ParserOptions { AdaptRegexp = true, Tolerant = false };
+        private static readonly ParserOptions ParserOptions = new ParserOptions { Tolerant = false };
         private static readonly JsString _functionName = new JsString("Function");
         private static readonly JsString _functionNameAnonymous = new JsString("anonymous");
 

+ 5 - 28
Jint/Native/Function/FunctionInstance.cs

@@ -162,24 +162,6 @@ namespace Jint.Native.Function
             }
         }
 
-        public override bool HasOwnProperty(JsValue property)
-        {
-            if (property == CommonProperties.Prototype)
-            {
-                return _prototypeDescriptor != null;
-            }
-            if (property == CommonProperties.Length)
-            {
-                return _length != null;
-            }
-            if (property == CommonProperties.Name)
-            {
-                return _nameDescriptor != null;
-            }
-
-            return base.HasOwnProperty(property);
-        }
-
         public override void RemoveOwnProperty(JsValue property)
         {
             if (property == CommonProperties.Prototype)
@@ -388,6 +370,11 @@ namespace Jint.Native.Function
             _prototypeDescriptor = new PropertyDescriptor(prototype, writableProperty, enumerable: false, configurable: false);
         }
 
+        internal void SetFunctionLength(JsNumber length)
+        {
+            DefinePropertyOrThrow(CommonProperties.Length, new PropertyDescriptor(length, writable: false, enumerable: false, configurable: true));
+        }
+
         public override string ToString()
         {
             // TODO no way to extract SourceText from Esprima at the moment, just returning native code
@@ -444,16 +431,6 @@ namespace Jint.Native.Function
                 }
             }
 
-            public override bool HasOwnProperty(JsValue property)
-            {
-                if (property == CommonProperties.Constructor)
-                {
-                    return _constructor != null;
-                }
-
-                return base.HasOwnProperty(property);
-            }
-
             public override void RemoveOwnProperty(JsValue property)
             {
                 if (property == CommonProperties.Constructor)

+ 7 - 6
Jint/Native/Function/FunctionPrototype.cs

@@ -59,19 +59,20 @@ namespace Jint.Native.Function
         /// </summary>
         private JsValue Bind(JsValue thisObj, JsValue[] arguments)
         {
-            if (thisObj is not ICallable)
+            if (thisObj is not (ICallable and ObjectInstance oi))
             {
                 ExceptionHelper.ThrowTypeError(_realm, "Bind must be called on a function");
+                return default;
             }
 
             var thisArg = arguments.At(0);
-            var f = BoundFunctionCreate((ObjectInstance) thisObj, thisArg, arguments.Skip(1));
+            var f = BoundFunctionCreate(oi, thisArg, arguments.Skip(1));
 
             JsNumber l;
-            var targetHasLength = thisObj.HasOwnProperty(CommonProperties.Length);
+            var targetHasLength = oi.HasOwnProperty(CommonProperties.Length) == true;
             if (targetHasLength)
             {
-                var targetLen = thisObj.Get(CommonProperties.Length);
+                var targetLen = oi.Get(CommonProperties.Length);
                 if (targetLen is not JsNumber number)
                 {
                     l = JsNumber.PositiveZero;
@@ -102,7 +103,7 @@ namespace Jint.Native.Function
 
             f.DefinePropertyOrThrow(CommonProperties.Length, new PropertyDescriptor(l, PropertyFlag.Configurable));
 
-            var targetName = thisObj.Get(CommonProperties.Name);
+            var targetName = oi.Get(CommonProperties.Name);
             if (!targetName.IsString())
             {
                 targetName = JsString.Empty;
@@ -207,4 +208,4 @@ namespace Jint.Native.Function
             return Undefined;
         }
     }
-}
+}

+ 34 - 26
Jint/Native/Global/GlobalObject.cs

@@ -35,46 +35,54 @@ namespace Jint.Native.Global
 
             var properties = new PropertyDictionary(55, checkExistingKeys: false)
             {
-                ["Object"] = new PropertyDescriptor(_realm.Intrinsics.Object, propertyFlags),
-                ["Function"] = new PropertyDescriptor(_realm.Intrinsics.Function, propertyFlags),
-                ["Symbol"] = new LazyPropertyDescriptor(this, static state => ((GlobalObject) state)._realm.Intrinsics.Symbol, propertyFlags),
+                ["AggregateError"] = new LazyPropertyDescriptor(this, static state => Undefined, propertyFlags),
                 ["Array"] = new LazyPropertyDescriptor(this, static state => ((GlobalObject) state)._realm.Intrinsics.Array, propertyFlags),
                 ["ArrayBuffer"] = new LazyPropertyDescriptor(this, static state => ((GlobalObject) state)._realm.Intrinsics.ArrayBuffer, propertyFlags),
-                ["DataView"] = new LazyPropertyDescriptor(this, static state => ((GlobalObject) state)._realm.Intrinsics.DataView, propertyFlags),
-                ["TypedArray"] = new LazyPropertyDescriptor(this, static state => ((GlobalObject) state)._realm.Intrinsics.TypedArray, propertyFlags),
-                ["Int8Array"] = new LazyPropertyDescriptor(this, static state => ((GlobalObject) state)._realm.Intrinsics.Int8Array, propertyFlags),
-                ["Uint8Array"] = new LazyPropertyDescriptor(this, static state => ((GlobalObject) state)._realm.Intrinsics.Uint8Array, propertyFlags),
-                ["Uint8ClampedArray"] = new LazyPropertyDescriptor(this, static state => ((GlobalObject) state)._realm.Intrinsics.Uint8ClampedArray, propertyFlags),
-                ["Int16Array"] = new LazyPropertyDescriptor(this, static state => ((GlobalObject) state)._realm.Intrinsics.Int16Array, propertyFlags),
-                ["Uint16Array"] = new LazyPropertyDescriptor(this, static state => ((GlobalObject) state)._realm.Intrinsics.Uint16Array, propertyFlags),
-                ["Int32Array"] = new LazyPropertyDescriptor(this, static state => ((GlobalObject) state)._realm.Intrinsics.Int32Array, propertyFlags),
-                ["Uint32Array"] = new LazyPropertyDescriptor(this, static state => ((GlobalObject) state)._realm.Intrinsics.Uint32Array, propertyFlags),
+                ["Atomics"] = new LazyPropertyDescriptor(this, static state => Undefined, propertyFlags),
+                ["BigInt"] = new LazyPropertyDescriptor(this, static state => ((GlobalObject) state)._realm.Intrinsics.BigInt, propertyFlags),
                 ["BigInt64Array"] = new LazyPropertyDescriptor(this, static state => ((GlobalObject) state)._realm.Intrinsics.BigInt64Array, propertyFlags),
                 ["BigUint64Array"] = new LazyPropertyDescriptor(this, static state => ((GlobalObject) state)._realm.Intrinsics.BigUint64Array, propertyFlags),
-                ["Float32Array"] = new LazyPropertyDescriptor(this, static state => ((GlobalObject) state)._realm.Intrinsics.Float32Array, propertyFlags),
-                ["Float64Array"] = new LazyPropertyDescriptor(this, static state => ((GlobalObject) state)._realm.Intrinsics.Float64Array, propertyFlags),
-                ["Map"] = new LazyPropertyDescriptor(this, static state => ((GlobalObject) state)._realm.Intrinsics.Map, propertyFlags),
-                ["Set"] = new LazyPropertyDescriptor(this, static state => ((GlobalObject) state)._realm.Intrinsics.Set, propertyFlags),
-                ["WeakMap"] = new LazyPropertyDescriptor(this, static state => ((GlobalObject) state)._realm.Intrinsics.WeakMap, propertyFlags),
-                ["WeakSet"] = new LazyPropertyDescriptor(this, static state => ((GlobalObject) state)._realm.Intrinsics.WeakSet, propertyFlags),
-                ["Promise"] = new LazyPropertyDescriptor(this, static state => ((GlobalObject) state)._realm.Intrinsics.Promise, propertyFlags),
-                ["String"] = new LazyPropertyDescriptor(this, static state => ((GlobalObject) state)._realm.Intrinsics.String, propertyFlags),
-                ["RegExp"] = new LazyPropertyDescriptor(this, static state => ((GlobalObject) state)._realm.Intrinsics.RegExp, propertyFlags),
-                ["Number"] = new LazyPropertyDescriptor(this, static state => ((GlobalObject) state)._realm.Intrinsics.Number, propertyFlags),
-                ["BigInt"] = new LazyPropertyDescriptor(this, static state => ((GlobalObject) state)._realm.Intrinsics.BigInt, propertyFlags),
                 ["Boolean"] = new LazyPropertyDescriptor(this, static state => ((GlobalObject) state)._realm.Intrinsics.Boolean, propertyFlags),
+                ["DataView"] = new LazyPropertyDescriptor(this, static state => ((GlobalObject) state)._realm.Intrinsics.DataView, propertyFlags),
                 ["Date"] = new LazyPropertyDescriptor(this, static state => ((GlobalObject) state)._realm.Intrinsics.Date, propertyFlags),
-                ["Math"] = new LazyPropertyDescriptor(this, static state => ((GlobalObject) state)._realm.Intrinsics.Math, propertyFlags),
-                ["JSON"] = new LazyPropertyDescriptor(this, static state => ((GlobalObject) state)._realm.Intrinsics.Json, propertyFlags),
                 ["Error"] = new LazyPropertyDescriptor(this, static state => ((GlobalObject) state)._realm.Intrinsics.Error, propertyFlags),
                 ["EvalError"] = new LazyPropertyDescriptor(this, static state => ((GlobalObject) state)._realm.Intrinsics.EvalError, propertyFlags),
+                ["FinalizationRegistry"] = new LazyPropertyDescriptor(this, static state => Undefined, propertyFlags),
+                ["Float32Array"] = new LazyPropertyDescriptor(this, static state => ((GlobalObject) state)._realm.Intrinsics.Float32Array, propertyFlags),
+                ["Float64Array"] = new LazyPropertyDescriptor(this, static state => ((GlobalObject) state)._realm.Intrinsics.Float64Array, propertyFlags),
+                ["Function"] = new PropertyDescriptor(_realm.Intrinsics.Function, propertyFlags),
+                ["Int16Array"] = new LazyPropertyDescriptor(this, static state => ((GlobalObject) state)._realm.Intrinsics.Int16Array, propertyFlags),
+                ["Int32Array"] = new LazyPropertyDescriptor(this, static state => ((GlobalObject) state)._realm.Intrinsics.Int32Array, propertyFlags),
+                ["Int8Array"] = new LazyPropertyDescriptor(this, static state => ((GlobalObject) state)._realm.Intrinsics.Int8Array, propertyFlags),
+                ["JSON"] = new LazyPropertyDescriptor(this, static state => ((GlobalObject) state)._realm.Intrinsics.Json, propertyFlags),
+                ["Map"] = new LazyPropertyDescriptor(this, static state => ((GlobalObject) state)._realm.Intrinsics.Map, propertyFlags),
+                ["Math"] = new LazyPropertyDescriptor(this, static state => ((GlobalObject) state)._realm.Intrinsics.Math, propertyFlags),
+                ["Number"] = new LazyPropertyDescriptor(this, static state => ((GlobalObject) state)._realm.Intrinsics.Number, propertyFlags),
+                ["Object"] = new PropertyDescriptor(_realm.Intrinsics.Object, propertyFlags),
+                ["Promise"] = new LazyPropertyDescriptor(this, static state => ((GlobalObject) state)._realm.Intrinsics.Promise, propertyFlags),
                 ["Proxy"] = new LazyPropertyDescriptor(this, static state => ((GlobalObject) state)._realm.Intrinsics.Proxy, propertyFlags),
                 ["RangeError"] = new LazyPropertyDescriptor(this, static state => ((GlobalObject) state)._realm.Intrinsics.RangeError, propertyFlags),
                 ["ReferenceError"] = new LazyPropertyDescriptor(this, static state => ((GlobalObject) state)._realm.Intrinsics.ReferenceError, propertyFlags),
                 ["Reflect"] = new LazyPropertyDescriptor(this, static state => ((GlobalObject) state)._realm.Intrinsics.Reflect, propertyFlags),
+                ["RegExp"] = new LazyPropertyDescriptor(this, static state => ((GlobalObject) state)._realm.Intrinsics.RegExp, propertyFlags),
+                ["Set"] = new LazyPropertyDescriptor(this, static state => ((GlobalObject) state)._realm.Intrinsics.Set, propertyFlags),
+                ["ShadowRealm"] = new LazyPropertyDescriptor(this, static state => ((GlobalObject) state)._realm.Intrinsics.ShadowRealm, propertyFlags),
+                ["SharedArrayBuffer"] = new LazyPropertyDescriptor(this, static state => Undefined, propertyFlags),
+                ["String"] = new LazyPropertyDescriptor(this, static state => ((GlobalObject) state)._realm.Intrinsics.String, propertyFlags),
+                ["Symbol"] = new LazyPropertyDescriptor(this, static state => ((GlobalObject) state)._realm.Intrinsics.Symbol, propertyFlags),
                 ["SyntaxError"] = new LazyPropertyDescriptor(this, static state => ((GlobalObject) state)._realm.Intrinsics.SyntaxError, propertyFlags),
                 ["TypeError"] = new LazyPropertyDescriptor(this, static state => ((GlobalObject) state)._realm.Intrinsics.TypeError, propertyFlags),
+                ["TypedArray"] = new LazyPropertyDescriptor(this, static state => ((GlobalObject) state)._realm.Intrinsics.TypedArray, propertyFlags),
                 ["URIError"] = new LazyPropertyDescriptor(this, static state => ((GlobalObject) state)._realm.Intrinsics.UriError, propertyFlags),
+                ["Uint16Array"] = new LazyPropertyDescriptor(this, static state => ((GlobalObject) state)._realm.Intrinsics.Uint16Array, propertyFlags),
+                ["Uint32Array"] = new LazyPropertyDescriptor(this, static state => ((GlobalObject) state)._realm.Intrinsics.Uint32Array, propertyFlags),
+                ["Uint8Array"] = new LazyPropertyDescriptor(this, static state => ((GlobalObject) state)._realm.Intrinsics.Uint8Array, propertyFlags),
+                ["Uint8ClampedArray"] = new LazyPropertyDescriptor(this, static state => ((GlobalObject) state)._realm.Intrinsics.Uint8ClampedArray, propertyFlags),
+                ["WeakMap"] = new LazyPropertyDescriptor(this, static state => ((GlobalObject) state)._realm.Intrinsics.WeakMap, propertyFlags),
+                ["WeakRef"] = new LazyPropertyDescriptor(this, static state => Undefined, propertyFlags),
+                ["WeakSet"] = new LazyPropertyDescriptor(this, static state => ((GlobalObject) state)._realm.Intrinsics.WeakSet, propertyFlags),
+
+
                 ["NaN"] = new PropertyDescriptor(double.NaN, PropertyFlag.AllForbidden),
                 ["Infinity"] = new PropertyDescriptor(double.PositiveInfinity, PropertyFlag.AllForbidden),
                 ["undefined"] = new PropertyDescriptor(Undefined, PropertyFlag.AllForbidden),
@@ -843,4 +851,4 @@ namespace Jint.Native.Global
             SetProperty(property, desc);
         }
     }
-}
+}

+ 1 - 3
Jint/Native/JsValue.cs

@@ -157,8 +157,6 @@ namespace Jint.Native
             return engine.Invoke(this, arguments);
         }
 
-        public virtual bool HasOwnProperty(JsValue property) => false;
-
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         public JsValue Get(JsValue property)
         {
@@ -508,4 +506,4 @@ namespace Jint.Native
             return (IConstructor) c;
         }
     }
-}
+}

+ 1 - 1
Jint/Native/Json/JsonInstance.cs

@@ -16,7 +16,7 @@ namespace Jint.Native.Json
             Engine engine,
             Realm realm,
             ObjectPrototype objectPrototype)
-            : base(engine, objectClass: ObjectClass.Object)
+            : base(engine)
         {
             _realm = realm;
             _prototype = objectPrototype;

+ 5 - 12
Jint/Native/Object/ObjectInstance.cs

@@ -288,17 +288,10 @@ namespace Jint.Native.Object
             return _symbols?.TryGetValue((JsSymbol) key, out descriptor) == true;
         }
 
-        public override bool HasOwnProperty(JsValue property)
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public bool HasOwnProperty(JsValue property)
         {
-            EnsureInitialized();
-
-            var key = TypeConverter.ToPropertyKey(property);
-            if (!key.IsSymbol())
-            {
-                return _properties?.ContainsKey(TypeConverter.ToString(key)) == true;
-            }
-
-            return _symbols?.ContainsKey((JsSymbol) key) == true;
+            return !ReferenceEquals(GetOwnProperty(property), PropertyDescriptor.Undefined);
         }
 
         public virtual void RemoveOwnProperty(JsValue property)
@@ -964,7 +957,7 @@ namespace Jint.Native.Object
 
                 case ObjectClass.Arguments:
                 case ObjectClass.Object:
-                    
+
                     if (this is ArrayInstance arrayInstance)
                     {
                         var result = new object[arrayInstance.Length];
@@ -983,7 +976,7 @@ namespace Jint.Native.Object
                         converted = result;
                         break;
                     }
-                    
+
                     var o = _engine.Options.Interop.CreateClrObject(this);
                     foreach (var p in GetOwnProperties())
                     {

+ 1 - 1
Jint/Native/RegExp/RegExpConstructor.cs

@@ -105,7 +105,7 @@ namespace Jint.Native.RegExp
 
             try
             {
-                var parserOptions = new ParserOptions { AdaptRegexp = true };
+                var parserOptions = new ParserOptions();
                 var scanner = new Scanner("/" + p + "/" + flags, parserOptions);
 
                 // seems valid

+ 1 - 11
Jint/Native/RegExp/RegExpInstance.cs

@@ -109,15 +109,5 @@ namespace Jint.Native.RegExp
             keys.AddRange(base.GetOwnPropertyKeys(types));
             return keys;
         }
-
-        public override bool HasOwnProperty(JsValue property)
-        {
-            if (property == PropertyLastIndex)
-            {
-                return _prototypeDescriptor != null;
-            }
-
-            return base.HasOwnProperty(property);
-        }
     }
-}
+}

+ 84 - 0
Jint/Native/ShadowRealm/ShadowRealmConstructor.cs

@@ -0,0 +1,84 @@
+#nullable enable
+
+using Jint.Native.Function;
+using Jint.Native.Object;
+using Jint.Runtime;
+using Jint.Runtime.Descriptors;
+using Jint.Runtime.Environments;
+
+namespace Jint.Native.ShadowRealm;
+
+/// <summary>
+/// https://tc39.es/proposal-shadowrealm/#sec-properties-of-the-shadowRealm-constructor
+/// </summary>
+public sealed class ShadowRealmConstructor : FunctionInstance, IConstructor
+{
+    private static readonly JsString _functionName = new JsString("ShadowRealm");
+
+    internal ShadowRealmConstructor(
+        Engine engine,
+        Realm realm,
+        FunctionPrototype functionPrototype,
+        ObjectPrototype objectPrototype)
+        : base(engine, realm, _functionName)
+    {
+        _prototype = functionPrototype;
+        PrototypeObject = new ShadowRealmPrototype(engine, realm, this, objectPrototype);
+        _length = new PropertyDescriptor(0, PropertyFlag.Configurable);
+        _prototypeDescriptor = new PropertyDescriptor(PrototypeObject, PropertyFlag.AllForbidden);
+    }
+
+    private ShadowRealmPrototype PrototypeObject { get; }
+
+    protected internal override JsValue Call(JsValue thisObject, JsValue[] arguments)
+    {
+        ExceptionHelper.ThrowTypeError(_realm, "Constructor ShadowRealm requires 'new'");
+        return null;
+    }
+
+    public ShadowRealmInstance Construct()
+    {
+        return Construct(PrototypeObject);
+    }
+
+    private ShadowRealmInstance Construct(JsValue newTarget)
+    {
+        var realmRec = _engine._host.CreateRealm();
+
+        var o = OrdinaryCreateFromConstructor(
+            newTarget,
+            static intrinsics => intrinsics.ShadowRealm.PrototypeObject,
+            static (engine, _, realmRec) =>
+            {
+                var context = new ExecutionContext(
+                    scriptOrModule: null,
+                    lexicalEnvironment: realmRec.GlobalEnv,
+                    variableEnvironment: realmRec.GlobalEnv,
+                    privateEnvironment: null,
+                    realm: realmRec,
+                    function: null);
+
+                return new ShadowRealmInstance(engine, context, realmRec);
+            },
+            realmRec);
+
+        // this are currently handled as part of realm construction
+        // SetRealmGlobalObject(realmRec, Undefined, Undefined);
+        // SetDefaultGlobalBindings(o._ShadowRealm);
+
+        _engine._host.InitializeShadowRealm(o._shadowRealm);
+
+        return o;
+    }
+
+
+    ObjectInstance IConstructor.Construct(JsValue[] arguments, JsValue newTarget)
+    {
+        if (newTarget.IsUndefined())
+        {
+            ExceptionHelper.ThrowTypeError(_realm);
+        }
+
+        return Construct(newTarget);
+    }
+}

+ 330 - 0
Jint/Native/ShadowRealm/ShadowRealmInstance.cs

@@ -0,0 +1,330 @@
+#nullable enable
+
+using Esprima;
+using Esprima.Ast;
+using Esprima.Utils;
+using Jint.Native.Function;
+using Jint.Native.Object;
+using Jint.Native.Promise;
+using Jint.Runtime;
+using Jint.Runtime.Environments;
+using Jint.Runtime.Interpreter;
+using Jint.Runtime.Interpreter.Statements;
+using Jint.Runtime.Modules;
+
+namespace Jint.Native.ShadowRealm;
+
+/// <summary>
+/// https://tc39.es/proposal-shadowrealm/#sec-properties-of-shadowrealm-instances
+/// </summary>
+public sealed class ShadowRealmInstance : ObjectInstance
+{
+    private static readonly ParserOptions ParserOptions = new() { Tolerant = false };
+
+    internal readonly Realm _shadowRealm;
+    internal readonly ExecutionContext _executionContext;
+
+    internal ShadowRealmInstance(Engine engine, ExecutionContext executionContext, Realm shadowRealm) : base(engine)
+    {
+        _executionContext = executionContext;
+        _shadowRealm = shadowRealm;
+    }
+
+    public JsValue Evaluate(string sourceText)
+    {
+        var callerRealm = _engine.Realm;
+        return PerformShadowRealmEval(sourceText, callerRealm);
+    }
+
+    public JsValue ImportValue(string specifier, string exportName)
+    {
+        var callerRealm = _engine.Realm;
+        return ShadowRealmImportValue(specifier, exportName, callerRealm);
+    }
+
+    /// <summary>
+    /// https://tc39.es/proposal-shadowrealm/#sec-performshadowrealmeval
+    /// </summary>
+    internal JsValue PerformShadowRealmEval(string sourceText, Realm callerRealm)
+    {
+        var evalRealm = _shadowRealm;
+
+        _engine._host.EnsureCanCompileStrings(callerRealm, evalRealm);
+
+        var parser = new JavaScriptParser(sourceText, ParserOptions);
+
+        Script script;
+        try
+        {
+            script = parser.ParseScript();
+        }
+        catch (ParserException e)
+        {
+            if (e.Description == Messages.InvalidLHSInAssignment)
+            {
+                ExceptionHelper.ThrowReferenceError(callerRealm, Messages.InvalidLHSInAssignment);
+            }
+            else
+            {
+                ExceptionHelper.ThrowSyntaxError(callerRealm, e.Message);
+            }
+
+            return default;
+        }
+
+        ref readonly var body = ref script.Body;
+        if (body.Count == 0)
+        {
+            return Undefined;
+        }
+
+        var validator = new ShadowScriptValidator(callerRealm);
+        validator.Visit(script);
+
+        var strictEval = script.Strict;
+        var runningContext = _engine.ExecutionContext;
+        var lexEnv = JintEnvironment.NewDeclarativeEnvironment(_engine, evalRealm.GlobalEnv);
+        EnvironmentRecord varEnv = evalRealm.GlobalEnv;
+
+        if (strictEval)
+        {
+            varEnv = lexEnv;
+        }
+
+        // If runningContext is not already suspended, suspend runningContext.
+
+        var evalContext = new ExecutionContext(null, lexEnv, varEnv, null, evalRealm, null);
+        _engine.EnterExecutionContext(evalContext);
+
+        Completion result;
+        try
+        {
+            _engine.EvalDeclarationInstantiation(script, varEnv, lexEnv, privateEnv: null, strictEval);
+
+            using (new StrictModeScope(strictEval, force: true))
+            {
+                result = new JintScript(script).Execute(new EvaluationContext(_engine));
+            }
+
+            if (result.Type == CompletionType.Throw)
+            {
+                ThrowCrossRealmError(callerRealm, result.GetValueOrDefault().ToString());
+            }
+        }
+        finally
+        {
+            _engine.LeaveExecutionContext();
+        }
+
+        return GetWrappedValue(callerRealm, callerRealm, result.Value);
+    }
+
+
+    /// <summary>
+    /// https://tc39.es/proposal-shadowrealm/#sec-getwrappedvalue
+    /// </summary>
+    private static JsValue GetWrappedValue(Realm throwerRealm, Realm callerRealm, JsValue value)
+    {
+        if (value is ObjectInstance oi)
+        {
+            if (!oi.IsCallable)
+            {
+                ThrowCrossRealmError(throwerRealm, "Result is not callable");
+            }
+
+            return WrappedFunctionCreate(throwerRealm, callerRealm, oi);
+        }
+
+        return value;
+    }
+
+    /// <summary>
+    /// https://tc39.es/proposal-shadowrealm/#sec-wrappedfunctioncreate
+    /// </summary>
+    private static JsValue WrappedFunctionCreate(Realm throwerRealm, Realm callerRealm, ObjectInstance target)
+    {
+        var wrapped = new WrappedFunction(callerRealm.GlobalEnv._engine, callerRealm, target);
+        try
+        {
+            CopyNameAndLength(wrapped, target);
+        }
+        catch (JavaScriptException ex)
+        {
+            ThrowCrossRealmError(throwerRealm, ex.Message);
+        }
+        return wrapped;
+    }
+
+    /// <summary>
+    /// https://tc39.es/proposal-shadowrealm/#sec-copynameandlength
+    /// </summary>
+    private static void CopyNameAndLength(WrappedFunction f, ObjectInstance target, string? prefix = null, int argCount = 0)
+    {
+        var L = JsNumber.PositiveZero;
+        var targetHasLength = target.HasOwnProperty("length");
+        if (targetHasLength)
+        {
+            var targetLen = target.Get("length");
+            if (targetLen is JsNumber number)
+            {
+                if (number.IsPositiveInfinity())
+                {
+                    L = number;
+                }
+                else if (number.IsNegativeInfinity())
+                {
+                    L = JsNumber.PositiveZero;
+                }
+                else
+                {
+                    var targetLenAsInt = TypeConverter.ToIntegerOrInfinity(targetLen);
+                    L = JsNumber.Create(System.Math.Max(targetLenAsInt - argCount, 0));
+                }
+
+            }
+        }
+
+        f.SetFunctionLength(L);
+        var targetName = target.Get(CommonProperties.Name);
+        if (!targetName.IsString())
+        {
+            targetName = JsString.Empty;
+        }
+
+        f.SetFunctionName(targetName, prefix);
+    }
+
+    /// <summary>
+    /// https://tc39.es/proposal-shadowrealm/#sec-shadowrealmimportvalue
+    /// </summary>
+    internal JsValue ShadowRealmImportValue(
+        string specifierString,
+        string exportNameString,
+        Realm callerRealm)
+    {
+        var innerCapability = PromiseConstructor.NewPromiseCapability(_engine, _engine.Realm.Intrinsics.Promise);
+
+        // var runningContext = _engine.ExecutionContext;
+        // 4. If runningContext is not already suspended, suspend runningContext.
+
+        _engine.EnterExecutionContext(_executionContext);
+        _engine._host.ImportModuleDynamically(null, specifierString, innerCapability);
+        _engine.LeaveExecutionContext();
+
+        var onFulfilled = new StepsFunction(_engine, callerRealm, exportNameString);
+        var promiseCapability = PromiseConstructor.NewPromiseCapability(_engine, _engine.Realm.Intrinsics.Promise);
+        var value = PromiseOperations.PerformPromiseThen(_engine, (PromiseInstance) innerCapability.PromiseInstance, onFulfilled, callerRealm.Intrinsics.ThrowTypeError, promiseCapability);
+
+        _engine.RunAvailableContinuations();
+
+        return value;
+    }
+
+    private sealed class StepsFunction : FunctionInstance
+    {
+        private readonly string _exportNameString;
+
+        public StepsFunction(Engine engine, Realm realm, string exportNameString) : base(engine, realm, JsString.Empty)
+        {
+            _exportNameString = exportNameString;
+            SetFunctionLength(JsNumber.PositiveOne);
+        }
+
+        protected internal override JsValue Call(JsValue thisObject, JsValue[] arguments)
+        {
+            var exports = (ModuleNamespace) arguments.At(0);
+            var f = this;
+            var s = _exportNameString;
+            var hasOwn = exports.HasOwnProperty(s);
+            if (!hasOwn)
+            {
+                ExceptionHelper.ThrowTypeError(_realm, $"export name {s} missing");
+            }
+
+            var value = exports.Get(s);
+            var realm = f._realm;
+            return GetWrappedValue(_engine.Realm, realm, value);
+        }
+    }
+
+    private static ShadowRealmInstance ValidateShadowRealmObject(Realm callerRealm, JsValue thisObj)
+    {
+        var instance = thisObj as ShadowRealmInstance;
+        if (instance is null)
+        {
+            ExceptionHelper.ThrowTypeError(callerRealm, "object must be a ShadowRealm");
+        }
+
+        return instance;
+    }
+
+    private static void ThrowCrossRealmError(Realm callerRealm, string message)
+    {
+        ExceptionHelper.ThrowTypeError(callerRealm, "Cross-Realm Error: " + message);
+    }
+
+    private sealed class WrappedFunction : FunctionInstance
+    {
+        private readonly ObjectInstance _wrappedTargetFunction;
+
+        public WrappedFunction(
+            Engine engine,
+            Realm callerRealm,
+            ObjectInstance wrappedTargetFunction) : base(engine, callerRealm, null)
+        {
+            _wrappedTargetFunction = wrappedTargetFunction;
+            _prototype = callerRealm.Intrinsics.Function.PrototypeObject;
+        }
+
+        /// <summary>
+        /// https://tc39.es/proposal-shadowrealm/#sec-wrapped-function-exotic-objects-call-thisargument-argumentslist
+        /// </summary>
+        protected internal override JsValue Call(JsValue thisArgument, JsValue[] arguments)
+        {
+            var target = _wrappedTargetFunction;
+            var targetRealm = GetFunctionRealm(target);
+            var callerRealm = GetFunctionRealm(this);
+
+            var wrappedArgs = new JsValue[arguments.Length];
+            for (var i = 0; i < arguments.Length; i++)
+            {
+                wrappedArgs[i] = GetWrappedValue(callerRealm, targetRealm, arguments[i]);
+            }
+
+            var wrappedThisArgument = GetWrappedValue(callerRealm, targetRealm, thisArgument);
+
+            JsValue result;
+            try
+            {
+                result = target.Call(wrappedThisArgument, wrappedArgs);
+            }
+            catch (JavaScriptException ex)
+            {
+                ThrowCrossRealmError(_realm, ex.Message);
+                return default!;
+            }
+
+            return GetWrappedValue(callerRealm, callerRealm, result);
+        }
+    }
+
+    /// <summary>
+    /// If body Contains NewTarget is true, throw a SyntaxError exception.
+    /// If body Contains SuperProperty is true, throw a SyntaxError exception.
+    /// If body Contains SuperCall is true, throw a SyntaxError exception.
+    /// </summary>
+    private sealed class ShadowScriptValidator : AstVisitor
+    {
+        private readonly Realm _realm;
+
+        public ShadowScriptValidator(Realm realm)
+        {
+            _realm = realm;
+        }
+
+        protected override void VisitSuper(Super super)
+        {
+            ExceptionHelper.ThrowTypeError(_realm, "Shadow realm code cannot contain super");
+        }
+    }
+}

+ 98 - 0
Jint/Native/ShadowRealm/ShadowRealmPrototype.cs

@@ -0,0 +1,98 @@
+#nullable enable
+
+using Jint.Collections;
+using Jint.Native.Object;
+using Jint.Native.Symbol;
+using Jint.Runtime;
+using Jint.Runtime.Descriptors;
+using Jint.Runtime.Interop;
+
+namespace Jint.Native.ShadowRealm;
+
+/// <summary>
+/// https://tc39.es/proposal-shadowrealm/#sec-properties-of-the-shadowrealm-prototype-object
+/// </summary>
+internal sealed class ShadowRealmPrototype : Prototype
+{
+    private readonly ShadowRealmConstructor _constructor;
+
+    internal ShadowRealmPrototype(
+        Engine engine,
+        Realm realm,
+        ShadowRealmConstructor constructor,
+        ObjectPrototype prototype) : base(engine, realm)
+    {
+        _prototype = prototype;
+        _constructor = constructor;
+    }
+
+    protected override void Initialize()
+    {
+        const PropertyFlag propertyFlags = PropertyFlag.Configurable | PropertyFlag.Writable;
+        var properties = new PropertyDictionary(5, checkExistingKeys: false)
+        {
+            ["length"] = new PropertyDescriptor(0, PropertyFlag.Configurable),
+            ["constructor"] = new PropertyDescriptor(_constructor, PropertyFlag.NonEnumerable),
+            ["evaluate"] = new PropertyDescriptor(new ClrFunctionInstance(Engine, "evaluate", Evaluate, 1, PropertyFlag.Configurable), propertyFlags),
+            ["importValue"] = new PropertyDescriptor(new ClrFunctionInstance(Engine, "importValue", ImportValue, 2, PropertyFlag.Configurable), propertyFlags),
+        };
+        SetProperties(properties);
+
+        var symbols = new SymbolDictionary(1) { [GlobalSymbolRegistry.ToStringTag] = new PropertyDescriptor("ShadowRealm", false, false, true) };
+        SetSymbols(symbols);
+    }
+
+    /// <summary>
+    /// https://tc39.es/proposal-shadowrealm/#sec-shadowrealm.prototype.evaluate
+    /// </summary>
+    private JsValue Evaluate(JsValue thisObj, JsValue[] arguments)
+    {
+        var shadowRealm = ValidateShadowRealmObject(thisObj);
+        var sourceText = arguments.At(0);
+
+        if (!sourceText.IsString())
+        {
+            ExceptionHelper.ThrowTypeError(_realm, "Invalid source text " + sourceText);
+        }
+
+        return shadowRealm.PerformShadowRealmEval(sourceText.AsString(), _realm);
+    }
+
+    /// <summary>
+    /// https://tc39.es/proposal-shadowrealm/#sec-shadowrealm.prototype.importvalue
+    /// </summary>
+    private JsValue ImportValue(JsValue thisObj, JsValue[] arguments)
+    {
+        var specifier = arguments.At(0);
+        var exportName = arguments.At(1);
+
+        var O = ValidateShadowRealmObject(thisObj);
+        var specifierString = TypeConverter.ToJsString(specifier);
+        if (!specifier.IsString())
+        {
+            ExceptionHelper.ThrowTypeError(_realm, "Invalid specifier");
+        }
+
+        // TODO, newer test suite expects that this is always a string
+        /*
+        if (!exportName.IsString())
+        {
+            ExceptionHelper.ThrowTypeError(_realm, "Invalid exportName");
+        }
+        */
+
+        var callerRealm = _realm;
+        return O.ShadowRealmImportValue(specifierString.ToString(), exportName.ToString(), callerRealm);
+    }
+
+    private ShadowRealmInstance ValidateShadowRealmObject(JsValue thisObj)
+    {
+        var instance = thisObj as ShadowRealmInstance;
+        if (instance is null)
+        {
+            ExceptionHelper.ThrowTypeError(_realm, "object must be a ShadowRealm");
+        }
+
+        return instance;
+    }
+}

+ 1 - 11
Jint/Native/String/StringInstance.cs

@@ -116,16 +116,6 @@ namespace Jint.Native.String
             }
         }
 
-        public override bool HasOwnProperty(JsValue property)
-        {
-            if (property == CommonProperties.Length)
-            {
-                return _length != null;
-            }
-
-            return base.HasOwnProperty(property);
-        }
-
         public override void RemoveOwnProperty(JsValue property)
         {
             if (property == CommonProperties.Length)
@@ -136,4 +126,4 @@ namespace Jint.Native.String
             base.RemoveOwnProperty(property);
         }
     }
-}
+}

+ 1 - 1
Jint/Runtime/Debugger/DebugHandler.cs

@@ -111,7 +111,7 @@ namespace Jint.Runtime.Debugger
         /// <inheritdoc cref="Evaluate(Script)" />
         public JsValue Evaluate(string source, ParserOptions options = null)
         {
-            options ??= new ParserOptions("evaluation") { AdaptRegexp = true, Tolerant = true };
+            options ??= new ParserOptions("evaluation");
             var parser = new JavaScriptParser(source, options);
             try
             {

+ 7 - 0
Jint/Runtime/Host.cs

@@ -187,5 +187,12 @@ namespace Jint.Runtime
         public virtual void FinalizeImportMeta(ObjectInstance importMeta, ModuleRecord moduleRecord)
         {
         }
+
+        /// <summary>
+        /// https://tc39.es/proposal-shadowrealm/#sec-host-initialize-shadow-shadowrealm
+        /// </summary>
+        public virtual void InitializeShadowRealm(Realm realm)
+        {
+        }
     }
 }

+ 1 - 1
Jint/Runtime/Interpreter/Expressions/JintAssignmentExpression.cs

@@ -398,7 +398,7 @@ namespace Jint.Runtime.Interpreter.Expressions
                 {
                     if (strict && hasEvalOrArguments)
                     {
-                        ExceptionHelper.ThrowSyntaxError(engine.Realm);
+                        ExceptionHelper.ThrowSyntaxError(engine.Realm, "Invalid assignment target");
                     }
 
                     var completion = right.GetValue(context);

+ 1 - 1
Jint/Runtime/Interpreter/JintFunctionDefinition.cs

@@ -33,7 +33,7 @@ namespace Jint.Runtime.Interpreter
             Strict = function.Strict;
         }
 
-        public FunctionThisMode ThisMode => Strict || _engine._isStrict ? FunctionThisMode.Strict : FunctionThisMode.Global;
+        public FunctionThisMode ThisMode => Strict ? FunctionThisMode.Strict : FunctionThisMode.Global;
 
         /// <summary>
         /// https://tc39.es/ecma262/#sec-runtime-semantics-evaluatebody

+ 7 - 1
Jint/Runtime/Intrinsics.cs

@@ -18,6 +18,7 @@ using Jint.Native.Proxy;
 using Jint.Native.Reflect;
 using Jint.Native.RegExp;
 using Jint.Native.Set;
+using Jint.Native.ShadowRealm;
 using Jint.Native.String;
 using Jint.Native.Symbol;
 using Jint.Native.TypedArray;
@@ -88,6 +89,8 @@ namespace Jint.Runtime
         private Float32ArrayConstructor _float32Array;
         private Float64ArrayConstructor _float64Array;
 
+        private ShadowRealmConstructor _shadowRealm;
+
         internal Intrinsics(Engine engine, Realm realm)
         {
             _engine = engine;
@@ -218,6 +221,9 @@ namespace Jint.Runtime
         public SymbolConstructor Symbol =>
             _symbol ??= new SymbolConstructor(_engine, _realm, Function.PrototypeObject, Object.PrototypeObject);
 
+        public ShadowRealmConstructor ShadowRealm =>
+            _shadowRealm ??= new ShadowRealmConstructor(_engine, _realm, Function.PrototypeObject, Object.PrototypeObject);
+
         public EvalFunctionInstance Eval =>
             _eval ??= new EvalFunctionInstance(_engine, _realm, Function.PrototypeObject);
 
@@ -245,4 +251,4 @@ namespace Jint.Runtime
         public ThrowTypeError ThrowTypeError =>
             _throwTypeError ??= new ThrowTypeError(_engine, _engine.Realm) { _prototype = _engine.Realm.Intrinsics.Function.PrototypeObject };
     }
-}
+}

+ 1 - 6
Jint/Runtime/Modules/DefaultModuleLoader.cs

@@ -132,12 +132,7 @@ public sealed class DefaultModuleLoader : IModuleLoader
         Module module;
         try
         {
-            var parserOptions = new ParserOptions(resolved.Uri.LocalPath)
-            {
-                AdaptRegexp = true,
-                Tolerant = true
-            };
-
+            var parserOptions = new ParserOptions(resolved.Uri.LocalPath);
             module = new JavaScriptParser(code, parserOptions).ParseModule();
         }
         catch (ParserException ex)

+ 1 - 1
Jint/Runtime/Realm.cs

@@ -38,4 +38,4 @@ namespace Jint.Runtime
         /// </summary>
         public object HostDefined { get; set; }
     }
-}
+}

+ 1 - 0
README.md

@@ -106,6 +106,7 @@ The entire execution engine was rebuild with performance in mind, in many cases
 #### ECMAScript Stage 3 (no version yet)
 
 - ✔ Array find from last
+- ✔ ShadowRealm
 
 #### Other