aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/arch/wasm/CodeGen.zig23
-rw-r--r--src/link.zig2
-rw-r--r--src/link/Wasm.zig96
-rw-r--r--src/link/Wasm/Object.zig1
4 files changed, 64 insertions, 58 deletions
diff --git a/src/arch/wasm/CodeGen.zig b/src/arch/wasm/CodeGen.zig
index ca571370ad..4c6a9641eb 100644
--- a/src/arch/wasm/CodeGen.zig
+++ b/src/arch/wasm/CodeGen.zig
@@ -1318,13 +1318,14 @@ pub const DeclGen = struct {
if (decl.link.wasm.sym_index == 0) {
try writer.writeIntLittle(u32, 0);
} else {
- try writer.writeIntLittle(u32, try self.bin_file.getDeclVAddr(
- self.decl, // parent decl that owns the atom of the symbol
- self.symbol_index, // source symbol index
- decl, // target decl that contains the target symbol
- @intCast(u32, self.code.items.len), // offset
- @intCast(u32, offset), // addend
- ));
+ try writer.writeIntLittle(u32, @intCast(u32, try self.bin_file.getDeclVAddr(
+ decl,
+ .{
+ .parent_atom_index = self.symbol_index,
+ .offset = self.code.items.len,
+ .addend = @intCast(u32, offset),
+ },
+ )));
}
return Result{ .appended = {} };
}
@@ -1809,8 +1810,12 @@ fn airCall(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
if (func_val.castTag(.function)) |func| {
break :blk func.data.owner_decl;
- } else if (func_val.castTag(.extern_fn)) |ext_fn| {
- break :blk ext_fn.data.owner_decl;
+ } else if (func_val.castTag(.extern_fn)) |extern_fn| {
+ const ext_decl = extern_fn.data.owner_decl;
+ var func_type = try genFunctype(self.gpa, ext_decl.ty, self.target);
+ defer func_type.deinit(self.gpa);
+ ext_decl.fn_link.wasm.type_index = try self.bin_file.putOrGetFuncType(func_type);
+ break :blk ext_decl;
} else if (func_val.castTag(.decl_ref)) |decl_ref| {
break :blk decl_ref.data;
}
diff --git a/src/link.zig b/src/link.zig
index 996622443a..6e33b11669 100644
--- a/src/link.zig
+++ b/src/link.zig
@@ -702,7 +702,7 @@ pub const File = struct {
.macho => return @fieldParentPtr(MachO, "base", base).getDeclVAddr(decl, reloc_info),
.plan9 => return @fieldParentPtr(Plan9, "base", base).getDeclVAddr(decl, reloc_info),
.c => unreachable,
- .wasm => unreachable,
+ .wasm => return @fieldParentPtr(Wasm, "base", base).getDeclVAddr(decl, reloc_info),
.spirv => unreachable,
.nvptx => unreachable,
}
diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig
index 7026418dd5..a3704789e2 100644
--- a/src/link/Wasm.zig
+++ b/src/link/Wasm.zig
@@ -14,6 +14,7 @@ const Atom = @import("Wasm/Atom.zig");
const Module = @import("../Module.zig");
const Compilation = @import("../Compilation.zig");
const CodeGen = @import("../arch/wasm/CodeGen.zig");
+const codegen = @import("../codegen.zig");
const link = @import("../link.zig");
const lldMain = @import("../main.zig").lldMain;
const trace = @import("../tracy.zig").trace;
@@ -488,10 +489,8 @@ pub fn allocateDeclIndexes(self: *Wasm, decl: *Module.Decl) !void {
self.symbols.appendAssumeCapacity(symbol);
}
- try self.resolved_symbols.putNoClobber(self.base.allocator, .{
- .index = atom.sym_index,
- .file = null,
- }, {});
+ try self.resolved_symbols.putNoClobber(self.base.allocator, atom.symbolLoc(), {});
+ try self.symbol_atom.putNoClobber(self.base.allocator, atom.symbolLoc(), atom);
}
pub fn updateFunc(self: *Wasm, module: *Module, func: *Module.Fn, air: Air, liveness: Liveness) !void {
@@ -506,7 +505,7 @@ pub fn updateFunc(self: *Wasm, module: *Module, func: *Module.Fn, air: Air, live
decl.link.wasm.clear();
- var codegen: CodeGen = .{
+ var codegen_: CodeGen = .{
.gpa = self.base.allocator,
.air = air,
.liveness = liveness,
@@ -519,18 +518,18 @@ pub fn updateFunc(self: *Wasm, module: *Module, func: *Module.Fn, air: Air, live
.bin_file = self,
.module = module,
};
- defer codegen.deinit();
+ defer codegen_.deinit();
// generate the 'code' section for the function declaration
- codegen.genFunc() catch |err| switch (err) {
+ codegen_.genFunc() catch |err| switch (err) {
error.CodegenFail => {
decl.analysis = .codegen_failure;
- try module.failed_decls.put(module.gpa, decl, codegen.err_msg);
+ try module.failed_decls.put(module.gpa, decl, codegen_.err_msg);
return;
},
else => |e| return e,
};
- return self.finishUpdateDecl(decl, codegen.code.items);
+ return self.finishUpdateDecl(decl, codegen_.code.items);
}
// Generate code for the Decl, storing it in memory to be later written to
@@ -547,31 +546,37 @@ pub fn updateDecl(self: *Wasm, module: *Module, decl: *Module.Decl) !void {
decl.link.wasm.clear();
+ if (decl.isExtern()) {
+ return self.addOrUpdateImport(decl);
+ }
+
+ if (decl.val.castTag(.function)) |_| {
+ return;
+ } else if (decl.val.castTag(.extern_fn)) |_| {
+ return;
+ }
+ const val = if (decl.val.castTag(.variable)) |payload| payload.data.init else decl.val;
+
var code_writer = std.ArrayList(u8).init(self.base.allocator);
defer code_writer.deinit();
- var decl_gen: CodeGen.DeclGen = .{
- .gpa = self.base.allocator,
- .decl = decl,
- .symbol_index = decl.link.wasm.sym_index,
- .bin_file = self,
- .err_msg = undefined,
- .code = &code_writer,
- .module = module,
- };
- // generate the 'code' section for the function declaration
- const result = decl_gen.genDecl() catch |err| switch (err) {
- error.CodegenFail => {
+ const res = try codegen.generateSymbol(
+ &self.base,
+ decl.srcLoc(),
+ .{ .ty = decl.ty, .val = val },
+ &code_writer,
+ .none,
+ .{ .parent_atom_index = decl.link.wasm.sym_index },
+ );
+
+ const code = switch (res) {
+ .externally_managed => |x| x,
+ .appended => code_writer.items,
+ .fail => |em| {
decl.analysis = .codegen_failure;
- try module.failed_decls.put(module.gpa, decl, decl_gen.err_msg);
+ try module.failed_decls.put(module.gpa, decl, em);
return;
},
- else => |e| return e,
- };
-
- const code = switch (result) {
- .externally_managed => |data| data,
- .appended => code_writer.items,
};
return self.finishUpdateDecl(decl, code);
@@ -624,10 +629,8 @@ pub fn lowerUnnamedConst(self: *Wasm, decl: *Module.Decl, tv: TypedValue) !u32 {
atom.sym_index = @intCast(u32, self.symbols.items.len);
self.symbols.appendAssumeCapacity(symbol);
}
- try self.resolved_symbols.putNoClobber(self.base.allocator, .{
- .file = null,
- .index = atom.sym_index,
- }, {});
+ try self.resolved_symbols.putNoClobber(self.base.allocator, atom.symbolLoc(), {});
+ try self.symbol_atom.putNoClobber(self.base.allocator, atom.symbolLoc(), atom);
var value_bytes = std.ArrayList(u8).init(self.base.allocator);
defer value_bytes.deinit();
@@ -665,35 +668,31 @@ pub fn lowerUnnamedConst(self: *Wasm, decl: *Module.Decl, tv: TypedValue) !u32 {
/// Returns the given pointer address
pub fn getDeclVAddr(
self: *Wasm,
- decl: *Module.Decl,
- symbol_index: u32,
- target_decl: *Module.Decl,
- offset: u32,
- addend: u32,
-) !u32 {
- const target_symbol_index = target_decl.link.wasm.sym_index;
+ decl: *const Module.Decl,
+ reloc_info: link.File.RelocInfo,
+) !u64 {
+ const target_symbol_index = decl.link.wasm.sym_index;
assert(target_symbol_index != 0);
- assert(symbol_index != 0);
-
- const atom = decl.link.wasm.symbolAtom(symbol_index);
+ assert(reloc_info.parent_atom_index != 0);
+ const atom = self.symbol_atom.get(.{ .file = null, .index = reloc_info.parent_atom_index }).?;
const is_wasm32 = self.base.options.target.cpu.arch == .wasm32;
- if (target_decl.ty.zigTypeTag() == .Fn) {
- assert(addend == 0); // addend not allowed for function relocations
+ if (decl.ty.zigTypeTag() == .Fn) {
+ assert(reloc_info.addend == 0); // addend not allowed for function relocations
// We found a function pointer, so add it to our table,
// as function pointers are not allowed to be stored inside the data section.
// They are instead stored in a function table which are called by index.
try self.addTableFunction(target_symbol_index);
try atom.relocs.append(self.base.allocator, .{
.index = target_symbol_index,
- .offset = offset,
+ .offset = @intCast(u32, reloc_info.offset),
.relocation_type = if (is_wasm32) .R_WASM_TABLE_INDEX_I32 else .R_WASM_TABLE_INDEX_I64,
});
} else {
try atom.relocs.append(self.base.allocator, .{
.index = target_symbol_index,
- .offset = offset,
+ .offset = @intCast(u32, reloc_info.offset),
.relocation_type = if (is_wasm32) .R_WASM_MEMORY_ADDR_I32 else .R_WASM_MEMORY_ADDR_I64,
- .addend = addend,
+ .addend = reloc_info.addend,
});
}
// we do not know the final address at this point,
@@ -823,12 +822,14 @@ pub fn freeDecl(self: *Wasm, decl: *Module.Decl) void {
local_symbol.tag = .dead; // also for any local symbol
self.symbols_free_list.append(self.base.allocator, local_atom.sym_index) catch {};
assert(self.resolved_symbols.swapRemove(local_atom.symbolLoc()));
+ assert(self.symbol_atom.remove(local_atom.symbolLoc()));
}
if (decl.isExtern()) {
assert(self.imports.remove(atom.symbolLoc()));
}
assert(self.resolved_symbols.swapRemove(atom.symbolLoc()));
+ assert(self.symbol_atom.remove(atom.symbolLoc()));
atom.deinit(self.base.allocator);
}
@@ -988,7 +989,6 @@ fn allocateAtoms(self: *Wasm) !void {
atom.size,
});
offset += atom.size;
- try self.symbol_atom.putNoClobber(self.base.allocator, symbol_loc, atom);
atom = atom.next orelse break;
}
}
diff --git a/src/link/Wasm/Object.zig b/src/link/Wasm/Object.zig
index b0ec835a86..011ec2e9e4 100644
--- a/src/link/Wasm/Object.zig
+++ b/src/link/Wasm/Object.zig
@@ -861,6 +861,7 @@ pub fn parseIntoAtoms(self: *Object, gpa: Allocator, object_index: u16, wasm_bin
}
try atom.code.appendSlice(gpa, relocatable_data.data[0..relocatable_data.size]);
+ try wasm_bin.symbol_atom.putNoClobber(gpa, atom.symbolLoc(), atom);
const segment: *Wasm.Segment = &wasm_bin.segments.items[final_index];
segment.alignment = std.math.max(segment.alignment, atom.alignment);