mirror of
https://github.com/LadybirdBrowser/ladybird
synced 2026-04-30 11:37:16 +02:00
LibJS: Use simdjson for JSON.parse
Replace the custom AK JSON parser with simdjson for parsing JSON in LibJS. This eliminates the intermediate AK::JsonValue object graph, going directly from JSON text to JS::Value. simdjson's on-demand API parses at ~4GB/s and only materializes values as they are accessed, making this both faster and more memory efficient than the previous approach. The AK JSON parser is still used elsewhere (WebDriver protocol, config files, etc.) but LibJS now uses simdjson exclusively for JSON.parse() and JSON.rawJSON().
This commit is contained in:
Notes:
github-actions[bot]
2026-01-12 18:54:37 +00:00
Author: https://github.com/awesomekling Commit: https://github.com/LadybirdBrowser/ladybird/commit/5e0ee26e8be Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/7436 Reviewed-by: https://github.com/tcl3 ✅ Reviewed-by: https://github.com/trflynn89 ✅
@@ -74,3 +74,73 @@ test("does not truncate large integers", () => {
|
||||
expect(JSON.parse("18446744073709551616")).toEqual(18446744073709551616);
|
||||
expect(JSON.parse("18446744073709551617")).toEqual(18446744073709551617);
|
||||
});
|
||||
|
||||
test("number overflow to infinity", () => {
|
||||
expect(JSON.parse("1e309")).toBe(Infinity);
|
||||
expect(JSON.parse("-1e309")).toBe(-Infinity);
|
||||
expect(JSON.parse("1e-400")).toBe(0);
|
||||
});
|
||||
|
||||
test("rejects invalid number formats", () => {
|
||||
// Leading zeros not allowed
|
||||
expect(() => JSON.parse("01")).toThrow(SyntaxError);
|
||||
expect(() => JSON.parse("-01")).toThrow(SyntaxError);
|
||||
expect(() => JSON.parse("00")).toThrow(SyntaxError);
|
||||
expect(() => JSON.parse("007")).toThrow(SyntaxError);
|
||||
|
||||
// Trailing decimal point not allowed
|
||||
expect(() => JSON.parse("1.")).toThrow(SyntaxError);
|
||||
expect(() => JSON.parse("0.")).toThrow(SyntaxError);
|
||||
expect(() => JSON.parse("-1.")).toThrow(SyntaxError);
|
||||
|
||||
// Other invalid formats
|
||||
expect(() => JSON.parse("+1")).toThrow(SyntaxError);
|
||||
expect(() => JSON.parse(".1")).toThrow(SyntaxError);
|
||||
expect(() => JSON.parse("1e")).toThrow(SyntaxError);
|
||||
expect(() => JSON.parse("1e+")).toThrow(SyntaxError);
|
||||
expect(() => JSON.parse("1e-")).toThrow(SyntaxError);
|
||||
});
|
||||
|
||||
test("rejects trailing content", () => {
|
||||
expect(() => JSON.parse("123 garbage")).toThrow(SyntaxError);
|
||||
expect(() => JSON.parse("null garbage")).toThrow(SyntaxError);
|
||||
expect(() => JSON.parse("true garbage")).toThrow(SyntaxError);
|
||||
expect(() => JSON.parse('"string" garbage')).toThrow(SyntaxError);
|
||||
expect(() => JSON.parse("[] garbage")).toThrow(SyntaxError);
|
||||
expect(() => JSON.parse("{} garbage")).toThrow(SyntaxError);
|
||||
});
|
||||
|
||||
test("string escape sequences", () => {
|
||||
expect(JSON.parse('"\\""')).toBe('"');
|
||||
expect(JSON.parse('"\\\\"')).toBe("\\");
|
||||
expect(JSON.parse('"\\/"')).toBe("/");
|
||||
expect(JSON.parse('"\\b"')).toBe("\b");
|
||||
expect(JSON.parse('"\\f"')).toBe("\f");
|
||||
expect(JSON.parse('"\\n"')).toBe("\n");
|
||||
expect(JSON.parse('"\\r"')).toBe("\r");
|
||||
expect(JSON.parse('"\\t"')).toBe("\t");
|
||||
expect(JSON.parse('"\\u0041"')).toBe("A");
|
||||
expect(JSON.parse('"\\u0000"')).toBe("\0");
|
||||
});
|
||||
|
||||
test("unicode and surrogate pairs", () => {
|
||||
expect(JSON.parse('"café"')).toBe("café");
|
||||
expect(JSON.parse('"日本語"')).toBe("日本語");
|
||||
expect(JSON.parse('"\\uD83D\\uDE00"')).toBe("😀");
|
||||
expect(JSON.parse('"\\u4e2d\\u6587"')).toBe("中文");
|
||||
|
||||
// Lone surrogates (valid JSON)
|
||||
expect(JSON.parse('"\\uD800"')).toBe("\uD800");
|
||||
expect(JSON.parse('"\\uDFFF"')).toBe("\uDFFF");
|
||||
});
|
||||
|
||||
test("whitespace handling", () => {
|
||||
expect(JSON.parse(" null")).toBe(null);
|
||||
expect(JSON.parse("null ")).toBe(null);
|
||||
expect(JSON.parse(" null ")).toBe(null);
|
||||
expect(JSON.parse("\t123")).toBe(123);
|
||||
expect(JSON.parse("123\n")).toBe(123);
|
||||
expect(JSON.parse("\r\n123\r\n")).toBe(123);
|
||||
expect(JSON.parse(" { } ")).toEqual({});
|
||||
expect(JSON.parse(" [ ] ")).toEqual([]);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user