Chromium Code Reviews| 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 | |
|
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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |