Browse Source

Incremental work of property descriptors

Sebastien Ros 11 years ago
parent
commit
cc305fbf76

+ 1 - 0
Jint.Tests.Ecma/Ecma/15.2.3.3.cs

@@ -2,6 +2,7 @@ using Xunit;
 
 namespace Jint.Tests.Ecma
 {
+    [Trait("Category", "Pass")]
     public class Test_15_2_3_3 : EcmaTest
     {
         [Fact]

+ 1 - 0
Jint.Tests.Ecma/Ecma/15.2.3.4.cs

@@ -2,6 +2,7 @@ using Xunit;
 
 namespace Jint.Tests.Ecma
 {
+    [Trait("Category", "Pass")]
     public class Test_15_2_3_4 : EcmaTest
     {
         [Fact]

+ 1 - 0
Jint.Tests.Ecma/Ecma/15.2.3.5.cs

@@ -2,6 +2,7 @@ using Xunit;
 
 namespace Jint.Tests.Ecma
 {
+    [Trait("Category", "Pass")]
     public class Test_15_2_3_5 : EcmaTest
     {
         [Fact]

+ 1 - 0
Jint.Tests.Ecma/Ecma/15.2.cs

@@ -2,6 +2,7 @@ using Xunit;
 
 namespace Jint.Tests.Ecma
 {
+    [Trait("Category", "Pass")]
     public class Test_15_2 : EcmaTest
     {
         [Fact]

+ 5 - 3
Jint/Engine.cs

@@ -368,11 +368,13 @@ namespace Jint
                         return desc.As<DataDescriptor>().Value;
                     }
                     var getter = desc.As<AccessorDescriptor>().Get;
-                    if (getter == null)
+                    if (getter == Undefined.Instance)
                     {
                         return Undefined.Instance;
                     }
-                    return getter.Call(baseValue, Arguments.Empty);
+
+                    var callable = (ICallable)getter;
+                    return callable.Call(baseValue, Arguments.Empty);
                 }
             }
             else
@@ -466,7 +468,7 @@ namespace Jint
 
             if (desc.IsAccessorDescriptor())
             {
-                var setter = desc.As<AccessorDescriptor>().Set;
+                var setter = (ICallable)desc.As<AccessorDescriptor>().Set;
                 setter.Call(b, new[] { value });
             }
             else

+ 2 - 2
Jint/Native/Array/ArrayPrototype.cs

@@ -828,8 +828,8 @@ namespace Jint.Native.Array
 
         private object ReduceRight(object thisObj, object[] arguments)
         {
-            var callbackfn = arguments.Length > 0 ? arguments[0] : Undefined.Instance;
-            var initialValue = arguments.Length > 1 ? arguments[1] : Undefined.Instance;
+            var callbackfn = arguments.At(0);
+            var initialValue = arguments.At(1);
 
             var o = TypeConverter.ToObject(Engine, thisObj);
             var lenValue = o.Get("length");

+ 8 - 8
Jint/Native/Global/GlobalObject.cs

@@ -50,14 +50,14 @@ namespace Jint.Native.Global
             FastAddProperty("undefined", Undefined.Instance, false, false, false);
 
             // Global object functions
-            FastAddProperty("parseInt", new ClrFunctionInstance<object, double>(Engine, ParseInt, 2), false, false, false);
-            FastAddProperty("parseFloat", new ClrFunctionInstance<object, double>(Engine, ParseFloat, 1), false, false, false);
-            FastAddProperty("isNaN", new ClrFunctionInstance<object, bool>(Engine, IsNaN ,1), false, false, false);
-            FastAddProperty("isFinite", new ClrFunctionInstance<object, bool>(Engine, IsFinite, 1), false, false, false);
-            FastAddProperty("decodeURI", new ClrFunctionInstance<object, string>(Engine, DecodeUri, 1), false, false, false);
-            FastAddProperty("decodeURIComponent", new ClrFunctionInstance<object, string>(Engine, DecodeUriComponent, 1), false, false, false);
-            FastAddProperty("encodeURI", new ClrFunctionInstance<object, string>(Engine, EncodeUri, 1), false, false, false);
-            FastAddProperty("encodeURIComponent", new ClrFunctionInstance<object, string>(Engine, EncodeUriComponent, 1), false, false, false);
+            FastAddProperty("parseInt", new ClrFunctionInstance<object, double>(Engine, ParseInt, 2), true, false, true);
+            FastAddProperty("parseFloat", new ClrFunctionInstance<object, double>(Engine, ParseFloat, 1), true, false, true);
+            FastAddProperty("isNaN", new ClrFunctionInstance<object, bool>(Engine, IsNaN, 1), true, false, true);
+            FastAddProperty("isFinite", new ClrFunctionInstance<object, bool>(Engine, IsFinite, 1), true, false, true);
+            FastAddProperty("decodeURI", new ClrFunctionInstance<object, string>(Engine, DecodeUri, 1), true, false, true);
+            FastAddProperty("decodeURIComponent", new ClrFunctionInstance<object, string>(Engine, DecodeUriComponent, 1), true, false, true);
+            FastAddProperty("encodeURI", new ClrFunctionInstance<object, string>(Engine, EncodeUri, 1), true, false, true);
+            FastAddProperty("encodeURIComponent", new ClrFunctionInstance<object, string>(Engine, EncodeUriComponent, 1), true, false, true);
         }
 
         /// <summary>

+ 43 - 31
Jint/Native/Object/ObjectConstructor.cs

@@ -2,6 +2,7 @@
 using System.Collections.Generic;
 using System.Linq;
 using Jint.Native.Function;
+using Jint.Native.String;
 using Jint.Runtime;
 using Jint.Runtime.Descriptors;
 using Jint.Runtime.Interop;
@@ -34,19 +35,19 @@ namespace Jint.Native.Object
         {
             Prototype = Engine.Function.PrototypeObject;
 
-            FastAddProperty("getPrototypeOf", new ClrFunctionInstance<object, object>(Engine, GetPrototypeOf, 1), false, false, false);
-            FastAddProperty("getOwnPropertyDescriptor", new ClrFunctionInstance<object, object>(Engine, GetOwnPropertyDescriptor, 2), false, false, false);
-            FastAddProperty("getOwnPropertyNames", new ClrFunctionInstance<object, object>(Engine, GetOwnPropertyNames), false, false, false);
-            FastAddProperty("create", new ClrFunctionInstance<object, object>(Engine, Create), false, false, false);
-            FastAddProperty("defineProperty", new ClrFunctionInstance<object, object>(Engine, DefineProperty), false, false, false);
-            FastAddProperty("defineProperties", new ClrFunctionInstance<object, object>(Engine, DefineProperties), false, false, false);
-            FastAddProperty("seal", new ClrFunctionInstance<object, object>(Engine, Seal, 1), false, false, false);
-            FastAddProperty("freeze", new ClrFunctionInstance<object, object>(Engine, Freeze, 1), false, false, false);
-            FastAddProperty("preventExtensions", new ClrFunctionInstance<object, object>(Engine, PreventExtensions, 1), false, false, false);
-            FastAddProperty("isSealed", new ClrFunctionInstance<object, object>(Engine, IsSealed, 1), false, false, false);
-            FastAddProperty("isFrozen", new ClrFunctionInstance<object, object>(Engine, IsFrozen, 1), false, false, false);
-            FastAddProperty("isExtensible", new ClrFunctionInstance<object, object>(Engine, IsExtensible, 1), false, false, false);
-            FastAddProperty("keys", new ClrFunctionInstance<object, object>(Engine, Keys), false, false, false);
+            FastAddProperty("getPrototypeOf", new ClrFunctionInstance<object, object>(Engine, GetPrototypeOf, 1), true, false, true);
+            FastAddProperty("getOwnPropertyDescriptor", new ClrFunctionInstance<object, object>(Engine, GetOwnPropertyDescriptor, 2), true, false, true);
+            FastAddProperty("getOwnPropertyNames", new ClrFunctionInstance<object, object>(Engine, GetOwnPropertyNames, 1), true, false, true);
+            FastAddProperty("create", new ClrFunctionInstance<object, object>(Engine, Create, 2), true, false, true);
+            FastAddProperty("defineProperty", new ClrFunctionInstance<object, object>(Engine, DefineProperty), true, false, true);
+            FastAddProperty("defineProperties", new ClrFunctionInstance<object, object>(Engine, DefineProperties), true, false, true);
+            FastAddProperty("seal", new ClrFunctionInstance<object, object>(Engine, Seal, 1), true, false, true);
+            FastAddProperty("freeze", new ClrFunctionInstance<object, object>(Engine, Freeze, 1), true, false, true);
+            FastAddProperty("preventExtensions", new ClrFunctionInstance<object, object>(Engine, PreventExtensions, 1), true, false, true);
+            FastAddProperty("isSealed", new ClrFunctionInstance<object, object>(Engine, IsSealed, 1), true, false, true);
+            FastAddProperty("isFrozen", new ClrFunctionInstance<object, object>(Engine, IsFrozen, 1), true, false, true);
+            FastAddProperty("isExtensible", new ClrFunctionInstance<object, object>(Engine, IsExtensible, 1), true, false, true);
+            FastAddProperty("keys", new ClrFunctionInstance<object, object>(Engine, Keys), true, false, true);
         }
 
         public ObjectPrototype PrototypeObject { get; private set; }
@@ -145,6 +146,17 @@ namespace Jint.Native.Object
 
             var array = Engine.Array.Construct(Arguments.Empty);
             var n = 0;
+
+            var s = o as StringInstance;
+            if (s != null)
+            {
+                for (var i = 0; i < s.PrimitiveValue.Length; i++)
+                {
+                    array.DefineOwnProperty(n.ToString(), new DataDescriptor(i.ToString()) { Writable = true, Enumerable = true, Configurable = true }, false);
+                    n++;
+                }  
+            }
+
             foreach (var p in o.Properties)
             {
                 array.DefineOwnProperty(n.ToString(), new DataDescriptor(p.Key) { Writable = true, Enumerable = true, Configurable = true }, false);
@@ -156,14 +168,14 @@ namespace Jint.Native.Object
 
         public object Create(object thisObject, object[] arguments)
         {
-            var oArg = arguments.Length > 0 ? arguments[0] : Undefined.Instance;
-            if (TypeConverter.GetType(oArg) != Types.Object)
+            var oArg = arguments.At(0);
+            if (TypeConverter.GetType(oArg) != Types.Object && oArg != Null.Instance)
             {
                 throw new JavaScriptException(Engine.TypeError);
             }
 
             var obj = Engine.Object.Construct(Arguments.Empty);
-            obj.Prototype = thisObject as ObjectInstance;
+            obj.Prototype = oArg as ObjectInstance;
 
             var properties = arguments.Length > 1 ? arguments[1] : Undefined.Instance;
             if (properties != Undefined.Instance)
@@ -176,23 +188,19 @@ namespace Jint.Native.Object
 
         public object DefineProperty(object thisObject, object[] arguments)
         {
-            var o = arguments[0] as ObjectInstance;
-            var p = arguments[1];
-            var attributes = arguments[2] as ObjectInstance;
-            
-            if (o == null)
-            {
-                throw new JavaScriptException(Engine.TypeError);
-            }
-
-            if (attributes == null)
+            var o = arguments.At(0);
+            if (TypeConverter.GetType(o) != Types.Object)
             {
                 throw new JavaScriptException(Engine.TypeError);
             }
 
+            var p = arguments.At(1);
             var name = TypeConverter.ToString(p);
+
+            var attributes = arguments.At(2);
             var desc = PropertyDescriptor.ToPropertyDescriptor(Engine, attributes);
-            o.DefineOwnProperty(name, desc, true);
+
+            ((ObjectInstance)o).DefineOwnProperty(name, desc, true);
             return o;
         }
 
@@ -208,13 +216,17 @@ namespace Jint.Native.Object
 
             var properties = arguments.Length > 1 ? arguments[1] : Undefined.Instance;
             var props = TypeConverter.ToObject(Engine, properties);
-            var names = props.Properties.Keys;
             var descriptors = new List<KeyValuePair<string, PropertyDescriptor>>();
-            foreach (var p in names)
+            foreach (var p in props.Properties)
             {
-                var descObj = props.Get(p);
+                if (!p.Value.EnumerableIsSet)
+                {
+                    continue;
+                }
+
+                var descObj = props.Get(p.Key);
                 var desc = PropertyDescriptor.ToPropertyDescriptor(Engine, descObj);
-                descriptors.Add(new KeyValuePair<string, PropertyDescriptor>(p, desc));
+                descriptors.Add(new KeyValuePair<string, PropertyDescriptor>(p.Key, desc));
             }
             foreach (var pair in descriptors)
             {

+ 110 - 50
Jint/Native/Object/ObjectInstance.cs

@@ -1,5 +1,4 @@
-using System;
-using System.Collections.Generic;
+using System.Collections.Generic;
 using Jint.Native.Date;
 using Jint.Native.String;
 using Jint.Runtime;
@@ -61,12 +60,14 @@ namespace Jint.Native.Object
 
             var getter = desc.As<AccessorDescriptor>().Get;
 
-            if (getter == null)
+            if (getter == Undefined.Instance)
             {
                 return Undefined.Instance;
             }
 
-            return getter.Call(this, Arguments.Empty);
+            // if getter is not undefined it must be ICallable
+            var callable = (ICallable)getter;
+            return callable.Call(this, Arguments.Empty);
         }
 
         public void Set(string name, object value)
@@ -172,7 +173,7 @@ namespace Jint.Native.Object
 
             if (desc.IsAccessorDescriptor())
             {
-                var setter = desc.As<AccessorDescriptor>().Set;
+                var setter = (ICallable)desc.As<AccessorDescriptor>().Set;
                 setter.Call(this, new [] {value});
             }
             else
@@ -198,7 +199,7 @@ namespace Jint.Native.Object
             {
                 if (desc.IsAccessorDescriptor())
                 {
-                    if (desc.As<AccessorDescriptor>().Set == null)
+                    if (desc.As<AccessorDescriptor>().Set == Undefined.Instance)
                     {
                         return false;
                     }
@@ -223,7 +224,7 @@ namespace Jint.Native.Object
 
             if (inherited.IsAccessorDescriptor())
             {
-                if (inherited.As<AccessorDescriptor>().Set == null)
+                if (inherited.As<AccessorDescriptor>().Set == Undefined.Instance)
                 {
                     return false;
                 }
@@ -390,7 +391,54 @@ namespace Jint.Native.Object
                 return true;
             }
 
-            // todo: if desc and current are the same, return true
+            // Step 5
+            if(!current.Configurable.HasValue && !current.Enumerable.HasValue && !(current.IsDataDescriptor() && ((DataDescriptor)current).Writable.HasValue))
+            {
+                if (!desc.IsDataDescriptor() || desc.As<DataDescriptor>().Value == null)
+                {
+                    return true;
+                }
+            }
+
+            // Step 6
+            var configurableIsSame = current.Configurable.HasValue
+                ? desc.Configurable.HasValue && (current.Configurable.Value == desc.Configurable.Value)
+                : !desc.Configurable.HasValue;
+
+            var enumerableIsSame = current.Enumerable.HasValue
+                ? desc.Enumerable.HasValue && (current.Enumerable.Value == desc.Enumerable.Value)
+                : !desc.Enumerable.HasValue;
+
+            var writableIsSame = true;
+            var valueIsSame = true;
+
+            if (current.IsDataDescriptor() && desc.IsDataDescriptor())
+            {
+                var currentDataDescriptor = (DataDescriptor) current;
+                var descDataDescriptor = (DataDescriptor) desc;
+                writableIsSame = currentDataDescriptor.Writable.HasValue
+                ? descDataDescriptor.Writable.HasValue && (currentDataDescriptor.Writable.Value == descDataDescriptor.Writable.Value)
+                : !descDataDescriptor.Writable.HasValue;
+
+                valueIsSame = ExpressionInterpreter.SameValue(currentDataDescriptor.Value, descDataDescriptor.Value);
+            }
+            else if (current.IsAccessorDescriptor() && desc.IsAccessorDescriptor())
+            {
+                var currentAccessorDescriptor = (AccessorDescriptor) current;
+                var descAccessorDescriptor = (AccessorDescriptor) desc;
+
+                valueIsSame = ExpressionInterpreter.SameValue(currentAccessorDescriptor.Get, descAccessorDescriptor.Get)
+                              && ExpressionInterpreter.SameValue(currentAccessorDescriptor.Set, descAccessorDescriptor.Set);
+            }
+            else
+            {
+                valueIsSame = false;
+            }
+
+            if (configurableIsSame && enumerableIsSame && writableIsSame && valueIsSame)
+            {
+                return true;
+            }
 
             if (current.ConfigurableIsSetToFalse)
             {
@@ -404,7 +452,7 @@ namespace Jint.Native.Object
                     return false;
                 }
 
-                if (desc.Enumerable.HasValue && desc.Enumerable.Value != current.Enumerable.Value)
+                if (desc.Enumerable.HasValue && desc.EnumerableIsSet != current.EnumerableIsSet)
                 {
                     if (throwOnError)
                     {
@@ -415,67 +463,79 @@ namespace Jint.Native.Object
                 }
             }
 
-            if (desc.IsGenericDescriptor())
+            if (!desc.IsGenericDescriptor())
             {
-                // ????
-            }
 
-            if (current.IsDataDescriptor() != desc.IsDataDescriptor())
-            {
-                if (!current.ConfigurableIsSetToTrue)
+                if (current.IsDataDescriptor() != desc.IsDataDescriptor())
                 {
-                    if (throwOnError)
+                    if (!current.ConfigurableIsSetToTrue)
                     {
-                        throw new JavaScriptException(Engine.TypeError);
+                        if (throwOnError)
+                        {
+                            throw new JavaScriptException(Engine.TypeError);
+                        }
+
+                        return false;
                     }
 
-                    return false;
+                    if (current.IsDataDescriptor())
+                    {
+                        // todo: convert to accessor
+                    }
                 }
-
-                if (current.IsDataDescriptor())
+                else if (current.IsDataDescriptor() && desc.IsDataDescriptor())
                 {
-                    // todo: convert to accessor
-                }
-            }
-            else if (current.IsDataDescriptor() && desc.IsDataDescriptor())
-            {
-                var cd = current.As<DataDescriptor>();
-                var dd = current.As<DataDescriptor>();
+                    var cd = current.As<DataDescriptor>();
+                    var dd = current.As<DataDescriptor>();
 
-                if (!current.ConfigurableIsSetToTrue)
-                {
-                    if (!cd.WritableIsSet && dd.WritableIsSet)
+                    if (!current.ConfigurableIsSetToTrue)
                     {
-                        if (throwOnError)
+                        if (!cd.WritableIsSet && dd.WritableIsSet)
                         {
-                            throw new JavaScriptException(Engine.TypeError);
+                            if (throwOnError)
+                            {
+                                throw new JavaScriptException(Engine.TypeError);
+                            }
+
+                            return false;
                         }
 
-                        return false;
+                        if (!cd.WritableIsSet)
+                        {
+                            if (dd.Value != null && !valueIsSame)
+                            {
+                                if (throwOnError)
+                                {
+                                    throw new JavaScriptException(Engine.TypeError);
+                                }
+
+                                return false;
+                            }
+                        }
                     }
-                }
 
-                if (!dd.Writable.HasValue && cd.Writable.HasValue)
-                {
-                    dd.Enumerable = cd.Enumerable;
+                    if (!dd.Writable.HasValue && cd.Writable.HasValue)
+                    {
+                        dd.Enumerable = cd.Enumerable;
+                    }
                 }
-            }
-            else if (current.IsAccessorDescriptor() && desc.IsAccessorDescriptor())
-            {
-                var ca = current.As<AccessorDescriptor>();
-                var da = desc.As<AccessorDescriptor>();
-
-                if (!current.ConfigurableIsSetToTrue)
+                else if (current.IsAccessorDescriptor() && desc.IsAccessorDescriptor())
                 {
-                    if ( (da.Set != null && da.Set != ca.Set)
-                        || (da.Get != null && da.Get != ca.Get))
+                    var ca = current.As<AccessorDescriptor>();
+                    var da = desc.As<AccessorDescriptor>();
+
+                    if (!current.ConfigurableIsSetToTrue)
                     {
-                        if (throwOnError)
+                        if ((da.Set != Undefined.Instance && !ExpressionInterpreter.SameValue(da.Set, ca.Set))
+                            || (da.Get != Undefined.Instance && !ExpressionInterpreter.SameValue(da.Get, ca.Get)))
                         {
-                            throw new JavaScriptException(Engine.TypeError);
-                        }
+                            if (throwOnError)
+                            {
+                                throw new JavaScriptException(Engine.TypeError);
+                            }
 
-                        return false;
+                            return false;
+                        }
                     }
                 }
             }

+ 1 - 4
Jint/Native/RegExp/RegExpInstance.cs

@@ -1,7 +1,5 @@
-using System;
-using System.Text.RegularExpressions;
+using System.Text.RegularExpressions;
 using Jint.Native.Object;
-using Jint.Runtime;
 
 namespace Jint.Native.RegExp
 {
@@ -27,7 +25,6 @@ namespace Jint.Native.RegExp
         public string Pattern { get; set; }
         public string Source { get; set; }
         public string Flags { get; set; }
-        
         public bool Global { get; set; }
         public bool IgnoreCase { get; set; }
         public bool Multiline { get; set; }

+ 24 - 1
Jint/Native/RegExp/RegExpPrototype.cs

@@ -1,5 +1,4 @@
 using System.Text.RegularExpressions;
-using Jint.Native.Array;
 using Jint.Runtime;
 using Jint.Runtime.Descriptors;
 using Jint.Runtime.Interop;
@@ -29,6 +28,30 @@ namespace Jint.Native.RegExp
             FastAddProperty("toString", new ClrFunctionInstance<RegExpInstance, object>(Engine, ToRegExpString), true, false, true);
             FastAddProperty("exec", new ClrFunctionInstance<object, object>(Engine, Exec, 1), true, false, true);
             FastAddProperty("test", new ClrFunctionInstance<object, bool>(Engine, Test, 1), true, false, true);
+
+            FastAddProperty("global", new ClrFunctionInstance<RegExpInstance, bool>(Engine, GetGlobal, 1), false, false, false);
+            FastAddProperty("ignoreCase", new ClrFunctionInstance<RegExpInstance, bool>(Engine, GetIgnoreCase, 1), false, false, false);
+            FastAddProperty("multiline", new ClrFunctionInstance<RegExpInstance, bool>(Engine, GetMultiLine, 1), false, false, false);
+            FastAddProperty("source", new ClrFunctionInstance<RegExpInstance, string>(Engine, GetSource, 1), false, false, false);
+        }
+
+        private bool GetGlobal(RegExpInstance thisObj, object[] arguments)
+        {
+            return thisObj.Global;
+        }
+        private bool GetMultiLine(RegExpInstance thisObj, object[] arguments)
+        {
+            return thisObj.Multiline;
+        }
+
+        private bool GetIgnoreCase(RegExpInstance thisObj, object[] arguments)
+        {
+            return thisObj.IgnoreCase;
+        }
+
+        private string GetSource(RegExpInstance thisObj, object[] arguments)
+        {
+            return thisObj.Source;
         }
 
         private object ToRegExpString(RegExpInstance thisObj, object[] arguments)

+ 1 - 1
Jint/Native/String/StringConstructor.cs

@@ -31,7 +31,7 @@ namespace Jint.Native.String
 
         public void Configure()
         {
-            FastAddProperty("fromCharCode", new ClrFunctionInstance<object, string>(Engine, FromCharCode, 1), false, false, false);
+            FastAddProperty("fromCharCode", new ClrFunctionInstance<object, string>(Engine, FromCharCode, 1), true, false, true);
         }
 
         private static string FromCharCode(object thisObj, object[] arguments)

+ 21 - 6
Jint/Runtime/Descriptors/AccessorDescriptor.cs

@@ -1,13 +1,28 @@
-using Jint.Native;
+using System;
+using Jint.Native;
 
 namespace Jint.Runtime.Descriptors
 {
     public class AccessorDescriptor : PropertyDescriptor
     {
-        public AccessorDescriptor(ICallable get, ICallable set = null)
+        public AccessorDescriptor(object getter) : this(getter, Native.Undefined.Instance)
         {
-            Get = get;
-            Set = set;
+        }
+
+        public AccessorDescriptor(object getter, object setter)
+        {
+            if (getter == null)
+            {
+                throw new ArgumentNullException("getter", "get can only be undefined");
+            }
+
+            if (setter == null)
+            {
+                throw new ArgumentNullException("setter", "set can only be undefined");
+            }
+
+            Get = getter;
+            Set = setter;
         }
 
         public AccessorDescriptor(AccessorDescriptor a)
@@ -22,13 +37,13 @@ namespace Jint.Runtime.Descriptors
         /// The getter function
         /// </summary>
         /// <returns></returns>
-        public virtual ICallable Get { get; set; }
+        public virtual object Get { get; set; }
 
         /// <summary>
         /// The setter function
         /// </summary>
         /// <returns></returns>
-        public virtual ICallable Set { get; set; }
+        public virtual object Set { get; set; }
 
         public override bool IsAccessorDescriptor()
         {

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

@@ -92,7 +92,7 @@ namespace Jint.Runtime.Descriptors
                 desc = new DataDescriptor(value) { Configurable = configurable, Enumerable = enumerable, Writable = writable};
             }
 
-            object getter = null, setter = null;
+            object getter = Native.Undefined.Instance, setter = Native.Undefined.Instance;
             if (obj.HasProperty("get"))
             {
                 getter = obj.Get("get");
@@ -111,14 +111,14 @@ namespace Jint.Runtime.Descriptors
                 }
             }
 
-            if (getter != null || setter != null)
+            if (getter != Native.Undefined.Instance || setter != Native.Undefined.Instance)
             {
                 if (obj.HasProperty("value") || writable != null)
                 {
                     throw new JavaScriptException(engine.TypeError);
                 }
 
-                desc = new AccessorDescriptor(getter as ICallable, setter as ICallable) { Configurable = configurable, Enumerable = enumerable };
+                desc = new AccessorDescriptor(getter, setter) { Configurable = configurable, Enumerable = enumerable };
             }
 
             return desc;
@@ -142,8 +142,8 @@ namespace Jint.Runtime.Descriptors
             else
             {
                 var accdesc = desc.As<AccessorDescriptor>();
-                obj.DefineOwnProperty("get", new DataDescriptor(accdesc.Get ?? Native.Undefined.Instance) { Writable = true, Enumerable = true, Configurable = true }, false);
-                obj.DefineOwnProperty("set", new DataDescriptor(accdesc.Set ?? Native.Undefined.Instance) { Writable = true, Enumerable = true, Configurable = true }, false);
+                obj.DefineOwnProperty("get", new DataDescriptor(accdesc.Get) { Writable = true, Enumerable = true, Configurable = true }, false);
+                obj.DefineOwnProperty("set", new DataDescriptor(accdesc.Set) { Writable = true, Enumerable = true, Configurable = true }, false);
             }
 
             obj.DefineOwnProperty("enumerable", new DataDescriptor(desc.EnumerableIsSet) { Writable = true, Enumerable = true, Configurable = true }, false);

+ 7 - 7
Jint/Runtime/ExpressionIntepreter.cs

@@ -692,7 +692,7 @@ namespace Jint.Runtime
                                 StrictModeScope.IsStrictModeCode
                                 );
                         }
-                        propDesc = new AccessorDescriptor(null, set) { Enumerable = true, Configurable = true};
+                        propDesc = new AccessorDescriptor(Undefined.Instance, set) { Enumerable = true, Configurable = true};
                         break;
 
                     default:
@@ -726,26 +726,26 @@ namespace Jint.Runtime
                         var previousAccessor = previous.As<AccessorDescriptor>();
                         var propAccessor = propDesc.As<AccessorDescriptor>();
 
-                        if (propAccessor.Set != null)
+                        if (propAccessor.Set != Undefined.Instance)
                         {
-                            if (previousAccessor.Set != null)
+                            if (previousAccessor.Set != Undefined.Instance)
                             {
                                 throw new JavaScriptException(_engine.SyntaxError);
                             }
 
-                            if (previousAccessor.Get != null)
+                            if (previousAccessor.Get != Undefined.Instance)
                             {
                                 propAccessor.Get = previousAccessor.Get;
                             }
                         }
-                        else if (propAccessor.Get != null)
+                        else if (propAccessor.Get != Undefined.Instance)
                         {
-                            if (previousAccessor.Get != null)
+                            if (previousAccessor.Get != Undefined.Instance)
                             {
                                 throw new JavaScriptException(_engine.SyntaxError);
                             }
 
-                            if (previousAccessor.Set != null)
+                            if (previousAccessor.Set != Undefined.Instance)
                             {
                                 propAccessor.Set = previousAccessor.Set;
                             }