Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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 <map> | 5 #include <map> |
| 6 #include <set> | 6 #include <set> |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "vm/kernel_to_il.h" | 9 #include "vm/kernel_to_il.h" |
| 10 | 10 |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 51 } else if ((*outermost_node)->IsConstructor()) { | 51 } else if ((*outermost_node)->IsConstructor()) { |
| 52 parent = Constructor::Cast(*outermost_node)->parent(); | 52 parent = Constructor::Cast(*outermost_node)->parent(); |
| 53 } else if ((*outermost_node)->IsField()) { | 53 } else if ((*outermost_node)->IsField()) { |
| 54 parent = Field::Cast(*outermost_node)->parent(); | 54 parent = Field::Cast(*outermost_node)->parent(); |
| 55 } | 55 } |
| 56 if (parent != NULL && parent->IsClass()) *klass = Class::Cast(parent); | 56 if (parent != NULL && parent->IsClass()) *klass = Class::Cast(parent); |
| 57 } | 57 } |
| 58 } | 58 } |
| 59 | 59 |
| 60 | 60 |
| 61 void ScopeBuilder::EnterScope(TreeNode* node) { | 61 void ScopeBuilder::EnterScope(TreeNode* node, TokenPosition start_position) { |
| 62 scope_ = new (Z) LocalScope(scope_, depth_.function_, depth_.loop_); | 62 scope_ = new (Z) LocalScope(scope_, depth_.function_, depth_.loop_); |
| 63 scope_->set_begin_token_pos(start_position); | |
| 63 result_->scopes.Insert(node, scope_); | 64 result_->scopes.Insert(node, scope_); |
| 64 } | 65 } |
| 65 | 66 |
| 66 | 67 |
| 67 void ScopeBuilder::ExitScope() { | 68 void ScopeBuilder::ExitScope(TokenPosition end_position) { |
| 69 scope_->set_end_token_pos(end_position); | |
| 68 scope_ = scope_->parent(); | 70 scope_ = scope_->parent(); |
| 69 } | 71 } |
| 70 | 72 |
| 71 | 73 |
| 72 LocalVariable* ScopeBuilder::MakeVariable(const dart::String& name, | 74 LocalVariable* ScopeBuilder::MakeVariable(TokenPosition declaration_pos, |
| 75 TokenPosition token_pos, | |
| 76 const dart::String& name, | |
| 73 const AbstractType& type) { | 77 const AbstractType& type) { |
| 74 return new (Z) LocalVariable(TokenPosition::kNoSource, | 78 return new (Z) LocalVariable(declaration_pos, token_pos, name, type); |
| 75 TokenPosition::kNoSource, name, type); | |
| 76 } | 79 } |
| 77 | 80 |
| 78 | 81 |
| 79 void ScopeBuilder::AddParameters(FunctionNode* function, intptr_t pos) { | 82 void ScopeBuilder::AddParameters(FunctionNode* function, intptr_t pos) { |
| 80 List<VariableDeclaration>& positional = function->positional_parameters(); | 83 List<VariableDeclaration>& positional = function->positional_parameters(); |
| 81 for (intptr_t i = 0; i < positional.length(); ++i) { | 84 for (intptr_t i = 0; i < positional.length(); ++i) { |
| 82 AddParameter(positional[i], pos++); | 85 AddParameter(positional[i], pos++); |
| 83 } | 86 } |
| 84 List<VariableDeclaration>& named = function->named_parameters(); | 87 List<VariableDeclaration>& named = function->named_parameters(); |
| 85 for (intptr_t i = 0; i < named.length(); ++i) { | 88 for (intptr_t i = 0; i < named.length(); ++i) { |
| 86 AddParameter(named[i], pos++); | 89 AddParameter(named[i], pos++); |
| 87 } | 90 } |
| 88 } | 91 } |
| 89 | 92 |
| 90 | 93 |
| 91 void ScopeBuilder::AddParameter(VariableDeclaration* declaration, | 94 void ScopeBuilder::AddParameter(VariableDeclaration* declaration, |
| 92 intptr_t pos) { | 95 intptr_t pos) { |
| 93 LocalVariable* variable = MakeVariable(H.DartSymbol(declaration->name()), | 96 LocalVariable* variable = MakeVariable( |
| 94 T.TranslateVariableType(declaration)); | 97 declaration->position(), declaration->position(), |
|
jensj
2017/01/13 10:14:44
This is different than before --- I haven't looked
| |
| 98 H.DartSymbol(declaration->name()), T.TranslateVariableType(declaration)); | |
| 95 if (declaration->IsFinal()) { | 99 if (declaration->IsFinal()) { |
| 96 variable->set_is_final(); | 100 variable->set_is_final(); |
| 97 } | 101 } |
| 98 scope_->InsertParameterAt(pos, variable); | 102 scope_->InsertParameterAt(pos, variable); |
| 99 result_->locals.Insert(declaration, variable); | 103 result_->locals.Insert(declaration, variable); |
| 100 | 104 |
| 101 // The default value may contain 'let' bindings for which the constant | 105 // The default value may contain 'let' bindings for which the constant |
| 102 // evaluator needs scope bindings. | 106 // evaluator needs scope bindings. |
| 103 Expression* defaultValue = declaration->initializer(); | 107 Expression* defaultValue = declaration->initializer(); |
| 104 if (defaultValue != NULL) { | 108 if (defaultValue != NULL) { |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 131 } | 135 } |
| 132 | 136 |
| 133 // No need to create variables for try/catch-statements inside | 137 // No need to create variables for try/catch-statements inside |
| 134 // nested functions. | 138 // nested functions. |
| 135 if (depth_.function_ > 0) return; | 139 if (depth_.function_ > 0) return; |
| 136 if (variables->length() >= nesting_depth) return; | 140 if (variables->length() >= nesting_depth) return; |
| 137 | 141 |
| 138 // If variable was not lifted by the transformer introduce a new | 142 // If variable was not lifted by the transformer introduce a new |
| 139 // one into the current function scope. | 143 // one into the current function scope. |
| 140 if (v == NULL) { | 144 if (v == NULL) { |
| 141 v = MakeVariable(GenerateName(prefix, nesting_depth - 1), | 145 v = MakeVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, |
| 146 GenerateName(prefix, nesting_depth - 1), | |
| 142 AbstractType::dynamic_type()); | 147 AbstractType::dynamic_type()); |
| 143 | 148 |
| 144 // If transformer did not lift the variable then there is no need | 149 // If transformer did not lift the variable then there is no need |
| 145 // to lift it into the context when we encouter a YieldStatement. | 150 // to lift it into the context when we encouter a YieldStatement. |
| 146 v->set_is_forced_stack(); | 151 v->set_is_forced_stack(); |
| 147 current_function_scope_->AddVariable(v); | 152 current_function_scope_->AddVariable(v); |
| 148 } | 153 } |
| 149 | 154 |
| 150 variables->Add(v); | 155 variables->Add(v); |
| 151 } | 156 } |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 164 depth_.catch_); | 169 depth_.catch_); |
| 165 } | 170 } |
| 166 | 171 |
| 167 | 172 |
| 168 void ScopeBuilder::AddIteratorVariable() { | 173 void ScopeBuilder::AddIteratorVariable() { |
| 169 if (depth_.function_ > 0) return; | 174 if (depth_.function_ > 0) return; |
| 170 if (result_->iterator_variables.length() >= depth_.for_in_) return; | 175 if (result_->iterator_variables.length() >= depth_.for_in_) return; |
| 171 | 176 |
| 172 ASSERT(result_->iterator_variables.length() == depth_.for_in_ - 1); | 177 ASSERT(result_->iterator_variables.length() == depth_.for_in_ - 1); |
| 173 LocalVariable* iterator = | 178 LocalVariable* iterator = |
| 174 MakeVariable(GenerateName(":iterator", depth_.for_in_ - 1), | 179 MakeVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, |
| 180 GenerateName(":iterator", depth_.for_in_ - 1), | |
| 175 AbstractType::dynamic_type()); | 181 AbstractType::dynamic_type()); |
| 176 current_function_scope_->AddVariable(iterator); | 182 current_function_scope_->AddVariable(iterator); |
| 177 result_->iterator_variables.Add(iterator); | 183 result_->iterator_variables.Add(iterator); |
| 178 } | 184 } |
| 179 | 185 |
| 180 | 186 |
| 181 void ScopeBuilder::LookupVariable(VariableDeclaration* declaration) { | 187 void ScopeBuilder::LookupVariable(VariableDeclaration* declaration) { |
| 182 LocalVariable* variable = result_->locals.Lookup(declaration); | 188 LocalVariable* variable = result_->locals.Lookup(declaration); |
| 183 if (variable == NULL) { | 189 if (variable == NULL) { |
| 184 // We have not seen a declaration of the variable, so it must be the | 190 // We have not seen a declaration of the variable, so it must be the |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 230 | 236 |
| 231 | 237 |
| 232 void ScopeBuilder::AddVariable(VariableDeclaration* declaration) { | 238 void ScopeBuilder::AddVariable(VariableDeclaration* declaration) { |
| 233 // In case `declaration->IsConst()` the flow graph building will take care of | 239 // In case `declaration->IsConst()` the flow graph building will take care of |
| 234 // evaluating the constant and setting it via | 240 // evaluating the constant and setting it via |
| 235 // `declaration->SetConstantValue()`. | 241 // `declaration->SetConstantValue()`. |
| 236 const dart::String& name = declaration->name()->is_empty() | 242 const dart::String& name = declaration->name()->is_empty() |
| 237 ? GenerateName(":var", name_index_++) | 243 ? GenerateName(":var", name_index_++) |
| 238 : H.DartSymbol(declaration->name()); | 244 : H.DartSymbol(declaration->name()); |
| 239 LocalVariable* variable = | 245 LocalVariable* variable = |
| 240 MakeVariable(name, T.TranslateVariableType(declaration)); | 246 MakeVariable(declaration->position(), declaration->end_position(), name, |
| 247 T.TranslateVariableType(declaration)); | |
| 241 if (declaration->IsFinal()) { | 248 if (declaration->IsFinal()) { |
| 242 variable->set_is_final(); | 249 variable->set_is_final(); |
| 243 } | 250 } |
| 244 scope_->AddVariable(variable); | 251 scope_->AddVariable(variable); |
| 245 result_->locals.Insert(declaration, variable); | 252 result_->locals.Insert(declaration, variable); |
| 246 } | 253 } |
| 247 | 254 |
| 248 | 255 |
| 249 static bool IsStaticInitializer(const Function& function, Zone* zone) { | 256 static bool IsStaticInitializer(const Function& function, Zone* zone) { |
| 250 return (function.kind() == RawFunction::kImplicitStaticFinalGetter) && | 257 return (function.kind() == RawFunction::kImplicitStaticFinalGetter) && |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 280 : NULL; | 287 : NULL; |
| 281 ActiveMemberScope active_member(&active_class_, member); | 288 ActiveMemberScope active_member(&active_class_, member); |
| 282 | 289 |
| 283 | 290 |
| 284 LocalScope* enclosing_scope = NULL; | 291 LocalScope* enclosing_scope = NULL; |
| 285 if (function.IsLocalFunction()) { | 292 if (function.IsLocalFunction()) { |
| 286 enclosing_scope = LocalScope::RestoreOuterScope( | 293 enclosing_scope = LocalScope::RestoreOuterScope( |
| 287 ContextScope::Handle(Z, function.context_scope())); | 294 ContextScope::Handle(Z, function.context_scope())); |
| 288 } | 295 } |
| 289 current_function_scope_ = scope_ = new (Z) LocalScope(enclosing_scope, 0, 0); | 296 current_function_scope_ = scope_ = new (Z) LocalScope(enclosing_scope, 0, 0); |
| 297 scope_->set_begin_token_pos(function.token_pos()); | |
| 298 scope_->set_end_token_pos(function.end_token_pos()); | |
| 290 | 299 |
| 291 LocalVariable* context_var = parsed_function->current_context_var(); | 300 LocalVariable* context_var = parsed_function->current_context_var(); |
| 292 context_var->set_is_forced_stack(); | 301 context_var->set_is_forced_stack(); |
| 293 scope_->AddVariable(context_var); | 302 scope_->AddVariable(context_var); |
| 294 scope_->AddVariable(parsed_function->EnsureExpressionTemp()); | 303 scope_->AddVariable(parsed_function->EnsureExpressionTemp()); |
| 295 | 304 |
| 296 parsed_function->SetNodeSequence( | 305 parsed_function->SetNodeSequence( |
| 297 new SequenceNode(TokenPosition::kNoSource, scope_)); | 306 new SequenceNode(TokenPosition::kNoSource, scope_)); |
| 298 | 307 |
| 299 switch (function.kind()) { | 308 switch (function.kind()) { |
| 300 case RawFunction::kClosureFunction: | 309 case RawFunction::kClosureFunction: |
| 301 case RawFunction::kRegularFunction: | 310 case RawFunction::kRegularFunction: |
| 302 case RawFunction::kGetterFunction: | 311 case RawFunction::kGetterFunction: |
| 303 case RawFunction::kSetterFunction: | 312 case RawFunction::kSetterFunction: |
| 304 case RawFunction::kConstructor: { | 313 case RawFunction::kConstructor: { |
| 305 FunctionNode* node; | 314 FunctionNode* node; |
| 306 if (node_->IsProcedure()) { | 315 if (node_->IsProcedure()) { |
| 307 node = Procedure::Cast(node_)->function(); | 316 node = Procedure::Cast(node_)->function(); |
| 308 } else if (node_->IsConstructor()) { | 317 } else if (node_->IsConstructor()) { |
| 309 node = Constructor::Cast(node_)->function(); | 318 node = Constructor::Cast(node_)->function(); |
| 310 } else { | 319 } else { |
| 311 node = FunctionNode::Cast(node_); | 320 node = FunctionNode::Cast(node_); |
| 312 } | 321 } |
| 313 current_function_node_ = node; | 322 current_function_node_ = node; |
| 314 | 323 |
| 315 intptr_t pos = 0; | 324 intptr_t pos = 0; |
| 316 if (function.IsClosureFunction()) { | 325 if (function.IsClosureFunction()) { |
| 317 LocalVariable* variable = MakeVariable(Symbols::ClosureParameter(), | 326 LocalVariable* variable = MakeVariable( |
| 318 AbstractType::dynamic_type()); | 327 TokenPosition::kNoSource, TokenPosition::kNoSource, |
| 328 Symbols::ClosureParameter(), AbstractType::dynamic_type()); | |
| 319 variable->set_is_forced_stack(); | 329 variable->set_is_forced_stack(); |
| 320 scope_->InsertParameterAt(pos++, variable); | 330 scope_->InsertParameterAt(pos++, variable); |
| 321 } else if (!function.is_static()) { | 331 } else if (!function.is_static()) { |
| 322 // We use [is_static] instead of [IsStaticFunction] because the latter | 332 // We use [is_static] instead of [IsStaticFunction] because the latter |
| 323 // returns `false` for constructors. | 333 // returns `false` for constructors. |
| 324 dart::Class& klass = dart::Class::Handle(Z, function.Owner()); | 334 dart::Class& klass = dart::Class::Handle(Z, function.Owner()); |
| 325 Type& klass_type = H.GetCanonicalType(klass); | 335 Type& klass_type = H.GetCanonicalType(klass); |
| 326 LocalVariable* variable = MakeVariable(Symbols::This(), klass_type); | 336 LocalVariable* variable = |
| 337 MakeVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, | |
| 338 Symbols::This(), klass_type); | |
| 327 scope_->InsertParameterAt(pos++, variable); | 339 scope_->InsertParameterAt(pos++, variable); |
| 328 result_->this_variable = variable; | 340 result_->this_variable = variable; |
| 329 | 341 |
| 330 // We visit instance field initializers because they might contain | 342 // We visit instance field initializers because they might contain |
| 331 // [Let] expressions and we need to have a mapping. | 343 // [Let] expressions and we need to have a mapping. |
| 332 if (node_->IsConstructor()) { | 344 if (node_->IsConstructor()) { |
| 333 Class* klass = Class::Cast(Constructor::Cast(node_)->parent()); | 345 Class* klass = Class::Cast(Constructor::Cast(node_)->parent()); |
| 334 | 346 |
| 335 for (intptr_t i = 0; i < klass->fields().length(); i++) { | 347 for (intptr_t i = 0; i < klass->fields().length(); i++) { |
| 336 Field* field = klass->fields()[i]; | 348 Field* field = klass->fields()[i]; |
| 337 if (!field->IsStatic() && (field->initializer() != NULL)) { | 349 if (!field->IsStatic() && (field->initializer() != NULL)) { |
| 338 EnterScope(field); | 350 EnterScope(field, field->position()); |
| 339 field->initializer()->AcceptExpressionVisitor(this); | 351 field->initializer()->AcceptExpressionVisitor(this); |
| 340 ExitScope(); | 352 ExitScope(field->end_position()); |
| 341 } | 353 } |
| 342 } | 354 } |
| 343 } | 355 } |
| 344 } else if (function.IsFactory()) { | 356 } else if (function.IsFactory()) { |
| 345 LocalVariable* variable = MakeVariable( | 357 LocalVariable* variable = MakeVariable( |
| 358 TokenPosition::kNoSource, TokenPosition::kNoSource, | |
| 346 Symbols::TypeArgumentsParameter(), AbstractType::dynamic_type()); | 359 Symbols::TypeArgumentsParameter(), AbstractType::dynamic_type()); |
| 347 scope_->InsertParameterAt(pos++, variable); | 360 scope_->InsertParameterAt(pos++, variable); |
| 348 result_->type_arguments_variable = variable; | 361 result_->type_arguments_variable = variable; |
| 349 } | 362 } |
| 350 AddParameters(node, pos); | 363 AddParameters(node, pos); |
| 351 | 364 |
| 352 // We generate a syntethic body for implicit closure functions - which | 365 // We generate a syntethic body for implicit closure functions - which |
| 353 // will forward the call to the real function. | 366 // will forward the call to the real function. |
| 354 // -> see BuildGraphOfImplicitClosureFunction | 367 // -> see BuildGraphOfImplicitClosureFunction |
| 355 if (!function.IsImplicitClosureFunction()) { | 368 if (!function.IsImplicitClosureFunction()) { |
| 356 node_->AcceptVisitor(this); | 369 node_->AcceptVisitor(this); |
| 357 } | 370 } |
| 358 break; | 371 break; |
| 359 } | 372 } |
| 360 case RawFunction::kImplicitGetter: | 373 case RawFunction::kImplicitGetter: |
| 361 case RawFunction::kImplicitStaticFinalGetter: | 374 case RawFunction::kImplicitStaticFinalGetter: |
| 362 case RawFunction::kImplicitSetter: { | 375 case RawFunction::kImplicitSetter: { |
| 363 ASSERT(node_->IsField()); | 376 ASSERT(node_->IsField()); |
| 364 if (IsStaticInitializer(function, Z)) { | 377 if (IsStaticInitializer(function, Z)) { |
| 365 node_->AcceptVisitor(this); | 378 node_->AcceptVisitor(this); |
| 366 break; | 379 break; |
| 367 } | 380 } |
| 368 bool is_setter = function.IsImplicitSetterFunction(); | 381 bool is_setter = function.IsImplicitSetterFunction(); |
| 369 bool is_method = !function.IsStaticFunction(); | 382 bool is_method = !function.IsStaticFunction(); |
| 370 intptr_t pos = 0; | 383 intptr_t pos = 0; |
| 371 if (is_method) { | 384 if (is_method) { |
| 372 dart::Class& klass = dart::Class::Handle(Z, function.Owner()); | 385 dart::Class& klass = dart::Class::Handle(Z, function.Owner()); |
| 373 Type& klass_type = H.GetCanonicalType(klass); | 386 Type& klass_type = H.GetCanonicalType(klass); |
| 374 LocalVariable* variable = MakeVariable(Symbols::This(), klass_type); | 387 LocalVariable* variable = |
| 388 MakeVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, | |
| 389 Symbols::This(), klass_type); | |
| 375 scope_->InsertParameterAt(pos++, variable); | 390 scope_->InsertParameterAt(pos++, variable); |
| 376 result_->this_variable = variable; | 391 result_->this_variable = variable; |
| 377 } | 392 } |
| 378 if (is_setter) { | 393 if (is_setter) { |
| 379 result_->setter_value = | 394 result_->setter_value = |
| 380 MakeVariable(Symbols::Value(), AbstractType::dynamic_type()); | 395 MakeVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, |
| 396 Symbols::Value(), AbstractType::dynamic_type()); | |
| 381 scope_->InsertParameterAt(pos++, result_->setter_value); | 397 scope_->InsertParameterAt(pos++, result_->setter_value); |
| 382 } | 398 } |
| 383 break; | 399 break; |
| 384 } | 400 } |
| 385 case RawFunction::kMethodExtractor: { | 401 case RawFunction::kMethodExtractor: { |
| 386 // Add a receiver parameter. Though it is captured, we emit code to | 402 // Add a receiver parameter. Though it is captured, we emit code to |
| 387 // explicitly copy it to a fixed offset in a freshly-allocated context | 403 // explicitly copy it to a fixed offset in a freshly-allocated context |
| 388 // instead of using the generic code for regular functions. | 404 // instead of using the generic code for regular functions. |
| 389 // Therefore, it isn't necessary to mark it as captured here. | 405 // Therefore, it isn't necessary to mark it as captured here. |
| 390 dart::Class& klass = dart::Class::Handle(Z, function.Owner()); | 406 dart::Class& klass = dart::Class::Handle(Z, function.Owner()); |
| 391 Type& klass_type = H.GetCanonicalType(klass); | 407 Type& klass_type = H.GetCanonicalType(klass); |
| 392 LocalVariable* variable = MakeVariable(Symbols::This(), klass_type); | 408 LocalVariable* variable = |
| 409 MakeVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, | |
| 410 Symbols::This(), klass_type); | |
| 393 scope_->InsertParameterAt(0, variable); | 411 scope_->InsertParameterAt(0, variable); |
| 394 result_->this_variable = variable; | 412 result_->this_variable = variable; |
| 395 break; | 413 break; |
| 396 } | 414 } |
| 397 case RawFunction::kNoSuchMethodDispatcher: | 415 case RawFunction::kNoSuchMethodDispatcher: |
| 398 case RawFunction::kInvokeFieldDispatcher: | 416 case RawFunction::kInvokeFieldDispatcher: |
| 399 for (intptr_t i = 0; i < function.NumParameters(); ++i) { | 417 for (intptr_t i = 0; i < function.NumParameters(); ++i) { |
| 400 LocalVariable* variable = MakeVariable( | 418 LocalVariable* variable = MakeVariable( |
| 419 TokenPosition::kNoSource, TokenPosition::kNoSource, | |
| 401 dart::String::ZoneHandle(Z, function.ParameterNameAt(i)), | 420 dart::String::ZoneHandle(Z, function.ParameterNameAt(i)), |
| 402 AbstractType::dynamic_type()); | 421 AbstractType::dynamic_type()); |
| 403 scope_->InsertParameterAt(i, variable); | 422 scope_->InsertParameterAt(i, variable); |
| 404 } | 423 } |
| 405 break; | 424 break; |
| 406 case RawFunction::kSignatureFunction: | 425 case RawFunction::kSignatureFunction: |
| 407 case RawFunction::kIrregexpFunction: | 426 case RawFunction::kIrregexpFunction: |
| 408 UNREACHABLE(); | 427 UNREACHABLE(); |
| 409 } | 428 } |
| 410 | 429 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 448 node->VisitChildren(this); | 467 node->VisitChildren(this); |
| 449 } | 468 } |
| 450 | 469 |
| 451 | 470 |
| 452 void ScopeBuilder::HandleLocalFunction(TreeNode* parent, | 471 void ScopeBuilder::HandleLocalFunction(TreeNode* parent, |
| 453 FunctionNode* function) { | 472 FunctionNode* function) { |
| 454 LocalScope* saved_function_scope = current_function_scope_; | 473 LocalScope* saved_function_scope = current_function_scope_; |
| 455 FunctionNode* saved_function_node = current_function_node_; | 474 FunctionNode* saved_function_node = current_function_node_; |
| 456 ScopeBuilder::DepthState saved_depth_state = depth_; | 475 ScopeBuilder::DepthState saved_depth_state = depth_; |
| 457 depth_ = DepthState(depth_.function_ + 1); | 476 depth_ = DepthState(depth_.function_ + 1); |
| 458 EnterScope(parent); | 477 EnterScope(parent, function->position()); |
| 459 current_function_scope_ = scope_; | 478 current_function_scope_ = scope_; |
| 460 current_function_node_ = function; | 479 current_function_node_ = function; |
| 461 if (depth_.function_ == 1) { | 480 if (depth_.function_ == 1) { |
| 462 FunctionScope function_scope = {function, scope_}; | 481 FunctionScope function_scope = {function, scope_}; |
| 463 result_->function_scopes.Add(function_scope); | 482 result_->function_scopes.Add(function_scope); |
| 464 } | 483 } |
| 465 AddParameters(function); | 484 AddParameters(function); |
| 466 VisitFunctionNode(function); | 485 VisitFunctionNode(function); |
| 467 ExitScope(); | 486 ExitScope(function->end_position()); |
| 468 depth_ = saved_depth_state; | 487 depth_ = saved_depth_state; |
| 469 current_function_scope_ = saved_function_scope; | 488 current_function_scope_ = saved_function_scope; |
| 470 current_function_node_ = saved_function_node; | 489 current_function_node_ = saved_function_node; |
| 471 } | 490 } |
| 472 | 491 |
| 473 | 492 |
| 474 void ScopeBuilder::HandleSpecialLoad(LocalVariable** variable, | 493 void ScopeBuilder::HandleSpecialLoad(LocalVariable** variable, |
| 475 const dart::String& symbol) { | 494 const dart::String& symbol) { |
| 476 if (current_function_scope_->parent() != NULL) { | 495 if (current_function_scope_->parent() != NULL) { |
| 477 // We are building the scope tree of a closure function and saw [node]. We | 496 // We are building the scope tree of a closure function and saw [node]. We |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 492 } | 511 } |
| 493 } | 512 } |
| 494 | 513 |
| 495 | 514 |
| 496 void ScopeBuilder::VisitFunctionExpression(FunctionExpression* node) { | 515 void ScopeBuilder::VisitFunctionExpression(FunctionExpression* node) { |
| 497 HandleLocalFunction(node, node->function()); | 516 HandleLocalFunction(node, node->function()); |
| 498 } | 517 } |
| 499 | 518 |
| 500 | 519 |
| 501 void ScopeBuilder::VisitLet(Let* node) { | 520 void ScopeBuilder::VisitLet(Let* node) { |
| 502 EnterScope(node); | 521 EnterScope(node, node->position()); |
| 503 node->VisitChildren(this); | 522 node->VisitChildren(this); |
| 504 ExitScope(); | 523 ExitScope(node->end_position()); |
| 505 } | 524 } |
| 506 | 525 |
| 507 | 526 |
| 508 void ScopeBuilder::VisitBlock(Block* node) { | 527 void ScopeBuilder::VisitBlock(Block* node) { |
| 509 EnterScope(node); | 528 EnterScope(node, node->position()); |
| 510 node->VisitChildren(this); | 529 node->VisitChildren(this); |
| 511 ExitScope(); | 530 ExitScope(node->end_position()); |
| 512 } | 531 } |
| 513 | 532 |
| 514 | 533 |
| 515 void ScopeBuilder::VisitVariableDeclaration(VariableDeclaration* node) { | 534 void ScopeBuilder::VisitVariableDeclaration(VariableDeclaration* node) { |
| 516 AddVariable(node); | 535 AddVariable(node); |
| 517 node->VisitChildren(this); | 536 node->VisitChildren(this); |
| 518 } | 537 } |
| 519 | 538 |
| 520 | 539 |
| 521 void ScopeBuilder::VisitFunctionDeclaration(FunctionDeclaration* node) { | 540 void ScopeBuilder::VisitFunctionDeclaration(FunctionDeclaration* node) { |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 532 | 551 |
| 533 | 552 |
| 534 void ScopeBuilder::VisitDoStatement(DoStatement* node) { | 553 void ScopeBuilder::VisitDoStatement(DoStatement* node) { |
| 535 ++depth_.loop_; | 554 ++depth_.loop_; |
| 536 node->VisitChildren(this); | 555 node->VisitChildren(this); |
| 537 --depth_.loop_; | 556 --depth_.loop_; |
| 538 } | 557 } |
| 539 | 558 |
| 540 | 559 |
| 541 void ScopeBuilder::VisitForStatement(ForStatement* node) { | 560 void ScopeBuilder::VisitForStatement(ForStatement* node) { |
| 542 EnterScope(node); | 561 EnterScope(node, node->position()); |
| 543 List<VariableDeclaration>& variables = node->variables(); | 562 List<VariableDeclaration>& variables = node->variables(); |
| 544 for (intptr_t i = 0; i < variables.length(); ++i) { | 563 for (intptr_t i = 0; i < variables.length(); ++i) { |
| 545 VisitVariableDeclaration(variables[i]); | 564 VisitVariableDeclaration(variables[i]); |
| 546 } | 565 } |
| 547 ++depth_.loop_; | 566 ++depth_.loop_; |
| 548 if (node->condition() != NULL) { | 567 if (node->condition() != NULL) { |
| 549 node->condition()->AcceptExpressionVisitor(this); | 568 node->condition()->AcceptExpressionVisitor(this); |
| 550 } | 569 } |
| 551 node->body()->AcceptStatementVisitor(this); | 570 node->body()->AcceptStatementVisitor(this); |
| 552 List<Expression>& updates = node->updates(); | 571 List<Expression>& updates = node->updates(); |
| 553 for (intptr_t i = 0; i < updates.length(); ++i) { | 572 for (intptr_t i = 0; i < updates.length(); ++i) { |
| 554 updates[i]->AcceptExpressionVisitor(this); | 573 updates[i]->AcceptExpressionVisitor(this); |
| 555 } | 574 } |
| 556 --depth_.loop_; | 575 --depth_.loop_; |
| 557 ExitScope(); | 576 ExitScope(node->end_position()); |
| 558 } | 577 } |
| 559 | 578 |
| 560 | 579 |
| 561 void ScopeBuilder::VisitForInStatement(ForInStatement* node) { | 580 void ScopeBuilder::VisitForInStatement(ForInStatement* node) { |
| 562 node->iterable()->AcceptExpressionVisitor(this); | 581 node->iterable()->AcceptExpressionVisitor(this); |
| 563 ++depth_.for_in_; | 582 ++depth_.for_in_; |
| 564 AddIteratorVariable(); | 583 AddIteratorVariable(); |
| 565 ++depth_.loop_; | 584 ++depth_.loop_; |
| 566 EnterScope(node); | 585 EnterScope(node, node->position()); |
| 567 VisitVariableDeclaration(node->variable()); | 586 VisitVariableDeclaration(node->variable()); |
| 568 node->body()->AcceptStatementVisitor(this); | 587 node->body()->AcceptStatementVisitor(this); |
| 569 ExitScope(); | 588 ExitScope(node->end_position()); |
| 570 --depth_.loop_; | 589 --depth_.loop_; |
| 571 --depth_.for_in_; | 590 --depth_.for_in_; |
| 572 } | 591 } |
| 573 | 592 |
| 574 | 593 |
| 575 void ScopeBuilder::AddSwitchVariable() { | 594 void ScopeBuilder::AddSwitchVariable() { |
| 576 if ((depth_.function_ == 0) && (result_->switch_variable == NULL)) { | 595 if ((depth_.function_ == 0) && (result_->switch_variable == NULL)) { |
| 577 LocalVariable* variable = | 596 LocalVariable* variable = |
| 578 MakeVariable(Symbols::SwitchExpr(), AbstractType::dynamic_type()); | 597 MakeVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, |
| 598 Symbols::SwitchExpr(), AbstractType::dynamic_type()); | |
| 579 variable->set_is_forced_stack(); | 599 variable->set_is_forced_stack(); |
| 580 current_function_scope_->AddVariable(variable); | 600 current_function_scope_->AddVariable(variable); |
| 581 result_->switch_variable = variable; | 601 result_->switch_variable = variable; |
| 582 } | 602 } |
| 583 } | 603 } |
| 584 | 604 |
| 585 | 605 |
| 586 void ScopeBuilder::VisitSwitchStatement(SwitchStatement* node) { | 606 void ScopeBuilder::VisitSwitchStatement(SwitchStatement* node) { |
| 587 AddSwitchVariable(); | 607 AddSwitchVariable(); |
| 588 node->VisitChildren(this); | 608 node->VisitChildren(this); |
| 589 } | 609 } |
| 590 | 610 |
| 591 | 611 |
| 592 void ScopeBuilder::VisitReturnStatement(ReturnStatement* node) { | 612 void ScopeBuilder::VisitReturnStatement(ReturnStatement* node) { |
| 593 if ((depth_.function_ == 0) && (depth_.finally_ > 0) && | 613 if ((depth_.function_ == 0) && (depth_.finally_ > 0) && |
| 594 (result_->finally_return_variable == NULL)) { | 614 (result_->finally_return_variable == NULL)) { |
| 595 const dart::String& name = H.DartSymbol(":try_finally_return_value"); | 615 const dart::String& name = H.DartSymbol(":try_finally_return_value"); |
| 596 LocalVariable* variable = MakeVariable(name, AbstractType::dynamic_type()); | 616 LocalVariable* variable = |
| 617 MakeVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, name, | |
| 618 AbstractType::dynamic_type()); | |
| 597 current_function_scope_->AddVariable(variable); | 619 current_function_scope_->AddVariable(variable); |
| 598 result_->finally_return_variable = variable; | 620 result_->finally_return_variable = variable; |
| 599 } | 621 } |
| 600 node->VisitChildren(this); | 622 node->VisitChildren(this); |
| 601 } | 623 } |
| 602 | 624 |
| 603 | 625 |
| 604 void ScopeBuilder::VisitTryCatch(TryCatch* node) { | 626 void ScopeBuilder::VisitTryCatch(TryCatch* node) { |
| 605 ++depth_.try_; | 627 ++depth_.try_; |
| 606 AddTryVariables(); | 628 AddTryVariables(); |
| 607 node->body()->AcceptStatementVisitor(this); | 629 node->body()->AcceptStatementVisitor(this); |
| 608 --depth_.try_; | 630 --depth_.try_; |
| 609 | 631 |
| 610 ++depth_.catch_; | 632 ++depth_.catch_; |
| 611 AddCatchVariables(); | 633 AddCatchVariables(); |
| 612 List<Catch>& catches = node->catches(); | 634 List<Catch>& catches = node->catches(); |
| 613 for (intptr_t i = 0; i < catches.length(); ++i) { | 635 for (intptr_t i = 0; i < catches.length(); ++i) { |
| 614 Catch* ketch = catches[i]; | 636 Catch* ketch = catches[i]; |
| 615 EnterScope(ketch); | 637 EnterScope(ketch, ketch->position()); |
| 616 if (ketch->exception() != NULL) { | 638 if (ketch->exception() != NULL) { |
| 617 VisitVariableDeclaration(ketch->exception()); | 639 VisitVariableDeclaration(ketch->exception()); |
| 618 } | 640 } |
| 619 if (ketch->stack_trace() != NULL) { | 641 if (ketch->stack_trace() != NULL) { |
| 620 VisitVariableDeclaration(ketch->stack_trace()); | 642 VisitVariableDeclaration(ketch->stack_trace()); |
| 621 } | 643 } |
| 622 ketch->body()->AcceptStatementVisitor(this); | 644 ketch->body()->AcceptStatementVisitor(this); |
| 623 ExitScope(); | 645 ExitScope(ketch->end_position()); |
| 624 } | 646 } |
| 625 --depth_.catch_; | 647 --depth_.catch_; |
| 626 } | 648 } |
| 627 | 649 |
| 628 | 650 |
| 629 void ScopeBuilder::VisitTryFinally(TryFinally* node) { | 651 void ScopeBuilder::VisitTryFinally(TryFinally* node) { |
| 630 ++depth_.try_; | 652 ++depth_.try_; |
| 631 ++depth_.finally_; | 653 ++depth_.finally_; |
| 632 AddTryVariables(); | 654 AddTryVariables(); |
| 633 node->body()->AcceptStatementVisitor(this); | 655 node->body()->AcceptStatementVisitor(this); |
| (...skipping 1349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1983 } | 2005 } |
| 1984 return instructions; | 2006 return instructions; |
| 1985 } | 2007 } |
| 1986 | 2008 |
| 1987 | 2009 |
| 1988 Fragment FlowGraphBuilder::AdjustContextTo(int depth) { | 2010 Fragment FlowGraphBuilder::AdjustContextTo(int depth) { |
| 1989 ASSERT(depth <= context_depth_ && depth >= 0); | 2011 ASSERT(depth <= context_depth_ && depth >= 0); |
| 1990 Fragment instructions; | 2012 Fragment instructions; |
| 1991 if (depth < context_depth_) { | 2013 if (depth < context_depth_) { |
| 1992 instructions += LoadContextAt(depth); | 2014 instructions += LoadContextAt(depth); |
| 1993 instructions += StoreLocal(parsed_function_->current_context_var()); | 2015 instructions += StoreLocal(TokenPosition::kNoSource, |
| 2016 parsed_function_->current_context_var()); | |
| 1994 instructions += Drop(); | 2017 instructions += Drop(); |
| 1995 context_depth_ = depth; | 2018 context_depth_ = depth; |
| 1996 } | 2019 } |
| 1997 return instructions; | 2020 return instructions; |
| 1998 } | 2021 } |
| 1999 | 2022 |
| 2000 | 2023 |
| 2001 Fragment FlowGraphBuilder::PushContext(int size) { | 2024 Fragment FlowGraphBuilder::PushContext(int size) { |
| 2002 ASSERT(size > 0); | 2025 ASSERT(size > 0); |
| 2003 Fragment instructions = AllocateContext(size); | 2026 Fragment instructions = AllocateContext(size); |
| 2004 LocalVariable* context = MakeTemporary(); | 2027 LocalVariable* context = MakeTemporary(); |
| 2005 instructions += LoadLocal(context); | 2028 instructions += LoadLocal(context); |
| 2006 instructions += LoadLocal(parsed_function_->current_context_var()); | 2029 instructions += LoadLocal(parsed_function_->current_context_var()); |
| 2007 instructions += StoreInstanceField(Context::parent_offset()); | 2030 instructions += StoreInstanceField(Context::parent_offset()); |
| 2008 instructions += StoreLocal(parsed_function_->current_context_var()); | 2031 instructions += StoreLocal(TokenPosition::kNoSource, |
| 2032 parsed_function_->current_context_var()); | |
| 2009 ++context_depth_; | 2033 ++context_depth_; |
| 2010 return instructions; | 2034 return instructions; |
| 2011 } | 2035 } |
| 2012 | 2036 |
| 2013 | 2037 |
| 2014 Fragment FlowGraphBuilder::PopContext() { | 2038 Fragment FlowGraphBuilder::PopContext() { |
| 2015 return AdjustContextTo(context_depth_ - 1); | 2039 return AdjustContextTo(context_depth_ - 1); |
| 2016 } | 2040 } |
| 2017 | 2041 |
| 2018 | 2042 |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2198 // :saved_try_context_var can be captured in the context of | 2222 // :saved_try_context_var can be captured in the context of |
| 2199 // of the closure, in this case CatchBlockEntryInstr restores | 2223 // of the closure, in this case CatchBlockEntryInstr restores |
| 2200 // :current_context_var to point to closure context in the | 2224 // :current_context_var to point to closure context in the |
| 2201 // same way as normal function prologue does. | 2225 // same way as normal function prologue does. |
| 2202 // Update current context depth to reflect that. | 2226 // Update current context depth to reflect that. |
| 2203 const intptr_t saved_context_depth = context_depth_; | 2227 const intptr_t saved_context_depth = context_depth_; |
| 2204 ASSERT(!CurrentCatchContext()->is_captured() || | 2228 ASSERT(!CurrentCatchContext()->is_captured() || |
| 2205 CurrentCatchContext()->owner()->context_level() == 0); | 2229 CurrentCatchContext()->owner()->context_level() == 0); |
| 2206 context_depth_ = 0; | 2230 context_depth_ = 0; |
| 2207 instructions += LoadLocal(CurrentCatchContext()); | 2231 instructions += LoadLocal(CurrentCatchContext()); |
| 2208 instructions += StoreLocal(parsed_function_->current_context_var()); | 2232 instructions += StoreLocal(TokenPosition::kNoSource, |
| 2233 parsed_function_->current_context_var()); | |
| 2209 instructions += Drop(); | 2234 instructions += Drop(); |
| 2210 context_depth_ = saved_context_depth; | 2235 context_depth_ = saved_context_depth; |
| 2211 | 2236 |
| 2212 return instructions; | 2237 return instructions; |
| 2213 } | 2238 } |
| 2214 | 2239 |
| 2215 | 2240 |
| 2216 Fragment FlowGraphBuilder::TryCatch(int try_handler_index) { | 2241 Fragment FlowGraphBuilder::TryCatch(int try_handler_index) { |
| 2217 // The body of the try needs to have it's own block in order to get a new try | 2242 // The body of the try needs to have it's own block in order to get a new try |
| 2218 // index. | 2243 // index. |
| 2219 // | 2244 // |
| 2220 // => We therefore create a block for the body (fresh try index) and another | 2245 // => We therefore create a block for the body (fresh try index) and another |
| 2221 // join block (with current try index). | 2246 // join block (with current try index). |
| 2222 Fragment body; | 2247 Fragment body; |
| 2223 JoinEntryInstr* entry = | 2248 JoinEntryInstr* entry = |
| 2224 new (Z) JoinEntryInstr(AllocateBlockId(), try_handler_index); | 2249 new (Z) JoinEntryInstr(AllocateBlockId(), try_handler_index); |
| 2225 body += LoadLocal(parsed_function_->current_context_var()); | 2250 body += LoadLocal(parsed_function_->current_context_var()); |
| 2226 body += StoreLocal(CurrentCatchContext()); | 2251 body += StoreLocal(TokenPosition::kNoSource, CurrentCatchContext()); |
| 2227 body += Drop(); | 2252 body += Drop(); |
| 2228 body += Goto(entry); | 2253 body += Goto(entry); |
| 2229 return Fragment(body.entry, entry); | 2254 return Fragment(body.entry, entry); |
| 2230 } | 2255 } |
| 2231 | 2256 |
| 2232 | 2257 |
| 2233 Fragment FlowGraphBuilder::CheckStackOverflowInPrologue() { | 2258 Fragment FlowGraphBuilder::CheckStackOverflowInPrologue() { |
| 2234 if (IsInlining()) { | 2259 if (IsInlining()) { |
| 2235 // If we are inlining don't actually attach the stack check. We must still | 2260 // If we are inlining don't actually attach the stack check. We must still |
| 2236 // create the stack check in order to allocate a deopt id. | 2261 // create the stack check in order to allocate a deopt id. |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 2250 Fragment FlowGraphBuilder::CloneContext() { | 2275 Fragment FlowGraphBuilder::CloneContext() { |
| 2251 LocalVariable* context_variable = parsed_function_->current_context_var(); | 2276 LocalVariable* context_variable = parsed_function_->current_context_var(); |
| 2252 | 2277 |
| 2253 Fragment instructions = LoadLocal(context_variable); | 2278 Fragment instructions = LoadLocal(context_variable); |
| 2254 | 2279 |
| 2255 CloneContextInstr* clone_instruction = | 2280 CloneContextInstr* clone_instruction = |
| 2256 new (Z) CloneContextInstr(TokenPosition::kNoSource, Pop()); | 2281 new (Z) CloneContextInstr(TokenPosition::kNoSource, Pop()); |
| 2257 instructions <<= clone_instruction; | 2282 instructions <<= clone_instruction; |
| 2258 Push(clone_instruction); | 2283 Push(clone_instruction); |
| 2259 | 2284 |
| 2260 instructions += StoreLocal(context_variable); | 2285 instructions += StoreLocal(TokenPosition::kNoSource, context_variable); |
| 2261 instructions += Drop(); | 2286 instructions += Drop(); |
| 2262 return instructions; | 2287 return instructions; |
| 2263 } | 2288 } |
| 2264 | 2289 |
| 2265 | 2290 |
| 2266 Fragment FlowGraphBuilder::Constant(const Object& value) { | 2291 Fragment FlowGraphBuilder::Constant(const Object& value) { |
| 2267 ASSERT(value.IsNotTemporaryScopedHandle()); | 2292 ASSERT(value.IsNotTemporaryScopedHandle()); |
| 2268 ConstantInstr* constant = new (Z) ConstantInstr(value); | 2293 ConstantInstr* constant = new (Z) ConstantInstr(value); |
| 2269 Push(constant); | 2294 Push(constant); |
| 2270 return Fragment(constant); | 2295 return Fragment(constant); |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2460 PushArgumentInstr* argument = new (Z) PushArgumentInstr(Pop()); | 2485 PushArgumentInstr* argument = new (Z) PushArgumentInstr(Pop()); |
| 2461 Push(argument); | 2486 Push(argument); |
| 2462 | 2487 |
| 2463 argument->set_temp_index(argument->temp_index() - 1); | 2488 argument->set_temp_index(argument->temp_index() - 1); |
| 2464 ++pending_argument_count_; | 2489 ++pending_argument_count_; |
| 2465 | 2490 |
| 2466 return Fragment(argument); | 2491 return Fragment(argument); |
| 2467 } | 2492 } |
| 2468 | 2493 |
| 2469 | 2494 |
| 2470 Fragment FlowGraphBuilder::Return() { | 2495 Fragment FlowGraphBuilder::Return(TokenPosition position) { |
| 2471 Value* value = Pop(); | 2496 Value* value = Pop(); |
| 2472 ASSERT(stack_ == NULL); | 2497 ASSERT(stack_ == NULL); |
| 2473 ReturnInstr* return_instr = | 2498 ReturnInstr* return_instr = |
| 2474 new (Z) ReturnInstr(TokenPosition::kNoSource, value); | 2499 new (Z) ReturnInstr(TokenPosition::kNoSource, value); |
| 2475 if (exit_collector_ != NULL) exit_collector_->AddExit(return_instr); | 2500 if (exit_collector_ != NULL) exit_collector_->AddExit(return_instr); |
| 2476 return Fragment(return_instr).closed(); | 2501 return Fragment(return_instr).closed(); |
| 2477 } | 2502 } |
| 2478 | 2503 |
| 2479 | 2504 |
| 2480 Fragment FlowGraphBuilder::StaticCall(TokenPosition position, | 2505 Fragment FlowGraphBuilder::StaticCall(TokenPosition position, |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2575 Value* value = Pop(); | 2600 Value* value = Pop(); |
| 2576 if (value->BindsToConstant()) { | 2601 if (value->BindsToConstant()) { |
| 2577 emit_store_barrier = kNoStoreBarrier; | 2602 emit_store_barrier = kNoStoreBarrier; |
| 2578 } | 2603 } |
| 2579 StoreInstanceFieldInstr* store = new (Z) StoreInstanceFieldInstr( | 2604 StoreInstanceFieldInstr* store = new (Z) StoreInstanceFieldInstr( |
| 2580 offset, Pop(), value, emit_store_barrier, TokenPosition::kNoSource); | 2605 offset, Pop(), value, emit_store_barrier, TokenPosition::kNoSource); |
| 2581 return Fragment(store); | 2606 return Fragment(store); |
| 2582 } | 2607 } |
| 2583 | 2608 |
| 2584 | 2609 |
| 2585 Fragment FlowGraphBuilder::StoreLocal(LocalVariable* variable) { | 2610 Fragment FlowGraphBuilder::StoreLocal(TokenPosition position, |
| 2611 LocalVariable* variable) { | |
| 2586 Fragment instructions; | 2612 Fragment instructions; |
| 2587 if (variable->is_captured()) { | 2613 if (variable->is_captured()) { |
| 2588 LocalVariable* value = MakeTemporary(); | 2614 LocalVariable* value = MakeTemporary(); |
| 2589 instructions += LoadContextAt(variable->owner()->context_level()); | 2615 instructions += LoadContextAt(variable->owner()->context_level()); |
| 2590 instructions += LoadLocal(value); | 2616 instructions += LoadLocal(value); |
| 2591 instructions += | 2617 instructions += |
| 2592 StoreInstanceField(Context::variable_offset(variable->index())); | 2618 StoreInstanceField(Context::variable_offset(variable->index())); |
| 2593 } else { | 2619 } else { |
| 2620 Value* value = Pop(); | |
| 2594 StoreLocalInstr* store = | 2621 StoreLocalInstr* store = |
| 2595 new (Z) StoreLocalInstr(*variable, Pop(), TokenPosition::kNoSource); | 2622 new (Z) StoreLocalInstr(*variable, value, position); |
| 2596 instructions <<= store; | 2623 instructions <<= store; |
| 2597 Push(store); | 2624 Push(store); |
| 2598 } | 2625 } |
| 2599 return instructions; | 2626 return instructions; |
| 2600 } | 2627 } |
| 2601 | 2628 |
| 2602 | 2629 |
| 2603 Fragment FlowGraphBuilder::StoreStaticField(const dart::Field& field) { | 2630 Fragment FlowGraphBuilder::StoreStaticField(const dart::Field& field) { |
| 2604 return Fragment(new (Z) StoreStaticFieldInstr(MayCloneField(Z, field), Pop(), | 2631 return Fragment(new (Z) StoreStaticFieldInstr(MayCloneField(Z, field), Pop(), |
| 2605 TokenPosition::kNoSource)); | 2632 TokenPosition::kNoSource)); |
| 2606 } | 2633 } |
| 2607 | 2634 |
| 2608 | 2635 |
| 2609 Fragment FlowGraphBuilder::StringInterpolate() { | 2636 Fragment FlowGraphBuilder::StringInterpolate(TokenPosition position) { |
| 2610 Value* array = Pop(); | 2637 Value* array = Pop(); |
| 2611 StringInterpolateInstr* interpolate = | 2638 StringInterpolateInstr* interpolate = |
| 2612 new (Z) StringInterpolateInstr(array, TokenPosition::kNoSource); | 2639 new (Z) StringInterpolateInstr(array, position); |
| 2613 Push(interpolate); | 2640 Push(interpolate); |
| 2614 return Fragment(interpolate); | 2641 return Fragment(interpolate); |
| 2615 } | 2642 } |
| 2616 | 2643 |
| 2617 | 2644 |
| 2618 Fragment FlowGraphBuilder::ThrowTypeError() { | 2645 Fragment FlowGraphBuilder::ThrowTypeError() { |
| 2619 const dart::Class& klass = dart::Class::ZoneHandle( | 2646 const dart::Class& klass = dart::Class::ZoneHandle( |
| 2620 Z, dart::Library::LookupCoreClass(Symbols::TypeError())); | 2647 Z, dart::Library::LookupCoreClass(Symbols::TypeError())); |
| 2621 ASSERT(!klass.IsNull()); | 2648 ASSERT(!klass.IsNull()); |
| 2622 const dart::Function& constructor = dart::Function::ZoneHandle( | 2649 const dart::Function& constructor = dart::Function::ZoneHandle( |
| (...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2968 // try/catch. | 2995 // try/catch. |
| 2969 parameter->set_is_captured_parameter(true); | 2996 parameter->set_is_captured_parameter(true); |
| 2970 | 2997 |
| 2971 // Copy the parameter from the stack to the context. Overwrite it | 2998 // Copy the parameter from the stack to the context. Overwrite it |
| 2972 // with a null constant on the stack so the original value is | 2999 // with a null constant on the stack so the original value is |
| 2973 // eligible for garbage collection. | 3000 // eligible for garbage collection. |
| 2974 body += LoadLocal(context); | 3001 body += LoadLocal(context); |
| 2975 body += LoadLocal(parameter); | 3002 body += LoadLocal(parameter); |
| 2976 body += StoreInstanceField(Context::variable_offset(variable->index())); | 3003 body += StoreInstanceField(Context::variable_offset(variable->index())); |
| 2977 body += NullConstant(); | 3004 body += NullConstant(); |
| 2978 body += StoreLocal(parameter); | 3005 body += StoreLocal(TokenPosition::kNoSource, parameter); |
| 2979 body += Drop(); | 3006 body += Drop(); |
| 2980 } | 3007 } |
| 2981 } | 3008 } |
| 2982 body += Drop(); // The context. | 3009 body += Drop(); // The context. |
| 2983 } | 3010 } |
| 2984 if (constructor != NULL) { | 3011 if (constructor != NULL) { |
| 2985 // TODO(27590): Currently the [VariableDeclaration]s from the | 3012 // TODO(27590): Currently the [VariableDeclaration]s from the |
| 2986 // initializers will be visible inside the entire body of the constructor. | 3013 // initializers will be visible inside the entire body of the constructor. |
| 2987 // We should make a separate scope for them. | 3014 // We should make a separate scope for them. |
| 2988 Class* kernel_klass = Class::Cast(constructor->parent()); | 3015 Class* kernel_klass = Class::Cast(constructor->parent()); |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 3010 TargetEntryInstr* non_null_entry; | 3037 TargetEntryInstr* non_null_entry; |
| 3011 | 3038 |
| 3012 body += LoadLocal(parameter); | 3039 body += LoadLocal(parameter); |
| 3013 body += BranchIfNull(&null_entry, &non_null_entry); | 3040 body += BranchIfNull(&null_entry, &non_null_entry); |
| 3014 | 3041 |
| 3015 // The argument was `null` and the receiver is not the null class (we only | 3042 // The argument was `null` and the receiver is not the null class (we only |
| 3016 // go into this branch for user-defined == operators) so we can return | 3043 // go into this branch for user-defined == operators) so we can return |
| 3017 // false. | 3044 // false. |
| 3018 Fragment null_fragment(null_entry); | 3045 Fragment null_fragment(null_entry); |
| 3019 null_fragment += Constant(Bool::False()); | 3046 null_fragment += Constant(Bool::False()); |
| 3020 null_fragment += Return(); | 3047 null_fragment += Return(dart_function.end_token_pos()); |
| 3021 | 3048 |
| 3022 body = Fragment(body.entry, non_null_entry); | 3049 body = Fragment(body.entry, non_null_entry); |
| 3023 } | 3050 } |
| 3024 | 3051 |
| 3025 if (dart_function.is_native()) { | 3052 if (dart_function.is_native()) { |
| 3026 body += NativeFunctionBody(function, dart_function); | 3053 body += NativeFunctionBody(function, dart_function); |
| 3027 } else if (function->body() != NULL) { | 3054 } else if (function->body() != NULL) { |
| 3028 body += TranslateStatement(function->body()); | 3055 body += TranslateStatement(function->body()); |
| 3029 } | 3056 } |
| 3030 if (body.is_open()) { | 3057 if (body.is_open()) { |
| 3031 body += NullConstant(); | 3058 body += NullConstant(); |
| 3032 body += Return(); | 3059 body += Return(dart_function.end_token_pos()); |
| 3033 } | 3060 } |
| 3034 | 3061 |
| 3035 // If functions body contains any yield points build switch statement that | 3062 // If functions body contains any yield points build switch statement that |
| 3036 // selects a continuation point based on the value of :await_jump_var. | 3063 // selects a continuation point based on the value of :await_jump_var. |
| 3037 if (!yield_continuations_.is_empty()) { | 3064 if (!yield_continuations_.is_empty()) { |
| 3038 // The code we are building will be executed right after we enter | 3065 // The code we are building will be executed right after we enter |
| 3039 // the function and before any nested contexts are allocated. | 3066 // the function and before any nested contexts are allocated. |
| 3040 // Reset current context_depth_ to match this. | 3067 // Reset current context_depth_ to match this. |
| 3041 intptr_t current_context_depth = context_depth_; | 3068 intptr_t current_context_depth = context_depth_; |
| 3042 context_depth_ = scopes_->yield_jump_variable->owner()->context_level(); | 3069 context_depth_ = scopes_->yield_jump_variable->owner()->context_level(); |
| 3043 | 3070 |
| 3044 // Prepend an entry corresponding to normal entry to the function. | 3071 // Prepend an entry corresponding to normal entry to the function. |
| 3045 yield_continuations_.InsertAt( | 3072 yield_continuations_.InsertAt( |
| 3046 0, YieldContinuation(new (Z) DropTempsInstr(0, NULL), | 3073 0, YieldContinuation(new (Z) DropTempsInstr(0, NULL), |
| 3047 CatchClauseNode::kInvalidTryIndex)); | 3074 CatchClauseNode::kInvalidTryIndex)); |
| 3048 yield_continuations_[0].entry->LinkTo(body.entry); | 3075 yield_continuations_[0].entry->LinkTo(body.entry); |
| 3049 | 3076 |
| 3050 // Build a switch statement. | 3077 // Build a switch statement. |
| 3051 Fragment dispatch; | 3078 Fragment dispatch; |
| 3052 | 3079 |
| 3053 // Load :await_jump_var into a temporary. | 3080 // Load :await_jump_var into a temporary. |
| 3054 dispatch += LoadLocal(scopes_->yield_jump_variable); | 3081 dispatch += LoadLocal(scopes_->yield_jump_variable); |
| 3055 dispatch += StoreLocal(scopes_->switch_variable); | 3082 dispatch += StoreLocal(TokenPosition::kNoSource, scopes_->switch_variable); |
| 3056 dispatch += Drop(); | 3083 dispatch += Drop(); |
| 3057 | 3084 |
| 3058 BlockEntryInstr* block = NULL; | 3085 BlockEntryInstr* block = NULL; |
| 3059 for (intptr_t i = 0; i < yield_continuations_.length(); i++) { | 3086 for (intptr_t i = 0; i < yield_continuations_.length(); i++) { |
| 3060 if (i == 1) { | 3087 if (i == 1) { |
| 3061 // This is not a normal entry but a resumption. Restore | 3088 // This is not a normal entry but a resumption. Restore |
| 3062 // :current_context_var from :await_ctx_var. | 3089 // :current_context_var from :await_ctx_var. |
| 3063 // Note: after this point context_depth_ does not match current context | 3090 // Note: after this point context_depth_ does not match current context |
| 3064 // depth so we should not access any local variables anymore. | 3091 // depth so we should not access any local variables anymore. |
| 3065 dispatch += LoadLocal(scopes_->yield_context_variable); | 3092 dispatch += LoadLocal(scopes_->yield_context_variable); |
| 3066 dispatch += StoreLocal(parsed_function_->current_context_var()); | 3093 dispatch += StoreLocal(TokenPosition::kNoSource, |
| 3094 parsed_function_->current_context_var()); | |
| 3067 dispatch += Drop(); | 3095 dispatch += Drop(); |
| 3068 } | 3096 } |
| 3069 if (i == (yield_continuations_.length() - 1)) { | 3097 if (i == (yield_continuations_.length() - 1)) { |
| 3070 // We reached the last possility, no need to build more ifs. | 3098 // We reached the last possility, no need to build more ifs. |
| 3071 // Coninue to the last continuation. | 3099 // Coninue to the last continuation. |
| 3072 // Note: continuations start with nop DropTemps instruction | 3100 // Note: continuations start with nop DropTemps instruction |
| 3073 // which acts like an anchor, so we need to skip it. | 3101 // which acts like an anchor, so we need to skip it. |
| 3074 block->set_try_index(yield_continuations_[i].try_index); | 3102 block->set_try_index(yield_continuations_[i].try_index); |
| 3075 dispatch <<= yield_continuations_[i].entry->next(); | 3103 dispatch <<= yield_continuations_[i].entry->next(); |
| 3076 break; | 3104 break; |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 3095 then->set_try_index(yield_continuations_[i].try_index); | 3123 then->set_try_index(yield_continuations_[i].try_index); |
| 3096 | 3124 |
| 3097 // False branch will contain the next comparison. | 3125 // False branch will contain the next comparison. |
| 3098 dispatch = Fragment(dispatch.entry, otherwise); | 3126 dispatch = Fragment(dispatch.entry, otherwise); |
| 3099 block = otherwise; | 3127 block = otherwise; |
| 3100 } | 3128 } |
| 3101 body = dispatch; | 3129 body = dispatch; |
| 3102 | 3130 |
| 3103 context_depth_ = current_context_depth; | 3131 context_depth_ = current_context_depth; |
| 3104 } | 3132 } |
| 3133 | |
| 3105 normal_entry->LinkTo(body.entry); | 3134 normal_entry->LinkTo(body.entry); |
| 3106 | 3135 |
| 3107 // When compiling for OSR, use a depth first search to prune instructions | 3136 // When compiling for OSR, use a depth first search to prune instructions |
| 3108 // unreachable from the OSR entry. Catch entries are always considered | 3137 // unreachable from the OSR entry. Catch entries are always considered |
| 3109 // reachable, even if they become unreachable after OSR. | 3138 // reachable, even if they become unreachable after OSR. |
| 3110 if (osr_id_ != Compiler::kNoOSRDeoptId) { | 3139 if (osr_id_ != Compiler::kNoOSRDeoptId) { |
| 3111 BitVector* block_marks = new (Z) BitVector(Z, next_block_id_); | 3140 BitVector* block_marks = new (Z) BitVector(Z, next_block_id_); |
| 3112 bool found = graph_entry_->PruneUnreachable(graph_entry_, NULL, osr_id_, | 3141 bool found = graph_entry_->PruneUnreachable(graph_entry_, NULL, osr_id_, |
| 3113 block_marks); | 3142 block_marks); |
| 3114 ASSERT(found); | 3143 ASSERT(found); |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3262 body += LoadLocal(scopes_->this_variable); | 3291 body += LoadLocal(scopes_->this_variable); |
| 3263 body += LoadNativeField(kind, Bigint::neg_offset(), | 3292 body += LoadNativeField(kind, Bigint::neg_offset(), |
| 3264 Type::ZoneHandle(Z, Type::BoolType()), kBoolCid); | 3293 Type::ZoneHandle(Z, Type::BoolType()), kBoolCid); |
| 3265 break; | 3294 break; |
| 3266 default: { | 3295 default: { |
| 3267 dart::String& name = dart::String::ZoneHandle(Z, function.native_name()); | 3296 dart::String& name = dart::String::ZoneHandle(Z, function.native_name()); |
| 3268 body += NativeCall(&name, &function); | 3297 body += NativeCall(&name, &function); |
| 3269 break; | 3298 break; |
| 3270 } | 3299 } |
| 3271 } | 3300 } |
| 3272 return body + Return(); | 3301 return body + Return(TokenPosition::kNoSource); |
| 3273 } | 3302 } |
| 3274 | 3303 |
| 3275 | 3304 |
| 3276 FlowGraph* FlowGraphBuilder::BuildGraphOfFieldAccessor( | 3305 FlowGraph* FlowGraphBuilder::BuildGraphOfFieldAccessor( |
| 3277 Field* kernel_field, | 3306 Field* kernel_field, |
| 3278 LocalVariable* setter_value) { | 3307 LocalVariable* setter_value) { |
| 3279 const dart::Function& function = parsed_function_->function(); | 3308 const dart::Function& function = parsed_function_->function(); |
| 3280 | 3309 |
| 3281 bool is_setter = function.IsImplicitSetterFunction(); | 3310 bool is_setter = function.IsImplicitSetterFunction(); |
| 3282 bool is_method = !function.IsStaticFunction(); | 3311 bool is_method = !function.IsStaticFunction(); |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 3313 body += Constant(constant_evaluator_.EvaluateExpression(initializer)); | 3342 body += Constant(constant_evaluator_.EvaluateExpression(initializer)); |
| 3314 } else { | 3343 } else { |
| 3315 // The field always has an initializer because static fields without | 3344 // The field always has an initializer because static fields without |
| 3316 // initializers are initialized eagerly and do not have implicit getters. | 3345 // initializers are initialized eagerly and do not have implicit getters. |
| 3317 ASSERT(field.has_initializer()); | 3346 ASSERT(field.has_initializer()); |
| 3318 body += Constant(field); | 3347 body += Constant(field); |
| 3319 body += InitStaticField(field); | 3348 body += InitStaticField(field); |
| 3320 body += Constant(field); | 3349 body += Constant(field); |
| 3321 body += LoadStaticField(); | 3350 body += LoadStaticField(); |
| 3322 } | 3351 } |
| 3323 body += Return(); | 3352 body += Return(TokenPosition::kNoSource); |
| 3324 | 3353 |
| 3325 return new (Z) FlowGraph(*parsed_function_, graph_entry_, next_block_id_ - 1); | 3354 return new (Z) FlowGraph(*parsed_function_, graph_entry_, next_block_id_ - 1); |
| 3326 } | 3355 } |
| 3327 | 3356 |
| 3328 | 3357 |
| 3329 FlowGraph* FlowGraphBuilder::BuildGraphOfStaticFieldInitializer( | 3358 FlowGraph* FlowGraphBuilder::BuildGraphOfStaticFieldInitializer( |
| 3330 Field* kernel_field) { | 3359 Field* kernel_field) { |
| 3331 ASSERT(kernel_field->IsStatic()); | 3360 ASSERT(kernel_field->IsStatic()); |
| 3332 | 3361 |
| 3333 Expression* initializer = kernel_field->initializer(); | 3362 Expression* initializer = kernel_field->initializer(); |
| 3334 | 3363 |
| 3335 TargetEntryInstr* normal_entry = BuildTargetEntry(); | 3364 TargetEntryInstr* normal_entry = BuildTargetEntry(); |
| 3336 graph_entry_ = new (Z) | 3365 graph_entry_ = new (Z) |
| 3337 GraphEntryInstr(*parsed_function_, normal_entry, Compiler::kNoOSRDeoptId); | 3366 GraphEntryInstr(*parsed_function_, normal_entry, Compiler::kNoOSRDeoptId); |
| 3338 | 3367 |
| 3339 Fragment body(normal_entry); | 3368 Fragment body(normal_entry); |
| 3340 body += CheckStackOverflowInPrologue(); | 3369 body += CheckStackOverflowInPrologue(); |
| 3341 if (kernel_field->IsConst()) { | 3370 if (kernel_field->IsConst()) { |
| 3342 body += Constant(constant_evaluator_.EvaluateExpression(initializer)); | 3371 body += Constant(constant_evaluator_.EvaluateExpression(initializer)); |
| 3343 } else { | 3372 } else { |
| 3344 body += TranslateExpression(initializer); | 3373 body += TranslateExpression(initializer); |
| 3345 } | 3374 } |
| 3346 body += Return(); | 3375 body += Return(TokenPosition::kNoSource); |
| 3347 | 3376 |
| 3348 return new (Z) FlowGraph(*parsed_function_, graph_entry_, next_block_id_ - 1); | 3377 return new (Z) FlowGraph(*parsed_function_, graph_entry_, next_block_id_ - 1); |
| 3349 } | 3378 } |
| 3350 | 3379 |
| 3351 | 3380 |
| 3352 Fragment FlowGraphBuilder::BuildImplicitClosureCreation( | 3381 Fragment FlowGraphBuilder::BuildImplicitClosureCreation( |
| 3353 const Function& target) { | 3382 const Function& target) { |
| 3354 Fragment fragment; | 3383 Fragment fragment; |
| 3355 const dart::Class& closure_class = | 3384 const dart::Class& closure_class = |
| 3356 dart::Class::ZoneHandle(Z, I->object_store()->closure_class()); | 3385 dart::Class::ZoneHandle(Z, I->object_store()->closure_class()); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3397 // A method extractor is the implicit getter for a method. | 3426 // A method extractor is the implicit getter for a method. |
| 3398 const Function& function = | 3427 const Function& function = |
| 3399 Function::ZoneHandle(Z, method.extracted_method_closure()); | 3428 Function::ZoneHandle(Z, method.extracted_method_closure()); |
| 3400 | 3429 |
| 3401 TargetEntryInstr* normal_entry = BuildTargetEntry(); | 3430 TargetEntryInstr* normal_entry = BuildTargetEntry(); |
| 3402 graph_entry_ = new (Z) | 3431 graph_entry_ = new (Z) |
| 3403 GraphEntryInstr(*parsed_function_, normal_entry, Compiler::kNoOSRDeoptId); | 3432 GraphEntryInstr(*parsed_function_, normal_entry, Compiler::kNoOSRDeoptId); |
| 3404 Fragment body(normal_entry); | 3433 Fragment body(normal_entry); |
| 3405 body += CheckStackOverflowInPrologue(); | 3434 body += CheckStackOverflowInPrologue(); |
| 3406 body += BuildImplicitClosureCreation(function); | 3435 body += BuildImplicitClosureCreation(function); |
| 3407 body += Return(); | 3436 body += Return(TokenPosition::kNoSource); |
| 3408 | 3437 |
| 3409 return new (Z) FlowGraph(*parsed_function_, graph_entry_, next_block_id_ - 1); | 3438 return new (Z) FlowGraph(*parsed_function_, graph_entry_, next_block_id_ - 1); |
| 3410 } | 3439 } |
| 3411 | 3440 |
| 3412 | 3441 |
| 3413 FlowGraph* FlowGraphBuilder::BuildGraphOfImplicitClosureFunction( | 3442 FlowGraph* FlowGraphBuilder::BuildGraphOfImplicitClosureFunction( |
| 3414 FunctionNode* kernel_function, | 3443 FunctionNode* kernel_function, |
| 3415 const Function& function) { | 3444 const Function& function) { |
| 3416 const Function& target = Function::ZoneHandle(Z, function.parent_function()); | 3445 const Function& target = Function::ZoneHandle(Z, function.parent_function()); |
| 3417 | 3446 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3449 argument_names.SetAt(i, H.DartSymbol(variable->name())); | 3478 argument_names.SetAt(i, H.DartSymbol(variable->name())); |
| 3450 } | 3479 } |
| 3451 } | 3480 } |
| 3452 // Forward them to the target. | 3481 // Forward them to the target. |
| 3453 intptr_t argument_count = positional_argument_count + named_argument_count; | 3482 intptr_t argument_count = positional_argument_count + named_argument_count; |
| 3454 if (!target.is_static()) ++argument_count; | 3483 if (!target.is_static()) ++argument_count; |
| 3455 body += StaticCall(TokenPosition::kNoSource, target, argument_count, | 3484 body += StaticCall(TokenPosition::kNoSource, target, argument_count, |
| 3456 argument_names); | 3485 argument_names); |
| 3457 | 3486 |
| 3458 // Return the result. | 3487 // Return the result. |
| 3459 body += Return(); | 3488 body += Return(kernel_function->end_position()); |
| 3460 | 3489 |
| 3461 return new (Z) FlowGraph(*parsed_function_, graph_entry_, next_block_id_ - 1); | 3490 return new (Z) FlowGraph(*parsed_function_, graph_entry_, next_block_id_ - 1); |
| 3462 } | 3491 } |
| 3463 | 3492 |
| 3464 | 3493 |
| 3465 FlowGraph* FlowGraphBuilder::BuildGraphOfNoSuchMethodDispatcher( | 3494 FlowGraph* FlowGraphBuilder::BuildGraphOfNoSuchMethodDispatcher( |
| 3466 const Function& function) { | 3495 const Function& function) { |
| 3467 // This function is specialized for a receiver class, a method name, and | 3496 // This function is specialized for a receiver class, a method name, and |
| 3468 // the arguments descriptor at a call site. | 3497 // the arguments descriptor at a call site. |
| 3469 | 3498 |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3550 dart::Class::Handle(Z, function.Owner()), | 3579 dart::Class::Handle(Z, function.Owner()), |
| 3551 Symbols::NoSuchMethod(), two_arguments)); | 3580 Symbols::NoSuchMethod(), two_arguments)); |
| 3552 if (no_such_method.IsNull()) { | 3581 if (no_such_method.IsNull()) { |
| 3553 // If noSuchMethod is not found on the receiver class, call | 3582 // If noSuchMethod is not found on the receiver class, call |
| 3554 // Object.noSuchMethod. | 3583 // Object.noSuchMethod. |
| 3555 no_such_method = Resolver::ResolveDynamicForReceiverClass( | 3584 no_such_method = Resolver::ResolveDynamicForReceiverClass( |
| 3556 dart::Class::Handle(Z, I->object_store()->object_class()), | 3585 dart::Class::Handle(Z, I->object_store()->object_class()), |
| 3557 Symbols::NoSuchMethod(), two_arguments); | 3586 Symbols::NoSuchMethod(), two_arguments); |
| 3558 } | 3587 } |
| 3559 body += StaticCall(TokenPosition::kMinSource, no_such_method, 2); | 3588 body += StaticCall(TokenPosition::kMinSource, no_such_method, 2); |
| 3560 body += Return(); | 3589 body += Return(TokenPosition::kNoSource); |
| 3561 | 3590 |
| 3562 return new (Z) FlowGraph(*parsed_function_, graph_entry_, next_block_id_ - 1); | 3591 return new (Z) FlowGraph(*parsed_function_, graph_entry_, next_block_id_ - 1); |
| 3563 } | 3592 } |
| 3564 | 3593 |
| 3565 | 3594 |
| 3566 FlowGraph* FlowGraphBuilder::BuildGraphOfInvokeFieldDispatcher( | 3595 FlowGraph* FlowGraphBuilder::BuildGraphOfInvokeFieldDispatcher( |
| 3567 const Function& function) { | 3596 const Function& function) { |
| 3568 // Find the name of the field we should dispatch to. | 3597 // Find the name of the field we should dispatch to. |
| 3569 const dart::Class& owner = dart::Class::Handle(Z, function.Owner()); | 3598 const dart::Class& owner = dart::Class::Handle(Z, function.Owner()); |
| 3570 ASSERT(!owner.IsNull()); | 3599 ASSERT(!owner.IsNull()); |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3637 // Lookup the function in the closure. | 3666 // Lookup the function in the closure. |
| 3638 body += LoadLocal(closure); | 3667 body += LoadLocal(closure); |
| 3639 body += LoadField(Closure::function_offset()); | 3668 body += LoadField(Closure::function_offset()); |
| 3640 | 3669 |
| 3641 body += ClosureCall(descriptor.Count(), argument_names); | 3670 body += ClosureCall(descriptor.Count(), argument_names); |
| 3642 } else { | 3671 } else { |
| 3643 body += InstanceCall(TokenPosition::kMinSource, Symbols::Call(), | 3672 body += InstanceCall(TokenPosition::kMinSource, Symbols::Call(), |
| 3644 Token::kILLEGAL, descriptor.Count(), argument_names); | 3673 Token::kILLEGAL, descriptor.Count(), argument_names); |
| 3645 } | 3674 } |
| 3646 | 3675 |
| 3647 body += Return(); | 3676 body += Return(TokenPosition::kNoSource); |
| 3648 | 3677 |
| 3649 return new (Z) FlowGraph(*parsed_function_, graph_entry_, next_block_id_ - 1); | 3678 return new (Z) FlowGraph(*parsed_function_, graph_entry_, next_block_id_ - 1); |
| 3650 } | 3679 } |
| 3651 | 3680 |
| 3652 | 3681 |
| 3653 void FlowGraphBuilder::SetupDefaultParameterValues(FunctionNode* function) { | 3682 void FlowGraphBuilder::SetupDefaultParameterValues(FunctionNode* function) { |
| 3654 intptr_t num_optional_parameters = | 3683 intptr_t num_optional_parameters = |
| 3655 parsed_function_->function().NumOptionalParameters(); | 3684 parsed_function_->function().NumOptionalParameters(); |
| 3656 if (num_optional_parameters > 0) { | 3685 if (num_optional_parameters > 0) { |
| 3657 ZoneGrowableArray<const Instance*>* default_values = | 3686 ZoneGrowableArray<const Instance*>* default_values = |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3796 // specification but that is how it is currently implemented.) | 3825 // specification but that is how it is currently implemented.) |
| 3797 LocalInitializer* init = LocalInitializer::Cast(initializer); | 3826 LocalInitializer* init = LocalInitializer::Cast(initializer); |
| 3798 | 3827 |
| 3799 VariableDeclaration* declaration = init->variable(); | 3828 VariableDeclaration* declaration = init->variable(); |
| 3800 LocalVariable* variable = LookupVariable(declaration); | 3829 LocalVariable* variable = LookupVariable(declaration); |
| 3801 Expression* initializer = init->variable()->initializer(); | 3830 Expression* initializer = init->variable()->initializer(); |
| 3802 ASSERT(initializer != NULL); | 3831 ASSERT(initializer != NULL); |
| 3803 ASSERT(!declaration->IsConst()); | 3832 ASSERT(!declaration->IsConst()); |
| 3804 | 3833 |
| 3805 instructions += TranslateExpression(initializer); | 3834 instructions += TranslateExpression(initializer); |
| 3806 instructions += StoreLocal(variable); | 3835 instructions += StoreLocal(TokenPosition::kNoSource, variable); |
| 3807 instructions += Drop(); | 3836 instructions += Drop(); |
| 3808 | 3837 |
| 3809 fragment_ = instructions; | 3838 fragment_ = instructions; |
| 3810 } else { | 3839 } else { |
| 3811 UNIMPLEMENTED(); | 3840 UNIMPLEMENTED(); |
| 3812 } | 3841 } |
| 3813 } | 3842 } |
| 3814 return instructions; | 3843 return instructions; |
| 3815 } | 3844 } |
| 3816 | 3845 |
| (...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4208 } | 4237 } |
| 4209 | 4238 |
| 4210 | 4239 |
| 4211 void FlowGraphBuilder::VisitVariableGet(VariableGet* node) { | 4240 void FlowGraphBuilder::VisitVariableGet(VariableGet* node) { |
| 4212 fragment_ = LoadLocal(LookupVariable(node->variable())); | 4241 fragment_ = LoadLocal(LookupVariable(node->variable())); |
| 4213 } | 4242 } |
| 4214 | 4243 |
| 4215 | 4244 |
| 4216 void FlowGraphBuilder::VisitVariableSet(VariableSet* node) { | 4245 void FlowGraphBuilder::VisitVariableSet(VariableSet* node) { |
| 4217 Fragment instructions = TranslateExpression(node->expression()); | 4246 Fragment instructions = TranslateExpression(node->expression()); |
| 4218 instructions += StoreLocal(LookupVariable(node->variable())); | 4247 instructions += |
| 4248 StoreLocal(node->position(), LookupVariable(node->variable())); | |
| 4219 fragment_ = instructions; | 4249 fragment_ = instructions; |
| 4220 } | 4250 } |
| 4221 | 4251 |
| 4222 | 4252 |
| 4223 void FlowGraphBuilder::VisitStaticGet(StaticGet* node) { | 4253 void FlowGraphBuilder::VisitStaticGet(StaticGet* node) { |
| 4224 Member* target = node->target(); | 4254 Member* target = node->target(); |
| 4225 if (target->IsField()) { | 4255 if (target->IsField()) { |
| 4226 Field* kernel_field = Field::Cast(target); | 4256 Field* kernel_field = Field::Cast(target); |
| 4227 const dart::Field& field = | 4257 const dart::Field& field = |
| 4228 dart::Field::ZoneHandle(Z, H.LookupFieldByKernelField(kernel_field)); | 4258 dart::Field::ZoneHandle(Z, H.LookupFieldByKernelField(kernel_field)); |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4303 InstanceCall(node->position(), getter_name, Token::kGET, 1); | 4333 InstanceCall(node->position(), getter_name, Token::kGET, 1); |
| 4304 } | 4334 } |
| 4305 | 4335 |
| 4306 | 4336 |
| 4307 void FlowGraphBuilder::VisitPropertySet(PropertySet* node) { | 4337 void FlowGraphBuilder::VisitPropertySet(PropertySet* node) { |
| 4308 Fragment instructions(NullConstant()); | 4338 Fragment instructions(NullConstant()); |
| 4309 LocalVariable* variable = MakeTemporary(); | 4339 LocalVariable* variable = MakeTemporary(); |
| 4310 instructions += TranslateExpression(node->receiver()); | 4340 instructions += TranslateExpression(node->receiver()); |
| 4311 instructions += PushArgument(); | 4341 instructions += PushArgument(); |
| 4312 instructions += TranslateExpression(node->value()); | 4342 instructions += TranslateExpression(node->value()); |
| 4313 instructions += StoreLocal(variable); | 4343 instructions += StoreLocal(TokenPosition::kNoSource, variable); |
| 4314 instructions += PushArgument(); | 4344 instructions += PushArgument(); |
| 4315 | 4345 |
| 4316 const dart::String& setter_name = H.DartSetterName(node->name()); | 4346 const dart::String& setter_name = H.DartSetterName(node->name()); |
| 4317 instructions += InstanceCall(node->position(), setter_name, Token::kSET, 2); | 4347 instructions += InstanceCall(node->position(), setter_name, Token::kSET, 2); |
| 4318 fragment_ = instructions + Drop(); | 4348 fragment_ = instructions + Drop(); |
| 4319 } | 4349 } |
| 4320 | 4350 |
| 4321 | 4351 |
| 4322 void FlowGraphBuilder::VisitDirectPropertyGet(DirectPropertyGet* node) { | 4352 void FlowGraphBuilder::VisitDirectPropertyGet(DirectPropertyGet* node) { |
| 4323 Function& target = Function::ZoneHandle(Z); | 4353 Function& target = Function::ZoneHandle(Z); |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 4352 const dart::String& method_name = H.DartSetterName(node->target()->name()); | 4382 const dart::String& method_name = H.DartSetterName(node->target()->name()); |
| 4353 const Function& target = Function::ZoneHandle( | 4383 const Function& target = Function::ZoneHandle( |
| 4354 Z, LookupMethodByMember(node->target(), method_name)); | 4384 Z, LookupMethodByMember(node->target(), method_name)); |
| 4355 ASSERT(target.IsSetterFunction() || target.IsImplicitSetterFunction()); | 4385 ASSERT(target.IsSetterFunction() || target.IsImplicitSetterFunction()); |
| 4356 | 4386 |
| 4357 Fragment instructions(NullConstant()); | 4387 Fragment instructions(NullConstant()); |
| 4358 LocalVariable* value = MakeTemporary(); | 4388 LocalVariable* value = MakeTemporary(); |
| 4359 instructions += TranslateExpression(node->receiver()); | 4389 instructions += TranslateExpression(node->receiver()); |
| 4360 instructions += PushArgument(); | 4390 instructions += PushArgument(); |
| 4361 instructions += TranslateExpression(node->value()); | 4391 instructions += TranslateExpression(node->value()); |
| 4362 instructions += StoreLocal(value); | 4392 instructions += StoreLocal(TokenPosition::kNoSource, value); |
| 4363 instructions += PushArgument(); | 4393 instructions += PushArgument(); |
| 4364 instructions += StaticCall(node->position(), target, 2); | 4394 instructions += StaticCall(node->position(), target, 2); |
| 4365 | 4395 |
| 4366 fragment_ = instructions + Drop(); | 4396 fragment_ = instructions + Drop(); |
| 4367 } | 4397 } |
| 4368 | 4398 |
| 4369 | 4399 |
| 4370 void FlowGraphBuilder::VisitStaticInvocation(StaticInvocation* node) { | 4400 void FlowGraphBuilder::VisitStaticInvocation(StaticInvocation* node) { |
| 4371 const Function& target = Function::ZoneHandle( | 4401 const Function& target = Function::ZoneHandle( |
| 4372 Z, H.LookupStaticMethodByKernelProcedure(node->procedure())); | 4402 Z, H.LookupStaticMethodByKernelProcedure(node->procedure())); |
| (...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4619 } | 4649 } |
| 4620 instructions += PushArgument(); // Type arguments. | 4650 instructions += PushArgument(); // Type arguments. |
| 4621 | 4651 |
| 4622 instructions += Constant(type); | 4652 instructions += Constant(type); |
| 4623 instructions += PushArgument(); // Type. | 4653 instructions += PushArgument(); // Type. |
| 4624 | 4654 |
| 4625 instructions += Constant(Bool::False()); | 4655 instructions += Constant(Bool::False()); |
| 4626 instructions += PushArgument(); // Negate?. | 4656 instructions += PushArgument(); // Negate?. |
| 4627 | 4657 |
| 4628 instructions += | 4658 instructions += |
| 4629 InstanceCall(TokenPosition::kNoSource, | 4659 InstanceCall(node->position(), |
| 4630 dart::Library::PrivateCoreLibName(Symbols::_instanceOf()), | 4660 dart::Library::PrivateCoreLibName(Symbols::_instanceOf()), |
| 4631 Token::kIS, 4); | 4661 Token::kIS, 4); |
| 4632 } | 4662 } |
| 4633 | 4663 |
| 4634 fragment_ = instructions; | 4664 fragment_ = instructions; |
| 4635 } | 4665 } |
| 4636 | 4666 |
| 4637 | 4667 |
| 4638 void FlowGraphBuilder::VisitAsExpression(AsExpression* node) { | 4668 void FlowGraphBuilder::VisitAsExpression(AsExpression* node) { |
| 4639 Fragment instructions = TranslateExpression(node->operand()); | 4669 Fragment instructions = TranslateExpression(node->operand()); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4679 bool negate; | 4709 bool negate; |
| 4680 Fragment instructions = TranslateCondition(node->condition(), &negate); | 4710 Fragment instructions = TranslateCondition(node->condition(), &negate); |
| 4681 | 4711 |
| 4682 TargetEntryInstr* then_entry; | 4712 TargetEntryInstr* then_entry; |
| 4683 TargetEntryInstr* otherwise_entry; | 4713 TargetEntryInstr* otherwise_entry; |
| 4684 instructions += BranchIfTrue(&then_entry, &otherwise_entry, negate); | 4714 instructions += BranchIfTrue(&then_entry, &otherwise_entry, negate); |
| 4685 | 4715 |
| 4686 Value* top = stack_; | 4716 Value* top = stack_; |
| 4687 Fragment then_fragment(then_entry); | 4717 Fragment then_fragment(then_entry); |
| 4688 then_fragment += TranslateExpression(node->then()); | 4718 then_fragment += TranslateExpression(node->then()); |
| 4689 then_fragment += StoreLocal(parsed_function_->expression_temp_var()); | 4719 then_fragment += StoreLocal(TokenPosition::kNoSource, |
| 4720 parsed_function_->expression_temp_var()); | |
| 4690 then_fragment += Drop(); | 4721 then_fragment += Drop(); |
| 4691 ASSERT(stack_ == top); | 4722 ASSERT(stack_ == top); |
| 4692 | 4723 |
| 4693 Fragment otherwise_fragment(otherwise_entry); | 4724 Fragment otherwise_fragment(otherwise_entry); |
| 4694 otherwise_fragment += TranslateExpression(node->otherwise()); | 4725 otherwise_fragment += TranslateExpression(node->otherwise()); |
| 4695 otherwise_fragment += StoreLocal(parsed_function_->expression_temp_var()); | 4726 otherwise_fragment += StoreLocal(TokenPosition::kNoSource, |
| 4727 parsed_function_->expression_temp_var()); | |
| 4696 otherwise_fragment += Drop(); | 4728 otherwise_fragment += Drop(); |
| 4697 ASSERT(stack_ == top); | 4729 ASSERT(stack_ == top); |
| 4698 | 4730 |
| 4699 JoinEntryInstr* join = BuildJoinEntry(); | 4731 JoinEntryInstr* join = BuildJoinEntry(); |
| 4700 then_fragment += Goto(join); | 4732 then_fragment += Goto(join); |
| 4701 otherwise_fragment += Goto(join); | 4733 otherwise_fragment += Goto(join); |
| 4702 | 4734 |
| 4703 fragment_ = Fragment(instructions.entry, join) + | 4735 fragment_ = Fragment(instructions.entry, join) + |
| 4704 LoadLocal(parsed_function_->expression_temp_var()); | 4736 LoadLocal(parsed_function_->expression_temp_var()); |
| 4705 } | 4737 } |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 4716 } else { | 4748 } else { |
| 4717 instructions += BranchIfTrue(&constant_entry, &right_entry, negate); | 4749 instructions += BranchIfTrue(&constant_entry, &right_entry, negate); |
| 4718 } | 4750 } |
| 4719 | 4751 |
| 4720 Value* top = stack_; | 4752 Value* top = stack_; |
| 4721 Fragment right_fragment(right_entry); | 4753 Fragment right_fragment(right_entry); |
| 4722 right_fragment += TranslateCondition(node->right(), &negate); | 4754 right_fragment += TranslateCondition(node->right(), &negate); |
| 4723 right_fragment += Constant(Bool::True()); | 4755 right_fragment += Constant(Bool::True()); |
| 4724 right_fragment += | 4756 right_fragment += |
| 4725 StrictCompare(negate ? Token::kNE_STRICT : Token::kEQ_STRICT); | 4757 StrictCompare(negate ? Token::kNE_STRICT : Token::kEQ_STRICT); |
| 4726 right_fragment += StoreLocal(parsed_function_->expression_temp_var()); | 4758 right_fragment += StoreLocal(TokenPosition::kNoSource, |
| 4759 parsed_function_->expression_temp_var()); | |
| 4727 right_fragment += Drop(); | 4760 right_fragment += Drop(); |
| 4728 | 4761 |
| 4729 ASSERT(top == stack_); | 4762 ASSERT(top == stack_); |
| 4730 Fragment constant_fragment(constant_entry); | 4763 Fragment constant_fragment(constant_entry); |
| 4731 constant_fragment += | 4764 constant_fragment += |
| 4732 Constant(Bool::Get(node->op() == LogicalExpression::kOr)); | 4765 Constant(Bool::Get(node->op() == LogicalExpression::kOr)); |
| 4733 constant_fragment += StoreLocal(parsed_function_->expression_temp_var()); | 4766 constant_fragment += StoreLocal(TokenPosition::kNoSource, |
| 4767 parsed_function_->expression_temp_var()); | |
| 4734 constant_fragment += Drop(); | 4768 constant_fragment += Drop(); |
| 4735 | 4769 |
| 4736 JoinEntryInstr* join = BuildJoinEntry(); | 4770 JoinEntryInstr* join = BuildJoinEntry(); |
| 4737 right_fragment += Goto(join); | 4771 right_fragment += Goto(join); |
| 4738 constant_fragment += Goto(join); | 4772 constant_fragment += Goto(join); |
| 4739 | 4773 |
| 4740 fragment_ = Fragment(instructions.entry, join) + | 4774 fragment_ = Fragment(instructions.entry, join) + |
| 4741 LoadLocal(parsed_function_->expression_temp_var()); | 4775 LoadLocal(parsed_function_->expression_temp_var()); |
| 4742 } | 4776 } |
| 4743 | 4777 |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 4765 LocalVariable* array = MakeTemporary(); | 4799 LocalVariable* array = MakeTemporary(); |
| 4766 | 4800 |
| 4767 for (intptr_t i = 0; i < node->expressions().length(); i++) { | 4801 for (intptr_t i = 0; i < node->expressions().length(); i++) { |
| 4768 instructions += LoadLocal(array); | 4802 instructions += LoadLocal(array); |
| 4769 instructions += IntConstant(i); | 4803 instructions += IntConstant(i); |
| 4770 instructions += TranslateExpression(node->expressions()[i]); | 4804 instructions += TranslateExpression(node->expressions()[i]); |
| 4771 instructions += StoreIndexed(kArrayCid); | 4805 instructions += StoreIndexed(kArrayCid); |
| 4772 instructions += Drop(); | 4806 instructions += Drop(); |
| 4773 } | 4807 } |
| 4774 | 4808 |
| 4775 instructions += StringInterpolate(); | 4809 instructions += StringInterpolate(node->position()); |
| 4776 | 4810 |
| 4777 fragment_ = instructions; | 4811 fragment_ = instructions; |
| 4778 } | 4812 } |
| 4779 | 4813 |
| 4780 | 4814 |
| 4781 void FlowGraphBuilder::VisitListLiteral(ListLiteral* node) { | 4815 void FlowGraphBuilder::VisitListLiteral(ListLiteral* node) { |
| 4782 if (node->is_const()) { | 4816 if (node->is_const()) { |
| 4783 fragment_ = Constant(constant_evaluator_.EvaluateListLiteral(node)); | 4817 fragment_ = Constant(constant_evaluator_.EvaluateListLiteral(node)); |
| 4784 return; | 4818 return; |
| 4785 } | 4819 } |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4957 | 4991 |
| 4958 void FlowGraphBuilder::VisitReturnStatement(ReturnStatement* node) { | 4992 void FlowGraphBuilder::VisitReturnStatement(ReturnStatement* node) { |
| 4959 bool inside_try_finally = try_finally_block_ != NULL; | 4993 bool inside_try_finally = try_finally_block_ != NULL; |
| 4960 | 4994 |
| 4961 Fragment instructions = node->expression() == NULL | 4995 Fragment instructions = node->expression() == NULL |
| 4962 ? NullConstant() | 4996 ? NullConstant() |
| 4963 : TranslateExpression(node->expression()); | 4997 : TranslateExpression(node->expression()); |
| 4964 if (instructions.is_open()) { | 4998 if (instructions.is_open()) { |
| 4965 if (inside_try_finally) { | 4999 if (inside_try_finally) { |
| 4966 ASSERT(scopes_->finally_return_variable != NULL); | 5000 ASSERT(scopes_->finally_return_variable != NULL); |
| 4967 instructions += StoreLocal(scopes_->finally_return_variable); | 5001 instructions += StoreLocal(TokenPosition::kNoSource, |
| 5002 scopes_->finally_return_variable); | |
| 4968 instructions += Drop(); | 5003 instructions += Drop(); |
| 4969 instructions += TranslateFinallyFinalizers(NULL, -1); | 5004 instructions += TranslateFinallyFinalizers(NULL, -1); |
| 4970 if (instructions.is_open()) { | 5005 if (instructions.is_open()) { |
| 4971 instructions += LoadLocal(scopes_->finally_return_variable); | 5006 instructions += LoadLocal(scopes_->finally_return_variable); |
| 4972 instructions += Return(); | 5007 instructions += Return(node->position()); |
| 4973 } | 5008 } |
| 4974 } else { | 5009 } else { |
| 4975 instructions += Return(); | 5010 instructions += Return(node->position()); |
| 4976 } | 5011 } |
| 4977 } else { | 5012 } else { |
| 4978 Pop(); | 5013 Pop(); |
| 4979 } | 5014 } |
| 4980 fragment_ = instructions; | 5015 fragment_ = instructions; |
| 4981 } | 5016 } |
| 4982 | 5017 |
| 4983 | 5018 |
| 4984 void FlowGraphBuilder::VisitExpressionStatement(ExpressionStatement* node) { | 5019 void FlowGraphBuilder::VisitExpressionStatement(ExpressionStatement* node) { |
| 4985 Fragment instructions = TranslateExpression(node->expression()); | 5020 Fragment instructions = TranslateExpression(node->expression()); |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 4998 } else { | 5033 } else { |
| 4999 if (node->IsConst()) { | 5034 if (node->IsConst()) { |
| 5000 const Instance& constant_value = | 5035 const Instance& constant_value = |
| 5001 constant_evaluator_.EvaluateExpression(initializer); | 5036 constant_evaluator_.EvaluateExpression(initializer); |
| 5002 variable->SetConstValue(constant_value); | 5037 variable->SetConstValue(constant_value); |
| 5003 instructions += Constant(constant_value); | 5038 instructions += Constant(constant_value); |
| 5004 } else { | 5039 } else { |
| 5005 instructions += TranslateExpression(initializer); | 5040 instructions += TranslateExpression(initializer); |
| 5006 } | 5041 } |
| 5007 } | 5042 } |
| 5008 instructions += StoreLocal(variable); | 5043 instructions += StoreLocal(variable->token_pos(), variable); |
| 5009 instructions += Drop(); | 5044 instructions += Drop(); |
| 5010 fragment_ = instructions; | 5045 fragment_ = instructions; |
| 5011 } | 5046 } |
| 5012 | 5047 |
| 5013 | 5048 |
| 5014 void FlowGraphBuilder::VisitFunctionDeclaration(FunctionDeclaration* node) { | 5049 void FlowGraphBuilder::VisitFunctionDeclaration(FunctionDeclaration* node) { |
| 5015 Fragment instructions = TranslateFunctionNode(node->function(), node); | 5050 Fragment instructions = TranslateFunctionNode(node->function(), node); |
| 5016 instructions += StoreLocal(LookupVariable(node->variable())); | 5051 instructions += |
| 5052 StoreLocal(TokenPosition::kNoSource, LookupVariable(node->variable())); | |
| 5017 instructions += Drop(); | 5053 instructions += Drop(); |
| 5018 fragment_ = instructions; | 5054 fragment_ = instructions; |
| 5019 } | 5055 } |
| 5020 | 5056 |
| 5021 | 5057 |
| 5022 void FlowGraphBuilder::VisitIfStatement(IfStatement* node) { | 5058 void FlowGraphBuilder::VisitIfStatement(IfStatement* node) { |
| 5023 bool negate; | 5059 bool negate; |
| 5024 Fragment instructions = TranslateCondition(node->condition(), &negate); | 5060 Fragment instructions = TranslateCondition(node->condition(), &negate); |
| 5025 TargetEntryInstr* then_entry; | 5061 TargetEntryInstr* then_entry; |
| 5026 TargetEntryInstr* otherwise_entry; | 5062 TargetEntryInstr* otherwise_entry; |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5165 | 5201 |
| 5166 void FlowGraphBuilder::VisitForInStatement(ForInStatement* node) { | 5202 void FlowGraphBuilder::VisitForInStatement(ForInStatement* node) { |
| 5167 Fragment instructions = TranslateExpression(node->iterable()); | 5203 Fragment instructions = TranslateExpression(node->iterable()); |
| 5168 instructions += PushArgument(); | 5204 instructions += PushArgument(); |
| 5169 | 5205 |
| 5170 const dart::String& iterator_getter = dart::String::ZoneHandle( | 5206 const dart::String& iterator_getter = dart::String::ZoneHandle( |
| 5171 Z, dart::Field::GetterSymbol(Symbols::Iterator())); | 5207 Z, dart::Field::GetterSymbol(Symbols::Iterator())); |
| 5172 instructions += | 5208 instructions += |
| 5173 InstanceCall(TokenPosition::kNoSource, iterator_getter, Token::kGET, 1); | 5209 InstanceCall(TokenPosition::kNoSource, iterator_getter, Token::kGET, 1); |
| 5174 LocalVariable* iterator = scopes_->iterator_variables[for_in_depth_]; | 5210 LocalVariable* iterator = scopes_->iterator_variables[for_in_depth_]; |
| 5175 instructions += StoreLocal(iterator); | 5211 instructions += StoreLocal(TokenPosition::kNoSource, iterator); |
| 5176 instructions += Drop(); | 5212 instructions += Drop(); |
| 5177 | 5213 |
| 5178 ++for_in_depth_; | 5214 ++for_in_depth_; |
| 5179 ++loop_depth_; | 5215 ++loop_depth_; |
| 5180 Fragment condition = LoadLocal(iterator); | 5216 Fragment condition = LoadLocal(iterator); |
| 5181 condition += PushArgument(); | 5217 condition += PushArgument(); |
| 5182 condition += InstanceCall(TokenPosition::kNoSource, Symbols::MoveNext(), | 5218 condition += InstanceCall(TokenPosition::kNoSource, Symbols::MoveNext(), |
| 5183 Token::kILLEGAL, 1); | 5219 Token::kILLEGAL, 1); |
| 5184 TargetEntryInstr* body_entry; | 5220 TargetEntryInstr* body_entry; |
| 5185 TargetEntryInstr* loop_exit; | 5221 TargetEntryInstr* loop_exit; |
| 5186 condition += BranchIfTrue(&body_entry, &loop_exit); | 5222 condition += BranchIfTrue(&body_entry, &loop_exit); |
| 5187 | 5223 |
| 5188 Fragment body(body_entry); | 5224 Fragment body(body_entry); |
| 5189 body += EnterScope(node); | 5225 body += EnterScope(node); |
| 5190 body += LoadLocal(iterator); | 5226 body += LoadLocal(iterator); |
| 5191 body += PushArgument(); | 5227 body += PushArgument(); |
| 5192 const dart::String& current_getter = dart::String::ZoneHandle( | 5228 const dart::String& current_getter = dart::String::ZoneHandle( |
| 5193 Z, dart::Field::GetterSymbol(Symbols::Current())); | 5229 Z, dart::Field::GetterSymbol(Symbols::Current())); |
| 5194 body += | 5230 body += |
| 5195 InstanceCall(TokenPosition::kNoSource, current_getter, Token::kGET, 1); | 5231 InstanceCall(TokenPosition::kNoSource, current_getter, Token::kGET, 1); |
| 5196 body += StoreLocal(LookupVariable(node->variable())); | 5232 body += |
| 5233 StoreLocal(TokenPosition::kNoSource, LookupVariable(node->variable())); | |
| 5197 body += Drop(); | 5234 body += Drop(); |
| 5198 body += TranslateStatement(node->body()); | 5235 body += TranslateStatement(node->body()); |
| 5199 body += ExitScope(node); | 5236 body += ExitScope(node); |
| 5200 | 5237 |
| 5201 if (body.is_open()) { | 5238 if (body.is_open()) { |
| 5202 JoinEntryInstr* join = BuildJoinEntry(); | 5239 JoinEntryInstr* join = BuildJoinEntry(); |
| 5203 instructions += Goto(join); | 5240 instructions += Goto(join); |
| 5204 body += Goto(join); | 5241 body += Goto(join); |
| 5205 | 5242 |
| 5206 Fragment loop(join); | 5243 Fragment loop(join); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5256 fragment_ = instructions; | 5293 fragment_ = instructions; |
| 5257 } | 5294 } |
| 5258 | 5295 |
| 5259 | 5296 |
| 5260 void FlowGraphBuilder::VisitSwitchStatement(SwitchStatement* node) { | 5297 void FlowGraphBuilder::VisitSwitchStatement(SwitchStatement* node) { |
| 5261 SwitchBlock block(this, node); | 5298 SwitchBlock block(this, node); |
| 5262 | 5299 |
| 5263 // Instead of using a variable we should reuse the expression on the stack, | 5300 // Instead of using a variable we should reuse the expression on the stack, |
| 5264 // since it won't be assigned again, we don't need phi nodes. | 5301 // since it won't be assigned again, we don't need phi nodes. |
| 5265 Fragment head_instructions = TranslateExpression(node->condition()); | 5302 Fragment head_instructions = TranslateExpression(node->condition()); |
| 5266 head_instructions += StoreLocal(scopes_->switch_variable); | 5303 head_instructions += |
| 5304 StoreLocal(TokenPosition::kNoSource, scopes_->switch_variable); | |
| 5267 head_instructions += Drop(); | 5305 head_instructions += Drop(); |
| 5268 | 5306 |
| 5269 // Phase 1: Generate bodies and try to find out whether a body will be target | 5307 // Phase 1: Generate bodies and try to find out whether a body will be target |
| 5270 // of a jump due to: | 5308 // of a jump due to: |
| 5271 // * `continue case_label` | 5309 // * `continue case_label` |
| 5272 // * `case e1: case e2: body` | 5310 // * `case e1: case e2: body` |
| 5273 Fragment* body_fragments = new Fragment[node->cases().length()]; | 5311 Fragment* body_fragments = new Fragment[node->cases().length()]; |
| 5274 | 5312 |
| 5275 intptr_t num_cases = node->cases().length(); | 5313 intptr_t num_cases = node->cases().length(); |
| 5276 for (intptr_t i = 0; i < num_cases; i++) { | 5314 for (intptr_t i = 0; i < num_cases; i++) { |
| (...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5611 // Fill in the body of the catch. | 5649 // Fill in the body of the catch. |
| 5612 for (intptr_t i = 0; i < node->catches().length(); i++) { | 5650 for (intptr_t i = 0; i < node->catches().length(); i++) { |
| 5613 Catch* catch_clause = node->catches()[i]; | 5651 Catch* catch_clause = node->catches()[i]; |
| 5614 | 5652 |
| 5615 Fragment catch_handler_body; | 5653 Fragment catch_handler_body; |
| 5616 | 5654 |
| 5617 catch_handler_body += EnterScope(catch_clause); | 5655 catch_handler_body += EnterScope(catch_clause); |
| 5618 | 5656 |
| 5619 if (catch_clause->exception() != NULL) { | 5657 if (catch_clause->exception() != NULL) { |
| 5620 catch_handler_body += LoadLocal(CurrentException()); | 5658 catch_handler_body += LoadLocal(CurrentException()); |
| 5621 catch_handler_body += | 5659 catch_handler_body += StoreLocal( |
| 5622 StoreLocal(LookupVariable(catch_clause->exception())); | 5660 TokenPosition::kNoSource, LookupVariable(catch_clause->exception())); |
| 5623 catch_handler_body += Drop(); | 5661 catch_handler_body += Drop(); |
| 5624 } | 5662 } |
| 5625 if (catch_clause->stack_trace() != NULL) { | 5663 if (catch_clause->stack_trace() != NULL) { |
| 5626 catch_handler_body += LoadLocal(CurrentStackTrace()); | 5664 catch_handler_body += LoadLocal(CurrentStackTrace()); |
| 5627 catch_handler_body += | 5665 catch_handler_body += |
| 5628 StoreLocal(LookupVariable(catch_clause->stack_trace())); | 5666 StoreLocal(TokenPosition::kNoSource, |
| 5667 LookupVariable(catch_clause->stack_trace())); | |
| 5629 catch_handler_body += Drop(); | 5668 catch_handler_body += Drop(); |
| 5630 } | 5669 } |
| 5631 AbstractType* type_guard = NULL; | 5670 AbstractType* type_guard = NULL; |
| 5632 if (catch_clause->guard() != NULL && | 5671 if (catch_clause->guard() != NULL && |
| 5633 !catch_clause->guard()->IsDynamicType()) { | 5672 !catch_clause->guard()->IsDynamicType()) { |
| 5634 type_guard = &T.TranslateType(catch_clause->guard()); | 5673 type_guard = &T.TranslateType(catch_clause->guard()); |
| 5635 handler_types.SetAt(i, *type_guard); | 5674 handler_types.SetAt(i, *type_guard); |
| 5636 } else { | 5675 } else { |
| 5637 handler_types.SetAt(i, Object::dynamic_type()); | 5676 handler_types.SetAt(i, Object::dynamic_type()); |
| 5638 } | 5677 } |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5708 // return <expr> | 5747 // return <expr> |
| 5709 // | 5748 // |
| 5710 // Continuation<index>: | 5749 // Continuation<index>: |
| 5711 // Drop(1) | 5750 // Drop(1) |
| 5712 // ... | 5751 // ... |
| 5713 // | 5752 // |
| 5714 // BuildGraphOfFunction will create a dispatch that jumps to | 5753 // BuildGraphOfFunction will create a dispatch that jumps to |
| 5715 // Continuation<:await_jump_var> upon entry to the function. | 5754 // Continuation<:await_jump_var> upon entry to the function. |
| 5716 // | 5755 // |
| 5717 Fragment instructions = IntConstant(yield_continuations_.length() + 1); | 5756 Fragment instructions = IntConstant(yield_continuations_.length() + 1); |
| 5718 instructions += StoreLocal(scopes_->yield_jump_variable); | 5757 instructions += |
| 5758 StoreLocal(TokenPosition::kNoSource, scopes_->yield_jump_variable); | |
| 5719 instructions += Drop(); | 5759 instructions += Drop(); |
| 5720 instructions += LoadLocal(parsed_function_->current_context_var()); | 5760 instructions += LoadLocal(parsed_function_->current_context_var()); |
| 5721 instructions += StoreLocal(scopes_->yield_context_variable); | 5761 instructions += |
| 5762 StoreLocal(TokenPosition::kNoSource, scopes_->yield_context_variable); | |
| 5722 instructions += Drop(); | 5763 instructions += Drop(); |
| 5723 instructions += TranslateExpression(node->expression()); | 5764 instructions += TranslateExpression(node->expression()); |
| 5724 instructions += Return(); | 5765 instructions += Return(TokenPosition::kNoSource); |
| 5725 | 5766 |
| 5726 // Note: DropTempsInstr serves as an anchor instruction. It will not | 5767 // Note: DropTempsInstr serves as an anchor instruction. It will not |
| 5727 // be linked into the resulting graph. | 5768 // be linked into the resulting graph. |
| 5728 DropTempsInstr* anchor = new (Z) DropTempsInstr(0, NULL); | 5769 DropTempsInstr* anchor = new (Z) DropTempsInstr(0, NULL); |
| 5729 yield_continuations_.Add(YieldContinuation(anchor, CurrentTryIndex())); | 5770 yield_continuations_.Add(YieldContinuation(anchor, CurrentTryIndex())); |
| 5730 | 5771 |
| 5731 Fragment continuation(instructions.entry, anchor); | 5772 Fragment continuation(instructions.entry, anchor); |
| 5732 | 5773 |
| 5733 // TODO(27590): we need a better way to detect if we need to check for an | 5774 // TODO(27590): we need a better way to detect if we need to check for an |
| 5734 // exception after yield or not. | 5775 // exception after yield or not. |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5769 continuation = Fragment(continuation.entry, no_error); | 5810 continuation = Fragment(continuation.entry, no_error); |
| 5770 } | 5811 } |
| 5771 | 5812 |
| 5772 fragment_ = continuation; | 5813 fragment_ = continuation; |
| 5773 } | 5814 } |
| 5774 | 5815 |
| 5775 | 5816 |
| 5776 Fragment FlowGraphBuilder::TranslateFunctionNode(FunctionNode* node, | 5817 Fragment FlowGraphBuilder::TranslateFunctionNode(FunctionNode* node, |
| 5777 TreeNode* parent) { | 5818 TreeNode* parent) { |
| 5778 // The VM has a per-isolate table of functions indexed by the enclosing | 5819 // The VM has a per-isolate table of functions indexed by the enclosing |
| 5779 // function and token position. We don't have token positions, so we've | 5820 // function and token position. |
| 5780 // simply numbered the immediately-nested functions with respect to the | |
| 5781 // parent. | |
| 5782 Function& function = Function::ZoneHandle(Z); | 5821 Function& function = Function::ZoneHandle(Z); |
| 5783 for (intptr_t i = 0; i < scopes_->function_scopes.length(); ++i) { | 5822 for (intptr_t i = 0; i < scopes_->function_scopes.length(); ++i) { |
| 5784 if (scopes_->function_scopes[i].function != node) continue; | 5823 if (scopes_->function_scopes[i].function != node) continue; |
| 5785 | 5824 |
| 5825 TokenPosition position = node->position(); | |
| 5826 if (parent->IsFunctionDeclaration()) { | |
| 5827 position = FunctionDeclaration::Cast(parent)->position(); | |
| 5828 } | |
| 5829 if (!position.IsReal()) { | |
| 5830 // Positions has to be unique in regards to the parent. | |
| 5831 // A non-real at this point is probably -1, we cannot blindly use that | |
| 5832 // as others might use it too. Create a new dummy non-real TokenPosition. | |
| 5833 position = TokenPosition(i).ToSynthetic(); | |
| 5834 } | |
| 5835 | |
| 5786 // NOTE: This is not TokenPosition in the general sense! | 5836 // NOTE: This is not TokenPosition in the general sense! |
| 5787 function = I->LookupClosureFunction(parsed_function_->function(), | 5837 function = I->LookupClosureFunction(parsed_function_->function(), position); |
| 5788 TokenPosition(i)); | |
| 5789 if (function.IsNull()) { | 5838 if (function.IsNull()) { |
| 5790 const dart::String* name; | 5839 const dart::String* name; |
| 5791 if (parent->IsFunctionExpression()) { | 5840 if (parent->IsFunctionExpression()) { |
| 5792 name = &Symbols::AnonymousClosure(); | 5841 name = &Symbols::AnonymousClosure(); |
| 5793 } else { | 5842 } else { |
| 5794 ASSERT(parent->IsFunctionDeclaration()); | 5843 ASSERT(parent->IsFunctionDeclaration()); |
| 5795 name = &H.DartSymbol( | 5844 name = &H.DartSymbol( |
| 5796 FunctionDeclaration::Cast(parent)->variable()->name()); | 5845 FunctionDeclaration::Cast(parent)->variable()->name()); |
| 5797 } | 5846 } |
| 5798 // NOTE: This is not TokenPosition in the general sense! | 5847 // NOTE: This is not TokenPosition in the general sense! |
| 5799 function = Function::NewClosureFunction( | 5848 function = Function::NewClosureFunction( |
| 5800 *name, parsed_function_->function(), TokenPosition(i)); | 5849 *name, parsed_function_->function(), position); |
| 5801 function.set_is_debuggable(false); | 5850 function.set_is_debuggable(node->debuggable()); |
| 5851 function.set_end_token_pos(node->end_position()); | |
| 5802 LocalScope* scope = scopes_->function_scopes[i].scope; | 5852 LocalScope* scope = scopes_->function_scopes[i].scope; |
| 5803 const ContextScope& context_scope = | 5853 const ContextScope& context_scope = |
| 5804 ContextScope::Handle(Z, scope->PreserveOuterScope(context_depth_)); | 5854 ContextScope::Handle(Z, scope->PreserveOuterScope(context_depth_)); |
| 5805 function.set_context_scope(context_scope); | 5855 function.set_context_scope(context_scope); |
| 5806 function.set_kernel_function(node); | 5856 function.set_kernel_function(node); |
| 5807 KernelReader::SetupFunctionParameters(H, T, dart::Class::Handle(Z), | 5857 KernelReader::SetupFunctionParameters(H, T, dart::Class::Handle(Z), |
| 5808 function, node, | 5858 function, node, |
| 5809 false, // is_method | 5859 false, // is_method |
| 5810 true); // is_closure | 5860 true); // is_closure |
| 5811 // Finalize function type. | 5861 // Finalize function type. |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 5836 instructions += LoadLocal(parsed_function_->current_context_var()); | 5886 instructions += LoadLocal(parsed_function_->current_context_var()); |
| 5837 instructions += StoreInstanceField(Closure::context_offset()); | 5887 instructions += StoreInstanceField(Closure::context_offset()); |
| 5838 | 5888 |
| 5839 return instructions; | 5889 return instructions; |
| 5840 } | 5890 } |
| 5841 | 5891 |
| 5842 | 5892 |
| 5843 } // namespace kernel | 5893 } // namespace kernel |
| 5844 } // namespace dart | 5894 } // namespace dart |
| 5845 #endif // !defined(DART_PRECOMPILED_RUNTIME) | 5895 #endif // !defined(DART_PRECOMPILED_RUNTIME) |
| OLD | NEW |