mirror of
https://github.com/ziglang/zig.git
synced 2026-01-10 01:15:14 +00:00
wasm linker: support export section as implicit symbols
This commit is contained in:
parent
031c84c8cb
commit
26c38b2d42
@ -894,6 +894,15 @@ pub const ObjectGlobalIndex = enum(u32) {
|
||||
_,
|
||||
};
|
||||
|
||||
/// Index into `Wasm.object_memories`.
|
||||
pub const ObjectMemoryIndex = enum(u32) {
|
||||
_,
|
||||
|
||||
pub fn ptr(index: ObjectMemoryIndex, wasm: *const Wasm) *std.wasm.Memory {
|
||||
return &wasm.object_memories.items[@intFromEnum(index)];
|
||||
}
|
||||
};
|
||||
|
||||
/// Index into `object_functions`.
|
||||
pub const ObjectFunctionIndex = enum(u32) {
|
||||
_,
|
||||
@ -2609,7 +2618,10 @@ pub fn addExpr(wasm: *Wasm, bytes: []const u8) Allocator.Error!Expr {
|
||||
pub fn addRelocatableDataPayload(wasm: *Wasm, bytes: []const u8) Allocator.Error!DataSegment.Payload {
|
||||
const gpa = wasm.base.comp.gpa;
|
||||
try wasm.string_bytes.appendSlice(gpa, bytes);
|
||||
return @enumFromInt(wasm.string_bytes.items.len - bytes.len);
|
||||
return .{
|
||||
.off = @intCast(wasm.string_bytes.items.len - bytes.len),
|
||||
.len = @intCast(bytes.len),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn uavSymbolIndex(wasm: *Wasm, ip_index: InternPool.Index) Allocator.Error!SymbolTableIndex {
|
||||
|
||||
@ -122,6 +122,19 @@ pub const ScratchSpace = struct {
|
||||
func_imports: std.ArrayListUnmanaged(FunctionImport) = .empty,
|
||||
symbol_table: std.ArrayListUnmanaged(Symbol) = .empty,
|
||||
segment_info: std.ArrayListUnmanaged(SegmentInfo) = .empty,
|
||||
exports: std.ArrayListUnmanaged(Export) = .empty,
|
||||
|
||||
const Export = struct {
|
||||
name: Wasm.String,
|
||||
pointee: Pointee,
|
||||
|
||||
const Pointee = union(std.wasm.ExternalKind) {
|
||||
function: Wasm.ObjectFunctionIndex,
|
||||
table: Wasm.ObjectTableIndex,
|
||||
memory: Wasm.ObjectMemoryIndex,
|
||||
global: Wasm.ObjectGlobalIndex,
|
||||
};
|
||||
};
|
||||
|
||||
/// Index into `func_imports`.
|
||||
const FuncImportIndex = enum(u32) {
|
||||
@ -142,6 +155,7 @@ pub const ScratchSpace = struct {
|
||||
};
|
||||
|
||||
pub fn deinit(ss: *ScratchSpace, gpa: Allocator) void {
|
||||
ss.exports.deinit(gpa);
|
||||
ss.func_types.deinit(gpa);
|
||||
ss.func_type_indexes.deinit(gpa);
|
||||
ss.func_imports.deinit(gpa);
|
||||
@ -151,6 +165,7 @@ pub const ScratchSpace = struct {
|
||||
}
|
||||
|
||||
fn clear(ss: *ScratchSpace) void {
|
||||
ss.exports.clearRetainingCapacity();
|
||||
ss.func_types.clearRetainingCapacity();
|
||||
ss.func_type_indexes.clearRetainingCapacity();
|
||||
ss.func_imports.clearRetainingCapacity();
|
||||
@ -622,24 +637,22 @@ pub fn parse(
|
||||
},
|
||||
.@"export" => {
|
||||
const exports_len, pos = readLeb(u32, bytes, pos);
|
||||
// TODO: instead, read into scratch space, and then later
|
||||
// add this data as if it were extra symbol table entries,
|
||||
// but allow merging with existing symbol table data if the name matches.
|
||||
for (try wasm.object_exports.addManyAsSlice(gpa, exports_len)) |*exp| {
|
||||
// Read into scratch space, and then later add this data as if
|
||||
// it were extra symbol table entries, but allow merging with
|
||||
// existing symbol table data if the name matches.
|
||||
for (try ss.exports.addManyAsSlice(gpa, exports_len)) |*exp| {
|
||||
const name, pos = readBytes(bytes, pos);
|
||||
const kind: std.wasm.ExternalKind = @enumFromInt(bytes[pos]);
|
||||
pos += 1;
|
||||
const index, pos = readLeb(u32, bytes, pos);
|
||||
const rebased_index = index + switch (kind) {
|
||||
.function => functions_start,
|
||||
.table => tables_start,
|
||||
.memory => memories_start,
|
||||
.global => globals_start,
|
||||
};
|
||||
exp.* = .{
|
||||
.name = try wasm.internString(name),
|
||||
.kind = kind,
|
||||
.index = rebased_index,
|
||||
.pointee = switch (kind) {
|
||||
.function => .{ .function = @enumFromInt(functions_start + index) },
|
||||
.table => .{ .table = @enumFromInt(tables_start + index) },
|
||||
.memory => .{ .memory = @enumFromInt(memories_start + index) },
|
||||
.global => .{ .global = @enumFromInt(globals_start + index) },
|
||||
},
|
||||
};
|
||||
}
|
||||
},
|
||||
@ -828,6 +841,21 @@ pub fn parse(
|
||||
},
|
||||
};
|
||||
|
||||
// Apply export section info. This is done after the symbol table above so
|
||||
// that the symbol table can take precedence, overriding the export name.
|
||||
for (ss.exports.items) |*exp| {
|
||||
switch (exp.pointee) {
|
||||
inline .function, .table, .memory, .global => |index| {
|
||||
const ptr = index.ptr(wasm);
|
||||
if (ptr.name == .none) {
|
||||
// Missng symbol table entry; use defaults for exported things.
|
||||
ptr.name = exp.name.toOptional();
|
||||
ptr.flags.exported = true;
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Apply segment_info.
|
||||
for (wasm.object_data_segments.items[data_segment_start..], ss.segment_info.items) |*data, info| {
|
||||
data.name = info.name.toOptional();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user