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 4733 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4744 } | 4744 } |
4745 | 4745 |
4746 PropertyAttributes att = object->GetLocalPropertyAttribute(key); | 4746 PropertyAttributes att = object->GetLocalPropertyAttribute(key); |
4747 return isolate->heap()->ToBoolean(att != ABSENT && (att & DONT_ENUM) == 0); | 4747 return isolate->heap()->ToBoolean(att != ABSENT && (att & DONT_ENUM) == 0); |
4748 } | 4748 } |
4749 | 4749 |
4750 | 4750 |
4751 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPropertyNames) { | 4751 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPropertyNames) { |
4752 HandleScope scope(isolate); | 4752 HandleScope scope(isolate); |
4753 ASSERT(args.length() == 1); | 4753 ASSERT(args.length() == 1); |
4754 CONVERT_ARG_CHECKED(JSObject, object, 0); | 4754 CONVERT_ARG_CHECKED(JSReceiver, object, 0); |
4755 return *GetKeysFor(object); | 4755 bool threw = false; |
| 4756 Handle<JSArray> result = GetKeysFor(object, &threw); |
| 4757 if (threw) return Failure::Exception(); |
| 4758 return *result; |
4756 } | 4759 } |
4757 | 4760 |
4758 | 4761 |
4759 // Returns either a FixedArray as Runtime_GetPropertyNames, | 4762 // Returns either a FixedArray as Runtime_GetPropertyNames, |
4760 // or, if the given object has an enum cache that contains | 4763 // or, if the given object has an enum cache that contains |
4761 // all enumerable properties of the object and its prototypes | 4764 // all enumerable properties of the object and its prototypes |
4762 // have none, the map of the object. This is used to speed up | 4765 // have none, the map of the object. This is used to speed up |
4763 // the check for deletions during a for-in. | 4766 // the check for deletions during a for-in. |
4764 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPropertyNamesFast) { | 4767 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPropertyNamesFast) { |
4765 ASSERT(args.length() == 1); | 4768 ASSERT(args.length() == 1); |
4766 | 4769 |
4767 CONVERT_CHECKED(JSObject, raw_object, args[0]); | 4770 CONVERT_CHECKED(JSReceiver, raw_object, args[0]); |
4768 | 4771 |
4769 if (raw_object->IsSimpleEnum()) return raw_object->map(); | 4772 if (raw_object->IsSimpleEnum()) return raw_object->map(); |
4770 | 4773 |
4771 HandleScope scope(isolate); | 4774 HandleScope scope(isolate); |
4772 Handle<JSObject> object(raw_object); | 4775 Handle<JSReceiver> object(raw_object); |
4773 Handle<FixedArray> content = GetKeysInFixedArrayFor(object, | 4776 bool threw = false; |
4774 INCLUDE_PROTOS); | 4777 Handle<FixedArray> content = |
| 4778 GetKeysInFixedArrayFor(object, INCLUDE_PROTOS, &threw); |
| 4779 if (threw) return Failure::Exception(); |
4775 | 4780 |
4776 // Test again, since cache may have been built by preceding call. | 4781 // Test again, since cache may have been built by preceding call. |
4777 if (object->IsSimpleEnum()) return object->map(); | 4782 if (object->IsSimpleEnum()) return object->map(); |
4778 | 4783 |
4779 return *content; | 4784 return *content; |
4780 } | 4785 } |
4781 | 4786 |
4782 | 4787 |
4783 // Find the length of the prototype chain that is to to handled as one. If a | 4788 // Find the length of the prototype chain that is to to handled as one. If a |
4784 // prototype object is hidden it is to be viewed as part of the the object it | 4789 // 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... |
4961 isolate->ReportFailedAccessCheck(*object, v8::ACCESS_KEYS); | 4966 isolate->ReportFailedAccessCheck(*object, v8::ACCESS_KEYS); |
4962 return *isolate->factory()->NewJSArray(0); | 4967 return *isolate->factory()->NewJSArray(0); |
4963 } | 4968 } |
4964 | 4969 |
4965 Handle<Object> proto(object->GetPrototype()); | 4970 Handle<Object> proto(object->GetPrototype()); |
4966 // If proxy is detached we simply return an empty array. | 4971 // If proxy is detached we simply return an empty array. |
4967 if (proto->IsNull()) return *isolate->factory()->NewJSArray(0); | 4972 if (proto->IsNull()) return *isolate->factory()->NewJSArray(0); |
4968 object = Handle<JSObject>::cast(proto); | 4973 object = Handle<JSObject>::cast(proto); |
4969 } | 4974 } |
4970 | 4975 |
4971 Handle<FixedArray> contents = GetKeysInFixedArrayFor(object, | 4976 bool threw = false; |
4972 LOCAL_ONLY); | 4977 Handle<FixedArray> contents = |
| 4978 GetKeysInFixedArrayFor(object, LOCAL_ONLY, &threw); |
| 4979 if (threw) return Failure::Exception(); |
| 4980 |
4973 // Some fast paths through GetKeysInFixedArrayFor reuse a cached | 4981 // Some fast paths through GetKeysInFixedArrayFor reuse a cached |
4974 // property array and since the result is mutable we have to create | 4982 // property array and since the result is mutable we have to create |
4975 // a fresh clone on each invocation. | 4983 // a fresh clone on each invocation. |
4976 int length = contents->length(); | 4984 int length = contents->length(); |
4977 Handle<FixedArray> copy = isolate->factory()->NewFixedArray(length); | 4985 Handle<FixedArray> copy = isolate->factory()->NewFixedArray(length); |
4978 for (int i = 0; i < length; i++) { | 4986 for (int i = 0; i < length; i++) { |
4979 Object* entry = contents->get(i); | 4987 Object* entry = contents->get(i); |
4980 if (entry->IsString()) { | 4988 if (entry->IsString()) { |
4981 copy->set(i, entry); | 4989 copy->set(i, entry); |
4982 } else { | 4990 } else { |
(...skipping 5088 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10071 // positive (length)) or undefined values. | 10079 // positive (length)) or undefined values. |
10072 // Intervals can span over some keys that are not in the object. | 10080 // Intervals can span over some keys that are not in the object. |
10073 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetArrayKeys) { | 10081 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetArrayKeys) { |
10074 ASSERT(args.length() == 2); | 10082 ASSERT(args.length() == 2); |
10075 HandleScope scope(isolate); | 10083 HandleScope scope(isolate); |
10076 CONVERT_ARG_CHECKED(JSObject, array, 0); | 10084 CONVERT_ARG_CHECKED(JSObject, array, 0); |
10077 CONVERT_NUMBER_CHECKED(uint32_t, length, Uint32, args[1]); | 10085 CONVERT_NUMBER_CHECKED(uint32_t, length, Uint32, args[1]); |
10078 if (array->elements()->IsDictionary()) { | 10086 if (array->elements()->IsDictionary()) { |
10079 // Create an array and get all the keys into it, then remove all the | 10087 // Create an array and get all the keys into it, then remove all the |
10080 // keys that are not integers in the range 0 to length-1. | 10088 // keys that are not integers in the range 0 to length-1. |
10081 Handle<FixedArray> keys = GetKeysInFixedArrayFor(array, INCLUDE_PROTOS); | 10089 bool threw = false; |
| 10090 Handle<FixedArray> keys = |
| 10091 GetKeysInFixedArrayFor(array, INCLUDE_PROTOS, &threw); |
| 10092 if (threw) return Failure::Exception(); |
| 10093 |
10082 int keys_length = keys->length(); | 10094 int keys_length = keys->length(); |
10083 for (int i = 0; i < keys_length; i++) { | 10095 for (int i = 0; i < keys_length; i++) { |
10084 Object* key = keys->get(i); | 10096 Object* key = keys->get(i); |
10085 uint32_t index = 0; | 10097 uint32_t index = 0; |
10086 if (!key->ToArrayIndex(&index) || index >= length) { | 10098 if (!key->ToArrayIndex(&index) || index >= length) { |
10087 // Zap invalid keys. | 10099 // Zap invalid keys. |
10088 keys->set_undefined(i); | 10100 keys->set_undefined(i); |
10089 } | 10101 } |
10090 } | 10102 } |
10091 return *isolate->factory()->NewJSArrayWithElements(keys); | 10103 return *isolate->factory()->NewJSArrayWithElements(keys); |
(...skipping 798 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10890 function_context, local_scope)) { | 10902 function_context, local_scope)) { |
10891 return Handle<JSObject>(); | 10903 return Handle<JSObject>(); |
10892 } | 10904 } |
10893 | 10905 |
10894 // Finally copy any properties from the function context extension. | 10906 // Finally copy any properties from the function context extension. |
10895 // These will be variables introduced by eval. | 10907 // These will be variables introduced by eval. |
10896 if (function_context->closure() == *function) { | 10908 if (function_context->closure() == *function) { |
10897 if (function_context->has_extension() && | 10909 if (function_context->has_extension() && |
10898 !function_context->IsGlobalContext()) { | 10910 !function_context->IsGlobalContext()) { |
10899 Handle<JSObject> ext(JSObject::cast(function_context->extension())); | 10911 Handle<JSObject> ext(JSObject::cast(function_context->extension())); |
10900 Handle<FixedArray> keys = GetKeysInFixedArrayFor(ext, INCLUDE_PROTOS); | 10912 bool threw = false; |
| 10913 Handle<FixedArray> keys = |
| 10914 GetKeysInFixedArrayFor(ext, INCLUDE_PROTOS, &threw); |
| 10915 if (threw) return Handle<JSObject>(); |
| 10916 |
10901 for (int i = 0; i < keys->length(); i++) { | 10917 for (int i = 0; i < keys->length(); i++) { |
10902 // Names of variables introduced by eval are strings. | 10918 // Names of variables introduced by eval are strings. |
10903 ASSERT(keys->get(i)->IsString()); | 10919 ASSERT(keys->get(i)->IsString()); |
10904 Handle<String> key(String::cast(keys->get(i))); | 10920 Handle<String> key(String::cast(keys->get(i))); |
10905 RETURN_IF_EMPTY_HANDLE_VALUE( | 10921 RETURN_IF_EMPTY_HANDLE_VALUE( |
10906 isolate, | 10922 isolate, |
10907 SetProperty(local_scope, | 10923 SetProperty(local_scope, |
10908 key, | 10924 key, |
10909 GetProperty(ext, key), | 10925 GetProperty(ext, key), |
10910 NONE, | 10926 NONE, |
(...skipping 27 matching lines...) Expand all Loading... |
10938 if (!CopyContextLocalsToScopeObject(isolate, | 10954 if (!CopyContextLocalsToScopeObject(isolate, |
10939 serialized_scope_info, scope_info, | 10955 serialized_scope_info, scope_info, |
10940 context, closure_scope)) { | 10956 context, closure_scope)) { |
10941 return Handle<JSObject>(); | 10957 return Handle<JSObject>(); |
10942 } | 10958 } |
10943 | 10959 |
10944 // Finally copy any properties from the function context extension. This will | 10960 // Finally copy any properties from the function context extension. This will |
10945 // be variables introduced by eval. | 10961 // be variables introduced by eval. |
10946 if (context->has_extension()) { | 10962 if (context->has_extension()) { |
10947 Handle<JSObject> ext(JSObject::cast(context->extension())); | 10963 Handle<JSObject> ext(JSObject::cast(context->extension())); |
10948 Handle<FixedArray> keys = GetKeysInFixedArrayFor(ext, INCLUDE_PROTOS); | 10964 bool threw = false; |
| 10965 Handle<FixedArray> keys = |
| 10966 GetKeysInFixedArrayFor(ext, INCLUDE_PROTOS, &threw); |
| 10967 if (threw) return Handle<JSObject>(); |
| 10968 |
10949 for (int i = 0; i < keys->length(); i++) { | 10969 for (int i = 0; i < keys->length(); i++) { |
10950 // Names of variables introduced by eval are strings. | 10970 // Names of variables introduced by eval are strings. |
10951 ASSERT(keys->get(i)->IsString()); | 10971 ASSERT(keys->get(i)->IsString()); |
10952 Handle<String> key(String::cast(keys->get(i))); | 10972 Handle<String> key(String::cast(keys->get(i))); |
10953 RETURN_IF_EMPTY_HANDLE_VALUE( | 10973 RETURN_IF_EMPTY_HANDLE_VALUE( |
10954 isolate, | 10974 isolate, |
10955 SetProperty(closure_scope, | 10975 SetProperty(closure_scope, |
10956 key, | 10976 key, |
10957 GetProperty(ext, key), | 10977 GetProperty(ext, key), |
10958 NONE, | 10978 NONE, |
(...skipping 2329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13288 } else { | 13308 } else { |
13289 // Handle last resort GC and make sure to allow future allocations | 13309 // Handle last resort GC and make sure to allow future allocations |
13290 // to grow the heap without causing GCs (if possible). | 13310 // to grow the heap without causing GCs (if possible). |
13291 isolate->counters()->gc_last_resort_from_js()->Increment(); | 13311 isolate->counters()->gc_last_resort_from_js()->Increment(); |
13292 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags); | 13312 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags); |
13293 } | 13313 } |
13294 } | 13314 } |
13295 | 13315 |
13296 | 13316 |
13297 } } // namespace v8::internal | 13317 } } // namespace v8::internal |
OLD | NEW |