d8.cc revision 7f4d5bd8c03935e2c0cd412e561b8fc5a6a880ae
1a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Copyright 2009 the V8 project authors. All rights reserved. 2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without 3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are 4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met: 5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Redistributions of source code must retain the above copyright 7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// notice, this list of conditions and the following disclaimer. 8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Redistributions in binary form must reproduce the above 9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// copyright notice, this list of conditions and the following 10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// disclaimer in the documentation and/or other materials provided 11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// with the distribution. 12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Neither the name of Google Inc. nor the names of its 13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// contributors may be used to endorse or promote products derived 14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// from this software without specific prior written permission. 15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include <stdlib.h> 30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include <errno.h> 31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "d8.h" 33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "d8-debug.h" 34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "debug.h" 35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "api.h" 36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "natives.h" 37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "platform.h" 38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 { 41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst char* Shell::kHistoryFileName = ".d8_history"; 44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst char* Shell::kPrompt = "d8> "; 45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockLineEditor *LineEditor::first_ = NULL; 48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockLineEditor::LineEditor(Type type, const char* name) 51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : type_(type), 52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block name_(name), 53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block next_(first_) { 54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block first_ = this; 55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockLineEditor* LineEditor::Get() { 59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block LineEditor* current = first_; 60a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block LineEditor* best = current; 61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (current != NULL) { 62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (current->type_ > best->type_) 63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block best = current; 64a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block current = current->next_; 65a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return best; 67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass DumbLineEditor: public LineEditor { 71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DumbLineEditor() : LineEditor(LineEditor::DUMB, "dumb") { } 73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual i::SmartPointer<char> Prompt(const char* prompt); 74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic DumbLineEditor dumb_line_editor; 78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocki::SmartPointer<char> DumbLineEditor::Prompt(const char* prompt) { 81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const int kBufferSize = 256; 82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block char buffer[kBufferSize]; 83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block printf("%s", prompt); 84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block char* str = fgets(buffer, kBufferSize, stdin); 85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return i::SmartPointer<char>(str ? i::StrDup(str) : str); 86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockCounterMap* Shell::counter_map_; 90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocki::OS::MemoryMappedFile* Shell::counters_file_ = NULL; 91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockCounterCollection Shell::local_counters_; 92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockCounterCollection* Shell::counters_ = &local_counters_; 93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockPersistent<Context> Shell::utility_context_; 94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockPersistent<Context> Shell::evaluation_context_; 95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool CounterMap::Match(void* key1, void* key2) { 98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* name1 = reinterpret_cast<const char*>(key1); 99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* name2 = reinterpret_cast<const char*>(key2); 100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return strcmp(name1, name2) == 0; 101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Converts a V8 value to a C string. 1056ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockconst char* Shell::ToCString(const v8::String::Utf8Value& value) { 106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return *value ? *value : "<string conversion failed>"; 107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Executes a string within the current v8 context. 111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool Shell::ExecuteString(Handle<String> source, 112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Value> name, 113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool print_result, 114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool report_exceptions) { 115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block HandleScope handle_scope; 116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block TryCatch try_catch; 117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (i::FLAG_debugger) { 118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // When debugging make exceptions appear to be uncaught. 119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block try_catch.SetVerbose(true); 120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Script> script = Script::Compile(source, name); 122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (script.IsEmpty()) { 123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Print errors that happened during compilation. 124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (report_exceptions && !i::FLAG_debugger) 125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ReportException(&try_catch); 126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return false; 127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Value> result = script->Run(); 129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (result.IsEmpty()) { 130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Print errors that happened during execution. 131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (report_exceptions && !i::FLAG_debugger) 132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ReportException(&try_catch); 133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return false; 134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (print_result && !result->IsUndefined()) { 136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If all went well and the result wasn't undefined then print 137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the returned value. 138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::String::Utf8Value str(result); 139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* cstr = ToCString(str); 140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block printf("%s\n", cstr); 141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return true; 143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Value> Shell::Print(const Arguments& args) { 149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Value> val = Write(args); 150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block printf("\n"); 151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return val; 152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Value> Shell::Write(const Arguments& args) { 156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < args.Length(); i++) { 157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block HandleScope handle_scope; 158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (i != 0) { 159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block printf(" "); 160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::String::Utf8Value str(args[i]); 162d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block int n = fwrite(*str, sizeof(**str), str.length(), stdout); 163d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (n != str.length()) { 164d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block printf("Error in fwrite\n"); 165d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block exit(1); 166d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Undefined(); 169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Value> Shell::Read(const Arguments& args) { 173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block String::Utf8Value file(args[0]); 174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (*file == NULL) { 175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return ThrowException(String::New("Error loading file")); 176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<String> source = ReadFile(*file); 178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (source.IsEmpty()) { 179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return ThrowException(String::New("Error loading file")); 180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return source; 182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Value> Shell::ReadLine(const Arguments& args) { 186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block i::SmartPointer<char> line(i::ReadLine("")); 187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (*line == NULL) { 188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Null(); 189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block size_t len = strlen(*line); 191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (len > 0 && line[len - 1] == '\n') { 192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block --len; 193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return String::New(*line, len); 195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Value> Shell::Load(const Arguments& args) { 199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < args.Length(); i++) { 200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block HandleScope handle_scope; 201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block String::Utf8Value file(args[i]); 202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (*file == NULL) { 203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return ThrowException(String::New("Error loading file")); 204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<String> source = ReadFile(*file); 206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (source.IsEmpty()) { 207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return ThrowException(String::New("Error loading file")); 208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!ExecuteString(source, String::New(*file), false, false)) { 210d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block return ThrowException(String::New("Error executing file")); 211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Undefined(); 214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Value> Shell::Yield(const Arguments& args) { 218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Unlocker unlocker; 219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Undefined(); 220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Value> Shell::Quit(const Arguments& args) { 224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int exit_code = args[0]->Int32Value(); 225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block OnExit(); 226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block exit(exit_code); 227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Undefined(); 228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Value> Shell::Version(const Arguments& args) { 232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return String::New(V8::GetVersion()); 233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Shell::ReportException(v8::TryCatch* try_catch) { 237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block HandleScope handle_scope; 238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::String::Utf8Value exception(try_catch->Exception()); 239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* exception_string = ToCString(exception); 240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Message> message = try_catch->Message(); 241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (message.IsEmpty()) { 242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // V8 didn't provide any extra information about this error; just 243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // print the exception. 244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block printf("%s\n", exception_string); 245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Print (filename):(line number): (message). 247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::String::Utf8Value filename(message->GetScriptResourceName()); 248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* filename_string = ToCString(filename); 249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int linenum = message->GetLineNumber(); 250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block printf("%s:%i: %s\n", filename_string, linenum, exception_string); 251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Print line of source code. 252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::String::Utf8Value sourceline(message->GetSourceLine()); 253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* sourceline_string = ToCString(sourceline); 254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block printf("%s\n", sourceline_string); 255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Print wavy underline (GetUnderline is deprecated). 256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int start = message->GetStartColumn(); 257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < start; i++) { 258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block printf(" "); 259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int end = message->GetEndColumn(); 261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = start; i < end; i++) { 262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block printf("^"); 263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block printf("\n"); 265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Array> Shell::GetCompletions(Handle<String> text, Handle<String> full) { 270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block HandleScope handle_scope; 271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Context::Scope context_scope(utility_context_); 272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> global = utility_context_->Global(); 273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Value> fun = global->Get(String::New("GetCompletions")); 274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const int kArgc = 3; 275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Value> argv[kArgc] = { evaluation_context_->Global(), text, full }; 276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Value> val = Handle<Function>::Cast(fun)->Call(global, kArgc, argv); 277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return handle_scope.Close(Handle<Array>::Cast(val)); 278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT 282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> Shell::DebugMessageDetails(Handle<String> message) { 283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Context::Scope context_scope(utility_context_); 284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> global = utility_context_->Global(); 285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Value> fun = global->Get(String::New("DebugMessageDetails")); 286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const int kArgc = 1; 287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Value> argv[kArgc] = { message }; 288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Value> val = Handle<Function>::Cast(fun)->Call(global, kArgc, argv); 289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Handle<Object>::Cast(val); 290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Value> Shell::DebugCommandToJSONRequest(Handle<String> command) { 294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Context::Scope context_scope(utility_context_); 295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> global = utility_context_->Global(); 296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Value> fun = global->Get(String::New("DebugCommandToJSONRequest")); 297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const int kArgc = 1; 298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Value> argv[kArgc] = { command }; 299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Value> val = Handle<Function>::Cast(fun)->Call(global, kArgc, argv); 300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return val; 301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint32_t* Counter::Bind(const char* name, bool is_histogram) { 306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int i; 307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (i = 0; i < kMaxNameSize - 1 && name[i]; i++) 308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block name_[i] = static_cast<char>(name[i]); 309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block name_[i] = '\0'; 310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block is_histogram_ = is_histogram; 311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return ptr(); 312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Counter::AddSample(int32_t sample) { 316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block count_++; 317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block sample_total_ += sample; 318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockCounterCollection::CounterCollection() { 322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block magic_number_ = 0xDEADFACE; 323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block max_counters_ = kMaxCounters; 324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block max_name_size_ = Counter::kMaxNameSize; 325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block counters_in_use_ = 0; 326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockCounter* CounterCollection::GetNextCounter() { 330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (counters_in_use_ == kMaxCounters) return NULL; 331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return &counters_[counters_in_use_++]; 332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Shell::MapCounters(const char* name) { 336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block counters_file_ = i::OS::MemoryMappedFile::create(name, 337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block sizeof(CounterCollection), &local_counters_); 338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void* memory = (counters_file_ == NULL) ? 339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block NULL : counters_file_->memory(); 340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (memory == NULL) { 341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block printf("Could not map counters file %s\n", name); 342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block exit(1); 343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block counters_ = static_cast<CounterCollection*>(memory); 345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block V8::SetCounterFunction(LookupCounter); 346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block V8::SetCreateHistogramFunction(CreateHistogram); 347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block V8::SetAddHistogramSampleFunction(AddHistogramSample); 348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint CounterMap::Hash(const char* name) { 352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int h = 0; 353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int c; 354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while ((c = *name++) != 0) { 355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block h += h << 5; 356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block h += c; 357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return h; 359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockCounter* Shell::GetCounter(const char* name, bool is_histogram) { 363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Counter* counter = counter_map_->Lookup(name); 364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (counter == NULL) { 366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block counter = counters_->GetNextCounter(); 367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (counter != NULL) { 368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block counter_map_->Set(name, counter); 369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block counter->Bind(name, is_histogram); 370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(counter->is_histogram() == is_histogram); 373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return counter; 375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint* Shell::LookupCounter(const char* name) { 379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Counter* counter = GetCounter(name, false); 380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (counter != NULL) { 382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return counter->ptr(); 383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return NULL; 385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 389a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid* Shell::CreateHistogram(const char* name, 390a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int min, 391a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int max, 392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block size_t buckets) { 393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return GetCounter(name, true); 394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Shell::AddHistogramSample(void* histogram, int sample) { 398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Counter* counter = reinterpret_cast<Counter*>(histogram); 399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block counter->AddSample(sample); 400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Shell::Initialize() { 404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Shell::counter_map_ = new CounterMap(); 405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set up counters 406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (i::FLAG_map_counters != NULL) 407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block MapCounters(i::FLAG_map_counters); 408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (i::FLAG_dump_counters) { 409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block V8::SetCounterFunction(LookupCounter); 410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block V8::SetCreateHistogramFunction(CreateHistogram); 411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block V8::SetAddHistogramSampleFunction(AddHistogramSample); 412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Initialize the global objects 415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block HandleScope scope; 416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<ObjectTemplate> global_template = ObjectTemplate::New(); 417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block global_template->Set(String::New("print"), FunctionTemplate::New(Print)); 418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block global_template->Set(String::New("write"), FunctionTemplate::New(Write)); 419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block global_template->Set(String::New("read"), FunctionTemplate::New(Read)); 420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block global_template->Set(String::New("readline"), 421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block FunctionTemplate::New(ReadLine)); 422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block global_template->Set(String::New("load"), FunctionTemplate::New(Load)); 423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block global_template->Set(String::New("quit"), FunctionTemplate::New(Quit)); 424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block global_template->Set(String::New("version"), FunctionTemplate::New(Version)); 425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<ObjectTemplate> os_templ = ObjectTemplate::New(); 427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block AddOSMethods(os_templ); 428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block global_template->Set(String::New("os"), os_templ); 429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block utility_context_ = Context::New(NULL, global_template); 431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block utility_context_->SetSecurityToken(Undefined()); 432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Context::Scope utility_scope(utility_context_); 433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block i::JSArguments js_args = i::FLAG_js_arguments; 435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block i::Handle<i::FixedArray> arguments_array = 436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block i::Factory::NewFixedArray(js_args.argc()); 437a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int j = 0; j < js_args.argc(); j++) { 438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block i::Handle<i::String> arg = 439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block i::Factory::NewStringFromUtf8(i::CStrVector(js_args[j])); 440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arguments_array->set(j, *arg); 441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block i::Handle<i::JSArray> arguments_jsarray = 443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block i::Factory::NewJSArrayWithElements(arguments_array); 444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block global_template->Set(String::New("arguments"), 445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Utils::ToLocal(arguments_jsarray)); 446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT 448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Install the debugger object in the utility scope 449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block i::Debug::Load(); 4506ded16be15dd865a9b21ea304d5273c8be299c87Steve Block i::Handle<i::JSObject> debug 4516ded16be15dd865a9b21ea304d5273c8be299c87Steve Block = i::Handle<i::JSObject>(i::Debug::debug_context()->global()); 452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block utility_context_->Global()->Set(String::New("$debug"), 4536ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Utils::ToLocal(debug)); 454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Run the d8 shell utility script in the utility context 457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int source_index = i::NativesCollection<i::D8>::GetIndex("d8"); 458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block i::Vector<const char> shell_source 459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block = i::NativesCollection<i::D8>::GetScriptSource(source_index); 460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block i::Vector<const char> shell_source_name 461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block = i::NativesCollection<i::D8>::GetScriptName(source_index); 462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<String> source = String::New(shell_source.start(), 463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block shell_source.length()); 464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<String> name = String::New(shell_source_name.start(), 465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block shell_source_name.length()); 466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Script> script = Script::Compile(source, name); 467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block script->Run(); 468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Mark the d8 shell script as native to avoid it showing up as normal source 470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // in the debugger. 4716ded16be15dd865a9b21ea304d5273c8be299c87Steve Block i::Handle<i::Object> compiled_script = Utils::OpenHandle(*script); 4726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block i::Handle<i::Script> script_object = compiled_script->IsJSFunction() 4736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ? i::Handle<i::Script>(i::Script::cast( 4746ded16be15dd865a9b21ea304d5273c8be299c87Steve Block i::JSFunction::cast(*compiled_script)->shared()->script())) 4756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block : i::Handle<i::Script>(i::Script::cast( 4766ded16be15dd865a9b21ea304d5273c8be299c87Steve Block i::SharedFunctionInfo::cast(*compiled_script)->script())); 477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block script_object->set_type(i::Smi::FromInt(i::Script::TYPE_NATIVE)); 478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create the evaluation context 480a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block evaluation_context_ = Context::New(NULL, global_template); 481a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block evaluation_context_->SetSecurityToken(Undefined()); 482a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT 484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set the security token of the debug context to allow access. 485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block i::Debug::debug_context()->set_security_token(i::Heap::undefined_value()); 486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Start the debugger agent if requested. 488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (i::FLAG_debugger_agent) { 489a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::EnableAgent("d8 shell", i::FLAG_debugger_port); 490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Start the in-process debugger if requested. 493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (i::FLAG_debugger && !i::FLAG_debugger_agent) { 494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(HandleDebugEvent); 495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Shell::OnExit() { 501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (i::FLAG_dump_counters) { 502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ::printf("+----------------------------------------+-------------+\n"); 503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ::printf("| Name | Value |\n"); 504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ::printf("+----------------------------------------+-------------+\n"); 505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (CounterMap::Iterator i(counter_map_); i.More(); i.Next()) { 506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Counter* counter = i.CurrentValue(); 507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (counter->is_histogram()) { 508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ::printf("| c:%-36s | %11i |\n", i.CurrentKey(), counter->count()); 509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ::printf("| t:%-36s | %11i |\n", 510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block i.CurrentKey(), 511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block counter->sample_total()); 512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ::printf("| %-38s | %11i |\n", i.CurrentKey(), counter->count()); 514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ::printf("+----------------------------------------+-------------+\n"); 517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (counters_file_ != NULL) 519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block delete counters_file_; 520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 521a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 522a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic char* ReadChars(const char* name, int* size_out) { 524a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Unlocker unlocker; // Release the V8 lock while reading files. 525a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block FILE* file = i::OS::FOpen(name, "rb"); 526a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (file == NULL) return NULL; 527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 528a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block fseek(file, 0, SEEK_END); 529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int size = ftell(file); 530a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block rewind(file); 531a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 532a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block char* chars = new char[size + 1]; 533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block chars[size] = '\0'; 534a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < size;) { 535a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int read = fread(&chars[i], 1, size - i, file); 536a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block i += read; 537a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 538a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block fclose(file); 539a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *size_out = size; 540a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return chars; 541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 543a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 544a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic char* ReadToken(char* data, char token) { 545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block char* next = i::OS::StrChr(data, token); 546a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (next != NULL) { 547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *next = '\0'; 548a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return (next + 1); 549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return NULL; 552a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 553a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 554a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 555a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic char* ReadLine(char* data) { 556a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return ReadToken(data, '\n'); 557a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic char* ReadWord(char* data) { 561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return ReadToken(data, ' '); 562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Reads a file into a v8 string. 566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<String> Shell::ReadFile(const char* name) { 567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int size = 0; 568a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block char* chars = ReadChars(name, &size); 569a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (chars == NULL) return Handle<String>(); 570a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<String> result = String::New(chars); 571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block delete[] chars; 572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return result; 573a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Shell::RunShell() { 577a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block LineEditor* editor = LineEditor::Get(); 578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block printf("V8 version %s [console: %s]\n", V8::GetVersion(), editor->name()); 5797f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch if (i::FLAG_debugger) { 5807f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch printf("JavaScript debugger enabled\n"); 5817f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } 582a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block editor->Open(); 583a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (true) { 584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Locker locker; 585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block HandleScope handle_scope; 586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Context::Scope context_scope(evaluation_context_); 587a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block i::SmartPointer<char> input = editor->Prompt(Shell::kPrompt); 588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (input.is_empty()) 589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block editor->AddHistory(*input); 591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<String> name = String::New("(d8)"); 592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ExecuteString(String::New(*input), name, true, true); 593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block editor->Close(); 595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block printf("\n"); 596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass ShellThread : public i::Thread { 600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ShellThread(int no, i::Vector<const char> files) 602a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : no_(no), files_(files) { } 603a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual void Run(); 604a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 605a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int no_; 606a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block i::Vector<const char> files_; 607a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 608a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 610a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid ShellThread::Run() { 611a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Prepare the context for this thread. 612a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Locker locker; 613a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block HandleScope scope; 614a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<ObjectTemplate> global_template = ObjectTemplate::New(); 615a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block global_template->Set(String::New("print"), 616a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block FunctionTemplate::New(Shell::Print)); 617a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block global_template->Set(String::New("write"), 618a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block FunctionTemplate::New(Shell::Write)); 619a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block global_template->Set(String::New("read"), 620a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block FunctionTemplate::New(Shell::Read)); 621a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block global_template->Set(String::New("readline"), 622a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block FunctionTemplate::New(Shell::ReadLine)); 623a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block global_template->Set(String::New("load"), 624a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block FunctionTemplate::New(Shell::Load)); 625a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block global_template->Set(String::New("yield"), 626a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block FunctionTemplate::New(Shell::Yield)); 627a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block global_template->Set(String::New("version"), 628a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block FunctionTemplate::New(Shell::Version)); 629a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 630a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block char* ptr = const_cast<char*>(files_.start()); 631a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while ((ptr != NULL) && (*ptr != '\0')) { 632a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // For each newline-separated line. 633a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block char* next_line = ReadLine(ptr); 634a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 635a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (*ptr == '#') { 636a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Skip comment lines. 637a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ptr = next_line; 638a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block continue; 639a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 640a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 641a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Persistent<Context> thread_context = Context::New(NULL, global_template); 642a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_context->SetSecurityToken(Undefined()); 643a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Context::Scope context_scope(thread_context); 644a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 645a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while ((ptr != NULL) && (*ptr != '\0')) { 646a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block char* filename = ptr; 647a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ptr = ReadWord(ptr); 648a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 649a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Skip empty strings. 650a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (strlen(filename) == 0) { 651a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 652a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 654a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<String> str = Shell::ReadFile(filename); 655a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (str.IsEmpty()) { 656a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block printf("WARNING: %s not found\n", filename); 657a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 658a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 660a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Shell::ExecuteString(str, String::New(filename), false, false); 661a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 662a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 663a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_context.Dispose(); 664a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ptr = next_line; 665a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 666a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 667a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 668a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 669a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint Shell::Main(int argc, char* argv[]) { 670a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block i::FlagList::SetFlagsFromCommandLine(&argc, argv, true); 671a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (i::FLAG_help) { 672a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return 1; 673a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 674a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Initialize(); 675a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool run_shell = (argc == 1); 676a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 677a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Default use preemption if threads are created. 678a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool use_preemption = true; 679a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 680a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Default to use lowest possible thread preemption interval to test as many 681a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // edgecases as possible. 682a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int preemption_interval = 1; 683a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 684a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block i::List<i::Thread*> threads(1); 685a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 686a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block { 687a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Acquire the V8 lock once initialization has finished. Since the thread 688a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // below may spawn new threads accessing V8 holding the V8 lock here is 689a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // mandatory. 690a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Locker locker; 691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Context::Scope context_scope(evaluation_context_); 692a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 1; i < argc; i++) { 693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block char* str = argv[i]; 694a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (strcmp(str, "--shell") == 0) { 695a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block run_shell = true; 696a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (strcmp(str, "--preemption") == 0) { 697a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block use_preemption = true; 698a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (strcmp(str, "--no-preemption") == 0) { 699a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block use_preemption = false; 700a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (strcmp(str, "--preemption-interval") == 0) { 701a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (i + 1 < argc) { 702a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block char* end = NULL; 703a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block preemption_interval = strtol(argv[++i], &end, 10); // NOLINT 704a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (preemption_interval <= 0 || *end != '\0' || errno == ERANGE) { 705a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block printf("Invalid value for --preemption-interval '%s'\n", argv[i]); 706a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return 1; 707a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 708a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 709a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block printf("Missing value for --preemption-interval\n"); 710a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return 1; 711a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 712a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (strcmp(str, "-f") == 0) { 713a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Ignore any -f flags for compatibility with other stand-alone 714a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // JavaScript engines. 715a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block continue; 716a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (strncmp(str, "--", 2) == 0) { 717a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block printf("Warning: unknown flag %s.\nTry --help for options\n", str); 718a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (strcmp(str, "-e") == 0 && i + 1 < argc) { 719a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Execute argument given to -e option directly. 720a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope handle_scope; 721a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::String> file_name = v8::String::New("unnamed"); 722a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::String> source = v8::String::New(argv[i + 1]); 723a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!ExecuteString(source, file_name, false, true)) { 724a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block OnExit(); 725a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return 1; 726a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 727a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block i++; 728a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (strcmp(str, "-p") == 0 && i + 1 < argc) { 729a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int size = 0; 730a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* files = ReadChars(argv[++i], &size); 731a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (files == NULL) return 1; 732a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ShellThread* thread = 733a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block new ShellThread(threads.length(), 734a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block i::Vector<const char>(files, size)); 735a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread->Start(); 736a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block threads.Add(thread); 737a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 738a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Use all other arguments as names of files to load and run. 739a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block HandleScope handle_scope; 740a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<String> file_name = v8::String::New(str); 741a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<String> source = ReadFile(str); 742a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (source.IsEmpty()) { 743a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block printf("Error reading '%s'\n", str); 744a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return 1; 745a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 746a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!ExecuteString(source, file_name, false, true)) { 747a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block OnExit(); 748a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return 1; 749a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 750a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 751a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 752a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 753a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Start preemption if threads have been created and preemption is enabled. 754a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (threads.length() > 0 && use_preemption) { 755a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Locker::StartPreemption(preemption_interval); 756a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 757a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 758a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT 759a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Run the remote debugger if requested. 760a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (i::FLAG_remote_debugger) { 761a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RunRemoteDebugger(i::FLAG_debugger_port); 762a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return 0; 763a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 764a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 765a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 766a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (run_shell) 767a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RunShell(); 768a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < threads.length(); i++) { 769a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block i::Thread* thread = threads[i]; 770a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread->Join(); 771a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block delete thread; 772a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 773a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block OnExit(); 774a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return 0; 775a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 776a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 777a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 778a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} // namespace v8 779a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 780a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 781a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint main(int argc, char* argv[]) { 782a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return v8::Shell::Main(argc, argv); 783a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 784