| ... | ... | @@ -2885,26 +2885,25 @@ fn wrapOperand(func: *CodeGen, operand: WValue, ty: Type) InnerError!WValue { |
| 2885 | 2885 | return WValue{ .stack = {} }; |
| 2886 | 2886 | } |
| 2887 | 2887 | |
| 2888 | | fn lowerParentPtr(func: *CodeGen, ptr_val: Value, ptr_child_ty: Type) InnerError!WValue { |
| 2888 | fn lowerParentPtr(func: *CodeGen, ptr_val: Value, offset: u32) InnerError!WValue { |
| 2889 | 2889 | switch (ptr_val.tag()) { |
| 2890 | 2890 | .decl_ref_mut => { |
| 2891 | 2891 | const decl_index = ptr_val.castTag(.decl_ref_mut).?.data.decl_index; |
| 2892 | | return func.lowerParentPtrDecl(ptr_val, decl_index); |
| 2892 | return func.lowerParentPtrDecl(ptr_val, decl_index, offset); |
| 2893 | 2893 | }, |
| 2894 | 2894 | .decl_ref => { |
| 2895 | 2895 | const decl_index = ptr_val.castTag(.decl_ref).?.data; |
| 2896 | | return func.lowerParentPtrDecl(ptr_val, decl_index); |
| 2896 | return func.lowerParentPtrDecl(ptr_val, decl_index, offset); |
| 2897 | 2897 | }, |
| 2898 | 2898 | .variable => { |
| 2899 | 2899 | const decl_index = ptr_val.castTag(.variable).?.data.owner_decl; |
| 2900 | | return func.lowerParentPtrDecl(ptr_val, decl_index); |
| 2900 | return func.lowerParentPtrDecl(ptr_val, decl_index, offset); |
| 2901 | 2901 | }, |
| 2902 | 2902 | .field_ptr => { |
| 2903 | 2903 | const field_ptr = ptr_val.castTag(.field_ptr).?.data; |
| 2904 | 2904 | const parent_ty = field_ptr.container_ty; |
| 2905 | | const parent_ptr = try func.lowerParentPtr(field_ptr.container_ptr, parent_ty); |
| 2906 | 2905 | |
| 2907 | | const offset = switch (parent_ty.zigTypeTag()) { |
| 2906 | const field_offset = switch (parent_ty.zigTypeTag()) { |
| 2908 | 2907 | .Struct => switch (parent_ty.containerLayout()) { |
| 2909 | 2908 | .Packed => parent_ty.packedStructFieldByteOffset(field_ptr.field_index, func.target), |
| 2910 | 2909 | else => parent_ty.structFieldOffset(field_ptr.field_index, func.target), |
| ... | ... | @@ -2917,8 +2916,8 @@ fn lowerParentPtr(func: *CodeGen, ptr_val: Value, ptr_child_ty: Type) InnerError |
| 2917 | 2916 | if (layout.payload_align > layout.tag_align) break :blk 0; |
| 2918 | 2917 | |
| 2919 | 2918 | // tag is stored first so calculate offset from where payload starts |
| 2920 | | const offset = @intCast(u32, std.mem.alignForwardGeneric(u64, layout.tag_size, layout.tag_align)); |
| 2921 | | break :blk offset; |
| 2919 | const field_offset = @intCast(u32, std.mem.alignForwardGeneric(u64, layout.tag_size, layout.tag_align)); |
| 2920 | break :blk field_offset; |
| 2922 | 2921 | }, |
| 2923 | 2922 | }, |
| 2924 | 2923 | .Pointer => switch (parent_ty.ptrSize()) { |
| ... | ... | @@ -2931,43 +2930,23 @@ fn lowerParentPtr(func: *CodeGen, ptr_val: Value, ptr_child_ty: Type) InnerError |
| 2931 | 2930 | }, |
| 2932 | 2931 | else => unreachable, |
| 2933 | 2932 | }; |
| 2934 | | |
| 2935 | | return switch (parent_ptr) { |
| 2936 | | .memory => |ptr| WValue{ |
| 2937 | | .memory_offset = .{ |
| 2938 | | .pointer = ptr, |
| 2939 | | .offset = @intCast(u32, offset), |
| 2940 | | }, |
| 2941 | | }, |
| 2942 | | .memory_offset => |mem_off| WValue{ |
| 2943 | | .memory_offset = .{ |
| 2944 | | .pointer = mem_off.pointer, |
| 2945 | | .offset = @intCast(u32, offset) + mem_off.offset, |
| 2946 | | }, |
| 2947 | | }, |
| 2948 | | else => unreachable, |
| 2949 | | }; |
| 2933 | return func.lowerParentPtr(field_ptr.container_ptr, offset + @intCast(u32, field_offset)); |
| 2950 | 2934 | }, |
| 2951 | 2935 | .elem_ptr => { |
| 2952 | 2936 | const elem_ptr = ptr_val.castTag(.elem_ptr).?.data; |
| 2953 | 2937 | const index = elem_ptr.index; |
| 2954 | | const offset = index * ptr_child_ty.abiSize(func.target); |
| 2955 | | const array_ptr = try func.lowerParentPtr(elem_ptr.array_ptr, elem_ptr.elem_ty); |
| 2956 | | |
| 2957 | | return WValue{ .memory_offset = .{ |
| 2958 | | .pointer = array_ptr.memory, |
| 2959 | | .offset = @intCast(u32, offset), |
| 2960 | | } }; |
| 2938 | const elem_offset = index * elem_ptr.elem_ty.abiSize(func.target); |
| 2939 | return func.lowerParentPtr(elem_ptr.array_ptr, offset + @intCast(u32, elem_offset)); |
| 2961 | 2940 | }, |
| 2962 | 2941 | .opt_payload_ptr => { |
| 2963 | 2942 | const payload_ptr = ptr_val.castTag(.opt_payload_ptr).?.data; |
| 2964 | | return func.lowerParentPtr(payload_ptr.container_ptr, payload_ptr.container_ty); |
| 2943 | return func.lowerParentPtr(payload_ptr.container_ptr, offset); |
| 2965 | 2944 | }, |
| 2966 | 2945 | else => |tag| return func.fail("TODO: Implement lowerParentPtr for tag: {}", .{tag}), |
| 2967 | 2946 | } |
| 2968 | 2947 | } |
| 2969 | 2948 | |
| 2970 | | fn lowerParentPtrDecl(func: *CodeGen, ptr_val: Value, decl_index: Module.Decl.Index) InnerError!WValue { |
| 2949 | fn lowerParentPtrDecl(func: *CodeGen, ptr_val: Value, decl_index: Module.Decl.Index, offset: u32) InnerError!WValue { |
| 2971 | 2950 | const module = func.bin_file.base.options.module.?; |
| 2972 | 2951 | const decl = module.declPtr(decl_index); |
| 2973 | 2952 | module.markDeclAlive(decl); |
| ... | ... | @@ -2976,10 +2955,10 @@ fn lowerParentPtrDecl(func: *CodeGen, ptr_val: Value, decl_index: Module.Decl.In |
| 2976 | 2955 | .data = decl.ty, |
| 2977 | 2956 | }; |
| 2978 | 2957 | const ptr_ty = Type.initPayload(&ptr_ty_payload.base); |
| 2979 | | return func.lowerDeclRefValue(.{ .ty = ptr_ty, .val = ptr_val }, decl_index); |
| 2958 | return func.lowerDeclRefValue(.{ .ty = ptr_ty, .val = ptr_val }, decl_index, offset); |
| 2980 | 2959 | } |
| 2981 | 2960 | |
| 2982 | | fn lowerDeclRefValue(func: *CodeGen, tv: TypedValue, decl_index: Module.Decl.Index) InnerError!WValue { |
| 2961 | fn lowerDeclRefValue(func: *CodeGen, tv: TypedValue, decl_index: Module.Decl.Index, offset: u32) InnerError!WValue { |
| 2983 | 2962 | if (tv.ty.isSlice()) { |
| 2984 | 2963 | return WValue{ .memory = try func.bin_file.lowerUnnamedConst(tv, decl_index) }; |
| 2985 | 2964 | } |
| ... | ... | @@ -2998,7 +2977,9 @@ fn lowerDeclRefValue(func: *CodeGen, tv: TypedValue, decl_index: Module.Decl.Ind |
| 2998 | 2977 | if (decl.ty.zigTypeTag() == .Fn) { |
| 2999 | 2978 | try func.bin_file.addTableFunction(target_sym_index); |
| 3000 | 2979 | return WValue{ .function_index = target_sym_index }; |
| 3001 | | } else return WValue{ .memory = target_sym_index }; |
| 2980 | } else if (offset == 0) { |
| 2981 | return WValue{ .memory = target_sym_index }; |
| 2982 | } else return WValue{ .memory_offset = .{ .pointer = target_sym_index, .offset = offset } }; |
| 3002 | 2983 | } |
| 3003 | 2984 | |
| 3004 | 2985 | /// Converts a signed integer to its 2's complement form and returns |
| ... | ... | @@ -3025,11 +3006,11 @@ fn lowerConstant(func: *CodeGen, arg_val: Value, ty: Type) InnerError!WValue { |
| 3025 | 3006 | if (val.isUndefDeep()) return func.emitUndefined(ty); |
| 3026 | 3007 | if (val.castTag(.decl_ref)) |decl_ref| { |
| 3027 | 3008 | const decl_index = decl_ref.data; |
| 3028 | | return func.lowerDeclRefValue(.{ .ty = ty, .val = val }, decl_index); |
| 3009 | return func.lowerDeclRefValue(.{ .ty = ty, .val = val }, decl_index, 0); |
| 3029 | 3010 | } |
| 3030 | 3011 | if (val.castTag(.decl_ref_mut)) |decl_ref_mut| { |
| 3031 | 3012 | const decl_index = decl_ref_mut.data.decl_index; |
| 3032 | | return func.lowerDeclRefValue(.{ .ty = ty, .val = val }, decl_index); |
| 3013 | return func.lowerDeclRefValue(.{ .ty = ty, .val = val }, decl_index, 0); |
| 3033 | 3014 | } |
| 3034 | 3015 | const target = func.target; |
| 3035 | 3016 | switch (ty.zigTypeTag()) { |
| ... | ... | @@ -3063,9 +3044,7 @@ fn lowerConstant(func: *CodeGen, arg_val: Value, ty: Type) InnerError!WValue { |
| 3063 | 3044 | else => unreachable, |
| 3064 | 3045 | }, |
| 3065 | 3046 | .Pointer => switch (val.tag()) { |
| 3066 | | .field_ptr, .elem_ptr, .opt_payload_ptr => { |
| 3067 | | return func.lowerParentPtr(val, ty.childType()); |
| 3068 | | }, |
| 3047 | .field_ptr, .elem_ptr, .opt_payload_ptr => return func.lowerParentPtr(val, 0), |
| 3069 | 3048 | .int_u64, .one => return WValue{ .imm32 = @intCast(u32, val.toUnsignedInt(target)) }, |
| 3070 | 3049 | .zero, .null_value => return WValue{ .imm32 = 0 }, |
| 3071 | 3050 | else => return func.fail("Wasm TODO: lowerConstant for other const pointer tag {}", .{val.tag()}), |
| ... | ... | @@ -5281,7 +5260,7 @@ fn airMemcpy(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5281 | 5260 | const src_ty = func.air.typeOf(bin_op.rhs); |
| 5282 | 5261 | const len = switch (dst_ty.ptrSize()) { |
| 5283 | 5262 | .Slice => try func.sliceLen(dst), |
| 5284 | | .One => @as(WValue, .{ .imm64 = dst_ty.childType().arrayLen() }), |
| 5263 | .One => @as(WValue, .{ .imm32 = @intCast(u32, dst_ty.childType().arrayLen()) }), |
| 5285 | 5264 | .C, .Many => unreachable, |
| 5286 | 5265 | }; |
| 5287 | 5266 | const dst_ptr = try func.sliceOrArrayPtr(dst, dst_ty); |