1 /* Digital Mars DMDScript source code.
2  * Copyright (c) 2000-2002 by Chromium Communications
3  * D version Copyright (c) 2004-2010 by Digital Mars
4  * Distributed under the Boost Software License, Version 1.0.
5  * (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6  * written by Walter Bright
7  * http://www.digitalmars.com
8  *
9  * D2 port by Dmitry Olshansky 
10  *
11  * DMDScript is implemented in the D Programming Language,
12  * http://www.digitalmars.com/d/
13  *
14  * For a C++ implementation of DMDScript, including COM support, see
15  * http://www.digitalmars.com/dscript/cppscript.html
16  */
17 
18 module dmdscript.derror;
19 
20 import dmdscript.script;
21 import dmdscript.dobject;
22 import dmdscript.dfunction;
23 import dmdscript.value;
24 import dmdscript.threadcontext;
25 import dmdscript.dnative;
26 import dmdscript.text;
27 import dmdscript.property;
28 
29 
30 // Comes from MAKE_HRESULT(SEVERITY_ERROR, FACILITY_CONTROL, 0)
31 const uint FACILITY = 0x800A0000;
32 
33 /* ===================== Derror_constructor ==================== */
34 
35 class DerrorConstructor : Dfunction
36 {
37     this(CallContext* cc)
38     {
39         super(cc, 1, cc.tc.Dfunction_prototype);
40     }
41 
42     override void* Construct(CallContext *cc, Value *ret, Value[] arglist)
43     {
44         // ECMA 15.7.2
45         Dobject o;
46         Value* m;
47         Value* n;
48         Value vemptystring;
49 
50         vemptystring.putVstring(null);
51         switch(arglist.length)
52         {
53         case 0:         // ECMA doesn't say what we do if m is undefined
54             m = &vemptystring;
55             n = &vundefined;
56             break;
57         case 1:
58             m = &arglist[0];
59             if(m.isNumber())
60             {
61                 n = m;
62                 m = &vemptystring;
63             }
64             else
65                 n = &vundefined;
66             break;
67         default:
68             m = &arglist[0];
69             n = &arglist[1];
70             break;
71         }
72         o = new Derror(cc, m, n);
73         ret.putVobject(o);
74         return null;
75     }
76 
77     override void* Call(CallContext *cc, Dobject othis, Value* ret, Value[] arglist)
78     {
79         // ECMA v3 15.11.1
80         return Construct(cc, ret, arglist);
81     }
82 }
83 
84 
85 /* ===================== Derror_prototype_toString =============== */
86 
87 void* Derror_prototype_toString(Dobject pthis, CallContext *cc, Dobject othis, Value *ret, Value[] arglist)
88 {
89     // ECMA v3 15.11.4.3
90     // Return implementation defined string
91     Value* v;
92 
93     //writef("Error.prototype.toString()\n");
94     v = othis.Get(TEXT_message);
95     if(!v)
96         v = &vundefined;
97     ret.putVstring(othis.Get(TEXT_name).toString(cc)~": "~v.toString(cc));
98     return null;
99 }
100 
101 /* ===================== Derror_prototype ==================== */
102 
103 class DerrorPrototype : Derror
104 {
105     this(CallContext* cc)
106     {
107         super(cc, cc.tc.Dobject_prototype);
108         Dobject f = cc.tc.Dfunction_prototype;
109         //d_string m = d_string_ctor(DTEXT("Error.prototype.message"));
110 
111         Put(cc, TEXT_constructor, cc.tc.Derror_constructor, DontEnum);
112 
113         static enum NativeFunctionData[] nfd =
114         [
115             { TEXT_toString, &Derror_prototype_toString, 0 },
116         ];
117 
118         DnativeFunction.initialize(this, cc, nfd, 0);
119 
120         Put(cc, TEXT_name, TEXT_Error, 0);
121         Put(cc, TEXT_message, TEXT_, 0);
122         Put(cc, TEXT_description, TEXT_, 0);
123         Put(cc, TEXT_number, cast(d_number)(/*FACILITY |*/ 0), 0);
124     }
125 }
126 
127 
128 /* ===================== Derror ==================== */
129 
130 class Derror : Dobject
131 {
132     this(CallContext* cc, Value * m, Value * v2)
133     {
134         super(cc, getPrototype(cc));
135         classname = TEXT_Error;
136 
137         immutable(char)[] msg;
138         msg = m.toString(cc);
139         Put(cc, TEXT_message, msg, 0);
140         Put(cc, TEXT_description, msg, 0);
141         if(m.isString())
142         {
143         }
144         else if(m.isNumber())
145         {
146             d_number n = m.toNumber(cc);
147             n = cast(d_number)(/*FACILITY |*/ cast(int)n);
148             Put(cc, TEXT_number, n, 0);
149         }
150         if(v2.isString())
151         {
152             Put(cc, TEXT_description, v2.toString(cc), 0);
153             Put(cc, TEXT_message, v2.toString(cc), 0);
154         }
155         else if(v2.isNumber())
156         {
157             d_number n = v2.toNumber(cc);
158             n = cast(d_number)(/*FACILITY |*/ cast(int)n);
159             Put(cc, TEXT_number, n, 0);
160         }
161     }
162 
163     this(CallContext* cc, Dobject prototype)
164     {
165         super(cc, prototype);
166         classname = TEXT_Error;
167     }
168 
169     static Dfunction getConstructor(CallContext* cc)
170     {
171         return cc.tc.Derror_constructor;
172     }
173 
174     static Dobject getPrototype(CallContext* cc)
175     {
176         return cc.tc.Derror_prototype;
177     }
178 
179     static void initialize(CallContext* cc)
180     {
181         cc.tc.Derror_constructor = new DerrorConstructor(cc);
182         cc.tc.Derror_prototype = new DerrorPrototype(cc);
183 
184         cc.tc.Derror_constructor.Put(cc, TEXT_prototype, cc.tc.Derror_prototype, DontEnum | DontDelete | ReadOnly);
185     }
186 }
187