Skip to content

feat(builtins): implement JsAsyncGenerator safe wrapper#4755

Merged
jedel1043 merged 4 commits intoboa-dev:mainfrom
KaustubhOG:feat/js-async-generator-wrapper
Mar 1, 2026
Merged

feat(builtins): implement JsAsyncGenerator safe wrapper#4755
jedel1043 merged 4 commits intoboa-dev:mainfrom
KaustubhOG:feat/js-async-generator-wrapper

Conversation

@KaustubhOG
Copy link
Contributor

Implements the JsAsyncGenerator safe Rust wrapper as part of #2098.

Adds core/engine/src/object/builtins/jsasyncgenerator.rs with:

  • from_object(object: JsObject) -> JsResult<Self>
  • next(value, context) -> JsResult<JsValue>
  • return(value, context) -> JsResult<JsValue>
  • throw(value, context) -> JsResult<JsValue>
  • From<JsAsyncGenerator> for JsObject and JsValue
  • Deref to JsObject
  • TryFromJs impl

Follows the same pattern as JsGenerator.

@KaustubhOG KaustubhOG requested a review from a team as a code owner February 28, 2026 09:24
@github-actions
Copy link

github-actions bot commented Feb 28, 2026

Test262 conformance changes

Test result main count PR count difference
Total 52,862 52,862 0
Passed 49,505 49,505 0
Ignored 2,261 2,261 0
Failed 1,096 1,096 0
Panics 0 0 0
Conformance 93.65% 93.65% 0.00%

Tested PR commit: 470d550032d2969e02acf7b924650fd2bff01b93

@codecov
Copy link

codecov bot commented Feb 28, 2026

Codecov Report

❌ Patch coverage is 0% with 36 lines in your changes missing coverage. Please review.
✅ Project coverage is 57.18%. Comparing base (6ddc2b4) to head (470d550).
⚠️ Report is 711 commits behind head on main.

Files with missing lines Patch % Lines
...ore/engine/src/object/builtins/jsasyncgenerator.rs 0.00% 36 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4755      +/-   ##
==========================================
+ Coverage   47.24%   57.18%   +9.93%     
==========================================
  Files         476      554      +78     
  Lines       46892    60654   +13762     
==========================================
+ Hits        22154    34682   +12528     
- Misses      24738    25972    +1234     

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

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@nekevss nekevss added builtins PRs and Issues related to builtins/intrinsics API labels Feb 28, 2026
Comment on lines 40 to 71
pub fn next<T>(&self, value: T, context: &mut Context) -> JsResult<JsValue>
where
T: Into<JsValue>,
{
AsyncGenerator::next(&self.inner.clone().into(), &[value.into()], context)
}

/// Calls `AsyncGenerator.prototype.return()`.
///
/// More information:
/// - [MDN documentation][mdn]
///
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/AsyncGenerator/return
pub fn r#return<T>(&self, value: T, context: &mut Context) -> JsResult<JsValue>
where
T: Into<JsValue>,
{
AsyncGenerator::r#return(&self.inner.clone().into(), &[value.into()], context)
}

/// Calls `AsyncGenerator.prototype.throw()`.
///
/// More information:
/// - [MDN documentation][mdn]
///
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/AsyncGenerator/throw
pub fn throw<T>(&self, value: T, context: &mut Context) -> JsResult<JsValue>
where
T: Into<JsValue>,
{
AsyncGenerator::throw(&self.inner.clone().into(), &[value.into()], context)
}
Copy link
Member

Choose a reason for hiding this comment

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

All of these should return JsResult<JsPromise> to follow the protocol of AsyncGenerator

Copy link
Contributor Author

@KaustubhOG KaustubhOG Feb 28, 2026

Choose a reason for hiding this comment

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

yup i was waiting for that one, i try to handle it same way #4756 was handled , i made changes have a look @jedel1043 ?

let async_gen = JsAsyncGenerator::from_object(obj).unwrap();

// next() returns a Promise
let promise = async_gen.next(JsValue::undefined(), &mut context).unwrap();
Copy link
Member

Choose a reason for hiding this comment

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

What you could do here is to call context.run_jobs() to resolve the promise, then you should be able to access the value 1 from its state.

Copy link
Member

Choose a reason for hiding this comment

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

That way we at least show that promises can only go forward if you call context.run_jobs()

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yup let me handle this quickly

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@jedel1043 i made some changes u suggested me , have a look at it

let promise = async_gen.next(JsValue::undefined(), &mut context).unwrap();
drop(context.run_jobs());
if let PromiseState::Fulfilled(val) = promise.state() {
println!("next resolved with: {}", val.display());
Copy link
Member

Choose a reason for hiding this comment

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

Would be kinda better to assert_eq with a JsValue::from(1) to test that the function returns the correct value.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hi @jedel1043, updated the example to use assert_eq! to verify the resolved promise values — JsValue::from(1) for next and JsValue::from(42) for return. The assertions pass cleanly. is it what you mean to test the function or any other way ?

Copy link
Member

Choose a reason for hiding this comment

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

Yep, pretty much what I meant

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.

Looks good!

@jedel1043 jedel1043 added this pull request to the merge queue Mar 1, 2026
Merged via the queue into boa-dev:main with commit 12a30b1 Mar 1, 2026
19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

API builtins PRs and Issues related to builtins/intrinsics

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants