| 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 4731 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4742 } | 4742 } |
| 4743 | 4743 |
| 4744 PropertyAttributes att = object->GetLocalPropertyAttribute(key); | 4744 PropertyAttributes att = object->GetLocalPropertyAttribute(key); |
| 4745 return isolate->heap()->ToBoolean(att != ABSENT && (att & DONT_ENUM) == 0); | 4745 return isolate->heap()->ToBoolean(att != ABSENT && (att & DONT_ENUM) == 0); |
| 4746 } | 4746 } |
| 4747 | 4747 |
| 4748 | 4748 |
| 4749 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPropertyNames) { | 4749 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPropertyNames) { |
| 4750 HandleScope scope(isolate); | 4750 HandleScope scope(isolate); |
| 4751 ASSERT(args.length() == 1); | 4751 ASSERT(args.length() == 1); |
| 4752 CONVERT_ARG_CHECKED(JSObject, object, 0); | 4752 CONVERT_ARG_CHECKED(JSReceiver, object, 0); |
| 4753 return *GetKeysFor(object); | 4753 bool threw = false; |
| 4754 Handle<JSArray> result = GetKeysFor(object, &threw); |
| 4755 if (threw) return Failure::Exception(); |
| 4756 return *result; |
| 4754 } | 4757 } |
| 4755 | 4758 |
| 4756 | 4759 |
| 4757 // Returns either a FixedArray as Runtime_GetPropertyNames, | 4760 // Returns either a FixedArray as Runtime_GetPropertyNames, |
| 4758 // or, if the given object has an enum cache that contains | 4761 // or, if the given object has an enum cache that contains |
| 4759 // all enumerable properties of the object and its prototypes | 4762 // all enumerable properties of the object and its prototypes |
| 4760 // have none, the map of the object. This is used to speed up | 4763 // have none, the map of the object. This is used to speed up |
| 4761 // the check for deletions during a for-in. | 4764 // the check for deletions during a for-in. |
| 4762 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPropertyNamesFast) { | 4765 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPropertyNamesFast) { |
| 4763 ASSERT(args.length() == 1); | 4766 ASSERT(args.length() == 1); |
| 4764 | 4767 |
| 4765 CONVERT_CHECKED(JSObject, raw_object, args[0]); | 4768 CONVERT_CHECKED(JSReceiver, raw_object, args[0]); |
| 4766 | 4769 |
| 4767 if (raw_object->IsSimpleEnum()) return raw_object->map(); | 4770 if (raw_object->IsSimpleEnum()) return raw_object->map(); |
| 4768 | 4771 |
| 4769 HandleScope scope(isolate); | 4772 HandleScope scope(isolate); |
| 4770 Handle<JSObject> object(raw_object); | 4773 Handle<JSReceiver> object(raw_object); |
| 4771 Handle<FixedArray> content = GetKeysInFixedArrayFor(object, | 4774 bool threw = false; |
| 4772 INCLUDE_PROTOS); | 4775 Handle<FixedArray> content = |
| 4776 GetKeysInFixedArrayFor(object, INCLUDE_PROTOS, &threw); |
| 4777 if (threw) return Failure::Exception(); |
| 4773 | 4778 |
| 4774 // Test again, since cache may have been built by preceding call. | 4779 // Test again, since cache may have been built by preceding call. |
| 4775 if (object->IsSimpleEnum()) return object->map(); | 4780 if (object->IsSimpleEnum()) return object->map(); |
| 4776 | 4781 |
| 4777 return *content; | 4782 return *content; |
| 4778 } | 4783 } |
| 4779 | 4784 |
| 4780 | 4785 |
| 4781 // Find the length of the prototype chain that is to to handled as one. If a | 4786 // Find the length of the prototype chain that is to to handled as one. If a |
| 4782 // prototype object is hidden it is to be viewed as part of the the object it | 4787 // prototype object is hidden it is to be viewed as part of the the object it |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4959 isolate->ReportFailedAccessCheck(*object, v8::ACCESS_KEYS); | 4964 isolate->ReportFailedAccessCheck(*object, v8::ACCESS_KEYS); |
| 4960 return *isolate->factory()->NewJSArray(0); | 4965 return *isolate->factory()->NewJSArray(0); |
| 4961 } | 4966 } |
| 4962 | 4967 |
| 4963 Handle<Object> proto(object->GetPrototype()); | 4968 Handle<Object> proto(object->GetPrototype()); |
| 4964 // If proxy is detached we simply return an empty array. | 4969 // If proxy is detached we simply return an empty array. |
| 4965 if (proto->IsNull()) return *isolate->factory()->NewJSArray(0); | 4970 if (proto->IsNull()) return *isolate->factory()->NewJSArray(0); |
| 4966 object = Handle<JSObject>::cast(proto); | 4971 object = Handle<JSObject>::cast(proto); |
| 4967 } | 4972 } |
| 4968 | 4973 |
| 4969 Handle<FixedArray> contents = GetKeysInFixedArrayFor(object, | 4974 bool threw = false; |
| 4970 LOCAL_ONLY); | 4975 Handle<FixedArray> contents = |
| 4976 GetKeysInFixedArrayFor(object, LOCAL_ONLY, &threw); |
| 4977 if (threw) return Failure::Exception(); |
| 4978 |
| 4971 // Some fast paths through GetKeysInFixedArrayFor reuse a cached | 4979 // Some fast paths through GetKeysInFixedArrayFor reuse a cached |
| 4972 // property array and since the result is mutable we have to create | 4980 // property array and since the result is mutable we have to create |
| 4973 // a fresh clone on each invocation. | 4981 // a fresh clone on each invocation. |
| 4974 int length = contents->length(); | 4982 int length = contents->length(); |
| 4975 Handle<FixedArray> copy = isolate->factory()->NewFixedArray(length); | 4983 Handle<FixedArray> copy = isolate->factory()->NewFixedArray(length); |
| 4976 for (int i = 0; i < length; i++) { | 4984 for (int i = 0; i < length; i++) { |
| 4977 Object* entry = contents->get(i); | 4985 Object* entry = contents->get(i); |
| 4978 if (entry->IsString()) { | 4986 if (entry->IsString()) { |
| 4979 copy->set(i, entry); | 4987 copy->set(i, entry); |
| 4980 } else { | 4988 } else { |
| (...skipping 5144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10125 // positive (length)) or undefined values. | 10133 // positive (length)) or undefined values. |
| 10126 // Intervals can span over some keys that are not in the object. | 10134 // Intervals can span over some keys that are not in the object. |
| 10127 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetArrayKeys) { | 10135 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetArrayKeys) { |
| 10128 ASSERT(args.length() == 2); | 10136 ASSERT(args.length() == 2); |
| 10129 HandleScope scope(isolate); | 10137 HandleScope scope(isolate); |
| 10130 CONVERT_ARG_CHECKED(JSObject, array, 0); | 10138 CONVERT_ARG_CHECKED(JSObject, array, 0); |
| 10131 CONVERT_NUMBER_CHECKED(uint32_t, length, Uint32, args[1]); | 10139 CONVERT_NUMBER_CHECKED(uint32_t, length, Uint32, args[1]); |
| 10132 if (array->elements()->IsDictionary()) { | 10140 if (array->elements()->IsDictionary()) { |
| 10133 // Create an array and get all the keys into it, then remove all the | 10141 // Create an array and get all the keys into it, then remove all the |
| 10134 // keys that are not integers in the range 0 to length-1. | 10142 // keys that are not integers in the range 0 to length-1. |
| 10135 Handle<FixedArray> keys = GetKeysInFixedArrayFor(array, INCLUDE_PROTOS); | 10143 bool threw = false; |
| 10144 Handle<FixedArray> keys = |
| 10145 GetKeysInFixedArrayFor(array, INCLUDE_PROTOS, &threw); |
| 10146 if (threw) return Failure::Exception(); |
| 10147 |
| 10136 int keys_length = keys->length(); | 10148 int keys_length = keys->length(); |
| 10137 for (int i = 0; i < keys_length; i++) { | 10149 for (int i = 0; i < keys_length; i++) { |
| 10138 Object* key = keys->get(i); | 10150 Object* key = keys->get(i); |
| 10139 uint32_t index = 0; | 10151 uint32_t index = 0; |
| 10140 if (!key->ToArrayIndex(&index) || index >= length) { | 10152 if (!key->ToArrayIndex(&index) || index >= length) { |
| 10141 // Zap invalid keys. | 10153 // Zap invalid keys. |
| 10142 keys->set_undefined(i); | 10154 keys->set_undefined(i); |
| 10143 } | 10155 } |
| 10144 } | 10156 } |
| 10145 return *isolate->factory()->NewJSArrayWithElements(keys); | 10157 return *isolate->factory()->NewJSArrayWithElements(keys); |
| (...skipping 798 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10944 function_context, local_scope)) { | 10956 function_context, local_scope)) { |
| 10945 return Handle<JSObject>(); | 10957 return Handle<JSObject>(); |
| 10946 } | 10958 } |
| 10947 | 10959 |
| 10948 // Finally copy any properties from the function context extension. | 10960 // Finally copy any properties from the function context extension. |
| 10949 // These will be variables introduced by eval. | 10961 // These will be variables introduced by eval. |
| 10950 if (function_context->closure() == *function) { | 10962 if (function_context->closure() == *function) { |
| 10951 if (function_context->has_extension() && | 10963 if (function_context->has_extension() && |
| 10952 !function_context->IsGlobalContext()) { | 10964 !function_context->IsGlobalContext()) { |
| 10953 Handle<JSObject> ext(JSObject::cast(function_context->extension())); | 10965 Handle<JSObject> ext(JSObject::cast(function_context->extension())); |
| 10954 Handle<FixedArray> keys = GetKeysInFixedArrayFor(ext, INCLUDE_PROTOS); | 10966 bool threw = false; |
| 10967 Handle<FixedArray> keys = |
| 10968 GetKeysInFixedArrayFor(ext, INCLUDE_PROTOS, &threw); |
| 10969 if (threw) return Handle<JSObject>(); |
| 10970 |
| 10955 for (int i = 0; i < keys->length(); i++) { | 10971 for (int i = 0; i < keys->length(); i++) { |
| 10956 // Names of variables introduced by eval are strings. | 10972 // Names of variables introduced by eval are strings. |
| 10957 ASSERT(keys->get(i)->IsString()); | 10973 ASSERT(keys->get(i)->IsString()); |
| 10958 Handle<String> key(String::cast(keys->get(i))); | 10974 Handle<String> key(String::cast(keys->get(i))); |
| 10959 RETURN_IF_EMPTY_HANDLE_VALUE( | 10975 RETURN_IF_EMPTY_HANDLE_VALUE( |
| 10960 isolate, | 10976 isolate, |
| 10961 SetProperty(local_scope, | 10977 SetProperty(local_scope, |
| 10962 key, | 10978 key, |
| 10963 GetProperty(ext, key), | 10979 GetProperty(ext, key), |
| 10964 NONE, | 10980 NONE, |
| (...skipping 27 matching lines...) Expand all Loading... |
| 10992 if (!CopyContextLocalsToScopeObject(isolate, | 11008 if (!CopyContextLocalsToScopeObject(isolate, |
| 10993 serialized_scope_info, scope_info, | 11009 serialized_scope_info, scope_info, |
| 10994 context, closure_scope)) { | 11010 context, closure_scope)) { |
| 10995 return Handle<JSObject>(); | 11011 return Handle<JSObject>(); |
| 10996 } | 11012 } |
| 10997 | 11013 |
| 10998 // Finally copy any properties from the function context extension. This will | 11014 // Finally copy any properties from the function context extension. This will |
| 10999 // be variables introduced by eval. | 11015 // be variables introduced by eval. |
| 11000 if (context->has_extension()) { | 11016 if (context->has_extension()) { |
| 11001 Handle<JSObject> ext(JSObject::cast(context->extension())); | 11017 Handle<JSObject> ext(JSObject::cast(context->extension())); |
| 11002 Handle<FixedArray> keys = GetKeysInFixedArrayFor(ext, INCLUDE_PROTOS); | 11018 bool threw = false; |
| 11019 Handle<FixedArray> keys = |
| 11020 GetKeysInFixedArrayFor(ext, INCLUDE_PROTOS, &threw); |
| 11021 if (threw) return Handle<JSObject>(); |
| 11022 |
| 11003 for (int i = 0; i < keys->length(); i++) { | 11023 for (int i = 0; i < keys->length(); i++) { |
| 11004 // Names of variables introduced by eval are strings. | 11024 // Names of variables introduced by eval are strings. |
| 11005 ASSERT(keys->get(i)->IsString()); | 11025 ASSERT(keys->get(i)->IsString()); |
| 11006 Handle<String> key(String::cast(keys->get(i))); | 11026 Handle<String> key(String::cast(keys->get(i))); |
| 11007 RETURN_IF_EMPTY_HANDLE_VALUE( | 11027 RETURN_IF_EMPTY_HANDLE_VALUE( |
| 11008 isolate, | 11028 isolate, |
| 11009 SetProperty(closure_scope, | 11029 SetProperty(closure_scope, |
| 11010 key, | 11030 key, |
| 11011 GetProperty(ext, key), | 11031 GetProperty(ext, key), |
| 11012 NONE, | 11032 NONE, |
| (...skipping 2400 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13413 } else { | 13433 } else { |
| 13414 // Handle last resort GC and make sure to allow future allocations | 13434 // Handle last resort GC and make sure to allow future allocations |
| 13415 // to grow the heap without causing GCs (if possible). | 13435 // to grow the heap without causing GCs (if possible). |
| 13416 isolate->counters()->gc_last_resort_from_js()->Increment(); | 13436 isolate->counters()->gc_last_resort_from_js()->Increment(); |
| 13417 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags); | 13437 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags); |
| 13418 } | 13438 } |
| 13419 } | 13439 } |
| 13420 | 13440 |
| 13421 | 13441 |
| 13422 } } // namespace v8::internal | 13442 } } // namespace v8::internal |
| OLD | NEW |