13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 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
2969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#ifdef USING_V8_SHARED  // Defined when linking against shared lib on Windows.
3069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#define V8_SHARED
313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif
323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#ifdef COMPRESS_STARTUP_DATA_BZ2
343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#include <bzlib.h>
353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif
363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include <errno.h>
383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#include <stdlib.h>
393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#include <string.h>
4069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#include <sys/stat.h>
41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#ifdef V8_SHARED
433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#include <assert.h>
443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#include "../include/v8-testing.h"
4569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#endif  // V8_SHARED
4644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "d8.h"
483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
4969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#ifndef V8_SHARED
503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#include "api.h"
513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#include "checks.h"
52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "d8-debug.h"
53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "debug.h"
54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "natives.h"
55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "platform.h"
563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#include "v8.h"
5769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#endif  // V8_SHARED
58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#if !defined(_WIN32) && !defined(_WIN64)
603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#include <unistd.h>  // NOLINT
613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif
62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#ifndef ASSERT
643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#define ASSERT(condition) assert(condition)
6569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#endif
66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochnamespace v8 {
68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockLineEditor *LineEditor::first_ = NULL;
70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockLineEditor::LineEditor(Type type, const char* name)
73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    : type_(type),
74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      name_(name),
75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      next_(first_) {
76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  first_ = this;
77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockLineEditor* LineEditor::Get() {
81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  LineEditor* current = first_;
82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  LineEditor* best = current;
83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  while (current != NULL) {
84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (current->type_ > best->type_)
85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      best = current;
86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    current = current->next_;
87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return best;
89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass DumbLineEditor: public LineEditor {
93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DumbLineEditor() : LineEditor(LineEditor::DUMB, "dumb") { }
953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  virtual Handle<String> Prompt(const char* prompt);
96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic DumbLineEditor dumb_line_editor;
100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1023ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<String> DumbLineEditor::Prompt(const char* prompt) {
103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  printf("%s", prompt);
1043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return Shell::ReadFromStdin();
105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#ifndef V8_SHARED
109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockCounterMap* Shell::counter_map_;
110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocki::OS::MemoryMappedFile* Shell::counters_file_ = NULL;
111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockCounterCollection Shell::local_counters_;
112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockCounterCollection* Shell::counters_ = &local_counters_;
1133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochi::Mutex* Shell::context_mutex_(i::OS::CreateMutex());
114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockPersistent<Context> Shell::utility_context_;
11569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#endif  // V8_SHARED
1163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1173ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochLineEditor* Shell::console = NULL;
118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockPersistent<Context> Shell::evaluation_context_;
1193fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochShellOptions Shell::options;
1203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochconst char* Shell::kPrompt = "d8> ";
121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int MB = 1024 * 1024;
1243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
12669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#ifndef V8_SHARED
127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool CounterMap::Match(void* key1, void* key2) {
128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  const char* name1 = reinterpret_cast<const char*>(key1);
129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  const char* name2 = reinterpret_cast<const char*>(key2);
130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return strcmp(name1, name2) == 0;
131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
13269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#endif  // V8_SHARED
133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Converts a V8 value to a C string.
1366ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockconst char* Shell::ToCString(const v8::String::Utf8Value& value) {
137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return *value ? *value : "<string conversion failed>";
138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Executes a string within the current v8 context.
142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool Shell::ExecuteString(Handle<String> source,
143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          Handle<Value> name,
144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          bool print_result,
145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          bool report_exceptions) {
1463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#if !defined(V8_SHARED) && defined(ENABLE_DEBUGGER_SUPPORT)
1473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  bool FLAG_debugger = i::FLAG_debugger;
1483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#else
1493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  bool FLAG_debugger = false;
1503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif  // !V8_SHARED && ENABLE_DEBUGGER_SUPPORT
151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  HandleScope handle_scope;
152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  TryCatch try_catch;
1533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  options.script_executed = true;
1543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  if (FLAG_debugger) {
155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // When debugging make exceptions appear to be uncaught.
156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    try_catch.SetVerbose(true);
157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<Script> script = Script::Compile(source, name);
159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (script.IsEmpty()) {
160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Print errors that happened during compilation.
1613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    if (report_exceptions && !FLAG_debugger)
162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      ReportException(&try_catch);
163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return false;
164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Handle<Value> result = script->Run();
166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (result.IsEmpty()) {
167e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      ASSERT(try_catch.HasCaught());
168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // Print errors that happened during execution.
1693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      if (report_exceptions && !FLAG_debugger)
170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        ReportException(&try_catch);
171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return false;
172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    } else {
173e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      ASSERT(!try_catch.HasCaught());
174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      if (print_result && !result->IsUndefined()) {
175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        // If all went well and the result wasn't undefined then print
176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        // the returned value.
177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        v8::String::Utf8Value str(result);
1783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        size_t count = fwrite(*str, sizeof(**str), str.length(), stdout);
1793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        (void) count;  // Silence GCC-4.5.x "unused result" warning.
180589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        printf("\n");
181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return true;
183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Value> Shell::Print(const Arguments& args) {
189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<Value> val = Write(args);
190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  printf("\n");
1913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  fflush(stdout);
192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return val;
193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Value> Shell::Write(const Arguments& args) {
197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; i < args.Length(); i++) {
198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    HandleScope handle_scope;
199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (i != 0) {
200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      printf(" ");
201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    v8::String::Utf8Value str(args[i]);
20369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    int n = static_cast<int>(fwrite(*str, sizeof(**str), str.length(), stdout));
204d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    if (n != str.length()) {
205d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      printf("Error in fwrite\n");
206589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      Exit(1);
207d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    }
208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return Undefined();
210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
213589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben MurdochHandle<Value> Shell::EnableProfiler(const Arguments& args) {
214589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  V8::ResumeProfiler();
215589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  return Undefined();
216589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch}
217589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
218589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
219589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben MurdochHandle<Value> Shell::DisableProfiler(const Arguments& args) {
220589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  V8::PauseProfiler();
221589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  return Undefined();
222589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch}
223589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
224589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Value> Shell::Read(const Arguments& args) {
226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  String::Utf8Value file(args[0]);
227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (*file == NULL) {
228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return ThrowException(String::New("Error loading file"));
229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<String> source = ReadFile(*file);
231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (source.IsEmpty()) {
232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return ThrowException(String::New("Error loading file"));
233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return source;
235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2383ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<String> Shell::ReadFromStdin() {
2393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  static const int kBufferSize = 256;
2403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  char buffer[kBufferSize];
2413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  Handle<String> accumulator = String::New("");
2423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  int length;
24369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  while (true) {
24469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    // Continue reading if the line ends with an escape '\\' or the line has
24569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    // not been fully read into the buffer yet (does not end with '\n').
24669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    // If fgets gets an error, just give up.
2473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    char* input = NULL;
2483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    {  // Release lock for blocking input.
2493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Unlocker unlock(Isolate::GetCurrent());
2503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      input = fgets(buffer, kBufferSize, stdin);
2513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
2523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (input == NULL) return Handle<String>();
25369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    length = static_cast<int>(strlen(buffer));
25469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    if (length == 0) {
25569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch      return accumulator;
25669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    } else if (buffer[length-1] != '\n') {
25769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch      accumulator = String::Concat(accumulator, String::New(buffer, length));
25869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    } else if (length > 1 && buffer[length-2] == '\\') {
25969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch      buffer[length-2] = '\n';
26069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch      accumulator = String::Concat(accumulator, String::New(buffer, length-1));
26169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    } else {
26269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch      return String::Concat(accumulator, String::New(buffer, length-1));
26369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    }
26469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  }
265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Value> Shell::Load(const Arguments& args) {
269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; i < args.Length(); i++) {
270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    HandleScope handle_scope;
271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    String::Utf8Value file(args[i]);
272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (*file == NULL) {
273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return ThrowException(String::New("Error loading file"));
274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Handle<String> source = ReadFile(*file);
276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (source.IsEmpty()) {
277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return ThrowException(String::New("Error loading file"));
278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
279589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    if (!ExecuteString(source, String::New(*file), false, true)) {
280d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      return ThrowException(String::New("Error executing file"));
281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return Undefined();
284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic size_t convertToUint(Local<Value> value_in, TryCatch* try_catch) {
2873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (value_in->IsUint32()) {
2883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return value_in->Uint32Value();
2893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
2903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Local<Value> number = value_in->ToNumber();
2923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (try_catch->HasCaught()) return 0;
2933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(number->IsNumber());
2953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Local<Int32> int32 = number->ToInt32();
2963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (try_catch->HasCaught() || int32.IsEmpty()) return 0;
2973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int32_t raw_value = int32->Int32Value();
2993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (try_catch->HasCaught()) return 0;
3003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (raw_value < 0) {
3023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    ThrowException(String::New("Array length must not be negative."));
3033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return 0;
3043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
3053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kMaxLength = 0x3fffffff;
3073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#ifndef V8_SHARED
3083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(kMaxLength == i::ExternalArray::kMaxLength);
3093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif  // V8_SHARED
3103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (raw_value > static_cast<int32_t>(kMaxLength)) {
3113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    ThrowException(
3123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        String::New("Array length exceeds maximum length."));
3133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
3143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return static_cast<size_t>(raw_value);
3153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
3163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst char kArrayBufferReferencePropName[] = "_is_array_buffer_";
3193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst char kArrayBufferMarkerPropName[] = "_array_buffer_ref_";
3203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3223fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochHandle<Value> Shell::CreateExternalArray(const Arguments& args,
3233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                         ExternalArrayType type,
3243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                         size_t element_size) {
3253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  TryCatch try_catch;
3263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool is_array_buffer_construct = element_size == 0;
3273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (is_array_buffer_construct) {
3283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    type = v8::kExternalByteArray;
3293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    element_size = 1;
3303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
3313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  ASSERT(element_size == 1 || element_size == 2 || element_size == 4 ||
3323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch         element_size == 8);
3333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (args.Length() == 0) {
334c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch    return ThrowException(
3353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        String::New("Array constructor must have at least one "
3363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                    "parameter."));
337c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  }
3383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool first_arg_is_array_buffer =
3393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      args[0]->IsObject() &&
3403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      args[0]->ToObject()->Get(
3413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          String::New(kArrayBufferMarkerPropName))->IsTrue();
3423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Currently, only the following constructors are supported:
3433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //   TypedArray(unsigned long length)
3443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //   TypedArray(ArrayBuffer buffer,
3453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //              optional unsigned long byteOffset,
3463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //              optional unsigned long length)
3473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (args.Length() > 3) {
3483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return ThrowException(
3493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        String::New("Array constructor from ArrayBuffer must "
3503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                    "have 1-3 parameters."));
3513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
3523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Local<Value> length_value = (args.Length() < 3)
3543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      ? (first_arg_is_array_buffer
3553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch         ? args[0]->ToObject()->Get(String::New("length"))
3563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch         : args[0])
3573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      : args[2];
3583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  size_t length = convertToUint(length_value, &try_catch);
3593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (try_catch.HasCaught()) return try_catch.Exception();
3603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void* data = NULL;
3623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  size_t offset = 0;
3633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Object> array = Object::New();
3653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (first_arg_is_array_buffer) {
3663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Handle<Object> derived_from = args[0]->ToObject();
3673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    data = derived_from->GetIndexedPropertiesExternalArrayData();
3683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    size_t array_buffer_length = convertToUint(
3703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        derived_from->Get(String::New("length")),
3713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        &try_catch);
3723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (try_catch.HasCaught()) return try_catch.Exception();
3733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (data == NULL && array_buffer_length != 0) {
3753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      return ThrowException(
3763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          String::New("ArrayBuffer doesn't have data"));
377589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    }
3783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (args.Length() > 1) {
3803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      offset = convertToUint(args[1], &try_catch);
3813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      if (try_catch.HasCaught()) return try_catch.Exception();
3823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      // The given byteOffset must be a multiple of the element size of the
3843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      // specific type, otherwise an exception is raised.
3853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      if (offset % element_size != 0) {
3863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        return ThrowException(
3873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch            String::New("offset must be multiple of element_size"));
3883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      }
3893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    }
3903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (offset > array_buffer_length) {
3923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      return ThrowException(
3933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          String::New("byteOffset must be less than ArrayBuffer length."));
3943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    }
3953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (args.Length() == 2) {
3973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      // If length is not explicitly specified, the length of the ArrayBuffer
3983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      // minus the byteOffset must be a multiple of the element size of the
3993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      // specific type, or an exception is raised.
4003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      length = array_buffer_length - offset;
4013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
4023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (args.Length() != 3) {
4043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      if (length % element_size != 0) {
4053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        return ThrowException(
4063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch            String::New("ArrayBuffer length minus the byteOffset must be a "
4073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                        "multiple of the element size"));
4083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      }
4093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      length /= element_size;
4103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
4113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // If a given byteOffset and length references an area beyond the end of
4133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // the ArrayBuffer an exception is raised.
4143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (offset + (length * element_size) > array_buffer_length) {
4153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      return ThrowException(
4163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          String::New("length references an area beyond the end of the "
4173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      "ArrayBuffer"));
4183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
4193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // Hold a reference to the ArrayBuffer so its buffer doesn't get collected.
4213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    array->Set(String::New(kArrayBufferReferencePropName), args[0], ReadOnly);
4223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
4233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (is_array_buffer_construct) {
4253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    array->Set(String::New(kArrayBufferMarkerPropName), True(), ReadOnly);
42685b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch  }
4273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  Persistent<Object> persistent_array = Persistent<Object>::New(array);
4293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  persistent_array.MakeWeak(data, ExternalArrayWeakCallback);
4303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  persistent_array.MarkIndependent();
4313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (data == NULL && length != 0) {
4323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    data = calloc(length, element_size);
4333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (data == NULL) {
4343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      return ThrowException(String::New("Memory allocation failed."));
4353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
4363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
4373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  array->SetIndexedPropertiesToExternalArrayData(
4393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      reinterpret_cast<uint8_t*>(data) + offset, type,
4403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      static_cast<int>(length));
44169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  array->Set(String::New("length"),
44269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch             Int32::New(static_cast<int32_t>(length)), ReadOnly);
44369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  array->Set(String::New("BYTES_PER_ELEMENT"),
44469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch             Int32::New(static_cast<int32_t>(element_size)));
4453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  return array;
4463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
4473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
4483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
4493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid Shell::ExternalArrayWeakCallback(Persistent<Value> object, void* data) {
4503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  HandleScope scope;
4513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<String> prop_name = String::New(kArrayBufferReferencePropName);
4523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Object> converted_object = object->ToObject();
4533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Local<Value> prop_value = converted_object->Get(prop_name);
4543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (data != NULL && !prop_value->IsObject()) {
4553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    free(data);
4563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
4573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  object.Dispose();
4583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
4593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
4603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
4613ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Value> Shell::ArrayBuffer(const Arguments& args) {
4623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return CreateExternalArray(args, v8::kExternalByteArray, 0);
4633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
4643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4663fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochHandle<Value> Shell::Int8Array(const Arguments& args) {
4673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  return CreateExternalArray(args, v8::kExternalByteArray, sizeof(int8_t));
4683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
4693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
4703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
4713fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochHandle<Value> Shell::Uint8Array(const Arguments& args) {
4723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  return CreateExternalArray(args, kExternalUnsignedByteArray, sizeof(uint8_t));
4733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
4743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
4753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
4763fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochHandle<Value> Shell::Int16Array(const Arguments& args) {
4773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  return CreateExternalArray(args, kExternalShortArray, sizeof(int16_t));
4783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
4793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
4803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
4813fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochHandle<Value> Shell::Uint16Array(const Arguments& args) {
4823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  return CreateExternalArray(args, kExternalUnsignedShortArray,
4833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                             sizeof(uint16_t));
4843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
4853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
4863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
4873fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochHandle<Value> Shell::Int32Array(const Arguments& args) {
4883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  return CreateExternalArray(args, kExternalIntArray, sizeof(int32_t));
4893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
4903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
4913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
4923fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochHandle<Value> Shell::Uint32Array(const Arguments& args) {
4933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  return CreateExternalArray(args, kExternalUnsignedIntArray, sizeof(uint32_t));
4943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
4953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
4963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
4973fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochHandle<Value> Shell::Float32Array(const Arguments& args) {
4983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  return CreateExternalArray(args, kExternalFloatArray,
4993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                             sizeof(float));  // NOLINT
5003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
5013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
5023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
5033fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochHandle<Value> Shell::Float64Array(const Arguments& args) {
5043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  return CreateExternalArray(args, kExternalDoubleArray,
5053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                             sizeof(double));  // NOLINT
5063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
5073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
5083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
5093fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochHandle<Value> Shell::PixelArray(const Arguments& args) {
5103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  return CreateExternalArray(args, kExternalPixelArray, sizeof(uint8_t));
5113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
5123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
5133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Value> Shell::Yield(const Arguments& args) {
515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  v8::Unlocker unlocker;
516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return Undefined();
517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Value> Shell::Quit(const Arguments& args) {
521a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int exit_code = args[0]->Int32Value();
52269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#ifndef V8_SHARED
523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  OnExit();
52469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#endif  // V8_SHARED
525a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  exit(exit_code);
526a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return Undefined();
527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
528a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
530a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Value> Shell::Version(const Arguments& args) {
531a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return String::New(V8::GetVersion());
532a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
534a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
535a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Shell::ReportException(v8::TryCatch* try_catch) {
536a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  HandleScope handle_scope;
5373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#if !defined(V8_SHARED) && defined(ENABLE_DEBUGGER_SUPPORT)
5383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool enter_context = !Context::InContext();
5393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (enter_context) utility_context_->Enter();
5403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif  // !V8_SHARED && ENABLE_DEBUGGER_SUPPORT
541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  v8::String::Utf8Value exception(try_catch->Exception());
542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  const char* exception_string = ToCString(exception);
543a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<Message> message = try_catch->Message();
544a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (message.IsEmpty()) {
545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // V8 didn't provide any extra information about this error; just
546a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // print the exception.
547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    printf("%s\n", exception_string);
548a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Print (filename):(line number): (message).
550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    v8::String::Utf8Value filename(message->GetScriptResourceName());
551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    const char* filename_string = ToCString(filename);
552a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    int linenum = message->GetLineNumber();
553a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    printf("%s:%i: %s\n", filename_string, linenum, exception_string);
554a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Print line of source code.
555a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    v8::String::Utf8Value sourceline(message->GetSourceLine());
556a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    const char* sourceline_string = ToCString(sourceline);
557a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    printf("%s\n", sourceline_string);
558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Print wavy underline (GetUnderline is deprecated).
559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    int start = message->GetStartColumn();
560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    for (int i = 0; i < start; i++) {
561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      printf(" ");
562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    int end = message->GetEndColumn();
564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    for (int i = start; i < end; i++) {
565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      printf("^");
566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    printf("\n");
568257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    v8::String::Utf8Value stack_trace(try_catch->StackTrace());
569257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    if (stack_trace.length() > 0) {
570257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      const char* stack_trace_string = ToCString(stack_trace);
571257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      printf("%s\n", stack_trace_string);
572257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    }
573a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
574589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  printf("\n");
5753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#if !defined(V8_SHARED) && defined(ENABLE_DEBUGGER_SUPPORT)
5763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (enter_context) utility_context_->Exit();
5773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif  // !V8_SHARED && ENABLE_DEBUGGER_SUPPORT
578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
58169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#ifndef V8_SHARED
582a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Array> Shell::GetCompletions(Handle<String> text, Handle<String> full) {
583a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  HandleScope handle_scope;
584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Context::Scope context_scope(utility_context_);
585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<Object> global = utility_context_->Global();
586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<Value> fun = global->Get(String::New("GetCompletions"));
587a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kArgc = 3;
588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<Value> argv[kArgc] = { evaluation_context_->Global(), text, full };
589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<Value> val = Handle<Function>::Cast(fun)->Call(global, kArgc, argv);
590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return handle_scope.Close(Handle<Array>::Cast(val));
591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT
595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> Shell::DebugMessageDetails(Handle<String> message) {
596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Context::Scope context_scope(utility_context_);
597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<Object> global = utility_context_->Global();
598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<Value> fun = global->Get(String::New("DebugMessageDetails"));
599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kArgc = 1;
600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<Value> argv[kArgc] = { message };
601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<Value> val = Handle<Function>::Cast(fun)->Call(global, kArgc, argv);
602a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return Handle<Object>::Cast(val);
603a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
604a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
605a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
606a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Value> Shell::DebugCommandToJSONRequest(Handle<String> command) {
607a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Context::Scope context_scope(utility_context_);
608a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<Object> global = utility_context_->Global();
609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<Value> fun = global->Get(String::New("DebugCommandToJSONRequest"));
610a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kArgc = 1;
611a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<Value> argv[kArgc] = { command };
612a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<Value> val = Handle<Function>::Cast(fun)->Call(global, kArgc, argv);
613a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return val;
614a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
6153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid Shell::DispatchDebugMessages() {
6183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  v8::Context::Scope scope(Shell::evaluation_context_);
6193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  v8::Debug::ProcessDebugMessages();
6203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
6213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif  // ENABLE_DEBUGGER_SUPPORT
62269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#endif  // V8_SHARED
623a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
624a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
62569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#ifndef V8_SHARED
626a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint32_t* Counter::Bind(const char* name, bool is_histogram) {
627a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int i;
628a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (i = 0; i < kMaxNameSize - 1 && name[i]; i++)
629a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    name_[i] = static_cast<char>(name[i]);
630a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  name_[i] = '\0';
631a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  is_histogram_ = is_histogram;
632a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return ptr();
633a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
634a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
635a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
636a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Counter::AddSample(int32_t sample) {
637a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  count_++;
638a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  sample_total_ += sample;
639a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
640a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
641a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
642a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockCounterCollection::CounterCollection() {
643a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  magic_number_ = 0xDEADFACE;
644a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  max_counters_ = kMaxCounters;
645a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  max_name_size_ = Counter::kMaxNameSize;
646a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  counters_in_use_ = 0;
647a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
648a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
649a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
650a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockCounter* CounterCollection::GetNextCounter() {
651a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (counters_in_use_ == kMaxCounters) return NULL;
652a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return &counters_[counters_in_use_++];
653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
654a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
655a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
656a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Shell::MapCounters(const char* name) {
6573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  counters_file_ = i::OS::MemoryMappedFile::create(
6583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      name, sizeof(CounterCollection), &local_counters_);
659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void* memory = (counters_file_ == NULL) ?
660a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      NULL : counters_file_->memory();
661a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (memory == NULL) {
662a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    printf("Could not map counters file %s\n", name);
663589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    Exit(1);
664a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
665a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  counters_ = static_cast<CounterCollection*>(memory);
666a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  V8::SetCounterFunction(LookupCounter);
667a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  V8::SetCreateHistogramFunction(CreateHistogram);
668a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  V8::SetAddHistogramSampleFunction(AddHistogramSample);
669a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
670a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
671a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
672a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint CounterMap::Hash(const char* name) {
673a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int h = 0;
674a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int c;
675a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  while ((c = *name++) != 0) {
676a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    h += h << 5;
677a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    h += c;
678a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
679a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return h;
680a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
681a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
682a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
683a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockCounter* Shell::GetCounter(const char* name, bool is_histogram) {
684a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Counter* counter = counter_map_->Lookup(name);
685a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
686a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (counter == NULL) {
687a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    counter = counters_->GetNextCounter();
688a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (counter != NULL) {
689a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      counter_map_->Set(name, counter);
690a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      counter->Bind(name, is_histogram);
691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
692a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ASSERT(counter->is_histogram() == is_histogram);
694a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
695a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return counter;
696a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
697a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
698a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
699a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint* Shell::LookupCounter(const char* name) {
700a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Counter* counter = GetCounter(name, false);
701a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
702a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (counter != NULL) {
703a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return counter->ptr();
704a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
705a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return NULL;
706a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
707a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
708a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
709a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
710a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid* Shell::CreateHistogram(const char* name,
711a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                             int min,
712a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                             int max,
713a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                             size_t buckets) {
714a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return GetCounter(name, true);
715a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
716a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
717a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
718a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Shell::AddHistogramSample(void* histogram, int sample) {
719a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Counter* counter = reinterpret_cast<Counter*>(histogram);
720a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  counter->AddSample(sample);
721a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
722a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
723a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid Shell::InstallUtilityScript() {
7253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  Locker lock;
726a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  HandleScope scope;
7273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // If we use the utility context, we have to set the security tokens so that
7283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // utility, evaluation and debug context can all access each other.
729a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  utility_context_->SetSecurityToken(Undefined());
7303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  evaluation_context_->SetSecurityToken(Undefined());
731a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Context::Scope utility_scope(utility_context_);
732a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
733a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT
7343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (i::FLAG_debugger) printf("JavaScript debugger enabled\n");
735a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Install the debugger object in the utility scope
73644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Debug* debug = i::Isolate::Current()->debug();
73744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  debug->Load();
73844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Handle<i::JSObject> js_debug
73944f0eee88ff00398ff7f715fab053374d808c90dSteve Block      = i::Handle<i::JSObject>(debug->debug_context()->global());
740a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  utility_context_->Global()->Set(String::New("$debug"),
74144f0eee88ff00398ff7f715fab053374d808c90dSteve Block                                  Utils::ToLocal(js_debug));
7423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  debug->debug_context()->set_security_token(HEAP->undefined_value());
7433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif  // ENABLE_DEBUGGER_SUPPORT
744a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
745a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Run the d8 shell utility script in the utility context
746a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int source_index = i::NativesCollection<i::D8>::GetIndex("d8");
7473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  i::Vector<const char> shell_source =
7483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      i::NativesCollection<i::D8>::GetRawScriptSource(source_index);
7493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  i::Vector<const char> shell_source_name =
7503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      i::NativesCollection<i::D8>::GetScriptName(source_index);
751a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<String> source = String::New(shell_source.start(),
7523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      shell_source.length());
753a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<String> name = String::New(shell_source_name.start(),
7543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      shell_source_name.length());
755a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<Script> script = Script::Compile(source, name);
756a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  script->Run();
757a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Mark the d8 shell script as native to avoid it showing up as normal source
758a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // in the debugger.
7596ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  i::Handle<i::Object> compiled_script = Utils::OpenHandle(*script);
7606ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  i::Handle<i::Script> script_object = compiled_script->IsJSFunction()
7616ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      ? i::Handle<i::Script>(i::Script::cast(
7626ded16be15dd865a9b21ea304d5273c8be299c87Steve Block          i::JSFunction::cast(*compiled_script)->shared()->script()))
7636ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      : i::Handle<i::Script>(i::Script::cast(
7646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block          i::SharedFunctionInfo::cast(*compiled_script)->script()));
765a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  script_object->set_type(i::Smi::FromInt(i::Script::TYPE_NATIVE));
766a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
767a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT
7683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Start the in-process debugger if requested.
7693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  if (i::FLAG_debugger && !i::FLAG_debugger_agent) {
7703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    v8::Debug::SetDebugEventListener(HandleDebugEvent);
7713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
7723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif  // ENABLE_DEBUGGER_SUPPORT
7733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
77469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#endif  // V8_SHARED
7753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
7763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
7773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#ifdef COMPRESS_STARTUP_DATA_BZ2
7783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochclass BZip2Decompressor : public v8::StartupDataDecompressor {
7793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch public:
7803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  virtual ~BZip2Decompressor() { }
7813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
7823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch protected:
7833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  virtual int DecompressData(char* raw_data,
7843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                             int* raw_data_size,
7853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                             const char* compressed_data,
7863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                             int compressed_data_size) {
7873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    ASSERT_EQ(v8::StartupData::kBZip2,
7883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch              v8::V8::GetCompressedStartupDataAlgorithm());
7893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    unsigned int decompressed_size = *raw_data_size;
7903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    int result =
7913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch        BZ2_bzBuffToBuffDecompress(raw_data,
7923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                   &decompressed_size,
7933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                   const_cast<char*>(compressed_data),
7943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                   compressed_data_size,
7953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                   0, 1);
7963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    if (result == BZ_OK) {
7973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      *raw_data_size = decompressed_size;
7983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    }
7993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    return result;
8003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
8013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch};
8023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif
803a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8043fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochHandle<ObjectTemplate> Shell::CreateGlobalTemplate() {
8053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  Handle<ObjectTemplate> global_template = ObjectTemplate::New();
8063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  global_template->Set(String::New("print"), FunctionTemplate::New(Print));
8073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  global_template->Set(String::New("write"), FunctionTemplate::New(Write));
8083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  global_template->Set(String::New("read"), FunctionTemplate::New(Read));
8093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  global_template->Set(String::New("readbinary"),
8103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                       FunctionTemplate::New(ReadBinary));
8113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  global_template->Set(String::New("readline"),
8123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                       FunctionTemplate::New(ReadLine));
8133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  global_template->Set(String::New("load"), FunctionTemplate::New(Load));
8143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  global_template->Set(String::New("quit"), FunctionTemplate::New(Quit));
8153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  global_template->Set(String::New("version"), FunctionTemplate::New(Version));
816589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  global_template->Set(String::New("enableProfiler"),
817589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch                       FunctionTemplate::New(EnableProfiler));
818589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  global_template->Set(String::New("disableProfiler"),
819589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch                       FunctionTemplate::New(DisableProfiler));
8203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
8213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Bind the handlers for external arrays.
8223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  global_template->Set(String::New("ArrayBuffer"),
8233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                       FunctionTemplate::New(ArrayBuffer));
8243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  global_template->Set(String::New("Int8Array"),
8253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                       FunctionTemplate::New(Int8Array));
8263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  global_template->Set(String::New("Uint8Array"),
8273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                       FunctionTemplate::New(Uint8Array));
8283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  global_template->Set(String::New("Int16Array"),
8293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                       FunctionTemplate::New(Int16Array));
8303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  global_template->Set(String::New("Uint16Array"),
8313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                       FunctionTemplate::New(Uint16Array));
8323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  global_template->Set(String::New("Int32Array"),
8333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                       FunctionTemplate::New(Int32Array));
8343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  global_template->Set(String::New("Uint32Array"),
8353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                       FunctionTemplate::New(Uint32Array));
8363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  global_template->Set(String::New("Float32Array"),
8373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                       FunctionTemplate::New(Float32Array));
8383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  global_template->Set(String::New("Float64Array"),
8393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                       FunctionTemplate::New(Float64Array));
8403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  global_template->Set(String::New("PixelArray"),
8413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                       FunctionTemplate::New(PixelArray));
8423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
8433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#ifdef LIVE_OBJECT_LIST
84469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  global_template->Set(String::New("lol_is_enabled"), True());
8453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#else
84669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  global_template->Set(String::New("lol_is_enabled"), False());
8473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif
8483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
849589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch#if !defined(V8_SHARED) && !defined(_WIN32) && !defined(_WIN64)
8503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  Handle<ObjectTemplate> os_templ = ObjectTemplate::New();
8513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  AddOSMethods(os_templ);
8523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  global_template->Set(String::New("os"), os_templ);
85369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#endif  // V8_SHARED
8543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
8553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  return global_template;
8563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
8573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
8583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
8593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid Shell::Initialize() {
8603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#ifdef COMPRESS_STARTUP_DATA_BZ2
8613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  BZip2Decompressor startup_data_decompressor;
8623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  int bz2_result = startup_data_decompressor.Decompress();
8633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  if (bz2_result != BZ_OK) {
8643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    fprintf(stderr, "bzip error code: %d\n", bz2_result);
865589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    Exit(1);
8663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
8673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif
8683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
86969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#ifndef V8_SHARED
8703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  Shell::counter_map_ = new CounterMap();
8713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Set up counters
8723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  if (i::StrLength(i::FLAG_map_counters) != 0)
8733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    MapCounters(i::FLAG_map_counters);
8743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  if (i::FLAG_dump_counters) {
8753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    V8::SetCounterFunction(LookupCounter);
8763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    V8::SetCreateHistogramFunction(CreateHistogram);
8773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    V8::SetAddHistogramSampleFunction(AddHistogramSample);
8783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
87969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#endif  // V8_SHARED
8803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  if (options.test_shell) return;
8813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
88269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#ifndef V8_SHARED
8833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  Locker lock;
8843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  HandleScope scope;
8853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  Handle<ObjectTemplate> global_template = CreateGlobalTemplate();
8863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  utility_context_ = Context::New(NULL, global_template);
8873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
8883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#ifdef ENABLE_DEBUGGER_SUPPORT
889a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Start the debugger agent if requested.
890a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (i::FLAG_debugger_agent) {
8919ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick    v8::Debug::EnableAgent("d8 shell", i::FLAG_debugger_port, true);
8923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    v8::Debug::SetDebugMessageDispatchHandler(DispatchDebugMessages, true);
893a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
8943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif  // ENABLE_DEBUGGER_SUPPORT
89569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#endif  // V8_SHARED
8963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
897a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
8993fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochPersistent<Context> Shell::CreateEvaluationContext() {
90069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#ifndef V8_SHARED
9013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // This needs to be a critical section since this is not thread-safe
9023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  i::ScopedLock lock(context_mutex_);
90369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#endif  // V8_SHARED
9043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Initialize the global objects
9053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  Handle<ObjectTemplate> global_template = CreateGlobalTemplate();
9063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  Persistent<Context> context = Context::New(NULL, global_template);
9073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(!context.IsEmpty());
9083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  Context::Scope scope(context);
9093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
91069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#ifndef V8_SHARED
9113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  i::JSArguments js_args = i::FLAG_js_arguments;
9123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  i::Handle<i::FixedArray> arguments_array =
9133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      FACTORY->NewFixedArray(js_args.argc());
9143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  for (int j = 0; j < js_args.argc(); j++) {
9153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    i::Handle<i::String> arg =
9163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch        FACTORY->NewStringFromUtf8(i::CStrVector(js_args[j]));
9173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    arguments_array->set(j, *arg);
918a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
9193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  i::Handle<i::JSArray> arguments_jsarray =
9203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      FACTORY->NewJSArrayWithElements(arguments_array);
9213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  context->Global()->Set(String::New("arguments"),
9223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                         Utils::ToLocal(arguments_jsarray));
92369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#endif  // V8_SHARED
9243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  return context;
925a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
926a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
927a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
928589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochvoid Shell::Exit(int exit_code) {
929589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // Use _exit instead of exit to avoid races between isolate
930589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // threads and static destructors.
931589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  fflush(stdout);
932589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  fflush(stderr);
933589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  _exit(exit_code);
934589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch}
935589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
936589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
93769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#ifndef V8_SHARED
9383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstruct CounterAndKey {
9393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Counter* counter;
9403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  const char* key;
9413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch};
9423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
9433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
9443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochint CompareKeys(const void* a, const void* b) {
9453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return strcmp(static_cast<const CounterAndKey*>(a)->key,
9463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                static_cast<const CounterAndKey*>(b)->key);
9473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
9483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
9493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
950a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Shell::OnExit() {
951589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  if (console != NULL) console->Close();
952a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (i::FLAG_dump_counters) {
9533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    int number_of_counters = 0;
954a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    for (CounterMap::Iterator i(counter_map_); i.More(); i.Next()) {
9553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      number_of_counters++;
9563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
9573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    CounterAndKey* counters = new CounterAndKey[number_of_counters];
9583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    int j = 0;
9593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    for (CounterMap::Iterator i(counter_map_); i.More(); i.Next(), j++) {
9603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      counters[j].counter = i.CurrentValue();
9613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      counters[j].key = i.CurrentKey();
9623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
9633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    qsort(counters, number_of_counters, sizeof(counters[0]), CompareKeys);
9643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    printf("+--------------------------------------------+-------------+\n");
9653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    printf("| Name                                       | Value       |\n");
9663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    printf("+--------------------------------------------+-------------+\n");
9673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    for (j = 0; j < number_of_counters; j++) {
9683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Counter* counter = counters[j].counter;
9693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      const char* key = counters[j].key;
970a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      if (counter->is_histogram()) {
9713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        printf("| c:%-40s | %11i |\n", key, counter->count());
9723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        printf("| t:%-40s | %11i |\n", key, counter->sample_total());
973a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      } else {
9743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        printf("| %-42s | %11i |\n", key, counter->count());
975a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
976a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
9773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    printf("+--------------------------------------------+-------------+\n");
9783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    delete [] counters;
979a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
980a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (counters_file_ != NULL)
981a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    delete counters_file_;
982a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
98369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#endif  // V8_SHARED
98469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
98569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
98669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochstatic FILE* FOpen(const char* path, const char* mode) {
9873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#if defined(_MSC_VER) && (defined(_WIN32) || defined(_WIN64))
98869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  FILE* result;
98969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  if (fopen_s(&result, path, mode) == 0) {
99069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    return result;
99169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  } else {
99269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    return NULL;
99369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  }
99469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#else
99569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  FILE* file = fopen(path, mode);
99669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  if (file == NULL) return NULL;
99769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  struct stat file_stat;
99869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  if (fstat(fileno(file), &file_stat) != 0) return NULL;
99969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  bool is_regular_file = ((file_stat.st_mode & S_IFREG) != 0);
100069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  if (is_regular_file) return file;
100169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  fclose(file);
100269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  return NULL;
100369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#endif
100469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch}
1005a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1006a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1007a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic char* ReadChars(const char* name, int* size_out) {
10083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Release the V8 lock while reading files.
10093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  v8::Unlocker unlocker(Isolate::GetCurrent());
101069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  FILE* file = FOpen(name, "rb");
1011a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (file == NULL) return NULL;
1012a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1013a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  fseek(file, 0, SEEK_END);
1014a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int size = ftell(file);
1015a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  rewind(file);
1016a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1017a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  char* chars = new char[size + 1];
1018a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  chars[size] = '\0';
1019a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; i < size;) {
102069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    int read = static_cast<int>(fread(&chars[i], 1, size - i, file));
1021a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    i += read;
1022a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1023a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  fclose(file);
1024a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  *size_out = size;
1025a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return chars;
1026a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1027a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1028a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
10293ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Value> Shell::ReadBinary(const Arguments& args) {
10303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  String::Utf8Value filename(args[0]);
10313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int size;
10323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (*filename == NULL) {
10333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return ThrowException(String::New("Error loading file"));
10343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
10353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  char* chars = ReadChars(*filename, &size);
10363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (chars == NULL) {
10373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return ThrowException(String::New("Error reading file"));
10383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
10393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // We skip checking the string for UTF8 characters and use it raw as
10403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // backing store for the external string with 8-bit characters.
10413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  BinaryResource* resource = new BinaryResource(chars, size);
10423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return String::NewExternal(resource);
10433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
10443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
10453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
104669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#ifndef V8_SHARED
1047a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic char* ReadToken(char* data, char token) {
1048a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  char* next = i::OS::StrChr(data, token);
1049a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (next != NULL) {
1050a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    *next = '\0';
1051a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return (next + 1);
1052a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1053a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1054a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return NULL;
1055a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1056a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1057a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1058a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic char* ReadLine(char* data) {
1059a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return ReadToken(data, '\n');
1060a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1061a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1062a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1063a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic char* ReadWord(char* data) {
1064a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return ReadToken(data, ' ');
1065a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
106669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#endif  // V8_SHARED
1067a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1068a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1069a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Reads a file into a v8 string.
1070a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<String> Shell::ReadFile(const char* name) {
1071a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int size = 0;
1072a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  char* chars = ReadChars(name, &size);
1073a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (chars == NULL) return Handle<String>();
1074a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<String> result = String::New(chars);
1075a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  delete[] chars;
1076a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return result;
1077a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1078a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1079a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1080a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Shell::RunShell() {
10813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  Locker locker;
10823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  Context::Scope context_scope(evaluation_context_);
1083589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  HandleScope outer_scope;
10843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  Handle<String> name = String::New("(d8)");
1085589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  console = LineEditor::Get();
1086589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  printf("V8 version %s [console: %s]\n", V8::GetVersion(), console->name());
1087589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  console->Open();
1088a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  while (true) {
1089589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    HandleScope inner_scope;
10903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Handle<String> input = console->Prompt(Shell::kPrompt);
10913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (input.IsEmpty()) break;
10923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    ExecuteString(input, name, true, true);
1093a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1094a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  printf("\n");
1095a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1096a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1097a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
109869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#ifndef V8_SHARED
1099a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass ShellThread : public i::Thread {
1100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
1101589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // Takes ownership of the underlying char array of |files|.
1102589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  ShellThread(int no, char* files)
11033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      : Thread("d8:ShellThread"),
11043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch        no_(no), files_(files) { }
1105589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
1106589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  ~ShellThread() {
1107589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    delete[] files_;
1108589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  }
1109589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
1110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  virtual void Run();
1111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
1112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int no_;
1113589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  char* files_;
1114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
1115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid ShellThread::Run() {
1118589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  char* ptr = files_;
1119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  while ((ptr != NULL) && (*ptr != '\0')) {
1120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // For each newline-separated line.
1121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    char* next_line = ReadLine(ptr);
1122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (*ptr == '#') {
1124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // Skip comment lines.
1125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      ptr = next_line;
1126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      continue;
1127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
1128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
11293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    // Prepare the context for this thread.
11303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    Locker locker;
1131589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    HandleScope outer_scope;
11323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    Persistent<Context> thread_context = Shell::CreateEvaluationContext();
1133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Context::Scope context_scope(thread_context);
1134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    while ((ptr != NULL) && (*ptr != '\0')) {
1136589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      HandleScope inner_scope;
1137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      char* filename = ptr;
1138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      ptr = ReadWord(ptr);
1139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // Skip empty strings.
1141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      if (strlen(filename) == 0) {
1142589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        continue;
1143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
1144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Handle<String> str = Shell::ReadFile(filename);
1146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      if (str.IsEmpty()) {
1147589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        printf("File '%s' not found\n", filename);
1148589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        Shell::Exit(1);
1149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
1150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Shell::ExecuteString(str, String::New(filename), false, false);
1152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
1153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    thread_context.Dispose();
1155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ptr = next_line;
1156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
115869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#endif  // V8_SHARED
1159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1161589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben MurdochSourceGroup::~SourceGroup() {
1162589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch#ifndef V8_SHARED
1163589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  delete next_semaphore_;
1164589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  next_semaphore_ = NULL;
1165589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  delete done_semaphore_;
1166589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  done_semaphore_ = NULL;
1167589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  delete thread_;
1168589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  thread_ = NULL;
1169589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch#endif  // V8_SHARED
11703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
11713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
11723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
11733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid SourceGroup::Execute() {
11743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  for (int i = begin_offset_; i < end_offset_; ++i) {
11753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    const char* arg = argv_[i];
11763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    if (strcmp(arg, "-e") == 0 && i + 1 < end_offset_) {
11773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      // Execute argument given to -e option directly.
11783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      HandleScope handle_scope;
11793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      Handle<String> file_name = String::New("unnamed");
11803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      Handle<String> source = String::New(argv_[i + 1]);
11813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      if (!Shell::ExecuteString(source, file_name, false, true)) {
1182589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        Shell::Exit(1);
11833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      }
11843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      ++i;
11853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    } else if (arg[0] == '-') {
11863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      // Ignore other options. They have been parsed already.
11873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    } else {
11883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      // Use all other arguments as names of files to load and run.
11893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      HandleScope handle_scope;
11903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      Handle<String> file_name = String::New(arg);
11913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      Handle<String> source = ReadFile(arg);
11923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      if (source.IsEmpty()) {
11933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch        printf("Error reading '%s'\n", arg);
1194589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        Shell::Exit(1);
11953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      }
11963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      if (!Shell::ExecuteString(source, file_name, false, true)) {
1197589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        Shell::Exit(1);
11983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      }
11993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    }
1200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
12013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
1202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
12043fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochHandle<String> SourceGroup::ReadFile(const char* name) {
120569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  int size;
120669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  const char* chars = ReadChars(name, &size);
120769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  if (chars == NULL) return Handle<String>();
12083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  Handle<String> result = String::New(chars, size);
12093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  delete[] chars;
12103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  return result;
12113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
12123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
12133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
121469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#ifndef V8_SHARED
12153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochi::Thread::Options SourceGroup::GetThreadOptions() {
12163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // On some systems (OSX 10.6) the stack size default is 0.5Mb or less
12173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // which is not enough to parse the big literal expressions used in tests.
12183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // The stack size should be at least StackGuard::kLimitSize + some
12193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // OS-specific padding for thread startup code.  2Mbytes seems to be enough.
12203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return i::Thread::Options("IsolateThread", 2 * MB);
12213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
12223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
12233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
12243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid SourceGroup::ExecuteInThread() {
12253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  Isolate* isolate = Isolate::New();
12263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  do {
12273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    if (next_semaphore_ != NULL) next_semaphore_->Wait();
12283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    {
12293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      Isolate::Scope iscope(isolate);
12303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      Locker lock(isolate);
12313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      HandleScope scope;
12323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      Persistent<Context> context = Shell::CreateEvaluationContext();
12333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      {
12343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch        Context::Scope cscope(context);
12353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch        Execute();
12363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      }
12373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      context.Dispose();
12383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    }
12393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    if (done_semaphore_ != NULL) done_semaphore_->Signal();
12403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  } while (!Shell::options.last_run);
12413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  isolate->Dispose();
12423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
12433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
12443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
12453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid SourceGroup::StartExecuteInThread() {
12463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  if (thread_ == NULL) {
12473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    thread_ = new IsolateThread(this);
12483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    thread_->Start();
12493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
12503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  next_semaphore_->Signal();
12513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
12523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
12533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
12543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid SourceGroup::WaitForThread() {
12553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  if (thread_ == NULL) return;
12563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  if (Shell::options.last_run) {
12573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    thread_->Join();
12583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  } else {
12593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    done_semaphore_->Wait();
12603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
12613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
126269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#endif  // V8_SHARED
12633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
12643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
12653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochbool Shell::SetOptions(int argc, char* argv[]) {
12663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  for (int i = 0; i < argc; i++) {
12673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    if (strcmp(argv[i], "--stress-opt") == 0) {
12683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      options.stress_opt = true;
12693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      argv[i] = NULL;
12703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    } else if (strcmp(argv[i], "--stress-deopt") == 0) {
12713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      options.stress_deopt = true;
12723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      argv[i] = NULL;
12733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    } else if (strcmp(argv[i], "--noalways-opt") == 0) {
12743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      // No support for stressing if we can't use --always-opt.
12753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      options.stress_opt = false;
12763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      options.stress_deopt = false;
12773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    } else if (strcmp(argv[i], "--shell") == 0) {
12783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      options.interactive_shell = true;
12793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      argv[i] = NULL;
12803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    } else if (strcmp(argv[i], "--test") == 0) {
12813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      options.test_shell = true;
12823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      argv[i] = NULL;
12833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    } else if (strcmp(argv[i], "--preemption") == 0) {
128469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#ifdef V8_SHARED
12853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      printf("D8 with shared library does not support multi-threading\n");
12863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      return false;
12873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#else
12883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      options.use_preemption = true;
12893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      argv[i] = NULL;
129069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#endif  // V8_SHARED
12913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    } else if (strcmp(argv[i], "--nopreemption") == 0) {
129269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#ifdef V8_SHARED
12933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      printf("D8 with shared library does not support multi-threading\n");
12943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      return false;
12953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#else
12963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      options.use_preemption = false;
12973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      argv[i] = NULL;
129869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#endif  // V8_SHARED
12993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    } else if (strcmp(argv[i], "--preemption-interval") == 0) {
130069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#ifdef V8_SHARED
13013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      printf("D8 with shared library does not support multi-threading\n");
13023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      return false;
13033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#else
13043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      if (++i < argc) {
13053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch        argv[i-1] = NULL;
13063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch        char* end = NULL;
13073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch        options.preemption_interval = strtol(argv[i], &end, 10);  // NOLINT
13083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch        if (options.preemption_interval <= 0
13093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch            || *end != '\0'
13103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch            || errno == ERANGE) {
13113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch          printf("Invalid value for --preemption-interval '%s'\n", argv[i]);
13123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch          return false;
1313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        }
13143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch        argv[i] = NULL;
1315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      } else {
13163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch        printf("Missing value for --preemption-interval\n");
13173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch        return false;
1318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
131969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#endif  // V8_SHARED
13203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    } else if (strcmp(argv[i], "-f") == 0) {
13213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      // Ignore any -f flags for compatibility with other stand-alone
13223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      // JavaScript engines.
13233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      continue;
13243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    } else if (strcmp(argv[i], "--isolate") == 0) {
132569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#ifdef V8_SHARED
13263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      printf("D8 with shared library does not support multi-threading\n");
13273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      return false;
132869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#endif  // V8_SHARED
13293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      options.num_isolates++;
1330589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    } else if (strcmp(argv[i], "-p") == 0) {
1331589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch#ifdef V8_SHARED
1332589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      printf("D8 with shared library does not support multi-threading\n");
1333589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      return false;
1334589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch#else
1335589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      options.num_parallel_files++;
1336589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch#endif  // V8_SHARED
13373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    }
133869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#ifdef V8_SHARED
13393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    else if (strcmp(argv[i], "--dump-counters") == 0) {
13403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      printf("D8 with shared library does not include counters\n");
13413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      return false;
13423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    } else if (strcmp(argv[i], "--debugger") == 0) {
13433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      printf("Javascript debugger not included\n");
13443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      return false;
1345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
134669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#endif  // V8_SHARED
13473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
1348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
134969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#ifndef V8_SHARED
13503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Run parallel threads if we are not using --isolate
1351589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  options.parallel_files = new char*[options.num_parallel_files];
1352589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  int parallel_files_set = 0;
13533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  for (int i = 1; i < argc; i++) {
13543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    if (argv[i] == NULL) continue;
13553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    if (strcmp(argv[i], "-p") == 0 && i + 1 < argc) {
13563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      if (options.num_isolates > 1) {
13573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch        printf("-p is not compatible with --isolate\n");
13583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch        return false;
13593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      }
13603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      argv[i] = NULL;
1361589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      i++;
1362589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      options.parallel_files[parallel_files_set] = argv[i];
1363589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      parallel_files_set++;
13643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      argv[i] = NULL;
1365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
13663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
1367589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  if (parallel_files_set != options.num_parallel_files) {
1368589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    printf("-p requires a file containing a list of files as parameter\n");
1369589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    return false;
1370589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  }
137169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#endif  // V8_SHARED
13723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
13733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  v8::V8::SetFlagsFromCommandLine(&argc, argv, true);
13743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1375589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // Set up isolated source groups.
13763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  options.isolate_sources = new SourceGroup[options.num_isolates];
13773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  SourceGroup* current = options.isolate_sources;
13783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  current->Begin(argv, 1);
13793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  for (int i = 1; i < argc; i++) {
13803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    const char* str = argv[i];
13813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    if (strcmp(str, "--isolate") == 0) {
13823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      current->End(i);
13833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      current++;
13843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      current->Begin(argv, i + 1);
13853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    } else if (strncmp(argv[i], "--", 2) == 0) {
13863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      printf("Warning: unknown flag %s.\nTry --help for options\n", argv[i]);
13873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    }
13883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
13893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  current->End(argc);
1390a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
13913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  return true;
13923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
13933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
13943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
13953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochint Shell::RunMain(int argc, char* argv[]) {
139669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#ifndef V8_SHARED
13973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  i::List<i::Thread*> threads(1);
1398589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  if (options.parallel_files != NULL) {
1399589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    for (int i = 0; i < options.num_parallel_files; i++) {
1400589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      char* files = NULL;
1401589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      { Locker lock(Isolate::GetCurrent());
1402589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        int size = 0;
1403589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        files = ReadChars(options.parallel_files[i], &size);
1404589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      }
1405589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      if (files == NULL) {
1406589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        printf("File list '%s' not found\n", options.parallel_files[i]);
1407589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        Exit(1);
1408589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      }
14093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      ShellThread* thread = new ShellThread(threads.length(), files);
14103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      thread->Start();
14113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      threads.Add(thread);
1412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
1413589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  }
14143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  for (int i = 1; i < options.num_isolates; ++i) {
14153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    options.isolate_sources[i].StartExecuteInThread();
1416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
141769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#endif  // V8_SHARED
14183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  {  // NOLINT
14193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    Locker lock;
14203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    HandleScope scope;
14213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    Persistent<Context> context = CreateEvaluationContext();
14223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (options.last_run) {
14233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      // Keep using the same context in the interactive shell.
14243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      evaluation_context_ = context;
14253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#if !defined(V8_SHARED) && defined(ENABLE_DEBUGGER_SUPPORT)
14263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      // If the interactive debugger is enabled make sure to activate
14273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      // it before running the files passed on the command line.
14283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      if (i::FLAG_debugger) {
14293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        InstallUtilityScript();
14303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      }
14313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif  // !V8_SHARED && ENABLE_DEBUGGER_SUPPORT
14323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
14333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    {
14343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      Context::Scope cscope(context);
14353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      options.isolate_sources[0].Execute();
14363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    }
14373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (!options.last_run) {
14383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      context.Dispose();
14393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#if !defined(V8_SHARED)
14403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      if (i::FLAG_send_idle_notification) {
14413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        const int kLongIdlePauseInMs = 1000;
14423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        V8::ContextDisposedNotification();
14433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        V8::IdleNotification(kLongIdlePauseInMs);
14443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      }
14453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif  // !V8_SHARED
14463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    }
14473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
144869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#ifndef V8_SHARED
14493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    // Start preemption if threads have been created and preemption is enabled.
1450589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    if (threads.length() > 0
14513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch        && options.use_preemption) {
14523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      Locker::StartPreemption(options.preemption_interval);
14533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    }
145469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#endif  // V8_SHARED
1455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
14563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
145769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#ifndef V8_SHARED
14583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  for (int i = 1; i < options.num_isolates; ++i) {
14593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    options.isolate_sources[i].WaitForThread();
14603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
14613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1462589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  for (int i = 0; i < threads.length(); i++) {
1463589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    i::Thread* thread = threads[i];
1464589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    thread->Join();
1465589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    delete thread;
1466589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  }
1467589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
1468589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  if (threads.length() > 0 && options.use_preemption) {
1469589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    Locker lock;
1470589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    Locker::StopPreemption();
1471589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  }
147269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#endif  // V8_SHARED
1473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return 0;
1474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
14773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochint Shell::Main(int argc, char* argv[]) {
14783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  if (!SetOptions(argc, argv)) return 1;
14793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  Initialize();
14803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
14813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  int result = 0;
14823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  if (options.stress_opt || options.stress_deopt) {
14833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    Testing::SetStressRunType(
14843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch        options.stress_opt ? Testing::kStressTypeOpt
14853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                           : Testing::kStressTypeDeopt);
14863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    int stress_runs = Testing::GetStressRuns();
14873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    for (int i = 0; i < stress_runs && result == 0; i++) {
14883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      printf("============ Stress %d/%d ============\n", i + 1, stress_runs);
14893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      Testing::PrepareStressRun(i);
14903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      options.last_run = (i == stress_runs - 1);
14913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      result = RunMain(argc, argv);
14923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    }
14933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    printf("======== Full Deoptimization =======\n");
14943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    Testing::DeoptimizeAll();
14953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#if !defined(V8_SHARED)
14963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  } else if (i::FLAG_stress_runs > 0) {
14973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    int stress_runs = i::FLAG_stress_runs;
14983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    for (int i = 0; i < stress_runs && result == 0; i++) {
14993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      printf("============ Run %d/%d ============\n", i + 1, stress_runs);
15003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      options.last_run = (i == stress_runs - 1);
15013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      result = RunMain(argc, argv);
15023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
15033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif
15043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  } else {
15053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    result = RunMain(argc, argv);
15063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
15073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
15083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
150969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#if !defined(V8_SHARED) && defined(ENABLE_DEBUGGER_SUPPORT)
15103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Run remote debugger if requested, but never on --test
15113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  if (i::FLAG_remote_debugger && !options.test_shell) {
15123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    InstallUtilityScript();
15133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    RunRemoteDebugger(i::FLAG_debugger_port);
15143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    return 0;
15153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
151669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#endif  // !V8_SHARED && ENABLE_DEBUGGER_SUPPORT
15173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
15183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Run interactive shell if explicitly requested or if no script has been
15193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // executed, but never on --test
15203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
15213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  if (( options.interactive_shell
15223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      || !options.script_executed )
15233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      && !options.test_shell ) {
15243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#if !defined(V8_SHARED) && defined(ENABLE_DEBUGGER_SUPPORT)
15253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (!i::FLAG_debugger) {
15263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      InstallUtilityScript();
15273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
15283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif  // !V8_SHARED && ENABLE_DEBUGGER_SUPPORT
15293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    RunShell();
15303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
15313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
15323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  V8::Dispose();
15333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
153469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#ifndef V8_SHARED
153569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  OnExit();
153669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#endif  // V8_SHARED
153769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
15383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  return result;
15393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
15403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}  // namespace v8
1542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1543a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1544257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#ifndef GOOGLE3
1545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint main(int argc, char* argv[]) {
1546a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return v8::Shell::Main(argc, argv);
1547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1548257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#endif
1549