Skip to content
This repository was archived by the owner on Aug 17, 2022. It is now read-only.
This repository was archived by the owner on Aug 17, 2022. It is now read-only.

Instructions for duplicating and swapping values on stack #118

Open

Description

@mikevoronov

Hi! I am trying to use WIT for server-side modules and found that it is a bit tricky. Basically, because there are no "common" instructions to stack-based virtual machines like dup and swap. In my setup I have several Wasm modules with separate incapsulated memories. Each module could have exports/imports with corresponding adapters.

Let's imagine two modules: ipfs_node and ipfs_rpc. The first, ipfs_node has exports with corresponding adapters. The second, ipfs_rpc also has exports and imports from ipfs_node. Each adapter has following type @interface type (func (param string) (result string))). So let's follow a little bit a process of calling ipfs_node imports from ipfs_rpc:

;; ipfs_rpc: adapter for import function ipfs.get
(@interface func (type 9)
    arg.get 0
    arg.get 1
    string.lift_memory
    call-core 9             ;; call ipfs_node.get that returns string
    dup
    string.size
    call-core 0             ;; call allocate
    swap2
    string.lower_memory
    call-core 5             ;; call set_result_size
    call-core 6             ;; call set_result_ptr
)

;; ipfs_node: adapter for export function get
(@interface func (type 8)
    arg.get 0
    string.size
    call-core 0         ;; call allocate
    arg.get 0
    string.lower_memory
    call-core 7         ;; call self.get
    call-core 3         ;; call get_result_ptr
    call-core 2         ;; call get_result_size
    string.lift_memory
    call-core 3         ;; call get_result_ptr
    call-core 2         ;; call get_result_size
    call-core 1         ;; call deallocate
)

Here I am using functions like {get, set}_result_ptr, {get, set}_result_size, because Wasmer isn't support multi-value now. So the interesting part of this flow is following:

  1. Raw ipfs.get called from Wasm side of ipfs_rpc. It receives two i32 (ptr and size).
  2. These 3 instructions are needed to get string from memory of ipfs_rpc
   arg.get 0
   arg.get 1
   string.lift_memory
  1. Then ipfs_node export adapter is called and returns string on the stack.
  2. Then we need to push this string to memory of the ipfs_rpc module. To do this we have to lower memory with string.lower_memory that consumes string object and pointer to module memory from the stack. In its turn, to obtain module memory pointer we need string size, so we have to call string.size that also consumes string object. So here we need some mechanism for duplicating and swapping values on stack. I solved it with following set of instructions (I extended WIT interpreter with these two instructions):
    dup
    string.size
    call-core 0             ;; call allocate
    swap2
    string.lower_memory

I don't know is it possible to do this without very messy tricks like returning string object together with its size from callee module. It seems reasonable to add these possibilities in some form.

Activity

  1. fgmccabe commented on Jun 24, 2020

    @fgmccabe
    Contributor

    instead of stack ops like dup, swap etc we are proposing the use of let: effectively a temporary local. This is part of the function reference types proposal https://github.com/WebAssembly/function-references/blob/master/proposals/function-references/Overview.md

  2. mikevoronov commented on Jun 24, 2020

    @mikevoronov
    Author

    Thanks! Will take a look, are there any plans to include let to the WIT proposal in the nearest future?

  3. fgmccabe commented on Jun 24, 2020

    @fgmccabe
    Contributor

    I don't know what WIT folk are planning. But, they will likely follow what goes on in Interface Types on this kind of issue.

  4. changed the title [-]Instructions for duplicating and swapping values ion stack[/-] [+]Instructions for duplicating and swapping values on stack[/+] on Jun 24, 2020
  5. mikevoronov commented on Jun 24, 2020

    @mikevoronov
    Author

    Maybe I am getting smth wrong, are WIT (Wasm Interface Types) and Interface Types the same thing? Or maybe you mean Typed Functions instead of Interface Types.

  6. fgmccabe commented on Jun 24, 2020

    @fgmccabe
    Contributor

    WIT is a sub-proposal which is part of WASI. Not really the same as Interface Types; although there is a somewhat close connection :)

  7. mikevoronov commented on Jun 24, 2020

    @mikevoronov
    Author

    Ohh, I thought it is called WITX (or module types/linking) :). Thank you.

  8. mikevoronov commented on Jun 24, 2020

    @mikevoronov
    Author

    So, are there any plans to include let to the interface-types proposal in the nearest future? :) I am super interested in it, because our current sub-idea (Wasm RPC) is based on interface types (yes, we know that interface-types is very unstable, but the only alternative to us is to write something like that ourself).

  9. fgmccabe commented on Jun 24, 2020

    @fgmccabe
    Contributor

    this is still under discussion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions