| 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 1938 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 == 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 | |
| 1960 } else { | 1959 } else { |
| 1961 return value; | 1960 return value; |
| 1962 } | 1961 } |
| 1963 } | 1962 } |
| 1964 // This is a real property that is not read-only, or it is a | 1963 // This is a real property that is not read-only, or it is a |
| 1965 // transition or null descriptor and there are no setters in the prototypes. | 1964 // transition or null descriptor and there are no setters in the prototypes. |
| 1966 switch (result->type()) { | 1965 switch (result->type()) { |
| 1967 case NORMAL: | 1966 case NORMAL: |
| 1968 return SetNormalizedProperty(result, value); | 1967 return SetNormalizedProperty(result, value); |
| 1969 case FIELD: | 1968 case FIELD: |
| (...skipping 4926 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6896 if (this->IsStringObjectWithCharacterAt(index)) return true; | 6895 if (this->IsStringObjectWithCharacterAt(index)) return true; |
| 6897 | 6896 |
| 6898 Object* pt = GetPrototype(); | 6897 Object* pt = GetPrototype(); |
| 6899 if (pt == Heap::null_value()) return false; | 6898 if (pt == Heap::null_value()) return false; |
| 6900 return JSObject::cast(pt)->HasElementWithReceiver(receiver, index); | 6899 return JSObject::cast(pt)->HasElementWithReceiver(receiver, index); |
| 6901 } | 6900 } |
| 6902 | 6901 |
| 6903 | 6902 |
| 6904 MaybeObject* JSObject::SetElementWithInterceptor(uint32_t index, | 6903 MaybeObject* JSObject::SetElementWithInterceptor(uint32_t index, |
| 6905 Object* value, | 6904 Object* value, |
| 6905 StrictModeFlag strict_mode, |
| 6906 bool check_prototype) { | 6906 bool check_prototype) { |
| 6907 // Make sure that the top context does not change when doing | 6907 // Make sure that the top context does not change when doing |
| 6908 // callbacks or interceptor calls. | 6908 // callbacks or interceptor calls. |
| 6909 AssertNoContextChange ncc; | 6909 AssertNoContextChange ncc; |
| 6910 HandleScope scope; | 6910 HandleScope scope; |
| 6911 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor()); | 6911 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor()); |
| 6912 Handle<JSObject> this_handle(this); | 6912 Handle<JSObject> this_handle(this); |
| 6913 Handle<Object> value_handle(value); | 6913 Handle<Object> value_handle(value); |
| 6914 if (!interceptor->setter()->IsUndefined()) { | 6914 if (!interceptor->setter()->IsUndefined()) { |
| 6915 v8::IndexedPropertySetter setter = | 6915 v8::IndexedPropertySetter setter = |
| 6916 v8::ToCData<v8::IndexedPropertySetter>(interceptor->setter()); | 6916 v8::ToCData<v8::IndexedPropertySetter>(interceptor->setter()); |
| 6917 LOG(ApiIndexedPropertyAccess("interceptor-indexed-set", this, index)); | 6917 LOG(ApiIndexedPropertyAccess("interceptor-indexed-set", this, index)); |
| 6918 CustomArguments args(interceptor->data(), this, this); | 6918 CustomArguments args(interceptor->data(), this, this); |
| 6919 v8::AccessorInfo info(args.end()); | 6919 v8::AccessorInfo info(args.end()); |
| 6920 v8::Handle<v8::Value> result; | 6920 v8::Handle<v8::Value> result; |
| 6921 { | 6921 { |
| 6922 // Leaving JavaScript. | 6922 // Leaving JavaScript. |
| 6923 VMState state(EXTERNAL); | 6923 VMState state(EXTERNAL); |
| 6924 result = setter(index, v8::Utils::ToLocal(value_handle), info); | 6924 result = setter(index, v8::Utils::ToLocal(value_handle), info); |
| 6925 } | 6925 } |
| 6926 RETURN_IF_SCHEDULED_EXCEPTION(); | 6926 RETURN_IF_SCHEDULED_EXCEPTION(); |
| 6927 if (!result.IsEmpty()) return *value_handle; | 6927 if (!result.IsEmpty()) return *value_handle; |
| 6928 } | 6928 } |
| 6929 MaybeObject* raw_result = | 6929 MaybeObject* raw_result = |
| 6930 this_handle->SetElementWithoutInterceptor(index, | 6930 this_handle->SetElementWithoutInterceptor(index, |
| 6931 *value_handle, | 6931 *value_handle, |
| 6932 strict_mode, |
| 6932 check_prototype); | 6933 check_prototype); |
| 6933 RETURN_IF_SCHEDULED_EXCEPTION(); | 6934 RETURN_IF_SCHEDULED_EXCEPTION(); |
| 6934 return raw_result; | 6935 return raw_result; |
| 6935 } | 6936 } |
| 6936 | 6937 |
| 6937 | 6938 |
| 6938 MaybeObject* JSObject::GetElementWithCallback(Object* receiver, | 6939 MaybeObject* JSObject::GetElementWithCallback(Object* receiver, |
| 6939 Object* structure, | 6940 Object* structure, |
| 6940 uint32_t index, | 6941 uint32_t index, |
| 6941 Object* holder) { | 6942 Object* holder) { |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7035 UNREACHABLE(); | 7036 UNREACHABLE(); |
| 7036 return NULL; | 7037 return NULL; |
| 7037 } | 7038 } |
| 7038 | 7039 |
| 7039 | 7040 |
| 7040 // Adding n elements in fast case is O(n*n). | 7041 // Adding n elements in fast case is O(n*n). |
| 7041 // Note: revisit design to have dual undefined values to capture absent | 7042 // Note: revisit design to have dual undefined values to capture absent |
| 7042 // elements. | 7043 // elements. |
| 7043 MaybeObject* JSObject::SetFastElement(uint32_t index, | 7044 MaybeObject* JSObject::SetFastElement(uint32_t index, |
| 7044 Object* value, | 7045 Object* value, |
| 7046 StrictModeFlag strict_mode, |
| 7045 bool check_prototype) { | 7047 bool check_prototype) { |
| 7046 ASSERT(HasFastElements()); | 7048 ASSERT(HasFastElements()); |
| 7047 | 7049 |
| 7048 Object* elms_obj; | 7050 Object* elms_obj; |
| 7049 { MaybeObject* maybe_elms_obj = EnsureWritableFastElements(); | 7051 { MaybeObject* maybe_elms_obj = EnsureWritableFastElements(); |
| 7050 if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj; | 7052 if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj; |
| 7051 } | 7053 } |
| 7052 FixedArray* elms = FixedArray::cast(elms_obj); | 7054 FixedArray* elms = FixedArray::cast(elms_obj); |
| 7053 uint32_t elms_length = static_cast<uint32_t>(elms->length()); | 7055 uint32_t elms_length = static_cast<uint32_t>(elms->length()); |
| 7054 | 7056 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7091 return value; | 7093 return value; |
| 7092 } | 7094 } |
| 7093 } | 7095 } |
| 7094 | 7096 |
| 7095 // Otherwise default to slow case. | 7097 // Otherwise default to slow case. |
| 7096 Object* obj; | 7098 Object* obj; |
| 7097 { MaybeObject* maybe_obj = NormalizeElements(); | 7099 { MaybeObject* maybe_obj = NormalizeElements(); |
| 7098 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 7100 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 7099 } | 7101 } |
| 7100 ASSERT(HasDictionaryElements()); | 7102 ASSERT(HasDictionaryElements()); |
| 7101 return SetElement(index, value, check_prototype); | 7103 return SetElement(index, value, strict_mode, check_prototype); |
| 7102 } | 7104 } |
| 7103 | 7105 |
| 7104 | 7106 |
| 7105 MaybeObject* JSObject::SetElement(uint32_t index, | 7107 MaybeObject* JSObject::SetElement(uint32_t index, |
| 7106 Object* value, | 7108 Object* value, |
| 7109 StrictModeFlag strict_mode, |
| 7107 bool check_prototype) { | 7110 bool check_prototype) { |
| 7108 // Check access rights if needed. | 7111 // Check access rights if needed. |
| 7109 if (IsAccessCheckNeeded() && | 7112 if (IsAccessCheckNeeded() && |
| 7110 !Top::MayIndexedAccess(this, index, v8::ACCESS_SET)) { | 7113 !Top::MayIndexedAccess(this, index, v8::ACCESS_SET)) { |
| 7111 HandleScope scope; | 7114 HandleScope scope; |
| 7112 Handle<Object> value_handle(value); | 7115 Handle<Object> value_handle(value); |
| 7113 Top::ReportFailedAccessCheck(this, v8::ACCESS_SET); | 7116 Top::ReportFailedAccessCheck(this, v8::ACCESS_SET); |
| 7114 return *value_handle; | 7117 return *value_handle; |
| 7115 } | 7118 } |
| 7116 | 7119 |
| 7117 if (IsJSGlobalProxy()) { | 7120 if (IsJSGlobalProxy()) { |
| 7118 Object* proto = GetPrototype(); | 7121 Object* proto = GetPrototype(); |
| 7119 if (proto->IsNull()) return value; | 7122 if (proto->IsNull()) return value; |
| 7120 ASSERT(proto->IsJSGlobalObject()); | 7123 ASSERT(proto->IsJSGlobalObject()); |
| 7121 return JSObject::cast(proto)->SetElement(index, value, check_prototype); | 7124 return JSObject::cast(proto)->SetElement(index, |
| 7125 value, |
| 7126 strict_mode, |
| 7127 check_prototype); |
| 7122 } | 7128 } |
| 7123 | 7129 |
| 7124 // Check for lookup interceptor | 7130 // Check for lookup interceptor |
| 7125 if (HasIndexedInterceptor()) { | 7131 if (HasIndexedInterceptor()) { |
| 7126 return SetElementWithInterceptor(index, value, check_prototype); | 7132 return SetElementWithInterceptor(index, |
| 7133 value, |
| 7134 strict_mode, |
| 7135 check_prototype); |
| 7127 } | 7136 } |
| 7128 | 7137 |
| 7129 return SetElementWithoutInterceptor(index, value, check_prototype); | 7138 return SetElementWithoutInterceptor(index, |
| 7139 value, |
| 7140 strict_mode, |
| 7141 check_prototype); |
| 7130 } | 7142 } |
| 7131 | 7143 |
| 7132 | 7144 |
| 7133 MaybeObject* JSObject::SetElementWithoutInterceptor(uint32_t index, | 7145 MaybeObject* JSObject::SetElementWithoutInterceptor(uint32_t index, |
| 7134 Object* value, | 7146 Object* value, |
| 7147 StrictModeFlag strict_mode, |
| 7135 bool check_prototype) { | 7148 bool check_prototype) { |
| 7136 switch (GetElementsKind()) { | 7149 switch (GetElementsKind()) { |
| 7137 case FAST_ELEMENTS: | 7150 case FAST_ELEMENTS: |
| 7138 // Fast case. | 7151 // Fast case. |
| 7139 return SetFastElement(index, value, check_prototype); | 7152 return SetFastElement(index, value, strict_mode, check_prototype); |
| 7140 case PIXEL_ELEMENTS: { | 7153 case PIXEL_ELEMENTS: { |
| 7141 PixelArray* pixels = PixelArray::cast(elements()); | 7154 PixelArray* pixels = PixelArray::cast(elements()); |
| 7142 return pixels->SetValue(index, value); | 7155 return pixels->SetValue(index, value); |
| 7143 } | 7156 } |
| 7144 case EXTERNAL_BYTE_ELEMENTS: { | 7157 case EXTERNAL_BYTE_ELEMENTS: { |
| 7145 ExternalByteArray* array = ExternalByteArray::cast(elements()); | 7158 ExternalByteArray* array = ExternalByteArray::cast(elements()); |
| 7146 return array->SetValue(index, value); | 7159 return array->SetValue(index, value); |
| 7147 } | 7160 } |
| 7148 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: { | 7161 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: { |
| 7149 ExternalUnsignedByteArray* array = | 7162 ExternalUnsignedByteArray* array = |
| (...skipping 28 matching lines...) Expand all Loading... |
| 7178 NumberDictionary* dictionary = NumberDictionary::cast(elms); | 7191 NumberDictionary* dictionary = NumberDictionary::cast(elms); |
| 7179 | 7192 |
| 7180 int entry = dictionary->FindEntry(index); | 7193 int entry = dictionary->FindEntry(index); |
| 7181 if (entry != NumberDictionary::kNotFound) { | 7194 if (entry != NumberDictionary::kNotFound) { |
| 7182 Object* element = dictionary->ValueAt(entry); | 7195 Object* element = dictionary->ValueAt(entry); |
| 7183 PropertyDetails details = dictionary->DetailsAt(entry); | 7196 PropertyDetails details = dictionary->DetailsAt(entry); |
| 7184 if (details.type() == CALLBACKS) { | 7197 if (details.type() == CALLBACKS) { |
| 7185 return SetElementWithCallback(element, index, value, this); | 7198 return SetElementWithCallback(element, index, value, this); |
| 7186 } else { | 7199 } else { |
| 7187 dictionary->UpdateMaxNumberKey(index); | 7200 dictionary->UpdateMaxNumberKey(index); |
| 7188 dictionary->ValueAtPut(entry, value); | 7201 // If put fails instrict mode, throw exception. |
| 7202 if (!dictionary->ValueAtPut(entry, value) && |
| 7203 strict_mode == kStrictMode) { |
| 7204 Handle<Object> number(Factory::NewNumberFromUint(index)); |
| 7205 Handle<Object> holder(this); |
| 7206 Handle<Object> args[2] = { number, holder }; |
| 7207 return Top::Throw( |
| 7208 *Factory::NewTypeError("strict_read_only_property", |
| 7209 HandleVector(args, 2))); |
| 7210 } |
| 7189 } | 7211 } |
| 7190 } else { | 7212 } else { |
| 7191 // Index not already used. Look for an accessor in the prototype chain. | 7213 // Index not already used. Look for an accessor in the prototype chain. |
| 7192 if (check_prototype) { | 7214 if (check_prototype) { |
| 7193 bool found; | 7215 bool found; |
| 7194 MaybeObject* result = | 7216 MaybeObject* result = |
| 7217 // Strict mode not needed. No-setter case already handled. |
| 7195 SetElementWithCallbackSetterInPrototypes(index, value, &found); | 7218 SetElementWithCallbackSetterInPrototypes(index, value, &found); |
| 7196 if (found) return result; | 7219 if (found) return result; |
| 7197 } | 7220 } |
| 7198 // When we set the is_extensible flag to false we always force | 7221 // When we set the is_extensible flag to false we always force |
| 7199 // the element into dictionary mode (and force them to stay there). | 7222 // the element into dictionary mode (and force them to stay there). |
| 7200 if (!map()->is_extensible()) { | 7223 if (!map()->is_extensible()) { |
| 7201 Handle<Object> number(Factory::NewNumberFromUint(index)); | 7224 Handle<Object> number(Factory::NewNumberFromUint(index)); |
| 7202 Handle<String> index_string(Factory::NumberToString(number)); | 7225 Handle<String> index_string(Factory::NumberToString(number)); |
| 7203 Handle<Object> args[1] = { index_string }; | 7226 Handle<Object> args[1] = { index_string }; |
| 7204 return Top::Throw(*Factory::NewTypeError("object_not_extensible", | 7227 return Top::Throw(*Factory::NewTypeError("object_not_extensible", |
| (...skipping 2830 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10035 if (break_point_objects()->IsUndefined()) return 0; | 10058 if (break_point_objects()->IsUndefined()) return 0; |
| 10036 // Single beak point. | 10059 // Single beak point. |
| 10037 if (!break_point_objects()->IsFixedArray()) return 1; | 10060 if (!break_point_objects()->IsFixedArray()) return 1; |
| 10038 // Multiple break points. | 10061 // Multiple break points. |
| 10039 return FixedArray::cast(break_point_objects())->length(); | 10062 return FixedArray::cast(break_point_objects())->length(); |
| 10040 } | 10063 } |
| 10041 #endif | 10064 #endif |
| 10042 | 10065 |
| 10043 | 10066 |
| 10044 } } // namespace v8::internal | 10067 } } // namespace v8::internal |
| OLD | NEW |