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_(v8::internal::OS::CreateSemaphore(0)), 144 done_semaphore_(v8::internal::OS::CreateSemaphore(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 use_preemption(true), 223 preemption_interval(10), 224 num_parallel_files(0), 225 parallel_files(NULL), 226 #endif // V8_SHARED 227 script_executed(false), 228 last_run(true), 229 send_idle_notification(false), 230 stress_opt(false), 231 stress_deopt(false), 232 interactive_shell(false), 233 test_shell(false), 234 dump_heap_constants(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 bool use_preemption; 247 int preemption_interval; 248 int num_parallel_files; 249 char** parallel_files; 250 #endif // V8_SHARED 251 bool script_executed; 252 bool last_run; 253 bool send_idle_notification; 254 bool stress_opt; 255 bool stress_deopt; 256 bool interactive_shell; 257 bool test_shell; 258 bool dump_heap_constants; 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 #endif // V8_SHARED 304 305 static void RealmCurrent(const v8::FunctionCallbackInfo<v8::Value>& args); 306 static void RealmOwner(const v8::FunctionCallbackInfo<v8::Value>& args); 307 static void RealmGlobal(const v8::FunctionCallbackInfo<v8::Value>& args); 308 static void RealmCreate(const v8::FunctionCallbackInfo<v8::Value>& args); 309 static void RealmDispose(const v8::FunctionCallbackInfo<v8::Value>& args); 310 static void RealmSwitch(const v8::FunctionCallbackInfo<v8::Value>& args); 311 static void RealmEval(const v8::FunctionCallbackInfo<v8::Value>& args); 312 static void RealmSharedGet(Local<String> property, 313 const PropertyCallbackInfo<Value>& info); 314 static void RealmSharedSet(Local<String> property, 315 Local<Value> value, 316 const PropertyCallbackInfo<void>& info); 317 318 static void Print(const v8::FunctionCallbackInfo<v8::Value>& args); 319 static void Write(const v8::FunctionCallbackInfo<v8::Value>& args); 320 static void Quit(const v8::FunctionCallbackInfo<v8::Value>& args); 321 static void Version(const v8::FunctionCallbackInfo<v8::Value>& args); 322 static void Read(const v8::FunctionCallbackInfo<v8::Value>& args); 323 static void ReadBuffer(const v8::FunctionCallbackInfo<v8::Value>& args); 324 static Handle<String> ReadFromStdin(Isolate* isolate); 325 static void ReadLine(const v8::FunctionCallbackInfo<v8::Value>& args) { 326 args.GetReturnValue().Set(ReadFromStdin(args.GetIsolate())); 327 } 328 static void Load(const v8::FunctionCallbackInfo<v8::Value>& args); 329 static void ArrayBuffer(const v8::FunctionCallbackInfo<v8::Value>& args); 330 static void Int8Array(const v8::FunctionCallbackInfo<v8::Value>& args); 331 static void Uint8Array(const v8::FunctionCallbackInfo<v8::Value>& args); 332 static void Int16Array(const v8::FunctionCallbackInfo<v8::Value>& args); 333 static void Uint16Array(const v8::FunctionCallbackInfo<v8::Value>& args); 334 static void Int32Array(const v8::FunctionCallbackInfo<v8::Value>& args); 335 static void Uint32Array(const v8::FunctionCallbackInfo<v8::Value>& args); 336 static void Float32Array(const v8::FunctionCallbackInfo<v8::Value>& args); 337 static void Float64Array(const v8::FunctionCallbackInfo<v8::Value>& args); 338 static void Uint8ClampedArray( 339 const v8::FunctionCallbackInfo<v8::Value>& args); 340 static void ArrayBufferSlice(const v8::FunctionCallbackInfo<v8::Value>& args); 341 static void ArraySubArray(const v8::FunctionCallbackInfo<v8::Value>& args); 342 static void ArraySet(const v8::FunctionCallbackInfo<v8::Value>& args); 343 // The OS object on the global object contains methods for performing 344 // operating system calls: 345 // 346 // os.system("program_name", ["arg1", "arg2", ...], timeout1, timeout2) will 347 // run the command, passing the arguments to the program. The standard output 348 // of the program will be picked up and returned as a multiline string. If 349 // timeout1 is present then it should be a number. -1 indicates no timeout 350 // and a positive number is used as a timeout in milliseconds that limits the 351 // time spent waiting between receiving output characters from the program. 352 // timeout2, if present, should be a number indicating the limit in 353 // milliseconds on the total running time of the program. Exceptions are 354 // thrown on timeouts or other errors or if the exit status of the program 355 // indicates an error. 356 // 357 // os.chdir(dir) changes directory to the given directory. Throws an 358 // exception/ on error. 359 // 360 // os.setenv(variable, value) sets an environment variable. Repeated calls to 361 // this method leak memory due to the API of setenv in the standard C library. 362 // 363 // os.umask(alue) calls the umask system call and returns the old umask. 364 // 365 // os.mkdirp(name, mask) creates a directory. The mask (if present) is anded 366 // with the current umask. Intermediate directories are created if necessary. 367 // An exception is not thrown if the directory already exists. Analogous to 368 // the "mkdir -p" command. 369 static void OSObject(const v8::FunctionCallbackInfo<v8::Value>& args); 370 static void System(const v8::FunctionCallbackInfo<v8::Value>& args); 371 static void ChangeDirectory(const v8::FunctionCallbackInfo<v8::Value>& args); 372 static void SetEnvironment(const v8::FunctionCallbackInfo<v8::Value>& args); 373 static void UnsetEnvironment(const v8::FunctionCallbackInfo<v8::Value>& args); 374 static void SetUMask(const v8::FunctionCallbackInfo<v8::Value>& args); 375 static void MakeDirectory(const v8::FunctionCallbackInfo<v8::Value>& args); 376 static void RemoveDirectory(const v8::FunctionCallbackInfo<v8::Value>& args); 377 378 static void AddOSMethods(Handle<ObjectTemplate> os_template); 379 380 static const char* kPrompt; 381 static ShellOptions options; 382 383 private: 384 static Persistent<Context> evaluation_context_; 385 #ifndef V8_SHARED 386 static Persistent<Context> utility_context_; 387 static CounterMap* counter_map_; 388 // We statically allocate a set of local counters to be used if we 389 // don't want to store the stats in a memory-mapped file 390 static CounterCollection local_counters_; 391 static CounterCollection* counters_; 392 static i::OS::MemoryMappedFile* counters_file_; 393 static i::Mutex* context_mutex_; 394 395 static Counter* GetCounter(const char* name, bool is_histogram); 396 static void InstallUtilityScript(Isolate* isolate); 397 #endif // V8_SHARED 398 static void Initialize(Isolate* isolate); 399 static void InitializeDebugger(Isolate* isolate); 400 static void RunShell(Isolate* isolate); 401 static bool SetOptions(int argc, char* argv[]); 402 static Handle<ObjectTemplate> CreateGlobalTemplate(Isolate* isolate); 403 static Handle<FunctionTemplate> CreateArrayBufferTemplate(InvocationCallback); 404 static Handle<FunctionTemplate> CreateArrayTemplate(InvocationCallback); 405 static Handle<Value> CreateExternalArrayBuffer(Isolate* isolate, 406 Handle<Object> buffer, 407 int32_t size); 408 static Handle<Object> CreateExternalArray(Isolate* isolate, 409 Handle<Object> array, 410 Handle<Object> buffer, 411 ExternalArrayType type, 412 int32_t length, 413 int32_t byteLength, 414 int32_t byteOffset, 415 int32_t element_size); 416 static void CreateExternalArray( 417 const v8::FunctionCallbackInfo<v8::Value>& args, 418 ExternalArrayType type, 419 int32_t element_size); 420 static void ExternalArrayWeakCallback(Isolate* isolate, 421 Persistent<Object>* object, 422 uint8_t* data); 423 }; 424 425 426 } // namespace v8 427 428 429 #endif // V8_D8_H_ 430