Skip to content
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

Js typed array methods #3481

Merged
merged 16 commits into from
Feb 24, 2024
Merged

Conversation

AngeloChecked
Copy link
Contributor

@AngeloChecked AngeloChecked commented Nov 25, 2023

This Pull Request pertains to issue #3252

It implements the following JsTypedArray methods:

  • get buffer
  • constructor
  • copyWithin
  • find_index
  • find_last
  • find_last_index
  • foreach
  • includes
  • set
  • subarray
  • toLocaleString*
  • toStringTag

Hi guys!
I'd like to create this draft pull request to share my work on the issue through examples and seek feedback. Is that alright with you? I'll gradually compile this post as I make progress on the issue.

@AngeloChecked

This comment was marked as resolved.

Copy link
Member

@jedel1043 jedel1043 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really nice work! Just have some suggestions.

boa_examples/src/bin/jstypedarray.rs Outdated Show resolved Hide resolved
boa_examples/src/bin/jstypedarray.rs Outdated Show resolved Hide resolved
boa_engine/src/object/builtins/jstypedarray.rs Outdated Show resolved Hide resolved
boa_engine/src/object/builtins/jstypedarray.rs Outdated Show resolved Hide resolved
boa_engine/src/object/builtins/jstypedarray.rs Outdated Show resolved Hide resolved
@AngeloChecked AngeloChecked force-pushed the JsTypedArray_methods branch 3 times, most recently from bdfaab0 to 66b6a6d Compare November 28, 2023 07:24
Copy link

codecov bot commented Nov 28, 2023

Codecov Report

Attention: Patch coverage is 1.53846% with 64 lines in your changes are missing coverage. Please review.

Project coverage is 47.01%. Comparing base (6ddc2b4) to head (a9cc900).
Report is 43 commits behind head on main.

Files Patch % Lines
core/engine/src/object/builtins/jstypedarray.rs 0.00% 59 Missing ⚠️
core/engine/src/builtins/typed_array/builtin.rs 16.66% 5 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3481      +/-   ##
==========================================
- Coverage   47.24%   47.01%   -0.24%     
==========================================
  Files         476      477       +1     
  Lines       46892    47494     +602     
==========================================
+ Hits        22154    22327     +173     
- Misses      24738    25167     +429     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@jedel1043 jedel1043 self-assigned this Nov 29, 2023
@jedel1043 jedel1043 added the waiting-on-author Waiting on PR changes from the author label Nov 29, 2023
@AngeloChecked

This comment was marked as resolved.

@jedel1043
Copy link
Member

It appears that there's an overlap between TypedArray.prototype.set() and the functionality defined in https://tc39.es/ecma262/#sec-set-o-p-v-throw. I'm uncertain how to resolve this conflict. I've renamed it to typed_array_set, but I'm open to any suggestions or considerations.

Should probably be renamed to set_values, because the original method allows setting multiple values at the same time.

@AngeloChecked

This comment was marked as resolved.

@jedel1043
Copy link
Member

While exploring toLocaleString and attempting to replicate the example from MDN, I encountered a localization problem that prevented the code from working as expected. I'm unsure if this issue is widespread. As a temporary solution, I've commented out the example code for now.

Don't worry about that. We haven't implemented the NumberFormat API, meaning our numbers always format to plain numbers. When we implement that, this should be fixed.

@AngeloChecked
Copy link
Contributor Author

AngeloChecked commented Dec 9, 2023

I want to summarize the current status of the PR:

function implemented:

  • at <- already implemented
  • get buffer
  • get byteLength <- already implemented
  • get byteOffset <- already implemented
  • constructor
  • copyWithin
  • every <- already implemented
  • fill <- already implemented
  • filter <- already implemented
  • find <- already implemented
  • findIndex
  • findLast
  • findLastIndex
  • forEach
  • includes
  • indexOf <- already implemented
  • join <- already implemented
  • lastIndexOf <- already implemented
  • get length <- already implemented
  • map <- already implemented
  • reduce <- already implemented
  • reduceRight <- already implemented
  • reverse <- already implemented
  • set
  • slice <- already implemented
  • some <- already implemented
  • sort <- already implemented
  • subarray
  • toReversed <- already implemented
  • toSorted <- already implemented
  • with <- already implemented

function implemented but:

  • toLocaleString -> currently not working
  • get @@toStringTag -> i don't know if its behavior is correct

i don't know how to implement it

  • toString

iterators are unstable

desired features

  • Easily return the inner data as &[u8] or &Vec

@jedel1043 in your opinion what can be the next steps?

Can we review each implementation to align with the desired feature and reduce the utilization of JsValue? Any suggestions or tips on how to achieve this?

@jedel1043
Copy link
Member

Can we review each implementation to align with the desired feature and reduce the utilization of JsValue?

Yep, it'll be good to check already implemented functions to see if we can improve the API on them, but that can be done in another PR.

Any suggestions or tips on how to achieve this?

Probably to check the JS implementation to see if there are any patterns on the return types of the methods; methods returning only JsValue::String should return JsString on the object wrapper, methods returning either undefined or a specific type should return Option<Type>, etc.

@jedel1043
Copy link
Member

Also, when you feel like this is ready, just ping me so that I can change the label to waiting-on-review

@AngeloChecked
Copy link
Contributor Author

hi @jedel1043

pub fn buffer(&self, context: &mut Context) -> JsResult<JsValue>
pub fn constructor(&self, context: &mut Context) -> JsResult<JsValue>
pub fn copy_within<T>( &self, target: T, start: u64, end: Option<u64>, context: &mut Context,) -> JsResult<Self> where T: Into<JsValue>
pub fn find_index( &self, predicate: JsFunction, this_arg: Option<JsValue>, context: &mut Context,) -> JsResult<Option<u64>> 
pub fn find_last( &self, predicate: JsFunction, this_arg: Option<JsValue>, context: &mut Context,) -> JsResult<JsValue>
pub fn find_last_index( &self, predicate: JsFunction, this_arg: Option<JsValue>, context: &mut Context,) -> JsResult<Option<u64>>
pub fn foreach( &self, callback: JsFunction, this_arg: Option<JsValue>, context: &mut Context,) -> JsResult<JsValue> 
pub fn includes<T>( &self, search_element: T, from_index: Option<u64>, context: &mut Context,) -> JsResult<bool> where T: Into<JsValue>
pub fn set_values( &self, source: JsValue, offset: Option<u64>, context: &mut Context,) -> JsResult<JsValue>
pub fn subarray(&self, begin: i64, end: i64, context: &mut Context) -> JsResult<Self>

from your point of view should any of these fn signs be improved, make the types more explicit?
otherwise, I think I'll go with the review, considering that any side improvements can be put in another card.

@jedel1043 jedel1043 added waiting-on-review Waiting on reviews from the maintainers enhancement New feature or request builtins PRs and Issues related to builtins/intrinsics and removed waiting-on-author Waiting on PR changes from the author labels Dec 25, 2023
@AngeloChecked AngeloChecked marked this pull request as ready for review January 9, 2024 00:25
@AngeloChecked
Copy link
Contributor Author

hi @jedel1043,

It's been a while. What are our next steps? Did I forget to complete something specific? Can I assist with any tasks for the review?

Copy link
Member

@nekevss nekevss left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great overall! Really nice job!

I had just a couple nits.


/// Calls `TypedArray.prototype.forEach()`.
#[inline]
pub fn foreach(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Should this be in snake case?

This is extending the API from BuiltinTypedArray, but we use for_each in other places in the engine. Would it be better to maintain consistency?

Copy link
Contributor Author

@AngeloChecked AngeloChecked Feb 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @nekevss, big thanks for your support! Apologies for the delay; I got tied up with something else. Now, I'm eager to maintain continuity with this.

I used foreach because the internal API BuiltinTypedArray::foreach uses it too. But I'm flexible to rename it for consistency with the right naming conventions also in the internal api, following your guidance.
If you approve, I'll proceed to rename both. Otherwise, do we prefer to keep the internal API unchanged? give me feedback.

Copy link
Member

@nekevss nekevss Feb 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jedel1043 any thoughts on the use of snake case with foreach on the internal API for BuiltinTypedArray.

In general, I'm of the opinion for at least the external API to be closer to the Rust convention. Anyone who consumes the API will probably expect snake case. At minimum, we should probably be at least consistent throughout the engine on whether it's foreach or for_each.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we mostly agree on always converting camelCase JS APIs to snake_case Rust APIs. IMO, functions that differ from this convention should be treated as naming bugs.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good! 😄 Then let's go with renaming the functions from foreach to for_each for naming.

@@ -273,6 +358,104 @@ impl JsTypedArray {
)
}

/// Calls `TypedArray.prototype.findIndex()`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: can there be some examples added to these docs.

Since JsTypedArray et al. are meant to be an externally facing API. Some more thorough examples in the documentation would be nice. Something a bit more like the examples provided in JsPromise or JsMap.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think it would be more meaningful to enhance the builtins/jstypedarray.rs module with standard Rust documentation, or should we focus solely on improving the code in the examples folder? I drew a lot of inspiration from MDN for those examples, because originally I hadn't thought about it; I used them as acceptance tests to ensure the implementation was correct. However, I'm open to reconsidering them as documentation if that would be more beneficial.

Copy link
Member

@jedel1043 jedel1043 Feb 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The rule of thumb is to have examples that demonstrate HOW to use the APIs as doc comments, and to have examples that demonstrate WHEN to use the APIs as code examples.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The module level rustdoc documentation was more what I meant in this instance. The examples don't have to be a completely different from those in examples. Mostly since the Rust documentation will be auto generated into the docs, which is super handy and may be the first place someone consuming the API would go for information. For example, here's the JsPromise docs for reference

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, here i created the first rust doc test

the preview looks like:
image

I intend to keep drawing considerable inspiration from MDN for comments. What are your thoughts? Should I proceed with implementing Rust doc tests throughout the module? Do you have any specific considerations or tips to share?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks really nice! I think it's a good call to adapt the examples from MDN, since it removes the effort of having to come up with descriptive usages.

As a small suggestion, I would remove the "The FindIndex method of Array instances" prefix, since it is mostly idiomatic to start a method's documentation with a verb; in this case, "Returns the index of...".

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added doc tests to all the functions I've touched. Give me feedback!

@AngeloChecked AngeloChecked force-pushed the JsTypedArray_methods branch 2 times, most recently from 703411b to c5e0b76 Compare February 18, 2024 16:30
Copy link
Member

@nekevss nekevss left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is looking great! I have a one nit about the docs, but nothing else really.

core/engine/src/object/builtins/jstypedarray.rs Outdated Show resolved Hide resolved
Copy link
Member

@nekevss nekevss left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Thanks for contributing to Boa! 😄

EDIT: Looks like this needs a cargo fmt -all

@AngeloChecked
Copy link
Contributor Author

AngeloChecked commented Feb 24, 2024

LGTM! Thanks for contributing to Boa! 😄

EDIT: Looks like this needs a cargo fmt -all

Done!

And sure... please close this PR. However, if we want to discuss the points further:

i don't know how to implement it

  • toString

iterators are unstable

desired features

  • Easily return the inner data as &[u8] or &Vec

I'm open to contribute. I'm also open to adding(the remaining) Rust test documentation to the jstypedarray module in another pull request. What do you think?

@jedel1043
Copy link
Member

jedel1043 commented Feb 24, 2024

Easily return the inner data as &[u8] or &Vec

I think it's fine to only expose this in ArrayBuffer and SharedArrayBuffer. We already allow getting the inner buffer of the typed array, and projecting to another inner object would mean handling two runtime borrows at the same time, which is not ideal.

Copy link
Member

@jedel1043 jedel1043 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really nice work! It's also really helpful to have so many new doc tests for this wrapper. There are definitely some other optimizations that can be done, but having the methods in place is already a big improvement.

@jedel1043 jedel1043 added this pull request to the merge queue Feb 24, 2024
Merged via the queue into boa-dev:main with commit 14b34fe Feb 24, 2024
14 checks passed
@nekevss nekevss added this to the v0.18.0 milestone Feb 28, 2024
@jedel1043 jedel1043 removed the waiting-on-review Waiting on reviews from the maintainers label Sep 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
builtins PRs and Issues related to builtins/intrinsics enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants