Commit 8d3e4147d5
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) {
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 {