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

Side by Side Diff: samples/shell.cc

Issue 3601010: [Isolates] Allow running multiple isolates in shell and use this in tests. (Closed)
Patch Set: Created 10 years, 2 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
« no previous file with comments | « no previous file | src/allocation-inl.h » ('j') | tools/statics.whitelist » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 13 matching lines...) Expand all
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 #include <v8.h> 28 #include <v8.h>
29 #include <fcntl.h> 29 #include <fcntl.h>
30 #include <string.h> 30 #include <string.h>
31 #include <stdio.h> 31 #include <stdio.h>
32 #include <stdlib.h> 32 #include <stdlib.h>
33 33
34 // TODO(isolates):
35 // o Add thread implementation for more platforms.
36 // o Do not assume not WIN32 implies pthreads.
37 #ifndef WIN32
38 #include <pthread.h>
39 #endif
34 40
41 v8::Handle<v8::Context> CreateShellContext();
35 void RunShell(v8::Handle<v8::Context> context); 42 void RunShell(v8::Handle<v8::Context> context);
36 bool ExecuteString(v8::Handle<v8::String> source, 43 bool ExecuteString(v8::Handle<v8::String> source,
37 v8::Handle<v8::Value> name, 44 v8::Handle<v8::Value> name,
38 bool print_result, 45 bool print_result,
39 bool report_exceptions); 46 bool report_exceptions);
40 v8::Handle<v8::Value> Print(const v8::Arguments& args); 47 v8::Handle<v8::Value> Print(const v8::Arguments& args);
41 v8::Handle<v8::Value> Read(const v8::Arguments& args); 48 v8::Handle<v8::Value> Read(const v8::Arguments& args);
42 v8::Handle<v8::Value> Load(const v8::Arguments& args); 49 v8::Handle<v8::Value> Load(const v8::Arguments& args);
43 v8::Handle<v8::Value> Quit(const v8::Arguments& args); 50 v8::Handle<v8::Value> Quit(const v8::Arguments& args);
44 v8::Handle<v8::Value> Version(const v8::Arguments& args); 51 v8::Handle<v8::Value> Version(const v8::Arguments& args);
45 v8::Handle<v8::String> ReadFile(const char* name); 52 v8::Handle<v8::String> ReadFile(const char* name);
46 void ReportException(v8::TryCatch* handler); 53 void ReportException(v8::TryCatch* handler);
47 54
48 55
56 #ifndef WIN32
57 void* IsolateThreadEntry(void* arg);
58 #endif
59
60 class SourceGroup {
61 public:
62 SourceGroup() : argv_(NULL), begin_offset_(0), end_offset_(0) {
63 #ifndef WIN32
64 thread_ = 0;
65 #endif
66 }
67
68 void Begin(char** argv, int offset) {
69 argv_ = const_cast<const char**>(argv);
70 begin_offset_ = offset;
71 }
72
73 void End(int offset) { end_offset_ = offset; }
74
75 void Execute() {
76 for (int i = begin_offset_; i < end_offset_; ++i) {
77 const char* arg = argv_[i];
78 if (strcmp(arg, "-e") == 0 && i + 1 < end_offset_) {
79 // Execute argument given to -e option directly.
80 v8::HandleScope handle_scope;
81 v8::Handle<v8::String> file_name = v8::String::New("unnamed");
82 v8::Handle<v8::String> source = v8::String::New(argv_[i + 1]);
83 if (!ExecuteString(source, file_name, false, true)) {
84 exit(1);
85 return;
86 }
87 ++i;
88 } else if (arg[0] == '-') {
89 // Ignore other options. They have been parsed already.
90 } else {
91 // Use all other arguments as names of files to load and run.
92 v8::HandleScope handle_scope;
93 v8::Handle<v8::String> file_name = v8::String::New(arg);
94 v8::Handle<v8::String> source = ReadFile(arg);
95 if (source.IsEmpty()) {
96 printf("Error reading '%s'\n", arg);
97 }
98 if (!ExecuteString(source, file_name, false, true)) {
yurys 2010/10/06 14:52:58 This code can be extracted out of the if/else expr
99 exit(1);
100 return;
101 }
102 }
103 }
104 }
105
106 #ifdef WIN32
107 void StartExecuteInThread() { ExecuteInThread(); }
108 void WaitForThread() {}
109
110 #else
111 void StartExecuteInThread() {
112 pthread_create(&thread_, NULL, &IsolateThreadEntry, this);
113 }
114
115 void WaitForThread() {
116 if (thread_ == 0) return;
117 pthread_join(thread_, NULL);
118 thread_ = 0;
119 }
120 #endif // WIN32
121
122 private:
123 void ExecuteInThread() {
124 v8::Isolate* isolate = v8::Isolate::New();
125 {
126 v8::Isolate::Scope iscope(isolate);
127 v8::HandleScope scope;
128 v8::Context::Scope cscope(CreateShellContext());
129 Execute();
130 }
131 isolate->Dispose();
132 }
133
134 const char** argv_;
135 int begin_offset_;
136 int end_offset_;
137 #ifndef WIN32
138 pthread_t thread_;
139 #endif
140
141 friend void* IsolateThreadEntry(void* arg);
142 };
143
144 #ifndef WIN32
145 void* IsolateThreadEntry(void* arg) {
yurys 2010/10/06 14:52:58 This function can be made a private static method
146 reinterpret_cast<SourceGroup*>(arg)->ExecuteInThread();
147 return NULL;
148 }
149 #endif
150
151
49 int RunMain(int argc, char* argv[]) { 152 int RunMain(int argc, char* argv[]) {
50 v8::V8::SetFlagsFromCommandLine(&argc, argv, true); 153 v8::V8::SetFlagsFromCommandLine(&argc, argv, true);
51 v8::HandleScope handle_scope; 154 v8::HandleScope handle_scope;
52 // Create a template for the global object. 155 v8::Handle<v8::Context> context = CreateShellContext();
53 v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New();
54 // Bind the global 'print' function to the C++ Print callback.
55 global->Set(v8::String::New("print"), v8::FunctionTemplate::New(Print));
56 // Bind the global 'read' function to the C++ Read callback.
57 global->Set(v8::String::New("read"), v8::FunctionTemplate::New(Read));
58 // Bind the global 'load' function to the C++ Load callback.
59 global->Set(v8::String::New("load"), v8::FunctionTemplate::New(Load));
60 // Bind the 'quit' function
61 global->Set(v8::String::New("quit"), v8::FunctionTemplate::New(Quit));
62 // Bind the 'version' function
63 global->Set(v8::String::New("version"), v8::FunctionTemplate::New(Version));
64 // Create a new execution environment containing the built-in
65 // functions
66 v8::Handle<v8::Context> context = v8::Context::New(NULL, global);
67 // Enter the newly created execution environment. 156 // Enter the newly created execution environment.
68 v8::Context::Scope context_scope(context); 157 v8::Context::Scope context_scope(context);
69 bool run_shell = (argc == 1); 158 bool run_shell = (argc == 1);
159 int num_isolates = 1;
160 for (int i = 1; i < argc; i++) {
161 if (strcmp(argv[i], "--isolate") == 0) ++num_isolates;
162 }
163 SourceGroup* isolate_sources = new SourceGroup[num_isolates];
164 SourceGroup* current = isolate_sources;
165 current->Begin(argv, 1);
70 for (int i = 1; i < argc; i++) { 166 for (int i = 1; i < argc; i++) {
71 const char* str = argv[i]; 167 const char* str = argv[i];
72 if (strcmp(str, "--shell") == 0) { 168 if (strcmp(str, "--isolate") == 0) {
169 current->End(i);
170 current++;
171 current->Begin(argv, i + 1);
172 } else if (strcmp(str, "--shell") == 0) {
73 run_shell = true; 173 run_shell = true;
74 } else if (strcmp(str, "-f") == 0) { 174 } else if (strcmp(str, "-f") == 0) {
75 // Ignore any -f flags for compatibility with the other stand- 175 // Ignore any -f flags for compatibility with the other stand-
76 // alone JavaScript engines. 176 // alone JavaScript engines.
77 continue; 177 continue;
78 } else if (strncmp(str, "--", 2) == 0) { 178 } else if (strncmp(str, "--", 2) == 0) {
79 printf("Warning: unknown flag %s.\nTry --help for options\n", str); 179 printf("Warning: unknown flag %s.\nTry --help for options\n", str);
80 } else if (strcmp(str, "-e") == 0 && i + 1 < argc) {
81 // Execute argument given to -e option directly
82 v8::HandleScope handle_scope;
83 v8::Handle<v8::String> file_name = v8::String::New("unnamed");
84 v8::Handle<v8::String> source = v8::String::New(argv[i + 1]);
85 if (!ExecuteString(source, file_name, false, true))
86 return 1;
87 i++;
88 } else {
89 // Use all other arguments as names of files to load and run.
90 v8::HandleScope handle_scope;
91 v8::Handle<v8::String> file_name = v8::String::New(str);
92 v8::Handle<v8::String> source = ReadFile(str);
93 if (source.IsEmpty()) {
94 printf("Error reading '%s'\n", str);
95 return 1;
96 }
97 if (!ExecuteString(source, file_name, false, true))
98 return 1;
99 } 180 }
100 } 181 }
182 current->End(argc);
183 for (int i = 1; i < num_isolates; ++i) {
184 isolate_sources[i].StartExecuteInThread();
185 }
186 isolate_sources[0].Execute();
101 if (run_shell) RunShell(context); 187 if (run_shell) RunShell(context);
188 for (int i = 1; i < num_isolates; ++i) {
189 isolate_sources[i].WaitForThread();
190 }
yurys 2010/10/06 14:52:58 Should we delete isolate_sources before exit here?
102 return 0; 191 return 0;
103 } 192 }
104 193
105 194
106 int main(int argc, char* argv[]) { 195 int main(int argc, char* argv[]) {
107 int result = RunMain(argc, argv); 196 int result = RunMain(argc, argv);
108 v8::V8::Dispose(); 197 v8::V8::Dispose();
109 return result; 198 return result;
110 } 199 }
111 200
112 201
113 // Extracts a C string from a V8 Utf8Value. 202 // Extracts a C string from a V8 Utf8Value.
114 const char* ToCString(const v8::String::Utf8Value& value) { 203 const char* ToCString(const v8::String::Utf8Value& value) {
115 return *value ? *value : "<string conversion failed>"; 204 return *value ? *value : "<string conversion failed>";
116 } 205 }
117 206
118 207
208 // Creates a new execution environment containing the built-in
209 // functions.
210 v8::Handle<v8::Context> CreateShellContext() {
211 // Create a template for the global object.
212 v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New();
213 // Bind the global 'print' function to the C++ Print callback.
214 global->Set(v8::String::New("print"), v8::FunctionTemplate::New(Print));
215 // Bind the global 'read' function to the C++ Read callback.
216 global->Set(v8::String::New("read"), v8::FunctionTemplate::New(Read));
217 // Bind the global 'load' function to the C++ Load callback.
218 global->Set(v8::String::New("load"), v8::FunctionTemplate::New(Load));
219 // Bind the 'quit' function
220 global->Set(v8::String::New("quit"), v8::FunctionTemplate::New(Quit));
221 // Bind the 'version' function
222 global->Set(v8::String::New("version"), v8::FunctionTemplate::New(Version));
223 return v8::Context::New(NULL, global);
224 }
225
226
119 // The callback that is invoked by v8 whenever the JavaScript 'print' 227 // The callback that is invoked by v8 whenever the JavaScript 'print'
120 // function is called. Prints its arguments on stdout separated by 228 // function is called. Prints its arguments on stdout separated by
121 // spaces and ending with a newline. 229 // spaces and ending with a newline.
122 v8::Handle<v8::Value> Print(const v8::Arguments& args) { 230 v8::Handle<v8::Value> Print(const v8::Arguments& args) {
123 bool first = true; 231 bool first = true;
124 for (int i = 0; i < args.Length(); i++) { 232 for (int i = 0; i < args.Length(); i++) {
125 v8::HandleScope handle_scope; 233 v8::HandleScope handle_scope;
126 if (first) { 234 if (first) {
127 first = false; 235 first = false;
128 } else { 236 } else {
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
299 printf("^"); 407 printf("^");
300 } 408 }
301 printf("\n"); 409 printf("\n");
302 v8::String::Utf8Value stack_trace(try_catch->StackTrace()); 410 v8::String::Utf8Value stack_trace(try_catch->StackTrace());
303 if (stack_trace.length() > 0) { 411 if (stack_trace.length() > 0) {
304 const char* stack_trace_string = ToCString(stack_trace); 412 const char* stack_trace_string = ToCString(stack_trace);
305 printf("%s\n", stack_trace_string); 413 printf("%s\n", stack_trace_string);
306 } 414 }
307 } 415 }
308 } 416 }
OLDNEW
« no previous file with comments | « no previous file | src/allocation-inl.h » ('j') | tools/statics.whitelist » ('J')

Powered by Google App Engine
This is Rietveld 408576698