The data contained in this repository can be downloaded to your computer using one of several clients.
Please see the documentation of your version control software client for more information.

Please select the desired protocol below to get the URL.

This URL has Read-Only access.

Statistics
| Branch: | Revision:

main_repo / deps / v8 / samples / shell.cc @ 40c0f755

History | View | Annotate | Download (9.68 KB)

1
// Copyright 2009 the V8 project authors. All rights reserved.
2
// Redistribution and use in source and binary forms, with or without
3
// modification, are permitted provided that the following conditions are
4
// met:
5
//
6
//     * Redistributions of source code must retain the above copyright
7
//       notice, this list of conditions and the following disclaimer.
8
//     * Redistributions in binary form must reproduce the above
9
//       copyright notice, this list of conditions and the following
10
//       disclaimer in the documentation and/or other materials provided
11
//       with the distribution.
12
//     * Neither the name of Google Inc. nor the names of its
13
//       contributors may be used to endorse or promote products derived
14
//       from this software without specific prior written permission.
15
//
16
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27

    
28
#include <v8.h>
29
#include <fcntl.h>
30
#include <string.h>
31
#include <stdio.h>
32
#include <stdlib.h>
33

    
34

    
35
void RunShell(v8::Handle<v8::Context> context);
36
bool ExecuteString(v8::Handle<v8::String> source,
37
                   v8::Handle<v8::Value> name,
38
                   bool print_result,
39
                   bool report_exceptions);
40
v8::Handle<v8::Value> Print(const v8::Arguments& args);
41
v8::Handle<v8::Value> Load(const v8::Arguments& args);
42
v8::Handle<v8::Value> Quit(const v8::Arguments& args);
43
v8::Handle<v8::Value> Version(const v8::Arguments& args);
44
v8::Handle<v8::String> ReadFile(const char* name);
45
void ReportException(v8::TryCatch* handler);
46

    
47

    
48
int RunMain(int argc, char* argv[]) {
49
  v8::V8::SetFlagsFromCommandLine(&argc, argv, true);
50
  v8::HandleScope handle_scope;
51
  // Create a template for the global object.
52
  v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New();
53
  // Bind the global 'print' function to the C++ Print callback.
54
  global->Set(v8::String::New("print"), v8::FunctionTemplate::New(Print));
55
  // Bind the global 'load' function to the C++ Load callback.
56
  global->Set(v8::String::New("load"), v8::FunctionTemplate::New(Load));
57
  // Bind the 'quit' function
58
  global->Set(v8::String::New("quit"), v8::FunctionTemplate::New(Quit));
59
  // Bind the 'version' function
60
  global->Set(v8::String::New("version"), v8::FunctionTemplate::New(Version));
61
  // Create a new execution environment containing the built-in
62
  // functions
63
  v8::Handle<v8::Context> context = v8::Context::New(NULL, global);
64
  // Enter the newly created execution environment.
65
  v8::Context::Scope context_scope(context);
66
  bool run_shell = (argc == 1);
67
  for (int i = 1; i < argc; i++) {
68
    const char* str = argv[i];
69
    if (strcmp(str, "--shell") == 0) {
70
      run_shell = true;
71
    } else if (strcmp(str, "-f") == 0) {
72
      // Ignore any -f flags for compatibility with the other stand-
73
      // alone JavaScript engines.
74
      continue;
75
    } else if (strncmp(str, "--", 2) == 0) {
76
      printf("Warning: unknown flag %s.\nTry --help for options\n", str);
77
    } else if (strcmp(str, "-e") == 0 && i + 1 < argc) {
78
      // Execute argument given to -e option directly
79
      v8::HandleScope handle_scope;
80
      v8::Handle<v8::String> file_name = v8::String::New("unnamed");
81
      v8::Handle<v8::String> source = v8::String::New(argv[i + 1]);
82
      if (!ExecuteString(source, file_name, false, true))
83
        return 1;
84
      i++;
85
    } else {
86
      // Use all other arguments as names of files to load and run.
87
      v8::HandleScope handle_scope;
88
      v8::Handle<v8::String> file_name = v8::String::New(str);
89
      v8::Handle<v8::String> source = ReadFile(str);
90
      if (source.IsEmpty()) {
91
        printf("Error reading '%s'\n", str);
92
        return 1;
93
      }
94
      if (!ExecuteString(source, file_name, false, true))
95
        return 1;
96
    }
97
  }
98
  if (run_shell) RunShell(context);
99
  return 0;
100
}
101

    
102

    
103
int main(int argc, char* argv[]) {
104
  int result = RunMain(argc, argv);
105
  v8::V8::Dispose();
106
  return result;
107
}
108

    
109

    
110
// Extracts a C string from a V8 Utf8Value.
111
const char* ToCString(const v8::String::Utf8Value& value) {
112
  return *value ? *value : "<string conversion failed>";
113
}
114

    
115

    
116
// The callback that is invoked by v8 whenever the JavaScript 'print'
117
// function is called.  Prints its arguments on stdout separated by
118
// spaces and ending with a newline.
119
v8::Handle<v8::Value> Print(const v8::Arguments& args) {
120
  bool first = true;
121
  for (int i = 0; i < args.Length(); i++) {
122
    v8::HandleScope handle_scope;
123
    if (first) {
124
      first = false;
125
    } else {
126
      printf(" ");
127
    }
128
    v8::String::Utf8Value str(args[i]);
129
    const char* cstr = ToCString(str);
130
    printf("%s", cstr);
131
  }
132
  printf("\n");
133
  fflush(stdout);
134
  return v8::Undefined();
135
}
136

    
137

    
138
// The callback that is invoked by v8 whenever the JavaScript 'load'
139
// function is called.  Loads, compiles and executes its argument
140
// JavaScript file.
141
v8::Handle<v8::Value> Load(const v8::Arguments& args) {
142
  for (int i = 0; i < args.Length(); i++) {
143
    v8::HandleScope handle_scope;
144
    v8::String::Utf8Value file(args[i]);
145
    if (*file == NULL) {
146
      return v8::ThrowException(v8::String::New("Error loading file"));
147
    }
148
    v8::Handle<v8::String> source = ReadFile(*file);
149
    if (source.IsEmpty()) {
150
      return v8::ThrowException(v8::String::New("Error loading file"));
151
    }
152
    if (!ExecuteString(source, v8::String::New(*file), false, false)) {
153
      return v8::ThrowException(v8::String::New("Error executing file"));
154
    }
155
  }
156
  return v8::Undefined();
157
}
158

    
159

    
160
// The callback that is invoked by v8 whenever the JavaScript 'quit'
161
// function is called.  Quits.
162
v8::Handle<v8::Value> Quit(const v8::Arguments& args) {
163
  // If not arguments are given args[0] will yield undefined which
164
  // converts to the integer value 0.
165
  int exit_code = args[0]->Int32Value();
166
  exit(exit_code);
167
  return v8::Undefined();
168
}
169

    
170

    
171
v8::Handle<v8::Value> Version(const v8::Arguments& args) {
172
  return v8::String::New(v8::V8::GetVersion());
173
}
174

    
175

    
176
// Reads a file into a v8 string.
177
v8::Handle<v8::String> ReadFile(const char* name) {
178
  FILE* file = fopen(name, "rb");
179
  if (file == NULL) return v8::Handle<v8::String>();
180

    
181
  fseek(file, 0, SEEK_END);
182
  int size = ftell(file);
183
  rewind(file);
184

    
185
  char* chars = new char[size + 1];
186
  chars[size] = '\0';
187
  for (int i = 0; i < size;) {
188
    int read = fread(&chars[i], 1, size - i, file);
189
    i += read;
190
  }
191
  fclose(file);
192
  v8::Handle<v8::String> result = v8::String::New(chars, size);
193
  delete[] chars;
194
  return result;
195
}
196

    
197

    
198
// The read-eval-execute loop of the shell.
199
void RunShell(v8::Handle<v8::Context> context) {
200
  printf("V8 version %s\n", v8::V8::GetVersion());
201
  static const int kBufferSize = 256;
202
  while (true) {
203
    char buffer[kBufferSize];
204
    printf("> ");
205
    char* str = fgets(buffer, kBufferSize, stdin);
206
    if (str == NULL) break;
207
    v8::HandleScope handle_scope;
208
    ExecuteString(v8::String::New(str),
209
                  v8::String::New("(shell)"),
210
                  true,
211
                  true);
212
  }
213
  printf("\n");
214
}
215

    
216

    
217
// Executes a string within the current v8 context.
218
bool ExecuteString(v8::Handle<v8::String> source,
219
                   v8::Handle<v8::Value> name,
220
                   bool print_result,
221
                   bool report_exceptions) {
222
  v8::HandleScope handle_scope;
223
  v8::TryCatch try_catch;
224
  v8::Handle<v8::Script> script = v8::Script::Compile(source, name);
225
  if (script.IsEmpty()) {
226
    // Print errors that happened during compilation.
227
    if (report_exceptions)
228
      ReportException(&try_catch);
229
    return false;
230
  } else {
231
    v8::Handle<v8::Value> result = script->Run();
232
    if (result.IsEmpty()) {
233
      // Print errors that happened during execution.
234
      if (report_exceptions)
235
        ReportException(&try_catch);
236
      return false;
237
    } else {
238
      if (print_result && !result->IsUndefined()) {
239
        // If all went well and the result wasn't undefined then print
240
        // the returned value.
241
        v8::String::Utf8Value str(result);
242
        const char* cstr = ToCString(str);
243
        printf("%s\n", cstr);
244
      }
245
      return true;
246
    }
247
  }
248
}
249

    
250

    
251
void ReportException(v8::TryCatch* try_catch) {
252
  v8::HandleScope handle_scope;
253
  v8::String::Utf8Value exception(try_catch->Exception());
254
  const char* exception_string = ToCString(exception);
255
  v8::Handle<v8::Message> message = try_catch->Message();
256
  if (message.IsEmpty()) {
257
    // V8 didn't provide any extra information about this error; just
258
    // print the exception.
259
    printf("%s\n", exception_string);
260
  } else {
261
    // Print (filename):(line number): (message).
262
    v8::String::Utf8Value filename(message->GetScriptResourceName());
263
    const char* filename_string = ToCString(filename);
264
    int linenum = message->GetLineNumber();
265
    printf("%s:%i: %s\n", filename_string, linenum, exception_string);
266
    // Print line of source code.
267
    v8::String::Utf8Value sourceline(message->GetSourceLine());
268
    const char* sourceline_string = ToCString(sourceline);
269
    printf("%s\n", sourceline_string);
270
    // Print wavy underline (GetUnderline is deprecated).
271
    int start = message->GetStartColumn();
272
    for (int i = 0; i < start; i++) {
273
      printf(" ");
274
    }
275
    int end = message->GetEndColumn();
276
    for (int i = start; i < end; i++) {
277
      printf("^");
278
    }
279
    printf("\n");
280
  }
281
}