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