diff options
Diffstat (limited to 'src/js_parser/js_parser.zig')
-rw-r--r-- | src/js_parser/js_parser.zig | 63 |
1 files changed, 28 insertions, 35 deletions
diff --git a/src/js_parser/js_parser.zig b/src/js_parser/js_parser.zig index 3321d0ed3..26dfc9bc2 100644 --- a/src/js_parser/js_parser.zig +++ b/src/js_parser/js_parser.zig @@ -1650,7 +1650,7 @@ pub const P = struct { // symbols must be separate from the pass that binds identifiers to declared // symbols to handle declaring a hoisted "var" symbol in a nested scope and // binding a name to it in a parent or sibling scope. - scopes_in_order: std.ArrayListUnmanaged(ScopeOrder), + scopes_in_order: std.ArrayListUnmanaged(?ScopeOrder), // These properties are for the visit pass, which runs after the parse pass. // The visit pass binds identifiers to declared symbols, does constant @@ -2242,11 +2242,14 @@ pub const P = struct { pub fn pushScopeForVisitPass(p: *P, comptime kind: js_ast.Scope.Kind, loc: logger.Loc) !void { assert(p.scopes_in_order.items.len > 0); - const order = p.scopes_in_order.items[0]; - if (p.scopes_in_order.items.len > 1) { - p.scopes_in_order.items = p.scopes_in_order.items[1..p.scopes_in_order.items.len]; + var i: usize = 0; + while (p.scopes_in_order.items[i] == null and i < p.scopes_in_order.items.len) : (i += 1) {} + const order = p.scopes_in_order.items[i].?; + i += 1; + if (p.scopes_in_order.items.len > i) { + p.scopes_in_order.items = p.scopes_in_order.items[i..p.scopes_in_order.items.len]; } else { - p.scopes_in_order.items = &([_]ScopeOrder{}); + p.scopes_in_order.items = &([_]?ScopeOrder{}); } // Sanity-check that the scopes generated by the first and second passes match @@ -2281,9 +2284,15 @@ pub const P = struct { // Enforce that scope locations are strictly increasing to help catch bugs // where the pushed scopes are mistmatched between the first and second passes if (std.builtin.mode != std.builtin.Mode.ReleaseFast and p.scopes_in_order.items.len > 0) { - const prev_start = p.scopes_in_order.items[p.scopes_in_order.items.len - 1].loc.start; - if (prev_start >= loc.start) { - p.panic("Scope location {d} must be greater than {d}", .{ loc.start, prev_start }); + var last_i = p.scopes_in_order.items.len - 1; + while (p.scopes_in_order.items[last_i] == null and last_i > 0) { + last_i -= 1; + } + + if (p.scopes_in_order.items[last_i]) |prev_scope| { + if (prev_scope.loc.start >= loc.start) { + p.panic("Scope location {d} must be greater than {d}", .{ loc.start, prev_scope.loc.start }); + } } } @@ -4050,7 +4059,9 @@ pub const P = struct { // Remove any direct children from their parent var scope = p.current_scope; var children = scope.children; - for (p.scopes_in_order.items[scope_index..]) |child| { + for (p.scopes_in_order.items[scope_index..]) |_child| { + const child = _child orelse continue; + if (child.scope.parent == p.current_scope) { var i: usize = children.items.len - 1; while (i >= 0) { @@ -5000,24 +5011,6 @@ pub const P = struct { } } - // Saves us from allocating a slice to the heap - pub fn parseArrowBodySingleArg(p: *P, arg: G.Arg, data: anytype) !E.Arrow { - switch (@TypeOf(data)) { - FnOrArrowDataParse => { - var args = [_]G.Arg{arg}; - - var d = data; - - return p.parseArrowBody(args[0..], &d); - }, - *FnOrArrowDataParse => { - var args = [_]G.Arg{arg}; - return p.parseArrowBody(args[0..], data); - }, - else => unreachable, - } - } - // This is where the allocate memory to the heap for AST objects. // This is a short name to keep the code more readable. // It also swallows errors, but I think that's correct here. @@ -5085,9 +5078,9 @@ pub const P = struct { async_range.loc, ) }; _ = p.pushScopeForParsePass(.function_args, async_range.loc) catch unreachable; - defer p.popScope(); var data = FnOrArrowDataParse{}; var arrow_body = try p.parseArrowBody(args, &data); + p.popScope(); return p.e(arrow_body, async_range.loc); } }, @@ -5806,7 +5799,8 @@ pub const P = struct { var value = p.parseExpr(.lowest); var tail_loc = p.lexer.loc(); p.lexer.rescanCloseBraceAsTemplateToken(); - var tail = p.allocator.dupe(u16, p.lexer.string_literal) catch unreachable; + + var tail = p.lexer.stringLiteralUTF16(); var tail_raw: string = ""; if (include_raw) { @@ -6655,7 +6649,7 @@ pub const P = struct { pub fn panic(p: *P, comptime str: string, args: anytype) noreturn { p.log.addRangeErrorFmt(p.source, p.lexer.range(), p.allocator, str, args) catch unreachable; - var fixedBuffer = [_]u8{0} ** 4096; + var fixedBuffer = [_]u8{0} ** (1024 * 1024); var stream = std.io.fixedBufferStream(&fixedBuffer); p.log.print(stream.writer()) catch unreachable; @@ -6833,7 +6827,7 @@ pub const P = struct { }, .t_template_head => { var legacy_octal_loc = logger.Loc.Empty; - var head = p.lexer.string_literal; + var head = p.lexer.stringLiteralUTF16(); var head_raw = p.lexer.raw(); if (p.lexer.legacy_octal_loc.start > loc.start) { legacy_octal_loc = p.lexer.legacy_octal_loc; @@ -8184,7 +8178,7 @@ pub const P = struct { }, .bin_logical_and => { const side_effects = SideEffects.toBoolean(e_.left.data); - if (side_effects.ok and side_effects.value) { + if (side_effects.ok and !side_effects.value) { // "false && dead" const old = p.is_control_flow_dead; p.is_control_flow_dead = true; @@ -10715,8 +10709,7 @@ pub const P = struct { // These scopes were all created in between this scope's push and pop // operations, so they should all be child scopes and should all be popped // by the time we get here. - _ = p.scopes_in_order.swapRemove(scope_index); - + p.scopes_in_order.items[scope_index] = null; // Remove the last child from the parent scope const last = parent.children.items.len - 1; assert(parent.children.items[last] == to_flatten); @@ -10906,7 +10899,7 @@ pub const P = struct { .named_exports = @TypeOf(_parser.named_exports).init(allocator), .top_level_symbol_to_parts = @TypeOf(_parser.top_level_symbol_to_parts).init(allocator), .import_namespace_cc_map = @TypeOf(_parser.import_namespace_cc_map).init(allocator), - .scopes_in_order = try std.ArrayListUnmanaged(ScopeOrder).initCapacity(allocator, 1), + .scopes_in_order = try std.ArrayListUnmanaged(?ScopeOrder).initCapacity(allocator, 1), .temp_refs_to_declare = @TypeOf(_parser.temp_refs_to_declare).init(allocator), .relocated_top_level_vars = @TypeOf(_parser.relocated_top_level_vars).init(allocator), .log = log, |