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

Side by Side Diff: src/factory.cc

Issue 347503003: Move invalid string length check to the factory. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: addressed comments Created 6 years, 6 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 | « src/factory.h ('k') | src/heap.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 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
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
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
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
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
OLDNEW
« no previous file with comments | « src/factory.h ('k') | src/heap.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698