| author | |
| committer | |
| log | 331f6a07a98206c3b5c096e73860ef1b7a3dfe85 |
| tree | ac5a8794de5467d828e375297e92b52c0ee40614 |
| parent | b7a883b7d1247e9342805a8d06e70fd4d02f11b3 |
3 files changed, 48 insertions(+), 24 deletions(-)
src-self-hosted/codegen.zig+18-9| ... | ... | @@ -396,12 +396,21 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { |
| 396 | 396 | const branch = try branch_stack.addOne(); |
| 397 | 397 | branch.* = .{}; |
| 398 | 398 | |
| 399 | const scope_file = module_fn.owner_decl.scope.cast(Module.Scope.File).?; | |
| 400 | const tree = scope_file.contents.tree; | |
| 401 | const fn_proto = tree.root_node.decls()[module_fn.owner_decl.src_index].castTag(.FnProto).?; | |
| 402 | const block = fn_proto.body().?.castTag(.Block).?; | |
| 403 | const lbrace_src = tree.token_locs[block.lbrace].start; | |
| 404 | const rbrace_src = tree.token_locs[block.rbrace].start; | |
| 399 | const src_data: struct {lbrace_src: usize, rbrace_src: usize, source: []const u8} = blk: { | |
| 400 | if (module_fn.owner_decl.scope.cast(Module.Scope.File)) |scope_file| { | |
| 401 | const tree = scope_file.contents.tree; | |
| 402 | const fn_proto = tree.root_node.decls()[module_fn.owner_decl.src_index].castTag(.FnProto).?; | |
| 403 | const block = fn_proto.body().?.castTag(.Block).?; | |
| 404 | const lbrace_src = tree.token_locs[block.lbrace].start; | |
| 405 | const rbrace_src = tree.token_locs[block.rbrace].start; | |
| 406 | break :blk .{ .lbrace_src = lbrace_src, .rbrace_src = rbrace_src, .source = tree.source }; | |
| 407 | } else if (module_fn.owner_decl.scope.cast(Module.Scope.ZIRModule)) |zir_module| { | |
| 408 | const byte_off = zir_module.contents.module.decls[module_fn.owner_decl.src_index].inst.src; | |
| 409 | break :blk .{ .lbrace_src = byte_off, .rbrace_src = byte_off, .source = zir_module.source.bytes }; | |
| 410 | } else { | |
| 411 | unreachable; | |
| 412 | } | |
| 413 | }; | |
| 405 | 414 | |
| 406 | 415 | var function = Self{ |
| 407 | 416 | .gpa = bin_file.allocator, |
| ... | ... | @@ -419,9 +428,9 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { |
| 419 | 428 | .src = src, |
| 420 | 429 | .stack_align = undefined, |
| 421 | 430 | .prev_di_pc = 0, |
| 422 | .prev_di_src = lbrace_src, | |
| 423 | .rbrace_src = rbrace_src, | |
| 424 | .source = tree.source, | |
| 431 | .prev_di_src = src_data.lbrace_src, | |
| 432 | .rbrace_src = src_data.rbrace_src, | |
| 433 | .source = src_data.source, | |
| 425 | 434 | }; |
| 426 | 435 | defer function.exitlude_jump_relocs.deinit(bin_file.allocator); |
| 427 | 436 |
src-self-hosted/codegen/c.zig+11-5| ... | ... | @@ -89,17 +89,17 @@ fn genFn(file: *C, decl: *Decl) !void { |
| 89 | 89 | const func: *Module.Fn = tv.val.cast(Value.Payload.Function).?.func; |
| 90 | 90 | const instructions = func.analysis.success.instructions; |
| 91 | 91 | if (instructions.len > 0) { |
| 92 | try writer.writeAll("\n"); | |
| 92 | 93 | for (instructions) |inst| { |
| 93 | try writer.writeAll("\n "); | |
| 94 | 94 | switch (inst.tag) { |
| 95 | 95 | .assembly => try genAsm(file, inst.castTag(.assembly).?, decl), |
| 96 | 96 | .call => try genCall(file, inst.castTag(.call).?, decl), |
| 97 | 97 | .ret => try genRet(file, inst.castTag(.ret).?, decl, tv.ty.fnReturnType()), |
| 98 | .retvoid => try file.main.writer().print("return;", .{}), | |
| 98 | .retvoid => try file.main.writer().print(" return;\n", .{}), | |
| 99 | .dbg_stmt => try genDbgStmt(file, inst.castTag(.dbg_stmt).?, decl), | |
| 99 | 100 | else => |e| return file.fail(decl.src(), "TODO implement C codegen for {}", .{e}), |
| 100 | 101 | } |
| 101 | 102 | } |
| 102 | try writer.writeAll("\n"); | |
| 103 | 103 | } |
| 104 | 104 | |
| 105 | 105 | try writer.writeAll("}\n\n"); |
| ... | ... | @@ -112,6 +112,7 @@ fn genRet(file: *C, inst: *Inst.UnOp, decl: *Decl, expected_return_type: Type) ! |
| 112 | 112 | fn genCall(file: *C, inst: *Inst.Call, decl: *Decl) !void { |
| 113 | 113 | const writer = file.main.writer(); |
| 114 | 114 | const header = file.header.writer(); |
| 115 | try writer.writeAll(" "); | |
| 115 | 116 | if (inst.func.castTag(.constant)) |func_inst| { |
| 116 | 117 | if (func_inst.val.cast(Value.Payload.Function)) |func_val| { |
| 117 | 118 | const target = func_val.func.owner_decl; |
| ... | ... | @@ -126,7 +127,7 @@ fn genCall(file: *C, inst: *Inst.Call, decl: *Decl) !void { |
| 126 | 127 | try renderFunctionSignature(file, header, target); |
| 127 | 128 | try header.writeAll(";\n"); |
| 128 | 129 | } |
| 129 | try writer.print("{}();", .{tname}); | |
| 130 | try writer.print("{}();\n", .{tname}); | |
| 130 | 131 | } else { |
| 131 | 132 | return file.fail(decl.src(), "TODO non-function call target?", .{}); |
| 132 | 133 | } |
| ... | ... | @@ -138,8 +139,13 @@ fn genCall(file: *C, inst: *Inst.Call, decl: *Decl) !void { |
| 138 | 139 | } |
| 139 | 140 | } |
| 140 | 141 | |
| 142 | fn genDbgStmt(file: *C, inst: *Inst.NoOp, decl: *Decl) !void { | |
| 143 | // TODO emit #line directive here with line number and filename | |
| 144 | } | |
| 145 | ||
| 141 | 146 | fn genAsm(file: *C, as: *Inst.Assembly, decl: *Decl) !void { |
| 142 | 147 | const writer = file.main.writer(); |
| 148 | try writer.writeAll(" "); | |
| 143 | 149 | for (as.inputs) |i, index| { |
| 144 | 150 | if (i[0] == '{' and i[i.len - 1] == '}') { |
| 145 | 151 | const reg = i[1 .. i.len - 1]; |
| ... | ... | @@ -187,5 +193,5 @@ fn genAsm(file: *C, as: *Inst.Assembly, decl: *Decl) !void { |
| 187 | 193 | } |
| 188 | 194 | } |
| 189 | 195 | } |
| 190 | try writer.writeAll(");"); | |
| 196 | try writer.writeAll(");\n"); | |
| 191 | 197 | } |
src-self-hosted/link.zig+19-10| ... | ... | @@ -1825,15 +1825,24 @@ pub const File = struct { |
| 1825 | 1825 | // For functions we need to add a prologue to the debug line program. |
| 1826 | 1826 | try dbg_line_buffer.ensureCapacity(26); |
| 1827 | 1827 | |
| 1828 | const scope_file = decl.scope.cast(Module.Scope.File).?; | |
| 1829 | const tree = scope_file.contents.tree; | |
| 1830 | const file_ast_decls = tree.root_node.decls(); | |
| 1831 | // TODO Look into improving the performance here by adding a token-index-to-line | |
| 1832 | // lookup table. Currently this involves scanning over the source code for newlines. | |
| 1833 | const fn_proto = file_ast_decls[decl.src_index].castTag(.FnProto).?; | |
| 1834 | const block = fn_proto.body().?.castTag(.Block).?; | |
| 1835 | const line_delta = std.zig.lineDelta(tree.source, 0, tree.token_locs[block.lbrace].start); | |
| 1836 | const casted_line_off = @intCast(u28, line_delta); | |
| 1828 | const line_off: u28 = blk: { | |
| 1829 | if (decl.scope.cast(Module.Scope.File)) |scope_file| { | |
| 1830 | const tree = scope_file.contents.tree; | |
| 1831 | const file_ast_decls = tree.root_node.decls(); | |
| 1832 | // TODO Look into improving the performance here by adding a token-index-to-line | |
| 1833 | // lookup table. Currently this involves scanning over the source code for newlines. | |
| 1834 | const fn_proto = file_ast_decls[decl.src_index].castTag(.FnProto).?; | |
| 1835 | const block = fn_proto.body().?.castTag(.Block).?; | |
| 1836 | const line_delta = std.zig.lineDelta(tree.source, 0, tree.token_locs[block.lbrace].start); | |
| 1837 | break :blk @intCast(u28, line_delta); | |
| 1838 | } else if (decl.scope.cast(Module.Scope.ZIRModule)) |zir_module| { | |
| 1839 | const byte_off = zir_module.contents.module.decls[decl.src_index].inst.src; | |
| 1840 | const line_delta = std.zig.lineDelta(zir_module.source.bytes, 0, byte_off); | |
| 1841 | break :blk @intCast(u28, line_delta); | |
| 1842 | } else { | |
| 1843 | unreachable; | |
| 1844 | } | |
| 1845 | }; | |
| 1837 | 1846 | |
| 1838 | 1847 | const ptr_width_bytes = self.ptrWidthBytes(); |
| 1839 | 1848 | dbg_line_buffer.appendSliceAssumeCapacity(&[_]u8{ |
| ... | ... | @@ -1850,7 +1859,7 @@ pub const File = struct { |
| 1850 | 1859 | // to this function's begin curly. |
| 1851 | 1860 | assert(self.getRelocDbgLineOff() == dbg_line_buffer.items.len); |
| 1852 | 1861 | // Here we use a ULEB128-fixed-4 to make sure this field can be overwritten later. |
| 1853 | leb128.writeUnsignedFixed(4, dbg_line_buffer.addManyAsArrayAssumeCapacity(4), casted_line_off); | |
| 1862 | leb128.writeUnsignedFixed(4, dbg_line_buffer.addManyAsArrayAssumeCapacity(4), line_off); | |
| 1854 | 1863 | |
| 1855 | 1864 | dbg_line_buffer.appendAssumeCapacity(DW.LNS_set_file); |
| 1856 | 1865 | assert(self.getRelocDbgFileIndex() == dbg_line_buffer.items.len); |