aboutsummaryrefslogtreecommitdiff
path: root/src/ir.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2019-02-21 10:07:11 -0500
committerAndrew Kelley <andrew@ziglang.org>2019-02-21 10:07:11 -0500
commit2bb795dc455823e76ef3e0c9b3fcee6bcb15fddb (patch)
tree995e0a82e2d47d0b6701716372808ae7a40a406f /src/ir.cpp
parentdb31c2524df4352593128aaceaa0b085ef8bb674 (diff)
downloadzig-2bb795dc455823e76ef3e0c9b3fcee6bcb15fddb.tar.gz
zig-2bb795dc455823e76ef3e0c9b3fcee6bcb15fddb.zip
`@sliceToBytes` works at comptime
closes #262
Diffstat (limited to 'src/ir.cpp')
-rw-r--r--src/ir.cpp59
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: