Selaa lähdekoodia

Fixing unit tests

Sebastien Ros 11 vuotta sitten
vanhempi
commit
936d5eb9fe

+ 2 - 2
Jint/Engine.cs

@@ -184,7 +184,7 @@ namespace Jint
                 var result = _statements.ExecuteProgram(program);
                 if (result.Type == Completion.Throw)
                 {
-                    throw new JavaScriptException(result.Value);
+                    throw new JavaScriptException(result.GetValueOrDefault());
                 }
 
                 return GetValue(result.Value);
@@ -223,7 +223,7 @@ namespace Jint
                     return _statements.ExecuteForInStatement(statement.As<ForInStatement>());
 
                 case SyntaxNodes.FunctionDeclaration:
-                    return new Completion(Completion.Normal, Undefined.Instance, null);
+                    return new Completion(Completion.Normal, null, null);
                     
                 case SyntaxNodes.IfStatement:
                     return _statements.ExecuteIfStatement(statement.As<IfStatement>());

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

@@ -875,7 +875,7 @@ namespace Jint.Native.Array
         public JsValue Push(JsValue thisObject, JsValue[] arguments)
         {
             ObjectInstance o = TypeConverter.ToObject(Engine, thisObject);
-            var lenVal = o.Get("length").AsNumber();
+            var lenVal = TypeConverter.ToNumber(o.Get("length"));
             
             // cast to double as we need to prevent an overflow
             double n = TypeConverter.ToUint32(lenVal);
@@ -893,7 +893,8 @@ namespace Jint.Native.Array
         public JsValue Pop(JsValue thisObject, JsValue[] arguments)
         {
             ObjectInstance o = TypeConverter.ToObject(Engine, thisObject);
-            var lenVal = o.Get("length").AsNumber();
+            var lenVal = TypeConverter.ToNumber(o.Get("length"));
+
             uint len = TypeConverter.ToUint32(lenVal);
             if (len == 0)
             {

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

@@ -33,10 +33,9 @@ namespace Jint.Native.Boolean
         private JsValue ValueOf(JsValue thisObj, JsValue[] arguments)
         {
             var B = thisObj;
-            object b;
             if (B.IsBoolean())
             {
-                b = B;
+                return B;
             }
             else
             {
@@ -50,8 +49,6 @@ namespace Jint.Native.Boolean
                     throw new JavaScriptException(Engine.TypeError);
                 }
             }
-
-            return (bool)b;
         }
 
         private JsValue ToBooleanString(JsValue thisObj, JsValue[] arguments)

+ 4 - 3
Jint/Native/Error/ErrorPrototype.cs

@@ -43,14 +43,15 @@ namespace Jint.Native.Error
 
             var name = TypeConverter.ToString(o.Get("name"));
 
-            var msg = o.Get("message");
-            if (msg == Undefined.Instance)
+            var msgProp = o.Get("message");
+            string msg;
+            if (msgProp == Undefined.Instance)
             {
                 msg = "";
             }
             else
             {
-                msg = TypeConverter.ToString(msg);
+                msg = TypeConverter.ToString(msgProp);
             }
             if (name == "")
             {

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

@@ -58,11 +58,11 @@ namespace Jint.Native.Function
 
                             if (result.Type == Completion.Throw)
                             {
-                                throw new JavaScriptException(result.Value);
+                                throw new JavaScriptException(result.GetValueOrDefault());
                             }
                             else
                             {
-                                return result.Value;
+                                return result.GetValueOrDefault();
                             }
                         }
                         finally

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

@@ -97,12 +97,12 @@ namespace Jint.Native.Function
 
                     if (result.Type == Completion.Throw)
                     {
-                        throw new JavaScriptException(result.Value);
+                        throw new JavaScriptException(result.GetValueOrDefault());
                     }
 
                     if (result.Type == Completion.Return)
                     {
-                        return result.Value;
+                        return result.GetValueOrDefault();
                     }
                 }
                 finally

+ 8 - 12
Jint/Native/JsValue.cs

@@ -125,18 +125,16 @@ namespace Jint.Native
         [Pure]
         public T TryCast<T>(Action<JsValue> fail = null) where T: class
         {
-            if (!this.IsObject())
+            if (this.IsObject())
             {
-                return null;
+                var o = this.AsObject();
+                var t = o as T;
+                if (t != null)
+                {
+                    return t;
+                }
             }
 
-            var o = this.AsObject();
-            var t = o as T;
-            if (t != null)
-            {
-                return t;
-            }
-            
             if (fail != null)
             {
                 fail(this);
@@ -252,7 +250,7 @@ namespace Jint.Native
 
             if (System.Array.IndexOf(NumberTypes, value.GetType()) != -1)
             {
-                return (double) value;
+                return Convert.ToDouble(value);
             }
 
             if (value is bool)
@@ -366,6 +364,4 @@ namespace Jint.Native
         public static JsValue Instance = JsValue.Null;
         public static string Text = "null";
     }
-
-
 }

+ 3 - 2
Jint/Native/Object/ObjectConstructor.cs

@@ -165,8 +165,9 @@ namespace Jint.Native.Object
         public JsValue Create(JsValue thisObject, JsValue[] arguments)
         {
             var oArg = arguments.At(0);
+
             var o = oArg.TryCast<ObjectInstance>();
-            if (o == null)
+            if (o == null && oArg != Null.Instance)
             {
                 throw new JavaScriptException(Engine.TypeError);
             }
@@ -216,7 +217,7 @@ namespace Jint.Native.Object
             var descriptors = new List<KeyValuePair<string, PropertyDescriptor>>();
             foreach (var p in props.Properties)
             {
-                if (!p.Value.Enumerable.HasValue)
+                if (!p.Value.Enumerable.HasValue || !p.Value.Enumerable.Value.AsBoolean())
                 {
                     continue;
                 }

+ 37 - 13
Jint/Native/Object/ObjectInstance.cs

@@ -55,7 +55,7 @@ namespace Jint.Native.Object
 
             if (desc.IsDataDescriptor())
             {
-                return desc.Value.Value;
+                return desc.Value.HasValue ? desc.Value.Value : Undefined.Instance;
             }
 
             var getter = desc.Get.HasValue ? desc.Get.Value : Undefined.Instance;
@@ -416,15 +416,39 @@ namespace Jint.Native.Object
                 ? descDataDescriptor.Writable.HasValue && (currentDataDescriptor.Writable.Value == descDataDescriptor.Writable.Value)
                 : !descDataDescriptor.Writable.HasValue;
 
-                valueIsSame = ExpressionInterpreter.SameValue(currentDataDescriptor.Value.Value, descDataDescriptor.Value.Value);
+                var valueA = currentDataDescriptor.Value.HasValue
+                    ? currentDataDescriptor.Value.Value
+                    : Undefined.Instance;
+
+                var valueB = descDataDescriptor.Value.HasValue
+                                    ? descDataDescriptor.Value.Value
+                                    : Undefined.Instance;
+
+                valueIsSame = ExpressionInterpreter.SameValue(valueA, valueB);
             }
             else if (current.IsAccessorDescriptor() && desc.IsAccessorDescriptor())
             {
                 var currentAccessorDescriptor = current;
                 var descAccessorDescriptor = desc;
 
-                valueIsSame = ExpressionInterpreter.SameValue(currentAccessorDescriptor.Get.Value, descAccessorDescriptor.Get.Value)
-                              && ExpressionInterpreter.SameValue(currentAccessorDescriptor.Set.Value, descAccessorDescriptor.Set.Value);
+                var getValueA = currentAccessorDescriptor.Get.HasValue
+                    ? currentAccessorDescriptor.Get.Value
+                    : Undefined.Instance;
+
+                var getValueB = descAccessorDescriptor.Get.HasValue
+                                    ? descAccessorDescriptor.Get.Value
+                                    : Undefined.Instance;
+
+                var setValueA = currentAccessorDescriptor.Set.HasValue
+                   ? currentAccessorDescriptor.Set.Value
+                   : Undefined.Instance;
+
+                var setValueB = descAccessorDescriptor.Set.HasValue
+                                    ? descAccessorDescriptor.Set.Value
+                                    : Undefined.Instance;
+
+                valueIsSame = ExpressionInterpreter.SameValue(getValueA, getValueB)
+                              && ExpressionInterpreter.SameValue(setValueA, setValueB);
             }
             else
             {
@@ -448,7 +472,7 @@ namespace Jint.Native.Object
                     return false;
                 }
 
-                if (desc.Enumerable.HasValue && desc.Enumerable.Value != current.Enumerable.Value)
+                if (desc.Enumerable.HasValue && (!current.Enumerable.HasValue || desc.Enumerable.Value != current.Enumerable.Value))
                 {
                     if (throwOnError)
                     {
@@ -464,7 +488,7 @@ namespace Jint.Native.Object
 
                 if (current.IsDataDescriptor() != desc.IsDataDescriptor())
                 {
-                    if (!current.Configurable.Value.AsBoolean())
+                    if (!current.Configurable.HasValue || !current.Configurable.Value.AsBoolean())
                     {
                         if (throwOnError)
                         {
@@ -479,8 +503,8 @@ namespace Jint.Native.Object
                         Properties[propertyName] = current = new PropertyDescriptor(
                             get: Undefined.Instance,
                             set: Undefined.Instance,
-                            enumerable: current.Enumerable.Value.AsBoolean(), 
-                            configurable: current.Configurable.Value.AsBoolean()
+                            enumerable: current.Enumerable.HasValue && current.Enumerable.Value.AsBoolean(),
+                            configurable: current.Configurable.HasValue && current.Configurable.Value.AsBoolean()
                             );
                     }
                     else
@@ -488,16 +512,16 @@ namespace Jint.Native.Object
                         Properties[propertyName] = current = new PropertyDescriptor(
                             value: Undefined.Instance, 
                             writable: null,
-                            enumerable: current.Enumerable.Value.AsBoolean(), 
-                            configurable: current.Configurable.Value.AsBoolean()
+                            enumerable: current.Enumerable.HasValue && current.Enumerable.Value.AsBoolean(),
+                            configurable: current.Configurable.HasValue && current.Configurable.Value.AsBoolean()
                             );
                     }
                 }
                 else if (current.IsDataDescriptor() && desc.IsDataDescriptor())
                 {
-                    if (current.Configurable.Value.AsBoolean() == false)
+                    if (!current.Configurable.HasValue || current.Configurable.Value.AsBoolean() == false)
                     {
-                        if (!current.Writable.Value.AsBoolean() && desc.Writable.Value.AsBoolean())
+                        if (!current.Writable.HasValue || !current.Writable.Value.AsBoolean() && desc.Writable.HasValue && desc.Writable.Value.AsBoolean())
                         {
                             if (throwOnError)
                             {
@@ -531,7 +555,7 @@ namespace Jint.Native.Object
                     if (!current.Configurable.HasValue || !current.Configurable.Value.AsBoolean())
                     {
                         if ((desc.Set.HasValue && desc.Set.Value != Undefined.Instance &&
-                             !ExpressionInterpreter.SameValue(desc.Set.Value, current.Set.Value))
+                            !ExpressionInterpreter.SameValue(desc.Set.Value, current.Set.HasValue ? current.Set.Value : Undefined.Instance))
                             ||
                             (desc.Get.HasValue && desc.Get.Value != Undefined.Instance &&
                              !ExpressionInterpreter.SameValue(desc.Get.Value, current.Get.Value)))

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

@@ -49,19 +49,24 @@ namespace Jint.Native.Object
 
         private JsValue IsPrototypeOf(JsValue thisObject, JsValue[] arguments)
         {
-            var v = arguments[0];
-            if (!v.IsObject())
+            var arg = arguments[0];
+            if (!arg.IsObject())
             {
                 return false;
             }
 
+            var v = arg.AsObject();
+
             var o = TypeConverter.ToObject(Engine, thisObject);
             while (true)
             {
-                if (v.AsObject().Prototype == null)
+                v = v.Prototype;
+
+                if (v == null)
                 {
                     return false;
                 }
+
                 if (o == v)
                 {
                     return true;

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

@@ -61,12 +61,12 @@ namespace Jint.Native.RegExp
             var flags = arguments.At(1);
 
             var r = pattern.TryCast<RegExpInstance>();
-            if (pattern.AsString() != null && flags == Undefined.Instance && r != null)
+            if (pattern.IsString() && flags == Undefined.Instance && r != null)
             {
                 p = r.Pattern;
                 f = r.Flags;
             }
-            else if (pattern.AsString() != null && flags != Undefined.Instance && r != null)
+            else if (pattern.IsString() && flags != Undefined.Instance && r != null)
             {
                 throw new JavaScriptException(Engine.TypeError);
             }

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

@@ -122,7 +122,7 @@ namespace Jint.Native.RegExp
             var matchIndex = r.Index;
             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);
+            a.DefineOwnProperty("length", new PropertyDescriptor(value: n, writable:false, enumerable: false, configurable:false), true);
             for (var k = 0; k < n; k++)
             {
                 var group = r.Groups[k];

+ 6 - 3
Jint/Runtime/Completion.cs

@@ -13,17 +13,20 @@ 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;
             Identifier = identifier;
         }
 
-
         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;
+        }
     }
 }

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

@@ -76,7 +76,7 @@ namespace Jint.Runtime.Descriptors
         
         public bool IsAccessorDescriptor()
         {
-            if (!Get.HasValue && !Get.HasValue)
+            if (!Get.HasValue && !Set.HasValue)
             {
                 return false;
             }
@@ -182,7 +182,7 @@ namespace Jint.Runtime.Descriptors
 
             if (desc.IsDataDescriptor())
             {
-                obj.DefineOwnProperty("value", new PropertyDescriptor(value: desc.Value.Value, writable: true, enumerable: true, configurable: true ), false);
+                obj.DefineOwnProperty("value", new PropertyDescriptor(value: desc.Value.HasValue ? desc.Value.Value : Native.Undefined.Instance, writable: true, enumerable: true, configurable: true ), false);
                 obj.DefineOwnProperty("writable", new PropertyDescriptor(value: desc.Writable.HasValue && desc.Writable.Value.AsBoolean(), writable: true, enumerable: true, configurable: true), false);
             }
             else

+ 28 - 26
Jint/Runtime/StatementInterpreter.cs

@@ -24,7 +24,7 @@ namespace Jint.Runtime
 
         public Completion ExecuteEmptyStatement(EmptyStatement emptyStatement)
         {
-            return new Completion(Completion.Normal, Undefined.Instance, null);
+            return new Completion(Completion.Normal, null, null);
         }
 
         public Completion ExecuteExpressionStatement(ExpressionStatement expressionStatement)
@@ -48,7 +48,7 @@ namespace Jint.Runtime
             }
             else
             {
-                return new Completion(Completion.Normal, Null.Instance, null);
+                return new Completion(Completion.Normal, null, null);
             }
 
             return result;
@@ -73,15 +73,15 @@ namespace Jint.Runtime
         /// <returns></returns>
         public Completion ExecuteDoWhileStatement(DoWhileStatement doWhileStatement)
         {
-            JsValue v = Null.Instance;
+            JsValue v = Undefined.Instance;
             bool iterating;
 
             do
             {
                 var stmt = ExecuteStatement(doWhileStatement.Body);
-                if (stmt.Value != Undefined.Instance)
+                if (stmt.Value.HasValue)
                 {
-                    v = stmt.Value;
+                    v = stmt.Value.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 = Null.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 != Null.Instance)
+                if (stmt.Value.HasValue)
                 {
-                    v = stmt.Value;
+                    v = stmt.Value.Value;
                 }
 
                 if (stmt.Type != Completion.Continue || stmt.Identifier != whileStatement.LabelSet)
@@ -162,7 +162,7 @@ namespace Jint.Runtime
                 }
             }
 
-            JsValue v = Null.Instance;
+            JsValue v = Undefined.Instance;
             while (true)
             {
                 if (forStatement.Test != null)
@@ -175,9 +175,9 @@ namespace Jint.Runtime
                 }
 
                 var stmt = ExecuteStatement(forStatement.Body);
-                if (stmt.Value != Null.Instance)
+                if (stmt.Value.HasValue)
                 {
-                    v = stmt.Value;
+                    v = stmt.Value.Value;
                 }
                 if (stmt.Type == Completion.Break && (stmt.Identifier == null || stmt.Identifier == forStatement.LabelSet))
                 {
@@ -214,7 +214,7 @@ namespace Jint.Runtime
             var experValue = _engine.GetValue(exprRef);
             if (experValue == Undefined.Instance || experValue == Null.Instance)
             {
-                return new Completion(Completion.Normal, Null.Instance, null);
+                return new Completion(Completion.Normal, null, null);
             }
 
 
@@ -252,15 +252,15 @@ namespace Jint.Runtime
                     _engine.PutValue(varRef, p);
 
                     var stmt = ExecuteStatement(forInStatement.Body);
-                    if (stmt.Value != Null.Instance)
+                    if (stmt.Value.HasValue)
                     {
-                        v = stmt.Value;
+                        v = stmt.Value.Value;
                     }
-                    if (stmt.Type == Completion.Break /* todo: complete */)
+                    if (stmt.Type == Completion.Break)
                     {
                         return new Completion(Completion.Normal, v, null);
                     }
-                    if (stmt.Type != Completion.Continue /* todo: complete */)
+                    if (stmt.Type != Completion.Continue)
                     {
                         if (stmt.Type != Completion.Normal)
                         {
@@ -282,7 +282,7 @@ namespace Jint.Runtime
         /// <returns></returns>
         public Completion ExecuteContinueStatement(ContinueStatement continueStatement)
         {
-            return new Completion(Completion.Continue, Null.Instance, continueStatement.Label != null ? continueStatement.Label.Name : null);
+            return new Completion(Completion.Continue, null, continueStatement.Label != null ? continueStatement.Label.Name : null);
         }
 
         /// <summary>
@@ -292,7 +292,7 @@ namespace Jint.Runtime
         /// <returns></returns>
         public Completion ExecuteBreakStatement(BreakStatement breakStatement)
         {
-            return new Completion(Completion.Break, Null.Instance, breakStatement.Label != null ? breakStatement.Label.Name : null);
+            return new Completion(Completion.Break, null, breakStatement.Label != null ? breakStatement.Label.Name : null);
         }
 
         /// <summary>
@@ -359,7 +359,7 @@ namespace Jint.Runtime
 
         public Completion ExecuteSwitchBlock(IEnumerable<SwitchCase> switchBlock, JsValue input)
         {
-            JsValue v = Null.Instance;
+            JsValue v = Undefined.Instance;
             SwitchCase defaultCase = null;
             bool hit = false;
             foreach (var clause in switchBlock)
@@ -384,7 +384,8 @@ namespace Jint.Runtime
                     {
                         return r;
                     }
-                    v = r.Value;
+                    
+                    v = r.Value.HasValue ? r.Value.Value : Undefined.Instance;
                 }
 
             }
@@ -397,7 +398,8 @@ namespace Jint.Runtime
                 {
                     return r;
                 }
-                v = r.Value;
+
+                v = r.Value.HasValue ? r.Value.Value : Undefined.Instance;
             }
 
             return new Completion(Completion.Normal, v, null);
@@ -405,7 +407,7 @@ namespace Jint.Runtime
 
         public Completion ExecuteStatementList(IEnumerable<Statement> statementList)
         {
-            var c = new Completion(Completion.Normal, Null.Instance, null);
+            var c = new Completion(Completion.Normal, null, null);
             Completion sl = c;
 
             try
@@ -415,7 +417,7 @@ namespace Jint.Runtime
                     c = ExecuteStatement(statement);
                     if (c.Type != Completion.Normal)
                     {
-                        return new Completion(c.Type, c.Value != Null.Instance ? c.Value : sl.Value, c.Identifier);
+                        return new Completion(c.Type, c.Value.HasValue ? c.Value : sl.Value, c.Identifier);
                     }
 
                     sl = c;
@@ -426,7 +428,7 @@ namespace Jint.Runtime
                 return new Completion(Completion.Throw, v.Error, null);
             }
 
-            return new Completion(c.Type, c.Value != Null.Instance ? c.Value : sl.Value, c.Identifier);
+            return new Completion(c.Type, c.GetValueOrDefault(), c.Identifier);
         }
 
         /// <summary>
@@ -511,7 +513,7 @@ namespace Jint.Runtime
                 }
             }
 
-            return new Completion(Completion.Normal, Null.Instance, null);
+            return new Completion(Completion.Normal, Undefined.Instance, null);
         }
 
         public Completion ExecuteBlockStatement(BlockStatement blockStatement)
@@ -528,7 +530,7 @@ namespace Jint.Runtime
             
             System.Diagnostics.Debugger.Break();
 
-            return new Completion(Completion.Normal, Null.Instance, null);
+            return new Completion(Completion.Normal, null, null);
         }
     }
 }

+ 1 - 5
Jint/Runtime/TypeConverter.cs

@@ -50,11 +50,7 @@ namespace Jint.Runtime
         {
             if (o.IsObject())
             {
-                var p = o.AsObject() as IPrimitiveInstance;
-                if (p != null)
-                {
-                    o = p.PrimitiveValue;
-                }
+                return true;
             }
 
             if (o == Undefined.Instance || o == Null.Instance)