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
This commit is contained in:
Andrew Kelley
2017-04-02 18:19:59 -04:00
parent 0594487a2e
commit 8fd0fddce5
11 changed files with 742 additions and 51 deletions

View File

@@ -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();
}
@@ -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);
@@ -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)
{
@@ -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: