AtomicsInstance.cs 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. using System.Threading;
  2. using Jint.Collections;
  3. using Jint.Native.Object;
  4. using Jint.Runtime;
  5. using Jint.Runtime.Descriptors;
  6. using Jint.Runtime.Interop;
  7. namespace Jint.Native.Atomics;
  8. /// <summary>
  9. /// https://tc39.es/ecma262/#sec-atomics-object
  10. /// </summary>
  11. internal sealed class AtomicsInstance : ObjectInstance
  12. {
  13. private readonly Realm _realm;
  14. public AtomicsInstance(
  15. Engine engine,
  16. Realm realm,
  17. ObjectPrototype objectPrototype) : base(engine)
  18. {
  19. _realm = realm;
  20. _prototype = objectPrototype;
  21. }
  22. protected override void Initialize()
  23. {
  24. var properties = new PropertyDictionary(1, checkExistingKeys: false)
  25. {
  26. ["pause"] = new(new ClrFunction(Engine, "pause", Pause, 0, PropertyFlag.Configurable), true, false, true),
  27. };
  28. SetProperties(properties);
  29. }
  30. private JsValue Pause(JsValue thisObject, JsCallArguments arguments)
  31. {
  32. var iterationNumber = arguments.At(0);
  33. if (!iterationNumber.IsUndefined())
  34. {
  35. if (!iterationNumber.IsNumber())
  36. {
  37. ExceptionHelper.ThrowTypeError(_realm, "Invalid iteration count");
  38. }
  39. var n = TypeConverter.ToNumber(iterationNumber);
  40. if (!TypeConverter.IsIntegralNumber(n))
  41. {
  42. ExceptionHelper.ThrowTypeError(_realm, "Invalid iteration count");
  43. }
  44. if (n < 0)
  45. {
  46. ExceptionHelper.ThrowRangeError(_realm, "Invalid iteration count");
  47. }
  48. n = System.Math.Min(n, _engine.Options.Constraints.MaxAtomicsPauseIterations);
  49. Thread.SpinWait((int) n);
  50. }
  51. else
  52. {
  53. Thread.SpinWait(1);
  54. }
  55. return Undefined;
  56. }
  57. }