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

Side by Side Diff: src/runtime.cc

Issue 8256015: Implement for-in loop for proxies. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Activate test cases that relied on for-in. Created 9 years, 2 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
OLDNEW
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698