Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(211)

Side by Side Diff: frog/leg/ssa/builder.dart

Issue 9378040: Allow self-referencing closures. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address comments. Created 8 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « frog/leg/elements/elements.dart ('k') | frog/leg/ssa/closure.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « frog/leg/elements/elements.dart ('k') | frog/leg/ssa/closure.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698