diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/asm_v_wasm.h | 3 | ||||
-rw-r--r-- | src/asmjs/asm_v_wasm.cpp | 14 | ||||
-rw-r--r-- | src/emscripten-optimizer/optimizer-shared.cpp | 271 | ||||
-rw-r--r-- | src/emscripten-optimizer/optimizer.h | 146 | ||||
-rw-r--r-- | src/passes/MinifyImportsAndExports.cpp | 2 | ||||
-rw-r--r-- | src/passes/NoExitRuntime.cpp | 2 | ||||
-rw-r--r-- | src/passes/OptimizeInstructions.cpp | 6 | ||||
-rw-r--r-- | src/wasm.h | 7 | ||||
-rw-r--r-- | src/wasm2js.h | 175 |
9 files changed, 152 insertions, 474 deletions
diff --git a/src/asm_v_wasm.h b/src/asm_v_wasm.h index d2089b569..aaa7cabd0 100644 --- a/src/asm_v_wasm.h +++ b/src/asm_v_wasm.h @@ -18,12 +18,11 @@ #define wasm_asm_v_wasm_h #include "emscripten-optimizer/optimizer.h" -#include "mixed_arena.h" #include "wasm.h" namespace wasm { -AsmType wasmToAsmType(Type type); +JsType wasmToJsType(Type type); char getSig(Type type); std::string getSig(Type results, Type params); diff --git a/src/asmjs/asm_v_wasm.cpp b/src/asmjs/asm_v_wasm.cpp index e87e13062..9e05d8722 100644 --- a/src/asmjs/asm_v_wasm.cpp +++ b/src/asmjs/asm_v_wasm.cpp @@ -20,17 +20,17 @@ namespace wasm { -AsmType wasmToAsmType(Type type) { +JsType wasmToJsType(Type type) { TODO_SINGLE_COMPOUND(type); switch (type.getBasic()) { case Type::i32: - return ASM_INT; + return JS_INT; case Type::f32: - return ASM_FLOAT; + return JS_FLOAT; case Type::f64: - return ASM_DOUBLE; + return JS_DOUBLE; case Type::i64: - return ASM_INT64; + return JS_INT64; case Type::v128: WASM_UNREACHABLE("v128 not implemented yet"); case Type::funcref: @@ -39,9 +39,9 @@ AsmType wasmToAsmType(Type type) { case Type::eqref: case Type::i31ref: case Type::dataref: - WASM_UNREACHABLE("reference types are not supported by asm2wasm"); + WASM_UNREACHABLE("reference types are not supported by wasm2js"); case Type::none: - return ASM_NONE; + return JS_NONE; case Type::unreachable: WASM_UNREACHABLE("invalid type"); } diff --git a/src/emscripten-optimizer/optimizer-shared.cpp b/src/emscripten-optimizer/optimizer-shared.cpp index 720ac858e..8208f6f47 100644 --- a/src/emscripten-optimizer/optimizer-shared.cpp +++ b/src/emscripten-optimizer/optimizer-shared.cpp @@ -21,252 +21,31 @@ using namespace cashew; -IString ASM_FLOAT_ZERO; +IString JS_FLOAT_ZERO; IString SIMD_INT8X16_CHECK("SIMD_Int8x16_check"); IString SIMD_INT16X8_CHECK("SIMD_Int16x8_check"); IString SIMD_INT32X4_CHECK("SIMD_Int32x4_check"); IString SIMD_FLOAT32X4_CHECK("SIMD_Float32x4_check"); IString SIMD_FLOAT64X2_CHECK("SIMD_Float64x2_check"); -IString TEMP_RET0("tempRet0"); -int parseInt(const char* str) { - int ret = *str - '0'; - while (*(++str)) { - ret *= 10; - ret += *str - '0'; - } - return ret; -} - -HeapInfo parseHeap(const char* name) { - HeapInfo ret; - if (name[0] != 'H' || name[1] != 'E' || name[2] != 'A' || name[3] != 'P') { - ret.valid = false; - return ret; - } - ret.valid = true; - ret.unsign = name[4] == 'U'; - ret.floaty = name[4] == 'F'; - ret.bits = parseInt(name + (ret.unsign || ret.floaty ? 5 : 4)); - ret.type = !ret.floaty ? ASM_INT : (ret.bits == 64 ? ASM_DOUBLE : ASM_FLOAT); - return ret; -} - -AsmType detectType(Ref node, - AsmData* asmData, - bool inVarDef, - IString minifiedFround, - bool allowI64) { - if (node->isString()) { - if (asmData) { - AsmType ret = asmData->getType(node->getCString()); - if (ret != ASM_NONE) { - return ret; - } - } - if (!inVarDef) { - if (node == INF || node == NaN) { - return ASM_DOUBLE; - } - if (node == TEMP_RET0) { - return ASM_INT; - } - return ASM_NONE; - } - // We are in a variable definition, where Math_fround(0) optimized into a - // global constant becomes f0 = Math_fround(0) - if (ASM_FLOAT_ZERO.isNull()) { - ASM_FLOAT_ZERO = node->getIString(); - } else { - assert(node == ASM_FLOAT_ZERO); - } - return ASM_FLOAT; - } - if (node->isNumber()) { - if (!wasm::isInteger(node->getNumber())) { - return ASM_DOUBLE; - } - return ASM_INT; - } - switch (node[0]->getCString()[0]) { - case 'u': { - if (node[0] == UNARY_PREFIX) { - switch (node[1]->getCString()[0]) { - case '+': - return ASM_DOUBLE; - case '-': - return detectType( - node[2], asmData, inVarDef, minifiedFround, allowI64); - case '!': - case '~': - return ASM_INT; - } - break; - } - break; - } - case 'c': { - if (node[0] == CALL) { - if (node[1]->isString()) { - IString name = node[1]->getIString(); - if (name == MATH_FROUND || name == minifiedFround) { - return ASM_FLOAT; - } else if (allowI64 && (name == INT64 || name == INT64_CONST)) { - return ASM_INT64; - } else if (name == SIMD_FLOAT32X4 || name == SIMD_FLOAT32X4_CHECK) { - return ASM_FLOAT32X4; - } else if (name == SIMD_FLOAT64X2 || name == SIMD_FLOAT64X2_CHECK) { - return ASM_FLOAT64X2; - } else if (name == SIMD_INT8X16 || name == SIMD_INT8X16_CHECK) { - return ASM_INT8X16; - } else if (name == SIMD_INT16X8 || name == SIMD_INT16X8_CHECK) { - return ASM_INT16X8; - } else if (name == SIMD_INT32X4 || name == SIMD_INT32X4_CHECK) { - return ASM_INT32X4; - } - } - return ASM_NONE; - } else if (node[0] == CONDITIONAL) { - return detectType(node[2], asmData, inVarDef, minifiedFround, allowI64); - } - break; - } - case 'b': { - if (node[0] == BINARY) { - switch (node[1]->getCString()[0]) { - case '+': - case '-': - case '*': - case '/': - case '%': - return detectType( - node[2], asmData, inVarDef, minifiedFround, allowI64); - case '|': - case '&': - case '^': - case '<': - case '>': // handles <<, >>, >>=, <=, >= - case '=': - case '!': { // handles ==, != - return ASM_INT; - } - } - } - break; - } - case 's': { - if (node[0] == SEQ) { - return detectType(node[2], asmData, inVarDef, minifiedFround, allowI64); - } else if (node[0] == SUB) { - assert(node[1]->isString()); - HeapInfo info = parseHeap(node[1][1]->getCString()); - if (info.valid) { - return ASM_NONE; - } - return info.floaty ? ASM_DOUBLE : ASM_INT; // XXX ASM_FLOAT? - } - break; - } - } - // dump("horrible", node); - // assert(0); - return ASM_NONE; -} - -static void abort_on(Ref node) { - node->stringify(std::cerr); - std::cerr << '\n'; - abort(); -} - -AsmSign detectSign(Ref node, IString minifiedFround) { - if (node->isString()) { - return ASM_FLEXIBLE; - } - if (node->isNumber()) { - double value = node->getNumber(); - if (value < 0) { - return ASM_SIGNED; - } - if (value > uint32_t(-1) || !wasm::isInteger(value)) { - return ASM_NONSIGNED; - } - if (wasm::isSInteger32(value)) { - return ASM_FLEXIBLE; - } - return ASM_UNSIGNED; - } - IString type = node[0]->getIString(); - if (type == BINARY) { - IString op = node[1]->getIString(); - switch (op.str[0]) { - case '>': { - if (op == TRSHIFT) { - return ASM_UNSIGNED; - } - [[fallthrough]]; - } - case '|': - case '&': - case '^': - case '<': - case '=': - case '!': - return ASM_SIGNED; - case '+': - case '-': - return ASM_FLEXIBLE; - case '*': - case '/': - case '%': - return ASM_NONSIGNED; // without a coercion, these are double - default: - abort_on(node); - } - } else if (type == UNARY_PREFIX) { - IString op = node[1]->getIString(); - switch (op.str[0]) { - case '-': - return ASM_FLEXIBLE; - case '+': - return ASM_NONSIGNED; // XXX double - case '~': - return ASM_SIGNED; - default: - abort_on(node); - } - } else if (type == CONDITIONAL) { - return detectSign(node[2], minifiedFround); - } else if (type == CALL) { - if (node[1]->isString() && - (node[1] == MATH_FROUND || node[1] == minifiedFround)) { - return ASM_NONSIGNED; - } - } else if (type == SEQ) { - return detectSign(node[2], minifiedFround); - } - abort_on(node); - abort(); // avoid warning -} - -Ref makeAsmCoercedZero(AsmType type) { +Ref makeJsCoercedZero(JsType type) { switch (type) { - case ASM_INT: + case JS_INT: return ValueBuilder::makeNum(0); break; - case ASM_DOUBLE: + case JS_DOUBLE: return ValueBuilder::makeUnary(PLUS, ValueBuilder::makeNum(0)); break; - case ASM_FLOAT: { - if (!ASM_FLOAT_ZERO.isNull()) { - return ValueBuilder::makeName(ASM_FLOAT_ZERO); + case JS_FLOAT: { + if (!JS_FLOAT_ZERO.isNull()) { + return ValueBuilder::makeName(JS_FLOAT_ZERO); } else { return ValueBuilder::makeCall(MATH_FROUND, ValueBuilder::makeNum(0)); } break; } - case ASM_FLOAT32X4: { + case JS_FLOAT32X4: { return ValueBuilder::makeCall(SIMD_FLOAT32X4, ValueBuilder::makeNum(0), ValueBuilder::makeNum(0), @@ -274,12 +53,12 @@ Ref makeAsmCoercedZero(AsmType type) { ValueBuilder::makeNum(0)); break; } - case ASM_FLOAT64X2: { + case JS_FLOAT64X2: { return ValueBuilder::makeCall( SIMD_FLOAT64X2, ValueBuilder::makeNum(0), ValueBuilder::makeNum(0)); break; } - case ASM_INT8X16: { + case JS_INT8X16: { return ValueBuilder::makeCall(SIMD_INT8X16, ValueBuilder::makeNum(0), ValueBuilder::makeNum(0), @@ -299,7 +78,7 @@ Ref makeAsmCoercedZero(AsmType type) { ValueBuilder::makeNum(0)); break; } - case ASM_INT16X8: { + case JS_INT16X8: { return ValueBuilder::makeCall(SIMD_INT16X8, ValueBuilder::makeNum(0), ValueBuilder::makeNum(0), @@ -311,7 +90,7 @@ Ref makeAsmCoercedZero(AsmType type) { ValueBuilder::makeNum(0)); break; } - case ASM_INT32X4: { + case JS_INT32X4: { return ValueBuilder::makeCall(SIMD_INT32X4, ValueBuilder::makeNum(0), ValueBuilder::makeNum(0), @@ -325,25 +104,25 @@ Ref makeAsmCoercedZero(AsmType type) { abort(); } -Ref makeAsmCoercion(Ref node, AsmType type) { +Ref makeJsCoercion(Ref node, JsType type) { switch (type) { - case ASM_INT: + case JS_INT: return ValueBuilder::makeBinary(node, OR, ValueBuilder::makeNum(0)); - case ASM_DOUBLE: + case JS_DOUBLE: return ValueBuilder::makeUnary(PLUS, node); - case ASM_FLOAT: + case JS_FLOAT: return ValueBuilder::makeCall(MATH_FROUND, node); - case ASM_FLOAT32X4: + case JS_FLOAT32X4: return ValueBuilder::makeCall(SIMD_FLOAT32X4_CHECK, node); - case ASM_FLOAT64X2: + case JS_FLOAT64X2: return ValueBuilder::makeCall(SIMD_FLOAT64X2_CHECK, node); - case ASM_INT8X16: + case JS_INT8X16: return ValueBuilder::makeCall(SIMD_INT8X16_CHECK, node); - case ASM_INT16X8: + case JS_INT16X8: return ValueBuilder::makeCall(SIMD_INT16X8_CHECK, node); - case ASM_INT32X4: + case JS_INT32X4: return ValueBuilder::makeCall(SIMD_INT32X4_CHECK, node); - case ASM_NONE: + case JS_NONE: default: // non-validating code, emit nothing XXX this is dangerous, we should only // allow this when we know we are not validating @@ -351,8 +130,8 @@ Ref makeAsmCoercion(Ref node, AsmType type) { } } -Ref makeSigning(Ref node, AsmSign sign) { - assert(sign == ASM_SIGNED || sign == ASM_UNSIGNED); +Ref makeSigning(Ref node, JsSign sign) { + assert(sign == JS_SIGNED || sign == JS_UNSIGNED); return ValueBuilder::makeBinary( - node, sign == ASM_SIGNED ? OR : TRSHIFT, ValueBuilder::makeNum(0)); + node, sign == JS_SIGNED ? OR : TRSHIFT, ValueBuilder::makeNum(0)); } diff --git a/src/emscripten-optimizer/optimizer.h b/src/emscripten-optimizer/optimizer.h index e30347025..132ff6fb8 100644 --- a/src/emscripten-optimizer/optimizer.h +++ b/src/emscripten-optimizer/optimizer.h @@ -19,127 +19,39 @@ #include "simple_ast.h" -extern bool preciseF32, receiveJSON, emitJSON, minifyWhitespace, last; - -extern cashew::Ref extraInfo; - -// - -enum AsmType { - ASM_INT = 0, - ASM_DOUBLE, - ASM_FLOAT, - ASM_FLOAT32X4, - ASM_FLOAT64X2, - ASM_INT8X16, - ASM_INT16X8, - ASM_INT32X4, - ASM_INT64, // non-asm.js - ASM_NONE // number of types +using namespace cashew; + +extern IString JS_FLOAT_ZERO; + +extern IString SIMD_INT8X16_CHECK; +extern IString SIMD_INT16X8_CHECK; +extern IString SIMD_INT32X4_CHECK; +extern IString SIMD_FLOAT32X4_CHECK; +extern IString SIMD_FLOAT64X2_CHECK; + +enum JsType { + JS_INT = 0, + JS_DOUBLE, + JS_FLOAT, + JS_FLOAT32X4, + JS_FLOAT64X2, + JS_INT8X16, + JS_INT16X8, + JS_INT32X4, + JS_INT64, + JS_NONE // number of types }; -struct AsmData; - -AsmType detectType(cashew::Ref node, - AsmData* asmData = nullptr, - bool inVarDef = false, - cashew::IString minifiedFround = cashew::IString(), - bool allowI64 = false); - -struct AsmData { - struct Local { - Local() = default; - Local(AsmType type, bool param) : type(type), param(param) {} - AsmType type; - bool param; // false if a var - }; - typedef std::unordered_map<cashew::IString, Local> Locals; - - Locals locals; - std::vector<cashew::IString> params; // in order - std::vector<cashew::IString> vars; // in order - AsmType ret; - - cashew::Ref func; - - AsmType getType(const cashew::IString& name) { - auto ret = locals.find(name); - if (ret != locals.end()) { - return ret->second.type; - } - return ASM_NONE; - } - void setType(const cashew::IString& name, AsmType type) { - locals[name].type = type; - } - - bool isLocal(const cashew::IString& name) { return locals.count(name) > 0; } - bool isParam(const cashew::IString& name) { - return isLocal(name) && locals[name].param; - } - bool isVar(const cashew::IString& name) { - return isLocal(name) && !locals[name].param; - } - - // if you want to fill in the data yourself - AsmData() = default; - // if you want to read data from f, and modify it as you go (parallel to - // denormalize) - AsmData(cashew::Ref f); - - void denormalize(); - - void addParam(cashew::IString name, AsmType type) { - locals[name] = Local(type, true); - params.push_back(name); - } - void addVar(cashew::IString name, AsmType type) { - locals[name] = Local(type, false); - vars.push_back(name); - } - - void deleteVar(cashew::IString name) { - locals.erase(name); - for (size_t i = 0; i < vars.size(); i++) { - if (vars[i] == name) { - vars.erase(vars.begin() + i); - break; - } - } - } -}; - -extern cashew::IString ASM_FLOAT_ZERO; - -extern cashew::IString SIMD_INT8X16_CHECK; -extern cashew::IString SIMD_INT16X8_CHECK; -extern cashew::IString SIMD_INT32X4_CHECK; -extern cashew::IString SIMD_FLOAT32X4_CHECK; -extern cashew::IString SIMD_FLOAT64X2_CHECK; - -int parseInt(const char* str); - -struct HeapInfo { - bool valid, unsign, floaty; - int bits; - AsmType type; -}; - -HeapInfo parseHeap(const char* name); - -enum AsmSign { +enum JsSign { // small constants can be signed or unsigned, variables are also flexible - ASM_FLEXIBLE = 0, - ASM_SIGNED = 1, - ASM_UNSIGNED = 2, - ASM_NONSIGNED = 3, + JS_FLEXIBLE = 0, + JS_SIGNED, + JS_UNSIGNED, + JS_NONSIGNED, }; -extern AsmSign detectSign(cashew::Ref node, cashew::IString minifiedFround); - -cashew::Ref makeAsmCoercedZero(AsmType type); -cashew::Ref makeAsmCoercion(cashew::Ref node, AsmType type); - -cashew::Ref makeSigning(cashew::Ref node, AsmSign sign); +Ref makeJsCoercedZero(JsType type); +Ref makeJsCoercion(Ref node, JsType type); +Ref makeSigning(Ref node, JsSign sign); #endif // wasm_optimizer_h diff --git a/src/passes/MinifyImportsAndExports.cpp b/src/passes/MinifyImportsAndExports.cpp index 532616851..cad6bd9da 100644 --- a/src/passes/MinifyImportsAndExports.cpp +++ b/src/passes/MinifyImportsAndExports.cpp @@ -76,7 +76,7 @@ private: // Minify all import base names if we are importing modules (which means // we will minify all modules names, so we are not being careful). // Otherwise, assume we just want to minify "normal" imports like env - // and wasi, but not special things like asm2wasm or custom user things. + // and wasi, but not custom user things. if (minifyModules || curr->module == ENV || curr->module.startsWith("wasi_")) { process(curr->base); diff --git a/src/passes/NoExitRuntime.cpp b/src/passes/NoExitRuntime.cpp index deffccd36..07cd4fc87 100644 --- a/src/passes/NoExitRuntime.cpp +++ b/src/passes/NoExitRuntime.cpp @@ -34,7 +34,7 @@ struct NoExitRuntime : public WalkerPass<PostWalker<NoExitRuntime>> { Pass* create() override { return new NoExitRuntime; } - // Remove all possible manifestations of atexit, across asm2wasm and llvm wasm + // Remove all possible manifestations of atexit, across llvm wasm // backend. std::array<Name, 4> ATEXIT_NAMES = { {"___cxa_atexit", "__cxa_atexit", "_atexit", "atexit"}}; diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp index 8752c76cb..423148510 100644 --- a/src/passes/OptimizeInstructions.cpp +++ b/src/passes/OptimizeInstructions.cpp @@ -46,12 +46,6 @@ namespace wasm { -Name I32_EXPR = "i32.expr"; -Name I64_EXPR = "i64.expr"; -Name F32_EXPR = "f32.expr"; -Name F64_EXPR = "f64.expr"; -Name ANY_EXPR = "any.expr"; - // Useful information about locals struct LocalInfo { static const Index kUnknown = Index(-1); diff --git a/src/wasm.h b/src/wasm.h index b6e57525f..c4a58f3a4 100644 --- a/src/wasm.h +++ b/src/wasm.h @@ -560,10 +560,9 @@ enum BrOnOp { // Expressions // // Note that little is provided in terms of constructors for these. The -// rationale is that writing new Something(a, b, c, d, e) is not the clearest, -// and it would be better to write new Something(name=a, leftOperand=b... -// etc., but C++ lacks named operands, so in asm2wasm etc. you will see things -// like +// rationale is that writing `new Something(a, b, c, d, e)` is not the clearest, +// and it would be better to write new `Something(name=a, leftOperand=b...` +// etc., but C++ lacks named operands so you will see things like // auto x = new Something(); // x->name = a; // x->leftOperand = b; diff --git a/src/wasm2js.h b/src/wasm2js.h index 3e264f98b..e2b95f114 100644 --- a/src/wasm2js.h +++ b/src/wasm2js.h @@ -145,17 +145,13 @@ enum class NameScope { // // Wasm2JSBuilder - converts a WebAssembly module's functions into JS // -// In general, JS (asm.js) => wasm is very straightforward, as can -// be seen in asm2wasm.h. Just a single pass, plus a little -// state bookkeeping (breakStack, etc.), and a few after-the -// fact corrections for imports, etc. However, wasm => JS -// is tricky because wasm has statements == expressions, or in -// other words, things like `break` and `if` can show up -// in places where JS can't handle them, like inside an -// a loop's condition check. For that reason we use flat IR here. +// Wasm-to-JS is tricky because wasm doesn't distinguish +// statements and expressions, or in other words, things like `break` and `if` +// can show up in places where JS can't handle them, like inside an a loop's +// condition check. For that reason we use flat IR here. // We do optimize it later, to allow some nesting, but we avoid -// non-JS-compatible nesting like block return values control -// flow in an if condition, etc. +// non-JS-compatible nesting like block return values control flow in an if +// condition, etc. // class Wasm2JSBuilder { @@ -618,7 +614,7 @@ void Wasm2JSBuilder::addGlobalImport(Ref ast, Global* import) { Ref value = ValueBuilder::makeDot(module, fromName(import->base, NameScope::Top)); if (import->type == Type::i32) { - value = makeAsmCoercion(value, ASM_INT); + value = makeJsCoercion(value, JS_INT); } ValueBuilder::appendToVar( theVar, fromName(import->name, NameScope::Top), value); @@ -798,13 +794,13 @@ void Wasm2JSBuilder::addGlobal(Ref ast, Global* global) { case Type::f32: { theValue = ValueBuilder::makeCall( MATH_FROUND, - makeAsmCoercion(ValueBuilder::makeDouble(const_->value.getf32()), - ASM_DOUBLE)); + makeJsCoercion(ValueBuilder::makeDouble(const_->value.getf32()), + JS_DOUBLE)); break; } case Type::f64: { - theValue = makeAsmCoercion( - ValueBuilder::makeDouble(const_->value.getf64()), ASM_DOUBLE); + theValue = makeJsCoercion( + ValueBuilder::makeDouble(const_->value.getf64()), JS_DOUBLE); break; } default: { @@ -864,8 +860,8 @@ Ref Wasm2JSBuilder::processFunction(Module* m, ret[3]->push_back(ValueBuilder::makeStatement(ValueBuilder::makeBinary( ValueBuilder::makeName(name), SET, - makeAsmCoercion(ValueBuilder::makeName(name), - wasmToAsmType(func->getLocalType(i)))))); + makeJsCoercion(ValueBuilder::makeName(name), + wasmToJsType(func->getLocalType(i)))))); } } Ref theVar = ValueBuilder::makeVar(); @@ -878,7 +874,7 @@ Ref Wasm2JSBuilder::processFunction(Module* m, ValueBuilder::appendToVar( theVar, fromName(func->getLocalNameOrGeneric(i), NameScope::Local), - makeAsmCoercedZero(wasmToAsmType(func->getLocalType(i)))); + makeJsCoercedZero(wasmToJsType(func->getLocalType(i)))); } if (theVar[1]->size() == 0) { ret[3]->splice(theVarIndex, 1); @@ -1191,7 +1187,7 @@ Ref Wasm2JSBuilder::processFunctionBody(Module* m, // nesting of a size that JS engines can't handle. Ref condition = visit(curr->condition, EXPRESSION_RESULT); Ref theSwitch = - ValueBuilder::makeSwitch(makeAsmCoercion(condition, ASM_INT)); + ValueBuilder::makeSwitch(makeJsCoercion(condition, JS_INT)); // First, group the switch targets. std::map<Name, std::vector<Index>> targetIndexes; for (size_t i = 0; i < curr->targets.size(); i++) { @@ -1281,12 +1277,12 @@ Ref Wasm2JSBuilder::processFunctionBody(Module* m, for (auto operand : curr->operands) { auto value = visit(operand, EXPRESSION_RESULT); if (needCoercions) { - value = makeAsmCoercion(value, wasmToAsmType(operand->type)); + value = makeJsCoercion(value, wasmToJsType(operand->type)); } theCall[2]->push_back(value); } if (needCoercions) { - theCall = makeAsmCoercion(theCall, wasmToAsmType(curr->type)); + theCall = makeJsCoercion(theCall, wasmToJsType(curr->type)); } return theCall; } @@ -1315,7 +1311,7 @@ Ref Wasm2JSBuilder::processFunctionBody(Module* m, // because FUNCTION_TABLE is just a normal JS object, not a typed array // or a mathematical operation (all of which coerce to a number for us). auto target = visit(curr->target, EXPRESSION_RESULT); - target = makeAsmCoercion(target, ASM_INT); + target = makeJsCoercion(target, JS_INT); if (mustReorder) { Ref ret; ScopedTemp idx(Type::i32, parent, func); @@ -1333,10 +1329,10 @@ Ref Wasm2JSBuilder::processFunctionBody(Module* m, for (size_t i = 0; i < temps.size(); i++) { IString temp = temps[i]->temp; auto& operand = curr->operands[i]; - theCall[2]->push_back(makeAsmCoercion(ValueBuilder::makeName(temp), - wasmToAsmType(operand->type))); + theCall[2]->push_back(makeJsCoercion(ValueBuilder::makeName(temp), + wasmToJsType(operand->type))); } - theCall = makeAsmCoercion(theCall, wasmToAsmType(curr->type)); + theCall = makeJsCoercion(theCall, wasmToJsType(curr->type)); sequenceAppend(ret, theCall); for (auto temp : temps) { delete temp; @@ -1349,7 +1345,7 @@ Ref Wasm2JSBuilder::processFunctionBody(Module* m, for (auto* operand : curr->operands) { theCall[2]->push_back(visit(operand, EXPRESSION_RESULT)); } - theCall = makeAsmCoercion(theCall, wasmToAsmType(curr->type)); + theCall = makeJsCoercion(theCall, wasmToJsType(curr->type)); return theCall; } } @@ -1444,7 +1440,7 @@ Ref Wasm2JSBuilder::processFunctionBody(Module* m, bool needCoercions = parent->options.optimizeLevel == 0 || standaloneFunction; if (needCoercions) { - ret = makeAsmCoercion(ret, wasmToAsmType(curr->type)); + ret = makeJsCoercion(ret, wasmToJsType(curr->type)); } return ret; } @@ -1689,11 +1685,11 @@ Ref Wasm2JSBuilder::processFunctionBody(Module* m, MATH_SQRT, visit(curr->value, EXPRESSION_RESULT)); break; case PromoteFloat32: - return makeAsmCoercion(visit(curr->value, EXPRESSION_RESULT), - ASM_DOUBLE); + return makeJsCoercion(visit(curr->value, EXPRESSION_RESULT), + JS_DOUBLE); case DemoteFloat64: - return makeAsmCoercion(visit(curr->value, EXPRESSION_RESULT), - ASM_FLOAT); + return makeJsCoercion(visit(curr->value, EXPRESSION_RESULT), + JS_FLOAT); case ReinterpretInt32: { ABI::wasm2js::ensureHelpers(module, ABI::wasm2js::SCRATCH_STORE_I32); @@ -1712,27 +1708,27 @@ Ref Wasm2JSBuilder::processFunctionBody(Module* m, } // Coerce the integer to a float as emscripten does case ConvertSInt32ToFloat32: - return makeAsmCoercion( - makeAsmCoercion(visit(curr->value, EXPRESSION_RESULT), ASM_INT), - ASM_FLOAT); + return makeJsCoercion( + makeJsCoercion(visit(curr->value, EXPRESSION_RESULT), JS_INT), + JS_FLOAT); case ConvertSInt32ToFloat64: - return makeAsmCoercion( - makeAsmCoercion(visit(curr->value, EXPRESSION_RESULT), ASM_INT), - ASM_DOUBLE); + return makeJsCoercion( + makeJsCoercion(visit(curr->value, EXPRESSION_RESULT), JS_INT), + JS_DOUBLE); // Generate (expr >>> 0), followed by a coercion case ConvertUInt32ToFloat32: - return makeAsmCoercion( + return makeJsCoercion( ValueBuilder::makeBinary(visit(curr->value, EXPRESSION_RESULT), TRSHIFT, ValueBuilder::makeInt(0)), - ASM_FLOAT); + JS_FLOAT); case ConvertUInt32ToFloat64: - return makeAsmCoercion( + return makeJsCoercion( ValueBuilder::makeBinary(visit(curr->value, EXPRESSION_RESULT), TRSHIFT, ValueBuilder::makeInt(0)), - ASM_DOUBLE); + JS_DOUBLE); // TODO: more complex unary conversions case NearestFloat32: case NearestFloat64: @@ -1743,7 +1739,7 @@ Ref Wasm2JSBuilder::processFunctionBody(Module* m, WASM_UNREACHABLE("unhandled unary float operator"); } if (curr->type == Type::f32) { // doubles need much less coercing - return makeAsmCoercion(ret, ASM_FLOAT); + return makeJsCoercion(ret, JS_FLOAT); } return ret; } @@ -1776,24 +1772,24 @@ Ref Wasm2JSBuilder::processFunctionBody(Module* m, } } case DivSInt32: - ret = ValueBuilder::makeBinary(makeSigning(left, ASM_SIGNED), + ret = ValueBuilder::makeBinary(makeSigning(left, JS_SIGNED), DIV, - makeSigning(right, ASM_SIGNED)); + makeSigning(right, JS_SIGNED)); break; case DivUInt32: - ret = ValueBuilder::makeBinary(makeSigning(left, ASM_UNSIGNED), + ret = ValueBuilder::makeBinary(makeSigning(left, JS_UNSIGNED), DIV, - makeSigning(right, ASM_UNSIGNED)); + makeSigning(right, JS_UNSIGNED)); break; case RemSInt32: - ret = ValueBuilder::makeBinary(makeSigning(left, ASM_SIGNED), + ret = ValueBuilder::makeBinary(makeSigning(left, JS_SIGNED), MOD, - makeSigning(right, ASM_SIGNED)); + makeSigning(right, JS_SIGNED)); break; case RemUInt32: - ret = ValueBuilder::makeBinary(makeSigning(left, ASM_UNSIGNED), + ret = ValueBuilder::makeBinary(makeSigning(left, JS_UNSIGNED), MOD, - makeSigning(right, ASM_UNSIGNED)); + makeSigning(right, JS_UNSIGNED)); break; case AndInt32: ret = ValueBuilder::makeBinary(left, AND, right); @@ -1814,47 +1810,47 @@ Ref Wasm2JSBuilder::processFunctionBody(Module* m, ret = ValueBuilder::makeBinary(left, RSHIFT, right); break; case EqInt32: { - return ValueBuilder::makeBinary(makeSigning(left, ASM_SIGNED), + return ValueBuilder::makeBinary(makeSigning(left, JS_SIGNED), EQ, - makeSigning(right, ASM_SIGNED)); + makeSigning(right, JS_SIGNED)); } case NeInt32: { - return ValueBuilder::makeBinary(makeSigning(left, ASM_SIGNED), + return ValueBuilder::makeBinary(makeSigning(left, JS_SIGNED), NE, - makeSigning(right, ASM_SIGNED)); + makeSigning(right, JS_SIGNED)); } case LtSInt32: - return ValueBuilder::makeBinary(makeSigning(left, ASM_SIGNED), + return ValueBuilder::makeBinary(makeSigning(left, JS_SIGNED), LT, - makeSigning(right, ASM_SIGNED)); + makeSigning(right, JS_SIGNED)); case LtUInt32: - return ValueBuilder::makeBinary(makeSigning(left, ASM_UNSIGNED), + return ValueBuilder::makeBinary(makeSigning(left, JS_UNSIGNED), LT, - makeSigning(right, ASM_UNSIGNED)); + makeSigning(right, JS_UNSIGNED)); case LeSInt32: - return ValueBuilder::makeBinary(makeSigning(left, ASM_SIGNED), + return ValueBuilder::makeBinary(makeSigning(left, JS_SIGNED), LE, - makeSigning(right, ASM_SIGNED)); + makeSigning(right, JS_SIGNED)); case LeUInt32: - return ValueBuilder::makeBinary(makeSigning(left, ASM_UNSIGNED), + return ValueBuilder::makeBinary(makeSigning(left, JS_UNSIGNED), LE, - makeSigning(right, ASM_UNSIGNED)); + makeSigning(right, JS_UNSIGNED)); case GtSInt32: - return ValueBuilder::makeBinary(makeSigning(left, ASM_SIGNED), + return ValueBuilder::makeBinary(makeSigning(left, JS_SIGNED), GT, - makeSigning(right, ASM_SIGNED)); + makeSigning(right, JS_SIGNED)); case GtUInt32: - return ValueBuilder::makeBinary(makeSigning(left, ASM_UNSIGNED), + return ValueBuilder::makeBinary(makeSigning(left, JS_UNSIGNED), GT, - makeSigning(right, ASM_UNSIGNED)); + makeSigning(right, JS_UNSIGNED)); case GeSInt32: - return ValueBuilder::makeBinary(makeSigning(left, ASM_SIGNED), + return ValueBuilder::makeBinary(makeSigning(left, JS_SIGNED), GE, - makeSigning(right, ASM_SIGNED)); + makeSigning(right, JS_SIGNED)); case GeUInt32: - return ValueBuilder::makeBinary(makeSigning(left, ASM_UNSIGNED), + return ValueBuilder::makeBinary(makeSigning(left, JS_UNSIGNED), GE, - makeSigning(right, ASM_UNSIGNED)); + makeSigning(right, JS_UNSIGNED)); case EqFloat32: case EqFloat64: return ValueBuilder::makeBinary(left, EQ, right); @@ -1914,13 +1910,13 @@ Ref Wasm2JSBuilder::processFunctionBody(Module* m, Fatal() << "Unhandled binary float operator: "; } if (curr->type == Type::f32) { - return makeAsmCoercion(ret, ASM_FLOAT); + return makeJsCoercion(ret, JS_FLOAT); } return ret; default: Fatal() << "Unhandled type in binary: " << curr; } - return makeAsmCoercion(ret, wasmToAsmType(curr->type)); + return makeJsCoercion(ret, wasmToJsType(curr->type)); } Ref visitSelect(Select* curr) { @@ -1972,7 +1968,7 @@ Ref Wasm2JSBuilder::processFunctionBody(Module* m, parent->options.optimizeLevel == 0 || standaloneFunction || parent->functionsCallableFromOutside.count(func->name); if (needCoercion) { - val = makeAsmCoercion(val, wasmToAsmType(curr->value->type)); + val = makeJsCoercion(val, wasmToJsType(curr->value->type)); } return ValueBuilder::makeReturn(val); } @@ -1986,8 +1982,8 @@ Ref Wasm2JSBuilder::processFunctionBody(Module* m, module->memory.max > module->memory.initial) { return ValueBuilder::makeCall( WASM_MEMORY_GROW, - makeAsmCoercion(visit(curr->delta, EXPRESSION_RESULT), - wasmToAsmType(curr->delta->type))); + makeJsCoercion(visit(curr->delta, EXPRESSION_RESULT), + wasmToJsType(curr->delta->type))); } else { return ValueBuilder::makeCall(ABORT_FUNC); } @@ -2073,7 +2069,7 @@ Ref Wasm2JSBuilder::processFunctionBody(Module* m, ValueBuilder::appendToCall(call, hap.ptr); ValueBuilder::appendToCall(call, expected); ValueBuilder::appendToCall(call, replacement); - return makeAsmCoercion(call, wasmToAsmType(curr->type)); + return makeJsCoercion(call, wasmToJsType(curr->type)); } Ref visitAtomicWait(AtomicWait* curr) { @@ -2268,9 +2264,9 @@ Ref Wasm2JSBuilder::processFunctionBody(Module* m, Ref makePointer(Expression* ptr, Address offset) { auto ret = visit(ptr, EXPRESSION_RESULT); if (offset) { - ret = makeAsmCoercion( + ret = makeJsCoercion( ValueBuilder::makeBinary(ret, PLUS, ValueBuilder::makeNum(offset)), - ASM_INT); + JS_INT); } return ret; } @@ -2286,12 +2282,12 @@ Ref Wasm2JSBuilder::processFunctionBody(Module* m, void Wasm2JSBuilder::addMemoryFuncs(Ref ast, Module* wasm) { Ref memorySizeFunc = ValueBuilder::makeFunction(WASM_MEMORY_SIZE); memorySizeFunc[3]->push_back(ValueBuilder::makeReturn( - makeAsmCoercion(ValueBuilder::makeBinary( - ValueBuilder::makeDot(ValueBuilder::makeName(BUFFER), - IString("byteLength")), - DIV, - ValueBuilder::makeInt(Memory::kPageSize)), - AsmType::ASM_INT))); + makeJsCoercion(ValueBuilder::makeBinary( + ValueBuilder::makeDot(ValueBuilder::makeName(BUFFER), + IString("byteLength")), + DIV, + ValueBuilder::makeInt(Memory::kPageSize)), + JsType::JS_INT))); ast->push_back(memorySizeFunc); if (wasm->memory.max > wasm->memory.initial) { @@ -2307,27 +2303,26 @@ void Wasm2JSBuilder::addMemoryGrowFunc(Ref ast, Module* wasm) { ValueBuilder::makeStatement(ValueBuilder::makeBinary( ValueBuilder::makeName(IString("pagesToAdd")), SET, - makeAsmCoercion(ValueBuilder::makeName(IString("pagesToAdd")), - AsmType::ASM_INT)))); + makeJsCoercion(ValueBuilder::makeName(IString("pagesToAdd")), + JsType::JS_INT)))); Ref oldPages = ValueBuilder::makeVar(); memoryGrowFunc[3]->push_back(oldPages); ValueBuilder::appendToVar( oldPages, IString("oldPages"), - makeAsmCoercion(ValueBuilder::makeCall(WASM_MEMORY_SIZE), - AsmType::ASM_INT)); + makeJsCoercion(ValueBuilder::makeCall(WASM_MEMORY_SIZE), JsType::JS_INT)); Ref newPages = ValueBuilder::makeVar(); memoryGrowFunc[3]->push_back(newPages); ValueBuilder::appendToVar( newPages, IString("newPages"), - makeAsmCoercion( + makeJsCoercion( ValueBuilder::makeBinary(ValueBuilder::makeName(IString("oldPages")), PLUS, ValueBuilder::makeName(IString("pagesToAdd"))), - AsmType::ASM_INT)); + JsType::JS_INT)); Ref block = ValueBuilder::makeBlock(); memoryGrowFunc[3]->push_back(ValueBuilder::makeIf( |