| 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 838 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 849 /** | 849 /** |
| 850 * This method sets up the local state of the builder for inlining [function]. | 850 * This method sets up the local state of the builder for inlining [function]. |
| 851 * The arguments of the function are inserted into the [localsHandler]. | 851 * The arguments of the function are inserted into the [localsHandler]. |
| 852 * | 852 * |
| 853 * When inlining a function, [:return:] statements are not emitted as | 853 * When inlining a function, [:return:] statements are not emitted as |
| 854 * [HReturn] instructions. Instead, the value of a synthetic element is | 854 * [HReturn] instructions. Instead, the value of a synthetic element is |
| 855 * updated in the [localsHandler]. This function creates such an element and | 855 * updated in the [localsHandler]. This function creates such an element and |
| 856 * stores it in the [returnLocal] field. | 856 * stores it in the [returnLocal] field. |
| 857 */ | 857 */ |
| 858 void setupStateForInlining( | 858 void setupStateForInlining( |
| 859 FunctionElement function, List<HInstruction> compiledArguments, | 859 MethodElement function, List<HInstruction> compiledArguments, |
| 860 {ResolutionInterfaceType instanceType}) { | 860 {ResolutionInterfaceType instanceType}) { |
| 861 ResolvedAst resolvedAst = function.resolvedAst; | 861 ResolvedAst resolvedAst = function.resolvedAst; |
| 862 assert(resolvedAst != null); | 862 assert(resolvedAst != null); |
| 863 localsHandler = new LocalsHandler(this, function, function.memberContext, | 863 localsHandler = new LocalsHandler(this, function, function.memberContext, |
| 864 function.contextClass, instanceType, nativeData, interceptorData); | 864 function.contextClass, instanceType, nativeData, interceptorData); |
| 865 localsHandler.closureData = | 865 localsHandler.closureData = closureToClassMapper.getMemberMap(function); |
| 866 closureToClassMapper.getClosureToClassMapping(resolvedAst); | |
| 867 returnLocal = | 866 returnLocal = |
| 868 new SyntheticLocal("result", function, function.memberContext); | 867 new SyntheticLocal("result", function, function.memberContext); |
| 869 localsHandler.updateLocal(returnLocal, graph.addConstantNull(closedWorld)); | 868 localsHandler.updateLocal(returnLocal, graph.addConstantNull(closedWorld)); |
| 870 | 869 |
| 871 inTryStatement = false; // TODO(lry): why? Document. | 870 inTryStatement = false; // TODO(lry): why? Document. |
| 872 | 871 |
| 873 int argumentIndex = 0; | 872 int argumentIndex = 0; |
| 874 if (function.isInstanceMember) { | 873 if (function.isInstanceMember) { |
| 875 localsHandler.updateLocal(localsHandler.closureData.thisLocal, | 874 localsHandler.updateLocal(localsHandler.closureData.thisLocal, |
| 876 compiledArguments[argumentIndex++]); | 875 compiledArguments[argumentIndex++]); |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1024 } | 1023 } |
| 1025 }); | 1024 }); |
| 1026 | 1025 |
| 1027 // Build the initializers in the context of the new constructor. | 1026 // Build the initializers in the context of the new constructor. |
| 1028 ResolvedAst oldResolvedAst = resolvedAst; | 1027 ResolvedAst oldResolvedAst = resolvedAst; |
| 1029 resolvedAst = callee.resolvedAst; | 1028 resolvedAst = callee.resolvedAst; |
| 1030 final oldElementInferenceResults = elementInferenceResults; | 1029 final oldElementInferenceResults = elementInferenceResults; |
| 1031 elementInferenceResults = globalInferenceResults.resultOfMember(callee); | 1030 elementInferenceResults = globalInferenceResults.resultOfMember(callee); |
| 1032 ClosureClassMap oldClosureData = localsHandler.closureData; | 1031 ClosureClassMap oldClosureData = localsHandler.closureData; |
| 1033 ClosureClassMap newClosureData = | 1032 ClosureClassMap newClosureData = |
| 1034 closureToClassMapper.getClosureToClassMapping(resolvedAst); | 1033 closureToClassMapper.getMemberMap(callee); |
| 1035 localsHandler.closureData = newClosureData; | 1034 localsHandler.closureData = newClosureData; |
| 1036 if (resolvedAst.kind == ResolvedAstKind.PARSED) { | 1035 if (resolvedAst.kind == ResolvedAstKind.PARSED) { |
| 1037 localsHandler.enterScope(resolvedAst.node, callee); | 1036 localsHandler.enterScope(resolvedAst.node, |
| 1037 forGenerativeConstructorBody: callee.isGenerativeConstructorBody); |
| 1038 } | 1038 } |
| 1039 buildInitializers(callee, constructorResolvedAsts, fieldValues); | 1039 buildInitializers(callee, constructorResolvedAsts, fieldValues); |
| 1040 localsHandler.closureData = oldClosureData; | 1040 localsHandler.closureData = oldClosureData; |
| 1041 resolvedAst = oldResolvedAst; | 1041 resolvedAst = oldResolvedAst; |
| 1042 elementInferenceResults = oldElementInferenceResults; | 1042 elementInferenceResults = oldElementInferenceResults; |
| 1043 }); | 1043 }); |
| 1044 } | 1044 } |
| 1045 | 1045 |
| 1046 void buildInitializers( | 1046 void buildInitializers( |
| 1047 ConstructorElement constructor, | 1047 ConstructorElement constructor, |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1198 if (!nativeData.isNativeOrExtendsNative(classElement)) { | 1198 if (!nativeData.isNativeOrExtendsNative(classElement)) { |
| 1199 fieldValues[member] = graph.addConstantNull(closedWorld); | 1199 fieldValues[member] = graph.addConstantNull(closedWorld); |
| 1200 } | 1200 } |
| 1201 } else { | 1201 } else { |
| 1202 ast.Node right = initializer; | 1202 ast.Node right = initializer; |
| 1203 ResolvedAst savedResolvedAst = resolvedAst; | 1203 ResolvedAst savedResolvedAst = resolvedAst; |
| 1204 resolvedAst = fieldResolvedAst; | 1204 resolvedAst = fieldResolvedAst; |
| 1205 final oldElementInferenceResults = elementInferenceResults; | 1205 final oldElementInferenceResults = elementInferenceResults; |
| 1206 elementInferenceResults = | 1206 elementInferenceResults = |
| 1207 globalInferenceResults.resultOfMember(member); | 1207 globalInferenceResults.resultOfMember(member); |
| 1208 // In case the field initializer uses closures, run the | |
| 1209 // closure to class mapper. | |
| 1210 closureToClassMapper.getClosureToClassMapping(resolvedAst); | |
| 1211 inlinedFrom(fieldResolvedAst, () => right.accept(this)); | 1208 inlinedFrom(fieldResolvedAst, () => right.accept(this)); |
| 1212 resolvedAst = savedResolvedAst; | 1209 resolvedAst = savedResolvedAst; |
| 1213 elementInferenceResults = oldElementInferenceResults; | 1210 elementInferenceResults = oldElementInferenceResults; |
| 1214 fieldValues[member] = pop(); | 1211 fieldValues[member] = pop(); |
| 1215 } | 1212 } |
| 1216 }); | 1213 }); |
| 1217 }); | 1214 }); |
| 1218 } | 1215 } |
| 1219 | 1216 |
| 1220 /** | 1217 /** |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1363 if (isNativeUpgradeFactory) { | 1360 if (isNativeUpgradeFactory) { |
| 1364 if (interceptor == null) { | 1361 if (interceptor == null) { |
| 1365 ConstantValue constant = new InterceptorConstantValue(classElement); | 1362 ConstantValue constant = new InterceptorConstantValue(classElement); |
| 1366 interceptor = graph.addConstant(constant, closedWorld); | 1363 interceptor = graph.addConstant(constant, closedWorld); |
| 1367 } | 1364 } |
| 1368 bodyCallInputs.add(interceptor); | 1365 bodyCallInputs.add(interceptor); |
| 1369 } | 1366 } |
| 1370 bodyCallInputs.add(newObject); | 1367 bodyCallInputs.add(newObject); |
| 1371 ast.Node node = constructorResolvedAst.node; | 1368 ast.Node node = constructorResolvedAst.node; |
| 1372 ClosureClassMap parameterClosureData = | 1369 ClosureClassMap parameterClosureData = |
| 1373 closureToClassMapper.getClosureToClassMapping(constructorResolvedAst); | 1370 closureToClassMapper.getMemberMap(functionElement); |
| 1374 | 1371 |
| 1375 FunctionSignature functionSignature = body.functionSignature; | 1372 FunctionSignature functionSignature = body.functionSignature; |
| 1376 // Provide the parameters to the generative constructor body. | 1373 // Provide the parameters to the generative constructor body. |
| 1377 functionSignature.orderedForEachParameter((ParameterElement parameter) { | 1374 functionSignature.orderedForEachParameter((ParameterElement parameter) { |
| 1378 // If [parameter] is boxed, it will be a field in the box passed as the | 1375 // If [parameter] is boxed, it will be a field in the box passed as the |
| 1379 // last parameter. So no need to directly pass it. | 1376 // last parameter. So no need to directly pass it. |
| 1380 if (!localsHandler.isBoxed(parameter)) { | 1377 if (!localsHandler.isBoxed(parameter)) { |
| 1381 bodyCallInputs.add(localsHandler.readLocal(parameter)); | 1378 bodyCallInputs.add(localsHandler.readLocal(parameter)); |
| 1382 } | 1379 } |
| 1383 }); | 1380 }); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1429 /** | 1426 /** |
| 1430 * Documentation wanted -- johnniwinther | 1427 * Documentation wanted -- johnniwinther |
| 1431 * | 1428 * |
| 1432 * Invariant: [functionElement] must be the implementation element. | 1429 * Invariant: [functionElement] must be the implementation element. |
| 1433 */ | 1430 */ |
| 1434 void openFunction(MemberElement element, ast.Node node) { | 1431 void openFunction(MemberElement element, ast.Node node) { |
| 1435 assert(invariant(element, element.isImplementation)); | 1432 assert(invariant(element, element.isImplementation)); |
| 1436 HBasicBlock block = graph.addNewBlock(); | 1433 HBasicBlock block = graph.addNewBlock(); |
| 1437 open(graph.entry); | 1434 open(graph.entry); |
| 1438 | 1435 |
| 1439 localsHandler.startFunction(element, node); | 1436 localsHandler.startFunction(element, node, |
| 1437 isGenerativeConstructorBody: element.isGenerativeConstructorBody); |
| 1440 close(new HGoto()).addSuccessor(block); | 1438 close(new HGoto()).addSuccessor(block); |
| 1441 | 1439 |
| 1442 open(block); | 1440 open(block); |
| 1443 | 1441 |
| 1444 // Add the type parameters of the class as parameters of this method. This | 1442 // Add the type parameters of the class as parameters of this method. This |
| 1445 // must be done before adding the normal parameters, because their types | 1443 // must be done before adding the normal parameters, because their types |
| 1446 // may contain references to type variables. | 1444 // may contain references to type variables. |
| 1447 ClassElement cls = element.enclosingClass; | 1445 ClassElement cls = element.enclosingClass; |
| 1448 if ((element.isConstructor || element.isGenerativeConstructorBody) && | 1446 if ((element.isConstructor || element.isGenerativeConstructorBody) && |
| 1449 rtiNeed.classNeedsRti(cls)) { | 1447 rtiNeed.classNeedsRti(cls)) { |
| (...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1857 block.remove(breakInstruction); | 1855 block.remove(breakInstruction); |
| 1858 }); | 1856 }); |
| 1859 } | 1857 } |
| 1860 } | 1858 } |
| 1861 jumpHandler.close(); | 1859 jumpHandler.close(); |
| 1862 loopDepth--; | 1860 loopDepth--; |
| 1863 } | 1861 } |
| 1864 | 1862 |
| 1865 visitFunctionExpression(ast.FunctionExpression node) { | 1863 visitFunctionExpression(ast.FunctionExpression node) { |
| 1866 LocalFunctionElement methodElement = elements[node]; | 1864 LocalFunctionElement methodElement = elements[node]; |
| 1867 ClosureClassMap nestedClosureData = closureToClassMapper | 1865 ClosureClassMap nestedClosureData = |
| 1868 .getClosureToClassMapping(methodElement.resolvedAst); | 1866 closureToClassMapper.getLocalFunctionMap(methodElement); |
| 1869 assert(nestedClosureData != null); | 1867 assert(nestedClosureData != null); |
| 1870 assert(nestedClosureData.closureClassElement != null); | 1868 assert(nestedClosureData.closureClassElement != null); |
| 1871 ClosureClassElement closureClassElement = | 1869 ClosureClassElement closureClassElement = |
| 1872 nestedClosureData.closureClassElement; | 1870 nestedClosureData.closureClassElement; |
| 1873 MethodElement callElement = nestedClosureData.callElement; | 1871 MethodElement callElement = nestedClosureData.callElement; |
| 1874 | 1872 |
| 1875 List<HInstruction> capturedVariables = <HInstruction>[]; | 1873 List<HInstruction> capturedVariables = <HInstruction>[]; |
| 1876 closureClassElement.closureFields.forEach((ClosureFieldElement field) { | 1874 closureClassElement.closureFields.forEach((ClosureFieldElement field) { |
| 1877 Local capturedLocal = | 1875 Local capturedLocal = |
| 1878 nestedClosureData.getLocalVariableForClosureField(field); | 1876 nestedClosureData.getLocalVariableForClosureField(field); |
| (...skipping 4924 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6803 this.oldReturnLocal, | 6801 this.oldReturnLocal, |
| 6804 this.oldReturnType, | 6802 this.oldReturnType, |
| 6805 this.oldResolvedAst, | 6803 this.oldResolvedAst, |
| 6806 this.oldStack, | 6804 this.oldStack, |
| 6807 this.oldLocalsHandler, | 6805 this.oldLocalsHandler, |
| 6808 this.inTryStatement, | 6806 this.inTryStatement, |
| 6809 this.allFunctionsCalledOnce, | 6807 this.allFunctionsCalledOnce, |
| 6810 this.oldElementInferenceResults) | 6808 this.oldElementInferenceResults) |
| 6811 : super(function); | 6809 : super(function); |
| 6812 } | 6810 } |
| OLD | NEW |