| ... | ... | @@ -404,6 +404,8 @@ pub fn flushModule(self: *Wasm, comp: *Compilation) !void { |
| 404 | 404 | // The table contains all decl's with its corresponding offset into |
| 405 | 405 | // the 'data' section |
| 406 | 406 | const offset_table_size = @intCast(u32, self.offset_table.items.len * ptr_width); |
| 407 | // The size of the emulated stack |
| 408 | const stack_size = @intCast(u32, self.base.options.stack_size_override orelse std.wasm.page_size); |
| 407 | 409 | |
| 408 | 410 | // The size of the data, this together with `offset_table_size` amounts to the |
| 409 | 411 | // total size of the 'data' section |
| ... | ... | @@ -487,7 +489,7 @@ pub fn flushModule(self: *Wasm, comp: *Compilation) !void { |
| 487 | 489 | } |
| 488 | 490 | |
| 489 | 491 | // Memory section |
| 490 | | if (data_size != 0) { |
| 492 | { |
| 491 | 493 | const header_offset = try reserveVecSectionHeader(file); |
| 492 | 494 | const writer = file.writer(); |
| 493 | 495 | |
| ... | ... | @@ -498,7 +500,7 @@ pub fn flushModule(self: *Wasm, comp: *Compilation) !void { |
| 498 | 500 | writer, |
| 499 | 501 | try std.math.divCeil( |
| 500 | 502 | u32, |
| 501 | | offset_table_size + data_size, |
| 503 | offset_table_size + data_size + stack_size, |
| 502 | 504 | std.wasm.page_size, |
| 503 | 505 | ), |
| 504 | 506 | ); |
| ... | ... | @@ -511,6 +513,34 @@ pub fn flushModule(self: *Wasm, comp: *Compilation) !void { |
| 511 | 513 | ); |
| 512 | 514 | } |
| 513 | 515 | |
| 516 | // Global section (used to emit stack pointer) |
| 517 | { |
| 518 | // We emit the emulated stack at the end of the data section, |
| 519 | // 'growing' downwards towards the program memory. |
| 520 | // TODO: Have linker resolve the offset table, so we can emit the stack |
| 521 | // at the start so we can't overwrite program memory with the stack. |
| 522 | const sp_value = offset_table_size + data_size + std.wasm.page_size; |
| 523 | const mutable = true; // stack pointer MUST be mutable |
| 524 | const header_offset = try reserveVecSectionHeader(file); |
| 525 | const writer = file.writer(); |
| 526 | |
| 527 | try writer.writeByte(wasm.valtype(.i32)); |
| 528 | try writer.writeByte(@boolToInt(mutable)); |
| 529 | |
| 530 | // set the initial value of the stack pointer to the data size + stack size |
| 531 | try writer.writeByte(wasm.opcode(.i32_const)); |
| 532 | try leb.writeILEB128(writer, @bitCast(i32, sp_value)); |
| 533 | try writer.writeByte(wasm.opcode(.end)); |
| 534 | |
| 535 | try writeVecSectionHeader( |
| 536 | file, |
| 537 | header_offset, |
| 538 | .global, |
| 539 | @intCast(u32, (try file.getPos()) - header_offset - header_size), |
| 540 | @as(u32, 1), |
| 541 | ); |
| 542 | } |
| 543 | |
| 514 | 544 | // Export section |
| 515 | 545 | if (self.base.options.module) |module| { |
| 516 | 546 | const header_offset = try reserveVecSectionHeader(file); |