Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(180)

Side by Side Diff: src/objects.cc

Issue 6576024: (early draft) Strict mode - throw exception on assignment to read only property. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Assign to read only property in strict mode. Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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_rdonly_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
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
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
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698