diff options
Diffstat (limited to 'src/s2wasm.h')
-rw-r--r-- | src/s2wasm.h | 49 |
1 files changed, 45 insertions, 4 deletions
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> |