| 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'; |
| (...skipping 1058 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1069 for (Link<ast.Node> link = initializers; | 1069 for (Link<ast.Node> link = initializers; |
| 1070 !link.isEmpty; | 1070 !link.isEmpty; |
| 1071 link = link.tail) { | 1071 link = link.tail) { |
| 1072 assert(link.head is ast.Send); | 1072 assert(link.head is ast.Send); |
| 1073 if (link.head is! ast.SendSet) { | 1073 if (link.head is! ast.SendSet) { |
| 1074 // A super initializer or constructor redirection. | 1074 // A super initializer or constructor redirection. |
| 1075 foundSuperOrRedirect = true; | 1075 foundSuperOrRedirect = true; |
| 1076 ast.Send call = link.head; | 1076 ast.Send call = link.head; |
| 1077 assert(ast.Initializers.isSuperConstructorCall(call) || | 1077 assert(ast.Initializers.isSuperConstructorCall(call) || |
| 1078 ast.Initializers.isConstructorRedirect(call)); | 1078 ast.Initializers.isConstructorRedirect(call)); |
| 1079 FunctionElement target = elements[call].implementation; | 1079 ConstructorElement target = elements[call]; |
| 1080 CallStructure callStructure = | 1080 CallStructure callStructure = |
| 1081 elements.getSelector(call).callStructure; | 1081 elements.getSelector(call).callStructure; |
| 1082 Link<ast.Node> arguments = call.arguments; | 1082 Link<ast.Node> arguments = call.arguments; |
| 1083 List<HInstruction> compiledArguments; | 1083 List<HInstruction> compiledArguments; |
| 1084 inlinedFrom(resolvedAst, () { | 1084 inlinedFrom(resolvedAst, () { |
| 1085 compiledArguments = | 1085 compiledArguments = |
| 1086 makeStaticArgumentList(callStructure, arguments, target); | 1086 makeStaticArgumentList(callStructure, arguments, target); |
| 1087 }); | 1087 }); |
| 1088 inlineSuperOrRedirect(target.resolvedAst, compiledArguments, | 1088 inlineSuperOrRedirect(target.resolvedAst, compiledArguments, |
| 1089 constructorResolvedAsts, fieldValues, constructor); | 1089 constructorResolvedAsts, fieldValues, constructor); |
| (...skipping 1400 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2490 } | 2490 } |
| 2491 } | 2491 } |
| 2492 | 2492 |
| 2493 /** | 2493 /** |
| 2494 * Returns a list with the evaluated [arguments] in the normalized order. | 2494 * Returns a list with the evaluated [arguments] in the normalized order. |
| 2495 * | 2495 * |
| 2496 * Precondition: `this.applies(element, world)`. | 2496 * Precondition: `this.applies(element, world)`. |
| 2497 * Invariant: [element] must be an implementation element. | 2497 * Invariant: [element] must be an implementation element. |
| 2498 */ | 2498 */ |
| 2499 List<HInstruction> makeStaticArgumentList(CallStructure callStructure, | 2499 List<HInstruction> makeStaticArgumentList(CallStructure callStructure, |
| 2500 Link<ast.Node> arguments, FunctionElement element) { | 2500 Link<ast.Node> arguments, MethodElement element) { |
| 2501 assert(invariant(element, element.isImplementation)); | 2501 assert(invariant(element, element.isDeclaration)); |
| 2502 | 2502 |
| 2503 HInstruction compileArgument(ast.Node argument) { | 2503 HInstruction compileArgument(ast.Node argument) { |
| 2504 visit(argument); | 2504 visit(argument); |
| 2505 return pop(); | 2505 return pop(); |
| 2506 } | 2506 } |
| 2507 | 2507 |
| 2508 return Elements.makeArgumentsList<HInstruction>( | 2508 return Elements.makeArgumentsList<HInstruction>( |
| 2509 callStructure, | 2509 callStructure, |
| 2510 arguments, | 2510 arguments, |
| 2511 element, | 2511 element.implementation, |
| 2512 compileArgument, | 2512 compileArgument, |
| 2513 backend.nativeData.isJsInteropMember(element) | 2513 backend.nativeData.isJsInteropMember(element) |
| 2514 ? handleConstantForOptionalParameterJsInterop | 2514 ? handleConstantForOptionalParameterJsInterop |
| 2515 : handleConstantForOptionalParameter); | 2515 : handleConstantForOptionalParameter); |
| 2516 } | 2516 } |
| 2517 | 2517 |
| 2518 void addGenericSendArgumentsToList( | 2518 void addGenericSendArgumentsToList( |
| 2519 Link<ast.Node> link, List<HInstruction> list) { | 2519 Link<ast.Node> link, List<HInstruction> list) { |
| 2520 for (; !link.isEmpty; link = link.tail) { | 2520 for (; !link.isEmpty; link = link.tail) { |
| 2521 visit(link.head); | 2521 visit(link.head); |
| (...skipping 547 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3069 } | 3069 } |
| 3070 | 3070 |
| 3071 /// Generate a call to a super method or constructor. | 3071 /// Generate a call to a super method or constructor. |
| 3072 void generateSuperInvoke(ast.Send node, MethodElement method, | 3072 void generateSuperInvoke(ast.Send node, MethodElement method, |
| 3073 SourceInformation sourceInformation) { | 3073 SourceInformation sourceInformation) { |
| 3074 // TODO(5347): Try to avoid the need for calling [implementation] before | 3074 // TODO(5347): Try to avoid the need for calling [implementation] before |
| 3075 // calling [makeStaticArgumentList]. | 3075 // calling [makeStaticArgumentList]. |
| 3076 Selector selector = elements.getSelector(node); | 3076 Selector selector = elements.getSelector(node); |
| 3077 assert(invariant(node, selector.applies(method.implementation), | 3077 assert(invariant(node, selector.applies(method.implementation), |
| 3078 message: "$selector does not apply to ${method.implementation}")); | 3078 message: "$selector does not apply to ${method.implementation}")); |
| 3079 List<HInstruction> inputs = makeStaticArgumentList( | 3079 List<HInstruction> inputs = |
| 3080 selector.callStructure, node.arguments, method.implementation); | 3080 makeStaticArgumentList(selector.callStructure, node.arguments, method); |
| 3081 push(buildInvokeSuper(selector, method, inputs, sourceInformation)); | 3081 push(buildInvokeSuper(selector, method, inputs, sourceInformation)); |
| 3082 } | 3082 } |
| 3083 | 3083 |
| 3084 /// Access the value from the super [element]. | 3084 /// Access the value from the super [element]. |
| 3085 void handleSuperGet(ast.Send node, Element element) { | 3085 void handleSuperGet(ast.Send node, Element element) { |
| 3086 Selector selector = elements.getSelector(node); | 3086 Selector selector = elements.getSelector(node); |
| 3087 SourceInformation sourceInformation = | 3087 SourceInformation sourceInformation = |
| 3088 sourceInformationBuilder.buildGet(node); | 3088 sourceInformationBuilder.buildGet(node); |
| 3089 push(buildInvokeSuper( | 3089 push(buildInvokeSuper( |
| 3090 selector, element, const <HInstruction>[], sourceInformation)); | 3090 selector, element, const <HInstruction>[], sourceInformation)); |
| (...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3402 | 3402 |
| 3403 List<HInstruction> inputs = <HInstruction>[]; | 3403 List<HInstruction> inputs = <HInstruction>[]; |
| 3404 if (constructor.isGenerativeConstructor && | 3404 if (constructor.isGenerativeConstructor && |
| 3405 backend.nativeData | 3405 backend.nativeData |
| 3406 .isNativeOrExtendsNative(constructor.enclosingClass) && | 3406 .isNativeOrExtendsNative(constructor.enclosingClass) && |
| 3407 !backend.nativeData.isJsInteropMember(constructor)) { | 3407 !backend.nativeData.isJsInteropMember(constructor)) { |
| 3408 // Native class generative constructors take a pre-constructed object. | 3408 // Native class generative constructors take a pre-constructed object. |
| 3409 inputs.add(graph.addConstantNull(closedWorld)); | 3409 inputs.add(graph.addConstantNull(closedWorld)); |
| 3410 } | 3410 } |
| 3411 inputs.addAll(makeStaticArgumentList( | 3411 inputs.addAll(makeStaticArgumentList( |
| 3412 callStructure, send.arguments, constructorImplementation)); | 3412 callStructure, send.arguments, constructorImplementation.declaration)); |
| 3413 | 3413 |
| 3414 TypeMask elementType = computeType(constructor); | 3414 TypeMask elementType = computeType(constructor); |
| 3415 if (isFixedListConstructorCall) { | 3415 if (isFixedListConstructorCall) { |
| 3416 if (!inputs[0].isNumber(closedWorld)) { | 3416 if (!inputs[0].isNumber(closedWorld)) { |
| 3417 HTypeConversion conversion = new HTypeConversion( | 3417 HTypeConversion conversion = new HTypeConversion( |
| 3418 null, | 3418 null, |
| 3419 HTypeConversion.ARGUMENT_TYPE_CHECK, | 3419 HTypeConversion.ARGUMENT_TYPE_CHECK, |
| 3420 commonMasks.numType, | 3420 commonMasks.numType, |
| 3421 inputs[0]); | 3421 inputs[0]); |
| 3422 add(conversion); | 3422 add(conversion); |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3562 } | 3562 } |
| 3563 return false; | 3563 return false; |
| 3564 } | 3564 } |
| 3565 | 3565 |
| 3566 visitStaticSend(ast.Send node) { | 3566 visitStaticSend(ast.Send node) { |
| 3567 internalError(node, "Unexpected visitStaticSend"); | 3567 internalError(node, "Unexpected visitStaticSend"); |
| 3568 } | 3568 } |
| 3569 | 3569 |
| 3570 /// Generate an invocation to the static or top level [function]. | 3570 /// Generate an invocation to the static or top level [function]. |
| 3571 void generateStaticFunctionInvoke( | 3571 void generateStaticFunctionInvoke( |
| 3572 ast.Send node, FunctionElement function, CallStructure callStructure) { | 3572 ast.Send node, MethodElement function, CallStructure callStructure) { |
| 3573 List<HInstruction> inputs = makeStaticArgumentList( | 3573 List<HInstruction> inputs = |
| 3574 callStructure, node.arguments, function.implementation); | 3574 makeStaticArgumentList(callStructure, node.arguments, function); |
| 3575 | 3575 |
| 3576 pushInvokeStatic(node, function, inputs, | 3576 pushInvokeStatic(node, function, inputs, |
| 3577 sourceInformation: | 3577 sourceInformation: |
| 3578 sourceInformationBuilder.buildCall(node, node.selector)); | 3578 sourceInformationBuilder.buildCall(node, node.selector)); |
| 3579 } | 3579 } |
| 3580 | 3580 |
| 3581 /// Generate an invocation to a static or top level function with the wrong | 3581 /// Generate an invocation to a static or top level function with the wrong |
| 3582 /// number of arguments. | 3582 /// number of arguments. |
| 3583 void generateStaticFunctionIncompatibleInvoke( | 3583 void generateStaticFunctionIncompatibleInvoke( |
| 3584 ast.Send node, Element element) { | 3584 ast.Send node, Element element) { |
| (...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4026 var filteredArguments = <HInstruction>[]; | 4026 var filteredArguments = <HInstruction>[]; |
| 4027 var parameterNameMap = new Map<String, js.Expression>(); | 4027 var parameterNameMap = new Map<String, js.Expression>(); |
| 4028 params.orderedForEachParameter((ParameterElement parameter) { | 4028 params.orderedForEachParameter((ParameterElement parameter) { |
| 4029 // TODO(jacobr): consider throwing if parameter names do not match | 4029 // TODO(jacobr): consider throwing if parameter names do not match |
| 4030 // names of properties in the class. | 4030 // names of properties in the class. |
| 4031 assert(parameter.isNamed); | 4031 assert(parameter.isNamed); |
| 4032 HInstruction argument = arguments[i]; | 4032 HInstruction argument = arguments[i]; |
| 4033 if (argument != null) { | 4033 if (argument != null) { |
| 4034 filteredArguments.add(argument); | 4034 filteredArguments.add(argument); |
| 4035 var jsName = | 4035 var jsName = |
| 4036 backend.nativeData.getUnescapedJSInteropName(parameter.name); | 4036 backend.nativeData.computeUnescapedJSInteropName(parameter.name); |
| 4037 parameterNameMap[jsName] = new js.InterpolatedExpression(positions++); | 4037 parameterNameMap[jsName] = new js.InterpolatedExpression(positions++); |
| 4038 } | 4038 } |
| 4039 i++; | 4039 i++; |
| 4040 }); | 4040 }); |
| 4041 var codeTemplate = | 4041 var codeTemplate = |
| 4042 new js.Template(null, js.objectLiteral(parameterNameMap)); | 4042 new js.Template(null, js.objectLiteral(parameterNameMap)); |
| 4043 | 4043 |
| 4044 var nativeBehavior = new native.NativeBehavior() | 4044 var nativeBehavior = new native.NativeBehavior() |
| 4045 ..codeTemplate = codeTemplate; | 4045 ..codeTemplate = codeTemplate; |
| 4046 if (compiler.options.trustJSInteropTypeAnnotations) { | 4046 if (compiler.options.trustJSInteropTypeAnnotations) { |
| 4047 nativeBehavior.typesReturned.add(constructor.enclosingClass.thisType); | 4047 nativeBehavior.typesReturned.add(constructor.enclosingClass.thisType); |
| 4048 } | 4048 } |
| 4049 return new HForeignCode( | 4049 return new HForeignCode( |
| 4050 codeTemplate, commonMasks.dynamicType, filteredArguments, | 4050 codeTemplate, commonMasks.dynamicType, filteredArguments, |
| 4051 nativeBehavior: nativeBehavior) | 4051 nativeBehavior: nativeBehavior) |
| 4052 ..sourceInformation = sourceInformation; | 4052 ..sourceInformation = sourceInformation; |
| 4053 } | 4053 } |
| 4054 var target = new HForeignCode( | 4054 var target = new HForeignCode( |
| 4055 js.js.parseForeignJS("${backend.namer.fixedBackendMethodPath(element)}." | 4055 js.js.parseForeignJS( |
| 4056 "${backend.nativeData.getFixedBackendMethodPath(element)}." |
| 4056 "${backend.nativeData.getFixedBackendName(element)}"), | 4057 "${backend.nativeData.getFixedBackendName(element)}"), |
| 4057 commonMasks.dynamicType, | 4058 commonMasks.dynamicType, |
| 4058 <HInstruction>[]); | 4059 <HInstruction>[]); |
| 4059 add(target); | 4060 add(target); |
| 4060 // Strip off trailing arguments that were not specified. | 4061 // Strip off trailing arguments that were not specified. |
| 4061 // we could assert that the trailing arguments are all null. | 4062 // we could assert that the trailing arguments are all null. |
| 4062 // TODO(jacobr): rewrite named arguments to an object literal matching | 4063 // TODO(jacobr): rewrite named arguments to an object literal matching |
| 4063 // the factory constructor case. | 4064 // the factory constructor case. |
| 4064 arguments = arguments.where((arg) => arg != null).toList(); | 4065 arguments = arguments.where((arg) => arg != null).toList(); |
| 4065 var inputs = <HInstruction>[target]..addAll(arguments); | 4066 var inputs = <HInstruction>[target]..addAll(arguments); |
| (...skipping 2662 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6728 this.oldReturnLocal, | 6729 this.oldReturnLocal, |
| 6729 this.oldReturnType, | 6730 this.oldReturnType, |
| 6730 this.oldResolvedAst, | 6731 this.oldResolvedAst, |
| 6731 this.oldStack, | 6732 this.oldStack, |
| 6732 this.oldLocalsHandler, | 6733 this.oldLocalsHandler, |
| 6733 this.inTryStatement, | 6734 this.inTryStatement, |
| 6734 this.allFunctionsCalledOnce, | 6735 this.allFunctionsCalledOnce, |
| 6735 this.oldElementInferenceResults) | 6736 this.oldElementInferenceResults) |
| 6736 : super(function); | 6737 : super(function); |
| 6737 } | 6738 } |
| OLD | NEW |