authorgravatar for paul.verigo@gmail.comPavel Verigo <paul.verigo@gmail.com> 2025-03-02 20:10:25+01:00
committergravatar for paul.verigo@gmail.comPavel Verigo <paul.verigo@gmail.com> 2025-03-24 15:00:00+01:00
log47cd0961cb938248a2bc65d2a9d49ba1d37b0764
treef5eba03c90218b3e4e15654085ec4466ca4a93d5
parent58b38238f51b6a268559144e8bbe7c0646170488

stage2-wasm: pass field_parent_ptr tests

Handle packed containers, also fixes packed union lowering for non int type + union field pointer logic fix

2 files changed, 34 insertions(+), 35 deletions(-)

src/arch/wasm/CodeGen.zig+34-27
...@@ -3154,19 +3154,7 @@ fn lowerPtr(cg: *CodeGen, ptr_val: InternPool.Index, prev_offset: u64) InnerErro...@@ -3154,19 +3154,7 @@ fn lowerPtr(cg: *CodeGen, ptr_val: InternPool.Index, prev_offset: u64) InnerErro
3154 .@"extern", .@"packed" => unreachable,3154 .@"extern", .@"packed" => unreachable,
3155 },3155 },
3156 .@"union" => switch (base_ty.containerLayout(zcu)) {3156 .@"union" => switch (base_ty.containerLayout(zcu)) {
3157 .auto => off: {3157 .auto => base_ty.structFieldOffset(@intCast(field.index), zcu),
3158 // Keep in sync with the `un` case of `generateSymbol`.
3159 const layout = base_ty.unionGetLayout(zcu);
3160 if (layout.payload_size == 0) break :off 0;
3161 if (layout.tag_size == 0) break :off 0;
3162 if (layout.tag_align.compare(.gte, layout.payload_align)) {
3163 // Tag first.
3164 break :off layout.tag_size;
3165 } else {
3166 // Payload first.
3167 break :off 0;
3168 }
3169 },
3170 .@"extern", .@"packed" => unreachable,3158 .@"extern", .@"packed" => unreachable,
3171 },3159 },
3172 else => unreachable,3160 else => unreachable,
...@@ -3312,16 +3300,16 @@ fn lowerConstant(cg: *CodeGen, val: Value, ty: Type) InnerError!WValue {...@@ -3312,16 +3300,16 @@ fn lowerConstant(cg: *CodeGen, val: Value, ty: Type) InnerError!WValue {
3312 },3300 },
3313 else => unreachable,3301 else => unreachable,
3314 },3302 },
3315 .un => |un| {3303 .un => {
3316 // in this case we have a packed union which will not be passed by reference.3304 const int_type = try pt.intType(.unsigned, @intCast(ty.bitSize(zcu)));
3317 const constant_ty = if (un.tag == .none)3305
3318 try ty.unionBackingType(pt)3306 var buf: [8]u8 = .{0} ** 8; // zero the buffer so we do not read 0xaa as integer
3319 else field_ty: {3307 val.writeToPackedMemory(ty, pt, &buf, 0) catch unreachable;
3320 const union_obj = zcu.typeToUnion(ty).?;3308 const int_val = try pt.intValue(
3321 const field_index = zcu.unionTagFieldIndex(union_obj, Value.fromInterned(un.tag)).?;3309 int_type,
3322 break :field_ty Type.fromInterned(union_obj.field_types.get(ip)[field_index]);3310 mem.readInt(u64, &buf, .little),
3323 };3311 );
3324 return cg.lowerConstant(Value.fromInterned(un.val), constant_ty);3312 return cg.lowerConstant(int_val, int_type);
3325 },3313 },
3326 .memoized_call => unreachable,3314 .memoized_call => unreachable,
3327 }3315 }
...@@ -3369,6 +3357,14 @@ fn emitUndefined(cg: *CodeGen, ty: Type) InnerError!WValue {...@@ -3369,6 +3357,14 @@ fn emitUndefined(cg: *CodeGen, ty: Type) InnerError!WValue {
3369 const packed_struct = zcu.typeToPackedStruct(ty).?;3357 const packed_struct = zcu.typeToPackedStruct(ty).?;
3370 return cg.emitUndefined(Type.fromInterned(packed_struct.backingIntTypeUnordered(ip)));3358 return cg.emitUndefined(Type.fromInterned(packed_struct.backingIntTypeUnordered(ip)));
3371 },3359 },
3360 .@"union" => switch (ty.containerLayout(zcu)) {
3361 .@"packed" => switch (ty.bitSize(zcu)) {
3362 0...32 => return .{ .imm32 = 0xaaaaaaaa },
3363 33...64 => return .{ .imm64 = 0xaaaaaaaaaaaaaaaa },
3364 else => unreachable,
3365 },
3366 else => unreachable,
3367 },
3372 else => return cg.fail("Wasm TODO: emitUndefined for type: {}\n", .{ty.zigTypeTag(zcu)}),3368 else => return cg.fail("Wasm TODO: emitUndefined for type: {}\n", .{ty.zigTypeTag(zcu)}),
3373 }3369 }
3374}3370}
...@@ -4211,7 +4207,6 @@ fn airUnwrapErrUnionPayload(cg: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool)...@@ -4211,7 +4207,6 @@ fn airUnwrapErrUnionPayload(cg: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool)
4211 assert(isByRef(eu_ty, zcu, cg.target));4207 assert(isByRef(eu_ty, zcu, cg.target));
4212 break :result try cg.load(operand, payload_ty, pl_offset);4208 break :result try cg.load(operand, payload_ty, pl_offset);
4213 }4209 }
4214
4215 };4210 };
4216 return cg.finishAir(inst, result, &.{ty_op.operand});4211 return cg.finishAir(inst, result, &.{ty_op.operand});
4217}4212}
...@@ -5691,13 +5686,25 @@ fn airErrUnionPayloadPtrSet(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void...@@ -5691,13 +5686,25 @@ fn airErrUnionPayloadPtrSet(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void
5691}5686}
56925687
5693fn airFieldParentPtr(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {5688fn airFieldParentPtr(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5694 const zcu = cg.pt.zcu;5689 const pt = cg.pt;
5690 const zcu = pt.zcu;
5695 const ty_pl = cg.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;5691 const ty_pl = cg.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
5696 const extra = cg.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;5692 const extra = cg.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;
56975693
5698 const field_ptr = try cg.resolveInst(extra.field_ptr);5694 const field_ptr = try cg.resolveInst(extra.field_ptr);
5699 const parent_ty = ty_pl.ty.toType().childType(zcu);5695 const parent_ptr_ty = cg.typeOfIndex(inst);
5700 const field_offset = parent_ty.structFieldOffset(extra.field_index, zcu);5696 const parent_ty = parent_ptr_ty.childType(zcu);
5697 const field_ptr_ty = cg.typeOf(extra.field_ptr);
5698 const field_index = extra.field_index;
5699 const field_offset = switch (parent_ty.containerLayout(zcu)) {
5700 .auto, .@"extern" => parent_ty.structFieldOffset(field_index, zcu),
5701 .@"packed" => offset: {
5702 const parent_ptr_offset = parent_ptr_ty.ptrInfo(zcu).packed_offset.bit_offset;
5703 const field_offset = if (zcu.typeToStruct(parent_ty)) |loaded_struct| pt.structPackedFieldBitOffset(loaded_struct, field_index) else 0;
5704 const field_ptr_offset = field_ptr_ty.ptrInfo(zcu).packed_offset.bit_offset;
5705 break :offset @divExact(parent_ptr_offset + field_offset - field_ptr_offset, 8);
5706 },
5707 };
57015708
5702 const result = if (field_offset != 0) result: {5709 const result = if (field_offset != 0) result: {
5703 const base = try cg.buildPointerOffset(field_ptr, 0, .new);5710 const base = try cg.buildPointerOffset(field_ptr, 0, .new);
test/behavior/field_parent_ptr.zig-8
...@@ -588,7 +588,6 @@ test "@fieldParentPtr extern struct last zero-bit field" {...@@ -588,7 +588,6 @@ test "@fieldParentPtr extern struct last zero-bit field" {
588test "@fieldParentPtr unaligned packed struct" {588test "@fieldParentPtr unaligned packed struct" {
589 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;589 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
590 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;590 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
591 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
592 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;591 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
593 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;592 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
594593
...@@ -727,7 +726,6 @@ test "@fieldParentPtr unaligned packed struct" {...@@ -727,7 +726,6 @@ test "@fieldParentPtr unaligned packed struct" {
727test "@fieldParentPtr aligned packed struct" {726test "@fieldParentPtr aligned packed struct" {
728 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;727 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
729 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;728 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
730 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
731 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;729 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
732 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;730 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
733731
...@@ -865,7 +863,6 @@ test "@fieldParentPtr aligned packed struct" {...@@ -865,7 +863,6 @@ test "@fieldParentPtr aligned packed struct" {
865863
866test "@fieldParentPtr nested packed struct" {864test "@fieldParentPtr nested packed struct" {
867 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;865 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
868 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
869 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;866 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
870 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;867 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
871868
...@@ -1028,7 +1025,6 @@ test "@fieldParentPtr nested packed struct" {...@@ -1028,7 +1025,6 @@ test "@fieldParentPtr nested packed struct" {
10281025
1029test "@fieldParentPtr packed struct first zero-bit field" {1026test "@fieldParentPtr packed struct first zero-bit field" {
1030 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;1027 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
1031 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
1032 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;1028 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1033 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;1029 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
10341030
...@@ -1134,7 +1130,6 @@ test "@fieldParentPtr packed struct first zero-bit field" {...@@ -1134,7 +1130,6 @@ test "@fieldParentPtr packed struct first zero-bit field" {
11341130
1135test "@fieldParentPtr packed struct middle zero-bit field" {1131test "@fieldParentPtr packed struct middle zero-bit field" {
1136 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;1132 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
1137 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
1138 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;1133 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1139 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;1134 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
11401135
...@@ -1240,7 +1235,6 @@ test "@fieldParentPtr packed struct middle zero-bit field" {...@@ -1240,7 +1235,6 @@ test "@fieldParentPtr packed struct middle zero-bit field" {
12401235
1241test "@fieldParentPtr packed struct last zero-bit field" {1236test "@fieldParentPtr packed struct last zero-bit field" {
1242 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;1237 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
1243 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
1244 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;1238 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1245 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;1239 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
12461240
...@@ -1753,7 +1747,6 @@ test "@fieldParentPtr extern union" {...@@ -1753,7 +1747,6 @@ test "@fieldParentPtr extern union" {
1753}1747}
17541748
1755test "@fieldParentPtr packed union" {1749test "@fieldParentPtr packed union" {
1756 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
1757 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;1750 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1758 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;1751 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1759 if (builtin.target.cpu.arch.endian() == .big) return error.SkipZigTest; // TODO1752 if (builtin.target.cpu.arch.endian() == .big) return error.SkipZigTest; // TODO
...@@ -1892,7 +1885,6 @@ test "@fieldParentPtr packed union" {...@@ -1892,7 +1885,6 @@ test "@fieldParentPtr packed union" {
18921885
1893test "@fieldParentPtr tagged union all zero-bit fields" {1886test "@fieldParentPtr tagged union all zero-bit fields" {
1894 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;1887 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
1895 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
1896 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;1888 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1897 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;1889 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
18981890