Skip to content

Commit

Permalink
Implement Atomics.pause (#1929)
Browse files Browse the repository at this point in the history
  • Loading branch information
lahma authored Jul 29, 2024
1 parent 81babf2 commit 39f7c6f
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 2 deletions.
3 changes: 2 additions & 1 deletion Jint.Tests.Test262/Test262Harness.settings.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"SuiteGitSha": "b8cb40b66a61afd57550a84f4170e16ebfbd1e46",
"SuiteGitSha": "242f6f98f0f86c0a3276929b4a450438526057cb",
//"SuiteDirectory": "//mnt/c/work/test262",
"TargetPath": "./Generated",
"Namespace": "Jint.Tests.Test262",
Expand All @@ -16,6 +16,7 @@
"regexp-modifiers",
"regexp-unicode-property-escapes",
"regexp-v-flag",
"RegExp.escape",
"source-phase-imports",
"tail-call-optimization",
"Temporal",
Expand Down
66 changes: 66 additions & 0 deletions Jint/Native/Atomics/AtomicsInstance.cs
Original file line number Diff line number Diff line change
@@ -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;

/// <summary>
/// https://tc39.es/ecma262/#sec-atomics-object
/// </summary>
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;
}
}
2 changes: 1 addition & 1 deletion Jint/Native/Global/GlobalObject.Properties.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ protected override void Initialize()
properties.AddDangerous(propertyAggregateError, new LazyPropertyDescriptor<GlobalObject>(this, static global => global._realm.Intrinsics.AggregateError, PropertyFlags));
properties.AddDangerous(propertyArray, new LazyPropertyDescriptor<GlobalObject>(this, static global => global._realm.Intrinsics.Array, PropertyFlags));
properties.AddDangerous(propertyArrayBuffer, new LazyPropertyDescriptor<GlobalObject>(this, static global => global._realm.Intrinsics.ArrayBuffer, PropertyFlags));
properties.AddDangerous(propertyAtomics, new LazyPropertyDescriptor<GlobalObject>(this, static _ => Undefined, PropertyFlags));
properties.AddDangerous(propertyAtomics, new LazyPropertyDescriptor<GlobalObject>(this, static global => global._realm.Intrinsics.Atomics, PropertyFlags));
properties.AddDangerous(propertyBigInt, new LazyPropertyDescriptor<GlobalObject>(this, static global => global._realm.Intrinsics.BigInt, PropertyFlags));
properties.AddDangerous(propertyBigInt64Array, new LazyPropertyDescriptor<GlobalObject>(this, static global => global._realm.Intrinsics.BigInt64Array, PropertyFlags));
properties.AddDangerous(propertyBigUint64Array, new LazyPropertyDescriptor<GlobalObject>(this, static global => global._realm.Intrinsics.BigUint64Array, PropertyFlags));
Expand Down
5 changes: 5 additions & 0 deletions Jint/Runtime/Intrinsics.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);

Expand Down

0 comments on commit 39f7c6f

Please sign in to comment.