Found while validating #5039 / PR #5045 (the gap test had to compare char codes instead of JSON output).
Repro
console.log(JSON.stringify('a' + String.fromCharCode(12) + 'b' + String.fromCharCode(8) + 'c'));
Actual (Perry)
Perry emits the generic 4-hex-digit unicode escape for U+000C (formfeed) and U+0008 (backspace): the output is "a + backslash-u000c + b + backslash-u0008 + c".
Expected (Node, per ECMA-262 QuoteJSONString)
Node uses the two-character short forms: "a + backslash-f + b + backslash-b + c".
QuoteJSONString defines short forms for backspace, tab, newline, formfeed, and carriage return. Perry uses them for tab/newline/CR but falls back to the 4-hex-digit escape for backspace and formfeed. Both parse back identically, so this is a formatting-only divergence — but it breaks byte-for-byte parity comparisons and snapshot tests.
Found while validating #5039 / PR #5045 (the gap test had to compare char codes instead of JSON output).
Repro
Actual (Perry)
Perry emits the generic 4-hex-digit unicode escape for U+000C (formfeed) and U+0008 (backspace): the output is
"a+ backslash-u000c +b+ backslash-u0008 +c".Expected (Node, per ECMA-262 QuoteJSONString)
Node uses the two-character short forms:
"a+ backslash-f +b+ backslash-b +c".QuoteJSONStringdefines short forms for backspace, tab, newline, formfeed, and carriage return. Perry uses them for tab/newline/CR but falls back to the 4-hex-digit escape for backspace and formfeed. Both parse back identically, so this is a formatting-only divergence — but it breaks byte-for-byte parity comparisons and snapshot tests.