summaryrefslogtreecommitdiff
path: root/src/s2wasm.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/s2wasm.h')
-rw-r--r--src/s2wasm.h58
1 files changed, 58 insertions, 0 deletions
diff --git a/src/s2wasm.h b/src/s2wasm.h
index c21a8b0f8..bdeb78fdd 100644
--- a/src/s2wasm.h
+++ b/src/s2wasm.h
@@ -11,6 +11,8 @@ namespace wasm {
extern int debug; // wasm::debug is set in main(), typically from an env var
+cashew::IString EMSCRIPTEN_ASM_CONST("emscripten_asm_const");
+
//
// S2WasmBuilder - parses a .s file into WebAssembly
//
@@ -43,6 +45,8 @@ private:
std::set<Name> implementedFunctions;
+ std::map<size_t, size_t> addressSegments; // address => segment index
+
// utilities
void skipWhitespace() {
@@ -815,6 +819,7 @@ private:
while (nextStatic % align) nextStatic++;
// assign the address, add to memory
staticAddresses[name] = nextStatic;
+ addressSegments[nextStatic] = wasm.memory.segments.size();
wasm.memory.segments.emplace_back(nextStatic, (const char*)&(*raw)[0], seenSize);
nextStatic += seenSize;
}
@@ -844,6 +849,59 @@ private:
(*(int32_t*)(&(*raw)[0])) = staticAddresses[name];
}
}
+
+ template<class C>
+ void printSet(std::ostream& o, C& c) {
+ o << "[";
+ bool first = true;
+ for (auto& item : c) {
+ if (first) first = false;
+ else o << ",";
+ o << '"' << item << '"';
+ }
+ o << "]";
+ }
+
+public:
+
+ // emit metadata for emscripten integration
+ void printMeta(std::ostream& o) {
+ o << "; METADATA: { ";
+ // find asmConst calls, and emit their metadata
+ struct AsmConstWalker : public WasmWalker {
+ S2WasmBuilder* parent;
+ std::ostream& o;
+
+ std::map<std::string, std::set<std::string>> sigsForCode;
+
+ AsmConstWalker(S2WasmBuilder* parent) : parent(parent), o(o) {}
+
+ void visitCallImport(CallImport* curr) override {
+ if (curr->target == EMSCRIPTEN_ASM_CONST) {
+ auto arg = curr->operands[0]->cast<Const>();
+ size_t segmentIndex = parent->addressSegments[arg->value.geti32()];
+ std::string code = parent->wasm.memory.segments[segmentIndex].data;
+ std::string sig = getSig(curr);
+ sigsForCode[code].insert(sig);
+ }
+ }
+ };
+ AsmConstWalker walker(this);
+ walker.startWalk(&wasm);
+ o << "\"asmConsts\": {";
+ bool first = true;
+ for (auto& pair : walker.sigsForCode) {
+ auto& code = pair.first;
+ auto& sigs = pair.second;
+ if (first) first = false;
+ else o << ",";
+ o << '"' << code << '"' << ":";
+ printSet(o, sigs);
+ }
+ o << "}";
+
+ o << " }";
+ }
};
} // namespace wasm