how does async work / how is async going to work in starlight #49
-
Based on what you said in #44 i had a look at function.rs and generator.rs and i don't quite understand how that is going to work async JavaScript engines typically rely on running in an EventLoop and provide a way to expose jobs which should be added to that loop. QuickJS has an internal vec of pending jobs accessed by calling JS_IsJobPending() and then JS_ExecutePendingJob() (the downside of this is that you have call those after everything you do with the quickjs runtime). Spidermonkey has a more elegant solution, you can add a hook (fn/closure) for when an async job has to run (SetJobQueue()) For quickjs I implemented an generic EventLoop here: https://github.com/HiRoFa/utils/blob/master/src/eventloop.rs For Promises in starlight i was planning to add a simple hook (vm.registerJobAddHookThingy(Fn(Job)) which in turn adds the job to the EventLoop so it wil run async (but in the same thread) but i'm wondering if that's the way you want to go or have an other solution for async jobs...? |
Beta Was this translation helpful? Give feedback.
Replies: 14 comments 5 replies
-
I was talking on how async function state should be saved/restored and not the actual impl. I don't actually know what is the best way to implement promises and async fns for JS engine actually. All my experience with coroutines is all in greenie which implements green threads and nothing more. |
Beta Was this translation helpful? Give feedback.
-
i'll see what I can come up with and get back to you with a suggestion later ok? |
Beta Was this translation helpful? Give feedback.
-
That would be awesome! I still haven't finished exams so I do not have much time to work on such complex things like async. :( |
Beta Was this translation helpful? Give feedback.
-
Well get back to studying then! i don't want to be the one that distracted you from your exams! ;) Good luck with your exams! |
Beta Was this translation helpful? Give feedback.
-
Thank you! Btw if you have questions about internals of Starlight I guess GH Discussions is better place. :) |
Beta Was this translation helpful? Give feedback.
-
ok, so i made some first steps for async support you can see my suggestion here https://github.com/HiRoFa/starlight/commit/a6e32c222fb3706a5fcdfccae4f3d45a51301938 i'm going for the spidermonkey strategy of beeing able to register jobs as async, is added this as an option in the RuntimeParams struct I also added a test as an example which implements a setImmediate function (the sole purpose of which is do something async) First of all of course i'd like to know what you think of the direction i'm going, and also what is the simplest way to turn a String into a JsValue :)? Later i'm going to try an implement a Promise class using your define_jsclass! macro |
Beta Was this translation helpful? Give feedback.
-
@playXE Can i regard a JsValue as a Handle to a GcPointer which means that as long as i don't drop all the JsValues the contained object will not be garbage collected? or do i need to do something extra to prevent garbage collection of an Object like my JsPromise? |
Beta Was this translation helpful? Give feedback.
-
looks like a No, your shadowstack seems closely modelled to spidermonkey, Can i just move a Rooted<JsValue> in a closure to prevent contained objects from beeing garbage collected? or do i need something like spidermonkey's PersistentRooted struct? |
Beta Was this translation helpful? Give feedback.
-
@playXE see my code here i guess it has to do with GC but i'm unsure how to keep a JsValue from getting garbage collected... |
Beta Was this translation helpful? Give feedback.
-
@andrieshiemstra sorry for not answering your questions for too long, I have been busy for these few days. To be sure it is GC problem debugging is needed or you can enable conservative scanning for GC references in
Simply use
Your design looks nice, I think SerenityOS's LibJS does a similar thing.
Just invoke |
Beta Was this translation helpful? Give feedback.
-
Rooted is strictly bonded to shadow stack instance lifetime so you can't move it to the closure. I haven't worked on persistent roots but if you really need them I guess I could try to implement 'em. |
Beta Was this translation helpful? Give feedback.
-
No problem at all, i know you're busy. Are your exams going ok?
Thanks, i'll continue this way. i'll also have a look at SerenityOS's LibJS for educational purposes :)
Haha , yeah i managed to figure that one out :)
Well in order to keep objects rooted which are moved into a closure i think we kinda need something like that, basicly we just need something like spidermonkeys addRoot and removeRoot methods which just add a Trace to some collection and make sure the GC traces those. A PersistentRooted struct would just call those methods on init and drop so we have a nice wapper. My first idea would be to add that collection and methods to Hmm, maybe it would be nicer to just have a HashMap or something in Runtime and trace that in the closure passed to this.gc.add_constraint() at line 595 in vm.rs? |
Beta Was this translation helpful? Give feedback.
-
Question, still getting SIGABORT with my promise code In https://github.com/HiRoFa/starlight/blob/dev/crates/starlight/src/vm/promise.rs#L372 I impld Trace for my Promise class, but is that enough? or do i need to implement something somewhere to actually trace my JsPromise struct? my testcase is still randomly passing or failing (if i disable GC the results are the same so i'm also wondering if realy is a GC issue..) |
Beta Was this translation helpful? Give feedback.
-
i altered the code to resemble your File example now it fails just as often but always with a stackoverflow, vm.rs/Runtime has a with_heap() method.. at the end it calls
i'll continue debugging tomorrow but insights are appreciated :) |
Beta Was this translation helpful? Give feedback.
@andrieshiemstra sorry for not answering your questions for too long, I have been busy for these few days. To be sure it is GC problem debugging is needed or you can enable conservative scanning for GC references in
GcParams
or usingsl --conservative-marking
It will check stack and registers for potential GC pointers so even If you didn't root some value GC will scan it.Simply use
letroot!(val = stack, JsValue::<smth>)
and GC will s…