| ... | ... | @@ -377,6 +377,17 @@ pub fn open( |
| 377 | 377 | comp: *Compilation, |
| 378 | 378 | emit: Compilation.Emit, |
| 379 | 379 | options: link.File.OpenOptions, |
| 380 | ) !*Wasm { |
| 381 | // TODO: restore saved linker state, don't truncate the file, and |
| 382 | // participate in incremental compilation. |
| 383 | return createEmpty(arena, comp, emit, options); |
| 384 | } |
| 385 | |
| 386 | pub fn createEmpty( |
| 387 | arena: Allocator, |
| 388 | comp: *Compilation, |
| 389 | emit: Compilation.Emit, |
| 390 | options: link.File.OpenOptions, |
| 380 | 391 | ) !*Wasm { |
| 381 | 392 | const gpa = comp.gpa; |
| 382 | 393 | const target = comp.root_mod.resolved_target.result; |
| ... | ... | @@ -387,7 +398,46 @@ pub fn open( |
| 387 | 398 | const output_mode = comp.config.output_mode; |
| 388 | 399 | const shared_memory = comp.config.shared_memory; |
| 389 | 400 | |
| 390 | | const wasm = try createEmpty(arena, comp, emit, options); |
| 401 | // If using LLD to link, this code should produce an object file so that it |
| 402 | // can be passed to LLD. |
| 403 | // If using LLVM to generate the object file for the zig compilation unit, |
| 404 | // we need a place to put the object file so that it can be subsequently |
| 405 | // handled. |
| 406 | const zcu_object_sub_path = if (!use_lld and !use_llvm) |
| 407 | null |
| 408 | else |
| 409 | try std.fmt.allocPrint(arena, "{s}.o", .{emit.sub_path}); |
| 410 | |
| 411 | const wasm = try arena.create(Wasm); |
| 412 | wasm.* = .{ |
| 413 | .base = .{ |
| 414 | .tag = .wasm, |
| 415 | .comp = comp, |
| 416 | .emit = emit, |
| 417 | .zcu_object_sub_path = zcu_object_sub_path, |
| 418 | .gc_sections = options.gc_sections orelse (output_mode != .Obj), |
| 419 | .print_gc_sections = options.print_gc_sections, |
| 420 | .stack_size = options.stack_size orelse std.wasm.page_size * 16, // 1MB |
| 421 | .allow_shlib_undefined = options.allow_shlib_undefined orelse false, |
| 422 | .file = null, |
| 423 | .disable_lld_caching = options.disable_lld_caching, |
| 424 | .build_id = options.build_id, |
| 425 | .rpath_list = options.rpath_list, |
| 426 | .force_undefined_symbols = options.force_undefined_symbols, |
| 427 | }, |
| 428 | .name = undefined, |
| 429 | .import_table = options.import_table, |
| 430 | .export_table = options.export_table, |
| 431 | .import_symbols = options.import_symbols, |
| 432 | .export_symbol_names = options.export_symbol_names, |
| 433 | .global_base = options.global_base, |
| 434 | .initial_memory = options.initial_memory, |
| 435 | .max_memory = options.max_memory, |
| 436 | .wasi_emulated_libs = options.wasi_emulated_libs, |
| 437 | }; |
| 438 | if (use_llvm and comp.config.have_zcu) { |
| 439 | wasm.llvm_object = try LlvmObject.create(arena, comp); |
| 440 | } |
| 391 | 441 | errdefer wasm.base.destroy(); |
| 392 | 442 | |
| 393 | 443 | if (use_lld and use_llvm) { |
| ... | ... | @@ -395,17 +445,11 @@ pub fn open( |
| 395 | 445 | return wasm; |
| 396 | 446 | } |
| 397 | 447 | |
| 398 | | const sub_path = if (!use_lld) emit.sub_path else p: { |
| 399 | | // Open a temporary object file, not the final output file because we |
| 400 | | // want to link with LLD. |
| 401 | | const o_file_path = try std.fmt.allocPrint(arena, "{s}{s}", .{ |
| 402 | | emit.sub_path, target.ofmt.fileExt(target.cpu.arch), |
| 403 | | }); |
| 404 | | wasm.base.zcu_object_sub_path = o_file_path; |
| 405 | | break :p o_file_path; |
| 406 | | }; |
| 448 | // What path should this Wasm linker code output to? |
| 449 | // If using LLD to link, this code should produce an object file so that it |
| 450 | // can be passed to LLD. |
| 451 | const sub_path = if (use_lld) zcu_object_sub_path.? else emit.sub_path; |
| 407 | 452 | |
| 408 | | // TODO: read the file and keep valid parts instead of truncating |
| 409 | 453 | const file = try emit.directory.handle.createFile(sub_path, .{ |
| 410 | 454 | .truncate = true, |
| 411 | 455 | .read = true, |
| ... | ... | @@ -532,48 +576,6 @@ pub fn open( |
| 532 | 576 | return wasm; |
| 533 | 577 | } |
| 534 | 578 | |
| 535 | | pub fn createEmpty( |
| 536 | | arena: Allocator, |
| 537 | | comp: *Compilation, |
| 538 | | emit: Compilation.Emit, |
| 539 | | options: link.File.OpenOptions, |
| 540 | | ) !*Wasm { |
| 541 | | const use_llvm = comp.config.use_llvm; |
| 542 | | const output_mode = comp.config.output_mode; |
| 543 | | |
| 544 | | const wasm = try arena.create(Wasm); |
| 545 | | wasm.* = .{ |
| 546 | | .base = .{ |
| 547 | | .tag = .wasm, |
| 548 | | .comp = comp, |
| 549 | | .emit = emit, |
| 550 | | .gc_sections = options.gc_sections orelse (output_mode != .Obj), |
| 551 | | .print_gc_sections = options.print_gc_sections, |
| 552 | | .stack_size = options.stack_size orelse std.wasm.page_size * 16, // 1MB |
| 553 | | .allow_shlib_undefined = options.allow_shlib_undefined orelse false, |
| 554 | | .file = null, |
| 555 | | .disable_lld_caching = options.disable_lld_caching, |
| 556 | | .build_id = options.build_id, |
| 557 | | .rpath_list = options.rpath_list, |
| 558 | | .force_undefined_symbols = options.force_undefined_symbols, |
| 559 | | }, |
| 560 | | .name = undefined, |
| 561 | | .import_table = options.import_table, |
| 562 | | .export_table = options.export_table, |
| 563 | | .import_symbols = options.import_symbols, |
| 564 | | .export_symbol_names = options.export_symbol_names, |
| 565 | | .global_base = options.global_base, |
| 566 | | .initial_memory = options.initial_memory, |
| 567 | | .max_memory = options.max_memory, |
| 568 | | .wasi_emulated_libs = options.wasi_emulated_libs, |
| 569 | | }; |
| 570 | | |
| 571 | | if (use_llvm) { |
| 572 | | wasm.llvm_object = try LlvmObject.create(arena, comp); |
| 573 | | } |
| 574 | | return wasm; |
| 575 | | } |
| 576 | | |
| 577 | 579 | /// For a given name, creates a new global synthetic symbol. |
| 578 | 580 | /// Leaves index undefined and the default flags (0). |
| 579 | 581 | fn createSyntheticSymbol(wasm: *Wasm, name: []const u8, tag: Symbol.Tag) !SymbolLoc { |