Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(205)

Side by Side Diff: src/api.cc

Issue 10905075: Revert r12430, r12432, r12433 (basic support for Latin1). (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « include/v8.h ('k') | src/factory.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 3839 matching lines...) Expand 10 before | Expand all | Expand 10 after
3850 if (IsDeadCheck(isolate, "v8::String::WriteUtf8()")) return 0; 3850 if (IsDeadCheck(isolate, "v8::String::WriteUtf8()")) return 0;
3851 LOG_API(isolate, "String::WriteUtf8"); 3851 LOG_API(isolate, "String::WriteUtf8");
3852 ENTER_V8(isolate); 3852 ENTER_V8(isolate);
3853 i::Handle<i::String> str = Utils::OpenHandle(this); 3853 i::Handle<i::String> str = Utils::OpenHandle(this);
3854 if (options & HINT_MANY_WRITES_EXPECTED) { 3854 if (options & HINT_MANY_WRITES_EXPECTED) {
3855 FlattenString(str); // Flatten the string for efficiency. 3855 FlattenString(str); // Flatten the string for efficiency.
3856 } 3856 }
3857 int string_length = str->length(); 3857 int string_length = str->length();
3858 if (str->IsAsciiRepresentation()) { 3858 if (str->IsAsciiRepresentation()) {
3859 int len; 3859 int len;
3860 if (capacity == kUndefinedLength) { 3860 if (capacity == -1) {
3861 capacity = str->length() + 1; 3861 capacity = str->length() + 1;
3862 len = string_length; 3862 len = string_length;
3863 } else { 3863 } else {
3864 len = i::Min(capacity, str->length()); 3864 len = i::Min(capacity, str->length());
3865 } 3865 }
3866 i::String::WriteToFlat(*str, buffer, 0, len); 3866 i::String::WriteToFlat(*str, buffer, 0, len);
3867 if (nchars_ref != NULL) *nchars_ref = len; 3867 if (nchars_ref != NULL) *nchars_ref = len;
3868 if (!(options & NO_NULL_TERMINATION) && capacity > len) { 3868 if (!(options & NO_NULL_TERMINATION) && capacity > len) {
3869 buffer[len] = '\0'; 3869 buffer[len] = '\0';
3870 return len + 1; 3870 return len + 1;
3871 } 3871 }
3872 return len; 3872 return len;
3873 } 3873 }
3874 3874
3875 if (capacity == kUndefinedLength || capacity / 3 >= string_length) { 3875 if (capacity == -1 || capacity / 3 >= string_length) {
3876 int32_t previous = unibrow::Utf16::kNoPreviousCharacter; 3876 int32_t previous = unibrow::Utf16::kNoPreviousCharacter;
3877 const int kMaxRecursion = 100; 3877 const int kMaxRecursion = 100;
3878 int utf8_bytes = 3878 int utf8_bytes =
3879 RecursivelySerializeToUtf8(*str, 3879 RecursivelySerializeToUtf8(*str,
3880 buffer, 3880 buffer,
3881 0, 3881 0,
3882 string_length, 3882 string_length,
3883 kMaxRecursion, 3883 kMaxRecursion,
3884 previous, 3884 previous,
3885 &previous); 3885 &previous);
(...skipping 10 matching lines...) Expand all
3896 // Recurse once. This time around the string is flat and the serializing 3896 // Recurse once. This time around the string is flat and the serializing
3897 // with recursion will certainly succeed. 3897 // with recursion will certainly succeed.
3898 return WriteUtf8(buffer, capacity, nchars_ref, options); 3898 return WriteUtf8(buffer, capacity, nchars_ref, options);
3899 } else if (capacity >= string_length) { 3899 } else if (capacity >= string_length) {
3900 // First check that the buffer is large enough. If it is, then recurse 3900 // First check that the buffer is large enough. If it is, then recurse
3901 // once without a capacity limit, which will get into the other branch of 3901 // once without a capacity limit, which will get into the other branch of
3902 // this 'if'. 3902 // this 'if'.
3903 int utf8_bytes = i::Utf8Length(str); 3903 int utf8_bytes = i::Utf8Length(str);
3904 if ((options & NO_NULL_TERMINATION) == 0) utf8_bytes++; 3904 if ((options & NO_NULL_TERMINATION) == 0) utf8_bytes++;
3905 if (utf8_bytes <= capacity) { 3905 if (utf8_bytes <= capacity) {
3906 return WriteUtf8(buffer, kUndefinedLength, nchars_ref, options); 3906 return WriteUtf8(buffer, -1, nchars_ref, options);
3907 } 3907 }
3908 } 3908 }
3909 3909
3910 // Slow case. 3910 // Slow case.
3911 i::StringInputBuffer& write_input_buffer = *isolate->write_input_buffer(); 3911 i::StringInputBuffer& write_input_buffer = *isolate->write_input_buffer();
3912 isolate->string_tracker()->RecordWrite(str); 3912 isolate->string_tracker()->RecordWrite(str);
3913 3913
3914 write_input_buffer.Reset(0, *str); 3914 write_input_buffer.Reset(0, *str);
3915 int len = str->length(); 3915 int len = str->length();
3916 // Encode the first K - 3 bytes directly into the buffer since we 3916 // Encode the first K - 3 bytes directly into the buffer since we
3917 // know there's room for them. If no capacity is given we copy all 3917 // know there's room for them. If no capacity is given we copy all
3918 // of them here. 3918 // of them here.
3919 int fast_end = capacity - (unibrow::Utf8::kMaxEncodedSize - 1); 3919 int fast_end = capacity - (unibrow::Utf8::kMaxEncodedSize - 1);
3920 int i; 3920 int i;
3921 int pos = 0; 3921 int pos = 0;
3922 int nchars = 0; 3922 int nchars = 0;
3923 int previous = unibrow::Utf16::kNoPreviousCharacter; 3923 int previous = unibrow::Utf16::kNoPreviousCharacter;
3924 for (i = 0; 3924 for (i = 0; i < len && (capacity == -1 || pos < fast_end); i++) {
3925 i < len && (capacity == kUndefinedLength || pos < fast_end);
3926 i++) {
3927 i::uc32 c = write_input_buffer.GetNext(); 3925 i::uc32 c = write_input_buffer.GetNext();
3928 int written = unibrow::Utf8::Encode(buffer + pos, c, previous); 3926 int written = unibrow::Utf8::Encode(buffer + pos, c, previous);
3929 pos += written; 3927 pos += written;
3930 nchars++; 3928 nchars++;
3931 previous = c; 3929 previous = c;
3932 } 3930 }
3933 if (i < len) { 3931 if (i < len) {
3934 // For the last characters we need to check the length for each one 3932 // For the last characters we need to check the length for each one
3935 // because they may be longer than the remaining space in the 3933 // because they may be longer than the remaining space in the
3936 // buffer. 3934 // buffer.
(...skipping 25 matching lines...) Expand all
3962 } else { 3960 } else {
3963 // We've reached the end of the buffer 3961 // We've reached the end of the buffer
3964 break; 3962 break;
3965 } 3963 }
3966 } 3964 }
3967 previous = c; 3965 previous = c;
3968 } 3966 }
3969 } 3967 }
3970 if (nchars_ref != NULL) *nchars_ref = nchars; 3968 if (nchars_ref != NULL) *nchars_ref = nchars;
3971 if (!(options & NO_NULL_TERMINATION) && 3969 if (!(options & NO_NULL_TERMINATION) &&
3972 (i == len && (capacity == kUndefinedLength || pos < capacity))) { 3970 (i == len && (capacity == -1 || pos < capacity))) {
3973 buffer[pos++] = '\0'; 3971 buffer[pos++] = '\0';
3974 } 3972 }
3975 return pos; 3973 return pos;
3976 } 3974 }
3977 3975
3978 3976
3979 int String::WriteAscii(char* buffer, 3977 int String::WriteAscii(char* buffer,
3980 int start, 3978 int start,
3981 int length, 3979 int length,
3982 int options) const { 3980 int options) const {
3983 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); 3981 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3984 if (IsDeadCheck(isolate, "v8::String::WriteAscii()")) return 0; 3982 if (IsDeadCheck(isolate, "v8::String::WriteAscii()")) return 0;
3985 LOG_API(isolate, "String::WriteAscii"); 3983 LOG_API(isolate, "String::WriteAscii");
3986 ENTER_V8(isolate); 3984 ENTER_V8(isolate);
3987 ASSERT(start >= 0 && length >= kUndefinedLength); 3985 ASSERT(start >= 0 && length >= -1);
3988 i::Handle<i::String> str = Utils::OpenHandle(this); 3986 i::Handle<i::String> str = Utils::OpenHandle(this);
3989 isolate->string_tracker()->RecordWrite(str); 3987 isolate->string_tracker()->RecordWrite(str);
3990 if (options & HINT_MANY_WRITES_EXPECTED) { 3988 if (options & HINT_MANY_WRITES_EXPECTED) {
3991 FlattenString(str); // Flatten the string for efficiency. 3989 FlattenString(str); // Flatten the string for efficiency.
3992 } 3990 }
3993 3991
3994 if (str->IsAsciiRepresentation()) { 3992 if (str->IsAsciiRepresentation()) {
3995 // WriteToFlat is faster than using the StringInputBuffer. 3993 // WriteToFlat is faster than using the StringInputBuffer.
3996 if (length == kUndefinedLength) length = str->length() + 1; 3994 if (length == -1) length = str->length() + 1;
3997 int len = i::Min(length, str->length() - start); 3995 int len = i::Min(length, str->length() - start);
3998 i::String::WriteToFlat(*str, buffer, start, start + len); 3996 i::String::WriteToFlat(*str, buffer, start, start + len);
3999 if (!(options & PRESERVE_ASCII_NULL)) { 3997 if (!(options & PRESERVE_ASCII_NULL)) {
4000 for (int i = 0; i < len; i++) { 3998 for (int i = 0; i < len; i++) {
4001 if (buffer[i] == '\0') buffer[i] = ' '; 3999 if (buffer[i] == '\0') buffer[i] = ' ';
4002 } 4000 }
4003 } 4001 }
4004 if (!(options & NO_NULL_TERMINATION) && length > len) { 4002 if (!(options & NO_NULL_TERMINATION) && length > len) {
4005 buffer[len] = '\0'; 4003 buffer[len] = '\0';
4006 } 4004 }
4007 return len; 4005 return len;
4008 } 4006 }
4009 4007
4010 i::StringInputBuffer& write_input_buffer = *isolate->write_input_buffer(); 4008 i::StringInputBuffer& write_input_buffer = *isolate->write_input_buffer();
4011 int end = length; 4009 int end = length;
4012 if ((length == kUndefinedLength) || (length > str->length() - start)) { 4010 if ((length == -1) || (length > str->length() - start)) {
4013 end = str->length() - start; 4011 end = str->length() - start;
4014 } 4012 }
4015 if (end < 0) return 0; 4013 if (end < 0) return 0;
4016 write_input_buffer.Reset(start, *str); 4014 write_input_buffer.Reset(start, *str);
4017 int i; 4015 int i;
4018 for (i = 0; i < end; i++) { 4016 for (i = 0; i < end; i++) {
4019 char c = static_cast<char>(write_input_buffer.GetNext()); 4017 char c = static_cast<char>(write_input_buffer.GetNext());
4020 if (c == '\0' && !(options & PRESERVE_ASCII_NULL)) c = ' '; 4018 if (c == '\0' && !(options & PRESERVE_ASCII_NULL)) c = ' ';
4021 buffer[i] = c; 4019 buffer[i] = c;
4022 } 4020 }
4023 if (!(options & NO_NULL_TERMINATION) && (length == -1 || i < length)) { 4021 if (!(options & NO_NULL_TERMINATION) && (length == -1 || i < length)) {
4024 buffer[i] = '\0'; 4022 buffer[i] = '\0';
4025 } 4023 }
4026 return i; 4024 return i;
4027 } 4025 }
4028 4026
4029 4027
4030 int String::WriteLatin1(char* buffer,
4031 int start,
4032 int length,
4033 int options) const {
4034 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
4035 if (IsDeadCheck(isolate, "v8::String::WriteLatin1()")) return 0;
4036 LOG_API(isolate, "String::WriteLatin1");
4037 ENTER_V8(isolate);
4038 ASSERT(start >= 0 && length >= kUndefinedLength);
4039 i::Handle<i::String> str = Utils::OpenHandle(this);
4040 isolate->string_tracker()->RecordWrite(str);
4041 if (options & HINT_MANY_WRITES_EXPECTED) {
4042 FlattenString(str); // Flatten the string for efficiency.
4043 }
4044
4045 if (length == kUndefinedLength) length = str->length() + 1;
4046 int len = i::Min(length, str->length() - start);
4047 i::String::WriteToFlat(*str, buffer, start, start + len);
4048 if (!(options & NO_NULL_TERMINATION) && length > len) {
4049 buffer[len] = '\0';
4050 }
4051 return len;
4052 }
4053
4054
4055 int String::Write(uint16_t* buffer, 4028 int String::Write(uint16_t* buffer,
4056 int start, 4029 int start,
4057 int length, 4030 int length,
4058 int options) const { 4031 int options) const {
4059 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); 4032 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
4060 if (IsDeadCheck(isolate, "v8::String::Write()")) return 0; 4033 if (IsDeadCheck(isolate, "v8::String::Write()")) return 0;
4061 LOG_API(isolate, "String::Write"); 4034 LOG_API(isolate, "String::Write");
4062 ENTER_V8(isolate); 4035 ENTER_V8(isolate);
4063 ASSERT(start >= 0 && length >= kUndefinedLength); 4036 ASSERT(start >= 0 && length >= -1);
4064 i::Handle<i::String> str = Utils::OpenHandle(this); 4037 i::Handle<i::String> str = Utils::OpenHandle(this);
4065 isolate->string_tracker()->RecordWrite(str); 4038 isolate->string_tracker()->RecordWrite(str);
4066 if (options & HINT_MANY_WRITES_EXPECTED) { 4039 if (options & HINT_MANY_WRITES_EXPECTED) {
4067 // Flatten the string for efficiency. This applies whether we are 4040 // Flatten the string for efficiency. This applies whether we are
4068 // using StringInputBuffer or Get(i) to access the characters. 4041 // using StringInputBuffer or Get(i) to access the characters.
4069 FlattenString(str); 4042 FlattenString(str);
4070 } 4043 }
4071 int end = start + length; 4044 int end = start + length;
4072 if ((length == kUndefinedLength) || (length > str->length() - start) ) 4045 if ((length == -1) || (length > str->length() - start) )
4073 end = str->length(); 4046 end = str->length();
4074 if (end < 0) return 0; 4047 if (end < 0) return 0;
4075 i::String::WriteToFlat(*str, buffer, start, end); 4048 i::String::WriteToFlat(*str, buffer, start, end);
4076 if (!(options & NO_NULL_TERMINATION) && 4049 if (!(options & NO_NULL_TERMINATION) &&
4077 (length == -1 || end - start < length)) { 4050 (length == -1 || end - start < length)) {
4078 buffer[end - start] = '\0'; 4051 buffer[end - start] = '\0';
4079 } 4052 }
4080 return end - start; 4053 return end - start;
4081 } 4054 }
4082 4055
(...skipping 10 matching lines...) Expand all
4093 4066
4094 bool v8::String::IsExternalAscii() const { 4067 bool v8::String::IsExternalAscii() const {
4095 i::Handle<i::String> str = Utils::OpenHandle(this); 4068 i::Handle<i::String> str = Utils::OpenHandle(this);
4096 if (IsDeadCheck(str->GetIsolate(), "v8::String::IsExternalAscii()")) { 4069 if (IsDeadCheck(str->GetIsolate(), "v8::String::IsExternalAscii()")) {
4097 return false; 4070 return false;
4098 } 4071 }
4099 return i::StringShape(*str).IsExternalAscii(); 4072 return i::StringShape(*str).IsExternalAscii();
4100 } 4073 }
4101 4074
4102 4075
4103 void v8::String::VerifyExternalStringEncoding(int encoding) const { 4076 void v8::String::VerifyExternalStringResource(
4104 typedef internal::Internals I; 4077 v8::String::ExternalStringResource* value) const {
4105 i::Handle<i::String> str = Utils::OpenHandle(this); 4078 i::Handle<i::String> str = Utils::OpenHandle(this);
4106 switch (encoding) { 4079 const v8::String::ExternalStringResource* expected;
4107 case UTF_16_ENCODING | ASCII_HINT: 4080 if (i::StringShape(*str).IsExternalTwoByte()) {
4108 CHECK(str->HasOnlyAsciiChars()); 4081 const void* resource =
4109 // Fall through 4082 i::Handle<i::ExternalTwoByteString>::cast(str)->resource();
4110 case UTF_16_ENCODING | NOT_ASCII_HINT : 4083 expected = reinterpret_cast<const ExternalStringResource*>(resource);
4111 CHECK(str->IsExternalTwoByteString()); 4084 } else {
4112 break; 4085 expected = NULL;
4113 case LATIN1_ENCODING | ASCII_HINT:
4114 CHECK(str->IsExternalAsciiString());
4115 break;
4116 default:
4117 CHECK_EQ(INVALID_ENCODING, encoding);
4118 CHECK(!str->IsExternalString());
4119 break;
4120 } 4086 }
4087 CHECK_EQ(expected, value);
4121 } 4088 }
4122 4089
4123 4090
4124 void v8::String::VerifyExternalStringResourceBase(
4125 v8::String::ExternalStringResourceBase* value) const {
4126 i::Handle<i::String> str = Utils::OpenHandle(this);
4127 i::StringShape shape(*str);
4128 const void* expected;
4129 // We expect an external string at this point since GetExternalStringEncoding
4130 // should have already been called to rule out non-external strings.
4131 if (i::StringShape(*str).IsExternalTwoByte()) {
4132 expected = i::ExternalTwoByteString::cast(*str)->resource();
4133 } else {
4134 ASSERT(i::StringShape(*str).IsExternalAscii());
4135 expected = i::ExternalAsciiString::cast(*str)->resource();
4136 }
4137
4138 CHECK_EQ(expected,
4139 reinterpret_cast<const ExternalStringResourceBase*>(value));
4140 }
4141
4142
4143 const v8::String::ExternalAsciiStringResource* 4091 const v8::String::ExternalAsciiStringResource*
4144 v8::String::GetExternalAsciiStringResource() const { 4092 v8::String::GetExternalAsciiStringResource() const {
4145 i::Handle<i::String> str = Utils::OpenHandle(this); 4093 i::Handle<i::String> str = Utils::OpenHandle(this);
4146 if (IsDeadCheck(str->GetIsolate(), 4094 if (IsDeadCheck(str->GetIsolate(),
4147 "v8::String::GetExternalAsciiStringResource()")) { 4095 "v8::String::GetExternalAsciiStringResource()")) {
4148 return NULL; 4096 return NULL;
4149 } 4097 }
4150 if (i::StringShape(*str).IsExternalAscii()) { 4098 if (i::StringShape(*str).IsExternalAscii()) {
4151 const void* resource = 4099 const void* resource =
4152 i::Handle<i::ExternalAsciiString>::cast(str)->resource(); 4100 i::Handle<i::ExternalAsciiString>::cast(str)->resource();
(...skipping 593 matching lines...) Expand 10 before | Expand all | Expand 10 after
4746 Local<String> v8::String::Empty() { 4694 Local<String> v8::String::Empty() {
4747 i::Isolate* isolate = i::Isolate::Current(); 4695 i::Isolate* isolate = i::Isolate::Current();
4748 if (!EnsureInitializedForIsolate(isolate, "v8::String::Empty()")) { 4696 if (!EnsureInitializedForIsolate(isolate, "v8::String::Empty()")) {
4749 return v8::Local<String>(); 4697 return v8::Local<String>();
4750 } 4698 }
4751 LOG_API(isolate, "String::Empty()"); 4699 LOG_API(isolate, "String::Empty()");
4752 return Utils::ToLocal(isolate->factory()->empty_symbol()); 4700 return Utils::ToLocal(isolate->factory()->empty_symbol());
4753 } 4701 }
4754 4702
4755 4703
4756 static i::Handle<i::String> NewOneByteEncodedString( 4704 Local<String> v8::String::New(const char* data, int length) {
4757 i::Factory* factory, const char* data, int length, int encoding) {
4758 if (length == String::kUndefinedLength) length = i::StrLength(data);
4759 typedef v8::String S;
4760
4761 static const int kAsciiHintShift = 16;
4762 ASSERT(IS_POWER_OF_TWO(encoding & S::kAsciiHintMask));
4763 i::String::AsciiHint ascii_hint =
4764 static_cast<i::String::AsciiHint>(encoding >> kAsciiHintShift);
4765 STATIC_ASSERT(i::String::MAYBE_ASCII == 0);
4766 STATIC_ASSERT(i::String::NOT_ASCII ==
4767 (v8::String::NOT_ASCII_HINT >> kAsciiHintShift));
4768 STATIC_ASSERT(i::String::ASCII ==
4769 (v8::String::ASCII_HINT >> kAsciiHintShift));
4770
4771 int masked_encoding = encoding & S::kStringEncodingMask;
4772
4773 if (masked_encoding == S::UTF_8_ENCODING) {
4774 return factory->NewStringFromUtf8(
4775 i::Vector<const char>(data, length), i::NOT_TENURED, ascii_hint);
4776 } else if (masked_encoding == S::LATIN1_ENCODING) {
4777 return factory->NewStringFromLatin1(
4778 i::Vector<const char>(data, length), i::NOT_TENURED, ascii_hint);
4779 } else { // Wrong encoding.
4780 return i::Handle<i::String>();
4781 }
4782 }
4783
4784
4785 Local<String> v8::String::New(
4786 const char* data, int length, int encoding) {
4787 i::Isolate* isolate = i::Isolate::Current(); 4705 i::Isolate* isolate = i::Isolate::Current();
4788 EnsureInitializedForIsolate(isolate, "v8::String::New()"); 4706 EnsureInitializedForIsolate(isolate, "v8::String::New()");
4789 LOG_API(isolate, "String::New(char)"); 4707 LOG_API(isolate, "String::New(char)");
4790 if (length == 0) return Empty(); 4708 if (length == 0) return Empty();
4791 ENTER_V8(isolate); 4709 ENTER_V8(isolate);
4792 return Utils::ToLocal( 4710 if (length == -1) length = i::StrLength(data);
4793 NewOneByteEncodedString(isolate->factory(), data, length, encoding)); 4711 i::Handle<i::String> result =
4712 isolate->factory()->NewStringFromUtf8(
4713 i::Vector<const char>(data, length));
4714 return Utils::ToLocal(result);
4794 } 4715 }
4795 4716
4796 4717
4797 Local<String> v8::String::Concat(Handle<String> left, Handle<String> right) { 4718 Local<String> v8::String::Concat(Handle<String> left, Handle<String> right) {
4798 i::Handle<i::String> left_string = Utils::OpenHandle(*left); 4719 i::Handle<i::String> left_string = Utils::OpenHandle(*left);
4799 i::Isolate* isolate = left_string->GetIsolate(); 4720 i::Isolate* isolate = left_string->GetIsolate();
4800 EnsureInitializedForIsolate(isolate, "v8::String::New()"); 4721 EnsureInitializedForIsolate(isolate, "v8::String::New()");
4801 LOG_API(isolate, "String::New(char)"); 4722 LOG_API(isolate, "String::New(char)");
4802 ENTER_V8(isolate); 4723 ENTER_V8(isolate);
4803 i::Handle<i::String> right_string = Utils::OpenHandle(*right); 4724 i::Handle<i::String> right_string = Utils::OpenHandle(*right);
4804 i::Handle<i::String> result = isolate->factory()->NewConsString(left_string, 4725 i::Handle<i::String> result = isolate->factory()->NewConsString(left_string,
4805 right_string); 4726 right_string);
4806 return Utils::ToLocal(result); 4727 return Utils::ToLocal(result);
4807 } 4728 }
4808 4729
4809 4730
4810 Local<String> v8::String::NewUndetectable( 4731 Local<String> v8::String::NewUndetectable(const char* data, int length) {
4811 const char* data, int length, int encoding) {
4812 i::Isolate* isolate = i::Isolate::Current(); 4732 i::Isolate* isolate = i::Isolate::Current();
4813 EnsureInitializedForIsolate(isolate, "v8::String::NewUndetectable()"); 4733 EnsureInitializedForIsolate(isolate, "v8::String::NewUndetectable()");
4814 LOG_API(isolate, "String::NewUndetectable(char)"); 4734 LOG_API(isolate, "String::NewUndetectable(char)");
4815 ENTER_V8(isolate); 4735 ENTER_V8(isolate);
4736 if (length == -1) length = i::StrLength(data);
4816 i::Handle<i::String> result = 4737 i::Handle<i::String> result =
4817 NewOneByteEncodedString(isolate->factory(), data, length, encoding); 4738 isolate->factory()->NewStringFromUtf8(
4739 i::Vector<const char>(data, length));
4818 result->MarkAsUndetectable(); 4740 result->MarkAsUndetectable();
4819 return Utils::ToLocal(result); 4741 return Utils::ToLocal(result);
4820 } 4742 }
4821 4743
4822 4744
4823 static int TwoByteStringLength(const uint16_t* data) { 4745 static int TwoByteStringLength(const uint16_t* data) {
4824 int length = 0; 4746 int length = 0;
4825 while (data[length] != '\0') length++; 4747 while (data[length] != '\0') length++;
4826 return length; 4748 return length;
4827 } 4749 }
4828 4750
4829 4751
4830 Local<String> v8::String::New(const uint16_t* data, int length) { 4752 Local<String> v8::String::New(const uint16_t* data, int length) {
4831 i::Isolate* isolate = i::Isolate::Current(); 4753 i::Isolate* isolate = i::Isolate::Current();
4832 EnsureInitializedForIsolate(isolate, "v8::String::New()"); 4754 EnsureInitializedForIsolate(isolate, "v8::String::New()");
4833 LOG_API(isolate, "String::New(uint16_)"); 4755 LOG_API(isolate, "String::New(uint16_)");
4834 if (length == 0) return Empty(); 4756 if (length == 0) return Empty();
4835 ENTER_V8(isolate); 4757 ENTER_V8(isolate);
4836 if (length == kUndefinedLength) length = TwoByteStringLength(data); 4758 if (length == -1) length = TwoByteStringLength(data);
4837 i::Handle<i::String> result = 4759 i::Handle<i::String> result =
4838 isolate->factory()->NewStringFromTwoByte( 4760 isolate->factory()->NewStringFromTwoByte(
4839 i::Vector<const uint16_t>(data, length)); 4761 i::Vector<const uint16_t>(data, length));
4840 return Utils::ToLocal(result); 4762 return Utils::ToLocal(result);
4841 } 4763 }
4842 4764
4843 4765
4844 Local<String> v8::String::NewUndetectable(const uint16_t* data, int length) { 4766 Local<String> v8::String::NewUndetectable(const uint16_t* data, int length) {
4845 i::Isolate* isolate = i::Isolate::Current(); 4767 i::Isolate* isolate = i::Isolate::Current();
4846 EnsureInitializedForIsolate(isolate, "v8::String::NewUndetectable()"); 4768 EnsureInitializedForIsolate(isolate, "v8::String::NewUndetectable()");
4847 LOG_API(isolate, "String::NewUndetectable(uint16_)"); 4769 LOG_API(isolate, "String::NewUndetectable(uint16_)");
4848 ENTER_V8(isolate); 4770 ENTER_V8(isolate);
4849 if (length == kUndefinedLength) length = TwoByteStringLength(data); 4771 if (length == -1) length = TwoByteStringLength(data);
4850 i::Handle<i::String> result = 4772 i::Handle<i::String> result =
4851 isolate->factory()->NewStringFromTwoByte( 4773 isolate->factory()->NewStringFromTwoByte(
4852 i::Vector<const uint16_t>(data, length)); 4774 i::Vector<const uint16_t>(data, length));
4853 result->MarkAsUndetectable(); 4775 result->MarkAsUndetectable();
4854 return Utils::ToLocal(result); 4776 return Utils::ToLocal(result);
4855 } 4777 }
4856 4778
4857 4779
4858 i::Handle<i::String> NewExternalStringHandle(i::Isolate* isolate, 4780 i::Handle<i::String> NewExternalStringHandle(i::Isolate* isolate,
4859 v8::String::ExternalStringResource* resource) { 4781 v8::String::ExternalStringResource* resource) {
(...skipping 17 matching lines...) Expand all
4877 EnsureInitializedForIsolate(isolate, "v8::String::NewExternal()"); 4799 EnsureInitializedForIsolate(isolate, "v8::String::NewExternal()");
4878 LOG_API(isolate, "String::NewExternal"); 4800 LOG_API(isolate, "String::NewExternal");
4879 ENTER_V8(isolate); 4801 ENTER_V8(isolate);
4880 CHECK(resource && resource->data()); 4802 CHECK(resource && resource->data());
4881 i::Handle<i::String> result = NewExternalStringHandle(isolate, resource); 4803 i::Handle<i::String> result = NewExternalStringHandle(isolate, resource);
4882 isolate->heap()->external_string_table()->AddString(*result); 4804 isolate->heap()->external_string_table()->AddString(*result);
4883 return Utils::ToLocal(result); 4805 return Utils::ToLocal(result);
4884 } 4806 }
4885 4807
4886 4808
4887 template<class StringResourceType> 4809 bool v8::String::MakeExternal(v8::String::ExternalStringResource* resource) {
4888 static bool MakeStringExternal( 4810 i::Handle<i::String> obj = Utils::OpenHandle(this);
4889 i::Handle<i::String> string, StringResourceType* resource) { 4811 i::Isolate* isolate = obj->GetIsolate();
4890 i::Isolate* isolate = string->GetIsolate();
4891 if (IsDeadCheck(isolate, "v8::String::MakeExternal()")) return false; 4812 if (IsDeadCheck(isolate, "v8::String::MakeExternal()")) return false;
4892 if (i::StringShape(*string).IsExternal()) { 4813 if (i::StringShape(*obj).IsExternalTwoByte()) {
4893 return false; // Already an external string. 4814 return false; // Already an external string.
4894 } 4815 }
4895 ENTER_V8(isolate); 4816 ENTER_V8(isolate);
4896 if (isolate->string_tracker()->IsFreshUnusedString(string)) { 4817 if (isolate->string_tracker()->IsFreshUnusedString(obj)) {
4897 return false; 4818 return false;
4898 } 4819 }
4899 if (isolate->heap()->IsInGCPostProcessing()) { 4820 if (isolate->heap()->IsInGCPostProcessing()) {
4900 return false; 4821 return false;
4901 } 4822 }
4902 CHECK(resource && resource->data()); 4823 CHECK(resource && resource->data());
4903 bool result = string->MakeExternal(resource); 4824 bool result = obj->MakeExternal(resource);
4904 if (result && !string->IsSymbol()) { 4825 if (result && !obj->IsSymbol()) {
4905 isolate->heap()->external_string_table()->AddString(*string); 4826 isolate->heap()->external_string_table()->AddString(*obj);
4906 } 4827 }
4907 return result; 4828 return result;
4908 } 4829 }
4909 4830
4910 4831
4911 bool v8::String::MakeExternal(ExternalStringResource* resource) {
4912 i::Handle<i::String> obj = Utils::OpenHandle(this);
4913 return MakeStringExternal(obj, resource);
4914 }
4915
4916
4917 bool v8::String::MakeExternal(ExternalAsciiStringResource* resource) {
4918 i::Handle<i::String> obj = Utils::OpenHandle(this);
4919 ASSERT(obj->HasOnlyAsciiChars());
4920 return MakeStringExternal(obj, resource);
4921 }
4922
4923
4924 Local<String> v8::String::NewExternal( 4832 Local<String> v8::String::NewExternal(
4925 v8::String::ExternalAsciiStringResource* resource) { 4833 v8::String::ExternalAsciiStringResource* resource) {
4926 i::Isolate* isolate = i::Isolate::Current(); 4834 i::Isolate* isolate = i::Isolate::Current();
4927 EnsureInitializedForIsolate(isolate, "v8::String::NewExternal()"); 4835 EnsureInitializedForIsolate(isolate, "v8::String::NewExternal()");
4928 LOG_API(isolate, "String::NewExternal"); 4836 LOG_API(isolate, "String::NewExternal");
4929 ENTER_V8(isolate); 4837 ENTER_V8(isolate);
4930 CHECK(resource && resource->data()); 4838 CHECK(resource && resource->data());
4931 i::Handle<i::String> result = NewExternalAsciiStringHandle(isolate, resource); 4839 i::Handle<i::String> result = NewExternalAsciiStringHandle(isolate, resource);
4932 isolate->heap()->external_string_table()->AddString(*result); 4840 isolate->heap()->external_string_table()->AddString(*result);
4933 return Utils::ToLocal(result); 4841 return Utils::ToLocal(result);
4934 } 4842 }
4935 4843
4936 4844
4937 Local<String> v8::String::NewExternal(ExternalLatin1StringResource* resource, 4845 bool v8::String::MakeExternal(
4938 int encoding) { 4846 v8::String::ExternalAsciiStringResource* resource) {
4939 typedef v8::internal::Internals I; 4847 i::Handle<i::String> obj = Utils::OpenHandle(this);
4940 i::Isolate* isolate = i::Isolate::Current(); 4848 i::Isolate* isolate = obj->GetIsolate();
4941 EnsureInitializedForIsolate(isolate, "v8::String::NewExternal()"); 4849 if (IsDeadCheck(isolate, "v8::String::MakeExternal()")) return false;
4942 LOG_API(isolate, "String::NewExternal"); 4850 if (i::StringShape(*obj).IsExternalTwoByte()) {
4851 return false; // Already an external string.
4852 }
4943 ENTER_V8(isolate); 4853 ENTER_V8(isolate);
4944 ASSERT((encoding & kStringEncodingMask) == LATIN1_ENCODING); 4854 if (isolate->string_tracker()->IsFreshUnusedString(obj)) {
4855 return false;
4856 }
4857 if (isolate->heap()->IsInGCPostProcessing()) {
4858 return false;
4859 }
4945 CHECK(resource && resource->data()); 4860 CHECK(resource && resource->data());
4946 int ascii_hint = (encoding & kAsciiHintMask); 4861 bool result = obj->MakeExternal(resource);
4947 i::Handle<i::String> result; 4862 if (result && !obj->IsSymbol()) {
4948 4863 isolate->heap()->external_string_table()->AddString(*obj);
4949 if (ascii_hint == ASCII_HINT ||
4950 (ascii_hint != NOT_ASCII_HINT &&
4951 i::String::IsAscii(resource->data(),
4952 static_cast<int>(resource->length())))) {
4953 // Assert that the ascii hint is correct.
4954 ASSERT(ascii_hint != ASCII_HINT ||
4955 i::String::IsAscii(resource->data(),
4956 static_cast<int>(resource->length())));
4957 result = NewExternalAsciiStringHandle(isolate, resource);
4958 isolate->heap()->external_string_table()->AddString(*result);
4959 } else {
4960 // We cannot simply take the backing store and use it as an ASCII string,
4961 // since it's not. Instead, we convert it to an internal string and dispose
4962 // the external resource.
4963 result = isolate->factory()->NewStringFromLatin1(
4964 i::Vector<const char>(resource->data(),
4965 static_cast<int>(resource->length())),
4966 i::NOT_TENURED,
4967 i::String::NOT_ASCII);
4968 resource->Dispose();
4969 } 4864 }
4970 return Utils::ToLocal(result); 4865 return result;
4971 } 4866 }
4972 4867
4973 4868
4974 bool v8::String::CanMakeExternal() { 4869 bool v8::String::CanMakeExternal() {
4975 if (!internal::FLAG_clever_optimizations) return false; 4870 if (!internal::FLAG_clever_optimizations) return false;
4976 i::Handle<i::String> obj = Utils::OpenHandle(this); 4871 i::Handle<i::String> obj = Utils::OpenHandle(this);
4977 i::Isolate* isolate = obj->GetIsolate(); 4872 i::Isolate* isolate = obj->GetIsolate();
4978 if (IsDeadCheck(isolate, "v8::String::CanMakeExternal()")) return false; 4873 if (IsDeadCheck(isolate, "v8::String::CanMakeExternal()")) return false;
4979 if (isolate->string_tracker()->IsFreshUnusedString(obj)) return false; 4874 if (isolate->string_tracker()->IsFreshUnusedString(obj)) return false;
4980 int size = obj->Size(); // Byte size of the original string. 4875 int size = obj->Size(); // Byte size of the original string.
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
5223 i::Handle<i::JSObject> paragon_handle(i::JSObject::cast(paragon)); 5118 i::Handle<i::JSObject> paragon_handle(i::JSObject::cast(paragon));
5224 EXCEPTION_PREAMBLE(isolate); 5119 EXCEPTION_PREAMBLE(isolate);
5225 ENTER_V8(isolate); 5120 ENTER_V8(isolate);
5226 i::Handle<i::JSObject> result = i::Copy(paragon_handle); 5121 i::Handle<i::JSObject> result = i::Copy(paragon_handle);
5227 has_pending_exception = result.is_null(); 5122 has_pending_exception = result.is_null();
5228 EXCEPTION_BAILOUT_CHECK(isolate, Local<Object>()); 5123 EXCEPTION_BAILOUT_CHECK(isolate, Local<Object>());
5229 return Utils::ToLocal(result); 5124 return Utils::ToLocal(result);
5230 } 5125 }
5231 5126
5232 5127
5233 Local<String> v8::String::NewSymbol( 5128 Local<String> v8::String::NewSymbol(const char* data, int length) {
5234 const char* data, int length, int encoding) {
5235 i::Isolate* isolate = i::Isolate::Current(); 5129 i::Isolate* isolate = i::Isolate::Current();
5236 EnsureInitializedForIsolate(isolate, "v8::String::NewSymbol()"); 5130 EnsureInitializedForIsolate(isolate, "v8::String::NewSymbol()");
5237 LOG_API(isolate, "String::NewSymbol(char)"); 5131 LOG_API(isolate, "String::NewSymbol(char)");
5238 ENTER_V8(isolate); 5132 ENTER_V8(isolate);
5239 if (length == kUndefinedLength) length = i::StrLength(data); 5133 if (length == -1) length = i::StrLength(data);
5240 i::Handle<i::String> result; 5134 i::Handle<i::String> result =
5241 5135 isolate->factory()->LookupSymbol(i::Vector<const char>(data, length));
5242 ASSERT(IS_POWER_OF_TWO(encoding & kAsciiHintMask));
5243 if (((encoding & kStringEncodingMask) == LATIN1_ENCODING) &&
5244 ((encoding & kAsciiHintMask) == NOT_ASCII_HINT ||
5245 !i::String::IsAscii(data, length))) {
5246 result = isolate->factory()->NewStringFromLatin1(
5247 i::Vector<const char>(data, length),
5248 i::NOT_TENURED,
5249 i::String::NOT_ASCII);
5250 result = isolate->factory()->LookupSymbol(result);
5251 } else { // We can handle UTF8 and ASCII strings here.
5252 result =
5253 isolate->factory()->LookupSymbol(i::Vector<const char>(data, length));
5254 }
5255 return Utils::ToLocal(result); 5136 return Utils::ToLocal(result);
5256 } 5137 }
5257 5138
5258 5139
5259 Local<Number> v8::Number::New(double value) { 5140 Local<Number> v8::Number::New(double value) {
5260 i::Isolate* isolate = i::Isolate::Current(); 5141 i::Isolate* isolate = i::Isolate::Current();
5261 EnsureInitializedForIsolate(isolate, "v8::Number::New()"); 5142 EnsureInitializedForIsolate(isolate, "v8::Number::New()");
5262 if (isnan(value)) { 5143 if (isnan(value)) {
5263 // Introduce only canonical NaN value into the VM, to avoid signaling NaNs. 5144 // Introduce only canonical NaN value into the VM, to avoid signaling NaNs.
5264 value = i::OS::nan_value(); 5145 value = i::OS::nan_value();
(...skipping 1389 matching lines...) Expand 10 before | Expand all | Expand 10 after
6654 6535
6655 v->VisitPointers(blocks_.first(), first_block_limit_); 6536 v->VisitPointers(blocks_.first(), first_block_limit_);
6656 6537
6657 for (int i = 1; i < blocks_.length(); i++) { 6538 for (int i = 1; i < blocks_.length(); i++) {
6658 v->VisitPointers(blocks_[i], &blocks_[i][kHandleBlockSize]); 6539 v->VisitPointers(blocks_[i], &blocks_[i][kHandleBlockSize]);
6659 } 6540 }
6660 } 6541 }
6661 6542
6662 6543
6663 } } // namespace v8::internal 6544 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « include/v8.h ('k') | src/factory.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698