Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(175)

Side by Side Diff: pkg/compiler/lib/src/ssa/builder_kernel.dart

Issue 2404123002: Build CFG for various JS() foreign methods (Closed)
Patch Set: format Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 import 'package:kernel/ast.dart' as ir; 5 import 'package:kernel/ast.dart' as ir;
6 6
7 import '../common.dart'; 7 import '../common.dart';
8 import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem; 8 import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem;
9 import '../common/names.dart'; 9 import '../common/names.dart';
10 import '../common/tasks.dart' show CompilerTask; 10 import '../common/tasks.dart' show CompilerTask;
11 import '../compiler.dart'; 11 import '../compiler.dart';
12 import '../constants/values.dart' show StringConstantValue;
12 import '../dart_types.dart'; 13 import '../dart_types.dart';
13 import '../elements/elements.dart'; 14 import '../elements/elements.dart';
14 import '../io/source_information.dart'; 15 import '../io/source_information.dart';
16 import '../js/js.dart' as js;
15 import '../js_backend/backend.dart' show JavaScriptBackend; 17 import '../js_backend/backend.dart' show JavaScriptBackend;
16 import '../kernel/kernel.dart'; 18 import '../kernel/kernel.dart';
19 import '../native/native.dart' as native;
17 import '../resolution/tree_elements.dart'; 20 import '../resolution/tree_elements.dart';
18 import '../tree/dartstring.dart'; 21 import '../tree/dartstring.dart';
19 import '../tree/nodes.dart' show FunctionExpression, Node; 22 import '../tree/nodes.dart' show FunctionExpression, Node;
20 import '../types/masks.dart'; 23 import '../types/masks.dart';
21 import '../universe/call_structure.dart' show CallStructure; 24 import '../universe/call_structure.dart' show CallStructure;
22 import '../universe/selector.dart'; 25 import '../universe/selector.dart';
23 import '../universe/use.dart' show TypeUse; 26 import '../universe/use.dart' show TypeUse;
27 import '../universe/side_effects.dart' show SideEffects;
24 import 'graph_builder.dart'; 28 import 'graph_builder.dart';
25 import 'kernel_ast_adapter.dart'; 29 import 'kernel_ast_adapter.dart';
26 import 'kernel_string_builder.dart'; 30 import 'kernel_string_builder.dart';
27 import 'locals_handler.dart'; 31 import 'locals_handler.dart';
28 import 'loop_handler.dart'; 32 import 'loop_handler.dart';
29 import 'nodes.dart'; 33 import 'nodes.dart';
30 import 'ssa_branch_builder.dart'; 34 import 'ssa_branch_builder.dart';
31 import 'type_builder.dart'; 35 import 'type_builder.dart';
32 import 'types.dart' show TypeMaskFactory; 36 import 'types.dart' show TypeMaskFactory;
33 37
(...skipping 824 matching lines...) Expand 10 before | Expand all | Expand 10 after
858 @override 862 @override
859 void visitMapEntry(ir.MapEntry mapEntry) { 863 void visitMapEntry(ir.MapEntry mapEntry) {
860 // Visit value before the key because each will push an expression to the 864 // Visit value before the key because each will push an expression to the
861 // stack, so when we pop them off, the key is popped first, then the value. 865 // stack, so when we pop them off, the key is popped first, then the value.
862 mapEntry.value.accept(this); 866 mapEntry.value.accept(this);
863 mapEntry.key.accept(this); 867 mapEntry.key.accept(this);
864 } 868 }
865 869
866 @override 870 @override
867 void visitStaticGet(ir.StaticGet staticGet) { 871 void visitStaticGet(ir.StaticGet staticGet) {
868 var staticTarget = staticGet.target; 872 ir.Member staticTarget = staticGet.target;
869 if (staticTarget is ir.Procedure && 873 if (staticTarget is ir.Procedure &&
870 staticTarget.kind == ir.ProcedureKind.Getter) { 874 staticTarget.kind == ir.ProcedureKind.Getter) {
871 // Invoke the getter 875 // Invoke the getter
872 _pushStaticInvocation(staticTarget, const <HInstruction>[], 876 _pushStaticInvocation(staticTarget, const <HInstruction>[],
873 astAdapter.returnTypeOf(staticTarget)); 877 astAdapter.returnTypeOf(staticTarget));
878 } else if (staticTarget is ir.Field && staticTarget.isConst) {
879 assert(staticTarget.initializer != null);
880 stack.add(graph.addConstant(
881 astAdapter.getConstantFor(staticTarget.initializer), compiler));
874 } else { 882 } else {
875 push(new HStatic(astAdapter.getMember(staticTarget), 883 push(new HStatic(astAdapter.getMember(staticTarget),
876 astAdapter.inferredTypeOf(staticTarget))); 884 astAdapter.inferredTypeOf(staticTarget)));
877 } 885 }
878 } 886 }
879 887
880 @override 888 @override
881 void visitStaticSet(ir.StaticSet staticSet) { 889 void visitStaticSet(ir.StaticSet staticSet) {
882 staticSet.value.accept(this); 890 staticSet.value.accept(this);
883 HInstruction value = pop(); 891 HInstruction value = pop();
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
966 argument.value.accept(this); 974 argument.value.accept(this);
967 result.add(pop()); 975 result.add(pop());
968 } 976 }
969 977
970 return result; 978 return result;
971 } 979 }
972 980
973 @override 981 @override
974 void visitStaticInvocation(ir.StaticInvocation invocation) { 982 void visitStaticInvocation(ir.StaticInvocation invocation) {
975 ir.Procedure target = invocation.target; 983 ir.Procedure target = invocation.target;
984 if (astAdapter.isInForeignLibrary(target)) {
985 handleInvokeStaticForeign(invocation, target);
986 return;
987 }
976 TypeMask typeMask = astAdapter.returnTypeOf(target); 988 TypeMask typeMask = astAdapter.returnTypeOf(target);
977 989
978 List<HInstruction> arguments = _visitArguments(invocation.arguments); 990 List<HInstruction> arguments = _visitArguments(invocation.arguments);
979 991
980 _pushStaticInvocation(target, arguments, typeMask); 992 _pushStaticInvocation(target, arguments, typeMask);
981 } 993 }
982 994
995 void handleInvokeStaticForeign(
996 ir.StaticInvocation invocation, ir.Procedure target) {
997 String name = target.name.name;
998 if (name == 'JS') {
999 handleForeignJs(invocation);
1000 } else if (name == 'JS_CURRENT_ISOLATE_CONTEXT') {
1001 handleForeignJsCurrentIsolateContext(invocation);
1002 } else if (name == 'JS_CALL_IN_ISOLATE') {
1003 handleForeignJsCallInIsolate(invocation);
1004 } else if (name == 'DART_CLOSURE_TO_JS') {
1005 handleForeignDartClosureToJs(invocation, 'DART_CLOSURE_TO_JS');
1006 } else if (name == 'RAW_DART_FUNCTION_REF') {
1007 handleForeignRawFunctionRef(invocation, 'RAW_DART_FUNCTION_REF');
1008 } else if (name == 'JS_SET_STATIC_STATE') {
1009 handleForeignJsSetStaticState(invocation);
1010 } else if (name == 'JS_GET_STATIC_STATE') {
1011 handleForeignJsGetStaticState(invocation);
1012 } else if (name == 'JS_GET_NAME') {
1013 handleForeignJsGetName(invocation);
1014 } else if (name == 'JS_EMBEDDED_GLOBAL') {
1015 handleForeignJsEmbeddedGlobal(invocation);
1016 } else if (name == 'JS_BUILTIN') {
1017 handleForeignJsBuiltin(invocation);
1018 } else if (name == 'JS_GET_FLAG') {
1019 handleForeignJsGetFlag(invocation);
1020 } else if (name == 'JS_EFFECT') {
1021 stack.add(graph.addConstantNull(compiler));
1022 } else if (name == 'JS_INTERCEPTOR_CONSTANT') {
1023 handleJsInterceptorConstant(invocation);
1024 } else if (name == 'JS_STRING_CONCAT') {
1025 handleJsStringConcat(invocation);
1026 } else {
1027 compiler.reporter.internalError(
1028 astAdapter.getNode(invocation), "Unknown foreign: ${name}");
1029 }
1030 }
1031
1032 bool _unexpectedForeignArguments(
1033 ir.StaticInvocation invocation, int minPositional,
1034 [int maxPositional]) {
1035 String pluralizeArguments(int count) {
1036 if (count == 0) return 'no arguments';
1037 if (count == 1) return 'one argument';
1038 if (count == 2) return 'two arguments';
1039 return '$count arguments';
1040 }
1041
1042 String name() => invocation.target.name.name;
1043
1044 ir.Arguments arguments = invocation.arguments;
1045 bool bad = false;
1046 if (arguments.types.isNotEmpty) {
1047 compiler.reporter.reportErrorMessage(
1048 astAdapter.getNode(invocation),
1049 MessageKind.GENERIC,
1050 {'text': "Error: '${name()}' does not take type arguments."});
1051 bad = true;
1052 }
1053 if (arguments.positional.length < minPositional) {
1054 String phrase = pluralizeArguments(minPositional);
1055 if (maxPositional != minPositional) phrase = 'at least $phrase';
1056 compiler.reporter.reportErrorMessage(
1057 astAdapter.getNode(invocation),
1058 MessageKind.GENERIC,
1059 {'text': "Error: Too few arguments. '${name()}' takes $phrase."});
1060 bad = true;
1061 }
1062 if (maxPositional != null && arguments.positional.length > maxPositional) {
1063 String phrase = pluralizeArguments(maxPositional);
1064 if (maxPositional != minPositional) phrase = 'at most $phrase';
1065 compiler.reporter.reportErrorMessage(
1066 astAdapter.getNode(invocation),
1067 MessageKind.GENERIC,
1068 {'text': "Error: Too many arguments. '${name()}' takes $phrase."});
1069 bad = true;
1070 }
1071 if (arguments.named.isNotEmpty) {
1072 compiler.reporter.reportErrorMessage(
1073 astAdapter.getNode(invocation),
1074 MessageKind.GENERIC,
1075 {'text': "Error: '${name()}' does not take named arguments."});
1076 bad = true;
1077 }
1078 return bad;
1079 }
1080
1081 /// Returns the value of the string argument. The argument must evaluate to a
1082 /// constant. If there is an error, the error is reported and `null` is
1083 /// returned.
1084 String _foreignConstantStringArgument(
1085 ir.StaticInvocation invocation, int position, String methodName,
1086 [String adjective = '']) {
1087 ir.Expression argument = invocation.arguments.positional[position];
1088 argument.accept(this);
1089 HInstruction instruction = pop();
1090
1091 if (!instruction.isConstantString()) {
1092 compiler.reporter.reportErrorMessage(
1093 astAdapter.getNode(argument), MessageKind.GENERIC, {
1094 'text': "Error: Expected String constant as ${adjective}argument "
1095 "to '$methodName'."
1096 });
1097 return null;
1098 }
1099
1100 HConstant hConstant = instruction;
1101 StringConstantValue stringConstant = hConstant.constant;
1102 return stringConstant.primitiveValue.slowToString();
1103 }
1104
1105 // TODO(sra): Remove when handleInvokeStaticForeign fully implemented.
1106 void unhandledForeign(ir.StaticInvocation invocation) {
1107 ir.Procedure target = invocation.target;
1108 TypeMask typeMask = astAdapter.returnTypeOf(target);
1109 List<HInstruction> arguments = _visitArguments(invocation.arguments);
1110 _pushStaticInvocation(target, arguments, typeMask);
1111 }
1112
1113 void handleForeignJsCurrentIsolateContext(ir.StaticInvocation invocation) {
1114 if (_unexpectedForeignArguments(invocation, 0, 0)) {
1115 stack.add(graph.addConstantNull(compiler)); // Result expected on stack.
1116 return;
1117 }
1118
1119 if (!compiler.hasIsolateSupport) {
1120 // If the isolate library is not used, we just generate code
1121 // to fetch the static state.
1122 String name = backend.namer.staticStateHolder;
1123 push(new HForeignCode(
1124 js.js.parseForeignJS(name), backend.dynamicType, <HInstruction>[],
1125 nativeBehavior: native.NativeBehavior.DEPENDS_OTHER));
1126 } else {
1127 // Call a helper method from the isolate library. The isolate library uses
1128 // its own isolate structure that encapsulates the isolate structure used
1129 // for binding to methods.
1130 ir.Procedure target = astAdapter.currentIsolate;
1131 if (target == null) {
1132 compiler.reporter.internalError(astAdapter.getNode(invocation),
1133 'Isolate library and compiler mismatch.');
1134 }
1135 _pushStaticInvocation(target, <HInstruction>[], backend.dynamicType);
1136 }
1137
1138 /*
1139 if (!node.arguments.isEmpty) {
1140 reporter.internalError(
1141 node, 'Too many arguments to JS_CURRENT_ISOLATE_CONTEXT.');
1142 }
1143
1144 if (!compiler.hasIsolateSupport) {
1145 // If the isolate library is not used, we just generate code
1146 // to fetch the static state.
1147 String name = backend.namer.staticStateHolder;
1148 push(new HForeignCode(
1149 js.js.parseForeignJS(name), backend.dynamicType, <HInstruction>[],
1150 nativeBehavior: native.NativeBehavior.DEPENDS_OTHER));
1151 } else {
1152 // Call a helper method from the isolate library. The isolate
1153 // library uses its own isolate structure, that encapsulates
1154 // Leg's isolate.
1155 Element element = helpers.currentIsolate;
1156 if (element == null) {
1157 reporter.internalError(node, 'Isolate library and compiler mismatch.');
1158 }
1159 pushInvokeStatic(null, element, [], typeMask: backend.dynamicType);
1160 }
1161 */
1162 }
1163
1164 void handleForeignJsCallInIsolate(ir.StaticInvocation invocation) {
1165 unhandledForeign(invocation);
1166 }
1167
1168 void handleForeignDartClosureToJs(
1169 ir.StaticInvocation invocation, String name) {
1170 unhandledForeign(invocation);
1171 }
1172
1173 void handleForeignRawFunctionRef(
1174 ir.StaticInvocation invocation, String name) {
1175 unhandledForeign(invocation);
1176 }
1177
1178 void handleForeignJsSetStaticState(ir.StaticInvocation invocation) {
1179 if (_unexpectedForeignArguments(invocation, 0, 0)) {
1180 stack.add(graph.addConstantNull(compiler)); // Result expected on stack.
1181 return;
1182 }
1183 _visitArguments(invocation.arguments);
1184 String isolateName = backend.namer.staticStateHolder;
1185 SideEffects sideEffects = new SideEffects.empty();
1186 sideEffects.setAllSideEffects();
1187 push(new HForeignCode(js.js.parseForeignJS("$isolateName = #"),
1188 backend.dynamicType, <HInstruction>[pop()],
1189 nativeBehavior: native.NativeBehavior.CHANGES_OTHER,
1190 effects: sideEffects));
1191 }
1192
1193 void handleForeignJsGetStaticState(ir.StaticInvocation invocation) {
1194 if (_unexpectedForeignArguments(invocation, 0, 0)) {
1195 stack.add(graph.addConstantNull(compiler)); // Result expected on stack.
1196 return;
1197 }
1198
1199 push(new HForeignCode(js.js.parseForeignJS(backend.namer.staticStateHolder),
1200 backend.dynamicType, <HInstruction>[],
1201 nativeBehavior: native.NativeBehavior.DEPENDS_OTHER));
1202 }
1203
1204 void handleForeignJsGetName(ir.StaticInvocation invocation) {
1205 if (_unexpectedForeignArguments(invocation, 1, 1)) {
1206 stack.add(graph.addConstantNull(compiler)); // Result expected on stack.
1207 return;
1208 }
1209
1210 ir.Node argument = invocation.arguments.positional.first;
1211 argument.accept(this);
1212 HInstruction instruction = pop();
1213
1214 if (instruction is HConstant) {
1215 js.Name name =
1216 astAdapter.getNameForJsGetName(argument, instruction.constant);
1217 stack.add(graph.addConstantStringFromName(name, compiler));
1218 return;
1219 }
1220
1221 compiler.reporter.reportErrorMessage(
1222 astAdapter.getNode(argument),
1223 MessageKind.GENERIC,
1224 {'text': 'Error: Expected a JsGetName enum value.'});
1225 stack.add(graph.addConstantNull(compiler)); // Result expected on stack.
1226 }
1227
1228 void handleForeignJsEmbeddedGlobal(ir.StaticInvocation invocation) {
1229 if (_unexpectedForeignArguments(invocation, 2, 2)) {
1230 stack.add(graph.addConstantNull(compiler)); // Result expected on stack.
1231 return;
1232 }
1233 String globalName = _foreignConstantStringArgument(
1234 invocation, 1, 'JS_EMBEDDED_GLOBAL', 'second ');
1235 js.Template expr = js.js.expressionTemplateYielding(
1236 backend.emitter.generateEmbeddedGlobalAccess(globalName));
1237
1238 native.NativeBehavior nativeBehavior =
1239 astAdapter.getNativeBehavior(invocation);
1240 assert(invariant(astAdapter.getNode(invocation), nativeBehavior != null,
1241 message: "No NativeBehavior for $invocation"));
1242
1243 TypeMask ssaType = astAdapter.typeFromNativeBehavior(nativeBehavior);
1244 push(new HForeignCode(expr, ssaType, const <HInstruction>[],
1245 nativeBehavior: nativeBehavior));
1246 }
1247
1248 void handleForeignJsBuiltin(ir.StaticInvocation invocation) {
1249 if (_unexpectedForeignArguments(invocation, 2)) {
1250 stack.add(graph.addConstantNull(compiler)); // Result expected on stack.
1251 return;
1252 }
1253
1254 List<ir.Expression> arguments = invocation.arguments.positional;
1255 ir.Expression nameArgument = arguments[1];
1256
1257 nameArgument.accept(this);
1258 HInstruction instruction = pop();
1259
1260 js.Template template;
1261 if (instruction is HConstant) {
1262 template = astAdapter.getJsBuiltinTemplate(instruction.constant);
1263 }
1264 if (template == null) {
1265 compiler.reporter.reportErrorMessage(
1266 astAdapter.getNode(nameArgument),
1267 MessageKind.GENERIC,
1268 {'text': 'Error: Expected a JsBuiltin enum value.'});
1269 stack.add(graph.addConstantNull(compiler)); // Result expected on stack.
1270 return;
1271 }
1272
1273 List<HInstruction> inputs = <HInstruction>[];
1274 for (ir.Expression argument in arguments.skip(2)) {
1275 argument.accept(this);
1276 inputs.add(pop());
1277 }
1278
1279 native.NativeBehavior nativeBehavior =
1280 astAdapter.getNativeBehavior(invocation);
1281 assert(invariant(astAdapter.getNode(invocation), nativeBehavior != null,
1282 message: "No NativeBehavior for $invocation"));
1283
1284 TypeMask ssaType = astAdapter.typeFromNativeBehavior(nativeBehavior);
1285 push(new HForeignCode(template, ssaType, inputs,
1286 nativeBehavior: nativeBehavior));
1287 }
1288
1289 void handleForeignJsGetFlag(ir.StaticInvocation invocation) {
1290 if (_unexpectedForeignArguments(invocation, 1, 1)) {
1291 stack.add(
1292 graph.addConstantBool(false, compiler)); // Result expected on stack.
1293 return;
1294 }
1295 String name = _foreignConstantStringArgument(invocation, 0, 'JS_GET_FLAG');
1296 bool value = false;
1297 switch (name) {
1298 case 'MUST_RETAIN_METADATA':
1299 value = backend.mustRetainMetadata;
1300 break;
1301 case 'USE_CONTENT_SECURITY_POLICY':
1302 value = compiler.options.useContentSecurityPolicy;
1303 break;
1304 default:
1305 compiler.reporter.reportErrorMessage(
1306 astAdapter.getNode(invocation),
1307 MessageKind.GENERIC,
1308 {'text': 'Error: Unknown internal flag "$name".'});
1309 }
1310 stack.add(graph.addConstantBool(value, compiler));
1311 }
1312
1313 void handleJsInterceptorConstant(ir.StaticInvocation invocation) {
1314 unhandledForeign(invocation);
1315 }
1316
1317 void handleForeignJs(ir.StaticInvocation invocation) {
1318 if (_unexpectedForeignArguments(invocation, 2)) {
1319 stack.add(graph.addConstantNull(compiler)); // Result expected on stack.
1320 return;
1321 }
1322
1323 native.NativeBehavior nativeBehavior =
1324 astAdapter.getNativeBehavior(invocation);
1325 assert(invariant(astAdapter.getNode(invocation), nativeBehavior != null,
1326 message: "No NativeBehavior for $invocation"));
1327
1328 List<HInstruction> inputs = <HInstruction>[];
1329 for (ir.Expression argument in invocation.arguments.positional.skip(2)) {
1330 argument.accept(this);
1331 inputs.add(pop());
1332 }
1333
1334 if (nativeBehavior.codeTemplate.positionalArgumentCount != inputs.length) {
1335 compiler.reporter.reportErrorMessage(
1336 astAdapter.getNode(invocation), MessageKind.GENERIC, {
1337 'text': 'Mismatch between number of placeholders'
1338 ' and number of arguments.'
1339 });
1340 stack.add(graph.addConstantNull(compiler)); // Result expected on stack.
1341 return;
1342 }
1343
1344 if (native.HasCapturedPlaceholders.check(nativeBehavior.codeTemplate.ast)) {
1345 compiler.reporter.reportErrorMessage(
1346 astAdapter.getNode(invocation), MessageKind.JS_PLACEHOLDER_CAPTURE);
1347 }
1348
1349 TypeMask ssaType = astAdapter.typeFromNativeBehavior(nativeBehavior);
1350
1351 SourceInformation sourceInformation = null;
1352 push(new HForeignCode(nativeBehavior.codeTemplate, ssaType, inputs,
1353 isStatement: !nativeBehavior.codeTemplate.isExpression,
1354 effects: nativeBehavior.sideEffects,
1355 nativeBehavior: nativeBehavior)..sourceInformation = sourceInformation);
1356 }
1357
1358 void handleJsStringConcat(ir.StaticInvocation invocation) {
1359 if (_unexpectedForeignArguments(invocation, 2, 2)) {
1360 stack.add(graph.addConstantNull(compiler)); // Result expected on stack.
1361 return;
1362 }
1363 List<HInstruction> inputs = _visitArguments(invocation.arguments);
1364 push(new HStringConcat(inputs[0], inputs[1], backend.stringType));
1365 }
1366
983 void _pushStaticInvocation( 1367 void _pushStaticInvocation(
984 ir.Node target, List<HInstruction> arguments, TypeMask typeMask) { 1368 ir.Node target, List<HInstruction> arguments, TypeMask typeMask) {
985 HInvokeStatic instruction = new HInvokeStatic( 1369 HInvokeStatic instruction = new HInvokeStatic(
986 astAdapter.getMember(target), arguments, typeMask, 1370 astAdapter.getMember(target), arguments, typeMask,
987 targetCanThrow: astAdapter.getCanThrow(target)); 1371 targetCanThrow: astAdapter.getCanThrow(target));
988 if (currentImplicitInstantiations.isNotEmpty) { 1372 if (currentImplicitInstantiations.isNotEmpty) {
989 instruction.instantiatedTypes = 1373 instruction.instantiatedTypes =
990 new List<DartType>.from(currentImplicitInstantiations); 1374 new List<DartType>.from(currentImplicitInstantiations);
991 } 1375 }
992 instruction.sideEffects = astAdapter.getSideEffects(target); 1376 instruction.sideEffects = astAdapter.getSideEffects(target);
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
1123 push(new HNot(popBoolified(), backend.boolType)); 1507 push(new HNot(popBoolified(), backend.boolType));
1124 } 1508 }
1125 1509
1126 @override 1510 @override
1127 void visitStringConcatenation(ir.StringConcatenation stringConcat) { 1511 void visitStringConcatenation(ir.StringConcatenation stringConcat) {
1128 KernelStringBuilder stringBuilder = new KernelStringBuilder(this); 1512 KernelStringBuilder stringBuilder = new KernelStringBuilder(this);
1129 stringConcat.accept(stringBuilder); 1513 stringConcat.accept(stringBuilder);
1130 stack.add(stringBuilder.result); 1514 stack.add(stringBuilder.result);
1131 } 1515 }
1132 } 1516 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/kernel/kernel_visitor.dart ('k') | pkg/compiler/lib/src/ssa/kernel_ast_adapter.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698