mirror of
https://github.com/dart-lang/sdk
synced 2024-10-06 13:57:58 +00:00
[dart2wasm] Optimize Dart->JS string conversion by specializing for OneByteString vs TwoByteString
Change-Id: Ia143312dc694a10fdaa778a57631bc98d14d9c7d Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/372484 Commit-Queue: Martin Kustermann <kustermann@google.com> Reviewed-by: Ömer Ağacan <omersa@google.com>
This commit is contained in:
parent
ef59500e6f
commit
5e12a4a79b
|
@ -2,7 +2,7 @@
|
|||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import 'dart:_internal' show patch;
|
||||
import 'dart:_internal' show patch, unsafeCast;
|
||||
import 'dart:_js_helper' show JS;
|
||||
import 'dart:_string';
|
||||
import 'dart:_wasm';
|
||||
|
@ -10,23 +10,42 @@ import 'dart:_wasm';
|
|||
@patch
|
||||
@pragma('wasm:prefer-inline')
|
||||
JSStringImpl jsStringFromDartString(String s) {
|
||||
if (s is JSStringImpl) return s;
|
||||
|
||||
return JSStringImpl(JS<WasmExternRef>(r'''
|
||||
if (s is OneByteString) {
|
||||
return JSStringImpl(JS<WasmExternRef>(r'''
|
||||
(s, length) => {
|
||||
let result = '';
|
||||
let index = 0;
|
||||
while (index < length) {
|
||||
let chunkLength = Math.min(length - index, 0xFFFF);
|
||||
const array = new Array(chunkLength);
|
||||
for (let i = 0; i < chunkLength; i++) {
|
||||
array[i] = dartInstance.exports.$stringRead(s, index++);
|
||||
}
|
||||
result += String.fromCharCode(...array);
|
||||
let result = '';
|
||||
let index = 0;
|
||||
while (index < length) {
|
||||
let chunkLength = Math.min(length - index, 0xFFFF);
|
||||
const array = new Array(chunkLength);
|
||||
for (let i = 0; i < chunkLength; i++) {
|
||||
array[i] = dartInstance.exports.$stringRead1(s, index++);
|
||||
}
|
||||
return result;
|
||||
result += String.fromCharCode(...array);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
''', jsObjectFromDartObject(s), s.length.toWasmI32()));
|
||||
}
|
||||
if (s is TwoByteString) {
|
||||
return JSStringImpl(JS<WasmExternRef>(r'''
|
||||
(s, length) => {
|
||||
let result = '';
|
||||
let index = 0;
|
||||
while (index < length) {
|
||||
let chunkLength = Math.min(length - index, 0xFFFF);
|
||||
const array = new Array(chunkLength);
|
||||
for (let i = 0; i < chunkLength; i++) {
|
||||
array[i] = dartInstance.exports.$stringRead2(s, index++);
|
||||
}
|
||||
result += String.fromCharCode(...array);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
''', jsObjectFromDartObject(s), s.length.toWasmI32()));
|
||||
}
|
||||
|
||||
return unsafeCast<JSStringImpl>(s);
|
||||
}
|
||||
|
||||
@patch
|
||||
|
@ -40,15 +59,45 @@ String jsStringToDartString(JSStringImpl s) => JS<String>(r'''
|
|||
if (range < 256) {
|
||||
const dartString = dartInstance.exports.$stringAllocate1(length);
|
||||
for (let i = 0; i < length; i++) {
|
||||
dartInstance.exports.$stringWrite1(dartString, i, s.codePointAt(i));
|
||||
dartInstance.exports.$stringWrite1(dartString, i, s.codePointAt(i));
|
||||
}
|
||||
return dartString;
|
||||
} else {
|
||||
const dartString = dartInstance.exports.$stringAllocate2(length);
|
||||
for (let i = 0; i < length; i++) {
|
||||
dartInstance.exports.$stringWrite2(dartString, i, s.charCodeAt(i));
|
||||
dartInstance.exports.$stringWrite2(dartString, i, s.charCodeAt(i));
|
||||
}
|
||||
return dartString;
|
||||
}
|
||||
}
|
||||
''', s.toExternRef, s.length.toWasmI32());
|
||||
|
||||
@pragma("wasm:export", "\$stringAllocate1")
|
||||
OneByteString _stringAllocate1(WasmI32 length) {
|
||||
return OneByteString.withLength(length.toIntSigned());
|
||||
}
|
||||
|
||||
@pragma("wasm:export", "\$stringRead1")
|
||||
WasmI32 _stringRead1(OneByteString string, WasmI32 index) {
|
||||
return string.codeUnitAtUnchecked(index.toIntSigned()).toWasmI32();
|
||||
}
|
||||
|
||||
@pragma("wasm:export", "\$stringWrite1")
|
||||
void _stringWrite1(OneByteString string, WasmI32 index, WasmI32 codePoint) {
|
||||
string.setUnchecked(index.toIntSigned(), codePoint.toIntSigned());
|
||||
}
|
||||
|
||||
@pragma("wasm:export", "\$stringAllocate2")
|
||||
TwoByteString _stringAllocate2(WasmI32 length) {
|
||||
return TwoByteString.withLength(length.toIntSigned());
|
||||
}
|
||||
|
||||
@pragma("wasm:export", "\$stringRead2")
|
||||
WasmI32 _stringRead2(TwoByteString string, WasmI32 index) {
|
||||
return string.codeUnitAtUnchecked(index.toIntSigned()).toWasmI32();
|
||||
}
|
||||
|
||||
@pragma("wasm:export", "\$stringWrite2")
|
||||
void _stringWrite2(TwoByteString string, WasmI32 index, WasmI32 codePoint) {
|
||||
string.setUnchecked(index.toIntSigned(), codePoint.toIntSigned());
|
||||
}
|
||||
|
|
|
@ -1638,35 +1638,3 @@ final class TwoByteString extends StringBase {
|
|||
return offset + length;
|
||||
}
|
||||
}
|
||||
|
||||
// String accessors used to perform Dart<->JS string conversion
|
||||
|
||||
@pragma("wasm:export", "\$stringLength")
|
||||
WasmI32 _stringLength(String string) {
|
||||
return string.length.toWasmI32();
|
||||
}
|
||||
|
||||
@pragma("wasm:export", "\$stringRead")
|
||||
WasmI32 _stringRead(String string, WasmI32 index) {
|
||||
return string.codeUnitAt(index.toIntSigned()).toWasmI32();
|
||||
}
|
||||
|
||||
@pragma("wasm:export", "\$stringAllocate1")
|
||||
OneByteString _stringAllocate1(WasmI32 length) {
|
||||
return OneByteString.withLength(length.toIntSigned());
|
||||
}
|
||||
|
||||
@pragma("wasm:export", "\$stringWrite1")
|
||||
void _stringWrite1(OneByteString string, WasmI32 index, WasmI32 codePoint) {
|
||||
string.setUnchecked(index.toIntSigned(), codePoint.toIntSigned());
|
||||
}
|
||||
|
||||
@pragma("wasm:export", "\$stringAllocate2")
|
||||
TwoByteString _stringAllocate2(WasmI32 length) {
|
||||
return TwoByteString.withLength(length.toIntSigned());
|
||||
}
|
||||
|
||||
@pragma("wasm:export", "\$stringWrite2")
|
||||
void _stringWrite2(TwoByteString string, WasmI32 index, WasmI32 codePoint) {
|
||||
string.setUnchecked(index.toIntSigned(), codePoint.toIntSigned());
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue