| OLD | NEW |
| 1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 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 17 matching lines...) Expand all Loading... |
| 28 #include <v8.h> | 28 #include <v8.h> |
| 29 #include <v8-testing.h> | 29 #include <v8-testing.h> |
| 30 #include <assert.h> | 30 #include <assert.h> |
| 31 #include <fcntl.h> | 31 #include <fcntl.h> |
| 32 #include <string.h> | 32 #include <string.h> |
| 33 #include <stdio.h> | 33 #include <stdio.h> |
| 34 #include <stdlib.h> | 34 #include <stdlib.h> |
| 35 | 35 |
| 36 #include "../src/v8.h" | 36 #include "../src/v8.h" |
| 37 | 37 |
| 38 // TODO(isolates): | 38 #if !defined(_WIN32) && !defined(_WIN64) |
| 39 // o Either use V8 internal platform stuff for every platform or | |
| 40 // re-implement it. | |
| 41 // o Do not assume not WIN32 implies pthreads. | |
| 42 #ifndef WIN32 | |
| 43 #include <pthread.h> // NOLINT | |
| 44 #include <unistd.h> // NOLINT | 39 #include <unistd.h> // NOLINT |
| 45 #endif | 40 #endif |
| 46 | 41 |
| 47 static void ExitShell(int exit_code) { | 42 static void ExitShell(int exit_code) { |
| 48 // Use _exit instead of exit to avoid races between isolate | 43 // Use _exit instead of exit to avoid races between isolate |
| 49 // threads and static destructors. | 44 // threads and static destructors. |
| 50 fflush(stdout); | 45 fflush(stdout); |
| 51 fflush(stderr); | 46 fflush(stderr); |
| 52 _exit(exit_code); | 47 _exit(exit_code); |
| 53 } | 48 } |
| 54 | 49 |
| 55 v8::Persistent<v8::Context> CreateShellContext(); | 50 v8::Persistent<v8::Context> CreateShellContext(); |
| 56 void RunShell(v8::Handle<v8::Context> context); | 51 void RunShell(v8::Handle<v8::Context> context); |
| 57 bool ExecuteString(v8::Handle<v8::String> source, | 52 bool ExecuteString(v8::Handle<v8::String> source, |
| 58 v8::Handle<v8::Value> name, | 53 v8::Handle<v8::Value> name, |
| 59 bool print_result, | 54 bool print_result, |
| 60 bool report_exceptions); | 55 bool report_exceptions); |
| 61 v8::Handle<v8::Value> Print(const v8::Arguments& args); | 56 v8::Handle<v8::Value> Print(const v8::Arguments& args); |
| 62 v8::Handle<v8::Value> Read(const v8::Arguments& args); | 57 v8::Handle<v8::Value> Read(const v8::Arguments& args); |
| 63 v8::Handle<v8::Value> Load(const v8::Arguments& args); | 58 v8::Handle<v8::Value> Load(const v8::Arguments& args); |
| 64 v8::Handle<v8::Value> Quit(const v8::Arguments& args); | 59 v8::Handle<v8::Value> Quit(const v8::Arguments& args); |
| 65 v8::Handle<v8::Value> Version(const v8::Arguments& args); | 60 v8::Handle<v8::Value> Version(const v8::Arguments& args); |
| 66 v8::Handle<v8::String> ReadFile(const char* name); | 61 v8::Handle<v8::String> ReadFile(const char* name); |
| 67 void ReportException(v8::TryCatch* handler); | 62 void ReportException(v8::TryCatch* handler); |
| 68 | 63 |
| 69 | 64 |
| 70 #ifndef WIN32 | |
| 71 void* IsolateThreadEntry(void* arg); | |
| 72 #endif | |
| 73 | |
| 74 static bool last_run = true; | 65 static bool last_run = true; |
| 75 | 66 |
| 76 class SourceGroup { | 67 class SourceGroup { |
| 77 public: | 68 public: |
| 78 SourceGroup() : argv_(NULL), | 69 SourceGroup() : argv_(NULL), |
| 79 begin_offset_(0), | 70 begin_offset_(0), |
| 80 end_offset_(0), | 71 end_offset_(0), |
| 81 next_semaphore_(NULL), | 72 next_semaphore_(v8::internal::OS::CreateSemaphore(0)), |
| 82 done_semaphore_(NULL) { | 73 done_semaphore_(v8::internal::OS::CreateSemaphore(0)), |
| 83 #ifndef WIN32 | 74 thread_(NULL) { } |
| 84 next_semaphore_ = v8::internal::OS::CreateSemaphore(0); | |
| 85 done_semaphore_ = v8::internal::OS::CreateSemaphore(0); | |
| 86 thread_ = 0; | |
| 87 #endif | |
| 88 } | |
| 89 | 75 |
| 90 void Begin(char** argv, int offset) { | 76 void Begin(char** argv, int offset) { |
| 91 argv_ = const_cast<const char**>(argv); | 77 argv_ = const_cast<const char**>(argv); |
| 92 begin_offset_ = offset; | 78 begin_offset_ = offset; |
| 93 } | 79 } |
| 94 | 80 |
| 95 void End(int offset) { end_offset_ = offset; } | 81 void End(int offset) { end_offset_ = offset; } |
| 96 | 82 |
| 97 void Execute() { | 83 void Execute() { |
| 98 for (int i = begin_offset_; i < end_offset_; ++i) { | 84 for (int i = begin_offset_; i < end_offset_; ++i) { |
| (...skipping 19 matching lines...) Expand all Loading... |
| 118 printf("Error reading '%s'\n", arg); | 104 printf("Error reading '%s'\n", arg); |
| 119 } | 105 } |
| 120 if (!ExecuteString(source, file_name, false, true)) { | 106 if (!ExecuteString(source, file_name, false, true)) { |
| 121 ExitShell(1); | 107 ExitShell(1); |
| 122 return; | 108 return; |
| 123 } | 109 } |
| 124 } | 110 } |
| 125 } | 111 } |
| 126 } | 112 } |
| 127 | 113 |
| 128 #ifdef WIN32 | |
| 129 void StartExecuteInThread() { ExecuteInThread(); } | |
| 130 void WaitForThread() {} | |
| 131 | |
| 132 #else | |
| 133 void StartExecuteInThread() { | 114 void StartExecuteInThread() { |
| 134 if (thread_ == 0) { | 115 if (thread_ == NULL) { |
| 135 pthread_attr_t attr; | 116 thread_ = new IsolateThread(this); |
| 136 // On some systems (OSX 10.6) the stack size default is 0.5Mb or less | 117 thread_->Start(); |
| 137 // which is not enough to parse the big literal expressions used in tests. | |
| 138 // The stack size should be at least StackGuard::kLimitSize + some | |
| 139 // OS-specific padding for thread startup code. | |
| 140 size_t stacksize = 2 << 20; // 2 Mb seems to be enough | |
| 141 pthread_attr_init(&attr); | |
| 142 pthread_attr_setstacksize(&attr, stacksize); | |
| 143 int error = pthread_create(&thread_, &attr, &IsolateThreadEntry, this); | |
| 144 if (error != 0) { | |
| 145 fprintf(stderr, "Error creating isolate thread.\n"); | |
| 146 ExitShell(1); | |
| 147 } | |
| 148 } | 118 } |
| 149 next_semaphore_->Signal(); | 119 next_semaphore_->Signal(); |
| 150 } | 120 } |
| 151 | 121 |
| 152 void WaitForThread() { | 122 void WaitForThread() { |
| 153 if (thread_ == 0) return; | 123 if (thread_ == NULL) return; |
| 154 if (last_run) { | 124 if (last_run) { |
| 155 pthread_join(thread_, NULL); | 125 thread_->Join(); |
| 156 thread_ = 0; | 126 thread_ = NULL; |
| 157 } else { | 127 } else { |
| 158 done_semaphore_->Wait(); | 128 done_semaphore_->Wait(); |
| 159 } | 129 } |
| 160 } | 130 } |
| 161 #endif // WIN32 | |
| 162 | 131 |
| 163 private: | 132 private: |
| 133 static v8::internal::Thread::Options GetThreadOptions() { |
| 134 v8::internal::Thread::Options options; |
| 135 options.name = "IsolateThread"; |
| 136 // On some systems (OSX 10.6) the stack size default is 0.5Mb or less |
| 137 // which is not enough to parse the big literal expressions used in tests. |
| 138 // The stack size should be at least StackGuard::kLimitSize + some |
| 139 // OS-specific padding for thread startup code. |
| 140 options.stack_size = 2 << 20; // 2 Mb seems to be enough |
| 141 return options; |
| 142 } |
| 143 |
| 144 class IsolateThread : public v8::internal::Thread { |
| 145 public: |
| 146 explicit IsolateThread(SourceGroup* group) |
| 147 : group_(group), v8::internal::Thread(NULL, GetThreadOptions()) {} |
| 148 |
| 149 virtual void Run() { |
| 150 group_->ExecuteInThread(); |
| 151 } |
| 152 |
| 153 private: |
| 154 SourceGroup* group_; |
| 155 }; |
| 156 |
| 164 void ExecuteInThread() { | 157 void ExecuteInThread() { |
| 165 v8::Isolate* isolate = v8::Isolate::New(); | 158 v8::Isolate* isolate = v8::Isolate::New(); |
| 166 do { | 159 do { |
| 167 if (next_semaphore_ != NULL) next_semaphore_->Wait(); | 160 if (next_semaphore_ != NULL) next_semaphore_->Wait(); |
| 168 { | 161 { |
| 169 v8::Isolate::Scope iscope(isolate); | 162 v8::Isolate::Scope iscope(isolate); |
| 170 v8::HandleScope scope; | 163 v8::HandleScope scope; |
| 171 v8::Persistent<v8::Context> context = CreateShellContext(); | 164 v8::Persistent<v8::Context> context = CreateShellContext(); |
| 172 { | 165 { |
| 173 v8::Context::Scope cscope(context); | 166 v8::Context::Scope cscope(context); |
| 174 Execute(); | 167 Execute(); |
| 175 } | 168 } |
| 176 context.Dispose(); | 169 context.Dispose(); |
| 177 } | 170 } |
| 178 if (done_semaphore_ != NULL) done_semaphore_->Signal(); | 171 if (done_semaphore_ != NULL) done_semaphore_->Signal(); |
| 179 } while (!last_run); | 172 } while (!last_run); |
| 180 isolate->Dispose(); | 173 isolate->Dispose(); |
| 181 } | 174 } |
| 182 | 175 |
| 183 const char** argv_; | 176 const char** argv_; |
| 184 int begin_offset_; | 177 int begin_offset_; |
| 185 int end_offset_; | 178 int end_offset_; |
| 186 v8::internal::Semaphore* next_semaphore_; | 179 v8::internal::Semaphore* next_semaphore_; |
| 187 v8::internal::Semaphore* done_semaphore_; | 180 v8::internal::Semaphore* done_semaphore_; |
| 188 #ifndef WIN32 | 181 v8::internal::Thread* thread_; |
| 189 pthread_t thread_; | |
| 190 #endif | |
| 191 | |
| 192 friend void* IsolateThreadEntry(void* arg); | |
| 193 }; | 182 }; |
| 194 | 183 |
| 195 #ifndef WIN32 | |
| 196 void* IsolateThreadEntry(void* arg) { | |
| 197 reinterpret_cast<SourceGroup*>(arg)->ExecuteInThread(); | |
| 198 return NULL; | |
| 199 } | |
| 200 #endif | |
| 201 | |
| 202 | 184 |
| 203 static SourceGroup* isolate_sources = NULL; | 185 static SourceGroup* isolate_sources = NULL; |
| 204 | 186 |
| 205 | 187 |
| 206 int RunMain(int argc, char* argv[]) { | 188 int RunMain(int argc, char* argv[]) { |
| 207 v8::V8::SetFlagsFromCommandLine(&argc, argv, true); | 189 v8::V8::SetFlagsFromCommandLine(&argc, argv, true); |
| 208 v8::HandleScope handle_scope; | 190 v8::HandleScope handle_scope; |
| 209 v8::Persistent<v8::Context> context = CreateShellContext(); | 191 v8::Persistent<v8::Context> context = CreateShellContext(); |
| 210 // Enter the newly created execution environment. | 192 // Enter the newly created execution environment. |
| 211 context->Enter(); | 193 context->Enter(); |
| (...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 516 printf("^"); | 498 printf("^"); |
| 517 } | 499 } |
| 518 printf("\n"); | 500 printf("\n"); |
| 519 v8::String::Utf8Value stack_trace(try_catch->StackTrace()); | 501 v8::String::Utf8Value stack_trace(try_catch->StackTrace()); |
| 520 if (stack_trace.length() > 0) { | 502 if (stack_trace.length() > 0) { |
| 521 const char* stack_trace_string = ToCString(stack_trace); | 503 const char* stack_trace_string = ToCString(stack_trace); |
| 522 printf("%s\n", stack_trace_string); | 504 printf("%s\n", stack_trace_string); |
| 523 } | 505 } |
| 524 } | 506 } |
| 525 } | 507 } |
| OLD | NEW |