Stream: StarlingMonkey

Topic: Exporting JS functions as guest exports


view this post on Zulip Piotr Sarnacki (Oct 10 2024 at 21:23):

I'm playing with StarlingMonkey and one thing that I can't figure out at the moment is how to export javascript functions as guest component exports. Let's say I have a .wit file like:

world foo {
  export print-foo: func();
}

I can embed the .wit file into the component, but I'm not quite sure how tell StarlingMonkey to export a certain function as print-foo. Are there any examples somewhere that would show such a thing? Is the only way to add it as C++ (or maybe Rust?) code and compile into the binary?

view this post on Zulip Piotr Sarnacki (Oct 10 2024 at 21:29):

Ok, sorry, I somehow missed host-apis paragraph in the README :sweat_smile: I'll try doing that!

view this post on Zulip Piotr Sarnacki (Oct 11 2024 at 01:17):

Ok, so I had a bit of time to play with that and the last piece of code I'm missing is how to get an exported function using SpiderMonkey's API and call it :thinking: I'm componentizing a JS file with sth like export function foo() { }. Now in here I have to get the function and call it and I'm not that familiar with SpiderMonkey APIs yet. I've been reading a bit of the source code of StarlingMonkey, but I couldn't find any place where exports are handled.

The StarlingMonkey JS runtime. Contribute to drogus/StarlingMonkey development by creating an account on GitHub.

view this post on Zulip Piotr Sarnacki (Oct 11 2024 at 08:59):

Ok, I figured out the general principle when I have a module:

  JS::RootedObject ns(cx, JS::GetModuleNamespace(cx, module));
  JS::RootedValue val(cx);
  JS_GetProperty(cx, ns, "foo", &val);
  RootedValue rval(cx);
  JS_CallFunctionValue(cx, ENGINE->global(), val,  HandleValueArray::empty(), &rval);

Now only to figure out how to get the module from where I get the host API call

view this post on Zulip Piotr Sarnacki (Oct 11 2024 at 12:40):

I figured out how to call the script in the context of the host_api.cpp file (for anyone interested it's here), but my C++ memory is quite rusty as I haven't done any C++ in more than 15 years and the only way I found to have access to ENGINE in the host_api.cpp file was to change static api::Engine *ENGINE to extern "C" api::Engine *ENGINE in js.cpp. I'm pretty sure there's a better way, but not sure what would make it work without changing the project code :thinking:

The StarlingMonkey JS runtime. Contribute to drogus/StarlingMonkey development by creating an account on GitHub.

view this post on Zulip Guy Bedford (Oct 11 2024 at 17:55):

There is an "install" hook for builtins which gives the engine as an argument. Follow the builtin pattern via a CMake setup per https://github.com/bytecodealliance/StarlingMonkey?tab=readme-ov-file#using-starlingmonkey-as-a-cmake-sub-project, eg in Fastly we do this - https://github.com/fastly/js-compute-runtime/blob/main/runtime/fastly/CMakeLists.txt

The StarlingMonkey JS runtime. Contribute to bytecodealliance/StarlingMonkey development by creating an account on GitHub.
JavaScript SDK and runtime for building Fastly Compute applications - fastly/js-compute-runtime

view this post on Zulip Piotr Sarnacki (Oct 11 2024 at 19:16):

@Guy Bedford thanks for the link, I'll take a look!


Last updated: Dec 23 2024 at 13:07 UTC