| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 code_generator; | 5 library code_generator; |
| 6 | 6 |
| 7 import 'glue.dart'; | 7 import 'glue.dart'; |
| 8 | 8 |
| 9 import '../../tree_ir/tree_ir_nodes.dart' as tree_ir; | 9 import '../../tree_ir/tree_ir_nodes.dart' as tree_ir; |
| 10 import '../../js/js.dart' as js; | 10 import '../../js/js.dart' as js; |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 88 js.Expression result = node.accept(this); | 88 js.Expression result = node.accept(this); |
| 89 if (result == null) { | 89 if (result == null) { |
| 90 glue.reportInternalError('$node did not produce code.'); | 90 glue.reportInternalError('$node did not produce code.'); |
| 91 } | 91 } |
| 92 return result; | 92 return result; |
| 93 } | 93 } |
| 94 | 94 |
| 95 /// Generates a name for the given variable. First trying with the name of | 95 /// Generates a name for the given variable. First trying with the name of |
| 96 /// the [Variable.element] if it is non-null. | 96 /// the [Variable.element] if it is non-null. |
| 97 String getVariableName(tree_ir.Variable variable) { | 97 String getVariableName(tree_ir.Variable variable) { |
| 98 // TODO(sigurdm): Handle case where the variable belongs to an enclosing | 98 // Functions are not nested in the JS backend. |
| 99 // function. | 99 assert(variable.host == currentFunction); |
| 100 if (variable.host != currentFunction) giveup(variable); | |
| 101 | 100 |
| 102 // Get the name if we already have one. | 101 // Get the name if we already have one. |
| 103 String name = variableNames[variable]; | 102 String name = variableNames[variable]; |
| 104 if (name != null) { | 103 if (name != null) { |
| 105 return name; | 104 return name; |
| 106 } | 105 } |
| 107 | 106 |
| 108 // Synthesize a variable name that isn't used elsewhere. | 107 // Synthesize a variable name that isn't used elsewhere. |
| 109 // The [usedVariableNames] set is shared between nested emitters, | 108 // The [usedVariableNames] set is shared between nested emitters, |
| 110 // so this also prevents clash with variables in an enclosing/inner scope. | 109 // so this also prevents clash with variables in an enclosing/inner scope. |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 169 js.Expression buildConstant(ConstantValue constant) { | 168 js.Expression buildConstant(ConstantValue constant) { |
| 170 registry.registerCompileTimeConstant(constant); | 169 registry.registerCompileTimeConstant(constant); |
| 171 return glue.constantReference(constant); | 170 return glue.constantReference(constant); |
| 172 } | 171 } |
| 173 | 172 |
| 174 @override | 173 @override |
| 175 js.Expression visitConstant(tree_ir.Constant node) { | 174 js.Expression visitConstant(tree_ir.Constant node) { |
| 176 return buildConstant(node.expression.value); | 175 return buildConstant(node.expression.value); |
| 177 } | 176 } |
| 178 | 177 |
| 179 @override | |
| 180 js.Expression visitFunctionExpression(tree_ir.FunctionExpression node) { | |
| 181 return giveup(node); | |
| 182 // TODO: implement visitFunctionExpression | |
| 183 } | |
| 184 | |
| 185 js.Expression compileConstant(ParameterElement parameter) { | 178 js.Expression compileConstant(ParameterElement parameter) { |
| 186 return buildConstant(glue.getConstantForVariable(parameter).value); | 179 return buildConstant(glue.getConstantForVariable(parameter).value); |
| 187 } | 180 } |
| 188 | 181 |
| 189 // TODO(karlklose): get rid of the selector argument. | 182 // TODO(karlklose): get rid of the selector argument. |
| 190 js.Expression buildStaticInvoke(Selector selector, | 183 js.Expression buildStaticInvoke(Selector selector, |
| 191 Element target, | 184 Element target, |
| 192 List<js.Expression> arguments) { | 185 List<js.Expression> arguments) { |
| 193 registry.registerStaticInvocation(target.declaration); | 186 registry.registerStaticInvocation(target.declaration); |
| 194 if (target == glue.getInterceptorMethod) { | 187 if (target == glue.getInterceptorMethod) { |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 335 } | 328 } |
| 336 | 329 |
| 337 @override | 330 @override |
| 338 js.Expression visitReifyTypeVar(tree_ir.ReifyTypeVar node) { | 331 js.Expression visitReifyTypeVar(tree_ir.ReifyTypeVar node) { |
| 339 return giveup(node); | 332 return giveup(node); |
| 340 // TODO: implement visitReifyTypeVar | 333 // TODO: implement visitReifyTypeVar |
| 341 } | 334 } |
| 342 | 335 |
| 343 @override | 336 @override |
| 344 js.Expression visitThis(tree_ir.This node) { | 337 js.Expression visitThis(tree_ir.This node) { |
| 345 // TODO(sigurdm): Inside a js closure this will not work. | |
| 346 return new js.This(); | 338 return new js.This(); |
| 347 } | 339 } |
| 348 | 340 |
| 349 @override | 341 @override |
| 350 js.Expression visitTypeOperator(tree_ir.TypeOperator node) { | 342 js.Expression visitTypeOperator(tree_ir.TypeOperator node) { |
| 351 return giveup(node); | 343 return giveup(node); |
| 352 // TODO: implement visitTypeOperator | 344 // TODO: implement visitTypeOperator |
| 353 } | 345 } |
| 354 | 346 |
| 355 @override | 347 @override |
| (...skipping 16 matching lines...) Expand all Loading... |
| 372 } | 364 } |
| 373 | 365 |
| 374 @override | 366 @override |
| 375 void visitExpressionStatement(tree_ir.ExpressionStatement node) { | 367 void visitExpressionStatement(tree_ir.ExpressionStatement node) { |
| 376 accumulator.add(new js.ExpressionStatement( | 368 accumulator.add(new js.ExpressionStatement( |
| 377 visitExpression(node.expression))); | 369 visitExpression(node.expression))); |
| 378 visitStatement(node.next); | 370 visitStatement(node.next); |
| 379 } | 371 } |
| 380 | 372 |
| 381 @override | 373 @override |
| 382 void visitFunctionDeclaration(tree_ir.FunctionDeclaration node) { | |
| 383 giveup(node); | |
| 384 // TODO: implement visitFunctionDeclaration | |
| 385 } | |
| 386 | |
| 387 @override | |
| 388 void visitIf(tree_ir.If node) { | 374 void visitIf(tree_ir.If node) { |
| 389 accumulator.add(new js.If(visitExpression(node.condition), | 375 accumulator.add(new js.If(visitExpression(node.condition), |
| 390 buildBody(node.thenStatement), | 376 buildBody(node.thenStatement), |
| 391 buildBody(node.elseStatement))); | 377 buildBody(node.elseStatement))); |
| 392 } | 378 } |
| 393 | 379 |
| 394 @override | 380 @override |
| 395 void visitLabeledStatement(tree_ir.LabeledStatement node) { | 381 void visitLabeledStatement(tree_ir.LabeledStatement node) { |
| 396 accumulator.add(buildLabeled(() => buildBody(node.body), | 382 accumulator.add(buildLabeled(() => buildBody(node.body), |
| 397 node.label, | 383 node.label, |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 482 accumulator.add( | 468 accumulator.add( |
| 483 buildWhile(new js.LiteralBool(true), node.body, node.label, node)); | 469 buildWhile(new js.LiteralBool(true), node.body, node.label, node)); |
| 484 } | 470 } |
| 485 | 471 |
| 486 @override | 472 @override |
| 487 void visitReturn(tree_ir.Return node) { | 473 void visitReturn(tree_ir.Return node) { |
| 488 accumulator.add(new js.Return(visitExpression(node.value))); | 474 accumulator.add(new js.Return(visitExpression(node.value))); |
| 489 } | 475 } |
| 490 | 476 |
| 491 @override | 477 @override |
| 492 js.Expression visitFieldInitializer(tree_ir.FieldInitializer node) { | |
| 493 return giveup(node); | |
| 494 // TODO: implement FieldInitializer | |
| 495 } | |
| 496 | |
| 497 @override | |
| 498 js.Expression visitSuperInitializer(tree_ir.SuperInitializer node) { | |
| 499 return giveup(node); | |
| 500 // TODO: implement SuperInitializer | |
| 501 } | |
| 502 | |
| 503 @override | |
| 504 js.Expression visitCreateBox(tree_ir.CreateBox node) { | 478 js.Expression visitCreateBox(tree_ir.CreateBox node) { |
| 505 return new js.ObjectInitializer([]); | 479 return new js.ObjectInitializer([]); |
| 506 } | 480 } |
| 507 | 481 |
| 508 @override | 482 @override |
| 509 js.Expression visitCreateInstance(tree_ir.CreateInstance node) { | 483 js.Expression visitCreateInstance(tree_ir.CreateInstance node) { |
| 510 registry.registerInstantiatedClass(node.classElement); | 484 registry.registerInstantiatedClass(node.classElement); |
| 511 return new js.New(glue.constructorAccess(node.classElement), | 485 return new js.New(glue.constructorAccess(node.classElement), |
| 512 node.arguments.map(visitExpression).toList()); | 486 node.arguments.map(visitExpression).toList()); |
| 513 } | 487 } |
| 514 | 488 |
| 515 @override | 489 @override |
| 516 js.Expression visitGetField(tree_ir.GetField node) { | 490 js.Expression visitGetField(tree_ir.GetField node) { |
| 517 return new js.PropertyAccess.field( | 491 return new js.PropertyAccess.field( |
| 518 visitExpression(node.object), | 492 visitExpression(node.object), |
| 519 glue.instanceFieldPropertyName(node.field)); | 493 glue.instanceFieldPropertyName(node.field)); |
| 520 } | 494 } |
| 521 | 495 |
| 522 @override | 496 @override |
| 523 void visitSetField(tree_ir.SetField node) { | 497 void visitSetField(tree_ir.SetField node) { |
| 524 js.PropertyAccess field = | 498 js.PropertyAccess field = |
| 525 new js.PropertyAccess.field( | 499 new js.PropertyAccess.field( |
| 526 visitExpression(node.object), | 500 visitExpression(node.object), |
| 527 glue.instanceFieldPropertyName(node.field)); | 501 glue.instanceFieldPropertyName(node.field)); |
| 528 js.Assignment asn = new js.Assignment(field, visitExpression(node.value)); | 502 js.Assignment asn = new js.Assignment(field, visitExpression(node.value)); |
| 529 accumulator.add(new js.ExpressionStatement(asn)); | 503 accumulator.add(new js.ExpressionStatement(asn)); |
| 530 visitStatement(node.next); | 504 visitStatement(node.next); |
| 531 } | 505 } |
| 506 |
| 507 // Dart-specific IR nodes |
| 508 |
| 509 @override |
| 510 visitFunctionExpression(tree_ir.FunctionExpression node) { |
| 511 return errorUnsupportedNode(node); |
| 512 } |
| 513 |
| 514 @override |
| 515 visitFunctionDeclaration(tree_ir.FunctionDeclaration node) { |
| 516 return errorUnsupportedNode(node); |
| 517 } |
| 518 |
| 519 @override |
| 520 visitFieldInitializer(tree_ir.FieldInitializer node) { |
| 521 return errorUnsupportedNode(node); |
| 522 } |
| 523 |
| 524 @override |
| 525 visitSuperInitializer(tree_ir.SuperInitializer node) { |
| 526 return errorUnsupportedNode(node); |
| 527 } |
| 528 |
| 529 dynamic errorUnsupportedNode(tree_ir.DartSpecificNode node) { |
| 530 throw "Unsupported node in JS backend: $node"; |
| 531 } |
| 532 } | 532 } |
| OLD | NEW |