blob: d92a79fbd87dc5818c83c76866e65fd5ed5886b5 [file] [log] [blame]
Piotr Cabanf33f5c92009-07-20 18:17:51 +02001/*
2 * Copyright 2009 Piotr Caban
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17 */
Piotr Cabana77e3692009-07-20 18:18:22 +020018#include "config.h"
19#include "wine/port.h"
20
21#include <math.h>
Piotr Cabanf33f5c92009-07-20 18:17:51 +020022
23#include "jscript.h"
24
25#include "wine/debug.h"
26
27WINE_DEFAULT_DEBUG_CHANNEL(jscript);
28
Piotr Caban7c0a7022009-07-20 18:18:17 +020029static const WCHAR descriptionW[] = {'d','e','s','c','r','i','p','t','i','o','n',0};
Piotr Cabanf33f5c92009-07-20 18:17:51 +020030static const WCHAR messageW[] = {'m','e','s','s','a','g','e',0};
Jacek Caban86e7bea2009-10-19 20:41:02 +020031static const WCHAR nameW[] = {'n','a','m','e',0};
Piotr Caban7c0a7022009-07-20 18:18:17 +020032static const WCHAR numberW[] = {'n','u','m','b','e','r',0};
Piotr Cabanf33f5c92009-07-20 18:17:51 +020033static const WCHAR toStringW[] = {'t','o','S','t','r','i','n','g',0};
Piotr Cabanf33f5c92009-07-20 18:17:51 +020034
Piotr Caban2d71dac2009-07-20 18:17:57 +020035/* ECMA-262 3rd Edition 15.11.4.4 */
Jacek Cabanae8cb5a2010-08-04 15:32:59 +020036static HRESULT Error_toString(script_ctx_t *ctx, vdisp_t *vthis, WORD flags,
Jacek Caban86e7bea2009-10-19 20:41:02 +020037 DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
Piotr Cabanf33f5c92009-07-20 18:17:51 +020038{
Jacek Cabanae8cb5a2010-08-04 15:32:59 +020039 DispatchEx *jsthis;
40 BSTR name = NULL, msg = NULL, ret = NULL;
Jacek Caban86e7bea2009-10-19 20:41:02 +020041 VARIANT v;
42 HRESULT hres;
43
Jacek Cabanae8cb5a2010-08-04 15:32:59 +020044 static const WCHAR object_errorW[] = {'[','o','b','j','e','c','t',' ','E','r','r','o','r',']',0};
Piotr Caban2d71dac2009-07-20 18:17:57 +020045
46 TRACE("\n");
47
Jacek Cabanae8cb5a2010-08-04 15:32:59 +020048 jsthis = get_jsdisp(vthis);
49 if(!jsthis || ctx->version < 2) {
Jacek Caban86e7bea2009-10-19 20:41:02 +020050 if(retv) {
51 V_VT(retv) = VT_BSTR;
Jacek Cabanae8cb5a2010-08-04 15:32:59 +020052 V_BSTR(retv) = SysAllocString(object_errorW);
Jacek Caban86e7bea2009-10-19 20:41:02 +020053 if(!V_BSTR(retv))
54 return E_OUTOFMEMORY;
55 }
56 return S_OK;
57 }
58
Jacek Cabanae8cb5a2010-08-04 15:32:59 +020059 hres = jsdisp_propget_name(jsthis, nameW, &v, ei, caller);
Jacek Caban86e7bea2009-10-19 20:41:02 +020060 if(FAILED(hres))
61 return hres;
62
Jacek Cabanae8cb5a2010-08-04 15:32:59 +020063 if(V_VT(&v) != VT_EMPTY) {
64 hres = to_string(ctx, &v, ei, &name);
65 VariantClear(&v);
66 if(FAILED(hres))
67 return hres;
68 if(!*name) {
69 SysFreeString(name);
70 name = NULL;
71 }
72 }
Jacek Caban86e7bea2009-10-19 20:41:02 +020073
Jacek Cabanae8cb5a2010-08-04 15:32:59 +020074 hres = jsdisp_propget_name(jsthis, messageW, &v, ei, caller);
Jacek Caban04819e92010-08-04 15:32:39 +020075 if(SUCCEEDED(hres)) {
76 if(V_VT(&v) != VT_EMPTY) {
77 hres = to_string(ctx, &v, ei, &msg);
78 VariantClear(&v);
79 if(SUCCEEDED(hres) && !*msg) {
80 SysFreeString(msg);
81 msg = NULL;
82 }
Jacek Caban86e7bea2009-10-19 20:41:02 +020083 }
84 }
85
86 if(SUCCEEDED(hres)) {
Jacek Cabanae8cb5a2010-08-04 15:32:59 +020087 if(name && msg) {
Jacek Caban86e7bea2009-10-19 20:41:02 +020088 DWORD name_len, msg_len;
89
90 name_len = SysStringLen(name);
91 msg_len = SysStringLen(msg);
92
93 ret = SysAllocStringLen(NULL, name_len + msg_len + 2);
94 if(ret) {
95 memcpy(ret, name, name_len*sizeof(WCHAR));
96 ret[name_len] = ':';
97 ret[name_len+1] = ' ';
98 memcpy(ret+name_len+2, msg, msg_len*sizeof(WCHAR));
99 }
Jacek Cabanae8cb5a2010-08-04 15:32:59 +0200100 }else if(name) {
Jacek Caban86e7bea2009-10-19 20:41:02 +0200101 ret = name;
102 name = NULL;
Jacek Cabanae8cb5a2010-08-04 15:32:59 +0200103 }else if(msg) {
104 ret = msg;
105 msg = NULL;
106 }else {
107 ret = SysAllocString(object_errorW);
108 if(!V_BSTR(retv))
109 hres = E_OUTOFMEMORY;
Jacek Caban86e7bea2009-10-19 20:41:02 +0200110 }
111 }
112
113 SysFreeString(msg);
114 SysFreeString(name);
115 if(FAILED(hres))
116 return hres;
117 if(!ret)
118 return E_OUTOFMEMORY;
119
Piotr Caban2d71dac2009-07-20 18:17:57 +0200120 if(retv) {
121 V_VT(retv) = VT_BSTR;
Jacek Caban86e7bea2009-10-19 20:41:02 +0200122 V_BSTR(retv) = ret;
123 }else {
124 SysFreeString(ret);
Piotr Caban2d71dac2009-07-20 18:17:57 +0200125 }
126
127 return S_OK;
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200128}
129
Jacek Cabanf8c2b422009-09-23 16:18:39 +0200130static HRESULT Error_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200131 DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
132{
Piotr Caban8dd1d9b2009-07-22 13:02:30 +0200133 TRACE("\n");
134
135 switch(flags) {
136 case INVOKE_FUNC:
Jacek Caban5dcd1822009-09-23 16:17:17 +0200137 return throw_type_error(ctx, ei, IDS_NOT_FUNC, NULL);
Piotr Caban8dd1d9b2009-07-22 13:02:30 +0200138 default:
139 FIXME("unimplemented flags %x\n", flags);
140 return E_NOTIMPL;
141 }
142
143 return S_OK;
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200144}
145
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200146static const builtin_prop_t Error_props[] = {
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200147 {toStringW, Error_toString, PROPF_METHOD}
148};
149
150static const builtin_info_t Error_info = {
151 JSCLASS_ERROR,
152 {NULL, Error_value, 0},
153 sizeof(Error_props)/sizeof(*Error_props),
154 Error_props,
Jacek Caban884b7662010-08-04 15:33:17 +0200155 NULL,
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200156 NULL
157};
158
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200159static const builtin_info_t ErrorInst_info = {
160 JSCLASS_ERROR,
161 {NULL, Error_value, 0},
Jacek Caban04819e92010-08-04 15:32:39 +0200162 0,
163 NULL,
Jacek Caban884b7662010-08-04 15:33:17 +0200164 NULL,
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200165 NULL
166};
167
Piotr Caban28734e32009-08-14 11:58:10 +0200168static HRESULT alloc_error(script_ctx_t *ctx, DispatchEx *prototype,
Jacek Caban884b7662010-08-04 15:33:17 +0200169 DispatchEx *constr, DispatchEx **ret)
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200170{
Jacek Caban884b7662010-08-04 15:33:17 +0200171 DispatchEx *err;
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200172 HRESULT hres;
173
Jacek Caban884b7662010-08-04 15:33:17 +0200174 err = heap_alloc_zero(sizeof(*err));
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200175 if(!err)
176 return E_OUTOFMEMORY;
177
Piotr Caban28734e32009-08-14 11:58:10 +0200178 if(prototype)
Jacek Caban884b7662010-08-04 15:33:17 +0200179 hres = init_dispex(err, ctx, &Error_info, prototype);
Piotr Caban28734e32009-08-14 11:58:10 +0200180 else
Jacek Caban884b7662010-08-04 15:33:17 +0200181 hres = init_dispex_from_constr(err, ctx, &ErrorInst_info,
Piotr Caban28734e32009-08-14 11:58:10 +0200182 constr ? constr : ctx->error_constr);
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200183 if(FAILED(hres)) {
184 heap_free(err);
185 return hres;
186 }
187
188 *ret = err;
189 return S_OK;
190}
191
192static HRESULT create_error(script_ctx_t *ctx, DispatchEx *constr,
Jacek Caban6263f002010-08-02 11:10:03 +0200193 UINT number, const WCHAR *msg, DispatchEx **ret)
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200194{
Jacek Caban884b7662010-08-04 15:33:17 +0200195 DispatchEx *err;
Jacek Caban6263f002010-08-02 11:10:03 +0200196 VARIANT v;
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200197 HRESULT hres;
198
Piotr Caban28734e32009-08-14 11:58:10 +0200199 hres = alloc_error(ctx, NULL, constr, &err);
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200200 if(FAILED(hres))
201 return hres;
202
Jacek Caban6263f002010-08-02 11:10:03 +0200203 V_VT(&v) = VT_I4;
204 V_I4(&v) = number;
Jacek Caban884b7662010-08-04 15:33:17 +0200205 hres = jsdisp_propput_name(err, numberW, &v, NULL/*FIXME*/, NULL/*FIXME*/);
Jacek Caban6263f002010-08-02 11:10:03 +0200206 if(FAILED(hres)) {
Jacek Caban884b7662010-08-04 15:33:17 +0200207 jsdisp_release(err);
Jacek Caban6263f002010-08-02 11:10:03 +0200208 return hres;
Piotr Cabana77e3692009-07-20 18:18:22 +0200209 }
210
Jacek Caban04819e92010-08-04 15:32:39 +0200211 V_VT(&v) = VT_BSTR;
212 if(msg) V_BSTR(&v) = SysAllocString(msg);
213 else V_BSTR(&v) = SysAllocStringLen(NULL, 0);
214 if(V_BSTR(&v)) {
Jacek Caban884b7662010-08-04 15:33:17 +0200215 hres = jsdisp_propput_name(err, messageW, &v, NULL/*FIXME*/, NULL/*FIXME*/);
Jacek Caban04819e92010-08-04 15:32:39 +0200216 if(SUCCEEDED(hres))
Jacek Caban884b7662010-08-04 15:33:17 +0200217 hres = jsdisp_propput_name(err, descriptionW, &v, NULL/*FIXME*/, NULL/*FIXME*/);
Jacek Caban04819e92010-08-04 15:32:39 +0200218 SysFreeString(V_BSTR(&v));
219 }else {
220 hres = E_OUTOFMEMORY;
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200221 }
Jacek Caban96990cf2010-08-04 15:32:11 +0200222 if(FAILED(hres)) {
Jacek Caban884b7662010-08-04 15:33:17 +0200223 jsdisp_release(err);
Jacek Caban96990cf2010-08-04 15:32:11 +0200224 return hres;
225 }
226
Jacek Caban884b7662010-08-04 15:33:17 +0200227 *ret = err;
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200228 return S_OK;
229}
230
Jacek Caban5dcd1822009-09-23 16:17:17 +0200231static HRESULT error_constr(script_ctx_t *ctx, WORD flags, DISPPARAMS *dp,
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200232 VARIANT *retv, jsexcept_t *ei, DispatchEx *constr) {
233 DispatchEx *err;
Jacek Caban6263f002010-08-02 11:10:03 +0200234 UINT num = 0;
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200235 BSTR msg = NULL;
236 HRESULT hres;
237
238 if(arg_cnt(dp)) {
Jacek Caban6263f002010-08-02 11:10:03 +0200239 VARIANT numv;
240
Jacek Caban5dcd1822009-09-23 16:17:17 +0200241 hres = to_number(ctx, get_arg(dp, 0), ei, &numv);
Piotr Cabana77e3692009-07-20 18:18:22 +0200242 if(FAILED(hres) || (V_VT(&numv)==VT_R8 && isnan(V_R8(&numv))))
Jacek Caban5dcd1822009-09-23 16:17:17 +0200243 hres = to_string(ctx, get_arg(dp, 0), ei, &msg);
Piotr Cabana77e3692009-07-20 18:18:22 +0200244 else if(V_VT(&numv) == VT_I4)
245 num = V_I4(&numv);
246 else
247 num = V_R8(&numv);
248
249 if(FAILED(hres))
250 return hres;
251 }
252
253 if(arg_cnt(dp)>1 && !msg) {
Jacek Caban5dcd1822009-09-23 16:17:17 +0200254 hres = to_string(ctx, get_arg(dp, 1), ei, &msg);
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200255 if(FAILED(hres))
256 return hres;
257 }
258
259 switch(flags) {
260 case INVOKE_FUNC:
261 case DISPATCH_CONSTRUCT:
Jacek Caban6263f002010-08-02 11:10:03 +0200262 hres = create_error(ctx, constr, num, msg, &err);
Rob Shearman9dc584d2009-12-31 12:03:01 +0000263 SysFreeString(msg);
Piotr Cabana77e3692009-07-20 18:18:22 +0200264
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200265 if(FAILED(hres))
266 return hres;
267
268 if(retv) {
269 V_VT(retv) = VT_DISPATCH;
270 V_DISPATCH(retv) = (IDispatch*)_IDispatchEx_(err);
271 }
272 else
Jacek Cabanc444a492009-09-01 13:26:08 +0200273 jsdisp_release(err);
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200274
275 return S_OK;
276
277 default:
278 FIXME("unimplemented flags %x\n", flags);
279 return E_NOTIMPL;
280 }
281}
282
Jacek Cabanf8c2b422009-09-23 16:18:39 +0200283static HRESULT ErrorConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200284 DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
285{
286 TRACE("\n");
Jacek Caban5dcd1822009-09-23 16:17:17 +0200287 return error_constr(ctx, flags, dp, retv, ei, ctx->error_constr);
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200288}
289
Jacek Cabanf8c2b422009-09-23 16:18:39 +0200290static HRESULT EvalErrorConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200291 DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
292{
293 TRACE("\n");
Jacek Caban5dcd1822009-09-23 16:17:17 +0200294 return error_constr(ctx, flags, dp, retv, ei, ctx->eval_error_constr);
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200295}
296
Jacek Cabanf8c2b422009-09-23 16:18:39 +0200297static HRESULT RangeErrorConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200298 DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
299{
300 TRACE("\n");
Jacek Caban5dcd1822009-09-23 16:17:17 +0200301 return error_constr(ctx, flags, dp, retv, ei, ctx->range_error_constr);
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200302}
303
Jacek Cabanf8c2b422009-09-23 16:18:39 +0200304static HRESULT ReferenceErrorConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200305 DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
306{
307 TRACE("\n");
Jacek Caban5dcd1822009-09-23 16:17:17 +0200308 return error_constr(ctx, flags, dp, retv, ei, ctx->reference_error_constr);
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200309}
310
Jacek Cabanf8c2b422009-09-23 16:18:39 +0200311static HRESULT RegExpErrorConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
Jacek Caban9e523c62009-09-23 16:09:22 +0200312 DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
313{
314 TRACE("\n");
Jacek Caban5dcd1822009-09-23 16:17:17 +0200315 return error_constr(ctx, flags, dp, retv, ei, ctx->regexp_error_constr);
Jacek Caban9e523c62009-09-23 16:09:22 +0200316}
317
Jacek Cabanf8c2b422009-09-23 16:18:39 +0200318static HRESULT SyntaxErrorConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200319 DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
320{
321 TRACE("\n");
Jacek Caban5dcd1822009-09-23 16:17:17 +0200322 return error_constr(ctx, flags, dp, retv, ei, ctx->syntax_error_constr);
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200323}
324
Jacek Cabanf8c2b422009-09-23 16:18:39 +0200325static HRESULT TypeErrorConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200326 DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
327{
328 TRACE("\n");
Jacek Caban5dcd1822009-09-23 16:17:17 +0200329 return error_constr(ctx, flags, dp, retv, ei, ctx->type_error_constr);
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200330}
331
Jacek Cabanf8c2b422009-09-23 16:18:39 +0200332static HRESULT URIErrorConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200333 DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
334{
335 TRACE("\n");
Jacek Caban5dcd1822009-09-23 16:17:17 +0200336 return error_constr(ctx, flags, dp, retv, ei, ctx->uri_error_constr);
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200337}
338
Piotr Caban28734e32009-08-14 11:58:10 +0200339HRESULT init_error_constr(script_ctx_t *ctx, DispatchEx *object_prototype)
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200340{
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200341 static const WCHAR ErrorW[] = {'E','r','r','o','r',0};
342 static const WCHAR EvalErrorW[] = {'E','v','a','l','E','r','r','o','r',0};
343 static const WCHAR RangeErrorW[] = {'R','a','n','g','e','E','r','r','o','r',0};
344 static const WCHAR ReferenceErrorW[] = {'R','e','f','e','r','e','n','c','e','E','r','r','o','r',0};
Jacek Caban9e523c62009-09-23 16:09:22 +0200345 static const WCHAR RegExpErrorW[] = {'R','e','g','E','x','p','E','r','r','o','r',0};
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200346 static const WCHAR SyntaxErrorW[] = {'S','y','n','t','a','x','E','r','r','o','r',0};
347 static const WCHAR TypeErrorW[] = {'T','y','p','e','E','r','r','o','r',0};
348 static const WCHAR URIErrorW[] = {'U','R','I','E','r','r','o','r',0};
349 static const WCHAR *names[] = {ErrorW, EvalErrorW, RangeErrorW,
Jacek Caban9e523c62009-09-23 16:09:22 +0200350 ReferenceErrorW, RegExpErrorW, SyntaxErrorW, TypeErrorW, URIErrorW};
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200351 DispatchEx **constr_addr[] = {&ctx->error_constr, &ctx->eval_error_constr,
Jacek Caban9e523c62009-09-23 16:09:22 +0200352 &ctx->range_error_constr, &ctx->reference_error_constr, &ctx->regexp_error_constr,
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200353 &ctx->syntax_error_constr, &ctx->type_error_constr,
354 &ctx->uri_error_constr};
355 static builtin_invoke_t constr_val[] = {ErrorConstr_value, EvalErrorConstr_value,
Jacek Caban9e523c62009-09-23 16:09:22 +0200356 RangeErrorConstr_value, ReferenceErrorConstr_value, RegExpErrorConstr_value,
357 SyntaxErrorConstr_value, TypeErrorConstr_value, URIErrorConstr_value};
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200358
Jacek Caban884b7662010-08-04 15:33:17 +0200359 DispatchEx *err;
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200360 INT i;
361 VARIANT v;
362 HRESULT hres;
363
Jacek Caban9e523c62009-09-23 16:09:22 +0200364 for(i=0; i < sizeof(names)/sizeof(names[0]); i++) {
Piotr Caban28734e32009-08-14 11:58:10 +0200365 hres = alloc_error(ctx, i==0 ? object_prototype : NULL, NULL, &err);
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200366 if(FAILED(hres))
367 return hres;
368
369 V_VT(&v) = VT_BSTR;
370 V_BSTR(&v) = SysAllocString(names[i]);
371 if(!V_BSTR(&v)) {
Jacek Caban884b7662010-08-04 15:33:17 +0200372 jsdisp_release(err);
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200373 return E_OUTOFMEMORY;
374 }
375
Jacek Caban884b7662010-08-04 15:33:17 +0200376 hres = jsdisp_propput_name(err, nameW, &v, NULL/*FIXME*/, NULL/*FIXME*/);
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200377
378 if(SUCCEEDED(hres))
Jacek Caband918a182009-09-17 01:04:44 +0200379 hres = create_builtin_function(ctx, constr_val[i], names[i], NULL,
Jacek Caban884b7662010-08-04 15:33:17 +0200380 PROPF_CONSTR|1, err, constr_addr[i]);
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200381
Jacek Caban884b7662010-08-04 15:33:17 +0200382 jsdisp_release(err);
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200383 VariantClear(&v);
384 if(FAILED(hres))
385 return hres;
386 }
387
388 return S_OK;
389}
Piotr Caban469b5972009-07-20 18:18:00 +0200390
391static HRESULT throw_error(script_ctx_t *ctx, jsexcept_t *ei, UINT id, const WCHAR *str, DispatchEx *constr)
392{
393 WCHAR buf[1024], *pos = NULL;
394 DispatchEx *err;
395 HRESULT hres;
396
Piotr Caban98223b92009-07-24 09:35:56 +0200397 buf[0] = '\0';
398 LoadStringW(jscript_hinstance, id&0xFFFF, buf, sizeof(buf)/sizeof(WCHAR));
Piotr Caban469b5972009-07-20 18:18:00 +0200399
400 if(str) pos = strchrW(buf, '|');
401 if(pos) {
402 int len = strlenW(str);
Piotr Caband8e841c2009-07-22 13:01:59 +0200403 memmove(pos+len, pos+1, (strlenW(pos+1)+1)*sizeof(WCHAR));
Piotr Caban469b5972009-07-20 18:18:00 +0200404 memcpy(pos, str, len*sizeof(WCHAR));
405 }
406
Piotr Caband8e841c2009-07-22 13:01:59 +0200407 WARN("%s\n", debugstr_w(buf));
408
Piotr Caban98223b92009-07-24 09:35:56 +0200409 id |= JSCRIPT_ERROR;
Jacek Caban6263f002010-08-02 11:10:03 +0200410 hres = create_error(ctx, constr, id, buf, &err);
Piotr Caban469b5972009-07-20 18:18:00 +0200411 if(FAILED(hres))
412 return hres;
413
414 if(!ei)
415 return id;
416
417 V_VT(&ei->var) = VT_DISPATCH;
418 V_DISPATCH(&ei->var) = (IDispatch*)_IDispatchEx_(err);
419
Piotr Cabana77e3692009-07-20 18:18:22 +0200420 return id;
Piotr Caban469b5972009-07-20 18:18:00 +0200421}
422
Jacek Caban6d4533a2009-09-30 14:34:47 +0200423HRESULT throw_generic_error(script_ctx_t *ctx, jsexcept_t *ei, UINT id, const WCHAR *str)
424{
425 return throw_error(ctx, ei, id, str, ctx->error_constr);
426}
427
Piotr Caban469b5972009-07-20 18:18:00 +0200428HRESULT throw_range_error(script_ctx_t *ctx, jsexcept_t *ei, UINT id, const WCHAR *str)
429{
430 return throw_error(ctx, ei, id, str, ctx->range_error_constr);
431}
432
433HRESULT throw_reference_error(script_ctx_t *ctx, jsexcept_t *ei, UINT id, const WCHAR *str)
434{
435 return throw_error(ctx, ei, id, str, ctx->reference_error_constr);
436}
437
Jacek Caban9e523c62009-09-23 16:09:22 +0200438HRESULT throw_regexp_error(script_ctx_t *ctx, jsexcept_t *ei, UINT id, const WCHAR *str)
439{
440 return throw_error(ctx, ei, id, str, ctx->regexp_error_constr);
441}
442
Piotr Caban469b5972009-07-20 18:18:00 +0200443HRESULT throw_syntax_error(script_ctx_t *ctx, jsexcept_t *ei, UINT id, const WCHAR *str)
444{
445 return throw_error(ctx, ei, id, str, ctx->syntax_error_constr);
446}
447
448HRESULT throw_type_error(script_ctx_t *ctx, jsexcept_t *ei, UINT id, const WCHAR *str)
449{
450 return throw_error(ctx, ei, id, str, ctx->type_error_constr);
451}
452
453HRESULT throw_uri_error(script_ctx_t *ctx, jsexcept_t *ei, UINT id, const WCHAR *str)
454{
455 return throw_error(ctx, ei, id, str, ctx->uri_error_constr);
456}