authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-13 18:14:38-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-13 18:14:38-04:00
logdd8c8c080229c1f0e742fb8702687f4080d7714d
tree3d306f07769d4f275a76f23f11600560b3a1f64e
parent50926341036c3ba377215d1c70c3e97adb07a292
signaturelock-open Commit is signed but in an unrecognized format.

get_struct_type accepts field alignment overrides


2 files changed, 37 insertions(+), 84 deletions(-)

BRANCH_TODO deleted-42
......@@ -1,42 +0,0 @@
1 * zig fmt support for the syntax
2 * alignment of variables not being respected in async functions
3 * await of a non async function
4 * async call on a non async function
5 * documentation
6 - @asyncCall
7 - @frame
8 - @Frame
9 - @frameSize
10 - coroutines section
11 - suspend
12 - resume
13 - anyframe, anyframe->T
14 * a test where an async function destroys its own frame in a defer
15 * compile error (instead of crashing) for trying to get @Frame of generic function
16 * compile error (instead of crashing) for trying to async call and passing @Frame of wrong function
17 * implicit cast of normal function to async function should be allowed when it is inferred to be async
18 * compile error for error: expected anyframe->T, found 'anyframe'
19 * compile error for error: expected anyframe->T, found 'i32'
20 * peer type resolution of *@Frame(func) and anyframe
21 * peer type resolution of *@Frame(func) and anyframe->T when the return type matches
22 * for loops need to spill the index. other payload captures probably also need to spill
23 * `const result = (await a) + (await b);` this causes "Instruction does not dominate all uses" - need spill
24 * @typeInfo for @Frame(func)
25 * returning a value from within a suspend block
26 * make resuming inside a suspend block, with nothing after it, a must-tail call.
27 * make sure there are safety tests for all the new safety features (search the new PanicFnId enum values)
28 * compile error for casting a function to a non-async function pointer, but then later it gets inferred to be an async function
29 * compile error for copying a frame
30 * compile error for resuming a const frame pointer
31 * runtime safety enabling/disabling scope has to be coordinated across resume/await/calls/return
32 * calling a generic function which is async
33 * make sure `await @asyncCall` and `await async` are handled correctly.
34 * allow @asyncCall with a real @Frame(func) (the point of this is result pointer)
35 * when there are multiple calls to async functions in a function, reuse the same frame buffer, so that the
36 needed bytes is equal to the largest callee's frame
37 * if an async function is never called with async then a few optimizations can be made:
38 - the return does not need to be atomic
39 - it can be assumed that these are always available: the awaiter ptr, return ptr if applicable,
40 error return trace ptr if applicable.
41 - it can be assumed that it is never cancelled
42 * fix the debug info for variables of async functions
src/analyze.cpp+37-42
......@@ -1499,9 +1499,14 @@ bool type_is_invalid(ZigType *type_entry) {
14991499 zig_unreachable();
15001500}
15011501
1502struct SrcField {
1503 const char *name;
1504 ZigType *ty;
1505 unsigned align;
1506};
15021507
1503static ZigType *get_struct_type(CodeGen *g, const char *type_name, const char *field_names[],
1504 ZigType *field_types[], size_t field_count, unsigned min_abi_align)
1508static ZigType *get_struct_type(CodeGen *g, const char *type_name, SrcField fields[], size_t field_count,
1509 unsigned min_abi_align)
15051510{
15061511 ZigType *struct_type = new_type_table_entry(ZigTypeIdStruct);
15071512
......@@ -1516,14 +1521,15 @@ static ZigType *get_struct_type(CodeGen *g, const char *type_name, const char *f
15161521 size_t abi_align = min_abi_align;
15171522 for (size_t i = 0; i < field_count; i += 1) {
15181523 TypeStructField *field = &struct_type->data.structure.fields[i];
1519 field->name = buf_create_from_str(field_names[i]);
1520 field->type_entry = field_types[i];
1524 field->name = buf_create_from_str(fields[i].name);
1525 field->type_entry = fields[i].ty;
15211526 field->src_index = i;
15221527
15231528 if (type_has_bits(field->type_entry)) {
15241529 assert(type_is_resolved(field->type_entry, ResolveStatusSizeKnown));
1525 if (field->type_entry->abi_align > abi_align) {
1526 abi_align = field->type_entry->abi_align;
1530 unsigned field_abi_align = max(fields[i].align, field->type_entry->abi_align);
1531 if (field_abi_align > abi_align) {
1532 abi_align = field_abi_align;
15271533 }
15281534 }
15291535
......@@ -1545,8 +1551,13 @@ static ZigType *get_struct_type(CodeGen *g, const char *type_name, const char *f
15451551 if (type_has_bits(struct_type->data.structure.fields[next_src_field_index].type_entry))
15461552 break;
15471553 }
1548 size_t next_abi_align = (next_src_field_index == field_count) ?
1549 abi_align : struct_type->data.structure.fields[next_src_field_index].type_entry->abi_align;
1554 size_t next_abi_align;
1555 if (next_src_field_index == field_count) {
1556 next_abi_align = abi_align;
1557 } else {
1558 next_abi_align = max(fields[next_src_field_index].align,
1559 struct_type->data.structure.fields[next_src_field_index].type_entry->abi_align);
1560 }
15501561 next_offset = next_field_offset(next_offset, abi_align, field->type_entry->abi_size, next_abi_align);
15511562 }
15521563
......@@ -5245,35 +5256,22 @@ static Error resolve_async_frame(CodeGen *g, ZigType *frame_type) {
52455256 }
52465257
52475258 // label (grep this): [fn_frame_struct_layout]
5248 ZigList<ZigType *> field_types = {};
5249 ZigList<const char *> field_names = {};
5250
5251 field_names.append("@fn_ptr");
5252 field_types.append(fn_type);
5253
5254 field_names.append("@resume_index");
5255 field_types.append(g->builtin_types.entry_usize);
5259 ZigList<SrcField> fields = {};
52565260
5257 field_names.append("@awaiter");
5258 field_types.append(g->builtin_types.entry_usize);
5259
5260 field_names.append("@prev_val");
5261 field_types.append(g->builtin_types.entry_usize);
5261 fields.append({"@fn_ptr", fn_type, 0});
5262 fields.append({"@resume_index", g->builtin_types.entry_usize, 0});
5263 fields.append({"@awaiter", g->builtin_types.entry_usize, 0});
5264 fields.append({"@prev_val", g->builtin_types.entry_usize, 0});
52625265
52635266 FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id;
52645267 ZigType *ptr_return_type = get_pointer_to_type(g, fn_type_id->return_type, false);
5265 field_names.append("@result_ptr_callee");
5266 field_types.append(ptr_return_type);
5267
5268 field_names.append("@result_ptr_awaiter");
5269 field_types.append(ptr_return_type);
52705268
5271 field_names.append("@result");
5272 field_types.append(fn_type_id->return_type);
5269 fields.append({"@result_ptr_callee", ptr_return_type, 0});
5270 fields.append({"@result_ptr_awaiter", ptr_return_type, 0});
5271 fields.append({"@result", fn_type_id->return_type, 0});
52735272
52745273 if (codegen_fn_has_err_ret_tracing_arg(g, fn_type_id->return_type)) {
5275 field_names.append("@ptr_stack_trace");
5276 field_types.append(get_ptr_to_stack_trace_type(g));
5274 fields.append({"@ptr_stack_trace", get_ptr_to_stack_trace_type(g), 0});
52775275 }
52785276
52795277 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) {
52875285 param_name = buf_sprintf("@arg%" ZIG_PRI_usize, arg_i);
52885286 }
52895287 ZigType *param_type = param_info->type;
5290 field_names.append(buf_ptr(param_name));
5291 field_types.append(param_type);
5288
5289 fields.append({buf_ptr(param_name), param_type, 0});
52925290 }
52935291
52945292 if (codegen_fn_has_err_ret_tracing_stack(g, fn, true)) {
52955293 (void)get_ptr_to_stack_trace_type(g); // populate g->stack_trace_type
52965294
5297 field_names.append("@stack_trace");
5298 field_types.append(g->stack_trace_type);
5299
5300 field_names.append("@instruction_addresses");
5301 field_types.append(get_array_type(g, g->builtin_types.entry_usize, stack_trace_ptr_count));
5295 fields.append({"@stack_trace", g->stack_trace_type, 0});
5296 fields.append({"@instruction_addresses",
5297 get_array_type(g, g->builtin_types.entry_usize, stack_trace_ptr_count), 0});
53025298 }
53035299
53045300 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) {
53275323 } else {
53285324 name = buf_ptr(buf_sprintf("%s.%" ZIG_PRI_usize, instruction->name_hint, alloca_i));
53295325 }
5330 instruction->field_index = field_types.length;
5331 field_names.append(name);
5332 field_types.append(child_type);
5326 instruction->field_index = fields.length;
5327
5328 fields.append({name, child_type, 0});
53335329 }
53345330
53355331
5336 assert(field_names.length == field_types.length);
53375332 frame_type->data.frame.locals_struct = get_struct_type(g, buf_ptr(&frame_type->name),
5338 field_names.items, field_types.items, field_names.length, target_fn_align(g->zig_target));
5333 fields.items, fields.length, target_fn_align(g->zig_target));
53395334 frame_type->abi_size = frame_type->data.frame.locals_struct->abi_size;
53405335 frame_type->abi_align = frame_type->data.frame.locals_struct->abi_align;
53415336 frame_type->size_in_bits = frame_type->data.frame.locals_struct->size_in_bits;