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 |