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" |
(...skipping 4337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4348 return result.raw(); | 4348 return result.raw(); |
4349 } | 4349 } |
4350 | 4350 |
4351 | 4351 |
4352 const char* LiteralToken::ToCString() const { | 4352 const char* LiteralToken::ToCString() const { |
4353 const String& token = String::Handle(literal()); | 4353 const String& token = String::Handle(literal()); |
4354 return token.ToCString(); | 4354 return token.ToCString(); |
4355 } | 4355 } |
4356 | 4356 |
4357 | 4357 |
4358 RawArray* TokenStream::TokenObjects() const { | |
4359 return raw_ptr()->token_objects_; | |
4360 } | |
4361 | |
4362 | |
4363 void TokenStream::SetTokenObjects(const Array& value) const { | |
4364 StorePointer(&raw_ptr()->token_objects_, value.raw()); | |
4365 } | |
4366 | |
4367 | |
4358 void TokenStream::SetLength(intptr_t value) const { | 4368 void TokenStream::SetLength(intptr_t value) const { |
4359 raw_ptr()->length_ = Smi::New(value); | 4369 raw_ptr()->length_ = value; |
4360 } | |
4361 | |
4362 | |
4363 void TokenStream::SetTokenAt(intptr_t index, | |
4364 Token::Kind kind, | |
4365 const String& literal) { | |
4366 if (kind == Token::kIDENT) { | |
4367 if (FLAG_compiler_stats) { | |
4368 CompilerStats::num_ident_tokens_total += 1; | |
4369 } | |
4370 StorePointer(EntryAddr(index), reinterpret_cast<RawObject*>(literal.raw())); | |
4371 } else if (Token::NeedsLiteralToken(kind)) { | |
4372 if (FLAG_compiler_stats) { | |
4373 CompilerStats::num_literal_tokens_total += 1; | |
4374 } | |
4375 StorePointer( | |
4376 EntryAddr(index), | |
4377 reinterpret_cast<RawObject*>(LiteralToken::New(kind, literal))); | |
4378 } else { | |
4379 ASSERT(kind < Token::kNumTokens); | |
4380 *(SmiAddr(index)) = Smi::New(kind); | |
4381 } | |
4382 } | |
4383 | |
4384 | |
4385 void TokenStream::SetTokenAt(intptr_t index, const Object& token) { | |
4386 StorePointer(EntryAddr(index), token.raw()); | |
4387 } | |
4388 | |
4389 | |
4390 RawObject* TokenStream::TokenAt(intptr_t index) const { | |
4391 return *EntryAddr(index); | |
4392 } | |
4393 | |
4394 | |
4395 RawString* TokenStream::LiteralAt(intptr_t index) const { | |
4396 const Object& obj = Object::Handle(TokenAt(index)); | |
4397 if (obj.IsString()) { | |
4398 return reinterpret_cast<RawString*>(obj.raw()); | |
4399 } else if (obj.IsSmi()) { | |
4400 Token::Kind kind = static_cast<Token::Kind>( | |
4401 Smi::Value(reinterpret_cast<RawSmi*>(obj.raw()))); | |
4402 ASSERT(kind < Token::kNumTokens); | |
4403 if (Token::IsPseudoKeyword(kind) || Token::IsKeyword(kind)) { | |
4404 Isolate* isolate = Isolate::Current(); | |
4405 ObjectStore* object_store = isolate->object_store(); | |
4406 String& str = String::Handle(isolate, String::null()); | |
4407 const Array& symbols = Array::Handle(isolate, | |
4408 object_store->keyword_symbols()); | |
4409 ASSERT(!symbols.IsNull()); | |
4410 str ^= symbols.At(kind - Token::kFirstKeyword); | |
4411 ASSERT(!str.IsNull()); | |
4412 return str.raw(); | |
4413 } | |
4414 return String::NewSymbol(Token::Str(kind)); | |
4415 } else { | |
4416 LiteralToken& token = LiteralToken::Handle(); | |
4417 token ^= obj.raw(); // Must be a literal token. | |
4418 return token.literal(); | |
4419 } | |
4420 } | 4370 } |
4421 | 4371 |
4422 | 4372 |
4423 RawString* TokenStream::GenerateSource() const { | 4373 RawString* TokenStream::GenerateSource() const { |
4374 TokenStreamIterator iterator(*this, 0); | |
4424 GrowableObjectArray& literals = | 4375 GrowableObjectArray& literals = |
4425 GrowableObjectArray::Handle(GrowableObjectArray::New(Length())); | 4376 GrowableObjectArray::Handle(GrowableObjectArray::New(Length())); |
4426 String& literal = String::Handle(); | 4377 String& literal = String::Handle(); |
4427 String& blank = String::Handle(String::New(" ")); | 4378 String& blank = String::Handle(String::New(" ")); |
4428 String& newline = String::Handle(String::New("\n")); | 4379 String& newline = String::Handle(String::New("\n")); |
4429 for (intptr_t i = 0; i < Length(); i++) { | 4380 Object& obj = Object::Handle(); |
4430 Token::Kind kind = KindAt(i); | 4381 Token::Kind kind = iterator.CurrentTokenKind(); |
4431 literal = LiteralAt(i); | 4382 while (kind != Token::kEOS) { |
4383 obj = iterator.CurrentToken(); | |
4384 literal = iterator.MakeLiteralToken(obj); | |
4432 literals.Add(literal); | 4385 literals.Add(literal); |
4433 if (kind == Token::kLBRACE) { | 4386 if (kind == Token::kLBRACE) { |
4434 literals.Add(newline); | 4387 literals.Add(newline); |
4435 } else { | 4388 } else { |
4436 literals.Add(blank); | 4389 literals.Add(blank); |
4437 } | 4390 } |
4391 iterator.Advance(); | |
4392 kind = iterator.CurrentTokenKind(); | |
4438 } | 4393 } |
4439 const Array& source = Array::Handle(Array::MakeArray(literals)); | 4394 const Array& source = Array::Handle(Array::MakeArray(literals)); |
4440 return String::ConcatAll(source); | 4395 return String::ConcatAll(source); |
4441 } | 4396 } |
4442 | 4397 |
4443 | 4398 |
4399 intptr_t TokenStream::ComputeSourcePosition(intptr_t tok_pos) const { | |
4400 TokenStreamIterator iterator(*this, 0); | |
4401 intptr_t src_pos = 0; | |
4402 Token::Kind kind = iterator.CurrentTokenKind(); | |
4403 while (iterator.CurrentPosition() < tok_pos && kind != Token::kEOS) { | |
4404 iterator.Advance(); | |
4405 kind = iterator.CurrentTokenKind(); | |
4406 src_pos += 1; | |
4407 } | |
4408 return src_pos; | |
4409 } | |
4410 | |
4411 | |
4444 RawTokenStream* TokenStream::New(intptr_t len) { | 4412 RawTokenStream* TokenStream::New(intptr_t len) { |
4445 const Class& token_stream_class = Class::Handle(Object::token_stream_class()); | 4413 const Class& token_stream_class = Class::Handle(Object::token_stream_class()); |
4446 TokenStream& result = TokenStream::Handle(); | 4414 TokenStream& result = TokenStream::Handle(); |
4447 { | 4415 { |
4448 RawObject* raw = Object::Allocate(token_stream_class, | 4416 RawObject* raw = Object::Allocate(token_stream_class, |
4449 TokenStream::InstanceSize(len), | 4417 TokenStream::InstanceSize(len), |
4450 Heap::kOld); | 4418 Heap::kOld); |
4451 NoGCScope no_gc; | 4419 NoGCScope no_gc; |
4452 result ^= raw; | 4420 result ^= raw; |
4453 result.SetLength(len); | 4421 result.SetLength(len); |
4454 } | 4422 } |
4455 return result.raw(); | 4423 return result.raw(); |
4456 } | 4424 } |
4457 | 4425 |
4458 | 4426 |
4427 // Helper class for creation of compressed token stream data. | |
4428 class CompressedTokenStreamData : public ValueObject { | |
4429 public: | |
4430 CompressedTokenStreamData() : | |
4431 buffer_(NULL), | |
4432 stream_(&buffer_, Reallocate), | |
4433 token_objects_(GrowableObjectArray::Handle( | |
4434 GrowableObjectArray::New(kInitialTokenCount, Heap::kOld))), | |
4435 ident_obj_(Object::Handle()), | |
4436 literal_token_(LiteralToken::Handle()) { | |
4437 const String& empty_literal = String::Handle(); | |
4438 token_objects_.Add(empty_literal); | |
4439 } | |
4440 ~CompressedTokenStreamData() { | |
4441 free(buffer_); | |
4442 } | |
4443 | |
4444 // Add an IDENT token into the stream and the token objects array. | |
4445 void AddIdentToken(String* ident) { | |
4446 if (ident != NULL) { | |
4447 // If the IDENT token is already in the tokens object array use the | |
4448 // same index instead of duplicating it. | |
4449 intptr_t index = FindIdentIndex(ident); | |
4450 if (index == -1) { | |
4451 WriteIndex(token_objects_.Length()); | |
4452 ASSERT(ident != NULL); | |
4453 token_objects_.Add(*ident); | |
4454 } else { | |
4455 WriteIndex(index); | |
4456 } | |
4457 } else { | |
4458 WriteIndex(0); | |
4459 } | |
4460 } | |
4461 | |
4462 // Add a LITERAL token into the stream and the token objects array. | |
4463 void AddLiteralToken(Token::Kind kind, String* literal) { | |
4464 if (literal != NULL) { | |
4465 WriteIndex(token_objects_.Length()); | |
4466 ASSERT(literal != NULL); | |
4467 literal_token_ = LiteralToken::New(kind, *literal); | |
4468 token_objects_.Add(literal_token_); | |
4469 } else { | |
4470 WriteIndex(0); | |
4471 } | |
4472 } | |
4473 | |
4474 // Add a simple token into the stream. | |
4475 void AddSimpleToken(intptr_t kind) { | |
4476 stream_.WriteUnsigned(kind); | |
4477 } | |
4478 | |
4479 // Return the compressed token stream length. | |
4480 intptr_t Length() const { return stream_.bytes_written(); } | |
4481 | |
4482 // Finalize the compressed token stream by copying the stream into the | |
4483 // TokenStream object and setting up the token objects array. | |
4484 void FinalizeTokenStreamData(const TokenStream& token_stream, | |
4485 void* data_addr) { | |
4486 NoGCScope no_gc; | |
4487 memmove(data_addr, buffer_, Length()); | |
4488 const Array& tokens = Array::Handle(Array::MakeArray(token_objects_)); | |
4489 token_stream.SetTokenObjects(tokens); | |
4490 } | |
4491 | |
4492 private: | |
4493 intptr_t FindIdentIndex(String* ident) { | |
Ivan Posva
2012/07/02 22:56:05
We should also investigate unique indices for lite
siva
2012/07/04 01:43:02
Done.
| |
4494 ASSERT(ident != NULL); | |
4495 intptr_t hash_value = ident->Hash() % kTableSize; | |
4496 GrowableArray<intptr_t>& value = table_[hash_value]; | |
4497 for (intptr_t i = 0; i < value.length(); i++) { | |
4498 intptr_t index = value[i]; | |
4499 ident_obj_ = token_objects_.At(index); | |
4500 if (ident_obj_.IsString()) { | |
4501 const String& ident_str = String::Cast(ident_obj_); | |
4502 if (ident->Equals(ident_str)) { | |
4503 return index; | |
4504 } | |
4505 } | |
4506 } | |
4507 value.Add(token_objects_.Length()); | |
4508 return -1; | |
4509 } | |
4510 | |
4511 void WriteIndex(intptr_t value) { | |
4512 stream_.WriteUnsigned(value + Token::kNumTokens); | |
4513 } | |
4514 | |
4515 static uint8_t* Reallocate(uint8_t* ptr, | |
4516 intptr_t old_size, | |
4517 intptr_t new_size) { | |
4518 void* new_ptr = ::realloc(reinterpret_cast<void*>(ptr), new_size); | |
4519 return reinterpret_cast<uint8_t*>(new_ptr); | |
4520 } | |
4521 | |
4522 static const int kInitialTokenCount = 32; | |
4523 static const intptr_t kTableSize = 128; | |
4524 | |
4525 uint8_t* buffer_; | |
4526 WriteStream stream_; | |
4527 GrowableArray<intptr_t> table_[kTableSize]; | |
4528 const GrowableObjectArray& token_objects_; | |
4529 Object& ident_obj_; | |
4530 LiteralToken& literal_token_; | |
4531 | |
4532 DISALLOW_COPY_AND_ASSIGN(CompressedTokenStreamData); | |
4533 }; | |
4534 | |
4535 | |
4459 RawTokenStream* TokenStream::New(const Scanner::GrowableTokenStream& tokens) { | 4536 RawTokenStream* TokenStream::New(const Scanner::GrowableTokenStream& tokens) { |
4537 // Copy the relevant data out of the scanner into a compressed stream of | |
4538 // tokens. | |
4539 CompressedTokenStreamData data; | |
4460 intptr_t len = tokens.length(); | 4540 intptr_t len = tokens.length(); |
4461 | |
4462 TokenStream& result = TokenStream::Handle(New(len)); | |
4463 // Copy the relevant data out of the scanner's token stream. | |
4464 const String& empty_literal = String::Handle(); | |
4465 for (intptr_t i = 0; i < len; i++) { | 4541 for (intptr_t i = 0; i < len; i++) { |
4466 Scanner::TokenDescriptor token = tokens[i]; | 4542 Scanner::TokenDescriptor token = tokens[i]; |
4467 if (token.literal != NULL) { | 4543 if (token.kind == Token::kIDENT) { // Identifier token. |
4468 result.SetTokenAt(i, token.kind, *(token.literal)); | 4544 if (FLAG_compiler_stats) { |
4469 } else { | 4545 CompilerStats::num_ident_tokens_total += 1; |
4470 result.SetTokenAt(i, token.kind, empty_literal); | 4546 } |
4547 data.AddIdentToken(token.literal); | |
4548 } else if (Token::NeedsLiteralToken(token.kind)) { // Literal token. | |
4549 if (FLAG_compiler_stats) { | |
4550 CompilerStats::num_literal_tokens_total += 1; | |
4551 } | |
4552 data.AddLiteralToken(token.kind, token.literal); | |
4553 } else { // Keyword, pseudo keyword etc. | |
4554 ASSERT(token.kind < Token::kNumTokens); | |
4555 data.AddSimpleToken(token.kind); | |
4471 } | 4556 } |
4472 } | 4557 } |
4558 if (FLAG_compiler_stats) { | |
4559 CompilerStats::num_tokens_total += len; | |
4560 } | |
4561 data.AddSimpleToken(Token::kEOS); // End of stream. | |
4562 | |
4563 // Create and setup the token stream object. | |
4564 const TokenStream& result = TokenStream::Handle(New(data.Length())); | |
4565 data.FinalizeTokenStreamData(result, result.EntryAddr(0)); | |
4473 return result.raw(); | 4566 return result.raw(); |
4474 } | 4567 } |
4475 | 4568 |
4476 | 4569 |
4477 const char* TokenStream::ToCString() const { | 4570 const char* TokenStream::ToCString() const { |
4478 return "TokenStream"; | 4571 return "TokenStream"; |
4479 } | 4572 } |
4480 | 4573 |
4481 | 4574 |
4575 TokenStreamIterator::TokenStreamIterator(const TokenStream& tokens, | |
4576 intptr_t token_pos) | |
4577 : tokens_(tokens), | |
4578 stream_(tokens.EntryAddr(0), tokens.Length()), | |
Ivan Posva
2012/07/02 21:48:32
This is not GC safe.
siva
2012/07/04 01:43:02
Removed the stream_ field and instead use EntryAdd
| |
4579 token_objects_(Array::Handle(tokens.TokenObjects())), | |
4580 obj_(Object::Handle()), | |
4581 cur_token_pos_(token_pos), | |
4582 cur_token_kind_(Token::kILLEGAL), | |
4583 cur_token_obj_index_(-1) { | |
4584 SetCurrentPosition(token_pos); | |
4585 } | |
4586 | |
4587 | |
4588 bool TokenStreamIterator::IsValid() const { | |
4589 return !tokens_.IsNull(); | |
4590 } | |
4591 | |
4592 | |
4593 Token::Kind TokenStreamIterator::LookaheadTokenKind(intptr_t num_tokens) { | |
4594 intptr_t saved_position = stream_.CurrentPosition(); | |
4595 Token::Kind kind = Token::kILLEGAL; | |
4596 intptr_t value = -1; | |
4597 intptr_t count = 0; | |
4598 while (count < num_tokens && value != Token::kEOS) { | |
4599 value = ReadToken(); | |
4600 count += 1; | |
4601 } | |
4602 if (value < Token::kNumTokens) { | |
4603 kind = static_cast<Token::Kind>(value); | |
4604 } else { | |
4605 value = value - Token::kNumTokens; | |
4606 obj_ = token_objects_.At(value); | |
4607 if (obj_.IsLiteralToken()) { | |
4608 const LiteralToken& literal_token = LiteralToken::Cast(obj_); | |
4609 kind = literal_token.kind(); | |
4610 } else { | |
4611 ASSERT(obj_.IsString()); // Must be an identifier. | |
4612 kind = Token::kIDENT; | |
4613 } | |
4614 } | |
4615 stream_.SetPosition(saved_position); | |
4616 return kind; | |
4617 } | |
4618 | |
4619 | |
4620 intptr_t TokenStreamIterator::CurrentPosition() const { | |
4621 return cur_token_pos_; | |
4622 } | |
4623 | |
4624 | |
4625 void TokenStreamIterator::SetCurrentPosition(intptr_t value) { | |
4626 stream_.SetPosition(value); | |
4627 Advance(); | |
4628 } | |
4629 | |
4630 | |
4631 void TokenStreamIterator::Advance() { | |
4632 cur_token_pos_ = stream_.CurrentPosition(); | |
4633 intptr_t value = ReadToken(); | |
4634 if (value < Token::kNumTokens) { | |
4635 cur_token_kind_ = static_cast<Token::Kind>(value); | |
4636 cur_token_obj_index_ = -1; | |
4637 return; | |
4638 } | |
4639 cur_token_obj_index_ = value - Token::kNumTokens; | |
4640 obj_ = token_objects_.At(cur_token_obj_index_); | |
4641 if (obj_.IsLiteralToken()) { | |
4642 const LiteralToken& literal_token = LiteralToken::Cast(obj_); | |
4643 cur_token_kind_ = literal_token.kind(); | |
4644 return; | |
4645 } | |
4646 ASSERT(obj_.IsString()); // Must be an identifier. | |
4647 cur_token_kind_ = Token::kIDENT; | |
4648 } | |
4649 | |
4650 | |
4651 RawObject* TokenStreamIterator::CurrentToken() const { | |
4652 if (cur_token_obj_index_ != -1) { | |
4653 return token_objects_.At(cur_token_obj_index_); | |
4654 } else { | |
4655 return Smi::New(cur_token_kind_); | |
4656 } | |
4657 } | |
4658 | |
4659 | |
4660 RawString* TokenStreamIterator::CurrentLiteral() const { | |
4661 obj_ = CurrentToken(); | |
4662 return MakeLiteralToken(obj_); | |
4663 } | |
4664 | |
4665 | |
4666 RawString* TokenStreamIterator::MakeLiteralToken(const Object& obj) const { | |
4667 if (obj.IsString()) { | |
4668 return reinterpret_cast<RawString*>(obj.raw()); | |
4669 } else if (obj.IsSmi()) { | |
4670 Token::Kind kind = static_cast<Token::Kind>( | |
4671 Smi::Value(reinterpret_cast<RawSmi*>(obj.raw()))); | |
4672 ASSERT(kind < Token::kNumTokens); | |
4673 if (Token::IsPseudoKeyword(kind) || Token::IsKeyword(kind)) { | |
4674 Isolate* isolate = Isolate::Current(); | |
4675 ObjectStore* object_store = isolate->object_store(); | |
4676 String& str = String::Handle(isolate, String::null()); | |
4677 const Array& symbols = Array::Handle(isolate, | |
4678 object_store->keyword_symbols()); | |
4679 ASSERT(!symbols.IsNull()); | |
4680 str ^= symbols.At(kind - Token::kFirstKeyword); | |
4681 ASSERT(!str.IsNull()); | |
4682 return str.raw(); | |
4683 } | |
4684 return String::NewSymbol(Token::Str(kind)); | |
4685 } else { | |
4686 ASSERT(obj.IsLiteralToken()); // Must be a literal token. | |
4687 const LiteralToken& literal_token = LiteralToken::Cast(obj); | |
4688 return literal_token.literal(); | |
4689 } | |
4690 } | |
4691 | |
4692 | |
4482 RawString* Script::source() const { | 4693 RawString* Script::source() const { |
4483 String& source = String::Handle(raw_ptr()->source_); | 4694 String& source = String::Handle(raw_ptr()->source_); |
4484 if (source.IsNull()) { | 4695 if (source.IsNull()) { |
4485 const TokenStream& token_stream = TokenStream::Handle(tokens()); | 4696 const TokenStream& token_stream = TokenStream::Handle(tokens()); |
4486 return token_stream.GenerateSource(); | 4697 return token_stream.GenerateSource(); |
4487 } else { | 4698 } else { |
4488 return raw_ptr()->source_; | 4699 return raw_ptr()->source_; |
4489 } | 4700 } |
4490 } | 4701 } |
4491 | 4702 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4526 CompilerStats::src_length += src.Length(); | 4737 CompilerStats::src_length += src.Length(); |
4527 } | 4738 } |
4528 } | 4739 } |
4529 | 4740 |
4530 | 4741 |
4531 void Script::GetTokenLocation(intptr_t token_pos, | 4742 void Script::GetTokenLocation(intptr_t token_pos, |
4532 intptr_t* line, | 4743 intptr_t* line, |
4533 intptr_t* column) const { | 4744 intptr_t* column) const { |
4534 const String& src = String::Handle(source()); | 4745 const String& src = String::Handle(source()); |
4535 const String& dummy_key = String::Handle(String::New("")); | 4746 const String& dummy_key = String::Handle(String::New("")); |
4747 const TokenStream& tkns = TokenStream::Handle(tokens()); | |
4748 intptr_t src_pos = tkns.ComputeSourcePosition(token_pos); | |
4536 Scanner scanner(src, dummy_key); | 4749 Scanner scanner(src, dummy_key); |
4537 scanner.ScanTo(token_pos); | 4750 scanner.ScanTo(src_pos); |
4538 *line = scanner.CurrentPosition().line; | 4751 *line = scanner.CurrentPosition().line; |
4539 *column = scanner.CurrentPosition().column; | 4752 *column = scanner.CurrentPosition().column; |
4540 } | 4753 } |
4541 | 4754 |
4542 | 4755 |
4543 void Script::TokenRangeAtLine(intptr_t line_number, | 4756 void Script::TokenRangeAtLine(intptr_t line_number, |
4544 intptr_t* first_token_index, | 4757 intptr_t* first_token_index, |
4545 intptr_t* last_token_index) const { | 4758 intptr_t* last_token_index) const { |
4546 const String& src = String::Handle(source()); | 4759 const String& src = String::Handle(source()); |
4547 const String& dummy_key = String::Handle(String::New("")); | 4760 const String& dummy_key = String::Handle(String::New("")); |
(...skipping 5710 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
10258 const String& str = String::Handle(pattern()); | 10471 const String& str = String::Handle(pattern()); |
10259 const char* format = "JSRegExp: pattern=%s flags=%s"; | 10472 const char* format = "JSRegExp: pattern=%s flags=%s"; |
10260 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags()); | 10473 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags()); |
10261 char* chars = reinterpret_cast<char*>( | 10474 char* chars = reinterpret_cast<char*>( |
10262 Isolate::Current()->current_zone()->Allocate(len + 1)); | 10475 Isolate::Current()->current_zone()->Allocate(len + 1)); |
10263 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags()); | 10476 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags()); |
10264 return chars; | 10477 return chars; |
10265 } | 10478 } |
10266 | 10479 |
10267 } // namespace dart | 10480 } // namespace dart |
OLD | NEW |