diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/passes/RemoveImports.cpp | 2 | ||||
-rw-r--r-- | src/s2wasm.h | 94 |
2 files changed, 59 insertions, 37 deletions
diff --git a/src/passes/RemoveImports.cpp b/src/passes/RemoveImports.cpp index 06865a8f9..561002f57 100644 --- a/src/passes/RemoveImports.cpp +++ b/src/passes/RemoveImports.cpp @@ -31,7 +31,7 @@ struct RemoveImports : public Pass { } } - void visitModule(Module *curr) { + void visitModule(Module *curr) override { curr->importsMap.clear(); curr->imports.clear(); } diff --git a/src/s2wasm.h b/src/s2wasm.h index 3a8dd7ddb..449b6f56c 100644 --- a/src/s2wasm.h +++ b/src/s2wasm.h @@ -41,10 +41,10 @@ private: std::vector<Addressing> addressings; // we fix these up struct Relocation { - std::vector<char>* data; + uint32_t* data; Name value; int offset; - Relocation(std::vector<char>* data, Name value, int offset) : data(data), value(value), offset(offset) {} + Relocation(uint32_t* data, Name value, int offset) : data(data), value(value), offset(offset) {} }; std::vector<Relocation> relocations; @@ -117,14 +117,14 @@ private: } void skipToSep() { - while (*s && !isspace(*s) && *s != ',' && *s != ')' && *s != ':' && *s != '+') { + while (*s && !isspace(*s) && *s != ',' && *s != '(' && *s != ')' && *s != ':' && *s != '+') { s++; } } Name getStrToSep() { std::string str; - while (*s && !isspace(*s) && *s != ',' && *s != ')' && *s != ':' && *s != '+') { + while (*s && !isspace(*s) && *s != ',' && *s != '(' && *s != ')' && *s != ':' && *s != '+') { str += *s; s++; } @@ -156,6 +156,21 @@ private: return ret; } + void getConst(uint32_t* target) { + if (isdigit(*s)) { + *target = getInt(); + } else { + // a global constant, we need to fix it up later + Name name = getStrToSep(); + int offset = 0; + if (*s == '+') { + s++; + offset = getInt(); + } + relocations.emplace_back(target, name, offset); + } + } + int64_t getInt64() { int64_t ret = 0; bool neg = false; @@ -267,6 +282,8 @@ private: else if (match("type")) parseType(); else if (match("imports")) skipImports(); else if (match("data")) {} + else if (match("ident")) {} + else if (match("section")) s = strchr(s, '\n'); else abort_on("process"); } } @@ -451,7 +468,7 @@ private: curr->signed_ = match("_s"); match("_u"); Name assign = getAssign(); - curr->offset = getInt(); + getConst(&curr->offset); curr->align = curr->bytes; // XXX mustMatch("("); curr->ptr = getInput(); @@ -465,7 +482,7 @@ private: curr->bytes = bytes > 0 ? bytes : getWasmTypeSize(type); curr->align = curr->bytes; // XXX Name assign = getAssign(); - curr->offset = getInt(); + getConst(&curr->offset); mustMatch("("); auto inputs = getInputs(2); curr->ptr = inputs[0]; @@ -811,7 +828,13 @@ private: } void parseObject(Name name) { - match(".data"); + if (match(".data") || match(".bss")) { + } else if (match(".lcomm")) { + mustMatch(name.str); + skipComma(); + getInt(); + return; + } size_t align = 16; // XXX default? if (match(".globl")) { mustMatch(name.str); @@ -832,36 +855,35 @@ private: mustMatch(name.str); mustMatch(":"); auto raw = new std::vector<char>(); // leaked intentionally, no new allocation in Memory - bool zero = false; - if (match(".asciz")) { - *raw = getQuoted(); - raw->push_back(0); - } else if (match(".ascii")) { - *raw = getQuoted(); - } else if (match(".zero")) { - zero = true; - int32_t size = getInt(); - for (size_t i = 0; i < size; i++) { + bool zero = true; + while (1) { + skipWhitespace(); + if (match(".asciz")) { + *raw = getQuoted(); raw->push_back(0); - } - } else if (match(".int32")) { - raw->resize(4); - if (isdigit(*s)) { - (*(int32_t*)(&(*raw)[0])) = getInt(); + zero = false; + } else if (match(".ascii")) { + *raw = getQuoted(); + zero = false; + } else if (match(".zero")) { + int32_t size = getInt(); + for (size_t i = 0; i < size; i++) { + raw->push_back(0); + } + } else if (match(".int32")) { + size_t size = raw->size(); + raw->resize(size + 4); + getConst((uint32_t*)&(*raw)[size]); + zero = false; + } else if (match(".int64")) { + size_t size = raw->size(); + raw->resize(size + 8); + (*(int64_t*)(&(*raw)[size])) = getInt(); + zero = false; } else { - // relocation, the address of something - Name value = getStrToSep(); - int offset = 0; - if (*s == '+') { - s++; - offset = getInt(); - } - relocations.emplace_back(raw, value, offset); + break; } - } else if (match(".int64")) { - raw->resize(8); - (*(int64_t*)(&(*raw)[0])) = getInt(); - } else abort_on("data form"); + } skipWhitespace(); size_t size = raw->size(); if (match(".size")) { @@ -900,7 +922,7 @@ private: curr->type = i32; } for (auto& relocation : relocations) { - (*(int32_t*)(&(*relocation.data)[0])) = staticAddresses[relocation.value] + relocation.offset; + *(relocation.data) = staticAddresses[relocation.value] + relocation.offset; } } @@ -922,7 +944,7 @@ public: void emscriptenGlue(std::ostream& o) { wasm.removeImport(EMSCRIPTEN_ASM_CONST); // we create _sig versions - o << "; METADATA: { "; + o << ";; METADATA: { "; // find asmConst calls, and emit their metadata struct AsmConstWalker : public WasmWalker { S2WasmBuilder* parent; |