diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2021-03-20 17:09:06 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2021-03-20 17:09:06 -0700 |
| commit | 50010447bde42ca96aff63e0a620f941464f2eae (patch) | |
| tree | 620e963139761ede5900e91f7ebbbe4373a7b864 /src | |
| parent | 907142a03627f170ef1e721e996a8759952fb58f (diff) | |
| download | zig-50010447bde42ca96aff63e0a620f941464f2eae.tar.gz zig-50010447bde42ca96aff63e0a620f941464f2eae.zip | |
astgen: implement function calls
Diffstat (limited to 'src')
| -rw-r--r-- | src/Module.zig | 96 | ||||
| -rw-r--r-- | src/Sema.zig | 2 | ||||
| -rw-r--r-- | src/astgen.zig | 21 | ||||
| -rw-r--r-- | src/zir.zig | 23 |
4 files changed, 96 insertions, 46 deletions
diff --git a/src/Module.zig b/src/Module.zig index 30b454b12d..cb1c11cda7 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -237,12 +237,20 @@ pub const Decl = struct { } } - pub fn tokSrcLoc(decl: *Decl, token_index: ast.TokenIndex) LazySrcLoc { + pub fn relativeToNodeIndex(decl: Decl, offset: i32) ast.Node.Index { + return @bitCast(ast.Node.Index, offset + @bitCast(i32, decl.srcNode())); + } + + pub fn nodeIndexToRelative(decl: Decl, node_index: ast.Node.Index) i32 { + return @bitCast(i32, node_index) - @bitCast(i32, decl.srcNode()); + } + + pub fn tokSrcLoc(decl: Decl, token_index: ast.TokenIndex) LazySrcLoc { return .{ .token_offset = token_index - decl.srcToken() }; } - pub fn nodeSrcLoc(decl: *Decl, node_index: ast.Node.Index) LazySrcLoc { - return .{ .node_offset = node_index - decl.srcNode() }; + pub fn nodeSrcLoc(decl: Decl, node_index: ast.Node.Index) LazySrcLoc { + return .{ .node_offset = decl.nodeIndexToRelative(node_index) }; } pub fn srcLoc(decl: *Decl) SrcLoc { @@ -1076,6 +1084,40 @@ pub const Scope = struct { return new_index + gz.zir_code.ref_start_index; } + pub fn addCall( + gz: *GenZir, + tag: zir.Inst.Tag, + callee: zir.Inst.Ref, + args: []const zir.Inst.Ref, + /// Absolute node index. This function does the conversion to offset from Decl. + abs_node_index: ast.Node.Index, + ) !zir.Inst.Index { + assert(callee != 0); + assert(abs_node_index != 0); + const gpa = gz.zir_code.gpa; + try gz.instructions.ensureCapacity(gpa, gz.instructions.items.len + 1); + try gz.zir_code.instructions.ensureCapacity(gpa, gz.zir_code.instructions.len + 1); + try gz.zir_code.extra.ensureCapacity(gpa, gz.zir_code.extra.items.len + + @typeInfo(zir.Inst.Call).Struct.fields.len + args.len); + + const payload_index = gz.zir_code.addExtra(zir.Inst.Call{ + .callee = callee, + .args_len = @intCast(u32, args.len), + }) catch unreachable; // Capacity is ensured above. + gz.zir_code.extra.appendSliceAssumeCapacity(args); + + const new_index = @intCast(zir.Inst.Index, gz.zir_code.instructions.len); + gz.zir_code.instructions.appendAssumeCapacity(.{ + .tag = tag, + .data = .{ .pl_node = .{ + .src_node = gz.zir_code.decl.nodeIndexToRelative(abs_node_index), + .payload_index = payload_index, + } }, + }); + gz.instructions.appendAssumeCapacity(new_index); + return new_index + gz.zir_code.ref_start_index; + } + pub fn addInt(gz: *GenZir, integer: u64) !zir.Inst.Ref { return gz.add(.{ .tag = .int, @@ -1095,7 +1137,7 @@ pub const Scope = struct { .tag = tag, .data = .{ .un_node = .{ .operand = operand, - .src_node = abs_node_index - gz.zir_code.decl.srcNode(), + .src_node = gz.zir_code.decl.nodeIndexToRelative(abs_node_index), } }, }); } @@ -1116,7 +1158,7 @@ pub const Scope = struct { gz.zir_code.instructions.appendAssumeCapacity(.{ .tag = tag, .data = .{ .pl_node = .{ - .src_node = gz.zir_code.decl.srcNode() - abs_node_index, + .src_node = gz.zir_code.decl.nodeIndexToRelative(abs_node_index), .payload_index = payload_index, } }, }); @@ -1177,7 +1219,7 @@ pub const Scope = struct { ) !zir.Inst.Ref { return gz.add(.{ .tag = tag, - .data = .{ .node = abs_node_index - gz.zir_code.decl.srcNode() }, + .data = .{ .node = gz.zir_code.decl.nodeIndexToRelative(abs_node_index) }, }); } @@ -1205,14 +1247,14 @@ pub const Scope = struct { try gz.zir_code.instructions.append(gz.zir_code.gpa, .{ .tag = tag, .data = .{ .pl_node = .{ - .src_node = node - gz.zir_code.decl.srcNode(), + .src_node = gz.zir_code.decl.nodeIndexToRelative(node), .payload_index = undefined, } }, }); return new_index; } - fn add(gz: *GenZir, inst: zir.Inst) !zir.Inst.Ref { + pub fn add(gz: *GenZir, inst: zir.Inst) !zir.Inst.Ref { const gpa = gz.zir_code.gpa; try gz.instructions.ensureCapacity(gpa, gz.instructions.items.len + 1); try gz.zir_code.instructions.ensureCapacity(gpa, gz.zir_code.instructions.len + 1); @@ -1593,7 +1635,7 @@ pub const SrcLoc = struct { }, .node_offset => |node_off| { const decl = src_loc.container.decl; - const node_index = decl.srcNode() + node_off; + const node_index = decl.relativeToNodeIndex(node_off); const tree = decl.container.file_scope.base.tree(); const tok_index = tree.firstToken(node_index); const token_starts = tree.tokens.items(.start); @@ -1659,84 +1701,84 @@ pub const LazySrcLoc = union(enum) { /// The source location points to an AST node, which is this value offset /// from its containing Decl node AST index. /// The Decl is determined contextually. - node_offset: u32, + node_offset: i32, /// The source location points to a variable declaration type expression, /// found by taking this AST node index offset from the containing /// Decl AST node, which points to a variable declaration AST node. Next, navigate /// to the type expression. /// The Decl is determined contextually. - node_offset_var_decl_ty: u32, + node_offset_var_decl_ty: i32, /// The source location points to a for loop condition expression, /// found by taking this AST node index offset from the containing /// Decl AST node, which points to a for loop AST node. Next, navigate /// to the condition expression. /// The Decl is determined contextually. - node_offset_for_cond: u32, + node_offset_for_cond: i32, /// The source location points to the first parameter of a builtin /// function call, found by taking this AST node index offset from the containing /// Decl AST node, which points to a builtin call AST node. Next, navigate /// to the first parameter. /// The Decl is determined contextually. - node_offset_builtin_call_arg0: u32, + node_offset_builtin_call_arg0: i32, /// Same as `node_offset_builtin_call_arg0` except arg index 1. - node_offset_builtin_call_arg1: u32, + node_offset_builtin_call_arg1: i32, /// Same as `node_offset_builtin_call_arg0` except the arg index is contextually /// determined. - node_offset_builtin_call_argn: u32, + node_offset_builtin_call_argn: i32, /// The source location points to the index expression of an array access /// expression, found by taking this AST node index offset from the containing /// Decl AST node, which points to an array access AST node. Next, navigate /// to the index expression. /// The Decl is determined contextually. - node_offset_array_access_index: u32, + node_offset_array_access_index: i32, /// The source location points to the sentinel expression of a slice /// expression, found by taking this AST node index offset from the containing /// Decl AST node, which points to a slice AST node. Next, navigate /// to the sentinel expression. /// The Decl is determined contextually. - node_offset_slice_sentinel: u32, + node_offset_slice_sentinel: i32, /// The source location points to the callee expression of a function /// call expression, found by taking this AST node index offset from the containing /// Decl AST node, which points to a function call AST node. Next, navigate /// to the callee expression. /// The Decl is determined contextually. - node_offset_call_func: u32, + node_offset_call_func: i32, /// The source location points to the field name of a field access expression, /// found by taking this AST node index offset from the containing /// Decl AST node, which points to a field access AST node. Next, navigate /// to the field name token. /// The Decl is determined contextually. - node_offset_field_name: u32, + node_offset_field_name: i32, /// The source location points to the pointer of a pointer deref expression, /// found by taking this AST node index offset from the containing /// Decl AST node, which points to a pointer deref AST node. Next, navigate /// to the pointer expression. /// The Decl is determined contextually. - node_offset_deref_ptr: u32, + node_offset_deref_ptr: i32, /// The source location points to the assembly source code of an inline assembly /// expression, found by taking this AST node index offset from the containing /// Decl AST node, which points to inline assembly AST node. Next, navigate /// to the asm template source code. /// The Decl is determined contextually. - node_offset_asm_source: u32, + node_offset_asm_source: i32, /// The source location points to the return type of an inline assembly /// expression, found by taking this AST node index offset from the containing /// Decl AST node, which points to inline assembly AST node. Next, navigate /// to the return type expression. /// The Decl is determined contextually. - node_offset_asm_ret_ty: u32, + node_offset_asm_ret_ty: i32, /// The source location points to the condition expression of an if /// expression, found by taking this AST node index offset from the containing /// Decl AST node, which points to an if expression AST node. Next, navigate /// to the condition expression. /// The Decl is determined contextually. - node_offset_if_cond: u32, + node_offset_if_cond: i32, /// The source location points to the type expression of an `anyframe->T` /// expression, found by taking this AST node index offset from the containing /// Decl AST node, which points to a `anyframe->T` expression AST node. Next, navigate /// to the type expression. /// The Decl is determined contextually. - node_offset_anyframe_type: u32, + node_offset_anyframe_type: i32, /// Upgrade to a `SrcLoc` based on the `Decl` or file in the provided scope. pub fn toSrcLoc(lazy: LazySrcLoc, scope: *Scope) SrcLoc { @@ -3678,8 +3720,7 @@ pub fn failTok( comptime format: []const u8, args: anytype, ) InnerError { - const decl_token = scope.srcDecl().?.srcToken(); - const src: LazySrcLoc = .{ .token_offset = token_index - decl_token }; + const src = scope.srcDecl().?.tokSrcLoc(token_index); return mod.fail(scope, src, format, args); } @@ -3692,8 +3733,7 @@ pub fn failNode( comptime format: []const u8, args: anytype, ) InnerError { - const decl_node = scope.srcDecl().?.srcNode(); - const src: LazySrcLoc = .{ .node_offset = decl_node - node_index }; + const src = scope.srcDecl().?.nodeSrcLoc(node_index); return mod.fail(scope, src, format, args); } diff --git a/src/Sema.zig b/src/Sema.zig index ba07da3fdf..873c3ed1ae 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -618,7 +618,7 @@ fn zirParamType(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerErr const tracy = trace(@src()); defer tracy.end(); - const src: LazySrcLoc = .todo; + const src: LazySrcLoc = .unneeded; const inst_data = sema.code.instructions.items(.data)[inst].param_type; const fn_inst = try sema.resolveInst(inst_data.callee); const param_index = inst_data.param_index; diff --git a/src/astgen.zig b/src/astgen.zig index 9a0b336f8e..9065a125af 100644 --- a/src/astgen.zig +++ b/src/astgen.zig @@ -3402,10 +3402,6 @@ fn callExpr( node: ast.Node.Index, call: ast.full.Call, ) InnerError!zir.Inst.Ref { - if (true) { - @panic("TODO update for zir-memory-layout branch"); - } - if (call.async_token) |async_token| { return mod.failTok(scope, async_token, "TODO implement async fn call", .{}); } @@ -3414,11 +3410,14 @@ fn callExpr( const args = try mod.gpa.alloc(zir.Inst.Index, call.ast.params.len); defer mod.gpa.free(args); - const gen_zir = scope.getGenZir(); + const gz = scope.getGenZir(); for (call.ast.params) |param_node, i| { - const param_type = try gen_zir.addParamType(.{ - .callee = lhs, - .param_index = i, + const param_type = try gz.add(.{ + .tag = .param_type, + .data = .{ .param_type = .{ + .callee = lhs, + .param_index = @intCast(u32, i), + } }, }); args[i] = try expr(mod, scope, .{ .ty = param_type }, param_node); } @@ -3430,7 +3429,7 @@ fn callExpr( const result: zir.Inst.Index = res: { const tag: zir.Inst.Tag = switch (modifier) { .auto => switch (args.len == 0) { - true => break :res try gen_zir.addCallNone(lhs, node), + true => break :res try gz.addUnNode(.call_none, lhs, node), false => .call, }, .async_kw => .call_async_kw, @@ -3441,9 +3440,9 @@ fn callExpr( .always_inline => unreachable, .compile_time => .call_compile_time, }; - break :res try gen_zir.addCall(tag, lhs, args, node); + break :res try gz.addCall(tag, lhs, args, node); }; - return rvalue(mod, scope, rl, result); // TODO function call with result location + return rvalue(mod, scope, rl, result, node); // TODO function call with result location } fn suspendExpr(mod: *Module, scope: *Scope, node: ast.Node.Index) InnerError!zir.Inst.Ref { diff --git a/src/zir.zig b/src/zir.zig index 9026173b13..c5005a976d 100644 --- a/src/zir.zig +++ b/src/zir.zig @@ -1019,7 +1019,7 @@ pub const Inst = struct { /// Used for unary operators, with an AST node source location. un_node: struct { /// Offset from Decl AST node index. - src_node: ast.Node.Index, + src_node: i32, /// The meaning of this operand depends on the corresponding `Tag`. operand: Ref, @@ -1041,7 +1041,7 @@ pub const Inst = struct { pl_node: struct { /// Offset from Decl AST node index. /// `Tag` determines which kind of AST node this points to. - src_node: ast.Node.Index, + src_node: i32, /// index into extra. /// `Tag` determines what lives there. payload_index: u32, @@ -1092,7 +1092,7 @@ pub const Inst = struct { /// Offset from Decl AST token index. tok: ast.TokenIndex, /// Offset from Decl AST node index. - node: ast.Node.Index, + node: i32, int: u64, array_type_sentinel: struct { len: Ref, @@ -1400,9 +1400,10 @@ const Writer = struct { .slice_sentinel, .typeof_peer, .suspend_block, - .as_node, => try self.writePlNode(stream, inst), + .as_node => try self.writeAs(stream, inst), + .breakpoint, .dbg_stmt_node, .ret_ptr, @@ -1544,6 +1545,16 @@ const Writer = struct { try self.writeSrc(stream, inst_data.src()); } + fn writeAs(self: *Writer, stream: anytype, inst: Inst.Index) !void { + const inst_data = self.code.instructions.items(.data)[inst].pl_node; + const extra = self.code.extraData(Inst.As, inst_data.payload_index).data; + try self.writeInstRef(stream, extra.dest_type); + try stream.writeAll(", "); + try self.writeInstRef(stream, extra.operand); + try stream.writeAll(") "); + try self.writeSrc(stream, inst_data.src()); + } + fn writeNode( self: *Writer, stream: anytype, @@ -1560,8 +1571,8 @@ const Writer = struct { stream: anytype, inst: Inst.Index, ) (@TypeOf(stream).Error || error{OutOfMemory})!void { - const inst_data = self.code.instructions.items(.data)[inst].decl; - try stream.writeAll("TODO)"); + const decl = self.code.instructions.items(.data)[inst].decl; + try stream.print("{s})", .{decl.name}); } fn writeStrTok( |
