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

Side by Side Diff: runtime/vm/parser.cc

Issue 24203004: Dart VM: Simplify code generation for equality operators. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: fixed single stepping, added debugger test Created 7 years, 2 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 #include "vm/parser.h" 5 #include "vm/parser.h"
6 6
7 #include "lib/invocation_mirror.h" 7 #include "lib/invocation_mirror.h"
8 #include "vm/bigint_operations.h" 8 #include "vm/bigint_operations.h"
9 #include "vm/bootstrap.h" 9 #include "vm/bootstrap.h"
10 #include "vm/class_finalizer.h" 10 #include "vm/class_finalizer.h"
(...skipping 1905 matching lines...) Expand 10 before | Expand all | Expand 10 after
1916 const Function& super_operator = Function::ZoneHandle( 1916 const Function& super_operator = Function::ZoneHandle(
1917 GetSuperFunction(operator_pos, 1917 GetSuperFunction(operator_pos,
1918 operator_function_name, 1918 operator_function_name,
1919 op_arguments, 1919 op_arguments,
1920 kResolveGetter, 1920 kResolveGetter,
1921 &is_no_such_method)); 1921 &is_no_such_method));
1922 if (is_no_such_method) { 1922 if (is_no_such_method) {
1923 op_arguments = BuildNoSuchMethodArguments( 1923 op_arguments = BuildNoSuchMethodArguments(
1924 operator_pos, operator_function_name, *op_arguments); 1924 operator_pos, operator_function_name, *op_arguments);
1925 } 1925 }
1926 if (super_operator.name() == Symbols::EqualOperator().raw()) { 1926 super_op = new StaticCallNode(operator_pos, super_operator, op_arguments);
1927 // Expand super.== call to match correct == semantics into:
1928 // Let t1 = left, t2 = right {
1929 // (t1 === null || t2 === null) ? t1 === t2
1930 // : static_call(super.==, t1, t2)
1931 // }
1932 // Normal == calls are not expanded at the AST level to produce
1933 // more compact code and enable more optimization opportunities.
1934 ASSERT(!is_no_such_method); // == is always found.
1935 EnsureExpressionTemp(); // Needed for ConditionalExprNode.
1936 LetNode* result = new LetNode(operator_pos);
1937 AstNode* left =
1938 new LoadLocalNode(operator_pos,
1939 result->AddInitializer(op_arguments->NodeAt(0)));
1940 AstNode* right =
1941 new LoadLocalNode(operator_pos,
1942 result->AddInitializer(op_arguments->NodeAt(1)));
1943 LiteralNode* null_operand =
1944 new LiteralNode(operator_pos, Instance::ZoneHandle());
1945 ComparisonNode* is_left_null = new ComparisonNode(operator_pos,
1946 Token::kEQ_STRICT,
1947 left,
1948 null_operand);
1949 ComparisonNode* is_right_null = new ComparisonNode(operator_pos,
1950 Token::kEQ_STRICT,
1951 right,
1952 null_operand);
1953 BinaryOpNode* null_check = new BinaryOpNode(operator_pos,
1954 Token::kOR,
1955 is_left_null,
1956 is_right_null);
1957 ArgumentListNode* new_arguments = new ArgumentListNode(operator_pos);
1958 new_arguments->Add(left);
1959 new_arguments->Add(right);
1960 StaticCallNode* call = new StaticCallNode(operator_pos,
1961 super_operator,
1962 new_arguments);
1963 ComparisonNode* strict_eq = new ComparisonNode(operator_pos,
1964 Token::kEQ_STRICT,
1965 left,
1966 right);
1967 result->AddNode(new ConditionalExprNode(operator_pos,
1968 null_check,
1969 strict_eq,
1970 call));
1971 super_op = result;
1972 } else {
1973 super_op = new StaticCallNode(operator_pos, super_operator, op_arguments);
1974 }
1975 if (negate_result) { 1927 if (negate_result) {
1976 super_op = new UnaryOpNode(operator_pos, Token::kNOT, super_op); 1928 super_op = new UnaryOpNode(operator_pos, Token::kNOT, super_op);
1977 } 1929 }
1978 } 1930 }
1979 return super_op; 1931 return super_op;
1980 } 1932 }
1981 1933
1982 1934
1983 AstNode* Parser::CreateImplicitClosureNode(const Function& func, 1935 AstNode* Parser::CreateImplicitClosureNode(const Function& func,
1984 intptr_t token_pos, 1936 intptr_t token_pos,
(...skipping 884 matching lines...) Expand 10 before | Expand all | Expand 10 after
2869 // instantiate types. 2821 // instantiate types.
2870 CaptureInstantiator(); 2822 CaptureInstantiator();
2871 } 2823 }
2872 } 2824 }
2873 } 2825 }
2874 2826
2875 OpenBlock(); // Open a nested scope for the outermost function block. 2827 OpenBlock(); // Open a nested scope for the outermost function block.
2876 intptr_t end_token_pos = 0; 2828 intptr_t end_token_pos = 0;
2877 if (CurrentToken() == Token::kLBRACE) { 2829 if (CurrentToken() == Token::kLBRACE) {
2878 ConsumeToken(); 2830 ConsumeToken();
2831 if (String::Handle(func.name()).Equals(Symbols::EqualOperator())) {
2832 const Class& owner = Class::Handle(func.Owner());
2833 if (!owner.IsObjectClass()) {
2834 AddEqualityNullCheck();
2835 }
2836 }
2879 ParseStatementSequence(); 2837 ParseStatementSequence();
2880 end_token_pos = TokenPos(); 2838 end_token_pos = TokenPos();
2881 ExpectToken(Token::kRBRACE); 2839 ExpectToken(Token::kRBRACE);
2882 } else if (CurrentToken() == Token::kARROW) { 2840 } else if (CurrentToken() == Token::kARROW) {
2883 ConsumeToken(); 2841 ConsumeToken();
2842 if (String::Handle(func.name()).Equals(Symbols::EqualOperator())) {
2843 const Class& owner = Class::Handle(func.Owner());
2844 if (!owner.IsObjectClass()) {
2845 AddEqualityNullCheck();
2846 }
2847 }
2884 const intptr_t expr_pos = TokenPos(); 2848 const intptr_t expr_pos = TokenPos();
2885 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); 2849 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades);
2886 ASSERT(expr != NULL); 2850 ASSERT(expr != NULL);
2887 current_block_->statements->Add(new ReturnNode(expr_pos, expr)); 2851 current_block_->statements->Add(new ReturnNode(expr_pos, expr));
2888 end_token_pos = TokenPos(); 2852 end_token_pos = TokenPos();
2889 } else if (IsLiteral("native")) { 2853 } else if (IsLiteral("native")) {
2890 ParseNativeFunctionBlock(&params, func); 2854 ParseNativeFunctionBlock(&params, func);
hausner 2013/09/25 16:36:11 This is a nit, but your scheme does not work for n
Florian Schneider 2013/09/26 11:34:21 Good point. Right now, native methods contain just
2891 end_token_pos = TokenPos(); 2855 end_token_pos = TokenPos();
2892 ExpectSemicolon(); 2856 ExpectSemicolon();
2893 } else if (func.is_external()) { 2857 } else if (func.is_external()) {
2894 // Body of an external method contains a single throw. 2858 // Body of an external method contains a single throw.
2895 const String& function_name = String::ZoneHandle(func.name()); 2859 const String& function_name = String::ZoneHandle(func.name());
2896 // TODO(regis): For an instance function, pass the receiver to 2860 // TODO(regis): For an instance function, pass the receiver to
2897 // NoSuchMethodError. 2861 // NoSuchMethodError.
2898 current_block_->statements->Add( 2862 current_block_->statements->Add(
2899 ThrowNoSuchMethodError(TokenPos(), 2863 ThrowNoSuchMethodError(TokenPos(),
2900 current_class(), 2864 current_class(),
(...skipping 12 matching lines...) Expand all
2913 func.end_token_pos() == end_token_pos); 2877 func.end_token_pos() == end_token_pos);
2914 func.set_end_token_pos(end_token_pos); 2878 func.set_end_token_pos(end_token_pos);
2915 SequenceNode* body = CloseBlock(); 2879 SequenceNode* body = CloseBlock();
2916 current_block_->statements->Add(body); 2880 current_block_->statements->Add(body);
2917 innermost_function_ = saved_innermost_function.raw(); 2881 innermost_function_ = saved_innermost_function.raw();
2918 last_used_try_index_ = saved_try_index; 2882 last_used_try_index_ = saved_try_index;
2919 return CloseBlock(); 2883 return CloseBlock();
2920 } 2884 }
2921 2885
2922 2886
2887 void Parser::AddEqualityNullCheck() {
2888 const intptr_t token_pos = Scanner::kDummyTokenIndex;
2889 AstNode* argument =
2890 new LoadLocalNode(token_pos,
2891 current_block_->scope->parent()->VariableAt(1));
2892 LiteralNode* null_operand =
2893 new LiteralNode(token_pos, Instance::ZoneHandle());
2894 ComparisonNode* check_arg = new ComparisonNode(token_pos,
2895 Token::kEQ_STRICT,
2896 argument,
2897 null_operand);
2898 ComparisonNode* result = new ComparisonNode(token_pos,
2899 Token::kEQ_STRICT,
2900 LoadReceiver(token_pos),
2901 null_operand);
2902 SequenceNode* arg_is_null = new SequenceNode(token_pos, NULL);
2903 arg_is_null->Add(new ReturnNode(token_pos, result));
2904 IfNode* if_arg_null = new IfNode(token_pos,
2905 check_arg,
2906 arg_is_null,
2907 NULL);
2908 current_block_->statements->Add(if_arg_null);
2909 }
2910
2911
2923 void Parser::SkipIf(Token::Kind token) { 2912 void Parser::SkipIf(Token::Kind token) {
2924 if (CurrentToken() == token) { 2913 if (CurrentToken() == token) {
2925 ConsumeToken(); 2914 ConsumeToken();
2926 } 2915 }
2927 } 2916 }
2928 2917
2929 2918
2930 // Skips tokens up to matching closing parenthesis. 2919 // Skips tokens up to matching closing parenthesis.
2931 void Parser::SkipToMatchingParenthesis() { 2920 void Parser::SkipToMatchingParenthesis() {
2932 ASSERT(CurrentToken() == Token::kLPAREN); 2921 ASSERT(CurrentToken() == Token::kLPAREN);
(...skipping 7584 matching lines...) Expand 10 before | Expand all | Expand 10 after
10517 void Parser::SkipQualIdent() { 10506 void Parser::SkipQualIdent() {
10518 ASSERT(IsIdentifier()); 10507 ASSERT(IsIdentifier());
10519 ConsumeToken(); 10508 ConsumeToken();
10520 if (CurrentToken() == Token::kPERIOD) { 10509 if (CurrentToken() == Token::kPERIOD) {
10521 ConsumeToken(); // Consume the kPERIOD token. 10510 ConsumeToken(); // Consume the kPERIOD token.
10522 ExpectIdentifier("identifier expected after '.'"); 10511 ExpectIdentifier("identifier expected after '.'");
10523 } 10512 }
10524 } 10513 }
10525 10514
10526 } // namespace dart 10515 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698