Index: src/d8.cc |
=================================================================== |
--- src/d8.cc (revision 1141) |
+++ src/d8.cc (working copy) |
@@ -385,6 +385,7 @@ |
static char* ReadChars(const char *name, int* size_out) { |
+ v8::Unlocker unlocker; // Release the V8 lock while reading files. |
FILE* file = i::OS::FOpen(name, "rb"); |
if (file == NULL) return NULL; |
@@ -422,6 +423,7 @@ |
while (true) { |
Locker locker; |
HandleScope handle_scope; |
+ Context::Scope context_scope(evaluation_context_); |
i::SmartPointer<char> input = editor->Prompt(Shell::kPrompt); |
if (input.is_empty()) |
break; |
@@ -446,8 +448,24 @@ |
void ShellThread::Run() { |
+ // Prepare the context for this thread. |
+ Locker locker; |
+ HandleScope scope; |
+ Handle<ObjectTemplate> global_template = ObjectTemplate::New(); |
+ global_template->Set(String::New("print"), |
+ FunctionTemplate::New(Shell::Print)); |
+ global_template->Set(String::New("load"), |
+ FunctionTemplate::New(Shell::Load)); |
+ global_template->Set(String::New("version"), |
+ FunctionTemplate::New(Shell::Version)); |
+ |
+ Persistent<Context> thread_context = Context::New(NULL, global_template); |
+ thread_context->SetSecurityToken(Undefined()); |
+ |
+ Context::Scope context_scope(thread_context); |
+ |
char* ptr = const_cast<char*>(files_.start()); |
- while (ptr != NULL) { |
+ while ((ptr != NULL) && (*ptr != '\0')) { |
// For each newline-separated line. |
char *filename = ptr; |
char* next = ::strchr(ptr, '\n'); |
@@ -457,11 +475,11 @@ |
} else { |
ptr = NULL; |
} |
- Locker locker; |
- HandleScope scope; |
Handle<String> str = Shell::ReadFile(filename); |
Shell::ExecuteString(str, String::New(filename), false, false); |
} |
+ |
+ thread_context.Dispose(); |
} |
@@ -473,52 +491,59 @@ |
Initialize(); |
bool run_shell = (argc == 1); |
i::List<i::Thread*> threads(1); |
- Context::Scope context_scope(evaluation_context_); |
- for (int i = 1; i < argc; i++) { |
- char* str = argv[i]; |
- if (strcmp(str, "--shell") == 0) { |
- run_shell = true; |
- } else if (strcmp(str, "-f") == 0) { |
- // Ignore any -f flags for compatibility with other stand-alone |
- // JavaScript engines. |
- 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. |
- Locker locker; |
- 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 if (strcmp(str, "-p") == 0 && i + 1 < argc) { |
- Locker locker; |
- Locker::StartPreemption(10); |
- int size = 0; |
- const char *files = ReadChars(argv[++i], &size); |
- if (files == NULL) return 1; |
- ShellThread *thread = |
- new ShellThread(threads.length(), i::Vector<const char>(files, size)); |
- thread->Start(); |
- threads.Add(thread); |
- } else { |
- // Use all other arguments as names of files to load and run. |
- Locker locker; |
- HandleScope handle_scope; |
- Handle<String> file_name = v8::String::New(str); |
- Handle<String> source = ReadFile(str); |
- if (source.IsEmpty()) { |
- printf("Error reading '%s'\n", str); |
- return 1; |
+ |
+ { |
+ // Acquire the V8 lock once initialization has finished. Since the thread |
+ // below may spawn new threads accessing V8 holding the V8 lock here is |
+ // mandatory. |
+ Locker locker; |
+ Context::Scope context_scope(evaluation_context_); |
+ for (int i = 1; i < argc; i++) { |
+ char* str = argv[i]; |
+ if (strcmp(str, "--shell") == 0) { |
+ run_shell = true; |
+ } else if (strcmp(str, "-f") == 0) { |
+ // Ignore any -f flags for compatibility with other stand-alone |
+ // JavaScript engines. |
+ 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 if (strcmp(str, "-p") == 0 && i + 1 < argc) { |
+ // Use the lowest possible thread preemption interval to test as many |
+ // edgecases as possible. |
+ Locker::StartPreemption(1); |
+ int size = 0; |
+ const char *files = ReadChars(argv[++i], &size); |
+ if (files == NULL) return 1; |
+ ShellThread *thread = |
+ new ShellThread(threads.length(), |
+ i::Vector<const char>(files, size)); |
+ thread->Start(); |
+ threads.Add(thread); |
+ } else { |
+ // Use all other arguments as names of files to load and run. |
+ HandleScope handle_scope; |
+ Handle<String> file_name = v8::String::New(str); |
+ Handle<String> source = ReadFile(str); |
+ if (source.IsEmpty()) { |
+ printf("Error reading '%s'\n", str); |
+ return 1; |
+ } |
+ if (!ExecuteString(source, file_name, false, true)) |
+ return 1; |
} |
- if (!ExecuteString(source, file_name, false, true)) |
- return 1; |
} |
+ if (i::FLAG_debugger) |
+ v8::Debug::AddDebugEventListener(HandleDebugEvent); |
} |
- if (i::FLAG_debugger) |
- v8::Debug::AddDebugEventListener(HandleDebugEvent); |
if (run_shell) |
RunShell(); |
for (int i = 0; i < threads.length(); i++) { |