OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 16575 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16586 v8::V8::SetFatalErrorHandler(CountingErrorCallback); | 16586 v8::V8::SetFatalErrorHandler(CountingErrorCallback); |
16587 v8::Utils::ReportApiFailure("StringEmpty()", "Kill V8"); | 16587 v8::Utils::ReportApiFailure("StringEmpty()", "Kill V8"); |
16588 i::Isolate::Current()->TearDown(); | 16588 i::Isolate::Current()->TearDown(); |
16589 CHECK(!i::Internals::IsInitialized(isolate)); | 16589 CHECK(!i::Internals::IsInitialized(isolate)); |
16590 CHECK_EQ(1, fatal_error_callback_counter); | 16590 CHECK_EQ(1, fatal_error_callback_counter); |
16591 CHECK(v8::String::Empty().IsEmpty()); | 16591 CHECK(v8::String::Empty().IsEmpty()); |
16592 CHECK_EQ(2, fatal_error_callback_counter); | 16592 CHECK_EQ(2, fatal_error_callback_counter); |
16593 CHECK(v8::String::Empty(isolate).IsEmpty()); | 16593 CHECK(v8::String::Empty(isolate).IsEmpty()); |
16594 CHECK_EQ(3, fatal_error_callback_counter); | 16594 CHECK_EQ(3, fatal_error_callback_counter); |
16595 } | 16595 } |
| 16596 |
| 16597 |
| 16598 static int instance_checked_getter_count = 0; |
| 16599 static Handle<Value> InstanceCheckedGetter(Local<String> name, |
| 16600 const AccessorInfo& info) { |
| 16601 CHECK_EQ(name, v8_str("foo")); |
| 16602 instance_checked_getter_count++; |
| 16603 return v8_num(11); |
| 16604 } |
| 16605 |
| 16606 |
| 16607 static int instance_checked_setter_count = 0; |
| 16608 static void InstanceCheckedSetter(Local<String> name, |
| 16609 Local<Value> value, |
| 16610 const AccessorInfo& info) { |
| 16611 CHECK_EQ(name, v8_str("foo")); |
| 16612 CHECK_EQ(value, v8_num(23)); |
| 16613 instance_checked_setter_count++; |
| 16614 } |
| 16615 |
| 16616 |
| 16617 static void CheckInstanceCheckedResult(int getters, |
| 16618 int setters, |
| 16619 bool expects_callbacks, |
| 16620 TryCatch* try_catch) { |
| 16621 if (expects_callbacks) { |
| 16622 CHECK(!try_catch->HasCaught()); |
| 16623 CHECK_EQ(getters, instance_checked_getter_count); |
| 16624 CHECK_EQ(setters, instance_checked_setter_count); |
| 16625 } else { |
| 16626 CHECK(try_catch->HasCaught()); |
| 16627 CHECK_EQ(0, instance_checked_getter_count); |
| 16628 CHECK_EQ(0, instance_checked_setter_count); |
| 16629 } |
| 16630 try_catch->Reset(); |
| 16631 } |
| 16632 |
| 16633 |
| 16634 static void CheckInstanceCheckedAccessors(bool expects_callbacks) { |
| 16635 instance_checked_getter_count = 0; |
| 16636 instance_checked_setter_count = 0; |
| 16637 TryCatch try_catch; |
| 16638 |
| 16639 // Test path through generic runtime code. |
| 16640 CompileRun("obj.foo"); |
| 16641 CheckInstanceCheckedResult(1, 0, expects_callbacks, &try_catch); |
| 16642 CompileRun("obj.foo = 23"); |
| 16643 CheckInstanceCheckedResult(1, 1, expects_callbacks, &try_catch); |
| 16644 |
| 16645 // Test path through generated LoadIC and StoredIC. |
| 16646 CompileRun("function test_get(o) { o.foo; }" |
| 16647 "test_get(obj);"); |
| 16648 CheckInstanceCheckedResult(2, 1, expects_callbacks, &try_catch); |
| 16649 CompileRun("test_get(obj);"); |
| 16650 CheckInstanceCheckedResult(3, 1, expects_callbacks, &try_catch); |
| 16651 CompileRun("test_get(obj);"); |
| 16652 CheckInstanceCheckedResult(4, 1, expects_callbacks, &try_catch); |
| 16653 CompileRun("function test_set(o) { o.foo = 23; }" |
| 16654 "test_set(obj);"); |
| 16655 CheckInstanceCheckedResult(4, 2, expects_callbacks, &try_catch); |
| 16656 CompileRun("test_set(obj);"); |
| 16657 CheckInstanceCheckedResult(4, 3, expects_callbacks, &try_catch); |
| 16658 CompileRun("test_set(obj);"); |
| 16659 CheckInstanceCheckedResult(4, 4, expects_callbacks, &try_catch); |
| 16660 |
| 16661 // Test path through optimized code. |
| 16662 CompileRun("%OptimizeFunctionOnNextCall(test_get);" |
| 16663 "test_get(obj);"); |
| 16664 CheckInstanceCheckedResult(5, 4, expects_callbacks, &try_catch); |
| 16665 CompileRun("%OptimizeFunctionOnNextCall(test_set);" |
| 16666 "test_set(obj);"); |
| 16667 CheckInstanceCheckedResult(5, 5, expects_callbacks, &try_catch); |
| 16668 |
| 16669 // Cleanup so that closures start out fresh in next check. |
| 16670 CompileRun("%DeoptimizeFunction(test_get);" |
| 16671 "%ClearFunctionTypeFeedback(test_get);" |
| 16672 "%DeoptimizeFunction(test_set);" |
| 16673 "%ClearFunctionTypeFeedback(test_set);"); |
| 16674 } |
| 16675 |
| 16676 |
| 16677 THREADED_TEST(InstanceCheckOnInstanceAccessor) { |
| 16678 v8::internal::FLAG_allow_natives_syntax = true; |
| 16679 v8::HandleScope scope; |
| 16680 LocalContext context; |
| 16681 |
| 16682 Local<FunctionTemplate> templ = FunctionTemplate::New(); |
| 16683 Local<ObjectTemplate> inst = templ->InstanceTemplate(); |
| 16684 inst->SetAccessor(v8_str("foo"), |
| 16685 InstanceCheckedGetter, InstanceCheckedSetter, |
| 16686 Handle<Value>(), |
| 16687 v8::DEFAULT, |
| 16688 v8::None, |
| 16689 v8::AccessorSignature::New(templ)); |
| 16690 context->Global()->Set(v8_str("f"), templ->GetFunction()); |
| 16691 |
| 16692 printf("Testing positive ...\n"); |
| 16693 CompileRun("var obj = new f();"); |
| 16694 CHECK(templ->HasInstance(context->Global()->Get(v8_str("obj")))); |
| 16695 CheckInstanceCheckedAccessors(true); |
| 16696 |
| 16697 printf("Testing negative ...\n"); |
| 16698 CompileRun("var obj = {};" |
| 16699 "obj.__proto__ = new f();"); |
| 16700 CHECK(!templ->HasInstance(context->Global()->Get(v8_str("obj")))); |
| 16701 CheckInstanceCheckedAccessors(false); |
| 16702 } |
| 16703 |
| 16704 |
| 16705 THREADED_TEST(InstanceCheckOnInstanceAccessorWithInterceptor) { |
| 16706 v8::internal::FLAG_allow_natives_syntax = true; |
| 16707 v8::HandleScope scope; |
| 16708 LocalContext context; |
| 16709 |
| 16710 Local<FunctionTemplate> templ = FunctionTemplate::New(); |
| 16711 Local<ObjectTemplate> inst = templ->InstanceTemplate(); |
| 16712 AddInterceptor(templ, EmptyInterceptorGetter, EmptyInterceptorSetter); |
| 16713 inst->SetAccessor(v8_str("foo"), |
| 16714 InstanceCheckedGetter, InstanceCheckedSetter, |
| 16715 Handle<Value>(), |
| 16716 v8::DEFAULT, |
| 16717 v8::None, |
| 16718 v8::AccessorSignature::New(templ)); |
| 16719 context->Global()->Set(v8_str("f"), templ->GetFunction()); |
| 16720 |
| 16721 printf("Testing positive ...\n"); |
| 16722 CompileRun("var obj = new f();"); |
| 16723 CHECK(templ->HasInstance(context->Global()->Get(v8_str("obj")))); |
| 16724 CheckInstanceCheckedAccessors(true); |
| 16725 |
| 16726 printf("Testing negative ...\n"); |
| 16727 CompileRun("var obj = {};" |
| 16728 "obj.__proto__ = new f();"); |
| 16729 CHECK(!templ->HasInstance(context->Global()->Get(v8_str("obj")))); |
| 16730 CheckInstanceCheckedAccessors(false); |
| 16731 } |
| 16732 |
| 16733 |
| 16734 THREADED_TEST(InstanceCheckOnPrototypeAccessor) { |
| 16735 v8::internal::FLAG_allow_natives_syntax = true; |
| 16736 v8::HandleScope scope; |
| 16737 LocalContext context; |
| 16738 |
| 16739 Local<FunctionTemplate> templ = FunctionTemplate::New(); |
| 16740 Local<ObjectTemplate> proto = templ->PrototypeTemplate(); |
| 16741 proto->SetAccessor(v8_str("foo"), |
| 16742 InstanceCheckedGetter, InstanceCheckedSetter, |
| 16743 Handle<Value>(), |
| 16744 v8::DEFAULT, |
| 16745 v8::None, |
| 16746 v8::AccessorSignature::New(templ)); |
| 16747 context->Global()->Set(v8_str("f"), templ->GetFunction()); |
| 16748 |
| 16749 printf("Testing positive ...\n"); |
| 16750 CompileRun("var obj = new f();"); |
| 16751 CHECK(templ->HasInstance(context->Global()->Get(v8_str("obj")))); |
| 16752 CheckInstanceCheckedAccessors(true); |
| 16753 |
| 16754 printf("Testing negative ...\n"); |
| 16755 CompileRun("var obj = {};" |
| 16756 "obj.__proto__ = new f();"); |
| 16757 CHECK(!templ->HasInstance(context->Global()->Get(v8_str("obj")))); |
| 16758 CheckInstanceCheckedAccessors(false); |
| 16759 |
| 16760 printf("Testing positive with modified prototype chain ...\n"); |
| 16761 CompileRun("var obj = new f();" |
| 16762 "var pro = {};" |
| 16763 "pro.__proto__ = obj.__proto__;" |
| 16764 "obj.__proto__ = pro;"); |
| 16765 CHECK(templ->HasInstance(context->Global()->Get(v8_str("obj")))); |
| 16766 CheckInstanceCheckedAccessors(true); |
| 16767 } |
OLD | NEW |