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 1427 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1438 } | 1438 } |
1439 } | 1439 } |
1440 return AddSlowProperty(name, value, attributes); | 1440 return AddSlowProperty(name, value, attributes); |
1441 } | 1441 } |
1442 | 1442 |
1443 | 1443 |
1444 MaybeObject* JSObject::SetPropertyPostInterceptor( | 1444 MaybeObject* JSObject::SetPropertyPostInterceptor( |
1445 String* name, | 1445 String* name, |
1446 Object* value, | 1446 Object* value, |
1447 PropertyAttributes attributes, | 1447 PropertyAttributes attributes, |
1448 StrictModeFlag strict) { | 1448 StrictModeFlag strict_mode) { |
1449 // Check local property, ignore interceptor. | 1449 // Check local property, ignore interceptor. |
1450 LookupResult result; | 1450 LookupResult result; |
1451 LocalLookupRealNamedProperty(name, &result); | 1451 LocalLookupRealNamedProperty(name, &result); |
1452 if (result.IsFound()) { | 1452 if (result.IsFound()) { |
1453 // An existing property, a map transition or a null descriptor was | 1453 // An existing property, a map transition or a null descriptor was |
1454 // found. Use set property to handle all these cases. | 1454 // found. Use set property to handle all these cases. |
1455 return SetProperty(&result, name, value, attributes, strict); | 1455 return SetProperty(&result, name, value, attributes, strict_mode); |
1456 } | 1456 } |
1457 // Add a new real property. | 1457 // Add a new real property. |
1458 return AddProperty(name, value, attributes); | 1458 return AddProperty(name, value, attributes); |
1459 } | 1459 } |
1460 | 1460 |
1461 | 1461 |
1462 MaybeObject* JSObject::ReplaceSlowProperty(String* name, | 1462 MaybeObject* JSObject::ReplaceSlowProperty(String* name, |
1463 Object* value, | 1463 Object* value, |
1464 PropertyAttributes attributes) { | 1464 PropertyAttributes attributes) { |
1465 StringDictionary* dictionary = property_dictionary(); | 1465 StringDictionary* dictionary = property_dictionary(); |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1571 } | 1571 } |
1572 return FastPropertyAtPut(index, new_value); | 1572 return FastPropertyAtPut(index, new_value); |
1573 } | 1573 } |
1574 | 1574 |
1575 | 1575 |
1576 | 1576 |
1577 MaybeObject* JSObject::SetPropertyWithInterceptor( | 1577 MaybeObject* JSObject::SetPropertyWithInterceptor( |
1578 String* name, | 1578 String* name, |
1579 Object* value, | 1579 Object* value, |
1580 PropertyAttributes attributes, | 1580 PropertyAttributes attributes, |
1581 StrictModeFlag strict) { | 1581 StrictModeFlag strict_mode) { |
1582 HandleScope scope; | 1582 HandleScope scope; |
1583 Handle<JSObject> this_handle(this); | 1583 Handle<JSObject> this_handle(this); |
1584 Handle<String> name_handle(name); | 1584 Handle<String> name_handle(name); |
1585 Handle<Object> value_handle(value); | 1585 Handle<Object> value_handle(value); |
1586 Handle<InterceptorInfo> interceptor(GetNamedInterceptor()); | 1586 Handle<InterceptorInfo> interceptor(GetNamedInterceptor()); |
1587 if (!interceptor->setter()->IsUndefined()) { | 1587 if (!interceptor->setter()->IsUndefined()) { |
1588 LOG(ApiNamedPropertyAccess("interceptor-named-set", this, name)); | 1588 LOG(ApiNamedPropertyAccess("interceptor-named-set", this, name)); |
1589 CustomArguments args(interceptor->data(), this, this); | 1589 CustomArguments args(interceptor->data(), this, this); |
1590 v8::AccessorInfo info(args.end()); | 1590 v8::AccessorInfo info(args.end()); |
1591 v8::NamedPropertySetter setter = | 1591 v8::NamedPropertySetter setter = |
1592 v8::ToCData<v8::NamedPropertySetter>(interceptor->setter()); | 1592 v8::ToCData<v8::NamedPropertySetter>(interceptor->setter()); |
1593 v8::Handle<v8::Value> result; | 1593 v8::Handle<v8::Value> result; |
1594 { | 1594 { |
1595 // Leaving JavaScript. | 1595 // Leaving JavaScript. |
1596 VMState state(EXTERNAL); | 1596 VMState state(EXTERNAL); |
1597 Handle<Object> value_unhole(value->IsTheHole() ? | 1597 Handle<Object> value_unhole(value->IsTheHole() ? |
1598 Heap::undefined_value() : | 1598 Heap::undefined_value() : |
1599 value); | 1599 value); |
1600 result = setter(v8::Utils::ToLocal(name_handle), | 1600 result = setter(v8::Utils::ToLocal(name_handle), |
1601 v8::Utils::ToLocal(value_unhole), | 1601 v8::Utils::ToLocal(value_unhole), |
1602 info); | 1602 info); |
1603 } | 1603 } |
1604 RETURN_IF_SCHEDULED_EXCEPTION(); | 1604 RETURN_IF_SCHEDULED_EXCEPTION(); |
1605 if (!result.IsEmpty()) return *value_handle; | 1605 if (!result.IsEmpty()) return *value_handle; |
1606 } | 1606 } |
1607 MaybeObject* raw_result = | 1607 MaybeObject* raw_result = |
1608 this_handle->SetPropertyPostInterceptor(*name_handle, | 1608 this_handle->SetPropertyPostInterceptor(*name_handle, |
1609 *value_handle, | 1609 *value_handle, |
1610 attributes, | 1610 attributes, |
1611 strict); | 1611 strict_mode); |
1612 RETURN_IF_SCHEDULED_EXCEPTION(); | 1612 RETURN_IF_SCHEDULED_EXCEPTION(); |
1613 return raw_result; | 1613 return raw_result; |
1614 } | 1614 } |
1615 | 1615 |
1616 | 1616 |
1617 MaybeObject* JSObject::SetProperty(String* name, | 1617 MaybeObject* JSObject::SetProperty(String* name, |
1618 Object* value, | 1618 Object* value, |
1619 PropertyAttributes attributes, | 1619 PropertyAttributes attributes, |
1620 StrictModeFlag strict) { | 1620 StrictModeFlag strict_mode) { |
1621 LookupResult result; | 1621 LookupResult result; |
1622 LocalLookup(name, &result); | 1622 LocalLookup(name, &result); |
1623 return SetProperty(&result, name, value, attributes, strict); | 1623 return SetProperty(&result, name, value, attributes, strict_mode); |
1624 } | 1624 } |
1625 | 1625 |
1626 | 1626 |
1627 MaybeObject* JSObject::SetPropertyWithCallback(Object* structure, | 1627 MaybeObject* JSObject::SetPropertyWithCallback(Object* structure, |
1628 String* name, | 1628 String* name, |
1629 Object* value, | 1629 Object* value, |
1630 JSObject* holder) { | 1630 JSObject* holder) { |
1631 HandleScope scope; | 1631 HandleScope scope; |
1632 | 1632 |
1633 // We should never get here to initialize a const with the hole | 1633 // We should never get here to initialize a const with the hole |
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1894 Handle<Object> value_handle(value); | 1894 Handle<Object> value_handle(value); |
1895 Top::ReportFailedAccessCheck(this, v8::ACCESS_SET); | 1895 Top::ReportFailedAccessCheck(this, v8::ACCESS_SET); |
1896 return *value_handle; | 1896 return *value_handle; |
1897 } | 1897 } |
1898 | 1898 |
1899 | 1899 |
1900 MaybeObject* JSObject::SetProperty(LookupResult* result, | 1900 MaybeObject* JSObject::SetProperty(LookupResult* result, |
1901 String* name, | 1901 String* name, |
1902 Object* value, | 1902 Object* value, |
1903 PropertyAttributes attributes, | 1903 PropertyAttributes attributes, |
1904 StrictModeFlag strict) { | 1904 StrictModeFlag strict_mode) { |
1905 // Make sure that the top context does not change when doing callbacks or | 1905 // Make sure that the top context does not change when doing callbacks or |
1906 // interceptor calls. | 1906 // interceptor calls. |
1907 AssertNoContextChange ncc; | 1907 AssertNoContextChange ncc; |
1908 | 1908 |
1909 // Optimization for 2-byte strings often used as keys in a decompression | 1909 // Optimization for 2-byte strings often used as keys in a decompression |
1910 // dictionary. We make these short keys into symbols to avoid constantly | 1910 // dictionary. We make these short keys into symbols to avoid constantly |
1911 // reallocating them. | 1911 // reallocating them. |
1912 if (!name->IsSymbol() && name->length() <= 2) { | 1912 if (!name->IsSymbol() && name->length() <= 2) { |
1913 Object* symbol_version; | 1913 Object* symbol_version; |
1914 { MaybeObject* maybe_symbol_version = Heap::LookupSymbol(name); | 1914 { MaybeObject* maybe_symbol_version = Heap::LookupSymbol(name); |
1915 if (maybe_symbol_version->ToObject(&symbol_version)) { | 1915 if (maybe_symbol_version->ToObject(&symbol_version)) { |
1916 name = String::cast(symbol_version); | 1916 name = String::cast(symbol_version); |
1917 } | 1917 } |
1918 } | 1918 } |
1919 } | 1919 } |
1920 | 1920 |
1921 // Check access rights if needed. | 1921 // Check access rights if needed. |
1922 if (IsAccessCheckNeeded() | 1922 if (IsAccessCheckNeeded() |
1923 && !Top::MayNamedAccess(this, name, v8::ACCESS_SET)) { | 1923 && !Top::MayNamedAccess(this, name, v8::ACCESS_SET)) { |
1924 return SetPropertyWithFailedAccessCheck(result, name, value, true); | 1924 return SetPropertyWithFailedAccessCheck(result, name, value, true); |
1925 } | 1925 } |
1926 | 1926 |
1927 if (IsJSGlobalProxy()) { | 1927 if (IsJSGlobalProxy()) { |
1928 Object* proto = GetPrototype(); | 1928 Object* proto = GetPrototype(); |
1929 if (proto->IsNull()) return value; | 1929 if (proto->IsNull()) return value; |
1930 ASSERT(proto->IsJSGlobalObject()); | 1930 ASSERT(proto->IsJSGlobalObject()); |
1931 return JSObject::cast(proto)->SetProperty( | 1931 return JSObject::cast(proto)->SetProperty( |
1932 result, name, value, attributes, strict); | 1932 result, name, value, attributes, strict_mode); |
1933 } | 1933 } |
1934 | 1934 |
1935 if (!result->IsProperty() && !IsJSContextExtensionObject()) { | 1935 if (!result->IsProperty() && !IsJSContextExtensionObject()) { |
1936 // We could not find a local property so let's check whether there is an | 1936 // We could not find a local property so let's check whether there is an |
1937 // accessor that wants to handle the property. | 1937 // accessor that wants to handle the property. |
1938 LookupResult accessor_result; | 1938 LookupResult accessor_result; |
1939 LookupCallbackSetterInPrototypes(name, &accessor_result); | 1939 LookupCallbackSetterInPrototypes(name, &accessor_result); |
1940 if (accessor_result.IsProperty()) { | 1940 if (accessor_result.IsProperty()) { |
1941 return SetPropertyWithCallback(accessor_result.GetCallbackObject(), | 1941 return SetPropertyWithCallback(accessor_result.GetCallbackObject(), |
1942 name, | 1942 name, |
1943 value, | 1943 value, |
1944 accessor_result.holder()); | 1944 accessor_result.holder()); |
1945 } | 1945 } |
1946 } | 1946 } |
1947 if (!result->IsFound()) { | 1947 if (!result->IsFound()) { |
1948 // Neither properties nor transitions found. | 1948 // Neither properties nor transitions found. |
1949 return AddProperty(name, value, attributes); | 1949 return AddProperty(name, value, attributes); |
1950 } | 1950 } |
1951 if (result->IsReadOnly() && result->IsProperty()) { | 1951 if (result->IsReadOnly() && result->IsProperty()) { |
1952 if (strict == kStrictMode) { | 1952 if (strict_mode == kStrictMode) { |
1953 HandleScope scope; | 1953 HandleScope scope; |
1954 Handle<String> key(name); | 1954 Handle<String> key(name); |
1955 Handle<Object> holder(this); | 1955 Handle<Object> holder(this); |
1956 Handle<Object> args[2] = { key, holder }; | 1956 Handle<Object> args[2] = { key, holder }; |
1957 return Top::Throw(*Factory::NewTypeError("strict_read_only_property", | 1957 return Top::Throw(*Factory::NewTypeError("strict_read_only_property", |
1958 HandleVector(args, 2))); | 1958 HandleVector(args, 2))); |
1959 | 1959 |
1960 } else { | 1960 } else { |
1961 return value; | 1961 return value; |
1962 } | 1962 } |
(...skipping 18 matching lines...) Expand all Loading... |
1981 if (value == result->GetConstantFunction()) return value; | 1981 if (value == result->GetConstantFunction()) return value; |
1982 // Preserve the attributes of this existing property. | 1982 // Preserve the attributes of this existing property. |
1983 attributes = result->GetAttributes(); | 1983 attributes = result->GetAttributes(); |
1984 return ConvertDescriptorToField(name, value, attributes); | 1984 return ConvertDescriptorToField(name, value, attributes); |
1985 case CALLBACKS: | 1985 case CALLBACKS: |
1986 return SetPropertyWithCallback(result->GetCallbackObject(), | 1986 return SetPropertyWithCallback(result->GetCallbackObject(), |
1987 name, | 1987 name, |
1988 value, | 1988 value, |
1989 result->holder()); | 1989 result->holder()); |
1990 case INTERCEPTOR: | 1990 case INTERCEPTOR: |
1991 return SetPropertyWithInterceptor(name, value, attributes, strict); | 1991 return SetPropertyWithInterceptor(name, value, attributes, strict_mode); |
1992 case CONSTANT_TRANSITION: { | 1992 case CONSTANT_TRANSITION: { |
1993 // If the same constant function is being added we can simply | 1993 // If the same constant function is being added we can simply |
1994 // transition to the target map. | 1994 // transition to the target map. |
1995 Map* target_map = result->GetTransitionMap(); | 1995 Map* target_map = result->GetTransitionMap(); |
1996 DescriptorArray* target_descriptors = target_map->instance_descriptors(); | 1996 DescriptorArray* target_descriptors = target_map->instance_descriptors(); |
1997 int number = target_descriptors->SearchWithCache(name); | 1997 int number = target_descriptors->SearchWithCache(name); |
1998 ASSERT(number != DescriptorArray::kNotFound); | 1998 ASSERT(number != DescriptorArray::kNotFound); |
1999 ASSERT(target_descriptors->GetType(number) == CONSTANT_FUNCTION); | 1999 ASSERT(target_descriptors->GetType(number) == CONSTANT_FUNCTION); |
2000 JSFunction* function = | 2000 JSFunction* function = |
2001 JSFunction::cast(target_descriptors->GetValue(number)); | 2001 JSFunction::cast(target_descriptors->GetValue(number)); |
(...skipping 8033 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10035 if (break_point_objects()->IsUndefined()) return 0; | 10035 if (break_point_objects()->IsUndefined()) return 0; |
10036 // Single beak point. | 10036 // Single beak point. |
10037 if (!break_point_objects()->IsFixedArray()) return 1; | 10037 if (!break_point_objects()->IsFixedArray()) return 1; |
10038 // Multiple break points. | 10038 // Multiple break points. |
10039 return FixedArray::cast(break_point_objects())->length(); | 10039 return FixedArray::cast(break_point_objects())->length(); |
10040 } | 10040 } |
10041 #endif | 10041 #endif |
10042 | 10042 |
10043 | 10043 |
10044 } } // namespace v8::internal | 10044 } } // namespace v8::internal |
OLD | NEW |