| ... | @@ -1875,8 +1875,8 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO | ... | @@ -1875,8 +1875,8 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO |
| 1875 | .union_init => try airUnionInit(f, inst), | 1875 | .union_init => try airUnionInit(f, inst), |
| 1876 | .prefetch => try airPrefetch(f, inst), | 1876 | .prefetch => try airPrefetch(f, inst), |
| 1877 | | 1877 | |
| 1878 | .@"try" => @panic("TODO"), | 1878 | .@"try" => try airTry(f, inst), |
| 1879 | .try_ptr => @panic("TODO"), | 1879 | .try_ptr => try airTryPtr(f, inst), |
| 1880 | | 1880 | |
| 1881 | .dbg_var_ptr, | 1881 | .dbg_var_ptr, |
| 1882 | .dbg_var_val, | 1882 | .dbg_var_val, |
| ... | @@ -2864,6 +2864,91 @@ fn airBlock(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -2864,6 +2864,91 @@ fn airBlock(f: *Function, inst: Air.Inst.Index) !CValue { |
| 2864 | return result; | 2864 | return result; |
| 2865 | } | 2865 | } |
| 2866 | | 2866 | |
| | 2867 | fn airTry(f: *Function, inst: Air.Inst.Index) !CValue { |
| | 2868 | const pl_op = f.air.instructions.items(.data)[inst].pl_op; |
| | 2869 | const err_union = try f.resolveInst(pl_op.operand); |
| | 2870 | const extra = f.air.extraData(Air.Try, pl_op.payload); |
| | 2871 | const body = f.air.extra[extra.end..][0..extra.data.body_len]; |
| | 2872 | const err_union_ty = f.air.typeOf(pl_op.operand); |
| | 2873 | const result_ty = f.air.typeOfIndex(inst); |
| | 2874 | return lowerTry(f, err_union, body, err_union_ty, false, result_ty); |
| | 2875 | } |
| | 2876 | |
| | 2877 | fn airTryPtr(f: *Function, inst: Air.Inst.Index) !CValue { |
| | 2878 | const ty_pl = f.air.instructions.items(.data)[inst].ty_pl; |
| | 2879 | const extra = f.air.extraData(Air.TryPtr, ty_pl.payload); |
| | 2880 | const err_union_ptr = try f.resolveInst(extra.data.ptr); |
| | 2881 | const body = f.air.extra[extra.end..][0..extra.data.body_len]; |
| | 2882 | const err_union_ty = f.air.typeOf(extra.data.ptr).childType(); |
| | 2883 | const result_ty = f.air.typeOfIndex(inst); |
| | 2884 | return lowerTry(f, err_union_ptr, body, err_union_ty, true, result_ty); |
| | 2885 | } |
| | 2886 | |
| | 2887 | fn lowerTry( |
| | 2888 | f: *Function, |
| | 2889 | err_union: CValue, |
| | 2890 | body: []const Air.Inst.Index, |
| | 2891 | err_union_ty: Type, |
| | 2892 | operand_is_ptr: bool, |
| | 2893 | result_ty: Type, |
| | 2894 | ) !CValue { |
| | 2895 | if (err_union_ty.errorUnionSet().errorSetCardinality() == .zero) { |
| | 2896 | // If the error set has no fields, then the payload and the error |
| | 2897 | // union are the same value. |
| | 2898 | return err_union; |
| | 2899 | } |
| | 2900 | |
| | 2901 | const payload_ty = err_union_ty.errorUnionPayload(); |
| | 2902 | const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(); |
| | 2903 | |
| | 2904 | const writer = f.object.writer(); |
| | 2905 | |
| | 2906 | err: { |
| | 2907 | if (!payload_has_bits) { |
| | 2908 | if (operand_is_ptr) { |
| | 2909 | try writer.writeAll("if(*"); |
| | 2910 | } else { |
| | 2911 | try writer.writeAll("if("); |
| | 2912 | } |
| | 2913 | try f.writeCValue(writer, err_union); |
| | 2914 | try writer.writeAll(")"); |
| | 2915 | break :err; |
| | 2916 | } |
| | 2917 | if (operand_is_ptr or isByRef(err_union_ty)) { |
| | 2918 | try writer.writeAll("if("); |
| | 2919 | try f.writeCValue(writer, err_union); |
| | 2920 | try writer.writeAll("->error)"); |
| | 2921 | break :err; |
| | 2922 | } |
| | 2923 | try writer.writeAll("if("); |
| | 2924 | try f.writeCValue(writer, err_union); |
| | 2925 | try writer.writeAll(".error)"); |
| | 2926 | } |
| | 2927 | |
| | 2928 | try genBody(f, body); |
| | 2929 | try f.object.indent_writer.insertNewline(); |
| | 2930 | |
| | 2931 | if (!payload_has_bits) { |
| | 2932 | if (!operand_is_ptr) { |
| | 2933 | return CValue.none; |
| | 2934 | } else { |
| | 2935 | return err_union; |
| | 2936 | } |
| | 2937 | } |
| | 2938 | |
| | 2939 | const local = try f.allocLocal(result_ty, .Const); |
| | 2940 | if (operand_is_ptr or isByRef(payload_ty)) { |
| | 2941 | try writer.writeAll(" = &"); |
| | 2942 | try f.writeCValue(writer, err_union); |
| | 2943 | try writer.writeAll("->payload;\n"); |
| | 2944 | } else { |
| | 2945 | try writer.writeAll(" = "); |
| | 2946 | try f.writeCValue(writer, err_union); |
| | 2947 | try writer.writeAll(".payload;\n"); |
| | 2948 | } |
| | 2949 | return local; |
| | 2950 | } |
| | 2951 | |
| 2867 | fn airBr(f: *Function, inst: Air.Inst.Index) !CValue { | 2952 | fn airBr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 2868 | const branch = f.air.instructions.items(.data)[inst].br; | 2953 | const branch = f.air.instructions.items(.data)[inst].br; |
| 2869 | const block = f.blocks.get(branch.block_inst).?; | 2954 | const block = f.blocks.get(branch.block_inst).?; |
| ... | @@ -4224,3 +4309,8 @@ fn loweredFnRetTyHasBits(fn_ty: Type) bool { | ... | @@ -4224,3 +4309,8 @@ fn loweredFnRetTyHasBits(fn_ty: Type) bool { |
| 4224 | } | 4309 | } |
| 4225 | return false; | 4310 | return false; |
| 4226 | } | 4311 | } |
| | 4312 | |
| | 4313 | fn isByRef(ty: Type) bool { |
| | 4314 | _ = ty; |
| | 4315 | return false; |
| | 4316 | } |