| 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; | 14 import '../compiler.dart' show Compiler; |
| 15 import '../constants/constant_system.dart'; | 15 import '../constants/constant_system.dart'; |
| 16 import '../constants/expressions.dart'; | 16 import '../constants/expressions.dart'; |
| 17 import '../constants/values.dart'; | 17 import '../constants/values.dart'; |
| 18 import '../core_types.dart' show CoreClasses; | 18 import '../core_types.dart' show CommonElements; |
| 19 import '../dart_types.dart'; | 19 import '../dart_types.dart'; |
| 20 import '../diagnostics/messages.dart' show Message, MessageTemplate; | 20 import '../diagnostics/messages.dart' show Message, MessageTemplate; |
| 21 import '../dump_info.dart' show InfoReporter; | 21 import '../dump_info.dart' show InfoReporter; |
| 22 import '../elements/elements.dart'; | 22 import '../elements/elements.dart'; |
| 23 import '../elements/entities.dart'; | 23 import '../elements/entities.dart'; |
| 24 import '../elements/modelx.dart' show ConstructorBodyElementX; | 24 import '../elements/modelx.dart' show ConstructorBodyElementX; |
| 25 import '../io/source_information.dart'; | 25 import '../io/source_information.dart'; |
| 26 import '../js/js.dart' as js; | 26 import '../js/js.dart' as js; |
| 27 import '../js_backend/backend_helpers.dart' show BackendHelpers; | 27 import '../js_backend/backend_helpers.dart' show BackendHelpers; |
| 28 import '../js_backend/js_backend.dart'; | 28 import '../js_backend/js_backend.dart'; |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 222 loopHandler = new SsaLoopHandler(this); | 222 loopHandler = new SsaLoopHandler(this); |
| 223 typeBuilder = new TypeBuilder(this); | 223 typeBuilder = new TypeBuilder(this); |
| 224 } | 224 } |
| 225 | 225 |
| 226 BackendHelpers get helpers => backend.helpers; | 226 BackendHelpers get helpers => backend.helpers; |
| 227 | 227 |
| 228 RuntimeTypesEncoder get rtiEncoder => backend.rtiEncoder; | 228 RuntimeTypesEncoder get rtiEncoder => backend.rtiEncoder; |
| 229 | 229 |
| 230 DiagnosticReporter get reporter => compiler.reporter; | 230 DiagnosticReporter get reporter => compiler.reporter; |
| 231 | 231 |
| 232 CoreClasses get coreClasses => compiler.coreClasses; | 232 CommonElements get commonElements => closedWorld.commonElements; |
| 233 | 233 |
| 234 Element get targetElement => target; | 234 Element get targetElement => target; |
| 235 | 235 |
| 236 /// Reference to resolved elements in [target]'s AST. | 236 /// Reference to resolved elements in [target]'s AST. |
| 237 TreeElements get elements => resolvedAst.elements; | 237 TreeElements get elements => resolvedAst.elements; |
| 238 | 238 |
| 239 @override | 239 @override |
| 240 SemanticSendVisitor get sendVisitor => this; | 240 SemanticSendVisitor get sendVisitor => this; |
| 241 | 241 |
| 242 @override | 242 @override |
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 446 if (!selector.applies(function)) return false; | 446 if (!selector.applies(function)) return false; |
| 447 if (mask != null && !mask.canHit(function, selector, closedWorld)) { | 447 if (mask != null && !mask.canHit(function, selector, closedWorld)) { |
| 448 return false; | 448 return false; |
| 449 } | 449 } |
| 450 } | 450 } |
| 451 | 451 |
| 452 if (backend.isJsInterop(element)) return false; | 452 if (backend.isJsInterop(element)) return false; |
| 453 | 453 |
| 454 // Don't inline operator== methods if the parameter can be null. | 454 // Don't inline operator== methods if the parameter can be null. |
| 455 if (element.name == '==') { | 455 if (element.name == '==') { |
| 456 if (element.enclosingClass != coreClasses.objectClass && | 456 if (element.enclosingClass != commonElements.objectClass && |
| 457 providedArguments[1].canBeNull()) { | 457 providedArguments[1].canBeNull()) { |
| 458 return false; | 458 return false; |
| 459 } | 459 } |
| 460 } | 460 } |
| 461 | 461 |
| 462 // Generative constructors of native classes should not be called directly | 462 // Generative constructors of native classes should not be called directly |
| 463 // and have an extra argument that causes problems with inlining. | 463 // and have an extra argument that causes problems with inlining. |
| 464 if (element.isGenerativeConstructor && | 464 if (element.isGenerativeConstructor && |
| 465 backend.isNativeOrExtendsNative(element.enclosingClass)) { | 465 backend.isNativeOrExtendsNative(element.enclosingClass)) { |
| 466 return false; | 466 return false; |
| (...skipping 1084 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1551 } | 1551 } |
| 1552 | 1552 |
| 1553 /// Pops the most recent instruction from the stack and 'boolifies' it. | 1553 /// Pops the most recent instruction from the stack and 'boolifies' it. |
| 1554 /// | 1554 /// |
| 1555 /// Boolification is checking if the value is '=== true'. | 1555 /// Boolification is checking if the value is '=== true'. |
| 1556 @override | 1556 @override |
| 1557 HInstruction popBoolified() { | 1557 HInstruction popBoolified() { |
| 1558 HInstruction value = pop(); | 1558 HInstruction value = pop(); |
| 1559 if (typeBuilder.checkOrTrustTypes) { | 1559 if (typeBuilder.checkOrTrustTypes) { |
| 1560 return typeBuilder.potentiallyCheckOrTrustType( | 1560 return typeBuilder.potentiallyCheckOrTrustType( |
| 1561 value, compiler.coreTypes.boolType, | 1561 value, compiler.commonElements.boolType, |
| 1562 kind: HTypeConversion.BOOLEAN_CONVERSION_CHECK); | 1562 kind: HTypeConversion.BOOLEAN_CONVERSION_CHECK); |
| 1563 } | 1563 } |
| 1564 HInstruction result = new HBoolify(value, commonMasks.boolType); | 1564 HInstruction result = new HBoolify(value, commonMasks.boolType); |
| 1565 add(result); | 1565 add(result); |
| 1566 return result; | 1566 return result; |
| 1567 } | 1567 } |
| 1568 | 1568 |
| 1569 HInstruction attachPosition(HInstruction target, ast.Node node) { | 1569 HInstruction attachPosition(HInstruction target, ast.Node node) { |
| 1570 if (node != null) { | 1570 if (node != null) { |
| 1571 target.sourceInformation = sourceInformationBuilder.buildGeneric(node); | 1571 target.sourceInformation = sourceInformationBuilder.buildGeneric(node); |
| (...skipping 1469 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3041 targetCanThrow: false)..sourceInformation = sourceInformation); | 3041 targetCanThrow: false)..sourceInformation = sourceInformation); |
| 3042 } | 3042 } |
| 3043 | 3043 |
| 3044 generateSuperNoSuchMethodSend( | 3044 generateSuperNoSuchMethodSend( |
| 3045 ast.Send node, Selector selector, List<HInstruction> arguments) { | 3045 ast.Send node, Selector selector, List<HInstruction> arguments) { |
| 3046 String name = selector.name; | 3046 String name = selector.name; |
| 3047 | 3047 |
| 3048 ClassElement cls = currentNonClosureClass; | 3048 ClassElement cls = currentNonClosureClass; |
| 3049 MethodElement element = cls.lookupSuperMember(Identifiers.noSuchMethod_); | 3049 MethodElement element = cls.lookupSuperMember(Identifiers.noSuchMethod_); |
| 3050 if (!Selectors.noSuchMethod_.signatureApplies(element)) { | 3050 if (!Selectors.noSuchMethod_.signatureApplies(element)) { |
| 3051 element = coreClasses.objectClass.lookupMember(Identifiers.noSuchMethod_); | 3051 element = |
| 3052 commonElements.objectClass.lookupMember(Identifiers.noSuchMethod_); |
| 3052 } | 3053 } |
| 3053 if (backend.hasInvokeOnSupport && !element.enclosingClass.isObject) { | 3054 if (backend.hasInvokeOnSupport && !element.enclosingClass.isObject) { |
| 3054 // Register the call as dynamic if [noSuchMethod] on the super | 3055 // Register the call as dynamic if [noSuchMethod] on the super |
| 3055 // class is _not_ the default implementation from [Object], in | 3056 // class is _not_ the default implementation from [Object], in |
| 3056 // case the [noSuchMethod] implementation calls | 3057 // case the [noSuchMethod] implementation calls |
| 3057 // [JSInvocationMirror._invokeOn]. | 3058 // [JSInvocationMirror._invokeOn]. |
| 3058 // TODO(johnniwinther): Register this more precisely. | 3059 // TODO(johnniwinther): Register this more precisely. |
| 3059 registry?.registerDynamicUse(new DynamicUse(selector, null)); | 3060 registry?.registerDynamicUse(new DynamicUse(selector, null)); |
| 3060 } | 3061 } |
| 3061 String publicName = name; | 3062 String publicName = name; |
| (...skipping 435 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3497 // Overwrite the element type, in case the allocation site has | 3498 // Overwrite the element type, in case the allocation site has |
| 3498 // been inlined. | 3499 // been inlined. |
| 3499 newInstance.instructionType = elementType; | 3500 newInstance.instructionType = elementType; |
| 3500 graph.allocatedFixedLists?.add(newInstance); | 3501 graph.allocatedFixedLists?.add(newInstance); |
| 3501 } | 3502 } |
| 3502 | 3503 |
| 3503 // The List constructor forwards to a Dart static method that does | 3504 // The List constructor forwards to a Dart static method that does |
| 3504 // not know about the type argument. Therefore we special case | 3505 // not know about the type argument. Therefore we special case |
| 3505 // this constructor to have the setRuntimeTypeInfo called where | 3506 // this constructor to have the setRuntimeTypeInfo called where |
| 3506 // the 'new' is done. | 3507 // the 'new' is done. |
| 3507 if (backend.classNeedsRti(coreClasses.listClass) && | 3508 if (backend.classNeedsRti(commonElements.listClass) && |
| 3508 (isFixedListConstructorCall || | 3509 (isFixedListConstructorCall || |
| 3509 isGrowableListConstructorCall || | 3510 isGrowableListConstructorCall || |
| 3510 isJSArrayTypedConstructor)) { | 3511 isJSArrayTypedConstructor)) { |
| 3511 newInstance = handleListConstructor(type, send, pop()); | 3512 newInstance = handleListConstructor(type, send, pop()); |
| 3512 stack.add(newInstance); | 3513 stack.add(newInstance); |
| 3513 } | 3514 } |
| 3514 | 3515 |
| 3515 // Finally, if we called a redirecting factory constructor, check the type. | 3516 // Finally, if we called a redirecting factory constructor, check the type. |
| 3516 if (isRedirected) { | 3517 if (isRedirected) { |
| 3517 HInstruction checked = | 3518 HInstruction checked = |
| (...skipping 1630 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5148 assert(isBuildingAsyncFunction); | 5149 assert(isBuildingAsyncFunction); |
| 5149 // TODO(sigurdm): In an internal library a function could be declared: | 5150 // TODO(sigurdm): In an internal library a function could be declared: |
| 5150 // | 5151 // |
| 5151 // _FutureImpl foo async => 1; | 5152 // _FutureImpl foo async => 1; |
| 5152 // | 5153 // |
| 5153 // This should be valid (because the actual value returned from an async | 5154 // This should be valid (because the actual value returned from an async |
| 5154 // function is a `_FutureImpl`), but currently false is returned in this | 5155 // function is a `_FutureImpl`), but currently false is returned in this |
| 5155 // case. | 5156 // case. |
| 5156 return type.isDynamic || | 5157 return type.isDynamic || |
| 5157 type.isObject || | 5158 type.isObject || |
| 5158 (type is InterfaceType && type.element == coreClasses.futureClass); | 5159 (type is InterfaceType && type.element == commonElements.futureClass); |
| 5159 } | 5160 } |
| 5160 | 5161 |
| 5161 visitReturn(ast.Return node) { | 5162 visitReturn(ast.Return node) { |
| 5162 if (identical(node.beginToken.stringValue, 'native')) { | 5163 if (identical(node.beginToken.stringValue, 'native')) { |
| 5163 native.handleSsaNative(this, node.expression); | 5164 native.handleSsaNative(this, node.expression); |
| 5164 return; | 5165 return; |
| 5165 } | 5166 } |
| 5166 HInstruction value; | 5167 HInstruction value; |
| 5167 if (node.expression == null) { | 5168 if (node.expression == null) { |
| 5168 value = graph.addConstantNull(closedWorld); | 5169 value = graph.addConstantNull(closedWorld); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5200 visitYield(ast.Yield node) { | 5201 visitYield(ast.Yield node) { |
| 5201 visit(node.expression); | 5202 visit(node.expression); |
| 5202 HInstruction yielded = pop(); | 5203 HInstruction yielded = pop(); |
| 5203 add(new HYield(yielded, node.hasStar)); | 5204 add(new HYield(yielded, node.hasStar)); |
| 5204 } | 5205 } |
| 5205 | 5206 |
| 5206 visitAwait(ast.Await node) { | 5207 visitAwait(ast.Await node) { |
| 5207 visit(node.expression); | 5208 visit(node.expression); |
| 5208 HInstruction awaited = pop(); | 5209 HInstruction awaited = pop(); |
| 5209 // TODO(herhut): Improve this type. | 5210 // TODO(herhut): Improve this type. |
| 5210 push(new HAwait( | 5211 push(new HAwait(awaited, |
| 5211 awaited, new TypeMask.subclass(coreClasses.objectClass, closedWorld))); | 5212 new TypeMask.subclass(commonElements.objectClass, closedWorld))); |
| 5212 } | 5213 } |
| 5213 | 5214 |
| 5214 visitTypeAnnotation(ast.TypeAnnotation node) { | 5215 visitTypeAnnotation(ast.TypeAnnotation node) { |
| 5215 reporter.internalError(node, 'Visiting type annotation in SSA builder.'); | 5216 reporter.internalError(node, 'Visiting type annotation in SSA builder.'); |
| 5216 } | 5217 } |
| 5217 | 5218 |
| 5218 visitVariableDefinitions(ast.VariableDefinitions node) { | 5219 visitVariableDefinitions(ast.VariableDefinitions node) { |
| 5219 assert(isReachable); | 5220 assert(isReachable); |
| 5220 for (Link<ast.Node> link = node.definitions.nodes; | 5221 for (Link<ast.Node> link = node.definitions.nodes; |
| 5221 !link.isEmpty; | 5222 !link.isEmpty; |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5365 [expression, graph.addConstantNull(closedWorld)]); | 5366 [expression, graph.addConstantNull(closedWorld)]); |
| 5366 streamIterator = pop(); | 5367 streamIterator = pop(); |
| 5367 | 5368 |
| 5368 void buildInitializer() {} | 5369 void buildInitializer() {} |
| 5369 | 5370 |
| 5370 HInstruction buildCondition() { | 5371 HInstruction buildCondition() { |
| 5371 Selector selector = Selectors.moveNext; | 5372 Selector selector = Selectors.moveNext; |
| 5372 TypeMask mask = elementInferenceResults.typeOfIteratorMoveNext(node); | 5373 TypeMask mask = elementInferenceResults.typeOfIteratorMoveNext(node); |
| 5373 pushInvokeDynamic(node, selector, mask, [streamIterator]); | 5374 pushInvokeDynamic(node, selector, mask, [streamIterator]); |
| 5374 HInstruction future = pop(); | 5375 HInstruction future = pop(); |
| 5375 push(new HAwait( | 5376 push(new HAwait(future, |
| 5376 future, new TypeMask.subclass(coreClasses.objectClass, closedWorld))); | 5377 new TypeMask.subclass(commonElements.objectClass, closedWorld))); |
| 5377 return popBoolified(); | 5378 return popBoolified(); |
| 5378 } | 5379 } |
| 5379 | 5380 |
| 5380 void buildBody() { | 5381 void buildBody() { |
| 5381 Selector call = Selectors.current; | 5382 Selector call = Selectors.current; |
| 5382 TypeMask callMask = elementInferenceResults.typeOfIteratorCurrent(node); | 5383 TypeMask callMask = elementInferenceResults.typeOfIteratorCurrent(node); |
| 5383 pushInvokeDynamic(node, call, callMask, [streamIterator]); | 5384 pushInvokeDynamic(node, call, callMask, [streamIterator]); |
| 5384 | 5385 |
| 5385 ast.Node identifier = node.declaredIdentifier; | 5386 ast.Node identifier = node.declaredIdentifier; |
| 5386 Element variable = elements.getForInVariable(node); | 5387 Element variable = elements.getForInVariable(node); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 5401 visit(node.body); | 5402 visit(node.body); |
| 5402 } | 5403 } |
| 5403 | 5404 |
| 5404 void buildUpdate() {} | 5405 void buildUpdate() {} |
| 5405 | 5406 |
| 5406 buildProtectedByFinally(() { | 5407 buildProtectedByFinally(() { |
| 5407 loopHandler.handleLoop( | 5408 loopHandler.handleLoop( |
| 5408 node, buildInitializer, buildCondition, buildUpdate, buildBody); | 5409 node, buildInitializer, buildCondition, buildUpdate, buildBody); |
| 5409 }, () { | 5410 }, () { |
| 5410 pushInvokeDynamic(node, Selectors.cancel, null, [streamIterator]); | 5411 pushInvokeDynamic(node, Selectors.cancel, null, [streamIterator]); |
| 5411 push(new HAwait( | 5412 push(new HAwait(pop(), |
| 5412 pop(), new TypeMask.subclass(coreClasses.objectClass, closedWorld))); | 5413 new TypeMask.subclass(commonElements.objectClass, closedWorld))); |
| 5413 pop(); | 5414 pop(); |
| 5414 }); | 5415 }); |
| 5415 } | 5416 } |
| 5416 | 5417 |
| 5417 visitSyncForIn(ast.SyncForIn node) { | 5418 visitSyncForIn(ast.SyncForIn node) { |
| 5418 // The 'get iterator' selector for this node has the inferred receiver type. | 5419 // The 'get iterator' selector for this node has the inferred receiver type. |
| 5419 // If the receiver supports JavaScript indexing we generate an indexing loop | 5420 // If the receiver supports JavaScript indexing we generate an indexing loop |
| 5420 // instead of allocating an iterator object. | 5421 // instead of allocating an iterator object. |
| 5421 | 5422 |
| 5422 // This scheme recognizes for-in on direct lists. It does not recognize all | 5423 // This scheme recognizes for-in on direct lists. It does not recognize all |
| (...skipping 1330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6753 this.oldReturnLocal, | 6754 this.oldReturnLocal, |
| 6754 this.oldReturnType, | 6755 this.oldReturnType, |
| 6755 this.oldResolvedAst, | 6756 this.oldResolvedAst, |
| 6756 this.oldStack, | 6757 this.oldStack, |
| 6757 this.oldLocalsHandler, | 6758 this.oldLocalsHandler, |
| 6758 this.inTryStatement, | 6759 this.inTryStatement, |
| 6759 this.allFunctionsCalledOnce, | 6760 this.allFunctionsCalledOnce, |
| 6760 this.oldElementInferenceResults) | 6761 this.oldElementInferenceResults) |
| 6761 : super(function); | 6762 : super(function); |
| 6762 } | 6763 } |
| OLD | NEW |