2
0
Эх сурвалжийг харах

Implement Promise.withResolvers and update test suite (#1650)

Marko Lahma 1 жил өмнө
parent
commit
1a6aa38f1e

+ 0 - 1
Jint.Tests.PublicInterface/ShadowRealmTests.cs

@@ -1,4 +1,3 @@
-using Jint.Native;
 using Jint.Native.Object;
 
 namespace Jint.Tests.PublicInterface;

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

@@ -1,5 +1,5 @@
 {
-  "SuiteGitSha": "9437cab774ab2f22c5cb971b11b8512eca705721",
+  "SuiteGitSha": "6396ebde0316639292530460d1ef961fd9bbe0d4",
   //"SuiteDirectory": "//mnt/c/work/test262",
   "TargetPath": "./Generated",
   "Namespace": "Jint.Tests.Test262",
@@ -46,6 +46,7 @@
     // RegExp handling problems
     "built-ins/RegExp/prototype/exec/S15.10.6.2_A1_T6.js",
     "language/literals/regexp/u-case-mapping.js",
+    "built-ins/RegExp/lookahead-quantifier-match-groups.js",
 
     // requires investigation how to process complex function name evaluation for property
     "built-ins/Function/prototype/toString/method-computed-property-name.js",

+ 21 - 10
Jint/Native/Promise/PromiseConstructor.cs

@@ -21,8 +21,6 @@ namespace Jint.Native.Promise
     {
         private static readonly JsString _functionName = new JsString("Promise");
 
-        internal PromisePrototype PrototypeObject { get; private set; }
-
         internal PromiseConstructor(
             Engine engine,
             Realm realm,
@@ -36,18 +34,21 @@ namespace Jint.Native.Promise
             _prototypeDescriptor = new PropertyDescriptor(PrototypeObject, PropertyFlag.AllForbidden);
         }
 
+        internal PromisePrototype PrototypeObject { get; }
+
         protected override void Initialize()
         {
-            const PropertyFlag propertyFlags = PropertyFlag.Configurable | PropertyFlag.Writable;
-            const PropertyFlag lengthFlags = PropertyFlag.Configurable;
+            const PropertyFlag PropertyFlags = PropertyFlag.Configurable | PropertyFlag.Writable;
+            const PropertyFlag LengthFlags = PropertyFlag.Configurable;
             var properties = new PropertyDictionary(6, checkExistingKeys: false)
             {
-                ["resolve"] = new(new PropertyDescriptor(new ClrFunctionInstance(Engine, "resolve", Resolve, 1, lengthFlags), propertyFlags)),
-                ["reject"] = new(new PropertyDescriptor(new ClrFunctionInstance(Engine, "reject", Reject, 1, lengthFlags), propertyFlags)),
-                ["all"] = new(new PropertyDescriptor(new ClrFunctionInstance(Engine, "all", All, 1, lengthFlags), propertyFlags)),
-                ["allSettled"] = new(new PropertyDescriptor(new ClrFunctionInstance(Engine, "allSettled", AllSettled, 1, lengthFlags), propertyFlags)),
-                ["any"] = new(new PropertyDescriptor(new ClrFunctionInstance(Engine, "any", Any, 1, lengthFlags), propertyFlags)),
-                ["race"] = new(new PropertyDescriptor(new ClrFunctionInstance(Engine, "race", Race, 1, lengthFlags), propertyFlags)),
+                ["all"] = new(new PropertyDescriptor(new ClrFunctionInstance(Engine, "all", All, 1, LengthFlags), PropertyFlags)),
+                ["allSettled"] = new(new PropertyDescriptor(new ClrFunctionInstance(Engine, "allSettled", AllSettled, 1, LengthFlags), PropertyFlags)),
+                ["any"] = new(new PropertyDescriptor(new ClrFunctionInstance(Engine, "any", Any, 1, LengthFlags), PropertyFlags)),
+                ["race"] = new(new PropertyDescriptor(new ClrFunctionInstance(Engine, "race", Race, 1, LengthFlags), PropertyFlags)),
+                ["reject"] = new(new PropertyDescriptor(new ClrFunctionInstance(Engine, "reject", Reject, 1, LengthFlags), PropertyFlags)),
+                ["resolve"] = new(new PropertyDescriptor(new ClrFunctionInstance(Engine, "resolve", Resolve, 1, LengthFlags), PropertyFlags)),
+                ["withResolvers"] = new(new PropertyDescriptor(new ClrFunctionInstance(Engine, "withResolvers", WithResolvers , 0, LengthFlags), PropertyFlags)),
             };
             SetProperties(properties);
 
@@ -113,6 +114,16 @@ namespace Jint.Native.Promise
             return PromiseResolve(thisObject, x);
         }
 
+        private JsValue WithResolvers(JsValue thisObject, JsValue[] arguments)
+        {
+            var promiseCapability = NewPromiseCapability(_engine, thisObject);
+            var obj = OrdinaryObjectCreate(_engine, _engine.Realm.Intrinsics.Object.PrototypeObject);
+            obj.CreateDataPropertyOrThrow("promise", promiseCapability.PromiseInstance);
+            obj.CreateDataPropertyOrThrow("resolve", promiseCapability.ResolveObj);
+            obj.CreateDataPropertyOrThrow("reject", promiseCapability.RejectObj);
+            return obj;
+        }
+
         /// <summary>
         /// https://tc39.es/ecma262/#sec-promise-resolve
         /// </summary>

+ 0 - 1
Jint/Native/Proxy/JsProxy.cs

@@ -2,7 +2,6 @@ using Jint.Native.Function;
 using Jint.Native.Object;
 using Jint.Runtime;
 using Jint.Runtime.Descriptors;
-using Jint.Runtime.Interop;
 
 namespace Jint.Native.Proxy
 {

+ 2 - 0
Jint/Native/RegExp/JsRegExp.cs

@@ -74,6 +74,8 @@ namespace Jint.Native.RegExp
         public bool FullUnicode { get; private set; }
         public bool UnicodeSets { get; private set; }
 
+        internal bool HasDefaultRegExpExec => Properties == null && Prototype is RegExpPrototype { HasDefaultExec: true };
+
         public override PropertyDescriptor GetOwnProperty(JsValue property)
         {
             if (property == PropertyLastIndex)

+ 2 - 23
Jint/Native/RegExp/RegExpExtensions.cs

@@ -1,26 +1,5 @@
-using System.Diagnostics.CodeAnalysis;
-using Jint.Native.Object;
+namespace Jint.Native.RegExp;
 
-namespace Jint.Native.RegExp
+internal static class RegExpExtensions
 {
-    internal static class RegExpExtensions
-    {
-        internal static bool TryGetDefaultRegExpExec(this ObjectInstance? o, [NotNullWhen(true)] out Func<JsValue, JsValue[], JsValue>? exec)
-        {
-            if (o is RegExpPrototype prototype)
-            {
-                return prototype.TryGetDefaultExec(prototype, out exec);
-            }
-
-            if (o is JsRegExp instance)
-            {
-                exec = default;
-                return instance.Properties == null
-                       && TryGetDefaultRegExpExec(instance.Prototype, out exec);
-            }
-
-            exec = default;
-            return false;
-        }
-    }
 }

+ 8 - 19
Jint/Native/RegExp/RegExpPrototype.cs

@@ -1,5 +1,4 @@
-using System.Diagnostics.CodeAnalysis;
-using System.Text.RegularExpressions;
+using System.Text.RegularExpressions;
 using Jint.Collections;
 using Jint.Native.Number;
 using Jint.Native.Object;
@@ -158,7 +157,7 @@ namespace Jint.Native.RegExp
             if (!fullUnicode
                 && !mayHaveNamedCaptures
                 && !TypeConverter.ToBoolean(rx.Get(PropertySticky))
-                && rx is JsRegExp rei && rei.TryGetDefaultRegExpExec(out _))
+                && rx is JsRegExp rei && rei.HasDefaultRegExpExec)
             {
                 var count = global ? int.MaxValue : 1;
 
@@ -464,7 +463,7 @@ namespace Jint.Native.RegExp
                 return a;
             }
 
-            if (!unicodeMatching && rx is JsRegExp R && R.TryGetDefaultRegExpExec(out _))
+            if (!unicodeMatching && rx is JsRegExp R && R.HasDefaultRegExpExec)
             {
                 // we can take faster path
 
@@ -690,7 +689,7 @@ namespace Jint.Native.RegExp
 
             if (!fullUnicode
                 && rx is JsRegExp rei
-                && rei.TryGetDefaultRegExpExec(out _))
+                && rei.HasDefaultRegExpExec)
             {
                 // fast path
                 var a = _realm.Intrinsics.Array.ArrayCreate(0);
@@ -812,8 +811,9 @@ namespace Jint.Native.RegExp
 
         internal static JsValue RegExpExec(ObjectInstance r, string s)
         {
-            var exec = r.Get(PropertyExec);
-            if (exec is ICallable callable)
+            var ri = r as JsRegExp;
+
+            if ((ri is null || !ri.HasDefaultRegExpExec) && r.Get(PropertyExec) is ICallable callable)
             {
                 var result = callable.Call(r, new JsValue[] { s });
                 if (!result.IsNull() && !result.IsObject())
@@ -824,7 +824,6 @@ namespace Jint.Native.RegExp
                 return result;
             }
 
-            var ri = r as JsRegExp;
             if (ri is null)
             {
                 ExceptionHelper.ThrowTypeError(r.Engine.Realm);
@@ -833,17 +832,7 @@ namespace Jint.Native.RegExp
             return RegExpBuiltinExec(ri, s);
         }
 
-        internal bool TryGetDefaultExec(ObjectInstance o, [NotNullWhen((true))] out Func<JsValue, JsValue[], JsValue>? exec)
-        {
-            if (o.Get(PropertyExec) is ClrFunctionInstance functionInstance && functionInstance._func == _defaultExec)
-            {
-                exec = _defaultExec;
-                return true;
-            }
-
-            exec = default;
-            return false;
-        }
+        internal bool HasDefaultExec => Get(PropertyExec) is ClrFunctionInstance functionInstance && functionInstance._func == _defaultExec;
 
         /// <summary>
         /// https://tc39.es/ecma262/#sec-regexpbuiltinexec

+ 1 - 0
README.md

@@ -109,6 +109,7 @@ Following features are supported in version 3.x.
 #### ECMAScript Stage 3 (no version yet)
 
 - ✔ Array Grouping - `Object.groupBy` and `Map.groupBy`
+- ✔ Promise.withResolvers
 - ✔ ShadowRealm
 
 #### Other