Commit a4895f3c42
Changed files (3)
src
link
src/link/Wasm/Object.zig
@@ -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;
src/link/Wasm.zig
@@ -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,
src/Compilation.zig
@@ -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) {