[dart2wasm] Use polyfill for string constants if builtin isn't available
This makes us always emit strings into the `<app>.wasm` module only.
If the runtime doesn't support `js-string` builtin (and we
don't have `--require-js-string` builtin flag on) then we use a
JS Proxy object to resolve the string imports.
Now we only emit string constants in the `<app>.mjs` file iff those
cannot be encoded in the `<app>.wasm` file due to being invalid
utf-8 (such as unpaired surrogates, ...)
Change-Id: I7f4a0d61238e847c0c7dccadfa9e473f76512dc1
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/426462
Reviewed-by: Slava Egorov <vegorov@google.com>
Commit-Queue: Martin Kustermann <kustermann@google.com>
diff --git a/pkg/dart2wasm/lib/compile.dart b/pkg/dart2wasm/lib/compile.dart
index edc6fd4..c0fbc32 100644
--- a/pkg/dart2wasm/lib/compile.dart
+++ b/pkg/dart2wasm/lib/compile.dart
@@ -342,6 +342,7 @@
final jsRuntime = isDynamicSubmodule
? jsRuntimeFinalizer.generateDynamicSubmodule(
translator.functions.translatedProcedures,
+ translator.options.requireJsStringBuiltin,
translator.internalizedStringsForJSRuntime)
: jsRuntimeFinalizer.generate(
translator.functions.translatedProcedures,
diff --git a/pkg/dart2wasm/lib/js/runtime_generator.dart b/pkg/dart2wasm/lib/js/runtime_generator.dart
index d425a93..b3c7a36 100644
--- a/pkg/dart2wasm/lib/js/runtime_generator.dart
+++ b/pkg/dart2wasm/lib/js/runtime_generator.dart
@@ -85,13 +85,23 @@
return jsMethods.toString();
}
- String _generateInternalizedStrings(List<String> constantStrings) {
- if (constantStrings.isEmpty) return '';
- return '''
- s: [
- ${constantStrings.map(escape).join(',\n')}
- ],
-''';
+ String _generateInternalizedStrings(
+ bool requireJsBuiltin, List<String> constantStrings) {
+ final sb = StringBuffer();
+ String indent = '';
+ if (constantStrings.isNotEmpty) {
+ sb.writeln('s: [');
+ indent = ' ';
+ for (final c in constantStrings) {
+ sb.writeln('$indent ${escape(c)},');
+ }
+ sb.writeln('$indent],');
+ }
+ if (!requireJsBuiltin) {
+ sb.writeln(
+ '${indent}S: new Proxy({}, { get(_, prop) { return prop; } }),');
+ }
+ return '$sb';
}
String generate(
@@ -106,7 +116,8 @@
if (requireJsBuiltin) 'importedStringConstants: \'S\'',
];
- String internalizedStrings = _generateInternalizedStrings(constantStrings);
+ String internalizedStrings =
+ _generateInternalizedStrings(requireJsBuiltin, constantStrings);
final jsStringBuiltinPolyfillImportVars = {
'JS_POLYFILL_IMPORT':
@@ -135,14 +146,14 @@
});
}
- String generateDynamicSubmodule(
- Iterable<Procedure> translatedProcedures, List<String> constantStrings) {
+ String generateDynamicSubmodule(Iterable<Procedure> translatedProcedures,
+ bool requireJsStringBuiltin, List<String> constantStrings) {
final jsMethods = generateJsMethods(translatedProcedures);
return dynamicSubmoduleJsImportTemplate.instantiate({
'JS_METHODS': jsMethods,
'IMPORTED_JS_STRINGS_IN_MJS':
- _generateInternalizedStrings(constantStrings),
+ _generateInternalizedStrings(requireJsStringBuiltin, constantStrings),
});
}
}
diff --git a/pkg/dart2wasm/lib/translator.dart b/pkg/dart2wasm/lib/translator.dart
index d43b4b7..87cd2c9 100644
--- a/pkg/dart2wasm/lib/translator.dart
+++ b/pkg/dart2wasm/lib/translator.dart
@@ -1803,7 +1803,7 @@
return false;
}
- if (!options.requireJsStringBuiltin || hasUnpairedSurrogate(s)) {
+ if (hasUnpairedSurrogate(s)) {
// Unpaired surrogates can't be encoded as UTF-8, import them from JS
// runtime.
final i = internalizedStringsForJSRuntime.length;