summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorHeejin Ahn <aheejin@users.noreply.github.com>2016-08-11 21:02:33 -0700
committerAlon Zakai <alonzakai@gmail.com>2016-08-11 21:02:33 -0700
commit1448c6bb26a60b26e70f7e913e56e0d0bf03b5da (patch)
tree6af5b7a0d34a7278a695112db41c1af1a45965c3 /test
parent8e8c311aaeecf9b5433e4a651585914465731f0c (diff)
downloadbinaryen-1448c6bb26a60b26e70f7e913e56e0d0bf03b5da.tar.gz
binaryen-1448c6bb26a60b26e70f7e913e56e0d0bf03b5da.tar.bz2
binaryen-1448c6bb26a60b26e70f7e913e56e0d0bf03b5da.zip
Implement asm.js style exception handling for Wasm (#664)
* Implement asm.js style exception handling for Wasm Converts invoke wrapper names generated by LLVM backend to real invoke wrapper names that are expected by JavaScript glue code. This is required to support wasm exception handling (asm.js style). LLVM backend lowers invoke @func(arg1, arg2) to label %invoke.cont unwind label %lpad into ... (some code) call @invoke_SIG(func, arg1, arg2) ... (some code) SIG is a mangled string generated based on the LLVM IR-level function signature. In LLVM IR, types are not lowered yet, so this mangling scheme simply takes LLVM's string representtion of parameter types and concatenate them with '_'. For example, the name of an invoke wrapper for function void foo(struct mystruct*, int) will be "__invoke_void_%struct.mystruct*_int". This function converts the names of invoke wrappers based on their lowered argument types and a return type. In the example above, the resulting new wrapper name becomes "invoke_vii". * Address comments Change variable names to camelcase Add a small (semi-)handwritten test case * Export malloc and free from wasm when available * Add a test case for exporting malloc/free feature + cosmetic 'file' name change in text_before_type.s * fixInvokeWrapper -> fixEmExceptionInvoke * Add a TODO
Diffstat (limited to 'test')
-rw-r--r--test/dot_s/export_malloc_free.s29
-rw-r--r--test/dot_s/export_malloc_free.wast16
-rw-r--r--test/dot_s/invoke_wrapper.s67
-rw-r--r--test/dot_s/invoke_wrapper.wast95
-rw-r--r--test/dot_s/text_before_type.s2
5 files changed, 208 insertions, 1 deletions
diff --git a/test/dot_s/export_malloc_free.s b/test/dot_s/export_malloc_free.s
new file mode 100644
index 000000000..0158811a4
--- /dev/null
+++ b/test/dot_s/export_malloc_free.s
@@ -0,0 +1,29 @@
+ .text
+ .file "export_malloc_free.bc"
+ .hidden main
+ .globl main
+ .type main,@function
+main:
+ .result i32
+ i32.const $push0=, 0
+ .endfunc
+.Lfunc_end1:
+ .size main, .Lfunc_end1-main
+
+ .weak malloc
+ .type malloc,@function
+malloc:
+ .param i32
+ .result i32
+ i32.const $push0=, 0
+ .endfunc
+.Lfunc_end20:
+ .size malloc, .Lfunc_end20-malloc
+
+ .weak free
+ .type free,@function
+free:
+ .param i32
+ .endfunc
+.Lfunc_end21:
+ .size free, .Lfunc_end21-free
diff --git a/test/dot_s/export_malloc_free.wast b/test/dot_s/export_malloc_free.wast
new file mode 100644
index 000000000..e3c2f3d6f
--- /dev/null
+++ b/test/dot_s/export_malloc_free.wast
@@ -0,0 +1,16 @@
+(module
+ (memory 1)
+ (export "memory" memory)
+ (export "main" $main)
+ (export "malloc" $malloc)
+ (export "free" $free)
+ (func $main (result i32)
+ (i32.const 0)
+ )
+ (func $malloc (param $0 i32) (result i32)
+ (i32.const 0)
+ )
+ (func $free (param $0 i32)
+ )
+)
+;; METADATA: { "asmConsts": {},"staticBump": 12, "initializers": [] }
diff --git a/test/dot_s/invoke_wrapper.s b/test/dot_s/invoke_wrapper.s
new file mode 100644
index 000000000..6de2f8b4c
--- /dev/null
+++ b/test/dot_s/invoke_wrapper.s
@@ -0,0 +1,67 @@
+ .text
+ .file "invoke_wrapper.bc"
+ .type _Z5func1v,@function
+_Z5func1v:
+ .endfunc
+.Lfunc_end0:
+ .size _Z5func1v, .Lfunc_end0-_Z5func1v
+
+ .type _Z5func2iii,@function
+_Z5func2iii:
+ .param i32, i32, i32
+ .result i32
+ i32.const $push0=, 3
+ .endfunc
+.Lfunc_end1:
+ .size _Z5func2iii, .Lfunc_end1-_Z5func2iii
+
+ .type _Z5func3fd,@function
+_Z5func3fd:
+ .param f32, f64
+ .result f32
+ f32.const $push0=, 0x1p0
+ .endfunc
+.Lfunc_end2:
+ .size _Z5func3fd, .Lfunc_end2-_Z5func3fd
+
+ .type _Z5func4P8mystructS_,@function
+_Z5func4P8mystructS_:
+ .param i32, i32
+ .result i32
+ i32.const $push0=, 0
+ .endfunc
+.Lfunc_end3:
+ .size _Z5func4P8mystructS_, .Lfunc_end3-_Z5func4P8mystructS_
+
+ .hidden main
+ .globl main
+ .type main,@function
+main:
+ .result i32
+ .local i32, i32, i32, i32
+ i32.const $push1=, _Z5func1v@FUNCTION
+ call __invoke_void@FUNCTION, $pop1
+ i32.const $push5=, _Z5func2iii@FUNCTION
+ i32.const $push4=, 1
+ i32.const $push3=, 2
+ i32.const $push2=, 3
+ i32.call $drop=, __invoke_i32_i32_i32_i32@FUNCTION, $pop5, $pop4, $pop3, $pop2
+ i32.const $push9=, _Z5func3fd@FUNCTION
+ f32.const $push8=, 0x1.8p0
+ f64.const $push7=, 0x1.b333333333333p1
+ f32.call $drop=, __invoke_float_float_double@FUNCTION, $pop9, $pop8, $pop7
+ i32.const $push21=, _Z5func4P8mystructS_@FUNCTION
+ i32.const $push37=, 32
+ i32.add $push38=, $1, $pop37
+ i32.const $push39=, 4
+ i32.add $push40=, $1, $pop39
+ i32.call $drop=, "__invoke_%struct.mystruct*_%struct.mystruct*_%struct.mystruct*"@FUNCTION, $pop21, $pop38, $pop40
+ i32.const $push23=, 0
+ .endfunc
+.Lfunc_end4:
+ .size main, .Lfunc_end4-main
+
+ .functype __invoke_void, void, i32
+ .functype __invoke_i32_i32_i32_i32, i32, i32, i32, i32, i32
+ .functype __invoke_float_float_double, f32, i32, f32, f64
+ .functype __invoke_%struct.mystruct*_%struct.mystruct*_%struct.mystruct*, i32, i32, i32, i32
diff --git a/test/dot_s/invoke_wrapper.wast b/test/dot_s/invoke_wrapper.wast
new file mode 100644
index 000000000..6aa7a4ce6
--- /dev/null
+++ b/test/dot_s/invoke_wrapper.wast
@@ -0,0 +1,95 @@
+(module
+ (memory 1)
+ (export "memory" memory)
+ (type $FUNCSIG$vi (func (param i32)))
+ (type $FUNCSIG$iiiii (func (param i32 i32 i32 i32) (result i32)))
+ (type $FUNCSIG$fifd (func (param i32 f32 f64) (result f32)))
+ (type $FUNCSIG$iiii (func (param i32 i32 i32) (result i32)))
+ (type $FUNCSIG$v (func))
+ (type $FUNCSIG$ffd (func (param f32 f64) (result f32)))
+ (type $FUNCSIG$iii (func (param i32 i32) (result i32)))
+ (import $invoke_ffd "env" "invoke_ffd" (param i32 f32 f64) (result f32))
+ (import $invoke_iii "env" "invoke_iii" (param i32 i32 i32) (result i32))
+ (import $invoke_iiii "env" "invoke_iiii" (param i32 i32 i32 i32) (result i32))
+ (import $invoke_v "env" "invoke_v" (param i32))
+ (export "main" $main)
+ (export "dynCall_v" $dynCall_v)
+ (export "dynCall_iiii" $dynCall_iiii)
+ (export "dynCall_ffd" $dynCall_ffd)
+ (export "dynCall_iii" $dynCall_iii)
+ (table $__wasm_nullptr $_Z5func1v $_Z5func2iii $_Z5func3fd $_Z5func4P8mystructS_)
+ (func $_Z5func1v (type $FUNCSIG$v)
+ )
+ (func $_Z5func2iii (type $FUNCSIG$iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32)
+ (i32.const 3)
+ )
+ (func $_Z5func3fd (type $FUNCSIG$ffd) (param $0 f32) (param $1 f64) (result f32)
+ (f32.const 1)
+ )
+ (func $_Z5func4P8mystructS_ (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32)
+ (i32.const 0)
+ )
+ (func $main (result i32)
+ (local $0 i32)
+ (local $1 i32)
+ (local $2 i32)
+ (local $3 i32)
+ (call_import $invoke_v
+ (i32.const 1)
+ )
+ (call_import $invoke_iiii
+ (i32.const 2)
+ (i32.const 1)
+ (i32.const 2)
+ (i32.const 3)
+ )
+ (call_import $invoke_ffd
+ (i32.const 3)
+ (f32.const 1.5)
+ (f64.const 3.4)
+ )
+ (call_import $invoke_iii
+ (i32.const 4)
+ (i32.add
+ (get_local $1)
+ (i32.const 32)
+ )
+ (i32.add
+ (get_local $1)
+ (i32.const 4)
+ )
+ )
+ (i32.const 0)
+ )
+ (func $__wasm_nullptr (type $FUNCSIG$v)
+ (unreachable)
+ )
+ (func $dynCall_v (param $fptr i32)
+ (call_indirect $FUNCSIG$v
+ (get_local $fptr)
+ )
+ )
+ (func $dynCall_iiii (param $fptr i32) (param $0 i32) (param $1 i32) (param $2 i32) (result i32)
+ (call_indirect $FUNCSIG$iiii
+ (get_local $fptr)
+ (get_local $0)
+ (get_local $1)
+ (get_local $2)
+ )
+ )
+ (func $dynCall_ffd (param $fptr i32) (param $0 f32) (param $1 f64) (result f32)
+ (call_indirect $FUNCSIG$ffd
+ (get_local $fptr)
+ (get_local $0)
+ (get_local $1)
+ )
+ )
+ (func $dynCall_iii (param $fptr i32) (param $0 i32) (param $1 i32) (result i32)
+ (call_indirect $FUNCSIG$iii
+ (get_local $fptr)
+ (get_local $0)
+ (get_local $1)
+ )
+ )
+)
+;; METADATA: { "asmConsts": {},"staticBump": 12, "initializers": [] }
diff --git a/test/dot_s/text_before_type.s b/test/dot_s/text_before_type.s
index 7c341078a..c76ecfbed 100644
--- a/test/dot_s/text_before_type.s
+++ b/test/dot_s/text_before_type.s
@@ -1,5 +1,5 @@
.text
- .file "/tmp/tmpGckQku/foo.bc"
+ .file "text_before_type.bc"
.hidden main
.globl main
.type main,@function