Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(402)

Side by Side Diff: src/runtime.cc

Issue 23496058: Handlify JSReceiver::HasProperty and friends. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/objects-inl.h ('k') | test/cctest/test-heap.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/objects-inl.h ('k') | test/cctest/test-heap.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698