diff options
Diffstat (limited to 'src/s2wasm.h')
-rw-r--r-- | src/s2wasm.h | 72 |
1 files changed, 54 insertions, 18 deletions
diff --git a/src/s2wasm.h b/src/s2wasm.h index 02fc37cfe..74387859e 100644 --- a/src/s2wasm.h +++ b/src/s2wasm.h @@ -40,8 +40,8 @@ class S2WasmBuilder { bool debug; public: - S2WasmBuilder(AllocatingModule& wasm, const char* input, bool debug) - : wasm(wasm), allocator(wasm.allocator), debug(debug) { + S2WasmBuilder(AllocatingModule& wasm, const char* input, bool debug, size_t globalBase) + : wasm(wasm), allocator(wasm.allocator), debug(debug), globalBase(globalBase), nextStatic(globalBase) { s = input; scan(); s = input; @@ -52,10 +52,16 @@ public: private: // state - size_t nextStatic = 1; // location of next static allocation, i.e., the data segment + size_t globalBase, // where globals can start to be statically allocated, i.e., the data segment + nextStatic; // location of next static allocation std::map<Name, int32_t> staticAddresses; // name => address - typedef std::pair<Const*, Name> Addressing; + struct Addressing { + Const* value; + Name name; + int32_t offset; + Addressing(Const* value, Name name, int32_t offset) : value(value), name(name), offset(offset) {} + }; std::vector<Addressing> addressings; // we fix these up struct Relocation { @@ -70,6 +76,8 @@ private: std::map<size_t, size_t> addressSegments; // address => segment index + std::map<Name, size_t> functionIndexes; + // utilities void skipWhitespace() { @@ -588,12 +596,14 @@ private: if (match("const")) { Name assign = getAssign(); char start = *s; - cashew::IString str = getStr(); - if (start == '.' || (isalpha(start) && str != NAN_ && str != INFINITY_)) { + cashew::IString str = getStrToSep(); + if (start == '.' || (isalpha(start) && str != NAN__ && str != INFINITY__)) { // global address + int32_t offset = 0; + if (match("+")) offset = getInt(); auto curr = allocator.alloc<Const>(); curr->type = i32; - addressings.emplace_back(curr, str); + addressings.emplace_back(curr, str, offset); setOutput(curr, assign); } else { // constant @@ -881,12 +891,17 @@ private: bool zero = true; while (1) { skipWhitespace(); - if (match(".asciz")) { - *raw = getQuoted(); - raw->push_back(0); - zero = false; - } else if (match(".ascii")) { - *raw = getQuoted(); + if (match(".asci")) { + bool z; + if (match("i")) { + z = false; + } else { + mustMatch("z"); + z = true; + } + auto quoted = getQuoted(); + raw->insert(raw->end(), quoted.begin(), quoted.end()); + if (z) raw->push_back(0); zero = false; } else if (match(".zero")) { int32_t size = getInt(); @@ -926,7 +941,11 @@ private: mustMatch(name.str); mustMatch(","); size_t seenSize = atoi(getStr().str); // TODO: optimize - assert(seenSize == size); + assert(seenSize >= size); + while (raw->size() < seenSize) { + raw->push_back(0); + } + size = seenSize; } while (nextStatic % align) nextStatic++; // assign the address, add to memory @@ -950,10 +969,25 @@ private: } void fix() { - for (auto& pair : addressings) { - Const* curr = pair.first; - Name name = pair.second; - curr->value = Literal(staticAddresses[name]); + for (auto& triple : addressings) { + Const* curr = triple.value; + Name name = triple.name; + size_t offset = triple.offset; + const auto &symbolAddress = staticAddresses.find(name); + if (symbolAddress != staticAddresses.end()) { + curr->value = Literal(symbolAddress->second + offset); + } else { + // must be a function address + if (wasm.functionsMap.count(name) == 0) { + std::cerr << "Unknown symbol: " << name << '\n'; + abort_on("Unknown symbol"); + } + if (functionIndexes.count(name) == 0) { + functionIndexes[name] = functionIndexes.size(); + wasm.table.names.push_back(name); + } + curr->value = Literal(functionIndexes[name] + offset); + } assert(curr->value.i32 > 0); curr->type = i32; } @@ -1056,6 +1090,8 @@ public: o << "]"; } o << "}"; + o << ","; + o << "\"staticBump\": " << (nextStatic - globalBase); o << " }"; } |