diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/wasm-interpreter.h | 10 | ||||
-rw-r--r-- | src/wasm-js.cpp | 6 | ||||
-rw-r--r-- | src/wasm-s-parser.h | 13 | ||||
-rw-r--r-- | src/wasm-validator.h | 22 | ||||
-rw-r--r-- | src/wasm.h | 7 |
5 files changed, 42 insertions, 16 deletions
diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h index 3f9427ed7..73a536903 100644 --- a/src/wasm-interpreter.h +++ b/src/wasm-interpreter.h @@ -233,17 +233,17 @@ private: Flow visitBreak(Break *curr) { NOTE_ENTER("Break"); bool condition = true; - if (curr->condition) { - Flow flow = visit(curr->condition); - if (flow.breaking()) return flow; - condition = flow.value.getInteger(); - } Flow flow(curr->name); if (curr->value) { flow = visit(curr->value); if (flow.breaking()) return flow; flow.breakTo = curr->name; } + if (curr->condition) { + Flow conditionFlow = visit(curr->condition); + if (conditionFlow.breaking()) return conditionFlow; + condition = conditionFlow.value.getInteger(); + } return condition ? flow : Flow(); } Flow visitSwitch(Switch *curr) { diff --git a/src/wasm-js.cpp b/src/wasm-js.cpp index 067e3fdea..82a74d2ab 100644 --- a/src/wasm-js.cpp +++ b/src/wasm-js.cpp @@ -311,8 +311,8 @@ extern "C" void EMSCRIPTEN_KEEPALIVE call_from_js(const char *target) { if (wasmJSDebug) std::cout << "call_from_js returning " << ret << '\n'; if (ret.type == none) EM_ASM({ Module['tempReturn'] = undefined }); - else if (ret.type == i32) EM_ASM_({ Module['tempReturn'] = $0 }, ret.i32); - else if (ret.type == f32) EM_ASM_({ Module['tempReturn'] = $0 }, ret.f32); - else if (ret.type == f64) EM_ASM_({ Module['tempReturn'] = $0 }, ret.f64); + else if (ret.type == i32) EM_ASM_({ Module['tempReturn'] = $0 }, ret.geti32()); + else if (ret.type == f32) EM_ASM_({ Module['tempReturn'] = $0 }, ret.getf32()); + else if (ret.type == f64) EM_ASM_({ Module['tempReturn'] = $0 }, ret.getf64()); else abort(); } diff --git a/src/wasm-s-parser.h b/src/wasm-s-parser.h index dc946fc3b..ce216fd8e 100644 --- a/src/wasm-s-parser.h +++ b/src/wasm-s-parser.h @@ -868,10 +868,6 @@ private: Expression* makeBreak(Element& s) { auto ret = allocator.alloc<Break>(); size_t i = 1; - if (s[0]->str() == BR_IF) { - ret->condition = parseExpression(s[i]); - i++; - } if (s[i]->dollared()) { ret->name = s[i]->str(); } else { @@ -881,7 +877,14 @@ private: ret->name = labelStack[labelStack.size() - 1 - offset]; } i++; - if (i < s.size()) { + if (i == s.size()) return ret; + if (s[0]->str() == BR_IF) { + if (i + 1 < s.size()) { + ret->value = parseExpression(s[i]); + i++; + } + ret->condition = parseExpression(s[i]); + } else { ret->value = parseExpression(s[i]); } return ret; diff --git a/src/wasm-validator.h b/src/wasm-validator.h index ba4e5fe08..fad33a081 100644 --- a/src/wasm-validator.h +++ b/src/wasm-validator.h @@ -28,6 +28,8 @@ namespace wasm { struct WasmValidator : public WasmWalker<WasmValidator> { bool valid; + std::map<Name, WasmType> breakTypes; // breaks to a label must all have the same type, and the right type + public: bool validate(Module& module) { valid = true; @@ -37,6 +39,15 @@ public: // visitors + void visitBlock(Block *curr) { + // if we are break'ed to, then the value must be right for us + if (curr->name.is()) { + if (breakTypes.count(curr->name) > 0) { + shouldBeTrue(curr->type == breakTypes[curr->name]); + breakTypes.erase(curr->name); + } + } + } void visitLoop(Loop *curr) { if (curr->in.is()) { LoopChildChecker childChecker(curr->in); @@ -44,6 +55,17 @@ public: shouldBeTrue(childChecker.valid); } } + void visitBreak(Break *curr) { + WasmType valueType = none; + if (curr->value) { + valueType = curr->value->type; + } + if (breakTypes.count(curr->name) == 0) { + breakTypes[curr->name] = valueType; + } else { + shouldBeTrue(valueType == breakTypes[curr->name]); + } + } void visitSetLocal(SetLocal *curr) { shouldBeTrue(curr->type == curr->value->type); } diff --git a/src/wasm.h b/src/wasm.h index 893c777c4..20a7b34ef 100644 --- a/src/wasm.h +++ b/src/wasm.h @@ -511,10 +511,8 @@ public: std::ostream& doPrint(std::ostream &o, unsigned indent) { if (condition) { - printOpening(o, "br_if"); + printOpening(o, "br_if ") << name; incIndent(o, indent); - printFullLine(o, indent, condition); - doIndent(o, indent) << name << '\n'; } else { printOpening(o, "br ") << name; if (!value || value->is<Nop>()) { @@ -525,6 +523,9 @@ public: incIndent(o, indent); } if (value && !value->is<Nop>()) printFullLine(o, indent, value); + if (condition) { + printFullLine(o, indent, condition); + } return decIndent(o, indent); } }; |