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 |