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

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

Issue 17977002: - Remove arguments definition test from the VM. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 5 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/class_finalizer.h" 9 #include "vm/class_finalizer.h"
10 #include "vm/compiler.h" 10 #include "vm/compiler.h"
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
124 } 124 }
125 125
126 126
127 void ParsedFunction::SetNodeSequence(SequenceNode* node_sequence) { 127 void ParsedFunction::SetNodeSequence(SequenceNode* node_sequence) {
128 ASSERT(node_sequence_ == NULL); 128 ASSERT(node_sequence_ == NULL);
129 ASSERT(node_sequence != NULL); 129 ASSERT(node_sequence != NULL);
130 node_sequence_ = node_sequence; 130 node_sequence_ = node_sequence;
131 } 131 }
132 132
133 133
134 LocalVariable* ParsedFunction::GetSavedArgumentsDescriptorVar() const {
135 const int num_parameters = function().NumParameters();
136 LocalScope* scope = node_sequence()->scope();
137 if (scope->num_variables() > num_parameters) {
138 LocalVariable* saved_args_desc_var = scope->VariableAt(num_parameters);
139 ASSERT(saved_args_desc_var != NULL);
140 // The scope of the formal parameters may also contain at this position
141 // an alias for the saved arguments descriptor variable of the enclosing
142 // function (check its scope owner) or an internal variable such as the
143 // expression temp variable or the saved entry context variable (check its
144 // name).
145 if ((saved_args_desc_var->owner() == scope) &&
146 saved_args_desc_var->name().StartsWith(
147 Symbols::SavedArgDescVarPrefix())) {
148 return saved_args_desc_var;
149 }
150 }
151 return NULL;
152 }
153
154
155 void ParsedFunction::AllocateVariables() { 134 void ParsedFunction::AllocateVariables() {
156 LocalScope* scope = node_sequence()->scope(); 135 LocalScope* scope = node_sequence()->scope();
157 const intptr_t num_fixed_params = function().num_fixed_parameters(); 136 const intptr_t num_fixed_params = function().num_fixed_parameters();
158 const intptr_t num_opt_params = function().NumOptionalParameters(); 137 const intptr_t num_opt_params = function().NumOptionalParameters();
159 intptr_t num_params = num_fixed_params + num_opt_params; 138 intptr_t num_params = num_fixed_params + num_opt_params;
regis 2013/06/27 01:06:27 const?
Ivan Posva 2013/06/27 18:36:44 Done.
160 // Compute start indices to parameters and locals, and the number of 139 // Compute start indices to parameters and locals, and the number of
161 // parameters to copy. 140 // parameters to copy.
162 if (num_opt_params == 0) { 141 if (num_opt_params == 0) {
163 // Parameter i will be at fp[kParamEndSlotFromFp + num_params - i] and 142 // Parameter i will be at fp[kParamEndSlotFromFp + num_params - i] and
164 // local variable j will be at fp[kFirstLocalSlotFromFp - j]. 143 // local variable j will be at fp[kFirstLocalSlotFromFp - j].
165 ASSERT(GetSavedArgumentsDescriptorVar() == NULL);
166 first_parameter_index_ = kParamEndSlotFromFp + num_params; 144 first_parameter_index_ = kParamEndSlotFromFp + num_params;
167 first_stack_local_index_ = kFirstLocalSlotFromFp; 145 first_stack_local_index_ = kFirstLocalSlotFromFp;
168 num_copied_params_ = 0; 146 num_copied_params_ = 0;
169 } else { 147 } else {
170 // Parameter i will be at fp[kFirstLocalSlotFromFp - i] and local variable 148 // Parameter i will be at fp[kFirstLocalSlotFromFp - i] and local variable
171 // j will be at fp[kFirstLocalSlotFromFp - num_params - j]. 149 // j will be at fp[kFirstLocalSlotFromFp - num_params - j].
172 // The saved arguments descriptor variable must be allocated similarly to
173 // a parameter, so that it gets both a frame slot and a context slot when
174 // captured.
175 if (GetSavedArgumentsDescriptorVar() != NULL) {
176 num_params += 1;
177 }
178 first_parameter_index_ = kFirstLocalSlotFromFp; 150 first_parameter_index_ = kFirstLocalSlotFromFp;
179 first_stack_local_index_ = first_parameter_index_ - num_params; 151 first_stack_local_index_ = first_parameter_index_ - num_params;
180 num_copied_params_ = num_params; 152 num_copied_params_ = num_params;
181 } 153 }
182 154
183 // Allocate parameters and local variables, either in the local frame or 155 // Allocate parameters and local variables, either in the local frame or
184 // in the context(s). 156 // in the context(s).
185 LocalScope* context_owner = NULL; // No context needed yet. 157 LocalScope* context_owner = NULL; // No context needed yet.
186 int next_free_frame_index = 158 int next_free_frame_index =
187 scope->AllocateVariables(first_parameter_index_, 159 scope->AllocateVariables(first_parameter_index_,
(...skipping 7879 matching lines...) Expand 10 before | Expand all | Expand 10 after
8067 LocalVariable* Parser::LookupLocalScope(const String& ident) { 8039 LocalVariable* Parser::LookupLocalScope(const String& ident) {
8068 if (current_block_ == NULL) { 8040 if (current_block_ == NULL) {
8069 return NULL; 8041 return NULL;
8070 } 8042 }
8071 // A found name is treated as accessed and possibly marked as captured. 8043 // A found name is treated as accessed and possibly marked as captured.
8072 const bool kTestOnly = false; 8044 const bool kTestOnly = false;
8073 return current_block_->scope->LookupVariable(ident, kTestOnly); 8045 return current_block_->scope->LookupVariable(ident, kTestOnly);
8074 } 8046 }
8075 8047
8076 8048
8077 // Returns true if ident resolves to a formal parameter of the current function
8078 // or of one of its enclosing functions.
8079 // Make sure not to capture the formal parameter, since it is not accessed.
8080 bool Parser::IsFormalParameter(const String& ident,
8081 Function* owner_function,
8082 LocalScope** owner_scope,
8083 intptr_t* local_index) {
8084 if (current_block_ == NULL) {
8085 return false;
8086 }
8087 if (ident.Equals(Symbols::This())) {
8088 // 'this' is not a formal parameter that can be tested with '?this'.
8089 return false;
8090 }
8091 // Since an argument definition test does not use the value of the formal
8092 // parameter, there is no reason to capture it.
8093 const bool kTestOnly = true; // No capturing.
8094 LocalVariable* local =
8095 current_block_->scope->LookupVariable(ident, kTestOnly);
8096 if ((local == NULL) ||
8097 (local->owner()->HasContextLevel() &&
8098 (local->owner()->context_level() < 1))) {
8099 if ((local == NULL) && !current_function().IsLocalFunction()) {
8100 // We are not generating code for a local function, so all locals,
8101 // captured or not, are in scope. However, 'ident' was not found, so it
8102 // does not exist.
8103 return false;
8104 }
8105 // The formal parameter belongs to an enclosing function and may not have
8106 // been captured, so it was not included in the context scope and it cannot
8107 // be found by LookupVariable.
8108 ASSERT((local == NULL) || local->is_captured());
8109 // 'ident' necessarily refers to the formal parameter of one of the
8110 // enclosing functions, or a compile error would have prevented the
8111 // outermost enclosing function to be executed and we would not be compiling
8112 // this local function.
8113 // Therefore, look for ident directly in the formal parameter lists of the
8114 // enclosing functions.
8115 // There is no need to return the owner_scope, since the caller will not
8116 // create the saved_arguments_descriptor variable, which already exists.
8117 Function& function = Function::Handle(innermost_function().raw());
8118 String& param_name = String::Handle();
8119 do {
8120 const int num_parameters = function.NumParameters();
8121 for (intptr_t i = 0; i < num_parameters; i++) {
8122 param_name = function.ParameterNameAt(i);
8123 if (ident.Equals(param_name)) {
8124 *owner_function = function.raw();
8125 *owner_scope = NULL;
8126 *local_index = i;
8127 return true;
8128 }
8129 }
8130 function = function.parent_function();
8131 } while (!function.IsNull());
8132 UNREACHABLE();
8133 }
8134 // Verify that local is a formal parameter of the current function or of one
8135 // of its enclosing functions.
8136 // Note that scopes are not yet associated to functions.
8137 Function& function = Function::Handle(innermost_function().raw());
8138 LocalScope* scope = current_block_->scope;
8139 while (scope != NULL) {
8140 ASSERT(!function.IsNull());
8141 // Find the top scope for this function level.
8142 while ((scope->parent() != NULL) &&
8143 (scope->parent()->function_level() == scope->function_level())) {
8144 scope = scope->parent();
8145 }
8146 if (scope == local->owner()) {
8147 // Scope contains 'local' and the formal parameters of 'function'.
8148 const int num_parameters = function.NumParameters();
8149 for (intptr_t i = 0; i < num_parameters; i++) {
8150 if (scope->VariableAt(i) == local) {
8151 *owner_function = function.raw();
8152 *owner_scope = scope;
8153 *local_index = i;
8154 return true;
8155 }
8156 }
8157 // The variable 'local' is not a formal parameter.
8158 return false;
8159 }
8160 scope = scope->parent();
8161 function = function.parent_function();
8162 }
8163 // The variable 'local' does not belong to a function top scope.
8164 return false;
8165 }
8166
8167
8168 void Parser::CheckInstanceFieldAccess(intptr_t field_pos, 8049 void Parser::CheckInstanceFieldAccess(intptr_t field_pos,
8169 const String& field_name) { 8050 const String& field_name) {
8170 // Fields are not accessible from a static function, except from a 8051 // Fields are not accessible from a static function, except from a
8171 // constructor, which is considered as non-static by the compiler. 8052 // constructor, which is considered as non-static by the compiler.
8172 if (current_function().is_static()) { 8053 if (current_function().is_static()) {
8173 ErrorMsg(field_pos, 8054 ErrorMsg(field_pos,
8174 "cannot access instance field '%s' from a static function", 8055 "cannot access instance field '%s' from a static function",
8175 field_name.ToCString()); 8056 field_name.ToCString());
8176 } 8057 }
8177 } 8058 }
(...skipping 1464 matching lines...) Expand 10 before | Expand all | Expand 10 after
9642 values_list); 9523 values_list);
9643 interpolate_arg->Add(values); 9524 interpolate_arg->Add(values);
9644 primary = MakeStaticCall(Symbols::StringBase(), 9525 primary = MakeStaticCall(Symbols::StringBase(),
9645 PrivateCoreLibName(Symbols::Interpolate()), 9526 PrivateCoreLibName(Symbols::Interpolate()),
9646 interpolate_arg); 9527 interpolate_arg);
9647 } 9528 }
9648 return primary; 9529 return primary;
9649 } 9530 }
9650 9531
9651 9532
9652 AstNode* Parser::ParseArgumentDefinitionTest() {
9653 const intptr_t test_pos = TokenPos();
9654 ConsumeToken();
9655 const intptr_t ident_pos = TokenPos();
9656 String* ident = ExpectIdentifier("parameter name expected");
9657 Function& owner_function = Function::Handle();
9658 LocalScope* owner_scope;
9659 intptr_t param_index;
9660 if (!IsFormalParameter(*ident, &owner_function, &owner_scope, &param_index)) {
9661 ErrorMsg(ident_pos, "formal parameter name expected");
9662 }
9663 if (param_index < owner_function.num_fixed_parameters()) {
9664 // The formal parameter is not optional, therefore the corresponding
9665 // argument is always passed and defined.
9666 return new LiteralNode(test_pos, Bool::True());
9667 }
9668 char name[64];
9669 OS::SNPrint(name, 64, "%s_%"Pd"",
9670 Symbols::Name(Symbols::kSavedArgDescVarPrefixId),
9671 owner_function.token_pos());
9672 const String& saved_args_desc_name = String::ZoneHandle(Symbols::New(name));
9673 LocalVariable* saved_args_desc_var = LookupLocalScope(saved_args_desc_name);
9674 if (saved_args_desc_var == NULL) {
9675 ASSERT(owner_scope != NULL);
9676 saved_args_desc_var =
9677 new LocalVariable(owner_function.token_pos(),
9678 saved_args_desc_name,
9679 Type::ZoneHandle(Type::ArrayType()));
9680 saved_args_desc_var->set_is_final();
9681 // The saved arguments descriptor variable must be added just after the
9682 // formal parameters. This simplifies the 2-step saving of a captured
9683 // arguments descriptor.
9684 // At this time, the owner scope should only contain formal parameters.
9685 ASSERT(owner_scope->num_variables() == owner_function.NumParameters());
9686 bool success = owner_scope->AddVariable(saved_args_desc_var);
9687 ASSERT(success);
9688 // Capture the saved arguments descriptor variable if necessary.
9689 LocalVariable* local = LookupLocalScope(saved_args_desc_name);
9690 ASSERT(local == saved_args_desc_var);
9691 }
9692 // If we currently generate code for the local function of an enclosing owner
9693 // function, the saved arguments descriptor variable must have been captured
9694 // by the above lookup.
9695 ASSERT((owner_function.raw() == innermost_function().raw()) ||
9696 saved_args_desc_var->is_captured());
9697 const String& param_name = String::ZoneHandle(Symbols::New(*ident));
9698 return new ArgumentDefinitionTestNode(
9699 test_pos, param_index, param_name, saved_args_desc_var);
9700 }
9701
9702
9703 AstNode* Parser::ParsePrimary() { 9533 AstNode* Parser::ParsePrimary() {
9704 TRACE_PARSER("ParsePrimary"); 9534 TRACE_PARSER("ParsePrimary");
9705 ASSERT(!is_top_level_); 9535 ASSERT(!is_top_level_);
9706 AstNode* primary = NULL; 9536 AstNode* primary = NULL;
9707 if (IsFunctionLiteral()) { 9537 if (IsFunctionLiteral()) {
9708 // The name of a literal function is visible from inside the function, but 9538 // The name of a literal function is visible from inside the function, but
9709 // must not collide with names in the scope declaring the literal. 9539 // must not collide with names in the scope declaring the literal.
9710 OpenBlock(); 9540 OpenBlock();
9711 primary = ParseFunctionStatement(true); 9541 primary = ParseFunctionStatement(true);
9712 CloseBlock(); 9542 CloseBlock();
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
9823 } else { 9653 } else {
9824 primary = ParseSuperFieldAccess(ident); 9654 primary = ParseSuperFieldAccess(ident);
9825 } 9655 }
9826 } else if ((CurrentToken() == Token::kLBRACK) || 9656 } else if ((CurrentToken() == Token::kLBRACK) ||
9827 Token::CanBeOverloaded(CurrentToken()) || 9657 Token::CanBeOverloaded(CurrentToken()) ||
9828 (CurrentToken() == Token::kNE)) { 9658 (CurrentToken() == Token::kNE)) {
9829 primary = ParseSuperOperator(); 9659 primary = ParseSuperOperator();
9830 } else { 9660 } else {
9831 primary = new PrimaryNode(TokenPos(), Symbols::Super()); 9661 primary = new PrimaryNode(TokenPos(), Symbols::Super());
9832 } 9662 }
9833 } else if (CurrentToken() == Token::kCONDITIONAL) {
9834 primary = ParseArgumentDefinitionTest();
9835 } else { 9663 } else {
9836 UnexpectedToken(); 9664 UnexpectedToken();
9837 } 9665 }
9838 return primary; 9666 return primary;
9839 } 9667 }
9840 9668
9841 9669
9842 // Evaluate expression in expr and return the value. The expression must 9670 // Evaluate expression in expr and return the value. The expression must
9843 // be a compile time constant. 9671 // be a compile time constant.
9844 const Instance& Parser::EvaluateConstExpr(AstNode* expr) { 9672 const Instance& Parser::EvaluateConstExpr(AstNode* expr) {
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
10024 } else { 9852 } else {
10025 SkipNewOperator(); 9853 SkipNewOperator();
10026 } 9854 }
10027 break; 9855 break;
10028 case Token::kLT: 9856 case Token::kLT:
10029 case Token::kLBRACE: 9857 case Token::kLBRACE:
10030 case Token::kLBRACK: 9858 case Token::kLBRACK:
10031 case Token::kINDEX: 9859 case Token::kINDEX:
10032 SkipCompoundLiteral(); 9860 SkipCompoundLiteral();
10033 break; 9861 break;
10034 case Token::kCONDITIONAL:
10035 ConsumeToken();
10036 if (IsIdentifier()) {
10037 ConsumeToken();
10038 }
10039 break;
10040 default: 9862 default:
10041 if (IsIdentifier()) { 9863 if (IsIdentifier()) {
10042 ConsumeToken(); // Handle pseudo-keyword identifiers. 9864 ConsumeToken(); // Handle pseudo-keyword identifiers.
10043 } else { 9865 } else {
10044 UnexpectedToken(); 9866 UnexpectedToken();
10045 UNREACHABLE(); 9867 UNREACHABLE();
10046 } 9868 }
10047 break; 9869 break;
10048 } 9870 }
10049 } 9871 }
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
10152 void Parser::SkipQualIdent() { 9974 void Parser::SkipQualIdent() {
10153 ASSERT(IsIdentifier()); 9975 ASSERT(IsIdentifier());
10154 ConsumeToken(); 9976 ConsumeToken();
10155 if (CurrentToken() == Token::kPERIOD) { 9977 if (CurrentToken() == Token::kPERIOD) {
10156 ConsumeToken(); // Consume the kPERIOD token. 9978 ConsumeToken(); // Consume the kPERIOD token.
10157 ExpectIdentifier("identifier expected after '.'"); 9979 ExpectIdentifier("identifier expected after '.'");
10158 } 9980 }
10159 } 9981 }
10160 9982
10161 } // namespace dart 9983 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698