mirror of
https://github.com/ziglang/zig.git
synced 2025-12-16 11:13:08 +00:00
wasm object parsing: fix handling of weak functions and globals
This commit is contained in:
parent
4fccb5ae7a
commit
a4895f3c42
@ -1596,7 +1596,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
|
|||||||
.pdb_source_path = options.pdb_source_path,
|
.pdb_source_path = options.pdb_source_path,
|
||||||
.pdb_out_path = options.pdb_out_path,
|
.pdb_out_path = options.pdb_out_path,
|
||||||
.entry_addr = null, // CLI does not expose this option (yet?)
|
.entry_addr = null, // CLI does not expose this option (yet?)
|
||||||
.object_host_name = null, // TODO expose in the CLI
|
.object_host_name = "env",
|
||||||
};
|
};
|
||||||
|
|
||||||
switch (options.cache_mode) {
|
switch (options.cache_mode) {
|
||||||
|
|||||||
@ -1113,7 +1113,7 @@ pub const GlobalImport = extern struct {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fromObjectGlobal(wasm: *const Wasm, object_global: ObjectGlobalIndex) Resolution {
|
pub fn fromObjectGlobal(wasm: *const Wasm, object_global: ObjectGlobalIndex) Resolution {
|
||||||
return pack(wasm, .{ .object_global = object_global });
|
return pack(wasm, .{ .object_global = object_global });
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1154,9 +1154,13 @@ pub const GlobalImport = extern struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn globalType(index: Index, wasm: *const Wasm) ObjectGlobal.Type {
|
pub fn globalType(index: Index, wasm: *const Wasm) ObjectGlobal.Type {
|
||||||
return value(index, wasm).flags.global_type.to();
|
return value(index, wasm).type();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub fn @"type"(gi: *const GlobalImport) ObjectGlobal.Type {
|
||||||
|
return gi.flags.global_type.to();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const ObjectGlobal = extern struct {
|
pub const ObjectGlobal = extern struct {
|
||||||
@ -1169,6 +1173,10 @@ pub const ObjectGlobal = extern struct {
|
|||||||
offset: u32,
|
offset: u32,
|
||||||
size: u32,
|
size: u32,
|
||||||
|
|
||||||
|
pub fn @"type"(og: *const ObjectGlobal) Type {
|
||||||
|
return og.flags.global_type.to();
|
||||||
|
}
|
||||||
|
|
||||||
pub const Type = struct {
|
pub const Type = struct {
|
||||||
valtype: std.wasm.Valtype,
|
valtype: std.wasm.Valtype,
|
||||||
mutable: bool,
|
mutable: bool,
|
||||||
|
|||||||
@ -982,9 +982,6 @@ pub fn parse(
|
|||||||
source_location.addNote(&err, "module '{s}' here", .{ptr.module_name.slice(wasm)});
|
source_location.addNote(&err, "module '{s}' here", .{ptr.module_name.slice(wasm)});
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (symbol.flags.binding == .strong) gop.value_ptr.flags.binding = .strong;
|
|
||||||
if (!symbol.flags.visibility_hidden) gop.value_ptr.flags.visibility_hidden = false;
|
|
||||||
if (symbol.flags.no_strip) gop.value_ptr.flags.no_strip = true;
|
|
||||||
} else {
|
} else {
|
||||||
gop.value_ptr.* = .{
|
gop.value_ptr.* = .{
|
||||||
.flags = symbol.flags,
|
.flags = symbol.flags,
|
||||||
@ -1004,7 +1001,7 @@ pub fn parse(
|
|||||||
}
|
}
|
||||||
const gop = try wasm.object_global_imports.getOrPut(gpa, name);
|
const gop = try wasm.object_global_imports.getOrPut(gpa, name);
|
||||||
if (gop.found_existing) {
|
if (gop.found_existing) {
|
||||||
const existing_ty = gop.value_ptr.flags.global_type.to();
|
const existing_ty = gop.value_ptr.type();
|
||||||
if (ptr.valtype != existing_ty.valtype) {
|
if (ptr.valtype != existing_ty.valtype) {
|
||||||
var err = try diags.addErrorWithNotes(2);
|
var err = try diags.addErrorWithNotes(2);
|
||||||
try err.addMsg("symbol '{s}' mismatching global types", .{name.slice(wasm)});
|
try err.addMsg("symbol '{s}' mismatching global types", .{name.slice(wasm)});
|
||||||
@ -1034,9 +1031,6 @@ pub fn parse(
|
|||||||
source_location.addNote(&err, "module '{s}' here", .{ptr.module_name.slice(wasm)});
|
source_location.addNote(&err, "module '{s}' here", .{ptr.module_name.slice(wasm)});
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (symbol.flags.binding == .strong) gop.value_ptr.flags.binding = .strong;
|
|
||||||
if (!symbol.flags.visibility_hidden) gop.value_ptr.flags.visibility_hidden = false;
|
|
||||||
if (symbol.flags.no_strip) gop.value_ptr.flags.no_strip = true;
|
|
||||||
} else {
|
} else {
|
||||||
gop.value_ptr.* = .{
|
gop.value_ptr.* = .{
|
||||||
.flags = symbol.flags,
|
.flags = symbol.flags,
|
||||||
@ -1117,6 +1111,11 @@ pub fn parse(
|
|||||||
gop.value_ptr.source_location = source_location;
|
gop.value_ptr.source_location = source_location;
|
||||||
gop.value_ptr.module_name = host_name;
|
gop.value_ptr.module_name = host_name;
|
||||||
gop.value_ptr.resolution = .fromObjectFunction(wasm, index);
|
gop.value_ptr.resolution = .fromObjectFunction(wasm, index);
|
||||||
|
gop.value_ptr.flags = symbol.flags;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (ptr.flags.binding == .weak) {
|
||||||
|
// Keep the existing one.
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
var err = try diags.addErrorWithNotes(2);
|
var err = try diags.addErrorWithNotes(2);
|
||||||
@ -1134,8 +1133,65 @@ pub fn parse(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
.global => |index| {
|
||||||
inline .global, .table => |i| {
|
const ptr = index.ptr(wasm);
|
||||||
|
ptr.name = symbol.name;
|
||||||
|
ptr.flags = symbol.flags;
|
||||||
|
if (symbol.flags.binding == .local) continue; // No participation in symbol resolution.
|
||||||
|
const new_ty = ptr.type();
|
||||||
|
const name = symbol.name.unwrap().?;
|
||||||
|
const gop = try wasm.object_global_imports.getOrPut(gpa, name);
|
||||||
|
if (gop.found_existing) {
|
||||||
|
const existing_ty = gop.value_ptr.type();
|
||||||
|
if (new_ty.valtype != existing_ty.valtype) {
|
||||||
|
var err = try diags.addErrorWithNotes(2);
|
||||||
|
try err.addMsg("symbol '{s}' mismatching global types", .{name.slice(wasm)});
|
||||||
|
gop.value_ptr.source_location.addNote(&err, "type {s} here", .{@tagName(existing_ty.valtype)});
|
||||||
|
source_location.addNote(&err, "type {s} here", .{@tagName(new_ty.valtype)});
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (new_ty.mutable != existing_ty.mutable) {
|
||||||
|
var err = try diags.addErrorWithNotes(2);
|
||||||
|
try err.addMsg("symbol '{s}' mismatching global mutability", .{name.slice(wasm)});
|
||||||
|
gop.value_ptr.source_location.addNote(&err, "{s} here", .{
|
||||||
|
if (existing_ty.mutable) "mutable" else "not mutable",
|
||||||
|
});
|
||||||
|
source_location.addNote(&err, "{s} here", .{
|
||||||
|
if (new_ty.mutable) "mutable" else "not mutable",
|
||||||
|
});
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (gop.value_ptr.resolution == .unresolved or gop.value_ptr.flags.binding == .weak) {
|
||||||
|
// Intentional: if they're both weak, take the last one.
|
||||||
|
gop.value_ptr.source_location = source_location;
|
||||||
|
gop.value_ptr.module_name = host_name;
|
||||||
|
gop.value_ptr.resolution = .fromObjectGlobal(wasm, index);
|
||||||
|
gop.value_ptr.flags = symbol.flags;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (ptr.flags.binding == .weak) {
|
||||||
|
// Keep the existing one.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
var err = try diags.addErrorWithNotes(2);
|
||||||
|
try err.addMsg("symbol collision: {s}", .{name.slice(wasm)});
|
||||||
|
gop.value_ptr.source_location.addNote(&err, "exported as {s} here", .{@tagName(existing_ty.valtype)});
|
||||||
|
source_location.addNote(&err, "exported as {s} here", .{@tagName(new_ty.valtype)});
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
gop.value_ptr.* = .{
|
||||||
|
.flags = symbol.flags,
|
||||||
|
.module_name = .none,
|
||||||
|
.source_location = source_location,
|
||||||
|
.resolution = .unresolved,
|
||||||
|
};
|
||||||
|
gop.value_ptr.flags.global_type = .{
|
||||||
|
.valtype = .from(new_ty.valtype),
|
||||||
|
.mutable = new_ty.mutable,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
},
|
||||||
|
.table => |i| {
|
||||||
const ptr = i.ptr(wasm);
|
const ptr = i.ptr(wasm);
|
||||||
ptr.name = symbol.name;
|
ptr.name = symbol.name;
|
||||||
ptr.flags = symbol.flags;
|
ptr.flags = symbol.flags;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user