Index: src/factory.cc |
diff --git a/src/factory.cc b/src/factory.cc |
index 86c314c0dbda8c4ea659b32c16a5ef105a6b7fda..3d373fbb5bd85c9708e2c9884e1e3acc86433cbc 100644 |
--- a/src/factory.cc |
+++ b/src/factory.cc |
@@ -212,9 +212,7 @@ template Handle<String> Factory::InternalizeStringWithKey< |
MaybeHandle<String> Factory::NewStringFromOneByte(Vector<const uint8_t> string, |
PretenureFlag pretenure) { |
int length = string.length(); |
- if (length == 1) { |
- return LookupSingleCharacterStringFromCode(string[0]); |
- } |
+ if (length == 1) return LookupSingleCharacterStringFromCode(string[0]); |
Handle<SeqOneByteString> result; |
ASSIGN_RETURN_ON_EXCEPTION( |
isolate(), |
@@ -241,22 +239,55 @@ MaybeHandle<String> Factory::NewStringFromUtf8(Vector<const char> string, |
// since UTF8 is backwards compatible with ASCII. |
return NewStringFromOneByte(Vector<const uint8_t>::cast(string), pretenure); |
} |
+ |
// Non-ASCII and we need to decode. |
- CALL_HEAP_FUNCTION( |
- isolate(), |
- isolate()->heap()->AllocateStringFromUtf8Slow(string, |
- non_ascii_start, |
- pretenure), |
+ Access<UnicodeCache::Utf8Decoder> |
+ decoder(isolate()->unicode_cache()->utf8_decoder()); |
+ decoder->Reset(string.start() + non_ascii_start, |
+ length - non_ascii_start); |
+ int utf16_length = decoder->Utf16Length(); |
+ ASSERT(utf16_length > 0); |
+ // Allocate string. |
+ Handle<SeqTwoByteString> result; |
+ ASSIGN_RETURN_ON_EXCEPTION( |
+ isolate(), result, |
+ NewRawTwoByteString(non_ascii_start + utf16_length, pretenure), |
String); |
+ // Copy ascii portion. |
+ uint16_t* data = result->GetChars(); |
+ const char* ascii_data = string.start(); |
+ for (int i = 0; i < non_ascii_start; i++) { |
+ *data++ = *ascii_data++; |
+ } |
+ // Now write the remainder. |
+ decoder->WriteUtf16(data, utf16_length); |
+ return result; |
} |
MaybeHandle<String> Factory::NewStringFromTwoByte(Vector<const uc16> string, |
PretenureFlag pretenure) { |
- CALL_HEAP_FUNCTION( |
- isolate(), |
- isolate()->heap()->AllocateStringFromTwoByte(string, pretenure), |
- String); |
+ int length = string.length(); |
+ const uc16* start = string.start(); |
+ if (String::IsOneByte(start, length)) { |
+ Handle<SeqOneByteString> result; |
+ ASSIGN_RETURN_ON_EXCEPTION( |
+ isolate(), |
+ result, |
+ NewRawOneByteString(length, pretenure), |
+ String); |
+ CopyChars(result->GetChars(), start, length); |
+ return result; |
+ } else { |
+ Handle<SeqTwoByteString> result; |
+ ASSIGN_RETURN_ON_EXCEPTION( |
+ isolate(), |
+ result, |
+ NewRawTwoByteString(length, pretenure), |
+ String); |
+ CopyChars(result->GetChars(), start, length); |
+ return result; |
+ } |
} |
@@ -328,6 +359,9 @@ MaybeHandle<Map> Factory::InternalizedStringMapForString( |
MaybeHandle<SeqOneByteString> Factory::NewRawOneByteString( |
int length, PretenureFlag pretenure) { |
+ if (length > String::kMaxLength || length < 0) { |
+ return isolate()->Throw<SeqOneByteString>(NewInvalidStringLengthError()); |
+ } |
CALL_HEAP_FUNCTION( |
isolate(), |
isolate()->heap()->AllocateRawOneByteString(length, pretenure), |
@@ -337,6 +371,9 @@ MaybeHandle<SeqOneByteString> Factory::NewRawOneByteString( |
MaybeHandle<SeqTwoByteString> Factory::NewRawTwoByteString( |
int length, PretenureFlag pretenure) { |
+ if (length > String::kMaxLength || length < 0) { |
+ return isolate()->Throw<SeqTwoByteString>(NewInvalidStringLengthError()); |
+ } |
CALL_HEAP_FUNCTION( |
isolate(), |
isolate()->heap()->AllocateRawTwoByteString(length, pretenure), |
@@ -586,8 +623,7 @@ MaybeHandle<String> Factory::NewExternalStringFromAscii( |
const ExternalAsciiString::Resource* resource) { |
size_t length = resource->length(); |
if (length > static_cast<size_t>(String::kMaxLength)) { |
- isolate()->ThrowInvalidStringLength(); |
- return MaybeHandle<String>(); |
+ return isolate()->Throw<String>(NewInvalidStringLengthError()); |
} |
Handle<Map> map = external_ascii_string_map(); |
@@ -605,8 +641,7 @@ MaybeHandle<String> Factory::NewExternalStringFromTwoByte( |
const ExternalTwoByteString::Resource* resource) { |
size_t length = resource->length(); |
if (length > static_cast<size_t>(String::kMaxLength)) { |
- isolate()->ThrowInvalidStringLength(); |
- return MaybeHandle<String>(); |
+ return isolate()->Throw<String>(NewInvalidStringLengthError()); |
} |
// For small strings we check whether the resource contains only |