mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 15:42:20 +00:00
[dart2wasm] Port VM JSON decoding improvements
This ports https://dart-review.googlesource.com/c/sdk/+/358445 to dart2wasm. The only difference from the VM patch is that we use `U8List` instead of `Uint8List` for the chunk type in `_JsonUtf8Parser`, to avoid parsing slow dart2wasm `Uint8List` subclasses (`JSUint8ArrayImpl`, `_SlowU8List`). Benchmarks: https://golem.corp.goog/Revision?repository=dart&revision=110551&patch=19217 Change-Id: I2af7131e72014587e97bab09e80e920c445b2c32 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/370820 Commit-Queue: Ömer Ağacan <omersa@google.com> Reviewed-by: Martin Kustermann <kustermann@google.com>
This commit is contained in:
parent
4796b25a30
commit
e7d3b7820a
|
@ -48,9 +48,7 @@ class _JsonUtf8Decoder extends Converter<List<int>, Object?> {
|
||||||
|
|
||||||
Object? convert(List<int> input) {
|
Object? convert(List<int> input) {
|
||||||
var parser = _JsonUtf8DecoderSink._createParser(_reviver, _allowMalformed);
|
var parser = _JsonUtf8DecoderSink._createParser(_reviver, _allowMalformed);
|
||||||
parser.chunk = input;
|
parser.parseChunk(input, 0, input.length);
|
||||||
parser.chunkEnd = input.length;
|
|
||||||
parser.parse(0);
|
|
||||||
parser.close();
|
parser.close();
|
||||||
return parser.result;
|
return parser.result;
|
||||||
}
|
}
|
||||||
|
@ -238,6 +236,11 @@ class _NumberBuffer {
|
||||||
double parseDouble() => double.parse(getString());
|
double parseDouble() => double.parse(getString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
abstract class _JsonParserWithListener {
|
||||||
|
final _JsonListener listener;
|
||||||
|
_JsonParserWithListener(this.listener);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Chunked JSON parser.
|
* Chunked JSON parser.
|
||||||
*
|
*
|
||||||
|
@ -245,8 +248,13 @@ class _NumberBuffer {
|
||||||
* and stores input state between chunks.
|
* and stores input state between chunks.
|
||||||
*
|
*
|
||||||
* Implementations include [String] and UTF-8 parsers.
|
* Implementations include [String] and UTF-8 parsers.
|
||||||
|
*
|
||||||
|
* Note: this is a mixin instead of the base class to allow compilers
|
||||||
|
* to specialize applications otherwise accessing chunk characters becomes
|
||||||
|
* polymorphic.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
abstract class _ChunkedJsonParser<T> {
|
mixin _ChunkedJsonParser<T> on _JsonParserWithListener {
|
||||||
// A simple non-recursive state-based parser for JSON.
|
// A simple non-recursive state-based parser for JSON.
|
||||||
//
|
//
|
||||||
// Literal values accepted in states ARRAY_EMPTY, ARRAY_COMMA, OBJECT_COLON
|
// Literal values accepted in states ARRAY_EMPTY, ARRAY_COMMA, OBJECT_COLON
|
||||||
|
@ -377,8 +385,6 @@ abstract class _ChunkedJsonParser<T> {
|
||||||
// Mask used to mask off two lower bits.
|
// Mask used to mask off two lower bits.
|
||||||
static const int TWO_BIT_MASK = 3;
|
static const int TWO_BIT_MASK = 3;
|
||||||
|
|
||||||
final _JsonListener listener;
|
|
||||||
|
|
||||||
// The current parsing state.
|
// The current parsing state.
|
||||||
int state = STATE_INITIAL;
|
int state = STATE_INITIAL;
|
||||||
List<int> states = <int>[];
|
List<int> states = <int>[];
|
||||||
|
@ -429,8 +435,6 @@ abstract class _ChunkedJsonParser<T> {
|
||||||
*/
|
*/
|
||||||
dynamic buffer = null;
|
dynamic buffer = null;
|
||||||
|
|
||||||
_ChunkedJsonParser(this.listener);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Push the current parse [state] on a stack.
|
* Push the current parse [state] on a stack.
|
||||||
*
|
*
|
||||||
|
@ -1368,7 +1372,8 @@ abstract class _ChunkedJsonParser<T> {
|
||||||
/**
|
/**
|
||||||
* Chunked JSON parser that parses [String] chunks.
|
* Chunked JSON parser that parses [String] chunks.
|
||||||
*/
|
*/
|
||||||
class _JsonStringParser extends _ChunkedJsonParser<String> {
|
class _JsonStringParser extends _JsonParserWithListener
|
||||||
|
with _ChunkedJsonParser<String> {
|
||||||
String chunk = '';
|
String chunk = '';
|
||||||
int chunkEnd = 0;
|
int chunkEnd = 0;
|
||||||
|
|
||||||
|
@ -1465,11 +1470,12 @@ class _JsonStringDecoderSink extends StringConversionSinkBase {
|
||||||
/**
|
/**
|
||||||
* Chunked JSON parser that parses UTF-8 chunks.
|
* Chunked JSON parser that parses UTF-8 chunks.
|
||||||
*/
|
*/
|
||||||
class _JsonUtf8Parser extends _ChunkedJsonParser<List<int>> {
|
class _JsonUtf8Parser extends _JsonParserWithListener
|
||||||
|
with _ChunkedJsonParser<U8List> {
|
||||||
static final U8List emptyChunk = U8List(0);
|
static final U8List emptyChunk = U8List(0);
|
||||||
|
|
||||||
final _Utf8Decoder decoder;
|
final _Utf8Decoder decoder;
|
||||||
List<int> chunk = emptyChunk;
|
U8List chunk = emptyChunk;
|
||||||
int chunkEnd = 0;
|
int chunkEnd = 0;
|
||||||
|
|
||||||
_JsonUtf8Parser(_JsonListener listener, bool allowMalformed)
|
_JsonUtf8Parser(_JsonListener listener, bool allowMalformed)
|
||||||
|
@ -1480,6 +1486,21 @@ class _JsonUtf8Parser extends _ChunkedJsonParser<List<int>> {
|
||||||
_ChunkedJsonParser.PARTIAL_KEYWORD | _ChunkedJsonParser.KWD_BOM;
|
_ChunkedJsonParser.PARTIAL_KEYWORD | _ChunkedJsonParser.KWD_BOM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void parseChunk(List<int> value, int start, int end) {
|
||||||
|
if (value is U8List) {
|
||||||
|
chunk = value;
|
||||||
|
} else {
|
||||||
|
final bytes = U8List(end - start);
|
||||||
|
bytes.setRange(0, bytes.length, value, start);
|
||||||
|
end = bytes.length;
|
||||||
|
start = 0;
|
||||||
|
chunk = bytes;
|
||||||
|
}
|
||||||
|
chunkEnd = end;
|
||||||
|
parse(start);
|
||||||
|
}
|
||||||
|
|
||||||
|
@pragma('wasm:prefer-inline')
|
||||||
int getChar(int position) => chunk[position];
|
int getChar(int position) => chunk[position];
|
||||||
|
|
||||||
String getString(int start, int end, int bits) {
|
String getString(int start, int end, int bits) {
|
||||||
|
@ -1558,9 +1579,7 @@ class _JsonUtf8DecoderSink extends ByteConversionSink {
|
||||||
}
|
}
|
||||||
|
|
||||||
void _addChunk(List<int> chunk, int start, int end) {
|
void _addChunk(List<int> chunk, int start, int end) {
|
||||||
_parser.chunk = chunk;
|
_parser.parseChunk(chunk, start, end);
|
||||||
_parser.chunkEnd = end;
|
|
||||||
_parser.parse(start);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void close() {
|
void close() {
|
||||||
|
|
Loading…
Reference in a new issue