diff options
Diffstat (limited to 'src/wasm/wasm-stack.cpp')
-rw-r--r-- | src/wasm/wasm-stack.cpp | 76 |
1 files changed, 61 insertions, 15 deletions
diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp index 593214838..22d6a0036 100644 --- a/src/wasm/wasm-stack.cpp +++ b/src/wasm/wasm-stack.cpp @@ -147,8 +147,10 @@ void BinaryInstWriter::visitLoad(Load* curr) { // the pointer is unreachable, so we are never reached; just don't emit // a load return; - case anyref: // anyref cannot be loaded from memory - case exnref: // exnref cannot be loaded from memory + case funcref: + case anyref: + case nullref: + case exnref: case none: WASM_UNREACHABLE("unexpected type"); } @@ -247,8 +249,10 @@ void BinaryInstWriter::visitStore(Store* curr) { o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::V128Store); break; - case anyref: // anyref cannot be stored from memory - case exnref: // exnref cannot be stored in memory + case funcref: + case anyref: + case nullref: + case exnref: case none: case unreachable: WASM_UNREACHABLE("unexpected type"); @@ -642,8 +646,10 @@ void BinaryInstWriter::visitConst(Const* curr) { } break; } - case anyref: // there's no anyref.const - case exnref: // there's no exnref.const + case funcref: + case anyref: + case nullref: + case exnref: case none: case unreachable: WASM_UNREACHABLE("unexpected type"); @@ -1541,7 +1547,15 @@ void BinaryInstWriter::visitBinary(Binary* curr) { } void BinaryInstWriter::visitSelect(Select* curr) { - o << int8_t(BinaryConsts::Select); + if (curr->type.isRef()) { + o << int8_t(BinaryConsts::SelectWithType) << U32LEB(curr->type.size()); + for (size_t i = 0; i < curr->type.size(); i++) { + o << binaryType(curr->type != Type::unreachable ? curr->type + : Type::none); + } + } else { + o << int8_t(BinaryConsts::Select); + } } void BinaryInstWriter::visitReturn(Return* curr) { @@ -1562,6 +1576,19 @@ void BinaryInstWriter::visitHost(Host* curr) { o << U32LEB(0); // Reserved flags field } +void BinaryInstWriter::visitRefNull(RefNull* curr) { + o << int8_t(BinaryConsts::RefNull); +} + +void BinaryInstWriter::visitRefIsNull(RefIsNull* curr) { + o << int8_t(BinaryConsts::RefIsNull); +} + +void BinaryInstWriter::visitRefFunc(RefFunc* curr) { + o << int8_t(BinaryConsts::RefFunc) + << U32LEB(parent.getFunctionIndex(curr->func)); +} + void BinaryInstWriter::visitTry(Try* curr) { breakStack.emplace_back(IMPOSSIBLE_CONTINUE); o << int8_t(BinaryConsts::Try); @@ -1659,11 +1686,21 @@ void BinaryInstWriter::mapLocalsAndEmitHeader() { continue; } index += numLocalsByType[v128]; + if (type == funcref) { + mappedLocals[i] = index + currLocalsByType[funcref] - 1; + continue; + } + index += numLocalsByType[funcref]; if (type == anyref) { mappedLocals[i] = index + currLocalsByType[anyref] - 1; continue; } index += numLocalsByType[anyref]; + if (type == nullref) { + mappedLocals[i] = index + currLocalsByType[nullref] - 1; + continue; + } + index += numLocalsByType[nullref]; if (type == exnref) { mappedLocals[i] = index + currLocalsByType[exnref] - 1; continue; @@ -1671,11 +1708,12 @@ void BinaryInstWriter::mapLocalsAndEmitHeader() { WASM_UNREACHABLE("unexpected type"); } // Emit them. - o << U32LEB((numLocalsByType[i32] ? 1 : 0) + (numLocalsByType[i64] ? 1 : 0) + - (numLocalsByType[f32] ? 1 : 0) + (numLocalsByType[f64] ? 1 : 0) + - (numLocalsByType[v128] ? 1 : 0) + - (numLocalsByType[anyref] ? 1 : 0) + - (numLocalsByType[exnref] ? 1 : 0)); + o << U32LEB( + (numLocalsByType[i32] ? 1 : 0) + (numLocalsByType[i64] ? 1 : 0) + + (numLocalsByType[f32] ? 1 : 0) + (numLocalsByType[f64] ? 1 : 0) + + (numLocalsByType[v128] ? 1 : 0) + (numLocalsByType[funcref] ? 1 : 0) + + (numLocalsByType[anyref] ? 1 : 0) + (numLocalsByType[nullref] ? 1 : 0) + + (numLocalsByType[exnref] ? 1 : 0)); if (numLocalsByType[i32]) { o << U32LEB(numLocalsByType[i32]) << binaryType(i32); } @@ -1691,9 +1729,15 @@ void BinaryInstWriter::mapLocalsAndEmitHeader() { if (numLocalsByType[v128]) { o << U32LEB(numLocalsByType[v128]) << binaryType(v128); } + if (numLocalsByType[funcref]) { + o << U32LEB(numLocalsByType[funcref]) << binaryType(funcref); + } if (numLocalsByType[anyref]) { o << U32LEB(numLocalsByType[anyref]) << binaryType(anyref); } + if (numLocalsByType[nullref]) { + o << U32LEB(numLocalsByType[nullref]) << binaryType(nullref); + } if (numLocalsByType[exnref]) { o << U32LEB(numLocalsByType[exnref]) << binaryType(exnref); } @@ -1760,7 +1804,7 @@ StackInst* StackIRGenerator::makeStackInst(StackInst::Op op, // type. stackType = none; } else if (op != StackInst::BlockEnd && op != StackInst::IfEnd && - op != StackInst::LoopEnd) { + op != StackInst::LoopEnd && op != StackInst::TryEnd) { // If a concrete type is returned, we mark the end of the construct has // having that type (as it is pushed to the value stack at that point), // other parts are marked as none). @@ -1781,13 +1825,15 @@ void StackIRToBinaryWriter::write() { case StackInst::Basic: case StackInst::BlockBegin: case StackInst::IfBegin: - case StackInst::LoopBegin: { + case StackInst::LoopBegin: + case StackInst::TryBegin: { writer.visit(inst->origin); break; } case StackInst::BlockEnd: case StackInst::IfEnd: - case StackInst::LoopEnd: { + case StackInst::LoopEnd: + case StackInst::TryEnd: { writer.emitScopeEnd(); break; } |