authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-04-21 21:33:55-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-04-21 21:33:55-04:00
log8d3e4147d591342d6ec4ce54c5e14da98c1a692a
tree1dd4dc925c43d75e7dc6368827d8f60b5aa1b66b
parent2c11acf807b2f52d076e3e35399d9cd5d038759a

ir: analyze deref instruction


2 files changed, 67 insertions(+), 3 deletions(-)

src-self-hosted/ir.zig+18-2
...@@ -383,7 +383,7 @@ const Analyze = struct {...@@ -383,7 +383,7 @@ const Analyze = struct {
383 },383 },
384 .ptrtoint => return self.analyzeInstPtrToInt(func, old_inst.cast(text.Inst.PtrToInt).?),384 .ptrtoint => return self.analyzeInstPtrToInt(func, old_inst.cast(text.Inst.PtrToInt).?),
385 .fieldptr => return self.analyzeInstFieldPtr(func, old_inst.cast(text.Inst.FieldPtr).?),385 .fieldptr => return self.analyzeInstFieldPtr(func, old_inst.cast(text.Inst.FieldPtr).?),
386 .deref => return self.fail(old_inst.src, "TODO implement analyzing {}", .{@tagName(old_inst.tag)}),386 .deref => return self.analyzeInstDeref(func, old_inst.cast(text.Inst.Deref).?),
387 .as => return self.analyzeInstAs(func, old_inst.cast(text.Inst.As).?),387 .as => return self.analyzeInstAs(func, old_inst.cast(text.Inst.As).?),
388 .@"asm" => return self.fail(old_inst.src, "TODO implement analyzing {}", .{@tagName(old_inst.tag)}),388 .@"asm" => return self.fail(old_inst.src, "TODO implement analyzing {}", .{@tagName(old_inst.tag)}),
389 .@"unreachable" => return self.fail(old_inst.src, "TODO implement analyzing {}", .{@tagName(old_inst.tag)}),389 .@"unreachable" => return self.fail(old_inst.src, "TODO implement analyzing {}", .{@tagName(old_inst.tag)}),
...@@ -476,7 +476,7 @@ const Analyze = struct {...@@ -476,7 +476,7 @@ const Analyze = struct {
476476
477 const elem_ty = switch (object_ptr.ty.zigTypeTag()) {477 const elem_ty = switch (object_ptr.ty.zigTypeTag()) {
478 .Pointer => object_ptr.ty.elemType(),478 .Pointer => object_ptr.ty.elemType(),
479 else => return self.fail(fieldptr.base.src, "expected pointer, found '{}'", .{object_ptr.ty}),479 else => return self.fail(fieldptr.positionals.object_ptr.src, "expected pointer, found '{}'", .{object_ptr.ty}),
480 };480 };
481 switch (elem_ty.zigTypeTag()) {481 switch (elem_ty.zigTypeTag()) {
482 .Array => {482 .Array => {
...@@ -535,6 +535,22 @@ const Analyze = struct {...@@ -535,6 +535,22 @@ const Analyze = struct {
535 return self.fail(intcast.base.src, "TODO implement analyze widen or shorten int", .{});535 return self.fail(intcast.base.src, "TODO implement analyze widen or shorten int", .{});
536 }536 }
537537
538 fn analyzeInstDeref(self: *Analyze, func: ?*Fn, deref: *text.Inst.Deref) InnerError!*Inst {
539 const ptr = try self.resolveInst(func, deref.positionals.ptr);
540 const elem_ty = switch (ptr.ty.zigTypeTag()) {
541 .Pointer => ptr.ty.elemType(),
542 else => return self.fail(deref.positionals.ptr.src, "expected pointer, found '{}'", .{ptr.ty}),
543 };
544 if (ptr.value()) |val| {
545 return self.constInst(deref.base.src, .{
546 .ty = elem_ty,
547 .val = val.pointerDeref(),
548 });
549 }
550
551 return self.fail(deref.base.src, "TODO implement runtime deref", .{});
552 }
553
538 fn coerce(self: *Analyze, dest_type: Type, inst: *Inst) !*Inst {554 fn coerce(self: *Analyze, dest_type: Type, inst: *Inst) !*Inst {
539 const in_memory_result = coerceInMemoryAllowed(dest_type, inst.ty);555 const in_memory_result = coerceInMemoryAllowed(dest_type, inst.ty);
540 if (in_memory_result == .ok) {556 if (in_memory_result == .ok) {
src-self-hosted/value.zig+49-1
...@@ -284,6 +284,54 @@ pub const Value = extern union {...@@ -284,6 +284,54 @@ pub const Value = extern union {
284 }284 }
285 }285 }
286286
287 /// Asserts the value is a pointer and dereferences it.
288 pub fn pointerDeref(self: Value) Value {
289 switch (self.tag()) {
290 .ty,
291 .u8_type,
292 .i8_type,
293 .isize_type,
294 .usize_type,
295 .c_short_type,
296 .c_ushort_type,
297 .c_int_type,
298 .c_uint_type,
299 .c_long_type,
300 .c_ulong_type,
301 .c_longlong_type,
302 .c_ulonglong_type,
303 .c_longdouble_type,
304 .f16_type,
305 .f32_type,
306 .f64_type,
307 .f128_type,
308 .c_void_type,
309 .bool_type,
310 .void_type,
311 .type_type,
312 .anyerror_type,
313 .comptime_int_type,
314 .comptime_float_type,
315 .noreturn_type,
316 .fn_naked_noreturn_no_args_type,
317 .single_const_pointer_to_comptime_int_type,
318 .const_slice_u8_type,
319 .void_value,
320 .noreturn_value,
321 .bool_true,
322 .bool_false,
323 .function,
324 .int_u64,
325 .int_i64,
326 .int_big,
327 .bytes,
328 => unreachable,
329
330 .ref => return self.cast(Payload.Ref).?.cell.contents,
331 .ref_val => return self.cast(Payload.RefVal).?.val,
332 }
333 }
334
287 /// This type is not copyable since it may contain pointers to its inner data.335 /// This type is not copyable since it may contain pointers to its inner data.
288 pub const Payload = struct {336 pub const Payload = struct {
289 tag: Tag,337 tag: Tag,
...@@ -321,7 +369,7 @@ pub const Value = extern union {...@@ -321,7 +369,7 @@ pub const Value = extern union {
321369
322 pub const Ref = struct {370 pub const Ref = struct {
323 base: Payload = Payload{ .tag = .ref },371 base: Payload = Payload{ .tag = .ref },
324 pointee: *MemoryCell,372 cell: *MemoryCell,
325 };373 };
326374
327 pub const RefVal = struct {375 pub const RefVal = struct {