WebAssembly in Chrome Canary

101 views
Skip to first unread message

David Klassen

unread,
Oct 5, 2016, 7:26:23 AM10/5/16
to v8-users
Hi,

I started playing with the current wasm implementation and there are some things that are not clear for me.

If I compile this wast i get the expected result:

(module
  (func $add (param $x f32) (param $y f32) (result f32) (f32.add (get_local $x) (get_local $y)))
  (export "add" (func $add))
)

module = Wasm.instantiateModule(new Uint8Array(buffer), {});
module.exports.add(1,2) // => 3

But when I try to compile from C, I get an exception "Error: memory access out of bounds"

This is the C source:

double add(double a, double b) { return a + b; }

Fist I compile it to llvm ir:

; ModuleID = 'sample.c'
source_filename = "sample.c"
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
target triple = "wasm32"

; Function Attrs: nounwind
define hidden double @add(double %a, double %b) #0 {
entry:
  %a.addr = alloca double, align 8
  %b.addr = alloca double, align 8
  store double %a, double* %a.addr, align 8
  store double %b, double* %b.addr, align 8
  %0 = load double, double* %a.addr, align 8
  %1 = load double, double* %b.addr, align 8
  %add = fadd double %0, %1
  ret double %add
}

attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="generic" "unsafe-fp-math"="false" "use-soft-float"="false" }

!llvm.ident = !{!0}

!0 = !{!"clang version 4.0.0 (http://llvm.org/git/clang.git b1b3141a30d56f4feb3cc68f57d1ebaf6fbad246) (http://llvm.org/git/llvm.git cf04e5f0f84bd44c375bf866d777708df39935df)"}


Then to .s:

.text
.file "sample.ll"
.hidden add
.globl add
.type add,@function
add:                                    # @add
.param   f64, f64
.result f64
.local   i32
# BB#0:                                 # %entry
i32.const $push2=, 0
i32.load $push3=, __stack_pointer($pop2)
i32.const $push4=, 16
i32.sub $push6=, $pop3, $pop4
tee_local $push5=, $2=, $pop6
f64.store $drop=, 8($pop5), $0
f64.store $drop=, 0($2), $1
f64.load $push0=, 8($2)
f64.add $push1=, $pop0, $1
                                        # fallthrough-return: $pop1
.endfunc
.Lfunc_end0:
.size add, .Lfunc_end0-add


.ident "clang version 4.0.0 (http://llvm.org/git/clang.git b1b3141a30d56f4feb3cc68f57d1ebaf6fbad246) (http://llvm.org/git/llvm.git cf04e5f0f84bd44c375bf866d777708df39935df)"


Then i use binaryen s2wast:

(module
  (memory $0 1)
  (export "memory" (memory $0))
  (export "add" (func $add))
  (table 0 anyfunc)
  
  (func $add (param $0 f64) (param $1 f64) (result f64)
    (local $2 i32)
    (f64.store offset=8
      (tee_local $2
        (i32.sub
          (i32.load offset=4
            (i32.const 0)
          )
          (i32.const 16)
        )
      )
      (get_local $0)
    )
    (f64.store
      (get_local $2)
      (get_local $1)
    )
    (f64.add
      (f64.load offset=8
        (get_local $2)
      )
      (get_local $1)
    )
  )
)

And finally use wabt to get wasm file.

If I try to run the result in Chrome Canary i get  "Error: memory access out of bounds"

My goal is to be able to pass ArrayBuffers and other args from JS to wasm module and to be able to write the code in C. Can someone help me to solve this issue and maybe point to some useful resources. At this moment it is hard to find any working examples.

eh...@chromium.org

unread,
Oct 5, 2016, 2:19:27 PM10/5/16
to v8-users
What are the commands you used to generate each intermediate step?

In your .wast file, there should be a segments section which, among other things, initializes the stack pointer. Since that is not there, it's being initialized to 0, and then the translation of alloca yields a negative address. I suspect this is what's causing the out of bounds.

As a workaround, what happens if you compile from C to LLVM with optimization enabled? It seems like it'd likely be able to get rid of the alloca and avoid any memory access at all, at least for this tin

David Klassen

unread,
Oct 5, 2016, 3:02:23 PM10/5/16
to v8-u...@googlegroups.com
.c -> .ll: clang -emit-llvm --target=wasm32 -S sample.c
.ll -> .s: llc sample.ll -march=wasm32
.s -> .wast: s2wasm sample.s > sample.wast
.wast -> .wasm: wast2wasm sample.wast -o sample.wasm

--
--
v8-users mailing list
v8-u...@googlegroups.com
http://groups.google.com/group/v8-users
---
You received this message because you are subscribed to a topic in the Google Groups "v8-users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/v8-users/u03PhW4wPeg/unsubscribe.
To unsubscribe from this group and all its topics, send an email to v8-users+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages