On Mon, Feb 25, 2019 at 5:12 PM 'Steven Johnson' via v8-users < v8-users@googlegroups.com> wrote:
> 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"? > I'm not familiar with these, but do know about HEAP8, HEAP32, etc. :) The code I get generated does not have either of those symbols; it might be to support some C++ structure you have... All the code I compiled was actually C. The basic C library support all works as expected (fopen for instance). > > Was far as I know, the WASM code is basically self contained and doesn't > immediately provide interface with javascript. > I used WASM and compiled a GSM codec (audio). THis is the script I used to build it... There's several options to export functions for JS to call. The batch file includes `-s EXPORTED_FUNCTIONS="['_gsm_create','_gsm_decode','_gsm_encode']"` https://github.com/d3x0r/gsm/blob/master/x.bat The readme here shows basically how to use _gsm_create, _gsm_decode and _gsm_encode. https://github.com/d3x0r/gsm-wasm To get JS arrays/strings into the WASM code you need to malloc in the wasm heap, and copy the data to the buffers; primitive values (numbers/strings) pass through simply enough. And yes, there is very bad support for inter-oping the other direction; The other thing I was playing with WASMing is a JSOX(JSON variant) parser, but creating the objects on the .parse() side of things is very hairy. But most of these issues would be Emscripten; since WASM has to interop with other JS engines, and not just V8. > > > -- > -- > v8-users mailing list > v8-users@googlegroups.com > 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 v8-users+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. > -- -- v8-users mailing list v8-users@googlegroups.com 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 v8-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.