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