WIP: support stack pointer, setlocal
diff --git a/src/s2wasm.h b/src/s2wasm.h
index d14de82..4e9b009 100644
--- a/src/s2wasm.h
+++ b/src/s2wasm.h
@@ -46,6 +46,7 @@
std::unique_ptr<LinkerObject::SymbolInfo> symbolInfo;
std::unordered_map<uint32_t, uint32_t> fileIndexMap;
std::vector<Global*> globalVars;
+ int stackPointerGlobalIndex;
public:
S2WasmBuilder(const char* input, bool debug)
@@ -54,7 +55,8 @@
debug(debug),
wasm(nullptr),
allocator(nullptr),
- linkerObj(nullptr)
+ linkerObj(nullptr),
+ stackPointerGlobalIndex(-1)
{}
void build(LinkerObject *obj) {
@@ -65,8 +67,16 @@
wasm = &obj->wasm;
allocator = &wasm->allocator;
for (auto global : globalVars) {
+ auto c = allocator->alloc<Const>();
+ c->type = i32;
+ c->value = Literal(0);
+ global->init = c;
wasm->addGlobal(global);
}
+ if (stackPointerGlobalIndex != -1) {
+ auto g = globalVars[stackPointerGlobalIndex];
+ obj->stackPointerGlobalName = g->name;
+ }
s = inputStart;
process();
@@ -474,6 +484,9 @@
global->type = type;
global->mutable_ = true;
globalVars.push_back(global);
+ } else if (match(".stack_pointer")) {
+ assert(stackPointerGlobalIndex == -1);
+ stackPointerGlobalIndex = getInt();
} else {
// add data aliases
Name lhs = getStrToSep();
@@ -1272,9 +1285,16 @@
Name assign = getAssign();
skipComma();
auto curr = allocator->alloc<GetLocal>();
- curr->index = getInt();
- curr->type = i32;
+ int index = getInt();
+ curr->index = index;
+ curr->type = func->getLocalType(index);
setOutput(curr, assign);
+ } else if (match("set_local")) {
+ auto curr = allocator->alloc<SetLocal>();
+ curr->index = getInt();
+ skipComma();
+ curr->value = getInput();
+ addToBlock(curr);
} else if (match("get_global")) {
Name assign = getAssign();
skipComma();
diff --git a/src/tools/s2wasm.cpp b/src/tools/s2wasm.cpp
index a357834..1797a8b 100644
--- a/src/tools/s2wasm.cpp
+++ b/src/tools/s2wasm.cpp
@@ -155,6 +155,7 @@
if (generateEmscriptenGlue) {
emscripten::generateRuntimeFunctions(linker.getOutput());
}
+ emscripten::generateStackRestoreFunction(linker.getOutput());
linker.layout();
diff --git a/src/wasm-emscripten.cpp b/src/wasm-emscripten.cpp
index 43366e4..91df5e7 100644
--- a/src/wasm-emscripten.cpp
+++ b/src/wasm-emscripten.cpp
@@ -65,32 +65,40 @@
));
}
-Load* generateLoadStackPointer(Builder& builder, LinkerObject& linker) {
- Load* load = builder.makeLoad(
- /* bytes =*/ 4,
- /* signed =*/ false,
- /* offset =*/ 0,
- /* align =*/ 4,
- /* ptr =*/ builder.makeConst(Literal(0)),
- /* type =*/ i32
- );
- addStackPointerRelocation(linker, &load->offset.addr);
- return load;
+Expression* generateLoadStackPointer(Builder& builder, LinkerObject& linker) {
+ if (linker.stackPointerGlobalName.str) {
+ return builder.makeGetGlobal(linker.stackPointerGlobalName, i32);
+ } else {
+ Load* load = builder.makeLoad(
+ /* bytes =*/ 4,
+ /* signed =*/ false,
+ /* offset =*/ 0,
+ /* align =*/ 4,
+ /* ptr =*/ builder.makeConst(Literal(0)),
+ /* type =*/ i32
+ );
+ addStackPointerRelocation(linker, &load->offset.addr);
+ return load;
+ }
}
-Store* generateStoreStackPointer(Builder& builder,
- LinkerObject& linker,
- Expression* value) {
- Store* store = builder.makeStore(
- /* bytes =*/ 4,
- /* offset =*/ 0,
- /* align =*/ 4,
- /* ptr =*/ builder.makeConst(Literal(0)),
- /* value =*/ value,
- /* type =*/ i32
- );
- addStackPointerRelocation(linker, &store->offset.addr);
- return store;
+Expression* generateStoreStackPointer(Builder& builder,
+ LinkerObject& linker,
+ Expression* value) {
+ if (linker.stackPointerGlobalName.str) {
+ return builder.makeSetGlobal(linker.stackPointerGlobalName, value);
+ } else {
+ Store* store = builder.makeStore(
+ /* bytes =*/ 4,
+ /* offset =*/ 0,
+ /* align =*/ 4,
+ /* ptr =*/ builder.makeConst(Literal(0)),
+ /* value =*/ value,
+ /* type =*/ i32
+ );
+ addStackPointerRelocation(linker, &store->offset.addr);
+ return store;
+ }
}
void generateStackSaveFunction(LinkerObject& linker) {
@@ -115,7 +123,7 @@
Function* function = builder.makeFunction(
name, std::move(params), i32, { { "1", i32 } }
);
- Load* loadStack = generateLoadStackPointer(builder, linker);
+ Expression* loadStack = generateLoadStackPointer(builder, linker);
SetLocal* setStackLocal = builder.makeSetLocal(1, loadStack);
GetLocal* getStackLocal = builder.makeGetLocal(1, i32);
GetLocal* getSizeArg = builder.makeGetLocal(0, i32);
@@ -128,7 +136,7 @@
builder.makeBinary(AddInt32, add, addConst),
builder.makeConst(Literal(~bitMask))
);
- Store* storeStack = generateStoreStackPointer(builder, linker, maskedAdd);
+ Expression* storeStack = generateStoreStackPointer(builder, linker, maskedAdd);
Block* block = builder.makeBlock();
block->list.push_back(setStackLocal);
@@ -149,7 +157,7 @@
name, std::move(params), none, {}
);
GetLocal* getArg = builder.makeGetLocal(0, i32);
- Store* store = generateStoreStackPointer(builder, linker, getArg);
+ Expression* store = generateStoreStackPointer(builder, linker, getArg);
function->body = store;
@@ -159,7 +167,6 @@
void generateRuntimeFunctions(LinkerObject& linker) {
generateStackSaveFunction(linker);
generateStackAllocFunction(linker);
- generateStackRestoreFunction(linker);
}
static bool hasI64ResultOrParam(FunctionType* ft) {
diff --git a/src/wasm-emscripten.h b/src/wasm-emscripten.h
index 7400a8b..b7f4159 100644
--- a/src/wasm-emscripten.h
+++ b/src/wasm-emscripten.h
@@ -27,6 +27,7 @@
void generateRuntimeFunctions(LinkerObject& linker);
void generateMemoryGrowthFunction(Module&);
+void generateStackRestoreFunction(LinkerObject& linker);
// Create thunks for use with emscripten Runtime.dynCall. Creates one for each
// signature in the indirect function table.
diff --git a/src/wasm-linker.h b/src/wasm-linker.h
index 2129f4f..d74f308 100644
--- a/src/wasm-linker.h
+++ b/src/wasm-linker.h
@@ -159,6 +159,7 @@
friend class Linker;
Module wasm;
+ Name stackPointerGlobalName;
private:
struct StaticObject {