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 'ir_nodes.dart' as ir; | 7 import '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 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
229 * such as [:foo(){ }:]. | 229 * such as [:foo(){ }:]. |
230 */ | 230 */ |
231 void ensureReturn(ast.FunctionExpression node) { | 231 void ensureReturn(ast.FunctionExpression node) { |
232 if (!isOpen) return; | 232 if (!isOpen) return; |
233 ir.Constant constant = new ir.Constant(constantSystem.createNull()); | 233 ir.Constant constant = new ir.Constant(constantSystem.createNull()); |
234 add(new ir.LetPrim(constant)); | 234 add(new ir.LetPrim(constant)); |
235 add(new ir.InvokeContinuation(returnContinuation, constant)); | 235 add(new ir.InvokeContinuation(returnContinuation, constant)); |
236 current = null; | 236 current = null; |
237 } | 237 } |
238 | 238 |
| 239 // Build(EmptyStatement, C) = C |
239 ir.Definition visitEmptyStatement(ast.EmptyStatement node) { | 240 ir.Definition visitEmptyStatement(ast.EmptyStatement node) { |
240 assert(isOpen); | 241 assert(isOpen); |
241 return null; | 242 return null; |
242 } | 243 } |
243 | 244 |
| 245 // Build(Block(stamements), C) = C' |
| 246 // where C' = statements.fold(Build, C) |
244 ir.Definition visitBlock(ast.Block node) { | 247 ir.Definition visitBlock(ast.Block node) { |
245 assert(isOpen); | 248 assert(isOpen); |
246 for (var n in node.statements.nodes) { | 249 for (var n in node.statements.nodes) { |
247 n.accept(this); | 250 n.accept(this); |
248 if (!isOpen) return null; | 251 if (!isOpen) return null; |
249 } | 252 } |
250 return null; | 253 return null; |
251 } | 254 } |
252 | 255 |
253 // Build(Return) = let val x = null in InvokeContinuation(return, x) | 256 // Build(ExpressionStatement(e), C) = C' |
254 // Build(Return(e)) = C[InvokeContinuation(return, x)] | 257 // where (C', _) = Build(e, C) |
255 // where (C, x) = Build(e) | 258 ir.Definition visitExpressionStatement(ast.ExpressionStatement node) { |
| 259 assert(isOpen); |
| 260 node.expression.accept(this); |
| 261 return null; |
| 262 } |
| 263 |
| 264 // Build(Return(e), C) = C'[InvokeContinuation(return, x)] |
| 265 // where (C', x) = Build(e, C) |
| 266 // |
| 267 // Return without a subexpression is translated as if it were return null. |
256 ir.Definition visitReturn(ast.Return node) { | 268 ir.Definition visitReturn(ast.Return node) { |
257 assert(isOpen); | 269 assert(isOpen); |
258 // TODO(lry): support native returns. | 270 // TODO(lry): support native returns. |
259 if (node.beginToken.value == 'native') return giveup(); | 271 if (node.beginToken.value == 'native') return giveup(); |
260 ir.Definition value; | 272 ir.Definition value; |
261 if (node.expression == null) { | 273 if (node.expression == null) { |
262 value = new ir.Constant(constantSystem.createNull()); | 274 value = new ir.Constant(constantSystem.createNull()); |
263 add(new ir.LetPrim(value)); | 275 add(new ir.LetPrim(value)); |
264 } else { | 276 } else { |
265 value = node.expression.accept(this); | 277 value = node.expression.accept(this); |
266 if (!isOpen) return null; | 278 if (!isOpen) return null; |
267 } | 279 } |
268 add(new ir.InvokeContinuation(returnContinuation, value)); | 280 add(new ir.InvokeContinuation(returnContinuation, value)); |
269 current = null; | 281 current = null; |
270 return null; | 282 return null; |
271 } | 283 } |
272 | 284 |
273 // For all simple literals: | 285 // For all simple literals: |
274 // Build(Literal(c)) = (let val x = Constant(c) in [], x) | 286 // Build(Literal(c), C) = C[let val x = Constant(c) in [], x] |
275 ir.Definition visitLiteralBool(ast.LiteralBool node) { | 287 ir.Definition visitLiteralBool(ast.LiteralBool node) { |
276 assert(isOpen); | 288 assert(isOpen); |
277 ir.Constant constant = | 289 ir.Constant constant = |
278 new ir.Constant(constantSystem.createBool(node.value)); | 290 new ir.Constant(constantSystem.createBool(node.value)); |
279 add(new ir.LetPrim(constant)); | 291 add(new ir.LetPrim(constant)); |
280 return constant; | 292 return constant; |
281 } | 293 } |
282 | 294 |
283 ir.Definition visitLiteralDouble(ast.LiteralDouble node) { | 295 ir.Definition visitLiteralDouble(ast.LiteralDouble node) { |
284 assert(isOpen); | 296 assert(isOpen); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
325 } | 337 } |
326 | 338 |
327 ir.Definition visitGetterSend(ast.Send node) { | 339 ir.Definition visitGetterSend(ast.Send node) { |
328 return giveup(); | 340 return giveup(); |
329 } | 341 } |
330 | 342 |
331 ir.Definition visitOperatorSend(ast.Send node) { | 343 ir.Definition visitOperatorSend(ast.Send node) { |
332 return giveup(); | 344 return giveup(); |
333 } | 345 } |
334 | 346 |
335 // Build(StaticSend(f, a...)) = C[InvokeStatic(f, x...)] | 347 // Build(StaticSend(f, arguments), C) = C[C'[InvokeStatic(f, xs)]] |
336 // where (C, x...) = BuildList(a...) | 348 // where (C', xs) = arguments.fold(Build, C) |
337 ir.Definition visitStaticSend(ast.Send node) { | 349 ir.Definition visitStaticSend(ast.Send node) { |
338 assert(isOpen); | 350 assert(isOpen); |
339 Element element = elements[node]; | 351 Element element = elements[node]; |
340 // TODO(lry): support static fields. (separate IR instruction?) | 352 // TODO(lry): support static fields. (separate IR instruction?) |
341 if (element.isField() || element.isGetter()) return giveup(); | 353 if (element.isField() || element.isGetter()) return giveup(); |
| 354 // TODO(kmillikin): support static setters. |
| 355 if (element.isSetter()) return giveup(); |
342 // TODO(lry): support constructors / factory calls. | 356 // TODO(lry): support constructors / factory calls. |
343 if (element.isConstructor()) return giveup(); | 357 if (element.isConstructor()) return giveup(); |
344 // TODO(lry): support foreign functions. | 358 // TODO(lry): support foreign functions. |
345 if (element.isForeign(compiler)) return giveup(); | 359 if (element.isForeign(compiler)) return giveup(); |
346 // TODO(lry): for elements that could not be resolved emit code to throw a | 360 // TODO(lry): for elements that could not be resolved emit code to throw a |
347 // [NoSuchMethodError]. | 361 // [NoSuchMethodError]. |
348 if (element.isErroneous()) return giveup(); | 362 if (element.isErroneous()) return giveup(); |
349 // TODO(lry): generate IR for object identicality. | 363 // TODO(lry): generate IR for object identicality. |
350 if (element == compiler.identicalFunction) giveup(); | 364 if (element == compiler.identicalFunction) giveup(); |
351 | 365 |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
406 // Verify that types are ones that can be reconstructed by the type emitter. | 420 // Verify that types are ones that can be reconstructed by the type emitter. |
407 class SupportedTypeVerifier extends DartTypeVisitor<bool, Null> { | 421 class SupportedTypeVerifier extends DartTypeVisitor<bool, Null> { |
408 bool visitType(DartType type, Null _) => false; | 422 bool visitType(DartType type, Null _) => false; |
409 | 423 |
410 bool visitVoidType(VoidType type, Null _) => true; | 424 bool visitVoidType(VoidType type, Null _) => true; |
411 | 425 |
412 // Currently, InterfaceType and TypedefType are supported so long as they | 426 // Currently, InterfaceType and TypedefType are supported so long as they |
413 // do not have type parameters. They are subclasses of GenericType. | 427 // do not have type parameters. They are subclasses of GenericType. |
414 bool visitGenericType(GenericType type, Null _) => !type.isGeneric; | 428 bool visitGenericType(GenericType type, Null _) => !type.isGeneric; |
415 } | 429 } |
OLD | NEW |