194 lines
5.4 KiB
Diff
194 lines
5.4 KiB
Diff
diff --git a/src/s2wasm.h b/src/s2wasm.h
|
|
index 0fc0201c..c56a3a8c 100644
|
|
--- a/src/s2wasm.h
|
|
+++ b/src/s2wasm.h
|
|
@@ -153,9 +153,16 @@ class S2WasmBuilder {
|
|
|
|
Name getStr() {
|
|
std::string str; // TODO: optimize this and the other get* methods
|
|
- while (*s && !isspace(*s)) {
|
|
- str += *s;
|
|
- s++;
|
|
+ if (*s == '\"') {
|
|
+ str += *s++;
|
|
+ while (*s && *s != '\"') {
|
|
+ str += *s++;
|
|
+ }
|
|
+ if (*s == '\"') str += *s++;
|
|
+ } else {
|
|
+ while (*s && !isspace(*s)) {
|
|
+ str += *s++;
|
|
+ }
|
|
}
|
|
return cashew::IString(str.c_str(), false);
|
|
}
|
|
@@ -168,6 +175,11 @@ class S2WasmBuilder {
|
|
|
|
Name getStrToSep() {
|
|
std::string str;
|
|
+ if (*s == '\"') {
|
|
+ str += *s++;
|
|
+ while (*s && *s != '\"') str += *s++;
|
|
+ if (*s == '\"') str += *s++;
|
|
+ }
|
|
while (*s && !isspace(*s) && *s != ',' && *s != '(' && *s != ')' && *s != ':' && *s != '+' && *s != '-' && *s != '=') {
|
|
str += *s;
|
|
s++;
|
|
@@ -177,10 +189,15 @@ class S2WasmBuilder {
|
|
|
|
Name getStrToColon() {
|
|
std::string str;
|
|
- while (*s && !isspace(*s) && *s != ':') {
|
|
- str += *s;
|
|
- s++;
|
|
+ if (*s == '\"') {
|
|
+ str += *s++;
|
|
+ while (*s && *s != '\"') {
|
|
+ str += *s++;
|
|
+ }
|
|
+ if (*s == '\"') str += *s++;
|
|
}
|
|
+ while (*s && !isspace(*s) && *s != ':')
|
|
+ str += *s++;
|
|
return cashew::IString(str.c_str(), false);
|
|
}
|
|
|
|
@@ -330,9 +347,18 @@ class S2WasmBuilder {
|
|
Name getSeparated(char separator) {
|
|
skipWhitespace();
|
|
std::string str;
|
|
- while (*s && *s != separator && *s != '\n') {
|
|
- str += *s;
|
|
- s++;
|
|
+ bool inQuoted = false;
|
|
+ int inBrackets = 0;
|
|
+ while (*s && (*s != separator || inQuoted || inBrackets > 0) && *s != '\n') {
|
|
+ if (*s == '\"') {
|
|
+ inQuoted = !inQuoted;
|
|
+ } else if (*s == '(') {
|
|
+ inBrackets++;
|
|
+ } else if (*s == ')') {
|
|
+ inBrackets--;
|
|
+ }
|
|
+
|
|
+ str += *s++;
|
|
}
|
|
skipWhitespace();
|
|
return cashew::IString(str.c_str(), false);
|
|
@@ -421,14 +447,32 @@ class S2WasmBuilder {
|
|
bool isFunctionName(Name name) {
|
|
return !!strstr(name.str, "@FUNCTION");
|
|
}
|
|
- // Drop the @ and after it.
|
|
- Name cleanFunction(Name name) {
|
|
- if (!strchr(name.str, '@')) return name;
|
|
+
|
|
+ Name cleanName(Name name, char terminator = 0) {
|
|
char *temp = strdup(name.str);
|
|
- *strchr(temp, '@') = 0;
|
|
+ static const char* bads = "\";<>() ";
|
|
+ static const char* goods = "\'$__$$$";
|
|
+ int index = 0;
|
|
+ while (bads[index] != 0) {
|
|
+ char *pos = temp;
|
|
+ while ((pos = strchr(pos, bads[index])) != nullptr) {
|
|
+ *pos = goods[index];
|
|
+ pos++;
|
|
+ }
|
|
+ index++;
|
|
+ }
|
|
+ if (terminator != 0) {
|
|
+ char* pos = strrchr(temp, terminator);
|
|
+ if (pos != nullptr) *pos = '\0';
|
|
+ }
|
|
Name ret = cashew::IString(temp, false);
|
|
free(temp);
|
|
return ret;
|
|
+ }
|
|
+
|
|
+ // Drop the @ and after it.
|
|
+ Name cleanFunction(Name name) {
|
|
+ return cleanName(name, '@');
|
|
}
|
|
|
|
// processors
|
|
@@ -446,7 +490,7 @@ class S2WasmBuilder {
|
|
if (match(".hidden")) mustMatch(name.str);
|
|
mustMatch(name.str);
|
|
if (match(":")) {
|
|
- info->implementedFunctions.insert(name);
|
|
+ info->implementedFunctions.insert(cleanName(name));
|
|
} else if (match("=")) {
|
|
Name alias = getAtSeparated();
|
|
mustMatch("@FUNCTION");
|
|
@@ -461,7 +505,7 @@ class S2WasmBuilder {
|
|
s = strchr(s, '\n');
|
|
} else {
|
|
// add data aliases
|
|
- Name lhs = getStrToSep();
|
|
+ Name lhs = cleanName(getStrToSep());
|
|
// When the current line contains only one word, e.g.".text"
|
|
if (match("\n"))
|
|
continue;
|
|
@@ -473,7 +517,7 @@ class S2WasmBuilder {
|
|
}
|
|
|
|
// get the original name
|
|
- Name rhs = getStrToSep();
|
|
+ Name rhs = cleanName(getStrToSep());
|
|
assert(!isFunctionName(rhs));
|
|
Offset offset = 0;
|
|
if (*s == '+') {
|
|
@@ -620,7 +664,7 @@ class S2WasmBuilder {
|
|
}
|
|
|
|
void parseGlobl() {
|
|
- linkerObj->addGlobal(getStr());
|
|
+ linkerObj->addGlobal(cleanName(getStr()));
|
|
skipWhitespace();
|
|
}
|
|
|
|
@@ -753,7 +797,7 @@ class S2WasmBuilder {
|
|
skipWhitespace();
|
|
} else break;
|
|
}
|
|
- Function* func = builder.makeFunction(name, std::move(params), resultType, std::move(vars));
|
|
+ Function* func = builder.makeFunction(cleanName(name), std::move(params), resultType, std::move(vars));
|
|
|
|
// parse body
|
|
func->body = allocator->alloc<Block>();
|
|
@@ -1343,6 +1387,11 @@ class S2WasmBuilder {
|
|
mustMatch(name.str);
|
|
skipWhitespace();
|
|
}
|
|
+ if (match(".weak")) {
|
|
+ // Do nothing special on weak symbols so far.
|
|
+ mustMatch(name.str);
|
|
+ skipWhitespace();
|
|
+ }
|
|
if (match(".align") || match(".p2align")) {
|
|
align = getInt();
|
|
skipWhitespace();
|
|
@@ -1436,9 +1485,10 @@ class S2WasmBuilder {
|
|
r->data = (uint32_t*)&raw[i];
|
|
}
|
|
// assign the address, add to memory
|
|
- linkerObj->addStatic(size, align, name);
|
|
+ Name wasmName = cleanName(name);
|
|
+ linkerObj->addStatic(size, align, wasmName);
|
|
if (!zero) {
|
|
- linkerObj->addSegment(name, raw);
|
|
+ linkerObj->addSegment(wasmName, raw);
|
|
}
|
|
}
|
|
|
|
@@ -1451,7 +1501,7 @@ class S2WasmBuilder {
|
|
skipComma();
|
|
localAlign = 1 << getInt();
|
|
}
|
|
- linkerObj->addStatic(size, std::max(align, localAlign), name);
|
|
+ linkerObj->addStatic(size, std::max(align, localAlign), cleanName(name));
|
|
}
|
|
|
|
void skipImports() {
|