From a64153f7cd3c1efc109d4d6986882388cfd29427 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Fri, 22 Jul 2016 10:06:18 -0700 Subject: [PATCH 1/2] call_indirect is now structural in the spec:314 --- src/wasm-interpreter.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h index adaee0b6fca..5fd13d4bbb0 100644 --- a/src/wasm-interpreter.h +++ b/src/wasm-interpreter.h @@ -670,7 +670,6 @@ class ModuleInstance { if (index >= instance.wasm.table.names.size()) trap("callIndirect: overflow"); Name name = instance.wasm.table.names[index]; Function *func = instance.wasm.getFunction(name); - if (func->type.is() && func->type != curr->fullType) trap("callIndirect: bad type"); if (func->params.size() != arguments.size()) trap("callIndirect: bad # of arguments"); for (size_t i = 0; i < func->params.size(); i++) { if (func->params[i] != arguments[i].type) { From 7a84a622d57677a04cb510e276c1ce97c545b43a Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Fri, 22 Jul 2016 14:11:06 -0700 Subject: [PATCH 2/2] wast function type name desugaring is changing in spec:301 --- src/wasm-s-parser.h | 51 +++++++++++++++++++++++++++++++++++++-------- src/wasm.h | 8 +++++-- 2 files changed, 48 insertions(+), 11 deletions(-) diff --git a/src/wasm-s-parser.h b/src/wasm-s-parser.h index b93494c769c..49397f49435 100644 --- a/src/wasm-s-parser.h +++ b/src/wasm-s-parser.h @@ -312,21 +312,49 @@ class SExpressionWasmBuilder { } functionNames.push_back(name); functionCounter++; + FunctionType* type = nullptr; + functionTypes[name] = none; + std::vector params; for (;i < s.size(); i++) { Element& curr = *s[i]; IString id = curr[0]->str(); if (id == RESULT) { functionTypes[name] = stringToWasmType(curr[1]->str()); - return; } else if (id == TYPE) { Name typeName = curr[1]->str(); if (!wasm.checkFunctionType(typeName)) throw ParseException("unknown function"); - FunctionType* type = wasm.getFunctionType(typeName); + type = wasm.getFunctionType(typeName); functionTypes[name] = type->result; - return; + } else if (id == PARAM && curr.size() > 1) { + Index j = 1; + if (curr[j]->dollared()) { + // dollared input symbols cannot be types + params.push_back(stringToWasmType(curr[j + 1]->str(), true)); + } else { + while (j < curr.size()) { + params.push_back(stringToWasmType(curr[j++]->str(), true)); + } + } + } + } + if (!type) { + // if no function type provided, generate one, but reuse a previous one with the + // right structure if there is + // see https://github.com/WebAssembly/spec/pull/301 + bool need = true; + std::unique_ptr functionType = make_unique(); + functionType->result = functionTypes[name]; + functionType->params = std::move(params); + for (auto& existing : wasm.functionTypes) { + if (existing->structuralComparison(*functionType)) { + need = false; + break; + } + } + if (need) { + wasm.addFunctionType(functionType.release()); } } - functionTypes[name] = none; } void preParseImports(Element& curr) { @@ -500,16 +528,21 @@ class SExpressionWasmBuilder { body = allocator.alloc(); } if (currFunction->result != result) throw ParseException("bad func declaration", s.line, s.col); - /* TODO: spec in flux, https://github.com/WebAssembly/spec/pull/301 + // see https://github.com/WebAssembly/spec/pull/301 if (type.isNull()) { - // if no function type provided, generate a private one for this function + // if no function type name provided, then we generated one auto* functionType = sigToFunctionType(getSig(currFunction.get())); - wasm.addFunctionType(functionType); - type = functionType->name; + for (auto& existing : wasm.functionTypes) { + if (existing->structuralComparison(*functionType)) { + type = existing->name; + break; + } + } + assert(type.is()); } - */ currFunction->body = body; currFunction->type = type; + wasm.addFunction(currFunction.release()); currLocalTypes.clear(); labelStack.clear(); diff --git a/src/wasm.h b/src/wasm.h index f3eee73755b..0b3b7f14531 100644 --- a/src/wasm.h +++ b/src/wasm.h @@ -1065,8 +1065,7 @@ class FunctionType { FunctionType() : result(none) {} - bool operator==(FunctionType& b) { - if (name != b.name) return false; // XXX + bool structuralComparison(FunctionType& b) { if (result != b.result) return false; if (params.size() != b.params.size()) return false; for (size_t i = 0; i < params.size(); i++) { @@ -1074,6 +1073,11 @@ class FunctionType { } return true; } + + bool operator==(FunctionType& b) { + if (name != b.name) return false; + return structuralComparison(b); + } bool operator!=(FunctionType& b) { return !(*this == b); }