[PATCH] D34172: [WebAssembly] Use __stack_pointer global when writing wasm binary

Sanket Diwale via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sat Jan 9 18:37:12 PST 2021


sanketdiwale added a comment.
Herald added subscribers: llvm-commits, wingo, ecnelises.
Herald added a project: LLVM.

Could you clarify what the __stack_pointer expects from the external code.

I generated .wasm code for accessing a struct defined in c++ and when trying to run the corresponding code from the wasm module imported into a javascript file. I end up getting a "bus error:10". Simpler codes where the __stack_pointer is not used work fine.

To make things more concrete, I have a c++ code like:

  // c++ code
  struct foo {
   double a;
   double b;
  }
  
  double f(double x){
    foo r;
    r.b = x;
    return 0.0;
  }

This generates a wasm file of the form

  (module
    (type $t1 (func (param f64) (result f64)))
    (import "env" "__linear_memory" (memory $env.__linear_memory 0))
    (import "env" "__indirect_function_table" (table $env.__indirect_function_table 0 funcref))
    (import "env" "__stack_pointer" (global $env.__stack_pointer (mut i32)))
  ...
    (func $f (type $t1) (param $p0 f64) (result f64)
    (local $l1 i32) (local $l2 f64)
      global.get $env.__stack_pointer
      i32.const 32
      i32.sub
      local.tee $l1
      global.set $env.__stack_pointer
      local.get $l1
      ...
    )
    (export "f" (func $f))
  ...

and so on, using the __stack_pointer load and store values onto a stack.

However it's not clear as to what the stack object is when referenced from the external file.

For example, if I instantiate the corresponding wasm file from a javascript as shown below, it leads to crash with "bus error:10" displayed in the terminal:

  // js file to load module
  const http = require('http');
  const fs = require('fs');
  
  const buf = fs.readFileSync('foo.wasm');
  var typedbuf = new Uint8Array(buf);
  const env = {
      __linear_memory: new WebAssembly.Memory({initial:256}),
      __indirect_function_table: new WebAssembly.Table({initial:0,element:'anyfunc'}),
      __stack_pointer: new WebAssembly.Global({value:'i32', mutable:true}, 0)
  }
  WebAssembly.instantiate(typedbuf,{env:env}).then(res=>console.log(res.instance.exports.f(4))).catch(e => {
      // error caught
      console.log(e);
    });
  ...

Here the WebAssembly.instantiate, defines the imports in "env" and includes a "_ _stack_pointer" as a WebAssembly.Global object. However this doesn't seem to work as stated previously.
Does the "_ _stack_pointer" have to refer to a particular memory address, say from the "_ _linear_memory" object defined for the module? Or is there something else that the __stack_pointer should be referring to?


Repository:
  rL LLVM

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D34172/new/

https://reviews.llvm.org/D34172



More information about the llvm-commits mailing list