summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuanzhong Chen <gzchen@google.com>2019-08-16 13:32:11 -0700
committerGitHub <noreply@github.com>2019-08-16 13:32:11 -0700
commit42f98bc9937b76ae12574bdb01652d09034fdec4 (patch)
treeac7aa67ae1f9a88d8df57ac95ed23e93849b9143
parentc8a797d120a1413d993281c98268c1c2ee9f3f94 (diff)
downloadbinaryen-42f98bc9937b76ae12574bdb01652d09034fdec4.tar.gz
binaryen-42f98bc9937b76ae12574bdb01652d09034fdec4.tar.bz2
binaryen-42f98bc9937b76ae12574bdb01652d09034fdec4.zip
Remove code to handle EM_ASM and setjmp/longjmp (#2302)
This reverts commit 12add6f17c377de7ac334e8fa7885b61b98f3db4 (#2283). This is done due to the complexity of supporting EM_ASM and setjmp/longjmp, especially with dynamic linking thrown into the mix. In https://reviews.llvm.org/D66356, using EM_ASM and setjmp/longjmp in the same function is now an error.
-rw-r--r--src/wasm/wasm-emscripten.cpp165
-rw-r--r--test/lld/em_asm_table.wast8
-rw-r--r--test/lld/em_asm_table.wast.out67
3 files changed, 53 insertions, 187 deletions
diff --git a/src/wasm/wasm-emscripten.cpp b/src/wasm/wasm-emscripten.cpp
index 602889b39..caea83302 100644
--- a/src/wasm/wasm-emscripten.cpp
+++ b/src/wasm/wasm-emscripten.cpp
@@ -16,7 +16,6 @@
#include "wasm-emscripten.h"
-#include <functional>
#include <sstream>
#include "asm_v_wasm.h"
@@ -33,7 +32,6 @@ namespace wasm {
cashew::IString EMSCRIPTEN_ASM_CONST("emscripten_asm_const");
cashew::IString EM_JS_PREFIX("__em_js__");
-static const char* INVOKE_PREFIX = "invoke_";
static Name STACK_SAVE("stackSave");
static Name STACK_RESTORE("stackRestore");
@@ -674,12 +672,6 @@ struct AsmConstWalker : public LinearExecutionWalker<AsmConstWalker> {
std::set<std::string> allSigs;
// last sets in the current basic block, per index
std::map<Index, LocalSet*> sets;
- // table indices that are calls to emscripten_asm_const_*
- std::map<Index, Name> asmTable;
- // cache used by tableIndexForName
- std::map<Name, Literal> tableIndices;
- // first available index after the table segment for each segment
- std::vector<int32_t> tableOffsets;
AsmConstWalker(Module& _wasm)
: wasm(_wasm), segmentOffsets(getSegmentOffsets(wasm)) {}
@@ -700,14 +692,7 @@ private:
void queueImport(Name importName, std::string baseSig);
void addImports();
- Index resolveConstIndex(Expression* arg,
- std::function<void(Expression*)> reportError);
- Const* resolveConstAddr(Expression* arg, const Name& target);
- void prepareAsmIndices(Table* table);
- Literal tableIndexForName(Name name);
-
std::vector<std::unique_ptr<Function>> queuedImports;
- std::vector<Name> queuedTableEntries;
};
void AsmConstWalker::noteNonLinear(Expression* curr) {
@@ -717,115 +702,45 @@ void AsmConstWalker::noteNonLinear(Expression* curr) {
void AsmConstWalker::visitLocalSet(LocalSet* curr) { sets[curr->index] = curr; }
-Const* AsmConstWalker::resolveConstAddr(Expression* arg, const Name& target) {
- while (!arg->dynCast<Const>()) {
- if (auto* get = arg->dynCast<LocalGet>()) {
- // The argument may be a local.get, in which case, the last set in this
- // basic block has the value.
- auto* set = sets[get->index];
- if (set) {
- assert(set->index == get->index);
- arg = set->value;
- }
- } else if (auto* value = arg->dynCast<Binary>()) {
- // In the dynamic linking case the address of the string constant
- // is the result of adding its offset to __memory_base.
- // In this case are only looking for the offset with the data segment so
- // the RHS of the addition is just what we want.
- assert(value->op == AddInt32);
- arg = value->right;
- } else {
- Fatal() << "Unexpected arg0 type (" << getExpressionName(arg)
- << ") in call to to: " << target;
- }
- }
- return arg->cast<Const>();
-}
-
-Index AsmConstWalker::resolveConstIndex(
- Expression* arg, std::function<void(Expression*)> reportError) {
- while (!arg->is<Const>()) {
- if (auto* get = arg->dynCast<LocalGet>()) {
- // The argument may be a local.get, in which case, the last set in this
- // basic block has the value.
- auto* set = sets[get->index];
- if (set) {
- assert(set->index == get->index);
- arg = set->value;
- } else {
- reportError(arg);
- return 0;
- }
- } else if (arg->is<GlobalGet>()) {
- // In the dynamic linking case, indices start at __table_base.
- // We want the value relative to __table_base.
- // If we are doing a global.get, assume it's __table_base, then the
- // offset relative to __table_base must be 0.
- return 0;
- } else {
- reportError(arg);
- return 0;
- }
- }
- return Index(arg->cast<Const>()->value.geti32());
-}
-
void AsmConstWalker::visitCall(Call* curr) {
auto* import = wasm.getFunction(curr->target);
- if (!import->imported()) {
- return;
- }
-
// Find calls to emscripten_asm_const* functions whose first argument is
// is always a string constant.
- if (import->base.hasSubstring(EMSCRIPTEN_ASM_CONST)) {
+ if (import->imported() && import->base.hasSubstring(EMSCRIPTEN_ASM_CONST)) {
auto baseSig = getSig(curr);
auto sig = fixupNameWithSig(curr->target, baseSig);
- auto* value = resolveConstAddr(curr->operands[0], import->base);
+ auto* arg = curr->operands[0];
+ while (!arg->dynCast<Const>()) {
+ if (auto* get = arg->dynCast<LocalGet>()) {
+ // The argument may be a local.get, in which case, the last set in this
+ // basic block has the value.
+ auto* set = sets[get->index];
+ if (set) {
+ assert(set->index == get->index);
+ arg = set->value;
+ }
+ } else if (auto* value = arg->dynCast<Binary>()) {
+ // In the dynamic linking case the address of the string constant
+ // is the result of adding its offset to __memory_base.
+ // In this case are only looking for the offset with the data segment so
+ // the RHS of the addition is just what we want.
+ assert(value->op == AddInt32);
+ arg = value->right;
+ } else {
+ if (!value) {
+ Fatal() << "Unexpected arg0 type (" << getExpressionName(arg)
+ << ") in call to to: " << import->base;
+ }
+ }
+ }
+
+ auto* value = arg->cast<Const>();
auto code = codeForConstAddr(wasm, segmentOffsets, value);
sigsForCode[code].insert(sig);
// Replace the first argument to the call with a Const index
Builder builder(wasm);
curr->operands[0] = builder.makeConst(idLiteralForCode(code));
- } else if (import->base.startsWith(INVOKE_PREFIX)) {
- // A call to emscripten_asm_const_* maybe done indirectly via one of the
- // invoke_* functions, in case of setjmp/longjmp, for example.
- // We attempt to modify the invoke_* call instead.
- auto idx = resolveConstIndex(curr->operands[0], [&](Expression* arg) {});
-
- // If the address of the invoke call is an emscripten_asm_const_* function:
- if (asmTable.count(idx)) {
- auto* value = resolveConstAddr(curr->operands[1], asmTable[idx]);
- auto code = codeForConstAddr(wasm, segmentOffsets, value);
-
- // Extract the base signature from the invoke_* function name.
- std::string baseSig(import->base.c_str() + sizeof(INVOKE_PREFIX) - 1);
- Name name;
- auto sig = fixupNameWithSig(name, baseSig);
- sigsForCode[code].insert(sig);
-
- Builder builder(wasm);
- curr->operands[0] = builder.makeConst(tableIndexForName(name));
- curr->operands[1] = builder.makeConst(idLiteralForCode(code));
- }
- }
-}
-
-void AsmConstWalker::prepareAsmIndices(Table* table) {
- for (auto& segment : table->segments) {
- auto idx = resolveConstIndex(segment.offset, [&](Expression* arg) {
- Fatal() << "Unexpected table index type (" << getExpressionName(arg)
- << ") table";
- });
- for (auto& name : segment.data) {
- auto* func = wasm.getFunction(name);
- if (func->imported() && func->base.hasSubstring(EMSCRIPTEN_ASM_CONST)) {
- asmTable[idx] = name;
- }
- ++idx;
- }
- tableOffsets.push_back(idx);
}
}
@@ -842,8 +757,6 @@ void AsmConstWalker::visitTable(Table* curr) {
}
void AsmConstWalker::process() {
- // Find table indices that point to emscripten_asm_const_* functions.
- prepareAsmIndices(&wasm.table);
// Find and queue necessary imports
walkModule(&wasm);
// Add them after the walk, to avoid iterator invalidation on
@@ -899,28 +812,10 @@ void AsmConstWalker::queueImport(Name importName, std::string baseSig) {
queuedImports.push_back(std::unique_ptr<Function>(import));
}
-Literal AsmConstWalker::tableIndexForName(Name name) {
- auto result = tableIndices.find(name);
- if (result != tableIndices.end()) {
- return result->second;
- }
- queuedTableEntries.push_back(name);
- return tableIndices[name] = Literal(tableOffsets[0]++);
-}
-
void AsmConstWalker::addImports() {
for (auto& import : queuedImports) {
wasm.addFunction(import.release());
}
-
- if (!queuedTableEntries.empty()) {
- assert(wasm.table.segments.size() == 1);
- std::vector<Name>& tableSegmentData = wasm.table.segments[0].data;
- for (auto& entry : queuedTableEntries) {
- tableSegmentData.push_back(entry);
- }
- wasm.table.initial.addr += queuedTableEntries.size();
- }
}
AsmConstWalker fixEmAsmConstsAndReturnWalker(Module& wasm) {
@@ -1056,7 +951,7 @@ struct FixInvokeFunctionNamesWalker
}
std::string sigWoOrigFunc = sig.front() + sig.substr(2, sig.size() - 2);
invokeSigs.insert(sigWoOrigFunc);
- return Name(INVOKE_PREFIX + sigWoOrigFunc);
+ return Name("invoke_" + sigWoOrigFunc);
}
Name fixEmEHSjLjNames(const Name& name, const std::string& sig) {
@@ -1196,7 +1091,7 @@ std::string EmscriptenGlueGenerator::generateEmscriptenMetadata(
ModuleUtils::iterImportedFunctions(wasm, [&](Function* import) {
if (emJsWalker.codeByName.count(import->base.str) == 0 &&
!import->base.startsWith(EMSCRIPTEN_ASM_CONST.str) &&
- !import->base.startsWith(INVOKE_PREFIX)) {
+ !import->base.startsWith("invoke_")) {
if (declares.insert(import->base.str).second) {
meta << nextElement() << '"' << import->base.str << '"';
}
@@ -1250,7 +1145,7 @@ std::string EmscriptenGlueGenerator::generateEmscriptenMetadata(
meta << " \"invokeFuncs\": [";
commaFirst = true;
ModuleUtils::iterImportedFunctions(wasm, [&](Function* import) {
- if (import->base.startsWith(INVOKE_PREFIX)) {
+ if (import->base.startsWith("invoke_")) {
if (invokeFuncs.insert(import->base.str).second) {
meta << nextElement() << '"' << import->base.str << '"';
}
diff --git a/test/lld/em_asm_table.wast b/test/lld/em_asm_table.wast
index 673e27585..c35ebe577 100644
--- a/test/lld/em_asm_table.wast
+++ b/test/lld/em_asm_table.wast
@@ -4,18 +4,10 @@
(import "env" "memory" (memory $2 8192))
(import "env" "emscripten_log" (func $fimport$0 (param i32 i32)))
(import "env" "emscripten_asm_const_int" (func $fimport$1 (param i32 i32 i32) (result i32)))
- (import "env" "__invoke_i32_i8*_i8*_..." (func $__invoke_i32_i8*_i8*_... (param i32 i32 i32 i32) (result i32)))
- (data (i32.const 1024) "{ console.log(\"hello world\"); }\00")
(table $0 159609 funcref)
(elem (i32.const 1) $fimport$0 $fimport$1)
(global $global$0 (mut i32) (i32.const 1024))
(global $global$1 i32 (i32.const 1048))
(export "__data_end" (global $global$1))
- (export "main" (func $main))
- (func $main
- (drop
- (call $__invoke_i32_i8*_i8*_... (i32.const 2) (i32.const 1024) (i32.const 13) (i32.const 27))
- )
- )
)
diff --git a/test/lld/em_asm_table.wast.out b/test/lld/em_asm_table.wast.out
index 80f8ee4c8..48d02d208 100644
--- a/test/lld/em_asm_table.wast.out
+++ b/test/lld/em_asm_table.wast.out
@@ -1,49 +1,26 @@
(module
(type $0 (func (param i32 i32)))
(type $1 (func (param i32 i32 i32) (result i32)))
- (type $FUNCSIG$iiiii (func (param i32 i32 i32 i32) (result i32)))
- (type $FUNCSIG$v (func))
- (type $FUNCSIG$iiii (func (param i32 i32 i32) (result i32)))
(type $FUNCSIG$vii (func (param i32 i32)))
+ (type $FUNCSIG$iiii (func (param i32 i32 i32) (result i32)))
(import "env" "memory" (memory $0 8192))
- (data (i32.const 1024) "{ console.log(\"hello world\"); }\00")
(import "env" "emscripten_log" (func $fimport$0 (param i32 i32)))
- (import "env" "invoke_iiii" (func $invoke_iiii (param i32 i32 i32 i32) (result i32)))
(import "env" "emscripten_asm_const_iii" (func $emscripten_asm_const_iii (param i32 i32 i32) (result i32)))
- (table $0 159610 funcref)
- (elem (i32.const 1) $fimport$0 $emscripten_asm_const_iii $emscripten_asm_const_iii)
+ (table $0 159609 funcref)
+ (elem (i32.const 1) $fimport$0 $emscripten_asm_const_iii)
(global $global$0 (mut i32) (i32.const 1024))
(global $global$1 i32 (i32.const 1048))
(export "__data_end" (global $global$1))
- (export "main" (func $main))
- (export "dynCall_iiii" (func $dynCall_iiii))
(export "stackSave" (func $stackSave))
(export "stackAlloc" (func $stackAlloc))
(export "stackRestore" (func $stackRestore))
(export "__growWasmMemory" (func $__growWasmMemory))
(export "dynCall_vii" (func $dynCall_vii))
- (func $main (; 3 ;) (type $FUNCSIG$v)
- (drop
- (call $invoke_iiii
- (i32.const 3)
- (i32.const 0)
- (i32.const 13)
- (i32.const 27)
- )
- )
- )
- (func $dynCall_iiii (; 4 ;) (param $fptr i32) (param $0 i32) (param $1 i32) (param $2 i32) (result i32)
- (call_indirect (type $FUNCSIG$iiii)
- (local.get $0)
- (local.get $1)
- (local.get $2)
- (local.get $fptr)
- )
- )
- (func $stackSave (; 5 ;) (result i32)
+ (export "dynCall_iiii" (func $dynCall_iiii))
+ (func $stackSave (; 2 ;) (result i32)
(global.get $global$0)
)
- (func $stackAlloc (; 6 ;) (param $0 i32) (result i32)
+ (func $stackAlloc (; 3 ;) (param $0 i32) (result i32)
(local $1 i32)
(global.set $global$0
(local.tee $1
@@ -58,64 +35,66 @@
)
(local.get $1)
)
- (func $stackRestore (; 7 ;) (param $0 i32)
+ (func $stackRestore (; 4 ;) (param $0 i32)
(global.set $global$0
(local.get $0)
)
)
- (func $__growWasmMemory (; 8 ;) (param $newSize i32) (result i32)
+ (func $__growWasmMemory (; 5 ;) (param $newSize i32) (result i32)
(memory.grow
(local.get $newSize)
)
)
- (func $dynCall_vii (; 9 ;) (param $fptr i32) (param $0 i32) (param $1 i32)
+ (func $dynCall_vii (; 6 ;) (param $fptr i32) (param $0 i32) (param $1 i32)
(call_indirect (type $FUNCSIG$vii)
(local.get $0)
(local.get $1)
(local.get $fptr)
)
)
+ (func $dynCall_iiii (; 7 ;) (param $fptr i32) (param $0 i32) (param $1 i32) (param $2 i32) (result i32)
+ (call_indirect (type $FUNCSIG$iiii)
+ (local.get $0)
+ (local.get $1)
+ (local.get $2)
+ (local.get $fptr)
+ )
+ )
)
(;
--BEGIN METADATA --
{
- "asmConsts": {
- "0": ["{ console.log(\"hello world\"); }", ["iii"], [""]]
- },
"staticBump": 480,
- "tableSize": 159610,
+ "tableSize": 159609,
"declares": [
"emscripten_log"
],
"externs": [
],
"implementedFunctions": [
- "_main",
- "_dynCall_iiii",
"_stackSave",
"_stackAlloc",
"_stackRestore",
"___growWasmMemory",
- "_dynCall_vii"
+ "_dynCall_vii",
+ "_dynCall_iiii"
],
"exports": [
- "main",
- "dynCall_iiii",
"stackSave",
"stackAlloc",
"stackRestore",
"__growWasmMemory",
- "dynCall_vii"
+ "dynCall_vii",
+ "dynCall_iiii"
],
"namedGlobals": {
"__data_end" : "1048"
},
"invokeFuncs": [
- "invoke_iiii"
],
"features": [
],
- "mainReadsParams": 1
+ "mainReadsParams": 0
}
-- END METADATA --
;)