Skip to content

Commit 8fd0fdd

Browse files
committed
zig build system progress
* In-progress os.ChildProcess.spawn implementation. See #204 * Add explicit cast from integer to error. Closes #294 * fix casting from error to integer * fix compiler crash when initializing variable to undefined with no type
1 parent 0594487 commit 8fd0fdd

File tree

11 files changed

+742
-51
lines changed

11 files changed

+742
-51
lines changed

src/all_types.hpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -520,7 +520,6 @@ struct AstNodeUnwrapErrorExpr {
520520
enum CastOp {
521521
CastOpNoCast, // signifies the function call expression is not a cast
522522
CastOpNoop, // fn call expr is a cast, but does nothing
523-
CastOpErrToInt,
524523
CastOpIntToFloat,
525524
CastOpFloatToInt,
526525
CastOpBoolToInt,
@@ -1223,6 +1222,7 @@ enum PanicMsgId {
12231222
PanicMsgIdSliceWidenRemainder,
12241223
PanicMsgIdUnwrapMaybeFail,
12251224
PanicMsgIdUnwrapErrFail,
1225+
PanicMsgIdInvalidErrorCode,
12261226

12271227
PanicMsgIdCount,
12281228
};
@@ -1728,6 +1728,8 @@ enum IrInstructionId {
17281728
IrInstructionIdIntToPtr,
17291729
IrInstructionIdPtrToInt,
17301730
IrInstructionIdIntToEnum,
1731+
IrInstructionIdIntToErr,
1732+
IrInstructionIdErrToInt,
17311733
IrInstructionIdCheckSwitchProngs,
17321734
IrInstructionIdTestType,
17331735
IrInstructionIdTypeName,
@@ -2404,6 +2406,18 @@ struct IrInstructionIntToEnum {
24042406
IrInstruction *target;
24052407
};
24062408

2409+
struct IrInstructionIntToErr {
2410+
IrInstruction base;
2411+
2412+
IrInstruction *target;
2413+
};
2414+
2415+
struct IrInstructionErrToInt {
2416+
IrInstruction base;
2417+
2418+
IrInstruction *target;
2419+
};
2420+
24072421
struct IrInstructionCheckSwitchProngsRange {
24082422
IrInstruction *start;
24092423
IrInstruction *end;

src/codegen.cpp

Lines changed: 66 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -570,6 +570,8 @@ static Buf *panic_msg_buf(PanicMsgId msg_id) {
570570
return buf_create_from_str("attempt to unwrap error");
571571
case PanicMsgIdUnreachable:
572572
return buf_create_from_str("reached unreachable code");
573+
case PanicMsgIdInvalidErrorCode:
574+
return buf_create_from_str("invalid error code");
573575
}
574576
zig_unreachable();
575577
}
@@ -1227,14 +1229,6 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable,
12271229
zig_unreachable();
12281230
case CastOpNoop:
12291231
return expr_val;
1230-
case CastOpErrToInt:
1231-
assert(actual_type->id == TypeTableEntryIdErrorUnion);
1232-
if (!type_has_bits(actual_type->data.error.child_type)) {
1233-
return gen_widen_or_shorten(g, ir_want_debug_safety(g, &cast_instruction->base),
1234-
g->err_tag_type, wanted_type, expr_val);
1235-
} else {
1236-
zig_panic("TODO");
1237-
}
12381232
case CastOpResizeSlice:
12391233
{
12401234
assert(cast_instruction->tmp_ptr);
@@ -1402,6 +1396,66 @@ static LLVMValueRef ir_render_int_to_enum(CodeGen *g, IrExecutable *executable,
14021396
instruction->target->value.type, wanted_int_type, target_val);
14031397
}
14041398

1399+
static LLVMValueRef ir_render_int_to_err(CodeGen *g, IrExecutable *executable, IrInstructionIntToErr *instruction) {
1400+
TypeTableEntry *wanted_type = instruction->base.value.type;
1401+
assert(wanted_type->id == TypeTableEntryIdPureError);
1402+
1403+
TypeTableEntry *actual_type = instruction->target->value.type;
1404+
assert(actual_type->id == TypeTableEntryIdInt);
1405+
assert(!actual_type->data.integral.is_signed);
1406+
1407+
LLVMValueRef target_val = ir_llvm_value(g, instruction->target);
1408+
1409+
if (ir_want_debug_safety(g, &instruction->base)) {
1410+
LLVMValueRef zero = LLVMConstNull(actual_type->type_ref);
1411+
LLVMValueRef neq_zero_bit = LLVMBuildICmp(g->builder, LLVMIntNE, target_val, zero, "");
1412+
LLVMValueRef ok_bit;
1413+
uint64_t biggest_possible_err_val = max_unsigned_val(actual_type);
1414+
if (biggest_possible_err_val < g->error_decls.length) {
1415+
ok_bit = neq_zero_bit;
1416+
} else {
1417+
LLVMValueRef error_value_count = LLVMConstInt(actual_type->type_ref, g->error_decls.length, false);
1418+
LLVMValueRef in_bounds_bit = LLVMBuildICmp(g->builder, LLVMIntULT, target_val, error_value_count, "");
1419+
ok_bit = LLVMBuildAnd(g->builder, neq_zero_bit, in_bounds_bit, "");
1420+
}
1421+
1422+
LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "IntToErrOk");
1423+
LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "IntToErrFail");
1424+
1425+
LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);
1426+
1427+
LLVMPositionBuilderAtEnd(g->builder, fail_block);
1428+
gen_debug_safety_crash(g, PanicMsgIdInvalidErrorCode);
1429+
1430+
LLVMPositionBuilderAtEnd(g->builder, ok_block);
1431+
}
1432+
1433+
return gen_widen_or_shorten(g, false, actual_type, g->err_tag_type, target_val);
1434+
}
1435+
1436+
static LLVMValueRef ir_render_err_to_int(CodeGen *g, IrExecutable *executable, IrInstructionErrToInt *instruction) {
1437+
TypeTableEntry *wanted_type = instruction->base.value.type;
1438+
assert(wanted_type->id == TypeTableEntryIdInt);
1439+
assert(!wanted_type->data.integral.is_signed);
1440+
1441+
TypeTableEntry *actual_type = instruction->target->value.type;
1442+
LLVMValueRef target_val = ir_llvm_value(g, instruction->target);
1443+
1444+
if (actual_type->id == TypeTableEntryIdPureError) {
1445+
return gen_widen_or_shorten(g, ir_want_debug_safety(g, &instruction->base),
1446+
g->err_tag_type, wanted_type, target_val);
1447+
} else if (actual_type->id == TypeTableEntryIdErrorUnion) {
1448+
if (!type_has_bits(actual_type->data.error.child_type)) {
1449+
return gen_widen_or_shorten(g, ir_want_debug_safety(g, &instruction->base),
1450+
g->err_tag_type, wanted_type, target_val);
1451+
} else {
1452+
zig_panic("TODO");
1453+
}
1454+
} else {
1455+
zig_unreachable();
1456+
}
1457+
}
1458+
14051459
static LLVMValueRef ir_render_unreachable(CodeGen *g, IrExecutable *executable,
14061460
IrInstructionUnreachable *unreachable_instruction)
14071461
{
@@ -2786,6 +2840,10 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
27862840
return ir_render_int_to_ptr(g, executable, (IrInstructionIntToPtr *)instruction);
27872841
case IrInstructionIdIntToEnum:
27882842
return ir_render_int_to_enum(g, executable, (IrInstructionIntToEnum *)instruction);
2843+
case IrInstructionIdIntToErr:
2844+
return ir_render_int_to_err(g, executable, (IrInstructionIntToErr *)instruction);
2845+
case IrInstructionIdErrToInt:
2846+
return ir_render_err_to_int(g, executable, (IrInstructionErrToInt *)instruction);
27892847
case IrInstructionIdContainerInitList:
27902848
return ir_render_container_init_list(g, executable, (IrInstructionContainerInitList *)instruction);
27912849
case IrInstructionIdPanic:

0 commit comments

Comments
 (0)