aboutsummaryrefslogtreecommitdiff
path: root/src/js_ast.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/js_ast.zig')
-rw-r--r--src/js_ast.zig625
1 files changed, 273 insertions, 352 deletions
diff --git a/src/js_ast.zig b/src/js_ast.zig
index 5b3f1a7c1..416a3c752 100644
--- a/src/js_ast.zig
+++ b/src/js_ast.zig
@@ -11,15 +11,88 @@ const allocators = @import("allocators.zig");
const _hash_map = @import("hash_map.zig");
const StringHashMap = _hash_map.StringHashMap;
const AutoHashMap = _hash_map.AutoHashMap;
+pub fn NewStore(comptime ValueType: type, comptime count: usize) type {
+ const max_index = count - 1;
+ const list_count = count;
+ return struct {
+ const Allocator = std.mem.Allocator;
+ const Self = @This();
+ const Block = struct {
+ items: [count]ValueType = undefined,
+ used: usize = 0,
+ allocator: *std.mem.Allocator,
-pub const ListIndex = packed struct {
- index: u31,
- is_overflowing: bool = false,
+ pub fn isFull(block: *const Block) bool {
+ return block.used >= block.items.len;
+ }
- pub fn eql(a: ListIndex, b: ListIndex) bool {
- return @bitCast(u32, a) == @bitCast(u32, b);
- }
-};
+ pub fn append(block: *Block, value: ValueType) *ValueType {
+ std.debug.assert(block.used < count);
+ const index = block.used;
+ block.items[index] = value;
+
+ block.used += 1;
+ return &block.items[index];
+ }
+ };
+
+ block: Block,
+ overflow_ptrs: [500]*Block = undefined,
+ overflow: []*Block = &([_]*Block{}),
+ overflow_used: usize = 0,
+ allocator: *Allocator,
+
+ pub threadlocal var instance: Self = undefined;
+ pub threadlocal var _self: *Self = undefined;
+
+ pub fn reset() void {
+ _self.block.used = 0;
+ for (_self.overflow[0.._self.overflow_used]) |b| {
+ b.used = 0;
+ }
+ _self.overflow_used = 0;
+ }
+
+ pub fn init(allocator: *std.mem.Allocator) *Self {
+ instance = Self{
+ .allocator = allocator,
+ .block = Block{ .allocator = allocator },
+ };
+
+ _self = &instance;
+ return _self;
+ }
+
+ pub fn append(value: ValueType) *ValueType {
+ return _self._append(value);
+ }
+
+ fn _append(self: *Self, value: ValueType) *ValueType {
+ if (!self.block.isFull()) {
+ return self.block.append(value);
+ }
+
+ if (self.overflow_used >= self.overflow.len or self.overflow[self.overflow_used].isFull()) {
+ var slice = self.allocator.alloc(Block, 2) catch unreachable;
+ for (slice) |*block| {
+ block.allocator = self.allocator;
+ block.used = 0;
+ block.items = undefined;
+ self.overflow_ptrs[self.overflow.len] = block;
+ self.overflow = self.overflow_ptrs[0 .. self.overflow.len + 1];
+ }
+ }
+
+ var block = self.overflow[self.overflow_used];
+ var ptr = block.append(value);
+ if (block.isFull()) {
+ self.overflow_used += 1;
+ }
+
+ return ptr;
+ }
+ };
+}
// There are three types.
// 1. Expr (expression)
@@ -709,7 +782,7 @@ pub const E = struct {
pub const Call = struct {
// Node:
target: ExprNodeIndex,
- args: ExprNodeList,
+ args: ExprNodeList = &([_]ExprNodeIndex{}),
optional_chain: ?OptionalChain = null,
is_direct_eval: bool = false,
@@ -1086,103 +1159,103 @@ pub const Stmt = struct {
var None = S.Empty{};
pub inline fn getBlock(self: *const @This()) *S.Block {
- return Data.Store.Block.at(self.data.s_block);
+ return self.data.s_block;
}
pub inline fn getBreak(self: *const @This()) *S.Break {
- return Data.Store.Break.at(self.data.s_break);
+ return self.data.s_break;
}
pub inline fn getClass(self: *const @This()) *S.Class {
- return Data.Store.Class.at(self.data.s_class);
+ return self.data.s_class;
}
pub inline fn getComment(self: *const @This()) *S.Comment {
- return Data.Store.Comment.at(self.data.s_comment);
+ return self.data.s_comment;
}
pub inline fn getContinue(self: *const @This()) *S.Continue {
- return Data.Store.Continue.at(self.data.s_continue);
+ return self.data.s_continue;
}
pub inline fn getDebugger(self: *const @This()) S.Debugger {
return S.Debugger{};
}
pub inline fn getDirective(self: *const @This()) *S.Directive {
- return Data.Store.Directive.at(self.data.s_directive);
+ return self.data.s_directive;
}
pub inline fn getDoWhile(self: *const @This()) *S.DoWhile {
- return Data.Store.DoWhile.at(self.data.s_do_while);
+ return self.data.s_do_while;
}
pub inline fn getEmpty(self: *const @This()) S.Empty {
return S.Empty{};
}
pub inline fn getEnum(self: *const @This()) *S.Enum {
- return Data.Store.Enum.at(self.data.s_enum);
+ return self.data.s_enum;
}
pub inline fn getExportClause(self: *const @This()) *S.ExportClause {
- return Data.Store.ExportClause.at(self.data.s_export_clause);
+ return self.data.s_export_clause;
}
pub inline fn getExportDefault(self: *const @This()) *S.ExportDefault {
- return Data.Store.ExportDefault.at(self.data.s_export_default);
+ return self.data.s_export_default;
}
pub inline fn getExportEquals(self: *const @This()) *S.ExportEquals {
- return Data.Store.ExportEquals.at(self.data.s_export_equals);
+ return self.data.s_export_equals;
}
pub inline fn getExportFrom(self: *const @This()) *S.ExportFrom {
- return Data.Store.ExportFrom.at(self.data.s_export_from);
+ return self.data.s_export_from;
}
pub inline fn getExportStar(self: *const @This()) *S.ExportStar {
- return Data.Store.ExportStar.at(self.data.s_export_star);
+ return self.data.s_export_star;
}
pub inline fn getExpr(self: *const @This()) *S.SExpr {
- return Data.Store.SExpr.at(self.data.s_expr);
+ return self.data.s_expr;
}
pub inline fn getForIn(self: *const @This()) *S.ForIn {
- return Data.Store.ForIn.at(self.data.s_for_in);
+ return self.data.s_for_in;
}
pub inline fn getForOf(self: *const @This()) *S.ForOf {
- return Data.Store.ForOf.at(self.data.s_for_of);
+ return self.data.s_for_of;
}
pub inline fn getFor(self: *const @This()) *S.For {
- return Data.Store.For.at(self.data.s_for);
+ return self.data.s_for;
}
pub inline fn getFunction(self: *const @This()) *S.Function {
- return Data.Store.Function.at(self.data.s_function);
+ return self.data.s_function;
}
pub inline fn getIf(self: *const @This()) *S.If {
- return Data.Store.If.at(self.data.s_if);
+ return self.data.s_if;
}
pub inline fn getImport(self: *const @This()) *S.Import {
- return Data.Store.Import.at(self.data.s_import);
+ return self.data.s_import;
}
pub inline fn getLabel(self: *const @This()) *S.Label {
- return Data.Store.Label.at(self.data.s_label);
+ return self.data.s_label;
}
pub inline fn getLazyExport(self: *const @This()) *S.LazyExport {
- return Data.Store.LazyExport.at(self.data.s_lazy_export);
+ return self.data.s_lazy_export;
}
pub inline fn getLocal(self: *const @This()) *S.Local {
- return Data.Store.Local.at(self.data.s_local);
+ return self.data.s_local;
}
pub inline fn getNamespace(self: *const @This()) *S.Namespace {
- return Data.Store.Namespace.at(self.data.s_namespace);
+ return self.data.s_namespace;
}
pub inline fn getReturn(self: *const @This()) *S.Return {
- return Data.Store.Return.at(self.data.s_return);
+ return self.data.s_return;
}
pub inline fn getSwitch(self: *const @This()) *S.Switch {
- return Data.Store.Switch.at(self.data.s_switch);
+ return self.data.s_switch;
}
pub inline fn getThrow(self: *const @This()) *S.Throw {
- return Data.Store.Throw.at(self.data.s_throw);
+ return self.data.s_throw;
}
pub inline fn getTry(self: *const @This()) *S.Try {
- return Data.Store.Try.at(self.data.s_try);
+ return self.data.s_try;
}
pub inline fn getTypeScript(self: *const @This()) S.TypeScript {
return S.TypeScript{};
}
pub inline fn getWhile(self: *const @This()) *S.While {
- return Data.Store.While.at(self.data.s_while);
+ return self.data.s_while;
}
pub inline fn getWith(self: *const @This()) *S.With {
- return Data.Store.With.at(self.data.s_with);
+ return self.data.s_with;
}
pub var icount: usize = 0;
pub fn init(origData: anytype, loc: logger.Loc) Stmt {
@@ -1454,72 +1527,73 @@ pub const Stmt = struct {
};
pub const Data = union(Tag) {
- s_block: ListIndex,
- s_break: ListIndex,
- s_class: ListIndex,
- s_comment: ListIndex,
- s_continue: ListIndex,
- s_debugger: S.Debugger,
- s_directive: ListIndex,
- s_do_while: ListIndex,
- s_empty: S.Empty, // special case, its a zero value type
- s_enum: ListIndex,
- s_export_clause: ListIndex,
- s_export_default: ListIndex,
- s_export_equals: ListIndex,
- s_export_from: ListIndex,
- s_export_star: ListIndex,
- s_expr: ListIndex,
- s_for_in: ListIndex,
- s_for_of: ListIndex,
- s_for: ListIndex,
- s_function: ListIndex,
- s_if: ListIndex,
- s_import: ListIndex,
- s_label: ListIndex,
- s_lazy_export: ListIndex,
- s_local: ListIndex,
- s_namespace: ListIndex,
- s_return: ListIndex,
- s_switch: ListIndex,
- s_throw: ListIndex,
- s_try: ListIndex,
+ s_block: *S.Block,
+ s_break: *S.Break,
+ s_class: *S.Class,
+ s_comment: *S.Comment,
+ s_continue: *S.Continue,
+ s_directive: *S.Directive,
+ s_do_while: *S.DoWhile,
+ s_enum: *S.Enum,
+ s_export_clause: *S.ExportClause,
+ s_export_default: *S.ExportDefault,
+ s_export_equals: *S.ExportEquals,
+ s_export_from: *S.ExportFrom,
+ s_export_star: *S.ExportStar,
+ s_expr: *S.SExpr,
+ s_for_in: *S.ForIn,
+ s_for_of: *S.ForOf,
+ s_for: *S.For,
+ s_function: *S.Function,
+ s_if: *S.If,
+ s_import: *S.Import,
+ s_label: *S.Label,
+ s_lazy_export: *S.LazyExport,
+ s_local: *S.Local,
+ s_namespace: *S.Namespace,
+ s_return: *S.Return,
+ s_switch: *S.Switch,
+ s_throw: *S.Throw,
+ s_try: *S.Try,
+ s_while: *S.While,
+ s_with: *S.With,
+
s_type_script: S.TypeScript,
- s_while: ListIndex,
- s_with: ListIndex,
+ s_empty: S.Empty, // special case, its a zero value type
+ s_debugger: S.Debugger,
pub const Store = struct {
- pub const Block = NewStore(S.Block);
- pub const Break = NewStore(S.Break);
- pub const Class = NewStore(S.Class);
- pub const Comment = NewStore(S.Comment);
- pub const Continue = NewStore(S.Continue);
- pub const Directive = NewStore(S.Directive);
- pub const DoWhile = NewStore(S.DoWhile);
- pub const Enum = NewStore(S.Enum);
- pub const ExportClause = NewStore(S.ExportClause);
- pub const ExportDefault = NewStore(S.ExportDefault);
- pub const ExportEquals = NewStore(S.ExportEquals);
- pub const ExportFrom = NewStore(S.ExportFrom);
- pub const ExportStar = NewStore(S.ExportStar);
- pub const SExpr = NewStore(S.SExpr);
- pub const ForIn = NewStore(S.ForIn);
- pub const ForOf = NewStore(S.ForOf);
- pub const For = NewStore(S.For);
- pub const Function = NewStore(S.Function);
- pub const If = NewStore(S.If);
- pub const Import = NewStore(S.Import);
- pub const Label = NewStore(S.Label);
- pub const LazyExport = NewStore(S.LazyExport);
- pub const Local = NewStore(S.Local);
- pub const Namespace = NewStore(S.Namespace);
- pub const Return = NewStore(S.Return);
- pub const Switch = NewStore(S.Switch);
- pub const Throw = NewStore(S.Throw);
- pub const Try = NewStore(S.Try);
- pub const TypeScript = NewStore(S.TypeScript);
- pub const While = NewStore(S.While);
- pub const With = NewStore(S.With);
+ pub const Block = NewStore(S.Block, 24);
+ pub const Break = NewStore(S.Break, 24);
+ pub const Class = NewStore(S.Class, 24);
+ pub const Comment = NewStore(S.Comment, 24);
+ pub const Continue = NewStore(S.Continue, 24);
+ pub const Directive = NewStore(S.Directive, 24);
+ pub const DoWhile = NewStore(S.DoWhile, 24);
+ pub const Enum = NewStore(S.Enum, 24);
+ pub const ExportClause = NewStore(S.ExportClause, 24);
+ pub const ExportDefault = NewStore(S.ExportDefault, 24);
+ pub const ExportEquals = NewStore(S.ExportEquals, 24);
+ pub const ExportFrom = NewStore(S.ExportFrom, 24);
+ pub const ExportStar = NewStore(S.ExportStar, 24);
+ pub const SExpr = NewStore(S.SExpr, 24);
+ pub const ForIn = NewStore(S.ForIn, 24);
+ pub const ForOf = NewStore(S.ForOf, 24);
+ pub const For = NewStore(S.For, 24);
+ pub const Function = NewStore(S.Function, 24);
+ pub const If = NewStore(S.If, 24);
+ pub const Import = NewStore(S.Import, 24);
+ pub const Label = NewStore(S.Label, 24);
+ pub const LazyExport = NewStore(S.LazyExport, 24);
+ pub const Local = NewStore(S.Local, 24);
+ pub const Namespace = NewStore(S.Namespace, 24);
+ pub const Return = NewStore(S.Return, 24);
+ pub const Switch = NewStore(S.Switch, 24);
+ pub const Throw = NewStore(S.Throw, 24);
+ pub const Try = NewStore(S.Try, 24);
+ pub const TypeScript = NewStore(S.TypeScript, 24);
+ pub const While = NewStore(S.While, 24);
+ pub const With = NewStore(S.With, 24);
threadlocal var has_inited = false;
pub fn create(allocator: *std.mem.Allocator) void {
@@ -1593,7 +1667,7 @@ pub const Stmt = struct {
With.reset();
}
- pub fn append(comptime ValueType: type, value: anytype) ListIndex {
+ pub fn append(comptime ValueType: type, value: anytype) *ValueType {
switch (comptime ValueType) {
S.Block => {
return Block.append(value);
@@ -1695,76 +1769,6 @@ pub const Stmt = struct {
},
}
}
-
- pub fn NewStore(comptime ValueType: type) type {
- const count = 8096;
- const max_index = count - 1;
- const list_count = count;
- return struct {
- pub threadlocal var backing_buf: [count]ValueType = undefined;
- pub threadlocal var backing_buf_used: u16 = 0;
- const Allocator = std.mem.Allocator;
- const Self = @This();
- const NotFound = allocators.NotFound;
- const Unassigned = allocators.Unassigned;
-
- overflow_list: std.ArrayListUnmanaged(ValueType),
- allocator: *Allocator,
-
- pub threadlocal var instance: Self = undefined;
- pub threadlocal var self: *Self = undefined;
-
- pub fn reset() void {
- backing_buf_used = 0;
- self.overflow_list.items.len = 0;
- }
-
- pub fn init(allocator: *std.mem.Allocator) *Self {
- instance = Self{
- .allocator = allocator,
- .overflow_list = std.ArrayListUnmanaged(ValueType){},
- };
-
- self = &instance;
- return self;
- }
-
- pub fn isOverflowing() bool {
- return backing_buf_used >= @as(u16, count);
- }
-
- pub fn at(index: ListIndex) *ValueType {
- std.debug.assert(index.index != NotFound.index and index.index != Unassigned.index);
-
- if (index.is_overflowing) {
- return &self.overflow_list.items[index.index];
- } else {
- return &backing_buf[index.index];
- }
- }
-
- pub fn exists(value: ValueType) bool {
- return isSliceInBuffer(value, backing_buf);
- }
-
- pub fn append(value: ValueType) ListIndex {
- var result = ListIndex{ .index = std.math.maxInt(u31), .is_overflowing = backing_buf_used > max_index };
- if (result.is_overflowing) {
- result.index = @intCast(u31, self.overflow_list.items.len);
- self.overflow_list.append(self.allocator, value) catch unreachable;
- } else {
- result.index = backing_buf_used;
- backing_buf[result.index] = value;
- backing_buf_used += 1;
- if (backing_buf_used >= max_index and self.overflow_list.capacity == 0) {
- self.overflow_list = @TypeOf(self.overflow_list).initCapacity(self.allocator, 1) catch unreachable;
- }
- }
-
- return result;
- }
- };
- }
};
pub inline fn set(data: *Data, value: anytype) void {
@@ -1912,110 +1916,110 @@ pub const Expr = struct {
pub const Query = struct { expr: Expr, loc: logger.Loc };
pub fn getArray(exp: *const Expr) *E.Array {
- return Data.Store.Array.at(exp.data.e_array);
+ return exp.data.e_array;
}
pub fn getUnary(exp: *const Expr) *E.Unary {
- return Data.Store.Unary.at(exp.data.e_unary);
+ return exp.data.e_unary;
}
pub fn getBinary(exp: *const Expr) *E.Binary {
- return Data.Store.Binary.at(exp.data.e_binary);
+ return exp.data.e_binary;
}
pub fn getThis(exp: *const Expr) *E.This {
return E.This{};
}
pub fn getClass(exp: *const Expr) *E.Class {
- return Data.Store.Class.at(exp.data.e_class);
+ return exp.data.e_class;
}
pub fn getBoolean(exp: *const Expr) *E.Boolean {
- return Data.Store.Boolean.at(exp.data.e_boolean);
+ return exp.data.e_boolean;
}
pub fn getSuper(exp: *const Expr) *E.Super {
- return Data.Store.Super.at(exp.data.e_super);
+ return exp.data.e_super;
}
pub fn getNull(exp: *const Expr) *E.Null {
- return Data.Store.Null.at(exp.data.e_null);
+ return exp.data.e_null;
}
pub fn getUndefined(exp: *const Expr) *E.Undefined {
- return Data.Store.Undefined.at(exp.data.e_undefined);
+ return exp.data.e_undefined;
}
pub fn getNew(exp: *const Expr) *E.New {
- return Data.Store.New.at(exp.data.e_new);
+ return exp.data.e_new;
}
pub fn getNewTarget(exp: *const Expr) *E.NewTarget {
return &E.NewTarget{};
}
pub fn getFunction(exp: *const Expr) *E.Function {
- return Data.Store.Function.at(exp.data.e_function);
+ return exp.data.e_function;
}
pub fn getCall(exp: *const Expr) *E.Call {
- return Data.Store.Call.at(exp.data.e_call);
+ return exp.data.e_call;
}
pub fn getDot(exp: *const Expr) *E.Dot {
- return Data.Store.Dot.at(exp.data.e_dot);
+ return exp.data.e_dot;
}
pub fn getIndex(exp: *const Expr) *E.Index {
- return Data.Store.Index.at(exp.data.e_index);
+ return exp.data.e_index;
}
pub fn getArrow(exp: *const Expr) *E.Arrow {
- return Data.Store.Arrow.at(exp.data.e_arrow);
+ return exp.data.e_arrow;
}
pub fn getIdentifier(exp: *const Expr) *E.Identifier {
- return Data.Store.Identifier.at(exp.data.e_identifier);
+ return exp.data.e_identifier;
}
pub fn getImportIdentifier(exp: *const Expr) *E.ImportIdentifier {
- return Data.Store.ImportIdentifier.at(exp.data.e_import_identifier);
+ return exp.data.e_import_identifier;
}
pub fn getPrivateIdentifier(exp: *const Expr) *E.PrivateIdentifier {
- return Data.Store.PrivateIdentifier.at(exp.data.e_private_identifier);
+ return exp.data.e_private_identifier;
}
pub fn getJsxElement(exp: *const Expr) *E.JSXElement {
- return Data.Store.JSXElement.at(exp.data.e_jsx_element);
+ return exp.data.e_jsx_element;
}
pub fn getMissing(exp: *const Expr) *E.Missing {
- return Data.Store.Missing.at(exp.data.e_missing);
+ return exp.data.e_missing;
}
pub fn getNumber(exp: *const Expr) *E.Number {
- return Data.Store.Number.at(exp.data.e_number);
+ return exp.data.e_number;
}
pub fn getBigInt(exp: *const Expr) *E.BigInt {
- return Data.Store.BigInt.at(exp.data.e_big_int);
+ return exp.data.e_big_int;
}
pub fn getObject(exp: *const Expr) *E.Object {
- return Data.Store.Object.at(exp.data.e_object);
+ return exp.data.e_object;
}
pub fn getSpread(exp: *const Expr) *E.Spread {
- return Data.Store.Spread.at(exp.data.e_spread);
+ return exp.data.e_spread;
}
pub fn getString(exp: *const Expr) *E.String {
- return Data.Store.String.at(exp.data.e_string);
+ return exp.data.e_string;
}
pub fn getTemplatePart(exp: *const Expr) *E.TemplatePart {
- return Data.Store.TemplatePart.at(exp.data.e_template_part);
+ return exp.data.e_template_part;
}
pub fn getTemplate(exp: *const Expr) *E.Template {
- return Data.Store.Template.at(exp.data.e_template);
+ return exp.data.e_template;
}
pub fn getRegExp(exp: *const Expr) *E.RegExp {
- return Data.Store.RegExp.at(exp.data.e_reg_exp);
+ return exp.data.e_reg_exp;
}
pub fn getAwait(exp: *const Expr) *E.Await {
- return Data.Store.Await.at(exp.data.e_await);
+ return exp.data.e_await;
}
pub fn getYield(exp: *const Expr) *E.Yield {
- return Data.Store.Yield.at(exp.data.e_yield);
+ return exp.data.e_yield;
}
pub fn getIf(exp: *const Expr) *E.If {
- return Data.Store.If.at(exp.data.e_if);
+ return exp.data.e_if;
}
pub fn getRequire(exp: *const Expr) *E.Require {
- return Data.Store.Require.at(exp.data.e_require);
+ return exp.data.e_require;
}
pub fn getRequireOrRequireResolve(exp: *const Expr) *E.RequireOrRequireResolve {
- return Data.Store.RequireOrRequireResolve.at(exp.data.e_require_or_require_resolve);
+ return exp.data.e_require_or_require_resolve;
}
pub fn getImport(exp: *const Expr) *E.Import {
- return Data.Store.Import.at(exp.data.e_import);
+ return exp.data.e_import;
}
pub fn asProperty(expr: *const Expr, name: string) ?Query {
@@ -2108,7 +2112,7 @@ pub const Expr = struct {
return null;
}
- return [2]f64{ Expr.Data.Store.Number.at(left.e_number).value, Expr.Data.Store.Number.at(right.e_number).value };
+ return [2]f64{ left.e_number.value, right.e_number.value };
}
pub fn isAnonymousNamed(e: *Expr) bool {
@@ -3250,12 +3254,35 @@ pub const Expr = struct {
}
pub const Data = union(Tag) {
- e_array: ListIndex,
- e_unary: ListIndex,
- e_binary: ListIndex,
-
- e_class: ListIndex,
- e_boolean: ListIndex,
+ e_array: *E.Array,
+ e_unary: *E.Unary,
+ e_binary: *E.Binary,
+ e_class: *E.Class,
+ e_boolean: *E.Boolean,
+ e_new: *E.New,
+ e_function: *E.Function,
+ e_call: *E.Call,
+ e_dot: *E.Dot,
+ e_index: *E.Index,
+ e_arrow: *E.Arrow,
+ e_identifier: *E.Identifier,
+ e_import_identifier: *E.ImportIdentifier,
+ e_private_identifier: *E.PrivateIdentifier,
+ e_jsx_element: *E.JSXElement,
+ e_number: *E.Number,
+ e_big_int: *E.BigInt,
+ e_object: *E.Object,
+ e_spread: *E.Spread,
+ e_string: *E.String,
+ e_template_part: *E.TemplatePart,
+ e_template: *E.Template,
+ e_reg_exp: *E.RegExp,
+ e_await: *E.Await,
+ e_yield: *E.Yield,
+ e_if: *E.If,
+ e_require: *E.Require,
+ e_require_or_require_resolve: *E.RequireOrRequireResolve,
+ e_import: *E.Import,
e_missing: E.Missing,
e_this: E.This,
@@ -3263,71 +3290,42 @@ pub const Expr = struct {
e_null: E.Null,
e_undefined: E.Undefined,
e_new_target: E.NewTarget,
-
- e_new: ListIndex,
-
- e_function: ListIndex,
e_import_meta: E.ImportMeta,
- e_call: ListIndex,
- e_dot: ListIndex,
- e_index: ListIndex,
- e_arrow: ListIndex,
- e_identifier: ListIndex,
- e_import_identifier: ListIndex,
- e_private_identifier: ListIndex,
- e_jsx_element: ListIndex,
-
- e_number: ListIndex,
- e_big_int: ListIndex,
- e_object: ListIndex,
- e_spread: ListIndex,
- e_string: ListIndex,
- e_template_part: ListIndex,
- e_template: ListIndex,
- e_reg_exp: ListIndex,
- e_await: ListIndex,
- e_yield: ListIndex,
- e_if: ListIndex,
- e_require: ListIndex,
- e_require_or_require_resolve: ListIndex,
- e_import: ListIndex,
pub const Store = struct {
- pub const Array = NewStore(E.Array);
- pub const Unary = NewStore(E.Unary);
- pub const Binary = NewStore(E.Binary);
- pub const This = NewStore(E.This);
- pub const Class = NewStore(E.Class);
- pub const Boolean = NewStore(E.Boolean);
- pub const Super = NewStore(E.Super);
- pub const Null = NewStore(E.Null);
- pub const Undefined = NewStore(E.Undefined);
- pub const New = NewStore(E.New);
- pub const Function = NewStore(E.Function);
- pub const ImportMeta = NewStore(E.ImportMeta);
- pub const Call = NewStore(E.Call);
- pub const Dot = NewStore(E.Dot);
- pub const Index = NewStore(E.Index);
- pub const Arrow = NewStore(E.Arrow);
- pub const Identifier = NewStore(E.Identifier);
- pub const ImportIdentifier = NewStore(E.ImportIdentifier);
- pub const PrivateIdentifier = NewStore(E.PrivateIdentifier);
- pub const JSXElement = NewStore(E.JSXElement);
- pub const Missing = NewStore(E.Missing);
- pub const Number = NewStore(E.Number);
- pub const BigInt = NewStore(E.BigInt);
- pub const Object = NewStore(E.Object);
- pub const Spread = NewStore(E.Spread);
- pub const String = NewStore(E.String);
- pub const TemplatePart = NewStore(E.TemplatePart);
- pub const Template = NewStore(E.Template);
- pub const RegExp = NewStore(E.RegExp);
- pub const Await = NewStore(E.Await);
- pub const Yield = NewStore(E.Yield);
- pub const If = NewStore(E.If);
- pub const Require = NewStore(E.Require);
- pub const RequireOrRequireResolve = NewStore(E.RequireOrRequireResolve);
- pub const Import = NewStore(E.Import);
+ const often = 512;
+ const medium = 256;
+ const rare = 24;
+ pub const Array = NewStore(E.Array, 128);
+ pub const Unary = NewStore(E.Unary, 128);
+ pub const Binary = NewStore(E.Binary, 128);
+ pub const Class = NewStore(E.Class, 24);
+ pub const Boolean = NewStore(E.Boolean, 512);
+ pub const Super = NewStore(E.Super, 128);
+ pub const New = NewStore(E.New, 128);
+ pub const Function = NewStore(E.Function, 24);
+ pub const Call = NewStore(E.Call, often);
+ pub const Dot = NewStore(E.Dot, often);
+ pub const Index = NewStore(E.Index, 24);
+ pub const Arrow = NewStore(E.Arrow, 24);
+ pub const Identifier = NewStore(E.Identifier, 24);
+ pub const ImportIdentifier = NewStore(E.ImportIdentifier, 24);
+ pub const PrivateIdentifier = NewStore(E.PrivateIdentifier, 24);
+ pub const JSXElement = NewStore(E.JSXElement, 24);
+ pub const Number = NewStore(E.Number, 256);
+ pub const BigInt = NewStore(E.BigInt, 256);
+ pub const Object = NewStore(E.Object, 512);
+ pub const Spread = NewStore(E.Spread, 256);
+ pub const String = NewStore(E.String, 512);
+ pub const TemplatePart = NewStore(E.TemplatePart, 128);
+ pub const Template = NewStore(E.Template, 64);
+ pub const RegExp = NewStore(E.RegExp, 24);
+ pub const Await = NewStore(E.Await, 24);
+ pub const Yield = NewStore(E.Yield, 24);
+ pub const If = NewStore(E.If, 24);
+ pub const Require = NewStore(E.Require, 24);
+ pub const RequireOrRequireResolve = NewStore(E.RequireOrRequireResolve, 24);
+ pub const Import = NewStore(E.Import, 24);
threadlocal var has_inited = false;
pub fn create(allocator: *std.mem.Allocator) void {
@@ -3339,12 +3337,10 @@ pub const Expr = struct {
_ = Array.init(allocator);
_ = Unary.init(allocator);
_ = Binary.init(allocator);
- _ = This.init(allocator);
_ = Class.init(allocator);
_ = Boolean.init(allocator);
_ = New.init(allocator);
_ = Function.init(allocator);
- _ = ImportMeta.init(allocator);
_ = Call.init(allocator);
_ = Dot.init(allocator);
_ = Index.init(allocator);
@@ -3353,7 +3349,6 @@ pub const Expr = struct {
_ = ImportIdentifier.init(allocator);
_ = PrivateIdentifier.init(allocator);
_ = JSXElement.init(allocator);
- _ = Missing.init(allocator);
_ = Number.init(allocator);
_ = BigInt.init(allocator);
_ = Object.init(allocator);
@@ -3374,12 +3369,10 @@ pub const Expr = struct {
Array.reset();
Unary.reset();
Binary.reset();
- This.reset();
Class.reset();
Boolean.reset();
New.reset();
Function.reset();
- ImportMeta.reset();
Call.reset();
Dot.reset();
Index.reset();
@@ -3388,7 +3381,6 @@ pub const Expr = struct {
ImportIdentifier.reset();
PrivateIdentifier.reset();
JSXElement.reset();
- Missing.reset();
Number.reset();
BigInt.reset();
Object.reset();
@@ -3405,7 +3397,7 @@ pub const Expr = struct {
Import.reset();
}
- pub fn append(comptime ValueType: type, value: anytype) ListIndex {
+ pub fn append(comptime ValueType: type, value: anytype) *ValueType {
switch (comptime ValueType) {
E.Array => {
return Array.append(value);
@@ -3520,77 +3512,6 @@ pub const Expr = struct {
},
}
}
-
- pub fn NewStore(comptime ValueType: type) type {
- const count = 8096;
- const max_index = count - 1;
- const list_count = count;
- return struct {
- pub threadlocal var backing_buf: [count]ValueType = undefined;
- pub threadlocal var backing_buf_used: u16 = 0;
- const Allocator = std.mem.Allocator;
- const Self = @This();
- const NotFound = allocators.NotFound;
- const Unassigned = allocators.Unassigned;
-
- overflow_list: std.ArrayListUnmanaged(ValueType),
- allocator: *Allocator,
-
- pub threadlocal var instance: Self = undefined;
- pub threadlocal var self: *Self = undefined;
-
- pub fn reset() void {
- backing_buf_used = 0;
- self.overflow_list.shrinkRetainingCapacity(0);
- }
-
- pub fn init(allocator: *std.mem.Allocator) *Self {
- instance = Self{
- .allocator = allocator,
- .overflow_list = std.ArrayListUnmanaged(ValueType){},
- };
-
- self = &instance;
- return self;
- }
-
- pub fn isOverflowing() bool {
- return backing_buf_used >= @as(u16, count);
- }
-
- pub fn at(index: ListIndex) *ValueType {
- std.debug.assert(index.index != NotFound.index and index.index != Unassigned.index);
-
- if (index.is_overflowing) {
- return &self.overflow_list.items[index.index];
- } else {
- return &backing_buf[index.index];
- }
- }
-
- pub fn exists(value: ValueType) bool {
- return isSliceInBuffer(value, backing_buf);
- }
-
- pub fn append(value: ValueType) ListIndex {
- var result = ListIndex{ .index = std.math.maxInt(u31), .is_overflowing = backing_buf_used > max_index };
- if (result.is_overflowing) {
- result.index = @intCast(u31, self.overflow_list.items.len);
- self.overflow_list.append(self.allocator, value) catch unreachable;
- } else {
- result.index = backing_buf_used;
- backing_buf[result.index] = value;
- backing_buf_used += 1;
-
- if (backing_buf_used >= max_index and self.overflow_list.capacity == 0) {
- self.overflow_list = @TypeOf(self.overflow_list).initCapacity(self.allocator, 1) catch unreachable;
- }
- }
-
- return result;
- }
- };
- }
};
pub fn isBooleanValue(self: *Expr) bool {