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