Browse Source

Refactoring PropertyDescriptor

Sebastien Ros 11 years ago
parent
commit
37bf2f5e2b

+ 4 - 0
Jint.Tests.Ecma/Ecma/15.1.3.1.cs

@@ -2,7 +2,11 @@ using Xunit;
 
 
 namespace Jint.Tests.Ecma
 namespace Jint.Tests.Ecma
 {
 {
+
+#if RELEASE
+    // Ignore in DEBUG to prevent too long running test
     [Trait("Category", "Pass")]
     [Trait("Category", "Pass")]
+#endif
     public class Test_15_1_3_1 : EcmaTest
     public class Test_15_1_3_1 : EcmaTest
     {
     {
         [Fact]
         [Fact]

+ 4 - 0
Jint.Tests.Ecma/Ecma/15.1.3.2.cs

@@ -2,7 +2,11 @@ using Xunit;
 
 
 namespace Jint.Tests.Ecma
 namespace Jint.Tests.Ecma
 {
 {
+
+#if RELEASE
+    // Ignore in DEBUG to prevent too long running test
     [Trait("Category", "Pass")]
     [Trait("Category", "Pass")]
+#endif
     public class Test_15_1_3_2 : EcmaTest
     public class Test_15_1_3_2 : EcmaTest
     {
     {
         [Fact]
         [Fact]

+ 13 - 11
Jint/Engine.cs

@@ -363,11 +363,13 @@ namespace Jint
                     {
                     {
                         return Undefined.Instance;
                         return Undefined.Instance;
                     }
                     }
+                    
                     if (desc.IsDataDescriptor())
                     if (desc.IsDataDescriptor())
                     {
                     {
-                        return desc.As<DataDescriptor>().Value;
+                        return desc.Value.Value;
                     }
                     }
-                    var getter = desc.As<AccessorDescriptor>().Get;
+
+                    var getter = desc.Get.Value;
                     if (getter == Undefined.Instance)
                     if (getter == Undefined.Instance)
                     {
                     {
                         return Undefined.Instance;
                         return Undefined.Instance;
@@ -468,7 +470,7 @@ namespace Jint
 
 
             if (desc.IsAccessorDescriptor())
             if (desc.IsAccessorDescriptor())
             {
             {
-                var setter = (ICallable)desc.As<AccessorDescriptor>().Set;
+                var setter = (ICallable)desc.Set.Value;
                 setter.Call(b, new[] { value });
                 setter.Call(b, new[] { value });
             }
             }
             else
             else
@@ -531,19 +533,19 @@ namespace Jint
                     {
                     {
                         var go = Global;
                         var go = Global;
                         var existingProp = go.GetProperty(fn);
                         var existingProp = go.GetProperty(fn);
-                        if (existingProp.ConfigurableIsSetToTrue)
+                        if (existingProp.Configurable.Value)
                         {
                         {
                             go.DefineOwnProperty(fn,
                             go.DefineOwnProperty(fn,
-                                                 new DataDescriptor(Undefined.Instance)
-                                                 {
-                                                     Writable = true,
-                                                     Enumerable = true,
-                                                     Configurable = configurableBindings
-                                                 }, true);
+                                                 new PropertyDescriptor(
+                                                     value: Undefined.Instance,
+                                                     writable: true,
+                                                     enumerable: true,
+                                                     configurable: configurableBindings
+                                                     ), true);
                         }
                         }
                         else
                         else
                         {
                         {
-                            if (existingProp.IsAccessorDescriptor() || (!existingProp.EnumerableIsSet))
+                            if (existingProp.IsAccessorDescriptor() || (!existingProp.Enumerable.Value))
                             {
                             {
                                 throw new JavaScriptException(TypeError);
                                 throw new JavaScriptException(TypeError);
                             }
                             }

+ 0 - 2
Jint/Jint.csproj

@@ -150,8 +150,6 @@
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="Runtime\Arguments.cs" />
     <Compile Include="Runtime\Arguments.cs" />
     <Compile Include="Runtime\Completion.cs" />
     <Compile Include="Runtime\Completion.cs" />
-    <Compile Include="Runtime\Descriptors\AccessorDescriptor.cs" />
-    <Compile Include="Runtime\Descriptors\DataDescriptor.cs" />
     <Compile Include="Runtime\Descriptors\PropertyDescriptor.cs" />
     <Compile Include="Runtime\Descriptors\PropertyDescriptor.cs" />
     <Compile Include="Runtime\Descriptors\Specialized\ClrDataDescriptor.cs" />
     <Compile Include="Runtime\Descriptors\Specialized\ClrDataDescriptor.cs" />
     <Compile Include="Runtime\Descriptors\Specialized\ClrAccessDescriptor.cs" />
     <Compile Include="Runtime\Descriptors\Specialized\ClrAccessDescriptor.cs" />

+ 7 - 7
Jint/Native/Argument/ArgumentsObject.cs

@@ -46,7 +46,7 @@ namespace Jint.Native.Argument
                         Func<object, object> g = n => env.GetBindingValue(name, false);
                         Func<object, object> g = n => env.GetBindingValue(name, false);
                         var p = new Action<object, object>((n, o) => env.SetMutableBinding(name, o, true));
                         var p = new Action<object, object>((n, o) => env.SetMutableBinding(name, o, true));
 
 
-                        map.DefineOwnProperty(indxStr, new ClrAccessDescriptor<object>(engine, g, p) { Configurable = true }, false);
+                        map.DefineOwnProperty(indxStr, new ClrAccessDescriptor<object>(engine, g, p) { Configurable = new Field<bool>(true) }, false);
                     }
                     }
                 }
                 }
                 indx--;
                 indx--;
@@ -67,8 +67,8 @@ namespace Jint.Native.Argument
             else
             else
             {
             {
                 var thrower = engine.Function.ThrowTypeError;
                 var thrower = engine.Function.ThrowTypeError;
-                obj.DefineOwnProperty("caller", new AccessorDescriptor(thrower, thrower) { Enumerable = false, Configurable = false }, false);
-                obj.DefineOwnProperty("callee", new AccessorDescriptor(thrower, thrower) { Enumerable = false, Configurable = false }, false);
+                obj.DefineOwnProperty("caller", new PropertyDescriptor(get: thrower, set: thrower, enumerable:false, configurable:false), false);
+                obj.DefineOwnProperty("callee", new PropertyDescriptor(get: thrower, set: thrower, enumerable: false, configurable: false), false);
             }
             }
 
 
             return obj;
             return obj;
@@ -98,7 +98,7 @@ namespace Jint.Native.Argument
                 var isMapped = ParameterMap.GetOwnProperty(propertyName);
                 var isMapped = ParameterMap.GetOwnProperty(propertyName);
                 if (isMapped != PropertyDescriptor.Undefined)
                 if (isMapped != PropertyDescriptor.Undefined)
                 {
                 {
-                    desc.As<DataDescriptor>().Value = ParameterMap.Get(propertyName);
+                    desc.Value = new Field<object>(ParameterMap.Get(propertyName));
                 }
                 }
 
 
                 return desc;
                 return desc;
@@ -129,12 +129,12 @@ namespace Jint.Native.Argument
                     }
                     }
                     else
                     else
                     {
                     {
-                        if (desc.As<DataDescriptor>().Value != null)
+                        if (desc.Value.Value != null)
                         {
                         {
-                            map.Put(propertyName, desc.As<DataDescriptor>().Value, throwOnError);
+                            map.Put(propertyName, desc.Value.Value, throwOnError);
                         }
                         }
 
 
-                        if (desc.As<DataDescriptor>().Writable.HasValue == false)
+                        if (desc.Writable.IsAbsent)
                         {
                         {
                             map.Delete(propertyName, false);
                             map.Delete(propertyName, false);
                         }
                         }

+ 26 - 21
Jint/Native/Array/ArrayInstance.cs

@@ -24,28 +24,28 @@ namespace Jint.Native.Array
 
 
         public override bool DefineOwnProperty(string propertyName, PropertyDescriptor desc, bool throwOnError)
         public override bool DefineOwnProperty(string propertyName, PropertyDescriptor desc, bool throwOnError)
         {
         {
-            var oldLenDesc = GetOwnProperty("length").As<DataDescriptor>();
-            var oldLen = TypeConverter.ToNumber(oldLenDesc.Value);
+            var oldLenDesc = GetOwnProperty("length");
+            var oldLen = TypeConverter.ToNumber(oldLenDesc.Value.Value);
             if (propertyName == "length")
             if (propertyName == "length")
             {
             {
-                var descData = desc as DataDescriptor;
-                if (descData == null)
+                if (desc.Value.IsAbsent)
                 {
                 {
                     return base.DefineOwnProperty("length", desc, throwOnError);
                     return base.DefineOwnProperty("length", desc, throwOnError);
                 }
                 }
-                
-                var newLenDesc = new DataDescriptor(desc);
-                uint newLen = TypeConverter.ToUint32(descData.Value);
-                if (newLen != TypeConverter.ToNumber(descData.Value))
+
+                var newLenDesc = new PropertyDescriptor(desc);
+                uint newLen = TypeConverter.ToUint32(desc.Value.Value);
+                if (newLen != TypeConverter.ToNumber(desc.Value.Value))
                 {
                 {
                     throw new JavaScriptException(_engine.RangeError);
                     throw new JavaScriptException(_engine.RangeError);
                 }
                 }
-                newLenDesc.Value = newLen;
+
+                newLenDesc.Value = new Field<object>(newLen);
                 if (newLen >= oldLen)
                 if (newLen >= oldLen)
                 {
                 {
                     return base.DefineOwnProperty("length", newLenDesc, throwOnError);
                     return base.DefineOwnProperty("length", newLenDesc, throwOnError);
                 }
                 }
-                if (!oldLenDesc.WritableIsSet)
+                if (!oldLenDesc.Writable.Value)
                 {
                 {
                     if (throwOnError)
                     if (throwOnError)
                     {
                     {
@@ -54,12 +54,17 @@ namespace Jint.Native.Array
 
 
                     return false;
                     return false;
                 }
                 }
-                var newWritable = true;
-                if (!newLenDesc.WritableIsSet)
+                bool newWritable;
+                if (newLenDesc.Writable.IsAbsent || newLenDesc.Writable.Value)
+                {
+                    newWritable = true;
+                }
+                else
                 {
                 {
                     newWritable = false;
                     newWritable = false;
-                    newLenDesc.Writable = true;
+                    newLenDesc.Writable = new Field<bool>(true);
                 }
                 }
+                
                 var succeeded = base.DefineOwnProperty("length", newLenDesc, throwOnError);
                 var succeeded = base.DefineOwnProperty("length", newLenDesc, throwOnError);
                 if (!succeeded)
                 if (!succeeded)
                 {
                 {
@@ -80,10 +85,10 @@ namespace Jint.Native.Array
                             var deleteSucceeded = Delete(key, false);
                             var deleteSucceeded = Delete(key, false);
                             if (!deleteSucceeded)
                             if (!deleteSucceeded)
                             {
                             {
-                                newLenDesc.Value = index + 1;
+                                newLenDesc.Value = new Field<object>(index + 1);
                                 if (!newWritable)
                                 if (!newWritable)
                                 {
                                 {
-                                    newLenDesc.Writable = false;
+                                    newLenDesc.Writable = new Field<bool>(false);
                                 }
                                 }
                                 base.DefineOwnProperty("length", newLenDesc, false);
                                 base.DefineOwnProperty("length", newLenDesc, false);
                                 if (throwOnError)
                                 if (throwOnError)
@@ -105,10 +110,10 @@ namespace Jint.Native.Array
                         var deleteSucceeded = Delete(TypeConverter.ToString(oldLen), false);
                         var deleteSucceeded = Delete(TypeConverter.ToString(oldLen), false);
                         if (!deleteSucceeded)
                         if (!deleteSucceeded)
                         {
                         {
-                            newLenDesc.Value = oldLen + 1;
+                            newLenDesc.Value = new Field<object>(oldLen + 1);
                             if (!newWritable)
                             if (!newWritable)
                             {
                             {
-                                newLenDesc.Writable = false;
+                                newLenDesc.Writable = new Field<bool>(false);
                             }
                             }
                             base.DefineOwnProperty("length", newLenDesc, false);
                             base.DefineOwnProperty("length", newLenDesc, false);
                             if (throwOnError)
                             if (throwOnError)
@@ -122,14 +127,14 @@ namespace Jint.Native.Array
                 }
                 }
                 if (!newWritable)
                 if (!newWritable)
                 {
                 {
-                    DefineOwnProperty("length", new DataDescriptor(null) {Writable = false}, false);
+                    DefineOwnProperty("length", new PropertyDescriptor(value: null, writable: false, enumerable: null, configurable: null), false);
                 }
                 }
                 return true;
                 return true;
             }
             }
             else if (IsArrayIndex(propertyName))
             else if (IsArrayIndex(propertyName))
             {
             {
                 var index = TypeConverter.ToUint32(propertyName);
                 var index = TypeConverter.ToUint32(propertyName);
-                if (index >= oldLen && !oldLenDesc.WritableIsSet)
+                if (index >= oldLen && !oldLenDesc.Writable.Value)
                 {
                 {
                     if (throwOnError)
                     if (throwOnError)
                     {
                     {
@@ -150,13 +155,13 @@ namespace Jint.Native.Array
                 }
                 }
                 if (index >= oldLen)
                 if (index >= oldLen)
                 {
                 {
-                    oldLenDesc.Value = index + 1;
+                    oldLenDesc.Value = new Field<object>(index + 1);
                     base.DefineOwnProperty("length", oldLenDesc, false);
                     base.DefineOwnProperty("length", oldLenDesc, false);
                 }
                 }
                 return true;
                 return true;
             }
             }
 
 
-            return base.DefineOwnProperty(propertyName, desc, false);
+            return base.DefineOwnProperty(propertyName, desc, throwOnError);
         }
         }
 
 
         public static bool IsArrayIndex(object p)
         public static bool IsArrayIndex(object p)

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

@@ -182,7 +182,7 @@ namespace Jint.Native.Array
                     var selected = callable.Call(thisArg, new [] { kvalue, k, o });
                     var selected = callable.Call(thisArg, new [] { kvalue, k, o });
                     if (TypeConverter.ToBoolean(selected))
                     if (TypeConverter.ToBoolean(selected))
                     {
                     {
-                        a.DefineOwnProperty(to.ToString(), new DataDescriptor(kvalue) { Writable = true, Enumerable = true, Configurable = true }, false);
+                        a.DefineOwnProperty(to.ToString(), new PropertyDescriptor(kvalue, true, true, true), false);
                         to++;
                         to++;
                     }
                     }
                 }
                 }
@@ -216,7 +216,7 @@ namespace Jint.Native.Array
                 {
                 {
                     var kvalue = o.Get(pk);
                     var kvalue = o.Get(pk);
                     var mappedValue = callable.Call(thisArg, new [] { kvalue, k, o });
                     var mappedValue = callable.Call(thisArg, new [] { kvalue, k, o });
-                    a.DefineOwnProperty(pk, new DataDescriptor(mappedValue) { Writable = true, Enumerable = true, Configurable = true }, false);
+                    a.DefineOwnProperty(pk, new PropertyDescriptor(mappedValue, true, true, true), false);
                 }
                 }
             }
             }
 
 
@@ -393,7 +393,7 @@ namespace Jint.Native.Array
                 if (fromPresent)
                 if (fromPresent)
                 {
                 {
                     var fromValue = o.Get(from); 
                     var fromValue = o.Get(from); 
-                    a.DefineOwnProperty(k.ToString(), new DataDescriptor(fromValue) { Writable = true, Enumerable = true, Configurable = true }, false);
+                    a.DefineOwnProperty(k.ToString(), new PropertyDescriptor(fromValue, true, true, true), false);
                 }
                 }
             }
             }
             
             
@@ -601,12 +601,7 @@ namespace Jint.Native.Array
                 {
                 {
                     var kValue = o.Get(pk);
                     var kValue = o.Get(pk);
                     a.DefineOwnProperty(TypeConverter.ToString(n),
                     a.DefineOwnProperty(TypeConverter.ToString(n),
-                                        new DataDescriptor(kValue)
-                                            {
-                                                Writable = true,
-                                                Enumerable = true,
-                                                Configurable = true
-                                            }, false);
+                                        new PropertyDescriptor(kValue, true, true, true), false);
                 }
                 }
                 n++;
                 n++;
             }
             }
@@ -790,21 +785,21 @@ namespace Jint.Native.Array
                         if (exists)
                         if (exists)
                         {
                         {
                             var subElement = eArray.Get(p);
                             var subElement = eArray.Get(p);
-                            a.DefineOwnProperty(TypeConverter.ToString(n), new DataDescriptor(subElement) { Writable = true, Enumerable = true, Configurable = true}, false);
+                            a.DefineOwnProperty(TypeConverter.ToString(n), new PropertyDescriptor(subElement, true, true, true), false);
                         }
                         }
                         n++;
                         n++;
                     }
                     }
                 }
                 }
                 else
                 else
                 {
                 {
-                    a.DefineOwnProperty(TypeConverter.ToString(n), new DataDescriptor(e) { Writable = true, Enumerable = true, Configurable = true }, false);
+                    a.DefineOwnProperty(TypeConverter.ToString(n), new PropertyDescriptor(e, true, true, true ), false);
                     n++;
                     n++;
                 }
                 }
             }
             }
 
 
             // this is not in the specs, but is necessary in case the last element of the last
             // this is not in the specs, but is necessary in case the last element of the last
             // array doesn't exist, and thus the length would not be incremented
             // array doesn't exist, and thus the length would not be incremented
-            a.DefineOwnProperty("length", new DataDescriptor(n), false);
+            a.DefineOwnProperty("length", new PropertyDescriptor(n, null, null, null), false);
             
             
             return a;
             return a;
         }
         }

+ 2 - 2
Jint/Native/Function/FunctionPrototype.cs

@@ -68,8 +68,8 @@ namespace Jint.Native.Function
             
             
 
 
             var thrower = Engine.Function.ThrowTypeError;
             var thrower = Engine.Function.ThrowTypeError;
-            f.DefineOwnProperty("caller", new AccessorDescriptor(thrower, thrower) { Enumerable = false, Configurable = false }, false);
-            f.DefineOwnProperty("arguments", new AccessorDescriptor(thrower, thrower) { Enumerable = false, Configurable = false }, false);
+            f.DefineOwnProperty("caller", new PropertyDescriptor(thrower, thrower, false, false), false);
+            f.DefineOwnProperty("arguments", new PropertyDescriptor(thrower, thrower, false, false), false);
 
 
 
 
             return f;
             return f;

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

@@ -33,18 +33,18 @@ namespace Jint.Native.Function
             Extensible = true;
             Extensible = true;
             Prototype = engine.Function.PrototypeObject;
             Prototype = engine.Function.PrototypeObject;
 
 
-            DefineOwnProperty("length", new DataDescriptor(FormalParameters.Length) { Writable = false, Enumerable = false, Configurable = false }, false);
+            DefineOwnProperty("length", new PropertyDescriptor(FormalParameters.Length, false, false, false ), false);
 
 
             var proto = engine.Object.Construct(Arguments.Empty);
             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("name", new DataDescriptor(_functionDeclaration.Id), false);
+            proto.DefineOwnProperty("constructor", new PropertyDescriptor(this, true, false, true), false);
+            DefineOwnProperty("prototype", new PropertyDescriptor(proto, true, false, false ), false);
+            DefineOwnProperty("name", new PropertyDescriptor(_functionDeclaration.Id, null, null, null), false);
             
             
             if (strict)
             if (strict)
             {
             {
                 var thrower = engine.Function.ThrowTypeError;
                 var thrower = engine.Function.ThrowTypeError;
-                DefineOwnProperty("caller", new AccessorDescriptor(thrower, thrower) { Enumerable = false, Configurable = false }, false);
-                DefineOwnProperty("arguments", new AccessorDescriptor(thrower, thrower) { Enumerable = false, Configurable = false }, false);
+                DefineOwnProperty("caller", new PropertyDescriptor(thrower, thrower, false, false), false);
+                DefineOwnProperty("arguments", new PropertyDescriptor(thrower, thrower, false, false), false);
             }
             }
         }
         }
 
 

+ 1 - 1
Jint/Native/Function/ThrowTypeError.cs

@@ -11,7 +11,7 @@ namespace Jint.Native.Function
         public ThrowTypeError(Engine engine): base(engine, new string[0], engine.GlobalEnvironment, false)
         public ThrowTypeError(Engine engine): base(engine, new string[0], engine.GlobalEnvironment, false)
         {
         {
             _engine = engine;
             _engine = engine;
-            DefineOwnProperty("length", new DataDescriptor(0) { Writable = false, Enumerable = false, Configurable = false }, false);
+            DefineOwnProperty("length", new PropertyDescriptor(0, false, false, false), false);
             Extensible = false;
             Extensible = false;
         }
         }
 
 

+ 45 - 0
Jint/Native/JsObject.cs

@@ -0,0 +1,45 @@
+using Jint.Native.Object;
+using Jint.Runtime;
+
+namespace Jint.Native
+{
+    public struct JsObject
+    {
+        public JsObject(bool value)
+        {
+            _bool = value;
+            _double = null;
+            _object = null;
+            _string = null;
+            _type = Types.Boolean;
+        }
+
+        public JsObject(double value)
+        {
+            _bool = null;
+            _double = value;
+            _object = null;
+            _string = null;
+            _type = Types.Number;
+        }
+
+        public JsObject(ObjectInstance value)
+        {
+            _bool = null;
+            _double = null;
+            _object = value;
+            _string = null;
+            _type = Types.Object;
+        }
+
+        private bool? _bool;
+
+        private double? _double;
+
+        private ObjectInstance _object;
+
+        private string _string;
+
+        private Types _type;
+    };
+}

+ 2 - 8
Jint/Native/Json/JsonSerializer.cs

@@ -101,13 +101,7 @@ namespace Jint.Native.Json
             }
             }
 
 
             var wrapper = _engine.Object.Construct(Arguments.Empty);
             var wrapper = _engine.Object.Construct(Arguments.Empty);
-            wrapper.DefineOwnProperty("",
-                                      new DataDescriptor(value)
-                                          {
-                                              Configurable = true,
-                                              Enumerable = true,
-                                              Writable = true
-                                          }, false);
+            wrapper.DefineOwnProperty("", new PropertyDescriptor(value, true, true, true), false);
 
 
             return Str("", wrapper);
             return Str("", wrapper);
         }
         }
@@ -299,7 +293,7 @@ namespace Jint.Native.Json
             var k = _propertyList;
             var k = _propertyList;
             if (k == null)
             if (k == null)
             {
             {
-                k = value.Properties.Where(x => x.Value.EnumerableIsSet).Select(x => x.Key).ToList();
+                k = value.Properties.Where(x => x.Value.Enumerable.Value).Select(x => x.Key).ToList();
             }
             }
             var partial = new List<string>();
             var partial = new List<string>();
             foreach (var p in k)
             foreach (var p in k)

+ 15 - 16
Jint/Native/Object/ObjectConstructor.cs

@@ -152,14 +152,14 @@ namespace Jint.Native.Object
             {
             {
                 for (var i = 0; i < s.PrimitiveValue.Length; i++)
                 for (var i = 0; i < s.PrimitiveValue.Length; i++)
                 {
                 {
-                    array.DefineOwnProperty(n.ToString(), new DataDescriptor(i.ToString()) { Writable = true, Enumerable = true, Configurable = true }, false);
+                    array.DefineOwnProperty(n.ToString(), new PropertyDescriptor(i.ToString(), true, true, true), false);
                     n++;
                     n++;
                 }  
                 }  
             }
             }
 
 
             foreach (var p in o.Properties)
             foreach (var p in o.Properties)
             {
             {
-                array.DefineOwnProperty(n.ToString(), new DataDescriptor(p.Key) { Writable = true, Enumerable = true, Configurable = true }, false);
+                array.DefineOwnProperty(n.ToString(), new PropertyDescriptor(p.Key, true, true, true), false);
                 n++;
                 n++;
             }
             }
 
 
@@ -219,7 +219,7 @@ namespace Jint.Native.Object
             var descriptors = new List<KeyValuePair<string, PropertyDescriptor>>();
             var descriptors = new List<KeyValuePair<string, PropertyDescriptor>>();
             foreach (var p in props.Properties)
             foreach (var p in props.Properties)
             {
             {
-                if (!p.Value.EnumerableIsSet)
+                if (!p.Value.Enumerable.IsPresent)
                 {
                 {
                     continue;
                     continue;
                 }
                 }
@@ -248,9 +248,9 @@ namespace Jint.Native.Object
 
 
             foreach (var prop in o.Properties)
             foreach (var prop in o.Properties)
             {
             {
-                if (prop.Value.ConfigurableIsSetToTrue)
+                if (prop.Value.Configurable.Value == true)
                 {
                 {
-                    prop.Value.Configurable = false;
+                    prop.Value.Configurable = new Field<bool>(false);
                 }
                 }
 
 
                 o.DefineOwnProperty(prop.Key, prop.Value, true);
                 o.DefineOwnProperty(prop.Key, prop.Value, true);
@@ -277,15 +277,14 @@ namespace Jint.Native.Object
                 var prop = o.Properties[key];
                 var prop = o.Properties[key];
                 if (prop.IsDataDescriptor())
                 if (prop.IsDataDescriptor())
                 {
                 {
-                    var datadesc = prop.As<DataDescriptor>();
-                    if (datadesc.WritableIsSet)
+                    if (prop.Writable.IsPresent)
                     {
                     {
-                        datadesc.Writable = false;
+                        prop.Writable = new Field<bool>(false);
                     }
                     }
                 }
                 }
-                if (prop.ConfigurableIsSetToTrue)
+                if (prop.Configurable.Value == true)
                 {
                 {
-                    prop.Configurable = false;
+                    prop.Configurable = new Field<bool>(false);
                 }
                 }
                 o.DefineOwnProperty(key, prop, true);
                 o.DefineOwnProperty(key, prop, true);
             }
             }
@@ -322,7 +321,7 @@ namespace Jint.Native.Object
 
 
             foreach (var prop in o.Properties)
             foreach (var prop in o.Properties)
             {
             {
-                if (prop.Value.ConfigurableIsSetToTrue)
+                if (prop.Value.Configurable.Value == true)
                 {
                 {
                     return false;
                     return false;
                 }
                 }
@@ -350,12 +349,12 @@ namespace Jint.Native.Object
             {
             {
                 if (prop.Value.IsDataDescriptor())
                 if (prop.Value.IsDataDescriptor())
                 {
                 {
-                    if (prop.Value.As<DataDescriptor>().WritableIsSet)
+                    if (prop.Value.Writable.IsPresent)
                     {
                     {
                         return false;
                         return false;
                     }
                     }
                 }
                 }
-                if (prop.Value.ConfigurableIsSetToTrue)
+                if (prop.Value.Configurable.Value == true)
                 {
                 {
                     return false;
                     return false;
                 }
                 }
@@ -392,12 +391,12 @@ namespace Jint.Native.Object
 
 
             var o = oArg as ObjectInstance;
             var o = oArg as ObjectInstance;
 
 
-            var n = o.Properties.Values.Count(x => x.EnumerableIsSet);
+            var n = o.Properties.Values.Count(x => x.Enumerable.Value);
             var array = Engine.Array.Construct(new object[] {n});
             var array = Engine.Array.Construct(new object[] {n});
             var index = 0;
             var index = 0;
-            foreach (var prop in o.Properties.Where(x => x.Value.EnumerableIsSet))
+            foreach (var prop in o.Properties.Where(x => x.Value.Enumerable.Value))
             {
             {
-                array.DefineOwnProperty(index.ToString(), new DataDescriptor(prop.Key) { Writable = true, Enumerable = true, Configurable = true }, false);
+                array.DefineOwnProperty(index.ToString(), new PropertyDescriptor(prop.Key, true, true, true), false);
                 index++;
                 index++;
             }
             }
             return array;
             return array;

+ 86 - 57
Jint/Native/Object/ObjectInstance.cs

@@ -55,12 +55,12 @@ namespace Jint.Native.Object
 
 
             if (desc.IsDataDescriptor())
             if (desc.IsDataDescriptor())
             {
             {
-                return desc.As<DataDescriptor>().Value;
+                return desc.Value.Value;
             }
             }
 
 
-            var getter = desc.As<AccessorDescriptor>().Get;
+            var getter = desc.Get.Value;
 
 
-            if (getter == Undefined.Instance)
+            if (getter == Undefined.Instance || getter == null)
             {
             {
                 return Undefined.Instance;
                 return Undefined.Instance;
             }
             }
@@ -75,7 +75,7 @@ namespace Jint.Native.Object
 
 
             if (!HasProperty(name))
             if (!HasProperty(name))
             {
             {
-                DefineOwnProperty(name, new DataDescriptor(value) { Configurable = true, Enumerable = true, Writable = true }, false);
+                DefineOwnProperty(name, new PropertyDescriptor(value, true, true, true), false);
             }
             }
             else
             else
             {
             {
@@ -100,11 +100,11 @@ namespace Jint.Native.Object
                 PropertyDescriptor d;
                 PropertyDescriptor d;
                 if (x.IsDataDescriptor())
                 if (x.IsDataDescriptor())
                 {
                 {
-                    d = new DataDescriptor(x.As<DataDescriptor>());
+                    d = new PropertyDescriptor(x.As<DataDescriptor>());
                 }
                 }
                 else
                 else
                 {
                 {
-                    d = new AccessorDescriptor(x.As<AccessorDescriptor>());
+                    d = new PropertyDescriptor(x.As<AccessorDescriptor>());
                 }
                 }
 
 
                 return d;
                 return d;
@@ -163,7 +163,7 @@ namespace Jint.Native.Object
 
 
             if (ownDesc.IsDataDescriptor())
             if (ownDesc.IsDataDescriptor())
             {
             {
-                var valueDesc = new DataDescriptor(value);
+                var valueDesc = new PropertyDescriptor(value, null, null, null);
                 DefineOwnProperty(propertyName, valueDesc, throwOnError);
                 DefineOwnProperty(propertyName, valueDesc, throwOnError);
                 return;
                 return;
             }
             }
@@ -173,12 +173,12 @@ namespace Jint.Native.Object
 
 
             if (desc.IsAccessorDescriptor())
             if (desc.IsAccessorDescriptor())
             {
             {
-                var setter = (ICallable)desc.As<AccessorDescriptor>().Set;
+                var setter = (ICallable)desc.Set.Value;
                 setter.Call(this, new [] {value});
                 setter.Call(this, new [] {value});
             }
             }
             else
             else
             {
             {
-                var newDesc = new DataDescriptor(value) {Writable = true, Enumerable = true, Configurable = true};
+                var newDesc = new PropertyDescriptor(value, true, true, true);
                 DefineOwnProperty(propertyName, newDesc, throwOnError);
                 DefineOwnProperty(propertyName, newDesc, throwOnError);
             }
             }
         }
         }
@@ -199,7 +199,7 @@ namespace Jint.Native.Object
             {
             {
                 if (desc.IsAccessorDescriptor())
                 if (desc.IsAccessorDescriptor())
                 {
                 {
-                    if (desc.As<AccessorDescriptor>().Set == Undefined.Instance)
+                    if (desc.Set.Value == Undefined.Instance)
                     {
                     {
                         return false;
                         return false;
                     }
                     }
@@ -207,7 +207,7 @@ namespace Jint.Native.Object
                     return true;
                     return true;
                 }
                 }
 
 
-                return desc.As<DataDescriptor>().WritableIsSet;
+                return desc.Writable.Value;
             }
             }
 
 
             if (Prototype == null)
             if (Prototype == null)
@@ -224,7 +224,7 @@ namespace Jint.Native.Object
 
 
             if (inherited.IsAccessorDescriptor())
             if (inherited.IsAccessorDescriptor())
             {
             {
-                if (inherited.As<AccessorDescriptor>().Set == Undefined.Instance)
+                if (inherited.Set.Value == Undefined.Instance)
                 {
                 {
                     return false;
                     return false;
                 }
                 }
@@ -238,7 +238,7 @@ namespace Jint.Native.Object
             }
             }
             else
             else
             {
             {
-                return inherited.As<DataDescriptor>().WritableIsSet;
+                return inherited.Writable.Value;
             }
             }
         }
         }
 
 
@@ -271,7 +271,7 @@ namespace Jint.Native.Object
                 return true;
                 return true;
             }
             }
 
 
-            if (desc.ConfigurableIsSetToTrue)
+            if (desc.Configurable.Value)
             {
             {
                 Properties.Remove(propertyName);
                 Properties.Remove(propertyName);
                 return true;
                 return true;
@@ -380,11 +380,11 @@ namespace Jint.Native.Object
                 {
                 {
                     if (desc.IsGenericDescriptor() || desc.IsDataDescriptor())
                     if (desc.IsGenericDescriptor() || desc.IsDataDescriptor())
                     {
                     {
-                        Properties[propertyName] = new DataDescriptor(desc.As<DataDescriptor>());
+                        Properties[propertyName] = new PropertyDescriptor(desc);
                     }
                     }
                     else
                     else
                     {
                     {
-                        Properties[propertyName] = new AccessorDescriptor(desc.As<AccessorDescriptor>());
+                        Properties[propertyName] = new PropertyDescriptor(desc);
                     }
                     }
                 }
                 }
 
 
@@ -392,40 +392,40 @@ namespace Jint.Native.Object
             }
             }
 
 
             // Step 5
             // Step 5
-            if(!current.Configurable.HasValue && !current.Enumerable.HasValue && !(current.IsDataDescriptor() && ((DataDescriptor)current).Writable.HasValue))
+            if(!current.Configurable.IsPresent && !current.Enumerable.IsPresent && !(current.IsDataDescriptor() && current.Writable.IsPresent))
             {
             {
-                if (!desc.IsDataDescriptor() || desc.As<DataDescriptor>().Value == null)
+                if (!desc.IsDataDescriptor() || desc.Value.Value == null)
                 {
                 {
                     return true;
                     return true;
                 }
                 }
             }
             }
 
 
             // Step 6
             // Step 6
-            var configurableIsSame = current.Configurable.HasValue
-                ? desc.Configurable.HasValue && (current.Configurable.Value == desc.Configurable.Value)
-                : !desc.Configurable.HasValue;
+            var configurableIsSame = current.Configurable.IsPresent
+                ? desc.Configurable.IsPresent && (current.Configurable.Value == desc.Configurable.Value)
+                : !desc.Configurable.IsPresent;
 
 
-            var enumerableIsSame = current.Enumerable.HasValue
-                ? desc.Enumerable.HasValue && (current.Enumerable.Value == desc.Enumerable.Value)
-                : !desc.Enumerable.HasValue;
+            var enumerableIsSame = current.Enumerable.IsPresent
+                ? desc.Enumerable.IsPresent && (current.Enumerable.Value == desc.Enumerable.Value)
+                : !desc.Enumerable.IsPresent;
 
 
             var writableIsSame = true;
             var writableIsSame = true;
             var valueIsSame = true;
             var valueIsSame = true;
 
 
             if (current.IsDataDescriptor() && desc.IsDataDescriptor())
             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;
+                var currentDataDescriptor = current;
+                var descDataDescriptor = desc;
+                writableIsSame = currentDataDescriptor.Writable.IsPresent
+                ? descDataDescriptor.Writable.IsPresent && (currentDataDescriptor.Writable.Value == descDataDescriptor.Writable.Value)
+                : !descDataDescriptor.Writable.IsPresent;
 
 
                 valueIsSame = ExpressionInterpreter.SameValue(currentDataDescriptor.Value, descDataDescriptor.Value);
                 valueIsSame = ExpressionInterpreter.SameValue(currentDataDescriptor.Value, descDataDescriptor.Value);
             }
             }
             else if (current.IsAccessorDescriptor() && desc.IsAccessorDescriptor())
             else if (current.IsAccessorDescriptor() && desc.IsAccessorDescriptor())
             {
             {
-                var currentAccessorDescriptor = (AccessorDescriptor) current;
-                var descAccessorDescriptor = (AccessorDescriptor) desc;
+                var currentAccessorDescriptor = current;
+                var descAccessorDescriptor = desc;
 
 
                 valueIsSame = ExpressionInterpreter.SameValue(currentAccessorDescriptor.Get, descAccessorDescriptor.Get)
                 valueIsSame = ExpressionInterpreter.SameValue(currentAccessorDescriptor.Get, descAccessorDescriptor.Get)
                               && ExpressionInterpreter.SameValue(currentAccessorDescriptor.Set, descAccessorDescriptor.Set);
                               && ExpressionInterpreter.SameValue(currentAccessorDescriptor.Set, descAccessorDescriptor.Set);
@@ -440,9 +440,9 @@ namespace Jint.Native.Object
                 return true;
                 return true;
             }
             }
 
 
-            if (current.ConfigurableIsSetToFalse)
+            if (current.Configurable.Value == false)
             {
             {
-                if (desc.ConfigurableIsSetToTrue)
+                if (desc.Configurable.Value)
                 {
                 {
                     if (throwOnError)
                     if (throwOnError)
                     {
                     {
@@ -452,7 +452,7 @@ namespace Jint.Native.Object
                     return false;
                     return false;
                 }
                 }
 
 
-                if (desc.Enumerable.HasValue && desc.EnumerableIsSet != current.EnumerableIsSet)
+                if (desc.Enumerable.IsPresent && desc.Enumerable.Value != current.Enumerable.Value)
                 {
                 {
                     if (throwOnError)
                     if (throwOnError)
                     {
                     {
@@ -468,7 +468,7 @@ namespace Jint.Native.Object
 
 
                 if (current.IsDataDescriptor() != desc.IsDataDescriptor())
                 if (current.IsDataDescriptor() != desc.IsDataDescriptor())
                 {
                 {
-                    if (!current.ConfigurableIsSetToTrue)
+                    if (!current.Configurable.Value)
                     {
                     {
                         if (throwOnError)
                         if (throwOnError)
                         {
                         {
@@ -480,17 +480,28 @@ namespace Jint.Native.Object
 
 
                     if (current.IsDataDescriptor())
                     if (current.IsDataDescriptor())
                     {
                     {
-                        // todo: convert to accessor
+                        Properties[propertyName] = current = new PropertyDescriptor(
+                            get: Undefined.Instance,
+                            set: Undefined.Instance,
+                            enumerable: current.Enumerable.Value, 
+                            configurable: current.Configurable.Value
+                            );
+                    }
+                    else
+                    {
+                        Properties[propertyName] = current = new PropertyDescriptor(
+                            value: Undefined.Instance, 
+                            writable: null,
+                            enumerable: current.Enumerable.Value, 
+                            configurable: current.Configurable.Value
+                            );
                     }
                     }
                 }
                 }
                 else if (current.IsDataDescriptor() && desc.IsDataDescriptor())
                 else if (current.IsDataDescriptor() && desc.IsDataDescriptor())
                 {
                 {
-                    var cd = current.As<DataDescriptor>();
-                    var dd = current.As<DataDescriptor>();
-
-                    if (!current.ConfigurableIsSetToTrue)
+                    if (current.Configurable.Value == false)
                     {
                     {
-                        if (!cd.WritableIsSet && dd.WritableIsSet)
+                        if (!current.Writable.Value && desc.Writable.Value)
                         {
                         {
                             if (throwOnError)
                             if (throwOnError)
                             {
                             {
@@ -500,9 +511,9 @@ namespace Jint.Native.Object
                             return false;
                             return false;
                         }
                         }
 
 
-                        if (!cd.WritableIsSet)
+                        if (!current.Writable.Value)
                         {
                         {
-                            if (dd.Value != null && !valueIsSame)
+                            if (desc.Value.IsPresent && !valueIsSame)
                             {
                             {
                                 if (throwOnError)
                                 if (throwOnError)
                                 {
                                 {
@@ -514,20 +525,20 @@ namespace Jint.Native.Object
                         }
                         }
                     }
                     }
 
 
-                    if (!dd.Writable.HasValue && cd.Writable.HasValue)
+                    if (desc.Writable.IsAbsent && current.Writable.IsPresent)
                     {
                     {
-                        dd.Enumerable = cd.Enumerable;
+                        desc.Enumerable = current.Enumerable;
                     }
                     }
                 }
                 }
                 else if (current.IsAccessorDescriptor() && desc.IsAccessorDescriptor())
                 else if (current.IsAccessorDescriptor() && desc.IsAccessorDescriptor())
                 {
                 {
-                    var ca = current.As<AccessorDescriptor>();
-                    var da = desc.As<AccessorDescriptor>();
-
-                    if (!current.ConfigurableIsSetToTrue)
+                    if (current.Configurable.Value == false)
                     {
                     {
-                        if ((da.Set != Undefined.Instance && !ExpressionInterpreter.SameValue(da.Set, ca.Set))
-                            || (da.Get != Undefined.Instance && !ExpressionInterpreter.SameValue(da.Get, ca.Get)))
+                        if ((desc.Set.Value != Undefined.Instance &&
+                             !ExpressionInterpreter.SameValue(desc.Set.Value, current.Set.Value))
+                            ||
+                            (desc.Get.Value != Undefined.Instance &&
+                             !ExpressionInterpreter.SameValue(desc.Get.Value, current.Get.Value)))
                         {
                         {
                             if (throwOnError)
                             if (throwOnError)
                             {
                             {
@@ -540,16 +551,34 @@ namespace Jint.Native.Object
                 }
                 }
             }
             }
 
 
-            Properties[propertyName] = desc;
+            if (desc.Value.IsPresent)
+            {
+                current.Value = desc.Value;
+            }
+
+            if (desc.Writable.IsPresent)
+            {
+                current.Writable = desc.Writable;
+            }
+
+            if (desc.Enumerable.IsPresent)
+            {
+                current.Enumerable = desc.Enumerable;
+            }
+
+            if (desc.Configurable.IsPresent)
+            {
+                current.Configurable = desc.Configurable;
+            }
 
 
-            if (!desc.Configurable.HasValue && current.Configurable.HasValue)
+            if (desc.Get.IsPresent)
             {
             {
-                desc.Configurable = current.Configurable;
+                current.Get = desc.Get;
             }
             }
 
 
-            if (!desc.Enumerable.HasValue && current.Enumerable.HasValue)
+            if (desc.Set.IsPresent)
             {
             {
-                desc.Enumerable = current.Enumerable;
+                current.Set = desc.Set;
             }
             }
 
 
             return true;
             return true;
@@ -565,7 +594,7 @@ namespace Jint.Native.Object
         /// <param name="enumerable"></param>
         /// <param name="enumerable"></param>
         public void FastAddProperty(string name, object value, bool writable, bool enumerable, bool configurable)
         public void FastAddProperty(string name, object value, bool writable, bool enumerable, bool configurable)
         {
         {
-            Properties.Add(name, new DataDescriptor(value) { Writable = writable, Enumerable = enumerable, Configurable = configurable });
+            Properties.Add(name, new PropertyDescriptor(value, writable, enumerable, configurable));
         }
         }
 
 
         /// <summary>
         /// <summary>

+ 1 - 1
Jint/Native/Object/ObjectPrototype.cs

@@ -39,7 +39,7 @@ namespace Jint.Native.Object
             {
             {
                 return false;
                 return false;
             }
             }
-            return desc.EnumerableIsSet;
+            return desc.Enumerable.Value;
         }
         }
 
 
         private object ValueOf(object thisObject, object[] arguments)
         private object ValueOf(object thisObject, object[] arguments)

+ 4 - 4
Jint/Native/RegExp/RegExpConstructor.cs

@@ -36,8 +36,8 @@ namespace Jint.Native.RegExp
 
 
         public override object Call(object thisObject, object[] arguments)
         public override object Call(object thisObject, object[] arguments)
         {
         {
-            var pattern = arguments.Length > 0 ? arguments[0] : Undefined.Instance;
-            var flags = arguments.Length > 1 ? arguments[1] : Undefined.Instance;
+            var pattern = arguments.At(0);
+            var flags = arguments.At(1);
 
 
             if (pattern != Undefined.Instance && flags == Undefined.Instance && TypeConverter.ToObject(Engine, pattern).Class == "Regex")
             if (pattern != Undefined.Instance && flags == Undefined.Instance && TypeConverter.ToObject(Engine, pattern).Class == "Regex")
             {
             {
@@ -57,8 +57,8 @@ namespace Jint.Native.RegExp
             string p;
             string p;
             string f;
             string f;
 
 
-            var pattern = arguments.Length > 0 ? arguments[0] : Undefined.Instance;
-            var flags = arguments.Length > 1 ? arguments[1] : Undefined.Instance;
+            var pattern = arguments.At(0);
+            var flags = arguments.At(1);
 
 
             var r = pattern as RegExpInstance;
             var r = pattern as RegExpInstance;
             if (pattern != null && flags == Undefined.Instance && r != null)
             if (pattern != null && flags == Undefined.Instance && r != null)

+ 4 - 4
Jint/Native/RegExp/RegExpPrototype.cs

@@ -118,14 +118,14 @@ namespace Jint.Native.RegExp
             var n = r.Groups.Count;
             var n = r.Groups.Count;
             var a = Engine.Array.Construct(Arguments.Empty);
             var a = Engine.Array.Construct(Arguments.Empty);
             var matchIndex = r.Index;
             var matchIndex = r.Index;
-            a.DefineOwnProperty("index", new DataDescriptor(matchIndex) { Writable = true, Enumerable = true, Configurable = true }, true);
-            a.DefineOwnProperty("input", new DataDescriptor(s) { Writable = true, Enumerable = true, Configurable = true }, true);
-            a.DefineOwnProperty("length", new DataDescriptor(n) { Writable = true, Enumerable = true, Configurable = true }, true);
+            a.DefineOwnProperty("index", new PropertyDescriptor(matchIndex, writable: true, enumerable: true, configurable: true), true);
+            a.DefineOwnProperty("input", new PropertyDescriptor(s, writable: true, enumerable: true, configurable: true), true);
+            a.DefineOwnProperty("length", new PropertyDescriptor(value: n, writable:null, enumerable: null, configurable:null), true);
             for (var k = 0; k < n; k++)
             for (var k = 0; k < n; k++)
             {
             {
                 var group = r.Groups[k];
                 var group = r.Groups[k];
                 var value = group.Success ? group.Value : Undefined.Instance;
                 var value = group.Success ? group.Value : Undefined.Instance;
-                a.DefineOwnProperty(k.ToString(), new DataDescriptor(value) { Writable = true, Enumerable = true, Configurable = true }, true);
+                a.DefineOwnProperty(k.ToString(), new PropertyDescriptor(value, true, true, true), true);
             
             
             }
             }
 
 

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

@@ -52,7 +52,7 @@ namespace Jint.Native.String
                 return PropertyDescriptor.Undefined;
                 return PropertyDescriptor.Undefined;
             }
             }
             var resultStr = str[index].ToString();
             var resultStr = str[index].ToString();
-            return new DataDescriptor(resultStr) {Enumerable = true, Writable = false, Configurable = false};
+            return new PropertyDescriptor(resultStr, false, true, false);
         }
         }
     }
     }
 }
 }

+ 4 - 4
Jint/Native/String/StringPrototype.cs

@@ -164,7 +164,7 @@ namespace Jint.Native.String
                     }
                     }
 
 
                     // Add the match results to the array.
                     // Add the match results to the array.
-                    a.DefineOwnProperty(index++.ToString(), new DataDescriptor(s.Substring(lastIndex, match.Index - lastIndex)) {Writable = true, Enumerable = true,Configurable = true}, false);
+                    a.DefineOwnProperty(index++.ToString(), new PropertyDescriptor(s.Substring(lastIndex, match.Index - lastIndex), true, true, true), false);
                     
                     
                     if (index >= limit)
                     if (index >= limit)
                     {
                     {
@@ -181,7 +181,7 @@ namespace Jint.Native.String
                             item = match.Groups[i].Value;
                             item = match.Groups[i].Value;
                         }
                         }
 
 
-                        a.DefineOwnProperty(index++.ToString(), new DataDescriptor(item) { Writable = true, Enumerable = true, Configurable = true }, false);
+                        a.DefineOwnProperty(index++.ToString(), new PropertyDescriptor(item, true, true, true ), false);
 
 
                         if (index >= limit)
                         if (index >= limit)
                         {
                         {
@@ -202,7 +202,7 @@ namespace Jint.Native.String
                 var segments = s.Split(new [] { sep }, StringSplitOptions.None);
                 var segments = s.Split(new [] { sep }, StringSplitOptions.None);
                 for (int i = 0; i < segments.Length && i < limit; i++)
                 for (int i = 0; i < segments.Length && i < limit; i++)
                 {
                 {
-                    a.DefineOwnProperty(i.ToString(), new DataDescriptor(segments[i]) {Writable = true, Enumerable = true, Configurable=true} , false);
+                    a.DefineOwnProperty(i.ToString(), new PropertyDescriptor(segments[i], true, true, true), false);
                 }
                 }
             
             
                 return a;
                 return a;
@@ -432,7 +432,7 @@ namespace Jint.Native.String
                         }
                         }
 
 
                         var matchStr = result.Get("0");
                         var matchStr = result.Get("0");
-                        a.DefineOwnProperty(TypeConverter.ToString(n), new DataDescriptor(matchStr) { Writable = true, Enumerable = true, Configurable = true}, false);
+                        a.DefineOwnProperty(TypeConverter.ToString(n), new PropertyDescriptor(matchStr, true, true, true), false);
                         n++;
                         n++;
                     }
                     }
                 }
                 }

+ 0 - 58
Jint/Runtime/Descriptors/AccessorDescriptor.cs

@@ -1,58 +0,0 @@
-using System;
-using Jint.Native;
-
-namespace Jint.Runtime.Descriptors
-{
-    public class AccessorDescriptor : PropertyDescriptor
-    {
-        public AccessorDescriptor(object getter) : this(getter, Native.Undefined.Instance)
-        {
-        }
-
-        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)
-        {
-            Get = a.Get;
-            Set = a.Set;
-            Configurable = a.Configurable;
-            Enumerable = a.Enumerable;
-        }
-
-        /// <summary>
-        /// The getter function
-        /// </summary>
-        /// <returns></returns>
-        public virtual object Get { get; set; }
-
-        /// <summary>
-        /// The setter function
-        /// </summary>
-        /// <returns></returns>
-        public virtual object Set { get; set; }
-
-        public override bool IsAccessorDescriptor()
-        {
-            return true;
-        }
-
-        public override bool IsDataDescriptor()
-        {
-            return false;
-        }
-    }
-}

+ 0 - 43
Jint/Runtime/Descriptors/DataDescriptor.cs

@@ -1,43 +0,0 @@
-namespace Jint.Runtime.Descriptors
-{
-    public class DataDescriptor : PropertyDescriptor
-    {
-        public DataDescriptor(object value) : this(value, true, null, null)
-        {
-        }
-
-        public DataDescriptor(DataDescriptor d) : this(d.Value, d.Writable, d.Enumerable, d.Configurable)
-        {
-        }
-
-        public DataDescriptor(object value, bool? writable, bool? enumerable, bool? configurable)
-        {
-            Value = value;
-            Writable = writable;
-            Enumerable = enumerable;
-            Configurable = configurable;
-        }
-
-        public object Value { get; set; }
-        /// <summary>
-        /// If false, attempts by ECMAScript code to change the 
-        /// property‘s [[Value]] attribute using [[Put]] will not succeed.
-        /// </summary>
-        public bool? Writable { get; set; }
-
-        public bool WritableIsSet
-        {
-            get { return Writable.HasValue && Writable.Value; }
-        }
-
-        public override bool IsAccessorDescriptor()
-        {
-            return false;
-        }
-
-        public override bool IsDataDescriptor()
-        {
-            return true;
-        }
-    }
-}

+ 173 - 81
Jint/Runtime/Descriptors/PropertyDescriptor.cs

@@ -1,55 +1,165 @@
-using Jint.Native;
+using System.Collections.Generic;
+using Jint.Native;
 using Jint.Native.Object;
 using Jint.Native.Object;
 
 
 namespace Jint.Runtime.Descriptors
 namespace Jint.Runtime.Descriptors
 {
 {
-    /// <summary>
-    /// An element of a javascript object
-    /// </summary>
-    public abstract class PropertyDescriptor
+    public enum Fields
     {
     {
-        public static PropertyDescriptor Undefined = new UndefinedPropertyDescriptor();
+        Get,
+        Set,
+        Enumerable,
+        Configurable,
+        Writable,
+        Value
+    }
 
 
-        /// <summary>
-        /// If true, the property will be enumerated by a for-in 
-        /// enumeration (see 12.6.4). Otherwise, the property is said 
-        /// to be non-enumerable.
-        /// </summary>
-        public bool? Enumerable { get; set; }
+    public interface IPropertyField
+    {
+        bool IsPresent { get; }
+
+        bool IsAbsent { get; }
+
+        object Value { get; }
+    }
+
+    public struct Field<T> : IPropertyField
+    {
+        private readonly T _field;
+        private readonly bool _present;
 
 
-        public bool EnumerableIsSet
+        public Field(T value)
         {
         {
-            get { return Enumerable.HasValue && Enumerable.Value; }
+            _field = value;
+            _present = true;
         }
         }
 
 
-        /// <summary>
-        /// If false, attempts to delete the property, change the 
-        /// property to be a data property, or change its attributes will 
-        /// fail.
-        /// </summary>
-        public bool? Configurable { get; set; }
+        public bool IsPresent
+        {
+            get { return _present; }
+        }
 
 
-        public bool ConfigurableIsSetToTrue
+        public bool IsAbsent
         {
         {
-            get { return Configurable.HasValue && Configurable.Value; }
+            get { return !_present; }
         }
         }
 
 
-        public bool ConfigurableIsSetToFalse
+        public T Value
         {
         {
-            get { return Configurable.HasValue && !Configurable.Value; }
+            get
+            {
+                return _field;
+            }
         }
         }
 
 
-        /// <summary>
-        /// http://www.ecma-international.org/ecma-262/5.1/#sec-8.10.1
-        /// </summary>
-        /// <returns></returns>
-        public abstract bool IsAccessorDescriptor();
+        bool IPropertyField.IsPresent
+        {
+            get { return IsPresent; }
+        }
 
 
-        /// <summary>
-        /// http://www.ecma-international.org/ecma-262/5.1/#sec-8.10.2
-        /// </summary>
-        /// <returns></returns>
-        public abstract bool IsDataDescriptor();
+        bool IPropertyField.IsAbsent
+        {
+            get { return IsAbsent; }
+        }
+
+        object IPropertyField.Value
+        {
+            get
+            {
+                return Value;
+            }
+        }
+    }
+
+    public class PropertyDescriptor
+    {
+        public static PropertyDescriptor Undefined = new PropertyDescriptor();
+
+        public PropertyDescriptor()
+        {
+            Get = new Field<object>();
+            Set = new Field<object>();
+            Value = new Field<object>();
+            Enumerable = new Field<bool>();
+            Configurable = new Field<bool>();
+            Writable = new Field<bool>();
+        }
+
+        public PropertyDescriptor(object value, bool? writable, bool? enumerable, bool? configurable)
+        {
+            Value = value == null ? new Field<object>() : new Field<object>(value);
+            Writable = writable == null ? new Field<bool>() : new Field<bool>(writable.Value);
+            Enumerable = enumerable == null ? new Field<bool>() : new Field<bool>(enumerable.Value);
+            Configurable = configurable == null ? new Field<bool>() : new Field<bool>(configurable.Value);
+
+            Get = new Field<object>();
+            Set = new Field<object>();
+        }
+
+        public PropertyDescriptor(object get, object set, bool? enumerable = null, bool? configurable = null)
+        {
+            Get = get == null ? new Field<object>() : new Field<object>(get);
+            Set = set == null ? new Field<object>() : new Field<object>(set);
+
+            Enumerable = enumerable == null ? new Field<bool>() : new Field<bool>(enumerable.Value);
+            Configurable = configurable == null ? new Field<bool>() : new Field<bool>(configurable.Value);
+
+            Value = new Field<object>();
+            Writable = new Field<bool>();
+        }
+
+        public PropertyDescriptor(PropertyDescriptor descriptor)
+        {
+            Get = descriptor.Get;
+            Set = descriptor.Set;
+            Value = descriptor.Value;
+            Enumerable = descriptor.Enumerable;
+            Configurable = descriptor.Configurable;
+            Writable = descriptor.Writable;
+        }
+
+        public Field<object> Get { get; set; }
+        public Field<object> Set { get; set; }
+        public Field<bool> Enumerable { get; set; }
+        public Field<bool> Writable { get; set; }
+        public Field<bool> Configurable { get; set; }
+        public Field<object> Value { get; set; }
+
+        public IDictionary<string, IPropertyField> AllFields
+        {
+            get
+            {
+                return new Dictionary<string, IPropertyField>
+                {
+                    {"Get", Get},
+                    {"Set", Set},
+                    {"Enumerable", Enumerable},
+                    {"Configurable", Configurable},
+                    {"Writable", Writable},
+                    {"Value", Value},
+                };
+            }
+        }
+
+        public bool IsAccessorDescriptor()
+        {
+            if (Get.IsAbsent && Set.IsAbsent)
+            {
+                return false;
+            }
+
+            return true;
+        }
+
+        public bool IsDataDescriptor()
+        {
+            if (Writable.IsAbsent && Value.IsAbsent)
+            {
+                return false;
+            }
+
+            return true;
+        }
 
 
         /// <summary>
         /// <summary>
         /// http://www.ecma-international.org/ecma-262/5.1/#sec-8.10.3
         /// http://www.ecma-international.org/ecma-262/5.1/#sec-8.10.3
@@ -60,11 +170,6 @@ namespace Jint.Runtime.Descriptors
             return !IsDataDescriptor() && !IsAccessorDescriptor();
             return !IsDataDescriptor() && !IsAccessorDescriptor();
         }
         }
 
 
-        public T As<T>() where T : PropertyDescriptor
-        {
-            return (T)this;
-        }
-
         public static PropertyDescriptor ToPropertyDescriptor(Engine engine, object o)
         public static PropertyDescriptor ToPropertyDescriptor(Engine engine, object o)
         {
         {
             var obj = o as ObjectInstance;
             var obj = o as ObjectInstance;
@@ -80,45 +185,55 @@ namespace Jint.Runtime.Descriptors
                 throw new JavaScriptException(engine.TypeError);
                 throw new JavaScriptException(engine.TypeError);
             }
             }
 
 
-            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?);
+            var desc = new PropertyDescriptor();
 
 
-            PropertyDescriptor desc = new DataDescriptor(Native.Undefined.Instance) { Configurable = configurable, Enumerable = enumerable, Writable = writable };
+            if (obj.HasProperty("enumerable"))
+            {
+                desc.Enumerable = new Field<bool>(TypeConverter.ToBoolean(obj.Get("enumerable")));
+            }
+
+            if (obj.HasProperty("configurable"))
+            {
+                desc.Configurable = new Field<bool>(TypeConverter.ToBoolean(obj.Get("configurable")));
+            }
 
 
             if (obj.HasProperty("value"))
             if (obj.HasProperty("value"))
             {
             {
                 var value = obj.Get("value");
                 var value = obj.Get("value");
-                desc = new DataDescriptor(value) { Configurable = configurable, Enumerable = enumerable, Writable = writable};
+                desc.Value = new Field<object>(value);
+            }
+
+            if (obj.HasProperty("writable"))
+            {
+                desc.Writable = new Field<bool>(TypeConverter.ToBoolean(obj.Get("writable")));
             }
             }
 
 
-            object getter = Native.Undefined.Instance, setter = Native.Undefined.Instance;
             if (obj.HasProperty("get"))
             if (obj.HasProperty("get"))
             {
             {
-                getter = obj.Get("get");
+                var getter = obj.Get("get");
                 if (getter != Native.Undefined.Instance && !(getter is ICallable))
                 if (getter != Native.Undefined.Instance && !(getter is ICallable))
                 {
                 {
                     throw new JavaScriptException(engine.TypeError);
                     throw new JavaScriptException(engine.TypeError);
                 }
                 }
+                desc.Get = new Field<object>(getter);
             }
             }
 
 
             if (obj.HasProperty("set"))
             if (obj.HasProperty("set"))
             {
             {
-                setter = obj.Get("set");
+                var setter = obj.Get("set");
                 if (setter != Native.Undefined.Instance && !(setter is ICallable))
                 if (setter != Native.Undefined.Instance && !(setter is ICallable))
                 {
                 {
                     throw new JavaScriptException(engine.TypeError);
                     throw new JavaScriptException(engine.TypeError);
                 }
                 }
+                desc.Set = new Field<object>(setter);
             }
             }
 
 
-            if (getter != Native.Undefined.Instance || setter != Native.Undefined.Instance)
+            if (desc.Get.IsPresent || desc.Get.IsPresent)
             {
             {
-                if (obj.HasProperty("value") || writable != null)
+                if (desc.Value.IsPresent || desc.Writable.IsPresent)
                 {
                 {
                     throw new JavaScriptException(engine.TypeError);
                     throw new JavaScriptException(engine.TypeError);
                 }
                 }
-
-                desc = new AccessorDescriptor(getter, setter) { Configurable = configurable, Enumerable = enumerable };
             }
             }
 
 
             return desc;
             return desc;
@@ -126,7 +241,7 @@ namespace Jint.Runtime.Descriptors
 
 
         public static object FromPropertyDescriptor(Engine engine, PropertyDescriptor desc)
         public static object FromPropertyDescriptor(Engine engine, PropertyDescriptor desc)
         {
         {
-            if (desc == PropertyDescriptor.Undefined)
+            if (desc == Undefined)
             {
             {
                 return Native.Undefined.Instance;
                 return Native.Undefined.Instance;
             }
             }
@@ -135,42 +250,19 @@ namespace Jint.Runtime.Descriptors
 
 
             if (desc.IsDataDescriptor())
             if (desc.IsDataDescriptor())
             {
             {
-                var datadesc = desc.As<DataDescriptor>();
-                obj.DefineOwnProperty("value", new DataDescriptor(datadesc.Value) { Writable = true, Enumerable = true, Configurable = true }, false);
-                obj.DefineOwnProperty("writable", new DataDescriptor(datadesc.WritableIsSet) { Writable = true, Enumerable = true, Configurable = true }, false);
+                obj.DefineOwnProperty("value", new PropertyDescriptor(value: desc.Value.Value, writable: true, enumerable: true, configurable: true ), false);
+                obj.DefineOwnProperty("writable", new PropertyDescriptor(value: desc.Writable.IsPresent && desc.Writable.Value, writable: true, enumerable: true, configurable: true ), false);
             }
             }
             else
             else
             {
             {
-                var accdesc = desc.As<AccessorDescriptor>();
-                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("get", new PropertyDescriptor(desc.Get.Value ?? Native.Undefined.Instance, writable: true, enumerable: true, configurable: true ), false);
+                obj.DefineOwnProperty("set", new PropertyDescriptor(desc.Set.Value ?? Native.Undefined.Instance, writable: true, enumerable: true, configurable: true), false);
             }
             }
 
 
-            obj.DefineOwnProperty("enumerable", new DataDescriptor(desc.EnumerableIsSet) { Writable = true, Enumerable = true, Configurable = true }, false);
-            obj.DefineOwnProperty("configurable", new DataDescriptor(desc.ConfigurableIsSetToTrue) { Writable = true, Enumerable = true, Configurable = true }, false);
+            obj.DefineOwnProperty("enumerable", new PropertyDescriptor(value: desc.Enumerable.IsPresent && desc.Enumerable.Value, writable: true, enumerable: true, configurable: true), false);
+            obj.DefineOwnProperty("configurable", new PropertyDescriptor(value: desc.Configurable.IsPresent && desc.Configurable.Value, writable: true, enumerable: true, configurable: true), false);
 
 
             return obj;
             return obj;
         }
         }
-
-        /// <summary>
-        /// Local implementation used to create a singleton representing 
-        /// an undefined result of a PropertyDescriptor. This prevents the rest
-        /// of the code to return 'object' in order to be able to return
-        /// Undefined.Instance
-        /// </summary>
-        internal sealed class UndefinedPropertyDescriptor : PropertyDescriptor
-        {
-            public override bool IsAccessorDescriptor()
-            {
-                return false;
-            }
-
-            public override bool IsDataDescriptor()
-            {
-                return false;
-            }
-        }
-
-
     }
     }
 }
 }

+ 3 - 13
Jint/Runtime/Descriptors/Specialized/ClrAccessDescriptor.cs

@@ -3,7 +3,7 @@ using Jint.Runtime.Interop;
 
 
 namespace Jint.Runtime.Descriptors.Specialized
 namespace Jint.Runtime.Descriptors.Specialized
 {
 {
-    public sealed class ClrAccessDescriptor<T> : AccessorDescriptor
+    public sealed class ClrAccessDescriptor<T> : PropertyDescriptor
     {
     {
         public ClrAccessDescriptor(Engine engine, Func<T, object> get)
         public ClrAccessDescriptor(Engine engine, Func<T, object> get)
             : this(engine, get, null)
             : this(engine, get, null)
@@ -12,20 +12,10 @@ namespace Jint.Runtime.Descriptors.Specialized
 
 
         public ClrAccessDescriptor(Engine engine, Func<T, object> get, Action<T, object> set)
         public ClrAccessDescriptor(Engine engine, Func<T, object> get, Action<T, object> set)
             : base(
             : base(
-                new GetterFunctionInstance<T>(engine, get),
-                set == null ? null : new SetterFunctionInstance<T>(engine, set)
+                get: new GetterFunctionInstance<T>(engine, get),
+                set: set == null ? Native.Undefined.Instance : new SetterFunctionInstance<T>(engine, set)
                 )
                 )
         {
         {
         }
         }
-
-        public override bool IsAccessorDescriptor()
-        {
-            return true;
-        }
-
-        public override bool IsDataDescriptor()
-        {
-            return false;
-        }
     }
     }
 }
 }

+ 2 - 12
Jint/Runtime/Descriptors/Specialized/ClrDataDescriptor.cs

@@ -3,21 +3,11 @@ using Jint.Runtime.Interop;
 
 
 namespace Jint.Runtime.Descriptors.Specialized
 namespace Jint.Runtime.Descriptors.Specialized
 {
 {
-    public sealed class ClrDataDescriptor<TObject, TResult> : DataDescriptor
+    public sealed class ClrDataDescriptor<TObject, TResult> : PropertyDescriptor
     {
     {
         public ClrDataDescriptor(Engine engine, Func<TObject, object[], TResult> func)
         public ClrDataDescriptor(Engine engine, Func<TObject, object[], TResult> func)
-            : base(new ClrFunctionInstance<TObject, TResult>(engine, func))
+            : base(value: new ClrFunctionInstance<TObject, TResult>(engine, func), writable: null, enumerable: null, configurable: null)
         {
         {
         }
         }
-
-        public override bool IsAccessorDescriptor()
-        {
-            return false;
-        }
-
-        public override bool IsDataDescriptor()
-        {
-            return true;
-        }
     }
     }
 }
 }

+ 1 - 1
Jint/Runtime/Environments/ObjectEnvironmentRecord.cs

@@ -33,7 +33,7 @@ namespace Jint.Runtime.Environments
         /// <param name="configurable"></param>
         /// <param name="configurable"></param>
         public override void CreateMutableBinding(string name, bool configurable = true)
         public override void CreateMutableBinding(string name, bool configurable = true)
         {
         {
-            _bindingObject.DefineOwnProperty(name, new DataDescriptor(Undefined.Instance, true, true, configurable), true);
+            _bindingObject.DefineOwnProperty(name, new PropertyDescriptor(Undefined.Instance, true, true, configurable), true);
         }
         }
 
 
         public override void SetMutableBinding(string name, object value, bool strict)
         public override void SetMutableBinding(string name, object value, bool strict)

+ 14 - 37
Jint/Runtime/ExpressionIntepreter.cs

@@ -648,7 +648,7 @@ namespace Jint.Runtime
                     case PropertyKind.Data:
                     case PropertyKind.Data:
                         var exprValue = _engine.EvaluateExpression(property.Value);
                         var exprValue = _engine.EvaluateExpression(property.Value);
                         var propValue = _engine.GetValue(exprValue);
                         var propValue = _engine.GetValue(exprValue);
-                        propDesc = new DataDescriptor(propValue) {Writable=true, Enumerable=true,Configurable = true};
+                        propDesc = new PropertyDescriptor(propValue, true, true, true);
                         break;
                         break;
 
 
                     case PropertyKind.Get:
                     case PropertyKind.Get:
@@ -670,7 +670,7 @@ namespace Jint.Runtime
                             );
                             );
                         }
                         }
 
 
-                        propDesc = new AccessorDescriptor(get) { Enumerable = true, Configurable = true};
+                        propDesc = new PropertyDescriptor(get: get, set: null, enumerable: true, configurable:true);
                         break;
                         break;
                     
                     
                     case PropertyKind.Set:
                     case PropertyKind.Set:
@@ -692,63 +692,40 @@ namespace Jint.Runtime
                                 StrictModeScope.IsStrictModeCode
                                 StrictModeScope.IsStrictModeCode
                                 );
                                 );
                         }
                         }
-                        propDesc = new AccessorDescriptor(Undefined.Instance, set) { Enumerable = true, Configurable = true};
+                        propDesc = new PropertyDescriptor(get:null, set: set, enumerable: true, configurable: true);
                         break;
                         break;
 
 
                     default:
                     default:
                         throw new ArgumentOutOfRangeException();
                         throw new ArgumentOutOfRangeException();
                 }
                 }
 
 
-                if (previous != Undefined.Instance)
+                if (previous != PropertyDescriptor.Undefined)
                 {
                 {
-                    var previousIsData = previous.IsDataDescriptor();
-                    var previousIsAccessor = previous.IsAccessorDescriptor();
-                    var propIsData = propDesc.IsDataDescriptor();
-                    var propIsAccessor = propDesc.IsAccessorDescriptor();
-
-                    if (StrictModeScope.IsStrictModeCode && previousIsData && propIsData)
+                    if (StrictModeScope.IsStrictModeCode && previous.IsDataDescriptor() && propDesc.IsDataDescriptor())
                     {
                     {
                         throw new JavaScriptException(_engine.SyntaxError);
                         throw new JavaScriptException(_engine.SyntaxError);
                     }
                     }
 
 
-                    if (previousIsData && propIsAccessor)
+                    if (previous.IsDataDescriptor() && propDesc.IsAccessorDescriptor())
                     {
                     {
                         throw new JavaScriptException(_engine.SyntaxError);
                         throw new JavaScriptException(_engine.SyntaxError);
                     }
                     }
 
 
-                    if (previousIsAccessor && propIsData)
+                    if (previous.IsAccessorDescriptor() && propDesc.IsDataDescriptor())
                     {
                     {
                         throw new JavaScriptException(_engine.SyntaxError);
                         throw new JavaScriptException(_engine.SyntaxError);
                     }
                     }
 
 
-                    if (previousIsAccessor && propIsAccessor)
+                    if (previous.IsAccessorDescriptor() && propDesc.IsAccessorDescriptor())
                     {
                     {
-                        var previousAccessor = previous.As<AccessorDescriptor>();
-                        var propAccessor = propDesc.As<AccessorDescriptor>();
-
-                        if (propAccessor.Set != Undefined.Instance)
+                        if (propDesc.Set.IsPresent && previous.Set.IsPresent)
                         {
                         {
-                            if (previousAccessor.Set != Undefined.Instance)
-                            {
-                                throw new JavaScriptException(_engine.SyntaxError);
-                            }
-
-                            if (previousAccessor.Get != Undefined.Instance)
-                            {
-                                propAccessor.Get = previousAccessor.Get;
-                            }
+                            throw new JavaScriptException(_engine.SyntaxError);
                         }
                         }
-                        else if (propAccessor.Get != Undefined.Instance)
+                        
+                        if (propDesc.Get.IsPresent && previous.Get.IsPresent)
                         {
                         {
-                            if (previousAccessor.Get != Undefined.Instance)
-                            {
-                                throw new JavaScriptException(_engine.SyntaxError);
-                            }
-
-                            if (previousAccessor.Set != Undefined.Instance)
-                            {
-                                propAccessor.Set = previousAccessor.Set;
-                            }
+                            throw new JavaScriptException(_engine.SyntaxError);
                         }
                         }
                     }
                     }
                 }
                 }
@@ -951,7 +928,7 @@ namespace Jint.Runtime
                 {
                 {
                     var value = _engine.GetValue(EvaluateExpression(expr));
                     var value = _engine.GetValue(EvaluateExpression(expr));
                     a.DefineOwnProperty(n.ToString(),
                     a.DefineOwnProperty(n.ToString(),
-                        new DataDescriptor(value) {Writable = true, Enumerable = true, Configurable = true}, false);
+                        new PropertyDescriptor(value, true, true, true), false);
                 }
                 }
                 n++;
                 n++;
             }
             }

+ 1 - 1
Jint/Runtime/StatementInterpreter.cs

@@ -245,7 +245,7 @@ namespace Jint.Runtime
                     }
                     }
 
 
                     var value = cursor.Properties[p];
                     var value = cursor.Properties[p];
-                    if (!value.EnumerableIsSet)
+                    if (!value.Enumerable.Value)
                     {
                     {
                         continue;
                         continue;
                     }
                     }