authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-06-03 16:10:41-07:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-06-05 10:37:08+02:00
logd2f31d315e47c3918cd711d1008862df49df38f2
tree837e3a388702515cd6037b0b7a3b648a710b86bb
parent779770cff58923e5113b5419accf910059fddea7

C backend: implement `try` instruction


1 files changed, 92 insertions(+), 2 deletions(-)

src/codegen/c.zig+92-2
...@@ -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),
18771877
1878 .@"try" => @panic("TODO"),1878 .@"try" => try airTry(f, inst),
1879 .try_ptr => @panic("TODO"),1879 .try_ptr => try airTryPtr(f, inst),
18801880
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}
28662866
2867fn 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
2877fn 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
2887fn 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
2867fn airBr(f: *Function, inst: Air.Inst.Index) !CValue {2952fn 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
4313fn isByRef(ty: Type) bool {
4314 _ = ty;
4315 return false;
4316}