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 '../compile_time_constants.dart' show BackendConstantEnvironment; | 7 import '../compile_time_constants.dart' show BackendConstantEnvironment; |
8 import '../constants/constant_system.dart'; | 8 import '../constants/constant_system.dart'; |
9 import '../constants/expressions.dart'; | 9 import '../constants/expressions.dart'; |
10 import '../constants/values.dart' show ConstantValue, PrimitiveConstantValue; | 10 import '../constants/values.dart' show ConstantValue, PrimitiveConstantValue; |
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
388 final BackendConstantEnvironment constants; | 388 final BackendConstantEnvironment constants; |
389 | 389 |
390 ConstantSystem get constantSystem => constants.constantSystem; | 390 ConstantSystem get constantSystem => constants.constantSystem; |
391 | 391 |
392 /// A stack of collectors for breaks. | 392 /// A stack of collectors for breaks. |
393 final List<JumpCollector> breakCollectors = <JumpCollector>[]; | 393 final List<JumpCollector> breakCollectors = <JumpCollector>[]; |
394 | 394 |
395 /// A stack of collectors for continues. | 395 /// A stack of collectors for continues. |
396 final List<JumpCollector> continueCollectors = <JumpCollector>[]; | 396 final List<JumpCollector> continueCollectors = <JumpCollector>[]; |
397 | 397 |
398 final List<ConstDeclaration> localConstants = <ConstDeclaration>[]; | |
399 | |
400 final ExecutableElement currentElement; | 398 final ExecutableElement currentElement; |
401 | 399 |
402 final ir.Continuation returnContinuation = new ir.Continuation.retrn(); | 400 final ir.Continuation returnContinuation = new ir.Continuation.retrn(); |
403 ir.Parameter _thisParameter; | 401 ir.Parameter _thisParameter; |
404 ir.Parameter enclosingMethodThisParameter; | 402 ir.Parameter enclosingMethodThisParameter; |
405 | 403 |
406 final List<ir.Parameter> functionParameters = <ir.Parameter>[]; | 404 final List<ir.Parameter> functionParameters = <ir.Parameter>[]; |
407 | 405 |
408 IrBuilderSharedState(this.constants, this.currentElement); | 406 IrBuilderSharedState(this.constants, this.currentElement); |
409 | 407 |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
587 } | 585 } |
588 | 586 |
589 /// Creates a parameter for [local] and adds it to the current environment. | 587 /// Creates a parameter for [local] and adds it to the current environment. |
590 ir.Parameter createLocalParameter(Local local) { | 588 ir.Parameter createLocalParameter(Local local) { |
591 ir.Parameter parameter = new ir.Parameter(local); | 589 ir.Parameter parameter = new ir.Parameter(local); |
592 _parameters.add(parameter); | 590 _parameters.add(parameter); |
593 environment.extend(local, parameter); | 591 environment.extend(local, parameter); |
594 return parameter; | 592 return parameter; |
595 } | 593 } |
596 | 594 |
597 /// Adds the constant [variableElement] to the environment with [value] as its | |
598 /// constant value. | |
599 void declareLocalConstant(LocalVariableElement variableElement, | |
600 ConstantExpression value) { | |
601 state.localConstants.add(new ConstDeclaration(variableElement, value)); | |
602 } | |
603 | |
604 /// Plug an expression into the 'hole' in the context being accumulated. The | 595 /// Plug an expression into the 'hole' in the context being accumulated. The |
605 /// empty context (just a hole) is represented by root (and current) being | 596 /// empty context (just a hole) is represented by root (and current) being |
606 /// null. Since the hole in the current context is filled by this function, | 597 /// null. Since the hole in the current context is filled by this function, |
607 /// the new hole must be in the newly added expression---which becomes the | 598 /// the new hole must be in the newly added expression---which becomes the |
608 /// new value of current. | 599 /// new value of current. |
609 void add(ir.Expression expr) { | 600 void add(ir.Expression expr) { |
610 assert(isOpen); | 601 assert(isOpen); |
611 if (_root == null) { | 602 if (_root == null) { |
612 _root = _current = expr; | 603 _root = _current = expr; |
613 } else { | 604 } else { |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
664 ir.Primitive _buildInvokeCall(ir.Primitive target, | 655 ir.Primitive _buildInvokeCall(ir.Primitive target, |
665 CallStructure callStructure, | 656 CallStructure callStructure, |
666 List<ir.Definition> arguments, | 657 List<ir.Definition> arguments, |
667 {SourceInformation sourceInformation}) { | 658 {SourceInformation sourceInformation}) { |
668 Selector selector = callStructure.callSelector; | 659 Selector selector = callStructure.callSelector; |
669 return _buildInvokeDynamic(target, selector, arguments, | 660 return _buildInvokeDynamic(target, selector, arguments, |
670 sourceInformation: sourceInformation); | 661 sourceInformation: sourceInformation); |
671 } | 662 } |
672 | 663 |
673 | 664 |
674 /// Create a [ir.Constant] from [constant] and add it to the CPS term. | 665 /// Create a [ir.Constant] from [value] and add it to the CPS term. |
675 // TODO(johnniwinther): Remove [value] when [ConstantValue] can be computed | 666 ir.Constant buildConstant(ConstantValue value) { |
676 // directly from [constant]. | |
677 ir.Constant buildConstant(ConstantExpression constant, ConstantValue value) { | |
678 assert(isOpen); | 667 assert(isOpen); |
679 return addPrimitive(new ir.Constant(constant, value)); | 668 return addPrimitive(new ir.Constant(value)); |
680 } | 669 } |
681 | 670 |
682 /// Create an integer constant and add it to the CPS term. | 671 /// Create an integer constant and add it to the CPS term. |
683 ir.Constant buildIntegerConstant(int value) { | 672 ir.Constant buildIntegerConstant(int value) { |
684 return buildConstant( | 673 return buildConstant(state.constantSystem.createInt(value)); |
685 new IntConstantExpression(value), | |
686 state.constantSystem.createInt(value)); | |
687 } | 674 } |
688 | 675 |
689 /// Create a double constant and add it to the CPS term. | 676 /// Create a double constant and add it to the CPS term. |
690 ir.Constant buildDoubleConstant(double value) { | 677 ir.Constant buildDoubleConstant(double value) { |
691 return buildConstant( | 678 return buildConstant(state.constantSystem.createDouble(value)); |
692 new DoubleConstantExpression(value), | |
693 state.constantSystem.createDouble(value)); | |
694 } | 679 } |
695 | 680 |
696 /// Create a Boolean constant and add it to the CPS term. | 681 /// Create a Boolean constant and add it to the CPS term. |
697 ir.Constant buildBooleanConstant(bool value) { | 682 ir.Constant buildBooleanConstant(bool value) { |
698 return buildConstant( | 683 return buildConstant(state.constantSystem.createBool(value)); |
699 new BoolConstantExpression(value), | |
700 state.constantSystem.createBool(value)); | |
701 } | 684 } |
702 | 685 |
703 /// Create a null constant and add it to the CPS term. | 686 /// Create a null constant and add it to the CPS term. |
704 ir.Constant buildNullConstant() { | 687 ir.Constant buildNullConstant() { |
705 return buildConstant( | 688 return buildConstant(state.constantSystem.createNull()); |
706 new NullConstantExpression(), | |
707 state.constantSystem.createNull()); | |
708 } | 689 } |
709 | 690 |
710 /// Create a string constant and add it to the CPS term. | 691 /// Create a string constant and add it to the CPS term. |
711 ir.Constant buildStringConstant(String value) { | 692 ir.Constant buildStringConstant(String value) { |
712 return buildConstant( | 693 return buildConstant( |
713 new StringConstantExpression(value), | |
714 state.constantSystem.createString(new ast.DartString.literal(value))); | 694 state.constantSystem.createString(new ast.DartString.literal(value))); |
715 } | 695 } |
716 | 696 |
717 /// Create a string constant and add it to the CPS term. | 697 /// Create a string constant and add it to the CPS term. |
718 ir.Constant buildDartStringConstant(ast.DartString value) { | 698 ir.Constant buildDartStringConstant(ast.DartString value) { |
719 return buildConstant( | 699 return buildConstant(state.constantSystem.createString(value)); |
720 new StringConstantExpression(value.slowToString()), | |
721 state.constantSystem.createString(value)); | |
722 } | 700 } |
723 | 701 |
724 /// Creates a non-constant list literal of the provided [type] and with the | 702 /// Creates a non-constant list literal of the provided [type] and with the |
725 /// provided [values]. | 703 /// provided [values]. |
726 ir.Primitive buildListLiteral(InterfaceType type, | 704 ir.Primitive buildListLiteral(InterfaceType type, |
727 Iterable<ir.Primitive> values) { | 705 Iterable<ir.Primitive> values) { |
728 assert(isOpen); | 706 assert(isOpen); |
729 return addPrimitive(new ir.LiteralList(type, values.toList())); | 707 return addPrimitive(new ir.LiteralList(type, values.toList())); |
730 } | 708 } |
731 | 709 |
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1079 } | 1057 } |
1080 | 1058 |
1081 /// Create a constructor invocation of [element] on [type] where the | 1059 /// Create a constructor invocation of [element] on [type] where the |
1082 /// constructor name and argument structure are defined by [callStructure] and | 1060 /// constructor name and argument structure are defined by [callStructure] and |
1083 /// the argument values are defined by [arguments]. | 1061 /// the argument values are defined by [arguments]. |
1084 ir.Primitive buildConstructorInvocation(FunctionElement element, | 1062 ir.Primitive buildConstructorInvocation(FunctionElement element, |
1085 CallStructure callStructure, | 1063 CallStructure callStructure, |
1086 DartType type, | 1064 DartType type, |
1087 List<ir.Primitive> arguments); | 1065 List<ir.Primitive> arguments); |
1088 | 1066 |
1089 /// Create a string concatenation of the [arguments]. | 1067 ir.Primitive buildStringify(ir.Primitive argument); |
| 1068 |
| 1069 /// Concatenate string values. |
| 1070 /// |
| 1071 /// The arguments must be strings; usually a call to [buildStringify] is |
| 1072 /// needed to ensure the proper conversion takes places. |
1090 ir.Primitive buildStringConcatenation(List<ir.Primitive> arguments) { | 1073 ir.Primitive buildStringConcatenation(List<ir.Primitive> arguments) { |
1091 assert(isOpen); | 1074 assert(isOpen); |
1092 return _continueWithExpression( | 1075 return addPrimitive(new ir.ApplyBuiltinOperator( |
1093 (k) => new ir.ConcatenateStrings(arguments, k)); | 1076 ir.BuiltinOperator.StringConcat, |
| 1077 arguments)); |
1094 } | 1078 } |
1095 | 1079 |
1096 /// Create an invocation of the `call` method of [functionExpression], where | 1080 /// Create an invocation of the `call` method of [functionExpression], where |
1097 /// the structure of arguments are given by [callStructure]. | 1081 /// the structure of arguments are given by [callStructure]. |
1098 ir.Primitive buildCallInvocation( | 1082 ir.Primitive buildCallInvocation( |
1099 ir.Primitive functionExpression, | 1083 ir.Primitive functionExpression, |
1100 CallStructure callStructure, | 1084 CallStructure callStructure, |
1101 List<ir.Definition> arguments, | 1085 List<ir.Definition> arguments, |
1102 {SourceInformation sourceInformation}) { | 1086 {SourceInformation sourceInformation}) { |
1103 return _buildInvokeCall(functionExpression, callStructure, arguments, | 1087 return _buildInvokeCall(functionExpression, callStructure, arguments, |
(...skipping 814 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1918 // ! e is translated as e ? false : true | 1902 // ! e is translated as e ? false : true |
1919 | 1903 |
1920 // Add a continuation parameter for the result of the expression. | 1904 // Add a continuation parameter for the result of the expression. |
1921 ir.Parameter resultParameter = new ir.Parameter(null); | 1905 ir.Parameter resultParameter = new ir.Parameter(null); |
1922 | 1906 |
1923 ir.Continuation joinContinuation = new ir.Continuation([resultParameter]); | 1907 ir.Continuation joinContinuation = new ir.Continuation([resultParameter]); |
1924 ir.Continuation thenContinuation = new ir.Continuation([]); | 1908 ir.Continuation thenContinuation = new ir.Continuation([]); |
1925 ir.Continuation elseContinuation = new ir.Continuation([]); | 1909 ir.Continuation elseContinuation = new ir.Continuation([]); |
1926 | 1910 |
1927 ir.Constant makeBoolConstant(bool value) { | 1911 ir.Constant makeBoolConstant(bool value) { |
1928 return new ir.Constant( | 1912 return new ir.Constant(state.constantSystem.createBool(value)); |
1929 new BoolConstantExpression(value), | |
1930 state.constantSystem.createBool(value)); | |
1931 } | 1913 } |
1932 | 1914 |
1933 ir.Constant trueConstant = makeBoolConstant(true); | 1915 ir.Constant trueConstant = makeBoolConstant(true); |
1934 ir.Constant falseConstant = makeBoolConstant(false); | 1916 ir.Constant falseConstant = makeBoolConstant(false); |
1935 | 1917 |
1936 thenContinuation.body = new ir.LetPrim(falseConstant) | 1918 thenContinuation.body = new ir.LetPrim(falseConstant) |
1937 ..plug(new ir.InvokeContinuation(joinContinuation, [falseConstant])); | 1919 ..plug(new ir.InvokeContinuation(joinContinuation, [falseConstant])); |
1938 elseContinuation.body = new ir.LetPrim(trueConstant) | 1920 elseContinuation.body = new ir.LetPrim(trueConstant) |
1939 ..plug(new ir.InvokeContinuation(joinContinuation, [trueConstant])); | 1921 ..plug(new ir.InvokeContinuation(joinContinuation, [trueConstant])); |
1940 | 1922 |
(...skipping 511 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2452 ir.Primitive condition = _buildCheckNull(receiver); | 2434 ir.Primitive condition = _buildCheckNull(receiver); |
2453 return buildConditional(condition, (_) => receiver, buildSend); | 2435 return buildConditional(condition, (_) => receiver, buildSend); |
2454 } | 2436 } |
2455 | 2437 |
2456 /// Creates a type test checking whether [value] is null. | 2438 /// Creates a type test checking whether [value] is null. |
2457 ir.Primitive _buildCheckNull(ir.Primitive value) { | 2439 ir.Primitive _buildCheckNull(ir.Primitive value) { |
2458 assert(isOpen); | 2440 assert(isOpen); |
2459 ir.Primitive right = buildNullConstant(); | 2441 ir.Primitive right = buildNullConstant(); |
2460 return addPrimitive(new ir.Identical(value, right)); | 2442 return addPrimitive(new ir.Identical(value, right)); |
2461 } | 2443 } |
| 2444 |
| 2445 /// Convert the given value to a string. |
| 2446 ir.Primitive buildStringify(ir.Primitive value) { |
| 2447 return buildStaticFunctionInvocation( |
| 2448 program.stringifyFunction, |
| 2449 new CallStructure.unnamed(1), |
| 2450 <ir.Primitive>[value]); |
| 2451 } |
2462 } | 2452 } |
2463 | 2453 |
2464 | 2454 |
2465 /// Location of a variable relative to a given closure. | 2455 /// Location of a variable relative to a given closure. |
2466 class ClosureLocation { | 2456 class ClosureLocation { |
2467 /// If not `null`, this location is [box].[field]. | 2457 /// If not `null`, this location is [box].[field]. |
2468 /// The location of [box] can be obtained separately from an | 2458 /// The location of [box] can be obtained separately from an |
2469 /// enclosing [ClosureEnvironment] or [ClosureScope]. | 2459 /// enclosing [ClosureEnvironment] or [ClosureScope]. |
2470 /// If `null`, then the location is [field] on the enclosing function object. | 2460 /// If `null`, then the location is [field] on the enclosing function object. |
2471 final BoxLocal box; | 2461 final BoxLocal box; |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2524 final DartType type; | 2514 final DartType type; |
2525 final LocalVariableElement exceptionVariable; | 2515 final LocalVariableElement exceptionVariable; |
2526 final LocalVariableElement stackTraceVariable; | 2516 final LocalVariableElement stackTraceVariable; |
2527 final SubbuildFunction buildCatchBlock; | 2517 final SubbuildFunction buildCatchBlock; |
2528 | 2518 |
2529 CatchClauseInfo({this.type, | 2519 CatchClauseInfo({this.type, |
2530 this.exceptionVariable, | 2520 this.exceptionVariable, |
2531 this.stackTraceVariable, | 2521 this.stackTraceVariable, |
2532 this.buildCatchBlock}); | 2522 this.buildCatchBlock}); |
2533 } | 2523 } |
OLD | NEW |