Browse Source

Implementing Array.prototype.push and Array.prototype.pop

Sebastien Ros 12 years ago
parent
commit
fff4c4f0a0

+ 1 - 1
Jint/Native/Array/ArrayInstance.cs

@@ -34,7 +34,7 @@ namespace Jint.Native.Array
                 }
                 }
                 
                 
                 var newLenDesc = new DataDescriptor(desc);
                 var newLenDesc = new DataDescriptor(desc);
-                double newLen = TypeConverter.ToUint32(descData.Value);
+                uint newLen = TypeConverter.ToUint32(descData.Value);
                 if (newLen != TypeConverter.ToNumber(descData.Value))
                 if (newLen != TypeConverter.ToNumber(descData.Value))
                 {
                 {
                     throw new JavaScriptException(_engine.RangeError);
                     throw new JavaScriptException(_engine.RangeError);

+ 11 - 7
Jint/Native/Array/ArrayPrototype.cs

@@ -37,8 +37,8 @@ namespace Jint.Native.Array
             FastAddProperty("toLocaleString", new ClrFunctionInstance<object, object>(Engine, ToLocaleString), true, false, true);
             FastAddProperty("toLocaleString", new ClrFunctionInstance<object, object>(Engine, ToLocaleString), true, false, true);
             FastAddProperty("concat", new ClrFunctionInstance<object, object>(Engine, Concat, 1), true, false, true);
             FastAddProperty("concat", new ClrFunctionInstance<object, object>(Engine, Concat, 1), true, false, true);
             FastAddProperty("join", new ClrFunctionInstance<object, object>(Engine, Join, 1), true, false, true);
             FastAddProperty("join", new ClrFunctionInstance<object, object>(Engine, Join, 1), true, false, true);
-            FastAddProperty("pop", new ClrFunctionInstance<ArrayInstance, object>(Engine, Pop), true, false, true);
-            FastAddProperty("push", new ClrFunctionInstance<ArrayInstance, object>(Engine, Push, 1), true, false, true);
+            FastAddProperty("pop", new ClrFunctionInstance<object, object>(Engine, Pop), true, false, true);
+            FastAddProperty("push", new ClrFunctionInstance<object, object>(Engine, Push, 1), true, false, true);
             FastAddProperty("reverse", new ClrFunctionInstance<object, object>(Engine, Reverse), true, false, true);
             FastAddProperty("reverse", new ClrFunctionInstance<object, object>(Engine, Reverse), true, false, true);
             FastAddProperty("shift", new ClrFunctionInstance<ArrayInstance, object>(Engine, Shift), true, false, true);
             FastAddProperty("shift", new ClrFunctionInstance<ArrayInstance, object>(Engine, Shift), true, false, true);
             FastAddProperty("slice", new ClrFunctionInstance<ArrayInstance, object>(Engine, Slice, 2), true, false, true);
             FastAddProperty("slice", new ClrFunctionInstance<ArrayInstance, object>(Engine, Slice, 2), true, false, true);
@@ -272,14 +272,17 @@ namespace Jint.Native.Array
         {
         {
             ObjectInstance o = TypeConverter.ToObject(Engine, thisObject);
             ObjectInstance o = TypeConverter.ToObject(Engine, thisObject);
             object lenVal = o.Get("length");
             object lenVal = o.Get("length");
-            uint n = TypeConverter.ToUint32(lenVal);
+            
+            // cast to double as we need to prevent an overflow
+            double n = TypeConverter.ToUint32(lenVal);
             foreach (object e in arguments)
             foreach (object e in arguments)
             {
             {
-                o.DefineOwnProperty(TypeConverter.ToString(n), new DataDescriptor(e){Configurable = true, Enumerable = true, Writable = true}, true);
+                o.Put(TypeConverter.ToString(n), e, true);
                 n++;
                 n++;
             }
             }
-            o.Put("length", n, true);
 
 
+            o.Put("length", n, true);
+            
             return n;
             return n;
         }
         }
 
 
@@ -295,10 +298,11 @@ namespace Jint.Native.Array
             }
             }
             else
             else
             {
             {
-                string indx = TypeConverter.ToString(len - 1);
+                len = len - 1;
+                string indx = TypeConverter.ToString(len);
                 object element = o.Get(indx);
                 object element = o.Get(indx);
                 o.Delete(indx, true);
                 o.Delete(indx, true);
-                o.Put("length", indx, true);
+                o.Put("length", len, true);
                 return element;
                 return element;
             }
             }
         }
         }

+ 4 - 19
Jint/Native/Object/ObjectInstance.cs

@@ -156,23 +156,8 @@ namespace Jint.Native.Object
 
 
             if (ownDesc.IsDataDescriptor())
             if (ownDesc.IsDataDescriptor())
             {
             {
-                /* Spec implementation 
-                 * var valueDesc = new DataDescriptor(value);
-                 * DefineOwnProperty(propertyName, valueDesc, throwOnError);
-                 */
-
-                // optimized implementation which doesn't require to create a new descriptor
-                if (!ownDesc.Configurable)
-                {
-                    if (throwOnError)
-                    {
-                        throw new JavaScriptException(Engine.TypeError);
-                    }
-
-                    return;
-                }
-
-                ownDesc.As<DataDescriptor>().Value = value;
+                var valueDesc = new DataDescriptor(value) { Writable = true, Enumerable = true, Configurable = true };
+                DefineOwnProperty(propertyName, valueDesc, throwOnError);
                 return;
                 return;
             }
             }
 
 
@@ -388,11 +373,11 @@ namespace Jint.Native.Object
                 {
                 {
                     if (desc.IsGenericDescriptor() || desc.IsDataDescriptor())
                     if (desc.IsGenericDescriptor() || desc.IsDataDescriptor())
                     {
                     {
-                        Properties.Add(propertyName, new DataDescriptor(desc.As<DataDescriptor>()));
+                        Properties[propertyName] = new DataDescriptor(desc.As<DataDescriptor>());
                     }
                     }
                     else
                     else
                     {
                     {
-                        Properties.Add(propertyName, new AccessorDescriptor(desc.As<AccessorDescriptor>()));
+                        Properties[propertyName] = new AccessorDescriptor(desc.As<AccessorDescriptor>());
                     }
                     }
                 }
                 }
 
 

+ 4 - 3
Jint/Runtime/StatementInterpreter.cs

@@ -208,14 +208,15 @@ namespace Jint.Runtime
 
 
             var obj = TypeConverter.ToObject(_engine, experValue);
             var obj = TypeConverter.ToObject(_engine, experValue);
             object v = null;
             object v = null;
-            foreach (var entry in obj.Properties)
+            var keys = obj.Properties.Keys.ToArray();
+            foreach (var p in keys)
             {
             {
-                if (!entry.Value.Enumerable)
+                var value = obj.Properties[p];
+                if (!value.Enumerable)
                 {
                 {
                     continue;
                     continue;
                 }
                 }
 
 
-                var p = entry.Key;
                 _engine.PutValue(varRef, p);
                 _engine.PutValue(varRef, p);
 
 
                 var stmt = ExecuteStatement(forInStatement.Body);
                 var stmt = ExecuteStatement(forInStatement.Body);