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 2151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2162 ASSERT(context->IsFunctionContext()); | 2162 ASSERT(context->IsFunctionContext()); |
2163 object = isolate->factory()->NewJSObject( | 2163 object = isolate->factory()->NewJSObject( |
2164 isolate->context_extension_function()); | 2164 isolate->context_extension_function()); |
2165 context->set_extension(*object); | 2165 context->set_extension(*object); |
2166 } | 2166 } |
2167 ASSERT(*object != NULL); | 2167 ASSERT(*object != NULL); |
2168 | 2168 |
2169 // Declare the property by setting it to the initial value if provided, | 2169 // Declare the property by setting it to the initial value if provided, |
2170 // or undefined, and use the correct mode (e.g. READ_ONLY attribute for | 2170 // or undefined, and use the correct mode (e.g. READ_ONLY attribute for |
2171 // constant declarations). | 2171 // constant declarations). |
2172 ASSERT(!object->HasLocalProperty(*name)); | 2172 ASSERT(!JSReceiver::HasLocalProperty(object, name)); |
2173 Handle<Object> value(isolate->heap()->undefined_value(), isolate); | 2173 Handle<Object> value(isolate->heap()->undefined_value(), isolate); |
2174 if (*initial_value != NULL) value = initial_value; | 2174 if (*initial_value != NULL) value = initial_value; |
2175 // Declaring a const context slot is a conflicting declaration if | 2175 // Declaring a const context slot is a conflicting declaration if |
2176 // there is a callback with that name in a prototype. It is | 2176 // there is a callback with that name in a prototype. It is |
2177 // allowed to introduce const variables in | 2177 // allowed to introduce const variables in |
2178 // JSContextExtensionObjects. They are treated specially in | 2178 // JSContextExtensionObjects. They are treated specially in |
2179 // SetProperty and no setters are invoked for those since they are | 2179 // SetProperty and no setters are invoked for those since they are |
2180 // not real JSObjects. | 2180 // not real JSObjects. |
2181 if (initial_value->IsTheHole() && | 2181 if (initial_value->IsTheHole() && |
2182 !object->IsJSContextExtensionObject()) { | 2182 !object->IsJSContextExtensionObject()) { |
(...skipping 2597 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4780 | 4780 |
4781 | 4781 |
4782 MaybeObject* Runtime::HasObjectProperty(Isolate* isolate, | 4782 MaybeObject* Runtime::HasObjectProperty(Isolate* isolate, |
4783 Handle<JSReceiver> object, | 4783 Handle<JSReceiver> object, |
4784 Handle<Object> key) { | 4784 Handle<Object> key) { |
4785 HandleScope scope(isolate); | 4785 HandleScope scope(isolate); |
4786 | 4786 |
4787 // Check if the given key is an array index. | 4787 // Check if the given key is an array index. |
4788 uint32_t index; | 4788 uint32_t index; |
4789 if (key->ToArrayIndex(&index)) { | 4789 if (key->ToArrayIndex(&index)) { |
4790 return isolate->heap()->ToBoolean(object->HasElement(index)); | 4790 return isolate->heap()->ToBoolean(JSReceiver::HasElement(object, index)); |
4791 } | 4791 } |
4792 | 4792 |
4793 // Convert the key to a name - possibly by calling back into JavaScript. | 4793 // Convert the key to a name - possibly by calling back into JavaScript. |
4794 Handle<Name> name; | 4794 Handle<Name> name; |
4795 if (key->IsName()) { | 4795 if (key->IsName()) { |
4796 name = Handle<Name>::cast(key); | 4796 name = Handle<Name>::cast(key); |
4797 } else { | 4797 } else { |
4798 bool has_pending_exception = false; | 4798 bool has_pending_exception = false; |
4799 Handle<Object> converted = | 4799 Handle<Object> converted = |
4800 Execution::ToString(isolate, key, &has_pending_exception); | 4800 Execution::ToString(isolate, key, &has_pending_exception); |
4801 if (has_pending_exception) return Failure::Exception(); | 4801 if (has_pending_exception) return Failure::Exception(); |
4802 name = Handle<Name>::cast(converted); | 4802 name = Handle<Name>::cast(converted); |
4803 } | 4803 } |
4804 | 4804 |
4805 return isolate->heap()->ToBoolean(object->HasProperty(*name)); | 4805 return isolate->heap()->ToBoolean(JSReceiver::HasProperty(object, name)); |
4806 } | 4806 } |
4807 | 4807 |
4808 MaybeObject* Runtime::GetObjectPropertyOrFail( | 4808 MaybeObject* Runtime::GetObjectPropertyOrFail( |
4809 Isolate* isolate, | 4809 Isolate* isolate, |
4810 Handle<Object> object, | 4810 Handle<Object> object, |
4811 Handle<Object> key) { | 4811 Handle<Object> key) { |
4812 CALL_HEAP_FUNCTION_PASS_EXCEPTION(isolate, | 4812 CALL_HEAP_FUNCTION_PASS_EXCEPTION(isolate, |
4813 GetObjectProperty(isolate, object, key)); | 4813 GetObjectProperty(isolate, object, key)); |
4814 } | 4814 } |
4815 | 4815 |
(...skipping 701 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5517 ? JSReceiver::STRICT_DELETION : JSReceiver::NORMAL_DELETION; | 5517 ? JSReceiver::STRICT_DELETION : JSReceiver::NORMAL_DELETION; |
5518 Handle<Object> result = JSReceiver::DeleteProperty(object, key, delete_mode); | 5518 Handle<Object> result = JSReceiver::DeleteProperty(object, key, delete_mode); |
5519 RETURN_IF_EMPTY_HANDLE(isolate, result); | 5519 RETURN_IF_EMPTY_HANDLE(isolate, result); |
5520 return *result; | 5520 return *result; |
5521 } | 5521 } |
5522 | 5522 |
5523 | 5523 |
5524 static MaybeObject* HasLocalPropertyImplementation(Isolate* isolate, | 5524 static MaybeObject* HasLocalPropertyImplementation(Isolate* isolate, |
5525 Handle<JSObject> object, | 5525 Handle<JSObject> object, |
5526 Handle<Name> key) { | 5526 Handle<Name> key) { |
5527 if (object->HasLocalProperty(*key)) return isolate->heap()->true_value(); | 5527 if (JSReceiver::HasLocalProperty(object, key)) { |
| 5528 return isolate->heap()->true_value(); |
| 5529 } |
5528 // Handle hidden prototypes. If there's a hidden prototype above this thing | 5530 // Handle hidden prototypes. If there's a hidden prototype above this thing |
5529 // then we have to check it for properties, because they are supposed to | 5531 // then we have to check it for properties, because they are supposed to |
5530 // look like they are on this object. | 5532 // look like they are on this object. |
5531 Handle<Object> proto(object->GetPrototype(), isolate); | 5533 Handle<Object> proto(object->GetPrototype(), isolate); |
5532 if (proto->IsJSObject() && | 5534 if (proto->IsJSObject() && |
5533 Handle<JSObject>::cast(proto)->map()->is_hidden_prototype()) { | 5535 Handle<JSObject>::cast(proto)->map()->is_hidden_prototype()) { |
5534 return HasLocalPropertyImplementation(isolate, | 5536 return HasLocalPropertyImplementation(isolate, |
5535 Handle<JSObject>::cast(proto), | 5537 Handle<JSObject>::cast(proto), |
5536 key); | 5538 key); |
5537 } | 5539 } |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5577 String* string = String::cast(obj); | 5579 String* string = String::cast(obj); |
5578 if (index < static_cast<uint32_t>(string->length())) { | 5580 if (index < static_cast<uint32_t>(string->length())) { |
5579 return isolate->heap()->true_value(); | 5581 return isolate->heap()->true_value(); |
5580 } | 5582 } |
5581 } | 5583 } |
5582 return isolate->heap()->false_value(); | 5584 return isolate->heap()->false_value(); |
5583 } | 5585 } |
5584 | 5586 |
5585 | 5587 |
5586 RUNTIME_FUNCTION(MaybeObject*, Runtime_HasProperty) { | 5588 RUNTIME_FUNCTION(MaybeObject*, Runtime_HasProperty) { |
5587 SealHandleScope shs(isolate); | 5589 HandleScope scope(isolate); |
5588 ASSERT(args.length() == 2); | 5590 ASSERT(args.length() == 2); |
5589 CONVERT_ARG_CHECKED(JSReceiver, receiver, 0); | 5591 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0); |
5590 CONVERT_ARG_CHECKED(Name, key, 1); | 5592 CONVERT_ARG_HANDLE_CHECKED(Name, key, 1); |
5591 | 5593 |
5592 bool result = receiver->HasProperty(key); | 5594 bool result = JSReceiver::HasProperty(receiver, key); |
5593 RETURN_IF_SCHEDULED_EXCEPTION(isolate); | 5595 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
5594 if (isolate->has_pending_exception()) return Failure::Exception(); | 5596 if (isolate->has_pending_exception()) return Failure::Exception(); |
5595 return isolate->heap()->ToBoolean(result); | 5597 return isolate->heap()->ToBoolean(result); |
5596 } | 5598 } |
5597 | 5599 |
5598 | 5600 |
5599 RUNTIME_FUNCTION(MaybeObject*, Runtime_HasElement) { | 5601 RUNTIME_FUNCTION(MaybeObject*, Runtime_HasElement) { |
5600 SealHandleScope shs(isolate); | 5602 HandleScope scope(isolate); |
5601 ASSERT(args.length() == 2); | 5603 ASSERT(args.length() == 2); |
5602 CONVERT_ARG_CHECKED(JSReceiver, receiver, 0); | 5604 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0); |
5603 CONVERT_SMI_ARG_CHECKED(index, 1); | 5605 CONVERT_SMI_ARG_CHECKED(index, 1); |
5604 | 5606 |
5605 bool result = receiver->HasElement(index); | 5607 bool result = JSReceiver::HasElement(receiver, index); |
5606 RETURN_IF_SCHEDULED_EXCEPTION(isolate); | 5608 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
5607 if (isolate->has_pending_exception()) return Failure::Exception(); | 5609 if (isolate->has_pending_exception()) return Failure::Exception(); |
5608 return isolate->heap()->ToBoolean(result); | 5610 return isolate->heap()->ToBoolean(result); |
5609 } | 5611 } |
5610 | 5612 |
5611 | 5613 |
5612 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsPropertyEnumerable) { | 5614 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsPropertyEnumerable) { |
5613 SealHandleScope shs(isolate); | 5615 SealHandleScope shs(isolate); |
5614 ASSERT(args.length() == 2); | 5616 ASSERT(args.length() == 2); |
5615 | 5617 |
(...skipping 3590 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9206 UNREACHABLE(); | 9208 UNREACHABLE(); |
9207 return MakePair(NULL, NULL); | 9209 return MakePair(NULL, NULL); |
9208 } | 9210 } |
9209 } | 9211 } |
9210 | 9212 |
9211 // Otherwise, if the slot was found the holder is a context extension | 9213 // Otherwise, if the slot was found the holder is a context extension |
9212 // object, subject of a with, or a global object. We read the named | 9214 // object, subject of a with, or a global object. We read the named |
9213 // property from it. | 9215 // property from it. |
9214 if (!holder.is_null()) { | 9216 if (!holder.is_null()) { |
9215 Handle<JSReceiver> object = Handle<JSReceiver>::cast(holder); | 9217 Handle<JSReceiver> object = Handle<JSReceiver>::cast(holder); |
9216 ASSERT(object->IsJSProxy() || object->HasProperty(*name)); | 9218 ASSERT(object->IsJSProxy() || JSReceiver::HasProperty(object, name)); |
9217 // GetProperty below can cause GC. | 9219 // GetProperty below can cause GC. |
9218 Handle<Object> receiver_handle( | 9220 Handle<Object> receiver_handle( |
9219 object->IsGlobalObject() | 9221 object->IsGlobalObject() |
9220 ? GlobalObject::cast(*object)->global_receiver() | 9222 ? GlobalObject::cast(*object)->global_receiver() |
9221 : object->IsJSProxy() ? static_cast<Object*>(*object) | 9223 : object->IsJSProxy() ? static_cast<Object*>(*object) |
9222 : ComputeReceiverForNonGlobal(isolate, JSObject::cast(*object)), | 9224 : ComputeReceiverForNonGlobal(isolate, JSObject::cast(*object)), |
9223 isolate); | 9225 isolate); |
9224 | 9226 |
9225 // No need to unhole the value here. This is taken care of by the | 9227 // No need to unhole the value here. This is taken care of by the |
9226 // GetProperty function. | 9228 // GetProperty function. |
(...skipping 960 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10187 // Run through the elements FixedArray and use HasElement and GetElement | 10189 // Run through the elements FixedArray and use HasElement and GetElement |
10188 // to check the prototype for missing elements. | 10190 // to check the prototype for missing elements. |
10189 Handle<FixedArray> elements(FixedArray::cast(receiver->elements())); | 10191 Handle<FixedArray> elements(FixedArray::cast(receiver->elements())); |
10190 int fast_length = static_cast<int>(length); | 10192 int fast_length = static_cast<int>(length); |
10191 ASSERT(fast_length <= elements->length()); | 10193 ASSERT(fast_length <= elements->length()); |
10192 for (int j = 0; j < fast_length; j++) { | 10194 for (int j = 0; j < fast_length; j++) { |
10193 HandleScope loop_scope(isolate); | 10195 HandleScope loop_scope(isolate); |
10194 Handle<Object> element_value(elements->get(j), isolate); | 10196 Handle<Object> element_value(elements->get(j), isolate); |
10195 if (!element_value->IsTheHole()) { | 10197 if (!element_value->IsTheHole()) { |
10196 visitor->visit(j, element_value); | 10198 visitor->visit(j, element_value); |
10197 } else if (receiver->HasElement(j)) { | 10199 } else if (JSReceiver::HasElement(receiver, j)) { |
10198 // Call GetElement on receiver, not its prototype, or getters won't | 10200 // Call GetElement on receiver, not its prototype, or getters won't |
10199 // have the correct receiver. | 10201 // have the correct receiver. |
10200 element_value = Object::GetElement(isolate, receiver, j); | 10202 element_value = Object::GetElement(isolate, receiver, j); |
10201 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, element_value, false); | 10203 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, element_value, false); |
10202 visitor->visit(j, element_value); | 10204 visitor->visit(j, element_value); |
10203 } | 10205 } |
10204 } | 10206 } |
10205 break; | 10207 break; |
10206 } | 10208 } |
10207 case FAST_HOLEY_DOUBLE_ELEMENTS: | 10209 case FAST_HOLEY_DOUBLE_ELEMENTS: |
10208 case FAST_DOUBLE_ELEMENTS: { | 10210 case FAST_DOUBLE_ELEMENTS: { |
10209 // Run through the elements FixedArray and use HasElement and GetElement | 10211 // Run through the elements FixedArray and use HasElement and GetElement |
10210 // to check the prototype for missing elements. | 10212 // to check the prototype for missing elements. |
10211 Handle<FixedDoubleArray> elements( | 10213 Handle<FixedDoubleArray> elements( |
10212 FixedDoubleArray::cast(receiver->elements())); | 10214 FixedDoubleArray::cast(receiver->elements())); |
10213 int fast_length = static_cast<int>(length); | 10215 int fast_length = static_cast<int>(length); |
10214 ASSERT(fast_length <= elements->length()); | 10216 ASSERT(fast_length <= elements->length()); |
10215 for (int j = 0; j < fast_length; j++) { | 10217 for (int j = 0; j < fast_length; j++) { |
10216 HandleScope loop_scope(isolate); | 10218 HandleScope loop_scope(isolate); |
10217 if (!elements->is_the_hole(j)) { | 10219 if (!elements->is_the_hole(j)) { |
10218 double double_value = elements->get_scalar(j); | 10220 double double_value = elements->get_scalar(j); |
10219 Handle<Object> element_value = | 10221 Handle<Object> element_value = |
10220 isolate->factory()->NewNumber(double_value); | 10222 isolate->factory()->NewNumber(double_value); |
10221 visitor->visit(j, element_value); | 10223 visitor->visit(j, element_value); |
10222 } else if (receiver->HasElement(j)) { | 10224 } else if (JSReceiver::HasElement(receiver, j)) { |
10223 // Call GetElement on receiver, not its prototype, or getters won't | 10225 // Call GetElement on receiver, not its prototype, or getters won't |
10224 // have the correct receiver. | 10226 // have the correct receiver. |
10225 Handle<Object> element_value = | 10227 Handle<Object> element_value = |
10226 Object::GetElement(isolate, receiver, j); | 10228 Object::GetElement(isolate, receiver, j); |
10227 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, element_value, false); | 10229 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, element_value, false); |
10228 visitor->visit(j, element_value); | 10230 visitor->visit(j, element_value); |
10229 } | 10231 } |
10230 } | 10232 } |
10231 break; | 10233 break; |
10232 } | 10234 } |
(...skipping 1295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11528 isolate, scope_info, function_context, variable_name, new_value)) { | 11530 isolate, scope_info, function_context, variable_name, new_value)) { |
11529 return true; | 11531 return true; |
11530 } | 11532 } |
11531 | 11533 |
11532 // Function context extension. These are variables introduced by eval. | 11534 // Function context extension. These are variables introduced by eval. |
11533 if (function_context->closure() == *function) { | 11535 if (function_context->closure() == *function) { |
11534 if (function_context->has_extension() && | 11536 if (function_context->has_extension() && |
11535 !function_context->IsNativeContext()) { | 11537 !function_context->IsNativeContext()) { |
11536 Handle<JSObject> ext(JSObject::cast(function_context->extension())); | 11538 Handle<JSObject> ext(JSObject::cast(function_context->extension())); |
11537 | 11539 |
11538 if (ext->HasProperty(*variable_name)) { | 11540 if (JSReceiver::HasProperty(ext, variable_name)) { |
11539 // We don't expect this to do anything except replacing | 11541 // We don't expect this to do anything except replacing |
11540 // property value. | 11542 // property value. |
11541 SetProperty(isolate, | 11543 SetProperty(isolate, |
11542 ext, | 11544 ext, |
11543 variable_name, | 11545 variable_name, |
11544 new_value, | 11546 new_value, |
11545 NONE, | 11547 NONE, |
11546 kNonStrictMode); | 11548 kNonStrictMode); |
11547 return true; | 11549 return true; |
11548 } | 11550 } |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11616 // Context locals to the context extension. | 11618 // Context locals to the context extension. |
11617 if (SetContextLocalValue( | 11619 if (SetContextLocalValue( |
11618 isolate, scope_info, context, variable_name, new_value)) { | 11620 isolate, scope_info, context, variable_name, new_value)) { |
11619 return true; | 11621 return true; |
11620 } | 11622 } |
11621 | 11623 |
11622 // Properties from the function context extension. This will | 11624 // Properties from the function context extension. This will |
11623 // be variables introduced by eval. | 11625 // be variables introduced by eval. |
11624 if (context->has_extension()) { | 11626 if (context->has_extension()) { |
11625 Handle<JSObject> ext(JSObject::cast(context->extension())); | 11627 Handle<JSObject> ext(JSObject::cast(context->extension())); |
11626 if (ext->HasProperty(*variable_name)) { | 11628 if (JSReceiver::HasProperty(ext, variable_name)) { |
11627 // We don't expect this to do anything except replacing property value. | 11629 // We don't expect this to do anything except replacing property value. |
11628 SetProperty(isolate, | 11630 SetProperty(isolate, |
11629 ext, | 11631 ext, |
11630 variable_name, | 11632 variable_name, |
11631 new_value, | 11633 new_value, |
11632 NONE, | 11634 NONE, |
11633 kNonStrictMode); | 11635 kNonStrictMode); |
11634 return true; | 11636 return true; |
11635 } | 11637 } |
11636 } | 11638 } |
(...skipping 1022 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12659 | 12661 |
12660 // Helper function to find or create the arguments object for | 12662 // Helper function to find or create the arguments object for |
12661 // Runtime_DebugEvaluate. | 12663 // Runtime_DebugEvaluate. |
12662 static Handle<JSObject> MaterializeArgumentsObject( | 12664 static Handle<JSObject> MaterializeArgumentsObject( |
12663 Isolate* isolate, | 12665 Isolate* isolate, |
12664 Handle<JSObject> target, | 12666 Handle<JSObject> target, |
12665 Handle<JSFunction> function) { | 12667 Handle<JSFunction> function) { |
12666 // Do not materialize the arguments object for eval or top-level code. | 12668 // Do not materialize the arguments object for eval or top-level code. |
12667 // Skip if "arguments" is already taken. | 12669 // Skip if "arguments" is already taken. |
12668 if (!function->shared()->is_function() || | 12670 if (!function->shared()->is_function() || |
12669 target->HasLocalProperty(isolate->heap()->arguments_string())) { | 12671 JSReceiver::HasLocalProperty(target, |
| 12672 isolate->factory()->arguments_string())) { |
12670 return target; | 12673 return target; |
12671 } | 12674 } |
12672 | 12675 |
12673 // FunctionGetArguments can't throw an exception. | 12676 // FunctionGetArguments can't throw an exception. |
12674 Handle<JSObject> arguments = Handle<JSObject>::cast( | 12677 Handle<JSObject> arguments = Handle<JSObject>::cast( |
12675 Accessors::FunctionGetArguments(function)); | 12678 Accessors::FunctionGetArguments(function)); |
12676 SetProperty(isolate, | 12679 SetProperty(isolate, |
12677 target, | 12680 target, |
12678 isolate->factory()->arguments_string(), | 12681 isolate->factory()->arguments_string(), |
12679 arguments, | 12682 arguments, |
(...skipping 2141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14821 // Handle last resort GC and make sure to allow future allocations | 14824 // Handle last resort GC and make sure to allow future allocations |
14822 // to grow the heap without causing GCs (if possible). | 14825 // to grow the heap without causing GCs (if possible). |
14823 isolate->counters()->gc_last_resort_from_js()->Increment(); | 14826 isolate->counters()->gc_last_resort_from_js()->Increment(); |
14824 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, | 14827 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, |
14825 "Runtime::PerformGC"); | 14828 "Runtime::PerformGC"); |
14826 } | 14829 } |
14827 } | 14830 } |
14828 | 14831 |
14829 | 14832 |
14830 } } // namespace v8::internal | 14833 } } // namespace v8::internal |
OLD | NEW |