aboutsummaryrefslogtreecommitdiff
path: root/src/js_parser/js_parser.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/js_parser/js_parser.zig')
-rw-r--r--src/js_parser/js_parser.zig77
1 files changed, 43 insertions, 34 deletions
diff --git a/src/js_parser/js_parser.zig b/src/js_parser/js_parser.zig
index 4441a7867..cb48f08e3 100644
--- a/src/js_parser/js_parser.zig
+++ b/src/js_parser/js_parser.zig
@@ -1,6 +1,10 @@
usingnamespace @import("imports.zig");
const TemplatePartTuple = std.meta.Tuple(&[_]type{ []E.TemplatePart, logger.Loc });
+const ScopeOrderList = std.ArrayListUnmanaged(?ScopeOrder);
+
+var panic_buffer = std.mem.zeros(32 * 1024);
+var panic_stream = std.io.fixedBufferStream(&panic_buffer);
pub fn ExpressionTransposer(comptime ctx: type, visitor: fn (ptr: *ctx, arg: Expr, state: anytype) Expr) type {
return struct {
@@ -1573,7 +1577,7 @@ pub const P = struct {
module_ref: js_ast.Ref = js_ast.Ref.None,
import_meta_ref: js_ast.Ref = js_ast.Ref.None,
promise_ref: ?js_ast.Ref = null,
-
+ scopes_in_order_visitor_index: usize = 0,
has_classic_runtime_warned: bool = false,
data: js_ast.AstData,
@@ -1652,7 +1656,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: ScopeOrderList,
// These properties are for the visit pass, which runs after the parse pass.
// The visit pass binds identifiers to declared symbols, does constant
@@ -2261,22 +2265,26 @@ 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);
- 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{});
+ pub fn nextScopeInOrderForVisitPass(p: *P) ScopeOrder {
+ while (p.scopes_in_order.items[p.scopes_in_order_visitor_index] == null) {
+ p.scopes_in_order_visitor_index += 1;
+ }
+ const scope_order = p.scopes_in_order.items[p.scopes_in_order_visitor_index].?;
+ p.scopes_in_order_visitor_index += 1;
+ return scope_order;
+ }
+
+ pub fn pushScopeForVisitPass(p: *P, kind: js_ast.Scope.Kind, loc: logger.Loc) !void {
+ for (p.scopes_in_order.items[p.scopes_in_order_visitor_index..p.scopes_in_order.items.len]) |scope_order, i| {
+ if (scope_order) |ord| {
+ Output.print("Scope ({d}, {d})\n", .{ @enumToInt(ord.scope.kind), ord.loc.start });
+ }
}
+ const order = p.nextScopeInOrderForVisitPass();
// Sanity-check that the scopes generated by the first and second passes match
if (order.loc.start != loc.start or order.scope.kind != kind) {
- Output.print("Expected scope ({s}, {d}) in {s}, found scope ({s}, {d})", .{ kind, loc.start, p.source.path.pretty, order.scope.kind, order.loc.start });
- p.panic("", .{});
+ p.panic("Expected scope ({s}, {d}) in {s}, found scope ({s}, {d})", .{ kind, loc.start, p.source.path.pretty, order.scope.kind, order.loc.start });
}
p.current_scope = order.scope;
@@ -2284,21 +2292,27 @@ pub const P = struct {
try p.scopes_for_current_part.append(order.scope);
}
- pub fn pushScopeForParsePass(p: *P, comptime kind: js_ast.Scope.Kind, loc: logger.Loc) !usize {
+ pub fn pushScopeForParsePass(p: *P, kind: js_ast.Scope.Kind, loc: logger.Loc) !usize {
debugl("<pushScopeForParsePass>");
defer debugl("</pushScopeForParsePass>");
- var scope = try Scope.initPtr(p.allocator);
- scope.kind = kind;
- scope.label_ref = null;
+ var parent: *Scope = p.current_scope;
+ p.scope_id += 1;
- var parent: *Scope = undefined;
+ var scope = try p.allocator.create(Scope);
+ scope.* = Scope{
+ .members = @TypeOf(scope.members).init(p.allocator),
+ .children = @TypeOf(scope.children).init(
+ p.allocator,
+ ),
+ .generated = @TypeOf(scope.generated).init(p.allocator),
+ .kind = kind,
+ .label_ref = null,
+ .parent = parent,
+ .id = p.scope_id,
+ };
- if (kind != .entry) {
- parent = p.current_scope;
- scope.parent = parent;
- try parent.children.append(scope);
- scope.strict_mode = parent.strict_mode;
- }
+ try parent.children.append(scope);
+ scope.strict_mode = parent.strict_mode;
p.current_scope = scope;
@@ -5083,8 +5097,7 @@ pub const P = struct {
p.fn_or_arrow_data_parse = old_fn_or_arrow_data;
var stmts = try p.allocator.alloc(Stmt, 1);
- stmts[0] = p.s(S.Return{ .value = expr }, arrow_loc);
-
+ stmts[0] = p.s(S.Return{ .value = expr }, expr.loc);
return E.Arrow{ .args = args, .prefer_expr = true, .body = G.FnBody{ .loc = arrow_loc, .stmts = stmts } };
}
@@ -6742,12 +6755,8 @@ 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} ** (1024 * 1024);
- var stream = std.io.fixedBufferStream(&fixedBuffer);
-
- p.log.print(stream.writer()) catch unreachable;
- Global.panic("{s}", .{fixedBuffer});
+ p.log.print(panic_stream.writer()) catch unreachable;
+ Global.panic("{s}", .{panic_buffer});
}
pub fn _parsePrefix(p: *P, level: Level, errors: *DeferredErrors, flags: Expr.EFlags) anyerror!Expr {
@@ -10959,7 +10968,7 @@ pub const P = struct {
}
pub fn init(allocator: *std.mem.Allocator, log: *logger.Log, source: *const logger.Source, define: *Define, lexer: js_lexer.Lexer, opts: Parser.Options) !*P {
- var scope_order = try std.ArrayListUnmanaged(?ScopeOrder).initCapacity(allocator, 1);
+ var scope_order = try ScopeOrderList.initCapacity(allocator, 1);
var scope = try allocator.create(Scope);
scope.* = Scope{
.members = @TypeOf(scope.members).init(allocator),