| ... | @@ -14,6 +14,7 @@ const Atom = @import("Wasm/Atom.zig"); | ... | @@ -14,6 +14,7 @@ const Atom = @import("Wasm/Atom.zig"); |
| 14 | const Module = @import("../Module.zig"); | 14 | const Module = @import("../Module.zig"); |
| 15 | const Compilation = @import("../Compilation.zig"); | 15 | const Compilation = @import("../Compilation.zig"); |
| 16 | const CodeGen = @import("../arch/wasm/CodeGen.zig"); | 16 | const CodeGen = @import("../arch/wasm/CodeGen.zig"); |
| | 17 | const codegen = @import("../codegen.zig"); |
| 17 | const link = @import("../link.zig"); | 18 | const link = @import("../link.zig"); |
| 18 | const lldMain = @import("../main.zig").lldMain; | 19 | const lldMain = @import("../main.zig").lldMain; |
| 19 | const trace = @import("../tracy.zig").trace; | 20 | const trace = @import("../tracy.zig").trace; |
| ... | @@ -488,10 +489,8 @@ pub fn allocateDeclIndexes(self: *Wasm, decl: *Module.Decl) !void { | ... | @@ -488,10 +489,8 @@ pub fn allocateDeclIndexes(self: *Wasm, decl: *Module.Decl) !void { |
| 488 | self.symbols.appendAssumeCapacity(symbol); | 489 | self.symbols.appendAssumeCapacity(symbol); |
| 489 | } | 490 | } |
| 490 | | 491 | |
| 491 | try self.resolved_symbols.putNoClobber(self.base.allocator, .{ | 492 | try self.resolved_symbols.putNoClobber(self.base.allocator, atom.symbolLoc(), {}); |
| 492 | .index = atom.sym_index, | 493 | try self.symbol_atom.putNoClobber(self.base.allocator, atom.symbolLoc(), atom); |
| 493 | .file = null, | | |
| 494 | }, {}); | | |
| 495 | } | 494 | } |
| 496 | | 495 | |
| 497 | pub fn updateFunc(self: *Wasm, module: *Module, func: *Module.Fn, air: Air, liveness: Liveness) !void { | 496 | pub fn updateFunc(self: *Wasm, module: *Module, func: *Module.Fn, air: Air, liveness: Liveness) !void { |
| ... | @@ -506,7 +505,7 @@ pub fn updateFunc(self: *Wasm, module: *Module, func: *Module.Fn, air: Air, live | ... | @@ -506,7 +505,7 @@ pub fn updateFunc(self: *Wasm, module: *Module, func: *Module.Fn, air: Air, live |
| 506 | | 505 | |
| 507 | decl.link.wasm.clear(); | 506 | decl.link.wasm.clear(); |
| 508 | | 507 | |
| 509 | var codegen: CodeGen = .{ | 508 | var codegen_: CodeGen = .{ |
| 510 | .gpa = self.base.allocator, | 509 | .gpa = self.base.allocator, |
| 511 | .air = air, | 510 | .air = air, |
| 512 | .liveness = liveness, | 511 | .liveness = liveness, |
| ... | @@ -519,18 +518,18 @@ pub fn updateFunc(self: *Wasm, module: *Module, func: *Module.Fn, air: Air, live | ... | @@ -519,18 +518,18 @@ pub fn updateFunc(self: *Wasm, module: *Module, func: *Module.Fn, air: Air, live |
| 519 | .bin_file = self, | 518 | .bin_file = self, |
| 520 | .module = module, | 519 | .module = module, |
| 521 | }; | 520 | }; |
| 522 | defer codegen.deinit(); | 521 | defer codegen_.deinit(); |
| 523 | | 522 | |
| 524 | // generate the 'code' section for the function declaration | 523 | // generate the 'code' section for the function declaration |
| 525 | codegen.genFunc() catch |err| switch (err) { | 524 | codegen_.genFunc() catch |err| switch (err) { |
| 526 | error.CodegenFail => { | 525 | error.CodegenFail => { |
| 527 | decl.analysis = .codegen_failure; | 526 | decl.analysis = .codegen_failure; |
| 528 | try module.failed_decls.put(module.gpa, decl, codegen.err_msg); | 527 | try module.failed_decls.put(module.gpa, decl, codegen_.err_msg); |
| 529 | return; | 528 | return; |
| 530 | }, | 529 | }, |
| 531 | else => |e| return e, | 530 | else => |e| return e, |
| 532 | }; | 531 | }; |
| 533 | return self.finishUpdateDecl(decl, codegen.code.items); | 532 | return self.finishUpdateDecl(decl, codegen_.code.items); |
| 534 | } | 533 | } |
| 535 | | 534 | |
| 536 | // Generate code for the Decl, storing it in memory to be later written to | 535 | // Generate code for the Decl, storing it in memory to be later written to |
| ... | @@ -547,31 +546,37 @@ pub fn updateDecl(self: *Wasm, module: *Module, decl: *Module.Decl) !void { | ... | @@ -547,31 +546,37 @@ pub fn updateDecl(self: *Wasm, module: *Module, decl: *Module.Decl) !void { |
| 547 | | 546 | |
| 548 | decl.link.wasm.clear(); | 547 | decl.link.wasm.clear(); |
| 549 | | 548 | |
| | 549 | if (decl.isExtern()) { |
| | 550 | return self.addOrUpdateImport(decl); |
| | 551 | } |
| | 552 | |
| | 553 | if (decl.val.castTag(.function)) |_| { |
| | 554 | return; |
| | 555 | } else if (decl.val.castTag(.extern_fn)) |_| { |
| | 556 | return; |
| | 557 | } |
| | 558 | const val = if (decl.val.castTag(.variable)) |payload| payload.data.init else decl.val; |
| | 559 | |
| 550 | var code_writer = std.ArrayList(u8).init(self.base.allocator); | 560 | var code_writer = std.ArrayList(u8).init(self.base.allocator); |
| 551 | defer code_writer.deinit(); | 561 | defer code_writer.deinit(); |
| 552 | var decl_gen: CodeGen.DeclGen = .{ | | |
| 553 | .gpa = self.base.allocator, | | |
| 554 | .decl = decl, | | |
| 555 | .symbol_index = decl.link.wasm.sym_index, | | |
| 556 | .bin_file = self, | | |
| 557 | .err_msg = undefined, | | |
| 558 | .code = &code_writer, | | |
| 559 | .module = module, | | |
| 560 | }; | | |
| 561 | | 562 | |
| 562 | // generate the 'code' section for the function declaration | 563 | const res = try codegen.generateSymbol( |
| 563 | const result = decl_gen.genDecl() catch |err| switch (err) { | 564 | &self.base, |
| 564 | error.CodegenFail => { | 565 | decl.srcLoc(), |
| | 566 | .{ .ty = decl.ty, .val = val }, |
| | 567 | &code_writer, |
| | 568 | .none, |
| | 569 | .{ .parent_atom_index = decl.link.wasm.sym_index }, |
| | 570 | ); |
| | 571 | |
| | 572 | const code = switch (res) { |
| | 573 | .externally_managed => |x| x, |
| | 574 | .appended => code_writer.items, |
| | 575 | .fail => |em| { |
| 565 | decl.analysis = .codegen_failure; | 576 | decl.analysis = .codegen_failure; |
| 566 | try module.failed_decls.put(module.gpa, decl, decl_gen.err_msg); | 577 | try module.failed_decls.put(module.gpa, decl, em); |
| 567 | return; | 578 | return; |
| 568 | }, | 579 | }, |
| 569 | else => |e| return e, | | |
| 570 | }; | | |
| 571 | | | |
| 572 | const code = switch (result) { | | |
| 573 | .externally_managed => |data| data, | | |
| 574 | .appended => code_writer.items, | | |
| 575 | }; | 580 | }; |
| 576 | | 581 | |
| 577 | return self.finishUpdateDecl(decl, code); | 582 | return self.finishUpdateDecl(decl, code); |
| ... | @@ -624,10 +629,8 @@ pub fn lowerUnnamedConst(self: *Wasm, decl: *Module.Decl, tv: TypedValue) !u32 { | ... | @@ -624,10 +629,8 @@ pub fn lowerUnnamedConst(self: *Wasm, decl: *Module.Decl, tv: TypedValue) !u32 { |
| 624 | atom.sym_index = @intCast(u32, self.symbols.items.len); | 629 | atom.sym_index = @intCast(u32, self.symbols.items.len); |
| 625 | self.symbols.appendAssumeCapacity(symbol); | 630 | self.symbols.appendAssumeCapacity(symbol); |
| 626 | } | 631 | } |
| 627 | try self.resolved_symbols.putNoClobber(self.base.allocator, .{ | 632 | try self.resolved_symbols.putNoClobber(self.base.allocator, atom.symbolLoc(), {}); |
| 628 | .file = null, | 633 | try self.symbol_atom.putNoClobber(self.base.allocator, atom.symbolLoc(), atom); |
| 629 | .index = atom.sym_index, | | |
| 630 | }, {}); | | |
| 631 | | 634 | |
| 632 | var value_bytes = std.ArrayList(u8).init(self.base.allocator); | 635 | var value_bytes = std.ArrayList(u8).init(self.base.allocator); |
| 633 | defer value_bytes.deinit(); | 636 | defer value_bytes.deinit(); |
| ... | @@ -665,35 +668,31 @@ pub fn lowerUnnamedConst(self: *Wasm, decl: *Module.Decl, tv: TypedValue) !u32 { | ... | @@ -665,35 +668,31 @@ pub fn lowerUnnamedConst(self: *Wasm, decl: *Module.Decl, tv: TypedValue) !u32 { |
| 665 | /// Returns the given pointer address | 668 | /// Returns the given pointer address |
| 666 | pub fn getDeclVAddr( | 669 | pub fn getDeclVAddr( |
| 667 | self: *Wasm, | 670 | self: *Wasm, |
| 668 | decl: *Module.Decl, | 671 | decl: *const Module.Decl, |
| 669 | symbol_index: u32, | 672 | reloc_info: link.File.RelocInfo, |
| 670 | target_decl: *Module.Decl, | 673 | ) !u64 { |
| 671 | offset: u32, | 674 | const target_symbol_index = decl.link.wasm.sym_index; |
| 672 | addend: u32, | | |
| 673 | ) !u32 { | | |
| 674 | const target_symbol_index = target_decl.link.wasm.sym_index; | | |
| 675 | assert(target_symbol_index != 0); | 675 | assert(target_symbol_index != 0); |
| 676 | assert(symbol_index != 0); | 676 | assert(reloc_info.parent_atom_index != 0); |
| 677 | | 677 | const atom = self.symbol_atom.get(.{ .file = null, .index = reloc_info.parent_atom_index }).?; |
| 678 | const atom = decl.link.wasm.symbolAtom(symbol_index); | | |
| 679 | const is_wasm32 = self.base.options.target.cpu.arch == .wasm32; | 678 | const is_wasm32 = self.base.options.target.cpu.arch == .wasm32; |
| 680 | if (target_decl.ty.zigTypeTag() == .Fn) { | 679 | if (decl.ty.zigTypeTag() == .Fn) { |
| 681 | assert(addend == 0); // addend not allowed for function relocations | 680 | assert(reloc_info.addend == 0); // addend not allowed for function relocations |
| 682 | // We found a function pointer, so add it to our table, | 681 | // We found a function pointer, so add it to our table, |
| 683 | // as function pointers are not allowed to be stored inside the data section. | 682 | // as function pointers are not allowed to be stored inside the data section. |
| 684 | // They are instead stored in a function table which are called by index. | 683 | // They are instead stored in a function table which are called by index. |
| 685 | try self.addTableFunction(target_symbol_index); | 684 | try self.addTableFunction(target_symbol_index); |
| 686 | try atom.relocs.append(self.base.allocator, .{ | 685 | try atom.relocs.append(self.base.allocator, .{ |
| 687 | .index = target_symbol_index, | 686 | .index = target_symbol_index, |
| 688 | .offset = offset, | 687 | .offset = @intCast(u32, reloc_info.offset), |
| 689 | .relocation_type = if (is_wasm32) .R_WASM_TABLE_INDEX_I32 else .R_WASM_TABLE_INDEX_I64, | 688 | .relocation_type = if (is_wasm32) .R_WASM_TABLE_INDEX_I32 else .R_WASM_TABLE_INDEX_I64, |
| 690 | }); | 689 | }); |
| 691 | } else { | 690 | } else { |
| 692 | try atom.relocs.append(self.base.allocator, .{ | 691 | try atom.relocs.append(self.base.allocator, .{ |
| 693 | .index = target_symbol_index, | 692 | .index = target_symbol_index, |
| 694 | .offset = offset, | 693 | .offset = @intCast(u32, reloc_info.offset), |
| 695 | .relocation_type = if (is_wasm32) .R_WASM_MEMORY_ADDR_I32 else .R_WASM_MEMORY_ADDR_I64, | 694 | .relocation_type = if (is_wasm32) .R_WASM_MEMORY_ADDR_I32 else .R_WASM_MEMORY_ADDR_I64, |
| 696 | .addend = addend, | 695 | .addend = reloc_info.addend, |
| 697 | }); | 696 | }); |
| 698 | } | 697 | } |
| 699 | // we do not know the final address at this point, | 698 | // we do not know the final address at this point, |
| ... | @@ -823,12 +822,14 @@ pub fn freeDecl(self: *Wasm, decl: *Module.Decl) void { | ... | @@ -823,12 +822,14 @@ pub fn freeDecl(self: *Wasm, decl: *Module.Decl) void { |
| 823 | local_symbol.tag = .dead; // also for any local symbol | 822 | local_symbol.tag = .dead; // also for any local symbol |
| 824 | self.symbols_free_list.append(self.base.allocator, local_atom.sym_index) catch {}; | 823 | self.symbols_free_list.append(self.base.allocator, local_atom.sym_index) catch {}; |
| 825 | assert(self.resolved_symbols.swapRemove(local_atom.symbolLoc())); | 824 | assert(self.resolved_symbols.swapRemove(local_atom.symbolLoc())); |
| | 825 | assert(self.symbol_atom.remove(local_atom.symbolLoc())); |
| 826 | } | 826 | } |
| 827 | | 827 | |
| 828 | if (decl.isExtern()) { | 828 | if (decl.isExtern()) { |
| 829 | assert(self.imports.remove(atom.symbolLoc())); | 829 | assert(self.imports.remove(atom.symbolLoc())); |
| 830 | } | 830 | } |
| 831 | assert(self.resolved_symbols.swapRemove(atom.symbolLoc())); | 831 | assert(self.resolved_symbols.swapRemove(atom.symbolLoc())); |
| | 832 | assert(self.symbol_atom.remove(atom.symbolLoc())); |
| 832 | atom.deinit(self.base.allocator); | 833 | atom.deinit(self.base.allocator); |
| 833 | } | 834 | } |
| 834 | | 835 | |
| ... | @@ -988,7 +989,6 @@ fn allocateAtoms(self: *Wasm) !void { | ... | @@ -988,7 +989,6 @@ fn allocateAtoms(self: *Wasm) !void { |
| 988 | atom.size, | 989 | atom.size, |
| 989 | }); | 990 | }); |
| 990 | offset += atom.size; | 991 | offset += atom.size; |
| 991 | try self.symbol_atom.putNoClobber(self.base.allocator, symbol_loc, atom); | | |
| 992 | atom = atom.next orelse break; | 992 | atom = atom.next orelse break; |
| 993 | } | 993 | } |
| 994 | } | 994 | } |