authorgravatar for matthew.h.borkowski@gmail.comMatthew Borkowski <matthew.h.borkowski@gmail.com> 2021-05-27 14:30:42-04:00
committergravatar for matthew.h.borkowski@gmail.comMatthew Borkowski <matthew.h.borkowski@gmail.com> 2021-05-27 14:30:42-04:00
log80c86ec9608478ade64964e7206487b6178853af
tree42ae3749dedb8486092146394cc41d927277e920
parent9ddd12ea14ba1aa3f6f97d87fd13a636812aa6ea

keep temporary list from escaping `parseParamDeclList`, make SmallSpan.multi hold Node.SubRange instead of owned memory


1 files changed, 25 insertions(+), 26 deletions(-)

lib/std/zig/parse.zig+25-26
......@@ -97,6 +97,11 @@ const Parser = struct {
9797 extra_data: std.ArrayListUnmanaged(Node.Index),
9898 scratch: std.ArrayListUnmanaged(Node.Index),
9999
100 const SmallSpan = union(enum) {
101 zero_or_one: Node.Index,
102 multi: Node.SubRange,
103 };
104
100105 const Members = struct {
101106 len: usize,
102107 lhs: Node.Index,
......@@ -639,9 +644,6 @@ const Parser = struct {
639644 const fn_proto_index = try p.reserveNode();
640645
641646 _ = p.eatToken(.identifier);
642 const scratch_top = p.scratch.items.len;
643 defer p.scratch.shrinkRetainingCapacity(scratch_top);
644 // parseParamDeclList does not shrink scratch buffer, but we will
645647 const params = try p.parseParamDeclList();
646648 const align_expr = try p.parseByteAlign();
647649 const section_expr = try p.parseLinkSection();
......@@ -656,17 +658,16 @@ const Parser = struct {
656658 }
657659
658660 if (align_expr == 0 and section_expr == 0 and callconv_expr == 0) {
659 switch (params.len) {
660 0, 1 => return p.setNode(fn_proto_index, .{
661 switch (params) {
662 .zero_or_one => |param| return p.setNode(fn_proto_index, .{
661663 .tag = .fn_proto_simple,
662664 .main_token = fn_token,
663665 .data = .{
664 .lhs = if (params.len > 0) params[0] else 0,
666 .lhs = param,
665667 .rhs = return_type_expr,
666668 },
667669 }),
668 else => {
669 const span = try p.listToSpan(params);
670 .multi => |span| {
670671 return p.setNode(fn_proto_index, .{
671672 .tag = .fn_proto_multi,
672673 .main_token = fn_token,
......@@ -681,13 +682,13 @@ const Parser = struct {
681682 },
682683 }
683684 }
684 switch (params.len) {
685 0, 1 => return p.setNode(fn_proto_index, .{
685 switch (params) {
686 .zero_or_one => |param| return p.setNode(fn_proto_index, .{
686687 .tag = .fn_proto_one,
687688 .main_token = fn_token,
688689 .data = .{
689690 .lhs = try p.addExtra(Node.FnProtoOne{
690 .param = if (params.len > 0) params[0] else 0,
691 .param = param,
691692 .align_expr = align_expr,
692693 .section_expr = section_expr,
693694 .callconv_expr = callconv_expr,
......@@ -695,8 +696,7 @@ const Parser = struct {
695696 .rhs = return_type_expr,
696697 },
697698 }),
698 else => {
699 const span = try p.listToSpan(params);
699 .multi => |span| {
700700 return p.setNode(fn_proto_index, .{
701701 .tag = .fn_proto,
702702 .main_token = fn_token,
......@@ -3550,13 +3550,10 @@ const Parser = struct {
35503550 }
35513551
35523552 /// ParamDeclList <- (ParamDecl COMMA)* ParamDecl?
3553 fn parseParamDeclList(p: *Parser) ![]Node.Index {
3554 const scratch_top = p.scratch.items.len;
3555 // don't defer p.scratch.shrinkRetainingCapacity because caller will do it
3556
3553 fn parseParamDeclList(p: *Parser) !SmallSpan {
35573554 _ = try p.expectToken(.l_paren);
35583555 if (p.eatToken(.r_paren)) |_| {
3559 return p.scratch.items[scratch_top..];
3556 return SmallSpan{ .zero_or_one = 0 };
35603557 }
35613558 const param_one = while (true) {
35623559 const param = try p.expectParamDecl();
......@@ -3564,10 +3561,10 @@ const Parser = struct {
35643561 switch (p.token_tags[p.nextToken()]) {
35653562 .comma => {
35663563 if (p.eatToken(.r_paren)) |_| {
3567 return p.scratch.items[scratch_top..];
3564 return SmallSpan{ .zero_or_one = 0 };
35683565 }
35693566 },
3570 .r_paren => return p.scratch.items[scratch_top..],
3567 .r_paren => return SmallSpan{ .zero_or_one = 0 },
35713568 else => {
35723569 // This is likely just a missing comma;
35733570 // give an error but continue parsing this list.
......@@ -3576,12 +3573,11 @@ const Parser = struct {
35763573 },
35773574 }
35783575 } else unreachable;
3579 try p.scratch.append(p.gpa, param_one);
35803576
35813577 const param_two = while (true) {
35823578 switch (p.token_tags[p.nextToken()]) {
35833579 .comma => {},
3584 .r_paren => return p.scratch.items[scratch_top..],
3580 .r_paren => return SmallSpan{ .zero_or_one = param_one },
35853581 .colon, .r_brace, .r_bracket => {
35863582 p.tok_i -= 1;
35873583 return p.failExpected(.r_paren);
......@@ -3594,17 +3590,20 @@ const Parser = struct {
35943590 },
35953591 }
35963592 if (p.eatToken(.r_paren)) |_| {
3597 return p.scratch.items[scratch_top..];
3593 return SmallSpan{ .zero_or_one = param_one };
35983594 }
35993595 const param = try p.expectParamDecl();
36003596 if (param != 0) break param;
36013597 } else unreachable;
3602 try p.scratch.append(p.gpa, param_two);
3598
3599 const scratch_top = p.scratch.items.len;
3600 defer p.scratch.shrinkRetainingCapacity(scratch_top);
3601 try p.scratch.appendSlice(p.gpa, &.{ param_one, param_two });
36033602
36043603 while (true) {
36053604 switch (p.token_tags[p.nextToken()]) {
36063605 .comma => {},
3607 .r_paren => return p.scratch.items[scratch_top..],
3606 .r_paren => return SmallSpan{ .multi = try p.listToSpan(p.scratch.items[scratch_top..]) },
36083607 .colon, .r_brace, .r_bracket => {
36093608 p.tok_i -= 1;
36103609 return p.failExpected(.r_paren);
......@@ -3617,7 +3616,7 @@ const Parser = struct {
36173616 },
36183617 }
36193618 if (p.eatToken(.r_paren)) |_| {
3620 return p.scratch.items[scratch_top..];
3619 return SmallSpan{ .multi = try p.listToSpan(p.scratch.items[scratch_top..]) };
36213620 }
36223621 const param = try p.expectParamDecl();
36233622 if (param != 0) try p.scratch.append(p.gpa, param);