OLD | NEW |
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 4506 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4517 int dest_position = 0; | 4517 int dest_position = 0; |
4518 for (int i = 0; i < length; dest_position++) { | 4518 for (int i = 0; i < length; dest_position++) { |
4519 int step; | 4519 int step; |
4520 destination->Set(dest_position, Unescape(source, i, length, &step)); | 4520 destination->Set(dest_position, Unescape(source, i, length, &step)); |
4521 i += step; | 4521 i += step; |
4522 } | 4522 } |
4523 return destination; | 4523 return destination; |
4524 } | 4524 } |
4525 | 4525 |
4526 | 4526 |
| 4527 static const char* const JsonQuotes[128] = { |
| 4528 "\\u0000", "\\u0001", "\\u0002", "\\u0003", |
| 4529 "\\u0004", "\\u0005", "\\u0006", "\\u0007", |
| 4530 "\\b", "\\t", "\\n", "\\u000b", |
| 4531 "\\f", "\\r", "\\u000e", "\\u000f", |
| 4532 "\\u0010", "\\u0011", "\\u0012", "\\u0013", |
| 4533 "\\u0014", "\\u0015", "\\u0016", "\\u0017", |
| 4534 "\\u0018", "\\u0019", "\\u001a", "\\u001b", |
| 4535 "\\u001c", "\\u001d", "\\u001e", "\\u001f", |
| 4536 NULL, NULL, "\\\"", NULL, |
| 4537 NULL, NULL, NULL, NULL, |
| 4538 NULL, NULL, NULL, NULL, |
| 4539 NULL, NULL, NULL, NULL, |
| 4540 NULL, NULL, NULL, NULL, |
| 4541 NULL, NULL, NULL, NULL, |
| 4542 NULL, NULL, NULL, NULL, |
| 4543 NULL, NULL, NULL, NULL, |
| 4544 NULL, NULL, NULL, NULL, |
| 4545 NULL, NULL, NULL, NULL, |
| 4546 NULL, NULL, NULL, NULL, |
| 4547 NULL, NULL, NULL, NULL, |
| 4548 NULL, NULL, NULL, NULL, |
| 4549 NULL, NULL, NULL, NULL, |
| 4550 NULL, NULL, NULL, NULL, |
| 4551 "\\\\", NULL, NULL, NULL, |
| 4552 NULL, NULL, NULL, NULL, |
| 4553 NULL, NULL, NULL, NULL, |
| 4554 NULL, NULL, NULL, NULL, |
| 4555 NULL, NULL, NULL, NULL, |
| 4556 NULL, NULL, NULL, NULL, |
| 4557 NULL, NULL, NULL, NULL, |
| 4558 NULL, NULL, NULL, NULL, |
| 4559 NULL, NULL, NULL, NULL, |
| 4560 }; |
| 4561 |
| 4562 |
| 4563 static const byte JsonQuoteLengths[128] = { |
| 4564 6, 6, 6, 6, 6, 6, 6, 6, |
| 4565 2, 2, 2, 6, 2, 2, 6, 6, |
| 4566 6, 6, 6, 6, 6, 6, 6, 6, |
| 4567 6, 6, 6, 6, 6, 6, 6, 6, |
| 4568 1, 1, 2, 1, 1, 1, 1, 1, |
| 4569 1, 1, 1, 1, 1, 1, 1, 1, |
| 4570 1, 1, 1, 1, 1, 1, 1, 1, |
| 4571 1, 1, 1, 1, 1, 1, 1, 1, |
| 4572 1, 1, 1, 1, 1, 1, 1, 1, |
| 4573 1, 1, 1, 1, 1, 1, 1, 1, |
| 4574 1, 1, 1, 1, 1, 1, 1, 1, |
| 4575 1, 1, 1, 1, 2, 1, 1, 1, |
| 4576 1, 1, 1, 1, 1, 1, 1, 1, |
| 4577 1, 1, 1, 1, 1, 1, 1, 1, |
| 4578 1, 1, 1, 1, 1, 1, 1, 1, |
| 4579 1, 1, 1, 1, 1, 1, 1, 1, |
| 4580 }; |
| 4581 |
| 4582 |
| 4583 template <typename Char> |
| 4584 Char* WriteString(Char* dst, const char* src_string) { |
| 4585 char c; |
| 4586 for (c = *src_string; c; c = *src_string) { |
| 4587 *dst = c; |
| 4588 dst++; |
| 4589 src_string++; |
| 4590 } |
| 4591 return dst; |
| 4592 } |
| 4593 |
| 4594 |
| 4595 template <typename StringType> |
| 4596 MaybeObject* AllocateRawString(int length); |
| 4597 |
| 4598 |
| 4599 template <> |
| 4600 MaybeObject* AllocateRawString<SeqTwoByteString>(int length) { |
| 4601 return Heap::AllocateRawTwoByteString(length); |
| 4602 } |
| 4603 |
| 4604 |
| 4605 template <> |
| 4606 MaybeObject* AllocateRawString<SeqAsciiString>(int length) { |
| 4607 return Heap::AllocateRawAsciiString(length); |
| 4608 } |
| 4609 |
| 4610 |
| 4611 template <typename Char, typename StringType> |
| 4612 static MaybeObject* QuoteJsonString(String* original, |
| 4613 Vector<const Char> characters) { |
| 4614 int length = characters.length(); |
| 4615 int quoted_length = 0; |
| 4616 for (int i = 0; i < length; i++) { |
| 4617 unsigned int c = characters[i]; |
| 4618 if (sizeof(Char) > 1u) { |
| 4619 quoted_length += |
| 4620 (c >= sizeof(JsonQuoteLengths)) ? 1 : JsonQuoteLengths[c]; |
| 4621 } else { |
| 4622 quoted_length += JsonQuoteLengths[c]; |
| 4623 } |
| 4624 } |
| 4625 if (quoted_length == length) { |
| 4626 return Heap::undefined_value(); |
| 4627 } |
| 4628 Counters::quote_json_char_count.Increment(length); |
| 4629 |
| 4630 // Add space for quotes. |
| 4631 quoted_length += 2; |
| 4632 |
| 4633 MaybeObject* new_alloc = AllocateRawString<StringType>(quoted_length); |
| 4634 Object* new_object; |
| 4635 if (!new_alloc->ToObject(&new_object)) { |
| 4636 Counters::quote_json_char_recount.Increment(length); |
| 4637 return new_alloc; |
| 4638 } |
| 4639 StringType* new_string = StringType::cast(new_object); |
| 4640 |
| 4641 |
| 4642 STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqAsciiString::kHeaderSize); |
| 4643 Char* write_cursor = reinterpret_cast<Char*>( |
| 4644 new_string->address() + SeqAsciiString::kHeaderSize); |
| 4645 *(write_cursor++) = '"'; |
| 4646 const Char* read_cursor = characters.start(); |
| 4647 const Char* end = read_cursor + length; |
| 4648 while (read_cursor < end) { |
| 4649 Char c = *(read_cursor++); |
| 4650 if (sizeof(Char) > 1u && static_cast<unsigned>(c) >= sizeof(JsonQuotes)) { |
| 4651 *(write_cursor++) = c; |
| 4652 } else { |
| 4653 const char* replacement = JsonQuotes[static_cast<unsigned>(c)]; |
| 4654 if (!replacement) { |
| 4655 *(write_cursor++) = c; |
| 4656 } else { |
| 4657 write_cursor = WriteString(write_cursor, replacement); |
| 4658 } |
| 4659 } |
| 4660 } |
| 4661 *(write_cursor++) = '"'; |
| 4662 ASSERT_EQ(SeqAsciiString::kHeaderSize + quoted_length * sizeof(Char), |
| 4663 reinterpret_cast<Address>(write_cursor) - new_string->address()); |
| 4664 return new_string; |
| 4665 } |
| 4666 |
| 4667 |
| 4668 static MaybeObject* Runtime_QuoteJSONString(Arguments args) { |
| 4669 NoHandleAllocation ha; |
| 4670 CONVERT_CHECKED(String, str, args[0]); |
| 4671 if (!str->IsFlat()) { |
| 4672 MaybeObject* try_flatten = str->TryFlatten(); |
| 4673 Object* flat; |
| 4674 if (!try_flatten->ToObject(&flat)) { |
| 4675 return try_flatten; |
| 4676 } |
| 4677 str = String::cast(flat); |
| 4678 ASSERT(str->IsFlat()); |
| 4679 } |
| 4680 if (str->IsTwoByteRepresentation()) { |
| 4681 return QuoteJsonString<uc16, SeqTwoByteString>(str, str->ToUC16Vector()); |
| 4682 } else { |
| 4683 return QuoteJsonString<char, SeqAsciiString>(str, str->ToAsciiVector()); |
| 4684 } |
| 4685 } |
| 4686 |
| 4687 |
4527 static MaybeObject* Runtime_StringParseInt(Arguments args) { | 4688 static MaybeObject* Runtime_StringParseInt(Arguments args) { |
4528 NoHandleAllocation ha; | 4689 NoHandleAllocation ha; |
4529 | 4690 |
4530 CONVERT_CHECKED(String, s, args[0]); | 4691 CONVERT_CHECKED(String, s, args[0]); |
4531 CONVERT_SMI_CHECKED(radix, args[1]); | 4692 CONVERT_SMI_CHECKED(radix, args[1]); |
4532 | 4693 |
4533 s->TryFlatten(); | 4694 s->TryFlatten(); |
4534 | 4695 |
4535 RUNTIME_ASSERT(radix == 0 || (2 <= radix && radix <= 36)); | 4696 RUNTIME_ASSERT(radix == 0 || (2 <= radix && radix <= 36)); |
4536 double value = StringToInt(s, radix); | 4697 double value = StringToInt(s, radix); |
(...skipping 5788 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10325 } else { | 10486 } else { |
10326 // Handle last resort GC and make sure to allow future allocations | 10487 // Handle last resort GC and make sure to allow future allocations |
10327 // to grow the heap without causing GCs (if possible). | 10488 // to grow the heap without causing GCs (if possible). |
10328 Counters::gc_last_resort_from_js.Increment(); | 10489 Counters::gc_last_resort_from_js.Increment(); |
10329 Heap::CollectAllGarbage(false); | 10490 Heap::CollectAllGarbage(false); |
10330 } | 10491 } |
10331 } | 10492 } |
10332 | 10493 |
10333 | 10494 |
10334 } } // namespace v8::internal | 10495 } } // namespace v8::internal |
OLD | NEW |