| Index: src/handles.cc
|
| diff --git a/src/handles.cc b/src/handles.cc
|
| index c0dea20aae3c09b6a98d3b4bd851e8fc15da140b..c8217d9481f462b2751ddf4322a8ba0b4fa73873 100644
|
| --- a/src/handles.cc
|
| +++ b/src/handles.cc
|
| @@ -632,6 +632,17 @@ static bool ContainsOnlyValidKeys(Handle<FixedArray> array) {
|
| }
|
|
|
|
|
| +
|
| +template
|
| +Handle<FixedArray> GetKeysInFixedArrayFor<true>(Handle<JSReceiver> object,
|
| + KeyCollectionType type,
|
| + bool* threw);
|
| +template
|
| +Handle<FixedArray> GetKeysInFixedArrayFor<false>(Handle<JSReceiver> object,
|
| + KeyCollectionType type,
|
| + bool* threw);
|
| +
|
| +template<bool allow_side_effect>
|
| Handle<FixedArray> GetKeysInFixedArrayFor(Handle<JSReceiver> object,
|
| KeyCollectionType type,
|
| bool* threw) {
|
| @@ -650,24 +661,28 @@ Handle<FixedArray> GetKeysInFixedArrayFor(Handle<JSReceiver> object,
|
| *p != isolate->heap()->null_value();
|
| p = Handle<Object>(p->GetPrototype(), isolate)) {
|
| if (p->IsJSProxy()) {
|
| - Handle<JSProxy> proxy(JSProxy::cast(*p), isolate);
|
| - Handle<Object> args[] = { proxy };
|
| - Handle<Object> names = Execution::Call(
|
| - isolate->proxy_enumerate(), object, ARRAY_SIZE(args), args, threw);
|
| - if (*threw) return content;
|
| - content = AddKeysFromJSArray(content, Handle<JSArray>::cast(names));
|
| + if (allow_side_effect) {
|
| + Handle<JSProxy> proxy(JSProxy::cast(*p), isolate);
|
| + Handle<Object> args[] = { proxy };
|
| + Handle<Object> names = Execution::Call(
|
| + isolate->proxy_enumerate(), object, ARRAY_SIZE(args), args, threw);
|
| + if (*threw) return content;
|
| + content = AddKeysFromJSArray(content, Handle<JSArray>::cast(names));
|
| + }
|
| break;
|
| }
|
|
|
| Handle<JSObject> current(JSObject::cast(*p), isolate);
|
|
|
| // Check access rights if required.
|
| - if (current->IsAccessCheckNeeded() &&
|
| - !isolate->MayNamedAccess(*current,
|
| - isolate->heap()->undefined_value(),
|
| - v8::ACCESS_KEYS)) {
|
| - isolate->ReportFailedAccessCheck(*current, v8::ACCESS_KEYS);
|
| - break;
|
| + if (current->IsAccessCheckNeeded()) {
|
| + if (!allow_side_effect) {
|
| + break;
|
| + } else if (!isolate->MayNamedAccess(
|
| + *current, isolate->heap()->undefined_value(), v8::ACCESS_KEYS)) {
|
| + isolate->ReportFailedAccessCheck(*current, v8::ACCESS_KEYS);
|
| + break;
|
| + }
|
| }
|
|
|
| // Compute the element keys.
|
| @@ -678,7 +693,7 @@ Handle<FixedArray> GetKeysInFixedArrayFor(Handle<JSReceiver> object,
|
| ASSERT(ContainsOnlyValidKeys(content));
|
|
|
| // Add the element keys from the interceptor.
|
| - if (current->HasIndexedInterceptor()) {
|
| + if (allow_side_effect && current->HasIndexedInterceptor()) {
|
| v8::Handle<v8::Array> result =
|
| GetKeysForIndexedInterceptor(object, current);
|
| if (!result.IsEmpty())
|
| @@ -708,7 +723,7 @@ Handle<FixedArray> GetKeysInFixedArrayFor(Handle<JSReceiver> object,
|
| ASSERT(ContainsOnlyValidKeys(content));
|
|
|
| // Add the property keys from the interceptor.
|
| - if (current->HasNamedInterceptor()) {
|
| + if (allow_side_effect && current->HasNamedInterceptor()) {
|
| v8::Handle<v8::Array> result =
|
| GetKeysForNamedInterceptor(object, current);
|
| if (!result.IsEmpty())
|
| @@ -718,22 +733,12 @@ Handle<FixedArray> GetKeysInFixedArrayFor(Handle<JSReceiver> object,
|
|
|
| // If we only want local properties we bail out after the first
|
| // iteration.
|
| - if (type == LOCAL_ONLY)
|
| - break;
|
| + if (type == LOCAL_ONLY) break;
|
| }
|
| return content;
|
| }
|
|
|
|
|
| -Handle<JSArray> GetKeysFor(Handle<JSReceiver> object, bool* threw) {
|
| - Isolate* isolate = object->GetIsolate();
|
| - isolate->counters()->for_in()->Increment();
|
| - Handle<FixedArray> elements =
|
| - GetKeysInFixedArrayFor(object, INCLUDE_PROTOS, threw);
|
| - return isolate->factory()->NewJSArrayWithElements(elements);
|
| -}
|
| -
|
| -
|
| Handle<FixedArray> ReduceFixedArrayTo(Handle<FixedArray> array, int length) {
|
| ASSERT(array->length() >= length);
|
| if (array->length() == length) return array;
|
|
|