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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | src/allocation-inl.h » ('j') | tools/statics.whitelist » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: samples/shell.cc
diff --git a/samples/shell.cc b/samples/shell.cc
index 1a13f5f80bff11979c5fdf55cbdebc888ca36825..a4475912fe70c46cee4632ec51ecb719c611837b 100644
--- a/samples/shell.cc
+++ b/samples/shell.cc
@@ -31,7 +31,14 @@
#include <stdio.h>
#include <stdlib.h>
+// TODO(isolates):
+// o Add thread implementation for more platforms.
+// o Do not assume not WIN32 implies pthreads.
+#ifndef WIN32
+#include <pthread.h>
+#endif
+v8::Handle<v8::Context> CreateShellContext();
void RunShell(v8::Handle<v8::Context> context);
bool ExecuteString(v8::Handle<v8::String> source,
v8::Handle<v8::Value> name,
@@ -46,30 +53,123 @@ v8::Handle<v8::String> ReadFile(const char* name);
void ReportException(v8::TryCatch* handler);
+#ifndef WIN32
+void* IsolateThreadEntry(void* arg);
+#endif
+
+class SourceGroup {
+ public:
+ SourceGroup() : argv_(NULL), begin_offset_(0), end_offset_(0) {
+#ifndef WIN32
+ thread_ = 0;
+#endif
+ }
+
+ void Begin(char** argv, int offset) {
+ argv_ = const_cast<const char**>(argv);
+ begin_offset_ = offset;
+ }
+
+ void End(int offset) { end_offset_ = offset; }
+
+ void Execute() {
+ for (int i = begin_offset_; i < end_offset_; ++i) {
+ const char* arg = argv_[i];
+ if (strcmp(arg, "-e") == 0 && i + 1 < end_offset_) {
+ // Execute argument given to -e option directly.
+ v8::HandleScope handle_scope;
+ v8::Handle<v8::String> file_name = v8::String::New("unnamed");
+ v8::Handle<v8::String> source = v8::String::New(argv_[i + 1]);
+ if (!ExecuteString(source, file_name, false, true)) {
+ exit(1);
+ return;
+ }
+ ++i;
+ } else if (arg[0] == '-') {
+ // Ignore other options. They have been parsed already.
+ } else {
+ // Use all other arguments as names of files to load and run.
+ v8::HandleScope handle_scope;
+ v8::Handle<v8::String> file_name = v8::String::New(arg);
+ v8::Handle<v8::String> source = ReadFile(arg);
+ if (source.IsEmpty()) {
+ printf("Error reading '%s'\n", arg);
+ }
+ 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
+ exit(1);
+ return;
+ }
+ }
+ }
+ }
+
+#ifdef WIN32
+ void StartExecuteInThread() { ExecuteInThread(); }
+ void WaitForThread() {}
+
+#else
+ void StartExecuteInThread() {
+ pthread_create(&thread_, NULL, &IsolateThreadEntry, this);
+ }
+
+ void WaitForThread() {
+ if (thread_ == 0) return;
+ pthread_join(thread_, NULL);
+ thread_ = 0;
+ }
+#endif // WIN32
+
+ private:
+ void ExecuteInThread() {
+ v8::Isolate* isolate = v8::Isolate::New();
+ {
+ v8::Isolate::Scope iscope(isolate);
+ v8::HandleScope scope;
+ v8::Context::Scope cscope(CreateShellContext());
+ Execute();
+ }
+ isolate->Dispose();
+ }
+
+ const char** argv_;
+ int begin_offset_;
+ int end_offset_;
+#ifndef WIN32
+ pthread_t thread_;
+#endif
+
+ friend void* IsolateThreadEntry(void* arg);
+};
+
+#ifndef WIN32
+void* IsolateThreadEntry(void* arg) {
yurys 2010/10/06 14:52:58 This function can be made a private static method
+ reinterpret_cast<SourceGroup*>(arg)->ExecuteInThread();
+ return NULL;
+}
+#endif
+
+
int RunMain(int argc, char* argv[]) {
v8::V8::SetFlagsFromCommandLine(&argc, argv, true);
v8::HandleScope handle_scope;
- // Create a template for the global object.
- v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New();
- // Bind the global 'print' function to the C++ Print callback.
- global->Set(v8::String::New("print"), v8::FunctionTemplate::New(Print));
- // Bind the global 'read' function to the C++ Read callback.
- global->Set(v8::String::New("read"), v8::FunctionTemplate::New(Read));
- // Bind the global 'load' function to the C++ Load callback.
- global->Set(v8::String::New("load"), v8::FunctionTemplate::New(Load));
- // Bind the 'quit' function
- global->Set(v8::String::New("quit"), v8::FunctionTemplate::New(Quit));
- // Bind the 'version' function
- global->Set(v8::String::New("version"), v8::FunctionTemplate::New(Version));
- // Create a new execution environment containing the built-in
- // functions
- v8::Handle<v8::Context> context = v8::Context::New(NULL, global);
+ v8::Handle<v8::Context> context = CreateShellContext();
// Enter the newly created execution environment.
v8::Context::Scope context_scope(context);
bool run_shell = (argc == 1);
+ int num_isolates = 1;
+ for (int i = 1; i < argc; i++) {
+ if (strcmp(argv[i], "--isolate") == 0) ++num_isolates;
+ }
+ SourceGroup* isolate_sources = new SourceGroup[num_isolates];
+ SourceGroup* current = isolate_sources;
+ current->Begin(argv, 1);
for (int i = 1; i < argc; i++) {
const char* str = argv[i];
- if (strcmp(str, "--shell") == 0) {
+ if (strcmp(str, "--isolate") == 0) {
+ current->End(i);
+ current++;
+ current->Begin(argv, i + 1);
+ } else if (strcmp(str, "--shell") == 0) {
run_shell = true;
} else if (strcmp(str, "-f") == 0) {
// Ignore any -f flags for compatibility with the other stand-
@@ -77,28 +177,17 @@ int RunMain(int argc, char* argv[]) {
continue;
} else if (strncmp(str, "--", 2) == 0) {
printf("Warning: unknown flag %s.\nTry --help for options\n", str);
- } else if (strcmp(str, "-e") == 0 && i + 1 < argc) {
- // Execute argument given to -e option directly
- v8::HandleScope handle_scope;
- v8::Handle<v8::String> file_name = v8::String::New("unnamed");
- v8::Handle<v8::String> source = v8::String::New(argv[i + 1]);
- if (!ExecuteString(source, file_name, false, true))
- return 1;
- i++;
- } else {
- // Use all other arguments as names of files to load and run.
- v8::HandleScope handle_scope;
- v8::Handle<v8::String> file_name = v8::String::New(str);
- v8::Handle<v8::String> source = ReadFile(str);
- if (source.IsEmpty()) {
- printf("Error reading '%s'\n", str);
- return 1;
- }
- if (!ExecuteString(source, file_name, false, true))
- return 1;
}
}
+ current->End(argc);
+ for (int i = 1; i < num_isolates; ++i) {
+ isolate_sources[i].StartExecuteInThread();
+ }
+ isolate_sources[0].Execute();
if (run_shell) RunShell(context);
+ for (int i = 1; i < num_isolates; ++i) {
+ isolate_sources[i].WaitForThread();
+ }
yurys 2010/10/06 14:52:58 Should we delete isolate_sources before exit here?
return 0;
}
@@ -116,6 +205,25 @@ const char* ToCString(const v8::String::Utf8Value& value) {
}
+// Creates a new execution environment containing the built-in
+// functions.
+v8::Handle<v8::Context> CreateShellContext() {
+ // Create a template for the global object.
+ v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New();
+ // Bind the global 'print' function to the C++ Print callback.
+ global->Set(v8::String::New("print"), v8::FunctionTemplate::New(Print));
+ // Bind the global 'read' function to the C++ Read callback.
+ global->Set(v8::String::New("read"), v8::FunctionTemplate::New(Read));
+ // Bind the global 'load' function to the C++ Load callback.
+ global->Set(v8::String::New("load"), v8::FunctionTemplate::New(Load));
+ // Bind the 'quit' function
+ global->Set(v8::String::New("quit"), v8::FunctionTemplate::New(Quit));
+ // Bind the 'version' function
+ global->Set(v8::String::New("version"), v8::FunctionTemplate::New(Version));
+ return v8::Context::New(NULL, global);
+}
+
+
// The callback that is invoked by v8 whenever the JavaScript 'print'
// function is called. Prints its arguments on stdout separated by
// spaces and ending with a newline.
« 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