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

Side by Side Diff: test/cctest/test-api.cc

Issue 185653004: Experimental parser: merge to r19637 (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/parser
Patch Set: Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « test/cctest/test-alloc.cc ('k') | test/cctest/test-assembler-a64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « test/cctest/test-alloc.cc ('k') | test/cctest/test-assembler-a64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698