Skip to content
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

Use main entrypoint for note scripts #350

Open
greenhat opened this issue Oct 30, 2024 · 3 comments
Open

Use main entrypoint for note scripts #350

greenhat opened this issue Oct 30, 2024 · 3 comments
Assignees
Milestone

Comments

@greenhat
Copy link
Contributor

I compiled this P2ID note script using the main entrypoint:

#![no_std]
#![no_main]

#[global_allocator]
static ALLOC: miden::BumpAlloc = miden::BumpAlloc::new();

#[panic_handler]
fn my_panic(_info: &core::panic::PanicInfo) -> ! {
    loop {}
}

mod bindings;

fn main() {
    let inputs = miden::note::get_inputs();
    let target_account_id_felt = inputs[0];
    let account_id = miden::account::get_id();
    assert_eq!(account_id.as_felt(), target_account_id_felt);
    let assets = miden::note::get_assets();
    for asset in assets {
        bindings::miden::basic_wallet::basic_wallet::receive_asset(asset);
    }
}

#[no_mangle]
fn __main_void() -> i32 {
    main();
    0
}

#[no_mangle]
fn __wasm_call_dtors() {}

#[no_mangle]
fn __wasi_proc_exit(_: u32) {}

__* Rust functions need to be defined to make component encoder happy. Otherwise, it will fail on unknown imports. I presume they are only implemented in std environment. The command component is heavy on wasi:* code for I/O, files, etc. so I believe no_std is not really supported for the command components. We can "hide" those functions in the Miden SDK crate or generate via macros.

The Rust code above compiles to the following Wasm component - https://gist.github.com/greenhat/5ea1e3c0651f717137f778d958b5cbd3

There are two problems with this component:

  1. The second core module (core module (;1;)) with all wasi:* machinery is brought in by the adapter in cargo-component at https://github.com/bytecodealliance/cargo-component/blob/37c042e3340c25cfcb3646a2445e46321289bbfe/src/lib.rs#L900-L902 and is built from https://github.com/bytecodealliance/wasmtime/blob/b9874992ba92b06cbbfab7131ef740ba4c10720f/crates/wasi-preview1-component-adapter/src/lib.rs# crate in wasmtime repo.
    I want to craft our own some sort of "empty" adapter to get rid of the wasi:* code.

  2. The _start function is supposed to be the entrypoint for the command component (used in the second core module):

    (func $_start (;6;) (type 5)
      (local i32)
      block ;; label = @1
        block ;; label = @2
          global.get $GOT.data.internal.__memory_base
          i32.const 1048612
          i32.add
          i32.load
          br_if 0 (;@2;)
          global.get $GOT.data.internal.__memory_base
          i32.const 1048612
          i32.add
          i32.const 1
          i32.store
          call $__wasm_call_ctors
          call $__main_void
          local.set 0
          call $__wasm_call_dtors
          local.get 0
          br_if 1 (;@1;)
          return
        end
        unreachable
        unreachable
      end
      local.get 0
      call $__wasi_proc_exit
      unreachable
    )

The Rust code for it is in the wasi-libc - https://github.com/WebAssembly/wasi-libc/blob/98897e29fcfc81e2b12e487e4154ac99188330c4/libc-bottom-half/crt/crt1-command.c

With __wasm_call_ctors and __wasm_call_dtors being empty functions, the only thing that this code is doing is preventing the reentrance of the _start function.
We can probably ignore _start altogether and call the __main_void function directly as our entrypoint.

@greenhat greenhat added this to the Beta 1 milestone Oct 30, 2024
@greenhat greenhat self-assigned this Oct 30, 2024
@bobbinth
Copy link
Contributor

Not related to this issue (and feel free to ignore if this is too much of distraction), but I'm curious how big is the generated MASM code here. Looking at WASM code, I think that's about 1.5K lines, right? And so MASM is some multiple of that?

@greenhat
Copy link
Contributor Author

Not related to this issue (and feel free to ignore if this is too much of distraction), but I'm curious how big is the generated MASM code here. Looking at WASM code, I think that's about 1.5K lines, right? And so MASM is some multiple of that?

This WASM code is a bad example, since almost 1K out of 1.5K lines is WASI code for I/O, error handling, etc. that we will ditch anyway. The more accurate prediction would be the WIT interface P2ID IR which is 0.65K lines and applying the ~2x ratio IR -> MASM we have in the basic-wallet example. So the generated MASM code should be about 1.3K lines. Switching to the main entrypoint approach should not meaningfully increase the size of code compared to the current WIT interface approach.

@bobbinth
Copy link
Contributor

Makes sense! Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants