| ... | ... | @@ -2482,11 +2482,14 @@ const WipDecls = struct { |
| 2482 | 2482 | decl_index: usize = 0, |
| 2483 | 2483 | cur_bit_bag: u32 = 0, |
| 2484 | 2484 | bit_bag: ArrayListUnmanaged(u32) = .{}, |
| 2485 | | name_and_value: ArrayListUnmanaged(u32) = .{}, |
| 2485 | payload: ArrayListUnmanaged(u32) = .{}, |
| 2486 | |
| 2487 | const bits_per_field = 4; |
| 2488 | const fields_per_u32 = 32 / bits_per_field; |
| 2486 | 2489 | |
| 2487 | 2490 | fn deinit(wip_decls: *WipDecls, gpa: *Allocator) void { |
| 2488 | 2491 | wip_decls.bit_bag.deinit(gpa); |
| 2489 | | wip_decls.name_and_value.deinit(gpa); |
| 2492 | wip_decls.payload.deinit(gpa); |
| 2490 | 2493 | } |
| 2491 | 2494 | }; |
| 2492 | 2495 | |
| ... | ... | @@ -2501,6 +2504,15 @@ fn fnDecl( |
| 2501 | 2504 | const tree = &astgen.file.tree; |
| 2502 | 2505 | const token_tags = tree.tokens.items(.tag); |
| 2503 | 2506 | |
| 2507 | var decl_gz: GenZir = .{ |
| 2508 | .force_comptime = true, |
| 2509 | .decl_node_index = fn_proto.ast.proto_node, |
| 2510 | .parent = &gz.base, |
| 2511 | .astgen = astgen, |
| 2512 | .ref_start_index = @intCast(u32, Zir.Inst.Ref.typed_value_map.len), |
| 2513 | }; |
| 2514 | defer decl_gz.instructions.deinit(gpa); |
| 2515 | |
| 2504 | 2516 | const is_pub = fn_proto.visib_token != null; |
| 2505 | 2517 | const is_export = blk: { |
| 2506 | 2518 | const maybe_export_token = fn_proto.extern_export_token orelse break :blk false; |
| ... | ... | @@ -2510,13 +2522,22 @@ fn fnDecl( |
| 2510 | 2522 | const maybe_extern_token = fn_proto.extern_export_token orelse break :blk false; |
| 2511 | 2523 | break :blk token_tags[maybe_extern_token] == .keyword_extern; |
| 2512 | 2524 | }; |
| 2513 | | if (wip_decls.decl_index % 16 == 0 and wip_decls.decl_index != 0) { |
| 2525 | const align_inst: Zir.Inst.Ref = if (fn_proto.ast.align_expr == 0) .none else inst: { |
| 2526 | break :inst try expr(&decl_gz, &decl_gz.base, align_rl, fn_proto.ast.align_expr); |
| 2527 | }; |
| 2528 | const section_inst: Zir.Inst.Ref = if (fn_proto.ast.section_expr == 0) .none else inst: { |
| 2529 | break :inst try comptimeExpr(&decl_gz, &decl_gz.base, .{ .ty = .const_slice_u8_type }, fn_proto.ast.section_expr); |
| 2530 | }; |
| 2531 | |
| 2532 | if (wip_decls.decl_index % WipDecls.fields_per_u32 == 0 and wip_decls.decl_index != 0) { |
| 2514 | 2533 | try wip_decls.bit_bag.append(gpa, wip_decls.cur_bit_bag); |
| 2515 | 2534 | wip_decls.cur_bit_bag = 0; |
| 2516 | 2535 | } |
| 2517 | | wip_decls.cur_bit_bag = (wip_decls.cur_bit_bag >> 2) | |
| 2518 | | (@as(u32, @boolToInt(is_pub)) << 30) | |
| 2519 | | (@as(u32, @boolToInt(is_export)) << 31); |
| 2536 | wip_decls.cur_bit_bag = (wip_decls.cur_bit_bag >> WipDecls.bits_per_field) | |
| 2537 | (@as(u32, @boolToInt(is_pub)) << 28) | |
| 2538 | (@as(u32, @boolToInt(is_export)) << 29) | |
| 2539 | (@as(u32, @boolToInt(align_inst != .none)) << 30) | |
| 2540 | (@as(u32, @boolToInt(section_inst != .none)) << 31); |
| 2520 | 2541 | wip_decls.decl_index += 1; |
| 2521 | 2542 | |
| 2522 | 2543 | // The AST params array does not contain anytype and ... parameters. |
| ... | ... | @@ -2537,15 +2558,6 @@ fn fnDecl( |
| 2537 | 2558 | const param_types = try gpa.alloc(Zir.Inst.Ref, param_count); |
| 2538 | 2559 | defer gpa.free(param_types); |
| 2539 | 2560 | |
| 2540 | | var decl_gz: GenZir = .{ |
| 2541 | | .force_comptime = true, |
| 2542 | | .decl_node_index = fn_proto.ast.proto_node, |
| 2543 | | .parent = &gz.base, |
| 2544 | | .astgen = astgen, |
| 2545 | | .ref_start_index = @intCast(u32, Zir.Inst.Ref.typed_value_map.len), |
| 2546 | | }; |
| 2547 | | defer decl_gz.instructions.deinit(gpa); |
| 2548 | | |
| 2549 | 2561 | var is_var_args = false; |
| 2550 | 2562 | { |
| 2551 | 2563 | var param_type_i: usize = 0; |
| ... | ... | @@ -2577,21 +2589,6 @@ fn fnDecl( |
| 2577 | 2589 | break :blk lib_name_str.index; |
| 2578 | 2590 | } else 0; |
| 2579 | 2591 | |
| 2580 | | if (fn_proto.ast.align_expr != 0) { |
| 2581 | | return astgen.failNode( |
| 2582 | | fn_proto.ast.align_expr, |
| 2583 | | "TODO implement function align expression", |
| 2584 | | .{}, |
| 2585 | | ); |
| 2586 | | } |
| 2587 | | if (fn_proto.ast.section_expr != 0) { |
| 2588 | | return astgen.failNode( |
| 2589 | | fn_proto.ast.section_expr, |
| 2590 | | "TODO implement function section expression", |
| 2591 | | .{}, |
| 2592 | | ); |
| 2593 | | } |
| 2594 | | |
| 2595 | 2592 | const maybe_bang = tree.firstToken(fn_proto.ast.return_type) - 1; |
| 2596 | 2593 | const is_inferred_error = token_tags[maybe_bang] == .bang; |
| 2597 | 2594 | |
| ... | ... | @@ -2713,9 +2710,15 @@ fn fnDecl( |
| 2713 | 2710 | _ = try decl_gz.addBreak(.break_inline, block_inst, func_inst); |
| 2714 | 2711 | try decl_gz.setBlockBody(block_inst); |
| 2715 | 2712 | |
| 2716 | | try wip_decls.name_and_value.ensureCapacity(gpa, wip_decls.name_and_value.items.len + 2); |
| 2717 | | wip_decls.name_and_value.appendAssumeCapacity(fn_name_str_index); |
| 2718 | | wip_decls.name_and_value.appendAssumeCapacity(block_inst); |
| 2713 | try wip_decls.payload.ensureUnusedCapacity(gpa, 4); |
| 2714 | wip_decls.payload.appendAssumeCapacity(fn_name_str_index); |
| 2715 | wip_decls.payload.appendAssumeCapacity(block_inst); |
| 2716 | if (align_inst != .none) { |
| 2717 | wip_decls.payload.appendAssumeCapacity(@enumToInt(align_inst)); |
| 2718 | } |
| 2719 | if (section_inst != .none) { |
| 2720 | wip_decls.payload.appendAssumeCapacity(@enumToInt(section_inst)); |
| 2721 | } |
| 2719 | 2722 | } |
| 2720 | 2723 | |
| 2721 | 2724 | fn globalVarDecl( |
| ... | ... | @@ -2730,6 +2733,14 @@ fn globalVarDecl( |
| 2730 | 2733 | const tree = &astgen.file.tree; |
| 2731 | 2734 | const token_tags = tree.tokens.items(.tag); |
| 2732 | 2735 | |
| 2736 | var block_scope: GenZir = .{ |
| 2737 | .parent = scope, |
| 2738 | .decl_node_index = node, |
| 2739 | .astgen = astgen, |
| 2740 | .force_comptime = true, |
| 2741 | }; |
| 2742 | defer block_scope.instructions.deinit(gpa); |
| 2743 | |
| 2733 | 2744 | const is_pub = var_decl.visib_token != null; |
| 2734 | 2745 | const is_export = blk: { |
| 2735 | 2746 | const maybe_export_token = var_decl.extern_export_token orelse break :blk false; |
| ... | ... | @@ -2739,13 +2750,21 @@ fn globalVarDecl( |
| 2739 | 2750 | const maybe_extern_token = var_decl.extern_export_token orelse break :blk false; |
| 2740 | 2751 | break :blk token_tags[maybe_extern_token] == .keyword_extern; |
| 2741 | 2752 | }; |
| 2742 | | if (wip_decls.decl_index % 16 == 0 and wip_decls.decl_index != 0) { |
| 2753 | const align_inst: Zir.Inst.Ref = if (var_decl.ast.align_node == 0) .none else inst: { |
| 2754 | break :inst try expr(&block_scope, &block_scope.base, align_rl, var_decl.ast.align_node); |
| 2755 | }; |
| 2756 | const section_inst: Zir.Inst.Ref = if (var_decl.ast.section_node == 0) .none else inst: { |
| 2757 | break :inst try comptimeExpr(&block_scope, &block_scope.base, .{ .ty = .const_slice_u8_type }, var_decl.ast.section_node); |
| 2758 | }; |
| 2759 | if (wip_decls.decl_index % WipDecls.fields_per_u32 == 0 and wip_decls.decl_index != 0) { |
| 2743 | 2760 | try wip_decls.bit_bag.append(gpa, wip_decls.cur_bit_bag); |
| 2744 | 2761 | wip_decls.cur_bit_bag = 0; |
| 2745 | 2762 | } |
| 2746 | | wip_decls.cur_bit_bag = (wip_decls.cur_bit_bag >> 2) | |
| 2747 | | (@as(u32, @boolToInt(is_pub)) << 30) | |
| 2748 | | (@as(u32, @boolToInt(is_export)) << 31); |
| 2763 | wip_decls.cur_bit_bag = (wip_decls.cur_bit_bag >> WipDecls.bits_per_field) | |
| 2764 | (@as(u32, @boolToInt(is_pub)) << 28) | |
| 2765 | (@as(u32, @boolToInt(is_export)) << 29) | |
| 2766 | (@as(u32, @boolToInt(align_inst != .none)) << 30) | |
| 2767 | (@as(u32, @boolToInt(section_inst != .none)) << 31); |
| 2749 | 2768 | wip_decls.decl_index += 1; |
| 2750 | 2769 | |
| 2751 | 2770 | const is_mutable = token_tags[var_decl.ast.mut_token] == .keyword_var; |
| ... | ... | @@ -2762,12 +2781,6 @@ fn globalVarDecl( |
| 2762 | 2781 | } else 0; |
| 2763 | 2782 | |
| 2764 | 2783 | assert(var_decl.comptime_token == null); // handled by parser |
| 2765 | | if (var_decl.ast.align_node != 0) { |
| 2766 | | return astgen.failNode(var_decl.ast.align_node, "TODO implement alignment on globals", .{}); |
| 2767 | | } |
| 2768 | | if (var_decl.ast.section_node != 0) { |
| 2769 | | return astgen.failNode(var_decl.ast.section_node, "TODO linksection on globals", .{}); |
| 2770 | | } |
| 2771 | 2784 | |
| 2772 | 2785 | const var_inst: Zir.Inst.Index = if (var_decl.ast.init_node != 0) vi: { |
| 2773 | 2786 | if (is_extern) { |
| ... | ... | @@ -2778,14 +2791,6 @@ fn globalVarDecl( |
| 2778 | 2791 | ); |
| 2779 | 2792 | } |
| 2780 | 2793 | |
| 2781 | | var block_scope: GenZir = .{ |
| 2782 | | .parent = scope, |
| 2783 | | .decl_node_index = node, |
| 2784 | | .astgen = astgen, |
| 2785 | | .force_comptime = true, |
| 2786 | | }; |
| 2787 | | defer block_scope.instructions.deinit(gpa); |
| 2788 | | |
| 2789 | 2794 | const init_result_loc: AstGen.ResultLoc = if (var_decl.ast.type_node != 0) .{ |
| 2790 | 2795 | .ty = try expr( |
| 2791 | 2796 | &block_scope, |
| ... | ... | @@ -2812,7 +2817,7 @@ fn globalVarDecl( |
| 2812 | 2817 | } else if (var_decl.ast.type_node != 0) { |
| 2813 | 2818 | // Extern variable which has an explicit type. |
| 2814 | 2819 | |
| 2815 | | const type_inst = try typeExpr(gz, scope, var_decl.ast.type_node); |
| 2820 | const type_inst = try typeExpr(&block_scope, &block_scope.base, var_decl.ast.type_node); |
| 2816 | 2821 | |
| 2817 | 2822 | return astgen.failNode(node, "TODO AstGen extern global variable", .{}); |
| 2818 | 2823 | } else { |
| ... | ... | @@ -2822,9 +2827,15 @@ fn globalVarDecl( |
| 2822 | 2827 | const name_token = var_decl.ast.mut_token + 1; |
| 2823 | 2828 | const name_str_index = try gz.identAsString(name_token); |
| 2824 | 2829 | |
| 2825 | | try wip_decls.name_and_value.ensureCapacity(gpa, wip_decls.name_and_value.items.len + 2); |
| 2826 | | wip_decls.name_and_value.appendAssumeCapacity(name_str_index); |
| 2827 | | wip_decls.name_and_value.appendAssumeCapacity(var_inst); |
| 2830 | try wip_decls.payload.ensureUnusedCapacity(gpa, 4); |
| 2831 | wip_decls.payload.appendAssumeCapacity(name_str_index); |
| 2832 | wip_decls.payload.appendAssumeCapacity(var_inst); |
| 2833 | if (align_inst != .none) { |
| 2834 | wip_decls.payload.appendAssumeCapacity(@enumToInt(align_inst)); |
| 2835 | } |
| 2836 | if (section_inst != .none) { |
| 2837 | wip_decls.payload.appendAssumeCapacity(@enumToInt(section_inst)); |
| 2838 | } |
| 2828 | 2839 | } |
| 2829 | 2840 | |
| 2830 | 2841 | fn comptimeDecl( |
| ... | ... | @@ -3080,7 +3091,7 @@ fn structDeclInner( |
| 3080 | 3091 | (@as(u32, @boolToInt(have_value)) << 31); |
| 3081 | 3092 | |
| 3082 | 3093 | if (have_align) { |
| 3083 | | const align_inst = try expr(&block_scope, &block_scope.base, .{ .ty = .u32_type }, member.ast.align_expr); |
| 3094 | const align_inst = try expr(&block_scope, &block_scope.base, align_rl, member.ast.align_expr); |
| 3084 | 3095 | fields_data.appendAssumeCapacity(@enumToInt(align_inst)); |
| 3085 | 3096 | } |
| 3086 | 3097 | if (have_value) { |
| ... | ... | @@ -3097,9 +3108,9 @@ fn structDeclInner( |
| 3097 | 3108 | } |
| 3098 | 3109 | } |
| 3099 | 3110 | { |
| 3100 | | const empty_slot_count = 16 - (wip_decls.decl_index % 16); |
| 3101 | | if (empty_slot_count < 16) { |
| 3102 | | wip_decls.cur_bit_bag >>= @intCast(u5, empty_slot_count * 2); |
| 3111 | const empty_slot_count = WipDecls.fields_per_u32 - (wip_decls.decl_index % WipDecls.fields_per_u32); |
| 3112 | if (empty_slot_count < WipDecls.fields_per_u32) { |
| 3113 | wip_decls.cur_bit_bag >>= @intCast(u5, empty_slot_count * WipDecls.bits_per_field); |
| 3103 | 3114 | } |
| 3104 | 3115 | } |
| 3105 | 3116 | |
| ... | ... | @@ -3113,7 +3124,7 @@ fn structDeclInner( |
| 3113 | 3124 | bit_bag.items.len + @boolToInt(field_index != 0) + fields_data.items.len + |
| 3114 | 3125 | block_scope.instructions.items.len + |
| 3115 | 3126 | wip_decls.bit_bag.items.len + @boolToInt(wip_decls.decl_index != 0) + |
| 3116 | | wip_decls.name_and_value.items.len); |
| 3127 | wip_decls.payload.items.len); |
| 3117 | 3128 | const zir_datas = astgen.instructions.items(.data); |
| 3118 | 3129 | zir_datas[decl_inst].pl_node.payload_index = astgen.addExtraAssumeCapacity(Zir.Inst.StructDecl{ |
| 3119 | 3130 | .body_len = @intCast(u32, block_scope.instructions.items.len), |
| ... | ... | @@ -3132,7 +3143,7 @@ fn structDeclInner( |
| 3132 | 3143 | if (wip_decls.decl_index != 0) { |
| 3133 | 3144 | astgen.extra.appendAssumeCapacity(wip_decls.cur_bit_bag); |
| 3134 | 3145 | } |
| 3135 | | astgen.extra.appendSliceAssumeCapacity(wip_decls.name_and_value.items); |
| 3146 | astgen.extra.appendSliceAssumeCapacity(wip_decls.payload.items); |
| 3136 | 3147 | |
| 3137 | 3148 | return gz.indexToRef(decl_inst); |
| 3138 | 3149 | } |
| ... | ... | @@ -3321,9 +3332,9 @@ fn unionDeclInner( |
| 3321 | 3332 | } |
| 3322 | 3333 | } |
| 3323 | 3334 | { |
| 3324 | | const empty_slot_count = 16 - (wip_decls.decl_index % 16); |
| 3325 | | if (empty_slot_count < 16) { |
| 3326 | | wip_decls.cur_bit_bag >>= @intCast(u5, empty_slot_count * 2); |
| 3335 | const empty_slot_count = WipDecls.fields_per_u32 - (wip_decls.decl_index % WipDecls.fields_per_u32); |
| 3336 | if (empty_slot_count < WipDecls.fields_per_u32) { |
| 3337 | wip_decls.cur_bit_bag >>= @intCast(u5, empty_slot_count * WipDecls.bits_per_field); |
| 3327 | 3338 | } |
| 3328 | 3339 | } |
| 3329 | 3340 | |
| ... | ... | @@ -3337,7 +3348,7 @@ fn unionDeclInner( |
| 3337 | 3348 | bit_bag.items.len + 1 + fields_data.items.len + |
| 3338 | 3349 | block_scope.instructions.items.len + |
| 3339 | 3350 | wip_decls.bit_bag.items.len + @boolToInt(wip_decls.decl_index != 0) + |
| 3340 | | wip_decls.name_and_value.items.len); |
| 3351 | wip_decls.payload.items.len); |
| 3341 | 3352 | const zir_datas = astgen.instructions.items(.data); |
| 3342 | 3353 | zir_datas[decl_inst].pl_node.payload_index = astgen.addExtraAssumeCapacity(Zir.Inst.UnionDecl{ |
| 3343 | 3354 | .tag_type = arg_inst, |
| ... | ... | @@ -3355,7 +3366,7 @@ fn unionDeclInner( |
| 3355 | 3366 | if (wip_decls.decl_index != 0) { |
| 3356 | 3367 | astgen.extra.appendAssumeCapacity(wip_decls.cur_bit_bag); |
| 3357 | 3368 | } |
| 3358 | | astgen.extra.appendSliceAssumeCapacity(wip_decls.name_and_value.items); |
| 3369 | astgen.extra.appendSliceAssumeCapacity(wip_decls.payload.items); |
| 3359 | 3370 | |
| 3360 | 3371 | return gz.indexToRef(decl_inst); |
| 3361 | 3372 | } |
| ... | ... | @@ -3653,9 +3664,9 @@ fn containerDecl( |
| 3653 | 3664 | } |
| 3654 | 3665 | } |
| 3655 | 3666 | { |
| 3656 | | const empty_slot_count = 16 - (wip_decls.decl_index % 16); |
| 3657 | | if (empty_slot_count < 16) { |
| 3658 | | wip_decls.cur_bit_bag >>= @intCast(u5, empty_slot_count * 2); |
| 3667 | const empty_slot_count = WipDecls.fields_per_u32 - (wip_decls.decl_index % WipDecls.fields_per_u32); |
| 3668 | if (empty_slot_count < WipDecls.fields_per_u32) { |
| 3669 | wip_decls.cur_bit_bag >>= @intCast(u5, empty_slot_count * WipDecls.bits_per_field); |
| 3659 | 3670 | } |
| 3660 | 3671 | } |
| 3661 | 3672 | |
| ... | ... | @@ -3669,7 +3680,7 @@ fn containerDecl( |
| 3669 | 3680 | bit_bag.items.len + 1 + fields_data.items.len + |
| 3670 | 3681 | block_scope.instructions.items.len + |
| 3671 | 3682 | wip_decls.bit_bag.items.len + @boolToInt(wip_decls.decl_index != 0) + |
| 3672 | | wip_decls.name_and_value.items.len); |
| 3683 | wip_decls.payload.items.len); |
| 3673 | 3684 | const zir_datas = astgen.instructions.items(.data); |
| 3674 | 3685 | zir_datas[decl_inst].pl_node.payload_index = astgen.addExtraAssumeCapacity(Zir.Inst.EnumDecl{ |
| 3675 | 3686 | .tag_type = arg_inst, |
| ... | ... | @@ -3686,7 +3697,7 @@ fn containerDecl( |
| 3686 | 3697 | if (wip_decls.decl_index != 0) { |
| 3687 | 3698 | astgen.extra.appendAssumeCapacity(wip_decls.cur_bit_bag); |
| 3688 | 3699 | } |
| 3689 | | astgen.extra.appendSliceAssumeCapacity(wip_decls.name_and_value.items); |
| 3700 | astgen.extra.appendSliceAssumeCapacity(wip_decls.payload.items); |
| 3690 | 3701 | |
| 3691 | 3702 | return rvalue(gz, scope, rl, gz.indexToRef(decl_inst), node); |
| 3692 | 3703 | }, |