diff --git a/Jint.Tests.PublicInterface/ShadowRealmTests.cs b/Jint.Tests.PublicInterface/ShadowRealmTests.cs
index 1740def1c5..f0d062d506 100644
--- a/Jint.Tests.PublicInterface/ShadowRealmTests.cs
+++ b/Jint.Tests.PublicInterface/ShadowRealmTests.cs
@@ -1,4 +1,3 @@
-using Jint.Native;
using Jint.Native.Object;
namespace Jint.Tests.PublicInterface;
diff --git a/Jint.Tests.Test262/Test262Harness.settings.json b/Jint.Tests.Test262/Test262Harness.settings.json
index 88fa50bd24..f6ac59bf09 100644
--- a/Jint.Tests.Test262/Test262Harness.settings.json
+++ b/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",
diff --git a/Jint/Native/Promise/PromiseConstructor.cs b/Jint/Native/Promise/PromiseConstructor.cs
index 63d7d3b568..56b227b4e6 100644
--- a/Jint/Native/Promise/PromiseConstructor.cs
+++ b/Jint/Native/Promise/PromiseConstructor.cs
@@ -21,8 +21,6 @@ internal sealed class PromiseConstructor : Constructor
{
private static readonly JsString _functionName = new JsString("Promise");
- internal PromisePrototype PrototypeObject { get; private set; }
-
internal PromiseConstructor(
Engine engine,
Realm realm,
@@ -36,18 +34,21 @@ internal PromiseConstructor(
_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 @@ internal JsValue Resolve(JsValue thisObject, JsValue[] arguments)
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;
+ }
+
///
/// https://tc39.es/ecma262/#sec-promise-resolve
///
diff --git a/Jint/Native/Proxy/JsProxy.cs b/Jint/Native/Proxy/JsProxy.cs
index 1607632b32..386d70a695 100644
--- a/Jint/Native/Proxy/JsProxy.cs
+++ b/Jint/Native/Proxy/JsProxy.cs
@@ -2,7 +2,6 @@
using Jint.Native.Object;
using Jint.Runtime;
using Jint.Runtime.Descriptors;
-using Jint.Runtime.Interop;
namespace Jint.Native.Proxy
{
diff --git a/Jint/Native/RegExp/JsRegExp.cs b/Jint/Native/RegExp/JsRegExp.cs
index 629fabae0f..62f5886cdd 100644
--- a/Jint/Native/RegExp/JsRegExp.cs
+++ b/Jint/Native/RegExp/JsRegExp.cs
@@ -74,6 +74,8 @@ public string Flags
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)
diff --git a/Jint/Native/RegExp/RegExpExtensions.cs b/Jint/Native/RegExp/RegExpExtensions.cs
index 927f8be297..aa27b6bb8e 100644
--- a/Jint/Native/RegExp/RegExpExtensions.cs
+++ b/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? 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;
- }
- }
}
diff --git a/Jint/Native/RegExp/RegExpPrototype.cs b/Jint/Native/RegExp/RegExpPrototype.cs
index 7912a64859..279f229a53 100644
--- a/Jint/Native/RegExp/RegExpPrototype.cs
+++ b/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 @@ private JsValue Replace(JsValue thisObject, JsValue[] arguments)
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 @@ private JsValue Split(JsValue thisObject, JsValue[] arguments)
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 @@ private JsValue Match(JsValue thisObject, JsValue[] arguments)
if (!fullUnicode
&& rx is JsRegExp rei
- && rei.TryGetDefaultRegExpExec(out _))
+ && rei.HasDefaultRegExpExec)
{
// fast path
var a = _realm.Intrinsics.Array.ArrayCreate(0);
@@ -812,8 +811,9 @@ private static ulong AdvanceStringIndex(string s, ulong index, bool unicode)
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 @@ internal static JsValue RegExpExec(ObjectInstance r, string s)
return result;
}
- var ri = r as JsRegExp;
if (ri is null)
{
ExceptionHelper.ThrowTypeError(r.Engine.Realm);
@@ -833,17 +832,7 @@ internal static JsValue RegExpExec(ObjectInstance r, string s)
return RegExpBuiltinExec(ri, s);
}
- internal bool TryGetDefaultExec(ObjectInstance o, [NotNullWhen((true))] out Func? 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;
///
/// https://tc39.es/ecma262/#sec-regexpbuiltinexec
diff --git a/README.md b/README.md
index edaaf5a8df..93113e6778 100644
--- a/README.md
+++ b/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