| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 10124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10135 ASSERT(elements()->IsFixedArray()); | 10135 ASSERT(elements()->IsFixedArray()); |
| 10136 backing_store->set(index, value); | 10136 backing_store->set(index, value); |
| 10137 if (must_update_array_length) { | 10137 if (must_update_array_length) { |
| 10138 JSArray::cast(this)->set_length(Smi::FromInt(array_length)); | 10138 JSArray::cast(this)->set_length(Smi::FromInt(array_length)); |
| 10139 } | 10139 } |
| 10140 return value; | 10140 return value; |
| 10141 } | 10141 } |
| 10142 | 10142 |
| 10143 | 10143 |
| 10144 MaybeObject* JSObject::SetDictionaryElement(uint32_t index, | 10144 MaybeObject* JSObject::SetDictionaryElement(uint32_t index, |
| 10145 Object* value, | 10145 Object* value_raw, |
| 10146 PropertyAttributes attributes, | 10146 PropertyAttributes attributes, |
| 10147 StrictModeFlag strict_mode, | 10147 StrictModeFlag strict_mode, |
| 10148 bool check_prototype, | 10148 bool check_prototype, |
| 10149 SetPropertyMode set_mode) { | 10149 SetPropertyMode set_mode) { |
| 10150 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements()); | 10150 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements()); |
| 10151 Isolate* isolate = GetIsolate(); | 10151 Isolate* isolate = GetIsolate(); |
| 10152 Heap* heap = isolate->heap(); | 10152 Heap* heap = isolate->heap(); |
| 10153 Handle<JSObject> self(this); |
| 10154 Handle<Object> value(value_raw); |
| 10153 | 10155 |
| 10154 // Insert element in the dictionary. | 10156 // Insert element in the dictionary. |
| 10155 FixedArray* elements = FixedArray::cast(this->elements()); | 10157 Handle<FixedArray> elements(FixedArray::cast(this->elements())); |
| 10156 bool is_arguments = | 10158 bool is_arguments = |
| 10157 (elements->map() == heap->non_strict_arguments_elements_map()); | 10159 (elements->map() == heap->non_strict_arguments_elements_map()); |
| 10158 SeededNumberDictionary* dictionary = NULL; | 10160 Handle<SeededNumberDictionary> dictionary(is_arguments |
| 10159 if (is_arguments) { | 10161 ? SeededNumberDictionary::cast(elements->get(1)) |
| 10160 dictionary = SeededNumberDictionary::cast(elements->get(1)); | 10162 : SeededNumberDictionary::cast(*elements)); |
| 10161 } else { | |
| 10162 dictionary = SeededNumberDictionary::cast(elements); | |
| 10163 } | |
| 10164 | 10163 |
| 10165 int entry = dictionary->FindEntry(index); | 10164 int entry = dictionary->FindEntry(index); |
| 10166 if (entry != SeededNumberDictionary::kNotFound) { | 10165 if (entry != SeededNumberDictionary::kNotFound) { |
| 10167 Object* element = dictionary->ValueAt(entry); | 10166 Object* element = dictionary->ValueAt(entry); |
| 10168 PropertyDetails details = dictionary->DetailsAt(entry); | 10167 PropertyDetails details = dictionary->DetailsAt(entry); |
| 10169 if (details.type() == CALLBACKS && set_mode == SET_PROPERTY) { | 10168 if (details.type() == CALLBACKS && set_mode == SET_PROPERTY) { |
| 10170 return SetElementWithCallback(element, index, value, this, strict_mode); | 10169 return SetElementWithCallback(element, index, *value, this, strict_mode); |
| 10171 } else { | 10170 } else { |
| 10172 dictionary->UpdateMaxNumberKey(index); | 10171 dictionary->UpdateMaxNumberKey(index); |
| 10173 // If a value has not been initialized we allow writing to it even if it | 10172 // If a value has not been initialized we allow writing to it even if it |
| 10174 // is read-only (a declared const that has not been initialized). If a | 10173 // is read-only (a declared const that has not been initialized). If a |
| 10175 // value is being defined we skip attribute checks completely. | 10174 // value is being defined we skip attribute checks completely. |
| 10176 if (set_mode == DEFINE_PROPERTY) { | 10175 if (set_mode == DEFINE_PROPERTY) { |
| 10177 details = PropertyDetails( | 10176 details = PropertyDetails( |
| 10178 attributes, NORMAL, details.dictionary_index()); | 10177 attributes, NORMAL, details.dictionary_index()); |
| 10179 dictionary->DetailsAtPut(entry, details); | 10178 dictionary->DetailsAtPut(entry, details); |
| 10180 } else if (details.IsReadOnly() && !element->IsTheHole()) { | 10179 } else if (details.IsReadOnly() && !element->IsTheHole()) { |
| 10181 if (strict_mode == kNonStrictMode) { | 10180 if (strict_mode == kNonStrictMode) { |
| 10182 return isolate->heap()->undefined_value(); | 10181 return isolate->heap()->undefined_value(); |
| 10183 } else { | 10182 } else { |
| 10184 Handle<Object> holder(this); | 10183 Handle<Object> holder(this); |
| 10185 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); | 10184 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); |
| 10186 Handle<Object> args[2] = { number, holder }; | 10185 Handle<Object> args[2] = { number, holder }; |
| 10187 Handle<Object> error = | 10186 Handle<Object> error = |
| 10188 isolate->factory()->NewTypeError("strict_read_only_property", | 10187 isolate->factory()->NewTypeError("strict_read_only_property", |
| 10189 HandleVector(args, 2)); | 10188 HandleVector(args, 2)); |
| 10190 return isolate->Throw(*error); | 10189 return isolate->Throw(*error); |
| 10191 } | 10190 } |
| 10192 } | 10191 } |
| 10193 // Elements of the arguments object in slow mode might be slow aliases. | 10192 // Elements of the arguments object in slow mode might be slow aliases. |
| 10194 if (is_arguments && element->IsAliasedArgumentsEntry()) { | 10193 if (is_arguments && element->IsAliasedArgumentsEntry()) { |
| 10195 AliasedArgumentsEntry* entry = AliasedArgumentsEntry::cast(element); | 10194 AliasedArgumentsEntry* entry = AliasedArgumentsEntry::cast(element); |
| 10196 Context* context = Context::cast(elements->get(0)); | 10195 Context* context = Context::cast(elements->get(0)); |
| 10197 int context_index = entry->aliased_context_slot(); | 10196 int context_index = entry->aliased_context_slot(); |
| 10198 ASSERT(!context->get(context_index)->IsTheHole()); | 10197 ASSERT(!context->get(context_index)->IsTheHole()); |
| 10199 context->set(context_index, value); | 10198 context->set(context_index, *value); |
| 10200 // For elements that are still writable we keep slow aliasing. | 10199 // For elements that are still writable we keep slow aliasing. |
| 10201 if (!details.IsReadOnly()) value = element; | 10200 if (!details.IsReadOnly()) value = handle(element, isolate); |
| 10202 } | 10201 } |
| 10203 dictionary->ValueAtPut(entry, value); | 10202 dictionary->ValueAtPut(entry, *value); |
| 10204 } | 10203 } |
| 10205 } else { | 10204 } else { |
| 10206 // Index not already used. Look for an accessor in the prototype chain. | 10205 // Index not already used. Look for an accessor in the prototype chain. |
| 10206 // Can cause GC! |
| 10207 if (check_prototype) { | 10207 if (check_prototype) { |
| 10208 bool found; | 10208 bool found; |
| 10209 MaybeObject* result = | 10209 MaybeObject* result = SetElementWithCallbackSetterInPrototypes( |
| 10210 SetElementWithCallbackSetterInPrototypes( | 10210 index, *value, &found, strict_mode); |
| 10211 index, value, &found, strict_mode); | |
| 10212 if (found) return result; | 10211 if (found) return result; |
| 10213 } | 10212 } |
| 10214 // When we set the is_extensible flag to false we always force the | 10213 // When we set the is_extensible flag to false we always force the |
| 10215 // element into dictionary mode (and force them to stay there). | 10214 // element into dictionary mode (and force them to stay there). |
| 10216 if (!map()->is_extensible()) { | 10215 if (!self->map()->is_extensible()) { |
| 10217 if (strict_mode == kNonStrictMode) { | 10216 if (strict_mode == kNonStrictMode) { |
| 10218 return isolate->heap()->undefined_value(); | 10217 return isolate->heap()->undefined_value(); |
| 10219 } else { | 10218 } else { |
| 10220 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); | 10219 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); |
| 10221 Handle<String> name = isolate->factory()->NumberToString(number); | 10220 Handle<String> name = isolate->factory()->NumberToString(number); |
| 10222 Handle<Object> args[1] = { name }; | 10221 Handle<Object> args[1] = { name }; |
| 10223 Handle<Object> error = | 10222 Handle<Object> error = |
| 10224 isolate->factory()->NewTypeError("object_not_extensible", | 10223 isolate->factory()->NewTypeError("object_not_extensible", |
| 10225 HandleVector(args, 1)); | 10224 HandleVector(args, 1)); |
| 10226 return isolate->Throw(*error); | 10225 return isolate->Throw(*error); |
| 10227 } | 10226 } |
| 10228 } | 10227 } |
| 10229 FixedArrayBase* new_dictionary; | 10228 FixedArrayBase* new_dictionary; |
| 10230 PropertyDetails details = PropertyDetails(attributes, NORMAL); | 10229 PropertyDetails details = PropertyDetails(attributes, NORMAL); |
| 10231 MaybeObject* maybe = dictionary->AddNumberEntry(index, value, details); | 10230 MaybeObject* maybe = dictionary->AddNumberEntry(index, *value, details); |
| 10232 if (!maybe->To(&new_dictionary)) return maybe; | 10231 if (!maybe->To(&new_dictionary)) return maybe; |
| 10233 if (dictionary != SeededNumberDictionary::cast(new_dictionary)) { | 10232 if (*dictionary != SeededNumberDictionary::cast(new_dictionary)) { |
| 10234 if (is_arguments) { | 10233 if (is_arguments) { |
| 10235 elements->set(1, new_dictionary); | 10234 elements->set(1, new_dictionary); |
| 10236 } else { | 10235 } else { |
| 10237 set_elements(new_dictionary); | 10236 self->set_elements(new_dictionary); |
| 10238 } | 10237 } |
| 10239 dictionary = SeededNumberDictionary::cast(new_dictionary); | 10238 dictionary = |
| 10239 handle(SeededNumberDictionary::cast(new_dictionary), isolate); |
| 10240 } | 10240 } |
| 10241 } | 10241 } |
| 10242 | 10242 |
| 10243 // Update the array length if this JSObject is an array. | 10243 // Update the array length if this JSObject is an array. |
| 10244 if (IsJSArray()) { | 10244 if (self->IsJSArray()) { |
| 10245 MaybeObject* result = | 10245 MaybeObject* result = |
| 10246 JSArray::cast(this)->JSArrayUpdateLengthFromIndex(index, value); | 10246 JSArray::cast(*self)->JSArrayUpdateLengthFromIndex(index, *value); |
| 10247 if (result->IsFailure()) return result; | 10247 if (result->IsFailure()) return result; |
| 10248 } | 10248 } |
| 10249 | 10249 |
| 10250 // Attempt to put this object back in fast case. | 10250 // Attempt to put this object back in fast case. |
| 10251 if (ShouldConvertToFastElements()) { | 10251 if (self->ShouldConvertToFastElements()) { |
| 10252 uint32_t new_length = 0; | 10252 uint32_t new_length = 0; |
| 10253 if (IsJSArray()) { | 10253 if (self->IsJSArray()) { |
| 10254 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&new_length)); | 10254 CHECK(JSArray::cast(*self)->length()->ToArrayIndex(&new_length)); |
| 10255 } else { | 10255 } else { |
| 10256 new_length = dictionary->max_number_key() + 1; | 10256 new_length = dictionary->max_number_key() + 1; |
| 10257 } | 10257 } |
| 10258 SetFastElementsCapacitySmiMode smi_mode = FLAG_smi_only_arrays | 10258 SetFastElementsCapacitySmiMode smi_mode = FLAG_smi_only_arrays |
| 10259 ? kAllowSmiElements | 10259 ? kAllowSmiElements |
| 10260 : kDontAllowSmiElements; | 10260 : kDontAllowSmiElements; |
| 10261 bool has_smi_only_elements = false; | 10261 bool has_smi_only_elements = false; |
| 10262 bool should_convert_to_fast_double_elements = | 10262 bool should_convert_to_fast_double_elements = |
| 10263 ShouldConvertToFastDoubleElements(&has_smi_only_elements); | 10263 self->ShouldConvertToFastDoubleElements(&has_smi_only_elements); |
| 10264 if (has_smi_only_elements) { | 10264 if (has_smi_only_elements) { |
| 10265 smi_mode = kForceSmiElements; | 10265 smi_mode = kForceSmiElements; |
| 10266 } | 10266 } |
| 10267 MaybeObject* result = should_convert_to_fast_double_elements | 10267 MaybeObject* result = should_convert_to_fast_double_elements |
| 10268 ? SetFastDoubleElementsCapacityAndLength(new_length, new_length) | 10268 ? self->SetFastDoubleElementsCapacityAndLength(new_length, new_length) |
| 10269 : SetFastElementsCapacityAndLength(new_length, | 10269 : self->SetFastElementsCapacityAndLength( |
| 10270 new_length, | 10270 new_length, new_length, smi_mode); |
| 10271 smi_mode); | 10271 self->ValidateElements(); |
| 10272 ValidateElements(); | |
| 10273 if (result->IsFailure()) return result; | 10272 if (result->IsFailure()) return result; |
| 10274 #ifdef DEBUG | 10273 #ifdef DEBUG |
| 10275 if (FLAG_trace_normalization) { | 10274 if (FLAG_trace_normalization) { |
| 10276 PrintF("Object elements are fast case again:\n"); | 10275 PrintF("Object elements are fast case again:\n"); |
| 10277 Print(); | 10276 Print(); |
| 10278 } | 10277 } |
| 10279 #endif | 10278 #endif |
| 10280 } | 10279 } |
| 10281 return value; | 10280 return *value; |
| 10282 } | 10281 } |
| 10283 | 10282 |
| 10284 | 10283 |
| 10285 MUST_USE_RESULT MaybeObject* JSObject::SetFastDoubleElement( | 10284 MUST_USE_RESULT MaybeObject* JSObject::SetFastDoubleElement( |
| 10286 uint32_t index, | 10285 uint32_t index, |
| 10287 Object* value, | 10286 Object* value, |
| 10288 StrictModeFlag strict_mode, | 10287 StrictModeFlag strict_mode, |
| 10289 bool check_prototype) { | 10288 bool check_prototype) { |
| 10290 ASSERT(HasFastDoubleElements()); | 10289 ASSERT(HasFastDoubleElements()); |
| 10291 | 10290 |
| (...skipping 3740 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14032 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); | 14031 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); |
| 14033 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); | 14032 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); |
| 14034 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); | 14033 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); |
| 14035 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); | 14034 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); |
| 14036 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); | 14035 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); |
| 14037 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); | 14036 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); |
| 14038 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); | 14037 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); |
| 14039 } | 14038 } |
| 14040 | 14039 |
| 14041 } } // namespace v8::internal | 14040 } } // namespace v8::internal |
| OLD | NEW |