| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 1456 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1467 } | 1467 } |
| 1468 } | 1468 } |
| 1469 return AddSlowProperty(name, value, attributes); | 1469 return AddSlowProperty(name, value, attributes); |
| 1470 } | 1470 } |
| 1471 | 1471 |
| 1472 | 1472 |
| 1473 MaybeObject* JSObject::SetPropertyPostInterceptor( | 1473 MaybeObject* JSObject::SetPropertyPostInterceptor( |
| 1474 String* name, | 1474 String* name, |
| 1475 Object* value, | 1475 Object* value, |
| 1476 PropertyAttributes attributes, | 1476 PropertyAttributes attributes, |
| 1477 StrictModeFlag strict) { | 1477 StrictModeFlag strict_mode) { |
| 1478 // Check local property, ignore interceptor. | 1478 // Check local property, ignore interceptor. |
| 1479 LookupResult result; | 1479 LookupResult result; |
| 1480 LocalLookupRealNamedProperty(name, &result); | 1480 LocalLookupRealNamedProperty(name, &result); |
| 1481 if (result.IsFound()) { | 1481 if (result.IsFound()) { |
| 1482 // An existing property, a map transition or a null descriptor was | 1482 // An existing property, a map transition or a null descriptor was |
| 1483 // found. Use set property to handle all these cases. | 1483 // found. Use set property to handle all these cases. |
| 1484 return SetProperty(&result, name, value, attributes, strict); | 1484 return SetProperty(&result, name, value, attributes, strict_mode); |
| 1485 } | 1485 } |
| 1486 // Add a new real property. | 1486 // Add a new real property. |
| 1487 return AddProperty(name, value, attributes); | 1487 return AddProperty(name, value, attributes); |
| 1488 } | 1488 } |
| 1489 | 1489 |
| 1490 | 1490 |
| 1491 MaybeObject* JSObject::ReplaceSlowProperty(String* name, | 1491 MaybeObject* JSObject::ReplaceSlowProperty(String* name, |
| 1492 Object* value, | 1492 Object* value, |
| 1493 PropertyAttributes attributes) { | 1493 PropertyAttributes attributes) { |
| 1494 StringDictionary* dictionary = property_dictionary(); | 1494 StringDictionary* dictionary = property_dictionary(); |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1601 } | 1601 } |
| 1602 return FastPropertyAtPut(index, new_value); | 1602 return FastPropertyAtPut(index, new_value); |
| 1603 } | 1603 } |
| 1604 | 1604 |
| 1605 | 1605 |
| 1606 | 1606 |
| 1607 MaybeObject* JSObject::SetPropertyWithInterceptor( | 1607 MaybeObject* JSObject::SetPropertyWithInterceptor( |
| 1608 String* name, | 1608 String* name, |
| 1609 Object* value, | 1609 Object* value, |
| 1610 PropertyAttributes attributes, | 1610 PropertyAttributes attributes, |
| 1611 StrictModeFlag strict) { | 1611 StrictModeFlag strict_mode) { |
| 1612 Isolate* isolate = GetIsolate(); | 1612 Isolate* isolate = GetIsolate(); |
| 1613 HandleScope scope(isolate); | 1613 HandleScope scope(isolate); |
| 1614 Handle<JSObject> this_handle(this); | 1614 Handle<JSObject> this_handle(this); |
| 1615 Handle<String> name_handle(name); | 1615 Handle<String> name_handle(name); |
| 1616 Handle<Object> value_handle(value, isolate); | 1616 Handle<Object> value_handle(value, isolate); |
| 1617 Handle<InterceptorInfo> interceptor(GetNamedInterceptor()); | 1617 Handle<InterceptorInfo> interceptor(GetNamedInterceptor()); |
| 1618 if (!interceptor->setter()->IsUndefined()) { | 1618 if (!interceptor->setter()->IsUndefined()) { |
| 1619 LOG(ApiNamedPropertyAccess("interceptor-named-set", this, name)); | 1619 LOG(ApiNamedPropertyAccess("interceptor-named-set", this, name)); |
| 1620 CustomArguments args(isolate, interceptor->data(), this, this); | 1620 CustomArguments args(isolate, interceptor->data(), this, this); |
| 1621 v8::AccessorInfo info(args.end()); | 1621 v8::AccessorInfo info(args.end()); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1633 v8::Utils::ToLocal(value_unhole), | 1633 v8::Utils::ToLocal(value_unhole), |
| 1634 info); | 1634 info); |
| 1635 } | 1635 } |
| 1636 RETURN_IF_SCHEDULED_EXCEPTION(isolate); | 1636 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 1637 if (!result.IsEmpty()) return *value_handle; | 1637 if (!result.IsEmpty()) return *value_handle; |
| 1638 } | 1638 } |
| 1639 MaybeObject* raw_result = | 1639 MaybeObject* raw_result = |
| 1640 this_handle->SetPropertyPostInterceptor(*name_handle, | 1640 this_handle->SetPropertyPostInterceptor(*name_handle, |
| 1641 *value_handle, | 1641 *value_handle, |
| 1642 attributes, | 1642 attributes, |
| 1643 strict); | 1643 strict_mode); |
| 1644 RETURN_IF_SCHEDULED_EXCEPTION(isolate); | 1644 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 1645 return raw_result; | 1645 return raw_result; |
| 1646 } | 1646 } |
| 1647 | 1647 |
| 1648 | 1648 |
| 1649 MaybeObject* JSObject::SetProperty(String* name, | 1649 MaybeObject* JSObject::SetProperty(String* name, |
| 1650 Object* value, | 1650 Object* value, |
| 1651 PropertyAttributes attributes, | 1651 PropertyAttributes attributes, |
| 1652 StrictModeFlag strict) { | 1652 StrictModeFlag strict_mode) { |
| 1653 LookupResult result; | 1653 LookupResult result; |
| 1654 LocalLookup(name, &result); | 1654 LocalLookup(name, &result); |
| 1655 return SetProperty(&result, name, value, attributes, strict); | 1655 return SetProperty(&result, name, value, attributes, strict_mode); |
| 1656 } | 1656 } |
| 1657 | 1657 |
| 1658 | 1658 |
| 1659 MaybeObject* JSObject::SetPropertyWithCallback(Object* structure, | 1659 MaybeObject* JSObject::SetPropertyWithCallback(Object* structure, |
| 1660 String* name, | 1660 String* name, |
| 1661 Object* value, | 1661 Object* value, |
| 1662 JSObject* holder) { | 1662 JSObject* holder) { |
| 1663 Isolate* isolate = GetIsolate(); | 1663 Isolate* isolate = GetIsolate(); |
| 1664 HandleScope scope(isolate); | 1664 HandleScope scope(isolate); |
| 1665 | 1665 |
| (...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1935 Handle<Object> value_handle(value); | 1935 Handle<Object> value_handle(value); |
| 1936 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_SET); | 1936 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_SET); |
| 1937 return *value_handle; | 1937 return *value_handle; |
| 1938 } | 1938 } |
| 1939 | 1939 |
| 1940 | 1940 |
| 1941 MaybeObject* JSObject::SetProperty(LookupResult* result, | 1941 MaybeObject* JSObject::SetProperty(LookupResult* result, |
| 1942 String* name, | 1942 String* name, |
| 1943 Object* value, | 1943 Object* value, |
| 1944 PropertyAttributes attributes, | 1944 PropertyAttributes attributes, |
| 1945 StrictModeFlag strict) { | 1945 StrictModeFlag strict_mode) { |
| 1946 Heap* heap = GetHeap(); | 1946 Heap* heap = GetHeap(); |
| 1947 // Make sure that the top context does not change when doing callbacks or | 1947 // Make sure that the top context does not change when doing callbacks or |
| 1948 // interceptor calls. | 1948 // interceptor calls. |
| 1949 AssertNoContextChange ncc; | 1949 AssertNoContextChange ncc; |
| 1950 | 1950 |
| 1951 // Optimization for 2-byte strings often used as keys in a decompression | 1951 // Optimization for 2-byte strings often used as keys in a decompression |
| 1952 // dictionary. We make these short keys into symbols to avoid constantly | 1952 // dictionary. We make these short keys into symbols to avoid constantly |
| 1953 // reallocating them. | 1953 // reallocating them. |
| 1954 if (!name->IsSymbol() && name->length() <= 2) { | 1954 if (!name->IsSymbol() && name->length() <= 2) { |
| 1955 Object* symbol_version; | 1955 Object* symbol_version; |
| 1956 { MaybeObject* maybe_symbol_version = heap->LookupSymbol(name); | 1956 { MaybeObject* maybe_symbol_version = heap->LookupSymbol(name); |
| 1957 if (maybe_symbol_version->ToObject(&symbol_version)) { | 1957 if (maybe_symbol_version->ToObject(&symbol_version)) { |
| 1958 name = String::cast(symbol_version); | 1958 name = String::cast(symbol_version); |
| 1959 } | 1959 } |
| 1960 } | 1960 } |
| 1961 } | 1961 } |
| 1962 | 1962 |
| 1963 // Check access rights if needed. | 1963 // Check access rights if needed. |
| 1964 if (IsAccessCheckNeeded() | 1964 if (IsAccessCheckNeeded() |
| 1965 && !heap->isolate()->MayNamedAccess(this, name, v8::ACCESS_SET)) { | 1965 && !heap->isolate()->MayNamedAccess(this, name, v8::ACCESS_SET)) { |
| 1966 return SetPropertyWithFailedAccessCheck(result, name, value, true); | 1966 return SetPropertyWithFailedAccessCheck(result, name, value, true); |
| 1967 } | 1967 } |
| 1968 | 1968 |
| 1969 if (IsJSGlobalProxy()) { | 1969 if (IsJSGlobalProxy()) { |
| 1970 Object* proto = GetPrototype(); | 1970 Object* proto = GetPrototype(); |
| 1971 if (proto->IsNull()) return value; | 1971 if (proto->IsNull()) return value; |
| 1972 ASSERT(proto->IsJSGlobalObject()); | 1972 ASSERT(proto->IsJSGlobalObject()); |
| 1973 return JSObject::cast(proto)->SetProperty( | 1973 return JSObject::cast(proto)->SetProperty( |
| 1974 result, name, value, attributes, strict); | 1974 result, name, value, attributes, strict_mode); |
| 1975 } | 1975 } |
| 1976 | 1976 |
| 1977 if (!result->IsProperty() && !IsJSContextExtensionObject()) { | 1977 if (!result->IsProperty() && !IsJSContextExtensionObject()) { |
| 1978 // We could not find a local property so let's check whether there is an | 1978 // We could not find a local property so let's check whether there is an |
| 1979 // accessor that wants to handle the property. | 1979 // accessor that wants to handle the property. |
| 1980 LookupResult accessor_result; | 1980 LookupResult accessor_result; |
| 1981 LookupCallbackSetterInPrototypes(name, &accessor_result); | 1981 LookupCallbackSetterInPrototypes(name, &accessor_result); |
| 1982 if (accessor_result.IsProperty()) { | 1982 if (accessor_result.IsProperty()) { |
| 1983 return SetPropertyWithCallback(accessor_result.GetCallbackObject(), | 1983 return SetPropertyWithCallback(accessor_result.GetCallbackObject(), |
| 1984 name, | 1984 name, |
| 1985 value, | 1985 value, |
| 1986 accessor_result.holder()); | 1986 accessor_result.holder()); |
| 1987 } | 1987 } |
| 1988 } | 1988 } |
| 1989 if (!result->IsFound()) { | 1989 if (!result->IsFound()) { |
| 1990 // Neither properties nor transitions found. | 1990 // Neither properties nor transitions found. |
| 1991 return AddProperty(name, value, attributes); | 1991 return AddProperty(name, value, attributes); |
| 1992 } | 1992 } |
| 1993 if (result->IsReadOnly() && result->IsProperty()) { | 1993 if (result->IsReadOnly() && result->IsProperty()) { |
| 1994 if (strict == kStrictMode) { | 1994 if (strict_mode == kStrictMode) { |
| 1995 HandleScope scope; | 1995 HandleScope scope; |
| 1996 Handle<String> key(name); | 1996 Handle<String> key(name); |
| 1997 Handle<Object> holder(this); | 1997 Handle<Object> holder(this); |
| 1998 Handle<Object> args[2] = { key, holder }; | 1998 Handle<Object> args[2] = { key, holder }; |
| 1999 return heap->isolate()->Throw(*heap->isolate()->factory()->NewTypeError( | 1999 return heap->isolate()->Throw(*heap->isolate()->factory()->NewTypeError( |
| 2000 "strict_read_only_property", HandleVector(args, 2))); | 2000 "strict_read_only_property", HandleVector(args, 2))); |
| 2001 | 2001 |
| 2002 } else { | 2002 } else { |
| 2003 return value; | 2003 return value; |
| 2004 } | 2004 } |
| (...skipping 18 matching lines...) Expand all Loading... |
| 2023 if (value == result->GetConstantFunction()) return value; | 2023 if (value == result->GetConstantFunction()) return value; |
| 2024 // Preserve the attributes of this existing property. | 2024 // Preserve the attributes of this existing property. |
| 2025 attributes = result->GetAttributes(); | 2025 attributes = result->GetAttributes(); |
| 2026 return ConvertDescriptorToField(name, value, attributes); | 2026 return ConvertDescriptorToField(name, value, attributes); |
| 2027 case CALLBACKS: | 2027 case CALLBACKS: |
| 2028 return SetPropertyWithCallback(result->GetCallbackObject(), | 2028 return SetPropertyWithCallback(result->GetCallbackObject(), |
| 2029 name, | 2029 name, |
| 2030 value, | 2030 value, |
| 2031 result->holder()); | 2031 result->holder()); |
| 2032 case INTERCEPTOR: | 2032 case INTERCEPTOR: |
| 2033 return SetPropertyWithInterceptor(name, value, attributes, strict); | 2033 return SetPropertyWithInterceptor(name, value, attributes, strict_mode); |
| 2034 case CONSTANT_TRANSITION: { | 2034 case CONSTANT_TRANSITION: { |
| 2035 // If the same constant function is being added we can simply | 2035 // If the same constant function is being added we can simply |
| 2036 // transition to the target map. | 2036 // transition to the target map. |
| 2037 Map* target_map = result->GetTransitionMap(); | 2037 Map* target_map = result->GetTransitionMap(); |
| 2038 DescriptorArray* target_descriptors = target_map->instance_descriptors(); | 2038 DescriptorArray* target_descriptors = target_map->instance_descriptors(); |
| 2039 int number = target_descriptors->SearchWithCache(name); | 2039 int number = target_descriptors->SearchWithCache(name); |
| 2040 ASSERT(number != DescriptorArray::kNotFound); | 2040 ASSERT(number != DescriptorArray::kNotFound); |
| 2041 ASSERT(target_descriptors->GetType(number) == CONSTANT_FUNCTION); | 2041 ASSERT(target_descriptors->GetType(number) == CONSTANT_FUNCTION); |
| 2042 JSFunction* function = | 2042 JSFunction* function = |
| 2043 JSFunction::cast(target_descriptors->GetValue(number)); | 2043 JSFunction::cast(target_descriptors->GetValue(number)); |
| (...skipping 3599 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5643 initial_object_prototype(); | 5643 initial_object_prototype(); |
| 5644 } else { | 5644 } else { |
| 5645 map()->set_non_instance_prototype(false); | 5645 map()->set_non_instance_prototype(false); |
| 5646 } | 5646 } |
| 5647 | 5647 |
| 5648 return SetInstancePrototype(construct_prototype); | 5648 return SetInstancePrototype(construct_prototype); |
| 5649 } | 5649 } |
| 5650 | 5650 |
| 5651 | 5651 |
| 5652 Object* JSFunction::RemovePrototype() { | 5652 Object* JSFunction::RemovePrototype() { |
| 5653 if (map() == context()->global_context()->function_without_prototype_map()) { |
| 5654 // Be idempotent. |
| 5655 return this; |
| 5656 } |
| 5653 ASSERT(map() == context()->global_context()->function_map()); | 5657 ASSERT(map() == context()->global_context()->function_map()); |
| 5654 Heap* heap = GetHeap(); | 5658 Heap* heap = GetHeap(); |
| 5655 set_map(context()->global_context()->function_without_prototype_map()); | 5659 set_map(context()->global_context()->function_without_prototype_map()); |
| 5656 set_prototype_or_initial_map(heap->the_hole_value()); | 5660 set_prototype_or_initial_map(heap->the_hole_value()); |
| 5657 return this; | 5661 return this; |
| 5658 } | 5662 } |
| 5659 | 5663 |
| 5660 | 5664 |
| 5661 Object* JSFunction::SetInstanceClassName(String* name) { | 5665 Object* JSFunction::SetInstanceClassName(String* name) { |
| 5662 shared()->set_instance_class_name(name); | 5666 shared()->set_instance_class_name(name); |
| (...skipping 965 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6628 Handle<FixedArray> old_backing(FixedArray::cast(elements())); | 6632 Handle<FixedArray> old_backing(FixedArray::cast(elements())); |
| 6629 int old_size = old_backing->length(); | 6633 int old_size = old_backing->length(); |
| 6630 int new_size = required_size > old_size ? required_size : old_size; | 6634 int new_size = required_size > old_size ? required_size : old_size; |
| 6631 Handle<FixedArray> new_backing = FACTORY->NewFixedArray(new_size); | 6635 Handle<FixedArray> new_backing = FACTORY->NewFixedArray(new_size); |
| 6632 // Can't use this any more now because we may have had a GC! | 6636 // Can't use this any more now because we may have had a GC! |
| 6633 for (int i = 0; i < old_size; i++) new_backing->set(i, old_backing->get(i)); | 6637 for (int i = 0; i < old_size; i++) new_backing->set(i, old_backing->get(i)); |
| 6634 self->SetContent(*new_backing); | 6638 self->SetContent(*new_backing); |
| 6635 } | 6639 } |
| 6636 | 6640 |
| 6637 | 6641 |
| 6638 // Computes the new capacity when expanding the elements of a JSObject. | |
| 6639 static int NewElementsCapacity(int old_capacity) { | |
| 6640 // (old_capacity + 50%) + 16 | |
| 6641 return old_capacity + (old_capacity >> 1) + 16; | |
| 6642 } | |
| 6643 | |
| 6644 | |
| 6645 static Failure* ArrayLengthRangeError(Heap* heap) { | 6642 static Failure* ArrayLengthRangeError(Heap* heap) { |
| 6646 HandleScope scope; | 6643 HandleScope scope; |
| 6647 return heap->isolate()->Throw( | 6644 return heap->isolate()->Throw( |
| 6648 *FACTORY->NewRangeError("invalid_array_length", | 6645 *FACTORY->NewRangeError("invalid_array_length", |
| 6649 HandleVector<Object>(NULL, 0))); | 6646 HandleVector<Object>(NULL, 0))); |
| 6650 } | 6647 } |
| 6651 | 6648 |
| 6652 | 6649 |
| 6653 MaybeObject* JSObject::SetElementsLength(Object* len) { | 6650 MaybeObject* JSObject::SetElementsLength(Object* len) { |
| 6654 Heap* heap = GetHeap(); | 6651 Heap* heap = GetHeap(); |
| (...skipping 3482 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10137 if (break_point_objects()->IsUndefined()) return 0; | 10134 if (break_point_objects()->IsUndefined()) return 0; |
| 10138 // Single beak point. | 10135 // Single beak point. |
| 10139 if (!break_point_objects()->IsFixedArray()) return 1; | 10136 if (!break_point_objects()->IsFixedArray()) return 1; |
| 10140 // Multiple break points. | 10137 // Multiple break points. |
| 10141 return FixedArray::cast(break_point_objects())->length(); | 10138 return FixedArray::cast(break_point_objects())->length(); |
| 10142 } | 10139 } |
| 10143 #endif | 10140 #endif |
| 10144 | 10141 |
| 10145 | 10142 |
| 10146 } } // namespace v8::internal | 10143 } } // namespace v8::internal |
| OLD | NEW |