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

Side by Side Diff: pkg/compiler/lib/src/ssa/builder.dart

Issue 839323003: Implementation of async-await transformation on js ast. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Add missing functions to the MockCompiler's library Created 5 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
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 part of ssa; 5 part of ssa;
6 6
7 class SsaFunctionCompiler implements FunctionCompiler { 7 class SsaFunctionCompiler implements FunctionCompiler {
8 SsaCodeGeneratorTask generator; 8 SsaCodeGeneratorTask generator;
9 SsaBuilderTask builder; 9 SsaBuilderTask builder;
10 SsaOptimizerTask optimizer; 10 SsaOptimizerTask optimizer;
11 11
12 SsaFunctionCompiler(JavaScriptBackend backend, bool generateSourceMap) 12 SsaFunctionCompiler(JavaScriptBackend backend, bool generateSourceMap)
13 : generator = new SsaCodeGeneratorTask(backend), 13 : generator = new SsaCodeGeneratorTask(backend),
14 builder = new SsaBuilderTask(backend, generateSourceMap), 14 builder = new SsaBuilderTask(backend, generateSourceMap),
15 optimizer = new SsaOptimizerTask(backend); 15 optimizer = new SsaOptimizerTask(backend);
16 16
17 /// Generates JavaScript code for `work.element`. 17 /// Generates JavaScript code for `work.element`.
18 /// Using the ssa builder, optimizer and codegenerator. 18 /// Using the ssa builder, optimizer and codegenerator.
19 js.Fun compile(CodegenWorkItem work) { 19 js.Fun compile(CodegenWorkItem work) {
20 HGraph graph = builder.build(work); 20 HGraph graph = builder.build(work);
21 optimizer.optimize(work, graph); 21 optimizer.optimize(work, graph);
22 return generator.generateCode(work, graph); 22 Element element = work.element;
23 js.Expression result = generator.generateCode(work, graph);
24 if (element is FunctionElement) {
25 JavaScriptBackend backend = builder.backend;
26 AsyncRewriter rewriter = null;
27 if (element.asyncMarker == AsyncMarker.ASYNC) {
28 rewriter = new AsyncRewriter(
29 backend.compiler,
30 backend.compiler.currentElement,
31 thenHelper:
32 backend.emitter.staticFunctionAccess(backend.getThenHelper()),
33 newController: new js.New(backend.emitter.staticFunctionAccess(
34 backend.getCompleterConstructor()), []),
35 safeVariableName: backend.namer.safeVariableName);
36 } else if (element.asyncMarker == AsyncMarker.SYNC_STAR) {
37 rewriter = new AsyncRewriter(
38 backend.compiler,
39 backend.compiler.currentElement,
40 endOfIteration: backend.emitter.staticFunctionAccess(
41 backend.getEndOfIteration()),
42 newIterable: backend.emitter.staticFunctionAccess(
43 backend.getSyncStarIterableConstructor()),
44 yieldStarExpression: backend.emitter.staticFunctionAccess(
45 backend.getYieldStar()),
46 safeVariableName: backend.namer.safeVariableName);
47 }
48 else if (element.asyncMarker == AsyncMarker.ASYNC_STAR) {
49 rewriter = new AsyncRewriter(
50 backend.compiler,
51 backend.compiler.currentElement,
52 thenHelper: backend.emitter.staticFunctionAccess(
53 backend.getStreamHelper()),
54 newController: new js.Call(backend.emitter.staticFunctionAccess(
55 backend.getMakeController()), []),
56 safeVariableName: backend.namer.safeVariableName,
57 yieldExpression: backend.emitter.staticFunctionAccess(
58 backend.getYieldSingle()),
59 yieldStarExpression: backend.emitter.staticFunctionAccess(
60 backend.getYieldStar()));
61 }
62 if (rewriter != null) {
63 result = rewriter.rewrite(result);
64 }
65 }
66 return result;
23 } 67 }
24 68
25 Iterable<CompilerTask> get tasks { 69 Iterable<CompilerTask> get tasks {
26 return <CompilerTask>[builder, optimizer, generator]; 70 return <CompilerTask>[builder, optimizer, generator];
27 } 71 }
28 } 72 }
29 73
30 /// A synthetic local variable only used with the SSA graph. 74 /// A synthetic local variable only used with the SSA graph.
31 /// 75 ///
32 /// For instance used for holding return value of function or the exception of a 76 /// For instance used for holding return value of function or the exception of a
(...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after
355 } 399 }
356 } 400 }
357 401
358 /** 402 /**
359 * Returns true if the local can be accessed directly. Boxed variables or 403 * Returns true if the local can be accessed directly. Boxed variables or
360 * captured variables that are stored in the closure-field return [:false:]. 404 * captured variables that are stored in the closure-field return [:false:].
361 */ 405 */
362 bool isAccessedDirectly(Local local) { 406 bool isAccessedDirectly(Local local) {
363 assert(local != null); 407 assert(local != null);
364 return !redirectionMapping.containsKey(local) 408 return !redirectionMapping.containsKey(local)
365 && !closureData.usedVariablesInTry.contains(local); 409 && !closureData.variablesUsedInTryOrGenerator.contains(local);
366 } 410 }
367 411
368 bool isStoredInClosureField(Local local) { 412 bool isStoredInClosureField(Local local) {
369 assert(local != null); 413 assert(local != null);
370 if (isAccessedDirectly(local)) return false; 414 if (isAccessedDirectly(local)) return false;
371 CapturedVariable redirectTarget = redirectionMapping[local]; 415 CapturedVariable redirectTarget = redirectionMapping[local];
372 if (redirectTarget == null) return false; 416 if (redirectTarget == null) return false;
373 return redirectTarget is ClosureFieldElement; 417 return redirectTarget is ClosureFieldElement;
374 } 418 }
375 419
376 bool isBoxed(Local local) { 420 bool isBoxed(Local local) {
377 if (isAccessedDirectly(local)) return false; 421 if (isAccessedDirectly(local)) return false;
378 if (isStoredInClosureField(local)) return false; 422 if (isStoredInClosureField(local)) return false;
379 return redirectionMapping.containsKey(local); 423 return redirectionMapping.containsKey(local);
380 } 424 }
381 425
382 bool isUsedInTry(Local local) { 426 bool isUsedInTryOrGenerator(Local local) {
383 return closureData.usedVariablesInTry.contains(local); 427 return closureData.variablesUsedInTryOrGenerator.contains(local);
384 } 428 }
385 429
386 /** 430 /**
387 * Returns an [HInstruction] for the given element. If the element is 431 * Returns an [HInstruction] for the given element. If the element is
388 * boxed or stored in a closure then the method generates code to retrieve 432 * boxed or stored in a closure then the method generates code to retrieve
389 * the value. 433 * the value.
390 */ 434 */
391 HInstruction readLocal(Local local) { 435 HInstruction readLocal(Local local) {
392 if (isAccessedDirectly(local)) { 436 if (isAccessedDirectly(local)) {
393 if (directLocals[local] == null) { 437 if (directLocals[local] == null) {
(...skipping 21 matching lines...) Expand all
415 // accessed as direct local. Inside the nested closure the box is 459 // accessed as direct local. Inside the nested closure the box is
416 // accessed through a closure-field. 460 // accessed through a closure-field.
417 // Calling [readLocal] makes sure we generate the correct code to get 461 // Calling [readLocal] makes sure we generate the correct code to get
418 // the box. 462 // the box.
419 HInstruction box = readLocal(redirect.box); 463 HInstruction box = readLocal(redirect.box);
420 HInstruction lookup = new HFieldGet( 464 HInstruction lookup = new HFieldGet(
421 redirect, box, builder.getTypeOfCapturedVariable(redirect)); 465 redirect, box, builder.getTypeOfCapturedVariable(redirect));
422 builder.add(lookup); 466 builder.add(lookup);
423 return lookup; 467 return lookup;
424 } else { 468 } else {
425 assert(isUsedInTry(local)); 469 assert(isUsedInTryOrGenerator(local));
426 HLocalValue localValue = getLocal(local); 470 HLocalValue localValue = getLocal(local);
427 HInstruction instruction = new HLocalGet( 471 HInstruction instruction = new HLocalGet(
428 local, localValue, builder.backend.dynamicType); 472 local, localValue, builder.backend.dynamicType);
429 builder.add(instruction); 473 builder.add(instruction);
430 return instruction; 474 return instruction;
431 } 475 }
432 } 476 }
433 477
434 HInstruction readThis() { 478 HInstruction readThis() {
435 HInstruction res = readLocal(closureData.thisLocal); 479 HInstruction res = readLocal(closureData.thisLocal);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
471 directLocals[local] = value; 515 directLocals[local] = value;
472 } else if (isBoxed(local)) { 516 } else if (isBoxed(local)) {
473 BoxFieldElement redirect = redirectionMapping[local]; 517 BoxFieldElement redirect = redirectionMapping[local];
474 // The box itself could be captured, or be local. A local variable that 518 // The box itself could be captured, or be local. A local variable that
475 // is captured will be boxed, but the box itself will be a local. 519 // is captured will be boxed, but the box itself will be a local.
476 // Inside the closure the box is stored in a closure-field and cannot 520 // Inside the closure the box is stored in a closure-field and cannot
477 // be accessed directly. 521 // be accessed directly.
478 HInstruction box = readLocal(redirect.box); 522 HInstruction box = readLocal(redirect.box);
479 builder.add(new HFieldSet(redirect, box, value)); 523 builder.add(new HFieldSet(redirect, box, value));
480 } else { 524 } else {
481 assert(isUsedInTry(local)); 525 assert(isUsedInTryOrGenerator(local));
482 HLocalValue localValue = getLocal(local); 526 HLocalValue localValue = getLocal(local);
483 builder.add(new HLocalSet(local, localValue, value)); 527 builder.add(new HLocalSet(local, localValue, value));
484 } 528 }
485 } 529 }
486 530
487 /** 531 /**
488 * This function, startLoop, must be called before visiting any children of 532 * This function, startLoop, must be called before visiting any children of
489 * the loop. In particular it needs to be called before executing the 533 * the loop. In particular it needs to be called before executing the
490 * initializers. 534 * initializers.
491 * 535 *
(...skipping 4665 matching lines...) Expand 10 before | Expand all | Expand 10 after
5157 visitThrow(ast.Throw node) { 5201 visitThrow(ast.Throw node) {
5158 visitThrowExpression(node.expression); 5202 visitThrowExpression(node.expression);
5159 if (isReachable) { 5203 if (isReachable) {
5160 handleInTryStatement(); 5204 handleInTryStatement();
5161 push(new HThrowExpression(pop())); 5205 push(new HThrowExpression(pop()));
5162 isReachable = false; 5206 isReachable = false;
5163 } 5207 }
5164 } 5208 }
5165 5209
5166 visitYield(ast.Yield node) { 5210 visitYield(ast.Yield node) {
5167 // Dummy implementation.
5168 visit(node.expression); 5211 visit(node.expression);
5169 pop(); 5212 HInstruction yielded = pop();
5213 add(new HYield(yielded, node.hasStar));
5170 } 5214 }
5171 5215
5172 visitAwait(ast.Await node) { 5216 visitAwait(ast.Await node) {
5173 // Dummy implementation.
5174 visit(node.expression); 5217 visit(node.expression);
5218 HInstruction awaited = pop();
5219 // TODO(herhut): Improve this type.
5220 push(new HAwait(awaited, new TypeMask.subclass(compiler.objectClass,
5221 compiler.world)));
5175 } 5222 }
5176 5223
5177 visitTypeAnnotation(ast.TypeAnnotation node) { 5224 visitTypeAnnotation(ast.TypeAnnotation node) {
5178 compiler.internalError(node, 5225 compiler.internalError(node,
5179 'Visiting type annotation in SSA builder.'); 5226 'Visiting type annotation in SSA builder.');
5180 } 5227 }
5181 5228
5182 visitVariableDefinitions(ast.VariableDefinitions node) { 5229 visitVariableDefinitions(ast.VariableDefinitions node) {
5183 assert(isReachable); 5230 assert(isReachable);
5184 for (Link<ast.Node> link = node.definitions.nodes; 5231 for (Link<ast.Node> link = node.definitions.nodes;
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
5308 return new NullJumpHandler(compiler); 5355 return new NullJumpHandler(compiler);
5309 } 5356 }
5310 if (isLoopJump && node is ast.SwitchStatement) { 5357 if (isLoopJump && node is ast.SwitchStatement) {
5311 // Create a special jump handler for loops created for switch statements 5358 // Create a special jump handler for loops created for switch statements
5312 // with continue statements. 5359 // with continue statements.
5313 return new SwitchCaseJumpHandler(this, element, node); 5360 return new SwitchCaseJumpHandler(this, element, node);
5314 } 5361 }
5315 return new JumpHandler(this, element); 5362 return new JumpHandler(this, element);
5316 } 5363 }
5317 5364
5365 buildAsyncForIn(ast.ForIn node) {
5366 assert(node.isAsync);
5367 // The async-for is implemented with a StreamIterator.
5368 HInstruction streamIterator;
5369
5370 visit(node.expression);
5371 HInstruction expression = pop();
5372 pushInvokeStatic(node,
5373 backend.getStreamIteratorConstructor(),
5374 [expression, graph.addConstantNull(compiler)]);
5375 streamIterator = pop();
5376
5377 void buildInitializer() {}
5378
5379 HInstruction buildCondition() {
5380 Selector selector = elements.getMoveNextSelector(node);
5381 pushInvokeDynamic(node, selector, [streamIterator]);
5382 HInstruction future = pop();
5383 push(new HAwait(future, new TypeMask.subclass(compiler.objectClass,
5384 compiler.world)));
5385 return popBoolified();
5386 }
5387 void buildBody() {
5388 Selector call = elements.getCurrentSelector(node);
5389 pushInvokeDynamic(node, call, [streamIterator]);
5390
5391 ast.Node identifier = node.declaredIdentifier;
5392 Element variable = elements.getForInVariable(node);
5393 Selector selector = elements.getSelector(identifier);
5394
5395 HInstruction value = pop();
5396 if (identifier.asSend() != null
5397 && Elements.isInstanceSend(identifier, elements)) {
5398 HInstruction receiver = generateInstanceSendReceiver(identifier);
5399 assert(receiver != null);
5400 generateInstanceSetterWithCompiledReceiver(
5401 null,
5402 receiver,
5403 value,
5404 selector: selector,
5405 location: identifier);
5406 } else {
5407 generateNonInstanceSetter(
5408 null, variable, value, location: identifier);
5409 }
5410 pop(); // Pop the value pushed by the setter call.
5411
5412 visit(node.body);
5413 }
5414
5415 void buildUpdate() {};
5416
5417 buildProtectedByFinally(() {
5418 handleLoop(node,
5419 buildInitializer,
5420 buildCondition,
5421 buildUpdate,
5422 buildBody);
5423 }, () {
5424 pushInvokeDynamic(node, new Selector.call("cancel", null, 0),
5425 [streamIterator]);
5426 push(new HAwait(pop(), new TypeMask.subclass(compiler.objectClass,
5427 compiler.world)));
5428 pop();
5429 });
5430 }
5431
5318 visitForIn(ast.ForIn node) { 5432 visitForIn(ast.ForIn node) {
5433 if (node.isAsync) {
5434 return buildAsyncForIn(node);
5435 }
5436
5319 // Generate a structure equivalent to: 5437 // Generate a structure equivalent to:
5320 // Iterator<E> $iter = <iterable>.iterator; 5438 // Iterator<E> $iter = <iterable>.iterator;
5321 // while ($iter.moveNext()) { 5439 // while ($iter.moveNext()) {
5322 // E <declaredIdentifier> = $iter.current; 5440 // E <declaredIdentifier> = $iter.current;
5323 // <body> 5441 // <body>
5324 // } 5442 // }
5325 5443
5326 // The iterator is shared between initializer, condition and body. 5444 // The iterator is shared between initializer, condition and body.
5327 HInstruction iterator; 5445 HInstruction iterator;
5328 void buildInitializer() { 5446 void buildInitializer() {
(...skipping 515 matching lines...) Expand 10 before | Expand all | Expand 10 after
5844 } 5962 }
5845 5963
5846 visitSwitchCase(ast.SwitchCase node) { 5964 visitSwitchCase(ast.SwitchCase node) {
5847 compiler.internalError(node, 'SsaFromAstMixin.visitSwitchCase.'); 5965 compiler.internalError(node, 'SsaFromAstMixin.visitSwitchCase.');
5848 } 5966 }
5849 5967
5850 visitCaseMatch(ast.CaseMatch node) { 5968 visitCaseMatch(ast.CaseMatch node) {
5851 compiler.internalError(node, 'SsaFromAstMixin.visitCaseMatch.'); 5969 compiler.internalError(node, 'SsaFromAstMixin.visitCaseMatch.');
5852 } 5970 }
5853 5971
5972 /// Calls [buildTry] inside a synthetic try block with [buildFinally] in the
5973 /// finally block.
5974 void buildProtectedByFinally(void buildTry(), void buildFinally()) {
5975 // Save the current locals. The finally block must not reuse the existing
5976 // locals handler. None of the variables
5977 // that have been defined in the body-block will be used, but for
5978 // loops we will add (unnecessary) phis that will reference the body
5979 // variables. This makes it look as if the variables were used
5980 // in a non-dominated block.
5981 LocalsHandler savedLocals = new LocalsHandler.from(localsHandler);
5982 HBasicBlock enterBlock = openNewBlock();
5983 HTry tryInstruction = new HTry();
5984 close(tryInstruction);
5985 bool oldInTryStatement = inTryStatement;
5986 inTryStatement = true;
5987
5988 HBasicBlock startTryBlock;
5989 HBasicBlock endTryBlock;
5990 HBasicBlock startFinallyBlock;
5991 HBasicBlock endFinallyBlock;
5992
5993 startTryBlock = graph.addNewBlock();
5994 open(startTryBlock);
5995 buildTry();
5996 // We use a [HExitTry] instead of a [HGoto] for the try block
5997 // because it will have two successors: the join block, and
5998 // the finally block.
5999 if (!isAborted()) endTryBlock = close(new HExitTry());
6000 SubGraph bodyGraph = new SubGraph(startTryBlock, lastOpenedBlock);
6001
6002 SubGraph finallyGraph = null;
6003
6004 localsHandler = new LocalsHandler.from(savedLocals);
6005 startFinallyBlock = graph.addNewBlock();
6006 open(startFinallyBlock);
6007 buildFinally();
6008 if (!isAborted()) endFinallyBlock = close(new HGoto());
6009 tryInstruction.finallyBlock = startFinallyBlock;
6010 finallyGraph = new SubGraph(startFinallyBlock, lastOpenedBlock);
6011
6012 HBasicBlock exitBlock = graph.addNewBlock();
6013
6014 void addExitTrySuccessor(HBasicBlock successor) {
6015 // Iterate over all blocks created inside this try/catch, and
6016 // attach successor information to blocks that end with
6017 // [HExitTry].
6018 for (int i = startTryBlock.id; i < successor.id; i++) {
6019 HBasicBlock block = graph.blocks[i];
6020 var last = block.last;
6021 if (last is HExitTry) {
6022 block.addSuccessor(successor);
6023 }
6024 }
6025 }
6026
6027 // Setup all successors. The entry block that contains the [HTry]
6028 // has 1) the body 2) the finally, and 4) the exit
6029 // blocks as successors.
6030 enterBlock.addSuccessor(startTryBlock);
6031 enterBlock.addSuccessor(startFinallyBlock);
6032 enterBlock.addSuccessor(exitBlock);
6033
6034 // The body has the finally block as successor.
6035 if (endTryBlock != null) {
6036 endTryBlock.addSuccessor(startFinallyBlock);
6037 endTryBlock.addSuccessor(exitBlock);
6038 }
6039
6040 // The finally block has the exit block as successor.
6041 endFinallyBlock.addSuccessor(exitBlock);
6042
6043 // If a block inside try/catch aborts (eg with a return statement),
6044 // we explicitely mark this block a predecessor of the catch
6045 // block and the finally block.
6046 addExitTrySuccessor(startFinallyBlock);
6047
6048 // Use the locals handler not altered by the catch and finally
6049 // blocks.
6050 localsHandler = savedLocals;
6051 open(exitBlock);
6052 enterBlock.setBlockFlow(
6053 new HTryBlockInformation(
6054 wrapStatementGraph(bodyGraph),
6055 null,
6056 null, // No catchGraph
6057 wrapStatementGraph(finallyGraph)),
6058 exitBlock);
6059 inTryStatement = oldInTryStatement;
6060 }
6061
5854 visitTryStatement(ast.TryStatement node) { 6062 visitTryStatement(ast.TryStatement node) {
5855 // Save the current locals. The catch block and the finally block 6063 // Save the current locals. The catch block and the finally block
5856 // must not reuse the existing locals handler. None of the variables 6064 // must not reuse the existing locals handler. None of the variables
5857 // that have been defined in the body-block will be used, but for 6065 // that have been defined in the body-block will be used, but for
5858 // loops we will add (unnecessary) phis that will reference the body 6066 // loops we will add (unnecessary) phis that will reference the body
5859 // variables. This makes it look as if the variables were used 6067 // variables. This makes it look as if the variables were used
5860 // in a non-dominated block. 6068 // in a non-dominated block.
5861 LocalsHandler savedLocals = new LocalsHandler.from(localsHandler); 6069 LocalsHandler savedLocals = new LocalsHandler.from(localsHandler);
5862 HBasicBlock enterBlock = openNewBlock(); 6070 HBasicBlock enterBlock = openNewBlock();
5863 HTry tryInstruction = new HTry(); 6071 HTry tryInstruction = new HTry();
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
6038 enterBlock.setBlockFlow( 6246 enterBlock.setBlockFlow(
6039 new HTryBlockInformation( 6247 new HTryBlockInformation(
6040 wrapStatementGraph(bodyGraph), 6248 wrapStatementGraph(bodyGraph),
6041 exception, 6249 exception,
6042 wrapStatementGraph(catchGraph), 6250 wrapStatementGraph(catchGraph),
6043 wrapStatementGraph(finallyGraph)), 6251 wrapStatementGraph(finallyGraph)),
6044 exitBlock); 6252 exitBlock);
6045 inTryStatement = oldInTryStatement; 6253 inTryStatement = oldInTryStatement;
6046 } 6254 }
6047 6255
6256
6048 visitCatchBlock(ast.CatchBlock node) { 6257 visitCatchBlock(ast.CatchBlock node) {
6049 visit(node.block); 6258 visit(node.block);
6050 } 6259 }
6051 6260
6052 visitTypedef(ast.Typedef node) { 6261 visitTypedef(ast.Typedef node) {
6053 compiler.unimplemented(node, 'SsaFromAstMixin.visitTypedef.'); 6262 compiler.unimplemented(node, 'SsaFromAstMixin.visitTypedef.');
6054 } 6263 }
6055 6264
6056 visitTypeVariable(ast.TypeVariable node) { 6265 visitTypeVariable(ast.TypeVariable node) {
6057 compiler.internalError(node, 'SsaFromAstMixin.visitTypeVariable.'); 6266 compiler.internalError(node, 'SsaFromAstMixin.visitTypeVariable.');
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
6213 InlineWeeder(this.maxInliningNodes, 6422 InlineWeeder(this.maxInliningNodes,
6214 this.useMaxInliningNodes, 6423 this.useMaxInliningNodes,
6215 this.allowLoops); 6424 this.allowLoops);
6216 6425
6217 static bool canBeInlined(ast.FunctionExpression functionExpression, 6426 static bool canBeInlined(ast.FunctionExpression functionExpression,
6218 int maxInliningNodes, 6427 int maxInliningNodes,
6219 bool useMaxInliningNodes, 6428 bool useMaxInliningNodes,
6220 {bool allowLoops: false}) { 6429 {bool allowLoops: false}) {
6221 InlineWeeder weeder = 6430 InlineWeeder weeder =
6222 new InlineWeeder(maxInliningNodes, useMaxInliningNodes, allowLoops); 6431 new InlineWeeder(maxInliningNodes, useMaxInliningNodes, allowLoops);
6432 if (functionExpression.asyncModifier != null) return false;
herhut 2015/02/04 09:42:49 Nit: Why not move one line up? I would prefer to
sigurdm 2015/02/04 10:11:44 Done.
6223 weeder.visit(functionExpression.initializers); 6433 weeder.visit(functionExpression.initializers);
6224 weeder.visit(functionExpression.body); 6434 weeder.visit(functionExpression.body);
6225 return !weeder.tooDifficult; 6435 return !weeder.tooDifficult;
6226 } 6436 }
6227 6437
6228 bool registerNode() { 6438 bool registerNode() {
6229 if (!useMaxInliningNodes) return true; 6439 if (!useMaxInliningNodes) return true;
6230 if (nodeCount++ > maxInliningNodes) { 6440 if (nodeCount++ > maxInliningNodes) {
6231 tooDifficult = true; 6441 tooDifficult = true;
6232 return false; 6442 return false;
(...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after
6670 if (unaliased is TypedefType) throw 'unable to unalias $type'; 6880 if (unaliased is TypedefType) throw 'unable to unalias $type';
6671 unaliased.accept(this, builder); 6881 unaliased.accept(this, builder);
6672 } 6882 }
6673 6883
6674 void visitDynamicType(DynamicType type, SsaBuilder builder) { 6884 void visitDynamicType(DynamicType type, SsaBuilder builder) {
6675 JavaScriptBackend backend = builder.compiler.backend; 6885 JavaScriptBackend backend = builder.compiler.backend;
6676 ClassElement cls = backend.findHelper('DynamicRuntimeType'); 6886 ClassElement cls = backend.findHelper('DynamicRuntimeType');
6677 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld))); 6887 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld)));
6678 } 6888 }
6679 } 6889 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698