-
-
Notifications
You must be signed in to change notification settings - Fork 407
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
Implement asynchronous evaluation of scripts #3044
Conversation
Test262 conformance changes
|
Codecov ReportAttention:
Additional details and impacted files@@ Coverage Diff @@
## main #3044 +/- ##
==========================================
- Coverage 45.78% 45.73% -0.06%
==========================================
Files 483 483
Lines 49349 49427 +78
==========================================
+ Hits 22594 22603 +9
- Misses 26755 26824 +69
☔ View full report in Codecov by Sentry. |
@HalidOdat you mentioned in #2904 that you wanted to refactor how we call functions to not recurse on the rust side. That would probably impact the design of this feature right? |
Ah, seems like @HalidOdat and I arrived at the same problem from two different but related features. We could probably solve both problems using the same solution then :) |
The solution I thought of was to have only one The How do we know if we should return or continue executing until we run out of call frames? For this we can have a flag in the call frame that returns in This would greatly simplify our calling logic! Not having to do a clone of the passed arguments and reversing them and pushing them back again instead just using the ones that where already pushed by the Note: This stops recursion (and causing a stack overflow) from JavaScript, You can still recurse in rust, by recursively calling a function that calls |
That sounds perfect to avoid recursing inside JS functions. We could implement that first, then think about how to avoid recursing inside Rust functions next. |
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.
Looks good! Just an memory optimization
I don't think this addition would make the call refactor any harder :)
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.
Looks good to me! :)
We can reduce the spend
function table which I did in #3401, we can merge this first, or merge into this?
Let's just merge it into this, since they're related changes :) |
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.
Nice work! I like the updates! 😄
* Implement asynchronous evaluation of scripts * cargo fmt * FIx fuzz build * Reduce execution table size --------- Co-authored-by: Haled Odat <8566042+HalidOdat@users.noreply.github.com>
This Pull Request implements and API to asynchronously run scripts.
Had to do some refactoring in order to share code between
run
andrun_async_with_budget
, but I ran the QuickJS benchmark and everything looks good!However, our engine has a big limitation right now: we cannot track the executed instructions of called functions because those internally useSolved by #3295run
. For this reason, this PR just tracks instructions executed in the root script being executed, but this can be implemented in the future.Some context
We have used this pattern of freely calling
run
inside several functions because it's easy to reason about, andContext
owns the current VM state. However, it is really unusual to have VM state inside a sharedContext
, and usingrun
this way causes problems that we've already seen but ignored, like duplicate prints of functions' bytecode when using tracing.If we can pull off the separation of the VM from the Context, we could even make the context reference we pass to every function an immutable one (
&Context<'_>
), which will unblock a LOT of patterns that we've been largely working around.Having said that, I have some ideas on how to make this work. This will probably involve changing the return value of our functions and some generator shenanigans, but I found an interesting crate that implements them using async/await, which makes them available on stable code (https://github.com/whatisaphone/genawaiter).
I'm open to any other ideas you have! The gist of problem is: "How to bubble up JS function calls to the original
Context::run
call".Anyways, sorry for the info dump.