| ... | ... | @@ -19,7 +19,7 @@ const trace = @import("../tracy.zig").trace; |
| 19 | 19 | const build_options = @import("build_options"); |
| 20 | 20 | const wasi_libc = @import("../wasi_libc.zig"); |
| 21 | 21 | const Cache = @import("../Cache.zig"); |
| 22 | | const TypedValue = @import("../TypedValue.zig"); |
| 22 | const Type = @import("../type.zig").Type; |
| 23 | 23 | const LlvmObject = @import("../codegen/llvm.zig").Object; |
| 24 | 24 | const Air = @import("../Air.zig"); |
| 25 | 25 | const Liveness = @import("../Liveness.zig"); |
| ... | ... | @@ -306,9 +306,41 @@ fn finishUpdateDecl(self: *Wasm, decl: *Module.Decl, result: CodeGen.Result, cod |
| 306 | 306 | if (code.len == 0) return; |
| 307 | 307 | const atom: *Atom = &decl.link.wasm; |
| 308 | 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 | 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 | 344 | pub fn updateDeclExports( |
| 313 | 345 | self: *Wasm, |
| 314 | 346 | module: *Module, |
| ... | ... | @@ -329,9 +361,12 @@ pub fn freeDecl(self: *Wasm, decl: *Module.Decl) void { |
| 329 | 361 | } |
| 330 | 362 | const atom = &decl.link.wasm; |
| 331 | 363 | self.symbols_free_list.append(self.base.allocator, atom.sym_index) catch {}; |
| 332 | | atom.deinit(self.base.allocator); |
| 333 | 364 | _ = self.decls.remove(decl); |
| 334 | 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 | 371 | if (decl.isExtern()) { |
| 337 | 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 | 412 | } |
| 378 | 413 | } |
| 379 | 414 | |
| 380 | | fn parseDeclIntoAtom(self: *Wasm, decl: *Module.Decl) !void { |
| 381 | | const atom: *Atom = &decl.link.wasm; |
| 415 | const Kind = union(enum) { |
| 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 | 422 | const symbol: *Symbol = &self.symbols.items[atom.sym_index]; |
| 383 | | symbol.name = decl.name; |
| 384 | | atom.alignment = decl.ty.abiAlignment(self.base.options.target); |
| 385 | | const final_index: u32 = switch (decl.ty.zigTypeTag()) { |
| 386 | | .Fn => result: { |
| 387 | | const fn_data = decl.fn_link.wasm; |
| 423 | const final_index: u32 = switch (kind) { |
| 424 | .function => |fn_data| result: { |
| 388 | 425 | const type_index = fn_data.type_index; |
| 389 | 426 | const index = @intCast(u32, self.functions.items.len + self.imported_functions_count); |
| 390 | 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 | 439 | |
| 403 | 440 | break :result self.code_section_index.?; |
| 404 | 441 | }, |
| 405 | | else => result: { |
| 442 | .data => result: { |
| 406 | 443 | const gop = try self.data_segments.getOrPut(self.base.allocator, ".rodata"); |
| 407 | 444 | const atom_index = if (gop.found_existing) blk: { |
| 408 | 445 | self.segments.items[gop.value_ptr.*].size += atom.size; |
| ... | ... | @@ -430,7 +467,6 @@ fn parseDeclIntoAtom(self: *Wasm, decl: *Module.Decl) !void { |
| 430 | 467 | }); |
| 431 | 468 | symbol.tag = .data; |
| 432 | 469 | symbol.index = info_index; |
| 433 | | atom.alignment = decl.ty.abiAlignment(self.base.options.target); |
| 434 | 470 | |
| 435 | 471 | break :result atom_index; |
| 436 | 472 | }, |
| ... | ... | @@ -617,7 +653,17 @@ pub fn flushModule(self: *Wasm, comp: *Compilation) !void { |
| 617 | 653 | var decl_it = self.decls.keyIterator(); |
| 618 | 654 | while (decl_it.next()) |decl| { |
| 619 | 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 | 669 | try self.setupMemory(); |