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

Side by Side Diff: src/d8.cc

Issue 11418088: Drastically reduce the number of created strings in d8, 2nd attempt. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Clean up LineEditor Created 8 years, 1 month 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 | « src/d8.h ('k') | 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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
60 #if !defined(_WIN32) && !defined(_WIN64) 60 #if !defined(_WIN32) && !defined(_WIN64)
61 #include <unistd.h> // NOLINT 61 #include <unistd.h> // NOLINT
62 #endif 62 #endif
63 63
64 #ifndef ASSERT 64 #ifndef ASSERT
65 #define ASSERT(condition) assert(condition) 65 #define ASSERT(condition) assert(condition)
66 #endif 66 #endif
67 67
68 namespace v8 { 68 namespace v8 {
69 69
70
71 static Handle<Value> Throw(const char* message) {
72 return ThrowException(String::New(message));
73 }
74
75
76 // TODO(rossberg): should replace these by proper uses of HasInstance,
77 // once we figure out a good way to make the templates global.
78 const char kArrayBufferMarkerPropName[] = "d8::_is_array_buffer_";
79 const char kArrayMarkerPropName[] = "d8::_is_typed_array_";
80
81
82 #define FOR_EACH_SYMBOL(V) \
83 V(ArrayBuffer, "ArrayBuffer") \
84 V(ArrayBufferMarkerPropName, kArrayBufferMarkerPropName) \
85 V(ArrayMarkerPropName, kArrayMarkerPropName) \
86 V(buffer, "buffer") \
87 V(byteLength, "byteLength") \
88 V(byteOffset, "byteOffset") \
89 V(BYTES_PER_ELEMENT, "BYTES_PER_ELEMENT") \
90 V(length, "length")
91
92
93 class Symbols {
94 public:
95 explicit Symbols(Isolate* isolate) : isolate_(isolate) {
96 HandleScope scope;
97 #define INIT_SYMBOL(name, value) \
98 name##_ = Persistent<String>::New(String::NewSymbol(value));
99 FOR_EACH_SYMBOL(INIT_SYMBOL)
100 #undef INIT_SYMBOL
101 isolate->SetData(this);
102 }
103
104 ~Symbols() {
105 #define DISPOSE_SYMBOL(name, value) name##_.Dispose();
106 FOR_EACH_SYMBOL(DISPOSE_SYMBOL)
107 #undef DISPOSE_SYMBOL
Michael Starzinger 2012/11/20 14:35:46 Can we defensively reset the embedder data to NULL
Sven Panne 2012/11/20 14:46:22 Done.
108 }
109
110 #define DEFINE_SYMBOL_GETTER(name, value) \
111 static Persistent<String> name(Isolate* isolate) { \
112 return reinterpret_cast<Symbols*>(isolate->GetData())->name##_; \
113 }
114 FOR_EACH_SYMBOL(DEFINE_SYMBOL_GETTER)
115 #undef DEFINE_SYMBOL_GETTER
116
117 private:
118 Isolate* isolate_;
119 #define DEFINE_MEMBER(name, value) Persistent<String> name##_;
120 FOR_EACH_SYMBOL(DEFINE_MEMBER)
121 #undef DEFINE_MEMBER
122 };
123
124
70 LineEditor *LineEditor::first_ = NULL; 125 LineEditor *LineEditor::first_ = NULL;
71 126
72 127
73 LineEditor::LineEditor(Type type, const char* name) 128 LineEditor::LineEditor(Type type, const char* name)
74 : type_(type), 129 : type_(type),
75 name_(name), 130 name_(name),
76 next_(first_) { 131 next_(first_) {
77 first_ = this; 132 first_ = this;
78 } 133 }
79 134
80 135
81 LineEditor* LineEditor::Get() { 136 LineEditor* LineEditor::Get() {
82 LineEditor* current = first_; 137 LineEditor* current = first_;
83 LineEditor* best = current; 138 LineEditor* best = current;
84 while (current != NULL) { 139 while (current != NULL) {
85 if (current->type_ > best->type_) 140 if (current->type_ > best->type_)
86 best = current; 141 best = current;
87 current = current->next_; 142 current = current->next_;
88 } 143 }
89 return best; 144 return best;
90 } 145 }
91 146
92 147
93 class DumbLineEditor: public LineEditor { 148 class DumbLineEditor: public LineEditor {
94 public: 149 public:
95 DumbLineEditor() : LineEditor(LineEditor::DUMB, "dumb") { } 150 explicit DumbLineEditor(Isolate* isolate)
151 : LineEditor(LineEditor::DUMB, "dumb"), isolate_(isolate) { }
96 virtual Handle<String> Prompt(const char* prompt); 152 virtual Handle<String> Prompt(const char* prompt);
153 private:
154 Isolate* isolate_;
97 }; 155 };
98 156
99 157
100 static DumbLineEditor dumb_line_editor;
101
102
103 Handle<String> DumbLineEditor::Prompt(const char* prompt) { 158 Handle<String> DumbLineEditor::Prompt(const char* prompt) {
104 printf("%s", prompt); 159 printf("%s", prompt);
105 return Shell::ReadFromStdin(); 160 return Shell::ReadFromStdin(isolate_);
106 } 161 }
107 162
108 163
109 #ifndef V8_SHARED 164 #ifndef V8_SHARED
110 CounterMap* Shell::counter_map_; 165 CounterMap* Shell::counter_map_;
111 i::OS::MemoryMappedFile* Shell::counters_file_ = NULL; 166 i::OS::MemoryMappedFile* Shell::counters_file_ = NULL;
112 CounterCollection Shell::local_counters_; 167 CounterCollection Shell::local_counters_;
113 CounterCollection* Shell::counters_ = &local_counters_; 168 CounterCollection* Shell::counters_ = &local_counters_;
114 i::Mutex* Shell::context_mutex_(i::OS::CreateMutex()); 169 i::Mutex* Shell::context_mutex_(i::OS::CreateMutex());
115 Persistent<Context> Shell::utility_context_; 170 Persistent<Context> Shell::utility_context_;
116 #endif // V8_SHARED 171 #endif // V8_SHARED
117 172
118 LineEditor* Shell::console = NULL;
119 Persistent<Context> Shell::evaluation_context_; 173 Persistent<Context> Shell::evaluation_context_;
120 ShellOptions Shell::options; 174 ShellOptions Shell::options;
121 const char* Shell::kPrompt = "d8> "; 175 const char* Shell::kPrompt = "d8> ";
122 176
123 177
124 const int MB = 1024 * 1024; 178 const int MB = 1024 * 1024;
125 179
126 180
127 #ifndef V8_SHARED 181 #ifndef V8_SHARED
128 bool CounterMap::Match(void* key1, void* key2) { 182 bool CounterMap::Match(void* key1, void* key2) {
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
225 279
226 Handle<Value> Shell::DisableProfiler(const Arguments& args) { 280 Handle<Value> Shell::DisableProfiler(const Arguments& args) {
227 V8::PauseProfiler(); 281 V8::PauseProfiler();
228 return Undefined(); 282 return Undefined();
229 } 283 }
230 284
231 285
232 Handle<Value> Shell::Read(const Arguments& args) { 286 Handle<Value> Shell::Read(const Arguments& args) {
233 String::Utf8Value file(args[0]); 287 String::Utf8Value file(args[0]);
234 if (*file == NULL) { 288 if (*file == NULL) {
235 return ThrowException(String::New("Error loading file")); 289 return Throw("Error loading file");
236 } 290 }
237 Handle<String> source = ReadFile(*file); 291 Handle<String> source = ReadFile(args.GetIsolate(), *file);
238 if (source.IsEmpty()) { 292 if (source.IsEmpty()) {
239 return ThrowException(String::New("Error loading file")); 293 return Throw("Error loading file");
240 } 294 }
241 return source; 295 return source;
242 } 296 }
243 297
244 298
245 Handle<String> Shell::ReadFromStdin() { 299 Handle<String> Shell::ReadFromStdin(Isolate* isolate) {
246 static const int kBufferSize = 256; 300 static const int kBufferSize = 256;
247 char buffer[kBufferSize]; 301 char buffer[kBufferSize];
248 Handle<String> accumulator = String::New(""); 302 Handle<String> accumulator = String::New("");
249 int length; 303 int length;
250 while (true) { 304 while (true) {
251 // Continue reading if the line ends with an escape '\\' or the line has 305 // Continue reading if the line ends with an escape '\\' or the line has
252 // not been fully read into the buffer yet (does not end with '\n'). 306 // not been fully read into the buffer yet (does not end with '\n').
253 // If fgets gets an error, just give up. 307 // If fgets gets an error, just give up.
254 char* input = NULL; 308 char* input = NULL;
255 { // Release lock for blocking input. 309 { // Release lock for blocking input.
256 Unlocker unlock(Isolate::GetCurrent()); 310 Unlocker unlock(isolate);
257 input = fgets(buffer, kBufferSize, stdin); 311 input = fgets(buffer, kBufferSize, stdin);
258 } 312 }
259 if (input == NULL) return Handle<String>(); 313 if (input == NULL) return Handle<String>();
260 length = static_cast<int>(strlen(buffer)); 314 length = static_cast<int>(strlen(buffer));
261 if (length == 0) { 315 if (length == 0) {
262 return accumulator; 316 return accumulator;
263 } else if (buffer[length-1] != '\n') { 317 } else if (buffer[length-1] != '\n') {
264 accumulator = String::Concat(accumulator, String::New(buffer, length)); 318 accumulator = String::Concat(accumulator, String::New(buffer, length));
265 } else if (length > 1 && buffer[length-2] == '\\') { 319 } else if (length > 1 && buffer[length-2] == '\\') {
266 buffer[length-2] = '\n'; 320 buffer[length-2] = '\n';
267 accumulator = String::Concat(accumulator, String::New(buffer, length-1)); 321 accumulator = String::Concat(accumulator, String::New(buffer, length-1));
268 } else { 322 } else {
269 return String::Concat(accumulator, String::New(buffer, length-1)); 323 return String::Concat(accumulator, String::New(buffer, length-1));
270 } 324 }
271 } 325 }
272 } 326 }
273 327
274 328
275 Handle<Value> Shell::Load(const Arguments& args) { 329 Handle<Value> Shell::Load(const Arguments& args) {
276 for (int i = 0; i < args.Length(); i++) { 330 for (int i = 0; i < args.Length(); i++) {
277 HandleScope handle_scope; 331 HandleScope handle_scope;
278 String::Utf8Value file(args[i]); 332 String::Utf8Value file(args[i]);
279 if (*file == NULL) { 333 if (*file == NULL) {
280 return ThrowException(String::New("Error loading file")); 334 return Throw("Error loading file");
281 } 335 }
282 Handle<String> source = ReadFile(*file); 336 Handle<String> source = ReadFile(args.GetIsolate(), *file);
283 if (source.IsEmpty()) { 337 if (source.IsEmpty()) {
284 return ThrowException(String::New("Error loading file")); 338 return Throw("Error loading file");
285 } 339 }
286 if (!ExecuteString(source, String::New(*file), false, true)) { 340 if (!ExecuteString(source, String::New(*file), false, true)) {
287 return ThrowException(String::New("Error executing file")); 341 return Throw("Error executing file");
288 } 342 }
289 } 343 }
290 return Undefined(); 344 return Undefined();
291 } 345 }
292 346
293 static int32_t convertToInt(Local<Value> value_in, TryCatch* try_catch) { 347 static int32_t convertToInt(Local<Value> value_in, TryCatch* try_catch) {
294 if (value_in->IsInt32()) { 348 if (value_in->IsInt32()) {
295 return value_in->Int32Value(); 349 return value_in->Int32Value();
296 } 350 }
297 351
298 Local<Value> number = value_in->ToNumber(); 352 Local<Value> number = value_in->ToNumber();
299 if (try_catch->HasCaught()) return 0; 353 if (try_catch->HasCaught()) return 0;
300 354
301 ASSERT(number->IsNumber()); 355 ASSERT(number->IsNumber());
302 Local<Int32> int32 = number->ToInt32(); 356 Local<Int32> int32 = number->ToInt32();
303 if (try_catch->HasCaught() || int32.IsEmpty()) return 0; 357 if (try_catch->HasCaught() || int32.IsEmpty()) return 0;
304 358
305 int32_t value = int32->Int32Value(); 359 int32_t value = int32->Int32Value();
306 if (try_catch->HasCaught()) return 0; 360 if (try_catch->HasCaught()) return 0;
307 361
308 return value; 362 return value;
309 } 363 }
310 364
311 365
312 static int32_t convertToUint(Local<Value> value_in, TryCatch* try_catch) { 366 static int32_t convertToUint(Local<Value> value_in, TryCatch* try_catch) {
313 int32_t raw_value = convertToInt(value_in, try_catch); 367 int32_t raw_value = convertToInt(value_in, try_catch);
314 if (try_catch->HasCaught()) return 0; 368 if (try_catch->HasCaught()) return 0;
315 369
316 if (raw_value < 0) { 370 if (raw_value < 0) {
317 ThrowException(String::New("Array length must not be negative.")); 371 Throw("Array length must not be negative.");
318 return 0; 372 return 0;
319 } 373 }
320 374
321 static const int kMaxLength = 0x3fffffff; 375 static const int kMaxLength = 0x3fffffff;
322 #ifndef V8_SHARED 376 #ifndef V8_SHARED
323 ASSERT(kMaxLength == i::ExternalArray::kMaxLength); 377 ASSERT(kMaxLength == i::ExternalArray::kMaxLength);
324 #endif // V8_SHARED 378 #endif // V8_SHARED
325 if (raw_value > static_cast<int32_t>(kMaxLength)) { 379 if (raw_value > static_cast<int32_t>(kMaxLength)) {
326 ThrowException( 380 Throw("Array length exceeds maximum length.");
327 String::New("Array length exceeds maximum length."));
328 } 381 }
329 return raw_value; 382 return raw_value;
330 } 383 }
331 384
332 385
333 // TODO(rossberg): should replace these by proper uses of HasInstance, 386 Handle<Value> Shell::CreateExternalArrayBuffer(Isolate* isolate,
334 // once we figure out a good way to make the templates global. 387 Handle<Object> buffer,
335 const char kArrayBufferMarkerPropName[] = "d8::_is_array_buffer_";
336 const char kArrayMarkerPropName[] = "d8::_is_typed_array_";
337
338
339 Handle<Value> Shell::CreateExternalArrayBuffer(Handle<Object> buffer,
340 int32_t length) { 388 int32_t length) {
341 static const int32_t kMaxSize = 0x7fffffff; 389 static const int32_t kMaxSize = 0x7fffffff;
342 // Make sure the total size fits into a (signed) int. 390 // Make sure the total size fits into a (signed) int.
343 if (length < 0 || length > kMaxSize) { 391 if (length < 0 || length > kMaxSize) {
344 return ThrowException(String::New("ArrayBuffer exceeds maximum size (2G)")); 392 return Throw("ArrayBuffer exceeds maximum size (2G)");
345 } 393 }
346 uint8_t* data = new uint8_t[length]; 394 uint8_t* data = new uint8_t[length];
347 if (data == NULL) { 395 if (data == NULL) {
348 return ThrowException(String::New("Memory allocation failed")); 396 return Throw("Memory allocation failed");
349 } 397 }
350 memset(data, 0, length); 398 memset(data, 0, length);
351 399
352 buffer->SetHiddenValue(String::New(kArrayBufferMarkerPropName), True()); 400 buffer->SetHiddenValue(Symbols::ArrayBufferMarkerPropName(isolate), True());
353 Persistent<Object> persistent_array = Persistent<Object>::New(buffer); 401 Persistent<Object> persistent_array = Persistent<Object>::New(buffer);
354 persistent_array.MakeWeak(data, ExternalArrayWeakCallback); 402 persistent_array.MakeWeak(data, ExternalArrayWeakCallback);
355 persistent_array.MarkIndependent(); 403 persistent_array.MarkIndependent();
356 V8::AdjustAmountOfExternalAllocatedMemory(length); 404 V8::AdjustAmountOfExternalAllocatedMemory(length);
357 405
358 buffer->SetIndexedPropertiesToExternalArrayData( 406 buffer->SetIndexedPropertiesToExternalArrayData(
359 data, v8::kExternalByteArray, length); 407 data, v8::kExternalByteArray, length);
360 buffer->Set(String::New("byteLength"), Int32::New(length), ReadOnly); 408 buffer->Set(Symbols::byteLength(isolate), Int32::New(length), ReadOnly);
361 409
362 return buffer; 410 return buffer;
363 } 411 }
364 412
365 413
366 Handle<Value> Shell::ArrayBuffer(const Arguments& args) { 414 Handle<Value> Shell::ArrayBuffer(const Arguments& args) {
367 if (!args.IsConstructCall()) { 415 if (!args.IsConstructCall()) {
368 Handle<Value>* rec_args = new Handle<Value>[args.Length()]; 416 Handle<Value>* rec_args = new Handle<Value>[args.Length()];
369 for (int i = 0; i < args.Length(); ++i) rec_args[i] = args[i]; 417 for (int i = 0; i < args.Length(); ++i) rec_args[i] = args[i];
370 Handle<Value> result = args.Callee()->NewInstance(args.Length(), rec_args); 418 Handle<Value> result = args.Callee()->NewInstance(args.Length(), rec_args);
371 delete[] rec_args; 419 delete[] rec_args;
372 return result; 420 return result;
373 } 421 }
374 422
375 if (args.Length() == 0) { 423 if (args.Length() == 0) {
376 return ThrowException( 424 return Throw("ArrayBuffer constructor must have one argument");
377 String::New("ArrayBuffer constructor must have one argument"));
378 } 425 }
379 TryCatch try_catch; 426 TryCatch try_catch;
380 int32_t length = convertToUint(args[0], &try_catch); 427 int32_t length = convertToUint(args[0], &try_catch);
381 if (try_catch.HasCaught()) return try_catch.ReThrow(); 428 if (try_catch.HasCaught()) return try_catch.ReThrow();
382 429
383 return CreateExternalArrayBuffer(args.This(), length); 430 return CreateExternalArrayBuffer(args.GetIsolate(), args.This(), length);
384 } 431 }
385 432
386 433
387 Handle<Object> Shell::CreateExternalArray(Handle<Object> array, 434 Handle<Object> Shell::CreateExternalArray(Isolate* isolate,
435 Handle<Object> array,
388 Handle<Object> buffer, 436 Handle<Object> buffer,
389 ExternalArrayType type, 437 ExternalArrayType type,
390 int32_t length, 438 int32_t length,
391 int32_t byteLength, 439 int32_t byteLength,
392 int32_t byteOffset, 440 int32_t byteOffset,
393 int32_t element_size) { 441 int32_t element_size) {
394 ASSERT(element_size == 1 || element_size == 2 || 442 ASSERT(element_size == 1 || element_size == 2 ||
395 element_size == 4 || element_size == 8); 443 element_size == 4 || element_size == 8);
396 ASSERT(byteLength == length * element_size); 444 ASSERT(byteLength == length * element_size);
397 445
398 void* data = buffer->GetIndexedPropertiesExternalArrayData(); 446 void* data = buffer->GetIndexedPropertiesExternalArrayData();
399 ASSERT(data != NULL); 447 ASSERT(data != NULL);
400 448
401 array->SetIndexedPropertiesToExternalArrayData( 449 array->SetIndexedPropertiesToExternalArrayData(
402 static_cast<uint8_t*>(data) + byteOffset, type, length); 450 static_cast<uint8_t*>(data) + byteOffset, type, length);
403 array->SetHiddenValue(String::New(kArrayMarkerPropName), Int32::New(type)); 451 array->SetHiddenValue(Symbols::ArrayMarkerPropName(isolate),
404 array->Set(String::New("byteLength"), Int32::New(byteLength), ReadOnly); 452 Int32::New(type));
405 array->Set(String::New("byteOffset"), Int32::New(byteOffset), ReadOnly); 453 array->Set(Symbols::byteLength(isolate), Int32::New(byteLength), ReadOnly);
406 array->Set(String::New("length"), Int32::New(length), ReadOnly); 454 array->Set(Symbols::byteOffset(isolate), Int32::New(byteOffset), ReadOnly);
407 array->Set(String::New("BYTES_PER_ELEMENT"), Int32::New(element_size)); 455 array->Set(Symbols::length(isolate), Int32::New(length), ReadOnly);
408 array->Set(String::New("buffer"), buffer, ReadOnly); 456 array->Set(Symbols::BYTES_PER_ELEMENT(isolate), Int32::New(element_size));
457 array->Set(Symbols::buffer(isolate), buffer, ReadOnly);
409 458
410 return array; 459 return array;
411 } 460 }
412 461
413 462
414 Handle<Value> Shell::CreateExternalArray(const Arguments& args, 463 Handle<Value> Shell::CreateExternalArray(const Arguments& args,
415 ExternalArrayType type, 464 ExternalArrayType type,
416 int32_t element_size) { 465 int32_t element_size) {
466 Isolate* isolate = args.GetIsolate();
417 if (!args.IsConstructCall()) { 467 if (!args.IsConstructCall()) {
418 Handle<Value>* rec_args = new Handle<Value>[args.Length()]; 468 Handle<Value>* rec_args = new Handle<Value>[args.Length()];
419 for (int i = 0; i < args.Length(); ++i) rec_args[i] = args[i]; 469 for (int i = 0; i < args.Length(); ++i) rec_args[i] = args[i];
420 Handle<Value> result = args.Callee()->NewInstance(args.Length(), rec_args); 470 Handle<Value> result = args.Callee()->NewInstance(args.Length(), rec_args);
421 delete[] rec_args; 471 delete[] rec_args;
422 return result; 472 return result;
423 } 473 }
424 474
425 TryCatch try_catch; 475 TryCatch try_catch;
426 ASSERT(element_size == 1 || element_size == 2 || 476 ASSERT(element_size == 1 || element_size == 2 ||
427 element_size == 4 || element_size == 8); 477 element_size == 4 || element_size == 8);
428 478
429 // All of the following constructors are supported: 479 // All of the following constructors are supported:
430 // TypedArray(unsigned long length) 480 // TypedArray(unsigned long length)
431 // TypedArray(type[] array) 481 // TypedArray(type[] array)
432 // TypedArray(TypedArray array) 482 // TypedArray(TypedArray array)
433 // TypedArray(ArrayBuffer buffer, 483 // TypedArray(ArrayBuffer buffer,
434 // optional unsigned long byteOffset, 484 // optional unsigned long byteOffset,
435 // optional unsigned long length) 485 // optional unsigned long length)
436 Handle<Object> buffer; 486 Handle<Object> buffer;
437 int32_t length; 487 int32_t length;
438 int32_t byteLength; 488 int32_t byteLength;
439 int32_t byteOffset; 489 int32_t byteOffset;
440 bool init_from_array = false; 490 bool init_from_array = false;
441 if (args.Length() == 0) { 491 if (args.Length() == 0) {
442 return ThrowException( 492 return Throw("Array constructor must have at least one argument");
443 String::New("Array constructor must have at least one argument"));
444 } 493 }
445 if (args[0]->IsObject() && 494 if (args[0]->IsObject() &&
446 !args[0]->ToObject()->GetHiddenValue( 495 !args[0]->ToObject()->GetHiddenValue(
447 String::New(kArrayBufferMarkerPropName)).IsEmpty()) { 496 Symbols::ArrayBufferMarkerPropName(isolate)).IsEmpty()) {
448 // Construct from ArrayBuffer. 497 // Construct from ArrayBuffer.
449 buffer = args[0]->ToObject(); 498 buffer = args[0]->ToObject();
450 int32_t bufferLength = 499 int32_t bufferLength =
451 convertToUint(buffer->Get(String::New("byteLength")), &try_catch); 500 convertToUint(buffer->Get(Symbols::byteLength(isolate)), &try_catch);
452 if (try_catch.HasCaught()) return try_catch.ReThrow(); 501 if (try_catch.HasCaught()) return try_catch.ReThrow();
453 502
454 if (args.Length() < 2 || args[1]->IsUndefined()) { 503 if (args.Length() < 2 || args[1]->IsUndefined()) {
455 byteOffset = 0; 504 byteOffset = 0;
456 } else { 505 } else {
457 byteOffset = convertToUint(args[1], &try_catch); 506 byteOffset = convertToUint(args[1], &try_catch);
458 if (try_catch.HasCaught()) return try_catch.ReThrow(); 507 if (try_catch.HasCaught()) return try_catch.ReThrow();
459 if (byteOffset > bufferLength) { 508 if (byteOffset > bufferLength) {
460 return ThrowException(String::New("byteOffset out of bounds")); 509 return Throw("byteOffset out of bounds");
461 } 510 }
462 if (byteOffset % element_size != 0) { 511 if (byteOffset % element_size != 0) {
463 return ThrowException( 512 return Throw("byteOffset must be multiple of element size");
464 String::New("byteOffset must be multiple of element size"));
465 } 513 }
466 } 514 }
467 515
468 if (args.Length() < 3 || args[2]->IsUndefined()) { 516 if (args.Length() < 3 || args[2]->IsUndefined()) {
469 byteLength = bufferLength - byteOffset; 517 byteLength = bufferLength - byteOffset;
470 length = byteLength / element_size; 518 length = byteLength / element_size;
471 if (byteLength % element_size != 0) { 519 if (byteLength % element_size != 0) {
472 return ThrowException( 520 return Throw("buffer size must be multiple of element size");
473 String::New("buffer size must be multiple of element size"));
474 } 521 }
475 } else { 522 } else {
476 length = convertToUint(args[2], &try_catch); 523 length = convertToUint(args[2], &try_catch);
477 if (try_catch.HasCaught()) return try_catch.ReThrow(); 524 if (try_catch.HasCaught()) return try_catch.ReThrow();
478 byteLength = length * element_size; 525 byteLength = length * element_size;
479 if (byteOffset + byteLength > bufferLength) { 526 if (byteOffset + byteLength > bufferLength) {
480 return ThrowException(String::New("length out of bounds")); 527 return Throw("length out of bounds");
481 } 528 }
482 } 529 }
483 } else { 530 } else {
484 if (args[0]->IsObject() && 531 if (args[0]->IsObject() &&
485 args[0]->ToObject()->Has(String::New("length"))) { 532 args[0]->ToObject()->Has(Symbols::length(isolate))) {
486 // Construct from array. 533 // Construct from array.
487 length = convertToUint( 534 length = convertToUint(
488 args[0]->ToObject()->Get(String::New("length")), &try_catch); 535 args[0]->ToObject()->Get(Symbols::length(isolate)), &try_catch);
489 if (try_catch.HasCaught()) return try_catch.ReThrow(); 536 if (try_catch.HasCaught()) return try_catch.ReThrow();
490 init_from_array = true; 537 init_from_array = true;
491 } else { 538 } else {
492 // Construct from size. 539 // Construct from size.
493 length = convertToUint(args[0], &try_catch); 540 length = convertToUint(args[0], &try_catch);
494 if (try_catch.HasCaught()) return try_catch.ReThrow(); 541 if (try_catch.HasCaught()) return try_catch.ReThrow();
495 } 542 }
496 byteLength = length * element_size; 543 byteLength = length * element_size;
497 byteOffset = 0; 544 byteOffset = 0;
498 545
499 Handle<Object> global = Context::GetCurrent()->Global(); 546 Handle<Object> global = Context::GetCurrent()->Global();
500 Handle<Value> array_buffer = global->Get(String::New("ArrayBuffer")); 547 Handle<Value> array_buffer = global->Get(Symbols::ArrayBuffer(isolate));
501 ASSERT(!try_catch.HasCaught() && array_buffer->IsFunction()); 548 ASSERT(!try_catch.HasCaught() && array_buffer->IsFunction());
502 Handle<Value> buffer_args[] = { Uint32::New(byteLength) }; 549 Handle<Value> buffer_args[] = { Uint32::New(byteLength) };
503 Handle<Value> result = Handle<Function>::Cast(array_buffer)->NewInstance( 550 Handle<Value> result = Handle<Function>::Cast(array_buffer)->NewInstance(
504 1, buffer_args); 551 1, buffer_args);
505 if (try_catch.HasCaught()) return result; 552 if (try_catch.HasCaught()) return result;
506 buffer = result->ToObject(); 553 buffer = result->ToObject();
507 } 554 }
508 555
509 Handle<Object> array = CreateExternalArray( 556 Handle<Object> array =
510 args.This(), buffer, type, length, byteLength, byteOffset, element_size); 557 CreateExternalArray(isolate, args.This(), buffer, type, length,
558 byteLength, byteOffset, element_size);
511 559
512 if (init_from_array) { 560 if (init_from_array) {
513 Handle<Object> init = args[0]->ToObject(); 561 Handle<Object> init = args[0]->ToObject();
514 for (int i = 0; i < length; ++i) array->Set(i, init->Get(i)); 562 for (int i = 0; i < length; ++i) array->Set(i, init->Get(i));
515 } 563 }
516 564
517 return array; 565 return array;
518 } 566 }
519 567
520 568
521 Handle<Value> Shell::ArrayBufferSlice(const Arguments& args) { 569 Handle<Value> Shell::ArrayBufferSlice(const Arguments& args) {
522 TryCatch try_catch; 570 TryCatch try_catch;
523 571
524 if (!args.This()->IsObject()) { 572 if (!args.This()->IsObject()) {
525 return ThrowException( 573 return Throw("'slice' invoked on non-object receiver");
526 String::New("'slice' invoked on non-object receiver"));
527 } 574 }
528 575
576 Isolate* isolate = args.GetIsolate();
529 Local<Object> self = args.This(); 577 Local<Object> self = args.This();
530 Local<Value> marker = 578 Local<Value> marker =
531 self->GetHiddenValue(String::New(kArrayBufferMarkerPropName)); 579 self->GetHiddenValue(Symbols::ArrayBufferMarkerPropName(isolate));
532 if (marker.IsEmpty()) { 580 if (marker.IsEmpty()) {
533 return ThrowException( 581 return Throw("'slice' invoked on wrong receiver type");
534 String::New("'slice' invoked on wrong receiver type"));
535 } 582 }
536 583
537 int32_t length = 584 int32_t length =
538 convertToUint(self->Get(String::New("byteLength")), &try_catch); 585 convertToUint(self->Get(Symbols::byteLength(isolate)), &try_catch);
539 if (try_catch.HasCaught()) return try_catch.ReThrow(); 586 if (try_catch.HasCaught()) return try_catch.ReThrow();
540 587
541 if (args.Length() == 0) { 588 if (args.Length() == 0) {
542 return ThrowException( 589 return Throw("'slice' must have at least one argument");
543 String::New("'slice' must have at least one argument"));
544 } 590 }
545 int32_t begin = convertToInt(args[0], &try_catch); 591 int32_t begin = convertToInt(args[0], &try_catch);
546 if (try_catch.HasCaught()) return try_catch.ReThrow(); 592 if (try_catch.HasCaught()) return try_catch.ReThrow();
547 if (begin < 0) begin += length; 593 if (begin < 0) begin += length;
548 if (begin < 0) begin = 0; 594 if (begin < 0) begin = 0;
549 if (begin > length) begin = length; 595 if (begin > length) begin = length;
550 596
551 int32_t end; 597 int32_t end;
552 if (args.Length() < 2 || args[1]->IsUndefined()) { 598 if (args.Length() < 2 || args[1]->IsUndefined()) {
553 end = length; 599 end = length;
(...skipping 18 matching lines...) Expand all
572 memcpy(dest, src, end - begin); 618 memcpy(dest, src, end - begin);
573 619
574 return buffer; 620 return buffer;
575 } 621 }
576 622
577 623
578 Handle<Value> Shell::ArraySubArray(const Arguments& args) { 624 Handle<Value> Shell::ArraySubArray(const Arguments& args) {
579 TryCatch try_catch; 625 TryCatch try_catch;
580 626
581 if (!args.This()->IsObject()) { 627 if (!args.This()->IsObject()) {
582 return ThrowException( 628 return Throw("'subarray' invoked on non-object receiver");
583 String::New("'subarray' invoked on non-object receiver"));
584 } 629 }
585 630
631 Isolate* isolate = args.GetIsolate();
586 Local<Object> self = args.This(); 632 Local<Object> self = args.This();
587 Local<Value> marker = self->GetHiddenValue(String::New(kArrayMarkerPropName)); 633 Local<Value> marker =
634 self->GetHiddenValue(Symbols::ArrayMarkerPropName(isolate));
588 if (marker.IsEmpty()) { 635 if (marker.IsEmpty()) {
589 return ThrowException( 636 return Throw("'subarray' invoked on wrong receiver type");
590 String::New("'subarray' invoked on wrong receiver type"));
591 } 637 }
592 638
593 Handle<Object> buffer = self->Get(String::New("buffer"))->ToObject(); 639 Handle<Object> buffer = self->Get(Symbols::buffer(isolate))->ToObject();
594 if (try_catch.HasCaught()) return try_catch.ReThrow(); 640 if (try_catch.HasCaught()) return try_catch.ReThrow();
595 int32_t length = 641 int32_t length =
596 convertToUint(self->Get(String::New("length")), &try_catch); 642 convertToUint(self->Get(Symbols::length(isolate)), &try_catch);
597 if (try_catch.HasCaught()) return try_catch.ReThrow(); 643 if (try_catch.HasCaught()) return try_catch.ReThrow();
598 int32_t byteOffset = 644 int32_t byteOffset =
599 convertToUint(self->Get(String::New("byteOffset")), &try_catch); 645 convertToUint(self->Get(Symbols::byteOffset(isolate)), &try_catch);
600 if (try_catch.HasCaught()) return try_catch.ReThrow(); 646 if (try_catch.HasCaught()) return try_catch.ReThrow();
601 int32_t element_size = 647 int32_t element_size =
602 convertToUint(self->Get(String::New("BYTES_PER_ELEMENT")), &try_catch); 648 convertToUint(self->Get(Symbols::BYTES_PER_ELEMENT(isolate)), &try_catch);
603 if (try_catch.HasCaught()) return try_catch.ReThrow(); 649 if (try_catch.HasCaught()) return try_catch.ReThrow();
604 650
605 if (args.Length() == 0) { 651 if (args.Length() == 0) {
606 return ThrowException( 652 return Throw("'subarray' must have at least one argument");
607 String::New("'subarray' must have at least one argument"));
608 } 653 }
609 int32_t begin = convertToInt(args[0], &try_catch); 654 int32_t begin = convertToInt(args[0], &try_catch);
610 if (try_catch.HasCaught()) return try_catch.ReThrow(); 655 if (try_catch.HasCaught()) return try_catch.ReThrow();
611 if (begin < 0) begin += length; 656 if (begin < 0) begin += length;
612 if (begin < 0) begin = 0; 657 if (begin < 0) begin = 0;
613 if (begin > length) begin = length; 658 if (begin > length) begin = length;
614 659
615 int32_t end; 660 int32_t end;
616 if (args.Length() < 2 || args[1]->IsUndefined()) { 661 if (args.Length() < 2 || args[1]->IsUndefined()) {
617 end = length; 662 end = length;
(...skipping 14 matching lines...) Expand all
632 buffer, Uint32::New(byteOffset), Uint32::New(length) 677 buffer, Uint32::New(byteOffset), Uint32::New(length)
633 }; 678 };
634 return constructor->NewInstance(3, construct_args); 679 return constructor->NewInstance(3, construct_args);
635 } 680 }
636 681
637 682
638 Handle<Value> Shell::ArraySet(const Arguments& args) { 683 Handle<Value> Shell::ArraySet(const Arguments& args) {
639 TryCatch try_catch; 684 TryCatch try_catch;
640 685
641 if (!args.This()->IsObject()) { 686 if (!args.This()->IsObject()) {
642 return ThrowException( 687 return Throw("'set' invoked on non-object receiver");
643 String::New("'set' invoked on non-object receiver"));
644 } 688 }
645 689
690 Isolate* isolate = args.GetIsolate();
646 Local<Object> self = args.This(); 691 Local<Object> self = args.This();
647 Local<Value> marker = self->GetHiddenValue(String::New(kArrayMarkerPropName)); 692 Local<Value> marker =
693 self->GetHiddenValue(Symbols::ArrayMarkerPropName(isolate));
648 if (marker.IsEmpty()) { 694 if (marker.IsEmpty()) {
649 return ThrowException( 695 return Throw("'set' invoked on wrong receiver type");
650 String::New("'set' invoked on wrong receiver type"));
651 } 696 }
652 int32_t length = 697 int32_t length =
653 convertToUint(self->Get(String::New("length")), &try_catch); 698 convertToUint(self->Get(Symbols::length(isolate)), &try_catch);
654 if (try_catch.HasCaught()) return try_catch.ReThrow(); 699 if (try_catch.HasCaught()) return try_catch.ReThrow();
655 int32_t element_size = 700 int32_t element_size =
656 convertToUint(self->Get(String::New("BYTES_PER_ELEMENT")), &try_catch); 701 convertToUint(self->Get(Symbols::BYTES_PER_ELEMENT(isolate)), &try_catch);
657 if (try_catch.HasCaught()) return try_catch.ReThrow(); 702 if (try_catch.HasCaught()) return try_catch.ReThrow();
658 703
659 if (args.Length() == 0) { 704 if (args.Length() == 0) {
660 return ThrowException( 705 return Throw("'set' must have at least one argument");
661 String::New("'set' must have at least one argument"));
662 } 706 }
663 if (!args[0]->IsObject() || 707 if (!args[0]->IsObject() ||
664 !args[0]->ToObject()->Has(String::New("length"))) { 708 !args[0]->ToObject()->Has(Symbols::length(isolate))) {
665 return ThrowException( 709 return Throw("'set' invoked with non-array argument");
666 String::New("'set' invoked with non-array argument"));
667 } 710 }
668 Handle<Object> source = args[0]->ToObject(); 711 Handle<Object> source = args[0]->ToObject();
669 int32_t source_length = 712 int32_t source_length =
670 convertToUint(source->Get(String::New("length")), &try_catch); 713 convertToUint(source->Get(Symbols::length(isolate)), &try_catch);
671 if (try_catch.HasCaught()) return try_catch.ReThrow(); 714 if (try_catch.HasCaught()) return try_catch.ReThrow();
672 715
673 int32_t offset; 716 int32_t offset;
674 if (args.Length() < 2 || args[1]->IsUndefined()) { 717 if (args.Length() < 2 || args[1]->IsUndefined()) {
675 offset = 0; 718 offset = 0;
676 } else { 719 } else {
677 offset = convertToUint(args[1], &try_catch); 720 offset = convertToUint(args[1], &try_catch);
678 if (try_catch.HasCaught()) return try_catch.ReThrow(); 721 if (try_catch.HasCaught()) return try_catch.ReThrow();
679 } 722 }
680 if (offset + source_length > length) { 723 if (offset + source_length > length) {
681 return ThrowException(String::New("offset or source length out of bounds")); 724 return Throw("offset or source length out of bounds");
682 } 725 }
683 726
684 int32_t source_element_size; 727 int32_t source_element_size;
685 if (source->GetHiddenValue(String::New(kArrayMarkerPropName)).IsEmpty()) { 728 if (source->GetHiddenValue(Symbols::ArrayMarkerPropName(isolate)).IsEmpty()) {
686 source_element_size = 0; 729 source_element_size = 0;
687 } else { 730 } else {
688 source_element_size = 731 source_element_size =
689 convertToUint(source->Get(String::New("BYTES_PER_ELEMENT")), &try_catch); 732 convertToUint(source->Get(Symbols::BYTES_PER_ELEMENT(isolate)),
733 &try_catch);
690 if (try_catch.HasCaught()) return try_catch.ReThrow(); 734 if (try_catch.HasCaught()) return try_catch.ReThrow();
691 } 735 }
692 736
693 if (element_size == source_element_size && 737 if (element_size == source_element_size &&
694 self->GetConstructor()->StrictEquals(source->GetConstructor())) { 738 self->GetConstructor()->StrictEquals(source->GetConstructor())) {
695 // Use memmove on the array buffers. 739 // Use memmove on the array buffers.
696 Handle<Object> buffer = self->Get(String::New("buffer"))->ToObject(); 740 Handle<Object> buffer = self->Get(Symbols::buffer(isolate))->ToObject();
697 if (try_catch.HasCaught()) return try_catch.ReThrow(); 741 if (try_catch.HasCaught()) return try_catch.ReThrow();
698 Handle<Object> source_buffer = 742 Handle<Object> source_buffer =
699 source->Get(String::New("buffer"))->ToObject(); 743 source->Get(Symbols::buffer(isolate))->ToObject();
700 if (try_catch.HasCaught()) return try_catch.ReThrow(); 744 if (try_catch.HasCaught()) return try_catch.ReThrow();
701 int32_t byteOffset = 745 int32_t byteOffset =
702 convertToUint(self->Get(String::New("byteOffset")), &try_catch); 746 convertToUint(self->Get(Symbols::byteOffset(isolate)), &try_catch);
703 if (try_catch.HasCaught()) return try_catch.ReThrow(); 747 if (try_catch.HasCaught()) return try_catch.ReThrow();
704 int32_t source_byteOffset = 748 int32_t source_byteOffset =
705 convertToUint(source->Get(String::New("byteOffset")), &try_catch); 749 convertToUint(source->Get(Symbols::byteOffset(isolate)), &try_catch);
706 if (try_catch.HasCaught()) return try_catch.ReThrow(); 750 if (try_catch.HasCaught()) return try_catch.ReThrow();
707 751
708 uint8_t* dest = byteOffset + offset * element_size + static_cast<uint8_t*>( 752 uint8_t* dest = byteOffset + offset * element_size + static_cast<uint8_t*>(
709 buffer->GetIndexedPropertiesExternalArrayData()); 753 buffer->GetIndexedPropertiesExternalArrayData());
710 uint8_t* src = source_byteOffset + static_cast<uint8_t*>( 754 uint8_t* src = source_byteOffset + static_cast<uint8_t*>(
711 source_buffer->GetIndexedPropertiesExternalArrayData()); 755 source_buffer->GetIndexedPropertiesExternalArrayData());
712 memmove(dest, src, source_length * element_size); 756 memmove(dest, src, source_length * element_size);
713 } else if (source_element_size == 0) { 757 } else if (source_element_size == 0) {
714 // Source is not a typed array, copy element-wise sequentially. 758 // Source is not a typed array, copy element-wise sequentially.
715 for (int i = 0; i < source_length; ++i) { 759 for (int i = 0; i < source_length; ++i) {
716 self->Set(offset + i, source->Get(i)); 760 self->Set(offset + i, source->Get(i));
717 if (try_catch.HasCaught()) return try_catch.ReThrow(); 761 if (try_catch.HasCaught()) return try_catch.ReThrow();
718 } 762 }
719 } else { 763 } else {
720 // Need to copy element-wise to make the right conversions. 764 // Need to copy element-wise to make the right conversions.
721 Handle<Object> buffer = self->Get(String::New("buffer"))->ToObject(); 765 Handle<Object> buffer = self->Get(Symbols::buffer(isolate))->ToObject();
722 if (try_catch.HasCaught()) return try_catch.ReThrow(); 766 if (try_catch.HasCaught()) return try_catch.ReThrow();
723 Handle<Object> source_buffer = 767 Handle<Object> source_buffer =
724 source->Get(String::New("buffer"))->ToObject(); 768 source->Get(Symbols::buffer(isolate))->ToObject();
725 if (try_catch.HasCaught()) return try_catch.ReThrow(); 769 if (try_catch.HasCaught()) return try_catch.ReThrow();
726 770
727 if (buffer->StrictEquals(source_buffer)) { 771 if (buffer->StrictEquals(source_buffer)) {
728 // Same backing store, need to handle overlap correctly. 772 // Same backing store, need to handle overlap correctly.
729 // This gets a bit tricky in the case of different element sizes 773 // This gets a bit tricky in the case of different element sizes
730 // (which, of course, is extremely unlikely to ever occur in practice). 774 // (which, of course, is extremely unlikely to ever occur in practice).
731 int32_t byteOffset = 775 int32_t byteOffset =
732 convertToUint(self->Get(String::New("byteOffset")), &try_catch); 776 convertToUint(self->Get(Symbols::byteOffset(isolate)), &try_catch);
733 if (try_catch.HasCaught()) return try_catch.ReThrow(); 777 if (try_catch.HasCaught()) return try_catch.ReThrow();
734 int32_t source_byteOffset = 778 int32_t source_byteOffset =
735 convertToUint(source->Get(String::New("byteOffset")), &try_catch); 779 convertToUint(source->Get(Symbols::byteOffset(isolate)), &try_catch);
736 if (try_catch.HasCaught()) return try_catch.ReThrow(); 780 if (try_catch.HasCaught()) return try_catch.ReThrow();
737 781
738 // Copy as much as we can from left to right. 782 // Copy as much as we can from left to right.
739 int i = 0; 783 int i = 0;
740 int32_t next_dest_offset = byteOffset + (offset + 1) * element_size; 784 int32_t next_dest_offset = byteOffset + (offset + 1) * element_size;
741 int32_t next_src_offset = source_byteOffset + source_element_size; 785 int32_t next_src_offset = source_byteOffset + source_element_size;
742 while (i < length && next_dest_offset <= next_src_offset) { 786 while (i < length && next_dest_offset <= next_src_offset) {
743 self->Set(offset + i, source->Get(i)); 787 self->Set(offset + i, source->Get(i));
744 ++i; 788 ++i;
745 next_dest_offset += element_size; 789 next_dest_offset += element_size;
(...skipping 25 matching lines...) Expand all
771 self->Set(offset + i, source->Get(i)); 815 self->Set(offset + i, source->Get(i));
772 } 816 }
773 } 817 }
774 818
775 return Undefined(); 819 return Undefined();
776 } 820 }
777 821
778 822
779 void Shell::ExternalArrayWeakCallback(Persistent<Value> object, void* data) { 823 void Shell::ExternalArrayWeakCallback(Persistent<Value> object, void* data) {
780 HandleScope scope; 824 HandleScope scope;
825 Isolate* isolate = Isolate::GetCurrent();
781 int32_t length = 826 int32_t length =
782 object->ToObject()->Get(String::New("byteLength"))->Uint32Value(); 827 object->ToObject()->Get(Symbols::byteLength(isolate))->Uint32Value();
783 V8::AdjustAmountOfExternalAllocatedMemory(-length); 828 V8::AdjustAmountOfExternalAllocatedMemory(-length);
784 delete[] static_cast<uint8_t*>(data); 829 delete[] static_cast<uint8_t*>(data);
785 object.Dispose(); 830 object.Dispose();
786 } 831 }
787 832
788 833
789 Handle<Value> Shell::Int8Array(const Arguments& args) { 834 Handle<Value> Shell::Int8Array(const Arguments& args) {
790 return CreateExternalArray(args, v8::kExternalByteArray, sizeof(int8_t)); 835 return CreateExternalArray(args, v8::kExternalByteArray, sizeof(int8_t));
791 } 836 }
792 837
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after
1138 Handle<FunctionTemplate> Shell::CreateArrayTemplate(InvocationCallback fun) { 1183 Handle<FunctionTemplate> Shell::CreateArrayTemplate(InvocationCallback fun) {
1139 Handle<FunctionTemplate> array_template = FunctionTemplate::New(fun); 1184 Handle<FunctionTemplate> array_template = FunctionTemplate::New(fun);
1140 Local<Template> proto_template = array_template->PrototypeTemplate(); 1185 Local<Template> proto_template = array_template->PrototypeTemplate();
1141 proto_template->Set(String::New("set"), FunctionTemplate::New(ArraySet)); 1186 proto_template->Set(String::New("set"), FunctionTemplate::New(ArraySet));
1142 proto_template->Set(String::New("subarray"), 1187 proto_template->Set(String::New("subarray"),
1143 FunctionTemplate::New(ArraySubArray)); 1188 FunctionTemplate::New(ArraySubArray));
1144 return array_template; 1189 return array_template;
1145 } 1190 }
1146 1191
1147 1192
1148 Handle<ObjectTemplate> Shell::CreateGlobalTemplate() { 1193 Handle<ObjectTemplate> Shell::CreateGlobalTemplate(Isolate* isolate) {
1149 Handle<ObjectTemplate> global_template = ObjectTemplate::New(); 1194 Handle<ObjectTemplate> global_template = ObjectTemplate::New();
1150 global_template->Set(String::New("print"), FunctionTemplate::New(Print)); 1195 global_template->Set(String::New("print"), FunctionTemplate::New(Print));
1151 global_template->Set(String::New("write"), FunctionTemplate::New(Write)); 1196 global_template->Set(String::New("write"), FunctionTemplate::New(Write));
1152 global_template->Set(String::New("read"), FunctionTemplate::New(Read)); 1197 global_template->Set(String::New("read"), FunctionTemplate::New(Read));
1153 global_template->Set(String::New("readbuffer"), 1198 global_template->Set(String::New("readbuffer"),
1154 FunctionTemplate::New(ReadBuffer)); 1199 FunctionTemplate::New(ReadBuffer));
1155 global_template->Set(String::New("readline"), 1200 global_template->Set(String::New("readline"),
1156 FunctionTemplate::New(ReadLine)); 1201 FunctionTemplate::New(ReadLine));
1157 global_template->Set(String::New("load"), FunctionTemplate::New(Load)); 1202 global_template->Set(String::New("load"), FunctionTemplate::New(Load));
1158 global_template->Set(String::New("quit"), FunctionTemplate::New(Quit)); 1203 global_template->Set(String::New("quit"), FunctionTemplate::New(Quit));
1159 global_template->Set(String::New("version"), FunctionTemplate::New(Version)); 1204 global_template->Set(String::New("version"), FunctionTemplate::New(Version));
1160 global_template->Set(String::New("enableProfiler"), 1205 global_template->Set(String::New("enableProfiler"),
1161 FunctionTemplate::New(EnableProfiler)); 1206 FunctionTemplate::New(EnableProfiler));
1162 global_template->Set(String::New("disableProfiler"), 1207 global_template->Set(String::New("disableProfiler"),
1163 FunctionTemplate::New(DisableProfiler)); 1208 FunctionTemplate::New(DisableProfiler));
1164 1209
1165 // Bind the handlers for external arrays. 1210 // Bind the handlers for external arrays.
1166 PropertyAttribute attr = 1211 PropertyAttribute attr =
1167 static_cast<PropertyAttribute>(ReadOnly | DontDelete); 1212 static_cast<PropertyAttribute>(ReadOnly | DontDelete);
1168 global_template->Set(String::New("ArrayBuffer"), 1213 global_template->Set(Symbols::ArrayBuffer(isolate),
1169 CreateArrayBufferTemplate(ArrayBuffer), attr); 1214 CreateArrayBufferTemplate(ArrayBuffer), attr);
1170 global_template->Set(String::New("Int8Array"), 1215 global_template->Set(String::New("Int8Array"),
1171 CreateArrayTemplate(Int8Array), attr); 1216 CreateArrayTemplate(Int8Array), attr);
1172 global_template->Set(String::New("Uint8Array"), 1217 global_template->Set(String::New("Uint8Array"),
1173 CreateArrayTemplate(Uint8Array), attr); 1218 CreateArrayTemplate(Uint8Array), attr);
1174 global_template->Set(String::New("Int16Array"), 1219 global_template->Set(String::New("Int16Array"),
1175 CreateArrayTemplate(Int16Array), attr); 1220 CreateArrayTemplate(Int16Array), attr);
1176 global_template->Set(String::New("Uint16Array"), 1221 global_template->Set(String::New("Uint16Array"),
1177 CreateArrayTemplate(Uint16Array), attr); 1222 CreateArrayTemplate(Uint16Array), attr);
1178 global_template->Set(String::New("Int32Array"), 1223 global_template->Set(String::New("Int32Array"),
(...skipping 16 matching lines...) Expand all
1195 #if !defined(V8_SHARED) && !defined(_WIN32) && !defined(_WIN64) 1240 #if !defined(V8_SHARED) && !defined(_WIN32) && !defined(_WIN64)
1196 Handle<ObjectTemplate> os_templ = ObjectTemplate::New(); 1241 Handle<ObjectTemplate> os_templ = ObjectTemplate::New();
1197 AddOSMethods(os_templ); 1242 AddOSMethods(os_templ);
1198 global_template->Set(String::New("os"), os_templ); 1243 global_template->Set(String::New("os"), os_templ);
1199 #endif // V8_SHARED 1244 #endif // V8_SHARED
1200 1245
1201 return global_template; 1246 return global_template;
1202 } 1247 }
1203 1248
1204 1249
1205 void Shell::Initialize() { 1250 void Shell::Initialize(Isolate* isolate) {
1206 #ifdef COMPRESS_STARTUP_DATA_BZ2 1251 #ifdef COMPRESS_STARTUP_DATA_BZ2
1207 BZip2Decompressor startup_data_decompressor; 1252 BZip2Decompressor startup_data_decompressor;
1208 int bz2_result = startup_data_decompressor.Decompress(); 1253 int bz2_result = startup_data_decompressor.Decompress();
1209 if (bz2_result != BZ_OK) { 1254 if (bz2_result != BZ_OK) {
1210 fprintf(stderr, "bzip error code: %d\n", bz2_result); 1255 fprintf(stderr, "bzip error code: %d\n", bz2_result);
1211 Exit(1); 1256 Exit(1);
1212 } 1257 }
1213 #endif 1258 #endif
1214 1259
1215 #ifndef V8_SHARED 1260 #ifndef V8_SHARED
1216 Shell::counter_map_ = new CounterMap(); 1261 Shell::counter_map_ = new CounterMap();
1217 // Set up counters 1262 // Set up counters
1218 if (i::StrLength(i::FLAG_map_counters) != 0) 1263 if (i::StrLength(i::FLAG_map_counters) != 0)
1219 MapCounters(i::FLAG_map_counters); 1264 MapCounters(i::FLAG_map_counters);
1220 if (i::FLAG_dump_counters || i::FLAG_track_gc_object_stats) { 1265 if (i::FLAG_dump_counters || i::FLAG_track_gc_object_stats) {
1221 V8::SetCounterFunction(LookupCounter); 1266 V8::SetCounterFunction(LookupCounter);
1222 V8::SetCreateHistogramFunction(CreateHistogram); 1267 V8::SetCreateHistogramFunction(CreateHistogram);
1223 V8::SetAddHistogramSampleFunction(AddHistogramSample); 1268 V8::SetAddHistogramSampleFunction(AddHistogramSample);
1224 } 1269 }
1225 #endif // V8_SHARED 1270 #endif // V8_SHARED
1226 if (options.test_shell) return; 1271 if (options.test_shell) return;
1227 1272
1228 #ifndef V8_SHARED 1273 #ifndef V8_SHARED
1229 Locker lock; 1274 Locker lock;
1230 HandleScope scope; 1275 HandleScope scope;
1231 Handle<ObjectTemplate> global_template = CreateGlobalTemplate(); 1276 Handle<ObjectTemplate> global_template = CreateGlobalTemplate(isolate);
1232 utility_context_ = Context::New(NULL, global_template); 1277 utility_context_ = Context::New(NULL, global_template);
1233 1278
1234 #ifdef ENABLE_DEBUGGER_SUPPORT 1279 #ifdef ENABLE_DEBUGGER_SUPPORT
1235 // Start the debugger agent if requested. 1280 // Start the debugger agent if requested.
1236 if (i::FLAG_debugger_agent) { 1281 if (i::FLAG_debugger_agent) {
1237 v8::Debug::EnableAgent("d8 shell", i::FLAG_debugger_port, true); 1282 v8::Debug::EnableAgent("d8 shell", i::FLAG_debugger_port, true);
1238 v8::Debug::SetDebugMessageDispatchHandler(DispatchDebugMessages, true); 1283 v8::Debug::SetDebugMessageDispatchHandler(DispatchDebugMessages, true);
1239 } 1284 }
1240 #endif // ENABLE_DEBUGGER_SUPPORT 1285 #endif // ENABLE_DEBUGGER_SUPPORT
1241 #endif // V8_SHARED 1286 #endif // V8_SHARED
1242 } 1287 }
1243 1288
1244 1289
1245 Persistent<Context> Shell::CreateEvaluationContext() { 1290 Persistent<Context> Shell::CreateEvaluationContext(Isolate* isolate) {
1246 #ifndef V8_SHARED 1291 #ifndef V8_SHARED
1247 // This needs to be a critical section since this is not thread-safe 1292 // This needs to be a critical section since this is not thread-safe
1248 i::ScopedLock lock(context_mutex_); 1293 i::ScopedLock lock(context_mutex_);
1249 #endif // V8_SHARED 1294 #endif // V8_SHARED
1250 // Initialize the global objects 1295 // Initialize the global objects
1251 Handle<ObjectTemplate> global_template = CreateGlobalTemplate(); 1296 Handle<ObjectTemplate> global_template = CreateGlobalTemplate(isolate);
1252 Persistent<Context> context = Context::New(NULL, global_template); 1297 Persistent<Context> context = Context::New(NULL, global_template);
1253 ASSERT(!context.IsEmpty()); 1298 ASSERT(!context.IsEmpty());
1254 Context::Scope scope(context); 1299 Context::Scope scope(context);
1255 1300
1256 #ifndef V8_SHARED 1301 #ifndef V8_SHARED
1257 i::JSArguments js_args = i::FLAG_js_arguments; 1302 i::JSArguments js_args = i::FLAG_js_arguments;
1258 i::Handle<i::FixedArray> arguments_array = 1303 i::Handle<i::FixedArray> arguments_array =
1259 FACTORY->NewFixedArray(js_args.argc()); 1304 FACTORY->NewFixedArray(js_args.argc());
1260 for (int j = 0; j < js_args.argc(); j++) { 1305 for (int j = 0; j < js_args.argc(); j++) {
1261 i::Handle<i::String> arg = 1306 i::Handle<i::String> arg =
(...skipping 25 matching lines...) Expand all
1287 }; 1332 };
1288 1333
1289 1334
1290 int CompareKeys(const void* a, const void* b) { 1335 int CompareKeys(const void* a, const void* b) {
1291 return strcmp(static_cast<const CounterAndKey*>(a)->key, 1336 return strcmp(static_cast<const CounterAndKey*>(a)->key,
1292 static_cast<const CounterAndKey*>(b)->key); 1337 static_cast<const CounterAndKey*>(b)->key);
1293 } 1338 }
1294 1339
1295 1340
1296 void Shell::OnExit() { 1341 void Shell::OnExit() {
1297 if (console != NULL) console->Close();
1298 if (i::FLAG_dump_counters) { 1342 if (i::FLAG_dump_counters) {
1299 int number_of_counters = 0; 1343 int number_of_counters = 0;
1300 for (CounterMap::Iterator i(counter_map_); i.More(); i.Next()) { 1344 for (CounterMap::Iterator i(counter_map_); i.More(); i.Next()) {
1301 number_of_counters++; 1345 number_of_counters++;
1302 } 1346 }
1303 CounterAndKey* counters = new CounterAndKey[number_of_counters]; 1347 CounterAndKey* counters = new CounterAndKey[number_of_counters];
1304 int j = 0; 1348 int j = 0;
1305 for (CounterMap::Iterator i(counter_map_); i.More(); i.Next(), j++) { 1349 for (CounterMap::Iterator i(counter_map_); i.More(); i.Next(), j++) {
1306 counters[j].counter = i.CurrentValue(); 1350 counters[j].counter = i.CurrentValue();
1307 counters[j].key = i.CurrentKey(); 1351 counters[j].key = i.CurrentKey();
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1347 struct stat file_stat; 1391 struct stat file_stat;
1348 if (fstat(fileno(file), &file_stat) != 0) return NULL; 1392 if (fstat(fileno(file), &file_stat) != 0) return NULL;
1349 bool is_regular_file = ((file_stat.st_mode & S_IFREG) != 0); 1393 bool is_regular_file = ((file_stat.st_mode & S_IFREG) != 0);
1350 if (is_regular_file) return file; 1394 if (is_regular_file) return file;
1351 fclose(file); 1395 fclose(file);
1352 return NULL; 1396 return NULL;
1353 #endif 1397 #endif
1354 } 1398 }
1355 1399
1356 1400
1357 static char* ReadChars(const char* name, int* size_out) { 1401 static char* ReadChars(Isolate* isolate, const char* name, int* size_out) {
1358 // Release the V8 lock while reading files. 1402 // Release the V8 lock while reading files.
1359 v8::Unlocker unlocker(Isolate::GetCurrent()); 1403 v8::Unlocker unlocker(isolate);
1360 FILE* file = FOpen(name, "rb"); 1404 FILE* file = FOpen(name, "rb");
1361 if (file == NULL) return NULL; 1405 if (file == NULL) return NULL;
1362 1406
1363 fseek(file, 0, SEEK_END); 1407 fseek(file, 0, SEEK_END);
1364 int size = ftell(file); 1408 int size = ftell(file);
1365 rewind(file); 1409 rewind(file);
1366 1410
1367 char* chars = new char[size + 1]; 1411 char* chars = new char[size + 1];
1368 chars[size] = '\0'; 1412 chars[size] = '\0';
1369 for (int i = 0; i < size;) { 1413 for (int i = 0; i < size;) {
1370 int read = static_cast<int>(fread(&chars[i], 1, size - i, file)); 1414 int read = static_cast<int>(fread(&chars[i], 1, size - i, file));
1371 i += read; 1415 i += read;
1372 } 1416 }
1373 fclose(file); 1417 fclose(file);
1374 *size_out = size; 1418 *size_out = size;
1375 return chars; 1419 return chars;
1376 } 1420 }
1377 1421
1378 1422
1379 Handle<Value> Shell::ReadBuffer(const Arguments& args) { 1423 Handle<Value> Shell::ReadBuffer(const Arguments& args) {
1380 ASSERT(sizeof(char) == sizeof(uint8_t)); // NOLINT 1424 ASSERT(sizeof(char) == sizeof(uint8_t)); // NOLINT
1381 String::Utf8Value filename(args[0]); 1425 String::Utf8Value filename(args[0]);
1382 int length; 1426 int length;
1383 if (*filename == NULL) { 1427 if (*filename == NULL) {
1384 return ThrowException(String::New("Error loading file")); 1428 return Throw("Error loading file");
1385 } 1429 }
1386 1430
1387 uint8_t* data = reinterpret_cast<uint8_t*>(ReadChars(*filename, &length)); 1431 uint8_t* data = reinterpret_cast<uint8_t*>(
1432 ReadChars(args.GetIsolate(), *filename, &length));
1388 if (data == NULL) { 1433 if (data == NULL) {
1389 return ThrowException(String::New("Error reading file")); 1434 return Throw("Error reading file");
1390 } 1435 }
1436 Isolate* isolate = args.GetIsolate();
1391 Handle<Object> buffer = Object::New(); 1437 Handle<Object> buffer = Object::New();
1392 buffer->SetHiddenValue(String::New(kArrayBufferMarkerPropName), True()); 1438 buffer->SetHiddenValue(Symbols::ArrayBufferMarkerPropName(isolate), True());
1393 Persistent<Object> persistent_buffer = Persistent<Object>::New(buffer); 1439 Persistent<Object> persistent_buffer = Persistent<Object>::New(buffer);
1394 persistent_buffer.MakeWeak(data, ExternalArrayWeakCallback); 1440 persistent_buffer.MakeWeak(data, ExternalArrayWeakCallback);
1395 persistent_buffer.MarkIndependent(); 1441 persistent_buffer.MarkIndependent();
1396 V8::AdjustAmountOfExternalAllocatedMemory(length); 1442 V8::AdjustAmountOfExternalAllocatedMemory(length);
1397 1443
1398 buffer->SetIndexedPropertiesToExternalArrayData( 1444 buffer->SetIndexedPropertiesToExternalArrayData(
1399 data, kExternalUnsignedByteArray, length); 1445 data, kExternalUnsignedByteArray, length);
1400 buffer->Set(String::New("byteLength"), 1446 buffer->Set(Symbols::byteLength(isolate),
1401 Int32::New(static_cast<int32_t>(length)), ReadOnly); 1447 Int32::New(static_cast<int32_t>(length)), ReadOnly);
1402 return buffer; 1448 return buffer;
1403 } 1449 }
1404 1450
1405 1451
1406 #ifndef V8_SHARED 1452 #ifndef V8_SHARED
1407 static char* ReadToken(char* data, char token) { 1453 static char* ReadToken(char* data, char token) {
1408 char* next = i::OS::StrChr(data, token); 1454 char* next = i::OS::StrChr(data, token);
1409 if (next != NULL) { 1455 if (next != NULL) {
1410 *next = '\0'; 1456 *next = '\0';
1411 return (next + 1); 1457 return (next + 1);
1412 } 1458 }
1413 1459
1414 return NULL; 1460 return NULL;
1415 } 1461 }
1416 1462
1417 1463
1418 static char* ReadLine(char* data) { 1464 static char* ReadLine(char* data) {
1419 return ReadToken(data, '\n'); 1465 return ReadToken(data, '\n');
1420 } 1466 }
1421 1467
1422 1468
1423 static char* ReadWord(char* data) { 1469 static char* ReadWord(char* data) {
1424 return ReadToken(data, ' '); 1470 return ReadToken(data, ' ');
1425 } 1471 }
1426 #endif // V8_SHARED 1472 #endif // V8_SHARED
1427 1473
1428 1474
1429 // Reads a file into a v8 string. 1475 // Reads a file into a v8 string.
1430 Handle<String> Shell::ReadFile(const char* name) { 1476 Handle<String> Shell::ReadFile(Isolate* isolate, const char* name) {
1431 int size = 0; 1477 int size = 0;
1432 char* chars = ReadChars(name, &size); 1478 char* chars = ReadChars(isolate, name, &size);
1433 if (chars == NULL) return Handle<String>(); 1479 if (chars == NULL) return Handle<String>();
1434 Handle<String> result = String::New(chars); 1480 Handle<String> result = String::New(chars);
1435 delete[] chars; 1481 delete[] chars;
1436 return result; 1482 return result;
1437 } 1483 }
1438 1484
1439 1485
1440 void Shell::RunShell() { 1486 void Shell::RunShell(Isolate* isolate) {
1441 Locker locker; 1487 Locker locker;
1442 Context::Scope context_scope(evaluation_context_); 1488 Context::Scope context_scope(evaluation_context_);
1443 HandleScope outer_scope; 1489 HandleScope outer_scope;
1444 Handle<String> name = String::New("(d8)"); 1490 Handle<String> name = String::New("(d8)");
1445 console = LineEditor::Get(); 1491 DumbLineEditor dumb_line_editor(isolate);
1492 LineEditor* console = LineEditor::Get();
1446 printf("V8 version %s [console: %s]\n", V8::GetVersion(), console->name()); 1493 printf("V8 version %s [console: %s]\n", V8::GetVersion(), console->name());
1447 console->Open(); 1494 console->Open();
1448 while (true) { 1495 while (true) {
1449 HandleScope inner_scope; 1496 HandleScope inner_scope;
1450 Handle<String> input = console->Prompt(Shell::kPrompt); 1497 Handle<String> input = console->Prompt(Shell::kPrompt);
1451 if (input.IsEmpty()) break; 1498 if (input.IsEmpty()) break;
1452 ExecuteString(input, name, true, true); 1499 ExecuteString(input, name, true, true);
1453 } 1500 }
1454 printf("\n"); 1501 printf("\n");
1502 console->Close();
1455 } 1503 }
1456 1504
1457 1505
1458 #ifndef V8_SHARED 1506 #ifndef V8_SHARED
1459 class ShellThread : public i::Thread { 1507 class ShellThread : public i::Thread {
1460 public: 1508 public:
1461 // Takes ownership of the underlying char array of |files|. 1509 // Takes ownership of the underlying char array of |files|.
1462 ShellThread(int no, char* files) 1510 ShellThread(Isolate* isolate, int no, char* files)
1463 : Thread("d8:ShellThread"), 1511 : Thread("d8:ShellThread"),
1464 no_(no), files_(files) { } 1512 isolate_(isolate), no_(no), files_(files) { }
1465 1513
1466 ~ShellThread() { 1514 ~ShellThread() {
1467 delete[] files_; 1515 delete[] files_;
1468 } 1516 }
1469 1517
1470 virtual void Run(); 1518 virtual void Run();
1471 private: 1519 private:
1520 Isolate* isolate_;
1472 int no_; 1521 int no_;
1473 char* files_; 1522 char* files_;
1474 }; 1523 };
1475 1524
1476 1525
1477 void ShellThread::Run() { 1526 void ShellThread::Run() {
1478 char* ptr = files_; 1527 char* ptr = files_;
1479 while ((ptr != NULL) && (*ptr != '\0')) { 1528 while ((ptr != NULL) && (*ptr != '\0')) {
1480 // For each newline-separated line. 1529 // For each newline-separated line.
1481 char* next_line = ReadLine(ptr); 1530 char* next_line = ReadLine(ptr);
1482 1531
1483 if (*ptr == '#') { 1532 if (*ptr == '#') {
1484 // Skip comment lines. 1533 // Skip comment lines.
1485 ptr = next_line; 1534 ptr = next_line;
1486 continue; 1535 continue;
1487 } 1536 }
1488 1537
1489 // Prepare the context for this thread. 1538 // Prepare the context for this thread.
1490 Locker locker; 1539 Locker locker;
1491 HandleScope outer_scope; 1540 HandleScope outer_scope;
1492 Persistent<Context> thread_context = Shell::CreateEvaluationContext(); 1541 Persistent<Context> thread_context =
1542 Shell::CreateEvaluationContext(isolate_);
1493 Context::Scope context_scope(thread_context); 1543 Context::Scope context_scope(thread_context);
1494 1544
1495 while ((ptr != NULL) && (*ptr != '\0')) { 1545 while ((ptr != NULL) && (*ptr != '\0')) {
1496 HandleScope inner_scope; 1546 HandleScope inner_scope;
1497 char* filename = ptr; 1547 char* filename = ptr;
1498 ptr = ReadWord(ptr); 1548 ptr = ReadWord(ptr);
1499 1549
1500 // Skip empty strings. 1550 // Skip empty strings.
1501 if (strlen(filename) == 0) { 1551 if (strlen(filename) == 0) {
1502 continue; 1552 continue;
1503 } 1553 }
1504 1554
1505 Handle<String> str = Shell::ReadFile(filename); 1555 Handle<String> str = Shell::ReadFile(isolate_, filename);
1506 if (str.IsEmpty()) { 1556 if (str.IsEmpty()) {
1507 printf("File '%s' not found\n", filename); 1557 printf("File '%s' not found\n", filename);
1508 Shell::Exit(1); 1558 Shell::Exit(1);
1509 } 1559 }
1510 1560
1511 Shell::ExecuteString(str, String::New(filename), false, false); 1561 Shell::ExecuteString(str, String::New(filename), false, false);
1512 } 1562 }
1513 1563
1514 thread_context.Dispose(); 1564 thread_context.Dispose();
1515 ptr = next_line; 1565 ptr = next_line;
1516 } 1566 }
1517 } 1567 }
1518 #endif // V8_SHARED 1568 #endif // V8_SHARED
1519 1569
1520 1570
1521 SourceGroup::~SourceGroup() { 1571 SourceGroup::~SourceGroup() {
1522 #ifndef V8_SHARED 1572 #ifndef V8_SHARED
1523 delete next_semaphore_; 1573 delete next_semaphore_;
1524 next_semaphore_ = NULL; 1574 next_semaphore_ = NULL;
1525 delete done_semaphore_; 1575 delete done_semaphore_;
1526 done_semaphore_ = NULL; 1576 done_semaphore_ = NULL;
1527 delete thread_; 1577 delete thread_;
1528 thread_ = NULL; 1578 thread_ = NULL;
1529 #endif // V8_SHARED 1579 #endif // V8_SHARED
1530 } 1580 }
1531 1581
1532 1582
1533 void SourceGroup::Execute() { 1583 void SourceGroup::Execute(Isolate* isolate) {
1534 for (int i = begin_offset_; i < end_offset_; ++i) { 1584 for (int i = begin_offset_; i < end_offset_; ++i) {
1535 const char* arg = argv_[i]; 1585 const char* arg = argv_[i];
1536 if (strcmp(arg, "-e") == 0 && i + 1 < end_offset_) { 1586 if (strcmp(arg, "-e") == 0 && i + 1 < end_offset_) {
1537 // Execute argument given to -e option directly. 1587 // Execute argument given to -e option directly.
1538 HandleScope handle_scope; 1588 HandleScope handle_scope;
1539 Handle<String> file_name = String::New("unnamed"); 1589 Handle<String> file_name = String::New("unnamed");
1540 Handle<String> source = String::New(argv_[i + 1]); 1590 Handle<String> source = String::New(argv_[i + 1]);
1541 if (!Shell::ExecuteString(source, file_name, false, true)) { 1591 if (!Shell::ExecuteString(source, file_name, false, true)) {
1542 Shell::Exit(1); 1592 Shell::Exit(1);
1543 } 1593 }
1544 ++i; 1594 ++i;
1545 } else if (arg[0] == '-') { 1595 } else if (arg[0] == '-') {
1546 // Ignore other options. They have been parsed already. 1596 // Ignore other options. They have been parsed already.
1547 } else { 1597 } else {
1548 // Use all other arguments as names of files to load and run. 1598 // Use all other arguments as names of files to load and run.
1549 HandleScope handle_scope; 1599 HandleScope handle_scope;
1550 Handle<String> file_name = String::New(arg); 1600 Handle<String> file_name = String::New(arg);
1551 Handle<String> source = ReadFile(arg); 1601 Handle<String> source = ReadFile(isolate, arg);
1552 if (source.IsEmpty()) { 1602 if (source.IsEmpty()) {
1553 printf("Error reading '%s'\n", arg); 1603 printf("Error reading '%s'\n", arg);
1554 Shell::Exit(1); 1604 Shell::Exit(1);
1555 } 1605 }
1556 if (!Shell::ExecuteString(source, file_name, false, true)) { 1606 if (!Shell::ExecuteString(source, file_name, false, true)) {
1557 Shell::Exit(1); 1607 Shell::Exit(1);
1558 } 1608 }
1559 } 1609 }
1560 } 1610 }
1561 } 1611 }
1562 1612
1563 1613
1564 Handle<String> SourceGroup::ReadFile(const char* name) { 1614 Handle<String> SourceGroup::ReadFile(Isolate* isolate, const char* name) {
1565 int size; 1615 int size;
1566 char* chars = ReadChars(name, &size); 1616 char* chars = ReadChars(isolate, name, &size);
1567 if (chars == NULL) return Handle<String>(); 1617 if (chars == NULL) return Handle<String>();
1568 Handle<String> result = String::New(chars, size); 1618 Handle<String> result = String::New(chars, size);
1569 delete[] chars; 1619 delete[] chars;
1570 return result; 1620 return result;
1571 } 1621 }
1572 1622
1573 1623
1574 #ifndef V8_SHARED 1624 #ifndef V8_SHARED
1575 i::Thread::Options SourceGroup::GetThreadOptions() { 1625 i::Thread::Options SourceGroup::GetThreadOptions() {
1576 // On some systems (OSX 10.6) the stack size default is 0.5Mb or less 1626 // On some systems (OSX 10.6) the stack size default is 0.5Mb or less
1577 // which is not enough to parse the big literal expressions used in tests. 1627 // which is not enough to parse the big literal expressions used in tests.
1578 // The stack size should be at least StackGuard::kLimitSize + some 1628 // The stack size should be at least StackGuard::kLimitSize + some
1579 // OS-specific padding for thread startup code. 2Mbytes seems to be enough. 1629 // OS-specific padding for thread startup code. 2Mbytes seems to be enough.
1580 return i::Thread::Options("IsolateThread", 2 * MB); 1630 return i::Thread::Options("IsolateThread", 2 * MB);
1581 } 1631 }
1582 1632
1583 1633
1584 void SourceGroup::ExecuteInThread() { 1634 void SourceGroup::ExecuteInThread() {
1585 Isolate* isolate = Isolate::New(); 1635 Isolate* isolate = Isolate::New();
1586 do { 1636 do {
1587 if (next_semaphore_ != NULL) next_semaphore_->Wait(); 1637 if (next_semaphore_ != NULL) next_semaphore_->Wait();
1588 { 1638 {
1589 Isolate::Scope iscope(isolate); 1639 Isolate::Scope iscope(isolate);
1590 Locker lock(isolate); 1640 Locker lock(isolate);
1591 HandleScope scope; 1641 HandleScope scope;
1592 Persistent<Context> context = Shell::CreateEvaluationContext(); 1642 Symbols symbols(isolate);
1643 Persistent<Context> context = Shell::CreateEvaluationContext(isolate);
1593 { 1644 {
1594 Context::Scope cscope(context); 1645 Context::Scope cscope(context);
1595 Execute(); 1646 Execute(isolate);
1596 } 1647 }
1597 context.Dispose(); 1648 context.Dispose();
1598 if (Shell::options.send_idle_notification) { 1649 if (Shell::options.send_idle_notification) {
1599 const int kLongIdlePauseInMs = 1000; 1650 const int kLongIdlePauseInMs = 1000;
1600 V8::ContextDisposedNotification(); 1651 V8::ContextDisposedNotification();
1601 V8::IdleNotification(kLongIdlePauseInMs); 1652 V8::IdleNotification(kLongIdlePauseInMs);
1602 } 1653 }
1603 } 1654 }
1604 if (done_semaphore_ != NULL) done_semaphore_->Signal(); 1655 if (done_semaphore_ != NULL) done_semaphore_->Signal();
1605 } while (!Shell::options.last_run); 1656 } while (!Shell::options.last_run);
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
1753 } else if (strncmp(argv[i], "--", 2) == 0) { 1804 } else if (strncmp(argv[i], "--", 2) == 0) {
1754 printf("Warning: unknown flag %s.\nTry --help for options\n", argv[i]); 1805 printf("Warning: unknown flag %s.\nTry --help for options\n", argv[i]);
1755 } 1806 }
1756 } 1807 }
1757 current->End(argc); 1808 current->End(argc);
1758 1809
1759 return true; 1810 return true;
1760 } 1811 }
1761 1812
1762 1813
1763 int Shell::RunMain(int argc, char* argv[]) { 1814 int Shell::RunMain(Isolate* isolate, int argc, char* argv[]) {
1764 #ifndef V8_SHARED 1815 #ifndef V8_SHARED
1765 i::List<i::Thread*> threads(1); 1816 i::List<i::Thread*> threads(1);
1766 if (options.parallel_files != NULL) { 1817 if (options.parallel_files != NULL) {
1767 for (int i = 0; i < options.num_parallel_files; i++) { 1818 for (int i = 0; i < options.num_parallel_files; i++) {
1768 char* files = NULL; 1819 char* files = NULL;
1769 { Locker lock(Isolate::GetCurrent()); 1820 { Locker lock(isolate);
1770 int size = 0; 1821 int size = 0;
1771 files = ReadChars(options.parallel_files[i], &size); 1822 files = ReadChars(isolate, options.parallel_files[i], &size);
1772 } 1823 }
1773 if (files == NULL) { 1824 if (files == NULL) {
1774 printf("File list '%s' not found\n", options.parallel_files[i]); 1825 printf("File list '%s' not found\n", options.parallel_files[i]);
1775 Exit(1); 1826 Exit(1);
1776 } 1827 }
1777 ShellThread* thread = new ShellThread(threads.length(), files); 1828 ShellThread* thread = new ShellThread(isolate, threads.length(), files);
1778 thread->Start(); 1829 thread->Start();
1779 threads.Add(thread); 1830 threads.Add(thread);
1780 } 1831 }
1781 } 1832 }
1782 for (int i = 1; i < options.num_isolates; ++i) { 1833 for (int i = 1; i < options.num_isolates; ++i) {
1783 options.isolate_sources[i].StartExecuteInThread(); 1834 options.isolate_sources[i].StartExecuteInThread();
1784 } 1835 }
1785 #endif // V8_SHARED 1836 #endif // V8_SHARED
1786 { // NOLINT 1837 { // NOLINT
1787 Locker lock; 1838 Locker lock;
1788 HandleScope scope; 1839 HandleScope scope;
1789 Persistent<Context> context = CreateEvaluationContext(); 1840 Persistent<Context> context = CreateEvaluationContext(isolate);
1790 if (options.last_run) { 1841 if (options.last_run) {
1791 // Keep using the same context in the interactive shell. 1842 // Keep using the same context in the interactive shell.
1792 evaluation_context_ = context; 1843 evaluation_context_ = context;
1793 #if !defined(V8_SHARED) && defined(ENABLE_DEBUGGER_SUPPORT) 1844 #if !defined(V8_SHARED) && defined(ENABLE_DEBUGGER_SUPPORT)
1794 // If the interactive debugger is enabled make sure to activate 1845 // If the interactive debugger is enabled make sure to activate
1795 // it before running the files passed on the command line. 1846 // it before running the files passed on the command line.
1796 if (i::FLAG_debugger) { 1847 if (i::FLAG_debugger) {
1797 InstallUtilityScript(); 1848 InstallUtilityScript();
1798 } 1849 }
1799 #endif // !V8_SHARED && ENABLE_DEBUGGER_SUPPORT 1850 #endif // !V8_SHARED && ENABLE_DEBUGGER_SUPPORT
1800 } 1851 }
1801 { 1852 {
1802 Context::Scope cscope(context); 1853 Context::Scope cscope(context);
1803 options.isolate_sources[0].Execute(); 1854 options.isolate_sources[0].Execute(isolate);
1804 } 1855 }
1805 if (!options.last_run) { 1856 if (!options.last_run) {
1806 context.Dispose(); 1857 context.Dispose();
1807 if (options.send_idle_notification) { 1858 if (options.send_idle_notification) {
1808 const int kLongIdlePauseInMs = 1000; 1859 const int kLongIdlePauseInMs = 1000;
1809 V8::ContextDisposedNotification(); 1860 V8::ContextDisposedNotification();
1810 V8::IdleNotification(kLongIdlePauseInMs); 1861 V8::IdleNotification(kLongIdlePauseInMs);
1811 } 1862 }
1812 } 1863 }
1813 1864
(...skipping 21 matching lines...) Expand all
1835 Locker lock; 1886 Locker lock;
1836 Locker::StopPreemption(); 1887 Locker::StopPreemption();
1837 } 1888 }
1838 #endif // V8_SHARED 1889 #endif // V8_SHARED
1839 return 0; 1890 return 0;
1840 } 1891 }
1841 1892
1842 1893
1843 int Shell::Main(int argc, char* argv[]) { 1894 int Shell::Main(int argc, char* argv[]) {
1844 if (!SetOptions(argc, argv)) return 1; 1895 if (!SetOptions(argc, argv)) return 1;
1845 Initialize(); 1896 int result = 0;
1897 Isolate* isolate = Isolate::GetCurrent();
1898 {
1899 Symbols symbols(isolate);
1900 Initialize(isolate);
1846 1901
1847 int result = 0; 1902 if (options.stress_opt || options.stress_deopt) {
1848 if (options.stress_opt || options.stress_deopt) { 1903 Testing::SetStressRunType(options.stress_opt
1849 Testing::SetStressRunType( 1904 ? Testing::kStressTypeOpt
1850 options.stress_opt ? Testing::kStressTypeOpt 1905 : Testing::kStressTypeDeopt);
1851 : Testing::kStressTypeDeopt); 1906 int stress_runs = Testing::GetStressRuns();
1852 int stress_runs = Testing::GetStressRuns(); 1907 for (int i = 0; i < stress_runs && result == 0; i++) {
1853 for (int i = 0; i < stress_runs && result == 0; i++) { 1908 printf("============ Stress %d/%d ============\n", i + 1, stress_runs);
1854 printf("============ Stress %d/%d ============\n", i + 1, stress_runs); 1909 Testing::PrepareStressRun(i);
1855 Testing::PrepareStressRun(i); 1910 options.last_run = (i == stress_runs - 1);
1856 options.last_run = (i == stress_runs - 1); 1911 result = RunMain(isolate, argc, argv);
1857 result = RunMain(argc, argv); 1912 }
1913 printf("======== Full Deoptimization =======\n");
1914 Testing::DeoptimizeAll();
1915 #if !defined(V8_SHARED)
1916 } else if (i::FLAG_stress_runs > 0) {
1917 int stress_runs = i::FLAG_stress_runs;
1918 for (int i = 0; i < stress_runs && result == 0; i++) {
1919 printf("============ Run %d/%d ============\n", i + 1, stress_runs);
1920 options.last_run = (i == stress_runs - 1);
1921 result = RunMain(isolate, argc, argv);
1922 }
1923 #endif
1924 } else {
1925 result = RunMain(isolate, argc, argv);
1858 } 1926 }
1859 printf("======== Full Deoptimization =======\n");
1860 Testing::DeoptimizeAll();
1861 #if !defined(V8_SHARED)
1862 } else if (i::FLAG_stress_runs > 0) {
1863 int stress_runs = i::FLAG_stress_runs;
1864 for (int i = 0; i < stress_runs && result == 0; i++) {
1865 printf("============ Run %d/%d ============\n", i + 1, stress_runs);
1866 options.last_run = (i == stress_runs - 1);
1867 result = RunMain(argc, argv);
1868 }
1869 #endif
1870 } else {
1871 result = RunMain(argc, argv);
1872 }
1873 1927
1874 1928
1875 #if !defined(V8_SHARED) && defined(ENABLE_DEBUGGER_SUPPORT) 1929 #if !defined(V8_SHARED) && defined(ENABLE_DEBUGGER_SUPPORT)
1876 // Run remote debugger if requested, but never on --test 1930 // Run remote debugger if requested, but never on --test
1877 if (i::FLAG_remote_debugger && !options.test_shell) { 1931 if (i::FLAG_remote_debugger && !options.test_shell) {
1878 InstallUtilityScript(); 1932 InstallUtilityScript();
1879 RunRemoteDebugger(i::FLAG_debugger_port); 1933 RunRemoteDebugger(i::FLAG_debugger_port);
1880 return 0; 1934 return 0;
1881 } 1935 }
1882 #endif // !V8_SHARED && ENABLE_DEBUGGER_SUPPORT 1936 #endif // !V8_SHARED && ENABLE_DEBUGGER_SUPPORT
1883 1937
1884 // Run interactive shell if explicitly requested or if no script has been 1938 // Run interactive shell if explicitly requested or if no script has been
1885 // executed, but never on --test 1939 // executed, but never on --test
1886 1940
1887 if (( options.interactive_shell 1941 if (( options.interactive_shell || !options.script_executed )
1888 || !options.script_executed ) 1942 && !options.test_shell ) {
1889 && !options.test_shell ) {
1890 #if !defined(V8_SHARED) && defined(ENABLE_DEBUGGER_SUPPORT) 1943 #if !defined(V8_SHARED) && defined(ENABLE_DEBUGGER_SUPPORT)
1891 if (!i::FLAG_debugger) { 1944 if (!i::FLAG_debugger) {
1892 InstallUtilityScript(); 1945 InstallUtilityScript();
1946 }
1947 #endif // !V8_SHARED && ENABLE_DEBUGGER_SUPPORT
1948 RunShell(isolate);
1893 } 1949 }
1894 #endif // !V8_SHARED && ENABLE_DEBUGGER_SUPPORT
1895 RunShell();
1896 } 1950 }
1897
1898 V8::Dispose(); 1951 V8::Dispose();
1899 1952
1900 #ifndef V8_SHARED 1953 #ifndef V8_SHARED
1901 OnExit(); 1954 OnExit();
1902 #endif // V8_SHARED 1955 #endif // V8_SHARED
1903 1956
1904 return result; 1957 return result;
1905 } 1958 }
1906 1959
1907 } // namespace v8 1960 } // namespace v8
1908 1961
1909 1962
1910 #ifndef GOOGLE3 1963 #ifndef GOOGLE3
1911 int main(int argc, char* argv[]) { 1964 int main(int argc, char* argv[]) {
1912 return v8::Shell::Main(argc, argv); 1965 return v8::Shell::Main(argc, argv);
1913 } 1966 }
1914 #endif 1967 #endif
OLDNEW
« no previous file with comments | « src/d8.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698