1e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// Copyright 2009 the V8 project authors. All rights reserved. 2e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// Redistribution and use in source and binary forms, with or without 3e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// modification, are permitted provided that the following conditions are 4e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// met: 5e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// 6e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// * Redistributions of source code must retain the above copyright 7e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// notice, this list of conditions and the following disclaimer. 8e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// * Redistributions in binary form must reproduce the above 9e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// copyright notice, this list of conditions and the following 10e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// disclaimer in the documentation and/or other materials provided 11e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// with the distribution. 12e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// * Neither the name of Google Inc. nor the names of its 13e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// contributors may be used to endorse or promote products derived 14e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// from this software without specific prior written permission. 15e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// 16e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 286ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 296ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// This controls whether this sample is compiled with debugger support. 306ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// You may trace its usages in source text to see what parts of program 316ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// are responsible for debugging support. 326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// Note that V8 itself should be compiled with enabled debugger support 336ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// to have it all working. 346ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#define SUPPORT_DEBUGGING 356ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 36e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke#include <v8.h> 376ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 386ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#ifdef SUPPORT_DEBUGGING 39e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke#include <v8-debug.h> 406ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#endif 416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 42e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke#include <fcntl.h> 43e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke#include <string.h> 44e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke#include <stdio.h> 45e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke#include <stdlib.h> 46e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 47e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke/** 48e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke * This sample program should demonstrate certain aspects of debugging 49e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke * standalone V8-based application. 50e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke * 51e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke * The program reads input stream, processes it line by line and print 52e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke * the result to output. The actual processing is done by custom JavaScript 53e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke * script. The script is specified with command line parameters. 54e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke * 55e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke * The main cycle of the program will sequentially read lines from standard 56e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke * input, process them and print to standard output until input closes. 57e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke * There are 2 possible configuration in regard to main cycle. 58e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke * 59e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke * 1. The main cycle is on C++ side. Program should be run with 60e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke * --main-cycle-in-cpp option. Script must declare a function named 61e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke * "ProcessLine". The main cycle in C++ reads lines and calls this function 62e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke * for processing every time. This is a sample script: 63e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 64e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkefunction ProcessLine(input_line) { 65e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke return ">>>" + input_line + "<<<"; 66e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 67e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 68e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke * 69e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke * 2. The main cycle is in JavaScript. Program should be run with 70e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke * --main-cycle-in-js option. Script gets run one time at all and gets 71e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke * API of 2 global functions: "read_line" and "print". It should read input 72e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke * and print converted lines to output itself. This a sample script: 73e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 74e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkewhile (true) { 75e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke var line = read_line(); 76e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if (!line) { 77e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke break; 78e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 79e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke var res = line + " | " + line; 80e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke print(res); 81e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 82e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 83e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke * 84e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke * When run with "-p" argument, the program starts V8 Debugger Agent and 85e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke * allows remote debugger to attach and debug JavaScript code. 86e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke * 87e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke * Interesting aspects: 88e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke * 1. Wait for remote debugger to attach 89e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke * Normally the program compiles custom script and immediately runs it. 90e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke * If programmer needs to debug script from the very beginning, he should 91e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke * run this sample program with "--wait-for-connection" command line parameter. 92e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke * This way V8 will suspend on the first statement and wait for 93e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke * debugger to attach. 94e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke * 95e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke * 2. Unresponsive V8 96e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke * V8 Debugger Agent holds a connection with remote debugger, but it does 97e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke * respond only when V8 is running some script. In particular, when this program 98e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke * is waiting for input, all requests from debugger get deferred until V8 99e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke * is called again. See how "--callback" command-line parameter in this sample 100e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke * fixes this issue. 101e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke */ 102e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 103e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkeenum MainCycleType { 104e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke CycleInCpp, 105e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke CycleInJs 106e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke}; 107e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 108e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkeconst char* ToCString(const v8::String::Utf8Value& value); 109e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkevoid ReportException(v8::TryCatch* handler); 110e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkev8::Handle<v8::String> ReadFile(const char* name); 111e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkev8::Handle<v8::String> ReadLine(); 112e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 113e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkev8::Handle<v8::Value> Print(const v8::Arguments& args); 114e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkev8::Handle<v8::Value> ReadLine(const v8::Arguments& args); 115e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkebool RunCppCycle(v8::Handle<v8::Script> script, v8::Local<v8::Context> context, 116e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke bool report_exceptions); 117e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 118e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 1196ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#ifdef SUPPORT_DEBUGGING 1206ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockv8::Persistent<v8::Context> debug_message_context; 121e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 122e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkevoid DispatchDebugMessages() { 123e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // We are in some random thread. We should already have v8::Locker acquired 124e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // (we requested this when registered this callback). We was called 125e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // because new debug messages arrived; they may have already been processed, 126e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // but we shouldn't worry about this. 127e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // 128e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // All we have to do is to set context and call ProcessDebugMessages. 129e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // 130e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // We should decide which V8 context to use here. This is important for 131e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // "evaluate" command, because it must be executed some context. 132e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // In our sample we have only one context, so there is nothing really to 133e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // think about. 134e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::Context::Scope scope(debug_message_context); 135e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 136e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::Debug::ProcessDebugMessages(); 137e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 1386ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#endif 139e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 140e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 141e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkeint RunMain(int argc, char* argv[]) { 142e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::V8::SetFlagsFromCommandLine(&argc, argv, true); 143e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::HandleScope handle_scope; 144e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 145e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::Handle<v8::String> script_source(NULL); 146e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::Handle<v8::Value> script_name(NULL); 147e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke int script_param_counter = 0; 148e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 1496ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#ifdef SUPPORT_DEBUGGING 150e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke int port_number = -1; 151e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke bool wait_for_connection = false; 152d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke bool support_callback = false; 1536ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#endif 1546ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 155e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke MainCycleType cycle_type = CycleInCpp; 156e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 157e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke for (int i = 1; i < argc; i++) { 158e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke const char* str = argv[i]; 159e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if (strcmp(str, "-f") == 0) { 160e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Ignore any -f flags for compatibility with the other stand- 161e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // alone JavaScript engines. 162e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke continue; 163e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } else if (strcmp(str, "--main-cycle-in-cpp") == 0) { 164e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke cycle_type = CycleInCpp; 165e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } else if (strcmp(str, "--main-cycle-in-js") == 0) { 166e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke cycle_type = CycleInJs; 1676ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#ifdef SUPPORT_DEBUGGING 1686ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } else if (strcmp(str, "--callback") == 0) { 1696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block support_callback = true; 1706ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } else if (strcmp(str, "--wait-for-connection") == 0) { 1716ded16be15dd865a9b21ea304d5273c8be299c87Steve Block wait_for_connection = true; 172e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } else if (strcmp(str, "-p") == 0 && i + 1 < argc) { 173402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu port_number = atoi(argv[i + 1]); // NOLINT 174e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke i++; 1756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#endif 176e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } else if (strncmp(str, "--", 2) == 0) { 177e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke printf("Warning: unknown flag %s.\nTry --help for options\n", str); 178e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } else if (strcmp(str, "-e") == 0 && i + 1 < argc) { 179e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke script_source = v8::String::New(argv[i + 1]); 180e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke script_name = v8::String::New("unnamed"); 181e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke i++; 182e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke script_param_counter++; 183e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } else { 184e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Use argument as a name of file to load. 185e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke script_source = ReadFile(str); 186e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke script_name = v8::String::New(str); 187e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if (script_source.IsEmpty()) { 188e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke printf("Error reading '%s'\n", str); 189e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke return 1; 190e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 191e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke script_param_counter++; 192e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 193e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 194e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 195e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if (script_param_counter == 0) { 196e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke printf("Script is not specified\n"); 197e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke return 1; 198e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 199e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if (script_param_counter != 1) { 200e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke printf("Only one script may be specified\n"); 201e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke return 1; 202e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 203e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 204e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Create a template for the global object. 205e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New(); 206e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 207e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Bind the global 'print' function to the C++ Print callback. 208e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke global->Set(v8::String::New("print"), v8::FunctionTemplate::New(Print)); 209e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 210e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if (cycle_type == CycleInJs) { 211e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Bind the global 'read_line' function to the C++ Print callback. 212e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke global->Set(v8::String::New("read_line"), 213e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::FunctionTemplate::New(ReadLine)); 214e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 215e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 216e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Create a new execution environment containing the built-in 217e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // functions 218e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::Handle<v8::Context> context = v8::Context::New(NULL, global); 219e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Enter the newly created execution environment. 220e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::Context::Scope context_scope(context); 221e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2226ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#ifdef SUPPORT_DEBUGGING 2236ded16be15dd865a9b21ea304d5273c8be299c87Steve Block debug_message_context = v8::Persistent<v8::Context>::New(context); 2246ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 225e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::Locker locker; 226e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 227e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if (support_callback) { 228e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::Debug::SetDebugMessageDispatchHandler(DispatchDebugMessages, true); 229e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 230e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 231e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if (port_number != -1) { 232e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::Debug::EnableAgent("lineprocessor", port_number, wait_for_connection); 233e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 2346ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#endif 235e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 236e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke bool report_exceptions = true; 237e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 238e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::Handle<v8::Script> script; 239e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke { 240e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Compile script in try/catch context. 241e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::TryCatch try_catch; 242e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke script = v8::Script::Compile(script_source, script_name); 243e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if (script.IsEmpty()) { 244e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Print errors that happened during compilation. 245e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if (report_exceptions) 246e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke ReportException(&try_catch); 247e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke return 1; 248e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 249e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 250e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 251e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke { 252e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::TryCatch try_catch; 253e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 254e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke script->Run(); 255e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if (try_catch.HasCaught()) { 256e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if (report_exceptions) 257e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke ReportException(&try_catch); 258e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke return 1; 259e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 260e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 261e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 262e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if (cycle_type == CycleInCpp) { 263e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke bool res = RunCppCycle(script, v8::Context::GetCurrent(), 264e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke report_exceptions); 265e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke return !res; 266e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } else { 267e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // All is already done. 268e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 269e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke return 0; 270e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 271e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 272e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 273e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkebool RunCppCycle(v8::Handle<v8::Script> script, v8::Local<v8::Context> context, 274e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke bool report_exceptions) { 2756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#ifdef SUPPORT_DEBUGGING 276e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::Locker lock; 2776ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#endif 278e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 279e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::Handle<v8::String> fun_name = v8::String::New("ProcessLine"); 280e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::Handle<v8::Value> process_val = 281e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::Context::GetCurrent()->Global()->Get(fun_name); 282e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 283e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // If there is no Process function, or if it is not a function, 284e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // bail out 285e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if (!process_val->IsFunction()) { 286e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke printf("Error: Script does not declare 'ProcessLine' global function.\n"); 287e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke return 1; 288e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 289e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 290e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // It is a function; cast it to a Function 291e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::Handle<v8::Function> process_fun = 292e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::Handle<v8::Function>::Cast(process_val); 293e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 294e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 295e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke while (!feof(stdin)) { 296e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::HandleScope handle_scope; 297e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 298e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::Handle<v8::String> input_line = ReadLine(); 299e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if (input_line == v8::Undefined()) { 300e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke continue; 301e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 302e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 303e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke const int argc = 1; 304e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::Handle<v8::Value> argv[argc] = { input_line }; 305e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 306e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::Handle<v8::Value> result; 307e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke { 308e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::TryCatch try_catch; 309e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke result = process_fun->Call(v8::Context::GetCurrent()->Global(), 310e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke argc, argv); 311e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if (try_catch.HasCaught()) { 312e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if (report_exceptions) 313e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke ReportException(&try_catch); 314e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke return false; 315e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 316e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 317e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::String::Utf8Value str(result); 318e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke const char* cstr = ToCString(str); 319e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke printf("%s\n", cstr); 320e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 321e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 322e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke return true; 323e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 324e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 325e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkeint main(int argc, char* argv[]) { 326e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke int result = RunMain(argc, argv); 327e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::V8::Dispose(); 328e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke return result; 329e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 330e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 331e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 332e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// Extracts a C string from a V8 Utf8Value. 333e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkeconst char* ToCString(const v8::String::Utf8Value& value) { 334e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke return *value ? *value : "<string conversion failed>"; 335e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 336e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 337e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 338e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// Reads a file into a v8 string. 339e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkev8::Handle<v8::String> ReadFile(const char* name) { 340e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke FILE* file = fopen(name, "rb"); 341e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if (file == NULL) return v8::Handle<v8::String>(); 342e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 343e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke fseek(file, 0, SEEK_END); 344e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke int size = ftell(file); 345e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke rewind(file); 346e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 347e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke char* chars = new char[size + 1]; 348e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke chars[size] = '\0'; 349e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke for (int i = 0; i < size;) { 350e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke int read = fread(&chars[i], 1, size - i, file); 351e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke i += read; 352e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 353e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke fclose(file); 354e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::Handle<v8::String> result = v8::String::New(chars, size); 355e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke delete[] chars; 356e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke return result; 357e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 358e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 359e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 360e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkevoid ReportException(v8::TryCatch* try_catch) { 361e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::HandleScope handle_scope; 362e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::String::Utf8Value exception(try_catch->Exception()); 363e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke const char* exception_string = ToCString(exception); 364e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::Handle<v8::Message> message = try_catch->Message(); 365e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if (message.IsEmpty()) { 366e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // V8 didn't provide any extra information about this error; just 367e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // print the exception. 368e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke printf("%s\n", exception_string); 369e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } else { 370e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Print (filename):(line number): (message). 371e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::String::Utf8Value filename(message->GetScriptResourceName()); 372e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke const char* filename_string = ToCString(filename); 373e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke int linenum = message->GetLineNumber(); 374e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke printf("%s:%i: %s\n", filename_string, linenum, exception_string); 375e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Print line of source code. 376e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::String::Utf8Value sourceline(message->GetSourceLine()); 377e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke const char* sourceline_string = ToCString(sourceline); 378e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke printf("%s\n", sourceline_string); 379e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Print wavy underline (GetUnderline is deprecated). 380e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke int start = message->GetStartColumn(); 381e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke for (int i = 0; i < start; i++) { 382e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke printf(" "); 383e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 384e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke int end = message->GetEndColumn(); 385e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke for (int i = start; i < end; i++) { 386e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke printf("^"); 387e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 388e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke printf("\n"); 389e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 390e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 391e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 392e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 393e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// The callback that is invoked by v8 whenever the JavaScript 'print' 394e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// function is called. Prints its arguments on stdout separated by 395e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// spaces and ending with a newline. 396e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkev8::Handle<v8::Value> Print(const v8::Arguments& args) { 397e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke bool first = true; 398e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke for (int i = 0; i < args.Length(); i++) { 399e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::HandleScope handle_scope; 400e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if (first) { 401e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke first = false; 402e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } else { 403e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke printf(" "); 404e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 405e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::String::Utf8Value str(args[i]); 406e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke const char* cstr = ToCString(str); 407e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke printf("%s", cstr); 408e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 409e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke printf("\n"); 410e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke fflush(stdout); 411e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke return v8::Undefined(); 412e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 413e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 414e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 415e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// The callback that is invoked by v8 whenever the JavaScript 'read_line' 416e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// function is called. Reads a string from standard input and returns. 417e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkev8::Handle<v8::Value> ReadLine(const v8::Arguments& args) { 418e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if (args.Length() > 0) { 419e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke return v8::ThrowException(v8::String::New("Unexpected arguments")); 420e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 421e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke return ReadLine(); 422e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 423e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 424e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkev8::Handle<v8::String> ReadLine() { 425e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke const int kBufferSize = 1024 + 1; 426e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke char buffer[kBufferSize]; 427e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 428e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke char* res; 429e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke { 4306ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#ifdef SUPPORT_DEBUGGING 431e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::Unlocker unlocker; 4326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#endif 433d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke res = fgets(buffer, kBufferSize, stdin); 434e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 435e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if (res == NULL) { 436e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::Handle<v8::Primitive> t = v8::Undefined(); 437e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke return reinterpret_cast<v8::Handle<v8::String>&>(t); 438e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 439e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // remove newline char 440e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke for (char* pos = buffer; *pos != '\0'; pos++) { 441e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if (*pos == '\n') { 442e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke *pos = '\0'; 443e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke break; 444e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 445e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 446e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke return v8::String::New(buffer); 447e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 448