authorgravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2023-06-14 20:01:52+02:00
committergravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2023-06-16 17:16:56+02:00
log098b0b50ab3980a257ad0840034f21ef5349ac8b
tree1254f7eee11ae765ae0e8ce1ed0b3a70327200b5
parent729f822e311f3bce1e7bd99bcf71937145451a4c
signaturelock-open Commit is signed but in an unrecognized format.

wasm: fix lowerParentPtr offsets

The was incorrectly merged during internPool. This commit forward fixes that and reinstates the correct logic.

1 files changed, 12 insertions(+), 46 deletions(-)

src/arch/wasm/CodeGen.zig+12-46
...@@ -2938,49 +2938,31 @@ fn wrapOperand(func: *CodeGen, operand: WValue, ty: Type) InnerError!WValue {...@@ -2938,49 +2938,31 @@ fn wrapOperand(func: *CodeGen, operand: WValue, ty: Type) InnerError!WValue {
2938 return WValue{ .stack = {} };2938 return WValue{ .stack = {} };
2939}2939}
29402940
2941fn lowerParentPtr(func: *CodeGen, ptr_val: Value) InnerError!WValue {2941fn lowerParentPtr(func: *CodeGen, ptr_val: Value, offset: u32) InnerError!WValue {
2942 const mod = func.bin_file.base.options.module.?;2942 const mod = func.bin_file.base.options.module.?;
2943 const ptr = mod.intern_pool.indexToKey(ptr_val.ip_index).ptr;2943 const ptr = mod.intern_pool.indexToKey(ptr_val.ip_index).ptr;
2944 switch (ptr.addr) {2944 switch (ptr.addr) {
2945 .decl => |decl_index| {2945 .decl => |decl_index| {
2946 return func.lowerParentPtrDecl(ptr_val, decl_index, 0);2946 return func.lowerParentPtrDecl(ptr_val, decl_index, offset);
2947 },2947 },
2948 .mut_decl => |mut_decl| {2948 .mut_decl => |mut_decl| {
2949 const decl_index = mut_decl.decl;2949 const decl_index = mut_decl.decl;
2950 return func.lowerParentPtrDecl(ptr_val, decl_index, 0);2950 return func.lowerParentPtrDecl(ptr_val, decl_index, offset);
2951 },
2952 .int, .eu_payload => |tag| return func.fail("TODO: Implement lowerParentPtr for {}", .{tag}),
2953 .opt_payload => |base_ptr| {
2954 return func.lowerParentPtr(base_ptr.toValue());
2955 },2951 },
2952 .eu_payload => |tag| return func.fail("TODO: Implement lowerParentPtr for {}", .{tag}),
2953 .int => |base| return func.lowerConstant(base.toValue(), Type.usize),
2954 .opt_payload => |base_ptr| return func.lowerParentPtr(base_ptr.toValue(), offset),
2956 .comptime_field => unreachable,2955 .comptime_field => unreachable,
2957 .elem => |elem| {2956 .elem => |elem| {
2958 const index = elem.index;2957 const index = elem.index;
2959 const elem_type = mod.intern_pool.typeOf(elem.base).toType().elemType2(mod);2958 const elem_type = mod.intern_pool.typeOf(elem.base).toType().elemType2(mod);
2960 const offset = index * elem_type.abiSize(mod);2959 const elem_offset = index * elem_type.abiSize(mod);
2961 const array_ptr = try func.lowerParentPtr(elem.base.toValue());2960 return func.lowerParentPtr(elem.base.toValue(), @intCast(u32, elem_offset + offset));
2962
2963 return switch (array_ptr) {
2964 .memory => |ptr_| WValue{
2965 .memory_offset = .{
2966 .pointer = ptr_,
2967 .offset = @intCast(u32, offset),
2968 },
2969 },
2970 .memory_offset => |mem_off| WValue{
2971 .memory_offset = .{
2972 .pointer = mem_off.pointer,
2973 .offset = @intCast(u32, offset) + mem_off.offset,
2974 },
2975 },
2976 else => unreachable,
2977 };
2978 },2961 },
2979 .field => |field| {2962 .field => |field| {
2980 const parent_ty = mod.intern_pool.typeOf(field.base).toType().childType(mod);2963 const parent_ty = mod.intern_pool.typeOf(field.base).toType().childType(mod);
2981 const parent_ptr = try func.lowerParentPtr(field.base.toValue());
29822964
2983 const offset = switch (parent_ty.zigTypeTag(mod)) {2965 const field_offset = switch (parent_ty.zigTypeTag(mod)) {
2984 .Struct => switch (parent_ty.containerLayout(mod)) {2966 .Struct => switch (parent_ty.containerLayout(mod)) {
2985 .Packed => parent_ty.packedStructFieldByteOffset(@intCast(usize, field.index), mod),2967 .Packed => parent_ty.packedStructFieldByteOffset(@intCast(usize, field.index), mod),
2986 else => parent_ty.structFieldOffset(@intCast(usize, field.index), mod),2968 else => parent_ty.structFieldOffset(@intCast(usize, field.index), mod),
...@@ -2993,8 +2975,7 @@ fn lowerParentPtr(func: *CodeGen, ptr_val: Value) InnerError!WValue {...@@ -2993,8 +2975,7 @@ fn lowerParentPtr(func: *CodeGen, ptr_val: Value) InnerError!WValue {
2993 if (layout.payload_align > layout.tag_align) break :blk 0;2975 if (layout.payload_align > layout.tag_align) break :blk 0;
29942976
2995 // tag is stored first so calculate offset from where payload starts2977 // tag is stored first so calculate offset from where payload starts
2996 const offset = @intCast(u32, std.mem.alignForwardGeneric(u64, layout.tag_size, layout.tag_align));2978 break :blk @intCast(u32, std.mem.alignForwardGeneric(u64, layout.tag_size, layout.tag_align));
2997 break :blk offset;
2998 },2979 },
2999 },2980 },
3000 .Pointer => switch (parent_ty.ptrSize(mod)) {2981 .Pointer => switch (parent_ty.ptrSize(mod)) {
...@@ -3007,22 +2988,7 @@ fn lowerParentPtr(func: *CodeGen, ptr_val: Value) InnerError!WValue {...@@ -3007,22 +2988,7 @@ fn lowerParentPtr(func: *CodeGen, ptr_val: Value) InnerError!WValue {
3007 },2988 },
3008 else => unreachable,2989 else => unreachable,
3009 };2990 };
30102991 return func.lowerParentPtr(field.base.toValue(), @intCast(u32, offset + field_offset));
3011 return switch (parent_ptr) {
3012 .memory => |ptr_| WValue{
3013 .memory_offset = .{
3014 .pointer = ptr_,
3015 .offset = @intCast(u32, offset),
3016 },
3017 },
3018 .memory_offset => |mem_off| WValue{
3019 .memory_offset = .{
3020 .pointer = mem_off.pointer,
3021 .offset = @intCast(u32, offset) + mem_off.offset,
3022 },
3023 },
3024 else => unreachable,
3025 };
3026 },2992 },
3027 }2993 }
3028}2994}
...@@ -3230,7 +3196,7 @@ fn lowerConstant(func: *CodeGen, arg_val: Value, ty: Type) InnerError!WValue {...@@ -3230,7 +3196,7 @@ fn lowerConstant(func: *CodeGen, arg_val: Value, ty: Type) InnerError!WValue {
3230 .decl => |decl| return func.lowerDeclRefValue(.{ .ty = ty, .val = val }, decl, 0),3196 .decl => |decl| return func.lowerDeclRefValue(.{ .ty = ty, .val = val }, decl, 0),
3231 .mut_decl => |mut_decl| return func.lowerDeclRefValue(.{ .ty = ty, .val = val }, mut_decl.decl, 0),3197 .mut_decl => |mut_decl| return func.lowerDeclRefValue(.{ .ty = ty, .val = val }, mut_decl.decl, 0),
3232 .int => |int| return func.lowerConstant(int.toValue(), mod.intern_pool.typeOf(int).toType()),3198 .int => |int| return func.lowerConstant(int.toValue(), mod.intern_pool.typeOf(int).toType()),
3233 .opt_payload, .elem, .field => return func.lowerParentPtr(val),3199 .opt_payload, .elem, .field => return func.lowerParentPtr(val, 0),
3234 else => return func.fail("Wasm TODO: lowerConstant for other const addr tag {}", .{ptr.addr}),3200 else => return func.fail("Wasm TODO: lowerConstant for other const addr tag {}", .{ptr.addr}),
3235 },3201 },
3236 .opt => if (ty.optionalReprIsPayload(mod)) {3202 .opt => if (ty.optionalReprIsPayload(mod)) {