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