diff --git a/nova_vm/src/ecmascript/abstract_operations/type_conversion.rs b/nova_vm/src/ecmascript/abstract_operations/type_conversion.rs index 47bab5a61..488dc44c8 100644 --- a/nova_vm/src/ecmascript/abstract_operations/type_conversion.rs +++ b/nova_vm/src/ecmascript/abstract_operations/type_conversion.rs @@ -14,6 +14,8 @@ //! The BigInt type has no implicit conversions in the ECMAScript language; //! programmers must call BigInt explicitly to convert values from other types. +use num_bigint::Sign; + use crate::engine::context::GcScope; use crate::{ ecmascript::{ @@ -707,6 +709,77 @@ pub(crate) fn string_to_big_int(_agent: &mut Agent, _argument: String) -> Option todo!("string_to_big_int: Implement BigInts") } +/// ### [7.1.15 ToBigInt64 ( argument )](https://tc39.es/ecma262/#sec-tobigint64) +/// +/// The abstract operation ToBigInt64 takes argument argument (an ECMAScript +/// language value) and returns either a normal completion containing a BigInt +/// or a throw completion. It converts argument to one of 2**64 BigInt values +/// in the inclusive interval from ℤ(-2**63) to ℤ(2**63 - 1). +#[inline(always)] +pub(crate) fn to_big_int64( + agent: &mut Agent, + gc: GcScope<'_, '_>, + argument: Value, +) -> JsResult { + // 1. Let n be ? ToBigInt(argument). + let n = to_big_int(agent, gc, argument)?; + + // 2. Let int64bit be ℝ(n) modulo 2**64. + match n { + BigInt::BigInt(heap_big_int) => { + // 3. If int64bit ≥ 2**63, return ℤ(int64bit - 2**64); otherwise return ℤ(int64bit). + let big_int = &agent[heap_big_int].data; + let int64bit = big_int.iter_u64_digits().next().unwrap_or(0); + let int64bit = if big_int.sign() == Sign::Minus { + u64::MAX - int64bit + 1 + } else { + int64bit + }; + let int64bit = i64::from_ne_bytes(int64bit.to_ne_bytes()); + Ok(int64bit) + } + BigInt::SmallBigInt(small_big_int) => { + let int64bit = small_big_int.into_i64(); + Ok(int64bit) + } + } +} + +/// ### [7.1.16 ToBigUint64 ( argument )](https://tc39.es/ecma262/#sec-tobiguint64) +/// +/// The abstract operation ToBigUint64 takes argument argument (an ECMAScript +/// language value) and returns either a normal completion containing a BigInt +/// or a throw completion. It converts argument to one of 2**64 BigInt values +/// in the inclusive interval from 0ℤ to ℤ(2**64 - 1). +#[inline(always)] +pub(crate) fn to_big_uint64( + agent: &mut Agent, + gc: GcScope<'_, '_>, + argument: Value, +) -> JsResult { + // 1. Let n be ? ToBigInt(argument). + let n = to_big_int(agent, gc, argument)?; + + // 2. Let int64bit be ℝ(n) modulo 2**64. + match n { + BigInt::BigInt(heap_big_int) => { + // https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=7d82adfe85f7d0ed44ab37a7b2cdf092 + let big_int = &agent[heap_big_int].data; + let int64bit = big_int.iter_u64_digits().next().unwrap_or(0); + let int64bit = if big_int.sign() == Sign::Minus { + u64::MAX - int64bit + 1 + } else { + int64bit + }; + Ok(int64bit) + } + BigInt::SmallBigInt(small_big_int) => { + let int64bit = small_big_int.into_i64(); + Ok(int64bit as u64) + } + } +} + /// ### [7.1.17 ToString ( argument )](https://tc39.es/ecma262/#sec-tostring) pub(crate) fn to_string( agent: &mut Agent, diff --git a/nova_vm/src/ecmascript/builtins/array_buffer.rs b/nova_vm/src/ecmascript/builtins/array_buffer.rs index 220cc4f3d..8c1c3070a 100644 --- a/nova_vm/src/ecmascript/builtins/array_buffer.rs +++ b/nova_vm/src/ecmascript/builtins/array_buffer.rs @@ -20,8 +20,8 @@ use crate::{ }; pub(crate) use abstract_operations::{ - allocate_array_buffer, array_buffer_byte_length, is_detached_buffer, - is_fixed_length_array_buffer, Ordering, + allocate_array_buffer, array_buffer_byte_length, get_value_from_buffer, is_detached_buffer, + is_fixed_length_array_buffer, set_value_in_buffer, Ordering, }; pub use data::ArrayBufferHeapData; use std::ops::{Index, IndexMut}; diff --git a/nova_vm/src/ecmascript/builtins/array_buffer/abstract_operations.rs b/nova_vm/src/ecmascript/builtins/array_buffer/abstract_operations.rs index 5fd63b4c2..93a9edaa0 100644 --- a/nova_vm/src/ecmascript/builtins/array_buffer/abstract_operations.rs +++ b/nova_vm/src/ecmascript/builtins/array_buffer/abstract_operations.rs @@ -3,6 +3,7 @@ // file, You can obtain one at https://mozilla.org/MPL/2.0/. use super::{ArrayBuffer, ArrayBufferHeapData}; +use crate::ecmascript::types::Viewable; use crate::engine::context::GcScope; use crate::{ ecmascript::{ @@ -314,7 +315,11 @@ pub(crate) const fn is_no_tear_configuration(r#type: (), order: Ordering) -> boo /// The abstract operation RawBytesToNumeric takes arguments type (a /// TypedArray element type), rawBytes (a List of byte values), and /// isLittleEndian (a Boolean) and returns a Number or a BigInt. -pub(crate) const fn raw_bytes_to_numeric(_type: (), _raw_bytes: &[u8], _is_little_endian: bool) { +pub(crate) fn raw_bytes_to_numeric( + agent: &mut Agent, + raw_bytes: T, + is_little_endian: bool, +) -> Value { // 1. Let elementSize be the Element Size value specified in Table 71 for Element Type type. // 2. If isLittleEndian is false, reverse the order of the elements of rawBytes. // 3. If type is FLOAT32, then @@ -331,6 +336,11 @@ pub(crate) const fn raw_bytes_to_numeric(_type: (), _raw_bytes: &[u8], _is_littl // a. Let intValue be the byte elements of rawBytes concatenated and interpreted as a bit string encoding of a binary little-endian two's complement number of bit length elementSize × 8. // 7. If IsBigIntElementType(type) is true, return the BigInt value that corresponds to intValue. // 8. Otherwise, return the Number value that corresponds to intValue. + if is_little_endian { + raw_bytes.into_le_value(agent) + } else { + raw_bytes.into_be_value(agent) + } } /// ### [25.1.3.14 GetRawBytesFromSharedBlock ( block, byteIndex, type, isTypedArray, order )](https://tc39.es/ecma262/#sec-getrawbytesfromsharedblock) @@ -366,18 +376,20 @@ pub(crate) fn get_raw_bytes_from_shared_block( /// integer), type (a TypedArray element type), isTypedArray (a Boolean), /// and order (SEQ-CST or UNORDERED) and optional argument isLittleEndian /// (a Boolean) and returns a Number or a BigInt. -pub(crate) fn get_value_from_buffer( - _array_buffer: ArrayBuffer, - _byte_index: u32, - _type: (), +pub(crate) fn get_value_from_buffer( + agent: &mut Agent, + array_buffer: ArrayBuffer, + byte_index: usize, _is_typed_array: bool, _order: Ordering, - _is_little_endian: Option, -) { + is_little_endian: Option, +) -> Value { // 1. Assert: IsDetachedBuffer(arrayBuffer) is false. + debug_assert!(!array_buffer.is_detached(agent)); // 2. Assert: There are sufficient bytes in arrayBuffer starting at byteIndex to represent a value of type. - // 3. Let block be arrayBuffer.[[ArrayBufferData]]. // 4. Let elementSize be the Element Size value specified in Table 71 for Element Type type. + // 3. Let block be arrayBuffer.[[ArrayBufferData]]. + let block = agent[array_buffer].get_data_block(); // 5. If IsSharedArrayBuffer(arrayBuffer) is true, then // a. Assert: block is a Shared Data Block. // b. Let rawValue be GetRawBytesFromSharedBlock(block, byteIndex, type, isTypedArray, order). @@ -385,7 +397,23 @@ pub(crate) fn get_value_from_buffer( // a. Let rawValue be a List whose elements are bytes from block at indices in the interval from byteIndex (inclusive) to byteIndex + elementSize (exclusive). // 7. Assert: The number of elements in rawValue is elementSize. // 8. If isLittleEndian is not present, set isLittleEndian to the value of the [[LittleEndian]] field of the surrounding agent's Agent Record. + let is_little_endian = is_little_endian.unwrap_or({ + #[cfg(target_endian = "little")] + { + true + } + #[cfg(target_endian = "big")] + { + false + } + }); + // 9. Return RawBytesToNumeric(type, rawValue, isLittleEndian). + raw_bytes_to_numeric::( + agent, + block.get_offset_by_byte::(byte_index).unwrap(), + is_little_endian, + ) } /// ### [25.1.3.16 NumericToRawBytes ( type, value, isLittleEndian )](https://tc39.es/ecma262/#sec-numerictorawbytes) @@ -393,12 +421,12 @@ pub(crate) fn get_value_from_buffer( /// The abstract operation NumericToRawBytes takes arguments type (a /// TypedArray element type), value (a Number or a BigInt), and /// isLittleEndian (a Boolean) and returns a List of byte values. -pub(crate) fn numeric_to_raw_bytes( - _array_buffer: ArrayBuffer, - _type: (), - _value: Number, - _is_little_endian: bool, -) { +pub(crate) fn numeric_to_raw_bytes( + agent: &mut Agent, + gc: GcScope<'_, '_>, + value: Value, + is_little_endian: bool, +) -> T { // 1. If type is FLOAT32, then // a. Let rawBytes be a List whose elements are the 4 bytes that are the result of converting value to IEEE 754-2019 binary32 format using roundTiesToEven mode. The bytes are arranged in little endian order. If value is NaN, rawBytes may be set to any implementation chosen IEEE 754-2019 binary32 format Not-a-Number encoding. An implementation must always choose the same encoding for each implementation distinguishable NaN value. // 2. Else if type is FLOAT64, then @@ -413,6 +441,11 @@ pub(crate) fn numeric_to_raw_bytes( // i. Let rawBytes be a List whose elements are the n-byte binary two's complement encoding of intValue. The bytes are ordered in little endian order. // 4. If isLittleEndian is false, reverse the order of the elements of rawBytes. // 5. Return rawBytes. + if is_little_endian { + T::from_le_value(agent, gc, value) + } else { + T::from_be_value(agent, gc, value) + } } /// ### [25.1.3.17 SetValueInBuffer ( arrayBuffer, byteIndex, type, value, isTypedArray, order \[ , isLittleEndian \] )](https://tc39.es/ecma262/#sec-setvalueinbuffer) @@ -422,29 +455,49 @@ pub(crate) fn numeric_to_raw_bytes( /// type (a TypedArray element type), value (a Number or a BigInt), /// isTypedArray (a Boolean), and order (SEQ-CST, UNORDERED, or INIT) and /// optional argument isLittleEndian (a Boolean) and returns UNUSED. -pub(crate) fn set_value_in_buffer( - _array_buffer: ArrayBuffer, - _byte_index: u32, - _type: (), - _value: Value, +#[allow(clippy::too_many_arguments)] +pub(crate) fn set_value_in_buffer( + agent: &mut Agent, + gc: GcScope<'_, '_>, + array_buffer: ArrayBuffer, + byte_index: usize, + value: Value, _is_typed_array: bool, _order: Ordering, - _is_little_endian: Option, + is_little_endian: Option, ) { // 1. Assert: IsDetachedBuffer(arrayBuffer) is false. + debug_assert!(!array_buffer.is_detached(agent)); // 2. Assert: There are sufficient bytes in arrayBuffer starting at byteIndex to represent a value of type. // 3. Assert: value is a BigInt if IsBigIntElementType(type) is true; otherwise, value is a Number. - // 4. Let block be arrayBuffer.[[ArrayBufferData]]. + // 5. Let elementSize be the Element Size value specified in Table 71 for Element Type type. // 6. If isLittleEndian is not present, set isLittleEndian to the value of the [[LittleEndian]] field of the surrounding agent's Agent Record. + let is_little_endian = is_little_endian.unwrap_or({ + #[cfg(target_endian = "little")] + { + true + } + #[cfg(target_endian = "big")] + { + false + } + }); + // 7. Let rawBytes be NumericToRawBytes(type, value, isLittleEndian). + let raw_bytes = numeric_to_raw_bytes::(agent, gc, value, is_little_endian); // 8. If IsSharedArrayBuffer(arrayBuffer) is true, then // a. Let execution be the [[CandidateExecution]] field of the surrounding agent's Agent Record. // b. Let eventsRecord be the Agent Events Record of execution.[[EventsRecords]] whose [[AgentSignifier]] is AgentSignifier(). // c. If isTypedArray is true and IsNoTearConfiguration(type, order) is true, let noTear be true; otherwise let noTear be false. // d. Append WriteSharedMemory { [[Order]]: order, [[NoTear]]: noTear, [[Block]]: block, [[ByteIndex]]: byteIndex, [[ElementSize]]: elementSize, [[Payload]]: rawBytes } to eventsRecord.[[EventList]]. // 9. Else, + + // 4. Let block be arrayBuffer.[[ArrayBufferData]]. + let block = agent[array_buffer].get_data_block_mut(); + // a. Store the individual bytes of rawBytes into block, starting at block[byteIndex]. + block.set_offset_by_byte::(byte_index, raw_bytes); // 10. Return UNUSED. } diff --git a/nova_vm/src/ecmascript/builtins/data_view/abstract_operations.rs b/nova_vm/src/ecmascript/builtins/data_view/abstract_operations.rs index 6eeac1a57..303901b30 100644 --- a/nova_vm/src/ecmascript/builtins/data_view/abstract_operations.rs +++ b/nova_vm/src/ecmascript/builtins/data_view/abstract_operations.rs @@ -1,6 +1,17 @@ -use crate::ecmascript::{ - builtins::array_buffer::{array_buffer_byte_length, is_fixed_length_array_buffer, Ordering}, - execution::Agent, +use crate::{ + ecmascript::{ + abstract_operations::type_conversion::{to_big_int, to_index, to_number}, + builtins::{ + array_buffer::{ + array_buffer_byte_length, get_value_from_buffer, is_fixed_length_array_buffer, + set_value_in_buffer, Ordering, + }, + structured_data::data_view_objects::data_view_prototype::require_internal_slot_data_view, + }, + execution::{agent::ExceptionType, Agent, JsResult}, + types::{IntoValue, Value, Viewable}, + }, + engine::context::GcScope, }; use super::DataView; @@ -65,7 +76,7 @@ pub(crate) fn make_data_view_with_buffer_witness_record( pub(crate) fn get_view_byte_length( agent: &Agent, view_record: &DataViewWithBufferWitnessRecord, -) -> i64 { +) -> usize { // 1. Assert: IsViewOutOfBounds(viewRecord) is false. assert!(!is_view_out_of_bounds(agent, view_record)); @@ -74,7 +85,7 @@ pub(crate) fn get_view_byte_length( // 3. If view.[[ByteLength]] is not auto, return view.[[ByteLength]]. if let Some(byte_length) = view.byte_length(agent) { - return byte_length as i64; + return byte_length; } // NOTE: This assert seems to not be guarding anything important, so it's @@ -94,7 +105,7 @@ pub(crate) fn get_view_byte_length( let byte_length = view_record.cached_buffer_byte_length.0; // 8. Return byteLength - byteOffset. - (byte_length - byte_offset) as i64 + byte_length - byte_offset } /// ### [25.3.1.4 IsViewOutOfBounds ( viewRecord )](https://tc39.es/ecma262/#sec-isviewoutofbounds) @@ -143,3 +154,147 @@ pub(crate) fn is_view_out_of_bounds( // 10. Return false. false } + +/// ### [25.3.1.5 GetViewValue ( view, requestIndex, isLittleEndian, type )](https://tc39.es/ecma262/#sec-getviewvalue) +/// +/// The abstract operation GetViewValue takes arguments view (an ECMAScript +/// language value), requestIndex (an ECMAScript language value), isLittleEndian +/// (an ECMAScript language value), and type (a TypedArray element type) and +/// returns either a normal completion containing either a Number or a BigInt, +/// or a throw completion. It is used by functions on DataView instances to +/// retrieve values from the view's buffer. +pub(crate) fn get_view_value( + agent: &mut Agent, + gc: GcScope<'_, '_>, + view: Value, + request_index: Value, + // 4. Set isLittleEndian to ToBoolean(isLittleEndian). + is_little_endian: bool, +) -> JsResult { + // 1. Perform ? RequireInternalSlot(view, [[DataView]]). + // 2. Assert: view has a [[ViewedArrayBuffer]] internal slot. + let view = require_internal_slot_data_view(agent, view)?; + + // 3. Let getIndex be ? ToIndex(requestIndex). + let get_index = to_index(agent, gc, request_index)? as usize; + // 5. Let viewOffset be view.[[ByteOffset]]. + let view_offset = view.byte_offset(agent); + + // 6. Let viewRecord be MakeDataViewWithBufferWitnessRecord(view, unordered). + let view_record = make_data_view_with_buffer_witness_record(agent, view, Ordering::Unordered); + + // 7. NOTE: Bounds checking is not a synchronizing operation when view's backing buffer is a growable SharedArrayBuffer. + // 8. If IsViewOutOfBounds(viewRecord) is true, throw a TypeError exception. + if is_view_out_of_bounds(agent, &view_record) { + return Err(agent.throw_exception_with_static_message( + ExceptionType::TypeError, + "DataView is out of bounds", + )); + } + + // 9. Let viewSize be GetViewByteLength(viewRecord). + let view_size = get_view_byte_length(agent, &view_record); + + // 10. Let elementSize be the Element Size value specified in Table 69 for Element Type type. + let element_size = size_of::(); + + // 11. If getIndex + elementSize > viewSize, throw a RangeError exception. + if get_index + element_size > view_size { + return Err(agent.throw_exception_with_static_message( + ExceptionType::RangeError, + "Index out of bounds", + )); + } + + // 12. Let bufferIndex be getIndex + viewOffset. + let buffer_index = get_index + view_offset; + + // 13. Return GetValueFromBuffer(view.[[ViewedArrayBuffer]], bufferIndex, type, false, unordered, isLittleEndian). + Ok(get_value_from_buffer::( + agent, + view.get_viewed_array_buffer(agent), + buffer_index, + false, + Ordering::Unordered, + Some(is_little_endian), + )) +} + +/// ### [25.3.1.6 SetViewValue ( view, requestIndex, isLittleEndian, type, value )](https://tc39.es/ecma262/#sec-setviewvalue) +/// +/// The abstract operation SetViewValue takes arguments view (an ECMAScript +/// language value), requestIndex (an ECMAScript language value), isLittleEndian +/// (an ECMAScript language value), type (a TypedArray element type), and value +/// (an ECMAScript language value) and returns either a normal completion +/// containing undefined or a throw completion. It is used by functions on +/// DataView instances to store values into the view's buffer. +pub(crate) fn set_view_value( + agent: &mut Agent, + mut gc: GcScope<'_, '_>, + view: Value, + request_index: Value, + // 6. Set isLittleEndian to ToBoolean(isLittleEndian). + is_little_endian: bool, + value: Value, +) -> JsResult { + // 1. Perform ? RequireInternalSlot(view, [[DataView]]). + // 2. Assert: view has a [[ViewedArrayBuffer]] internal slot. + let view = require_internal_slot_data_view(agent, view)?; + + // 3. Let getIndex be ? ToIndex(requestIndex). + let get_index = to_index(agent, gc.reborrow(), request_index)? as usize; + + // 4. If IsBigIntElementType(type) is true, let numberValue be ? ToBigInt(value). + let number_value = if T::IS_BIGINT { + to_big_int(agent, gc.reborrow(), value)?.into_value() + } else { + // 5. Otherwise, let numberValue be ? ToNumber(value). + to_number(agent, gc.reborrow(), value)?.into_value() + }; + + // 7. Let viewOffset be view.[[ByteOffset]]. + let view_offset = view.byte_offset(agent); + + // 8. Let viewRecord be MakeDataViewWithBufferWitnessRecord(view, unordered). + let view_record = make_data_view_with_buffer_witness_record(agent, view, Ordering::Unordered); + + // 9. NOTE: Bounds checking is not a synchronizing operation when view's backing buffer is a growable SharedArrayBuffer. + // 10. If IsViewOutOfBounds(viewRecord) is true, throw a TypeError exception. + if is_view_out_of_bounds(agent, &view_record) { + return Err(agent.throw_exception_with_static_message( + ExceptionType::TypeError, + "DataView is out of bounds", + )); + } + + // 11. Let viewSize be GetViewByteLength(viewRecord). + let view_size = get_view_byte_length(agent, &view_record); + + // 12. Let elementSize be the Element Size value specified in Table 69 for Element Type type. + let element_size = size_of::(); + // 13. If getIndex + elementSize > viewSize, throw a RangeError exception. + if get_index + element_size > view_size { + return Err(agent.throw_exception_with_static_message( + ExceptionType::RangeError, + "Index out of bounds", + )); + } + + // 14. Let bufferIndex be getIndex + viewOffset. + let buffer_index = get_index + view_offset; + + // 15. Perform SetValueInBuffer(view.[[ViewedArrayBuffer]], bufferIndex, type, numberValue, false, unordered, isLittleEndian). + set_value_in_buffer::( + agent, + gc, + view.get_viewed_array_buffer(agent), + buffer_index, + number_value, + false, + Ordering::Unordered, + Some(is_little_endian), + ); + + // 16. Return undefined. + Ok(Value::Undefined) +} diff --git a/nova_vm/src/ecmascript/builtins/numbers_and_dates/bigint_objects/bigint_constructor.rs b/nova_vm/src/ecmascript/builtins/numbers_and_dates/bigint_objects/bigint_constructor.rs index f51f9d711..67e1e6dd9 100644 --- a/nova_vm/src/ecmascript/builtins/numbers_and_dates/bigint_objects/bigint_constructor.rs +++ b/nova_vm/src/ecmascript/builtins/numbers_and_dates/bigint_objects/bigint_constructor.rs @@ -77,7 +77,14 @@ impl BigIntConstructor { let value = arguments.get(0); let prim = to_primitive(agent, gc.reborrow(), value, Some(PreferredType::Number))?; if let Ok(prim) = Number::try_from(prim) { - Ok(prim.into_value()) + if !prim.is_integer(agent) { + return Err(agent.throw_exception_with_static_message( + ExceptionType::RangeError, + "Can't convert number to BigInt because it isn't an integer", + )); + } + + Ok(BigInt::from_i64(agent, prim.into_i64(agent)).into_value()) } else { to_big_int(agent, gc.reborrow(), value).map(|result| result.into_value()) } diff --git a/nova_vm/src/ecmascript/builtins/structured_data/data_view_objects/data_view_prototype.rs b/nova_vm/src/ecmascript/builtins/structured_data/data_view_objects/data_view_prototype.rs index 7ea44b0b1..b3f7add19 100644 --- a/nova_vm/src/ecmascript/builtins/structured_data/data_view_objects/data_view_prototype.rs +++ b/nova_vm/src/ecmascript/builtins/structured_data/data_view_objects/data_view_prototype.rs @@ -2,6 +2,8 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. +use crate::ecmascript::abstract_operations::type_conversion::to_boolean; +use crate::ecmascript::builtins::data_view::abstract_operations::{get_view_value, set_view_value}; use crate::engine::context::GcScope; use crate::{ ecmascript::{ @@ -215,7 +217,7 @@ impl DataViewPrototype { )); } // 6. Let size be GetViewByteLength(viewRecord). - let size = get_view_byte_length(agent, &view_record); + let size = get_view_byte_length(agent, &view_record) as i64; // 7. Return 𝔽(size). Ok(Number::from(SmallInteger::try_from(size).unwrap()).into_value()) } @@ -248,184 +250,302 @@ impl DataViewPrototype { Ok(Number::from(SmallInteger::try_from(o.byte_offset(agent) as i64).unwrap()).into_value()) } + /// ### [25.3.4.5 DataView.prototype.getBigInt64 ( byteOffset \[ , littleEndian \] )](https://tc39.es/ecma262/#sec-dataview.prototype.getbigint64) fn get_big_int64( - _agent: &mut Agent, - _gc: GcScope<'_, '_>, - _this_value: Value, - _arguments: ArgumentsList, + agent: &mut Agent, + gc: GcScope<'_, '_>, + this_value: Value, + arguments: ArgumentsList, ) -> JsResult { - todo!() + let byte_offset = arguments.get(0); + let little_endian = to_boolean(agent, arguments.get(1)); + // 1. Let v be the this value. + // 2. Return ? GetViewValue(v, byteOffset, littleEndian, bigint64). + get_view_value::(agent, gc, this_value, byte_offset, little_endian) } + /// ### [25.3.4.6 DataView.prototype.getBigUint64 ( byteOffset \[ , littleEndian \] )](https://tc39.es/ecma262/#sec-dataview.prototype.getbiguint64) fn get_big_uint64( - _agent: &mut Agent, - _gc: GcScope<'_, '_>, - _this_value: Value, - _: ArgumentsList, + agent: &mut Agent, + gc: GcScope<'_, '_>, + this_value: Value, + arguments: ArgumentsList, ) -> JsResult { - todo!() + let byte_offset = arguments.get(0); + let little_endian = to_boolean(agent, arguments.get(1)); + // 1. Let v be the this value. + // 2. Return ? GetViewValue(v, byteOffset, littleEndian, biguint64). + get_view_value::(agent, gc, this_value, byte_offset, little_endian) } + /// ### [25.3.4.7 DataView.prototype.getFloat32 ( byteOffset \[ , littleEndian \] )](https://tc39.es/ecma262/#sec-dataview.prototype.getfloat32) fn get_float32( - _agent: &mut Agent, - _gc: GcScope<'_, '_>, - _this_value: Value, - _: ArgumentsList, + agent: &mut Agent, + gc: GcScope<'_, '_>, + this_value: Value, + arguments: ArgumentsList, ) -> JsResult { - todo!() + let byte_offset = arguments.get(0); + // 2. If littleEndian is not present, set littleEndian to false. + let little_endian = to_boolean(agent, arguments.get(1)); + // 1. Let v be the this value. + // 3. Return ? GetViewValue(v, byteOffset, littleEndian, float32). + get_view_value::(agent, gc, this_value, byte_offset, little_endian) } + /// ### [25.3.4.8 DataView.prototype.getFloat64 ( byteOffset \[ , littleEndian \] )](https://tc39.es/ecma262/#sec-dataview.prototype.getfloat64) fn get_float64( - _agent: &mut Agent, - _gc: GcScope<'_, '_>, - _this_value: Value, - _: ArgumentsList, + agent: &mut Agent, + gc: GcScope<'_, '_>, + this_value: Value, + arguments: ArgumentsList, ) -> JsResult { - todo!() + let byte_offset = arguments.get(0); + // 2. If littleEndian is not present, set littleEndian to false. + let little_endian = to_boolean(agent, arguments.get(1)); + // 1. Let v be the this value. + // 3. Return ? GetViewValue(v, byteOffset, littleEndian, float64). + get_view_value::(agent, gc, this_value, byte_offset, little_endian) } + /// ### [25.3.4.9 DataView.prototype.getInt8 ( byteOffset )](https://tc39.es/ecma262/#sec-dataview.prototype.getint8) fn get_int8( - _agent: &mut Agent, - _gc: GcScope<'_, '_>, - _this_value: Value, - _: ArgumentsList, + agent: &mut Agent, + gc: GcScope<'_, '_>, + this_value: Value, + arguments: ArgumentsList, ) -> JsResult { - todo!() + let byte_offset = arguments.get(0); + // 1. Let v be the this value. + // 2. Return ? GetViewValue(v, byteOffset, true, int8). + get_view_value::(agent, gc, this_value, byte_offset, true) } + /// ### [25.3.4.10 DataView.prototype.getInt16 ( byteOffset \[ , littleEndian \] )](https://tc39.es/ecma262/#sec-dataview.prototype.getint16) fn get_int16( - _agent: &mut Agent, - _gc: GcScope<'_, '_>, - _this_value: Value, - _: ArgumentsList, + agent: &mut Agent, + gc: GcScope<'_, '_>, + this_value: Value, + arguments: ArgumentsList, ) -> JsResult { - todo!() + let byte_offset = arguments.get(0); + // 2. If littleEndian is not present, set littleEndian to false. + let little_endian = to_boolean(agent, arguments.get(1)); + // 1. Let v be the this value. + // 3. Return ? GetViewValue(v, byteOffset, littleEndian, int16). + get_view_value::(agent, gc, this_value, byte_offset, little_endian) } + /// ### [25.3.4.11 DataView.prototype.getInt32 ( byteOffset \[ , littleEndian \] )](https://tc39.es/ecma262/#sec-dataview.prototype.getint32) fn get_int32( - _agent: &mut Agent, - _gc: GcScope<'_, '_>, - _this_value: Value, - _: ArgumentsList, + agent: &mut Agent, + gc: GcScope<'_, '_>, + this_value: Value, + arguments: ArgumentsList, ) -> JsResult { - todo!() + let byte_offset = arguments.get(0); + // 2. If littleEndian is not present, set littleEndian to false. + let little_endian = to_boolean(agent, arguments.get(1)); + // 1. Let v be the this value. + // 3. Return ? GetViewValue(v, byteOffset, littleEndian, int32). + get_view_value::(agent, gc, this_value, byte_offset, little_endian) } + /// ### [25.3.4.12 DataView.prototype.getUint8 ( byteOffset )](https://tc39.es/ecma262/#sec-dataview.prototype.getuint8) fn get_uint8( - _agent: &mut Agent, - _gc: GcScope<'_, '_>, - _this_value: Value, - _: ArgumentsList, + agent: &mut Agent, + gc: GcScope<'_, '_>, + this_value: Value, + arguments: ArgumentsList, ) -> JsResult { - todo!() + let byte_offset = arguments.get(0); + // 1. Let v be the this value. + // 2. Return ? GetViewValue(v, byteOffset, true, uint8). + get_view_value::(agent, gc, this_value, byte_offset, true) } + /// ### [25.3.4.13 DataView.prototype.getUint16 ( byteOffset \[ , littleEndian \] )](https://tc39.es/ecma262/#sec-dataview.prototype.getuint16) fn get_uint16( - _agent: &mut Agent, - _gc: GcScope<'_, '_>, - _this_value: Value, - _: ArgumentsList, + agent: &mut Agent, + gc: GcScope<'_, '_>, + this_value: Value, + arguments: ArgumentsList, ) -> JsResult { - todo!() + let byte_offset = arguments.get(0); + // 2. If littleEndian is not present, set littleEndian to false. + let little_endian = to_boolean(agent, arguments.get(1)); + // 1. Let v be the this value. + // 3. Return ? GetViewValue(v, byteOffset, littleEndian, uint16). + get_view_value::(agent, gc, this_value, byte_offset, little_endian) } + /// ### [25.3.4.14 DataView.prototype.getUint32 ( byteOffset \[ , littleEndian \] )](https://tc39.es/ecma262/#sec-dataview.prototype.getuint32) fn get_uint32( - _agent: &mut Agent, - _gc: GcScope<'_, '_>, - _this_value: Value, - _: ArgumentsList, + agent: &mut Agent, + gc: GcScope<'_, '_>, + this_value: Value, + arguments: ArgumentsList, ) -> JsResult { - todo!() + let byte_offset = arguments.get(0); + // 2. If littleEndian is not present, set littleEndian to false. + let little_endian = to_boolean(agent, arguments.get(1)); + // 1. Let v be the this value. + // 3. Return ? GetViewValue(v, byteOffset, littleEndian, uint32). + get_view_value::(agent, gc, this_value, byte_offset, little_endian) } + /// ### [25.3.4.15 DataView.prototype.setBigInt64 ( byteOffset, value \[ , littleEndian \] )](https://tc39.es/ecma262/#sec-dataview.prototype.setbigint64) fn set_big_int64( - _agent: &mut Agent, - _gc: GcScope<'_, '_>, - _this_value: Value, - _: ArgumentsList, + agent: &mut Agent, + gc: GcScope<'_, '_>, + this_value: Value, + arguments: ArgumentsList, ) -> JsResult { - todo!() + let byte_offset = arguments.get(0); + let value = arguments.get(1); + let little_endian = to_boolean(agent, arguments.get(2)); + // 1. Let v be the this value. + // 2. Return ? SetViewValue(v, byteOffset, littleEndian, bigint64, value). + set_view_value::(agent, gc, this_value, byte_offset, little_endian, value) } + /// ### [25.3.4.16 DataView.prototype.setBigUint64 ( byteOffset, value \[ , littleEndian \] )](https://tc39.es/ecma262/#sec-dataview.prototype.setbiguint64) fn set_big_uint64( - _agent: &mut Agent, - _gc: GcScope<'_, '_>, - _this_value: Value, - _: ArgumentsList, + agent: &mut Agent, + gc: GcScope<'_, '_>, + this_value: Value, + arguments: ArgumentsList, ) -> JsResult { - todo!() + let byte_offset = arguments.get(0); + let value = arguments.get(1); + let little_endian = to_boolean(agent, arguments.get(2)); + // 1. Let v be the this value. + // 2. Return ? SetViewValue(v, byteOffset, littleEndian, biguint64, value). + set_view_value::(agent, gc, this_value, byte_offset, little_endian, value) } + /// ### [25.3.4.17 DataView.prototype.setFloat32 ( byteOffset, value \[ , littleEndian \] )](https://tc39.es/ecma262/#sec-dataview.prototype.setfloat32) fn set_float32( - _agent: &mut Agent, - _gc: GcScope<'_, '_>, - _this_value: Value, - _: ArgumentsList, + agent: &mut Agent, + gc: GcScope<'_, '_>, + this_value: Value, + arguments: ArgumentsList, ) -> JsResult { - todo!() + let byte_offset = arguments.get(0); + let value = arguments.get(1); + // 2. If littleEndian is not present, set littleEndian to false. + let little_endian = to_boolean(agent, arguments.get(2)); + // 1. Let v be the this value. + // 2. Return ? SetViewValue(v, byteOffset, littleEndian, float32, value). + set_view_value::(agent, gc, this_value, byte_offset, little_endian, value) } + /// ### [25.3.4.18 DataView.prototype.setFloat64 ( byteOffset, value \[ , littleEndian \] )](https://tc39.es/ecma262/#sec-dataview.prototype.setfloat64) fn set_float64( - _agent: &mut Agent, - _gc: GcScope<'_, '_>, - _this_value: Value, - _: ArgumentsList, + agent: &mut Agent, + gc: GcScope<'_, '_>, + this_value: Value, + arguments: ArgumentsList, ) -> JsResult { - todo!() + let byte_offset = arguments.get(0); + let value = arguments.get(1); + // 2. If littleEndian is not present, set littleEndian to false. + let little_endian = to_boolean(agent, arguments.get(2)); + // 1. Let v be the this value. + // 2. Return ? SetViewValue(v, byteOffset, littleEndian, float64, value). + set_view_value::(agent, gc, this_value, byte_offset, little_endian, value) } + /// ### [25.3.4.19 DataView.prototype.setInt8 ( byteOffset, value )](https://tc39.es/ecma262/#sec-dataview.prototype.setint8) fn set_int8( - _agent: &mut Agent, - _gc: GcScope<'_, '_>, - _this_value: Value, - _: ArgumentsList, + agent: &mut Agent, + gc: GcScope<'_, '_>, + this_value: Value, + arguments: ArgumentsList, ) -> JsResult { - todo!() + let byte_offset = arguments.get(0); + let value = arguments.get(1); + // 1. Let v be the this value. + // 2. Return ? SetViewValue(v, byteOffset, true, int8, value). + set_view_value::(agent, gc, this_value, byte_offset, true, value) } + /// ### [25.3.4.20 DataView.prototype.setInt16 ( byteOffset, value \[ , littleEndian \] )](https://tc39.es/ecma262/#sec-dataview.prototype.setint16) fn set_int16( - _agent: &mut Agent, - _gc: GcScope<'_, '_>, - _this_value: Value, - _: ArgumentsList, + agent: &mut Agent, + gc: GcScope<'_, '_>, + this_value: Value, + arguments: ArgumentsList, ) -> JsResult { - todo!() + let byte_offset = arguments.get(0); + let value = arguments.get(1); + // 2. If littleEndian is not present, set littleEndian to false. + let little_endian = to_boolean(agent, arguments.get(2)); + // 1. Let v be the this value. + // 2. Return ? SetViewValue(v, byteOffset, littleEndian, int16, value). + set_view_value::(agent, gc, this_value, byte_offset, little_endian, value) } + /// ### [25.3.4.21 DataView.prototype.setInt32 ( byteOffset, value \[ , littleEndian \] )](https://tc39.es/ecma262/#sec-dataview.prototype.setint32) fn set_int32( - _agent: &mut Agent, - _gc: GcScope<'_, '_>, - _this_value: Value, - _: ArgumentsList, + agent: &mut Agent, + gc: GcScope<'_, '_>, + this_value: Value, + arguments: ArgumentsList, ) -> JsResult { - todo!() + let byte_offset = arguments.get(0); + let value = arguments.get(1); + // 2. If littleEndian is not present, set littleEndian to false. + let little_endian = to_boolean(agent, arguments.get(2)); + // 1. Let v be the this value. + // 2. Return ? SetViewValue(v, byteOffset, littleEndian, int32, value). + set_view_value::(agent, gc, this_value, byte_offset, little_endian, value) } + /// ### [25.3.4.22 DataView.prototype.setUint8 ( byteOffset, value )](https://tc39.es/ecma262/#sec-dataview.prototype.setuint8) fn set_uint8( - _agent: &mut Agent, - _gc: GcScope<'_, '_>, - _this_value: Value, - _: ArgumentsList, + agent: &mut Agent, + gc: GcScope<'_, '_>, + this_value: Value, + arguments: ArgumentsList, ) -> JsResult { - todo!() + let byte_offset = arguments.get(0); + let value = arguments.get(1); + // 1. Let v be the this value. + // 2. Return ? SetViewValue(v, byteOffset, true, uint8, value). + set_view_value::(agent, gc, this_value, byte_offset, true, value) } + /// ### [25.3.4.23 DataView.prototype.setUint16 ( byteOffset, value \[ , littleEndian \] )](https://tc39.es/ecma262/#sec-dataview.prototype.setuint16) fn set_uint16( - _agent: &mut Agent, - _gc: GcScope<'_, '_>, - _this_value: Value, - _: ArgumentsList, + agent: &mut Agent, + gc: GcScope<'_, '_>, + this_value: Value, + arguments: ArgumentsList, ) -> JsResult { - todo!() + let byte_offset = arguments.get(0); + let value = arguments.get(1); + // 2. If littleEndian is not present, set littleEndian to false. + let little_endian = to_boolean(agent, arguments.get(2)); + // 1. Let v be the this value. + // 2. Return ? SetViewValue(v, byteOffset, littleEndian, uint16, value). + set_view_value::(agent, gc, this_value, byte_offset, little_endian, value) } + /// ### [25.3.4.24 DataView.prototype.setUint32 ( byteOffset, value \[ , littleEndian \] )](https://tc39.es/ecma262/#sec-dataview.prototype.setuint32) fn set_uint32( - _agent: &mut Agent, - _gc: GcScope<'_, '_>, - _this_value: Value, - _: ArgumentsList, + agent: &mut Agent, + gc: GcScope<'_, '_>, + this_value: Value, + arguments: ArgumentsList, ) -> JsResult { - todo!() + let byte_offset = arguments.get(0); + let value = arguments.get(1); + // 2. If littleEndian is not present, set littleEndian to false. + let little_endian = to_boolean(agent, arguments.get(2)); + // 1. Let v be the this value. + // 2. Return ? SetViewValue(v, byteOffset, littleEndian, uint32, value). + set_view_value::(agent, gc, this_value, byte_offset, little_endian, value) } pub(crate) fn create_intrinsic(agent: &mut Agent, realm: RealmIdentifier) { @@ -474,7 +594,7 @@ impl DataViewPrototype { } #[inline] -fn require_internal_slot_data_view(agent: &mut Agent, o: Value) -> JsResult { +pub(crate) fn require_internal_slot_data_view(agent: &mut Agent, o: Value) -> JsResult { match o { // 1. Perform ? RequireInternalSlot(O, [[DataView]]). Value::DataView(array_buffer) => Ok(array_buffer), diff --git a/nova_vm/src/ecmascript/types/language/bigint.rs b/nova_vm/src/ecmascript/types/language/bigint.rs index fde6647f0..c9ee08d9f 100644 --- a/nova_vm/src/ecmascript/types/language/bigint.rs +++ b/nova_vm/src/ecmascript/types/language/bigint.rs @@ -167,6 +167,15 @@ impl TryFrom for SmallBigInt { } } +impl TryFrom for SmallBigInt { + type Error = (); + + #[inline(always)] + fn try_from(value: u64) -> Result { + Ok(Self(value.try_into()?)) + } +} + impl TryFrom<&num_bigint::BigInt> for SmallBigInt { type Error = (); @@ -211,6 +220,15 @@ impl BigInt { } } + #[inline] + pub fn from_u64(agent: &mut Agent, value: u64) -> Self { + if let Ok(result) = SmallBigInt::try_from(value) { + Self::SmallBigInt(result) + } else { + agent.heap.create(BigIntHeapData { data: value.into() }) + } + } + #[inline] pub(crate) fn from_num_bigint(agent: &mut Agent, value: num_bigint::BigInt) -> Self { if let Ok(result) = SmallBigInt::try_from(&value) { @@ -502,7 +520,6 @@ impl BigInt { } } - /// ### [ /// ### [6.1.6.2.13 BigInt::equal ( x, y )](https://tc39.es/ecma262/#sec-numeric-types-bigint-equal) /// /// The abstract operation BigInt::equal takes arguments x (a BigInt) and y diff --git a/nova_vm/src/ecmascript/types/language/number.rs b/nova_vm/src/ecmascript/types/language/number.rs index ec41fbdc1..02332ce67 100644 --- a/nova_vm/src/ecmascript/types/language/number.rs +++ b/nova_vm/src/ecmascript/types/language/number.rs @@ -311,6 +311,14 @@ impl Number { } } + pub fn is_integer(self, agent: &impl Index) -> bool { + match self { + Number::Number(n) => agent[n].fract() == 0.0, + Number::Integer(_) => true, + Number::SmallF64(n) => n.into_f64().fract() == 0.0, + } + } + pub fn is_nonzero(self, agent: &impl Index) -> bool { match self { Number::Number(n) => 0.0 != agent[n], diff --git a/nova_vm/src/ecmascript/types/spec.rs b/nova_vm/src/ecmascript/types/spec.rs index c1f8e97cc..bd7811602 100644 --- a/nova_vm/src/ecmascript/types/spec.rs +++ b/nova_vm/src/ecmascript/types/spec.rs @@ -6,6 +6,6 @@ mod data_block; mod property_descriptor; mod reference; #[cfg(feature = "array-buffer")] -pub(crate) use data_block::DataBlock; +pub(crate) use data_block::{DataBlock, Viewable}; pub use property_descriptor::PropertyDescriptor; pub(crate) use reference::*; diff --git a/nova_vm/src/ecmascript/types/spec/data_block.rs b/nova_vm/src/ecmascript/types/spec/data_block.rs index 753739486..e8c445497 100644 --- a/nova_vm/src/ecmascript/types/spec/data_block.rs +++ b/nova_vm/src/ecmascript/types/spec/data_block.rs @@ -9,7 +9,17 @@ use std::{ ptr::{self, read_unaligned, write_unaligned, NonNull}, }; -use crate::ecmascript::execution::{agent::ExceptionType, Agent, JsResult}; +use crate::{ + ecmascript::{ + abstract_operations::type_conversion::{ + to_big_int64, to_big_uint64, to_int16, to_int32, to_int8, to_uint16, to_uint32, + to_uint8, + }, + execution::{agent::ExceptionType, Agent, JsResult}, + types::{BigInt, IntoValue, Value}, + }, + engine::context::GcScope, +}; /// Sentinel pointer for a detached data block. /// @@ -61,18 +71,209 @@ mod private { impl Sealed for f64 {} } -pub trait Viewable: private::Sealed {} +pub trait Viewable: private::Sealed + Copy { + const IS_BIGINT: bool; + + fn into_be_value(self, agent: &mut Agent) -> Value; + fn into_le_value(self, agent: &mut Agent) -> Value; + fn from_le_value(agent: &mut Agent, gc: GcScope<'_, '_>, value: Value) -> Self; + fn from_be_value(agent: &mut Agent, gc: GcScope<'_, '_>, value: Value) -> Self; + + // TODO: Consider adding the following methods if needed + // fn into_ne_value(self, agent: &mut Agent) -> Value; + // fn from_ne_value(agent: &mut Agent, gc: GcScope<'_, '_>, value: Value) -> Self; +} + +impl Viewable for u8 { + const IS_BIGINT: bool = false; + + fn into_be_value(self, _: &mut Agent) -> Value { + Value::from(self.to_be()) + } + + fn into_le_value(self, _: &mut Agent) -> Value { + Value::from(self.to_le()) + } + + fn from_be_value(agent: &mut Agent, gc: GcScope<'_, '_>, value: Value) -> Self { + to_uint8(agent, gc, value).unwrap().to_be() + } + + fn from_le_value(agent: &mut Agent, gc: GcScope<'_, '_>, value: Value) -> Self { + to_uint8(agent, gc, value).unwrap().to_le() + } +} +impl Viewable for i8 { + const IS_BIGINT: bool = false; + + fn into_be_value(self, _: &mut Agent) -> Value { + Value::from(self.to_be()) + } + + fn into_le_value(self, _: &mut Agent) -> Value { + Value::from(self.to_le()) + } + + fn from_be_value(agent: &mut Agent, gc: GcScope<'_, '_>, value: Value) -> Self { + to_int8(agent, gc, value).unwrap().to_be() + } + + fn from_le_value(agent: &mut Agent, gc: GcScope<'_, '_>, value: Value) -> Self { + to_int8(agent, gc, value).unwrap().to_le() + } +} +impl Viewable for u16 { + const IS_BIGINT: bool = false; + + fn into_be_value(self, _: &mut Agent) -> Value { + Value::from(self.to_be()) + } + + fn into_le_value(self, _: &mut Agent) -> Value { + Value::from(self.to_le()) + } + + fn from_be_value(agent: &mut Agent, gc: GcScope<'_, '_>, value: Value) -> Self { + to_uint16(agent, gc, value).unwrap().to_be() + } + + fn from_le_value(agent: &mut Agent, gc: GcScope<'_, '_>, value: Value) -> Self { + to_uint16(agent, gc, value).unwrap().to_le() + } +} +impl Viewable for i16 { + const IS_BIGINT: bool = false; + + fn into_be_value(self, _: &mut Agent) -> Value { + Value::from(self.to_be()) + } + + fn into_le_value(self, _: &mut Agent) -> Value { + Value::from(self.to_le()) + } -impl Viewable for u8 {} -impl Viewable for i8 {} -impl Viewable for u16 {} -impl Viewable for i16 {} -impl Viewable for u32 {} -impl Viewable for i32 {} -impl Viewable for u64 {} -impl Viewable for i64 {} -impl Viewable for f32 {} -impl Viewable for f64 {} + fn from_be_value(agent: &mut Agent, gc: GcScope<'_, '_>, value: Value) -> Self { + to_int16(agent, gc, value).unwrap().to_be() + } + + fn from_le_value(agent: &mut Agent, gc: GcScope<'_, '_>, value: Value) -> Self { + to_int16(agent, gc, value).unwrap().to_le() + } +} +impl Viewable for u32 { + const IS_BIGINT: bool = false; + + fn into_be_value(self, _: &mut Agent) -> Value { + Value::from(self.to_be()) + } + + fn into_le_value(self, _: &mut Agent) -> Value { + Value::from(self.to_le()) + } + + fn from_be_value(agent: &mut Agent, gc: GcScope<'_, '_>, value: Value) -> Self { + to_uint32(agent, gc, value).unwrap().to_be() + } + + fn from_le_value(agent: &mut Agent, gc: GcScope<'_, '_>, value: Value) -> Self { + to_uint32(agent, gc, value).unwrap().to_le() + } +} +impl Viewable for i32 { + const IS_BIGINT: bool = false; + + fn into_be_value(self, _: &mut Agent) -> Value { + Value::from(self.to_be()) + } + + fn into_le_value(self, _: &mut Agent) -> Value { + Value::from(self.to_le()) + } + + fn from_be_value(agent: &mut Agent, gc: GcScope<'_, '_>, value: Value) -> Self { + to_int32(agent, gc, value).unwrap().to_be() + } + + fn from_le_value(agent: &mut Agent, gc: GcScope<'_, '_>, value: Value) -> Self { + to_int32(agent, gc, value).unwrap().to_le() + } +} +impl Viewable for u64 { + const IS_BIGINT: bool = true; + + fn into_be_value(self, agent: &mut Agent) -> Value { + BigInt::from_u64(agent, self.to_be()).into_value() + } + + fn into_le_value(self, agent: &mut Agent) -> Value { + BigInt::from_u64(agent, self.to_le()).into_value() + } + + fn from_be_value(agent: &mut Agent, gc: GcScope<'_, '_>, value: Value) -> Self { + to_big_uint64(agent, gc, value).unwrap().to_be() + } + + fn from_le_value(agent: &mut Agent, gc: GcScope<'_, '_>, value: Value) -> Self { + to_big_uint64(agent, gc, value).unwrap().to_le() + } +} +impl Viewable for i64 { + const IS_BIGINT: bool = true; + + fn into_be_value(self, agent: &mut Agent) -> Value { + BigInt::from_i64(agent, self.to_be()).into_value() + } + + fn into_le_value(self, agent: &mut Agent) -> Value { + BigInt::from_i64(agent, self.to_le()).into_value() + } + + fn from_be_value(agent: &mut Agent, gc: GcScope<'_, '_>, value: Value) -> Self { + to_big_int64(agent, gc, value).unwrap().to_be() + } + + fn from_le_value(agent: &mut Agent, gc: GcScope<'_, '_>, value: Value) -> Self { + to_big_int64(agent, gc, value).unwrap().to_le() + } +} +impl Viewable for f32 { + const IS_BIGINT: bool = false; + + fn into_be_value(self, _: &mut Agent) -> Value { + Value::from(Self::from_ne_bytes(self.to_be_bytes())) + } + + fn into_le_value(self, _: &mut Agent) -> Value { + Value::from(Self::from_ne_bytes(self.to_le_bytes())) + } + + fn from_be_value(agent: &mut Agent, gc: GcScope<'_, '_>, value: Value) -> Self { + Self::from_ne_bytes((value.to_real(agent, gc).unwrap() as Self).to_be_bytes()) + } + + fn from_le_value(agent: &mut Agent, gc: GcScope<'_, '_>, value: Value) -> Self { + Self::from_ne_bytes((value.to_real(agent, gc).unwrap() as Self).to_le_bytes()) + } +} +impl Viewable for f64 { + const IS_BIGINT: bool = false; + + fn into_be_value(self, agent: &mut Agent) -> Value { + Value::from_f64(agent, Self::from_ne_bytes(self.to_be_bytes())) + } + + fn into_le_value(self, agent: &mut Agent) -> Value { + Value::from_f64(agent, Self::from_ne_bytes(self.to_le_bytes())) + } + + fn from_be_value(agent: &mut Agent, gc: GcScope<'_, '_>, value: Value) -> Self { + Self::from_ne_bytes((value.to_real(agent, gc).unwrap() as Self).to_be_bytes()) + } + + fn from_le_value(agent: &mut Agent, gc: GcScope<'_, '_>, value: Value) -> Self { + Self::from_ne_bytes((value.to_real(agent, gc).unwrap() as Self).to_le_bytes()) + } +} impl DataBlock { /// Sentinel value for detached DataBlocks. @@ -162,6 +363,20 @@ impl DataBlock { } } + pub fn get_offset_by_byte(&self, byte_offset: usize) -> Option { + let size = std::mem::size_of::(); + let end_byte_offset = byte_offset + size; + if end_byte_offset > self.byte_length { + None + } else { + self.ptr.map(|data| { + // SAFETY: The data is properly initialized, and the T being read is + // checked to be fully within the length of the data allocation. + unsafe { read_unaligned(data.as_ptr().byte_add(byte_offset).cast()) } + }) + } + } + pub fn set(&mut self, offset: usize, value: T) { let size = std::mem::size_of::(); if let Some(data) = self.ptr { @@ -176,6 +391,20 @@ impl DataBlock { } } + pub fn set_offset_by_byte(&mut self, byte_offset: usize, value: T) { + let size = std::mem::size_of::(); + if let Some(data) = self.ptr { + // Note: We have to check offset + 1 to ensure that the write does + // not reach data beyond the end of the DataBlock allocation. + let end_byte_offset = byte_offset + size; + if end_byte_offset <= self.byte_length { + // SAFETY: The data is properly initialized, and the T being written is + // checked to be fully within the length of the data allocation. + unsafe { write_unaligned(data.as_ptr().byte_add(byte_offset).cast(), value) } + } + } + } + pub fn set_from( &mut self, dst_offset: usize, diff --git a/tests/expectations.json b/tests/expectations.json index 68d10f599..16803057b 100644 --- a/tests/expectations.json +++ b/tests/expectations.json @@ -567,7 +567,6 @@ "built-ins/Array/prototype/with/this-value-nullish.js": "CRASH", "built-ins/ArrayBuffer/allocation-limit.js": "CRASH", "built-ins/ArrayBuffer/data-allocation-after-object-creation.js": "CRASH", - "built-ins/ArrayBuffer/init-zero.js": "CRASH", "built-ins/ArrayBuffer/isView/arg-is-typedarray-buffer.js": "CRASH", "built-ins/ArrayBuffer/isView/arg-is-typedarray-subclass-instance.js": "CRASH", "built-ins/ArrayBuffer/isView/arg-is-typedarray.js": "CRASH", @@ -1161,7 +1160,6 @@ "built-ins/BigInt/asUintN/bigint-tobigint-toprimitive.js": "CRASH", "built-ins/BigInt/asUintN/bigint-tobigint-wrapped-values.js": "FAIL", "built-ins/BigInt/asUintN/bigint-tobigint.js": "CRASH", - "built-ins/BigInt/call-value-of-when-to-string-present.js": "FAIL", "built-ins/BigInt/constructor-coercion.js": "FAIL", "built-ins/BigInt/constructor-empty-string.js": "CRASH", "built-ins/BigInt/constructor-from-binary-string.js": "CRASH", @@ -1169,11 +1167,7 @@ "built-ins/BigInt/constructor-from-hex-string.js": "CRASH", "built-ins/BigInt/constructor-from-octal-string.js": "CRASH", "built-ins/BigInt/constructor-from-string-syntax-errors.js": "CRASH", - "built-ins/BigInt/constructor-integer.js": "FAIL", "built-ins/BigInt/constructor-trailing-leading-spaces.js": "CRASH", - "built-ins/BigInt/infinity-throws-rangeerror.js": "FAIL", - "built-ins/BigInt/nan-throws-rangeerror.js": "FAIL", - "built-ins/BigInt/negative-infinity-throws.rangeerror.js": "FAIL", "built-ins/BigInt/non-integer-rangeerror.js": "FAIL", "built-ins/BigInt/prototype/toString/a-z.js": "FAIL", "built-ins/BigInt/prototype/toString/default-radix.js": "CRASH", @@ -1221,39 +1215,13 @@ "built-ins/DataView/prototype/getBigInt64/detached-buffer-after-toindex-byteoffset.js": "CRASH", "built-ins/DataView/prototype/getBigInt64/detached-buffer-before-outofrange-byteoffset.js": "CRASH", "built-ins/DataView/prototype/getBigInt64/detached-buffer.js": "CRASH", - "built-ins/DataView/prototype/getBigInt64/index-is-out-of-range.js": "CRASH", - "built-ins/DataView/prototype/getBigInt64/negative-byteoffset-throws.js": "CRASH", - "built-ins/DataView/prototype/getBigInt64/resizable-buffer.js": "CRASH", - "built-ins/DataView/prototype/getBigInt64/return-abrupt-from-tonumber-byteoffset-symbol.js": "CRASH", - "built-ins/DataView/prototype/getBigInt64/return-abrupt-from-tonumber-byteoffset.js": "CRASH", - "built-ins/DataView/prototype/getBigInt64/return-value-clean-arraybuffer.js": "CRASH", - "built-ins/DataView/prototype/getBigInt64/return-values-custom-offset.js": "CRASH", - "built-ins/DataView/prototype/getBigInt64/return-values.js": "CRASH", "built-ins/DataView/prototype/getBigInt64/this-has-no-dataview-internal.js": "CRASH", - "built-ins/DataView/prototype/getBigInt64/this-is-not-object.js": "CRASH", "built-ins/DataView/prototype/getBigInt64/to-boolean-littleendian.js": "CRASH", - "built-ins/DataView/prototype/getBigInt64/toindex-byteoffset-errors.js": "CRASH", - "built-ins/DataView/prototype/getBigInt64/toindex-byteoffset-toprimitive.js": "CRASH", - "built-ins/DataView/prototype/getBigInt64/toindex-byteoffset-wrapped-values.js": "CRASH", - "built-ins/DataView/prototype/getBigInt64/toindex-byteoffset.js": "CRASH", "built-ins/DataView/prototype/getBigUint64/detached-buffer-after-toindex-byteoffset.js": "CRASH", "built-ins/DataView/prototype/getBigUint64/detached-buffer-before-outofrange-byteoffset.js": "CRASH", "built-ins/DataView/prototype/getBigUint64/detached-buffer.js": "CRASH", - "built-ins/DataView/prototype/getBigUint64/index-is-out-of-range.js": "CRASH", - "built-ins/DataView/prototype/getBigUint64/negative-byteoffset-throws.js": "CRASH", - "built-ins/DataView/prototype/getBigUint64/resizable-buffer.js": "CRASH", - "built-ins/DataView/prototype/getBigUint64/return-abrupt-from-tonumber-byteoffset-symbol.js": "CRASH", - "built-ins/DataView/prototype/getBigUint64/return-abrupt-from-tonumber-byteoffset.js": "CRASH", - "built-ins/DataView/prototype/getBigUint64/return-value-clean-arraybuffer.js": "CRASH", - "built-ins/DataView/prototype/getBigUint64/return-values-custom-offset.js": "CRASH", - "built-ins/DataView/prototype/getBigUint64/return-values.js": "CRASH", "built-ins/DataView/prototype/getBigUint64/this-has-no-dataview-internal.js": "CRASH", - "built-ins/DataView/prototype/getBigUint64/this-is-not-object.js": "CRASH", "built-ins/DataView/prototype/getBigUint64/to-boolean-littleendian.js": "CRASH", - "built-ins/DataView/prototype/getBigUint64/toindex-byteoffset-errors.js": "CRASH", - "built-ins/DataView/prototype/getBigUint64/toindex-byteoffset-toprimitive.js": "CRASH", - "built-ins/DataView/prototype/getBigUint64/toindex-byteoffset-wrapped-values.js": "CRASH", - "built-ins/DataView/prototype/getBigUint64/toindex-byteoffset.js": "CRASH", "built-ins/DataView/prototype/getFloat16/detached-buffer-after-toindex-byteoffset.js": "CRASH", "built-ins/DataView/prototype/getFloat16/detached-buffer-before-outofrange-byteoffset.js": "CRASH", "built-ins/DataView/prototype/getFloat16/detached-buffer.js": "CRASH", @@ -1276,158 +1244,57 @@ "built-ins/DataView/prototype/getFloat32/detached-buffer-after-toindex-byteoffset.js": "CRASH", "built-ins/DataView/prototype/getFloat32/detached-buffer-before-outofrange-byteoffset.js": "CRASH", "built-ins/DataView/prototype/getFloat32/detached-buffer.js": "CRASH", - "built-ins/DataView/prototype/getFloat32/index-is-out-of-range.js": "CRASH", - "built-ins/DataView/prototype/getFloat32/minus-zero.js": "CRASH", - "built-ins/DataView/prototype/getFloat32/negative-byteoffset-throws.js": "CRASH", "built-ins/DataView/prototype/getFloat32/resizable-buffer.js": "CRASH", - "built-ins/DataView/prototype/getFloat32/return-abrupt-from-tonumber-byteoffset-symbol.js": "CRASH", - "built-ins/DataView/prototype/getFloat32/return-abrupt-from-tonumber-byteoffset.js": "CRASH", - "built-ins/DataView/prototype/getFloat32/return-infinity.js": "CRASH", - "built-ins/DataView/prototype/getFloat32/return-nan.js": "CRASH", "built-ins/DataView/prototype/getFloat32/return-value-clean-arraybuffer.js": "CRASH", "built-ins/DataView/prototype/getFloat32/return-values-custom-offset.js": "CRASH", "built-ins/DataView/prototype/getFloat32/return-values.js": "CRASH", "built-ins/DataView/prototype/getFloat32/this-has-no-dataview-internal.js": "CRASH", - "built-ins/DataView/prototype/getFloat32/this-is-not-object.js": "CRASH", "built-ins/DataView/prototype/getFloat32/to-boolean-littleendian.js": "CRASH", "built-ins/DataView/prototype/getFloat32/toindex-byteoffset.js": "CRASH", "built-ins/DataView/prototype/getFloat64/detached-buffer-after-toindex-byteoffset.js": "CRASH", "built-ins/DataView/prototype/getFloat64/detached-buffer-before-outofrange-byteoffset.js": "CRASH", "built-ins/DataView/prototype/getFloat64/detached-buffer.js": "CRASH", - "built-ins/DataView/prototype/getFloat64/index-is-out-of-range.js": "CRASH", "built-ins/DataView/prototype/getFloat64/minus-zero.js": "CRASH", - "built-ins/DataView/prototype/getFloat64/negative-byteoffset-throws.js": "CRASH", - "built-ins/DataView/prototype/getFloat64/resizable-buffer.js": "CRASH", - "built-ins/DataView/prototype/getFloat64/return-abrupt-from-tonumber-byteoffset-symbol.js": "CRASH", - "built-ins/DataView/prototype/getFloat64/return-abrupt-from-tonumber-byteoffset.js": "CRASH", - "built-ins/DataView/prototype/getFloat64/return-infinity.js": "CRASH", - "built-ins/DataView/prototype/getFloat64/return-nan.js": "CRASH", - "built-ins/DataView/prototype/getFloat64/return-value-clean-arraybuffer.js": "CRASH", - "built-ins/DataView/prototype/getFloat64/return-values-custom-offset.js": "CRASH", - "built-ins/DataView/prototype/getFloat64/return-values.js": "CRASH", "built-ins/DataView/prototype/getFloat64/this-has-no-dataview-internal.js": "CRASH", - "built-ins/DataView/prototype/getFloat64/this-is-not-object.js": "CRASH", - "built-ins/DataView/prototype/getFloat64/to-boolean-littleendian.js": "CRASH", - "built-ins/DataView/prototype/getFloat64/toindex-byteoffset.js": "CRASH", "built-ins/DataView/prototype/getInt16/detached-buffer-after-toindex-byteoffset.js": "CRASH", "built-ins/DataView/prototype/getInt16/detached-buffer-before-outofrange-byteoffset.js": "CRASH", "built-ins/DataView/prototype/getInt16/detached-buffer.js": "CRASH", - "built-ins/DataView/prototype/getInt16/index-is-out-of-range.js": "CRASH", - "built-ins/DataView/prototype/getInt16/negative-byteoffset-throws.js": "CRASH", - "built-ins/DataView/prototype/getInt16/resizable-buffer.js": "CRASH", - "built-ins/DataView/prototype/getInt16/return-abrupt-from-tonumber-byteoffset-symbol.js": "CRASH", - "built-ins/DataView/prototype/getInt16/return-abrupt-from-tonumber-byteoffset.js": "CRASH", - "built-ins/DataView/prototype/getInt16/return-value-clean-arraybuffer.js": "CRASH", - "built-ins/DataView/prototype/getInt16/return-values-custom-offset.js": "CRASH", - "built-ins/DataView/prototype/getInt16/return-values.js": "CRASH", "built-ins/DataView/prototype/getInt16/this-has-no-dataview-internal.js": "CRASH", - "built-ins/DataView/prototype/getInt16/this-is-not-object.js": "CRASH", - "built-ins/DataView/prototype/getInt16/to-boolean-littleendian.js": "CRASH", - "built-ins/DataView/prototype/getInt16/toindex-byteoffset.js": "CRASH", "built-ins/DataView/prototype/getInt32/detached-buffer-after-toindex-byteoffset.js": "CRASH", "built-ins/DataView/prototype/getInt32/detached-buffer-before-outofrange-byteoffset.js": "CRASH", "built-ins/DataView/prototype/getInt32/detached-buffer.js": "CRASH", "built-ins/DataView/prototype/getInt32/index-is-out-of-range-sab.js": "CRASH", - "built-ins/DataView/prototype/getInt32/index-is-out-of-range.js": "CRASH", "built-ins/DataView/prototype/getInt32/negative-byteoffset-throws-sab.js": "CRASH", - "built-ins/DataView/prototype/getInt32/negative-byteoffset-throws.js": "CRASH", - "built-ins/DataView/prototype/getInt32/resizable-buffer.js": "CRASH", "built-ins/DataView/prototype/getInt32/return-abrupt-from-tonumber-byteoffset-sab.js": "CRASH", "built-ins/DataView/prototype/getInt32/return-abrupt-from-tonumber-byteoffset-symbol-sab.js": "CRASH", - "built-ins/DataView/prototype/getInt32/return-abrupt-from-tonumber-byteoffset-symbol.js": "CRASH", - "built-ins/DataView/prototype/getInt32/return-abrupt-from-tonumber-byteoffset.js": "CRASH", "built-ins/DataView/prototype/getInt32/return-value-clean-arraybuffer-sab.js": "CRASH", - "built-ins/DataView/prototype/getInt32/return-value-clean-arraybuffer.js": "CRASH", "built-ins/DataView/prototype/getInt32/return-values-custom-offset-sab.js": "CRASH", - "built-ins/DataView/prototype/getInt32/return-values-custom-offset.js": "CRASH", "built-ins/DataView/prototype/getInt32/return-values-sab.js": "CRASH", - "built-ins/DataView/prototype/getInt32/return-values.js": "CRASH", "built-ins/DataView/prototype/getInt32/this-has-no-dataview-internal-sab.js": "CRASH", "built-ins/DataView/prototype/getInt32/this-has-no-dataview-internal.js": "CRASH", - "built-ins/DataView/prototype/getInt32/this-is-not-object.js": "CRASH", "built-ins/DataView/prototype/getInt32/to-boolean-littleendian-sab.js": "CRASH", - "built-ins/DataView/prototype/getInt32/to-boolean-littleendian.js": "CRASH", "built-ins/DataView/prototype/getInt32/toindex-byteoffset-sab.js": "CRASH", - "built-ins/DataView/prototype/getInt32/toindex-byteoffset.js": "CRASH", "built-ins/DataView/prototype/getInt8/detached-buffer-after-toindex-byteoffset.js": "CRASH", "built-ins/DataView/prototype/getInt8/detached-buffer-before-outofrange-byteoffset.js": "CRASH", "built-ins/DataView/prototype/getInt8/detached-buffer.js": "CRASH", - "built-ins/DataView/prototype/getInt8/index-is-out-of-range.js": "CRASH", - "built-ins/DataView/prototype/getInt8/negative-byteoffset-throws.js": "CRASH", - "built-ins/DataView/prototype/getInt8/resizable-buffer.js": "CRASH", - "built-ins/DataView/prototype/getInt8/return-abrupt-from-tonumber-byteoffset-symbol.js": "CRASH", - "built-ins/DataView/prototype/getInt8/return-abrupt-from-tonumber-byteoffset.js": "CRASH", - "built-ins/DataView/prototype/getInt8/return-value-clean-arraybuffer.js": "CRASH", - "built-ins/DataView/prototype/getInt8/return-values-custom-offset.js": "CRASH", - "built-ins/DataView/prototype/getInt8/return-values.js": "CRASH", "built-ins/DataView/prototype/getInt8/this-has-no-dataview-internal.js": "CRASH", - "built-ins/DataView/prototype/getInt8/this-is-not-object.js": "CRASH", - "built-ins/DataView/prototype/getInt8/toindex-byteoffset.js": "CRASH", "built-ins/DataView/prototype/getUint16/detached-buffer-after-toindex-byteoffset.js": "CRASH", "built-ins/DataView/prototype/getUint16/detached-buffer-before-outofrange-byteoffset.js": "CRASH", "built-ins/DataView/prototype/getUint16/detached-buffer.js": "CRASH", - "built-ins/DataView/prototype/getUint16/index-is-out-of-range.js": "CRASH", - "built-ins/DataView/prototype/getUint16/negative-byteoffset-throws.js": "CRASH", - "built-ins/DataView/prototype/getUint16/resizable-buffer.js": "CRASH", - "built-ins/DataView/prototype/getUint16/return-abrupt-from-tonumber-byteoffset-symbol.js": "CRASH", - "built-ins/DataView/prototype/getUint16/return-abrupt-from-tonumber-byteoffset.js": "CRASH", - "built-ins/DataView/prototype/getUint16/return-value-clean-arraybuffer.js": "CRASH", - "built-ins/DataView/prototype/getUint16/return-values-custom-offset.js": "CRASH", - "built-ins/DataView/prototype/getUint16/return-values.js": "CRASH", "built-ins/DataView/prototype/getUint16/this-has-no-dataview-internal.js": "CRASH", - "built-ins/DataView/prototype/getUint16/this-is-not-object.js": "CRASH", - "built-ins/DataView/prototype/getUint16/to-boolean-littleendian.js": "CRASH", - "built-ins/DataView/prototype/getUint16/toindex-byteoffset.js": "CRASH", "built-ins/DataView/prototype/getUint32/detached-buffer-after-toindex-byteoffset.js": "CRASH", "built-ins/DataView/prototype/getUint32/detached-buffer-before-outofrange-byteoffset.js": "CRASH", "built-ins/DataView/prototype/getUint32/detached-buffer.js": "CRASH", - "built-ins/DataView/prototype/getUint32/index-is-out-of-range.js": "CRASH", - "built-ins/DataView/prototype/getUint32/negative-byteoffset-throws.js": "CRASH", - "built-ins/DataView/prototype/getUint32/resizable-buffer.js": "CRASH", - "built-ins/DataView/prototype/getUint32/return-abrupt-from-tonumber-byteoffset-symbol.js": "CRASH", - "built-ins/DataView/prototype/getUint32/return-abrupt-from-tonumber-byteoffset.js": "CRASH", - "built-ins/DataView/prototype/getUint32/return-value-clean-arraybuffer.js": "CRASH", - "built-ins/DataView/prototype/getUint32/return-values-custom-offset.js": "CRASH", - "built-ins/DataView/prototype/getUint32/return-values.js": "CRASH", "built-ins/DataView/prototype/getUint32/this-has-no-dataview-internal.js": "CRASH", - "built-ins/DataView/prototype/getUint32/this-is-not-object.js": "CRASH", - "built-ins/DataView/prototype/getUint32/to-boolean-littleendian.js": "CRASH", - "built-ins/DataView/prototype/getUint32/toindex-byteoffset.js": "CRASH", "built-ins/DataView/prototype/getUint8/detached-buffer-after-toindex-byteoffset.js": "CRASH", "built-ins/DataView/prototype/getUint8/detached-buffer-before-outofrange-byteoffset.js": "CRASH", "built-ins/DataView/prototype/getUint8/detached-buffer.js": "CRASH", - "built-ins/DataView/prototype/getUint8/index-is-out-of-range.js": "CRASH", - "built-ins/DataView/prototype/getUint8/negative-byteoffset-throws.js": "CRASH", - "built-ins/DataView/prototype/getUint8/resizable-buffer.js": "CRASH", - "built-ins/DataView/prototype/getUint8/return-abrupt-from-tonumber-byteoffset-symbol.js": "CRASH", - "built-ins/DataView/prototype/getUint8/return-abrupt-from-tonumber-byteoffset.js": "CRASH", - "built-ins/DataView/prototype/getUint8/return-value-clean-arraybuffer.js": "CRASH", - "built-ins/DataView/prototype/getUint8/return-values-custom-offset.js": "CRASH", - "built-ins/DataView/prototype/getUint8/return-values.js": "CRASH", "built-ins/DataView/prototype/getUint8/this-has-no-dataview-internal.js": "CRASH", - "built-ins/DataView/prototype/getUint8/this-is-not-object.js": "CRASH", - "built-ins/DataView/prototype/getUint8/toindex-byteoffset.js": "CRASH", "built-ins/DataView/prototype/setBigInt64/detached-buffer-after-bigint-value.js": "CRASH", "built-ins/DataView/prototype/setBigInt64/detached-buffer-after-toindex-byteoffset.js": "CRASH", "built-ins/DataView/prototype/setBigInt64/detached-buffer-before-outofrange-byteoffset.js": "CRASH", "built-ins/DataView/prototype/setBigInt64/detached-buffer.js": "CRASH", - "built-ins/DataView/prototype/setBigInt64/index-check-before-value-conversion.js": "CRASH", - "built-ins/DataView/prototype/setBigInt64/index-is-out-of-range.js": "CRASH", - "built-ins/DataView/prototype/setBigInt64/negative-byteoffset-throws.js": "CRASH", - "built-ins/DataView/prototype/setBigInt64/no-value-arg.js": "CRASH", - "built-ins/DataView/prototype/setBigInt64/range-check-after-value-conversion.js": "CRASH", - "built-ins/DataView/prototype/setBigInt64/resizable-buffer.js": "CRASH", - "built-ins/DataView/prototype/setBigInt64/return-abrupt-from-tobigint-value-symbol.js": "CRASH", - "built-ins/DataView/prototype/setBigInt64/return-abrupt-from-tobigint-value.js": "CRASH", - "built-ins/DataView/prototype/setBigInt64/return-abrupt-from-tonumber-byteoffset-symbol.js": "CRASH", - "built-ins/DataView/prototype/setBigInt64/return-abrupt-from-tonumber-byteoffset.js": "CRASH", - "built-ins/DataView/prototype/setBigInt64/set-values-little-endian-order.js": "CRASH", - "built-ins/DataView/prototype/setBigInt64/set-values-return-undefined.js": "CRASH", "built-ins/DataView/prototype/setBigInt64/this-has-no-dataview-internal.js": "CRASH", - "built-ins/DataView/prototype/setBigInt64/this-is-not-object.js": "CRASH", - "built-ins/DataView/prototype/setBigInt64/to-boolean-littleendian.js": "CRASH", - "built-ins/DataView/prototype/setBigInt64/toindex-byteoffset.js": "CRASH", - "built-ins/DataView/prototype/setBigUint64/resizable-buffer.js": "CRASH", "built-ins/DataView/prototype/setFloat16/detached-buffer-after-number-value.js": "CRASH", "built-ins/DataView/prototype/setFloat16/detached-buffer-after-toindex-byteoffset.js": "CRASH", "built-ins/DataView/prototype/setFloat16/detached-buffer-before-outofrange-byteoffset.js": "CRASH", @@ -1452,157 +1319,53 @@ "built-ins/DataView/prototype/setFloat32/detached-buffer-after-toindex-byteoffset.js": "CRASH", "built-ins/DataView/prototype/setFloat32/detached-buffer-before-outofrange-byteoffset.js": "CRASH", "built-ins/DataView/prototype/setFloat32/detached-buffer.js": "CRASH", - "built-ins/DataView/prototype/setFloat32/index-check-before-value-conversion.js": "CRASH", "built-ins/DataView/prototype/setFloat32/index-is-out-of-range.js": "CRASH", "built-ins/DataView/prototype/setFloat32/negative-byteoffset-throws.js": "CRASH", - "built-ins/DataView/prototype/setFloat32/no-value-arg.js": "CRASH", - "built-ins/DataView/prototype/setFloat32/range-check-after-value-conversion.js": "CRASH", - "built-ins/DataView/prototype/setFloat32/resizable-buffer.js": "CRASH", - "built-ins/DataView/prototype/setFloat32/return-abrupt-from-tonumber-byteoffset-symbol.js": "CRASH", - "built-ins/DataView/prototype/setFloat32/return-abrupt-from-tonumber-byteoffset.js": "CRASH", - "built-ins/DataView/prototype/setFloat32/return-abrupt-from-tonumber-value-symbol.js": "CRASH", - "built-ins/DataView/prototype/setFloat32/return-abrupt-from-tonumber-value.js": "CRASH", "built-ins/DataView/prototype/setFloat32/set-values-little-endian-order.js": "CRASH", "built-ins/DataView/prototype/setFloat32/set-values-return-undefined.js": "CRASH", "built-ins/DataView/prototype/setFloat32/this-has-no-dataview-internal.js": "CRASH", - "built-ins/DataView/prototype/setFloat32/this-is-not-object.js": "CRASH", "built-ins/DataView/prototype/setFloat32/to-boolean-littleendian.js": "CRASH", "built-ins/DataView/prototype/setFloat32/toindex-byteoffset.js": "CRASH", "built-ins/DataView/prototype/setFloat64/detached-buffer-after-number-value.js": "CRASH", "built-ins/DataView/prototype/setFloat64/detached-buffer-after-toindex-byteoffset.js": "CRASH", "built-ins/DataView/prototype/setFloat64/detached-buffer-before-outofrange-byteoffset.js": "CRASH", "built-ins/DataView/prototype/setFloat64/detached-buffer.js": "CRASH", - "built-ins/DataView/prototype/setFloat64/index-check-before-value-conversion.js": "CRASH", - "built-ins/DataView/prototype/setFloat64/index-is-out-of-range.js": "CRASH", - "built-ins/DataView/prototype/setFloat64/negative-byteoffset-throws.js": "CRASH", - "built-ins/DataView/prototype/setFloat64/no-value-arg.js": "CRASH", - "built-ins/DataView/prototype/setFloat64/range-check-after-value-conversion.js": "CRASH", - "built-ins/DataView/prototype/setFloat64/resizable-buffer.js": "CRASH", - "built-ins/DataView/prototype/setFloat64/return-abrupt-from-tonumber-byteoffset-symbol.js": "CRASH", - "built-ins/DataView/prototype/setFloat64/return-abrupt-from-tonumber-byteoffset.js": "CRASH", - "built-ins/DataView/prototype/setFloat64/return-abrupt-from-tonumber-value-symbol.js": "CRASH", - "built-ins/DataView/prototype/setFloat64/return-abrupt-from-tonumber-value.js": "CRASH", - "built-ins/DataView/prototype/setFloat64/set-values-little-endian-order.js": "CRASH", "built-ins/DataView/prototype/setFloat64/set-values-return-undefined.js": "CRASH", "built-ins/DataView/prototype/setFloat64/this-has-no-dataview-internal.js": "CRASH", - "built-ins/DataView/prototype/setFloat64/this-is-not-object.js": "CRASH", - "built-ins/DataView/prototype/setFloat64/to-boolean-littleendian.js": "CRASH", - "built-ins/DataView/prototype/setFloat64/toindex-byteoffset.js": "CRASH", "built-ins/DataView/prototype/setInt16/detached-buffer-after-number-value.js": "CRASH", "built-ins/DataView/prototype/setInt16/detached-buffer-after-toindex-byteoffset.js": "CRASH", "built-ins/DataView/prototype/setInt16/detached-buffer-before-outofrange-byteoffset.js": "CRASH", "built-ins/DataView/prototype/setInt16/detached-buffer.js": "CRASH", - "built-ins/DataView/prototype/setInt16/index-check-before-value-conversion.js": "CRASH", - "built-ins/DataView/prototype/setInt16/index-is-out-of-range.js": "CRASH", - "built-ins/DataView/prototype/setInt16/negative-byteoffset-throws.js": "CRASH", - "built-ins/DataView/prototype/setInt16/no-value-arg.js": "CRASH", - "built-ins/DataView/prototype/setInt16/range-check-after-value-conversion.js": "CRASH", - "built-ins/DataView/prototype/setInt16/resizable-buffer.js": "CRASH", - "built-ins/DataView/prototype/setInt16/return-abrupt-from-tonumber-byteoffset-symbol.js": "CRASH", - "built-ins/DataView/prototype/setInt16/return-abrupt-from-tonumber-byteoffset.js": "CRASH", - "built-ins/DataView/prototype/setInt16/return-abrupt-from-tonumber-value-symbol.js": "CRASH", - "built-ins/DataView/prototype/setInt16/return-abrupt-from-tonumber-value.js": "CRASH", - "built-ins/DataView/prototype/setInt16/set-values-little-endian-order.js": "CRASH", - "built-ins/DataView/prototype/setInt16/set-values-return-undefined.js": "CRASH", "built-ins/DataView/prototype/setInt16/this-has-no-dataview-internal.js": "CRASH", - "built-ins/DataView/prototype/setInt16/this-is-not-object.js": "CRASH", - "built-ins/DataView/prototype/setInt16/to-boolean-littleendian.js": "CRASH", - "built-ins/DataView/prototype/setInt16/toindex-byteoffset.js": "CRASH", "built-ins/DataView/prototype/setInt32/detached-buffer-after-number-value.js": "CRASH", "built-ins/DataView/prototype/setInt32/detached-buffer-after-toindex-byteoffset.js": "CRASH", "built-ins/DataView/prototype/setInt32/detached-buffer-before-outofrange-byteoffset.js": "CRASH", "built-ins/DataView/prototype/setInt32/detached-buffer.js": "CRASH", - "built-ins/DataView/prototype/setInt32/index-check-before-value-conversion.js": "CRASH", - "built-ins/DataView/prototype/setInt32/index-is-out-of-range.js": "CRASH", - "built-ins/DataView/prototype/setInt32/negative-byteoffset-throws.js": "CRASH", - "built-ins/DataView/prototype/setInt32/no-value-arg.js": "CRASH", - "built-ins/DataView/prototype/setInt32/range-check-after-value-conversion.js": "CRASH", - "built-ins/DataView/prototype/setInt32/resizable-buffer.js": "CRASH", - "built-ins/DataView/prototype/setInt32/return-abrupt-from-tonumber-byteoffset-symbol.js": "CRASH", - "built-ins/DataView/prototype/setInt32/return-abrupt-from-tonumber-byteoffset.js": "CRASH", - "built-ins/DataView/prototype/setInt32/return-abrupt-from-tonumber-value-symbol.js": "CRASH", - "built-ins/DataView/prototype/setInt32/return-abrupt-from-tonumber-value.js": "CRASH", - "built-ins/DataView/prototype/setInt32/set-values-little-endian-order.js": "CRASH", - "built-ins/DataView/prototype/setInt32/set-values-return-undefined.js": "CRASH", "built-ins/DataView/prototype/setInt32/this-has-no-dataview-internal.js": "CRASH", - "built-ins/DataView/prototype/setInt32/this-is-not-object.js": "CRASH", - "built-ins/DataView/prototype/setInt32/to-boolean-littleendian.js": "CRASH", - "built-ins/DataView/prototype/setInt32/toindex-byteoffset.js": "CRASH", "built-ins/DataView/prototype/setInt8/detached-buffer-after-number-value.js": "CRASH", "built-ins/DataView/prototype/setInt8/detached-buffer-after-toindex-byteoffset.js": "CRASH", "built-ins/DataView/prototype/setInt8/detached-buffer-before-outofrange-byteoffset.js": "CRASH", "built-ins/DataView/prototype/setInt8/detached-buffer.js": "CRASH", - "built-ins/DataView/prototype/setInt8/index-check-before-value-conversion.js": "CRASH", - "built-ins/DataView/prototype/setInt8/index-is-out-of-range.js": "CRASH", - "built-ins/DataView/prototype/setInt8/negative-byteoffset-throws.js": "CRASH", - "built-ins/DataView/prototype/setInt8/no-value-arg.js": "CRASH", - "built-ins/DataView/prototype/setInt8/range-check-after-value-conversion.js": "CRASH", - "built-ins/DataView/prototype/setInt8/resizable-buffer.js": "CRASH", - "built-ins/DataView/prototype/setInt8/return-abrupt-from-tonumber-byteoffset-symbol.js": "CRASH", - "built-ins/DataView/prototype/setInt8/return-abrupt-from-tonumber-byteoffset.js": "CRASH", - "built-ins/DataView/prototype/setInt8/return-abrupt-from-tonumber-value-symbol.js": "CRASH", - "built-ins/DataView/prototype/setInt8/return-abrupt-from-tonumber-value.js": "CRASH", - "built-ins/DataView/prototype/setInt8/set-values-return-undefined.js": "CRASH", "built-ins/DataView/prototype/setInt8/this-has-no-dataview-internal.js": "CRASH", - "built-ins/DataView/prototype/setInt8/this-is-not-object.js": "CRASH", - "built-ins/DataView/prototype/setInt8/toindex-byteoffset.js": "CRASH", "built-ins/DataView/prototype/setUint16/detached-buffer-after-number-value.js": "CRASH", "built-ins/DataView/prototype/setUint16/detached-buffer-after-toindex-byteoffset.js": "CRASH", "built-ins/DataView/prototype/setUint16/detached-buffer-before-outofrange-byteoffset.js": "CRASH", "built-ins/DataView/prototype/setUint16/detached-buffer.js": "CRASH", - "built-ins/DataView/prototype/setUint16/index-check-before-value-conversion.js": "CRASH", - "built-ins/DataView/prototype/setUint16/index-is-out-of-range.js": "CRASH", - "built-ins/DataView/prototype/setUint16/negative-byteoffset-throws.js": "CRASH", - "built-ins/DataView/prototype/setUint16/no-value-arg.js": "CRASH", - "built-ins/DataView/prototype/setUint16/range-check-after-value-conversion.js": "CRASH", - "built-ins/DataView/prototype/setUint16/resizable-buffer.js": "CRASH", - "built-ins/DataView/prototype/setUint16/return-abrupt-from-tonumber-byteoffset-symbol.js": "CRASH", - "built-ins/DataView/prototype/setUint16/return-abrupt-from-tonumber-byteoffset.js": "CRASH", - "built-ins/DataView/prototype/setUint16/return-abrupt-from-tonumber-value-symbol.js": "CRASH", - "built-ins/DataView/prototype/setUint16/return-abrupt-from-tonumber-value.js": "CRASH", - "built-ins/DataView/prototype/setUint16/set-values-little-endian-order.js": "CRASH", - "built-ins/DataView/prototype/setUint16/set-values-return-undefined.js": "CRASH", "built-ins/DataView/prototype/setUint16/this-has-no-dataview-internal.js": "CRASH", - "built-ins/DataView/prototype/setUint16/this-is-not-object.js": "CRASH", - "built-ins/DataView/prototype/setUint16/to-boolean-littleendian.js": "CRASH", - "built-ins/DataView/prototype/setUint16/toindex-byteoffset.js": "CRASH", "built-ins/DataView/prototype/setUint32/detached-buffer-after-number-value.js": "CRASH", "built-ins/DataView/prototype/setUint32/detached-buffer-after-toindex-byteoffset.js": "CRASH", "built-ins/DataView/prototype/setUint32/detached-buffer-before-outofrange-byteoffset.js": "CRASH", "built-ins/DataView/prototype/setUint32/detached-buffer.js": "CRASH", - "built-ins/DataView/prototype/setUint32/index-check-before-value-conversion.js": "CRASH", - "built-ins/DataView/prototype/setUint32/index-is-out-of-range.js": "CRASH", - "built-ins/DataView/prototype/setUint32/negative-byteoffset-throws.js": "CRASH", - "built-ins/DataView/prototype/setUint32/no-value-arg.js": "CRASH", - "built-ins/DataView/prototype/setUint32/range-check-after-value-conversion.js": "CRASH", - "built-ins/DataView/prototype/setUint32/resizable-buffer.js": "CRASH", - "built-ins/DataView/prototype/setUint32/return-abrupt-from-tonumber-byteoffset-symbol.js": "CRASH", - "built-ins/DataView/prototype/setUint32/return-abrupt-from-tonumber-byteoffset.js": "CRASH", - "built-ins/DataView/prototype/setUint32/return-abrupt-from-tonumber-value-symbol.js": "CRASH", - "built-ins/DataView/prototype/setUint32/return-abrupt-from-tonumber-value.js": "CRASH", - "built-ins/DataView/prototype/setUint32/set-values-little-endian-order.js": "CRASH", - "built-ins/DataView/prototype/setUint32/set-values-return-undefined.js": "CRASH", "built-ins/DataView/prototype/setUint32/this-has-no-dataview-internal.js": "CRASH", - "built-ins/DataView/prototype/setUint32/this-is-not-object.js": "CRASH", - "built-ins/DataView/prototype/setUint32/to-boolean-littleendian.js": "CRASH", - "built-ins/DataView/prototype/setUint32/toindex-byteoffset.js": "CRASH", "built-ins/DataView/prototype/setUint8/detached-buffer-after-number-value.js": "CRASH", "built-ins/DataView/prototype/setUint8/detached-buffer-after-toindex-byteoffset.js": "CRASH", "built-ins/DataView/prototype/setUint8/detached-buffer-before-outofrange-byteoffset.js": "CRASH", "built-ins/DataView/prototype/setUint8/detached-buffer.js": "CRASH", - "built-ins/DataView/prototype/setUint8/index-check-before-value-conversion.js": "CRASH", "built-ins/DataView/prototype/setUint8/index-is-out-of-range.js": "CRASH", "built-ins/DataView/prototype/setUint8/negative-byteoffset-throws.js": "CRASH", "built-ins/DataView/prototype/setUint8/no-value-arg.js": "CRASH", - "built-ins/DataView/prototype/setUint8/range-check-after-value-conversion.js": "CRASH", - "built-ins/DataView/prototype/setUint8/resizable-buffer.js": "CRASH", - "built-ins/DataView/prototype/setUint8/return-abrupt-from-tonumber-byteoffset-symbol.js": "CRASH", - "built-ins/DataView/prototype/setUint8/return-abrupt-from-tonumber-byteoffset.js": "CRASH", - "built-ins/DataView/prototype/setUint8/return-abrupt-from-tonumber-value-symbol.js": "CRASH", - "built-ins/DataView/prototype/setUint8/return-abrupt-from-tonumber-value.js": "CRASH", "built-ins/DataView/prototype/setUint8/set-values-return-undefined.js": "CRASH", "built-ins/DataView/prototype/setUint8/this-has-no-dataview-internal.js": "CRASH", - "built-ins/DataView/prototype/setUint8/this-is-not-object.js": "CRASH", "built-ins/DataView/prototype/setUint8/toindex-byteoffset.js": "CRASH", "built-ins/DataView/return-abrupt-tonumber-bytelength-sab.js": "CRASH", "built-ins/DataView/return-abrupt-tonumber-bytelength-symbol-sab.js": "CRASH", @@ -3137,9 +2900,7 @@ "built-ins/Object/prototype/toString/symbol-tag-array-builtin.js": "CRASH", "built-ins/Object/prototype/toString/symbol-tag-generators-builtin.js": "FAIL", "built-ins/Object/prototype/toString/symbol-tag-map-builtin.js": "CRASH", - "built-ins/Object/prototype/toString/symbol-tag-non-str-bigint.js": "FAIL", "built-ins/Object/prototype/toString/symbol-tag-non-str-proxy-function.js": "CRASH", - "built-ins/Object/prototype/toString/symbol-tag-override-bigint.js": "FAIL", "built-ins/Object/prototype/toString/symbol-tag-override-instances.js": "FAIL", "built-ins/Object/prototype/toString/symbol-tag-override-primitives.js": "FAIL", "built-ins/Object/prototype/toString/symbol-tag-set-builtin.js": "CRASH", @@ -18397,7 +18158,6 @@ "language/expressions/template-literal/tv-template-tail.js": "CRASH", "language/expressions/template-literal/tv-utf16-escape-sequence.js": "CRASH", "language/expressions/template-literal/tv-zwnbsp.js": "CRASH", - "language/expressions/typeof/bigint.js": "FAIL", "language/expressions/typeof/built-in-exotic-objects-no-call.js": "CRASH", "language/expressions/typeof/null.js": "CRASH", "language/expressions/typeof/proxy.js": "CRASH", diff --git a/tests/metrics.json b/tests/metrics.json index ce50fc561..7cc01e30b 100644 --- a/tests/metrics.json +++ b/tests/metrics.json @@ -1,8 +1,8 @@ { "results": { - "crash": 16101, - "fail": 8357, - "pass": 20790, + "crash": 15846, + "fail": 8372, + "pass": 21030, "skip": 40, "timeout": 3, "unresolved": 0