mirror of
https://github.com/ziglang/zig.git
synced 2025-12-15 18:53:07 +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_out_path = options.pdb_out_path,
|
||||
.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) {
|
||||
|
||||
@ -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 });
|
||||
}
|
||||
|
||||
@ -1154,9 +1154,13 @@ pub const GlobalImport = extern struct {
|
||||
}
|
||||
|
||||
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 {
|
||||
@ -1169,6 +1173,10 @@ pub const ObjectGlobal = extern struct {
|
||||
offset: u32,
|
||||
size: u32,
|
||||
|
||||
pub fn @"type"(og: *const ObjectGlobal) Type {
|
||||
return og.flags.global_type.to();
|
||||
}
|
||||
|
||||
pub const Type = struct {
|
||||
valtype: std.wasm.Valtype,
|
||||
mutable: bool,
|
||||
|
||||
@ -982,9 +982,6 @@ pub fn parse(
|
||||
source_location.addNote(&err, "module '{s}' here", .{ptr.module_name.slice(wasm)});
|
||||
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 {
|
||||
gop.value_ptr.* = .{
|
||||
.flags = symbol.flags,
|
||||
@ -1004,7 +1001,7 @@ pub fn parse(
|
||||
}
|
||||
const gop = try wasm.object_global_imports.getOrPut(gpa, name);
|
||||
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) {
|
||||
var err = try diags.addErrorWithNotes(2);
|
||||
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)});
|
||||
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 {
|
||||
gop.value_ptr.* = .{
|
||||
.flags = symbol.flags,
|
||||
@ -1117,6 +1111,11 @@ pub fn parse(
|
||||
gop.value_ptr.source_location = source_location;
|
||||
gop.value_ptr.module_name = host_name;
|
||||
gop.value_ptr.resolution = .fromObjectFunction(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);
|
||||
@ -1134,8 +1133,65 @@ pub fn parse(
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
inline .global, .table => |i| {
|
||||
.global => |index| {
|
||||
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);
|
||||
ptr.name = symbol.name;
|
||||
ptr.flags = symbol.flags;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user