diff --git a/src/s2wasm.h b/src/s2wasm.h index dd507143b67..ca6e5b7500d 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 == '+') { @@ -611,7 +655,7 @@ class S2WasmBuilder { } void parseGlobl() { - linkerObj->addGlobal(getStr()); + linkerObj->addGlobal(cleanName(getStr())); skipWhitespace(); } @@ -734,7 +778,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(); @@ -1324,6 +1368,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(); @@ -1417,9 +1466,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); } } @@ -1432,7 +1482,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() {