mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 21:08:36 +00:00
stage2: fix ZIR support and C back end
This commit is contained in:
parent
b7a883b7d1
commit
331f6a07a9
@ -396,12 +396,21 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
|
||||
const branch = try branch_stack.addOne();
|
||||
branch.* = .{};
|
||||
|
||||
const scope_file = module_fn.owner_decl.scope.cast(Module.Scope.File).?;
|
||||
const tree = scope_file.contents.tree;
|
||||
const fn_proto = tree.root_node.decls()[module_fn.owner_decl.src_index].castTag(.FnProto).?;
|
||||
const block = fn_proto.body().?.castTag(.Block).?;
|
||||
const lbrace_src = tree.token_locs[block.lbrace].start;
|
||||
const rbrace_src = tree.token_locs[block.rbrace].start;
|
||||
const src_data: struct {lbrace_src: usize, rbrace_src: usize, source: []const u8} = blk: {
|
||||
if (module_fn.owner_decl.scope.cast(Module.Scope.File)) |scope_file| {
|
||||
const tree = scope_file.contents.tree;
|
||||
const fn_proto = tree.root_node.decls()[module_fn.owner_decl.src_index].castTag(.FnProto).?;
|
||||
const block = fn_proto.body().?.castTag(.Block).?;
|
||||
const lbrace_src = tree.token_locs[block.lbrace].start;
|
||||
const rbrace_src = tree.token_locs[block.rbrace].start;
|
||||
break :blk .{ .lbrace_src = lbrace_src, .rbrace_src = rbrace_src, .source = tree.source };
|
||||
} else if (module_fn.owner_decl.scope.cast(Module.Scope.ZIRModule)) |zir_module| {
|
||||
const byte_off = zir_module.contents.module.decls[module_fn.owner_decl.src_index].inst.src;
|
||||
break :blk .{ .lbrace_src = byte_off, .rbrace_src = byte_off, .source = zir_module.source.bytes };
|
||||
} else {
|
||||
unreachable;
|
||||
}
|
||||
};
|
||||
|
||||
var function = Self{
|
||||
.gpa = bin_file.allocator,
|
||||
@ -419,9 +428,9 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
|
||||
.src = src,
|
||||
.stack_align = undefined,
|
||||
.prev_di_pc = 0,
|
||||
.prev_di_src = lbrace_src,
|
||||
.rbrace_src = rbrace_src,
|
||||
.source = tree.source,
|
||||
.prev_di_src = src_data.lbrace_src,
|
||||
.rbrace_src = src_data.rbrace_src,
|
||||
.source = src_data.source,
|
||||
};
|
||||
defer function.exitlude_jump_relocs.deinit(bin_file.allocator);
|
||||
|
||||
|
||||
@ -89,17 +89,17 @@ fn genFn(file: *C, decl: *Decl) !void {
|
||||
const func: *Module.Fn = tv.val.cast(Value.Payload.Function).?.func;
|
||||
const instructions = func.analysis.success.instructions;
|
||||
if (instructions.len > 0) {
|
||||
try writer.writeAll("\n");
|
||||
for (instructions) |inst| {
|
||||
try writer.writeAll("\n ");
|
||||
switch (inst.tag) {
|
||||
.assembly => try genAsm(file, inst.castTag(.assembly).?, decl),
|
||||
.call => try genCall(file, inst.castTag(.call).?, decl),
|
||||
.ret => try genRet(file, inst.castTag(.ret).?, decl, tv.ty.fnReturnType()),
|
||||
.retvoid => try file.main.writer().print("return;", .{}),
|
||||
.retvoid => try file.main.writer().print(" return;\n", .{}),
|
||||
.dbg_stmt => try genDbgStmt(file, inst.castTag(.dbg_stmt).?, decl),
|
||||
else => |e| return file.fail(decl.src(), "TODO implement C codegen for {}", .{e}),
|
||||
}
|
||||
}
|
||||
try writer.writeAll("\n");
|
||||
}
|
||||
|
||||
try writer.writeAll("}\n\n");
|
||||
@ -112,6 +112,7 @@ fn genRet(file: *C, inst: *Inst.UnOp, decl: *Decl, expected_return_type: Type) !
|
||||
fn genCall(file: *C, inst: *Inst.Call, decl: *Decl) !void {
|
||||
const writer = file.main.writer();
|
||||
const header = file.header.writer();
|
||||
try writer.writeAll(" ");
|
||||
if (inst.func.castTag(.constant)) |func_inst| {
|
||||
if (func_inst.val.cast(Value.Payload.Function)) |func_val| {
|
||||
const target = func_val.func.owner_decl;
|
||||
@ -126,7 +127,7 @@ fn genCall(file: *C, inst: *Inst.Call, decl: *Decl) !void {
|
||||
try renderFunctionSignature(file, header, target);
|
||||
try header.writeAll(";\n");
|
||||
}
|
||||
try writer.print("{}();", .{tname});
|
||||
try writer.print("{}();\n", .{tname});
|
||||
} else {
|
||||
return file.fail(decl.src(), "TODO non-function call target?", .{});
|
||||
}
|
||||
@ -138,8 +139,13 @@ fn genCall(file: *C, inst: *Inst.Call, decl: *Decl) !void {
|
||||
}
|
||||
}
|
||||
|
||||
fn genDbgStmt(file: *C, inst: *Inst.NoOp, decl: *Decl) !void {
|
||||
// TODO emit #line directive here with line number and filename
|
||||
}
|
||||
|
||||
fn genAsm(file: *C, as: *Inst.Assembly, decl: *Decl) !void {
|
||||
const writer = file.main.writer();
|
||||
try writer.writeAll(" ");
|
||||
for (as.inputs) |i, index| {
|
||||
if (i[0] == '{' and i[i.len - 1] == '}') {
|
||||
const reg = i[1 .. i.len - 1];
|
||||
@ -187,5 +193,5 @@ fn genAsm(file: *C, as: *Inst.Assembly, decl: *Decl) !void {
|
||||
}
|
||||
}
|
||||
}
|
||||
try writer.writeAll(");");
|
||||
try writer.writeAll(");\n");
|
||||
}
|
||||
|
||||
@ -1825,15 +1825,24 @@ pub const File = struct {
|
||||
// For functions we need to add a prologue to the debug line program.
|
||||
try dbg_line_buffer.ensureCapacity(26);
|
||||
|
||||
const scope_file = decl.scope.cast(Module.Scope.File).?;
|
||||
const tree = scope_file.contents.tree;
|
||||
const file_ast_decls = tree.root_node.decls();
|
||||
// TODO Look into improving the performance here by adding a token-index-to-line
|
||||
// lookup table. Currently this involves scanning over the source code for newlines.
|
||||
const fn_proto = file_ast_decls[decl.src_index].castTag(.FnProto).?;
|
||||
const block = fn_proto.body().?.castTag(.Block).?;
|
||||
const line_delta = std.zig.lineDelta(tree.source, 0, tree.token_locs[block.lbrace].start);
|
||||
const casted_line_off = @intCast(u28, line_delta);
|
||||
const line_off: u28 = blk: {
|
||||
if (decl.scope.cast(Module.Scope.File)) |scope_file| {
|
||||
const tree = scope_file.contents.tree;
|
||||
const file_ast_decls = tree.root_node.decls();
|
||||
// TODO Look into improving the performance here by adding a token-index-to-line
|
||||
// lookup table. Currently this involves scanning over the source code for newlines.
|
||||
const fn_proto = file_ast_decls[decl.src_index].castTag(.FnProto).?;
|
||||
const block = fn_proto.body().?.castTag(.Block).?;
|
||||
const line_delta = std.zig.lineDelta(tree.source, 0, tree.token_locs[block.lbrace].start);
|
||||
break :blk @intCast(u28, line_delta);
|
||||
} else if (decl.scope.cast(Module.Scope.ZIRModule)) |zir_module| {
|
||||
const byte_off = zir_module.contents.module.decls[decl.src_index].inst.src;
|
||||
const line_delta = std.zig.lineDelta(zir_module.source.bytes, 0, byte_off);
|
||||
break :blk @intCast(u28, line_delta);
|
||||
} else {
|
||||
unreachable;
|
||||
}
|
||||
};
|
||||
|
||||
const ptr_width_bytes = self.ptrWidthBytes();
|
||||
dbg_line_buffer.appendSliceAssumeCapacity(&[_]u8{
|
||||
@ -1850,7 +1859,7 @@ pub const File = struct {
|
||||
// to this function's begin curly.
|
||||
assert(self.getRelocDbgLineOff() == dbg_line_buffer.items.len);
|
||||
// Here we use a ULEB128-fixed-4 to make sure this field can be overwritten later.
|
||||
leb128.writeUnsignedFixed(4, dbg_line_buffer.addManyAsArrayAssumeCapacity(4), casted_line_off);
|
||||
leb128.writeUnsignedFixed(4, dbg_line_buffer.addManyAsArrayAssumeCapacity(4), line_off);
|
||||
|
||||
dbg_line_buffer.appendAssumeCapacity(DW.LNS_set_file);
|
||||
assert(self.getRelocDbgFileIndex() == dbg_line_buffer.items.len);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user