-
Notifications
You must be signed in to change notification settings - Fork 10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
An example of how to provide import functions? #185
Comments
@TUSF thanks for the issue and apologies for the current lack of documentation. There are some examples in the Define a function taking the fn print_i32(vm: *VirtualMachine) WasmError!void {
const value = vm.popOperand(i32);
std.debug.print("print_i32: {}\n", .{value});
} The function can access parameters via, say, popping off of the wasm stack. With the function written, it also needs to be registered with the runtime. This is quite clunky (at the moment), but you get the gist here: var print_i32_params = [_]ValType{.I32} ** 1;
var print_i32_results = [_]ValType{.I32} ** 0;
const print_i32_handle = try store.addFunction(Function{
.params = print_i32_params[0..],
.results = print_i32_results[0..],
.subtype = .{
.host_function = .{
.func = print_i32,
},
},
});
const print_i32_name = "print_i32";
try store.@"export"(spectest_module[0..], print_i32_name[0..], .Func, print_i32_handle); I would also recommend looking at @leroycep's For the future I would like:
|
Yes, I had actually found that project right after submitting this issue, and found it helpful in understanding what was going on. I suppose given that there's only one operand stack, any host function would have to pop off all of the parameters on the stack if they want to return any useful results first. Mind if I ask if there was a reason for that? |
At least at the moment, there is fixed function pointer type for these host functions. That doesn't leave much option in terms the signature of these functions and so I've ended up with the only parameter is the Honestly, having implement all of this, I'm a bit close to it and could use some outside perspective. Is there some way that you'd like to define host functions that might be a bit nice ergonomically? |
Well, the current way to do things is fairly low level, which I wouldn't say is a bad thing, but I guess I would want a more high-level way to do things. I think some higher level helper functions would be good to have, just to make things easier to read. Something like: fn addAndPrint(vm: *VirtualMachine) WasmError!void {
const ParamsType = struct { a: i32, b: i32 };
const args = vm.popParams(ParamsType);
const results = .{args.a + args.b};
vm.pushResults(results);
std.debug.print("print_i32: {}\n", results);
} The idea here would be that Further, I think you can make the registration of host functions less clunky by having a single store.addHostFunction("module", "print_i32",
print_i32, // The function handler.
.{.I32}, // Params, as a tuple of ValType
.{.I32} // Results, as a tuple of ValType
) |
Thinking we might also expand |
#199 adds wrappers for exported functions |
I've renamed |
In #206 |
There's an example for invoking a function from an instance, but with so little documentation, one has to dig through the code to figure out how to provide host functions, and even then, I'm not quite sure I understand how to go about it.
The text was updated successfully, but these errors were encountered: