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