| 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 class Interceptors { | 5 class Interceptors { |
| 6 Compiler compiler; | 6 Compiler compiler; |
| 7 Interceptors(Compiler this.compiler); | 7 Interceptors(Compiler this.compiler); |
| 8 | 8 |
| 9 SourceString mapOperatorToMethodName(Operator op) { | 9 SourceString mapOperatorToMethodName(Operator op) { |
| 10 String name = op.source.stringValue; | 10 String name = op.source.stringValue; |
| (...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 209 } | 209 } |
| 210 } | 210 } |
| 211 | 211 |
| 212 void startFunction(FunctionElement function, | 212 void startFunction(FunctionElement function, |
| 213 FunctionExpression node) { | 213 FunctionExpression node) { |
| 214 | 214 |
| 215 ClosureTranslator translator = | 215 ClosureTranslator translator = |
| 216 new ClosureTranslator(builder.compiler, builder.elements); | 216 new ClosureTranslator(builder.compiler, builder.elements); |
| 217 closureData = translator.translate(node); | 217 closureData = translator.translate(node); |
| 218 | 218 |
| 219 if (closureData.thisElement !== null && | |
| 220 isAccessedDirectly(closureData.thisElement)) { | |
| 221 HInstruction thisInstruction = new HThis(); | |
| 222 updateLocal(closureData.thisElement, thisInstruction); | |
| 223 builder.add(thisInstruction); | |
| 224 } | |
| 225 | |
| 226 FunctionParameters params = function.computeParameters(builder.compiler); | 219 FunctionParameters params = function.computeParameters(builder.compiler); |
| 227 params.forEachParameter((Element element) { | 220 params.forEachParameter((Element element) { |
| 228 HParameterValue parameter = new HParameterValue(element); | 221 HParameterValue parameter = new HParameterValue(element); |
| 229 builder.add(parameter); | 222 builder.add(parameter); |
| 230 // Note that for constructors [element] could be a field-element which we | 223 // Note that for constructors [element] could be a field-element which we |
| 231 // treat as if it was a local. | 224 // treat as if it was a local. |
| 232 directLocals[element] = parameter; | 225 directLocals[element] = parameter; |
| 233 }); | 226 }); |
| 234 | 227 |
| 235 enterScope(node); | 228 enterScope(node); |
| 236 | 229 |
| 237 // If the freeVariableMapping is not empty, then this function was a | 230 // If the freeVariableMapping is not empty, then this function was a |
| 238 // nested closure that captures variables. Redirect the captured | 231 // nested closure that captures variables. Redirect the captured |
| 239 // variables to fields in the closure. | 232 // variables to fields in the closure. |
| 240 closureData.freeVariableMapping.forEach((Element from, Element to) { | 233 closureData.freeVariableMapping.forEach((Element from, Element to) { |
| 241 redirectElement(from, to); | 234 redirectElement(from, to); |
| 242 }); | 235 }); |
| 236 if (closureData.isClosure()) { |
| 237 // Inside closure redirect references to itself to [:this:]. |
| 238 HInstruction thisInstruction = new HThis(); |
| 239 builder.add(thisInstruction); |
| 240 updateLocal(closureData.closureElement, thisInstruction); |
| 241 } else if (function.isInstanceMember() || |
| 242 function.isGenerativeConstructor()) { |
| 243 HInstruction thisInstruction = new HThis(); |
| 244 builder.add(thisInstruction); |
| 245 updateLocal(closureData.thisElement, thisInstruction); |
| 246 } |
| 243 } | 247 } |
| 244 | 248 |
| 245 /** | 249 /** |
| 246 * Returns true if the [For] loop declares a variable that is boxed. | 250 * Returns true if the [For] loop declares a variable that is boxed. |
| 247 */ | 251 */ |
| 248 bool isForLoopDeclaringBoxedLoopVariable(Loop node) { | 252 bool isForLoopDeclaringBoxedLoopVariable(Loop node) { |
| 249 For forNode = node.asFor(); | 253 For forNode = node.asFor(); |
| 250 if (forNode === null) return false; | 254 if (forNode === null) return false; |
| 251 if (forNode.initializer === null) return false; | 255 if (forNode.initializer === null) return false; |
| 252 VariableDefinitions definitions = | 256 VariableDefinitions definitions = |
| (...skipping 628 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 881 | 885 |
| 882 conditionBlock.addSuccessor(loopEntryBlock); // The back-edge. | 886 conditionBlock.addSuccessor(loopEntryBlock); // The back-edge. |
| 883 loopEntryBlock.postProcessLoopHeader(); | 887 loopEntryBlock.postProcessLoopHeader(); |
| 884 | 888 |
| 885 endLoop(loopEntryBlock, conditionBlock); | 889 endLoop(loopEntryBlock, conditionBlock); |
| 886 } | 890 } |
| 887 | 891 |
| 888 visitFunctionExpression(FunctionExpression node) { | 892 visitFunctionExpression(FunctionExpression node) { |
| 889 ClosureData nestedClosureData = closureDataCache[node]; | 893 ClosureData nestedClosureData = closureDataCache[node]; |
| 890 assert(nestedClosureData !== null); | 894 assert(nestedClosureData !== null); |
| 891 assert(nestedClosureData.globalizedClosureElement !== null); | 895 assert(nestedClosureData.closureClassElement !== null); |
| 892 ClassElement globalizedClosureElement = | 896 ClassElement closureClassElement = |
| 893 nestedClosureData.globalizedClosureElement; | 897 nestedClosureData.closureClassElement; |
| 894 FunctionElement callElement = nestedClosureData.callElement; | 898 FunctionElement callElement = nestedClosureData.callElement; |
| 895 compiler.enqueue(new WorkItem.toCodegen(callElement, elements)); | 899 compiler.enqueue(new WorkItem.toCodegen(callElement, elements)); |
| 896 compiler.registerInstantiatedClass(globalizedClosureElement); | 900 compiler.registerInstantiatedClass(closureClassElement); |
| 897 assert(globalizedClosureElement.members.isEmpty()); | 901 assert(closureClassElement.members.isEmpty()); |
| 898 | 902 |
| 899 List<HInstruction> capturedVariables = <HInstruction>[]; | 903 List<HInstruction> capturedVariables = <HInstruction>[]; |
| 900 for (Element member in globalizedClosureElement.backendMembers) { | 904 for (Element member in closureClassElement.backendMembers) { |
| 901 // The backendMembers also contains the call method(s). We are only | 905 // The backendMembers also contains the call method(s). We are only |
| 902 // interested in the fields. | 906 // interested in the fields. |
| 903 if (member.kind == ElementKind.FIELD) { | 907 if (member.kind == ElementKind.FIELD) { |
| 904 Element capturedLocal = nestedClosureData.capturedFieldMapping[member]; | 908 Element capturedLocal = nestedClosureData.capturedFieldMapping[member]; |
| 905 assert(capturedLocal != null); | 909 assert(capturedLocal != null); |
| 906 capturedVariables.add(localsHandler.readLocal(capturedLocal)); | 910 capturedVariables.add(localsHandler.readLocal(capturedLocal)); |
| 907 } | 911 } |
| 908 } | 912 } |
| 909 | 913 |
| 910 push(new HForeignNew(globalizedClosureElement, capturedVariables)); | 914 push(new HForeignNew(closureClassElement, capturedVariables)); |
| 911 } | 915 } |
| 912 | 916 |
| 913 visitIdentifier(Identifier node) { | 917 visitIdentifier(Identifier node) { |
| 914 if (node.isThis()) { | 918 if (node.isThis()) { |
| 915 stack.add(localsHandler.readThis()); | 919 stack.add(localsHandler.readThis()); |
| 916 } else { | 920 } else { |
| 917 compiler.internalError("SsaBuilder.visitIdentifier on non-this", | 921 compiler.internalError("SsaBuilder.visitIdentifier on non-this", |
| 918 node: node); | 922 node: node); |
| 919 } | 923 } |
| 920 } | 924 } |
| (...skipping 475 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1396 | 1400 |
| 1397 visitClosureSend(Send node) { | 1401 visitClosureSend(Send node) { |
| 1398 Selector selector = elements.getSelector(node); | 1402 Selector selector = elements.getSelector(node); |
| 1399 assert(node.receiver === null); | 1403 assert(node.receiver === null); |
| 1400 Element element = elements[node]; | 1404 Element element = elements[node]; |
| 1401 HInstruction closureTarget; | 1405 HInstruction closureTarget; |
| 1402 if (element === null) { | 1406 if (element === null) { |
| 1403 visit(node.selector); | 1407 visit(node.selector); |
| 1404 closureTarget = pop(); | 1408 closureTarget = pop(); |
| 1405 } else { | 1409 } else { |
| 1406 assert(element.kind === ElementKind.VARIABLE || | 1410 assert(Elements.isLocal(element)); |
| 1407 element.kind === ElementKind.PARAMETER); | |
| 1408 closureTarget = localsHandler.readLocal(element); | 1411 closureTarget = localsHandler.readLocal(element); |
| 1409 } | 1412 } |
| 1410 var inputs = <HInstruction>[]; | 1413 var inputs = <HInstruction>[]; |
| 1411 inputs.add(closureTarget); | 1414 inputs.add(closureTarget); |
| 1412 addDynamicSendArgumentsToList(node, inputs); | 1415 addDynamicSendArgumentsToList(node, inputs); |
| 1413 push(new HInvokeClosure(selector, inputs)); | 1416 push(new HInvokeClosure(selector, inputs)); |
| 1414 } | 1417 } |
| 1415 | 1418 |
| 1416 visitForeignSend(Send node) { | 1419 visitForeignSend(Send node) { |
| 1417 Identifier selector = node.selector; | 1420 Identifier selector = node.selector; |
| (...skipping 525 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1943 } | 1946 } |
| 1944 | 1947 |
| 1945 visitCatchBlock(CatchBlock node) { | 1948 visitCatchBlock(CatchBlock node) { |
| 1946 visit(node.block); | 1949 visit(node.block); |
| 1947 } | 1950 } |
| 1948 | 1951 |
| 1949 visitTypedef(Typedef node) { | 1952 visitTypedef(Typedef node) { |
| 1950 compiler.unimplemented('SsaBuilder.visitTypedef', node: node); | 1953 compiler.unimplemented('SsaBuilder.visitTypedef', node: node); |
| 1951 } | 1954 } |
| 1952 } | 1955 } |
| OLD | NEW |