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

[Help Wanted] Why global variables in wasm cannot be altered? #10

Open
SuperIceCN opened this issue Jan 17, 2021 · 1 comment
Open

[Help Wanted] Why global variables in wasm cannot be altered? #10

SuperIceCN opened this issue Jan 17, 2021 · 1 comment

Comments

@SuperIceCN
Copy link
Contributor

SuperIceCN commented Jan 17, 2021

I have a test and it fails. I don't know why the variable result equals to 0.

String wat = /* a .wat file */;
@Test
public void myTest(){
    Engine engine = new Engine();
    Store store = new Store(engine);
    Module module = new Module(engine,wat.getBytes(StandardCharsets.UTF_8));
    Memory memory = new Memory(store,new MemoryType(new MemoryType.Limit(64)));
    Linker linker = new Linker(store);
    WasiConfig wasiConfig = new WasiConfig(new String[]{},new WasiConfig.PreopenDir[]{});
    Wasi wasi = new Wasi(store,wasiConfig);
    wasi.addToLinker(linker);
    linker.define("env","memory",Extern.fromMemory(memory));
    linker.module("a",module);
    linker.getOneByName("a","_start").func().call();
    int result = linker.getOneByName("a","get").func().call()[0].i32();
    Assert.assertEquals(1,result); //failed, result==0
}

here is the .wat file:

(module
  (type $t0 (func (param i32)))
  (type $t1 (func))
  (type $t2 (func (result i32)))
  (import "env" "memory" (memory $env.memory 2))
  (import "wasi_snapshot_preview1" "proc_exit" (func $__wasi_proc_exit (type $t0)))
  (func $__wasm_call_ctors (type $t1))
  (func $_start (type $t1)
    (local $l0 i32)
    call $__wasm_call_ctors
    call $__original_main
    local.set $l0
    call $__wasm_call_dtors
    block $B0
      local.get $l0
      i32.eqz
      br_if $B0
      local.get $l0
      call $__wasi_proc_exit
      unreachable
    end)
  (func $__original_main (type $t2) (result i32)
    i32.const 0
    i32.const 1
    i32.store offset=1024
    i32.const 0)
  (func $get (type $t2) (result i32)
    i32.const 0
    i32.load offset=1024)
  (func $dummy (type $t1))
  (func $__wasm_call_dtors (type $t1)
    call $dummy
    call $dummy)
  (table $T0 1 1 funcref)
  (global $g0 (mut i32) (i32.const 66576))
  (export "_start" (func $_start))
  (export "get" (func $get))
  (data $d0 (i32.const 1024) "\00\00\00\00"))

this wat file is compiled from a c source code file with wasi-sdk:

volatile int a = 0;
int main(){
    a = 1;
    return 0;
}
__attribute__((export_name("get")))
int get(){
    return a;
}

@kawamuray Could please tell me why this happens? Thanks!

@kawamuray
Copy link
Owner

I think that's because your wasm module is recognized as a "command" rather than a "reactor". Please read https://github.com/WebAssembly/WASI/blob/2ccb606926bee332a7b0a486e150d1053a493977/design/application-abi.md#current-unstable-abi this document for the detail.

In short, when your wasm module contains the _start function, it is recognized as a command type, and for command type an Instance is created for each function invocation, meaning memory isn't shared between calls of _start and get.

You may want to compile your program as reactor-type (perhaps as a a shared object) if you want to share memory between multiple calls.

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