Revision f230a1cf deps/v8/src/runtime.cc
deps/v8/src/runtime.cc | ||
---|---|---|
31 | 31 |
#include "v8.h" |
32 | 32 |
|
33 | 33 |
#include "accessors.h" |
34 |
#include "allocation-site-scopes.h" |
|
34 | 35 |
#include "api.h" |
35 | 36 |
#include "arguments.h" |
36 | 37 |
#include "bootstrapper.h" |
... | ... | |
348 | 349 |
ElementsKind from_kind = |
349 | 350 |
Handle<JSObject>::cast(object)->map()->elements_kind(); |
350 | 351 |
if (Map::IsValidElementsTransition(from_kind, to_kind)) { |
351 |
Handle<Object> result = JSObject::TransitionElementsKind( |
|
352 |
Handle<JSObject>::cast(object), to_kind); |
|
353 |
if (result.is_null()) return isolate->ThrowIllegalOperation(); |
|
354 |
return *result; |
|
352 |
JSObject::TransitionElementsKind(Handle<JSObject>::cast(object), to_kind); |
|
353 |
return *object; |
|
355 | 354 |
} |
356 | 355 |
return isolate->ThrowIllegalOperation(); |
357 | 356 |
} |
... | ... | |
488 | 487 |
bool has_function_literal = (flags & ObjectLiteral::kHasFunction) != 0; |
489 | 488 |
|
490 | 489 |
// Check if boilerplate exists. If not, create it first. |
491 |
Handle<Object> boilerplate(literals->get(literals_index), isolate); |
|
492 |
if (*boilerplate == isolate->heap()->undefined_value()) { |
|
493 |
boilerplate = CreateObjectLiteralBoilerplate(isolate, |
|
494 |
literals, |
|
495 |
constant_properties, |
|
496 |
should_have_fast_elements, |
|
497 |
has_function_literal); |
|
498 |
RETURN_IF_EMPTY_HANDLE(isolate, boilerplate); |
|
499 |
// Update the functions literal and return the boilerplate. |
|
500 |
literals->set(literals_index, *boilerplate); |
|
501 |
} |
|
502 |
return JSObject::cast(*boilerplate)->DeepCopy(isolate); |
|
503 |
} |
|
504 |
|
|
505 |
|
|
506 |
RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateObjectLiteralShallow) { |
|
507 |
HandleScope scope(isolate); |
|
508 |
ASSERT(args.length() == 4); |
|
509 |
CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0); |
|
510 |
CONVERT_SMI_ARG_CHECKED(literals_index, 1); |
|
511 |
CONVERT_ARG_HANDLE_CHECKED(FixedArray, constant_properties, 2); |
|
512 |
CONVERT_SMI_ARG_CHECKED(flags, 3); |
|
513 |
bool should_have_fast_elements = (flags & ObjectLiteral::kFastElements) != 0; |
|
514 |
bool has_function_literal = (flags & ObjectLiteral::kHasFunction) != 0; |
|
490 |
Handle<Object> literal_site(literals->get(literals_index), isolate); |
|
491 |
Handle<AllocationSite> site; |
|
492 |
Handle<JSObject> boilerplate; |
|
493 |
if (*literal_site == isolate->heap()->undefined_value()) { |
|
494 |
Handle<Object> raw_boilerplate = CreateObjectLiteralBoilerplate( |
|
495 |
isolate, |
|
496 |
literals, |
|
497 |
constant_properties, |
|
498 |
should_have_fast_elements, |
|
499 |
has_function_literal); |
|
500 |
RETURN_IF_EMPTY_HANDLE(isolate, raw_boilerplate); |
|
501 |
boilerplate = Handle<JSObject>::cast(raw_boilerplate); |
|
502 |
|
|
503 |
AllocationSiteCreationContext creation_context(isolate); |
|
504 |
site = creation_context.EnterNewScope(); |
|
505 |
RETURN_IF_EMPTY_HANDLE(isolate, |
|
506 |
JSObject::DeepWalk(boilerplate, &creation_context)); |
|
507 |
creation_context.ExitScope(site, boilerplate); |
|
515 | 508 |
|
516 |
// Check if boilerplate exists. If not, create it first. |
|
517 |
Handle<Object> boilerplate(literals->get(literals_index), isolate); |
|
518 |
if (*boilerplate == isolate->heap()->undefined_value()) { |
|
519 |
boilerplate = CreateObjectLiteralBoilerplate(isolate, |
|
520 |
literals, |
|
521 |
constant_properties, |
|
522 |
should_have_fast_elements, |
|
523 |
has_function_literal); |
|
524 |
RETURN_IF_EMPTY_HANDLE(isolate, boilerplate); |
|
525 | 509 |
// Update the functions literal and return the boilerplate. |
526 |
literals->set(literals_index, *boilerplate); |
|
510 |
literals->set(literals_index, *site); |
|
511 |
} else { |
|
512 |
site = Handle<AllocationSite>::cast(literal_site); |
|
513 |
boilerplate = Handle<JSObject>(JSObject::cast(site->transition_info()), |
|
514 |
isolate); |
|
527 | 515 |
} |
528 |
return isolate->heap()->CopyJSObject(JSObject::cast(*boilerplate)); |
|
516 |
|
|
517 |
AllocationSiteUsageContext usage_context(isolate, site, true); |
|
518 |
usage_context.EnterNewScope(); |
|
519 |
Handle<Object> copy = JSObject::DeepCopy(boilerplate, &usage_context); |
|
520 |
usage_context.ExitScope(site, boilerplate); |
|
521 |
RETURN_IF_EMPTY_HANDLE(isolate, copy); |
|
522 |
return *copy; |
|
529 | 523 |
} |
530 | 524 |
|
531 | 525 |
|
... | ... | |
541 | 535 |
ASSERT(*elements != isolate->heap()->empty_fixed_array()); |
542 | 536 |
Handle<Object> boilerplate = |
543 | 537 |
Runtime::CreateArrayLiteralBoilerplate(isolate, literals, elements); |
544 |
if (boilerplate.is_null()) return site; |
|
545 |
site = isolate->factory()->NewAllocationSite(); |
|
546 |
site->set_transition_info(*boilerplate); |
|
538 |
if (boilerplate.is_null()) return Handle<AllocationSite>::null(); |
|
539 |
|
|
540 |
AllocationSiteCreationContext creation_context(isolate); |
|
541 |
site = creation_context.EnterNewScope(); |
|
542 |
if (JSObject::DeepWalk(Handle<JSObject>::cast(boilerplate), |
|
543 |
&creation_context).is_null()) { |
|
544 |
return Handle<AllocationSite>::null(); |
|
545 |
} |
|
546 |
creation_context.ExitScope(site, Handle<JSObject>::cast(boilerplate)); |
|
547 |
|
|
547 | 548 |
literals->set(literals_index, *site); |
548 | 549 |
} else { |
549 | 550 |
site = Handle<AllocationSite>::cast(literal_site); |
... | ... | |
564 | 565 |
literals_index, elements); |
565 | 566 |
RETURN_IF_EMPTY_HANDLE(isolate, site); |
566 | 567 |
|
567 |
JSObject* boilerplate = JSObject::cast(site->transition_info()); |
|
568 |
return boilerplate->DeepCopy(isolate); |
|
568 |
Handle<JSObject> boilerplate(JSObject::cast(site->transition_info())); |
|
569 |
AllocationSiteUsageContext usage_context(isolate, site, true); |
|
570 |
usage_context.EnterNewScope(); |
|
571 |
Handle<JSObject> copy = JSObject::DeepCopy(boilerplate, &usage_context); |
|
572 |
usage_context.ExitScope(site, boilerplate); |
|
573 |
RETURN_IF_EMPTY_HANDLE(isolate, copy); |
|
574 |
return *copy; |
|
569 | 575 |
} |
570 | 576 |
|
571 | 577 |
|
... | ... | |
586 | 592 |
isolate->counters()->cow_arrays_created_runtime()->Increment(); |
587 | 593 |
} |
588 | 594 |
|
589 |
AllocationSiteMode mode = AllocationSite::GetMode( |
|
590 |
boilerplate->GetElementsKind()); |
|
591 |
if (mode == TRACK_ALLOCATION_SITE) { |
|
592 |
return isolate->heap()->CopyJSObjectWithAllocationSite( |
|
593 |
boilerplate, *site); |
|
595 |
if (AllocationSite::GetMode(boilerplate->GetElementsKind()) == |
|
596 |
TRACK_ALLOCATION_SITE) { |
|
597 |
return isolate->heap()->CopyJSObject(boilerplate, *site); |
|
594 | 598 |
} |
595 | 599 |
|
596 | 600 |
return isolate->heap()->CopyJSObject(boilerplate); |
... | ... | |
822 | 826 |
} |
823 | 827 |
|
824 | 828 |
|
829 |
RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferIsView) { |
|
830 |
HandleScope scope(isolate); |
|
831 |
ASSERT(args.length() == 1); |
|
832 |
CONVERT_ARG_CHECKED(Object, object, 0); |
|
833 |
return object->IsJSArrayBufferView() |
|
834 |
? isolate->heap()->true_value() |
|
835 |
: isolate->heap()->false_value(); |
|
836 |
} |
|
837 |
|
|
838 |
|
|
825 | 839 |
enum TypedArrayId { |
826 | 840 |
// arrayIds below should be synchromized with typedarray.js natives. |
827 | 841 |
ARRAY_ID_UINT8 = 1, |
... | ... | |
954 | 968 |
HandleVector<Object>(NULL, 0))); |
955 | 969 |
} |
956 | 970 |
|
971 |
// NOTE: not initializing backing store. |
|
957 | 972 |
// We assume that the caller of this function will initialize holder |
958 | 973 |
// with the loop |
959 | 974 |
// for(i = 0; i < length; i++) { holder[i] = source[i]; } |
975 |
// We assume that the caller of this function is always a typed array |
|
976 |
// constructor. |
|
960 | 977 |
// If source is a typed array, this loop will always run to completion, |
961 | 978 |
// so we are sure that the backing store will be initialized. |
962 |
// Otherwise, we do not know (the indexing operation might throw). |
|
963 |
// Hence we require zero initialization unless our source is a typed array. |
|
964 |
bool should_zero_initialize = !source->IsJSTypedArray(); |
|
979 |
// Otherwise, the indexing operation might throw, so the loop will not |
|
980 |
// run to completion and the typed array might remain partly initialized. |
|
981 |
// However we further assume that the caller of this function is a typed array |
|
982 |
// constructor, and the exception will propagate out of the constructor, |
|
983 |
// therefore uninitialized memory will not be accessible by a user program. |
|
984 |
// |
|
985 |
// TODO(dslomov): revise this once we support subclassing. |
|
965 | 986 |
|
966 | 987 |
if (!Runtime::SetupArrayBufferAllocatingData( |
967 |
isolate, buffer, byte_length, should_zero_initialize)) {
|
|
988 |
isolate, buffer, byte_length, false)) {
|
|
968 | 989 |
return isolate->Throw(*isolate->factory()-> |
969 | 990 |
NewRangeError("invalid_array_buffer_length", |
970 | 991 |
HandleVector<Object>(NULL, 0))); |
... | ... | |
1578 | 1599 |
|
1579 | 1600 |
|
1580 | 1601 |
RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPrototype) { |
1581 |
SealHandleScope shs(isolate);
|
|
1602 |
HandleScope scope(isolate);
|
|
1582 | 1603 |
ASSERT(args.length() == 1); |
1583 |
CONVERT_ARG_CHECKED(Object, obj, 0); |
|
1604 |
CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0);
|
|
1584 | 1605 |
// We don't expect access checks to be needed on JSProxy objects. |
1585 | 1606 |
ASSERT(!obj->IsAccessCheckNeeded() || obj->IsJSObject()); |
1586 | 1607 |
do { |
1587 | 1608 |
if (obj->IsAccessCheckNeeded() && |
1588 |
!isolate->MayNamedAccess(JSObject::cast(obj),
|
|
1589 |
isolate->heap()->proto_string(),
|
|
1590 |
v8::ACCESS_GET)) { |
|
1591 |
isolate->ReportFailedAccessCheck(JSObject::cast(obj), v8::ACCESS_GET); |
|
1609 |
!isolate->MayNamedAccessWrapper(Handle<JSObject>::cast(obj),
|
|
1610 |
isolate->factory()->proto_string(),
|
|
1611 |
v8::ACCESS_GET)) {
|
|
1612 |
isolate->ReportFailedAccessCheck(JSObject::cast(*obj), v8::ACCESS_GET);
|
|
1592 | 1613 |
RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
1593 | 1614 |
return isolate->heap()->undefined_value(); |
1594 | 1615 |
} |
1595 |
obj = obj->GetPrototype(isolate);
|
|
1616 |
obj = handle(obj->GetPrototype(isolate), isolate);
|
|
1596 | 1617 |
} while (obj->IsJSObject() && |
1597 |
JSObject::cast(obj)->map()->is_hidden_prototype()); |
|
1598 |
return obj; |
|
1618 |
JSObject::cast(*obj)->map()->is_hidden_prototype());
|
|
1619 |
return *obj;
|
|
1599 | 1620 |
} |
1600 | 1621 |
|
1601 | 1622 |
|
... | ... | |
1654 | 1675 |
|
1655 | 1676 |
static bool CheckAccessException(Object* callback, |
1656 | 1677 |
v8::AccessType access_type) { |
1678 |
DisallowHeapAllocation no_gc; |
|
1657 | 1679 |
if (callback->IsAccessorInfo()) { |
1658 | 1680 |
AccessorInfo* info = AccessorInfo::cast(callback); |
1659 | 1681 |
return |
... | ... | |
1676 | 1698 |
|
1677 | 1699 |
template<class Key> |
1678 | 1700 |
static bool CheckGenericAccess( |
1679 |
JSObject* receiver,
|
|
1680 |
JSObject* holder,
|
|
1701 |
Handle<JSObject> receiver,
|
|
1702 |
Handle<JSObject> holder,
|
|
1681 | 1703 |
Key key, |
1682 | 1704 |
v8::AccessType access_type, |
1683 |
bool (Isolate::*mayAccess)(JSObject*, Key, v8::AccessType)) {
|
|
1705 |
bool (Isolate::*mayAccess)(Handle<JSObject>, Key, v8::AccessType)) {
|
|
1684 | 1706 |
Isolate* isolate = receiver->GetIsolate(); |
1685 |
for (JSObject* current = receiver;
|
|
1707 |
for (Handle<JSObject> current = receiver;
|
|
1686 | 1708 |
true; |
1687 |
current = JSObject::cast(current->GetPrototype())) {
|
|
1709 |
current = handle(JSObject::cast(current->GetPrototype()), isolate)) {
|
|
1688 | 1710 |
if (current->IsAccessCheckNeeded() && |
1689 | 1711 |
!(isolate->*mayAccess)(current, key, access_type)) { |
1690 | 1712 |
return false; |
1691 | 1713 |
} |
1692 |
if (current == holder) break;
|
|
1714 |
if (current.is_identical_to(holder)) break;
|
|
1693 | 1715 |
} |
1694 | 1716 |
return true; |
1695 | 1717 |
} |
... | ... | |
1702 | 1724 |
}; |
1703 | 1725 |
|
1704 | 1726 |
|
1705 |
static AccessCheckResult CheckPropertyAccess( |
|
1706 |
JSObject* obj, |
|
1707 |
Name* name, |
|
1708 |
v8::AccessType access_type) { |
|
1727 |
static AccessCheckResult CheckPropertyAccess(Handle<JSObject> obj, |
|
1728 |
Handle<Name> name, |
|
1729 |
v8::AccessType access_type) { |
|
1709 | 1730 |
uint32_t index; |
1710 | 1731 |
if (name->AsArrayIndex(&index)) { |
1711 | 1732 |
// TODO(1095): we should traverse hidden prototype hierachy as well. |
1712 | 1733 |
if (CheckGenericAccess( |
1713 |
obj, obj, index, access_type, &Isolate::MayIndexedAccess)) { |
|
1734 |
obj, obj, index, access_type, &Isolate::MayIndexedAccessWrapper)) {
|
|
1714 | 1735 |
return ACCESS_ALLOWED; |
1715 | 1736 |
} |
1716 | 1737 |
|
1717 |
obj->GetIsolate()->ReportFailedAccessCheck(obj, access_type); |
|
1738 |
obj->GetIsolate()->ReportFailedAccessCheck(*obj, access_type);
|
|
1718 | 1739 |
return ACCESS_FORBIDDEN; |
1719 | 1740 |
} |
1720 | 1741 |
|
1721 |
LookupResult lookup(obj->GetIsolate()); |
|
1722 |
obj->LocalLookup(name, &lookup, true); |
|
1742 |
Isolate* isolate = obj->GetIsolate(); |
|
1743 |
LookupResult lookup(isolate); |
|
1744 |
obj->LocalLookup(*name, &lookup, true); |
|
1723 | 1745 |
|
1724 | 1746 |
if (!lookup.IsProperty()) return ACCESS_ABSENT; |
1725 |
if (CheckGenericAccess<Object*>( |
|
1726 |
obj, lookup.holder(), name, access_type, &Isolate::MayNamedAccess)) { |
|
1747 |
Handle<JSObject> holder(lookup.holder(), isolate); |
|
1748 |
if (CheckGenericAccess<Handle<Object> >( |
|
1749 |
obj, holder, name, access_type, &Isolate::MayNamedAccessWrapper)) { |
|
1727 | 1750 |
return ACCESS_ALLOWED; |
1728 | 1751 |
} |
1729 | 1752 |
|
... | ... | |
1740 | 1763 |
case INTERCEPTOR: |
1741 | 1764 |
// If the object has an interceptor, try real named properties. |
1742 | 1765 |
// Overwrite the result to fetch the correct property later. |
1743 |
lookup.holder()->LookupRealNamedProperty(name, &lookup);
|
|
1766 |
holder->LookupRealNamedProperty(*name, &lookup);
|
|
1744 | 1767 |
if (lookup.IsProperty() && lookup.IsPropertyCallbacks()) { |
1745 | 1768 |
if (CheckAccessException(lookup.GetCallbackObject(), access_type)) { |
1746 | 1769 |
return ACCESS_ALLOWED; |
... | ... | |
1751 | 1774 |
break; |
1752 | 1775 |
} |
1753 | 1776 |
|
1754 |
obj->GetIsolate()->ReportFailedAccessCheck(obj, access_type);
|
|
1777 |
isolate->ReportFailedAccessCheck(*obj, access_type);
|
|
1755 | 1778 |
return ACCESS_FORBIDDEN; |
1756 | 1779 |
} |
1757 | 1780 |
|
... | ... | |
1769 | 1792 |
}; |
1770 | 1793 |
|
1771 | 1794 |
|
1772 |
static MaybeObject* GetOwnProperty(Isolate* isolate,
|
|
1773 |
Handle<JSObject> obj, |
|
1774 |
Handle<Name> name) { |
|
1795 |
static Handle<Object> GetOwnProperty(Isolate* isolate,
|
|
1796 |
Handle<JSObject> obj,
|
|
1797 |
Handle<Name> name) {
|
|
1775 | 1798 |
Heap* heap = isolate->heap(); |
1799 |
Factory* factory = isolate->factory(); |
|
1776 | 1800 |
// Due to some WebKit tests, we want to make sure that we do not log |
1777 | 1801 |
// more than one access failure here. |
1778 | 1802 |
AccessCheckResult access_check_result = |
1779 |
CheckPropertyAccess(*obj, *name, v8::ACCESS_HAS);
|
|
1780 |
RETURN_IF_SCHEDULED_EXCEPTION(isolate);
|
|
1803 |
CheckPropertyAccess(obj, name, v8::ACCESS_HAS);
|
|
1804 |
RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
|
|
1781 | 1805 |
switch (access_check_result) { |
1782 |
case ACCESS_FORBIDDEN: return heap->false_value();
|
|
1806 |
case ACCESS_FORBIDDEN: return factory->false_value();
|
|
1783 | 1807 |
case ACCESS_ALLOWED: break; |
1784 |
case ACCESS_ABSENT: return heap->undefined_value();
|
|
1808 |
case ACCESS_ABSENT: return factory->undefined_value();
|
|
1785 | 1809 |
} |
1786 | 1810 |
|
1787 | 1811 |
PropertyAttributes attrs = obj->GetLocalPropertyAttribute(*name); |
1788 | 1812 |
if (attrs == ABSENT) { |
1789 |
RETURN_IF_SCHEDULED_EXCEPTION(isolate);
|
|
1790 |
return heap->undefined_value();
|
|
1813 |
RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
|
|
1814 |
return factory->undefined_value();
|
|
1791 | 1815 |
} |
1792 | 1816 |
ASSERT(!isolate->has_scheduled_exception()); |
1793 | 1817 |
AccessorPair* raw_accessors = obj->GetLocalPropertyAccessorPair(*name); |
1794 | 1818 |
Handle<AccessorPair> accessors(raw_accessors, isolate); |
1795 |
|
|
1796 | 1819 |
Handle<FixedArray> elms = isolate->factory()->NewFixedArray(DESCRIPTOR_SIZE); |
1797 | 1820 |
elms->set(ENUMERABLE_INDEX, heap->ToBoolean((attrs & DONT_ENUM) == 0)); |
1798 | 1821 |
elms->set(CONFIGURABLE_INDEX, heap->ToBoolean((attrs & DONT_DELETE) == 0)); |
... | ... | |
1802 | 1825 |
elms->set(WRITABLE_INDEX, heap->ToBoolean((attrs & READ_ONLY) == 0)); |
1803 | 1826 |
// GetProperty does access check. |
1804 | 1827 |
Handle<Object> value = GetProperty(isolate, obj, name); |
1805 |
RETURN_IF_EMPTY_HANDLE(isolate, value);
|
|
1828 |
RETURN_IF_EMPTY_HANDLE_VALUE(isolate, value, Handle<Object>::null());
|
|
1806 | 1829 |
elms->set(VALUE_INDEX, *value); |
1807 | 1830 |
} else { |
1808 | 1831 |
// Access checks are performed for both accessors separately. |
1809 | 1832 |
// When they fail, the respective field is not set in the descriptor. |
1810 |
Object* getter = accessors->GetComponent(ACCESSOR_GETTER); |
|
1811 |
Object* setter = accessors->GetComponent(ACCESSOR_SETTER); |
|
1812 |
if (!getter->IsMap() && CheckPropertyAccess(*obj, *name, v8::ACCESS_GET)) { |
|
1833 |
Handle<Object> getter(accessors->GetComponent(ACCESSOR_GETTER), isolate); |
|
1834 |
Handle<Object> setter(accessors->GetComponent(ACCESSOR_SETTER), isolate); |
|
1835 |
|
|
1836 |
if (!getter->IsMap() && CheckPropertyAccess(obj, name, v8::ACCESS_GET)) { |
|
1813 | 1837 |
ASSERT(!isolate->has_scheduled_exception()); |
1814 |
elms->set(GETTER_INDEX, getter); |
|
1838 |
elms->set(GETTER_INDEX, *getter);
|
|
1815 | 1839 |
} else { |
1816 |
RETURN_IF_SCHEDULED_EXCEPTION(isolate);
|
|
1840 |
RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
|
|
1817 | 1841 |
} |
1818 |
if (!setter->IsMap() && CheckPropertyAccess(*obj, *name, v8::ACCESS_SET)) { |
|
1842 |
|
|
1843 |
if (!setter->IsMap() && CheckPropertyAccess(obj, name, v8::ACCESS_SET)) { |
|
1819 | 1844 |
ASSERT(!isolate->has_scheduled_exception()); |
1820 |
elms->set(SETTER_INDEX, setter); |
|
1845 |
elms->set(SETTER_INDEX, *setter);
|
|
1821 | 1846 |
} else { |
1822 |
RETURN_IF_SCHEDULED_EXCEPTION(isolate);
|
|
1847 |
RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
|
|
1823 | 1848 |
} |
1824 | 1849 |
} |
1825 | 1850 |
|
1826 |
return *isolate->factory()->NewJSArrayWithElements(elms);
|
|
1851 |
return isolate->factory()->NewJSArrayWithElements(elms); |
|
1827 | 1852 |
} |
1828 | 1853 |
|
1829 | 1854 |
|
... | ... | |
1839 | 1864 |
ASSERT(args.length() == 2); |
1840 | 1865 |
CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); |
1841 | 1866 |
CONVERT_ARG_HANDLE_CHECKED(Name, name, 1); |
1842 |
return GetOwnProperty(isolate, obj, name); |
|
1867 |
Handle<Object> result = GetOwnProperty(isolate, obj, name); |
|
1868 |
RETURN_IF_EMPTY_HANDLE(isolate, result); |
|
1869 |
return *result; |
|
1843 | 1870 |
} |
1844 | 1871 |
|
1845 | 1872 |
|
1846 | 1873 |
RUNTIME_FUNCTION(MaybeObject*, Runtime_PreventExtensions) { |
1847 |
SealHandleScope shs(isolate);
|
|
1874 |
HandleScope scope(isolate);
|
|
1848 | 1875 |
ASSERT(args.length() == 1); |
1849 |
CONVERT_ARG_CHECKED(JSObject, obj, 0); |
|
1850 |
return obj->PreventExtensions(); |
|
1876 |
CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); |
|
1877 |
Handle<Object> result = JSObject::PreventExtensions(obj); |
|
1878 |
RETURN_IF_EMPTY_HANDLE(isolate, result); |
|
1879 |
return *result; |
|
1851 | 1880 |
} |
1852 | 1881 |
|
1853 | 1882 |
|
... | ... | |
1871 | 1900 |
CONVERT_ARG_HANDLE_CHECKED(JSRegExp, re, 0); |
1872 | 1901 |
CONVERT_ARG_HANDLE_CHECKED(String, pattern, 1); |
1873 | 1902 |
CONVERT_ARG_HANDLE_CHECKED(String, flags, 2); |
1874 |
Handle<Object> result = |
|
1875 |
RegExpImpl::Compile(re, pattern, flags); |
|
1903 |
Handle<Object> result = RegExpImpl::Compile(re, pattern, flags); |
|
1876 | 1904 |
RETURN_IF_EMPTY_HANDLE(isolate, result); |
1877 | 1905 |
return *result; |
1878 | 1906 |
} |
... | ... | |
2164 | 2192 |
// Declare the property by setting it to the initial value if provided, |
2165 | 2193 |
// or undefined, and use the correct mode (e.g. READ_ONLY attribute for |
2166 | 2194 |
// constant declarations). |
2167 |
ASSERT(!object->HasLocalProperty(*name));
|
|
2195 |
ASSERT(!JSReceiver::HasLocalProperty(object, name));
|
|
2168 | 2196 |
Handle<Object> value(isolate->heap()->undefined_value(), isolate); |
2169 | 2197 |
if (*initial_value != NULL) value = initial_value; |
2170 | 2198 |
// Declaring a const context slot is a conflicting declaration if |
... | ... | |
2196 | 2224 |
|
2197 | 2225 |
|
2198 | 2226 |
RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) { |
2199 |
SealHandleScope shs(isolate);
|
|
2227 |
HandleScope scope(isolate);
|
|
2200 | 2228 |
// args[0] == name |
2201 | 2229 |
// args[1] == language_mode |
2202 | 2230 |
// args[2] == value (optional) |
... | ... | |
2207 | 2235 |
bool assign = args.length() == 3; |
2208 | 2236 |
|
2209 | 2237 |
CONVERT_ARG_HANDLE_CHECKED(String, name, 0); |
2210 |
GlobalObject* global = isolate->context()->global_object(); |
|
2211 | 2238 |
RUNTIME_ASSERT(args[1]->IsSmi()); |
2212 | 2239 |
CONVERT_LANGUAGE_MODE_ARG(language_mode, 1); |
2213 | 2240 |
StrictModeFlag strict_mode_flag = (language_mode == CLASSIC_MODE) |
... | ... | |
2224 | 2251 |
// to assign to the property. |
2225 | 2252 |
// Note that objects can have hidden prototypes, so we need to traverse |
2226 | 2253 |
// the whole chain of hidden prototypes to do a 'local' lookup. |
2227 |
Object* object = global; |
|
2228 | 2254 |
LookupResult lookup(isolate); |
2229 |
JSObject::cast(object)->LocalLookup(*name, &lookup, true);
|
|
2255 |
isolate->context()->global_object()->LocalLookup(*name, &lookup, true);
|
|
2230 | 2256 |
if (lookup.IsInterceptor()) { |
2231 |
HandleScope handle_scope(isolate); |
|
2232 | 2257 |
PropertyAttributes intercepted = |
2233 | 2258 |
lookup.holder()->GetPropertyAttribute(*name); |
2234 | 2259 |
if (intercepted != ABSENT && (intercepted & READ_ONLY) == 0) { |
2235 | 2260 |
// Found an interceptor that's not read only. |
2236 | 2261 |
if (assign) { |
2237 |
return lookup.holder()->SetProperty( |
|
2238 |
&lookup, *name, args[2], attributes, strict_mode_flag); |
|
2262 |
CONVERT_ARG_HANDLE_CHECKED(Object, value, 2); |
|
2263 |
Handle<Object> result = JSObject::SetPropertyForResult( |
|
2264 |
handle(lookup.holder()), &lookup, name, value, attributes, |
|
2265 |
strict_mode_flag); |
|
2266 |
RETURN_IF_EMPTY_HANDLE(isolate, result); |
|
2267 |
return *result; |
|
2239 | 2268 |
} else { |
2240 | 2269 |
return isolate->heap()->undefined_value(); |
2241 | 2270 |
} |
2242 | 2271 |
} |
2243 | 2272 |
} |
2244 | 2273 |
|
2245 |
// Reload global in case the loop above performed a GC. |
|
2246 |
global = isolate->context()->global_object(); |
|
2247 | 2274 |
if (assign) { |
2248 |
return global->SetProperty(*name, args[2], attributes, strict_mode_flag); |
|
2275 |
CONVERT_ARG_HANDLE_CHECKED(Object, value, 2); |
|
2276 |
Handle<GlobalObject> global(isolate->context()->global_object()); |
|
2277 |
Handle<Object> result = JSReceiver::SetProperty( |
|
2278 |
global, name, value, attributes, strict_mode_flag); |
|
2279 |
RETURN_IF_EMPTY_HANDLE(isolate, result); |
|
2280 |
return *result; |
|
2249 | 2281 |
} |
2250 | 2282 |
return isolate->heap()->undefined_value(); |
2251 | 2283 |
} |
... | ... | |
2901 | 2933 |
source_shared->set_dont_flush(true); |
2902 | 2934 |
|
2903 | 2935 |
// Set the code, scope info, formal parameter count, and the length |
2904 |
// of the target shared function info. Set the source code of the |
|
2905 |
// target function to undefined. SetCode is only used for built-in |
|
2906 |
// constructors like String, Array, and Object, and some web code |
|
2907 |
// doesn't like seeing source code for constructors. |
|
2936 |
// of the target shared function info. |
|
2908 | 2937 |
target_shared->ReplaceCode(source_shared->code()); |
2909 | 2938 |
target_shared->set_scope_info(source_shared->scope_info()); |
2910 | 2939 |
target_shared->set_length(source_shared->length()); |
2911 | 2940 |
target_shared->set_formal_parameter_count( |
2912 | 2941 |
source_shared->formal_parameter_count()); |
2913 |
target_shared->set_script(isolate->heap()->undefined_value()); |
|
2914 |
|
|
2915 |
// Since we don't store the source we should never optimize this. |
|
2916 |
target_shared->code()->set_optimizable(false); |
|
2942 |
target_shared->set_script(source_shared->script()); |
|
2943 |
target_shared->set_start_position_and_type( |
|
2944 |
source_shared->start_position_and_type()); |
|
2945 |
target_shared->set_end_position(source_shared->end_position()); |
|
2946 |
bool was_native = target_shared->native(); |
|
2947 |
target_shared->set_compiler_hints(source_shared->compiler_hints()); |
|
2948 |
target_shared->set_native(was_native); |
|
2917 | 2949 |
|
2918 | 2950 |
// Set the code of the target function. |
2919 | 2951 |
target->ReplaceCode(source_shared->code()); |
... | ... | |
2945 | 2977 |
RUNTIME_FUNCTION(MaybeObject*, Runtime_SetExpectedNumberOfProperties) { |
2946 | 2978 |
HandleScope scope(isolate); |
2947 | 2979 |
ASSERT(args.length() == 2); |
2948 |
CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
|
|
2980 |
CONVERT_ARG_HANDLE_CHECKED(JSFunction, func, 0); |
|
2949 | 2981 |
CONVERT_SMI_ARG_CHECKED(num, 1); |
2950 | 2982 |
RUNTIME_ASSERT(num >= 0); |
2951 |
SetExpectedNofProperties(function, num); |
|
2983 |
// If objects constructed from this function exist then changing |
|
2984 |
// 'estimated_nof_properties' is dangerous since the previous value might |
|
2985 |
// have been compiled into the fast construct stub. Moreover, the inobject |
|
2986 |
// slack tracking logic might have adjusted the previous value, so even |
|
2987 |
// passing the same value is risky. |
|
2988 |
if (!func->shared()->live_objects_may_exist()) { |
|
2989 |
func->shared()->set_expected_nof_properties(num); |
|
2990 |
if (func->has_initial_map()) { |
|
2991 |
Handle<Map> new_initial_map = |
|
2992 |
func->GetIsolate()->factory()->CopyMap( |
|
2993 |
Handle<Map>(func->initial_map())); |
|
2994 |
new_initial_map->set_unused_property_fields(num); |
|
2995 |
func->set_initial_map(*new_initial_map); |
|
2996 |
} |
|
2997 |
} |
|
2952 | 2998 |
return isolate->heap()->undefined_value(); |
2953 | 2999 |
} |
2954 | 3000 |
|
... | ... | |
3090 | 3136 |
|
3091 | 3137 |
|
3092 | 3138 |
RUNTIME_FUNCTION(MaybeObject*, Runtime_ObjectFreeze) { |
3093 |
SealHandleScope shs(isolate);
|
|
3139 |
HandleScope scope(isolate);
|
|
3094 | 3140 |
ASSERT(args.length() == 1); |
3095 |
CONVERT_ARG_CHECKED(JSObject, object, 0); |
|
3096 |
return object->Freeze(isolate); |
|
3141 |
CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); |
|
3142 |
Handle<Object> result = JSObject::Freeze(object); |
|
3143 |
RETURN_IF_EMPTY_HANDLE(isolate, result); |
|
3144 |
return *result; |
|
3097 | 3145 |
} |
3098 | 3146 |
|
3099 | 3147 |
|
... | ... | |
4778 | 4826 |
// Check if the given key is an array index. |
4779 | 4827 |
uint32_t index; |
4780 | 4828 |
if (key->ToArrayIndex(&index)) { |
4781 |
return isolate->heap()->ToBoolean(object->HasElement(index));
|
|
4829 |
return isolate->heap()->ToBoolean(JSReceiver::HasElement(object, index));
|
|
4782 | 4830 |
} |
4783 | 4831 |
|
4784 | 4832 |
// Convert the key to a name - possibly by calling back into JavaScript. |
... | ... | |
4793 | 4841 |
name = Handle<Name>::cast(converted); |
4794 | 4842 |
} |
4795 | 4843 |
|
4796 |
return isolate->heap()->ToBoolean(object->HasProperty(*name));
|
|
4844 |
return isolate->heap()->ToBoolean(JSReceiver::HasProperty(object, name));
|
|
4797 | 4845 |
} |
4798 | 4846 |
|
4799 | 4847 |
MaybeObject* Runtime::GetObjectPropertyOrFail( |
... | ... | |
5028 | 5076 |
// TODO(mstarzinger): So far this only works if property attributes don't |
5029 | 5077 |
// change, this should be fixed once we cleanup the underlying code. |
5030 | 5078 |
if (callback->IsForeign() && result.GetAttributes() == attr) { |
5031 |
return js_object->SetPropertyWithCallback(callback, |
|
5032 |
*name, |
|
5033 |
*obj_value, |
|
5034 |
result.holder(), |
|
5035 |
kStrictMode); |
|
5079 |
Handle<Object> result_object = |
|
5080 |
JSObject::SetPropertyWithCallback(js_object, |
|
5081 |
handle(callback, isolate), |
|
5082 |
name, |
|
5083 |
obj_value, |
|
5084 |
handle(result.holder()), |
|
5085 |
kStrictMode); |
|
5086 |
RETURN_IF_EMPTY_HANDLE(isolate, result_object); |
|
5087 |
return *result_object; |
|
5036 | 5088 |
} |
5037 | 5089 |
} |
5038 | 5090 |
|
... | ... | |
5128 | 5180 |
|
5129 | 5181 |
if (object->IsJSProxy()) { |
5130 | 5182 |
bool has_pending_exception = false; |
5131 |
Handle<Object> name = key->IsSymbol() |
|
5183 |
Handle<Object> name_object = key->IsSymbol()
|
|
5132 | 5184 |
? key : Execution::ToString(isolate, key, &has_pending_exception); |
5133 | 5185 |
if (has_pending_exception) return Failure::Exception(); |
5134 |
return JSProxy::cast(*object)->SetProperty( |
|
5135 |
Name::cast(*name), *value, attr, strict_mode); |
|
5186 |
Handle<Name> name = Handle<Name>::cast(name_object); |
|
5187 |
Handle<Object> result = JSReceiver::SetProperty( |
|
5188 |
Handle<JSProxy>::cast(object), name, value, attr, strict_mode); |
|
5189 |
RETURN_IF_EMPTY_HANDLE(isolate, result); |
|
5190 |
return *result; |
|
5136 | 5191 |
} |
5137 | 5192 |
|
5138 | 5193 |
// If the object isn't a JavaScript object, we ignore the store. |
... | ... | |
5172 | 5227 |
} |
5173 | 5228 |
|
5174 | 5229 |
if (key->IsName()) { |
5175 |
MaybeObject* result; |
|
5176 | 5230 |
Handle<Name> name = Handle<Name>::cast(key); |
5177 | 5231 |
if (name->AsArrayIndex(&index)) { |
5178 | 5232 |
if (js_object->HasExternalArrayElements()) { |
... | ... | |
5184 | 5238 |
value = number; |
5185 | 5239 |
} |
5186 | 5240 |
} |
5187 |
result = js_object->SetElement( |
|
5241 |
MaybeObject* result = js_object->SetElement(
|
|
5188 | 5242 |
index, *value, attr, strict_mode, true, set_mode); |
5243 |
if (result->IsFailure()) return result; |
|
5189 | 5244 |
} else { |
5190 | 5245 |
if (name->IsString()) Handle<String>::cast(name)->TryFlatten(); |
5191 |
result = js_object->SetProperty(*name, *value, attr, strict_mode); |
|
5246 |
Handle<Object> result = |
|
5247 |
JSReceiver::SetProperty(js_object, name, value, attr, strict_mode); |
|
5248 |
RETURN_IF_EMPTY_HANDLE(isolate, result); |
|
5192 | 5249 |
} |
5193 |
if (result->IsFailure()) return result; |
|
5194 | 5250 |
return *value; |
5195 | 5251 |
} |
5196 | 5252 |
|
... | ... | |
5205 | 5261 |
return js_object->SetElement( |
5206 | 5262 |
index, *value, attr, strict_mode, true, set_mode); |
5207 | 5263 |
} else { |
5208 |
return js_object->SetProperty(*name, *value, attr, strict_mode); |
|
5264 |
Handle<Object> result = |
|
5265 |
JSReceiver::SetProperty(js_object, name, value, attr, strict_mode); |
|
5266 |
RETURN_IF_EMPTY_HANDLE(isolate, result); |
|
5267 |
return *result; |
|
5209 | 5268 |
} |
5210 | 5269 |
} |
5211 | 5270 |
|
... | ... | |
5504 | 5563 |
static MaybeObject* HasLocalPropertyImplementation(Isolate* isolate, |
5505 | 5564 |
Handle<JSObject> object, |
5506 | 5565 |
Handle<Name> key) { |
5507 |
if (object->HasLocalProperty(*key)) return isolate->heap()->true_value(); |
|
5566 |
if (JSReceiver::HasLocalProperty(object, key)) { |
|
5567 |
return isolate->heap()->true_value(); |
|
5568 |
} |
|
5508 | 5569 |
// Handle hidden prototypes. If there's a hidden prototype above this thing |
5509 | 5570 |
// then we have to check it for properties, because they are supposed to |
5510 | 5571 |
// look like they are on this object. |
... | ... | |
5521 | 5582 |
|
5522 | 5583 |
|
5523 | 5584 |
RUNTIME_FUNCTION(MaybeObject*, Runtime_HasLocalProperty) { |
5524 |
SealHandleScope shs(isolate);
|
|
5585 |
HandleScope scope(isolate);
|
|
5525 | 5586 |
ASSERT(args.length() == 2); |
5526 |
CONVERT_ARG_CHECKED(Name, key, 1); |
|
5587 |
CONVERT_ARG_HANDLE_CHECKED(Name, key, 1); |
|
5588 |
Handle<Object> object = args.at<Object>(0); |
|
5527 | 5589 |
|
5528 | 5590 |
uint32_t index; |
5529 | 5591 |
const bool key_is_array_index = key->AsArrayIndex(&index); |
5530 | 5592 |
|
5531 |
Object* obj = args[0]; |
|
5532 | 5593 |
// Only JS objects can have properties. |
5533 |
if (obj->IsJSObject()) { |
|
5534 |
JSObject* object = JSObject::cast(obj);
|
|
5594 |
if (object->IsJSObject()) {
|
|
5595 |
Handle<JSObject> js_obj = Handle<JSObject>::cast(object);
|
|
5535 | 5596 |
// Fast case: either the key is a real named property or it is not |
5536 | 5597 |
// an array index and there are no interceptors or hidden |
5537 | 5598 |
// prototypes. |
5538 |
if (object->HasRealNamedProperty(isolate, key)) {
|
|
5599 |
if (JSObject::HasRealNamedProperty(js_obj, key)) {
|
|
5539 | 5600 |
ASSERT(!isolate->has_scheduled_exception()); |
5540 | 5601 |
return isolate->heap()->true_value(); |
5541 | 5602 |
} else { |
5542 | 5603 |
RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
5543 | 5604 |
} |
5544 |
Map* map = object->map();
|
|
5605 |
Map* map = js_obj->map();
|
|
5545 | 5606 |
if (!key_is_array_index && |
5546 | 5607 |
!map->has_named_interceptor() && |
5547 | 5608 |
!HeapObject::cast(map->prototype())->map()->is_hidden_prototype()) { |
5548 | 5609 |
return isolate->heap()->false_value(); |
5549 | 5610 |
} |
5550 | 5611 |
// Slow case. |
5551 |
HandleScope scope(isolate); |
|
5552 | 5612 |
return HasLocalPropertyImplementation(isolate, |
5553 |
Handle<JSObject>(object),
|
|
5613 |
Handle<JSObject>(js_obj),
|
|
5554 | 5614 |
Handle<Name>(key)); |
5555 |
} else if (obj->IsString() && key_is_array_index) { |
|
5615 |
} else if (object->IsString() && key_is_array_index) {
|
|
5556 | 5616 |
// Well, there is one exception: Handle [] on strings. |
5557 |
String* string = String::cast(obj);
|
|
5617 |
Handle<String> string = Handle<String>::cast(object);
|
|
5558 | 5618 |
if (index < static_cast<uint32_t>(string->length())) { |
5559 | 5619 |
return isolate->heap()->true_value(); |
5560 | 5620 |
} |
... | ... | |
5564 | 5624 |
|
5565 | 5625 |
|
5566 | 5626 |
RUNTIME_FUNCTION(MaybeObject*, Runtime_HasProperty) { |
5567 |
SealHandleScope shs(isolate);
|
|
5627 |
HandleScope scope(isolate);
|
|
5568 | 5628 |
ASSERT(args.length() == 2); |
5569 |
CONVERT_ARG_CHECKED(JSReceiver, receiver, 0); |
|
5570 |
CONVERT_ARG_CHECKED(Name, key, 1); |
|
5629 |
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
|
|
5630 |
CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
|
|
5571 | 5631 |
|
5572 |
bool result = receiver->HasProperty(key);
|
|
5632 |
bool result = JSReceiver::HasProperty(receiver, key);
|
|
5573 | 5633 |
RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
5574 | 5634 |
if (isolate->has_pending_exception()) return Failure::Exception(); |
5575 | 5635 |
return isolate->heap()->ToBoolean(result); |
... | ... | |
5577 | 5637 |
|
5578 | 5638 |
|
5579 | 5639 |
RUNTIME_FUNCTION(MaybeObject*, Runtime_HasElement) { |
5580 |
SealHandleScope shs(isolate);
|
|
5640 |
HandleScope scope(isolate);
|
|
5581 | 5641 |
ASSERT(args.length() == 2); |
5582 |
CONVERT_ARG_CHECKED(JSReceiver, receiver, 0); |
|
5642 |
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
|
|
5583 | 5643 |
CONVERT_SMI_ARG_CHECKED(index, 1); |
5584 | 5644 |
|
5585 |
bool result = receiver->HasElement(index);
|
|
5645 |
bool result = JSReceiver::HasElement(receiver, index);
|
|
5586 | 5646 |
RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
5587 | 5647 |
if (isolate->has_pending_exception()) return Failure::Exception(); |
5588 | 5648 |
return isolate->heap()->ToBoolean(result); |
... | ... | |
5923 | 5983 |
|
5924 | 5984 |
|
5925 | 5985 |
RUNTIME_FUNCTION(MaybeObject*, Runtime_ToFastProperties) { |
5926 |
SealHandleScope shs(isolate);
|
|
5986 |
HandleScope scope(isolate);
|
|
5927 | 5987 |
ASSERT(args.length() == 1); |
5928 |
Object* object = args[0]; |
|
5929 |
return (object->IsJSObject() && !object->IsGlobalObject()) |
|
5930 |
? JSObject::cast(object)->TransformToFastProperties(0) |
|
5931 |
: object; |
|
5988 |
CONVERT_ARG_HANDLE_CHECKED(Object, object, 0); |
|
5989 |
if (object->IsJSObject() && !object->IsGlobalObject()) { |
|
5990 |
JSObject::TransformToFastProperties(Handle<JSObject>::cast(object), 0); |
|
5991 |
} |
|
5992 |
return *object; |
|
5932 | 5993 |
} |
5933 | 5994 |
|
5934 | 5995 |
|
... | ... | |
7945 | 8006 |
// Allocate the elements if needed. |
7946 | 8007 |
if (length > 0) { |
7947 | 8008 |
// Allocate the fixed array. |
7948 |
Object* obj; |
|
7949 |
{ MaybeObject* maybe_obj = isolate->heap()->AllocateRawFixedArray(length); |
|
7950 |
if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
|
8009 |
FixedArray* array; |
|
8010 |
{ MaybeObject* maybe_obj = |
|
8011 |
isolate->heap()->AllocateUninitializedFixedArray(length); |
|
8012 |
if (!maybe_obj->To(&array)) return maybe_obj; |
|
7951 | 8013 |
} |
7952 | 8014 |
|
7953 | 8015 |
DisallowHeapAllocation no_gc; |
7954 |
FixedArray* array = reinterpret_cast<FixedArray*>(obj); |
|
7955 |
array->set_map_no_write_barrier(isolate->heap()->fixed_array_map()); |
|
7956 |
array->set_length(length); |
|
7957 |
|
|
7958 | 8016 |
WriteBarrierMode mode = array->GetWriteBarrierMode(no_gc); |
7959 | 8017 |
for (int i = 0; i < length; i++) { |
7960 | 8018 |
array->set(i, *--parameters, mode); |
7961 | 8019 |
} |
7962 |
JSObject::cast(result)->set_elements(FixedArray::cast(obj));
|
|
8020 |
JSObject::cast(result)->set_elements(array);
|
|
7963 | 8021 |
} |
7964 | 8022 |
return result; |
7965 | 8023 |
} |
... | ... | |
8288 | 8346 |
|
8289 | 8347 |
// If the function is not optimizable or debugger is active continue using the |
8290 | 8348 |
// code from the full compiler. |
8291 |
if (!FLAG_crankshaft ||
|
|
8349 |
if (!isolate->use_crankshaft() ||
|
|
8292 | 8350 |
function->shared()->optimization_disabled() || |
8293 | 8351 |
isolate->DebuggerHasBreakPoints()) { |
8294 | 8352 |
if (FLAG_trace_opt) { |
... | ... | |
8436 | 8494 |
} |
8437 | 8495 |
|
8438 | 8496 |
|
8439 |
RUNTIME_FUNCTION(MaybeObject*, Runtime_NotifyOSR) { |
|
8440 |
SealHandleScope shs(isolate); |
|
8441 |
Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate); |
|
8442 |
delete deoptimizer; |
|
8443 |
return isolate->heap()->undefined_value(); |
|
8444 |
} |
|
8445 |
|
|
8446 |
|
|
8447 | 8497 |
RUNTIME_FUNCTION(MaybeObject*, Runtime_DeoptimizeFunction) { |
8448 | 8498 |
HandleScope scope(isolate); |
8449 | 8499 |
ASSERT(args.length() == 1); |
... | ... | |
8501 | 8551 |
if (type->IsOneByteEqualTo(STATIC_ASCII_VECTOR("osr"))) { |
8502 | 8552 |
// Start patching from the currently patched loop nesting level. |
8503 | 8553 |
int current_level = unoptimized->allow_osr_at_loop_nesting_level(); |
8504 |
ASSERT(Deoptimizer::VerifyInterruptCode( |
|
8505 |
isolate, unoptimized, current_level)); |
|
8554 |
ASSERT(BackEdgeTable::Verify(isolate, unoptimized, current_level)); |
|
8506 | 8555 |
for (int i = current_level + 1; i <= Code::kMaxLoopNestingMarker; i++) { |
8507 | 8556 |
unoptimized->set_allow_osr_at_loop_nesting_level(i); |
8508 | 8557 |
isolate->runtime_profiler()->AttemptOnStackReplacement(*function); |
... | ... | |
8560 | 8609 |
} |
8561 | 8610 |
|
8562 | 8611 |
|
8612 |
RUNTIME_FUNCTION(MaybeObject*, Runtime_UnblockConcurrentRecompilation) { |
|
8613 |
RUNTIME_ASSERT(FLAG_block_concurrent_recompilation); |
|
8614 |
isolate->optimizing_compiler_thread()->Unblock(); |
|
8615 |
return isolate->heap()->undefined_value(); |
|
8616 |
} |
|
8617 |
|
|
8618 |
|
|
8563 | 8619 |
RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOptimizationCount) { |
8564 | 8620 |
HandleScope scope(isolate); |
8565 | 8621 |
ASSERT(args.length() == 1); |
... | ... | |
8572 | 8628 |
Handle<JSFunction> function, |
8573 | 8629 |
Handle<Code> unoptimized) { |
8574 | 8630 |
// Keep track of whether we've succeeded in optimizing. |
8575 |
if (!unoptimized->optimizable()) return false; |
|
8631 |
if (!isolate->use_crankshaft() || !unoptimized->optimizable()) return false;
|
|
8576 | 8632 |
// If we are trying to do OSR when there are already optimized |
8577 | 8633 |
// activations of the function, it means (a) the function is directly or |
8578 | 8634 |
// indirectly recursive and (b) an optimized invocation has been |
... | ... | |
8611 | 8667 |
Handle<Code> result = Handle<Code>::null(); |
8612 | 8668 |
BailoutId ast_id = BailoutId::None(); |
8613 | 8669 |
|
8614 |
if (FLAG_concurrent_recompilation && FLAG_concurrent_osr) {
|
|
8670 |
if (FLAG_concurrent_osr) { |
|
8615 | 8671 |
if (isolate->optimizing_compiler_thread()-> |
8616 | 8672 |
IsQueuedForOSR(function, pc_offset)) { |
8617 | 8673 |
// Still waiting for the optimizing compiler thread to finish. Carry on. |
... | ... | |
8623 | 8679 |
return NULL; |
8624 | 8680 |
} |
8625 | 8681 |
|
8626 |
OptimizingCompiler* compiler = isolate->optimizing_compiler_thread()->
|
|
8682 |
RecompileJob* job = isolate->optimizing_compiler_thread()->
|
|
8627 | 8683 |
FindReadyOSRCandidate(function, pc_offset); |
8628 | 8684 |
|
8629 |
if (compiler == NULL) {
|
|
8685 |
if (job == NULL) {
|
|
8630 | 8686 |
if (IsSuitableForOnStackReplacement(isolate, function, unoptimized) && |
8631 | 8687 |
Compiler::RecompileConcurrent(function, pc_offset)) { |
8632 | 8688 |
if (function->IsMarkedForLazyRecompilation() || |
8633 | 8689 |
function->IsMarkedForConcurrentRecompilation()) { |
8634 | 8690 |
// Prevent regular recompilation if we queue this for OSR. |
8635 | 8691 |
// TODO(yangguo): remove this as soon as OSR becomes one-shot. |
8636 |
function->ReplaceCode(function->shared()->code());
|
|
8692 |
function->ReplaceCode(*unoptimized);
|
|
8637 | 8693 |
} |
8638 | 8694 |
return NULL; |
8639 | 8695 |
} |
8640 | 8696 |
// Fall through to the end in case of failure. |
8641 | 8697 |
} else { |
8642 | 8698 |
// TODO(titzer): don't install the OSR code into the function. |
8643 |
ast_id = compiler->info()->osr_ast_id();
|
|
8644 |
result = Compiler::InstallOptimizedCode(compiler);
|
|
8699 |
ast_id = job->info()->osr_ast_id();
|
|
8700 |
result = Compiler::InstallOptimizedCode(job);
|
|
8645 | 8701 |
} |
8646 | 8702 |
} else if (IsSuitableForOnStackReplacement(isolate, function, unoptimized)) { |
8647 | 8703 |
ast_id = unoptimized->TranslatePcOffsetToAstId(pc_offset); |
... | ... | |
8655 | 8711 |
result = JSFunction::CompileOsr(function, ast_id, CLEAR_EXCEPTION); |
8656 | 8712 |
} |
8657 | 8713 |
|
8658 |
// Revert the patched interrupt now, regardless of whether OSR succeeds.
|
|
8659 |
Deoptimizer::RevertInterruptCode(isolate, *unoptimized);
|
|
8714 |
// Revert the patched back edge table, regardless of whether OSR succeeds.
|
|
8715 |
BackEdgeTable::Revert(isolate, *unoptimized);
|
|
8660 | 8716 |
|
8661 | 8717 |
// Check whether we ended up with usable optimized code. |
8662 | 8718 |
if (!result.is_null() && result->kind() == Code::OPTIMIZED_FUNCTION) { |
... | ... | |
9193 | 9249 |
// property from it. |
9194 | 9250 |
if (!holder.is_null()) { |
9195 | 9251 |
Handle<JSReceiver> object = Handle<JSReceiver>::cast(holder); |
9196 |
ASSERT(object->IsJSProxy() || object->HasProperty(*name));
|
|
9252 |
ASSERT(object->IsJSProxy() || JSReceiver::HasProperty(object, name));
|
|
9197 | 9253 |
// GetProperty below can cause GC. |
9198 | 9254 |
Handle<Object> receiver_handle( |
9199 | 9255 |
object->IsGlobalObject() |
... | ... | |
10174 | 10230 |
Handle<Object> element_value(elements->get(j), isolate); |
10175 | 10231 |
if (!element_value->IsTheHole()) { |
10176 | 10232 |
visitor->visit(j, element_value); |
10177 |
} else if (receiver->HasElement(j)) {
|
|
10233 |
} else if (JSReceiver::HasElement(receiver, j)) {
|
|
10178 | 10234 |
// Call GetElement on receiver, not its prototype, or getters won't |
10179 | 10235 |
// have the correct receiver. |
10180 | 10236 |
element_value = Object::GetElement(isolate, receiver, j); |
... | ... | |
10199 | 10255 |
Handle<Object> element_value = |
10200 | 10256 |
isolate->factory()->NewNumber(double_value); |
10201 | 10257 |
visitor->visit(j, element_value); |
10202 |
} else if (receiver->HasElement(j)) {
|
|
10258 |
} else if (JSReceiver::HasElement(receiver, j)) {
|
|
10203 | 10259 |
// Call GetElement on receiver, not its prototype, or getters won't |
10204 | 10260 |
// have the correct receiver. |
10205 | 10261 |
Handle<Object> element_value = |
... | ... | |
10492 | 10548 |
// property. |
10493 | 10549 |
// Returns the number of non-undefined elements collected. |
10494 | 10550 |
RUNTIME_FUNCTION(MaybeObject*, Runtime_RemoveArrayHoles) { |
10495 |
SealHandleScope shs(isolate);
|
|
10551 |
HandleScope scope(isolate);
|
|
10496 | 10552 |
ASSERT(args.length() == 2); |
10497 |
CONVERT_ARG_CHECKED(JSObject, object, 0); |
|
10553 |
CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
|
|
10498 | 10554 |
CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[1]); |
10499 |
return object->PrepareElementsForSort(limit);
|
|
10555 |
return *JSObject::PrepareElementsForSort(object, limit);
|
|
10500 | 10556 |
} |
10501 | 10557 |
|
10502 | 10558 |
|
... | ... | |
10587 | 10643 |
|
10588 | 10644 |
|
10589 | 10645 |
RUNTIME_FUNCTION(MaybeObject*, Runtime_LookupAccessor) { |
10590 |
SealHandleScope shs(isolate);
|
|
10646 |
HandleScope scope(isolate);
|
|
10591 | 10647 |
ASSERT(args.length() == 3); |
10592 |
CONVERT_ARG_CHECKED(JSReceiver, receiver, 0); |
|
10593 |
CONVERT_ARG_CHECKED(Name, name, 1); |
|
10648 |
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
|
|
10649 |
CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
|
|
10594 | 10650 |
CONVERT_SMI_ARG_CHECKED(flag, 2); |
10595 | 10651 |
AccessorComponent component = flag == 0 ? ACCESSOR_GETTER : ACCESSOR_SETTER; |
10596 | 10652 |
if (!receiver->IsJSObject()) return isolate->heap()->undefined_value(); |
10597 |
return JSObject::cast(receiver)->LookupAccessor(name, component); |
|
10653 |
Handle<Object> result = |
|
10654 |
JSObject::GetAccessor(Handle<JSObject>::cast(receiver), name, component); |
|
10655 |
RETURN_IF_EMPTY_HANDLE(isolate, result); |
|
10656 |
return *result; |
|
10598 | 10657 |
} |
10599 | 10658 |
|
10600 | 10659 |
|
... | ... | |
10674 | 10733 |
case CALLBACKS: { |
10675 | 10734 |
Object* structure = result->GetCallbackObject(); |
10676 | 10735 |
if (structure->IsForeign() || structure->IsAccessorInfo()) { |
10677 |
MaybeObject* maybe_value = result->holder()->GetPropertyWithCallback( |
|
10678 |
receiver, structure, name); |
|
10679 |
if (!maybe_value->ToObject(&value)) { |
|
10680 |
if (maybe_value->IsRetryAfterGC()) return maybe_value; |
|
10681 |
ASSERT(maybe_value->IsException()); |
|
10682 |
maybe_value = heap->isolate()->pending_exception(); |
|
10736 |
Isolate* isolate = heap->isolate(); |
|
10737 |
HandleScope scope(isolate); |
|
10738 |
Handle<Object> value = JSObject::GetPropertyWithCallback( |
|
10739 |
handle(result->holder(), isolate), |
|
10740 |
handle(receiver, isolate), |
|
10741 |
handle(structure, isolate), |
|
10742 |
handle(name, isolate)); |
|
10743 |
if (value.is_null()) { |
|
10744 |
MaybeObject* exception = heap->isolate()->pending_exception(); |
|
10683 | 10745 |
heap->isolate()->clear_pending_exception(); |
10684 |
if (caught_exception != NULL) { |
|
10685 |
*caught_exception = true; |
|
10686 |
} |
|
10687 |
return maybe_value; |
|
10746 |
if (caught_exception != NULL) *caught_exception = true; |
|
10747 |
return exception; |
|
10688 | 10748 |
} |
10689 |
return value; |
|
10749 |
return *value;
|
|
10690 | 10750 |
} else { |
10691 | 10751 |
return heap->undefined_value(); |
10692 | 10752 |
} |
... | ... | |
10874 | 10934 |
CONVERT_ARG_HANDLE_CHECKED(Name, name, 1); |
10875 | 10935 |
|
10876 | 10936 |
PropertyAttributes attributes; |
10877 |
return obj->GetPropertyWithInterceptor(*obj, *name, &attributes); |
|
10937 |
Handle<Object> result = |
|
10938 |
JSObject::GetPropertyWithInterceptor(obj, obj, name, &attributes); |
|
10939 |
RETURN_IF_EMPTY_HANDLE(isolate, result); |
|
10940 |
return *result; |
|
10878 | 10941 |
} |
10879 | 10942 |
|
10880 | 10943 |
|
... | ... | |
11391 | 11454 |
// Third fill all context locals. |
11392 | 11455 |
Handle<Context> frame_context(Context::cast(frame->context())); |
11393 | 11456 |
Handle<Context> function_context(frame_context->declaration_context()); |
11394 |
if (!scope_info->CopyContextLocalsToScopeObject(
|
|
11395 |
isolate, function_context, target)) {
|
|
11457 |
if (!ScopeInfo::CopyContextLocalsToScopeObject(
|
|
11458 |
scope_info, function_context, target)) {
|
|
11396 | 11459 |
return Handle<JSObject>(); |
11397 | 11460 |
} |
11398 | 11461 |
|
... | ... | |
11515 | 11578 |
!function_context->IsNativeContext()) { |
11516 | 11579 |
Handle<JSObject> ext(JSObject::cast(function_context->extension())); |
11517 | 11580 |
|
11518 |
if (ext->HasProperty(*variable_name)) {
|
|
11581 |
if (JSReceiver::HasProperty(ext, variable_name)) {
|
|
11519 | 11582 |
// We don't expect this to do anything except replacing |
11520 | 11583 |
// property value. |
11521 | 11584 |
SetProperty(isolate, |
... | ... | |
11549 | 11612 |
isolate->factory()->NewJSObject(isolate->object_function()); |
11550 | 11613 |
|
11551 | 11614 |
// Fill all context locals to the context extension. |
11552 |
if (!scope_info->CopyContextLocalsToScopeObject(
|
|
11553 |
isolate, context, closure_scope)) {
|
|
11615 |
if (!ScopeInfo::CopyContextLocalsToScopeObject(
|
|
11616 |
scope_info, context, closure_scope)) {
|
|
11554 | 11617 |
return Handle<JSObject>(); |
11555 | 11618 |
} |
11556 | 11619 |
|
... | ... | |
11603 | 11666 |
// be variables introduced by eval. |
11604 | 11667 |
if (context->has_extension()) { |
11605 | 11668 |
Handle<JSObject> ext(JSObject::cast(context->extension())); |
11606 |
if (ext->HasProperty(*variable_name)) {
|
|
11669 |
if (JSReceiver::HasProperty(ext, variable_name)) {
|
|
11607 | 11670 |
// We don't expect this to do anything except replacing property value. |
11608 | 11671 |
SetProperty(isolate, |
11609 | 11672 |
ext, |
... | ... | |
11670 | 11733 |
isolate->factory()->NewJSObject(isolate->object_function()); |
11671 | 11734 |
|
11672 | 11735 |
// Fill all context locals. |
11673 |
if (!scope_info->CopyContextLocalsToScopeObject(
|
|
11674 |
isolate, context, block_scope)) {
|
|
11736 |
if (!ScopeInfo::CopyContextLocalsToScopeObject(
|
|
11737 |
scope_info, context, block_scope)) {
|
|
11675 | 11738 |
return Handle<JSObject>(); |
11676 | 11739 |
} |
11677 | 11740 |
|
... | ... | |
11693 | 11756 |
isolate->factory()->NewJSObject(isolate->object_function()); |
11694 | 11757 |
|
11695 | 11758 |
// Fill all context locals. |
11696 |
if (!scope_info->CopyContextLocalsToScopeObject(
|
|
11697 |
isolate, context, module_scope)) {
|
|
11759 |
if (!ScopeInfo::CopyContextLocalsToScopeObject(
|
|
11760 |
scope_info, context, module_scope)) {
|
|
11698 | 11761 |
return Handle<JSObject>(); |
11699 | 11762 |
} |
11700 | 11763 |
|
... | ... | |
12646 | 12709 |
// Do not materialize the arguments object for eval or top-level code. |
12647 | 12710 |
// Skip if "arguments" is already taken. |
12648 | 12711 |
if (!function->shared()->is_function() || |
12649 |
target->HasLocalProperty(isolate->heap()->arguments_string())) { |
|
12712 |
JSReceiver::HasLocalProperty(target, |
|
12713 |
isolate->factory()->arguments_string())) { |
|
12650 | 12714 |
return target; |
12651 | 12715 |
} |
12652 | 12716 |
|
... | ... | |
14533 | 14597 |
|
14534 | 14598 |
|
14535 | 14599 |
RUNTIME_FUNCTION(MaybeObject*, Runtime_SetIsObserved) { |
14536 |
SealHandleScope shs(isolate);
|
|
14600 |
HandleScope scope(isolate);
|
|
14537 | 14601 |
ASSERT(args.length() == 1); |
14538 |
CONVERT_ARG_CHECKED(JSReceiver, obj, 0); |
|
14602 |
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, obj, 0);
|
|
14539 | 14603 |
if (obj->IsJSGlobalProxy()) { |
14540 | 14604 |
Object* proto = obj->GetPrototype(); |
14541 | 14605 |
if (proto->IsNull()) return isolate->heap()->undefined_value(); |
14542 | 14606 |
ASSERT(proto->IsJSGlobalObject()); |
14543 |
obj = JSReceiver::cast(proto);
|
|
14607 |
obj = handle(JSReceiver::cast(proto));
|
|
14544 | 14608 |
} |
14545 | 14609 |
if (obj->IsJSProxy()) |
14546 | 14610 |
return isolate->heap()->undefined_value(); |
14547 | 14611 |
|
14548 | 14612 |
ASSERT(!(obj->map()->is_observed() && obj->IsJSObject() && |
14549 |
JSObject::cast(obj)->HasFastElements()));
|
|
14613 |
Handle<JSObject>::cast(obj)->HasFastElements()));
|
|
14550 | 14614 |
ASSERT(obj->IsJSObject()); |
14551 |
return JSObject::cast(obj)->SetObserved(isolate); |
|
14615 |
JSObject::SetObserved(Handle<JSObject>::cast(obj)); |
|
14616 |
return isolate->heap()->undefined_value(); |
|
14552 | 14617 |
} |
14553 | 14618 |
|
14554 | 14619 |
|
... | ... | |
14652 | 14717 |
Handle<Cell> cell = Handle<Cell>::cast(type_info); |
14653 | 14718 |
Handle<AllocationSite> site = Handle<AllocationSite>( |
14654 | 14719 |
AllocationSite::cast(cell->value()), isolate); |
14655 |
ASSERT(!site->IsLiteralSite());
|
|
14720 |
ASSERT(!site->SitePointsToLiteral());
|
|
14656 | 14721 |
ElementsKind to_kind = site->GetElementsKind(); |
14657 | 14722 |
if (holey && !IsFastHoleyElementsKind(to_kind)) { |
14658 | 14723 |
to_kind = GetHoleyElementsKind(to_kind); |
... | ... | |
14786 | 14851 |
} |
14787 | 14852 |
|
14788 | 14853 |
|
14789 |
void Runtime::PerformGC(Object* result) { |
|
14790 |
Isolate* isolate = Isolate::Current(); |
|
14854 |
void Runtime::PerformGC(Object* result, Isolate* isolate) { |
|
14791 | 14855 |
Failure* failure = Failure::cast(result); |
14792 | 14856 |
if (failure->IsRetryAfterGC()) { |
14793 | 14857 |
if (isolate->heap()->new_space()->AddFreshPage()) { |
Also available in: Unified diff