| ... | @@ -79,14 +79,20 @@ pub fn finish(f: *Flush, wasm: *Wasm, arena: Allocator) !void { | ... | @@ -79,14 +79,20 @@ pub fn finish(f: *Flush, wasm: *Wasm, arena: Allocator) !void { |
| 79 | | 79 | |
| 80 | for (wasm.nav_exports.keys()) |*nav_export| { | 80 | for (wasm.nav_exports.keys()) |*nav_export| { |
| 81 | if (ip.isFunctionType(ip.getNav(nav_export.nav_index).typeOf(ip))) { | 81 | if (ip.isFunctionType(ip.getNav(nav_export.nav_index).typeOf(ip))) { |
| 82 | try wasm.function_exports.append(gpa, Wasm.FunctionIndex.fromIpNav(wasm, nav_export.nav_index).?); | 82 | try wasm.function_exports.append(gpa, .{ |
| | 83 | .name = nav_export.name, |
| | 84 | .function_index = Wasm.FunctionIndex.fromIpNav(wasm, nav_export.nav_index).?, |
| | 85 | }); |
| 83 | _ = f.missing_exports.swapRemove(nav_export.name); | 86 | _ = f.missing_exports.swapRemove(nav_export.name); |
| 84 | _ = wasm.function_imports.swapRemove(nav_export.name); | 87 | _ = wasm.function_imports.swapRemove(nav_export.name); |
| 85 | | 88 | |
| 86 | if (nav_export.name.toOptional() == entry_name) | 89 | if (nav_export.name.toOptional() == entry_name) |
| 87 | wasm.entry_resolution = .fromIpNav(wasm, nav_export.nav_index); | 90 | wasm.entry_resolution = .fromIpNav(wasm, nav_export.nav_index); |
| 88 | } else { | 91 | } else { |
| 89 | try wasm.global_exports.append(gpa, Wasm.GlobalIndex.fromIpNav(wasm, nav_export.nav_index).?); | 92 | try wasm.global_exports.append(gpa, .{ |
| | 93 | .name = nav_export.name, |
| | 94 | .global_index = Wasm.GlobalIndex.fromIpNav(wasm, nav_export.nav_index).?, |
| | 95 | }); |
| 90 | _ = f.missing_exports.swapRemove(nav_export.name); | 96 | _ = f.missing_exports.swapRemove(nav_export.name); |
| 91 | _ = wasm.global_imports.swapRemove(nav_export.name); | 97 | _ = wasm.global_imports.swapRemove(nav_export.name); |
| 92 | } | 98 | } |
| ... | @@ -437,8 +443,12 @@ pub fn finish(f: *Flush, wasm: *Wasm, arena: Allocator) !void { | ... | @@ -437,8 +443,12 @@ pub fn finish(f: *Flush, wasm: *Wasm, arena: Allocator) !void { |
| 437 | } | 443 | } |
| 438 | total_imports += wasm.global_imports.entries.len; | 444 | total_imports += wasm.global_imports.entries.len; |
| 439 | | 445 | |
| 440 | replaceVecSectionHeader(binary_bytes, header_offset, .import, @intCast(total_imports)); | 446 | if (total_imports > 0) { |
| 441 | section_index += 1; | 447 | replaceVecSectionHeader(binary_bytes, header_offset, .import, @intCast(total_imports)); |
| | 448 | section_index += 1; |
| | 449 | } else { |
| | 450 | binary_bytes.shrinkRetainingCapacity(header_offset); |
| | 451 | } |
| 442 | } | 452 | } |
| 443 | | 453 | |
| 444 | // Function section | 454 | // Function section |
| ... | @@ -474,7 +484,8 @@ pub fn finish(f: *Flush, wasm: *Wasm, arena: Allocator) !void { | ... | @@ -474,7 +484,8 @@ pub fn finish(f: *Flush, wasm: *Wasm, arena: Allocator) !void { |
| 474 | } | 484 | } |
| 475 | | 485 | |
| 476 | // Global section (used to emit stack pointer) | 486 | // Global section (used to emit stack pointer) |
| 477 | if (wasm.globals.entries.len > 0) { | 487 | const globals_len: u32 = @intCast(wasm.globals.entries.len); |
| | 488 | if (globals_len > 0) { |
| 478 | const header_offset = try reserveVecSectionHeader(gpa, binary_bytes); | 489 | const header_offset = try reserveVecSectionHeader(gpa, binary_bytes); |
| 479 | | 490 | |
| 480 | for (wasm.globals.keys()) |global_resolution| { | 491 | for (wasm.globals.keys()) |global_resolution| { |
| ... | @@ -498,32 +509,50 @@ pub fn finish(f: *Flush, wasm: *Wasm, arena: Allocator) !void { | ... | @@ -498,32 +509,50 @@ pub fn finish(f: *Flush, wasm: *Wasm, arena: Allocator) !void { |
| 498 | } | 509 | } |
| 499 | } | 510 | } |
| 500 | | 511 | |
| 501 | replaceVecSectionHeader(binary_bytes, header_offset, .global, @intCast(wasm.globals.entries.len)); | 512 | replaceVecSectionHeader(binary_bytes, header_offset, .global, globals_len); |
| 502 | section_index += 1; | 513 | section_index += 1; |
| 503 | } | 514 | } |
| 504 | | 515 | |
| 505 | // Export section | 516 | // Export section |
| 506 | if (wasm.exports.items.len != 0 or export_memory) { | 517 | { |
| 507 | const header_offset = try reserveVecSectionHeader(gpa, binary_bytes); | 518 | const header_offset = try reserveVecSectionHeader(gpa, binary_bytes); |
| | 519 | var exports_len: usize = 0; |
| 508 | | 520 | |
| 509 | for (wasm.exports.items) |exp| { | 521 | for (wasm.function_exports.items) |exp| { |
| 510 | const name = exp.name.slice(wasm); | 522 | const name = exp.name.slice(wasm); |
| 511 | try leb.writeUleb128(binary_writer, @as(u32, @intCast(name.len))); | 523 | try leb.writeUleb128(binary_writer, @as(u32, @intCast(name.len))); |
| 512 | try binary_writer.writeAll(name); | 524 | try binary_bytes.appendSlice(gpa, name); |
| 513 | try leb.writeUleb128(binary_writer, @intFromEnum(exp.kind)); | 525 | try binary_bytes.append(gpa, @intFromEnum(std.wasm.ExternalKind.function)); |
| 514 | try leb.writeUleb128(binary_writer, exp.index); | 526 | try leb.writeUleb128(binary_writer, @as(u32, @intCast(wasm.function_imports.entries.len + @intFromEnum(exp.function_index)))); |
| 515 | } | 527 | } |
| | 528 | exports_len += wasm.function_exports.items.len; |
| | 529 | |
| | 530 | // No table exports. |
| 516 | | 531 | |
| 517 | if (export_memory) { | 532 | if (export_memory) { |
| 518 | try leb.writeUleb128(binary_writer, @as(u32, @intCast("memory".len))); | 533 | const name = "memory"; |
| 519 | try binary_writer.writeAll("memory"); | 534 | try leb.writeUleb128(binary_writer, @as(u32, @intCast(name.len))); |
| 520 | try binary_writer.writeByte(std.wasm.externalKind(.memory)); | 535 | try binary_bytes.appendSlice(gpa, name); |
| | 536 | try binary_bytes.append(gpa, @intFromEnum(std.wasm.ExternalKind.memory)); |
| 521 | try leb.writeUleb128(binary_writer, @as(u32, 0)); | 537 | try leb.writeUleb128(binary_writer, @as(u32, 0)); |
| | 538 | exports_len += 1; |
| 522 | } | 539 | } |
| 523 | | 540 | |
| 524 | const n_items: u32 = @intCast(wasm.exports.items.len + @intFromBool(export_memory)); | 541 | for (wasm.global_exports.items) |exp| { |
| 525 | replaceVecSectionHeader(binary_bytes, header_offset, .@"export", n_items); | 542 | const name = exp.name.slice(wasm); |
| 526 | section_index += 1; | 543 | try leb.writeUleb128(binary_writer, @as(u32, @intCast(name.len))); |
| | 544 | try binary_bytes.appendSlice(gpa, name); |
| | 545 | try binary_bytes.append(gpa, @intFromEnum(std.wasm.ExternalKind.global)); |
| | 546 | try leb.writeUleb128(binary_writer, @as(u32, @intCast(wasm.global_imports.entries.len + @intFromEnum(exp.global_index)))); |
| | 547 | } |
| | 548 | exports_len += wasm.global_exports.items.len; |
| | 549 | |
| | 550 | if (exports_len > 0) { |
| | 551 | replaceVecSectionHeader(binary_bytes, header_offset, .@"export", @intCast(exports_len)); |
| | 552 | section_index += 1; |
| | 553 | } else { |
| | 554 | binary_bytes.shrinkRetainingCapacity(header_offset); |
| | 555 | } |
| 527 | } | 556 | } |
| 528 | | 557 | |
| 529 | if (Wasm.FunctionIndex.fromResolution(wasm.entry_resolution)) |entry_index| { | 558 | if (Wasm.FunctionIndex.fromResolution(wasm.entry_resolution)) |entry_index| { |