Chromium Code Reviews| Index: src/arm/full-codegen-arm.cc |
| diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc |
| index 353ce5b10646e2bd79319612be07a85bbc632b6c..7caf8d80c579190a59606447c5e59ee4db64d187 100644 |
| --- a/src/arm/full-codegen-arm.cc |
| +++ b/src/arm/full-codegen-arm.cc |
| @@ -929,11 +929,17 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { |
| __ bind(&done_convert); |
| __ push(r0); |
| + // Check for proxies. |
| + Label call_runtime; |
| + STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); |
| + __ CompareObjectType(r0, r1, r1, LAST_JS_PROXY_TYPE); |
| + __ b(le, &call_runtime); |
| + |
| // Check cache validity in generated code. This is a fast case for |
| // the JSObject::IsSimpleEnum cache validity checks. If we cannot |
| // guarantee cache validity, call the runtime system to check cache |
| // validity or get the property names in a fixed array. |
| - Label next, call_runtime; |
| + Label next; |
| // Preload a couple of values used in the loop. |
| Register empty_fixed_array_value = r6; |
| __ LoadRoot(empty_fixed_array_value, Heap::kEmptyFixedArrayRootIndex); |
| @@ -1012,9 +1018,16 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { |
| __ jmp(&loop); |
| // We got a fixed array in register r0. Iterate through that. |
| + Label non_proxy; |
| __ bind(&fixed_array); |
| - __ mov(r1, Operand(Smi::FromInt(0))); // Map (0) - force slow check. |
| - __ Push(r1, r0); |
| + __ mov(r1, Operand(Smi::FromInt(1))); // smi indicates slow check |
|
Rico
2011/10/20 14:25:31
Capitalize start of comment + below
rossberg
2011/10/24 13:31:35
Done.
|
| + __ ldr(r2, MemOperand(sp, 0 * kPointerSize)); // Get enumerated object |
| + STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); |
| + __ CompareObjectType(r2, r3, r3, LAST_JS_PROXY_TYPE); |
| + __ b(gt, &non_proxy); |
| + __ mov(r1, Operand(Smi::FromInt(0))); // zero indicates proxy |
| + __ bind(&non_proxy); |
| + __ Push(r1, r0); // map or smi, and array |
|
Rico
2011/10/20 14:25:31
how can r1 be a map, we either load smi 1 or smi 0
rossberg
2011/10/24 13:31:35
Done.
|
| __ ldr(r1, FieldMemOperand(r0, FixedArray::kLengthOffset)); |
| __ mov(r0, Operand(Smi::FromInt(0))); |
| __ Push(r1, r0); // Fixed array length (as smi) and initial index. |
| @@ -1031,18 +1044,23 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { |
| __ add(r2, r2, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); |
| __ ldr(r3, MemOperand(r2, r0, LSL, kPointerSizeLog2 - kSmiTagSize)); |
| - // Get the expected map from the stack or a zero map in the |
| + // Get the expected map from the stack or a smi in the |
| // permanent slow case into register r2. |
| __ ldr(r2, MemOperand(sp, 3 * kPointerSize)); |
| // Check if the expected map still matches that of the enumerable. |
| - // If not, we have to filter the key. |
| + // If not, we may have to filter the key. |
| Label update_each; |
| __ ldr(r1, MemOperand(sp, 4 * kPointerSize)); |
| __ ldr(r4, FieldMemOperand(r1, HeapObject::kMapOffset)); |
| __ cmp(r4, Operand(r2)); |
| __ b(eq, &update_each); |
| + // For proxies, no filtering is done. |
| + // TODO(rossberg): What if only a prototype is a proxy? Not specified. |
|
Rico
2011/10/20 14:25:31
Please file a bug
rossberg
2011/10/24 13:31:35
Will note it in bug v8:1543.
|
| + __ cmp(r2, Operand(Smi::FromInt(0))); |
| + __ b(eq, &update_each); |
| + |
| // Convert the entry to a string or (smi) 0 if it isn't a property |
| // any more. If the property has been removed while iterating, we |
| // just skip it. |