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

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

Issue 660095: Merge revision 3813 to 3930 from bleeding_edge to partial snapshots branch. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/partial_snapshots/
Patch Set: '' Created 10 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/x64/virtual-frame-x64.cc ('k') | test/cctest/test-compiler.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 2007-2009 the V8 project authors. All rights reserved. 1 // Copyright 2007-2009 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 376 matching lines...) Expand 10 before | Expand all | Expand 10 after
387 } 387 }
388 388
389 389
390 THREADED_TEST(ScriptMakingExternalString) { 390 THREADED_TEST(ScriptMakingExternalString) {
391 TestResource::dispose_count = 0; 391 TestResource::dispose_count = 0;
392 uint16_t* two_byte_source = AsciiToTwoByteString("1 + 2 * 3"); 392 uint16_t* two_byte_source = AsciiToTwoByteString("1 + 2 * 3");
393 { 393 {
394 v8::HandleScope scope; 394 v8::HandleScope scope;
395 LocalContext env; 395 LocalContext env;
396 Local<String> source = String::New(two_byte_source); 396 Local<String> source = String::New(two_byte_source);
397 // Trigger GCs so that the newly allocated string moves to old gen.
398 i::Heap::CollectGarbage(0, i::NEW_SPACE); // in survivor space now
399 i::Heap::CollectGarbage(0, i::NEW_SPACE); // in old gen now
397 bool success = source->MakeExternal(new TestResource(two_byte_source)); 400 bool success = source->MakeExternal(new TestResource(two_byte_source));
398 CHECK(success); 401 CHECK(success);
399 Local<Script> script = Script::Compile(source); 402 Local<Script> script = Script::Compile(source);
400 Local<Value> value = script->Run(); 403 Local<Value> value = script->Run();
401 CHECK(value->IsNumber()); 404 CHECK(value->IsNumber());
402 CHECK_EQ(7, value->Int32Value()); 405 CHECK_EQ(7, value->Int32Value());
403 v8::internal::Heap::CollectAllGarbage(false); 406 v8::internal::Heap::CollectAllGarbage(false);
404 CHECK_EQ(0, TestResource::dispose_count); 407 CHECK_EQ(0, TestResource::dispose_count);
405 } 408 }
406 v8::internal::CompilationCache::Clear(); 409 v8::internal::CompilationCache::Clear();
407 v8::internal::Heap::CollectAllGarbage(false); 410 v8::internal::Heap::CollectAllGarbage(false);
408 CHECK_EQ(1, TestResource::dispose_count); 411 CHECK_EQ(1, TestResource::dispose_count);
409 } 412 }
410 413
411 414
412 THREADED_TEST(ScriptMakingExternalAsciiString) { 415 THREADED_TEST(ScriptMakingExternalAsciiString) {
413 TestAsciiResource::dispose_count = 0; 416 TestAsciiResource::dispose_count = 0;
414 const char* c_source = "1 + 2 * 3"; 417 const char* c_source = "1 + 2 * 3";
415 { 418 {
416 v8::HandleScope scope; 419 v8::HandleScope scope;
417 LocalContext env; 420 LocalContext env;
418 Local<String> source = v8_str(c_source); 421 Local<String> source = v8_str(c_source);
422 // Trigger GCs so that the newly allocated string moves to old gen.
423 i::Heap::CollectGarbage(0, i::NEW_SPACE); // in survivor space now
424 i::Heap::CollectGarbage(0, i::NEW_SPACE); // in old gen now
419 bool success = source->MakeExternal( 425 bool success = source->MakeExternal(
420 new TestAsciiResource(i::StrDup(c_source))); 426 new TestAsciiResource(i::StrDup(c_source)));
421 CHECK(success); 427 CHECK(success);
422 Local<Script> script = Script::Compile(source); 428 Local<Script> script = Script::Compile(source);
423 Local<Value> value = script->Run(); 429 Local<Value> value = script->Run();
424 CHECK(value->IsNumber()); 430 CHECK(value->IsNumber());
425 CHECK_EQ(7, value->Int32Value()); 431 CHECK_EQ(7, value->Int32Value());
426 v8::internal::Heap::CollectAllGarbage(false); 432 v8::internal::Heap::CollectAllGarbage(false);
427 CHECK_EQ(0, TestAsciiResource::dispose_count); 433 CHECK_EQ(0, TestAsciiResource::dispose_count);
428 } 434 }
429 v8::internal::CompilationCache::Clear(); 435 v8::internal::CompilationCache::Clear();
430 v8::internal::Heap::CollectAllGarbage(false); 436 v8::internal::Heap::CollectAllGarbage(false);
431 CHECK_EQ(1, TestAsciiResource::dispose_count); 437 CHECK_EQ(1, TestAsciiResource::dispose_count);
432 } 438 }
433 439
434 440
441 TEST(MakingExternalStringConditions) {
442 v8::HandleScope scope;
443 LocalContext env;
444
445 // Free some space in the new space so that we can check freshness.
446 i::Heap::CollectGarbage(0, i::NEW_SPACE);
447 i::Heap::CollectGarbage(0, i::NEW_SPACE);
448
449 Local<String> small_string = String::New(AsciiToTwoByteString("small"));
450 // We should refuse to externalize newly created small string.
451 CHECK(!small_string->CanMakeExternal());
452 // Trigger GCs so that the newly allocated string moves to old gen.
453 i::Heap::CollectGarbage(0, i::NEW_SPACE); // in survivor space now
454 i::Heap::CollectGarbage(0, i::NEW_SPACE); // in old gen now
455 // Old space strings should be accepted.
456 CHECK(small_string->CanMakeExternal());
457
458 small_string = String::New(AsciiToTwoByteString("small 2"));
459 // We should refuse externalizing newly created small string.
460 CHECK(!small_string->CanMakeExternal());
461 for (int i = 0; i < 100; i++) {
462 String::Value value(small_string);
463 }
464 // Frequently used strings should be accepted.
465 CHECK(small_string->CanMakeExternal());
466
467 const int buf_size = 10 * 1024;
468 char* buf = i::NewArray<char>(buf_size);
469 memset(buf, 'a', buf_size);
470 buf[buf_size - 1] = '\0';
471 Local<String> large_string = String::New(AsciiToTwoByteString(buf));
472 i::DeleteArray(buf);
473 // Large strings should be immediately accepted.
474 CHECK(large_string->CanMakeExternal());
475 }
476
477
478 TEST(MakingExternalAsciiStringConditions) {
479 v8::HandleScope scope;
480 LocalContext env;
481
482 // Free some space in the new space so that we can check freshness.
483 i::Heap::CollectGarbage(0, i::NEW_SPACE);
484 i::Heap::CollectGarbage(0, i::NEW_SPACE);
485
486 Local<String> small_string = String::New("small");
487 // We should refuse to externalize newly created small string.
488 CHECK(!small_string->CanMakeExternal());
489 // Trigger GCs so that the newly allocated string moves to old gen.
490 i::Heap::CollectGarbage(0, i::NEW_SPACE); // in survivor space now
491 i::Heap::CollectGarbage(0, i::NEW_SPACE); // in old gen now
492 // Old space strings should be accepted.
493 CHECK(small_string->CanMakeExternal());
494
495 small_string = String::New("small 2");
496 // We should refuse externalizing newly created small string.
497 CHECK(!small_string->CanMakeExternal());
498 for (int i = 0; i < 100; i++) {
499 String::Value value(small_string);
500 }
501 // Frequently used strings should be accepted.
502 CHECK(small_string->CanMakeExternal());
503
504 const int buf_size = 10 * 1024;
505 char* buf = i::NewArray<char>(buf_size);
506 memset(buf, 'a', buf_size);
507 buf[buf_size - 1] = '\0';
508 Local<String> large_string = String::New(buf);
509 i::DeleteArray(buf);
510 // Large strings should be immediately accepted.
511 CHECK(large_string->CanMakeExternal());
512 }
513
514
435 THREADED_TEST(UsingExternalString) { 515 THREADED_TEST(UsingExternalString) {
436 { 516 {
437 v8::HandleScope scope; 517 v8::HandleScope scope;
438 uint16_t* two_byte_string = AsciiToTwoByteString("test string"); 518 uint16_t* two_byte_string = AsciiToTwoByteString("test string");
439 Local<String> string = 519 Local<String> string =
440 String::NewExternal(new TestResource(two_byte_string)); 520 String::NewExternal(new TestResource(two_byte_string));
441 i::Handle<i::String> istring = v8::Utils::OpenHandle(*string); 521 i::Handle<i::String> istring = v8::Utils::OpenHandle(*string);
442 // Trigger GCs so that the newly allocated string moves to old gen. 522 // Trigger GCs so that the newly allocated string moves to old gen.
443 i::Heap::CollectGarbage(0, i::NEW_SPACE); // in survivor space now 523 i::Heap::CollectGarbage(0, i::NEW_SPACE); // in survivor space now
444 i::Heap::CollectGarbage(0, i::NEW_SPACE); // in old gen now 524 i::Heap::CollectGarbage(0, i::NEW_SPACE); // in old gen now
(...skipping 1996 matching lines...) Expand 10 before | Expand all | Expand 10 after
2441 LocalContext context; 2521 LocalContext context;
2442 context->Global()->Set(v8_str("obj"), templ->NewInstance()); 2522 context->Global()->Set(v8_str("obj"), templ->NewInstance());
2443 Local<Script> script = Script::Compile(v8_str("obj.x")); 2523 Local<Script> script = Script::Compile(v8_str("obj.x"));
2444 for (int i = 0; i < 10; i++) { 2524 for (int i = 0; i < 10; i++) {
2445 Local<Value> result = script->Run(); 2525 Local<Value> result = script->Run();
2446 CHECK_EQ(result, v8_str("x")); 2526 CHECK_EQ(result, v8_str("x"));
2447 } 2527 }
2448 } 2528 }
2449 2529
2450 2530
2531 static v8::Handle<Value> SetXOnPrototypeGetter(Local<String> property,
2532 const AccessorInfo& info) {
2533 // Set x on the prototype object and do not handle the get request.
2534 v8::Handle<v8::Value> proto = info.Holder()->GetPrototype();
2535 v8::Handle<v8::Object>::Cast(proto)->Set(v8_str("x"), v8::Integer::New(23));
2536 return v8::Handle<Value>();
2537 }
2538
2539
2540 // This is a regression test for http://crbug.com/20104. Map
2541 // transitions should not interfere with post interceptor lookup.
2542 THREADED_TEST(NamedInterceptorMapTransitionRead) {
2543 v8::HandleScope scope;
2544 Local<v8::FunctionTemplate> function_template = v8::FunctionTemplate::New();
2545 Local<v8::ObjectTemplate> instance_template
2546 = function_template->InstanceTemplate();
2547 instance_template->SetNamedPropertyHandler(SetXOnPrototypeGetter);
2548 LocalContext context;
2549 context->Global()->Set(v8_str("F"), function_template->GetFunction());
2550 // Create an instance of F and introduce a map transition for x.
2551 CompileRun("var o = new F(); o.x = 23;");
2552 // Create an instance of F and invoke the getter. The result should be 23.
2553 Local<Value> result = CompileRun("o = new F(); o.x");
2554 CHECK_EQ(result->Int32Value(), 23);
2555 }
2556
2557
2451 static v8::Handle<Value> IndexedPropertyGetter(uint32_t index, 2558 static v8::Handle<Value> IndexedPropertyGetter(uint32_t index,
2452 const AccessorInfo& info) { 2559 const AccessorInfo& info) {
2453 ApiTestFuzzer::Fuzz(); 2560 ApiTestFuzzer::Fuzz();
2454 if (index == 37) { 2561 if (index == 37) {
2455 return v8::Handle<Value>(v8_num(625)); 2562 return v8::Handle<Value>(v8_num(625));
2456 } 2563 }
2457 return v8::Handle<Value>(); 2564 return v8::Handle<Value>();
2458 } 2565 }
2459 2566
2460 2567
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
2522 " if (v != 0) throw 'Wrong value ' + v + ' at iteration ' + i;" 2629 " if (v != 0) throw 'Wrong value ' + v + ' at iteration ' + i;"
2523 " }" 2630 " }"
2524 " 'PASSED'" 2631 " 'PASSED'"
2525 "} catch(e) {" 2632 "} catch(e) {"
2526 " e" 2633 " e"
2527 "}"; 2634 "}";
2528 ExpectString(code, "PASSED"); 2635 ExpectString(code, "PASSED");
2529 } 2636 }
2530 2637
2531 2638
2639 THREADED_TEST(IndexedInterceptorWithAccessorCheck) {
2640 v8::HandleScope scope;
2641 Local<ObjectTemplate> templ = ObjectTemplate::New();
2642 templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter);
2643
2644 LocalContext context;
2645 Local<v8::Object> obj = templ->NewInstance();
2646 obj->TurnOnAccessCheck();
2647 context->Global()->Set(v8_str("obj"), obj);
2648
2649 const char* code =
2650 "try {"
2651 " for (var i = 0; i < 100; i++) {"
2652 " var v = obj[0];"
2653 " if (v != undefined) throw 'Wrong value ' + v + ' at iteration ' + i;"
2654 " }"
2655 " 'PASSED'"
2656 "} catch(e) {"
2657 " e"
2658 "}";
2659 ExpectString(code, "PASSED");
2660 }
2661
2662
2663 THREADED_TEST(IndexedInterceptorWithAccessorCheckSwitchedOn) {
2664 i::FLAG_allow_natives_syntax = true;
2665 v8::HandleScope scope;
2666 Local<ObjectTemplate> templ = ObjectTemplate::New();
2667 templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter);
2668
2669 LocalContext context;
2670 Local<v8::Object> obj = templ->NewInstance();
2671 context->Global()->Set(v8_str("obj"), obj);
2672
2673 const char* code =
2674 "try {"
2675 " for (var i = 0; i < 100; i++) {"
2676 " var expected = i;"
2677 " if (i == 5) {"
2678 " %EnableAccessChecks(obj);"
2679 " expected = undefined;"
2680 " }"
2681 " var v = obj[i];"
2682 " if (v != expected) throw 'Wrong value ' + v + ' at iteration ' + i;"
2683 " if (i == 5) %DisableAccessChecks(obj);"
2684 " }"
2685 " 'PASSED'"
2686 "} catch(e) {"
2687 " e"
2688 "}";
2689 ExpectString(code, "PASSED");
2690 }
2691
2692
2693 THREADED_TEST(IndexedInterceptorWithDifferentIndices) {
2694 v8::HandleScope scope;
2695 Local<ObjectTemplate> templ = ObjectTemplate::New();
2696 templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter);
2697
2698 LocalContext context;
2699 Local<v8::Object> obj = templ->NewInstance();
2700 context->Global()->Set(v8_str("obj"), obj);
2701
2702 const char* code =
2703 "try {"
2704 " for (var i = 0; i < 100; i++) {"
2705 " var v = obj[i];"
2706 " if (v != i) throw 'Wrong value ' + v + ' at iteration ' + i;"
2707 " }"
2708 " 'PASSED'"
2709 "} catch(e) {"
2710 " e"
2711 "}";
2712 ExpectString(code, "PASSED");
2713 }
2714
2715
2716 THREADED_TEST(IndexedInterceptorWithNotSmiLookup) {
2717 v8::HandleScope scope;
2718 Local<ObjectTemplate> templ = ObjectTemplate::New();
2719 templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter);
2720
2721 LocalContext context;
2722 Local<v8::Object> obj = templ->NewInstance();
2723 context->Global()->Set(v8_str("obj"), obj);
2724
2725 const char* code =
2726 "try {"
2727 " for (var i = 0; i < 100; i++) {"
2728 " var expected = i;"
2729 " if (i == 50) {"
2730 " i = 'foobar';"
2731 " expected = undefined;"
2732 " }"
2733 " var v = obj[i];"
2734 " if (v != expected) throw 'Wrong value ' + v + ' at iteration ' + i;"
2735 " }"
2736 " 'PASSED'"
2737 "} catch(e) {"
2738 " e"
2739 "}";
2740 ExpectString(code, "PASSED");
2741 }
2742
2743
2744 THREADED_TEST(IndexedInterceptorGoingMegamorphic) {
2745 v8::HandleScope scope;
2746 Local<ObjectTemplate> templ = ObjectTemplate::New();
2747 templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter);
2748
2749 LocalContext context;
2750 Local<v8::Object> obj = templ->NewInstance();
2751 context->Global()->Set(v8_str("obj"), obj);
2752
2753 const char* code =
2754 "var original = obj;"
2755 "try {"
2756 " for (var i = 0; i < 100; i++) {"
2757 " var expected = i;"
2758 " if (i == 50) {"
2759 " obj = {50: 'foobar'};"
2760 " expected = 'foobar';"
2761 " }"
2762 " var v = obj[i];"
2763 " if (v != expected) throw 'Wrong value ' + v + ' at iteration ' + i;"
2764 " if (i == 50) obj = original;"
2765 " }"
2766 " 'PASSED'"
2767 "} catch(e) {"
2768 " e"
2769 "}";
2770 ExpectString(code, "PASSED");
2771 }
2772
2773
2774 THREADED_TEST(IndexedInterceptorReceiverTurningSmi) {
2775 v8::HandleScope scope;
2776 Local<ObjectTemplate> templ = ObjectTemplate::New();
2777 templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter);
2778
2779 LocalContext context;
2780 Local<v8::Object> obj = templ->NewInstance();
2781 context->Global()->Set(v8_str("obj"), obj);
2782
2783 const char* code =
2784 "var original = obj;"
2785 "try {"
2786 " for (var i = 0; i < 100; i++) {"
2787 " var expected = i;"
2788 " if (i == 5) {"
2789 " obj = 239;"
2790 " expected = undefined;"
2791 " }"
2792 " var v = obj[i];"
2793 " if (v != expected) throw 'Wrong value ' + v + ' at iteration ' + i;"
2794 " if (i == 5) obj = original;"
2795 " }"
2796 " 'PASSED'"
2797 "} catch(e) {"
2798 " e"
2799 "}";
2800 ExpectString(code, "PASSED");
2801 }
2802
2803
2804 THREADED_TEST(IndexedInterceptorOnProto) {
2805 v8::HandleScope scope;
2806 Local<ObjectTemplate> templ = ObjectTemplate::New();
2807 templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter);
2808
2809 LocalContext context;
2810 Local<v8::Object> obj = templ->NewInstance();
2811 context->Global()->Set(v8_str("obj"), obj);
2812
2813 const char* code =
2814 "var o = {__proto__: obj};"
2815 "try {"
2816 " for (var i = 0; i < 100; i++) {"
2817 " var v = o[i];"
2818 " if (v != i) throw 'Wrong value ' + v + ' at iteration ' + i;"
2819 " }"
2820 " 'PASSED'"
2821 "} catch(e) {"
2822 " e"
2823 "}";
2824 ExpectString(code, "PASSED");
2825 }
2826
2827
2532 THREADED_TEST(MultiContexts) { 2828 THREADED_TEST(MultiContexts) {
2533 v8::HandleScope scope; 2829 v8::HandleScope scope;
2534 v8::Handle<ObjectTemplate> templ = ObjectTemplate::New(); 2830 v8::Handle<ObjectTemplate> templ = ObjectTemplate::New();
2535 templ->Set(v8_str("dummy"), v8::FunctionTemplate::New(DummyCallHandler)); 2831 templ->Set(v8_str("dummy"), v8::FunctionTemplate::New(DummyCallHandler));
2536 2832
2537 Local<String> password = v8_str("Password"); 2833 Local<String> password = v8_str("Password");
2538 2834
2539 // Create an environment 2835 // Create an environment
2540 LocalContext context0(0, templ); 2836 LocalContext context0(0, templ);
2541 context0->SetSecurityToken(password); 2837 context0->SetSecurityToken(password);
(...skipping 2295 matching lines...) Expand 10 before | Expand all | Expand 10 after
4837 5133
4838 // Getting the prototype of o0 should get the first visible one 5134 // Getting the prototype of o0 should get the first visible one
4839 // which is o3. Therefore, z should not be defined on the prototype 5135 // which is o3. Therefore, z should not be defined on the prototype
4840 // object. 5136 // object.
4841 Local<Value> proto = o0->Get(v8_str("__proto__")); 5137 Local<Value> proto = o0->Get(v8_str("__proto__"));
4842 CHECK(proto->IsObject()); 5138 CHECK(proto->IsObject());
4843 CHECK(Local<v8::Object>::Cast(proto)->Get(v8_str("z"))->IsUndefined()); 5139 CHECK(Local<v8::Object>::Cast(proto)->Get(v8_str("z"))->IsUndefined());
4844 } 5140 }
4845 5141
4846 5142
5143 THREADED_TEST(SetPrototype) {
5144 v8::HandleScope handle_scope;
5145 LocalContext context;
5146
5147 Local<v8::FunctionTemplate> t0 = v8::FunctionTemplate::New();
5148 t0->InstanceTemplate()->Set(v8_str("x"), v8_num(0));
5149 Local<v8::FunctionTemplate> t1 = v8::FunctionTemplate::New();
5150 t1->SetHiddenPrototype(true);
5151 t1->InstanceTemplate()->Set(v8_str("y"), v8_num(1));
5152 Local<v8::FunctionTemplate> t2 = v8::FunctionTemplate::New();
5153 t2->SetHiddenPrototype(true);
5154 t2->InstanceTemplate()->Set(v8_str("z"), v8_num(2));
5155 Local<v8::FunctionTemplate> t3 = v8::FunctionTemplate::New();
5156 t3->InstanceTemplate()->Set(v8_str("u"), v8_num(3));
5157
5158 Local<v8::Object> o0 = t0->GetFunction()->NewInstance();
5159 Local<v8::Object> o1 = t1->GetFunction()->NewInstance();
5160 Local<v8::Object> o2 = t2->GetFunction()->NewInstance();
5161 Local<v8::Object> o3 = t3->GetFunction()->NewInstance();
5162
5163 // Setting the prototype on an object does not skip hidden prototypes.
5164 CHECK_EQ(0, o0->Get(v8_str("x"))->Int32Value());
5165 CHECK(o0->SetPrototype(o1));
5166 CHECK_EQ(0, o0->Get(v8_str("x"))->Int32Value());
5167 CHECK_EQ(1, o0->Get(v8_str("y"))->Int32Value());
5168 CHECK(o1->SetPrototype(o2));
5169 CHECK_EQ(0, o0->Get(v8_str("x"))->Int32Value());
5170 CHECK_EQ(1, o0->Get(v8_str("y"))->Int32Value());
5171 CHECK_EQ(2, o0->Get(v8_str("z"))->Int32Value());
5172 CHECK(o2->SetPrototype(o3));
5173 CHECK_EQ(0, o0->Get(v8_str("x"))->Int32Value());
5174 CHECK_EQ(1, o0->Get(v8_str("y"))->Int32Value());
5175 CHECK_EQ(2, o0->Get(v8_str("z"))->Int32Value());
5176 CHECK_EQ(3, o0->Get(v8_str("u"))->Int32Value());
5177
5178 // Getting the prototype of o0 should get the first visible one
5179 // which is o3. Therefore, z should not be defined on the prototype
5180 // object.
5181 Local<Value> proto = o0->Get(v8_str("__proto__"));
5182 CHECK(proto->IsObject());
5183 CHECK_EQ(v8::Handle<v8::Object>::Cast(proto), o3);
5184
5185 // However, Object::GetPrototype ignores hidden prototype.
5186 Local<Value> proto0 = o0->GetPrototype();
5187 CHECK(proto0->IsObject());
5188 CHECK_EQ(v8::Handle<v8::Object>::Cast(proto0), o1);
5189
5190 Local<Value> proto1 = o1->GetPrototype();
5191 CHECK(proto1->IsObject());
5192 CHECK_EQ(v8::Handle<v8::Object>::Cast(proto1), o2);
5193
5194 Local<Value> proto2 = o2->GetPrototype();
5195 CHECK(proto2->IsObject());
5196 CHECK_EQ(v8::Handle<v8::Object>::Cast(proto2), o3);
5197 }
5198
5199
5200 THREADED_TEST(SetPrototypeThrows) {
5201 v8::HandleScope handle_scope;
5202 LocalContext context;
5203
5204 Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New();
5205
5206 Local<v8::Object> o0 = t->GetFunction()->NewInstance();
5207 Local<v8::Object> o1 = t->GetFunction()->NewInstance();
5208
5209 CHECK(o0->SetPrototype(o1));
5210 // If setting the prototype leads to the cycle, SetPrototype should
5211 // return false and keep VM in sane state.
5212 v8::TryCatch try_catch;
5213 CHECK(!o1->SetPrototype(o0));
5214 CHECK(!try_catch.HasCaught());
5215 ASSERT(!i::Top::has_pending_exception());
5216
5217 CHECK_EQ(42, CompileRun("function f() { return 42; }; f()")->Int32Value());
5218 }
5219
5220
4847 THREADED_TEST(GetterSetterExceptions) { 5221 THREADED_TEST(GetterSetterExceptions) {
4848 v8::HandleScope handle_scope; 5222 v8::HandleScope handle_scope;
4849 LocalContext context; 5223 LocalContext context;
4850 CompileRun( 5224 CompileRun(
4851 "function Foo() { };" 5225 "function Foo() { };"
4852 "function Throw() { throw 5; };" 5226 "function Throw() { throw 5; };"
4853 "var x = { };" 5227 "var x = { };"
4854 "x.__defineSetter__('set', Throw);" 5228 "x.__defineSetter__('set', Throw);"
4855 "x.__defineGetter__('get', Throw);"); 5229 "x.__defineGetter__('get', Throw);");
4856 Local<v8::Object> x = 5230 Local<v8::Object> x =
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
5071 5445
5072 // Trigger lazy loading in other context. 5446 // Trigger lazy loading in other context.
5073 Local<Script> script = 5447 Local<Script> script =
5074 Script::Compile(v8_str("other.eval('new Date(42)')")); 5448 Script::Compile(v8_str("other.eval('new Date(42)')"));
5075 Local<Value> value = script->Run(); 5449 Local<Value> value = script->Run();
5076 CHECK_EQ(42.0, value->NumberValue()); 5450 CHECK_EQ(42.0, value->NumberValue());
5077 } 5451 }
5078 5452
5079 5453
5080 static v8::Handle<Value> call_as_function(const v8::Arguments& args) { 5454 static v8::Handle<Value> call_as_function(const v8::Arguments& args) {
5081 //ApiTestFuzzer::Fuzz(); 5455 ApiTestFuzzer::Fuzz();
5082 if (args.IsConstructCall()) { 5456 if (args.IsConstructCall()) {
5083 if (args[0]->IsInt32()) { 5457 if (args[0]->IsInt32()) {
5084 return v8_num(-args[0]->Int32Value()); 5458 return v8_num(-args[0]->Int32Value());
5085 } 5459 }
5086 } 5460 }
5087 5461
5088 return args[0]; 5462 return args[0];
5089 } 5463 }
5090 5464
5091 5465
(...skipping 792 matching lines...) Expand 10 before | Expand all | Expand 10 after
5884 " for (var i = 0; i < 10; i++) {" 6258 " for (var i = 0; i < 10; i++) {"
5885 " result += o.parseFloat('239');" 6259 " result += o.parseFloat('239');"
5886 " }" 6260 " }"
5887 " result" 6261 " result"
5888 "} catch(e) {" 6262 "} catch(e) {"
5889 " e" 6263 " e"
5890 "};"); 6264 "};");
5891 CHECK_EQ(239 * 10, value->Int32Value()); 6265 CHECK_EQ(239 * 10, value->Int32Value());
5892 } 6266 }
5893 6267
6268 static v8::Handle<Value> InterceptorCallICFastApi(Local<String> name,
6269 const AccessorInfo& info) {
6270 ApiTestFuzzer::Fuzz();
6271 int* call_count = reinterpret_cast<int*>(v8::External::Unwrap(info.Data()));
6272 ++(*call_count);
6273 if ((*call_count) % 20 == 0) {
6274 v8::internal::Heap::CollectAllGarbage(true);
6275 }
6276 return v8::Handle<Value>();
6277 }
6278
6279 static v8::Handle<Value> FastApiCallback_TrivialSignature(
6280 const v8::Arguments& args) {
6281 ApiTestFuzzer::Fuzz();
6282 CHECK_EQ(args.This(), args.Holder());
6283 CHECK(args.Data()->Equals(v8_str("method_data")));
6284 return v8::Integer::New(args[0]->Int32Value() + 1);
6285 }
6286
6287 static v8::Handle<Value> FastApiCallback_SimpleSignature(
6288 const v8::Arguments& args) {
6289 ApiTestFuzzer::Fuzz();
6290 CHECK_EQ(args.This()->GetPrototype(), args.Holder());
6291 CHECK(args.Data()->Equals(v8_str("method_data")));
6292 // Note, we're using HasRealNamedProperty instead of Has to avoid
6293 // invoking the interceptor again.
6294 CHECK(args.Holder()->HasRealNamedProperty(v8_str("foo")));
6295 return v8::Integer::New(args[0]->Int32Value() + 1);
6296 }
6297
6298 // Helper to maximize the odds of object moving.
6299 static void GenerateSomeGarbage() {
6300 CompileRun(
6301 "var garbage;"
6302 "for (var i = 0; i < 1000; i++) {"
6303 " garbage = [1/i, \"garbage\" + i, garbage, {foo: garbage}];"
6304 "}"
6305 "garbage = undefined;");
6306 }
6307
6308 THREADED_TEST(InterceptorCallICFastApi_TrivialSignature) {
6309 int interceptor_call_count = 0;
6310 v8::HandleScope scope;
6311 v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New();
6312 v8::Handle<v8::FunctionTemplate> method_templ =
6313 v8::FunctionTemplate::New(FastApiCallback_TrivialSignature,
6314 v8_str("method_data"),
6315 v8::Handle<v8::Signature>());
6316 v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate();
6317 proto_templ->Set(v8_str("method"), method_templ);
6318 v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate();
6319 templ->SetNamedPropertyHandler(InterceptorCallICFastApi,
6320 NULL, NULL, NULL, NULL,
6321 v8::External::Wrap(&interceptor_call_count));
6322 LocalContext context;
6323 v8::Handle<v8::Function> fun = fun_templ->GetFunction();
6324 GenerateSomeGarbage();
6325 context->Global()->Set(v8_str("o"), fun->NewInstance());
6326 v8::Handle<Value> value = CompileRun(
6327 "var result = 0;"
6328 "for (var i = 0; i < 100; i++) {"
6329 " result = o.method(41);"
6330 "}");
6331 CHECK_EQ(42, context->Global()->Get(v8_str("result"))->Int32Value());
6332 CHECK_EQ(100, interceptor_call_count);
6333 }
6334
6335 THREADED_TEST(InterceptorCallICFastApi_SimpleSignature) {
6336 int interceptor_call_count = 0;
6337 v8::HandleScope scope;
6338 v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New();
6339 v8::Handle<v8::FunctionTemplate> method_templ =
6340 v8::FunctionTemplate::New(FastApiCallback_SimpleSignature,
6341 v8_str("method_data"),
6342 v8::Signature::New(fun_templ));
6343 v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate();
6344 proto_templ->Set(v8_str("method"), method_templ);
6345 v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate();
6346 templ->SetNamedPropertyHandler(InterceptorCallICFastApi,
6347 NULL, NULL, NULL, NULL,
6348 v8::External::Wrap(&interceptor_call_count));
6349 LocalContext context;
6350 v8::Handle<v8::Function> fun = fun_templ->GetFunction();
6351 GenerateSomeGarbage();
6352 context->Global()->Set(v8_str("o"), fun->NewInstance());
6353 v8::Handle<Value> value = CompileRun(
6354 "o.foo = 17;"
6355 "var receiver = {};"
6356 "receiver.__proto__ = o;"
6357 "var result = 0;"
6358 "for (var i = 0; i < 100; i++) {"
6359 " result = receiver.method(41);"
6360 "}");
6361 CHECK_EQ(42, context->Global()->Get(v8_str("result"))->Int32Value());
6362 CHECK_EQ(100, interceptor_call_count);
6363 }
6364
6365 THREADED_TEST(InterceptorCallICFastApi_SimpleSignature_Miss1) {
6366 int interceptor_call_count = 0;
6367 v8::HandleScope scope;
6368 v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New();
6369 v8::Handle<v8::FunctionTemplate> method_templ =
6370 v8::FunctionTemplate::New(FastApiCallback_SimpleSignature,
6371 v8_str("method_data"),
6372 v8::Signature::New(fun_templ));
6373 v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate();
6374 proto_templ->Set(v8_str("method"), method_templ);
6375 v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate();
6376 templ->SetNamedPropertyHandler(InterceptorCallICFastApi,
6377 NULL, NULL, NULL, NULL,
6378 v8::External::Wrap(&interceptor_call_count));
6379 LocalContext context;
6380 v8::Handle<v8::Function> fun = fun_templ->GetFunction();
6381 GenerateSomeGarbage();
6382 context->Global()->Set(v8_str("o"), fun->NewInstance());
6383 v8::Handle<Value> value = CompileRun(
6384 "o.foo = 17;"
6385 "var receiver = {};"
6386 "receiver.__proto__ = o;"
6387 "var result = 0;"
6388 "var saved_result = 0;"
6389 "for (var i = 0; i < 100; i++) {"
6390 " result = receiver.method(41);"
6391 " if (i == 50) {"
6392 " saved_result = result;"
6393 " receiver = {method: function(x) { return x - 1 }};"
6394 " }"
6395 "}");
6396 CHECK_EQ(40, context->Global()->Get(v8_str("result"))->Int32Value());
6397 CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value());
6398 CHECK_GE(interceptor_call_count, 50);
6399 }
6400
6401 THREADED_TEST(InterceptorCallICFastApi_SimpleSignature_Miss2) {
6402 int interceptor_call_count = 0;
6403 v8::HandleScope scope;
6404 v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New();
6405 v8::Handle<v8::FunctionTemplate> method_templ =
6406 v8::FunctionTemplate::New(FastApiCallback_SimpleSignature,
6407 v8_str("method_data"),
6408 v8::Signature::New(fun_templ));
6409 v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate();
6410 proto_templ->Set(v8_str("method"), method_templ);
6411 v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate();
6412 templ->SetNamedPropertyHandler(InterceptorCallICFastApi,
6413 NULL, NULL, NULL, NULL,
6414 v8::External::Wrap(&interceptor_call_count));
6415 LocalContext context;
6416 v8::Handle<v8::Function> fun = fun_templ->GetFunction();
6417 GenerateSomeGarbage();
6418 context->Global()->Set(v8_str("o"), fun->NewInstance());
6419 v8::Handle<Value> value = CompileRun(
6420 "o.foo = 17;"
6421 "var receiver = {};"
6422 "receiver.__proto__ = o;"
6423 "var result = 0;"
6424 "var saved_result = 0;"
6425 "for (var i = 0; i < 100; i++) {"
6426 " result = receiver.method(41);"
6427 " if (i == 50) {"
6428 " saved_result = result;"
6429 " o.method = function(x) { return x - 1 };"
6430 " }"
6431 "}");
6432 CHECK_EQ(40, context->Global()->Get(v8_str("result"))->Int32Value());
6433 CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value());
6434 CHECK_GE(interceptor_call_count, 50);
6435 }
6436
6437 THREADED_TEST(InterceptorCallICFastApi_SimpleSignature_TypeError) {
6438 int interceptor_call_count = 0;
6439 v8::HandleScope scope;
6440 v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New();
6441 v8::Handle<v8::FunctionTemplate> method_templ =
6442 v8::FunctionTemplate::New(FastApiCallback_SimpleSignature,
6443 v8_str("method_data"),
6444 v8::Signature::New(fun_templ));
6445 v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate();
6446 proto_templ->Set(v8_str("method"), method_templ);
6447 v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate();
6448 templ->SetNamedPropertyHandler(InterceptorCallICFastApi,
6449 NULL, NULL, NULL, NULL,
6450 v8::External::Wrap(&interceptor_call_count));
6451 LocalContext context;
6452 v8::Handle<v8::Function> fun = fun_templ->GetFunction();
6453 GenerateSomeGarbage();
6454 context->Global()->Set(v8_str("o"), fun->NewInstance());
6455 v8::TryCatch try_catch;
6456 v8::Handle<Value> value = CompileRun(
6457 "o.foo = 17;"
6458 "var receiver = {};"
6459 "receiver.__proto__ = o;"
6460 "var result = 0;"
6461 "var saved_result = 0;"
6462 "for (var i = 0; i < 100; i++) {"
6463 " result = receiver.method(41);"
6464 " if (i == 50) {"
6465 " saved_result = result;"
6466 " receiver = {method: receiver.method};"
6467 " }"
6468 "}");
6469 CHECK(try_catch.HasCaught());
6470 CHECK_EQ(v8_str("TypeError: Illegal invocation"),
6471 try_catch.Exception()->ToString());
6472 CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value());
6473 CHECK_GE(interceptor_call_count, 50);
6474 }
6475
6476 THREADED_TEST(CallICFastApi_TrivialSignature) {
6477 v8::HandleScope scope;
6478 v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New();
6479 v8::Handle<v8::FunctionTemplate> method_templ =
6480 v8::FunctionTemplate::New(FastApiCallback_TrivialSignature,
6481 v8_str("method_data"),
6482 v8::Handle<v8::Signature>());
6483 v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate();
6484 proto_templ->Set(v8_str("method"), method_templ);
6485 v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate();
6486 LocalContext context;
6487 v8::Handle<v8::Function> fun = fun_templ->GetFunction();
6488 GenerateSomeGarbage();
6489 context->Global()->Set(v8_str("o"), fun->NewInstance());
6490 v8::Handle<Value> value = CompileRun(
6491 "var result = 0;"
6492 "for (var i = 0; i < 100; i++) {"
6493 " result = o.method(41);"
6494 "}");
6495
6496 CHECK_EQ(42, context->Global()->Get(v8_str("result"))->Int32Value());
6497 }
6498
6499 THREADED_TEST(CallICFastApi_SimpleSignature) {
6500 v8::HandleScope scope;
6501 v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New();
6502 v8::Handle<v8::FunctionTemplate> method_templ =
6503 v8::FunctionTemplate::New(FastApiCallback_SimpleSignature,
6504 v8_str("method_data"),
6505 v8::Signature::New(fun_templ));
6506 v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate();
6507 proto_templ->Set(v8_str("method"), method_templ);
6508 v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate();
6509 LocalContext context;
6510 v8::Handle<v8::Function> fun = fun_templ->GetFunction();
6511 GenerateSomeGarbage();
6512 context->Global()->Set(v8_str("o"), fun->NewInstance());
6513 v8::Handle<Value> value = CompileRun(
6514 "o.foo = 17;"
6515 "var receiver = {};"
6516 "receiver.__proto__ = o;"
6517 "var result = 0;"
6518 "for (var i = 0; i < 100; i++) {"
6519 " result = receiver.method(41);"
6520 "}");
6521
6522 CHECK_EQ(42, context->Global()->Get(v8_str("result"))->Int32Value());
6523 }
6524
6525 THREADED_TEST(CallICFastApi_SimpleSignature_Miss) {
6526 v8::HandleScope scope;
6527 v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New();
6528 v8::Handle<v8::FunctionTemplate> method_templ =
6529 v8::FunctionTemplate::New(FastApiCallback_SimpleSignature,
6530 v8_str("method_data"),
6531 v8::Signature::New(fun_templ));
6532 v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate();
6533 proto_templ->Set(v8_str("method"), method_templ);
6534 v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate();
6535 LocalContext context;
6536 v8::Handle<v8::Function> fun = fun_templ->GetFunction();
6537 GenerateSomeGarbage();
6538 context->Global()->Set(v8_str("o"), fun->NewInstance());
6539 v8::Handle<Value> value = CompileRun(
6540 "o.foo = 17;"
6541 "var receiver = {};"
6542 "receiver.__proto__ = o;"
6543 "var result = 0;"
6544 "var saved_result = 0;"
6545 "for (var i = 0; i < 100; i++) {"
6546 " result = receiver.method(41);"
6547 " if (i == 50) {"
6548 " saved_result = result;"
6549 " receiver = {method: function(x) { return x - 1 }};"
6550 " }"
6551 "}");
6552 CHECK_EQ(40, context->Global()->Get(v8_str("result"))->Int32Value());
6553 CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value());
6554 }
6555
5894 6556
5895 static int interceptor_call_count = 0; 6557 static int interceptor_call_count = 0;
5896 6558
5897 static v8::Handle<Value> InterceptorICRefErrorGetter(Local<String> name, 6559 static v8::Handle<Value> InterceptorICRefErrorGetter(Local<String> name,
5898 const AccessorInfo& info) { 6560 const AccessorInfo& info) {
5899 ApiTestFuzzer::Fuzz(); 6561 ApiTestFuzzer::Fuzz();
5900 if (v8_str("x")->Equals(name) && interceptor_call_count++ < 20) { 6562 if (v8_str("x")->Equals(name) && interceptor_call_count++ < 20) {
5901 return call_ic_function2; 6563 return call_ic_function2;
5902 } 6564 }
5903 return v8::Handle<Value>(); 6565 return v8::Handle<Value>();
(...skipping 3016 matching lines...) Expand 10 before | Expand all | Expand 10 after
8920 CompileRun(source_exception); 9582 CompileRun(source_exception);
8921 other_context->Exit(); 9583 other_context->Exit();
8922 v8::internal::Heap::CollectAllGarbage(false); 9584 v8::internal::Heap::CollectAllGarbage(false);
8923 if (GetGlobalObjectsCount() == 1) break; 9585 if (GetGlobalObjectsCount() == 1) break;
8924 } 9586 }
8925 CHECK_GE(2, gc_count); 9587 CHECK_GE(2, gc_count);
8926 CHECK_EQ(1, GetGlobalObjectsCount()); 9588 CHECK_EQ(1, GetGlobalObjectsCount());
8927 9589
8928 other_context.Dispose(); 9590 other_context.Dispose();
8929 } 9591 }
9592
9593
9594 THREADED_TEST(ScriptOrigin) {
9595 v8::HandleScope scope;
9596 LocalContext env;
9597 v8::ScriptOrigin origin = v8::ScriptOrigin(v8::String::New("test"));
9598 v8::Handle<v8::String> script = v8::String::New(
9599 "function f() {}\n\nfunction g() {}");
9600 v8::Script::Compile(script, &origin)->Run();
9601 v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast(
9602 env->Global()->Get(v8::String::New("f")));
9603 v8::Local<v8::Function> g = v8::Local<v8::Function>::Cast(
9604 env->Global()->Get(v8::String::New("g")));
9605
9606 v8::ScriptOrigin script_origin_f = f->GetScriptOrigin();
9607 CHECK_EQ("test", *v8::String::AsciiValue(script_origin_f.ResourceName()));
9608 CHECK_EQ(0, script_origin_f.ResourceLineOffset()->Int32Value());
9609
9610 v8::ScriptOrigin script_origin_g = g->GetScriptOrigin();
9611 CHECK_EQ("test", *v8::String::AsciiValue(script_origin_g.ResourceName()));
9612 CHECK_EQ(0, script_origin_g.ResourceLineOffset()->Int32Value());
9613 }
9614
9615
9616 THREADED_TEST(ScriptLineNumber) {
9617 v8::HandleScope scope;
9618 LocalContext env;
9619 v8::ScriptOrigin origin = v8::ScriptOrigin(v8::String::New("test"));
9620 v8::Handle<v8::String> script = v8::String::New(
9621 "function f() {}\n\nfunction g() {}");
9622 v8::Script::Compile(script, &origin)->Run();
9623 v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast(
9624 env->Global()->Get(v8::String::New("f")));
9625 v8::Local<v8::Function> g = v8::Local<v8::Function>::Cast(
9626 env->Global()->Get(v8::String::New("g")));
9627 CHECK_EQ(0, f->GetScriptLineNumber());
9628 CHECK_EQ(2, g->GetScriptLineNumber());
9629 }
9630
9631
9632 static v8::Handle<Value> GetterWhichReturns42(Local<String> name,
9633 const AccessorInfo& info) {
9634 return v8_num(42);
9635 }
9636
9637
9638 static void SetterWhichSetsYOnThisTo23(Local<String> name,
9639 Local<Value> value,
9640 const AccessorInfo& info) {
9641 info.This()->Set(v8_str("y"), v8_num(23));
9642 }
9643
9644
9645 THREADED_TEST(SetterOnConstructorPrototype) {
9646 v8::HandleScope scope;
9647 Local<ObjectTemplate> templ = ObjectTemplate::New();
9648 templ->SetAccessor(v8_str("x"),
9649 GetterWhichReturns42,
9650 SetterWhichSetsYOnThisTo23);
9651 LocalContext context;
9652 context->Global()->Set(v8_str("P"), templ->NewInstance());
9653 CompileRun("function C1() {"
9654 " this.x = 23;"
9655 "};"
9656 "C1.prototype = P;"
9657 "function C2() {"
9658 " this.x = 23"
9659 "};"
9660 "C2.prototype = { };"
9661 "C2.prototype.__proto__ = P;");
9662
9663 v8::Local<v8::Script> script;
9664 script = v8::Script::Compile(v8_str("new C1();"));
9665 for (int i = 0; i < 10; i++) {
9666 v8::Handle<v8::Object> c1 = v8::Handle<v8::Object>::Cast(script->Run());
9667 CHECK_EQ(42, c1->Get(v8_str("x"))->Int32Value());
9668 CHECK_EQ(23, c1->Get(v8_str("y"))->Int32Value());
9669 }
9670
9671 script = v8::Script::Compile(v8_str("new C2();"));
9672 for (int i = 0; i < 10; i++) {
9673 v8::Handle<v8::Object> c2 = v8::Handle<v8::Object>::Cast(script->Run());
9674 CHECK_EQ(42, c2->Get(v8_str("x"))->Int32Value());
9675 CHECK_EQ(23, c2->Get(v8_str("y"))->Int32Value());
9676 }
9677 }
9678
9679
9680 static v8::Handle<Value> NamedPropertyGetterWhichReturns42(
9681 Local<String> name, const AccessorInfo& info) {
9682 return v8_num(42);
9683 }
9684
9685
9686 static v8::Handle<Value> NamedPropertySetterWhichSetsYOnThisTo23(
9687 Local<String> name, Local<Value> value, const AccessorInfo& info) {
9688 if (name->Equals(v8_str("x"))) {
9689 info.This()->Set(v8_str("y"), v8_num(23));
9690 }
9691 return v8::Handle<Value>();
9692 }
9693
9694
9695 THREADED_TEST(InterceptorOnConstructorPrototype) {
9696 v8::HandleScope scope;
9697 Local<ObjectTemplate> templ = ObjectTemplate::New();
9698 templ->SetNamedPropertyHandler(NamedPropertyGetterWhichReturns42,
9699 NamedPropertySetterWhichSetsYOnThisTo23);
9700 LocalContext context;
9701 context->Global()->Set(v8_str("P"), templ->NewInstance());
9702 CompileRun("function C1() {"
9703 " this.x = 23;"
9704 "};"
9705 "C1.prototype = P;"
9706 "function C2() {"
9707 " this.x = 23"
9708 "};"
9709 "C2.prototype = { };"
9710 "C2.prototype.__proto__ = P;");
9711
9712 v8::Local<v8::Script> script;
9713 script = v8::Script::Compile(v8_str("new C1();"));
9714 for (int i = 0; i < 10; i++) {
9715 v8::Handle<v8::Object> c1 = v8::Handle<v8::Object>::Cast(script->Run());
9716 CHECK_EQ(23, c1->Get(v8_str("x"))->Int32Value());
9717 CHECK_EQ(42, c1->Get(v8_str("y"))->Int32Value());
9718 }
9719
9720 script = v8::Script::Compile(v8_str("new C2();"));
9721 for (int i = 0; i < 10; i++) {
9722 v8::Handle<v8::Object> c2 = v8::Handle<v8::Object>::Cast(script->Run());
9723 CHECK_EQ(23, c2->Get(v8_str("x"))->Int32Value());
9724 CHECK_EQ(42, c2->Get(v8_str("y"))->Int32Value());
9725 }
9726 }
OLDNEW
« no previous file with comments | « src/x64/virtual-frame-x64.cc ('k') | test/cctest/test-compiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698