mirror of
https://github.com/ziglang/zig.git
synced 2026-02-14 05:20:34 +00:00
stage2: lay the groundwork in prep for extern fn
This commit lays the groundwork in preparation for implementing handling of extern functions in various backends.
This commit is contained in:
parent
a021c7b1b2
commit
5487dd13ea
@ -22,6 +22,7 @@ const ast = std.zig.ast;
|
||||
const trace = @import("tracy.zig").trace;
|
||||
const astgen = @import("astgen.zig");
|
||||
const zir_sema = @import("zir_sema.zig");
|
||||
const target_util = @import("target.zig");
|
||||
|
||||
const default_eval_branch_quota = 1000;
|
||||
|
||||
@ -1109,8 +1110,48 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool {
|
||||
if (fn_proto.getVarArgsToken()) |var_args_token| {
|
||||
return self.failTok(&fn_type_scope.base, var_args_token, "TODO implement var args", .{});
|
||||
}
|
||||
if (fn_proto.getLibName()) |lib_name| {
|
||||
return self.failNode(&fn_type_scope.base, lib_name, "TODO implement function library name", .{});
|
||||
if (fn_proto.getLibName()) |lib_name| blk: {
|
||||
const lib_name_str = mem.trim(u8, tree.tokenSlice(lib_name.firstToken()), "\""); // TODO: call identifierTokenString
|
||||
log.debug("extern fn symbol expected in lib '{s}'", .{lib_name_str});
|
||||
const target = self.comp.getTarget();
|
||||
if (target_util.is_libc_lib_name(target, lib_name_str)) {
|
||||
if (!self.comp.bin_file.options.link_libc) {
|
||||
return self.failNode(
|
||||
&fn_type_scope.base,
|
||||
lib_name,
|
||||
"dependency on libc must be explicitly specified in the build command",
|
||||
.{},
|
||||
);
|
||||
}
|
||||
break :blk;
|
||||
}
|
||||
if (target_util.is_libcpp_lib_name(target, lib_name_str)) {
|
||||
if (!self.comp.bin_file.options.link_libcpp) {
|
||||
return self.failNode(
|
||||
&fn_type_scope.base,
|
||||
lib_name,
|
||||
"dependency on libc++ must be explicitly specified in the build command",
|
||||
.{},
|
||||
);
|
||||
}
|
||||
break :blk;
|
||||
}
|
||||
if (!target.isWasm() and !self.comp.bin_file.options.pic) {
|
||||
return self.failNode(
|
||||
&fn_type_scope.base,
|
||||
lib_name,
|
||||
"dependency on dynamic library '{s}' requires enabling Position Independent Code. Fixed by `-l{s}` or `-fPIC`.",
|
||||
.{ lib_name, lib_name },
|
||||
);
|
||||
}
|
||||
self.comp.stage1AddLinkLib(lib_name_str) catch |err| {
|
||||
return self.failNode(
|
||||
&fn_type_scope.base,
|
||||
lib_name,
|
||||
"unable to add link lib '{s}': {s}",
|
||||
.{ lib_name, @errorName(err) },
|
||||
);
|
||||
};
|
||||
}
|
||||
if (fn_proto.getAlignExpr()) |align_expr| {
|
||||
return self.failNode(&fn_type_scope.base, align_expr, "TODO implement function align expression", .{});
|
||||
|
||||
@ -1602,6 +1602,8 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
|
||||
try self.code.ensureCapacity(self.code.items.len + 7);
|
||||
self.code.appendSliceAssumeCapacity(&[3]u8{ 0xff, 0x14, 0x25 });
|
||||
mem.writeIntLittle(u32, self.code.addManyAsArrayAssumeCapacity(4), got_addr);
|
||||
} else if (func_value.castTag(.extern_fn)) |_| {
|
||||
return self.fail(inst.base.src, "TODO implement calling extern functions", .{});
|
||||
} else {
|
||||
return self.fail(inst.base.src, "TODO implement calling bitcasted functions", .{});
|
||||
}
|
||||
@ -1628,6 +1630,8 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
|
||||
|
||||
try self.genSetReg(inst.base.src, .ra, .{ .memory = got_addr });
|
||||
mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.jalr(.ra, 0, .ra).toU32());
|
||||
} else if (func_value.castTag(.extern_fn)) |_| {
|
||||
return self.fail(inst.base.src, "TODO implement calling extern functions", .{});
|
||||
} else {
|
||||
return self.fail(inst.base.src, "TODO implement calling bitcasted functions", .{});
|
||||
}
|
||||
@ -1672,6 +1676,8 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
|
||||
else => return self.fail(inst.base.src, "TODO implement fn call with non-void return value", .{}),
|
||||
}
|
||||
}
|
||||
} else if (func_value.castTag(.extern_fn)) |_| {
|
||||
return self.fail(inst.base.src, "TODO implement calling extern functions", .{});
|
||||
} else {
|
||||
return self.fail(inst.base.src, "TODO implement calling bitcasted functions", .{});
|
||||
}
|
||||
@ -1733,6 +1739,8 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
|
||||
writeInt(u32, try self.code.addManyAsArray(4), Instruction.mov(.al, .lr, Instruction.Operand.reg(.pc, Instruction.Operand.Shift.none)).toU32());
|
||||
writeInt(u32, try self.code.addManyAsArray(4), Instruction.bx(.al, .lr).toU32());
|
||||
}
|
||||
} else if (func_value.castTag(.extern_fn)) |_| {
|
||||
return self.fail(inst.base.src, "TODO implement calling extern functions", .{});
|
||||
} else {
|
||||
return self.fail(inst.base.src, "TODO implement calling bitcasted functions", .{});
|
||||
}
|
||||
@ -1787,6 +1795,8 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
|
||||
try self.genSetReg(inst.base.src, .x30, .{ .memory = got_addr });
|
||||
|
||||
writeInt(u32, try self.code.addManyAsArray(4), Instruction.blr(.x30).toU32());
|
||||
} else if (func_value.castTag(.extern_fn)) |_| {
|
||||
return self.fail(inst.base.src, "TODO implement calling extern functions", .{});
|
||||
} else {
|
||||
return self.fail(inst.base.src, "TODO implement calling bitcasted functions", .{});
|
||||
}
|
||||
@ -1849,6 +1859,8 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
|
||||
},
|
||||
else => unreachable, // unsupported architecture on MachO
|
||||
}
|
||||
} else if (func_value.castTag(.extern_fn)) |_| {
|
||||
return self.fail(inst.base.src, "TODO implement calling extern functions", .{});
|
||||
} else {
|
||||
return self.fail(inst.base.src, "TODO implement calling bitcasted functions", .{});
|
||||
}
|
||||
|
||||
@ -662,10 +662,14 @@ pub fn updateDecl(self: *Coff, module: *Module, decl: *Module.Decl) !void {
|
||||
if (build_options.have_llvm)
|
||||
if (self.llvm_ir_module) |llvm_ir_module| return try llvm_ir_module.updateDecl(module, decl);
|
||||
|
||||
const typed_value = decl.typed_value.most_recent.typed_value;
|
||||
if (typed_value.val.tag() == .extern_fn) {
|
||||
return; // TODO Should we do more when front-end analyzed extern decl?
|
||||
}
|
||||
|
||||
var code_buffer = std.ArrayList(u8).init(self.base.allocator);
|
||||
defer code_buffer.deinit();
|
||||
|
||||
const typed_value = decl.typed_value.most_recent.typed_value;
|
||||
const res = try codegen.generateSymbol(&self.base, decl.src(), typed_value, &code_buffer, .none);
|
||||
const code = switch (res) {
|
||||
.externally_managed => |x| x,
|
||||
|
||||
@ -2157,6 +2157,11 @@ pub fn updateDecl(self: *Elf, module: *Module, decl: *Module.Decl) !void {
|
||||
if (build_options.have_llvm)
|
||||
if (self.llvm_ir_module) |llvm_ir_module| return try llvm_ir_module.updateDecl(module, decl);
|
||||
|
||||
const typed_value = decl.typed_value.most_recent.typed_value;
|
||||
if (typed_value.val.tag() == .extern_fn) {
|
||||
return; // TODO Should we do more when front-end analyzed extern decl?
|
||||
}
|
||||
|
||||
var code_buffer = std.ArrayList(u8).init(self.base.allocator);
|
||||
defer code_buffer.deinit();
|
||||
|
||||
@ -2175,7 +2180,6 @@ pub fn updateDecl(self: *Elf, module: *Module, decl: *Module.Decl) !void {
|
||||
dbg_info_type_relocs.deinit(self.base.allocator);
|
||||
}
|
||||
|
||||
const typed_value = decl.typed_value.most_recent.typed_value;
|
||||
const is_fn: bool = switch (typed_value.ty.zigTypeTag()) {
|
||||
.Fn => true,
|
||||
else => false,
|
||||
|
||||
@ -1118,6 +1118,11 @@ pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void {
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
const typed_value = decl.typed_value.most_recent.typed_value;
|
||||
if (typed_value.val.tag() == .extern_fn) {
|
||||
return; // TODO Should we do more when front-end analyzed extern decl?
|
||||
}
|
||||
|
||||
var code_buffer = std.ArrayList(u8).init(self.base.allocator);
|
||||
defer code_buffer.deinit();
|
||||
|
||||
@ -1134,7 +1139,6 @@ pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void {
|
||||
}
|
||||
}
|
||||
|
||||
const typed_value = decl.typed_value.most_recent.typed_value;
|
||||
const res = if (debug_buffers) |*dbg|
|
||||
try codegen.generateSymbol(&self.base, decl.src(), typed_value, &code_buffer, .{
|
||||
.dwarf = .{
|
||||
|
||||
@ -100,8 +100,11 @@ pub fn deinit(self: *Wasm) void {
|
||||
// Generate code for the Decl, storing it in memory to be later written to
|
||||
// the file on flush().
|
||||
pub fn updateDecl(self: *Wasm, module: *Module, decl: *Module.Decl) !void {
|
||||
if (decl.typed_value.most_recent.typed_value.ty.zigTypeTag() != .Fn)
|
||||
const typed_value = decl.typed_value.most_recent.typed_value;
|
||||
if (typed_value.ty.zigTypeTag() != .Fn)
|
||||
return error.TODOImplementNonFnDeclsForWasm;
|
||||
if (typed_value.val.tag() == .extern_fn)
|
||||
return error.TODOImplementExternFnDeclsForWasm;
|
||||
|
||||
if (decl.fn_link.wasm) |*fn_data| {
|
||||
fn_data.functype.items.len = 0;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user