OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/object.h" | 5 #include "vm/object.h" |
6 | 6 |
7 #include "platform/assert.h" | 7 #include "platform/assert.h" |
8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
9 #include "vm/bigint_operations.h" | 9 #include "vm/bigint_operations.h" |
10 #include "vm/bootstrap.h" | 10 #include "vm/bootstrap.h" |
| 11 #include "vm/datastream.h" |
11 #include "vm/code_generator.h" | 12 #include "vm/code_generator.h" |
12 #include "vm/code_patcher.h" | 13 #include "vm/code_patcher.h" |
13 #include "vm/compiler.h" | 14 #include "vm/compiler.h" |
14 #include "vm/compiler_stats.h" | 15 #include "vm/compiler_stats.h" |
15 #include "vm/class_finalizer.h" | 16 #include "vm/class_finalizer.h" |
16 #include "vm/dart.h" | 17 #include "vm/dart.h" |
17 #include "vm/dart_api_state.h" | 18 #include "vm/dart_api_state.h" |
18 #include "vm/dart_entry.h" | 19 #include "vm/dart_entry.h" |
19 #include "vm/debuginfo.h" | 20 #include "vm/debuginfo.h" |
20 #include "vm/double_conversion.h" | 21 #include "vm/double_conversion.h" |
(...skipping 4358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4379 return result.raw(); | 4380 return result.raw(); |
4380 } | 4381 } |
4381 | 4382 |
4382 | 4383 |
4383 const char* LiteralToken::ToCString() const { | 4384 const char* LiteralToken::ToCString() const { |
4384 const String& token = String::Handle(literal()); | 4385 const String& token = String::Handle(literal()); |
4385 return token.ToCString(); | 4386 return token.ToCString(); |
4386 } | 4387 } |
4387 | 4388 |
4388 | 4389 |
| 4390 RawArray* TokenStream::TokenObjects() const { |
| 4391 return raw_ptr()->token_objects_; |
| 4392 } |
| 4393 |
| 4394 |
| 4395 void TokenStream::SetTokenObjects(const Array& value) const { |
| 4396 StorePointer(&raw_ptr()->token_objects_, value.raw()); |
| 4397 } |
| 4398 |
| 4399 |
4389 void TokenStream::SetLength(intptr_t value) const { | 4400 void TokenStream::SetLength(intptr_t value) const { |
4390 raw_ptr()->length_ = Smi::New(value); | 4401 raw_ptr()->length_ = Smi::New(value); |
4391 } | 4402 } |
4392 | 4403 |
4393 | 4404 |
4394 void TokenStream::SetTokenAt(intptr_t index, | |
4395 Token::Kind kind, | |
4396 const String& literal) { | |
4397 if (kind == Token::kIDENT) { | |
4398 if (FLAG_compiler_stats) { | |
4399 CompilerStats::num_ident_tokens_total += 1; | |
4400 } | |
4401 StorePointer(EntryAddr(index), reinterpret_cast<RawObject*>(literal.raw())); | |
4402 } else if (Token::NeedsLiteralToken(kind)) { | |
4403 if (FLAG_compiler_stats) { | |
4404 CompilerStats::num_literal_tokens_total += 1; | |
4405 } | |
4406 StorePointer( | |
4407 EntryAddr(index), | |
4408 reinterpret_cast<RawObject*>(LiteralToken::New(kind, literal))); | |
4409 } else { | |
4410 ASSERT(kind < Token::kNumTokens); | |
4411 *(SmiAddr(index)) = Smi::New(kind); | |
4412 } | |
4413 } | |
4414 | |
4415 | |
4416 void TokenStream::SetTokenAt(intptr_t index, const Object& token) { | |
4417 StorePointer(EntryAddr(index), token.raw()); | |
4418 } | |
4419 | |
4420 | |
4421 RawObject* TokenStream::TokenAt(intptr_t index) const { | |
4422 return *EntryAddr(index); | |
4423 } | |
4424 | |
4425 | |
4426 RawString* TokenStream::LiteralAt(intptr_t index) const { | |
4427 const Object& obj = Object::Handle(TokenAt(index)); | |
4428 if (obj.IsString()) { | |
4429 return reinterpret_cast<RawString*>(obj.raw()); | |
4430 } else if (obj.IsSmi()) { | |
4431 Token::Kind kind = static_cast<Token::Kind>( | |
4432 Smi::Value(reinterpret_cast<RawSmi*>(obj.raw()))); | |
4433 ASSERT(kind < Token::kNumTokens); | |
4434 if (Token::IsPseudoKeyword(kind) || Token::IsKeyword(kind)) { | |
4435 Isolate* isolate = Isolate::Current(); | |
4436 ObjectStore* object_store = isolate->object_store(); | |
4437 String& str = String::Handle(isolate, String::null()); | |
4438 const Array& symbols = Array::Handle(isolate, | |
4439 object_store->keyword_symbols()); | |
4440 ASSERT(!symbols.IsNull()); | |
4441 str ^= symbols.At(kind - Token::kFirstKeyword); | |
4442 ASSERT(!str.IsNull()); | |
4443 return str.raw(); | |
4444 } | |
4445 return String::NewSymbol(Token::Str(kind)); | |
4446 } else { | |
4447 // Must be a literal token. | |
4448 return LiteralToken::Cast(obj).literal(); | |
4449 } | |
4450 } | |
4451 | |
4452 | |
4453 RawString* TokenStream::GenerateSource() const { | 4405 RawString* TokenStream::GenerateSource() const { |
| 4406 Iterator iterator(*this, 0); |
4454 GrowableObjectArray& literals = | 4407 GrowableObjectArray& literals = |
4455 GrowableObjectArray::Handle(GrowableObjectArray::New(Length())); | 4408 GrowableObjectArray::Handle(GrowableObjectArray::New(Length())); |
4456 String& literal = String::Handle(); | 4409 String& literal = String::Handle(); |
4457 String& blank = String::Handle(String::New(" ")); | 4410 String& blank = String::Handle(String::New(" ")); |
4458 String& newline = String::Handle(String::New("\n")); | 4411 String& newline = String::Handle(String::New("\n")); |
4459 String& double_quotes = String::Handle(String::New("\"")); | 4412 String& double_quotes = String::Handle(String::New("\"")); |
4460 for (intptr_t i = 0; i < Length(); i++) { | 4413 Object& obj = Object::Handle(); |
4461 Token::Kind kind = KindAt(i); | 4414 Token::Kind kind = iterator.CurrentTokenKind(); |
4462 literal = LiteralAt(i); | 4415 while (kind != Token::kEOS) { |
| 4416 obj = iterator.CurrentToken(); |
| 4417 literal = iterator.MakeLiteralToken(obj); |
4463 if (kind == Token::kSTRING) { | 4418 if (kind == Token::kSTRING) { |
4464 bool escape_quotes = false; | 4419 bool escape_quotes = false; |
4465 for (intptr_t i = 0; i < literal.Length(); i++) { | 4420 for (intptr_t i = 0; i < literal.Length(); i++) { |
4466 if (literal.CharAt(i) == '"') { | 4421 if (literal.CharAt(i) == '"') { |
4467 escape_quotes = true; | 4422 escape_quotes = true; |
4468 break; | 4423 break; |
4469 } | 4424 } |
4470 } | 4425 } |
4471 literals.Add(double_quotes); | 4426 literals.Add(double_quotes); |
4472 if (escape_quotes) { | 4427 if (escape_quotes) { |
4473 literal = String::EscapeDoubleQuotes(literal); | 4428 literal = String::EscapeDoubleQuotes(literal); |
4474 literals.Add(literal); | 4429 literals.Add(literal); |
4475 } else { | 4430 } else { |
4476 literals.Add(literal); | 4431 literals.Add(literal); |
4477 } | 4432 } |
4478 literals.Add(double_quotes); | 4433 literals.Add(double_quotes); |
4479 } else { | 4434 } else { |
4480 literals.Add(literal); | 4435 literals.Add(literal); |
4481 } | 4436 } |
4482 if (kind == Token::kLBRACE) { | 4437 if (kind == Token::kLBRACE) { |
4483 literals.Add(newline); | 4438 literals.Add(newline); |
4484 } else { | 4439 } else { |
4485 literals.Add(blank); | 4440 literals.Add(blank); |
4486 } | 4441 } |
| 4442 iterator.Advance(); |
| 4443 kind = iterator.CurrentTokenKind(); |
4487 } | 4444 } |
4488 const Array& source = Array::Handle(Array::MakeArray(literals)); | 4445 const Array& source = Array::Handle(Array::MakeArray(literals)); |
4489 return String::ConcatAll(source); | 4446 return String::ConcatAll(source); |
4490 } | 4447 } |
4491 | 4448 |
4492 | 4449 |
| 4450 intptr_t TokenStream::ComputeSourcePosition(intptr_t tok_pos) const { |
| 4451 Iterator iterator(*this, 0); |
| 4452 intptr_t src_pos = 0; |
| 4453 Token::Kind kind = iterator.CurrentTokenKind(); |
| 4454 while (iterator.CurrentPosition() < tok_pos && kind != Token::kEOS) { |
| 4455 iterator.Advance(); |
| 4456 kind = iterator.CurrentTokenKind(); |
| 4457 src_pos += 1; |
| 4458 } |
| 4459 return src_pos; |
| 4460 } |
| 4461 |
| 4462 |
| 4463 intptr_t TokenStream::ComputeTokenPosition(intptr_t src_pos) const { |
| 4464 Iterator iterator(*this, 0); |
| 4465 intptr_t index = 0; |
| 4466 Token::Kind kind = iterator.CurrentTokenKind(); |
| 4467 while (index < src_pos && kind != Token::kEOS) { |
| 4468 iterator.Advance(); |
| 4469 kind = iterator.CurrentTokenKind(); |
| 4470 index += 1; |
| 4471 } |
| 4472 return iterator.CurrentPosition(); |
| 4473 } |
| 4474 |
| 4475 |
4493 RawTokenStream* TokenStream::New(intptr_t len) { | 4476 RawTokenStream* TokenStream::New(intptr_t len) { |
4494 const Class& token_stream_class = Class::Handle(Object::token_stream_class()); | 4477 const Class& token_stream_class = Class::Handle(Object::token_stream_class()); |
4495 TokenStream& result = TokenStream::Handle(); | 4478 TokenStream& result = TokenStream::Handle(); |
4496 { | 4479 { |
4497 RawObject* raw = Object::Allocate(token_stream_class, | 4480 RawObject* raw = Object::Allocate(token_stream_class, |
4498 TokenStream::InstanceSize(len), | 4481 TokenStream::InstanceSize(len), |
4499 Heap::kOld); | 4482 Heap::kOld); |
4500 NoGCScope no_gc; | 4483 NoGCScope no_gc; |
4501 result ^= raw; | 4484 result ^= raw; |
4502 result.SetLength(len); | 4485 result.SetLength(len); |
4503 } | 4486 } |
4504 return result.raw(); | 4487 return result.raw(); |
4505 } | 4488 } |
4506 | 4489 |
4507 | 4490 |
| 4491 // Helper class for creation of compressed token stream data. |
| 4492 class CompressedTokenStreamData : public ValueObject { |
| 4493 public: |
| 4494 CompressedTokenStreamData() : |
| 4495 buffer_(NULL), |
| 4496 stream_(&buffer_, Reallocate), |
| 4497 token_objects_(GrowableObjectArray::Handle( |
| 4498 GrowableObjectArray::New(kInitialTokenCount, Heap::kOld))), |
| 4499 token_obj_(Object::Handle()), |
| 4500 literal_token_(LiteralToken::Handle()), |
| 4501 literal_str_(String::Handle()) { |
| 4502 const String& empty_literal = String::Handle(); |
| 4503 token_objects_.Add(empty_literal); |
| 4504 } |
| 4505 ~CompressedTokenStreamData() { |
| 4506 free(buffer_); |
| 4507 } |
| 4508 |
| 4509 // Add an IDENT token into the stream and the token objects array. |
| 4510 void AddIdentToken(String* ident) { |
| 4511 if (ident != NULL) { |
| 4512 // If the IDENT token is already in the tokens object array use the |
| 4513 // same index instead of duplicating it. |
| 4514 intptr_t index = FindIdentIndex(ident); |
| 4515 if (index == -1) { |
| 4516 WriteIndex(token_objects_.Length()); |
| 4517 ASSERT(ident != NULL); |
| 4518 token_objects_.Add(*ident); |
| 4519 } else { |
| 4520 WriteIndex(index); |
| 4521 } |
| 4522 } else { |
| 4523 WriteIndex(0); |
| 4524 } |
| 4525 } |
| 4526 |
| 4527 // Add a LITERAL token into the stream and the token objects array. |
| 4528 void AddLiteralToken(Token::Kind kind, String* literal) { |
| 4529 if (literal != NULL) { |
| 4530 // If the literal token is already in the tokens object array use the |
| 4531 // same index instead of duplicating it. |
| 4532 intptr_t index = FindLiteralIndex(kind, literal); |
| 4533 if (index == -1) { |
| 4534 WriteIndex(token_objects_.Length()); |
| 4535 ASSERT(literal != NULL); |
| 4536 literal_token_ = LiteralToken::New(kind, *literal); |
| 4537 token_objects_.Add(literal_token_); |
| 4538 } else { |
| 4539 WriteIndex(index); |
| 4540 } |
| 4541 } else { |
| 4542 WriteIndex(0); |
| 4543 } |
| 4544 } |
| 4545 |
| 4546 // Add a simple token into the stream. |
| 4547 void AddSimpleToken(intptr_t kind) { |
| 4548 stream_.WriteUnsigned(kind); |
| 4549 } |
| 4550 |
| 4551 // Return the compressed token stream. |
| 4552 uint8_t* GetStream() const { return buffer_; } |
| 4553 |
| 4554 // Return the compressed token stream length. |
| 4555 intptr_t Length() const { return stream_.bytes_written(); } |
| 4556 |
| 4557 // Return the token objects array. |
| 4558 const GrowableObjectArray& TokenObjects() const { |
| 4559 return token_objects_; |
| 4560 } |
| 4561 |
| 4562 private: |
| 4563 intptr_t FindIdentIndex(String* ident) { |
| 4564 ASSERT(ident != NULL); |
| 4565 intptr_t hash_value = ident->Hash() % kTableSize; |
| 4566 GrowableArray<intptr_t>& value = ident_table_[hash_value]; |
| 4567 for (intptr_t i = 0; i < value.length(); i++) { |
| 4568 intptr_t index = value[i]; |
| 4569 token_obj_ = token_objects_.At(index); |
| 4570 if (token_obj_.IsString()) { |
| 4571 const String& ident_str = String::Cast(token_obj_); |
| 4572 if (ident->Equals(ident_str)) { |
| 4573 return index; |
| 4574 } |
| 4575 } |
| 4576 } |
| 4577 value.Add(token_objects_.Length()); |
| 4578 return -1; |
| 4579 } |
| 4580 |
| 4581 intptr_t FindLiteralIndex(Token::Kind kind, String* literal) { |
| 4582 ASSERT(literal != NULL); |
| 4583 intptr_t hash_value = literal->Hash() % kTableSize; |
| 4584 GrowableArray<intptr_t>& value = literal_table_[hash_value]; |
| 4585 for (intptr_t i = 0; i < value.length(); i++) { |
| 4586 intptr_t index = value[i]; |
| 4587 token_obj_ = token_objects_.At(index); |
| 4588 if (token_obj_.IsLiteralToken()) { |
| 4589 const LiteralToken& token = LiteralToken::Cast(token_obj_); |
| 4590 literal_str_ = token.literal(); |
| 4591 if (kind == token.kind() && literal->Equals(literal_str_)) { |
| 4592 return index; |
| 4593 } |
| 4594 } |
| 4595 } |
| 4596 value.Add(token_objects_.Length()); |
| 4597 return -1; |
| 4598 } |
| 4599 |
| 4600 void WriteIndex(intptr_t value) { |
| 4601 stream_.WriteUnsigned(value + Token::kNumTokens); |
| 4602 } |
| 4603 |
| 4604 static uint8_t* Reallocate(uint8_t* ptr, |
| 4605 intptr_t old_size, |
| 4606 intptr_t new_size) { |
| 4607 void* new_ptr = ::realloc(reinterpret_cast<void*>(ptr), new_size); |
| 4608 return reinterpret_cast<uint8_t*>(new_ptr); |
| 4609 } |
| 4610 |
| 4611 static const int kInitialTokenCount = 32; |
| 4612 static const intptr_t kTableSize = 128; |
| 4613 |
| 4614 uint8_t* buffer_; |
| 4615 WriteStream stream_; |
| 4616 GrowableArray<intptr_t> ident_table_[kTableSize]; |
| 4617 GrowableArray<intptr_t> literal_table_[kTableSize]; |
| 4618 const GrowableObjectArray& token_objects_; |
| 4619 Object& token_obj_; |
| 4620 LiteralToken& literal_token_; |
| 4621 String& literal_str_; |
| 4622 |
| 4623 DISALLOW_COPY_AND_ASSIGN(CompressedTokenStreamData); |
| 4624 }; |
| 4625 |
| 4626 |
4508 RawTokenStream* TokenStream::New(const Scanner::GrowableTokenStream& tokens) { | 4627 RawTokenStream* TokenStream::New(const Scanner::GrowableTokenStream& tokens) { |
| 4628 // Copy the relevant data out of the scanner into a compressed stream of |
| 4629 // tokens. |
| 4630 CompressedTokenStreamData data; |
4509 intptr_t len = tokens.length(); | 4631 intptr_t len = tokens.length(); |
4510 | |
4511 TokenStream& result = TokenStream::Handle(New(len)); | |
4512 // Copy the relevant data out of the scanner's token stream. | |
4513 const String& empty_literal = String::Handle(); | |
4514 for (intptr_t i = 0; i < len; i++) { | 4632 for (intptr_t i = 0; i < len; i++) { |
4515 Scanner::TokenDescriptor token = tokens[i]; | 4633 Scanner::TokenDescriptor token = tokens[i]; |
4516 if (token.literal != NULL) { | 4634 if (token.kind == Token::kIDENT) { // Identifier token. |
4517 result.SetTokenAt(i, token.kind, *(token.literal)); | 4635 if (FLAG_compiler_stats) { |
4518 } else { | 4636 CompilerStats::num_ident_tokens_total += 1; |
4519 result.SetTokenAt(i, token.kind, empty_literal); | 4637 } |
| 4638 data.AddIdentToken(token.literal); |
| 4639 } else if (Token::NeedsLiteralToken(token.kind)) { // Literal token. |
| 4640 if (FLAG_compiler_stats) { |
| 4641 CompilerStats::num_literal_tokens_total += 1; |
| 4642 } |
| 4643 data.AddLiteralToken(token.kind, token.literal); |
| 4644 } else { // Keyword, pseudo keyword etc. |
| 4645 ASSERT(token.kind < Token::kNumTokens); |
| 4646 data.AddSimpleToken(token.kind); |
4520 } | 4647 } |
4521 } | 4648 } |
| 4649 if (FLAG_compiler_stats) { |
| 4650 CompilerStats::num_tokens_total += len; |
| 4651 } |
| 4652 data.AddSimpleToken(Token::kEOS); // End of stream. |
| 4653 |
| 4654 // Create and setup the token stream object. |
| 4655 const TokenStream& result = TokenStream::Handle(New(data.Length())); |
| 4656 { |
| 4657 NoGCScope no_gc; |
| 4658 memmove(result.EntryAddr(0), data.GetStream(), data.Length()); |
| 4659 const Array& tokens = Array::Handle(Array::MakeArray(data.TokenObjects())); |
| 4660 result.SetTokenObjects(tokens); |
| 4661 } |
4522 return result.raw(); | 4662 return result.raw(); |
4523 } | 4663 } |
4524 | 4664 |
4525 | 4665 |
4526 const char* TokenStream::ToCString() const { | 4666 const char* TokenStream::ToCString() const { |
4527 return "TokenStream"; | 4667 return "TokenStream"; |
4528 } | 4668 } |
4529 | 4669 |
4530 | 4670 |
| 4671 TokenStream::Iterator::Iterator(const TokenStream& tokens, intptr_t token_pos) |
| 4672 : tokens_(tokens), |
| 4673 token_objects_(Array::Handle(tokens.TokenObjects())), |
| 4674 obj_(Object::Handle()), |
| 4675 cur_token_pos_(token_pos), |
| 4676 stream_token_pos_(token_pos), |
| 4677 cur_token_kind_(Token::kILLEGAL), |
| 4678 cur_token_obj_index_(-1) { |
| 4679 SetCurrentPosition(token_pos); |
| 4680 } |
| 4681 |
| 4682 |
| 4683 bool TokenStream::Iterator::IsValid() const { |
| 4684 return !tokens_.IsNull(); |
| 4685 } |
| 4686 |
| 4687 |
| 4688 Token::Kind TokenStream::Iterator::LookaheadTokenKind(intptr_t num_tokens) { |
| 4689 intptr_t saved_position = stream_token_pos_; |
| 4690 Token::Kind kind = Token::kILLEGAL; |
| 4691 intptr_t value = -1; |
| 4692 intptr_t count = 0; |
| 4693 while (count < num_tokens && value != Token::kEOS) { |
| 4694 value = ReadToken(); |
| 4695 count += 1; |
| 4696 } |
| 4697 if (value < Token::kNumTokens) { |
| 4698 kind = static_cast<Token::Kind>(value); |
| 4699 } else { |
| 4700 value = value - Token::kNumTokens; |
| 4701 obj_ = token_objects_.At(value); |
| 4702 if (obj_.IsLiteralToken()) { |
| 4703 const LiteralToken& literal_token = LiteralToken::Cast(obj_); |
| 4704 kind = literal_token.kind(); |
| 4705 } else { |
| 4706 ASSERT(obj_.IsString()); // Must be an identifier. |
| 4707 kind = Token::kIDENT; |
| 4708 } |
| 4709 } |
| 4710 stream_token_pos_ = saved_position; |
| 4711 return kind; |
| 4712 } |
| 4713 |
| 4714 |
| 4715 intptr_t TokenStream::Iterator::CurrentPosition() const { |
| 4716 return cur_token_pos_; |
| 4717 } |
| 4718 |
| 4719 |
| 4720 void TokenStream::Iterator::SetCurrentPosition(intptr_t value) { |
| 4721 stream_token_pos_ = value; |
| 4722 Advance(); |
| 4723 } |
| 4724 |
| 4725 |
| 4726 void TokenStream::Iterator::Advance() { |
| 4727 cur_token_pos_ = stream_token_pos_; |
| 4728 intptr_t value = ReadToken(); |
| 4729 if (value < Token::kNumTokens) { |
| 4730 cur_token_kind_ = static_cast<Token::Kind>(value); |
| 4731 cur_token_obj_index_ = -1; |
| 4732 return; |
| 4733 } |
| 4734 cur_token_obj_index_ = value - Token::kNumTokens; |
| 4735 obj_ = token_objects_.At(cur_token_obj_index_); |
| 4736 if (obj_.IsLiteralToken()) { |
| 4737 const LiteralToken& literal_token = LiteralToken::Cast(obj_); |
| 4738 cur_token_kind_ = literal_token.kind(); |
| 4739 return; |
| 4740 } |
| 4741 ASSERT(obj_.IsString()); // Must be an identifier. |
| 4742 cur_token_kind_ = Token::kIDENT; |
| 4743 } |
| 4744 |
| 4745 |
| 4746 RawObject* TokenStream::Iterator::CurrentToken() const { |
| 4747 if (cur_token_obj_index_ != -1) { |
| 4748 return token_objects_.At(cur_token_obj_index_); |
| 4749 } else { |
| 4750 return Smi::New(cur_token_kind_); |
| 4751 } |
| 4752 } |
| 4753 |
| 4754 |
| 4755 RawString* TokenStream::Iterator::CurrentLiteral() const { |
| 4756 obj_ = CurrentToken(); |
| 4757 return MakeLiteralToken(obj_); |
| 4758 } |
| 4759 |
| 4760 |
| 4761 RawString* TokenStream::Iterator::MakeLiteralToken(const Object& obj) const { |
| 4762 if (obj.IsString()) { |
| 4763 return reinterpret_cast<RawString*>(obj.raw()); |
| 4764 } else if (obj.IsSmi()) { |
| 4765 Token::Kind kind = static_cast<Token::Kind>( |
| 4766 Smi::Value(reinterpret_cast<RawSmi*>(obj.raw()))); |
| 4767 ASSERT(kind < Token::kNumTokens); |
| 4768 if (Token::IsPseudoKeyword(kind) || Token::IsKeyword(kind)) { |
| 4769 Isolate* isolate = Isolate::Current(); |
| 4770 ObjectStore* object_store = isolate->object_store(); |
| 4771 String& str = String::Handle(isolate, String::null()); |
| 4772 const Array& symbols = Array::Handle(isolate, |
| 4773 object_store->keyword_symbols()); |
| 4774 ASSERT(!symbols.IsNull()); |
| 4775 str ^= symbols.At(kind - Token::kFirstKeyword); |
| 4776 ASSERT(!str.IsNull()); |
| 4777 return str.raw(); |
| 4778 } |
| 4779 return String::NewSymbol(Token::Str(kind)); |
| 4780 } else { |
| 4781 ASSERT(obj.IsLiteralToken()); // Must be a literal token. |
| 4782 const LiteralToken& literal_token = LiteralToken::Cast(obj); |
| 4783 return literal_token.literal(); |
| 4784 } |
| 4785 } |
| 4786 |
| 4787 |
| 4788 intptr_t TokenStream::Iterator::ReadToken() { |
| 4789 uint8_t b = ReadByte(); |
| 4790 if (b > kMaxUnsignedDataPerByte) { |
| 4791 return static_cast<intptr_t>(b) - kEndUnsignedByteMarker; |
| 4792 } |
| 4793 intptr_t value = 0; |
| 4794 uint8_t s = 0; |
| 4795 do { |
| 4796 value |= static_cast<intptr_t>(b) << s; |
| 4797 s += kDataBitsPerByte; |
| 4798 b = ReadByte(); |
| 4799 } while (b <= kMaxUnsignedDataPerByte); |
| 4800 value |= ((static_cast<intptr_t>(b) - kEndUnsignedByteMarker) << s); |
| 4801 ASSERT((value >= 0) && (value <= kIntptrMax)); |
| 4802 return value; |
| 4803 } |
| 4804 |
| 4805 |
| 4806 uint8_t TokenStream::Iterator::ReadByte() { |
| 4807 ASSERT(stream_token_pos_ < tokens_.Length()); |
| 4808 return *(tokens_.EntryAddr(stream_token_pos_++)); |
| 4809 } |
| 4810 |
| 4811 |
4531 bool Script::HasSource() const { | 4812 bool Script::HasSource() const { |
4532 return raw_ptr()->source_ != String::null(); | 4813 return raw_ptr()->source_ != String::null(); |
4533 } | 4814 } |
4534 | 4815 |
4535 | 4816 |
4536 RawString* Script::Source() const { | 4817 RawString* Script::Source() const { |
4537 String& source = String::Handle(raw_ptr()->source_); | 4818 String& source = String::Handle(raw_ptr()->source_); |
4538 if (source.IsNull()) { | 4819 if (source.IsNull()) { |
4539 const TokenStream& token_stream = TokenStream::Handle(tokens()); | 4820 const TokenStream& token_stream = TokenStream::Handle(tokens()); |
4540 return token_stream.GenerateSource(); | 4821 return token_stream.GenerateSource(); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4580 CompilerStats::src_length += src.Length(); | 4861 CompilerStats::src_length += src.Length(); |
4581 } | 4862 } |
4582 } | 4863 } |
4583 | 4864 |
4584 | 4865 |
4585 void Script::GetTokenLocation(intptr_t token_pos, | 4866 void Script::GetTokenLocation(intptr_t token_pos, |
4586 intptr_t* line, | 4867 intptr_t* line, |
4587 intptr_t* column) const { | 4868 intptr_t* column) const { |
4588 const String& src = String::Handle(Source()); | 4869 const String& src = String::Handle(Source()); |
4589 const String& dummy_key = String::Handle(String::New("")); | 4870 const String& dummy_key = String::Handle(String::New("")); |
| 4871 const TokenStream& tkns = TokenStream::Handle(tokens()); |
| 4872 intptr_t src_pos = tkns.ComputeSourcePosition(token_pos); |
4590 Scanner scanner(src, dummy_key); | 4873 Scanner scanner(src, dummy_key); |
4591 scanner.ScanTo(token_pos); | 4874 scanner.ScanTo(src_pos); |
4592 *line = scanner.CurrentPosition().line; | 4875 *line = scanner.CurrentPosition().line; |
4593 *column = scanner.CurrentPosition().column; | 4876 *column = scanner.CurrentPosition().column; |
4594 } | 4877 } |
4595 | 4878 |
4596 | 4879 |
4597 void Script::TokenRangeAtLine(intptr_t line_number, | 4880 void Script::TokenRangeAtLine(intptr_t line_number, |
4598 intptr_t* first_token_index, | 4881 intptr_t* first_token_index, |
4599 intptr_t* last_token_index) const { | 4882 intptr_t* last_token_index) const { |
| 4883 intptr_t first_src_pos; |
| 4884 intptr_t last_src_pos; |
4600 const String& src = String::Handle(Source()); | 4885 const String& src = String::Handle(Source()); |
4601 const String& dummy_key = String::Handle(String::New("")); | 4886 const String& dummy_key = String::Handle(String::New("")); |
| 4887 const TokenStream& tkns = TokenStream::Handle(tokens()); |
4602 Scanner scanner(src, dummy_key); | 4888 Scanner scanner(src, dummy_key); |
4603 scanner.TokenRangeAtLine(line_number, first_token_index, last_token_index); | 4889 scanner.TokenRangeAtLine(line_number, &first_src_pos, &last_src_pos); |
| 4890 *first_token_index = tkns.ComputeTokenPosition(first_src_pos); |
| 4891 *last_token_index = tkns.ComputeTokenPosition(last_src_pos); |
4604 } | 4892 } |
4605 | 4893 |
4606 | 4894 |
4607 RawString* Script::GetLine(intptr_t line_number) const { | 4895 RawString* Script::GetLine(intptr_t line_number) const { |
4608 const String& src = String::Handle(Source()); | 4896 const String& src = String::Handle(Source()); |
4609 intptr_t current_line = 1; | 4897 intptr_t current_line = 1; |
4610 intptr_t line_start = -1; | 4898 intptr_t line_start = -1; |
4611 intptr_t last_char = -1; | 4899 intptr_t last_char = -1; |
4612 for (intptr_t ix = 0; | 4900 for (intptr_t ix = 0; |
4613 (ix < src.Length()) && (current_line <= line_number); | 4901 (ix < src.Length()) && (current_line <= line_number); |
(...skipping 5750 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10364 const String& str = String::Handle(pattern()); | 10652 const String& str = String::Handle(pattern()); |
10365 const char* format = "JSRegExp: pattern=%s flags=%s"; | 10653 const char* format = "JSRegExp: pattern=%s flags=%s"; |
10366 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags()); | 10654 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags()); |
10367 char* chars = reinterpret_cast<char*>( | 10655 char* chars = reinterpret_cast<char*>( |
10368 Isolate::Current()->current_zone()->Allocate(len + 1)); | 10656 Isolate::Current()->current_zone()->Allocate(len + 1)); |
10369 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags()); | 10657 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags()); |
10370 return chars; | 10658 return chars; |
10371 } | 10659 } |
10372 | 10660 |
10373 } // namespace dart | 10661 } // namespace dart |
OLD | NEW |