v8  3.14.5(node0.10.28)
V8 is Google's open source JavaScript engine
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
d8.cc
Go to the documentation of this file.
1 // Copyright 2012 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 
29 // Defined when linking against shared lib on Windows.
30 #if defined(USING_V8_SHARED) && !defined(V8_SHARED)
31 #define V8_SHARED
32 #endif
33 
34 #ifdef COMPRESS_STARTUP_DATA_BZ2
35 #include <bzlib.h>
36 #endif
37 
38 #include <errno.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include <sys/stat.h>
42 
43 #ifdef V8_SHARED
44 #include <assert.h>
45 #include "../include/v8-testing.h"
46 #endif // V8_SHARED
47 
48 #include "d8.h"
49 
50 #ifndef V8_SHARED
51 #include "api.h"
52 #include "checks.h"
53 #include "d8-debug.h"
54 #include "debug.h"
55 #include "natives.h"
56 #include "platform.h"
57 #include "v8.h"
58 #endif // V8_SHARED
59 
60 #if !defined(_WIN32) && !defined(_WIN64)
61 #include <unistd.h> // NOLINT
62 #endif
63 
64 #ifndef ASSERT
65 #define ASSERT(condition) assert(condition)
66 #endif
67 
68 namespace v8 {
69 
70 LineEditor *LineEditor::first_ = NULL;
71 
72 
73 LineEditor::LineEditor(Type type, const char* name)
74  : type_(type),
75  name_(name),
76  next_(first_) {
77  first_ = this;
78 }
79 
80 
82  LineEditor* current = first_;
83  LineEditor* best = current;
84  while (current != NULL) {
85  if (current->type_ > best->type_)
86  best = current;
87  current = current->next_;
88  }
89  return best;
90 }
91 
92 
93 class DumbLineEditor: public LineEditor {
94  public:
96  virtual Handle<String> Prompt(const char* prompt);
97 };
98 
99 
100 static DumbLineEditor dumb_line_editor;
101 
102 
104  printf("%s", prompt);
105  return Shell::ReadFromStdin();
106 }
107 
108 
109 #ifndef V8_SHARED
110 CounterMap* Shell::counter_map_;
111 i::OS::MemoryMappedFile* Shell::counters_file_ = NULL;
112 CounterCollection Shell::local_counters_;
113 CounterCollection* Shell::counters_ = &local_counters_;
114 i::Mutex* Shell::context_mutex_(i::OS::CreateMutex());
115 Persistent<Context> Shell::utility_context_;
116 #endif // V8_SHARED
117 
119 Persistent<Context> Shell::evaluation_context_;
121 const char* Shell::kPrompt = "d8> ";
122 
123 
124 const int MB = 1024 * 1024;
125 
126 
127 #ifndef V8_SHARED
128 bool CounterMap::Match(void* key1, void* key2) {
129  const char* name1 = reinterpret_cast<const char*>(key1);
130  const char* name2 = reinterpret_cast<const char*>(key2);
131  return strcmp(name1, name2) == 0;
132 }
133 #endif // V8_SHARED
134 
135 
136 // Converts a V8 value to a C string.
137 const char* Shell::ToCString(const v8::String::Utf8Value& value) {
138  return *value ? *value : "<string conversion failed>";
139 }
140 
141 
142 // Executes a string within the current v8 context.
144  Handle<Value> name,
145  bool print_result,
146  bool report_exceptions) {
147 #if !defined(V8_SHARED) && defined(ENABLE_DEBUGGER_SUPPORT)
148  bool FLAG_debugger = i::FLAG_debugger;
149 #else
150  bool FLAG_debugger = false;
151 #endif // !V8_SHARED && ENABLE_DEBUGGER_SUPPORT
152  HandleScope handle_scope;
153  TryCatch try_catch;
154  options.script_executed = true;
155  if (FLAG_debugger) {
156  // When debugging make exceptions appear to be uncaught.
157  try_catch.SetVerbose(true);
158  }
159  Handle<Script> script = Script::Compile(source, name);
160  if (script.IsEmpty()) {
161  // Print errors that happened during compilation.
162  if (report_exceptions && !FLAG_debugger)
163  ReportException(&try_catch);
164  return false;
165  } else {
166  Handle<Value> result = script->Run();
167  if (result.IsEmpty()) {
168  ASSERT(try_catch.HasCaught());
169  // Print errors that happened during execution.
170  if (report_exceptions && !FLAG_debugger)
171  ReportException(&try_catch);
172  return false;
173  } else {
174  ASSERT(!try_catch.HasCaught());
175  if (print_result && !result->IsUndefined()) {
176  // If all went well and the result wasn't undefined then print
177  // the returned value.
178  v8::String::Utf8Value str(result);
179  size_t count = fwrite(*str, sizeof(**str), str.length(), stdout);
180  (void) count; // Silence GCC-4.5.x "unused result" warning.
181  printf("\n");
182  }
183  return true;
184  }
185  }
186 }
187 
188 
190  Handle<Value> val = Write(args);
191  printf("\n");
192  fflush(stdout);
193  return val;
194 }
195 
196 
198  for (int i = 0; i < args.Length(); i++) {
199  HandleScope handle_scope;
200  if (i != 0) {
201  printf(" ");
202  }
203 
204  // Explicitly catch potential exceptions in toString().
205  v8::TryCatch try_catch;
206  Handle<String> str_obj = args[i]->ToString();
207  if (try_catch.HasCaught()) return try_catch.ReThrow();
208 
209  v8::String::Utf8Value str(str_obj);
210  int n = static_cast<int>(fwrite(*str, sizeof(**str), str.length(), stdout));
211  if (n != str.length()) {
212  printf("Error in fwrite\n");
213  Exit(1);
214  }
215  }
216  return Undefined();
217 }
218 
219 
222  return Undefined();
223 }
224 
225 
228  return Undefined();
229 }
230 
231 
233  String::Utf8Value file(args[0]);
234  if (*file == NULL) {
235  return ThrowException(String::New("Error loading file"));
236  }
237  Handle<String> source = ReadFile(*file);
238  if (source.IsEmpty()) {
239  return ThrowException(String::New("Error loading file"));
240  }
241  return source;
242 }
243 
244 
246  static const int kBufferSize = 256;
247  char buffer[kBufferSize];
248  Handle<String> accumulator = String::New("");
249  int length;
250  while (true) {
251  // Continue reading if the line ends with an escape '\\' or the line has
252  // not been fully read into the buffer yet (does not end with '\n').
253  // If fgets gets an error, just give up.
254  char* input = NULL;
255  { // Release lock for blocking input.
256  Unlocker unlock(Isolate::GetCurrent());
257  input = fgets(buffer, kBufferSize, stdin);
258  }
259  if (input == NULL) return Handle<String>();
260  length = static_cast<int>(strlen(buffer));
261  if (length == 0) {
262  return accumulator;
263  } else if (buffer[length-1] != '\n') {
264  accumulator = String::Concat(accumulator, String::New(buffer, length));
265  } else if (length > 1 && buffer[length-2] == '\\') {
266  buffer[length-2] = '\n';
267  accumulator = String::Concat(accumulator, String::New(buffer, length-1));
268  } else {
269  return String::Concat(accumulator, String::New(buffer, length-1));
270  }
271  }
272 }
273 
274 
276  for (int i = 0; i < args.Length(); i++) {
277  HandleScope handle_scope;
278  String::Utf8Value file(args[i]);
279  if (*file == NULL) {
280  return ThrowException(String::New("Error loading file"));
281  }
282  Handle<String> source = ReadFile(*file);
283  if (source.IsEmpty()) {
284  return ThrowException(String::New("Error loading file"));
285  }
286  if (!ExecuteString(source, String::New(*file), false, true)) {
287  return ThrowException(String::New("Error executing file"));
288  }
289  }
290  return Undefined();
291 }
292 
293 static int32_t convertToInt(Local<Value> value_in, TryCatch* try_catch) {
294  if (value_in->IsInt32()) {
295  return value_in->Int32Value();
296  }
297 
298  Local<Value> number = value_in->ToNumber();
299  if (try_catch->HasCaught()) return 0;
300 
301  ASSERT(number->IsNumber());
302  Local<Int32> int32 = number->ToInt32();
303  if (try_catch->HasCaught() || int32.IsEmpty()) return 0;
304 
305  int32_t value = int32->Int32Value();
306  if (try_catch->HasCaught()) return 0;
307 
308  return value;
309 }
310 
311 
312 static int32_t convertToUint(Local<Value> value_in, TryCatch* try_catch) {
313  int32_t raw_value = convertToInt(value_in, try_catch);
314  if (try_catch->HasCaught()) return 0;
315 
316  if (raw_value < 0) {
317  ThrowException(String::New("Array length must not be negative."));
318  return 0;
319  }
320 
321  static const int kMaxLength = 0x3fffffff;
322 #ifndef V8_SHARED
323  ASSERT(kMaxLength == i::ExternalArray::kMaxLength);
324 #endif // V8_SHARED
325  if (raw_value > static_cast<int32_t>(kMaxLength)) {
327  String::New("Array length exceeds maximum length."));
328  }
329  return raw_value;
330 }
331 
332 
333 // TODO(rossberg): should replace these by proper uses of HasInstance,
334 // once we figure out a good way to make the templates global.
335 const char kArrayBufferMarkerPropName[] = "d8::_is_array_buffer_";
336 const char kArrayMarkerPropName[] = "d8::_is_typed_array_";
337 
338 
339 Handle<Value> Shell::CreateExternalArrayBuffer(Handle<Object> buffer,
340  int32_t length) {
341  static const int32_t kMaxSize = 0x7fffffff;
342  // Make sure the total size fits into a (signed) int.
343  if (length < 0 || length > kMaxSize) {
344  return ThrowException(String::New("ArrayBuffer exceeds maximum size (2G)"));
345  }
346  uint8_t* data = new uint8_t[length];
347  if (data == NULL) {
348  return ThrowException(String::New("Memory allocation failed"));
349  }
350  memset(data, 0, length);
351 
352  buffer->SetHiddenValue(String::New(kArrayBufferMarkerPropName), True());
353  Persistent<Object> persistent_array = Persistent<Object>::New(buffer);
354  persistent_array.MakeWeak(data, ExternalArrayWeakCallback);
355  persistent_array.MarkIndependent();
357 
358  buffer->SetIndexedPropertiesToExternalArrayData(
359  data, v8::kExternalByteArray, length);
360  buffer->Set(String::New("byteLength"), Int32::New(length), ReadOnly);
361 
362  return buffer;
363 }
364 
365 
367  if (!args.IsConstructCall()) {
368  Handle<Value>* rec_args = new Handle<Value>[args.Length()];
369  for (int i = 0; i < args.Length(); ++i) rec_args[i] = args[i];
370  Handle<Value> result = args.Callee()->NewInstance(args.Length(), rec_args);
371  delete[] rec_args;
372  return result;
373  }
374 
375  if (args.Length() == 0) {
376  return ThrowException(
377  String::New("ArrayBuffer constructor must have one argument"));
378  }
379  TryCatch try_catch;
380  int32_t length = convertToUint(args[0], &try_catch);
381  if (try_catch.HasCaught()) return try_catch.ReThrow();
382 
383  return CreateExternalArrayBuffer(args.This(), length);
384 }
385 
386 
387 Handle<Object> Shell::CreateExternalArray(Handle<Object> array,
388  Handle<Object> buffer,
389  ExternalArrayType type,
390  int32_t length,
391  int32_t byteLength,
392  int32_t byteOffset,
393  int32_t element_size) {
394  ASSERT(element_size == 1 || element_size == 2 ||
395  element_size == 4 || element_size == 8);
396  ASSERT(byteLength == length * element_size);
397 
398  void* data = buffer->GetIndexedPropertiesExternalArrayData();
399  ASSERT(data != NULL);
400 
401  array->SetIndexedPropertiesToExternalArrayData(
402  static_cast<uint8_t*>(data) + byteOffset, type, length);
403  array->SetHiddenValue(String::New(kArrayMarkerPropName), Int32::New(type));
404  array->Set(String::New("byteLength"), Int32::New(byteLength), ReadOnly);
405  array->Set(String::New("byteOffset"), Int32::New(byteOffset), ReadOnly);
406  array->Set(String::New("length"), Int32::New(length), ReadOnly);
407  array->Set(String::New("BYTES_PER_ELEMENT"), Int32::New(element_size));
408  array->Set(String::New("buffer"), buffer, ReadOnly);
409 
410  return array;
411 }
412 
413 
414 Handle<Value> Shell::CreateExternalArray(const Arguments& args,
415  ExternalArrayType type,
416  int32_t element_size) {
417  if (!args.IsConstructCall()) {
418  Handle<Value>* rec_args = new Handle<Value>[args.Length()];
419  for (int i = 0; i < args.Length(); ++i) rec_args[i] = args[i];
420  Handle<Value> result = args.Callee()->NewInstance(args.Length(), rec_args);
421  delete[] rec_args;
422  return result;
423  }
424 
425  TryCatch try_catch;
426  ASSERT(element_size == 1 || element_size == 2 ||
427  element_size == 4 || element_size == 8);
428 
429  // All of the following constructors are supported:
430  // TypedArray(unsigned long length)
431  // TypedArray(type[] array)
432  // TypedArray(TypedArray array)
433  // TypedArray(ArrayBuffer buffer,
434  // optional unsigned long byteOffset,
435  // optional unsigned long length)
436  Handle<Object> buffer;
437  int32_t length;
438  int32_t byteLength;
439  int32_t byteOffset;
440  bool init_from_array = false;
441  if (args.Length() == 0) {
442  return ThrowException(
443  String::New("Array constructor must have at least one argument"));
444  }
445  if (args[0]->IsObject() &&
446  !args[0]->ToObject()->GetHiddenValue(
448  // Construct from ArrayBuffer.
449  buffer = args[0]->ToObject();
450  int32_t bufferLength =
451  convertToUint(buffer->Get(String::New("byteLength")), &try_catch);
452  if (try_catch.HasCaught()) return try_catch.ReThrow();
453 
454  if (args.Length() < 2 || args[1]->IsUndefined()) {
455  byteOffset = 0;
456  } else {
457  byteOffset = convertToUint(args[1], &try_catch);
458  if (try_catch.HasCaught()) return try_catch.ReThrow();
459  if (byteOffset > bufferLength) {
460  return ThrowException(String::New("byteOffset out of bounds"));
461  }
462  if (byteOffset % element_size != 0) {
463  return ThrowException(
464  String::New("byteOffset must be multiple of element size"));
465  }
466  }
467 
468  if (args.Length() < 3 || args[2]->IsUndefined()) {
469  byteLength = bufferLength - byteOffset;
470  length = byteLength / element_size;
471  if (byteLength % element_size != 0) {
472  return ThrowException(
473  String::New("buffer size must be multiple of element size"));
474  }
475  } else {
476  length = convertToUint(args[2], &try_catch);
477  if (try_catch.HasCaught()) return try_catch.ReThrow();
478  byteLength = length * element_size;
479  if (byteOffset + byteLength > bufferLength) {
480  return ThrowException(String::New("length out of bounds"));
481  }
482  }
483  } else {
484  if (args[0]->IsObject() &&
485  args[0]->ToObject()->Has(String::New("length"))) {
486  // Construct from array.
487  length = convertToUint(
488  args[0]->ToObject()->Get(String::New("length")), &try_catch);
489  if (try_catch.HasCaught()) return try_catch.ReThrow();
490  init_from_array = true;
491  } else {
492  // Construct from size.
493  length = convertToUint(args[0], &try_catch);
494  if (try_catch.HasCaught()) return try_catch.ReThrow();
495  }
496  byteLength = length * element_size;
497  byteOffset = 0;
498 
499  Handle<Object> global = Context::GetCurrent()->Global();
500  Handle<Value> array_buffer = global->Get(String::New("ArrayBuffer"));
501  ASSERT(!try_catch.HasCaught() && array_buffer->IsFunction());
502  Handle<Value> buffer_args[] = { Uint32::New(byteLength) };
503  Handle<Value> result = Handle<Function>::Cast(array_buffer)->NewInstance(
504  1, buffer_args);
505  if (try_catch.HasCaught()) return result;
506  buffer = result->ToObject();
507  }
508 
509  Handle<Object> array = CreateExternalArray(
510  args.This(), buffer, type, length, byteLength, byteOffset, element_size);
511 
512  if (init_from_array) {
513  Handle<Object> init = args[0]->ToObject();
514  for (int i = 0; i < length; ++i) array->Set(i, init->Get(i));
515  }
516 
517  return array;
518 }
519 
520 
522  TryCatch try_catch;
523 
524  if (!args.This()->IsObject()) {
525  return ThrowException(
526  String::New("'slice' invoked on non-object receiver"));
527  }
528 
529  Local<Object> self = args.This();
530  Local<Value> marker =
531  self->GetHiddenValue(String::New(kArrayBufferMarkerPropName));
532  if (marker.IsEmpty()) {
533  return ThrowException(
534  String::New("'slice' invoked on wrong receiver type"));
535  }
536 
537  int32_t length =
538  convertToUint(self->Get(String::New("byteLength")), &try_catch);
539  if (try_catch.HasCaught()) return try_catch.ReThrow();
540 
541  if (args.Length() == 0) {
542  return ThrowException(
543  String::New("'slice' must have at least one argument"));
544  }
545  int32_t begin = convertToInt(args[0], &try_catch);
546  if (try_catch.HasCaught()) return try_catch.ReThrow();
547  if (begin < 0) begin += length;
548  if (begin < 0) begin = 0;
549  if (begin > length) begin = length;
550 
551  int32_t end;
552  if (args.Length() < 2 || args[1]->IsUndefined()) {
553  end = length;
554  } else {
555  end = convertToInt(args[1], &try_catch);
556  if (try_catch.HasCaught()) return try_catch.ReThrow();
557  if (end < 0) end += length;
558  if (end < 0) end = 0;
559  if (end > length) end = length;
560  if (end < begin) end = begin;
561  }
562 
563  Local<Function> constructor = Local<Function>::Cast(self->GetConstructor());
564  Handle<Value> new_args[] = { Uint32::New(end - begin) };
565  Handle<Value> result = constructor->NewInstance(1, new_args);
566  if (try_catch.HasCaught()) return result;
567  Handle<Object> buffer = result->ToObject();
568  uint8_t* dest =
569  static_cast<uint8_t*>(buffer->GetIndexedPropertiesExternalArrayData());
570  uint8_t* src = begin + static_cast<uint8_t*>(
571  self->GetIndexedPropertiesExternalArrayData());
572  memcpy(dest, src, end - begin);
573 
574  return buffer;
575 }
576 
577 
579  TryCatch try_catch;
580 
581  if (!args.This()->IsObject()) {
582  return ThrowException(
583  String::New("'subarray' invoked on non-object receiver"));
584  }
585 
586  Local<Object> self = args.This();
587  Local<Value> marker = self->GetHiddenValue(String::New(kArrayMarkerPropName));
588  if (marker.IsEmpty()) {
589  return ThrowException(
590  String::New("'subarray' invoked on wrong receiver type"));
591  }
592 
593  Handle<Object> buffer = self->Get(String::New("buffer"))->ToObject();
594  if (try_catch.HasCaught()) return try_catch.ReThrow();
595  int32_t length =
596  convertToUint(self->Get(String::New("length")), &try_catch);
597  if (try_catch.HasCaught()) return try_catch.ReThrow();
598  int32_t byteOffset =
599  convertToUint(self->Get(String::New("byteOffset")), &try_catch);
600  if (try_catch.HasCaught()) return try_catch.ReThrow();
601  int32_t element_size =
602  convertToUint(self->Get(String::New("BYTES_PER_ELEMENT")), &try_catch);
603  if (try_catch.HasCaught()) return try_catch.ReThrow();
604 
605  if (args.Length() == 0) {
606  return ThrowException(
607  String::New("'subarray' must have at least one argument"));
608  }
609  int32_t begin = convertToInt(args[0], &try_catch);
610  if (try_catch.HasCaught()) return try_catch.ReThrow();
611  if (begin < 0) begin += length;
612  if (begin < 0) begin = 0;
613  if (begin > length) begin = length;
614 
615  int32_t end;
616  if (args.Length() < 2 || args[1]->IsUndefined()) {
617  end = length;
618  } else {
619  end = convertToInt(args[1], &try_catch);
620  if (try_catch.HasCaught()) return try_catch.ReThrow();
621  if (end < 0) end += length;
622  if (end < 0) end = 0;
623  if (end > length) end = length;
624  if (end < begin) end = begin;
625  }
626 
627  length = end - begin;
628  byteOffset += begin * element_size;
629 
630  Local<Function> constructor = Local<Function>::Cast(self->GetConstructor());
631  Handle<Value> construct_args[] = {
632  buffer, Uint32::New(byteOffset), Uint32::New(length)
633  };
634  return constructor->NewInstance(3, construct_args);
635 }
636 
637 
639  TryCatch try_catch;
640 
641  if (!args.This()->IsObject()) {
642  return ThrowException(
643  String::New("'set' invoked on non-object receiver"));
644  }
645 
646  Local<Object> self = args.This();
647  Local<Value> marker = self->GetHiddenValue(String::New(kArrayMarkerPropName));
648  if (marker.IsEmpty()) {
649  return ThrowException(
650  String::New("'set' invoked on wrong receiver type"));
651  }
652  int32_t length =
653  convertToUint(self->Get(String::New("length")), &try_catch);
654  if (try_catch.HasCaught()) return try_catch.ReThrow();
655  int32_t element_size =
656  convertToUint(self->Get(String::New("BYTES_PER_ELEMENT")), &try_catch);
657  if (try_catch.HasCaught()) return try_catch.ReThrow();
658 
659  if (args.Length() == 0) {
660  return ThrowException(
661  String::New("'set' must have at least one argument"));
662  }
663  if (!args[0]->IsObject() ||
664  !args[0]->ToObject()->Has(String::New("length"))) {
665  return ThrowException(
666  String::New("'set' invoked with non-array argument"));
667  }
668  Handle<Object> source = args[0]->ToObject();
669  int32_t source_length =
670  convertToUint(source->Get(String::New("length")), &try_catch);
671  if (try_catch.HasCaught()) return try_catch.ReThrow();
672 
673  int32_t offset;
674  if (args.Length() < 2 || args[1]->IsUndefined()) {
675  offset = 0;
676  } else {
677  offset = convertToUint(args[1], &try_catch);
678  if (try_catch.HasCaught()) return try_catch.ReThrow();
679  }
680  if (offset + source_length > length) {
681  return ThrowException(String::New("offset or source length out of bounds"));
682  }
683 
684  int32_t source_element_size;
685  if (source->GetHiddenValue(String::New(kArrayMarkerPropName)).IsEmpty()) {
686  source_element_size = 0;
687  } else {
688  source_element_size =
689  convertToUint(source->Get(String::New("BYTES_PER_ELEMENT")), &try_catch);
690  if (try_catch.HasCaught()) return try_catch.ReThrow();
691  }
692 
693  if (element_size == source_element_size &&
694  self->GetConstructor()->StrictEquals(source->GetConstructor())) {
695  // Use memmove on the array buffers.
696  Handle<Object> buffer = self->Get(String::New("buffer"))->ToObject();
697  if (try_catch.HasCaught()) return try_catch.ReThrow();
698  Handle<Object> source_buffer =
699  source->Get(String::New("buffer"))->ToObject();
700  if (try_catch.HasCaught()) return try_catch.ReThrow();
701  int32_t byteOffset =
702  convertToUint(self->Get(String::New("byteOffset")), &try_catch);
703  if (try_catch.HasCaught()) return try_catch.ReThrow();
704  int32_t source_byteOffset =
705  convertToUint(source->Get(String::New("byteOffset")), &try_catch);
706  if (try_catch.HasCaught()) return try_catch.ReThrow();
707 
708  uint8_t* dest = byteOffset + offset * element_size + static_cast<uint8_t*>(
709  buffer->GetIndexedPropertiesExternalArrayData());
710  uint8_t* src = source_byteOffset + static_cast<uint8_t*>(
711  source_buffer->GetIndexedPropertiesExternalArrayData());
712  memmove(dest, src, source_length * element_size);
713  } else if (source_element_size == 0) {
714  // Source is not a typed array, copy element-wise sequentially.
715  for (int i = 0; i < source_length; ++i) {
716  self->Set(offset + i, source->Get(i));
717  if (try_catch.HasCaught()) return try_catch.ReThrow();
718  }
719  } else {
720  // Need to copy element-wise to make the right conversions.
721  Handle<Object> buffer = self->Get(String::New("buffer"))->ToObject();
722  if (try_catch.HasCaught()) return try_catch.ReThrow();
723  Handle<Object> source_buffer =
724  source->Get(String::New("buffer"))->ToObject();
725  if (try_catch.HasCaught()) return try_catch.ReThrow();
726 
727  if (buffer->StrictEquals(source_buffer)) {
728  // Same backing store, need to handle overlap correctly.
729  // This gets a bit tricky in the case of different element sizes
730  // (which, of course, is extremely unlikely to ever occur in practice).
731  int32_t byteOffset =
732  convertToUint(self->Get(String::New("byteOffset")), &try_catch);
733  if (try_catch.HasCaught()) return try_catch.ReThrow();
734  int32_t source_byteOffset =
735  convertToUint(source->Get(String::New("byteOffset")), &try_catch);
736  if (try_catch.HasCaught()) return try_catch.ReThrow();
737 
738  // Copy as much as we can from left to right.
739  int i = 0;
740  int32_t next_dest_offset = byteOffset + (offset + 1) * element_size;
741  int32_t next_src_offset = source_byteOffset + source_element_size;
742  while (i < length && next_dest_offset <= next_src_offset) {
743  self->Set(offset + i, source->Get(i));
744  ++i;
745  next_dest_offset += element_size;
746  next_src_offset += source_element_size;
747  }
748  // Of what's left, copy as much as we can from right to left.
749  int j = length - 1;
750  int32_t dest_offset = byteOffset + (offset + j) * element_size;
751  int32_t src_offset = source_byteOffset + j * source_element_size;
752  while (j >= i && dest_offset >= src_offset) {
753  self->Set(offset + j, source->Get(j));
754  --j;
755  dest_offset -= element_size;
756  src_offset -= source_element_size;
757  }
758  // There can be at most 8 entries left in the middle that need buffering
759  // (because the largest element_size is 8 times the smallest).
760  ASSERT(j+1 - i <= 8);
761  Handle<Value> temp[8];
762  for (int k = i; k <= j; ++k) {
763  temp[k - i] = source->Get(k);
764  }
765  for (int k = i; k <= j; ++k) {
766  self->Set(offset + k, temp[k - i]);
767  }
768  } else {
769  // Different backing stores, safe to copy element-wise sequentially.
770  for (int i = 0; i < source_length; ++i)
771  self->Set(offset + i, source->Get(i));
772  }
773  }
774 
775  return Undefined();
776 }
777 
778 
779 void Shell::ExternalArrayWeakCallback(Persistent<Value> object, void* data) {
780  HandleScope scope;
781  int32_t length =
782  object->ToObject()->Get(String::New("byteLength"))->Uint32Value();
784  delete[] static_cast<uint8_t*>(data);
785  object.Dispose();
786 }
787 
788 
790  return CreateExternalArray(args, v8::kExternalByteArray, sizeof(int8_t));
791 }
792 
793 
795  return CreateExternalArray(args, kExternalUnsignedByteArray, sizeof(uint8_t));
796 }
797 
798 
800  return CreateExternalArray(args, kExternalShortArray, sizeof(int16_t));
801 }
802 
803 
805  return CreateExternalArray(
806  args, kExternalUnsignedShortArray, sizeof(uint16_t));
807 }
808 
809 
811  return CreateExternalArray(args, kExternalIntArray, sizeof(int32_t));
812 }
813 
814 
816  return CreateExternalArray(args, kExternalUnsignedIntArray, sizeof(uint32_t));
817 }
818 
819 
821  return CreateExternalArray(
822  args, kExternalFloatArray, sizeof(float)); // NOLINT
823 }
824 
825 
827  return CreateExternalArray(
828  args, kExternalDoubleArray, sizeof(double)); // NOLINT
829 }
830 
831 
833  return CreateExternalArray(args, kExternalPixelArray, sizeof(uint8_t));
834 }
835 
836 
838  v8::Unlocker unlocker;
839  return Undefined();
840 }
841 
842 
844  int exit_code = args[0]->Int32Value();
845 #ifndef V8_SHARED
846  OnExit();
847 #endif // V8_SHARED
848  exit(exit_code);
849  return Undefined();
850 }
851 
852 
854  return String::New(V8::GetVersion());
855 }
856 
857 
859  HandleScope handle_scope;
860 #if !defined(V8_SHARED) && defined(ENABLE_DEBUGGER_SUPPORT)
861  bool enter_context = !Context::InContext();
862  if (enter_context) utility_context_->Enter();
863 #endif // !V8_SHARED && ENABLE_DEBUGGER_SUPPORT
864  v8::String::Utf8Value exception(try_catch->Exception());
865  const char* exception_string = ToCString(exception);
866  Handle<Message> message = try_catch->Message();
867  if (message.IsEmpty()) {
868  // V8 didn't provide any extra information about this error; just
869  // print the exception.
870  printf("%s\n", exception_string);
871  } else {
872  // Print (filename):(line number): (message).
873  v8::String::Utf8Value filename(message->GetScriptResourceName());
874  const char* filename_string = ToCString(filename);
875  int linenum = message->GetLineNumber();
876  printf("%s:%i: %s\n", filename_string, linenum, exception_string);
877  // Print line of source code.
878  v8::String::Utf8Value sourceline(message->GetSourceLine());
879  const char* sourceline_string = ToCString(sourceline);
880  printf("%s\n", sourceline_string);
881  // Print wavy underline (GetUnderline is deprecated).
882  int start = message->GetStartColumn();
883  for (int i = 0; i < start; i++) {
884  printf(" ");
885  }
886  int end = message->GetEndColumn();
887  for (int i = start; i < end; i++) {
888  printf("^");
889  }
890  printf("\n");
891  v8::String::Utf8Value stack_trace(try_catch->StackTrace());
892  if (stack_trace.length() > 0) {
893  const char* stack_trace_string = ToCString(stack_trace);
894  printf("%s\n", stack_trace_string);
895  }
896  }
897  printf("\n");
898 #if !defined(V8_SHARED) && defined(ENABLE_DEBUGGER_SUPPORT)
899  if (enter_context) utility_context_->Exit();
900 #endif // !V8_SHARED && ENABLE_DEBUGGER_SUPPORT
901 }
902 
903 
904 #ifndef V8_SHARED
906  HandleScope handle_scope;
907  Context::Scope context_scope(utility_context_);
908  Handle<Object> global = utility_context_->Global();
909  Handle<Value> fun = global->Get(String::New("GetCompletions"));
910  static const int kArgc = 3;
911  Handle<Value> argv[kArgc] = { evaluation_context_->Global(), text, full };
912  Handle<Value> val = Handle<Function>::Cast(fun)->Call(global, kArgc, argv);
913  return handle_scope.Close(Handle<Array>::Cast(val));
914 }
915 
916 
917 #ifdef ENABLE_DEBUGGER_SUPPORT
918 Handle<Object> Shell::DebugMessageDetails(Handle<String> message) {
919  Context::Scope context_scope(utility_context_);
920  Handle<Object> global = utility_context_->Global();
921  Handle<Value> fun = global->Get(String::New("DebugMessageDetails"));
922  static const int kArgc = 1;
923  Handle<Value> argv[kArgc] = { message };
924  Handle<Value> val = Handle<Function>::Cast(fun)->Call(global, kArgc, argv);
925  return Handle<Object>::Cast(val);
926 }
927 
928 
929 Handle<Value> Shell::DebugCommandToJSONRequest(Handle<String> command) {
930  Context::Scope context_scope(utility_context_);
931  Handle<Object> global = utility_context_->Global();
932  Handle<Value> fun = global->Get(String::New("DebugCommandToJSONRequest"));
933  static const int kArgc = 1;
934  Handle<Value> argv[kArgc] = { command };
935  Handle<Value> val = Handle<Function>::Cast(fun)->Call(global, kArgc, argv);
936  return val;
937 }
938 
939 
940 void Shell::DispatchDebugMessages() {
941  v8::Context::Scope scope(Shell::evaluation_context_);
943 }
944 #endif // ENABLE_DEBUGGER_SUPPORT
945 #endif // V8_SHARED
946 
947 
948 #ifndef V8_SHARED
949 int32_t* Counter::Bind(const char* name, bool is_histogram) {
950  int i;
951  for (i = 0; i < kMaxNameSize - 1 && name[i]; i++)
952  name_[i] = static_cast<char>(name[i]);
953  name_[i] = '\0';
954  is_histogram_ = is_histogram;
955  return ptr();
956 }
957 
958 
960  count_++;
961  sample_total_ += sample;
962 }
963 
964 
966  magic_number_ = 0xDEADFACE;
967  max_counters_ = kMaxCounters;
968  max_name_size_ = Counter::kMaxNameSize;
969  counters_in_use_ = 0;
970 }
971 
972 
974  if (counters_in_use_ == kMaxCounters) return NULL;
975  return &counters_[counters_in_use_++];
976 }
977 
978 
979 void Shell::MapCounters(const char* name) {
980  counters_file_ = i::OS::MemoryMappedFile::create(
981  name, sizeof(CounterCollection), &local_counters_);
982  void* memory = (counters_file_ == NULL) ?
983  NULL : counters_file_->memory();
984  if (memory == NULL) {
985  printf("Could not map counters file %s\n", name);
986  Exit(1);
987  }
988  counters_ = static_cast<CounterCollection*>(memory);
992 }
993 
994 
995 int CounterMap::Hash(const char* name) {
996  int h = 0;
997  int c;
998  while ((c = *name++) != 0) {
999  h += h << 5;
1000  h += c;
1001  }
1002  return h;
1003 }
1004 
1005 
1006 Counter* Shell::GetCounter(const char* name, bool is_histogram) {
1007  Counter* counter = counter_map_->Lookup(name);
1008 
1009  if (counter == NULL) {
1010  counter = counters_->GetNextCounter();
1011  if (counter != NULL) {
1012  counter_map_->Set(name, counter);
1013  counter->Bind(name, is_histogram);
1014  }
1015  } else {
1016  ASSERT(counter->is_histogram() == is_histogram);
1017  }
1018  return counter;
1019 }
1020 
1021 
1022 int* Shell::LookupCounter(const char* name) {
1023  Counter* counter = GetCounter(name, false);
1024 
1025  if (counter != NULL) {
1026  return counter->ptr();
1027  } else {
1028  return NULL;
1029  }
1030 }
1031 
1032 
1033 void* Shell::CreateHistogram(const char* name,
1034  int min,
1035  int max,
1036  size_t buckets) {
1037  return GetCounter(name, true);
1038 }
1039 
1040 
1041 void Shell::AddHistogramSample(void* histogram, int sample) {
1042  Counter* counter = reinterpret_cast<Counter*>(histogram);
1043  counter->AddSample(sample);
1044 }
1045 
1046 
1047 void Shell::InstallUtilityScript() {
1048  Locker lock;
1049  HandleScope scope;
1050  // If we use the utility context, we have to set the security tokens so that
1051  // utility, evaluation and debug context can all access each other.
1052  utility_context_->SetSecurityToken(Undefined());
1053  evaluation_context_->SetSecurityToken(Undefined());
1054  Context::Scope utility_scope(utility_context_);
1055 
1056 #ifdef ENABLE_DEBUGGER_SUPPORT
1057  if (i::FLAG_debugger) printf("JavaScript debugger enabled\n");
1058  // Install the debugger object in the utility scope
1059  i::Debug* debug = i::Isolate::Current()->debug();
1060  debug->Load();
1061  i::Handle<i::JSObject> js_debug
1062  = i::Handle<i::JSObject>(debug->debug_context()->global_object());
1063  utility_context_->Global()->Set(String::New("$debug"),
1064  Utils::ToLocal(js_debug));
1065  debug->debug_context()->set_security_token(HEAP->undefined_value());
1066 #endif // ENABLE_DEBUGGER_SUPPORT
1067 
1068  // Run the d8 shell utility script in the utility context
1069  int source_index = i::NativesCollection<i::D8>::GetIndex("d8");
1070  i::Vector<const char> shell_source =
1072  i::Vector<const char> shell_source_name =
1074  Handle<String> source = String::New(shell_source.start(),
1075  shell_source.length());
1076  Handle<String> name = String::New(shell_source_name.start(),
1077  shell_source_name.length());
1078  Handle<Script> script = Script::Compile(source, name);
1079  script->Run();
1080  // Mark the d8 shell script as native to avoid it showing up as normal source
1081  // in the debugger.
1082  i::Handle<i::Object> compiled_script = Utils::OpenHandle(*script);
1083  i::Handle<i::Script> script_object = compiled_script->IsJSFunction()
1085  i::JSFunction::cast(*compiled_script)->shared()->script()))
1086  : i::Handle<i::Script>(i::Script::cast(
1087  i::SharedFunctionInfo::cast(*compiled_script)->script()));
1088  script_object->set_type(i::Smi::FromInt(i::Script::TYPE_NATIVE));
1089 
1090 #ifdef ENABLE_DEBUGGER_SUPPORT
1091  // Start the in-process debugger if requested.
1092  if (i::FLAG_debugger && !i::FLAG_debugger_agent) {
1094  }
1095 #endif // ENABLE_DEBUGGER_SUPPORT
1096 }
1097 #endif // V8_SHARED
1098 
1099 
1100 #ifdef COMPRESS_STARTUP_DATA_BZ2
1101 class BZip2Decompressor : public v8::StartupDataDecompressor {
1102  public:
1103  virtual ~BZip2Decompressor() { }
1104 
1105  protected:
1106  virtual int DecompressData(char* raw_data,
1107  int* raw_data_size,
1108  const char* compressed_data,
1109  int compressed_data_size) {
1112  unsigned int decompressed_size = *raw_data_size;
1113  int result =
1114  BZ2_bzBuffToBuffDecompress(raw_data,
1115  &decompressed_size,
1116  const_cast<char*>(compressed_data),
1117  compressed_data_size,
1118  0, 1);
1119  if (result == BZ_OK) {
1120  *raw_data_size = decompressed_size;
1121  }
1122  return result;
1123  }
1124 };
1125 #endif
1126 
1127 
1128 Handle<FunctionTemplate> Shell::CreateArrayBufferTemplate(
1129  InvocationCallback fun) {
1130  Handle<FunctionTemplate> buffer_template = FunctionTemplate::New(fun);
1131  Local<Template> proto_template = buffer_template->PrototypeTemplate();
1132  proto_template->Set(String::New("slice"),
1134  return buffer_template;
1135 }
1136 
1137 
1138 Handle<FunctionTemplate> Shell::CreateArrayTemplate(InvocationCallback fun) {
1139  Handle<FunctionTemplate> array_template = FunctionTemplate::New(fun);
1140  Local<Template> proto_template = array_template->PrototypeTemplate();
1141  proto_template->Set(String::New("set"), FunctionTemplate::New(ArraySet));
1142  proto_template->Set(String::New("subarray"),
1144  return array_template;
1145 }
1146 
1147 
1148 Handle<ObjectTemplate> Shell::CreateGlobalTemplate() {
1149  Handle<ObjectTemplate> global_template = ObjectTemplate::New();
1150  global_template->Set(String::New("print"), FunctionTemplate::New(Print));
1151  global_template->Set(String::New("write"), FunctionTemplate::New(Write));
1152  global_template->Set(String::New("read"), FunctionTemplate::New(Read));
1153  global_template->Set(String::New("readbuffer"),
1155  global_template->Set(String::New("readline"),
1157  global_template->Set(String::New("load"), FunctionTemplate::New(Load));
1158  global_template->Set(String::New("quit"), FunctionTemplate::New(Quit));
1159  global_template->Set(String::New("version"), FunctionTemplate::New(Version));
1160  global_template->Set(String::New("enableProfiler"),
1162  global_template->Set(String::New("disableProfiler"),
1164 
1165  // Bind the handlers for external arrays.
1166  PropertyAttribute attr =
1167  static_cast<PropertyAttribute>(ReadOnly | DontDelete);
1168  global_template->Set(String::New("ArrayBuffer"),
1169  CreateArrayBufferTemplate(ArrayBuffer), attr);
1170  global_template->Set(String::New("Int8Array"),
1171  CreateArrayTemplate(Int8Array), attr);
1172  global_template->Set(String::New("Uint8Array"),
1173  CreateArrayTemplate(Uint8Array), attr);
1174  global_template->Set(String::New("Int16Array"),
1175  CreateArrayTemplate(Int16Array), attr);
1176  global_template->Set(String::New("Uint16Array"),
1177  CreateArrayTemplate(Uint16Array), attr);
1178  global_template->Set(String::New("Int32Array"),
1179  CreateArrayTemplate(Int32Array), attr);
1180  global_template->Set(String::New("Uint32Array"),
1181  CreateArrayTemplate(Uint32Array), attr);
1182  global_template->Set(String::New("Float32Array"),
1183  CreateArrayTemplate(Float32Array), attr);
1184  global_template->Set(String::New("Float64Array"),
1185  CreateArrayTemplate(Float64Array), attr);
1186  global_template->Set(String::New("Uint8ClampedArray"),
1187  CreateArrayTemplate(Uint8ClampedArray), attr);
1188 
1189 #ifdef LIVE_OBJECT_LIST
1190  global_template->Set(String::New("lol_is_enabled"), True());
1191 #else
1192  global_template->Set(String::New("lol_is_enabled"), False());
1193 #endif
1194 
1195 #if !defined(V8_SHARED) && !defined(_WIN32) && !defined(_WIN64)
1196  Handle<ObjectTemplate> os_templ = ObjectTemplate::New();
1197  AddOSMethods(os_templ);
1198  global_template->Set(String::New("os"), os_templ);
1199 #endif // V8_SHARED
1200 
1201  return global_template;
1202 }
1203 
1204 
1205 void Shell::Initialize() {
1206 #ifdef COMPRESS_STARTUP_DATA_BZ2
1207  BZip2Decompressor startup_data_decompressor;
1208  int bz2_result = startup_data_decompressor.Decompress();
1209  if (bz2_result != BZ_OK) {
1210  fprintf(stderr, "bzip error code: %d\n", bz2_result);
1211  Exit(1);
1212  }
1213 #endif
1214 
1215 #ifndef V8_SHARED
1216  Shell::counter_map_ = new CounterMap();
1217  // Set up counters
1218  if (i::StrLength(i::FLAG_map_counters) != 0)
1219  MapCounters(i::FLAG_map_counters);
1220  if (i::FLAG_dump_counters || i::FLAG_track_gc_object_stats) {
1224  }
1225 #endif // V8_SHARED
1226  if (options.test_shell) return;
1227 
1228 #ifndef V8_SHARED
1229  Locker lock;
1230  HandleScope scope;
1231  Handle<ObjectTemplate> global_template = CreateGlobalTemplate();
1232  utility_context_ = Context::New(NULL, global_template);
1233 
1234 #ifdef ENABLE_DEBUGGER_SUPPORT
1235  // Start the debugger agent if requested.
1236  if (i::FLAG_debugger_agent) {
1237  v8::Debug::EnableAgent("d8 shell", i::FLAG_debugger_port, true);
1238  v8::Debug::SetDebugMessageDispatchHandler(DispatchDebugMessages, true);
1239  }
1240 #endif // ENABLE_DEBUGGER_SUPPORT
1241 #endif // V8_SHARED
1242 }
1243 
1244 
1246 #ifndef V8_SHARED
1247  // This needs to be a critical section since this is not thread-safe
1248  i::ScopedLock lock(context_mutex_);
1249 #endif // V8_SHARED
1250  // Initialize the global objects
1251  Handle<ObjectTemplate> global_template = CreateGlobalTemplate();
1252  Persistent<Context> context = Context::New(NULL, global_template);
1253  ASSERT(!context.IsEmpty());
1254  Context::Scope scope(context);
1255 
1256 #ifndef V8_SHARED
1257  i::JSArguments js_args = i::FLAG_js_arguments;
1258  i::Handle<i::FixedArray> arguments_array =
1259  FACTORY->NewFixedArray(js_args.argc());
1260  for (int j = 0; j < js_args.argc(); j++) {
1261  i::Handle<i::String> arg =
1262  FACTORY->NewStringFromUtf8(i::CStrVector(js_args[j]));
1263  arguments_array->set(j, *arg);
1264  }
1265  i::Handle<i::JSArray> arguments_jsarray =
1266  FACTORY->NewJSArrayWithElements(arguments_array);
1267  context->Global()->Set(String::New("arguments"),
1268  Utils::ToLocal(arguments_jsarray));
1269 #endif // V8_SHARED
1270  return context;
1271 }
1272 
1273 
1274 void Shell::Exit(int exit_code) {
1275  // Use _exit instead of exit to avoid races between isolate
1276  // threads and static destructors.
1277  fflush(stdout);
1278  fflush(stderr);
1279  _exit(exit_code);
1280 }
1281 
1282 
1283 #ifndef V8_SHARED
1286  const char* key;
1287 };
1288 
1289 
1290 int CompareKeys(const void* a, const void* b) {
1291  return strcmp(static_cast<const CounterAndKey*>(a)->key,
1292  static_cast<const CounterAndKey*>(b)->key);
1293 }
1294 
1295 
1297  if (console != NULL) console->Close();
1298  if (i::FLAG_dump_counters) {
1299  int number_of_counters = 0;
1300  for (CounterMap::Iterator i(counter_map_); i.More(); i.Next()) {
1301  number_of_counters++;
1302  }
1303  CounterAndKey* counters = new CounterAndKey[number_of_counters];
1304  int j = 0;
1305  for (CounterMap::Iterator i(counter_map_); i.More(); i.Next(), j++) {
1306  counters[j].counter = i.CurrentValue();
1307  counters[j].key = i.CurrentKey();
1308  }
1309  qsort(counters, number_of_counters, sizeof(counters[0]), CompareKeys);
1310  printf("+----------------------------------------------------------------+"
1311  "-------------+\n");
1312  printf("| Name |"
1313  " Value |\n");
1314  printf("+----------------------------------------------------------------+"
1315  "-------------+\n");
1316  for (j = 0; j < number_of_counters; j++) {
1317  Counter* counter = counters[j].counter;
1318  const char* key = counters[j].key;
1319  if (counter->is_histogram()) {
1320  printf("| c:%-60s | %11i |\n", key, counter->count());
1321  printf("| t:%-60s | %11i |\n", key, counter->sample_total());
1322  } else {
1323  printf("| %-62s | %11i |\n", key, counter->count());
1324  }
1325  }
1326  printf("+----------------------------------------------------------------+"
1327  "-------------+\n");
1328  delete [] counters;
1329  }
1330  delete counters_file_;
1331  delete counter_map_;
1332 }
1333 #endif // V8_SHARED
1334 
1335 
1336 static FILE* FOpen(const char* path, const char* mode) {
1337 #if defined(_MSC_VER) && (defined(_WIN32) || defined(_WIN64))
1338  FILE* result;
1339  if (fopen_s(&result, path, mode) == 0) {
1340  return result;
1341  } else {
1342  return NULL;
1343  }
1344 #else
1345  FILE* file = fopen(path, mode);
1346  if (file == NULL) return NULL;
1347  struct stat file_stat;
1348  if (fstat(fileno(file), &file_stat) != 0) return NULL;
1349  bool is_regular_file = ((file_stat.st_mode & S_IFREG) != 0);
1350  if (is_regular_file) return file;
1351  fclose(file);
1352  return NULL;
1353 #endif
1354 }
1355 
1356 
1357 static char* ReadChars(const char* name, int* size_out) {
1358  // Release the V8 lock while reading files.
1359  v8::Unlocker unlocker(Isolate::GetCurrent());
1360  FILE* file = FOpen(name, "rb");
1361  if (file == NULL) return NULL;
1362 
1363  fseek(file, 0, SEEK_END);
1364  int size = ftell(file);
1365  rewind(file);
1366 
1367  char* chars = new char[size + 1];
1368  chars[size] = '\0';
1369  for (int i = 0; i < size;) {
1370  int read = static_cast<int>(fread(&chars[i], 1, size - i, file));
1371  i += read;
1372  }
1373  fclose(file);
1374  *size_out = size;
1375  return chars;
1376 }
1377 
1378 
1380  ASSERT(sizeof(char) == sizeof(uint8_t)); // NOLINT
1381  String::Utf8Value filename(args[0]);
1382  int length;
1383  if (*filename == NULL) {
1384  return ThrowException(String::New("Error loading file"));
1385  }
1386 
1387  uint8_t* data = reinterpret_cast<uint8_t*>(ReadChars(*filename, &length));
1388  if (data == NULL) {
1389  return ThrowException(String::New("Error reading file"));
1390  }
1391  Handle<Object> buffer = Object::New();
1392  buffer->SetHiddenValue(String::New(kArrayBufferMarkerPropName), True());
1393  Persistent<Object> persistent_buffer = Persistent<Object>::New(buffer);
1394  persistent_buffer.MakeWeak(data, ExternalArrayWeakCallback);
1395  persistent_buffer.MarkIndependent();
1397 
1398  buffer->SetIndexedPropertiesToExternalArrayData(
1399  data, kExternalUnsignedByteArray, length);
1400  buffer->Set(String::New("byteLength"),
1401  Int32::New(static_cast<int32_t>(length)), ReadOnly);
1402  return buffer;
1403 }
1404 
1405 
1406 #ifndef V8_SHARED
1407 static char* ReadToken(char* data, char token) {
1408  char* next = i::OS::StrChr(data, token);
1409  if (next != NULL) {
1410  *next = '\0';
1411  return (next + 1);
1412  }
1413 
1414  return NULL;
1415 }
1416 
1417 
1418 static char* ReadLine(char* data) {
1419  return ReadToken(data, '\n');
1420 }
1421 
1422 
1423 static char* ReadWord(char* data) {
1424  return ReadToken(data, ' ');
1425 }
1426 #endif // V8_SHARED
1427 
1428 
1429 // Reads a file into a v8 string.
1430 Handle<String> Shell::ReadFile(const char* name) {
1431  int size = 0;
1432  char* chars = ReadChars(name, &size);
1433  if (chars == NULL) return Handle<String>();
1434  Handle<String> result = String::New(chars);
1435  delete[] chars;
1436  return result;
1437 }
1438 
1439 
1440 void Shell::RunShell() {
1441  Locker locker;
1442  Context::Scope context_scope(evaluation_context_);
1443  HandleScope outer_scope;
1444  Handle<String> name = String::New("(d8)");
1446  printf("V8 version %s [console: %s]\n", V8::GetVersion(), console->name());
1447  console->Open();
1448  while (true) {
1449  HandleScope inner_scope;
1451  if (input.IsEmpty()) break;
1452  ExecuteString(input, name, true, true);
1453  }
1454  printf("\n");
1455 }
1456 
1457 
1458 #ifndef V8_SHARED
1459 class ShellThread : public i::Thread {
1460  public:
1461  // Takes ownership of the underlying char array of |files|.
1462  ShellThread(int no, char* files)
1463  : Thread("d8:ShellThread"),
1464  no_(no), files_(files) { }
1465 
1467  delete[] files_;
1468  }
1469 
1470  virtual void Run();
1471  private:
1472  int no_;
1473  char* files_;
1474 };
1475 
1476 
1478  char* ptr = files_;
1479  while ((ptr != NULL) && (*ptr != '\0')) {
1480  // For each newline-separated line.
1481  char* next_line = ReadLine(ptr);
1482 
1483  if (*ptr == '#') {
1484  // Skip comment lines.
1485  ptr = next_line;
1486  continue;
1487  }
1488 
1489  // Prepare the context for this thread.
1490  Locker locker;
1491  HandleScope outer_scope;
1493  Context::Scope context_scope(thread_context);
1494 
1495  while ((ptr != NULL) && (*ptr != '\0')) {
1496  HandleScope inner_scope;
1497  char* filename = ptr;
1498  ptr = ReadWord(ptr);
1499 
1500  // Skip empty strings.
1501  if (strlen(filename) == 0) {
1502  continue;
1503  }
1504 
1505  Handle<String> str = Shell::ReadFile(filename);
1506  if (str.IsEmpty()) {
1507  printf("File '%s' not found\n", filename);
1508  Shell::Exit(1);
1509  }
1510 
1511  Shell::ExecuteString(str, String::New(filename), false, false);
1512  }
1513 
1514  thread_context.Dispose();
1515  ptr = next_line;
1516  }
1517 }
1518 #endif // V8_SHARED
1519 
1520 
1522 #ifndef V8_SHARED
1523  delete next_semaphore_;
1524  next_semaphore_ = NULL;
1525  delete done_semaphore_;
1526  done_semaphore_ = NULL;
1527  delete thread_;
1528  thread_ = NULL;
1529 #endif // V8_SHARED
1530 }
1531 
1532 
1534  for (int i = begin_offset_; i < end_offset_; ++i) {
1535  const char* arg = argv_[i];
1536  if (strcmp(arg, "-e") == 0 && i + 1 < end_offset_) {
1537  // Execute argument given to -e option directly.
1538  HandleScope handle_scope;
1539  Handle<String> file_name = String::New("unnamed");
1540  Handle<String> source = String::New(argv_[i + 1]);
1541  if (!Shell::ExecuteString(source, file_name, false, true)) {
1542  Shell::Exit(1);
1543  }
1544  ++i;
1545  } else if (arg[0] == '-') {
1546  // Ignore other options. They have been parsed already.
1547  } else {
1548  // Use all other arguments as names of files to load and run.
1549  HandleScope handle_scope;
1550  Handle<String> file_name = String::New(arg);
1551  Handle<String> source = ReadFile(arg);
1552  if (source.IsEmpty()) {
1553  printf("Error reading '%s'\n", arg);
1554  Shell::Exit(1);
1555  }
1556  if (!Shell::ExecuteString(source, file_name, false, true)) {
1557  Shell::Exit(1);
1558  }
1559  }
1560  }
1561 }
1562 
1563 
1564 Handle<String> SourceGroup::ReadFile(const char* name) {
1565  int size;
1566  char* chars = ReadChars(name, &size);
1567  if (chars == NULL) return Handle<String>();
1568  Handle<String> result = String::New(chars, size);
1569  delete[] chars;
1570  return result;
1571 }
1572 
1573 
1574 #ifndef V8_SHARED
1575 i::Thread::Options SourceGroup::GetThreadOptions() {
1576  // On some systems (OSX 10.6) the stack size default is 0.5Mb or less
1577  // which is not enough to parse the big literal expressions used in tests.
1578  // The stack size should be at least StackGuard::kLimitSize + some
1579  // OS-specific padding for thread startup code. 2Mbytes seems to be enough.
1580  return i::Thread::Options("IsolateThread", 2 * MB);
1581 }
1582 
1583 
1584 void SourceGroup::ExecuteInThread() {
1585  Isolate* isolate = Isolate::New();
1586  do {
1587  if (next_semaphore_ != NULL) next_semaphore_->Wait();
1588  {
1589  Isolate::Scope iscope(isolate);
1590  Locker lock(isolate);
1591  HandleScope scope;
1592  Persistent<Context> context = Shell::CreateEvaluationContext();
1593  {
1594  Context::Scope cscope(context);
1595  Execute();
1596  }
1597  context.Dispose();
1598  if (Shell::options.send_idle_notification) {
1599  const int kLongIdlePauseInMs = 1000;
1601  V8::IdleNotification(kLongIdlePauseInMs);
1602  }
1603  }
1604  if (done_semaphore_ != NULL) done_semaphore_->Signal();
1605  } while (!Shell::options.last_run);
1606  isolate->Dispose();
1607 }
1608 
1609 
1611  if (thread_ == NULL) {
1612  thread_ = new IsolateThread(this);
1613  thread_->Start();
1614  }
1615  next_semaphore_->Signal();
1616 }
1617 
1618 
1620  if (thread_ == NULL) return;
1621  if (Shell::options.last_run) {
1622  thread_->Join();
1623  } else {
1624  done_semaphore_->Wait();
1625  }
1626 }
1627 #endif // V8_SHARED
1628 
1629 
1630 bool Shell::SetOptions(int argc, char* argv[]) {
1631  for (int i = 0; i < argc; i++) {
1632  if (strcmp(argv[i], "--stress-opt") == 0) {
1633  options.stress_opt = true;
1634  argv[i] = NULL;
1635  } else if (strcmp(argv[i], "--stress-deopt") == 0) {
1636  options.stress_deopt = true;
1637  argv[i] = NULL;
1638  } else if (strcmp(argv[i], "--noalways-opt") == 0) {
1639  // No support for stressing if we can't use --always-opt.
1640  options.stress_opt = false;
1641  options.stress_deopt = false;
1642  } else if (strcmp(argv[i], "--shell") == 0) {
1643  options.interactive_shell = true;
1644  argv[i] = NULL;
1645  } else if (strcmp(argv[i], "--test") == 0) {
1646  options.test_shell = true;
1647  argv[i] = NULL;
1648  } else if (strcmp(argv[i], "--send-idle-notification") == 0) {
1650  argv[i] = NULL;
1651  } else if (strcmp(argv[i], "--preemption") == 0) {
1652 #ifdef V8_SHARED
1653  printf("D8 with shared library does not support multi-threading\n");
1654  return false;
1655 #else
1656  options.use_preemption = true;
1657  argv[i] = NULL;
1658 #endif // V8_SHARED
1659  } else if (strcmp(argv[i], "--nopreemption") == 0) {
1660 #ifdef V8_SHARED
1661  printf("D8 with shared library does not support multi-threading\n");
1662  return false;
1663 #else
1664  options.use_preemption = false;
1665  argv[i] = NULL;
1666 #endif // V8_SHARED
1667  } else if (strcmp(argv[i], "--preemption-interval") == 0) {
1668 #ifdef V8_SHARED
1669  printf("D8 with shared library does not support multi-threading\n");
1670  return false;
1671 #else
1672  if (++i < argc) {
1673  argv[i-1] = NULL;
1674  char* end = NULL;
1675  options.preemption_interval = strtol(argv[i], &end, 10); // NOLINT
1676  if (options.preemption_interval <= 0
1677  || *end != '\0'
1678  || errno == ERANGE) {
1679  printf("Invalid value for --preemption-interval '%s'\n", argv[i]);
1680  return false;
1681  }
1682  argv[i] = NULL;
1683  } else {
1684  printf("Missing value for --preemption-interval\n");
1685  return false;
1686  }
1687 #endif // V8_SHARED
1688  } else if (strcmp(argv[i], "-f") == 0) {
1689  // Ignore any -f flags for compatibility with other stand-alone
1690  // JavaScript engines.
1691  continue;
1692  } else if (strcmp(argv[i], "--isolate") == 0) {
1693 #ifdef V8_SHARED
1694  printf("D8 with shared library does not support multi-threading\n");
1695  return false;
1696 #endif // V8_SHARED
1698  } else if (strcmp(argv[i], "-p") == 0) {
1699 #ifdef V8_SHARED
1700  printf("D8 with shared library does not support multi-threading\n");
1701  return false;
1702 #else
1704 #endif // V8_SHARED
1705  }
1706 #ifdef V8_SHARED
1707  else if (strcmp(argv[i], "--dump-counters") == 0) {
1708  printf("D8 with shared library does not include counters\n");
1709  return false;
1710  } else if (strcmp(argv[i], "--debugger") == 0) {
1711  printf("Javascript debugger not included\n");
1712  return false;
1713  }
1714 #endif // V8_SHARED
1715  }
1716 
1717 #ifndef V8_SHARED
1718  // Run parallel threads if we are not using --isolate
1720  int parallel_files_set = 0;
1721  for (int i = 1; i < argc; i++) {
1722  if (argv[i] == NULL) continue;
1723  if (strcmp(argv[i], "-p") == 0 && i + 1 < argc) {
1724  if (options.num_isolates > 1) {
1725  printf("-p is not compatible with --isolate\n");
1726  return false;
1727  }
1728  argv[i] = NULL;
1729  i++;
1730  options.parallel_files[parallel_files_set] = argv[i];
1731  parallel_files_set++;
1732  argv[i] = NULL;
1733  }
1734  }
1735  if (parallel_files_set != options.num_parallel_files) {
1736  printf("-p requires a file containing a list of files as parameter\n");
1737  return false;
1738  }
1739 #endif // V8_SHARED
1740 
1741  v8::V8::SetFlagsFromCommandLine(&argc, argv, true);
1742 
1743  // Set up isolated source groups.
1744  options.isolate_sources = new SourceGroup[options.num_isolates];
1745  SourceGroup* current = options.isolate_sources;
1746  current->Begin(argv, 1);
1747  for (int i = 1; i < argc; i++) {
1748  const char* str = argv[i];
1749  if (strcmp(str, "--isolate") == 0) {
1750  current->End(i);
1751  current++;
1752  current->Begin(argv, i + 1);
1753  } else if (strncmp(argv[i], "--", 2) == 0) {
1754  printf("Warning: unknown flag %s.\nTry --help for options\n", argv[i]);
1755  }
1756  }
1757  current->End(argc);
1758 
1759  return true;
1760 }
1761 
1762 
1763 int Shell::RunMain(int argc, char* argv[]) {
1764 #ifndef V8_SHARED
1765  i::List<i::Thread*> threads(1);
1766  if (options.parallel_files != NULL) {
1767  for (int i = 0; i < options.num_parallel_files; i++) {
1768  char* files = NULL;
1769  { Locker lock(Isolate::GetCurrent());
1770  int size = 0;
1771  files = ReadChars(options.parallel_files[i], &size);
1772  }
1773  if (files == NULL) {
1774  printf("File list '%s' not found\n", options.parallel_files[i]);
1775  Exit(1);
1776  }
1777  ShellThread* thread = new ShellThread(threads.length(), files);
1778  thread->Start();
1779  threads.Add(thread);
1780  }
1781  }
1782  for (int i = 1; i < options.num_isolates; ++i) {
1784  }
1785 #endif // V8_SHARED
1786  { // NOLINT
1787  Locker lock;
1788  HandleScope scope;
1790  if (options.last_run) {
1791  // Keep using the same context in the interactive shell.
1792  evaluation_context_ = context;
1793 #if !defined(V8_SHARED) && defined(ENABLE_DEBUGGER_SUPPORT)
1794  // If the interactive debugger is enabled make sure to activate
1795  // it before running the files passed on the command line.
1796  if (i::FLAG_debugger) {
1797  InstallUtilityScript();
1798  }
1799 #endif // !V8_SHARED && ENABLE_DEBUGGER_SUPPORT
1800  }
1801  {
1802  Context::Scope cscope(context);
1804  }
1805  if (!options.last_run) {
1806  context.Dispose();
1808  const int kLongIdlePauseInMs = 1000;
1810  V8::IdleNotification(kLongIdlePauseInMs);
1811  }
1812  }
1813 
1814 #ifndef V8_SHARED
1815  // Start preemption if threads have been created and preemption is enabled.
1816  if (threads.length() > 0
1817  && options.use_preemption) {
1819  }
1820 #endif // V8_SHARED
1821  }
1822 
1823 #ifndef V8_SHARED
1824  for (int i = 1; i < options.num_isolates; ++i) {
1826  }
1827 
1828  for (int i = 0; i < threads.length(); i++) {
1829  i::Thread* thread = threads[i];
1830  thread->Join();
1831  delete thread;
1832  }
1833 
1834  if (threads.length() > 0 && options.use_preemption) {
1835  Locker lock;
1837  }
1838 #endif // V8_SHARED
1839  return 0;
1840 }
1841 
1842 
1843 int Shell::Main(int argc, char* argv[]) {
1844  if (!SetOptions(argc, argv)) return 1;
1845  Initialize();
1846 
1847  int result = 0;
1852  int stress_runs = Testing::GetStressRuns();
1853  for (int i = 0; i < stress_runs && result == 0; i++) {
1854  printf("============ Stress %d/%d ============\n", i + 1, stress_runs);
1856  options.last_run = (i == stress_runs - 1);
1857  result = RunMain(argc, argv);
1858  }
1859  printf("======== Full Deoptimization =======\n");
1861 #if !defined(V8_SHARED)
1862  } else if (i::FLAG_stress_runs > 0) {
1863  int stress_runs = i::FLAG_stress_runs;
1864  for (int i = 0; i < stress_runs && result == 0; i++) {
1865  printf("============ Run %d/%d ============\n", i + 1, stress_runs);
1866  options.last_run = (i == stress_runs - 1);
1867  result = RunMain(argc, argv);
1868  }
1869 #endif
1870  } else {
1871  result = RunMain(argc, argv);
1872  }
1873 
1874 
1875 #if !defined(V8_SHARED) && defined(ENABLE_DEBUGGER_SUPPORT)
1876  // Run remote debugger if requested, but never on --test
1877  if (i::FLAG_remote_debugger && !options.test_shell) {
1878  InstallUtilityScript();
1879  RunRemoteDebugger(i::FLAG_debugger_port);
1880  return 0;
1881  }
1882 #endif // !V8_SHARED && ENABLE_DEBUGGER_SUPPORT
1883 
1884  // Run interactive shell if explicitly requested or if no script has been
1885  // executed, but never on --test
1886 
1888  || !options.script_executed )
1889  && !options.test_shell ) {
1890 #if !defined(V8_SHARED) && defined(ENABLE_DEBUGGER_SUPPORT)
1891  if (!i::FLAG_debugger) {
1892  InstallUtilityScript();
1893  }
1894 #endif // !V8_SHARED && ENABLE_DEBUGGER_SUPPORT
1895  RunShell();
1896  }
1897 
1898  V8::Dispose();
1899 
1900 #ifndef V8_SHARED
1901  OnExit();
1902 #endif // V8_SHARED
1903 
1904  return result;
1905 }
1906 
1907 } // namespace v8
1908 
1909 
1910 #ifndef GOOGLE3
1911 int main(int argc, char* argv[]) {
1912  return v8::Shell::Main(argc, argv);
1913 }
1914 #endif
static Local< Context > GetCurrent()
Definition: api.cc:4545
static Isolate * GetCurrent()
Definition: api.cc:5520
static void Exit(int exit_code)
Definition: d8.cc:1274
void MakeWeak(void *parameters, WeakReferenceCallback callback)
Definition: v8.h:4245
static Handle< Array > GetCompletions(Handle< String > text, Handle< String > full)
Definition: d8.cc:905
void Set(const char *name, Counter *value)
Definition: d8.h:90
static Local< Script > Compile(Handle< String > source, ScriptOrigin *origin=NULL, ScriptData *pre_data=NULL, Handle< String > script_data=Handle< String >())
Definition: api.cc:1568
Counter * counter
Definition: d8.cc:1285
int num_parallel_files
Definition: d8.h:248
bool use_preemption
Definition: d8.h:246
void RunRemoteDebugger(int port)
static const int kMaxLength
Definition: objects.h:3738
static Local< FunctionTemplate > New(InvocationCallback callback=0, Handle< Value > data=Handle< Value >(), Handle< Signature > signature=Handle< Signature >())
Definition: api.cc:951
Handle< Boolean > V8EXPORT True()
Definition: api.cc:569
static int GetStressRuns()
Definition: api.cc:6443
void Dispose()
Definition: v8.h:4235
char ** parallel_files
Definition: d8.h:249
Thread(const Options &options)
Local< Value > Exception() const
Definition: api.cc:1720
static Handle< Value > ArrayBufferSlice(const Arguments &args)
Definition: d8.cc:521
static void SetAddHistogramSampleFunction(AddHistogramSampleCallback)
Definition: api.cc:5328
static Handle< Value > Version(const Arguments &args)
Definition: d8.cc:853
static Smi * FromInt(int value)
Definition: objects-inl.h:981
static int Main(int argc, char *argv[])
Definition: d8.cc:1843
static int GetIndex(const char *name)
void WaitForThread()
Definition: d8.cc:1619
bool HasCaught() const
Definition: api.cc:1703
static void AddHistogramSample(void *histogram, int sample)
Definition: d8.cc:1041
void AddSample(int32_t sample)
Definition: d8.cc:959
bool interactive_shell
Definition: d8.h:256
static Handle< Value > Int32Array(const Arguments &args)
Definition: d8.cc:810
static Handle< Value > Float32Array(const Arguments &args)
Definition: d8.cc:820
static Vector< const char > GetRawScriptSource(int index)
static Vector< const char > GetScriptName(int index)
static V8EXPORT Local< String > New(const char *data, int length=-1)
Definition: api.cc:4779
Local< Function > Callee() const
Definition: v8.h:4286
static Handle< Value > ReadLine(const Arguments &args)
Definition: d8.h:314
static void AddOSMethods(Handle< ObjectTemplate > os_template)
Definition: d8-posix.cc:677
int int32_t
Definition: unicode.cc:47
virtual bool Open()
Definition: d8.h:126
static LineEditor * Get()
Definition: d8.cc:81
int32_t * ptr()
Definition: d8.h:49
static Handle< T > Cast(Handle< S > that)
Definition: v8.h:244
MUST_USE_RESULT MaybeObject * ToObject()
Definition: objects.cc:85
int preemption_interval
Definition: d8.h:247
TickSample * sample
Counter * GetNextCounter()
Definition: d8.cc:973
int32_t * Bind(const char *name, bool histogram)
Definition: d8.cc:949
~ShellThread()
Definition: d8.cc:1466
#define ASSERT(condition)
Definition: checks.h:270
V8EXPORT Local< Number > ToNumber() const
Definition: api.cc:2390
static Handle< Value > Int16Array(const Arguments &args)
Definition: d8.cc:799
static Script * cast(Object *obj)
const char kArrayMarkerPropName[]
Definition: d8.cc:336
ExternalArrayType
Definition: v8.h:1431
unsigned short uint16_t
Definition: unicode.cc:46
DumbLineEditor()
Definition: d8.cc:95
int main(int argc, char *argv[])
Definition: d8.cc:1911
static const int kMaxNameSize
Definition: d8.h:47
static bool InContext()
Definition: api.cc:4527
static intptr_t AdjustAmountOfExternalAllocatedMemory(intptr_t change_in_bytes)
Definition: api.cc:5374
void SetVerbose(bool value)
Definition: api.cc:1768
int32_t * Bind(const char *name)
Definition: mksnapshot.cc:52
static bool Dispose()
Definition: api.cc:4303
static Handle< Value > Uint16Array(const Arguments &args)
Definition: d8.cc:804
ShellThread(int no, char *files)
Definition: d8.cc:1462
static LineEditor * console
Definition: d8.h:368
static const char * GetVersion()
Definition: api.cc:4394
static ShellOptions options
Definition: d8.h:370
const int MB
Definition: d8.cc:124
LineEditor(Type type, const char *name)
Definition: d8.cc:73
static bool SetDebugEventListener(EventCallback that, Handle< Value > data=Handle< Value >())
Handle< Value >(* InvocationCallback)(const Arguments &args)
Definition: v8.h:2047
bool is_histogram()
Definition: d8.h:52
T * start() const
Definition: utils.h:390
static Local< ObjectTemplate > New()
Definition: api.cc:1253
static Handle< Value > ArrayBuffer(const Arguments &args)
Definition: d8.cc:366
Handle< Value > ReThrow()
Definition: api.cc:1713
static Handle< Value > EnableProfiler(const Arguments &args)
Definition: d8.cc:220
static const char * ToCString(const v8::String::Utf8Value &value)
Definition: d8.cc:137
static Handle< Value > DisableProfiler(const Arguments &args)
Definition: d8.cc:226
static void ResumeProfiler()
Definition: api.cc:5468
int32_t sample_total()
Definition: d8.h:51
static Isolate * New()
Definition: api.cc:5526
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 and VFP2 enable use of VFP2 instructions if available enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of MIPS FPU instructions if expose natives in global object expose gc extension number of stack frames to capture disable builtin natives files print a stack trace if an assertion failure occurs use random jit cookie to mask large constants trace lazy optimization use adaptive optimizations prepare for turning on always opt minimum length for automatic enable preparsing maximum number of optimization attempts before giving up cache prototype transitions automatically set the debug break flag when debugger commands are in the queue always cause a debug break before aborting maximum length of function source code printed in a stack trace max size of the new max size of the old max size of executable always perform global GCs print one trace line following each garbage collection do not print trace line after scavenger collection print more details following each garbage collection print amount of external allocated memory after each time it is adjusted flush code that we expect not to use again before full gc do incremental marking steps track object counts and memory usage use caching Perform compaction on every full GC Never perform compaction on full GC testing only Compact code space on full incremental collections Default seed for initializing random allows verbose printing trace parsing and preparsing Check icache flushes in ARM and MIPS simulator Stack alingment in bytes in print stack trace when throwing exceptions randomize hashes to avoid predictable hash Fixed seed to use to hash property activate a timer that switches between V8 threads testing_bool_flag float flag Seed used for threading test randomness A filename with extra code to be included in the Print usage message
static int ContextDisposedNotification()
Definition: api.cc:4387
int Length() const
Definition: v8.h:4318
V8EXPORT int32_t Int32Value() const
Definition: api.cc:2662
static Handle< Value > Read(const Arguments &args)
Definition: d8.cc:232
SourceGroup * isolate_sources
Definition: d8.h:259
~SourceGroup()
Definition: d8.cc:1521
int num_isolates
Definition: d8.h:258
int length() const
Definition: utils.h:384
static void SetStressRunType(StressType type)
Definition: api.cc:6439
static Mutex * CreateMutex()
static const char * kPrompt
Definition: d8.h:369
bool stress_opt
Definition: d8.h:254
static Persistent< T > New(Handle< T > that)
Definition: v8.h:4206
static Handle< Value > ArraySet(const Arguments &args)
Definition: d8.cc:638
int CompareKeys(const void *a, const void *b)
Definition: d8.cc:1290
static bool EnableAgent(const char *name, int port, bool wait_for_connection=false)
static void * CreateHistogram(const char *name, int min, int max, size_t buckets)
Definition: d8.cc:1033
const char * name()
Definition: d8.h:130
bool IsUndefined() const
Definition: v8.h:4472
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 and VFP2 enable use of VFP2 instructions if available enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of MIPS FPU instructions if expose natives in global object expose gc extension number of stack frames to capture disable builtin natives files print a stack trace if an assertion failure occurs use random jit cookie to mask large constants trace lazy optimization use adaptive optimizations prepare for turning on always opt minimum length for automatic enable preparsing maximum number of optimization attempts before giving up cache prototype transitions automatically set the debug break flag when debugger commands are in the queue always cause a debug break before aborting maximum length of function source code printed in a stack trace max size of the new max size of the old max size of executable memory(in Mbytes)") DEFINE_bool(gc_global
Handle< Boolean > V8EXPORT False()
Definition: api.cc:579
static Handle< Value > Int8Array(const Arguments &args)
Definition: d8.cc:789
Definition: v8.h:598
bool stress_deopt
Definition: d8.h:255
Vector< const char > CStrVector(const char *data)
Definition: utils.h:526
int argc() const
Definition: flags.h:88
int StrLength(const char *string)
Definition: utils.h:234
static Local< Context > ToLocal(v8::internal::Handle< v8::internal::Context > obj)
Local< Object > This() const
Definition: v8.h:4292
static Local< T > Cast(Local< S > that)
Definition: v8.h:282
static Handle< Value > Write(const Arguments &args)
Definition: d8.cc:197
Local< Value > StackTrace() const
Definition: api.cc:1732
virtual bool Close()
Definition: d8.h:127
static Handle< Value > Load(const Arguments &args)
Definition: d8.cc:275
Counter * Lookup(const char *name)
Definition: d8.h:82
virtual Handle< String > Prompt(const char *prompt)=0
static void SetDebugMessageDispatchHandler(DebugMessageDispatchHandler handler, bool provide_locker=false)
static Handle< Value > ReadBuffer(const Arguments &args)
Definition: d8.cc:1379
const char * key
Definition: d8.cc:1286
static Handle< Value > Print(const Arguments &args)
Definition: d8.cc:189
int length() const
Definition: v8.h:1308
void Execute()
Definition: d8.cc:1533
static bool ExecuteString(Handle< String > source, Handle< Value > name, bool print_result, bool report_exceptions)
Definition: d8.cc:143
static Handle< Value > Float64Array(const Arguments &args)
Definition: d8.cc:826
virtual void Signal()=0
#define HEAP
Definition: isolate.h:1433
static Persistent< Context > CreateEvaluationContext()
Definition: d8.cc:1245
static Handle< String > ReadFile(const char *name)
Definition: d8.cc:1430
#define ASSERT_EQ(v1, v2)
Definition: checks.h:271
static V8EXPORT Local< Integer > New(int32_t value)
Definition: api.cc:5228
void Begin(char **argv, int offset)
Definition: d8.h:154
static void MapCounters(const char *name)
Definition: d8.cc:979
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 and VFP2 enable use of VFP2 instructions if available enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of MIPS FPU instructions if NULL
static void PrepareStressRun(int run)
Definition: api.cc:6460
static void StartPreemption(int every_n_ms)
Definition: v8threads.cc:142
static void SetCreateHistogramFunction(CreateHistogramCallback)
Definition: api.cc:5320
Local< T > Close(Handle< T > value)
Definition: v8.h:4324
static void ReportException(TryCatch *try_catch)
Definition: d8.cc:858
static Handle< Value > Uint8Array(const Arguments &args)
Definition: d8.cc:794
Handle< Primitive > V8EXPORT Undefined()
Definition: api.cc:549
virtual void Wait()=0
void Add(const T &element, AllocationPolicy allocator=AllocationPolicy())
Definition: list-inl.h:38
bool IsEmpty() const
Definition: v8.h:209
Local< Value > Run()
Definition: api.cc:1598
#define FACTORY
Definition: isolate.h:1434
static V8EXPORT Local< String > Concat(Handle< String > left, Handle< String > right)
Definition: api.cc:4793
static Handle< String > ReadFromStdin()
Definition: d8.cc:245
static Handle< Value > Uint8ClampedArray(const Arguments &args)
Definition: d8.cc:832
int32_t count()
Definition: d8.h:50
static Persistent< Context > New(ExtensionConfiguration *extensions=NULL, Handle< ObjectTemplate > global_template=Handle< ObjectTemplate >(), Handle< Value > global_object=Handle< Value >())
Definition: api.cc:4411
V8EXPORT Local< Object > ToObject() const
Definition: api.cc:2353
static Handle< Value > Quit(const Arguments &args)
Definition: d8.cc:843
static Handle< Value > ArraySubArray(const Arguments &args)
Definition: d8.cc:578
static Handle< Value > Uint32Array(const Arguments &args)
Definition: d8.cc:815
bool test_shell
Definition: d8.h:257
static void SetFlagsFromCommandLine(int *argc, char **argv, bool remove_flags)
Definition: api.cc:481
static int * LookupCounter(const char *name)
Definition: d8.cc:1022
static Handle< Value > Yield(const Arguments &args)
Definition: d8.cc:837
V8EXPORT bool IsInt32() const
Definition: api.cc:2205
signed short int16_t
Definition: unicode.cc:45
void MarkIndependent()
Definition: v8.h:4257
static void StopPreemption()
Definition: v8threads.cc:147
Handle< Value > V8EXPORT ThrowException(Handle< Value > exception)
Definition: api.cc:486
static StartupData::CompressionAlgorithm GetCompressedStartupDataAlgorithm()
Definition: api.cc:369
bool IsConstructCall() const
Definition: v8.h:4313
bool script_executed
Definition: d8.h:251
bool send_idle_notification
Definition: d8.h:253
static void DeoptimizeAll()
Definition: api.cc:6495
const char kArrayBufferMarkerPropName[]
Definition: d8.cc:335
static void ProcessDebugMessages()
Definition: v8.h:106
void RunShell(v8::Handle< v8::Context > context)
Definition: shell.cc:251
static void PauseProfiler()
Definition: api.cc:5462
Local< v8::Message > Message() const
Definition: api.cc:1750
Definition: d8.h:45
void StartExecuteInThread()
Definition: d8.cc:1610
PropertyAttribute
Definition: v8.h:1424
static void OnExit()
Definition: d8.cc:1296
static int RunMain(int argc, char *argv[])
Definition: d8.cc:1763
virtual Handle< String > Prompt(const char *prompt)
Definition: d8.cc:103
void HandleDebugEvent(DebugEvent event, Handle< Object > exec_state, Handle< Object > event_data, Handle< Value > data)
static V8EXPORT Local< Object > New()
Definition: api.cc:4957
static char * StrChr(char *str, int c)
static void SetCounterFunction(CounterLookupCallback)
Definition: api.cc:5314
virtual void Run()
Definition: d8.cc:1477
static bool IdleNotification(int hint=1000)
Definition: api.cc:4371
bool last_run
Definition: d8.h:252
static JSFunction * cast(Object *obj)