diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2019-02-21 10:07:11 -0500 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2019-02-21 10:07:11 -0500 |
| commit | 2bb795dc455823e76ef3e0c9b3fcee6bcb15fddb (patch) | |
| tree | 995e0a82e2d47d0b6701716372808ae7a40a406f /src/ir.cpp | |
| parent | db31c2524df4352593128aaceaa0b085ef8bb674 (diff) | |
| download | zig-2bb795dc455823e76ef3e0c9b3fcee6bcb15fddb.tar.gz zig-2bb795dc455823e76ef3e0c9b3fcee6bcb15fddb.zip | |
`@sliceToBytes` works at comptime
closes #262
Diffstat (limited to 'src/ir.cpp')
| -rw-r--r-- | src/ir.cpp | 59 |
1 files changed, 51 insertions, 8 deletions
diff --git a/src/ir.cpp b/src/ir.cpp index 03555c78f4..a385592e2d 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -456,6 +456,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionCast *) { return IrInstructionIdCast; } +static constexpr IrInstructionId ir_instruction_id(IrInstructionResizeSlice *) { + return IrInstructionIdResizeSlice; +} + static constexpr IrInstructionId ir_instruction_id(IrInstructionContainerInitList *) { return IrInstructionIdContainerInitList; } @@ -1475,6 +1479,19 @@ static IrInstruction *ir_build_var_decl_gen(IrAnalyze *ira, IrInstruction *sourc return &decl_var_instruction->base; } +static IrInstruction *ir_build_resize_slice(IrAnalyze *ira, IrInstruction *source_instruction, + IrInstruction *operand, ZigType *ty) +{ + IrInstructionResizeSlice *instruction = ir_build_instruction<IrInstructionResizeSlice>(&ira->new_irb, + source_instruction->scope, source_instruction->source_node); + instruction->base.value.type = ty; + instruction->operand = operand; + + ir_ref_instruction(operand, ira->new_irb.current_basic_block); + + return &instruction->base; +} + static IrInstruction *ir_build_export(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *name, IrInstruction *target, IrInstruction *linkage) { @@ -9674,9 +9691,6 @@ static bool eval_const_expr_implicit_cast(IrAnalyze *ira, IrInstruction *source_ } const_val->type = new_type; break; - case CastOpResizeSlice: - // can't do it - zig_unreachable(); case CastOpIntToFloat: { assert(new_type->id == ZigTypeIdFloat); @@ -9740,9 +9754,7 @@ static IrInstruction *ir_const(IrAnalyze *ira, IrInstruction *old_instruction, Z static IrInstruction *ir_resolve_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, ZigType *wanted_type, CastOp cast_op, bool need_alloca) { - if ((instr_is_comptime(value) || !type_has_bits(wanted_type)) && - cast_op != CastOpResizeSlice) - { + if (instr_is_comptime(value) || !type_has_bits(wanted_type)) { IrInstruction *result = ir_const(ira, source_instr, wanted_type); if (!eval_const_expr_implicit_cast(ira, source_instr, cast_op, &value->value, value->value.type, &result->value, wanted_type)) @@ -19082,7 +19094,9 @@ static IrInstruction *ir_analyze_instruction_from_bytes(IrAnalyze *ira, IrInstru } } - return ir_resolve_cast(ira, &instruction->base, casted_value, dest_slice_type, CastOpResizeSlice, true); + IrInstruction *result = ir_build_resize_slice(ira, &instruction->base, casted_value, dest_slice_type); + ir_add_alloca(ira, result, dest_slice_type); + return result; } static IrInstruction *ir_analyze_instruction_to_bytes(IrAnalyze *ira, IrInstructionToBytes *instruction) { @@ -19109,7 +19123,34 @@ static IrInstruction *ir_analyze_instruction_to_bytes(IrAnalyze *ira, IrInstruct alignment, 0, 0); ZigType *dest_slice_type = get_slice_type(ira->codegen, dest_ptr_type); - return ir_resolve_cast(ira, &instruction->base, target, dest_slice_type, CastOpResizeSlice, true); + if (instr_is_comptime(target)) { + ConstExprValue *target_val = ir_resolve_const(ira, target, UndefBad); + if (target_val == nullptr) + return ira->codegen->invalid_instruction; + + IrInstruction *result = ir_const(ira, &instruction->base, dest_slice_type); + result->value.data.x_struct.fields = create_const_vals(2); + + ConstExprValue *ptr_val = &result->value.data.x_struct.fields[slice_ptr_index]; + ConstExprValue *target_ptr_val = &target_val->data.x_struct.fields[slice_ptr_index]; + copy_const_val(ptr_val, target_ptr_val, false); + ptr_val->type = dest_ptr_type; + + ConstExprValue *len_val = &result->value.data.x_struct.fields[slice_len_index]; + len_val->special = ConstValSpecialStatic; + len_val->type = ira->codegen->builtin_types.entry_usize; + ConstExprValue *target_len_val = &target_val->data.x_struct.fields[slice_len_index]; + ZigType *elem_type = src_ptr_type->data.pointer.child_type; + BigInt elem_size_bigint; + bigint_init_unsigned(&elem_size_bigint, type_size(ira->codegen, elem_type)); + bigint_mul(&len_val->data.x_bigint, &target_len_val->data.x_bigint, &elem_size_bigint); + + return result; + } + + IrInstruction *result = ir_build_resize_slice(ira, &instruction->base, target, dest_slice_type); + ir_add_alloca(ira, result, dest_slice_type); + return result; } static Error resolve_ptr_align(IrAnalyze *ira, ZigType *ty, uint32_t *result_align) { @@ -22274,6 +22315,7 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio case IrInstructionIdArrayToVector: case IrInstructionIdVectorToArray: case IrInstructionIdAssertZero: + case IrInstructionIdResizeSlice: zig_unreachable(); case IrInstructionIdReturn: @@ -22673,6 +22715,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { case IrInstructionIdCmpxchgGen: case IrInstructionIdCmpxchgSrc: case IrInstructionIdAssertZero: + case IrInstructionIdResizeSlice: return true; case IrInstructionIdPhi: |
