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 |