| 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++) {
|
|
|