OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/factory.h" | 5 #include "src/factory.h" |
6 | 6 |
7 #include "src/conversions.h" | 7 #include "src/conversions.h" |
8 #include "src/isolate-inl.h" | 8 #include "src/isolate-inl.h" |
9 #include "src/macro-assembler.h" | 9 #include "src/macro-assembler.h" |
10 | 10 |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
205 | 205 |
206 template Handle<String> Factory::InternalizeStringWithKey< | 206 template Handle<String> Factory::InternalizeStringWithKey< |
207 SubStringKey<uint8_t> > (SubStringKey<uint8_t>* key); | 207 SubStringKey<uint8_t> > (SubStringKey<uint8_t>* key); |
208 template Handle<String> Factory::InternalizeStringWithKey< | 208 template Handle<String> Factory::InternalizeStringWithKey< |
209 SubStringKey<uint16_t> > (SubStringKey<uint16_t>* key); | 209 SubStringKey<uint16_t> > (SubStringKey<uint16_t>* key); |
210 | 210 |
211 | 211 |
212 MaybeHandle<String> Factory::NewStringFromOneByte(Vector<const uint8_t> string, | 212 MaybeHandle<String> Factory::NewStringFromOneByte(Vector<const uint8_t> string, |
213 PretenureFlag pretenure) { | 213 PretenureFlag pretenure) { |
214 int length = string.length(); | 214 int length = string.length(); |
215 if (length == 1) { | 215 if (length == 1) return LookupSingleCharacterStringFromCode(string[0]); |
216 return LookupSingleCharacterStringFromCode(string[0]); | |
217 } | |
218 Handle<SeqOneByteString> result; | 216 Handle<SeqOneByteString> result; |
219 ASSIGN_RETURN_ON_EXCEPTION( | 217 ASSIGN_RETURN_ON_EXCEPTION( |
220 isolate(), | 218 isolate(), |
221 result, | 219 result, |
222 NewRawOneByteString(string.length(), pretenure), | 220 NewRawOneByteString(string.length(), pretenure), |
223 String); | 221 String); |
224 | 222 |
225 DisallowHeapAllocation no_gc; | 223 DisallowHeapAllocation no_gc; |
226 // Copy the characters into the new object. | 224 // Copy the characters into the new object. |
227 CopyChars(SeqOneByteString::cast(*result)->GetChars(), | 225 CopyChars(SeqOneByteString::cast(*result)->GetChars(), |
228 string.start(), | 226 string.start(), |
229 length); | 227 length); |
230 return result; | 228 return result; |
231 } | 229 } |
232 | 230 |
233 MaybeHandle<String> Factory::NewStringFromUtf8(Vector<const char> string, | 231 MaybeHandle<String> Factory::NewStringFromUtf8(Vector<const char> string, |
234 PretenureFlag pretenure) { | 232 PretenureFlag pretenure) { |
235 // Check for ASCII first since this is the common case. | 233 // Check for ASCII first since this is the common case. |
236 const char* start = string.start(); | 234 const char* start = string.start(); |
237 int length = string.length(); | 235 int length = string.length(); |
238 int non_ascii_start = String::NonAsciiStart(start, length); | 236 int non_ascii_start = String::NonAsciiStart(start, length); |
239 if (non_ascii_start >= length) { | 237 if (non_ascii_start >= length) { |
240 // If the string is ASCII, we do not need to convert the characters | 238 // If the string is ASCII, we do not need to convert the characters |
241 // since UTF8 is backwards compatible with ASCII. | 239 // since UTF8 is backwards compatible with ASCII. |
242 return NewStringFromOneByte(Vector<const uint8_t>::cast(string), pretenure); | 240 return NewStringFromOneByte(Vector<const uint8_t>::cast(string), pretenure); |
243 } | 241 } |
| 242 |
244 // Non-ASCII and we need to decode. | 243 // Non-ASCII and we need to decode. |
245 CALL_HEAP_FUNCTION( | 244 Access<UnicodeCache::Utf8Decoder> |
246 isolate(), | 245 decoder(isolate()->unicode_cache()->utf8_decoder()); |
247 isolate()->heap()->AllocateStringFromUtf8Slow(string, | 246 decoder->Reset(string.start() + non_ascii_start, |
248 non_ascii_start, | 247 length - non_ascii_start); |
249 pretenure), | 248 int utf16_length = decoder->Utf16Length(); |
| 249 ASSERT(utf16_length > 0); |
| 250 // Allocate string. |
| 251 Handle<SeqTwoByteString> result; |
| 252 ASSIGN_RETURN_ON_EXCEPTION( |
| 253 isolate(), result, |
| 254 NewRawTwoByteString(non_ascii_start + utf16_length, pretenure), |
250 String); | 255 String); |
| 256 // Copy ascii portion. |
| 257 uint16_t* data = result->GetChars(); |
| 258 const char* ascii_data = string.start(); |
| 259 for (int i = 0; i < non_ascii_start; i++) { |
| 260 *data++ = *ascii_data++; |
| 261 } |
| 262 // Now write the remainder. |
| 263 decoder->WriteUtf16(data, utf16_length); |
| 264 return result; |
251 } | 265 } |
252 | 266 |
253 | 267 |
254 MaybeHandle<String> Factory::NewStringFromTwoByte(Vector<const uc16> string, | 268 MaybeHandle<String> Factory::NewStringFromTwoByte(Vector<const uc16> string, |
255 PretenureFlag pretenure) { | 269 PretenureFlag pretenure) { |
256 CALL_HEAP_FUNCTION( | 270 int length = string.length(); |
257 isolate(), | 271 const uc16* start = string.start(); |
258 isolate()->heap()->AllocateStringFromTwoByte(string, pretenure), | 272 if (String::IsOneByte(start, length)) { |
259 String); | 273 Handle<SeqOneByteString> result; |
| 274 ASSIGN_RETURN_ON_EXCEPTION( |
| 275 isolate(), |
| 276 result, |
| 277 NewRawOneByteString(length, pretenure), |
| 278 String); |
| 279 CopyChars(result->GetChars(), start, length); |
| 280 return result; |
| 281 } else { |
| 282 Handle<SeqTwoByteString> result; |
| 283 ASSIGN_RETURN_ON_EXCEPTION( |
| 284 isolate(), |
| 285 result, |
| 286 NewRawTwoByteString(length, pretenure), |
| 287 String); |
| 288 CopyChars(result->GetChars(), start, length); |
| 289 return result; |
| 290 } |
260 } | 291 } |
261 | 292 |
262 | 293 |
263 Handle<String> Factory::NewInternalizedStringFromUtf8(Vector<const char> str, | 294 Handle<String> Factory::NewInternalizedStringFromUtf8(Vector<const char> str, |
264 int chars, | 295 int chars, |
265 uint32_t hash_field) { | 296 uint32_t hash_field) { |
266 CALL_HEAP_FUNCTION( | 297 CALL_HEAP_FUNCTION( |
267 isolate(), | 298 isolate(), |
268 isolate()->heap()->AllocateInternalizedStringFromUtf8( | 299 isolate()->heap()->AllocateInternalizedStringFromUtf8( |
269 str, chars, hash_field), | 300 str, chars, hash_field), |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
321 return short_external_ascii_internalized_string_map(); | 352 return short_external_ascii_internalized_string_map(); |
322 case SHORT_EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE: | 353 case SHORT_EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE: |
323 return short_external_internalized_string_with_one_byte_data_map(); | 354 return short_external_internalized_string_with_one_byte_data_map(); |
324 default: return MaybeHandle<Map>(); // No match found. | 355 default: return MaybeHandle<Map>(); // No match found. |
325 } | 356 } |
326 } | 357 } |
327 | 358 |
328 | 359 |
329 MaybeHandle<SeqOneByteString> Factory::NewRawOneByteString( | 360 MaybeHandle<SeqOneByteString> Factory::NewRawOneByteString( |
330 int length, PretenureFlag pretenure) { | 361 int length, PretenureFlag pretenure) { |
| 362 if (length > String::kMaxLength || length < 0) { |
| 363 return isolate()->Throw<SeqOneByteString>(NewInvalidStringLengthError()); |
| 364 } |
331 CALL_HEAP_FUNCTION( | 365 CALL_HEAP_FUNCTION( |
332 isolate(), | 366 isolate(), |
333 isolate()->heap()->AllocateRawOneByteString(length, pretenure), | 367 isolate()->heap()->AllocateRawOneByteString(length, pretenure), |
334 SeqOneByteString); | 368 SeqOneByteString); |
335 } | 369 } |
336 | 370 |
337 | 371 |
338 MaybeHandle<SeqTwoByteString> Factory::NewRawTwoByteString( | 372 MaybeHandle<SeqTwoByteString> Factory::NewRawTwoByteString( |
339 int length, PretenureFlag pretenure) { | 373 int length, PretenureFlag pretenure) { |
| 374 if (length > String::kMaxLength || length < 0) { |
| 375 return isolate()->Throw<SeqTwoByteString>(NewInvalidStringLengthError()); |
| 376 } |
340 CALL_HEAP_FUNCTION( | 377 CALL_HEAP_FUNCTION( |
341 isolate(), | 378 isolate(), |
342 isolate()->heap()->AllocateRawTwoByteString(length, pretenure), | 379 isolate()->heap()->AllocateRawTwoByteString(length, pretenure), |
343 SeqTwoByteString); | 380 SeqTwoByteString); |
344 } | 381 } |
345 | 382 |
346 | 383 |
347 Handle<String> Factory::LookupSingleCharacterStringFromCode(uint32_t code) { | 384 Handle<String> Factory::LookupSingleCharacterStringFromCode(uint32_t code) { |
348 if (code <= String::kMaxOneByteCharCodeU) { | 385 if (code <= String::kMaxOneByteCharCodeU) { |
349 { | 386 { |
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
579 slice->set_parent(*str); | 616 slice->set_parent(*str); |
580 slice->set_offset(offset); | 617 slice->set_offset(offset); |
581 return slice; | 618 return slice; |
582 } | 619 } |
583 | 620 |
584 | 621 |
585 MaybeHandle<String> Factory::NewExternalStringFromAscii( | 622 MaybeHandle<String> Factory::NewExternalStringFromAscii( |
586 const ExternalAsciiString::Resource* resource) { | 623 const ExternalAsciiString::Resource* resource) { |
587 size_t length = resource->length(); | 624 size_t length = resource->length(); |
588 if (length > static_cast<size_t>(String::kMaxLength)) { | 625 if (length > static_cast<size_t>(String::kMaxLength)) { |
589 isolate()->ThrowInvalidStringLength(); | 626 return isolate()->Throw<String>(NewInvalidStringLengthError()); |
590 return MaybeHandle<String>(); | |
591 } | 627 } |
592 | 628 |
593 Handle<Map> map = external_ascii_string_map(); | 629 Handle<Map> map = external_ascii_string_map(); |
594 Handle<ExternalAsciiString> external_string = | 630 Handle<ExternalAsciiString> external_string = |
595 New<ExternalAsciiString>(map, NEW_SPACE); | 631 New<ExternalAsciiString>(map, NEW_SPACE); |
596 external_string->set_length(static_cast<int>(length)); | 632 external_string->set_length(static_cast<int>(length)); |
597 external_string->set_hash_field(String::kEmptyHashField); | 633 external_string->set_hash_field(String::kEmptyHashField); |
598 external_string->set_resource(resource); | 634 external_string->set_resource(resource); |
599 | 635 |
600 return external_string; | 636 return external_string; |
601 } | 637 } |
602 | 638 |
603 | 639 |
604 MaybeHandle<String> Factory::NewExternalStringFromTwoByte( | 640 MaybeHandle<String> Factory::NewExternalStringFromTwoByte( |
605 const ExternalTwoByteString::Resource* resource) { | 641 const ExternalTwoByteString::Resource* resource) { |
606 size_t length = resource->length(); | 642 size_t length = resource->length(); |
607 if (length > static_cast<size_t>(String::kMaxLength)) { | 643 if (length > static_cast<size_t>(String::kMaxLength)) { |
608 isolate()->ThrowInvalidStringLength(); | 644 return isolate()->Throw<String>(NewInvalidStringLengthError()); |
609 return MaybeHandle<String>(); | |
610 } | 645 } |
611 | 646 |
612 // For small strings we check whether the resource contains only | 647 // For small strings we check whether the resource contains only |
613 // one byte characters. If yes, we use a different string map. | 648 // one byte characters. If yes, we use a different string map. |
614 static const size_t kOneByteCheckLengthLimit = 32; | 649 static const size_t kOneByteCheckLengthLimit = 32; |
615 bool is_one_byte = length <= kOneByteCheckLengthLimit && | 650 bool is_one_byte = length <= kOneByteCheckLengthLimit && |
616 String::IsOneByte(resource->data(), static_cast<int>(length)); | 651 String::IsOneByte(resource->data(), static_cast<int>(length)); |
617 Handle<Map> map = is_one_byte ? | 652 Handle<Map> map = is_one_byte ? |
618 external_string_with_one_byte_data_map() : external_string_map(); | 653 external_string_with_one_byte_data_map() : external_string_map(); |
619 Handle<ExternalTwoByteString> external_string = | 654 Handle<ExternalTwoByteString> external_string = |
(...skipping 1717 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2337 return Handle<Object>::null(); | 2372 return Handle<Object>::null(); |
2338 } | 2373 } |
2339 | 2374 |
2340 | 2375 |
2341 Handle<Object> Factory::ToBoolean(bool value) { | 2376 Handle<Object> Factory::ToBoolean(bool value) { |
2342 return value ? true_value() : false_value(); | 2377 return value ? true_value() : false_value(); |
2343 } | 2378 } |
2344 | 2379 |
2345 | 2380 |
2346 } } // namespace v8::internal | 2381 } } // namespace v8::internal |
OLD | NEW |