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

Side by Side Diff: samples/shell.cc

Issue 7778013: NewGC: Merge bleeding edge up to 9009. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: Created 9 years, 3 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 | « samples/samples.gyp ('k') | src/accessors.cc » ('j') | 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 /**
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);
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
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 #if !(defined(USING_V8_SHARED) || defined(V8_SHARED))
99 ~SourceGroup() {
100 delete next_semaphore_;
101 delete done_semaphore_;
102 }
103 #endif // USING_V8_SHARED
104
105 void Begin(char** argv, int offset) {
106 argv_ = const_cast<const char**>(argv);
107 begin_offset_ = offset;
108 }
109
110 void End(int offset) { end_offset_ = offset; }
111
112 void Execute() {
113 for (int i = begin_offset_; i < end_offset_; ++i) {
114 const char* arg = argv_[i];
115 if (strcmp(arg, "-e") == 0 && i + 1 < end_offset_) {
116 // Execute argument given to -e option directly.
117 v8::HandleScope handle_scope;
118 v8::Handle<v8::String> file_name = v8::String::New("unnamed");
119 v8::Handle<v8::String> source = v8::String::New(argv_[i + 1]);
120 if (!ExecuteString(source, file_name, false, true)) {
121 ExitShell(1);
122 return;
123 }
124 ++i;
125 } else if (arg[0] == '-') {
126 // Ignore other options. They have been parsed already.
127 } else {
128 // Use all other arguments as names of files to load and run.
129 v8::HandleScope handle_scope;
130 v8::Handle<v8::String> file_name = v8::String::New(arg);
131 v8::Handle<v8::String> source = ReadFile(arg);
132 if (source.IsEmpty()) {
133 printf("Error reading '%s'\n", arg);
134 continue;
135 }
136 if (!ExecuteString(source, file_name, false, true)) {
137 ExitShell(1);
138 return;
139 }
140 }
141 }
142 }
143
144 #if !(defined(USING_V8_SHARED) || defined(V8_SHARED))
145 void StartExecuteInThread() {
146 if (thread_ == NULL) {
147 thread_ = new IsolateThread(this);
148 thread_->Start();
149 }
150 next_semaphore_->Signal();
151 }
152
153 void WaitForThread() {
154 if (thread_ == NULL) return;
155 if (last_run) {
156 thread_->Join();
157 thread_ = NULL;
158 } else {
159 done_semaphore_->Wait();
160 }
161 }
162 #endif // USING_V8_SHARED
163
164 private:
165 #if !(defined(USING_V8_SHARED) || defined(V8_SHARED))
166 static v8::internal::Thread::Options GetThreadOptions() {
167 v8::internal::Thread::Options options;
168 options.name = "IsolateThread";
169 // On some systems (OSX 10.6) the stack size default is 0.5Mb or less
170 // which is not enough to parse the big literal expressions used in tests.
171 // The stack size should be at least StackGuard::kLimitSize + some
172 // OS-specific padding for thread startup code.
173 options.stack_size = 2 << 20; // 2 Mb seems to be enough
174 return options;
175 }
176
177 class IsolateThread : public v8::internal::Thread {
178 public:
179 explicit IsolateThread(SourceGroup* group)
180 : v8::internal::Thread(GetThreadOptions()), group_(group) {}
181
182 virtual void Run() {
183 group_->ExecuteInThread();
184 }
185
186 private:
187 SourceGroup* group_;
188 };
189
190 void ExecuteInThread() {
191 v8::Isolate* isolate = v8::Isolate::New();
192 do {
193 if (next_semaphore_ != NULL) next_semaphore_->Wait();
194 {
195 v8::Isolate::Scope iscope(isolate);
196 v8::HandleScope scope;
197 v8::Persistent<v8::Context> context = CreateShellContext();
198 {
199 v8::Context::Scope cscope(context);
200 Execute();
201 }
202 context.Dispose();
203 }
204 if (done_semaphore_ != NULL) done_semaphore_->Signal();
205 } while (!last_run);
206 isolate->Dispose();
207 }
208
209 v8::internal::Semaphore* next_semaphore_;
210 v8::internal::Semaphore* done_semaphore_;
211 v8::internal::Thread* thread_;
212 #endif // USING_V8_SHARED
213
214 const char** argv_;
215 int begin_offset_;
216 int end_offset_;
217 };
218 65
219 66
220 static SourceGroup* isolate_sources = NULL; 67 int main(int argc, char* argv[]) {
221
222
223 #ifdef COMPRESS_STARTUP_DATA_BZ2
224 class BZip2Decompressor : public v8::StartupDataDecompressor {
225 public:
226 virtual ~BZip2Decompressor() { }
227
228 protected:
229 virtual int DecompressData(char* raw_data,
230 int* raw_data_size,
231 const char* compressed_data,
232 int compressed_data_size) {
233 ASSERT_EQ(v8::StartupData::kBZip2,
234 v8::V8::GetCompressedStartupDataAlgorithm());
235 unsigned int decompressed_size = *raw_data_size;
236 int result =
237 BZ2_bzBuffToBuffDecompress(raw_data,
238 &decompressed_size,
239 const_cast<char*>(compressed_data),
240 compressed_data_size,
241 0, 1);
242 if (result == BZ_OK) {
243 *raw_data_size = decompressed_size;
244 }
245 return result;
246 }
247 };
248 #endif
249
250
251 int RunMain(int argc, char* argv[]) {
252 v8::V8::SetFlagsFromCommandLine(&argc, argv, true); 68 v8::V8::SetFlagsFromCommandLine(&argc, argv, true);
69 run_shell = (argc == 1);
253 v8::HandleScope handle_scope; 70 v8::HandleScope handle_scope;
254 v8::Persistent<v8::Context> context = CreateShellContext(); 71 v8::Persistent<v8::Context> context = CreateShellContext();
255 // Enter the newly created execution environment.
256 context->Enter();
257 if (context.IsEmpty()) { 72 if (context.IsEmpty()) {
258 printf("Error creating context\n"); 73 printf("Error creating context\n");
259 return 1; 74 return 1;
260 } 75 }
261 76 context->Enter();
262 bool run_shell = (argc == 1); 77 int result = RunMain(argc, argv);
263 int num_isolates = 1;
264 for (int i = 1; i < argc; i++) {
265 if (strcmp(argv[i], "--isolate") == 0) {
266 #if !(defined(USING_V8_SHARED) || defined(V8_SHARED))
267 ++num_isolates;
268 #else // USING_V8_SHARED
269 printf("Error: --isolate not supported when linked with shared "
270 "library\n");
271 ExitShell(1);
272 #endif // USING_V8_SHARED
273 }
274 }
275 if (isolate_sources == NULL) {
276 isolate_sources = new SourceGroup[num_isolates];
277 SourceGroup* current = isolate_sources;
278 current->Begin(argv, 1);
279 for (int i = 1; i < argc; i++) {
280 const char* str = argv[i];
281 if (strcmp(str, "--isolate") == 0) {
282 current->End(i);
283 current++;
284 current->Begin(argv, i + 1);
285 } else if (strcmp(str, "--shell") == 0) {
286 run_shell = true;
287 } else if (strcmp(str, "-f") == 0) {
288 // Ignore any -f flags for compatibility with the other stand-
289 // alone JavaScript engines.
290 continue;
291 } else if (strncmp(str, "--", 2) == 0) {
292 printf("Warning: unknown flag %s.\nTry --help for options\n", str);
293 }
294 }
295 current->End(argc);
296 }
297 #if !(defined(USING_V8_SHARED) || defined(V8_SHARED))
298 for (int i = 1; i < num_isolates; ++i) {
299 isolate_sources[i].StartExecuteInThread();
300 }
301 #endif // USING_V8_SHARED
302 isolate_sources[0].Execute();
303 if (run_shell) RunShell(context); 78 if (run_shell) RunShell(context);
304 #if !(defined(USING_V8_SHARED) || defined(V8_SHARED))
305 for (int i = 1; i < num_isolates; ++i) {
306 isolate_sources[i].WaitForThread();
307 }
308 #endif // USING_V8_SHARED
309 if (last_run) {
310 delete[] isolate_sources;
311 isolate_sources = NULL;
312 }
313 context->Exit(); 79 context->Exit();
314 context.Dispose(); 80 context.Dispose();
315 return 0;
316 }
317
318
319 int main(int argc, char* argv[]) {
320 // Figure out if we're requested to stress the optimization
321 // infrastructure by running tests multiple times and forcing
322 // optimization in the last run.
323 bool FLAG_stress_opt = false;
324 bool FLAG_stress_deopt = false;
325 for (int i = 0; i < argc; i++) {
326 if (strcmp(argv[i], "--stress-opt") == 0) {
327 FLAG_stress_opt = true;
328 argv[i] = NULL;
329 } else if (strcmp(argv[i], "--stress-deopt") == 0) {
330 FLAG_stress_deopt = true;
331 argv[i] = NULL;
332 } else if (strcmp(argv[i], "--noalways-opt") == 0) {
333 // No support for stressing if we can't use --always-opt.
334 FLAG_stress_opt = false;
335 FLAG_stress_deopt = false;
336 break;
337 }
338 }
339
340 #ifdef COMPRESS_STARTUP_DATA_BZ2
341 BZip2Decompressor startup_data_decompressor;
342 int bz2_result = startup_data_decompressor.Decompress();
343 if (bz2_result != BZ_OK) {
344 fprintf(stderr, "bzip error code: %d\n", bz2_result);
345 exit(1);
346 }
347 #endif
348
349 v8::V8::SetFlagsFromCommandLine(&argc, argv, true);
350 int result = 0;
351 if (FLAG_stress_opt || FLAG_stress_deopt) {
352 v8::Testing::SetStressRunType(FLAG_stress_opt
353 ? v8::Testing::kStressTypeOpt
354 : v8::Testing::kStressTypeDeopt);
355 int stress_runs = v8::Testing::GetStressRuns();
356 for (int i = 0; i < stress_runs && result == 0; i++) {
357 printf("============ Stress %d/%d ============\n",
358 i + 1, stress_runs);
359 v8::Testing::PrepareStressRun(i);
360 last_run = (i == stress_runs - 1);
361 result = RunMain(argc, argv);
362 }
363 printf("======== Full Deoptimization =======\n");
364 v8::Testing::DeoptimizeAll();
365 } else {
366 result = RunMain(argc, argv);
367 }
368 v8::V8::Dispose(); 81 v8::V8::Dispose();
369
370 return result; 82 return result;
371 } 83 }
372 84
373 85
374 // Extracts a C string from a V8 Utf8Value. 86 // Extracts a C string from a V8 Utf8Value.
375 const char* ToCString(const v8::String::Utf8Value& value) { 87 const char* ToCString(const v8::String::Utf8Value& value) {
376 return *value ? *value : "<string conversion failed>"; 88 return *value ? *value : "<string conversion failed>";
377 } 89 }
378 90
379 91
380 // Creates a new execution environment containing the built-in 92 // Creates a new execution environment containing the built-in
381 // functions. 93 // functions.
382 v8::Persistent<v8::Context> CreateShellContext() { 94 v8::Persistent<v8::Context> CreateShellContext() {
383 // Create a template for the global object. 95 // Create a template for the global object.
384 v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New(); 96 v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New();
385 // Bind the global 'print' function to the C++ Print callback. 97 // Bind the global 'print' function to the C++ Print callback.
386 global->Set(v8::String::New("print"), v8::FunctionTemplate::New(Print)); 98 global->Set(v8::String::New("print"), v8::FunctionTemplate::New(Print));
387 // Bind the global 'read' function to the C++ Read callback. 99 // Bind the global 'read' function to the C++ Read callback.
388 global->Set(v8::String::New("read"), v8::FunctionTemplate::New(Read)); 100 global->Set(v8::String::New("read"), v8::FunctionTemplate::New(Read));
389 // Bind the global 'load' function to the C++ Load callback. 101 // Bind the global 'load' function to the C++ Load callback.
390 global->Set(v8::String::New("load"), v8::FunctionTemplate::New(Load)); 102 global->Set(v8::String::New("load"), v8::FunctionTemplate::New(Load));
391 // Bind the 'quit' function 103 // Bind the 'quit' function
392 global->Set(v8::String::New("quit"), v8::FunctionTemplate::New(Quit)); 104 global->Set(v8::String::New("quit"), v8::FunctionTemplate::New(Quit));
393 // Bind the 'version' function 105 // Bind the 'version' function
394 global->Set(v8::String::New("version"), v8::FunctionTemplate::New(Version)); 106 global->Set(v8::String::New("version"), v8::FunctionTemplate::New(Version));
395 107
396 // Bind the handlers for external arrays.
397 global->Set(v8::String::New("Int8Array"),
398 v8::FunctionTemplate::New(Int8Array));
399 global->Set(v8::String::New("Uint8Array"),
400 v8::FunctionTemplate::New(Uint8Array));
401 global->Set(v8::String::New("Int16Array"),
402 v8::FunctionTemplate::New(Int16Array));
403 global->Set(v8::String::New("Uint16Array"),
404 v8::FunctionTemplate::New(Uint16Array));
405 global->Set(v8::String::New("Int32Array"),
406 v8::FunctionTemplate::New(Int32Array));
407 global->Set(v8::String::New("Uint32Array"),
408 v8::FunctionTemplate::New(Uint32Array));
409 global->Set(v8::String::New("Float32Array"),
410 v8::FunctionTemplate::New(Float32Array));
411 global->Set(v8::String::New("Float64Array"),
412 v8::FunctionTemplate::New(Float64Array));
413 global->Set(v8::String::New("PixelArray"),
414 v8::FunctionTemplate::New(PixelArray));
415
416 return v8::Context::New(NULL, global); 108 return v8::Context::New(NULL, global);
417 } 109 }
418 110
419 111
420 // The callback that is invoked by v8 whenever the JavaScript 'print' 112 // The callback that is invoked by v8 whenever the JavaScript 'print'
421 // function is called. Prints its arguments on stdout separated by 113 // function is called. Prints its arguments on stdout separated by
422 // spaces and ending with a newline. 114 // spaces and ending with a newline.
423 v8::Handle<v8::Value> Print(const v8::Arguments& args) { 115 v8::Handle<v8::Value> Print(const v8::Arguments& args) {
424 bool first = true; 116 bool first = true;
425 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
479 return v8::Undefined(); 171 return v8::Undefined();
480 } 172 }
481 173
482 174
483 // The callback that is invoked by v8 whenever the JavaScript 'quit' 175 // The callback that is invoked by v8 whenever the JavaScript 'quit'
484 // function is called. Quits. 176 // function is called. Quits.
485 v8::Handle<v8::Value> Quit(const v8::Arguments& args) { 177 v8::Handle<v8::Value> Quit(const v8::Arguments& args) {
486 // If not arguments are given args[0] will yield undefined which 178 // If not arguments are given args[0] will yield undefined which
487 // converts to the integer value 0. 179 // converts to the integer value 0.
488 int exit_code = args[0]->Int32Value(); 180 int exit_code = args[0]->Int32Value();
489 ExitShell(exit_code); 181 fflush(stdout);
182 fflush(stderr);
183 exit(exit_code);
490 return v8::Undefined(); 184 return v8::Undefined();
491 } 185 }
492 186
493 187
494 v8::Handle<v8::Value> Version(const v8::Arguments& args) { 188 v8::Handle<v8::Value> Version(const v8::Arguments& args) {
495 return v8::String::New(v8::V8::GetVersion()); 189 return v8::String::New(v8::V8::GetVersion());
496 } 190 }
497 191
498 192
499 void ExternalArrayWeakCallback(v8::Persistent<v8::Value> object, void* data) {
500 free(data);
501 object.Dispose();
502 }
503
504
505 v8::Handle<v8::Value> CreateExternalArray(const v8::Arguments& args,
506 v8::ExternalArrayType type,
507 size_t element_size) {
508 assert(element_size == 1 ||
509 element_size == 2 ||
510 element_size == 4 ||
511 element_size == 8);
512 if (args.Length() != 1) {
513 return v8::ThrowException(
514 v8::String::New("Array constructor needs one parameter."));
515 }
516 static const int kMaxLength = 0x3fffffff;
517 size_t length = 0;
518 if (args[0]->IsUint32()) {
519 length = args[0]->Uint32Value();
520 } else if (args[0]->IsNumber()) {
521 double raw_length = args[0]->NumberValue();
522 if (raw_length < 0) {
523 return v8::ThrowException(
524 v8::String::New("Array length must not be negative."));
525 }
526 if (raw_length > kMaxLength) {
527 return v8::ThrowException(
528 v8::String::New("Array length exceeds maximum length."));
529 }
530 length = static_cast<size_t>(raw_length);
531 } else {
532 return v8::ThrowException(
533 v8::String::New("Array length must be a number."));
534 }
535 if (length > static_cast<size_t>(kMaxLength)) {
536 return v8::ThrowException(
537 v8::String::New("Array length exceeds maximum length."));
538 }
539 void* data = calloc(length, element_size);
540 if (data == NULL) {
541 return v8::ThrowException(v8::String::New("Memory allocation failed."));
542 }
543 v8::Handle<v8::Object> array = v8::Object::New();
544 v8::Persistent<v8::Object> persistent_array =
545 v8::Persistent<v8::Object>::New(array);
546 persistent_array.MakeWeak(data, ExternalArrayWeakCallback);
547 persistent_array.MarkIndependent();
548 array->SetIndexedPropertiesToExternalArrayData(data, type, length);
549 array->Set(v8::String::New("length"), v8::Int32::New(length),
550 v8::ReadOnly);
551 array->Set(v8::String::New("BYTES_PER_ELEMENT"),
552 v8::Int32::New(element_size));
553 return array;
554 }
555
556
557 v8::Handle<v8::Value> Int8Array(const v8::Arguments& args) {
558 return CreateExternalArray(args, v8::kExternalByteArray, sizeof(int8_t));
559 }
560
561
562 v8::Handle<v8::Value> Uint8Array(const v8::Arguments& args) {
563 return CreateExternalArray(args, v8::kExternalUnsignedByteArray,
564 sizeof(uint8_t));
565 }
566
567
568 v8::Handle<v8::Value> Int16Array(const v8::Arguments& args) {
569 return CreateExternalArray(args, v8::kExternalShortArray, sizeof(int16_t));
570 }
571
572
573 v8::Handle<v8::Value> Uint16Array(const v8::Arguments& args) {
574 return CreateExternalArray(args, v8::kExternalUnsignedShortArray,
575 sizeof(uint16_t));
576 }
577
578 v8::Handle<v8::Value> Int32Array(const v8::Arguments& args) {
579 return CreateExternalArray(args, v8::kExternalIntArray, sizeof(int32_t));
580 }
581
582
583 v8::Handle<v8::Value> Uint32Array(const v8::Arguments& args) {
584 return CreateExternalArray(args, v8::kExternalUnsignedIntArray,
585 sizeof(uint32_t));
586 }
587
588
589 v8::Handle<v8::Value> Float32Array(const v8::Arguments& args) {
590 return CreateExternalArray(args, v8::kExternalFloatArray,
591 sizeof(float)); // NOLINT
592 }
593
594
595 v8::Handle<v8::Value> Float64Array(const v8::Arguments& args) {
596 return CreateExternalArray(args, v8::kExternalDoubleArray,
597 sizeof(double)); // NOLINT
598 }
599
600
601 v8::Handle<v8::Value> PixelArray(const v8::Arguments& args) {
602 return CreateExternalArray(args, v8::kExternalPixelArray, sizeof(uint8_t));
603 }
604
605
606 // Reads a file into a v8 string. 193 // Reads a file into a v8 string.
607 v8::Handle<v8::String> ReadFile(const char* name) { 194 v8::Handle<v8::String> ReadFile(const char* name) {
608 FILE* file = fopen(name, "rb"); 195 FILE* file = fopen(name, "rb");
609 if (file == NULL) return v8::Handle<v8::String>(); 196 if (file == NULL) return v8::Handle<v8::String>();
610 197
611 fseek(file, 0, SEEK_END); 198 fseek(file, 0, SEEK_END);
612 int size = ftell(file); 199 int size = ftell(file);
613 rewind(file); 200 rewind(file);
614 201
615 char* chars = new char[size + 1]; 202 char* chars = new char[size + 1];
616 chars[size] = '\0'; 203 chars[size] = '\0';
617 for (int i = 0; i < size;) { 204 for (int i = 0; i < size;) {
618 int read = fread(&chars[i], 1, size - i, file); 205 int read = fread(&chars[i], 1, size - i, file);
619 i += read; 206 i += read;
620 } 207 }
621 fclose(file); 208 fclose(file);
622 v8::Handle<v8::String> result = v8::String::New(chars, size); 209 v8::Handle<v8::String> result = v8::String::New(chars, size);
623 delete[] chars; 210 delete[] chars;
624 return result; 211 return result;
625 } 212 }
626 213
627 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
628 // The read-eval-execute loop of the shell. 247 // The read-eval-execute loop of the shell.
629 void RunShell(v8::Handle<v8::Context> context) { 248 void RunShell(v8::Handle<v8::Context> context) {
630 printf("V8 version %s\n", v8::V8::GetVersion()); 249 printf("V8 version %s [sample shell]\n", v8::V8::GetVersion());
631 static const int kBufferSize = 256; 250 static const int kBufferSize = 256;
632 // Enter the execution environment before evaluating any code. 251 // Enter the execution environment before evaluating any code.
633 v8::Context::Scope context_scope(context); 252 v8::Context::Scope context_scope(context);
634 while (true) { 253 while (true) {
635 char buffer[kBufferSize]; 254 char buffer[kBufferSize];
636 printf("> "); 255 printf("> ");
637 char* str = fgets(buffer, kBufferSize, stdin); 256 char* str = fgets(buffer, kBufferSize, stdin);
638 if (str == NULL) break; 257 if (str == NULL) break;
639 v8::HandleScope handle_scope; 258 v8::HandleScope handle_scope;
640 ExecuteString(v8::String::New(str), 259 ExecuteString(v8::String::New(str),
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
711 printf("^"); 330 printf("^");
712 } 331 }
713 printf("\n"); 332 printf("\n");
714 v8::String::Utf8Value stack_trace(try_catch->StackTrace()); 333 v8::String::Utf8Value stack_trace(try_catch->StackTrace());
715 if (stack_trace.length() > 0) { 334 if (stack_trace.length() > 0) {
716 const char* stack_trace_string = ToCString(stack_trace); 335 const char* stack_trace_string = ToCString(stack_trace);
717 printf("%s\n", stack_trace_string); 336 printf("%s\n", stack_trace_string);
718 } 337 }
719 } 338 }
720 } 339 }
OLDNEW
« no previous file with comments | « samples/samples.gyp ('k') | src/accessors.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698