Skip to content

Commit

Permalink
zig build system progress
Browse files Browse the repository at this point in the history
 * 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
  • Loading branch information
andrewrk committed Apr 2, 2017
1 parent 0594487 commit 8fd0fdd
Show file tree
Hide file tree
Showing 11 changed files with 742 additions and 51 deletions.
16 changes: 15 additions & 1 deletion src/all_types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -520,7 +520,6 @@ struct AstNodeUnwrapErrorExpr {
enum CastOp {
CastOpNoCast, // signifies the function call expression is not a cast
CastOpNoop, // fn call expr is a cast, but does nothing
CastOpErrToInt,
CastOpIntToFloat,
CastOpFloatToInt,
CastOpBoolToInt,
Expand Down Expand Up @@ -1223,6 +1222,7 @@ enum PanicMsgId {
PanicMsgIdSliceWidenRemainder,
PanicMsgIdUnwrapMaybeFail,
PanicMsgIdUnwrapErrFail,
PanicMsgIdInvalidErrorCode,

PanicMsgIdCount,
};
Expand Down Expand Up @@ -1728,6 +1728,8 @@ enum IrInstructionId {
IrInstructionIdIntToPtr,
IrInstructionIdPtrToInt,
IrInstructionIdIntToEnum,
IrInstructionIdIntToErr,
IrInstructionIdErrToInt,
IrInstructionIdCheckSwitchProngs,
IrInstructionIdTestType,
IrInstructionIdTypeName,
Expand Down Expand Up @@ -2404,6 +2406,18 @@ struct IrInstructionIntToEnum {
IrInstruction *target;
};

struct IrInstructionIntToErr {
IrInstruction base;

IrInstruction *target;
};

struct IrInstructionErrToInt {
IrInstruction base;

IrInstruction *target;
};

struct IrInstructionCheckSwitchProngsRange {
IrInstruction *start;
IrInstruction *end;
Expand Down
74 changes: 66 additions & 8 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -570,6 +570,8 @@ static Buf *panic_msg_buf(PanicMsgId msg_id) {
return buf_create_from_str("attempt to unwrap error");
case PanicMsgIdUnreachable:
return buf_create_from_str("reached unreachable code");
case PanicMsgIdInvalidErrorCode:
return buf_create_from_str("invalid error code");
}
zig_unreachable();
}
Expand Down Expand Up @@ -1227,14 +1229,6 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable,
zig_unreachable();
case CastOpNoop:
return expr_val;
case CastOpErrToInt:
assert(actual_type->id == TypeTableEntryIdErrorUnion);
if (!type_has_bits(actual_type->data.error.child_type)) {
return gen_widen_or_shorten(g, ir_want_debug_safety(g, &cast_instruction->base),
g->err_tag_type, wanted_type, expr_val);
} else {
zig_panic("TODO");
}
case CastOpResizeSlice:
{
assert(cast_instruction->tmp_ptr);
Expand Down Expand Up @@ -1402,6 +1396,66 @@ static LLVMValueRef ir_render_int_to_enum(CodeGen *g, IrExecutable *executable,
instruction->target->value.type, wanted_int_type, target_val);
}

static LLVMValueRef ir_render_int_to_err(CodeGen *g, IrExecutable *executable, IrInstructionIntToErr *instruction) {
TypeTableEntry *wanted_type = instruction->base.value.type;
assert(wanted_type->id == TypeTableEntryIdPureError);

TypeTableEntry *actual_type = instruction->target->value.type;
assert(actual_type->id == TypeTableEntryIdInt);
assert(!actual_type->data.integral.is_signed);

LLVMValueRef target_val = ir_llvm_value(g, instruction->target);

if (ir_want_debug_safety(g, &instruction->base)) {
LLVMValueRef zero = LLVMConstNull(actual_type->type_ref);
LLVMValueRef neq_zero_bit = LLVMBuildICmp(g->builder, LLVMIntNE, target_val, zero, "");
LLVMValueRef ok_bit;
uint64_t biggest_possible_err_val = max_unsigned_val(actual_type);
if (biggest_possible_err_val < g->error_decls.length) {
ok_bit = neq_zero_bit;
} else {
LLVMValueRef error_value_count = LLVMConstInt(actual_type->type_ref, g->error_decls.length, false);
LLVMValueRef in_bounds_bit = LLVMBuildICmp(g->builder, LLVMIntULT, target_val, error_value_count, "");
ok_bit = LLVMBuildAnd(g->builder, neq_zero_bit, in_bounds_bit, "");
}

LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "IntToErrOk");
LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "IntToErrFail");

LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);

LLVMPositionBuilderAtEnd(g->builder, fail_block);
gen_debug_safety_crash(g, PanicMsgIdInvalidErrorCode);

LLVMPositionBuilderAtEnd(g->builder, ok_block);
}

return gen_widen_or_shorten(g, false, actual_type, g->err_tag_type, target_val);
}

static LLVMValueRef ir_render_err_to_int(CodeGen *g, IrExecutable *executable, IrInstructionErrToInt *instruction) {
TypeTableEntry *wanted_type = instruction->base.value.type;
assert(wanted_type->id == TypeTableEntryIdInt);
assert(!wanted_type->data.integral.is_signed);

TypeTableEntry *actual_type = instruction->target->value.type;
LLVMValueRef target_val = ir_llvm_value(g, instruction->target);

if (actual_type->id == TypeTableEntryIdPureError) {
return gen_widen_or_shorten(g, ir_want_debug_safety(g, &instruction->base),
g->err_tag_type, wanted_type, target_val);
} else if (actual_type->id == TypeTableEntryIdErrorUnion) {
if (!type_has_bits(actual_type->data.error.child_type)) {
return gen_widen_or_shorten(g, ir_want_debug_safety(g, &instruction->base),
g->err_tag_type, wanted_type, target_val);
} else {
zig_panic("TODO");
}
} else {
zig_unreachable();
}
}

static LLVMValueRef ir_render_unreachable(CodeGen *g, IrExecutable *executable,
IrInstructionUnreachable *unreachable_instruction)
{
Expand Down Expand Up @@ -2786,6 +2840,10 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
return ir_render_int_to_ptr(g, executable, (IrInstructionIntToPtr *)instruction);
case IrInstructionIdIntToEnum:
return ir_render_int_to_enum(g, executable, (IrInstructionIntToEnum *)instruction);
case IrInstructionIdIntToErr:
return ir_render_int_to_err(g, executable, (IrInstructionIntToErr *)instruction);
case IrInstructionIdErrToInt:
return ir_render_err_to_int(g, executable, (IrInstructionErrToInt *)instruction);
case IrInstructionIdContainerInitList:
return ir_render_container_init_list(g, executable, (IrInstructionContainerInitList *)instruction);
case IrInstructionIdPanic:
Expand Down
Loading

0 comments on commit 8fd0fdd

Please sign in to comment.