summaryrefslogtreecommitdiff
path: root/src/s2wasm.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/s2wasm.h')
-rw-r--r--src/s2wasm.h72
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 << " }";
}