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 21801 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
21812 RequestInterruptTestBase() | 21812 RequestInterruptTestBase() |
21813 : env_(), | 21813 : env_(), |
21814 isolate_(env_->GetIsolate()), | 21814 isolate_(env_->GetIsolate()), |
21815 sem_(0), | 21815 sem_(0), |
21816 warmup_(20000), | 21816 warmup_(20000), |
21817 should_continue_(true) { | 21817 should_continue_(true) { |
21818 } | 21818 } |
21819 | 21819 |
21820 virtual ~RequestInterruptTestBase() { } | 21820 virtual ~RequestInterruptTestBase() { } |
21821 | 21821 |
| 21822 virtual void StartInterruptThread() = 0; |
| 21823 |
21822 virtual void TestBody() = 0; | 21824 virtual void TestBody() = 0; |
21823 | 21825 |
21824 void RunTest() { | 21826 void RunTest() { |
21825 InterruptThread i_thread(this); | 21827 StartInterruptThread(); |
21826 i_thread.Start(); | |
21827 | 21828 |
21828 v8::HandleScope handle_scope(isolate_); | 21829 v8::HandleScope handle_scope(isolate_); |
21829 | 21830 |
21830 TestBody(); | 21831 TestBody(); |
21831 | 21832 |
21832 isolate_->ClearInterrupt(); | 21833 isolate_->ClearInterrupt(); |
21833 | 21834 |
21834 // Verify we arrived here because interruptor was called | 21835 // Verify we arrived here because interruptor was called |
21835 // not due to a bug causing us to exit the loop too early. | 21836 // not due to a bug causing us to exit the loop too early. |
21836 CHECK(!should_continue()); | 21837 CHECK(!should_continue()); |
21837 } | 21838 } |
21838 | 21839 |
21839 void WakeUpInterruptor() { | 21840 void WakeUpInterruptor() { |
21840 sem_.Signal(); | 21841 sem_.Signal(); |
21841 } | 21842 } |
21842 | 21843 |
21843 bool should_continue() const { return should_continue_; } | 21844 bool should_continue() const { return should_continue_; } |
21844 | 21845 |
21845 bool ShouldContinue() { | 21846 bool ShouldContinue() { |
21846 if (warmup_ > 0) { | 21847 if (warmup_ > 0) { |
21847 if (--warmup_ == 0) { | 21848 if (--warmup_ == 0) { |
21848 WakeUpInterruptor(); | 21849 WakeUpInterruptor(); |
21849 } | 21850 } |
21850 } | 21851 } |
21851 | 21852 |
21852 return should_continue_; | 21853 return should_continue_; |
21853 } | 21854 } |
21854 | 21855 |
21855 protected: | |
21856 static void ShouldContinueCallback( | 21856 static void ShouldContinueCallback( |
21857 const v8::FunctionCallbackInfo<Value>& info) { | 21857 const v8::FunctionCallbackInfo<Value>& info) { |
21858 RequestInterruptTestBase* test = | 21858 RequestInterruptTestBase* test = |
21859 reinterpret_cast<RequestInterruptTestBase*>( | 21859 reinterpret_cast<RequestInterruptTestBase*>( |
21860 info.Data().As<v8::External>()->Value()); | 21860 info.Data().As<v8::External>()->Value()); |
21861 info.GetReturnValue().Set(test->ShouldContinue()); | 21861 info.GetReturnValue().Set(test->ShouldContinue()); |
21862 } | 21862 } |
21863 | 21863 |
| 21864 LocalContext env_; |
| 21865 v8::Isolate* isolate_; |
| 21866 i::Semaphore sem_; |
| 21867 int warmup_; |
| 21868 bool should_continue_; |
| 21869 }; |
| 21870 |
| 21871 |
| 21872 class RequestInterruptTestBaseWithSimpleInterrupt |
| 21873 : public RequestInterruptTestBase { |
| 21874 public: |
| 21875 RequestInterruptTestBaseWithSimpleInterrupt() : i_thread(this) { } |
| 21876 |
| 21877 virtual void StartInterruptThread() { |
| 21878 i_thread.Start(); |
| 21879 } |
| 21880 |
| 21881 private: |
21864 class InterruptThread : public i::Thread { | 21882 class InterruptThread : public i::Thread { |
21865 public: | 21883 public: |
21866 explicit InterruptThread(RequestInterruptTestBase* test) | 21884 explicit InterruptThread(RequestInterruptTestBase* test) |
21867 : Thread("RequestInterruptTest"), test_(test) {} | 21885 : Thread("RequestInterruptTest"), test_(test) {} |
21868 | 21886 |
21869 virtual void Run() { | 21887 virtual void Run() { |
21870 test_->sem_.Wait(); | 21888 test_->sem_.Wait(); |
21871 test_->isolate_->RequestInterrupt(&OnInterrupt, test_); | 21889 test_->isolate_->RequestInterrupt(&OnInterrupt, test_); |
21872 } | 21890 } |
21873 | 21891 |
21874 static void OnInterrupt(v8::Isolate* isolate, void* data) { | 21892 static void OnInterrupt(v8::Isolate* isolate, void* data) { |
21875 reinterpret_cast<RequestInterruptTestBase*>(data)-> | 21893 reinterpret_cast<RequestInterruptTestBase*>(data)-> |
21876 should_continue_ = false; | 21894 should_continue_ = false; |
21877 } | 21895 } |
21878 | 21896 |
21879 private: | 21897 private: |
21880 RequestInterruptTestBase* test_; | 21898 RequestInterruptTestBase* test_; |
21881 }; | 21899 }; |
21882 | 21900 |
21883 LocalContext env_; | 21901 InterruptThread i_thread; |
21884 v8::Isolate* isolate_; | |
21885 i::Semaphore sem_; | |
21886 int warmup_; | |
21887 bool should_continue_; | |
21888 }; | 21902 }; |
21889 | 21903 |
21890 | 21904 |
21891 class RequestInterruptTestWithFunctionCall : public RequestInterruptTestBase { | 21905 class RequestInterruptTestWithFunctionCall |
| 21906 : public RequestInterruptTestBaseWithSimpleInterrupt { |
21892 public: | 21907 public: |
21893 virtual void TestBody() { | 21908 virtual void TestBody() { |
21894 Local<Function> func = Function::New( | 21909 Local<Function> func = Function::New( |
21895 isolate_, ShouldContinueCallback, v8::External::New(isolate_, this)); | 21910 isolate_, ShouldContinueCallback, v8::External::New(isolate_, this)); |
21896 env_->Global()->Set(v8_str("ShouldContinue"), func); | 21911 env_->Global()->Set(v8_str("ShouldContinue"), func); |
21897 | 21912 |
21898 CompileRun("while (ShouldContinue()) { }"); | 21913 CompileRun("while (ShouldContinue()) { }"); |
21899 } | 21914 } |
21900 }; | 21915 }; |
21901 | 21916 |
21902 | 21917 |
21903 class RequestInterruptTestWithMethodCall : public RequestInterruptTestBase { | 21918 class RequestInterruptTestWithMethodCall |
| 21919 : public RequestInterruptTestBaseWithSimpleInterrupt { |
21904 public: | 21920 public: |
21905 virtual void TestBody() { | 21921 virtual void TestBody() { |
21906 v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate_); | 21922 v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate_); |
21907 v8::Local<v8::Template> proto = t->PrototypeTemplate(); | 21923 v8::Local<v8::Template> proto = t->PrototypeTemplate(); |
21908 proto->Set(v8_str("shouldContinue"), Function::New( | 21924 proto->Set(v8_str("shouldContinue"), Function::New( |
21909 isolate_, ShouldContinueCallback, v8::External::New(isolate_, this))); | 21925 isolate_, ShouldContinueCallback, v8::External::New(isolate_, this))); |
21910 env_->Global()->Set(v8_str("Klass"), t->GetFunction()); | 21926 env_->Global()->Set(v8_str("Klass"), t->GetFunction()); |
21911 | 21927 |
21912 CompileRun("var obj = new Klass; while (obj.shouldContinue()) { }"); | 21928 CompileRun("var obj = new Klass; while (obj.shouldContinue()) { }"); |
21913 } | 21929 } |
21914 }; | 21930 }; |
21915 | 21931 |
21916 | 21932 |
21917 class RequestInterruptTestWithAccessor : public RequestInterruptTestBase { | 21933 class RequestInterruptTestWithAccessor |
| 21934 : public RequestInterruptTestBaseWithSimpleInterrupt { |
21918 public: | 21935 public: |
21919 virtual void TestBody() { | 21936 virtual void TestBody() { |
21920 v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate_); | 21937 v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate_); |
21921 v8::Local<v8::Template> proto = t->PrototypeTemplate(); | 21938 v8::Local<v8::Template> proto = t->PrototypeTemplate(); |
21922 proto->SetAccessorProperty(v8_str("shouldContinue"), FunctionTemplate::New( | 21939 proto->SetAccessorProperty(v8_str("shouldContinue"), FunctionTemplate::New( |
21923 isolate_, ShouldContinueCallback, v8::External::New(isolate_, this))); | 21940 isolate_, ShouldContinueCallback, v8::External::New(isolate_, this))); |
21924 env_->Global()->Set(v8_str("Klass"), t->GetFunction()); | 21941 env_->Global()->Set(v8_str("Klass"), t->GetFunction()); |
21925 | 21942 |
21926 CompileRun("var obj = new Klass; while (obj.shouldContinue) { }"); | 21943 CompileRun("var obj = new Klass; while (obj.shouldContinue) { }"); |
21927 } | 21944 } |
21928 }; | 21945 }; |
21929 | 21946 |
21930 | 21947 |
21931 class RequestInterruptTestWithNativeAccessor : public RequestInterruptTestBase { | 21948 class RequestInterruptTestWithNativeAccessor |
| 21949 : public RequestInterruptTestBaseWithSimpleInterrupt { |
21932 public: | 21950 public: |
21933 virtual void TestBody() { | 21951 virtual void TestBody() { |
21934 v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate_); | 21952 v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate_); |
21935 t->InstanceTemplate()->SetNativeDataProperty( | 21953 t->InstanceTemplate()->SetNativeDataProperty( |
21936 v8_str("shouldContinue"), | 21954 v8_str("shouldContinue"), |
21937 &ShouldContinueNativeGetter, | 21955 &ShouldContinueNativeGetter, |
21938 NULL, | 21956 NULL, |
21939 v8::External::New(isolate_, this)); | 21957 v8::External::New(isolate_, this)); |
21940 env_->Global()->Set(v8_str("Klass"), t->GetFunction()); | 21958 env_->Global()->Set(v8_str("Klass"), t->GetFunction()); |
21941 | 21959 |
21942 CompileRun("var obj = new Klass; while (obj.shouldContinue) { }"); | 21960 CompileRun("var obj = new Klass; while (obj.shouldContinue) { }"); |
21943 } | 21961 } |
21944 | 21962 |
21945 private: | 21963 private: |
21946 static void ShouldContinueNativeGetter( | 21964 static void ShouldContinueNativeGetter( |
21947 Local<String> property, | 21965 Local<String> property, |
21948 const v8::PropertyCallbackInfo<v8::Value>& info) { | 21966 const v8::PropertyCallbackInfo<v8::Value>& info) { |
21949 RequestInterruptTestBase* test = | 21967 RequestInterruptTestBase* test = |
21950 reinterpret_cast<RequestInterruptTestBase*>( | 21968 reinterpret_cast<RequestInterruptTestBase*>( |
21951 info.Data().As<v8::External>()->Value()); | 21969 info.Data().As<v8::External>()->Value()); |
21952 info.GetReturnValue().Set(test->ShouldContinue()); | 21970 info.GetReturnValue().Set(test->ShouldContinue()); |
21953 } | 21971 } |
21954 }; | 21972 }; |
21955 | 21973 |
21956 | 21974 |
21957 class RequestInterruptTestWithMethodCallAndInterceptor | 21975 class RequestInterruptTestWithMethodCallAndInterceptor |
21958 : public RequestInterruptTestBase { | 21976 : public RequestInterruptTestBaseWithSimpleInterrupt { |
21959 public: | 21977 public: |
21960 virtual void TestBody() { | 21978 virtual void TestBody() { |
21961 v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate_); | 21979 v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate_); |
21962 v8::Local<v8::Template> proto = t->PrototypeTemplate(); | 21980 v8::Local<v8::Template> proto = t->PrototypeTemplate(); |
21963 proto->Set(v8_str("shouldContinue"), Function::New( | 21981 proto->Set(v8_str("shouldContinue"), Function::New( |
21964 isolate_, ShouldContinueCallback, v8::External::New(isolate_, this))); | 21982 isolate_, ShouldContinueCallback, v8::External::New(isolate_, this))); |
21965 v8::Local<v8::ObjectTemplate> instance_template = t->InstanceTemplate(); | 21983 v8::Local<v8::ObjectTemplate> instance_template = t->InstanceTemplate(); |
21966 instance_template->SetNamedPropertyHandler(EmptyInterceptor); | 21984 instance_template->SetNamedPropertyHandler(EmptyInterceptor); |
21967 | 21985 |
21968 env_->Global()->Set(v8_str("Klass"), t->GetFunction()); | 21986 env_->Global()->Set(v8_str("Klass"), t->GetFunction()); |
21969 | 21987 |
21970 CompileRun("var obj = new Klass; while (obj.shouldContinue()) { }"); | 21988 CompileRun("var obj = new Klass; while (obj.shouldContinue()) { }"); |
21971 } | 21989 } |
21972 | 21990 |
21973 private: | 21991 private: |
21974 static void EmptyInterceptor( | 21992 static void EmptyInterceptor( |
21975 Local<String> property, | 21993 Local<String> property, |
21976 const v8::PropertyCallbackInfo<v8::Value>& info) { | 21994 const v8::PropertyCallbackInfo<v8::Value>& info) { |
21977 } | 21995 } |
21978 }; | 21996 }; |
21979 | 21997 |
21980 | 21998 |
21981 class RequestInterruptTestWithMathAbs : public RequestInterruptTestBase { | 21999 class RequestInterruptTestWithMathAbs |
| 22000 : public RequestInterruptTestBaseWithSimpleInterrupt { |
21982 public: | 22001 public: |
21983 virtual void TestBody() { | 22002 virtual void TestBody() { |
21984 env_->Global()->Set(v8_str("WakeUpInterruptor"), Function::New( | 22003 env_->Global()->Set(v8_str("WakeUpInterruptor"), Function::New( |
21985 isolate_, | 22004 isolate_, |
21986 WakeUpInterruptorCallback, | 22005 WakeUpInterruptorCallback, |
21987 v8::External::New(isolate_, this))); | 22006 v8::External::New(isolate_, this))); |
21988 | 22007 |
21989 env_->Global()->Set(v8_str("ShouldContinue"), Function::New( | 22008 env_->Global()->Set(v8_str("ShouldContinue"), Function::New( |
21990 isolate_, | 22009 isolate_, |
21991 ShouldContinueCallback, | 22010 ShouldContinueCallback, |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
22055 TEST(RequestInterruptTestWithMethodCallAndInterceptor) { | 22074 TEST(RequestInterruptTestWithMethodCallAndInterceptor) { |
22056 RequestInterruptTestWithMethodCallAndInterceptor().RunTest(); | 22075 RequestInterruptTestWithMethodCallAndInterceptor().RunTest(); |
22057 } | 22076 } |
22058 | 22077 |
22059 | 22078 |
22060 TEST(RequestInterruptTestWithMathAbs) { | 22079 TEST(RequestInterruptTestWithMathAbs) { |
22061 RequestInterruptTestWithMathAbs().RunTest(); | 22080 RequestInterruptTestWithMathAbs().RunTest(); |
22062 } | 22081 } |
22063 | 22082 |
22064 | 22083 |
| 22084 class ClearInterruptFromAnotherThread |
| 22085 : public RequestInterruptTestBase { |
| 22086 public: |
| 22087 ClearInterruptFromAnotherThread() : i_thread(this), sem2_(0) { } |
| 22088 |
| 22089 virtual void StartInterruptThread() { |
| 22090 i_thread.Start(); |
| 22091 } |
| 22092 |
| 22093 virtual void TestBody() { |
| 22094 Local<Function> func = Function::New( |
| 22095 isolate_, ShouldContinueCallback, v8::External::New(isolate_, this)); |
| 22096 env_->Global()->Set(v8_str("ShouldContinue"), func); |
| 22097 |
| 22098 CompileRun("while (ShouldContinue()) { }"); |
| 22099 } |
| 22100 |
| 22101 private: |
| 22102 class InterruptThread : public i::Thread { |
| 22103 public: |
| 22104 explicit InterruptThread(ClearInterruptFromAnotherThread* test) |
| 22105 : Thread("RequestInterruptTest"), test_(test) {} |
| 22106 |
| 22107 virtual void Run() { |
| 22108 test_->sem_.Wait(); |
| 22109 test_->isolate_->RequestInterrupt(&OnInterrupt, test_); |
| 22110 test_->sem_.Wait(); |
| 22111 test_->isolate_->ClearInterrupt(); |
| 22112 test_->sem2_.Signal(); |
| 22113 } |
| 22114 |
| 22115 static void OnInterrupt(v8::Isolate* isolate, void* data) { |
| 22116 ClearInterruptFromAnotherThread* test = |
| 22117 reinterpret_cast<ClearInterruptFromAnotherThread*>(data); |
| 22118 test->sem_.Signal(); |
| 22119 bool success = test->sem2_.WaitFor(i::TimeDelta::FromSeconds(2)); |
| 22120 // Crash instead of timeout to make this failure more prominent. |
| 22121 CHECK(success); |
| 22122 test->should_continue_ = false; |
| 22123 } |
| 22124 |
| 22125 private: |
| 22126 ClearInterruptFromAnotherThread* test_; |
| 22127 }; |
| 22128 |
| 22129 InterruptThread i_thread; |
| 22130 i::Semaphore sem2_; |
| 22131 }; |
| 22132 |
| 22133 |
| 22134 TEST(ClearInterruptFromAnotherThread) { |
| 22135 ClearInterruptFromAnotherThread().RunTest(); |
| 22136 } |
| 22137 |
| 22138 |
22065 static Local<Value> function_new_expected_env; | 22139 static Local<Value> function_new_expected_env; |
22066 static void FunctionNewCallback(const v8::FunctionCallbackInfo<Value>& info) { | 22140 static void FunctionNewCallback(const v8::FunctionCallbackInfo<Value>& info) { |
22067 CHECK_EQ(function_new_expected_env, info.Data()); | 22141 CHECK_EQ(function_new_expected_env, info.Data()); |
22068 info.GetReturnValue().Set(17); | 22142 info.GetReturnValue().Set(17); |
22069 } | 22143 } |
22070 | 22144 |
22071 | 22145 |
22072 THREADED_TEST(FunctionNew) { | 22146 THREADED_TEST(FunctionNew) { |
22073 LocalContext env; | 22147 LocalContext env; |
22074 v8::Isolate* isolate = env->GetIsolate(); | 22148 v8::Isolate* isolate = env->GetIsolate(); |
(...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
22533 v8::internal::FLAG_stack_size = 150; | 22607 v8::internal::FLAG_stack_size = 150; |
22534 LocalContext current; | 22608 LocalContext current; |
22535 v8::Isolate* isolate = current->GetIsolate(); | 22609 v8::Isolate* isolate = current->GetIsolate(); |
22536 v8::HandleScope scope(isolate); | 22610 v8::HandleScope scope(isolate); |
22537 V8::SetCaptureStackTraceForUncaughtExceptions( | 22611 V8::SetCaptureStackTraceForUncaughtExceptions( |
22538 true, 10, v8::StackTrace::kDetailed); | 22612 true, 10, v8::StackTrace::kDetailed); |
22539 v8::TryCatch try_catch; | 22613 v8::TryCatch try_catch; |
22540 CompileRun("(function f(x) { f(x+1); })(0)"); | 22614 CompileRun("(function f(x) { f(x+1); })(0)"); |
22541 CHECK(try_catch.HasCaught()); | 22615 CHECK(try_catch.HasCaught()); |
22542 } | 22616 } |
OLD | NEW |