Bläddra i källkod

Fixing all unit test for Array.prototype

Sebastien Ros 12 år sedan
förälder
incheckning
1427db5177

+ 9 - 4
Jint/Native/Array/ArrayConstructor.cs

@@ -33,7 +33,7 @@ namespace Jint.Native.Array
 
         public void Configure()
         {
-            FastAddProperty("isArray", new ClrFunctionInstance<object, object>(Engine, IsArray), true, false, true);
+            FastAddProperty("isArray", new ClrFunctionInstance<object, object>(Engine, IsArray, 1), true, false, true);
         }
 
         private object IsArray(object thisObj, object[] arguments)
@@ -58,15 +58,20 @@ namespace Jint.Native.Array
             instance.Prototype = PrototypeObject;
             instance.Extensible = true;
 
-            if (arguments.Length == 1 && TypeConverter.GetType(arguments[0]) == TypeCode.Double)
+            if (arguments.Length == 1 && TypeConverter.GetType(arguments[0]) == Types.Number)
             {
-                var length = TypeConverter.ToNumber(arguments[0]);
+                var length = TypeConverter.ToUint32(arguments[0]);
+                if (TypeConverter.ToNumber(arguments[0]) != length)
+                {
+                    throw new JavaScriptException(Engine.RangeError);
+                }
+                
                 instance.FastAddProperty("length", length, true, false, true);
             }
             else
             {
                 instance.FastAddProperty("length", 0, true, false, true);
-                ((ArrayPrototype)PrototypeObject).Push(instance, arguments);
+                PrototypeObject.Push(instance, arguments);
             }
 
             return instance;

+ 16 - 13
Jint/Native/Array/ArrayPrototype.cs

@@ -45,8 +45,8 @@ namespace Jint.Native.Array
             FastAddProperty("sort", new ClrFunctionInstance<object, ObjectInstance>(Engine, Sort, 1), true, false, true);
             FastAddProperty("splice", new ClrFunctionInstance<object, ObjectInstance>(Engine, Splice, 2), true, false, true);
             FastAddProperty("unshift", new ClrFunctionInstance<object, uint>(Engine, Unshift, 1), true, false, true);
-            FastAddProperty("indexOf", new ClrFunctionInstance<object, int>(Engine, IndexOf, 1), true, false, true);
-            FastAddProperty("lastIndexOf", new ClrFunctionInstance<object, int>(Engine, LastIndexOf, 1), true, false, true);
+            FastAddProperty("indexOf", new ClrFunctionInstance<object, double>(Engine, IndexOf, 1), true, false, true);
+            FastAddProperty("lastIndexOf", new ClrFunctionInstance<object, double>(Engine, LastIndexOf, 1), true, false, true);
             FastAddProperty("every", new ClrFunctionInstance<object, bool>(Engine, Every, 1), true, false, true);
             FastAddProperty("some", new ClrFunctionInstance<object, bool>(Engine, Some, 1), true, false, true);
             FastAddProperty("forEach", new ClrFunctionInstance<object, object>(Engine, ForEach, 1), true, false, true);
@@ -56,7 +56,7 @@ namespace Jint.Native.Array
             FastAddProperty("reduceRight", new ClrFunctionInstance<object, object>(Engine, ReduceRight, 1), true, false, true);
         }
 
-        private int LastIndexOf(object thisObj, object[] arguments)
+        private double LastIndexOf(object thisObj, object[] arguments)
         {
             var o = TypeConverter.ToObject(Engine, thisObj);
             var lenValue = o.Get("length");
@@ -66,18 +66,18 @@ namespace Jint.Native.Array
                 return -1;
             }
 
-            var n = arguments.Length > 1 ? (int)TypeConverter.ToInteger(arguments[1]) : (int)len - 1;
-            int k;
+            var n = arguments.Length > 1 ? TypeConverter.ToInteger(arguments[1]) : len - 1;
+            double k;
             if (n >= 0)
             {
-                k = System.Math.Min(n, (int)len - 1); // min
+                k = System.Math.Min(n, len - 1); // min
             }
             else
             {
-                k = (int)len - System.Math.Abs(n);
+                k = len - System.Math.Abs(n);
             }
             var searchElement = arguments.Length > 0 ? arguments[0] : Undefined.Instance;
-            for (; k > 0; k--)
+            for (; k >= 0; k--)
             {
                 var kString = TypeConverter.ToString(k);
                 var kPresent = o.HasProperty(kString);
@@ -206,7 +206,7 @@ namespace Jint.Native.Array
                 throw new JavaScriptException(Engine.TypeError, "Argument must be callable");
             }
 
-            var a = (ArrayInstance)Engine.Array.Construct(Arguments.Empty);
+            var a = (ArrayInstance)Engine.Array.Construct(new object[] {len});
 
             for (var k = 0; k < len; k++)
             {
@@ -318,7 +318,7 @@ namespace Jint.Native.Array
             return true;
         }
 
-        private int IndexOf(object thisObj, object[] arguments)
+        private double IndexOf(object thisObj, object[] arguments)
         {
             var o = TypeConverter.ToObject(Engine, thisObj);
             var lenValue = o.Get("length");
@@ -328,19 +328,19 @@ namespace Jint.Native.Array
                 return -1;
             }
 
-            var n = arguments.Length > 1 ? (int)TypeConverter.ToInteger(arguments[1]) : 0;
+            var n = arguments.Length > 1 ? TypeConverter.ToInteger(arguments[1]) : 0;
             if (n >= len)
             {
                 return -1;
             }
-            int k;
+            double k;
             if (n >= 0)
             {
                 k = n;
             }
             else
             {
-                k = (int)len - System.Math.Abs(n);
+                k = len - System.Math.Abs(n);
                 if (k < 0)
                 {
                     k = 0;
@@ -801,6 +801,9 @@ namespace Jint.Native.Array
                     n++;
                 }
             }
+
+            a.DefineOwnProperty("length", new DataDescriptor(n), false);
+            
             return a;
         }
 

+ 3 - 2
Jint/Native/Boolean/BooleanInstance.cs

@@ -1,5 +1,6 @@
 using System;
 using Jint.Native.Object;
+using Jint.Runtime;
 
 namespace Jint.Native.Boolean
 {
@@ -18,9 +19,9 @@ namespace Jint.Native.Boolean
             }
         }
 
-        TypeCode IPrimitiveType.TypeCode
+        Types IPrimitiveType.Type
         {
-            get { return TypeCode.Boolean; }
+            get { return Types.Boolean; }
         }
 
         object IPrimitiveType.PrimitiveValue

+ 1 - 1
Jint/Native/Boolean/BooleanPrototype.cs

@@ -36,7 +36,7 @@ namespace Jint.Native.Boolean
         {
             var B = thisObj;
             object b;
-            if (TypeConverter.GetType(B) == TypeCode.Boolean)
+            if (TypeConverter.GetType(B) == Types.Boolean)
             {
                 b = B;
             }

+ 1 - 1
Jint/Native/Date/DateConstructor.cs

@@ -72,7 +72,7 @@ namespace Jint.Native.Date
             else if (arguments.Length == 1)
             {
                 var v = TypeConverter.ToPrimitive(arguments[0]);
-                if (TypeConverter.GetType(v) == TypeCode.String)
+                if (TypeConverter.GetType(v) == Types.String)
                 {
                     var d = DateTime.Parse(TypeConverter.ToString(v));
                     return Construct(d);

+ 3 - 2
Jint/Native/Date/DateInstance.cs

@@ -1,5 +1,6 @@
 using System;
 using Jint.Native.Object;
+using Jint.Runtime;
 
 namespace Jint.Native.Date
 {
@@ -24,9 +25,9 @@ namespace Jint.Native.Date
             }
         }
 
-        TypeCode IPrimitiveType.TypeCode
+        Types IPrimitiveType.Type
         {
-            get { return TypeCode.DateTime; }
+            get { return Types.Number; }
         }
 
         object IPrimitiveType.PrimitiveValue

+ 1 - 0
Jint/Native/Function/FunctionPrototype.cs

@@ -19,6 +19,7 @@ namespace Jint.Native.Function
         public static FunctionPrototype CreatePrototypeObject(Engine engine)
         {
             var obj = new FunctionPrototype(engine);
+            obj.Extensible = true;
 
             // The value of the [[Prototype]] internal property of the Function prototype object is the standard built-in Object prototype object
             obj.Prototype = engine.Object.PrototypeObject;

+ 3 - 3
Jint/Native/Function/ScriptFunctionInstance.cs

@@ -37,7 +37,7 @@ namespace Jint.Native.Function
 
             var proto = engine.Object.Construct(Arguments.Empty);
             proto.DefineOwnProperty("constructor", new DataDescriptor(this) { Writable = true, Enumerable = false, Configurable = true }, false);
-            DefineOwnProperty("prototype", new DataDescriptor(proto) { Writable = true, Enumerable = false, Configurable = false }, false);
+            DefineOwnProperty("prototype", new DataDescriptor(proto) { Writable = true, Enumerable = false, Configurable = true }, false);
 
             DefineOwnProperty("name", new DataDescriptor(_functionDeclaration.Id), false);
             
@@ -68,7 +68,7 @@ namespace Jint.Native.Function
             {
                 thisBinding = Engine.Global;
             }
-            else if (TypeConverter.GetType(thisArg) != TypeCode.Object)
+            else if (TypeConverter.GetType(thisArg) != Types.Object)
             {
                 thisBinding = TypeConverter.ToObject(Engine, thisArg);
             }
@@ -157,7 +157,7 @@ namespace Jint.Native.Function
             var proto = Get("prototype") as ObjectInstance;
             var obj = new ObjectInstance(Engine);
             obj.Extensible = true;
-            obj.Prototype = proto ?? Engine.Object;
+            obj.Prototype = proto ?? Engine.Object.PrototypeObject;
 
             var result = Call(obj, arguments) as ObjectInstance;
             if (result != null)

+ 2 - 2
Jint/Native/IPrimitiveType.cs

@@ -1,10 +1,10 @@
-using System;
+using Jint.Runtime;
 
 namespace Jint.Native
 {
     public interface IPrimitiveType
     {
-        TypeCode TypeCode { get; } 
+        Types Type { get; } 
         object PrimitiveValue { get; }
     }
 }

+ 9 - 9
Jint/Native/Json/JsonSerializer.cs

@@ -27,7 +27,7 @@ namespace Jint.Native.Json
         {
             _stack = new Stack<object>();
 
-            if (TypeConverter.GetType(replacer) == TypeCode.Object)
+            if (TypeConverter.GetType(replacer) == Types.Object)
             {
                 if (replacer is ICallable)
                 {
@@ -46,15 +46,15 @@ namespace Jint.Native.Json
                         object v = _engine.GetValue(property);
                         string item = null;
                         var type = TypeConverter.GetType(v);
-                        if (type == TypeCode.String)
+                        if (type == Types.String)
                         {
                             item = (string)v;
                         }
-                        else if (type == TypeCode.Double)
+                        else if (type == Types.Number)
                         {
                             item = TypeConverter.ToString(v);
                         }
-                        else if(type == TypeCode.Object)
+                        else if (type == Types.Object)
                         {
                             var propertyObj = (ObjectInstance) v;
                             if (propertyObj.Class == "String" || propertyObj.Class == "Number")
@@ -86,11 +86,11 @@ namespace Jint.Native.Json
             }
 
             // defining the gap
-            if (TypeConverter.GetType(space) == TypeCode.Double)
+            if (TypeConverter.GetType(space) == Types.Number)
             {
                 _gap = new System.String(' ', (int) System.Math.Min(10, (double) space));
-            } 
-            else if (TypeConverter.GetType(space) == TypeCode.String)
+            }
+            else if (TypeConverter.GetType(space) == Types.String)
             {
                 var stringSpace = (string) space;
                 _gap = stringSpace.Length <= 10 ? stringSpace : stringSpace.Substring(0, 10);
@@ -163,12 +163,12 @@ namespace Jint.Native.Json
                 return "false";
             }
 
-            if (TypeConverter.GetType(value) == TypeCode.String)
+            if (TypeConverter.GetType(value) == Types.String)
             {
                 return Quote((string) value);
             }
 
-            if (TypeConverter.GetType(value) == TypeCode.Double)
+            if (TypeConverter.GetType(value) == Types.Number)
             {
                 if (GlobalObject.IsFinite(this, Arguments.From(value)))
                 {

+ 3 - 2
Jint/Native/Null.cs

@@ -1,4 +1,5 @@
 using System;
+using Jint.Runtime;
 
 namespace Jint.Native
 {
@@ -15,9 +16,9 @@ namespace Jint.Native
             return "null";
         }
 
-        public TypeCode TypeCode
+        public Types Type
         {
-            get { return TypeCode.Empty; }
+            get { return Types.Null; }
         }
 
         public object PrimitiveValue

+ 3 - 2
Jint/Native/Number/NumberInstance.cs

@@ -1,5 +1,6 @@
 using System;
 using Jint.Native.Object;
+using Jint.Runtime;
 
 namespace Jint.Native.Number
 {
@@ -20,9 +21,9 @@ namespace Jint.Native.Number
             }
         }
 
-        TypeCode IPrimitiveType.TypeCode
+        Types IPrimitiveType.Type
         {
-            get { return TypeCode.Double; }
+            get { return Types.Number; }
         }
 
         object IPrimitiveType.PrimitiveValue

+ 22 - 20
Jint/Native/Object/ObjectConstructor.cs

@@ -88,7 +88,7 @@ namespace Jint.Native.Object
                     return valueObj;
                 }
                 var type = TypeConverter.GetType(value);
-                if (type == TypeCode.String || type == TypeCode.Double || type == TypeCode.Boolean)
+                if (type == Types.String || type == Types.Number || type == Types.Boolean)
                 {
                     return TypeConverter.ToObject(_engine, value);
                 }
@@ -106,7 +106,7 @@ namespace Jint.Native.Object
         public object GetPrototypeOf(object thisObject, object[] arguments)
         {
             var oArg = arguments.Length > 0 ? arguments[0] : Undefined.Instance;
-            if (TypeConverter.GetType(oArg) != TypeCode.Object)
+            if (TypeConverter.GetType(oArg) != Types.Object)
             {
                 throw new JavaScriptException(Engine.TypeError);
             }
@@ -119,7 +119,7 @@ namespace Jint.Native.Object
         public object GetOwnPropertyDescriptor(object thisObject, object[] arguments)
         {
             var oArg = arguments.Length > 0 ? arguments[0] : Undefined.Instance;
-            if (TypeConverter.GetType(oArg) != TypeCode.Object)
+            if (TypeConverter.GetType(oArg) != Types.Object)
             {
                 throw new JavaScriptException(Engine.TypeError);
             }
@@ -136,7 +136,7 @@ namespace Jint.Native.Object
         public object GetOwnPropertyNames(object thisObject, object[] arguments)
         {
             var oArg = arguments.Length > 0 ? arguments[0] : Undefined.Instance;
-            if (TypeConverter.GetType(oArg) != TypeCode.Object)
+            if (TypeConverter.GetType(oArg) != Types.Object)
             {
                 throw new JavaScriptException(Engine.TypeError);
             }
@@ -157,7 +157,7 @@ namespace Jint.Native.Object
         public object Create(object thisObject, object[] arguments)
         {
             var oArg = arguments.Length > 0 ? arguments[0] : Undefined.Instance;
-            if (TypeConverter.GetType(oArg) != TypeCode.Object)
+            if (TypeConverter.GetType(oArg) != Types.Object)
             {
                 throw new JavaScriptException(Engine.TypeError);
             }
@@ -199,7 +199,7 @@ namespace Jint.Native.Object
         public object DefineProperties(object thisObject, object[] arguments)
         {
             var oArg = arguments.Length > 0 ? arguments[0] : Undefined.Instance;
-            if (TypeConverter.GetType(oArg) != TypeCode.Object)
+            if (TypeConverter.GetType(oArg) != Types.Object)
             {
                 throw new JavaScriptException(Engine.TypeError);
             }
@@ -227,7 +227,7 @@ namespace Jint.Native.Object
         public object Seal(object thisObject, object[] arguments)
         {
             var oArg = arguments.Length > 0 ? arguments[0] : Undefined.Instance;
-            if (TypeConverter.GetType(oArg) != TypeCode.Object)
+            if (TypeConverter.GetType(oArg) != Types.Object)
             {
                 throw new JavaScriptException(Engine.TypeError);
             }
@@ -252,28 +252,30 @@ namespace Jint.Native.Object
         public object Freeze(object thisObject, object[] arguments)
         {
             var oArg = arguments.Length > 0 ? arguments[0] : Undefined.Instance;
-            if (TypeConverter.GetType(oArg) != TypeCode.Object)
+            if (TypeConverter.GetType(oArg) != Types.Object)
             {
                 throw new JavaScriptException(Engine.TypeError);
             }
 
-            var o = oArg as ObjectInstance;
+            var o = (ObjectInstance)oArg;
 
-            foreach (var prop in o.Properties)
+            var keys = o.Properties.Keys.ToArray();
+            foreach (var key in keys)
             {
-                if (prop.Value.IsDataDescriptor())
+                var prop = o.Properties[key];
+                if (prop.IsDataDescriptor())
                 {
-                    var datadesc = prop.Value.As<DataDescriptor>();
+                    var datadesc = prop.As<DataDescriptor>();
                     if (datadesc.WritableIsSet)
                     {
                         datadesc.Writable = false;
                     }
                 }
-                if (prop.Value.ConfigurableIsSet)
+                if (prop.ConfigurableIsSet)
                 {
-                    prop.Value.Configurable = false;
+                    prop.Configurable = false;
                 }
-                o.DefineOwnProperty(prop.Key, prop.Value, true);
+                o.DefineOwnProperty(key, prop, true);
             }
             
             o.Extensible = false;
@@ -284,7 +286,7 @@ namespace Jint.Native.Object
         public object PreventExtensions(object thisObject, object[] arguments)
         {
             var oArg = arguments.Length > 0 ? arguments[0] : Undefined.Instance;
-            if (TypeConverter.GetType(oArg) != TypeCode.Object)
+            if (TypeConverter.GetType(oArg) != Types.Object)
             {
                 throw new JavaScriptException(Engine.TypeError);
             }
@@ -299,7 +301,7 @@ namespace Jint.Native.Object
         public object IsSealed(object thisObject, object[] arguments)
         {
             var oArg = arguments.Length > 0 ? arguments[0] : Undefined.Instance;
-            if (TypeConverter.GetType(oArg) != TypeCode.Object)
+            if (TypeConverter.GetType(oArg) != Types.Object)
             {
                 throw new JavaScriptException(Engine.TypeError);
             }
@@ -325,7 +327,7 @@ namespace Jint.Native.Object
         public object IsFrozen(object thisObject, object[] arguments)
         {
             var oArg = arguments.Length > 0 ? arguments[0] : Undefined.Instance;
-            if (TypeConverter.GetType(oArg) != TypeCode.Object)
+            if (TypeConverter.GetType(oArg) != Types.Object)
             {
                 throw new JavaScriptException(Engine.TypeError);
             }
@@ -358,7 +360,7 @@ namespace Jint.Native.Object
         public object IsExtensible(object thisObject, object[] arguments)
         {
             var oArg = arguments.Length > 0 ? arguments[0] : Undefined.Instance;
-            if (TypeConverter.GetType(oArg) != TypeCode.Object)
+            if (TypeConverter.GetType(oArg) != Types.Object)
             {
                 throw new JavaScriptException(Engine.TypeError);
             }
@@ -371,7 +373,7 @@ namespace Jint.Native.Object
         public object Keys(object thisObject, object[] arguments)
         {
             var oArg = arguments.Length > 0 ? arguments[0] : Undefined.Instance;
-            if (TypeConverter.GetType(oArg) != TypeCode.Object)
+            if (TypeConverter.GetType(oArg) != Types.Object)
             {
                 throw new JavaScriptException(Engine.TypeError);
             }

+ 8 - 3
Jint/Native/Object/ObjectInstance.cs

@@ -60,6 +60,11 @@ namespace Jint.Native.Object
 
             var getter = desc.As<AccessorDescriptor>().Get;
 
+            if (getter == null)
+            {
+                return Undefined.Instance;
+            }
+
             return getter.Call(this, Arguments.Empty);
         }
 
@@ -286,9 +291,9 @@ namespace Jint.Native.Object
         /// </summary>
         /// <param name="hint"></param>
         /// <returns></returns>
-        public object DefaultValue(TypeCode hint)
+        public object DefaultValue(Types hint)
         {
-            if ((hint == TypeCode.String) || (hint == TypeCode.Empty && this is StringInstance))
+            if ((hint == Types.String) || (hint == Types.None && this is StringInstance))
             {
                 var toString = Get("toString");
                 var callable = toString as ICallable;
@@ -315,7 +320,7 @@ namespace Jint.Native.Object
                 throw new JavaScriptException(Engine.TypeError);
             }
 
-            if ((hint == TypeCode.Double) || (hint == TypeCode.Empty))
+            if ((hint == Types.Number) || (hint == Types.None))
             {
                 var valueOf = Get("valueOf");
                 var callable = valueOf as ICallable;

+ 3 - 2
Jint/Native/RegExp/RegExpInstance.cs

@@ -1,5 +1,6 @@
 using System;
 using Jint.Native.Object;
+using Jint.Runtime;
 
 namespace Jint.Native.RegExp
 {
@@ -21,9 +22,9 @@ namespace Jint.Native.RegExp
             }
         }
 
-        TypeCode IPrimitiveType.TypeCode
+        Types IPrimitiveType.Type
         {
-            get { return TypeCode.Boolean; }
+            get { return Types.Boolean; }
         }
 
         object IPrimitiveType.PrimitiveValue

+ 2 - 2
Jint/Native/String/StringInstance.cs

@@ -23,9 +23,9 @@ namespace Jint.Native.String
             }
         }
 
-        TypeCode IPrimitiveType.TypeCode
+        Types IPrimitiveType.Type
         {
-            get { return TypeCode.Boolean; }
+            get { return Types.Boolean; }
         }
 
         object IPrimitiveType.PrimitiveValue

+ 3 - 2
Jint/Native/Undefined.cs

@@ -1,4 +1,5 @@
 using System;
+using Jint.Runtime;
 
 namespace Jint.Native
 {
@@ -15,9 +16,9 @@ namespace Jint.Native
             return "undefined";
         }
 
-        public TypeCode TypeCode
+        public Types Type
         {
-            get { return TypeCode.Empty; }
+            get { return Types.Undefined; }
         }
 
         public object PrimitiveValue

+ 6 - 6
Jint/Runtime/Descriptors/PropertyDescriptor.cs

@@ -74,14 +74,14 @@ namespace Jint.Runtime.Descriptors
             {
                 throw new JavaScriptException(engine.TypeError);
             }
-            
-            bool writable = TypeConverter.ToBoolean(obj.Get("writable"));
-            bool enumerable = TypeConverter.ToBoolean(obj.Get("enumerable"));
-            bool configurable = TypeConverter.ToBoolean(obj.Get("configurable"));
+
+            bool? writable = obj.HasProperty("writable") ? TypeConverter.ToBoolean(obj.Get("writable")) : default(bool?);
+            bool? enumerable = obj.HasProperty("enumerable") ? TypeConverter.ToBoolean(obj.Get("enumerable")) : default(bool?);
+            bool? configurable = obj.HasProperty("configurable") ? TypeConverter.ToBoolean(obj.Get("configurable")) : default(bool?);
 
             if (obj.HasProperty("value"))
             {
-                var value = TypeConverter.ToBoolean(obj.Get("value"));
+                var value = obj.Get("value");
                 return new DataDescriptor(value) { Configurable = configurable, Enumerable = enumerable, Writable = writable};
             }
             else
@@ -105,7 +105,7 @@ namespace Jint.Runtime.Descriptors
                     }
                 }
 
-                return new AccessorDescriptor(getter as ICallable, setter as ICallable);
+                return new AccessorDescriptor(getter as ICallable, setter as ICallable) { Configurable = configurable, Enumerable = enumerable };
             }
         }
 

+ 42 - 33
Jint/Runtime/ExpressionIntepreter.cs

@@ -57,8 +57,8 @@ namespace Jint.Runtime
                 case "+=":
                     var lprim = TypeConverter.ToPrimitive(lval);
                     var rprim = TypeConverter.ToPrimitive(rval);
-                    if (TypeConverter.GetType(lprim) == TypeCode.String ||
-                        TypeConverter.GetType(rprim) == TypeCode.String)
+                    if (TypeConverter.GetType(lprim) == Types.String ||
+                        TypeConverter.GetType(rprim) == Types.String)
                     {
                         lval = TypeConverter.ToString(lprim) + TypeConverter.ToString(rprim);
                     }
@@ -193,7 +193,7 @@ namespace Jint.Runtime
                 case "+":
                     var lprim = TypeConverter.ToPrimitive(left);
                     var rprim = TypeConverter.ToPrimitive(right);
-                    if (TypeConverter.GetType(lprim) == TypeCode.String || TypeConverter.GetType(rprim) == TypeCode.String)
+                    if (TypeConverter.GetType(lprim) == Types.String || TypeConverter.GetType(rprim) == Types.String)
                     {
                         value = TypeConverter.ToString(lprim) + TypeConverter.ToString(rprim);
                     }
@@ -369,12 +369,12 @@ namespace Jint.Runtime
 
             if (typex == typey)
             {
-                if (typex == TypeCode.Empty)
+                if (typex == Types.Undefined || typex == Types.Null)
                 {
                     return true;
                 }
 
-                if (typex == TypeCode.Double)
+                if (typex == Types.Number)
                 {
                     var nx = TypeConverter.ToNumber(x);
                     var ny = TypeConverter.ToNumber(y);
@@ -392,12 +392,12 @@ namespace Jint.Runtime
                     return false;
                 }
 
-                if (typex == TypeCode.String)
+                if (typex == Types.String)
                 {
                     return TypeConverter.ToString(x) == TypeConverter.ToString(y);
                 }
 
-                if (typex == TypeCode.Boolean)
+                if (typex == Types.Boolean)
                 {
                     return (bool) x == (bool) y;
                 }
@@ -415,32 +415,32 @@ namespace Jint.Runtime
                 return true;
             }
 
-            if (typex == TypeCode.Double && typey == TypeCode.String)
+            if (typex == Types.Number && typey == Types.String)
             {
                 return Equal(x, TypeConverter.ToNumber(y));
             }
 
-            if (typex == TypeCode.String && typey == TypeCode.Double)
+            if (typex == Types.String && typey == Types.Number)
             {
                 return Equal(TypeConverter.ToNumber(x), y);
             }
 
-            if (typex == TypeCode.Boolean)
+            if (typex == Types.Boolean)
             {
                 return Equal(TypeConverter.ToNumber(x), y);
             }
 
-            if (typey == TypeCode.Boolean)
+            if (typey == Types.Boolean)
             {
                 return Equal(x, TypeConverter.ToNumber(y));
             }
 
-            if (typey == TypeCode.Object && (typex == TypeCode.String || typex == TypeCode.Double))
+            if (typey == Types.Object && (typex == Types.String || typex == Types.Number))
             {
                 return Equal(x, TypeConverter.ToPrimitive(y));
             }
 
-            if (typex == TypeCode.Object && (typey == TypeCode.String || typey == TypeCode.Double))
+            if (typex == Types.Object && (typey == Types.String || typey == Types.Number))
             {
                 return Equal(TypeConverter.ToPrimitive(x), y);
             }
@@ -458,11 +458,16 @@ namespace Jint.Runtime
                 return false;
             }
 
-            if (typea == TypeCode.Empty)
+            if (typea == Types.Undefined || typea == Types.Null)
             {
                 return true;
             }
-            if (typea == TypeCode.Double)
+
+            if (typea == Types.None)
+            {
+                return true;
+            }
+            if (typea == Types.Number)
             {
                 var nx = TypeConverter.ToNumber(x);
                 var ny = TypeConverter.ToNumber(y);
@@ -478,11 +483,11 @@ namespace Jint.Runtime
 
                 return false;
             }
-            if (typea == TypeCode.String)
+            if (typea == Types.String)
             {
                 return TypeConverter.ToString(x) == TypeConverter.ToString(y);
             }
-            if (typea == TypeCode.Boolean)
+            if (typea == Types.Boolean)
             {
                 return TypeConverter.ToBoolean(x) == TypeConverter.ToBoolean(y);
             }
@@ -499,11 +504,11 @@ namespace Jint.Runtime
                 return false;
             }
 
-            if (typea == TypeCode.Empty)
+            if (typea == Types.None)
             {
                 return true;
             }
-            if (typea == TypeCode.Double)
+            if (typea == Types.Number)
             {
                 var nx = TypeConverter.ToNumber(x);
                 var ny = TypeConverter.ToNumber(y);
@@ -525,11 +530,11 @@ namespace Jint.Runtime
 
                 return false;
             }
-            if (typea == TypeCode.String)
+            if (typea == Types.String)
             {
                 return TypeConverter.ToString(x) == TypeConverter.ToString(y);
             }
-            if (typea == TypeCode.Boolean)
+            if (typea == Types.Boolean)
             {
                 return TypeConverter.ToBoolean(x) == TypeConverter.ToBoolean(y);
             }
@@ -541,18 +546,18 @@ namespace Jint.Runtime
             object px, py;
             if (leftFirst)
             {
-                px = TypeConverter.ToPrimitive(x, TypeCode.Double);
-                py = TypeConverter.ToPrimitive(y, TypeCode.Double);
+                px = TypeConverter.ToPrimitive(x, Types.Number);
+                py = TypeConverter.ToPrimitive(y, Types.Number);
             }
             else
             {
-                py = TypeConverter.ToPrimitive(y, TypeCode.Double);
-                px = TypeConverter.ToPrimitive(x, TypeCode.Double);
+                py = TypeConverter.ToPrimitive(y, Types.Number);
+                px = TypeConverter.ToPrimitive(x, Types.Number);
             }
             var typea = TypeConverter.GetType(x);
             var typeb = TypeConverter.GetType(y);
 
-            if (typea != TypeCode.String || typeb != TypeCode.String)
+            if (typea != Types.String || typeb != Types.String)
             {
                 var nx = TypeConverter.ToNumber(px);
                 var ny = TypeConverter.ToNumber(py);
@@ -776,7 +781,7 @@ namespace Jint.Runtime
             // todo: implement as in http://www.ecma-international.org/ecma-262/5.1/#sec-11.2.4
             var arguments = callExpression.Arguments.Select(EvaluateExpression).Select(_engine.GetValue).ToArray();
 
-            if (TypeConverter.GetType(func) != TypeCode.Object)
+            if (TypeConverter.GetType(func) != Types.Object)
             {
                 throw new JavaScriptException(_engine.TypeError);
             }
@@ -887,12 +892,16 @@ namespace Jint.Runtime
 
         public object EvaluateArrayExpression(ArrayExpression arrayExpression)
         {
-            var a = _engine.Array.Construct(Arguments.Empty);
+            var a = _engine.Array.Construct(new object[] { arrayExpression.Elements.Count() });
             var n = 0;
             foreach (var expr in arrayExpression.Elements)
             {
-                var value = expr == null ? Null.Instance : _engine.GetValue(EvaluateExpression(expr));
-                a.DefineOwnProperty(n.ToString(), new DataDescriptor(value) { Writable = true, Enumerable = true, Configurable = true }, false);
+                if (expr != null)
+                {
+                    var value = _engine.GetValue(EvaluateExpression(expr));
+                    a.DefineOwnProperty(n.ToString(),
+                        new DataDescriptor(value) {Writable = true, Enumerable = true, Configurable = true}, false);
+                }
                 n++;
             }
             
@@ -970,9 +979,9 @@ namespace Jint.Runtime
                     }
                     switch (TypeConverter.GetType(v))
                     {
-                        case TypeCode.Boolean: return "boolean";
-                        case TypeCode.Double: return "number";
-                        case TypeCode.String: return "string";
+                        case Types.Boolean: return "boolean";
+                        case Types.Number: return "number";
+                        case Types.String: return "string";
                     }
                     if (v is ICallable)
                     {

+ 3 - 3
Jint/Runtime/References/Reference.cs

@@ -41,9 +41,9 @@ namespace Jint.Runtime.References
         {
             var type = TypeConverter.GetType(_baseValue);
 
-            return (type == TypeCode.Boolean)
-                || (type == TypeCode.String)
-                || (type == TypeCode.Double)
+            return (type == Types.Boolean)
+                || (type == Types.String)
+                || (type == Types.Number)
                 ;
         }
 

+ 1 - 1
Jint/Runtime/StatementInterpreter.cs

@@ -366,7 +366,7 @@ namespace Jint.Runtime
 
         public Completion ExecuteStatementList(IEnumerable<Statement> statementList)
         {
-            var c = new Completion(Completion.Normal, null, null);
+            var c = new Completion(Completion.Normal, Null.Instance, null);
             Completion sl = c;
 
             try

+ 27 - 11
Jint/Runtime/TypeConverter.cs

@@ -5,6 +5,17 @@ using Jint.Native.Object;
 
 namespace Jint.Runtime
 {
+    public enum Types
+    {
+        None,
+        Undefined,
+        Null,
+        Boolean,
+        String,
+        Number,
+        Object
+    }
+
     public class TypeConverter
     {
         /// <summary>
@@ -13,7 +24,7 @@ namespace Jint.Runtime
         /// <param name="input"></param>
         /// <param name="preferredType"></param>
         /// <returns></returns>
-        public static object ToPrimitive(object input, TypeCode preferredType = TypeCode.Empty)
+        public static object ToPrimitive(object input, Types preferredType = Types.None)
         {
             if (input == Null.Instance || input == Undefined.Instance)
             {
@@ -210,7 +221,7 @@ namespace Jint.Runtime
                 return double.NaN;
             }
 
-            return ToNumber(ToPrimitive(o, TypeCode.Double));
+            return ToNumber(ToPrimitive(o, Types.Number));
         }
 
         /// <summary>
@@ -232,7 +243,7 @@ namespace Jint.Runtime
                 return number;
             }
 
-            return Math.Sign(number)*Math.Floor(Math.Abs(number));
+            return (long)number;
         }
 
         /// <summary>
@@ -350,7 +361,7 @@ namespace Jint.Runtime
                 return o.ToString();
             }
 
-            return ToString(ToPrimitive(o, TypeCode.String));
+            return ToString(ToPrimitive(o, Types.String));
         }
 
         public static ObjectInstance ToObject(Engine engine, object value)
@@ -405,29 +416,34 @@ namespace Jint.Runtime
             throw new JavaScriptException(engine.TypeError);
         }
 
-        public static TypeCode GetType(object value)
+        public static Types GetType(object value)
         {
-            if (value == null || value == Undefined.Instance || value == Null.Instance)
+            if (value == null || value == Null.Instance)
+            {
+                return Types.Null;
+            }
+
+            if (value == Undefined.Instance)
             {
-                return TypeCode.Empty;
+                return Types.Undefined;
             }
 
             if (value is string)
             {
-                return TypeCode.String;
+                return Types.String;
             }
 
             if (value is double || value is int || value is uint || value is ushort)
             {
-                return TypeCode.Double;
+                return Types.Number;
             }
 
             if (value is bool)
             {
-                return TypeCode.Boolean;
+                return Types.Boolean;
             }
 
-            return TypeCode.Object;
+            return Types.Object;
         }
 
         public static void CheckObjectCoercible(Engine engine, object o)