I'm experimenting with embedding V8 in a test app in order to load,
compile, and run wasm bytecode that has been generated by LLVM (using V8
7.4.x and recent trunk versions of LLVM)
Loading and running seems simple enough
(via WasmModuleObject::DeserializeOrCompile), but calling the resulting
functions from C++ seems tricky, because, well, it's not clear that there's
a public V8 API for actually looking at what's in the resulting
WasmModuleObject; in JavaScript, you can apparently do something like
let module = new WebAssembly.Module(buffer)
let imports = { ... map of funcs that are declared as 'import' by
the module, if any ... }
let instance = new WebAssembly.Instance(module, imports);
let myfunc = instance.exports["myfunc"];
myfunc(...);
but a similar API doesn't seem to be surfaced for C++, at least not in the
public API.
I've tried replicating the JavaScript calls from C++, but there's a big
problem: it appears that the 'imports' argument is required to be
v8::internal::Handle<v8::internal::JSReceiver>, which (AFAICT) there isn't
a clean way to create and manipulate directly from the C++ API, at least
certainly not from the public API:
Local<WasmModuleObject> module =
WasmModuleObject::DeserializeOrCompile(
isolate, {nullptr, 0}, {source, source_len}).ToLocalChecked();
v8::internal::Handle<v8::internal::JSReceiver> imports = ???; //
Oh well
Local<Value> args[2] = { module, imports };
Local<Object> module_instance_exports = context->Global()
->Get(context, String::NewFromUtf8(isolate,
"WebAssembly")).ToLocalChecked().As<Object>()
->Get(context, String::NewFromUtf8(isolate,
"Instance")).ToLocalChecked().As<Object>()
->CallAsConstructor(context, 2,
args).ToLocalChecked().As<Object>()
->Get(context, String::NewFromUtf8(isolate,
"exports")).ToLocalChecked().As<Object>()
;
I suppose I could accomplish this by adding some extra JS-only wrapper code
that does the necessary magic, but that's going to add another layer of
indirection that surely shouldn't be necessary here (since the code in
question here is otherwise free of JavaScript).
The thing that makes this extra-fun is that apparently LLVM injects a
couple of symbols into the import table of every bit of wasm it generates
("__linear_memory" and "__indirect_function_table")... which don't appear
to be referenced in any code in V8 that I can find, so their purpose is a
bit of a mystery to me. (Perhaps holdovers from older implementations of
wasm?) In any event, I'm almost certainly going to have other imports I
need to fill in here (for glue functions), so figuring out how to to
accomplish this is probably essential to my task.
So...
(1) Is there an explicit API to access/call wasm-compiled functions from
C++? Is so, where may I find it? If not, um, shouldn't we have one?
(2) If there isn't a C++ API for this (and/or isn't going to be one anytime
in the very near future), is the above approach the most reasonable
workaround for now?
(3) If the above mimic-JS-from-C++ approach is reasonable, is there a clean
way to specify the imports table?
(4) Finally, just out of curiosity, anyone know what the story is with
"__linear_memory" and "__indirect_function_table"?
--
--
v8-users mailing list
[email protected]
http://groups.google.com/group/v8-users
---
You received this message because you are subscribed to the Google Groups
"v8-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.