Browse Source

Changing JsValue to a class (#324)

Sébastien Ros 9 years ago
parent
commit
4cf1b7428b

+ 1 - 1
Jint.Tests/Runtime/Domain/A.cs

@@ -92,7 +92,7 @@ namespace Jint.Tests.Runtime.Domain
         }
         public string Call16(params JsValue[] values)
         {
-            return String.Join(",", values);
+            return String.Join(",", (System.Collections.Generic.IEnumerable<JsValue>)values);
         }
 
         public int Call17(Func<int, int> callback)

+ 25 - 25
Jint/Engine.cs

@@ -37,7 +37,7 @@ namespace Jint
         private int _statementsCount;
         private long _timeoutTicks;
         private SyntaxNode _lastSyntaxNode = null;
-        
+
         public ITypeConverter ClrTypeConverter;
 
         // cache of types used when resolving CLR type names
@@ -112,7 +112,7 @@ namespace Jint
 
             // create the global environment http://www.ecma-international.org/ecma-262/5.1/#sec-10.2.3
             GlobalEnvironment = LexicalEnvironment.NewObjectEnvironment(this, Global, null, false);
-            
+
             // create the global execution context http://www.ecma-international.org/ecma-262/5.1/#sec-10.4.1.1
             EnterExecutionContext(GlobalEnvironment, GlobalEnvironment, Global);
 
@@ -169,7 +169,7 @@ namespace Jint
         public ExecutionContext ExecutionContext { get { return _executionContexts.Peek(); } }
 
         internal Options Options { get; private set; }
-        
+
         #region Debugger
         public delegate StepMode DebugStepDelegate(object sender, DebugInformation e);
         public delegate StepMode BreakDelegate(object sender, DebugInformation e);
@@ -254,7 +254,7 @@ namespace Jint
         {
             _statementsCount = 0;
         }
-        
+
         public void ResetTimeoutTicks()
         {
             var timeoutIntervalTicks = Options._TimeoutInterval.Ticks;
@@ -334,7 +334,7 @@ namespace Jint
             }
 
             _lastSyntaxNode = statement;
-            
+
             if (Options._IsDebugMode)
             {
                 DebugHandler.OnStep(statement);
@@ -344,64 +344,64 @@ namespace Jint
             {
                 case SyntaxNodes.BlockStatement:
                     return _statements.ExecuteBlockStatement(statement.As<BlockStatement>());
-                    
+
                 case SyntaxNodes.BreakStatement:
                     return _statements.ExecuteBreakStatement(statement.As<BreakStatement>());
-                    
+
                 case SyntaxNodes.ContinueStatement:
                     return _statements.ExecuteContinueStatement(statement.As<ContinueStatement>());
-                    
+
                 case SyntaxNodes.DoWhileStatement:
                     return _statements.ExecuteDoWhileStatement(statement.As<DoWhileStatement>());
-                    
+
                 case SyntaxNodes.DebuggerStatement:
                     return _statements.ExecuteDebuggerStatement(statement.As<DebuggerStatement>());
-                    
+
                 case SyntaxNodes.EmptyStatement:
                     return _statements.ExecuteEmptyStatement(statement.As<EmptyStatement>());
-                    
+
                 case SyntaxNodes.ExpressionStatement:
                     return _statements.ExecuteExpressionStatement(statement.As<ExpressionStatement>());
 
                 case SyntaxNodes.ForStatement:
                     return _statements.ExecuteForStatement(statement.As<ForStatement>());
-                    
+
                 case SyntaxNodes.ForInStatement:
                     return _statements.ExecuteForInStatement(statement.As<ForInStatement>());
 
                 case SyntaxNodes.FunctionDeclaration:
                     return new Completion(Completion.Normal, null, null);
-                    
+
                 case SyntaxNodes.IfStatement:
                     return _statements.ExecuteIfStatement(statement.As<IfStatement>());
-                    
+
                 case SyntaxNodes.LabeledStatement:
                     return _statements.ExecuteLabelledStatement(statement.As<LabelledStatement>());
 
                 case SyntaxNodes.ReturnStatement:
                     return _statements.ExecuteReturnStatement(statement.As<ReturnStatement>());
-                    
+
                 case SyntaxNodes.SwitchStatement:
                     return _statements.ExecuteSwitchStatement(statement.As<SwitchStatement>());
-                    
+
                 case SyntaxNodes.ThrowStatement:
                     return _statements.ExecuteThrowStatement(statement.As<ThrowStatement>());
 
                 case SyntaxNodes.TryStatement:
                     return _statements.ExecuteTryStatement(statement.As<TryStatement>());
-                    
+
                 case SyntaxNodes.VariableDeclaration:
                     return _statements.ExecuteVariableDeclaration(statement.As<VariableDeclaration>());
-                    
+
                 case SyntaxNodes.WhileStatement:
                     return _statements.ExecuteWhileStatement(statement.As<WhileStatement>());
-                    
+
                 case SyntaxNodes.WithStatement:
                     return _statements.ExecuteWithStatement(statement.As<WithStatement>());
 
                 case SyntaxNodes.Program:
                     return _statements.ExecuteProgram(statement.As<Program>());
-                    
+
                 default:
                     throw new ArgumentOutOfRangeException();
             }
@@ -512,13 +512,13 @@ namespace Jint
                     {
                         return JsValue.Undefined;
                     }
-                    
+
                     if (desc.IsDataDescriptor())
                     {
-                        return desc.Value.Value;
+                        return desc.Value;
                     }
 
-                    var getter = desc.Get.Value;
+                    var getter = desc.Get;
                     if (getter == Undefined.Instance)
                     {
                         return Undefined.Instance;
@@ -537,7 +537,7 @@ namespace Jint
                     throw new ArgumentException();
                 }
 
-                return record.GetBindingValue(reference.GetReferencedName(), reference.IsStrict());    
+                return record.GetBindingValue(reference.GetReferencedName(), reference.IsStrict());
             }
         }
 
@@ -619,7 +619,7 @@ namespace Jint
 
             if (desc.IsAccessorDescriptor())
             {
-                var setter = (ICallable)desc.Set.Value.AsObject();
+                var setter = (ICallable)desc.Set.AsObject();
                 setter.Call(b, new[] { value });
             }
             else

+ 8 - 9
Jint/Native/Argument/ArgumentsInstance.cs

@@ -39,8 +39,8 @@ namespace Jint.Native.Argument
 
         public static ArgumentsInstance CreateArgumentsObject(Engine engine, FunctionInstance func, string[] names, JsValue[] args, EnvironmentRecord env, bool strict)
         {
-            var obj = new ArgumentsInstance(engine, self => 
-            {                
+            var obj = new ArgumentsInstance(engine, self =>
+            {
                 var len = args.Length;
                 self.FastAddProperty("length", len, true, false, true);
                 var map = engine.Object.Construct(Arguments.Empty);
@@ -91,7 +91,7 @@ namespace Jint.Native.Argument
             obj.Prototype = engine.Object.PrototypeObject;
             obj.Extensible = true;
             obj.Strict = strict;
-            
+
 
             return obj;
         }
@@ -131,8 +131,8 @@ namespace Jint.Native.Argument
             return base.GetOwnProperty(propertyName);
         }
 
-        /// Implementation from ObjectInstance official specs as the one 
-        /// in ObjectInstance is optimized for the general case and wouldn't work 
+        /// Implementation from ObjectInstance official specs as the one
+        /// in ObjectInstance is optimized for the general case and wouldn't work
         /// for arrays
         public override void Put(string propertyName, JsValue value, bool throwOnError)
         {
@@ -162,7 +162,7 @@ namespace Jint.Native.Argument
 
             if (desc.IsAccessorDescriptor())
             {
-                var setter = desc.Set.Value.TryCast<ICallable>();
+                var setter = desc.Set.TryCast<ICallable>();
                 setter.Call(new JsValue(this), new[] { value });
             }
             else
@@ -196,9 +196,9 @@ namespace Jint.Native.Argument
                     }
                     else
                     {
-                        if (desc.Value.HasValue && desc.Value.Value != Undefined.Instance)
+                        if (desc.Value != null && desc.Value != Undefined.Instance)
                         {
-                            map.Put(propertyName, desc.Value.Value, throwOnError);
+                            map.Put(propertyName, desc.Value, throwOnError);
                         }
 
                         if (desc.Writable.HasValue && desc.Writable.Value == false)
@@ -235,4 +235,3 @@ namespace Jint.Native.Argument
         }
     }
 }
- 

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

@@ -25,8 +25,8 @@ namespace Jint.Native.Array
             }
         }
 
-        /// Implementation from ObjectInstance official specs as the one 
-        /// in ObjectInstance is optimized for the general case and wouldn't work 
+        /// Implementation from ObjectInstance official specs as the one
+        /// in ObjectInstance is optimized for the general case and wouldn't work
         /// for arrays
         public override void Put(string propertyName, JsValue value, bool throwOnError)
         {
@@ -54,7 +54,7 @@ namespace Jint.Native.Array
 
             if (desc.IsAccessorDescriptor())
             {
-                var setter = desc.Set.Value.TryCast<ICallable>();
+                var setter = desc.Set.TryCast<ICallable>();
                 setter.Call(new JsValue(this), new[] { value });
             }
             else
@@ -67,19 +67,19 @@ namespace Jint.Native.Array
         public override bool DefineOwnProperty(string propertyName, PropertyDescriptor desc, bool throwOnError)
         {
             var oldLenDesc = GetOwnProperty("length");
-            var oldLen = (uint)TypeConverter.ToNumber(oldLenDesc.Value.Value);
+            var oldLen = (uint)TypeConverter.ToNumber(oldLenDesc.Value);
             uint index;
 
             if (propertyName == "length")
             {
-                if (!desc.Value.HasValue)
+                if (desc.Value == null)
                 {
                     return base.DefineOwnProperty("length", desc, throwOnError);
                 }
 
                 var newLenDesc = new PropertyDescriptor(desc);
-                uint newLen = TypeConverter.ToUint32(desc.Value.Value);
-                if (newLen != TypeConverter.ToNumber(desc.Value.Value))
+                uint newLen = TypeConverter.ToUint32(desc.Value);
+                if (newLen != TypeConverter.ToNumber(desc.Value))
                 {
                     throw new JavaScriptException(_engine.RangeError);
                 }
@@ -212,7 +212,7 @@ namespace Jint.Native.Array
 
         private uint GetLength()
         {
-            return TypeConverter.ToUint32(_length.Value.Value);
+            return TypeConverter.ToUint32(_length.Value);
         }
 
         public override IEnumerable<KeyValuePair<string, PropertyDescriptor>> GetOwnProperties()
@@ -241,7 +241,7 @@ namespace Jint.Native.Array
                 else
                 {
                     return PropertyDescriptor.Undefined;
-                } 
+                }
             }
 
             return base.GetOwnProperty(propertyName);
@@ -262,7 +262,7 @@ namespace Jint.Native.Array
                 }
 
                 base.SetOwnProperty(propertyName, desc);
-            }            
+            }
         }
 
         public override bool HasOwnProperty(string p)
@@ -309,11 +309,11 @@ namespace Jint.Native.Array
             if(d == 0 && p.Length > 1)
             {
                 // If p is a number that start with '0' and is not '0' then
-                // its ToString representation can't be the same a p. This is 
+                // its ToString representation can't be the same a p. This is
                 // not a valid array index. '01' !== ToString(ToUInt32('01'))
                 // http://www.ecma-international.org/ecma-262/5.1/#sec-15.4
 
-                return uint.MaxValue; 
+                return uint.MaxValue;
             }
 
             ulong result = (uint)d;
@@ -328,7 +328,7 @@ namespace Jint.Native.Array
                 }
 
                 result = result * 10 + (uint)d;
-                
+
                 if (result >= uint.MaxValue)
                 {
                     return uint.MaxValue;

+ 32 - 2
Jint/Native/JsValue.cs

@@ -17,7 +17,7 @@ using Jint.Runtime.Interop;
 namespace Jint.Native
 {
     [DebuggerTypeProxy(typeof(JsValueDebugView))]
-    public struct JsValue : IEquatable<JsValue>
+    public class JsValue : IEquatable<JsValue>
     {
         public readonly static JsValue Undefined = new JsValue(Types.Undefined);
         public readonly static JsValue Null = new JsValue(Types.Null);
@@ -242,6 +242,16 @@ namespace Jint.Native
 
         public bool Equals(JsValue other)
         {
+            if (other == null)
+            {
+                return false;
+            }
+
+            if(ReferenceEquals(this, other))
+            {
+                return true;
+            }
+
             if (_type != other._type)
             {
                 return false;
@@ -495,7 +505,7 @@ namespace Jint.Native
                         case "Arguments":
                         case "Object":
 #if __IOS__
-                                IDictionary<string, object> o = new Dictionary<string, object>(); 
+                                IDictionary<string, object> o = new Dictionary<string, object>();
 #else
                             IDictionary<string, object> o = new ExpandoObject();
 #endif
@@ -572,11 +582,31 @@ namespace Jint.Native
 
         public static bool operator ==(JsValue a, JsValue b)
         {
+            if ((object)a == null)
+            {
+                if ((object)b == null)
+                {
+                    return true;
+                }
+
+                return false;
+            }
+
             return a.Equals(b);
         }
 
         public static bool operator !=(JsValue a, JsValue b)
         {
+            if ((object)a == null)
+            {
+                if ((object)b == null)
+                {
+                    return false;
+                }
+
+                return true;
+            }
+
             return !a.Equals(b);
         }
 

+ 41 - 41
Jint/Native/Object/ObjectInstance.cs

@@ -21,15 +21,15 @@ namespace Jint.Native.Object
         /// The prototype of this object.
         /// </summary>
         public ObjectInstance Prototype { get; set; }
-        
+
         /// <summary>
-        /// If true, own properties may be added to the 
+        /// If true, own properties may be added to the
         /// object.
         /// </summary>
         public bool Extensible { get; set; }
 
         /// <summary>
-        /// A String value indicating a specification defined 
+        /// A String value indicating a specification defined
         /// classification of objects.
         /// </summary>
         public virtual string Class
@@ -73,10 +73,10 @@ namespace Jint.Native.Object
             if (desc.IsDataDescriptor())
             {
                 var val = desc.Value;
-                return val.HasValue ? val.Value : Undefined.Instance;
+                return val != null ? val : Undefined.Instance;
             }
 
-            var getter = desc.Get.HasValue ? desc.Get.Value : Undefined.Instance;
+            var getter = desc.Get != null ? desc.Get : Undefined.Instance;
 
             if (getter.IsUndefined())
             {
@@ -89,8 +89,8 @@ namespace Jint.Native.Object
         }
 
         /// <summary>
-        /// Returns the Property Descriptor of the named 
-        /// own property of this object, or undefined if 
+        /// Returns the Property Descriptor of the named
+        /// own property of this object, or undefined if
         /// absent.
         /// http://www.ecma-international.org/ecma-262/5.1/#sec-8.12.1
         /// </summary>
@@ -120,7 +120,7 @@ namespace Jint.Native.Object
                 // optimmized implementation
                 return x;
             }
-            
+
             return PropertyDescriptor.Undefined;
         }
 
@@ -143,7 +143,7 @@ namespace Jint.Native.Object
             {
                 return prop;
             }
-            
+
             if(Prototype == null)
             {
                 return PropertyDescriptor.Undefined;
@@ -153,8 +153,8 @@ namespace Jint.Native.Object
         }
 
         /// <summary>
-        /// Sets the specified named property to the value 
-        /// of the second parameter. The flag controls 
+        /// Sets the specified named property to the value
+        /// of the second parameter. The flag controls
         /// failure handling.
         /// </summary>
         /// <param name="propertyName"></param>
@@ -178,7 +178,7 @@ namespace Jint.Native.Object
             {
                 ownDesc.Value = value;
                 return;
-                
+
                 // as per specification
                 // var valueDesc = new PropertyDescriptor(value: value, writable: null, enumerable: null, configurable: null);
                 // DefineOwnProperty(propertyName, valueDesc, throwOnError);
@@ -190,7 +190,7 @@ namespace Jint.Native.Object
 
             if (desc.IsAccessorDescriptor())
             {
-                var setter = desc.Set.Value.TryCast<ICallable>();
+                var setter = desc.Set.TryCast<ICallable>();
                 setter.Call(new JsValue(this), new [] {value});
             }
             else
@@ -201,8 +201,8 @@ namespace Jint.Native.Object
         }
 
         /// <summary>
-        /// Returns a Boolean value indicating whether a 
-        /// [[Put]] operation with PropertyName can be 
+        /// Returns a Boolean value indicating whether a
+        /// [[Put]] operation with PropertyName can be
         /// performed.
         /// http://www.ecma-international.org/ecma-262/5.1/#sec-8.12.4
         /// </summary>
@@ -216,7 +216,7 @@ namespace Jint.Native.Object
             {
                 if (desc.IsAccessorDescriptor())
                 {
-                    if (!desc.Set.HasValue || desc.Set.Value.IsUndefined())
+                    if (desc.Set == null || desc.Set.IsUndefined())
                     {
                         return false;
                     }
@@ -241,7 +241,7 @@ namespace Jint.Native.Object
 
             if (inherited.IsAccessorDescriptor())
             {
-                if (!inherited.Set.HasValue || inherited.Set.Value.IsUndefined())
+                if (inherited.Set == null || inherited.Set.IsUndefined())
                 {
                     return false;
                 }
@@ -260,8 +260,8 @@ namespace Jint.Native.Object
         }
 
         /// <summary>
-        /// Returns a Boolean value indicating whether the 
-        /// object already has a property with the given 
+        /// Returns a Boolean value indicating whether the
+        /// object already has a property with the given
         /// name.
         /// </summary>
         /// <param name="propertyName"></param>
@@ -272,8 +272,8 @@ namespace Jint.Native.Object
         }
 
         /// <summary>
-        /// Removes the specified named own property 
-        /// from the object. The flag controls failure 
+        /// Removes the specified named own property
+        /// from the object. The flag controls failure
         /// handling.
         /// </summary>
         /// <param name="propertyName"></param>
@@ -282,7 +282,7 @@ namespace Jint.Native.Object
         public virtual bool Delete(string propertyName, bool throwOnError)
         {
             var desc = GetOwnProperty(propertyName);
-            
+
             if (desc == PropertyDescriptor.Undefined)
             {
                 return true;
@@ -305,7 +305,7 @@ namespace Jint.Native.Object
         }
 
         /// <summary>
-        /// Hint is a String. Returns a default value for the 
+        /// Hint is a String. Returns a default value for the
         /// object.
         /// </summary>
         /// <param name="hint"></param>
@@ -368,8 +368,8 @@ namespace Jint.Native.Object
         }
 
         /// <summary>
-        /// Creates or alters the named own property to 
-        /// have the state described by a Property 
+        /// Creates or alters the named own property to
+        /// have the state described by a Property
         /// Descriptor. The flag controls failure handling.
         /// </summary>
         /// <param name="propertyName"></param>
@@ -401,7 +401,7 @@ namespace Jint.Native.Object
                     {
                         SetOwnProperty(propertyName, new PropertyDescriptor(desc)
                         {
-                            Value = desc.Value.HasValue ? desc.Value : JsValue.Undefined,
+                            Value = desc.Value != null ? desc.Value : JsValue.Undefined,
                             Writable = desc.Writable.HasValue ? desc.Writable.Value : false,
                             Enumerable = desc.Enumerable.HasValue ? desc.Enumerable.Value : false,
                             Configurable = desc.Configurable.HasValue ? desc.Configurable.Value : false
@@ -423,12 +423,12 @@ namespace Jint.Native.Object
             }
 
             // Step 5
-            if (!current.Configurable.HasValue && 
+            if (!current.Configurable.HasValue &&
                 !current.Enumerable.HasValue &&
                 !current.Writable.HasValue &&
-                !current.Get.HasValue &&
-                !current.Set.HasValue &&
-                !current.Value.HasValue)
+                current.Get == null &&
+                current.Set == null &&
+                current.Value == null)
             {
 
                 return true;
@@ -440,9 +440,9 @@ namespace Jint.Native.Object
                 current.Writable == desc.Writable &&
                 current.Enumerable == desc.Enumerable &&
 
-                ((!current.Get.HasValue && !desc.Get.HasValue) || (current.Get.HasValue && desc.Get.HasValue && ExpressionInterpreter.SameValue(current.Get.Value, desc.Get.Value))) &&
-                ((!current.Set.HasValue && !desc.Set.HasValue) || (current.Set.HasValue && desc.Set.HasValue && ExpressionInterpreter.SameValue(current.Set.Value, desc.Set.Value))) &&
-                ((!current.Value.HasValue && !desc.Value.HasValue) || (current.Value.HasValue && desc.Value.HasValue && ExpressionInterpreter.StrictlyEqual(current.Value.Value, desc.Value.Value)))
+                ((current.Get == null && desc.Get == null) || (current.Get != null && desc.Get != null && ExpressionInterpreter.SameValue(current.Get, desc.Get))) &&
+                ((current.Set == null && desc.Set == null) || (current.Set != null && desc.Set != null && ExpressionInterpreter.SameValue(current.Set, desc.Set))) &&
+                ((current.Value == null && desc.Value == null) || (current.Value != null && desc.Value != null && ExpressionInterpreter.StrictlyEqual(current.Value, desc.Value)))
             ) {
                 return true;
             }
@@ -497,7 +497,7 @@ namespace Jint.Native.Object
                     else
                     {
                         SetOwnProperty(propertyName, current = new PropertyDescriptor(
-                            value: Undefined.Instance, 
+                            value: Undefined.Instance,
                             writable: null,
                             enumerable: current.Enumerable,
                             configurable: current.Configurable
@@ -520,7 +520,7 @@ namespace Jint.Native.Object
 
                         if (!current.Writable.Value)
                         {
-                            if (desc.Value.HasValue && !ExpressionInterpreter.SameValue(desc.Value.Value, current.Value.Value))
+                            if (desc.Value != null && !ExpressionInterpreter.SameValue(desc.Value, current.Value))
                             {
                                 if (throwOnError)
                                 {
@@ -536,9 +536,9 @@ namespace Jint.Native.Object
                 {
                     if (!current.Configurable.HasValue || !current.Configurable.Value)
                     {
-                        if ((desc.Set.HasValue && !ExpressionInterpreter.SameValue(desc.Set.Value, current.Set.HasValue ? current.Set.Value : Undefined.Instance))
+                        if ((desc.Set != null && !ExpressionInterpreter.SameValue(desc.Set, current.Set != null ? current.Set : Undefined.Instance))
                             ||
-                            (desc.Get.HasValue && !ExpressionInterpreter.SameValue(desc.Get.Value, current.Get.HasValue ? current.Get.Value : Undefined.Instance)))
+                            (desc.Get != null && !ExpressionInterpreter.SameValue(desc.Get, current.Get != null ? current.Get : Undefined.Instance)))
                         {
                             if (throwOnError)
                             {
@@ -551,7 +551,7 @@ namespace Jint.Native.Object
                 }
             }
 
-            if (desc.Value.HasValue)
+            if (desc.Value != null)
             {
                 current.Value = desc.Value;
             }
@@ -571,12 +571,12 @@ namespace Jint.Native.Object
                 current.Configurable = desc.Configurable;
             }
 
-            if (desc.Get.HasValue)
+            if (desc.Get != null)
             {
                 current.Get = desc.Get;
             }
 
-            if (desc.Set.HasValue)
+            if (desc.Set != null)
             {
                 current.Set = desc.Set;
             }
@@ -598,7 +598,7 @@ namespace Jint.Native.Object
         }
 
         /// <summary>
-        /// Optimized version of [[Put]] when the property is known to be already declared 
+        /// Optimized version of [[Put]] when the property is known to be already declared
         /// </summary>
         /// <param name="name"></param>
         /// <param name="value"></param>

+ 3 - 3
Jint/Runtime/Completion.cs

@@ -13,7 +13,7 @@ namespace Jint.Runtime
         public static string Return = "return";
         public static string Throw = "throw";
 
-        public Completion(string type, JsValue? value, string identifier)
+        public Completion(string type, JsValue value, string identifier)
         {
             Type = type;
             Value = value;
@@ -21,12 +21,12 @@ namespace Jint.Runtime
         }
 
         public string Type { get; private set; }
-        public JsValue? Value { get; private set; }
+        public JsValue Value { get; private set; }
         public string Identifier { get; private set; }
 
         public JsValue GetValueOrDefault()
         {
-            return Value.HasValue ? Value.Value : Undefined.Instance;
+            return Value != null ? Value : Undefined.Instance;
         }
 
         public Jint.Parser.Location Location { get; set; }

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

@@ -11,7 +11,7 @@ namespace Jint.Runtime.Descriptors
         {
         }
 
-        public PropertyDescriptor(JsValue? value, bool? writable, bool? enumerable, bool? configurable)
+        public PropertyDescriptor(JsValue value, bool? writable, bool? enumerable, bool? configurable)
         {
             Value = value;
 
@@ -31,7 +31,7 @@ namespace Jint.Runtime.Descriptors
             }
         }
 
-        public PropertyDescriptor(JsValue? get, JsValue? set, bool? enumerable = null, bool? configurable = null)
+        public PropertyDescriptor(JsValue get, JsValue set, bool? enumerable = null, bool? configurable = null)
         {
             Get = get;
             Set = set;
@@ -57,16 +57,16 @@ namespace Jint.Runtime.Descriptors
             Writable = descriptor.Writable;
         }
 
-        public JsValue? Get { get; set; }
-        public JsValue? Set { get; set; }
+        public JsValue Get { get; set; }
+        public JsValue Set { get; set; }
         public bool? Enumerable { get; set; }
         public bool? Writable { get; set; }
         public bool? Configurable { get; set; }
-        public virtual JsValue? Value { get; set; }
-        
+        public virtual JsValue Value { get; set; }
+
         public bool IsAccessorDescriptor()
         {
-            if (!Get.HasValue && !Set.HasValue)
+            if (Get ==null && Set == null)
             {
                 return false;
             }
@@ -76,7 +76,7 @@ namespace Jint.Runtime.Descriptors
 
         public bool IsDataDescriptor()
         {
-            if (!Writable.HasValue && !Value.HasValue)
+            if (!Writable.HasValue && Value == null)
             {
                 return false;
             }
@@ -150,9 +150,9 @@ namespace Jint.Runtime.Descriptors
                 desc.Set = setter;
             }
 
-            if (desc.Get.HasValue || desc.Get.HasValue)
+            if (desc.Get != null || desc.Get != null)
             {
-                if (desc.Value.HasValue || desc.Writable.HasValue)
+                if (desc.Value != null || desc.Writable.HasValue)
                 {
                     throw new JavaScriptException(engine.TypeError);
                 }
@@ -172,7 +172,7 @@ namespace Jint.Runtime.Descriptors
 
             if (desc.IsDataDescriptor())
             {
-                obj.DefineOwnProperty("value", new PropertyDescriptor(value: desc.Value.HasValue ? desc.Value : Native.Undefined.Instance, writable: true, enumerable: true, configurable: true ), false);
+                obj.DefineOwnProperty("value", new PropertyDescriptor(value: desc.Value != null ? desc.Value : Native.Undefined.Instance, writable: true, enumerable: true, configurable: true ), false);
                 obj.DefineOwnProperty("writable", new PropertyDescriptor(value: desc.Writable.HasValue && desc.Writable.Value, writable: true, enumerable: true, configurable: true), false);
             }
             else

+ 3 - 3
Jint/Runtime/Descriptors/Specialized/FieldInfoDescriptor.cs

@@ -19,7 +19,7 @@ namespace Jint.Runtime.Descriptors.Specialized
             Writable = !fieldInfo.Attributes.HasFlag(FieldAttributes.InitOnly); // don't write to fields marked as readonly
         }
 
-        public override JsValue? Value
+        public override JsValue Value
         {
             get
             {
@@ -28,7 +28,7 @@ namespace Jint.Runtime.Descriptors.Specialized
 
             set
             {
-                var currentValue = value.GetValueOrDefault();
+                var currentValue = value;
                 object obj;
                 if (_fieldInfo.FieldType == typeof (JsValue))
                 {
@@ -43,7 +43,7 @@ namespace Jint.Runtime.Descriptors.Specialized
                         obj = _engine.ClrTypeConverter.Convert(obj, _fieldInfo.FieldType, CultureInfo.InvariantCulture);
                     }
                 }
-                
+
                 _fieldInfo.SetValue(_item, obj);
             }
         }

+ 3 - 3
Jint/Runtime/Descriptors/Specialized/IndexDescriptor.cs

@@ -57,7 +57,7 @@ namespace Jint.Runtime.Descriptors.Specialized
         {
         }
 
-        public override JsValue? Value
+        public override JsValue Value
         {
             get
             {
@@ -77,7 +77,7 @@ namespace Jint.Runtime.Descriptors.Specialized
                         return JsValue.Undefined;
                     }
                 }
-                
+
                 try
                 {
                     return JsValue.FromObject(_engine, getter.Invoke(_item, parameters));
@@ -96,7 +96,7 @@ namespace Jint.Runtime.Descriptors.Specialized
                     throw new InvalidOperationException("Indexer has no public setter.");
                 }
 
-                object[] parameters = { _key, value.HasValue ? value.Value.ToObject() : null };
+                object[] parameters = { _key, value != null ? value.ToObject() : null };
                 setter.Invoke(_item, parameters);
             }
         }

+ 3 - 3
Jint/Runtime/Descriptors/Specialized/PropertyInfoDescriptor.cs

@@ -19,7 +19,7 @@ namespace Jint.Runtime.Descriptors.Specialized
             Writable = propertyInfo.CanWrite;
         }
 
-        public override JsValue? Value
+        public override JsValue Value
         {
             get
             {
@@ -28,7 +28,7 @@ namespace Jint.Runtime.Descriptors.Specialized
 
             set
             {
-                var currentValue = value.GetValueOrDefault();
+                var currentValue = value;
                 object obj;
                 if (_propertyInfo.PropertyType == typeof (JsValue))
                 {
@@ -43,7 +43,7 @@ namespace Jint.Runtime.Descriptors.Specialized
                         obj = _engine.ClrTypeConverter.Convert(obj, _propertyInfo.PropertyType, CultureInfo.InvariantCulture);
                     }
                 }
-                
+
                 _propertyInfo.SetValue(_item, obj, null);
             }
         }

+ 32 - 32
Jint/Runtime/ExpressionIntepreter.cs

@@ -51,7 +51,7 @@ namespace Jint.Runtime
 
             if (assignmentExpression.Operator == AssignmentOperator.Assign) // "="
             {
- 
+
                 if(lref.IsStrict() && lref.GetBase().TryCast<EnvironmentRecord>() != null && (lref.GetReferencedName() == "eval" || lref.GetReferencedName() == "arguments"))
                 {
                     throw new JavaScriptException(_engine.SyntaxError);
@@ -131,7 +131,7 @@ namespace Jint.Runtime
                 case AssignmentOperator.UnsignedRightShiftAssign:
                     lval = (uint)TypeConverter.ToInt32(lval) >> (int)(TypeConverter.ToUint32(rval) & 0x1F);
                     break;
-                
+
                 default:
                     throw new NotImplementedException();
 
@@ -201,7 +201,7 @@ namespace Jint.Runtime
             JsValue right = _engine.GetValue(rightExpression);
 
             JsValue value;
-              
+
             switch (expression.Operator)
             {
                 case BinaryOperator.Plus:
@@ -216,11 +216,11 @@ namespace Jint.Runtime
                         value = TypeConverter.ToNumber(lprim) + TypeConverter.ToNumber(rprim);
                     }
                     break;
-                
+
                 case BinaryOperator.Minus:
                     value = TypeConverter.ToNumber(left) - TypeConverter.ToNumber(right);
                     break;
-                
+
                 case BinaryOperator.Times:
                     if (left == Undefined.Instance || right == Undefined.Instance)
                     {
@@ -231,7 +231,7 @@ namespace Jint.Runtime
                         value = TypeConverter.ToNumber(left) * TypeConverter.ToNumber(right);
                     }
                     break;
-                
+
                 case BinaryOperator.Divide:
                     value = Divide(left, right);
                     break;
@@ -250,11 +250,11 @@ namespace Jint.Runtime
                 case BinaryOperator.Equal:
                     value = Equal(left, right);
                     break;
-                
+
                 case BinaryOperator.NotEqual:
                     value = !Equal(left, right);
                     break;
-                
+
                 case BinaryOperator.Greater:
                     value = Compare(right, left, false);
                     if (value == Undefined.Instance)
@@ -274,7 +274,7 @@ namespace Jint.Runtime
                         value = true;
                     }
                     break;
-                
+
                 case BinaryOperator.Less:
                     value = Compare(left, right);
                     if (value == Undefined.Instance)
@@ -282,7 +282,7 @@ namespace Jint.Runtime
                         value = false;
                     }
                     break;
-                
+
                 case BinaryOperator.LessOrEqual:
                     value = Compare(right, left, false);
                     if (value == Undefined.Instance || value.AsBoolean())
@@ -294,10 +294,10 @@ namespace Jint.Runtime
                         value = true;
                     }
                     break;
-                
+
                 case BinaryOperator.StrictlyEqual:
                     return StrictlyEqual(left, right);
-                
+
                 case BinaryOperator.StricltyNotEqual:
                     return !StrictlyEqual(left, right);
 
@@ -329,7 +329,7 @@ namespace Jint.Runtime
 
                     value = f.HasInstance(left);
                     break;
-                
+
                 case BinaryOperator.In:
                     if (!right.IsObject())
                     {
@@ -338,7 +338,7 @@ namespace Jint.Runtime
 
                     value = right.AsObject().HasProperty(TypeConverter.ToString(left));
                     break;
-                
+
                 default:
                     throw new NotImplementedException();
             }
@@ -670,20 +670,20 @@ namespace Jint.Runtime
                             throw new JavaScriptException(_engine.SyntaxError);
                         }
 
-                        ScriptFunctionInstance get; 
+                        ScriptFunctionInstance get;
                         using (new StrictModeScope(getter.Strict))
                         {
                             get = new ScriptFunctionInstance(
                                 _engine,
                                 getter,
-                                _engine.ExecutionContext.LexicalEnvironment, 
+                                _engine.ExecutionContext.LexicalEnvironment,
                                 StrictModeScope.IsStrictModeCode
                             );
                         }
 
                         propDesc = new PropertyDescriptor(get: get, set: null, enumerable: true, configurable:true);
                         break;
-                    
+
                     case PropertyKind.Set:
                         var setter = property.Value as FunctionExpression;
 
@@ -695,7 +695,7 @@ namespace Jint.Runtime
                         ScriptFunctionInstance set;
                         using (new StrictModeScope(setter.Strict))
                         {
-                            
+
                             set = new ScriptFunctionInstance(
                                 _engine,
                                 setter,
@@ -729,12 +729,12 @@ namespace Jint.Runtime
 
                     if (previous.IsAccessorDescriptor() && propDesc.IsAccessorDescriptor())
                     {
-                        if (propDesc.Set.HasValue && previous.Set.HasValue)
+                        if (propDesc.Set != null && previous.Set != null)
                         {
                             throw new JavaScriptException(_engine.SyntaxError);
                         }
 
-                        if (propDesc.Get.HasValue && previous.Get.HasValue)
+                        if (propDesc.Get != null && previous.Get != null)
                         {
                             throw new JavaScriptException(_engine.SyntaxError);
                         }
@@ -758,7 +758,7 @@ namespace Jint.Runtime
             var baseValue = _engine.GetValue(baseReference);
             Expression expression = memberExpression.Property;
 
-            
+
             if (!memberExpression.Computed) // index accessor ?
             {
                 expression = new Literal { Type = SyntaxNodes.Literal, Value = memberExpression.Property.As<Identifier>().Name };
@@ -837,7 +837,7 @@ namespace Jint.Runtime
             }
 
             var func = _engine.GetValue(callee);
-            
+
             var r = callee as Reference;
 
             if (_engine.Options._MaxRecursionDepth >= 0)
@@ -868,7 +868,7 @@ namespace Jint.Runtime
             {
                 throw new JavaScriptException(_engine.TypeError);
             }
-            
+
             if (r != null)
             {
                 if (r.IsPropertyReference())
@@ -891,7 +891,7 @@ namespace Jint.Runtime
             {
                 return ((EvalFunctionInstance) callable).Call(thisObject, arguments, true);
             }
-            
+
             var result = callable.Call(thisObject, arguments);
 
             if (_engine.Options._IsDebugMode)
@@ -970,10 +970,10 @@ namespace Jint.Runtime
         public JsValue EvaluateNewExpression(NewExpression newExpression)
         {
             var arguments = newExpression.Arguments.Select(EvaluateExpression).Select(_engine.GetValue).ToArray();
-            
+
             // todo: optimize by defining a common abstract class or interface
             var callee = _engine.GetValue(EvaluateExpression(newExpression.Callee)).TryCast<IConstructor>();
-            
+
             if (callee == null)
             {
                 throw new JavaScriptException(_engine.TypeError, "The object can't be used as constructor.");
@@ -999,7 +999,7 @@ namespace Jint.Runtime
                 }
                 n++;
             }
-            
+
             return a;
         }
 
@@ -1012,17 +1012,17 @@ namespace Jint.Runtime
             {
                 case UnaryOperator.Plus:
                     return TypeConverter.ToNumber(_engine.GetValue(value));
-                    
+
                 case UnaryOperator.Minus:
                     var n = TypeConverter.ToNumber(_engine.GetValue(value));
                     return double.IsNaN(n) ? double.NaN : n*-1;
-                
+
                 case UnaryOperator.BitwiseNot:
                     return ~TypeConverter.ToInt32(_engine.GetValue(value));
-                
+
                 case UnaryOperator.LogicalNot:
                     return !TypeConverter.ToBoolean(_engine.GetValue(value));
-                
+
                 case UnaryOperator.Delete:
                     r = value as Reference;
                     if (r == null)
@@ -1049,7 +1049,7 @@ namespace Jint.Runtime
                     }
                     var bindings = r.GetBase().TryCast<EnvironmentRecord>();
                     return bindings.DeleteBinding(r.GetReferencedName());
-                
+
                 case UnaryOperator.Void:
                     _engine.GetValue(value);
                     return Undefined.Instance;

+ 23 - 23
Jint/Runtime/StatementInterpreter.cs

@@ -60,7 +60,7 @@ namespace Jint.Runtime
             var result = ExecuteStatement(labelledStatement.Body);
             if (result.Type == Completion.Break && result.Identifier == labelledStatement.Label.Name)
             {
-                return new Completion(Completion.Normal, result.Value, null);    
+                return new Completion(Completion.Normal, result.Value, null);
             }
 
             return result;
@@ -79,9 +79,9 @@ namespace Jint.Runtime
             do
             {
                 var stmt = ExecuteStatement(doWhileStatement.Body);
-                if (stmt.Value.HasValue)
+                if (stmt.Value != null)
                 {
-                    v = stmt.Value.Value;
+                    v = stmt.Value;
                 }
                 if (stmt.Type != Completion.Continue || stmt.Identifier != doWhileStatement.LabelSet)
                 {
@@ -110,7 +110,7 @@ namespace Jint.Runtime
         /// <returns></returns>
         public Completion ExecuteWhileStatement(WhileStatement whileStatement)
         {
-            JsValue v = Undefined.Instance; 
+            JsValue v = Undefined.Instance;
             while (true)
             {
                 var exprRef = _engine.EvaluateExpression(whileStatement.Test);
@@ -122,9 +122,9 @@ namespace Jint.Runtime
 
                 var stmt = ExecuteStatement(whileStatement.Body);
 
-                if (stmt.Value.HasValue)
+                if (stmt.Value != null)
                 {
-                    v = stmt.Value.Value;
+                    v = stmt.Value;
                 }
 
                 if (stmt.Type != Completion.Continue || stmt.Identifier != whileStatement.LabelSet)
@@ -149,7 +149,7 @@ namespace Jint.Runtime
         /// <returns></returns>
         public Completion ExecuteForStatement(ForStatement forStatement)
         {
-            
+
             if (forStatement.Init != null)
             {
                 if (forStatement.Init.Type == SyntaxNodes.VariableDeclaration)
@@ -175,9 +175,9 @@ namespace Jint.Runtime
                 }
 
                 var stmt = ExecuteStatement(forStatement.Body);
-                if (stmt.Value.HasValue)
+                if (stmt.Value != null)
                 {
-                    v = stmt.Value.Value;
+                    v = stmt.Value;
                 }
                 if (stmt.Type == Completion.Break && (stmt.Identifier == null || stmt.Identifier == forStatement.LabelSet))
                 {
@@ -205,8 +205,8 @@ namespace Jint.Runtime
         /// <returns></returns>
         public Completion ExecuteForInStatement(ForInStatement forInStatement)
         {
-            Identifier identifier = forInStatement.Left.Type == SyntaxNodes.VariableDeclaration 
-                                        ? forInStatement.Left.As<VariableDeclaration>().Declarations.First().Id 
+            Identifier identifier = forInStatement.Left.Type == SyntaxNodes.VariableDeclaration
+                                        ? forInStatement.Left.As<VariableDeclaration>().Declarations.First().Id
                                         : forInStatement.Left.As<Identifier>();
 
             var varRef = _engine.EvaluateExpression(identifier) as Reference;
@@ -220,7 +220,7 @@ namespace Jint.Runtime
 
             var obj = TypeConverter.ToObject(_engine, experValue);
             JsValue v = Null.Instance;
-            
+
             // keys are constructed using the prototype chain
             var cursor = obj;
             var processedKeys = new HashSet<string>();
@@ -236,8 +236,8 @@ namespace Jint.Runtime
                     }
 
                     processedKeys.Add(p);
-                    
-                    // collection might be modified by inner statement 
+
+                    // collection might be modified by inner statement
                     if (!cursor.HasOwnProperty(p))
                     {
                         continue;
@@ -252,9 +252,9 @@ namespace Jint.Runtime
                     _engine.PutValue(varRef, p);
 
                     var stmt = ExecuteStatement(forInStatement.Body);
-                    if (stmt.Value.HasValue)
+                    if (stmt.Value != null)
                     {
-                        v = stmt.Value.Value;
+                        v = stmt.Value;
                     }
                     if (stmt.Type == Completion.Break)
                     {
@@ -306,8 +306,8 @@ namespace Jint.Runtime
             {
                 return new Completion(Completion.Return, Undefined.Instance, null);
             }
-            
-            var exprRef = _engine.EvaluateExpression(statement.Argument);    
+
+            var exprRef = _engine.EvaluateExpression(statement.Argument);
             return new Completion(Completion.Return, _engine.GetValue(exprRef), null);
         }
 
@@ -385,8 +385,8 @@ namespace Jint.Runtime
                     {
                         return r;
                     }
-                    
-                    v = r.Value.HasValue ? r.Value.Value : Undefined.Instance;
+
+                    v = r.Value != null ? r.Value : Undefined.Instance;
                 }
 
             }
@@ -400,7 +400,7 @@ namespace Jint.Runtime
                     return r;
                 }
 
-                v = r.Value.HasValue ? r.Value.Value : Undefined.Instance;
+                v = r.Value != null ? r.Value : Undefined.Instance;
             }
 
             return new Completion(Completion.Normal, v, null);
@@ -420,7 +420,7 @@ namespace Jint.Runtime
                     c = ExecuteStatement(statement);
                     if (c.Type != Completion.Normal)
                     {
-                        return new Completion(c.Type, c.Value.HasValue ? c.Value : sl.Value, c.Identifier)
+                        return new Completion(c.Type, c.Value != null ? c.Value : sl.Value, c.Identifier)
                         {
                             Location = c.Location
                         };
@@ -486,7 +486,7 @@ namespace Jint.Runtime
                 {
                     return b;
                 }
-            
+
                 return f;
             }