-
Notifications
You must be signed in to change notification settings - Fork 51
feat(ecmascript): %TypedArray%.prototype.set #744
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
"built-ins/TypedArray/prototype/set/BigInt/boolean-tobigint.js": "FAIL", | ||
"built-ins/TypedArray/prototype/set/BigInt/null-tobigint.js": "FAIL", | ||
"built-ins/TypedArray/prototype/set/BigInt/number-tobigint.js": "FAIL", | ||
"built-ins/TypedArray/prototype/set/BigInt/src-typedarray-big.js": "FAIL", | ||
"built-ins/TypedArray/prototype/set/BigInt/src-typedarray-not-big-throws.js": "FAIL", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here are the reasons for the test262 failures.
internal error: entered unreachable code
thread 'main' panicked at nova_vm/src/ecmascript/types/spec/data_block.rs:683:13:
internal error: entered unreachable code
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
fn from_le_value(agent: &mut Agent, value: Numeric) -> Self {
let Ok(value) = BigInt::try_from(value) else {
unreachable!()
};
to_big_int64_big_int(agent, value).to_le()
}
Uncaught exception: Error: SharedArrayBuffer not implemented (Testing with Int16Array.)
Uncaught exception: Error: SharedArrayBuffer not implemented (Testing with Int16Array.)
Test result: Fail
.../ecmascript/builtins/indexed_collections/typed_array_objects/typed_array_intrinsic_object.rs
Outdated
Show resolved
Hide resolved
…copy_from_slice" This reverts commit 7877d47.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A bit more work to do around the GC handling here. You could also use the existing optimised TypedArray copy functions here instead of using the generic GetValueFromBuffer
and SetValueFromBuffer
methods.
/// targetOffset, reading the values from source. | ||
pub(crate) fn set_typed_array_from_typed_array< | ||
'a, | ||
TargetType: Viewable + std::fmt::Debug, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nitpick: Preferablytake out the std::fmt::Debug
bounds once you don't need them for debugging anymore.
)); | ||
}; | ||
// 17. If target.[[ContentType]] is not source.[[ContentType]], throw a TypeError exception. | ||
let is_type_match = has_matching_content_type::<TargetType>(target.get(agent)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue: You should be checking source
against TargetType
; this is probably the reason for one of the failing tests.
let is_type_match = has_matching_content_type::<TargetType>(target.get(agent)); | |
let is_type_match = has_matching_content_type::<TargetType>(source.get(agent)); |
// 18. If IsSharedArrayBuffer(srcBuffer) is true, IsSharedArrayBuffer(targetBuffer) is true, and srcBuffer.[[ArrayBufferData]] is targetBuffer.[[ArrayBufferData]], let sameSharedArrayBuffer be true; otherwise, let sameSharedArrayBuffer be false. | ||
// TODO: SharedArrayBuffer that we can even take here. | ||
// 19. If SameValue(srcBuffer, targetBuffer) is true or sameSharedArrayBuffer is true, then | ||
let mut src_byte_index = if same_value(agent, src_buffer, target_buffer) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nitpick: I think you can just compare src_buffer == target_buffer
directly; SameValue(objA, objB)
is equal to objA == objB
.
src_byte_length, | ||
gc.nogc(), | ||
) | ||
.unbind()?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue: You need to rebind here since the resulting cloned src_buffer
needs to be tracked by the GC:
.unbind()?; | |
.unbind()?.bind(gc.nogc()); |
if core::any::TypeId::of::<SrcType>() == core::any::TypeId::of::<TargetType>() { | ||
// a. NOTE: The transfer must be performed in a manner that preserves the bit-level encoding of the source data. | ||
// Repeat, while targetByteIndex < limit, | ||
while target_byte_index < limit { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue: Here we want to use the methods you've already added to dealing with copying data from one TypedArray to another, that just perform copy_from_slice
from &[SrcType: Viewable]
to &mut [TargetType: Viewable]
.
scoped_o.get(agent), | ||
target_offset, | ||
scoped_source.get(agent), | ||
gc.reborrow() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nitpick: You could just pass in gc
directly to all the SetTypedArrayFrom... calls, which would mean you don't need to .unbind()?
the result but can just use ?
directly.
scoped_o.get(agent), | ||
target_offset, | ||
source, | ||
gc.reborrow() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
gc.reborrow() | |
gc |
), | ||
V | ||
) | ||
.unbind()?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.unbind()?; | |
?; |
scoped_o.get(agent), | ||
set_typed_array_from_array_like::<T>( | ||
agent, | ||
scoped_o.get(agent), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue: Since you already have scoped_o
as Scoped, it doesn't make sense to get
its result and then immediately scope
it again inside the SetTypedArrayFromX
calls: Just pass the Scoped<TypedArray>
directly instead, and that'll save you one unnecessary scoping.
agent, | ||
scoped_o.get(agent), | ||
target_offset, | ||
scoped_source.get(agent), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue: Here too, you can just pass in the scoped_source: Scoped<Value>
directly; inside the call you'll need to do let src = source.replace_self(agent, src);
after you've done let src = to_object(agent, source.get(agent), gc.nogc());
but otherwise it should be all good.
I think there are still a few things we can do.
ref: #145
doc: https://tc39.es/ecma262/multipage/indexed-collections.html#sec-%typedarray%.prototype.set