OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. |
2 | 2 |
3 // Check that we can traverse very deep stacks of ConsStrings using | 3 // Check that we can traverse very deep stacks of ConsStrings using |
4 // StringInputBuffer. Check that Get(int) works on very deep stacks | 4 // StringInputBuffer. Check that Get(int) works on very deep stacks |
5 // of ConsStrings. These operations may not be very fast, but they | 5 // of ConsStrings. These operations may not be very fast, but they |
6 // should be possible without getting errors due to too deep recursion. | 6 // should be possible without getting errors due to too deep recursion. |
7 | 7 |
8 #include <stdlib.h> | 8 #include <stdlib.h> |
9 | 9 |
10 #include "v8.h" | 10 #include "v8.h" |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
56 } | 56 } |
57 virtual const uint16_t* data() const { return data_; } | 57 virtual const uint16_t* data() const { return data_; } |
58 virtual size_t length() const { return length_; } | 58 virtual size_t length() const { return length_; } |
59 | 59 |
60 private: | 60 private: |
61 const uc16* data_; | 61 const uc16* data_; |
62 size_t length_; | 62 size_t length_; |
63 }; | 63 }; |
64 | 64 |
65 | 65 |
| 66 class AsciiResource: public v8::String::ExternalAsciiStringResource, |
| 67 public ZoneObject { |
| 68 public: |
| 69 explicit AsciiResource(Vector<const char> string): data_(string.start()) { |
| 70 length_ = string.length(); |
| 71 } |
| 72 virtual const char* data() const { return data_; } |
| 73 virtual size_t length() const { return length_; } |
| 74 |
| 75 private: |
| 76 const char* data_; |
| 77 size_t length_; |
| 78 }; |
| 79 |
| 80 |
66 static void InitializeBuildingBlocks( | 81 static void InitializeBuildingBlocks( |
67 Handle<String> building_blocks[NUMBER_OF_BUILDING_BLOCKS]) { | 82 Handle<String> building_blocks[NUMBER_OF_BUILDING_BLOCKS]) { |
68 // A list of pointers that we don't have any interest in cleaning up. | 83 // A list of pointers that we don't have any interest in cleaning up. |
69 // If they are reachable from a root then leak detection won't complain. | 84 // If they are reachable from a root then leak detection won't complain. |
70 for (int i = 0; i < NUMBER_OF_BUILDING_BLOCKS; i++) { | 85 for (int i = 0; i < NUMBER_OF_BUILDING_BLOCKS; i++) { |
71 int len = gen() % 16; | 86 int len = gen() % 16; |
72 if (len > 14) { | 87 if (len > 14) { |
73 len += 1234; | 88 len += 1234; |
74 } | 89 } |
75 switch (gen() % 4) { | 90 switch (gen() % 4) { |
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
322 // Check that the contents are correct | 337 // Check that the contents are correct |
323 for (int j = 0; j < lengths[i]; j++) | 338 for (int j = 0; j < lengths[i]; j++) |
324 CHECK_EQ(as_utf8[j], static_cast<unsigned char>(buffer[j])); | 339 CHECK_EQ(as_utf8[j], static_cast<unsigned char>(buffer[j])); |
325 // Check that the rest of the buffer hasn't been touched | 340 // Check that the rest of the buffer hasn't been touched |
326 for (int j = lengths[i]; j < 11; j++) | 341 for (int j = lengths[i]; j < 11; j++) |
327 CHECK_EQ(kNoChar, buffer[j]); | 342 CHECK_EQ(kNoChar, buffer[j]); |
328 } | 343 } |
329 } | 344 } |
330 | 345 |
331 | 346 |
332 class TwoByteResource: public v8::String::ExternalStringResource { | 347 TEST(ExternalShortStringAdd) { |
333 public: | 348 ZoneScope zone(DELETE_ON_EXIT); |
334 TwoByteResource(const uint16_t* data, size_t length, bool* destructed) | 349 |
335 : data_(data), length_(length), destructed_(destructed) { | 350 InitializeVM(); |
336 CHECK_NE(destructed, NULL); | 351 v8::HandleScope handle_scope; |
337 *destructed_ = false; | 352 |
| 353 // Make sure we cover all always-flat lengths and at least one above. |
| 354 static const int kMaxLength = 20; |
| 355 CHECK_GT(kMaxLength, i::String::kMinNonFlatLength); |
| 356 |
| 357 // Allocate two JavaScript arrays for holding short strings. |
| 358 v8::Handle<v8::Array> ascii_external_strings = |
| 359 v8::Array::New(kMaxLength + 1); |
| 360 v8::Handle<v8::Array> non_ascii_external_strings = |
| 361 v8::Array::New(kMaxLength + 1); |
| 362 |
| 363 // Generate short ascii and non-ascii external strings. |
| 364 for (int i = 0; i <= kMaxLength; i++) { |
| 365 char* ascii = Zone::NewArray<char>(i + 1); |
| 366 for (int j = 0; j < i; j++) { |
| 367 ascii[j] = 'a'; |
| 368 } |
| 369 // Terminating '\0' is left out on purpose. It is not required for external |
| 370 // string data. |
| 371 AsciiResource* ascii_resource = |
| 372 new AsciiResource(Vector<const char>(ascii, i)); |
| 373 v8::Local<v8::String> ascii_external_string = |
| 374 v8::String::NewExternal(ascii_resource); |
| 375 |
| 376 ascii_external_strings->Set(v8::Integer::New(i), ascii_external_string); |
| 377 uc16* non_ascii = Zone::NewArray<uc16>(i + 1); |
| 378 for (int j = 0; j < i; j++) { |
| 379 non_ascii[j] = 1234; |
| 380 } |
| 381 // Terminating '\0' is left out on purpose. It is not required for external |
| 382 // string data. |
| 383 Resource* resource = new Resource(Vector<const uc16>(non_ascii, i)); |
| 384 v8::Local<v8::String> non_ascii_external_string = |
| 385 v8::String::NewExternal(resource); |
| 386 non_ascii_external_strings->Set(v8::Integer::New(i), |
| 387 non_ascii_external_string); |
338 } | 388 } |
339 | 389 |
340 virtual ~TwoByteResource() { | 390 // Add the arrays with the short external strings in the global object. |
341 CHECK_NE(destructed_, NULL); | 391 v8::Handle<v8::Object> global = env->Global(); |
342 CHECK(!*destructed_); | 392 global->Set(v8_str("ascii"), ascii_external_strings); |
343 *destructed_ = true; | 393 global->Set(v8_str("non_ascii"), non_ascii_external_strings); |
344 } | |
345 | 394 |
346 const uint16_t* data() const { return data_; } | 395 // Add short external ascii and non-ascii strings checking the result. |
347 size_t length() const { return length_; } | 396 static const char* source = |
348 | 397 "function test() {" |
349 private: | 398 " for (var i = 0; i <= 20; i++) {" |
350 const uint16_t* data_; | 399 " for (var j = 0; j < i; j++) {" |
351 size_t length_; | 400 " if (non_ascii[i] != (non_ascii[j] + non_ascii[i - j])) return false;" |
352 bool* destructed_; | 401 " if (ascii[i] != (ascii[j] + ascii[i - j])) return false;" |
353 }; | 402 " }" |
| 403 " }" |
| 404 " return true;" |
| 405 "};" |
| 406 "test()"; |
| 407 CHECK(v8::Script::Compile(v8::String::New(source))->Run()->BooleanValue()); |
| 408 } |
OLD | NEW |