diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/asm2wasm.h | 2 | ||||
-rw-r--r-- | src/asmjs/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/asmjs/shared-constants.cpp (renamed from src/shared-constants.h) | 9 | ||||
-rw-r--r-- | src/asmjs/shared-constants.h | 104 | ||||
-rw-r--r-- | src/parsing.h | 4 | ||||
-rw-r--r-- | src/s2wasm-main.cpp | 8 | ||||
-rw-r--r-- | src/s2wasm.h | 109 | ||||
-rw-r--r-- | src/shell-interface.h | 3 | ||||
-rw-r--r-- | src/wasm-binary.h | 2 | ||||
-rw-r--r-- | src/wasm-linker.cpp | 36 | ||||
-rw-r--r-- | src/wasm-linker.h | 48 | ||||
-rw-r--r-- | src/wasm-s-parser.h | 2 | ||||
-rw-r--r-- | src/wasm2asm.h | 2 |
13 files changed, 250 insertions, 80 deletions
diff --git a/src/asm2wasm.h b/src/asm2wasm.h index 1da59d2f2..ae24358d7 100644 --- a/src/asm2wasm.h +++ b/src/asm2wasm.h @@ -25,7 +25,7 @@ #include "wasm.h" #include "emscripten-optimizer/optimizer.h" #include "mixed_arena.h" -#include "shared-constants.h" +#include "asmjs/shared-constants.h" #include "asm_v_wasm.h" #include "pass.h" #include "ast_utils.h" diff --git a/src/asmjs/CMakeLists.txt b/src/asmjs/CMakeLists.txt index 8be8ea2c4..2387d3ca0 100644 --- a/src/asmjs/CMakeLists.txt +++ b/src/asmjs/CMakeLists.txt @@ -1,4 +1,5 @@ SET(asmjs_SOURCES asm_v_wasm.cpp + shared-constants.cpp ) ADD_LIBRARY(asmjs STATIC ${asmjs_SOURCES})
\ No newline at end of file diff --git a/src/shared-constants.h b/src/asmjs/shared-constants.cpp index 626c5423e..bc1c0fa3d 100644 --- a/src/shared-constants.h +++ b/src/asmjs/shared-constants.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2015 WebAssembly Community Group participants + * Copyright 2016 WebAssembly Community Group participants * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,10 +14,7 @@ * limitations under the License. */ -#ifndef wasm_shared_constants_h -#define wasm_shared_constants_h - -#include "emscripten-optimizer/optimizer.h" +#include "asmjs/shared-constants.h" namespace wasm { @@ -100,5 +97,3 @@ cashew::IString GLOBAL("global"), EXIT("exit"); } - -#endif // wasm_shared_constants_h diff --git a/src/asmjs/shared-constants.h b/src/asmjs/shared-constants.h new file mode 100644 index 000000000..2f6c608ba --- /dev/null +++ b/src/asmjs/shared-constants.h @@ -0,0 +1,104 @@ +/* + * Copyright 2015 WebAssembly Community Group participants + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef wasm_asmjs_shared_constants_h +#define wasm_asmjs_shared_constants_h + +#include "emscripten-optimizer/istring.h" + +namespace wasm { + +extern cashew::IString GLOBAL, + NAN_, + INFINITY_, + NAN__, + INFINITY__, + TOPMOST, + INT8ARRAY, + INT16ARRAY, + INT32ARRAY, + UINT8ARRAY, + UINT16ARRAY, + UINT32ARRAY, + FLOAT32ARRAY, + FLOAT64ARRAY, + IMPOSSIBLE_CONTINUE, + MATH, + IMUL, + CLZ32, + FROUND, + ASM2WASM, + F64_REM, + F64_TO_INT, + GLOBAL_MATH, + ABS, + FLOOR, + CEIL, + SQRT, + I32_TEMP, + DEBUGGER, + GROW_WASM_MEMORY, + NEW_SIZE, + MODULE, + START, + FUNC, + PARAM, + RESULT, + MEMORY, + SEGMENT, + EXPORT, + IMPORT, + TABLE, + LOCAL, + TYPE, + CALL, + CALL_IMPORT, + CALL_INDIRECT, + BLOCK, + BR_IF, + THEN, + ELSE, + NEG_INFINITY, + NEG_NAN, + CASE, + BR, + USE_ASM, + BUFFER, + ENV, + FAKE_RETURN, + MATH_IMUL, + MATH_CLZ32, + MATH_CTZ32, + MATH_POPCNT32, + MATH_ABS, + MATH_CEIL, + MATH_FLOOR, + MATH_TRUNC, + MATH_NEAREST, + MATH_SQRT, + MATH_MIN, + MATH_MAX, + ASSERT_RETURN, + ASSERT_TRAP, + ASSERT_INVALID, + SPECTEST, + PRINT, + INVOKE, + EXIT; + +} + +#endif // wasm_asmjs_shared_constants_h diff --git a/src/parsing.h b/src/parsing.h index 935750537..2104337a6 100644 --- a/src/parsing.h +++ b/src/parsing.h @@ -19,14 +19,14 @@ #include <sstream> +#include "asmjs/shared-constants.h" #include "mixed_arena.h" -#include "shared-constants.h" #include "support/utilities.h" #include "wasm.h" namespace wasm { -Expression* parseConst(cashew::IString s, WasmType type, MixedArena& allocator) { +inline Expression* parseConst(cashew::IString s, WasmType type, MixedArena& allocator) { const char *str = s.str; auto ret = allocator.alloc<Const>(); ret->type = type; diff --git a/src/s2wasm-main.cpp b/src/s2wasm-main.cpp index 435eb560f..7b0e4c179 100644 --- a/src/s2wasm-main.cpp +++ b/src/s2wasm-main.cpp @@ -104,7 +104,13 @@ int main(int argc, const char *argv[]) { Linker linker(globalBase, stackAllocation, initialMem, maxMem, ignoreUnknownSymbols, startFunction, options.debug); - S2WasmBuilder s2wasm(linker.getOutput(), input.c_str(), options.debug); + S2WasmBuilder mainbuilder(input.c_str(), options.debug); + linker.linkObject(mainbuilder); + + // In the future, there will be code to open additional files/buffers and + // link additional objects, as well as archive members (which only get linked if needed), e.g.: + // S2WasmBuilder lazyObject(some_other_buffer, options.debug) + // linker.linkLazyObject(lazyObject); // calls builder.scan to get symbol info, then build linker.layout(); diff --git a/src/s2wasm.h b/src/s2wasm.h index 00e6b12a2..b66859ce9 100644 --- a/src/s2wasm.h +++ b/src/s2wasm.h @@ -37,26 +37,40 @@ namespace wasm { // class S2WasmBuilder { - Module& wasm; - MixedArena& allocator; + const char* inputStart; const char* s; bool debug; - LinkerObject& linkerObj; + Module* wasm; + MixedArena* allocator; + LinkerObject* linkerObj; public: - S2WasmBuilder(LinkerObject& linkerObj, const char* input, bool debug) - : wasm(linkerObj.wasm), - allocator(wasm.allocator), + S2WasmBuilder(const char* input, bool debug) + : inputStart(input), + s(input), debug(debug), - linkerObj(linkerObj) { - if (!linkerObj.isEmpty()) Fatal() << "Cannot construct an S2WasmBuilder in an non-empty LinkerObject"; - s = input; - scan(); - s = input; + wasm(nullptr), + allocator(nullptr), + linkerObj(nullptr) + {} + void build(LinkerObject *obj, LinkerObject::SymbolInfo* info) { + if (!obj->isEmpty()) Fatal() << "Cannot construct an S2WasmBuilder in an non-empty LinkerObject"; + if (!info) info = getSymbolInfo(); + linkerObj = obj; + wasm = &obj->wasm; + allocator = &wasm->allocator; + + s = inputStart; process(); } + LinkerObject::SymbolInfo* getSymbolInfo() { + auto* info = new LinkerObject::SymbolInfo(); + scan(info); + return info; + } + private: // utilities @@ -209,7 +223,7 @@ class S2WasmBuilder { s++; offset = -getInt(); } - linkerObj.addRelocation(kind, target, cleanFunction(name), offset); + linkerObj->addRelocation(kind, target, cleanFunction(name), offset); return true; } } @@ -334,7 +348,8 @@ class S2WasmBuilder { // processors - void scan() { + void scan(LinkerObject::SymbolInfo* info) { + s = inputStart; while (*s) { skipWhitespace(); s = strstr(s, ".type"); @@ -346,11 +361,11 @@ class S2WasmBuilder { if (match(".hidden")) mustMatch(name.str); mustMatch(name.str); if (match(":")) { - linkerObj.addImplementedFunction(name); + info->implementedFunctions.insert(name); } else if (match("=")) { Name alias = getAtSeparated(); mustMatch("@FUNCTION"); - linkerObj.addAliasedFunction(name, alias); + info->aliasedFunctions.insert({name, alias}); } else { abort_on("unknown directive"); } @@ -402,7 +417,7 @@ class S2WasmBuilder { } mustMatch(".int32"); do { - linkerObj.addInitializerFunction(cleanFunction(getStr())); + linkerObj->addInitializerFunction(cleanFunction(getStr())); skipWhitespace(); } while (match(".int32")); } @@ -437,7 +452,7 @@ class S2WasmBuilder { } void parseGlobl() { - linkerObj.addGlobal(getStr()); + linkerObj->addGlobal(getStr()); skipWhitespace(); } @@ -465,7 +480,7 @@ class S2WasmBuilder { auto getNextId = [&nextId]() { return cashew::IString(('$' + std::to_string(nextId++)).c_str(), false); }; - wasm::Builder builder(wasm); + wasm::Builder builder(*wasm); std::vector<NameType> params; WasmType resultType = none; std::vector<NameType> vars; @@ -498,7 +513,7 @@ class S2WasmBuilder { Function* func = builder.makeFunction(name, std::move(params), resultType, std::move(vars)); // parse body - func->body = allocator.alloc<Block>(); + func->body = allocator->alloc<Block>(); std::vector<Expression*> bstack; auto addToBlock = [&bstack](Expression* curr) { Expression* last = bstack.back(); @@ -543,7 +558,7 @@ class S2WasmBuilder { skipToSep(); inputs[i] = nullptr; } else { - auto curr = allocator.alloc<GetLocal>(); + auto curr = allocator->alloc<GetLocal>(); curr->index = func->getLocalIndex(getStrToSep()); curr->type = func->getLocalType(curr->index); inputs[i] = curr; @@ -569,7 +584,7 @@ class S2WasmBuilder { } else if (assign.str[1] == 'p') { // push push(curr); } else { // set to a local - auto set = allocator.alloc<SetLocal>(); + auto set = allocator->alloc<SetLocal>(); set->index = func->getLocalIndex(assign); set->value = curr; set->type = curr->type; @@ -597,7 +612,7 @@ class S2WasmBuilder { auto makeBinary = [&](BinaryOp op, WasmType type) { Name assign = getAssign(); skipComma(); - auto curr = allocator.alloc<Binary>(); + auto curr = allocator->alloc<Binary>(); curr->op = op; auto inputs = getInputs(2); curr->left = inputs[0]; @@ -609,7 +624,7 @@ class S2WasmBuilder { auto makeUnary = [&](UnaryOp op, WasmType type) { Name assign = getAssign(); skipComma(); - auto curr = allocator.alloc<Unary>(); + auto curr = allocator->alloc<Unary>(); curr->op = op; curr->value = getInput(); curr->type = type; @@ -617,20 +632,20 @@ class S2WasmBuilder { }; auto makeHost = [&](HostOp op) { Name assign = getAssign(); - auto curr = allocator.alloc<Host>(); + auto curr = allocator->alloc<Host>(); curr->op = op; setOutput(curr, assign); }; auto makeHost1 = [&](HostOp op) { Name assign = getAssign(); - auto curr = allocator.alloc<Host>(); + auto curr = allocator->alloc<Host>(); curr->op = op; curr->operands.push_back(getInput()); setOutput(curr, assign); }; auto makeLoad = [&](WasmType type) { skipComma(); - auto curr = allocator.alloc<Load>(); + auto curr = allocator->alloc<Load>(); curr->type = type; int32_t bytes = getInt() / CHAR_BIT; curr->bytes = bytes > 0 ? bytes : getWasmTypeSize(type); @@ -650,7 +665,7 @@ class S2WasmBuilder { }; auto makeStore = [&](WasmType type) { skipComma(); - auto curr = allocator.alloc<Store>(); + auto curr = allocator->alloc<Store>(); curr->type = type; int32_t bytes = getInt() / CHAR_BIT; curr->bytes = bytes > 0 ? bytes : getWasmTypeSize(type); @@ -671,7 +686,7 @@ class S2WasmBuilder { auto makeSelect = [&](WasmType type) { Name assign = getAssign(); skipComma(); - auto curr = allocator.alloc<Select>(); + auto curr = allocator->alloc<Select>(); auto inputs = getInputs(3); curr->ifTrue = inputs[0]; curr->ifFalse = inputs[1]; @@ -689,7 +704,7 @@ class S2WasmBuilder { auto input = inputs.begin(); auto* target = *input; std::vector<Expression*> operands(++input, inputs.end()); - auto* funcType = ensureFunctionType(getSig(type, operands), &wasm); + auto* funcType = ensureFunctionType(getSig(type, operands), wasm); assert(type == funcType->result); auto* indirect = builder.makeCallIndirect(funcType, target, std::move(operands)); setOutput(indirect, assign); @@ -697,13 +712,13 @@ class S2WasmBuilder { } else { // non-indirect call Name assign = getAssign(); - Name target = linkerObj.resolveAlias(cleanFunction(getCommaSeparated())); + Name target = linkerObj->resolveAlias(cleanFunction(getCommaSeparated())); - Call* curr = allocator.alloc<Call>(); + Call* curr = allocator->alloc<Call>(); curr->target = target; curr->type = type; - if (!linkerObj.isFunctionImplemented(target)) { - linkerObj.addUndefinedFunctionCall(curr); + if (!linkerObj->isFunctionImplemented(target)) { + linkerObj->addUndefinedFunctionCall(curr); } skipWhitespace(); if (*s == ',') { @@ -731,13 +746,13 @@ class S2WasmBuilder { Name assign = getAssign(); if (type == i32) { // may be a relocation - auto curr = allocator.alloc<Const>(); + auto curr = allocator->alloc<Const>(); curr->type = curr->value.type = i32; getConst((uint32_t*)curr->value.geti32Ptr()); setOutput(curr, assign); } else { cashew::IString str = getStr(); - setOutput(parseConst(str, type, allocator), assign); + setOutput(parseConst(str, type, *allocator), assign); } } else if (match("call")) makeCall(type); @@ -891,7 +906,7 @@ class S2WasmBuilder { } else if (match("f64.")) { handleTyped(f64); } else if (match("block")) { - auto curr = allocator.alloc<Block>(); + auto curr = allocator->alloc<Block>(); curr->name = getNextLabel(); addToBlock(curr); bstack.push_back(curr); @@ -900,11 +915,11 @@ class S2WasmBuilder { } else if (match(".LBB")) { s = strchr(s, '\n'); } else if (match("loop")) { - auto curr = allocator.alloc<Loop>(); + auto curr = allocator->alloc<Loop>(); addToBlock(curr); curr->in = getNextLabel(); curr->out = getNextLabel(); - auto block = allocator.alloc<Block>(); + auto block = allocator->alloc<Block>(); block->name = curr->out; // temporary, fake - this way, on bstack we have the right label at the right offset for a br curr->body = block; loopBlocks.push_back(block); @@ -914,7 +929,7 @@ class S2WasmBuilder { bstack.pop_back(); bstack.pop_back(); } else if (match("br_table")) { - auto curr = allocator.alloc<Switch>(); + auto curr = allocator->alloc<Switch>(); curr->condition = getInput(); while (skipComma()) { curr->targets.push_back(getBranchLabel(getInt())); @@ -924,7 +939,7 @@ class S2WasmBuilder { curr->targets.pop_back(); addToBlock(curr); } else if (match("br")) { - auto curr = allocator.alloc<Break>(); + auto curr = allocator->alloc<Break>(); bool hasCondition = false; if (*s == '_') { mustMatch("_if"); @@ -945,7 +960,7 @@ class S2WasmBuilder { } else if (match("tee_local")) { Name assign = getAssign(); skipComma(); - auto curr = allocator.alloc<SetLocal>(); + auto curr = allocator->alloc<SetLocal>(); curr->index = func->getLocalIndex(getAssign()); skipComma(); curr->value = getInput(); @@ -954,7 +969,7 @@ class S2WasmBuilder { } else if (match("return")) { addToBlock(builder.makeReturn(*s == '$' ? getInput() : nullptr)); } else if (match("unreachable")) { - addToBlock(allocator.alloc<Unreachable>()); + addToBlock(allocator->alloc<Unreachable>()); } else if (match("memory_size")) { makeHost(CurrentMemory); } else if (match("grow_memory")) { @@ -978,7 +993,7 @@ class S2WasmBuilder { block->name = Name(); } func->body->dynCast<Block>()->finalize(); - wasm.addFunction(func); + wasm->addFunction(func); } void parseType() { @@ -1064,7 +1079,7 @@ class S2WasmBuilder { size_t size = raw->size(); raw->resize(size + 4); if (getConst((uint32_t*)&(*raw)[size])) { // just the size, as we may reallocate; we must fix this later, if it's a relocation - currRelocations.emplace_back(linkerObj.getCurrentRelocation(), size); + currRelocations.emplace_back(linkerObj->getCurrentRelocation(), size); } zero = false; } else if (match(".int64")) { @@ -1095,9 +1110,9 @@ class S2WasmBuilder { r->data = (uint32_t*)&(*raw)[i]; } // assign the address, add to memory - linkerObj.addStatic(size, align, name); + linkerObj->addStatic(size, align, name); if (!zero) { - linkerObj.addSegment(name, (const char*)&(*raw)[0], size); + linkerObj->addSegment(name, (const char*)&(*raw)[0], size); } } @@ -1109,7 +1124,7 @@ class S2WasmBuilder { skipComma(); getInt(); } - linkerObj.addStatic(size, align, name); + linkerObj->addStatic(size, align, name); } void skipImports() { diff --git a/src/shell-interface.h b/src/shell-interface.h index daaf23501..b23b7b645 100644 --- a/src/shell-interface.h +++ b/src/shell-interface.h @@ -18,7 +18,7 @@ // Implementation of the shell interpreter execution environment // -#include "shared-constants.h" +#include "asmjs/shared-constants.h" #include "wasm.h" #include "wasm-interpreter.h" @@ -177,4 +177,3 @@ struct ShellExternalInterface : ModuleInstance::ExternalInterface { }; } - diff --git a/src/wasm-binary.h b/src/wasm-binary.h index d13e1a526..0cf85a50f 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -26,7 +26,7 @@ #include "wasm.h" #include "wasm-traversal.h" -#include "shared-constants.h" +#include "asmjs/shared-constants.h" #include "asm_v_wasm.h" #include "wasm-builder.h" #include "ast_utils.h" diff --git a/src/wasm-linker.cpp b/src/wasm-linker.cpp index 8fc4f18c8..6dca9e01b 100644 --- a/src/wasm-linker.cpp +++ b/src/wasm-linker.cpp @@ -17,6 +17,7 @@ #include "wasm-linker.h" #include "asm_v_wasm.h" #include "ast_utils.h" +#include "s2wasm.h" #include "support/utilities.h" #include "wasm-builder.h" #include "wasm-printing.h" @@ -51,7 +52,7 @@ void Linker::placeStackPointer(size_t stackAllocation) { void Linker::layout() { // Convert calls to undefined functions to call_imports - for (const auto& f : out.undefinedFunctions) { + for (const auto& f : out.undefinedFunctionCalls) { Name target = f.first; // Create an import for the target if necessary. if (!out.wasm.checkImport(target)) { @@ -145,12 +146,12 @@ void Linker::layout() { } } if (!!startFunction) { - if (out.implementedFunctions.count(startFunction) == 0) { + if (out.symbolInfo.implementedFunctions.count(startFunction) == 0) { Fatal() << "Unknown start function: `" << startFunction << "`\n"; } const auto *target = out.wasm.getFunction(startFunction); Name start("_start"); - if (out.implementedFunctions.count(start) != 0) { + if (out.symbolInfo.implementedFunctions.count(start) != 0) { Fatal() << "Start function already present: `" << start << "`\n"; } auto* func = out.wasm.allocator.alloc<Function>(); @@ -186,6 +187,35 @@ void Linker::layout() { } } +bool Linker::linkObject(S2WasmBuilder& builder) { + LinkerObject::SymbolInfo *newSymbols = builder.getSymbolInfo(); + // check for multiple definitions + for (const Name& symbol : newSymbols->implementedFunctions) { + if (out.symbolInfo.implementedFunctions.count(symbol)) { + // TODO: Figure out error handling for library-style pieces + // TODO: give LinkerObjects (or builders) names for better errors. + std::cerr << "Error: multiple definition of symbol " << symbol << "\n"; + return false; + } + } + // Allow duplicate aliases only if they refer to the same name. For now we + // do not expect aliases in compiler-rt files. + // TODO: figure out what the semantics of merging aliases should be. + for (const auto& alias : newSymbols->aliasedFunctions) { + if (out.symbolInfo.aliasedFunctions.count(alias.first) && + out.symbolInfo.aliasedFunctions[alias.first] != alias.second) { + std::cerr << "Error: conflicting definitions for alias " + << alias.first.c_str() << "\n"; + return false; + } + } + out.symbolInfo.merge(std::move(*newSymbols)); + builder.build(&out, &out.symbolInfo); + delete newSymbols; + return true; +} + + void Linker::emscriptenGlue(std::ostream& o) { if (debug) { WasmPrinter::printModule(&out.wasm, std::cerr); diff --git a/src/wasm-linker.h b/src/wasm-linker.h index e72f862f1..ab336e581 100644 --- a/src/wasm-linker.h +++ b/src/wasm-linker.h @@ -29,6 +29,8 @@ namespace wasm { +class S2WasmBuilder; + // An "object file" for linking. Contains a wasm module, plus the associated // information needed for linking/layout. class LinkerObject { @@ -44,6 +46,26 @@ class LinkerObject { Relocation(Kind kind, uint32_t* data, Name symbol, int addend) : kind(kind), data(data), symbol(symbol), addend(addend) {} }; + // Information about symbols + struct SymbolInfo { + std::unordered_set<cashew::IString> implementedFunctions; + std::unordered_set<cashew::IString> undefinedFunctions; + // TODO: it's not clear that this really belongs here. + std::unordered_map<cashew::IString, Name> aliasedFunctions; + + // For now, do not support weak symbols or anything special. Just directly + // merge the functions together, and remove any newly-defined functions + // from undefinedFunction + void merge(SymbolInfo&& other) { + for (const auto& func : other.implementedFunctions) { + undefinedFunctions.erase(func); + } + implementedFunctions.insert(other.implementedFunctions.begin(), + other.implementedFunctions.end()); + aliasedFunctions.insert(other.aliasedFunctions.begin(), + other.aliasedFunctions.end()); + } + }; LinkerObject() {} @@ -63,20 +85,15 @@ class LinkerObject { return relocations.back().get(); } - void addImplementedFunction(Name name) { - implementedFunctions.insert(name); - } + bool isFunctionImplemented(Name name) { - return implementedFunctions.count(name) != 0; + return symbolInfo.implementedFunctions.count(name) != 0; } - void addAliasedFunction(Name name, Name alias) { - aliasedFunctions.insert({name, alias}); - } // If name is an alias, return what it points to. Otherwise return name Name resolveAlias(Name name) { - auto aliased = aliasedFunctions.find(name); - if (aliased != aliasedFunctions.end()) return aliased->second; + auto aliased = symbolInfo.aliasedFunctions.find(name); + if (aliased != symbolInfo.aliasedFunctions.end()) return aliased->second; return name; } @@ -88,11 +105,12 @@ class LinkerObject { void addInitializerFunction(Name name) { initializerFunctions.emplace_back(name); - assert(implementedFunctions.count(name)); + assert(symbolInfo.implementedFunctions.count(name)); } void addUndefinedFunctionCall(Call* call) { - undefinedFunctions[call->target].push_back(call); + symbolInfo.undefinedFunctions.insert(call->target); + undefinedFunctionCalls[call->target].push_back(call); } bool isEmpty() { @@ -117,11 +135,10 @@ class LinkerObject { std::vector<StaticObject> staticObjects; std::vector<std::unique_ptr<Relocation>> relocations; - std::set<Name> implementedFunctions; - std::unordered_map<cashew::IString, Name> aliasedFunctions; + SymbolInfo symbolInfo; using CallList = std::vector<Call*>; - std::map<Name, CallList> undefinedFunctions; + std::map<Name, CallList> undefinedFunctionCalls; std::map<Name, size_t> segments; // name => segment index (in wasm module) @@ -187,6 +204,9 @@ class Linker { // metadata for asmConsts, staticBump and initializer functions. void emscriptenGlue(std::ostream& o); + // Add an object to the link by constructing it in-place with a builder. + bool linkObject(S2WasmBuilder& builder); + private: // Allocate a static variable and return its address in linear memory size_t allocateStatic(size_t allocSize, size_t alignment, Name name) { diff --git a/src/wasm-s-parser.h b/src/wasm-s-parser.h index e1a073b0b..b6a532790 100644 --- a/src/wasm-s-parser.h +++ b/src/wasm-s-parser.h @@ -27,8 +27,8 @@ #include <limits> #include "wasm.h" +#include "asmjs/shared-constants.h" #include "mixed_arena.h" -#include "shared-constants.h" #include "parsing.h" #include "asm_v_wasm.h" #include "ast_utils.h" diff --git a/src/wasm2asm.h b/src/wasm2asm.h index 1c1dba6e1..82eb0b1a9 100644 --- a/src/wasm2asm.h +++ b/src/wasm2asm.h @@ -24,11 +24,11 @@ #include <cmath> +#include "asmjs/shared-constants.h" #include "wasm.h" #include "emscripten-optimizer/optimizer.h" #include "mixed_arena.h" #include "asm_v_wasm.h" -#include "shared-constants.h" namespace wasm { |