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-array-pointer.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); ptr()49 int32_t* ptr() { return &count_; } count()50 int32_t count() { return count_; } sample_total()51 int32_t sample_total() { return sample_total_; } is_histogram()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 = 256; 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: CounterMap()81 CounterMap(): hash_map_(Match) { } Lookup(const char * name)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 } Set(const char * name,Counter * value)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: Iterator(CounterMap * map)100 explicit Iterator(CounterMap* map) 101 : map_(&map->hash_map_), entry_(map_->Start()) { } Next()102 void Next() { entry_ = map_->Next(entry_); } More()103 bool More() { return entry_ != NULL; } CurrentKey()104 const char* CurrentKey() { return static_cast<const char*>(entry_->key); } CurrentValue()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); ~LineEditor()123 virtual ~LineEditor() { } 124 125 virtual Handle<String> Prompt(const char* prompt) = 0; Open()126 virtual bool Open() { return true; } Close()127 virtual bool Close() { return true; } AddHistory(const char * str)128 virtual void AddHistory(const char* str) { } 129 name()130 const char* name() { return name_; } 131 static LineEditor* Get(); 132 private: 133 Type type_; 134 const char* name_; 135 LineEditor* next_; 136 static LineEditor* first_; 137 }; 138 139 140 class SourceGroup { 141 public: SourceGroup()142 SourceGroup() : 143 #ifndef V8_SHARED 144 next_semaphore_(v8::internal::OS::CreateSemaphore(0)), 145 done_semaphore_(v8::internal::OS::CreateSemaphore(0)), 146 thread_(NULL), 147 #endif // V8_SHARED 148 argv_(NULL), 149 begin_offset_(0), 150 end_offset_(0) {} 151 152 ~SourceGroup(); 153 Begin(char ** argv,int offset)154 void Begin(char** argv, int offset) { 155 argv_ = const_cast<const char**>(argv); 156 begin_offset_ = offset; 157 } 158 End(int offset)159 void End(int offset) { end_offset_ = offset; } 160 161 void Execute(); 162 163 #ifndef V8_SHARED 164 void StartExecuteInThread(); 165 void WaitForThread(); 166 167 private: 168 class IsolateThread : public i::Thread { 169 public: IsolateThread(SourceGroup * group)170 explicit IsolateThread(SourceGroup* group) 171 : i::Thread(GetThreadOptions()), group_(group) {} 172 Run()173 virtual void Run() { 174 group_->ExecuteInThread(); 175 } 176 177 private: 178 SourceGroup* group_; 179 }; 180 181 static i::Thread::Options GetThreadOptions(); 182 void ExecuteInThread(); 183 184 i::Semaphore* next_semaphore_; 185 i::Semaphore* done_semaphore_; 186 i::Thread* thread_; 187 #endif // V8_SHARED 188 189 void ExitShell(int exit_code); 190 Handle<String> ReadFile(const char* name); 191 192 const char** argv_; 193 int begin_offset_; 194 int end_offset_; 195 }; 196 197 198 class BinaryResource : public v8::String::ExternalAsciiStringResource { 199 public: BinaryResource(const char * string,int length)200 BinaryResource(const char* string, int length) 201 : data_(string), 202 length_(length) { } 203 ~BinaryResource()204 ~BinaryResource() { 205 delete[] data_; 206 data_ = NULL; 207 length_ = 0; 208 } 209 data()210 virtual const char* data() const { return data_; } length()211 virtual size_t length() const { return length_; } 212 213 private: 214 const char* data_; 215 size_t length_; 216 }; 217 218 219 class ShellOptions { 220 public: ShellOptions()221 ShellOptions() : 222 #ifndef V8_SHARED 223 use_preemption(true), 224 preemption_interval(10), 225 num_parallel_files(0), 226 parallel_files(NULL), 227 #endif // V8_SHARED 228 script_executed(false), 229 last_run(true), 230 stress_opt(false), 231 stress_deopt(false), 232 interactive_shell(false), 233 test_shell(false), 234 num_isolates(1), 235 isolate_sources(NULL) { } 236 ~ShellOptions()237 ~ShellOptions() { 238 #ifndef V8_SHARED 239 delete[] parallel_files; 240 #endif // V8_SHARED 241 delete[] isolate_sources; 242 } 243 244 #ifndef V8_SHARED 245 bool use_preemption; 246 int preemption_interval; 247 int num_parallel_files; 248 char** parallel_files; 249 #endif // V8_SHARED 250 bool script_executed; 251 bool last_run; 252 bool stress_opt; 253 bool stress_deopt; 254 bool interactive_shell; 255 bool test_shell; 256 int num_isolates; 257 SourceGroup* isolate_sources; 258 }; 259 260 #ifdef V8_SHARED 261 class Shell { 262 #else 263 class Shell : public i::AllStatic { 264 #endif // V8_SHARED 265 266 public: 267 static bool ExecuteString(Handle<String> source, 268 Handle<Value> name, 269 bool print_result, 270 bool report_exceptions); 271 static const char* ToCString(const v8::String::Utf8Value& value); 272 static void ReportException(TryCatch* try_catch); 273 static Handle<String> ReadFile(const char* name); 274 static Persistent<Context> CreateEvaluationContext(); 275 static int RunMain(int argc, char* argv[]); 276 static int Main(int argc, char* argv[]); 277 static void Exit(int exit_code); 278 279 #ifndef V8_SHARED 280 static Handle<Array> GetCompletions(Handle<String> text, 281 Handle<String> full); 282 static void OnExit(); 283 static int* LookupCounter(const char* name); 284 static void* CreateHistogram(const char* name, 285 int min, 286 int max, 287 size_t buckets); 288 static void AddHistogramSample(void* histogram, int sample); 289 static void MapCounters(const char* name); 290 291 #ifdef ENABLE_DEBUGGER_SUPPORT 292 static Handle<Object> DebugMessageDetails(Handle<String> message); 293 static Handle<Value> DebugCommandToJSONRequest(Handle<String> command); 294 static void DispatchDebugMessages(); 295 #endif // ENABLE_DEBUGGER_SUPPORT 296 #endif // V8_SHARED 297 298 #ifdef WIN32 299 #undef Yield 300 #endif 301 302 static Handle<Value> Print(const Arguments& args); 303 static Handle<Value> Write(const Arguments& args); 304 static Handle<Value> Yield(const Arguments& args); 305 static Handle<Value> Quit(const Arguments& args); 306 static Handle<Value> Version(const Arguments& args); 307 static Handle<Value> EnableProfiler(const Arguments& args); 308 static Handle<Value> DisableProfiler(const Arguments& args); 309 static Handle<Value> Read(const Arguments& args); 310 static Handle<Value> ReadBinary(const Arguments& args); 311 static Handle<String> ReadFromStdin(); ReadLine(const Arguments & args)312 static Handle<Value> ReadLine(const Arguments& args) { 313 return ReadFromStdin(); 314 } 315 static Handle<Value> Load(const Arguments& args); 316 static Handle<Value> ArrayBuffer(const Arguments& args); 317 static Handle<Value> Int8Array(const Arguments& args); 318 static Handle<Value> Uint8Array(const Arguments& args); 319 static Handle<Value> Int16Array(const Arguments& args); 320 static Handle<Value> Uint16Array(const Arguments& args); 321 static Handle<Value> Int32Array(const Arguments& args); 322 static Handle<Value> Uint32Array(const Arguments& args); 323 static Handle<Value> Float32Array(const Arguments& args); 324 static Handle<Value> Float64Array(const Arguments& args); 325 static Handle<Value> PixelArray(const Arguments& 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 Handle<Value> OSObject(const Arguments& args); 353 static Handle<Value> System(const Arguments& args); 354 static Handle<Value> ChangeDirectory(const Arguments& args); 355 static Handle<Value> SetEnvironment(const Arguments& args); 356 static Handle<Value> UnsetEnvironment(const Arguments& args); 357 static Handle<Value> SetUMask(const Arguments& args); 358 static Handle<Value> MakeDirectory(const Arguments& args); 359 static Handle<Value> RemoveDirectory(const Arguments& args); 360 361 static void AddOSMethods(Handle<ObjectTemplate> os_template); 362 363 static LineEditor* console; 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 i::OS::MemoryMappedFile* counters_file_; 377 static i::Mutex* context_mutex_; 378 379 static Counter* GetCounter(const char* name, bool is_histogram); 380 static void InstallUtilityScript(); 381 #endif // V8_SHARED 382 static void Initialize(); 383 static void RunShell(); 384 static bool SetOptions(int argc, char* argv[]); 385 static Handle<ObjectTemplate> CreateGlobalTemplate(); 386 static Handle<Value> CreateExternalArray(const Arguments& args, 387 ExternalArrayType type, 388 size_t element_size); 389 static void ExternalArrayWeakCallback(Persistent<Value> object, void* data); 390 }; 391 392 393 } // namespace v8 394 395 396 #endif // V8_D8_H_ 397