From 31b420f8a819c9e393bde4e7da2704dffbfd2e19 Mon Sep 17 00:00:00 2001 From: Marko Lahma Date: Mon, 29 Jul 2024 12:45:24 +0300 Subject: [PATCH] Implement Atomics.pause --- .../Test262Harness.settings.json | 3 +- Jint/Native/Atomics/AtomicsInstance.cs | 66 +++++++++++++++++++ Jint/Native/Global/GlobalObject.Properties.cs | 2 +- Jint/Runtime/Intrinsics.cs | 5 ++ 4 files changed, 74 insertions(+), 2 deletions(-) create mode 100644 Jint/Native/Atomics/AtomicsInstance.cs diff --git a/Jint.Tests.Test262/Test262Harness.settings.json b/Jint.Tests.Test262/Test262Harness.settings.json index a3d00b76d9..3a024d97eb 100644 --- a/Jint.Tests.Test262/Test262Harness.settings.json +++ b/Jint.Tests.Test262/Test262Harness.settings.json @@ -1,5 +1,5 @@ { - "SuiteGitSha": "b8cb40b66a61afd57550a84f4170e16ebfbd1e46", + "SuiteGitSha": "242f6f98f0f86c0a3276929b4a450438526057cb", //"SuiteDirectory": "//mnt/c/work/test262", "TargetPath": "./Generated", "Namespace": "Jint.Tests.Test262", @@ -16,6 +16,7 @@ "regexp-modifiers", "regexp-unicode-property-escapes", "regexp-v-flag", + "RegExp.escape", "source-phase-imports", "tail-call-optimization", "Temporal", diff --git a/Jint/Native/Atomics/AtomicsInstance.cs b/Jint/Native/Atomics/AtomicsInstance.cs new file mode 100644 index 0000000000..48bd202b67 --- /dev/null +++ b/Jint/Native/Atomics/AtomicsInstance.cs @@ -0,0 +1,66 @@ +using System.Numerics; +using System.Threading; +using Jint.Collections; +using Jint.Native.Object; +using Jint.Runtime; +using Jint.Runtime.Descriptors; +using Jint.Runtime.Interop; + +namespace Jint.Native.Atomics; + +/// +/// https://tc39.es/ecma262/#sec-atomics-object +/// +internal sealed class AtomicsInstance : ObjectInstance +{ + private readonly Realm _realm; + + public AtomicsInstance( + Engine engine, + Realm realm, + ObjectPrototype objectPrototype) : base(engine) + { + _realm = realm; + _prototype = objectPrototype; + } + + protected override void Initialize() + { + var properties = new PropertyDictionary(1, checkExistingKeys: false) + { + ["pause"] = new(new ClrFunction(Engine, "pause", Pause, 0, PropertyFlag.Configurable), true, false, true), + }; + SetProperties(properties); + } + + private JsValue Pause(JsValue thisObject, JsValue[] arguments) + { + var iterationNumber = arguments.At(0); + if (!iterationNumber.IsUndefined()) + { + if (!iterationNumber.IsNumber()) + { + ExceptionHelper.ThrowTypeError(_realm, "Invalid iteration count"); + } + + var n = TypeConverter.ToNumber(iterationNumber); + if (!TypeConverter.IsIntegralNumber(n)) + { + ExceptionHelper.ThrowTypeError(_realm, "Invalid iteration count"); + } + + if (n < 0) + { + ExceptionHelper.ThrowRangeError(_realm, "Invalid iteration count"); + } + + Thread.SpinWait((int) n); + } + else + { + Thread.SpinWait(1); + } + + return Undefined; + } +} diff --git a/Jint/Native/Global/GlobalObject.Properties.cs b/Jint/Native/Global/GlobalObject.Properties.cs index bd9de9e652..8a94dfb471 100644 --- a/Jint/Native/Global/GlobalObject.Properties.cs +++ b/Jint/Native/Global/GlobalObject.Properties.cs @@ -86,7 +86,7 @@ protected override void Initialize() properties.AddDangerous(propertyAggregateError, new LazyPropertyDescriptor(this, static global => global._realm.Intrinsics.AggregateError, PropertyFlags)); properties.AddDangerous(propertyArray, new LazyPropertyDescriptor(this, static global => global._realm.Intrinsics.Array, PropertyFlags)); properties.AddDangerous(propertyArrayBuffer, new LazyPropertyDescriptor(this, static global => global._realm.Intrinsics.ArrayBuffer, PropertyFlags)); - properties.AddDangerous(propertyAtomics, new LazyPropertyDescriptor(this, static _ => Undefined, PropertyFlags)); + properties.AddDangerous(propertyAtomics, new LazyPropertyDescriptor(this, static global => global._realm.Intrinsics.Atomics, PropertyFlags)); properties.AddDangerous(propertyBigInt, new LazyPropertyDescriptor(this, static global => global._realm.Intrinsics.BigInt, PropertyFlags)); properties.AddDangerous(propertyBigInt64Array, new LazyPropertyDescriptor(this, static global => global._realm.Intrinsics.BigInt64Array, PropertyFlags)); properties.AddDangerous(propertyBigUint64Array, new LazyPropertyDescriptor(this, static global => global._realm.Intrinsics.BigUint64Array, PropertyFlags)); diff --git a/Jint/Runtime/Intrinsics.cs b/Jint/Runtime/Intrinsics.cs index 26b603a758..fa524e52a0 100644 --- a/Jint/Runtime/Intrinsics.cs +++ b/Jint/Runtime/Intrinsics.cs @@ -3,6 +3,7 @@ using Jint.Native.Array; using Jint.Native.ArrayBuffer; using Jint.Native.AsyncFunction; +using Jint.Native.Atomics; using Jint.Native.BigInt; using Jint.Native.Boolean; using Jint.Native.DataView; @@ -82,6 +83,7 @@ public sealed partial class Intrinsics private SetIteratorPrototype? _setIteratorPrototype; private ArrayConstructor? _array; private ArrayIteratorPrototype? _arrayIteratorPrototype; + private AtomicsInstance? _atomics; private BooleanConstructor? _boolean; private ArrayBufferConstructor? _arrayBufferConstructor; private SharedArrayBufferConstructor? _sharedArrayBufferConstructor; @@ -133,6 +135,9 @@ internal Intrinsics(Engine engine, Realm realm) public ArrayConstructor Array => _array ??= new ArrayConstructor(_engine, _realm, Function.PrototypeObject, Object.PrototypeObject); + internal AtomicsInstance Atomics => + _atomics ??= new AtomicsInstance(_engine, _realm, Object.PrototypeObject); + internal AggregateErrorConstructor AggregateError => _aggregateError ??= new AggregateErrorConstructor(_engine, _realm, Error);