Commit f767f8e3dc

Luuk de Gram <luuk@degram.dev>
2022-01-11 20:21:22
wasm: Place the stack at the start of memory
1 parent 48731cc
Changed files (1)
src
src/link/Wasm.zig
@@ -494,9 +494,21 @@ fn setupMemory(self: *Wasm) !void {
     log.debug("Setting up memory layout", .{});
     const page_size = 64 * 1024;
     const stack_size = self.base.options.stack_size_override orelse page_size * 1;
-    const stack_alignment = 16;
-    var memory_ptr: u64 = self.base.options.global_base orelse 1024;
-    memory_ptr = std.mem.alignForwardGeneric(u64, memory_ptr, stack_alignment);
+    const stack_alignment = 16; // wasm's stack alignment as specified by tool-convention
+    // Always place the stack at the start by default
+    // unless the user specified the global-base flag
+    var place_stack_first = true;
+    var memory_ptr: u64 = if (self.base.options.global_base) |base| blk: {
+        place_stack_first = false;
+        break :blk base;
+    } else 0;
+
+    if (place_stack_first) {
+        memory_ptr = std.mem.alignForwardGeneric(u64, memory_ptr, stack_alignment);
+        memory_ptr += stack_size;
+        // We always put the stack pointer global at index 0
+        self.globals.items[0].init.i32_const = @bitCast(i32, @intCast(u32, memory_ptr));
+    }
 
     var offset: u32 = @intCast(u32, memory_ptr);
     for (self.segments.items) |*segment, i| {
@@ -510,8 +522,11 @@ fn setupMemory(self: *Wasm) !void {
         offset += segment.size;
     }
 
-    memory_ptr = std.mem.alignForwardGeneric(u64, memory_ptr, stack_alignment);
-    memory_ptr += stack_size;
+    if (!place_stack_first) {
+        memory_ptr = std.mem.alignForwardGeneric(u64, memory_ptr, stack_alignment);
+        memory_ptr += stack_size;
+        self.globals.items[0].init.i32_const = @bitCast(i32, @intCast(u32, memory_ptr));
+    }
 
     // Setup the max amount of pages
     // For now we only support wasm32 by setting the maximum allowed memory size 2^32-1
@@ -554,9 +569,6 @@ fn setupMemory(self: *Wasm) !void {
         self.memories.limits.max = @intCast(u32, max_memory / page_size);
         log.debug("Maximum memory pages: {d}", .{self.memories.limits.max});
     }
-
-    // We always put the stack pointer global at index 0
-    self.globals.items[0].init.i32_const = @bitCast(i32, @intCast(u32, memory_ptr));
 }
 
 fn resetState(self: *Wasm) void {