Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 library dart2js.ir_builder; | 5 library dart2js.ir_builder; |
| 6 | 6 |
| 7 import 'cps_ir_nodes.dart' as ir; | 7 import 'cps_ir_nodes.dart' as ir; |
| 8 import '../elements/elements.dart'; | 8 import '../elements/elements.dart'; |
| 9 import '../dart2jslib.dart'; | 9 import '../dart2jslib.dart'; |
| 10 import '../dart_types.dart'; | 10 import '../dart_types.dart'; |
| (...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 343 return buildPrimConst( | 343 return buildPrimConst( |
| 344 constantSystem.createString(new ast.DartString.literal(value))); | 344 constantSystem.createString(new ast.DartString.literal(value))); |
| 345 } | 345 } |
| 346 | 346 |
| 347 /// Create a get access of [local]. | 347 /// Create a get access of [local]. |
| 348 ir.Primitive buildGetLocal(Element local) { | 348 ir.Primitive buildGetLocal(Element local) { |
| 349 assert(isOpen); | 349 assert(isOpen); |
| 350 return environment.lookup(local); | 350 return environment.lookup(local); |
| 351 } | 351 } |
| 352 | 352 |
| 353 /// Create a get access of the static [element]. | |
| 354 ir.Primitive buildGetStatic(Element element, Selector selector) { | |
| 355 assert(isOpen); | |
| 356 assert(selector.isGetter); | |
| 357 return continueWithExpression( | |
| 358 (k) => new ir.InvokeStatic(element, selector, k, [])); | |
| 359 } | |
| 360 | |
| 353 /** | 361 /** |
| 354 * Add an explicit `return null` for functions that don't have a return | 362 * Add an explicit `return null` for functions that don't have a return |
| 355 * statement on each branch. This includes functions with an empty body, | 363 * statement on each branch. This includes functions with an empty body, |
| 356 * such as `foo(){ }`. | 364 * such as `foo(){ }`. |
| 357 */ | 365 */ |
| 358 void ensureReturn() { | 366 void ensureReturn() { |
| 359 if (!isOpen) return; | 367 if (!isOpen) return; |
| 360 ir.Constant constant = makePrimConst(constantSystem.createNull()); | 368 ir.Constant constant = makePrimConst(constantSystem.createNull()); |
| 361 add(new ir.LetPrim(constant)); | 369 add(new ir.LetPrim(constant)); |
| 362 add(new ir.InvokeContinuation(returnContinuation, [constant])); | 370 add(new ir.InvokeContinuation(returnContinuation, [constant])); |
| (...skipping 1068 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1431 LocalElement local = element; | 1439 LocalElement local = element; |
| 1432 result = new ir.GetClosureVariable(local); | 1440 result = new ir.GetClosureVariable(local); |
| 1433 add(new ir.LetPrim(result)); | 1441 add(new ir.LetPrim(result)); |
| 1434 } else if (Elements.isLocal(element)) { | 1442 } else if (Elements.isLocal(element)) { |
| 1435 // Reference to local variable | 1443 // Reference to local variable |
| 1436 result = buildGetLocal(element); | 1444 result = buildGetLocal(element); |
| 1437 } else if (element == null || | 1445 } else if (element == null || |
| 1438 Elements.isInstanceField(element) || | 1446 Elements.isInstanceField(element) || |
| 1439 Elements.isInstanceMethod(element) || | 1447 Elements.isInstanceMethod(element) || |
| 1440 selector.isIndex || | 1448 selector.isIndex || |
| 1441 // TODO(johnniwinther): clean up semantics of resultion. | 1449 // TODO(johnniwinther): clean up semantics of resolution. |
| 1442 node.isSuperCall) { | 1450 node.isSuperCall) { |
| 1443 // Dynamic dispatch to a getter. Sometimes resolution will suggest a | 1451 // Dynamic dispatch to a getter. Sometimes resolution will suggest a |
| 1444 // target element, but in these cases we must still emit a dynamic | 1452 // target element, but in these cases we must still emit a dynamic |
| 1445 // dispatch. The target element may be an instance method in case we are | 1453 // dispatch. The target element may be an instance method in case we are |
| 1446 // converting a method to a function object. | 1454 // converting a method to a function object. |
| 1447 | 1455 |
| 1448 receiver = visitReceiver(node.receiver); | 1456 receiver = visitReceiver(node.receiver); |
| 1449 List<ir.Primitive> arguments = new List<ir.Primitive>(); | 1457 List<ir.Primitive> arguments = new List<ir.Primitive>(); |
| 1450 if (selector.isIndex) { | 1458 if (selector.isIndex) { |
| 1451 index = visit(node.arguments.head); | 1459 index = visit(node.arguments.head); |
| 1452 arguments.add(index); | 1460 arguments.add(index); |
| 1453 } | 1461 } |
| 1454 | 1462 |
| 1455 assert(selector.kind == SelectorKind.GETTER || | 1463 assert(selector.kind == SelectorKind.GETTER || |
| 1456 selector.kind == SelectorKind.INDEX); | 1464 selector.kind == SelectorKind.INDEX); |
| 1457 result = continueWithExpression( | 1465 result = continueWithExpression( |
| 1458 (k) => createDynamicInvoke(node, selector, receiver, k, arguments)); | 1466 (k) => createDynamicInvoke(node, selector, receiver, k, arguments)); |
| 1459 } else if (element.isField || element.isGetter || element.isErroneous || | 1467 } else if (element.isField || element.isGetter || element.isErroneous || |
| 1460 element.isSetter) { | 1468 element.isSetter) { |
| 1461 // Access to a static field or getter (non-static case handled above). | 1469 // Access to a static field or getter (non-static case handled above). |
| 1462 // Even if there is only a setter, we compile as if it was a getter, | 1470 // Even if there is only a setter, we compile as if it was a getter, |
| 1463 // so the vm can fail at runtime. | 1471 // so the vm can fail at runtime. |
| 1464 assert(selector.kind == SelectorKind.GETTER || | 1472 assert(selector.kind == SelectorKind.GETTER || |
| 1465 selector.kind == SelectorKind.SETTER); | 1473 selector.kind == SelectorKind.SETTER); |
|
sigurdm
2014/09/29 08:59:42
Not your code, but it seems we should here only ch
Johnni Winther
2014/09/29 13:07:25
Added a TODO.
| |
| 1466 result = continueWithExpression( | 1474 result = buildGetStatic(element, selector); |
| 1467 (k) => new ir.InvokeStatic(element, selector, k, [])); | |
| 1468 } else if (Elements.isStaticOrTopLevelFunction(element)) { | 1475 } else if (Elements.isStaticOrTopLevelFunction(element)) { |
| 1469 // Convert a top-level or static function to a function object. | 1476 // Convert a top-level or static function to a function object. |
| 1470 result = translateConstant(node); | 1477 result = translateConstant(node); |
| 1471 } else { | 1478 } else { |
| 1472 throw "Unexpected SendSet getter: $node, $element"; | 1479 throw "Unexpected SendSet getter: $node, $element"; |
| 1473 } | 1480 } |
| 1474 return new _GetterElements( | 1481 return new _GetterElements( |
| 1475 result: result,index: index, receiver: receiver); | 1482 result: result,index: index, receiver: receiver); |
| 1476 } | 1483 } |
| 1477 | 1484 |
| (...skipping 625 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2103 } | 2110 } |
| 2104 | 2111 |
| 2105 visitFunctionExpression(ast.FunctionExpression node) { | 2112 visitFunctionExpression(ast.FunctionExpression node) { |
| 2106 FunctionElement oldFunction = currentFunction; | 2113 FunctionElement oldFunction = currentFunction; |
| 2107 currentFunction = elements[node]; | 2114 currentFunction = elements[node]; |
| 2108 visit(node.body); | 2115 visit(node.body); |
| 2109 currentFunction = oldFunction; | 2116 currentFunction = oldFunction; |
| 2110 } | 2117 } |
| 2111 | 2118 |
| 2112 } | 2119 } |
| OLD | NEW |