ir: analyze deref instruction
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user