1 // Copyright 2012 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef V8_D8_H_ 6 #define V8_D8_H_ 7 8 #ifndef V8_SHARED 9 #include "src/allocation.h" 10 #include "src/hashmap.h" 11 #include "src/smart-pointers.h" 12 #include "src/v8.h" 13 #else 14 #include "include/v8.h" 15 #endif // !V8_SHARED 16 17 namespace v8 { 18 19 20 #ifndef V8_SHARED 21 // A single counter in a counter collection. 22 class Counter { 23 public: 24 static const int kMaxNameSize = 64; 25 int32_t* Bind(const char* name, bool histogram); 26 int32_t* ptr() { return &count_; } 27 int32_t count() { return count_; } 28 int32_t sample_total() { return sample_total_; } 29 bool is_histogram() { return is_histogram_; } 30 void AddSample(int32_t sample); 31 private: 32 int32_t count_; 33 int32_t sample_total_; 34 bool is_histogram_; 35 uint8_t name_[kMaxNameSize]; 36 }; 37 38 39 // A set of counters and associated information. An instance of this 40 // class is stored directly in the memory-mapped counters file if 41 // the --map-counters options is used 42 class CounterCollection { 43 public: 44 CounterCollection(); 45 Counter* GetNextCounter(); 46 private: 47 static const unsigned kMaxCounters = 512; 48 uint32_t magic_number_; 49 uint32_t max_counters_; 50 uint32_t max_name_size_; 51 uint32_t counters_in_use_; 52 Counter counters_[kMaxCounters]; 53 }; 54 55 56 class CounterMap { 57 public: 58 CounterMap(): hash_map_(Match) { } 59 Counter* Lookup(const char* name) { 60 i::HashMap::Entry* answer = hash_map_.Lookup( 61 const_cast<char*>(name), 62 Hash(name), 63 false); 64 if (!answer) return NULL; 65 return reinterpret_cast<Counter*>(answer->value); 66 } 67 void Set(const char* name, Counter* value) { 68 i::HashMap::Entry* answer = hash_map_.Lookup( 69 const_cast<char*>(name), 70 Hash(name), 71 true); 72 ASSERT(answer != NULL); 73 answer->value = value; 74 } 75 class Iterator { 76 public: 77 explicit Iterator(CounterMap* map) 78 : map_(&map->hash_map_), entry_(map_->Start()) { } 79 void Next() { entry_ = map_->Next(entry_); } 80 bool More() { return entry_ != NULL; } 81 const char* CurrentKey() { return static_cast<const char*>(entry_->key); } 82 Counter* CurrentValue() { return static_cast<Counter*>(entry_->value); } 83 private: 84 i::HashMap* map_; 85 i::HashMap::Entry* entry_; 86 }; 87 88 private: 89 static int Hash(const char* name); 90 static bool Match(void* key1, void* key2); 91 i::HashMap hash_map_; 92 }; 93 #endif // !V8_SHARED 94 95 96 class LineEditor { 97 public: 98 enum Type { DUMB = 0, READLINE = 1 }; 99 LineEditor(Type type, const char* name); 100 virtual ~LineEditor() { } 101 102 virtual Handle<String> Prompt(const char* prompt) = 0; 103 virtual bool Open(Isolate* isolate) { return true; } 104 virtual bool Close() { return true; } 105 virtual void AddHistory(const char* str) { } 106 107 const char* name() { return name_; } 108 static LineEditor* Get() { return current_; } 109 private: 110 Type type_; 111 const char* name_; 112 static LineEditor* current_; 113 }; 114 115 116 class SourceGroup { 117 public: 118 SourceGroup() : 119 #ifndef V8_SHARED 120 next_semaphore_(0), 121 done_semaphore_(0), 122 thread_(NULL), 123 #endif // !V8_SHARED 124 argv_(NULL), 125 begin_offset_(0), 126 end_offset_(0) {} 127 128 ~SourceGroup(); 129 130 void Begin(char** argv, int offset) { 131 argv_ = const_cast<const char**>(argv); 132 begin_offset_ = offset; 133 } 134 135 void End(int offset) { end_offset_ = offset; } 136 137 void Execute(Isolate* isolate); 138 139 #ifndef V8_SHARED 140 void StartExecuteInThread(); 141 void WaitForThread(); 142 143 private: 144 class IsolateThread : public i::Thread { 145 public: 146 explicit IsolateThread(SourceGroup* group) 147 : i::Thread(GetThreadOptions()), group_(group) {} 148 149 virtual void Run() { 150 group_->ExecuteInThread(); 151 } 152 153 private: 154 SourceGroup* group_; 155 }; 156 157 static i::Thread::Options GetThreadOptions(); 158 void ExecuteInThread(); 159 160 i::Semaphore next_semaphore_; 161 i::Semaphore done_semaphore_; 162 i::Thread* thread_; 163 #endif // !V8_SHARED 164 165 void ExitShell(int exit_code); 166 Handle<String> ReadFile(Isolate* isolate, const char* name); 167 168 const char** argv_; 169 int begin_offset_; 170 int end_offset_; 171 }; 172 173 174 class BinaryResource : public v8::String::ExternalAsciiStringResource { 175 public: 176 BinaryResource(const char* string, int length) 177 : data_(string), 178 length_(length) { } 179 180 ~BinaryResource() { 181 delete[] data_; 182 data_ = NULL; 183 length_ = 0; 184 } 185 186 virtual const char* data() const { return data_; } 187 virtual size_t length() const { return length_; } 188 189 private: 190 const char* data_; 191 size_t length_; 192 }; 193 194 195 class ShellOptions { 196 public: 197 ShellOptions() : 198 script_executed(false), 199 last_run(true), 200 send_idle_notification(false), 201 invoke_weak_callbacks(false), 202 stress_opt(false), 203 stress_deopt(false), 204 interactive_shell(false), 205 test_shell(false), 206 dump_heap_constants(false), 207 expected_to_throw(false), 208 mock_arraybuffer_allocator(false), 209 num_isolates(1), 210 isolate_sources(NULL), 211 icu_data_file(NULL) { } 212 213 ~ShellOptions() { 214 delete[] isolate_sources; 215 } 216 217 bool use_interactive_shell() { 218 return (interactive_shell || !script_executed) && !test_shell; 219 } 220 221 bool script_executed; 222 bool last_run; 223 bool send_idle_notification; 224 bool invoke_weak_callbacks; 225 bool stress_opt; 226 bool stress_deopt; 227 bool interactive_shell; 228 bool test_shell; 229 bool dump_heap_constants; 230 bool expected_to_throw; 231 bool mock_arraybuffer_allocator; 232 int num_isolates; 233 SourceGroup* isolate_sources; 234 const char* icu_data_file; 235 }; 236 237 #ifdef V8_SHARED 238 class Shell { 239 #else 240 class Shell : public i::AllStatic { 241 #endif // V8_SHARED 242 243 public: 244 static bool ExecuteString(Isolate* isolate, 245 Handle<String> source, 246 Handle<Value> name, 247 bool print_result, 248 bool report_exceptions); 249 static const char* ToCString(const v8::String::Utf8Value& value); 250 static void ReportException(Isolate* isolate, TryCatch* try_catch); 251 static Handle<String> ReadFile(Isolate* isolate, const char* name); 252 static Local<Context> CreateEvaluationContext(Isolate* isolate); 253 static int RunMain(Isolate* isolate, int argc, char* argv[]); 254 static int Main(int argc, char* argv[]); 255 static void Exit(int exit_code); 256 static void OnExit(); 257 258 #ifndef V8_SHARED 259 static Handle<Array> GetCompletions(Isolate* isolate, 260 Handle<String> text, 261 Handle<String> full); 262 static int* LookupCounter(const char* name); 263 static void* CreateHistogram(const char* name, 264 int min, 265 int max, 266 size_t buckets); 267 static void AddHistogramSample(void* histogram, int sample); 268 static void MapCounters(v8::Isolate* isolate, const char* name); 269 270 static Local<Object> DebugMessageDetails(Isolate* isolate, 271 Handle<String> message); 272 static Local<Value> DebugCommandToJSONRequest(Isolate* isolate, 273 Handle<String> command); 274 275 static void PerformanceNow(const v8::FunctionCallbackInfo<v8::Value>& args); 276 #endif // !V8_SHARED 277 278 static void RealmCurrent(const v8::FunctionCallbackInfo<v8::Value>& args); 279 static void RealmOwner(const v8::FunctionCallbackInfo<v8::Value>& args); 280 static void RealmGlobal(const v8::FunctionCallbackInfo<v8::Value>& args); 281 static void RealmCreate(const v8::FunctionCallbackInfo<v8::Value>& args); 282 static void RealmDispose(const v8::FunctionCallbackInfo<v8::Value>& args); 283 static void RealmSwitch(const v8::FunctionCallbackInfo<v8::Value>& args); 284 static void RealmEval(const v8::FunctionCallbackInfo<v8::Value>& args); 285 static void RealmSharedGet(Local<String> property, 286 const PropertyCallbackInfo<Value>& info); 287 static void RealmSharedSet(Local<String> property, 288 Local<Value> value, 289 const PropertyCallbackInfo<void>& info); 290 291 static void Print(const v8::FunctionCallbackInfo<v8::Value>& args); 292 static void Write(const v8::FunctionCallbackInfo<v8::Value>& args); 293 static void Quit(const v8::FunctionCallbackInfo<v8::Value>& args); 294 static void Version(const v8::FunctionCallbackInfo<v8::Value>& args); 295 static void Read(const v8::FunctionCallbackInfo<v8::Value>& args); 296 static void ReadBuffer(const v8::FunctionCallbackInfo<v8::Value>& args); 297 static Handle<String> ReadFromStdin(Isolate* isolate); 298 static void ReadLine(const v8::FunctionCallbackInfo<v8::Value>& args) { 299 args.GetReturnValue().Set(ReadFromStdin(args.GetIsolate())); 300 } 301 static void Load(const v8::FunctionCallbackInfo<v8::Value>& args); 302 static void ArrayBuffer(const v8::FunctionCallbackInfo<v8::Value>& args); 303 static void Int8Array(const v8::FunctionCallbackInfo<v8::Value>& args); 304 static void Uint8Array(const v8::FunctionCallbackInfo<v8::Value>& args); 305 static void Int16Array(const v8::FunctionCallbackInfo<v8::Value>& args); 306 static void Uint16Array(const v8::FunctionCallbackInfo<v8::Value>& args); 307 static void Int32Array(const v8::FunctionCallbackInfo<v8::Value>& args); 308 static void Uint32Array(const v8::FunctionCallbackInfo<v8::Value>& args); 309 static void Float32Array(const v8::FunctionCallbackInfo<v8::Value>& args); 310 static void Float64Array(const v8::FunctionCallbackInfo<v8::Value>& args); 311 static void Uint8ClampedArray( 312 const v8::FunctionCallbackInfo<v8::Value>& args); 313 static void ArrayBufferSlice(const v8::FunctionCallbackInfo<v8::Value>& args); 314 static void ArraySubArray(const v8::FunctionCallbackInfo<v8::Value>& args); 315 static void ArraySet(const v8::FunctionCallbackInfo<v8::Value>& args); 316 // The OS object on the global object contains methods for performing 317 // operating system calls: 318 // 319 // os.system("program_name", ["arg1", "arg2", ...], timeout1, timeout2) will 320 // run the command, passing the arguments to the program. The standard output 321 // of the program will be picked up and returned as a multiline string. If 322 // timeout1 is present then it should be a number. -1 indicates no timeout 323 // and a positive number is used as a timeout in milliseconds that limits the 324 // time spent waiting between receiving output characters from the program. 325 // timeout2, if present, should be a number indicating the limit in 326 // milliseconds on the total running time of the program. Exceptions are 327 // thrown on timeouts or other errors or if the exit status of the program 328 // indicates an error. 329 // 330 // os.chdir(dir) changes directory to the given directory. Throws an 331 // exception/ on error. 332 // 333 // os.setenv(variable, value) sets an environment variable. Repeated calls to 334 // this method leak memory due to the API of setenv in the standard C library. 335 // 336 // os.umask(alue) calls the umask system call and returns the old umask. 337 // 338 // os.mkdirp(name, mask) creates a directory. The mask (if present) is anded 339 // with the current umask. Intermediate directories are created if necessary. 340 // An exception is not thrown if the directory already exists. Analogous to 341 // the "mkdir -p" command. 342 static void OSObject(const v8::FunctionCallbackInfo<v8::Value>& args); 343 static void System(const v8::FunctionCallbackInfo<v8::Value>& args); 344 static void ChangeDirectory(const v8::FunctionCallbackInfo<v8::Value>& args); 345 static void SetEnvironment(const v8::FunctionCallbackInfo<v8::Value>& args); 346 static void UnsetEnvironment(const v8::FunctionCallbackInfo<v8::Value>& args); 347 static void SetUMask(const v8::FunctionCallbackInfo<v8::Value>& args); 348 static void MakeDirectory(const v8::FunctionCallbackInfo<v8::Value>& args); 349 static void RemoveDirectory(const v8::FunctionCallbackInfo<v8::Value>& args); 350 351 static void AddOSMethods(v8::Isolate* isolate, 352 Handle<ObjectTemplate> os_template); 353 354 static const char* kPrompt; 355 static ShellOptions options; 356 357 private: 358 static Persistent<Context> evaluation_context_; 359 #ifndef V8_SHARED 360 static Persistent<Context> utility_context_; 361 static CounterMap* counter_map_; 362 // We statically allocate a set of local counters to be used if we 363 // don't want to store the stats in a memory-mapped file 364 static CounterCollection local_counters_; 365 static CounterCollection* counters_; 366 static i::OS::MemoryMappedFile* counters_file_; 367 static i::Mutex context_mutex_; 368 static const i::TimeTicks kInitialTicks; 369 370 static Counter* GetCounter(const char* name, bool is_histogram); 371 static void InstallUtilityScript(Isolate* isolate); 372 #endif // !V8_SHARED 373 static void Initialize(Isolate* isolate); 374 static void InitializeDebugger(Isolate* isolate); 375 static void RunShell(Isolate* isolate); 376 static bool SetOptions(int argc, char* argv[]); 377 static Handle<ObjectTemplate> CreateGlobalTemplate(Isolate* isolate); 378 static Handle<FunctionTemplate> CreateArrayBufferTemplate(FunctionCallback); 379 static Handle<FunctionTemplate> CreateArrayTemplate(FunctionCallback); 380 static Handle<Value> CreateExternalArrayBuffer(Isolate* isolate, 381 Handle<Object> buffer, 382 int32_t size); 383 static Handle<Object> CreateExternalArray(Isolate* isolate, 384 Handle<Object> array, 385 Handle<Object> buffer, 386 ExternalArrayType type, 387 int32_t length, 388 int32_t byteLength, 389 int32_t byteOffset, 390 int32_t element_size); 391 static void CreateExternalArray( 392 const v8::FunctionCallbackInfo<v8::Value>& args, 393 ExternalArrayType type, 394 int32_t element_size); 395 static void ExternalArrayWeakCallback(Isolate* isolate, 396 Persistent<Object>* object, 397 uint8_t* data); 398 }; 399 400 401 } // namespace v8 402 403 404 #endif // V8_D8_H_ 405