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 1426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1437 } | 1437 } |
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 // Check local property, ignore interceptor. | 1449 // Check local property, ignore interceptor. |
1449 LookupResult result; | 1450 LookupResult result; |
1450 LocalLookupRealNamedProperty(name, &result); | 1451 LocalLookupRealNamedProperty(name, &result); |
1451 if (result.IsFound()) { | 1452 if (result.IsFound()) { |
1452 // An existing property, a map transition or a null descriptor was | 1453 // An existing property, a map transition or a null descriptor was |
1453 // found. Use set property to handle all these cases. | 1454 // found. Use set property to handle all these cases. |
1454 return SetProperty(&result, name, value, attributes); | 1455 return SetProperty(&result, name, value, attributes, strict); |
1455 } | 1456 } |
1456 // Add a new real property. | 1457 // Add a new real property. |
1457 return AddProperty(name, value, attributes); | 1458 return AddProperty(name, value, attributes); |
1458 } | 1459 } |
1459 | 1460 |
1460 | 1461 |
1461 MaybeObject* JSObject::ReplaceSlowProperty(String* name, | 1462 MaybeObject* JSObject::ReplaceSlowProperty(String* name, |
1462 Object* value, | 1463 Object* value, |
1463 PropertyAttributes attributes) { | 1464 PropertyAttributes attributes) { |
1464 StringDictionary* dictionary = property_dictionary(); | 1465 StringDictionary* dictionary = property_dictionary(); |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1569 set_properties(FixedArray::cast(new_properties)); | 1570 set_properties(FixedArray::cast(new_properties)); |
1570 } | 1571 } |
1571 return FastPropertyAtPut(index, new_value); | 1572 return FastPropertyAtPut(index, new_value); |
1572 } | 1573 } |
1573 | 1574 |
1574 | 1575 |
1575 | 1576 |
1576 MaybeObject* JSObject::SetPropertyWithInterceptor( | 1577 MaybeObject* JSObject::SetPropertyWithInterceptor( |
1577 String* name, | 1578 String* name, |
1578 Object* value, | 1579 Object* value, |
1579 PropertyAttributes attributes) { | 1580 PropertyAttributes attributes, |
| 1581 StrictModeFlag strict) { |
1580 HandleScope scope; | 1582 HandleScope scope; |
1581 Handle<JSObject> this_handle(this); | 1583 Handle<JSObject> this_handle(this); |
1582 Handle<String> name_handle(name); | 1584 Handle<String> name_handle(name); |
1583 Handle<Object> value_handle(value); | 1585 Handle<Object> value_handle(value); |
1584 Handle<InterceptorInfo> interceptor(GetNamedInterceptor()); | 1586 Handle<InterceptorInfo> interceptor(GetNamedInterceptor()); |
1585 if (!interceptor->setter()->IsUndefined()) { | 1587 if (!interceptor->setter()->IsUndefined()) { |
1586 LOG(ApiNamedPropertyAccess("interceptor-named-set", this, name)); | 1588 LOG(ApiNamedPropertyAccess("interceptor-named-set", this, name)); |
1587 CustomArguments args(interceptor->data(), this, this); | 1589 CustomArguments args(interceptor->data(), this, this); |
1588 v8::AccessorInfo info(args.end()); | 1590 v8::AccessorInfo info(args.end()); |
1589 v8::NamedPropertySetter setter = | 1591 v8::NamedPropertySetter setter = |
1590 v8::ToCData<v8::NamedPropertySetter>(interceptor->setter()); | 1592 v8::ToCData<v8::NamedPropertySetter>(interceptor->setter()); |
1591 v8::Handle<v8::Value> result; | 1593 v8::Handle<v8::Value> result; |
1592 { | 1594 { |
1593 // Leaving JavaScript. | 1595 // Leaving JavaScript. |
1594 VMState state(EXTERNAL); | 1596 VMState state(EXTERNAL); |
1595 Handle<Object> value_unhole(value->IsTheHole() ? | 1597 Handle<Object> value_unhole(value->IsTheHole() ? |
1596 Heap::undefined_value() : | 1598 Heap::undefined_value() : |
1597 value); | 1599 value); |
1598 result = setter(v8::Utils::ToLocal(name_handle), | 1600 result = setter(v8::Utils::ToLocal(name_handle), |
1599 v8::Utils::ToLocal(value_unhole), | 1601 v8::Utils::ToLocal(value_unhole), |
1600 info); | 1602 info); |
1601 } | 1603 } |
1602 RETURN_IF_SCHEDULED_EXCEPTION(); | 1604 RETURN_IF_SCHEDULED_EXCEPTION(); |
1603 if (!result.IsEmpty()) return *value_handle; | 1605 if (!result.IsEmpty()) return *value_handle; |
1604 } | 1606 } |
1605 MaybeObject* raw_result = | 1607 MaybeObject* raw_result = |
1606 this_handle->SetPropertyPostInterceptor(*name_handle, | 1608 this_handle->SetPropertyPostInterceptor(*name_handle, |
1607 *value_handle, | 1609 *value_handle, |
1608 attributes); | 1610 attributes, |
| 1611 strict); |
1609 RETURN_IF_SCHEDULED_EXCEPTION(); | 1612 RETURN_IF_SCHEDULED_EXCEPTION(); |
1610 return raw_result; | 1613 return raw_result; |
1611 } | 1614 } |
1612 | 1615 |
1613 | 1616 |
1614 MaybeObject* JSObject::SetProperty(String* name, | 1617 MaybeObject* JSObject::SetProperty(String* name, |
1615 Object* value, | 1618 Object* value, |
1616 PropertyAttributes attributes) { | 1619 PropertyAttributes attributes, |
| 1620 StrictModeFlag strict) { |
1617 LookupResult result; | 1621 LookupResult result; |
1618 LocalLookup(name, &result); | 1622 LocalLookup(name, &result); |
1619 return SetProperty(&result, name, value, attributes); | 1623 return SetProperty(&result, name, value, attributes, strict); |
1620 } | 1624 } |
1621 | 1625 |
1622 | 1626 |
1623 MaybeObject* JSObject::SetPropertyWithCallback(Object* structure, | 1627 MaybeObject* JSObject::SetPropertyWithCallback(Object* structure, |
1624 String* name, | 1628 String* name, |
1625 Object* value, | 1629 Object* value, |
1626 JSObject* holder) { | 1630 JSObject* holder) { |
1627 HandleScope scope; | 1631 HandleScope scope; |
1628 | 1632 |
1629 // 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 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1889 HandleScope scope; | 1893 HandleScope scope; |
1890 Handle<Object> value_handle(value); | 1894 Handle<Object> value_handle(value); |
1891 Top::ReportFailedAccessCheck(this, v8::ACCESS_SET); | 1895 Top::ReportFailedAccessCheck(this, v8::ACCESS_SET); |
1892 return *value_handle; | 1896 return *value_handle; |
1893 } | 1897 } |
1894 | 1898 |
1895 | 1899 |
1896 MaybeObject* JSObject::SetProperty(LookupResult* result, | 1900 MaybeObject* JSObject::SetProperty(LookupResult* result, |
1897 String* name, | 1901 String* name, |
1898 Object* value, | 1902 Object* value, |
1899 PropertyAttributes attributes) { | 1903 PropertyAttributes attributes, |
| 1904 StrictModeFlag strict) { |
1900 // 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 |
1901 // interceptor calls. | 1906 // interceptor calls. |
1902 AssertNoContextChange ncc; | 1907 AssertNoContextChange ncc; |
1903 | 1908 |
1904 // 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 |
1905 // dictionary. We make these short keys into symbols to avoid constantly | 1910 // dictionary. We make these short keys into symbols to avoid constantly |
1906 // reallocating them. | 1911 // reallocating them. |
1907 if (!name->IsSymbol() && name->length() <= 2) { | 1912 if (!name->IsSymbol() && name->length() <= 2) { |
1908 Object* symbol_version; | 1913 Object* symbol_version; |
1909 { MaybeObject* maybe_symbol_version = Heap::LookupSymbol(name); | 1914 { MaybeObject* maybe_symbol_version = Heap::LookupSymbol(name); |
1910 if (maybe_symbol_version->ToObject(&symbol_version)) { | 1915 if (maybe_symbol_version->ToObject(&symbol_version)) { |
1911 name = String::cast(symbol_version); | 1916 name = String::cast(symbol_version); |
1912 } | 1917 } |
1913 } | 1918 } |
1914 } | 1919 } |
1915 | 1920 |
1916 // Check access rights if needed. | 1921 // Check access rights if needed. |
1917 if (IsAccessCheckNeeded() | 1922 if (IsAccessCheckNeeded() |
1918 && !Top::MayNamedAccess(this, name, v8::ACCESS_SET)) { | 1923 && !Top::MayNamedAccess(this, name, v8::ACCESS_SET)) { |
1919 return SetPropertyWithFailedAccessCheck(result, name, value, true); | 1924 return SetPropertyWithFailedAccessCheck(result, name, value, true); |
1920 } | 1925 } |
1921 | 1926 |
1922 if (IsJSGlobalProxy()) { | 1927 if (IsJSGlobalProxy()) { |
1923 Object* proto = GetPrototype(); | 1928 Object* proto = GetPrototype(); |
1924 if (proto->IsNull()) return value; | 1929 if (proto->IsNull()) return value; |
1925 ASSERT(proto->IsJSGlobalObject()); | 1930 ASSERT(proto->IsJSGlobalObject()); |
1926 return JSObject::cast(proto)->SetProperty(result, name, value, attributes); | 1931 return JSObject::cast(proto)->SetProperty( |
| 1932 result, name, value, attributes, strict); |
1927 } | 1933 } |
1928 | 1934 |
1929 if (!result->IsProperty() && !IsJSContextExtensionObject()) { | 1935 if (!result->IsProperty() && !IsJSContextExtensionObject()) { |
1930 // 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 |
1931 // accessor that wants to handle the property. | 1937 // accessor that wants to handle the property. |
1932 LookupResult accessor_result; | 1938 LookupResult accessor_result; |
1933 LookupCallbackSetterInPrototypes(name, &accessor_result); | 1939 LookupCallbackSetterInPrototypes(name, &accessor_result); |
1934 if (accessor_result.IsProperty()) { | 1940 if (accessor_result.IsProperty()) { |
1935 return SetPropertyWithCallback(accessor_result.GetCallbackObject(), | 1941 return SetPropertyWithCallback(accessor_result.GetCallbackObject(), |
1936 name, | 1942 name, |
1937 value, | 1943 value, |
1938 accessor_result.holder()); | 1944 accessor_result.holder()); |
1939 } | 1945 } |
1940 } | 1946 } |
1941 if (!result->IsFound()) { | 1947 if (!result->IsFound()) { |
1942 // Neither properties nor transitions found. | 1948 // Neither properties nor transitions found. |
1943 return AddProperty(name, value, attributes); | 1949 return AddProperty(name, value, attributes); |
1944 } | 1950 } |
1945 if (result->IsReadOnly() && result->IsProperty()) return value; | 1951 if (result->IsReadOnly() && result->IsProperty()) { |
| 1952 if (strict == kStrictMode) { |
| 1953 HandleScope scope; |
| 1954 Handle<String> key(name); |
| 1955 Handle<Object> holder(this); |
| 1956 Handle<Object> args[2] = { key, holder }; |
| 1957 return Top::Throw(*Factory::NewTypeError("strict_read_only_property", |
| 1958 HandleVector(args, 2))); |
| 1959 |
| 1960 } else { |
| 1961 return value; |
| 1962 } |
| 1963 } |
1946 // This is a real property that is not read-only, or it is a | 1964 // This is a real property that is not read-only, or it is a |
1947 // transition or null descriptor and there are no setters in the prototypes. | 1965 // transition or null descriptor and there are no setters in the prototypes. |
1948 switch (result->type()) { | 1966 switch (result->type()) { |
1949 case NORMAL: | 1967 case NORMAL: |
1950 return SetNormalizedProperty(result, value); | 1968 return SetNormalizedProperty(result, value); |
1951 case FIELD: | 1969 case FIELD: |
1952 return FastPropertyAtPut(result->GetFieldIndex(), value); | 1970 return FastPropertyAtPut(result->GetFieldIndex(), value); |
1953 case MAP_TRANSITION: | 1971 case MAP_TRANSITION: |
1954 if (attributes == result->GetAttributes()) { | 1972 if (attributes == result->GetAttributes()) { |
1955 // Only use map transition if the attributes match. | 1973 // Only use map transition if the attributes match. |
1956 return AddFastPropertyUsingMap(result->GetTransitionMap(), | 1974 return AddFastPropertyUsingMap(result->GetTransitionMap(), |
1957 name, | 1975 name, |
1958 value); | 1976 value); |
1959 } | 1977 } |
1960 return ConvertDescriptorToField(name, value, attributes); | 1978 return ConvertDescriptorToField(name, value, attributes); |
1961 case CONSTANT_FUNCTION: | 1979 case CONSTANT_FUNCTION: |
1962 // Only replace the function if necessary. | 1980 // Only replace the function if necessary. |
1963 if (value == result->GetConstantFunction()) return value; | 1981 if (value == result->GetConstantFunction()) return value; |
1964 // Preserve the attributes of this existing property. | 1982 // Preserve the attributes of this existing property. |
1965 attributes = result->GetAttributes(); | 1983 attributes = result->GetAttributes(); |
1966 return ConvertDescriptorToField(name, value, attributes); | 1984 return ConvertDescriptorToField(name, value, attributes); |
1967 case CALLBACKS: | 1985 case CALLBACKS: |
1968 return SetPropertyWithCallback(result->GetCallbackObject(), | 1986 return SetPropertyWithCallback(result->GetCallbackObject(), |
1969 name, | 1987 name, |
1970 value, | 1988 value, |
1971 result->holder()); | 1989 result->holder()); |
1972 case INTERCEPTOR: | 1990 case INTERCEPTOR: |
1973 return SetPropertyWithInterceptor(name, value, attributes); | 1991 return SetPropertyWithInterceptor(name, value, attributes, strict); |
1974 case CONSTANT_TRANSITION: { | 1992 case CONSTANT_TRANSITION: { |
1975 // If the same constant function is being added we can simply | 1993 // If the same constant function is being added we can simply |
1976 // transition to the target map. | 1994 // transition to the target map. |
1977 Map* target_map = result->GetTransitionMap(); | 1995 Map* target_map = result->GetTransitionMap(); |
1978 DescriptorArray* target_descriptors = target_map->instance_descriptors(); | 1996 DescriptorArray* target_descriptors = target_map->instance_descriptors(); |
1979 int number = target_descriptors->SearchWithCache(name); | 1997 int number = target_descriptors->SearchWithCache(name); |
1980 ASSERT(number != DescriptorArray::kNotFound); | 1998 ASSERT(number != DescriptorArray::kNotFound); |
1981 ASSERT(target_descriptors->GetType(number) == CONSTANT_FUNCTION); | 1999 ASSERT(target_descriptors->GetType(number) == CONSTANT_FUNCTION); |
1982 JSFunction* function = | 2000 JSFunction* function = |
1983 JSFunction::cast(target_descriptors->GetValue(number)); | 2001 JSFunction::cast(target_descriptors->GetValue(number)); |
(...skipping 4296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6280 | 6298 |
6281 void Code::PrintExtraICState(FILE* out, Kind kind, ExtraICState extra) { | 6299 void Code::PrintExtraICState(FILE* out, Kind kind, ExtraICState extra) { |
6282 const char* name = NULL; | 6300 const char* name = NULL; |
6283 switch (kind) { | 6301 switch (kind) { |
6284 case CALL_IC: | 6302 case CALL_IC: |
6285 if (extra == STRING_INDEX_OUT_OF_BOUNDS) { | 6303 if (extra == STRING_INDEX_OUT_OF_BOUNDS) { |
6286 name = "STRING_INDEX_OUT_OF_BOUNDS"; | 6304 name = "STRING_INDEX_OUT_OF_BOUNDS"; |
6287 } | 6305 } |
6288 break; | 6306 break; |
6289 case STORE_IC: | 6307 case STORE_IC: |
6290 if (extra == StoreIC::kStoreICStrict) { | 6308 case KEYED_STORE_IC: |
| 6309 if (extra == kStrictMode) { |
6291 name = "STRICT"; | 6310 name = "STRICT"; |
6292 } | 6311 } |
6293 break; | 6312 break; |
6294 default: | 6313 default: |
6295 break; | 6314 break; |
6296 } | 6315 } |
6297 if (name != NULL) { | 6316 if (name != NULL) { |
6298 PrintF(out, "extra_ic_state = %s\n", name); | 6317 PrintF(out, "extra_ic_state = %s\n", name); |
6299 } else { | 6318 } else { |
6300 PrintF(out, "etra_ic_state = %d\n", extra); | 6319 PrintF(out, "etra_ic_state = %d\n", extra); |
(...skipping 3715 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10016 if (break_point_objects()->IsUndefined()) return 0; | 10035 if (break_point_objects()->IsUndefined()) return 0; |
10017 // Single beak point. | 10036 // Single beak point. |
10018 if (!break_point_objects()->IsFixedArray()) return 1; | 10037 if (!break_point_objects()->IsFixedArray()) return 1; |
10019 // Multiple break points. | 10038 // Multiple break points. |
10020 return FixedArray::cast(break_point_objects())->length(); | 10039 return FixedArray::cast(break_point_objects())->length(); |
10021 } | 10040 } |
10022 #endif | 10041 #endif |
10023 | 10042 |
10024 | 10043 |
10025 } } // namespace v8::internal | 10044 } } // namespace v8::internal |
OLD | NEW |