DelSkayn / rquickjs

High level bindings to the quickjs javascript engine
MIT License
431 stars 58 forks source link

Update rquickjs to the newest version of QuickJS #293

Closed DelSkayn closed 2 months ago

DelSkayn commented 2 months ago

This PR updates the version of QuickJS used by rquickjs to the newest version. QuickJS has some rather significant changes since the last release which impact rquickjs. As a result rquickjs will have to introduce some breaking changes.

Changes

Promise

rquickjs::Promise is renamed to rquickjs::PromiseFuture and a new Promise struct is introduced. Unlike the previous promise struct the new one isn't a future by default, allowing it to be used by non-async code. You can turn the promise into a future if desired and future feature is enabled. You can also manually access the state and result of a promise allowing you to implement polling methods on the promises yourself if required.

Modules

A lot of the current design for modules was made to work around the problem of QuickJS freeing modules which were not evaluated if any module returned an error during evaluation. This is no longer the case. Unfortunately there are some functions which will segfault if they are called on an unevaluated module so we still need some safety system to avoid calling those functions. Furthermore with the introduction of top level await support in QuickJS the evaluation of a module now returns a promise. This means I needed to redesign the module API to support this.

Modules are now, once again, safe to hold onto once declared. Ctx::compile is removed, it didn't make sense since evaluating a module no longer returns the module but a promise which itself also doesn't return the module. If you want or replicate the behaviour of Ctx::compile you will have to first declare a module and then call eval on that module and make sure the promise is resolved. Further more modules are now tagged with a marker type: either Declared or Evaluated. There are some functions which you are only able to call after you make sure that the module is evaluated which is what these marker types are used for.

Most of the functions dealing with retrieving modules exports have been removed in favor of an approach based of the new QuickJS function JS_GetModuleNamespace which returns an object with all the exports of the module. This function can no be safely called with Module::<Evaluated>::namespace.