| 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 |