| 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 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 127 Handle<JSGlobalProxy> ReinitializeJSGlobalProxy( | 127 Handle<JSGlobalProxy> ReinitializeJSGlobalProxy( |
| 128 Handle<JSFunction> constructor, | 128 Handle<JSFunction> constructor, |
| 129 Handle<JSGlobalProxy> global) { | 129 Handle<JSGlobalProxy> global) { |
| 130 CALL_HEAP_FUNCTION( | 130 CALL_HEAP_FUNCTION( |
| 131 constructor->GetIsolate(), | 131 constructor->GetIsolate(), |
| 132 constructor->GetHeap()->ReinitializeJSGlobalProxy(*constructor, *global), | 132 constructor->GetHeap()->ReinitializeJSGlobalProxy(*constructor, *global), |
| 133 JSGlobalProxy); | 133 JSGlobalProxy); |
| 134 } | 134 } |
| 135 | 135 |
| 136 | 136 |
| 137 Handle<Object> GetProperty(Handle<JSReceiver> obj, | 137 MaybeHandle<Object> GetProperty(Handle<JSReceiver> obj, |
| 138 const char* name) { | 138 const char* name) { |
| 139 Isolate* isolate = obj->GetIsolate(); | 139 Isolate* isolate = obj->GetIsolate(); |
| 140 Handle<String> str = isolate->factory()->InternalizeUtf8String(name); | 140 Handle<String> str = isolate->factory()->InternalizeUtf8String(name); |
| 141 ASSERT(!str.is_null()); | 141 ASSERT(!str.is_null()); |
| 142 return Object::GetPropertyOrElement(obj, str); | 142 return Object::GetPropertyOrElement(obj, str); |
| 143 } | 143 } |
| 144 | 144 |
| 145 | 145 |
| 146 // Wrappers for scripts are kept alive and cached in weak global | 146 // Wrappers for scripts are kept alive and cached in weak global |
| 147 // handles referred from foreign objects held by the scripts as long as | 147 // handles referred from foreign objects held by the scripts as long as |
| 148 // they are used. When they are not used anymore, the garbage | 148 // they are used. When they are not used anymore, the garbage |
| (...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 419 static bool ContainsOnlyValidKeys(Handle<FixedArray> array) { | 419 static bool ContainsOnlyValidKeys(Handle<FixedArray> array) { |
| 420 int len = array->length(); | 420 int len = array->length(); |
| 421 for (int i = 0; i < len; i++) { | 421 for (int i = 0; i < len; i++) { |
| 422 Object* e = array->get(i); | 422 Object* e = array->get(i); |
| 423 if (!(e->IsString() || e->IsNumber())) return false; | 423 if (!(e->IsString() || e->IsNumber())) return false; |
| 424 } | 424 } |
| 425 return true; | 425 return true; |
| 426 } | 426 } |
| 427 | 427 |
| 428 | 428 |
| 429 Handle<FixedArray> GetKeysInFixedArrayFor(Handle<JSReceiver> object, | 429 MaybeHandle<FixedArray> GetKeysInFixedArrayFor(Handle<JSReceiver> object, |
| 430 KeyCollectionType type, | 430 KeyCollectionType type) { |
| 431 bool* threw) { | |
| 432 USE(ContainsOnlyValidKeys); | 431 USE(ContainsOnlyValidKeys); |
| 433 Isolate* isolate = object->GetIsolate(); | 432 Isolate* isolate = object->GetIsolate(); |
| 434 Handle<FixedArray> content = isolate->factory()->empty_fixed_array(); | 433 Handle<FixedArray> content = isolate->factory()->empty_fixed_array(); |
| 435 Handle<JSObject> arguments_boilerplate = Handle<JSObject>( | 434 Handle<JSObject> arguments_boilerplate = Handle<JSObject>( |
| 436 isolate->context()->native_context()->sloppy_arguments_boilerplate(), | 435 isolate->context()->native_context()->sloppy_arguments_boilerplate(), |
| 437 isolate); | 436 isolate); |
| 438 Handle<JSFunction> arguments_function = Handle<JSFunction>( | 437 Handle<JSFunction> arguments_function = Handle<JSFunction>( |
| 439 JSFunction::cast(arguments_boilerplate->map()->constructor()), | 438 JSFunction::cast(arguments_boilerplate->map()->constructor()), |
| 440 isolate); | 439 isolate); |
| 441 | 440 |
| 442 // Only collect keys if access is permitted. | 441 // Only collect keys if access is permitted. |
| 443 for (Handle<Object> p = object; | 442 for (Handle<Object> p = object; |
| 444 *p != isolate->heap()->null_value(); | 443 *p != isolate->heap()->null_value(); |
| 445 p = Handle<Object>(p->GetPrototype(isolate), isolate)) { | 444 p = Handle<Object>(p->GetPrototype(isolate), isolate)) { |
| 446 if (p->IsJSProxy()) { | 445 if (p->IsJSProxy()) { |
| 447 Handle<JSProxy> proxy(JSProxy::cast(*p), isolate); | 446 Handle<JSProxy> proxy(JSProxy::cast(*p), isolate); |
| 448 Handle<Object> args[] = { proxy }; | 447 Handle<Object> args[] = { proxy }; |
| 448 bool has_pending_exception; |
| 449 Handle<Object> names = Execution::Call(isolate, | 449 Handle<Object> names = Execution::Call(isolate, |
| 450 isolate->proxy_enumerate(), | 450 isolate->proxy_enumerate(), |
| 451 object, | 451 object, |
| 452 ARRAY_SIZE(args), | 452 ARRAY_SIZE(args), |
| 453 args, | 453 args, |
| 454 threw); | 454 &has_pending_exception); |
| 455 if (*threw) return content; | 455 if (has_pending_exception) return MaybeHandle<FixedArray>(); |
| 456 content = FixedArray::AddKeysFromJSArray(content, | 456 ASSIGN_RETURN_ON_EXCEPTION( |
| 457 Handle<JSArray>::cast(names)); | 457 isolate, content, |
| 458 FixedArray::AddKeysFromJSArray(content, Handle<JSArray>::cast(names)), |
| 459 FixedArray); |
| 458 break; | 460 break; |
| 459 } | 461 } |
| 460 | 462 |
| 461 Handle<JSObject> current(JSObject::cast(*p), isolate); | 463 Handle<JSObject> current(JSObject::cast(*p), isolate); |
| 462 | 464 |
| 463 // Check access rights if required. | 465 // Check access rights if required. |
| 464 if (current->IsAccessCheckNeeded() && | 466 if (current->IsAccessCheckNeeded() && |
| 465 !isolate->MayNamedAccessWrapper(current, | 467 !isolate->MayNamedAccessWrapper(current, |
| 466 isolate->factory()->undefined_value(), | 468 isolate->factory()->undefined_value(), |
| 467 v8::ACCESS_KEYS)) { | 469 v8::ACCESS_KEYS)) { |
| 468 isolate->ReportFailedAccessCheckWrapper(current, v8::ACCESS_KEYS); | 470 isolate->ReportFailedAccessCheckWrapper(current, v8::ACCESS_KEYS); |
| 469 if (isolate->has_scheduled_exception()) { | 471 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, FixedArray); |
| 470 isolate->PromoteScheduledException(); | |
| 471 *threw = true; | |
| 472 } | |
| 473 break; | 472 break; |
| 474 } | 473 } |
| 475 | 474 |
| 476 // Compute the element keys. | 475 // Compute the element keys. |
| 477 Handle<FixedArray> element_keys = | 476 Handle<FixedArray> element_keys = |
| 478 isolate->factory()->NewFixedArray(current->NumberOfEnumElements()); | 477 isolate->factory()->NewFixedArray(current->NumberOfEnumElements()); |
| 479 current->GetEnumElementKeys(*element_keys); | 478 current->GetEnumElementKeys(*element_keys); |
| 480 content = FixedArray::UnionOfKeys(content, element_keys); | 479 ASSIGN_RETURN_ON_EXCEPTION( |
| 480 isolate, content, |
| 481 FixedArray::UnionOfKeys(content, element_keys), |
| 482 FixedArray); |
| 481 ASSERT(ContainsOnlyValidKeys(content)); | 483 ASSERT(ContainsOnlyValidKeys(content)); |
| 482 | 484 |
| 483 // Add the element keys from the interceptor. | 485 // Add the element keys from the interceptor. |
| 484 if (current->HasIndexedInterceptor()) { | 486 if (current->HasIndexedInterceptor()) { |
| 485 v8::Handle<v8::Array> result = | 487 v8::Handle<v8::Array> result = |
| 486 GetKeysForIndexedInterceptor(object, current); | 488 GetKeysForIndexedInterceptor(object, current); |
| 487 if (!result.IsEmpty()) | 489 if (!result.IsEmpty()) { |
| 488 content = FixedArray::AddKeysFromJSArray( | 490 ASSIGN_RETURN_ON_EXCEPTION( |
| 489 content, v8::Utils::OpenHandle(*result)); | 491 isolate, content, |
| 492 FixedArray::AddKeysFromJSArray( |
| 493 content, v8::Utils::OpenHandle(*result)), |
| 494 FixedArray); |
| 495 } |
| 490 ASSERT(ContainsOnlyValidKeys(content)); | 496 ASSERT(ContainsOnlyValidKeys(content)); |
| 491 } | 497 } |
| 492 | 498 |
| 493 // We can cache the computed property keys if access checks are | 499 // We can cache the computed property keys if access checks are |
| 494 // not needed and no interceptors are involved. | 500 // not needed and no interceptors are involved. |
| 495 // | 501 // |
| 496 // We do not use the cache if the object has elements and | 502 // We do not use the cache if the object has elements and |
| 497 // therefore it does not make sense to cache the property names | 503 // therefore it does not make sense to cache the property names |
| 498 // for arguments objects. Arguments objects will always have | 504 // for arguments objects. Arguments objects will always have |
| 499 // elements. | 505 // elements. |
| 500 // Wrapped strings have elements, but don't have an elements | 506 // Wrapped strings have elements, but don't have an elements |
| 501 // array or dictionary. So the fast inline test for whether to | 507 // array or dictionary. So the fast inline test for whether to |
| 502 // use the cache says yes, so we should not create a cache. | 508 // use the cache says yes, so we should not create a cache. |
| 503 bool cache_enum_keys = | 509 bool cache_enum_keys = |
| 504 ((current->map()->constructor() != *arguments_function) && | 510 ((current->map()->constructor() != *arguments_function) && |
| 505 !current->IsJSValue() && | 511 !current->IsJSValue() && |
| 506 !current->IsAccessCheckNeeded() && | 512 !current->IsAccessCheckNeeded() && |
| 507 !current->HasNamedInterceptor() && | 513 !current->HasNamedInterceptor() && |
| 508 !current->HasIndexedInterceptor()); | 514 !current->HasIndexedInterceptor()); |
| 509 // Compute the property keys and cache them if possible. | 515 // Compute the property keys and cache them if possible. |
| 510 content = FixedArray::UnionOfKeys( | 516 ASSIGN_RETURN_ON_EXCEPTION( |
| 511 content, GetEnumPropertyKeys(current, cache_enum_keys)); | 517 isolate, content, |
| 518 FixedArray::UnionOfKeys( |
| 519 content, GetEnumPropertyKeys(current, cache_enum_keys)), |
| 520 FixedArray); |
| 512 ASSERT(ContainsOnlyValidKeys(content)); | 521 ASSERT(ContainsOnlyValidKeys(content)); |
| 513 | 522 |
| 514 // Add the property keys from the interceptor. | 523 // Add the property keys from the interceptor. |
| 515 if (current->HasNamedInterceptor()) { | 524 if (current->HasNamedInterceptor()) { |
| 516 v8::Handle<v8::Array> result = | 525 v8::Handle<v8::Array> result = |
| 517 GetKeysForNamedInterceptor(object, current); | 526 GetKeysForNamedInterceptor(object, current); |
| 518 if (!result.IsEmpty()) | 527 if (!result.IsEmpty()) { |
| 519 content = FixedArray::AddKeysFromJSArray( | 528 ASSIGN_RETURN_ON_EXCEPTION( |
| 520 content, v8::Utils::OpenHandle(*result)); | 529 isolate, content, |
| 530 FixedArray::AddKeysFromJSArray( |
| 531 content, v8::Utils::OpenHandle(*result)), |
| 532 FixedArray); |
| 533 } |
| 521 ASSERT(ContainsOnlyValidKeys(content)); | 534 ASSERT(ContainsOnlyValidKeys(content)); |
| 522 } | 535 } |
| 523 | 536 |
| 524 // If we only want local properties we bail out after the first | 537 // If we only want local properties we bail out after the first |
| 525 // iteration. | 538 // iteration. |
| 526 if (type == LOCAL_ONLY) | 539 if (type == LOCAL_ONLY) |
| 527 break; | 540 break; |
| 528 } | 541 } |
| 529 return content; | 542 return content; |
| 530 } | 543 } |
| 531 | 544 |
| 532 | 545 |
| 533 Handle<JSArray> GetKeysFor(Handle<JSReceiver> object, bool* threw) { | 546 MaybeHandle<JSArray> GetKeysFor(Handle<JSReceiver> object) { |
| 534 Isolate* isolate = object->GetIsolate(); | 547 Isolate* isolate = object->GetIsolate(); |
| 535 isolate->counters()->for_in()->Increment(); | 548 isolate->counters()->for_in()->Increment(); |
| 536 Handle<FixedArray> elements = | 549 Handle<FixedArray> elements; |
| 537 GetKeysInFixedArrayFor(object, INCLUDE_PROTOS, threw); | 550 ASSIGN_RETURN_ON_EXCEPTION( |
| 551 isolate, elements, |
| 552 GetKeysInFixedArrayFor(object, INCLUDE_PROTOS), |
| 553 JSArray); |
| 538 return isolate->factory()->NewJSArrayWithElements(elements); | 554 return isolate->factory()->NewJSArrayWithElements(elements); |
| 539 } | 555 } |
| 540 | 556 |
| 541 | 557 |
| 542 Handle<FixedArray> ReduceFixedArrayTo(Handle<FixedArray> array, int length) { | 558 Handle<FixedArray> ReduceFixedArrayTo(Handle<FixedArray> array, int length) { |
| 543 ASSERT(array->length() >= length); | 559 ASSERT(array->length() >= length); |
| 544 if (array->length() == length) return array; | 560 if (array->length() == length) return array; |
| 545 | 561 |
| 546 Handle<FixedArray> new_array = | 562 Handle<FixedArray> new_array = |
| 547 array->GetIsolate()->factory()->NewFixedArray(length); | 563 array->GetIsolate()->factory()->NewFixedArray(length); |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 698 Handle<Code> code) { | 714 Handle<Code> code) { |
| 699 heap->EnsureWeakObjectToCodeTable(); | 715 heap->EnsureWeakObjectToCodeTable(); |
| 700 Handle<DependentCode> dep(heap->LookupWeakObjectToCodeDependency(*object)); | 716 Handle<DependentCode> dep(heap->LookupWeakObjectToCodeDependency(*object)); |
| 701 dep = DependentCode::Insert(dep, DependentCode::kWeaklyEmbeddedGroup, code); | 717 dep = DependentCode::Insert(dep, DependentCode::kWeaklyEmbeddedGroup, code); |
| 702 CALL_HEAP_FUNCTION_VOID(heap->isolate(), | 718 CALL_HEAP_FUNCTION_VOID(heap->isolate(), |
| 703 heap->AddWeakObjectToCodeDependency(*object, *dep)); | 719 heap->AddWeakObjectToCodeDependency(*object, *dep)); |
| 704 } | 720 } |
| 705 | 721 |
| 706 | 722 |
| 707 } } // namespace v8::internal | 723 } } // namespace v8::internal |
| OLD | NEW |