 Chromium Code Reviews
 Chromium Code Reviews Issue 8256015:
  Implement for-in loop for proxies.  (Closed) 
  Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
    
  
    Issue 8256015:
  Implement for-in loop for proxies.  (Closed) 
  Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge| Index: src/x64/full-codegen-x64.cc | 
| diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc | 
| index b5c5fc5e719181cd283573cea7d95acd7279dbb2..1129f6573ef28677f191379cdbda9e541da72766 100644 | 
| --- a/src/x64/full-codegen-x64.cc | 
| +++ b/src/x64/full-codegen-x64.cc | 
| @@ -890,11 +890,17 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { | 
| __ bind(&done_convert); | 
| __ push(rax); | 
| + // Check for proxies. | 
| + Label call_runtime; | 
| + STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); | 
| + __ CmpObjectType(rax, LAST_JS_PROXY_TYPE, rcx); | 
| + __ 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; | 
| Register empty_fixed_array_value = r8; | 
| __ LoadRoot(empty_fixed_array_value, Heap::kEmptyFixedArrayRootIndex); | 
| Register empty_descriptor_array_value = r9; | 
| @@ -970,8 +976,16 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { | 
| __ jmp(&loop); | 
| // We got a fixed array in register rax. Iterate through that. | 
| + Label non_proxy; | 
| __ bind(&fixed_array); | 
| - __ Push(Smi::FromInt(0)); // Map (0) - force slow check. | 
| + __ Move(rbx, Smi::FromInt(1)); // smi indicates slow check | 
| + __ movq(rcx, Operand(rsp, 0 * kPointerSize)); // Get enumerated object | 
| + STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); | 
| + __ CmpObjectType(rcx, LAST_JS_PROXY_TYPE, rcx); | 
| + __ j(above, &non_proxy); | 
| + __ Move(rbx, Smi::FromInt(0)); // zero indicates proxy | 
| + __ bind(&non_proxy); | 
| + __ push(rbx); // map or smi | 
| __ push(rax); | 
| 
Rico
2011/10/20 14:25:31
Add comment about what rax is
 
rossberg
2011/10/24 13:31:35
Done.
 | 
| __ movq(rax, FieldOperand(rax, FixedArray::kLengthOffset)); | 
| __ push(rax); // Fixed array length (as smi). | 
| @@ -991,17 +1005,22 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { | 
| index.scale, | 
| 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 rdx. | 
| __ movq(rdx, Operand(rsp, 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; | 
| __ movq(rcx, Operand(rsp, 4 * kPointerSize)); | 
| __ cmpq(rdx, FieldOperand(rcx, 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. | 
| + __ Cmp(rdx, Smi::FromInt(0)); | 
| + __ j(equal, &update_each, Label::kNear); | 
| + | 
| // 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. |