| ... | ... | @@ -21,6 +21,7 @@ const build_options = @import("build_options"); |
| 21 | 21 | const wasi_libc = @import("../wasi_libc.zig"); |
| 22 | 22 | const Cache = @import("../Cache.zig"); |
| 23 | 23 | const Type = @import("../type.zig").Type; |
| 24 | const TypedValue = @import("../TypedValue.zig"); |
| 24 | 25 | const LlvmObject = @import("../codegen/llvm.zig").Object; |
| 25 | 26 | const Air = @import("../Air.zig"); |
| 26 | 27 | const Liveness = @import("../Liveness.zig"); |
| ... | ... | @@ -497,10 +498,13 @@ fn finishUpdateDecl(self: *Wasm, decl: *Module.Decl, code: []const u8) !void { |
| 497 | 498 | try atom.code.appendSlice(self.base.allocator, code); |
| 498 | 499 | } |
| 499 | 500 | |
| 500 | | /// Creates a new local symbol for a given type (and its bytes it's represented by) |
| 501 | | /// and then append it as a 'contained' atom onto the Decl. |
| 502 | | pub fn createLocalSymbol(self: *Wasm, decl: *Module.Decl, ty: Type) !u32 { |
| 503 | | assert(ty.zigTypeTag() != .Fn); // cannot create local symbols for functions |
| 501 | /// Lowers a constant typed value to a local symbol and atom. |
| 502 | /// Returns the symbol index of the local |
| 503 | /// The given `decl` is the parent decl whom owns the constant. |
| 504 | pub fn lowerUnnamedConst(self: *Wasm, decl: *Module.Decl, tv: TypedValue) !u32 { |
| 505 | assert(tv.ty.zigTypeTag() != .Fn); // cannot create local symbols for functions |
| 506 | |
| 507 | // Create and initialize a new local symbol and atom |
| 504 | 508 | const local_index = decl.link.wasm.locals.items.len; |
| 505 | 509 | const name = try std.fmt.allocPrintZ(self.base.allocator, "__unnamed_{s}_{d}", .{ decl.name, local_index }); |
| 506 | 510 | var symbol: Symbol = .{ |
| ... | ... | @@ -510,10 +514,10 @@ pub fn createLocalSymbol(self: *Wasm, decl: *Module.Decl, ty: Type) !u32 { |
| 510 | 514 | .index = undefined, |
| 511 | 515 | }; |
| 512 | 516 | symbol.setFlag(.WASM_SYM_BINDING_LOCAL); |
| 513 | | symbol.setFlag(.WASM_SYM_VISIBILITY_HIDDEN); |
| 514 | 517 | |
| 515 | | var atom = Atom.empty; |
| 516 | | atom.alignment = ty.abiAlignment(self.base.options.target); |
| 518 | const atom = try decl.link.wasm.locals.addOne(self.base.allocator); |
| 519 | atom.* = Atom.empty; |
| 520 | atom.alignment = tv.ty.abiAlignment(self.base.options.target); |
| 517 | 521 | try self.symbols.ensureUnusedCapacity(self.base.allocator, 1); |
| 518 | 522 | |
| 519 | 523 | if (self.symbols_free_list.popOrNull()) |index| { |
| ... | ... | @@ -528,14 +532,36 @@ pub fn createLocalSymbol(self: *Wasm, decl: *Module.Decl, ty: Type) !u32 { |
| 528 | 532 | .index = atom.sym_index, |
| 529 | 533 | }, {}); |
| 530 | 534 | |
| 531 | | try decl.link.wasm.locals.append(self.base.allocator, atom); |
| 532 | | return atom.sym_index; |
| 533 | | } |
| 535 | var value_bytes = std.ArrayList(u8).init(self.base.allocator); |
| 536 | defer value_bytes.deinit(); |
| 537 | |
| 538 | const module = self.base.options.module.?; |
| 539 | var decl_gen: CodeGen.DeclGen = .{ |
| 540 | .bin_file = self, |
| 541 | .decl = decl, |
| 542 | .err_msg = undefined, |
| 543 | .gpa = self.base.allocator, |
| 544 | .module = module, |
| 545 | .code = &value_bytes, |
| 546 | .symbol_index = atom.sym_index, |
| 547 | }; |
| 548 | |
| 549 | const result = decl_gen.genTypedValue(tv.ty, tv.val) catch |err| switch (err) { |
| 550 | error.CodegenFail => { |
| 551 | decl.analysis = .codegen_failure; |
| 552 | try module.failed_decls.put(module.gpa, decl, decl_gen.err_msg); |
| 553 | return error.AnalysisFail; |
| 554 | }, |
| 555 | else => |e| return e, |
| 556 | }; |
| 557 | const code = switch (result) { |
| 558 | .appended => value_bytes.items, |
| 559 | .externally_managed => |data| data, |
| 560 | }; |
| 534 | 561 | |
| 535 | | pub fn updateLocalSymbolCode(self: *Wasm, decl: *Module.Decl, symbol_index: u32, code: []const u8) !void { |
| 536 | | const atom = decl.link.wasm.symbolAtom(symbol_index); |
| 537 | 562 | atom.size = @intCast(u32, code.len); |
| 538 | 563 | try atom.code.appendSlice(self.base.allocator, code); |
| 564 | return atom.sym_index; |
| 539 | 565 | } |
| 540 | 566 | |
| 541 | 567 | /// For a given decl, find the given symbol index's atom, and create a relocation for the type. |
| ... | ... | @@ -543,16 +569,18 @@ pub fn updateLocalSymbolCode(self: *Wasm, decl: *Module.Decl, symbol_index: u32, |
| 543 | 569 | pub fn getDeclVAddr( |
| 544 | 570 | self: *Wasm, |
| 545 | 571 | decl: *Module.Decl, |
| 546 | | ty: Type, |
| 547 | 572 | symbol_index: u32, |
| 548 | | target_symbol_index: u32, |
| 573 | target_decl: *Module.Decl, |
| 549 | 574 | offset: u32, |
| 550 | 575 | addend: u32, |
| 551 | 576 | ) !u32 { |
| 577 | const target_symbol_index = target_decl.link.wasm.sym_index; |
| 552 | 578 | assert(target_symbol_index != 0); |
| 579 | assert(symbol_index != 0); |
| 580 | |
| 553 | 581 | const atom = decl.link.wasm.symbolAtom(symbol_index); |
| 554 | 582 | const is_wasm32 = self.base.options.target.cpu.arch == .wasm32; |
| 555 | | if (ty.zigTypeTag() == .Fn) { |
| 583 | if (target_decl.ty.zigTypeTag() == .Fn) { |
| 556 | 584 | assert(addend == 0); // addend not allowed for function relocations |
| 557 | 585 | // We found a function pointer, so add it to our table, |
| 558 | 586 | // as function pointers are not allowed to be stored inside the data section. |
| ... | ... | @@ -1192,6 +1220,11 @@ fn resetState(self: *Wasm) void { |
| 1192 | 1220 | const atom = &decl.*.link.wasm; |
| 1193 | 1221 | atom.next = null; |
| 1194 | 1222 | atom.prev = null; |
| 1223 | |
| 1224 | for (atom.locals.items) |*local_atom| { |
| 1225 | local_atom.next = null; |
| 1226 | local_atom.prev = null; |
| 1227 | } |
| 1195 | 1228 | } |
| 1196 | 1229 | self.functions.clearRetainingCapacity(); |
| 1197 | 1230 | self.exports.clearRetainingCapacity(); |