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

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

Issue 2563443007: Reduce use of Compiler.closedWorld (Closed)
Patch Set: Created 4 years 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
« no previous file with comments | « pkg/compiler/lib/src/native/ssa.dart ('k') | pkg/compiler/lib/src/ssa/builder_kernel.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 'dart:collection'; 5 import 'dart:collection';
6 6
7 import 'package:js_runtime/shared/embedded_names.dart'; 7 import 'package:js_runtime/shared/embedded_names.dart';
8 8
9 import '../closure.dart'; 9 import '../closure.dart';
10 import '../common.dart'; 10 import '../common.dart';
(...skipping 423 matching lines...) Expand 10 before | Expand all | Expand 10 after
434 if (compiler.options.disableInlining) return false; 434 if (compiler.options.disableInlining) return false;
435 435
436 assert(invariant( 436 assert(invariant(
437 currentNode != null ? currentNode : element, 437 currentNode != null ? currentNode : element,
438 selector != null || 438 selector != null ||
439 Elements.isStaticOrTopLevel(element) || 439 Elements.isStaticOrTopLevel(element) ||
440 element.isGenerativeConstructorBody, 440 element.isGenerativeConstructorBody,
441 message: "Missing selector for inlining of $element.")); 441 message: "Missing selector for inlining of $element."));
442 if (selector != null) { 442 if (selector != null) {
443 if (!selector.applies(function)) return false; 443 if (!selector.applies(function)) return false;
444 if (mask != null && 444 if (mask != null && !mask.canHit(function, selector, closedWorld)) {
445 !mask.canHit(function, selector, compiler.closedWorld)) {
446 return false; 445 return false;
447 } 446 }
448 } 447 }
449 448
450 if (backend.isJsInterop(element)) return false; 449 if (backend.isJsInterop(element)) return false;
451 450
452 // Don't inline operator== methods if the parameter can be null. 451 // Don't inline operator== methods if the parameter can be null.
453 if (element.name == '==') { 452 if (element.name == '==') {
454 if (element.enclosingClass != coreClasses.objectClass && 453 if (element.enclosingClass != coreClasses.objectClass &&
455 providedArguments[1].canBeNull()) { 454 providedArguments[1].canBeNull()) {
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
560 } 559 }
561 560
562 void doInlining() { 561 void doInlining() {
563 // Add an explicit null check on the receiver before doing the 562 // Add an explicit null check on the receiver before doing the
564 // inlining. We use [element] to get the same name in the 563 // inlining. We use [element] to get the same name in the
565 // NoSuchMethodError message as if we had called it. 564 // NoSuchMethodError message as if we had called it.
566 if (element.isInstanceMember && 565 if (element.isInstanceMember &&
567 !element.isGenerativeConstructorBody && 566 !element.isGenerativeConstructorBody &&
568 (mask == null || mask.isNullable)) { 567 (mask == null || mask.isNullable)) {
569 addWithPosition( 568 addWithPosition(
570 new HFieldGet(null, providedArguments[0], backend.dynamicType, 569 new HFieldGet(null, providedArguments[0], commonMasks.dynamicType,
571 isAssignable: false), 570 isAssignable: false),
572 currentNode); 571 currentNode);
573 } 572 }
574 List<HInstruction> compiledArguments = completeSendArgumentsList( 573 List<HInstruction> compiledArguments = completeSendArgumentsList(
575 function, selector, providedArguments, currentNode); 574 function, selector, providedArguments, currentNode);
576 enterInlinedMethod(function, functionResolvedAst, compiledArguments, 575 enterInlinedMethod(function, functionResolvedAst, compiledArguments,
577 instanceType: instanceType); 576 instanceType: instanceType);
578 inlinedFrom(functionResolvedAst, () { 577 inlinedFrom(functionResolvedAst, () {
579 if (!isReachable) { 578 if (!isReachable) {
580 emitReturn(graph.addConstantNull(compiler), null); 579 emitReturn(graph.addConstantNull(compiler), null);
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
678 return graph.addConstant(getConstantForNode(node), compiler); 677 return graph.addConstant(getConstantForNode(node), compiler);
679 } 678 }
680 679
681 /** 680 /**
682 * Documentation wanted -- johnniwinther 681 * Documentation wanted -- johnniwinther
683 * 682 *
684 * Invariant: [functionElement] must be an implementation element. 683 * Invariant: [functionElement] must be an implementation element.
685 */ 684 */
686 HGraph buildMethod(FunctionElement functionElement) { 685 HGraph buildMethod(FunctionElement functionElement) {
687 assert(invariant(functionElement, functionElement.isImplementation)); 686 assert(invariant(functionElement, functionElement.isImplementation));
688 graph.calledInLoop = compiler.closedWorld.isCalledInLoop(functionElement); 687 graph.calledInLoop = closedWorld.isCalledInLoop(functionElement);
689 ast.FunctionExpression function = resolvedAst.node; 688 ast.FunctionExpression function = resolvedAst.node;
690 assert(function != null); 689 assert(function != null);
691 assert(elements.getFunctionDefinition(function) != null); 690 assert(elements.getFunctionDefinition(function) != null);
692 openFunction(functionElement, function); 691 openFunction(functionElement, function);
693 String name = functionElement.name; 692 String name = functionElement.name;
694 if (backend.isJsInterop(functionElement)) { 693 if (backend.isJsInterop(functionElement)) {
695 push(invokeJsInteropFunction(functionElement, parameters.values.toList(), 694 push(invokeJsInteropFunction(functionElement, parameters.values.toList(),
696 sourceInformationBuilder.buildGeneric(function))); 695 sourceInformationBuilder.buildGeneric(function)));
697 var value = pop(); 696 var value = pop();
698 closeAndGotoExit(new HReturn( 697 closeAndGotoExit(new HReturn(
699 value, sourceInformationBuilder.buildReturn(functionElement.node))); 698 value, sourceInformationBuilder.buildReturn(functionElement.node)));
700 return closeFunction(); 699 return closeFunction();
701 } 700 }
702 assert(invariant(functionElement, !function.modifiers.isExternal)); 701 assert(invariant(functionElement, !function.modifiers.isExternal));
703 702
704 // If [functionElement] is `operator==` we explicitly add a null check at 703 // If [functionElement] is `operator==` we explicitly add a null check at
705 // the beginning of the method. This is to avoid having call sites do the 704 // the beginning of the method. This is to avoid having call sites do the
706 // null check. 705 // null check.
707 if (name == '==') { 706 if (name == '==') {
708 if (!backend.operatorEqHandlesNullArgument(functionElement)) { 707 if (!backend.operatorEqHandlesNullArgument(functionElement)) {
709 handleIf( 708 handleIf(
710 node: function, 709 node: function,
711 visitCondition: () { 710 visitCondition: () {
712 HParameterValue parameter = parameters.values.first; 711 HParameterValue parameter = parameters.values.first;
713 push(new HIdentity(parameter, graph.addConstantNull(compiler), 712 push(new HIdentity(parameter, graph.addConstantNull(compiler),
714 null, backend.boolType)); 713 null, commonMasks.boolType));
715 }, 714 },
716 visitThen: () { 715 visitThen: () {
717 closeAndGotoExit(new HReturn( 716 closeAndGotoExit(new HReturn(
718 graph.addConstantBool(false, compiler), 717 graph.addConstantBool(false, compiler),
719 sourceInformationBuilder 718 sourceInformationBuilder
720 .buildImplicitReturn(functionElement))); 719 .buildImplicitReturn(functionElement)));
721 }, 720 },
722 visitElse: null, 721 visitElse: null,
723 sourceInformation: sourceInformationBuilder.buildIf(function.body)); 722 sourceInformation: sourceInformationBuilder.buildIf(function.body));
724 } 723 }
(...skipping 12 matching lines...) Expand all
737 return closeFunction(); 736 return closeFunction();
738 } 737 }
739 738
740 /// Adds a JavaScript comment to the output. The comment will be omitted in 739 /// Adds a JavaScript comment to the output. The comment will be omitted in
741 /// minified mode. Each line in [text] is preceded with `//` and indented. 740 /// minified mode. Each line in [text] is preceded with `//` and indented.
742 /// Use sparingly. In order for the comment to be retained it is modeled as 741 /// Use sparingly. In order for the comment to be retained it is modeled as
743 /// having side effects which will inhibit code motion. 742 /// having side effects which will inhibit code motion.
744 // TODO(sra): Figure out how to keep comment anchored without effects. 743 // TODO(sra): Figure out how to keep comment anchored without effects.
745 void addComment(String text) { 744 void addComment(String text) {
746 add(new HForeignCode(js.js.statementTemplateYielding(new js.Comment(text)), 745 add(new HForeignCode(js.js.statementTemplateYielding(new js.Comment(text)),
747 backend.dynamicType, <HInstruction>[], 746 commonMasks.dynamicType, <HInstruction>[],
748 isStatement: true)); 747 isStatement: true));
749 } 748 }
750 749
751 HGraph buildCheckedSetter(FieldElement field) { 750 HGraph buildCheckedSetter(FieldElement field) {
752 ResolvedAst resolvedAst = field.resolvedAst; 751 ResolvedAst resolvedAst = field.resolvedAst;
753 openFunction(field, resolvedAst.node); 752 openFunction(field, resolvedAst.node);
754 HInstruction thisInstruction = localsHandler.readThis(); 753 HInstruction thisInstruction = localsHandler.readThis();
755 // Use dynamic type because the type computed by the inferrer is 754 // Use dynamic type because the type computed by the inferrer is
756 // narrowed to the type annotation. 755 // narrowed to the type annotation.
757 HInstruction parameter = new HParameterValue(field, backend.dynamicType); 756 HInstruction parameter =
757 new HParameterValue(field, commonMasks.dynamicType);
758 // Add the parameter as the last instruction of the entry block. 758 // Add the parameter as the last instruction of the entry block.
759 // If the method is intercepted, we want the actual receiver 759 // If the method is intercepted, we want the actual receiver
760 // to be the first parameter. 760 // to be the first parameter.
761 graph.entry.addBefore(graph.entry.last, parameter); 761 graph.entry.addBefore(graph.entry.last, parameter);
762 HInstruction value = 762 HInstruction value =
763 typeBuilder.potentiallyCheckOrTrustType(parameter, field.type); 763 typeBuilder.potentiallyCheckOrTrustType(parameter, field.type);
764 add(new HFieldSet(field, thisInstruction, value)); 764 add(new HFieldSet(field, thisInstruction, value));
765 return closeFunction(); 765 return closeFunction();
766 } 766 }
767 767
(...skipping 509 matching lines...) Expand 10 before | Expand all | Expand 10 after
1277 member, isNativeUpgradeFactory || compiler.compilationFailed)); 1277 member, isNativeUpgradeFactory || compiler.compilationFailed));
1278 } else { 1278 } else {
1279 fields.add(member); 1279 fields.add(member);
1280 DartType type = localsHandler.substInContext(member.type); 1280 DartType type = localsHandler.substInContext(member.type);
1281 constructorArguments 1281 constructorArguments
1282 .add(typeBuilder.potentiallyCheckOrTrustType(value, type)); 1282 .add(typeBuilder.potentiallyCheckOrTrustType(value, type));
1283 } 1283 }
1284 }, includeSuperAndInjectedMembers: true); 1284 }, includeSuperAndInjectedMembers: true);
1285 1285
1286 InterfaceType type = classElement.thisType; 1286 InterfaceType type = classElement.thisType;
1287 TypeMask ssaType = new TypeMask.nonNullExact( 1287 TypeMask ssaType =
1288 classElement.declaration, compiler.closedWorld); 1288 new TypeMask.nonNullExact(classElement.declaration, closedWorld);
1289 List<DartType> instantiatedTypes; 1289 List<DartType> instantiatedTypes;
1290 addInlinedInstantiation(type); 1290 addInlinedInstantiation(type);
1291 if (!currentInlinedInstantiations.isEmpty) { 1291 if (!currentInlinedInstantiations.isEmpty) {
1292 instantiatedTypes = new List<DartType>.from(currentInlinedInstantiations); 1292 instantiatedTypes = new List<DartType>.from(currentInlinedInstantiations);
1293 } 1293 }
1294 1294
1295 HInstruction newObject; 1295 HInstruction newObject;
1296 if (!isNativeUpgradeFactory) { 1296 if (!isNativeUpgradeFactory) {
1297 // Create the runtime type information, if needed. 1297 // Create the runtime type information, if needed.
1298 bool hasRtiInput = false; 1298 bool hasRtiInput = false;
1299 if (backend.classNeedsRtiField(classElement)) { 1299 if (backend.classNeedsRtiField(classElement)) {
1300 // Read the values of the type arguments and create a 1300 // Read the values of the type arguments and create a
1301 // HTypeInfoExpression to set on the newly create object. 1301 // HTypeInfoExpression to set on the newly create object.
1302 hasRtiInput = true; 1302 hasRtiInput = true;
1303 List<HInstruction> typeArguments = <HInstruction>[]; 1303 List<HInstruction> typeArguments = <HInstruction>[];
1304 classElement.typeVariables.forEach((TypeVariableType typeVariable) { 1304 classElement.typeVariables.forEach((TypeVariableType typeVariable) {
1305 HInstruction argument = localsHandler 1305 HInstruction argument = localsHandler
1306 .readLocal(localsHandler.getTypeVariableAsLocal(typeVariable)); 1306 .readLocal(localsHandler.getTypeVariableAsLocal(typeVariable));
1307 typeArguments.add(argument); 1307 typeArguments.add(argument);
1308 }); 1308 });
1309 1309
1310 HInstruction typeInfo = new HTypeInfoExpression( 1310 HInstruction typeInfo = new HTypeInfoExpression(
1311 TypeInfoExpressionKind.INSTANCE, 1311 TypeInfoExpressionKind.INSTANCE,
1312 classElement.thisType, 1312 classElement.thisType,
1313 typeArguments, 1313 typeArguments,
1314 backend.dynamicType); 1314 commonMasks.dynamicType);
1315 add(typeInfo); 1315 add(typeInfo);
1316 constructorArguments.add(typeInfo); 1316 constructorArguments.add(typeInfo);
1317 } 1317 }
1318 1318
1319 newObject = new HCreate(classElement, constructorArguments, ssaType, 1319 newObject = new HCreate(classElement, constructorArguments, ssaType,
1320 instantiatedTypes: instantiatedTypes, hasRtiInput: hasRtiInput); 1320 instantiatedTypes: instantiatedTypes, hasRtiInput: hasRtiInput);
1321 if (function != null) { 1321 if (function != null) {
1322 // TODO(johnniwinther): Provide source information for creation through 1322 // TODO(johnniwinther): Provide source information for creation through
1323 // synthetic constructors. 1323 // synthetic constructors.
1324 newObject.sourceInformation = 1324 newObject.sourceInformation =
1325 sourceInformationBuilder.buildCreate(function); 1325 sourceInformationBuilder.buildCreate(function);
1326 } 1326 }
1327 add(newObject); 1327 add(newObject);
1328 } else { 1328 } else {
1329 // Bulk assign to the initialized fields. 1329 // Bulk assign to the initialized fields.
1330 newObject = graph.explicitReceiverParameter; 1330 newObject = graph.explicitReceiverParameter;
1331 // Null guard ensures an error if we are being called from an explicit 1331 // Null guard ensures an error if we are being called from an explicit
1332 // 'new' of the constructor instead of via an upgrade. It is optimized out 1332 // 'new' of the constructor instead of via an upgrade. It is optimized out
1333 // if there are field initializers. 1333 // if there are field initializers.
1334 add(new HFieldGet(null, newObject, backend.dynamicType, 1334 add(new HFieldGet(null, newObject, commonMasks.dynamicType,
1335 isAssignable: false)); 1335 isAssignable: false));
1336 for (int i = 0; i < fields.length; i++) { 1336 for (int i = 0; i < fields.length; i++) {
1337 add(new HFieldSet(fields[i], newObject, constructorArguments[i])); 1337 add(new HFieldSet(fields[i], newObject, constructorArguments[i]));
1338 } 1338 }
1339 } 1339 }
1340 removeInlinedInstantiation(type); 1340 removeInlinedInstantiation(type);
1341 1341
1342 // Generate calls to the constructor bodies. 1342 // Generate calls to the constructor bodies.
1343 HInstruction interceptor = null; 1343 HInstruction interceptor = null;
1344 for (int index = constructorResolvedAsts.length - 1; index >= 0; index--) { 1344 for (int index = constructorResolvedAsts.length - 1; index >= 0; index--) {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1391 bodyCallInputs.add(localsHandler 1391 bodyCallInputs.add(localsHandler
1392 .readLocal(localsHandler.getTypeVariableAsLocal(argument))); 1392 .readLocal(localsHandler.getTypeVariableAsLocal(argument)));
1393 }); 1393 });
1394 } 1394 }
1395 1395
1396 if (!isNativeUpgradeFactory && // TODO(13836): Fix inlining. 1396 if (!isNativeUpgradeFactory && // TODO(13836): Fix inlining.
1397 tryInlineMethod(body, null, null, bodyCallInputs, function)) { 1397 tryInlineMethod(body, null, null, bodyCallInputs, function)) {
1398 pop(); 1398 pop();
1399 } else { 1399 } else {
1400 HInvokeConstructorBody invoke = new HInvokeConstructorBody( 1400 HInvokeConstructorBody invoke = new HInvokeConstructorBody(
1401 body.declaration, bodyCallInputs, backend.nonNullType); 1401 body.declaration, bodyCallInputs, commonMasks.nonNullType);
1402 invoke.sideEffects = 1402 invoke.sideEffects = closedWorld.getSideEffectsOfElement(constructor);
1403 compiler.closedWorld.getSideEffectsOfElement(constructor);
1404 add(invoke); 1403 add(invoke);
1405 } 1404 }
1406 } 1405 }
1407 if (inliningStack.isEmpty) { 1406 if (inliningStack.isEmpty) {
1408 closeAndGotoExit(new HReturn(newObject, 1407 closeAndGotoExit(new HReturn(newObject,
1409 sourceInformationBuilder.buildImplicitReturn(functionElement))); 1408 sourceInformationBuilder.buildImplicitReturn(functionElement)));
1410 return closeFunction(); 1409 return closeFunction();
1411 } else { 1410 } else {
1412 localsHandler.updateLocal(returnLocal, newObject); 1411 localsHandler.updateLocal(returnLocal, newObject);
1413 return null; 1412 return null;
(...skipping 16 matching lines...) Expand all
1430 open(block); 1429 open(block);
1431 1430
1432 // Add the type parameters of the class as parameters of this method. This 1431 // Add the type parameters of the class as parameters of this method. This
1433 // must be done before adding the normal parameters, because their types 1432 // must be done before adding the normal parameters, because their types
1434 // may contain references to type variables. 1433 // may contain references to type variables.
1435 var enclosing = element.enclosingElement; 1434 var enclosing = element.enclosingElement;
1436 if ((element.isConstructor || element.isGenerativeConstructorBody) && 1435 if ((element.isConstructor || element.isGenerativeConstructorBody) &&
1437 backend.classNeedsRti(enclosing)) { 1436 backend.classNeedsRti(enclosing)) {
1438 enclosing.typeVariables.forEach((TypeVariableType typeVariable) { 1437 enclosing.typeVariables.forEach((TypeVariableType typeVariable) {
1439 HParameterValue param = 1438 HParameterValue param =
1440 addParameter(typeVariable.element, backend.nonNullType); 1439 addParameter(typeVariable.element, commonMasks.nonNullType);
1441 localsHandler.directLocals[ 1440 localsHandler.directLocals[
1442 localsHandler.getTypeVariableAsLocal(typeVariable)] = param; 1441 localsHandler.getTypeVariableAsLocal(typeVariable)] = param;
1443 }); 1442 });
1444 } 1443 }
1445 1444
1446 if (element is FunctionElement) { 1445 if (element is FunctionElement) {
1447 FunctionElement functionElement = element; 1446 FunctionElement functionElement = element;
1448 FunctionSignature signature = functionElement.functionSignature; 1447 FunctionSignature signature = functionElement.functionSignature;
1449 1448
1450 // Put the type checks in the first successor of the entry, 1449 // Put the type checks in the first successor of the entry,
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1494 } 1493 }
1495 1494
1496 insertTraceCall(Element element) { 1495 insertTraceCall(Element element) {
1497 if (JavaScriptBackend.TRACE_METHOD == 'console') { 1496 if (JavaScriptBackend.TRACE_METHOD == 'console') {
1498 if (element == backend.helpers.traceHelper) return; 1497 if (element == backend.helpers.traceHelper) return;
1499 n(e) => e == null ? '' : e.name; 1498 n(e) => e == null ? '' : e.name;
1500 String name = "${n(element.library)}:${n(element.enclosingClass)}." 1499 String name = "${n(element.library)}:${n(element.enclosingClass)}."
1501 "${n(element)}"; 1500 "${n(element)}";
1502 HConstant nameConstant = addConstantString(name); 1501 HConstant nameConstant = addConstantString(name);
1503 add(new HInvokeStatic(backend.helpers.traceHelper, 1502 add(new HInvokeStatic(backend.helpers.traceHelper,
1504 <HInstruction>[nameConstant], backend.dynamicType)); 1503 <HInstruction>[nameConstant], commonMasks.dynamicType));
1505 } 1504 }
1506 } 1505 }
1507 1506
1508 insertCoverageCall(Element element) { 1507 insertCoverageCall(Element element) {
1509 if (JavaScriptBackend.TRACE_METHOD == 'post') { 1508 if (JavaScriptBackend.TRACE_METHOD == 'post') {
1510 if (element == backend.helpers.traceHelper) return; 1509 if (element == backend.helpers.traceHelper) return;
1511 // TODO(sigmund): create a better uuid for elements. 1510 // TODO(sigmund): create a better uuid for elements.
1512 HConstant idConstant = graph.addConstantInt(element.hashCode, compiler); 1511 HConstant idConstant = graph.addConstantInt(element.hashCode, compiler);
1513 HConstant nameConstant = addConstantString(element.name); 1512 HConstant nameConstant = addConstantString(element.name);
1514 add(new HInvokeStatic(backend.helpers.traceHelper, 1513 add(new HInvokeStatic(backend.helpers.traceHelper,
1515 <HInstruction>[idConstant, nameConstant], backend.dynamicType)); 1514 <HInstruction>[idConstant, nameConstant], commonMasks.dynamicType));
1516 } 1515 }
1517 } 1516 }
1518 1517
1519 void assertIsSubtype( 1518 void assertIsSubtype(
1520 ast.Node node, DartType subtype, DartType supertype, String message) { 1519 ast.Node node, DartType subtype, DartType supertype, String message) {
1521 HInstruction subtypeInstruction = typeBuilder.analyzeTypeArgument( 1520 HInstruction subtypeInstruction = typeBuilder.analyzeTypeArgument(
1522 localsHandler.substInContext(subtype), sourceElement); 1521 localsHandler.substInContext(subtype), sourceElement);
1523 HInstruction supertypeInstruction = typeBuilder.analyzeTypeArgument( 1522 HInstruction supertypeInstruction = typeBuilder.analyzeTypeArgument(
1524 localsHandler.substInContext(supertype), sourceElement); 1523 localsHandler.substInContext(supertype), sourceElement);
1525 HInstruction messageInstruction = 1524 HInstruction messageInstruction =
(...skipping 25 matching lines...) Expand all
1551 /// 1550 ///
1552 /// Boolification is checking if the value is '=== true'. 1551 /// Boolification is checking if the value is '=== true'.
1553 @override 1552 @override
1554 HInstruction popBoolified() { 1553 HInstruction popBoolified() {
1555 HInstruction value = pop(); 1554 HInstruction value = pop();
1556 if (typeBuilder.checkOrTrustTypes) { 1555 if (typeBuilder.checkOrTrustTypes) {
1557 return typeBuilder.potentiallyCheckOrTrustType( 1556 return typeBuilder.potentiallyCheckOrTrustType(
1558 value, compiler.coreTypes.boolType, 1557 value, compiler.coreTypes.boolType,
1559 kind: HTypeConversion.BOOLEAN_CONVERSION_CHECK); 1558 kind: HTypeConversion.BOOLEAN_CONVERSION_CHECK);
1560 } 1559 }
1561 HInstruction result = new HBoolify(value, backend.boolType); 1560 HInstruction result = new HBoolify(value, commonMasks.boolType);
1562 add(result); 1561 add(result);
1563 return result; 1562 return result;
1564 } 1563 }
1565 1564
1566 HInstruction attachPosition(HInstruction target, ast.Node node) { 1565 HInstruction attachPosition(HInstruction target, ast.Node node) {
1567 if (node != null) { 1566 if (node != null) {
1568 target.sourceInformation = sourceInformationBuilder.buildGeneric(node); 1567 target.sourceInformation = sourceInformationBuilder.buildGeneric(node);
1569 } 1568 }
1570 return target; 1569 return target;
1571 } 1570 }
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after
1864 registry?.registerStaticUse(new StaticUse.foreignUse(callElement)); 1863 registry?.registerStaticUse(new StaticUse.foreignUse(callElement));
1865 1864
1866 List<HInstruction> capturedVariables = <HInstruction>[]; 1865 List<HInstruction> capturedVariables = <HInstruction>[];
1867 closureClassElement.closureFields.forEach((ClosureFieldElement field) { 1866 closureClassElement.closureFields.forEach((ClosureFieldElement field) {
1868 Local capturedLocal = 1867 Local capturedLocal =
1869 nestedClosureData.getLocalVariableForClosureField(field); 1868 nestedClosureData.getLocalVariableForClosureField(field);
1870 assert(capturedLocal != null); 1869 assert(capturedLocal != null);
1871 capturedVariables.add(localsHandler.readLocal(capturedLocal)); 1870 capturedVariables.add(localsHandler.readLocal(capturedLocal));
1872 }); 1871 });
1873 1872
1874 TypeMask type = 1873 TypeMask type = new TypeMask.nonNullExact(closureClassElement, closedWorld);
1875 new TypeMask.nonNullExact(closureClassElement, compiler.closedWorld);
1876 push(new HCreate(closureClassElement, capturedVariables, type) 1874 push(new HCreate(closureClassElement, capturedVariables, type)
1877 ..sourceInformation = sourceInformationBuilder.buildCreate(node)); 1875 ..sourceInformation = sourceInformationBuilder.buildCreate(node));
1878 1876
1879 registry?.registerInstantiatedClosure(methodElement); 1877 registry?.registerInstantiatedClosure(methodElement);
1880 } 1878 }
1881 1879
1882 visitFunctionDeclaration(ast.FunctionDeclaration node) { 1880 visitFunctionDeclaration(ast.FunctionDeclaration node) {
1883 assert(isReachable); 1881 assert(isReachable);
1884 visit(node.function); 1882 visit(node.function);
1885 LocalFunctionElement localFunction = 1883 LocalFunctionElement localFunction =
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
1969 handleLogicalBinaryWithLeftNode(left, () => visit(right), branchBuilder, 1967 handleLogicalBinaryWithLeftNode(left, () => visit(right), branchBuilder,
1970 isAnd: false); 1968 isAnd: false);
1971 } 1969 }
1972 1970
1973 @override 1971 @override
1974 void visitNot(ast.Send node, ast.Node expression, _) { 1972 void visitNot(ast.Send node, ast.Node expression, _) {
1975 assert(node.argumentsNode is ast.Prefix); 1973 assert(node.argumentsNode is ast.Prefix);
1976 visit(expression); 1974 visit(expression);
1977 SourceInformation sourceInformation = 1975 SourceInformation sourceInformation =
1978 sourceInformationBuilder.buildGeneric(node); 1976 sourceInformationBuilder.buildGeneric(node);
1979 push(new HNot(popBoolified(), backend.boolType) 1977 push(new HNot(popBoolified(), commonMasks.boolType)
1980 ..sourceInformation = sourceInformation); 1978 ..sourceInformation = sourceInformation);
1981 } 1979 }
1982 1980
1983 @override 1981 @override
1984 void visitUnary( 1982 void visitUnary(
1985 ast.Send node, UnaryOperator operator, ast.Node expression, _) { 1983 ast.Send node, UnaryOperator operator, ast.Node expression, _) {
1986 assert(node.argumentsNode is ast.Prefix); 1984 assert(node.argumentsNode is ast.Prefix);
1987 HInstruction operand = visitAndPop(expression); 1985 HInstruction operand = visitAndPop(expression);
1988 1986
1989 // See if we can constant-fold right away. This avoids rewrites later on. 1987 // See if we can constant-fold right away. This avoids rewrites later on.
(...skipping 24 matching lines...) Expand all
2014 } 2012 }
2015 2013
2016 @override 2014 @override
2017 void visitEquals(ast.Send node, ast.Node left, ast.Node right, _) { 2015 void visitEquals(ast.Send node, ast.Node left, ast.Node right, _) {
2018 handleBinary(node, left, right); 2016 handleBinary(node, left, right);
2019 } 2017 }
2020 2018
2021 @override 2019 @override
2022 void visitNotEquals(ast.Send node, ast.Node left, ast.Node right, _) { 2020 void visitNotEquals(ast.Send node, ast.Node left, ast.Node right, _) {
2023 handleBinary(node, left, right); 2021 handleBinary(node, left, right);
2024 pushWithPosition(new HNot(popBoolified(), backend.boolType), node.selector); 2022 pushWithPosition(
2023 new HNot(popBoolified(), commonMasks.boolType), node.selector);
2025 } 2024 }
2026 2025
2027 void handleBinary(ast.Send node, ast.Node left, ast.Node right) { 2026 void handleBinary(ast.Send node, ast.Node left, ast.Node right) {
2028 visitBinarySend( 2027 visitBinarySend(
2029 visitAndPop(left), 2028 visitAndPop(left),
2030 visitAndPop(right), 2029 visitAndPop(right),
2031 elements.getSelector(node), 2030 elements.getSelector(node),
2032 elementInferenceResults.typeOfSend(node), 2031 elementInferenceResults.typeOfSend(node),
2033 node, 2032 node,
2034 sourceInformation: 2033 sourceInformation:
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
2130 graph.addDeferredConstant(value, prefix, sourceInformation, compiler); 2129 graph.addDeferredConstant(value, prefix, sourceInformation, compiler);
2131 } else { 2130 } else {
2132 instruction = graph.addConstant(value, compiler, 2131 instruction = graph.addConstant(value, compiler,
2133 sourceInformation: sourceInformation); 2132 sourceInformation: sourceInformation);
2134 } 2133 }
2135 stack.add(instruction); 2134 stack.add(instruction);
2136 // The inferrer may have found a better type than the constant 2135 // The inferrer may have found a better type than the constant
2137 // handler in the case of lists, because the constant handler 2136 // handler in the case of lists, because the constant handler
2138 // does not look at elements in the list. 2137 // does not look at elements in the list.
2139 TypeMask type = TypeMaskFactory.inferredTypeForElement(field, compiler); 2138 TypeMask type = TypeMaskFactory.inferredTypeForElement(field, compiler);
2140 if (!type.containsAll(compiler.closedWorld) && 2139 if (!type.containsAll(closedWorld) && !instruction.isConstantNull()) {
2141 !instruction.isConstantNull()) {
2142 // TODO(13429): The inferrer should know that an element 2140 // TODO(13429): The inferrer should know that an element
2143 // cannot be null. 2141 // cannot be null.
2144 instruction.instructionType = type.nonNullable(); 2142 instruction.instructionType = type.nonNullable();
2145 } 2143 }
2146 } 2144 }
2147 2145
2148 @override 2146 @override
2149 void previsitDeferredAccess(ast.Send node, PrefixElement prefix, _) { 2147 void previsitDeferredAccess(ast.Send node, PrefixElement prefix, _) {
2150 generateIsDeferredLoadedCheckIfNeeded(prefix, node); 2148 generateIsDeferredLoadedCheckIfNeeded(prefix, node);
2151 } 2149 }
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
2195 elementInferenceResults.typeOfSend(node), receiver); 2193 elementInferenceResults.typeOfSend(node), receiver);
2196 } 2194 }
2197 2195
2198 /// Generate a closurization of the static or top level [method]. 2196 /// Generate a closurization of the static or top level [method].
2199 void generateStaticFunctionGet(ast.Send node, MethodElement method) { 2197 void generateStaticFunctionGet(ast.Send node, MethodElement method) {
2200 assert(method.isDeclaration); 2198 assert(method.isDeclaration);
2201 // TODO(5346): Try to avoid the need for calling [declaration] before 2199 // TODO(5346): Try to avoid the need for calling [declaration] before
2202 // creating an [HStatic]. 2200 // creating an [HStatic].
2203 SourceInformation sourceInformation = 2201 SourceInformation sourceInformation =
2204 sourceInformationBuilder.buildGet(node); 2202 sourceInformationBuilder.buildGet(node);
2205 push(new HStatic(method, backend.nonNullType) 2203 push(new HStatic(method, commonMasks.nonNullType)
2206 ..sourceInformation = sourceInformation); 2204 ..sourceInformation = sourceInformation);
2207 } 2205 }
2208 2206
2209 /// Read a local variable, function or parameter. 2207 /// Read a local variable, function or parameter.
2210 void buildLocalGet(LocalElement local, SourceInformation sourceInformation) { 2208 void buildLocalGet(LocalElement local, SourceInformation sourceInformation) {
2211 stack.add( 2209 stack.add(
2212 localsHandler.readLocal(local, sourceInformation: sourceInformation)); 2210 localsHandler.readLocal(local, sourceInformation: sourceInformation));
2213 } 2211 }
2214 2212
2215 void handleLocalGet(ast.Send node, LocalElement local) { 2213 void handleLocalGet(ast.Send node, LocalElement local) {
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
2369 stack.add(checkedOrTrusted); 2367 stack.add(checkedOrTrusted);
2370 } 2368 }
2371 2369
2372 localsHandler.updateLocal(local, checkedOrTrusted, 2370 localsHandler.updateLocal(local, checkedOrTrusted,
2373 sourceInformation: 2371 sourceInformation:
2374 sourceInformationBuilder.buildAssignment(location)); 2372 sourceInformationBuilder.buildAssignment(location));
2375 } 2373 }
2376 } 2374 }
2377 2375
2378 HInstruction invokeInterceptor(HInstruction receiver) { 2376 HInstruction invokeInterceptor(HInstruction receiver) {
2379 HInterceptor interceptor = new HInterceptor(receiver, backend.nonNullType); 2377 HInterceptor interceptor =
2378 new HInterceptor(receiver, commonMasks.nonNullType);
2380 add(interceptor); 2379 add(interceptor);
2381 return interceptor; 2380 return interceptor;
2382 } 2381 }
2383 2382
2384 HLiteralList buildLiteralList(List<HInstruction> inputs) { 2383 HLiteralList buildLiteralList(List<HInstruction> inputs) {
2385 return new HLiteralList(inputs, backend.extendableArrayType); 2384 return new HLiteralList(inputs, commonMasks.extendableArrayType);
2386 } 2385 }
2387 2386
2388 @override 2387 @override
2389 void visitAs(ast.Send node, ast.Node expression, DartType type, _) { 2388 void visitAs(ast.Send node, ast.Node expression, DartType type, _) {
2390 HInstruction expressionInstruction = visitAndPop(expression); 2389 HInstruction expressionInstruction = visitAndPop(expression);
2391 if (type.isMalformed) { 2390 if (type.isMalformed) {
2392 if (type is MalformedType) { 2391 if (type is MalformedType) {
2393 ErroneousElement element = type.element; 2392 ErroneousElement element = type.element;
2394 generateTypeError(node, element.message); 2393 generateTypeError(node, element.message);
2395 } else { 2394 } else {
(...skipping 14 matching lines...) Expand all
2410 void visitIs(ast.Send node, ast.Node expression, DartType type, _) { 2409 void visitIs(ast.Send node, ast.Node expression, DartType type, _) {
2411 HInstruction expressionInstruction = visitAndPop(expression); 2410 HInstruction expressionInstruction = visitAndPop(expression);
2412 push(buildIsNode(node, type, expressionInstruction)); 2411 push(buildIsNode(node, type, expressionInstruction));
2413 } 2412 }
2414 2413
2415 @override 2414 @override
2416 void visitIsNot(ast.Send node, ast.Node expression, DartType type, _) { 2415 void visitIsNot(ast.Send node, ast.Node expression, DartType type, _) {
2417 HInstruction expressionInstruction = visitAndPop(expression); 2416 HInstruction expressionInstruction = visitAndPop(expression);
2418 HInstruction instruction = buildIsNode(node, type, expressionInstruction); 2417 HInstruction instruction = buildIsNode(node, type, expressionInstruction);
2419 add(instruction); 2418 add(instruction);
2420 push(new HNot(instruction, backend.boolType)); 2419 push(new HNot(instruction, commonMasks.boolType));
2421 } 2420 }
2422 2421
2423 HInstruction buildIsNode( 2422 HInstruction buildIsNode(
2424 ast.Node node, DartType type, HInstruction expression) { 2423 ast.Node node, DartType type, HInstruction expression) {
2425 type = localsHandler.substInContext(type).unaliased; 2424 type = localsHandler.substInContext(type).unaliased;
2426 if (type.isMalformed) { 2425 if (type.isMalformed) {
2427 String message; 2426 String message;
2428 if (type is MethodTypeVariableType) { 2427 if (type is MethodTypeVariableType) {
2429 message = "Method type variables are not reified, " 2428 message = "Method type variables are not reified, "
2430 "so they cannot be tested with an `is` expression."; 2429 "so they cannot be tested with an `is` expression.";
2431 } else { 2430 } else {
2432 assert(type is MalformedType); 2431 assert(type is MalformedType);
2433 ErroneousElement element = type.element; 2432 ErroneousElement element = type.element;
2434 message = element.message; 2433 message = element.message;
2435 } 2434 }
2436 generateTypeError(node, message); 2435 generateTypeError(node, message);
2437 HInstruction call = pop(); 2436 HInstruction call = pop();
2438 return new HIs.compound(type, expression, call, backend.boolType); 2437 return new HIs.compound(type, expression, call, commonMasks.boolType);
2439 } else if (type.isFunctionType) { 2438 } else if (type.isFunctionType) {
2440 List arguments = [buildFunctionType(type), expression]; 2439 List arguments = [buildFunctionType(type), expression];
2441 pushInvokeDynamic( 2440 pushInvokeDynamic(
2442 node, 2441 node,
2443 new Selector.call(new PrivateName('_isTest', helpers.jsHelperLibrary), 2442 new Selector.call(new PrivateName('_isTest', helpers.jsHelperLibrary),
2444 CallStructure.ONE_ARG), 2443 CallStructure.ONE_ARG),
2445 null, 2444 null,
2446 arguments); 2445 arguments);
2447 return new HIs.compound(type, expression, pop(), backend.boolType); 2446 return new HIs.compound(type, expression, pop(), commonMasks.boolType);
2448 } else if (type.isTypeVariable) { 2447 } else if (type.isTypeVariable) {
2449 HInstruction runtimeType = 2448 HInstruction runtimeType =
2450 typeBuilder.addTypeVariableReference(type, sourceElement); 2449 typeBuilder.addTypeVariableReference(type, sourceElement);
2451 Element helper = helpers.checkSubtypeOfRuntimeType; 2450 Element helper = helpers.checkSubtypeOfRuntimeType;
2452 List<HInstruction> inputs = <HInstruction>[expression, runtimeType]; 2451 List<HInstruction> inputs = <HInstruction>[expression, runtimeType];
2453 pushInvokeStatic(null, helper, inputs, typeMask: backend.boolType); 2452 pushInvokeStatic(null, helper, inputs, typeMask: commonMasks.boolType);
2454 HInstruction call = pop(); 2453 HInstruction call = pop();
2455 return new HIs.variable(type, expression, call, backend.boolType); 2454 return new HIs.variable(type, expression, call, commonMasks.boolType);
2456 } else if (RuntimeTypes.hasTypeArguments(type)) { 2455 } else if (RuntimeTypes.hasTypeArguments(type)) {
2457 ClassElement element = type.element; 2456 ClassElement element = type.element;
2458 Element helper = helpers.checkSubtype; 2457 Element helper = helpers.checkSubtype;
2459 HInstruction representations = 2458 HInstruction representations =
2460 typeBuilder.buildTypeArgumentRepresentations(type, sourceElement); 2459 typeBuilder.buildTypeArgumentRepresentations(type, sourceElement);
2461 add(representations); 2460 add(representations);
2462 js.Name operator = backend.namer.operatorIs(element); 2461 js.Name operator = backend.namer.operatorIs(element);
2463 HInstruction isFieldName = addConstantStringFromName(operator); 2462 HInstruction isFieldName = addConstantStringFromName(operator);
2464 HInstruction asFieldName = compiler.closedWorld 2463 HInstruction asFieldName = closedWorld.hasAnyStrictSubtype(element)
2465 .hasAnyStrictSubtype(element)
2466 ? addConstantStringFromName(backend.namer.substitutionName(element)) 2464 ? addConstantStringFromName(backend.namer.substitutionName(element))
2467 : graph.addConstantNull(compiler); 2465 : graph.addConstantNull(compiler);
2468 List<HInstruction> inputs = <HInstruction>[ 2466 List<HInstruction> inputs = <HInstruction>[
2469 expression, 2467 expression,
2470 isFieldName, 2468 isFieldName,
2471 representations, 2469 representations,
2472 asFieldName 2470 asFieldName
2473 ]; 2471 ];
2474 pushInvokeStatic(node, helper, inputs, typeMask: backend.boolType); 2472 pushInvokeStatic(node, helper, inputs, typeMask: commonMasks.boolType);
2475 HInstruction call = pop(); 2473 HInstruction call = pop();
2476 return new HIs.compound(type, expression, call, backend.boolType); 2474 return new HIs.compound(type, expression, call, commonMasks.boolType);
2477 } else { 2475 } else {
2478 if (backend.hasDirectCheckFor(type)) { 2476 if (backend.hasDirectCheckFor(type)) {
2479 return new HIs.direct(type, expression, backend.boolType); 2477 return new HIs.direct(type, expression, commonMasks.boolType);
2480 } 2478 }
2481 // The interceptor is not always needed. It is removed by optimization 2479 // The interceptor is not always needed. It is removed by optimization
2482 // when the receiver type or tested type permit. 2480 // when the receiver type or tested type permit.
2483 return new HIs.raw( 2481 return new HIs.raw(type, expression, invokeInterceptor(expression),
2484 type, expression, invokeInterceptor(expression), backend.boolType); 2482 commonMasks.boolType);
2485 } 2483 }
2486 } 2484 }
2487 2485
2488 void addDynamicSendArgumentsToList(ast.Send node, List<HInstruction> list) { 2486 void addDynamicSendArgumentsToList(ast.Send node, List<HInstruction> list) {
2489 CallStructure callStructure = elements.getSelector(node).callStructure; 2487 CallStructure callStructure = elements.getSelector(node).callStructure;
2490 if (callStructure.namedArgumentCount == 0) { 2488 if (callStructure.namedArgumentCount == 0) {
2491 addGenericSendArgumentsToList(node.arguments, list); 2489 addGenericSendArgumentsToList(node.arguments, list);
2492 } else { 2490 } else {
2493 // Visit positional arguments and add them to the list. 2491 // Visit positional arguments and add them to the list.
2494 Link<ast.Node> arguments = node.arguments; 2492 Link<ast.Node> arguments = node.arguments;
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
2691 ..sourceInformation = sourceInformation); 2689 ..sourceInformation = sourceInformation);
2692 } 2690 }
2693 } 2691 }
2694 2692
2695 void handleJsStringConcat(ast.Send node) { 2693 void handleJsStringConcat(ast.Send node) {
2696 List<HInstruction> inputs = <HInstruction>[]; 2694 List<HInstruction> inputs = <HInstruction>[];
2697 addGenericSendArgumentsToList(node.arguments, inputs); 2695 addGenericSendArgumentsToList(node.arguments, inputs);
2698 if (inputs.length != 2) { 2696 if (inputs.length != 2) {
2699 reporter.internalError(node.argumentsNode, 'Two arguments expected.'); 2697 reporter.internalError(node.argumentsNode, 'Two arguments expected.');
2700 } 2698 }
2701 push(new HStringConcat(inputs[0], inputs[1], backend.stringType)); 2699 push(new HStringConcat(inputs[0], inputs[1], commonMasks.stringType));
2702 } 2700 }
2703 2701
2704 void handleForeignJsCurrentIsolateContext(ast.Send node) { 2702 void handleForeignJsCurrentIsolateContext(ast.Send node) {
2705 if (!node.arguments.isEmpty) { 2703 if (!node.arguments.isEmpty) {
2706 reporter.internalError( 2704 reporter.internalError(
2707 node, 'Too many arguments to JS_CURRENT_ISOLATE_CONTEXT.'); 2705 node, 'Too many arguments to JS_CURRENT_ISOLATE_CONTEXT.');
2708 } 2706 }
2709 2707
2710 if (!backend.hasIsolateSupport) { 2708 if (!backend.hasIsolateSupport) {
2711 // If the isolate library is not used, we just generate code 2709 // If the isolate library is not used, we just generate code
2712 // to fetch the static state. 2710 // to fetch the static state.
2713 String name = backend.namer.staticStateHolder; 2711 String name = backend.namer.staticStateHolder;
2714 push(new HForeignCode( 2712 push(new HForeignCode(
2715 js.js.parseForeignJS(name), backend.dynamicType, <HInstruction>[], 2713 js.js.parseForeignJS(name), commonMasks.dynamicType, <HInstruction>[],
2716 nativeBehavior: native.NativeBehavior.DEPENDS_OTHER)); 2714 nativeBehavior: native.NativeBehavior.DEPENDS_OTHER));
2717 } else { 2715 } else {
2718 // Call a helper method from the isolate library. The isolate 2716 // Call a helper method from the isolate library. The isolate
2719 // library uses its own isolate structure, that encapsulates 2717 // library uses its own isolate structure, that encapsulates
2720 // Leg's isolate. 2718 // Leg's isolate.
2721 Element element = helpers.currentIsolate; 2719 Element element = helpers.currentIsolate;
2722 if (element == null) { 2720 if (element == null) {
2723 reporter.internalError(node, 'Isolate library and compiler mismatch.'); 2721 reporter.internalError(node, 'Isolate library and compiler mismatch.');
2724 } 2722 }
2725 pushInvokeStatic(null, element, [], typeMask: backend.dynamicType); 2723 pushInvokeStatic(null, element, [], typeMask: commonMasks.dynamicType);
2726 } 2724 }
2727 } 2725 }
2728 2726
2729 void handleForeignJsGetFlag(ast.Send node) { 2727 void handleForeignJsGetFlag(ast.Send node) {
2730 List<ast.Node> arguments = node.arguments.toList(); 2728 List<ast.Node> arguments = node.arguments.toList();
2731 ast.Node argument; 2729 ast.Node argument;
2732 switch (arguments.length) { 2730 switch (arguments.length) {
2733 case 0: 2731 case 0:
2734 reporter.reportErrorMessage(node, MessageKind.GENERIC, 2732 reporter.reportErrorMessage(node, MessageKind.GENERIC,
2735 {'text': 'Error: Expected one argument to JS_GET_FLAG.'}); 2733 {'text': 'Error: Expected one argument to JS_GET_FLAG.'});
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
2901 stack.add(graph.addConstantNull(compiler)); 2899 stack.add(graph.addConstantNull(compiler));
2902 } 2900 }
2903 2901
2904 void handleForeignJsCallInIsolate(ast.Send node) { 2902 void handleForeignJsCallInIsolate(ast.Send node) {
2905 Link<ast.Node> link = node.arguments; 2903 Link<ast.Node> link = node.arguments;
2906 if (!backend.hasIsolateSupport) { 2904 if (!backend.hasIsolateSupport) {
2907 // If the isolate library is not used, we just invoke the 2905 // If the isolate library is not used, we just invoke the
2908 // closure. 2906 // closure.
2909 visit(link.tail.head); 2907 visit(link.tail.head);
2910 push(new HInvokeClosure(new Selector.callClosure(0), 2908 push(new HInvokeClosure(new Selector.callClosure(0),
2911 <HInstruction>[pop()], backend.dynamicType)); 2909 <HInstruction>[pop()], commonMasks.dynamicType));
2912 } else { 2910 } else {
2913 // Call a helper method from the isolate library. 2911 // Call a helper method from the isolate library.
2914 Element element = helpers.callInIsolate; 2912 Element element = helpers.callInIsolate;
2915 if (element == null) { 2913 if (element == null) {
2916 reporter.internalError(node, 'Isolate library and compiler mismatch.'); 2914 reporter.internalError(node, 'Isolate library and compiler mismatch.');
2917 } 2915 }
2918 List<HInstruction> inputs = <HInstruction>[]; 2916 List<HInstruction> inputs = <HInstruction>[];
2919 addGenericSendArgumentsToList(link, inputs); 2917 addGenericSendArgumentsToList(link, inputs);
2920 pushInvokeStatic(node, element, inputs, typeMask: backend.dynamicType); 2918 pushInvokeStatic(node, element, inputs,
2919 typeMask: commonMasks.dynamicType);
2921 } 2920 }
2922 } 2921 }
2923 2922
2924 FunctionSignature handleForeignRawFunctionRef(ast.Send node, String name) { 2923 FunctionSignature handleForeignRawFunctionRef(ast.Send node, String name) {
2925 if (node.arguments.isEmpty || !node.arguments.tail.isEmpty) { 2924 if (node.arguments.isEmpty || !node.arguments.tail.isEmpty) {
2926 reporter.internalError( 2925 reporter.internalError(
2927 node.argumentsNode, '"$name" requires exactly one argument.'); 2926 node.argumentsNode, '"$name" requires exactly one argument.');
2928 } 2927 }
2929 ast.Node closure = node.arguments.head; 2928 ast.Node closure = node.arguments.head;
2930 Element element = elements[closure]; 2929 Element element = elements[closure];
2931 if (!Elements.isStaticOrTopLevelFunction(element)) { 2930 if (!Elements.isStaticOrTopLevelFunction(element)) {
2932 reporter.internalError( 2931 reporter.internalError(
2933 closure, '"$name" requires a static or top-level method.'); 2932 closure, '"$name" requires a static or top-level method.');
2934 } 2933 }
2935 FunctionElement function = element; 2934 FunctionElement function = element;
2936 // TODO(johnniwinther): Try to eliminate the need to distinguish declaration 2935 // TODO(johnniwinther): Try to eliminate the need to distinguish declaration
2937 // and implementation signatures. Currently it is need because the 2936 // and implementation signatures. Currently it is need because the
2938 // signatures have different elements for parameters. 2937 // signatures have different elements for parameters.
2939 FunctionElement implementation = function.implementation; 2938 FunctionElement implementation = function.implementation;
2940 FunctionSignature params = implementation.functionSignature; 2939 FunctionSignature params = implementation.functionSignature;
2941 if (params.optionalParameterCount != 0) { 2940 if (params.optionalParameterCount != 0) {
2942 reporter.internalError( 2941 reporter.internalError(
2943 closure, '"$name" does not handle closure with optional parameters.'); 2942 closure, '"$name" does not handle closure with optional parameters.');
2944 } 2943 }
2945 2944
2946 registry?.registerStaticUse(new StaticUse.foreignUse(function)); 2945 registry?.registerStaticUse(new StaticUse.foreignUse(function));
2947 push(new HForeignCode( 2946 push(new HForeignCode(
2948 js.js.expressionTemplateYielding( 2947 js.js.expressionTemplateYielding(
2949 backend.emitter.staticFunctionAccess(function)), 2948 backend.emitter.staticFunctionAccess(function)),
2950 backend.dynamicType, 2949 commonMasks.dynamicType,
2951 <HInstruction>[], 2950 <HInstruction>[],
2952 nativeBehavior: native.NativeBehavior.PURE)); 2951 nativeBehavior: native.NativeBehavior.PURE));
2953 return params; 2952 return params;
2954 } 2953 }
2955 2954
2956 void handleForeignDartClosureToJs(ast.Send node, String name) { 2955 void handleForeignDartClosureToJs(ast.Send node, String name) {
2957 // TODO(ahe): This implements DART_CLOSURE_TO_JS and should probably take 2956 // TODO(ahe): This implements DART_CLOSURE_TO_JS and should probably take
2958 // care to wrap the closure in another closure that saves the current 2957 // care to wrap the closure in another closure that saves the current
2959 // isolate. 2958 // isolate.
2960 handleForeignRawFunctionRef(node, name); 2959 handleForeignRawFunctionRef(node, name);
2961 } 2960 }
2962 2961
2963 void handleForeignJsSetStaticState(ast.Send node) { 2962 void handleForeignJsSetStaticState(ast.Send node) {
2964 if (node.arguments.isEmpty || !node.arguments.tail.isEmpty) { 2963 if (node.arguments.isEmpty || !node.arguments.tail.isEmpty) {
2965 reporter.internalError( 2964 reporter.internalError(
2966 node.argumentsNode, 'Exactly one argument required.'); 2965 node.argumentsNode, 'Exactly one argument required.');
2967 } 2966 }
2968 visit(node.arguments.head); 2967 visit(node.arguments.head);
2969 String isolateName = backend.namer.staticStateHolder; 2968 String isolateName = backend.namer.staticStateHolder;
2970 SideEffects sideEffects = new SideEffects.empty(); 2969 SideEffects sideEffects = new SideEffects.empty();
2971 sideEffects.setAllSideEffects(); 2970 sideEffects.setAllSideEffects();
2972 push(new HForeignCode(js.js.parseForeignJS("$isolateName = #"), 2971 push(new HForeignCode(js.js.parseForeignJS("$isolateName = #"),
2973 backend.dynamicType, <HInstruction>[pop()], 2972 commonMasks.dynamicType, <HInstruction>[pop()],
2974 nativeBehavior: native.NativeBehavior.CHANGES_OTHER, 2973 nativeBehavior: native.NativeBehavior.CHANGES_OTHER,
2975 effects: sideEffects)); 2974 effects: sideEffects));
2976 } 2975 }
2977 2976
2978 void handleForeignJsGetStaticState(ast.Send node) { 2977 void handleForeignJsGetStaticState(ast.Send node) {
2979 if (!node.arguments.isEmpty) { 2978 if (!node.arguments.isEmpty) {
2980 reporter.internalError(node.argumentsNode, 'Too many arguments.'); 2979 reporter.internalError(node.argumentsNode, 'Too many arguments.');
2981 } 2980 }
2982 push(new HForeignCode(js.js.parseForeignJS(backend.namer.staticStateHolder), 2981 push(new HForeignCode(js.js.parseForeignJS(backend.namer.staticStateHolder),
2983 backend.dynamicType, <HInstruction>[], 2982 commonMasks.dynamicType, <HInstruction>[],
2984 nativeBehavior: native.NativeBehavior.DEPENDS_OTHER)); 2983 nativeBehavior: native.NativeBehavior.DEPENDS_OTHER));
2985 } 2984 }
2986 2985
2987 void handleForeignSend(ast.Send node, FunctionElement element) { 2986 void handleForeignSend(ast.Send node, FunctionElement element) {
2988 String name = element.name; 2987 String name = element.name;
2989 if (name == BackendHelpers.JS) { 2988 if (name == BackendHelpers.JS) {
2990 handleForeignJs(node); 2989 handleForeignJs(node);
2991 } else if (name == 'JS_CURRENT_ISOLATE_CONTEXT') { 2990 } else if (name == 'JS_CURRENT_ISOLATE_CONTEXT') {
2992 handleForeignJsCurrentIsolateContext(node); 2991 handleForeignJsCurrentIsolateContext(node);
2993 } else if (name == 'JS_CALL_IN_ISOLATE') { 2992 } else if (name == 'JS_CALL_IN_ISOLATE') {
(...skipping 29 matching lines...) Expand all
3023 SourceInformation sourceInformation) { 3022 SourceInformation sourceInformation) {
3024 // Until now we only handle these as getters. 3023 // Until now we only handle these as getters.
3025 invariant(node, deferredLoader.isDeferredLoaderGetter); 3024 invariant(node, deferredLoader.isDeferredLoaderGetter);
3026 FunctionEntity loadFunction = helpers.loadLibraryWrapper; 3025 FunctionEntity loadFunction = helpers.loadLibraryWrapper;
3027 PrefixElement prefixElement = deferredLoader.enclosingElement; 3026 PrefixElement prefixElement = deferredLoader.enclosingElement;
3028 String loadId = 3027 String loadId =
3029 compiler.deferredLoadTask.getImportDeferName(node, prefixElement); 3028 compiler.deferredLoadTask.getImportDeferName(node, prefixElement);
3030 var inputs = [ 3029 var inputs = [
3031 graph.addConstantString(new ast.DartString.literal(loadId), compiler) 3030 graph.addConstantString(new ast.DartString.literal(loadId), compiler)
3032 ]; 3031 ];
3033 push(new HInvokeStatic(loadFunction, inputs, backend.nonNullType, 3032 push(new HInvokeStatic(loadFunction, inputs, commonMasks.nonNullType,
3034 targetCanThrow: false)..sourceInformation = sourceInformation); 3033 targetCanThrow: false)..sourceInformation = sourceInformation);
3035 } 3034 }
3036 3035
3037 generateSuperNoSuchMethodSend( 3036 generateSuperNoSuchMethodSend(
3038 ast.Send node, Selector selector, List<HInstruction> arguments) { 3037 ast.Send node, Selector selector, List<HInstruction> arguments) {
3039 String name = selector.name; 3038 String name = selector.name;
3040 3039
3041 ClassElement cls = currentNonClosureClass; 3040 ClassElement cls = currentNonClosureClass;
3042 MethodElement element = cls.lookupSuperMember(Identifiers.noSuchMethod_); 3041 MethodElement element = cls.lookupSuperMember(Identifiers.noSuchMethod_);
3043 if (!Selectors.noSuchMethod_.signatureApplies(element)) { 3042 if (!Selectors.noSuchMethod_.signatureApplies(element)) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
3078 pushInvokeStatic( 3077 pushInvokeStatic(
3079 null, 3078 null,
3080 createInvocationMirror, 3079 createInvocationMirror,
3081 [ 3080 [
3082 graph.addConstant(nameConstant, compiler), 3081 graph.addConstant(nameConstant, compiler),
3083 graph.addConstantStringFromName(internalName, compiler), 3082 graph.addConstantStringFromName(internalName, compiler),
3084 graph.addConstant(kindConstant, compiler), 3083 graph.addConstant(kindConstant, compiler),
3085 argumentsInstruction, 3084 argumentsInstruction,
3086 argumentNamesInstruction 3085 argumentNamesInstruction
3087 ], 3086 ],
3088 typeMask: backend.dynamicType); 3087 typeMask: commonMasks.dynamicType);
3089 3088
3090 var inputs = <HInstruction>[pop()]; 3089 var inputs = <HInstruction>[pop()];
3091 push(buildInvokeSuper(Selectors.noSuchMethod_, element, inputs)); 3090 push(buildInvokeSuper(Selectors.noSuchMethod_, element, inputs));
3092 } 3091 }
3093 3092
3094 /// Generate a call to a super method or constructor. 3093 /// Generate a call to a super method or constructor.
3095 void generateSuperInvoke(ast.Send node, MethodElement method, 3094 void generateSuperInvoke(ast.Send node, MethodElement method,
3096 SourceInformation sourceInformation) { 3095 SourceInformation sourceInformation) {
3097 // TODO(5347): Try to avoid the need for calling [implementation] before 3096 // TODO(5347): Try to avoid the need for calling [implementation] before
3098 // calling [makeStaticArgumentList]. 3097 // calling [makeStaticArgumentList].
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
3226 @override 3225 @override
3227 void visitSuperBinary(ast.Send node, MethodElement method, 3226 void visitSuperBinary(ast.Send node, MethodElement method,
3228 BinaryOperator operator, ast.Node argument, _) { 3227 BinaryOperator operator, ast.Node argument, _) {
3229 handleSuperMethodInvoke(node, method); 3228 handleSuperMethodInvoke(node, method);
3230 } 3229 }
3231 3230
3232 @override 3231 @override
3233 void visitSuperNotEquals( 3232 void visitSuperNotEquals(
3234 ast.Send node, MethodElement method, ast.Node argument, _) { 3233 ast.Send node, MethodElement method, ast.Node argument, _) {
3235 handleSuperMethodInvoke(node, method); 3234 handleSuperMethodInvoke(node, method);
3236 pushWithPosition(new HNot(popBoolified(), backend.boolType), node.selector); 3235 pushWithPosition(
3236 new HNot(popBoolified(), commonMasks.boolType), node.selector);
3237 } 3237 }
3238 3238
3239 @override 3239 @override
3240 void visitSuperUnary( 3240 void visitSuperUnary(
3241 ast.Send node, UnaryOperator operator, MethodElement method, _) { 3241 ast.Send node, UnaryOperator operator, MethodElement method, _) {
3242 handleSuperMethodInvoke(node, method); 3242 handleSuperMethodInvoke(node, method);
3243 } 3243 }
3244 3244
3245 @override 3245 @override
3246 void visitSuperMethodIncompatibleInvoke(ast.Send node, MethodElement method, 3246 void visitSuperMethodIncompatibleInvoke(ast.Send node, MethodElement method,
3247 ast.NodeList arguments, CallStructure callStructure, _) { 3247 ast.NodeList arguments, CallStructure callStructure, _) {
3248 handleInvalidSuperInvoke(node, arguments); 3248 handleInvalidSuperInvoke(node, arguments);
3249 } 3249 }
3250 3250
3251 @override 3251 @override
3252 void visitSuperSetterInvoke(ast.Send node, SetterElement setter, 3252 void visitSuperSetterInvoke(ast.Send node, SetterElement setter,
3253 ast.NodeList arguments, CallStructure callStructure, _) { 3253 ast.NodeList arguments, CallStructure callStructure, _) {
3254 handleInvalidSuperInvoke(node, arguments); 3254 handleInvalidSuperInvoke(node, arguments);
3255 } 3255 }
3256 3256
3257 void handleInvalidSuperInvoke(ast.Send node, ast.NodeList arguments) { 3257 void handleInvalidSuperInvoke(ast.Send node, ast.NodeList arguments) {
3258 Selector selector = elements.getSelector(node); 3258 Selector selector = elements.getSelector(node);
3259 List<HInstruction> inputs = <HInstruction>[]; 3259 List<HInstruction> inputs = <HInstruction>[];
3260 addGenericSendArgumentsToList(arguments.nodes, inputs); 3260 addGenericSendArgumentsToList(arguments.nodes, inputs);
3261 generateSuperNoSuchMethodSend(node, selector, inputs); 3261 generateSuperNoSuchMethodSend(node, selector, inputs);
3262 } 3262 }
3263 3263
3264 bool needsSubstitutionForTypeVariableAccess(ClassElement cls) { 3264 bool needsSubstitutionForTypeVariableAccess(ClassElement cls) {
3265 ClosedWorld closedWorld = compiler.closedWorld;
3266 if (closedWorld.isUsedAsMixin(cls)) return true; 3265 if (closedWorld.isUsedAsMixin(cls)) return true;
3267 3266
3268 return compiler.closedWorld.anyStrictSubclassOf(cls, 3267 return closedWorld.anyStrictSubclassOf(cls, (ClassElement subclass) {
3269 (ClassElement subclass) {
3270 return !rti.isTrivialSubstitution(subclass, cls); 3268 return !rti.isTrivialSubstitution(subclass, cls);
3271 }); 3269 });
3272 } 3270 }
3273 3271
3274 HInstruction handleListConstructor( 3272 HInstruction handleListConstructor(
3275 InterfaceType type, ast.Node currentNode, HInstruction newObject) { 3273 InterfaceType type, ast.Node currentNode, HInstruction newObject) {
3276 if (!backend.classNeedsRti(type.element) || type.treatAsRaw) { 3274 if (!backend.classNeedsRti(type.element) || type.treatAsRaw) {
3277 return newObject; 3275 return newObject;
3278 } 3276 }
3279 List<HInstruction> inputs = <HInstruction>[]; 3277 List<HInstruction> inputs = <HInstruction>[];
3280 type = localsHandler.substInContext(type); 3278 type = localsHandler.substInContext(type);
3281 type.typeArguments.forEach((DartType argument) { 3279 type.typeArguments.forEach((DartType argument) {
3282 inputs.add(typeBuilder.analyzeTypeArgument(argument, sourceElement)); 3280 inputs.add(typeBuilder.analyzeTypeArgument(argument, sourceElement));
3283 }); 3281 });
3284 // TODO(15489): Register at codegen. 3282 // TODO(15489): Register at codegen.
3285 registry?.registerInstantiation(type); 3283 registry?.registerInstantiation(type);
3286 return callSetRuntimeTypeInfoWithTypeArguments(type, inputs, newObject); 3284 return callSetRuntimeTypeInfoWithTypeArguments(type, inputs, newObject);
3287 } 3285 }
3288 3286
3289 HInstruction callSetRuntimeTypeInfo( 3287 HInstruction callSetRuntimeTypeInfo(
3290 HInstruction typeInfo, HInstruction newObject) { 3288 HInstruction typeInfo, HInstruction newObject) {
3291 // Set the runtime type information on the object. 3289 // Set the runtime type information on the object.
3292 Element typeInfoSetterElement = helpers.setRuntimeTypeInfo; 3290 Element typeInfoSetterElement = helpers.setRuntimeTypeInfo;
3293 pushInvokeStatic( 3291 pushInvokeStatic(
3294 null, typeInfoSetterElement, <HInstruction>[newObject, typeInfo], 3292 null, typeInfoSetterElement, <HInstruction>[newObject, typeInfo],
3295 typeMask: backend.dynamicType, 3293 typeMask: commonMasks.dynamicType,
3296 sourceInformation: newObject.sourceInformation); 3294 sourceInformation: newObject.sourceInformation);
3297 3295
3298 // The new object will now be referenced through the 3296 // The new object will now be referenced through the
3299 // `setRuntimeTypeInfo` call. We therefore set the type of that 3297 // `setRuntimeTypeInfo` call. We therefore set the type of that
3300 // instruction to be of the object's type. 3298 // instruction to be of the object's type.
3301 assert(invariant(CURRENT_ELEMENT_SPANNABLE, 3299 assert(invariant(CURRENT_ELEMENT_SPANNABLE,
3302 stack.last is HInvokeStatic || stack.last == newObject, 3300 stack.last is HInvokeStatic || stack.last == newObject,
3303 message: "Unexpected `stack.last`: Found ${stack.last}, " 3301 message: "Unexpected `stack.last`: Found ${stack.last}, "
3304 "expected ${newObject} or an HInvokeStatic. " 3302 "expected ${newObject} or an HInvokeStatic. "
3305 "State: typeInfo=$typeInfo, stack=$stack.")); 3303 "State: typeInfo=$typeInfo, stack=$stack."));
(...skipping 11 matching lines...) Expand all
3317 bool isGrowableListConstructorCall = 3315 bool isGrowableListConstructorCall =
3318 Elements.isGrowableListConstructorCall(elements[send], send, compiler); 3316 Elements.isGrowableListConstructorCall(elements[send], send, compiler);
3319 3317
3320 TypeMask computeType(element) { 3318 TypeMask computeType(element) {
3321 Element originalElement = elements[send]; 3319 Element originalElement = elements[send];
3322 if (isFixedListConstructorCall || 3320 if (isFixedListConstructorCall ||
3323 Elements.isFilledListConstructorCall( 3321 Elements.isFilledListConstructorCall(
3324 originalElement, send, compiler)) { 3322 originalElement, send, compiler)) {
3325 isFixedList = true; 3323 isFixedList = true;
3326 TypeMask inferred = _inferredTypeOfNewList(send); 3324 TypeMask inferred = _inferredTypeOfNewList(send);
3327 return inferred.containsAll(compiler.closedWorld) 3325 return inferred.containsAll(closedWorld)
3328 ? backend.fixedArrayType 3326 ? commonMasks.fixedArrayType
3329 : inferred; 3327 : inferred;
3330 } else if (isGrowableListConstructorCall) { 3328 } else if (isGrowableListConstructorCall) {
3331 TypeMask inferred = _inferredTypeOfNewList(send); 3329 TypeMask inferred = _inferredTypeOfNewList(send);
3332 return inferred.containsAll(compiler.closedWorld) 3330 return inferred.containsAll(closedWorld)
3333 ? backend.extendableArrayType 3331 ? commonMasks.extendableArrayType
3334 : inferred; 3332 : inferred;
3335 } else if (Elements.isConstructorOfTypedArraySubclass( 3333 } else if (Elements.isConstructorOfTypedArraySubclass(
3336 originalElement, compiler)) { 3334 originalElement, compiler)) {
3337 isFixedList = true; 3335 isFixedList = true;
3338 TypeMask inferred = _inferredTypeOfNewList(send); 3336 TypeMask inferred = _inferredTypeOfNewList(send);
3339 ClassElement cls = element.enclosingClass; 3337 ClassElement cls = element.enclosingClass;
3340 assert(backend.isNative(cls.thisType.element)); 3338 assert(backend.isNative(cls.thisType.element));
3341 return inferred.containsAll(compiler.closedWorld) 3339 return inferred.containsAll(closedWorld)
3342 ? new TypeMask.nonNullExact( 3340 ? new TypeMask.nonNullExact(cls.thisType.element, closedWorld)
3343 cls.thisType.element, compiler.closedWorld)
3344 : inferred; 3341 : inferred;
3345 } else if (element.isGenerativeConstructor) { 3342 } else if (element.isGenerativeConstructor) {
3346 ClassElement cls = element.enclosingClass; 3343 ClassElement cls = element.enclosingClass;
3347 if (cls.isAbstract) { 3344 if (cls.isAbstract) {
3348 // An error will be thrown. 3345 // An error will be thrown.
3349 return new TypeMask.nonNullEmpty(); 3346 return new TypeMask.nonNullEmpty();
3350 } else { 3347 } else {
3351 return new TypeMask.nonNullExact( 3348 return new TypeMask.nonNullExact(cls.thisType.element, closedWorld);
3352 cls.thisType.element, compiler.closedWorld);
3353 } 3349 }
3354 } else { 3350 } else {
3355 return TypeMaskFactory.inferredReturnTypeForElement( 3351 return TypeMaskFactory.inferredReturnTypeForElement(
3356 originalElement, compiler); 3352 originalElement, compiler);
3357 } 3353 }
3358 } 3354 }
3359 3355
3360 Element constructor = elements[send]; 3356 Element constructor = elements[send];
3361 CallStructure callStructure = elements.getSelector(send).callStructure; 3357 CallStructure callStructure = elements.getSelector(send).callStructure;
3362 ConstructorElement constructorDeclaration = constructor; 3358 ConstructorElement constructorDeclaration = constructor;
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
3420 // TODO(5347): Try to avoid the need for calling [implementation] before 3416 // TODO(5347): Try to avoid the need for calling [implementation] before
3421 // calling [makeStaticArgumentList]. 3417 // calling [makeStaticArgumentList].
3422 constructorImplementation = constructor.implementation; 3418 constructorImplementation = constructor.implementation;
3423 if (constructorImplementation.isMalformed || 3419 if (constructorImplementation.isMalformed ||
3424 !callStructure 3420 !callStructure
3425 .signatureApplies(constructorImplementation.functionSignature)) { 3421 .signatureApplies(constructorImplementation.functionSignature)) {
3426 generateWrongArgumentCountError(send, constructor, send.arguments); 3422 generateWrongArgumentCountError(send, constructor, send.arguments);
3427 return; 3423 return;
3428 } 3424 }
3429 3425
3430 var inputs = <HInstruction>[]; 3426 List<HInstruction> inputs = <HInstruction>[];
3431 if (constructor.isGenerativeConstructor && 3427 if (constructor.isGenerativeConstructor &&
3432 backend.isNativeOrExtendsNative(constructor.enclosingClass) && 3428 backend.isNativeOrExtendsNative(constructor.enclosingClass) &&
3433 !backend.isJsInterop(constructor)) { 3429 !backend.isJsInterop(constructor)) {
3434 // Native class generative constructors take a pre-constructed object. 3430 // Native class generative constructors take a pre-constructed object.
3435 inputs.add(graph.addConstantNull(compiler)); 3431 inputs.add(graph.addConstantNull(compiler));
3436 } 3432 }
3437 inputs.addAll(makeStaticArgumentList( 3433 inputs.addAll(makeStaticArgumentList(
3438 callStructure, send.arguments, constructorImplementation)); 3434 callStructure, send.arguments, constructorImplementation));
3439 3435
3440 TypeMask elementType = computeType(constructor); 3436 TypeMask elementType = computeType(constructor);
3441 if (isFixedListConstructorCall) { 3437 if (isFixedListConstructorCall) {
3442 if (!inputs[0].isNumber(compiler)) { 3438 if (!inputs[0].isNumber(closedWorld)) {
3443 HTypeConversion conversion = new HTypeConversion(null, 3439 HTypeConversion conversion = new HTypeConversion(
3444 HTypeConversion.ARGUMENT_TYPE_CHECK, backend.numType, inputs[0]); 3440 null,
3441 HTypeConversion.ARGUMENT_TYPE_CHECK,
3442 commonMasks.numType,
3443 inputs[0]);
3445 add(conversion); 3444 add(conversion);
3446 inputs[0] = conversion; 3445 inputs[0] = conversion;
3447 } 3446 }
3448 js.Template code = js.js.parseForeignJS('new Array(#)'); 3447 js.Template code = js.js.parseForeignJS('new Array(#)');
3449 var behavior = new native.NativeBehavior(); 3448 var behavior = new native.NativeBehavior();
3450 behavior.typesReturned.add(expectedType); 3449 behavior.typesReturned.add(expectedType);
3451 // The allocation can throw only if the given length is a double or 3450 // The allocation can throw only if the given length is a double or
3452 // outside the unsigned 32 bit range. 3451 // outside the unsigned 32 bit range.
3453 // TODO(sra): Array allocation should be an instruction so that canThrow 3452 // TODO(sra): Array allocation should be an instruction so that canThrow
3454 // can depend on a length type discovered in optimization. 3453 // can depend on a length type discovered in optimization.
3455 bool canThrow = true; 3454 bool canThrow = true;
3456 if (inputs[0].isInteger(compiler) && inputs[0] is HConstant) { 3455 if (inputs[0].isInteger(closedWorld) && inputs[0] is HConstant) {
3457 var constant = inputs[0]; 3456 var constant = inputs[0];
3458 int value = constant.constant.primitiveValue; 3457 int value = constant.constant.primitiveValue;
3459 if (0 <= value && value < 0x100000000) canThrow = false; 3458 if (0 <= value && value < 0x100000000) canThrow = false;
3460 } 3459 }
3461 HForeignCode foreign = new HForeignCode(code, elementType, inputs, 3460 HForeignCode foreign = new HForeignCode(code, elementType, inputs,
3462 nativeBehavior: behavior, 3461 nativeBehavior: behavior,
3463 throwBehavior: canThrow 3462 throwBehavior: canThrow
3464 ? native.NativeThrowBehavior.MAY 3463 ? native.NativeThrowBehavior.MAY
3465 : native.NativeThrowBehavior.NEVER); 3464 : native.NativeThrowBehavior.NEVER);
3466 push(foreign); 3465 push(foreign);
3467 if (inferenceResults.isFixedArrayCheckedForGrowable(send)) { 3466 if (inferenceResults.isFixedArrayCheckedForGrowable(send)) {
3468 js.Template code = js.js.parseForeignJS(r'#.fixed$length = Array'); 3467 js.Template code = js.js.parseForeignJS(r'#.fixed$length = Array');
3469 // We set the instruction as [canThrow] to avoid it being dead code. 3468 // We set the instruction as [canThrow] to avoid it being dead code.
3470 // We need a finer grained side effect. 3469 // We need a finer grained side effect.
3471 add(new HForeignCode(code, backend.nullType, [stack.last], 3470 add(new HForeignCode(code, commonMasks.nullType, [stack.last],
3472 throwBehavior: native.NativeThrowBehavior.MAY)); 3471 throwBehavior: native.NativeThrowBehavior.MAY));
3473 } 3472 }
3474 } else if (isGrowableListConstructorCall) { 3473 } else if (isGrowableListConstructorCall) {
3475 push(buildLiteralList(<HInstruction>[])); 3474 push(buildLiteralList(<HInstruction>[]));
3476 stack.last.instructionType = elementType; 3475 stack.last.instructionType = elementType;
3477 } else { 3476 } else {
3478 SourceInformation sourceInformation = 3477 SourceInformation sourceInformation =
3479 sourceInformationBuilder.buildNew(send); 3478 sourceInformationBuilder.buildNew(send);
3480 potentiallyAddTypeArguments(inputs, cls, expectedType); 3479 potentiallyAddTypeArguments(inputs, cls, expectedType);
3481 addInlinedInstantiation(expectedType); 3480 addInlinedInstantiation(expectedType);
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
3586 } 3585 }
3587 3586
3588 /// Generate an invocation to the static or top level [function]. 3587 /// Generate an invocation to the static or top level [function].
3589 void generateStaticFunctionInvoke( 3588 void generateStaticFunctionInvoke(
3590 ast.Send node, FunctionElement function, CallStructure callStructure) { 3589 ast.Send node, FunctionElement function, CallStructure callStructure) {
3591 List<HInstruction> inputs = makeStaticArgumentList( 3590 List<HInstruction> inputs = makeStaticArgumentList(
3592 callStructure, node.arguments, function.implementation); 3591 callStructure, node.arguments, function.implementation);
3593 3592
3594 if (function == compiler.commonElements.identicalFunction) { 3593 if (function == compiler.commonElements.identicalFunction) {
3595 pushWithPosition( 3594 pushWithPosition(
3596 new HIdentity(inputs[0], inputs[1], null, backend.boolType), node); 3595 new HIdentity(inputs[0], inputs[1], null, commonMasks.boolType),
3596 node);
3597 return; 3597 return;
3598 } else { 3598 } else {
3599 pushInvokeStatic(node, function, inputs, 3599 pushInvokeStatic(node, function, inputs,
3600 sourceInformation: 3600 sourceInformation:
3601 sourceInformationBuilder.buildCall(node, node.selector)); 3601 sourceInformationBuilder.buildCall(node, node.selector));
3602 } 3602 }
3603 } 3603 }
3604 3604
3605 /// Generate an invocation to a static or top level function with the wrong 3605 /// Generate an invocation to a static or top level function with the wrong
3606 /// number of arguments. 3606 /// number of arguments.
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
3791 // GENERIC_METHODS: This provides thin support for method type variables 3791 // GENERIC_METHODS: This provides thin support for method type variables
3792 // by treating them as malformed when evaluated as a literal. For full 3792 // by treating them as malformed when evaluated as a literal. For full
3793 // support of generic methods this must be revised. 3793 // support of generic methods this must be revised.
3794 if (typeVariable is MethodTypeVariableType) { 3794 if (typeVariable is MethodTypeVariableType) {
3795 generateTypeError(node, "Method type variables are not reified"); 3795 generateTypeError(node, "Method type variables are not reified");
3796 } else { 3796 } else {
3797 DartType type = localsHandler.substInContext(typeVariable); 3797 DartType type = localsHandler.substInContext(typeVariable);
3798 HInstruction value = typeBuilder.analyzeTypeArgument(type, sourceElement, 3798 HInstruction value = typeBuilder.analyzeTypeArgument(type, sourceElement,
3799 sourceInformation: sourceInformationBuilder.buildGet(node)); 3799 sourceInformation: sourceInformationBuilder.buildGet(node));
3800 pushInvokeStatic(node, helpers.runtimeTypeToString, [value], 3800 pushInvokeStatic(node, helpers.runtimeTypeToString, [value],
3801 typeMask: backend.stringType); 3801 typeMask: commonMasks.stringType);
3802 pushInvokeStatic(node, helpers.createRuntimeType, [pop()]); 3802 pushInvokeStatic(node, helpers.createRuntimeType, [pop()]);
3803 } 3803 }
3804 } 3804 }
3805 3805
3806 /// Generate a call to a type literal. 3806 /// Generate a call to a type literal.
3807 void generateTypeLiteralCall(ast.Send node) { 3807 void generateTypeLiteralCall(ast.Send node) {
3808 // This send is of the form 'e(...)', where e is resolved to a type 3808 // This send is of the form 'e(...)', where e is resolved to a type
3809 // reference. We create a regular closure call on the result of the type 3809 // reference. We create a regular closure call on the result of the type
3810 // reference instead of creating a NoSuchMethodError to avoid pulling it 3810 // reference instead of creating a NoSuchMethodError to avoid pulling it
3811 // in if it is not used (e.g., in a try/catch). 3811 // in if it is not used (e.g., in a try/catch).
3812 HInstruction target = pop(); 3812 HInstruction target = pop();
3813 generateCallInvoke(node, target, 3813 generateCallInvoke(node, target,
3814 sourceInformationBuilder.buildCall(node, node.argumentsNode)); 3814 sourceInformationBuilder.buildCall(node, node.argumentsNode));
3815 } 3815 }
3816 3816
3817 /// Generate a '.call' invocation on [target]. 3817 /// Generate a '.call' invocation on [target].
3818 void generateCallInvoke( 3818 void generateCallInvoke(
3819 ast.Send node, HInstruction target, SourceInformation sourceInformation) { 3819 ast.Send node, HInstruction target, SourceInformation sourceInformation) {
3820 Selector selector = elements.getSelector(node); 3820 Selector selector = elements.getSelector(node);
3821 List<HInstruction> inputs = <HInstruction>[target]; 3821 List<HInstruction> inputs = <HInstruction>[target];
3822 addDynamicSendArgumentsToList(node, inputs); 3822 addDynamicSendArgumentsToList(node, inputs);
3823 push(new HInvokeClosure( 3823 push(new HInvokeClosure(
3824 new Selector.callClosureFrom(selector), inputs, backend.dynamicType) 3824 new Selector.callClosureFrom(selector), inputs, commonMasks.dynamicType)
3825 ..sourceInformation = sourceInformation); 3825 ..sourceInformation = sourceInformation);
3826 } 3826 }
3827 3827
3828 visitGetterSend(ast.Send node) { 3828 visitGetterSend(ast.Send node) {
3829 internalError(node, "Unexpected visitGetterSend"); 3829 internalError(node, "Unexpected visitGetterSend");
3830 } 3830 }
3831 3831
3832 // TODO(antonm): migrate rest of SsaFromAstMixin to internalError. 3832 // TODO(antonm): migrate rest of SsaFromAstMixin to internalError.
3833 internalError(Spannable node, String reason) { 3833 internalError(Spannable node, String reason) {
3834 reporter.internalError(node, reason); 3834 reporter.internalError(node, reason);
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
3963 void pushInvokeDynamic(ast.Node node, Selector selector, TypeMask mask, 3963 void pushInvokeDynamic(ast.Node node, Selector selector, TypeMask mask,
3964 List<HInstruction> arguments, 3964 List<HInstruction> arguments,
3965 {SourceInformation sourceInformation}) { 3965 {SourceInformation sourceInformation}) {
3966 // We prefer to not inline certain operations on indexables, 3966 // We prefer to not inline certain operations on indexables,
3967 // because the constant folder will handle them better and turn 3967 // because the constant folder will handle them better and turn
3968 // them into simpler instructions that allow further 3968 // them into simpler instructions that allow further
3969 // optimizations. 3969 // optimizations.
3970 bool isOptimizableOperationOnIndexable(Selector selector, Element element) { 3970 bool isOptimizableOperationOnIndexable(Selector selector, Element element) {
3971 bool isLength = selector.isGetter && selector.name == "length"; 3971 bool isLength = selector.isGetter && selector.name == "length";
3972 if (isLength || selector.isIndex) { 3972 if (isLength || selector.isIndex) {
3973 return compiler.closedWorld.isSubtypeOf( 3973 return closedWorld.isSubtypeOf(
3974 element.enclosingClass.declaration, helpers.jsIndexableClass); 3974 element.enclosingClass.declaration, helpers.jsIndexableClass);
3975 } else if (selector.isIndexSet) { 3975 } else if (selector.isIndexSet) {
3976 return compiler.closedWorld.isSubtypeOf( 3976 return closedWorld.isSubtypeOf(element.enclosingClass.declaration,
3977 element.enclosingClass.declaration,
3978 helpers.jsMutableIndexableClass); 3977 helpers.jsMutableIndexableClass);
3979 } else { 3978 } else {
3980 return false; 3979 return false;
3981 } 3980 }
3982 } 3981 }
3983 3982
3984 bool isOptimizableOperation(Selector selector, Element element) { 3983 bool isOptimizableOperation(Selector selector, Element element) {
3985 ClassElement cls = element.enclosingClass; 3984 ClassElement cls = element.enclosingClass;
3986 if (isOptimizableOperationOnIndexable(selector, element)) return true; 3985 if (isOptimizableOperationOnIndexable(selector, element)) return true;
3987 if (!backend.interceptedClasses.contains(cls)) return false; 3986 if (!backend.interceptedClasses.contains(cls)) return false;
3988 if (selector.isOperator) return true; 3987 if (selector.isOperator) return true;
3989 if (selector.isSetter) return true; 3988 if (selector.isSetter) return true;
3990 if (selector.isIndex) return true; 3989 if (selector.isIndex) return true;
3991 if (selector.isIndexSet) return true; 3990 if (selector.isIndexSet) return true;
3992 if (element == helpers.jsArrayAdd || 3991 if (element == helpers.jsArrayAdd ||
3993 element == helpers.jsArrayRemoveLast || 3992 element == helpers.jsArrayRemoveLast ||
3994 element == helpers.jsStringSplit) { 3993 element == helpers.jsStringSplit) {
3995 return true; 3994 return true;
3996 } 3995 }
3997 return false; 3996 return false;
3998 } 3997 }
3999 3998
4000 Element element = compiler.closedWorld.locateSingleElement(selector, mask); 3999 Element element = closedWorld.locateSingleElement(selector, mask);
4001 if (element != null && 4000 if (element != null &&
4002 !element.isField && 4001 !element.isField &&
4003 !(element.isGetter && selector.isCall) && 4002 !(element.isGetter && selector.isCall) &&
4004 !(element.isFunction && selector.isGetter) && 4003 !(element.isFunction && selector.isGetter) &&
4005 !isOptimizableOperation(selector, element)) { 4004 !isOptimizableOperation(selector, element)) {
4006 if (tryInlineMethod(element, selector, mask, arguments, node)) { 4005 if (tryInlineMethod(element, selector, mask, arguments, node)) {
4007 return; 4006 return;
4008 } 4007 }
4009 } 4008 }
4010 4009
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
4060 }); 4059 });
4061 var codeTemplate = 4060 var codeTemplate =
4062 new js.Template(null, js.objectLiteral(parameterNameMap)); 4061 new js.Template(null, js.objectLiteral(parameterNameMap));
4063 4062
4064 var nativeBehavior = new native.NativeBehavior() 4063 var nativeBehavior = new native.NativeBehavior()
4065 ..codeTemplate = codeTemplate; 4064 ..codeTemplate = codeTemplate;
4066 if (compiler.options.trustJSInteropTypeAnnotations) { 4065 if (compiler.options.trustJSInteropTypeAnnotations) {
4067 nativeBehavior.typesReturned.add(constructor.enclosingClass.thisType); 4066 nativeBehavior.typesReturned.add(constructor.enclosingClass.thisType);
4068 } 4067 }
4069 return new HForeignCode( 4068 return new HForeignCode(
4070 codeTemplate, backend.dynamicType, filteredArguments, 4069 codeTemplate, commonMasks.dynamicType, filteredArguments,
4071 nativeBehavior: nativeBehavior) 4070 nativeBehavior: nativeBehavior)
4072 ..sourceInformation = sourceInformation; 4071 ..sourceInformation = sourceInformation;
4073 } 4072 }
4074 var target = new HForeignCode( 4073 var target = new HForeignCode(
4075 js.js.parseForeignJS("${backend.namer.fixedBackendPath(element)}." 4074 js.js.parseForeignJS("${backend.namer.fixedBackendPath(element)}."
4076 "${backend.nativeData.getFixedBackendName(element)}"), 4075 "${backend.nativeData.getFixedBackendName(element)}"),
4077 backend.dynamicType, 4076 commonMasks.dynamicType,
4078 <HInstruction>[]); 4077 <HInstruction>[]);
4079 add(target); 4078 add(target);
4080 // Strip off trailing arguments that were not specified. 4079 // Strip off trailing arguments that were not specified.
4081 // we could assert that the trailing arguments are all null. 4080 // we could assert that the trailing arguments are all null.
4082 // TODO(jacobr): rewrite named arguments to an object literal matching 4081 // TODO(jacobr): rewrite named arguments to an object literal matching
4083 // the factory constructor case. 4082 // the factory constructor case.
4084 arguments = arguments.where((arg) => arg != null).toList(); 4083 arguments = arguments.where((arg) => arg != null).toList();
4085 var inputs = <HInstruction>[target]..addAll(arguments); 4084 var inputs = <HInstruction>[target]..addAll(arguments);
4086 4085
4087 var nativeBehavior = new native.NativeBehavior() 4086 var nativeBehavior = new native.NativeBehavior()
(...skipping 30 matching lines...) Expand all
4118 code = "#"; 4117 code = "#";
4119 } else if (element.isSetter) { 4118 } else if (element.isSetter) {
4120 code = "# = #"; 4119 code = "# = #";
4121 } else { 4120 } else {
4122 var args = new List.filled(arguments.length, '#').join(','); 4121 var args = new List.filled(arguments.length, '#').join(',');
4123 code = element.isConstructor ? "new #($args)" : "#($args)"; 4122 code = element.isConstructor ? "new #($args)" : "#($args)";
4124 } 4123 }
4125 js.Template codeTemplate = js.js.parseForeignJS(code); 4124 js.Template codeTemplate = js.js.parseForeignJS(code);
4126 nativeBehavior.codeTemplate = codeTemplate; 4125 nativeBehavior.codeTemplate = codeTemplate;
4127 4126
4128 return new HForeignCode(codeTemplate, backend.dynamicType, inputs, 4127 return new HForeignCode(codeTemplate, commonMasks.dynamicType, inputs,
4129 nativeBehavior: nativeBehavior)..sourceInformation = sourceInformation; 4128 nativeBehavior: nativeBehavior)..sourceInformation = sourceInformation;
4130 } 4129 }
4131 4130
4132 void pushInvokeStatic( 4131 void pushInvokeStatic(
4133 ast.Node location, MethodElement element, List<HInstruction> arguments, 4132 ast.Node location, MethodElement element, List<HInstruction> arguments,
4134 {TypeMask typeMask, 4133 {TypeMask typeMask,
4135 InterfaceType instanceType, 4134 InterfaceType instanceType,
4136 SourceInformation sourceInformation}) { 4135 SourceInformation sourceInformation}) {
4137 assert(element.isDeclaration); 4136 assert(element.isDeclaration);
4138 // TODO(johnniwinther): Use [sourceInformation] instead of [location]. 4137 // TODO(johnniwinther): Use [sourceInformation] instead of [location].
4139 if (tryInlineMethod(element, null, null, arguments, location, 4138 if (tryInlineMethod(element, null, null, arguments, location,
4140 instanceType: instanceType)) { 4139 instanceType: instanceType)) {
4141 return; 4140 return;
4142 } 4141 }
4143 4142
4144 if (typeMask == null) { 4143 if (typeMask == null) {
4145 typeMask = 4144 typeMask =
4146 TypeMaskFactory.inferredReturnTypeForElement(element, compiler); 4145 TypeMaskFactory.inferredReturnTypeForElement(element, compiler);
4147 } 4146 }
4148 bool targetCanThrow = !compiler.closedWorld.getCannotThrow(element); 4147 bool targetCanThrow = !closedWorld.getCannotThrow(element);
4149 // TODO(5346): Try to avoid the need for calling [declaration] before 4148 // TODO(5346): Try to avoid the need for calling [declaration] before
4150 var instruction; 4149 var instruction;
4151 if (backend.isJsInterop(element)) { 4150 if (backend.isJsInterop(element)) {
4152 instruction = 4151 instruction =
4153 invokeJsInteropFunction(element, arguments, sourceInformation); 4152 invokeJsInteropFunction(element, arguments, sourceInformation);
4154 } else { 4153 } else {
4155 // creating an [HInvokeStatic]. 4154 // creating an [HInvokeStatic].
4156 instruction = new HInvokeStatic(element, arguments, typeMask, 4155 instruction = new HInvokeStatic(element, arguments, typeMask,
4157 targetCanThrow: targetCanThrow) 4156 targetCanThrow: targetCanThrow)
4158 ..sourceInformation = sourceInformation; 4157 ..sourceInformation = sourceInformation;
4159 if (currentInlinedInstantiations.isNotEmpty) { 4158 if (currentInlinedInstantiations.isNotEmpty) {
4160 instruction.instantiatedTypes = 4159 instruction.instantiatedTypes =
4161 new List<DartType>.from(currentInlinedInstantiations); 4160 new List<DartType>.from(currentInlinedInstantiations);
4162 } 4161 }
4163 instruction.sideEffects = 4162 instruction.sideEffects = closedWorld.getSideEffectsOfElement(element);
4164 compiler.closedWorld.getSideEffectsOfElement(element);
4165 } 4163 }
4166 if (location == null) { 4164 if (location == null) {
4167 push(instruction); 4165 push(instruction);
4168 } else { 4166 } else {
4169 pushWithPosition(instruction, location); 4167 pushWithPosition(instruction, location);
4170 } 4168 }
4171 } 4169 }
4172 4170
4173 HInstruction buildInvokeSuper( 4171 HInstruction buildInvokeSuper(
4174 Selector selector, MemberElement element, List<HInstruction> arguments, 4172 Selector selector, MemberElement element, List<HInstruction> arguments,
(...skipping 13 matching lines...) Expand all
4188 TypeMask type; 4186 TypeMask type;
4189 if (!element.isGetter && selector.isGetter) { 4187 if (!element.isGetter && selector.isGetter) {
4190 type = TypeMaskFactory.inferredTypeForElement(element, compiler); 4188 type = TypeMaskFactory.inferredTypeForElement(element, compiler);
4191 } else { 4189 } else {
4192 type = TypeMaskFactory.inferredReturnTypeForElement(element, compiler); 4190 type = TypeMaskFactory.inferredReturnTypeForElement(element, compiler);
4193 } 4191 }
4194 HInstruction instruction = new HInvokeSuper(element, currentNonClosureClass, 4192 HInstruction instruction = new HInvokeSuper(element, currentNonClosureClass,
4195 selector, inputs, type, sourceInformation, 4193 selector, inputs, type, sourceInformation,
4196 isSetter: selector.isSetter || selector.isIndexSet); 4194 isSetter: selector.isSetter || selector.isIndexSet);
4197 instruction.sideEffects = 4195 instruction.sideEffects =
4198 compiler.closedWorld.getSideEffectsOfSelector(selector, null); 4196 closedWorld.getSideEffectsOfSelector(selector, null);
4199 return instruction; 4197 return instruction;
4200 } 4198 }
4201 4199
4202 void handleComplexOperatorSend( 4200 void handleComplexOperatorSend(
4203 ast.SendSet node, HInstruction receiver, Link<ast.Node> arguments) { 4201 ast.SendSet node, HInstruction receiver, Link<ast.Node> arguments) {
4204 HInstruction rhs; 4202 HInstruction rhs;
4205 if (node.isPrefix || node.isPostfix) { 4203 if (node.isPrefix || node.isPostfix) {
4206 rhs = graph.addConstantInt(1, compiler); 4204 rhs = graph.addConstantInt(1, compiler);
4207 } else { 4205 } else {
4208 visit(arguments.head); 4206 visit(arguments.head);
(...skipping 983 matching lines...) Expand 10 before | Expand all | Expand 10 after
5192 visitYield(ast.Yield node) { 5190 visitYield(ast.Yield node) {
5193 visit(node.expression); 5191 visit(node.expression);
5194 HInstruction yielded = pop(); 5192 HInstruction yielded = pop();
5195 add(new HYield(yielded, node.hasStar)); 5193 add(new HYield(yielded, node.hasStar));
5196 } 5194 }
5197 5195
5198 visitAwait(ast.Await node) { 5196 visitAwait(ast.Await node) {
5199 visit(node.expression); 5197 visit(node.expression);
5200 HInstruction awaited = pop(); 5198 HInstruction awaited = pop();
5201 // TODO(herhut): Improve this type. 5199 // TODO(herhut): Improve this type.
5202 push(new HAwait(awaited, 5200 push(new HAwait(
5203 new TypeMask.subclass(coreClasses.objectClass, compiler.closedWorld))); 5201 awaited, new TypeMask.subclass(coreClasses.objectClass, closedWorld)));
5204 } 5202 }
5205 5203
5206 visitTypeAnnotation(ast.TypeAnnotation node) { 5204 visitTypeAnnotation(ast.TypeAnnotation node) {
5207 reporter.internalError(node, 'Visiting type annotation in SSA builder.'); 5205 reporter.internalError(node, 'Visiting type annotation in SSA builder.');
5208 } 5206 }
5209 5207
5210 visitVariableDefinitions(ast.VariableDefinitions node) { 5208 visitVariableDefinitions(ast.VariableDefinitions node) {
5211 assert(isReachable); 5209 assert(isReachable);
5212 for (Link<ast.Node> link = node.definitions.nodes; 5210 for (Link<ast.Node> link = node.definitions.nodes;
5213 !link.isEmpty; 5211 !link.isEmpty;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
5252 link = link.tail) { 5250 link = link.tail) {
5253 visit(link.head); 5251 visit(link.head);
5254 inputs.add(pop()); 5252 inputs.add(pop());
5255 } 5253 }
5256 instruction = buildLiteralList(inputs); 5254 instruction = buildLiteralList(inputs);
5257 add(instruction); 5255 add(instruction);
5258 instruction = setRtiIfNeeded(instruction, node); 5256 instruction = setRtiIfNeeded(instruction, node);
5259 } 5257 }
5260 5258
5261 TypeMask type = _inferredTypeOfNewList(node); 5259 TypeMask type = _inferredTypeOfNewList(node);
5262 if (!type.containsAll(compiler.closedWorld)) { 5260 if (!type.containsAll(closedWorld)) {
5263 instruction.instructionType = type; 5261 instruction.instructionType = type;
5264 } 5262 }
5265 stack.add(instruction); 5263 stack.add(instruction);
5266 } 5264 }
5267 5265
5268 _inferredTypeOfNewList(ast.Node node) => 5266 _inferredTypeOfNewList(ast.Node node) =>
5269 _resultOf(sourceElement).typeOfNewList(node) ?? 5267 _resultOf(sourceElement).typeOfNewList(node) ?? commonMasks.dynamicType;
5270 compiler.closedWorld.commonMasks.dynamicType;
5271 5268
5272 visitConditional(ast.Conditional node) { 5269 visitConditional(ast.Conditional node) {
5273 SsaBranchBuilder brancher = new SsaBranchBuilder(this, compiler, node); 5270 SsaBranchBuilder brancher = new SsaBranchBuilder(this, compiler, node);
5274 brancher.handleConditional(() => visit(node.condition), 5271 brancher.handleConditional(() => visit(node.condition),
5275 () => visit(node.thenExpression), () => visit(node.elseExpression)); 5272 () => visit(node.thenExpression), () => visit(node.elseExpression));
5276 } 5273 }
5277 5274
5278 visitStringInterpolation(ast.StringInterpolation node) { 5275 visitStringInterpolation(ast.StringInterpolation node) {
5279 StringBuilderVisitor stringBuilder = new StringBuilderVisitor(this, node); 5276 StringBuilderVisitor stringBuilder = new StringBuilderVisitor(this, node);
5280 stringBuilder.visit(node); 5277 stringBuilder.visit(node);
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
5359 streamIterator = pop(); 5356 streamIterator = pop();
5360 5357
5361 void buildInitializer() {} 5358 void buildInitializer() {}
5362 5359
5363 HInstruction buildCondition() { 5360 HInstruction buildCondition() {
5364 Selector selector = Selectors.moveNext; 5361 Selector selector = Selectors.moveNext;
5365 TypeMask mask = elementInferenceResults.typeOfIteratorMoveNext(node); 5362 TypeMask mask = elementInferenceResults.typeOfIteratorMoveNext(node);
5366 pushInvokeDynamic(node, selector, mask, [streamIterator]); 5363 pushInvokeDynamic(node, selector, mask, [streamIterator]);
5367 HInstruction future = pop(); 5364 HInstruction future = pop();
5368 push(new HAwait( 5365 push(new HAwait(
5369 future, 5366 future, new TypeMask.subclass(coreClasses.objectClass, closedWorld)));
5370 new TypeMask.subclass(
5371 coreClasses.objectClass, compiler.closedWorld)));
5372 return popBoolified(); 5367 return popBoolified();
5373 } 5368 }
5374 5369
5375 void buildBody() { 5370 void buildBody() {
5376 Selector call = Selectors.current; 5371 Selector call = Selectors.current;
5377 TypeMask callMask = elementInferenceResults.typeOfIteratorCurrent(node); 5372 TypeMask callMask = elementInferenceResults.typeOfIteratorCurrent(node);
5378 pushInvokeDynamic(node, call, callMask, [streamIterator]); 5373 pushInvokeDynamic(node, call, callMask, [streamIterator]);
5379 5374
5380 ast.Node identifier = node.declaredIdentifier; 5375 ast.Node identifier = node.declaredIdentifier;
5381 Element variable = elements.getForInVariable(node); 5376 Element variable = elements.getForInVariable(node);
(...skipping 15 matching lines...) Expand all
5397 } 5392 }
5398 5393
5399 void buildUpdate() {} 5394 void buildUpdate() {}
5400 5395
5401 buildProtectedByFinally(() { 5396 buildProtectedByFinally(() {
5402 loopHandler.handleLoop( 5397 loopHandler.handleLoop(
5403 node, buildInitializer, buildCondition, buildUpdate, buildBody); 5398 node, buildInitializer, buildCondition, buildUpdate, buildBody);
5404 }, () { 5399 }, () {
5405 pushInvokeDynamic(node, Selectors.cancel, null, [streamIterator]); 5400 pushInvokeDynamic(node, Selectors.cancel, null, [streamIterator]);
5406 push(new HAwait( 5401 push(new HAwait(
5407 pop(), 5402 pop(), new TypeMask.subclass(coreClasses.objectClass, closedWorld)));
5408 new TypeMask.subclass(
5409 coreClasses.objectClass, compiler.closedWorld)));
5410 pop(); 5403 pop();
5411 }); 5404 });
5412 } 5405 }
5413 5406
5414 visitSyncForIn(ast.SyncForIn node) { 5407 visitSyncForIn(ast.SyncForIn node) {
5415 // The 'get iterator' selector for this node has the inferred receiver type. 5408 // The 'get iterator' selector for this node has the inferred receiver type.
5416 // If the receiver supports JavaScript indexing we generate an indexing loop 5409 // If the receiver supports JavaScript indexing we generate an indexing loop
5417 // instead of allocating an iterator object. 5410 // instead of allocating an iterator object.
5418 5411
5419 // This scheme recognizes for-in on direct lists. It does not recognize all 5412 // This scheme recognizes for-in on direct lists. It does not recognize all
5420 // uses of ArrayIterator. They still occur when the receiver is an Iterable 5413 // uses of ArrayIterator. They still occur when the receiver is an Iterable
5421 // with a `get iterator` method that delegates to another Iterable and the 5414 // with a `get iterator` method that delegates to another Iterable and the
5422 // method is inlined. We would require full scalar replacement in that 5415 // method is inlined. We would require full scalar replacement in that
5423 // case. 5416 // case.
5424 5417
5425 TypeMask mask = elementInferenceResults.typeOfIterator(node); 5418 TypeMask mask = elementInferenceResults.typeOfIterator(node);
5426 5419
5427 ClosedWorld closedWorld = compiler.closedWorld;
5428 if (mask != null && 5420 if (mask != null &&
5429 mask.satisfies(helpers.jsIndexableClass, closedWorld) && 5421 mask.satisfies(helpers.jsIndexableClass, closedWorld) &&
5430 // String is indexable but not iterable. 5422 // String is indexable but not iterable.
5431 !mask.satisfies(helpers.jsStringClass, closedWorld)) { 5423 !mask.satisfies(helpers.jsStringClass, closedWorld)) {
5432 return buildSyncForInIndexable(node, mask); 5424 return buildSyncForInIndexable(node, mask);
5433 } 5425 }
5434 buildSyncForInIterator(node); 5426 buildSyncForInIterator(node);
5435 } 5427 }
5436 5428
5437 buildSyncForInIterator(ast.SyncForIn node) { 5429 buildSyncForInIterator(ast.SyncForIn node) {
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
5496 // 5488 //
5497 // int end = a.length; 5489 // int end = a.length;
5498 // for (int i = 0; 5490 // for (int i = 0;
5499 // i < a.length; 5491 // i < a.length;
5500 // checkConcurrentModificationError(a.length == end, a), ++i) { 5492 // checkConcurrentModificationError(a.length == end, a), ++i) {
5501 // <declaredIdentifier> = a[i]; 5493 // <declaredIdentifier> = a[i];
5502 // <body> 5494 // <body>
5503 // } 5495 // }
5504 Element loopVariable = elements.getForInVariable(node); 5496 Element loopVariable = elements.getForInVariable(node);
5505 SyntheticLocal indexVariable = new SyntheticLocal('_i', loopVariable); 5497 SyntheticLocal indexVariable = new SyntheticLocal('_i', loopVariable);
5506 TypeMask boolType = backend.boolType; 5498 TypeMask boolType = commonMasks.boolType;
5507 5499
5508 // These variables are shared by initializer, condition, body and update. 5500 // These variables are shared by initializer, condition, body and update.
5509 HInstruction array; // Set in buildInitializer. 5501 HInstruction array; // Set in buildInitializer.
5510 bool isFixed; // Set in buildInitializer. 5502 bool isFixed; // Set in buildInitializer.
5511 HInstruction originalLength = null; // Set for growable lists. 5503 HInstruction originalLength = null; // Set for growable lists.
5512 5504
5513 HInstruction buildGetLength() { 5505 HInstruction buildGetLength() {
5514 MemberElement lengthElement = helpers.jsIndexableLength; 5506 MemberElement lengthElement = helpers.jsIndexableLength;
5515 HFieldGet result = new HFieldGet( 5507 HFieldGet result = new HFieldGet(
5516 lengthElement, array, backend.positiveIntType, 5508 lengthElement, array, commonMasks.positiveIntType,
5517 isAssignable: !isFixed); 5509 isAssignable: !isFixed);
5518 add(result); 5510 add(result);
5519 return result; 5511 return result;
5520 } 5512 }
5521 5513
5522 void buildConcurrentModificationErrorCheck() { 5514 void buildConcurrentModificationErrorCheck() {
5523 if (originalLength == null) return; 5515 if (originalLength == null) return;
5524 // The static call checkConcurrentModificationError() is expanded in 5516 // The static call checkConcurrentModificationError() is expanded in
5525 // codegen to: 5517 // codegen to:
5526 // 5518 //
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
5577 // See buildBody as to why we check here. 5569 // See buildBody as to why we check here.
5578 buildConcurrentModificationErrorCheck(); 5570 buildConcurrentModificationErrorCheck();
5579 5571
5580 // TODO(sra): It would be slightly shorter to generate `a[i++]` in the 5572 // TODO(sra): It would be slightly shorter to generate `a[i++]` in the
5581 // body (and that more closely follows what an inlined iterator would do) 5573 // body (and that more closely follows what an inlined iterator would do)
5582 // but the code is horrible as `i+1` is carried around the loop in an 5574 // but the code is horrible as `i+1` is carried around the loop in an
5583 // additional variable. 5575 // additional variable.
5584 HInstruction index = localsHandler.readLocal(indexVariable); 5576 HInstruction index = localsHandler.readLocal(indexVariable);
5585 HInstruction one = graph.addConstantInt(1, compiler); 5577 HInstruction one = graph.addConstantInt(1, compiler);
5586 HInstruction addInstruction = 5578 HInstruction addInstruction =
5587 new HAdd(index, one, null, backend.positiveIntType); 5579 new HAdd(index, one, null, commonMasks.positiveIntType);
5588 add(addInstruction); 5580 add(addInstruction);
5589 localsHandler.updateLocal(indexVariable, addInstruction); 5581 localsHandler.updateLocal(indexVariable, addInstruction);
5590 } 5582 }
5591 5583
5592 loopHandler.handleLoop( 5584 loopHandler.handleLoop(
5593 node, buildInitializer, buildCondition, buildUpdate, buildBody); 5585 node, buildInitializer, buildCondition, buildUpdate, buildBody);
5594 } 5586 }
5595 5587
5596 visitLabel(ast.Label node) { 5588 visitLabel(ast.Label node) {
5597 reporter.internalError(node, 'SsaFromAstMixin.visitLabel.'); 5589 reporter.internalError(node, 'SsaFromAstMixin.visitLabel.');
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
5698 } 5690 }
5699 5691
5700 // If rti is needed and the map literal has no type parameters, 5692 // If rti is needed and the map literal has no type parameters,
5701 // 'constructor' is a static function that forwards the call to the factory 5693 // 'constructor' is a static function that forwards the call to the factory
5702 // constructor without type parameters. 5694 // constructor without type parameters.
5703 assert(constructor is ConstructorElement || constructor is FunctionElement); 5695 assert(constructor is ConstructorElement || constructor is FunctionElement);
5704 5696
5705 // The instruction type will always be a subtype of the mapLiteralClass, but 5697 // The instruction type will always be a subtype of the mapLiteralClass, but
5706 // type inference might discover a more specific type, or find nothing (in 5698 // type inference might discover a more specific type, or find nothing (in
5707 // dart2js unit tests). 5699 // dart2js unit tests).
5708 TypeMask mapType = new TypeMask.nonNullSubtype( 5700 TypeMask mapType =
5709 helpers.mapLiteralClass, compiler.closedWorld); 5701 new TypeMask.nonNullSubtype(helpers.mapLiteralClass, closedWorld);
5710 TypeMask returnTypeMask = 5702 TypeMask returnTypeMask =
5711 TypeMaskFactory.inferredReturnTypeForElement(constructor, compiler); 5703 TypeMaskFactory.inferredReturnTypeForElement(constructor, compiler);
5712 TypeMask instructionType = 5704 TypeMask instructionType =
5713 mapType.intersection(returnTypeMask, compiler.closedWorld); 5705 mapType.intersection(returnTypeMask, closedWorld);
5714 5706
5715 addInlinedInstantiation(expectedType); 5707 addInlinedInstantiation(expectedType);
5716 pushInvokeStatic(node, constructor, inputs, 5708 pushInvokeStatic(node, constructor, inputs,
5717 typeMask: instructionType, instanceType: expectedType); 5709 typeMask: instructionType, instanceType: expectedType);
5718 removeInlinedInstantiation(expectedType); 5710 removeInlinedInstantiation(expectedType);
5719 } 5711 }
5720 5712
5721 visitLiteralMapEntry(ast.LiteralMapEntry node) { 5713 visitLiteralMapEntry(ast.LiteralMapEntry node) {
5722 visit(node.value); 5714 visit(node.value);
5723 visit(node.key); 5715 visit(node.key);
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
5939 } 5931 }
5940 5932
5941 if (hasDefault) { 5933 if (hasDefault) {
5942 buildLoop(); 5934 buildLoop();
5943 } else { 5935 } else {
5944 // If the switch statement has no default case, surround the loop with 5936 // If the switch statement has no default case, surround the loop with
5945 // a test of the target. 5937 // a test of the target.
5946 void buildCondition() { 5938 void buildCondition() {
5947 js.Template code = js.js.parseForeignJS('#'); 5939 js.Template code = js.js.parseForeignJS('#');
5948 push(new HForeignCode( 5940 push(new HForeignCode(
5949 code, backend.boolType, [localsHandler.readLocal(switchTarget)], 5941 code, commonMasks.boolType, [localsHandler.readLocal(switchTarget)],
5950 nativeBehavior: native.NativeBehavior.PURE)); 5942 nativeBehavior: native.NativeBehavior.PURE));
5951 } 5943 }
5952 5944
5953 handleIf( 5945 handleIf(
5954 node: node, 5946 node: node,
5955 visitCondition: buildCondition, 5947 visitCondition: buildCondition,
5956 visitThen: buildLoop, 5948 visitThen: buildLoop,
5957 visitElse: () => {}); 5949 visitElse: () => {});
5958 } 5950 }
5959 } 5951 }
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
6221 SubGraph catchGraph = null; 6213 SubGraph catchGraph = null;
6222 HLocalValue exception = null; 6214 HLocalValue exception = null;
6223 6215
6224 if (!node.catchBlocks.isEmpty) { 6216 if (!node.catchBlocks.isEmpty) {
6225 localsHandler = new LocalsHandler.from(savedLocals); 6217 localsHandler = new LocalsHandler.from(savedLocals);
6226 startCatchBlock = graph.addNewBlock(); 6218 startCatchBlock = graph.addNewBlock();
6227 open(startCatchBlock); 6219 open(startCatchBlock);
6228 // Note that the name of this local is irrelevant. 6220 // Note that the name of this local is irrelevant.
6229 SyntheticLocal local = 6221 SyntheticLocal local =
6230 new SyntheticLocal('exception', localsHandler.executableContext); 6222 new SyntheticLocal('exception', localsHandler.executableContext);
6231 exception = new HLocalValue(local, backend.nonNullType); 6223 exception = new HLocalValue(local, commonMasks.nonNullType);
6232 add(exception); 6224 add(exception);
6233 HInstruction oldRethrowableException = rethrowableException; 6225 HInstruction oldRethrowableException = rethrowableException;
6234 rethrowableException = exception; 6226 rethrowableException = exception;
6235 6227
6236 pushInvokeStatic(node, helpers.exceptionUnwrapper, [exception]); 6228 pushInvokeStatic(node, helpers.exceptionUnwrapper, [exception]);
6237 HInvokeStatic unwrappedException = pop(); 6229 HInvokeStatic unwrappedException = pop();
6238 tryInstruction.exception = exception; 6230 tryInstruction.exception = exception;
6239 Link<ast.Node> link = node.catchBlocks.nodes; 6231 Link<ast.Node> link = node.catchBlocks.nodes;
6240 6232
6241 void pushCondition(ast.CatchBlock catchBlock) { 6233 void pushCondition(ast.CatchBlock catchBlock) {
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after
6531 void visitExpression(ast.Node node) { 6523 void visitExpression(ast.Node node) {
6532 node.accept(builder); 6524 node.accept(builder);
6533 HInstruction expression = builder.pop(); 6525 HInstruction expression = builder.pop();
6534 6526
6535 // We want to use HStringify when: 6527 // We want to use HStringify when:
6536 // 1. The value is known to be a primitive type, because it might get 6528 // 1. The value is known to be a primitive type, because it might get
6537 // constant-folded and codegen has some tricks with JavaScript 6529 // constant-folded and codegen has some tricks with JavaScript
6538 // conversions. 6530 // conversions.
6539 // 2. The value can be primitive, because the library stringifier has 6531 // 2. The value can be primitive, because the library stringifier has
6540 // fast-path code for most primitives. 6532 // fast-path code for most primitives.
6541 if (expression.canBePrimitive(compiler)) { 6533 if (expression.canBePrimitive(builder.closedWorld)) {
6542 append(stringify(node, expression)); 6534 append(stringify(node, expression));
6543 return; 6535 return;
6544 } 6536 }
6545 6537
6546 // If the `toString` method is guaranteed to return a string we can call it 6538 // If the `toString` method is guaranteed to return a string we can call it
6547 // directly. 6539 // directly.
6548 Selector selector = Selectors.toString_; 6540 Selector selector = Selectors.toString_;
6549 TypeMask type = TypeMaskFactory.inferredTypeForSelector( 6541 TypeMask type = TypeMaskFactory.inferredTypeForSelector(
6550 selector, expression.instructionType, compiler); 6542 selector, expression.instructionType, compiler);
6551 if (type.containsOnlyString(compiler.closedWorld)) { 6543 if (type.containsOnlyString(builder.closedWorld)) {
6552 builder.pushInvokeDynamic(node, selector, expression.instructionType, 6544 builder.pushInvokeDynamic(node, selector, expression.instructionType,
6553 <HInstruction>[expression]); 6545 <HInstruction>[expression]);
6554 append(builder.pop()); 6546 append(builder.pop());
6555 return; 6547 return;
6556 } 6548 }
6557 6549
6558 append(stringify(node, expression)); 6550 append(stringify(node, expression));
6559 } 6551 }
6560 6552
6561 void visitStringInterpolation(ast.StringInterpolation node) { 6553 void visitStringInterpolation(ast.StringInterpolation node) {
(...skipping 12 matching lines...) Expand all
6574 void visitNodeList(ast.NodeList node) { 6566 void visitNodeList(ast.NodeList node) {
6575 node.visitChildren(this); 6567 node.visitChildren(this);
6576 } 6568 }
6577 6569
6578 void append(HInstruction expression) { 6570 void append(HInstruction expression) {
6579 result = (result == null) ? expression : concat(result, expression); 6571 result = (result == null) ? expression : concat(result, expression);
6580 } 6572 }
6581 6573
6582 HInstruction concat(HInstruction left, HInstruction right) { 6574 HInstruction concat(HInstruction left, HInstruction right) {
6583 HInstruction instruction = 6575 HInstruction instruction =
6584 new HStringConcat(left, right, builder.backend.stringType); 6576 new HStringConcat(left, right, builder.commonMasks.stringType);
6585 builder.add(instruction); 6577 builder.add(instruction);
6586 return instruction; 6578 return instruction;
6587 } 6579 }
6588 6580
6589 HInstruction stringify(ast.Node node, HInstruction expression) { 6581 HInstruction stringify(ast.Node node, HInstruction expression) {
6590 HInstruction instruction = 6582 HInstruction instruction =
6591 new HStringify(expression, builder.backend.stringType); 6583 new HStringify(expression, builder.commonMasks.stringType);
6592 builder.add(instruction); 6584 builder.add(instruction);
6593 return instruction; 6585 return instruction;
6594 } 6586 }
6595 } 6587 }
6596 6588
6597 /** 6589 /**
6598 * This class visits the method that is a candidate for inlining and 6590 * This class visits the method that is a candidate for inlining and
6599 * finds whether it is too difficult to inline. 6591 * finds whether it is too difficult to inline.
6600 */ 6592 */
6601 // TODO(karlklose): refactor to make it possible to distinguish between 6593 // TODO(karlklose): refactor to make it possible to distinguish between
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
6751 this.oldReturnLocal, 6743 this.oldReturnLocal,
6752 this.oldReturnType, 6744 this.oldReturnType,
6753 this.oldResolvedAst, 6745 this.oldResolvedAst,
6754 this.oldStack, 6746 this.oldStack,
6755 this.oldLocalsHandler, 6747 this.oldLocalsHandler,
6756 this.inTryStatement, 6748 this.inTryStatement,
6757 this.allFunctionsCalledOnce, 6749 this.allFunctionsCalledOnce,
6758 this.oldElementInferenceResults) 6750 this.oldElementInferenceResults)
6759 : super(function); 6751 : super(function);
6760 } 6752 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/native/ssa.dart ('k') | pkg/compiler/lib/src/ssa/builder_kernel.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698