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 |