diff options
Diffstat (limited to 'src/wasm/wasm-binary.cpp')
-rw-r--r-- | src/wasm/wasm-binary.cpp | 83 |
1 files changed, 68 insertions, 15 deletions
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index 82eb51d7e..ba5a8d3dd 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -262,7 +262,7 @@ void WasmBinaryWriter::writeImports() { BYN_TRACE("write one table\n"); writeImportHeader(&wasm->table); o << U32LEB(int32_t(ExternalKind::Table)); - o << S32LEB(BinaryConsts::EncodedType::AnyFunc); + o << S32LEB(BinaryConsts::EncodedType::funcref); writeResizableLimits(wasm->table.initial, wasm->table.max, wasm->table.hasMax(), @@ -463,7 +463,7 @@ void WasmBinaryWriter::writeFunctionTableDeclaration() { BYN_TRACE("== writeFunctionTableDeclaration\n"); auto start = startSection(BinaryConsts::Section::Table); o << U32LEB(1); // Declare 1 table. - o << S32LEB(BinaryConsts::EncodedType::AnyFunc); + o << S32LEB(BinaryConsts::EncodedType::funcref); writeResizableLimits(wasm->table.initial, wasm->table.max, wasm->table.hasMax(), @@ -1059,8 +1059,12 @@ Type WasmBinaryBuilder::getType() { return f64; case BinaryConsts::EncodedType::v128: return v128; + case BinaryConsts::EncodedType::funcref: + return funcref; case BinaryConsts::EncodedType::anyref: return anyref; + case BinaryConsts::EncodedType::nullref: + return nullref; case BinaryConsts::EncodedType::exnref: return exnref; default: @@ -1258,8 +1262,8 @@ void WasmBinaryBuilder::readImports() { wasm.table.name = Name(std::string("timport$") + std::to_string(i)); auto elementType = getS32LEB(); WASM_UNUSED(elementType); - if (elementType != BinaryConsts::EncodedType::AnyFunc) { - throwError("Imported table type is not AnyFunc"); + if (elementType != BinaryConsts::EncodedType::funcref) { + throwError("Imported table type is not funcref"); } wasm.table.exists = true; bool is_shared; @@ -1802,11 +1806,17 @@ void WasmBinaryBuilder::processFunctions() { wasm.addExport(curr); } - for (auto& iter : functionCalls) { + for (auto& iter : functionRefs) { size_t index = iter.first; - auto& calls = iter.second; - for (auto* call : calls) { - call->target = getFunctionName(index); + auto& refs = iter.second; + for (auto* ref : refs) { + if (auto* call = ref->dynCast<Call>()) { + call->target = getFunctionName(index); + } else if (auto* refFunc = ref->dynCast<RefFunc>()) { + refFunc->func = getFunctionName(index); + } else { + WASM_UNREACHABLE("Invalid type in function references"); + } } } @@ -1869,8 +1879,8 @@ void WasmBinaryBuilder::readFunctionTableDeclaration() { } wasm.table.exists = true; auto elemType = getS32LEB(); - if (elemType != BinaryConsts::EncodedType::AnyFunc) { - throwError("ElementType must be AnyFunc in MVP"); + if (elemType != BinaryConsts::EncodedType::funcref) { + throwError("ElementType must be funcref in MVP"); } bool is_shared; getResizableLimits( @@ -2117,7 +2127,8 @@ BinaryConsts::ASTNodes WasmBinaryBuilder::readExpression(Expression*& curr) { visitGlobalSet((curr = allocator.alloc<GlobalSet>())->cast<GlobalSet>()); break; case BinaryConsts::Select: - visitSelect((curr = allocator.alloc<Select>())->cast<Select>()); + case BinaryConsts::SelectWithType: + visitSelect((curr = allocator.alloc<Select>())->cast<Select>(), code); break; case BinaryConsts::Return: visitReturn((curr = allocator.alloc<Return>())->cast<Return>()); @@ -2137,6 +2148,15 @@ BinaryConsts::ASTNodes WasmBinaryBuilder::readExpression(Expression*& curr) { case BinaryConsts::Catch: curr = nullptr; break; + case BinaryConsts::RefNull: + visitRefNull((curr = allocator.alloc<RefNull>())->cast<RefNull>()); + break; + case BinaryConsts::RefIsNull: + visitRefIsNull((curr = allocator.alloc<RefIsNull>())->cast<RefIsNull>()); + break; + case BinaryConsts::RefFunc: + visitRefFunc((curr = allocator.alloc<RefFunc>())->cast<RefFunc>()); + break; case BinaryConsts::Try: visitTry((curr = allocator.alloc<Try>())->cast<Try>()); break; @@ -2510,7 +2530,7 @@ void WasmBinaryBuilder::visitCall(Call* curr) { curr->operands[num - i - 1] = popNonVoidExpression(); } curr->type = sig.results; - functionCalls[index].push_back(curr); // we don't know function names yet + functionRefs[index].push_back(curr); // we don't know function names yet curr->finalize(); } @@ -4326,12 +4346,24 @@ bool WasmBinaryBuilder::maybeVisitSIMDLoad(Expression*& out, uint32_t code) { return true; } -void WasmBinaryBuilder::visitSelect(Select* curr) { - BYN_TRACE("zz node: Select\n"); +void WasmBinaryBuilder::visitSelect(Select* curr, uint8_t code) { + BYN_TRACE("zz node: Select, code " << int32_t(code) << std::endl); + if (code == BinaryConsts::SelectWithType) { + size_t numTypes = getU32LEB(); + std::vector<Type> types; + for (size_t i = 0; i < numTypes; i++) { + types.push_back(getType()); + } + curr->type = Type(types); + } curr->condition = popNonVoidExpression(); curr->ifFalse = popNonVoidExpression(); curr->ifTrue = popNonVoidExpression(); - curr->finalize(); + if (code == BinaryConsts::SelectWithType) { + curr->finalize(curr->type); + } else { + curr->finalize(); + } } void WasmBinaryBuilder::visitReturn(Return* curr) { @@ -4383,6 +4415,27 @@ void WasmBinaryBuilder::visitDrop(Drop* curr) { curr->finalize(); } +void WasmBinaryBuilder::visitRefNull(RefNull* curr) { + BYN_TRACE("zz node: RefNull\n"); + curr->finalize(); +} + +void WasmBinaryBuilder::visitRefIsNull(RefIsNull* curr) { + BYN_TRACE("zz node: RefIsNull\n"); + curr->value = popNonVoidExpression(); + curr->finalize(); +} + +void WasmBinaryBuilder::visitRefFunc(RefFunc* curr) { + BYN_TRACE("zz node: RefFunc\n"); + Index index = getU32LEB(); + if (index >= functionImports.size() + functionSignatures.size()) { + throwError("ref.func: invalid call index"); + } + functionRefs[index].push_back(curr); // we don't know function names yet + curr->finalize(); +} + void WasmBinaryBuilder::visitTry(Try* curr) { BYN_TRACE("zz node: Try\n"); // For simplicity of implementation, like if scopes, we create a hidden block |