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