| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 128 if (heap_object->IsHeapNumber()) { | 128 if (heap_object->IsHeapNumber()) { |
| 129 return HeapNumber::cast(this)->HeapNumberToBoolean(); | 129 return HeapNumber::cast(this)->HeapNumberToBoolean(); |
| 130 } | 130 } |
| 131 return heap_object->GetHeap()->true_value(); | 131 return heap_object->GetHeap()->true_value(); |
| 132 } | 132 } |
| 133 | 133 |
| 134 | 134 |
| 135 void Object::Lookup(String* name, LookupResult* result) { | 135 void Object::Lookup(String* name, LookupResult* result) { |
| 136 Object* holder = NULL; | 136 Object* holder = NULL; |
| 137 if (IsSmi()) { | 137 if (IsSmi()) { |
| 138 Heap* heap = Isolate::Current()->heap(); | 138 Context* global_context = Isolate::Current()->context()->global_context(); |
| 139 Context* global_context = heap->isolate()->context()->global_context(); | |
| 140 holder = global_context->number_function()->instance_prototype(); | 139 holder = global_context->number_function()->instance_prototype(); |
| 141 } else { | 140 } else { |
| 142 HeapObject* heap_object = HeapObject::cast(this); | 141 HeapObject* heap_object = HeapObject::cast(this); |
| 143 if (heap_object->IsJSObject()) { | 142 if (heap_object->IsJSObject()) { |
| 144 return JSObject::cast(this)->Lookup(name, result); | 143 return JSObject::cast(this)->Lookup(name, result); |
| 145 } | 144 } |
| 146 Heap* heap = heap_object->GetHeap(); | 145 Context* global_context = Isolate::Current()->context()->global_context(); |
| 147 if (heap_object->IsString()) { | 146 if (heap_object->IsString()) { |
| 148 Context* global_context = heap->isolate()->context()->global_context(); | |
| 149 holder = global_context->string_function()->instance_prototype(); | 147 holder = global_context->string_function()->instance_prototype(); |
| 150 } else if (heap_object->IsHeapNumber()) { | 148 } else if (heap_object->IsHeapNumber()) { |
| 151 Context* global_context = heap->isolate()->context()->global_context(); | |
| 152 holder = global_context->number_function()->instance_prototype(); | 149 holder = global_context->number_function()->instance_prototype(); |
| 153 } else if (heap_object->IsBoolean()) { | 150 } else if (heap_object->IsBoolean()) { |
| 154 Context* global_context = heap->isolate()->context()->global_context(); | |
| 155 holder = global_context->boolean_function()->instance_prototype(); | 151 holder = global_context->boolean_function()->instance_prototype(); |
| 152 } else if (heap_object->IsJSProxy()) { |
| 153 return result->HandlerResult(); |
| 156 } | 154 } |
| 157 } | 155 } |
| 158 ASSERT(holder != NULL); // Cannot handle null or undefined. | 156 ASSERT(holder != NULL); // Cannot handle null or undefined. |
| 159 JSObject::cast(holder)->Lookup(name, result); | 157 JSObject::cast(holder)->Lookup(name, result); |
| 160 } | 158 } |
| 161 | 159 |
| 162 | 160 |
| 163 MaybeObject* Object::GetPropertyWithReceiver(Object* receiver, | 161 MaybeObject* Object::GetPropertyWithReceiver(Object* receiver, |
| 164 String* name, | 162 String* name, |
| 165 PropertyAttributes* attributes) { | 163 PropertyAttributes* attributes) { |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 221 } | 219 } |
| 222 // Getter is not a function. | 220 // Getter is not a function. |
| 223 return isolate->heap()->undefined_value(); | 221 return isolate->heap()->undefined_value(); |
| 224 } | 222 } |
| 225 | 223 |
| 226 UNREACHABLE(); | 224 UNREACHABLE(); |
| 227 return NULL; | 225 return NULL; |
| 228 } | 226 } |
| 229 | 227 |
| 230 | 228 |
| 229 MaybeObject* Object::GetPropertyWithHandler(Object* receiver_raw, |
| 230 String* name_raw, |
| 231 Object* handler_raw) { |
| 232 Isolate* isolate = name_raw->GetIsolate(); |
| 233 HandleScope scope; |
| 234 Handle<Object> receiver(receiver_raw); |
| 235 Handle<Object> name(name_raw); |
| 236 Handle<Object> handler(handler_raw); |
| 237 |
| 238 // Extract trap function. |
| 239 LookupResult lookup; |
| 240 Handle<Object> trap(v8::internal::GetProperty(handler, "get", &lookup)); |
| 241 if (!lookup.IsFound()) { |
| 242 // Get the derived `get' property. |
| 243 trap = isolate->derived_get_trap(); |
| 244 } |
| 245 |
| 246 // Call trap function. |
| 247 Object** args[] = { receiver.location(), name.location() }; |
| 248 bool has_exception; |
| 249 Handle<Object> result = |
| 250 Execution::Call(trap, handler, ARRAY_SIZE(args), args, &has_exception); |
| 251 if (has_exception) return Failure::Exception(); |
| 252 |
| 253 return *result; |
| 254 } |
| 255 |
| 256 |
| 231 MaybeObject* Object::GetPropertyWithDefinedGetter(Object* receiver, | 257 MaybeObject* Object::GetPropertyWithDefinedGetter(Object* receiver, |
| 232 JSFunction* getter) { | 258 JSFunction* getter) { |
| 233 HandleScope scope; | 259 HandleScope scope; |
| 234 Handle<JSFunction> fun(JSFunction::cast(getter)); | 260 Handle<JSFunction> fun(JSFunction::cast(getter)); |
| 235 Handle<Object> self(receiver); | 261 Handle<Object> self(receiver); |
| 236 #ifdef ENABLE_DEBUGGER_SUPPORT | 262 #ifdef ENABLE_DEBUGGER_SUPPORT |
| 237 Debug* debug = fun->GetHeap()->isolate()->debug(); | 263 Debug* debug = fun->GetHeap()->isolate()->debug(); |
| 238 // Handle stepping into a getter if step into is active. | 264 // Handle stepping into a getter if step into is active. |
| 239 if (debug->StepInActive()) { | 265 if (debug->StepInActive()) { |
| 240 debug->HandleStepIn(fun, Handle<Object>::null(), 0, false); | 266 debug->HandleStepIn(fun, Handle<Object>::null(), 0, false); |
| (...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 488 MaybeObject* Object::GetProperty(Object* receiver, | 514 MaybeObject* Object::GetProperty(Object* receiver, |
| 489 LookupResult* result, | 515 LookupResult* result, |
| 490 String* name, | 516 String* name, |
| 491 PropertyAttributes* attributes) { | 517 PropertyAttributes* attributes) { |
| 492 // Make sure that the top context does not change when doing | 518 // Make sure that the top context does not change when doing |
| 493 // callbacks or interceptor calls. | 519 // callbacks or interceptor calls. |
| 494 AssertNoContextChange ncc; | 520 AssertNoContextChange ncc; |
| 495 Heap* heap = name->GetHeap(); | 521 Heap* heap = name->GetHeap(); |
| 496 | 522 |
| 497 // Traverse the prototype chain from the current object (this) to | 523 // Traverse the prototype chain from the current object (this) to |
| 498 // the holder and check for access rights. This avoid traversing the | 524 // the holder and check for access rights. This avoids traversing the |
| 499 // objects more than once in case of interceptors, because the | 525 // objects more than once in case of interceptors, because the |
| 500 // holder will always be the interceptor holder and the search may | 526 // holder will always be the interceptor holder and the search may |
| 501 // only continue with a current object just after the interceptor | 527 // only continue with a current object just after the interceptor |
| 502 // holder in the prototype chain. | 528 // holder in the prototype chain. |
| 503 Object* last = result->IsProperty() ? result->holder() : heap->null_value(); | 529 // Proxy handlers do not use the proxy's prototype, so we can skip this. |
| 504 for (Object* current = this; true; current = current->GetPrototype()) { | 530 if (!result->IsHandler()) { |
| 505 if (current->IsAccessCheckNeeded()) { | 531 Object* last = result->IsProperty() ? result->holder() : heap->null_value(); |
| 506 // Check if we're allowed to read from the current object. Note | 532 ASSERT(this != this->GetPrototype()); |
| 507 // that even though we may not actually end up loading the named | 533 for (Object* current = this; true; current = current->GetPrototype()) { |
| 508 // property from the current object, we still check that we have | 534 if (current->IsAccessCheckNeeded()) { |
| 509 // access to it. | 535 // Check if we're allowed to read from the current object. Note |
| 510 JSObject* checked = JSObject::cast(current); | 536 // that even though we may not actually end up loading the named |
| 511 if (!heap->isolate()->MayNamedAccess(checked, name, v8::ACCESS_GET)) { | 537 // property from the current object, we still check that we have |
| 512 return checked->GetPropertyWithFailedAccessCheck(receiver, | 538 // access to it. |
| 513 result, | 539 JSObject* checked = JSObject::cast(current); |
| 514 name, | 540 if (!heap->isolate()->MayNamedAccess(checked, name, v8::ACCESS_GET)) { |
| 515 attributes); | 541 return checked->GetPropertyWithFailedAccessCheck(receiver, |
| 542 result, |
| 543 name, |
| 544 attributes); |
| 545 } |
| 516 } | 546 } |
| 547 // Stop traversing the chain once we reach the last object in the |
| 548 // chain; either the holder of the result or null in case of an |
| 549 // absent property. |
| 550 if (current == last) break; |
| 517 } | 551 } |
| 518 // Stop traversing the chain once we reach the last object in the | |
| 519 // chain; either the holder of the result or null in case of an | |
| 520 // absent property. | |
| 521 if (current == last) break; | |
| 522 } | 552 } |
| 523 | 553 |
| 524 if (!result->IsProperty()) { | 554 if (!result->IsProperty()) { |
| 525 *attributes = ABSENT; | 555 *attributes = ABSENT; |
| 526 return heap->undefined_value(); | 556 return heap->undefined_value(); |
| 527 } | 557 } |
| 528 *attributes = result->GetAttributes(); | 558 *attributes = result->GetAttributes(); |
| 529 Object* value; | 559 Object* value; |
| 530 JSObject* holder = result->holder(); | 560 JSObject* holder = result->holder(); |
| 531 switch (result->type()) { | 561 switch (result->type()) { |
| 532 case NORMAL: | 562 case NORMAL: |
| 533 value = holder->GetNormalizedProperty(result); | 563 value = holder->GetNormalizedProperty(result); |
| 534 ASSERT(!value->IsTheHole() || result->IsReadOnly()); | 564 ASSERT(!value->IsTheHole() || result->IsReadOnly()); |
| 535 return value->IsTheHole() ? heap->undefined_value() : value; | 565 return value->IsTheHole() ? heap->undefined_value() : value; |
| 536 case FIELD: | 566 case FIELD: |
| 537 value = holder->FastPropertyAt(result->GetFieldIndex()); | 567 value = holder->FastPropertyAt(result->GetFieldIndex()); |
| 538 ASSERT(!value->IsTheHole() || result->IsReadOnly()); | 568 ASSERT(!value->IsTheHole() || result->IsReadOnly()); |
| 539 return value->IsTheHole() ? heap->undefined_value() : value; | 569 return value->IsTheHole() ? heap->undefined_value() : value; |
| 540 case CONSTANT_FUNCTION: | 570 case CONSTANT_FUNCTION: |
| 541 return result->GetConstantFunction(); | 571 return result->GetConstantFunction(); |
| 542 case CALLBACKS: | 572 case CALLBACKS: |
| 543 return GetPropertyWithCallback(receiver, | 573 return GetPropertyWithCallback(receiver, |
| 544 result->GetCallbackObject(), | 574 result->GetCallbackObject(), |
| 545 name, | 575 name, |
| 546 holder); | 576 holder); |
| 577 case HANDLER: { |
| 578 JSProxy* proxy = JSProxy::cast(this); |
| 579 return GetPropertyWithHandler(receiver, name, proxy->handler()); |
| 580 } |
| 547 case INTERCEPTOR: { | 581 case INTERCEPTOR: { |
| 548 JSObject* recvr = JSObject::cast(receiver); | 582 JSObject* recvr = JSObject::cast(receiver); |
| 549 return holder->GetPropertyWithInterceptor(recvr, name, attributes); | 583 return holder->GetPropertyWithInterceptor(recvr, name, attributes); |
| 550 } | 584 } |
| 551 default: | 585 case MAP_TRANSITION: |
| 552 UNREACHABLE(); | 586 case EXTERNAL_ARRAY_TRANSITION: |
| 553 return NULL; | 587 case CONSTANT_TRANSITION: |
| 588 case NULL_DESCRIPTOR: |
| 589 break; |
| 554 } | 590 } |
| 591 UNREACHABLE(); |
| 592 return NULL; |
| 555 } | 593 } |
| 556 | 594 |
| 557 | 595 |
| 558 MaybeObject* Object::GetElementWithReceiver(Object* receiver, uint32_t index) { | 596 MaybeObject* Object::GetElementWithReceiver(Object* receiver, uint32_t index) { |
| 559 Object* holder = NULL; | 597 Object* holder = NULL; |
| 560 if (IsSmi()) { | 598 if (IsSmi()) { |
| 561 Context* global_context = Isolate::Current()->context()->global_context(); | 599 Context* global_context = Isolate::Current()->context()->global_context(); |
| 562 holder = global_context->number_function()->instance_prototype(); | 600 holder = global_context->number_function()->instance_prototype(); |
| 563 } else { | 601 } else { |
| 564 HeapObject* heap_object = HeapObject::cast(this); | 602 HeapObject* heap_object = HeapObject::cast(this); |
| 565 | 603 |
| 566 if (heap_object->IsJSObject()) { | 604 if (heap_object->IsJSObject()) { |
| 567 return JSObject::cast(this)->GetElementWithReceiver(receiver, index); | 605 return JSObject::cast(this)->GetElementWithReceiver(receiver, index); |
| 568 } | 606 } |
| 569 Heap* heap = heap_object->GetHeap(); | 607 Heap* heap = heap_object->GetHeap(); |
| 570 Isolate* isolate = heap->isolate(); | 608 Isolate* isolate = heap->isolate(); |
| 571 | 609 |
| 572 Context* global_context = isolate->context()->global_context(); | 610 Context* global_context = isolate->context()->global_context(); |
| 573 if (heap_object->IsString()) { | 611 if (heap_object->IsString()) { |
| 574 holder = global_context->string_function()->instance_prototype(); | 612 holder = global_context->string_function()->instance_prototype(); |
| 575 } else if (heap_object->IsHeapNumber()) { | 613 } else if (heap_object->IsHeapNumber()) { |
| 576 holder = global_context->number_function()->instance_prototype(); | 614 holder = global_context->number_function()->instance_prototype(); |
| 577 } else if (heap_object->IsBoolean()) { | 615 } else if (heap_object->IsBoolean()) { |
| 578 holder = global_context->boolean_function()->instance_prototype(); | 616 holder = global_context->boolean_function()->instance_prototype(); |
| 617 } else if (heap_object->IsJSProxy()) { |
| 618 return heap->undefined_value(); // For now... |
| 579 } else { | 619 } else { |
| 580 // Undefined and null have no indexed properties. | 620 // Undefined and null have no indexed properties. |
| 581 ASSERT(heap_object->IsUndefined() || heap_object->IsNull()); | 621 ASSERT(heap_object->IsUndefined() || heap_object->IsNull()); |
| 582 return heap->undefined_value(); | 622 return heap->undefined_value(); |
| 583 } | 623 } |
| 584 } | 624 } |
| 585 | 625 |
| 586 return JSObject::cast(holder)->GetElementWithReceiver(receiver, index); | 626 return JSObject::cast(holder)->GetElementWithReceiver(receiver, index); |
| 587 } | 627 } |
| 588 | 628 |
| 589 | 629 |
| 590 Object* Object::GetPrototype() { | 630 Object* Object::GetPrototype() { |
| 591 if (IsSmi()) { | 631 if (IsSmi()) { |
| 592 Heap* heap = Isolate::Current()->heap(); | 632 Heap* heap = Isolate::Current()->heap(); |
| 593 Context* context = heap->isolate()->context()->global_context(); | 633 Context* context = heap->isolate()->context()->global_context(); |
| 594 return context->number_function()->instance_prototype(); | 634 return context->number_function()->instance_prototype(); |
| 595 } | 635 } |
| 596 | 636 |
| 597 HeapObject* heap_object = HeapObject::cast(this); | 637 HeapObject* heap_object = HeapObject::cast(this); |
| 598 | 638 |
| 599 // The object is either a number, a string, a boolean, or a real JS object. | 639 // The object is either a number, a string, a boolean, |
| 600 if (heap_object->IsJSObject()) { | 640 // a real JS object, or a Harmony proxy. |
| 601 return JSObject::cast(this)->map()->prototype(); | 641 if (heap_object->IsJSObject() || heap_object->IsJSProxy()) { |
| 642 return heap_object->map()->prototype(); |
| 602 } | 643 } |
| 603 Heap* heap = heap_object->GetHeap(); | 644 Heap* heap = heap_object->GetHeap(); |
| 604 Context* context = heap->isolate()->context()->global_context(); | 645 Context* context = heap->isolate()->context()->global_context(); |
| 605 | 646 |
| 606 if (heap_object->IsHeapNumber()) { | 647 if (heap_object->IsHeapNumber()) { |
| 607 return context->number_function()->instance_prototype(); | 648 return context->number_function()->instance_prototype(); |
| 608 } | 649 } |
| 609 if (heap_object->IsString()) { | 650 if (heap_object->IsString()) { |
| 610 return context->string_function()->instance_prototype(); | 651 return context->string_function()->instance_prototype(); |
| 611 } | 652 } |
| (...skipping 539 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1151 case JS_MESSAGE_OBJECT_TYPE: | 1192 case JS_MESSAGE_OBJECT_TYPE: |
| 1152 JSObject::BodyDescriptor::IterateBody(this, object_size, v); | 1193 JSObject::BodyDescriptor::IterateBody(this, object_size, v); |
| 1153 break; | 1194 break; |
| 1154 case JS_FUNCTION_TYPE: | 1195 case JS_FUNCTION_TYPE: |
| 1155 reinterpret_cast<JSFunction*>(this) | 1196 reinterpret_cast<JSFunction*>(this) |
| 1156 ->JSFunctionIterateBody(object_size, v); | 1197 ->JSFunctionIterateBody(object_size, v); |
| 1157 break; | 1198 break; |
| 1158 case ODDBALL_TYPE: | 1199 case ODDBALL_TYPE: |
| 1159 Oddball::BodyDescriptor::IterateBody(this, v); | 1200 Oddball::BodyDescriptor::IterateBody(this, v); |
| 1160 break; | 1201 break; |
| 1202 case JS_PROXY_TYPE: |
| 1203 JSProxy::BodyDescriptor::IterateBody(this, v); |
| 1204 break; |
| 1161 case PROXY_TYPE: | 1205 case PROXY_TYPE: |
| 1162 reinterpret_cast<Proxy*>(this)->ProxyIterateBody(v); | 1206 reinterpret_cast<Proxy*>(this)->ProxyIterateBody(v); |
| 1163 break; | 1207 break; |
| 1164 case MAP_TYPE: | 1208 case MAP_TYPE: |
| 1165 Map::BodyDescriptor::IterateBody(this, v); | 1209 Map::BodyDescriptor::IterateBody(this, v); |
| 1166 break; | 1210 break; |
| 1167 case CODE_TYPE: | 1211 case CODE_TYPE: |
| 1168 reinterpret_cast<Code*>(this)->CodeIterateBody(v); | 1212 reinterpret_cast<Code*>(this)->CodeIterateBody(v); |
| 1169 break; | 1213 break; |
| 1170 case JS_GLOBAL_PROPERTY_CELL_TYPE: | 1214 case JS_GLOBAL_PROPERTY_CELL_TYPE: |
| (...skipping 1408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2579 dictionary->Add(descs->GetKey(i), value, d); | 2623 dictionary->Add(descs->GetKey(i), value, d); |
| 2580 if (!maybe_result->ToObject(&result)) return maybe_result; | 2624 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 2581 } | 2625 } |
| 2582 dictionary = StringDictionary::cast(result); | 2626 dictionary = StringDictionary::cast(result); |
| 2583 break; | 2627 break; |
| 2584 } | 2628 } |
| 2585 case MAP_TRANSITION: | 2629 case MAP_TRANSITION: |
| 2586 case CONSTANT_TRANSITION: | 2630 case CONSTANT_TRANSITION: |
| 2587 case NULL_DESCRIPTOR: | 2631 case NULL_DESCRIPTOR: |
| 2588 case INTERCEPTOR: | 2632 case INTERCEPTOR: |
| 2633 case EXTERNAL_ARRAY_TRANSITION: |
| 2589 break; | 2634 break; |
| 2590 default: | 2635 default: |
| 2591 UNREACHABLE(); | 2636 UNREACHABLE(); |
| 2592 } | 2637 } |
| 2593 } | 2638 } |
| 2594 | 2639 |
| 2595 Heap* current_heap = GetHeap(); | 2640 Heap* current_heap = GetHeap(); |
| 2596 | 2641 |
| 2597 // Copy the next enumeration index from instance descriptor. | 2642 // Copy the next enumeration index from instance descriptor. |
| 2598 int index = map_of_this->instance_descriptors()->NextEnumerationIndex(); | 2643 int index = map_of_this->instance_descriptors()->NextEnumerationIndex(); |
| (...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2865 NumberDictionary* dictionary = element_dictionary(); | 2910 NumberDictionary* dictionary = element_dictionary(); |
| 2866 int entry = dictionary->FindEntry(index); | 2911 int entry = dictionary->FindEntry(index); |
| 2867 if (entry != NumberDictionary::kNotFound) { | 2912 if (entry != NumberDictionary::kNotFound) { |
| 2868 Object* result = dictionary->DeleteProperty(entry, mode); | 2913 Object* result = dictionary->DeleteProperty(entry, mode); |
| 2869 if (mode == STRICT_DELETION && result == | 2914 if (mode == STRICT_DELETION && result == |
| 2870 isolate->heap()->false_value()) { | 2915 isolate->heap()->false_value()) { |
| 2871 // In strict mode, deleting a non-configurable property throws | 2916 // In strict mode, deleting a non-configurable property throws |
| 2872 // exception. dictionary->DeleteProperty will return false_value() | 2917 // exception. dictionary->DeleteProperty will return false_value() |
| 2873 // if a non-configurable property is being deleted. | 2918 // if a non-configurable property is being deleted. |
| 2874 HandleScope scope; | 2919 HandleScope scope; |
| 2920 Handle<Object> self(this); |
| 2875 Handle<Object> i = isolate->factory()->NewNumberFromUint(index); | 2921 Handle<Object> i = isolate->factory()->NewNumberFromUint(index); |
| 2876 Handle<Object> args[2] = { i, Handle<Object>(this) }; | 2922 Handle<Object> args[2] = { i, self }; |
| 2877 return isolate->Throw(*isolate->factory()->NewTypeError( | 2923 return isolate->Throw(*isolate->factory()->NewTypeError( |
| 2878 "strict_delete_property", HandleVector(args, 2))); | 2924 "strict_delete_property", HandleVector(args, 2))); |
| 2879 } | 2925 } |
| 2880 } | 2926 } |
| 2881 break; | 2927 break; |
| 2882 } | 2928 } |
| 2883 default: | 2929 default: |
| 2884 UNREACHABLE(); | 2930 UNREACHABLE(); |
| 2885 break; | 2931 break; |
| 2886 } | 2932 } |
| (...skipping 874 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3761 *map_or_index_field = GetHeap()->fixed_array_map(); | 3807 *map_or_index_field = GetHeap()->fixed_array_map(); |
| 3762 Map* prev = current->map(); | 3808 Map* prev = current->map(); |
| 3763 current->set_map(meta_map); | 3809 current->set_map(meta_map); |
| 3764 callback(current, data); | 3810 callback(current, data); |
| 3765 current = prev; | 3811 current = prev; |
| 3766 } | 3812 } |
| 3767 } | 3813 } |
| 3768 | 3814 |
| 3769 | 3815 |
| 3770 MaybeObject* CodeCache::Update(String* name, Code* code) { | 3816 MaybeObject* CodeCache::Update(String* name, Code* code) { |
| 3771 ASSERT(code->ic_state() == MONOMORPHIC); | |
| 3772 | |
| 3773 // The number of monomorphic stubs for normal load/store/call IC's can grow to | 3817 // The number of monomorphic stubs for normal load/store/call IC's can grow to |
| 3774 // a large number and therefore they need to go into a hash table. They are | 3818 // a large number and therefore they need to go into a hash table. They are |
| 3775 // used to load global properties from cells. | 3819 // used to load global properties from cells. |
| 3776 if (code->type() == NORMAL) { | 3820 if (code->type() == NORMAL) { |
| 3777 // Make sure that a hash table is allocated for the normal load code cache. | 3821 // Make sure that a hash table is allocated for the normal load code cache. |
| 3778 if (normal_type_cache()->IsUndefined()) { | 3822 if (normal_type_cache()->IsUndefined()) { |
| 3779 Object* result; | 3823 Object* result; |
| 3780 { MaybeObject* maybe_result = | 3824 { MaybeObject* maybe_result = |
| 3781 CodeCacheHashTable::Allocate(CodeCacheHashTable::kInitialSize); | 3825 CodeCacheHashTable::Allocate(CodeCacheHashTable::kInitialSize); |
| 3782 if (!maybe_result->ToObject(&result)) return maybe_result; | 3826 if (!maybe_result->ToObject(&result)) return maybe_result; |
| (...skipping 1172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4955 } | 4999 } |
| 4956 | 5000 |
| 4957 | 5001 |
| 4958 // Reserve space for statics needing saving and restoring. | 5002 // Reserve space for statics needing saving and restoring. |
| 4959 int Relocatable::ArchiveSpacePerThread() { | 5003 int Relocatable::ArchiveSpacePerThread() { |
| 4960 return sizeof(Isolate::Current()->relocatable_top()); | 5004 return sizeof(Isolate::Current()->relocatable_top()); |
| 4961 } | 5005 } |
| 4962 | 5006 |
| 4963 | 5007 |
| 4964 // Archive statics that are thread local. | 5008 // Archive statics that are thread local. |
| 4965 char* Relocatable::ArchiveState(char* to) { | 5009 char* Relocatable::ArchiveState(Isolate* isolate, char* to) { |
| 4966 Isolate* isolate = Isolate::Current(); | |
| 4967 *reinterpret_cast<Relocatable**>(to) = isolate->relocatable_top(); | 5010 *reinterpret_cast<Relocatable**>(to) = isolate->relocatable_top(); |
| 4968 isolate->set_relocatable_top(NULL); | 5011 isolate->set_relocatable_top(NULL); |
| 4969 return to + ArchiveSpacePerThread(); | 5012 return to + ArchiveSpacePerThread(); |
| 4970 } | 5013 } |
| 4971 | 5014 |
| 4972 | 5015 |
| 4973 // Restore statics that are thread local. | 5016 // Restore statics that are thread local. |
| 4974 char* Relocatable::RestoreState(char* from) { | 5017 char* Relocatable::RestoreState(Isolate* isolate, char* from) { |
| 4975 Isolate* isolate = Isolate::Current(); | |
| 4976 isolate->set_relocatable_top(*reinterpret_cast<Relocatable**>(from)); | 5018 isolate->set_relocatable_top(*reinterpret_cast<Relocatable**>(from)); |
| 4977 return from + ArchiveSpacePerThread(); | 5019 return from + ArchiveSpacePerThread(); |
| 4978 } | 5020 } |
| 4979 | 5021 |
| 4980 | 5022 |
| 4981 char* Relocatable::Iterate(ObjectVisitor* v, char* thread_storage) { | 5023 char* Relocatable::Iterate(ObjectVisitor* v, char* thread_storage) { |
| 4982 Relocatable* top = *reinterpret_cast<Relocatable**>(thread_storage); | 5024 Relocatable* top = *reinterpret_cast<Relocatable**>(thread_storage); |
| 4983 Iterate(v, top); | 5025 Iterate(v, top); |
| 4984 return thread_storage + ArchiveSpacePerThread(); | 5026 return thread_storage + ArchiveSpacePerThread(); |
| 4985 } | 5027 } |
| (...skipping 1523 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6509 | 6551 |
| 6510 // Identify kind of code. | 6552 // Identify kind of code. |
| 6511 const char* Code::Kind2String(Kind kind) { | 6553 const char* Code::Kind2String(Kind kind) { |
| 6512 switch (kind) { | 6554 switch (kind) { |
| 6513 case FUNCTION: return "FUNCTION"; | 6555 case FUNCTION: return "FUNCTION"; |
| 6514 case OPTIMIZED_FUNCTION: return "OPTIMIZED_FUNCTION"; | 6556 case OPTIMIZED_FUNCTION: return "OPTIMIZED_FUNCTION"; |
| 6515 case STUB: return "STUB"; | 6557 case STUB: return "STUB"; |
| 6516 case BUILTIN: return "BUILTIN"; | 6558 case BUILTIN: return "BUILTIN"; |
| 6517 case LOAD_IC: return "LOAD_IC"; | 6559 case LOAD_IC: return "LOAD_IC"; |
| 6518 case KEYED_LOAD_IC: return "KEYED_LOAD_IC"; | 6560 case KEYED_LOAD_IC: return "KEYED_LOAD_IC"; |
| 6519 case KEYED_EXTERNAL_ARRAY_LOAD_IC: return "KEYED_EXTERNAL_ARRAY_LOAD_IC"; | |
| 6520 case STORE_IC: return "STORE_IC"; | 6561 case STORE_IC: return "STORE_IC"; |
| 6521 case KEYED_STORE_IC: return "KEYED_STORE_IC"; | 6562 case KEYED_STORE_IC: return "KEYED_STORE_IC"; |
| 6522 case KEYED_EXTERNAL_ARRAY_STORE_IC: return "KEYED_EXTERNAL_ARRAY_STORE_IC"; | |
| 6523 case CALL_IC: return "CALL_IC"; | 6563 case CALL_IC: return "CALL_IC"; |
| 6524 case KEYED_CALL_IC: return "KEYED_CALL_IC"; | 6564 case KEYED_CALL_IC: return "KEYED_CALL_IC"; |
| 6525 case TYPE_RECORDING_UNARY_OP_IC: return "TYPE_RECORDING_UNARY_OP_IC"; | 6565 case TYPE_RECORDING_UNARY_OP_IC: return "TYPE_RECORDING_UNARY_OP_IC"; |
| 6526 case TYPE_RECORDING_BINARY_OP_IC: return "TYPE_RECORDING_BINARY_OP_IC"; | 6566 case TYPE_RECORDING_BINARY_OP_IC: return "TYPE_RECORDING_BINARY_OP_IC"; |
| 6527 case COMPARE_IC: return "COMPARE_IC"; | 6567 case COMPARE_IC: return "COMPARE_IC"; |
| 6528 } | 6568 } |
| 6529 UNREACHABLE(); | 6569 UNREACHABLE(); |
| 6530 return NULL; | 6570 return NULL; |
| 6531 } | 6571 } |
| 6532 | 6572 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 6545 return NULL; | 6585 return NULL; |
| 6546 } | 6586 } |
| 6547 | 6587 |
| 6548 | 6588 |
| 6549 const char* Code::PropertyType2String(PropertyType type) { | 6589 const char* Code::PropertyType2String(PropertyType type) { |
| 6550 switch (type) { | 6590 switch (type) { |
| 6551 case NORMAL: return "NORMAL"; | 6591 case NORMAL: return "NORMAL"; |
| 6552 case FIELD: return "FIELD"; | 6592 case FIELD: return "FIELD"; |
| 6553 case CONSTANT_FUNCTION: return "CONSTANT_FUNCTION"; | 6593 case CONSTANT_FUNCTION: return "CONSTANT_FUNCTION"; |
| 6554 case CALLBACKS: return "CALLBACKS"; | 6594 case CALLBACKS: return "CALLBACKS"; |
| 6595 case HANDLER: return "HANDLER"; |
| 6555 case INTERCEPTOR: return "INTERCEPTOR"; | 6596 case INTERCEPTOR: return "INTERCEPTOR"; |
| 6556 case MAP_TRANSITION: return "MAP_TRANSITION"; | 6597 case MAP_TRANSITION: return "MAP_TRANSITION"; |
| 6557 case EXTERNAL_ARRAY_TRANSITION: return "EXTERNAL_ARRAY_TRANSITION"; | 6598 case EXTERNAL_ARRAY_TRANSITION: return "EXTERNAL_ARRAY_TRANSITION"; |
| 6558 case CONSTANT_TRANSITION: return "CONSTANT_TRANSITION"; | 6599 case CONSTANT_TRANSITION: return "CONSTANT_TRANSITION"; |
| 6559 case NULL_DESCRIPTOR: return "NULL_DESCRIPTOR"; | 6600 case NULL_DESCRIPTOR: return "NULL_DESCRIPTOR"; |
| 6560 } | 6601 } |
| 6561 UNREACHABLE(); | 6602 UNREACHABLE(); |
| 6562 return NULL; | 6603 return NULL; |
| 6563 } | 6604 } |
| 6564 | 6605 |
| (...skipping 723 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7288 | 7329 |
| 7289 MaybeObject* JSObject::GetElementWithCallback(Object* receiver, | 7330 MaybeObject* JSObject::GetElementWithCallback(Object* receiver, |
| 7290 Object* structure, | 7331 Object* structure, |
| 7291 uint32_t index, | 7332 uint32_t index, |
| 7292 Object* holder) { | 7333 Object* holder) { |
| 7293 Isolate* isolate = GetIsolate(); | 7334 Isolate* isolate = GetIsolate(); |
| 7294 ASSERT(!structure->IsProxy()); | 7335 ASSERT(!structure->IsProxy()); |
| 7295 | 7336 |
| 7296 // api style callbacks. | 7337 // api style callbacks. |
| 7297 if (structure->IsAccessorInfo()) { | 7338 if (structure->IsAccessorInfo()) { |
| 7298 AccessorInfo* data = AccessorInfo::cast(structure); | 7339 Handle<AccessorInfo> data(AccessorInfo::cast(structure)); |
| 7299 Object* fun_obj = data->getter(); | 7340 Object* fun_obj = data->getter(); |
| 7300 v8::AccessorGetter call_fun = v8::ToCData<v8::AccessorGetter>(fun_obj); | 7341 v8::AccessorGetter call_fun = v8::ToCData<v8::AccessorGetter>(fun_obj); |
| 7301 HandleScope scope(isolate); | 7342 HandleScope scope(isolate); |
| 7302 Handle<JSObject> self(JSObject::cast(receiver)); | 7343 Handle<JSObject> self(JSObject::cast(receiver)); |
| 7303 Handle<JSObject> holder_handle(JSObject::cast(holder)); | 7344 Handle<JSObject> holder_handle(JSObject::cast(holder)); |
| 7304 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); | 7345 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); |
| 7305 Handle<String> key(isolate->factory()->NumberToString(number)); | 7346 Handle<String> key(isolate->factory()->NumberToString(number)); |
| 7306 LOG(isolate, ApiNamedPropertyAccess("load", *self, *key)); | 7347 LOG(isolate, ApiNamedPropertyAccess("load", *self, *key)); |
| 7307 CustomArguments args(isolate, data->data(), *self, *holder_handle); | 7348 CustomArguments args(isolate, data->data(), *self, *holder_handle); |
| 7308 v8::AccessorInfo info(args.end()); | 7349 v8::AccessorInfo info(args.end()); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7345 ASSERT(!value->IsTheHole()); | 7386 ASSERT(!value->IsTheHole()); |
| 7346 Handle<Object> value_handle(value, isolate); | 7387 Handle<Object> value_handle(value, isolate); |
| 7347 | 7388 |
| 7348 // To accommodate both the old and the new api we switch on the | 7389 // To accommodate both the old and the new api we switch on the |
| 7349 // data structure used to store the callbacks. Eventually proxy | 7390 // data structure used to store the callbacks. Eventually proxy |
| 7350 // callbacks should be phased out. | 7391 // callbacks should be phased out. |
| 7351 ASSERT(!structure->IsProxy()); | 7392 ASSERT(!structure->IsProxy()); |
| 7352 | 7393 |
| 7353 if (structure->IsAccessorInfo()) { | 7394 if (structure->IsAccessorInfo()) { |
| 7354 // api style callbacks | 7395 // api style callbacks |
| 7355 AccessorInfo* data = AccessorInfo::cast(structure); | 7396 Handle<JSObject> self(this); |
| 7397 Handle<JSObject> holder_handle(JSObject::cast(holder)); |
| 7398 Handle<AccessorInfo> data(AccessorInfo::cast(structure)); |
| 7356 Object* call_obj = data->setter(); | 7399 Object* call_obj = data->setter(); |
| 7357 v8::AccessorSetter call_fun = v8::ToCData<v8::AccessorSetter>(call_obj); | 7400 v8::AccessorSetter call_fun = v8::ToCData<v8::AccessorSetter>(call_obj); |
| 7358 if (call_fun == NULL) return value; | 7401 if (call_fun == NULL) return value; |
| 7359 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); | 7402 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); |
| 7360 Handle<String> key(isolate->factory()->NumberToString(number)); | 7403 Handle<String> key(isolate->factory()->NumberToString(number)); |
| 7361 LOG(isolate, ApiNamedPropertyAccess("store", this, *key)); | 7404 LOG(isolate, ApiNamedPropertyAccess("store", *self, *key)); |
| 7362 CustomArguments args(isolate, data->data(), this, JSObject::cast(holder)); | 7405 CustomArguments args(isolate, data->data(), *self, *holder_handle); |
| 7363 v8::AccessorInfo info(args.end()); | 7406 v8::AccessorInfo info(args.end()); |
| 7364 { | 7407 { |
| 7365 // Leaving JavaScript. | 7408 // Leaving JavaScript. |
| 7366 VMState state(isolate, EXTERNAL); | 7409 VMState state(isolate, EXTERNAL); |
| 7367 call_fun(v8::Utils::ToLocal(key), | 7410 call_fun(v8::Utils::ToLocal(key), |
| 7368 v8::Utils::ToLocal(value_handle), | 7411 v8::Utils::ToLocal(value_handle), |
| 7369 info); | 7412 info); |
| 7370 } | 7413 } |
| 7371 RETURN_IF_SCHEDULED_EXCEPTION(isolate); | 7414 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 7372 return *value_handle; | 7415 return *value_handle; |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7554 if (entry != NumberDictionary::kNotFound) { | 7597 if (entry != NumberDictionary::kNotFound) { |
| 7555 Object* element = dictionary->ValueAt(entry); | 7598 Object* element = dictionary->ValueAt(entry); |
| 7556 PropertyDetails details = dictionary->DetailsAt(entry); | 7599 PropertyDetails details = dictionary->DetailsAt(entry); |
| 7557 if (details.type() == CALLBACKS) { | 7600 if (details.type() == CALLBACKS) { |
| 7558 return SetElementWithCallback(element, index, value, this); | 7601 return SetElementWithCallback(element, index, value, this); |
| 7559 } else { | 7602 } else { |
| 7560 dictionary->UpdateMaxNumberKey(index); | 7603 dictionary->UpdateMaxNumberKey(index); |
| 7561 // If put fails instrict mode, throw exception. | 7604 // If put fails instrict mode, throw exception. |
| 7562 if (!dictionary->ValueAtPut(entry, value) && | 7605 if (!dictionary->ValueAtPut(entry, value) && |
| 7563 strict_mode == kStrictMode) { | 7606 strict_mode == kStrictMode) { |
| 7607 Handle<Object> holder(this); |
| 7564 Handle<Object> number(isolate->factory()->NewNumberFromUint(index)); | 7608 Handle<Object> number(isolate->factory()->NewNumberFromUint(index)); |
| 7565 Handle<Object> holder(this); | |
| 7566 Handle<Object> args[2] = { number, holder }; | 7609 Handle<Object> args[2] = { number, holder }; |
| 7567 return isolate->Throw( | 7610 return isolate->Throw( |
| 7568 *isolate->factory()->NewTypeError("strict_read_only_property", | 7611 *isolate->factory()->NewTypeError("strict_read_only_property", |
| 7569 HandleVector(args, 2))); | 7612 HandleVector(args, 2))); |
| 7570 } | 7613 } |
| 7571 } | 7614 } |
| 7572 } else { | 7615 } else { |
| 7573 // Index not already used. Look for an accessor in the prototype chain. | 7616 // Index not already used. Look for an accessor in the prototype chain. |
| 7574 if (check_prototype) { | 7617 if (check_prototype) { |
| 7575 bool found; | 7618 bool found; |
| (...skipping 2854 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10430 if (break_point_objects()->IsUndefined()) return 0; | 10473 if (break_point_objects()->IsUndefined()) return 0; |
| 10431 // Single beak point. | 10474 // Single beak point. |
| 10432 if (!break_point_objects()->IsFixedArray()) return 1; | 10475 if (!break_point_objects()->IsFixedArray()) return 1; |
| 10433 // Multiple break points. | 10476 // Multiple break points. |
| 10434 return FixedArray::cast(break_point_objects())->length(); | 10477 return FixedArray::cast(break_point_objects())->length(); |
| 10435 } | 10478 } |
| 10436 #endif | 10479 #endif |
| 10437 | 10480 |
| 10438 | 10481 |
| 10439 } } // namespace v8::internal | 10482 } } // namespace v8::internal |
| OLD | NEW |