From 8d3e4147d591342d6ec4ce54c5e14da98c1a692a Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Tue, 21 Apr 2020 21:33:55 -0400 Subject: [PATCH] ir: analyze deref instruction --- src-self-hosted/ir.zig | 20 ++++++++++++++-- src-self-hosted/value.zig | 50 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 67 insertions(+), 3 deletions(-) diff --git a/src-self-hosted/ir.zig b/src-self-hosted/ir.zig index ed4d008934..ec08dcf6a5 100644 --- a/src-self-hosted/ir.zig +++ b/src-self-hosted/ir.zig @@ -383,7 +383,7 @@ const Analyze = struct { }, .ptrtoint => return self.analyzeInstPtrToInt(func, old_inst.cast(text.Inst.PtrToInt).?), .fieldptr => return self.analyzeInstFieldPtr(func, old_inst.cast(text.Inst.FieldPtr).?), - .deref => return self.fail(old_inst.src, "TODO implement analyzing {}", .{@tagName(old_inst.tag)}), + .deref => return self.analyzeInstDeref(func, old_inst.cast(text.Inst.Deref).?), .as => return self.analyzeInstAs(func, old_inst.cast(text.Inst.As).?), .@"asm" => return self.fail(old_inst.src, "TODO implement analyzing {}", .{@tagName(old_inst.tag)}), .@"unreachable" => return self.fail(old_inst.src, "TODO implement analyzing {}", .{@tagName(old_inst.tag)}), @@ -476,7 +476,7 @@ const Analyze = struct { const elem_ty = switch (object_ptr.ty.zigTypeTag()) { .Pointer => object_ptr.ty.elemType(), - else => return self.fail(fieldptr.base.src, "expected pointer, found '{}'", .{object_ptr.ty}), + else => return self.fail(fieldptr.positionals.object_ptr.src, "expected pointer, found '{}'", .{object_ptr.ty}), }; switch (elem_ty.zigTypeTag()) { .Array => { @@ -535,6 +535,22 @@ const Analyze = struct { return self.fail(intcast.base.src, "TODO implement analyze widen or shorten int", .{}); } + fn analyzeInstDeref(self: *Analyze, func: ?*Fn, deref: *text.Inst.Deref) InnerError!*Inst { + const ptr = try self.resolveInst(func, deref.positionals.ptr); + const elem_ty = switch (ptr.ty.zigTypeTag()) { + .Pointer => ptr.ty.elemType(), + else => return self.fail(deref.positionals.ptr.src, "expected pointer, found '{}'", .{ptr.ty}), + }; + if (ptr.value()) |val| { + return self.constInst(deref.base.src, .{ + .ty = elem_ty, + .val = val.pointerDeref(), + }); + } + + return self.fail(deref.base.src, "TODO implement runtime deref", .{}); + } + fn coerce(self: *Analyze, dest_type: Type, inst: *Inst) !*Inst { const in_memory_result = coerceInMemoryAllowed(dest_type, inst.ty); if (in_memory_result == .ok) { diff --git a/src-self-hosted/value.zig b/src-self-hosted/value.zig index 086473246f..44c44df2d4 100644 --- a/src-self-hosted/value.zig +++ b/src-self-hosted/value.zig @@ -284,6 +284,54 @@ pub const Value = extern union { } } + /// Asserts the value is a pointer and dereferences it. + pub fn pointerDeref(self: Value) Value { + switch (self.tag()) { + .ty, + .u8_type, + .i8_type, + .isize_type, + .usize_type, + .c_short_type, + .c_ushort_type, + .c_int_type, + .c_uint_type, + .c_long_type, + .c_ulong_type, + .c_longlong_type, + .c_ulonglong_type, + .c_longdouble_type, + .f16_type, + .f32_type, + .f64_type, + .f128_type, + .c_void_type, + .bool_type, + .void_type, + .type_type, + .anyerror_type, + .comptime_int_type, + .comptime_float_type, + .noreturn_type, + .fn_naked_noreturn_no_args_type, + .single_const_pointer_to_comptime_int_type, + .const_slice_u8_type, + .void_value, + .noreturn_value, + .bool_true, + .bool_false, + .function, + .int_u64, + .int_i64, + .int_big, + .bytes, + => unreachable, + + .ref => return self.cast(Payload.Ref).?.cell.contents, + .ref_val => return self.cast(Payload.RefVal).?.val, + } + } + /// This type is not copyable since it may contain pointers to its inner data. pub const Payload = struct { tag: Tag, @@ -321,7 +369,7 @@ pub const Value = extern union { pub const Ref = struct { base: Payload = Payload{ .tag = .ref }, - pointee: *MemoryCell, + cell: *MemoryCell, }; pub const RefVal = struct {