| OLD | NEW |
| 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 444 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 455 static uint16_t* AsciiToTwoByteString(const char* source) { | 455 static uint16_t* AsciiToTwoByteString(const char* source) { |
| 456 int array_length = i::StrLength(source) + 1; | 456 int array_length = i::StrLength(source) + 1; |
| 457 uint16_t* converted = i::NewArray<uint16_t>(array_length); | 457 uint16_t* converted = i::NewArray<uint16_t>(array_length); |
| 458 for (int i = 0; i < array_length; i++) converted[i] = source[i]; | 458 for (int i = 0; i < array_length; i++) converted[i] = source[i]; |
| 459 return converted; | 459 return converted; |
| 460 } | 460 } |
| 461 | 461 |
| 462 | 462 |
| 463 class TestResource: public String::ExternalStringResource { | 463 class TestResource: public String::ExternalStringResource { |
| 464 public: | 464 public: |
| 465 explicit TestResource(uint16_t* data, int* counter = NULL) | 465 TestResource(uint16_t* data, int* counter = NULL, bool owning_data = true) |
| 466 : data_(data), length_(0), counter_(counter) { | 466 : data_(data), length_(0), counter_(counter), owning_data_(owning_data) { |
| 467 while (data[length_]) ++length_; | 467 while (data[length_]) ++length_; |
| 468 } | 468 } |
| 469 | 469 |
| 470 ~TestResource() { | 470 ~TestResource() { |
| 471 i::DeleteArray(data_); | 471 if (owning_data_) i::DeleteArray(data_); |
| 472 if (counter_ != NULL) ++*counter_; | 472 if (counter_ != NULL) ++*counter_; |
| 473 } | 473 } |
| 474 | 474 |
| 475 const uint16_t* data() const { | 475 const uint16_t* data() const { |
| 476 return data_; | 476 return data_; |
| 477 } | 477 } |
| 478 | 478 |
| 479 size_t length() const { | 479 size_t length() const { |
| 480 return length_; | 480 return length_; |
| 481 } | 481 } |
| 482 |
| 482 private: | 483 private: |
| 483 uint16_t* data_; | 484 uint16_t* data_; |
| 484 size_t length_; | 485 size_t length_; |
| 485 int* counter_; | 486 int* counter_; |
| 487 bool owning_data_; |
| 486 }; | 488 }; |
| 487 | 489 |
| 488 | 490 |
| 489 class TestAsciiResource: public String::ExternalAsciiStringResource { | 491 class TestAsciiResource: public String::ExternalAsciiStringResource { |
| 490 public: | 492 public: |
| 491 explicit TestAsciiResource(const char* data, int* counter = NULL) | 493 TestAsciiResource(const char* data, int* counter = NULL, size_t offset = 0) |
| 492 : data_(data), length_(strlen(data)), counter_(counter) { } | 494 : orig_data_(data), |
| 495 data_(data + offset), |
| 496 length_(strlen(data) - offset), |
| 497 counter_(counter) { } |
| 493 | 498 |
| 494 ~TestAsciiResource() { | 499 ~TestAsciiResource() { |
| 495 i::DeleteArray(data_); | 500 i::DeleteArray(orig_data_); |
| 496 if (counter_ != NULL) ++*counter_; | 501 if (counter_ != NULL) ++*counter_; |
| 497 } | 502 } |
| 498 | 503 |
| 499 const char* data() const { | 504 const char* data() const { |
| 500 return data_; | 505 return data_; |
| 501 } | 506 } |
| 502 | 507 |
| 503 size_t length() const { | 508 size_t length() const { |
| 504 return length_; | 509 return length_; |
| 505 } | 510 } |
| 511 |
| 506 private: | 512 private: |
| 513 const char* orig_data_; |
| 507 const char* data_; | 514 const char* data_; |
| 508 size_t length_; | 515 size_t length_; |
| 509 int* counter_; | 516 int* counter_; |
| 510 }; | 517 }; |
| 511 | 518 |
| 512 | 519 |
| 513 THREADED_TEST(ScriptUsingStringResource) { | 520 THREADED_TEST(ScriptUsingStringResource) { |
| 514 int dispose_count = 0; | 521 int dispose_count = 0; |
| 515 const char* c_source = "1 + 2 * 3"; | 522 const char* c_source = "1 + 2 * 3"; |
| 516 uint16_t* two_byte_source = AsciiToTwoByteString(c_source); | 523 uint16_t* two_byte_source = AsciiToTwoByteString(c_source); |
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 723 // Create a sliced string that will land in old pointer space. | 730 // Create a sliced string that will land in old pointer space. |
| 724 Local<String> slice = Local<String>::Cast(CompileRun( | 731 Local<String> slice = Local<String>::Cast(CompileRun( |
| 725 "slice('abcdefghijklmnopqrstuvwxyz');")); | 732 "slice('abcdefghijklmnopqrstuvwxyz');")); |
| 726 | 733 |
| 727 // Trigger GCs so that the newly allocated string moves to old gen. | 734 // Trigger GCs so that the newly allocated string moves to old gen. |
| 728 SimulateFullSpace(CcTest::heap()->old_pointer_space()); | 735 SimulateFullSpace(CcTest::heap()->old_pointer_space()); |
| 729 CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in survivor space now | 736 CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in survivor space now |
| 730 CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in old gen now | 737 CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in old gen now |
| 731 | 738 |
| 732 // Turn into external string with unaligned resource data. | 739 // Turn into external string with unaligned resource data. |
| 733 int dispose_count = 0; | |
| 734 const char* c_cons = "_abcdefghijklmnopqrstuvwxyz"; | 740 const char* c_cons = "_abcdefghijklmnopqrstuvwxyz"; |
| 735 bool success = cons->MakeExternal( | 741 bool success = cons->MakeExternal( |
| 736 new TestAsciiResource(i::StrDup(c_cons) + 1, &dispose_count)); | 742 new TestAsciiResource(i::StrDup(c_cons), NULL, 1)); |
| 737 CHECK(success); | 743 CHECK(success); |
| 738 const char* c_slice = "_bcdefghijklmnopqrstuvwxyz"; | 744 const char* c_slice = "_bcdefghijklmnopqrstuvwxyz"; |
| 739 success = slice->MakeExternal( | 745 success = slice->MakeExternal( |
| 740 new TestAsciiResource(i::StrDup(c_slice) + 1, &dispose_count)); | 746 new TestAsciiResource(i::StrDup(c_slice), NULL, 1)); |
| 741 CHECK(success); | 747 CHECK(success); |
| 742 | 748 |
| 743 // Trigger GCs and force evacuation. | 749 // Trigger GCs and force evacuation. |
| 744 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); | 750 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 745 CcTest::heap()->CollectAllGarbage(i::Heap::kReduceMemoryFootprintMask); | 751 CcTest::heap()->CollectAllGarbage(i::Heap::kReduceMemoryFootprintMask); |
| 746 } | 752 } |
| 747 | 753 |
| 748 | 754 |
| 749 THREADED_TEST(UsingExternalString) { | 755 THREADED_TEST(UsingExternalString) { |
| 750 i::Factory* factory = CcTest::i_isolate()->factory(); | 756 i::Factory* factory = CcTest::i_isolate()->factory(); |
| 751 { | 757 { |
| 752 v8::HandleScope scope(CcTest::isolate()); | 758 v8::HandleScope scope(CcTest::isolate()); |
| 753 uint16_t* two_byte_string = AsciiToTwoByteString("test string"); | 759 uint16_t* two_byte_string = AsciiToTwoByteString("test string"); |
| 754 Local<String> string = String::NewExternal( | 760 Local<String> string = String::NewExternal( |
| 755 CcTest::isolate(), new TestResource(two_byte_string)); | 761 CcTest::isolate(), new TestResource(two_byte_string)); |
| 756 i::Handle<i::String> istring = v8::Utils::OpenHandle(*string); | 762 i::Handle<i::String> istring = v8::Utils::OpenHandle(*string); |
| 757 // Trigger GCs so that the newly allocated string moves to old gen. | 763 // Trigger GCs so that the newly allocated string moves to old gen. |
| 758 CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in survivor space now | 764 CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in survivor space now |
| 759 CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in old gen now | 765 CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in old gen now |
| 760 i::Handle<i::String> isymbol = | 766 i::Handle<i::String> isymbol = |
| 761 factory->InternalizedStringFromString(istring); | 767 factory->InternalizeString(istring); |
| 762 CHECK(isymbol->IsInternalizedString()); | 768 CHECK(isymbol->IsInternalizedString()); |
| 763 } | 769 } |
| 764 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); | 770 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 765 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); | 771 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 766 } | 772 } |
| 767 | 773 |
| 768 | 774 |
| 769 THREADED_TEST(UsingExternalAsciiString) { | 775 THREADED_TEST(UsingExternalAsciiString) { |
| 770 i::Factory* factory = CcTest::i_isolate()->factory(); | 776 i::Factory* factory = CcTest::i_isolate()->factory(); |
| 771 { | 777 { |
| 772 v8::HandleScope scope(CcTest::isolate()); | 778 v8::HandleScope scope(CcTest::isolate()); |
| 773 const char* one_byte_string = "test string"; | 779 const char* one_byte_string = "test string"; |
| 774 Local<String> string = String::NewExternal( | 780 Local<String> string = String::NewExternal( |
| 775 CcTest::isolate(), new TestAsciiResource(i::StrDup(one_byte_string))); | 781 CcTest::isolate(), new TestAsciiResource(i::StrDup(one_byte_string))); |
| 776 i::Handle<i::String> istring = v8::Utils::OpenHandle(*string); | 782 i::Handle<i::String> istring = v8::Utils::OpenHandle(*string); |
| 777 // Trigger GCs so that the newly allocated string moves to old gen. | 783 // Trigger GCs so that the newly allocated string moves to old gen. |
| 778 CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in survivor space now | 784 CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in survivor space now |
| 779 CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in old gen now | 785 CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in old gen now |
| 780 i::Handle<i::String> isymbol = | 786 i::Handle<i::String> isymbol = |
| 781 factory->InternalizedStringFromString(istring); | 787 factory->InternalizeString(istring); |
| 782 CHECK(isymbol->IsInternalizedString()); | 788 CHECK(isymbol->IsInternalizedString()); |
| 783 } | 789 } |
| 784 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); | 790 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 785 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); | 791 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 786 } | 792 } |
| 787 | 793 |
| 788 | 794 |
| 789 THREADED_TEST(ScavengeExternalString) { | 795 THREADED_TEST(ScavengeExternalString) { |
| 790 i::FLAG_stress_compaction = false; | 796 i::FLAG_stress_compaction = false; |
| 791 i::FLAG_gc_global = false; | 797 i::FLAG_gc_global = false; |
| (...skipping 1200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1992 LocalContext env; | 1998 LocalContext env; |
| 1993 env->Global()->Set(v8_str("Child"), child->GetFunction()); | 1999 env->Global()->Set(v8_str("Child"), child->GetFunction()); |
| 1994 CompileRun("var child = new Child;" | 2000 CompileRun("var child = new Child;" |
| 1995 "child.age = 10;"); | 2001 "child.age = 10;"); |
| 1996 ExpectBoolean("child.hasOwnProperty('age')", false); | 2002 ExpectBoolean("child.hasOwnProperty('age')", false); |
| 1997 ExpectInt32("child.age", 10); | 2003 ExpectInt32("child.age", 10); |
| 1998 ExpectInt32("child.accessor_age", 10); | 2004 ExpectInt32("child.accessor_age", 10); |
| 1999 } | 2005 } |
| 2000 | 2006 |
| 2001 | 2007 |
| 2008 THREADED_TEST(EmptyInterceptorBreakTransitions) { |
| 2009 v8::HandleScope scope(CcTest::isolate()); |
| 2010 Handle<FunctionTemplate> templ = FunctionTemplate::New(CcTest::isolate()); |
| 2011 AddInterceptor(templ, EmptyInterceptorGetter, EmptyInterceptorSetter); |
| 2012 LocalContext env; |
| 2013 env->Global()->Set(v8_str("Constructor"), templ->GetFunction()); |
| 2014 CompileRun("var o1 = new Constructor;" |
| 2015 "o1.a = 1;" // Ensure a and x share the descriptor array. |
| 2016 "Object.defineProperty(o1, 'x', {value: 10});"); |
| 2017 CompileRun("var o2 = new Constructor;" |
| 2018 "o2.a = 1;" |
| 2019 "Object.defineProperty(o2, 'x', {value: 10});"); |
| 2020 } |
| 2021 |
| 2022 |
| 2002 THREADED_TEST(EmptyInterceptorDoesNotShadowJSAccessors) { | 2023 THREADED_TEST(EmptyInterceptorDoesNotShadowJSAccessors) { |
| 2003 v8::Isolate* isolate = CcTest::isolate(); | 2024 v8::Isolate* isolate = CcTest::isolate(); |
| 2004 v8::HandleScope scope(isolate); | 2025 v8::HandleScope scope(isolate); |
| 2005 Handle<FunctionTemplate> parent = FunctionTemplate::New(isolate); | 2026 Handle<FunctionTemplate> parent = FunctionTemplate::New(isolate); |
| 2006 Handle<FunctionTemplate> child = FunctionTemplate::New(isolate); | 2027 Handle<FunctionTemplate> child = FunctionTemplate::New(isolate); |
| 2007 child->Inherit(parent); | 2028 child->Inherit(parent); |
| 2008 AddInterceptor(child, EmptyInterceptorGetter, EmptyInterceptorSetter); | 2029 AddInterceptor(child, EmptyInterceptorGetter, EmptyInterceptorSetter); |
| 2009 LocalContext env; | 2030 LocalContext env; |
| 2010 env->Global()->Set(v8_str("Child"), child->GetFunction()); | 2031 env->Global()->Set(v8_str("Child"), child->GetFunction()); |
| 2011 CompileRun("var child = new Child;" | 2032 CompileRun("var child = new Child;" |
| (...skipping 746 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2758 v8::Local<v8::Value> sym_val = sym2; | 2779 v8::Local<v8::Value> sym_val = sym2; |
| 2759 CHECK(sym_val->IsSymbol()); | 2780 CHECK(sym_val->IsSymbol()); |
| 2760 CHECK(sym_val->Equals(sym2)); | 2781 CHECK(sym_val->Equals(sym2)); |
| 2761 CHECK(sym_val->StrictEquals(sym2)); | 2782 CHECK(sym_val->StrictEquals(sym2)); |
| 2762 CHECK(v8::Symbol::Cast(*sym_val)->Equals(sym2)); | 2783 CHECK(v8::Symbol::Cast(*sym_val)->Equals(sym2)); |
| 2763 | 2784 |
| 2764 v8::Local<v8::Value> sym_obj = v8::SymbolObject::New(isolate, sym2); | 2785 v8::Local<v8::Value> sym_obj = v8::SymbolObject::New(isolate, sym2); |
| 2765 CHECK(sym_obj->IsSymbolObject()); | 2786 CHECK(sym_obj->IsSymbolObject()); |
| 2766 CHECK(!sym2->IsSymbolObject()); | 2787 CHECK(!sym2->IsSymbolObject()); |
| 2767 CHECK(!obj->IsSymbolObject()); | 2788 CHECK(!obj->IsSymbolObject()); |
| 2768 CHECK(sym_obj->Equals(sym2)); | 2789 CHECK(!sym_obj->Equals(sym2)); |
| 2769 CHECK(!sym_obj->StrictEquals(sym2)); | 2790 CHECK(!sym_obj->StrictEquals(sym2)); |
| 2770 CHECK(v8::SymbolObject::Cast(*sym_obj)->Equals(sym_obj)); | 2791 CHECK(v8::SymbolObject::Cast(*sym_obj)->Equals(sym_obj)); |
| 2771 CHECK(v8::SymbolObject::Cast(*sym_obj)->ValueOf()->Equals(sym2)); | 2792 CHECK(v8::SymbolObject::Cast(*sym_obj)->ValueOf()->Equals(sym2)); |
| 2772 | 2793 |
| 2773 // Make sure delete of a non-existent symbol property works. | 2794 // Make sure delete of a non-existent symbol property works. |
| 2774 CHECK(obj->Delete(sym1)); | 2795 CHECK(obj->Delete(sym1)); |
| 2775 CHECK(!obj->Has(sym1)); | 2796 CHECK(!obj->Has(sym1)); |
| 2776 | 2797 |
| 2777 CHECK(obj->Set(sym1, v8::Integer::New(isolate, 1503))); | 2798 CHECK(obj->Set(sym1, v8::Integer::New(isolate, 1503))); |
| 2778 CHECK(obj->Has(sym1)); | 2799 CHECK(obj->Has(sym1)); |
| (...skipping 3812 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6591 Script::Compile(v8_str("JSNI_Log('LOG')"))->Run(); | 6612 Script::Compile(v8_str("JSNI_Log('LOG')"))->Run(); |
| 6592 } | 6613 } |
| 6593 | 6614 |
| 6594 | 6615 |
| 6595 static const char* kSimpleExtensionSource = | 6616 static const char* kSimpleExtensionSource = |
| 6596 "function Foo() {" | 6617 "function Foo() {" |
| 6597 " return 4;" | 6618 " return 4;" |
| 6598 "}"; | 6619 "}"; |
| 6599 | 6620 |
| 6600 | 6621 |
| 6601 THREADED_TEST(SimpleExtensions) { | 6622 TEST(SimpleExtensions) { |
| 6602 v8::HandleScope handle_scope(CcTest::isolate()); | 6623 v8::HandleScope handle_scope(CcTest::isolate()); |
| 6603 v8::RegisterExtension(new Extension("simpletest", kSimpleExtensionSource)); | 6624 v8::RegisterExtension(new Extension("simpletest", kSimpleExtensionSource)); |
| 6604 const char* extension_names[] = { "simpletest" }; | 6625 const char* extension_names[] = { "simpletest" }; |
| 6605 v8::ExtensionConfiguration extensions(1, extension_names); | 6626 v8::ExtensionConfiguration extensions(1, extension_names); |
| 6606 v8::Handle<Context> context = | 6627 v8::Handle<Context> context = |
| 6607 Context::New(CcTest::isolate(), &extensions); | 6628 Context::New(CcTest::isolate(), &extensions); |
| 6608 Context::Scope lock(context); | 6629 Context::Scope lock(context); |
| 6609 v8::Handle<Value> result = Script::Compile(v8_str("Foo()"))->Run(); | 6630 v8::Handle<Value> result = Script::Compile(v8_str("Foo()"))->Run(); |
| 6610 CHECK_EQ(result, v8::Integer::New(CcTest::isolate(), 4)); | 6631 CHECK_EQ(result, v8::Integer::New(CcTest::isolate(), 4)); |
| 6611 } | 6632 } |
| 6612 | 6633 |
| 6613 | 6634 |
| 6614 THREADED_TEST(NullExtensions) { | 6635 TEST(NullExtensions) { |
| 6615 v8::HandleScope handle_scope(CcTest::isolate()); | 6636 v8::HandleScope handle_scope(CcTest::isolate()); |
| 6616 v8::RegisterExtension(new Extension("nulltest", NULL)); | 6637 v8::RegisterExtension(new Extension("nulltest", NULL)); |
| 6617 const char* extension_names[] = { "nulltest" }; | 6638 const char* extension_names[] = { "nulltest" }; |
| 6618 v8::ExtensionConfiguration extensions(1, extension_names); | 6639 v8::ExtensionConfiguration extensions(1, extension_names); |
| 6619 v8::Handle<Context> context = | 6640 v8::Handle<Context> context = |
| 6620 Context::New(CcTest::isolate(), &extensions); | 6641 Context::New(CcTest::isolate(), &extensions); |
| 6621 Context::Scope lock(context); | 6642 Context::Scope lock(context); |
| 6622 v8::Handle<Value> result = Script::Compile(v8_str("1+3"))->Run(); | 6643 v8::Handle<Value> result = Script::Compile(v8_str("1+3"))->Run(); |
| 6623 CHECK_EQ(result, v8::Integer::New(CcTest::isolate(), 4)); | 6644 CHECK_EQ(result, v8::Integer::New(CcTest::isolate(), 4)); |
| 6624 } | 6645 } |
| 6625 | 6646 |
| 6626 | 6647 |
| 6627 static const char* kEmbeddedExtensionSource = | 6648 static const char* kEmbeddedExtensionSource = |
| 6628 "function Ret54321(){return 54321;}~~@@$" | 6649 "function Ret54321(){return 54321;}~~@@$" |
| 6629 "$%% THIS IS A SERIES OF NON-NULL-TERMINATED STRINGS."; | 6650 "$%% THIS IS A SERIES OF NON-NULL-TERMINATED STRINGS."; |
| 6630 static const int kEmbeddedExtensionSourceValidLen = 34; | 6651 static const int kEmbeddedExtensionSourceValidLen = 34; |
| 6631 | 6652 |
| 6632 | 6653 |
| 6633 THREADED_TEST(ExtensionMissingSourceLength) { | 6654 TEST(ExtensionMissingSourceLength) { |
| 6634 v8::HandleScope handle_scope(CcTest::isolate()); | 6655 v8::HandleScope handle_scope(CcTest::isolate()); |
| 6635 v8::RegisterExtension(new Extension("srclentest_fail", | 6656 v8::RegisterExtension(new Extension("srclentest_fail", |
| 6636 kEmbeddedExtensionSource)); | 6657 kEmbeddedExtensionSource)); |
| 6637 const char* extension_names[] = { "srclentest_fail" }; | 6658 const char* extension_names[] = { "srclentest_fail" }; |
| 6638 v8::ExtensionConfiguration extensions(1, extension_names); | 6659 v8::ExtensionConfiguration extensions(1, extension_names); |
| 6639 v8::Handle<Context> context = | 6660 v8::Handle<Context> context = |
| 6640 Context::New(CcTest::isolate(), &extensions); | 6661 Context::New(CcTest::isolate(), &extensions); |
| 6641 CHECK_EQ(0, *context); | 6662 CHECK_EQ(0, *context); |
| 6642 } | 6663 } |
| 6643 | 6664 |
| 6644 | 6665 |
| 6645 THREADED_TEST(ExtensionWithSourceLength) { | 6666 TEST(ExtensionWithSourceLength) { |
| 6646 for (int source_len = kEmbeddedExtensionSourceValidLen - 1; | 6667 for (int source_len = kEmbeddedExtensionSourceValidLen - 1; |
| 6647 source_len <= kEmbeddedExtensionSourceValidLen + 1; ++source_len) { | 6668 source_len <= kEmbeddedExtensionSourceValidLen + 1; ++source_len) { |
| 6648 v8::HandleScope handle_scope(CcTest::isolate()); | 6669 v8::HandleScope handle_scope(CcTest::isolate()); |
| 6649 i::ScopedVector<char> extension_name(32); | 6670 i::ScopedVector<char> extension_name(32); |
| 6650 i::OS::SNPrintF(extension_name, "ext #%d", source_len); | 6671 i::OS::SNPrintF(extension_name, "ext #%d", source_len); |
| 6651 v8::RegisterExtension(new Extension(extension_name.start(), | 6672 v8::RegisterExtension(new Extension(extension_name.start(), |
| 6652 kEmbeddedExtensionSource, 0, 0, | 6673 kEmbeddedExtensionSource, 0, 0, |
| 6653 source_len)); | 6674 source_len)); |
| 6654 const char* extension_names[1] = { extension_name.start() }; | 6675 const char* extension_names[1] = { extension_name.start() }; |
| 6655 v8::ExtensionConfiguration extensions(1, extension_names); | 6676 v8::ExtensionConfiguration extensions(1, extension_names); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 6677 static const char* kEvalExtensionSource2 = | 6698 static const char* kEvalExtensionSource2 = |
| 6678 "(function() {" | 6699 "(function() {" |
| 6679 " var x = 42;" | 6700 " var x = 42;" |
| 6680 " function e() {" | 6701 " function e() {" |
| 6681 " return eval('x');" | 6702 " return eval('x');" |
| 6682 " }" | 6703 " }" |
| 6683 " this.UseEval2 = e;" | 6704 " this.UseEval2 = e;" |
| 6684 "})()"; | 6705 "})()"; |
| 6685 | 6706 |
| 6686 | 6707 |
| 6687 THREADED_TEST(UseEvalFromExtension) { | 6708 TEST(UseEvalFromExtension) { |
| 6688 v8::HandleScope handle_scope(CcTest::isolate()); | 6709 v8::HandleScope handle_scope(CcTest::isolate()); |
| 6689 v8::RegisterExtension(new Extension("evaltest1", kEvalExtensionSource1)); | 6710 v8::RegisterExtension(new Extension("evaltest1", kEvalExtensionSource1)); |
| 6690 v8::RegisterExtension(new Extension("evaltest2", kEvalExtensionSource2)); | 6711 v8::RegisterExtension(new Extension("evaltest2", kEvalExtensionSource2)); |
| 6691 const char* extension_names[] = { "evaltest1", "evaltest2" }; | 6712 const char* extension_names[] = { "evaltest1", "evaltest2" }; |
| 6692 v8::ExtensionConfiguration extensions(2, extension_names); | 6713 v8::ExtensionConfiguration extensions(2, extension_names); |
| 6693 v8::Handle<Context> context = | 6714 v8::Handle<Context> context = |
| 6694 Context::New(CcTest::isolate(), &extensions); | 6715 Context::New(CcTest::isolate(), &extensions); |
| 6695 Context::Scope lock(context); | 6716 Context::Scope lock(context); |
| 6696 v8::Handle<Value> result = Script::Compile(v8_str("UseEval1()"))->Run(); | 6717 v8::Handle<Value> result = Script::Compile(v8_str("UseEval1()"))->Run(); |
| 6697 CHECK_EQ(result, v8::Integer::New(CcTest::isolate(), 42)); | 6718 CHECK_EQ(result, v8::Integer::New(CcTest::isolate(), 42)); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 6711 static const char* kWithExtensionSource2 = | 6732 static const char* kWithExtensionSource2 = |
| 6712 "(function() {" | 6733 "(function() {" |
| 6713 " var x = 42;" | 6734 " var x = 42;" |
| 6714 " function e() {" | 6735 " function e() {" |
| 6715 " with ({x:87}) { return x; }" | 6736 " with ({x:87}) { return x; }" |
| 6716 " }" | 6737 " }" |
| 6717 " this.UseWith2 = e;" | 6738 " this.UseWith2 = e;" |
| 6718 "})()"; | 6739 "})()"; |
| 6719 | 6740 |
| 6720 | 6741 |
| 6721 THREADED_TEST(UseWithFromExtension) { | 6742 TEST(UseWithFromExtension) { |
| 6722 v8::HandleScope handle_scope(CcTest::isolate()); | 6743 v8::HandleScope handle_scope(CcTest::isolate()); |
| 6723 v8::RegisterExtension(new Extension("withtest1", kWithExtensionSource1)); | 6744 v8::RegisterExtension(new Extension("withtest1", kWithExtensionSource1)); |
| 6724 v8::RegisterExtension(new Extension("withtest2", kWithExtensionSource2)); | 6745 v8::RegisterExtension(new Extension("withtest2", kWithExtensionSource2)); |
| 6725 const char* extension_names[] = { "withtest1", "withtest2" }; | 6746 const char* extension_names[] = { "withtest1", "withtest2" }; |
| 6726 v8::ExtensionConfiguration extensions(2, extension_names); | 6747 v8::ExtensionConfiguration extensions(2, extension_names); |
| 6727 v8::Handle<Context> context = | 6748 v8::Handle<Context> context = |
| 6728 Context::New(CcTest::isolate(), &extensions); | 6749 Context::New(CcTest::isolate(), &extensions); |
| 6729 Context::Scope lock(context); | 6750 Context::Scope lock(context); |
| 6730 v8::Handle<Value> result = Script::Compile(v8_str("UseWith1()"))->Run(); | 6751 v8::Handle<Value> result = Script::Compile(v8_str("UseWith1()"))->Run(); |
| 6731 CHECK_EQ(result, v8::Integer::New(CcTest::isolate(), 87)); | 6752 CHECK_EQ(result, v8::Integer::New(CcTest::isolate(), 87)); |
| 6732 result = Script::Compile(v8_str("UseWith2()"))->Run(); | 6753 result = Script::Compile(v8_str("UseWith2()"))->Run(); |
| 6733 CHECK_EQ(result, v8::Integer::New(CcTest::isolate(), 87)); | 6754 CHECK_EQ(result, v8::Integer::New(CcTest::isolate(), 87)); |
| 6734 } | 6755 } |
| 6735 | 6756 |
| 6736 | 6757 |
| 6737 THREADED_TEST(AutoExtensions) { | 6758 TEST(AutoExtensions) { |
| 6738 v8::HandleScope handle_scope(CcTest::isolate()); | 6759 v8::HandleScope handle_scope(CcTest::isolate()); |
| 6739 Extension* extension = new Extension("autotest", kSimpleExtensionSource); | 6760 Extension* extension = new Extension("autotest", kSimpleExtensionSource); |
| 6740 extension->set_auto_enable(true); | 6761 extension->set_auto_enable(true); |
| 6741 v8::RegisterExtension(extension); | 6762 v8::RegisterExtension(extension); |
| 6742 v8::Handle<Context> context = | 6763 v8::Handle<Context> context = |
| 6743 Context::New(CcTest::isolate()); | 6764 Context::New(CcTest::isolate()); |
| 6744 Context::Scope lock(context); | 6765 Context::Scope lock(context); |
| 6745 v8::Handle<Value> result = Script::Compile(v8_str("Foo()"))->Run(); | 6766 v8::Handle<Value> result = Script::Compile(v8_str("Foo()"))->Run(); |
| 6746 CHECK_EQ(result, v8::Integer::New(CcTest::isolate(), 4)); | 6767 CHECK_EQ(result, v8::Integer::New(CcTest::isolate(), 4)); |
| 6747 } | 6768 } |
| 6748 | 6769 |
| 6749 | 6770 |
| 6750 static const char* kSyntaxErrorInExtensionSource = | 6771 static const char* kSyntaxErrorInExtensionSource = |
| 6751 "["; | 6772 "["; |
| 6752 | 6773 |
| 6753 | 6774 |
| 6754 // Test that a syntax error in an extension does not cause a fatal | 6775 // Test that a syntax error in an extension does not cause a fatal |
| 6755 // error but results in an empty context. | 6776 // error but results in an empty context. |
| 6756 THREADED_TEST(SyntaxErrorExtensions) { | 6777 TEST(SyntaxErrorExtensions) { |
| 6757 v8::HandleScope handle_scope(CcTest::isolate()); | 6778 v8::HandleScope handle_scope(CcTest::isolate()); |
| 6758 v8::RegisterExtension(new Extension("syntaxerror", | 6779 v8::RegisterExtension(new Extension("syntaxerror", |
| 6759 kSyntaxErrorInExtensionSource)); | 6780 kSyntaxErrorInExtensionSource)); |
| 6760 const char* extension_names[] = { "syntaxerror" }; | 6781 const char* extension_names[] = { "syntaxerror" }; |
| 6761 v8::ExtensionConfiguration extensions(1, extension_names); | 6782 v8::ExtensionConfiguration extensions(1, extension_names); |
| 6762 v8::Handle<Context> context = | 6783 v8::Handle<Context> context = |
| 6763 Context::New(CcTest::isolate(), &extensions); | 6784 Context::New(CcTest::isolate(), &extensions); |
| 6764 CHECK(context.IsEmpty()); | 6785 CHECK(context.IsEmpty()); |
| 6765 } | 6786 } |
| 6766 | 6787 |
| 6767 | 6788 |
| 6768 static const char* kExceptionInExtensionSource = | 6789 static const char* kExceptionInExtensionSource = |
| 6769 "throw 42"; | 6790 "throw 42"; |
| 6770 | 6791 |
| 6771 | 6792 |
| 6772 // Test that an exception when installing an extension does not cause | 6793 // Test that an exception when installing an extension does not cause |
| 6773 // a fatal error but results in an empty context. | 6794 // a fatal error but results in an empty context. |
| 6774 THREADED_TEST(ExceptionExtensions) { | 6795 TEST(ExceptionExtensions) { |
| 6775 v8::HandleScope handle_scope(CcTest::isolate()); | 6796 v8::HandleScope handle_scope(CcTest::isolate()); |
| 6776 v8::RegisterExtension(new Extension("exception", | 6797 v8::RegisterExtension(new Extension("exception", |
| 6777 kExceptionInExtensionSource)); | 6798 kExceptionInExtensionSource)); |
| 6778 const char* extension_names[] = { "exception" }; | 6799 const char* extension_names[] = { "exception" }; |
| 6779 v8::ExtensionConfiguration extensions(1, extension_names); | 6800 v8::ExtensionConfiguration extensions(1, extension_names); |
| 6780 v8::Handle<Context> context = | 6801 v8::Handle<Context> context = |
| 6781 Context::New(CcTest::isolate(), &extensions); | 6802 Context::New(CcTest::isolate(), &extensions); |
| 6782 CHECK(context.IsEmpty()); | 6803 CHECK(context.IsEmpty()); |
| 6783 } | 6804 } |
| 6784 | 6805 |
| 6785 | 6806 |
| 6786 static const char* kNativeCallInExtensionSource = | 6807 static const char* kNativeCallInExtensionSource = |
| 6787 "function call_runtime_last_index_of(x) {" | 6808 "function call_runtime_last_index_of(x) {" |
| 6788 " return %StringLastIndexOf(x, 'bob', 10);" | 6809 " return %StringLastIndexOf(x, 'bob', 10);" |
| 6789 "}"; | 6810 "}"; |
| 6790 | 6811 |
| 6791 | 6812 |
| 6792 static const char* kNativeCallTest = | 6813 static const char* kNativeCallTest = |
| 6793 "call_runtime_last_index_of('bobbobboellebobboellebobbob');"; | 6814 "call_runtime_last_index_of('bobbobboellebobboellebobbob');"; |
| 6794 | 6815 |
| 6795 // Test that a native runtime calls are supported in extensions. | 6816 // Test that a native runtime calls are supported in extensions. |
| 6796 THREADED_TEST(NativeCallInExtensions) { | 6817 TEST(NativeCallInExtensions) { |
| 6797 v8::HandleScope handle_scope(CcTest::isolate()); | 6818 v8::HandleScope handle_scope(CcTest::isolate()); |
| 6798 v8::RegisterExtension(new Extension("nativecall", | 6819 v8::RegisterExtension(new Extension("nativecall", |
| 6799 kNativeCallInExtensionSource)); | 6820 kNativeCallInExtensionSource)); |
| 6800 const char* extension_names[] = { "nativecall" }; | 6821 const char* extension_names[] = { "nativecall" }; |
| 6801 v8::ExtensionConfiguration extensions(1, extension_names); | 6822 v8::ExtensionConfiguration extensions(1, extension_names); |
| 6802 v8::Handle<Context> context = | 6823 v8::Handle<Context> context = |
| 6803 Context::New(CcTest::isolate(), &extensions); | 6824 Context::New(CcTest::isolate(), &extensions); |
| 6804 Context::Scope lock(context); | 6825 Context::Scope lock(context); |
| 6805 v8::Handle<Value> result = Script::Compile(v8_str(kNativeCallTest))->Run(); | 6826 v8::Handle<Value> result = Script::Compile(v8_str(kNativeCallTest))->Run(); |
| 6806 CHECK_EQ(result, v8::Integer::New(CcTest::isolate(), 3)); | 6827 CHECK_EQ(result, v8::Integer::New(CcTest::isolate(), 3)); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 6822 } | 6843 } |
| 6823 | 6844 |
| 6824 static void Echo(const v8::FunctionCallbackInfo<v8::Value>& args) { | 6845 static void Echo(const v8::FunctionCallbackInfo<v8::Value>& args) { |
| 6825 if (args.Length() >= 1) args.GetReturnValue().Set(args[0]); | 6846 if (args.Length() >= 1) args.GetReturnValue().Set(args[0]); |
| 6826 } | 6847 } |
| 6827 private: | 6848 private: |
| 6828 v8::FunctionCallback function_; | 6849 v8::FunctionCallback function_; |
| 6829 }; | 6850 }; |
| 6830 | 6851 |
| 6831 | 6852 |
| 6832 THREADED_TEST(NativeFunctionDeclaration) { | 6853 TEST(NativeFunctionDeclaration) { |
| 6833 v8::HandleScope handle_scope(CcTest::isolate()); | 6854 v8::HandleScope handle_scope(CcTest::isolate()); |
| 6834 const char* name = "nativedecl"; | 6855 const char* name = "nativedecl"; |
| 6835 v8::RegisterExtension(new NativeFunctionExtension(name, | 6856 v8::RegisterExtension(new NativeFunctionExtension(name, |
| 6836 "native function foo();")); | 6857 "native function foo();")); |
| 6837 const char* extension_names[] = { name }; | 6858 const char* extension_names[] = { name }; |
| 6838 v8::ExtensionConfiguration extensions(1, extension_names); | 6859 v8::ExtensionConfiguration extensions(1, extension_names); |
| 6839 v8::Handle<Context> context = | 6860 v8::Handle<Context> context = |
| 6840 Context::New(CcTest::isolate(), &extensions); | 6861 Context::New(CcTest::isolate(), &extensions); |
| 6841 Context::Scope lock(context); | 6862 Context::Scope lock(context); |
| 6842 v8::Handle<Value> result = Script::Compile(v8_str("foo(42);"))->Run(); | 6863 v8::Handle<Value> result = Script::Compile(v8_str("foo(42);"))->Run(); |
| 6843 CHECK_EQ(result, v8::Integer::New(CcTest::isolate(), 42)); | 6864 CHECK_EQ(result, v8::Integer::New(CcTest::isolate(), 42)); |
| 6844 } | 6865 } |
| 6845 | 6866 |
| 6846 | 6867 |
| 6847 THREADED_TEST(NativeFunctionDeclarationError) { | 6868 TEST(NativeFunctionDeclarationError) { |
| 6848 v8::HandleScope handle_scope(CcTest::isolate()); | 6869 v8::HandleScope handle_scope(CcTest::isolate()); |
| 6849 const char* name = "nativedeclerr"; | 6870 const char* name = "nativedeclerr"; |
| 6850 // Syntax error in extension code. | 6871 // Syntax error in extension code. |
| 6851 v8::RegisterExtension(new NativeFunctionExtension(name, | 6872 v8::RegisterExtension(new NativeFunctionExtension(name, |
| 6852 "native\nfunction foo();")); | 6873 "native\nfunction foo();")); |
| 6853 const char* extension_names[] = { name }; | 6874 const char* extension_names[] = { name }; |
| 6854 v8::ExtensionConfiguration extensions(1, extension_names); | 6875 v8::ExtensionConfiguration extensions(1, extension_names); |
| 6855 v8::Handle<Context> context = | 6876 v8::Handle<Context> context = |
| 6856 Context::New(CcTest::isolate(), &extensions); | 6877 Context::New(CcTest::isolate(), &extensions); |
| 6857 CHECK(context.IsEmpty()); | 6878 CHECK(context.IsEmpty()); |
| 6858 } | 6879 } |
| 6859 | 6880 |
| 6860 | 6881 |
| 6861 THREADED_TEST(NativeFunctionDeclarationErrorEscape) { | 6882 TEST(NativeFunctionDeclarationErrorEscape) { |
| 6862 v8::HandleScope handle_scope(CcTest::isolate()); | 6883 v8::HandleScope handle_scope(CcTest::isolate()); |
| 6863 const char* name = "nativedeclerresc"; | 6884 const char* name = "nativedeclerresc"; |
| 6864 // Syntax error in extension code - escape code in "native" means that | 6885 // Syntax error in extension code - escape code in "native" means that |
| 6865 // it's not treated as a keyword. | 6886 // it's not treated as a keyword. |
| 6866 v8::RegisterExtension(new NativeFunctionExtension( | 6887 v8::RegisterExtension(new NativeFunctionExtension( |
| 6867 name, | 6888 name, |
| 6868 "nativ\\u0065 function foo();")); | 6889 "nativ\\u0065 function foo();")); |
| 6869 const char* extension_names[] = { name }; | 6890 const char* extension_names[] = { name }; |
| 6870 v8::ExtensionConfiguration extensions(1, extension_names); | 6891 v8::ExtensionConfiguration extensions(1, extension_names); |
| 6871 v8::Handle<Context> context = | 6892 v8::Handle<Context> context = |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7018 v8::RegisterExtension(new Extension("B", "", 1, bDeps)); | 7039 v8::RegisterExtension(new Extension("B", "", 1, bDeps)); |
| 7019 last_location = NULL; | 7040 last_location = NULL; |
| 7020 v8::ExtensionConfiguration config(1, bDeps); | 7041 v8::ExtensionConfiguration config(1, bDeps); |
| 7021 v8::Handle<Context> context = | 7042 v8::Handle<Context> context = |
| 7022 Context::New(CcTest::isolate(), &config); | 7043 Context::New(CcTest::isolate(), &config); |
| 7023 CHECK(context.IsEmpty()); | 7044 CHECK(context.IsEmpty()); |
| 7024 CHECK_NE(last_location, NULL); | 7045 CHECK_NE(last_location, NULL); |
| 7025 } | 7046 } |
| 7026 | 7047 |
| 7027 | 7048 |
| 7028 static const char* js_code_causing_huge_string_flattening = | |
| 7029 "var str = 'X';" | |
| 7030 "for (var i = 0; i < 30; i++) {" | |
| 7031 " str = str + str;" | |
| 7032 "}" | |
| 7033 "str.match(/X/);"; | |
| 7034 | |
| 7035 | |
| 7036 TEST(RegexpOutOfMemory) { | |
| 7037 // Execute a script that causes out of memory when flattening a string. | |
| 7038 v8::HandleScope scope(CcTest::isolate()); | |
| 7039 v8::V8::SetFatalErrorHandler(OOMCallback); | |
| 7040 LocalContext context; | |
| 7041 Local<Script> script = Script::Compile(String::NewFromUtf8( | |
| 7042 CcTest::isolate(), js_code_causing_huge_string_flattening)); | |
| 7043 last_location = NULL; | |
| 7044 script->Run(); | |
| 7045 | |
| 7046 CHECK(false); // Should not return. | |
| 7047 } | |
| 7048 | |
| 7049 | |
| 7050 static void MissingScriptInfoMessageListener(v8::Handle<v8::Message> message, | 7049 static void MissingScriptInfoMessageListener(v8::Handle<v8::Message> message, |
| 7051 v8::Handle<Value> data) { | 7050 v8::Handle<Value> data) { |
| 7052 CHECK(message->GetScriptResourceName()->IsUndefined()); | 7051 CHECK(message->GetScriptResourceName()->IsUndefined()); |
| 7053 CHECK_EQ(v8::Undefined(CcTest::isolate()), message->GetScriptResourceName()); | 7052 CHECK_EQ(v8::Undefined(CcTest::isolate()), message->GetScriptResourceName()); |
| 7054 message->GetLineNumber(); | 7053 message->GetLineNumber(); |
| 7055 message->GetSourceLine(); | 7054 message->GetSourceLine(); |
| 7056 } | 7055 } |
| 7057 | 7056 |
| 7058 | 7057 |
| 7059 THREADED_TEST(ErrorWithMissingScriptInfo) { | 7058 THREADED_TEST(ErrorWithMissingScriptInfo) { |
| 7060 LocalContext context; | 7059 LocalContext context; |
| 7061 v8::HandleScope scope(context->GetIsolate()); | 7060 v8::HandleScope scope(context->GetIsolate()); |
| 7062 v8::V8::AddMessageListener(MissingScriptInfoMessageListener); | 7061 v8::V8::AddMessageListener(MissingScriptInfoMessageListener); |
| 7063 Script::Compile(v8_str("throw Error()"))->Run(); | 7062 Script::Compile(v8_str("throw Error()"))->Run(); |
| 7064 v8::V8::RemoveMessageListeners(MissingScriptInfoMessageListener); | 7063 v8::V8::RemoveMessageListeners(MissingScriptInfoMessageListener); |
| 7065 } | 7064 } |
| 7066 | 7065 |
| 7067 | 7066 |
| 7068 int global_index = 0; | |
| 7069 | |
| 7070 template<typename T> | |
| 7071 class Snorkel { | |
| 7072 public: | |
| 7073 explicit Snorkel(v8::Persistent<T>* handle) : handle_(handle) { | |
| 7074 index_ = global_index++; | |
| 7075 } | |
| 7076 v8::Persistent<T>* handle_; | |
| 7077 int index_; | |
| 7078 }; | |
| 7079 | |
| 7080 class Whammy { | |
| 7081 public: | |
| 7082 explicit Whammy(v8::Isolate* isolate) : cursor_(0), isolate_(isolate) { } | |
| 7083 ~Whammy() { script_.Reset(); } | |
| 7084 v8::Handle<Script> getScript() { | |
| 7085 if (script_.IsEmpty()) script_.Reset(isolate_, v8_compile("({}).blammo")); | |
| 7086 return Local<Script>::New(isolate_, script_); | |
| 7087 } | |
| 7088 | |
| 7089 public: | |
| 7090 static const int kObjectCount = 256; | |
| 7091 int cursor_; | |
| 7092 v8::Isolate* isolate_; | |
| 7093 v8::Persistent<v8::Object> objects_[kObjectCount]; | |
| 7094 v8::Persistent<Script> script_; | |
| 7095 }; | |
| 7096 | |
| 7097 static void HandleWeakReference( | |
| 7098 const v8::WeakCallbackData<v8::Value, Snorkel<v8::Value> >& data) { | |
| 7099 data.GetParameter()->handle_->ClearWeak(); | |
| 7100 delete data.GetParameter(); | |
| 7101 } | |
| 7102 | |
| 7103 void WhammyPropertyGetter(Local<String> name, | |
| 7104 const v8::PropertyCallbackInfo<v8::Value>& info) { | |
| 7105 Whammy* whammy = | |
| 7106 static_cast<Whammy*>(v8::Handle<v8::External>::Cast(info.Data())->Value()); | |
| 7107 | |
| 7108 v8::Persistent<v8::Object>& prev = whammy->objects_[whammy->cursor_]; | |
| 7109 | |
| 7110 v8::Handle<v8::Object> obj = v8::Object::New(info.GetIsolate()); | |
| 7111 if (!prev.IsEmpty()) { | |
| 7112 v8::Local<v8::Object>::New(info.GetIsolate(), prev) | |
| 7113 ->Set(v8_str("next"), obj); | |
| 7114 prev.SetWeak<Value, Snorkel<Value> >(new Snorkel<Value>(&prev.As<Value>()), | |
| 7115 &HandleWeakReference); | |
| 7116 } | |
| 7117 whammy->objects_[whammy->cursor_].Reset(info.GetIsolate(), obj); | |
| 7118 whammy->cursor_ = (whammy->cursor_ + 1) % Whammy::kObjectCount; | |
| 7119 info.GetReturnValue().Set(whammy->getScript()->Run()); | |
| 7120 } | |
| 7121 | |
| 7122 | |
| 7123 THREADED_TEST(WeakReference) { | |
| 7124 v8::Isolate* isolate = CcTest::isolate(); | |
| 7125 v8::HandleScope handle_scope(isolate); | |
| 7126 v8::Handle<v8::ObjectTemplate> templ= v8::ObjectTemplate::New(isolate); | |
| 7127 Whammy* whammy = new Whammy(CcTest::isolate()); | |
| 7128 templ->SetNamedPropertyHandler(WhammyPropertyGetter, | |
| 7129 0, 0, 0, 0, | |
| 7130 v8::External::New(CcTest::isolate(), whammy)); | |
| 7131 const char* extension_list[] = { "v8/gc" }; | |
| 7132 v8::ExtensionConfiguration extensions(1, extension_list); | |
| 7133 v8::Handle<Context> context = | |
| 7134 Context::New(CcTest::isolate(), &extensions); | |
| 7135 Context::Scope context_scope(context); | |
| 7136 | |
| 7137 v8::Handle<v8::Object> interceptor = templ->NewInstance(); | |
| 7138 context->Global()->Set(v8_str("whammy"), interceptor); | |
| 7139 const char* code = | |
| 7140 "var last;" | |
| 7141 "for (var i = 0; i < 10000; i++) {" | |
| 7142 " var obj = whammy.length;" | |
| 7143 " if (last) last.next = obj;" | |
| 7144 " last = obj;" | |
| 7145 "}" | |
| 7146 "gc();" | |
| 7147 "4"; | |
| 7148 v8::Handle<Value> result = CompileRun(code); | |
| 7149 CHECK_EQ(4.0, result->NumberValue()); | |
| 7150 delete whammy; | |
| 7151 } | |
| 7152 | |
| 7153 | |
| 7154 struct FlagAndPersistent { | 7067 struct FlagAndPersistent { |
| 7155 bool flag; | 7068 bool flag; |
| 7156 v8::Persistent<v8::Object> handle; | 7069 v8::Persistent<v8::Object> handle; |
| 7157 }; | 7070 }; |
| 7158 | 7071 |
| 7159 | 7072 |
| 7160 static void DisposeAndSetFlag( | 7073 static void DisposeAndSetFlag( |
| 7161 const v8::WeakCallbackData<v8::Object, FlagAndPersistent>& data) { | 7074 const v8::WeakCallbackData<v8::Object, FlagAndPersistent>& data) { |
| 7162 data.GetParameter()->handle.Reset(); | 7075 data.GetParameter()->handle.Reset(); |
| 7163 data.GetParameter()->flag = true; | 7076 data.GetParameter()->flag = true; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 7179 } | 7092 } |
| 7180 | 7093 |
| 7181 object_a.flag = false; | 7094 object_a.flag = false; |
| 7182 object_b.flag = false; | 7095 object_b.flag = false; |
| 7183 object_a.handle.SetWeak(&object_a, &DisposeAndSetFlag); | 7096 object_a.handle.SetWeak(&object_a, &DisposeAndSetFlag); |
| 7184 object_b.handle.SetWeak(&object_b, &DisposeAndSetFlag); | 7097 object_b.handle.SetWeak(&object_b, &DisposeAndSetFlag); |
| 7185 CHECK(!object_b.handle.IsIndependent()); | 7098 CHECK(!object_b.handle.IsIndependent()); |
| 7186 object_a.handle.MarkIndependent(); | 7099 object_a.handle.MarkIndependent(); |
| 7187 object_b.handle.MarkIndependent(); | 7100 object_b.handle.MarkIndependent(); |
| 7188 CHECK(object_b.handle.IsIndependent()); | 7101 CHECK(object_b.handle.IsIndependent()); |
| 7189 CcTest::heap()->PerformScavenge(); | 7102 CcTest::heap()->CollectGarbage(i::NEW_SPACE); |
| 7190 CHECK(object_a.flag); | 7103 CHECK(object_a.flag); |
| 7191 CHECK(object_b.flag); | 7104 CHECK(object_b.flag); |
| 7192 } | 7105 } |
| 7193 | 7106 |
| 7194 | 7107 |
| 7195 static void InvokeScavenge() { | 7108 static void InvokeScavenge() { |
| 7196 CcTest::heap()->PerformScavenge(); | 7109 CcTest::heap()->CollectGarbage(i::NEW_SPACE); |
| 7197 } | 7110 } |
| 7198 | 7111 |
| 7199 | 7112 |
| 7200 static void InvokeMarkSweep() { | 7113 static void InvokeMarkSweep() { |
| 7201 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); | 7114 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 7202 } | 7115 } |
| 7203 | 7116 |
| 7204 | 7117 |
| 7205 static void ForceScavenge( | 7118 static void ForceScavenge( |
| 7206 const v8::WeakCallbackData<v8::Object, FlagAndPersistent>& data) { | 7119 const v8::WeakCallbackData<v8::Object, FlagAndPersistent>& data) { |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7268 v8::HandleScope handle_scope(isolate); | 7181 v8::HandleScope handle_scope(isolate); |
| 7269 v8::Local<v8::Object> o = v8::Object::New(isolate); | 7182 v8::Local<v8::Object> o = v8::Object::New(isolate); |
| 7270 object.handle.Reset(isolate, o); | 7183 object.handle.Reset(isolate, o); |
| 7271 o->Set(v8_str("x"), v8::Integer::New(isolate, 1)); | 7184 o->Set(v8_str("x"), v8::Integer::New(isolate, 1)); |
| 7272 v8::Local<String> y_str = v8_str("y"); | 7185 v8::Local<String> y_str = v8_str("y"); |
| 7273 o->Set(y_str, y_str); | 7186 o->Set(y_str, y_str); |
| 7274 } | 7187 } |
| 7275 object.flag = false; | 7188 object.flag = false; |
| 7276 object.handle.SetWeak(&object, &RevivingCallback); | 7189 object.handle.SetWeak(&object, &RevivingCallback); |
| 7277 object.handle.MarkIndependent(); | 7190 object.handle.MarkIndependent(); |
| 7278 CcTest::heap()->PerformScavenge(); | 7191 CcTest::heap()->CollectGarbage(i::NEW_SPACE); |
| 7279 CHECK(object.flag); | 7192 CHECK(object.flag); |
| 7280 CcTest::heap()->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); | 7193 CcTest::heap()->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); |
| 7281 { | 7194 { |
| 7282 v8::HandleScope handle_scope(isolate); | 7195 v8::HandleScope handle_scope(isolate); |
| 7283 v8::Local<v8::Object> o = | 7196 v8::Local<v8::Object> o = |
| 7284 v8::Local<v8::Object>::New(isolate, object.handle); | 7197 v8::Local<v8::Object>::New(isolate, object.handle); |
| 7285 v8::Local<String> y_str = v8_str("y"); | 7198 v8::Local<String> y_str = v8_str("y"); |
| 7286 CHECK_EQ(v8::Integer::New(isolate, 1), o->Get(v8_str("x"))); | 7199 CHECK_EQ(v8::Integer::New(isolate, 1), o->Get(v8_str("x"))); |
| 7287 CHECK(o->Get(y_str)->Equals(y_str)); | 7200 CHECK(o->Get(y_str)->Equals(y_str)); |
| 7288 } | 7201 } |
| (...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7607 | 7520 |
| 7608 | 7521 |
| 7609 THREADED_TEST(StringWrite) { | 7522 THREADED_TEST(StringWrite) { |
| 7610 LocalContext context; | 7523 LocalContext context; |
| 7611 v8::HandleScope scope(context->GetIsolate()); | 7524 v8::HandleScope scope(context->GetIsolate()); |
| 7612 v8::Handle<String> str = v8_str("abcde"); | 7525 v8::Handle<String> str = v8_str("abcde"); |
| 7613 // abc<Icelandic eth><Unicode snowman>. | 7526 // abc<Icelandic eth><Unicode snowman>. |
| 7614 v8::Handle<String> str2 = v8_str("abc\303\260\342\230\203"); | 7527 v8::Handle<String> str2 = v8_str("abc\303\260\342\230\203"); |
| 7615 v8::Handle<String> str3 = v8::String::NewFromUtf8( | 7528 v8::Handle<String> str3 = v8::String::NewFromUtf8( |
| 7616 context->GetIsolate(), "abc\0def", v8::String::kNormalString, 7); | 7529 context->GetIsolate(), "abc\0def", v8::String::kNormalString, 7); |
| 7530 // "ab" + lead surrogate + "cd" + trail surrogate + "ef" |
| 7531 uint16_t orphans[8] = { 0x61, 0x62, 0xd800, 0x63, 0x64, 0xdc00, 0x65, 0x66 }; |
| 7532 v8::Handle<String> orphans_str = v8::String::NewFromTwoByte( |
| 7533 context->GetIsolate(), orphans, v8::String::kNormalString, 8); |
| 7534 // single lead surrogate |
| 7535 uint16_t lead[1] = { 0xd800 }; |
| 7536 v8::Handle<String> lead_str = v8::String::NewFromTwoByte( |
| 7537 context->GetIsolate(), lead, v8::String::kNormalString, 1); |
| 7538 // single trail surrogate |
| 7539 uint16_t trail[1] = { 0xdc00 }; |
| 7540 v8::Handle<String> trail_str = v8::String::NewFromTwoByte( |
| 7541 context->GetIsolate(), trail, v8::String::kNormalString, 1); |
| 7542 // surrogate pair |
| 7543 uint16_t pair[2] = { 0xd800, 0xdc00 }; |
| 7544 v8::Handle<String> pair_str = v8::String::NewFromTwoByte( |
| 7545 context->GetIsolate(), pair, v8::String::kNormalString, 2); |
| 7617 const int kStride = 4; // Must match stride in for loops in JS below. | 7546 const int kStride = 4; // Must match stride in for loops in JS below. |
| 7618 CompileRun( | 7547 CompileRun( |
| 7619 "var left = '';" | 7548 "var left = '';" |
| 7620 "for (var i = 0; i < 0xd800; i += 4) {" | 7549 "for (var i = 0; i < 0xd800; i += 4) {" |
| 7621 " left = left + String.fromCharCode(i);" | 7550 " left = left + String.fromCharCode(i);" |
| 7622 "}"); | 7551 "}"); |
| 7623 CompileRun( | 7552 CompileRun( |
| 7624 "var right = '';" | 7553 "var right = '';" |
| 7625 "for (var i = 0; i < 0xd800; i += 4) {" | 7554 "for (var i = 0; i < 0xd800; i += 4) {" |
| 7626 " right = String.fromCharCode(i) + right;" | 7555 " right = String.fromCharCode(i) + right;" |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7680 CHECK_EQ(3, len); | 7609 CHECK_EQ(3, len); |
| 7681 CHECK_EQ(3, charlen); | 7610 CHECK_EQ(3, charlen); |
| 7682 CHECK_EQ(0, strncmp(utf8buf, "abc\1", 4)); | 7611 CHECK_EQ(0, strncmp(utf8buf, "abc\1", 4)); |
| 7683 | 7612 |
| 7684 memset(utf8buf, 0x1, 1000); | 7613 memset(utf8buf, 0x1, 1000); |
| 7685 len = str2->WriteUtf8(utf8buf, 2, &charlen); | 7614 len = str2->WriteUtf8(utf8buf, 2, &charlen); |
| 7686 CHECK_EQ(2, len); | 7615 CHECK_EQ(2, len); |
| 7687 CHECK_EQ(2, charlen); | 7616 CHECK_EQ(2, charlen); |
| 7688 CHECK_EQ(0, strncmp(utf8buf, "ab\1", 3)); | 7617 CHECK_EQ(0, strncmp(utf8buf, "ab\1", 3)); |
| 7689 | 7618 |
| 7619 // allow orphan surrogates by default |
| 7620 memset(utf8buf, 0x1, 1000); |
| 7621 len = orphans_str->WriteUtf8(utf8buf, sizeof(utf8buf), &charlen); |
| 7622 CHECK_EQ(13, len); |
| 7623 CHECK_EQ(8, charlen); |
| 7624 CHECK_EQ(0, strcmp(utf8buf, "ab\355\240\200cd\355\260\200ef")); |
| 7625 |
| 7626 // replace orphan surrogates with unicode replacement character |
| 7627 memset(utf8buf, 0x1, 1000); |
| 7628 len = orphans_str->WriteUtf8(utf8buf, |
| 7629 sizeof(utf8buf), |
| 7630 &charlen, |
| 7631 String::REPLACE_INVALID_UTF8); |
| 7632 CHECK_EQ(13, len); |
| 7633 CHECK_EQ(8, charlen); |
| 7634 CHECK_EQ(0, strcmp(utf8buf, "ab\357\277\275cd\357\277\275ef")); |
| 7635 |
| 7636 // replace single lead surrogate with unicode replacement character |
| 7637 memset(utf8buf, 0x1, 1000); |
| 7638 len = lead_str->WriteUtf8(utf8buf, |
| 7639 sizeof(utf8buf), |
| 7640 &charlen, |
| 7641 String::REPLACE_INVALID_UTF8); |
| 7642 CHECK_EQ(4, len); |
| 7643 CHECK_EQ(1, charlen); |
| 7644 CHECK_EQ(0, strcmp(utf8buf, "\357\277\275")); |
| 7645 |
| 7646 // replace single trail surrogate with unicode replacement character |
| 7647 memset(utf8buf, 0x1, 1000); |
| 7648 len = trail_str->WriteUtf8(utf8buf, |
| 7649 sizeof(utf8buf), |
| 7650 &charlen, |
| 7651 String::REPLACE_INVALID_UTF8); |
| 7652 CHECK_EQ(4, len); |
| 7653 CHECK_EQ(1, charlen); |
| 7654 CHECK_EQ(0, strcmp(utf8buf, "\357\277\275")); |
| 7655 |
| 7656 // do not replace / write anything if surrogate pair does not fit the buffer |
| 7657 // space |
| 7658 memset(utf8buf, 0x1, 1000); |
| 7659 len = pair_str->WriteUtf8(utf8buf, |
| 7660 3, |
| 7661 &charlen, |
| 7662 String::REPLACE_INVALID_UTF8); |
| 7663 CHECK_EQ(0, len); |
| 7664 CHECK_EQ(0, charlen); |
| 7665 |
| 7690 memset(utf8buf, 0x1, sizeof(utf8buf)); | 7666 memset(utf8buf, 0x1, sizeof(utf8buf)); |
| 7691 len = GetUtf8Length(left_tree); | 7667 len = GetUtf8Length(left_tree); |
| 7692 int utf8_expected = | 7668 int utf8_expected = |
| 7693 (0x80 + (0x800 - 0x80) * 2 + (0xd800 - 0x800) * 3) / kStride; | 7669 (0x80 + (0x800 - 0x80) * 2 + (0xd800 - 0x800) * 3) / kStride; |
| 7694 CHECK_EQ(utf8_expected, len); | 7670 CHECK_EQ(utf8_expected, len); |
| 7695 len = left_tree->WriteUtf8(utf8buf, utf8_expected, &charlen); | 7671 len = left_tree->WriteUtf8(utf8buf, utf8_expected, &charlen); |
| 7696 CHECK_EQ(utf8_expected, len); | 7672 CHECK_EQ(utf8_expected, len); |
| 7697 CHECK_EQ(0xd800 / kStride, charlen); | 7673 CHECK_EQ(0xd800 / kStride, charlen); |
| 7698 CHECK_EQ(0xed, static_cast<unsigned char>(utf8buf[utf8_expected - 3])); | 7674 CHECK_EQ(0xed, static_cast<unsigned char>(utf8buf[utf8_expected - 3])); |
| 7699 CHECK_EQ(0x9f, static_cast<unsigned char>(utf8buf[utf8_expected - 2])); | 7675 CHECK_EQ(0x9f, static_cast<unsigned char>(utf8buf[utf8_expected - 2])); |
| (...skipping 2882 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10582 Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate); | 10558 Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate); |
| 10583 templ->SetClassName(v8_str("Fun")); | 10559 templ->SetClassName(v8_str("Fun")); |
| 10584 Local<Function> cons = templ->GetFunction(); | 10560 Local<Function> cons = templ->GetFunction(); |
| 10585 context->Global()->Set(v8_str("Fun"), cons); | 10561 context->Global()->Set(v8_str("Fun"), cons); |
| 10586 Local<Value> value = CompileRun( | 10562 Local<Value> value = CompileRun( |
| 10587 "function test() {" | 10563 "function test() {" |
| 10588 " try {" | 10564 " try {" |
| 10589 " (new Fun()).blah()" | 10565 " (new Fun()).blah()" |
| 10590 " } catch (e) {" | 10566 " } catch (e) {" |
| 10591 " var str = String(e);" | 10567 " var str = String(e);" |
| 10592 " if (str.indexOf('TypeError') == -1) return 1;" | 10568 // " if (str.indexOf('TypeError') == -1) return 1;" |
| 10593 " if (str.indexOf('[object Fun]') != -1) return 2;" | 10569 // " if (str.indexOf('[object Fun]') != -1) return 2;" |
| 10594 " if (str.indexOf('#<Fun>') == -1) return 3;" | 10570 // " if (str.indexOf('#<Fun>') == -1) return 3;" |
| 10595 " return 0;" | 10571 " return 0;" |
| 10596 " }" | 10572 " }" |
| 10597 " return 4;" | 10573 " return 4;" |
| 10598 "}" | 10574 "}" |
| 10599 "test();"); | 10575 "test();"); |
| 10600 CHECK_EQ(0, value->Int32Value()); | 10576 CHECK_EQ(0, value->Int32Value()); |
| 10601 } | 10577 } |
| 10602 | 10578 |
| 10603 | 10579 |
| 10604 THREADED_TEST(EvalAliasedDynamic) { | 10580 THREADED_TEST(EvalAliasedDynamic) { |
| (...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10859 context->Global()->Set(v8_str("obj2"), instance); | 10835 context->Global()->Set(v8_str("obj2"), instance); |
| 10860 v8::TryCatch try_catch; | 10836 v8::TryCatch try_catch; |
| 10861 Local<Value> value; | 10837 Local<Value> value; |
| 10862 CHECK(!try_catch.HasCaught()); | 10838 CHECK(!try_catch.HasCaught()); |
| 10863 | 10839 |
| 10864 // Call an object without call-as-function handler through the JS | 10840 // Call an object without call-as-function handler through the JS |
| 10865 value = CompileRun("obj2(28)"); | 10841 value = CompileRun("obj2(28)"); |
| 10866 CHECK(value.IsEmpty()); | 10842 CHECK(value.IsEmpty()); |
| 10867 CHECK(try_catch.HasCaught()); | 10843 CHECK(try_catch.HasCaught()); |
| 10868 String::Utf8Value exception_value1(try_catch.Exception()); | 10844 String::Utf8Value exception_value1(try_catch.Exception()); |
| 10869 CHECK_EQ("TypeError: Property 'obj2' of object #<Object> is not a function", | 10845 // TODO(verwaest): Better message |
| 10846 CHECK_EQ("TypeError: object is not a function", |
| 10870 *exception_value1); | 10847 *exception_value1); |
| 10871 try_catch.Reset(); | 10848 try_catch.Reset(); |
| 10872 | 10849 |
| 10873 // Call an object without call-as-function handler through the API | 10850 // Call an object without call-as-function handler through the API |
| 10874 value = CompileRun("obj2(28)"); | 10851 value = CompileRun("obj2(28)"); |
| 10875 v8::Handle<Value> args[] = { v8_num(28) }; | 10852 v8::Handle<Value> args[] = { v8_num(28) }; |
| 10876 value = instance->CallAsFunction(instance, 1, args); | 10853 value = instance->CallAsFunction(instance, 1, args); |
| 10877 CHECK(value.IsEmpty()); | 10854 CHECK(value.IsEmpty()); |
| 10878 CHECK(try_catch.HasCaught()); | 10855 CHECK(try_catch.HasCaught()); |
| 10879 String::Utf8Value exception_value2(try_catch.Exception()); | 10856 String::Utf8Value exception_value2(try_catch.Exception()); |
| (...skipping 1362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12242 "var result = 0;" | 12219 "var result = 0;" |
| 12243 "var saved_result = 0;" | 12220 "var saved_result = 0;" |
| 12244 "for (var i = 0; i < 100; i++) {" | 12221 "for (var i = 0; i < 100; i++) {" |
| 12245 " result = receiver.method(41);" | 12222 " result = receiver.method(41);" |
| 12246 " if (i == 50) {" | 12223 " if (i == 50) {" |
| 12247 " saved_result = result;" | 12224 " saved_result = result;" |
| 12248 " receiver = 333;" | 12225 " receiver = 333;" |
| 12249 " }" | 12226 " }" |
| 12250 "}"); | 12227 "}"); |
| 12251 CHECK(try_catch.HasCaught()); | 12228 CHECK(try_catch.HasCaught()); |
| 12252 CHECK_EQ(v8_str("TypeError: Object 333 has no method 'method'"), | 12229 // TODO(verwaest): Adjust message. |
| 12230 CHECK_EQ(v8_str("TypeError: undefined is not a function"), |
| 12253 try_catch.Exception()->ToString()); | 12231 try_catch.Exception()->ToString()); |
| 12254 CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value()); | 12232 CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value()); |
| 12255 CHECK_GE(interceptor_call_count, 50); | 12233 CHECK_GE(interceptor_call_count, 50); |
| 12256 } | 12234 } |
| 12257 | 12235 |
| 12258 | 12236 |
| 12259 THREADED_PROFILED_TEST(InterceptorCallICFastApi_SimpleSignature_TypeError) { | 12237 THREADED_PROFILED_TEST(InterceptorCallICFastApi_SimpleSignature_TypeError) { |
| 12260 int interceptor_call_count = 0; | 12238 int interceptor_call_count = 0; |
| 12261 v8::Isolate* isolate = CcTest::isolate(); | 12239 v8::Isolate* isolate = CcTest::isolate(); |
| 12262 v8::HandleScope scope(isolate); | 12240 v8::HandleScope scope(isolate); |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12416 "var result = 0;" | 12394 "var result = 0;" |
| 12417 "var saved_result = 0;" | 12395 "var saved_result = 0;" |
| 12418 "for (var i = 0; i < 100; i++) {" | 12396 "for (var i = 0; i < 100; i++) {" |
| 12419 " result = receiver.method(41);" | 12397 " result = receiver.method(41);" |
| 12420 " if (i == 50) {" | 12398 " if (i == 50) {" |
| 12421 " saved_result = result;" | 12399 " saved_result = result;" |
| 12422 " receiver = 333;" | 12400 " receiver = 333;" |
| 12423 " }" | 12401 " }" |
| 12424 "}"); | 12402 "}"); |
| 12425 CHECK(try_catch.HasCaught()); | 12403 CHECK(try_catch.HasCaught()); |
| 12426 CHECK_EQ(v8_str("TypeError: Object 333 has no method 'method'"), | 12404 // TODO(verwaest): Adjust message. |
| 12405 CHECK_EQ(v8_str("TypeError: undefined is not a function"), |
| 12427 try_catch.Exception()->ToString()); | 12406 try_catch.Exception()->ToString()); |
| 12428 CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value()); | 12407 CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value()); |
| 12429 } | 12408 } |
| 12430 | 12409 |
| 12431 | 12410 |
| 12432 THREADED_PROFILED_TEST(CallICFastApi_SimpleSignature_TypeError) { | 12411 THREADED_PROFILED_TEST(CallICFastApi_SimpleSignature_TypeError) { |
| 12433 v8::Isolate* isolate = CcTest::isolate(); | 12412 v8::Isolate* isolate = CcTest::isolate(); |
| 12434 v8::HandleScope scope(isolate); | 12413 v8::HandleScope scope(isolate); |
| 12435 v8::Handle<v8::FunctionTemplate> fun_templ = | 12414 v8::Handle<v8::FunctionTemplate> fun_templ = |
| 12436 v8::FunctionTemplate::New(isolate); | 12415 v8::FunctionTemplate::New(isolate); |
| (...skipping 972 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13409 #ifdef DEBUG | 13388 #ifdef DEBUG |
| 13410 if (count != expected) CcTest::heap()->TracePathToGlobal(); | 13389 if (count != expected) CcTest::heap()->TracePathToGlobal(); |
| 13411 #endif | 13390 #endif |
| 13412 CHECK_EQ(expected, count); | 13391 CHECK_EQ(expected, count); |
| 13413 } | 13392 } |
| 13414 | 13393 |
| 13415 | 13394 |
| 13416 TEST(DontLeakGlobalObjects) { | 13395 TEST(DontLeakGlobalObjects) { |
| 13417 // Regression test for issues 1139850 and 1174891. | 13396 // Regression test for issues 1139850 and 1174891. |
| 13418 | 13397 |
| 13398 i::FLAG_expose_gc = true; |
| 13419 v8::V8::Initialize(); | 13399 v8::V8::Initialize(); |
| 13420 | 13400 |
| 13421 for (int i = 0; i < 5; i++) { | 13401 for (int i = 0; i < 5; i++) { |
| 13422 { v8::HandleScope scope(CcTest::isolate()); | 13402 { v8::HandleScope scope(CcTest::isolate()); |
| 13423 LocalContext context; | 13403 LocalContext context; |
| 13424 } | 13404 } |
| 13425 v8::V8::ContextDisposedNotification(); | 13405 v8::V8::ContextDisposedNotification(); |
| 13426 CheckSurvivingGlobalObjectsCount(0); | 13406 CheckSurvivingGlobalObjectsCount(0); |
| 13427 | 13407 |
| 13428 { v8::HandleScope scope(CcTest::isolate()); | 13408 { v8::HandleScope scope(CcTest::isolate()); |
| (...skipping 1409 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14838 v8::ScriptData* deserialized_sd = | 14818 v8::ScriptData* deserialized_sd = |
| 14839 v8::ScriptData::New(serialized_data, serialized_data_length); | 14819 v8::ScriptData::New(serialized_data, serialized_data_length); |
| 14840 | 14820 |
| 14841 // Verify that the original is the same as the deserialized. | 14821 // Verify that the original is the same as the deserialized. |
| 14842 CHECK_EQ(sd->Length(), deserialized_sd->Length()); | 14822 CHECK_EQ(sd->Length(), deserialized_sd->Length()); |
| 14843 CHECK_EQ(0, memcmp(sd->Data(), deserialized_sd->Data(), sd->Length())); | 14823 CHECK_EQ(0, memcmp(sd->Data(), deserialized_sd->Data(), sd->Length())); |
| 14844 CHECK_EQ(sd->HasError(), deserialized_sd->HasError()); | 14824 CHECK_EQ(sd->HasError(), deserialized_sd->HasError()); |
| 14845 | 14825 |
| 14846 delete sd; | 14826 delete sd; |
| 14847 delete deserialized_sd; | 14827 delete deserialized_sd; |
| 14828 i::DeleteArray(serialized_data); |
| 14848 } | 14829 } |
| 14849 | 14830 |
| 14850 | 14831 |
| 14851 // Attempts to deserialize bad data. | 14832 // Attempts to deserialize bad data. |
| 14852 TEST(PreCompileDeserializationError) { | 14833 TEST(PreCompileDeserializationError) { |
| 14853 v8::V8::Initialize(); | 14834 v8::V8::Initialize(); |
| 14854 const char* data = "DONT CARE"; | 14835 const char* data = "DONT CARE"; |
| 14855 int invalid_size = 3; | 14836 int invalid_size = 3; |
| 14856 v8::ScriptData* sd = v8::ScriptData::New(data, invalid_size); | 14837 v8::ScriptData* sd = v8::ScriptData::New(data, invalid_size); |
| 14857 | 14838 |
| (...skipping 28 matching lines...) Expand all Loading... |
| 14886 v8::TryCatch try_catch; | 14867 v8::TryCatch try_catch; |
| 14887 | 14868 |
| 14888 Local<String> source = String::NewFromUtf8(isolate, script); | 14869 Local<String> source = String::NewFromUtf8(isolate, script); |
| 14889 Local<Script> compiled_script = Script::New(source, NULL, sd); | 14870 Local<Script> compiled_script = Script::New(source, NULL, sd); |
| 14890 CHECK(try_catch.HasCaught()); | 14871 CHECK(try_catch.HasCaught()); |
| 14891 String::Utf8Value exception_value(try_catch.Message()->Get()); | 14872 String::Utf8Value exception_value(try_catch.Message()->Get()); |
| 14892 CHECK_EQ("Uncaught SyntaxError: Invalid preparser data for function bar", | 14873 CHECK_EQ("Uncaught SyntaxError: Invalid preparser data for function bar", |
| 14893 *exception_value); | 14874 *exception_value); |
| 14894 | 14875 |
| 14895 try_catch.Reset(); | 14876 try_catch.Reset(); |
| 14877 delete sd; |
| 14896 | 14878 |
| 14897 // Overwrite function bar's start position with 200. The function entry | 14879 // Overwrite function bar's start position with 200. The function entry |
| 14898 // will not be found when searching for it by position and we should fall | 14880 // will not be found when searching for it by position and we should fall |
| 14899 // back on eager compilation. | 14881 // back on eager compilation. |
| 14900 sd = v8::ScriptData::PreCompile(v8::String::NewFromUtf8( | 14882 sd = v8::ScriptData::PreCompile(v8::String::NewFromUtf8( |
| 14901 isolate, script, v8::String::kNormalString, i::StrLength(script))); | 14883 isolate, script, v8::String::kNormalString, i::StrLength(script))); |
| 14902 sd_data = reinterpret_cast<unsigned*>(const_cast<char*>(sd->Data())); | 14884 sd_data = reinterpret_cast<unsigned*>(const_cast<char*>(sd->Data())); |
| 14903 sd_data[kHeaderSize + 1 * kFunctionEntrySize + kFunctionEntryStartOffset] = | 14885 sd_data[kHeaderSize + 1 * kFunctionEntrySize + kFunctionEntryStartOffset] = |
| 14904 200; | 14886 200; |
| 14905 compiled_script = Script::New(source, NULL, sd); | 14887 compiled_script = Script::New(source, NULL, sd); |
| (...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15126 const char* ascii_sources[] = { | 15108 const char* ascii_sources[] = { |
| 15127 "0.5", | 15109 "0.5", |
| 15128 "-0.5", // This mainly testes PushBack in the Scanner. | 15110 "-0.5", // This mainly testes PushBack in the Scanner. |
| 15129 "--0.5", // This mainly testes PushBack in the Scanner. | 15111 "--0.5", // This mainly testes PushBack in the Scanner. |
| 15130 NULL | 15112 NULL |
| 15131 }; | 15113 }; |
| 15132 | 15114 |
| 15133 // Compile the sources as external two byte strings. | 15115 // Compile the sources as external two byte strings. |
| 15134 for (int i = 0; ascii_sources[i] != NULL; i++) { | 15116 for (int i = 0; ascii_sources[i] != NULL; i++) { |
| 15135 uint16_t* two_byte_string = AsciiToTwoByteString(ascii_sources[i]); | 15117 uint16_t* two_byte_string = AsciiToTwoByteString(ascii_sources[i]); |
| 15136 UC16VectorResource uc16_resource( | 15118 TestResource* uc16_resource = new TestResource(two_byte_string); |
| 15137 i::Vector<const uint16_t>(two_byte_string, | |
| 15138 i::StrLength(ascii_sources[i]))); | |
| 15139 v8::Local<v8::String> source = | 15119 v8::Local<v8::String> source = |
| 15140 v8::String::NewExternal(context->GetIsolate(), &uc16_resource); | 15120 v8::String::NewExternal(context->GetIsolate(), uc16_resource); |
| 15141 v8::Script::Compile(source); | 15121 v8::Script::Compile(source); |
| 15142 i::DeleteArray(two_byte_string); | |
| 15143 } | 15122 } |
| 15144 } | 15123 } |
| 15145 | 15124 |
| 15146 | 15125 |
| 15147 #ifndef V8_INTERPRETED_REGEXP | 15126 #ifndef V8_INTERPRETED_REGEXP |
| 15148 | 15127 |
| 15149 struct RegExpInterruptionData { | 15128 struct RegExpInterruptionData { |
| 15150 int loop_count; | 15129 int loop_count; |
| 15151 UC16VectorResource* string_resource; | 15130 UC16VectorResource* string_resource; |
| 15152 v8::Persistent<v8::String> string; | 15131 v8::Persistent<v8::String> string; |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15204 i::Vector<const i::uc16>(uc16_content, i::StrLength(ascii_content))); | 15183 i::Vector<const i::uc16>(uc16_content, i::StrLength(ascii_content))); |
| 15205 | 15184 |
| 15206 v8::TryCatch try_catch; | 15185 v8::TryCatch try_catch; |
| 15207 timeout_thread.Start(); | 15186 timeout_thread.Start(); |
| 15208 | 15187 |
| 15209 CompileRun("/((a*)*)*b/.exec(a)"); | 15188 CompileRun("/((a*)*)*b/.exec(a)"); |
| 15210 CHECK(try_catch.HasTerminated()); | 15189 CHECK(try_catch.HasTerminated()); |
| 15211 | 15190 |
| 15212 timeout_thread.Join(); | 15191 timeout_thread.Join(); |
| 15213 | 15192 |
| 15214 delete regexp_interruption_data.string_resource; | |
| 15215 regexp_interruption_data.string.Reset(); | 15193 regexp_interruption_data.string.Reset(); |
| 15194 i::DeleteArray(uc16_content); |
| 15216 } | 15195 } |
| 15217 | 15196 |
| 15218 #endif // V8_INTERPRETED_REGEXP | 15197 #endif // V8_INTERPRETED_REGEXP |
| 15219 | 15198 |
| 15220 | 15199 |
| 15221 // Test that we cannot set a property on the global object if there | 15200 // Test that we cannot set a property on the global object if there |
| 15222 // is a read-only property in the prototype chain. | 15201 // is a read-only property in the prototype chain. |
| 15223 TEST(ReadOnlyPropertyInGlobalProto) { | 15202 TEST(ReadOnlyPropertyInGlobalProto) { |
| 15224 i::FLAG_es5_readonly = true; | 15203 i::FLAG_es5_readonly = true; |
| 15225 v8::Isolate* isolate = CcTest::isolate(); | 15204 v8::Isolate* isolate = CcTest::isolate(); |
| (...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15618 } | 15597 } |
| 15619 | 15598 |
| 15620 | 15599 |
| 15621 THREADED_TEST(PixelArray) { | 15600 THREADED_TEST(PixelArray) { |
| 15622 LocalContext context; | 15601 LocalContext context; |
| 15623 i::Isolate* isolate = CcTest::i_isolate(); | 15602 i::Isolate* isolate = CcTest::i_isolate(); |
| 15624 i::Factory* factory = isolate->factory(); | 15603 i::Factory* factory = isolate->factory(); |
| 15625 v8::HandleScope scope(context->GetIsolate()); | 15604 v8::HandleScope scope(context->GetIsolate()); |
| 15626 const int kElementCount = 260; | 15605 const int kElementCount = 260; |
| 15627 uint8_t* pixel_data = reinterpret_cast<uint8_t*>(malloc(kElementCount)); | 15606 uint8_t* pixel_data = reinterpret_cast<uint8_t*>(malloc(kElementCount)); |
| 15628 i::Handle<i::ExternalPixelArray> pixels = | 15607 i::Handle<i::ExternalUint8ClampedArray> pixels = |
| 15629 i::Handle<i::ExternalPixelArray>::cast( | 15608 i::Handle<i::ExternalUint8ClampedArray>::cast( |
| 15630 factory->NewExternalArray(kElementCount, | 15609 factory->NewExternalArray(kElementCount, |
| 15631 v8::kExternalPixelArray, | 15610 v8::kExternalUint8ClampedArray, |
| 15632 pixel_data)); | 15611 pixel_data)); |
| 15633 // Force GC to trigger verification. | 15612 // Force GC to trigger verification. |
| 15634 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); | 15613 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 15635 for (int i = 0; i < kElementCount; i++) { | 15614 for (int i = 0; i < kElementCount; i++) { |
| 15636 pixels->set(i, i % 256); | 15615 pixels->set(i, i % 256); |
| 15637 } | 15616 } |
| 15638 // Force GC to trigger verification. | 15617 // Force GC to trigger verification. |
| 15639 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); | 15618 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 15640 for (int i = 0; i < kElementCount; i++) { | 15619 for (int i = 0; i < kElementCount; i++) { |
| 15641 CHECK_EQ(i % 256, pixels->get_scalar(i)); | 15620 CHECK_EQ(i % 256, pixels->get_scalar(i)); |
| (...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16032 } | 16011 } |
| 16033 | 16012 |
| 16034 | 16013 |
| 16035 THREADED_TEST(PixelArrayWithInterceptor) { | 16014 THREADED_TEST(PixelArrayWithInterceptor) { |
| 16036 LocalContext context; | 16015 LocalContext context; |
| 16037 i::Factory* factory = CcTest::i_isolate()->factory(); | 16016 i::Factory* factory = CcTest::i_isolate()->factory(); |
| 16038 v8::Isolate* isolate = context->GetIsolate(); | 16017 v8::Isolate* isolate = context->GetIsolate(); |
| 16039 v8::HandleScope scope(isolate); | 16018 v8::HandleScope scope(isolate); |
| 16040 const int kElementCount = 260; | 16019 const int kElementCount = 260; |
| 16041 uint8_t* pixel_data = reinterpret_cast<uint8_t*>(malloc(kElementCount)); | 16020 uint8_t* pixel_data = reinterpret_cast<uint8_t*>(malloc(kElementCount)); |
| 16042 i::Handle<i::ExternalPixelArray> pixels = | 16021 i::Handle<i::ExternalUint8ClampedArray> pixels = |
| 16043 i::Handle<i::ExternalPixelArray>::cast( | 16022 i::Handle<i::ExternalUint8ClampedArray>::cast( |
| 16044 factory->NewExternalArray(kElementCount, | 16023 factory->NewExternalArray(kElementCount, |
| 16045 v8::kExternalPixelArray, | 16024 v8::kExternalUint8ClampedArray, |
| 16046 pixel_data)); | 16025 pixel_data)); |
| 16047 for (int i = 0; i < kElementCount; i++) { | 16026 for (int i = 0; i < kElementCount; i++) { |
| 16048 pixels->set(i, i % 256); | 16027 pixels->set(i, i % 256); |
| 16049 } | 16028 } |
| 16050 v8::Handle<v8::ObjectTemplate> templ = | 16029 v8::Handle<v8::ObjectTemplate> templ = |
| 16051 v8::ObjectTemplate::New(context->GetIsolate()); | 16030 v8::ObjectTemplate::New(context->GetIsolate()); |
| 16052 templ->SetIndexedPropertyHandler(NotHandledIndexedPropertyGetter, | 16031 templ->SetIndexedPropertyHandler(NotHandledIndexedPropertyGetter, |
| 16053 NotHandledIndexedPropertySetter); | 16032 NotHandledIndexedPropertySetter); |
| 16054 v8::Handle<v8::Object> obj = templ->NewInstance(); | 16033 v8::Handle<v8::Object> obj = templ->NewInstance(); |
| 16055 obj->SetIndexedPropertiesToPixelData(pixel_data, kElementCount); | 16034 obj->SetIndexedPropertiesToPixelData(pixel_data, kElementCount); |
| 16056 context->Global()->Set(v8_str("pixels"), obj); | 16035 context->Global()->Set(v8_str("pixels"), obj); |
| 16057 v8::Handle<v8::Value> result = CompileRun("pixels[1]"); | 16036 v8::Handle<v8::Value> result = CompileRun("pixels[1]"); |
| 16058 CHECK_EQ(1, result->Int32Value()); | 16037 CHECK_EQ(1, result->Int32Value()); |
| 16059 result = CompileRun("var sum = 0;" | 16038 result = CompileRun("var sum = 0;" |
| 16060 "for (var i = 0; i < 8; i++) {" | 16039 "for (var i = 0; i < 8; i++) {" |
| 16061 " sum += pixels[i] = pixels[i] = -i;" | 16040 " sum += pixels[i] = pixels[i] = -i;" |
| 16062 "}" | 16041 "}" |
| 16063 "sum;"); | 16042 "sum;"); |
| 16064 CHECK_EQ(-28, result->Int32Value()); | 16043 CHECK_EQ(-28, result->Int32Value()); |
| 16065 result = CompileRun("pixels.hasOwnProperty('1')"); | 16044 result = CompileRun("pixels.hasOwnProperty('1')"); |
| 16066 CHECK(result->BooleanValue()); | 16045 CHECK(result->BooleanValue()); |
| 16067 free(pixel_data); | 16046 free(pixel_data); |
| 16068 } | 16047 } |
| 16069 | 16048 |
| 16070 | 16049 |
| 16071 static int ExternalArrayElementSize(v8::ExternalArrayType array_type) { | 16050 static int ExternalArrayElementSize(v8::ExternalArrayType array_type) { |
| 16072 switch (array_type) { | 16051 switch (array_type) { |
| 16073 case v8::kExternalByteArray: | 16052 case v8::kExternalInt8Array: |
| 16074 case v8::kExternalUnsignedByteArray: | 16053 case v8::kExternalUint8Array: |
| 16075 case v8::kExternalPixelArray: | 16054 case v8::kExternalUint8ClampedArray: |
| 16076 return 1; | 16055 return 1; |
| 16077 break; | 16056 break; |
| 16078 case v8::kExternalShortArray: | 16057 case v8::kExternalInt16Array: |
| 16079 case v8::kExternalUnsignedShortArray: | 16058 case v8::kExternalUint16Array: |
| 16080 return 2; | 16059 return 2; |
| 16081 break; | 16060 break; |
| 16082 case v8::kExternalIntArray: | 16061 case v8::kExternalInt32Array: |
| 16083 case v8::kExternalUnsignedIntArray: | 16062 case v8::kExternalUint32Array: |
| 16084 case v8::kExternalFloatArray: | 16063 case v8::kExternalFloat32Array: |
| 16085 return 4; | 16064 return 4; |
| 16086 break; | 16065 break; |
| 16087 case v8::kExternalDoubleArray: | 16066 case v8::kExternalFloat64Array: |
| 16088 return 8; | 16067 return 8; |
| 16089 break; | 16068 break; |
| 16090 default: | 16069 default: |
| 16091 UNREACHABLE(); | 16070 UNREACHABLE(); |
| 16092 return -1; | 16071 return -1; |
| 16093 } | 16072 } |
| 16094 UNREACHABLE(); | 16073 UNREACHABLE(); |
| 16095 return -1; | 16074 return -1; |
| 16096 } | 16075 } |
| 16097 | 16076 |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16239 element_count); | 16218 element_count); |
| 16240 result = CompileRun(test_buf.start()); | 16219 result = CompileRun(test_buf.start()); |
| 16241 CHECK_EQ(false, result->BooleanValue()); | 16220 CHECK_EQ(false, result->BooleanValue()); |
| 16242 | 16221 |
| 16243 // Check other boundary conditions, values and operations. | 16222 // Check other boundary conditions, values and operations. |
| 16244 result = CompileRun("for (var i = 0; i < 8; i++) {" | 16223 result = CompileRun("for (var i = 0; i < 8; i++) {" |
| 16245 " ext_array[7] = undefined;" | 16224 " ext_array[7] = undefined;" |
| 16246 "}" | 16225 "}" |
| 16247 "ext_array[7];"); | 16226 "ext_array[7];"); |
| 16248 CHECK_EQ(0, result->Int32Value()); | 16227 CHECK_EQ(0, result->Int32Value()); |
| 16249 if (array_type == v8::kExternalDoubleArray || | 16228 if (array_type == v8::kExternalFloat64Array || |
| 16250 array_type == v8::kExternalFloatArray) { | 16229 array_type == v8::kExternalFloat32Array) { |
| 16251 CHECK_EQ(static_cast<int>(i::OS::nan_value()), | 16230 CHECK_EQ(static_cast<int>(i::OS::nan_value()), |
| 16252 static_cast<int>( | 16231 static_cast<int>( |
| 16253 jsobj->GetElement(isolate, 7)->ToObjectChecked()->Number())); | 16232 jsobj->GetElement(isolate, 7)->ToObjectChecked()->Number())); |
| 16254 } else { | 16233 } else { |
| 16255 CheckElementValue(isolate, 0, jsobj, 7); | 16234 CheckElementValue(isolate, 0, jsobj, 7); |
| 16256 } | 16235 } |
| 16257 | 16236 |
| 16258 result = CompileRun("for (var i = 0; i < 8; i++) {" | 16237 result = CompileRun("for (var i = 0; i < 8; i++) {" |
| 16259 " ext_array[6] = '2.3';" | 16238 " ext_array[6] = '2.3';" |
| 16260 "}" | 16239 "}" |
| 16261 "ext_array[6];"); | 16240 "ext_array[6];"); |
| 16262 CHECK_EQ(2, result->Int32Value()); | 16241 CHECK_EQ(2, result->Int32Value()); |
| 16263 CHECK_EQ(2, | 16242 CHECK_EQ(2, |
| 16264 static_cast<int>( | 16243 static_cast<int>( |
| 16265 jsobj->GetElement(isolate, 6)->ToObjectChecked()->Number())); | 16244 jsobj->GetElement(isolate, 6)->ToObjectChecked()->Number())); |
| 16266 | 16245 |
| 16267 if (array_type != v8::kExternalFloatArray && | 16246 if (array_type != v8::kExternalFloat32Array && |
| 16268 array_type != v8::kExternalDoubleArray) { | 16247 array_type != v8::kExternalFloat64Array) { |
| 16269 // Though the specification doesn't state it, be explicit about | 16248 // Though the specification doesn't state it, be explicit about |
| 16270 // converting NaNs and +/-Infinity to zero. | 16249 // converting NaNs and +/-Infinity to zero. |
| 16271 result = CompileRun("for (var i = 0; i < 8; i++) {" | 16250 result = CompileRun("for (var i = 0; i < 8; i++) {" |
| 16272 " ext_array[i] = 5;" | 16251 " ext_array[i] = 5;" |
| 16273 "}" | 16252 "}" |
| 16274 "for (var i = 0; i < 8; i++) {" | 16253 "for (var i = 0; i < 8; i++) {" |
| 16275 " ext_array[i] = NaN;" | 16254 " ext_array[i] = NaN;" |
| 16276 "}" | 16255 "}" |
| 16277 "ext_array[5];"); | 16256 "ext_array[5];"); |
| 16278 CHECK_EQ(0, result->Int32Value()); | 16257 CHECK_EQ(0, result->Int32Value()); |
| 16279 CheckElementValue(isolate, 0, jsobj, 5); | 16258 CheckElementValue(isolate, 0, jsobj, 5); |
| 16280 | 16259 |
| 16281 result = CompileRun("for (var i = 0; i < 8; i++) {" | 16260 result = CompileRun("for (var i = 0; i < 8; i++) {" |
| 16282 " ext_array[i] = 5;" | 16261 " ext_array[i] = 5;" |
| 16283 "}" | 16262 "}" |
| 16284 "for (var i = 0; i < 8; i++) {" | 16263 "for (var i = 0; i < 8; i++) {" |
| 16285 " ext_array[i] = Infinity;" | 16264 " ext_array[i] = Infinity;" |
| 16286 "}" | 16265 "}" |
| 16287 "ext_array[5];"); | 16266 "ext_array[5];"); |
| 16288 int expected_value = | 16267 int expected_value = |
| 16289 (array_type == v8::kExternalPixelArray) ? 255 : 0; | 16268 (array_type == v8::kExternalUint8ClampedArray) ? 255 : 0; |
| 16290 CHECK_EQ(expected_value, result->Int32Value()); | 16269 CHECK_EQ(expected_value, result->Int32Value()); |
| 16291 CheckElementValue(isolate, expected_value, jsobj, 5); | 16270 CheckElementValue(isolate, expected_value, jsobj, 5); |
| 16292 | 16271 |
| 16293 result = CompileRun("for (var i = 0; i < 8; i++) {" | 16272 result = CompileRun("for (var i = 0; i < 8; i++) {" |
| 16294 " ext_array[i] = 5;" | 16273 " ext_array[i] = 5;" |
| 16295 "}" | 16274 "}" |
| 16296 "for (var i = 0; i < 8; i++) {" | 16275 "for (var i = 0; i < 8; i++) {" |
| 16297 " ext_array[i] = -Infinity;" | 16276 " ext_array[i] = -Infinity;" |
| 16298 "}" | 16277 "}" |
| 16299 "ext_array[5];"); | 16278 "ext_array[5];"); |
| 16300 CHECK_EQ(0, result->Int32Value()); | 16279 CHECK_EQ(0, result->Int32Value()); |
| 16301 CheckElementValue(isolate, 0, jsobj, 5); | 16280 CheckElementValue(isolate, 0, jsobj, 5); |
| 16302 | 16281 |
| 16303 // Check truncation behavior of integral arrays. | 16282 // Check truncation behavior of integral arrays. |
| 16304 const char* unsigned_data = | 16283 const char* unsigned_data = |
| 16305 "var source_data = [0.6, 10.6];" | 16284 "var source_data = [0.6, 10.6];" |
| 16306 "var expected_results = [0, 10];"; | 16285 "var expected_results = [0, 10];"; |
| 16307 const char* signed_data = | 16286 const char* signed_data = |
| 16308 "var source_data = [0.6, 10.6, -0.6, -10.6];" | 16287 "var source_data = [0.6, 10.6, -0.6, -10.6];" |
| 16309 "var expected_results = [0, 10, 0, -10];"; | 16288 "var expected_results = [0, 10, 0, -10];"; |
| 16310 const char* pixel_data = | 16289 const char* pixel_data = |
| 16311 "var source_data = [0.6, 10.6];" | 16290 "var source_data = [0.6, 10.6];" |
| 16312 "var expected_results = [1, 11];"; | 16291 "var expected_results = [1, 11];"; |
| 16313 bool is_unsigned = | 16292 bool is_unsigned = |
| 16314 (array_type == v8::kExternalUnsignedByteArray || | 16293 (array_type == v8::kExternalUint8Array || |
| 16315 array_type == v8::kExternalUnsignedShortArray || | 16294 array_type == v8::kExternalUint16Array || |
| 16316 array_type == v8::kExternalUnsignedIntArray); | 16295 array_type == v8::kExternalUint32Array); |
| 16317 bool is_pixel_data = array_type == v8::kExternalPixelArray; | 16296 bool is_pixel_data = array_type == v8::kExternalUint8ClampedArray; |
| 16318 | 16297 |
| 16319 i::OS::SNPrintF(test_buf, | 16298 i::OS::SNPrintF(test_buf, |
| 16320 "%s" | 16299 "%s" |
| 16321 "var all_passed = true;" | 16300 "var all_passed = true;" |
| 16322 "for (var i = 0; i < source_data.length; i++) {" | 16301 "for (var i = 0; i < source_data.length; i++) {" |
| 16323 " for (var j = 0; j < 8; j++) {" | 16302 " for (var j = 0; j < 8; j++) {" |
| 16324 " ext_array[j] = source_data[i];" | 16303 " ext_array[j] = source_data[i];" |
| 16325 " }" | 16304 " }" |
| 16326 " all_passed = all_passed &&" | 16305 " all_passed = all_passed &&" |
| 16327 " (ext_array[5] == expected_results[i]);" | 16306 " (ext_array[5] == expected_results[i]);" |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16437 | 16416 |
| 16438 ObjectWithExternalArrayTestHelper<FixedTypedArrayClass, ElementType>( | 16417 ObjectWithExternalArrayTestHelper<FixedTypedArrayClass, ElementType>( |
| 16439 context.local(), obj, kElementCount, array_type, | 16418 context.local(), obj, kElementCount, array_type, |
| 16440 static_cast<int64_t>(low), | 16419 static_cast<int64_t>(low), |
| 16441 static_cast<int64_t>(high)); | 16420 static_cast<int64_t>(high)); |
| 16442 } | 16421 } |
| 16443 | 16422 |
| 16444 | 16423 |
| 16445 THREADED_TEST(FixedUint8Array) { | 16424 THREADED_TEST(FixedUint8Array) { |
| 16446 FixedTypedArrayTestHelper<i::FixedUint8Array, i::UINT8_ELEMENTS, uint8_t>( | 16425 FixedTypedArrayTestHelper<i::FixedUint8Array, i::UINT8_ELEMENTS, uint8_t>( |
| 16447 v8::kExternalUnsignedByteArray, | 16426 v8::kExternalUint8Array, |
| 16448 0x0, 0xFF); | 16427 0x0, 0xFF); |
| 16449 } | 16428 } |
| 16450 | 16429 |
| 16451 | 16430 |
| 16452 THREADED_TEST(FixedUint8ClampedArray) { | 16431 THREADED_TEST(FixedUint8ClampedArray) { |
| 16453 FixedTypedArrayTestHelper<i::FixedUint8ClampedArray, | 16432 FixedTypedArrayTestHelper<i::FixedUint8ClampedArray, |
| 16454 i::UINT8_CLAMPED_ELEMENTS, uint8_t>( | 16433 i::UINT8_CLAMPED_ELEMENTS, uint8_t>( |
| 16455 v8::kExternalPixelArray, | 16434 v8::kExternalUint8ClampedArray, |
| 16456 0x0, 0xFF); | 16435 0x0, 0xFF); |
| 16457 } | 16436 } |
| 16458 | 16437 |
| 16459 | 16438 |
| 16460 THREADED_TEST(FixedInt8Array) { | 16439 THREADED_TEST(FixedInt8Array) { |
| 16461 FixedTypedArrayTestHelper<i::FixedInt8Array, i::INT8_ELEMENTS, int8_t>( | 16440 FixedTypedArrayTestHelper<i::FixedInt8Array, i::INT8_ELEMENTS, int8_t>( |
| 16462 v8::kExternalByteArray, | 16441 v8::kExternalInt8Array, |
| 16463 -0x80, 0x7F); | 16442 -0x80, 0x7F); |
| 16464 } | 16443 } |
| 16465 | 16444 |
| 16466 | 16445 |
| 16467 THREADED_TEST(FixedUint16Array) { | 16446 THREADED_TEST(FixedUint16Array) { |
| 16468 FixedTypedArrayTestHelper<i::FixedUint16Array, i::UINT16_ELEMENTS, uint16_t>( | 16447 FixedTypedArrayTestHelper<i::FixedUint16Array, i::UINT16_ELEMENTS, uint16_t>( |
| 16469 v8::kExternalUnsignedShortArray, | 16448 v8::kExternalUint16Array, |
| 16470 0x0, 0xFFFF); | 16449 0x0, 0xFFFF); |
| 16471 } | 16450 } |
| 16472 | 16451 |
| 16473 | 16452 |
| 16474 THREADED_TEST(FixedInt16Array) { | 16453 THREADED_TEST(FixedInt16Array) { |
| 16475 FixedTypedArrayTestHelper<i::FixedInt16Array, i::INT16_ELEMENTS, int16_t>( | 16454 FixedTypedArrayTestHelper<i::FixedInt16Array, i::INT16_ELEMENTS, int16_t>( |
| 16476 v8::kExternalShortArray, | 16455 v8::kExternalInt16Array, |
| 16477 -0x8000, 0x7FFF); | 16456 -0x8000, 0x7FFF); |
| 16478 } | 16457 } |
| 16479 | 16458 |
| 16480 | 16459 |
| 16481 THREADED_TEST(FixedUint32Array) { | 16460 THREADED_TEST(FixedUint32Array) { |
| 16482 FixedTypedArrayTestHelper<i::FixedUint32Array, i::UINT32_ELEMENTS, uint32_t>( | 16461 FixedTypedArrayTestHelper<i::FixedUint32Array, i::UINT32_ELEMENTS, uint32_t>( |
| 16483 v8::kExternalUnsignedIntArray, | 16462 v8::kExternalUint32Array, |
| 16484 0x0, UINT_MAX); | 16463 0x0, UINT_MAX); |
| 16485 } | 16464 } |
| 16486 | 16465 |
| 16487 | 16466 |
| 16488 THREADED_TEST(FixedInt32Array) { | 16467 THREADED_TEST(FixedInt32Array) { |
| 16489 FixedTypedArrayTestHelper<i::FixedInt32Array, i::INT32_ELEMENTS, int32_t>( | 16468 FixedTypedArrayTestHelper<i::FixedInt32Array, i::INT32_ELEMENTS, int32_t>( |
| 16490 v8::kExternalIntArray, | 16469 v8::kExternalInt32Array, |
| 16491 INT_MIN, INT_MAX); | 16470 INT_MIN, INT_MAX); |
| 16492 } | 16471 } |
| 16493 | 16472 |
| 16494 | 16473 |
| 16495 THREADED_TEST(FixedFloat32Array) { | 16474 THREADED_TEST(FixedFloat32Array) { |
| 16496 FixedTypedArrayTestHelper<i::FixedFloat32Array, i::FLOAT32_ELEMENTS, float>( | 16475 FixedTypedArrayTestHelper<i::FixedFloat32Array, i::FLOAT32_ELEMENTS, float>( |
| 16497 v8::kExternalFloatArray, | 16476 v8::kExternalFloat32Array, |
| 16498 -500, 500); | 16477 -500, 500); |
| 16499 } | 16478 } |
| 16500 | 16479 |
| 16501 | 16480 |
| 16502 THREADED_TEST(FixedFloat64Array) { | 16481 THREADED_TEST(FixedFloat64Array) { |
| 16503 FixedTypedArrayTestHelper<i::FixedFloat64Array, i::FLOAT64_ELEMENTS, float>( | 16482 FixedTypedArrayTestHelper<i::FixedFloat64Array, i::FLOAT64_ELEMENTS, float>( |
| 16504 v8::kExternalDoubleArray, | 16483 v8::kExternalFloat64Array, |
| 16505 -500, 500); | 16484 -500, 500); |
| 16506 } | 16485 } |
| 16507 | 16486 |
| 16508 | 16487 |
| 16509 template <class ExternalArrayClass, class ElementType> | 16488 template <class ExternalArrayClass, class ElementType> |
| 16510 static void ExternalArrayTestHelper(v8::ExternalArrayType array_type, | 16489 static void ExternalArrayTestHelper(v8::ExternalArrayType array_type, |
| 16511 int64_t low, | 16490 int64_t low, |
| 16512 int64_t high) { | 16491 int64_t high) { |
| 16513 LocalContext context; | 16492 LocalContext context; |
| 16514 i::Isolate* isolate = CcTest::i_isolate(); | 16493 i::Isolate* isolate = CcTest::i_isolate(); |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16716 v8::Int32::New(context->GetIsolate(), 256)); | 16695 v8::Int32::New(context->GetIsolate(), 256)); |
| 16717 context->Global()->Set(v8_str("ext_array"), obj2); | 16696 context->Global()->Set(v8_str("ext_array"), obj2); |
| 16718 result = CompileRun("ext_array[''] = function() {return 1503;};" | 16697 result = CompileRun("ext_array[''] = function() {return 1503;};" |
| 16719 "ext_array['']();"); | 16698 "ext_array['']();"); |
| 16720 } | 16699 } |
| 16721 | 16700 |
| 16722 free(array_data); | 16701 free(array_data); |
| 16723 } | 16702 } |
| 16724 | 16703 |
| 16725 | 16704 |
| 16726 THREADED_TEST(ExternalByteArray) { | 16705 THREADED_TEST(ExternalInt8Array) { |
| 16727 ExternalArrayTestHelper<i::ExternalByteArray, int8_t>( | 16706 ExternalArrayTestHelper<i::ExternalInt8Array, int8_t>( |
| 16728 v8::kExternalByteArray, | 16707 v8::kExternalInt8Array, |
| 16729 -128, | 16708 -128, |
| 16730 127); | 16709 127); |
| 16731 } | 16710 } |
| 16732 | 16711 |
| 16733 | 16712 |
| 16734 THREADED_TEST(ExternalUnsignedByteArray) { | 16713 THREADED_TEST(ExternalUint8Array) { |
| 16735 ExternalArrayTestHelper<i::ExternalUnsignedByteArray, uint8_t>( | 16714 ExternalArrayTestHelper<i::ExternalUint8Array, uint8_t>( |
| 16736 v8::kExternalUnsignedByteArray, | 16715 v8::kExternalUint8Array, |
| 16737 0, | 16716 0, |
| 16738 255); | 16717 255); |
| 16739 } | 16718 } |
| 16740 | 16719 |
| 16741 | 16720 |
| 16742 THREADED_TEST(ExternalPixelArray) { | 16721 THREADED_TEST(ExternalUint8ClampedArray) { |
| 16743 ExternalArrayTestHelper<i::ExternalPixelArray, uint8_t>( | 16722 ExternalArrayTestHelper<i::ExternalUint8ClampedArray, uint8_t>( |
| 16744 v8::kExternalPixelArray, | 16723 v8::kExternalUint8ClampedArray, |
| 16745 0, | 16724 0, |
| 16746 255); | 16725 255); |
| 16747 } | 16726 } |
| 16748 | 16727 |
| 16749 | 16728 |
| 16750 THREADED_TEST(ExternalShortArray) { | 16729 THREADED_TEST(ExternalInt16Array) { |
| 16751 ExternalArrayTestHelper<i::ExternalShortArray, int16_t>( | 16730 ExternalArrayTestHelper<i::ExternalInt16Array, int16_t>( |
| 16752 v8::kExternalShortArray, | 16731 v8::kExternalInt16Array, |
| 16753 -32768, | 16732 -32768, |
| 16754 32767); | 16733 32767); |
| 16755 } | 16734 } |
| 16756 | 16735 |
| 16757 | 16736 |
| 16758 THREADED_TEST(ExternalUnsignedShortArray) { | 16737 THREADED_TEST(ExternalUint16Array) { |
| 16759 ExternalArrayTestHelper<i::ExternalUnsignedShortArray, uint16_t>( | 16738 ExternalArrayTestHelper<i::ExternalUint16Array, uint16_t>( |
| 16760 v8::kExternalUnsignedShortArray, | 16739 v8::kExternalUint16Array, |
| 16761 0, | 16740 0, |
| 16762 65535); | 16741 65535); |
| 16763 } | 16742 } |
| 16764 | 16743 |
| 16765 | 16744 |
| 16766 THREADED_TEST(ExternalIntArray) { | 16745 THREADED_TEST(ExternalInt32Array) { |
| 16767 ExternalArrayTestHelper<i::ExternalIntArray, int32_t>( | 16746 ExternalArrayTestHelper<i::ExternalInt32Array, int32_t>( |
| 16768 v8::kExternalIntArray, | 16747 v8::kExternalInt32Array, |
| 16769 INT_MIN, // -2147483648 | 16748 INT_MIN, // -2147483648 |
| 16770 INT_MAX); // 2147483647 | 16749 INT_MAX); // 2147483647 |
| 16771 } | 16750 } |
| 16772 | 16751 |
| 16773 | 16752 |
| 16774 THREADED_TEST(ExternalUnsignedIntArray) { | 16753 THREADED_TEST(ExternalUint32Array) { |
| 16775 ExternalArrayTestHelper<i::ExternalUnsignedIntArray, uint32_t>( | 16754 ExternalArrayTestHelper<i::ExternalUint32Array, uint32_t>( |
| 16776 v8::kExternalUnsignedIntArray, | 16755 v8::kExternalUint32Array, |
| 16777 0, | 16756 0, |
| 16778 UINT_MAX); // 4294967295 | 16757 UINT_MAX); // 4294967295 |
| 16779 } | 16758 } |
| 16780 | 16759 |
| 16781 | 16760 |
| 16782 THREADED_TEST(ExternalFloatArray) { | 16761 THREADED_TEST(ExternalFloat32Array) { |
| 16783 ExternalArrayTestHelper<i::ExternalFloatArray, float>( | 16762 ExternalArrayTestHelper<i::ExternalFloat32Array, float>( |
| 16784 v8::kExternalFloatArray, | 16763 v8::kExternalFloat32Array, |
| 16785 -500, | 16764 -500, |
| 16786 500); | 16765 500); |
| 16787 } | 16766 } |
| 16788 | 16767 |
| 16789 | 16768 |
| 16790 THREADED_TEST(ExternalDoubleArray) { | 16769 THREADED_TEST(ExternalFloat64Array) { |
| 16791 ExternalArrayTestHelper<i::ExternalDoubleArray, double>( | 16770 ExternalArrayTestHelper<i::ExternalFloat64Array, double>( |
| 16792 v8::kExternalDoubleArray, | 16771 v8::kExternalFloat64Array, |
| 16793 -500, | 16772 -500, |
| 16794 500); | 16773 500); |
| 16795 } | 16774 } |
| 16796 | 16775 |
| 16797 | 16776 |
| 16798 THREADED_TEST(ExternalArrays) { | 16777 THREADED_TEST(ExternalArrays) { |
| 16799 TestExternalByteArray(); | 16778 TestExternalInt8Array(); |
| 16800 TestExternalUnsignedByteArray(); | 16779 TestExternalUint8Array(); |
| 16801 TestExternalShortArray(); | 16780 TestExternalInt16Array(); |
| 16802 TestExternalUnsignedShortArray(); | 16781 TestExternalUint16Array(); |
| 16803 TestExternalIntArray(); | 16782 TestExternalInt32Array(); |
| 16804 TestExternalUnsignedIntArray(); | 16783 TestExternalUint32Array(); |
| 16805 TestExternalFloatArray(); | 16784 TestExternalFloat32Array(); |
| 16806 } | 16785 } |
| 16807 | 16786 |
| 16808 | 16787 |
| 16809 void ExternalArrayInfoTestHelper(v8::ExternalArrayType array_type) { | 16788 void ExternalArrayInfoTestHelper(v8::ExternalArrayType array_type) { |
| 16810 LocalContext context; | 16789 LocalContext context; |
| 16811 v8::HandleScope scope(context->GetIsolate()); | 16790 v8::HandleScope scope(context->GetIsolate()); |
| 16812 for (int size = 0; size < 100; size += 10) { | 16791 for (int size = 0; size < 100; size += 10) { |
| 16813 int element_size = ExternalArrayElementSize(array_type); | 16792 int element_size = ExternalArrayElementSize(array_type); |
| 16814 void* external_data = malloc(size * element_size); | 16793 void* external_data = malloc(size * element_size); |
| 16815 v8::Handle<v8::Object> obj = v8::Object::New(context->GetIsolate()); | 16794 v8::Handle<v8::Object> obj = v8::Object::New(context->GetIsolate()); |
| 16816 obj->SetIndexedPropertiesToExternalArrayData( | 16795 obj->SetIndexedPropertiesToExternalArrayData( |
| 16817 external_data, array_type, size); | 16796 external_data, array_type, size); |
| 16818 CHECK(obj->HasIndexedPropertiesInExternalArrayData()); | 16797 CHECK(obj->HasIndexedPropertiesInExternalArrayData()); |
| 16819 CHECK_EQ(external_data, obj->GetIndexedPropertiesExternalArrayData()); | 16798 CHECK_EQ(external_data, obj->GetIndexedPropertiesExternalArrayData()); |
| 16820 CHECK_EQ(array_type, obj->GetIndexedPropertiesExternalArrayDataType()); | 16799 CHECK_EQ(array_type, obj->GetIndexedPropertiesExternalArrayDataType()); |
| 16821 CHECK_EQ(size, obj->GetIndexedPropertiesExternalArrayDataLength()); | 16800 CHECK_EQ(size, obj->GetIndexedPropertiesExternalArrayDataLength()); |
| 16822 free(external_data); | 16801 free(external_data); |
| 16823 } | 16802 } |
| 16824 } | 16803 } |
| 16825 | 16804 |
| 16826 | 16805 |
| 16827 THREADED_TEST(ExternalArrayInfo) { | 16806 THREADED_TEST(ExternalArrayInfo) { |
| 16828 ExternalArrayInfoTestHelper(v8::kExternalByteArray); | 16807 ExternalArrayInfoTestHelper(v8::kExternalInt8Array); |
| 16829 ExternalArrayInfoTestHelper(v8::kExternalUnsignedByteArray); | 16808 ExternalArrayInfoTestHelper(v8::kExternalUint8Array); |
| 16830 ExternalArrayInfoTestHelper(v8::kExternalShortArray); | 16809 ExternalArrayInfoTestHelper(v8::kExternalInt16Array); |
| 16831 ExternalArrayInfoTestHelper(v8::kExternalUnsignedShortArray); | 16810 ExternalArrayInfoTestHelper(v8::kExternalUint16Array); |
| 16832 ExternalArrayInfoTestHelper(v8::kExternalIntArray); | 16811 ExternalArrayInfoTestHelper(v8::kExternalInt32Array); |
| 16833 ExternalArrayInfoTestHelper(v8::kExternalUnsignedIntArray); | 16812 ExternalArrayInfoTestHelper(v8::kExternalUint32Array); |
| 16834 ExternalArrayInfoTestHelper(v8::kExternalFloatArray); | 16813 ExternalArrayInfoTestHelper(v8::kExternalFloat32Array); |
| 16835 ExternalArrayInfoTestHelper(v8::kExternalDoubleArray); | 16814 ExternalArrayInfoTestHelper(v8::kExternalFloat64Array); |
| 16836 ExternalArrayInfoTestHelper(v8::kExternalPixelArray); | 16815 ExternalArrayInfoTestHelper(v8::kExternalUint8ClampedArray); |
| 16837 } | 16816 } |
| 16838 | 16817 |
| 16839 | 16818 |
| 16840 void ExtArrayLimitsHelper(v8::Isolate* isolate, | 16819 void ExtArrayLimitsHelper(v8::Isolate* isolate, |
| 16841 v8::ExternalArrayType array_type, | 16820 v8::ExternalArrayType array_type, |
| 16842 int size) { | 16821 int size) { |
| 16843 v8::Handle<v8::Object> obj = v8::Object::New(isolate); | 16822 v8::Handle<v8::Object> obj = v8::Object::New(isolate); |
| 16844 v8::V8::SetFatalErrorHandler(StoringErrorCallback); | 16823 v8::V8::SetFatalErrorHandler(StoringErrorCallback); |
| 16845 last_location = last_message = NULL; | 16824 last_location = last_message = NULL; |
| 16846 obj->SetIndexedPropertiesToExternalArrayData(NULL, array_type, size); | 16825 obj->SetIndexedPropertiesToExternalArrayData(NULL, array_type, size); |
| 16847 CHECK(!obj->HasIndexedPropertiesInExternalArrayData()); | 16826 CHECK(!obj->HasIndexedPropertiesInExternalArrayData()); |
| 16848 CHECK_NE(NULL, last_location); | 16827 CHECK_NE(NULL, last_location); |
| 16849 CHECK_NE(NULL, last_message); | 16828 CHECK_NE(NULL, last_message); |
| 16850 } | 16829 } |
| 16851 | 16830 |
| 16852 | 16831 |
| 16853 TEST(ExternalArrayLimits) { | 16832 TEST(ExternalArrayLimits) { |
| 16854 LocalContext context; | 16833 LocalContext context; |
| 16855 v8::Isolate* isolate = context->GetIsolate(); | 16834 v8::Isolate* isolate = context->GetIsolate(); |
| 16856 v8::HandleScope scope(isolate); | 16835 v8::HandleScope scope(isolate); |
| 16857 ExtArrayLimitsHelper(isolate, v8::kExternalByteArray, 0x40000000); | 16836 ExtArrayLimitsHelper(isolate, v8::kExternalInt8Array, 0x40000000); |
| 16858 ExtArrayLimitsHelper(isolate, v8::kExternalByteArray, 0xffffffff); | 16837 ExtArrayLimitsHelper(isolate, v8::kExternalInt8Array, 0xffffffff); |
| 16859 ExtArrayLimitsHelper(isolate, v8::kExternalUnsignedByteArray, 0x40000000); | 16838 ExtArrayLimitsHelper(isolate, v8::kExternalUint8Array, 0x40000000); |
| 16860 ExtArrayLimitsHelper(isolate, v8::kExternalUnsignedByteArray, 0xffffffff); | 16839 ExtArrayLimitsHelper(isolate, v8::kExternalUint8Array, 0xffffffff); |
| 16861 ExtArrayLimitsHelper(isolate, v8::kExternalShortArray, 0x40000000); | 16840 ExtArrayLimitsHelper(isolate, v8::kExternalInt16Array, 0x40000000); |
| 16862 ExtArrayLimitsHelper(isolate, v8::kExternalShortArray, 0xffffffff); | 16841 ExtArrayLimitsHelper(isolate, v8::kExternalInt16Array, 0xffffffff); |
| 16863 ExtArrayLimitsHelper(isolate, v8::kExternalUnsignedShortArray, 0x40000000); | 16842 ExtArrayLimitsHelper(isolate, v8::kExternalUint16Array, 0x40000000); |
| 16864 ExtArrayLimitsHelper(isolate, v8::kExternalUnsignedShortArray, 0xffffffff); | 16843 ExtArrayLimitsHelper(isolate, v8::kExternalUint16Array, 0xffffffff); |
| 16865 ExtArrayLimitsHelper(isolate, v8::kExternalIntArray, 0x40000000); | 16844 ExtArrayLimitsHelper(isolate, v8::kExternalInt32Array, 0x40000000); |
| 16866 ExtArrayLimitsHelper(isolate, v8::kExternalIntArray, 0xffffffff); | 16845 ExtArrayLimitsHelper(isolate, v8::kExternalInt32Array, 0xffffffff); |
| 16867 ExtArrayLimitsHelper(isolate, v8::kExternalUnsignedIntArray, 0x40000000); | 16846 ExtArrayLimitsHelper(isolate, v8::kExternalUint32Array, 0x40000000); |
| 16868 ExtArrayLimitsHelper(isolate, v8::kExternalUnsignedIntArray, 0xffffffff); | 16847 ExtArrayLimitsHelper(isolate, v8::kExternalUint32Array, 0xffffffff); |
| 16869 ExtArrayLimitsHelper(isolate, v8::kExternalFloatArray, 0x40000000); | 16848 ExtArrayLimitsHelper(isolate, v8::kExternalFloat32Array, 0x40000000); |
| 16870 ExtArrayLimitsHelper(isolate, v8::kExternalFloatArray, 0xffffffff); | 16849 ExtArrayLimitsHelper(isolate, v8::kExternalFloat32Array, 0xffffffff); |
| 16871 ExtArrayLimitsHelper(isolate, v8::kExternalDoubleArray, 0x40000000); | 16850 ExtArrayLimitsHelper(isolate, v8::kExternalFloat64Array, 0x40000000); |
| 16872 ExtArrayLimitsHelper(isolate, v8::kExternalDoubleArray, 0xffffffff); | 16851 ExtArrayLimitsHelper(isolate, v8::kExternalFloat64Array, 0xffffffff); |
| 16873 ExtArrayLimitsHelper(isolate, v8::kExternalPixelArray, 0x40000000); | 16852 ExtArrayLimitsHelper(isolate, v8::kExternalUint8ClampedArray, 0x40000000); |
| 16874 ExtArrayLimitsHelper(isolate, v8::kExternalPixelArray, 0xffffffff); | 16853 ExtArrayLimitsHelper(isolate, v8::kExternalUint8ClampedArray, 0xffffffff); |
| 16875 } | 16854 } |
| 16876 | 16855 |
| 16877 | 16856 |
| 16878 template <typename ElementType, typename TypedArray, | 16857 template <typename ElementType, typename TypedArray, |
| 16879 class ExternalArrayClass> | 16858 class ExternalArrayClass> |
| 16880 void TypedArrayTestHelper(v8::ExternalArrayType array_type, | 16859 void TypedArrayTestHelper(v8::ExternalArrayType array_type, |
| 16881 int64_t low, int64_t high) { | 16860 int64_t low, int64_t high) { |
| 16882 const int kElementCount = 50; | 16861 const int kElementCount = 50; |
| 16883 | 16862 |
| 16884 i::ScopedVector<ElementType> backing_store(kElementCount+2); | 16863 i::ScopedVector<ElementType> backing_store(kElementCount+2); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 16903 for (int i = 0; i < kElementCount; i++) { | 16882 for (int i = 0; i < kElementCount; i++) { |
| 16904 data[i] = static_cast<ElementType>(i); | 16883 data[i] = static_cast<ElementType>(i); |
| 16905 } | 16884 } |
| 16906 | 16885 |
| 16907 ObjectWithExternalArrayTestHelper<ExternalArrayClass, ElementType>( | 16886 ObjectWithExternalArrayTestHelper<ExternalArrayClass, ElementType>( |
| 16908 env.local(), ta, kElementCount, array_type, low, high); | 16887 env.local(), ta, kElementCount, array_type, low, high); |
| 16909 } | 16888 } |
| 16910 | 16889 |
| 16911 | 16890 |
| 16912 THREADED_TEST(Uint8Array) { | 16891 THREADED_TEST(Uint8Array) { |
| 16913 TypedArrayTestHelper<uint8_t, v8::Uint8Array, i::ExternalUnsignedByteArray>( | 16892 TypedArrayTestHelper<uint8_t, v8::Uint8Array, i::ExternalUint8Array>( |
| 16914 v8::kExternalUnsignedByteArray, 0, 0xFF); | 16893 v8::kExternalUint8Array, 0, 0xFF); |
| 16915 } | 16894 } |
| 16916 | 16895 |
| 16917 | 16896 |
| 16918 THREADED_TEST(Int8Array) { | 16897 THREADED_TEST(Int8Array) { |
| 16919 TypedArrayTestHelper<int8_t, v8::Int8Array, i::ExternalByteArray>( | 16898 TypedArrayTestHelper<int8_t, v8::Int8Array, i::ExternalInt8Array>( |
| 16920 v8::kExternalByteArray, -0x80, 0x7F); | 16899 v8::kExternalInt8Array, -0x80, 0x7F); |
| 16921 } | 16900 } |
| 16922 | 16901 |
| 16923 | 16902 |
| 16924 THREADED_TEST(Uint16Array) { | 16903 THREADED_TEST(Uint16Array) { |
| 16925 TypedArrayTestHelper<uint16_t, | 16904 TypedArrayTestHelper<uint16_t, |
| 16926 v8::Uint16Array, | 16905 v8::Uint16Array, |
| 16927 i::ExternalUnsignedShortArray>( | 16906 i::ExternalUint16Array>( |
| 16928 v8::kExternalUnsignedShortArray, 0, 0xFFFF); | 16907 v8::kExternalUint16Array, 0, 0xFFFF); |
| 16929 } | 16908 } |
| 16930 | 16909 |
| 16931 | 16910 |
| 16932 THREADED_TEST(Int16Array) { | 16911 THREADED_TEST(Int16Array) { |
| 16933 TypedArrayTestHelper<int16_t, v8::Int16Array, i::ExternalShortArray>( | 16912 TypedArrayTestHelper<int16_t, v8::Int16Array, i::ExternalInt16Array>( |
| 16934 v8::kExternalShortArray, -0x8000, 0x7FFF); | 16913 v8::kExternalInt16Array, -0x8000, 0x7FFF); |
| 16935 } | 16914 } |
| 16936 | 16915 |
| 16937 | 16916 |
| 16938 THREADED_TEST(Uint32Array) { | 16917 THREADED_TEST(Uint32Array) { |
| 16939 TypedArrayTestHelper<uint32_t, v8::Uint32Array, i::ExternalUnsignedIntArray>( | 16918 TypedArrayTestHelper<uint32_t, v8::Uint32Array, i::ExternalUint32Array>( |
| 16940 v8::kExternalUnsignedIntArray, 0, UINT_MAX); | 16919 v8::kExternalUint32Array, 0, UINT_MAX); |
| 16941 } | 16920 } |
| 16942 | 16921 |
| 16943 | 16922 |
| 16944 THREADED_TEST(Int32Array) { | 16923 THREADED_TEST(Int32Array) { |
| 16945 TypedArrayTestHelper<int32_t, v8::Int32Array, i::ExternalIntArray>( | 16924 TypedArrayTestHelper<int32_t, v8::Int32Array, i::ExternalInt32Array>( |
| 16946 v8::kExternalIntArray, INT_MIN, INT_MAX); | 16925 v8::kExternalInt32Array, INT_MIN, INT_MAX); |
| 16947 } | 16926 } |
| 16948 | 16927 |
| 16949 | 16928 |
| 16950 THREADED_TEST(Float32Array) { | 16929 THREADED_TEST(Float32Array) { |
| 16951 TypedArrayTestHelper<float, v8::Float32Array, i::ExternalFloatArray>( | 16930 TypedArrayTestHelper<float, v8::Float32Array, i::ExternalFloat32Array>( |
| 16952 v8::kExternalFloatArray, -500, 500); | 16931 v8::kExternalFloat32Array, -500, 500); |
| 16953 } | 16932 } |
| 16954 | 16933 |
| 16955 | 16934 |
| 16956 THREADED_TEST(Float64Array) { | 16935 THREADED_TEST(Float64Array) { |
| 16957 TypedArrayTestHelper<double, v8::Float64Array, i::ExternalDoubleArray>( | 16936 TypedArrayTestHelper<double, v8::Float64Array, i::ExternalFloat64Array>( |
| 16958 v8::kExternalDoubleArray, -500, 500); | 16937 v8::kExternalFloat64Array, -500, 500); |
| 16959 } | 16938 } |
| 16960 | 16939 |
| 16961 | 16940 |
| 16962 THREADED_TEST(Uint8ClampedArray) { | 16941 THREADED_TEST(Uint8ClampedArray) { |
| 16963 TypedArrayTestHelper<uint8_t, v8::Uint8ClampedArray, i::ExternalPixelArray>( | 16942 TypedArrayTestHelper<uint8_t, |
| 16964 v8::kExternalPixelArray, 0, 0xFF); | 16943 v8::Uint8ClampedArray, i::ExternalUint8ClampedArray>( |
| 16944 v8::kExternalUint8ClampedArray, 0, 0xFF); |
| 16965 } | 16945 } |
| 16966 | 16946 |
| 16967 | 16947 |
| 16968 THREADED_TEST(DataView) { | 16948 THREADED_TEST(DataView) { |
| 16969 const int kSize = 50; | 16949 const int kSize = 50; |
| 16970 | 16950 |
| 16971 i::ScopedVector<uint8_t> backing_store(kSize+2); | 16951 i::ScopedVector<uint8_t> backing_store(kSize+2); |
| 16972 | 16952 |
| 16973 LocalContext env; | 16953 LocalContext env; |
| 16974 v8::Isolate* isolate = env->GetIsolate(); | 16954 v8::Isolate* isolate = env->GetIsolate(); |
| (...skipping 558 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 17533 "outer()\n%s"; | 17513 "outer()\n%s"; |
| 17534 | 17514 |
| 17535 i::ScopedVector<char> code(1024); | 17515 i::ScopedVector<char> code(1024); |
| 17536 i::OS::SNPrintF(code, source, "//# sourceURL=source_url"); | 17516 i::OS::SNPrintF(code, source, "//# sourceURL=source_url"); |
| 17537 CHECK(CompileRunWithOrigin(code.start(), "url", 0, 0)->IsUndefined()); | 17517 CHECK(CompileRunWithOrigin(code.start(), "url", 0, 0)->IsUndefined()); |
| 17538 i::OS::SNPrintF(code, source, "//@ sourceURL=source_url"); | 17518 i::OS::SNPrintF(code, source, "//@ sourceURL=source_url"); |
| 17539 CHECK(CompileRunWithOrigin(code.start(), "url", 0, 0)->IsUndefined()); | 17519 CHECK(CompileRunWithOrigin(code.start(), "url", 0, 0)->IsUndefined()); |
| 17540 } | 17520 } |
| 17541 | 17521 |
| 17542 | 17522 |
| 17523 TEST(DynamicWithSourceURLInStackTraceString) { |
| 17524 LocalContext context; |
| 17525 v8::HandleScope scope(context->GetIsolate()); |
| 17526 |
| 17527 const char *source = |
| 17528 "function outer() {\n" |
| 17529 " function foo() {\n" |
| 17530 " FAIL.FAIL;\n" |
| 17531 " }\n" |
| 17532 " foo();\n" |
| 17533 "}\n" |
| 17534 "outer()\n%s"; |
| 17535 |
| 17536 i::ScopedVector<char> code(1024); |
| 17537 i::OS::SNPrintF(code, source, "//# sourceURL=source_url"); |
| 17538 v8::TryCatch try_catch; |
| 17539 CompileRunWithOrigin(code.start(), "", 0, 0); |
| 17540 CHECK(try_catch.HasCaught()); |
| 17541 v8::String::Utf8Value stack(try_catch.StackTrace()); |
| 17542 CHECK(strstr(*stack, "at foo (source_url:3:5)") != NULL); |
| 17543 } |
| 17544 |
| 17545 |
| 17543 static void CreateGarbageInOldSpace() { | 17546 static void CreateGarbageInOldSpace() { |
| 17544 i::Factory* factory = CcTest::i_isolate()->factory(); | 17547 i::Factory* factory = CcTest::i_isolate()->factory(); |
| 17545 v8::HandleScope scope(CcTest::isolate()); | 17548 v8::HandleScope scope(CcTest::isolate()); |
| 17546 i::AlwaysAllocateScope always_allocate; | 17549 i::AlwaysAllocateScope always_allocate; |
| 17547 for (int i = 0; i < 1000; i++) { | 17550 for (int i = 0; i < 1000; i++) { |
| 17548 factory->NewFixedArray(1000, i::TENURED); | 17551 factory->NewFixedArray(1000, i::TENURED); |
| 17549 } | 17552 } |
| 17550 } | 17553 } |
| 17551 | 17554 |
| 17552 | 17555 |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 17640 finished = v8::V8::IdleNotification(kShortIdlePauseInMs); | 17643 finished = v8::V8::IdleNotification(kShortIdlePauseInMs); |
| 17641 } | 17644 } |
| 17642 intptr_t final_size = CcTest::heap()->SizeOfObjects(); | 17645 intptr_t final_size = CcTest::heap()->SizeOfObjects(); |
| 17643 CHECK_LT(final_size, initial_size + 1); | 17646 CHECK_LT(final_size, initial_size + 1); |
| 17644 } | 17647 } |
| 17645 | 17648 |
| 17646 | 17649 |
| 17647 TEST(Regress2333) { | 17650 TEST(Regress2333) { |
| 17648 LocalContext env; | 17651 LocalContext env; |
| 17649 for (int i = 0; i < 3; i++) { | 17652 for (int i = 0; i < 3; i++) { |
| 17650 CcTest::heap()->PerformScavenge(); | 17653 CcTest::heap()->CollectGarbage(i::NEW_SPACE); |
| 17651 } | 17654 } |
| 17652 } | 17655 } |
| 17653 | 17656 |
| 17654 static uint32_t* stack_limit; | 17657 static uint32_t* stack_limit; |
| 17655 | 17658 |
| 17656 static void GetStackLimitCallback( | 17659 static void GetStackLimitCallback( |
| 17657 const v8::FunctionCallbackInfo<v8::Value>& args) { | 17660 const v8::FunctionCallbackInfo<v8::Value>& args) { |
| 17658 stack_limit = reinterpret_cast<uint32_t*>( | 17661 stack_limit = reinterpret_cast<uint32_t*>( |
| 17659 CcTest::i_isolate()->stack_guard()->real_climit()); | 17662 CcTest::i_isolate()->stack_guard()->real_climit()); |
| 17660 } | 17663 } |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 17769 CHECK(found_resource_[i]); | 17772 CHECK(found_resource_[i]); |
| 17770 } | 17773 } |
| 17771 } | 17774 } |
| 17772 | 17775 |
| 17773 private: | 17776 private: |
| 17774 v8::String::ExternalStringResource* resource_[4]; | 17777 v8::String::ExternalStringResource* resource_[4]; |
| 17775 bool found_resource_[4]; | 17778 bool found_resource_[4]; |
| 17776 }; | 17779 }; |
| 17777 | 17780 |
| 17778 | 17781 |
| 17782 TEST(ExternalizeOldSpaceTwoByteCons) { |
| 17783 LocalContext env; |
| 17784 v8::HandleScope scope(env->GetIsolate()); |
| 17785 v8::Local<v8::String> cons = |
| 17786 CompileRun("'Romeo Montague ' + 'Juliet Capulet'")->ToString(); |
| 17787 CHECK(v8::Utils::OpenHandle(*cons)->IsConsString()); |
| 17788 CcTest::heap()->CollectAllAvailableGarbage(); |
| 17789 CHECK(CcTest::heap()->old_pointer_space()->Contains( |
| 17790 *v8::Utils::OpenHandle(*cons))); |
| 17791 |
| 17792 TestResource* resource = new TestResource( |
| 17793 AsciiToTwoByteString("Romeo Montague Juliet Capulet")); |
| 17794 cons->MakeExternal(resource); |
| 17795 |
| 17796 CHECK(cons->IsExternal()); |
| 17797 CHECK_EQ(resource, cons->GetExternalStringResource()); |
| 17798 String::Encoding encoding; |
| 17799 CHECK_EQ(resource, cons->GetExternalStringResourceBase(&encoding)); |
| 17800 CHECK_EQ(String::TWO_BYTE_ENCODING, encoding); |
| 17801 } |
| 17802 |
| 17803 |
| 17804 TEST(ExternalizeOldSpaceOneByteCons) { |
| 17805 LocalContext env; |
| 17806 v8::HandleScope scope(env->GetIsolate()); |
| 17807 v8::Local<v8::String> cons = |
| 17808 CompileRun("'Romeo Montague ' + 'Juliet Capulet'")->ToString(); |
| 17809 CHECK(v8::Utils::OpenHandle(*cons)->IsConsString()); |
| 17810 CcTest::heap()->CollectAllAvailableGarbage(); |
| 17811 CHECK(CcTest::heap()->old_pointer_space()->Contains( |
| 17812 *v8::Utils::OpenHandle(*cons))); |
| 17813 |
| 17814 TestAsciiResource* resource = |
| 17815 new TestAsciiResource(i::StrDup("Romeo Montague Juliet Capulet")); |
| 17816 cons->MakeExternal(resource); |
| 17817 |
| 17818 CHECK(cons->IsExternalAscii()); |
| 17819 CHECK_EQ(resource, cons->GetExternalAsciiStringResource()); |
| 17820 String::Encoding encoding; |
| 17821 CHECK_EQ(resource, cons->GetExternalStringResourceBase(&encoding)); |
| 17822 CHECK_EQ(String::ONE_BYTE_ENCODING, encoding); |
| 17823 } |
| 17824 |
| 17825 |
| 17779 TEST(VisitExternalStrings) { | 17826 TEST(VisitExternalStrings) { |
| 17780 LocalContext env; | 17827 LocalContext env; |
| 17781 v8::HandleScope scope(env->GetIsolate()); | 17828 v8::HandleScope scope(env->GetIsolate()); |
| 17782 const char* string = "Some string"; | 17829 const char* string = "Some string"; |
| 17783 uint16_t* two_byte_string = AsciiToTwoByteString(string); | 17830 uint16_t* two_byte_string = AsciiToTwoByteString(string); |
| 17784 TestResource* resource[4]; | 17831 TestResource* resource[4]; |
| 17785 resource[0] = new TestResource(two_byte_string); | 17832 resource[0] = new TestResource(two_byte_string); |
| 17786 v8::Local<v8::String> string0 = | 17833 v8::Local<v8::String> string0 = |
| 17787 v8::String::NewExternal(env->GetIsolate(), resource[0]); | 17834 v8::String::NewExternal(env->GetIsolate(), resource[0]); |
| 17788 resource[1] = new TestResource(two_byte_string); | 17835 resource[1] = new TestResource(two_byte_string, NULL, false); |
| 17789 v8::Local<v8::String> string1 = | 17836 v8::Local<v8::String> string1 = |
| 17790 v8::String::NewExternal(env->GetIsolate(), resource[1]); | 17837 v8::String::NewExternal(env->GetIsolate(), resource[1]); |
| 17791 | 17838 |
| 17792 // Externalized symbol. | 17839 // Externalized symbol. |
| 17793 resource[2] = new TestResource(two_byte_string); | 17840 resource[2] = new TestResource(two_byte_string, NULL, false); |
| 17794 v8::Local<v8::String> string2 = v8::String::NewFromUtf8( | 17841 v8::Local<v8::String> string2 = v8::String::NewFromUtf8( |
| 17795 env->GetIsolate(), string, v8::String::kInternalizedString); | 17842 env->GetIsolate(), string, v8::String::kInternalizedString); |
| 17796 CHECK(string2->MakeExternal(resource[2])); | 17843 CHECK(string2->MakeExternal(resource[2])); |
| 17797 | 17844 |
| 17798 // Symbolized External. | 17845 // Symbolized External. |
| 17799 resource[3] = new TestResource(AsciiToTwoByteString("Some other string")); | 17846 resource[3] = new TestResource(AsciiToTwoByteString("Some other string")); |
| 17800 v8::Local<v8::String> string3 = | 17847 v8::Local<v8::String> string3 = |
| 17801 v8::String::NewExternal(env->GetIsolate(), resource[3]); | 17848 v8::String::NewExternal(env->GetIsolate(), resource[3]); |
| 17802 CcTest::heap()->CollectAllAvailableGarbage(); // Tenure string. | 17849 CcTest::heap()->CollectAllAvailableGarbage(); // Tenure string. |
| 17803 // Turn into a symbol. | 17850 // Turn into a symbol. |
| (...skipping 1055 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 18859 i::SmartArrayPointer<uintptr_t> | 18906 i::SmartArrayPointer<uintptr_t> |
| 18860 aligned_contents(new uintptr_t[aligned_length]); | 18907 aligned_contents(new uintptr_t[aligned_length]); |
| 18861 uint16_t* string_contents = | 18908 uint16_t* string_contents = |
| 18862 reinterpret_cast<uint16_t*>(aligned_contents.get()); | 18909 reinterpret_cast<uint16_t*>(aligned_contents.get()); |
| 18863 // Set to contain only one byte. | 18910 // Set to contain only one byte. |
| 18864 for (int i = 0; i < length-1; i++) { | 18911 for (int i = 0; i < length-1; i++) { |
| 18865 string_contents[i] = 0x41; | 18912 string_contents[i] = 0x41; |
| 18866 } | 18913 } |
| 18867 string_contents[length-1] = 0; | 18914 string_contents[length-1] = 0; |
| 18868 // Simple case. | 18915 // Simple case. |
| 18869 Handle<String> string; | 18916 Handle<String> string = |
| 18870 string = String::NewExternal(isolate, new TestResource(string_contents)); | 18917 String::NewExternal(isolate, |
| 18918 new TestResource(string_contents, NULL, false)); |
| 18871 CHECK(!string->IsOneByte() && string->ContainsOnlyOneByte()); | 18919 CHECK(!string->IsOneByte() && string->ContainsOnlyOneByte()); |
| 18872 // Counter example. | 18920 // Counter example. |
| 18873 string = String::NewFromTwoByte(isolate, string_contents); | 18921 string = String::NewFromTwoByte(isolate, string_contents); |
| 18874 CHECK(string->IsOneByte() && string->ContainsOnlyOneByte()); | 18922 CHECK(string->IsOneByte() && string->ContainsOnlyOneByte()); |
| 18875 // Test left right and balanced cons strings. | 18923 // Test left right and balanced cons strings. |
| 18876 Handle<String> base = String::NewFromUtf8(isolate, "a"); | 18924 Handle<String> base = String::NewFromUtf8(isolate, "a"); |
| 18877 Handle<String> left = base; | 18925 Handle<String> left = base; |
| 18878 Handle<String> right = base; | 18926 Handle<String> right = base; |
| 18879 for (int i = 0; i < 1000; i++) { | 18927 for (int i = 0; i < 1000; i++) { |
| 18880 left = String::Concat(base, left); | 18928 left = String::Concat(base, left); |
| 18881 right = String::Concat(right, base); | 18929 right = String::Concat(right, base); |
| 18882 } | 18930 } |
| 18883 Handle<String> balanced = String::Concat(left, base); | 18931 Handle<String> balanced = String::Concat(left, base); |
| 18884 balanced = String::Concat(balanced, right); | 18932 balanced = String::Concat(balanced, right); |
| 18885 Handle<String> cons_strings[] = {left, balanced, right}; | 18933 Handle<String> cons_strings[] = {left, balanced, right}; |
| 18886 Handle<String> two_byte = | 18934 Handle<String> two_byte = |
| 18887 String::NewExternal(isolate, new TestResource(string_contents)); | 18935 String::NewExternal(isolate, |
| 18936 new TestResource(string_contents, NULL, false)); |
| 18937 USE(two_byte); USE(cons_strings); |
| 18888 for (size_t i = 0; i < ARRAY_SIZE(cons_strings); i++) { | 18938 for (size_t i = 0; i < ARRAY_SIZE(cons_strings); i++) { |
| 18889 // Base assumptions. | 18939 // Base assumptions. |
| 18890 string = cons_strings[i]; | 18940 string = cons_strings[i]; |
| 18891 CHECK(string->IsOneByte() && string->ContainsOnlyOneByte()); | 18941 CHECK(string->IsOneByte() && string->ContainsOnlyOneByte()); |
| 18892 // Test left and right concatentation. | 18942 // Test left and right concatentation. |
| 18893 string = String::Concat(two_byte, cons_strings[i]); | 18943 string = String::Concat(two_byte, cons_strings[i]); |
| 18894 CHECK(!string->IsOneByte() && string->ContainsOnlyOneByte()); | 18944 CHECK(!string->IsOneByte() && string->ContainsOnlyOneByte()); |
| 18895 string = String::Concat(cons_strings[i], two_byte); | 18945 string = String::Concat(cons_strings[i], two_byte); |
| 18896 CHECK(!string->IsOneByte() && string->ContainsOnlyOneByte()); | 18946 CHECK(!string->IsOneByte() && string->ContainsOnlyOneByte()); |
| 18897 } | 18947 } |
| 18898 // Set bits in different positions | 18948 // Set bits in different positions |
| 18899 // for strings of different lengths and alignments. | 18949 // for strings of different lengths and alignments. |
| 18900 for (int alignment = 0; alignment < 7; alignment++) { | 18950 for (int alignment = 0; alignment < 7; alignment++) { |
| 18901 for (int size = 2; alignment + size < length; size *= 2) { | 18951 for (int size = 2; alignment + size < length; size *= 2) { |
| 18902 int zero_offset = size + alignment; | 18952 int zero_offset = size + alignment; |
| 18903 string_contents[zero_offset] = 0; | 18953 string_contents[zero_offset] = 0; |
| 18904 for (int i = 0; i < size; i++) { | 18954 for (int i = 0; i < size; i++) { |
| 18905 int shift = 8 + (i % 7); | 18955 int shift = 8 + (i % 7); |
| 18906 string_contents[alignment + i] = 1 << shift; | 18956 string_contents[alignment + i] = 1 << shift; |
| 18907 string = String::NewExternal( | 18957 string = String::NewExternal( |
| 18908 isolate, new TestResource(string_contents + alignment)); | 18958 isolate, |
| 18959 new TestResource(string_contents + alignment, NULL, false)); |
| 18909 CHECK_EQ(size, string->Length()); | 18960 CHECK_EQ(size, string->Length()); |
| 18910 CHECK(!string->ContainsOnlyOneByte()); | 18961 CHECK(!string->ContainsOnlyOneByte()); |
| 18911 string_contents[alignment + i] = 0x41; | 18962 string_contents[alignment + i] = 0x41; |
| 18912 } | 18963 } |
| 18913 string_contents[zero_offset] = 0x41; | 18964 string_contents[zero_offset] = 0x41; |
| 18914 } | 18965 } |
| 18915 } | 18966 } |
| 18916 } | 18967 } |
| 18917 | 18968 |
| 18918 | 18969 |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 19015 v8::V8::SetFatalErrorHandler(StoringErrorCallback); | 19066 v8::V8::SetFatalErrorHandler(StoringErrorCallback); |
| 19016 last_location = last_message = NULL; | 19067 last_location = last_message = NULL; |
| 19017 isolate->Dispose(); | 19068 isolate->Dispose(); |
| 19018 CHECK_EQ(last_location, NULL); | 19069 CHECK_EQ(last_location, NULL); |
| 19019 CHECK_EQ(last_message, NULL); | 19070 CHECK_EQ(last_message, NULL); |
| 19020 } | 19071 } |
| 19021 | 19072 |
| 19022 | 19073 |
| 19023 UNINITIALIZED_TEST(DisposeIsolateWhenInUse) { | 19074 UNINITIALIZED_TEST(DisposeIsolateWhenInUse) { |
| 19024 v8::Isolate* isolate = v8::Isolate::New(); | 19075 v8::Isolate* isolate = v8::Isolate::New(); |
| 19025 CHECK(isolate); | 19076 { |
| 19026 isolate->Enter(); | 19077 v8::Isolate::Scope i_scope(isolate); |
| 19027 v8::HandleScope scope(isolate); | 19078 v8::HandleScope scope(isolate); |
| 19028 LocalContext context(isolate); | 19079 LocalContext context(isolate); |
| 19029 // Run something in this isolate. | 19080 // Run something in this isolate. |
| 19030 ExpectTrue("true"); | 19081 ExpectTrue("true"); |
| 19031 v8::V8::SetFatalErrorHandler(StoringErrorCallback); | 19082 v8::V8::SetFatalErrorHandler(StoringErrorCallback); |
| 19032 last_location = last_message = NULL; | 19083 last_location = last_message = NULL; |
| 19033 // Still entered, should fail. | 19084 // Still entered, should fail. |
| 19085 isolate->Dispose(); |
| 19086 CHECK_NE(last_location, NULL); |
| 19087 CHECK_NE(last_message, NULL); |
| 19088 } |
| 19034 isolate->Dispose(); | 19089 isolate->Dispose(); |
| 19035 CHECK_NE(last_location, NULL); | |
| 19036 CHECK_NE(last_message, NULL); | |
| 19037 } | 19090 } |
| 19038 | 19091 |
| 19039 | 19092 |
| 19040 TEST(RunTwoIsolatesOnSingleThread) { | 19093 TEST(RunTwoIsolatesOnSingleThread) { |
| 19041 // Run isolate 1. | 19094 // Run isolate 1. |
| 19042 v8::Isolate* isolate1 = v8::Isolate::New(); | 19095 v8::Isolate* isolate1 = v8::Isolate::New(); |
| 19043 isolate1->Enter(); | 19096 isolate1->Enter(); |
| 19044 v8::Persistent<v8::Context> context1; | 19097 v8::Persistent<v8::Context> context1; |
| 19045 { | 19098 { |
| 19046 v8::HandleScope scope(isolate1); | 19099 v8::HandleScope scope(isolate1); |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 19241 } | 19294 } |
| 19242 { | 19295 { |
| 19243 v8::Isolate::Scope isolate_scope(isolate); | 19296 v8::Isolate::Scope isolate_scope(isolate); |
| 19244 v8::HandleScope handle_scope(isolate); | 19297 v8::HandleScope handle_scope(isolate); |
| 19245 context = v8::Context::New(isolate); | 19298 context = v8::Context::New(isolate); |
| 19246 v8::Context::Scope context_scope(context); | 19299 v8::Context::Scope context_scope(context); |
| 19247 Local<Value> v = CompileRun("22"); | 19300 Local<Value> v = CompileRun("22"); |
| 19248 CHECK(v->IsNumber()); | 19301 CHECK(v->IsNumber()); |
| 19249 CHECK_EQ(22, static_cast<int>(v->NumberValue())); | 19302 CHECK_EQ(22, static_cast<int>(v->NumberValue())); |
| 19250 } | 19303 } |
| 19304 isolate->Dispose(); |
| 19251 } | 19305 } |
| 19252 | 19306 |
| 19253 class InitDefaultIsolateThread : public v8::internal::Thread { | 19307 class InitDefaultIsolateThread : public v8::internal::Thread { |
| 19254 public: | 19308 public: |
| 19255 enum TestCase { | 19309 enum TestCase { |
| 19256 IgnoreOOM, | 19310 IgnoreOOM, |
| 19257 SetResourceConstraints, | 19311 SetResourceConstraints, |
| 19258 SetFatalHandler, | 19312 SetFatalHandler, |
| 19259 SetCounterFunction, | 19313 SetCounterFunction, |
| 19260 SetCreateHistogramFunction, | 19314 SetCreateHistogramFunction, |
| (...skipping 1192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 20453 | 20507 |
| 20454 | 20508 |
| 20455 TEST(CallCompletedCallbackTwoExceptions) { | 20509 TEST(CallCompletedCallbackTwoExceptions) { |
| 20456 LocalContext env; | 20510 LocalContext env; |
| 20457 v8::HandleScope scope(env->GetIsolate()); | 20511 v8::HandleScope scope(env->GetIsolate()); |
| 20458 v8::V8::AddCallCompletedCallback(CallCompletedCallbackException); | 20512 v8::V8::AddCallCompletedCallback(CallCompletedCallbackException); |
| 20459 CompileRun("throw 'first exception';"); | 20513 CompileRun("throw 'first exception';"); |
| 20460 } | 20514 } |
| 20461 | 20515 |
| 20462 | 20516 |
| 20517 static void MicrotaskOne(const v8::FunctionCallbackInfo<Value>& info) { |
| 20518 v8::HandleScope scope(info.GetIsolate()); |
| 20519 CompileRun("ext1Calls++;"); |
| 20520 } |
| 20521 |
| 20522 |
| 20523 static void MicrotaskTwo(const v8::FunctionCallbackInfo<Value>& info) { |
| 20524 v8::HandleScope scope(info.GetIsolate()); |
| 20525 CompileRun("ext2Calls++;"); |
| 20526 } |
| 20527 |
| 20528 |
| 20529 TEST(EnqueueMicrotask) { |
| 20530 LocalContext env; |
| 20531 v8::HandleScope scope(env->GetIsolate()); |
| 20532 CompileRun( |
| 20533 "var ext1Calls = 0;" |
| 20534 "var ext2Calls = 0;"); |
| 20535 CompileRun("1+1;"); |
| 20536 CHECK_EQ(0, CompileRun("ext1Calls")->Int32Value()); |
| 20537 CHECK_EQ(0, CompileRun("ext2Calls")->Int32Value()); |
| 20538 |
| 20539 v8::V8::EnqueueMicrotask(env->GetIsolate(), |
| 20540 Function::New(env->GetIsolate(), MicrotaskOne)); |
| 20541 CompileRun("1+1;"); |
| 20542 CHECK_EQ(1, CompileRun("ext1Calls")->Int32Value()); |
| 20543 CHECK_EQ(0, CompileRun("ext2Calls")->Int32Value()); |
| 20544 |
| 20545 v8::V8::EnqueueMicrotask(env->GetIsolate(), |
| 20546 Function::New(env->GetIsolate(), MicrotaskOne)); |
| 20547 v8::V8::EnqueueMicrotask(env->GetIsolate(), |
| 20548 Function::New(env->GetIsolate(), MicrotaskTwo)); |
| 20549 CompileRun("1+1;"); |
| 20550 CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value()); |
| 20551 CHECK_EQ(1, CompileRun("ext2Calls")->Int32Value()); |
| 20552 |
| 20553 v8::V8::EnqueueMicrotask(env->GetIsolate(), |
| 20554 Function::New(env->GetIsolate(), MicrotaskTwo)); |
| 20555 CompileRun("1+1;"); |
| 20556 CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value()); |
| 20557 CHECK_EQ(2, CompileRun("ext2Calls")->Int32Value()); |
| 20558 |
| 20559 CompileRun("1+1;"); |
| 20560 CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value()); |
| 20561 CHECK_EQ(2, CompileRun("ext2Calls")->Int32Value()); |
| 20562 } |
| 20563 |
| 20564 |
| 20565 TEST(SetAutorunMicrotasks) { |
| 20566 LocalContext env; |
| 20567 v8::HandleScope scope(env->GetIsolate()); |
| 20568 CompileRun( |
| 20569 "var ext1Calls = 0;" |
| 20570 "var ext2Calls = 0;"); |
| 20571 CompileRun("1+1;"); |
| 20572 CHECK_EQ(0, CompileRun("ext1Calls")->Int32Value()); |
| 20573 CHECK_EQ(0, CompileRun("ext2Calls")->Int32Value()); |
| 20574 |
| 20575 v8::V8::EnqueueMicrotask(env->GetIsolate(), |
| 20576 Function::New(env->GetIsolate(), MicrotaskOne)); |
| 20577 CompileRun("1+1;"); |
| 20578 CHECK_EQ(1, CompileRun("ext1Calls")->Int32Value()); |
| 20579 CHECK_EQ(0, CompileRun("ext2Calls")->Int32Value()); |
| 20580 |
| 20581 V8::SetAutorunMicrotasks(env->GetIsolate(), false); |
| 20582 v8::V8::EnqueueMicrotask(env->GetIsolate(), |
| 20583 Function::New(env->GetIsolate(), MicrotaskOne)); |
| 20584 v8::V8::EnqueueMicrotask(env->GetIsolate(), |
| 20585 Function::New(env->GetIsolate(), MicrotaskTwo)); |
| 20586 CompileRun("1+1;"); |
| 20587 CHECK_EQ(1, CompileRun("ext1Calls")->Int32Value()); |
| 20588 CHECK_EQ(0, CompileRun("ext2Calls")->Int32Value()); |
| 20589 |
| 20590 V8::RunMicrotasks(env->GetIsolate()); |
| 20591 CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value()); |
| 20592 CHECK_EQ(1, CompileRun("ext2Calls")->Int32Value()); |
| 20593 |
| 20594 v8::V8::EnqueueMicrotask(env->GetIsolate(), |
| 20595 Function::New(env->GetIsolate(), MicrotaskTwo)); |
| 20596 CompileRun("1+1;"); |
| 20597 CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value()); |
| 20598 CHECK_EQ(1, CompileRun("ext2Calls")->Int32Value()); |
| 20599 |
| 20600 V8::RunMicrotasks(env->GetIsolate()); |
| 20601 CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value()); |
| 20602 CHECK_EQ(2, CompileRun("ext2Calls")->Int32Value()); |
| 20603 |
| 20604 V8::SetAutorunMicrotasks(env->GetIsolate(), true); |
| 20605 v8::V8::EnqueueMicrotask(env->GetIsolate(), |
| 20606 Function::New(env->GetIsolate(), MicrotaskTwo)); |
| 20607 CompileRun("1+1;"); |
| 20608 CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value()); |
| 20609 CHECK_EQ(3, CompileRun("ext2Calls")->Int32Value()); |
| 20610 } |
| 20611 |
| 20612 |
| 20463 static int probes_counter = 0; | 20613 static int probes_counter = 0; |
| 20464 static int misses_counter = 0; | 20614 static int misses_counter = 0; |
| 20465 static int updates_counter = 0; | 20615 static int updates_counter = 0; |
| 20466 | 20616 |
| 20467 | 20617 |
| 20468 static int* LookupCounter(const char* name) { | 20618 static int* LookupCounter(const char* name) { |
| 20469 if (strcmp(name, "c:V8.MegamorphicStubCacheProbes") == 0) { | 20619 if (strcmp(name, "c:V8.MegamorphicStubCacheProbes") == 0) { |
| 20470 return &probes_counter; | 20620 return &probes_counter; |
| 20471 } else if (strcmp(name, "c:V8.MegamorphicStubCacheMisses") == 0) { | 20621 } else if (strcmp(name, "c:V8.MegamorphicStubCacheMisses") == 0) { |
| 20472 return &misses_counter; | 20622 return &misses_counter; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 20506 v8::HandleScope scope(env->GetIsolate()); | 20656 v8::HandleScope scope(env->GetIsolate()); |
| 20507 int initial_probes = probes_counter; | 20657 int initial_probes = probes_counter; |
| 20508 int initial_misses = misses_counter; | 20658 int initial_misses = misses_counter; |
| 20509 int initial_updates = updates_counter; | 20659 int initial_updates = updates_counter; |
| 20510 CompileRun(kMegamorphicTestProgram); | 20660 CompileRun(kMegamorphicTestProgram); |
| 20511 int probes = probes_counter - initial_probes; | 20661 int probes = probes_counter - initial_probes; |
| 20512 int misses = misses_counter - initial_misses; | 20662 int misses = misses_counter - initial_misses; |
| 20513 int updates = updates_counter - initial_updates; | 20663 int updates = updates_counter - initial_updates; |
| 20514 CHECK_LT(updates, 10); | 20664 CHECK_LT(updates, 10); |
| 20515 CHECK_LT(misses, 10); | 20665 CHECK_LT(misses, 10); |
| 20516 CHECK_GE(probes, 10000); | 20666 // TODO(verwaest): Update this test to overflow the degree of polymorphism |
| 20667 // before megamorphism. The number of probes will only work once we teach the |
| 20668 // serializer to embed references to counters in the stubs, given that the |
| 20669 // megamorphic_stub_cache_probes is updated in a snapshot-generated stub. |
| 20670 CHECK_GE(probes, 0); |
| 20517 #endif | 20671 #endif |
| 20518 } | 20672 } |
| 20519 | 20673 |
| 20520 | 20674 |
| 20521 TEST(SecondaryStubCache) { | 20675 TEST(SecondaryStubCache) { |
| 20522 StubCacheHelper(true); | 20676 StubCacheHelper(true); |
| 20523 } | 20677 } |
| 20524 | 20678 |
| 20525 | 20679 |
| 20526 TEST(PrimaryStubCache) { | 20680 TEST(PrimaryStubCache) { |
| (...skipping 1225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 21752 context->Global()->Set(v8_str("P"), templ->NewInstance()); | 21906 context->Global()->Set(v8_str("P"), templ->NewInstance()); |
| 21753 CompileRun( | 21907 CompileRun( |
| 21754 "function C1() {" | 21908 "function C1() {" |
| 21755 " this.x = 23;" | 21909 " this.x = 23;" |
| 21756 "};" | 21910 "};" |
| 21757 "C1.prototype = P;" | 21911 "C1.prototype = P;" |
| 21758 "for (var i = 0; i < 4; i++ ) {" | 21912 "for (var i = 0; i < 4; i++ ) {" |
| 21759 " new C1();" | 21913 " new C1();" |
| 21760 "}"); | 21914 "}"); |
| 21761 } | 21915 } |
| 21916 |
| 21917 |
| 21918 class ApiCallOptimizationChecker { |
| 21919 private: |
| 21920 static Local<Object> data; |
| 21921 static Local<Object> receiver; |
| 21922 static Local<Object> holder; |
| 21923 static Local<Object> callee; |
| 21924 static int count; |
| 21925 |
| 21926 static void OptimizationCallback( |
| 21927 const v8::FunctionCallbackInfo<v8::Value>& info) { |
| 21928 CHECK(callee == info.Callee()); |
| 21929 CHECK(data == info.Data()); |
| 21930 CHECK(receiver == info.This()); |
| 21931 if (info.Length() == 1) { |
| 21932 CHECK_EQ(v8_num(1), info[0]); |
| 21933 } |
| 21934 CHECK(holder == info.Holder()); |
| 21935 count++; |
| 21936 info.GetReturnValue().Set(v8_str("returned")); |
| 21937 } |
| 21938 |
| 21939 // TODO(dcarney): move this to v8.h |
| 21940 static void SetAccessorProperty(Local<Object> object, |
| 21941 Local<String> name, |
| 21942 Local<Function> getter, |
| 21943 Local<Function> setter = Local<Function>()) { |
| 21944 i::Isolate* isolate = CcTest::i_isolate(); |
| 21945 v8::AccessControl settings = v8::DEFAULT; |
| 21946 v8::PropertyAttribute attribute = v8::None; |
| 21947 i::Handle<i::Object> getter_i = v8::Utils::OpenHandle(*getter); |
| 21948 i::Handle<i::Object> setter_i = v8::Utils::OpenHandle(*setter, true); |
| 21949 if (setter_i.is_null()) setter_i = isolate->factory()->null_value(); |
| 21950 i::JSObject::DefineAccessor(v8::Utils::OpenHandle(*object), |
| 21951 v8::Utils::OpenHandle(*name), |
| 21952 getter_i, |
| 21953 setter_i, |
| 21954 static_cast<PropertyAttributes>(attribute), |
| 21955 settings); |
| 21956 } |
| 21957 |
| 21958 public: |
| 21959 enum SignatureType { |
| 21960 kNoSignature, |
| 21961 kSignatureOnReceiver, |
| 21962 kSignatureOnPrototype |
| 21963 }; |
| 21964 |
| 21965 void RunAll() { |
| 21966 SignatureType signature_types[] = |
| 21967 {kNoSignature, kSignatureOnReceiver, kSignatureOnPrototype}; |
| 21968 for (unsigned i = 0; i < ARRAY_SIZE(signature_types); i++) { |
| 21969 SignatureType signature_type = signature_types[i]; |
| 21970 for (int j = 0; j < 2; j++) { |
| 21971 bool global = j == 0; |
| 21972 int key = signature_type + |
| 21973 ARRAY_SIZE(signature_types) * (global ? 1 : 0); |
| 21974 Run(signature_type, global, key); |
| 21975 } |
| 21976 } |
| 21977 } |
| 21978 |
| 21979 void Run(SignatureType signature_type, bool global, int key) { |
| 21980 v8::Isolate* isolate = CcTest::isolate(); |
| 21981 v8::HandleScope scope(isolate); |
| 21982 // Build a template for signature checks. |
| 21983 Local<v8::ObjectTemplate> signature_template; |
| 21984 Local<v8::Signature> signature; |
| 21985 { |
| 21986 Local<v8::FunctionTemplate> parent_template = |
| 21987 FunctionTemplate::New(isolate); |
| 21988 parent_template->SetHiddenPrototype(true); |
| 21989 Local<v8::FunctionTemplate> function_template |
| 21990 = FunctionTemplate::New(isolate); |
| 21991 function_template->Inherit(parent_template); |
| 21992 switch (signature_type) { |
| 21993 case kNoSignature: |
| 21994 break; |
| 21995 case kSignatureOnReceiver: |
| 21996 signature = v8::Signature::New(isolate, function_template); |
| 21997 break; |
| 21998 case kSignatureOnPrototype: |
| 21999 signature = v8::Signature::New(isolate, parent_template); |
| 22000 break; |
| 22001 } |
| 22002 signature_template = function_template->InstanceTemplate(); |
| 22003 } |
| 22004 // Global object must pass checks. |
| 22005 Local<v8::Context> context = |
| 22006 v8::Context::New(isolate, NULL, signature_template); |
| 22007 v8::Context::Scope context_scope(context); |
| 22008 // Install regular object that can pass signature checks. |
| 22009 Local<Object> function_receiver = signature_template->NewInstance(); |
| 22010 context->Global()->Set(v8_str("function_receiver"), function_receiver); |
| 22011 // Get the holder objects. |
| 22012 Local<Object> inner_global = |
| 22013 Local<Object>::Cast(context->Global()->GetPrototype()); |
| 22014 // Install functions on hidden prototype object if there is one. |
| 22015 data = Object::New(isolate); |
| 22016 Local<FunctionTemplate> function_template = FunctionTemplate::New( |
| 22017 isolate, OptimizationCallback, data, signature); |
| 22018 Local<Function> function = function_template->GetFunction(); |
| 22019 Local<Object> global_holder = inner_global; |
| 22020 Local<Object> function_holder = function_receiver; |
| 22021 if (signature_type == kSignatureOnPrototype) { |
| 22022 function_holder = Local<Object>::Cast(function_holder->GetPrototype()); |
| 22023 global_holder = Local<Object>::Cast(global_holder->GetPrototype()); |
| 22024 } |
| 22025 global_holder->Set(v8_str("g_f"), function); |
| 22026 SetAccessorProperty(global_holder, v8_str("g_acc"), function, function); |
| 22027 function_holder->Set(v8_str("f"), function); |
| 22028 SetAccessorProperty(function_holder, v8_str("acc"), function, function); |
| 22029 // Initialize expected values. |
| 22030 callee = function; |
| 22031 count = 0; |
| 22032 if (global) { |
| 22033 receiver = context->Global(); |
| 22034 holder = inner_global; |
| 22035 } else { |
| 22036 holder = function_receiver; |
| 22037 // If not using a signature, add something else to the prototype chain |
| 22038 // to test the case that holder != receiver |
| 22039 if (signature_type == kNoSignature) { |
| 22040 receiver = Local<Object>::Cast(CompileRun( |
| 22041 "var receiver_subclass = {};\n" |
| 22042 "receiver_subclass.__proto__ = function_receiver;\n" |
| 22043 "receiver_subclass")); |
| 22044 } else { |
| 22045 receiver = Local<Object>::Cast(CompileRun( |
| 22046 "var receiver_subclass = function_receiver;\n" |
| 22047 "receiver_subclass")); |
| 22048 } |
| 22049 } |
| 22050 // With no signature, the holder is not set. |
| 22051 if (signature_type == kNoSignature) holder = receiver; |
| 22052 // build wrap_function |
| 22053 i::ScopedVector<char> wrap_function(200); |
| 22054 if (global) { |
| 22055 i::OS::SNPrintF( |
| 22056 wrap_function, |
| 22057 "function wrap_f_%d() { var f = g_f; return f(); }\n" |
| 22058 "function wrap_get_%d() { return this.g_acc; }\n" |
| 22059 "function wrap_set_%d() { return this.g_acc = 1; }\n", |
| 22060 key, key, key); |
| 22061 } else { |
| 22062 i::OS::SNPrintF( |
| 22063 wrap_function, |
| 22064 "function wrap_f_%d() { return receiver_subclass.f(); }\n" |
| 22065 "function wrap_get_%d() { return receiver_subclass.acc; }\n" |
| 22066 "function wrap_set_%d() { return receiver_subclass.acc = 1; }\n", |
| 22067 key, key, key); |
| 22068 } |
| 22069 // build source string |
| 22070 i::ScopedVector<char> source(1000); |
| 22071 i::OS::SNPrintF( |
| 22072 source, |
| 22073 "%s\n" // wrap functions |
| 22074 "function wrap_f() { return wrap_f_%d(); }\n" |
| 22075 "function wrap_get() { return wrap_get_%d(); }\n" |
| 22076 "function wrap_set() { return wrap_set_%d(); }\n" |
| 22077 "check = function(returned) {\n" |
| 22078 " if (returned !== 'returned') { throw returned; }\n" |
| 22079 "}\n" |
| 22080 "\n" |
| 22081 "check(wrap_f());\n" |
| 22082 "check(wrap_f());\n" |
| 22083 "%%OptimizeFunctionOnNextCall(wrap_f_%d);\n" |
| 22084 "check(wrap_f());\n" |
| 22085 "\n" |
| 22086 "check(wrap_get());\n" |
| 22087 "check(wrap_get());\n" |
| 22088 "%%OptimizeFunctionOnNextCall(wrap_get_%d);\n" |
| 22089 "check(wrap_get());\n" |
| 22090 "\n" |
| 22091 "check = function(returned) {\n" |
| 22092 " if (returned !== 1) { throw returned; }\n" |
| 22093 "}\n" |
| 22094 "check(wrap_set());\n" |
| 22095 "check(wrap_set());\n" |
| 22096 "%%OptimizeFunctionOnNextCall(wrap_set_%d);\n" |
| 22097 "check(wrap_set());\n", |
| 22098 wrap_function.start(), key, key, key, key, key, key); |
| 22099 v8::TryCatch try_catch; |
| 22100 CompileRun(source.start()); |
| 22101 ASSERT(!try_catch.HasCaught()); |
| 22102 CHECK_EQ(9, count); |
| 22103 } |
| 22104 }; |
| 22105 |
| 22106 |
| 22107 Local<Object> ApiCallOptimizationChecker::data; |
| 22108 Local<Object> ApiCallOptimizationChecker::receiver; |
| 22109 Local<Object> ApiCallOptimizationChecker::holder; |
| 22110 Local<Object> ApiCallOptimizationChecker::callee; |
| 22111 int ApiCallOptimizationChecker::count = 0; |
| 22112 |
| 22113 |
| 22114 TEST(TestFunctionCallOptimization) { |
| 22115 i::FLAG_allow_natives_syntax = true; |
| 22116 ApiCallOptimizationChecker checker; |
| 22117 checker.RunAll(); |
| 22118 } |
| OLD | NEW |