Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 2553 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2564 MaybeObject* JSObject::TransformToFastProperties(int unused_property_fields) { | 2564 MaybeObject* JSObject::TransformToFastProperties(int unused_property_fields) { |
| 2565 if (HasFastProperties()) return this; | 2565 if (HasFastProperties()) return this; |
| 2566 ASSERT(!IsGlobalObject()); | 2566 ASSERT(!IsGlobalObject()); |
| 2567 return property_dictionary()-> | 2567 return property_dictionary()-> |
| 2568 TransformPropertiesToFastFor(this, unused_property_fields); | 2568 TransformPropertiesToFastFor(this, unused_property_fields); |
| 2569 } | 2569 } |
| 2570 | 2570 |
| 2571 | 2571 |
| 2572 MaybeObject* JSObject::NormalizeElements() { | 2572 MaybeObject* JSObject::NormalizeElements() { |
| 2573 ASSERT(!HasExternalArrayElements()); | 2573 ASSERT(!HasExternalArrayElements()); |
| 2574 if (HasDictionaryElements() || HasDictionaryArgumentsElements()) { | 2574 // Find the backing store. |
| 2575 return elements(); | 2575 FixedArray* elements = FixedArray::cast(this->elements()); |
| 2576 bool is_arguments = | |
| 2577 (elements->map() == GetHeap()->non_strict_arguments_elements_map()); | |
| 2578 if (is_arguments) { | |
| 2579 elements = FixedArray::cast(elements->get(1)); | |
| 2576 } | 2580 } |
| 2581 if (elements->IsDictionary()) return elements; | |
| 2582 | |
| 2577 ASSERT(HasFastElements() || HasFastArgumentsElements()); | 2583 ASSERT(HasFastElements() || HasFastArgumentsElements()); |
| 2578 // Find the backing store. | |
| 2579 FixedArray* fast_elements = FixedArray::cast(elements()); | |
| 2580 bool is_arguments = | |
| 2581 (fast_elements->map() == GetHeap()->non_strict_arguments_elements_map()); | |
| 2582 if (is_arguments) { | |
| 2583 fast_elements = FixedArray::cast(fast_elements->get(1)); | |
| 2584 } | |
| 2585 | |
| 2586 // Compute the effective length and allocate a new backing store. | 2584 // Compute the effective length and allocate a new backing store. |
| 2587 int length = IsJSArray() | 2585 int length = IsJSArray() |
| 2588 ? Smi::cast(JSArray::cast(this)->length())->value() | 2586 ? Smi::cast(JSArray::cast(this)->length())->value() |
| 2589 : fast_elements->length(); | 2587 : elements->length(); |
| 2590 NumberDictionary* dictionary = NULL; | 2588 NumberDictionary* dictionary = NULL; |
| 2591 { Object* object; | 2589 { Object* object; |
| 2592 MaybeObject* maybe = NumberDictionary::Allocate(length); | 2590 MaybeObject* maybe = NumberDictionary::Allocate(length); |
| 2593 if (!maybe->ToObject(&object)) return maybe; | 2591 if (!maybe->ToObject(&object)) return maybe; |
| 2594 dictionary = NumberDictionary::cast(object); | 2592 dictionary = NumberDictionary::cast(object); |
| 2595 } | 2593 } |
| 2596 | 2594 |
| 2597 // Copy the elements to the new backing store. | 2595 // Copy the elements to the new backing store. |
| 2598 for (int i = 0; i < length; i++) { | 2596 for (int i = 0; i < length; i++) { |
| 2599 Object* value = fast_elements->get(i); | 2597 Object* value = elements->get(i); |
| 2600 if (!value->IsTheHole()) { | 2598 if (!value->IsTheHole()) { |
| 2601 PropertyDetails details = PropertyDetails(NONE, NORMAL); | 2599 PropertyDetails details = PropertyDetails(NONE, NORMAL); |
| 2602 Object* result; | 2600 Object* new_dictionary; |
| 2603 MaybeObject* maybe = | 2601 MaybeObject* maybe = |
| 2604 dictionary->AddNumberEntry(i, fast_elements->get(i), details); | 2602 dictionary->AddNumberEntry(i, elements->get(i), details); |
| 2605 if (!maybe->ToObject(&result)) return maybe; | 2603 if (!maybe->ToObject(&new_dictionary)) return maybe; |
| 2606 dictionary = NumberDictionary::cast(result); | 2604 dictionary = NumberDictionary::cast(new_dictionary); |
| 2607 } | 2605 } |
| 2608 } | 2606 } |
| 2609 | 2607 |
| 2610 // Switch to using the dictionary as the backing storage for elements. | 2608 // Switch to using the dictionary as the backing storage for elements. |
| 2611 if (is_arguments) { | 2609 if (is_arguments) { |
| 2612 FixedArray::cast(elements())->set(1, dictionary); | 2610 FixedArray::cast(this->elements())->set(1, dictionary); |
|
Mads Ager (chromium)
2011/03/30 10:38:37
Why the this-> here?
Kevin Millikin (Chromium)
2011/03/30 10:55:27
I shadowed the elements member function with an id
Mads Ager (chromium)
2011/03/30 11:01:18
That one should be called something else I think.
| |
| 2613 } else { | 2611 } else { |
| 2614 // Set the new map first to satify the elements type assert in | 2612 // Set the new map first to satify the elements type assert in |
| 2615 // set_elements(). | 2613 // set_elements(). |
| 2616 Object* new_map; | 2614 Object* new_map; |
| 2617 MaybeObject* maybe = map()->GetSlowElementsMap(); | 2615 MaybeObject* maybe = map()->GetSlowElementsMap(); |
| 2618 if (!maybe->ToObject(&new_map)) return maybe; | 2616 if (!maybe->ToObject(&new_map)) return maybe; |
| 2619 set_map(Map::cast(new_map)); | 2617 set_map(Map::cast(new_map)); |
| 2620 set_elements(dictionary); | 2618 set_elements(dictionary); |
| 2621 } | 2619 } |
| 2622 | 2620 |
| (...skipping 592 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3215 for (Object* current = this; | 3213 for (Object* current = this; |
| 3216 current != heap->null_value(); | 3214 current != heap->null_value(); |
| 3217 current = JSObject::cast(current)->GetPrototype()) { | 3215 current = JSObject::cast(current)->GetPrototype()) { |
| 3218 JSObject::cast(current)->LocalLookupRealNamedProperty(name, result); | 3216 JSObject::cast(current)->LocalLookupRealNamedProperty(name, result); |
| 3219 if (result->IsProperty() && result->type() == CALLBACKS) return; | 3217 if (result->IsProperty() && result->type() == CALLBACKS) return; |
| 3220 } | 3218 } |
| 3221 result->NotFound(); | 3219 result->NotFound(); |
| 3222 } | 3220 } |
| 3223 | 3221 |
| 3224 | 3222 |
| 3223 // Search for a getter or setter in an elements dictionary. Returns either | |
| 3224 // undefined if the element is read-only, or the getter/setter pair (fixed | |
| 3225 // array) if there is an existing one, or the hole value if the element does | |
| 3226 // not exist or is a normal non-getter/setter data element. | |
| 3227 static Object* FindGetterSetterInDictionary(NumberDictionary* dictionary, | |
| 3228 uint32_t index, | |
| 3229 Heap* heap) { | |
| 3230 int entry = dictionary->FindEntry(index); | |
| 3231 if (entry != NumberDictionary::kNotFound) { | |
| 3232 Object* result = dictionary->ValueAt(entry); | |
| 3233 PropertyDetails details = dictionary->DetailsAt(entry); | |
| 3234 if (details.IsReadOnly()) return heap->undefined_value(); | |
| 3235 if (details.type() == CALLBACKS && result->IsFixedArray()) return result; | |
| 3236 } | |
| 3237 return heap->the_hole_value(); | |
| 3238 } | |
| 3239 | |
| 3240 | |
| 3225 MaybeObject* JSObject::DefineGetterSetter(String* name, | 3241 MaybeObject* JSObject::DefineGetterSetter(String* name, |
| 3226 PropertyAttributes attributes) { | 3242 PropertyAttributes attributes) { |
| 3227 Heap* heap = GetHeap(); | 3243 Heap* heap = GetHeap(); |
| 3228 // Make sure that the top context does not change when doing callbacks or | 3244 // Make sure that the top context does not change when doing callbacks or |
| 3229 // interceptor calls. | 3245 // interceptor calls. |
| 3230 AssertNoContextChange ncc; | 3246 AssertNoContextChange ncc; |
| 3231 | 3247 |
| 3232 // Try to flatten before operating on the string. | 3248 // Try to flatten before operating on the string. |
| 3233 name->TryFlatten(); | 3249 name->TryFlatten(); |
| 3234 | 3250 |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 3248 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 3264 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
| 3249 case EXTERNAL_SHORT_ELEMENTS: | 3265 case EXTERNAL_SHORT_ELEMENTS: |
| 3250 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 3266 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
| 3251 case EXTERNAL_INT_ELEMENTS: | 3267 case EXTERNAL_INT_ELEMENTS: |
| 3252 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | 3268 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
| 3253 case EXTERNAL_FLOAT_ELEMENTS: | 3269 case EXTERNAL_FLOAT_ELEMENTS: |
| 3254 // Ignore getters and setters on pixel and external array | 3270 // Ignore getters and setters on pixel and external array |
| 3255 // elements. | 3271 // elements. |
| 3256 return heap->undefined_value(); | 3272 return heap->undefined_value(); |
| 3257 case DICTIONARY_ELEMENTS: { | 3273 case DICTIONARY_ELEMENTS: { |
| 3258 // Lookup the index. | 3274 Object* probe = |
| 3259 NumberDictionary* dictionary = element_dictionary(); | 3275 FindGetterSetterInDictionary(element_dictionary(), index, heap); |
| 3260 int entry = dictionary->FindEntry(index); | 3276 if (!probe->IsTheHole()) return probe; |
| 3261 if (entry != NumberDictionary::kNotFound) { | 3277 // Otherwise allow to override it. |
| 3262 Object* result = dictionary->ValueAt(entry); | 3278 break; |
| 3263 PropertyDetails details = dictionary->DetailsAt(entry); | 3279 } |
| 3264 if (details.IsReadOnly()) return heap->undefined_value(); | 3280 case NON_STRICT_ARGUMENTS_ELEMENTS: { |
| 3265 if (details.type() == CALLBACKS) { | 3281 // Ascertain whether we have read-only properties or an existing |
| 3266 if (result->IsFixedArray()) { | 3282 // getter/setter pair in an arguments elements dictionary backing |
| 3267 return result; | 3283 // store. |
| 3268 } | 3284 FixedArray* parameter_map = FixedArray::cast(elements()); |
| 3269 // Otherwise allow to override it. | 3285 uint32_t length = parameter_map->length(); |
| 3286 Object* probe = | |
| 3287 (index + 2) < length ? parameter_map->get(index + 2) : NULL; | |
| 3288 if (probe == NULL || probe->IsTheHole()) { | |
| 3289 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); | |
| 3290 if (arguments->IsDictionary()) { | |
| 3291 NumberDictionary* dictionary = NumberDictionary::cast(arguments); | |
| 3292 probe = FindGetterSetterInDictionary(dictionary, index, heap); | |
| 3293 if (!probe->IsTheHole()) return probe; | |
| 3270 } | 3294 } |
| 3271 } | 3295 } |
| 3272 break; | 3296 break; |
| 3273 } | 3297 } |
| 3274 case NON_STRICT_ARGUMENTS_ELEMENTS: | |
| 3275 UNIMPLEMENTED(); | |
| 3276 break; | |
| 3277 } | 3298 } |
| 3278 } else { | 3299 } else { |
| 3279 // Lookup the name. | 3300 // Lookup the name. |
| 3280 LookupResult result; | 3301 LookupResult result; |
| 3281 LocalLookup(name, &result); | 3302 LocalLookup(name, &result); |
| 3282 if (result.IsProperty()) { | 3303 if (result.IsProperty()) { |
| 3283 if (result.IsReadOnly()) return heap->undefined_value(); | 3304 if (result.IsReadOnly()) return heap->undefined_value(); |
| 3284 if (result.type() == CALLBACKS) { | 3305 if (result.type() == CALLBACKS) { |
| 3285 Object* obj = result.GetCallbackObject(); | 3306 Object* obj = result.GetCallbackObject(); |
| 3286 // Need to preserve old getters/setters. | 3307 // Need to preserve old getters/setters. |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3329 return true; | 3350 return true; |
| 3330 } | 3351 } |
| 3331 | 3352 |
| 3332 | 3353 |
| 3333 MaybeObject* JSObject::SetElementCallback(uint32_t index, | 3354 MaybeObject* JSObject::SetElementCallback(uint32_t index, |
| 3334 Object* structure, | 3355 Object* structure, |
| 3335 PropertyAttributes attributes) { | 3356 PropertyAttributes attributes) { |
| 3336 PropertyDetails details = PropertyDetails(attributes, CALLBACKS); | 3357 PropertyDetails details = PropertyDetails(attributes, CALLBACKS); |
| 3337 | 3358 |
| 3338 // Normalize elements to make this operation simple. | 3359 // Normalize elements to make this operation simple. |
| 3339 Object* ok; | 3360 NumberDictionary* dictionary = NULL; |
| 3340 { MaybeObject* maybe_ok = NormalizeElements(); | 3361 { Object* result; |
| 3341 if (!maybe_ok->ToObject(&ok)) return maybe_ok; | 3362 MaybeObject* maybe = NormalizeElements(); |
| 3363 if (!maybe->ToObject(&result)) return maybe; | |
| 3364 dictionary = NumberDictionary::cast(result); | |
| 3342 } | 3365 } |
| 3343 // TODO(kmillikin): Handle arguments object with dictionary elements. | 3366 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements()); |
| 3344 ASSERT(HasDictionaryElements()); | |
| 3345 | 3367 |
| 3346 // Update the dictionary with the new CALLBACKS property. | 3368 // Update the dictionary with the new CALLBACKS property. |
| 3347 Object* dict; | 3369 { Object* result; |
| 3348 { MaybeObject* maybe_dict = | 3370 MaybeObject* maybe = dictionary->Set(index, structure, details); |
| 3349 element_dictionary()->Set(index, structure, details); | 3371 if (!maybe->ToObject(&result)) return maybe; |
| 3350 if (!maybe_dict->ToObject(&dict)) return maybe_dict; | 3372 dictionary = NumberDictionary::cast(result); |
| 3351 } | 3373 } |
| 3352 | 3374 |
| 3353 NumberDictionary* elements = NumberDictionary::cast(dict); | 3375 dictionary->set_requires_slow_elements(); |
| 3354 elements->set_requires_slow_elements(); | 3376 // Update the dictionary backing store on the object. |
| 3355 // Set the potential new dictionary on the object. | 3377 if (elements()->map() == GetHeap()->non_strict_arguments_elements_map()) { |
| 3356 set_elements(elements); | 3378 // Also delete any parameter alias. |
| 3379 // | |
| 3380 // TODO(kmillikin): when deleting the last parameter alias we could | |
| 3381 // switch to a direct backing store without the parameter map. This | |
| 3382 // would allow GC of the context. | |
| 3383 FixedArray* parameter_map = FixedArray::cast(elements()); | |
| 3384 uint32_t length = parameter_map->length(); | |
| 3385 if (index + 2 < length) { | |
| 3386 parameter_map->set(index + 2, GetHeap()->the_hole_value()); | |
| 3387 } | |
| 3388 parameter_map->set(1, dictionary); | |
| 3389 } else { | |
| 3390 set_elements(dictionary); | |
| 3391 } | |
| 3357 | 3392 |
| 3358 return structure; | 3393 return structure; |
| 3359 } | 3394 } |
| 3360 | 3395 |
| 3361 | 3396 |
| 3362 MaybeObject* JSObject::SetPropertyCallback(String* name, | 3397 MaybeObject* JSObject::SetPropertyCallback(String* name, |
| 3363 Object* structure, | 3398 Object* structure, |
| 3364 PropertyAttributes attributes) { | 3399 PropertyAttributes attributes) { |
| 3365 PropertyDetails details = PropertyDetails(attributes, CALLBACKS); | 3400 PropertyDetails details = PropertyDetails(attributes, CALLBACKS); |
| 3366 | 3401 |
| (...skipping 3792 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7159 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 7194 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
| 7160 case EXTERNAL_INT_ELEMENTS: | 7195 case EXTERNAL_INT_ELEMENTS: |
| 7161 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | 7196 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
| 7162 case EXTERNAL_FLOAT_ELEMENTS: { | 7197 case EXTERNAL_FLOAT_ELEMENTS: { |
| 7163 ExternalArray* array = ExternalArray::cast(elements()); | 7198 ExternalArray* array = ExternalArray::cast(elements()); |
| 7164 if (index < static_cast<uint32_t>(array->length())) return FAST_ELEMENT; | 7199 if (index < static_cast<uint32_t>(array->length())) return FAST_ELEMENT; |
| 7165 break; | 7200 break; |
| 7166 } | 7201 } |
| 7167 case DICTIONARY_ELEMENTS: { | 7202 case DICTIONARY_ELEMENTS: { |
| 7168 if (element_dictionary()->FindEntry(index) != | 7203 if (element_dictionary()->FindEntry(index) != |
| 7169 NumberDictionary::kNotFound) { | 7204 NumberDictionary::kNotFound) { |
| 7170 return DICTIONARY_ELEMENT; | 7205 return DICTIONARY_ELEMENT; |
| 7171 } | 7206 } |
| 7172 break; | 7207 break; |
| 7173 } | 7208 } |
| 7174 case NON_STRICT_ARGUMENTS_ELEMENTS: | 7209 case NON_STRICT_ARGUMENTS_ELEMENTS: { |
| 7175 UNIMPLEMENTED(); | 7210 // Aliased parameters and non-aliased elements in a fast backing store |
| 7211 // behave as FAST_ELEMENT. Non-aliased elements in a dictionary | |
| 7212 // backing store behave as DICIONARY_ELEMENT. | |
| 7213 FixedArray* parameter_map = FixedArray::cast(elements()); | |
| 7214 uint32_t length = parameter_map->length(); | |
| 7215 Object* probe = | |
| 7216 (index + 2) < length ? parameter_map->get(index + 2) : NULL; | |
| 7217 if (probe != NULL && !probe->IsTheHole()) return FAST_ELEMENT; | |
| 7218 // If not aliased, check the arguments. | |
| 7219 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); | |
| 7220 if (arguments->IsDictionary()) { | |
| 7221 NumberDictionary* dictionary = NumberDictionary::cast(arguments); | |
| 7222 if (dictionary->FindEntry(index) != NumberDictionary::kNotFound) { | |
| 7223 return DICTIONARY_ELEMENT; | |
| 7224 } | |
| 7225 } else { | |
| 7226 length = arguments->length(); | |
| 7227 probe = (index < length) ? arguments->get(index) : NULL; | |
| 7228 if (probe != NULL && !probe->IsTheHole()) return FAST_ELEMENT; | |
| 7229 } | |
| 7176 break; | 7230 break; |
| 7231 } | |
| 7177 } | 7232 } |
| 7178 | 7233 |
| 7179 return UNDEFINED_ELEMENT; | 7234 return UNDEFINED_ELEMENT; |
| 7180 } | 7235 } |
| 7181 | 7236 |
| 7182 | 7237 |
| 7183 bool JSObject::HasElementInElements(FixedArray* elements, | 7238 bool JSObject::HasElementInElements(FixedArray* elements, |
| 7184 ElementsKind kind, | 7239 ElementsKind kind, |
| 7185 uint32_t index) { | 7240 uint32_t index) { |
| 7186 ASSERT(kind == FAST_ELEMENTS || kind == DICTIONARY_ELEMENTS); | 7241 ASSERT(kind == FAST_ELEMENTS || kind == DICTIONARY_ELEMENTS); |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7316 | 7371 |
| 7317 // api style callbacks. | 7372 // api style callbacks. |
| 7318 if (structure->IsAccessorInfo()) { | 7373 if (structure->IsAccessorInfo()) { |
| 7319 AccessorInfo* data = AccessorInfo::cast(structure); | 7374 AccessorInfo* data = AccessorInfo::cast(structure); |
| 7320 Object* fun_obj = data->getter(); | 7375 Object* fun_obj = data->getter(); |
| 7321 v8::AccessorGetter call_fun = v8::ToCData<v8::AccessorGetter>(fun_obj); | 7376 v8::AccessorGetter call_fun = v8::ToCData<v8::AccessorGetter>(fun_obj); |
| 7322 HandleScope scope(isolate); | 7377 HandleScope scope(isolate); |
| 7323 Handle<JSObject> self(JSObject::cast(receiver)); | 7378 Handle<JSObject> self(JSObject::cast(receiver)); |
| 7324 Handle<JSObject> holder_handle(JSObject::cast(holder)); | 7379 Handle<JSObject> holder_handle(JSObject::cast(holder)); |
| 7325 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); | 7380 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); |
| 7326 Handle<String> key(isolate->factory()->NumberToString(number)); | 7381 Handle<String> key = isolate->factory()->NumberToString(number); |
| 7327 LOG(isolate, ApiNamedPropertyAccess("load", *self, *key)); | 7382 LOG(isolate, ApiNamedPropertyAccess("load", *self, *key)); |
| 7328 CustomArguments args(isolate, data->data(), *self, *holder_handle); | 7383 CustomArguments args(isolate, data->data(), *self, *holder_handle); |
| 7329 v8::AccessorInfo info(args.end()); | 7384 v8::AccessorInfo info(args.end()); |
| 7330 v8::Handle<v8::Value> result; | 7385 v8::Handle<v8::Value> result; |
| 7331 { | 7386 { |
| 7332 // Leaving JavaScript. | 7387 // Leaving JavaScript. |
| 7333 VMState state(isolate, EXTERNAL); | 7388 VMState state(isolate, EXTERNAL); |
| 7334 result = call_fun(v8::Utils::ToLocal(key), info); | 7389 result = call_fun(v8::Utils::ToLocal(key), info); |
| 7335 } | 7390 } |
| 7336 RETURN_IF_SCHEDULED_EXCEPTION(isolate); | 7391 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| (...skipping 554 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7891 return context->get(context_index); | 7946 return context->get(context_index); |
| 7892 } else { | 7947 } else { |
| 7893 // Object is not mapped, defer to the arguments. | 7948 // Object is not mapped, defer to the arguments. |
| 7894 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); | 7949 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); |
| 7895 if (arguments->IsDictionary()) { | 7950 if (arguments->IsDictionary()) { |
| 7896 NumberDictionary* dictionary = NumberDictionary::cast(arguments); | 7951 NumberDictionary* dictionary = NumberDictionary::cast(arguments); |
| 7897 int entry = dictionary->FindEntry(index); | 7952 int entry = dictionary->FindEntry(index); |
| 7898 if (entry != NumberDictionary::kNotFound) { | 7953 if (entry != NumberDictionary::kNotFound) { |
| 7899 Object* element = dictionary->ValueAt(entry); | 7954 Object* element = dictionary->ValueAt(entry); |
| 7900 PropertyDetails details = dictionary->DetailsAt(entry); | 7955 PropertyDetails details = dictionary->DetailsAt(entry); |
| 7901 if (details.type() != CALLBACKS) return element; | 7956 if (details.type() == CALLBACKS) { |
| 7902 UNIMPLEMENTED(); // CALLBACKS not yet implemented. | 7957 return GetElementWithCallback(receiver, |
| 7958 element, | |
| 7959 index, | |
| 7960 this); | |
| 7961 } | |
| 7962 return element; | |
| 7903 } | 7963 } |
| 7904 } else if (index < static_cast<uint32_t>(arguments->length())) { | 7964 } else if (index < static_cast<uint32_t>(arguments->length())) { |
| 7905 Object* value = arguments->get(index); | 7965 Object* value = arguments->get(index); |
| 7906 if (!value->IsTheHole()) return value; | 7966 if (!value->IsTheHole()) return value; |
| 7907 } | 7967 } |
| 7908 } | 7968 } |
| 7909 break; | 7969 break; |
| 7910 } | 7970 } |
| 7911 } | 7971 } |
| 7912 | 7972 |
| (...skipping 2621 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10534 if (break_point_objects()->IsUndefined()) return 0; | 10594 if (break_point_objects()->IsUndefined()) return 0; |
| 10535 // Single beak point. | 10595 // Single beak point. |
| 10536 if (!break_point_objects()->IsFixedArray()) return 1; | 10596 if (!break_point_objects()->IsFixedArray()) return 1; |
| 10537 // Multiple break points. | 10597 // Multiple break points. |
| 10538 return FixedArray::cast(break_point_objects())->length(); | 10598 return FixedArray::cast(break_point_objects())->length(); |
| 10539 } | 10599 } |
| 10540 #endif | 10600 #endif |
| 10541 | 10601 |
| 10542 | 10602 |
| 10543 } } // namespace v8::internal | 10603 } } // namespace v8::internal |
| OLD | NEW |