OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 } |
OLD | NEW |