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 |
11 // with the distribution. | 11 // with the distribution. |
12 // * Neither the name of Google Inc. nor the names of its | 12 // * Neither the name of Google Inc. nor the names of its |
13 // contributors may be used to endorse or promote products derived | 13 // contributors may be used to endorse or promote products derived |
14 // from this software without specific prior written permission. | 14 // from this software without specific prior written permission. |
15 // | 15 // |
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
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 | 28 |
29 #include <stdlib.h> | 29 #include <stdlib.h> |
| 30 #include <errno.h> |
30 | 31 |
31 #include "d8.h" | 32 #include "d8.h" |
32 #include "d8-debug.h" | 33 #include "d8-debug.h" |
33 #include "debug.h" | 34 #include "debug.h" |
34 #include "api.h" | 35 #include "api.h" |
35 #include "natives.h" | 36 #include "natives.h" |
36 #include "platform.h" | 37 #include "platform.h" |
37 | 38 |
38 | 39 |
39 namespace v8 { | 40 namespace v8 { |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
167 return ThrowException(String::New("Error loading file")); | 168 return ThrowException(String::New("Error loading file")); |
168 } | 169 } |
169 if (!ExecuteString(source, String::New(*file), false, false)) { | 170 if (!ExecuteString(source, String::New(*file), false, false)) { |
170 return ThrowException(String::New("Error executing file")); | 171 return ThrowException(String::New("Error executing file")); |
171 } | 172 } |
172 } | 173 } |
173 return Undefined(); | 174 return Undefined(); |
174 } | 175 } |
175 | 176 |
176 | 177 |
| 178 Handle<Value> Shell::Yield(const Arguments& args) { |
| 179 v8::Unlocker unlocker; |
| 180 return Undefined(); |
| 181 } |
| 182 |
| 183 |
177 Handle<Value> Shell::Quit(const Arguments& args) { | 184 Handle<Value> Shell::Quit(const Arguments& args) { |
178 int exit_code = args[0]->Int32Value(); | 185 int exit_code = args[0]->Int32Value(); |
179 OnExit(); | 186 OnExit(); |
180 exit(exit_code); | 187 exit(exit_code); |
181 return Undefined(); | 188 return Undefined(); |
182 } | 189 } |
183 | 190 |
184 | 191 |
185 Handle<Value> Shell::Version(const Arguments& args) { | 192 Handle<Value> Shell::Version(const Arguments& args) { |
186 return String::New(V8::GetVersion()); | 193 return String::New(V8::GetVersion()); |
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
474 | 481 |
475 void ShellThread::Run() { | 482 void ShellThread::Run() { |
476 // Prepare the context for this thread. | 483 // Prepare the context for this thread. |
477 Locker locker; | 484 Locker locker; |
478 HandleScope scope; | 485 HandleScope scope; |
479 Handle<ObjectTemplate> global_template = ObjectTemplate::New(); | 486 Handle<ObjectTemplate> global_template = ObjectTemplate::New(); |
480 global_template->Set(String::New("print"), | 487 global_template->Set(String::New("print"), |
481 FunctionTemplate::New(Shell::Print)); | 488 FunctionTemplate::New(Shell::Print)); |
482 global_template->Set(String::New("load"), | 489 global_template->Set(String::New("load"), |
483 FunctionTemplate::New(Shell::Load)); | 490 FunctionTemplate::New(Shell::Load)); |
| 491 global_template->Set(String::New("yield"), |
| 492 FunctionTemplate::New(Shell::Yield)); |
484 global_template->Set(String::New("version"), | 493 global_template->Set(String::New("version"), |
485 FunctionTemplate::New(Shell::Version)); | 494 FunctionTemplate::New(Shell::Version)); |
486 | 495 |
487 char* ptr = const_cast<char*>(files_.start()); | 496 char* ptr = const_cast<char*>(files_.start()); |
488 while ((ptr != NULL) && (*ptr != '\0')) { | 497 while ((ptr != NULL) && (*ptr != '\0')) { |
489 // For each newline-separated line. | 498 // For each newline-separated line. |
490 char* next_line = ReadLine(ptr); | 499 char* next_line = ReadLine(ptr); |
491 | 500 |
492 if (*ptr == '#') { | 501 if (*ptr == '#') { |
493 // Skip comment lines. | 502 // Skip comment lines. |
(...skipping 29 matching lines...) Expand all Loading... |
523 } | 532 } |
524 | 533 |
525 | 534 |
526 int Shell::Main(int argc, char* argv[]) { | 535 int Shell::Main(int argc, char* argv[]) { |
527 i::FlagList::SetFlagsFromCommandLine(&argc, argv, true); | 536 i::FlagList::SetFlagsFromCommandLine(&argc, argv, true); |
528 if (i::FLAG_help) { | 537 if (i::FLAG_help) { |
529 return 1; | 538 return 1; |
530 } | 539 } |
531 Initialize(); | 540 Initialize(); |
532 bool run_shell = (argc == 1); | 541 bool run_shell = (argc == 1); |
| 542 |
| 543 // Default use preemption if threads are created. |
| 544 bool use_preemption = true; |
| 545 |
| 546 // Default to use lowest possible thread preemption interval to test as many |
| 547 // edgecases as possible. |
| 548 int preemption_interval = 1; |
| 549 |
533 i::List<i::Thread*> threads(1); | 550 i::List<i::Thread*> threads(1); |
534 | 551 |
535 { | 552 { |
536 // Acquire the V8 lock once initialization has finished. Since the thread | 553 // Acquire the V8 lock once initialization has finished. Since the thread |
537 // below may spawn new threads accessing V8 holding the V8 lock here is | 554 // below may spawn new threads accessing V8 holding the V8 lock here is |
538 // mandatory. | 555 // mandatory. |
539 Locker locker; | 556 Locker locker; |
540 Context::Scope context_scope(evaluation_context_); | 557 Context::Scope context_scope(evaluation_context_); |
541 for (int i = 1; i < argc; i++) { | 558 for (int i = 1; i < argc; i++) { |
542 char* str = argv[i]; | 559 char* str = argv[i]; |
543 if (strcmp(str, "--shell") == 0) { | 560 if (strcmp(str, "--shell") == 0) { |
544 run_shell = true; | 561 run_shell = true; |
| 562 } else if (strcmp(str, "--preemption") == 0) { |
| 563 use_preemption = true; |
| 564 } else if (strcmp(str, "--no-preemption") == 0) { |
| 565 use_preemption = false; |
| 566 } else if (strcmp(str, "--preemption-interval") == 0) { |
| 567 if (i + 1 < argc) { |
| 568 char *end = NULL; |
| 569 preemption_interval = strtol(argv[++i], &end, 10); // NOLINT |
| 570 if (preemption_interval <= 0 || *end != '\0' || errno == ERANGE) { |
| 571 printf("Invalid value for --preemption-interval '%s'\n", argv[i]); |
| 572 return 1; |
| 573 } |
| 574 } else { |
| 575 printf("Missing value for --preemption-interval\n"); |
| 576 return 1; |
| 577 } |
545 } else if (strcmp(str, "-f") == 0) { | 578 } else if (strcmp(str, "-f") == 0) { |
546 // Ignore any -f flags for compatibility with other stand-alone | 579 // Ignore any -f flags for compatibility with other stand-alone |
547 // JavaScript engines. | 580 // JavaScript engines. |
548 continue; | 581 continue; |
549 } else if (strncmp(str, "--", 2) == 0) { | 582 } else if (strncmp(str, "--", 2) == 0) { |
550 printf("Warning: unknown flag %s.\nTry --help for options\n", str); | 583 printf("Warning: unknown flag %s.\nTry --help for options\n", str); |
551 } else if (strcmp(str, "-e") == 0 && i + 1 < argc) { | 584 } else if (strcmp(str, "-e") == 0 && i + 1 < argc) { |
552 // Execute argument given to -e option directly. | 585 // Execute argument given to -e option directly. |
553 v8::HandleScope handle_scope; | 586 v8::HandleScope handle_scope; |
554 v8::Handle<v8::String> file_name = v8::String::New("unnamed"); | 587 v8::Handle<v8::String> file_name = v8::String::New("unnamed"); |
555 v8::Handle<v8::String> source = v8::String::New(argv[i + 1]); | 588 v8::Handle<v8::String> source = v8::String::New(argv[i + 1]); |
556 if (!ExecuteString(source, file_name, false, true)) | 589 if (!ExecuteString(source, file_name, false, true)) |
557 return 1; | 590 return 1; |
558 i++; | 591 i++; |
559 } else if (strcmp(str, "-p") == 0 && i + 1 < argc) { | 592 } else if (strcmp(str, "-p") == 0 && i + 1 < argc) { |
560 // Use the lowest possible thread preemption interval to test as many | |
561 // edgecases as possible. | |
562 Locker::StartPreemption(1); | |
563 int size = 0; | 593 int size = 0; |
564 const char *files = ReadChars(argv[++i], &size); | 594 const char *files = ReadChars(argv[++i], &size); |
565 if (files == NULL) return 1; | 595 if (files == NULL) return 1; |
566 ShellThread *thread = | 596 ShellThread *thread = |
567 new ShellThread(threads.length(), | 597 new ShellThread(threads.length(), |
568 i::Vector<const char>(files, size)); | 598 i::Vector<const char>(files, size)); |
569 thread->Start(); | 599 thread->Start(); |
570 threads.Add(thread); | 600 threads.Add(thread); |
571 } else { | 601 } else { |
572 // Use all other arguments as names of files to load and run. | 602 // Use all other arguments as names of files to load and run. |
573 HandleScope handle_scope; | 603 HandleScope handle_scope; |
574 Handle<String> file_name = v8::String::New(str); | 604 Handle<String> file_name = v8::String::New(str); |
575 Handle<String> source = ReadFile(str); | 605 Handle<String> source = ReadFile(str); |
576 if (source.IsEmpty()) { | 606 if (source.IsEmpty()) { |
577 printf("Error reading '%s'\n", str); | 607 printf("Error reading '%s'\n", str); |
578 return 1; | 608 return 1; |
579 } | 609 } |
580 if (!ExecuteString(source, file_name, false, true)) | 610 if (!ExecuteString(source, file_name, false, true)) |
581 return 1; | 611 return 1; |
582 } | 612 } |
583 } | 613 } |
584 | 614 |
| 615 // Start preemption if threads have been created and preemption is enabled. |
| 616 if (threads.length() > 0 && use_preemption) { |
| 617 Locker::StartPreemption(preemption_interval); |
| 618 } |
| 619 |
585 // Run the remote debugger if requested. | 620 // Run the remote debugger if requested. |
586 if (i::FLAG_remote_debugger) { | 621 if (i::FLAG_remote_debugger) { |
587 RunRemoteDebugger(i::FLAG_debugger_port); | 622 RunRemoteDebugger(i::FLAG_debugger_port); |
588 return 0; | 623 return 0; |
589 } | 624 } |
590 | 625 |
591 // Start the debugger agent if requested. | 626 // Start the debugger agent if requested. |
592 if (i::FLAG_debugger_agent) { | 627 if (i::FLAG_debugger_agent) { |
593 v8::Debug::EnableAgent(i::FLAG_debugger_port); | 628 v8::Debug::EnableAgent(i::FLAG_debugger_port); |
594 } | 629 } |
(...skipping 14 matching lines...) Expand all Loading... |
609 return 0; | 644 return 0; |
610 } | 645 } |
611 | 646 |
612 | 647 |
613 } // namespace v8 | 648 } // namespace v8 |
614 | 649 |
615 | 650 |
616 int main(int argc, char* argv[]) { | 651 int main(int argc, char* argv[]) { |
617 return v8::Shell::Main(argc, argv); | 652 return v8::Shell::Main(argc, argv); |
618 } | 653 } |
OLD | NEW |