Browse Source

Fixing for-in statement

Now processed prototypes chain
Sebastien Ros 11 years ago
parent
commit
1b1b5ebd7d
1 changed files with 42 additions and 25 deletions
  1. 42 25
      Jint/Runtime/StatementInterpreter.cs

+ 42 - 25
Jint/Runtime/StatementInterpreter.cs

@@ -2,6 +2,7 @@
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Linq;
 using System.Linq;
 using Jint.Native;
 using Jint.Native;
+using Jint.Native.Object;
 using Jint.Parser.Ast;
 using Jint.Parser.Ast;
 using Jint.Runtime.Environments;
 using Jint.Runtime.Environments;
 using Jint.Runtime.References;
 using Jint.Runtime.References;
@@ -220,40 +221,56 @@ namespace Jint.Runtime
 
 
             var obj = TypeConverter.ToObject(_engine, experValue);
             var obj = TypeConverter.ToObject(_engine, experValue);
             object v = null;
             object v = null;
-            var keys = obj.Properties.Keys.ToArray();
-            foreach (var p in keys)
+            
+            // keys are constructed using the prototype chain
+            var cursor = obj;
+            var processedKeys = new HashSet<string>();
+
+            while (cursor != null)
             {
             {
-                // collection might be modified by inner statement 
-                if (!obj.Properties.ContainsKey(p))
+                var keys = cursor.Properties.Keys.ToArray();
+                foreach (var p in keys)
                 {
                 {
-                    continue;
-                }
+                    if (processedKeys.Contains(p))
+                    {
+                        continue;
+                    }
 
 
-                var value = obj.Properties[p];
-                if (!value.EnumerableIsSet)
-                {
-                    continue;
-                }
+                    processedKeys.Add(p);
+                    
+                    // collection might be modified by inner statement 
+                    if (!cursor.Properties.ContainsKey(p))
+                    {
+                        continue;
+                    }
 
 
-                _engine.PutValue(varRef, p);
+                    var value = cursor.Properties[p];
+                    if (!value.EnumerableIsSet)
+                    {
+                        continue;
+                    }
 
 
-                var stmt = ExecuteStatement(forInStatement.Body);
-                if (stmt.Value != null)
-                {
-                    v = stmt.Value;
-                }
-                if (stmt.Type == Completion.Break /* todo: complete */)
-                {
-                    return new Completion(Completion.Normal, v, null);
-                }
-                if (stmt.Type != Completion.Continue /* todo: complete */)
-                {
-                    if (stmt.Type != Completion.Normal)
+                    _engine.PutValue(varRef, p);
+
+                    var stmt = ExecuteStatement(forInStatement.Body);
+                    if (stmt.Value != null)
                     {
                     {
-                        return stmt;
+                        v = stmt.Value;
+                    }
+                    if (stmt.Type == Completion.Break /* todo: complete */)
+                    {
+                        return new Completion(Completion.Normal, v, null);
+                    }
+                    if (stmt.Type != Completion.Continue /* todo: complete */)
+                    {
+                        if (stmt.Type != Completion.Normal)
+                        {
+                            return stmt;
+                        }
                     }
                     }
                 }
                 }
 
 
+                cursor = cursor.Prototype;
             }
             }
 
 
             return new Completion(Completion.Normal, v, null);
             return new Completion(Completion.Normal, v, null);