Browse Source

Implement `Atomics.pause` (#3956)

pull/3969/head
José Julián Espina 3 months ago committed by GitHub
parent
commit
af4fd5ab37
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 54
      core/engine/src/builtins/atomics/mod.rs
  2. 4
      test262_config.toml

54
core/engine/src/builtins/atomics/mod.rs

@ -38,7 +38,7 @@ impl IntrinsicObject for Atomics {
fn init(realm: &Realm) { fn init(realm: &Realm) {
let _timer = Profiler::global().start_event(std::any::type_name::<Self>(), "init"); let _timer = Profiler::global().start_event(std::any::type_name::<Self>(), "init");
BuiltInBuilder::with_intrinsic::<Self>(realm) let builder = BuiltInBuilder::with_intrinsic::<Self>(realm)
.static_property( .static_property(
JsSymbol::to_string_tag(), JsSymbol::to_string_tag(),
Self::NAME, Self::NAME,
@ -55,8 +55,12 @@ impl IntrinsicObject for Atomics {
.static_method(Atomics::sub, js_string!("sub"), 3) .static_method(Atomics::sub, js_string!("sub"), 3)
.static_method(Atomics::wait, js_string!("wait"), 4) .static_method(Atomics::wait, js_string!("wait"), 4)
.static_method(Atomics::notify, js_string!("notify"), 3) .static_method(Atomics::notify, js_string!("notify"), 3)
.static_method(Atomics::bit_xor, js_string!("xor"), 3) .static_method(Atomics::bit_xor, js_string!("xor"), 3);
.build();
#[cfg(feature = "experimental")]
let builder = builder.static_method(Atomics::pause, js_string!("pause"), 0);
builder.build();
} }
fn get(intrinsics: &Intrinsics) -> JsObject { fn get(intrinsics: &Intrinsics) -> JsObject {
@ -512,6 +516,50 @@ impl Atomics {
// 13. Return 𝔽(n). // 13. Return 𝔽(n).
Ok(count.into()) Ok(count.into())
} }
/// [`Atomics.pause ( [ iterationNumber ] )`][spec]
///
/// [spec]: https://tc39.es/proposal-atomics-microwait/#Atomics.pause
#[cfg(feature = "experimental")]
fn pause(_: &JsValue, args: &[JsValue], context: &mut Context) -> JsResult<JsValue> {
use super::Number;
let iteration_number = args.get_or_undefined(0);
// 1. If iterationNumber is not undefined, then
let iterations = if iteration_number.is_undefined() {
1
} else {
// a. If iterationNumber is not an integral Number, throw a TypeError exception.
if !Number::is_integer(iteration_number) {
return Err(JsNativeError::typ()
.with_message("`iterationNumber` must be an integral Number")
.into());
}
// b. If ℝ(iterationNumber) < 0, throw a RangeError exception.
let iteration_number = iteration_number.to_number(context)? as i16;
if iteration_number < 0 {
return Err(JsNativeError::range()
.with_message("`iterationNumber` must be a positive integer")
.into());
}
// Clamp to u16 so that the main thread cannot block using this.
iteration_number as u16
};
// 2. If the execution environment of the ECMAScript implementation supports a signal that the current executing code
// is in a spin-wait loop, send that signal. An ECMAScript implementation may send that signal multiple times,
// determined by iterationNumber when not undefined. The number of times the signal is sent for an integral Number
// N is at most the number of times it is sent for N + 1.
for _ in 0..iterations {
std::hint::spin_loop();
}
// 3. Return undefined.
Ok(JsValue::undefined())
}
} }
/// [`ValidateIntegerTypedArray ( typedArray, waitable )`][spec] /// [`ValidateIntegerTypedArray ( typedArray, waitable )`][spec]

4
test262_config.toml

@ -65,10 +65,6 @@ features = [
# https://github.com/tc39/proposal-arraybuffer-base64 # https://github.com/tc39/proposal-arraybuffer-base64
"uint8array-base64", "uint8array-base64",
# Atomics.pause
# https://github.com/tc39/proposal-atomics-microwait
"Atomics.pause",
### Non-standard ### Non-standard
"caller", "caller",
] ]

Loading…
Cancel
Save