| 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 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 76 return ThrowException(String::New(message)); | 76 return ThrowException(String::New(message)); |
| 77 } | 77 } |
| 78 | 78 |
| 79 | 79 |
| 80 // TODO(rossberg): should replace these by proper uses of HasInstance, | 80 // TODO(rossberg): should replace these by proper uses of HasInstance, |
| 81 // once we figure out a good way to make the templates global. | 81 // once we figure out a good way to make the templates global. |
| 82 const char kArrayBufferMarkerPropName[] = "d8::_is_array_buffer_"; | 82 const char kArrayBufferMarkerPropName[] = "d8::_is_array_buffer_"; |
| 83 const char kArrayMarkerPropName[] = "d8::_is_typed_array_"; | 83 const char kArrayMarkerPropName[] = "d8::_is_typed_array_"; |
| 84 | 84 |
| 85 | 85 |
| 86 #define FOR_EACH_SYMBOL(V) \ | 86 #define FOR_EACH_STRING(V) \ |
| 87 V(ArrayBuffer, "ArrayBuffer") \ | 87 V(ArrayBuffer, "ArrayBuffer") \ |
| 88 V(ArrayBufferMarkerPropName, kArrayBufferMarkerPropName) \ | 88 V(ArrayBufferMarkerPropName, kArrayBufferMarkerPropName) \ |
| 89 V(ArrayMarkerPropName, kArrayMarkerPropName) \ | 89 V(ArrayMarkerPropName, kArrayMarkerPropName) \ |
| 90 V(buffer, "buffer") \ | 90 V(buffer, "buffer") \ |
| 91 V(byteLength, "byteLength") \ | 91 V(byteLength, "byteLength") \ |
| 92 V(byteOffset, "byteOffset") \ | 92 V(byteOffset, "byteOffset") \ |
| 93 V(BYTES_PER_ELEMENT, "BYTES_PER_ELEMENT") \ | 93 V(BYTES_PER_ELEMENT, "BYTES_PER_ELEMENT") \ |
| 94 V(length, "length") | 94 V(length, "length") |
| 95 | 95 |
| 96 | 96 |
| 97 class Symbols { | 97 class PerIsolateData { |
| 98 public: | 98 public: |
| 99 explicit Symbols(Isolate* isolate) : isolate_(isolate) { | 99 explicit PerIsolateData(Isolate* isolate) : isolate_(isolate), realms_(NULL) { |
| 100 HandleScope scope(isolate); | 100 HandleScope scope(isolate); |
| 101 #define INIT_SYMBOL(name, value) \ | 101 #define INIT_STRING(name, value) \ |
| 102 name##_ = Persistent<String>::New(isolate, String::NewSymbol(value)); | 102 name##_string_ = Persistent<String>::New(isolate, String::NewSymbol(value)); |
| 103 FOR_EACH_SYMBOL(INIT_SYMBOL) | 103 FOR_EACH_STRING(INIT_STRING) |
| 104 #undef INIT_SYMBOL | 104 #undef INIT_STRING |
| 105 isolate->SetData(this); | 105 isolate->SetData(this); |
| 106 } | 106 } |
| 107 | 107 |
| 108 ~Symbols() { | 108 ~PerIsolateData() { |
| 109 #define DISPOSE_SYMBOL(name, value) name##_.Dispose(isolate_); | 109 #define DISPOSE_STRING(name, value) name##_string_.Dispose(isolate_); |
| 110 FOR_EACH_SYMBOL(DISPOSE_SYMBOL) | 110 FOR_EACH_STRING(DISPOSE_STRING) |
| 111 #undef DISPOSE_SYMBOL | 111 #undef DISPOSE_STRING |
| 112 isolate_->SetData(NULL); // Not really needed, just to be sure... | 112 isolate_->SetData(NULL); // Not really needed, just to be sure... |
| 113 } | 113 } |
| 114 | 114 |
| 115 #define DEFINE_SYMBOL_GETTER(name, value) \ | 115 inline static PerIsolateData* Get(Isolate* isolate) { |
| 116 static Persistent<String> name(Isolate* isolate) { \ | 116 return reinterpret_cast<PerIsolateData*>(isolate->GetData()); |
| 117 return reinterpret_cast<Symbols*>(isolate->GetData())->name##_; \ | |
| 118 } | 117 } |
| 119 FOR_EACH_SYMBOL(DEFINE_SYMBOL_GETTER) | 118 |
| 120 #undef DEFINE_SYMBOL_GETTER | 119 #define DEFINE_STRING_GETTER(name, value) \ |
| 120 static Persistent<String> name##_string(Isolate* isolate) { \ |
| 121 return Get(isolate)->name##_string_; \ |
| 122 } |
| 123 FOR_EACH_STRING(DEFINE_STRING_GETTER) |
| 124 #undef DEFINE_STRING_GETTER |
| 125 |
| 126 class RealmScope { |
| 127 public: |
| 128 explicit RealmScope(PerIsolateData* data); |
| 129 ~RealmScope(); |
| 130 private: |
| 131 PerIsolateData* data_; |
| 132 }; |
| 121 | 133 |
| 122 private: | 134 private: |
| 135 friend class Shell; |
| 136 friend class RealmScope; |
| 123 Isolate* isolate_; | 137 Isolate* isolate_; |
| 124 #define DEFINE_MEMBER(name, value) Persistent<String> name##_; | 138 int realm_count_; |
| 125 FOR_EACH_SYMBOL(DEFINE_MEMBER) | 139 int realm_current_; |
| 140 int realm_switch_; |
| 141 Persistent<Context>* realms_; |
| 142 Persistent<Value> realm_shared_; |
| 143 |
| 144 #define DEFINE_MEMBER(name, value) Persistent<String> name##_string_; |
| 145 FOR_EACH_STRING(DEFINE_MEMBER) |
| 126 #undef DEFINE_MEMBER | 146 #undef DEFINE_MEMBER |
| 147 |
| 148 int RealmFind(Handle<Context> context); |
| 127 }; | 149 }; |
| 128 | 150 |
| 129 | 151 |
| 130 LineEditor *LineEditor::current_ = NULL; | 152 LineEditor *LineEditor::current_ = NULL; |
| 131 | 153 |
| 132 | 154 |
| 133 LineEditor::LineEditor(Type type, const char* name) | 155 LineEditor::LineEditor(Type type, const char* name) |
| 134 : type_(type), name_(name) { | 156 : type_(type), name_(name) { |
| 135 if (current_ == NULL || current_->type_ < type) current_ = this; | 157 if (current_ == NULL || current_->type_ < type) current_ = this; |
| 136 } | 158 } |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 200 #else | 222 #else |
| 201 bool FLAG_debugger = false; | 223 bool FLAG_debugger = false; |
| 202 #endif // !V8_SHARED && ENABLE_DEBUGGER_SUPPORT | 224 #endif // !V8_SHARED && ENABLE_DEBUGGER_SUPPORT |
| 203 HandleScope handle_scope(isolate); | 225 HandleScope handle_scope(isolate); |
| 204 TryCatch try_catch; | 226 TryCatch try_catch; |
| 205 options.script_executed = true; | 227 options.script_executed = true; |
| 206 if (FLAG_debugger) { | 228 if (FLAG_debugger) { |
| 207 // When debugging make exceptions appear to be uncaught. | 229 // When debugging make exceptions appear to be uncaught. |
| 208 try_catch.SetVerbose(true); | 230 try_catch.SetVerbose(true); |
| 209 } | 231 } |
| 210 Handle<Script> script = Script::Compile(source, name); | 232 Handle<Script> script = Script::New(source, name); |
| 211 if (script.IsEmpty()) { | 233 if (script.IsEmpty()) { |
| 212 // Print errors that happened during compilation. | 234 // Print errors that happened during compilation. |
| 213 if (report_exceptions && !FLAG_debugger) | 235 if (report_exceptions && !FLAG_debugger) |
| 214 ReportException(isolate, &try_catch); | 236 ReportException(isolate, &try_catch); |
| 215 return false; | 237 return false; |
| 216 } else { | 238 } else { |
| 239 PerIsolateData* data = PerIsolateData::Get(isolate); |
| 240 Local<Context> realm = |
| 241 Local<Context>::New(data->realms_[data->realm_current_]); |
| 242 realm->Enter(); |
| 217 Handle<Value> result = script->Run(); | 243 Handle<Value> result = script->Run(); |
| 244 realm->Exit(); |
| 245 data->realm_current_ = data->realm_switch_; |
| 218 if (result.IsEmpty()) { | 246 if (result.IsEmpty()) { |
| 219 ASSERT(try_catch.HasCaught()); | 247 ASSERT(try_catch.HasCaught()); |
| 220 // Print errors that happened during execution. | 248 // Print errors that happened during execution. |
| 221 if (report_exceptions && !FLAG_debugger) | 249 if (report_exceptions && !FLAG_debugger) |
| 222 ReportException(isolate, &try_catch); | 250 ReportException(isolate, &try_catch); |
| 223 return false; | 251 return false; |
| 224 } else { | 252 } else { |
| 225 ASSERT(!try_catch.HasCaught()); | 253 ASSERT(!try_catch.HasCaught()); |
| 226 if (print_result) { | 254 if (print_result) { |
| 227 #if !defined(V8_SHARED) | 255 #if !defined(V8_SHARED) |
| (...skipping 20 matching lines...) Expand all Loading... |
| 248 printf("\n"); | 276 printf("\n"); |
| 249 } | 277 } |
| 250 #endif | 278 #endif |
| 251 } | 279 } |
| 252 return true; | 280 return true; |
| 253 } | 281 } |
| 254 } | 282 } |
| 255 } | 283 } |
| 256 | 284 |
| 257 | 285 |
| 286 PerIsolateData::RealmScope::RealmScope(PerIsolateData* data) : data_(data) { |
| 287 data_->realm_count_ = 1; |
| 288 data_->realm_current_ = 0; |
| 289 data_->realm_switch_ = 0; |
| 290 data_->realms_ = new Persistent<Context>[1]; |
| 291 data_->realms_[0] = |
| 292 Persistent<Context>::New(data_->isolate_, Context::GetEntered()); |
| 293 data_->realm_shared_.Clear(); |
| 294 } |
| 295 |
| 296 |
| 297 PerIsolateData::RealmScope::~RealmScope() { |
| 298 // Drop realms to avoid keeping them alive. |
| 299 for (int i = 0; i < data_->realm_count_; ++i) |
| 300 data_->realms_[i].Dispose(data_->isolate_); |
| 301 delete[] data_->realms_; |
| 302 if (!data_->realm_shared_.IsEmpty()) |
| 303 data_->realm_shared_.Dispose(data_->isolate_); |
| 304 } |
| 305 |
| 306 |
| 307 int PerIsolateData::RealmFind(Handle<Context> context) { |
| 308 for (int i = 0; i < realm_count_; ++i) { |
| 309 if (realms_[i] == context) return i; |
| 310 } |
| 311 return -1; |
| 312 } |
| 313 |
| 314 |
| 315 // Realm.current() returns the index of the currently active realm. |
| 316 Handle<Value> Shell::RealmCurrent(const Arguments& args) { |
| 317 Isolate* isolate = args.GetIsolate(); |
| 318 PerIsolateData* data = PerIsolateData::Get(isolate); |
| 319 int index = data->RealmFind(Context::GetEntered()); |
| 320 if (index == -1) return Undefined(isolate); |
| 321 return Number::New(index); |
| 322 } |
| 323 |
| 324 |
| 325 // Realm.owner(o) returns the index of the realm that created o. |
| 326 Handle<Value> Shell::RealmOwner(const Arguments& args) { |
| 327 Isolate* isolate = args.GetIsolate(); |
| 328 PerIsolateData* data = PerIsolateData::Get(isolate); |
| 329 if (args.Length() < 1 || !args[0]->IsObject()) { |
| 330 return Throw("Invalid argument"); |
| 331 } |
| 332 int index = data->RealmFind(args[0]->ToObject()->CreationContext()); |
| 333 if (index == -1) return Undefined(isolate); |
| 334 return Number::New(index); |
| 335 } |
| 336 |
| 337 |
| 338 // Realm.global(i) returns the global object of realm i. |
| 339 // (Note that properties of global objects cannot be read/written cross-realm.) |
| 340 Handle<Value> Shell::RealmGlobal(const Arguments& args) { |
| 341 PerIsolateData* data = PerIsolateData::Get(args.GetIsolate()); |
| 342 if (args.Length() < 1 || !args[0]->IsNumber()) { |
| 343 return Throw("Invalid argument"); |
| 344 } |
| 345 int index = args[0]->Uint32Value(); |
| 346 if (index >= data->realm_count_ || data->realms_[index].IsEmpty()) { |
| 347 return Throw("Invalid realm index"); |
| 348 } |
| 349 return data->realms_[index]->Global(); |
| 350 } |
| 351 |
| 352 |
| 353 // Realm.create() creates a new realm and returns its index. |
| 354 Handle<Value> Shell::RealmCreate(const Arguments& args) { |
| 355 Isolate* isolate = args.GetIsolate(); |
| 356 PerIsolateData* data = PerIsolateData::Get(isolate); |
| 357 Persistent<Context>* old_realms = data->realms_; |
| 358 int index = data->realm_count_; |
| 359 data->realms_ = new Persistent<Context>[++data->realm_count_]; |
| 360 for (int i = 0; i < index; ++i) data->realms_[i] = old_realms[i]; |
| 361 delete[] old_realms; |
| 362 Handle<ObjectTemplate> global_template = CreateGlobalTemplate(isolate); |
| 363 data->realms_[index] = Persistent<Context>::New( |
| 364 isolate, Context::New(isolate, NULL, global_template)); |
| 365 return Number::New(index); |
| 366 } |
| 367 |
| 368 |
| 369 // Realm.dispose(i) disposes the reference to the realm i. |
| 370 Handle<Value> Shell::RealmDispose(const Arguments& args) { |
| 371 Isolate* isolate = args.GetIsolate(); |
| 372 PerIsolateData* data = PerIsolateData::Get(isolate); |
| 373 if (args.Length() < 1 || !args[0]->IsNumber()) { |
| 374 return Throw("Invalid argument"); |
| 375 } |
| 376 int index = args[0]->Uint32Value(); |
| 377 if (index >= data->realm_count_ || data->realms_[index].IsEmpty() || |
| 378 index == 0 || |
| 379 index == data->realm_current_ || index == data->realm_switch_) { |
| 380 return Throw("Invalid realm index"); |
| 381 } |
| 382 data->realms_[index].Dispose(isolate); |
| 383 data->realms_[index].Clear(); |
| 384 return Undefined(isolate); |
| 385 } |
| 386 |
| 387 |
| 388 // Realm.switch(i) switches to the realm i for consecutive interactive inputs. |
| 389 Handle<Value> Shell::RealmSwitch(const Arguments& args) { |
| 390 Isolate* isolate = args.GetIsolate(); |
| 391 PerIsolateData* data = PerIsolateData::Get(isolate); |
| 392 if (args.Length() < 1 || !args[0]->IsNumber()) { |
| 393 return Throw("Invalid argument"); |
| 394 } |
| 395 int index = args[0]->Uint32Value(); |
| 396 if (index >= data->realm_count_ || data->realms_[index].IsEmpty()) { |
| 397 return Throw("Invalid realm index"); |
| 398 } |
| 399 data->realm_switch_ = index; |
| 400 return Undefined(isolate); |
| 401 } |
| 402 |
| 403 |
| 404 // Realm.eval(i, s) evaluates s in realm i and returns the result. |
| 405 Handle<Value> Shell::RealmEval(const Arguments& args) { |
| 406 Isolate* isolate = args.GetIsolate(); |
| 407 PerIsolateData* data = PerIsolateData::Get(isolate); |
| 408 if (args.Length() < 2 || !args[0]->IsNumber() || !args[1]->IsString()) { |
| 409 return Throw("Invalid argument"); |
| 410 } |
| 411 int index = args[0]->Uint32Value(); |
| 412 if (index >= data->realm_count_ || data->realms_[index].IsEmpty()) { |
| 413 return Throw("Invalid realm index"); |
| 414 } |
| 415 Handle<Script> script = Script::New(args[1]->ToString()); |
| 416 if (script.IsEmpty()) return Undefined(isolate); |
| 417 Local<Context> realm = Local<Context>::New(data->realms_[index]); |
| 418 realm->Enter(); |
| 419 Handle<Value> result = script->Run(); |
| 420 realm->Exit(); |
| 421 return result; |
| 422 } |
| 423 |
| 424 |
| 425 // Realm.shared is an accessor for a single shared value across realms. |
| 426 Handle<Value> Shell::RealmSharedGet(Local<String> property, |
| 427 const AccessorInfo& info) { |
| 428 Isolate* isolate = info.GetIsolate(); |
| 429 PerIsolateData* data = PerIsolateData::Get(isolate); |
| 430 if (data->realm_shared_.IsEmpty()) return Undefined(isolate); |
| 431 return data->realm_shared_; |
| 432 } |
| 433 |
| 434 void Shell::RealmSharedSet(Local<String> property, |
| 435 Local<Value> value, |
| 436 const AccessorInfo& info) { |
| 437 Isolate* isolate = info.GetIsolate(); |
| 438 PerIsolateData* data = PerIsolateData::Get(isolate); |
| 439 if (!data->realm_shared_.IsEmpty()) data->realm_shared_.Dispose(isolate); |
| 440 data->realm_shared_ = Persistent<Value>::New(isolate, value); |
| 441 } |
| 442 |
| 443 |
| 258 Handle<Value> Shell::Print(const Arguments& args) { | 444 Handle<Value> Shell::Print(const Arguments& args) { |
| 259 Handle<Value> val = Write(args); | 445 Handle<Value> val = Write(args); |
| 260 printf("\n"); | 446 printf("\n"); |
| 261 fflush(stdout); | 447 fflush(stdout); |
| 262 return val; | 448 return val; |
| 263 } | 449 } |
| 264 | 450 |
| 265 | 451 |
| 266 Handle<Value> Shell::Write(const Arguments& args) { | 452 Handle<Value> Shell::Write(const Arguments& args) { |
| 267 for (int i = 0; i < args.Length(); i++) { | 453 for (int i = 0; i < args.Length(); i++) { |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 409 // Make sure the total size fits into a (signed) int. | 595 // Make sure the total size fits into a (signed) int. |
| 410 if (length < 0 || length > kMaxSize) { | 596 if (length < 0 || length > kMaxSize) { |
| 411 return Throw("ArrayBuffer exceeds maximum size (2G)"); | 597 return Throw("ArrayBuffer exceeds maximum size (2G)"); |
| 412 } | 598 } |
| 413 uint8_t* data = new uint8_t[length]; | 599 uint8_t* data = new uint8_t[length]; |
| 414 if (data == NULL) { | 600 if (data == NULL) { |
| 415 return Throw("Memory allocation failed"); | 601 return Throw("Memory allocation failed"); |
| 416 } | 602 } |
| 417 memset(data, 0, length); | 603 memset(data, 0, length); |
| 418 | 604 |
| 419 buffer->SetHiddenValue(Symbols::ArrayBufferMarkerPropName(isolate), True()); | 605 buffer->SetHiddenValue( |
| 606 PerIsolateData::ArrayBufferMarkerPropName_string(isolate), True()); |
| 420 Persistent<Object> persistent_array = | 607 Persistent<Object> persistent_array = |
| 421 Persistent<Object>::New(isolate, buffer); | 608 Persistent<Object>::New(isolate, buffer); |
| 422 persistent_array.MakeWeak(isolate, data, ExternalArrayWeakCallback); | 609 persistent_array.MakeWeak(isolate, data, ExternalArrayWeakCallback); |
| 423 persistent_array.MarkIndependent(isolate); | 610 persistent_array.MarkIndependent(isolate); |
| 424 isolate->AdjustAmountOfExternalAllocatedMemory(length); | 611 isolate->AdjustAmountOfExternalAllocatedMemory(length); |
| 425 | 612 |
| 426 buffer->SetIndexedPropertiesToExternalArrayData( | 613 buffer->SetIndexedPropertiesToExternalArrayData( |
| 427 data, v8::kExternalByteArray, length); | 614 data, v8::kExternalByteArray, length); |
| 428 buffer->Set(Symbols::byteLength(isolate), | 615 buffer->Set(PerIsolateData::byteLength_string(isolate), |
| 429 Int32::New(length, isolate), | 616 Int32::New(length, isolate), |
| 430 ReadOnly); | 617 ReadOnly); |
| 431 | 618 |
| 432 return buffer; | 619 return buffer; |
| 433 } | 620 } |
| 434 | 621 |
| 435 | 622 |
| 436 Handle<Value> Shell::ArrayBuffer(const Arguments& args) { | 623 Handle<Value> Shell::ArrayBuffer(const Arguments& args) { |
| 437 if (!args.IsConstructCall()) { | 624 if (!args.IsConstructCall()) { |
| 438 Handle<Value>* rec_args = new Handle<Value>[args.Length()]; | 625 Handle<Value>* rec_args = new Handle<Value>[args.Length()]; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 463 int32_t element_size) { | 650 int32_t element_size) { |
| 464 ASSERT(element_size == 1 || element_size == 2 || | 651 ASSERT(element_size == 1 || element_size == 2 || |
| 465 element_size == 4 || element_size == 8); | 652 element_size == 4 || element_size == 8); |
| 466 ASSERT(byteLength == length * element_size); | 653 ASSERT(byteLength == length * element_size); |
| 467 | 654 |
| 468 void* data = buffer->GetIndexedPropertiesExternalArrayData(); | 655 void* data = buffer->GetIndexedPropertiesExternalArrayData(); |
| 469 ASSERT(data != NULL); | 656 ASSERT(data != NULL); |
| 470 | 657 |
| 471 array->SetIndexedPropertiesToExternalArrayData( | 658 array->SetIndexedPropertiesToExternalArrayData( |
| 472 static_cast<uint8_t*>(data) + byteOffset, type, length); | 659 static_cast<uint8_t*>(data) + byteOffset, type, length); |
| 473 array->SetHiddenValue(Symbols::ArrayMarkerPropName(isolate), | 660 array->SetHiddenValue(PerIsolateData::ArrayMarkerPropName_string(isolate), |
| 474 Int32::New(type, isolate)); | 661 Int32::New(type, isolate)); |
| 475 array->Set(Symbols::byteLength(isolate), | 662 array->Set(PerIsolateData::byteLength_string(isolate), |
| 476 Int32::New(byteLength, isolate), | 663 Int32::New(byteLength, isolate), |
| 477 ReadOnly); | 664 ReadOnly); |
| 478 array->Set(Symbols::byteOffset(isolate), | 665 array->Set(PerIsolateData::byteOffset_string(isolate), |
| 479 Int32::New(byteOffset, isolate), | 666 Int32::New(byteOffset, isolate), |
| 480 ReadOnly); | 667 ReadOnly); |
| 481 array->Set(Symbols::length(isolate), | 668 array->Set(PerIsolateData::length_string(isolate), |
| 482 Int32::New(length, isolate), | 669 Int32::New(length, isolate), |
| 483 ReadOnly); | 670 ReadOnly); |
| 484 array->Set(Symbols::BYTES_PER_ELEMENT(isolate), | 671 array->Set(PerIsolateData::BYTES_PER_ELEMENT_string(isolate), |
| 485 Int32::New(element_size, isolate)); | 672 Int32::New(element_size, isolate)); |
| 486 array->Set(Symbols::buffer(isolate), | 673 array->Set(PerIsolateData::buffer_string(isolate), |
| 487 buffer, | 674 buffer, |
| 488 ReadOnly); | 675 ReadOnly); |
| 489 | 676 |
| 490 return array; | 677 return array; |
| 491 } | 678 } |
| 492 | 679 |
| 493 | 680 |
| 494 Handle<Value> Shell::CreateExternalArray(const Arguments& args, | 681 Handle<Value> Shell::CreateExternalArray(const Arguments& args, |
| 495 ExternalArrayType type, | 682 ExternalArrayType type, |
| 496 int32_t element_size) { | 683 int32_t element_size) { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 517 Handle<Object> buffer; | 704 Handle<Object> buffer; |
| 518 int32_t length; | 705 int32_t length; |
| 519 int32_t byteLength; | 706 int32_t byteLength; |
| 520 int32_t byteOffset; | 707 int32_t byteOffset; |
| 521 bool init_from_array = false; | 708 bool init_from_array = false; |
| 522 if (args.Length() == 0) { | 709 if (args.Length() == 0) { |
| 523 return Throw("Array constructor must have at least one argument"); | 710 return Throw("Array constructor must have at least one argument"); |
| 524 } | 711 } |
| 525 if (args[0]->IsObject() && | 712 if (args[0]->IsObject() && |
| 526 !args[0]->ToObject()->GetHiddenValue( | 713 !args[0]->ToObject()->GetHiddenValue( |
| 527 Symbols::ArrayBufferMarkerPropName(isolate)).IsEmpty()) { | 714 PerIsolateData::ArrayBufferMarkerPropName_string(isolate)).IsEmpty()) { |
| 528 // Construct from ArrayBuffer. | 715 // Construct from ArrayBuffer. |
| 529 buffer = args[0]->ToObject(); | 716 buffer = args[0]->ToObject(); |
| 530 int32_t bufferLength = | 717 int32_t bufferLength = convertToUint( |
| 531 convertToUint(buffer->Get(Symbols::byteLength(isolate)), &try_catch); | 718 buffer->Get(PerIsolateData::byteLength_string(isolate)), &try_catch); |
| 532 if (try_catch.HasCaught()) return try_catch.ReThrow(); | 719 if (try_catch.HasCaught()) return try_catch.ReThrow(); |
| 533 | 720 |
| 534 if (args.Length() < 2 || args[1]->IsUndefined()) { | 721 if (args.Length() < 2 || args[1]->IsUndefined()) { |
| 535 byteOffset = 0; | 722 byteOffset = 0; |
| 536 } else { | 723 } else { |
| 537 byteOffset = convertToUint(args[1], &try_catch); | 724 byteOffset = convertToUint(args[1], &try_catch); |
| 538 if (try_catch.HasCaught()) return try_catch.ReThrow(); | 725 if (try_catch.HasCaught()) return try_catch.ReThrow(); |
| 539 if (byteOffset > bufferLength) { | 726 if (byteOffset > bufferLength) { |
| 540 return Throw("byteOffset out of bounds"); | 727 return Throw("byteOffset out of bounds"); |
| 541 } | 728 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 553 } else { | 740 } else { |
| 554 length = convertToUint(args[2], &try_catch); | 741 length = convertToUint(args[2], &try_catch); |
| 555 if (try_catch.HasCaught()) return try_catch.ReThrow(); | 742 if (try_catch.HasCaught()) return try_catch.ReThrow(); |
| 556 byteLength = length * element_size; | 743 byteLength = length * element_size; |
| 557 if (byteOffset + byteLength > bufferLength) { | 744 if (byteOffset + byteLength > bufferLength) { |
| 558 return Throw("length out of bounds"); | 745 return Throw("length out of bounds"); |
| 559 } | 746 } |
| 560 } | 747 } |
| 561 } else { | 748 } else { |
| 562 if (args[0]->IsObject() && | 749 if (args[0]->IsObject() && |
| 563 args[0]->ToObject()->Has(Symbols::length(isolate))) { | 750 args[0]->ToObject()->Has(PerIsolateData::length_string(isolate))) { |
| 564 // Construct from array. | 751 // Construct from array. |
| 565 Local<Value> value = args[0]->ToObject()->Get(Symbols::length(isolate)); | 752 Local<Value> value = |
| 753 args[0]->ToObject()->Get(PerIsolateData::length_string(isolate)); |
| 566 if (try_catch.HasCaught()) return try_catch.ReThrow(); | 754 if (try_catch.HasCaught()) return try_catch.ReThrow(); |
| 567 length = convertToUint(value, &try_catch); | 755 length = convertToUint(value, &try_catch); |
| 568 if (try_catch.HasCaught()) return try_catch.ReThrow(); | 756 if (try_catch.HasCaught()) return try_catch.ReThrow(); |
| 569 init_from_array = true; | 757 init_from_array = true; |
| 570 } else { | 758 } else { |
| 571 // Construct from size. | 759 // Construct from size. |
| 572 length = convertToUint(args[0], &try_catch); | 760 length = convertToUint(args[0], &try_catch); |
| 573 if (try_catch.HasCaught()) return try_catch.ReThrow(); | 761 if (try_catch.HasCaught()) return try_catch.ReThrow(); |
| 574 } | 762 } |
| 575 byteLength = length * element_size; | 763 byteLength = length * element_size; |
| 576 byteOffset = 0; | 764 byteOffset = 0; |
| 577 | 765 |
| 578 Handle<Object> global = Context::GetCurrent()->Global(); | 766 Handle<Object> global = Context::GetCurrent()->Global(); |
| 579 Handle<Value> array_buffer = global->Get(Symbols::ArrayBuffer(isolate)); | 767 Handle<Value> array_buffer = |
| 768 global->Get(PerIsolateData::ArrayBuffer_string(isolate)); |
| 580 ASSERT(!try_catch.HasCaught() && array_buffer->IsFunction()); | 769 ASSERT(!try_catch.HasCaught() && array_buffer->IsFunction()); |
| 581 Handle<Value> buffer_args[] = { Uint32::New(byteLength, isolate) }; | 770 Handle<Value> buffer_args[] = { Uint32::New(byteLength, isolate) }; |
| 582 Handle<Value> result = Handle<Function>::Cast(array_buffer)->NewInstance( | 771 Handle<Value> result = Handle<Function>::Cast(array_buffer)->NewInstance( |
| 583 1, buffer_args); | 772 1, buffer_args); |
| 584 if (try_catch.HasCaught()) return result; | 773 if (try_catch.HasCaught()) return result; |
| 585 buffer = result->ToObject(); | 774 buffer = result->ToObject(); |
| 586 } | 775 } |
| 587 | 776 |
| 588 Handle<Object> array = | 777 Handle<Object> array = |
| 589 CreateExternalArray(isolate, args.This(), buffer, type, length, | 778 CreateExternalArray(isolate, args.This(), buffer, type, length, |
| (...skipping 14 matching lines...) Expand all Loading... |
| 604 | 793 |
| 605 Handle<Value> Shell::ArrayBufferSlice(const Arguments& args) { | 794 Handle<Value> Shell::ArrayBufferSlice(const Arguments& args) { |
| 606 TryCatch try_catch; | 795 TryCatch try_catch; |
| 607 | 796 |
| 608 if (!args.This()->IsObject()) { | 797 if (!args.This()->IsObject()) { |
| 609 return Throw("'slice' invoked on non-object receiver"); | 798 return Throw("'slice' invoked on non-object receiver"); |
| 610 } | 799 } |
| 611 | 800 |
| 612 Isolate* isolate = args.GetIsolate(); | 801 Isolate* isolate = args.GetIsolate(); |
| 613 Local<Object> self = args.This(); | 802 Local<Object> self = args.This(); |
| 614 Local<Value> marker = | 803 Local<Value> marker = self->GetHiddenValue( |
| 615 self->GetHiddenValue(Symbols::ArrayBufferMarkerPropName(isolate)); | 804 PerIsolateData::ArrayBufferMarkerPropName_string(isolate)); |
| 616 if (marker.IsEmpty()) { | 805 if (marker.IsEmpty()) { |
| 617 return Throw("'slice' invoked on wrong receiver type"); | 806 return Throw("'slice' invoked on wrong receiver type"); |
| 618 } | 807 } |
| 619 | 808 |
| 620 int32_t length = | 809 int32_t length = convertToUint( |
| 621 convertToUint(self->Get(Symbols::byteLength(isolate)), &try_catch); | 810 self->Get(PerIsolateData::byteLength_string(isolate)), &try_catch); |
| 622 if (try_catch.HasCaught()) return try_catch.ReThrow(); | 811 if (try_catch.HasCaught()) return try_catch.ReThrow(); |
| 623 | 812 |
| 624 if (args.Length() == 0) { | 813 if (args.Length() == 0) { |
| 625 return Throw("'slice' must have at least one argument"); | 814 return Throw("'slice' must have at least one argument"); |
| 626 } | 815 } |
| 627 int32_t begin = convertToInt(args[0], &try_catch); | 816 int32_t begin = convertToInt(args[0], &try_catch); |
| 628 if (try_catch.HasCaught()) return try_catch.ReThrow(); | 817 if (try_catch.HasCaught()) return try_catch.ReThrow(); |
| 629 if (begin < 0) begin += length; | 818 if (begin < 0) begin += length; |
| 630 if (begin < 0) begin = 0; | 819 if (begin < 0) begin = 0; |
| 631 if (begin > length) begin = length; | 820 if (begin > length) begin = length; |
| (...skipping 28 matching lines...) Expand all Loading... |
| 660 Handle<Value> Shell::ArraySubArray(const Arguments& args) { | 849 Handle<Value> Shell::ArraySubArray(const Arguments& args) { |
| 661 TryCatch try_catch; | 850 TryCatch try_catch; |
| 662 | 851 |
| 663 if (!args.This()->IsObject()) { | 852 if (!args.This()->IsObject()) { |
| 664 return Throw("'subarray' invoked on non-object receiver"); | 853 return Throw("'subarray' invoked on non-object receiver"); |
| 665 } | 854 } |
| 666 | 855 |
| 667 Isolate* isolate = args.GetIsolate(); | 856 Isolate* isolate = args.GetIsolate(); |
| 668 Local<Object> self = args.This(); | 857 Local<Object> self = args.This(); |
| 669 Local<Value> marker = | 858 Local<Value> marker = |
| 670 self->GetHiddenValue(Symbols::ArrayMarkerPropName(isolate)); | 859 self->GetHiddenValue(PerIsolateData::ArrayMarkerPropName_string(isolate)); |
| 671 if (marker.IsEmpty()) { | 860 if (marker.IsEmpty()) { |
| 672 return Throw("'subarray' invoked on wrong receiver type"); | 861 return Throw("'subarray' invoked on wrong receiver type"); |
| 673 } | 862 } |
| 674 | 863 |
| 675 Handle<Object> buffer = self->Get(Symbols::buffer(isolate))->ToObject(); | 864 Handle<Object> buffer = |
| 865 self->Get(PerIsolateData::buffer_string(isolate))->ToObject(); |
| 676 if (try_catch.HasCaught()) return try_catch.ReThrow(); | 866 if (try_catch.HasCaught()) return try_catch.ReThrow(); |
| 677 int32_t length = | 867 int32_t length = convertToUint( |
| 678 convertToUint(self->Get(Symbols::length(isolate)), &try_catch); | 868 self->Get(PerIsolateData::length_string(isolate)), &try_catch); |
| 679 if (try_catch.HasCaught()) return try_catch.ReThrow(); | 869 if (try_catch.HasCaught()) return try_catch.ReThrow(); |
| 680 int32_t byteOffset = | 870 int32_t byteOffset = convertToUint( |
| 681 convertToUint(self->Get(Symbols::byteOffset(isolate)), &try_catch); | 871 self->Get(PerIsolateData::byteOffset_string(isolate)), &try_catch); |
| 682 if (try_catch.HasCaught()) return try_catch.ReThrow(); | 872 if (try_catch.HasCaught()) return try_catch.ReThrow(); |
| 683 int32_t element_size = | 873 int32_t element_size = convertToUint( |
| 684 convertToUint(self->Get(Symbols::BYTES_PER_ELEMENT(isolate)), &try_catch); | 874 self->Get(PerIsolateData::BYTES_PER_ELEMENT_string(isolate)), &try_catch); |
| 685 if (try_catch.HasCaught()) return try_catch.ReThrow(); | 875 if (try_catch.HasCaught()) return try_catch.ReThrow(); |
| 686 | 876 |
| 687 if (args.Length() == 0) { | 877 if (args.Length() == 0) { |
| 688 return Throw("'subarray' must have at least one argument"); | 878 return Throw("'subarray' must have at least one argument"); |
| 689 } | 879 } |
| 690 int32_t begin = convertToInt(args[0], &try_catch); | 880 int32_t begin = convertToInt(args[0], &try_catch); |
| 691 if (try_catch.HasCaught()) return try_catch.ReThrow(); | 881 if (try_catch.HasCaught()) return try_catch.ReThrow(); |
| 692 if (begin < 0) begin += length; | 882 if (begin < 0) begin += length; |
| 693 if (begin < 0) begin = 0; | 883 if (begin < 0) begin = 0; |
| 694 if (begin > length) begin = length; | 884 if (begin > length) begin = length; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 719 Handle<Value> Shell::ArraySet(const Arguments& args) { | 909 Handle<Value> Shell::ArraySet(const Arguments& args) { |
| 720 TryCatch try_catch; | 910 TryCatch try_catch; |
| 721 | 911 |
| 722 if (!args.This()->IsObject()) { | 912 if (!args.This()->IsObject()) { |
| 723 return Throw("'set' invoked on non-object receiver"); | 913 return Throw("'set' invoked on non-object receiver"); |
| 724 } | 914 } |
| 725 | 915 |
| 726 Isolate* isolate = args.GetIsolate(); | 916 Isolate* isolate = args.GetIsolate(); |
| 727 Local<Object> self = args.This(); | 917 Local<Object> self = args.This(); |
| 728 Local<Value> marker = | 918 Local<Value> marker = |
| 729 self->GetHiddenValue(Symbols::ArrayMarkerPropName(isolate)); | 919 self->GetHiddenValue(PerIsolateData::ArrayMarkerPropName_string(isolate)); |
| 730 if (marker.IsEmpty()) { | 920 if (marker.IsEmpty()) { |
| 731 return Throw("'set' invoked on wrong receiver type"); | 921 return Throw("'set' invoked on wrong receiver type"); |
| 732 } | 922 } |
| 733 int32_t length = | 923 int32_t length = convertToUint( |
| 734 convertToUint(self->Get(Symbols::length(isolate)), &try_catch); | 924 self->Get(PerIsolateData::length_string(isolate)), &try_catch); |
| 735 if (try_catch.HasCaught()) return try_catch.ReThrow(); | 925 if (try_catch.HasCaught()) return try_catch.ReThrow(); |
| 736 int32_t element_size = | 926 int32_t element_size = convertToUint( |
| 737 convertToUint(self->Get(Symbols::BYTES_PER_ELEMENT(isolate)), &try_catch); | 927 self->Get(PerIsolateData::BYTES_PER_ELEMENT_string(isolate)), &try_catch); |
| 738 if (try_catch.HasCaught()) return try_catch.ReThrow(); | 928 if (try_catch.HasCaught()) return try_catch.ReThrow(); |
| 739 | 929 |
| 740 if (args.Length() == 0) { | 930 if (args.Length() == 0) { |
| 741 return Throw("'set' must have at least one argument"); | 931 return Throw("'set' must have at least one argument"); |
| 742 } | 932 } |
| 743 if (!args[0]->IsObject() || | 933 if (!args[0]->IsObject() || |
| 744 !args[0]->ToObject()->Has(Symbols::length(isolate))) { | 934 !args[0]->ToObject()->Has(PerIsolateData::length_string(isolate))) { |
| 745 return Throw("'set' invoked with non-array argument"); | 935 return Throw("'set' invoked with non-array argument"); |
| 746 } | 936 } |
| 747 Handle<Object> source = args[0]->ToObject(); | 937 Handle<Object> source = args[0]->ToObject(); |
| 748 int32_t source_length = | 938 int32_t source_length = convertToUint( |
| 749 convertToUint(source->Get(Symbols::length(isolate)), &try_catch); | 939 source->Get(PerIsolateData::length_string(isolate)), &try_catch); |
| 750 if (try_catch.HasCaught()) return try_catch.ReThrow(); | 940 if (try_catch.HasCaught()) return try_catch.ReThrow(); |
| 751 | 941 |
| 752 int32_t offset; | 942 int32_t offset; |
| 753 if (args.Length() < 2 || args[1]->IsUndefined()) { | 943 if (args.Length() < 2 || args[1]->IsUndefined()) { |
| 754 offset = 0; | 944 offset = 0; |
| 755 } else { | 945 } else { |
| 756 offset = convertToUint(args[1], &try_catch); | 946 offset = convertToUint(args[1], &try_catch); |
| 757 if (try_catch.HasCaught()) return try_catch.ReThrow(); | 947 if (try_catch.HasCaught()) return try_catch.ReThrow(); |
| 758 } | 948 } |
| 759 if (offset + source_length > length) { | 949 if (offset + source_length > length) { |
| 760 return Throw("offset or source length out of bounds"); | 950 return Throw("offset or source length out of bounds"); |
| 761 } | 951 } |
| 762 | 952 |
| 763 int32_t source_element_size; | 953 int32_t source_element_size; |
| 764 if (source->GetHiddenValue(Symbols::ArrayMarkerPropName(isolate)).IsEmpty()) { | 954 if (source->GetHiddenValue( |
| 955 PerIsolateData::ArrayMarkerPropName_string(isolate)).IsEmpty()) { |
| 765 source_element_size = 0; | 956 source_element_size = 0; |
| 766 } else { | 957 } else { |
| 767 source_element_size = | 958 source_element_size = convertToUint( |
| 768 convertToUint(source->Get(Symbols::BYTES_PER_ELEMENT(isolate)), | 959 source->Get(PerIsolateData::BYTES_PER_ELEMENT_string(isolate)), |
| 769 &try_catch); | 960 &try_catch); |
| 770 if (try_catch.HasCaught()) return try_catch.ReThrow(); | 961 if (try_catch.HasCaught()) return try_catch.ReThrow(); |
| 771 } | 962 } |
| 772 | 963 |
| 773 if (element_size == source_element_size && | 964 if (element_size == source_element_size && |
| 774 self->GetConstructor()->StrictEquals(source->GetConstructor())) { | 965 self->GetConstructor()->StrictEquals(source->GetConstructor())) { |
| 775 // Use memmove on the array buffers. | 966 // Use memmove on the array buffers. |
| 776 Handle<Object> buffer = self->Get(Symbols::buffer(isolate))->ToObject(); | 967 Handle<Object> buffer = |
| 968 self->Get(PerIsolateData::buffer_string(isolate))->ToObject(); |
| 777 if (try_catch.HasCaught()) return try_catch.ReThrow(); | 969 if (try_catch.HasCaught()) return try_catch.ReThrow(); |
| 778 Handle<Object> source_buffer = | 970 Handle<Object> source_buffer = |
| 779 source->Get(Symbols::buffer(isolate))->ToObject(); | 971 source->Get(PerIsolateData::buffer_string(isolate))->ToObject(); |
| 780 if (try_catch.HasCaught()) return try_catch.ReThrow(); | 972 if (try_catch.HasCaught()) return try_catch.ReThrow(); |
| 781 int32_t byteOffset = | 973 int32_t byteOffset = convertToUint( |
| 782 convertToUint(self->Get(Symbols::byteOffset(isolate)), &try_catch); | 974 self->Get(PerIsolateData::byteOffset_string(isolate)), &try_catch); |
| 783 if (try_catch.HasCaught()) return try_catch.ReThrow(); | 975 if (try_catch.HasCaught()) return try_catch.ReThrow(); |
| 784 int32_t source_byteOffset = | 976 int32_t source_byteOffset = convertToUint( |
| 785 convertToUint(source->Get(Symbols::byteOffset(isolate)), &try_catch); | 977 source->Get(PerIsolateData::byteOffset_string(isolate)), &try_catch); |
| 786 if (try_catch.HasCaught()) return try_catch.ReThrow(); | 978 if (try_catch.HasCaught()) return try_catch.ReThrow(); |
| 787 | 979 |
| 788 uint8_t* dest = byteOffset + offset * element_size + static_cast<uint8_t*>( | 980 uint8_t* dest = byteOffset + offset * element_size + static_cast<uint8_t*>( |
| 789 buffer->GetIndexedPropertiesExternalArrayData()); | 981 buffer->GetIndexedPropertiesExternalArrayData()); |
| 790 uint8_t* src = source_byteOffset + static_cast<uint8_t*>( | 982 uint8_t* src = source_byteOffset + static_cast<uint8_t*>( |
| 791 source_buffer->GetIndexedPropertiesExternalArrayData()); | 983 source_buffer->GetIndexedPropertiesExternalArrayData()); |
| 792 memmove(dest, src, source_length * element_size); | 984 memmove(dest, src, source_length * element_size); |
| 793 } else if (source_element_size == 0) { | 985 } else if (source_element_size == 0) { |
| 794 // Source is not a typed array, copy element-wise sequentially. | 986 // Source is not a typed array, copy element-wise sequentially. |
| 795 for (int i = 0; i < source_length; ++i) { | 987 for (int i = 0; i < source_length; ++i) { |
| 796 self->Set(offset + i, source->Get(i)); | 988 self->Set(offset + i, source->Get(i)); |
| 797 if (try_catch.HasCaught()) return try_catch.ReThrow(); | 989 if (try_catch.HasCaught()) return try_catch.ReThrow(); |
| 798 } | 990 } |
| 799 } else { | 991 } else { |
| 800 // Need to copy element-wise to make the right conversions. | 992 // Need to copy element-wise to make the right conversions. |
| 801 Handle<Object> buffer = self->Get(Symbols::buffer(isolate))->ToObject(); | 993 Handle<Object> buffer = |
| 994 self->Get(PerIsolateData::buffer_string(isolate))->ToObject(); |
| 802 if (try_catch.HasCaught()) return try_catch.ReThrow(); | 995 if (try_catch.HasCaught()) return try_catch.ReThrow(); |
| 803 Handle<Object> source_buffer = | 996 Handle<Object> source_buffer = |
| 804 source->Get(Symbols::buffer(isolate))->ToObject(); | 997 source->Get(PerIsolateData::buffer_string(isolate))->ToObject(); |
| 805 if (try_catch.HasCaught()) return try_catch.ReThrow(); | 998 if (try_catch.HasCaught()) return try_catch.ReThrow(); |
| 806 | 999 |
| 807 if (buffer->StrictEquals(source_buffer)) { | 1000 if (buffer->StrictEquals(source_buffer)) { |
| 808 // Same backing store, need to handle overlap correctly. | 1001 // Same backing store, need to handle overlap correctly. |
| 809 // This gets a bit tricky in the case of different element sizes | 1002 // This gets a bit tricky in the case of different element sizes |
| 810 // (which, of course, is extremely unlikely to ever occur in practice). | 1003 // (which, of course, is extremely unlikely to ever occur in practice). |
| 811 int32_t byteOffset = | 1004 int32_t byteOffset = convertToUint( |
| 812 convertToUint(self->Get(Symbols::byteOffset(isolate)), &try_catch); | 1005 self->Get(PerIsolateData::byteOffset_string(isolate)), &try_catch); |
| 813 if (try_catch.HasCaught()) return try_catch.ReThrow(); | 1006 if (try_catch.HasCaught()) return try_catch.ReThrow(); |
| 814 int32_t source_byteOffset = | 1007 int32_t source_byteOffset = convertToUint( |
| 815 convertToUint(source->Get(Symbols::byteOffset(isolate)), &try_catch); | 1008 source->Get(PerIsolateData::byteOffset_string(isolate)), &try_catch); |
| 816 if (try_catch.HasCaught()) return try_catch.ReThrow(); | 1009 if (try_catch.HasCaught()) return try_catch.ReThrow(); |
| 817 | 1010 |
| 818 // Copy as much as we can from left to right. | 1011 // Copy as much as we can from left to right. |
| 819 int i = 0; | 1012 int i = 0; |
| 820 int32_t next_dest_offset = byteOffset + (offset + 1) * element_size; | 1013 int32_t next_dest_offset = byteOffset + (offset + 1) * element_size; |
| 821 int32_t next_src_offset = source_byteOffset + source_element_size; | 1014 int32_t next_src_offset = source_byteOffset + source_element_size; |
| 822 while (i < length && next_dest_offset <= next_src_offset) { | 1015 while (i < length && next_dest_offset <= next_src_offset) { |
| 823 self->Set(offset + i, source->Get(i)); | 1016 self->Set(offset + i, source->Get(i)); |
| 824 ++i; | 1017 ++i; |
| 825 next_dest_offset += element_size; | 1018 next_dest_offset += element_size; |
| (...skipping 27 matching lines...) Expand all Loading... |
| 853 } | 1046 } |
| 854 | 1047 |
| 855 return Undefined(args.GetIsolate()); | 1048 return Undefined(args.GetIsolate()); |
| 856 } | 1049 } |
| 857 | 1050 |
| 858 | 1051 |
| 859 void Shell::ExternalArrayWeakCallback(v8::Isolate* isolate, | 1052 void Shell::ExternalArrayWeakCallback(v8::Isolate* isolate, |
| 860 Persistent<Value> object, | 1053 Persistent<Value> object, |
| 861 void* data) { | 1054 void* data) { |
| 862 HandleScope scope(isolate); | 1055 HandleScope scope(isolate); |
| 863 int32_t length = | 1056 int32_t length = object->ToObject()->Get( |
| 864 object->ToObject()->Get(Symbols::byteLength(isolate))->Uint32Value(); | 1057 PerIsolateData::byteLength_string(isolate))->Uint32Value(); |
| 865 isolate->AdjustAmountOfExternalAllocatedMemory(-length); | 1058 isolate->AdjustAmountOfExternalAllocatedMemory(-length); |
| 866 delete[] static_cast<uint8_t*>(data); | 1059 delete[] static_cast<uint8_t*>(data); |
| 867 object.Dispose(isolate); | 1060 object.Dispose(isolate); |
| 868 } | 1061 } |
| 869 | 1062 |
| 870 | 1063 |
| 871 Handle<Value> Shell::Int8Array(const Arguments& args) { | 1064 Handle<Value> Shell::Int8Array(const Arguments& args) { |
| 872 return CreateExternalArray(args, v8::kExternalByteArray, sizeof(int8_t)); | 1065 return CreateExternalArray(args, v8::kExternalByteArray, sizeof(int8_t)); |
| 873 } | 1066 } |
| 874 | 1067 |
| (...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1231 global_template->Set(String::New("readline"), | 1424 global_template->Set(String::New("readline"), |
| 1232 FunctionTemplate::New(ReadLine)); | 1425 FunctionTemplate::New(ReadLine)); |
| 1233 global_template->Set(String::New("load"), FunctionTemplate::New(Load)); | 1426 global_template->Set(String::New("load"), FunctionTemplate::New(Load)); |
| 1234 global_template->Set(String::New("quit"), FunctionTemplate::New(Quit)); | 1427 global_template->Set(String::New("quit"), FunctionTemplate::New(Quit)); |
| 1235 global_template->Set(String::New("version"), FunctionTemplate::New(Version)); | 1428 global_template->Set(String::New("version"), FunctionTemplate::New(Version)); |
| 1236 global_template->Set(String::New("enableProfiler"), | 1429 global_template->Set(String::New("enableProfiler"), |
| 1237 FunctionTemplate::New(EnableProfiler)); | 1430 FunctionTemplate::New(EnableProfiler)); |
| 1238 global_template->Set(String::New("disableProfiler"), | 1431 global_template->Set(String::New("disableProfiler"), |
| 1239 FunctionTemplate::New(DisableProfiler)); | 1432 FunctionTemplate::New(DisableProfiler)); |
| 1240 | 1433 |
| 1434 // Bind the Realm object. |
| 1435 Handle<ObjectTemplate> realm_template = ObjectTemplate::New(); |
| 1436 realm_template->Set(String::New("current"), |
| 1437 FunctionTemplate::New(RealmCurrent)); |
| 1438 realm_template->Set(String::New("owner"), |
| 1439 FunctionTemplate::New(RealmOwner)); |
| 1440 realm_template->Set(String::New("global"), |
| 1441 FunctionTemplate::New(RealmGlobal)); |
| 1442 realm_template->Set(String::New("create"), |
| 1443 FunctionTemplate::New(RealmCreate)); |
| 1444 realm_template->Set(String::New("dispose"), |
| 1445 FunctionTemplate::New(RealmDispose)); |
| 1446 realm_template->Set(String::New("switch"), |
| 1447 FunctionTemplate::New(RealmSwitch)); |
| 1448 realm_template->Set(String::New("eval"), |
| 1449 FunctionTemplate::New(RealmEval)); |
| 1450 realm_template->SetAccessor(String::New("shared"), |
| 1451 RealmSharedGet, RealmSharedSet); |
| 1452 global_template->Set(String::New("Realm"), realm_template); |
| 1453 |
| 1241 // Bind the handlers for external arrays. | 1454 // Bind the handlers for external arrays. |
| 1242 PropertyAttribute attr = | 1455 PropertyAttribute attr = |
| 1243 static_cast<PropertyAttribute>(ReadOnly | DontDelete); | 1456 static_cast<PropertyAttribute>(ReadOnly | DontDelete); |
| 1244 global_template->Set(Symbols::ArrayBuffer(isolate), | 1457 global_template->Set(PerIsolateData::ArrayBuffer_string(isolate), |
| 1245 CreateArrayBufferTemplate(ArrayBuffer), attr); | 1458 CreateArrayBufferTemplate(ArrayBuffer), attr); |
| 1246 global_template->Set(String::New("Int8Array"), | 1459 global_template->Set(String::New("Int8Array"), |
| 1247 CreateArrayTemplate(Int8Array), attr); | 1460 CreateArrayTemplate(Int8Array), attr); |
| 1248 global_template->Set(String::New("Uint8Array"), | 1461 global_template->Set(String::New("Uint8Array"), |
| 1249 CreateArrayTemplate(Uint8Array), attr); | 1462 CreateArrayTemplate(Uint8Array), attr); |
| 1250 global_template->Set(String::New("Int16Array"), | 1463 global_template->Set(String::New("Int16Array"), |
| 1251 CreateArrayTemplate(Int16Array), attr); | 1464 CreateArrayTemplate(Int16Array), attr); |
| 1252 global_template->Set(String::New("Uint16Array"), | 1465 global_template->Set(String::New("Uint16Array"), |
| 1253 CreateArrayTemplate(Uint16Array), attr); | 1466 CreateArrayTemplate(Uint16Array), attr); |
| 1254 global_template->Set(String::New("Int32Array"), | 1467 global_template->Set(String::New("Int32Array"), |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1462 return Throw("Error loading file"); | 1675 return Throw("Error loading file"); |
| 1463 } | 1676 } |
| 1464 | 1677 |
| 1465 uint8_t* data = reinterpret_cast<uint8_t*>( | 1678 uint8_t* data = reinterpret_cast<uint8_t*>( |
| 1466 ReadChars(args.GetIsolate(), *filename, &length)); | 1679 ReadChars(args.GetIsolate(), *filename, &length)); |
| 1467 if (data == NULL) { | 1680 if (data == NULL) { |
| 1468 return Throw("Error reading file"); | 1681 return Throw("Error reading file"); |
| 1469 } | 1682 } |
| 1470 Isolate* isolate = args.GetIsolate(); | 1683 Isolate* isolate = args.GetIsolate(); |
| 1471 Handle<Object> buffer = Object::New(); | 1684 Handle<Object> buffer = Object::New(); |
| 1472 buffer->SetHiddenValue(Symbols::ArrayBufferMarkerPropName(isolate), True()); | 1685 buffer->SetHiddenValue( |
| 1686 PerIsolateData::ArrayBufferMarkerPropName_string(isolate), True()); |
| 1473 Persistent<Object> persistent_buffer = | 1687 Persistent<Object> persistent_buffer = |
| 1474 Persistent<Object>::New(isolate, buffer); | 1688 Persistent<Object>::New(isolate, buffer); |
| 1475 persistent_buffer.MakeWeak(isolate, data, ExternalArrayWeakCallback); | 1689 persistent_buffer.MakeWeak(isolate, data, ExternalArrayWeakCallback); |
| 1476 persistent_buffer.MarkIndependent(isolate); | 1690 persistent_buffer.MarkIndependent(isolate); |
| 1477 isolate->AdjustAmountOfExternalAllocatedMemory(length); | 1691 isolate->AdjustAmountOfExternalAllocatedMemory(length); |
| 1478 | 1692 |
| 1479 buffer->SetIndexedPropertiesToExternalArrayData( | 1693 buffer->SetIndexedPropertiesToExternalArrayData( |
| 1480 data, kExternalUnsignedByteArray, length); | 1694 data, kExternalUnsignedByteArray, length); |
| 1481 buffer->Set(Symbols::byteLength(isolate), | 1695 buffer->Set(PerIsolateData::byteLength_string(isolate), |
| 1482 Int32::New(static_cast<int32_t>(length), isolate), ReadOnly); | 1696 Int32::New(static_cast<int32_t>(length), isolate), ReadOnly); |
| 1483 return buffer; | 1697 return buffer; |
| 1484 } | 1698 } |
| 1485 | 1699 |
| 1486 | 1700 |
| 1487 #ifndef V8_SHARED | 1701 #ifndef V8_SHARED |
| 1488 static char* ReadToken(char* data, char token) { | 1702 static char* ReadToken(char* data, char token) { |
| 1489 char* next = i::OS::StrChr(data, token); | 1703 char* next = i::OS::StrChr(data, token); |
| 1490 if (next != NULL) { | 1704 if (next != NULL) { |
| 1491 *next = '\0'; | 1705 *next = '\0'; |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1514 if (chars == NULL) return Handle<String>(); | 1728 if (chars == NULL) return Handle<String>(); |
| 1515 Handle<String> result = String::New(chars, size); | 1729 Handle<String> result = String::New(chars, size); |
| 1516 delete[] chars; | 1730 delete[] chars; |
| 1517 return result; | 1731 return result; |
| 1518 } | 1732 } |
| 1519 | 1733 |
| 1520 | 1734 |
| 1521 void Shell::RunShell(Isolate* isolate) { | 1735 void Shell::RunShell(Isolate* isolate) { |
| 1522 Locker locker(isolate); | 1736 Locker locker(isolate); |
| 1523 Context::Scope context_scope(evaluation_context_); | 1737 Context::Scope context_scope(evaluation_context_); |
| 1738 PerIsolateData::RealmScope realm_scope(PerIsolateData::Get(isolate)); |
| 1524 HandleScope outer_scope(isolate); | 1739 HandleScope outer_scope(isolate); |
| 1525 Handle<String> name = String::New("(d8)"); | 1740 Handle<String> name = String::New("(d8)"); |
| 1526 LineEditor* console = LineEditor::Get(); | 1741 LineEditor* console = LineEditor::Get(); |
| 1527 printf("V8 version %s [console: %s]\n", V8::GetVersion(), console->name()); | 1742 printf("V8 version %s [console: %s]\n", V8::GetVersion(), console->name()); |
| 1528 console->Open(isolate); | 1743 console->Open(isolate); |
| 1529 while (true) { | 1744 while (true) { |
| 1530 HandleScope inner_scope(isolate); | 1745 HandleScope inner_scope(isolate); |
| 1531 Handle<String> input = console->Prompt(Shell::kPrompt); | 1746 Handle<String> input = console->Prompt(Shell::kPrompt); |
| 1532 if (input.IsEmpty()) break; | 1747 if (input.IsEmpty()) break; |
| 1533 ExecuteString(isolate, input, name, true, true); | 1748 ExecuteString(isolate, input, name, true, true); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1566 ptr = next_line; | 1781 ptr = next_line; |
| 1567 continue; | 1782 continue; |
| 1568 } | 1783 } |
| 1569 | 1784 |
| 1570 // Prepare the context for this thread. | 1785 // Prepare the context for this thread. |
| 1571 Locker locker(isolate_); | 1786 Locker locker(isolate_); |
| 1572 HandleScope outer_scope(isolate_); | 1787 HandleScope outer_scope(isolate_); |
| 1573 Persistent<Context> thread_context = | 1788 Persistent<Context> thread_context = |
| 1574 Shell::CreateEvaluationContext(isolate_); | 1789 Shell::CreateEvaluationContext(isolate_); |
| 1575 Context::Scope context_scope(thread_context); | 1790 Context::Scope context_scope(thread_context); |
| 1791 PerIsolateData::RealmScope realm_scope(PerIsolateData::Get(isolate_)); |
| 1576 | 1792 |
| 1577 while ((ptr != NULL) && (*ptr != '\0')) { | 1793 while ((ptr != NULL) && (*ptr != '\0')) { |
| 1578 HandleScope inner_scope(isolate_); | 1794 HandleScope inner_scope(isolate_); |
| 1579 char* filename = ptr; | 1795 char* filename = ptr; |
| 1580 ptr = ReadWord(ptr); | 1796 ptr = ReadWord(ptr); |
| 1581 | 1797 |
| 1582 // Skip empty strings. | 1798 // Skip empty strings. |
| 1583 if (strlen(filename) == 0) { | 1799 if (strlen(filename) == 0) { |
| 1584 continue; | 1800 continue; |
| 1585 } | 1801 } |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1664 | 1880 |
| 1665 | 1881 |
| 1666 void SourceGroup::ExecuteInThread() { | 1882 void SourceGroup::ExecuteInThread() { |
| 1667 Isolate* isolate = Isolate::New(); | 1883 Isolate* isolate = Isolate::New(); |
| 1668 do { | 1884 do { |
| 1669 if (next_semaphore_ != NULL) next_semaphore_->Wait(); | 1885 if (next_semaphore_ != NULL) next_semaphore_->Wait(); |
| 1670 { | 1886 { |
| 1671 Isolate::Scope iscope(isolate); | 1887 Isolate::Scope iscope(isolate); |
| 1672 Locker lock(isolate); | 1888 Locker lock(isolate); |
| 1673 HandleScope scope(isolate); | 1889 HandleScope scope(isolate); |
| 1674 Symbols symbols(isolate); | 1890 PerIsolateData data(isolate); |
| 1675 Persistent<Context> context = Shell::CreateEvaluationContext(isolate); | 1891 Persistent<Context> context = Shell::CreateEvaluationContext(isolate); |
| 1676 { | 1892 { |
| 1677 Context::Scope cscope(context); | 1893 Context::Scope cscope(context); |
| 1894 PerIsolateData::RealmScope realm_scope(PerIsolateData::Get(isolate)); |
| 1678 Execute(isolate); | 1895 Execute(isolate); |
| 1679 } | 1896 } |
| 1680 context.Dispose(isolate); | 1897 context.Dispose(isolate); |
| 1681 if (Shell::options.send_idle_notification) { | 1898 if (Shell::options.send_idle_notification) { |
| 1682 const int kLongIdlePauseInMs = 1000; | 1899 const int kLongIdlePauseInMs = 1000; |
| 1683 V8::ContextDisposedNotification(); | 1900 V8::ContextDisposedNotification(); |
| 1684 V8::IdleNotification(kLongIdlePauseInMs); | 1901 V8::IdleNotification(kLongIdlePauseInMs); |
| 1685 } | 1902 } |
| 1686 } | 1903 } |
| 1687 if (done_semaphore_ != NULL) done_semaphore_->Signal(); | 1904 if (done_semaphore_ != NULL) done_semaphore_->Signal(); |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1876 #if !defined(V8_SHARED) && defined(ENABLE_DEBUGGER_SUPPORT) | 2093 #if !defined(V8_SHARED) && defined(ENABLE_DEBUGGER_SUPPORT) |
| 1877 // If the interactive debugger is enabled make sure to activate | 2094 // If the interactive debugger is enabled make sure to activate |
| 1878 // it before running the files passed on the command line. | 2095 // it before running the files passed on the command line. |
| 1879 if (i::FLAG_debugger) { | 2096 if (i::FLAG_debugger) { |
| 1880 InstallUtilityScript(isolate); | 2097 InstallUtilityScript(isolate); |
| 1881 } | 2098 } |
| 1882 #endif // !V8_SHARED && ENABLE_DEBUGGER_SUPPORT | 2099 #endif // !V8_SHARED && ENABLE_DEBUGGER_SUPPORT |
| 1883 } | 2100 } |
| 1884 { | 2101 { |
| 1885 Context::Scope cscope(context); | 2102 Context::Scope cscope(context); |
| 2103 PerIsolateData::RealmScope realm_scope(PerIsolateData::Get(isolate)); |
| 1886 options.isolate_sources[0].Execute(isolate); | 2104 options.isolate_sources[0].Execute(isolate); |
| 1887 } | 2105 } |
| 1888 if (!options.last_run) { | 2106 if (!options.last_run) { |
| 1889 context.Dispose(isolate); | 2107 context.Dispose(isolate); |
| 1890 if (options.send_idle_notification) { | 2108 if (options.send_idle_notification) { |
| 1891 const int kLongIdlePauseInMs = 1000; | 2109 const int kLongIdlePauseInMs = 1000; |
| 1892 V8::ContextDisposedNotification(); | 2110 V8::ContextDisposedNotification(); |
| 1893 V8::IdleNotification(kLongIdlePauseInMs); | 2111 V8::IdleNotification(kLongIdlePauseInMs); |
| 1894 } | 2112 } |
| 1895 } | 2113 } |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1926 int Shell::Main(int argc, char* argv[]) { | 2144 int Shell::Main(int argc, char* argv[]) { |
| 1927 if (!SetOptions(argc, argv)) return 1; | 2145 if (!SetOptions(argc, argv)) return 1; |
| 1928 int result = 0; | 2146 int result = 0; |
| 1929 Isolate* isolate = Isolate::GetCurrent(); | 2147 Isolate* isolate = Isolate::GetCurrent(); |
| 1930 DumbLineEditor dumb_line_editor(isolate); | 2148 DumbLineEditor dumb_line_editor(isolate); |
| 1931 { | 2149 { |
| 1932 Initialize(isolate); | 2150 Initialize(isolate); |
| 1933 #ifdef ENABLE_VTUNE_JIT_INTERFACE | 2151 #ifdef ENABLE_VTUNE_JIT_INTERFACE |
| 1934 vTune::InitilizeVtuneForV8(); | 2152 vTune::InitilizeVtuneForV8(); |
| 1935 #endif | 2153 #endif |
| 1936 Symbols symbols(isolate); | 2154 PerIsolateData data(isolate); |
| 1937 InitializeDebugger(isolate); | 2155 InitializeDebugger(isolate); |
| 1938 | 2156 |
| 1939 if (options.stress_opt || options.stress_deopt) { | 2157 if (options.stress_opt || options.stress_deopt) { |
| 1940 Testing::SetStressRunType(options.stress_opt | 2158 Testing::SetStressRunType(options.stress_opt |
| 1941 ? Testing::kStressTypeOpt | 2159 ? Testing::kStressTypeOpt |
| 1942 : Testing::kStressTypeDeopt); | 2160 : Testing::kStressTypeDeopt); |
| 1943 int stress_runs = Testing::GetStressRuns(); | 2161 int stress_runs = Testing::GetStressRuns(); |
| 1944 for (int i = 0; i < stress_runs && result == 0; i++) { | 2162 for (int i = 0; i < stress_runs && result == 0; i++) { |
| 1945 printf("============ Stress %d/%d ============\n", i + 1, stress_runs); | 2163 printf("============ Stress %d/%d ============\n", i + 1, stress_runs); |
| 1946 Testing::PrepareStressRun(i); | 2164 Testing::PrepareStressRun(i); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1993 } | 2211 } |
| 1994 | 2212 |
| 1995 } // namespace v8 | 2213 } // namespace v8 |
| 1996 | 2214 |
| 1997 | 2215 |
| 1998 #ifndef GOOGLE3 | 2216 #ifndef GOOGLE3 |
| 1999 int main(int argc, char* argv[]) { | 2217 int main(int argc, char* argv[]) { |
| 2000 return v8::Shell::Main(argc, argv); | 2218 return v8::Shell::Main(argc, argv); |
| 2001 } | 2219 } |
| 2002 #endif | 2220 #endif |
| OLD | NEW |