Skip to content

Commit df9e0f9

Browse files
mkustermannCommit Queue
authored andcommitted
[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 <[email protected]> Commit-Queue: Martin Kustermann <[email protected]>
1 parent c9e3c33 commit df9e0f9

File tree

3 files changed

+24
-12
lines changed

3 files changed

+24
-12
lines changed

pkg/dart2wasm/lib/compile.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,7 @@ Future<CompilationResult> compileToModule(
342342
final jsRuntime = isDynamicSubmodule
343343
? jsRuntimeFinalizer.generateDynamicSubmodule(
344344
translator.functions.translatedProcedures,
345+
translator.options.requireJsStringBuiltin,
345346
translator.internalizedStringsForJSRuntime)
346347
: jsRuntimeFinalizer.generate(
347348
translator.functions.translatedProcedures,

pkg/dart2wasm/lib/js/runtime_generator.dart

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -85,13 +85,23 @@ class RuntimeFinalizer {
8585
return jsMethods.toString();
8686
}
8787

88-
String _generateInternalizedStrings(List<String> constantStrings) {
89-
if (constantStrings.isEmpty) return '';
90-
return '''
91-
s: [
92-
${constantStrings.map(escape).join(',\n')}
93-
],
94-
''';
88+
String _generateInternalizedStrings(
89+
bool requireJsBuiltin, List<String> constantStrings) {
90+
final sb = StringBuffer();
91+
String indent = '';
92+
if (constantStrings.isNotEmpty) {
93+
sb.writeln('s: [');
94+
indent = ' ';
95+
for (final c in constantStrings) {
96+
sb.writeln('$indent ${escape(c)},');
97+
}
98+
sb.writeln('$indent],');
99+
}
100+
if (!requireJsBuiltin) {
101+
sb.writeln(
102+
'${indent}S: new Proxy({}, { get(_, prop) { return prop; } }),');
103+
}
104+
return '$sb';
95105
}
96106

97107
String generate(
@@ -106,7 +116,8 @@ class RuntimeFinalizer {
106116
if (requireJsBuiltin) 'importedStringConstants: \'S\'',
107117
];
108118

109-
String internalizedStrings = _generateInternalizedStrings(constantStrings);
119+
String internalizedStrings =
120+
_generateInternalizedStrings(requireJsBuiltin, constantStrings);
110121

111122
final jsStringBuiltinPolyfillImportVars = {
112123
'JS_POLYFILL_IMPORT':
@@ -135,14 +146,14 @@ class RuntimeFinalizer {
135146
});
136147
}
137148

138-
String generateDynamicSubmodule(
139-
Iterable<Procedure> translatedProcedures, List<String> constantStrings) {
149+
String generateDynamicSubmodule(Iterable<Procedure> translatedProcedures,
150+
bool requireJsStringBuiltin, List<String> constantStrings) {
140151
final jsMethods = generateJsMethods(translatedProcedures);
141152

142153
return dynamicSubmoduleJsImportTemplate.instantiate({
143154
'JS_METHODS': jsMethods,
144155
'IMPORTED_JS_STRINGS_IN_MJS':
145-
_generateInternalizedStrings(constantStrings),
156+
_generateInternalizedStrings(requireJsStringBuiltin, constantStrings),
146157
});
147158
}
148159
}

pkg/dart2wasm/lib/translator.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1803,7 +1803,7 @@ class Translator with KernelNodes {
18031803
return false;
18041804
}
18051805

1806-
if (!options.requireJsStringBuiltin || hasUnpairedSurrogate(s)) {
1806+
if (hasUnpairedSurrogate(s)) {
18071807
// Unpaired surrogates can't be encoded as UTF-8, import them from JS
18081808
// runtime.
18091809
final i = internalizedStringsForJSRuntime.length;

0 commit comments

Comments
 (0)