| ... | ... | @@ -13,124 +13,8 @@ const Sema = @import("Sema.zig"); |
| 13 | 13 | const InternPool = @import("InternPool.zig"); |
| 14 | 14 | const Value = @This(); |
| 15 | 15 | |
| 16 | | /// We are migrating towards using this for every Value object. However, many |
| 17 | | /// values are still represented the legacy way. This is indicated by using |
| 18 | | /// InternPool.Index.none. |
| 19 | 16 | ip_index: InternPool.Index, |
| 20 | 17 | |
| 21 | | /// This is the raw data, with no bookkeeping, no memory awareness, |
| 22 | | /// no de-duplication, and no type system awareness. |
| 23 | | /// This union takes advantage of the fact that the first page of memory |
| 24 | | /// is unmapped, giving us 4096 possible enum tags that have no payload. |
| 25 | | legacy: extern union { |
| 26 | | ptr_otherwise: *Payload, |
| 27 | | }, |
| 28 | | |
| 29 | | // Keep in sync with tools/stage2_pretty_printers_common.py |
| 30 | | pub const Tag = enum(usize) { |
| 31 | | // The first section of this enum are tags that require no payload. |
| 32 | | // After this, the tag requires a payload. |
| 33 | | |
| 34 | | /// When the type is error union: |
| 35 | | /// * If the tag is `.@"error"`, the error union is an error. |
| 36 | | /// * If the tag is `.eu_payload`, the error union is a payload. |
| 37 | | /// * A nested error such as `anyerror!(anyerror!T)` in which the the outer error union |
| 38 | | /// is non-error, but the inner error union is an error, is represented as |
| 39 | | /// a tag of `.eu_payload`, with a sub-tag of `.@"error"`. |
| 40 | | eu_payload, |
| 41 | | /// When the type is optional: |
| 42 | | /// * If the tag is `.null_value`, the optional is null. |
| 43 | | /// * If the tag is `.opt_payload`, the optional is a payload. |
| 44 | | /// * A nested optional such as `??T` in which the the outer optional |
| 45 | | /// is non-null, but the inner optional is null, is represented as |
| 46 | | /// a tag of `.opt_payload`, with a sub-tag of `.null_value`. |
| 47 | | opt_payload, |
| 48 | | /// Pointer and length as sub `Value` objects. |
| 49 | | slice, |
| 50 | | /// A slice of u8 whose memory is managed externally. |
| 51 | | bytes, |
| 52 | | /// This value is repeated some number of times. The amount of times to repeat |
| 53 | | /// is stored externally. |
| 54 | | repeated, |
| 55 | | /// An instance of a struct, array, or vector. |
| 56 | | /// Each element/field stored as a `Value`. |
| 57 | | /// In the case of sentinel-terminated arrays, the sentinel value *is* stored, |
| 58 | | /// so the slice length will be one more than the type's array length. |
| 59 | | aggregate, |
| 60 | | /// An instance of a union. |
| 61 | | @"union", |
| 62 | | |
| 63 | | pub fn Type(comptime t: Tag) type { |
| 64 | | return switch (t) { |
| 65 | | .eu_payload, |
| 66 | | .opt_payload, |
| 67 | | .repeated, |
| 68 | | => Payload.SubValue, |
| 69 | | .slice => Payload.Slice, |
| 70 | | .bytes => Payload.Bytes, |
| 71 | | .aggregate => Payload.Aggregate, |
| 72 | | .@"union" => Payload.Union, |
| 73 | | }; |
| 74 | | } |
| 75 | | |
| 76 | | pub fn create(comptime t: Tag, ally: Allocator, data: Data(t)) error{OutOfMemory}!Value { |
| 77 | | const ptr = try ally.create(t.Type()); |
| 78 | | ptr.* = .{ |
| 79 | | .base = .{ .tag = t }, |
| 80 | | .data = data, |
| 81 | | }; |
| 82 | | return Value{ |
| 83 | | .ip_index = .none, |
| 84 | | .legacy = .{ .ptr_otherwise = &ptr.base }, |
| 85 | | }; |
| 86 | | } |
| 87 | | |
| 88 | | pub fn Data(comptime t: Tag) type { |
| 89 | | return std.meta.fieldInfo(t.Type(), .data).type; |
| 90 | | } |
| 91 | | }; |
| 92 | | |
| 93 | | pub fn initPayload(payload: *Payload) Value { |
| 94 | | return Value{ |
| 95 | | .ip_index = .none, |
| 96 | | .legacy = .{ .ptr_otherwise = payload }, |
| 97 | | }; |
| 98 | | } |
| 99 | | |
| 100 | | pub fn tag(self: Value) Tag { |
| 101 | | assert(self.ip_index == .none); |
| 102 | | return self.legacy.ptr_otherwise.tag; |
| 103 | | } |
| 104 | | |
| 105 | | /// Prefer `castTag` to this. |
| 106 | | pub fn cast(self: Value, comptime T: type) ?*T { |
| 107 | | if (self.ip_index != .none) { |
| 108 | | return null; |
| 109 | | } |
| 110 | | if (@hasField(T, "base_tag")) { |
| 111 | | return self.castTag(T.base_tag); |
| 112 | | } |
| 113 | | inline for (@typeInfo(Tag).Enum.fields) |field| { |
| 114 | | const t = @as(Tag, @enumFromInt(field.value)); |
| 115 | | if (self.legacy.ptr_otherwise.tag == t) { |
| 116 | | if (T == t.Type()) { |
| 117 | | return @fieldParentPtr(T, "base", self.legacy.ptr_otherwise); |
| 118 | | } |
| 119 | | return null; |
| 120 | | } |
| 121 | | } |
| 122 | | unreachable; |
| 123 | | } |
| 124 | | |
| 125 | | pub fn castTag(self: Value, comptime t: Tag) ?*t.Type() { |
| 126 | | if (self.ip_index != .none) return null; |
| 127 | | |
| 128 | | if (self.legacy.ptr_otherwise.tag == t) |
| 129 | | return @fieldParentPtr(t.Type(), "base", self.legacy.ptr_otherwise); |
| 130 | | |
| 131 | | return null; |
| 132 | | } |
| 133 | | |
| 134 | 18 | pub fn format(val: Value, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void { |
| 135 | 19 | _ = val; |
| 136 | 20 | _ = fmt; |
| ... | ... | @@ -148,33 +32,7 @@ pub fn dump( |
| 148 | 32 | out_stream: anytype, |
| 149 | 33 | ) !void { |
| 150 | 34 | comptime assert(fmt.len == 0); |
| 151 | | if (start_val.ip_index != .none) { |
| 152 | | try out_stream.print("(interned: {})", .{start_val.toIntern()}); |
| 153 | | return; |
| 154 | | } |
| 155 | | var val = start_val; |
| 156 | | while (true) switch (val.tag()) { |
| 157 | | .aggregate => { |
| 158 | | return out_stream.writeAll("(aggregate)"); |
| 159 | | }, |
| 160 | | .@"union" => { |
| 161 | | return out_stream.writeAll("(union value)"); |
| 162 | | }, |
| 163 | | .bytes => return out_stream.print("\"{}\"", .{std.zig.fmtEscapes(val.castTag(.bytes).?.data)}), |
| 164 | | .repeated => { |
| 165 | | try out_stream.writeAll("(repeated) "); |
| 166 | | val = val.castTag(.repeated).?.data; |
| 167 | | }, |
| 168 | | .eu_payload => { |
| 169 | | try out_stream.writeAll("(eu_payload) "); |
| 170 | | val = val.castTag(.repeated).?.data; |
| 171 | | }, |
| 172 | | .opt_payload => { |
| 173 | | try out_stream.writeAll("(opt_payload) "); |
| 174 | | val = val.castTag(.repeated).?.data; |
| 175 | | }, |
| 176 | | .slice => return out_stream.writeAll("(slice)"), |
| 177 | | }; |
| 35 | try out_stream.print("(interned: {})", .{start_val.toIntern()}); |
| 178 | 36 | } |
| 179 | 37 | |
| 180 | 38 | pub fn fmtDebug(val: Value) std.fmt.Formatter(dump) { |
| ... | ... | @@ -252,162 +110,9 @@ fn arrayToIpString(val: Value, len_u64: u64, mod: *Module) !InternPool.NullTermi |
| 252 | 110 | return ip.getOrPutTrailingString(gpa, len); |
| 253 | 111 | } |
| 254 | 112 | |
| 255 | | pub fn intern2(val: Value, ty: Type, mod: *Module) Allocator.Error!InternPool.Index { |
| 256 | | if (val.ip_index != .none) return val.ip_index; |
| 257 | | return intern(val, ty, mod); |
| 258 | | } |
| 259 | | |
| 260 | | pub fn intern(val: Value, ty: Type, mod: *Module) Allocator.Error!InternPool.Index { |
| 261 | | if (val.ip_index != .none) return (try mod.getCoerced(val, ty)).toIntern(); |
| 262 | | const ip = &mod.intern_pool; |
| 263 | | switch (val.tag()) { |
| 264 | | .eu_payload => { |
| 265 | | const pl = val.castTag(.eu_payload).?.data; |
| 266 | | return mod.intern(.{ .error_union = .{ |
| 267 | | .ty = ty.toIntern(), |
| 268 | | .val = .{ .payload = try pl.intern(ty.errorUnionPayload(mod), mod) }, |
| 269 | | } }); |
| 270 | | }, |
| 271 | | .opt_payload => { |
| 272 | | const pl = val.castTag(.opt_payload).?.data; |
| 273 | | return mod.intern(.{ .opt = .{ |
| 274 | | .ty = ty.toIntern(), |
| 275 | | .val = try pl.intern(ty.optionalChild(mod), mod), |
| 276 | | } }); |
| 277 | | }, |
| 278 | | .slice => { |
| 279 | | const pl = val.castTag(.slice).?.data; |
| 280 | | return mod.intern(.{ .slice = .{ |
| 281 | | .ty = ty.toIntern(), |
| 282 | | .len = try pl.len.intern(Type.usize, mod), |
| 283 | | .ptr = try pl.ptr.intern(ty.slicePtrFieldType(mod), mod), |
| 284 | | } }); |
| 285 | | }, |
| 286 | | .bytes => { |
| 287 | | const pl = val.castTag(.bytes).?.data; |
| 288 | | return mod.intern(.{ .aggregate = .{ |
| 289 | | .ty = ty.toIntern(), |
| 290 | | .storage = .{ .bytes = pl }, |
| 291 | | } }); |
| 292 | | }, |
| 293 | | .repeated => { |
| 294 | | const pl = val.castTag(.repeated).?.data; |
| 295 | | return mod.intern(.{ .aggregate = .{ |
| 296 | | .ty = ty.toIntern(), |
| 297 | | .storage = .{ .repeated_elem = try pl.intern(ty.childType(mod), mod) }, |
| 298 | | } }); |
| 299 | | }, |
| 300 | | .aggregate => { |
| 301 | | const len = @as(usize, @intCast(ty.arrayLen(mod))); |
| 302 | | const old_elems = val.castTag(.aggregate).?.data[0..len]; |
| 303 | | const new_elems = try mod.gpa.alloc(InternPool.Index, old_elems.len); |
| 304 | | defer mod.gpa.free(new_elems); |
| 305 | | const ty_key = ip.indexToKey(ty.toIntern()); |
| 306 | | for (new_elems, old_elems, 0..) |*new_elem, old_elem, field_i| |
| 307 | | new_elem.* = try old_elem.intern(switch (ty_key) { |
| 308 | | .struct_type => ty.structFieldType(field_i, mod), |
| 309 | | .anon_struct_type => |info| Type.fromInterned(info.types.get(ip)[field_i]), |
| 310 | | inline .array_type, .vector_type => |info| Type.fromInterned(info.child), |
| 311 | | else => unreachable, |
| 312 | | }, mod); |
| 313 | | return mod.intern(.{ .aggregate = .{ |
| 314 | | .ty = ty.toIntern(), |
| 315 | | .storage = .{ .elems = new_elems }, |
| 316 | | } }); |
| 317 | | }, |
| 318 | | .@"union" => { |
| 319 | | const pl = val.castTag(.@"union").?.data; |
| 320 | | if (pl.tag) |pl_tag| { |
| 321 | | return mod.intern(.{ .un = .{ |
| 322 | | .ty = ty.toIntern(), |
| 323 | | .tag = try pl_tag.intern(ty.unionTagTypeHypothetical(mod), mod), |
| 324 | | .val = try pl.val.intern(ty.unionFieldType(pl_tag, mod).?, mod), |
| 325 | | } }); |
| 326 | | } else { |
| 327 | | return mod.intern(.{ .un = .{ |
| 328 | | .ty = ty.toIntern(), |
| 329 | | .tag = .none, |
| 330 | | .val = try pl.val.intern(try ty.unionBackingType(mod), mod), |
| 331 | | } }); |
| 332 | | } |
| 333 | | }, |
| 334 | | } |
| 335 | | } |
| 336 | | |
| 337 | | pub fn unintern(val: Value, arena: Allocator, mod: *Module) Allocator.Error!Value { |
| 338 | | return if (val.ip_index == .none) val else switch (mod.intern_pool.indexToKey(val.toIntern())) { |
| 339 | | .int_type, |
| 340 | | .ptr_type, |
| 341 | | .array_type, |
| 342 | | .vector_type, |
| 343 | | .opt_type, |
| 344 | | .anyframe_type, |
| 345 | | .error_union_type, |
| 346 | | .simple_type, |
| 347 | | .struct_type, |
| 348 | | .anon_struct_type, |
| 349 | | .union_type, |
| 350 | | .opaque_type, |
| 351 | | .enum_type, |
| 352 | | .func_type, |
| 353 | | .error_set_type, |
| 354 | | .inferred_error_set_type, |
| 355 | | |
| 356 | | .undef, |
| 357 | | .simple_value, |
| 358 | | .variable, |
| 359 | | .extern_func, |
| 360 | | .func, |
| 361 | | .int, |
| 362 | | .err, |
| 363 | | .enum_literal, |
| 364 | | .enum_tag, |
| 365 | | .empty_enum_value, |
| 366 | | .float, |
| 367 | | .ptr, |
| 368 | | => val, |
| 369 | | |
| 370 | | .error_union => |error_union| switch (error_union.val) { |
| 371 | | .err_name => val, |
| 372 | | .payload => |payload| Tag.eu_payload.create(arena, Value.fromInterned(payload)), |
| 373 | | }, |
| 374 | | |
| 375 | | .slice => |slice| Tag.slice.create(arena, .{ |
| 376 | | .ptr = Value.fromInterned(slice.ptr), |
| 377 | | .len = Value.fromInterned(slice.len), |
| 378 | | }), |
| 379 | | |
| 380 | | .opt => |opt| switch (opt.val) { |
| 381 | | .none => val, |
| 382 | | else => |payload| Tag.opt_payload.create(arena, Value.fromInterned(payload)), |
| 383 | | }, |
| 384 | | |
| 385 | | .aggregate => |aggregate| switch (aggregate.storage) { |
| 386 | | .bytes => |bytes| Tag.bytes.create(arena, try arena.dupe(u8, bytes)), |
| 387 | | .elems => |old_elems| { |
| 388 | | const new_elems = try arena.alloc(Value, old_elems.len); |
| 389 | | for (new_elems, old_elems) |*new_elem, old_elem| new_elem.* = Value.fromInterned(old_elem); |
| 390 | | return Tag.aggregate.create(arena, new_elems); |
| 391 | | }, |
| 392 | | .repeated_elem => |elem| Tag.repeated.create(arena, Value.fromInterned(elem)), |
| 393 | | }, |
| 394 | | |
| 395 | | .un => |un| Tag.@"union".create(arena, .{ |
| 396 | | // toValue asserts that the value cannot be .none which is valid on unions. |
| 397 | | .tag = if (un.tag == .none) null else Value.fromInterned(un.tag), |
| 398 | | .val = Value.fromInterned(un.val), |
| 399 | | }), |
| 400 | | |
| 401 | | .memoized_call => unreachable, |
| 402 | | }; |
| 403 | | } |
| 404 | | |
| 405 | 113 | pub fn fromInterned(i: InternPool.Index) Value { |
| 406 | 114 | assert(i != .none); |
| 407 | | return .{ |
| 408 | | .ip_index = i, |
| 409 | | .legacy = undefined, |
| 410 | | }; |
| 115 | return .{ .ip_index = i }; |
| 411 | 116 | } |
| 412 | 117 | |
| 413 | 118 | pub fn toIntern(val: Value) InternPool.Index { |
| ... | ... | @@ -492,24 +197,24 @@ pub fn isFuncBody(val: Value, mod: *Module) bool { |
| 492 | 197 | } |
| 493 | 198 | |
| 494 | 199 | pub fn getFunction(val: Value, mod: *Module) ?InternPool.Key.Func { |
| 495 | | return if (val.ip_index != .none) switch (mod.intern_pool.indexToKey(val.toIntern())) { |
| 200 | return switch (mod.intern_pool.indexToKey(val.toIntern())) { |
| 496 | 201 | .func => |x| x, |
| 497 | 202 | else => null, |
| 498 | | } else null; |
| 203 | }; |
| 499 | 204 | } |
| 500 | 205 | |
| 501 | 206 | pub fn getExternFunc(val: Value, mod: *Module) ?InternPool.Key.ExternFunc { |
| 502 | | return if (val.ip_index != .none) switch (mod.intern_pool.indexToKey(val.toIntern())) { |
| 207 | return switch (mod.intern_pool.indexToKey(val.toIntern())) { |
| 503 | 208 | .extern_func => |extern_func| extern_func, |
| 504 | 209 | else => null, |
| 505 | | } else null; |
| 210 | }; |
| 506 | 211 | } |
| 507 | 212 | |
| 508 | 213 | pub fn getVariable(val: Value, mod: *Module) ?InternPool.Key.Variable { |
| 509 | | return if (val.ip_index != .none) switch (mod.intern_pool.indexToKey(val.toIntern())) { |
| 214 | return switch (mod.intern_pool.indexToKey(val.toIntern())) { |
| 510 | 215 | .variable => |variable| variable, |
| 511 | 216 | else => null, |
| 512 | | } else null; |
| 217 | }; |
| 513 | 218 | } |
| 514 | 219 | |
| 515 | 220 | /// If the value fits in a u64, return it, otherwise null. |
| ... | ... | @@ -677,25 +382,14 @@ pub fn writeToMemory(val: Value, ty: Type, mod: *Module, buffer: []u8) error{ |
| 677 | 382 | .auto => return error.IllDefinedMemoryLayout, |
| 678 | 383 | .@"extern" => for (0..struct_type.field_types.len) |i| { |
| 679 | 384 | const off: usize = @intCast(ty.structFieldOffset(i, mod)); |
| 680 | | const field_val = switch (val.ip_index) { |
| 681 | | .none => switch (val.tag()) { |
| 682 | | .bytes => { |
| 683 | | buffer[off] = val.castTag(.bytes).?.data[i]; |
| 684 | | continue; |
| 685 | | }, |
| 686 | | .aggregate => val.castTag(.aggregate).?.data[i], |
| 687 | | .repeated => val.castTag(.repeated).?.data, |
| 688 | | else => unreachable, |
| 385 | const field_val = Value.fromInterned(switch (ip.indexToKey(val.toIntern()).aggregate.storage) { |
| 386 | .bytes => |bytes| { |
| 387 | buffer[off] = bytes[i]; |
| 388 | continue; |
| 689 | 389 | }, |
| 690 | | else => Value.fromInterned(switch (ip.indexToKey(val.toIntern()).aggregate.storage) { |
| 691 | | .bytes => |bytes| { |
| 692 | | buffer[off] = bytes[i]; |
| 693 | | continue; |
| 694 | | }, |
| 695 | | .elems => |elems| elems[i], |
| 696 | | .repeated_elem => |elem| elem, |
| 697 | | }), |
| 698 | | }; |
| 390 | .elems => |elems| elems[i], |
| 391 | .repeated_elem => |elem| elem, |
| 392 | }); |
| 699 | 393 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]); |
| 700 | 394 | try writeToMemory(field_val, field_ty, mod, buffer[off..]); |
| 701 | 395 | }, |
| ... | ... | @@ -842,19 +536,11 @@ pub fn writeToPackedMemory( |
| 842 | 536 | assert(struct_type.layout == .@"packed"); |
| 843 | 537 | var bits: u16 = 0; |
| 844 | 538 | for (0..struct_type.field_types.len) |i| { |
| 845 | | const field_val = switch (val.ip_index) { |
| 846 | | .none => switch (val.tag()) { |
| 847 | | .bytes => unreachable, |
| 848 | | .aggregate => val.castTag(.aggregate).?.data[i], |
| 849 | | .repeated => val.castTag(.repeated).?.data, |
| 850 | | else => unreachable, |
| 851 | | }, |
| 852 | | else => Value.fromInterned(switch (ip.indexToKey(val.toIntern()).aggregate.storage) { |
| 853 | | .bytes => unreachable, |
| 854 | | .elems => |elems| elems[i], |
| 855 | | .repeated_elem => |elem| elem, |
| 856 | | }), |
| 857 | | }; |
| 539 | const field_val = Value.fromInterned(switch (ip.indexToKey(val.toIntern()).aggregate.storage) { |
| 540 | .bytes => unreachable, |
| 541 | .elems => |elems| elems[i], |
| 542 | .repeated_elem => |elem| elem, |
| 543 | }); |
| 858 | 544 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]); |
| 859 | 545 | const field_bits: u16 = @intCast(field_ty.bitSize(mod)); |
| 860 | 546 | try field_val.writeToPackedMemory(field_ty, mod, buffer, bit_offset + bits); |
| ... | ... | @@ -972,7 +658,7 @@ pub fn readFromMemory( |
| 972 | 658 | const elems = try arena.alloc(InternPool.Index, @as(usize, @intCast(ty.arrayLen(mod)))); |
| 973 | 659 | var offset: usize = 0; |
| 974 | 660 | for (elems) |*elem| { |
| 975 | | elem.* = try (try readFromMemory(elem_ty, mod, buffer[offset..], arena)).intern(elem_ty, mod); |
| 661 | elem.* = (try readFromMemory(elem_ty, mod, buffer[offset..], arena)).toIntern(); |
| 976 | 662 | offset += @as(usize, @intCast(elem_size)); |
| 977 | 663 | } |
| 978 | 664 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| ... | ... | @@ -997,7 +683,7 @@ pub fn readFromMemory( |
| 997 | 683 | const field_ty = Type.fromInterned(field_types.get(ip)[i]); |
| 998 | 684 | const off: usize = @intCast(ty.structFieldOffset(i, mod)); |
| 999 | 685 | const sz: usize = @intCast(field_ty.abiSize(mod)); |
| 1000 | | field_val.* = try (try readFromMemory(field_ty, mod, buffer[off..(off + sz)], arena)).intern(field_ty, mod); |
| 686 | field_val.* = (try readFromMemory(field_ty, mod, buffer[off..(off + sz)], arena)).toIntern(); |
| 1001 | 687 | } |
| 1002 | 688 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 1003 | 689 | .ty = ty.toIntern(), |
| ... | ... | @@ -1027,7 +713,7 @@ pub fn readFromMemory( |
| 1027 | 713 | .@"extern" => { |
| 1028 | 714 | const union_size = ty.abiSize(mod); |
| 1029 | 715 | const array_ty = try mod.arrayType(.{ .len = union_size, .child = .u8_type }); |
| 1030 | | const val = try (try readFromMemory(array_ty, mod, buffer, arena)).intern(array_ty, mod); |
| 716 | const val = (try readFromMemory(array_ty, mod, buffer, arena)).toIntern(); |
| 1031 | 717 | return Value.fromInterned((try mod.intern(.{ .un = .{ |
| 1032 | 718 | .ty = ty.toIntern(), |
| 1033 | 719 | .tag = .none, |
| ... | ... | @@ -1094,7 +780,7 @@ pub fn readFromPackedMemory( |
| 1094 | 780 | return Value.true; |
| 1095 | 781 | } |
| 1096 | 782 | }, |
| 1097 | | .Int, .Enum => |ty_tag| { |
| 783 | .Int => { |
| 1098 | 784 | if (buffer.len == 0) return mod.intValue(ty, 0); |
| 1099 | 785 | const int_info = ty.intInfo(mod); |
| 1100 | 786 | const bits = int_info.bits; |
| ... | ... | @@ -1102,21 +788,10 @@ pub fn readFromPackedMemory( |
| 1102 | 788 | |
| 1103 | 789 | // Fast path for integers <= u64 |
| 1104 | 790 | if (bits <= 64) { |
| 1105 | | const int_ty = switch (ty_tag) { |
| 1106 | | .Int => ty, |
| 1107 | | .Enum => ty.intTagType(mod), |
| 1108 | | else => unreachable, |
| 1109 | | }; |
| 1110 | | return mod.getCoerced(switch (int_info.signedness) { |
| 1111 | | .signed => return mod.intValue( |
| 1112 | | int_ty, |
| 1113 | | std.mem.readVarPackedInt(i64, buffer, bit_offset, bits, endian, .signed), |
| 1114 | | ), |
| 1115 | | .unsigned => return mod.intValue( |
| 1116 | | int_ty, |
| 1117 | | std.mem.readVarPackedInt(u64, buffer, bit_offset, bits, endian, .unsigned), |
| 1118 | | ), |
| 1119 | | }, ty); |
| 791 | return mod.intValue( |
| 792 | ty, |
| 793 | std.mem.readVarPackedInt(i64, buffer, bit_offset, bits, endian, int_info.signedness), |
| 794 | ); |
| 1120 | 795 | } |
| 1121 | 796 | |
| 1122 | 797 | // Slow path, we have to construct a big-int |
| ... | ... | @@ -1129,6 +804,11 @@ pub fn readFromPackedMemory( |
| 1129 | 804 | bigint.readPackedTwosComplement(buffer, bit_offset, bits, endian, int_info.signedness); |
| 1130 | 805 | return mod.intValue_big(ty, bigint.toConst()); |
| 1131 | 806 | }, |
| 807 | .Enum => { |
| 808 | const int_ty = ty.intTagType(mod); |
| 809 | const int_val = try Value.readFromPackedMemory(int_ty, mod, buffer, bit_offset, arena); |
| 810 | return mod.getCoerced(int_val, ty); |
| 811 | }, |
| 1132 | 812 | .Float => return Value.fromInterned((try mod.intern(.{ .float = .{ |
| 1133 | 813 | .ty = ty.toIntern(), |
| 1134 | 814 | .storage = switch (ty.floatBits(target)) { |
| ... | ... | @@ -1149,7 +829,7 @@ pub fn readFromPackedMemory( |
| 1149 | 829 | for (elems, 0..) |_, i| { |
| 1150 | 830 | // On big-endian systems, LLVM reverses the element order of vectors by default |
| 1151 | 831 | const tgt_elem_i = if (endian == .big) elems.len - i - 1 else i; |
| 1152 | | elems[tgt_elem_i] = try (try readFromPackedMemory(elem_ty, mod, buffer, bit_offset + bits, arena)).intern(elem_ty, mod); |
| 832 | elems[tgt_elem_i] = (try readFromPackedMemory(elem_ty, mod, buffer, bit_offset + bits, arena)).toIntern(); |
| 1153 | 833 | bits += elem_bit_size; |
| 1154 | 834 | } |
| 1155 | 835 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| ... | ... | @@ -1166,7 +846,7 @@ pub fn readFromPackedMemory( |
| 1166 | 846 | for (field_vals, 0..) |*field_val, i| { |
| 1167 | 847 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]); |
| 1168 | 848 | const field_bits: u16 = @intCast(field_ty.bitSize(mod)); |
| 1169 | | field_val.* = try (try readFromPackedMemory(field_ty, mod, buffer, bit_offset + bits, arena)).intern(field_ty, mod); |
| 849 | field_val.* = (try readFromPackedMemory(field_ty, mod, buffer, bit_offset + bits, arena)).toIntern(); |
| 1170 | 850 | bits += field_bits; |
| 1171 | 851 | } |
| 1172 | 852 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| ... | ... | @@ -1611,51 +1291,42 @@ pub fn maybeElemValue(val: Value, mod: *Module, index: usize) Allocator.Error!?V |
| 1611 | 1291 | } |
| 1612 | 1292 | |
| 1613 | 1293 | pub fn maybeElemValueFull(val: Value, sema: ?*Sema, mod: *Module, index: usize) Allocator.Error!?Value { |
| 1614 | | return switch (val.ip_index) { |
| 1615 | | .none => switch (val.tag()) { |
| 1616 | | .bytes => try mod.intValue(Type.u8, val.castTag(.bytes).?.data[index]), |
| 1617 | | .repeated => val.castTag(.repeated).?.data, |
| 1618 | | .aggregate => val.castTag(.aggregate).?.data[index], |
| 1619 | | .slice => val.castTag(.slice).?.data.ptr.maybeElemValueFull(sema, mod, index), |
| 1620 | | else => null, |
| 1621 | | }, |
| 1622 | | else => switch (mod.intern_pool.indexToKey(val.toIntern())) { |
| 1623 | | .undef => |ty| Value.fromInterned((try mod.intern(.{ |
| 1624 | | .undef = Type.fromInterned(ty).elemType2(mod).toIntern(), |
| 1625 | | }))), |
| 1626 | | .slice => |slice| return Value.fromInterned(slice.ptr).maybeElemValueFull(sema, mod, index), |
| 1627 | | .ptr => |ptr| switch (ptr.addr) { |
| 1628 | | .decl => |decl| mod.declPtr(decl).val.maybeElemValueFull(sema, mod, index), |
| 1629 | | .anon_decl => |anon_decl| Value.fromInterned(anon_decl.val).maybeElemValueFull(sema, mod, index), |
| 1630 | | .comptime_alloc => |idx| if (sema) |s| Value.fromInterned( |
| 1631 | | try s.getComptimeAlloc(idx).val.intern(mod, s.arena), |
| 1632 | | ).maybeElemValueFull(sema, mod, index) else null, |
| 1633 | | .int, .eu_payload => null, |
| 1634 | | .opt_payload => |base| Value.fromInterned(base).maybeElemValueFull(sema, mod, index), |
| 1635 | | .comptime_field => |field_val| Value.fromInterned(field_val).maybeElemValueFull(sema, mod, index), |
| 1636 | | .elem => |elem| Value.fromInterned(elem.base).maybeElemValueFull(sema, mod, index + @as(usize, @intCast(elem.index))), |
| 1637 | | .field => |field| if (Value.fromInterned(field.base).pointerDecl(mod)) |decl_index| { |
| 1638 | | const base_decl = mod.declPtr(decl_index); |
| 1639 | | const field_val = try base_decl.val.fieldValue(mod, @as(usize, @intCast(field.index))); |
| 1640 | | return field_val.maybeElemValueFull(sema, mod, index); |
| 1641 | | } else null, |
| 1642 | | }, |
| 1643 | | .opt => |opt| Value.fromInterned(opt.val).maybeElemValueFull(sema, mod, index), |
| 1644 | | .aggregate => |aggregate| { |
| 1645 | | const len = mod.intern_pool.aggregateTypeLen(aggregate.ty); |
| 1646 | | if (index < len) return Value.fromInterned(switch (aggregate.storage) { |
| 1647 | | .bytes => |bytes| try mod.intern(.{ .int = .{ |
| 1648 | | .ty = .u8_type, |
| 1649 | | .storage = .{ .u64 = bytes[index] }, |
| 1650 | | } }), |
| 1651 | | .elems => |elems| elems[index], |
| 1652 | | .repeated_elem => |elem| elem, |
| 1653 | | }); |
| 1654 | | assert(index == len); |
| 1655 | | return Value.fromInterned(mod.intern_pool.indexToKey(aggregate.ty).array_type.sentinel); |
| 1656 | | }, |
| 1657 | | else => null, |
| 1294 | return switch (mod.intern_pool.indexToKey(val.toIntern())) { |
| 1295 | .undef => |ty| Value.fromInterned((try mod.intern(.{ |
| 1296 | .undef = Type.fromInterned(ty).elemType2(mod).toIntern(), |
| 1297 | }))), |
| 1298 | .slice => |slice| return Value.fromInterned(slice.ptr).maybeElemValueFull(sema, mod, index), |
| 1299 | .ptr => |ptr| switch (ptr.addr) { |
| 1300 | .decl => |decl| mod.declPtr(decl).val.maybeElemValueFull(sema, mod, index), |
| 1301 | .anon_decl => |anon_decl| Value.fromInterned(anon_decl.val).maybeElemValueFull(sema, mod, index), |
| 1302 | .comptime_alloc => |idx| if (sema) |s| Value.fromInterned( |
| 1303 | try s.getComptimeAlloc(idx).val.intern(mod, s.arena), |
| 1304 | ).maybeElemValueFull(sema, mod, index) else null, |
| 1305 | .int, .eu_payload => null, |
| 1306 | .opt_payload => |base| Value.fromInterned(base).maybeElemValueFull(sema, mod, index), |
| 1307 | .comptime_field => |field_val| Value.fromInterned(field_val).maybeElemValueFull(sema, mod, index), |
| 1308 | .elem => |elem| Value.fromInterned(elem.base).maybeElemValueFull(sema, mod, index + @as(usize, @intCast(elem.index))), |
| 1309 | .field => |field| if (Value.fromInterned(field.base).pointerDecl(mod)) |decl_index| { |
| 1310 | const base_decl = mod.declPtr(decl_index); |
| 1311 | const field_val = try base_decl.val.fieldValue(mod, @as(usize, @intCast(field.index))); |
| 1312 | return field_val.maybeElemValueFull(sema, mod, index); |
| 1313 | } else null, |
| 1314 | }, |
| 1315 | .opt => |opt| Value.fromInterned(opt.val).maybeElemValueFull(sema, mod, index), |
| 1316 | .aggregate => |aggregate| { |
| 1317 | const len = mod.intern_pool.aggregateTypeLen(aggregate.ty); |
| 1318 | if (index < len) return Value.fromInterned(switch (aggregate.storage) { |
| 1319 | .bytes => |bytes| try mod.intern(.{ .int = .{ |
| 1320 | .ty = .u8_type, |
| 1321 | .storage = .{ .u64 = bytes[index] }, |
| 1322 | } }), |
| 1323 | .elems => |elems| elems[index], |
| 1324 | .repeated_elem => |elem| elem, |
| 1325 | }); |
| 1326 | assert(index == len); |
| 1327 | return Value.fromInterned(mod.intern_pool.indexToKey(aggregate.ty).array_type.sentinel); |
| 1658 | 1328 | }, |
| 1329 | else => null, |
| 1659 | 1330 | }; |
| 1660 | 1331 | } |
| 1661 | 1332 | |
| ... | ... | @@ -1688,85 +1359,61 @@ pub fn sliceArray( |
| 1688 | 1359 | ) error{OutOfMemory}!Value { |
| 1689 | 1360 | // TODO: write something like getCoercedInts to avoid needing to dupe |
| 1690 | 1361 | const mod = sema.mod; |
| 1691 | | return switch (val.ip_index) { |
| 1692 | | .none => switch (val.tag()) { |
| 1693 | | .slice => val.castTag(.slice).?.data.ptr.sliceArray(sema, start, end), |
| 1694 | | .bytes => Tag.bytes.create(sema.arena, val.castTag(.bytes).?.data[start..end]), |
| 1695 | | .repeated => val, |
| 1696 | | .aggregate => Tag.aggregate.create(sema.arena, val.castTag(.aggregate).?.data[start..end]), |
| 1362 | return switch (mod.intern_pool.indexToKey(val.toIntern())) { |
| 1363 | .ptr => |ptr| switch (ptr.addr) { |
| 1364 | .decl => |decl| try mod.declPtr(decl).val.sliceArray(sema, start, end), |
| 1365 | .comptime_alloc => |idx| try Value.fromInterned( |
| 1366 | try sema.getComptimeAlloc(idx).val.intern(mod, sema.arena), |
| 1367 | ).sliceArray(sema, start, end), |
| 1368 | .comptime_field => |comptime_field| Value.fromInterned(comptime_field) |
| 1369 | .sliceArray(sema, start, end), |
| 1370 | .elem => |elem| Value.fromInterned(elem.base) |
| 1371 | .sliceArray(sema, start + @as(usize, @intCast(elem.index)), end + @as(usize, @intCast(elem.index))), |
| 1697 | 1372 | else => unreachable, |
| 1698 | 1373 | }, |
| 1699 | | else => switch (mod.intern_pool.indexToKey(val.toIntern())) { |
| 1700 | | .ptr => |ptr| switch (ptr.addr) { |
| 1701 | | .decl => |decl| try mod.declPtr(decl).val.sliceArray(sema, start, end), |
| 1702 | | .comptime_alloc => |idx| try Value.fromInterned( |
| 1703 | | try sema.getComptimeAlloc(idx).val.intern(mod, sema.arena), |
| 1704 | | ).sliceArray(sema, start, end), |
| 1705 | | .comptime_field => |comptime_field| Value.fromInterned(comptime_field) |
| 1706 | | .sliceArray(sema, start, end), |
| 1707 | | .elem => |elem| Value.fromInterned(elem.base) |
| 1708 | | .sliceArray(sema, start + @as(usize, @intCast(elem.index)), end + @as(usize, @intCast(elem.index))), |
| 1374 | .aggregate => |aggregate| Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 1375 | .ty = switch (mod.intern_pool.indexToKey(mod.intern_pool.typeOf(val.toIntern()))) { |
| 1376 | .array_type => |array_type| try mod.arrayType(.{ |
| 1377 | .len = @as(u32, @intCast(end - start)), |
| 1378 | .child = array_type.child, |
| 1379 | .sentinel = if (end == array_type.len) array_type.sentinel else .none, |
| 1380 | }), |
| 1381 | .vector_type => |vector_type| try mod.vectorType(.{ |
| 1382 | .len = @as(u32, @intCast(end - start)), |
| 1383 | .child = vector_type.child, |
| 1384 | }), |
| 1709 | 1385 | else => unreachable, |
| 1386 | }.toIntern(), |
| 1387 | .storage = switch (aggregate.storage) { |
| 1388 | .bytes => .{ .bytes = try sema.arena.dupe(u8, mod.intern_pool.indexToKey(val.toIntern()).aggregate.storage.bytes[start..end]) }, |
| 1389 | .elems => .{ .elems = try sema.arena.dupe(InternPool.Index, mod.intern_pool.indexToKey(val.toIntern()).aggregate.storage.elems[start..end]) }, |
| 1390 | .repeated_elem => |elem| .{ .repeated_elem = elem }, |
| 1710 | 1391 | }, |
| 1711 | | .aggregate => |aggregate| Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 1712 | | .ty = switch (mod.intern_pool.indexToKey(mod.intern_pool.typeOf(val.toIntern()))) { |
| 1713 | | .array_type => |array_type| try mod.arrayType(.{ |
| 1714 | | .len = @as(u32, @intCast(end - start)), |
| 1715 | | .child = array_type.child, |
| 1716 | | .sentinel = if (end == array_type.len) array_type.sentinel else .none, |
| 1717 | | }), |
| 1718 | | .vector_type => |vector_type| try mod.vectorType(.{ |
| 1719 | | .len = @as(u32, @intCast(end - start)), |
| 1720 | | .child = vector_type.child, |
| 1721 | | }), |
| 1722 | | else => unreachable, |
| 1723 | | }.toIntern(), |
| 1724 | | .storage = switch (aggregate.storage) { |
| 1725 | | .bytes => .{ .bytes = try sema.arena.dupe(u8, mod.intern_pool.indexToKey(val.toIntern()).aggregate.storage.bytes[start..end]) }, |
| 1726 | | .elems => .{ .elems = try sema.arena.dupe(InternPool.Index, mod.intern_pool.indexToKey(val.toIntern()).aggregate.storage.elems[start..end]) }, |
| 1727 | | .repeated_elem => |elem| .{ .repeated_elem = elem }, |
| 1728 | | }, |
| 1729 | | } }))), |
| 1730 | | else => unreachable, |
| 1731 | | }, |
| 1392 | } }))), |
| 1393 | else => unreachable, |
| 1732 | 1394 | }; |
| 1733 | 1395 | } |
| 1734 | 1396 | |
| 1735 | 1397 | pub fn fieldValue(val: Value, mod: *Module, index: usize) !Value { |
| 1736 | | return switch (val.ip_index) { |
| 1737 | | .none => switch (val.tag()) { |
| 1738 | | .aggregate => { |
| 1739 | | const field_values = val.castTag(.aggregate).?.data; |
| 1740 | | return field_values[index]; |
| 1741 | | }, |
| 1742 | | .@"union" => { |
| 1743 | | const payload = val.castTag(.@"union").?.data; |
| 1744 | | // TODO assert the tag is correct |
| 1745 | | return payload.val; |
| 1746 | | }, |
| 1747 | | else => unreachable, |
| 1748 | | }, |
| 1749 | | else => switch (mod.intern_pool.indexToKey(val.toIntern())) { |
| 1750 | | .undef => |ty| Value.fromInterned((try mod.intern(.{ |
| 1751 | | .undef = Type.fromInterned(ty).structFieldType(index, mod).toIntern(), |
| 1752 | | }))), |
| 1753 | | .aggregate => |aggregate| Value.fromInterned(switch (aggregate.storage) { |
| 1754 | | .bytes => |bytes| try mod.intern(.{ .int = .{ |
| 1755 | | .ty = .u8_type, |
| 1756 | | .storage = .{ .u64 = bytes[index] }, |
| 1757 | | } }), |
| 1758 | | .elems => |elems| elems[index], |
| 1759 | | .repeated_elem => |elem| elem, |
| 1760 | | }), |
| 1761 | | // TODO assert the tag is correct |
| 1762 | | .un => |un| Value.fromInterned(un.val), |
| 1763 | | else => unreachable, |
| 1764 | | }, |
| 1398 | return switch (mod.intern_pool.indexToKey(val.toIntern())) { |
| 1399 | .undef => |ty| Value.fromInterned((try mod.intern(.{ |
| 1400 | .undef = Type.fromInterned(ty).structFieldType(index, mod).toIntern(), |
| 1401 | }))), |
| 1402 | .aggregate => |aggregate| Value.fromInterned(switch (aggregate.storage) { |
| 1403 | .bytes => |bytes| try mod.intern(.{ .int = .{ |
| 1404 | .ty = .u8_type, |
| 1405 | .storage = .{ .u64 = bytes[index] }, |
| 1406 | } }), |
| 1407 | .elems => |elems| elems[index], |
| 1408 | .repeated_elem => |elem| elem, |
| 1409 | }), |
| 1410 | // TODO assert the tag is correct |
| 1411 | .un => |un| Value.fromInterned(un.val), |
| 1412 | else => unreachable, |
| 1765 | 1413 | }; |
| 1766 | 1414 | } |
| 1767 | 1415 | |
| 1768 | 1416 | pub fn unionTag(val: Value, mod: *Module) ?Value { |
| 1769 | | if (val.ip_index == .none) return val.castTag(.@"union").?.data.tag; |
| 1770 | 1417 | return switch (mod.intern_pool.indexToKey(val.toIntern())) { |
| 1771 | 1418 | .undef, .enum_tag => val, |
| 1772 | 1419 | .un => |un| if (un.tag != .none) Value.fromInterned(un.tag) else return null, |
| ... | ... | @@ -1775,7 +1422,6 @@ pub fn unionTag(val: Value, mod: *Module) ?Value { |
| 1775 | 1422 | } |
| 1776 | 1423 | |
| 1777 | 1424 | pub fn unionValue(val: Value, mod: *Module) Value { |
| 1778 | | if (val.ip_index == .none) return val.castTag(.@"union").?.data.val; |
| 1779 | 1425 | return switch (mod.intern_pool.indexToKey(val.toIntern())) { |
| 1780 | 1426 | .un => |un| Value.fromInterned(un.val), |
| 1781 | 1427 | else => unreachable, |
| ... | ... | @@ -1821,7 +1467,7 @@ pub fn elemPtr( |
| 1821 | 1467 | } |
| 1822 | 1468 | |
| 1823 | 1469 | pub fn isUndef(val: Value, mod: *Module) bool { |
| 1824 | | return val.ip_index != .none and mod.intern_pool.isUndef(val.toIntern()); |
| 1470 | return mod.intern_pool.isUndef(val.toIntern()); |
| 1825 | 1471 | } |
| 1826 | 1472 | |
| 1827 | 1473 | /// TODO: check for cases such as array that is not marked undef but all the element |
| ... | ... | @@ -1915,7 +1561,7 @@ pub fn floatFromIntAdvanced(val: Value, arena: Allocator, int_ty: Type, float_ty |
| 1915 | 1561 | const scalar_ty = float_ty.scalarType(mod); |
| 1916 | 1562 | for (result_data, 0..) |*scalar, i| { |
| 1917 | 1563 | const elem_val = try val.elemValue(mod, i); |
| 1918 | | scalar.* = try (try floatFromIntScalar(elem_val, scalar_ty, mod, opt_sema)).intern(scalar_ty, mod); |
| 1564 | scalar.* = (try floatFromIntScalar(elem_val, scalar_ty, mod, opt_sema)).toIntern(); |
| 1919 | 1565 | } |
| 1920 | 1566 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 1921 | 1567 | .ty = float_ty.toIntern(), |
| ... | ... | @@ -1993,7 +1639,7 @@ pub fn intAddSat( |
| 1993 | 1639 | for (result_data, 0..) |*scalar, i| { |
| 1994 | 1640 | const lhs_elem = try lhs.elemValue(mod, i); |
| 1995 | 1641 | const rhs_elem = try rhs.elemValue(mod, i); |
| 1996 | | scalar.* = try (try intAddSatScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod)).intern(scalar_ty, mod); |
| 1642 | scalar.* = (try intAddSatScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod)).toIntern(); |
| 1997 | 1643 | } |
| 1998 | 1644 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 1999 | 1645 | .ty = ty.toIntern(), |
| ... | ... | @@ -2043,7 +1689,7 @@ pub fn intSubSat( |
| 2043 | 1689 | for (result_data, 0..) |*scalar, i| { |
| 2044 | 1690 | const lhs_elem = try lhs.elemValue(mod, i); |
| 2045 | 1691 | const rhs_elem = try rhs.elemValue(mod, i); |
| 2046 | | scalar.* = try (try intSubSatScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod)).intern(scalar_ty, mod); |
| 1692 | scalar.* = (try intSubSatScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod)).toIntern(); |
| 2047 | 1693 | } |
| 2048 | 1694 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 2049 | 1695 | .ty = ty.toIntern(), |
| ... | ... | @@ -2095,8 +1741,8 @@ pub fn intMulWithOverflow( |
| 2095 | 1741 | const lhs_elem = try lhs.elemValue(mod, i); |
| 2096 | 1742 | const rhs_elem = try rhs.elemValue(mod, i); |
| 2097 | 1743 | const of_math_result = try intMulWithOverflowScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod); |
| 2098 | | of.* = try of_math_result.overflow_bit.intern(Type.u1, mod); |
| 2099 | | scalar.* = try of_math_result.wrapped_result.intern(scalar_ty, mod); |
| 1744 | of.* = of_math_result.overflow_bit.toIntern(); |
| 1745 | scalar.* = of_math_result.wrapped_result.toIntern(); |
| 2100 | 1746 | } |
| 2101 | 1747 | return OverflowArithmeticResult{ |
| 2102 | 1748 | .overflow_bit = Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| ... | ... | @@ -2161,7 +1807,7 @@ pub fn numberMulWrap( |
| 2161 | 1807 | for (result_data, 0..) |*scalar, i| { |
| 2162 | 1808 | const lhs_elem = try lhs.elemValue(mod, i); |
| 2163 | 1809 | const rhs_elem = try rhs.elemValue(mod, i); |
| 2164 | | scalar.* = try (try numberMulWrapScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod)).intern(scalar_ty, mod); |
| 1810 | scalar.* = (try numberMulWrapScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod)).toIntern(); |
| 2165 | 1811 | } |
| 2166 | 1812 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 2167 | 1813 | .ty = ty.toIntern(), |
| ... | ... | @@ -2207,7 +1853,7 @@ pub fn intMulSat( |
| 2207 | 1853 | for (result_data, 0..) |*scalar, i| { |
| 2208 | 1854 | const lhs_elem = try lhs.elemValue(mod, i); |
| 2209 | 1855 | const rhs_elem = try rhs.elemValue(mod, i); |
| 2210 | | scalar.* = try (try intMulSatScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod)).intern(scalar_ty, mod); |
| 1856 | scalar.* = (try intMulSatScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod)).toIntern(); |
| 2211 | 1857 | } |
| 2212 | 1858 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 2213 | 1859 | .ty = ty.toIntern(), |
| ... | ... | @@ -2283,7 +1929,7 @@ pub fn bitwiseNot(val: Value, ty: Type, arena: Allocator, mod: *Module) !Value { |
| 2283 | 1929 | const scalar_ty = ty.scalarType(mod); |
| 2284 | 1930 | for (result_data, 0..) |*scalar, i| { |
| 2285 | 1931 | const elem_val = try val.elemValue(mod, i); |
| 2286 | | scalar.* = try (try bitwiseNotScalar(elem_val, scalar_ty, arena, mod)).intern(scalar_ty, mod); |
| 1932 | scalar.* = (try bitwiseNotScalar(elem_val, scalar_ty, arena, mod)).toIntern(); |
| 2287 | 1933 | } |
| 2288 | 1934 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 2289 | 1935 | .ty = ty.toIntern(), |
| ... | ... | @@ -2326,7 +1972,7 @@ pub fn bitwiseAnd(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: * |
| 2326 | 1972 | for (result_data, 0..) |*scalar, i| { |
| 2327 | 1973 | const lhs_elem = try lhs.elemValue(mod, i); |
| 2328 | 1974 | const rhs_elem = try rhs.elemValue(mod, i); |
| 2329 | | scalar.* = try (try bitwiseAndScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod)).intern(scalar_ty, mod); |
| 1975 | scalar.* = (try bitwiseAndScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod)).toIntern(); |
| 2330 | 1976 | } |
| 2331 | 1977 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 2332 | 1978 | .ty = ty.toIntern(), |
| ... | ... | @@ -2365,7 +2011,7 @@ pub fn bitwiseNand(lhs: Value, rhs: Value, ty: Type, arena: Allocator, mod: *Mod |
| 2365 | 2011 | for (result_data, 0..) |*scalar, i| { |
| 2366 | 2012 | const lhs_elem = try lhs.elemValue(mod, i); |
| 2367 | 2013 | const rhs_elem = try rhs.elemValue(mod, i); |
| 2368 | | scalar.* = try (try bitwiseNandScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod)).intern(scalar_ty, mod); |
| 2014 | scalar.* = (try bitwiseNandScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod)).toIntern(); |
| 2369 | 2015 | } |
| 2370 | 2016 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 2371 | 2017 | .ty = ty.toIntern(), |
| ... | ... | @@ -2393,7 +2039,7 @@ pub fn bitwiseOr(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *M |
| 2393 | 2039 | for (result_data, 0..) |*scalar, i| { |
| 2394 | 2040 | const lhs_elem = try lhs.elemValue(mod, i); |
| 2395 | 2041 | const rhs_elem = try rhs.elemValue(mod, i); |
| 2396 | | scalar.* = try (try bitwiseOrScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod)).intern(scalar_ty, mod); |
| 2042 | scalar.* = (try bitwiseOrScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod)).toIntern(); |
| 2397 | 2043 | } |
| 2398 | 2044 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 2399 | 2045 | .ty = ty.toIntern(), |
| ... | ... | @@ -2431,7 +2077,7 @@ pub fn bitwiseXor(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: * |
| 2431 | 2077 | for (result_data, 0..) |*scalar, i| { |
| 2432 | 2078 | const lhs_elem = try lhs.elemValue(mod, i); |
| 2433 | 2079 | const rhs_elem = try rhs.elemValue(mod, i); |
| 2434 | | scalar.* = try (try bitwiseXorScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod)).intern(scalar_ty, mod); |
| 2080 | scalar.* = (try bitwiseXorScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod)).toIntern(); |
| 2435 | 2081 | } |
| 2436 | 2082 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 2437 | 2083 | .ty = ty.toIntern(), |
| ... | ... | @@ -2497,7 +2143,7 @@ fn intDivInner(lhs: Value, rhs: Value, ty: Type, overflow_idx: *usize, allocator |
| 2497 | 2143 | }, |
| 2498 | 2144 | else => |e| return e, |
| 2499 | 2145 | }; |
| 2500 | | scalar.* = try val.intern(scalar_ty, mod); |
| 2146 | scalar.* = val.toIntern(); |
| 2501 | 2147 | } |
| 2502 | 2148 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 2503 | 2149 | .ty = ty.toIntern(), |
| ... | ... | @@ -2545,7 +2191,7 @@ pub fn intDivFloor(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: |
| 2545 | 2191 | for (result_data, 0..) |*scalar, i| { |
| 2546 | 2192 | const lhs_elem = try lhs.elemValue(mod, i); |
| 2547 | 2193 | const rhs_elem = try rhs.elemValue(mod, i); |
| 2548 | | scalar.* = try (try intDivFloorScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod)).intern(scalar_ty, mod); |
| 2194 | scalar.* = (try intDivFloorScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod)).toIntern(); |
| 2549 | 2195 | } |
| 2550 | 2196 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 2551 | 2197 | .ty = ty.toIntern(), |
| ... | ... | @@ -2587,7 +2233,7 @@ pub fn intMod(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Modu |
| 2587 | 2233 | for (result_data, 0..) |*scalar, i| { |
| 2588 | 2234 | const lhs_elem = try lhs.elemValue(mod, i); |
| 2589 | 2235 | const rhs_elem = try rhs.elemValue(mod, i); |
| 2590 | | scalar.* = try (try intModScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod)).intern(scalar_ty, mod); |
| 2236 | scalar.* = (try intModScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod)).toIntern(); |
| 2591 | 2237 | } |
| 2592 | 2238 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 2593 | 2239 | .ty = ty.toIntern(), |
| ... | ... | @@ -2624,7 +2270,6 @@ pub fn intModScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: |
| 2624 | 2270 | |
| 2625 | 2271 | /// Returns true if the value is a floating point type and is NaN. Returns false otherwise. |
| 2626 | 2272 | pub fn isNan(val: Value, mod: *const Module) bool { |
| 2627 | | if (val.ip_index == .none) return false; |
| 2628 | 2273 | return switch (mod.intern_pool.indexToKey(val.toIntern())) { |
| 2629 | 2274 | .float => |float| switch (float.storage) { |
| 2630 | 2275 | inline else => |x| std.math.isNan(x), |
| ... | ... | @@ -2635,7 +2280,6 @@ pub fn isNan(val: Value, mod: *const Module) bool { |
| 2635 | 2280 | |
| 2636 | 2281 | /// Returns true if the value is a floating point type and is infinite. Returns false otherwise. |
| 2637 | 2282 | pub fn isInf(val: Value, mod: *const Module) bool { |
| 2638 | | if (val.ip_index == .none) return false; |
| 2639 | 2283 | return switch (mod.intern_pool.indexToKey(val.toIntern())) { |
| 2640 | 2284 | .float => |float| switch (float.storage) { |
| 2641 | 2285 | inline else => |x| std.math.isInf(x), |
| ... | ... | @@ -2645,7 +2289,6 @@ pub fn isInf(val: Value, mod: *const Module) bool { |
| 2645 | 2289 | } |
| 2646 | 2290 | |
| 2647 | 2291 | pub fn isNegativeInf(val: Value, mod: *const Module) bool { |
| 2648 | | if (val.ip_index == .none) return false; |
| 2649 | 2292 | return switch (mod.intern_pool.indexToKey(val.toIntern())) { |
| 2650 | 2293 | .float => |float| switch (float.storage) { |
| 2651 | 2294 | inline else => |x| std.math.isNegativeInf(x), |
| ... | ... | @@ -2661,7 +2304,7 @@ pub fn floatRem(lhs: Value, rhs: Value, float_type: Type, arena: Allocator, mod: |
| 2661 | 2304 | for (result_data, 0..) |*scalar, i| { |
| 2662 | 2305 | const lhs_elem = try lhs.elemValue(mod, i); |
| 2663 | 2306 | const rhs_elem = try rhs.elemValue(mod, i); |
| 2664 | | scalar.* = try (try floatRemScalar(lhs_elem, rhs_elem, scalar_ty, mod)).intern(scalar_ty, mod); |
| 2307 | scalar.* = (try floatRemScalar(lhs_elem, rhs_elem, scalar_ty, mod)).toIntern(); |
| 2665 | 2308 | } |
| 2666 | 2309 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 2667 | 2310 | .ty = float_type.toIntern(), |
| ... | ... | @@ -2694,7 +2337,7 @@ pub fn floatMod(lhs: Value, rhs: Value, float_type: Type, arena: Allocator, mod: |
| 2694 | 2337 | for (result_data, 0..) |*scalar, i| { |
| 2695 | 2338 | const lhs_elem = try lhs.elemValue(mod, i); |
| 2696 | 2339 | const rhs_elem = try rhs.elemValue(mod, i); |
| 2697 | | scalar.* = try (try floatModScalar(lhs_elem, rhs_elem, scalar_ty, mod)).intern(scalar_ty, mod); |
| 2340 | scalar.* = (try floatModScalar(lhs_elem, rhs_elem, scalar_ty, mod)).toIntern(); |
| 2698 | 2341 | } |
| 2699 | 2342 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 2700 | 2343 | .ty = float_type.toIntern(), |
| ... | ... | @@ -2755,7 +2398,7 @@ fn intMulInner(lhs: Value, rhs: Value, ty: Type, overflow_idx: *usize, allocator |
| 2755 | 2398 | }, |
| 2756 | 2399 | else => |e| return e, |
| 2757 | 2400 | }; |
| 2758 | | scalar.* = try val.intern(scalar_ty, mod); |
| 2401 | scalar.* = val.toIntern(); |
| 2759 | 2402 | } |
| 2760 | 2403 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 2761 | 2404 | .ty = ty.toIntern(), |
| ... | ... | @@ -2797,7 +2440,7 @@ pub fn intTrunc(val: Value, ty: Type, allocator: Allocator, signedness: std.buil |
| 2797 | 2440 | const scalar_ty = ty.scalarType(mod); |
| 2798 | 2441 | for (result_data, 0..) |*scalar, i| { |
| 2799 | 2442 | const elem_val = try val.elemValue(mod, i); |
| 2800 | | scalar.* = try (try intTruncScalar(elem_val, scalar_ty, allocator, signedness, bits, mod)).intern(scalar_ty, mod); |
| 2443 | scalar.* = (try intTruncScalar(elem_val, scalar_ty, allocator, signedness, bits, mod)).toIntern(); |
| 2801 | 2444 | } |
| 2802 | 2445 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 2803 | 2446 | .ty = ty.toIntern(), |
| ... | ... | @@ -2822,7 +2465,7 @@ pub fn intTruncBitsAsValue( |
| 2822 | 2465 | for (result_data, 0..) |*scalar, i| { |
| 2823 | 2466 | const elem_val = try val.elemValue(mod, i); |
| 2824 | 2467 | const bits_elem = try bits.elemValue(mod, i); |
| 2825 | | scalar.* = try (try intTruncScalar(elem_val, scalar_ty, allocator, signedness, @as(u16, @intCast(bits_elem.toUnsignedInt(mod))), mod)).intern(scalar_ty, mod); |
| 2468 | scalar.* = (try intTruncScalar(elem_val, scalar_ty, allocator, signedness, @as(u16, @intCast(bits_elem.toUnsignedInt(mod))), mod)).toIntern(); |
| 2826 | 2469 | } |
| 2827 | 2470 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 2828 | 2471 | .ty = ty.toIntern(), |
| ... | ... | @@ -2862,7 +2505,7 @@ pub fn shl(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) |
| 2862 | 2505 | for (result_data, 0..) |*scalar, i| { |
| 2863 | 2506 | const lhs_elem = try lhs.elemValue(mod, i); |
| 2864 | 2507 | const rhs_elem = try rhs.elemValue(mod, i); |
| 2865 | | scalar.* = try (try shlScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod)).intern(scalar_ty, mod); |
| 2508 | scalar.* = (try shlScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod)).toIntern(); |
| 2866 | 2509 | } |
| 2867 | 2510 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 2868 | 2511 | .ty = ty.toIntern(), |
| ... | ... | @@ -2912,8 +2555,8 @@ pub fn shlWithOverflow( |
| 2912 | 2555 | const lhs_elem = try lhs.elemValue(mod, i); |
| 2913 | 2556 | const rhs_elem = try rhs.elemValue(mod, i); |
| 2914 | 2557 | const of_math_result = try shlWithOverflowScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod); |
| 2915 | | of.* = try of_math_result.overflow_bit.intern(Type.u1, mod); |
| 2916 | | scalar.* = try of_math_result.wrapped_result.intern(scalar_ty, mod); |
| 2558 | of.* = of_math_result.overflow_bit.toIntern(); |
| 2559 | scalar.* = of_math_result.wrapped_result.toIntern(); |
| 2917 | 2560 | } |
| 2918 | 2561 | return OverflowArithmeticResult{ |
| 2919 | 2562 | .overflow_bit = Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| ... | ... | @@ -2973,7 +2616,7 @@ pub fn shlSat( |
| 2973 | 2616 | for (result_data, 0..) |*scalar, i| { |
| 2974 | 2617 | const lhs_elem = try lhs.elemValue(mod, i); |
| 2975 | 2618 | const rhs_elem = try rhs.elemValue(mod, i); |
| 2976 | | scalar.* = try (try shlSatScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod)).intern(scalar_ty, mod); |
| 2619 | scalar.* = (try shlSatScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod)).toIntern(); |
| 2977 | 2620 | } |
| 2978 | 2621 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 2979 | 2622 | .ty = ty.toIntern(), |
| ... | ... | @@ -3023,7 +2666,7 @@ pub fn shlTrunc( |
| 3023 | 2666 | for (result_data, 0..) |*scalar, i| { |
| 3024 | 2667 | const lhs_elem = try lhs.elemValue(mod, i); |
| 3025 | 2668 | const rhs_elem = try rhs.elemValue(mod, i); |
| 3026 | | scalar.* = try (try shlTruncScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod)).intern(scalar_ty, mod); |
| 2669 | scalar.* = (try shlTruncScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod)).toIntern(); |
| 3027 | 2670 | } |
| 3028 | 2671 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 3029 | 2672 | .ty = ty.toIntern(), |
| ... | ... | @@ -3053,7 +2696,7 @@ pub fn shr(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) |
| 3053 | 2696 | for (result_data, 0..) |*scalar, i| { |
| 3054 | 2697 | const lhs_elem = try lhs.elemValue(mod, i); |
| 3055 | 2698 | const rhs_elem = try rhs.elemValue(mod, i); |
| 3056 | | scalar.* = try (try shrScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod)).intern(scalar_ty, mod); |
| 2699 | scalar.* = (try shrScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod)).toIntern(); |
| 3057 | 2700 | } |
| 3058 | 2701 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 3059 | 2702 | .ty = ty.toIntern(), |
| ... | ... | @@ -3105,7 +2748,7 @@ pub fn floatNeg( |
| 3105 | 2748 | const scalar_ty = float_type.scalarType(mod); |
| 3106 | 2749 | for (result_data, 0..) |*scalar, i| { |
| 3107 | 2750 | const elem_val = try val.elemValue(mod, i); |
| 3108 | | scalar.* = try (try floatNegScalar(elem_val, scalar_ty, mod)).intern(scalar_ty, mod); |
| 2751 | scalar.* = (try floatNegScalar(elem_val, scalar_ty, mod)).toIntern(); |
| 3109 | 2752 | } |
| 3110 | 2753 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 3111 | 2754 | .ty = float_type.toIntern(), |
| ... | ... | @@ -3148,7 +2791,7 @@ pub fn floatAdd( |
| 3148 | 2791 | for (result_data, 0..) |*scalar, i| { |
| 3149 | 2792 | const lhs_elem = try lhs.elemValue(mod, i); |
| 3150 | 2793 | const rhs_elem = try rhs.elemValue(mod, i); |
| 3151 | | scalar.* = try (try floatAddScalar(lhs_elem, rhs_elem, scalar_ty, mod)).intern(scalar_ty, mod); |
| 2794 | scalar.* = (try floatAddScalar(lhs_elem, rhs_elem, scalar_ty, mod)).toIntern(); |
| 3152 | 2795 | } |
| 3153 | 2796 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 3154 | 2797 | .ty = float_type.toIntern(), |
| ... | ... | @@ -3192,7 +2835,7 @@ pub fn floatSub( |
| 3192 | 2835 | for (result_data, 0..) |*scalar, i| { |
| 3193 | 2836 | const lhs_elem = try lhs.elemValue(mod, i); |
| 3194 | 2837 | const rhs_elem = try rhs.elemValue(mod, i); |
| 3195 | | scalar.* = try (try floatSubScalar(lhs_elem, rhs_elem, scalar_ty, mod)).intern(scalar_ty, mod); |
| 2838 | scalar.* = (try floatSubScalar(lhs_elem, rhs_elem, scalar_ty, mod)).toIntern(); |
| 3196 | 2839 | } |
| 3197 | 2840 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 3198 | 2841 | .ty = float_type.toIntern(), |
| ... | ... | @@ -3236,7 +2879,7 @@ pub fn floatDiv( |
| 3236 | 2879 | for (result_data, 0..) |*scalar, i| { |
| 3237 | 2880 | const lhs_elem = try lhs.elemValue(mod, i); |
| 3238 | 2881 | const rhs_elem = try rhs.elemValue(mod, i); |
| 3239 | | scalar.* = try (try floatDivScalar(lhs_elem, rhs_elem, scalar_ty, mod)).intern(scalar_ty, mod); |
| 2882 | scalar.* = (try floatDivScalar(lhs_elem, rhs_elem, scalar_ty, mod)).toIntern(); |
| 3240 | 2883 | } |
| 3241 | 2884 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 3242 | 2885 | .ty = float_type.toIntern(), |
| ... | ... | @@ -3280,7 +2923,7 @@ pub fn floatDivFloor( |
| 3280 | 2923 | for (result_data, 0..) |*scalar, i| { |
| 3281 | 2924 | const lhs_elem = try lhs.elemValue(mod, i); |
| 3282 | 2925 | const rhs_elem = try rhs.elemValue(mod, i); |
| 3283 | | scalar.* = try (try floatDivFloorScalar(lhs_elem, rhs_elem, scalar_ty, mod)).intern(scalar_ty, mod); |
| 2926 | scalar.* = (try floatDivFloorScalar(lhs_elem, rhs_elem, scalar_ty, mod)).toIntern(); |
| 3284 | 2927 | } |
| 3285 | 2928 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 3286 | 2929 | .ty = float_type.toIntern(), |
| ... | ... | @@ -3324,7 +2967,7 @@ pub fn floatDivTrunc( |
| 3324 | 2967 | for (result_data, 0..) |*scalar, i| { |
| 3325 | 2968 | const lhs_elem = try lhs.elemValue(mod, i); |
| 3326 | 2969 | const rhs_elem = try rhs.elemValue(mod, i); |
| 3327 | | scalar.* = try (try floatDivTruncScalar(lhs_elem, rhs_elem, scalar_ty, mod)).intern(scalar_ty, mod); |
| 2970 | scalar.* = (try floatDivTruncScalar(lhs_elem, rhs_elem, scalar_ty, mod)).toIntern(); |
| 3328 | 2971 | } |
| 3329 | 2972 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 3330 | 2973 | .ty = float_type.toIntern(), |
| ... | ... | @@ -3368,7 +3011,7 @@ pub fn floatMul( |
| 3368 | 3011 | for (result_data, 0..) |*scalar, i| { |
| 3369 | 3012 | const lhs_elem = try lhs.elemValue(mod, i); |
| 3370 | 3013 | const rhs_elem = try rhs.elemValue(mod, i); |
| 3371 | | scalar.* = try (try floatMulScalar(lhs_elem, rhs_elem, scalar_ty, mod)).intern(scalar_ty, mod); |
| 3014 | scalar.* = (try floatMulScalar(lhs_elem, rhs_elem, scalar_ty, mod)).toIntern(); |
| 3372 | 3015 | } |
| 3373 | 3016 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 3374 | 3017 | .ty = float_type.toIntern(), |
| ... | ... | @@ -3405,7 +3048,7 @@ pub fn sqrt(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value |
| 3405 | 3048 | const scalar_ty = float_type.scalarType(mod); |
| 3406 | 3049 | for (result_data, 0..) |*scalar, i| { |
| 3407 | 3050 | const elem_val = try val.elemValue(mod, i); |
| 3408 | | scalar.* = try (try sqrtScalar(elem_val, scalar_ty, mod)).intern(scalar_ty, mod); |
| 3051 | scalar.* = (try sqrtScalar(elem_val, scalar_ty, mod)).toIntern(); |
| 3409 | 3052 | } |
| 3410 | 3053 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 3411 | 3054 | .ty = float_type.toIntern(), |
| ... | ... | @@ -3437,7 +3080,7 @@ pub fn sin(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value |
| 3437 | 3080 | const scalar_ty = float_type.scalarType(mod); |
| 3438 | 3081 | for (result_data, 0..) |*scalar, i| { |
| 3439 | 3082 | const elem_val = try val.elemValue(mod, i); |
| 3440 | | scalar.* = try (try sinScalar(elem_val, scalar_ty, mod)).intern(scalar_ty, mod); |
| 3083 | scalar.* = (try sinScalar(elem_val, scalar_ty, mod)).toIntern(); |
| 3441 | 3084 | } |
| 3442 | 3085 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 3443 | 3086 | .ty = float_type.toIntern(), |
| ... | ... | @@ -3469,7 +3112,7 @@ pub fn cos(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value |
| 3469 | 3112 | const scalar_ty = float_type.scalarType(mod); |
| 3470 | 3113 | for (result_data, 0..) |*scalar, i| { |
| 3471 | 3114 | const elem_val = try val.elemValue(mod, i); |
| 3472 | | scalar.* = try (try cosScalar(elem_val, scalar_ty, mod)).intern(scalar_ty, mod); |
| 3115 | scalar.* = (try cosScalar(elem_val, scalar_ty, mod)).toIntern(); |
| 3473 | 3116 | } |
| 3474 | 3117 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 3475 | 3118 | .ty = float_type.toIntern(), |
| ... | ... | @@ -3501,7 +3144,7 @@ pub fn tan(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value |
| 3501 | 3144 | const scalar_ty = float_type.scalarType(mod); |
| 3502 | 3145 | for (result_data, 0..) |*scalar, i| { |
| 3503 | 3146 | const elem_val = try val.elemValue(mod, i); |
| 3504 | | scalar.* = try (try tanScalar(elem_val, scalar_ty, mod)).intern(scalar_ty, mod); |
| 3147 | scalar.* = (try tanScalar(elem_val, scalar_ty, mod)).toIntern(); |
| 3505 | 3148 | } |
| 3506 | 3149 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 3507 | 3150 | .ty = float_type.toIntern(), |
| ... | ... | @@ -3533,7 +3176,7 @@ pub fn exp(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value |
| 3533 | 3176 | const scalar_ty = float_type.scalarType(mod); |
| 3534 | 3177 | for (result_data, 0..) |*scalar, i| { |
| 3535 | 3178 | const elem_val = try val.elemValue(mod, i); |
| 3536 | | scalar.* = try (try expScalar(elem_val, scalar_ty, mod)).intern(scalar_ty, mod); |
| 3179 | scalar.* = (try expScalar(elem_val, scalar_ty, mod)).toIntern(); |
| 3537 | 3180 | } |
| 3538 | 3181 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 3539 | 3182 | .ty = float_type.toIntern(), |
| ... | ... | @@ -3565,7 +3208,7 @@ pub fn exp2(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value |
| 3565 | 3208 | const scalar_ty = float_type.scalarType(mod); |
| 3566 | 3209 | for (result_data, 0..) |*scalar, i| { |
| 3567 | 3210 | const elem_val = try val.elemValue(mod, i); |
| 3568 | | scalar.* = try (try exp2Scalar(elem_val, scalar_ty, mod)).intern(scalar_ty, mod); |
| 3211 | scalar.* = (try exp2Scalar(elem_val, scalar_ty, mod)).toIntern(); |
| 3569 | 3212 | } |
| 3570 | 3213 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 3571 | 3214 | .ty = float_type.toIntern(), |
| ... | ... | @@ -3597,7 +3240,7 @@ pub fn log(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value |
| 3597 | 3240 | const scalar_ty = float_type.scalarType(mod); |
| 3598 | 3241 | for (result_data, 0..) |*scalar, i| { |
| 3599 | 3242 | const elem_val = try val.elemValue(mod, i); |
| 3600 | | scalar.* = try (try logScalar(elem_val, scalar_ty, mod)).intern(scalar_ty, mod); |
| 3243 | scalar.* = (try logScalar(elem_val, scalar_ty, mod)).toIntern(); |
| 3601 | 3244 | } |
| 3602 | 3245 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 3603 | 3246 | .ty = float_type.toIntern(), |
| ... | ... | @@ -3629,7 +3272,7 @@ pub fn log2(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value |
| 3629 | 3272 | const scalar_ty = float_type.scalarType(mod); |
| 3630 | 3273 | for (result_data, 0..) |*scalar, i| { |
| 3631 | 3274 | const elem_val = try val.elemValue(mod, i); |
| 3632 | | scalar.* = try (try log2Scalar(elem_val, scalar_ty, mod)).intern(scalar_ty, mod); |
| 3275 | scalar.* = (try log2Scalar(elem_val, scalar_ty, mod)).toIntern(); |
| 3633 | 3276 | } |
| 3634 | 3277 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 3635 | 3278 | .ty = float_type.toIntern(), |
| ... | ... | @@ -3661,7 +3304,7 @@ pub fn log10(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Valu |
| 3661 | 3304 | const scalar_ty = float_type.scalarType(mod); |
| 3662 | 3305 | for (result_data, 0..) |*scalar, i| { |
| 3663 | 3306 | const elem_val = try val.elemValue(mod, i); |
| 3664 | | scalar.* = try (try log10Scalar(elem_val, scalar_ty, mod)).intern(scalar_ty, mod); |
| 3307 | scalar.* = (try log10Scalar(elem_val, scalar_ty, mod)).toIntern(); |
| 3665 | 3308 | } |
| 3666 | 3309 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 3667 | 3310 | .ty = float_type.toIntern(), |
| ... | ... | @@ -3693,7 +3336,7 @@ pub fn abs(val: Value, ty: Type, arena: Allocator, mod: *Module) !Value { |
| 3693 | 3336 | const scalar_ty = ty.scalarType(mod); |
| 3694 | 3337 | for (result_data, 0..) |*scalar, i| { |
| 3695 | 3338 | const elem_val = try val.elemValue(mod, i); |
| 3696 | | scalar.* = try (try absScalar(elem_val, scalar_ty, mod, arena)).intern(scalar_ty, mod); |
| 3339 | scalar.* = (try absScalar(elem_val, scalar_ty, mod, arena)).toIntern(); |
| 3697 | 3340 | } |
| 3698 | 3341 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 3699 | 3342 | .ty = ty.toIntern(), |
| ... | ... | @@ -3744,7 +3387,7 @@ pub fn floor(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Valu |
| 3744 | 3387 | const scalar_ty = float_type.scalarType(mod); |
| 3745 | 3388 | for (result_data, 0..) |*scalar, i| { |
| 3746 | 3389 | const elem_val = try val.elemValue(mod, i); |
| 3747 | | scalar.* = try (try floorScalar(elem_val, scalar_ty, mod)).intern(scalar_ty, mod); |
| 3390 | scalar.* = (try floorScalar(elem_val, scalar_ty, mod)).toIntern(); |
| 3748 | 3391 | } |
| 3749 | 3392 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 3750 | 3393 | .ty = float_type.toIntern(), |
| ... | ... | @@ -3776,7 +3419,7 @@ pub fn ceil(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value |
| 3776 | 3419 | const scalar_ty = float_type.scalarType(mod); |
| 3777 | 3420 | for (result_data, 0..) |*scalar, i| { |
| 3778 | 3421 | const elem_val = try val.elemValue(mod, i); |
| 3779 | | scalar.* = try (try ceilScalar(elem_val, scalar_ty, mod)).intern(scalar_ty, mod); |
| 3422 | scalar.* = (try ceilScalar(elem_val, scalar_ty, mod)).toIntern(); |
| 3780 | 3423 | } |
| 3781 | 3424 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 3782 | 3425 | .ty = float_type.toIntern(), |
| ... | ... | @@ -3808,7 +3451,7 @@ pub fn round(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Valu |
| 3808 | 3451 | const scalar_ty = float_type.scalarType(mod); |
| 3809 | 3452 | for (result_data, 0..) |*scalar, i| { |
| 3810 | 3453 | const elem_val = try val.elemValue(mod, i); |
| 3811 | | scalar.* = try (try roundScalar(elem_val, scalar_ty, mod)).intern(scalar_ty, mod); |
| 3454 | scalar.* = (try roundScalar(elem_val, scalar_ty, mod)).toIntern(); |
| 3812 | 3455 | } |
| 3813 | 3456 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 3814 | 3457 | .ty = float_type.toIntern(), |
| ... | ... | @@ -3840,7 +3483,7 @@ pub fn trunc(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Valu |
| 3840 | 3483 | const scalar_ty = float_type.scalarType(mod); |
| 3841 | 3484 | for (result_data, 0..) |*scalar, i| { |
| 3842 | 3485 | const elem_val = try val.elemValue(mod, i); |
| 3843 | | scalar.* = try (try truncScalar(elem_val, scalar_ty, mod)).intern(scalar_ty, mod); |
| 3486 | scalar.* = (try truncScalar(elem_val, scalar_ty, mod)).toIntern(); |
| 3844 | 3487 | } |
| 3845 | 3488 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 3846 | 3489 | .ty = float_type.toIntern(), |
| ... | ... | @@ -3881,7 +3524,7 @@ pub fn mulAdd( |
| 3881 | 3524 | const mulend1_elem = try mulend1.elemValue(mod, i); |
| 3882 | 3525 | const mulend2_elem = try mulend2.elemValue(mod, i); |
| 3883 | 3526 | const addend_elem = try addend.elemValue(mod, i); |
| 3884 | | scalar.* = try (try mulAddScalar(scalar_ty, mulend1_elem, mulend2_elem, addend_elem, mod)).intern(scalar_ty, mod); |
| 3527 | scalar.* = (try mulAddScalar(scalar_ty, mulend1_elem, mulend2_elem, addend_elem, mod)).toIntern(); |
| 3885 | 3528 | } |
| 3886 | 3529 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 3887 | 3530 | .ty = float_type.toIntern(), |
| ... | ... | @@ -3957,98 +3600,26 @@ pub fn intValueBounds(val: Value, mod: *Module) !?[2]Value { |
| 3957 | 3600 | }; |
| 3958 | 3601 | } |
| 3959 | 3602 | |
| 3960 | | /// This type is not copyable since it may contain pointers to its inner data. |
| 3961 | | pub const Payload = struct { |
| 3962 | | tag: Tag, |
| 3963 | | |
| 3964 | | pub const Slice = struct { |
| 3965 | | base: Payload, |
| 3966 | | data: struct { |
| 3967 | | ptr: Value, |
| 3968 | | len: Value, |
| 3969 | | }, |
| 3970 | | }; |
| 3971 | | |
| 3972 | | pub const Bytes = struct { |
| 3973 | | base: Payload, |
| 3974 | | /// Includes the sentinel, if any. |
| 3975 | | data: []const u8, |
| 3976 | | }; |
| 3977 | | |
| 3978 | | pub const SubValue = struct { |
| 3979 | | base: Payload, |
| 3980 | | data: Value, |
| 3981 | | }; |
| 3982 | | |
| 3983 | | pub const Aggregate = struct { |
| 3984 | | base: Payload, |
| 3985 | | /// Field values. The types are according to the struct or array type. |
| 3986 | | /// The length is provided here so that copying a Value does not depend on the Type. |
| 3987 | | data: []Value, |
| 3988 | | }; |
| 3989 | | |
| 3990 | | pub const Union = struct { |
| 3991 | | pub const base_tag = Tag.@"union"; |
| 3992 | | |
| 3993 | | base: Payload = .{ .tag = base_tag }, |
| 3994 | | data: Data, |
| 3995 | | |
| 3996 | | pub const Data = struct { |
| 3997 | | tag: ?Value, |
| 3998 | | val: Value, |
| 3999 | | }; |
| 4000 | | }; |
| 4001 | | }; |
| 4002 | | |
| 4003 | 3603 | pub const BigIntSpace = InternPool.Key.Int.Storage.BigIntSpace; |
| 4004 | 3604 | |
| 4005 | | pub const zero_usize: Value = .{ .ip_index = .zero_usize, .legacy = undefined }; |
| 4006 | | pub const zero_u8: Value = .{ .ip_index = .zero_u8, .legacy = undefined }; |
| 4007 | | pub const zero_comptime_int: Value = .{ .ip_index = .zero, .legacy = undefined }; |
| 4008 | | pub const one_comptime_int: Value = .{ .ip_index = .one, .legacy = undefined }; |
| 4009 | | pub const negative_one_comptime_int: Value = .{ .ip_index = .negative_one, .legacy = undefined }; |
| 4010 | | pub const undef: Value = .{ .ip_index = .undef, .legacy = undefined }; |
| 4011 | | pub const @"void": Value = .{ .ip_index = .void_value, .legacy = undefined }; |
| 4012 | | pub const @"null": Value = .{ .ip_index = .null_value, .legacy = undefined }; |
| 4013 | | pub const @"false": Value = .{ .ip_index = .bool_false, .legacy = undefined }; |
| 4014 | | pub const @"true": Value = .{ .ip_index = .bool_true, .legacy = undefined }; |
| 4015 | | pub const @"unreachable": Value = .{ .ip_index = .unreachable_value, .legacy = undefined }; |
| 4016 | | |
| 4017 | | pub const generic_poison: Value = .{ .ip_index = .generic_poison, .legacy = undefined }; |
| 4018 | | pub const generic_poison_type: Value = .{ .ip_index = .generic_poison_type, .legacy = undefined }; |
| 4019 | | pub const empty_struct: Value = .{ .ip_index = .empty_struct, .legacy = undefined }; |
| 3605 | pub const zero_usize: Value = .{ .ip_index = .zero_usize }; |
| 3606 | pub const zero_u8: Value = .{ .ip_index = .zero_u8 }; |
| 3607 | pub const zero_comptime_int: Value = .{ .ip_index = .zero }; |
| 3608 | pub const one_comptime_int: Value = .{ .ip_index = .one }; |
| 3609 | pub const negative_one_comptime_int: Value = .{ .ip_index = .negative_one }; |
| 3610 | pub const undef: Value = .{ .ip_index = .undef }; |
| 3611 | pub const @"void": Value = .{ .ip_index = .void_value }; |
| 3612 | pub const @"null": Value = .{ .ip_index = .null_value }; |
| 3613 | pub const @"false": Value = .{ .ip_index = .bool_false }; |
| 3614 | pub const @"true": Value = .{ .ip_index = .bool_true }; |
| 3615 | pub const @"unreachable": Value = .{ .ip_index = .unreachable_value }; |
| 3616 | |
| 3617 | pub const generic_poison: Value = .{ .ip_index = .generic_poison }; |
| 3618 | pub const generic_poison_type: Value = .{ .ip_index = .generic_poison_type }; |
| 3619 | pub const empty_struct: Value = .{ .ip_index = .empty_struct }; |
| 4020 | 3620 | |
| 4021 | 3621 | pub fn makeBool(x: bool) Value { |
| 4022 | 3622 | return if (x) Value.true else Value.false; |
| 4023 | 3623 | } |
| 4024 | 3624 | |
| 4025 | 3625 | pub const RuntimeIndex = InternPool.RuntimeIndex; |
| 4026 | | |
| 4027 | | /// This function is used in the debugger pretty formatters in tools/ to fetch the |
| 4028 | | /// Tag to Payload mapping to facilitate fancy debug printing for this type. |
| 4029 | | fn dbHelper(self: *Value, tag_to_payload_map: *map: { |
| 4030 | | const tags = @typeInfo(Tag).Enum.fields; |
| 4031 | | var fields: [tags.len]std.builtin.Type.StructField = undefined; |
| 4032 | | for (&fields, tags) |*field, t| field.* = .{ |
| 4033 | | .name = t.name ++ "", |
| 4034 | | .type = *@field(Tag, t.name).Type(), |
| 4035 | | .default_value = null, |
| 4036 | | .is_comptime = false, |
| 4037 | | .alignment = 0, |
| 4038 | | }; |
| 4039 | | break :map @Type(.{ .Struct = .{ |
| 4040 | | .layout = .@"extern", |
| 4041 | | .fields = &fields, |
| 4042 | | .decls = &.{}, |
| 4043 | | .is_tuple = false, |
| 4044 | | } }); |
| 4045 | | }) void { |
| 4046 | | _ = self; |
| 4047 | | _ = tag_to_payload_map; |
| 4048 | | } |
| 4049 | | |
| 4050 | | comptime { |
| 4051 | | if (!builtin.strip_debug_info) { |
| 4052 | | _ = &dbHelper; |
| 4053 | | } |
| 4054 | | } |