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

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

Issue 39973003: Merge bleeding_edge. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/parser
Patch Set: again Created 7 years, 1 month 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/cctest.status ('k') | test/cctest/test-assembler-ia32.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 3300 matching lines...) Expand 10 before | Expand all | Expand 10 after
3311 explicit WeakCallCounter(int id) : id_(id), number_of_weak_calls_(0) { } 3311 explicit WeakCallCounter(int id) : id_(id), number_of_weak_calls_(0) { }
3312 int id() { return id_; } 3312 int id() { return id_; }
3313 void increment() { number_of_weak_calls_++; } 3313 void increment() { number_of_weak_calls_++; }
3314 int NumberOfWeakCalls() { return number_of_weak_calls_; } 3314 int NumberOfWeakCalls() { return number_of_weak_calls_; }
3315 private: 3315 private:
3316 int id_; 3316 int id_;
3317 int number_of_weak_calls_; 3317 int number_of_weak_calls_;
3318 }; 3318 };
3319 3319
3320 3320
3321 template<typename T>
3321 static void WeakPointerCallback(v8::Isolate* isolate, 3322 static void WeakPointerCallback(v8::Isolate* isolate,
3322 Persistent<Value>* handle, 3323 Persistent<T>* handle,
3323 WeakCallCounter* counter) { 3324 WeakCallCounter* counter) {
3324 CHECK_EQ(1234, counter->id()); 3325 CHECK_EQ(1234, counter->id());
3325 counter->increment(); 3326 counter->increment();
3326 handle->Dispose(); 3327 handle->Dispose();
3327 } 3328 }
3328 3329
3329 3330
3330 static UniqueId MakeUniqueId(const Persistent<Value>& p) { 3331 template<typename T>
3332 static UniqueId MakeUniqueId(const Persistent<T>& p) {
3331 return UniqueId(reinterpret_cast<uintptr_t>(*v8::Utils::OpenPersistent(p))); 3333 return UniqueId(reinterpret_cast<uintptr_t>(*v8::Utils::OpenPersistent(p)));
3332 } 3334 }
3333 3335
3334 3336
3335 THREADED_TEST(ApiObjectGroups) { 3337 THREADED_TEST(ApiObjectGroups) {
3336 LocalContext env; 3338 LocalContext env;
3337 v8::Isolate* iso = env->GetIsolate(); 3339 v8::Isolate* iso = env->GetIsolate();
3338 HandleScope scope(iso); 3340 HandleScope scope(iso);
3339 3341
3340 Persistent<Value> g1s1; 3342 Persistent<Value> g1s1;
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
3418 3420
3419 // And now make children weak again and collect them. 3421 // And now make children weak again and collect them.
3420 g1c1.MakeWeak(&counter, &WeakPointerCallback); 3422 g1c1.MakeWeak(&counter, &WeakPointerCallback);
3421 g2c1.MakeWeak(&counter, &WeakPointerCallback); 3423 g2c1.MakeWeak(&counter, &WeakPointerCallback);
3422 3424
3423 heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); 3425 heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
3424 CHECK_EQ(7, counter.NumberOfWeakCalls()); 3426 CHECK_EQ(7, counter.NumberOfWeakCalls());
3425 } 3427 }
3426 3428
3427 3429
3430 THREADED_TEST(ApiObjectGroupsForSubtypes) {
3431 LocalContext env;
3432 v8::Isolate* iso = env->GetIsolate();
3433 HandleScope scope(iso);
3434
3435 Persistent<Object> g1s1;
3436 Persistent<String> g1s2;
3437 Persistent<String> g1c1;
3438 Persistent<Object> g2s1;
3439 Persistent<String> g2s2;
3440 Persistent<String> g2c1;
3441
3442 WeakCallCounter counter(1234);
3443
3444 {
3445 HandleScope scope(iso);
3446 g1s1.Reset(iso, Object::New());
3447 g1s2.Reset(iso, String::New("foo1"));
3448 g1c1.Reset(iso, String::New("foo2"));
3449 g1s1.MakeWeak(&counter, &WeakPointerCallback);
3450 g1s2.MakeWeak(&counter, &WeakPointerCallback);
3451 g1c1.MakeWeak(&counter, &WeakPointerCallback);
3452
3453 g2s1.Reset(iso, Object::New());
3454 g2s2.Reset(iso, String::New("foo3"));
3455 g2c1.Reset(iso, String::New("foo4"));
3456 g2s1.MakeWeak(&counter, &WeakPointerCallback);
3457 g2s2.MakeWeak(&counter, &WeakPointerCallback);
3458 g2c1.MakeWeak(&counter, &WeakPointerCallback);
3459 }
3460
3461 Persistent<Value> root(iso, g1s1); // make a root.
3462
3463 // Connect group 1 and 2, make a cycle.
3464 {
3465 HandleScope scope(iso);
3466 CHECK(Local<Object>::New(iso, g1s1)->Set(0, Local<Object>::New(iso, g2s1)));
3467 CHECK(Local<Object>::New(iso, g2s1)->Set(0, Local<Object>::New(iso, g1s1)));
3468 }
3469
3470 {
3471 UniqueId id1 = MakeUniqueId(g1s1);
3472 UniqueId id2 = MakeUniqueId(g2s2);
3473 iso->SetObjectGroupId(g1s1, id1);
3474 iso->SetObjectGroupId(g1s2, id1);
3475 iso->SetReference(g1s1, g1c1);
3476 iso->SetObjectGroupId(g2s1, id2);
3477 iso->SetObjectGroupId(g2s2, id2);
3478 iso->SetReferenceFromGroup(id2, g2c1);
3479 }
3480 // Do a single full GC, ensure incremental marking is stopped.
3481 v8::internal::Heap* heap = reinterpret_cast<v8::internal::Isolate*>(
3482 iso)->heap();
3483 heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
3484
3485 // All object should be alive.
3486 CHECK_EQ(0, counter.NumberOfWeakCalls());
3487
3488 // Weaken the root.
3489 root.MakeWeak(&counter, &WeakPointerCallback);
3490 // But make children strong roots---all the objects (except for children)
3491 // should be collectable now.
3492 g1c1.ClearWeak();
3493 g2c1.ClearWeak();
3494
3495 // Groups are deleted, rebuild groups.
3496 {
3497 UniqueId id1 = MakeUniqueId(g1s1);
3498 UniqueId id2 = MakeUniqueId(g2s2);
3499 iso->SetObjectGroupId(g1s1, id1);
3500 iso->SetObjectGroupId(g1s2, id1);
3501 iso->SetReference(g1s1, g1c1);
3502 iso->SetObjectGroupId(g2s1, id2);
3503 iso->SetObjectGroupId(g2s2, id2);
3504 iso->SetReferenceFromGroup(id2, g2c1);
3505 }
3506
3507 heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
3508
3509 // All objects should be gone. 5 global handles in total.
3510 CHECK_EQ(5, counter.NumberOfWeakCalls());
3511
3512 // And now make children weak again and collect them.
3513 g1c1.MakeWeak(&counter, &WeakPointerCallback);
3514 g2c1.MakeWeak(&counter, &WeakPointerCallback);
3515
3516 heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
3517 CHECK_EQ(7, counter.NumberOfWeakCalls());
3518 }
3519
3520
3428 THREADED_TEST(ApiObjectGroupsCycle) { 3521 THREADED_TEST(ApiObjectGroupsCycle) {
3429 LocalContext env; 3522 LocalContext env;
3430 v8::Isolate* iso = env->GetIsolate(); 3523 v8::Isolate* iso = env->GetIsolate();
3431 HandleScope scope(iso); 3524 HandleScope scope(iso);
3432 3525
3433 WeakCallCounter counter(1234); 3526 WeakCallCounter counter(1234);
3434 3527
3435 Persistent<Value> g1s1; 3528 Persistent<Value> g1s1;
3436 Persistent<Value> g1s2; 3529 Persistent<Value> g1s2;
3437 Persistent<Value> g2s1; 3530 Persistent<Value> g2s1;
(...skipping 10878 matching lines...) Expand 10 before | Expand all | Expand 10 after
14316 // result has the 'x' property. 14409 // result has the 'x' property.
14317 context1->Enter(); 14410 context1->Enter();
14318 context1->Global()->Set(v8_str("other"), context0->Global()); 14411 context1->Global()->Set(v8_str("other"), context0->Global());
14319 Local<Value> value = CompileRun("var instance = new other.C(); instance.x"); 14412 Local<Value> value = CompileRun("var instance = new other.C(); instance.x");
14320 CHECK(value->IsInt32()); 14413 CHECK(value->IsInt32());
14321 CHECK_EQ(42, value->Int32Value()); 14414 CHECK_EQ(42, value->Int32Value());
14322 context1->Exit(); 14415 context1->Exit();
14323 } 14416 }
14324 14417
14325 14418
14326 class RegExpInterruptTest {
14327 public:
14328 RegExpInterruptTest() : block_(0) {}
14329 ~RegExpInterruptTest() {}
14330 void RunTest() {
14331 gc_count_ = 0;
14332 gc_during_regexp_ = 0;
14333 regexp_success_ = false;
14334 gc_success_ = false;
14335 GCThread gc_thread(this);
14336 gc_thread.Start();
14337 v8::Isolate* isolate = CcTest::isolate();
14338 v8::Locker::StartPreemption(isolate, 1);
14339
14340 LongRunningRegExp();
14341 {
14342 v8::Unlocker unlock(isolate);
14343 gc_thread.Join();
14344 }
14345 v8::Locker::StopPreemption(isolate);
14346 CHECK(regexp_success_);
14347 CHECK(gc_success_);
14348 }
14349
14350 private:
14351 // Number of garbage collections required.
14352 static const int kRequiredGCs = 5;
14353
14354 class GCThread : public i::Thread {
14355 public:
14356 explicit GCThread(RegExpInterruptTest* test)
14357 : Thread("GCThread"), test_(test) {}
14358 virtual void Run() {
14359 test_->CollectGarbage();
14360 }
14361 private:
14362 RegExpInterruptTest* test_;
14363 };
14364
14365 void CollectGarbage() {
14366 block_.Wait();
14367 while (gc_during_regexp_ < kRequiredGCs) {
14368 {
14369 v8::Locker lock(CcTest::isolate());
14370 v8::Isolate::Scope isolate_scope(CcTest::isolate());
14371 // TODO(lrn): Perhaps create some garbage before collecting.
14372 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags);
14373 gc_count_++;
14374 }
14375 i::OS::Sleep(1);
14376 }
14377 gc_success_ = true;
14378 }
14379
14380 void LongRunningRegExp() {
14381 block_.Signal(); // Enable garbage collection thread on next preemption.
14382 int rounds = 0;
14383 while (gc_during_regexp_ < kRequiredGCs) {
14384 int gc_before = gc_count_;
14385 {
14386 // Match 15-30 "a"'s against 14 and a "b".
14387 const char* c_source =
14388 "/a?a?a?a?a?a?a?a?a?a?a?a?a?a?aaaaaaaaaaaaaaaa/"
14389 ".exec('aaaaaaaaaaaaaaab') === null";
14390 Local<String> source = String::New(c_source);
14391 Local<Script> script = Script::Compile(source);
14392 Local<Value> result = script->Run();
14393 if (!result->BooleanValue()) {
14394 gc_during_regexp_ = kRequiredGCs; // Allow gc thread to exit.
14395 return;
14396 }
14397 }
14398 {
14399 // Match 15-30 "a"'s against 15 and a "b".
14400 const char* c_source =
14401 "/a?a?a?a?a?a?a?a?a?a?a?a?a?a?aaaaaaaaaaaaaaaa/"
14402 ".exec('aaaaaaaaaaaaaaaab')[0] === 'aaaaaaaaaaaaaaaa'";
14403 Local<String> source = String::New(c_source);
14404 Local<Script> script = Script::Compile(source);
14405 Local<Value> result = script->Run();
14406 if (!result->BooleanValue()) {
14407 gc_during_regexp_ = kRequiredGCs;
14408 return;
14409 }
14410 }
14411 int gc_after = gc_count_;
14412 gc_during_regexp_ += gc_after - gc_before;
14413 rounds++;
14414 i::OS::Sleep(1);
14415 }
14416 regexp_success_ = true;
14417 }
14418
14419 i::Semaphore block_;
14420 int gc_count_;
14421 int gc_during_regexp_;
14422 bool regexp_success_;
14423 bool gc_success_;
14424 };
14425
14426
14427 // Test that a regular expression execution can be interrupted and
14428 // survive a garbage collection.
14429 TEST(RegExpInterruption) {
14430 v8::Locker lock(CcTest::isolate());
14431 v8::HandleScope scope(CcTest::isolate());
14432 Local<Context> local_env;
14433 {
14434 LocalContext env;
14435 local_env = env.local();
14436 }
14437
14438 // Local context should still be live.
14439 CHECK(!local_env.IsEmpty());
14440 local_env->Enter();
14441
14442 // Should complete without problems.
14443 RegExpInterruptTest().RunTest();
14444
14445 local_env->Exit();
14446 }
14447
14448
14449 class ApplyInterruptTest { 14419 class ApplyInterruptTest {
14450 public: 14420 public:
14451 ApplyInterruptTest() : block_(0) {} 14421 ApplyInterruptTest() : block_(0) {}
14452 ~ApplyInterruptTest() {} 14422 ~ApplyInterruptTest() {}
14453 void RunTest() { 14423 void RunTest() {
14454 gc_count_ = 0; 14424 gc_count_ = 0;
14455 gc_during_apply_ = 0; 14425 gc_during_apply_ = 0;
14456 apply_success_ = false; 14426 apply_success_ = false;
14457 gc_success_ = false; 14427 gc_success_ = false;
14458 GCThread gc_thread(this); 14428 GCThread gc_thread(this);
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after
14728 UC16VectorResource uc16_resource( 14698 UC16VectorResource uc16_resource(
14729 i::Vector<const uint16_t>(two_byte_string, 14699 i::Vector<const uint16_t>(two_byte_string,
14730 i::StrLength(ascii_sources[i]))); 14700 i::StrLength(ascii_sources[i])));
14731 v8::Local<v8::String> source = v8::String::NewExternal(&uc16_resource); 14701 v8::Local<v8::String> source = v8::String::NewExternal(&uc16_resource);
14732 v8::Script::Compile(source); 14702 v8::Script::Compile(source);
14733 i::DeleteArray(two_byte_string); 14703 i::DeleteArray(two_byte_string);
14734 } 14704 }
14735 } 14705 }
14736 14706
14737 14707
14738 class RegExpStringModificationTest { 14708 #ifndef V8_INTERPRETED_REGEXP
14709
14710 struct RegExpInterruptionData {
14711 int loop_count;
14712 UC16VectorResource* string_resource;
14713 v8::Persistent<v8::String> string;
14714 } regexp_interruption_data;
14715
14716
14717 class RegExpInterruptionThread : public i::Thread {
14739 public: 14718 public:
14740 RegExpStringModificationTest() 14719 explicit RegExpInterruptionThread(v8::Isolate* isolate)
14741 : block_(0), 14720 : Thread("TimeoutThread"), isolate_(isolate) {}
14742 morphs_(0),
14743 morphs_during_regexp_(0),
14744 ascii_resource_(i::Vector<const char>("aaaaaaaaaaaaaab", 15)),
14745 uc16_resource_(i::Vector<const uint16_t>(two_byte_content_, 15)) {}
14746 ~RegExpStringModificationTest() {}
14747 void RunTest() {
14748 v8::Isolate* isolate = CcTest::isolate();
14749 i::Factory* factory = CcTest::i_isolate()->factory();
14750 14721
14751 regexp_success_ = false; 14722 virtual void Run() {
14752 morph_success_ = false; 14723 for (regexp_interruption_data.loop_count = 0;
14753 14724 regexp_interruption_data.loop_count < 7;
14754 // Initialize the contents of two_byte_content_ to be a uc16 representation 14725 regexp_interruption_data.loop_count++) {
14755 // of "aaaaaaaaaaaaaab". 14726 i::OS::Sleep(50); // Wait a bit before requesting GC.
14756 for (int i = 0; i < 14; i++) { 14727 reinterpret_cast<i::Isolate*>(isolate_)->stack_guard()->RequestGC();
14757 two_byte_content_[i] = 'a';
14758 } 14728 }
14759 two_byte_content_[14] = 'b'; 14729 i::OS::Sleep(50); // Wait a bit before terminating.
14760 14730 v8::V8::TerminateExecution(isolate_);
14761 // Create the input string for the regexp - the one we are going to change
14762 // properties of.
14763 input_ = factory->NewExternalStringFromAscii(&ascii_resource_);
14764
14765 // Inject the input as a global variable.
14766 i::Handle<i::String> input_name =
14767 factory->NewStringFromAscii(i::Vector<const char>("input", 5));
14768 i::JSReceiver::SetProperty(
14769 i::handle(CcTest::i_isolate()->native_context()->global_object()),
14770 input_name,
14771 input_,
14772 NONE,
14773 i::kNonStrictMode);
14774
14775 MorphThread morph_thread(this);
14776 morph_thread.Start();
14777 v8::Locker::StartPreemption(isolate, 1);
14778 LongRunningRegExp();
14779 {
14780 v8::Unlocker unlock(isolate);
14781 morph_thread.Join();
14782 }
14783 v8::Locker::StopPreemption(isolate);
14784 CHECK(regexp_success_);
14785 CHECK(morph_success_);
14786 } 14731 }
14787 14732
14788 private: 14733 private:
14789 // Number of string modifications required. 14734 v8::Isolate* isolate_;
14790 static const int kRequiredModifications = 5;
14791 static const int kMaxModifications = 100;
14792
14793 class MorphThread : public i::Thread {
14794 public:
14795 explicit MorphThread(RegExpStringModificationTest* test)
14796 : Thread("MorphThread"), test_(test) {}
14797 virtual void Run() {
14798 test_->MorphString();
14799 }
14800 private:
14801 RegExpStringModificationTest* test_;
14802 };
14803
14804 void MorphString() {
14805 block_.Wait();
14806 while (morphs_during_regexp_ < kRequiredModifications &&
14807 morphs_ < kMaxModifications) {
14808 {
14809 v8::Locker lock(CcTest::isolate());
14810 v8::Isolate::Scope isolate_scope(CcTest::isolate());
14811 // Swap string between ascii and two-byte representation.
14812 i::String* string = *input_;
14813 MorphAString(string, &ascii_resource_, &uc16_resource_);
14814 morphs_++;
14815 }
14816 i::OS::Sleep(1);
14817 }
14818 morph_success_ = true;
14819 }
14820
14821 void LongRunningRegExp() {
14822 block_.Signal(); // Enable morphing thread on next preemption.
14823 while (morphs_during_regexp_ < kRequiredModifications &&
14824 morphs_ < kMaxModifications) {
14825 int morphs_before = morphs_;
14826 {
14827 v8::HandleScope scope(CcTest::isolate());
14828 // Match 15-30 "a"'s against 14 and a "b".
14829 const char* c_source =
14830 "/a?a?a?a?a?a?a?a?a?a?a?a?a?a?aaaaaaaaaaaaaaaa/"
14831 ".exec(input) === null";
14832 Local<String> source = String::New(c_source);
14833 Local<Script> script = Script::Compile(source);
14834 Local<Value> result = script->Run();
14835 CHECK(result->IsTrue());
14836 }
14837 int morphs_after = morphs_;
14838 morphs_during_regexp_ += morphs_after - morphs_before;
14839 }
14840 regexp_success_ = true;
14841 }
14842
14843 i::uc16 two_byte_content_[15];
14844 i::Semaphore block_;
14845 int morphs_;
14846 int morphs_during_regexp_;
14847 bool regexp_success_;
14848 bool morph_success_;
14849 i::Handle<i::String> input_;
14850 AsciiVectorResource ascii_resource_;
14851 UC16VectorResource uc16_resource_;
14852 }; 14735 };
14853 14736
14854 14737
14855 // Test that a regular expression execution can be interrupted and 14738 void RunBeforeGC(v8::GCType type, v8::GCCallbackFlags flags) {
14856 // the string changed without failing. 14739 if (regexp_interruption_data.loop_count != 2) return;
14857 TEST(RegExpStringModification) {
14858 v8::Locker lock(CcTest::isolate());
14859 v8::HandleScope scope(CcTest::isolate()); 14740 v8::HandleScope scope(CcTest::isolate());
14860 Local<Context> local_env; 14741 v8::Local<v8::String> string = v8::Local<v8::String>::New(
14861 { 14742 CcTest::isolate(), regexp_interruption_data.string);
14862 LocalContext env; 14743 string->MakeExternal(regexp_interruption_data.string_resource);
14863 local_env = env.local(); 14744 }
14864 }
14865 14745
14866 // Local context should still be live.
14867 CHECK(!local_env.IsEmpty());
14868 local_env->Enter();
14869 14746
14870 // Should complete without problems. 14747 // Test that RegExp execution can be interrupted. Specifically, we test
14871 RegExpStringModificationTest().RunTest(); 14748 // * interrupting with GC
14749 // * turn the subject string from one-byte internal to two-byte external string
14750 // * force termination
14751 TEST(RegExpInterruption) {
14752 v8::HandleScope scope(CcTest::isolate());
14753 LocalContext env;
14872 14754
14873 local_env->Exit(); 14755 RegExpInterruptionThread timeout_thread(CcTest::isolate());
14756
14757 v8::V8::AddGCPrologueCallback(RunBeforeGC);
14758 static const char* ascii_content = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
14759 i::uc16* uc16_content = AsciiToTwoByteString(ascii_content);
14760 v8::Local<v8::String> string = v8_str(ascii_content);
14761
14762 CcTest::global()->Set(v8_str("a"), string);
14763 regexp_interruption_data.string.Reset(CcTest::isolate(), string);
14764 regexp_interruption_data.string_resource = new UC16VectorResource(
14765 i::Vector<const i::uc16>(uc16_content, i::StrLength(ascii_content)));
14766
14767 v8::TryCatch try_catch;
14768 timeout_thread.Start();
14769
14770 CompileRun("/((a*)*)*b/.exec(a)");
14771 CHECK(try_catch.HasTerminated());
14772
14773 timeout_thread.Join();
14774
14775 delete regexp_interruption_data.string_resource;
14776 regexp_interruption_data.string.Dispose();
14874 } 14777 }
14875 14778
14779 #endif // V8_INTERPRETED_REGEXP
14780
14876 14781
14877 // Test that we cannot set a property on the global object if there 14782 // Test that we cannot set a property on the global object if there
14878 // is a read-only property in the prototype chain. 14783 // is a read-only property in the prototype chain.
14879 TEST(ReadOnlyPropertyInGlobalProto) { 14784 TEST(ReadOnlyPropertyInGlobalProto) {
14880 i::FLAG_es5_readonly = true; 14785 i::FLAG_es5_readonly = true;
14881 v8::HandleScope scope(CcTest::isolate()); 14786 v8::HandleScope scope(CcTest::isolate());
14882 v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(); 14787 v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New();
14883 LocalContext context(0, templ); 14788 LocalContext context(0, templ);
14884 v8::Handle<v8::Object> global = context->Global(); 14789 v8::Handle<v8::Object> global = context->Global();
14885 v8::Handle<v8::Object> global_proto = 14790 v8::Handle<v8::Object> global_proto =
(...skipping 2706 matching lines...) Expand 10 before | Expand all | Expand 10 after
17592 v8::ScriptOrigin origin = v8::ScriptOrigin(v8::String::New("test")); 17497 v8::ScriptOrigin origin = v8::ScriptOrigin(v8::String::New("test"));
17593 v8::Handle<v8::String> script = v8::String::New( 17498 v8::Handle<v8::String> script = v8::String::New(
17594 "var foo = { bar : { baz : function() {}}}; var f = foo.bar.baz;"); 17499 "var foo = { bar : { baz : function() {}}}; var f = foo.bar.baz;");
17595 v8::Script::Compile(script, &origin)->Run(); 17500 v8::Script::Compile(script, &origin)->Run();
17596 v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast( 17501 v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast(
17597 env->Global()->Get(v8::String::New("f"))); 17502 env->Global()->Get(v8::String::New("f")));
17598 CHECK_EQ("foo.bar.baz", *v8::String::Utf8Value(f->GetInferredName())); 17503 CHECK_EQ("foo.bar.baz", *v8::String::Utf8Value(f->GetInferredName()));
17599 } 17504 }
17600 17505
17601 17506
17507 THREADED_TEST(FunctionGetDisplayName) {
17508 LocalContext env;
17509 v8::HandleScope scope(env->GetIsolate());
17510 const char* code = "var error = false;"
17511 "function a() { this.x = 1; };"
17512 "a.displayName = 'display_a';"
17513 "var b = (function() {"
17514 " var f = function() { this.x = 2; };"
17515 " f.displayName = 'display_b';"
17516 " return f;"
17517 "})();"
17518 "var c = function() {};"
17519 "c.__defineGetter__('displayName', function() {"
17520 " error = true;"
17521 " throw new Error();"
17522 "});"
17523 "function d() {};"
17524 "d.__defineGetter__('displayName', function() {"
17525 " error = true;"
17526 " return 'wrong_display_name';"
17527 "});"
17528 "function e() {};"
17529 "e.displayName = 'wrong_display_name';"
17530 "e.__defineSetter__('displayName', function() {"
17531 " error = true;"
17532 " throw new Error();"
17533 "});"
17534 "function f() {};"
17535 "f.displayName = { 'foo': 6, toString: function() {"
17536 " error = true;"
17537 " return 'wrong_display_name';"
17538 "}};"
17539 "var g = function() {"
17540 " arguments.callee.displayName = 'set_in_runtime';"
17541 "}; g();"
17542 ;
17543 v8::ScriptOrigin origin = v8::ScriptOrigin(v8::String::New("test"));
17544 v8::Script::Compile(v8::String::New(code), &origin)->Run();
17545 v8::Local<v8::Value> error = env->Global()->Get(v8::String::New("error"));
17546 v8::Local<v8::Function> a = v8::Local<v8::Function>::Cast(
17547 env->Global()->Get(v8::String::New("a")));
17548 v8::Local<v8::Function> b = v8::Local<v8::Function>::Cast(
17549 env->Global()->Get(v8::String::New("b")));
17550 v8::Local<v8::Function> c = v8::Local<v8::Function>::Cast(
17551 env->Global()->Get(v8::String::New("c")));
17552 v8::Local<v8::Function> d = v8::Local<v8::Function>::Cast(
17553 env->Global()->Get(v8::String::New("d")));
17554 v8::Local<v8::Function> e = v8::Local<v8::Function>::Cast(
17555 env->Global()->Get(v8::String::New("e")));
17556 v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast(
17557 env->Global()->Get(v8::String::New("f")));
17558 v8::Local<v8::Function> g = v8::Local<v8::Function>::Cast(
17559 env->Global()->Get(v8::String::New("g")));
17560 CHECK_EQ(false, error->BooleanValue());
17561 CHECK_EQ("display_a", *v8::String::Utf8Value(a->GetDisplayName()));
17562 CHECK_EQ("display_b", *v8::String::Utf8Value(b->GetDisplayName()));
17563 CHECK(c->GetDisplayName()->IsUndefined());
17564 CHECK(d->GetDisplayName()->IsUndefined());
17565 CHECK(e->GetDisplayName()->IsUndefined());
17566 CHECK(f->GetDisplayName()->IsUndefined());
17567 CHECK_EQ("set_in_runtime", *v8::String::Utf8Value(g->GetDisplayName()));
17568 }
17569
17570
17602 THREADED_TEST(ScriptLineNumber) { 17571 THREADED_TEST(ScriptLineNumber) {
17603 LocalContext env; 17572 LocalContext env;
17604 v8::HandleScope scope(env->GetIsolate()); 17573 v8::HandleScope scope(env->GetIsolate());
17605 v8::ScriptOrigin origin = v8::ScriptOrigin(v8::String::New("test")); 17574 v8::ScriptOrigin origin = v8::ScriptOrigin(v8::String::New("test"));
17606 v8::Handle<v8::String> script = v8::String::New( 17575 v8::Handle<v8::String> script = v8::String::New(
17607 "function f() {}\n\nfunction g() {}"); 17576 "function f() {}\n\nfunction g() {}");
17608 v8::Script::Compile(script, &origin)->Run(); 17577 v8::Script::Compile(script, &origin)->Run();
17609 v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast( 17578 v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast(
17610 env->Global()->Get(v8::String::New("f"))); 17579 env->Global()->Get(v8::String::New("f")));
17611 v8::Local<v8::Function> g = v8::Local<v8::Function>::Cast( 17580 v8::Local<v8::Function> g = v8::Local<v8::Function>::Cast(
(...skipping 13 matching lines...) Expand all
17625 v8::Script::Compile(script, &origin)->Run(); 17594 v8::Script::Compile(script, &origin)->Run();
17626 v8::Local<v8::Function> foo = v8::Local<v8::Function>::Cast( 17595 v8::Local<v8::Function> foo = v8::Local<v8::Function>::Cast(
17627 env->Global()->Get(v8::String::New("foo"))); 17596 env->Global()->Get(v8::String::New("foo")));
17628 v8::Local<v8::Function> bar = v8::Local<v8::Function>::Cast( 17597 v8::Local<v8::Function> bar = v8::Local<v8::Function>::Cast(
17629 env->Global()->Get(v8::String::New("bar"))); 17598 env->Global()->Get(v8::String::New("bar")));
17630 CHECK_EQ(14, foo->GetScriptColumnNumber()); 17599 CHECK_EQ(14, foo->GetScriptColumnNumber());
17631 CHECK_EQ(17, bar->GetScriptColumnNumber()); 17600 CHECK_EQ(17, bar->GetScriptColumnNumber());
17632 } 17601 }
17633 17602
17634 17603
17604 THREADED_TEST(FunctionIsBuiltin) {
17605 LocalContext env;
17606 v8::HandleScope scope(env->GetIsolate());
17607 v8::Local<v8::Function> f;
17608 f = v8::Local<v8::Function>::Cast(CompileRun("Math.floor"));
17609 CHECK(f->IsBuiltin());
17610 f = v8::Local<v8::Function>::Cast(CompileRun("Object"));
17611 CHECK(f->IsBuiltin());
17612 f = v8::Local<v8::Function>::Cast(CompileRun("Object.__defineSetter__"));
17613 CHECK(f->IsBuiltin());
17614 f = v8::Local<v8::Function>::Cast(CompileRun("Array.prototype.toString"));
17615 CHECK(f->IsBuiltin());
17616 f = v8::Local<v8::Function>::Cast(CompileRun("function a() {}; a;"));
17617 CHECK(!f->IsBuiltin());
17618 }
17619
17620
17635 THREADED_TEST(FunctionGetScriptId) { 17621 THREADED_TEST(FunctionGetScriptId) {
17636 LocalContext env; 17622 LocalContext env;
17637 v8::HandleScope scope(env->GetIsolate()); 17623 v8::HandleScope scope(env->GetIsolate());
17638 v8::ScriptOrigin origin = v8::ScriptOrigin(v8::String::New("test"), 17624 v8::ScriptOrigin origin = v8::ScriptOrigin(v8::String::New("test"),
17639 v8::Integer::New(3), v8::Integer::New(2)); 17625 v8::Integer::New(3), v8::Integer::New(2));
17640 v8::Handle<v8::String> scriptSource = v8::String::New( 17626 v8::Handle<v8::String> scriptSource = v8::String::New(
17641 "function foo() {}\n\n function bar() {}"); 17627 "function foo() {}\n\n function bar() {}");
17642 v8::Local<v8::Script> script(v8::Script::Compile(scriptSource, &origin)); 17628 v8::Local<v8::Script> script(v8::Script::Compile(scriptSource, &origin));
17643 script->Run(); 17629 script->Run();
17644 v8::Local<v8::Function> foo = v8::Local<v8::Function>::Cast( 17630 v8::Local<v8::Function> foo = v8::Local<v8::Function>::Cast(
(...skipping 3080 matching lines...) Expand 10 before | Expand all | Expand 10 after
20725 } 20711 }
20726 for (int i = 0; i < runs; i++) { 20712 for (int i = 0; i < runs; i++) {
20727 Local<String> expected; 20713 Local<String> expected;
20728 if (i != 0) { 20714 if (i != 0) {
20729 CHECK_EQ(v8_str("escape value"), values[i]); 20715 CHECK_EQ(v8_str("escape value"), values[i]);
20730 } else { 20716 } else {
20731 CHECK(values[i].IsEmpty()); 20717 CHECK(values[i].IsEmpty());
20732 } 20718 }
20733 } 20719 }
20734 } 20720 }
OLDNEW
« no previous file with comments | « test/cctest/cctest.status ('k') | test/cctest/test-assembler-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698