| ... | @@ -19,7 +19,7 @@ const trace = @import("../tracy.zig").trace; | ... | @@ -19,7 +19,7 @@ const trace = @import("../tracy.zig").trace; |
| 19 | const build_options = @import("build_options"); | 19 | const build_options = @import("build_options"); |
| 20 | const wasi_libc = @import("../wasi_libc.zig"); | 20 | const wasi_libc = @import("../wasi_libc.zig"); |
| 21 | const Cache = @import("../Cache.zig"); | 21 | const Cache = @import("../Cache.zig"); |
| 22 | const TypedValue = @import("../TypedValue.zig"); | 22 | const Type = @import("../type.zig").Type; |
| 23 | const LlvmObject = @import("../codegen/llvm.zig").Object; | 23 | const LlvmObject = @import("../codegen/llvm.zig").Object; |
| 24 | const Air = @import("../Air.zig"); | 24 | const Air = @import("../Air.zig"); |
| 25 | const Liveness = @import("../Liveness.zig"); | 25 | const Liveness = @import("../Liveness.zig"); |
| ... | @@ -306,9 +306,41 @@ fn finishUpdateDecl(self: *Wasm, decl: *Module.Decl, result: CodeGen.Result, cod | ... | @@ -306,9 +306,41 @@ fn finishUpdateDecl(self: *Wasm, decl: *Module.Decl, result: CodeGen.Result, cod |
| 306 | if (code.len == 0) return; | 306 | if (code.len == 0) return; |
| 307 | const atom: *Atom = &decl.link.wasm; | 307 | const atom: *Atom = &decl.link.wasm; |
| 308 | atom.size = @intCast(u32, code.len); | 308 | atom.size = @intCast(u32, code.len); |
| | 309 | atom.alignment = decl.ty.abiAlignment(self.base.options.target); |
| | 310 | self.symbols.items[atom.sym_index].name = decl.name; |
| 309 | try atom.code.appendSlice(self.base.allocator, code); | 311 | try atom.code.appendSlice(self.base.allocator, code); |
| 310 | } | 312 | } |
| 311 | | 313 | |
| | 314 | /// Creates a new local symbol for a given type (and its bytes it's represented by) |
| | 315 | /// and then append it as a 'contained' atom onto the Decl. |
| | 316 | pub fn createLocalSymbol(self: *Wasm, decl: *Module.Decl, ty: Type, code: []const u8) !u32 { |
| | 317 | assert(ty.zigTypeTag() != .Fn); // cannot create local symbols for functions |
| | 318 | var symbol: Symbol = .{ |
| | 319 | .name = "unnamed_local", |
| | 320 | .flags = 0, |
| | 321 | .tag = .data, |
| | 322 | .index = undefined, |
| | 323 | }; |
| | 324 | symbol.setFlag(.WASM_SYM_BINDING_LOCAL); |
| | 325 | symbol.setFlag(.WASM_SYM_VISIBILITY_HIDDEN); |
| | 326 | |
| | 327 | var atom = Atom.empty; |
| | 328 | atom.size = @intCast(u32, code.len); |
| | 329 | atom.alignment = ty.abiAlignment(self.base.options.target); |
| | 330 | try atom.code.appendSlice(self.base.allocator, code); |
| | 331 | |
| | 332 | if (self.symbols_free_list.popOrNull()) |index| { |
| | 333 | atom.sym_index = index; |
| | 334 | self.symbols.items[index] = symbol; |
| | 335 | } else { |
| | 336 | atom.sym_index = @intCast(u32, self.symbols.items.len); |
| | 337 | self.symbols.appendAssumeCapacity(symbol); |
| | 338 | } |
| | 339 | |
| | 340 | try decl.link.wasm.locals.append(self.base.allocator, atom); |
| | 341 | return atom.sym_index; |
| | 342 | } |
| | 343 | |
| 312 | pub fn updateDeclExports( | 344 | pub fn updateDeclExports( |
| 313 | self: *Wasm, | 345 | self: *Wasm, |
| 314 | module: *Module, | 346 | module: *Module, |
| ... | @@ -329,9 +361,12 @@ pub fn freeDecl(self: *Wasm, decl: *Module.Decl) void { | ... | @@ -329,9 +361,12 @@ pub fn freeDecl(self: *Wasm, decl: *Module.Decl) void { |
| 329 | } | 361 | } |
| 330 | const atom = &decl.link.wasm; | 362 | const atom = &decl.link.wasm; |
| 331 | self.symbols_free_list.append(self.base.allocator, atom.sym_index) catch {}; | 363 | self.symbols_free_list.append(self.base.allocator, atom.sym_index) catch {}; |
| 332 | atom.deinit(self.base.allocator); | | |
| 333 | _ = self.decls.remove(decl); | 364 | _ = self.decls.remove(decl); |
| 334 | self.symbols.items[atom.sym_index].tag = .dead; // to ensure it does not end in the names section | 365 | self.symbols.items[atom.sym_index].tag = .dead; // to ensure it does not end in the names section |
| | 366 | for (atom.locals.items) |local_atom| { |
| | 367 | self.symbols.items[local_atom.sym_index].tag = .dead; // also for any local symbol |
| | 368 | } |
| | 369 | atom.deinit(self.base.allocator); |
| 335 | | 370 | |
| 336 | if (decl.isExtern()) { | 371 | if (decl.isExtern()) { |
| 337 | const import = self.imports.fetchRemove(decl.link.wasm.sym_index).?.value; | 372 | const import = self.imports.fetchRemove(decl.link.wasm.sym_index).?.value; |
| ... | @@ -377,14 +412,16 @@ fn addOrUpdateImport(self: *Wasm, decl: *Module.Decl) !void { | ... | @@ -377,14 +412,16 @@ fn addOrUpdateImport(self: *Wasm, decl: *Module.Decl) !void { |
| 377 | } | 412 | } |
| 378 | } | 413 | } |
| 379 | | 414 | |
| 380 | fn parseDeclIntoAtom(self: *Wasm, decl: *Module.Decl) !void { | 415 | const Kind = union(enum) { |
| 381 | const atom: *Atom = &decl.link.wasm; | 416 | data: void, |
| | 417 | function: FnData, |
| | 418 | }; |
| | 419 | |
| | 420 | /// Parses an Atom and inserts its metadata into the corresponding sections. |
| | 421 | fn parseAtom(self: *Wasm, atom: *Atom, kind: Kind) !void { |
| 382 | const symbol: *Symbol = &self.symbols.items[atom.sym_index]; | 422 | const symbol: *Symbol = &self.symbols.items[atom.sym_index]; |
| 383 | symbol.name = decl.name; | 423 | const final_index: u32 = switch (kind) { |
| 384 | atom.alignment = decl.ty.abiAlignment(self.base.options.target); | 424 | .function => |fn_data| result: { |
| 385 | const final_index: u32 = switch (decl.ty.zigTypeTag()) { | | |
| 386 | .Fn => result: { | | |
| 387 | const fn_data = decl.fn_link.wasm; | | |
| 388 | const type_index = fn_data.type_index; | 425 | const type_index = fn_data.type_index; |
| 389 | const index = @intCast(u32, self.functions.items.len + self.imported_functions_count); | 426 | const index = @intCast(u32, self.functions.items.len + self.imported_functions_count); |
| 390 | try self.functions.append(self.base.allocator, .{ .type_index = type_index }); | 427 | try self.functions.append(self.base.allocator, .{ .type_index = type_index }); |
| ... | @@ -402,7 +439,7 @@ fn parseDeclIntoAtom(self: *Wasm, decl: *Module.Decl) !void { | ... | @@ -402,7 +439,7 @@ fn parseDeclIntoAtom(self: *Wasm, decl: *Module.Decl) !void { |
| 402 | | 439 | |
| 403 | break :result self.code_section_index.?; | 440 | break :result self.code_section_index.?; |
| 404 | }, | 441 | }, |
| 405 | else => result: { | 442 | .data => result: { |
| 406 | const gop = try self.data_segments.getOrPut(self.base.allocator, ".rodata"); | 443 | const gop = try self.data_segments.getOrPut(self.base.allocator, ".rodata"); |
| 407 | const atom_index = if (gop.found_existing) blk: { | 444 | const atom_index = if (gop.found_existing) blk: { |
| 408 | self.segments.items[gop.value_ptr.*].size += atom.size; | 445 | self.segments.items[gop.value_ptr.*].size += atom.size; |
| ... | @@ -430,7 +467,6 @@ fn parseDeclIntoAtom(self: *Wasm, decl: *Module.Decl) !void { | ... | @@ -430,7 +467,6 @@ fn parseDeclIntoAtom(self: *Wasm, decl: *Module.Decl) !void { |
| 430 | }); | 467 | }); |
| 431 | symbol.tag = .data; | 468 | symbol.tag = .data; |
| 432 | symbol.index = info_index; | 469 | symbol.index = info_index; |
| 433 | atom.alignment = decl.ty.abiAlignment(self.base.options.target); | | |
| 434 | | 470 | |
| 435 | break :result atom_index; | 471 | break :result atom_index; |
| 436 | }, | 472 | }, |
| ... | @@ -617,7 +653,17 @@ pub fn flushModule(self: *Wasm, comp: *Compilation) !void { | ... | @@ -617,7 +653,17 @@ pub fn flushModule(self: *Wasm, comp: *Compilation) !void { |
| 617 | var decl_it = self.decls.keyIterator(); | 653 | var decl_it = self.decls.keyIterator(); |
| 618 | while (decl_it.next()) |decl| { | 654 | while (decl_it.next()) |decl| { |
| 619 | if (decl.*.isExtern()) continue; | 655 | if (decl.*.isExtern()) continue; |
| 620 | try self.parseDeclIntoAtom(decl.*); | 656 | const atom = &decl.*.link.wasm; |
| | 657 | if (decl.*.ty.zigTypeTag() == .Fn) { |
| | 658 | try self.parseAtom(atom, .{ .function = decl.*.fn_link.wasm }); |
| | 659 | } else { |
| | 660 | try self.parseAtom(atom, .data); |
| | 661 | } |
| | 662 | |
| | 663 | // also parse atoms for a decl's locals |
| | 664 | for (atom.locals.items) |*local_atom| { |
| | 665 | try self.parseAtom(local_atom, .data); |
| | 666 | } |
| 621 | } | 667 | } |
| 622 | | 668 | |
| 623 | try self.setupMemory(); | 669 | try self.setupMemory(); |