diff options
author | Alon Zakai <alonzakai@gmail.com> | 2016-08-15 14:29:57 -0700 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2016-08-15 15:03:36 -0700 |
commit | 113efcaa1e814304662ccc56312d8c59014a3a6c (patch) | |
tree | 5639a4a9d834947c9fc190e5916b9961e545cfba /src/wasm-linker.cpp | |
parent | 086c4c0f89bbe626f4c98ae95716084db0541b0d (diff) | |
download | binaryen-113efcaa1e814304662ccc56312d8c59014a3a6c.tar.gz binaryen-113efcaa1e814304662ccc56312d8c59014a3a6c.tar.bz2 binaryen-113efcaa1e814304662ccc56312d8c59014a3a6c.zip |
offset support in table
Diffstat (limited to 'src/wasm-linker.cpp')
-rw-r--r-- | src/wasm-linker.cpp | 31 |
1 files changed, 22 insertions, 9 deletions
diff --git a/src/wasm-linker.cpp b/src/wasm-linker.cpp index 29f439bfb..2c9a4cd4d 100644 --- a/src/wasm-linker.cpp +++ b/src/wasm-linker.cpp @@ -132,7 +132,7 @@ void Linker::layout() { // Emit the pre-assigned function names in sorted order for (const auto& P : functionNames) { - out.wasm.table.names.push_back(P.second); + getTableSegment().data.push_back(P.second); } for (auto& relocation : out.relocations) { @@ -206,9 +206,11 @@ void Linker::layout() { } // ensure an explicit function type for indirect call targets - for (auto& name : out.wasm.table.names) { - auto* func = out.wasm.getFunction(name); - func->type = ensureFunctionType(getSig(func), &out.wasm)->name; + for (auto& segment : out.wasm.table.segments) { + for (auto& name : segment.data) { + auto* func = out.wasm.getFunction(name); + func->type = ensureFunctionType(getSig(func), &out.wasm)->name; + } } // Export malloc and free whenever availble. JavsScript version of malloc has @@ -225,7 +227,9 @@ void Linker::layout() { } // finalize function table - out.wasm.table.initial = out.wasm.table.max = out.wasm.table.names.size(); + if (out.wasm.table.segments.size() > 0) { + out.wasm.table.initial = out.wasm.table.max = getTableSegment().data.size(); + } } bool Linker::linkObject(S2WasmBuilder& builder) { @@ -385,10 +389,19 @@ void Linker::emscriptenGlue(std::ostream& o) { o << " }\n"; } +Table::Segment& Linker::getTableSegment() { + if (out.wasm.table.segments.size() == 0) { + out.wasm.table.segments.emplace_back(out.wasm.allocator.alloc<Const>()->set(Literal(uint32_t(0)))); + } else { + assert(out.wasm.table.segments.size() == 1); + } + return out.wasm.table.segments[0]; +} + Index Linker::getFunctionIndex(Name name) { if (!functionIndexes.count(name)) { - functionIndexes[name] = out.wasm.table.names.size(); - out.wasm.table.names.push_back(name); + functionIndexes[name] = getTableSegment().data.size(); + getTableSegment().data.push_back(name); if (debug) { std::cerr << "function index: " << name << ": " << functionIndexes[name] << '\n'; @@ -406,7 +419,6 @@ bool hasI64ResultOrParam(FunctionType* ft) { } void Linker::makeDummyFunction() { - assert(out.wasm.table.names.empty()); bool create = false; // Check if there are address-taken functions for (auto& relocation : out.relocations) { @@ -424,9 +436,10 @@ void Linker::makeDummyFunction() { } void Linker::makeDynCallThunks() { + if (out.wasm.table.segments.size() == 0) return; std::unordered_set<std::string> sigs; wasm::Builder wasmBuilder(out.wasm); - for (const auto& indirectFunc : out.wasm.table.names) { + for (const auto& indirectFunc : getTableSegment().data) { // Skip generating thunks for the dummy function if (indirectFunc == dummyFunction) continue; std::string sig(getSig(out.wasm.getFunction(indirectFunc))); |