diff options
Diffstat (limited to 'src/Module.zig')
| -rw-r--r-- | src/Module.zig | 98 |
1 files changed, 50 insertions, 48 deletions
diff --git a/src/Module.zig b/src/Module.zig index fdf8267017..9fdc1c2c9a 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -914,16 +914,16 @@ pub const Scope = struct { parent: *Scope, /// All `GenZir` scopes for the same ZIR share this. zir_code: *WipZirCode, - /// Keeps track of the list of instructions in this scope only. References + /// Keeps track of the list of instructions in this scope only. Indexes /// to instructions in `zir_code`. - instructions: std.ArrayListUnmanaged(zir.Inst.Ref) = .{}, + instructions: std.ArrayListUnmanaged(zir.Inst.Index) = .{}, label: ?Label = null, break_block: zir.Inst.Index = 0, continue_block: zir.Inst.Index = 0, /// Only valid when setBlockResultLoc is called. break_result_loc: astgen.ResultLoc = undefined, /// When a block has a pointer result location, here it is. - rl_ptr: zir.Inst.Ref = 0, + rl_ptr: zir.Inst.Ref = .none, /// Keeps track of how many branches of a block did not actually /// consume the result location. astgen uses this to figure out /// whether to rely on break instructions or writing to the result @@ -1001,8 +1001,8 @@ pub const Scope = struct { ret_ty: zir.Inst.Ref, cc: zir.Inst.Ref, }) !zir.Inst.Ref { - assert(args.ret_ty != 0); - assert(args.cc != 0); + assert(args.ret_ty != .none); + assert(args.cc != .none); 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); @@ -1013,7 +1013,7 @@ pub const Scope = struct { .cc = args.cc, .param_types_len = @intCast(u32, args.param_types.len), }); - gz.zir_code.extra.appendSliceAssumeCapacity(args.param_types); + gz.zir_code.extra.appendSliceAssumeCapacity(mem.bytesAsSlice(u32, mem.sliceAsBytes(args.param_types))); const new_index = @intCast(zir.Inst.Index, gz.zir_code.instructions.len); gz.zir_code.instructions.appendAssumeCapacity(.{ @@ -1024,7 +1024,7 @@ pub const Scope = struct { } }, }); gz.instructions.appendAssumeCapacity(new_index); - return new_index + gz.zir_code.ref_start_index; + return zir.Inst.Ref.fromIndex(new_index, gz.zir_code.param_count); } pub fn addFnType( @@ -1033,7 +1033,7 @@ pub const Scope = struct { ret_ty: zir.Inst.Ref, param_types: []const zir.Inst.Ref, ) !zir.Inst.Ref { - assert(ret_ty != 0); + assert(ret_ty != .none); 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); @@ -1043,7 +1043,7 @@ pub const Scope = struct { const payload_index = gz.zir_code.addExtraAssumeCapacity(zir.Inst.FnType{ .param_types_len = @intCast(u32, param_types.len), }); - gz.zir_code.extra.appendSliceAssumeCapacity(param_types); + gz.zir_code.extra.appendSliceAssumeCapacity(mem.bytesAsSlice(u32, mem.sliceAsBytes(param_types))); const new_index = @intCast(zir.Inst.Index, gz.zir_code.instructions.len); gz.zir_code.instructions.appendAssumeCapacity(.{ @@ -1054,7 +1054,7 @@ pub const Scope = struct { } }, }); gz.instructions.appendAssumeCapacity(new_index); - return new_index + gz.zir_code.ref_start_index; + return zir.Inst.Ref.fromIndex(new_index, gz.zir_code.param_count); } pub fn addCall( @@ -1065,7 +1065,7 @@ pub const Scope = struct { /// Absolute node index. This function does the conversion to offset from Decl. src_node: ast.Node.Index, ) !zir.Inst.Ref { - assert(callee != 0); + assert(callee != .none); assert(src_node != 0); const gpa = gz.zir_code.gpa; try gz.instructions.ensureCapacity(gpa, gz.instructions.items.len + 1); @@ -1077,7 +1077,7 @@ pub const Scope = struct { .callee = callee, .args_len = @intCast(u32, args.len), }); - gz.zir_code.extra.appendSliceAssumeCapacity(args); + gz.zir_code.extra.appendSliceAssumeCapacity(mem.bytesAsSlice(u32, mem.sliceAsBytes(args))); const new_index = @intCast(zir.Inst.Index, gz.zir_code.instructions.len); gz.zir_code.instructions.appendAssumeCapacity(.{ @@ -1088,7 +1088,7 @@ pub const Scope = struct { } }, }); gz.instructions.appendAssumeCapacity(new_index); - return new_index + gz.zir_code.ref_start_index; + return zir.Inst.Ref.fromIndex(new_index, gz.zir_code.param_count); } /// Note that this returns a `zir.Inst.Index` not a ref. @@ -1098,7 +1098,7 @@ pub const Scope = struct { tag: zir.Inst.Tag, lhs: zir.Inst.Ref, ) !zir.Inst.Index { - assert(lhs != 0); + assert(lhs != .none); 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); @@ -1129,7 +1129,7 @@ pub const Scope = struct { /// Absolute node index. This function does the conversion to offset from Decl. src_node: ast.Node.Index, ) !zir.Inst.Ref { - assert(operand != 0); + assert(operand != .none); return gz.add(.{ .tag = tag, .data = .{ .un_node = .{ @@ -1160,7 +1160,7 @@ pub const Scope = struct { } }, }); gz.instructions.appendAssumeCapacity(new_index); - return new_index + gz.zir_code.ref_start_index; + return zir.Inst.Ref.fromIndex(new_index, gz.zir_code.param_count); } pub fn addArrayTypeSentinel( @@ -1186,7 +1186,7 @@ pub const Scope = struct { } }, }); gz.instructions.appendAssumeCapacity(new_index); - return new_index + gz.zir_code.ref_start_index; + return zir.Inst.Ref.fromIndex(new_index, gz.zir_code.param_count); } pub fn addUnTok( @@ -1196,7 +1196,7 @@ pub const Scope = struct { /// Absolute token index. This function does the conversion to Decl offset. abs_tok_index: ast.TokenIndex, ) !zir.Inst.Ref { - assert(operand != 0); + assert(operand != .none); return gz.add(.{ .tag = tag, .data = .{ .un_tok = .{ @@ -1228,8 +1228,8 @@ pub const Scope = struct { lhs: zir.Inst.Ref, rhs: zir.Inst.Ref, ) !zir.Inst.Ref { - assert(lhs != 0); - assert(rhs != 0); + assert(lhs != .none); + assert(rhs != .none); return gz.add(.{ .tag = tag, .data = .{ .bin = .{ @@ -1317,7 +1317,7 @@ pub const Scope = struct { const new_index = @intCast(zir.Inst.Index, gz.zir_code.instructions.len); gz.zir_code.instructions.appendAssumeCapacity(inst); gz.instructions.appendAssumeCapacity(new_index); - return gz.zir_code.ref_start_index + new_index; + return zir.Inst.Ref.fromIndex(new_index, gz.zir_code.param_count); } }; @@ -1331,7 +1331,7 @@ pub const Scope = struct { parent: *Scope, gen_zir: *GenZir, name: []const u8, - inst: zir.Inst.Index, + inst: zir.Inst.Ref, /// Source location of the corresponding variable declaration. src: LazySrcLoc, }; @@ -1346,7 +1346,7 @@ pub const Scope = struct { parent: *Scope, gen_zir: *GenZir, name: []const u8, - ptr: zir.Inst.Index, + ptr: zir.Inst.Ref, /// Source location of the corresponding variable declaration. src: LazySrcLoc, }; @@ -1366,9 +1366,9 @@ pub const WipZirCode = struct { instructions: std.MultiArrayList(zir.Inst) = .{}, string_bytes: std.ArrayListUnmanaged(u8) = .{}, extra: std.ArrayListUnmanaged(u32) = .{}, - /// The end of special indexes. `zir.Inst.Ref` subtracts against this number to convert - /// to `zir.Inst.Index`. The default here is correct if there are 0 parameters. - ref_start_index: u32 = zir.const_inst_list.len, + /// We need to keep track of this count in order to convert between + /// `zir.Inst.Ref` and `zir.Inst.Index` types. + param_count: u32 = 0, decl: *Decl, gpa: *Allocator, arena: *Allocator, @@ -1383,15 +1383,18 @@ pub const WipZirCode = struct { const fields = std.meta.fields(@TypeOf(extra)); const result = @intCast(u32, wzc.extra.items.len); inline for (fields) |field| { - comptime assert(field.field_type == u32); - wzc.extra.appendAssumeCapacity(@field(extra, field.name)); + wzc.extra.appendAssumeCapacity(switch (field.field_type) { + u32 => @field(extra, field.name), + zir.Inst.Ref => @enumToInt(@field(extra, field.name)), + else => unreachable, + }); } return result; } pub fn refIsNoReturn(wzc: WipZirCode, zir_inst_ref: zir.Inst.Ref) bool { - if (zir_inst_ref >= wzc.ref_start_index) { - const zir_inst = zir_inst_ref - wzc.ref_start_index; + if (zir_inst_ref == .unreachable_value) return true; + if (zir_inst_ref.toIndex(wzc.param_count)) |zir_inst| { return wzc.instructions.items(.tag)[zir_inst].isNoReturn(); } return false; @@ -2072,7 +2075,7 @@ fn astgenAndSemaFn( // The AST params array does not contain anytype and ... parameters. // We must iterate to count how many param types to allocate. const param_count = blk: { - var count: usize = 0; + var count: u32 = 0; var it = fn_proto.iterate(tree); while (it.next()) |param| { if (param.anytype_ellipsis3) |some| if (token_tags[some] == .ellipsis3) break; @@ -2081,7 +2084,6 @@ fn astgenAndSemaFn( break :blk count; }; const param_types = try fn_type_scope_arena.allocator.alloc(zir.Inst.Ref, param_count); - const type_type_rl: astgen.ResultLoc = .{ .ty = @enumToInt(zir.Const.type_type) }; var is_var_args = false; { @@ -2106,7 +2108,7 @@ fn astgenAndSemaFn( const param_type_node = param.type_expr; assert(param_type_node != 0); param_types[param_type_i] = - try astgen.expr(mod, &fn_type_scope.base, type_type_rl, param_type_node); + try astgen.expr(mod, &fn_type_scope.base, .{ .ty = .type_type }, param_type_node); } assert(param_type_i == param_count); } @@ -2178,7 +2180,7 @@ fn astgenAndSemaFn( const return_type_inst = try astgen.expr( mod, &fn_type_scope.base, - type_type_rl, + .{ .ty = .type_type }, fn_proto.ast.return_type, ); @@ -2187,19 +2189,22 @@ fn astgenAndSemaFn( else false; - const cc: zir.Inst.Index = if (fn_proto.ast.callconv_expr != 0) + const cc: zir.Inst.Ref = if (fn_proto.ast.callconv_expr != 0) // TODO instead of enum literal type, this needs to be the // std.builtin.CallingConvention enum. We need to implement importing other files // and enums in order to fix this. - try astgen.comptimeExpr(mod, &fn_type_scope.base, .{ - .ty = @enumToInt(zir.Const.enum_literal_type), - }, fn_proto.ast.callconv_expr) + try astgen.comptimeExpr( + mod, + &fn_type_scope.base, + .{ .ty = .enum_literal_type }, + fn_proto.ast.callconv_expr, + ) else if (is_extern) // note: https://github.com/ziglang/zig/issues/5269 try fn_type_scope.addSmallStr(.enum_literal_small, "C") else - 0; + .none; - const fn_type_inst: zir.Inst.Ref = if (cc != 0) fn_type: { + const fn_type_inst: zir.Inst.Ref = if (cc != .none) fn_type: { const tag: zir.Inst.Tag = if (is_var_args) .fn_type_cc_var_args else .fn_type_cc; break :fn_type try fn_type_scope.addFnTypeCc(tag, .{ .ret_ty = return_type_inst, @@ -2292,7 +2297,7 @@ fn astgenAndSemaFn( .decl = decl, .arena = &decl_arena.allocator, .gpa = mod.gpa, - .ref_start_index = @intCast(u32, zir.const_inst_list.len + param_count), + .param_count = param_count, }; defer wip_zir_code.deinit(); @@ -2309,7 +2314,7 @@ fn astgenAndSemaFn( try wip_zir_code.extra.ensureCapacity(mod.gpa, param_count); var params_scope = &gen_scope.base; - var i: usize = 0; + var i: u32 = 0; var it = fn_proto.iterate(tree); while (it.next()) |param| : (i += 1) { const name_token = param.name_token.?; @@ -2320,7 +2325,7 @@ fn astgenAndSemaFn( .gen_zir = &gen_scope, .name = param_name, // Implicit const list first, then implicit arg list. - .inst = @intCast(u32, zir.const_inst_list.len + i), + .inst = zir.Inst.Ref.fromParam(i), .src = decl.tokSrcLoc(name_token), }; params_scope = &sub_scope.base; @@ -2344,8 +2349,7 @@ fn astgenAndSemaFn( // astgen uses result location semantics to coerce return operands. // Since we are adding the return instruction here, we must handle the coercion. // We do this by using the `ret_coerce` instruction. - const void_inst: zir.Inst.Ref = @enumToInt(zir.Const.void_value); - _ = try gen_scope.addUnTok(.ret_coerce, void_inst, tree.lastToken(body_node)); + _ = try gen_scope.addUnTok(.ret_coerce, .void_value, tree.lastToken(body_node)); } const code = try gen_scope.finish(); @@ -2514,9 +2518,7 @@ fn astgenAndSemaVarDecl( defer gen_scope.instructions.deinit(mod.gpa); const init_result_loc: astgen.ResultLoc = if (var_decl.ast.type_node != 0) .{ - .ty = try astgen.expr(mod, &gen_scope.base, .{ - .ty = @enumToInt(zir.Const.type_type), - }, var_decl.ast.type_node), + .ty = try astgen.expr(mod, &gen_scope.base, .{ .ty = .type_type }, var_decl.ast.type_node), } else .none; const init_inst = try astgen.comptimeExpr( |
