authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-29 12:43:56-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-29 12:43:56-04:00
logd9f0446b1f993c1b3c1bf5cc410b6d5f8a2f94fe
tree78a89e490a0e143e1927770be67d6d4fca01ccdf
parent94bbb46ca602be0ea0df97c207a98734ac459a0f
signature Commit is signed but in an unrecognized format.

make `@sizeOf` lazy


5 files changed, 134 insertions(+), 51 deletions(-)

src/all_types.hpp+8
...@@ -308,6 +308,7 @@ struct ConstGlobalRefs {...@@ -308,6 +308,7 @@ struct ConstGlobalRefs {
308enum LazyValueId {308enum LazyValueId {
309 LazyValueIdInvalid,309 LazyValueIdInvalid,
310 LazyValueIdAlignOf,310 LazyValueIdAlignOf,
311 LazyValueIdSizeOf,
311 LazyValueIdPtrType,312 LazyValueIdPtrType,
312 LazyValueIdOptType,313 LazyValueIdOptType,
313 LazyValueIdSliceType,314 LazyValueIdSliceType,
...@@ -326,6 +327,13 @@ struct LazyValueAlignOf {...@@ -326,6 +327,13 @@ struct LazyValueAlignOf {
326 IrInstruction *target_type;327 IrInstruction *target_type;
327};328};
328329
330struct LazyValueSizeOf {
331 LazyValue base;
332
333 IrAnalyze *ira;
334 IrInstruction *target_type;
335};
336
329struct LazyValueSliceType {337struct LazyValueSliceType {
330 LazyValue base;338 LazyValue base;
331339
src/analyze.cpp+53-6
...@@ -997,6 +997,7 @@ static Error type_val_resolve_zero_bits(CodeGen *g, ConstExprValue *type_val, Zi...@@ -997,6 +997,7 @@ static Error type_val_resolve_zero_bits(CodeGen *g, ConstExprValue *type_val, Zi
997 switch (type_val->data.x_lazy->id) {997 switch (type_val->data.x_lazy->id) {
998 case LazyValueIdInvalid:998 case LazyValueIdInvalid:
999 case LazyValueIdAlignOf:999 case LazyValueIdAlignOf:
1000 case LazyValueIdSizeOf:
1000 zig_unreachable();1001 zig_unreachable();
1001 case LazyValueIdPtrType: {1002 case LazyValueIdPtrType: {
1002 LazyValuePtrType *lazy_ptr_type = reinterpret_cast<LazyValuePtrType *>(type_val->data.x_lazy);1003 LazyValuePtrType *lazy_ptr_type = reinterpret_cast<LazyValuePtrType *>(type_val->data.x_lazy);
...@@ -1036,6 +1037,7 @@ Error type_val_resolve_is_opaque_type(CodeGen *g, ConstExprValue *type_val, bool...@@ -1036,6 +1037,7 @@ Error type_val_resolve_is_opaque_type(CodeGen *g, ConstExprValue *type_val, bool
1036 switch (type_val->data.x_lazy->id) {1037 switch (type_val->data.x_lazy->id) {
1037 case LazyValueIdInvalid:1038 case LazyValueIdInvalid:
1038 case LazyValueIdAlignOf:1039 case LazyValueIdAlignOf:
1040 case LazyValueIdSizeOf:
1039 zig_unreachable();1041 zig_unreachable();
1040 case LazyValueIdSliceType:1042 case LazyValueIdSliceType:
1041 case LazyValueIdPtrType:1043 case LazyValueIdPtrType:
...@@ -1055,6 +1057,7 @@ static ReqCompTime type_val_resolve_requires_comptime(CodeGen *g, ConstExprValue...@@ -1055,6 +1057,7 @@ static ReqCompTime type_val_resolve_requires_comptime(CodeGen *g, ConstExprValue
1055 switch (type_val->data.x_lazy->id) {1057 switch (type_val->data.x_lazy->id) {
1056 case LazyValueIdInvalid:1058 case LazyValueIdInvalid:
1057 case LazyValueIdAlignOf:1059 case LazyValueIdAlignOf:
1060 case LazyValueIdSizeOf:
1058 zig_unreachable();1061 zig_unreachable();
1059 case LazyValueIdSliceType: {1062 case LazyValueIdSliceType: {
1060 LazyValueSliceType *lazy_slice_type = reinterpret_cast<LazyValueSliceType *>(type_val->data.x_lazy);1063 LazyValueSliceType *lazy_slice_type = reinterpret_cast<LazyValueSliceType *>(type_val->data.x_lazy);
...@@ -1105,7 +1108,7 @@ static ReqCompTime type_val_resolve_requires_comptime(CodeGen *g, ConstExprValue...@@ -1105,7 +1108,7 @@ static ReqCompTime type_val_resolve_requires_comptime(CodeGen *g, ConstExprValue
1105 zig_unreachable();1108 zig_unreachable();
1106}1109}
11071110
1108static Error type_val_resolve_abi_size(CodeGen *g, AstNode *source_node, ConstExprValue *type_val,1111Error type_val_resolve_abi_size(CodeGen *g, AstNode *source_node, ConstExprValue *type_val,
1109 size_t *abi_size, size_t *size_in_bits)1112 size_t *abi_size, size_t *size_in_bits)
1110{1113{
1111 Error err;1114 Error err;
...@@ -1123,12 +1126,42 @@ start_over:...@@ -1123,12 +1126,42 @@ start_over:
1123 switch (type_val->data.x_lazy->id) {1126 switch (type_val->data.x_lazy->id) {
1124 case LazyValueIdInvalid:1127 case LazyValueIdInvalid:
1125 case LazyValueIdAlignOf:1128 case LazyValueIdAlignOf:
1129 case LazyValueIdSizeOf:
1126 zig_unreachable();1130 zig_unreachable();
1127 case LazyValueIdSliceType:1131 case LazyValueIdSliceType: {
1128 *abi_size = g->builtin_types.entry_usize->abi_size * 2;1132 LazyValueSliceType *lazy_slice_type = reinterpret_cast<LazyValueSliceType *>(type_val->data.x_lazy);
1129 *size_in_bits = g->builtin_types.entry_usize->size_in_bits * 2;1133 bool is_zero_bits;
1134 if ((err = type_val_resolve_zero_bits(g, &lazy_slice_type->elem_type->value, nullptr,
1135 nullptr, &is_zero_bits)))
1136 {
1137 return err;
1138 }
1139 if (is_zero_bits) {
1140 *abi_size = g->builtin_types.entry_usize->abi_size;
1141 *size_in_bits = g->builtin_types.entry_usize->size_in_bits;
1142 } else {
1143 *abi_size = g->builtin_types.entry_usize->abi_size * 2;
1144 *size_in_bits = g->builtin_types.entry_usize->size_in_bits * 2;
1145 }
1130 return ErrorNone;1146 return ErrorNone;
1131 case LazyValueIdPtrType:1147 }
1148 case LazyValueIdPtrType: {
1149 LazyValuePtrType *lazy_ptr_type = reinterpret_cast<LazyValuePtrType *>(type_val->data.x_lazy);
1150 bool is_zero_bits;
1151 if ((err = type_val_resolve_zero_bits(g, &lazy_ptr_type->elem_type->value, nullptr,
1152 nullptr, &is_zero_bits)))
1153 {
1154 return err;
1155 }
1156 if (is_zero_bits) {
1157 *abi_size = 0;
1158 *size_in_bits = 0;
1159 } else {
1160 *abi_size = g->builtin_types.entry_usize->abi_size;
1161 *size_in_bits = g->builtin_types.entry_usize->size_in_bits;
1162 }
1163 return ErrorNone;
1164 }
1132 case LazyValueIdFnType:1165 case LazyValueIdFnType:
1133 *abi_size = g->builtin_types.entry_usize->abi_size;1166 *abi_size = g->builtin_types.entry_usize->abi_size;
1134 *size_in_bits = g->builtin_types.entry_usize->size_in_bits;1167 *size_in_bits = g->builtin_types.entry_usize->size_in_bits;
...@@ -1159,6 +1192,7 @@ Error type_val_resolve_abi_align(CodeGen *g, ConstExprValue *type_val, uint32_t...@@ -1159,6 +1192,7 @@ Error type_val_resolve_abi_align(CodeGen *g, ConstExprValue *type_val, uint32_t
1159 switch (type_val->data.x_lazy->id) {1192 switch (type_val->data.x_lazy->id) {
1160 case LazyValueIdInvalid:1193 case LazyValueIdInvalid:
1161 case LazyValueIdAlignOf:1194 case LazyValueIdAlignOf:
1195 case LazyValueIdSizeOf:
1162 zig_unreachable();1196 zig_unreachable();
1163 case LazyValueIdSliceType:1197 case LazyValueIdSliceType:
1164 case LazyValueIdPtrType:1198 case LazyValueIdPtrType:
...@@ -1193,6 +1227,7 @@ static OnePossibleValue type_val_resolve_has_one_possible_value(CodeGen *g, Cons...@@ -1193,6 +1227,7 @@ static OnePossibleValue type_val_resolve_has_one_possible_value(CodeGen *g, Cons
1193 switch (type_val->data.x_lazy->id) {1227 switch (type_val->data.x_lazy->id) {
1194 case LazyValueIdInvalid:1228 case LazyValueIdInvalid:
1195 case LazyValueIdAlignOf:1229 case LazyValueIdAlignOf:
1230 case LazyValueIdSizeOf:
1196 zig_unreachable();1231 zig_unreachable();
1197 case LazyValueIdSliceType: // it has the len field1232 case LazyValueIdSliceType: // it has the len field
1198 case LazyValueIdOptType: // it has the optional bit1233 case LazyValueIdOptType: // it has the optional bit
...@@ -4202,7 +4237,12 @@ static void analyze_fn_async(CodeGen *g, ZigFn *fn, bool resolve_frame) {...@@ -4202,7 +4237,12 @@ static void analyze_fn_async(CodeGen *g, ZigFn *fn, bool resolve_frame) {
4202 return;4237 return;
4203 }4238 }
4204 }4239 }
4205 assert(callee->anal_state == FnAnalStateComplete);4240 if (callee->anal_state != FnAnalStateComplete) {
4241 add_node_error(g, call->base.source_node,
4242 buf_sprintf("call to function '%s' depends on itself", buf_ptr(&callee->symbol_name)));
4243 fn->anal_state = FnAnalStateInvalid;
4244 return;
4245 }
4206 analyze_fn_async(g, callee, true);4246 analyze_fn_async(g, callee, true);
4207 if (callee->anal_state == FnAnalStateInvalid) {4247 if (callee->anal_state == FnAnalStateInvalid) {
4208 fn->anal_state = FnAnalStateInvalid;4248 fn->anal_state = FnAnalStateInvalid;
...@@ -4480,6 +4520,8 @@ void semantic_analyze(CodeGen *g) {...@@ -4480,6 +4520,8 @@ void semantic_analyze(CodeGen *g) {
4480 ZigFn *fn = g->fn_defs.at(g->fn_defs_index);4520 ZigFn *fn = g->fn_defs.at(g->fn_defs_index);
4481 g->trace_err = nullptr;4521 g->trace_err = nullptr;
4482 analyze_fn_async(g, fn, true);4522 analyze_fn_async(g, fn, true);
4523 if (fn->anal_state == FnAnalStateInvalid)
4524 continue;
4483 if (fn_is_async(fn) && fn->non_async_node != nullptr) {4525 if (fn_is_async(fn) && fn->non_async_node != nullptr) {
4484 ErrorMsg *msg = add_node_error(g, fn->proto_node,4526 ErrorMsg *msg = add_node_error(g, fn->proto_node,
4485 buf_sprintf("'%s' cannot be async", buf_ptr(&fn->symbol_name)));4527 buf_sprintf("'%s' cannot be async", buf_ptr(&fn->symbol_name)));
...@@ -5632,6 +5674,11 @@ static Error resolve_async_frame(CodeGen *g, ZigType *frame_type) {...@@ -5632,6 +5674,11 @@ static Error resolve_async_frame(CodeGen *g, ZigType *frame_type) {
5632 return ErrorSemanticAnalyzeFail;5674 return ErrorSemanticAnalyzeFail;
5633 }5675 }
5634 analyze_fn_async(g, callee, true);5676 analyze_fn_async(g, callee, true);
5677 if (callee->inferred_async_node == inferred_async_checking) {
5678 assert(g->errors.length != 0);
5679 frame_type->data.frame.locals_struct = g->builtin_types.entry_invalid;
5680 return ErrorSemanticAnalyzeFail;
5681 }
5635 if (!fn_is_async(callee))5682 if (!fn_is_async(callee))
5636 continue;5683 continue;
56375684
src/analyze.hpp+2
...@@ -247,6 +247,8 @@ void resolve_llvm_types_fn(CodeGen *g, ZigFn *fn);...@@ -247,6 +247,8 @@ void resolve_llvm_types_fn(CodeGen *g, ZigFn *fn);
247bool fn_is_async(ZigFn *fn);247bool fn_is_async(ZigFn *fn);
248248
249Error type_val_resolve_abi_align(CodeGen *g, ConstExprValue *type_val, uint32_t *abi_align);249Error type_val_resolve_abi_align(CodeGen *g, ConstExprValue *type_val, uint32_t *abi_align);
250Error type_val_resolve_abi_size(CodeGen *g, AstNode *source_node, ConstExprValue *type_val,
251 size_t *abi_size, size_t *size_in_bits);
250ZigType *resolve_union_field_type(CodeGen *g, TypeUnionField *union_field);252ZigType *resolve_union_field_type(CodeGen *g, TypeUnionField *union_field);
251ZigType *resolve_struct_field_type(CodeGen *g, TypeStructField *struct_field);253ZigType *resolve_struct_field_type(CodeGen *g, TypeStructField *struct_field);
252254
src/codegen.cpp+5
...@@ -6845,6 +6845,7 @@ static void set_global_tls(CodeGen *g, ZigVar *var, LLVMValueRef global_value) {...@@ -6845,6 +6845,7 @@ static void set_global_tls(CodeGen *g, ZigVar *var, LLVMValueRef global_value) {
6845}6845}
68466846
6847static void do_code_gen(CodeGen *g) {6847static void do_code_gen(CodeGen *g) {
6848 Error err;
6848 assert(!g->errors.length);6849 assert(!g->errors.length);
68496850
6850 generate_error_name_table(g);6851 generate_error_name_table(g);
...@@ -6858,6 +6859,8 @@ static void do_code_gen(CodeGen *g) {...@@ -6858,6 +6859,8 @@ static void do_code_gen(CodeGen *g) {
6858 // Generate debug info for it but that's it.6859 // Generate debug info for it but that's it.
6859 ConstExprValue *const_val = var->const_value;6860 ConstExprValue *const_val = var->const_value;
6860 assert(const_val->special != ConstValSpecialRuntime);6861 assert(const_val->special != ConstValSpecialRuntime);
6862 if ((err = ir_resolve_lazy(g, var->decl_node, const_val)))
6863 zig_unreachable();
6861 if (const_val->type != var->var_type) {6864 if (const_val->type != var->var_type) {
6862 zig_panic("TODO debug info for var with ptr casted value");6865 zig_panic("TODO debug info for var with ptr casted value");
6863 }6866 }
...@@ -6875,6 +6878,8 @@ static void do_code_gen(CodeGen *g) {...@@ -6875,6 +6878,8 @@ static void do_code_gen(CodeGen *g) {
6875 // Generate debug info for it but that's it.6878 // Generate debug info for it but that's it.
6876 ConstExprValue *const_val = var->const_value;6879 ConstExprValue *const_val = var->const_value;
6877 assert(const_val->special != ConstValSpecialRuntime);6880 assert(const_val->special != ConstValSpecialRuntime);
6881 if ((err = ir_resolve_lazy(g, var->decl_node, const_val)))
6882 zig_unreachable();
6878 if (const_val->type != var->var_type) {6883 if (const_val->type != var->var_type) {
6879 zig_panic("TODO debug info for var with ptr casted value");6884 zig_panic("TODO debug info for var with ptr casted value");
6880 }6885 }
src/ir.cpp+66-45
...@@ -18066,54 +18066,20 @@ static IrInstruction *ir_analyze_instruction_array_type(IrAnalyze *ira,...@@ -18066,54 +18066,20 @@ static IrInstruction *ir_analyze_instruction_array_type(IrAnalyze *ira,
18066 zig_unreachable();18066 zig_unreachable();
18067}18067}
1806818068
18069static IrInstruction *ir_analyze_instruction_size_of(IrAnalyze *ira,18069static IrInstruction *ir_analyze_instruction_size_of(IrAnalyze *ira, IrInstructionSizeOf *instruction) {
18070 IrInstructionSizeOf *size_of_instruction)18070 IrInstruction *result = ir_const(ira, &instruction->base, ira->codegen->builtin_types.entry_num_lit_int);
18071{18071 result->value.special = ConstValSpecialLazy;
18072 Error err;
18073 IrInstruction *type_value = size_of_instruction->type_value->child;
18074 ZigType *type_entry = ir_resolve_type(ira, type_value);
1807518072
18076 if ((err = type_resolve(ira->codegen, type_entry, ResolveStatusSizeKnown)))18073 LazyValueSizeOf *lazy_size_of = allocate<LazyValueSizeOf>(1);
18074 lazy_size_of->ira = ira;
18075 result->value.data.x_lazy = &lazy_size_of->base;
18076 lazy_size_of->base.id = LazyValueIdSizeOf;
18077
18078 lazy_size_of->target_type = instruction->type_value->child;
18079 if (ir_resolve_type_lazy(ira, lazy_size_of->target_type) == nullptr)
18077 return ira->codegen->invalid_instruction;18080 return ira->codegen->invalid_instruction;
1807818081
18079 switch (type_entry->id) {18082 return result;
18080 case ZigTypeIdInvalid: // handled above
18081 zig_unreachable();
18082 case ZigTypeIdUnreachable:
18083 case ZigTypeIdUndefined:
18084 case ZigTypeIdNull:
18085 case ZigTypeIdBoundFn:
18086 case ZigTypeIdArgTuple:
18087 case ZigTypeIdOpaque:
18088 ir_add_error_node(ira, type_value->source_node,
18089 buf_sprintf("no size available for type '%s'", buf_ptr(&type_entry->name)));
18090 return ira->codegen->invalid_instruction;
18091 case ZigTypeIdMetaType:
18092 case ZigTypeIdEnumLiteral:
18093 case ZigTypeIdComptimeFloat:
18094 case ZigTypeIdComptimeInt:
18095 case ZigTypeIdVoid:
18096 case ZigTypeIdBool:
18097 case ZigTypeIdInt:
18098 case ZigTypeIdFloat:
18099 case ZigTypeIdPointer:
18100 case ZigTypeIdArray:
18101 case ZigTypeIdStruct:
18102 case ZigTypeIdOptional:
18103 case ZigTypeIdErrorUnion:
18104 case ZigTypeIdErrorSet:
18105 case ZigTypeIdEnum:
18106 case ZigTypeIdUnion:
18107 case ZigTypeIdFn:
18108 case ZigTypeIdVector:
18109 case ZigTypeIdFnFrame:
18110 case ZigTypeIdAnyFrame:
18111 {
18112 uint64_t size_in_bytes = type_size(ira->codegen, type_entry);
18113 return ir_const_unsigned(ira, &size_of_instruction->base, size_in_bytes);
18114 }
18115 }
18116 zig_unreachable();
18117}18083}
1811818084
18119static IrInstruction *ir_analyze_test_non_null(IrAnalyze *ira, IrInstruction *source_inst, IrInstruction *value) {18085static IrInstruction *ir_analyze_test_non_null(IrAnalyze *ira, IrInstruction *source_inst, IrInstruction *value) {
...@@ -25548,6 +25514,61 @@ static Error ir_resolve_lazy_raw(AstNode *source_node, ConstExprValue *val) {...@@ -25548,6 +25514,61 @@ static Error ir_resolve_lazy_raw(AstNode *source_node, ConstExprValue *val) {
25548 bigint_init_unsigned(&val->data.x_bigint, align_in_bytes);25514 bigint_init_unsigned(&val->data.x_bigint, align_in_bytes);
25549 return ErrorNone;25515 return ErrorNone;
25550 }25516 }
25517 case LazyValueIdSizeOf: {
25518 LazyValueSizeOf *lazy_size_of = reinterpret_cast<LazyValueSizeOf *>(val->data.x_lazy);
25519 IrAnalyze *ira = lazy_size_of->ira;
25520
25521 if (lazy_size_of->target_type->value.special == ConstValSpecialStatic) {
25522 switch (lazy_size_of->target_type->value.data.x_type->id) {
25523 case ZigTypeIdInvalid: // handled above
25524 zig_unreachable();
25525 case ZigTypeIdUnreachable:
25526 case ZigTypeIdUndefined:
25527 case ZigTypeIdNull:
25528 case ZigTypeIdBoundFn:
25529 case ZigTypeIdArgTuple:
25530 case ZigTypeIdOpaque:
25531 ir_add_error(ira, lazy_size_of->target_type,
25532 buf_sprintf("no size available for type '%s'",
25533 buf_ptr(&lazy_size_of->target_type->value.data.x_type->name)));
25534 return ErrorSemanticAnalyzeFail;
25535 case ZigTypeIdMetaType:
25536 case ZigTypeIdEnumLiteral:
25537 case ZigTypeIdComptimeFloat:
25538 case ZigTypeIdComptimeInt:
25539 case ZigTypeIdVoid:
25540 case ZigTypeIdBool:
25541 case ZigTypeIdInt:
25542 case ZigTypeIdFloat:
25543 case ZigTypeIdPointer:
25544 case ZigTypeIdArray:
25545 case ZigTypeIdStruct:
25546 case ZigTypeIdOptional:
25547 case ZigTypeIdErrorUnion:
25548 case ZigTypeIdErrorSet:
25549 case ZigTypeIdEnum:
25550 case ZigTypeIdUnion:
25551 case ZigTypeIdFn:
25552 case ZigTypeIdVector:
25553 case ZigTypeIdFnFrame:
25554 case ZigTypeIdAnyFrame:
25555 break;
25556 }
25557 }
25558
25559 uint64_t abi_size;
25560 uint64_t size_in_bits;
25561 if ((err = type_val_resolve_abi_size(ira->codegen, source_node, &lazy_size_of->target_type->value,
25562 &abi_size, &size_in_bits)))
25563 {
25564 return err;
25565 }
25566
25567 val->special = ConstValSpecialStatic;
25568 assert(val->type->id == ZigTypeIdComptimeInt);
25569 bigint_init_unsigned(&val->data.x_bigint, abi_size);
25570 return ErrorNone;
25571 }
25551 case LazyValueIdSliceType: {25572 case LazyValueIdSliceType: {
25552 LazyValueSliceType *lazy_slice_type = reinterpret_cast<LazyValueSliceType *>(val->data.x_lazy);25573 LazyValueSliceType *lazy_slice_type = reinterpret_cast<LazyValueSliceType *>(val->data.x_lazy);
25553 IrAnalyze *ira = lazy_slice_type->ira;25574 IrAnalyze *ira = lazy_slice_type->ira;