aboutsummaryrefslogtreecommitdiff
path: root/src/json_parser.zig
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <jarred@jarredsumner.com> 2021-09-23 21:43:37 -0700
committerGravatar Jarred Sumner <jarred@jarredsumner.com> 2021-09-23 21:43:37 -0700
commitff01dfa03da3b9cb17fe2797a7e5e096844e5ee6 (patch)
tree04f86518e18a42fe74e5a16033051b51a3ae7b9d /src/json_parser.zig
parent638b204d1ee38003e7ae1c8d1e3571003964ed30 (diff)
downloadbun-ff01dfa03da3b9cb17fe2797a7e5e096844e5ee6.tar.gz
bun-ff01dfa03da3b9cb17fe2797a7e5e096844e5ee6.tar.zst
bun-ff01dfa03da3b9cb17fe2797a7e5e096844e5ee6.zip
When bundling JSON, only use JSON.parse when the input is ASCII.
We don't want to add an extra pass over the input to convert it to UTF16. And JS engines storing strings as UTF-16 is more expensive anyway, so the runtime win here probably isn't as big (though open to evidence to the contrary!)
Diffstat (limited to 'src/json_parser.zig')
-rw-r--r--src/json_parser.zig38
1 files changed, 38 insertions, 0 deletions
diff --git a/src/json_parser.zig b/src/json_parser.zig
index 696b62325..5d65291a7 100644
--- a/src/json_parser.zig
+++ b/src/json_parser.zig
@@ -255,6 +255,44 @@ pub fn ParseJSON(source: *const logger.Source, log: *logger.Log, allocator: *std
return try parser.parseExpr(false);
}
+pub const JSONParseResult = struct {
+ expr: Expr,
+ tag: Tag,
+
+ pub const Tag = enum {
+ expr,
+ ascii,
+ empty,
+ };
+};
+
+pub fn ParseJSONForBundling(source: *const logger.Source, log: *logger.Log, allocator: *std.mem.Allocator) !JSONParseResult {
+ var parser = try JSONParser.init(allocator, source, log);
+ switch (source.contents.len) {
+ // This is to be consisntent with how disabled JS files are handled
+ 0 => {
+ return JSONParseResult{ .expr = Expr{ .loc = logger.Loc{ .start = 0 }, .data = empty_object_data }, .tag = .empty };
+ },
+ // This is a fast pass I guess
+ 2 => {
+ if (strings.eqlComptime(source.contents[0..1], "\"\"") or strings.eqlComptime(source.contents[0..1], "''")) {
+ return JSONParseResult{ .expr = Expr{ .loc = logger.Loc{ .start = 0 }, .data = empty_string_data }, .tag = .expr };
+ } else if (strings.eqlComptime(source.contents[0..1], "{}")) {
+ return JSONParseResult{ .expr = Expr{ .loc = logger.Loc{ .start = 0 }, .data = empty_object_data }, .tag = .expr };
+ } else if (strings.eqlComptime(source.contents[0..1], "[]")) {
+ return JSONParseResult{ .expr = Expr{ .loc = logger.Loc{ .start = 0 }, .data = empty_array_data }, .tag = .expr };
+ }
+ },
+ else => {},
+ }
+
+ const result = try parser.parseExpr(false);
+ return JSONParseResult{
+ .tag = if (parser.lexer.is_ascii_only) JSONParseResult.Tag.ascii else JSONParseResult.Tag.expr,
+ .expr = result,
+ };
+}
+
// threadlocal var env_json_auto_quote_buffer: MutableString = undefined;
// threadlocal var env_json_auto_quote_buffer_loaded: bool = false;
pub fn ParseEnvJSON(source: *const logger.Source, log: *logger.Log, allocator: *std.mem.Allocator) !Expr {