diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/emscripten-optimizer/istring.h | 4 | ||||
-rw-r--r-- | src/s2wasm-main.cpp | 8 | ||||
-rw-r--r-- | src/s2wasm.h | 49 | ||||
-rw-r--r-- | src/shared-constants.h | 1 | ||||
-rw-r--r-- | src/wasm-s-parser.h | 3 | ||||
-rw-r--r-- | src/wasm.h | 8 |
6 files changed, 66 insertions, 7 deletions
diff --git a/src/emscripten-optimizer/istring.h b/src/emscripten-optimizer/istring.h index d114540e2..abc1e327b 100644 --- a/src/emscripten-optimizer/istring.h +++ b/src/emscripten-optimizer/istring.h @@ -114,8 +114,8 @@ struct IString { const char *c_str() const { return str; } bool equals(const char *other) const { return !strcmp(str, other); } - bool is() { return str != nullptr; } - bool isNull() { return str == nullptr; } + bool is() const { return str != nullptr; } + bool isNull() const { return str == nullptr; } }; } // namespace cashew diff --git a/src/s2wasm-main.cpp b/src/s2wasm-main.cpp index e75147b75..03321a608 100644 --- a/src/s2wasm-main.cpp +++ b/src/s2wasm-main.cpp @@ -28,6 +28,7 @@ using namespace wasm; int main(int argc, const char *argv[]) { bool ignoreUnknownSymbols = false; + std::string startFunction; Options options("s2wasm", "Link .s file into .wast"); options .add("--output", "-o", "Output file (stdout if not specified)", @@ -41,6 +42,11 @@ int main(int argc, const char *argv[]) { [&ignoreUnknownSymbols](Options *, const std::string &) { ignoreUnknownSymbols = true; }) + .add("--start", "", "Generate the start method (default: main)", + Options::Arguments::Optional, + [&startFunction](Options *, const std::string &argument) { + startFunction = argument.size() ? argument : "main"; + }) .add("--global-base", "-g", "Where to start to place globals", Options::Arguments::One, [](Options *o, const std::string &argument) { @@ -70,7 +76,7 @@ int main(int argc, const char *argv[]) { : 0; if (options.debug) std::cerr << "Global base " << globalBase << '\n'; S2WasmBuilder s2wasm(wasm, input.c_str(), options.debug, globalBase, - stackAllocation, ignoreUnknownSymbols); + stackAllocation, ignoreUnknownSymbols, startFunction); if (options.debug) std::cerr << "Emscripten gluing..." << std::endl; std::stringstream meta; diff --git a/src/s2wasm.h b/src/s2wasm.h index 1e0a28b43..275cf6a9c 100644 --- a/src/s2wasm.h +++ b/src/s2wasm.h @@ -39,15 +39,17 @@ class S2WasmBuilder { const char* s; bool debug; bool ignoreUnknownSymbols; + Name startFunction; public: S2WasmBuilder(AllocatingModule& wasm, const char* input, bool debug, size_t globalBase, size_t stackAllocation, - bool ignoreUnknownSymbols) + bool ignoreUnknownSymbols, Name startFunction) : wasm(wasm), allocator(wasm.allocator), debug(debug), ignoreUnknownSymbols(ignoreUnknownSymbols), + startFunction(startFunction), globalBase(globalBase), nextStatic(globalBase) { s = input; @@ -722,7 +724,7 @@ class S2WasmBuilder { Name target = cleanFunction(getCommaSeparated()); auto aliased = aliasedFunctions.find(target); if (aliased != aliasedFunctions.end()) target = aliased->second; - if (implementedFunctions.count(target) > 0) { + if (implementedFunctions.count(target) != 0) { auto specific = allocator.alloc<Call>(); specific->target = target; curr = specific; @@ -1171,13 +1173,16 @@ class S2WasmBuilder { if (functionIndexes.count(name) == 0) { functionIndexes[name] = wasm.table.names.size(); wasm.table.names.push_back(name); - if (debug) std::cerr << "function index: " << name << ": " << functionIndexes[name] << '\n'; + if (debug) { + std::cerr << "function index: " << name << ": " + << functionIndexes[name] << '\n'; + } } }; for (auto& relocation : relocations) { Name name = relocation.value; if (debug) std::cerr << "fix relocation " << name << '\n'; - const auto &symbolAddress = staticAddresses.find(name); + const auto& symbolAddress = staticAddresses.find(name); if (symbolAddress != staticAddresses.end()) { *(relocation.data) = symbolAddress->second + relocation.offset; if (debug) std::cerr << " ==> " << *(relocation.data) << '\n'; @@ -1193,6 +1198,42 @@ class S2WasmBuilder { } } } + if (!!startFunction) { + if (implementedFunctions.count(startFunction) == 0) { + std::cerr << "Unknown start function: `" << startFunction << "`\n"; + abort(); + } + const auto *target = wasm.functionsMap[startFunction]; + Name start("_start"); + if (implementedFunctions.count(start) != 0) { + std::cerr << "Start function already present: `" << start << "`\n"; + abort(); + } + auto* func = allocator.alloc<Function>(); + func->name = start; + wasm.addFunction(func); + auto* exp = allocator.alloc<Export>(); + exp->name = exp->value = start; + wasm.addExport(exp); + wasm.addStart(start); + auto* block = allocator.alloc<Block>(); + func->body = block; + { // Create the call, matching its parameters. + // TODO allow calling with non-default values. + auto* call = allocator.alloc<Call>(); + call->target = startFunction; + size_t paramNum = 0; + for (const NameType& nt : target->params) { + Name name = Name::fromInt(paramNum++); + func->locals.emplace_back(name, nt.type); + auto* param = allocator.alloc<GetLocal>(); + param->name = name; + param->type = nt.type; + call->operands.push_back(param); + } + block->list.push_back(call); + } + } } template<class C> diff --git a/src/shared-constants.h b/src/shared-constants.h index a928756da..6662c50b2 100644 --- a/src/shared-constants.h +++ b/src/shared-constants.h @@ -52,6 +52,7 @@ cashew::IString GLOBAL("global"), GROW_WASM_MEMORY("__growWasmMemory"), NEW_SIZE("newSize"), MODULE("module"), + START("start"), FUNC("func"), PARAM("param"), RESULT("result"), diff --git a/src/wasm-s-parser.h b/src/wasm-s-parser.h index 1c704ac74..e2a880e51 100644 --- a/src/wasm-s-parser.h +++ b/src/wasm-s-parser.h @@ -283,6 +283,7 @@ private: void parseModuleElement(Element& curr) { IString id = curr[0]->str(); + if (id == START) return parseStart(curr); if (id == FUNC) return parseFunction(curr); if (id == MEMORY) return parseMemory(curr); if (id == EXPORT) return parseExport(curr); @@ -304,6 +305,8 @@ private: return IString((prefix + std::to_string(otherIndex++)).c_str(), false); } + void parseStart(Element& s) { wasm.addStart(s[1]->str()); } + void parseFunction(Element& s) { auto func = currFunction = allocator.alloc<Function>(); size_t i = 1; diff --git a/src/wasm.h b/src/wasm.h index c030d9d60..b9d0d6822 100644 --- a/src/wasm.h +++ b/src/wasm.h @@ -1125,6 +1125,7 @@ public: std::map<Name, Function*> functionsMap; Table table; Memory memory; + Name start; Module() : functionTypeIndex(0), importIndex(0), exportIndex(0), functionIndex(0) {} @@ -1168,6 +1169,9 @@ public: functionsMap[numericName] = curr; functionIndex++; } + void addStart(const Name &s) { + start = s; + } void removeImport(Name name) { for (size_t i = 0; i < imports.size(); i++) { @@ -1211,6 +1215,10 @@ public: o << "\")"; } o << (module.memory.segments.size() > 0 ? "\n " : "") << ")\n"; + if (module.start.is()) { + doIndent(o, indent); + printOpening(o, "start") << " " << module.start << ")\n"; + } for (auto& curr : module.functionTypes) { doIndent(o, indent); curr->print(o, indent, true); |