summaryrefslogtreecommitdiff
path: root/src/s2wasm.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/s2wasm.h')
-rw-r--r--src/s2wasm.h94
1 files changed, 58 insertions, 36 deletions
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;