| ... | ... | @@ -2938,49 +2938,31 @@ fn wrapOperand(func: *CodeGen, operand: WValue, ty: Type) InnerError!WValue { |
| 2938 | 2938 | return WValue{ .stack = {} }; |
| 2939 | 2939 | } |
| 2940 | 2940 | |
| 2941 | | fn lowerParentPtr(func: *CodeGen, ptr_val: Value) InnerError!WValue { |
| 2941 | fn lowerParentPtr(func: *CodeGen, ptr_val: Value, offset: u32) InnerError!WValue { |
| 2942 | 2942 | const mod = func.bin_file.base.options.module.?; |
| 2943 | 2943 | const ptr = mod.intern_pool.indexToKey(ptr_val.ip_index).ptr; |
| 2944 | 2944 | switch (ptr.addr) { |
| 2945 | 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 | 2948 | .mut_decl => |mut_decl| { |
| 2949 | 2949 | const decl_index = mut_decl.decl; |
| 2950 | | return func.lowerParentPtrDecl(ptr_val, decl_index, 0); |
| 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()); |
| 2950 | return func.lowerParentPtrDecl(ptr_val, decl_index, offset); |
| 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 | 2955 | .comptime_field => unreachable, |
| 2957 | 2956 | .elem => |elem| { |
| 2958 | 2957 | const index = elem.index; |
| 2959 | 2958 | const elem_type = mod.intern_pool.typeOf(elem.base).toType().elemType2(mod); |
| 2960 | | const offset = index * elem_type.abiSize(mod); |
| 2961 | | const array_ptr = try func.lowerParentPtr(elem.base.toValue()); |
| 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 | | }; |
| 2959 | const elem_offset = index * elem_type.abiSize(mod); |
| 2960 | return func.lowerParentPtr(elem.base.toValue(), @intCast(u32, elem_offset + offset)); |
| 2978 | 2961 | }, |
| 2979 | 2962 | .field => |field| { |
| 2980 | 2963 | const parent_ty = mod.intern_pool.typeOf(field.base).toType().childType(mod); |
| 2981 | | const parent_ptr = try func.lowerParentPtr(field.base.toValue()); |
| 2982 | 2964 | |
| 2983 | | const offset = switch (parent_ty.zigTypeTag(mod)) { |
| 2965 | const field_offset = switch (parent_ty.zigTypeTag(mod)) { |
| 2984 | 2966 | .Struct => switch (parent_ty.containerLayout(mod)) { |
| 2985 | 2967 | .Packed => parent_ty.packedStructFieldByteOffset(@intCast(usize, field.index), mod), |
| 2986 | 2968 | else => parent_ty.structFieldOffset(@intCast(usize, field.index), mod), |
| ... | ... | @@ -2993,8 +2975,7 @@ fn lowerParentPtr(func: *CodeGen, ptr_val: Value) InnerError!WValue { |
| 2993 | 2975 | if (layout.payload_align > layout.tag_align) break :blk 0; |
| 2994 | 2976 | |
| 2995 | 2977 | // 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)); |
| 2997 | | break :blk offset; |
| 2978 | break :blk @intCast(u32, std.mem.alignForwardGeneric(u64, layout.tag_size, layout.tag_align)); |
| 2998 | 2979 | }, |
| 2999 | 2980 | }, |
| 3000 | 2981 | .Pointer => switch (parent_ty.ptrSize(mod)) { |
| ... | ... | @@ -3007,22 +2988,7 @@ fn lowerParentPtr(func: *CodeGen, ptr_val: Value) InnerError!WValue { |
| 3007 | 2988 | }, |
| 3008 | 2989 | else => unreachable, |
| 3009 | 2990 | }; |
| 3010 | | |
| 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 | | }; |
| 2991 | return func.lowerParentPtr(field.base.toValue(), @intCast(u32, offset + field_offset)); |
| 3026 | 2992 | }, |
| 3027 | 2993 | } |
| 3028 | 2994 | } |
| ... | ... | @@ -3230,7 +3196,7 @@ fn lowerConstant(func: *CodeGen, arg_val: Value, ty: Type) InnerError!WValue { |
| 3230 | 3196 | .decl => |decl| return func.lowerDeclRefValue(.{ .ty = ty, .val = val }, decl, 0), |
| 3231 | 3197 | .mut_decl => |mut_decl| return func.lowerDeclRefValue(.{ .ty = ty, .val = val }, mut_decl.decl, 0), |
| 3232 | 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 | 3200 | else => return func.fail("Wasm TODO: lowerConstant for other const addr tag {}", .{ptr.addr}), |
| 3235 | 3201 | }, |
| 3236 | 3202 | .opt => if (ty.optionalReprIsPayload(mod)) { |