blob: 840ca1e8fd4899c190342ffdb361d3bcd33a3de4 [file] [log] [blame]
Steve Blocka7e24c12009-10-30 11:49:00 +00001// Copyright 2009 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
Steve Blocka7e24c12009-10-30 11:49:00 +000031
Ben Murdoch3fb3ca82011-12-02 17:19:32 +000032#ifndef USING_V8_SHARED
33#include "v8.h"
34#include "allocation.h"
35#include "hashmap.h"
36#else
37#include "../include/v8.h"
38#endif // USING_V8_SHARED
Steve Blocka7e24c12009-10-30 11:49:00 +000039
40namespace v8 {
41
Ben Murdoch3fb3ca82011-12-02 17:19:32 +000042#ifndef USING_V8_SHARED
Steve Blocka7e24c12009-10-30 11:49:00 +000043namespace i = v8::internal;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +000044#endif // USING_V8_SHARED
Steve Blocka7e24c12009-10-30 11:49:00 +000045
46
Ben Murdoch3fb3ca82011-12-02 17:19:32 +000047#ifndef USING_V8_SHARED
Steve Blocka7e24c12009-10-30 11:49:00 +000048// A single counter in a counter collection.
49class Counter {
50 public:
51 static const int kMaxNameSize = 64;
52 int32_t* Bind(const char* name, bool histogram);
53 int32_t* ptr() { return &count_; }
54 int32_t count() { return count_; }
55 int32_t sample_total() { return sample_total_; }
56 bool is_histogram() { return is_histogram_; }
57 void AddSample(int32_t sample);
58 private:
59 int32_t count_;
60 int32_t sample_total_;
61 bool is_histogram_;
62 uint8_t name_[kMaxNameSize];
63};
64
65
66// A set of counters and associated information. An instance of this
67// class is stored directly in the memory-mapped counters file if
68// the --map-counters options is used
69class CounterCollection {
70 public:
71 CounterCollection();
72 Counter* GetNextCounter();
73 private:
74 static const unsigned kMaxCounters = 256;
75 uint32_t magic_number_;
76 uint32_t max_counters_;
77 uint32_t max_name_size_;
78 uint32_t counters_in_use_;
79 Counter counters_[kMaxCounters];
80};
81
82
83class CounterMap {
84 public:
85 CounterMap(): hash_map_(Match) { }
86 Counter* Lookup(const char* name) {
87 i::HashMap::Entry* answer = hash_map_.Lookup(
88 const_cast<char*>(name),
89 Hash(name),
90 false);
91 if (!answer) return NULL;
92 return reinterpret_cast<Counter*>(answer->value);
93 }
94 void Set(const char* name, Counter* value) {
95 i::HashMap::Entry* answer = hash_map_.Lookup(
96 const_cast<char*>(name),
97 Hash(name),
98 true);
99 ASSERT(answer != NULL);
100 answer->value = value;
101 }
102 class Iterator {
103 public:
104 explicit Iterator(CounterMap* map)
105 : map_(&map->hash_map_), entry_(map_->Start()) { }
106 void Next() { entry_ = map_->Next(entry_); }
107 bool More() { return entry_ != NULL; }
108 const char* CurrentKey() { return static_cast<const char*>(entry_->key); }
109 Counter* CurrentValue() { return static_cast<Counter*>(entry_->value); }
110 private:
111 i::HashMap* map_;
112 i::HashMap::Entry* entry_;
113 };
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000114
Steve Blocka7e24c12009-10-30 11:49:00 +0000115 private:
116 static int Hash(const char* name);
117 static bool Match(void* key1, void* key2);
118 i::HashMap hash_map_;
119};
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000120#endif // USING_V8_SHARED
Steve Blocka7e24c12009-10-30 11:49:00 +0000121
122
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000123class SourceGroup {
124 public:
125 SourceGroup() :
126#ifndef USING_V8_SHARED
127 next_semaphore_(v8::internal::OS::CreateSemaphore(0)),
128 done_semaphore_(v8::internal::OS::CreateSemaphore(0)),
129 thread_(NULL),
130#endif // USING_V8_SHARED
131 argv_(NULL),
132 begin_offset_(0),
133 end_offset_(0) { }
134
135 void Begin(char** argv, int offset) {
136 argv_ = const_cast<const char**>(argv);
137 begin_offset_ = offset;
138 }
139
140 void End(int offset) { end_offset_ = offset; }
141
142 void Execute();
143
144#ifndef USING_V8_SHARED
145 void StartExecuteInThread();
146 void WaitForThread();
147
148 private:
149 class IsolateThread : public i::Thread {
150 public:
151 explicit IsolateThread(SourceGroup* group)
152 : i::Thread(GetThreadOptions()), group_(group) {}
153
154 virtual void Run() {
155 group_->ExecuteInThread();
156 }
157
158 private:
159 SourceGroup* group_;
160 };
161
162 static i::Thread::Options GetThreadOptions();
163 void ExecuteInThread();
164
165 i::Semaphore* next_semaphore_;
166 i::Semaphore* done_semaphore_;
167 i::Thread* thread_;
168#endif // USING_V8_SHARED
169
170 void ExitShell(int exit_code);
171 Handle<String> ReadFile(const char* name);
172
173 const char** argv_;
174 int begin_offset_;
175 int end_offset_;
176};
177
178
179class ShellOptions {
180 public:
181 ShellOptions() :
182#ifndef USING_V8_SHARED
183 use_preemption(true),
184 preemption_interval(10),
185 parallel_files(NULL),
186#endif // USING_V8_SHARED
187 script_executed(false),
188 last_run(true),
189 stress_opt(false),
190 stress_deopt(false),
191 interactive_shell(false),
192 test_shell(false),
193 num_isolates(1),
194 isolate_sources(NULL) { }
195
196#ifndef USING_V8_SHARED
197 bool use_preemption;
198 int preemption_interval;
199 i::List< i::Vector<const char> >* parallel_files;
200#endif // USING_V8_SHARED
201 bool script_executed;
202 bool last_run;
203 bool stress_opt;
204 bool stress_deopt;
205 bool interactive_shell;
206 bool test_shell;
207 int num_isolates;
208 SourceGroup* isolate_sources;
209};
210
211#ifdef USING_V8_SHARED
212class Shell {
213#else
214class Shell : public i::AllStatic {
215#endif // USING_V8_SHARED
Steve Blocka7e24c12009-10-30 11:49:00 +0000216 public:
217 static bool ExecuteString(Handle<String> source,
218 Handle<Value> name,
219 bool print_result,
220 bool report_exceptions);
Steve Block6ded16b2010-05-10 14:33:55 +0100221 static const char* ToCString(const v8::String::Utf8Value& value);
Steve Blocka7e24c12009-10-30 11:49:00 +0000222 static void ReportException(TryCatch* try_catch);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000223 static Handle<String> ReadFile(const char* name);
224 static Persistent<Context> CreateEvaluationContext();
225 static int RunMain(int argc, char* argv[]);
226 static int Main(int argc, char* argv[]);
227
228#ifndef USING_V8_SHARED
229 static Handle<Array> GetCompletions(Handle<String> text,
230 Handle<String> full);
Steve Blocka7e24c12009-10-30 11:49:00 +0000231 static void OnExit();
232 static int* LookupCounter(const char* name);
233 static void* CreateHistogram(const char* name,
234 int min,
235 int max,
236 size_t buckets);
237 static void AddHistogramSample(void* histogram, int sample);
238 static void MapCounters(const char* name);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000239#endif // USING_V8_SHARED
240
Steve Blocka7e24c12009-10-30 11:49:00 +0000241#ifdef ENABLE_DEBUGGER_SUPPORT
242 static Handle<Object> DebugMessageDetails(Handle<String> message);
243 static Handle<Value> DebugCommandToJSONRequest(Handle<String> command);
244#endif
245
Ben Murdochb0fe1622011-05-05 13:52:32 +0100246#ifdef WIN32
247#undef Yield
248#endif
249
Steve Blocka7e24c12009-10-30 11:49:00 +0000250 static Handle<Value> Print(const Arguments& args);
251 static Handle<Value> Write(const Arguments& args);
252 static Handle<Value> Yield(const Arguments& args);
253 static Handle<Value> Quit(const Arguments& args);
254 static Handle<Value> Version(const Arguments& args);
255 static Handle<Value> Read(const Arguments& args);
256 static Handle<Value> ReadLine(const Arguments& args);
257 static Handle<Value> Load(const Arguments& args);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000258 static Handle<Value> Int8Array(const Arguments& args);
259 static Handle<Value> Uint8Array(const Arguments& args);
260 static Handle<Value> Int16Array(const Arguments& args);
261 static Handle<Value> Uint16Array(const Arguments& args);
262 static Handle<Value> Int32Array(const Arguments& args);
263 static Handle<Value> Uint32Array(const Arguments& args);
264 static Handle<Value> Float32Array(const Arguments& args);
265 static Handle<Value> Float64Array(const Arguments& args);
266 static Handle<Value> PixelArray(const Arguments& args);
Steve Blocka7e24c12009-10-30 11:49:00 +0000267 // The OS object on the global object contains methods for performing
268 // operating system calls:
269 //
270 // os.system("program_name", ["arg1", "arg2", ...], timeout1, timeout2) will
271 // run the command, passing the arguments to the program. The standard output
272 // of the program will be picked up and returned as a multiline string. If
273 // timeout1 is present then it should be a number. -1 indicates no timeout
274 // and a positive number is used as a timeout in milliseconds that limits the
275 // time spent waiting between receiving output characters from the program.
276 // timeout2, if present, should be a number indicating the limit in
277 // milliseconds on the total running time of the program. Exceptions are
278 // thrown on timeouts or other errors or if the exit status of the program
279 // indicates an error.
280 //
281 // os.chdir(dir) changes directory to the given directory. Throws an
282 // exception/ on error.
283 //
284 // os.setenv(variable, value) sets an environment variable. Repeated calls to
285 // this method leak memory due to the API of setenv in the standard C library.
286 //
287 // os.umask(alue) calls the umask system call and returns the old umask.
288 //
289 // os.mkdirp(name, mask) creates a directory. The mask (if present) is anded
290 // with the current umask. Intermediate directories are created if necessary.
291 // An exception is not thrown if the directory already exists. Analogous to
292 // the "mkdir -p" command.
293 static Handle<Value> OSObject(const Arguments& args);
294 static Handle<Value> System(const Arguments& args);
295 static Handle<Value> ChangeDirectory(const Arguments& args);
296 static Handle<Value> SetEnvironment(const Arguments& args);
Steve Block6ded16b2010-05-10 14:33:55 +0100297 static Handle<Value> UnsetEnvironment(const Arguments& args);
Steve Blocka7e24c12009-10-30 11:49:00 +0000298 static Handle<Value> SetUMask(const Arguments& args);
299 static Handle<Value> MakeDirectory(const Arguments& args);
300 static Handle<Value> RemoveDirectory(const Arguments& args);
301
302 static void AddOSMethods(Handle<ObjectTemplate> os_template);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000303#ifndef USING_V8_SHARED
Steve Blocka7e24c12009-10-30 11:49:00 +0000304 static const char* kHistoryFileName;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000305#endif // USING_V8_SHARED
Steve Blocka7e24c12009-10-30 11:49:00 +0000306 static const char* kPrompt;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000307 static ShellOptions options;
308
Steve Blocka7e24c12009-10-30 11:49:00 +0000309 private:
Steve Blocka7e24c12009-10-30 11:49:00 +0000310 static Persistent<Context> evaluation_context_;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000311#ifndef USING_V8_SHARED
312 static Persistent<Context> utility_context_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000313 static CounterMap* counter_map_;
314 // We statically allocate a set of local counters to be used if we
315 // don't want to store the stats in a memory-mapped file
316 static CounterCollection local_counters_;
317 static CounterCollection* counters_;
318 static i::OS::MemoryMappedFile* counters_file_;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000319 static i::Mutex* context_mutex_;
320
Steve Blocka7e24c12009-10-30 11:49:00 +0000321 static Counter* GetCounter(const char* name, bool is_histogram);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000322 static void InstallUtilityScript();
323#endif // USING_V8_SHARED
324 static void Initialize();
325 static void RunShell();
326 static bool SetOptions(int argc, char* argv[]);
327 static Handle<ObjectTemplate> CreateGlobalTemplate();
328 static Handle<Value> CreateExternalArray(const Arguments& args,
329 ExternalArrayType type,
330 size_t element_size);
331 static void ExternalArrayWeakCallback(Persistent<Value> object, void* data);
Steve Blocka7e24c12009-10-30 11:49:00 +0000332};
333
334
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000335#ifndef USING_V8_SHARED
Steve Blocka7e24c12009-10-30 11:49:00 +0000336class LineEditor {
337 public:
338 enum Type { DUMB = 0, READLINE = 1 };
339 LineEditor(Type type, const char* name);
340 virtual ~LineEditor() { }
341
342 virtual i::SmartPointer<char> Prompt(const char* prompt) = 0;
343 virtual bool Open() { return true; }
344 virtual bool Close() { return true; }
345 virtual void AddHistory(const char* str) { }
346
347 const char* name() { return name_; }
348 static LineEditor* Get();
349 private:
350 Type type_;
351 const char* name_;
352 LineEditor* next_;
353 static LineEditor* first_;
354};
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000355#endif // USING_V8_SHARED
Steve Blocka7e24c12009-10-30 11:49:00 +0000356
357
358} // namespace v8
359
360
361#endif // V8_D8_H_