summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2017-02-21 14:09:33 -0800
committerGitHub <noreply@github.com>2017-02-21 14:09:33 -0800
commit38a029f5b697878d13e41d5ecdc6c5fa69837b77 (patch)
tree1baa1835b961922cfa7c14906248e1170d2452db
parentc27040e315f75f5b5c50078e539714973dc21d12 (diff)
downloadbinaryen-38a029f5b697878d13e41d5ecdc6c5fa69837b77.tar.gz
binaryen-38a029f5b697878d13e41d5ecdc6c5fa69837b77.tar.bz2
binaryen-38a029f5b697878d13e41d5ecdc6c5fa69837b77.zip
fix asm2wasm import type setting - set the type of used calls based o… (#920)
* fix asm2wasm import type setting - set the type of used calls based on the context, early, so it's valid in the optimizer
-rw-r--r--src/asm2wasm.h25
-rw-r--r--test/importedSignCast.asm.js14
-rw-r--r--test/importedSignCast.fromasm18
-rw-r--r--test/importedSignCast.fromasm.imprecise17
-rw-r--r--test/importedSignCast.fromasm.imprecise.no-opts23
-rw-r--r--test/importedSignCast.fromasm.no-opts23
6 files changed, 111 insertions, 9 deletions
diff --git a/src/asm2wasm.h b/src/asm2wasm.h
index 561e48238..d75e07f98 100644
--- a/src/asm2wasm.h
+++ b/src/asm2wasm.h
@@ -1948,7 +1948,7 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) {
}
Expression* ret;
ExpressionList* operands;
- bool import = false;
+ CallImport* callImport = nullptr;
Index firstOperand = 0;
Ref args = ast[2];
if (tableCall) {
@@ -1958,11 +1958,10 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) {
operands = &specific->operands;
ret = specific;
} else if (wasm.checkImport(name)) {
- import = true;
- auto specific = allocator.alloc<CallImport>();
- specific->target = name;
- operands = &specific->operands;
- ret = specific;
+ callImport = allocator.alloc<CallImport>();
+ callImport->target = name;
+ operands = &callImport->operands;
+ ret = callImport;
} else {
auto specific = allocator.alloc<Call>();
specific->target = name;
@@ -1979,10 +1978,18 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) {
specific->fullType = fullType->name;
specific->type = fullType->result;
}
- if (import) {
+ if (callImport) {
+ // apply the detected type from the parent
+ // note that this may not be complete, e.g. we may see f(); but f is an
+ // import which does return a value, and we use that elsewhere. finalizeCalls
+ // fixes that up. what we do here is wherever a value is used, we set the right
+ // value, which is enough to ensure that the wasm ast is valid for such uses.
+ // this is important as we run the optimizer on functions before we get
+ // to finalizeCalls (which we can only do once we've read all the functions,
+ // and we optimize in parallel starting earlier).
Ref parent = astStackHelper.getParent();
- WasmType type = !!parent ? detectWasmType(parent, &asmData) : none;
- noteImportedFunctionCall(ast, type, ret->cast<CallImport>());
+ callImport->type = !!parent ? detectWasmType(parent, &asmData) : none;
+ noteImportedFunctionCall(ast, callImport->type, callImport);
}
return ret;
}
diff --git a/test/importedSignCast.asm.js b/test/importedSignCast.asm.js
new file mode 100644
index 000000000..60cc99d39
--- /dev/null
+++ b/test/importedSignCast.asm.js
@@ -0,0 +1,14 @@
+function asm(global, env, buffer) {
+ "use asm";
+
+ var gm = env._emscripten_glIsTexture;
+
+ function func() {
+ gm(0) << 24 >> 24;
+ }
+
+ var FUNCTION_TABLE_a = [ gm ];
+
+ return { func: func };
+}
+
diff --git a/test/importedSignCast.fromasm b/test/importedSignCast.fromasm
new file mode 100644
index 000000000..3df5f661d
--- /dev/null
+++ b/test/importedSignCast.fromasm
@@ -0,0 +1,18 @@
+(module
+ (type $FUNCSIG$ii (func (param i32) (result i32)))
+ (import "env" "_emscripten_glIsTexture" (func $gm (param i32) (result i32)))
+ (import "env" "memory" (memory $0 256 256))
+ (import "env" "table" (table 1 1 anyfunc))
+ (import "env" "memoryBase" (global $memoryBase i32))
+ (import "env" "tableBase" (global $tableBase i32))
+ (elem (get_global $tableBase) $gm)
+ (data (get_global $memoryBase) "importedSignCast.asm.js")
+ (export "func" (func $func))
+ (func $func
+ (drop
+ (call $gm
+ (i32.const 0)
+ )
+ )
+ )
+)
diff --git a/test/importedSignCast.fromasm.imprecise b/test/importedSignCast.fromasm.imprecise
new file mode 100644
index 000000000..ebebba81d
--- /dev/null
+++ b/test/importedSignCast.fromasm.imprecise
@@ -0,0 +1,17 @@
+(module
+ (type $FUNCSIG$ii (func (param i32) (result i32)))
+ (import "env" "_emscripten_glIsTexture" (func $gm (param i32) (result i32)))
+ (import "env" "memory" (memory $0 256 256))
+ (import "env" "table" (table 1 1 anyfunc))
+ (import "env" "memoryBase" (global $memoryBase i32))
+ (import "env" "tableBase" (global $tableBase i32))
+ (elem (get_global $tableBase) $gm)
+ (export "func" (func $func))
+ (func $func
+ (drop
+ (call $gm
+ (i32.const 0)
+ )
+ )
+ )
+)
diff --git a/test/importedSignCast.fromasm.imprecise.no-opts b/test/importedSignCast.fromasm.imprecise.no-opts
new file mode 100644
index 000000000..97f1f82b7
--- /dev/null
+++ b/test/importedSignCast.fromasm.imprecise.no-opts
@@ -0,0 +1,23 @@
+(module
+ (type $FUNCSIG$ii (func (param i32) (result i32)))
+ (import "env" "_emscripten_glIsTexture" (func $gm (param i32) (result i32)))
+ (import "env" "memory" (memory $0 256 256))
+ (import "env" "table" (table 1 1 anyfunc))
+ (import "env" "memoryBase" (global $memoryBase i32))
+ (import "env" "tableBase" (global $tableBase i32))
+ (elem (get_global $tableBase) $gm)
+ (export "func" (func $func))
+ (func $func
+ (drop
+ (i32.shr_s
+ (i32.shl
+ (call $gm
+ (i32.const 0)
+ )
+ (i32.const 24)
+ )
+ (i32.const 24)
+ )
+ )
+ )
+)
diff --git a/test/importedSignCast.fromasm.no-opts b/test/importedSignCast.fromasm.no-opts
new file mode 100644
index 000000000..97f1f82b7
--- /dev/null
+++ b/test/importedSignCast.fromasm.no-opts
@@ -0,0 +1,23 @@
+(module
+ (type $FUNCSIG$ii (func (param i32) (result i32)))
+ (import "env" "_emscripten_glIsTexture" (func $gm (param i32) (result i32)))
+ (import "env" "memory" (memory $0 256 256))
+ (import "env" "table" (table 1 1 anyfunc))
+ (import "env" "memoryBase" (global $memoryBase i32))
+ (import "env" "tableBase" (global $tableBase i32))
+ (elem (get_global $tableBase) $gm)
+ (export "func" (func $func))
+ (func $func
+ (drop
+ (i32.shr_s
+ (i32.shl
+ (call $gm
+ (i32.const 0)
+ )
+ (i32.const 24)
+ )
+ (i32.const 24)
+ )
+ )
+ )
+)