| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/ast.h" | 5 #include "vm/ast.h" |
| 6 #include "vm/compiler.h" | 6 #include "vm/compiler.h" |
| 7 #include "vm/dart_entry.h" | 7 #include "vm/dart_entry.h" |
| 8 #include "vm/isolate.h" | 8 #include "vm/isolate.h" |
| 9 #include "vm/object_store.h" | 9 #include "vm/object_store.h" |
| 10 | 10 |
| (...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 291 return NULL; | 291 return NULL; |
| 292 } | 292 } |
| 293 } | 293 } |
| 294 | 294 |
| 295 | 295 |
| 296 const char* UnaryOpNode::Name() const { | 296 const char* UnaryOpNode::Name() const { |
| 297 return Token::Str(kind_); | 297 return Token::Str(kind_); |
| 298 } | 298 } |
| 299 | 299 |
| 300 | 300 |
| 301 const char* IncrOpInstanceFieldNode::Name() const { | |
| 302 switch (kind_) { | |
| 303 case Token::kINCR: | |
| 304 return prefix_ ? "instance_field_pre_++" : "instance_field_post_++"; | |
| 305 case Token::kDECR: | |
| 306 return prefix_ ? "instance_field_pre_--" : "instance_field_post_--"; | |
| 307 default: | |
| 308 UNREACHABLE(); | |
| 309 return NULL; | |
| 310 } | |
| 311 } | |
| 312 | |
| 313 | |
| 314 const char* JumpNode::Name() const { | 301 const char* JumpNode::Name() const { |
| 315 return Token::Str(kind_); | 302 return Token::Str(kind_); |
| 316 } | 303 } |
| 317 | 304 |
| 318 | 305 |
| 319 const char* IncrOpIndexedNode::Name() const { | |
| 320 switch (kind_) { | |
| 321 case Token::kINCR: | |
| 322 return prefix_ ? "indexed_pre_++" : "indexed_post_++"; | |
| 323 case Token::kDECR: | |
| 324 return prefix_ ? "indexed_pre_--" : "indexed_post_--"; | |
| 325 default: | |
| 326 UNREACHABLE(); | |
| 327 return NULL; | |
| 328 } | |
| 329 } | |
| 330 | |
| 331 | |
| 332 AstNode* LoadLocalNode::MakeAssignmentNode(AstNode* rhs) { | 306 AstNode* LoadLocalNode::MakeAssignmentNode(AstNode* rhs) { |
| 333 if (local().is_final()) { | 307 if (local().is_final()) { |
| 334 return NULL; | 308 return NULL; |
| 335 } | 309 } |
| 336 if (HasPseudo()) { | 310 if (HasPseudo()) { |
| 337 return NULL; | 311 return NULL; |
| 338 } | 312 } |
| 339 return new StoreLocalNode(token_index(), local(), rhs); | 313 return new StoreLocalNode(token_index(), local(), rhs); |
| 340 } | 314 } |
| 341 | 315 |
| 342 | 316 |
| 343 AstNode* LoadLocalNode::MakeIncrOpNode(intptr_t token_index, | |
| 344 Token::Kind kind, | |
| 345 bool is_prefix) { | |
| 346 if (local().is_final()) { | |
| 347 return NULL; | |
| 348 } | |
| 349 if (is_prefix) { | |
| 350 const Instance& literal = Instance::ZoneHandle(Smi::New(1)); | |
| 351 AstNode* lhs = this; | |
| 352 LiteralNode* rhs = new LiteralNode(token_index, literal); | |
| 353 Token::Kind binop_kind = (kind == Token::kINCR) ? Token::kADD : Token::kSUB; | |
| 354 BinaryOpNode* result = new BinaryOpNode(token_index, binop_kind, lhs, rhs); | |
| 355 StoreLocalNode* store = new StoreLocalNode(token_index, local(), result); | |
| 356 return store; | |
| 357 } | |
| 358 UNIMPLEMENTED(); | |
| 359 return NULL; | |
| 360 } | |
| 361 | |
| 362 | |
| 363 AstNode* LoadStaticFieldNode::MakeAssignmentNode(AstNode* rhs) { | 317 AstNode* LoadStaticFieldNode::MakeAssignmentNode(AstNode* rhs) { |
| 364 return new StoreStaticFieldNode(token_index(), field(), rhs); | 318 return new StoreStaticFieldNode(token_index(), field(), rhs); |
| 365 } | 319 } |
| 366 | 320 |
| 367 | 321 |
| 368 AstNode* LoadStaticFieldNode::MakeIncrOpNode(intptr_t token_index, | |
| 369 Token::Kind kind, | |
| 370 bool is_prefix) { | |
| 371 UNIMPLEMENTED(); | |
| 372 return NULL; | |
| 373 } | |
| 374 | |
| 375 | |
| 376 AstNode* InstanceGetterNode::MakeAssignmentNode(AstNode* rhs) { | 322 AstNode* InstanceGetterNode::MakeAssignmentNode(AstNode* rhs) { |
| 377 return new InstanceSetterNode(token_index(), receiver(), field_name(), rhs); | 323 return new InstanceSetterNode(token_index(), receiver(), field_name(), rhs); |
| 378 } | 324 } |
| 379 | 325 |
| 380 | 326 |
| 381 AstNode* InstanceGetterNode::MakeIncrOpNode(intptr_t token_index, | |
| 382 Token::Kind kind, | |
| 383 bool is_prefix) { | |
| 384 return new IncrOpInstanceFieldNode(token_index, | |
| 385 kind, | |
| 386 is_prefix, | |
| 387 receiver(), | |
| 388 field_name()); | |
| 389 } | |
| 390 | |
| 391 | |
| 392 AstNode* LoadIndexedNode::MakeAssignmentNode(AstNode* rhs) { | 327 AstNode* LoadIndexedNode::MakeAssignmentNode(AstNode* rhs) { |
| 393 return new StoreIndexedNode(token_index(), array(), index_expr(), rhs); | 328 return new StoreIndexedNode(token_index(), array(), index_expr(), rhs); |
| 394 } | 329 } |
| 395 | 330 |
| 396 | 331 |
| 397 AstNode* LoadIndexedNode::MakeIncrOpNode(intptr_t token_index, | |
| 398 Token::Kind kind, | |
| 399 bool is_prefix) { | |
| 400 return new IncrOpIndexedNode(token_index, | |
| 401 kind, | |
| 402 is_prefix, | |
| 403 array(), | |
| 404 index_expr()); | |
| 405 } | |
| 406 | |
| 407 | |
| 408 AstNode* StaticGetterNode::MakeAssignmentNode(AstNode* rhs) { | 332 AstNode* StaticGetterNode::MakeAssignmentNode(AstNode* rhs) { |
| 409 // If no setter exist, set the field directly. | 333 // If no setter exist, set the field directly. |
| 410 const String& setter_name = String::Handle(Field::SetterName(field_name())); | 334 const String& setter_name = String::Handle(Field::SetterName(field_name())); |
| 411 const Function& setter = | 335 const Function& setter = |
| 412 Function::ZoneHandle(cls().LookupStaticFunction(setter_name)); | 336 Function::ZoneHandle(cls().LookupStaticFunction(setter_name)); |
| 413 if (setter.IsNull()) { | 337 if (setter.IsNull()) { |
| 414 // Access to a lazily initialized static field that has not yet been | 338 // Access to a lazily initialized static field that has not yet been |
| 415 // initialized is compiled to a static implicit getter. | 339 // initialized is compiled to a static implicit getter. |
| 416 // A setter may not exist for such a field. | 340 // A setter may not exist for such a field. |
| 417 #if defined(DEBUG) | 341 #if defined(DEBUG) |
| 418 const String& getter_name = String::Handle(Field::GetterName(field_name())); | 342 const String& getter_name = String::Handle(Field::GetterName(field_name())); |
| 419 const Function& getter = | 343 const Function& getter = |
| 420 Function::ZoneHandle(cls().LookupStaticFunction(getter_name)); | 344 Function::ZoneHandle(cls().LookupStaticFunction(getter_name)); |
| 421 ASSERT(!getter.IsNull() && | 345 ASSERT(!getter.IsNull() && |
| 422 (getter.kind() == RawFunction::kConstImplicitGetter)); | 346 (getter.kind() == RawFunction::kConstImplicitGetter)); |
| 423 #endif | 347 #endif |
| 424 const Field& field = Field::ZoneHandle( | 348 const Field& field = Field::ZoneHandle( |
| 425 cls().LookupStaticField(field_name())); | 349 cls().LookupStaticField(field_name())); |
| 426 ASSERT(!field.IsNull()); | 350 ASSERT(!field.IsNull()); |
| 427 return new StoreStaticFieldNode(token_index(), field, rhs); | 351 return new StoreStaticFieldNode(token_index(), field, rhs); |
| 428 } else { | 352 } else { |
| 429 return new StaticSetterNode(token_index(), cls(), field_name(), rhs); | 353 return new StaticSetterNode(token_index(), cls(), field_name(), rhs); |
| 430 } | 354 } |
| 431 } | 355 } |
| 432 | 356 |
| 433 | 357 |
| 434 AstNode* StaticGetterNode::MakeIncrOpNode(intptr_t token_index, | |
| 435 Token::Kind kind, | |
| 436 bool is_prefix) { | |
| 437 UNIMPLEMENTED(); | |
| 438 return NULL; | |
| 439 } | |
| 440 | |
| 441 | |
| 442 const Instance* StaticGetterNode::EvalConstExpr() const { | 358 const Instance* StaticGetterNode::EvalConstExpr() const { |
| 443 const String& getter_name = | 359 const String& getter_name = |
| 444 String::Handle(Field::GetterName(this->field_name())); | 360 String::Handle(Field::GetterName(this->field_name())); |
| 445 const Function& getter_func = | 361 const Function& getter_func = |
| 446 Function::Handle(this->cls().LookupStaticFunction(getter_name)); | 362 Function::Handle(this->cls().LookupStaticFunction(getter_name)); |
| 447 if (getter_func.IsNull() || !getter_func.is_const()) { | 363 if (getter_func.IsNull() || !getter_func.is_const()) { |
| 448 return NULL; | 364 return NULL; |
| 449 } | 365 } |
| 450 GrowableArray<const Object*> arguments; | 366 GrowableArray<const Object*> arguments; |
| 451 const Array& kNoArgumentNames = Array::Handle(); | 367 const Array& kNoArgumentNames = Array::Handle(); |
| 452 const Object& result = | 368 const Object& result = |
| 453 Object::Handle(DartEntry::InvokeStatic(getter_func, | 369 Object::Handle(DartEntry::InvokeStatic(getter_func, |
| 454 arguments, | 370 arguments, |
| 455 kNoArgumentNames)); | 371 kNoArgumentNames)); |
| 456 if (result.IsError() || result.IsNull()) { | 372 if (result.IsError() || result.IsNull()) { |
| 457 // TODO(turnidge): We could get better error messages by returning | 373 // TODO(turnidge): We could get better error messages by returning |
| 458 // the Error object directly to the parser. This will involve | 374 // the Error object directly to the parser. This will involve |
| 459 // replumbing all of the EvalConstExpr methods. | 375 // replumbing all of the EvalConstExpr methods. |
| 460 return NULL; | 376 return NULL; |
| 461 } | 377 } |
| 462 Instance& field_value = Instance::ZoneHandle(); | 378 Instance& field_value = Instance::ZoneHandle(); |
| 463 field_value ^= result.raw(); | 379 field_value ^= result.raw(); |
| 464 return &field_value; | 380 return &field_value; |
| 465 } | 381 } |
| 466 | 382 |
| 467 } // namespace dart | 383 } // namespace dart |
| OLD | NEW |