What does Polywrap's WebAssembly layer look like?


# Today (Nov 2022) In its current form, Polywrap interacts with WebAssembly through a series of pre-defined imports & exports. For example: ```rust /// exports /// // invoke wrap method export fn _wrap_invoke( method_size: u32, args_size: u32, env_size: u32 ) -> bool; /// imports: invoke /// // get invoke arguments extern fn __wrap_invoke_args( method_ptr: u32, args_ptr: u32 ) -> void; // set invoke result extern fn __wrap_invoke_result( ptr: u32, len: u32 ) -> void; // set invoke error extern fn __wrap_invoke_error( ptr: u32, len: u32 ) -> void; /// imports: subinvoke /// // subinvoke a wrap method extern fn __wrap_subinvoke( uri_ptr: u32, uri_len: u32, method_ptr: u32, method_len: u32, args_ptr: u32, args_len: u32, ) -> bool; // get subinvoke result extern fn __wrap_subinvoke_result_len() -> u32; extern fn __wrap_subinvoke_result(ptr: u32); /// get subinvoke error extern fn __wrap_subinvoke_error_len() -> u32; extern fn __wrap_subinvoke_error(ptr: u32); /// and a few more imports for: env, abort, debug, etc ``` The goal of these exports & imports is to enable what we currently call the "WebAssembly Random Access Protocol" or "WRAP" for short. This is something that's still early, but gradually becoming more and more robust. To see an initial vision document on what WRAP is intended to do, you can see here: https://github.com/polywrap/specification/blob/main/standard/01.0%20General%20Standard/WRAP%20Standard.md ### Source Pointers WRAP Exports: https://github.com/polywrap/toolchain/blob/origin-0.9/packages/schema/bind/src/bindings/rust/wasm/templates/entry-rs.mustache#L17 https://github.com/polywrap/toolchain/blob/origin-0.9/packages/js/wasm/src/WasmWrapper.ts#L48-L49 WRAP Imports: https://github.com/polywrap/toolchain/blob/origin-0.9/packages/js/wasm/src/imports.ts#L19-L223 https://github.com/polywrap/toolchain/blob/origin-0.9/packages/wasm/rs/src/invoke.rs#L3-L16 https://github.com/polywrap/toolchain/blob/origin-0.9/packages/wasm/rs/src/subinvoke.rs#L3-L29 # Tomorrow (?) Recently [NerfZael](https://github.com/nerfzael) has published a revision of this Wasm boundary, initially called "Dt", which stands for "data transfer". It is much more generic, and simply deals in the abstraction of transfering data from one DtInstance to another. ```rust /// exports /// export fn _dt_receive: (buffer_len: u32) -> u32; ``` And the imports are very simple to implement, like so: ```typescript const imports = { __dt_fill_input_buffer: (bufferPtr: u32): void => { writeBytes(this.state.inputBuffer, this.memory.buffer, bufferPtr); }, __dt_send: async (bufferPtr: u32, bufferLen: u32): Promise => { const buffer = readBytes(this.memory.buffer, bufferPtr, bufferLen); this.state.sendResult = await this.state.onReceive(new Uint8Array(buffer)); return this.state.sendResult.byteLength; }, __dt_fill_send_result: (bufferPtr: u32): void => { writeBytes(this.state.sendResult, this.memory.buffer, bufferPtr); }, } ``` The WRAP standard as we know it today can be built on-top as units of functionality, that could themselves be within Wasm. How do you know what WRAP features a given Wasm module has? Well this is what the "wrap.info" file is for, allowing one DtInstance to invoke functionality in another. ### Open Questions - How do we further describe the "Dt Standard"? - What are the benefits of further abstracting the Wasm boundary? - How can we know this will provide better feature detection & less breaking changes? ### Source Pointers Dt Instance: https://github.com/polywrap/reimagined/blob/develop/js/packages/dt/src/IDtInstance.ts Dt Wasm Exports: https://github.com/polywrap/reimagined/blob/b3f637d872c820a0db59e0044d96a7b05bee02b8/js/packages/dt-wasm/src/DtExports.ts#L4 Dt Wasm Imports: https://github.com/polywrap/reimagined/blob/develop/js/packages/dt-wasm/src/DtImports.ts#L12-L24

Answers 0