| 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 4137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4148 obj_value, | 4148 obj_value, |
| 4149 attr); | 4149 attr); |
| 4150 } | 4150 } |
| 4151 | 4151 |
| 4152 | 4152 |
| 4153 // Return property without being observable by accessors or interceptors. | 4153 // Return property without being observable by accessors or interceptors. |
| 4154 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetDataProperty) { | 4154 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetDataProperty) { |
| 4155 ASSERT(args.length() == 2); | 4155 ASSERT(args.length() == 2); |
| 4156 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); | 4156 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); |
| 4157 CONVERT_ARG_HANDLE_CHECKED(String, key, 1); | 4157 CONVERT_ARG_HANDLE_CHECKED(String, key, 1); |
| 4158 // In rare cases the global object backing the global proxy may already be |
| 4159 // invalid. In that case, return undefined. |
| 4160 if (object->IsJSGlobalProxy() && |
| 4161 !object->GetPrototype()->IsJSGlobalObject()) { |
| 4162 return isolate->heap()->undefined_value(); |
| 4163 } |
| 4158 LookupResult lookup(isolate); | 4164 LookupResult lookup(isolate); |
| 4159 object->LookupRealNamedProperty(*key, &lookup); | 4165 object->LookupRealNamedProperty(*key, &lookup); |
| 4160 if (!lookup.IsFound()) return isolate->heap()->undefined_value(); | 4166 if (!lookup.IsFound()) return isolate->heap()->undefined_value(); |
| 4161 switch (lookup.type()) { | 4167 switch (lookup.type()) { |
| 4162 case NORMAL: | 4168 case NORMAL: |
| 4163 return lookup.holder()->GetNormalizedProperty(&lookup); | 4169 return lookup.holder()->GetNormalizedProperty(&lookup); |
| 4164 case FIELD: | 4170 case FIELD: |
| 4165 return lookup.holder()->FastPropertyAt( | 4171 return lookup.holder()->FastPropertyAt( |
| 4166 lookup.GetFieldIndex().field_index()); | 4172 lookup.GetFieldIndex().field_index()); |
| 4167 case CONSTANT_FUNCTION: | 4173 case CONSTANT_FUNCTION: |
| (...skipping 469 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4637 ASSERT(args.length() == 2); | 4643 ASSERT(args.length() == 2); |
| 4638 | 4644 |
| 4639 CONVERT_ARG_CHECKED(JSObject, object, 0); | 4645 CONVERT_ARG_CHECKED(JSObject, object, 0); |
| 4640 CONVERT_ARG_CHECKED(String, key, 1); | 4646 CONVERT_ARG_CHECKED(String, key, 1); |
| 4641 | 4647 |
| 4642 PropertyAttributes att = object->GetLocalPropertyAttribute(key); | 4648 PropertyAttributes att = object->GetLocalPropertyAttribute(key); |
| 4643 return isolate->heap()->ToBoolean(att != ABSENT && (att & DONT_ENUM) == 0); | 4649 return isolate->heap()->ToBoolean(att != ABSENT && (att & DONT_ENUM) == 0); |
| 4644 } | 4650 } |
| 4645 | 4651 |
| 4646 | 4652 |
| 4647 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPropertyNames) { | 4653 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPropertyNamesNoSideEffect) { |
| 4648 HandleScope scope(isolate); | 4654 HandleScope scope(isolate); |
| 4649 ASSERT(args.length() == 1); | 4655 ASSERT(args.length() == 1); |
| 4650 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0); | 4656 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0); |
| 4657 // In rare cases the global object backing the global proxy may already be |
| 4658 // invalid. In that case, return an empty array. |
| 4659 if (object->IsJSGlobalProxy() && |
| 4660 !object->GetPrototype()->IsJSGlobalObject()) { |
| 4661 return *isolate->factory()->NewJSArray(0); |
| 4662 } |
| 4651 bool threw = false; | 4663 bool threw = false; |
| 4652 Handle<JSArray> result = GetKeysFor(object, &threw); | 4664 Handle<FixedArray> elements = |
| 4665 GetKeysInFixedArrayFor<false>(object, INCLUDE_PROTOS, &threw); |
| 4653 if (threw) return Failure::Exception(); | 4666 if (threw) return Failure::Exception(); |
| 4654 return *result; | 4667 return *isolate->factory()->NewJSArrayWithElements(elements); |
| 4655 } | 4668 } |
| 4656 | 4669 |
| 4657 | 4670 |
| 4658 // Returns either a FixedArray as Runtime_GetPropertyNames, | 4671 // Returns either a FixedArray as Runtime_GetPropertyNames, |
| 4659 // or, if the given object has an enum cache that contains | 4672 // or, if the given object has an enum cache that contains |
| 4660 // all enumerable properties of the object and its prototypes | 4673 // all enumerable properties of the object and its prototypes |
| 4661 // have none, the map of the object. This is used to speed up | 4674 // have none, the map of the object. This is used to speed up |
| 4662 // the check for deletions during a for-in. | 4675 // the check for deletions during a for-in. |
| 4663 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPropertyNamesFast) { | 4676 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPropertyNamesFast) { |
| 4664 ASSERT(args.length() == 1); | 4677 ASSERT(args.length() == 1); |
| 4665 | 4678 |
| 4666 CONVERT_ARG_CHECKED(JSReceiver, raw_object, 0); | 4679 CONVERT_ARG_CHECKED(JSReceiver, raw_object, 0); |
| 4667 | 4680 |
| 4668 if (raw_object->IsSimpleEnum()) return raw_object->map(); | 4681 if (raw_object->IsSimpleEnum()) return raw_object->map(); |
| 4669 | 4682 |
| 4670 HandleScope scope(isolate); | 4683 HandleScope scope(isolate); |
| 4671 Handle<JSReceiver> object(raw_object); | 4684 Handle<JSReceiver> object(raw_object); |
| 4672 bool threw = false; | 4685 bool threw = false; |
| 4673 Handle<FixedArray> content = | 4686 Handle<FixedArray> content = |
| 4674 GetKeysInFixedArrayFor(object, INCLUDE_PROTOS, &threw); | 4687 GetKeysInFixedArrayFor<true>(object, INCLUDE_PROTOS, &threw); |
| 4675 if (threw) return Failure::Exception(); | 4688 if (threw) return Failure::Exception(); |
| 4676 | 4689 |
| 4677 // Test again, since cache may have been built by preceding call. | 4690 // Test again, since cache may have been built by preceding call. |
| 4678 if (object->IsSimpleEnum()) return object->map(); | 4691 if (object->IsSimpleEnum()) return object->map(); |
| 4679 | 4692 |
| 4680 return *content; | 4693 return *content; |
| 4681 } | 4694 } |
| 4682 | 4695 |
| 4683 | 4696 |
| 4684 // Find the length of the prototype chain that is to to handled as one. If a | 4697 // Find the length of the prototype chain that is to to handled as one. If a |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4864 } | 4877 } |
| 4865 | 4878 |
| 4866 Handle<Object> proto(object->GetPrototype()); | 4879 Handle<Object> proto(object->GetPrototype()); |
| 4867 // If proxy is detached we simply return an empty array. | 4880 // If proxy is detached we simply return an empty array. |
| 4868 if (proto->IsNull()) return *isolate->factory()->NewJSArray(0); | 4881 if (proto->IsNull()) return *isolate->factory()->NewJSArray(0); |
| 4869 object = Handle<JSObject>::cast(proto); | 4882 object = Handle<JSObject>::cast(proto); |
| 4870 } | 4883 } |
| 4871 | 4884 |
| 4872 bool threw = false; | 4885 bool threw = false; |
| 4873 Handle<FixedArray> contents = | 4886 Handle<FixedArray> contents = |
| 4874 GetKeysInFixedArrayFor(object, LOCAL_ONLY, &threw); | 4887 GetKeysInFixedArrayFor<true>(object, LOCAL_ONLY, &threw); |
| 4875 if (threw) return Failure::Exception(); | 4888 if (threw) return Failure::Exception(); |
| 4876 | 4889 |
| 4877 // Some fast paths through GetKeysInFixedArrayFor reuse a cached | 4890 // Some fast paths through GetKeysInFixedArrayFor reuse a cached |
| 4878 // property array and since the result is mutable we have to create | 4891 // property array and since the result is mutable we have to create |
| 4879 // a fresh clone on each invocation. | 4892 // a fresh clone on each invocation. |
| 4880 int length = contents->length(); | 4893 int length = contents->length(); |
| 4881 Handle<FixedArray> copy = isolate->factory()->NewFixedArray(length); | 4894 Handle<FixedArray> copy = isolate->factory()->NewFixedArray(length); |
| 4882 for (int i = 0; i < length; i++) { | 4895 for (int i = 0; i < length; i++) { |
| 4883 Object* entry = contents->get(i); | 4896 Object* entry = contents->get(i); |
| 4884 if (entry->IsString()) { | 4897 if (entry->IsString()) { |
| (...skipping 5129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10014 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetArrayKeys) { | 10027 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetArrayKeys) { |
| 10015 ASSERT(args.length() == 2); | 10028 ASSERT(args.length() == 2); |
| 10016 HandleScope scope(isolate); | 10029 HandleScope scope(isolate); |
| 10017 CONVERT_ARG_HANDLE_CHECKED(JSObject, array, 0); | 10030 CONVERT_ARG_HANDLE_CHECKED(JSObject, array, 0); |
| 10018 CONVERT_NUMBER_CHECKED(uint32_t, length, Uint32, args[1]); | 10031 CONVERT_NUMBER_CHECKED(uint32_t, length, Uint32, args[1]); |
| 10019 if (array->elements()->IsDictionary()) { | 10032 if (array->elements()->IsDictionary()) { |
| 10020 // Create an array and get all the keys into it, then remove all the | 10033 // Create an array and get all the keys into it, then remove all the |
| 10021 // keys that are not integers in the range 0 to length-1. | 10034 // keys that are not integers in the range 0 to length-1. |
| 10022 bool threw = false; | 10035 bool threw = false; |
| 10023 Handle<FixedArray> keys = | 10036 Handle<FixedArray> keys = |
| 10024 GetKeysInFixedArrayFor(array, INCLUDE_PROTOS, &threw); | 10037 GetKeysInFixedArrayFor<true>(array, INCLUDE_PROTOS, &threw); |
| 10025 if (threw) return Failure::Exception(); | 10038 if (threw) return Failure::Exception(); |
| 10026 | 10039 |
| 10027 int keys_length = keys->length(); | 10040 int keys_length = keys->length(); |
| 10028 for (int i = 0; i < keys_length; i++) { | 10041 for (int i = 0; i < keys_length; i++) { |
| 10029 Object* key = keys->get(i); | 10042 Object* key = keys->get(i); |
| 10030 uint32_t index = 0; | 10043 uint32_t index = 0; |
| 10031 if (!key->ToArrayIndex(&index) || index >= length) { | 10044 if (!key->ToArrayIndex(&index) || index >= length) { |
| 10032 // Zap invalid keys. | 10045 // Zap invalid keys. |
| 10033 keys->set_undefined(i); | 10046 keys->set_undefined(i); |
| 10034 } | 10047 } |
| (...skipping 794 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10829 } | 10842 } |
| 10830 | 10843 |
| 10831 // Finally copy any properties from the function context extension. | 10844 // Finally copy any properties from the function context extension. |
| 10832 // These will be variables introduced by eval. | 10845 // These will be variables introduced by eval. |
| 10833 if (function_context->closure() == *function) { | 10846 if (function_context->closure() == *function) { |
| 10834 if (function_context->has_extension() && | 10847 if (function_context->has_extension() && |
| 10835 !function_context->IsNativeContext()) { | 10848 !function_context->IsNativeContext()) { |
| 10836 Handle<JSObject> ext(JSObject::cast(function_context->extension())); | 10849 Handle<JSObject> ext(JSObject::cast(function_context->extension())); |
| 10837 bool threw = false; | 10850 bool threw = false; |
| 10838 Handle<FixedArray> keys = | 10851 Handle<FixedArray> keys = |
| 10839 GetKeysInFixedArrayFor(ext, INCLUDE_PROTOS, &threw); | 10852 GetKeysInFixedArrayFor<true>(ext, INCLUDE_PROTOS, &threw); |
| 10840 if (threw) return Handle<JSObject>(); | 10853 if (threw) return Handle<JSObject>(); |
| 10841 | 10854 |
| 10842 for (int i = 0; i < keys->length(); i++) { | 10855 for (int i = 0; i < keys->length(); i++) { |
| 10843 // Names of variables introduced by eval are strings. | 10856 // Names of variables introduced by eval are strings. |
| 10844 ASSERT(keys->get(i)->IsString()); | 10857 ASSERT(keys->get(i)->IsString()); |
| 10845 Handle<String> key(String::cast(keys->get(i))); | 10858 Handle<String> key(String::cast(keys->get(i))); |
| 10846 RETURN_IF_EMPTY_HANDLE_VALUE( | 10859 RETURN_IF_EMPTY_HANDLE_VALUE( |
| 10847 isolate, | 10860 isolate, |
| 10848 SetProperty(isolate, | 10861 SetProperty(isolate, |
| 10849 local_scope, | 10862 local_scope, |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10980 isolate, scope_info, context, closure_scope)) { | 10993 isolate, scope_info, context, closure_scope)) { |
| 10981 return Handle<JSObject>(); | 10994 return Handle<JSObject>(); |
| 10982 } | 10995 } |
| 10983 | 10996 |
| 10984 // Finally copy any properties from the function context extension. This will | 10997 // Finally copy any properties from the function context extension. This will |
| 10985 // be variables introduced by eval. | 10998 // be variables introduced by eval. |
| 10986 if (context->has_extension()) { | 10999 if (context->has_extension()) { |
| 10987 Handle<JSObject> ext(JSObject::cast(context->extension())); | 11000 Handle<JSObject> ext(JSObject::cast(context->extension())); |
| 10988 bool threw = false; | 11001 bool threw = false; |
| 10989 Handle<FixedArray> keys = | 11002 Handle<FixedArray> keys = |
| 10990 GetKeysInFixedArrayFor(ext, INCLUDE_PROTOS, &threw); | 11003 GetKeysInFixedArrayFor<true>(ext, INCLUDE_PROTOS, &threw); |
| 10991 if (threw) return Handle<JSObject>(); | 11004 if (threw) return Handle<JSObject>(); |
| 10992 | 11005 |
| 10993 for (int i = 0; i < keys->length(); i++) { | 11006 for (int i = 0; i < keys->length(); i++) { |
| 10994 // Names of variables introduced by eval are strings. | 11007 // Names of variables introduced by eval are strings. |
| 10995 ASSERT(keys->get(i)->IsString()); | 11008 ASSERT(keys->get(i)->IsString()); |
| 10996 Handle<String> key(String::cast(keys->get(i))); | 11009 Handle<String> key(String::cast(keys->get(i))); |
| 10997 RETURN_IF_EMPTY_HANDLE_VALUE( | 11010 RETURN_IF_EMPTY_HANDLE_VALUE( |
| 10998 isolate, | 11011 isolate, |
| 10999 SetProperty(isolate, | 11012 SetProperty(isolate, |
| 11000 closure_scope, | 11013 closure_scope, |
| (...skipping 2070 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13071 CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0); | 13084 CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0); |
| 13072 HandleScope scope(isolate); | 13085 HandleScope scope(isolate); |
| 13073 Handle<String> key = isolate->factory()->hidden_stack_trace_symbol(); | 13086 Handle<String> key = isolate->factory()->hidden_stack_trace_symbol(); |
| 13074 JSObject::SetHiddenProperty(fun, key, key); | 13087 JSObject::SetHiddenProperty(fun, key, key); |
| 13075 return *fun; | 13088 return *fun; |
| 13076 } | 13089 } |
| 13077 | 13090 |
| 13078 | 13091 |
| 13079 // Retrieve the stack trace. This could be the raw stack trace collected | 13092 // Retrieve the stack trace. This could be the raw stack trace collected |
| 13080 // on stack overflow or the already formatted stack trace string. | 13093 // on stack overflow or the already formatted stack trace string. |
| 13081 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOverflowedStackTrace) { | 13094 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOverflowStackTrace) { |
| 13082 HandleScope scope(isolate); | 13095 HandleScope scope(isolate); |
| 13083 ASSERT_EQ(args.length(), 1); | 13096 ASSERT_EQ(args.length(), 1); |
| 13084 CONVERT_ARG_CHECKED(JSObject, error_object, 0); | 13097 CONVERT_ARG_CHECKED(JSObject, error_object, 0); |
| 13085 String* key = isolate->heap()->hidden_stack_trace_symbol(); | 13098 String* key = isolate->heap()->overflow_stack_trace_symbol(); |
| 13086 Object* result = error_object->GetHiddenProperty(key); | 13099 Object* result = error_object->GetHiddenProperty(key); |
| 13087 RUNTIME_ASSERT(result->IsJSArray() || | 13100 RUNTIME_ASSERT(result->IsJSArray() || |
| 13088 result->IsString() || | 13101 result->IsString() || |
| 13102 result->IsJSObject() || |
| 13089 result->IsUndefined()); | 13103 result->IsUndefined()); |
| 13090 return result; | 13104 return result; |
| 13091 } | 13105 } |
| 13092 | 13106 |
| 13093 | 13107 |
| 13094 // Set or clear the stack trace attached to an stack overflow error object. | 13108 // Set or clear the stack trace attached to an stack overflow error object. |
| 13095 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetOverflowedStackTrace) { | 13109 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetOverflowStackTrace) { |
| 13096 HandleScope scope(isolate); | 13110 HandleScope scope(isolate); |
| 13097 ASSERT_EQ(args.length(), 2); | 13111 ASSERT_EQ(args.length(), 2); |
| 13098 CONVERT_ARG_HANDLE_CHECKED(JSObject, error_object, 0); | 13112 CONVERT_ARG_HANDLE_CHECKED(JSObject, error_object, 0); |
| 13099 CONVERT_ARG_HANDLE_CHECKED(HeapObject, value, 1); | 13113 CONVERT_ARG_HANDLE_CHECKED(HeapObject, value, 1); |
| 13100 Handle<String> key = isolate->factory()->hidden_stack_trace_symbol(); | 13114 Handle<String> key = isolate->factory()->overflow_stack_trace_symbol(); |
| 13101 if (value->IsUndefined()) { | 13115 if (value->IsUndefined()) { |
| 13102 error_object->DeleteHiddenProperty(*key); | 13116 error_object->DeleteHiddenProperty(*key); |
| 13103 } else { | 13117 } else { |
| 13104 RUNTIME_ASSERT(value->IsString()); | 13118 RUNTIME_ASSERT(value->IsString() || value->IsJSObject()); |
| 13105 JSObject::SetHiddenProperty(error_object, key, value); | 13119 JSObject::SetHiddenProperty(error_object, key, value); |
| 13106 } | 13120 } |
| 13107 return *error_object; | 13121 return *error_object; |
| 13108 } | 13122 } |
| 13109 | 13123 |
| 13110 | 13124 |
| 13111 // Returns V8 version as a string. | 13125 // Returns V8 version as a string. |
| 13112 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetV8Version) { | 13126 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetV8Version) { |
| 13113 ASSERT_EQ(args.length(), 0); | 13127 ASSERT_EQ(args.length(), 0); |
| 13114 | 13128 |
| (...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13519 // Handle last resort GC and make sure to allow future allocations | 13533 // Handle last resort GC and make sure to allow future allocations |
| 13520 // to grow the heap without causing GCs (if possible). | 13534 // to grow the heap without causing GCs (if possible). |
| 13521 isolate->counters()->gc_last_resort_from_js()->Increment(); | 13535 isolate->counters()->gc_last_resort_from_js()->Increment(); |
| 13522 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, | 13536 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, |
| 13523 "Runtime::PerformGC"); | 13537 "Runtime::PerformGC"); |
| 13524 } | 13538 } |
| 13525 } | 13539 } |
| 13526 | 13540 |
| 13527 | 13541 |
| 13528 } } // namespace v8::internal | 13542 } } // namespace v8::internal |
| OLD | NEW |