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

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: Addressed Rico's comments. 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
« no previous file with comments | « src/proxy.js ('k') | src/runtime.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 4731 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/proxy.js ('k') | src/runtime.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698