Skip to content

Commit 47cd096

Browse files
committed
stage2-wasm: pass field_parent_ptr tests
Handle packed containers, also fixes packed union lowering for non int type + union field pointer logic fix
1 parent 58b3823 commit 47cd096

File tree

2 files changed

+34
-35
lines changed

2 files changed

+34
-35
lines changed

src/arch/wasm/CodeGen.zig

Lines changed: 34 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3154,19 +3154,7 @@ fn lowerPtr(cg: *CodeGen, ptr_val: InternPool.Index, prev_offset: u64) InnerErro
31543154
.@"extern", .@"packed" => unreachable,
31553155
},
31563156
.@"union" => switch (base_ty.containerLayout(zcu)) {
3157-
.auto => off: {
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-
},
3157+
.auto => base_ty.structFieldOffset(@intCast(field.index), zcu),
31703158
.@"extern", .@"packed" => unreachable,
31713159
},
31723160
else => unreachable,
@@ -3312,16 +3300,16 @@ fn lowerConstant(cg: *CodeGen, val: Value, ty: Type) InnerError!WValue {
33123300
},
33133301
else => unreachable,
33143302
},
3315-
.un => |un| {
3316-
// in this case we have a packed union which will not be passed by reference.
3317-
const constant_ty = if (un.tag == .none)
3318-
try ty.unionBackingType(pt)
3319-
else field_ty: {
3320-
const union_obj = zcu.typeToUnion(ty).?;
3321-
const field_index = zcu.unionTagFieldIndex(union_obj, Value.fromInterned(un.tag)).?;
3322-
break :field_ty Type.fromInterned(union_obj.field_types.get(ip)[field_index]);
3323-
};
3324-
return cg.lowerConstant(Value.fromInterned(un.val), constant_ty);
3303+
.un => {
3304+
const int_type = try pt.intType(.unsigned, @intCast(ty.bitSize(zcu)));
3305+
3306+
var buf: [8]u8 = .{0} ** 8; // zero the buffer so we do not read 0xaa as integer
3307+
val.writeToPackedMemory(ty, pt, &buf, 0) catch unreachable;
3308+
const int_val = try pt.intValue(
3309+
int_type,
3310+
mem.readInt(u64, &buf, .little),
3311+
);
3312+
return cg.lowerConstant(int_val, int_type);
33253313
},
33263314
.memoized_call => unreachable,
33273315
}
@@ -3369,6 +3357,14 @@ fn emitUndefined(cg: *CodeGen, ty: Type) InnerError!WValue {
33693357
const packed_struct = zcu.typeToPackedStruct(ty).?;
33703358
return cg.emitUndefined(Type.fromInterned(packed_struct.backingIntTypeUnordered(ip)));
33713359
},
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+
},
33723368
else => return cg.fail("Wasm TODO: emitUndefined for type: {}\n", .{ty.zigTypeTag(zcu)}),
33733369
}
33743370
}
@@ -4211,7 +4207,6 @@ fn airUnwrapErrUnionPayload(cg: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool)
42114207
assert(isByRef(eu_ty, zcu, cg.target));
42124208
break :result try cg.load(operand, payload_ty, pl_offset);
42134209
}
4214-
42154210
};
42164211
return cg.finishAir(inst, result, &.{ty_op.operand});
42174212
}
@@ -5691,13 +5686,25 @@ fn airErrUnionPayloadPtrSet(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void
56915686
}
56925687

56935688
fn 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;
56955691
const ty_pl = cg.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
56965692
const extra = cg.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;
56975693

56985694
const field_ptr = try cg.resolveInst(extra.field_ptr);
5699-
const parent_ty = ty_pl.ty.toType().childType(zcu);
5700-
const field_offset = parent_ty.structFieldOffset(extra.field_index, zcu);
5695+
const parent_ptr_ty = cg.typeOfIndex(inst);
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

57025709
const result = if (field_offset != 0) result: {
57035710
const base = try cg.buildPointerOffset(field_ptr, 0, .new);

test/behavior/field_parent_ptr.zig

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -588,7 +588,6 @@ test "@fieldParentPtr extern struct last zero-bit field" {
588588
test "@fieldParentPtr unaligned packed struct" {
589589
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
590590
if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
591-
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
592591
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
593592
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
594593

@@ -727,7 +726,6 @@ test "@fieldParentPtr unaligned packed struct" {
727726
test "@fieldParentPtr aligned packed struct" {
728727
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
729728
if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
730-
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
731729
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
732730
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
733731

@@ -865,7 +863,6 @@ test "@fieldParentPtr aligned packed struct" {
865863

866864
test "@fieldParentPtr nested packed struct" {
867865
if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
868-
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
869866
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
870867
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
871868

@@ -1028,7 +1025,6 @@ test "@fieldParentPtr nested packed struct" {
10281025

10291026
test "@fieldParentPtr packed struct first zero-bit field" {
10301027
if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
1031-
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
10321028
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
10331029
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
10341030

@@ -1134,7 +1130,6 @@ test "@fieldParentPtr packed struct first zero-bit field" {
11341130

11351131
test "@fieldParentPtr packed struct middle zero-bit field" {
11361132
if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
1137-
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
11381133
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
11391134
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
11401135

@@ -1240,7 +1235,6 @@ test "@fieldParentPtr packed struct middle zero-bit field" {
12401235

12411236
test "@fieldParentPtr packed struct last zero-bit field" {
12421237
if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
1243-
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
12441238
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
12451239
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
12461240

@@ -1753,7 +1747,6 @@ test "@fieldParentPtr extern union" {
17531747
}
17541748

17551749
test "@fieldParentPtr packed union" {
1756-
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
17571750
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
17581751
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
17591752
if (builtin.target.cpu.arch.endian() == .big) return error.SkipZigTest; // TODO
@@ -1892,7 +1885,6 @@ test "@fieldParentPtr packed union" {
18921885

18931886
test "@fieldParentPtr tagged union all zero-bit fields" {
18941887
if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
1895-
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
18961888
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
18971889
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
18981890

0 commit comments

Comments
 (0)