-
Notifications
You must be signed in to change notification settings - Fork 51
feat(ecmascript): %TypedArray%.prototype.slice #736
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
yossydev
commented
May 25, 2025
- doc: https://tc39.es/ecma262/multipage/indexed-collections.html#sec-%typedarray%.prototype.slice
- ref: %TypedArray%.prototype builtin functions #145
fa5ab1e
to
710456b
Compare
.../ecmascript/builtins/indexed_collections/typed_array_objects/typed_array_intrinsic_object.rs
Outdated
Show resolved
Hide resolved
e16349a
to
555ae9c
Compare
555ae9c
to
5a70dcb
Compare
.../ecmascript/builtins/indexed_collections/typed_array_objects/typed_array_intrinsic_object.rs
Show resolved
Hide resolved
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.
Some nitpicks and one or two issues, that may actually be non-issues?
But overall, looks really good! Thank you, and great work <3
.../ecmascript/builtins/indexed_collections/typed_array_objects/typed_array_intrinsic_object.rs
Show resolved
Hide resolved
.unbind()? | ||
.bind(gc.nogc()); | ||
let o = ta_record.object; | ||
// 3. Let srcArrayLength be TypedArrayLength(taRecord). |
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: This comment should be inside the slice_typed_array
method.
gc: GcScope<'gc, '_>, | ||
) -> JsResult<'gc, Value<'gc>> { | ||
Err(agent.todo("TypedArray.prototype.slice", gc.into_nogc())) | ||
let start = arguments_list.get(0); |
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: Both the get
call results and the o = this_value;
should have a .bind(gc.nogc())
attached. Here it does not make a difference, but it's better to have them here just so that anyone coming in later and using this method as a template to copy-paste from will have the right "idioms" in place.
let end = end.scope(agent, gc.nogc()); | ||
let src_array_length = typed_array_length::<T>(agent, &ta_record, gc.nogc()) as i64; | ||
// 4. Let relativeStart be ? ToIntegerOrInfinity(start). | ||
let relative_start = to_integer_or_infinity(agent, start.get(agent), gc.reborrow()).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: No reason to scope start
as it is accessed here directly after. You can just remove the scoping line and change this to use start.unbind()
:
let relative_start = to_integer_or_infinity(agent, start.get(agent), gc.reborrow()).unbind()?; | |
let relative_start = to_integer_or_infinity(agent, start.unbind(), gc.reborrow()).unbind()?; |
let end = end.bind(gc.nogc()); | ||
let o = ta_record.object; | ||
let o = o.scope(agent, gc.nogc()); | ||
let start = start.scope(agent, gc.nogc()); |
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.
let start = start.scope(agent, gc.nogc()); |
relative_start.into_i64().min(src_array_length) | ||
}; | ||
// 8. If end is undefined, let relativeEnd be srcArrayLength; else let relativeEnd be ? ToIntegerOrInfinity(end). | ||
let end_index = if end.get(agent).is_undefined() { |
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 take end
out of the scoping here:
let end_index = if end.get(agent).is_undefined() { | |
// SAFETY: end is not shared. | |
let end = unsafe { end.take(agent) }.bind(gc.nogc()); | |
let end_index = if end.is_undefined() { |
src_array_length | ||
} else { | ||
let integer_or_infinity = | ||
to_integer_or_infinity(agent, end.get(agent), gc.reborrow()).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.
to_integer_or_infinity(agent, end.get(agent), gc.reborrow()).unbind()?; | |
to_integer_or_infinity(agent, end.unbind(), gc.reborrow()).unbind()?; |
.unbind()? | ||
.bind(gc.nogc()); | ||
// 14. If countBytes > 0, then | ||
if count_bytes > 0 { |
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: Could maybe return early if count_bytes == 0
and de-indent the if-branch.
if is_typed_array_out_of_bounds::<T>(agent, &ta_record, gc.nogc()) { | ||
return Err(agent.throw_exception_with_static_message( | ||
ExceptionType::TypeError, | ||
"Callback is not callable", |
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: Wrong error message.
)); | ||
}; | ||
// c. Set endIndex to min(endIndex, TypedArrayLength(taRecord)). | ||
// let end_index = end_index.min(typed_array_length::<T>(agent, &ta_record, gc.nogc()) as i64); |
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: Commented out code. Are these being done inside the with_typed_array_viewable!(a, ...)
branch? If so, the comments should be moved there. Otherwise, the code should presumably be actually performed.