summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/wasm-emscripten.cpp96
1 files changed, 61 insertions, 35 deletions
diff --git a/src/wasm-emscripten.cpp b/src/wasm-emscripten.cpp
index 143ab2ad8..9594b5047 100644
--- a/src/wasm-emscripten.cpp
+++ b/src/wasm-emscripten.cpp
@@ -111,54 +111,44 @@ struct AsmConstWalker : public PostWalker<AsmConstWalker> {
void visitCallImport(CallImport* curr);
+private:
+ std::string codeForConstAddr(Const* addrConst);
+ Literal idLiteralForCode(std::string code);
+ std::string asmConstSig(std::string baseSig);
+ Name nameForImportWithSig(std::string sig);
+ void addImport(Name importName, std::string baseSig);
std::string escape(const char *input);
};
void AsmConstWalker::visitCallImport(CallImport* curr) {
if (curr->target.hasSubstring(EMSCRIPTEN_ASM_CONST)) {
auto arg = curr->operands[0]->cast<Const>();
- auto address = arg->value.geti32();
- auto segmentIterator = segmentsByAddress.find(address);
- std::string code;
- if (segmentIterator != segmentsByAddress.end()) {
- Address segmentIndex = segmentsByAddress[address];
- code = escape(&wasm.memory.segments[segmentIndex].data[0]);
- } else {
- // If we can't find the segment corresponding with the address, then we omitted the segment and the address points to an empty string.
- code = escape("");
- }
- int32_t id;
- if (ids.count(code) == 0) {
- id = ids.size();
- ids[code] = id;
- } else {
- id = ids[code];
- }
- std::string baseSig = getSig(curr);
- std::string sig = "";
- for (size_t i = 0; i < baseSig.size(); ++i) {
- // Omit the signature of the "code" parameter, taken as a string, as the first argument
- if (i != 1) {
- sig += baseSig[i];
- }
- }
+ auto code = codeForConstAddr(arg);
+ arg->value = idLiteralForCode(code);
+ auto baseSig = getSig(curr);
+ auto sig = asmConstSig(baseSig);
sigsForCode[code].insert(sig);
- std::string fixedTarget = EMSCRIPTEN_ASM_CONST.str + std::string("_") + sig;
- curr->target = cashew::IString(fixedTarget.c_str(), false);
- arg->value = Literal(id);
- // add import, if necessary
+ auto importName = nameForImportWithSig(sig);
+ curr->target = importName;
+
if (allSigs.count(sig) == 0) {
allSigs.insert(sig);
- auto import = new Import;
- import->name = import->base = curr->target;
- import->module = ENV;
- import->functionType = ensureFunctionType(getSig(curr), &wasm)->name;
- import->kind = ExternalKind::Function;
- wasm.addImport(import);
+ addImport(importName, baseSig);
}
}
}
+std::string AsmConstWalker::codeForConstAddr(Const* addrConst) {
+ auto address = addrConst->value.geti32();
+ auto segmentIterator = segmentsByAddress.find(address);
+ if (segmentIterator == segmentsByAddress.end()) {
+ // If we can't find the segment corresponding with the address, then we omitted the segment and the address points to an empty string.
+ return escape("");
+ }
+ Address segmentIndex = segmentsByAddress[address];
+ return escape(&wasm.memory.segments[segmentIndex].data[0]);
+}
+
std::string AsmConstWalker::escape(const char *input) {
std::string code = input;
// replace newlines quotes with escaped newlines
@@ -181,6 +171,42 @@ std::string AsmConstWalker::escape(const char *input) {
return code;
}
+Literal AsmConstWalker::idLiteralForCode(std::string code) {
+ int32_t id;
+ if (ids.count(code) == 0) {
+ id = ids.size();
+ ids[code] = id;
+ } else {
+ id = ids[code];
+ }
+ return Literal(id);
+}
+
+std::string AsmConstWalker::asmConstSig(std::string baseSig) {
+ std::string sig = "";
+ for (size_t i = 0; i < baseSig.size(); ++i) {
+ // Omit the signature of the "code" parameter, taken as a string, as the first argument
+ if (i != 1) {
+ sig += baseSig[i];
+ }
+ }
+ return sig;
+}
+
+Name AsmConstWalker::nameForImportWithSig(std::string sig) {
+ std::string fixedTarget = EMSCRIPTEN_ASM_CONST.str + std::string("_") + sig;
+ return Name(fixedTarget.c_str());
+}
+
+void AsmConstWalker::addImport(Name importName, std::string baseSig) {
+ auto import = new Import;
+ import->name = import->base = importName;
+ import->module = ENV;
+ import->functionType = ensureFunctionType(baseSig, &wasm)->name;
+ import->kind = ExternalKind::Function;
+ wasm.addImport(import);
+}
+
template<class C>
void printSet(std::ostream& o, C& c) {
o << "[";