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

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

Issue 2808683003: Remove most direct uses of 'backend' and 'compiler' in GraphBuilder. (Closed)
Patch Set: Created 3 years, 8 months 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';
11 import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem; 11 import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem;
12 import '../common/names.dart' show Identifiers, Selectors; 12 import '../common/names.dart' show Identifiers, Selectors;
13 import '../common/tasks.dart' show CompilerTask; 13 import '../common/tasks.dart' show CompilerTask;
14 import '../compiler.dart' show Compiler;
15 import '../constants/constant_system.dart'; 14 import '../constants/constant_system.dart';
16 import '../constants/expressions.dart'; 15 import '../constants/expressions.dart';
17 import '../constants/values.dart'; 16 import '../constants/values.dart';
18 import '../elements/resolution_types.dart'; 17 import '../elements/resolution_types.dart';
19 import '../diagnostics/messages.dart' show Message, MessageTemplate; 18 import '../diagnostics/messages.dart' show Message, MessageTemplate;
20 import '../dump_info.dart' show InfoReporter; 19 import '../dump_info.dart' show InfoReporter;
21 import '../elements/elements.dart'; 20 import '../elements/elements.dart';
22 import '../elements/entities.dart'; 21 import '../elements/entities.dart';
23 import '../elements/modelx.dart' show ConstructorBodyElementX; 22 import '../elements/modelx.dart' show ConstructorBodyElementX;
24 import '../io/source_information.dart'; 23 import '../io/source_information.dart';
(...skipping 21 matching lines...) Expand all
46 import 'nodes.dart'; 45 import 'nodes.dart';
47 import 'optimize.dart'; 46 import 'optimize.dart';
48 import 'ssa_branch_builder.dart'; 47 import 'ssa_branch_builder.dart';
49 import 'type_builder.dart'; 48 import 'type_builder.dart';
50 import 'types.dart'; 49 import 'types.dart';
51 50
52 class SsaBuilderTask extends CompilerTask { 51 class SsaBuilderTask extends CompilerTask {
53 final CodeEmitterTask emitter; 52 final CodeEmitterTask emitter;
54 final JavaScriptBackend backend; 53 final JavaScriptBackend backend;
55 final SourceInformationStrategy sourceInformationFactory; 54 final SourceInformationStrategy sourceInformationFactory;
56 final Compiler compiler;
57 55
58 String get name => 'SSA builder'; 56 String get name => 'SSA builder';
59 57
60 SsaBuilderTask(JavaScriptBackend backend, this.sourceInformationFactory) 58 SsaBuilderTask(JavaScriptBackend backend, this.sourceInformationFactory)
61 : emitter = backend.emitter, 59 : emitter = backend.emitter,
62 backend = backend, 60 backend = backend,
63 compiler = backend.compiler,
64 super(backend.compiler.measurer); 61 super(backend.compiler.measurer);
65 62
66 DiagnosticReporter get reporter => compiler.reporter; 63 DiagnosticReporter get reporter => backend.reporter;
67 64
68 HGraph build(CodegenWorkItem work, ClosedWorld closedWorld) { 65 HGraph build(CodegenWorkItem work, ClosedWorld closedWorld) {
69 return measure(() { 66 return measure(() {
70 MemberElement element = work.element.implementation; 67 MemberElement element = work.element.implementation;
71 return reporter.withCurrentElement(element, () { 68 return reporter.withCurrentElement(element, () {
72 SsaBuilder builder = new SsaBuilder( 69 SsaBuilder builder = new SsaBuilder(
73 work.element.implementation, 70 work.element.implementation,
74 work.resolvedAst, 71 work.resolvedAst,
75 work.registry, 72 work.registry,
76 backend, 73 backend,
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
212 sourceInformationBuilder = 209 sourceInformationBuilder =
213 sourceInformationFactory.createBuilderForContext(resolvedAst); 210 sourceInformationFactory.createBuilderForContext(resolvedAst);
214 graph.sourceInformation = 211 graph.sourceInformation =
215 sourceInformationBuilder.buildVariableDeclaration(); 212 sourceInformationBuilder.buildVariableDeclaration();
216 localsHandler = new LocalsHandler( 213 localsHandler = new LocalsHandler(
217 this, target, null, backend.nativeData, backend.interceptorData); 214 this, target, null, backend.nativeData, backend.interceptorData);
218 loopHandler = new SsaLoopHandler(this); 215 loopHandler = new SsaLoopHandler(this);
219 typeBuilder = new TypeBuilder(this); 216 typeBuilder = new TypeBuilder(this);
220 } 217 }
221 218
222 BackendHelpers get helpers => backend.helpers;
223
224 RuntimeTypesEncoder get rtiEncoder => backend.rtiEncoder;
225
226 Element get targetElement => target; 219 Element get targetElement => target;
227 220
228 /// Reference to resolved elements in [target]'s AST. 221 /// Reference to resolved elements in [target]'s AST.
229 TreeElements get elements => resolvedAst.elements; 222 TreeElements get elements => resolvedAst.elements;
230 223
231 @override 224 @override
232 SemanticSendVisitor get sendVisitor => this; 225 SemanticSendVisitor get sendVisitor => this;
233 226
234 @override 227 @override
235 void visitNode(ast.Node node) { 228 void visitNode(ast.Node node) {
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
390 383
391 /** 384 /**
392 * Try to inline [element] within the correct context of the builder. The 385 * Try to inline [element] within the correct context of the builder. The
393 * insertion point is the state of the builder. 386 * insertion point is the state of the builder.
394 */ 387 */
395 bool tryInlineMethod(MethodElement element, Selector selector, TypeMask mask, 388 bool tryInlineMethod(MethodElement element, Selector selector, TypeMask mask,
396 List<HInstruction> providedArguments, ast.Node currentNode, 389 List<HInstruction> providedArguments, ast.Node currentNode,
397 {ResolutionInterfaceType instanceType}) { 390 {ResolutionInterfaceType instanceType}) {
398 registry.registerStaticUse(new StaticUse.inlining(element)); 391 registry.registerStaticUse(new StaticUse.inlining(element));
399 392
400 if (backend.nativeData.isJsInteropMember(element) && 393 if (nativeData.isJsInteropMember(element) &&
401 !element.isFactoryConstructor) { 394 !element.isFactoryConstructor) {
402 // We only inline factory JavaScript interop constructors. 395 // We only inline factory JavaScript interop constructors.
403 return false; 396 return false;
404 } 397 }
405 398
406 // Ensure that [element] is an implementation element. 399 // Ensure that [element] is an implementation element.
407 element = element.implementation; 400 element = element.implementation;
408 401
409 if (compiler.elementHasCompileTimeError(element)) return false; 402 if (compiler.elementHasCompileTimeError(element)) return false;
410 403
411 MethodElement function = element; 404 MethodElement function = element;
412 ResolvedAst functionResolvedAst = function.resolvedAst; 405 ResolvedAst functionResolvedAst = function.resolvedAst;
413 bool insideLoop = loopDepth > 0 || graph.calledInLoop; 406 bool insideLoop = loopDepth > 0 || graph.calledInLoop;
414 407
415 // Bail out early if the inlining decision is in the cache and we can't 408 // Bail out early if the inlining decision is in the cache and we can't
416 // inline (no need to check the hard constraints). 409 // inline (no need to check the hard constraints).
417 bool cachedCanBeInlined = 410 bool cachedCanBeInlined =
418 backend.inlineCache.canInline(function, insideLoop: insideLoop); 411 inlineCache.canInline(function, insideLoop: insideLoop);
419 if (cachedCanBeInlined == false) return false; 412 if (cachedCanBeInlined == false) return false;
420 413
421 bool meetsHardConstraints() { 414 bool meetsHardConstraints() {
422 if (options.disableInlining) return false; 415 if (options.disableInlining) return false;
423 416
424 assert(invariant( 417 assert(invariant(
425 currentNode != null ? currentNode : function, 418 currentNode != null ? currentNode : function,
426 selector != null || 419 selector != null ||
427 Elements.isStaticOrTopLevel(function) || 420 Elements.isStaticOrTopLevel(function) ||
428 function.isGenerativeConstructorBody, 421 function.isGenerativeConstructorBody,
429 message: "Missing selector for inlining of $function.")); 422 message: "Missing selector for inlining of $function."));
430 if (selector != null) { 423 if (selector != null) {
431 if (!selector.applies(function)) return false; 424 if (!selector.applies(function)) return false;
432 if (mask != null && !mask.canHit(function, selector, closedWorld)) { 425 if (mask != null && !mask.canHit(function, selector, closedWorld)) {
433 return false; 426 return false;
434 } 427 }
435 } 428 }
436 429
437 if (backend.nativeData.isJsInteropMember(function)) return false; 430 if (nativeData.isJsInteropMember(function)) return false;
438 431
439 // Don't inline operator== methods if the parameter can be null. 432 // Don't inline operator== methods if the parameter can be null.
440 if (function.name == '==') { 433 if (function.name == '==') {
441 if (function.enclosingClass != commonElements.objectClass && 434 if (function.enclosingClass != commonElements.objectClass &&
442 providedArguments[1].canBeNull()) { 435 providedArguments[1].canBeNull()) {
443 return false; 436 return false;
444 } 437 }
445 } 438 }
446 439
447 // Generative constructors of native classes should not be called directly 440 // Generative constructors of native classes should not be called directly
448 // and have an extra argument that causes problems with inlining. 441 // and have an extra argument that causes problems with inlining.
449 if (function.isGenerativeConstructor && 442 if (function.isGenerativeConstructor &&
450 backend.nativeData.isNativeOrExtendsNative(function.enclosingClass)) { 443 nativeData.isNativeOrExtendsNative(function.enclosingClass)) {
451 return false; 444 return false;
452 } 445 }
453 446
454 // A generative constructor body is not seen by global analysis, 447 // A generative constructor body is not seen by global analysis,
455 // so we should not query for its type. 448 // so we should not query for its type.
456 if (!function.isGenerativeConstructorBody) { 449 if (!function.isGenerativeConstructorBody) {
457 if (globalInferenceResults.resultOfMember(function).throwsAlways) { 450 if (globalInferenceResults.resultOfMember(function).throwsAlways) {
458 isReachable = false; 451 isReachable = false;
459 return false; 452 return false;
460 } 453 }
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
530 // If a method is called only once, and all the methods in the 523 // If a method is called only once, and all the methods in the
531 // inlining stack are called only once as well, we know we will 524 // inlining stack are called only once as well, we know we will
532 // save on output size by inlining this method. 525 // save on output size by inlining this method.
533 if (isCalledOnce(function)) { 526 if (isCalledOnce(function)) {
534 maxInliningNodes = null; 527 maxInliningNodes = null;
535 } 528 }
536 bool canInline = InlineWeeder.canBeInlined( 529 bool canInline = InlineWeeder.canBeInlined(
537 functionResolvedAst, maxInliningNodes, 530 functionResolvedAst, maxInliningNodes,
538 enableUserAssertions: options.enableUserAssertions); 531 enableUserAssertions: options.enableUserAssertions);
539 if (canInline) { 532 if (canInline) {
540 backend.inlineCache.markAsInlinable(function, insideLoop: insideLoop); 533 inlineCache.markAsInlinable(function, insideLoop: insideLoop);
541 } else { 534 } else {
542 backend.inlineCache 535 inlineCache.markAsNonInlinable(function, insideLoop: insideLoop);
543 .markAsNonInlinable(function, insideLoop: insideLoop);
544 } 536 }
545 return canInline; 537 return canInline;
546 } 538 }
547 539
548 void doInlining() { 540 void doInlining() {
549 // Add an explicit null check on the receiver before doing the 541 // Add an explicit null check on the receiver before doing the
550 // inlining. We use [element] to get the same name in the 542 // inlining. We use [element] to get the same name in the
551 // NoSuchMethodError message as if we had called it. 543 // NoSuchMethodError message as if we had called it.
552 if (function.isInstanceMember && 544 if (function.isInstanceMember &&
553 !function.isGenerativeConstructorBody && 545 !function.isGenerativeConstructorBody &&
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
614 606
615 /** 607 /**
616 * Return null so it is simple to remove the optional parameters completely 608 * Return null so it is simple to remove the optional parameters completely
617 * from interop methods to match JavaScript semantics for omitted arguments. 609 * from interop methods to match JavaScript semantics for omitted arguments.
618 */ 610 */
619 HInstruction handleConstantForOptionalParameterJsInterop(Element parameter) => 611 HInstruction handleConstantForOptionalParameterJsInterop(Element parameter) =>
620 null; 612 null;
621 613
622 HInstruction handleConstantForOptionalParameter(ParameterElement parameter) { 614 HInstruction handleConstantForOptionalParameter(ParameterElement parameter) {
623 ConstantValue constantValue = 615 ConstantValue constantValue =
624 backend.constants.getConstantValue(parameter.constant); 616 constants.getConstantValue(parameter.constant);
625 assert(invariant(parameter, constantValue != null, 617 assert(invariant(parameter, constantValue != null,
626 message: 'No constant computed for $parameter')); 618 message: 'No constant computed for $parameter'));
627 return graph.addConstant(constantValue, closedWorld); 619 return graph.addConstant(constantValue, closedWorld);
628 } 620 }
629 621
630 ClassElement get currentNonClosureClass { 622 ClassElement get currentNonClosureClass {
631 ClassElement cls = sourceElement.enclosingClass; 623 ClassElement cls = sourceElement.enclosingClass;
632 if (cls != null && cls.isClosure) { 624 if (cls != null && cls.isClosure) {
633 dynamic closureClass = cls; 625 dynamic closureClass = cls;
634 // ignore: UNDEFINED_GETTER 626 // ignore: UNDEFINED_GETTER
(...skipping 12 matching lines...) Expand all
647 final List<ResolutionDartType> currentInlinedInstantiations = 639 final List<ResolutionDartType> currentInlinedInstantiations =
648 <ResolutionDartType>[]; 640 <ResolutionDartType>[];
649 641
650 final List<AstInliningState> inliningStack = <AstInliningState>[]; 642 final List<AstInliningState> inliningStack = <AstInliningState>[];
651 643
652 Local returnLocal; 644 Local returnLocal;
653 ResolutionDartType returnType; 645 ResolutionDartType returnType;
654 646
655 ConstantValue getConstantForNode(ast.Node node) { 647 ConstantValue getConstantForNode(ast.Node node) {
656 ConstantValue constantValue = 648 ConstantValue constantValue =
657 backend.constants.getConstantValueForNode(node, elements); 649 constants.getConstantValueForNode(node, elements);
658 assert(invariant(node, constantValue != null, 650 assert(invariant(node, constantValue != null,
659 message: 'No constant computed for $node')); 651 message: 'No constant computed for $node'));
660 return constantValue; 652 return constantValue;
661 } 653 }
662 654
663 HInstruction addConstant(ast.Node node) { 655 HInstruction addConstant(ast.Node node) {
664 return graph.addConstant(getConstantForNode(node), closedWorld); 656 return graph.addConstant(getConstantForNode(node), closedWorld);
665 } 657 }
666 658
667 /** 659 /**
668 * Documentation wanted -- johnniwinther 660 * Documentation wanted -- johnniwinther
669 * 661 *
670 * Invariant: [functionElement] must be an implementation element. 662 * Invariant: [functionElement] must be an implementation element.
671 */ 663 */
672 HGraph buildMethod(MethodElement functionElement) { 664 HGraph buildMethod(MethodElement functionElement) {
673 assert(invariant(functionElement, functionElement.isImplementation)); 665 assert(invariant(functionElement, functionElement.isImplementation));
674 graph.calledInLoop = closedWorld.isCalledInLoop(functionElement); 666 graph.calledInLoop = closedWorld.isCalledInLoop(functionElement);
675 ast.FunctionExpression function = resolvedAst.node; 667 ast.FunctionExpression function = resolvedAst.node;
676 assert(function != null); 668 assert(function != null);
677 assert(elements.getFunctionDefinition(function) != null); 669 assert(elements.getFunctionDefinition(function) != null);
678 openFunction(functionElement, function); 670 openFunction(functionElement, function);
679 String name = functionElement.name; 671 String name = functionElement.name;
680 if (backend.nativeData.isJsInteropMember(functionElement)) { 672 if (nativeData.isJsInteropMember(functionElement)) {
681 push(invokeJsInteropFunction(functionElement, parameters.values.toList(), 673 push(invokeJsInteropFunction(functionElement, parameters.values.toList(),
682 sourceInformationBuilder.buildGeneric(function))); 674 sourceInformationBuilder.buildGeneric(function)));
683 var value = pop(); 675 var value = pop();
684 closeAndGotoExit(new HReturn( 676 closeAndGotoExit(new HReturn(
685 value, sourceInformationBuilder.buildReturn(functionElement.node))); 677 value, sourceInformationBuilder.buildReturn(functionElement.node)));
686 return closeFunction(); 678 return closeFunction();
687 } 679 }
688 assert(invariant(functionElement, !function.modifiers.isExternal)); 680 assert(invariant(functionElement, !function.modifiers.isExternal));
689 681
690 // If [functionElement] is `operator==` we explicitly add a null check at 682 // If [functionElement] is `operator==` we explicitly add a null check at
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
788 * When inlining a function, [:return:] statements are not emitted as 780 * When inlining a function, [:return:] statements are not emitted as
789 * [HReturn] instructions. Instead, the value of a synthetic element is 781 * [HReturn] instructions. Instead, the value of a synthetic element is
790 * updated in the [localsHandler]. This function creates such an element and 782 * updated in the [localsHandler]. This function creates such an element and
791 * stores it in the [returnLocal] field. 783 * stores it in the [returnLocal] field.
792 */ 784 */
793 void setupStateForInlining( 785 void setupStateForInlining(
794 FunctionElement function, List<HInstruction> compiledArguments, 786 FunctionElement function, List<HInstruction> compiledArguments,
795 {ResolutionInterfaceType instanceType}) { 787 {ResolutionInterfaceType instanceType}) {
796 ResolvedAst resolvedAst = function.resolvedAst; 788 ResolvedAst resolvedAst = function.resolvedAst;
797 assert(resolvedAst != null); 789 assert(resolvedAst != null);
798 localsHandler = new LocalsHandler(this, function, instanceType, 790 localsHandler = new LocalsHandler(
799 backend.nativeData, backend.interceptorData); 791 this, function, instanceType, nativeData, interceptorData);
800 localsHandler.closureData = 792 localsHandler.closureData =
801 closureToClassMapper.getClosureToClassMapping(resolvedAst); 793 closureToClassMapper.getClosureToClassMapping(resolvedAst);
802 returnLocal = new SyntheticLocal("result", function); 794 returnLocal = new SyntheticLocal("result", function);
803 localsHandler.updateLocal(returnLocal, graph.addConstantNull(closedWorld)); 795 localsHandler.updateLocal(returnLocal, graph.addConstantNull(closedWorld));
804 796
805 inTryStatement = false; // TODO(lry): why? Document. 797 inTryStatement = false; // TODO(lry): why? Document.
806 798
807 int argumentIndex = 0; 799 int argumentIndex = 0;
808 if (function.isInstanceMember) { 800 if (function.isInstanceMember) {
809 localsHandler.updateLocal(localsHandler.closureData.thisLocal, 801 localsHandler.updateLocal(localsHandler.closureData.thisLocal,
810 compiledArguments[argumentIndex++]); 802 compiledArguments[argumentIndex++]);
811 } 803 }
812 804
813 FunctionSignature signature = function.functionSignature; 805 FunctionSignature signature = function.functionSignature;
814 signature.orderedForEachParameter((ParameterElement parameter) { 806 signature.orderedForEachParameter((ParameterElement parameter) {
815 HInstruction argument = compiledArguments[argumentIndex++]; 807 HInstruction argument = compiledArguments[argumentIndex++];
816 localsHandler.updateLocal(parameter, argument); 808 localsHandler.updateLocal(parameter, argument);
817 }); 809 });
818 810
819 ClassElement enclosing = function.enclosingClass; 811 ClassElement enclosing = function.enclosingClass;
820 if ((function.isConstructor || function.isGenerativeConstructorBody) && 812 if ((function.isConstructor || function.isGenerativeConstructorBody) &&
821 backend.rtiNeed.classNeedsRti(enclosing)) { 813 rtiNeed.classNeedsRti(enclosing)) {
822 enclosing.typeVariables 814 enclosing.typeVariables
823 .forEach((ResolutionTypeVariableType typeVariable) { 815 .forEach((ResolutionTypeVariableType typeVariable) {
824 HInstruction argument = compiledArguments[argumentIndex++]; 816 HInstruction argument = compiledArguments[argumentIndex++];
825 localsHandler.updateLocal( 817 localsHandler.updateLocal(
826 localsHandler.getTypeVariableAsLocal(typeVariable), argument); 818 localsHandler.getTypeVariableAsLocal(typeVariable), argument);
827 }); 819 });
828 } 820 }
829 assert(argumentIndex == compiledArguments.length); 821 assert(argumentIndex == compiledArguments.length);
830 822
831 returnType = signature.type.returnType; 823 returnType = signature.type.returnType;
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
891 void inlineSuperOrRedirect( 883 void inlineSuperOrRedirect(
892 ResolvedAst constructorResolvedAst, 884 ResolvedAst constructorResolvedAst,
893 List<HInstruction> compiledArguments, 885 List<HInstruction> compiledArguments,
894 List<ResolvedAst> constructorResolvedAsts, 886 List<ResolvedAst> constructorResolvedAsts,
895 Map<Element, HInstruction> fieldValues, 887 Map<Element, HInstruction> fieldValues,
896 FunctionElement caller) { 888 FunctionElement caller) {
897 ConstructorElement callee = constructorResolvedAst.element.implementation; 889 ConstructorElement callee = constructorResolvedAst.element.implementation;
898 reporter.withCurrentElement(callee, () { 890 reporter.withCurrentElement(callee, () {
899 constructorResolvedAsts.add(constructorResolvedAst); 891 constructorResolvedAsts.add(constructorResolvedAst);
900 ClassElement enclosingClass = callee.enclosingClass; 892 ClassElement enclosingClass = callee.enclosingClass;
901 if (backend.rtiNeed.classNeedsRti(enclosingClass)) { 893 if (rtiNeed.classNeedsRti(enclosingClass)) {
902 // If [enclosingClass] needs RTI, we have to give a value to its 894 // If [enclosingClass] needs RTI, we have to give a value to its
903 // type parameters. 895 // type parameters.
904 ClassElement currentClass = caller.enclosingClass; 896 ClassElement currentClass = caller.enclosingClass;
905 // For a super constructor call, the type is the supertype of 897 // For a super constructor call, the type is the supertype of
906 // [currentClass]. For a redirecting constructor, the type is 898 // [currentClass]. For a redirecting constructor, the type is
907 // the current type. [InterfaceType.asInstanceOf] takes care 899 // the current type. [InterfaceType.asInstanceOf] takes care
908 // of both. 900 // of both.
909 ResolutionInterfaceType type = 901 ResolutionInterfaceType type =
910 currentClass.thisType.asInstanceOf(enclosingClass); 902 currentClass.thisType.asInstanceOf(enclosingClass);
911 type = localsHandler.substInContext(type); 903 type = localsHandler.substInContext(type);
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
1122 assert(invariant(classElement, classElement.isImplementation)); 1114 assert(invariant(classElement, classElement.isImplementation));
1123 classElement.forEachInstanceField( 1115 classElement.forEachInstanceField(
1124 (ClassElement enclosingClass, FieldElement member) { 1116 (ClassElement enclosingClass, FieldElement member) {
1125 if (compiler.elementHasCompileTimeError(member)) return; 1117 if (compiler.elementHasCompileTimeError(member)) return;
1126 reporter.withCurrentElement(member, () { 1118 reporter.withCurrentElement(member, () {
1127 ResolvedAst fieldResolvedAst = member.resolvedAst; 1119 ResolvedAst fieldResolvedAst = member.resolvedAst;
1128 ast.Expression initializer = fieldResolvedAst.body; 1120 ast.Expression initializer = fieldResolvedAst.body;
1129 if (initializer == null) { 1121 if (initializer == null) {
1130 // Unassigned fields of native classes are not initialized to 1122 // Unassigned fields of native classes are not initialized to
1131 // prevent overwriting pre-initialized native properties. 1123 // prevent overwriting pre-initialized native properties.
1132 if (!backend.nativeData.isNativeOrExtendsNative(classElement)) { 1124 if (!nativeData.isNativeOrExtendsNative(classElement)) {
1133 fieldValues[member] = graph.addConstantNull(closedWorld); 1125 fieldValues[member] = graph.addConstantNull(closedWorld);
1134 } 1126 }
1135 } else { 1127 } else {
1136 ast.Node right = initializer; 1128 ast.Node right = initializer;
1137 ResolvedAst savedResolvedAst = resolvedAst; 1129 ResolvedAst savedResolvedAst = resolvedAst;
1138 resolvedAst = fieldResolvedAst; 1130 resolvedAst = fieldResolvedAst;
1139 final oldElementInferenceResults = elementInferenceResults; 1131 final oldElementInferenceResults = elementInferenceResults;
1140 elementInferenceResults = 1132 elementInferenceResults =
1141 globalInferenceResults.resultOfMember(member); 1133 globalInferenceResults.resultOfMember(member);
1142 // In case the field initializer uses closures, run the 1134 // In case the field initializer uses closures, run the
(...skipping 15 matching lines...) Expand all
1158 * current constructor and super constructors or constructors redirected 1150 * current constructor and super constructors or constructors redirected
1159 * to, starting from the current constructor. 1151 * to, starting from the current constructor.
1160 * - Call the constructor bodies, starting from the constructor(s) in the 1152 * - Call the constructor bodies, starting from the constructor(s) in the
1161 * super class(es). 1153 * super class(es).
1162 */ 1154 */
1163 HGraph buildFactory(ResolvedAst resolvedAst) { 1155 HGraph buildFactory(ResolvedAst resolvedAst) {
1164 ConstructorElement functionElement = resolvedAst.element; 1156 ConstructorElement functionElement = resolvedAst.element;
1165 functionElement = functionElement.implementation; 1157 functionElement = functionElement.implementation;
1166 ClassElement classElement = functionElement.enclosingClass.implementation; 1158 ClassElement classElement = functionElement.enclosingClass.implementation;
1167 bool isNativeUpgradeFactory = 1159 bool isNativeUpgradeFactory =
1168 backend.nativeData.isNativeOrExtendsNative(classElement) && 1160 nativeData.isNativeOrExtendsNative(classElement) &&
1169 !backend.nativeData.isJsInteropClass(classElement); 1161 !nativeData.isJsInteropClass(classElement);
1170 ast.FunctionExpression function; 1162 ast.FunctionExpression function;
1171 if (resolvedAst.kind == ResolvedAstKind.PARSED) { 1163 if (resolvedAst.kind == ResolvedAstKind.PARSED) {
1172 function = resolvedAst.node; 1164 function = resolvedAst.node;
1173 } 1165 }
1174 1166
1175 // Note that constructors (like any other static function) do not need 1167 // Note that constructors (like any other static function) do not need
1176 // to deal with optional arguments. It is the callers job to provide all 1168 // to deal with optional arguments. It is the callers job to provide all
1177 // arguments as if they were positional. 1169 // arguments as if they were positional.
1178 1170
1179 if (inliningStack.isEmpty) { 1171 if (inliningStack.isEmpty) {
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1234 addInlinedInstantiation(type); 1226 addInlinedInstantiation(type);
1235 if (!currentInlinedInstantiations.isEmpty) { 1227 if (!currentInlinedInstantiations.isEmpty) {
1236 instantiatedTypes = 1228 instantiatedTypes =
1237 new List<ResolutionDartType>.from(currentInlinedInstantiations); 1229 new List<ResolutionDartType>.from(currentInlinedInstantiations);
1238 } 1230 }
1239 1231
1240 HInstruction newObject; 1232 HInstruction newObject;
1241 if (!isNativeUpgradeFactory) { 1233 if (!isNativeUpgradeFactory) {
1242 // Create the runtime type information, if needed. 1234 // Create the runtime type information, if needed.
1243 bool hasRtiInput = false; 1235 bool hasRtiInput = false;
1244 if (backend.rtiNeed.classNeedsRtiField(classElement)) { 1236 if (rtiNeed.classNeedsRtiField(classElement)) {
1245 // Read the values of the type arguments and create a 1237 // Read the values of the type arguments and create a
1246 // HTypeInfoExpression to set on the newly create object. 1238 // HTypeInfoExpression to set on the newly create object.
1247 hasRtiInput = true; 1239 hasRtiInput = true;
1248 List<HInstruction> typeArguments = <HInstruction>[]; 1240 List<HInstruction> typeArguments = <HInstruction>[];
1249 classElement.typeVariables 1241 classElement.typeVariables
1250 .forEach((ResolutionTypeVariableType typeVariable) { 1242 .forEach((ResolutionTypeVariableType typeVariable) {
1251 HInstruction argument = localsHandler 1243 HInstruction argument = localsHandler
1252 .readLocal(localsHandler.getTypeVariableAsLocal(typeVariable)); 1244 .readLocal(localsHandler.getTypeVariableAsLocal(typeVariable));
1253 typeArguments.add(argument); 1245 typeArguments.add(argument);
1254 }); 1246 });
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
1321 // The box must be passed before any type variable. 1313 // The box must be passed before any type variable.
1322 ClosureScope scopeData = parameterClosureData.capturingScopes[node]; 1314 ClosureScope scopeData = parameterClosureData.capturingScopes[node];
1323 if (scopeData != null) { 1315 if (scopeData != null) {
1324 bodyCallInputs.add(localsHandler.readLocal(scopeData.boxElement)); 1316 bodyCallInputs.add(localsHandler.readLocal(scopeData.boxElement));
1325 } 1317 }
1326 1318
1327 // Type variables arguments must come after the box (if there is one). 1319 // Type variables arguments must come after the box (if there is one).
1328 ConstructorElement constructor = 1320 ConstructorElement constructor =
1329 constructorResolvedAst.element.implementation; 1321 constructorResolvedAst.element.implementation;
1330 ClassElement currentClass = constructor.enclosingClass; 1322 ClassElement currentClass = constructor.enclosingClass;
1331 if (backend.rtiNeed.classNeedsRti(currentClass)) { 1323 if (rtiNeed.classNeedsRti(currentClass)) {
1332 // If [currentClass] needs RTI, we add the type variables as 1324 // If [currentClass] needs RTI, we add the type variables as
1333 // parameters of the generative constructor body. 1325 // parameters of the generative constructor body.
1334 currentClass.typeVariables 1326 currentClass.typeVariables
1335 .forEach((ResolutionTypeVariableType argument) { 1327 .forEach((ResolutionTypeVariableType argument) {
1336 // TODO(johnniwinther): Substitute [argument] with 1328 // TODO(johnniwinther): Substitute [argument] with
1337 // `localsHandler.substInContext(argument)`. 1329 // `localsHandler.substInContext(argument)`.
1338 bodyCallInputs.add(localsHandler 1330 bodyCallInputs.add(localsHandler
1339 .readLocal(localsHandler.getTypeVariableAsLocal(argument))); 1331 .readLocal(localsHandler.getTypeVariableAsLocal(argument)));
1340 }); 1332 });
1341 } 1333 }
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1373 localsHandler.startFunction(element, node); 1365 localsHandler.startFunction(element, node);
1374 close(new HGoto()).addSuccessor(block); 1366 close(new HGoto()).addSuccessor(block);
1375 1367
1376 open(block); 1368 open(block);
1377 1369
1378 // Add the type parameters of the class as parameters of this method. This 1370 // Add the type parameters of the class as parameters of this method. This
1379 // must be done before adding the normal parameters, because their types 1371 // must be done before adding the normal parameters, because their types
1380 // may contain references to type variables. 1372 // may contain references to type variables.
1381 var enclosing = element.enclosingElement; 1373 var enclosing = element.enclosingElement;
1382 if ((element.isConstructor || element.isGenerativeConstructorBody) && 1374 if ((element.isConstructor || element.isGenerativeConstructorBody) &&
1383 backend.rtiNeed.classNeedsRti(enclosing)) { 1375 rtiNeed.classNeedsRti(enclosing)) {
1384 enclosing.typeVariables 1376 enclosing.typeVariables
1385 .forEach((ResolutionTypeVariableType typeVariable) { 1377 .forEach((ResolutionTypeVariableType typeVariable) {
1386 HParameterValue param = 1378 HParameterValue param =
1387 addParameter(typeVariable.element, commonMasks.nonNullType); 1379 addParameter(typeVariable.element, commonMasks.nonNullType);
1388 localsHandler.directLocals[ 1380 localsHandler.directLocals[
1389 localsHandler.getTypeVariableAsLocal(typeVariable)] = param; 1381 localsHandler.getTypeVariableAsLocal(typeVariable)] = param;
1390 }); 1382 });
1391 } 1383 }
1392 1384
1393 if (element is MethodElement) { 1385 if (element is MethodElement) {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1435 // Otherwise it is a lazy initializer which does not have parameters. 1427 // Otherwise it is a lazy initializer which does not have parameters.
1436 assert(element is VariableElement); 1428 assert(element is VariableElement);
1437 } 1429 }
1438 1430
1439 insertTraceCall(element); 1431 insertTraceCall(element);
1440 insertCoverageCall(element); 1432 insertCoverageCall(element);
1441 } 1433 }
1442 1434
1443 insertTraceCall(Element element) { 1435 insertTraceCall(Element element) {
1444 if (JavaScriptBackend.TRACE_METHOD == 'console') { 1436 if (JavaScriptBackend.TRACE_METHOD == 'console') {
1445 if (element == backend.helpers.traceHelper) return; 1437 if (element == helpers.traceHelper) return;
1446 n(e) => e == null ? '' : e.name; 1438 n(e) => e == null ? '' : e.name;
1447 String name = "${n(element.library)}:${n(element.enclosingClass)}." 1439 String name = "${n(element.library)}:${n(element.enclosingClass)}."
1448 "${n(element)}"; 1440 "${n(element)}";
1449 HConstant nameConstant = addConstantString(name); 1441 HConstant nameConstant = addConstantString(name);
1450 add(new HInvokeStatic(backend.helpers.traceHelper, 1442 add(new HInvokeStatic(helpers.traceHelper, <HInstruction>[nameConstant],
1451 <HInstruction>[nameConstant], commonMasks.dynamicType)); 1443 commonMasks.dynamicType));
1452 } 1444 }
1453 } 1445 }
1454 1446
1455 insertCoverageCall(Element element) { 1447 insertCoverageCall(Element element) {
1456 if (JavaScriptBackend.TRACE_METHOD == 'post') { 1448 if (JavaScriptBackend.TRACE_METHOD == 'post') {
1457 if (element == backend.helpers.traceHelper) return; 1449 if (element == helpers.traceHelper) return;
1458 // TODO(sigmund): create a better uuid for elements. 1450 // TODO(sigmund): create a better uuid for elements.
1459 HConstant idConstant = 1451 HConstant idConstant =
1460 graph.addConstantInt(element.hashCode, closedWorld); 1452 graph.addConstantInt(element.hashCode, closedWorld);
1461 HConstant nameConstant = addConstantString(element.name); 1453 HConstant nameConstant = addConstantString(element.name);
1462 add(new HInvokeStatic(backend.helpers.traceHelper, 1454 add(new HInvokeStatic(helpers.traceHelper,
1463 <HInstruction>[idConstant, nameConstant], commonMasks.dynamicType)); 1455 <HInstruction>[idConstant, nameConstant], commonMasks.dynamicType));
1464 } 1456 }
1465 } 1457 }
1466 1458
1467 void assertIsSubtype(ast.Node node, ResolutionDartType subtype, 1459 void assertIsSubtype(ast.Node node, ResolutionDartType subtype,
1468 ResolutionDartType supertype, String message) { 1460 ResolutionDartType supertype, String message) {
1469 HInstruction subtypeInstruction = typeBuilder.analyzeTypeArgument( 1461 HInstruction subtypeInstruction = typeBuilder.analyzeTypeArgument(
1470 localsHandler.substInContext(subtype), sourceElement); 1462 localsHandler.substInContext(subtype), sourceElement);
1471 HInstruction supertypeInstruction = typeBuilder.analyzeTypeArgument( 1463 HInstruction supertypeInstruction = typeBuilder.analyzeTypeArgument(
1472 localsHandler.substInContext(supertype), sourceElement); 1464 localsHandler.substInContext(supertype), sourceElement);
(...skipping 593 matching lines...) Expand 10 before | Expand all | Expand 10 after
2066 assert(invariant(node, element == null || element.isMalformed)); 2058 assert(invariant(node, element == null || element.isMalformed));
2067 // TODO(ahe): Do something like the above, that is, emit a runtime 2059 // TODO(ahe): Do something like the above, that is, emit a runtime
2068 // error. 2060 // error.
2069 stack.add(graph.addConstantNull(closedWorld)); 2061 stack.add(graph.addConstantNull(closedWorld));
2070 } 2062 }
2071 } 2063 }
2072 2064
2073 /// Read a static or top level [field] of constant value. 2065 /// Read a static or top level [field] of constant value.
2074 void generateStaticConstGet(ast.Send node, FieldElement field, 2066 void generateStaticConstGet(ast.Send node, FieldElement field,
2075 ConstantExpression constant, SourceInformation sourceInformation) { 2067 ConstantExpression constant, SourceInformation sourceInformation) {
2076 ConstantValue value = backend.constants.getConstantValue(constant); 2068 ConstantValue value = constants.getConstantValue(constant);
2077 HConstant instruction; 2069 HConstant instruction;
2078 // Constants that are referred via a deferred prefix should be referred 2070 // Constants that are referred via a deferred prefix should be referred
2079 // by reference. 2071 // by reference.
2080 PrefixElement prefix = 2072 PrefixElement prefix =
2081 compiler.deferredLoadTask.deferredPrefixElement(node, elements); 2073 compiler.deferredLoadTask.deferredPrefixElement(node, elements);
2082 if (prefix != null) { 2074 if (prefix != null) {
2083 instruction = graph.addDeferredConstant( 2075 instruction = graph.addDeferredConstant(
2084 value, prefix, sourceInformation, compiler, closedWorld); 2076 value, prefix, sourceInformation, compiler, closedWorld);
2085 } else { 2077 } else {
2086 instruction = graph.addConstant(value, closedWorld, 2078 instruction = graph.addConstant(value, closedWorld,
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after
2412 List<HInstruction> inputs = <HInstruction>[expression, runtimeType]; 2404 List<HInstruction> inputs = <HInstruction>[expression, runtimeType];
2413 pushInvokeStatic(null, helper, inputs, typeMask: commonMasks.boolType); 2405 pushInvokeStatic(null, helper, inputs, typeMask: commonMasks.boolType);
2414 HInstruction call = pop(); 2406 HInstruction call = pop();
2415 return new HIs.variable(type, expression, call, commonMasks.boolType); 2407 return new HIs.variable(type, expression, call, commonMasks.boolType);
2416 } else if (RuntimeTypesSubstitutions.hasTypeArguments(type)) { 2408 } else if (RuntimeTypesSubstitutions.hasTypeArguments(type)) {
2417 ClassElement element = type.element; 2409 ClassElement element = type.element;
2418 MethodElement helper = helpers.checkSubtype; 2410 MethodElement helper = helpers.checkSubtype;
2419 HInstruction representations = 2411 HInstruction representations =
2420 typeBuilder.buildTypeArgumentRepresentations(type, sourceElement); 2412 typeBuilder.buildTypeArgumentRepresentations(type, sourceElement);
2421 add(representations); 2413 add(representations);
2422 js.Name operator = backend.namer.operatorIs(element); 2414 js.Name operator = namer.operatorIs(element);
2423 HInstruction isFieldName = addConstantStringFromName(operator); 2415 HInstruction isFieldName = addConstantStringFromName(operator);
2424 HInstruction asFieldName = closedWorld.hasAnyStrictSubtype(element) 2416 HInstruction asFieldName = closedWorld.hasAnyStrictSubtype(element)
2425 ? addConstantStringFromName(backend.namer.substitutionName(element)) 2417 ? addConstantStringFromName(namer.substitutionName(element))
2426 : graph.addConstantNull(closedWorld); 2418 : graph.addConstantNull(closedWorld);
2427 List<HInstruction> inputs = <HInstruction>[ 2419 List<HInstruction> inputs = <HInstruction>[
2428 expression, 2420 expression,
2429 isFieldName, 2421 isFieldName,
2430 representations, 2422 representations,
2431 asFieldName 2423 asFieldName
2432 ]; 2424 ];
2433 pushInvokeStatic(node, helper, inputs, typeMask: commonMasks.boolType); 2425 pushInvokeStatic(node, helper, inputs, typeMask: commonMasks.boolType);
2434 HInstruction call = pop(); 2426 HInstruction call = pop();
2435 return new HIs.compound(type, expression, call, commonMasks.boolType); 2427 return new HIs.compound(type, expression, call, commonMasks.boolType);
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
2491 HInstruction compileArgument(ast.Node argument) { 2483 HInstruction compileArgument(ast.Node argument) {
2492 visit(argument); 2484 visit(argument);
2493 return pop(); 2485 return pop();
2494 } 2486 }
2495 2487
2496 return Elements.makeArgumentsList<HInstruction>( 2488 return Elements.makeArgumentsList<HInstruction>(
2497 callStructure, 2489 callStructure,
2498 arguments, 2490 arguments,
2499 element.implementation, 2491 element.implementation,
2500 compileArgument, 2492 compileArgument,
2501 backend.nativeData.isJsInteropMember(element) 2493 nativeData.isJsInteropMember(element)
2502 ? handleConstantForOptionalParameterJsInterop 2494 ? handleConstantForOptionalParameterJsInterop
2503 : handleConstantForOptionalParameter); 2495 : handleConstantForOptionalParameter);
2504 } 2496 }
2505 2497
2506 void addGenericSendArgumentsToList( 2498 void addGenericSendArgumentsToList(
2507 Link<ast.Node> link, List<HInstruction> list) { 2499 Link<ast.Node> link, List<HInstruction> list) {
2508 for (; !link.isEmpty; link = link.tail) { 2500 for (; !link.isEmpty; link = link.tail) {
2509 visit(link.head); 2501 visit(link.head);
2510 list.add(pop()); 2502 list.add(pop());
2511 } 2503 }
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
2661 } 2653 }
2662 push(new HStringConcat(inputs[0], inputs[1], commonMasks.stringType)); 2654 push(new HStringConcat(inputs[0], inputs[1], commonMasks.stringType));
2663 } 2655 }
2664 2656
2665 void handleForeignJsCurrentIsolateContext(ast.Send node) { 2657 void handleForeignJsCurrentIsolateContext(ast.Send node) {
2666 if (!node.arguments.isEmpty) { 2658 if (!node.arguments.isEmpty) {
2667 reporter.internalError( 2659 reporter.internalError(
2668 node, 'Too many arguments to JS_CURRENT_ISOLATE_CONTEXT.'); 2660 node, 'Too many arguments to JS_CURRENT_ISOLATE_CONTEXT.');
2669 } 2661 }
2670 2662
2671 if (!backend.backendUsage.isIsolateInUse) { 2663 if (!backendUsage.isIsolateInUse) {
2672 // If the isolate library is not used, we just generate code 2664 // If the isolate library is not used, we just generate code
2673 // to fetch the static state. 2665 // to fetch the static state.
2674 String name = backend.namer.staticStateHolder; 2666 String name = namer.staticStateHolder;
2675 push(new HForeignCode( 2667 push(new HForeignCode(
2676 js.js.parseForeignJS(name), commonMasks.dynamicType, <HInstruction>[], 2668 js.js.parseForeignJS(name), commonMasks.dynamicType, <HInstruction>[],
2677 nativeBehavior: native.NativeBehavior.DEPENDS_OTHER)); 2669 nativeBehavior: native.NativeBehavior.DEPENDS_OTHER));
2678 } else { 2670 } else {
2679 // Call a helper method from the isolate library. The isolate 2671 // Call a helper method from the isolate library. The isolate
2680 // library uses its own isolate structure, that encapsulates 2672 // library uses its own isolate structure, that encapsulates
2681 // Leg's isolate. 2673 // Leg's isolate.
2682 MethodElement element = helpers.currentIsolate; 2674 MethodElement element = helpers.currentIsolate;
2683 if (element == null) { 2675 if (element == null) {
2684 reporter.internalError(node, 'Isolate library and compiler mismatch.'); 2676 reporter.internalError(node, 'Isolate library and compiler mismatch.');
(...skipping 22 matching lines...) Expand all
2707 } 2699 }
2708 ast.LiteralString string = argument.asLiteralString(); 2700 ast.LiteralString string = argument.asLiteralString();
2709 if (string == null) { 2701 if (string == null) {
2710 reporter.reportErrorMessage(argument, MessageKind.GENERIC, 2702 reporter.reportErrorMessage(argument, MessageKind.GENERIC,
2711 {'text': 'Error: Expected a literal string.'}); 2703 {'text': 'Error: Expected a literal string.'});
2712 } 2704 }
2713 String name = string.dartString.slowToString(); 2705 String name = string.dartString.slowToString();
2714 bool value = false; 2706 bool value = false;
2715 switch (name) { 2707 switch (name) {
2716 case 'MUST_RETAIN_METADATA': 2708 case 'MUST_RETAIN_METADATA':
2717 value = backend.mirrorsData.mustRetainMetadata; 2709 value = mirrorsData.mustRetainMetadata;
2718 break; 2710 break;
2719 case 'USE_CONTENT_SECURITY_POLICY': 2711 case 'USE_CONTENT_SECURITY_POLICY':
2720 value = options.useContentSecurityPolicy; 2712 value = options.useContentSecurityPolicy;
2721 break; 2713 break;
2722 default: 2714 default:
2723 reporter.reportErrorMessage(node, MessageKind.GENERIC, 2715 reporter.reportErrorMessage(node, MessageKind.GENERIC,
2724 {'text': 'Error: Unknown internal flag "$name".'}); 2716 {'text': 'Error: Unknown internal flag "$name".'});
2725 } 2717 }
2726 stack.add(graph.addConstantBool(value, closedWorld)); 2718 stack.add(graph.addConstantBool(value, closedWorld));
2727 } 2719 }
(...skipping 19 matching lines...) Expand all
2747 Element element = elements[argument]; 2739 Element element = elements[argument];
2748 if (element == null || 2740 if (element == null ||
2749 element is! EnumConstantElement || 2741 element is! EnumConstantElement ||
2750 element.enclosingClass != helpers.jsGetNameEnum) { 2742 element.enclosingClass != helpers.jsGetNameEnum) {
2751 reporter.reportErrorMessage(argument, MessageKind.GENERIC, 2743 reporter.reportErrorMessage(argument, MessageKind.GENERIC,
2752 {'text': 'Error: Expected a JsGetName enum value.'}); 2744 {'text': 'Error: Expected a JsGetName enum value.'});
2753 } 2745 }
2754 EnumConstantElement enumConstant = element; 2746 EnumConstantElement enumConstant = element;
2755 int index = enumConstant.index; 2747 int index = enumConstant.index;
2756 stack.add(addConstantStringFromName( 2748 stack.add(addConstantStringFromName(
2757 backend.namer.getNameForJsGetName(argument, JsGetName.values[index]))); 2749 namer.getNameForJsGetName(argument, JsGetName.values[index])));
2758 } 2750 }
2759 2751
2760 void handleForeignJsBuiltin(ast.Send node) { 2752 void handleForeignJsBuiltin(ast.Send node) {
2761 List<ast.Node> arguments = node.arguments.toList(); 2753 List<ast.Node> arguments = node.arguments.toList();
2762 ast.Node argument; 2754 ast.Node argument;
2763 if (arguments.length < 2) { 2755 if (arguments.length < 2) {
2764 reporter.reportErrorMessage(node, MessageKind.GENERIC, 2756 reporter.reportErrorMessage(node, MessageKind.GENERIC,
2765 {'text': 'Error: Expected at least two arguments to JS_BUILTIN.'}); 2757 {'text': 'Error: Expected at least two arguments to JS_BUILTIN.'});
2766 } 2758 }
2767 2759
2768 Element builtinElement = elements[arguments[1]]; 2760 Element builtinElement = elements[arguments[1]];
2769 if (builtinElement == null || 2761 if (builtinElement == null ||
2770 (builtinElement is! EnumConstantElement) || 2762 (builtinElement is! EnumConstantElement) ||
2771 builtinElement.enclosingClass != helpers.jsBuiltinEnum) { 2763 builtinElement.enclosingClass != helpers.jsBuiltinEnum) {
2772 reporter.reportErrorMessage(argument, MessageKind.GENERIC, 2764 reporter.reportErrorMessage(argument, MessageKind.GENERIC,
2773 {'text': 'Error: Expected a JsBuiltin enum value.'}); 2765 {'text': 'Error: Expected a JsBuiltin enum value.'});
2774 } 2766 }
2775 EnumConstantElement enumConstant = builtinElement; 2767 EnumConstantElement enumConstant = builtinElement;
2776 int index = enumConstant.index; 2768 int index = enumConstant.index;
2777 2769
2778 js.Template template = 2770 js.Template template = emitter.builtinTemplateFor(JsBuiltin.values[index]);
2779 backend.emitter.builtinTemplateFor(JsBuiltin.values[index]);
2780 2771
2781 List<HInstruction> compiledArguments = <HInstruction>[]; 2772 List<HInstruction> compiledArguments = <HInstruction>[];
2782 for (int i = 2; i < arguments.length; i++) { 2773 for (int i = 2; i < arguments.length; i++) {
2783 visit(arguments[i]); 2774 visit(arguments[i]);
2784 compiledArguments.add(pop()); 2775 compiledArguments.add(pop());
2785 } 2776 }
2786 2777
2787 native.NativeBehavior nativeBehavior = elements.getNativeData(node); 2778 native.NativeBehavior nativeBehavior = elements.getNativeData(node);
2788 assert(invariant(node, nativeBehavior != null, 2779 assert(invariant(node, nativeBehavior != null,
2789 message: "No NativeBehavior for $node")); 2780 message: "No NativeBehavior for $node"));
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
2822 reporter.reportErrorMessage(arguments[1], MessageKind.GENERIC, { 2813 reporter.reportErrorMessage(arguments[1], MessageKind.GENERIC, {
2823 'text': 'Error: Expected String as second argument ' 2814 'text': 'Error: Expected String as second argument '
2824 'to JS_EMBEDDED_GLOBAL.' 2815 'to JS_EMBEDDED_GLOBAL.'
2825 }); 2816 });
2826 return; 2817 return;
2827 } 2818 }
2828 HConstant hConstant = globalNameHNode; 2819 HConstant hConstant = globalNameHNode;
2829 StringConstantValue constant = hConstant.constant; 2820 StringConstantValue constant = hConstant.constant;
2830 String globalName = constant.primitiveValue.slowToString(); 2821 String globalName = constant.primitiveValue.slowToString();
2831 js.Template expr = js.js.expressionTemplateYielding( 2822 js.Template expr = js.js.expressionTemplateYielding(
2832 backend.emitter.generateEmbeddedGlobalAccess(globalName)); 2823 emitter.generateEmbeddedGlobalAccess(globalName));
2833 native.NativeBehavior nativeBehavior = elements.getNativeData(node); 2824 native.NativeBehavior nativeBehavior = elements.getNativeData(node);
2834 assert(invariant(node, nativeBehavior != null, 2825 assert(invariant(node, nativeBehavior != null,
2835 message: "No NativeBehavior for $node")); 2826 message: "No NativeBehavior for $node"));
2836 TypeMask ssaType = 2827 TypeMask ssaType =
2837 TypeMaskFactory.fromNativeBehavior(nativeBehavior, closedWorld); 2828 TypeMaskFactory.fromNativeBehavior(nativeBehavior, closedWorld);
2838 push(new HForeignCode(expr, ssaType, const [], 2829 push(new HForeignCode(expr, ssaType, const [],
2839 nativeBehavior: nativeBehavior)); 2830 nativeBehavior: nativeBehavior));
2840 } 2831 }
2841 2832
2842 void handleJsInterceptorConstant(ast.Send node) { 2833 void handleJsInterceptorConstant(ast.Send node) {
(...skipping 15 matching lines...) Expand all
2858 } 2849 }
2859 } 2850 }
2860 } 2851 }
2861 reporter.reportErrorMessage( 2852 reporter.reportErrorMessage(
2862 node, MessageKind.WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT); 2853 node, MessageKind.WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT);
2863 stack.add(graph.addConstantNull(closedWorld)); 2854 stack.add(graph.addConstantNull(closedWorld));
2864 } 2855 }
2865 2856
2866 void handleForeignJsCallInIsolate(ast.Send node) { 2857 void handleForeignJsCallInIsolate(ast.Send node) {
2867 Link<ast.Node> link = node.arguments; 2858 Link<ast.Node> link = node.arguments;
2868 if (!backend.backendUsage.isIsolateInUse) { 2859 if (!backendUsage.isIsolateInUse) {
2869 // If the isolate library is not used, we just invoke the 2860 // If the isolate library is not used, we just invoke the
2870 // closure. 2861 // closure.
2871 visit(link.tail.head); 2862 visit(link.tail.head);
2872 push(new HInvokeClosure(new Selector.callClosure(0), 2863 push(new HInvokeClosure(new Selector.callClosure(0),
2873 <HInstruction>[pop()], commonMasks.dynamicType)); 2864 <HInstruction>[pop()], commonMasks.dynamicType));
2874 } else { 2865 } else {
2875 // Call a helper method from the isolate library. 2866 // Call a helper method from the isolate library.
2876 MethodElement element = helpers.callInIsolate; 2867 MethodElement element = helpers.callInIsolate;
2877 if (element == null) { 2868 if (element == null) {
2878 reporter.internalError(node, 'Isolate library and compiler mismatch.'); 2869 reporter.internalError(node, 'Isolate library and compiler mismatch.');
(...skipping 21 matching lines...) Expand all
2900 // and implementation signatures. Currently it is need because the 2891 // and implementation signatures. Currently it is need because the
2901 // signatures have different elements for parameters. 2892 // signatures have different elements for parameters.
2902 FunctionElement implementation = function.implementation; 2893 FunctionElement implementation = function.implementation;
2903 FunctionSignature params = implementation.functionSignature; 2894 FunctionSignature params = implementation.functionSignature;
2904 if (params.optionalParameterCount != 0) { 2895 if (params.optionalParameterCount != 0) {
2905 reporter.internalError( 2896 reporter.internalError(
2906 closure, '"$name" does not handle closure with optional parameters.'); 2897 closure, '"$name" does not handle closure with optional parameters.');
2907 } 2898 }
2908 2899
2909 push(new HForeignCode( 2900 push(new HForeignCode(
2910 js.js.expressionTemplateYielding( 2901 js.js
2911 backend.emitter.staticFunctionAccess(function)), 2902 .expressionTemplateYielding(emitter.staticFunctionAccess(function)),
2912 commonMasks.dynamicType, 2903 commonMasks.dynamicType,
2913 <HInstruction>[], 2904 <HInstruction>[],
2914 nativeBehavior: native.NativeBehavior.PURE, 2905 nativeBehavior: native.NativeBehavior.PURE,
2915 foreignFunction: function)); 2906 foreignFunction: function));
2916 return params; 2907 return params;
2917 } 2908 }
2918 2909
2919 void handleForeignDartClosureToJs(ast.Send node, String name) { 2910 void handleForeignDartClosureToJs(ast.Send node, String name) {
2920 // TODO(ahe): This implements DART_CLOSURE_TO_JS and should probably take 2911 // TODO(ahe): This implements DART_CLOSURE_TO_JS and should probably take
2921 // care to wrap the closure in another closure that saves the current 2912 // care to wrap the closure in another closure that saves the current
2922 // isolate. 2913 // isolate.
2923 handleForeignRawFunctionRef(node, name); 2914 handleForeignRawFunctionRef(node, name);
2924 } 2915 }
2925 2916
2926 void handleForeignJsSetStaticState(ast.Send node) { 2917 void handleForeignJsSetStaticState(ast.Send node) {
2927 if (node.arguments.isEmpty || !node.arguments.tail.isEmpty) { 2918 if (node.arguments.isEmpty || !node.arguments.tail.isEmpty) {
2928 reporter.internalError( 2919 reporter.internalError(
2929 node.argumentsNode, 'Exactly one argument required.'); 2920 node.argumentsNode, 'Exactly one argument required.');
2930 } 2921 }
2931 visit(node.arguments.head); 2922 visit(node.arguments.head);
2932 String isolateName = backend.namer.staticStateHolder; 2923 String isolateName = namer.staticStateHolder;
2933 SideEffects sideEffects = new SideEffects.empty(); 2924 SideEffects sideEffects = new SideEffects.empty();
2934 sideEffects.setAllSideEffects(); 2925 sideEffects.setAllSideEffects();
2935 push(new HForeignCode(js.js.parseForeignJS("$isolateName = #"), 2926 push(new HForeignCode(js.js.parseForeignJS("$isolateName = #"),
2936 commonMasks.dynamicType, <HInstruction>[pop()], 2927 commonMasks.dynamicType, <HInstruction>[pop()],
2937 nativeBehavior: native.NativeBehavior.CHANGES_OTHER, 2928 nativeBehavior: native.NativeBehavior.CHANGES_OTHER,
2938 effects: sideEffects)); 2929 effects: sideEffects));
2939 } 2930 }
2940 2931
2941 void handleForeignJsGetStaticState(ast.Send node) { 2932 void handleForeignJsGetStaticState(ast.Send node) {
2942 if (!node.arguments.isEmpty) { 2933 if (!node.arguments.isEmpty) {
2943 reporter.internalError(node.argumentsNode, 'Too many arguments.'); 2934 reporter.internalError(node.argumentsNode, 'Too many arguments.');
2944 } 2935 }
2945 push(new HForeignCode(js.js.parseForeignJS(backend.namer.staticStateHolder), 2936 push(new HForeignCode(js.js.parseForeignJS(namer.staticStateHolder),
2946 commonMasks.dynamicType, <HInstruction>[], 2937 commonMasks.dynamicType, <HInstruction>[],
2947 nativeBehavior: native.NativeBehavior.DEPENDS_OTHER)); 2938 nativeBehavior: native.NativeBehavior.DEPENDS_OTHER));
2948 } 2939 }
2949 2940
2950 void handleForeignSend(ast.Send node, FunctionElement element) { 2941 void handleForeignSend(ast.Send node, FunctionElement element) {
2951 String name = element.name; 2942 String name = element.name;
2952 if (name == BackendHelpers.JS) { 2943 if (name == BackendHelpers.JS) {
2953 handleForeignJs(node); 2944 handleForeignJs(node);
2954 } else if (name == 'JS_CURRENT_ISOLATE_CONTEXT') { 2945 } else if (name == 'JS_CURRENT_ISOLATE_CONTEXT') {
2955 handleForeignJsCurrentIsolateContext(node); 2946 handleForeignJsCurrentIsolateContext(node);
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
3001 generateSuperNoSuchMethodSend( 2992 generateSuperNoSuchMethodSend(
3002 ast.Send node, Selector selector, List<HInstruction> arguments) { 2993 ast.Send node, Selector selector, List<HInstruction> arguments) {
3003 String name = selector.name; 2994 String name = selector.name;
3004 2995
3005 ClassElement cls = currentNonClosureClass; 2996 ClassElement cls = currentNonClosureClass;
3006 MethodElement element = cls.lookupSuperMember(Identifiers.noSuchMethod_); 2997 MethodElement element = cls.lookupSuperMember(Identifiers.noSuchMethod_);
3007 if (!Selectors.noSuchMethod_.signatureApplies(element)) { 2998 if (!Selectors.noSuchMethod_.signatureApplies(element)) {
3008 ClassElement objectClass = commonElements.objectClass; 2999 ClassElement objectClass = commonElements.objectClass;
3009 element = objectClass.lookupMember(Identifiers.noSuchMethod_); 3000 element = objectClass.lookupMember(Identifiers.noSuchMethod_);
3010 } 3001 }
3011 if (backend.backendUsage.isInvokeOnUsed && 3002 if (backendUsage.isInvokeOnUsed && !element.enclosingClass.isObject) {
3012 !element.enclosingClass.isObject) {
3013 // Register the call as dynamic if [noSuchMethod] on the super 3003 // Register the call as dynamic if [noSuchMethod] on the super
3014 // class is _not_ the default implementation from [Object], in 3004 // class is _not_ the default implementation from [Object], in
3015 // case the [noSuchMethod] implementation calls 3005 // case the [noSuchMethod] implementation calls
3016 // [JSInvocationMirror._invokeOn]. 3006 // [JSInvocationMirror._invokeOn].
3017 // TODO(johnniwinther): Register this more precisely. 3007 // TODO(johnniwinther): Register this more precisely.
3018 registry?.registerDynamicUse(new DynamicUse(selector, null)); 3008 registry?.registerDynamicUse(new DynamicUse(selector, null));
3019 } 3009 }
3020 String publicName = name; 3010 String publicName = name;
3021 if (selector.isSetter) publicName += '='; 3011 if (selector.isSetter) publicName += '=';
3022 3012
3023 ConstantValue nameConstant = 3013 ConstantValue nameConstant =
3024 constantSystem.createString(new ast.DartString.literal(publicName)); 3014 constantSystem.createString(new ast.DartString.literal(publicName));
3025 3015
3026 js.Name internalName = backend.namer.invocationName(selector); 3016 js.Name internalName = namer.invocationName(selector);
3027 3017
3028 MethodElement createInvocationMirror = helpers.createInvocationMirror; 3018 MethodElement createInvocationMirror = helpers.createInvocationMirror;
3029 var argumentsInstruction = buildLiteralList(arguments); 3019 var argumentsInstruction = buildLiteralList(arguments);
3030 add(argumentsInstruction); 3020 add(argumentsInstruction);
3031 3021
3032 var argumentNames = new List<HInstruction>(); 3022 var argumentNames = new List<HInstruction>();
3033 for (String argumentName in selector.namedArguments) { 3023 for (String argumentName in selector.namedArguments) {
3034 ConstantValue argumentNameConstant = 3024 ConstantValue argumentNameConstant =
3035 constantSystem.createString(new ast.DartString.literal(argumentName)); 3025 constantSystem.createString(new ast.DartString.literal(argumentName));
3036 argumentNames.add(graph.addConstant(argumentNameConstant, closedWorld)); 3026 argumentNames.add(graph.addConstant(argumentNameConstant, closedWorld));
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
3231 bool needsSubstitutionForTypeVariableAccess(ClassElement cls) { 3221 bool needsSubstitutionForTypeVariableAccess(ClassElement cls) {
3232 if (closedWorld.isUsedAsMixin(cls)) return true; 3222 if (closedWorld.isUsedAsMixin(cls)) return true;
3233 3223
3234 return closedWorld.anyStrictSubclassOf(cls, (ClassElement subclass) { 3224 return closedWorld.anyStrictSubclassOf(cls, (ClassElement subclass) {
3235 return !rtiSubstitutions.isTrivialSubstitution(subclass, cls); 3225 return !rtiSubstitutions.isTrivialSubstitution(subclass, cls);
3236 }); 3226 });
3237 } 3227 }
3238 3228
3239 HInstruction handleListConstructor(ResolutionInterfaceType type, 3229 HInstruction handleListConstructor(ResolutionInterfaceType type,
3240 ast.Node currentNode, HInstruction newObject) { 3230 ast.Node currentNode, HInstruction newObject) {
3241 if (!backend.rtiNeed.classNeedsRti(type.element) || type.treatAsRaw) { 3231 if (!rtiNeed.classNeedsRti(type.element) || type.treatAsRaw) {
3242 return newObject; 3232 return newObject;
3243 } 3233 }
3244 List<HInstruction> inputs = <HInstruction>[]; 3234 List<HInstruction> inputs = <HInstruction>[];
3245 type = localsHandler.substInContext(type); 3235 type = localsHandler.substInContext(type);
3246 type.typeArguments.forEach((ResolutionDartType argument) { 3236 type.typeArguments.forEach((ResolutionDartType argument) {
3247 inputs.add(typeBuilder.analyzeTypeArgument(argument, sourceElement)); 3237 inputs.add(typeBuilder.analyzeTypeArgument(argument, sourceElement));
3248 }); 3238 });
3249 // TODO(15489): Register at codegen. 3239 // TODO(15489): Register at codegen.
3250 registry?.registerInstantiation(type); 3240 registry?.registerInstantiation(type);
3251 return callSetRuntimeTypeInfoWithTypeArguments(type, inputs, newObject); 3241 return callSetRuntimeTypeInfoWithTypeArguments(type, inputs, newObject);
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
3296 } else if (isGrowableListConstructorCall) { 3286 } else if (isGrowableListConstructorCall) {
3297 TypeMask inferred = _inferredTypeOfNewList(send); 3287 TypeMask inferred = _inferredTypeOfNewList(send);
3298 return inferred.containsAll(closedWorld) 3288 return inferred.containsAll(closedWorld)
3299 ? commonMasks.extendableArrayType 3289 ? commonMasks.extendableArrayType
3300 : inferred; 3290 : inferred;
3301 } else if (Elements.isConstructorOfTypedArraySubclass( 3291 } else if (Elements.isConstructorOfTypedArraySubclass(
3302 originalElement, closedWorld)) { 3292 originalElement, closedWorld)) {
3303 isFixedList = true; 3293 isFixedList = true;
3304 TypeMask inferred = _inferredTypeOfNewList(send); 3294 TypeMask inferred = _inferredTypeOfNewList(send);
3305 ClassElement cls = element.enclosingClass; 3295 ClassElement cls = element.enclosingClass;
3306 assert(backend.nativeData.isNativeClass(cls)); 3296 assert(nativeData.isNativeClass(cls));
3307 return inferred.containsAll(closedWorld) 3297 return inferred.containsAll(closedWorld)
3308 ? new TypeMask.nonNullExact(cls, closedWorld) 3298 ? new TypeMask.nonNullExact(cls, closedWorld)
3309 : inferred; 3299 : inferred;
3310 } else if (element.isGenerativeConstructor) { 3300 } else if (element.isGenerativeConstructor) {
3311 ClassElement cls = element.enclosingClass; 3301 ClassElement cls = element.enclosingClass;
3312 if (cls.isAbstract) { 3302 if (cls.isAbstract) {
3313 // An error will be thrown. 3303 // An error will be thrown.
3314 return new TypeMask.nonNullEmpty(); 3304 return new TypeMask.nonNullEmpty();
3315 } else { 3305 } else {
3316 return new TypeMask.nonNullExact(cls, closedWorld); 3306 return new TypeMask.nonNullExact(cls, closedWorld);
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
3384 // calling [makeStaticArgumentList]. 3374 // calling [makeStaticArgumentList].
3385 constructorImplementation = constructor.implementation; 3375 constructorImplementation = constructor.implementation;
3386 if (constructorImplementation.isMalformed || 3376 if (constructorImplementation.isMalformed ||
3387 !callStructure.signatureApplies(constructorImplementation.type)) { 3377 !callStructure.signatureApplies(constructorImplementation.type)) {
3388 generateWrongArgumentCountError(send, constructor, send.arguments); 3378 generateWrongArgumentCountError(send, constructor, send.arguments);
3389 return; 3379 return;
3390 } 3380 }
3391 3381
3392 List<HInstruction> inputs = <HInstruction>[]; 3382 List<HInstruction> inputs = <HInstruction>[];
3393 if (constructor.isGenerativeConstructor && 3383 if (constructor.isGenerativeConstructor &&
3394 backend.nativeData 3384 nativeData.isNativeOrExtendsNative(constructor.enclosingClass) &&
3395 .isNativeOrExtendsNative(constructor.enclosingClass) && 3385 !nativeData.isJsInteropMember(constructor)) {
3396 !backend.nativeData.isJsInteropMember(constructor)) {
3397 // Native class generative constructors take a pre-constructed object. 3386 // Native class generative constructors take a pre-constructed object.
3398 inputs.add(graph.addConstantNull(closedWorld)); 3387 inputs.add(graph.addConstantNull(closedWorld));
3399 } 3388 }
3400 inputs.addAll(makeStaticArgumentList( 3389 inputs.addAll(makeStaticArgumentList(
3401 callStructure, send.arguments, constructorImplementation.declaration)); 3390 callStructure, send.arguments, constructorImplementation.declaration));
3402 3391
3403 TypeMask elementType = computeType(constructor); 3392 TypeMask elementType = computeType(constructor);
3404 if (isFixedListConstructorCall) { 3393 if (isFixedListConstructorCall) {
3405 if (!inputs[0].isNumber(closedWorld)) { 3394 if (!inputs[0].isNumber(closedWorld)) {
3406 HTypeConversion conversion = new HTypeConversion( 3395 HTypeConversion conversion = new HTypeConversion(
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
3457 // Overwrite the element type, in case the allocation site has 3446 // Overwrite the element type, in case the allocation site has
3458 // been inlined. 3447 // been inlined.
3459 newInstance.instructionType = elementType; 3448 newInstance.instructionType = elementType;
3460 graph.allocatedFixedLists?.add(newInstance); 3449 graph.allocatedFixedLists?.add(newInstance);
3461 } 3450 }
3462 3451
3463 // The List constructor forwards to a Dart static method that does 3452 // The List constructor forwards to a Dart static method that does
3464 // not know about the type argument. Therefore we special case 3453 // not know about the type argument. Therefore we special case
3465 // this constructor to have the setRuntimeTypeInfo called where 3454 // this constructor to have the setRuntimeTypeInfo called where
3466 // the 'new' is done. 3455 // the 'new' is done.
3467 if (backend.rtiNeed.classNeedsRti(commonElements.listClass) && 3456 if (rtiNeed.classNeedsRti(commonElements.listClass) &&
3468 (isFixedListConstructorCall || 3457 (isFixedListConstructorCall ||
3469 isGrowableListConstructorCall || 3458 isGrowableListConstructorCall ||
3470 isJSArrayTypedConstructor)) { 3459 isJSArrayTypedConstructor)) {
3471 newInstance = handleListConstructor(type, send, pop()); 3460 newInstance = handleListConstructor(type, send, pop());
3472 stack.add(newInstance); 3461 stack.add(newInstance);
3473 } 3462 }
3474 3463
3475 // Finally, if we called a redirecting factory constructor, check the type. 3464 // Finally, if we called a redirecting factory constructor, check the type.
3476 if (isRedirected) { 3465 if (isRedirected) {
3477 HInstruction checked = 3466 HInstruction checked =
3478 typeBuilder.potentiallyCheckOrTrustType(newInstance, type); 3467 typeBuilder.potentiallyCheckOrTrustType(newInstance, type);
3479 if (checked != newInstance) { 3468 if (checked != newInstance) {
3480 pop(); 3469 pop();
3481 stack.add(checked); 3470 stack.add(checked);
3482 } 3471 }
3483 } 3472 }
3484 } 3473 }
3485 3474
3486 void potentiallyAddTypeArguments(List<HInstruction> inputs, ClassElement cls, 3475 void potentiallyAddTypeArguments(List<HInstruction> inputs, ClassElement cls,
3487 ResolutionInterfaceType expectedType, 3476 ResolutionInterfaceType expectedType,
3488 {SourceInformation sourceInformation}) { 3477 {SourceInformation sourceInformation}) {
3489 if (!backend.rtiNeed.classNeedsRti(cls)) return; 3478 if (!rtiNeed.classNeedsRti(cls)) return;
3490 assert(cls.typeVariables.length == expectedType.typeArguments.length); 3479 assert(cls.typeVariables.length == expectedType.typeArguments.length);
3491 expectedType.typeArguments.forEach((ResolutionDartType argument) { 3480 expectedType.typeArguments.forEach((ResolutionDartType argument) {
3492 inputs.add(typeBuilder.analyzeTypeArgument(argument, sourceElement, 3481 inputs.add(typeBuilder.analyzeTypeArgument(argument, sourceElement,
3493 sourceInformation: sourceInformation)); 3482 sourceInformation: sourceInformation));
3494 }); 3483 });
3495 } 3484 }
3496 3485
3497 /// In checked mode checks the [type] of [node] to be well-bounded. The method 3486 /// In checked mode checks the [type] of [node] to be well-bounded. The method
3498 /// returns [:true:] if an error can be statically determined. 3487 /// returns [:true:] if an error can be statically determined.
3499 bool checkTypeVariableBounds( 3488 bool checkTypeVariableBounds(
(...skipping 444 matching lines...) Expand 10 before | Expand all | Expand 10 after
3944 return closedWorld.isSubtypeOf( 3933 return closedWorld.isSubtypeOf(
3945 element.enclosingClass, helpers.jsMutableIndexableClass); 3934 element.enclosingClass, helpers.jsMutableIndexableClass);
3946 } else { 3935 } else {
3947 return false; 3936 return false;
3948 } 3937 }
3949 } 3938 }
3950 3939
3951 bool isOptimizableOperation(Selector selector, Element element) { 3940 bool isOptimizableOperation(Selector selector, Element element) {
3952 ClassElement cls = element.enclosingClass; 3941 ClassElement cls = element.enclosingClass;
3953 if (isOptimizableOperationOnIndexable(selector, element)) return true; 3942 if (isOptimizableOperationOnIndexable(selector, element)) return true;
3954 if (!backend.interceptorData.interceptedClasses.contains(cls)) 3943 if (!interceptorData.interceptedClasses.contains(cls)) return false;
3955 return false;
3956 if (selector.isOperator) return true; 3944 if (selector.isOperator) return true;
3957 if (selector.isSetter) return true; 3945 if (selector.isSetter) return true;
3958 if (selector.isIndex) return true; 3946 if (selector.isIndex) return true;
3959 if (selector.isIndexSet) return true; 3947 if (selector.isIndexSet) return true;
3960 if (element == helpers.jsArrayAdd || 3948 if (element == helpers.jsArrayAdd ||
3961 element == helpers.jsArrayRemoveLast || 3949 element == helpers.jsArrayRemoveLast ||
3962 element == helpers.jsStringSplit) { 3950 element == helpers.jsStringSplit) {
3963 return true; 3951 return true;
3964 } 3952 }
3965 return false; 3953 return false;
3966 } 3954 }
3967 3955
3968 MemberElement element = closedWorld.locateSingleElement(selector, mask); 3956 MemberElement element = closedWorld.locateSingleElement(selector, mask);
3969 if (element != null && 3957 if (element != null &&
3970 !element.isField && 3958 !element.isField &&
3971 !(element.isGetter && selector.isCall) && 3959 !(element.isGetter && selector.isCall) &&
3972 !(element.isFunction && selector.isGetter) && 3960 !(element.isFunction && selector.isGetter) &&
3973 !isOptimizableOperation(selector, element)) { 3961 !isOptimizableOperation(selector, element)) {
3974 if (tryInlineMethod(element, selector, mask, arguments, node)) { 3962 if (tryInlineMethod(element, selector, mask, arguments, node)) {
3975 return; 3963 return;
3976 } 3964 }
3977 } 3965 }
3978 3966
3979 HInstruction receiver = arguments[0]; 3967 HInstruction receiver = arguments[0];
3980 List<HInstruction> inputs = <HInstruction>[]; 3968 List<HInstruction> inputs = <HInstruction>[];
3981 bool isIntercepted = 3969 bool isIntercepted = interceptorData.isInterceptedSelector(selector);
3982 backend.interceptorData.isInterceptedSelector(selector);
3983 if (isIntercepted) { 3970 if (isIntercepted) {
3984 inputs.add(invokeInterceptor(receiver)); 3971 inputs.add(invokeInterceptor(receiver));
3985 } 3972 }
3986 inputs.addAll(arguments); 3973 inputs.addAll(arguments);
3987 TypeMask type = TypeMaskFactory.inferredTypeForSelector( 3974 TypeMask type = TypeMaskFactory.inferredTypeForSelector(
3988 selector, mask, globalInferenceResults); 3975 selector, mask, globalInferenceResults);
3989 if (selector.isGetter) { 3976 if (selector.isGetter) {
3990 push(new HInvokeDynamicGetter(selector, mask, null, inputs, type) 3977 push(new HInvokeDynamicGetter(selector, mask, null, inputs, type)
3991 ..sourceInformation = sourceInformation); 3978 ..sourceInformation = sourceInformation);
3992 } else if (selector.isSetter) { 3979 } else if (selector.isSetter) {
3993 push(new HInvokeDynamicSetter(selector, mask, null, inputs, type) 3980 push(new HInvokeDynamicSetter(selector, mask, null, inputs, type)
3994 ..sourceInformation = sourceInformation); 3981 ..sourceInformation = sourceInformation);
3995 } else { 3982 } else {
3996 push(new HInvokeDynamicMethod(selector, mask, inputs, type, isIntercepted) 3983 push(new HInvokeDynamicMethod(selector, mask, inputs, type, isIntercepted)
3997 ..sourceInformation = sourceInformation); 3984 ..sourceInformation = sourceInformation);
3998 } 3985 }
3999 } 3986 }
4000 3987
4001 HForeignCode invokeJsInteropFunction(MethodElement element, 3988 HForeignCode invokeJsInteropFunction(MethodElement element,
4002 List<HInstruction> arguments, SourceInformation sourceInformation) { 3989 List<HInstruction> arguments, SourceInformation sourceInformation) {
4003 assert(backend.nativeData.isJsInteropMember(element)); 3990 assert(nativeData.isJsInteropMember(element));
4004 nativeEmitter.nativeMethods.add(element); 3991 nativeEmitter.nativeMethods.add(element);
4005 3992
4006 if (element.isFactoryConstructor && 3993 if (element.isFactoryConstructor &&
4007 backend.jsInteropAnalysis 3994 jsInteropAnalysis.hasAnonymousAnnotation(element.contextClass)) {
4008 .hasAnonymousAnnotation(element.contextClass)) {
4009 // Factory constructor that is syntactic sugar for creating a JavaScript 3995 // Factory constructor that is syntactic sugar for creating a JavaScript
4010 // object literal. 3996 // object literal.
4011 ConstructorElement constructor = element; 3997 ConstructorElement constructor = element;
4012 FunctionSignature params = constructor.functionSignature; 3998 FunctionSignature params = constructor.functionSignature;
4013 int i = 0; 3999 int i = 0;
4014 int positions = 0; 4000 int positions = 0;
4015 var filteredArguments = <HInstruction>[]; 4001 var filteredArguments = <HInstruction>[];
4016 var parameterNameMap = new Map<String, js.Expression>(); 4002 var parameterNameMap = new Map<String, js.Expression>();
4017 params.orderedForEachParameter((ParameterElement parameter) { 4003 params.orderedForEachParameter((ParameterElement parameter) {
4018 // TODO(jacobr): consider throwing if parameter names do not match 4004 // TODO(jacobr): consider throwing if parameter names do not match
4019 // names of properties in the class. 4005 // names of properties in the class.
4020 assert(parameter.isNamed); 4006 assert(parameter.isNamed);
4021 HInstruction argument = arguments[i]; 4007 HInstruction argument = arguments[i];
4022 if (argument != null) { 4008 if (argument != null) {
4023 filteredArguments.add(argument); 4009 filteredArguments.add(argument);
4024 var jsName = 4010 var jsName = nativeData.computeUnescapedJSInteropName(parameter.name);
4025 backend.nativeData.computeUnescapedJSInteropName(parameter.name);
4026 parameterNameMap[jsName] = new js.InterpolatedExpression(positions++); 4011 parameterNameMap[jsName] = new js.InterpolatedExpression(positions++);
4027 } 4012 }
4028 i++; 4013 i++;
4029 }); 4014 });
4030 var codeTemplate = 4015 var codeTemplate =
4031 new js.Template(null, js.objectLiteral(parameterNameMap)); 4016 new js.Template(null, js.objectLiteral(parameterNameMap));
4032 4017
4033 var nativeBehavior = new native.NativeBehavior() 4018 var nativeBehavior = new native.NativeBehavior()
4034 ..codeTemplate = codeTemplate; 4019 ..codeTemplate = codeTemplate;
4035 if (options.trustJSInteropTypeAnnotations) { 4020 if (options.trustJSInteropTypeAnnotations) {
4036 nativeBehavior.typesReturned.add(constructor.enclosingClass.thisType); 4021 nativeBehavior.typesReturned.add(constructor.enclosingClass.thisType);
4037 } 4022 }
4038 return new HForeignCode( 4023 return new HForeignCode(
4039 codeTemplate, commonMasks.dynamicType, filteredArguments, 4024 codeTemplate, commonMasks.dynamicType, filteredArguments,
4040 nativeBehavior: nativeBehavior) 4025 nativeBehavior: nativeBehavior)
4041 ..sourceInformation = sourceInformation; 4026 ..sourceInformation = sourceInformation;
4042 } 4027 }
4043 var target = new HForeignCode( 4028 var target = new HForeignCode(
4044 js.js.parseForeignJS( 4029 js.js.parseForeignJS("${nativeData.getFixedBackendMethodPath(element)}."
4045 "${backend.nativeData.getFixedBackendMethodPath(element)}." 4030 "${nativeData.getFixedBackendName(element)}"),
4046 "${backend.nativeData.getFixedBackendName(element)}"),
4047 commonMasks.dynamicType, 4031 commonMasks.dynamicType,
4048 <HInstruction>[]); 4032 <HInstruction>[]);
4049 add(target); 4033 add(target);
4050 // Strip off trailing arguments that were not specified. 4034 // Strip off trailing arguments that were not specified.
4051 // we could assert that the trailing arguments are all null. 4035 // we could assert that the trailing arguments are all null.
4052 // TODO(jacobr): rewrite named arguments to an object literal matching 4036 // TODO(jacobr): rewrite named arguments to an object literal matching
4053 // the factory constructor case. 4037 // the factory constructor case.
4054 arguments = arguments.where((arg) => arg != null).toList(); 4038 arguments = arguments.where((arg) => arg != null).toList();
4055 var inputs = <HInstruction>[target]..addAll(arguments); 4039 var inputs = <HInstruction>[target]..addAll(arguments);
4056 4040
4057 var nativeBehavior = new native.NativeBehavior() 4041 var nativeBehavior = new native.NativeBehavior()
4058 ..sideEffects.setAllSideEffects(); 4042 ..sideEffects.setAllSideEffects();
4059 4043
4060 ResolutionDartType type = element.isConstructor 4044 ResolutionDartType type = element.isConstructor
4061 ? element.enclosingClass.thisType 4045 ? element.enclosingClass.thisType
4062 : element.type.returnType; 4046 : element.type.returnType;
4063 // Native behavior effects here are similar to native/behavior.dart. 4047 // Native behavior effects here are similar to native/behavior.dart.
4064 // The return type is dynamic if we don't trust js-interop type 4048 // The return type is dynamic if we don't trust js-interop type
4065 // declarations. 4049 // declarations.
4066 nativeBehavior.typesReturned.add(options.trustJSInteropTypeAnnotations 4050 nativeBehavior.typesReturned.add(options.trustJSInteropTypeAnnotations
4067 ? type 4051 ? type
4068 : const ResolutionDynamicType()); 4052 : const ResolutionDynamicType());
4069 4053
4070 // The allocation effects include the declared type if it is native (which 4054 // The allocation effects include the declared type if it is native (which
4071 // includes js interop types). 4055 // includes js interop types).
4072 if (type is ResolutionInterfaceType && 4056 if (type is ResolutionInterfaceType &&
4073 backend.nativeData.isNativeClass(type.element)) { 4057 nativeData.isNativeClass(type.element)) {
4074 nativeBehavior.typesInstantiated.add(type); 4058 nativeBehavior.typesInstantiated.add(type);
4075 } 4059 }
4076 4060
4077 // It also includes any other JS interop type if we don't trust the 4061 // It also includes any other JS interop type if we don't trust the
4078 // annotation or if is declared too broad. 4062 // annotation or if is declared too broad.
4079 if (!options.trustJSInteropTypeAnnotations || 4063 if (!options.trustJSInteropTypeAnnotations ||
4080 type.isObject || 4064 type.isObject ||
4081 type.isDynamic) { 4065 type.isDynamic) {
4082 ClassElement cls = backend.helpers.jsJavaScriptObjectClass; 4066 ClassElement cls = helpers.jsJavaScriptObjectClass;
4083 nativeBehavior.typesInstantiated.add(cls.thisType); 4067 nativeBehavior.typesInstantiated.add(cls.thisType);
4084 } 4068 }
4085 4069
4086 String code; 4070 String code;
4087 if (element.isGetter) { 4071 if (element.isGetter) {
4088 code = "#"; 4072 code = "#";
4089 } else if (element.isSetter) { 4073 } else if (element.isSetter) {
4090 code = "# = #"; 4074 code = "# = #";
4091 } else { 4075 } else {
4092 var args = new List.filled(arguments.length, '#').join(','); 4076 var args = new List.filled(arguments.length, '#').join(',');
(...skipping 19 matching lines...) Expand all
4112 return; 4096 return;
4113 } 4097 }
4114 4098
4115 if (typeMask == null) { 4099 if (typeMask == null) {
4116 typeMask = TypeMaskFactory.inferredReturnTypeForElement( 4100 typeMask = TypeMaskFactory.inferredReturnTypeForElement(
4117 element, globalInferenceResults); 4101 element, globalInferenceResults);
4118 } 4102 }
4119 bool targetCanThrow = !closedWorld.getCannotThrow(element); 4103 bool targetCanThrow = !closedWorld.getCannotThrow(element);
4120 // TODO(5346): Try to avoid the need for calling [declaration] before 4104 // TODO(5346): Try to avoid the need for calling [declaration] before
4121 var instruction; 4105 var instruction;
4122 if (backend.nativeData.isJsInteropMember(element)) { 4106 if (nativeData.isJsInteropMember(element)) {
4123 instruction = 4107 instruction =
4124 invokeJsInteropFunction(element, arguments, sourceInformation); 4108 invokeJsInteropFunction(element, arguments, sourceInformation);
4125 } else { 4109 } else {
4126 // creating an [HInvokeStatic]. 4110 // creating an [HInvokeStatic].
4127 instruction = new HInvokeStatic(element, arguments, typeMask, 4111 instruction = new HInvokeStatic(element, arguments, typeMask,
4128 targetCanThrow: targetCanThrow) 4112 targetCanThrow: targetCanThrow)
4129 ..sourceInformation = sourceInformation; 4113 ..sourceInformation = sourceInformation;
4130 if (currentInlinedInstantiations.isNotEmpty) { 4114 if (currentInlinedInstantiations.isNotEmpty) {
4131 instruction.instantiatedTypes = 4115 instruction.instantiatedTypes =
4132 new List<ResolutionDartType>.from(currentInlinedInstantiations); 4116 new List<ResolutionDartType>.from(currentInlinedInstantiations);
4133 } 4117 }
4134 instruction.sideEffects = closedWorld.getSideEffectsOfElement(element); 4118 instruction.sideEffects = closedWorld.getSideEffectsOfElement(element);
4135 } 4119 }
4136 if (location == null) { 4120 if (location == null) {
4137 push(instruction); 4121 push(instruction);
4138 } else { 4122 } else {
4139 pushWithPosition(instruction, location); 4123 pushWithPosition(instruction, location);
4140 } 4124 }
4141 } 4125 }
4142 4126
4143 HInstruction buildInvokeSuper( 4127 HInstruction buildInvokeSuper(
4144 Selector selector, MemberElement element, List<HInstruction> arguments, 4128 Selector selector, MemberElement element, List<HInstruction> arguments,
4145 [SourceInformation sourceInformation]) { 4129 [SourceInformation sourceInformation]) {
4146 HInstruction receiver = localsHandler.readThis(); 4130 HInstruction receiver = localsHandler.readThis();
4147 // TODO(5346): Try to avoid the need for calling [declaration] before 4131 // TODO(5346): Try to avoid the need for calling [declaration] before
4148 // creating an [HStatic]. 4132 // creating an [HStatic].
4149 List<HInstruction> inputs = <HInstruction>[]; 4133 List<HInstruction> inputs = <HInstruction>[];
4150 if (backend.interceptorData.isInterceptedSelector(selector) && 4134 if (interceptorData.isInterceptedSelector(selector) &&
4151 // Fields don't need an interceptor; consider generating HFieldGet/Set 4135 // Fields don't need an interceptor; consider generating HFieldGet/Set
4152 // instead. 4136 // instead.
4153 element.kind != ElementKind.FIELD) { 4137 element.kind != ElementKind.FIELD) {
4154 inputs.add(invokeInterceptor(receiver)); 4138 inputs.add(invokeInterceptor(receiver));
4155 } 4139 }
4156 inputs.add(receiver); 4140 inputs.add(receiver);
4157 inputs.addAll(arguments); 4141 inputs.addAll(arguments);
4158 TypeMask type; 4142 TypeMask type;
4159 if (!element.isGetter && selector.isGetter) { 4143 if (!element.isGetter && selector.isGetter) {
4160 type = TypeMaskFactory.inferredTypeForMember( 4144 type = TypeMaskFactory.inferredTypeForMember(
(...skipping 912 matching lines...) Expand 10 before | Expand all | Expand 10 after
5073 } 5057 }
5074 } 5058 }
5075 } else { 5059 } else {
5076 for (ParameterElement parameter in targetOptionals) { 5060 for (ParameterElement parameter in targetOptionals) {
5077 loadPosition(position++, parameter); 5061 loadPosition(position++, parameter);
5078 } 5062 }
5079 } 5063 }
5080 } 5064 }
5081 5065
5082 ClassElement targetClass = targetConstructor.enclosingClass; 5066 ClassElement targetClass = targetConstructor.enclosingClass;
5083 if (backend.rtiNeed.classNeedsRti(targetClass)) { 5067 if (rtiNeed.classNeedsRti(targetClass)) {
5084 ClassElement cls = redirectingConstructor.enclosingClass; 5068 ClassElement cls = redirectingConstructor.enclosingClass;
5085 ResolutionInterfaceType targetType = 5069 ResolutionInterfaceType targetType =
5086 redirectingConstructor.computeEffectiveTargetType(cls.thisType); 5070 redirectingConstructor.computeEffectiveTargetType(cls.thisType);
5087 targetType = localsHandler.substInContext(targetType); 5071 targetType = localsHandler.substInContext(targetType);
5088 targetType.typeArguments.forEach((ResolutionDartType argument) { 5072 targetType.typeArguments.forEach((ResolutionDartType argument) {
5089 inputs.add(typeBuilder.analyzeTypeArgument(argument, sourceElement)); 5073 inputs.add(typeBuilder.analyzeTypeArgument(argument, sourceElement));
5090 }); 5074 });
5091 } 5075 }
5092 pushInvokeStatic(node, targetConstructor.declaration, inputs); 5076 pushInvokeStatic(node, targetConstructor.declaration, inputs);
5093 HInstruction value = pop(); 5077 HInstruction value = pop();
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
5188 generateNonInstanceSetter( 5172 generateNonInstanceSetter(
5189 node, local, visitAndPop(node.arguments.first)); 5173 node, local, visitAndPop(node.arguments.first));
5190 pop(); // Discard value. 5174 pop(); // Discard value.
5191 } 5175 }
5192 } 5176 }
5193 } 5177 }
5194 5178
5195 HInstruction setRtiIfNeeded(HInstruction object, ast.Node node) { 5179 HInstruction setRtiIfNeeded(HInstruction object, ast.Node node) {
5196 ResolutionInterfaceType type = 5180 ResolutionInterfaceType type =
5197 localsHandler.substInContext(elements.getType(node)); 5181 localsHandler.substInContext(elements.getType(node));
5198 if (!backend.rtiNeed.classNeedsRti(type.element) || type.treatAsRaw) { 5182 if (!rtiNeed.classNeedsRti(type.element) || type.treatAsRaw) {
5199 return object; 5183 return object;
5200 } 5184 }
5201 List<HInstruction> arguments = <HInstruction>[]; 5185 List<HInstruction> arguments = <HInstruction>[];
5202 for (ResolutionDartType argument in type.typeArguments) { 5186 for (ResolutionDartType argument in type.typeArguments) {
5203 arguments.add(typeBuilder.analyzeTypeArgument(argument, sourceElement)); 5187 arguments.add(typeBuilder.analyzeTypeArgument(argument, sourceElement));
5204 } 5188 }
5205 // TODO(15489): Register at codegen. 5189 // TODO(15489): Register at codegen.
5206 registry?.registerInstantiation(type); 5190 registry?.registerInstantiation(type);
5207 return callSetRuntimeTypeInfoWithTypeArguments(type, arguments, object); 5191 return callSetRuntimeTypeInfoWithTypeArguments(type, arguments, object);
5208 } 5192 }
(...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after
5636 listConstructor = constructorElement.effectiveTarget; 5620 listConstructor = constructorElement.effectiveTarget;
5637 5621
5638 ResolutionInterfaceType type = elements.getType(node); 5622 ResolutionInterfaceType type = elements.getType(node);
5639 ResolutionInterfaceType expectedType = 5623 ResolutionInterfaceType expectedType =
5640 constructorElement.computeEffectiveTargetType(type); 5624 constructorElement.computeEffectiveTargetType(type);
5641 expectedType = localsHandler.substInContext(expectedType); 5625 expectedType = localsHandler.substInContext(expectedType);
5642 5626
5643 ClassElement cls = listConstructor.enclosingClass; 5627 ClassElement cls = listConstructor.enclosingClass;
5644 5628
5645 MethodElement createFunction = listConstructor; 5629 MethodElement createFunction = listConstructor;
5646 if (backend.rtiNeed.classNeedsRti(cls)) { 5630 if (rtiNeed.classNeedsRti(cls)) {
5647 List<HInstruction> typeInputs = <HInstruction>[]; 5631 List<HInstruction> typeInputs = <HInstruction>[];
5648 expectedType.typeArguments.forEach((ResolutionDartType argument) { 5632 expectedType.typeArguments.forEach((ResolutionDartType argument) {
5649 typeInputs 5633 typeInputs
5650 .add(typeBuilder.analyzeTypeArgument(argument, sourceElement)); 5634 .add(typeBuilder.analyzeTypeArgument(argument, sourceElement));
5651 }); 5635 });
5652 5636
5653 // We lift this common call pattern into a helper function to save space 5637 // We lift this common call pattern into a helper function to save space
5654 // in the output. 5638 // in the output.
5655 if (typeInputs.every((HInstruction input) => input.isNull())) { 5639 if (typeInputs.every((HInstruction input) => input.isNull())) {
5656 if (listInputs.isEmpty) { 5640 if (listInputs.isEmpty) {
(...skipping 1098 matching lines...) Expand 10 before | Expand all | Expand 10 after
6755 this.oldReturnLocal, 6739 this.oldReturnLocal,
6756 this.oldReturnType, 6740 this.oldReturnType,
6757 this.oldResolvedAst, 6741 this.oldResolvedAst,
6758 this.oldStack, 6742 this.oldStack,
6759 this.oldLocalsHandler, 6743 this.oldLocalsHandler,
6760 this.inTryStatement, 6744 this.inTryStatement,
6761 this.allFunctionsCalledOnce, 6745 this.allFunctionsCalledOnce,
6762 this.oldElementInferenceResults) 6746 this.oldElementInferenceResults)
6763 : super(function); 6747 : super(function);
6764 } 6748 }
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