浏览代码

Fixing error objects

Sebastien Ros 12 年之前
父节点
当前提交
dbd659d7ca

+ 0 - 8
Jint/Engine.cs

@@ -42,8 +42,6 @@ namespace Jint
             Object = ObjectConstructor.CreateObjectConstructor(this);
             Function = FunctionConstructor.CreateFunctionConstructor(this);
 
-            
-
             Array = ArrayConstructor.CreateArrayConstructor(this);
             String = StringConstructor.CreateStringConstructor(this);
             Number = NumberConstructor.CreateNumberConstructor(this);
@@ -90,12 +88,6 @@ namespace Jint
             Json.Configure();
 
             Error.Configure();
-            EvalError.Configure();
-            RangeError.Configure();
-            ReferenceError.Configure();
-            SyntaxError.Configure();
-            TypeError.Configure();
-            UriError.Configure();
 
             // create the global environment http://www.ecma-international.org/ecma-262/5.1/#sec-10.2.3
             GlobalEnvironment = LexicalEnvironment.NewObjectEnvironment(this, Global, null, true);

+ 2 - 4
Jint/Native/Error/ErrorConstructor.cs

@@ -4,7 +4,7 @@ using Jint.Runtime;
 
 namespace Jint.Native.Error
 {
-    public sealed class ErrorConstructor : FunctionInstance, IConstructor
+    public class ErrorConstructor : FunctionInstance, IConstructor
     {
         public ErrorConstructor(Engine engine) : base(engine, null, null, false)
         {
@@ -45,14 +45,12 @@ namespace Jint.Native.Error
 
             if (arguments.Length > 0 && arguments[0] != Undefined.Instance)
             {
-                instance.Message = TypeConverter.ToString(arguments[0]);
+                instance.Put("message", TypeConverter.ToString(arguments[0]), false);
             }
 
             return instance;
         }
 
         public ErrorPrototype PrototypeObject { get; private set; }
-
-
     }
 }

+ 2 - 42
Jint/Native/Error/ErrorInstance.cs

@@ -8,8 +8,8 @@ namespace Jint.Native.Error
         public ErrorInstance(Engine engine, string name)
             : base(engine)
         {
-            Name = name;
-            Message = "";
+            FastAddProperty("name", name, true, false, true);
+            FastAddProperty("message", "", true, false, true);
         }
 
         public override string Class
@@ -19,45 +19,5 @@ namespace Jint.Native.Error
                 return "Error";
             }
         }
-
-        public object Message { get; set; }
-
-        public object Name { get; set; }
-
-        public string ToErrorString()
-        {
-            string name;
-            string msg;
-
-            if (Name == null || Name == "" || Name == Undefined.Instance)
-            {
-                name = "Error";
-            }
-            else
-            {
-                name = TypeConverter.ToString(Name);
-            }
-
-            if (Message == Undefined.Instance)
-            {
-                msg = "";
-            }
-            else
-            {
-                msg = TypeConverter.ToString(Message);
-            }
-
-            if (name == "")
-            {
-                return msg;
-            }
-
-            if (msg == "")
-            {
-                return name;
-            }
-
-            return name + ":" + msg;
-        }
     }
 }

+ 46 - 9
Jint/Native/Error/ErrorPrototype.cs

@@ -1,5 +1,6 @@
 using Jint.Native.Object;
-using Jint.Runtime.Descriptors.Specialized;
+using Jint.Runtime;
+using Jint.Runtime.Interop;
 
 namespace Jint.Native.Error
 {
@@ -8,34 +9,70 @@ namespace Jint.Native.Error
     /// </summary>
     public sealed class ErrorPrototype : ObjectInstance
     {
-        private ErrorPrototype(Engine engine)
+        private readonly string _name;
+
+        private ErrorPrototype(Engine engine, string name)
             : base(engine)
         {
+            _name = name;
         }
 
         public static ErrorPrototype CreatePrototypeObject(Engine engine, ErrorConstructor errorConstructor, string name)
         {
-            var obj = new ErrorPrototype(engine) { Extensible = true };
+            var obj = new ErrorPrototype(engine, name) { Extensible = true };
+            obj.Prototype = engine.Object.PrototypeObject;
 
             obj.FastAddProperty("constructor", errorConstructor, false, false, false);
 
-
             return obj;
         }
 
         public void Configure()
         {
             // Error prototype properties
-            DefineOwnProperty("message", new ClrAccessDescriptor<ErrorInstance>(Engine, x => x.Message), false);
-            DefineOwnProperty("name", new ClrAccessDescriptor<ErrorInstance>(Engine, x => x.Name), false);
+            FastAddProperty("message", "", true, false, true);
+            FastAddProperty("name", _name, true, false, true);
 
             // Error prototype functions
-            DefineOwnProperty("toString", new ClrDataDescriptor<ErrorInstance, object>(Engine, ToErrorString), false);
+            FastAddProperty("toString", new ClrFunctionInstance<object, object>(Engine, ToString), true, false, true);
         }
 
-        private static object ToErrorString(ErrorInstance thisObject, object[] arguments)
+        private object ToString(object thisObject, object[] arguments)
         {
-            return thisObject.ToErrorString();
+            var o = thisObject as ObjectInstance;
+            if (o == null)
+            {
+                throw new JavaScriptException(Engine.TypeError);
+            }
+
+            var name = o.Get("name");
+            if (name == Undefined.Instance)
+            {
+                name = _name;
+            }
+            else
+            {
+                name = TypeConverter.ToString(name);
+            }
+
+            var msg = o.Get("message");
+            if (msg == Undefined.Instance)
+            {
+                msg = "";
+            }
+            else
+            {
+                msg = TypeConverter.ToString(msg);
+            }
+            if (name == "")
+            {
+                return msg;
+            }
+            if (msg == "")
+            {
+                return name;
+            }
+            return name + ": " + msg;
         }
     }
 }

+ 3 - 3
Jint/Native/Function/FunctionInstance.cs

@@ -60,13 +60,13 @@ namespace Jint.Native.Function
 
             while (true)
             {
-                v = vObj.Prototype;
+                vObj = vObj.Prototype;
 
-                if (v == null)
+                if (vObj == null)
                 {
                     return false;
                 }
-                if (v == o)
+                if (vObj == o)
                 {
                     return true;
                 }

+ 6 - 1
Jint/Runtime/ExpressionIntepreter.cs

@@ -677,7 +677,12 @@ namespace Jint.Runtime
             var arguments = newExpression.Arguments.Select(EvaluateExpression).Select(_engine.GetValue).ToArray();
             
             // todo: optimize by defining a common abstract class or interface
-            var callee = (IConstructor)_engine.GetValue(EvaluateExpression(newExpression.Callee));
+            var callee = _engine.GetValue(EvaluateExpression(newExpression.Callee)) as IConstructor;
+            
+            if (callee == null)
+            {
+                throw new JavaScriptException(_engine.TypeError, "The object can't be used as constructor.");
+            }
 
             // construct the new instance using the Function's constructor method
             var instance = callee.Construct(arguments);

+ 12 - 4
Jint/Runtime/JavaScriptException.cs

@@ -1,4 +1,5 @@
 using System;
+using Jint.Native.Error;
 
 namespace Jint.Runtime
 {
@@ -6,14 +7,21 @@ namespace Jint.Runtime
     {
         private readonly object _errorObject;
 
-        public JavaScriptException(object errorObject) : base(errorObject.ToString())
+        public JavaScriptException(ErrorConstructor errorConstructor) : base("")
         {
-            _errorObject = errorObject;
+            _errorObject = errorConstructor.Construct(Arguments.Empty);
         }
 
-        public JavaScriptException(object errorObject, string message):base(message)
+        public JavaScriptException(ErrorConstructor errorConstructor, string message)
+            : base(message)
         {
-            _errorObject = errorObject;
+            _errorObject = errorConstructor.Construct(new object[] { message });
+        }
+
+        public JavaScriptException(object error)
+            : base("")
+        {
+            _errorObject = error;
         }
 
         public object Error { get { return _errorObject; } }