| 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 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 123 return heap_object->GetHeap()->ToBoolean( | 123 return heap_object->GetHeap()->ToBoolean( |
| 124 String::cast(this)->length() != 0); | 124 String::cast(this)->length() != 0); |
| 125 } | 125 } |
| 126 if (heap_object->IsHeapNumber()) { | 126 if (heap_object->IsHeapNumber()) { |
| 127 return HeapNumber::cast(this)->HeapNumberToBoolean(); | 127 return HeapNumber::cast(this)->HeapNumberToBoolean(); |
| 128 } | 128 } |
| 129 return heap_object->GetHeap()->true_value(); | 129 return heap_object->GetHeap()->true_value(); |
| 130 } | 130 } |
| 131 | 131 |
| 132 | 132 |
| 133 void Object::Lookup(String* name, LookupResult* result) { | 133 void Object::Lookup(Name* name, LookupResult* result) { |
| 134 Object* holder = NULL; | 134 Object* holder = NULL; |
| 135 if (IsJSReceiver()) { | 135 if (IsJSReceiver()) { |
| 136 holder = this; | 136 holder = this; |
| 137 } else { | 137 } else { |
| 138 Context* native_context = Isolate::Current()->context()->native_context(); | 138 Context* native_context = Isolate::Current()->context()->native_context(); |
| 139 if (IsNumber()) { | 139 if (IsNumber()) { |
| 140 holder = native_context->number_function()->instance_prototype(); | 140 holder = native_context->number_function()->instance_prototype(); |
| 141 } else if (IsString()) { | 141 } else if (IsString()) { |
| 142 holder = native_context->string_function()->instance_prototype(); | 142 holder = native_context->string_function()->instance_prototype(); |
| 143 } else if (IsBoolean()) { | 143 } else if (IsBoolean()) { |
| 144 holder = native_context->boolean_function()->instance_prototype(); | 144 holder = native_context->boolean_function()->instance_prototype(); |
| 145 } else if (IsSymbol()) { | 145 } else if (IsSymbol()) { |
| 146 holder = native_context->symbol_delegate(); | 146 holder = native_context->symbol_delegate(); |
| 147 } else { | 147 } else { |
| 148 Isolate::Current()->PushStackTraceAndDie( | 148 Isolate::Current()->PushStackTraceAndDie( |
| 149 0xDEAD0000, this, JSReceiver::cast(this)->map(), 0xDEAD0001); | 149 0xDEAD0000, this, JSReceiver::cast(this)->map(), 0xDEAD0001); |
| 150 } | 150 } |
| 151 } | 151 } |
| 152 ASSERT(holder != NULL); // Cannot handle null or undefined. | 152 ASSERT(holder != NULL); // Cannot handle null or undefined. |
| 153 JSReceiver::cast(holder)->Lookup(name, result); | 153 JSReceiver::cast(holder)->Lookup(name, result); |
| 154 } | 154 } |
| 155 | 155 |
| 156 | 156 |
| 157 MaybeObject* Object::GetPropertyWithReceiver(Object* receiver, | 157 MaybeObject* Object::GetPropertyWithReceiver(Object* receiver, |
| 158 String* name, | 158 Name* name, |
| 159 PropertyAttributes* attributes) { | 159 PropertyAttributes* attributes) { |
| 160 LookupResult result(name->GetIsolate()); | 160 LookupResult result(name->GetIsolate()); |
| 161 Lookup(name, &result); | 161 Lookup(name, &result); |
| 162 MaybeObject* value = GetProperty(receiver, &result, name, attributes); | 162 MaybeObject* value = GetProperty(receiver, &result, name, attributes); |
| 163 ASSERT(*attributes <= ABSENT); | 163 ASSERT(*attributes <= ABSENT); |
| 164 return value; | 164 return value; |
| 165 } | 165 } |
| 166 | 166 |
| 167 | 167 |
| 168 MaybeObject* JSObject::GetPropertyWithCallback(Object* receiver, | 168 MaybeObject* JSObject::GetPropertyWithCallback(Object* receiver, |
| 169 Object* structure, | 169 Object* structure, |
| 170 String* name) { | 170 Name* name) { |
| 171 Isolate* isolate = name->GetIsolate(); | 171 Isolate* isolate = name->GetIsolate(); |
| 172 // To accommodate both the old and the new api we switch on the | 172 // To accommodate both the old and the new api we switch on the |
| 173 // data structure used to store the callbacks. Eventually foreign | 173 // data structure used to store the callbacks. Eventually foreign |
| 174 // callbacks should be phased out. | 174 // callbacks should be phased out. |
| 175 if (structure->IsForeign()) { | 175 if (structure->IsForeign()) { |
| 176 AccessorDescriptor* callback = | 176 AccessorDescriptor* callback = |
| 177 reinterpret_cast<AccessorDescriptor*>( | 177 reinterpret_cast<AccessorDescriptor*>( |
| 178 Foreign::cast(structure)->foreign_address()); | 178 Foreign::cast(structure)->foreign_address()); |
| 179 MaybeObject* value = (callback->getter)(receiver, callback->data); | 179 MaybeObject* value = (callback->getter)(receiver, callback->data); |
| 180 RETURN_IF_SCHEDULED_EXCEPTION(isolate); | 180 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 181 return value; | 181 return value; |
| 182 } | 182 } |
| 183 | 183 |
| 184 // api style callbacks. | 184 // api style callbacks. |
| 185 if (structure->IsAccessorInfo()) { | 185 if (structure->IsAccessorInfo()) { |
| 186 AccessorInfo* data = AccessorInfo::cast(structure); | 186 AccessorInfo* data = AccessorInfo::cast(structure); |
| 187 if (!data->IsCompatibleReceiver(receiver)) { | 187 if (!data->IsCompatibleReceiver(receiver)) { |
| 188 Handle<Object> name_handle(name); | 188 Handle<Object> name_handle(name); |
| 189 Handle<Object> receiver_handle(receiver); | 189 Handle<Object> receiver_handle(receiver); |
| 190 Handle<Object> args[2] = { name_handle, receiver_handle }; | 190 Handle<Object> args[2] = { name_handle, receiver_handle }; |
| 191 Handle<Object> error = | 191 Handle<Object> error = |
| 192 isolate->factory()->NewTypeError("incompatible_method_receiver", | 192 isolate->factory()->NewTypeError("incompatible_method_receiver", |
| 193 HandleVector(args, | 193 HandleVector(args, |
| 194 ARRAY_SIZE(args))); | 194 ARRAY_SIZE(args))); |
| 195 return isolate->Throw(*error); | 195 return isolate->Throw(*error); |
| 196 } | 196 } |
| 197 // TODO(rossberg): Handling symbols in the API requires changing the API, |
| 198 // so we do not support it for now. |
| 199 if (name->IsSymbol()) return isolate->heap()->undefined_value(); |
| 197 Object* fun_obj = data->getter(); | 200 Object* fun_obj = data->getter(); |
| 198 v8::AccessorGetter call_fun = v8::ToCData<v8::AccessorGetter>(fun_obj); | 201 v8::AccessorGetter call_fun = v8::ToCData<v8::AccessorGetter>(fun_obj); |
| 199 if (call_fun == NULL) return isolate->heap()->undefined_value(); | 202 if (call_fun == NULL) return isolate->heap()->undefined_value(); |
| 200 HandleScope scope(isolate); | 203 HandleScope scope(isolate); |
| 201 JSObject* self = JSObject::cast(receiver); | 204 JSObject* self = JSObject::cast(receiver); |
| 202 Handle<String> key(name); | 205 Handle<String> key(String::cast(name)); |
| 203 LOG(isolate, ApiNamedPropertyAccess("load", self, name)); | 206 LOG(isolate, ApiNamedPropertyAccess("load", self, name)); |
| 204 CustomArguments args(isolate, data->data(), self, this); | 207 CustomArguments args(isolate, data->data(), self, this); |
| 205 v8::AccessorInfo info(args.end()); | 208 v8::AccessorInfo info(args.end()); |
| 206 v8::Handle<v8::Value> result; | 209 v8::Handle<v8::Value> result; |
| 207 { | 210 { |
| 208 // Leaving JavaScript. | 211 // Leaving JavaScript. |
| 209 VMState state(isolate, EXTERNAL); | 212 VMState state(isolate, EXTERNAL); |
| 210 result = call_fun(v8::Utils::ToLocal(key), info); | 213 result = call_fun(v8::Utils::ToLocal(key), info); |
| 211 } | 214 } |
| 212 RETURN_IF_SCHEDULED_EXCEPTION(isolate); | 215 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 228 // Getter is not a function. | 231 // Getter is not a function. |
| 229 return isolate->heap()->undefined_value(); | 232 return isolate->heap()->undefined_value(); |
| 230 } | 233 } |
| 231 | 234 |
| 232 UNREACHABLE(); | 235 UNREACHABLE(); |
| 233 return NULL; | 236 return NULL; |
| 234 } | 237 } |
| 235 | 238 |
| 236 | 239 |
| 237 MaybeObject* JSProxy::GetPropertyWithHandler(Object* receiver_raw, | 240 MaybeObject* JSProxy::GetPropertyWithHandler(Object* receiver_raw, |
| 238 String* name_raw) { | 241 Name* name_raw) { |
| 239 Isolate* isolate = GetIsolate(); | 242 Isolate* isolate = GetIsolate(); |
| 240 HandleScope scope(isolate); | 243 HandleScope scope(isolate); |
| 241 Handle<Object> receiver(receiver_raw); | 244 Handle<Object> receiver(receiver_raw); |
| 242 Handle<Object> name(name_raw); | 245 Handle<Object> name(name_raw); |
| 243 | 246 |
| 244 Handle<Object> args[] = { receiver, name }; | 247 Handle<Object> args[] = { receiver, name }; |
| 245 Handle<Object> result = CallTrap( | 248 Handle<Object> result = CallTrap( |
| 246 "get", isolate->derived_get_trap(), ARRAY_SIZE(args), args); | 249 "get", isolate->derived_get_trap(), ARRAY_SIZE(args), args); |
| 247 if (isolate->has_pending_exception()) return Failure::Exception(); | 250 if (isolate->has_pending_exception()) return Failure::Exception(); |
| 248 | 251 |
| 249 return *result; | 252 return *result; |
| 250 } | 253 } |
| 251 | 254 |
| 252 | 255 |
| 253 Handle<Object> Object::GetProperty(Handle<Object> object, Handle<String> name) { | 256 Handle<Object> Object::GetProperty(Handle<Object> object, Handle<Name> name) { |
| 254 // TODO(rossberg): The index test should not be here but in the GetProperty | 257 // TODO(rossberg): The index test should not be here but in the GetProperty |
| 255 // method (or somewhere else entirely). Needs more global clean-up. | 258 // method (or somewhere else entirely). Needs more global clean-up. |
| 256 uint32_t index; | 259 uint32_t index; |
| 257 if (name->AsArrayIndex(&index)) return GetElement(object, index); | 260 if (name->AsArrayIndex(&index)) |
| 261 return GetElement(object, index); |
| 258 Isolate* isolate = object->IsHeapObject() | 262 Isolate* isolate = object->IsHeapObject() |
| 259 ? Handle<HeapObject>::cast(object)->GetIsolate() | 263 ? Handle<HeapObject>::cast(object)->GetIsolate() |
| 260 : Isolate::Current(); | 264 : Isolate::Current(); |
| 261 CALL_HEAP_FUNCTION(isolate, object->GetProperty(*name), Object); | 265 CALL_HEAP_FUNCTION(isolate, object->GetProperty(*name), Object); |
| 262 } | 266 } |
| 263 | 267 |
| 264 | 268 |
| 265 Handle<Object> Object::GetElement(Handle<Object> object, uint32_t index) { | 269 Handle<Object> Object::GetElement(Handle<Object> object, uint32_t index) { |
| 266 Isolate* isolate = object->IsHeapObject() | 270 Isolate* isolate = object->IsHeapObject() |
| 267 ? Handle<HeapObject>::cast(object)->GetIsolate() | 271 ? Handle<HeapObject>::cast(object)->GetIsolate() |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 319 // Check for pending exception and return the result. | 323 // Check for pending exception and return the result. |
| 320 if (has_pending_exception) return Failure::Exception(); | 324 if (has_pending_exception) return Failure::Exception(); |
| 321 return *result; | 325 return *result; |
| 322 } | 326 } |
| 323 | 327 |
| 324 | 328 |
| 325 // Only deal with CALLBACKS and INTERCEPTOR | 329 // Only deal with CALLBACKS and INTERCEPTOR |
| 326 MaybeObject* JSObject::GetPropertyWithFailedAccessCheck( | 330 MaybeObject* JSObject::GetPropertyWithFailedAccessCheck( |
| 327 Object* receiver, | 331 Object* receiver, |
| 328 LookupResult* result, | 332 LookupResult* result, |
| 329 String* name, | 333 Name* name, |
| 330 PropertyAttributes* attributes) { | 334 PropertyAttributes* attributes) { |
| 331 if (result->IsProperty()) { | 335 if (result->IsProperty()) { |
| 332 switch (result->type()) { | 336 switch (result->type()) { |
| 333 case CALLBACKS: { | 337 case CALLBACKS: { |
| 334 // Only allow API accessors. | 338 // Only allow API accessors. |
| 335 Object* obj = result->GetCallbackObject(); | 339 Object* obj = result->GetCallbackObject(); |
| 336 if (obj->IsAccessorInfo()) { | 340 if (obj->IsAccessorInfo()) { |
| 337 AccessorInfo* info = AccessorInfo::cast(obj); | 341 AccessorInfo* info = AccessorInfo::cast(obj); |
| 338 if (info->all_can_read()) { | 342 if (info->all_can_read()) { |
| 339 *attributes = result->GetAttributes(); | 343 *attributes = result->GetAttributes(); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 379 *attributes = ABSENT; | 383 *attributes = ABSENT; |
| 380 Heap* heap = name->GetHeap(); | 384 Heap* heap = name->GetHeap(); |
| 381 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_GET); | 385 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_GET); |
| 382 return heap->undefined_value(); | 386 return heap->undefined_value(); |
| 383 } | 387 } |
| 384 | 388 |
| 385 | 389 |
| 386 PropertyAttributes JSObject::GetPropertyAttributeWithFailedAccessCheck( | 390 PropertyAttributes JSObject::GetPropertyAttributeWithFailedAccessCheck( |
| 387 Object* receiver, | 391 Object* receiver, |
| 388 LookupResult* result, | 392 LookupResult* result, |
| 389 String* name, | 393 Name* name, |
| 390 bool continue_search) { | 394 bool continue_search) { |
| 391 if (result->IsProperty()) { | 395 if (result->IsProperty()) { |
| 392 switch (result->type()) { | 396 switch (result->type()) { |
| 393 case CALLBACKS: { | 397 case CALLBACKS: { |
| 394 // Only allow API accessors. | 398 // Only allow API accessors. |
| 395 Object* obj = result->GetCallbackObject(); | 399 Object* obj = result->GetCallbackObject(); |
| 396 if (obj->IsAccessorInfo()) { | 400 if (obj->IsAccessorInfo()) { |
| 397 AccessorInfo* info = AccessorInfo::cast(obj); | 401 AccessorInfo* info = AccessorInfo::cast(obj); |
| 398 if (info->all_can_read()) { | 402 if (info->all_can_read()) { |
| 399 return result->GetAttributes(); | 403 return result->GetAttributes(); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 465 property_dictionary()->ValueAt(result->GetDictionaryEntry())); | 469 property_dictionary()->ValueAt(result->GetDictionaryEntry())); |
| 466 cell->set_value(value); | 470 cell->set_value(value); |
| 467 } else { | 471 } else { |
| 468 property_dictionary()->ValueAtPut(result->GetDictionaryEntry(), value); | 472 property_dictionary()->ValueAtPut(result->GetDictionaryEntry(), value); |
| 469 } | 473 } |
| 470 return value; | 474 return value; |
| 471 } | 475 } |
| 472 | 476 |
| 473 | 477 |
| 474 Handle<Object> JSObject::SetNormalizedProperty(Handle<JSObject> object, | 478 Handle<Object> JSObject::SetNormalizedProperty(Handle<JSObject> object, |
| 475 Handle<String> key, | 479 Handle<Name> key, |
| 476 Handle<Object> value, | 480 Handle<Object> value, |
| 477 PropertyDetails details) { | 481 PropertyDetails details) { |
| 478 CALL_HEAP_FUNCTION(object->GetIsolate(), | 482 CALL_HEAP_FUNCTION(object->GetIsolate(), |
| 479 object->SetNormalizedProperty(*key, *value, details), | 483 object->SetNormalizedProperty(*key, *value, details), |
| 480 Object); | 484 Object); |
| 481 } | 485 } |
| 482 | 486 |
| 483 | 487 |
| 484 MaybeObject* JSObject::SetNormalizedProperty(String* name, | 488 MaybeObject* JSObject::SetNormalizedProperty(Name* name, |
| 485 Object* value, | 489 Object* value, |
| 486 PropertyDetails details) { | 490 PropertyDetails details) { |
| 487 ASSERT(!HasFastProperties()); | 491 ASSERT(!HasFastProperties()); |
| 488 int entry = property_dictionary()->FindEntry(name); | 492 int entry = property_dictionary()->FindEntry(name); |
| 489 if (entry == StringDictionary::kNotFound) { | 493 if (entry == NameDictionary::kNotFound) { |
| 490 Object* store_value = value; | 494 Object* store_value = value; |
| 491 if (IsGlobalObject()) { | 495 if (IsGlobalObject()) { |
| 492 Heap* heap = name->GetHeap(); | 496 Heap* heap = name->GetHeap(); |
| 493 MaybeObject* maybe_store_value = | 497 MaybeObject* maybe_store_value = |
| 494 heap->AllocateJSGlobalPropertyCell(value); | 498 heap->AllocateJSGlobalPropertyCell(value); |
| 495 if (!maybe_store_value->ToObject(&store_value)) return maybe_store_value; | 499 if (!maybe_store_value->ToObject(&store_value)) return maybe_store_value; |
| 496 } | 500 } |
| 497 Object* dict; | 501 Object* dict; |
| 498 { MaybeObject* maybe_dict = | 502 { MaybeObject* maybe_dict = |
| 499 property_dictionary()->Add(name, store_value, details); | 503 property_dictionary()->Add(name, store_value, details); |
| 500 if (!maybe_dict->ToObject(&dict)) return maybe_dict; | 504 if (!maybe_dict->ToObject(&dict)) return maybe_dict; |
| 501 } | 505 } |
| 502 set_properties(StringDictionary::cast(dict)); | 506 set_properties(NameDictionary::cast(dict)); |
| 503 return value; | 507 return value; |
| 504 } | 508 } |
| 505 | 509 |
| 506 PropertyDetails original_details = property_dictionary()->DetailsAt(entry); | 510 PropertyDetails original_details = property_dictionary()->DetailsAt(entry); |
| 507 int enumeration_index; | 511 int enumeration_index; |
| 508 // Preserve the enumeration index unless the property was deleted. | 512 // Preserve the enumeration index unless the property was deleted. |
| 509 if (original_details.IsDeleted()) { | 513 if (original_details.IsDeleted()) { |
| 510 enumeration_index = property_dictionary()->NextEnumerationIndex(); | 514 enumeration_index = property_dictionary()->NextEnumerationIndex(); |
| 511 property_dictionary()->SetNextEnumerationIndex(enumeration_index + 1); | 515 property_dictionary()->SetNextEnumerationIndex(enumeration_index + 1); |
| 512 } else { | 516 } else { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 523 cell->set_value(value); | 527 cell->set_value(value); |
| 524 // Please note we have to update the property details. | 528 // Please note we have to update the property details. |
| 525 property_dictionary()->DetailsAtPut(entry, details); | 529 property_dictionary()->DetailsAtPut(entry, details); |
| 526 } else { | 530 } else { |
| 527 property_dictionary()->SetEntry(entry, name, value, details); | 531 property_dictionary()->SetEntry(entry, name, value, details); |
| 528 } | 532 } |
| 529 return value; | 533 return value; |
| 530 } | 534 } |
| 531 | 535 |
| 532 | 536 |
| 533 MaybeObject* JSObject::DeleteNormalizedProperty(String* name, DeleteMode mode) { | 537 MaybeObject* JSObject::DeleteNormalizedProperty(Name* name, DeleteMode mode) { |
| 534 ASSERT(!HasFastProperties()); | 538 ASSERT(!HasFastProperties()); |
| 535 StringDictionary* dictionary = property_dictionary(); | 539 NameDictionary* dictionary = property_dictionary(); |
| 536 int entry = dictionary->FindEntry(name); | 540 int entry = dictionary->FindEntry(name); |
| 537 if (entry != StringDictionary::kNotFound) { | 541 if (entry != NameDictionary::kNotFound) { |
| 538 // If we have a global object set the cell to the hole. | 542 // If we have a global object set the cell to the hole. |
| 539 if (IsGlobalObject()) { | 543 if (IsGlobalObject()) { |
| 540 PropertyDetails details = dictionary->DetailsAt(entry); | 544 PropertyDetails details = dictionary->DetailsAt(entry); |
| 541 if (details.IsDontDelete()) { | 545 if (details.IsDontDelete()) { |
| 542 if (mode != FORCE_DELETION) return GetHeap()->false_value(); | 546 if (mode != FORCE_DELETION) return GetHeap()->false_value(); |
| 543 // When forced to delete global properties, we have to make a | 547 // When forced to delete global properties, we have to make a |
| 544 // map change to invalidate any ICs that think they can load | 548 // map change to invalidate any ICs that think they can load |
| 545 // from the DontDelete cell without checking if it contains | 549 // from the DontDelete cell without checking if it contains |
| 546 // the hole value. | 550 // the hole value. |
| 547 Map* new_map; | 551 Map* new_map; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 583 // created with then no changes can have been made to it. | 587 // created with then no changes can have been made to it. |
| 584 return map() != fun->initial_map() | 588 return map() != fun->initial_map() |
| 585 || !HasFastObjectElements() | 589 || !HasFastObjectElements() |
| 586 || !HasFastProperties(); | 590 || !HasFastProperties(); |
| 587 } | 591 } |
| 588 | 592 |
| 589 | 593 |
| 590 Handle<Object> Object::GetProperty(Handle<Object> object, | 594 Handle<Object> Object::GetProperty(Handle<Object> object, |
| 591 Handle<Object> receiver, | 595 Handle<Object> receiver, |
| 592 LookupResult* result, | 596 LookupResult* result, |
| 593 Handle<String> key, | 597 Handle<Name> key, |
| 594 PropertyAttributes* attributes) { | 598 PropertyAttributes* attributes) { |
| 595 Isolate* isolate = object->IsHeapObject() | 599 Isolate* isolate = object->IsHeapObject() |
| 596 ? Handle<HeapObject>::cast(object)->GetIsolate() | 600 ? Handle<HeapObject>::cast(object)->GetIsolate() |
| 597 : Isolate::Current(); | 601 : Isolate::Current(); |
| 598 CALL_HEAP_FUNCTION( | 602 CALL_HEAP_FUNCTION( |
| 599 isolate, | 603 isolate, |
| 600 object->GetProperty(*receiver, result, *key, attributes), | 604 object->GetProperty(*receiver, result, *key, attributes), |
| 601 Object); | 605 Object); |
| 602 } | 606 } |
| 603 | 607 |
| 604 | 608 |
| 605 MaybeObject* Object::GetProperty(Object* receiver, | 609 MaybeObject* Object::GetProperty(Object* receiver, |
| 606 LookupResult* result, | 610 LookupResult* result, |
| 607 String* name, | 611 Name* name, |
| 608 PropertyAttributes* attributes) { | 612 PropertyAttributes* attributes) { |
| 609 // Make sure that the top context does not change when doing | 613 // Make sure that the top context does not change when doing |
| 610 // callbacks or interceptor calls. | 614 // callbacks or interceptor calls. |
| 611 AssertNoContextChange ncc; | 615 AssertNoContextChange ncc; |
| 612 Heap* heap = name->GetHeap(); | 616 Heap* heap = name->GetHeap(); |
| 613 | 617 |
| 614 // Traverse the prototype chain from the current object (this) to | 618 // Traverse the prototype chain from the current object (this) to |
| 615 // the holder and check for access rights. This avoids traversing the | 619 // the holder and check for access rights. This avoids traversing the |
| 616 // objects more than once in case of interceptors, because the | 620 // objects more than once in case of interceptors, because the |
| 617 // holder will always be the interceptor holder and the search may | 621 // holder will always be the interceptor holder and the search may |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 777 if (IsSymbol()) { | 781 if (IsSymbol()) { |
| 778 Heap* heap = Symbol::cast(this)->GetHeap(); | 782 Heap* heap = Symbol::cast(this)->GetHeap(); |
| 779 Context* context = heap->isolate()->context()->native_context(); | 783 Context* context = heap->isolate()->context()->native_context(); |
| 780 return context->symbol_delegate(); | 784 return context->symbol_delegate(); |
| 781 } | 785 } |
| 782 return GetPrototype(); | 786 return GetPrototype(); |
| 783 } | 787 } |
| 784 | 788 |
| 785 | 789 |
| 786 MaybeObject* Object::GetHash(CreationFlag flag) { | 790 MaybeObject* Object::GetHash(CreationFlag flag) { |
| 787 // The object is either a number, a string, an odd-ball, | 791 // The object is either a number, a name, an odd-ball, |
| 788 // a real JS object, or a Harmony proxy. | 792 // a real JS object, or a Harmony proxy. |
| 789 if (IsNumber()) { | 793 if (IsNumber()) { |
| 790 uint32_t hash = ComputeLongHash(double_to_uint64(Number())); | 794 uint32_t hash = ComputeLongHash(double_to_uint64(Number())); |
| 791 return Smi::FromInt(hash & Smi::kMaxValue); | 795 return Smi::FromInt(hash & Smi::kMaxValue); |
| 792 } | 796 } |
| 793 if (IsString()) { | 797 if (IsName()) { |
| 794 uint32_t hash = String::cast(this)->Hash(); | 798 uint32_t hash = Name::cast(this)->Hash(); |
| 795 return Smi::FromInt(hash); | 799 return Smi::FromInt(hash); |
| 796 } | 800 } |
| 797 if (IsOddball()) { | 801 if (IsOddball()) { |
| 798 uint32_t hash = Oddball::cast(this)->to_string()->Hash(); | 802 uint32_t hash = Oddball::cast(this)->to_string()->Hash(); |
| 799 return Smi::FromInt(hash); | 803 return Smi::FromInt(hash); |
| 800 } | 804 } |
| 801 if (IsJSReceiver()) { | 805 if (IsJSReceiver()) { |
| 802 return JSReceiver::cast(this)->GetIdentityHash(flag); | 806 return JSReceiver::cast(this)->GetIdentityHash(flag); |
| 803 } | 807 } |
| 804 | 808 |
| 805 UNREACHABLE(); | 809 UNREACHABLE(); |
| 806 return Smi::FromInt(0); | 810 return Smi::FromInt(0); |
| 807 } | 811 } |
| 808 | 812 |
| 809 | 813 |
| 810 bool Object::SameValue(Object* other) { | 814 bool Object::SameValue(Object* other) { |
| 811 if (other == this) return true; | 815 if (other == this) return true; |
| 812 | 816 |
| 813 // The object is either a number, a string, an odd-ball, | 817 // The object is either a number, a name, an odd-ball, |
| 814 // a real JS object, or a Harmony proxy. | 818 // a real JS object, or a Harmony proxy. |
| 815 if (IsNumber() && other->IsNumber()) { | 819 if (IsNumber() && other->IsNumber()) { |
| 816 double this_value = Number(); | 820 double this_value = Number(); |
| 817 double other_value = other->Number(); | 821 double other_value = other->Number(); |
| 818 return (this_value == other_value) || | 822 return (this_value == other_value) || |
| 819 (isnan(this_value) && isnan(other_value)); | 823 (isnan(this_value) && isnan(other_value)); |
| 820 } | 824 } |
| 821 if (IsString() && other->IsString()) { | 825 if (IsString() && other->IsString()) { |
| 822 return String::cast(this)->Equals(String::cast(other)); | 826 return String::cast(this)->Equals(String::cast(other)); |
| 823 } | 827 } |
| (...skipping 715 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1539 Object* proto = GetPrototype(); | 1543 Object* proto = GetPrototype(); |
| 1540 if (proto->IsJSObject()) return JSObject::cast(proto)->constructor_name(); | 1544 if (proto->IsJSObject()) return JSObject::cast(proto)->constructor_name(); |
| 1541 } | 1545 } |
| 1542 // TODO(rossberg): what about proxies? | 1546 // TODO(rossberg): what about proxies? |
| 1543 // If the constructor is not present, return "Object". | 1547 // If the constructor is not present, return "Object". |
| 1544 return GetHeap()->Object_string(); | 1548 return GetHeap()->Object_string(); |
| 1545 } | 1549 } |
| 1546 | 1550 |
| 1547 | 1551 |
| 1548 MaybeObject* JSObject::AddFastPropertyUsingMap(Map* new_map, | 1552 MaybeObject* JSObject::AddFastPropertyUsingMap(Map* new_map, |
| 1549 String* name, | 1553 Name* name, |
| 1550 Object* value, | 1554 Object* value, |
| 1551 int field_index) { | 1555 int field_index) { |
| 1552 if (map()->unused_property_fields() == 0) { | 1556 if (map()->unused_property_fields() == 0) { |
| 1553 int new_unused = new_map->unused_property_fields(); | 1557 int new_unused = new_map->unused_property_fields(); |
| 1554 FixedArray* values; | 1558 FixedArray* values; |
| 1555 { MaybeObject* maybe_values = | 1559 { MaybeObject* maybe_values = |
| 1556 properties()->CopySize(properties()->length() + new_unused + 1); | 1560 properties()->CopySize(properties()->length() + new_unused + 1); |
| 1557 if (!maybe_values->To(&values)) return maybe_values; | 1561 if (!maybe_values->To(&values)) return maybe_values; |
| 1558 } | 1562 } |
| 1559 set_properties(values); | 1563 set_properties(values); |
| 1560 } | 1564 } |
| 1561 set_map(new_map); | 1565 set_map(new_map); |
| 1562 return FastPropertyAtPut(field_index, value); | 1566 return FastPropertyAtPut(field_index, value); |
| 1563 } | 1567 } |
| 1564 | 1568 |
| 1565 | 1569 |
| 1566 static bool IsIdentifier(UnicodeCache* cache, String* string) { | 1570 static bool IsIdentifier(UnicodeCache* cache, Name* name) { |
| 1567 // Checks whether the buffer contains an identifier (no escape). | 1571 // Checks whether the buffer contains an identifier (no escape). |
| 1572 if (!name->IsString()) return false; |
| 1573 String* string = String::cast(name); |
| 1568 if (string->length() == 0) return false; | 1574 if (string->length() == 0) return false; |
| 1569 ConsStringIteratorOp op; | 1575 ConsStringIteratorOp op; |
| 1570 StringCharacterStream stream(string, &op); | 1576 StringCharacterStream stream(string, &op); |
| 1571 if (!cache->IsIdentifierStart(stream.GetNext())) { | 1577 if (!cache->IsIdentifierStart(stream.GetNext())) { |
| 1572 return false; | 1578 return false; |
| 1573 } | 1579 } |
| 1574 while (stream.HasMore()) { | 1580 while (stream.HasMore()) { |
| 1575 if (!cache->IsIdentifierPart(stream.GetNext())) { | 1581 if (!cache->IsIdentifierPart(stream.GetNext())) { |
| 1576 return false; | 1582 return false; |
| 1577 } | 1583 } |
| 1578 } | 1584 } |
| 1579 return true; | 1585 return true; |
| 1580 } | 1586 } |
| 1581 | 1587 |
| 1582 | 1588 |
| 1583 MaybeObject* JSObject::AddFastProperty(String* name, | 1589 MaybeObject* JSObject::AddFastProperty(Name* name, |
| 1584 Object* value, | 1590 Object* value, |
| 1585 PropertyAttributes attributes, | 1591 PropertyAttributes attributes, |
| 1586 StoreFromKeyed store_mode) { | 1592 StoreFromKeyed store_mode) { |
| 1587 ASSERT(!IsJSGlobalProxy()); | 1593 ASSERT(!IsJSGlobalProxy()); |
| 1588 ASSERT(DescriptorArray::kNotFound == | 1594 ASSERT(DescriptorArray::kNotFound == |
| 1589 map()->instance_descriptors()->Search( | 1595 map()->instance_descriptors()->Search( |
| 1590 name, map()->NumberOfOwnDescriptors())); | 1596 name, map()->NumberOfOwnDescriptors())); |
| 1591 | 1597 |
| 1592 // Normalize the object if the name is an actual string (not the | 1598 // Normalize the object if the name is an actual name (not the |
| 1593 // hidden strings) and is not a real identifier. | 1599 // hidden strings) and is not a real identifier. |
| 1594 // Normalize the object if it will have too many fast properties. | 1600 // Normalize the object if it will have too many fast properties. |
| 1595 Isolate* isolate = GetHeap()->isolate(); | 1601 Isolate* isolate = GetHeap()->isolate(); |
| 1596 if ((!IsIdentifier(isolate->unicode_cache(), name) | 1602 if ((!IsIdentifier(isolate->unicode_cache(), name) |
| 1597 && name != isolate->heap()->hidden_string()) || | 1603 && name != isolate->heap()->hidden_string()) || |
| 1598 (map()->unused_property_fields() == 0 && | 1604 (map()->unused_property_fields() == 0 && |
| 1599 TooManyFastProperties(properties()->length(), store_mode))) { | 1605 TooManyFastProperties(properties()->length(), store_mode))) { |
| 1600 Object* obj; | 1606 Object* obj; |
| 1601 MaybeObject* maybe_obj = | 1607 MaybeObject* maybe_obj = |
| 1602 NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); | 1608 NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1637 } else { | 1643 } else { |
| 1638 new_map->set_unused_property_fields(map()->unused_property_fields() - 1); | 1644 new_map->set_unused_property_fields(map()->unused_property_fields() - 1); |
| 1639 } | 1645 } |
| 1640 | 1646 |
| 1641 set_map(new_map); | 1647 set_map(new_map); |
| 1642 return FastPropertyAtPut(index, value); | 1648 return FastPropertyAtPut(index, value); |
| 1643 } | 1649 } |
| 1644 | 1650 |
| 1645 | 1651 |
| 1646 MaybeObject* JSObject::AddConstantFunctionProperty( | 1652 MaybeObject* JSObject::AddConstantFunctionProperty( |
| 1647 String* name, | 1653 Name* name, |
| 1648 JSFunction* function, | 1654 JSFunction* function, |
| 1649 PropertyAttributes attributes) { | 1655 PropertyAttributes attributes) { |
| 1650 // Allocate new instance descriptors with (name, function) added | 1656 // Allocate new instance descriptors with (name, function) added |
| 1651 ConstantFunctionDescriptor d(name, function, attributes, 0); | 1657 ConstantFunctionDescriptor d(name, function, attributes, 0); |
| 1652 | 1658 |
| 1653 TransitionFlag flag = | 1659 TransitionFlag flag = |
| 1654 // Do not add transitions to global objects. | 1660 // Do not add transitions to global objects. |
| 1655 (IsGlobalObject() || | 1661 (IsGlobalObject() || |
| 1656 // Don't add transitions to special properties with non-trivial | 1662 // Don't add transitions to special properties with non-trivial |
| 1657 // attributes. | 1663 // attributes. |
| 1658 attributes != NONE) | 1664 attributes != NONE) |
| 1659 ? OMIT_TRANSITION | 1665 ? OMIT_TRANSITION |
| 1660 : INSERT_TRANSITION; | 1666 : INSERT_TRANSITION; |
| 1661 | 1667 |
| 1662 Map* new_map; | 1668 Map* new_map; |
| 1663 MaybeObject* maybe_new_map = map()->CopyAddDescriptor(&d, flag); | 1669 MaybeObject* maybe_new_map = map()->CopyAddDescriptor(&d, flag); |
| 1664 if (!maybe_new_map->To(&new_map)) return maybe_new_map; | 1670 if (!maybe_new_map->To(&new_map)) return maybe_new_map; |
| 1665 | 1671 |
| 1666 set_map(new_map); | 1672 set_map(new_map); |
| 1667 return function; | 1673 return function; |
| 1668 } | 1674 } |
| 1669 | 1675 |
| 1670 | 1676 |
| 1671 // Add property in slow mode | 1677 // Add property in slow mode |
| 1672 MaybeObject* JSObject::AddSlowProperty(String* name, | 1678 MaybeObject* JSObject::AddSlowProperty(Name* name, |
| 1673 Object* value, | 1679 Object* value, |
| 1674 PropertyAttributes attributes) { | 1680 PropertyAttributes attributes) { |
| 1675 ASSERT(!HasFastProperties()); | 1681 ASSERT(!HasFastProperties()); |
| 1676 StringDictionary* dict = property_dictionary(); | 1682 NameDictionary* dict = property_dictionary(); |
| 1677 Object* store_value = value; | 1683 Object* store_value = value; |
| 1678 if (IsGlobalObject()) { | 1684 if (IsGlobalObject()) { |
| 1679 // In case name is an orphaned property reuse the cell. | 1685 // In case name is an orphaned property reuse the cell. |
| 1680 int entry = dict->FindEntry(name); | 1686 int entry = dict->FindEntry(name); |
| 1681 if (entry != StringDictionary::kNotFound) { | 1687 if (entry != NameDictionary::kNotFound) { |
| 1682 store_value = dict->ValueAt(entry); | 1688 store_value = dict->ValueAt(entry); |
| 1683 JSGlobalPropertyCell::cast(store_value)->set_value(value); | 1689 JSGlobalPropertyCell::cast(store_value)->set_value(value); |
| 1684 // Assign an enumeration index to the property and update | 1690 // Assign an enumeration index to the property and update |
| 1685 // SetNextEnumerationIndex. | 1691 // SetNextEnumerationIndex. |
| 1686 int index = dict->NextEnumerationIndex(); | 1692 int index = dict->NextEnumerationIndex(); |
| 1687 PropertyDetails details = PropertyDetails(attributes, NORMAL, index); | 1693 PropertyDetails details = PropertyDetails(attributes, NORMAL, index); |
| 1688 dict->SetNextEnumerationIndex(index + 1); | 1694 dict->SetNextEnumerationIndex(index + 1); |
| 1689 dict->SetEntry(entry, name, store_value, details); | 1695 dict->SetEntry(entry, name, store_value, details); |
| 1690 return value; | 1696 return value; |
| 1691 } | 1697 } |
| 1692 Heap* heap = GetHeap(); | 1698 Heap* heap = GetHeap(); |
| 1693 { MaybeObject* maybe_store_value = | 1699 { MaybeObject* maybe_store_value = |
| 1694 heap->AllocateJSGlobalPropertyCell(value); | 1700 heap->AllocateJSGlobalPropertyCell(value); |
| 1695 if (!maybe_store_value->ToObject(&store_value)) return maybe_store_value; | 1701 if (!maybe_store_value->ToObject(&store_value)) return maybe_store_value; |
| 1696 } | 1702 } |
| 1697 JSGlobalPropertyCell::cast(store_value)->set_value(value); | 1703 JSGlobalPropertyCell::cast(store_value)->set_value(value); |
| 1698 } | 1704 } |
| 1699 PropertyDetails details = PropertyDetails(attributes, NORMAL); | 1705 PropertyDetails details = PropertyDetails(attributes, NORMAL); |
| 1700 Object* result; | 1706 Object* result; |
| 1701 { MaybeObject* maybe_result = dict->Add(name, store_value, details); | 1707 { MaybeObject* maybe_result = dict->Add(name, store_value, details); |
| 1702 if (!maybe_result->ToObject(&result)) return maybe_result; | 1708 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 1703 } | 1709 } |
| 1704 if (dict != result) set_properties(StringDictionary::cast(result)); | 1710 if (dict != result) set_properties(NameDictionary::cast(result)); |
| 1705 return value; | 1711 return value; |
| 1706 } | 1712 } |
| 1707 | 1713 |
| 1708 | 1714 |
| 1709 MaybeObject* JSObject::AddProperty(String* name, | 1715 MaybeObject* JSObject::AddProperty(Name* name, |
| 1710 Object* value, | 1716 Object* value, |
| 1711 PropertyAttributes attributes, | 1717 PropertyAttributes attributes, |
| 1712 StrictModeFlag strict_mode, | 1718 StrictModeFlag strict_mode, |
| 1713 JSReceiver::StoreFromKeyed store_mode, | 1719 JSReceiver::StoreFromKeyed store_mode, |
| 1714 ExtensibilityCheck extensibility_check) { | 1720 ExtensibilityCheck extensibility_check) { |
| 1715 ASSERT(!IsJSGlobalProxy()); | 1721 ASSERT(!IsJSGlobalProxy()); |
| 1716 Map* map_of_this = map(); | 1722 Map* map_of_this = map(); |
| 1717 Heap* heap = GetHeap(); | 1723 Heap* heap = GetHeap(); |
| 1718 Isolate* isolate = heap->isolate(); | 1724 Isolate* isolate = heap->isolate(); |
| 1719 MaybeObject* result; | 1725 MaybeObject* result; |
| 1720 if (extensibility_check == PERFORM_EXTENSIBILITY_CHECK && | 1726 if (extensibility_check == PERFORM_EXTENSIBILITY_CHECK && |
| 1721 !map_of_this->is_extensible()) { | 1727 !map_of_this->is_extensible()) { |
| 1722 if (strict_mode == kNonStrictMode) { | 1728 if (strict_mode == kNonStrictMode) { |
| 1723 return value; | 1729 return value; |
| 1724 } else { | 1730 } else { |
| 1725 Handle<Object> args[1] = {Handle<String>(name)}; | 1731 Handle<Object> args[1] = {Handle<Name>(name)}; |
| 1726 return isolate->Throw( | 1732 return isolate->Throw( |
| 1727 *FACTORY->NewTypeError("object_not_extensible", | 1733 *FACTORY->NewTypeError("object_not_extensible", |
| 1728 HandleVector(args, 1))); | 1734 HandleVector(args, 1))); |
| 1729 } | 1735 } |
| 1730 } | 1736 } |
| 1731 | 1737 |
| 1732 if (HasFastProperties()) { | 1738 if (HasFastProperties()) { |
| 1733 // Ensure the descriptor array does not get too big. | 1739 // Ensure the descriptor array does not get too big. |
| 1734 if (map_of_this->NumberOfOwnDescriptors() < | 1740 if (map_of_this->NumberOfOwnDescriptors() < |
| 1735 DescriptorArray::kMaxNumberOfDescriptors) { | 1741 DescriptorArray::kMaxNumberOfDescriptors) { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1761 handle(name, isolate), | 1767 handle(name, isolate), |
| 1762 handle(heap->the_hole_value(), isolate)); | 1768 handle(heap->the_hole_value(), isolate)); |
| 1763 } | 1769 } |
| 1764 | 1770 |
| 1765 return *hresult; | 1771 return *hresult; |
| 1766 } | 1772 } |
| 1767 | 1773 |
| 1768 | 1774 |
| 1769 void JSObject::EnqueueChangeRecord(Handle<JSObject> object, | 1775 void JSObject::EnqueueChangeRecord(Handle<JSObject> object, |
| 1770 const char* type_str, | 1776 const char* type_str, |
| 1771 Handle<String> name, | 1777 Handle<Name> name, |
| 1772 Handle<Object> old_value) { | 1778 Handle<Object> old_value) { |
| 1773 Isolate* isolate = object->GetIsolate(); | 1779 Isolate* isolate = object->GetIsolate(); |
| 1774 HandleScope scope; | 1780 HandleScope scope; |
| 1775 Handle<String> type = isolate->factory()->InternalizeUtf8String(type_str); | 1781 Handle<String> type = isolate->factory()->InternalizeUtf8String(type_str); |
| 1776 if (object->IsJSGlobalObject()) { | 1782 if (object->IsJSGlobalObject()) { |
| 1777 object = handle(JSGlobalObject::cast(*object)->global_receiver(), isolate); | 1783 object = handle(JSGlobalObject::cast(*object)->global_receiver(), isolate); |
| 1778 } | 1784 } |
| 1779 Handle<Object> args[] = { type, object, name, old_value }; | 1785 Handle<Object> args[] = { type, object, name, old_value }; |
| 1780 bool threw; | 1786 bool threw; |
| 1781 Execution::Call(Handle<JSFunction>(isolate->observers_notify_change()), | 1787 Execution::Call(Handle<JSFunction>(isolate->observers_notify_change()), |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1794 isolate->factory()->undefined_value(), | 1800 isolate->factory()->undefined_value(), |
| 1795 0, | 1801 0, |
| 1796 NULL, | 1802 NULL, |
| 1797 &threw); | 1803 &threw); |
| 1798 ASSERT(!threw); | 1804 ASSERT(!threw); |
| 1799 isolate->set_observer_delivery_pending(false); | 1805 isolate->set_observer_delivery_pending(false); |
| 1800 } | 1806 } |
| 1801 | 1807 |
| 1802 | 1808 |
| 1803 MaybeObject* JSObject::SetPropertyPostInterceptor( | 1809 MaybeObject* JSObject::SetPropertyPostInterceptor( |
| 1804 String* name, | 1810 Name* name, |
| 1805 Object* value, | 1811 Object* value, |
| 1806 PropertyAttributes attributes, | 1812 PropertyAttributes attributes, |
| 1807 StrictModeFlag strict_mode, | 1813 StrictModeFlag strict_mode, |
| 1808 ExtensibilityCheck extensibility_check) { | 1814 ExtensibilityCheck extensibility_check) { |
| 1809 // Check local property, ignore interceptor. | 1815 // Check local property, ignore interceptor. |
| 1810 LookupResult result(GetIsolate()); | 1816 LookupResult result(GetIsolate()); |
| 1811 LocalLookupRealNamedProperty(name, &result); | 1817 LocalLookupRealNamedProperty(name, &result); |
| 1812 if (!result.IsFound()) map()->LookupTransition(this, name, &result); | 1818 if (!result.IsFound()) map()->LookupTransition(this, name, &result); |
| 1813 if (result.IsFound()) { | 1819 if (result.IsFound()) { |
| 1814 // An existing property or a map transition was found. Use set property to | 1820 // An existing property or a map transition was found. Use set property to |
| 1815 // handle all these cases. | 1821 // handle all these cases. |
| 1816 return SetProperty(&result, name, value, attributes, strict_mode); | 1822 return SetProperty(&result, name, value, attributes, strict_mode); |
| 1817 } | 1823 } |
| 1818 bool done = false; | 1824 bool done = false; |
| 1819 MaybeObject* result_object; | 1825 MaybeObject* result_object; |
| 1820 result_object = | 1826 result_object = |
| 1821 SetPropertyViaPrototypes(name, value, attributes, strict_mode, &done); | 1827 SetPropertyViaPrototypes(name, value, attributes, strict_mode, &done); |
| 1822 if (done) return result_object; | 1828 if (done) return result_object; |
| 1823 // Add a new real property. | 1829 // Add a new real property. |
| 1824 return AddProperty(name, value, attributes, strict_mode, | 1830 return AddProperty(name, value, attributes, strict_mode, |
| 1825 MAY_BE_STORE_FROM_KEYED, extensibility_check); | 1831 MAY_BE_STORE_FROM_KEYED, extensibility_check); |
| 1826 } | 1832 } |
| 1827 | 1833 |
| 1828 | 1834 |
| 1829 MaybeObject* JSObject::ReplaceSlowProperty(String* name, | 1835 MaybeObject* JSObject::ReplaceSlowProperty(Name* name, |
| 1830 Object* value, | 1836 Object* value, |
| 1831 PropertyAttributes attributes) { | 1837 PropertyAttributes attributes) { |
| 1832 StringDictionary* dictionary = property_dictionary(); | 1838 NameDictionary* dictionary = property_dictionary(); |
| 1833 int old_index = dictionary->FindEntry(name); | 1839 int old_index = dictionary->FindEntry(name); |
| 1834 int new_enumeration_index = 0; // 0 means "Use the next available index." | 1840 int new_enumeration_index = 0; // 0 means "Use the next available index." |
| 1835 if (old_index != -1) { | 1841 if (old_index != -1) { |
| 1836 // All calls to ReplaceSlowProperty have had all transitions removed. | 1842 // All calls to ReplaceSlowProperty have had all transitions removed. |
| 1837 new_enumeration_index = dictionary->DetailsAt(old_index).dictionary_index(); | 1843 new_enumeration_index = dictionary->DetailsAt(old_index).dictionary_index(); |
| 1838 } | 1844 } |
| 1839 | 1845 |
| 1840 PropertyDetails new_details(attributes, NORMAL, new_enumeration_index); | 1846 PropertyDetails new_details(attributes, NORMAL, new_enumeration_index); |
| 1841 return SetNormalizedProperty(name, value, new_details); | 1847 return SetNormalizedProperty(name, value, new_details); |
| 1842 } | 1848 } |
| 1843 | 1849 |
| 1844 | 1850 |
| 1845 MaybeObject* JSObject::ConvertTransitionToMapTransition( | 1851 MaybeObject* JSObject::ConvertTransitionToMapTransition( |
| 1846 int transition_index, | 1852 int transition_index, |
| 1847 String* name, | 1853 Name* name, |
| 1848 Object* new_value, | 1854 Object* new_value, |
| 1849 PropertyAttributes attributes) { | 1855 PropertyAttributes attributes) { |
| 1850 Map* old_map = map(); | 1856 Map* old_map = map(); |
| 1851 Map* old_target = old_map->GetTransition(transition_index); | 1857 Map* old_target = old_map->GetTransition(transition_index); |
| 1852 Object* result; | 1858 Object* result; |
| 1853 | 1859 |
| 1854 MaybeObject* maybe_result = | 1860 MaybeObject* maybe_result = |
| 1855 ConvertDescriptorToField(name, new_value, attributes); | 1861 ConvertDescriptorToField(name, new_value, attributes); |
| 1856 if (!maybe_result->To(&result)) return maybe_result; | 1862 if (!maybe_result->To(&result)) return maybe_result; |
| 1857 | 1863 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1883 } | 1889 } |
| 1884 old_map->set_owns_descriptors(false); | 1890 old_map->set_owns_descriptors(false); |
| 1885 } | 1891 } |
| 1886 | 1892 |
| 1887 old_map->SetTransition(transition_index, new_map); | 1893 old_map->SetTransition(transition_index, new_map); |
| 1888 new_map->SetBackPointer(old_map); | 1894 new_map->SetBackPointer(old_map); |
| 1889 return result; | 1895 return result; |
| 1890 } | 1896 } |
| 1891 | 1897 |
| 1892 | 1898 |
| 1893 MaybeObject* JSObject::ConvertDescriptorToField(String* name, | 1899 MaybeObject* JSObject::ConvertDescriptorToField(Name* name, |
| 1894 Object* new_value, | 1900 Object* new_value, |
| 1895 PropertyAttributes attributes) { | 1901 PropertyAttributes attributes) { |
| 1896 if (map()->unused_property_fields() == 0 && | 1902 if (map()->unused_property_fields() == 0 && |
| 1897 TooManyFastProperties(properties()->length(), MAY_BE_STORE_FROM_KEYED)) { | 1903 TooManyFastProperties(properties()->length(), MAY_BE_STORE_FROM_KEYED)) { |
| 1898 Object* obj; | 1904 Object* obj; |
| 1899 MaybeObject* maybe_obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); | 1905 MaybeObject* maybe_obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); |
| 1900 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 1906 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 1901 return ReplaceSlowProperty(name, new_value, attributes); | 1907 return ReplaceSlowProperty(name, new_value, attributes); |
| 1902 } | 1908 } |
| 1903 | 1909 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1926 set_map(new_map); | 1932 set_map(new_map); |
| 1927 if (new_properties != NULL) { | 1933 if (new_properties != NULL) { |
| 1928 set_properties(new_properties); | 1934 set_properties(new_properties); |
| 1929 } | 1935 } |
| 1930 return FastPropertyAtPut(index, new_value); | 1936 return FastPropertyAtPut(index, new_value); |
| 1931 } | 1937 } |
| 1932 | 1938 |
| 1933 | 1939 |
| 1934 | 1940 |
| 1935 MaybeObject* JSObject::SetPropertyWithInterceptor( | 1941 MaybeObject* JSObject::SetPropertyWithInterceptor( |
| 1936 String* name, | 1942 Name* name, |
| 1937 Object* value, | 1943 Object* value, |
| 1938 PropertyAttributes attributes, | 1944 PropertyAttributes attributes, |
| 1939 StrictModeFlag strict_mode) { | 1945 StrictModeFlag strict_mode) { |
| 1946 // TODO(rossberg): Support symbols in the API. |
| 1947 if (name->IsSymbol()) return value; |
| 1940 Isolate* isolate = GetIsolate(); | 1948 Isolate* isolate = GetIsolate(); |
| 1941 HandleScope scope(isolate); | 1949 HandleScope scope(isolate); |
| 1942 Handle<JSObject> this_handle(this); | 1950 Handle<JSObject> this_handle(this); |
| 1943 Handle<String> name_handle(name); | 1951 Handle<String> name_handle(String::cast(name)); |
| 1944 Handle<Object> value_handle(value, isolate); | 1952 Handle<Object> value_handle(value, isolate); |
| 1945 Handle<InterceptorInfo> interceptor(GetNamedInterceptor()); | 1953 Handle<InterceptorInfo> interceptor(GetNamedInterceptor()); |
| 1946 if (!interceptor->setter()->IsUndefined()) { | 1954 if (!interceptor->setter()->IsUndefined()) { |
| 1947 LOG(isolate, ApiNamedPropertyAccess("interceptor-named-set", this, name)); | 1955 LOG(isolate, ApiNamedPropertyAccess("interceptor-named-set", this, name)); |
| 1948 CustomArguments args(isolate, interceptor->data(), this, this); | 1956 CustomArguments args(isolate, interceptor->data(), this, this); |
| 1949 v8::AccessorInfo info(args.end()); | 1957 v8::AccessorInfo info(args.end()); |
| 1950 v8::NamedPropertySetter setter = | 1958 v8::NamedPropertySetter setter = |
| 1951 v8::ToCData<v8::NamedPropertySetter>(interceptor->setter()); | 1959 v8::ToCData<v8::NamedPropertySetter>(interceptor->setter()); |
| 1952 v8::Handle<v8::Value> result; | 1960 v8::Handle<v8::Value> result; |
| 1953 { | 1961 { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1969 *value_handle, | 1977 *value_handle, |
| 1970 attributes, | 1978 attributes, |
| 1971 strict_mode, | 1979 strict_mode, |
| 1972 PERFORM_EXTENSIBILITY_CHECK); | 1980 PERFORM_EXTENSIBILITY_CHECK); |
| 1973 RETURN_IF_SCHEDULED_EXCEPTION(isolate); | 1981 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 1974 return raw_result; | 1982 return raw_result; |
| 1975 } | 1983 } |
| 1976 | 1984 |
| 1977 | 1985 |
| 1978 Handle<Object> JSReceiver::SetProperty(Handle<JSReceiver> object, | 1986 Handle<Object> JSReceiver::SetProperty(Handle<JSReceiver> object, |
| 1979 Handle<String> key, | 1987 Handle<Name> key, |
| 1980 Handle<Object> value, | 1988 Handle<Object> value, |
| 1981 PropertyAttributes attributes, | 1989 PropertyAttributes attributes, |
| 1982 StrictModeFlag strict_mode) { | 1990 StrictModeFlag strict_mode) { |
| 1983 CALL_HEAP_FUNCTION(object->GetIsolate(), | 1991 CALL_HEAP_FUNCTION(object->GetIsolate(), |
| 1984 object->SetProperty(*key, *value, attributes, strict_mode), | 1992 object->SetProperty(*key, *value, attributes, strict_mode), |
| 1985 Object); | 1993 Object); |
| 1986 } | 1994 } |
| 1987 | 1995 |
| 1988 | 1996 |
| 1989 MaybeObject* JSReceiver::SetProperty(String* name, | 1997 MaybeObject* JSReceiver::SetProperty(Name* name, |
| 1990 Object* value, | 1998 Object* value, |
| 1991 PropertyAttributes attributes, | 1999 PropertyAttributes attributes, |
| 1992 StrictModeFlag strict_mode, | 2000 StrictModeFlag strict_mode, |
| 1993 JSReceiver::StoreFromKeyed store_mode) { | 2001 JSReceiver::StoreFromKeyed store_mode) { |
| 1994 LookupResult result(GetIsolate()); | 2002 LookupResult result(GetIsolate()); |
| 1995 LocalLookup(name, &result, true); | 2003 LocalLookup(name, &result, true); |
| 1996 if (!result.IsFound()) { | 2004 if (!result.IsFound()) { |
| 1997 map()->LookupTransition(JSObject::cast(this), name, &result); | 2005 map()->LookupTransition(JSObject::cast(this), name, &result); |
| 1998 } | 2006 } |
| 1999 return SetProperty(&result, name, value, attributes, strict_mode, store_mode); | 2007 return SetProperty(&result, name, value, attributes, strict_mode, store_mode); |
| 2000 } | 2008 } |
| 2001 | 2009 |
| 2002 | 2010 |
| 2003 MaybeObject* JSObject::SetPropertyWithCallback(Object* structure, | 2011 MaybeObject* JSObject::SetPropertyWithCallback(Object* structure, |
| 2004 String* name, | 2012 Name* name, |
| 2005 Object* value, | 2013 Object* value, |
| 2006 JSObject* holder, | 2014 JSObject* holder, |
| 2007 StrictModeFlag strict_mode) { | 2015 StrictModeFlag strict_mode) { |
| 2008 Isolate* isolate = GetIsolate(); | 2016 Isolate* isolate = GetIsolate(); |
| 2009 HandleScope scope(isolate); | 2017 HandleScope scope(isolate); |
| 2010 | 2018 |
| 2011 // We should never get here to initialize a const with the hole | 2019 // We should never get here to initialize a const with the hole |
| 2012 // value since a const declaration would conflict with the setter. | 2020 // value since a const declaration would conflict with the setter. |
| 2013 ASSERT(!value->IsTheHole()); | 2021 ASSERT(!value->IsTheHole()); |
| 2014 Handle<Object> value_handle(value, isolate); | 2022 Handle<Object> value_handle(value, isolate); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 2032 if (!data->IsCompatibleReceiver(this)) { | 2040 if (!data->IsCompatibleReceiver(this)) { |
| 2033 Handle<Object> name_handle(name); | 2041 Handle<Object> name_handle(name); |
| 2034 Handle<Object> receiver_handle(this); | 2042 Handle<Object> receiver_handle(this); |
| 2035 Handle<Object> args[2] = { name_handle, receiver_handle }; | 2043 Handle<Object> args[2] = { name_handle, receiver_handle }; |
| 2036 Handle<Object> error = | 2044 Handle<Object> error = |
| 2037 isolate->factory()->NewTypeError("incompatible_method_receiver", | 2045 isolate->factory()->NewTypeError("incompatible_method_receiver", |
| 2038 HandleVector(args, | 2046 HandleVector(args, |
| 2039 ARRAY_SIZE(args))); | 2047 ARRAY_SIZE(args))); |
| 2040 return isolate->Throw(*error); | 2048 return isolate->Throw(*error); |
| 2041 } | 2049 } |
| 2050 // TODO(rossberg): Support symbols in the API. |
| 2051 if (name->IsSymbol()) return value; |
| 2042 Object* call_obj = data->setter(); | 2052 Object* call_obj = data->setter(); |
| 2043 v8::AccessorSetter call_fun = v8::ToCData<v8::AccessorSetter>(call_obj); | 2053 v8::AccessorSetter call_fun = v8::ToCData<v8::AccessorSetter>(call_obj); |
| 2044 if (call_fun == NULL) return value; | 2054 if (call_fun == NULL) return value; |
| 2045 Handle<String> key(name); | 2055 Handle<String> key(String::cast(name)); |
| 2046 LOG(isolate, ApiNamedPropertyAccess("store", this, name)); | 2056 LOG(isolate, ApiNamedPropertyAccess("store", this, name)); |
| 2047 CustomArguments args(isolate, data->data(), this, JSObject::cast(holder)); | 2057 CustomArguments args(isolate, data->data(), this, JSObject::cast(holder)); |
| 2048 v8::AccessorInfo info(args.end()); | 2058 v8::AccessorInfo info(args.end()); |
| 2049 { | 2059 { |
| 2050 // Leaving JavaScript. | 2060 // Leaving JavaScript. |
| 2051 VMState state(isolate, EXTERNAL); | 2061 VMState state(isolate, EXTERNAL); |
| 2052 call_fun(v8::Utils::ToLocal(key), | 2062 call_fun(v8::Utils::ToLocal(key), |
| 2053 v8::Utils::ToLocal(value_handle), | 2063 v8::Utils::ToLocal(value_handle), |
| 2054 info); | 2064 info); |
| 2055 } | 2065 } |
| 2056 RETURN_IF_SCHEDULED_EXCEPTION(isolate); | 2066 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 2057 return *value_handle; | 2067 return *value_handle; |
| 2058 } | 2068 } |
| 2059 | 2069 |
| 2060 if (structure->IsAccessorPair()) { | 2070 if (structure->IsAccessorPair()) { |
| 2061 Object* setter = AccessorPair::cast(structure)->setter(); | 2071 Object* setter = AccessorPair::cast(structure)->setter(); |
| 2062 if (setter->IsSpecFunction()) { | 2072 if (setter->IsSpecFunction()) { |
| 2063 // TODO(rossberg): nicer would be to cast to some JSCallable here... | 2073 // TODO(rossberg): nicer would be to cast to some JSCallable here... |
| 2064 return SetPropertyWithDefinedSetter(JSReceiver::cast(setter), value); | 2074 return SetPropertyWithDefinedSetter(JSReceiver::cast(setter), value); |
| 2065 } else { | 2075 } else { |
| 2066 if (strict_mode == kNonStrictMode) { | 2076 if (strict_mode == kNonStrictMode) { |
| 2067 return value; | 2077 return value; |
| 2068 } | 2078 } |
| 2069 Handle<String> key(name); | 2079 Handle<Name> key(name); |
| 2070 Handle<Object> holder_handle(holder, isolate); | 2080 Handle<Object> holder_handle(holder, isolate); |
| 2071 Handle<Object> args[2] = { key, holder_handle }; | 2081 Handle<Object> args[2] = { key, holder_handle }; |
| 2072 return isolate->Throw( | 2082 return isolate->Throw( |
| 2073 *isolate->factory()->NewTypeError("no_setter_in_callback", | 2083 *isolate->factory()->NewTypeError("no_setter_in_callback", |
| 2074 HandleVector(args, 2))); | 2084 HandleVector(args, 2))); |
| 2075 } | 2085 } |
| 2076 } | 2086 } |
| 2077 | 2087 |
| 2078 UNREACHABLE(); | 2088 UNREACHABLE(); |
| 2079 return NULL; | 2089 return NULL; |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2139 JSObject::cast(pt), | 2149 JSObject::cast(pt), |
| 2140 strict_mode); | 2150 strict_mode); |
| 2141 } | 2151 } |
| 2142 } | 2152 } |
| 2143 } | 2153 } |
| 2144 *found = false; | 2154 *found = false; |
| 2145 return heap->the_hole_value(); | 2155 return heap->the_hole_value(); |
| 2146 } | 2156 } |
| 2147 | 2157 |
| 2148 MaybeObject* JSObject::SetPropertyViaPrototypes( | 2158 MaybeObject* JSObject::SetPropertyViaPrototypes( |
| 2149 String* name, | 2159 Name* name, |
| 2150 Object* value, | 2160 Object* value, |
| 2151 PropertyAttributes attributes, | 2161 PropertyAttributes attributes, |
| 2152 StrictModeFlag strict_mode, | 2162 StrictModeFlag strict_mode, |
| 2153 bool* done) { | 2163 bool* done) { |
| 2154 Heap* heap = GetHeap(); | 2164 Heap* heap = GetHeap(); |
| 2155 Isolate* isolate = heap->isolate(); | 2165 Isolate* isolate = heap->isolate(); |
| 2156 | 2166 |
| 2157 *done = false; | 2167 *done = false; |
| 2158 // We could not find a local property so let's check whether there is an | 2168 // We could not find a local property so let's check whether there is an |
| 2159 // accessor that wants to handle the property, or whether the property is | 2169 // accessor that wants to handle the property, or whether the property is |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2271 | 2281 |
| 2272 void Map::AppendCallbackDescriptors(Handle<Map> map, | 2282 void Map::AppendCallbackDescriptors(Handle<Map> map, |
| 2273 Handle<Object> descriptors) { | 2283 Handle<Object> descriptors) { |
| 2274 Isolate* isolate = map->GetIsolate(); | 2284 Isolate* isolate = map->GetIsolate(); |
| 2275 Handle<DescriptorArray> array(map->instance_descriptors()); | 2285 Handle<DescriptorArray> array(map->instance_descriptors()); |
| 2276 NeanderArray callbacks(descriptors); | 2286 NeanderArray callbacks(descriptors); |
| 2277 int nof_callbacks = callbacks.length(); | 2287 int nof_callbacks = callbacks.length(); |
| 2278 | 2288 |
| 2279 ASSERT(array->NumberOfSlackDescriptors() >= nof_callbacks); | 2289 ASSERT(array->NumberOfSlackDescriptors() >= nof_callbacks); |
| 2280 | 2290 |
| 2281 // Ensure the keys are internalized strings before writing them into the | 2291 // Ensure the keys are unique names before writing them into the |
| 2282 // instance descriptor. Since it may cause a GC, it has to be done before we | 2292 // instance descriptor. Since it may cause a GC, it has to be done before we |
| 2283 // temporarily put the heap in an invalid state while appending descriptors. | 2293 // temporarily put the heap in an invalid state while appending descriptors. |
| 2284 for (int i = 0; i < nof_callbacks; ++i) { | 2294 for (int i = 0; i < nof_callbacks; ++i) { |
| 2285 Handle<AccessorInfo> entry(AccessorInfo::cast(callbacks.get(i))); | 2295 Handle<AccessorInfo> entry(AccessorInfo::cast(callbacks.get(i))); |
| 2286 Handle<String> key = | 2296 if (!entry->name()->IsUniqueName()) { |
| 2287 isolate->factory()->InternalizedStringFromString( | 2297 Handle<String> key = |
| 2288 Handle<String>(String::cast(entry->name()))); | 2298 isolate->factory()->InternalizedStringFromString( |
| 2289 entry->set_name(*key); | 2299 Handle<String>(String::cast(entry->name()))); |
| 2300 entry->set_name(*key); |
| 2301 } |
| 2290 } | 2302 } |
| 2291 | 2303 |
| 2292 int nof = map->NumberOfOwnDescriptors(); | 2304 int nof = map->NumberOfOwnDescriptors(); |
| 2293 | 2305 |
| 2294 // Fill in new callback descriptors. Process the callbacks from | 2306 // Fill in new callback descriptors. Process the callbacks from |
| 2295 // back to front so that the last callback with a given name takes | 2307 // back to front so that the last callback with a given name takes |
| 2296 // precedence over previously added callbacks with that name. | 2308 // precedence over previously added callbacks with that name. |
| 2297 for (int i = nof_callbacks - 1; i >= 0; i--) { | 2309 for (int i = nof_callbacks - 1; i >= 0; i--) { |
| 2298 AccessorInfo* entry = AccessorInfo::cast(callbacks.get(i)); | 2310 AccessorInfo* entry = AccessorInfo::cast(callbacks.get(i)); |
| 2299 String* key = String::cast(entry->name()); | 2311 Name* key = Name::cast(entry->name()); |
| 2300 // Check if a descriptor with this name already exists before writing. | 2312 // Check if a descriptor with this name already exists before writing. |
| 2301 if (array->Search(key, nof) == DescriptorArray::kNotFound) { | 2313 if (array->Search(key, nof) == DescriptorArray::kNotFound) { |
| 2302 CallbacksDescriptor desc(key, entry, entry->property_attributes()); | 2314 CallbacksDescriptor desc(key, entry, entry->property_attributes()); |
| 2303 array->Append(&desc); | 2315 array->Append(&desc); |
| 2304 nof += 1; | 2316 nof += 1; |
| 2305 } | 2317 } |
| 2306 } | 2318 } |
| 2307 | 2319 |
| 2308 map->SetNumberOfOwnDescriptors(nof); | 2320 map->SetNumberOfOwnDescriptors(nof); |
| 2309 } | 2321 } |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2448 Map* closest_map = FindClosestElementsTransition(start_map, to_kind); | 2460 Map* closest_map = FindClosestElementsTransition(start_map, to_kind); |
| 2449 | 2461 |
| 2450 if (closest_map->elements_kind() == to_kind) { | 2462 if (closest_map->elements_kind() == to_kind) { |
| 2451 return closest_map; | 2463 return closest_map; |
| 2452 } | 2464 } |
| 2453 | 2465 |
| 2454 return AddMissingElementsTransitions(closest_map, to_kind); | 2466 return AddMissingElementsTransitions(closest_map, to_kind); |
| 2455 } | 2467 } |
| 2456 | 2468 |
| 2457 | 2469 |
| 2458 void JSObject::LocalLookupRealNamedProperty(String* name, | 2470 void JSObject::LocalLookupRealNamedProperty(Name* name, LookupResult* result) { |
| 2459 LookupResult* result) { | |
| 2460 if (IsJSGlobalProxy()) { | 2471 if (IsJSGlobalProxy()) { |
| 2461 Object* proto = GetPrototype(); | 2472 Object* proto = GetPrototype(); |
| 2462 if (proto->IsNull()) return result->NotFound(); | 2473 if (proto->IsNull()) return result->NotFound(); |
| 2463 ASSERT(proto->IsJSGlobalObject()); | 2474 ASSERT(proto->IsJSGlobalObject()); |
| 2464 // A GlobalProxy's prototype should always be a proper JSObject. | 2475 // A GlobalProxy's prototype should always be a proper JSObject. |
| 2465 return JSObject::cast(proto)->LocalLookupRealNamedProperty(name, result); | 2476 return JSObject::cast(proto)->LocalLookupRealNamedProperty(name, result); |
| 2466 } | 2477 } |
| 2467 | 2478 |
| 2468 if (HasFastProperties()) { | 2479 if (HasFastProperties()) { |
| 2469 map()->LookupDescriptor(this, name, result); | 2480 map()->LookupDescriptor(this, name, result); |
| 2470 // A property or a map transition was found. We return all of these result | 2481 // A property or a map transition was found. We return all of these result |
| 2471 // types because LocalLookupRealNamedProperty is used when setting | 2482 // types because LocalLookupRealNamedProperty is used when setting |
| 2472 // properties where map transitions are handled. | 2483 // properties where map transitions are handled. |
| 2473 ASSERT(!result->IsFound() || | 2484 ASSERT(!result->IsFound() || |
| 2474 (result->holder() == this && result->IsFastPropertyType())); | 2485 (result->holder() == this && result->IsFastPropertyType())); |
| 2475 // Disallow caching for uninitialized constants. These can only | 2486 // Disallow caching for uninitialized constants. These can only |
| 2476 // occur as fields. | 2487 // occur as fields. |
| 2477 if (result->IsField() && | 2488 if (result->IsField() && |
| 2478 result->IsReadOnly() && | 2489 result->IsReadOnly() && |
| 2479 FastPropertyAt(result->GetFieldIndex().field_index())->IsTheHole()) { | 2490 FastPropertyAt(result->GetFieldIndex().field_index())->IsTheHole()) { |
| 2480 result->DisallowCaching(); | 2491 result->DisallowCaching(); |
| 2481 } | 2492 } |
| 2482 return; | 2493 return; |
| 2483 } | 2494 } |
| 2484 | 2495 |
| 2485 int entry = property_dictionary()->FindEntry(name); | 2496 int entry = property_dictionary()->FindEntry(name); |
| 2486 if (entry != StringDictionary::kNotFound) { | 2497 if (entry != NameDictionary::kNotFound) { |
| 2487 Object* value = property_dictionary()->ValueAt(entry); | 2498 Object* value = property_dictionary()->ValueAt(entry); |
| 2488 if (IsGlobalObject()) { | 2499 if (IsGlobalObject()) { |
| 2489 PropertyDetails d = property_dictionary()->DetailsAt(entry); | 2500 PropertyDetails d = property_dictionary()->DetailsAt(entry); |
| 2490 if (d.IsDeleted()) { | 2501 if (d.IsDeleted()) { |
| 2491 result->NotFound(); | 2502 result->NotFound(); |
| 2492 return; | 2503 return; |
| 2493 } | 2504 } |
| 2494 value = JSGlobalPropertyCell::cast(value)->value(); | 2505 value = JSGlobalPropertyCell::cast(value)->value(); |
| 2495 } | 2506 } |
| 2496 // Make sure to disallow caching for uninitialized constants | 2507 // Make sure to disallow caching for uninitialized constants |
| 2497 // found in the dictionary-mode objects. | 2508 // found in the dictionary-mode objects. |
| 2498 if (value->IsTheHole()) result->DisallowCaching(); | 2509 if (value->IsTheHole()) result->DisallowCaching(); |
| 2499 result->DictionaryResult(this, entry); | 2510 result->DictionaryResult(this, entry); |
| 2500 return; | 2511 return; |
| 2501 } | 2512 } |
| 2502 | 2513 |
| 2503 result->NotFound(); | 2514 result->NotFound(); |
| 2504 } | 2515 } |
| 2505 | 2516 |
| 2506 | 2517 |
| 2507 void JSObject::LookupRealNamedProperty(String* name, LookupResult* result) { | 2518 void JSObject::LookupRealNamedProperty(Name* name, LookupResult* result) { |
| 2508 LocalLookupRealNamedProperty(name, result); | 2519 LocalLookupRealNamedProperty(name, result); |
| 2509 if (result->IsFound()) return; | 2520 if (result->IsFound()) return; |
| 2510 | 2521 |
| 2511 LookupRealNamedPropertyInPrototypes(name, result); | 2522 LookupRealNamedPropertyInPrototypes(name, result); |
| 2512 } | 2523 } |
| 2513 | 2524 |
| 2514 | 2525 |
| 2515 void JSObject::LookupRealNamedPropertyInPrototypes(String* name, | 2526 void JSObject::LookupRealNamedPropertyInPrototypes(Name* name, |
| 2516 LookupResult* result) { | 2527 LookupResult* result) { |
| 2517 Heap* heap = GetHeap(); | 2528 Heap* heap = GetHeap(); |
| 2518 for (Object* pt = GetPrototype(); | 2529 for (Object* pt = GetPrototype(); |
| 2519 pt != heap->null_value(); | 2530 pt != heap->null_value(); |
| 2520 pt = pt->GetPrototype()) { | 2531 pt = pt->GetPrototype()) { |
| 2521 if (pt->IsJSProxy()) { | 2532 if (pt->IsJSProxy()) { |
| 2522 return result->HandlerResult(JSProxy::cast(pt)); | 2533 return result->HandlerResult(JSProxy::cast(pt)); |
| 2523 } | 2534 } |
| 2524 JSObject::cast(pt)->LocalLookupRealNamedProperty(name, result); | 2535 JSObject::cast(pt)->LocalLookupRealNamedProperty(name, result); |
| 2525 ASSERT(!(result->IsFound() && result->type() == INTERCEPTOR)); | 2536 ASSERT(!(result->IsFound() && result->type() == INTERCEPTOR)); |
| 2526 if (result->IsFound()) return; | 2537 if (result->IsFound()) return; |
| 2527 } | 2538 } |
| 2528 result->NotFound(); | 2539 result->NotFound(); |
| 2529 } | 2540 } |
| 2530 | 2541 |
| 2531 | 2542 |
| 2532 // We only need to deal with CALLBACKS and INTERCEPTORS | 2543 // We only need to deal with CALLBACKS and INTERCEPTORS |
| 2533 MaybeObject* JSObject::SetPropertyWithFailedAccessCheck( | 2544 MaybeObject* JSObject::SetPropertyWithFailedAccessCheck( |
| 2534 LookupResult* result, | 2545 LookupResult* result, |
| 2535 String* name, | 2546 Name* name, |
| 2536 Object* value, | 2547 Object* value, |
| 2537 bool check_prototype, | 2548 bool check_prototype, |
| 2538 StrictModeFlag strict_mode) { | 2549 StrictModeFlag strict_mode) { |
| 2539 if (check_prototype && !result->IsProperty()) { | 2550 if (check_prototype && !result->IsProperty()) { |
| 2540 LookupRealNamedPropertyInPrototypes(name, result); | 2551 LookupRealNamedPropertyInPrototypes(name, result); |
| 2541 } | 2552 } |
| 2542 | 2553 |
| 2543 if (result->IsProperty()) { | 2554 if (result->IsProperty()) { |
| 2544 if (!result->IsReadOnly()) { | 2555 if (!result->IsReadOnly()) { |
| 2545 switch (result->type()) { | 2556 switch (result->type()) { |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2580 | 2591 |
| 2581 Isolate* isolate = GetIsolate(); | 2592 Isolate* isolate = GetIsolate(); |
| 2582 HandleScope scope(isolate); | 2593 HandleScope scope(isolate); |
| 2583 Handle<Object> value_handle(value); | 2594 Handle<Object> value_handle(value); |
| 2584 isolate->ReportFailedAccessCheck(this, v8::ACCESS_SET); | 2595 isolate->ReportFailedAccessCheck(this, v8::ACCESS_SET); |
| 2585 return *value_handle; | 2596 return *value_handle; |
| 2586 } | 2597 } |
| 2587 | 2598 |
| 2588 | 2599 |
| 2589 MaybeObject* JSReceiver::SetProperty(LookupResult* result, | 2600 MaybeObject* JSReceiver::SetProperty(LookupResult* result, |
| 2590 String* key, | 2601 Name* key, |
| 2591 Object* value, | 2602 Object* value, |
| 2592 PropertyAttributes attributes, | 2603 PropertyAttributes attributes, |
| 2593 StrictModeFlag strict_mode, | 2604 StrictModeFlag strict_mode, |
| 2594 JSReceiver::StoreFromKeyed store_mode) { | 2605 JSReceiver::StoreFromKeyed store_mode) { |
| 2595 if (result->IsHandler()) { | 2606 if (result->IsHandler()) { |
| 2596 return result->proxy()->SetPropertyWithHandler( | 2607 return result->proxy()->SetPropertyWithHandler( |
| 2597 this, key, value, attributes, strict_mode); | 2608 this, key, value, attributes, strict_mode); |
| 2598 } else { | 2609 } else { |
| 2599 return JSObject::cast(this)->SetPropertyForResult( | 2610 return JSObject::cast(this)->SetPropertyForResult( |
| 2600 result, key, value, attributes, strict_mode, store_mode); | 2611 result, key, value, attributes, strict_mode, store_mode); |
| 2601 } | 2612 } |
| 2602 } | 2613 } |
| 2603 | 2614 |
| 2604 | 2615 |
| 2605 bool JSProxy::HasPropertyWithHandler(String* name_raw) { | 2616 bool JSProxy::HasPropertyWithHandler(Name* name_raw) { |
| 2606 Isolate* isolate = GetIsolate(); | 2617 Isolate* isolate = GetIsolate(); |
| 2607 HandleScope scope(isolate); | 2618 HandleScope scope(isolate); |
| 2608 Handle<Object> receiver(this); | 2619 Handle<Object> receiver(this); |
| 2609 Handle<Object> name(name_raw); | 2620 Handle<Object> name(name_raw); |
| 2610 | 2621 |
| 2611 Handle<Object> args[] = { name }; | 2622 Handle<Object> args[] = { name }; |
| 2612 Handle<Object> result = CallTrap( | 2623 Handle<Object> result = CallTrap( |
| 2613 "has", isolate->derived_has_trap(), ARRAY_SIZE(args), args); | 2624 "has", isolate->derived_has_trap(), ARRAY_SIZE(args), args); |
| 2614 if (isolate->has_pending_exception()) return false; | 2625 if (isolate->has_pending_exception()) return false; |
| 2615 | 2626 |
| 2616 return result->ToBoolean()->IsTrue(); | 2627 return result->ToBoolean()->IsTrue(); |
| 2617 } | 2628 } |
| 2618 | 2629 |
| 2619 | 2630 |
| 2620 MUST_USE_RESULT MaybeObject* JSProxy::SetPropertyWithHandler( | 2631 MUST_USE_RESULT MaybeObject* JSProxy::SetPropertyWithHandler( |
| 2621 JSReceiver* receiver_raw, | 2632 JSReceiver* receiver_raw, |
| 2622 String* name_raw, | 2633 Name* name_raw, |
| 2623 Object* value_raw, | 2634 Object* value_raw, |
| 2624 PropertyAttributes attributes, | 2635 PropertyAttributes attributes, |
| 2625 StrictModeFlag strict_mode) { | 2636 StrictModeFlag strict_mode) { |
| 2626 Isolate* isolate = GetIsolate(); | 2637 Isolate* isolate = GetIsolate(); |
| 2627 HandleScope scope(isolate); | 2638 HandleScope scope(isolate); |
| 2628 Handle<JSReceiver> receiver(receiver_raw); | 2639 Handle<JSReceiver> receiver(receiver_raw); |
| 2629 Handle<Object> name(name_raw); | 2640 Handle<Object> name(name_raw); |
| 2630 Handle<Object> value(value_raw); | 2641 Handle<Object> value(value_raw); |
| 2631 | 2642 |
| 2632 Handle<Object> args[] = { receiver, name, value }; | 2643 Handle<Object> args[] = { receiver, name, value }; |
| 2633 CallTrap("set", isolate->derived_set_trap(), ARRAY_SIZE(args), args); | 2644 CallTrap("set", isolate->derived_set_trap(), ARRAY_SIZE(args), args); |
| 2634 if (isolate->has_pending_exception()) return Failure::Exception(); | 2645 if (isolate->has_pending_exception()) return Failure::Exception(); |
| 2635 | 2646 |
| 2636 return *value; | 2647 return *value; |
| 2637 } | 2648 } |
| 2638 | 2649 |
| 2639 | 2650 |
| 2640 MUST_USE_RESULT MaybeObject* JSProxy::SetPropertyViaPrototypesWithHandler( | 2651 MUST_USE_RESULT MaybeObject* JSProxy::SetPropertyViaPrototypesWithHandler( |
| 2641 JSReceiver* receiver_raw, | 2652 JSReceiver* receiver_raw, |
| 2642 String* name_raw, | 2653 Name* name_raw, |
| 2643 Object* value_raw, | 2654 Object* value_raw, |
| 2644 PropertyAttributes attributes, | 2655 PropertyAttributes attributes, |
| 2645 StrictModeFlag strict_mode, | 2656 StrictModeFlag strict_mode, |
| 2646 bool* done) { | 2657 bool* done) { |
| 2647 Isolate* isolate = GetIsolate(); | 2658 Isolate* isolate = GetIsolate(); |
| 2648 Handle<JSProxy> proxy(this); | 2659 Handle<JSProxy> proxy(this); |
| 2649 Handle<JSReceiver> receiver(receiver_raw); | 2660 Handle<JSReceiver> receiver(receiver_raw); |
| 2650 Handle<String> name(name_raw); | 2661 Handle<Name> name(name_raw); |
| 2651 Handle<Object> value(value_raw); | 2662 Handle<Object> value(value_raw); |
| 2652 Handle<Object> handler(this->handler()); // Trap might morph proxy. | 2663 Handle<Object> handler(this->handler()); // Trap might morph proxy. |
| 2653 | 2664 |
| 2654 *done = true; // except where redefined... | 2665 *done = true; // except where redefined... |
| 2655 Handle<Object> args[] = { name }; | 2666 Handle<Object> args[] = { name }; |
| 2656 Handle<Object> result = proxy->CallTrap( | 2667 Handle<Object> result = proxy->CallTrap( |
| 2657 "getPropertyDescriptor", Handle<Object>(), ARRAY_SIZE(args), args); | 2668 "getPropertyDescriptor", Handle<Object>(), ARRAY_SIZE(args), args); |
| 2658 if (isolate->has_pending_exception()) return Failure::Exception(); | 2669 if (isolate->has_pending_exception()) return Failure::Exception(); |
| 2659 | 2670 |
| 2660 if (result->IsUndefined()) { | 2671 if (result->IsUndefined()) { |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2725 | 2736 |
| 2726 if (strict_mode == kNonStrictMode) return *value; | 2737 if (strict_mode == kNonStrictMode) return *value; |
| 2727 Handle<Object> args2[] = { name, proxy }; | 2738 Handle<Object> args2[] = { name, proxy }; |
| 2728 Handle<Object> error = isolate->factory()->NewTypeError( | 2739 Handle<Object> error = isolate->factory()->NewTypeError( |
| 2729 "no_setter_in_callback", HandleVector(args2, ARRAY_SIZE(args2))); | 2740 "no_setter_in_callback", HandleVector(args2, ARRAY_SIZE(args2))); |
| 2730 return isolate->Throw(*error); | 2741 return isolate->Throw(*error); |
| 2731 } | 2742 } |
| 2732 | 2743 |
| 2733 | 2744 |
| 2734 MUST_USE_RESULT MaybeObject* JSProxy::DeletePropertyWithHandler( | 2745 MUST_USE_RESULT MaybeObject* JSProxy::DeletePropertyWithHandler( |
| 2735 String* name_raw, DeleteMode mode) { | 2746 Name* name_raw, DeleteMode mode) { |
| 2736 Isolate* isolate = GetIsolate(); | 2747 Isolate* isolate = GetIsolate(); |
| 2737 HandleScope scope(isolate); | 2748 HandleScope scope(isolate); |
| 2738 Handle<JSProxy> receiver(this); | 2749 Handle<JSProxy> receiver(this); |
| 2739 Handle<Object> name(name_raw); | 2750 Handle<Object> name(name_raw); |
| 2740 | 2751 |
| 2741 Handle<Object> args[] = { name }; | 2752 Handle<Object> args[] = { name }; |
| 2742 Handle<Object> result = CallTrap( | 2753 Handle<Object> result = CallTrap( |
| 2743 "delete", Handle<Object>(), ARRAY_SIZE(args), args); | 2754 "delete", Handle<Object>(), ARRAY_SIZE(args), args); |
| 2744 if (isolate->has_pending_exception()) return Failure::Exception(); | 2755 if (isolate->has_pending_exception()) return Failure::Exception(); |
| 2745 | 2756 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 2763 DeleteMode mode) { | 2774 DeleteMode mode) { |
| 2764 Isolate* isolate = GetIsolate(); | 2775 Isolate* isolate = GetIsolate(); |
| 2765 HandleScope scope(isolate); | 2776 HandleScope scope(isolate); |
| 2766 Handle<String> name = isolate->factory()->Uint32ToString(index); | 2777 Handle<String> name = isolate->factory()->Uint32ToString(index); |
| 2767 return JSProxy::DeletePropertyWithHandler(*name, mode); | 2778 return JSProxy::DeletePropertyWithHandler(*name, mode); |
| 2768 } | 2779 } |
| 2769 | 2780 |
| 2770 | 2781 |
| 2771 MUST_USE_RESULT PropertyAttributes JSProxy::GetPropertyAttributeWithHandler( | 2782 MUST_USE_RESULT PropertyAttributes JSProxy::GetPropertyAttributeWithHandler( |
| 2772 JSReceiver* receiver_raw, | 2783 JSReceiver* receiver_raw, |
| 2773 String* name_raw) { | 2784 Name* name_raw) { |
| 2774 Isolate* isolate = GetIsolate(); | 2785 Isolate* isolate = GetIsolate(); |
| 2775 HandleScope scope(isolate); | 2786 HandleScope scope(isolate); |
| 2776 Handle<JSProxy> proxy(this); | 2787 Handle<JSProxy> proxy(this); |
| 2777 Handle<Object> handler(this->handler()); // Trap might morph proxy. | 2788 Handle<Object> handler(this->handler()); // Trap might morph proxy. |
| 2778 Handle<JSReceiver> receiver(receiver_raw); | 2789 Handle<JSReceiver> receiver(receiver_raw); |
| 2779 Handle<Object> name(name_raw); | 2790 Handle<Object> name(name_raw); |
| 2780 | 2791 |
| 2781 Handle<Object> args[] = { name }; | 2792 Handle<Object> args[] = { name }; |
| 2782 Handle<Object> result = CallTrap( | 2793 Handle<Object> result = CallTrap( |
| 2783 "getPropertyDescriptor", Handle<Object>(), ARRAY_SIZE(args), args); | 2794 "getPropertyDescriptor", Handle<Object>(), ARRAY_SIZE(args), args); |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2890 | 2901 |
| 2891 void JSObject::AddFastPropertyUsingMap(Handle<JSObject> object, | 2902 void JSObject::AddFastPropertyUsingMap(Handle<JSObject> object, |
| 2892 Handle<Map> map) { | 2903 Handle<Map> map) { |
| 2893 CALL_HEAP_FUNCTION_VOID( | 2904 CALL_HEAP_FUNCTION_VOID( |
| 2894 object->GetIsolate(), | 2905 object->GetIsolate(), |
| 2895 object->AddFastPropertyUsingMap(*map)); | 2906 object->AddFastPropertyUsingMap(*map)); |
| 2896 } | 2907 } |
| 2897 | 2908 |
| 2898 | 2909 |
| 2899 MaybeObject* JSObject::SetPropertyForResult(LookupResult* lookup, | 2910 MaybeObject* JSObject::SetPropertyForResult(LookupResult* lookup, |
| 2900 String* name_raw, | 2911 Name* name_raw, |
| 2901 Object* value_raw, | 2912 Object* value_raw, |
| 2902 PropertyAttributes attributes, | 2913 PropertyAttributes attributes, |
| 2903 StrictModeFlag strict_mode, | 2914 StrictModeFlag strict_mode, |
| 2904 StoreFromKeyed store_mode) { | 2915 StoreFromKeyed store_mode) { |
| 2905 Heap* heap = GetHeap(); | 2916 Heap* heap = GetHeap(); |
| 2906 Isolate* isolate = heap->isolate(); | 2917 Isolate* isolate = heap->isolate(); |
| 2907 // Make sure that the top context does not change when doing callbacks or | 2918 // Make sure that the top context does not change when doing callbacks or |
| 2908 // interceptor calls. | 2919 // interceptor calls. |
| 2909 AssertNoContextChange ncc; | 2920 AssertNoContextChange ncc; |
| 2910 | 2921 |
| 2911 // Optimization for 2-byte strings often used as keys in a decompression | 2922 // Optimization for 2-byte strings often used as keys in a decompression |
| 2912 // dictionary. We internalize these short keys to avoid constantly | 2923 // dictionary. We internalize these short keys to avoid constantly |
| 2913 // reallocating them. | 2924 // reallocating them. |
| 2914 if (!name_raw->IsInternalizedString() && name_raw->length() <= 2) { | 2925 if (name_raw->IsString() && !name_raw->IsInternalizedString() && |
| 2926 String::cast(name_raw)->length() <= 2) { |
| 2915 Object* internalized_version; | 2927 Object* internalized_version; |
| 2916 { MaybeObject* maybe_string_version = heap->InternalizeString(name_raw); | 2928 { MaybeObject* maybe_string_version = |
| 2929 heap->InternalizeString(String::cast(name_raw)); |
| 2917 if (maybe_string_version->ToObject(&internalized_version)) { | 2930 if (maybe_string_version->ToObject(&internalized_version)) { |
| 2918 name_raw = String::cast(internalized_version); | 2931 name_raw = String::cast(internalized_version); |
| 2919 } | 2932 } |
| 2920 } | 2933 } |
| 2921 } | 2934 } |
| 2922 | 2935 |
| 2923 // Check access rights if needed. | 2936 // Check access rights if needed. |
| 2924 if (IsAccessCheckNeeded()) { | 2937 if (IsAccessCheckNeeded()) { |
| 2925 if (!isolate->MayNamedAccess(this, name_raw, v8::ACCESS_SET)) { | 2938 if (!isolate->MayNamedAccess(this, name_raw, v8::ACCESS_SET)) { |
| 2926 return SetPropertyWithFailedAccessCheck( | 2939 return SetPropertyWithFailedAccessCheck( |
| 2927 lookup, name_raw, value_raw, true, strict_mode); | 2940 lookup, name_raw, value_raw, true, strict_mode); |
| 2928 } | 2941 } |
| 2929 } | 2942 } |
| 2930 | 2943 |
| 2931 if (IsJSGlobalProxy()) { | 2944 if (IsJSGlobalProxy()) { |
| 2932 Object* proto = GetPrototype(); | 2945 Object* proto = GetPrototype(); |
| 2933 if (proto->IsNull()) return value_raw; | 2946 if (proto->IsNull()) return value_raw; |
| 2934 ASSERT(proto->IsJSGlobalObject()); | 2947 ASSERT(proto->IsJSGlobalObject()); |
| 2935 return JSObject::cast(proto)->SetPropertyForResult( | 2948 return JSObject::cast(proto)->SetPropertyForResult( |
| 2936 lookup, name_raw, value_raw, attributes, strict_mode, store_mode); | 2949 lookup, name_raw, value_raw, attributes, strict_mode, store_mode); |
| 2937 } | 2950 } |
| 2938 | 2951 |
| 2939 ASSERT(!lookup->IsFound() || lookup->holder() == this || | 2952 ASSERT(!lookup->IsFound() || lookup->holder() == this || |
| 2940 lookup->holder()->map()->is_hidden_prototype()); | 2953 lookup->holder()->map()->is_hidden_prototype()); |
| 2941 | 2954 |
| 2942 // From this point on everything needs to be handlified, because | 2955 // From this point on everything needs to be handlified, because |
| 2943 // SetPropertyViaPrototypes might call back into JavaScript. | 2956 // SetPropertyViaPrototypes might call back into JavaScript. |
| 2944 HandleScope scope(isolate); | 2957 HandleScope scope(isolate); |
| 2945 Handle<JSObject> self(this); | 2958 Handle<JSObject> self(this); |
| 2946 Handle<String> name(name_raw); | 2959 Handle<Name> name(name_raw); |
| 2947 Handle<Object> value(value_raw, isolate); | 2960 Handle<Object> value(value_raw, isolate); |
| 2948 | 2961 |
| 2949 if (!lookup->IsProperty() && !self->IsJSContextExtensionObject()) { | 2962 if (!lookup->IsProperty() && !self->IsJSContextExtensionObject()) { |
| 2950 bool done = false; | 2963 bool done = false; |
| 2951 MaybeObject* result_object = self->SetPropertyViaPrototypes( | 2964 MaybeObject* result_object = self->SetPropertyViaPrototypes( |
| 2952 *name, *value, attributes, strict_mode, &done); | 2965 *name, *value, attributes, strict_mode, &done); |
| 2953 if (done) return result_object; | 2966 if (done) return result_object; |
| 2954 } | 2967 } |
| 2955 | 2968 |
| 2956 if (!lookup->IsFound()) { | 2969 if (!lookup->IsFound()) { |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3069 // present, add it with attributes NONE. This code is an exact clone of | 3082 // present, add it with attributes NONE. This code is an exact clone of |
| 3070 // SetProperty, with the check for IsReadOnly and the check for a | 3083 // SetProperty, with the check for IsReadOnly and the check for a |
| 3071 // callback setter removed. The two lines looking up the LookupResult | 3084 // callback setter removed. The two lines looking up the LookupResult |
| 3072 // result are also added. If one of the functions is changed, the other | 3085 // result are also added. If one of the functions is changed, the other |
| 3073 // should be. | 3086 // should be. |
| 3074 // Note that this method cannot be used to set the prototype of a function | 3087 // Note that this method cannot be used to set the prototype of a function |
| 3075 // because ConvertDescriptorToField() which is called in "case CALLBACKS:" | 3088 // because ConvertDescriptorToField() which is called in "case CALLBACKS:" |
| 3076 // doesn't handle function prototypes correctly. | 3089 // doesn't handle function prototypes correctly. |
| 3077 Handle<Object> JSObject::SetLocalPropertyIgnoreAttributes( | 3090 Handle<Object> JSObject::SetLocalPropertyIgnoreAttributes( |
| 3078 Handle<JSObject> object, | 3091 Handle<JSObject> object, |
| 3079 Handle<String> key, | 3092 Handle<Name> key, |
| 3080 Handle<Object> value, | 3093 Handle<Object> value, |
| 3081 PropertyAttributes attributes) { | 3094 PropertyAttributes attributes) { |
| 3082 CALL_HEAP_FUNCTION( | 3095 CALL_HEAP_FUNCTION( |
| 3083 object->GetIsolate(), | 3096 object->GetIsolate(), |
| 3084 object->SetLocalPropertyIgnoreAttributes(*key, *value, attributes), | 3097 object->SetLocalPropertyIgnoreAttributes(*key, *value, attributes), |
| 3085 Object); | 3098 Object); |
| 3086 } | 3099 } |
| 3087 | 3100 |
| 3088 | 3101 |
| 3089 MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes( | 3102 MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes( |
| 3090 String* name_raw, | 3103 Name* name_raw, |
| 3091 Object* value_raw, | 3104 Object* value_raw, |
| 3092 PropertyAttributes attributes) { | 3105 PropertyAttributes attributes) { |
| 3093 // Make sure that the top context does not change when doing callbacks or | 3106 // Make sure that the top context does not change when doing callbacks or |
| 3094 // interceptor calls. | 3107 // interceptor calls. |
| 3095 AssertNoContextChange ncc; | 3108 AssertNoContextChange ncc; |
| 3096 Isolate* isolate = GetIsolate(); | 3109 Isolate* isolate = GetIsolate(); |
| 3097 LookupResult lookup(isolate); | 3110 LookupResult lookup(isolate); |
| 3098 LocalLookup(name_raw, &lookup, true); | 3111 LocalLookup(name_raw, &lookup, true); |
| 3099 if (!lookup.IsFound()) map()->LookupTransition(this, name_raw, &lookup); | 3112 if (!lookup.IsFound()) map()->LookupTransition(this, name_raw, &lookup); |
| 3100 // Check access rights if needed. | 3113 // Check access rights if needed. |
| (...skipping 19 matching lines...) Expand all Loading... |
| 3120 | 3133 |
| 3121 // Check for accessor in prototype chain removed here in clone. | 3134 // Check for accessor in prototype chain removed here in clone. |
| 3122 if (!lookup.IsFound()) { | 3135 if (!lookup.IsFound()) { |
| 3123 // Neither properties nor transitions found. | 3136 // Neither properties nor transitions found. |
| 3124 return AddProperty(name_raw, value_raw, attributes, kNonStrictMode); | 3137 return AddProperty(name_raw, value_raw, attributes, kNonStrictMode); |
| 3125 } | 3138 } |
| 3126 | 3139 |
| 3127 // From this point on everything needs to be handlified. | 3140 // From this point on everything needs to be handlified. |
| 3128 HandleScope scope(isolate); | 3141 HandleScope scope(isolate); |
| 3129 Handle<JSObject> self(this); | 3142 Handle<JSObject> self(this); |
| 3130 Handle<String> name(name_raw); | 3143 Handle<Name> name(name_raw); |
| 3131 Handle<Object> value(value_raw, isolate); | 3144 Handle<Object> value(value_raw, isolate); |
| 3132 | 3145 |
| 3133 Handle<Object> old_value(isolate->heap()->the_hole_value(), isolate); | 3146 Handle<Object> old_value(isolate->heap()->the_hole_value(), isolate); |
| 3134 PropertyAttributes old_attributes = ABSENT; | 3147 PropertyAttributes old_attributes = ABSENT; |
| 3135 bool is_observed = FLAG_harmony_observation && self->map()->is_observed(); | 3148 bool is_observed = FLAG_harmony_observation && self->map()->is_observed(); |
| 3136 if (is_observed) { | 3149 if (is_observed) { |
| 3137 if (lookup.IsDataProperty()) old_value = Object::GetProperty(self, name); | 3150 if (lookup.IsDataProperty()) old_value = Object::GetProperty(self, name); |
| 3138 old_attributes = lookup.GetAttributes(); | 3151 old_attributes = lookup.GetAttributes(); |
| 3139 } | 3152 } |
| 3140 | 3153 |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3216 } | 3229 } |
| 3217 } | 3230 } |
| 3218 } | 3231 } |
| 3219 | 3232 |
| 3220 return *hresult; | 3233 return *hresult; |
| 3221 } | 3234 } |
| 3222 | 3235 |
| 3223 | 3236 |
| 3224 PropertyAttributes JSObject::GetPropertyAttributePostInterceptor( | 3237 PropertyAttributes JSObject::GetPropertyAttributePostInterceptor( |
| 3225 JSObject* receiver, | 3238 JSObject* receiver, |
| 3226 String* name, | 3239 Name* name, |
| 3227 bool continue_search) { | 3240 bool continue_search) { |
| 3228 // Check local property, ignore interceptor. | 3241 // Check local property, ignore interceptor. |
| 3229 LookupResult result(GetIsolate()); | 3242 LookupResult result(GetIsolate()); |
| 3230 LocalLookupRealNamedProperty(name, &result); | 3243 LocalLookupRealNamedProperty(name, &result); |
| 3231 if (result.IsFound()) return result.GetAttributes(); | 3244 if (result.IsFound()) return result.GetAttributes(); |
| 3232 | 3245 |
| 3233 if (continue_search) { | 3246 if (continue_search) { |
| 3234 // Continue searching via the prototype chain. | 3247 // Continue searching via the prototype chain. |
| 3235 Object* pt = GetPrototype(); | 3248 Object* pt = GetPrototype(); |
| 3236 if (!pt->IsNull()) { | 3249 if (!pt->IsNull()) { |
| 3237 return JSObject::cast(pt)-> | 3250 return JSObject::cast(pt)-> |
| 3238 GetPropertyAttributeWithReceiver(receiver, name); | 3251 GetPropertyAttributeWithReceiver(receiver, name); |
| 3239 } | 3252 } |
| 3240 } | 3253 } |
| 3241 return ABSENT; | 3254 return ABSENT; |
| 3242 } | 3255 } |
| 3243 | 3256 |
| 3244 | 3257 |
| 3245 PropertyAttributes JSObject::GetPropertyAttributeWithInterceptor( | 3258 PropertyAttributes JSObject::GetPropertyAttributeWithInterceptor( |
| 3246 JSObject* receiver, | 3259 JSObject* receiver, |
| 3247 String* name, | 3260 Name* name, |
| 3248 bool continue_search) { | 3261 bool continue_search) { |
| 3262 // TODO(rossberg): Support symbols in the API. |
| 3263 if (name->IsSymbol()) return ABSENT; |
| 3264 |
| 3249 Isolate* isolate = GetIsolate(); | 3265 Isolate* isolate = GetIsolate(); |
| 3250 | 3266 |
| 3251 // Make sure that the top context does not change when doing | 3267 // Make sure that the top context does not change when doing |
| 3252 // callbacks or interceptor calls. | 3268 // callbacks or interceptor calls. |
| 3253 AssertNoContextChange ncc; | 3269 AssertNoContextChange ncc; |
| 3254 | 3270 |
| 3255 HandleScope scope(isolate); | 3271 HandleScope scope(isolate); |
| 3256 Handle<InterceptorInfo> interceptor(GetNamedInterceptor()); | 3272 Handle<InterceptorInfo> interceptor(GetNamedInterceptor()); |
| 3257 Handle<JSObject> receiver_handle(receiver); | 3273 Handle<JSObject> receiver_handle(receiver); |
| 3258 Handle<JSObject> holder_handle(this); | 3274 Handle<JSObject> holder_handle(this); |
| 3259 Handle<String> name_handle(name); | 3275 Handle<String> name_handle(String::cast(name)); |
| 3260 CustomArguments args(isolate, interceptor->data(), receiver, this); | 3276 CustomArguments args(isolate, interceptor->data(), receiver, this); |
| 3261 v8::AccessorInfo info(args.end()); | 3277 v8::AccessorInfo info(args.end()); |
| 3262 if (!interceptor->query()->IsUndefined()) { | 3278 if (!interceptor->query()->IsUndefined()) { |
| 3263 v8::NamedPropertyQuery query = | 3279 v8::NamedPropertyQuery query = |
| 3264 v8::ToCData<v8::NamedPropertyQuery>(interceptor->query()); | 3280 v8::ToCData<v8::NamedPropertyQuery>(interceptor->query()); |
| 3265 LOG(isolate, | 3281 LOG(isolate, |
| 3266 ApiNamedPropertyAccess("interceptor-named-has", *holder_handle, name)); | 3282 ApiNamedPropertyAccess("interceptor-named-has", *holder_handle, name)); |
| 3267 v8::Handle<v8::Integer> result; | 3283 v8::Handle<v8::Integer> result; |
| 3268 { | 3284 { |
| 3269 // Leaving JavaScript. | 3285 // Leaving JavaScript. |
| (...skipping 18 matching lines...) Expand all Loading... |
| 3288 if (!result.IsEmpty()) return DONT_ENUM; | 3304 if (!result.IsEmpty()) return DONT_ENUM; |
| 3289 } | 3305 } |
| 3290 return holder_handle->GetPropertyAttributePostInterceptor(*receiver_handle, | 3306 return holder_handle->GetPropertyAttributePostInterceptor(*receiver_handle, |
| 3291 *name_handle, | 3307 *name_handle, |
| 3292 continue_search); | 3308 continue_search); |
| 3293 } | 3309 } |
| 3294 | 3310 |
| 3295 | 3311 |
| 3296 PropertyAttributes JSReceiver::GetPropertyAttributeWithReceiver( | 3312 PropertyAttributes JSReceiver::GetPropertyAttributeWithReceiver( |
| 3297 JSReceiver* receiver, | 3313 JSReceiver* receiver, |
| 3298 String* key) { | 3314 Name* key) { |
| 3299 uint32_t index = 0; | 3315 uint32_t index = 0; |
| 3300 if (IsJSObject() && key->AsArrayIndex(&index)) { | 3316 if (IsJSObject() && key->AsArrayIndex(&index)) { |
| 3301 return JSObject::cast(this)->GetElementAttributeWithReceiver( | 3317 return JSObject::cast(this)->GetElementAttributeWithReceiver( |
| 3302 receiver, index, true); | 3318 receiver, index, true); |
| 3303 } | 3319 } |
| 3304 // Named property. | 3320 // Named property. |
| 3305 LookupResult lookup(GetIsolate()); | 3321 LookupResult lookup(GetIsolate()); |
| 3306 Lookup(key, &lookup); | 3322 Lookup(key, &lookup); |
| 3307 return GetPropertyAttributeForResult(receiver, &lookup, key, true); | 3323 return GetPropertyAttributeForResult(receiver, &lookup, key, true); |
| 3308 } | 3324 } |
| 3309 | 3325 |
| 3310 | 3326 |
| 3311 PropertyAttributes JSReceiver::GetPropertyAttributeForResult( | 3327 PropertyAttributes JSReceiver::GetPropertyAttributeForResult( |
| 3312 JSReceiver* receiver, | 3328 JSReceiver* receiver, |
| 3313 LookupResult* lookup, | 3329 LookupResult* lookup, |
| 3314 String* name, | 3330 Name* name, |
| 3315 bool continue_search) { | 3331 bool continue_search) { |
| 3316 // Check access rights if needed. | 3332 // Check access rights if needed. |
| 3317 if (IsAccessCheckNeeded()) { | 3333 if (IsAccessCheckNeeded()) { |
| 3318 JSObject* this_obj = JSObject::cast(this); | 3334 JSObject* this_obj = JSObject::cast(this); |
| 3319 Heap* heap = GetHeap(); | 3335 Heap* heap = GetHeap(); |
| 3320 if (!heap->isolate()->MayNamedAccess(this_obj, name, v8::ACCESS_HAS)) { | 3336 if (!heap->isolate()->MayNamedAccess(this_obj, name, v8::ACCESS_HAS)) { |
| 3321 return this_obj->GetPropertyAttributeWithFailedAccessCheck( | 3337 return this_obj->GetPropertyAttributeWithFailedAccessCheck( |
| 3322 receiver, lookup, name, continue_search); | 3338 receiver, lookup, name, continue_search); |
| 3323 } | 3339 } |
| 3324 } | 3340 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 3338 JSObject::cast(receiver), name, continue_search); | 3354 JSObject::cast(receiver), name, continue_search); |
| 3339 case TRANSITION: | 3355 case TRANSITION: |
| 3340 case NONEXISTENT: | 3356 case NONEXISTENT: |
| 3341 UNREACHABLE(); | 3357 UNREACHABLE(); |
| 3342 } | 3358 } |
| 3343 } | 3359 } |
| 3344 return ABSENT; | 3360 return ABSENT; |
| 3345 } | 3361 } |
| 3346 | 3362 |
| 3347 | 3363 |
| 3348 PropertyAttributes JSReceiver::GetLocalPropertyAttribute(String* name) { | 3364 PropertyAttributes JSReceiver::GetLocalPropertyAttribute(Name* name) { |
| 3349 // Check whether the name is an array index. | 3365 // Check whether the name is an array index. |
| 3350 uint32_t index = 0; | 3366 uint32_t index = 0; |
| 3351 if (IsJSObject() && name->AsArrayIndex(&index)) { | 3367 if (IsJSObject() && name->AsArrayIndex(&index)) { |
| 3352 return GetLocalElementAttribute(index); | 3368 return GetLocalElementAttribute(index); |
| 3353 } | 3369 } |
| 3354 // Named property. | 3370 // Named property. |
| 3355 LookupResult lookup(GetIsolate()); | 3371 LookupResult lookup(GetIsolate()); |
| 3356 LocalLookup(name, &lookup, true); | 3372 LocalLookup(name, &lookup, true); |
| 3357 return GetPropertyAttributeForResult(this, &lookup, name, false); | 3373 return GetPropertyAttributeForResult(this, &lookup, name, false); |
| 3358 } | 3374 } |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3513 | 3529 |
| 3514 void NormalizedMapCache::Clear() { | 3530 void NormalizedMapCache::Clear() { |
| 3515 int entries = length(); | 3531 int entries = length(); |
| 3516 for (int i = 0; i != entries; i++) { | 3532 for (int i = 0; i != entries; i++) { |
| 3517 set_undefined(i); | 3533 set_undefined(i); |
| 3518 } | 3534 } |
| 3519 } | 3535 } |
| 3520 | 3536 |
| 3521 | 3537 |
| 3522 void JSObject::UpdateMapCodeCache(Handle<JSObject> object, | 3538 void JSObject::UpdateMapCodeCache(Handle<JSObject> object, |
| 3523 Handle<String> name, | 3539 Handle<Name> name, |
| 3524 Handle<Code> code) { | 3540 Handle<Code> code) { |
| 3525 Isolate* isolate = object->GetIsolate(); | 3541 Isolate* isolate = object->GetIsolate(); |
| 3526 CALL_HEAP_FUNCTION_VOID(isolate, | 3542 CALL_HEAP_FUNCTION_VOID(isolate, |
| 3527 object->UpdateMapCodeCache(*name, *code)); | 3543 object->UpdateMapCodeCache(*name, *code)); |
| 3528 } | 3544 } |
| 3529 | 3545 |
| 3530 | 3546 |
| 3531 MaybeObject* JSObject::UpdateMapCodeCache(String* name, Code* code) { | 3547 MaybeObject* JSObject::UpdateMapCodeCache(Name* name, Code* code) { |
| 3532 if (map()->is_shared()) { | 3548 if (map()->is_shared()) { |
| 3533 // Fast case maps are never marked as shared. | 3549 // Fast case maps are never marked as shared. |
| 3534 ASSERT(!HasFastProperties()); | 3550 ASSERT(!HasFastProperties()); |
| 3535 // Replace the map with an identical copy that can be safely modified. | 3551 // Replace the map with an identical copy that can be safely modified. |
| 3536 Object* obj; | 3552 Object* obj; |
| 3537 { MaybeObject* maybe_obj = map()->CopyNormalized(KEEP_INOBJECT_PROPERTIES, | 3553 { MaybeObject* maybe_obj = map()->CopyNormalized(KEEP_INOBJECT_PROPERTIES, |
| 3538 UNIQUE_NORMALIZED_MAP); | 3554 UNIQUE_NORMALIZED_MAP); |
| 3539 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 3555 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 3540 } | 3556 } |
| 3541 GetIsolate()->counters()->normalized_maps()->Increment(); | 3557 GetIsolate()->counters()->normalized_maps()->Increment(); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 3567 Map* map_of_this = map(); | 3583 Map* map_of_this = map(); |
| 3568 | 3584 |
| 3569 // Allocate new content. | 3585 // Allocate new content. |
| 3570 int real_size = map_of_this->NumberOfOwnDescriptors(); | 3586 int real_size = map_of_this->NumberOfOwnDescriptors(); |
| 3571 int property_count = real_size; | 3587 int property_count = real_size; |
| 3572 if (expected_additional_properties > 0) { | 3588 if (expected_additional_properties > 0) { |
| 3573 property_count += expected_additional_properties; | 3589 property_count += expected_additional_properties; |
| 3574 } else { | 3590 } else { |
| 3575 property_count += 2; // Make space for two more properties. | 3591 property_count += 2; // Make space for two more properties. |
| 3576 } | 3592 } |
| 3577 StringDictionary* dictionary; | 3593 NameDictionary* dictionary; |
| 3578 MaybeObject* maybe_dictionary = StringDictionary::Allocate(property_count); | 3594 MaybeObject* maybe_dictionary = NameDictionary::Allocate(property_count); |
| 3579 if (!maybe_dictionary->To(&dictionary)) return maybe_dictionary; | 3595 if (!maybe_dictionary->To(&dictionary)) return maybe_dictionary; |
| 3580 | 3596 |
| 3581 DescriptorArray* descs = map_of_this->instance_descriptors(); | 3597 DescriptorArray* descs = map_of_this->instance_descriptors(); |
| 3582 for (int i = 0; i < real_size; i++) { | 3598 for (int i = 0; i < real_size; i++) { |
| 3583 PropertyDetails details = descs->GetDetails(i); | 3599 PropertyDetails details = descs->GetDetails(i); |
| 3584 switch (details.type()) { | 3600 switch (details.type()) { |
| 3585 case CONSTANT_FUNCTION: { | 3601 case CONSTANT_FUNCTION: { |
| 3586 PropertyDetails d = PropertyDetails(details.attributes(), | 3602 PropertyDetails d = PropertyDetails(details.attributes(), |
| 3587 NORMAL, | 3603 NORMAL, |
| 3588 details.descriptor_index()); | 3604 details.descriptor_index()); |
| (...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3832 MaybeObject* JSProxy::GetIdentityHash(CreationFlag flag) { | 3848 MaybeObject* JSProxy::GetIdentityHash(CreationFlag flag) { |
| 3833 Object* hash = this->hash(); | 3849 Object* hash = this->hash(); |
| 3834 if (!hash->IsSmi() && flag == ALLOW_CREATION) { | 3850 if (!hash->IsSmi() && flag == ALLOW_CREATION) { |
| 3835 hash = GenerateIdentityHash(); | 3851 hash = GenerateIdentityHash(); |
| 3836 set_hash(hash); | 3852 set_hash(hash); |
| 3837 } | 3853 } |
| 3838 return hash; | 3854 return hash; |
| 3839 } | 3855 } |
| 3840 | 3856 |
| 3841 | 3857 |
| 3842 Object* JSObject::GetHiddenProperty(String* key) { | 3858 Object* JSObject::GetHiddenProperty(Name* key) { |
| 3843 ASSERT(key->IsInternalizedString()); | 3859 ASSERT(key->IsUniqueName()); |
| 3844 if (IsJSGlobalProxy()) { | 3860 if (IsJSGlobalProxy()) { |
| 3845 // For a proxy, use the prototype as target object. | 3861 // For a proxy, use the prototype as target object. |
| 3846 Object* proxy_parent = GetPrototype(); | 3862 Object* proxy_parent = GetPrototype(); |
| 3847 // If the proxy is detached, return undefined. | 3863 // If the proxy is detached, return undefined. |
| 3848 if (proxy_parent->IsNull()) return GetHeap()->undefined_value(); | 3864 if (proxy_parent->IsNull()) return GetHeap()->undefined_value(); |
| 3849 ASSERT(proxy_parent->IsJSGlobalObject()); | 3865 ASSERT(proxy_parent->IsJSGlobalObject()); |
| 3850 return JSObject::cast(proxy_parent)->GetHiddenProperty(key); | 3866 return JSObject::cast(proxy_parent)->GetHiddenProperty(key); |
| 3851 } | 3867 } |
| 3852 ASSERT(!IsJSGlobalProxy()); | 3868 ASSERT(!IsJSGlobalProxy()); |
| 3853 MaybeObject* hidden_lookup = | 3869 MaybeObject* hidden_lookup = |
| (...skipping 12 matching lines...) Expand all Loading... |
| 3866 if (inline_value->IsUndefined()) return GetHeap()->undefined_value(); | 3882 if (inline_value->IsUndefined()) return GetHeap()->undefined_value(); |
| 3867 | 3883 |
| 3868 ObjectHashTable* hashtable = ObjectHashTable::cast(inline_value); | 3884 ObjectHashTable* hashtable = ObjectHashTable::cast(inline_value); |
| 3869 Object* entry = hashtable->Lookup(key); | 3885 Object* entry = hashtable->Lookup(key); |
| 3870 if (entry->IsTheHole()) return GetHeap()->undefined_value(); | 3886 if (entry->IsTheHole()) return GetHeap()->undefined_value(); |
| 3871 return entry; | 3887 return entry; |
| 3872 } | 3888 } |
| 3873 | 3889 |
| 3874 | 3890 |
| 3875 Handle<Object> JSObject::SetHiddenProperty(Handle<JSObject> obj, | 3891 Handle<Object> JSObject::SetHiddenProperty(Handle<JSObject> obj, |
| 3876 Handle<String> key, | 3892 Handle<Name> key, |
| 3877 Handle<Object> value) { | 3893 Handle<Object> value) { |
| 3878 CALL_HEAP_FUNCTION(obj->GetIsolate(), | 3894 CALL_HEAP_FUNCTION(obj->GetIsolate(), |
| 3879 obj->SetHiddenProperty(*key, *value), | 3895 obj->SetHiddenProperty(*key, *value), |
| 3880 Object); | 3896 Object); |
| 3881 } | 3897 } |
| 3882 | 3898 |
| 3883 | 3899 |
| 3884 MaybeObject* JSObject::SetHiddenProperty(String* key, Object* value) { | 3900 MaybeObject* JSObject::SetHiddenProperty(Name* key, Object* value) { |
| 3885 ASSERT(key->IsInternalizedString()); | 3901 ASSERT(key->IsUniqueName()); |
| 3886 if (IsJSGlobalProxy()) { | 3902 if (IsJSGlobalProxy()) { |
| 3887 // For a proxy, use the prototype as target object. | 3903 // For a proxy, use the prototype as target object. |
| 3888 Object* proxy_parent = GetPrototype(); | 3904 Object* proxy_parent = GetPrototype(); |
| 3889 // If the proxy is detached, return undefined. | 3905 // If the proxy is detached, return undefined. |
| 3890 if (proxy_parent->IsNull()) return GetHeap()->undefined_value(); | 3906 if (proxy_parent->IsNull()) return GetHeap()->undefined_value(); |
| 3891 ASSERT(proxy_parent->IsJSGlobalObject()); | 3907 ASSERT(proxy_parent->IsJSGlobalObject()); |
| 3892 return JSObject::cast(proxy_parent)->SetHiddenProperty(key, value); | 3908 return JSObject::cast(proxy_parent)->SetHiddenProperty(key, value); |
| 3893 } | 3909 } |
| 3894 ASSERT(!IsJSGlobalProxy()); | 3910 ASSERT(!IsJSGlobalProxy()); |
| 3895 MaybeObject* hidden_lookup = | 3911 MaybeObject* hidden_lookup = |
| (...skipping 19 matching lines...) Expand all Loading... |
| 3915 // If adding the key expanded the dictionary (i.e., Add returned a new | 3931 // If adding the key expanded the dictionary (i.e., Add returned a new |
| 3916 // dictionary), store it back to the object. | 3932 // dictionary), store it back to the object. |
| 3917 MaybeObject* store_result = SetHiddenPropertiesHashTable(new_table); | 3933 MaybeObject* store_result = SetHiddenPropertiesHashTable(new_table); |
| 3918 if (store_result->IsFailure()) return store_result; | 3934 if (store_result->IsFailure()) return store_result; |
| 3919 } | 3935 } |
| 3920 // Return this to mark success. | 3936 // Return this to mark success. |
| 3921 return this; | 3937 return this; |
| 3922 } | 3938 } |
| 3923 | 3939 |
| 3924 | 3940 |
| 3925 void JSObject::DeleteHiddenProperty(String* key) { | 3941 void JSObject::DeleteHiddenProperty(Name* key) { |
| 3926 ASSERT(key->IsInternalizedString()); | 3942 ASSERT(key->IsUniqueName()); |
| 3927 if (IsJSGlobalProxy()) { | 3943 if (IsJSGlobalProxy()) { |
| 3928 // For a proxy, use the prototype as target object. | 3944 // For a proxy, use the prototype as target object. |
| 3929 Object* proxy_parent = GetPrototype(); | 3945 Object* proxy_parent = GetPrototype(); |
| 3930 // If the proxy is detached, return immediately. | 3946 // If the proxy is detached, return immediately. |
| 3931 if (proxy_parent->IsNull()) return; | 3947 if (proxy_parent->IsNull()) return; |
| 3932 ASSERT(proxy_parent->IsJSGlobalObject()); | 3948 ASSERT(proxy_parent->IsJSGlobalObject()); |
| 3933 JSObject::cast(proxy_parent)->DeleteHiddenProperty(key); | 3949 JSObject::cast(proxy_parent)->DeleteHiddenProperty(key); |
| 3934 return; | 3950 return; |
| 3935 } | 3951 } |
| 3936 ASSERT(!IsJSGlobalProxy()); | 3952 ASSERT(!IsJSGlobalProxy()); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 3956 } | 3972 } |
| 3957 | 3973 |
| 3958 | 3974 |
| 3959 MaybeObject* JSObject::GetHiddenPropertiesHashTable( | 3975 MaybeObject* JSObject::GetHiddenPropertiesHashTable( |
| 3960 InitializeHiddenProperties init_option) { | 3976 InitializeHiddenProperties init_option) { |
| 3961 ASSERT(!IsJSGlobalProxy()); | 3977 ASSERT(!IsJSGlobalProxy()); |
| 3962 Object* inline_value; | 3978 Object* inline_value; |
| 3963 if (HasFastProperties()) { | 3979 if (HasFastProperties()) { |
| 3964 // If the object has fast properties, check whether the first slot | 3980 // If the object has fast properties, check whether the first slot |
| 3965 // in the descriptor array matches the hidden string. Since the | 3981 // in the descriptor array matches the hidden string. Since the |
| 3966 // hidden strings hash code is zero (and no other string has hash | 3982 // hidden strings hash code is zero (and no other name has hash |
| 3967 // code zero) it will always occupy the first entry if present. | 3983 // code zero) it will always occupy the first entry if present. |
| 3968 DescriptorArray* descriptors = this->map()->instance_descriptors(); | 3984 DescriptorArray* descriptors = this->map()->instance_descriptors(); |
| 3969 if (descriptors->number_of_descriptors() > 0) { | 3985 if (descriptors->number_of_descriptors() > 0) { |
| 3970 int sorted_index = descriptors->GetSortedKeyIndex(0); | 3986 int sorted_index = descriptors->GetSortedKeyIndex(0); |
| 3971 if (descriptors->GetKey(sorted_index) == GetHeap()->hidden_string() && | 3987 if (descriptors->GetKey(sorted_index) == GetHeap()->hidden_string() && |
| 3972 sorted_index < map()->NumberOfOwnDescriptors()) { | 3988 sorted_index < map()->NumberOfOwnDescriptors()) { |
| 3973 ASSERT(descriptors->GetType(sorted_index) == FIELD); | 3989 ASSERT(descriptors->GetType(sorted_index) == FIELD); |
| 3974 inline_value = | 3990 inline_value = |
| 3975 this->FastPropertyAt(descriptors->GetFieldIndex(sorted_index)); | 3991 this->FastPropertyAt(descriptors->GetFieldIndex(sorted_index)); |
| 3976 } else { | 3992 } else { |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4025 | 4041 |
| 4026 | 4042 |
| 4027 MaybeObject* JSObject::SetHiddenPropertiesHashTable(Object* value) { | 4043 MaybeObject* JSObject::SetHiddenPropertiesHashTable(Object* value) { |
| 4028 ASSERT(!IsJSGlobalProxy()); | 4044 ASSERT(!IsJSGlobalProxy()); |
| 4029 // We can store the identity hash inline iff there is no backing store | 4045 // We can store the identity hash inline iff there is no backing store |
| 4030 // for hidden properties yet. | 4046 // for hidden properties yet. |
| 4031 ASSERT(HasHiddenProperties() != value->IsSmi()); | 4047 ASSERT(HasHiddenProperties() != value->IsSmi()); |
| 4032 if (HasFastProperties()) { | 4048 if (HasFastProperties()) { |
| 4033 // If the object has fast properties, check whether the first slot | 4049 // If the object has fast properties, check whether the first slot |
| 4034 // in the descriptor array matches the hidden string. Since the | 4050 // in the descriptor array matches the hidden string. Since the |
| 4035 // hidden strings hash code is zero (and no other string has hash | 4051 // hidden strings hash code is zero (and no other name has hash |
| 4036 // code zero) it will always occupy the first entry if present. | 4052 // code zero) it will always occupy the first entry if present. |
| 4037 DescriptorArray* descriptors = this->map()->instance_descriptors(); | 4053 DescriptorArray* descriptors = this->map()->instance_descriptors(); |
| 4038 if (descriptors->number_of_descriptors() > 0) { | 4054 if (descriptors->number_of_descriptors() > 0) { |
| 4039 int sorted_index = descriptors->GetSortedKeyIndex(0); | 4055 int sorted_index = descriptors->GetSortedKeyIndex(0); |
| 4040 if (descriptors->GetKey(sorted_index) == GetHeap()->hidden_string() && | 4056 if (descriptors->GetKey(sorted_index) == GetHeap()->hidden_string() && |
| 4041 sorted_index < map()->NumberOfOwnDescriptors()) { | 4057 sorted_index < map()->NumberOfOwnDescriptors()) { |
| 4042 ASSERT(descriptors->GetType(sorted_index) == FIELD); | 4058 ASSERT(descriptors->GetType(sorted_index) == FIELD); |
| 4043 this->FastPropertyAtPut(descriptors->GetFieldIndex(sorted_index), | 4059 this->FastPropertyAtPut(descriptors->GetFieldIndex(sorted_index), |
| 4044 value); | 4060 value); |
| 4045 return this; | 4061 return this; |
| 4046 } | 4062 } |
| 4047 } | 4063 } |
| 4048 } | 4064 } |
| 4049 MaybeObject* store_result = | 4065 MaybeObject* store_result = |
| 4050 SetPropertyPostInterceptor(GetHeap()->hidden_string(), | 4066 SetPropertyPostInterceptor(GetHeap()->hidden_string(), |
| 4051 value, | 4067 value, |
| 4052 DONT_ENUM, | 4068 DONT_ENUM, |
| 4053 kNonStrictMode, | 4069 kNonStrictMode, |
| 4054 OMIT_EXTENSIBILITY_CHECK); | 4070 OMIT_EXTENSIBILITY_CHECK); |
| 4055 if (store_result->IsFailure()) return store_result; | 4071 if (store_result->IsFailure()) return store_result; |
| 4056 return this; | 4072 return this; |
| 4057 } | 4073 } |
| 4058 | 4074 |
| 4059 | 4075 |
| 4060 MaybeObject* JSObject::DeletePropertyPostInterceptor(String* name, | 4076 MaybeObject* JSObject::DeletePropertyPostInterceptor(Name* name, |
| 4061 DeleteMode mode) { | 4077 DeleteMode mode) { |
| 4062 // Check local property, ignore interceptor. | 4078 // Check local property, ignore interceptor. |
| 4063 LookupResult result(GetIsolate()); | 4079 LookupResult result(GetIsolate()); |
| 4064 LocalLookupRealNamedProperty(name, &result); | 4080 LocalLookupRealNamedProperty(name, &result); |
| 4065 if (!result.IsFound()) return GetHeap()->true_value(); | 4081 if (!result.IsFound()) return GetHeap()->true_value(); |
| 4066 | 4082 |
| 4067 // Normalize object if needed. | 4083 // Normalize object if needed. |
| 4068 Object* obj; | 4084 Object* obj; |
| 4069 { MaybeObject* maybe_obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); | 4085 { MaybeObject* maybe_obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); |
| 4070 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 4086 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 4071 } | 4087 } |
| 4072 | 4088 |
| 4073 return DeleteNormalizedProperty(name, mode); | 4089 return DeleteNormalizedProperty(name, mode); |
| 4074 } | 4090 } |
| 4075 | 4091 |
| 4076 | 4092 |
| 4077 MaybeObject* JSObject::DeletePropertyWithInterceptor(String* name) { | 4093 MaybeObject* JSObject::DeletePropertyWithInterceptor(Name* name) { |
| 4094 // TODO(rossberg): Support symbols in the API. |
| 4095 if (name->IsSymbol()) return GetHeap()->false_value(); |
| 4096 |
| 4078 Isolate* isolate = GetIsolate(); | 4097 Isolate* isolate = GetIsolate(); |
| 4079 HandleScope scope(isolate); | 4098 HandleScope scope(isolate); |
| 4080 Handle<InterceptorInfo> interceptor(GetNamedInterceptor()); | 4099 Handle<InterceptorInfo> interceptor(GetNamedInterceptor()); |
| 4081 Handle<String> name_handle(name); | 4100 Handle<String> name_handle(String::cast(name)); |
| 4082 Handle<JSObject> this_handle(this); | 4101 Handle<JSObject> this_handle(this); |
| 4083 if (!interceptor->deleter()->IsUndefined()) { | 4102 if (!interceptor->deleter()->IsUndefined()) { |
| 4084 v8::NamedPropertyDeleter deleter = | 4103 v8::NamedPropertyDeleter deleter = |
| 4085 v8::ToCData<v8::NamedPropertyDeleter>(interceptor->deleter()); | 4104 v8::ToCData<v8::NamedPropertyDeleter>(interceptor->deleter()); |
| 4086 LOG(isolate, | 4105 LOG(isolate, |
| 4087 ApiNamedPropertyAccess("interceptor-named-delete", *this_handle, name)); | 4106 ApiNamedPropertyAccess("interceptor-named-delete", *this_handle, name)); |
| 4088 CustomArguments args(isolate, interceptor->data(), this, this); | 4107 CustomArguments args(isolate, interceptor->data(), this, this); |
| 4089 v8::AccessorInfo info(args.end()); | 4108 v8::AccessorInfo info(args.end()); |
| 4090 v8::Handle<v8::Boolean> result; | 4109 v8::Handle<v8::Boolean> result; |
| 4091 { | 4110 { |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4214 if (should_enqueue_change_record && !self->HasLocalElement(index)) { | 4233 if (should_enqueue_change_record && !self->HasLocalElement(index)) { |
| 4215 Handle<String> name = isolate->factory()->Uint32ToString(index); | 4234 Handle<String> name = isolate->factory()->Uint32ToString(index); |
| 4216 EnqueueChangeRecord(self, "deleted", name, old_value); | 4235 EnqueueChangeRecord(self, "deleted", name, old_value); |
| 4217 } | 4236 } |
| 4218 | 4237 |
| 4219 return *hresult; | 4238 return *hresult; |
| 4220 } | 4239 } |
| 4221 | 4240 |
| 4222 | 4241 |
| 4223 Handle<Object> JSObject::DeleteProperty(Handle<JSObject> obj, | 4242 Handle<Object> JSObject::DeleteProperty(Handle<JSObject> obj, |
| 4224 Handle<String> prop) { | 4243 Handle<Name> prop) { |
| 4225 CALL_HEAP_FUNCTION(obj->GetIsolate(), | 4244 CALL_HEAP_FUNCTION(obj->GetIsolate(), |
| 4226 obj->DeleteProperty(*prop, JSObject::NORMAL_DELETION), | 4245 obj->DeleteProperty(*prop, JSObject::NORMAL_DELETION), |
| 4227 Object); | 4246 Object); |
| 4228 } | 4247 } |
| 4229 | 4248 |
| 4230 | 4249 |
| 4231 MaybeObject* JSObject::DeleteProperty(String* name, DeleteMode mode) { | 4250 MaybeObject* JSObject::DeleteProperty(Name* name, DeleteMode mode) { |
| 4232 Isolate* isolate = GetIsolate(); | 4251 Isolate* isolate = GetIsolate(); |
| 4233 // ECMA-262, 3rd, 8.6.2.5 | 4252 // ECMA-262, 3rd, 8.6.2.5 |
| 4234 ASSERT(name->IsString()); | 4253 ASSERT(name->IsName()); |
| 4235 | 4254 |
| 4236 // Check access rights if needed. | 4255 // Check access rights if needed. |
| 4237 if (IsAccessCheckNeeded() && | 4256 if (IsAccessCheckNeeded() && |
| 4238 !isolate->MayNamedAccess(this, name, v8::ACCESS_DELETE)) { | 4257 !isolate->MayNamedAccess(this, name, v8::ACCESS_DELETE)) { |
| 4239 isolate->ReportFailedAccessCheck(this, v8::ACCESS_DELETE); | 4258 isolate->ReportFailedAccessCheck(this, v8::ACCESS_DELETE); |
| 4240 return isolate->heap()->false_value(); | 4259 return isolate->heap()->false_value(); |
| 4241 } | 4260 } |
| 4242 | 4261 |
| 4243 if (IsJSGlobalProxy()) { | 4262 if (IsJSGlobalProxy()) { |
| 4244 Object* proto = GetPrototype(); | 4263 Object* proto = GetPrototype(); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 4263 Handle<Object> args[2] = { Handle<Object>(name), Handle<Object>(this) }; | 4282 Handle<Object> args[2] = { Handle<Object>(name), Handle<Object>(this) }; |
| 4264 return isolate->Throw(*isolate->factory()->NewTypeError( | 4283 return isolate->Throw(*isolate->factory()->NewTypeError( |
| 4265 "strict_delete_property", HandleVector(args, 2))); | 4284 "strict_delete_property", HandleVector(args, 2))); |
| 4266 } | 4285 } |
| 4267 return isolate->heap()->false_value(); | 4286 return isolate->heap()->false_value(); |
| 4268 } | 4287 } |
| 4269 | 4288 |
| 4270 // From this point on everything needs to be handlified. | 4289 // From this point on everything needs to be handlified. |
| 4271 HandleScope scope(isolate); | 4290 HandleScope scope(isolate); |
| 4272 Handle<JSObject> self(this); | 4291 Handle<JSObject> self(this); |
| 4273 Handle<String> hname(name); | 4292 Handle<Name> hname(name); |
| 4274 | 4293 |
| 4275 Handle<Object> old_value(isolate->heap()->the_hole_value()); | 4294 Handle<Object> old_value(isolate->heap()->the_hole_value()); |
| 4276 bool is_observed = FLAG_harmony_observation && self->map()->is_observed(); | 4295 bool is_observed = FLAG_harmony_observation && self->map()->is_observed(); |
| 4277 if (is_observed && lookup.IsDataProperty()) { | 4296 if (is_observed && lookup.IsDataProperty()) { |
| 4278 old_value = Object::GetProperty(self, hname); | 4297 old_value = Object::GetProperty(self, hname); |
| 4279 } | 4298 } |
| 4280 MaybeObject* result; | 4299 MaybeObject* result; |
| 4281 | 4300 |
| 4282 // Check for interceptor. | 4301 // Check for interceptor. |
| 4283 if (lookup.IsInterceptor()) { | 4302 if (lookup.IsInterceptor()) { |
| (...skipping 24 matching lines...) Expand all Loading... |
| 4308 | 4327 |
| 4309 | 4328 |
| 4310 MaybeObject* JSReceiver::DeleteElement(uint32_t index, DeleteMode mode) { | 4329 MaybeObject* JSReceiver::DeleteElement(uint32_t index, DeleteMode mode) { |
| 4311 if (IsJSProxy()) { | 4330 if (IsJSProxy()) { |
| 4312 return JSProxy::cast(this)->DeleteElementWithHandler(index, mode); | 4331 return JSProxy::cast(this)->DeleteElementWithHandler(index, mode); |
| 4313 } | 4332 } |
| 4314 return JSObject::cast(this)->DeleteElement(index, mode); | 4333 return JSObject::cast(this)->DeleteElement(index, mode); |
| 4315 } | 4334 } |
| 4316 | 4335 |
| 4317 | 4336 |
| 4318 MaybeObject* JSReceiver::DeleteProperty(String* name, DeleteMode mode) { | 4337 MaybeObject* JSReceiver::DeleteProperty(Name* name, DeleteMode mode) { |
| 4319 if (IsJSProxy()) { | 4338 if (IsJSProxy()) { |
| 4320 return JSProxy::cast(this)->DeletePropertyWithHandler(name, mode); | 4339 return JSProxy::cast(this)->DeletePropertyWithHandler(name, mode); |
| 4321 } | 4340 } |
| 4322 return JSObject::cast(this)->DeleteProperty(name, mode); | 4341 return JSObject::cast(this)->DeleteProperty(name, mode); |
| 4323 } | 4342 } |
| 4324 | 4343 |
| 4325 | 4344 |
| 4326 bool JSObject::ReferencesObjectFromElements(FixedArray* elements, | 4345 bool JSObject::ReferencesObjectFromElements(FixedArray* elements, |
| 4327 ElementsKind kind, | 4346 ElementsKind kind, |
| 4328 Object* object) { | 4347 Object* object) { |
| (...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4540 int limit = which == ALL_DESCRIPTORS | 4559 int limit = which == ALL_DESCRIPTORS |
| 4541 ? descs->number_of_descriptors() | 4560 ? descs->number_of_descriptors() |
| 4542 : NumberOfOwnDescriptors(); | 4561 : NumberOfOwnDescriptors(); |
| 4543 for (int i = 0; i < limit; i++) { | 4562 for (int i = 0; i < limit; i++) { |
| 4544 if ((descs->GetDetails(i).attributes() & filter) == 0) result++; | 4563 if ((descs->GetDetails(i).attributes() & filter) == 0) result++; |
| 4545 } | 4564 } |
| 4546 return result; | 4565 return result; |
| 4547 } | 4566 } |
| 4548 | 4567 |
| 4549 | 4568 |
| 4550 int Map::PropertyIndexFor(String* name) { | 4569 int Map::PropertyIndexFor(Name* name) { |
| 4551 DescriptorArray* descs = instance_descriptors(); | 4570 DescriptorArray* descs = instance_descriptors(); |
| 4552 int limit = NumberOfOwnDescriptors(); | 4571 int limit = NumberOfOwnDescriptors(); |
| 4553 for (int i = 0; i < limit; i++) { | 4572 for (int i = 0; i < limit; i++) { |
| 4554 if (name->Equals(descs->GetKey(i))) return descs->GetFieldIndex(i); | 4573 if (name->Equals(descs->GetKey(i))) return descs->GetFieldIndex(i); |
| 4555 } | 4574 } |
| 4556 return -1; | 4575 return -1; |
| 4557 } | 4576 } |
| 4558 | 4577 |
| 4559 | 4578 |
| 4560 int Map::NextFreePropertyIndex() { | 4579 int Map::NextFreePropertyIndex() { |
| 4561 int max_index = -1; | 4580 int max_index = -1; |
| 4562 int number_of_own_descriptors = NumberOfOwnDescriptors(); | 4581 int number_of_own_descriptors = NumberOfOwnDescriptors(); |
| 4563 DescriptorArray* descs = instance_descriptors(); | 4582 DescriptorArray* descs = instance_descriptors(); |
| 4564 for (int i = 0; i < number_of_own_descriptors; i++) { | 4583 for (int i = 0; i < number_of_own_descriptors; i++) { |
| 4565 if (descs->GetType(i) == FIELD) { | 4584 if (descs->GetType(i) == FIELD) { |
| 4566 int current_index = descs->GetFieldIndex(i); | 4585 int current_index = descs->GetFieldIndex(i); |
| 4567 if (current_index > max_index) max_index = current_index; | 4586 if (current_index > max_index) max_index = current_index; |
| 4568 } | 4587 } |
| 4569 } | 4588 } |
| 4570 return max_index + 1; | 4589 return max_index + 1; |
| 4571 } | 4590 } |
| 4572 | 4591 |
| 4573 | 4592 |
| 4574 AccessorDescriptor* Map::FindAccessor(String* name) { | 4593 AccessorDescriptor* Map::FindAccessor(Name* name) { |
| 4575 DescriptorArray* descs = instance_descriptors(); | 4594 DescriptorArray* descs = instance_descriptors(); |
| 4576 int number_of_own_descriptors = NumberOfOwnDescriptors(); | 4595 int number_of_own_descriptors = NumberOfOwnDescriptors(); |
| 4577 for (int i = 0; i < number_of_own_descriptors; i++) { | 4596 for (int i = 0; i < number_of_own_descriptors; i++) { |
| 4578 if (descs->GetType(i) == CALLBACKS && name->Equals(descs->GetKey(i))) { | 4597 if (descs->GetType(i) == CALLBACKS && name->Equals(descs->GetKey(i))) { |
| 4579 return descs->GetCallbacks(i); | 4598 return descs->GetCallbacks(i); |
| 4580 } | 4599 } |
| 4581 } | 4600 } |
| 4582 return NULL; | 4601 return NULL; |
| 4583 } | 4602 } |
| 4584 | 4603 |
| 4585 | 4604 |
| 4586 void JSReceiver::LocalLookup( | 4605 void JSReceiver::LocalLookup( |
| 4587 String* name, LookupResult* result, bool search_hidden_prototypes) { | 4606 Name* name, LookupResult* result, bool search_hidden_prototypes) { |
| 4588 ASSERT(name->IsString()); | 4607 ASSERT(name->IsName()); |
| 4589 | 4608 |
| 4590 Heap* heap = GetHeap(); | 4609 Heap* heap = GetHeap(); |
| 4591 | 4610 |
| 4592 if (IsJSGlobalProxy()) { | 4611 if (IsJSGlobalProxy()) { |
| 4593 Object* proto = GetPrototype(); | 4612 Object* proto = GetPrototype(); |
| 4594 if (proto->IsNull()) return result->NotFound(); | 4613 if (proto->IsNull()) return result->NotFound(); |
| 4595 ASSERT(proto->IsJSGlobalObject()); | 4614 ASSERT(proto->IsJSGlobalObject()); |
| 4596 return JSReceiver::cast(proto)->LocalLookup( | 4615 return JSReceiver::cast(proto)->LocalLookup( |
| 4597 name, result, search_hidden_prototypes); | 4616 name, result, search_hidden_prototypes); |
| 4598 } | 4617 } |
| (...skipping 29 matching lines...) Expand all Loading... |
| 4628 | 4647 |
| 4629 Object* proto = js_object->GetPrototype(); | 4648 Object* proto = js_object->GetPrototype(); |
| 4630 if (!proto->IsJSReceiver()) return; | 4649 if (!proto->IsJSReceiver()) return; |
| 4631 JSReceiver* receiver = JSReceiver::cast(proto); | 4650 JSReceiver* receiver = JSReceiver::cast(proto); |
| 4632 if (receiver->map()->is_hidden_prototype()) { | 4651 if (receiver->map()->is_hidden_prototype()) { |
| 4633 receiver->LocalLookup(name, result, search_hidden_prototypes); | 4652 receiver->LocalLookup(name, result, search_hidden_prototypes); |
| 4634 } | 4653 } |
| 4635 } | 4654 } |
| 4636 | 4655 |
| 4637 | 4656 |
| 4638 void JSReceiver::Lookup(String* name, LookupResult* result) { | 4657 void JSReceiver::Lookup(Name* name, LookupResult* result) { |
| 4639 // Ecma-262 3rd 8.6.2.4 | 4658 // Ecma-262 3rd 8.6.2.4 |
| 4640 Heap* heap = GetHeap(); | 4659 Heap* heap = GetHeap(); |
| 4641 for (Object* current = this; | 4660 for (Object* current = this; |
| 4642 current != heap->null_value(); | 4661 current != heap->null_value(); |
| 4643 current = JSObject::cast(current)->GetPrototype()) { | 4662 current = JSObject::cast(current)->GetPrototype()) { |
| 4644 JSReceiver::cast(current)->LocalLookup(name, result, false); | 4663 JSReceiver::cast(current)->LocalLookup(name, result, false); |
| 4645 if (result->IsFound()) return; | 4664 if (result->IsFound()) return; |
| 4646 } | 4665 } |
| 4647 result->NotFound(); | 4666 result->NotFound(); |
| 4648 } | 4667 } |
| 4649 | 4668 |
| 4650 | 4669 |
| 4651 // Search object and its prototype chain for callback properties. | 4670 // Search object and its prototype chain for callback properties. |
| 4652 void JSObject::LookupCallbackProperty(String* name, LookupResult* result) { | 4671 void JSObject::LookupCallbackProperty(Name* name, LookupResult* result) { |
| 4653 Heap* heap = GetHeap(); | 4672 Heap* heap = GetHeap(); |
| 4654 for (Object* current = this; | 4673 for (Object* current = this; |
| 4655 current != heap->null_value() && current->IsJSObject(); | 4674 current != heap->null_value() && current->IsJSObject(); |
| 4656 current = JSObject::cast(current)->GetPrototype()) { | 4675 current = JSObject::cast(current)->GetPrototype()) { |
| 4657 JSObject::cast(current)->LocalLookupRealNamedProperty(name, result); | 4676 JSObject::cast(current)->LocalLookupRealNamedProperty(name, result); |
| 4658 if (result->IsPropertyCallbacks()) return; | 4677 if (result->IsPropertyCallbacks()) return; |
| 4659 } | 4678 } |
| 4660 result->NotFound(); | 4679 result->NotFound(); |
| 4661 } | 4680 } |
| 4662 | 4681 |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4748 AccessorPair* accessors; | 4767 AccessorPair* accessors; |
| 4749 { MaybeObject* maybe_accessors = GetHeap()->AllocateAccessorPair(); | 4768 { MaybeObject* maybe_accessors = GetHeap()->AllocateAccessorPair(); |
| 4750 if (!maybe_accessors->To(&accessors)) return maybe_accessors; | 4769 if (!maybe_accessors->To(&accessors)) return maybe_accessors; |
| 4751 } | 4770 } |
| 4752 accessors->SetComponents(getter, setter); | 4771 accessors->SetComponents(getter, setter); |
| 4753 | 4772 |
| 4754 return SetElementCallback(index, accessors, attributes); | 4773 return SetElementCallback(index, accessors, attributes); |
| 4755 } | 4774 } |
| 4756 | 4775 |
| 4757 | 4776 |
| 4758 MaybeObject* JSObject::CreateAccessorPairFor(String* name) { | 4777 MaybeObject* JSObject::CreateAccessorPairFor(Name* name) { |
| 4759 LookupResult result(GetHeap()->isolate()); | 4778 LookupResult result(GetHeap()->isolate()); |
| 4760 LocalLookupRealNamedProperty(name, &result); | 4779 LocalLookupRealNamedProperty(name, &result); |
| 4761 if (result.IsPropertyCallbacks()) { | 4780 if (result.IsPropertyCallbacks()) { |
| 4762 // Note that the result can actually have IsDontDelete() == true when we | 4781 // Note that the result can actually have IsDontDelete() == true when we |
| 4763 // e.g. have to fall back to the slow case while adding a setter after | 4782 // e.g. have to fall back to the slow case while adding a setter after |
| 4764 // successfully reusing a map transition for a getter. Nevertheless, this is | 4783 // successfully reusing a map transition for a getter. Nevertheless, this is |
| 4765 // OK, because the assertion only holds for the whole addition of both | 4784 // OK, because the assertion only holds for the whole addition of both |
| 4766 // accessors, not for the addition of each part. See first comment in | 4785 // accessors, not for the addition of each part. See first comment in |
| 4767 // DefinePropertyAccessor below. | 4786 // DefinePropertyAccessor below. |
| 4768 Object* obj = result.GetCallbackObject(); | 4787 Object* obj = result.GetCallbackObject(); |
| 4769 if (obj->IsAccessorPair()) { | 4788 if (obj->IsAccessorPair()) { |
| 4770 return AccessorPair::cast(obj)->Copy(); | 4789 return AccessorPair::cast(obj)->Copy(); |
| 4771 } | 4790 } |
| 4772 } | 4791 } |
| 4773 return GetHeap()->AllocateAccessorPair(); | 4792 return GetHeap()->AllocateAccessorPair(); |
| 4774 } | 4793 } |
| 4775 | 4794 |
| 4776 | 4795 |
| 4777 MaybeObject* JSObject::DefinePropertyAccessor(String* name, | 4796 MaybeObject* JSObject::DefinePropertyAccessor(Name* name, |
| 4778 Object* getter, | 4797 Object* getter, |
| 4779 Object* setter, | 4798 Object* setter, |
| 4780 PropertyAttributes attributes) { | 4799 PropertyAttributes attributes) { |
| 4781 // We could assert that the property is configurable here, but we would need | 4800 // We could assert that the property is configurable here, but we would need |
| 4782 // to do a lookup, which seems to be a bit of overkill. | 4801 // to do a lookup, which seems to be a bit of overkill. |
| 4783 Heap* heap = GetHeap(); | 4802 Heap* heap = GetHeap(); |
| 4784 bool only_attribute_changes = getter->IsNull() && setter->IsNull(); | 4803 bool only_attribute_changes = getter->IsNull() && setter->IsNull(); |
| 4785 if (HasFastProperties() && !only_attribute_changes && | 4804 if (HasFastProperties() && !only_attribute_changes && |
| 4786 (map()->NumberOfOwnDescriptors() < | 4805 (map()->NumberOfOwnDescriptors() < |
| 4787 DescriptorArray::kMaxNumberOfDescriptors)) { | 4806 DescriptorArray::kMaxNumberOfDescriptors)) { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 4804 | 4823 |
| 4805 AccessorPair* accessors; | 4824 AccessorPair* accessors; |
| 4806 MaybeObject* maybe_accessors = CreateAccessorPairFor(name); | 4825 MaybeObject* maybe_accessors = CreateAccessorPairFor(name); |
| 4807 if (!maybe_accessors->To(&accessors)) return maybe_accessors; | 4826 if (!maybe_accessors->To(&accessors)) return maybe_accessors; |
| 4808 | 4827 |
| 4809 accessors->SetComponents(getter, setter); | 4828 accessors->SetComponents(getter, setter); |
| 4810 return SetPropertyCallback(name, accessors, attributes); | 4829 return SetPropertyCallback(name, accessors, attributes); |
| 4811 } | 4830 } |
| 4812 | 4831 |
| 4813 | 4832 |
| 4814 bool JSObject::CanSetCallback(String* name) { | 4833 bool JSObject::CanSetCallback(Name* name) { |
| 4815 ASSERT(!IsAccessCheckNeeded() || | 4834 ASSERT(!IsAccessCheckNeeded() || |
| 4816 GetIsolate()->MayNamedAccess(this, name, v8::ACCESS_SET)); | 4835 GetIsolate()->MayNamedAccess(this, name, v8::ACCESS_SET)); |
| 4817 | 4836 |
| 4818 // Check if there is an API defined callback object which prohibits | 4837 // Check if there is an API defined callback object which prohibits |
| 4819 // callback overwriting in this object or its prototype chain. | 4838 // callback overwriting in this object or its prototype chain. |
| 4820 // This mechanism is needed for instance in a browser setting, where | 4839 // This mechanism is needed for instance in a browser setting, where |
| 4821 // certain accessors such as window.location should not be allowed | 4840 // certain accessors such as window.location should not be allowed |
| 4822 // to be overwritten because allowing overwriting could potentially | 4841 // to be overwritten because allowing overwriting could potentially |
| 4823 // cause security problems. | 4842 // cause security problems. |
| 4824 LookupResult callback_result(GetIsolate()); | 4843 LookupResult callback_result(GetIsolate()); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4866 } | 4885 } |
| 4867 parameter_map->set(1, dictionary); | 4886 parameter_map->set(1, dictionary); |
| 4868 } else { | 4887 } else { |
| 4869 set_elements(dictionary); | 4888 set_elements(dictionary); |
| 4870 } | 4889 } |
| 4871 | 4890 |
| 4872 return GetHeap()->undefined_value(); | 4891 return GetHeap()->undefined_value(); |
| 4873 } | 4892 } |
| 4874 | 4893 |
| 4875 | 4894 |
| 4876 MaybeObject* JSObject::SetPropertyCallback(String* name, | 4895 MaybeObject* JSObject::SetPropertyCallback(Name* name, |
| 4877 Object* structure, | 4896 Object* structure, |
| 4878 PropertyAttributes attributes) { | 4897 PropertyAttributes attributes) { |
| 4879 // Normalize object to make this operation simple. | 4898 // Normalize object to make this operation simple. |
| 4880 MaybeObject* maybe_ok = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); | 4899 MaybeObject* maybe_ok = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); |
| 4881 if (maybe_ok->IsFailure()) return maybe_ok; | 4900 if (maybe_ok->IsFailure()) return maybe_ok; |
| 4882 | 4901 |
| 4883 // For the global object allocate a new map to invalidate the global inline | 4902 // For the global object allocate a new map to invalidate the global inline |
| 4884 // caches which have a global property cell reference directly in the code. | 4903 // caches which have a global property cell reference directly in the code. |
| 4885 if (IsGlobalObject()) { | 4904 if (IsGlobalObject()) { |
| 4886 Map* new_map; | 4905 Map* new_map; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 4898 // Update the dictionary with the new CALLBACKS property. | 4917 // Update the dictionary with the new CALLBACKS property. |
| 4899 PropertyDetails details = PropertyDetails(attributes, CALLBACKS); | 4918 PropertyDetails details = PropertyDetails(attributes, CALLBACKS); |
| 4900 maybe_ok = SetNormalizedProperty(name, structure, details); | 4919 maybe_ok = SetNormalizedProperty(name, structure, details); |
| 4901 if (maybe_ok->IsFailure()) return maybe_ok; | 4920 if (maybe_ok->IsFailure()) return maybe_ok; |
| 4902 | 4921 |
| 4903 return GetHeap()->undefined_value(); | 4922 return GetHeap()->undefined_value(); |
| 4904 } | 4923 } |
| 4905 | 4924 |
| 4906 | 4925 |
| 4907 void JSObject::DefineAccessor(Handle<JSObject> object, | 4926 void JSObject::DefineAccessor(Handle<JSObject> object, |
| 4908 Handle<String> name, | 4927 Handle<Name> name, |
| 4909 Handle<Object> getter, | 4928 Handle<Object> getter, |
| 4910 Handle<Object> setter, | 4929 Handle<Object> setter, |
| 4911 PropertyAttributes attributes) { | 4930 PropertyAttributes attributes) { |
| 4912 CALL_HEAP_FUNCTION_VOID( | 4931 CALL_HEAP_FUNCTION_VOID( |
| 4913 object->GetIsolate(), | 4932 object->GetIsolate(), |
| 4914 object->DefineAccessor(*name, *getter, *setter, attributes)); | 4933 object->DefineAccessor(*name, *getter, *setter, attributes)); |
| 4915 } | 4934 } |
| 4916 | 4935 |
| 4917 MaybeObject* JSObject::DefineAccessor(String* name_raw, | 4936 MaybeObject* JSObject::DefineAccessor(Name* name_raw, |
| 4918 Object* getter_raw, | 4937 Object* getter_raw, |
| 4919 Object* setter_raw, | 4938 Object* setter_raw, |
| 4920 PropertyAttributes attributes) { | 4939 PropertyAttributes attributes) { |
| 4921 Isolate* isolate = GetIsolate(); | 4940 Isolate* isolate = GetIsolate(); |
| 4922 // Check access rights if needed. | 4941 // Check access rights if needed. |
| 4923 if (IsAccessCheckNeeded() && | 4942 if (IsAccessCheckNeeded() && |
| 4924 !isolate->MayNamedAccess(this, name_raw, v8::ACCESS_SET)) { | 4943 !isolate->MayNamedAccess(this, name_raw, v8::ACCESS_SET)) { |
| 4925 isolate->ReportFailedAccessCheck(this, v8::ACCESS_SET); | 4944 isolate->ReportFailedAccessCheck(this, v8::ACCESS_SET); |
| 4926 return isolate->heap()->undefined_value(); | 4945 return isolate->heap()->undefined_value(); |
| 4927 } | 4946 } |
| 4928 | 4947 |
| 4929 if (IsJSGlobalProxy()) { | 4948 if (IsJSGlobalProxy()) { |
| 4930 Object* proto = GetPrototype(); | 4949 Object* proto = GetPrototype(); |
| 4931 if (proto->IsNull()) return this; | 4950 if (proto->IsNull()) return this; |
| 4932 ASSERT(proto->IsJSGlobalObject()); | 4951 ASSERT(proto->IsJSGlobalObject()); |
| 4933 return JSObject::cast(proto)->DefineAccessor( | 4952 return JSObject::cast(proto)->DefineAccessor( |
| 4934 name_raw, getter_raw, setter_raw, attributes); | 4953 name_raw, getter_raw, setter_raw, attributes); |
| 4935 } | 4954 } |
| 4936 | 4955 |
| 4937 // Make sure that the top context does not change when doing callbacks or | 4956 // Make sure that the top context does not change when doing callbacks or |
| 4938 // interceptor calls. | 4957 // interceptor calls. |
| 4939 AssertNoContextChange ncc; | 4958 AssertNoContextChange ncc; |
| 4940 | 4959 |
| 4941 // Try to flatten before operating on the string. | 4960 // Try to flatten before operating on the string. |
| 4942 name_raw->TryFlatten(); | 4961 if (name_raw->IsString()) String::cast(name_raw)->TryFlatten(); |
| 4943 | 4962 |
| 4944 if (!CanSetCallback(name_raw)) return isolate->heap()->undefined_value(); | 4963 if (!CanSetCallback(name_raw)) return isolate->heap()->undefined_value(); |
| 4945 | 4964 |
| 4946 // From this point on everything needs to be handlified. | 4965 // From this point on everything needs to be handlified. |
| 4947 HandleScope scope(isolate); | 4966 HandleScope scope(isolate); |
| 4948 Handle<JSObject> self(this); | 4967 Handle<JSObject> self(this); |
| 4949 Handle<String> name(name_raw); | 4968 Handle<Name> name(name_raw); |
| 4950 Handle<Object> getter(getter_raw); | 4969 Handle<Object> getter(getter_raw); |
| 4951 Handle<Object> setter(setter_raw); | 4970 Handle<Object> setter(setter_raw); |
| 4952 | 4971 |
| 4953 uint32_t index = 0; | 4972 uint32_t index = 0; |
| 4954 bool is_element = name->AsArrayIndex(&index); | 4973 bool is_element = name->AsArrayIndex(&index); |
| 4955 | 4974 |
| 4956 Handle<Object> old_value = isolate->factory()->the_hole_value(); | 4975 Handle<Object> old_value = isolate->factory()->the_hole_value(); |
| 4957 bool is_observed = FLAG_harmony_observation && self->map()->is_observed(); | 4976 bool is_observed = FLAG_harmony_observation && self->map()->is_observed(); |
| 4958 bool preexists = false; | 4977 bool preexists = false; |
| 4959 if (is_observed) { | 4978 if (is_observed) { |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5010 self->set_map(transitioned_map); | 5029 self->set_map(transitioned_map); |
| 5011 return self; | 5030 return self; |
| 5012 } | 5031 } |
| 5013 | 5032 |
| 5014 // If either not the same accessor, or not the same attributes, fall back to | 5033 // If either not the same accessor, or not the same attributes, fall back to |
| 5015 // the slow case. | 5034 // the slow case. |
| 5016 return self->GetHeap()->null_value(); | 5035 return self->GetHeap()->null_value(); |
| 5017 } | 5036 } |
| 5018 | 5037 |
| 5019 | 5038 |
| 5020 MaybeObject* JSObject::DefineFastAccessor(String* name, | 5039 MaybeObject* JSObject::DefineFastAccessor(Name* name, |
| 5021 AccessorComponent component, | 5040 AccessorComponent component, |
| 5022 Object* accessor, | 5041 Object* accessor, |
| 5023 PropertyAttributes attributes) { | 5042 PropertyAttributes attributes) { |
| 5024 ASSERT(accessor->IsSpecFunction() || accessor->IsUndefined()); | 5043 ASSERT(accessor->IsSpecFunction() || accessor->IsUndefined()); |
| 5025 LookupResult result(GetIsolate()); | 5044 LookupResult result(GetIsolate()); |
| 5026 LocalLookup(name, &result); | 5045 LocalLookup(name, &result); |
| 5027 | 5046 |
| 5028 if (result.IsFound() | 5047 if (result.IsFound() |
| 5029 && !result.IsPropertyCallbacks() | 5048 && !result.IsPropertyCallbacks() |
| 5030 && !result.IsTransition()) return GetHeap()->null_value(); | 5049 && !result.IsTransition()) return GetHeap()->null_value(); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5093 map()->CopyInsertDescriptor(&new_accessors_desc, INSERT_TRANSITION); | 5112 map()->CopyInsertDescriptor(&new_accessors_desc, INSERT_TRANSITION); |
| 5094 if (!maybe_new_map->To(&new_map)) return maybe_new_map; | 5113 if (!maybe_new_map->To(&new_map)) return maybe_new_map; |
| 5095 | 5114 |
| 5096 set_map(new_map); | 5115 set_map(new_map); |
| 5097 return this; | 5116 return this; |
| 5098 } | 5117 } |
| 5099 | 5118 |
| 5100 | 5119 |
| 5101 MaybeObject* JSObject::DefineAccessor(AccessorInfo* info) { | 5120 MaybeObject* JSObject::DefineAccessor(AccessorInfo* info) { |
| 5102 Isolate* isolate = GetIsolate(); | 5121 Isolate* isolate = GetIsolate(); |
| 5103 String* name = String::cast(info->name()); | 5122 Name* name = Name::cast(info->name()); |
| 5104 // Check access rights if needed. | 5123 // Check access rights if needed. |
| 5105 if (IsAccessCheckNeeded() && | 5124 if (IsAccessCheckNeeded() && |
| 5106 !isolate->MayNamedAccess(this, name, v8::ACCESS_SET)) { | 5125 !isolate->MayNamedAccess(this, name, v8::ACCESS_SET)) { |
| 5107 isolate->ReportFailedAccessCheck(this, v8::ACCESS_SET); | 5126 isolate->ReportFailedAccessCheck(this, v8::ACCESS_SET); |
| 5108 return isolate->heap()->undefined_value(); | 5127 return isolate->heap()->undefined_value(); |
| 5109 } | 5128 } |
| 5110 | 5129 |
| 5111 if (IsJSGlobalProxy()) { | 5130 if (IsJSGlobalProxy()) { |
| 5112 Object* proto = GetPrototype(); | 5131 Object* proto = GetPrototype(); |
| 5113 if (proto->IsNull()) return this; | 5132 if (proto->IsNull()) return this; |
| 5114 ASSERT(proto->IsJSGlobalObject()); | 5133 ASSERT(proto->IsJSGlobalObject()); |
| 5115 return JSObject::cast(proto)->DefineAccessor(info); | 5134 return JSObject::cast(proto)->DefineAccessor(info); |
| 5116 } | 5135 } |
| 5117 | 5136 |
| 5118 // Make sure that the top context does not change when doing callbacks or | 5137 // Make sure that the top context does not change when doing callbacks or |
| 5119 // interceptor calls. | 5138 // interceptor calls. |
| 5120 AssertNoContextChange ncc; | 5139 AssertNoContextChange ncc; |
| 5121 | 5140 |
| 5122 // Try to flatten before operating on the string. | 5141 // Try to flatten before operating on the string. |
| 5123 name->TryFlatten(); | 5142 if (name->IsString()) String::cast(name)->TryFlatten(); |
| 5124 | 5143 |
| 5125 if (!CanSetCallback(name)) return isolate->heap()->undefined_value(); | 5144 if (!CanSetCallback(name)) return isolate->heap()->undefined_value(); |
| 5126 | 5145 |
| 5127 uint32_t index = 0; | 5146 uint32_t index = 0; |
| 5128 bool is_element = name->AsArrayIndex(&index); | 5147 bool is_element = name->AsArrayIndex(&index); |
| 5129 | 5148 |
| 5130 if (is_element) { | 5149 if (is_element) { |
| 5131 if (IsJSArray()) return isolate->heap()->undefined_value(); | 5150 if (IsJSArray()) return isolate->heap()->undefined_value(); |
| 5132 | 5151 |
| 5133 // Accessors overwrite previous callbacks (cf. with getters/setters). | 5152 // Accessors overwrite previous callbacks (cf. with getters/setters). |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5173 | 5192 |
| 5174 MaybeObject* maybe_ok = | 5193 MaybeObject* maybe_ok = |
| 5175 SetPropertyCallback(name, info, info->property_attributes()); | 5194 SetPropertyCallback(name, info, info->property_attributes()); |
| 5176 if (maybe_ok->IsFailure()) return maybe_ok; | 5195 if (maybe_ok->IsFailure()) return maybe_ok; |
| 5177 } | 5196 } |
| 5178 | 5197 |
| 5179 return this; | 5198 return this; |
| 5180 } | 5199 } |
| 5181 | 5200 |
| 5182 | 5201 |
| 5183 Object* JSObject::LookupAccessor(String* name, AccessorComponent component) { | 5202 Object* JSObject::LookupAccessor(Name* name, AccessorComponent component) { |
| 5184 Heap* heap = GetHeap(); | 5203 Heap* heap = GetHeap(); |
| 5185 | 5204 |
| 5186 // Make sure that the top context does not change when doing callbacks or | 5205 // Make sure that the top context does not change when doing callbacks or |
| 5187 // interceptor calls. | 5206 // interceptor calls. |
| 5188 AssertNoContextChange ncc; | 5207 AssertNoContextChange ncc; |
| 5189 | 5208 |
| 5190 // Check access rights if needed. | 5209 // Check access rights if needed. |
| 5191 if (IsAccessCheckNeeded() && | 5210 if (IsAccessCheckNeeded() && |
| 5192 !heap->isolate()->MayNamedAccess(this, name, v8::ACCESS_HAS)) { | 5211 !heap->isolate()->MayNamedAccess(this, name, v8::ACCESS_HAS)) { |
| 5193 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); | 5212 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5324 Descriptor* descriptor) { | 5343 Descriptor* descriptor) { |
| 5325 // Sanity check. This path is only to be taken if the map owns its descriptor | 5344 // Sanity check. This path is only to be taken if the map owns its descriptor |
| 5326 // array, implying that its NumberOfOwnDescriptors equals the number of | 5345 // array, implying that its NumberOfOwnDescriptors equals the number of |
| 5327 // descriptors in the descriptor array. | 5346 // descriptors in the descriptor array. |
| 5328 ASSERT(NumberOfOwnDescriptors() == | 5347 ASSERT(NumberOfOwnDescriptors() == |
| 5329 instance_descriptors()->number_of_descriptors()); | 5348 instance_descriptors()->number_of_descriptors()); |
| 5330 Map* result; | 5349 Map* result; |
| 5331 MaybeObject* maybe_result = CopyDropDescriptors(); | 5350 MaybeObject* maybe_result = CopyDropDescriptors(); |
| 5332 if (!maybe_result->To(&result)) return maybe_result; | 5351 if (!maybe_result->To(&result)) return maybe_result; |
| 5333 | 5352 |
| 5334 String* name = descriptor->GetKey(); | 5353 Name* name = descriptor->GetKey(); |
| 5335 | 5354 |
| 5336 TransitionArray* transitions; | 5355 TransitionArray* transitions; |
| 5337 MaybeObject* maybe_transitions = | 5356 MaybeObject* maybe_transitions = |
| 5338 AddTransition(name, result, SIMPLE_TRANSITION); | 5357 AddTransition(name, result, SIMPLE_TRANSITION); |
| 5339 if (!maybe_transitions->To(&transitions)) return maybe_transitions; | 5358 if (!maybe_transitions->To(&transitions)) return maybe_transitions; |
| 5340 | 5359 |
| 5341 int old_size = descriptors->number_of_descriptors(); | 5360 int old_size = descriptors->number_of_descriptors(); |
| 5342 | 5361 |
| 5343 DescriptorArray* new_descriptors; | 5362 DescriptorArray* new_descriptors; |
| 5344 | 5363 |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5389 ASSERT(result->NumberOfOwnDescriptors() == NumberOfOwnDescriptors() + 1); | 5408 ASSERT(result->NumberOfOwnDescriptors() == NumberOfOwnDescriptors() + 1); |
| 5390 | 5409 |
| 5391 set_transitions(transitions); | 5410 set_transitions(transitions); |
| 5392 set_owns_descriptors(false); | 5411 set_owns_descriptors(false); |
| 5393 | 5412 |
| 5394 return result; | 5413 return result; |
| 5395 } | 5414 } |
| 5396 | 5415 |
| 5397 | 5416 |
| 5398 MaybeObject* Map::CopyReplaceDescriptors(DescriptorArray* descriptors, | 5417 MaybeObject* Map::CopyReplaceDescriptors(DescriptorArray* descriptors, |
| 5399 String* name, | 5418 Name* name, |
| 5400 TransitionFlag flag, | 5419 TransitionFlag flag, |
| 5401 int descriptor_index) { | 5420 int descriptor_index) { |
| 5402 ASSERT(descriptors->IsSortedNoDuplicates()); | 5421 ASSERT(descriptors->IsSortedNoDuplicates()); |
| 5403 | 5422 |
| 5404 Map* result; | 5423 Map* result; |
| 5405 MaybeObject* maybe_result = CopyDropDescriptors(); | 5424 MaybeObject* maybe_result = CopyDropDescriptors(); |
| 5406 if (!maybe_result->To(&result)) return maybe_result; | 5425 if (!maybe_result->To(&result)) return maybe_result; |
| 5407 | 5426 |
| 5408 result->InitializeDescriptors(descriptors); | 5427 result->InitializeDescriptors(descriptors); |
| 5409 | 5428 |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5505 if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors; | 5524 if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors; |
| 5506 | 5525 |
| 5507 return CopyReplaceDescriptors(new_descriptors, NULL, OMIT_TRANSITION, 0); | 5526 return CopyReplaceDescriptors(new_descriptors, NULL, OMIT_TRANSITION, 0); |
| 5508 } | 5527 } |
| 5509 | 5528 |
| 5510 | 5529 |
| 5511 MaybeObject* Map::CopyAddDescriptor(Descriptor* descriptor, | 5530 MaybeObject* Map::CopyAddDescriptor(Descriptor* descriptor, |
| 5512 TransitionFlag flag) { | 5531 TransitionFlag flag) { |
| 5513 DescriptorArray* descriptors = instance_descriptors(); | 5532 DescriptorArray* descriptors = instance_descriptors(); |
| 5514 | 5533 |
| 5515 // Ensure the key is an internalized string. | 5534 // Ensure the key is unique. |
| 5516 MaybeObject* maybe_failure = descriptor->KeyToInternalizedString(); | 5535 MaybeObject* maybe_failure = descriptor->KeyToUniqueName(); |
| 5517 if (maybe_failure->IsFailure()) return maybe_failure; | 5536 if (maybe_failure->IsFailure()) return maybe_failure; |
| 5518 | 5537 |
| 5519 int old_size = NumberOfOwnDescriptors(); | 5538 int old_size = NumberOfOwnDescriptors(); |
| 5520 int new_size = old_size + 1; | 5539 int new_size = old_size + 1; |
| 5521 descriptor->SetEnumerationIndex(new_size); | 5540 descriptor->SetEnumerationIndex(new_size); |
| 5522 | 5541 |
| 5523 if (flag == INSERT_TRANSITION && | 5542 if (flag == INSERT_TRANSITION && |
| 5524 owns_descriptors() && | 5543 owns_descriptors() && |
| 5525 CanHaveMoreTransitions()) { | 5544 CanHaveMoreTransitions()) { |
| 5526 return ShareDescriptor(descriptors, descriptor); | 5545 return ShareDescriptor(descriptors, descriptor); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 5538 } | 5557 } |
| 5539 | 5558 |
| 5540 if (old_size != descriptors->number_of_descriptors()) { | 5559 if (old_size != descriptors->number_of_descriptors()) { |
| 5541 new_descriptors->SetNumberOfDescriptors(new_size); | 5560 new_descriptors->SetNumberOfDescriptors(new_size); |
| 5542 new_descriptors->Set(old_size, descriptor, witness); | 5561 new_descriptors->Set(old_size, descriptor, witness); |
| 5543 new_descriptors->Sort(); | 5562 new_descriptors->Sort(); |
| 5544 } else { | 5563 } else { |
| 5545 new_descriptors->Append(descriptor, witness); | 5564 new_descriptors->Append(descriptor, witness); |
| 5546 } | 5565 } |
| 5547 | 5566 |
| 5548 String* key = descriptor->GetKey(); | 5567 Name* key = descriptor->GetKey(); |
| 5549 int insertion_index = new_descriptors->number_of_descriptors() - 1; | 5568 int insertion_index = new_descriptors->number_of_descriptors() - 1; |
| 5550 | 5569 |
| 5551 return CopyReplaceDescriptors(new_descriptors, key, flag, insertion_index); | 5570 return CopyReplaceDescriptors(new_descriptors, key, flag, insertion_index); |
| 5552 } | 5571 } |
| 5553 | 5572 |
| 5554 | 5573 |
| 5555 MaybeObject* Map::CopyInsertDescriptor(Descriptor* descriptor, | 5574 MaybeObject* Map::CopyInsertDescriptor(Descriptor* descriptor, |
| 5556 TransitionFlag flag) { | 5575 TransitionFlag flag) { |
| 5557 DescriptorArray* old_descriptors = instance_descriptors(); | 5576 DescriptorArray* old_descriptors = instance_descriptors(); |
| 5558 | 5577 |
| 5559 // Ensure the key is an internalized string. | 5578 // Ensure the key is unique. |
| 5560 MaybeObject* maybe_result = descriptor->KeyToInternalizedString(); | 5579 MaybeObject* maybe_result = descriptor->KeyToUniqueName(); |
| 5561 if (maybe_result->IsFailure()) return maybe_result; | 5580 if (maybe_result->IsFailure()) return maybe_result; |
| 5562 | 5581 |
| 5563 // We replace the key if it is already present. | 5582 // We replace the key if it is already present. |
| 5564 int index = old_descriptors->SearchWithCache(descriptor->GetKey(), this); | 5583 int index = old_descriptors->SearchWithCache(descriptor->GetKey(), this); |
| 5565 if (index != DescriptorArray::kNotFound) { | 5584 if (index != DescriptorArray::kNotFound) { |
| 5566 return CopyReplaceDescriptor(old_descriptors, descriptor, index, flag); | 5585 return CopyReplaceDescriptor(old_descriptors, descriptor, index, flag); |
| 5567 } | 5586 } |
| 5568 return CopyAddDescriptor(descriptor, flag); | 5587 return CopyAddDescriptor(descriptor, flag); |
| 5569 } | 5588 } |
| 5570 | 5589 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 5586 if (number_of_descriptors() != enumeration_index) descriptors->Sort(); | 5605 if (number_of_descriptors() != enumeration_index) descriptors->Sort(); |
| 5587 | 5606 |
| 5588 return descriptors; | 5607 return descriptors; |
| 5589 } | 5608 } |
| 5590 | 5609 |
| 5591 | 5610 |
| 5592 MaybeObject* Map::CopyReplaceDescriptor(DescriptorArray* descriptors, | 5611 MaybeObject* Map::CopyReplaceDescriptor(DescriptorArray* descriptors, |
| 5593 Descriptor* descriptor, | 5612 Descriptor* descriptor, |
| 5594 int insertion_index, | 5613 int insertion_index, |
| 5595 TransitionFlag flag) { | 5614 TransitionFlag flag) { |
| 5596 // Ensure the key is an internalized string. | 5615 // Ensure the key is unique. |
| 5597 MaybeObject* maybe_failure = descriptor->KeyToInternalizedString(); | 5616 MaybeObject* maybe_failure = descriptor->KeyToUniqueName(); |
| 5598 if (maybe_failure->IsFailure()) return maybe_failure; | 5617 if (maybe_failure->IsFailure()) return maybe_failure; |
| 5599 | 5618 |
| 5600 String* key = descriptor->GetKey(); | 5619 Name* key = descriptor->GetKey(); |
| 5601 ASSERT(key == descriptors->GetKey(insertion_index)); | 5620 ASSERT(key == descriptors->GetKey(insertion_index)); |
| 5602 | 5621 |
| 5603 int new_size = NumberOfOwnDescriptors(); | 5622 int new_size = NumberOfOwnDescriptors(); |
| 5604 ASSERT(0 <= insertion_index && insertion_index < new_size); | 5623 ASSERT(0 <= insertion_index && insertion_index < new_size); |
| 5605 | 5624 |
| 5606 PropertyDetails details = descriptors->GetDetails(insertion_index); | 5625 PropertyDetails details = descriptors->GetDetails(insertion_index); |
| 5607 ASSERT_LE(details.descriptor_index(), new_size); | 5626 ASSERT_LE(details.descriptor_index(), new_size); |
| 5608 descriptor->SetEnumerationIndex(details.descriptor_index()); | 5627 descriptor->SetEnumerationIndex(details.descriptor_index()); |
| 5609 | 5628 |
| 5610 DescriptorArray* new_descriptors; | 5629 DescriptorArray* new_descriptors; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 5621 } | 5640 } |
| 5622 | 5641 |
| 5623 // Re-sort if descriptors were removed. | 5642 // Re-sort if descriptors were removed. |
| 5624 if (new_size != descriptors->length()) new_descriptors->Sort(); | 5643 if (new_size != descriptors->length()) new_descriptors->Sort(); |
| 5625 | 5644 |
| 5626 return CopyReplaceDescriptors(new_descriptors, key, flag, insertion_index); | 5645 return CopyReplaceDescriptors(new_descriptors, key, flag, insertion_index); |
| 5627 } | 5646 } |
| 5628 | 5647 |
| 5629 | 5648 |
| 5630 void Map::UpdateCodeCache(Handle<Map> map, | 5649 void Map::UpdateCodeCache(Handle<Map> map, |
| 5631 Handle<String> name, | 5650 Handle<Name> name, |
| 5632 Handle<Code> code) { | 5651 Handle<Code> code) { |
| 5633 Isolate* isolate = map->GetIsolate(); | 5652 Isolate* isolate = map->GetIsolate(); |
| 5634 CALL_HEAP_FUNCTION_VOID(isolate, | 5653 CALL_HEAP_FUNCTION_VOID(isolate, |
| 5635 map->UpdateCodeCache(*name, *code)); | 5654 map->UpdateCodeCache(*name, *code)); |
| 5636 } | 5655 } |
| 5637 | 5656 |
| 5638 | 5657 |
| 5639 MaybeObject* Map::UpdateCodeCache(String* name, Code* code) { | 5658 MaybeObject* Map::UpdateCodeCache(Name* name, Code* code) { |
| 5640 ASSERT(!is_shared() || code->allowed_in_shared_map_code_cache()); | 5659 ASSERT(!is_shared() || code->allowed_in_shared_map_code_cache()); |
| 5641 | 5660 |
| 5642 // Allocate the code cache if not present. | 5661 // Allocate the code cache if not present. |
| 5643 if (code_cache()->IsFixedArray()) { | 5662 if (code_cache()->IsFixedArray()) { |
| 5644 Object* result; | 5663 Object* result; |
| 5645 { MaybeObject* maybe_result = GetHeap()->AllocateCodeCache(); | 5664 { MaybeObject* maybe_result = GetHeap()->AllocateCodeCache(); |
| 5646 if (!maybe_result->ToObject(&result)) return maybe_result; | 5665 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 5647 } | 5666 } |
| 5648 set_code_cache(result); | 5667 set_code_cache(result); |
| 5649 } | 5668 } |
| 5650 | 5669 |
| 5651 // Update the code cache. | 5670 // Update the code cache. |
| 5652 return CodeCache::cast(code_cache())->Update(name, code); | 5671 return CodeCache::cast(code_cache())->Update(name, code); |
| 5653 } | 5672 } |
| 5654 | 5673 |
| 5655 | 5674 |
| 5656 Object* Map::FindInCodeCache(String* name, Code::Flags flags) { | 5675 Object* Map::FindInCodeCache(Name* name, Code::Flags flags) { |
| 5657 // Do a lookup if a code cache exists. | 5676 // Do a lookup if a code cache exists. |
| 5658 if (!code_cache()->IsFixedArray()) { | 5677 if (!code_cache()->IsFixedArray()) { |
| 5659 return CodeCache::cast(code_cache())->Lookup(name, flags); | 5678 return CodeCache::cast(code_cache())->Lookup(name, flags); |
| 5660 } else { | 5679 } else { |
| 5661 return GetHeap()->undefined_value(); | 5680 return GetHeap()->undefined_value(); |
| 5662 } | 5681 } |
| 5663 } | 5682 } |
| 5664 | 5683 |
| 5665 | 5684 |
| 5666 int Map::IndexInCodeCache(Object* name, Code* code) { | 5685 int Map::IndexInCodeCache(Object* name, Code* code) { |
| 5667 // Get the internal index if a code cache exists. | 5686 // Get the internal index if a code cache exists. |
| 5668 if (!code_cache()->IsFixedArray()) { | 5687 if (!code_cache()->IsFixedArray()) { |
| 5669 return CodeCache::cast(code_cache())->GetIndex(name, code); | 5688 return CodeCache::cast(code_cache())->GetIndex(name, code); |
| 5670 } | 5689 } |
| 5671 return -1; | 5690 return -1; |
| 5672 } | 5691 } |
| 5673 | 5692 |
| 5674 | 5693 |
| 5675 void Map::RemoveFromCodeCache(String* name, Code* code, int index) { | 5694 void Map::RemoveFromCodeCache(Name* name, Code* code, int index) { |
| 5676 // No GC is supposed to happen between a call to IndexInCodeCache and | 5695 // No GC is supposed to happen between a call to IndexInCodeCache and |
| 5677 // RemoveFromCodeCache so the code cache must be there. | 5696 // RemoveFromCodeCache so the code cache must be there. |
| 5678 ASSERT(!code_cache()->IsFixedArray()); | 5697 ASSERT(!code_cache()->IsFixedArray()); |
| 5679 CodeCache::cast(code_cache())->RemoveByIndex(name, code, index); | 5698 CodeCache::cast(code_cache())->RemoveByIndex(name, code, index); |
| 5680 } | 5699 } |
| 5681 | 5700 |
| 5682 | 5701 |
| 5683 // An iterator over all map transitions in an descriptor array, reusing the map | 5702 // An iterator over all map transitions in an descriptor array, reusing the map |
| 5684 // field of the contens array while it is running. | 5703 // field of the contens array while it is running. |
| 5685 class IntrusiveMapTransitionIterator { | 5704 class IntrusiveMapTransitionIterator { |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5868 } else { | 5887 } else { |
| 5869 TraversableMap* parent = current->GetAndResetParent(); | 5888 TraversableMap* parent = current->GetAndResetParent(); |
| 5870 callback(current, data); | 5889 callback(current, data); |
| 5871 if (current == this) break; | 5890 if (current == this) break; |
| 5872 current = parent; | 5891 current = parent; |
| 5873 } | 5892 } |
| 5874 } | 5893 } |
| 5875 } | 5894 } |
| 5876 | 5895 |
| 5877 | 5896 |
| 5878 MaybeObject* CodeCache::Update(String* name, Code* code) { | 5897 MaybeObject* CodeCache::Update(Name* name, Code* code) { |
| 5879 // The number of monomorphic stubs for normal load/store/call IC's can grow to | 5898 // The number of monomorphic stubs for normal load/store/call IC's can grow to |
| 5880 // a large number and therefore they need to go into a hash table. They are | 5899 // a large number and therefore they need to go into a hash table. They are |
| 5881 // used to load global properties from cells. | 5900 // used to load global properties from cells. |
| 5882 if (code->type() == Code::NORMAL) { | 5901 if (code->type() == Code::NORMAL) { |
| 5883 // Make sure that a hash table is allocated for the normal load code cache. | 5902 // Make sure that a hash table is allocated for the normal load code cache. |
| 5884 if (normal_type_cache()->IsUndefined()) { | 5903 if (normal_type_cache()->IsUndefined()) { |
| 5885 Object* result; | 5904 Object* result; |
| 5886 { MaybeObject* maybe_result = | 5905 { MaybeObject* maybe_result = |
| 5887 CodeCacheHashTable::Allocate(CodeCacheHashTable::kInitialSize); | 5906 CodeCacheHashTable::Allocate(CodeCacheHashTable::kInitialSize); |
| 5888 if (!maybe_result->ToObject(&result)) return maybe_result; | 5907 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 5889 } | 5908 } |
| 5890 set_normal_type_cache(result); | 5909 set_normal_type_cache(result); |
| 5891 } | 5910 } |
| 5892 return UpdateNormalTypeCache(name, code); | 5911 return UpdateNormalTypeCache(name, code); |
| 5893 } else { | 5912 } else { |
| 5894 ASSERT(default_cache()->IsFixedArray()); | 5913 ASSERT(default_cache()->IsFixedArray()); |
| 5895 return UpdateDefaultCache(name, code); | 5914 return UpdateDefaultCache(name, code); |
| 5896 } | 5915 } |
| 5897 } | 5916 } |
| 5898 | 5917 |
| 5899 | 5918 |
| 5900 MaybeObject* CodeCache::UpdateDefaultCache(String* name, Code* code) { | 5919 MaybeObject* CodeCache::UpdateDefaultCache(Name* name, Code* code) { |
| 5901 // When updating the default code cache we disregard the type encoded in the | 5920 // When updating the default code cache we disregard the type encoded in the |
| 5902 // flags. This allows call constant stubs to overwrite call field | 5921 // flags. This allows call constant stubs to overwrite call field |
| 5903 // stubs, etc. | 5922 // stubs, etc. |
| 5904 Code::Flags flags = Code::RemoveTypeFromFlags(code->flags()); | 5923 Code::Flags flags = Code::RemoveTypeFromFlags(code->flags()); |
| 5905 | 5924 |
| 5906 // First check whether we can update existing code cache without | 5925 // First check whether we can update existing code cache without |
| 5907 // extending it. | 5926 // extending it. |
| 5908 FixedArray* cache = default_cache(); | 5927 FixedArray* cache = default_cache(); |
| 5909 int length = cache->length(); | 5928 int length = cache->length(); |
| 5910 int deleted_index = -1; | 5929 int deleted_index = -1; |
| 5911 for (int i = 0; i < length; i += kCodeCacheEntrySize) { | 5930 for (int i = 0; i < length; i += kCodeCacheEntrySize) { |
| 5912 Object* key = cache->get(i); | 5931 Object* key = cache->get(i); |
| 5913 if (key->IsNull()) { | 5932 if (key->IsNull()) { |
| 5914 if (deleted_index < 0) deleted_index = i; | 5933 if (deleted_index < 0) deleted_index = i; |
| 5915 continue; | 5934 continue; |
| 5916 } | 5935 } |
| 5917 if (key->IsUndefined()) { | 5936 if (key->IsUndefined()) { |
| 5918 if (deleted_index >= 0) i = deleted_index; | 5937 if (deleted_index >= 0) i = deleted_index; |
| 5919 cache->set(i + kCodeCacheEntryNameOffset, name); | 5938 cache->set(i + kCodeCacheEntryNameOffset, name); |
| 5920 cache->set(i + kCodeCacheEntryCodeOffset, code); | 5939 cache->set(i + kCodeCacheEntryCodeOffset, code); |
| 5921 return this; | 5940 return this; |
| 5922 } | 5941 } |
| 5923 if (name->Equals(String::cast(key))) { | 5942 if (name->Equals(Name::cast(key))) { |
| 5924 Code::Flags found = | 5943 Code::Flags found = |
| 5925 Code::cast(cache->get(i + kCodeCacheEntryCodeOffset))->flags(); | 5944 Code::cast(cache->get(i + kCodeCacheEntryCodeOffset))->flags(); |
| 5926 if (Code::RemoveTypeFromFlags(found) == flags) { | 5945 if (Code::RemoveTypeFromFlags(found) == flags) { |
| 5927 cache->set(i + kCodeCacheEntryCodeOffset, code); | 5946 cache->set(i + kCodeCacheEntryCodeOffset, code); |
| 5928 return this; | 5947 return this; |
| 5929 } | 5948 } |
| 5930 } | 5949 } |
| 5931 } | 5950 } |
| 5932 | 5951 |
| 5933 // Reached the end of the code cache. If there were deleted | 5952 // Reached the end of the code cache. If there were deleted |
| (...skipping 16 matching lines...) Expand all Loading... |
| 5950 | 5969 |
| 5951 // Add the (name, code) pair to the new cache. | 5970 // Add the (name, code) pair to the new cache. |
| 5952 cache = FixedArray::cast(result); | 5971 cache = FixedArray::cast(result); |
| 5953 cache->set(length + kCodeCacheEntryNameOffset, name); | 5972 cache->set(length + kCodeCacheEntryNameOffset, name); |
| 5954 cache->set(length + kCodeCacheEntryCodeOffset, code); | 5973 cache->set(length + kCodeCacheEntryCodeOffset, code); |
| 5955 set_default_cache(cache); | 5974 set_default_cache(cache); |
| 5956 return this; | 5975 return this; |
| 5957 } | 5976 } |
| 5958 | 5977 |
| 5959 | 5978 |
| 5960 MaybeObject* CodeCache::UpdateNormalTypeCache(String* name, Code* code) { | 5979 MaybeObject* CodeCache::UpdateNormalTypeCache(Name* name, Code* code) { |
| 5961 // Adding a new entry can cause a new cache to be allocated. | 5980 // Adding a new entry can cause a new cache to be allocated. |
| 5962 CodeCacheHashTable* cache = CodeCacheHashTable::cast(normal_type_cache()); | 5981 CodeCacheHashTable* cache = CodeCacheHashTable::cast(normal_type_cache()); |
| 5963 Object* new_cache; | 5982 Object* new_cache; |
| 5964 { MaybeObject* maybe_new_cache = cache->Put(name, code); | 5983 { MaybeObject* maybe_new_cache = cache->Put(name, code); |
| 5965 if (!maybe_new_cache->ToObject(&new_cache)) return maybe_new_cache; | 5984 if (!maybe_new_cache->ToObject(&new_cache)) return maybe_new_cache; |
| 5966 } | 5985 } |
| 5967 set_normal_type_cache(new_cache); | 5986 set_normal_type_cache(new_cache); |
| 5968 return this; | 5987 return this; |
| 5969 } | 5988 } |
| 5970 | 5989 |
| 5971 | 5990 |
| 5972 Object* CodeCache::Lookup(String* name, Code::Flags flags) { | 5991 Object* CodeCache::Lookup(Name* name, Code::Flags flags) { |
| 5973 if (Code::ExtractTypeFromFlags(flags) == Code::NORMAL) { | 5992 if (Code::ExtractTypeFromFlags(flags) == Code::NORMAL) { |
| 5974 return LookupNormalTypeCache(name, flags); | 5993 return LookupNormalTypeCache(name, flags); |
| 5975 } else { | 5994 } else { |
| 5976 return LookupDefaultCache(name, flags); | 5995 return LookupDefaultCache(name, flags); |
| 5977 } | 5996 } |
| 5978 } | 5997 } |
| 5979 | 5998 |
| 5980 | 5999 |
| 5981 Object* CodeCache::LookupDefaultCache(String* name, Code::Flags flags) { | 6000 Object* CodeCache::LookupDefaultCache(Name* name, Code::Flags flags) { |
| 5982 FixedArray* cache = default_cache(); | 6001 FixedArray* cache = default_cache(); |
| 5983 int length = cache->length(); | 6002 int length = cache->length(); |
| 5984 for (int i = 0; i < length; i += kCodeCacheEntrySize) { | 6003 for (int i = 0; i < length; i += kCodeCacheEntrySize) { |
| 5985 Object* key = cache->get(i + kCodeCacheEntryNameOffset); | 6004 Object* key = cache->get(i + kCodeCacheEntryNameOffset); |
| 5986 // Skip deleted elements. | 6005 // Skip deleted elements. |
| 5987 if (key->IsNull()) continue; | 6006 if (key->IsNull()) continue; |
| 5988 if (key->IsUndefined()) return key; | 6007 if (key->IsUndefined()) return key; |
| 5989 if (name->Equals(String::cast(key))) { | 6008 if (name->Equals(Name::cast(key))) { |
| 5990 Code* code = Code::cast(cache->get(i + kCodeCacheEntryCodeOffset)); | 6009 Code* code = Code::cast(cache->get(i + kCodeCacheEntryCodeOffset)); |
| 5991 if (code->flags() == flags) { | 6010 if (code->flags() == flags) { |
| 5992 return code; | 6011 return code; |
| 5993 } | 6012 } |
| 5994 } | 6013 } |
| 5995 } | 6014 } |
| 5996 return GetHeap()->undefined_value(); | 6015 return GetHeap()->undefined_value(); |
| 5997 } | 6016 } |
| 5998 | 6017 |
| 5999 | 6018 |
| 6000 Object* CodeCache::LookupNormalTypeCache(String* name, Code::Flags flags) { | 6019 Object* CodeCache::LookupNormalTypeCache(Name* name, Code::Flags flags) { |
| 6001 if (!normal_type_cache()->IsUndefined()) { | 6020 if (!normal_type_cache()->IsUndefined()) { |
| 6002 CodeCacheHashTable* cache = CodeCacheHashTable::cast(normal_type_cache()); | 6021 CodeCacheHashTable* cache = CodeCacheHashTable::cast(normal_type_cache()); |
| 6003 return cache->Lookup(name, flags); | 6022 return cache->Lookup(name, flags); |
| 6004 } else { | 6023 } else { |
| 6005 return GetHeap()->undefined_value(); | 6024 return GetHeap()->undefined_value(); |
| 6006 } | 6025 } |
| 6007 } | 6026 } |
| 6008 | 6027 |
| 6009 | 6028 |
| 6010 int CodeCache::GetIndex(Object* name, Code* code) { | 6029 int CodeCache::GetIndex(Object* name, Code* code) { |
| 6011 if (code->type() == Code::NORMAL) { | 6030 if (code->type() == Code::NORMAL) { |
| 6012 if (normal_type_cache()->IsUndefined()) return -1; | 6031 if (normal_type_cache()->IsUndefined()) return -1; |
| 6013 CodeCacheHashTable* cache = CodeCacheHashTable::cast(normal_type_cache()); | 6032 CodeCacheHashTable* cache = CodeCacheHashTable::cast(normal_type_cache()); |
| 6014 return cache->GetIndex(String::cast(name), code->flags()); | 6033 return cache->GetIndex(Name::cast(name), code->flags()); |
| 6015 } | 6034 } |
| 6016 | 6035 |
| 6017 FixedArray* array = default_cache(); | 6036 FixedArray* array = default_cache(); |
| 6018 int len = array->length(); | 6037 int len = array->length(); |
| 6019 for (int i = 0; i < len; i += kCodeCacheEntrySize) { | 6038 for (int i = 0; i < len; i += kCodeCacheEntrySize) { |
| 6020 if (array->get(i + kCodeCacheEntryCodeOffset) == code) return i + 1; | 6039 if (array->get(i + kCodeCacheEntryCodeOffset) == code) return i + 1; |
| 6021 } | 6040 } |
| 6022 return -1; | 6041 return -1; |
| 6023 } | 6042 } |
| 6024 | 6043 |
| 6025 | 6044 |
| 6026 void CodeCache::RemoveByIndex(Object* name, Code* code, int index) { | 6045 void CodeCache::RemoveByIndex(Object* name, Code* code, int index) { |
| 6027 if (code->type() == Code::NORMAL) { | 6046 if (code->type() == Code::NORMAL) { |
| 6028 ASSERT(!normal_type_cache()->IsUndefined()); | 6047 ASSERT(!normal_type_cache()->IsUndefined()); |
| 6029 CodeCacheHashTable* cache = CodeCacheHashTable::cast(normal_type_cache()); | 6048 CodeCacheHashTable* cache = CodeCacheHashTable::cast(normal_type_cache()); |
| 6030 ASSERT(cache->GetIndex(String::cast(name), code->flags()) == index); | 6049 ASSERT(cache->GetIndex(Name::cast(name), code->flags()) == index); |
| 6031 cache->RemoveByIndex(index); | 6050 cache->RemoveByIndex(index); |
| 6032 } else { | 6051 } else { |
| 6033 FixedArray* array = default_cache(); | 6052 FixedArray* array = default_cache(); |
| 6034 ASSERT(array->length() >= index && array->get(index)->IsCode()); | 6053 ASSERT(array->length() >= index && array->get(index)->IsCode()); |
| 6035 // Use null instead of undefined for deleted elements to distinguish | 6054 // Use null instead of undefined for deleted elements to distinguish |
| 6036 // deleted elements from unused elements. This distinction is used | 6055 // deleted elements from unused elements. This distinction is used |
| 6037 // when looking up in the cache and when updating the cache. | 6056 // when looking up in the cache and when updating the cache. |
| 6038 ASSERT_EQ(1, kCodeCacheEntryCodeOffset - kCodeCacheEntryNameOffset); | 6057 ASSERT_EQ(1, kCodeCacheEntryCodeOffset - kCodeCacheEntryNameOffset); |
| 6039 array->set_null(index - 1); // Name. | 6058 array->set_null(index - 1); // Name. |
| 6040 array->set_null(index); // Code. | 6059 array->set_null(index); // Code. |
| 6041 } | 6060 } |
| 6042 } | 6061 } |
| 6043 | 6062 |
| 6044 | 6063 |
| 6045 // The key in the code cache hash table consists of the property name and the | 6064 // The key in the code cache hash table consists of the property name and the |
| 6046 // code object. The actual match is on the name and the code flags. If a key | 6065 // code object. The actual match is on the name and the code flags. If a key |
| 6047 // is created using the flags and not a code object it can only be used for | 6066 // is created using the flags and not a code object it can only be used for |
| 6048 // lookup not to create a new entry. | 6067 // lookup not to create a new entry. |
| 6049 class CodeCacheHashTableKey : public HashTableKey { | 6068 class CodeCacheHashTableKey : public HashTableKey { |
| 6050 public: | 6069 public: |
| 6051 CodeCacheHashTableKey(String* name, Code::Flags flags) | 6070 CodeCacheHashTableKey(Name* name, Code::Flags flags) |
| 6052 : name_(name), flags_(flags), code_(NULL) { } | 6071 : name_(name), flags_(flags), code_(NULL) { } |
| 6053 | 6072 |
| 6054 CodeCacheHashTableKey(String* name, Code* code) | 6073 CodeCacheHashTableKey(Name* name, Code* code) |
| 6055 : name_(name), | 6074 : name_(name), |
| 6056 flags_(code->flags()), | 6075 flags_(code->flags()), |
| 6057 code_(code) { } | 6076 code_(code) { } |
| 6058 | 6077 |
| 6059 | 6078 |
| 6060 bool IsMatch(Object* other) { | 6079 bool IsMatch(Object* other) { |
| 6061 if (!other->IsFixedArray()) return false; | 6080 if (!other->IsFixedArray()) return false; |
| 6062 FixedArray* pair = FixedArray::cast(other); | 6081 FixedArray* pair = FixedArray::cast(other); |
| 6063 String* name = String::cast(pair->get(0)); | 6082 Name* name = Name::cast(pair->get(0)); |
| 6064 Code::Flags flags = Code::cast(pair->get(1))->flags(); | 6083 Code::Flags flags = Code::cast(pair->get(1))->flags(); |
| 6065 if (flags != flags_) { | 6084 if (flags != flags_) { |
| 6066 return false; | 6085 return false; |
| 6067 } | 6086 } |
| 6068 return name_->Equals(name); | 6087 return name_->Equals(name); |
| 6069 } | 6088 } |
| 6070 | 6089 |
| 6071 static uint32_t NameFlagsHashHelper(String* name, Code::Flags flags) { | 6090 static uint32_t NameFlagsHashHelper(Name* name, Code::Flags flags) { |
| 6072 return name->Hash() ^ flags; | 6091 return name->Hash() ^ flags; |
| 6073 } | 6092 } |
| 6074 | 6093 |
| 6075 uint32_t Hash() { return NameFlagsHashHelper(name_, flags_); } | 6094 uint32_t Hash() { return NameFlagsHashHelper(name_, flags_); } |
| 6076 | 6095 |
| 6077 uint32_t HashForObject(Object* obj) { | 6096 uint32_t HashForObject(Object* obj) { |
| 6078 FixedArray* pair = FixedArray::cast(obj); | 6097 FixedArray* pair = FixedArray::cast(obj); |
| 6079 String* name = String::cast(pair->get(0)); | 6098 Name* name = Name::cast(pair->get(0)); |
| 6080 Code* code = Code::cast(pair->get(1)); | 6099 Code* code = Code::cast(pair->get(1)); |
| 6081 return NameFlagsHashHelper(name, code->flags()); | 6100 return NameFlagsHashHelper(name, code->flags()); |
| 6082 } | 6101 } |
| 6083 | 6102 |
| 6084 MUST_USE_RESULT MaybeObject* AsObject() { | 6103 MUST_USE_RESULT MaybeObject* AsObject() { |
| 6085 ASSERT(code_ != NULL); | 6104 ASSERT(code_ != NULL); |
| 6086 Object* obj; | 6105 Object* obj; |
| 6087 { MaybeObject* maybe_obj = code_->GetHeap()->AllocateFixedArray(2); | 6106 { MaybeObject* maybe_obj = code_->GetHeap()->AllocateFixedArray(2); |
| 6088 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 6107 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 6089 } | 6108 } |
| 6090 FixedArray* pair = FixedArray::cast(obj); | 6109 FixedArray* pair = FixedArray::cast(obj); |
| 6091 pair->set(0, name_); | 6110 pair->set(0, name_); |
| 6092 pair->set(1, code_); | 6111 pair->set(1, code_); |
| 6093 return pair; | 6112 return pair; |
| 6094 } | 6113 } |
| 6095 | 6114 |
| 6096 private: | 6115 private: |
| 6097 String* name_; | 6116 Name* name_; |
| 6098 Code::Flags flags_; | 6117 Code::Flags flags_; |
| 6099 // TODO(jkummerow): We should be able to get by without this. | 6118 // TODO(jkummerow): We should be able to get by without this. |
| 6100 Code* code_; | 6119 Code* code_; |
| 6101 }; | 6120 }; |
| 6102 | 6121 |
| 6103 | 6122 |
| 6104 Object* CodeCacheHashTable::Lookup(String* name, Code::Flags flags) { | 6123 Object* CodeCacheHashTable::Lookup(Name* name, Code::Flags flags) { |
| 6105 CodeCacheHashTableKey key(name, flags); | 6124 CodeCacheHashTableKey key(name, flags); |
| 6106 int entry = FindEntry(&key); | 6125 int entry = FindEntry(&key); |
| 6107 if (entry == kNotFound) return GetHeap()->undefined_value(); | 6126 if (entry == kNotFound) return GetHeap()->undefined_value(); |
| 6108 return get(EntryToIndex(entry) + 1); | 6127 return get(EntryToIndex(entry) + 1); |
| 6109 } | 6128 } |
| 6110 | 6129 |
| 6111 | 6130 |
| 6112 MaybeObject* CodeCacheHashTable::Put(String* name, Code* code) { | 6131 MaybeObject* CodeCacheHashTable::Put(Name* name, Code* code) { |
| 6113 CodeCacheHashTableKey key(name, code); | 6132 CodeCacheHashTableKey key(name, code); |
| 6114 Object* obj; | 6133 Object* obj; |
| 6115 { MaybeObject* maybe_obj = EnsureCapacity(1, &key); | 6134 { MaybeObject* maybe_obj = EnsureCapacity(1, &key); |
| 6116 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 6135 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 6117 } | 6136 } |
| 6118 | 6137 |
| 6119 // Don't use |this|, as the table might have grown. | 6138 // Don't use |this|, as the table might have grown. |
| 6120 CodeCacheHashTable* cache = reinterpret_cast<CodeCacheHashTable*>(obj); | 6139 CodeCacheHashTable* cache = reinterpret_cast<CodeCacheHashTable*>(obj); |
| 6121 | 6140 |
| 6122 int entry = cache->FindInsertionEntry(key.Hash()); | 6141 int entry = cache->FindInsertionEntry(key.Hash()); |
| 6123 Object* k; | 6142 Object* k; |
| 6124 { MaybeObject* maybe_k = key.AsObject(); | 6143 { MaybeObject* maybe_k = key.AsObject(); |
| 6125 if (!maybe_k->ToObject(&k)) return maybe_k; | 6144 if (!maybe_k->ToObject(&k)) return maybe_k; |
| 6126 } | 6145 } |
| 6127 | 6146 |
| 6128 cache->set(EntryToIndex(entry), k); | 6147 cache->set(EntryToIndex(entry), k); |
| 6129 cache->set(EntryToIndex(entry) + 1, code); | 6148 cache->set(EntryToIndex(entry) + 1, code); |
| 6130 cache->ElementAdded(); | 6149 cache->ElementAdded(); |
| 6131 return cache; | 6150 return cache; |
| 6132 } | 6151 } |
| 6133 | 6152 |
| 6134 | 6153 |
| 6135 int CodeCacheHashTable::GetIndex(String* name, Code::Flags flags) { | 6154 int CodeCacheHashTable::GetIndex(Name* name, Code::Flags flags) { |
| 6136 CodeCacheHashTableKey key(name, flags); | 6155 CodeCacheHashTableKey key(name, flags); |
| 6137 int entry = FindEntry(&key); | 6156 int entry = FindEntry(&key); |
| 6138 return (entry == kNotFound) ? -1 : entry; | 6157 return (entry == kNotFound) ? -1 : entry; |
| 6139 } | 6158 } |
| 6140 | 6159 |
| 6141 | 6160 |
| 6142 void CodeCacheHashTable::RemoveByIndex(int index) { | 6161 void CodeCacheHashTable::RemoveByIndex(int index) { |
| 6143 ASSERT(index >= 0); | 6162 ASSERT(index >= 0); |
| 6144 Heap* heap = GetHeap(); | 6163 Heap* heap = GetHeap(); |
| 6145 set(EntryToIndex(index), heap->the_hole_value()); | 6164 set(EntryToIndex(index), heap->the_hole_value()); |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6322 MaybeObject* FixedArray::AddKeysFromJSArray(JSArray* array) { | 6341 MaybeObject* FixedArray::AddKeysFromJSArray(JSArray* array) { |
| 6323 ElementsAccessor* accessor = array->GetElementsAccessor(); | 6342 ElementsAccessor* accessor = array->GetElementsAccessor(); |
| 6324 MaybeObject* maybe_result = | 6343 MaybeObject* maybe_result = |
| 6325 accessor->AddElementsToFixedArray(array, array, this); | 6344 accessor->AddElementsToFixedArray(array, array, this); |
| 6326 FixedArray* result; | 6345 FixedArray* result; |
| 6327 if (!maybe_result->To<FixedArray>(&result)) return maybe_result; | 6346 if (!maybe_result->To<FixedArray>(&result)) return maybe_result; |
| 6328 #ifdef DEBUG | 6347 #ifdef DEBUG |
| 6329 if (FLAG_enable_slow_asserts) { | 6348 if (FLAG_enable_slow_asserts) { |
| 6330 for (int i = 0; i < result->length(); i++) { | 6349 for (int i = 0; i < result->length(); i++) { |
| 6331 Object* current = result->get(i); | 6350 Object* current = result->get(i); |
| 6332 ASSERT(current->IsNumber() || current->IsString()); | 6351 ASSERT(current->IsNumber() || current->IsName()); |
| 6333 } | 6352 } |
| 6334 } | 6353 } |
| 6335 #endif | 6354 #endif |
| 6336 return result; | 6355 return result; |
| 6337 } | 6356 } |
| 6338 | 6357 |
| 6339 | 6358 |
| 6340 MaybeObject* FixedArray::UnionOfKeys(FixedArray* other) { | 6359 MaybeObject* FixedArray::UnionOfKeys(FixedArray* other) { |
| 6341 ElementsAccessor* accessor = ElementsAccessor::ForArray(other); | 6360 ElementsAccessor* accessor = ElementsAccessor::ForArray(other); |
| 6342 MaybeObject* maybe_result = | 6361 MaybeObject* maybe_result = |
| 6343 accessor->AddElementsToFixedArray(NULL, NULL, this, other); | 6362 accessor->AddElementsToFixedArray(NULL, NULL, this, other); |
| 6344 FixedArray* result; | 6363 FixedArray* result; |
| 6345 if (!maybe_result->To(&result)) return maybe_result; | 6364 if (!maybe_result->To(&result)) return maybe_result; |
| 6346 #ifdef DEBUG | 6365 #ifdef DEBUG |
| 6347 if (FLAG_enable_slow_asserts) { | 6366 if (FLAG_enable_slow_asserts) { |
| 6348 for (int i = 0; i < result->length(); i++) { | 6367 for (int i = 0; i < result->length(); i++) { |
| 6349 Object* current = result->get(i); | 6368 Object* current = result->get(i); |
| 6350 ASSERT(current->IsNumber() || current->IsString()); | 6369 ASSERT(current->IsNumber() || current->IsName()); |
| 6351 } | 6370 } |
| 6352 } | 6371 } |
| 6353 #endif | 6372 #endif |
| 6354 return result; | 6373 return result; |
| 6355 } | 6374 } |
| 6356 | 6375 |
| 6357 | 6376 |
| 6358 MaybeObject* FixedArray::CopySize(int new_length) { | 6377 MaybeObject* FixedArray::CopySize(int new_length) { |
| 6359 Heap* heap = GetHeap(); | 6378 Heap* heap = GetHeap(); |
| 6360 if (new_length == 0) return heap->empty_fixed_array(); | 6379 if (new_length == 0) return heap->empty_fixed_array(); |
| (...skipping 1350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7711 | 7730 |
| 7712 // Compact all live descriptors to the left. | 7731 // Compact all live descriptors to the left. |
| 7713 for (int i = 0; i < t->number_of_transitions(); ++i) { | 7732 for (int i = 0; i < t->number_of_transitions(); ++i) { |
| 7714 Map* target = t->GetTarget(i); | 7733 Map* target = t->GetTarget(i); |
| 7715 if (ClearBackPointer(heap, target)) { | 7734 if (ClearBackPointer(heap, target)) { |
| 7716 if (target->instance_descriptors() == descriptors) { | 7735 if (target->instance_descriptors() == descriptors) { |
| 7717 descriptors_owner_died = true; | 7736 descriptors_owner_died = true; |
| 7718 } | 7737 } |
| 7719 } else { | 7738 } else { |
| 7720 if (i != transition_index) { | 7739 if (i != transition_index) { |
| 7721 String* key = t->GetKey(i); | 7740 Name* key = t->GetKey(i); |
| 7722 t->SetKey(transition_index, key); | 7741 t->SetKey(transition_index, key); |
| 7723 Object** key_slot = t->GetKeySlot(transition_index); | 7742 Object** key_slot = t->GetKeySlot(transition_index); |
| 7724 collector->RecordSlot(key_slot, key_slot, key); | 7743 collector->RecordSlot(key_slot, key_slot, key); |
| 7725 // Target slots do not need to be recorded since maps are not compacted. | 7744 // Target slots do not need to be recorded since maps are not compacted. |
| 7726 t->SetTarget(transition_index, t->GetTarget(i)); | 7745 t->SetTarget(transition_index, t->GetTarget(i)); |
| 7727 } | 7746 } |
| 7728 transition_index++; | 7747 transition_index++; |
| 7729 } | 7748 } |
| 7730 } | 7749 } |
| 7731 | 7750 |
| (...skipping 1921 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9653 EnsureElementsMode mode) { | 9672 EnsureElementsMode mode) { |
| 9654 // Elements in |Arguments| are ordered backwards (because they're on the | 9673 // Elements in |Arguments| are ordered backwards (because they're on the |
| 9655 // stack), but the method that's called here iterates over them in forward | 9674 // stack), but the method that's called here iterates over them in forward |
| 9656 // direction. | 9675 // direction. |
| 9657 return EnsureCanContainElements( | 9676 return EnsureCanContainElements( |
| 9658 args->arguments() - first_arg - (arg_count - 1), | 9677 args->arguments() - first_arg - (arg_count - 1), |
| 9659 arg_count, mode); | 9678 arg_count, mode); |
| 9660 } | 9679 } |
| 9661 | 9680 |
| 9662 | 9681 |
| 9663 PropertyType JSObject::GetLocalPropertyType(String* name) { | 9682 PropertyType JSObject::GetLocalPropertyType(Name* name) { |
| 9664 uint32_t index = 0; | 9683 uint32_t index = 0; |
| 9665 if (name->AsArrayIndex(&index)) { | 9684 if (name->AsArrayIndex(&index)) { |
| 9666 return GetLocalElementType(index); | 9685 return GetLocalElementType(index); |
| 9667 } | 9686 } |
| 9668 LookupResult lookup(GetIsolate()); | 9687 LookupResult lookup(GetIsolate()); |
| 9669 LocalLookup(name, &lookup, true); | 9688 LocalLookup(name, &lookup, true); |
| 9670 return lookup.type(); | 9689 return lookup.type(); |
| 9671 } | 9690 } |
| 9672 | 9691 |
| 9673 | 9692 |
| 9674 PropertyType JSObject::GetLocalElementType(uint32_t index) { | 9693 PropertyType JSObject::GetLocalElementType(uint32_t index) { |
| 9675 return GetElementsAccessor()->GetType(this, this, index); | 9694 return GetElementsAccessor()->GetType(this, this, index); |
| 9676 } | 9695 } |
| 9677 | 9696 |
| 9678 | 9697 |
| 9679 AccessorPair* JSObject::GetLocalPropertyAccessorPair(String* name) { | 9698 AccessorPair* JSObject::GetLocalPropertyAccessorPair(Name* name) { |
| 9680 uint32_t index = 0; | 9699 uint32_t index = 0; |
| 9681 if (name->AsArrayIndex(&index)) { | 9700 if (name->AsArrayIndex(&index)) { |
| 9682 return GetLocalElementAccessorPair(index); | 9701 return GetLocalElementAccessorPair(index); |
| 9683 } | 9702 } |
| 9684 | 9703 |
| 9685 LookupResult lookup(GetIsolate()); | 9704 LookupResult lookup(GetIsolate()); |
| 9686 LocalLookupRealNamedProperty(name, &lookup); | 9705 LocalLookupRealNamedProperty(name, &lookup); |
| 9687 | 9706 |
| 9688 if (lookup.IsPropertyCallbacks() && | 9707 if (lookup.IsPropertyCallbacks() && |
| 9689 lookup.GetCallbackObject()->IsAccessorPair()) { | 9708 lookup.GetCallbackObject()->IsAccessorPair()) { |
| (...skipping 1244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10934 JSFunction* constructor = JSFunction::cast(map()->constructor()); | 10953 JSFunction* constructor = JSFunction::cast(map()->constructor()); |
| 10935 ASSERT(constructor->shared()->IsApiFunction()); | 10954 ASSERT(constructor->shared()->IsApiFunction()); |
| 10936 Object* result = | 10955 Object* result = |
| 10937 constructor->shared()->get_api_func_data()->indexed_property_handler(); | 10956 constructor->shared()->get_api_func_data()->indexed_property_handler(); |
| 10938 return InterceptorInfo::cast(result); | 10957 return InterceptorInfo::cast(result); |
| 10939 } | 10958 } |
| 10940 | 10959 |
| 10941 | 10960 |
| 10942 MaybeObject* JSObject::GetPropertyPostInterceptor( | 10961 MaybeObject* JSObject::GetPropertyPostInterceptor( |
| 10943 Object* receiver, | 10962 Object* receiver, |
| 10944 String* name, | 10963 Name* name, |
| 10945 PropertyAttributes* attributes) { | 10964 PropertyAttributes* attributes) { |
| 10946 // Check local property in holder, ignore interceptor. | 10965 // Check local property in holder, ignore interceptor. |
| 10947 LookupResult result(GetIsolate()); | 10966 LookupResult result(GetIsolate()); |
| 10948 LocalLookupRealNamedProperty(name, &result); | 10967 LocalLookupRealNamedProperty(name, &result); |
| 10949 if (result.IsFound()) { | 10968 if (result.IsFound()) { |
| 10950 return GetProperty(receiver, &result, name, attributes); | 10969 return GetProperty(receiver, &result, name, attributes); |
| 10951 } | 10970 } |
| 10952 // Continue searching via the prototype chain. | 10971 // Continue searching via the prototype chain. |
| 10953 Object* pt = GetPrototype(); | 10972 Object* pt = GetPrototype(); |
| 10954 *attributes = ABSENT; | 10973 *attributes = ABSENT; |
| 10955 if (pt->IsNull()) return GetHeap()->undefined_value(); | 10974 if (pt->IsNull()) return GetHeap()->undefined_value(); |
| 10956 return pt->GetPropertyWithReceiver(receiver, name, attributes); | 10975 return pt->GetPropertyWithReceiver(receiver, name, attributes); |
| 10957 } | 10976 } |
| 10958 | 10977 |
| 10959 | 10978 |
| 10960 MaybeObject* JSObject::GetLocalPropertyPostInterceptor( | 10979 MaybeObject* JSObject::GetLocalPropertyPostInterceptor( |
| 10961 Object* receiver, | 10980 Object* receiver, |
| 10962 String* name, | 10981 Name* name, |
| 10963 PropertyAttributes* attributes) { | 10982 PropertyAttributes* attributes) { |
| 10964 // Check local property in holder, ignore interceptor. | 10983 // Check local property in holder, ignore interceptor. |
| 10965 LookupResult result(GetIsolate()); | 10984 LookupResult result(GetIsolate()); |
| 10966 LocalLookupRealNamedProperty(name, &result); | 10985 LocalLookupRealNamedProperty(name, &result); |
| 10967 if (result.IsFound()) { | 10986 if (result.IsFound()) { |
| 10968 return GetProperty(receiver, &result, name, attributes); | 10987 return GetProperty(receiver, &result, name, attributes); |
| 10969 } | 10988 } |
| 10970 return GetHeap()->undefined_value(); | 10989 return GetHeap()->undefined_value(); |
| 10971 } | 10990 } |
| 10972 | 10991 |
| 10973 | 10992 |
| 10974 MaybeObject* JSObject::GetPropertyWithInterceptor( | 10993 MaybeObject* JSObject::GetPropertyWithInterceptor( |
| 10975 Object* receiver, | 10994 Object* receiver, |
| 10976 String* name, | 10995 Name* name, |
| 10977 PropertyAttributes* attributes) { | 10996 PropertyAttributes* attributes) { |
| 10997 // TODO(rossberg): Support symbols in the API. |
| 10998 if (name->IsSymbol()) return GetHeap()->undefined_value(); |
| 10999 |
| 10978 Isolate* isolate = GetIsolate(); | 11000 Isolate* isolate = GetIsolate(); |
| 10979 InterceptorInfo* interceptor = GetNamedInterceptor(); | 11001 InterceptorInfo* interceptor = GetNamedInterceptor(); |
| 10980 HandleScope scope(isolate); | 11002 HandleScope scope(isolate); |
| 10981 Handle<Object> receiver_handle(receiver); | 11003 Handle<Object> receiver_handle(receiver); |
| 10982 Handle<JSObject> holder_handle(this); | 11004 Handle<JSObject> holder_handle(this); |
| 10983 Handle<String> name_handle(name); | 11005 Handle<String> name_handle(String::cast(name)); |
| 10984 | 11006 |
| 10985 if (!interceptor->getter()->IsUndefined()) { | 11007 if (!interceptor->getter()->IsUndefined()) { |
| 10986 v8::NamedPropertyGetter getter = | 11008 v8::NamedPropertyGetter getter = |
| 10987 v8::ToCData<v8::NamedPropertyGetter>(interceptor->getter()); | 11009 v8::ToCData<v8::NamedPropertyGetter>(interceptor->getter()); |
| 10988 LOG(isolate, | 11010 LOG(isolate, |
| 10989 ApiNamedPropertyAccess("interceptor-named-get", *holder_handle, name)); | 11011 ApiNamedPropertyAccess("interceptor-named-get", *holder_handle, name)); |
| 10990 CustomArguments args(isolate, interceptor->data(), receiver, this); | 11012 CustomArguments args(isolate, interceptor->data(), receiver, this); |
| 10991 v8::AccessorInfo info(args.end()); | 11013 v8::AccessorInfo info(args.end()); |
| 10992 v8::Handle<v8::Value> result; | 11014 v8::Handle<v8::Value> result; |
| 10993 { | 11015 { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 11006 | 11028 |
| 11007 MaybeObject* result = holder_handle->GetPropertyPostInterceptor( | 11029 MaybeObject* result = holder_handle->GetPropertyPostInterceptor( |
| 11008 *receiver_handle, | 11030 *receiver_handle, |
| 11009 *name_handle, | 11031 *name_handle, |
| 11010 attributes); | 11032 attributes); |
| 11011 RETURN_IF_SCHEDULED_EXCEPTION(isolate); | 11033 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 11012 return result; | 11034 return result; |
| 11013 } | 11035 } |
| 11014 | 11036 |
| 11015 | 11037 |
| 11016 bool JSObject::HasRealNamedProperty(String* key) { | 11038 bool JSObject::HasRealNamedProperty(Name* key) { |
| 11017 // Check access rights if needed. | 11039 // Check access rights if needed. |
| 11018 Isolate* isolate = GetIsolate(); | 11040 Isolate* isolate = GetIsolate(); |
| 11019 if (IsAccessCheckNeeded()) { | 11041 if (IsAccessCheckNeeded()) { |
| 11020 if (!isolate->MayNamedAccess(this, key, v8::ACCESS_HAS)) { | 11042 if (!isolate->MayNamedAccess(this, key, v8::ACCESS_HAS)) { |
| 11021 isolate->ReportFailedAccessCheck(this, v8::ACCESS_HAS); | 11043 isolate->ReportFailedAccessCheck(this, v8::ACCESS_HAS); |
| 11022 return false; | 11044 return false; |
| 11023 } | 11045 } |
| 11024 } | 11046 } |
| 11025 | 11047 |
| 11026 LookupResult result(isolate); | 11048 LookupResult result(isolate); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11086 case NON_STRICT_ARGUMENTS_ELEMENTS: | 11108 case NON_STRICT_ARGUMENTS_ELEMENTS: |
| 11087 UNIMPLEMENTED(); | 11109 UNIMPLEMENTED(); |
| 11088 break; | 11110 break; |
| 11089 } | 11111 } |
| 11090 // All possibilities have been handled above already. | 11112 // All possibilities have been handled above already. |
| 11091 UNREACHABLE(); | 11113 UNREACHABLE(); |
| 11092 return GetHeap()->null_value(); | 11114 return GetHeap()->null_value(); |
| 11093 } | 11115 } |
| 11094 | 11116 |
| 11095 | 11117 |
| 11096 bool JSObject::HasRealNamedCallbackProperty(String* key) { | 11118 bool JSObject::HasRealNamedCallbackProperty(Name* key) { |
| 11097 // Check access rights if needed. | 11119 // Check access rights if needed. |
| 11098 Isolate* isolate = GetIsolate(); | 11120 Isolate* isolate = GetIsolate(); |
| 11099 if (IsAccessCheckNeeded()) { | 11121 if (IsAccessCheckNeeded()) { |
| 11100 if (!isolate->MayNamedAccess(this, key, v8::ACCESS_HAS)) { | 11122 if (!isolate->MayNamedAccess(this, key, v8::ACCESS_HAS)) { |
| 11101 isolate->ReportFailedAccessCheck(this, v8::ACCESS_HAS); | 11123 isolate->ReportFailedAccessCheck(this, v8::ACCESS_HAS); |
| 11102 return false; | 11124 return false; |
| 11103 } | 11125 } |
| 11104 } | 11126 } |
| 11105 | 11127 |
| 11106 LookupResult result(isolate); | 11128 LookupResult result(isolate); |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11244 if (HasFastProperties()) { | 11266 if (HasFastProperties()) { |
| 11245 int real_size = map()->NumberOfOwnDescriptors(); | 11267 int real_size = map()->NumberOfOwnDescriptors(); |
| 11246 DescriptorArray* descs = map()->instance_descriptors(); | 11268 DescriptorArray* descs = map()->instance_descriptors(); |
| 11247 ASSERT(storage->length() >= index + real_size); | 11269 ASSERT(storage->length() >= index + real_size); |
| 11248 for (int i = 0; i < real_size; i++) { | 11270 for (int i = 0; i < real_size; i++) { |
| 11249 storage->set(index + i, descs->GetKey(i)); | 11271 storage->set(index + i, descs->GetKey(i)); |
| 11250 } | 11272 } |
| 11251 } else { | 11273 } else { |
| 11252 property_dictionary()->CopyKeysTo(storage, | 11274 property_dictionary()->CopyKeysTo(storage, |
| 11253 index, | 11275 index, |
| 11254 StringDictionary::UNSORTED); | 11276 NameDictionary::UNSORTED); |
| 11255 } | 11277 } |
| 11256 } | 11278 } |
| 11257 | 11279 |
| 11258 | 11280 |
| 11259 int JSObject::NumberOfLocalElements(PropertyAttributes filter) { | 11281 int JSObject::NumberOfLocalElements(PropertyAttributes filter) { |
| 11260 return GetLocalElementKeys(NULL, filter); | 11282 return GetLocalElementKeys(NULL, filter); |
| 11261 } | 11283 } |
| 11262 | 11284 |
| 11263 | 11285 |
| 11264 int JSObject::NumberOfEnumElements() { | 11286 int JSObject::NumberOfEnumElements() { |
| (...skipping 518 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11783 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 11805 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 11784 } | 11806 } |
| 11785 HashTable::cast(obj)->SetNumberOfElements(0); | 11807 HashTable::cast(obj)->SetNumberOfElements(0); |
| 11786 HashTable::cast(obj)->SetNumberOfDeletedElements(0); | 11808 HashTable::cast(obj)->SetNumberOfDeletedElements(0); |
| 11787 HashTable::cast(obj)->SetCapacity(capacity); | 11809 HashTable::cast(obj)->SetCapacity(capacity); |
| 11788 return obj; | 11810 return obj; |
| 11789 } | 11811 } |
| 11790 | 11812 |
| 11791 | 11813 |
| 11792 // Find entry for key otherwise return kNotFound. | 11814 // Find entry for key otherwise return kNotFound. |
| 11793 int StringDictionary::FindEntry(String* key) { | 11815 int NameDictionary::FindEntry(Name* key) { |
| 11794 if (!key->IsInternalizedString()) { | 11816 if (!key->IsUniqueName()) { |
| 11795 return HashTable<StringDictionaryShape, String*>::FindEntry(key); | 11817 return HashTable<NameDictionaryShape, Name*>::FindEntry(key); |
| 11796 } | 11818 } |
| 11797 | 11819 |
| 11798 // Optimized for internalized string key. Knowledge of the key type allows: | 11820 // Optimized for unique names. Knowledge of the key type allows: |
| 11799 // 1. Move the check if the key is internalized out of the loop. | 11821 // 1. Move the check if the key is unique out of the loop. |
| 11800 // 2. Avoid comparing hash codes in internalized-to-internalized comparison. | 11822 // 2. Avoid comparing hash codes in unique-to-unique comparison. |
| 11801 // 3. Detect a case when a dictionary key is not internalized but the key is. | 11823 // 3. Detect a case when a dictionary key is not unique but the key is. |
| 11802 // In case of positive result the dictionary key may be replaced by the | 11824 // In case of positive result the dictionary key may be replaced by the |
| 11803 // internalized string with minimal performance penalty. It gives a chance | 11825 // internalized string with minimal performance penalty. It gives a chance |
| 11804 // to perform further lookups in code stubs (and significant performance | 11826 // to perform further lookups in code stubs (and significant performance |
| 11805 // boost a certain style of code). | 11827 // boost a certain style of code). |
| 11806 | 11828 |
| 11807 // EnsureCapacity will guarantee the hash table is never full. | 11829 // EnsureCapacity will guarantee the hash table is never full. |
| 11808 uint32_t capacity = Capacity(); | 11830 uint32_t capacity = Capacity(); |
| 11809 uint32_t entry = FirstProbe(key->Hash(), capacity); | 11831 uint32_t entry = FirstProbe(key->Hash(), capacity); |
| 11810 uint32_t count = 1; | 11832 uint32_t count = 1; |
| 11811 | 11833 |
| 11812 while (true) { | 11834 while (true) { |
| 11813 int index = EntryToIndex(entry); | 11835 int index = EntryToIndex(entry); |
| 11814 Object* element = get(index); | 11836 Object* element = get(index); |
| 11815 if (element->IsUndefined()) break; // Empty entry. | 11837 if (element->IsUndefined()) break; // Empty entry. |
| 11816 if (key == element) return entry; | 11838 if (key == element) return entry; |
| 11817 if (!element->IsInternalizedString() && | 11839 if (!element->IsUniqueName() && |
| 11818 !element->IsTheHole() && | 11840 !element->IsTheHole() && |
| 11819 String::cast(element)->Equals(key)) { | 11841 Name::cast(element)->Equals(key)) { |
| 11820 // Replace a key that is not an internalized string by the equivalent | 11842 // Replace a key that is a non-internalized string by the equivalent |
| 11821 // internalized string for faster further lookups. | 11843 // internalized string for faster further lookups. |
| 11822 set(index, key); | 11844 set(index, key); |
| 11823 return entry; | 11845 return entry; |
| 11824 } | 11846 } |
| 11825 ASSERT(element->IsTheHole() || !String::cast(element)->Equals(key)); | 11847 ASSERT(element->IsTheHole() || !Name::cast(element)->Equals(key)); |
| 11826 entry = NextProbe(entry, count++, capacity); | 11848 entry = NextProbe(entry, count++, capacity); |
| 11827 } | 11849 } |
| 11828 return kNotFound; | 11850 return kNotFound; |
| 11829 } | 11851 } |
| 11830 | 11852 |
| 11831 | 11853 |
| 11832 template<typename Shape, typename Key> | 11854 template<typename Shape, typename Key> |
| 11833 MaybeObject* HashTable<Shape, Key>::Rehash(HashTable* new_table, Key key) { | 11855 MaybeObject* HashTable<Shape, Key>::Rehash(HashTable* new_table, Key key) { |
| 11834 ASSERT(NumberOfElements() < new_table->Capacity()); | 11856 ASSERT(NumberOfElements() < new_table->Capacity()); |
| 11835 | 11857 |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11942 template class HashTable<StringTableShape, HashTableKey*>; | 11964 template class HashTable<StringTableShape, HashTableKey*>; |
| 11943 | 11965 |
| 11944 template class HashTable<CompilationCacheShape, HashTableKey*>; | 11966 template class HashTable<CompilationCacheShape, HashTableKey*>; |
| 11945 | 11967 |
| 11946 template class HashTable<MapCacheShape, HashTableKey*>; | 11968 template class HashTable<MapCacheShape, HashTableKey*>; |
| 11947 | 11969 |
| 11948 template class HashTable<ObjectHashTableShape<1>, Object*>; | 11970 template class HashTable<ObjectHashTableShape<1>, Object*>; |
| 11949 | 11971 |
| 11950 template class HashTable<ObjectHashTableShape<2>, Object*>; | 11972 template class HashTable<ObjectHashTableShape<2>, Object*>; |
| 11951 | 11973 |
| 11952 template class Dictionary<StringDictionaryShape, String*>; | 11974 template class Dictionary<NameDictionaryShape, Name*>; |
| 11953 | 11975 |
| 11954 template class Dictionary<SeededNumberDictionaryShape, uint32_t>; | 11976 template class Dictionary<SeededNumberDictionaryShape, uint32_t>; |
| 11955 | 11977 |
| 11956 template class Dictionary<UnseededNumberDictionaryShape, uint32_t>; | 11978 template class Dictionary<UnseededNumberDictionaryShape, uint32_t>; |
| 11957 | 11979 |
| 11958 template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>:: | 11980 template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>:: |
| 11959 Allocate(int at_least_space_for); | 11981 Allocate(int at_least_space_for); |
| 11960 | 11982 |
| 11961 template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>:: | 11983 template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>:: |
| 11962 Allocate(int at_least_space_for); | 11984 Allocate(int at_least_space_for); |
| 11963 | 11985 |
| 11964 template MaybeObject* Dictionary<StringDictionaryShape, String*>::Allocate( | 11986 template MaybeObject* Dictionary<NameDictionaryShape, Name*>::Allocate(int n); |
| 11965 int); | |
| 11966 | 11987 |
| 11967 template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>::AtPut( | 11988 template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>::AtPut( |
| 11968 uint32_t, Object*); | 11989 uint32_t, Object*); |
| 11969 | 11990 |
| 11970 template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>:: | 11991 template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>:: |
| 11971 AtPut(uint32_t, Object*); | 11992 AtPut(uint32_t, Object*); |
| 11972 | 11993 |
| 11973 template Object* Dictionary<SeededNumberDictionaryShape, uint32_t>:: | 11994 template Object* Dictionary<SeededNumberDictionaryShape, uint32_t>:: |
| 11974 SlowReverseLookup(Object* value); | 11995 SlowReverseLookup(Object* value); |
| 11975 | 11996 |
| 11976 template Object* Dictionary<UnseededNumberDictionaryShape, uint32_t>:: | 11997 template Object* Dictionary<UnseededNumberDictionaryShape, uint32_t>:: |
| 11977 SlowReverseLookup(Object* value); | 11998 SlowReverseLookup(Object* value); |
| 11978 | 11999 |
| 11979 template Object* Dictionary<StringDictionaryShape, String*>::SlowReverseLookup( | 12000 template Object* Dictionary<NameDictionaryShape, Name*>::SlowReverseLookup( |
| 11980 Object*); | 12001 Object*); |
| 11981 | 12002 |
| 11982 template void Dictionary<SeededNumberDictionaryShape, uint32_t>::CopyKeysTo( | 12003 template void Dictionary<SeededNumberDictionaryShape, uint32_t>::CopyKeysTo( |
| 11983 FixedArray*, | 12004 FixedArray*, |
| 11984 PropertyAttributes, | 12005 PropertyAttributes, |
| 11985 Dictionary<SeededNumberDictionaryShape, uint32_t>::SortMode); | 12006 Dictionary<SeededNumberDictionaryShape, uint32_t>::SortMode); |
| 11986 | 12007 |
| 11987 template Object* Dictionary<StringDictionaryShape, String*>::DeleteProperty( | 12008 template Object* Dictionary<NameDictionaryShape, Name*>::DeleteProperty( |
| 11988 int, JSObject::DeleteMode); | 12009 int, JSObject::DeleteMode); |
| 11989 | 12010 |
| 11990 template Object* Dictionary<SeededNumberDictionaryShape, uint32_t>:: | 12011 template Object* Dictionary<SeededNumberDictionaryShape, uint32_t>:: |
| 11991 DeleteProperty(int, JSObject::DeleteMode); | 12012 DeleteProperty(int, JSObject::DeleteMode); |
| 11992 | 12013 |
| 11993 template MaybeObject* Dictionary<StringDictionaryShape, String*>::Shrink( | 12014 template MaybeObject* Dictionary<NameDictionaryShape, Name*>::Shrink(Name* n); |
| 11994 String*); | |
| 11995 | 12015 |
| 11996 template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>::Shrink( | 12016 template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>::Shrink( |
| 11997 uint32_t); | 12017 uint32_t); |
| 11998 | 12018 |
| 11999 template void Dictionary<StringDictionaryShape, String*>::CopyKeysTo( | 12019 template void Dictionary<NameDictionaryShape, Name*>::CopyKeysTo( |
| 12000 FixedArray*, | 12020 FixedArray*, |
| 12001 int, | 12021 int, |
| 12002 Dictionary<StringDictionaryShape, String*>::SortMode); | 12022 Dictionary<NameDictionaryShape, Name*>::SortMode); |
| 12003 | 12023 |
| 12004 template int | 12024 template int |
| 12005 Dictionary<StringDictionaryShape, String*>::NumberOfElementsFilterAttributes( | 12025 Dictionary<NameDictionaryShape, Name*>::NumberOfElementsFilterAttributes( |
| 12006 PropertyAttributes); | 12026 PropertyAttributes); |
| 12007 | 12027 |
| 12008 template MaybeObject* Dictionary<StringDictionaryShape, String*>::Add( | 12028 template MaybeObject* Dictionary<NameDictionaryShape, Name*>::Add( |
| 12009 String*, Object*, PropertyDetails); | 12029 Name*, Object*, PropertyDetails); |
| 12010 | 12030 |
| 12011 template MaybeObject* | 12031 template MaybeObject* |
| 12012 Dictionary<StringDictionaryShape, String*>::GenerateNewEnumerationIndices(); | 12032 Dictionary<NameDictionaryShape, Name*>::GenerateNewEnumerationIndices(); |
| 12013 | 12033 |
| 12014 template int | 12034 template int |
| 12015 Dictionary<SeededNumberDictionaryShape, uint32_t>:: | 12035 Dictionary<SeededNumberDictionaryShape, uint32_t>:: |
| 12016 NumberOfElementsFilterAttributes(PropertyAttributes); | 12036 NumberOfElementsFilterAttributes(PropertyAttributes); |
| 12017 | 12037 |
| 12018 template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>::Add( | 12038 template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>::Add( |
| 12019 uint32_t, Object*, PropertyDetails); | 12039 uint32_t, Object*, PropertyDetails); |
| 12020 | 12040 |
| 12021 template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>::Add( | 12041 template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>::Add( |
| 12022 uint32_t, Object*, PropertyDetails); | 12042 uint32_t, Object*, PropertyDetails); |
| 12023 | 12043 |
| 12024 template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>:: | 12044 template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>:: |
| 12025 EnsureCapacity(int, uint32_t); | 12045 EnsureCapacity(int, uint32_t); |
| 12026 | 12046 |
| 12027 template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>:: | 12047 template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>:: |
| 12028 EnsureCapacity(int, uint32_t); | 12048 EnsureCapacity(int, uint32_t); |
| 12029 | 12049 |
| 12030 template MaybeObject* Dictionary<StringDictionaryShape, String*>:: | 12050 template MaybeObject* Dictionary<NameDictionaryShape, Name*>:: |
| 12031 EnsureCapacity(int, String*); | 12051 EnsureCapacity(int, Name*); |
| 12032 | 12052 |
| 12033 template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>:: | 12053 template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>:: |
| 12034 AddEntry(uint32_t, Object*, PropertyDetails, uint32_t); | 12054 AddEntry(uint32_t, Object*, PropertyDetails, uint32_t); |
| 12035 | 12055 |
| 12036 template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>:: | 12056 template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>:: |
| 12037 AddEntry(uint32_t, Object*, PropertyDetails, uint32_t); | 12057 AddEntry(uint32_t, Object*, PropertyDetails, uint32_t); |
| 12038 | 12058 |
| 12039 template MaybeObject* Dictionary<StringDictionaryShape, String*>::AddEntry( | 12059 template MaybeObject* Dictionary<NameDictionaryShape, Name*>::AddEntry( |
| 12040 String*, Object*, PropertyDetails, uint32_t); | 12060 Name*, Object*, PropertyDetails, uint32_t); |
| 12041 | 12061 |
| 12042 template | 12062 template |
| 12043 int Dictionary<SeededNumberDictionaryShape, uint32_t>::NumberOfEnumElements(); | 12063 int Dictionary<SeededNumberDictionaryShape, uint32_t>::NumberOfEnumElements(); |
| 12044 | 12064 |
| 12045 template | 12065 template |
| 12046 int Dictionary<StringDictionaryShape, String*>::NumberOfEnumElements(); | 12066 int Dictionary<NameDictionaryShape, Name*>::NumberOfEnumElements(); |
| 12047 | 12067 |
| 12048 template | 12068 template |
| 12049 int HashTable<SeededNumberDictionaryShape, uint32_t>::FindEntry(uint32_t); | 12069 int HashTable<SeededNumberDictionaryShape, uint32_t>::FindEntry(uint32_t); |
| 12050 | 12070 |
| 12051 | 12071 |
| 12052 // Collates undefined and unexisting elements below limit from position | 12072 // Collates undefined and unexisting elements below limit from position |
| 12053 // zero of the elements. The object stays in Dictionary mode. | 12073 // zero of the elements. The object stays in Dictionary mode. |
| 12054 MaybeObject* JSObject::PrepareSlowElementsForSort(uint32_t limit) { | 12074 MaybeObject* JSObject::PrepareSlowElementsForSort(uint32_t limit) { |
| 12055 ASSERT(HasDictionaryElements()); | 12075 ASSERT(HasDictionaryElements()); |
| 12056 // Must stay in dictionary mode, either because of requires_slow_elements, | 12076 // Must stay in dictionary mode, either because of requires_slow_elements, |
| (...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12454 | 12474 |
| 12455 JSGlobalPropertyCell* GlobalObject::GetPropertyCell(LookupResult* result) { | 12475 JSGlobalPropertyCell* GlobalObject::GetPropertyCell(LookupResult* result) { |
| 12456 ASSERT(!HasFastProperties()); | 12476 ASSERT(!HasFastProperties()); |
| 12457 Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry()); | 12477 Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry()); |
| 12458 return JSGlobalPropertyCell::cast(value); | 12478 return JSGlobalPropertyCell::cast(value); |
| 12459 } | 12479 } |
| 12460 | 12480 |
| 12461 | 12481 |
| 12462 Handle<JSGlobalPropertyCell> GlobalObject::EnsurePropertyCell( | 12482 Handle<JSGlobalPropertyCell> GlobalObject::EnsurePropertyCell( |
| 12463 Handle<GlobalObject> global, | 12483 Handle<GlobalObject> global, |
| 12464 Handle<String> name) { | 12484 Handle<Name> name) { |
| 12465 Isolate* isolate = global->GetIsolate(); | 12485 Isolate* isolate = global->GetIsolate(); |
| 12466 CALL_HEAP_FUNCTION(isolate, | 12486 CALL_HEAP_FUNCTION(isolate, |
| 12467 global->EnsurePropertyCell(*name), | 12487 global->EnsurePropertyCell(*name), |
| 12468 JSGlobalPropertyCell); | 12488 JSGlobalPropertyCell); |
| 12469 } | 12489 } |
| 12470 | 12490 |
| 12471 | 12491 |
| 12472 MaybeObject* GlobalObject::EnsurePropertyCell(String* name) { | 12492 MaybeObject* GlobalObject::EnsurePropertyCell(Name* name) { |
| 12473 ASSERT(!HasFastProperties()); | 12493 ASSERT(!HasFastProperties()); |
| 12474 int entry = property_dictionary()->FindEntry(name); | 12494 int entry = property_dictionary()->FindEntry(name); |
| 12475 if (entry == StringDictionary::kNotFound) { | 12495 if (entry == NameDictionary::kNotFound) { |
| 12476 Heap* heap = GetHeap(); | 12496 Heap* heap = GetHeap(); |
| 12477 Object* cell; | 12497 Object* cell; |
| 12478 { MaybeObject* maybe_cell = | 12498 { MaybeObject* maybe_cell = |
| 12479 heap->AllocateJSGlobalPropertyCell(heap->the_hole_value()); | 12499 heap->AllocateJSGlobalPropertyCell(heap->the_hole_value()); |
| 12480 if (!maybe_cell->ToObject(&cell)) return maybe_cell; | 12500 if (!maybe_cell->ToObject(&cell)) return maybe_cell; |
| 12481 } | 12501 } |
| 12482 PropertyDetails details(NONE, NORMAL); | 12502 PropertyDetails details(NONE, NORMAL); |
| 12483 details = details.AsDeleted(); | 12503 details = details.AsDeleted(); |
| 12484 Object* dictionary; | 12504 Object* dictionary; |
| 12485 { MaybeObject* maybe_dictionary = | 12505 { MaybeObject* maybe_dictionary = |
| 12486 property_dictionary()->Add(name, cell, details); | 12506 property_dictionary()->Add(name, cell, details); |
| 12487 if (!maybe_dictionary->ToObject(&dictionary)) return maybe_dictionary; | 12507 if (!maybe_dictionary->ToObject(&dictionary)) return maybe_dictionary; |
| 12488 } | 12508 } |
| 12489 set_properties(StringDictionary::cast(dictionary)); | 12509 set_properties(NameDictionary::cast(dictionary)); |
| 12490 return cell; | 12510 return cell; |
| 12491 } else { | 12511 } else { |
| 12492 Object* value = property_dictionary()->ValueAt(entry); | 12512 Object* value = property_dictionary()->ValueAt(entry); |
| 12493 ASSERT(value->IsJSGlobalPropertyCell()); | 12513 ASSERT(value->IsJSGlobalPropertyCell()); |
| 12494 return value; | 12514 return value; |
| 12495 } | 12515 } |
| 12496 } | 12516 } |
| 12497 | 12517 |
| 12498 | 12518 |
| 12499 MaybeObject* StringTable::LookupString(String* string, Object** s) { | 12519 MaybeObject* StringTable::LookupString(String* string, Object** s) { |
| (...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12787 if (get(value_index) == value) { | 12807 if (get(value_index) == value) { |
| 12788 NoWriteBarrierSet(this, entry_index, the_hole_value); | 12808 NoWriteBarrierSet(this, entry_index, the_hole_value); |
| 12789 NoWriteBarrierSet(this, value_index, the_hole_value); | 12809 NoWriteBarrierSet(this, value_index, the_hole_value); |
| 12790 ElementRemoved(); | 12810 ElementRemoved(); |
| 12791 } | 12811 } |
| 12792 } | 12812 } |
| 12793 return; | 12813 return; |
| 12794 } | 12814 } |
| 12795 | 12815 |
| 12796 | 12816 |
| 12797 // StringsKey used for HashTable where key is array of internalzied strings. | 12817 // StringsKey used for HashTable where key is array of internalized strings. |
| 12798 class StringsKey : public HashTableKey { | 12818 class StringsKey : public HashTableKey { |
| 12799 public: | 12819 public: |
| 12800 explicit StringsKey(FixedArray* strings) : strings_(strings) { } | 12820 explicit StringsKey(FixedArray* strings) : strings_(strings) { } |
| 12801 | 12821 |
| 12802 bool IsMatch(Object* strings) { | 12822 bool IsMatch(Object* strings) { |
| 12803 FixedArray* o = FixedArray::cast(strings); | 12823 FixedArray* o = FixedArray::cast(strings); |
| 12804 int len = strings_->length(); | 12824 int len = strings_->length(); |
| 12805 if (o->length() != len) return false; | 12825 if (o->length() != len) return false; |
| 12806 for (int i = 0; i < len; i++) { | 12826 for (int i = 0; i < len; i++) { |
| 12807 if (o->get(i) != strings_->get(i)) return false; | 12827 if (o->get(i) != strings_->get(i)) return false; |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12859 HashTable<Shape, Key>::Allocate(at_least_space_for); | 12879 HashTable<Shape, Key>::Allocate(at_least_space_for); |
| 12860 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 12880 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 12861 } | 12881 } |
| 12862 // Initialize the next enumeration index. | 12882 // Initialize the next enumeration index. |
| 12863 Dictionary<Shape, Key>::cast(obj)-> | 12883 Dictionary<Shape, Key>::cast(obj)-> |
| 12864 SetNextEnumerationIndex(PropertyDetails::kInitialIndex); | 12884 SetNextEnumerationIndex(PropertyDetails::kInitialIndex); |
| 12865 return obj; | 12885 return obj; |
| 12866 } | 12886 } |
| 12867 | 12887 |
| 12868 | 12888 |
| 12869 void StringDictionary::DoGenerateNewEnumerationIndices( | 12889 void NameDictionary::DoGenerateNewEnumerationIndices( |
| 12870 Handle<StringDictionary> dictionary) { | 12890 Handle<NameDictionary> dictionary) { |
| 12871 CALL_HEAP_FUNCTION_VOID(dictionary->GetIsolate(), | 12891 CALL_HEAP_FUNCTION_VOID(dictionary->GetIsolate(), |
| 12872 dictionary->GenerateNewEnumerationIndices()); | 12892 dictionary->GenerateNewEnumerationIndices()); |
| 12873 } | 12893 } |
| 12874 | 12894 |
| 12875 template<typename Shape, typename Key> | 12895 template<typename Shape, typename Key> |
| 12876 MaybeObject* Dictionary<Shape, Key>::GenerateNewEnumerationIndices() { | 12896 MaybeObject* Dictionary<Shape, Key>::GenerateNewEnumerationIndices() { |
| 12877 Heap* heap = Dictionary<Shape, Key>::GetHeap(); | 12897 Heap* heap = Dictionary<Shape, Key>::GetHeap(); |
| 12878 int length = HashTable<Shape, Key>::NumberOfElements(); | 12898 int length = HashTable<Shape, Key>::NumberOfElements(); |
| 12879 | 12899 |
| 12880 // Allocate and initialize iteration order array. | 12900 // Allocate and initialize iteration order array. |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13030 if (!details.IsDeleted() && | 13050 if (!details.IsDeleted() && |
| 13031 details.dictionary_index() == 0 && | 13051 details.dictionary_index() == 0 && |
| 13032 Shape::kIsEnumerable) { | 13052 Shape::kIsEnumerable) { |
| 13033 // Assign an enumeration index to the property and update | 13053 // Assign an enumeration index to the property and update |
| 13034 // SetNextEnumerationIndex. | 13054 // SetNextEnumerationIndex. |
| 13035 int index = NextEnumerationIndex(); | 13055 int index = NextEnumerationIndex(); |
| 13036 details = PropertyDetails(details.attributes(), details.type(), index); | 13056 details = PropertyDetails(details.attributes(), details.type(), index); |
| 13037 SetNextEnumerationIndex(index + 1); | 13057 SetNextEnumerationIndex(index + 1); |
| 13038 } | 13058 } |
| 13039 SetEntry(entry, k, value, details); | 13059 SetEntry(entry, k, value, details); |
| 13040 ASSERT((Dictionary<Shape, Key>::KeyAt(entry)->IsNumber() | 13060 ASSERT((Dictionary<Shape, Key>::KeyAt(entry)->IsNumber() || |
| 13041 || Dictionary<Shape, Key>::KeyAt(entry)->IsString())); | 13061 Dictionary<Shape, Key>::KeyAt(entry)->IsName())); |
| 13042 HashTable<Shape, Key>::ElementAdded(); | 13062 HashTable<Shape, Key>::ElementAdded(); |
| 13043 return this; | 13063 return this; |
| 13044 } | 13064 } |
| 13045 | 13065 |
| 13046 | 13066 |
| 13047 void SeededNumberDictionary::UpdateMaxNumberKey(uint32_t key) { | 13067 void SeededNumberDictionary::UpdateMaxNumberKey(uint32_t key) { |
| 13048 // If the dictionary requires slow elements an element has already | 13068 // If the dictionary requires slow elements an element has already |
| 13049 // been added at a high index. | 13069 // been added at a high index. |
| 13050 if (requires_slow_elements()) return; | 13070 if (requires_slow_elements()) return; |
| 13051 // Check if this index is high enough that we should require slow | 13071 // Check if this index is high enough that we should require slow |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13184 if ((attr & filter) == 0) storage->set(index++, k); | 13204 if ((attr & filter) == 0) storage->set(index++, k); |
| 13185 } | 13205 } |
| 13186 } | 13206 } |
| 13187 if (sort_mode == Dictionary<Shape, Key>::SORTED) { | 13207 if (sort_mode == Dictionary<Shape, Key>::SORTED) { |
| 13188 storage->SortPairs(storage, index); | 13208 storage->SortPairs(storage, index); |
| 13189 } | 13209 } |
| 13190 ASSERT(storage->length() >= index); | 13210 ASSERT(storage->length() >= index); |
| 13191 } | 13211 } |
| 13192 | 13212 |
| 13193 | 13213 |
| 13194 FixedArray* StringDictionary::CopyEnumKeysTo(FixedArray* storage) { | 13214 FixedArray* NameDictionary::CopyEnumKeysTo(FixedArray* storage) { |
| 13195 int length = storage->length(); | 13215 int length = storage->length(); |
| 13196 ASSERT(length >= NumberOfEnumElements()); | 13216 ASSERT(length >= NumberOfEnumElements()); |
| 13197 Heap* heap = GetHeap(); | 13217 Heap* heap = GetHeap(); |
| 13198 Object* undefined_value = heap->undefined_value(); | 13218 Object* undefined_value = heap->undefined_value(); |
| 13199 int capacity = Capacity(); | 13219 int capacity = Capacity(); |
| 13200 int properties = 0; | 13220 int properties = 0; |
| 13201 | 13221 |
| 13202 // Fill in the enumeration array by assigning enumerable keys at their | 13222 // Fill in the enumeration array by assigning enumerable keys at their |
| 13203 // enumeration index. This will leave holes in the array if there are keys | 13223 // enumeration index. This will leave holes in the array if there are keys |
| 13204 // that are deleted or not enumerable. | 13224 // that are deleted or not enumerable. |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13268 e = JSGlobalPropertyCell::cast(e)->value(); | 13288 e = JSGlobalPropertyCell::cast(e)->value(); |
| 13269 } | 13289 } |
| 13270 if (e == value) return k; | 13290 if (e == value) return k; |
| 13271 } | 13291 } |
| 13272 } | 13292 } |
| 13273 Heap* heap = Dictionary<Shape, Key>::GetHeap(); | 13293 Heap* heap = Dictionary<Shape, Key>::GetHeap(); |
| 13274 return heap->undefined_value(); | 13294 return heap->undefined_value(); |
| 13275 } | 13295 } |
| 13276 | 13296 |
| 13277 | 13297 |
| 13278 MaybeObject* StringDictionary::TransformPropertiesToFastFor( | 13298 MaybeObject* NameDictionary::TransformPropertiesToFastFor( |
| 13279 JSObject* obj, int unused_property_fields) { | 13299 JSObject* obj, int unused_property_fields) { |
| 13280 // Make sure we preserve dictionary representation if there are too many | 13300 // Make sure we preserve dictionary representation if there are too many |
| 13281 // descriptors. | 13301 // descriptors. |
| 13282 int number_of_elements = NumberOfElements(); | 13302 int number_of_elements = NumberOfElements(); |
| 13283 if (number_of_elements > DescriptorArray::kMaxNumberOfDescriptors) return obj; | 13303 if (number_of_elements > DescriptorArray::kMaxNumberOfDescriptors) return obj; |
| 13284 | 13304 |
| 13285 if (number_of_elements != NextEnumerationIndex()) { | 13305 if (number_of_elements != NextEnumerationIndex()) { |
| 13286 MaybeObject* maybe_result = GenerateNewEnumerationIndices(); | 13306 MaybeObject* maybe_result = GenerateNewEnumerationIndices(); |
| 13287 if (maybe_result->IsFailure()) return maybe_result; | 13307 if (maybe_result->IsFailure()) return maybe_result; |
| 13288 } | 13308 } |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13349 MaybeObject* maybe_fields = | 13369 MaybeObject* maybe_fields = |
| 13350 heap->AllocateFixedArray(number_of_allocated_fields); | 13370 heap->AllocateFixedArray(number_of_allocated_fields); |
| 13351 if (!maybe_fields->To(&fields)) return maybe_fields; | 13371 if (!maybe_fields->To(&fields)) return maybe_fields; |
| 13352 | 13372 |
| 13353 // Fill in the instance descriptor and the fields. | 13373 // Fill in the instance descriptor and the fields. |
| 13354 int current_offset = 0; | 13374 int current_offset = 0; |
| 13355 for (int i = 0; i < capacity; i++) { | 13375 for (int i = 0; i < capacity; i++) { |
| 13356 Object* k = KeyAt(i); | 13376 Object* k = KeyAt(i); |
| 13357 if (IsKey(k)) { | 13377 if (IsKey(k)) { |
| 13358 Object* value = ValueAt(i); | 13378 Object* value = ValueAt(i); |
| 13359 // Ensure the key is an internalized string before writing into the | 13379 Name* key; |
| 13360 // instance descriptor. | 13380 if (k->IsSymbol()) { |
| 13361 String* key; | 13381 key = Symbol::cast(k); |
| 13362 MaybeObject* maybe_key = heap->InternalizeString(String::cast(k)); | 13382 } else { |
| 13363 if (!maybe_key->To(&key)) return maybe_key; | 13383 // Ensure the key is a unique name before writing into the |
| 13384 // instance descriptor. |
| 13385 MaybeObject* maybe_key = heap->InternalizeString(String::cast(k)); |
| 13386 if (!maybe_key->To(&key)) return maybe_key; |
| 13387 } |
| 13364 | 13388 |
| 13365 PropertyDetails details = DetailsAt(i); | 13389 PropertyDetails details = DetailsAt(i); |
| 13366 ASSERT(details.descriptor_index() == details.dictionary_index()); | 13390 ASSERT(details.descriptor_index() == details.dictionary_index()); |
| 13367 int enumeration_index = details.descriptor_index(); | 13391 int enumeration_index = details.descriptor_index(); |
| 13368 PropertyType type = details.type(); | 13392 PropertyType type = details.type(); |
| 13369 | 13393 |
| 13370 if (value->IsJSFunction()) { | 13394 if (value->IsJSFunction()) { |
| 13371 ConstantFunctionDescriptor d(key, | 13395 ConstantFunctionDescriptor d(key, |
| 13372 JSFunction::cast(value), | 13396 JSFunction::cast(value), |
| 13373 details.attributes(), | 13397 details.attributes(), |
| (...skipping 541 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13915 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); | 13939 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); |
| 13916 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); | 13940 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); |
| 13917 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); | 13941 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); |
| 13918 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); | 13942 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); |
| 13919 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); | 13943 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); |
| 13920 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); | 13944 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); |
| 13921 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); | 13945 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); |
| 13922 } | 13946 } |
| 13923 | 13947 |
| 13924 } } // namespace v8::internal | 13948 } } // namespace v8::internal |
| OLD | NEW |