Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(885)

Side by Side Diff: samples/shell.cc

Issue 7354022: Simplified the sample shell. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution. 11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its 12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived 13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission. 14 // from this software without specific prior written permission.
15 // 15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 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. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 #include <v8.h> 28 #include <v8.h>
29 #include <v8-testing.h>
30 #include <assert.h> 29 #include <assert.h>
31 #ifdef COMPRESS_STARTUP_DATA_BZ2
32 #include <bzlib.h>
33 #endif
34 #include <fcntl.h> 30 #include <fcntl.h>
35 #include <string.h> 31 #include <string.h>
36 #include <stdio.h> 32 #include <stdio.h>
37 #include <stdlib.h> 33 #include <stdlib.h>
38 34
39 // When building with V8 in a shared library we cannot use functions which 35 #ifdef COMPRESS_STARTUP_DATA_BZ2
40 // is not explicitly a part of the public V8 API. This extensive use of 36 #error Using compressed startup data is not supported for this sample
41 // #ifndef USING_V8_SHARED/#endif is a hack until we can resolve whether to
42 // still use the shell sample for testing or change to use the developer
43 // shell d8 TODO(1272).
44 #if !(defined(USING_V8_SHARED) || defined(V8_SHARED))
45 #include "../src/v8.h"
46 #endif // USING_V8_SHARED
47
48 #if !defined(_WIN32) && !defined(_WIN64)
49 #include <unistd.h> // NOLINT
50 #endif 37 #endif
51 38
52 static void ExitShell(int exit_code) { 39 /**
Yang 2011/07/13 16:08:46 Removed since there is no longer multi-threading.
53 // Use _exit instead of exit to avoid races between isolate 40 * This sample program shows how to implement a simple javascript shell
54 // threads and static destructors. 41 * based on V8. This includes initializing V8 with command line options,
55 fflush(stdout); 42 * creating global functions, compiling and executing strings.
56 fflush(stderr); 43 *
57 _exit(exit_code); 44 * For a more sophisticated shell, consider using the debug shell D8.
58 } 45 */
46
59 47
60 v8::Persistent<v8::Context> CreateShellContext(); 48 v8::Persistent<v8::Context> CreateShellContext();
61 void RunShell(v8::Handle<v8::Context> context); 49 void RunShell(v8::Handle<v8::Context> context);
50 int RunMain(int argc, char* argv[]);
62 bool ExecuteString(v8::Handle<v8::String> source, 51 bool ExecuteString(v8::Handle<v8::String> source,
63 v8::Handle<v8::Value> name, 52 v8::Handle<v8::Value> name,
64 bool print_result, 53 bool print_result,
65 bool report_exceptions); 54 bool report_exceptions);
66 v8::Handle<v8::Value> Print(const v8::Arguments& args); 55 v8::Handle<v8::Value> Print(const v8::Arguments& args);
67 v8::Handle<v8::Value> Read(const v8::Arguments& args); 56 v8::Handle<v8::Value> Read(const v8::Arguments& args);
68 v8::Handle<v8::Value> Load(const v8::Arguments& args); 57 v8::Handle<v8::Value> Load(const v8::Arguments& args);
69 v8::Handle<v8::Value> Quit(const v8::Arguments& args); 58 v8::Handle<v8::Value> Quit(const v8::Arguments& args);
70 v8::Handle<v8::Value> Version(const v8::Arguments& args); 59 v8::Handle<v8::Value> Version(const v8::Arguments& args);
71 v8::Handle<v8::Value> Int8Array(const v8::Arguments& args);
Yang 2011/07/13 16:08:46 Removed external arrays completely.
72 v8::Handle<v8::Value> Uint8Array(const v8::Arguments& args);
73 v8::Handle<v8::Value> Int16Array(const v8::Arguments& args);
74 v8::Handle<v8::Value> Uint16Array(const v8::Arguments& args);
75 v8::Handle<v8::Value> Int32Array(const v8::Arguments& args);
76 v8::Handle<v8::Value> Uint32Array(const v8::Arguments& args);
77 v8::Handle<v8::Value> Float32Array(const v8::Arguments& args);
78 v8::Handle<v8::Value> Float64Array(const v8::Arguments& args);
79 v8::Handle<v8::Value> PixelArray(const v8::Arguments& args);
80 v8::Handle<v8::String> ReadFile(const char* name); 60 v8::Handle<v8::String> ReadFile(const char* name);
81 void ReportException(v8::TryCatch* handler); 61 void ReportException(v8::TryCatch* handler);
82 62
83 63
84 static bool last_run = true; 64 static bool run_shell;
85
Yang 2011/07/13 16:08:46 Removed support for --isolate.
86 class SourceGroup {
87 public:
88 SourceGroup() :
89 #if !(defined(USING_V8_SHARED) || defined(V8_SHARED))
90 next_semaphore_(v8::internal::OS::CreateSemaphore(0)),
91 done_semaphore_(v8::internal::OS::CreateSemaphore(0)),
92 thread_(NULL),
93 #endif // USING_V8_SHARED
94 argv_(NULL),
95 begin_offset_(0),
96 end_offset_(0) { }
97
98 void Begin(char** argv, int offset) {
99 argv_ = const_cast<const char**>(argv);
100 begin_offset_ = offset;
101 }
102
103 void End(int offset) { end_offset_ = offset; }
104
105 void Execute() {
106 for (int i = begin_offset_; i < end_offset_; ++i) {
107 const char* arg = argv_[i];
108 if (strcmp(arg, "-e") == 0 && i + 1 < end_offset_) {
109 // Execute argument given to -e option directly.
110 v8::HandleScope handle_scope;
111 v8::Handle<v8::String> file_name = v8::String::New("unnamed");
112 v8::Handle<v8::String> source = v8::String::New(argv_[i + 1]);
113 if (!ExecuteString(source, file_name, false, true)) {
114 ExitShell(1);
115 return;
116 }
117 ++i;
118 } else if (arg[0] == '-') {
119 // Ignore other options. They have been parsed already.
120 } else {
121 // Use all other arguments as names of files to load and run.
122 v8::HandleScope handle_scope;
123 v8::Handle<v8::String> file_name = v8::String::New(arg);
124 v8::Handle<v8::String> source = ReadFile(arg);
125 if (source.IsEmpty()) {
126 printf("Error reading '%s'\n", arg);
127 continue;
128 }
129 if (!ExecuteString(source, file_name, false, true)) {
130 ExitShell(1);
131 return;
132 }
133 }
134 }
135 }
136
137 #if !(defined(USING_V8_SHARED) || defined(V8_SHARED))
138 void StartExecuteInThread() {
139 if (thread_ == NULL) {
140 thread_ = new IsolateThread(this);
141 thread_->Start();
142 }
143 next_semaphore_->Signal();
144 }
145
146 void WaitForThread() {
147 if (thread_ == NULL) return;
148 if (last_run) {
149 thread_->Join();
150 thread_ = NULL;
151 } else {
152 done_semaphore_->Wait();
153 }
154 }
155 #endif // USING_V8_SHARED
156
157 private:
158 #if !(defined(USING_V8_SHARED) || defined(V8_SHARED))
159 static v8::internal::Thread::Options GetThreadOptions() {
160 v8::internal::Thread::Options options;
161 options.name = "IsolateThread";
162 // On some systems (OSX 10.6) the stack size default is 0.5Mb or less
163 // which is not enough to parse the big literal expressions used in tests.
164 // The stack size should be at least StackGuard::kLimitSize + some
165 // OS-specific padding for thread startup code.
166 options.stack_size = 2 << 20; // 2 Mb seems to be enough
167 return options;
168 }
169
170 class IsolateThread : public v8::internal::Thread {
171 public:
172 explicit IsolateThread(SourceGroup* group)
173 : v8::internal::Thread(GetThreadOptions()), group_(group) {}
174
175 virtual void Run() {
176 group_->ExecuteInThread();
177 }
178
179 private:
180 SourceGroup* group_;
181 };
182
183 void ExecuteInThread() {
184 v8::Isolate* isolate = v8::Isolate::New();
185 do {
186 if (next_semaphore_ != NULL) next_semaphore_->Wait();
187 {
188 v8::Isolate::Scope iscope(isolate);
189 v8::HandleScope scope;
190 v8::Persistent<v8::Context> context = CreateShellContext();
191 {
192 v8::Context::Scope cscope(context);
193 Execute();
194 }
195 context.Dispose();
196 }
197 if (done_semaphore_ != NULL) done_semaphore_->Signal();
198 } while (!last_run);
199 isolate->Dispose();
200 }
201
202 v8::internal::Semaphore* next_semaphore_;
203 v8::internal::Semaphore* done_semaphore_;
204 v8::internal::Thread* thread_;
205 #endif // USING_V8_SHARED
206
207 const char** argv_;
208 int begin_offset_;
209 int end_offset_;
210 };
211 65
212 66
213 static SourceGroup* isolate_sources = NULL; 67 int main(int argc, char* argv[]) {
214
215
Yang 2011/07/13 16:08:46 Removed support for compression.
216 #ifdef COMPRESS_STARTUP_DATA_BZ2
217 class BZip2Decompressor : public v8::StartupDataDecompressor {
218 public:
219 virtual ~BZip2Decompressor() { }
220
221 protected:
222 virtual int DecompressData(char* raw_data,
223 int* raw_data_size,
224 const char* compressed_data,
225 int compressed_data_size) {
226 ASSERT_EQ(v8::StartupData::kBZip2,
227 v8::V8::GetCompressedStartupDataAlgorithm());
228 unsigned int decompressed_size = *raw_data_size;
229 int result =
230 BZ2_bzBuffToBuffDecompress(raw_data,
231 &decompressed_size,
232 const_cast<char*>(compressed_data),
233 compressed_data_size,
234 0, 1);
235 if (result == BZ_OK) {
236 *raw_data_size = decompressed_size;
237 }
238 return result;
239 }
240 };
241 #endif
242
243
244 int RunMain(int argc, char* argv[]) {
245 v8::V8::SetFlagsFromCommandLine(&argc, argv, true); 68 v8::V8::SetFlagsFromCommandLine(&argc, argv, true);
69 run_shell = (argc == 1);
246 v8::HandleScope handle_scope; 70 v8::HandleScope handle_scope;
247 v8::Persistent<v8::Context> context = CreateShellContext(); 71 v8::Persistent<v8::Context> context = CreateShellContext();
248 // Enter the newly created execution environment.
249 context->Enter();
250 if (context.IsEmpty()) { 72 if (context.IsEmpty()) {
251 printf("Error creating context\n"); 73 printf("Error creating context\n");
252 return 1; 74 return 1;
253 } 75 }
254 76 context->Enter();
255 bool run_shell = (argc == 1); 77 int result = RunMain(argc, argv);
256 int num_isolates = 1;
257 for (int i = 1; i < argc; i++) {
258 if (strcmp(argv[i], "--isolate") == 0) {
259 #if !(defined(USING_V8_SHARED) || defined(V8_SHARED))
260 ++num_isolates;
261 #else // USING_V8_SHARED
262 printf("Error: --isolate not supported when linked with shared "
263 "library\n");
264 ExitShell(1);
265 #endif // USING_V8_SHARED
266 }
267 }
268 if (isolate_sources == NULL) {
269 isolate_sources = new SourceGroup[num_isolates];
270 SourceGroup* current = isolate_sources;
271 current->Begin(argv, 1);
272 for (int i = 1; i < argc; i++) {
273 const char* str = argv[i];
274 if (strcmp(str, "--isolate") == 0) {
275 current->End(i);
276 current++;
277 current->Begin(argv, i + 1);
278 } else if (strcmp(str, "--shell") == 0) {
279 run_shell = true;
280 } else if (strcmp(str, "-f") == 0) {
281 // Ignore any -f flags for compatibility with the other stand-
282 // alone JavaScript engines.
283 continue;
284 } else if (strncmp(str, "--", 2) == 0) {
285 printf("Warning: unknown flag %s.\nTry --help for options\n", str);
286 }
287 }
288 current->End(argc);
289 }
290 #if !(defined(USING_V8_SHARED) || defined(V8_SHARED))
291 for (int i = 1; i < num_isolates; ++i) {
292 isolate_sources[i].StartExecuteInThread();
293 }
294 #endif // USING_V8_SHARED
295 isolate_sources[0].Execute();
296 if (run_shell) RunShell(context); 78 if (run_shell) RunShell(context);
297 #if !(defined(USING_V8_SHARED) || defined(V8_SHARED))
298 for (int i = 1; i < num_isolates; ++i) {
299 isolate_sources[i].WaitForThread();
300 }
301 #endif // USING_V8_SHARED
302 if (last_run) {
303 delete[] isolate_sources;
304 isolate_sources = NULL;
305 }
306 context->Exit(); 79 context->Exit();
307 context.Dispose(); 80 context.Dispose();
308 return 0;
309 }
310
311
312 int main(int argc, char* argv[]) {
313 // Figure out if we're requested to stress the optimization
314 // infrastructure by running tests multiple times and forcing
315 // optimization in the last run.
316 bool FLAG_stress_opt = false;
317 bool FLAG_stress_deopt = false;
318 for (int i = 0; i < argc; i++) {
319 if (strcmp(argv[i], "--stress-opt") == 0) {
320 FLAG_stress_opt = true;
321 argv[i] = NULL;
322 } else if (strcmp(argv[i], "--stress-deopt") == 0) {
323 FLAG_stress_deopt = true;
324 argv[i] = NULL;
325 } else if (strcmp(argv[i], "--noalways-opt") == 0) {
326 // No support for stressing if we can't use --always-opt.
327 FLAG_stress_opt = false;
328 FLAG_stress_deopt = false;
329 break;
330 }
331 }
332
333 #ifdef COMPRESS_STARTUP_DATA_BZ2
334 BZip2Decompressor startup_data_decompressor;
335 int bz2_result = startup_data_decompressor.Decompress();
336 if (bz2_result != BZ_OK) {
337 fprintf(stderr, "bzip error code: %d\n", bz2_result);
338 exit(1);
339 }
340 #endif
341
Yang 2011/07/13 16:08:46 Removed stress runs.
342 v8::V8::SetFlagsFromCommandLine(&argc, argv, true);
343 int result = 0;
344 if (FLAG_stress_opt || FLAG_stress_deopt) {
345 v8::Testing::SetStressRunType(FLAG_stress_opt
346 ? v8::Testing::kStressTypeOpt
347 : v8::Testing::kStressTypeDeopt);
348 int stress_runs = v8::Testing::GetStressRuns();
349 for (int i = 0; i < stress_runs && result == 0; i++) {
350 printf("============ Stress %d/%d ============\n",
351 i + 1, stress_runs);
352 v8::Testing::PrepareStressRun(i);
353 last_run = (i == stress_runs - 1);
354 result = RunMain(argc, argv);
355 }
356 printf("======== Full Deoptimization =======\n");
357 v8::Testing::DeoptimizeAll();
358 } else {
359 result = RunMain(argc, argv);
360 }
361 v8::V8::Dispose(); 81 v8::V8::Dispose();
362
363 return result; 82 return result;
364 } 83 }
365 84
366 85
367 // Extracts a C string from a V8 Utf8Value. 86 // Extracts a C string from a V8 Utf8Value.
368 const char* ToCString(const v8::String::Utf8Value& value) { 87 const char* ToCString(const v8::String::Utf8Value& value) {
369 return *value ? *value : "<string conversion failed>"; 88 return *value ? *value : "<string conversion failed>";
370 } 89 }
371 90
372 91
373 // Creates a new execution environment containing the built-in 92 // Creates a new execution environment containing the built-in
374 // functions. 93 // functions.
375 v8::Persistent<v8::Context> CreateShellContext() { 94 v8::Persistent<v8::Context> CreateShellContext() {
376 // Create a template for the global object. 95 // Create a template for the global object.
377 v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New(); 96 v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New();
378 // Bind the global 'print' function to the C++ Print callback. 97 // Bind the global 'print' function to the C++ Print callback.
379 global->Set(v8::String::New("print"), v8::FunctionTemplate::New(Print)); 98 global->Set(v8::String::New("print"), v8::FunctionTemplate::New(Print));
380 // Bind the global 'read' function to the C++ Read callback. 99 // Bind the global 'read' function to the C++ Read callback.
381 global->Set(v8::String::New("read"), v8::FunctionTemplate::New(Read)); 100 global->Set(v8::String::New("read"), v8::FunctionTemplate::New(Read));
382 // Bind the global 'load' function to the C++ Load callback. 101 // Bind the global 'load' function to the C++ Load callback.
383 global->Set(v8::String::New("load"), v8::FunctionTemplate::New(Load)); 102 global->Set(v8::String::New("load"), v8::FunctionTemplate::New(Load));
384 // Bind the 'quit' function 103 // Bind the 'quit' function
385 global->Set(v8::String::New("quit"), v8::FunctionTemplate::New(Quit)); 104 global->Set(v8::String::New("quit"), v8::FunctionTemplate::New(Quit));
386 // Bind the 'version' function 105 // Bind the 'version' function
387 global->Set(v8::String::New("version"), v8::FunctionTemplate::New(Version)); 106 global->Set(v8::String::New("version"), v8::FunctionTemplate::New(Version));
388 107
389 // Bind the handlers for external arrays.
390 global->Set(v8::String::New("Int8Array"),
391 v8::FunctionTemplate::New(Int8Array));
392 global->Set(v8::String::New("Uint8Array"),
393 v8::FunctionTemplate::New(Uint8Array));
394 global->Set(v8::String::New("Int16Array"),
395 v8::FunctionTemplate::New(Int16Array));
396 global->Set(v8::String::New("Uint16Array"),
397 v8::FunctionTemplate::New(Uint16Array));
398 global->Set(v8::String::New("Int32Array"),
399 v8::FunctionTemplate::New(Int32Array));
400 global->Set(v8::String::New("Uint32Array"),
401 v8::FunctionTemplate::New(Uint32Array));
402 global->Set(v8::String::New("Float32Array"),
403 v8::FunctionTemplate::New(Float32Array));
404 global->Set(v8::String::New("Float64Array"),
405 v8::FunctionTemplate::New(Float64Array));
406 global->Set(v8::String::New("PixelArray"),
407 v8::FunctionTemplate::New(PixelArray));
408
409 return v8::Context::New(NULL, global); 108 return v8::Context::New(NULL, global);
410 } 109 }
411 110
412 111
413 // The callback that is invoked by v8 whenever the JavaScript 'print' 112 // The callback that is invoked by v8 whenever the JavaScript 'print'
414 // function is called. Prints its arguments on stdout separated by 113 // function is called. Prints its arguments on stdout separated by
415 // spaces and ending with a newline. 114 // spaces and ending with a newline.
416 v8::Handle<v8::Value> Print(const v8::Arguments& args) { 115 v8::Handle<v8::Value> Print(const v8::Arguments& args) {
417 bool first = true; 116 bool first = true;
418 for (int i = 0; i < args.Length(); i++) { 117 for (int i = 0; i < args.Length(); i++) {
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
472 return v8::Undefined(); 171 return v8::Undefined();
473 } 172 }
474 173
475 174
476 // The callback that is invoked by v8 whenever the JavaScript 'quit' 175 // The callback that is invoked by v8 whenever the JavaScript 'quit'
477 // function is called. Quits. 176 // function is called. Quits.
478 v8::Handle<v8::Value> Quit(const v8::Arguments& args) { 177 v8::Handle<v8::Value> Quit(const v8::Arguments& args) {
479 // If not arguments are given args[0] will yield undefined which 178 // If not arguments are given args[0] will yield undefined which
480 // converts to the integer value 0. 179 // converts to the integer value 0.
481 int exit_code = args[0]->Int32Value(); 180 int exit_code = args[0]->Int32Value();
482 ExitShell(exit_code); 181 fflush(stdout);
182 fflush(stderr);
183 exit(exit_code);
483 return v8::Undefined(); 184 return v8::Undefined();
484 } 185 }
485 186
486 187
487 v8::Handle<v8::Value> Version(const v8::Arguments& args) { 188 v8::Handle<v8::Value> Version(const v8::Arguments& args) {
488 return v8::String::New(v8::V8::GetVersion()); 189 return v8::String::New(v8::V8::GetVersion());
489 } 190 }
490 191
491 192
492 void ExternalArrayWeakCallback(v8::Persistent<v8::Value> object, void* data) {
493 free(data);
494 object.Dispose();
495 }
496
497
498 v8::Handle<v8::Value> CreateExternalArray(const v8::Arguments& args,
499 v8::ExternalArrayType type,
500 size_t element_size) {
501 assert(element_size == 1 ||
502 element_size == 2 ||
503 element_size == 4 ||
504 element_size == 8);
505 if (args.Length() != 1) {
506 return v8::ThrowException(
507 v8::String::New("Array constructor needs one parameter."));
508 }
509 static const int kMaxLength = 0x3fffffff;
510 size_t length = 0;
511 if (args[0]->IsUint32()) {
512 length = args[0]->Uint32Value();
513 } else if (args[0]->IsNumber()) {
514 double raw_length = args[0]->NumberValue();
515 if (raw_length < 0) {
516 return v8::ThrowException(
517 v8::String::New("Array length must not be negative."));
518 }
519 if (raw_length > kMaxLength) {
520 return v8::ThrowException(
521 v8::String::New("Array length exceeds maximum length."));
522 }
523 length = static_cast<size_t>(raw_length);
524 } else {
525 return v8::ThrowException(
526 v8::String::New("Array length must be a number."));
527 }
528 if (length > static_cast<size_t>(kMaxLength)) {
529 return v8::ThrowException(
530 v8::String::New("Array length exceeds maximum length."));
531 }
532 void* data = calloc(length, element_size);
533 if (data == NULL) {
534 return v8::ThrowException(v8::String::New("Memory allocation failed."));
535 }
536 v8::Handle<v8::Object> array = v8::Object::New();
537 v8::Persistent<v8::Object> persistent_array =
538 v8::Persistent<v8::Object>::New(array);
539 persistent_array.MakeWeak(data, ExternalArrayWeakCallback);
540 persistent_array.MarkIndependent();
541 array->SetIndexedPropertiesToExternalArrayData(data, type, length);
542 array->Set(v8::String::New("length"), v8::Int32::New(length),
543 v8::ReadOnly);
544 array->Set(v8::String::New("BYTES_PER_ELEMENT"),
545 v8::Int32::New(element_size));
546 return array;
547 }
548
549
550 v8::Handle<v8::Value> Int8Array(const v8::Arguments& args) {
551 return CreateExternalArray(args, v8::kExternalByteArray, sizeof(int8_t));
552 }
553
554
555 v8::Handle<v8::Value> Uint8Array(const v8::Arguments& args) {
556 return CreateExternalArray(args, v8::kExternalUnsignedByteArray,
557 sizeof(uint8_t));
558 }
559
560
561 v8::Handle<v8::Value> Int16Array(const v8::Arguments& args) {
562 return CreateExternalArray(args, v8::kExternalShortArray, sizeof(int16_t));
563 }
564
565
566 v8::Handle<v8::Value> Uint16Array(const v8::Arguments& args) {
567 return CreateExternalArray(args, v8::kExternalUnsignedShortArray,
568 sizeof(uint16_t));
569 }
570
571 v8::Handle<v8::Value> Int32Array(const v8::Arguments& args) {
572 return CreateExternalArray(args, v8::kExternalIntArray, sizeof(int32_t));
573 }
574
575
576 v8::Handle<v8::Value> Uint32Array(const v8::Arguments& args) {
577 return CreateExternalArray(args, v8::kExternalUnsignedIntArray,
578 sizeof(uint32_t));
579 }
580
581
582 v8::Handle<v8::Value> Float32Array(const v8::Arguments& args) {
583 return CreateExternalArray(args, v8::kExternalFloatArray,
584 sizeof(float)); // NOLINT
585 }
586
587
588 v8::Handle<v8::Value> Float64Array(const v8::Arguments& args) {
589 return CreateExternalArray(args, v8::kExternalDoubleArray,
590 sizeof(double)); // NOLINT
591 }
592
593
594 v8::Handle<v8::Value> PixelArray(const v8::Arguments& args) {
595 return CreateExternalArray(args, v8::kExternalPixelArray, sizeof(uint8_t));
596 }
597
598
599 // Reads a file into a v8 string. 193 // Reads a file into a v8 string.
600 v8::Handle<v8::String> ReadFile(const char* name) { 194 v8::Handle<v8::String> ReadFile(const char* name) {
601 FILE* file = fopen(name, "rb"); 195 FILE* file = fopen(name, "rb");
602 if (file == NULL) return v8::Handle<v8::String>(); 196 if (file == NULL) return v8::Handle<v8::String>();
603 197
604 fseek(file, 0, SEEK_END); 198 fseek(file, 0, SEEK_END);
605 int size = ftell(file); 199 int size = ftell(file);
606 rewind(file); 200 rewind(file);
607 201
608 char* chars = new char[size + 1]; 202 char* chars = new char[size + 1];
609 chars[size] = '\0'; 203 chars[size] = '\0';
610 for (int i = 0; i < size;) { 204 for (int i = 0; i < size;) {
611 int read = fread(&chars[i], 1, size - i, file); 205 int read = fread(&chars[i], 1, size - i, file);
612 i += read; 206 i += read;
613 } 207 }
614 fclose(file); 208 fclose(file);
615 v8::Handle<v8::String> result = v8::String::New(chars, size); 209 v8::Handle<v8::String> result = v8::String::New(chars, size);
616 delete[] chars; 210 delete[] chars;
617 return result; 211 return result;
618 } 212 }
619 213
620 214
215 // Process remaining command line arguments and execute files
216 int RunMain(int argc, char* argv[]) {
217 for (int i = 1; i < argc; i++) {
218 const char* str = argv[i];
219 if (strcmp(str, "--shell") == 0) {
220 run_shell = true;
221 } else if (strcmp(str, "-f") == 0) {
222 // Ignore any -f flags for compatibility with the other stand-
223 // alone JavaScript engines.
224 continue;
225 } else if (strncmp(str, "--", 2) == 0) {
226 printf("Warning: unknown flag %s.\nTry --help for options\n", str);
227 } else if (strcmp(str, "-e") == 0 && i + 1 < argc) {
228 // Execute argument given to -e option directly.
229 v8::Handle<v8::String> file_name = v8::String::New("unnamed");
230 v8::Handle<v8::String> source = v8::String::New(argv[++i]);
231 if (!ExecuteString(source, file_name, false, true)) return 1;
232 } else {
233 // Use all other arguments as names of files to load and run.
234 v8::Handle<v8::String> file_name = v8::String::New(str);
235 v8::Handle<v8::String> source = ReadFile(str);
236 if (source.IsEmpty()) {
237 printf("Error reading '%s'\n", str);
238 continue;
239 }
240 if (!ExecuteString(source, file_name, false, true)) return 1;
241 }
242 }
243 return 0;
244 }
245
246
621 // The read-eval-execute loop of the shell. 247 // The read-eval-execute loop of the shell.
622 void RunShell(v8::Handle<v8::Context> context) { 248 void RunShell(v8::Handle<v8::Context> context) {
623 printf("V8 version %s\n", v8::V8::GetVersion()); 249 printf("V8 version %s [sample shell]\n", v8::V8::GetVersion());
624 static const int kBufferSize = 256; 250 static const int kBufferSize = 256;
625 // Enter the execution environment before evaluating any code. 251 // Enter the execution environment before evaluating any code.
626 v8::Context::Scope context_scope(context); 252 v8::Context::Scope context_scope(context);
627 while (true) { 253 while (true) {
628 char buffer[kBufferSize]; 254 char buffer[kBufferSize];
629 printf("> "); 255 printf("> ");
630 char* str = fgets(buffer, kBufferSize, stdin); 256 char* str = fgets(buffer, kBufferSize, stdin);
631 if (str == NULL) break; 257 if (str == NULL) break;
632 v8::HandleScope handle_scope; 258 v8::HandleScope handle_scope;
633 ExecuteString(v8::String::New(str), 259 ExecuteString(v8::String::New(str),
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
704 printf("^"); 330 printf("^");
705 } 331 }
706 printf("\n"); 332 printf("\n");
707 v8::String::Utf8Value stack_trace(try_catch->StackTrace()); 333 v8::String::Utf8Value stack_trace(try_catch->StackTrace());
708 if (stack_trace.length() > 0) { 334 if (stack_trace.length() > 0) {
709 const char* stack_trace_string = ToCString(stack_trace); 335 const char* stack_trace_string = ToCString(stack_trace);
710 printf("%s\n", stack_trace_string); 336 printf("%s\n", stack_trace_string);
711 } 337 }
712 } 338 }
713 } 339 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698