Browse Source

Date prototype is only valid on Date object

Fixes #231
Sebastien Ros 10 years ago
parent
commit
fad0e2b27b
2 changed files with 89 additions and 64 deletions
  1. 13 0
      Jint.Tests/Runtime/EngineTests.cs
  2. 76 64
      Jint/Native/Date/DatePrototype.cs

+ 13 - 0
Jint.Tests/Runtime/EngineTests.cs

@@ -1522,5 +1522,18 @@ namespace Jint.Tests.Runtime
                 assert(a['00'] === undefined);
                 assert(a['00'] === undefined);
             ");
             ");
         }
         }
+
+        [Fact]
+        public void DatePrototypeFunctionWorkOnDateOnly()
+        {
+            RunTest(@"
+                try {
+                    var myObj = Object.create(Date.prototype);
+                    myObj.toDateString();
+                } catch (e) {
+                    assert(e instanceof TypeError);
+                }
+            ");
+        }
     }
     }
 }
 }

+ 76 - 64
Jint/Native/Date/DatePrototype.cs

@@ -78,54 +78,66 @@ namespace Jint.Native.Date
             FastAddProperty("toJSON", new ClrFunctionInstance(Engine, ToJSON, 1), true, false, true);
             FastAddProperty("toJSON", new ClrFunctionInstance(Engine, ToJSON, 1), true, false, true);
         }
         }
 
 
-        private static JsValue ValueOf(JsValue thisObj, JsValue[] arguments)
+        private JsValue ValueOf(JsValue thisObj, JsValue[] arguments)
         {
         {
-            return thisObj.TryCast<DateInstance>().PrimitiveValue;
+            return EnsureDateInstance(thisObj).PrimitiveValue;
+        }
+
+        /// <summary>
+        /// Converts a value to a <see cref="DateInstance"/> or throws a TypeError exception.
+        /// c.f., http://www.ecma-international.org/ecma-262/5.1/#sec-15.9.5
+        /// </summary>
+        private DateInstance EnsureDateInstance(JsValue thisObj)
+        {
+            return thisObj.TryCast<DateInstance>(value =>
+               {
+                   throw new JavaScriptException(Engine.TypeError, "Invalid Date");
+               });
         }
         }
 
 
         public JsValue ToString(JsValue thisObj, JsValue[] arg2)
         public JsValue ToString(JsValue thisObj, JsValue[] arg2)
         {
         {
-            return ToLocalTime(thisObj.TryCast<DateInstance>().ToDateTime()).ToString("ddd MMM dd yyyy HH:mm:ss 'GMT'K", CultureInfo.InvariantCulture);
+            return ToLocalTime(EnsureDateInstance(thisObj).ToDateTime()).ToString("ddd MMM dd yyyy HH:mm:ss 'GMT'K", CultureInfo.InvariantCulture);
         }
         }
 
 
-        private static JsValue ToDateString(JsValue thisObj, JsValue[] arguments)
+        private JsValue ToDateString(JsValue thisObj, JsValue[] arguments)
         {
         {
-            return thisObj.TryCast<DateInstance>().ToDateTime().ToString("D", CultureInfo.InvariantCulture);
+            return EnsureDateInstance(thisObj).ToDateTime().ToString("D", CultureInfo.InvariantCulture);
         }
         }
 
 
-        private static JsValue ToTimeString(JsValue thisObj, JsValue[] arguments)
+        private JsValue ToTimeString(JsValue thisObj, JsValue[] arguments)
         {
         {
             return thisObj.TryCast<DateInstance>().ToDateTime().ToString("T", CultureInfo.InvariantCulture);
             return thisObj.TryCast<DateInstance>().ToDateTime().ToString("T", CultureInfo.InvariantCulture);
         }
         }
 
 
-        private static JsValue ToLocaleString(JsValue thisObj, JsValue[] arguments)
+        private JsValue ToLocaleString(JsValue thisObj, JsValue[] arguments)
         {
         {
-            return thisObj.TryCast<DateInstance>().ToDateTime().ToString("F");
+            return EnsureDateInstance(thisObj).ToDateTime().ToString("F");
         }
         }
 
 
-        private static JsValue ToLocaleDateString(JsValue thisObj, JsValue[] arguments)
+        private JsValue ToLocaleDateString(JsValue thisObj, JsValue[] arguments)
         {
         {
             return thisObj.TryCast<DateInstance>().ToDateTime().ToString("D");
             return thisObj.TryCast<DateInstance>().ToDateTime().ToString("D");
         }
         }
 
 
         private JsValue ToLocaleTimeString(JsValue thisObj, JsValue[] arguments)
         private JsValue ToLocaleTimeString(JsValue thisObj, JsValue[] arguments)
         {
         {
-            return thisObj.TryCast<DateInstance>().ToDateTime().ToString("T");
+            return EnsureDateInstance(thisObj).ToDateTime().ToString("T");
         }
         }
 
 
-        private static JsValue GetTime(JsValue thisObj, JsValue[] arguments)
+        private JsValue GetTime(JsValue thisObj, JsValue[] arguments)
         {
         {
-            if (double.IsNaN(thisObj.TryCast<DateInstance>().PrimitiveValue))
+            if (double.IsNaN(EnsureDateInstance(thisObj).PrimitiveValue))
             {
             {
                 return double.NaN;
                 return double.NaN;
             }
             }
 
 
-            return thisObj.TryCast<DateInstance>().PrimitiveValue;
+            return EnsureDateInstance(thisObj).PrimitiveValue;
         }
         }
 
 
         private JsValue GetFullYear(JsValue thisObj, JsValue[] arguments)
         private JsValue GetFullYear(JsValue thisObj, JsValue[] arguments)
         {
         {
-            var t = thisObj.TryCast<DateInstance>().PrimitiveValue;
+            var t = EnsureDateInstance(thisObj).PrimitiveValue;
             if (double.IsNaN(t))
             if (double.IsNaN(t))
             {
             {
                 return double.NaN;
                 return double.NaN;
@@ -136,7 +148,7 @@ namespace Jint.Native.Date
 
 
         private JsValue GetYear(JsValue thisObj, JsValue[] arguments)
         private JsValue GetYear(JsValue thisObj, JsValue[] arguments)
         {
         {
-            var t = thisObj.TryCast<DateInstance>().PrimitiveValue;
+            var t = EnsureDateInstance(thisObj).PrimitiveValue;
             if (double.IsNaN(t))
             if (double.IsNaN(t))
             {
             {
                 return double.NaN;
                 return double.NaN;
@@ -145,9 +157,9 @@ namespace Jint.Native.Date
             return YearFromTime(LocalTime(t)) - 1900;
             return YearFromTime(LocalTime(t)) - 1900;
         }
         }
 
 
-        private static JsValue GetUTCFullYear(JsValue thisObj, JsValue[] arguments)
+        private JsValue GetUTCFullYear(JsValue thisObj, JsValue[] arguments)
         {
         {
-            var t = thisObj.TryCast<DateInstance>().PrimitiveValue;
+            var t = EnsureDateInstance(thisObj).PrimitiveValue;
             if (double.IsNaN(t))
             if (double.IsNaN(t))
             {
             {
                 return double.NaN;
                 return double.NaN;
@@ -158,7 +170,7 @@ namespace Jint.Native.Date
 
 
         private JsValue GetMonth(JsValue thisObj, JsValue[] arguments)
         private JsValue GetMonth(JsValue thisObj, JsValue[] arguments)
         {
         {
-            var t = thisObj.TryCast<DateInstance>().PrimitiveValue;
+            var t = EnsureDateInstance(thisObj).PrimitiveValue;
             if (double.IsNaN(t))
             if (double.IsNaN(t))
             {
             {
                 return double.NaN;
                 return double.NaN;
@@ -167,9 +179,9 @@ namespace Jint.Native.Date
             return MonthFromTime(LocalTime(t));
             return MonthFromTime(LocalTime(t));
         }
         }
 
 
-        private static JsValue GetUTCMonth(JsValue thisObj, JsValue[] arguments)
+        private JsValue GetUTCMonth(JsValue thisObj, JsValue[] arguments)
         {
         {
-            var t = thisObj.TryCast<DateInstance>().PrimitiveValue;
+            var t = EnsureDateInstance(thisObj).PrimitiveValue;
             if (double.IsNaN(t))
             if (double.IsNaN(t))
             {
             {
                 return double.NaN;
                 return double.NaN;
@@ -180,7 +192,7 @@ namespace Jint.Native.Date
 
 
         private JsValue GetDate(JsValue thisObj, JsValue[] arguments)
         private JsValue GetDate(JsValue thisObj, JsValue[] arguments)
         {
         {
-            var t = thisObj.TryCast<DateInstance>().PrimitiveValue;
+            var t = EnsureDateInstance(thisObj).PrimitiveValue;
             if (double.IsNaN(t))
             if (double.IsNaN(t))
             {
             {
                 return double.NaN;
                 return double.NaN;
@@ -189,9 +201,9 @@ namespace Jint.Native.Date
             return DateFromTime(LocalTime(t));
             return DateFromTime(LocalTime(t));
         }
         }
 
 
-        private static JsValue GetUTCDate(JsValue thisObj, JsValue[] arguments)
+        private JsValue GetUTCDate(JsValue thisObj, JsValue[] arguments)
         {
         {
-            var t = thisObj.TryCast<DateInstance>().PrimitiveValue;
+            var t = EnsureDateInstance(thisObj).PrimitiveValue;
             if (double.IsNaN(t))
             if (double.IsNaN(t))
             {
             {
                 return double.NaN;
                 return double.NaN;
@@ -202,7 +214,7 @@ namespace Jint.Native.Date
 
 
         private JsValue GetDay(JsValue thisObj, JsValue[] arguments)
         private JsValue GetDay(JsValue thisObj, JsValue[] arguments)
         {
         {
-            var t = thisObj.TryCast<DateInstance>().PrimitiveValue;
+            var t = EnsureDateInstance(thisObj).PrimitiveValue;
             if (double.IsNaN(t))
             if (double.IsNaN(t))
             {
             {
                 return double.NaN;
                 return double.NaN;
@@ -211,9 +223,9 @@ namespace Jint.Native.Date
             return WeekDay(LocalTime(t));
             return WeekDay(LocalTime(t));
         }
         }
 
 
-        private static JsValue GetUTCDay(JsValue thisObj, JsValue[] arguments)
+        private JsValue GetUTCDay(JsValue thisObj, JsValue[] arguments)
         {
         {
-            var t = thisObj.TryCast<DateInstance>().PrimitiveValue;
+            var t = EnsureDateInstance(thisObj).PrimitiveValue;
             if (double.IsNaN(t))
             if (double.IsNaN(t))
             {
             {
                 return double.NaN;
                 return double.NaN;
@@ -224,7 +236,7 @@ namespace Jint.Native.Date
 
 
         private JsValue GetHours(JsValue thisObj, JsValue[] arguments)
         private JsValue GetHours(JsValue thisObj, JsValue[] arguments)
         {
         {
-            var t = thisObj.TryCast<DateInstance>().PrimitiveValue;
+            var t = EnsureDateInstance(thisObj).PrimitiveValue;
             if (double.IsNaN(t))
             if (double.IsNaN(t))
             {
             {
                 return double.NaN;
                 return double.NaN;
@@ -233,9 +245,9 @@ namespace Jint.Native.Date
             return HourFromTime(LocalTime(t));
             return HourFromTime(LocalTime(t));
         }
         }
 
 
-        private static JsValue GetUTCHours(JsValue thisObj, JsValue[] arguments)
+        private JsValue GetUTCHours(JsValue thisObj, JsValue[] arguments)
         {
         {
-            var t = thisObj.TryCast<DateInstance>().PrimitiveValue;
+            var t = EnsureDateInstance(thisObj).PrimitiveValue;
             if (double.IsNaN(t))
             if (double.IsNaN(t))
             {
             {
                 return double.NaN;
                 return double.NaN;
@@ -246,7 +258,7 @@ namespace Jint.Native.Date
 
 
         private JsValue GetMinutes(JsValue thisObj, JsValue[] arguments)
         private JsValue GetMinutes(JsValue thisObj, JsValue[] arguments)
         {
         {
-            var t = thisObj.TryCast<DateInstance>().PrimitiveValue;
+            var t = EnsureDateInstance(thisObj).PrimitiveValue;
             if (double.IsNaN(t))
             if (double.IsNaN(t))
             {
             {
                 return double.NaN;
                 return double.NaN;
@@ -255,9 +267,9 @@ namespace Jint.Native.Date
             return MinFromTime(LocalTime(t));
             return MinFromTime(LocalTime(t));
         }
         }
 
 
-        private static JsValue GetUTCMinutes(JsValue thisObj, JsValue[] arguments)
+        private JsValue GetUTCMinutes(JsValue thisObj, JsValue[] arguments)
         {
         {
-            var t = thisObj.TryCast<DateInstance>().PrimitiveValue;
+            var t = EnsureDateInstance(thisObj).PrimitiveValue;
             if (double.IsNaN(t))
             if (double.IsNaN(t))
             {
             {
                 return double.NaN;
                 return double.NaN;
@@ -277,9 +289,9 @@ namespace Jint.Native.Date
             return SecFromTime(LocalTime(t));
             return SecFromTime(LocalTime(t));
         }
         }
 
 
-        private static JsValue GetUTCSeconds(JsValue thisObj, JsValue[] arguments)
+        private JsValue GetUTCSeconds(JsValue thisObj, JsValue[] arguments)
         {
         {
-            var t = thisObj.TryCast<DateInstance>().PrimitiveValue;
+            var t = EnsureDateInstance(thisObj).PrimitiveValue;
             if (double.IsNaN(t))
             if (double.IsNaN(t))
             {
             {
                 return double.NaN;
                 return double.NaN;
@@ -290,7 +302,7 @@ namespace Jint.Native.Date
 
 
         private JsValue GetMilliseconds(JsValue thisObj, JsValue[] arguments)
         private JsValue GetMilliseconds(JsValue thisObj, JsValue[] arguments)
         {
         {
-            var t = thisObj.TryCast<DateInstance>().PrimitiveValue;
+            var t = EnsureDateInstance(thisObj).PrimitiveValue;
             if (double.IsNaN(t))
             if (double.IsNaN(t))
             {
             {
                 return double.NaN;
                 return double.NaN;
@@ -299,9 +311,9 @@ namespace Jint.Native.Date
             return MsFromTime(LocalTime(t));
             return MsFromTime(LocalTime(t));
         }
         }
 
 
-        private static JsValue GetUTCMilliseconds(JsValue thisObj, JsValue[] arguments)
+        private JsValue GetUTCMilliseconds(JsValue thisObj, JsValue[] arguments)
         {
         {
-            var t = thisObj.TryCast<DateInstance>().PrimitiveValue;
+            var t = EnsureDateInstance(thisObj).PrimitiveValue;
             if (double.IsNaN(t))
             if (double.IsNaN(t))
             {
             {
                 return double.NaN;
                 return double.NaN;
@@ -312,7 +324,7 @@ namespace Jint.Native.Date
 
 
         private JsValue GetTimezoneOffset(JsValue thisObj, JsValue[] arguments)
         private JsValue GetTimezoneOffset(JsValue thisObj, JsValue[] arguments)
         {
         {
-            var t = thisObj.TryCast<DateInstance>().PrimitiveValue;
+            var t = EnsureDateInstance(thisObj).PrimitiveValue;
             if (double.IsNaN(t))
             if (double.IsNaN(t))
             {
             {
                 return double.NaN;
                 return double.NaN;
@@ -321,23 +333,23 @@ namespace Jint.Native.Date
             return (t - LocalTime(t))/MsPerMinute;
             return (t - LocalTime(t))/MsPerMinute;
         }
         }
 
 
-        private static JsValue SetTime(JsValue thisObj, JsValue[] arguments)
+        private JsValue SetTime(JsValue thisObj, JsValue[] arguments)
         {
         {
-            return thisObj.As<DateInstance>().PrimitiveValue = TimeClip(TypeConverter.ToNumber(arguments.At(0)));
+            return EnsureDateInstance(thisObj).PrimitiveValue = TimeClip(TypeConverter.ToNumber(arguments.At(0)));
         }
         }
 
 
         private JsValue SetMilliseconds(JsValue thisObj, JsValue[] arguments)
         private JsValue SetMilliseconds(JsValue thisObj, JsValue[] arguments)
         {
         {
-            var t = LocalTime(thisObj.As<DateInstance>().PrimitiveValue);
+            var t = LocalTime(EnsureDateInstance(thisObj).PrimitiveValue);
             var time = MakeTime(HourFromTime(t), MinFromTime(t), SecFromTime(t), TypeConverter.ToNumber(arguments.At(0)));
             var time = MakeTime(HourFromTime(t), MinFromTime(t), SecFromTime(t), TypeConverter.ToNumber(arguments.At(0)));
             var u = TimeClip(Utc(MakeDate(Day(t), time)));
             var u = TimeClip(Utc(MakeDate(Day(t), time)));
             thisObj.As<DateInstance>().PrimitiveValue = u;
             thisObj.As<DateInstance>().PrimitiveValue = u;
             return u;
             return u;
         }
         }
 
 
-        private static JsValue SetUTCMilliseconds(JsValue thisObj, JsValue[] arguments)
+        private JsValue SetUTCMilliseconds(JsValue thisObj, JsValue[] arguments)
         {
         {
-            var t = thisObj.As<DateInstance>().PrimitiveValue;
+            var t = EnsureDateInstance(thisObj).PrimitiveValue;
             var time = MakeTime(HourFromTime(t), MinFromTime(t), SecFromTime(t), TypeConverter.ToNumber(arguments.At(0)));
             var time = MakeTime(HourFromTime(t), MinFromTime(t), SecFromTime(t), TypeConverter.ToNumber(arguments.At(0)));
             var u = TimeClip(MakeDate(Day(t), time));
             var u = TimeClip(MakeDate(Day(t), time));
             thisObj.As<DateInstance>().PrimitiveValue = u;
             thisObj.As<DateInstance>().PrimitiveValue = u;
@@ -346,7 +358,7 @@ namespace Jint.Native.Date
 
 
         private JsValue SetSeconds(JsValue thisObj, JsValue[] arguments)
         private JsValue SetSeconds(JsValue thisObj, JsValue[] arguments)
         {
         {
-            var t = LocalTime(thisObj.As<DateInstance>().PrimitiveValue);
+            var t = LocalTime(EnsureDateInstance(thisObj).PrimitiveValue);
             var s = TypeConverter.ToNumber(arguments.At(0));
             var s = TypeConverter.ToNumber(arguments.At(0));
             var milli = arguments.Length <= 1 ? MsFromTime(t) : TypeConverter.ToNumber(arguments.At(1)); 
             var milli = arguments.Length <= 1 ? MsFromTime(t) : TypeConverter.ToNumber(arguments.At(1)); 
             var date = MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), s, milli));
             var date = MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), s, milli));
@@ -355,9 +367,9 @@ namespace Jint.Native.Date
             return u;
             return u;
         }
         }
 
 
-        private static JsValue SetUTCSeconds(JsValue thisObj, JsValue[] arguments)
+        private JsValue SetUTCSeconds(JsValue thisObj, JsValue[] arguments)
         {
         {
-            var t = thisObj.As<DateInstance>().PrimitiveValue;
+            var t = EnsureDateInstance(thisObj).PrimitiveValue;
             var s = TypeConverter.ToNumber(arguments.At(0));
             var s = TypeConverter.ToNumber(arguments.At(0));
             var milli = arguments.Length <= 1 ? MsFromTime(t) : TypeConverter.ToNumber(arguments.At(1));
             var milli = arguments.Length <= 1 ? MsFromTime(t) : TypeConverter.ToNumber(arguments.At(1));
             var date = MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), s, milli));
             var date = MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), s, milli));
@@ -368,7 +380,7 @@ namespace Jint.Native.Date
 
 
         private JsValue SetMinutes(JsValue thisObj, JsValue[] arguments)
         private JsValue SetMinutes(JsValue thisObj, JsValue[] arguments)
         {
         {
-            var t = LocalTime(thisObj.As<DateInstance>().PrimitiveValue);
+            var t = LocalTime(EnsureDateInstance(thisObj).PrimitiveValue);
             var m = TypeConverter.ToNumber(arguments.At(0));
             var m = TypeConverter.ToNumber(arguments.At(0));
             var s = arguments.Length <= 1 ? SecFromTime(t) : TypeConverter.ToNumber(arguments.At(1));
             var s = arguments.Length <= 1 ? SecFromTime(t) : TypeConverter.ToNumber(arguments.At(1));
             var milli = arguments.Length <= 2 ? MsFromTime(t) : TypeConverter.ToNumber(arguments.At(2));
             var milli = arguments.Length <= 2 ? MsFromTime(t) : TypeConverter.ToNumber(arguments.At(2));
@@ -378,9 +390,9 @@ namespace Jint.Native.Date
             return u;
             return u;
         }
         }
 
 
-        private static JsValue SetUTCMinutes(JsValue thisObj, JsValue[] arguments)
+        private JsValue SetUTCMinutes(JsValue thisObj, JsValue[] arguments)
         {
         {
-            var t = thisObj.As<DateInstance>().PrimitiveValue;
+            var t = EnsureDateInstance(thisObj).PrimitiveValue;
             var m = TypeConverter.ToNumber(arguments.At(0));
             var m = TypeConverter.ToNumber(arguments.At(0));
             var s = arguments.Length <= 1 ? SecFromTime(t) : TypeConverter.ToNumber(arguments.At(1));
             var s = arguments.Length <= 1 ? SecFromTime(t) : TypeConverter.ToNumber(arguments.At(1));
             var milli = arguments.Length <= 2 ? MsFromTime(t) : TypeConverter.ToNumber(arguments.At(2));
             var milli = arguments.Length <= 2 ? MsFromTime(t) : TypeConverter.ToNumber(arguments.At(2));
@@ -392,7 +404,7 @@ namespace Jint.Native.Date
 
 
         private JsValue SetHours(JsValue thisObj, JsValue[] arguments)
         private JsValue SetHours(JsValue thisObj, JsValue[] arguments)
         {
         {
-            var t = LocalTime(thisObj.As<DateInstance>().PrimitiveValue);
+            var t = LocalTime(EnsureDateInstance(thisObj).PrimitiveValue);
             var h = TypeConverter.ToNumber(arguments.At(0));
             var h = TypeConverter.ToNumber(arguments.At(0));
             var m = arguments.Length <= 1 ? MinFromTime(t) : TypeConverter.ToNumber(arguments.At(1));
             var m = arguments.Length <= 1 ? MinFromTime(t) : TypeConverter.ToNumber(arguments.At(1));
             var s = arguments.Length <= 2 ? SecFromTime(t) : TypeConverter.ToNumber(arguments.At(2));
             var s = arguments.Length <= 2 ? SecFromTime(t) : TypeConverter.ToNumber(arguments.At(2));
@@ -403,9 +415,9 @@ namespace Jint.Native.Date
             return u;
             return u;
         }
         }
 
 
-        private static JsValue SetUTCHours(JsValue thisObj, JsValue[] arguments)
+        private JsValue SetUTCHours(JsValue thisObj, JsValue[] arguments)
         {
         {
-            var t = thisObj.As<DateInstance>().PrimitiveValue;
+            var t = EnsureDateInstance(thisObj).PrimitiveValue;
             var h = TypeConverter.ToNumber(arguments.At(0));
             var h = TypeConverter.ToNumber(arguments.At(0));
             var m = arguments.Length <= 1 ? MinFromTime(t) : TypeConverter.ToNumber(arguments.At(1));
             var m = arguments.Length <= 1 ? MinFromTime(t) : TypeConverter.ToNumber(arguments.At(1));
             var s = arguments.Length <= 2 ? SecFromTime(t) : TypeConverter.ToNumber(arguments.At(2));
             var s = arguments.Length <= 2 ? SecFromTime(t) : TypeConverter.ToNumber(arguments.At(2));
@@ -418,7 +430,7 @@ namespace Jint.Native.Date
 
 
         private JsValue SetDate(JsValue thisObj, JsValue[] arguments)
         private JsValue SetDate(JsValue thisObj, JsValue[] arguments)
         {
         {
-            var t = LocalTime(thisObj.As<DateInstance>().PrimitiveValue);
+            var t = LocalTime(EnsureDateInstance(thisObj).PrimitiveValue);
             var dt = TypeConverter.ToNumber(arguments.At(0));
             var dt = TypeConverter.ToNumber(arguments.At(0));
             var newDate = MakeDate(MakeDay(YearFromTime(t), MonthFromTime(t), dt), TimeWithinDay(t));
             var newDate = MakeDate(MakeDay(YearFromTime(t), MonthFromTime(t), dt), TimeWithinDay(t));
             var u = TimeClip(Utc(newDate));
             var u = TimeClip(Utc(newDate));
@@ -426,9 +438,9 @@ namespace Jint.Native.Date
             return u;
             return u;
         }
         }
 
 
-        private static JsValue SetUTCDate(JsValue thisObj, JsValue[] arguments)
+        private JsValue SetUTCDate(JsValue thisObj, JsValue[] arguments)
         {
         {
-            var t = thisObj.As<DateInstance>().PrimitiveValue;
+            var t = EnsureDateInstance(thisObj).PrimitiveValue;
             var dt = TypeConverter.ToNumber(arguments.At(0));
             var dt = TypeConverter.ToNumber(arguments.At(0));
             var newDate = MakeDate(MakeDay(YearFromTime(t), MonthFromTime(t), dt), TimeWithinDay(t));
             var newDate = MakeDate(MakeDay(YearFromTime(t), MonthFromTime(t), dt), TimeWithinDay(t));
             var u = TimeClip(newDate);
             var u = TimeClip(newDate);
@@ -438,7 +450,7 @@ namespace Jint.Native.Date
 
 
         private JsValue SetMonth(JsValue thisObj, JsValue[] arguments)
         private JsValue SetMonth(JsValue thisObj, JsValue[] arguments)
         {
         {
-            var t = LocalTime(thisObj.As<DateInstance>().PrimitiveValue);
+            var t = LocalTime(EnsureDateInstance(thisObj).PrimitiveValue);
             var m = TypeConverter.ToNumber(arguments.At(0));
             var m = TypeConverter.ToNumber(arguments.At(0));
             var dt = arguments.Length <= 1 ? DateFromTime(t) : TypeConverter.ToNumber(arguments.At(1));
             var dt = arguments.Length <= 1 ? DateFromTime(t) : TypeConverter.ToNumber(arguments.At(1));
             var newDate = MakeDate(MakeDay(YearFromTime(t), m, dt), TimeWithinDay(t));
             var newDate = MakeDate(MakeDay(YearFromTime(t), m, dt), TimeWithinDay(t));
@@ -447,9 +459,9 @@ namespace Jint.Native.Date
             return u;
             return u;
         }
         }
 
 
-        private static JsValue SetUTCMonth(JsValue thisObj, JsValue[] arguments)
+        private JsValue SetUTCMonth(JsValue thisObj, JsValue[] arguments)
         {
         {
-            var t = thisObj.As<DateInstance>().PrimitiveValue;
+            var t = EnsureDateInstance(thisObj).PrimitiveValue;
             var m = TypeConverter.ToNumber(arguments.At(0));
             var m = TypeConverter.ToNumber(arguments.At(0));
             var dt = arguments.Length <= 1 ? DateFromTime(t) : TypeConverter.ToNumber(arguments.At(1));
             var dt = arguments.Length <= 1 ? DateFromTime(t) : TypeConverter.ToNumber(arguments.At(1));
             var newDate = MakeDate(MakeDay(YearFromTime(t), m, dt), TimeWithinDay(t));
             var newDate = MakeDate(MakeDay(YearFromTime(t), m, dt), TimeWithinDay(t));
@@ -460,7 +472,7 @@ namespace Jint.Native.Date
 
 
         private JsValue SetFullYear(JsValue thisObj, JsValue[] arguments)
         private JsValue SetFullYear(JsValue thisObj, JsValue[] arguments)
         {
         {
-            var thisTime = thisObj.As<DateInstance>().PrimitiveValue;
+            var thisTime = EnsureDateInstance(thisObj).PrimitiveValue;
             var t = double.IsNaN(thisTime) ? +0 : LocalTime(thisTime);
             var t = double.IsNaN(thisTime) ? +0 : LocalTime(thisTime);
             var y = TypeConverter.ToNumber(arguments.At(0));
             var y = TypeConverter.ToNumber(arguments.At(0));
             var m = arguments.Length <= 1 ? MonthFromTime(t) : TypeConverter.ToNumber(arguments.At(1));
             var m = arguments.Length <= 1 ? MonthFromTime(t) : TypeConverter.ToNumber(arguments.At(1));
@@ -473,12 +485,12 @@ namespace Jint.Native.Date
 
 
         private JsValue SetYear(JsValue thisObj, JsValue[] arguments)
         private JsValue SetYear(JsValue thisObj, JsValue[] arguments)
         {
         {
-            var thisTime = thisObj.As<DateInstance>().PrimitiveValue;
+            var thisTime = EnsureDateInstance(thisObj).PrimitiveValue;
             var t = double.IsNaN(thisTime) ? +0 : LocalTime(thisTime);
             var t = double.IsNaN(thisTime) ? +0 : LocalTime(thisTime);
             var y = TypeConverter.ToNumber(arguments.At(0));
             var y = TypeConverter.ToNumber(arguments.At(0));
             if (double.IsNaN(y))
             if (double.IsNaN(y))
             {
             {
-                thisObj.As<DateInstance>().PrimitiveValue = double.NaN;
+                EnsureDateInstance(thisObj).PrimitiveValue = double.NaN;
                 return double.NaN;
                 return double.NaN;
             }
             }
 
 
@@ -490,13 +502,13 @@ namespace Jint.Native.Date
 
 
             var newDate = MakeDay(fy, MonthFromTime(t), DateFromTime(t));
             var newDate = MakeDay(fy, MonthFromTime(t), DateFromTime(t));
             var u = Utc(MakeDate(newDate, TimeWithinDay(t)));
             var u = Utc(MakeDate(newDate, TimeWithinDay(t)));
-            thisObj.As<DateInstance>().PrimitiveValue = TimeClip(u);
+            EnsureDateInstance(thisObj).PrimitiveValue = TimeClip(u);
             return u;
             return u;
         }
         }
 
 
-        private static JsValue SetUTCFullYear(JsValue thisObj, JsValue[] arguments)
+        private JsValue SetUTCFullYear(JsValue thisObj, JsValue[] arguments)
         {
         {
-            var thisTime = thisObj.As<DateInstance>().PrimitiveValue;
+            var thisTime = EnsureDateInstance(thisObj).PrimitiveValue;
             var t = double.IsNaN(thisTime) ? +0 : thisTime;
             var t = double.IsNaN(thisTime) ? +0 : thisTime;
             var y = TypeConverter.ToNumber(arguments.At(0));
             var y = TypeConverter.ToNumber(arguments.At(0));
             var m = arguments.Length <= 1 ? MonthFromTime(t) : TypeConverter.ToNumber(arguments.At(1));
             var m = arguments.Length <= 1 ? MonthFromTime(t) : TypeConverter.ToNumber(arguments.At(1));