blob: 5a5238011aea88af32d8506d90d1fb3060bd1174 [file] [log] [blame]
ager@chromium.org41826e72009-03-30 13:30:57 +00001// Copyright 2009 the V8 project authors. All rights reserved.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002// 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
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +000029#ifdef COMPRESS_STARTUP_DATA_BZ2
30#include <bzlib.h>
31#endif
ager@chromium.orgbb29dc92009-03-24 13:25:23 +000032#include <errno.h>
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +000033#include <stdlib.h>
ager@chromium.orga74f0da2008-12-03 16:05:52 +000034
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000035#include "v8.h"
36
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +000037#include "d8.h"
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +000038#include "d8-debug.h"
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +000039#include "debug.h"
40#include "api.h"
41#include "natives.h"
ager@chromium.orgddb913d2009-01-27 10:01:48 +000042#include "platform.h"
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +000043
44
45namespace v8 {
46
47
48const char* Shell::kHistoryFileName = ".d8_history";
49const char* Shell::kPrompt = "d8> ";
50
51
52LineEditor *LineEditor::first_ = NULL;
53
54
55LineEditor::LineEditor(Type type, const char* name)
56 : type_(type),
57 name_(name),
58 next_(first_) {
59 first_ = this;
60}
61
62
63LineEditor* LineEditor::Get() {
64 LineEditor* current = first_;
65 LineEditor* best = current;
66 while (current != NULL) {
67 if (current->type_ > best->type_)
68 best = current;
69 current = current->next_;
70 }
71 return best;
72}
73
74
75class DumbLineEditor: public LineEditor {
76 public:
77 DumbLineEditor() : LineEditor(LineEditor::DUMB, "dumb") { }
78 virtual i::SmartPointer<char> Prompt(const char* prompt);
79};
80
81
82static DumbLineEditor dumb_line_editor;
83
84
85i::SmartPointer<char> DumbLineEditor::Prompt(const char* prompt) {
86 static const int kBufferSize = 256;
87 char buffer[kBufferSize];
88 printf("%s", prompt);
89 char* str = fgets(buffer, kBufferSize, stdin);
ager@chromium.orga74f0da2008-12-03 16:05:52 +000090 return i::SmartPointer<char>(str ? i::StrDup(str) : str);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +000091}
92
93
kasperl@chromium.orgf5aa8372009-03-24 14:47:14 +000094CounterMap* Shell::counter_map_;
ager@chromium.orga74f0da2008-12-03 16:05:52 +000095i::OS::MemoryMappedFile* Shell::counters_file_ = NULL;
96CounterCollection Shell::local_counters_;
97CounterCollection* Shell::counters_ = &local_counters_;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +000098Persistent<Context> Shell::utility_context_;
99Persistent<Context> Shell::evaluation_context_;
100
101
kasperl@chromium.orgf5aa8372009-03-24 14:47:14 +0000102bool CounterMap::Match(void* key1, void* key2) {
103 const char* name1 = reinterpret_cast<const char*>(key1);
104 const char* name2 = reinterpret_cast<const char*>(key2);
105 return strcmp(name1, name2) == 0;
106}
107
108
iposva@chromium.org245aa852009-02-10 00:49:54 +0000109// Converts a V8 value to a C string.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +0000110const char* Shell::ToCString(const v8::String::Utf8Value& value) {
iposva@chromium.org245aa852009-02-10 00:49:54 +0000111 return *value ? *value : "<string conversion failed>";
112}
113
114
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000115// Executes a string within the current v8 context.
116bool Shell::ExecuteString(Handle<String> source,
117 Handle<Value> name,
118 bool print_result,
119 bool report_exceptions) {
120 HandleScope handle_scope;
121 TryCatch try_catch;
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000122 if (i::FLAG_debugger) {
123 // When debugging make exceptions appear to be uncaught.
124 try_catch.SetVerbose(true);
125 }
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000126 Handle<Script> script = Script::Compile(source, name);
127 if (script.IsEmpty()) {
128 // Print errors that happened during compilation.
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000129 if (report_exceptions && !i::FLAG_debugger)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000130 ReportException(&try_catch);
131 return false;
132 } else {
133 Handle<Value> result = script->Run();
134 if (result.IsEmpty()) {
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +0000135 ASSERT(try_catch.HasCaught());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000136 // Print errors that happened during execution.
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000137 if (report_exceptions && !i::FLAG_debugger)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000138 ReportException(&try_catch);
139 return false;
140 } else {
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +0000141 ASSERT(!try_catch.HasCaught());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000142 if (print_result && !result->IsUndefined()) {
143 // If all went well and the result wasn't undefined then print
144 // the returned value.
iposva@chromium.org245aa852009-02-10 00:49:54 +0000145 v8::String::Utf8Value str(result);
146 const char* cstr = ToCString(str);
147 printf("%s\n", cstr);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000148 }
149 return true;
150 }
151 }
152}
153
154
155Handle<Value> Shell::Print(const Arguments& args) {
christian.plesner.hansen@gmail.com5a6af922009-08-12 14:20:51 +0000156 Handle<Value> val = Write(args);
157 printf("\n");
158 return val;
159}
160
161
162Handle<Value> Shell::Write(const Arguments& args) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000163 for (int i = 0; i < args.Length(); i++) {
164 HandleScope handle_scope;
christian.plesner.hansen@gmail.com5a6af922009-08-12 14:20:51 +0000165 if (i != 0) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000166 printf(" ");
167 }
iposva@chromium.org245aa852009-02-10 00:49:54 +0000168 v8::String::Utf8Value str(args[i]);
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +0000169 int n = fwrite(*str, sizeof(**str), str.length(), stdout);
170 if (n != str.length()) {
171 printf("Error in fwrite\n");
172 exit(1);
173 }
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000174 }
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000175 return Undefined();
176}
177
178
ager@chromium.org65dad4b2009-04-23 08:48:43 +0000179Handle<Value> Shell::Read(const Arguments& args) {
ager@chromium.org65dad4b2009-04-23 08:48:43 +0000180 String::Utf8Value file(args[0]);
181 if (*file == NULL) {
182 return ThrowException(String::New("Error loading file"));
183 }
184 Handle<String> source = ReadFile(*file);
185 if (source.IsEmpty()) {
186 return ThrowException(String::New("Error loading file"));
187 }
188 return source;
189}
190
191
ager@chromium.orgadd848f2009-08-13 12:44:13 +0000192Handle<Value> Shell::ReadLine(const Arguments& args) {
ager@chromium.orga1645e22009-09-09 19:27:10 +0000193 i::SmartPointer<char> line(i::ReadLine(""));
194 if (*line == NULL) {
195 return Null();
ager@chromium.orgadd848f2009-08-13 12:44:13 +0000196 }
ager@chromium.orga1645e22009-09-09 19:27:10 +0000197 size_t len = strlen(*line);
198 if (len > 0 && line[len - 1] == '\n') {
ager@chromium.orgadd848f2009-08-13 12:44:13 +0000199 --len;
200 }
ager@chromium.orga1645e22009-09-09 19:27:10 +0000201 return String::New(*line, len);
ager@chromium.orgadd848f2009-08-13 12:44:13 +0000202}
203
204
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000205Handle<Value> Shell::Load(const Arguments& args) {
206 for (int i = 0; i < args.Length(); i++) {
207 HandleScope handle_scope;
208 String::Utf8Value file(args[i]);
iposva@chromium.org245aa852009-02-10 00:49:54 +0000209 if (*file == NULL) {
210 return ThrowException(String::New("Error loading file"));
211 }
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000212 Handle<String> source = ReadFile(*file);
213 if (source.IsEmpty()) {
214 return ThrowException(String::New("Error loading file"));
215 }
216 if (!ExecuteString(source, String::New(*file), false, false)) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +0000217 return ThrowException(String::New("Error executing file"));
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000218 }
219 }
220 return Undefined();
221}
222
223
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000224Handle<Value> Shell::CreateExternalArray(const Arguments& args,
225 ExternalArrayType type,
226 int element_size) {
227 if (args.Length() != 1) {
228 return ThrowException(
229 String::New("Array constructor needs one parameter."));
230 }
231 int length = args[0]->Int32Value();
232 void* data = malloc(length * element_size);
233 memset(data, 0, length * element_size);
234 Handle<Object> array = Object::New();
235 Persistent<Object> persistent_array = Persistent<Object>::New(array);
236 persistent_array.MakeWeak(data, ExternalArrayWeakCallback);
237 persistent_array.MarkIndependent();
238 array->SetIndexedPropertiesToExternalArrayData(data, type, length);
239 array->Set(String::New("length"), Int32::New(length), ReadOnly);
240 array->Set(String::New("BYTES_PER_ELEMENT"), Int32::New(element_size));
241 return array;
242}
243
244
245void Shell::ExternalArrayWeakCallback(Persistent<Value> object, void* data) {
246 free(data);
247 object.Dispose();
248}
249
250
251Handle<Value> Shell::Int8Array(const Arguments& args) {
252 return CreateExternalArray(args, v8::kExternalByteArray, sizeof(int8_t));
253}
254
255
256Handle<Value> Shell::Uint8Array(const Arguments& args) {
257 return CreateExternalArray(args, kExternalUnsignedByteArray, sizeof(uint8_t));
258}
259
260
261Handle<Value> Shell::Int16Array(const Arguments& args) {
262 return CreateExternalArray(args, kExternalShortArray, sizeof(int16_t));
263}
264
265
266Handle<Value> Shell::Uint16Array(const Arguments& args) {
267 return CreateExternalArray(args, kExternalUnsignedShortArray,
268 sizeof(uint16_t));
269}
270
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000271
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000272Handle<Value> Shell::Int32Array(const Arguments& args) {
273 return CreateExternalArray(args, kExternalIntArray, sizeof(int32_t));
274}
275
276
277Handle<Value> Shell::Uint32Array(const Arguments& args) {
278 return CreateExternalArray(args, kExternalUnsignedIntArray, sizeof(uint32_t));
279}
280
281
282Handle<Value> Shell::Float32Array(const Arguments& args) {
283 return CreateExternalArray(args, kExternalFloatArray,
284 sizeof(float)); // NOLINT
285}
286
287
288Handle<Value> Shell::Float64Array(const Arguments& args) {
289 return CreateExternalArray(args, kExternalDoubleArray,
290 sizeof(double)); // NOLINT
291}
292
293
294Handle<Value> Shell::PixelArray(const Arguments& args) {
295 return CreateExternalArray(args, kExternalPixelArray, sizeof(uint8_t));
296}
297
298
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000299Handle<Value> Shell::Yield(const Arguments& args) {
300 v8::Unlocker unlocker;
301 return Undefined();
302}
303
304
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000305Handle<Value> Shell::Quit(const Arguments& args) {
306 int exit_code = args[0]->Int32Value();
307 OnExit();
308 exit(exit_code);
309 return Undefined();
310}
311
312
313Handle<Value> Shell::Version(const Arguments& args) {
314 return String::New(V8::GetVersion());
315}
316
317
318void Shell::ReportException(v8::TryCatch* try_catch) {
319 HandleScope handle_scope;
iposva@chromium.org245aa852009-02-10 00:49:54 +0000320 v8::String::Utf8Value exception(try_catch->Exception());
321 const char* exception_string = ToCString(exception);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000322 Handle<Message> message = try_catch->Message();
323 if (message.IsEmpty()) {
324 // V8 didn't provide any extra information about this error; just
325 // print the exception.
iposva@chromium.org245aa852009-02-10 00:49:54 +0000326 printf("%s\n", exception_string);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000327 } else {
328 // Print (filename):(line number): (message).
iposva@chromium.org245aa852009-02-10 00:49:54 +0000329 v8::String::Utf8Value filename(message->GetScriptResourceName());
330 const char* filename_string = ToCString(filename);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000331 int linenum = message->GetLineNumber();
iposva@chromium.org245aa852009-02-10 00:49:54 +0000332 printf("%s:%i: %s\n", filename_string, linenum, exception_string);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000333 // Print line of source code.
iposva@chromium.org245aa852009-02-10 00:49:54 +0000334 v8::String::Utf8Value sourceline(message->GetSourceLine());
335 const char* sourceline_string = ToCString(sourceline);
336 printf("%s\n", sourceline_string);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000337 // Print wavy underline (GetUnderline is deprecated).
338 int start = message->GetStartColumn();
339 for (int i = 0; i < start; i++) {
340 printf(" ");
341 }
342 int end = message->GetEndColumn();
343 for (int i = start; i < end; i++) {
344 printf("^");
345 }
346 printf("\n");
danno@chromium.org40cb8782011-05-25 07:58:50 +0000347 v8::String::Utf8Value stack_trace(try_catch->StackTrace());
348 if (stack_trace.length() > 0) {
349 const char* stack_trace_string = ToCString(stack_trace);
350 printf("%s\n", stack_trace_string);
351 }
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000352 }
353}
354
355
356Handle<Array> Shell::GetCompletions(Handle<String> text, Handle<String> full) {
357 HandleScope handle_scope;
358 Context::Scope context_scope(utility_context_);
359 Handle<Object> global = utility_context_->Global();
360 Handle<Value> fun = global->Get(String::New("GetCompletions"));
361 static const int kArgc = 3;
362 Handle<Value> argv[kArgc] = { evaluation_context_->Global(), text, full };
363 Handle<Value> val = Handle<Function>::Cast(fun)->Call(global, kArgc, argv);
364 return handle_scope.Close(Handle<Array>::Cast(val));
365}
366
367
ager@chromium.org65dad4b2009-04-23 08:48:43 +0000368#ifdef ENABLE_DEBUGGER_SUPPORT
kasperl@chromium.org7be3c992009-03-12 07:19:55 +0000369Handle<Object> Shell::DebugMessageDetails(Handle<String> message) {
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000370 Context::Scope context_scope(utility_context_);
371 Handle<Object> global = utility_context_->Global();
kasperl@chromium.org7be3c992009-03-12 07:19:55 +0000372 Handle<Value> fun = global->Get(String::New("DebugMessageDetails"));
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000373 static const int kArgc = 1;
kasperl@chromium.org7be3c992009-03-12 07:19:55 +0000374 Handle<Value> argv[kArgc] = { message };
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000375 Handle<Value> val = Handle<Function>::Cast(fun)->Call(global, kArgc, argv);
kasperl@chromium.org7be3c992009-03-12 07:19:55 +0000376 return Handle<Object>::Cast(val);
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000377}
378
379
380Handle<Value> Shell::DebugCommandToJSONRequest(Handle<String> command) {
381 Context::Scope context_scope(utility_context_);
382 Handle<Object> global = utility_context_->Global();
383 Handle<Value> fun = global->Get(String::New("DebugCommandToJSONRequest"));
384 static const int kArgc = 1;
385 Handle<Value> argv[kArgc] = { command };
386 Handle<Value> val = Handle<Function>::Cast(fun)->Call(global, kArgc, argv);
387 return val;
388}
ager@chromium.org65dad4b2009-04-23 08:48:43 +0000389#endif
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000390
391
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +0000392int32_t* Counter::Bind(const char* name, bool is_histogram) {
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000393 int i;
394 for (i = 0; i < kMaxNameSize - 1 && name[i]; i++)
395 name_[i] = static_cast<char>(name[i]);
396 name_[i] = '\0';
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +0000397 is_histogram_ = is_histogram;
398 return ptr();
399}
400
401
402void Counter::AddSample(int32_t sample) {
403 count_++;
404 sample_total_ += sample;
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000405}
406
407
408CounterCollection::CounterCollection() {
409 magic_number_ = 0xDEADFACE;
410 max_counters_ = kMaxCounters;
411 max_name_size_ = Counter::kMaxNameSize;
412 counters_in_use_ = 0;
413}
414
415
416Counter* CounterCollection::GetNextCounter() {
417 if (counters_in_use_ == kMaxCounters) return NULL;
418 return &counters_[counters_in_use_++];
419}
420
421
422void Shell::MapCounters(const char* name) {
423 counters_file_ = i::OS::MemoryMappedFile::create(name,
424 sizeof(CounterCollection), &local_counters_);
425 void* memory = (counters_file_ == NULL) ?
426 NULL : counters_file_->memory();
427 if (memory == NULL) {
428 printf("Could not map counters file %s\n", name);
429 exit(1);
430 }
431 counters_ = static_cast<CounterCollection*>(memory);
432 V8::SetCounterFunction(LookupCounter);
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +0000433 V8::SetCreateHistogramFunction(CreateHistogram);
434 V8::SetAddHistogramSampleFunction(AddHistogramSample);
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000435}
436
437
kasperl@chromium.orgf5aa8372009-03-24 14:47:14 +0000438int CounterMap::Hash(const char* name) {
439 int h = 0;
440 int c;
441 while ((c = *name++) != 0) {
442 h += h << 5;
443 h += c;
444 }
445 return h;
446}
447
448
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +0000449Counter* Shell::GetCounter(const char* name, bool is_histogram) {
kasperl@chromium.orgf5aa8372009-03-24 14:47:14 +0000450 Counter* counter = counter_map_->Lookup(name);
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +0000451
452 if (counter == NULL) {
453 counter = counters_->GetNextCounter();
454 if (counter != NULL) {
455 counter_map_->Set(name, counter);
456 counter->Bind(name, is_histogram);
457 }
458 } else {
459 ASSERT(counter->is_histogram() == is_histogram);
460 }
461 return counter;
462}
463
464
465int* Shell::LookupCounter(const char* name) {
466 Counter* counter = GetCounter(name, false);
467
kasperl@chromium.orgf5aa8372009-03-24 14:47:14 +0000468 if (counter != NULL) {
469 return counter->ptr();
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +0000470 } else {
471 return NULL;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000472 }
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +0000473}
474
475
476void* Shell::CreateHistogram(const char* name,
477 int min,
478 int max,
479 size_t buckets) {
480 return GetCounter(name, true);
481}
482
483
484void Shell::AddHistogramSample(void* histogram, int sample) {
485 Counter* counter = reinterpret_cast<Counter*>(histogram);
486 counter->AddSample(sample);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000487}
488
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000489void Shell::InstallUtilityScript() {
490 Locker lock;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000491 HandleScope scope;
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000492 Context::Scope utility_scope(utility_context_);
493 // Run the d8 shell utility script in the utility context
494 int source_index = i::NativesCollection<i::D8>::GetIndex("d8");
495 i::Vector<const char> shell_source =
496 i::NativesCollection<i::D8>::GetRawScriptSource(source_index);
497 i::Vector<const char> shell_source_name =
498 i::NativesCollection<i::D8>::GetScriptName(source_index);
499 Handle<String> source = String::New(shell_source.start(),
500 shell_source.length());
501 Handle<String> name = String::New(shell_source_name.start(),
502 shell_source_name.length());
503 Handle<Script> script = Script::Compile(source, name);
504 script->Run();
505
506 // Mark the d8 shell script as native to avoid it showing up as normal source
507 // in the debugger.
508 i::Handle<i::Object> compiled_script = Utils::OpenHandle(*script);
509 i::Handle<i::Script> script_object = compiled_script->IsJSFunction()
510 ? i::Handle<i::Script>(i::Script::cast(
511 i::JSFunction::cast(*compiled_script)->shared()->script()))
512 : i::Handle<i::Script>(i::Script::cast(
513 i::SharedFunctionInfo::cast(*compiled_script)->script()));
514 script_object->set_type(i::Smi::FromInt(i::Script::TYPE_NATIVE));
515}
516
517#ifdef COMPRESS_STARTUP_DATA_BZ2
518class BZip2Decompressor : public v8::StartupDataDecompressor {
519 public:
520 virtual ~BZip2Decompressor() { }
521
522 protected:
523 virtual int DecompressData(char* raw_data,
524 int* raw_data_size,
525 const char* compressed_data,
526 int compressed_data_size) {
527 ASSERT_EQ(v8::StartupData::kBZip2,
528 v8::V8::GetCompressedStartupDataAlgorithm());
529 unsigned int decompressed_size = *raw_data_size;
530 int result =
531 BZ2_bzBuffToBuffDecompress(raw_data,
532 &decompressed_size,
533 const_cast<char*>(compressed_data),
534 compressed_data_size,
535 0, 1);
536 if (result == BZ_OK) {
537 *raw_data_size = decompressed_size;
538 }
539 return result;
540 }
541};
542#endif
543
544Handle<ObjectTemplate> Shell::CreateGlobalTemplate() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000545 Handle<ObjectTemplate> global_template = ObjectTemplate::New();
546 global_template->Set(String::New("print"), FunctionTemplate::New(Print));
christian.plesner.hansen@gmail.com5a6af922009-08-12 14:20:51 +0000547 global_template->Set(String::New("write"), FunctionTemplate::New(Write));
ager@chromium.org65dad4b2009-04-23 08:48:43 +0000548 global_template->Set(String::New("read"), FunctionTemplate::New(Read));
ager@chromium.orgadd848f2009-08-13 12:44:13 +0000549 global_template->Set(String::New("readline"),
550 FunctionTemplate::New(ReadLine));
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000551 global_template->Set(String::New("load"), FunctionTemplate::New(Load));
552 global_template->Set(String::New("quit"), FunctionTemplate::New(Quit));
553 global_template->Set(String::New("version"), FunctionTemplate::New(Version));
ager@chromium.org71daaf62009-04-01 07:22:49 +0000554
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000555 // Bind the handlers for external arrays.
556 global_template->Set(String::New("Int8Array"),
557 FunctionTemplate::New(Int8Array));
558 global_template->Set(String::New("Uint8Array"),
559 FunctionTemplate::New(Uint8Array));
560 global_template->Set(String::New("Int16Array"),
561 FunctionTemplate::New(Int16Array));
562 global_template->Set(String::New("Uint16Array"),
563 FunctionTemplate::New(Uint16Array));
564 global_template->Set(String::New("Int32Array"),
565 FunctionTemplate::New(Int32Array));
566 global_template->Set(String::New("Uint32Array"),
567 FunctionTemplate::New(Uint32Array));
568 global_template->Set(String::New("Float32Array"),
569 FunctionTemplate::New(Float32Array));
570 global_template->Set(String::New("Float64Array"),
571 FunctionTemplate::New(Float64Array));
572 global_template->Set(String::New("PixelArray"),
573 FunctionTemplate::New(PixelArray));
574
ager@chromium.org9ee27ae2011-03-02 13:43:26 +0000575#ifdef LIVE_OBJECT_LIST
576 global_template->Set(String::New("lol_is_enabled"), Boolean::New(true));
577#else
578 global_template->Set(String::New("lol_is_enabled"), Boolean::New(false));
579#endif
580
ager@chromium.org71daaf62009-04-01 07:22:49 +0000581 Handle<ObjectTemplate> os_templ = ObjectTemplate::New();
582 AddOSMethods(os_templ);
583 global_template->Set(String::New("os"), os_templ);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000584
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000585 return global_template;
586}
587
588void Shell::Initialize() {
589#ifdef COMPRESS_STARTUP_DATA_BZ2
590 BZip2Decompressor startup_data_decompressor;
591 int bz2_result = startup_data_decompressor.Decompress();
592 if (bz2_result != BZ_OK) {
593 fprintf(stderr, "bzip error code: %d\n", bz2_result);
594 exit(1);
595 }
596#endif
597
598 Shell::counter_map_ = new CounterMap();
599 // Set up counters
600 if (i::StrLength(i::FLAG_map_counters) != 0)
601 MapCounters(i::FLAG_map_counters);
602 if (i::FLAG_dump_counters) {
603 V8::SetCounterFunction(LookupCounter);
604 V8::SetCreateHistogramFunction(CreateHistogram);
605 V8::SetAddHistogramSampleFunction(AddHistogramSample);
606 }
607
608 // Initialize the global objects
609 HandleScope scope;
610 Handle<ObjectTemplate> global_template = CreateGlobalTemplate();
611
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000612 utility_context_ = Context::New(NULL, global_template);
613 utility_context_->SetSecurityToken(Undefined());
614 Context::Scope utility_scope(utility_context_);
615
ager@chromium.org3bf7b912008-11-17 09:09:45 +0000616 i::JSArguments js_args = i::FLAG_js_arguments;
617 i::Handle<i::FixedArray> arguments_array =
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000618 FACTORY->NewFixedArray(js_args.argc());
ager@chromium.org3bf7b912008-11-17 09:09:45 +0000619 for (int j = 0; j < js_args.argc(); j++) {
620 i::Handle<i::String> arg =
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000621 FACTORY->NewStringFromUtf8(i::CStrVector(js_args[j]));
ager@chromium.org3bf7b912008-11-17 09:09:45 +0000622 arguments_array->set(j, *arg);
623 }
624 i::Handle<i::JSArray> arguments_jsarray =
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000625 FACTORY->NewJSArrayWithElements(arguments_array);
ager@chromium.org3bf7b912008-11-17 09:09:45 +0000626 global_template->Set(String::New("arguments"),
627 Utils::ToLocal(arguments_jsarray));
628
ager@chromium.org65dad4b2009-04-23 08:48:43 +0000629#ifdef ENABLE_DEBUGGER_SUPPORT
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000630 // Install the debugger object in the utility scope
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000631 i::Debug* debug = i::Isolate::Current()->debug();
632 debug->Load();
633 i::Handle<i::JSObject> js_debug
634 = i::Handle<i::JSObject>(debug->debug_context()->global());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000635 utility_context_->Global()->Set(String::New("$debug"),
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000636 Utils::ToLocal(js_debug));
ager@chromium.org65dad4b2009-04-23 08:48:43 +0000637#endif
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000638}
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000639
kasperl@chromium.org7be3c992009-03-12 07:19:55 +0000640
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000641void Shell::RenewEvaluationContext() {
642 // Initialize the global objects
643 HandleScope scope;
644 Handle<ObjectTemplate> global_template = CreateGlobalTemplate();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000645
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000646 // (Re-)create the evaluation context
647 if (!evaluation_context_.IsEmpty()) {
648 evaluation_context_.Dispose();
649 }
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000650 evaluation_context_ = Context::New(NULL, global_template);
651 evaluation_context_->SetSecurityToken(Undefined());
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000652
ager@chromium.org65dad4b2009-04-23 08:48:43 +0000653#ifdef ENABLE_DEBUGGER_SUPPORT
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000654 i::Debug* debug = i::Isolate::Current()->debug();
655 debug->Load();
656
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000657 // Set the security token of the debug context to allow access.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000658 debug->debug_context()->set_security_token(HEAP->undefined_value());
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000659
660 // Start the debugger agent if requested.
661 if (i::FLAG_debugger_agent) {
kmillikin@chromium.org3cdd9e12010-09-06 11:39:48 +0000662 v8::Debug::EnableAgent("d8 shell", i::FLAG_debugger_port, true);
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000663 }
664
665 // Start the in-process debugger if requested.
666 if (i::FLAG_debugger && !i::FLAG_debugger_agent) {
667 v8::Debug::SetDebugEventListener(HandleDebugEvent);
668 }
ager@chromium.org65dad4b2009-04-23 08:48:43 +0000669#endif
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000670}
671
672
673void Shell::OnExit() {
674 if (i::FLAG_dump_counters) {
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000675 ::printf("+----------------------------------------+-------------+\n");
676 ::printf("| Name | Value |\n");
677 ::printf("+----------------------------------------+-------------+\n");
kasperl@chromium.orgf5aa8372009-03-24 14:47:14 +0000678 for (CounterMap::Iterator i(counter_map_); i.More(); i.Next()) {
679 Counter* counter = i.CurrentValue();
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +0000680 if (counter->is_histogram()) {
681 ::printf("| c:%-36s | %11i |\n", i.CurrentKey(), counter->count());
682 ::printf("| t:%-36s | %11i |\n",
683 i.CurrentKey(),
684 counter->sample_total());
685 } else {
686 ::printf("| %-38s | %11i |\n", i.CurrentKey(), counter->count());
687 }
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000688 }
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000689 ::printf("+----------------------------------------+-------------+\n");
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000690 }
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000691 if (counters_file_ != NULL)
692 delete counters_file_;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000693}
694
695
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +0000696static char* ReadChars(const char* name, int* size_out) {
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000697 v8::Unlocker unlocker; // Release the V8 lock while reading files.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000698 FILE* file = i::OS::FOpen(name, "rb");
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000699 if (file == NULL) return NULL;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000700
701 fseek(file, 0, SEEK_END);
702 int size = ftell(file);
703 rewind(file);
704
705 char* chars = new char[size + 1];
706 chars[size] = '\0';
707 for (int i = 0; i < size;) {
708 int read = fread(&chars[i], 1, size - i, file);
709 i += read;
710 }
711 fclose(file);
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000712 *size_out = size;
713 return chars;
714}
715
716
ager@chromium.org381abbb2009-02-25 13:23:22 +0000717static char* ReadToken(char* data, char token) {
718 char* next = i::OS::StrChr(data, token);
719 if (next != NULL) {
720 *next = '\0';
721 return (next + 1);
722 }
723
724 return NULL;
725}
726
727
728static char* ReadLine(char* data) {
729 return ReadToken(data, '\n');
730}
731
732
733static char* ReadWord(char* data) {
734 return ReadToken(data, ' ');
735}
736
737
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000738// Reads a file into a v8 string.
739Handle<String> Shell::ReadFile(const char* name) {
740 int size = 0;
741 char* chars = ReadChars(name, &size);
742 if (chars == NULL) return Handle<String>();
743 Handle<String> result = String::New(chars);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000744 delete[] chars;
745 return result;
746}
747
748
749void Shell::RunShell() {
750 LineEditor* editor = LineEditor::Get();
751 printf("V8 version %s [console: %s]\n", V8::GetVersion(), editor->name());
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +0000752 if (i::FLAG_debugger) {
753 printf("JavaScript debugger enabled\n");
754 }
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000755 editor->Open();
756 while (true) {
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000757 Locker locker;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000758 HandleScope handle_scope;
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000759 Context::Scope context_scope(evaluation_context_);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000760 i::SmartPointer<char> input = editor->Prompt(Shell::kPrompt);
761 if (input.is_empty())
762 break;
763 editor->AddHistory(*input);
764 Handle<String> name = String::New("(d8)");
765 ExecuteString(String::New(*input), name, true, true);
766 }
767 editor->Close();
768 printf("\n");
769}
770
771
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000772class ShellThread : public i::Thread {
773 public:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000774 ShellThread(int no, i::Vector<const char> files)
775 : Thread("d8:ShellThread"),
lrn@chromium.org5d00b602011-01-05 09:51:43 +0000776 no_(no), files_(files) { }
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000777 virtual void Run();
778 private:
779 int no_;
780 i::Vector<const char> files_;
781};
782
783
784void ShellThread::Run() {
785 // Prepare the context for this thread.
786 Locker locker;
787 HandleScope scope;
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000788 Handle<ObjectTemplate> global_template = Shell::CreateGlobalTemplate();
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000789
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000790 char* ptr = const_cast<char*>(files_.start());
791 while ((ptr != NULL) && (*ptr != '\0')) {
792 // For each newline-separated line.
ager@chromium.org381abbb2009-02-25 13:23:22 +0000793 char* next_line = ReadLine(ptr);
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000794
ager@chromium.org381abbb2009-02-25 13:23:22 +0000795 if (*ptr == '#') {
796 // Skip comment lines.
797 ptr = next_line;
798 continue;
799 }
800
801 Persistent<Context> thread_context = Context::New(NULL, global_template);
802 thread_context->SetSecurityToken(Undefined());
803 Context::Scope context_scope(thread_context);
804
805 while ((ptr != NULL) && (*ptr != '\0')) {
806 char* filename = ptr;
807 ptr = ReadWord(ptr);
808
809 // Skip empty strings.
810 if (strlen(filename) == 0) {
811 break;
812 }
813
814 Handle<String> str = Shell::ReadFile(filename);
815 if (str.IsEmpty()) {
816 printf("WARNING: %s not found\n", filename);
817 break;
818 }
819
820 Shell::ExecuteString(str, String::New(filename), false, false);
821 }
822
823 thread_context.Dispose();
824 ptr = next_line;
825 }
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000826}
827
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000828int Shell::RunMain(int argc, char* argv[]) {
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000829 // Default use preemption if threads are created.
830 bool use_preemption = true;
831
832 // Default to use lowest possible thread preemption interval to test as many
833 // edgecases as possible.
834 int preemption_interval = 1;
835
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000836 i::List<i::Thread*> threads(1);
837
838 {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000839 // Since the thread below may spawn new threads accessing V8 holding the
840 // V8 lock here is mandatory.
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000841 Locker locker;
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000842 RenewEvaluationContext();
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000843 Context::Scope context_scope(evaluation_context_);
844 for (int i = 1; i < argc; i++) {
845 char* str = argv[i];
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000846 if (strcmp(str, "--preemption") == 0) {
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000847 use_preemption = true;
848 } else if (strcmp(str, "--no-preemption") == 0) {
849 use_preemption = false;
850 } else if (strcmp(str, "--preemption-interval") == 0) {
851 if (i + 1 < argc) {
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +0000852 char* end = NULL;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000853 preemption_interval = strtol(argv[++i], &end, 10); // NOLINT
854 if (preemption_interval <= 0 || *end != '\0' || errno == ERANGE) {
855 printf("Invalid value for --preemption-interval '%s'\n", argv[i]);
856 return 1;
857 }
858 } else {
859 printf("Missing value for --preemption-interval\n");
860 return 1;
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000861 }
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000862 } else if (strcmp(str, "-f") == 0) {
863 // Ignore any -f flags for compatibility with other stand-alone
864 // JavaScript engines.
865 continue;
866 } else if (strncmp(str, "--", 2) == 0) {
867 printf("Warning: unknown flag %s.\nTry --help for options\n", str);
868 } else if (strcmp(str, "-e") == 0 && i + 1 < argc) {
869 // Execute argument given to -e option directly.
870 v8::HandleScope handle_scope;
871 v8::Handle<v8::String> file_name = v8::String::New("unnamed");
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000872 v8::Handle<v8::String> source = v8::String::New(argv[++i]);
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000873 if (!ExecuteString(source, file_name, false, true)) {
874 OnExit();
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000875 return 1;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000876 }
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000877 } else if (strcmp(str, "-p") == 0 && i + 1 < argc) {
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000878 int size = 0;
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +0000879 const char* files = ReadChars(argv[++i], &size);
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000880 if (files == NULL) return 1;
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +0000881 ShellThread* thread =
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000882 new ShellThread(threads.length(),
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000883 i::Vector<const char>(files, size));
884 thread->Start();
885 threads.Add(thread);
886 } else {
887 // Use all other arguments as names of files to load and run.
888 HandleScope handle_scope;
889 Handle<String> file_name = v8::String::New(str);
890 Handle<String> source = ReadFile(str);
891 if (source.IsEmpty()) {
892 printf("Error reading '%s'\n", str);
893 return 1;
894 }
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000895 if (!ExecuteString(source, file_name, false, true)) {
896 OnExit();
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000897 return 1;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000898 }
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000899 }
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000900 }
kasperl@chromium.org7be3c992009-03-12 07:19:55 +0000901
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000902 // Start preemption if threads have been created and preemption is enabled.
903 if (threads.length() > 0 && use_preemption) {
904 Locker::StartPreemption(preemption_interval);
905 }
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000906 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000907
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000908 for (int i = 0; i < threads.length(); i++) {
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +0000909 i::Thread* thread = threads[i];
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000910 thread->Join();
911 delete thread;
912 }
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000913 OnExit();
914 return 0;
915}
916
917
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000918int Shell::Main(int argc, char* argv[]) {
919 // Figure out if we're requested to stress the optimization
920 // infrastructure by running tests multiple times and forcing
921 // optimization in the last run.
922 bool FLAG_stress_opt = false;
923 bool FLAG_stress_deopt = false;
924 bool run_shell = (argc == 1);
925
926 for (int i = 0; i < argc; i++) {
927 if (strcmp(argv[i], "--stress-opt") == 0) {
928 FLAG_stress_opt = true;
929 argv[i] = NULL;
930 } else if (strcmp(argv[i], "--stress-deopt") == 0) {
931 FLAG_stress_deopt = true;
932 argv[i] = NULL;
933 } else if (strcmp(argv[i], "--noalways-opt") == 0) {
934 // No support for stressing if we can't use --always-opt.
935 FLAG_stress_opt = false;
936 FLAG_stress_deopt = false;
937 } else if (strcmp(argv[i], "--shell") == 0) {
938 run_shell = true;
939 argv[i] = NULL;
940 }
941 }
942
943 v8::V8::SetFlagsFromCommandLine(&argc, argv, true);
944
945 Initialize();
946
947 int result = 0;
948 if (FLAG_stress_opt || FLAG_stress_deopt) {
949 v8::Testing::SetStressRunType(
950 FLAG_stress_opt ? v8::Testing::kStressTypeOpt
951 : v8::Testing::kStressTypeDeopt);
952 int stress_runs = v8::Testing::GetStressRuns();
953 for (int i = 0; i < stress_runs && result == 0; i++) {
954 printf("============ Stress %d/%d ============\n", i + 1, stress_runs);
955 v8::Testing::PrepareStressRun(i);
956 result = RunMain(argc, argv);
957 }
958 printf("======== Full Deoptimization =======\n");
959 v8::Testing::DeoptimizeAll();
960 } else {
961 result = RunMain(argc, argv);
962 }
963
964#ifdef ENABLE_DEBUGGER_SUPPORT
965 if (i::FLAG_remote_debugger) {
966 RunRemoteDebugger(i::FLAG_debugger_port);
967 return 0;
968 }
969#endif
970
971 if (run_shell) {
972 InstallUtilityScript();
973 RunShell();
974 }
975
976 v8::V8::Dispose();
977
978 return result;
979}
980
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000981} // namespace v8
982
983
danno@chromium.org40cb8782011-05-25 07:58:50 +0000984#ifndef GOOGLE3
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000985int main(int argc, char* argv[]) {
986 return v8::Shell::Main(argc, argv);
987}
danno@chromium.org40cb8782011-05-25 07:58:50 +0000988#endif