Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2008 the V8 project authors. All rights reserved. | 1 // Copyright 2008 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 15 matching lines...) Expand all Loading... | |
| 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 | 28 |
| 29 #include <stdlib.h> | 29 #include <stdlib.h> |
| 30 | 30 |
| 31 #include "d8.h" | 31 #include "d8.h" |
| 32 #include "d8-debug.h" | 32 #include "d8-debug.h" |
| 33 #include "debug.h" | 33 #include "debug.h" |
| 34 #include "api.h" | 34 #include "api.h" |
| 35 #include "natives.h" | 35 #include "natives.h" |
| 36 #include "platform.h" | |
| 36 | 37 |
| 37 | 38 |
| 38 namespace v8 { | 39 namespace v8 { |
| 39 | 40 |
| 40 | 41 |
| 41 const char* Shell::kHistoryFileName = ".d8_history"; | 42 const char* Shell::kHistoryFileName = ".d8_history"; |
| 42 const char* Shell::kPrompt = "d8> "; | 43 const char* Shell::kPrompt = "d8> "; |
| 43 | 44 |
| 44 | 45 |
| 45 LineEditor *LineEditor::first_ = NULL; | 46 LineEditor *LineEditor::first_ = NULL; |
| (...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 376 Counter* counter = (*i).second; | 377 Counter* counter = (*i).second; |
| 377 ::printf("| %-38s | %11i |\n", (*i).first, counter->value()); | 378 ::printf("| %-38s | %11i |\n", (*i).first, counter->value()); |
| 378 } | 379 } |
| 379 ::printf("+----------------------------------------+-------------+\n"); | 380 ::printf("+----------------------------------------+-------------+\n"); |
| 380 } | 381 } |
| 381 if (counters_file_ != NULL) | 382 if (counters_file_ != NULL) |
| 382 delete counters_file_; | 383 delete counters_file_; |
| 383 } | 384 } |
| 384 | 385 |
| 385 | 386 |
| 386 // Reads a file into a v8 string. | 387 static char* ReadChars(const char *name, int* size_out) { |
| 387 Handle<String> Shell::ReadFile(const char* name) { | |
| 388 FILE* file = i::OS::FOpen(name, "rb"); | 388 FILE* file = i::OS::FOpen(name, "rb"); |
| 389 if (file == NULL) return Handle<String>(); | 389 if (file == NULL) return NULL; |
| 390 | 390 |
| 391 fseek(file, 0, SEEK_END); | 391 fseek(file, 0, SEEK_END); |
| 392 int size = ftell(file); | 392 int size = ftell(file); |
| 393 rewind(file); | 393 rewind(file); |
| 394 | 394 |
| 395 char* chars = new char[size + 1]; | 395 char* chars = new char[size + 1]; |
| 396 chars[size] = '\0'; | 396 chars[size] = '\0'; |
| 397 for (int i = 0; i < size;) { | 397 for (int i = 0; i < size;) { |
| 398 int read = fread(&chars[i], 1, size - i, file); | 398 int read = fread(&chars[i], 1, size - i, file); |
| 399 i += read; | 399 i += read; |
| 400 } | 400 } |
| 401 fclose(file); | 401 fclose(file); |
| 402 Handle<String> result = String::New(chars, size); | 402 *size_out = size; |
| 403 return chars; | |
| 404 } | |
| 405 | |
| 406 | |
| 407 // Reads a file into a v8 string. | |
| 408 Handle<String> Shell::ReadFile(const char* name) { | |
| 409 int size = 0; | |
| 410 char* chars = ReadChars(name, &size); | |
| 411 if (chars == NULL) return Handle<String>(); | |
| 412 Handle<String> result = String::New(chars); | |
| 403 delete[] chars; | 413 delete[] chars; |
| 404 return result; | 414 return result; |
| 405 } | 415 } |
| 406 | 416 |
| 407 | 417 |
| 408 void Shell::RunShell() { | 418 void Shell::RunShell() { |
| 409 LineEditor* editor = LineEditor::Get(); | 419 LineEditor* editor = LineEditor::Get(); |
| 410 printf("V8 version %s [console: %s]\n", V8::GetVersion(), editor->name()); | 420 printf("V8 version %s [console: %s]\n", V8::GetVersion(), editor->name()); |
| 411 editor->Open(); | 421 editor->Open(); |
| 412 while (true) { | 422 while (true) { |
| 413 HandleScope handle_scope; | 423 HandleScope handle_scope; |
| 414 i::SmartPointer<char> input = editor->Prompt(Shell::kPrompt); | 424 i::SmartPointer<char> input = editor->Prompt(Shell::kPrompt); |
| 415 if (input.is_empty()) | 425 if (input.is_empty()) |
| 416 break; | 426 break; |
| 417 editor->AddHistory(*input); | 427 editor->AddHistory(*input); |
| 418 Handle<String> name = String::New("(d8)"); | 428 Handle<String> name = String::New("(d8)"); |
| 419 ExecuteString(String::New(*input), name, true, true); | 429 ExecuteString(String::New(*input), name, true, true); |
| 420 } | 430 } |
| 421 editor->Close(); | 431 editor->Close(); |
| 422 printf("\n"); | 432 printf("\n"); |
| 423 } | 433 } |
| 424 | 434 |
| 425 | 435 |
| 436 class ShellThread : public i::Thread { | |
| 437 public: | |
| 438 ShellThread(int no, i::Vector<const char> files) | |
| 439 : no_(no), files_(files) { } | |
| 440 virtual void Run(); | |
| 441 private: | |
| 442 int no_; | |
| 443 i::Vector<const char> files_; | |
| 444 }; | |
| 445 | |
| 446 | |
| 447 void ShellThread::Run() { | |
| 448 char* ptr = const_cast<char*>(files_.start()); | |
| 449 while (ptr) { | |
|
Erik Corry
2009/01/20 13:28:31
Test against NULL should be explicit.
Christian Plesner Hansen
2009/01/20 14:13:46
Fixed (times 3).
| |
| 450 // For each newline-separated line. | |
| 451 char *filename = ptr; | |
| 452 char* next = ::strchr(ptr, '\n'); | |
| 453 if (next) { | |
|
Erik Corry
2009/01/20 13:28:31
Test against NULL should be explicit.
| |
| 454 *next = '\0'; | |
| 455 ptr = (next + 1); | |
| 456 } else { | |
| 457 ptr = next; | |
|
Erik Corry
2009/01/20 13:28:31
ptr = NULL would be clearer.
| |
| 458 } | |
| 459 Locker locker; | |
| 460 HandleScope scope; | |
| 461 Handle<String> str = Shell::ReadFile(filename); | |
| 462 Shell::ExecuteString(str, String::New(filename), false, false); | |
| 463 } | |
| 464 } | |
| 465 | |
| 466 | |
| 426 int Shell::Main(int argc, char* argv[]) { | 467 int Shell::Main(int argc, char* argv[]) { |
| 427 i::FlagList::SetFlagsFromCommandLine(&argc, argv, true); | 468 i::FlagList::SetFlagsFromCommandLine(&argc, argv, true); |
| 428 if (i::FLAG_help) { | 469 if (i::FLAG_help) { |
| 429 return 1; | 470 return 1; |
| 430 } | 471 } |
| 431 Initialize(); | 472 Initialize(); |
| 432 bool run_shell = (argc == 1); | 473 bool run_shell = (argc == 1); |
| 474 i::List<i::Thread*> threads(1); | |
| 433 Context::Scope context_scope(evaluation_context_); | 475 Context::Scope context_scope(evaluation_context_); |
|
Erik Corry
2009/01/20 13:28:31
This should be protected by a locker. Also the pl
Christian Plesner Hansen
2009/01/20 14:13:46
I don't think so -- there can only be one thread d
| |
| 434 for (int i = 1; i < argc; i++) { | 476 for (int i = 1; i < argc; i++) { |
| 435 char* str = argv[i]; | 477 char* str = argv[i]; |
| 436 if (strcmp(str, "--shell") == 0) { | 478 if (strcmp(str, "--shell") == 0) { |
| 437 run_shell = true; | 479 run_shell = true; |
| 438 } else if (strcmp(str, "-f") == 0) { | 480 } else if (strcmp(str, "-f") == 0) { |
| 439 // Ignore any -f flags for compatibility with other stand-alone | 481 // Ignore any -f flags for compatibility with other stand-alone |
| 440 // JavaScript engines. | 482 // JavaScript engines. |
| 441 continue; | 483 continue; |
| 442 } else if (strncmp(str, "--", 2) == 0) { | 484 } else if (strncmp(str, "--", 2) == 0) { |
| 443 printf("Warning: unknown flag %s.\nTry --help for options\n", str); | 485 printf("Warning: unknown flag %s.\nTry --help for options\n", str); |
| 444 } else if (strcmp(str, "-e") == 0 && i + 1 < argc) { | 486 } else if (strcmp(str, "-e") == 0 && i + 1 < argc) { |
| 445 // Execute argument given to -e option directly. | 487 // Execute argument given to -e option directly. |
| 446 v8::HandleScope handle_scope; | 488 v8::HandleScope handle_scope; |
| 447 v8::Handle<v8::String> file_name = v8::String::New("unnamed"); | 489 v8::Handle<v8::String> file_name = v8::String::New("unnamed"); |
| 448 v8::Handle<v8::String> source = v8::String::New(argv[i + 1]); | 490 v8::Handle<v8::String> source = v8::String::New(argv[i + 1]); |
| 449 if (!ExecuteString(source, file_name, false, true)) | 491 if (!ExecuteString(source, file_name, false, true)) |
| 450 return 1; | 492 return 1; |
| 451 i++; | 493 i++; |
| 494 } else if (strcmp(str, "-p") == 0 && i + 1 < argc) { | |
| 495 Locker locker; | |
| 496 Locker::StartPreemption(10); | |
|
Erik Corry
2009/01/20 13:28:31
You only need to do this once, not once per file.
Christian Plesner Hansen
2009/01/20 14:13:46
Right, but I don't want to enable it without the -
| |
| 497 int size = 0; | |
| 498 const char *files = ReadChars(argv[++i], &size); | |
| 499 if (files == NULL) return 1; | |
| 500 ShellThread *thread = | |
| 501 new ShellThread(threads.length(), i::Vector<const char>(files, size)); | |
| 502 thread->Start(); | |
| 503 threads.Add(thread); | |
| 452 } else { | 504 } else { |
| 453 // Use all other arguments as names of files to load and run. | 505 // Use all other arguments as names of files to load and run. |
|
Erik Corry
2009/01/20 13:28:31
If the user uses both -p files and straight js fil
Christian Plesner Hansen
2009/01/20 14:13:46
Fixed
| |
| 454 HandleScope handle_scope; | 506 HandleScope handle_scope; |
| 455 Handle<String> file_name = v8::String::New(str); | 507 Handle<String> file_name = v8::String::New(str); |
| 456 Handle<String> source = ReadFile(str); | 508 Handle<String> source = ReadFile(str); |
| 457 if (source.IsEmpty()) { | 509 if (source.IsEmpty()) { |
| 458 printf("Error reading '%s'\n", str); | 510 printf("Error reading '%s'\n", str); |
| 459 return 1; | 511 return 1; |
| 460 } | 512 } |
| 461 if (!ExecuteString(source, file_name, false, true)) | 513 if (!ExecuteString(source, file_name, false, true)) |
| 462 return 1; | 514 return 1; |
| 463 } | 515 } |
| 464 } | 516 } |
| 465 if (i::FLAG_debugger) | 517 if (i::FLAG_debugger) |
| 466 v8::Debug::AddDebugEventListener(HandleDebugEvent); | 518 v8::Debug::AddDebugEventListener(HandleDebugEvent); |
| 467 if (run_shell) | 519 if (run_shell) |
| 468 RunShell(); | 520 RunShell(); |
|
Erik Corry
2009/01/20 13:28:31
and here.
Christian Plesner Hansen
2009/01/20 14:13:46
Fixed
| |
| 521 for (int i = 0; i < threads.length(); i++) { | |
| 522 Thread *thread = threads[i]; | |
| 523 thread->Join(); | |
| 524 delete thread; | |
| 525 } | |
| 469 OnExit(); | 526 OnExit(); |
| 470 return 0; | 527 return 0; |
| 471 } | 528 } |
| 472 | 529 |
| 473 | 530 |
| 474 } // namespace v8 | 531 } // namespace v8 |
| 475 | 532 |
| 476 | 533 |
| 477 int main(int argc, char* argv[]) { | 534 int main(int argc, char* argv[]) { |
| 478 return v8::Shell::Main(argc, argv); | 535 return v8::Shell::Main(argc, argv); |
| 479 } | 536 } |
| OLD | NEW |