Commit dd8c8c0802
Changed files (2)
src/analyze.cpp
@@ -1499,9 +1499,14 @@ bool type_is_invalid(ZigType *type_entry) {
zig_unreachable();
}
+struct SrcField {
+ const char *name;
+ ZigType *ty;
+ unsigned align;
+};
-static ZigType *get_struct_type(CodeGen *g, const char *type_name, const char *field_names[],
- ZigType *field_types[], size_t field_count, unsigned min_abi_align)
+static ZigType *get_struct_type(CodeGen *g, const char *type_name, SrcField fields[], size_t field_count,
+ unsigned min_abi_align)
{
ZigType *struct_type = new_type_table_entry(ZigTypeIdStruct);
@@ -1516,14 +1521,15 @@ static ZigType *get_struct_type(CodeGen *g, const char *type_name, const char *f
size_t abi_align = min_abi_align;
for (size_t i = 0; i < field_count; i += 1) {
TypeStructField *field = &struct_type->data.structure.fields[i];
- field->name = buf_create_from_str(field_names[i]);
- field->type_entry = field_types[i];
+ field->name = buf_create_from_str(fields[i].name);
+ field->type_entry = fields[i].ty;
field->src_index = i;
if (type_has_bits(field->type_entry)) {
assert(type_is_resolved(field->type_entry, ResolveStatusSizeKnown));
- if (field->type_entry->abi_align > abi_align) {
- abi_align = field->type_entry->abi_align;
+ unsigned field_abi_align = max(fields[i].align, field->type_entry->abi_align);
+ if (field_abi_align > abi_align) {
+ abi_align = field_abi_align;
}
}
@@ -1545,8 +1551,13 @@ static ZigType *get_struct_type(CodeGen *g, const char *type_name, const char *f
if (type_has_bits(struct_type->data.structure.fields[next_src_field_index].type_entry))
break;
}
- size_t next_abi_align = (next_src_field_index == field_count) ?
- abi_align : struct_type->data.structure.fields[next_src_field_index].type_entry->abi_align;
+ size_t next_abi_align;
+ if (next_src_field_index == field_count) {
+ next_abi_align = abi_align;
+ } else {
+ next_abi_align = max(fields[next_src_field_index].align,
+ struct_type->data.structure.fields[next_src_field_index].type_entry->abi_align);
+ }
next_offset = next_field_offset(next_offset, abi_align, field->type_entry->abi_size, next_abi_align);
}
@@ -5245,35 +5256,22 @@ static Error resolve_async_frame(CodeGen *g, ZigType *frame_type) {
}
// label (grep this): [fn_frame_struct_layout]
- ZigList<ZigType *> field_types = {};
- ZigList<const char *> field_names = {};
-
- field_names.append("@fn_ptr");
- field_types.append(fn_type);
-
- field_names.append("@resume_index");
- field_types.append(g->builtin_types.entry_usize);
+ ZigList<SrcField> fields = {};
- field_names.append("@awaiter");
- field_types.append(g->builtin_types.entry_usize);
-
- field_names.append("@prev_val");
- field_types.append(g->builtin_types.entry_usize);
+ fields.append({"@fn_ptr", fn_type, 0});
+ fields.append({"@resume_index", g->builtin_types.entry_usize, 0});
+ fields.append({"@awaiter", g->builtin_types.entry_usize, 0});
+ fields.append({"@prev_val", g->builtin_types.entry_usize, 0});
FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id;
ZigType *ptr_return_type = get_pointer_to_type(g, fn_type_id->return_type, false);
- field_names.append("@result_ptr_callee");
- field_types.append(ptr_return_type);
-
- field_names.append("@result_ptr_awaiter");
- field_types.append(ptr_return_type);
- field_names.append("@result");
- field_types.append(fn_type_id->return_type);
+ fields.append({"@result_ptr_callee", ptr_return_type, 0});
+ fields.append({"@result_ptr_awaiter", ptr_return_type, 0});
+ fields.append({"@result", fn_type_id->return_type, 0});
if (codegen_fn_has_err_ret_tracing_arg(g, fn_type_id->return_type)) {
- field_names.append("@ptr_stack_trace");
- field_types.append(get_ptr_to_stack_trace_type(g));
+ fields.append({"@ptr_stack_trace", get_ptr_to_stack_trace_type(g), 0});
}
for (size_t arg_i = 0; arg_i < fn_type_id->param_count; arg_i += 1) {
@@ -5287,18 +5285,16 @@ static Error resolve_async_frame(CodeGen *g, ZigType *frame_type) {
param_name = buf_sprintf("@arg%" ZIG_PRI_usize, arg_i);
}
ZigType *param_type = param_info->type;
- field_names.append(buf_ptr(param_name));
- field_types.append(param_type);
+
+ fields.append({buf_ptr(param_name), param_type, 0});
}
if (codegen_fn_has_err_ret_tracing_stack(g, fn, true)) {
(void)get_ptr_to_stack_trace_type(g); // populate g->stack_trace_type
- field_names.append("@stack_trace");
- field_types.append(g->stack_trace_type);
-
- field_names.append("@instruction_addresses");
- field_types.append(get_array_type(g, g->builtin_types.entry_usize, stack_trace_ptr_count));
+ fields.append({"@stack_trace", g->stack_trace_type, 0});
+ fields.append({"@instruction_addresses",
+ get_array_type(g, g->builtin_types.entry_usize, stack_trace_ptr_count), 0});
}
for (size_t alloca_i = 0; alloca_i < fn->alloca_gen_list.length; alloca_i += 1) {
@@ -5327,15 +5323,14 @@ static Error resolve_async_frame(CodeGen *g, ZigType *frame_type) {
} else {
name = buf_ptr(buf_sprintf("%s.%" ZIG_PRI_usize, instruction->name_hint, alloca_i));
}
- instruction->field_index = field_types.length;
- field_names.append(name);
- field_types.append(child_type);
+ instruction->field_index = fields.length;
+
+ fields.append({name, child_type, 0});
}
- assert(field_names.length == field_types.length);
frame_type->data.frame.locals_struct = get_struct_type(g, buf_ptr(&frame_type->name),
- field_names.items, field_types.items, field_names.length, target_fn_align(g->zig_target));
+ fields.items, fields.length, target_fn_align(g->zig_target));
frame_type->abi_size = frame_type->data.frame.locals_struct->abi_size;
frame_type->abi_align = frame_type->data.frame.locals_struct->abi_align;
frame_type->size_in_bits = frame_type->data.frame.locals_struct->size_in_bits;
BRANCH_TODO
@@ -1,42 +0,0 @@
- * zig fmt support for the syntax
- * alignment of variables not being respected in async functions
- * await of a non async function
- * async call on a non async function
- * documentation
- - @asyncCall
- - @frame
- - @Frame
- - @frameSize
- - coroutines section
- - suspend
- - resume
- - anyframe, anyframe->T
- * a test where an async function destroys its own frame in a defer
- * compile error (instead of crashing) for trying to get @Frame of generic function
- * compile error (instead of crashing) for trying to async call and passing @Frame of wrong function
- * implicit cast of normal function to async function should be allowed when it is inferred to be async
- * compile error for error: expected anyframe->T, found 'anyframe'
- * compile error for error: expected anyframe->T, found 'i32'
- * peer type resolution of *@Frame(func) and anyframe
- * peer type resolution of *@Frame(func) and anyframe->T when the return type matches
- * for loops need to spill the index. other payload captures probably also need to spill
- * `const result = (await a) + (await b);` this causes "Instruction does not dominate all uses" - need spill
- * @typeInfo for @Frame(func)
- * returning a value from within a suspend block
- * make resuming inside a suspend block, with nothing after it, a must-tail call.
- * make sure there are safety tests for all the new safety features (search the new PanicFnId enum values)
- * compile error for casting a function to a non-async function pointer, but then later it gets inferred to be an async function
- * compile error for copying a frame
- * compile error for resuming a const frame pointer
- * runtime safety enabling/disabling scope has to be coordinated across resume/await/calls/return
- * calling a generic function which is async
- * make sure `await @asyncCall` and `await async` are handled correctly.
- * allow @asyncCall with a real @Frame(func) (the point of this is result pointer)
- * when there are multiple calls to async functions in a function, reuse the same frame buffer, so that the
- needed bytes is equal to the largest callee's frame
- * if an async function is never called with async then a few optimizations can be made:
- - the return does not need to be atomic
- - it can be assumed that these are always available: the awaiter ptr, return ptr if applicable,
- error return trace ptr if applicable.
- - it can be assumed that it is never cancelled
- * fix the debug info for variables of async functions