Chromium Code Reviews| Index: src/ia32/full-codegen-ia32.cc |
| diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc |
| index 33d5cabad7ebb0bb90bb91093b621ddeca16423f..9e364eb28e4359e39f1a16de51694b9842e7087d 100644 |
| --- a/src/ia32/full-codegen-ia32.cc |
| +++ b/src/ia32/full-codegen-ia32.cc |
| @@ -920,11 +920,17 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { |
| __ push(eax); |
| increment_stack_height(); |
| + // Check for proxies. |
| + Label call_runtime; |
| + STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); |
| + __ CmpObjectType(eax, LAST_JS_PROXY_TYPE, ecx); |
| + __ j(below_equal, &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; |
| __ mov(ecx, eax); |
| __ bind(&next); |
| @@ -995,8 +1001,16 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { |
| __ jmp(&loop); |
| // We got a fixed array in register eax. Iterate through that. |
| + Label non_proxy; |
| __ bind(&fixed_array); |
| - __ push(Immediate(Smi::FromInt(0))); // Map (0) - force slow check. |
| + __ mov(ebx, Immediate(Smi::FromInt(1))); // smi indicates slow check |
| + __ mov(ecx, Operand(esp, 0 * kPointerSize)); // Get enumerated object |
| + STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); |
| + __ CmpObjectType(ecx, LAST_JS_PROXY_TYPE, ecx); |
| + __ j(above, &non_proxy); |
| + __ mov(ebx, Immediate(Smi::FromInt(0))); // zero indicates proxy |
| + __ bind(&non_proxy); |
| + __ push(ebx); // map or smi |
| __ push(eax); |
|
Rico
2011/10/20 14:25:31
Add comment about what eax is
rossberg
2011/10/24 13:31:35
Done.
|
| __ mov(eax, FieldOperand(eax, FixedArray::kLengthOffset)); |
| __ push(eax); // Fixed array length (as smi). |
| @@ -1014,17 +1028,23 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { |
| __ mov(ebx, Operand(esp, 2 * kPointerSize)); |
| __ mov(ebx, FieldOperand(ebx, eax, times_2, FixedArray::kHeaderSize)); |
| - // 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 edx. |
| __ mov(edx, Operand(esp, 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; |
| __ mov(ecx, Operand(esp, 4 * kPointerSize)); |
| __ cmp(edx, FieldOperand(ecx, HeapObject::kMapOffset)); |
| __ j(equal, &update_each, Label::kNear); |
| + // For proxies, no filtering is done. |
| + // TODO(rossberg): What if only a prototype is a proxy? Not specified. |
| + ASSERT(Smi::FromInt(0) == 0); |
| + __ test(edx, edx); |
| + __ j(zero, &update_each); |
| + |
| // Convert the entry to a string or null if it isn't a property |
| // anymore. If the property has been removed while iterating, we |
| // just skip it. |