blob: 593244da3fe9d02f13cb49c14ec981270c9d2c48 [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
29typedef struct {
30 DispatchEx dispex;
31
Piotr Cabanf33f5c92009-07-20 18:17:51 +020032 VARIANT message;
33} ErrorInstance;
34
Piotr Caban7c0a7022009-07-20 18:18:17 +020035static const WCHAR descriptionW[] = {'d','e','s','c','r','i','p','t','i','o','n',0};
Piotr Cabanf33f5c92009-07-20 18:17:51 +020036static const WCHAR messageW[] = {'m','e','s','s','a','g','e',0};
Jacek Caban86e7bea2009-10-19 20:41:02 +020037static const WCHAR nameW[] = {'n','a','m','e',0};
Piotr Caban7c0a7022009-07-20 18:18:17 +020038static const WCHAR numberW[] = {'n','u','m','b','e','r',0};
Piotr Cabanf33f5c92009-07-20 18:17:51 +020039static const WCHAR toStringW[] = {'t','o','S','t','r','i','n','g',0};
Piotr Cabanf33f5c92009-07-20 18:17:51 +020040
Jacek Cabanf8c2b422009-09-23 16:18:39 +020041static inline ErrorInstance *error_from_vdisp(vdisp_t *vdisp)
42{
43 return (ErrorInstance*)vdisp->u.jsdisp;
44}
45
Jacek Caban86e7bea2009-10-19 20:41:02 +020046static inline ErrorInstance *error_this(vdisp_t *jsthis)
47{
48 return is_vclass(jsthis, JSCLASS_ERROR) ? error_from_vdisp(jsthis) : NULL;
49}
50
Piotr Cabanf33f5c92009-07-20 18:17:51 +020051/* ECMA-262 3rd Edition 15.11.4.3 */
Jacek Cabanf8c2b422009-09-23 16:18:39 +020052static HRESULT Error_message(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
Piotr Cabanf33f5c92009-07-20 18:17:51 +020053 DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
54{
Jacek Cabanf8c2b422009-09-23 16:18:39 +020055 ErrorInstance *This = error_from_vdisp(jsthis);
Piotr Cabanf17b1f62009-07-20 18:17:54 +020056
57 TRACE("\n");
58
59 switch(flags) {
60 case DISPATCH_PROPERTYGET:
61 return VariantCopy(retv, &This->message);
62 case DISPATCH_PROPERTYPUT:
63 return VariantCopy(&This->message, get_arg(dp, 0));
64 default:
65 FIXME("unimplemented flags %x\n", flags);
66 return E_NOTIMPL;
67 }
Piotr Cabanf33f5c92009-07-20 18:17:51 +020068}
69
Piotr Caban2d71dac2009-07-20 18:17:57 +020070/* ECMA-262 3rd Edition 15.11.4.4 */
Jacek Cabanf8c2b422009-09-23 16:18:39 +020071static HRESULT Error_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
Jacek Caban86e7bea2009-10-19 20:41:02 +020072 DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
Piotr Cabanf33f5c92009-07-20 18:17:51 +020073{
Jacek Caban86e7bea2009-10-19 20:41:02 +020074 ErrorInstance *error;
75 BSTR name, msg = NULL, ret = NULL;
76 VARIANT v;
77 HRESULT hres;
78
Piotr Caban2d71dac2009-07-20 18:17:57 +020079 static const WCHAR str[] = {'[','o','b','j','e','c','t',' ','E','r','r','o','r',']',0};
80
81 TRACE("\n");
82
Jacek Caban86e7bea2009-10-19 20:41:02 +020083 error = error_this(jsthis);
84 if(ctx->version < 2 || !error) {
85 if(retv) {
86 V_VT(retv) = VT_BSTR;
87 V_BSTR(retv) = SysAllocString(str);
88 if(!V_BSTR(retv))
89 return E_OUTOFMEMORY;
90 }
91 return S_OK;
92 }
93
94 hres = jsdisp_propget_name(&error->dispex, nameW, &v, ei, caller);
95 if(FAILED(hres))
96 return hres;
97
98 hres = to_string(ctx, &v, ei, &name);
99 VariantClear(&v);
100 if(FAILED(hres))
101 return hres;
102
103 if(V_VT(&error->message) != VT_EMPTY) {
104 hres = to_string(ctx, &error->message, ei, &msg);
105 if(SUCCEEDED(hres) && !*msg) {
106 SysFreeString(msg);
107 msg = NULL;
108 }
109 }
110
111 if(SUCCEEDED(hres)) {
112 if(msg) {
113 DWORD name_len, msg_len;
114
115 name_len = SysStringLen(name);
116 msg_len = SysStringLen(msg);
117
118 ret = SysAllocStringLen(NULL, name_len + msg_len + 2);
119 if(ret) {
120 memcpy(ret, name, name_len*sizeof(WCHAR));
121 ret[name_len] = ':';
122 ret[name_len+1] = ' ';
123 memcpy(ret+name_len+2, msg, msg_len*sizeof(WCHAR));
124 }
125 }else {
126 ret = name;
127 name = NULL;
128 }
129 }
130
131 SysFreeString(msg);
132 SysFreeString(name);
133 if(FAILED(hres))
134 return hres;
135 if(!ret)
136 return E_OUTOFMEMORY;
137
Piotr Caban2d71dac2009-07-20 18:17:57 +0200138 if(retv) {
139 V_VT(retv) = VT_BSTR;
Jacek Caban86e7bea2009-10-19 20:41:02 +0200140 V_BSTR(retv) = ret;
141 }else {
142 SysFreeString(ret);
Piotr Caban2d71dac2009-07-20 18:17:57 +0200143 }
144
145 return S_OK;
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200146}
147
Jacek Cabanf8c2b422009-09-23 16:18:39 +0200148static HRESULT Error_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200149 DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
150{
Piotr Caban8dd1d9b2009-07-22 13:02:30 +0200151 TRACE("\n");
152
153 switch(flags) {
154 case INVOKE_FUNC:
Jacek Caban5dcd1822009-09-23 16:17:17 +0200155 return throw_type_error(ctx, ei, IDS_NOT_FUNC, NULL);
Piotr Caban8dd1d9b2009-07-22 13:02:30 +0200156 default:
157 FIXME("unimplemented flags %x\n", flags);
158 return E_NOTIMPL;
159 }
160
161 return S_OK;
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200162}
163
164static void Error_destructor(DispatchEx *dispex)
165{
166 ErrorInstance *This = (ErrorInstance*)dispex;
167
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200168 VariantClear(&This->message);
169 heap_free(This);
170}
171
172static const builtin_prop_t Error_props[] = {
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200173 {messageW, Error_message, 0},
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200174 {toStringW, Error_toString, PROPF_METHOD}
175};
176
177static const builtin_info_t Error_info = {
178 JSCLASS_ERROR,
179 {NULL, Error_value, 0},
180 sizeof(Error_props)/sizeof(*Error_props),
181 Error_props,
182 Error_destructor,
183 NULL
184};
185
186static const builtin_prop_t ErrorInst_props[] = {
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200187 {messageW, Error_message, 0},
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200188};
189
190static const builtin_info_t ErrorInst_info = {
191 JSCLASS_ERROR,
192 {NULL, Error_value, 0},
193 sizeof(ErrorInst_props)/sizeof(*ErrorInst_props),
194 ErrorInst_props,
195 Error_destructor,
196 NULL
197};
198
Piotr Caban28734e32009-08-14 11:58:10 +0200199static HRESULT alloc_error(script_ctx_t *ctx, DispatchEx *prototype,
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200200 DispatchEx *constr, ErrorInstance **ret)
201{
202 ErrorInstance *err;
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200203 HRESULT hres;
204
205 err = heap_alloc_zero(sizeof(ErrorInstance));
206 if(!err)
207 return E_OUTOFMEMORY;
208
Piotr Caban28734e32009-08-14 11:58:10 +0200209 if(prototype)
210 hres = init_dispex(&err->dispex, ctx, &Error_info, prototype);
211 else
212 hres = init_dispex_from_constr(&err->dispex, ctx, &ErrorInst_info,
213 constr ? constr : ctx->error_constr);
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200214 if(FAILED(hres)) {
215 heap_free(err);
216 return hres;
217 }
218
219 *ret = err;
220 return S_OK;
221}
222
223static HRESULT create_error(script_ctx_t *ctx, DispatchEx *constr,
Jacek Caban6263f002010-08-02 11:10:03 +0200224 UINT number, const WCHAR *msg, DispatchEx **ret)
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200225{
226 ErrorInstance *err;
Jacek Caban6263f002010-08-02 11:10:03 +0200227 VARIANT v;
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200228 HRESULT hres;
229
Piotr Caban28734e32009-08-14 11:58:10 +0200230 hres = alloc_error(ctx, NULL, constr, &err);
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200231 if(FAILED(hres))
232 return hres;
233
Jacek Caban6263f002010-08-02 11:10:03 +0200234 V_VT(&v) = VT_I4;
235 V_I4(&v) = number;
236 hres = jsdisp_propput_name(&err->dispex, numberW, &v, NULL/*FIXME*/, NULL/*FIXME*/);
237 if(FAILED(hres)) {
238 jsdisp_release(&err->dispex);
239 return hres;
Piotr Cabana77e3692009-07-20 18:18:22 +0200240 }
241
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200242 V_VT(&err->message) = VT_BSTR;
243 if(msg) V_BSTR(&err->message) = SysAllocString(msg);
244 else V_BSTR(&err->message) = SysAllocStringLen(NULL, 0);
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200245 if(!V_BSTR(&err->message)) {
246 heap_free(err);
247 return E_OUTOFMEMORY;
248 }
249
Jacek Caban96990cf2010-08-04 15:32:11 +0200250 hres = jsdisp_propput_name(&err->dispex, descriptionW, &err->message, NULL/*FIXME*/, NULL/*FIXME*/);
251 if(FAILED(hres)) {
252 jsdisp_release(&err->dispex);
253 return hres;
254 }
255
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200256 *ret = &err->dispex;
257 return S_OK;
258}
259
Jacek Caban5dcd1822009-09-23 16:17:17 +0200260static HRESULT error_constr(script_ctx_t *ctx, WORD flags, DISPPARAMS *dp,
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200261 VARIANT *retv, jsexcept_t *ei, DispatchEx *constr) {
262 DispatchEx *err;
Jacek Caban6263f002010-08-02 11:10:03 +0200263 UINT num = 0;
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200264 BSTR msg = NULL;
265 HRESULT hres;
266
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200267 if(arg_cnt(dp)) {
Jacek Caban6263f002010-08-02 11:10:03 +0200268 VARIANT numv;
269
Jacek Caban5dcd1822009-09-23 16:17:17 +0200270 hres = to_number(ctx, get_arg(dp, 0), ei, &numv);
Piotr Cabana77e3692009-07-20 18:18:22 +0200271 if(FAILED(hres) || (V_VT(&numv)==VT_R8 && isnan(V_R8(&numv))))
Jacek Caban5dcd1822009-09-23 16:17:17 +0200272 hres = to_string(ctx, get_arg(dp, 0), ei, &msg);
Piotr Cabana77e3692009-07-20 18:18:22 +0200273 else if(V_VT(&numv) == VT_I4)
274 num = V_I4(&numv);
275 else
276 num = V_R8(&numv);
277
278 if(FAILED(hres))
279 return hres;
280 }
281
282 if(arg_cnt(dp)>1 && !msg) {
Jacek Caban5dcd1822009-09-23 16:17:17 +0200283 hres = to_string(ctx, get_arg(dp, 1), ei, &msg);
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200284 if(FAILED(hres))
285 return hres;
286 }
287
288 switch(flags) {
289 case INVOKE_FUNC:
290 case DISPATCH_CONSTRUCT:
Jacek Caban6263f002010-08-02 11:10:03 +0200291 hres = create_error(ctx, constr, num, msg, &err);
Rob Shearman9dc584d2009-12-31 12:03:01 +0000292 SysFreeString(msg);
Piotr Cabana77e3692009-07-20 18:18:22 +0200293
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200294 if(FAILED(hres))
295 return hres;
296
297 if(retv) {
298 V_VT(retv) = VT_DISPATCH;
299 V_DISPATCH(retv) = (IDispatch*)_IDispatchEx_(err);
300 }
301 else
Jacek Cabanc444a492009-09-01 13:26:08 +0200302 jsdisp_release(err);
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200303
304 return S_OK;
305
306 default:
307 FIXME("unimplemented flags %x\n", flags);
308 return E_NOTIMPL;
309 }
310}
311
Jacek Cabanf8c2b422009-09-23 16:18:39 +0200312static HRESULT ErrorConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200313 DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
314{
315 TRACE("\n");
Jacek Caban5dcd1822009-09-23 16:17:17 +0200316 return error_constr(ctx, flags, dp, retv, ei, ctx->error_constr);
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200317}
318
Jacek Cabanf8c2b422009-09-23 16:18:39 +0200319static HRESULT EvalErrorConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200320 DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
321{
322 TRACE("\n");
Jacek Caban5dcd1822009-09-23 16:17:17 +0200323 return error_constr(ctx, flags, dp, retv, ei, ctx->eval_error_constr);
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200324}
325
Jacek Cabanf8c2b422009-09-23 16:18:39 +0200326static HRESULT RangeErrorConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200327 DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
328{
329 TRACE("\n");
Jacek Caban5dcd1822009-09-23 16:17:17 +0200330 return error_constr(ctx, flags, dp, retv, ei, ctx->range_error_constr);
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200331}
332
Jacek Cabanf8c2b422009-09-23 16:18:39 +0200333static HRESULT ReferenceErrorConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200334 DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
335{
336 TRACE("\n");
Jacek Caban5dcd1822009-09-23 16:17:17 +0200337 return error_constr(ctx, flags, dp, retv, ei, ctx->reference_error_constr);
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200338}
339
Jacek Cabanf8c2b422009-09-23 16:18:39 +0200340static HRESULT RegExpErrorConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
Jacek Caban9e523c62009-09-23 16:09:22 +0200341 DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
342{
343 TRACE("\n");
Jacek Caban5dcd1822009-09-23 16:17:17 +0200344 return error_constr(ctx, flags, dp, retv, ei, ctx->regexp_error_constr);
Jacek Caban9e523c62009-09-23 16:09:22 +0200345}
346
Jacek Cabanf8c2b422009-09-23 16:18:39 +0200347static HRESULT SyntaxErrorConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200348 DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
349{
350 TRACE("\n");
Jacek Caban5dcd1822009-09-23 16:17:17 +0200351 return error_constr(ctx, flags, dp, retv, ei, ctx->syntax_error_constr);
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200352}
353
Jacek Cabanf8c2b422009-09-23 16:18:39 +0200354static HRESULT TypeErrorConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200355 DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
356{
357 TRACE("\n");
Jacek Caban5dcd1822009-09-23 16:17:17 +0200358 return error_constr(ctx, flags, dp, retv, ei, ctx->type_error_constr);
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200359}
360
Jacek Cabanf8c2b422009-09-23 16:18:39 +0200361static HRESULT URIErrorConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200362 DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
363{
364 TRACE("\n");
Jacek Caban5dcd1822009-09-23 16:17:17 +0200365 return error_constr(ctx, flags, dp, retv, ei, ctx->uri_error_constr);
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200366}
367
Piotr Caban28734e32009-08-14 11:58:10 +0200368HRESULT init_error_constr(script_ctx_t *ctx, DispatchEx *object_prototype)
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200369{
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200370 static const WCHAR ErrorW[] = {'E','r','r','o','r',0};
371 static const WCHAR EvalErrorW[] = {'E','v','a','l','E','r','r','o','r',0};
372 static const WCHAR RangeErrorW[] = {'R','a','n','g','e','E','r','r','o','r',0};
373 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 +0200374 static const WCHAR RegExpErrorW[] = {'R','e','g','E','x','p','E','r','r','o','r',0};
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200375 static const WCHAR SyntaxErrorW[] = {'S','y','n','t','a','x','E','r','r','o','r',0};
376 static const WCHAR TypeErrorW[] = {'T','y','p','e','E','r','r','o','r',0};
377 static const WCHAR URIErrorW[] = {'U','R','I','E','r','r','o','r',0};
378 static const WCHAR *names[] = {ErrorW, EvalErrorW, RangeErrorW,
Jacek Caban9e523c62009-09-23 16:09:22 +0200379 ReferenceErrorW, RegExpErrorW, SyntaxErrorW, TypeErrorW, URIErrorW};
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200380 DispatchEx **constr_addr[] = {&ctx->error_constr, &ctx->eval_error_constr,
Jacek Caban9e523c62009-09-23 16:09:22 +0200381 &ctx->range_error_constr, &ctx->reference_error_constr, &ctx->regexp_error_constr,
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200382 &ctx->syntax_error_constr, &ctx->type_error_constr,
383 &ctx->uri_error_constr};
384 static builtin_invoke_t constr_val[] = {ErrorConstr_value, EvalErrorConstr_value,
Jacek Caban9e523c62009-09-23 16:09:22 +0200385 RangeErrorConstr_value, ReferenceErrorConstr_value, RegExpErrorConstr_value,
386 SyntaxErrorConstr_value, TypeErrorConstr_value, URIErrorConstr_value};
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200387
388 ErrorInstance *err;
389 INT i;
390 VARIANT v;
391 HRESULT hres;
392
Jacek Caban9e523c62009-09-23 16:09:22 +0200393 for(i=0; i < sizeof(names)/sizeof(names[0]); i++) {
Piotr Caban28734e32009-08-14 11:58:10 +0200394 hres = alloc_error(ctx, i==0 ? object_prototype : NULL, NULL, &err);
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200395 if(FAILED(hres))
396 return hres;
397
398 V_VT(&v) = VT_BSTR;
399 V_BSTR(&v) = SysAllocString(names[i]);
400 if(!V_BSTR(&v)) {
Jacek Cabanc444a492009-09-01 13:26:08 +0200401 jsdisp_release(&err->dispex);
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200402 return E_OUTOFMEMORY;
403 }
404
Jacek Cabanfadfab52009-09-23 16:11:11 +0200405 hres = jsdisp_propput_name(&err->dispex, nameW, &v, NULL/*FIXME*/, NULL/*FIXME*/);
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200406
407 if(SUCCEEDED(hres))
Jacek Caband918a182009-09-17 01:04:44 +0200408 hres = create_builtin_function(ctx, constr_val[i], names[i], NULL,
Piotr Caban662a8522009-10-13 22:08:43 +0200409 PROPF_CONSTR|1, &err->dispex, constr_addr[i]);
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200410
Jacek Cabanc444a492009-09-01 13:26:08 +0200411 jsdisp_release(&err->dispex);
Piotr Cabanf33f5c92009-07-20 18:17:51 +0200412 VariantClear(&v);
413 if(FAILED(hres))
414 return hres;
415 }
416
417 return S_OK;
418}
Piotr Caban469b5972009-07-20 18:18:00 +0200419
420static HRESULT throw_error(script_ctx_t *ctx, jsexcept_t *ei, UINT id, const WCHAR *str, DispatchEx *constr)
421{
422 WCHAR buf[1024], *pos = NULL;
423 DispatchEx *err;
424 HRESULT hres;
425
Piotr Caban98223b92009-07-24 09:35:56 +0200426 buf[0] = '\0';
427 LoadStringW(jscript_hinstance, id&0xFFFF, buf, sizeof(buf)/sizeof(WCHAR));
Piotr Caban469b5972009-07-20 18:18:00 +0200428
429 if(str) pos = strchrW(buf, '|');
430 if(pos) {
431 int len = strlenW(str);
Piotr Caband8e841c2009-07-22 13:01:59 +0200432 memmove(pos+len, pos+1, (strlenW(pos+1)+1)*sizeof(WCHAR));
Piotr Caban469b5972009-07-20 18:18:00 +0200433 memcpy(pos, str, len*sizeof(WCHAR));
434 }
435
Piotr Caband8e841c2009-07-22 13:01:59 +0200436 WARN("%s\n", debugstr_w(buf));
437
Piotr Caban98223b92009-07-24 09:35:56 +0200438 id |= JSCRIPT_ERROR;
Jacek Caban6263f002010-08-02 11:10:03 +0200439 hres = create_error(ctx, constr, id, buf, &err);
Piotr Caban469b5972009-07-20 18:18:00 +0200440 if(FAILED(hres))
441 return hres;
442
443 if(!ei)
444 return id;
445
446 V_VT(&ei->var) = VT_DISPATCH;
447 V_DISPATCH(&ei->var) = (IDispatch*)_IDispatchEx_(err);
448
Piotr Cabana77e3692009-07-20 18:18:22 +0200449 return id;
Piotr Caban469b5972009-07-20 18:18:00 +0200450}
451
Jacek Caban6d4533a2009-09-30 14:34:47 +0200452HRESULT throw_generic_error(script_ctx_t *ctx, jsexcept_t *ei, UINT id, const WCHAR *str)
453{
454 return throw_error(ctx, ei, id, str, ctx->error_constr);
455}
456
Piotr Caban469b5972009-07-20 18:18:00 +0200457HRESULT throw_range_error(script_ctx_t *ctx, jsexcept_t *ei, UINT id, const WCHAR *str)
458{
459 return throw_error(ctx, ei, id, str, ctx->range_error_constr);
460}
461
462HRESULT throw_reference_error(script_ctx_t *ctx, jsexcept_t *ei, UINT id, const WCHAR *str)
463{
464 return throw_error(ctx, ei, id, str, ctx->reference_error_constr);
465}
466
Jacek Caban9e523c62009-09-23 16:09:22 +0200467HRESULT throw_regexp_error(script_ctx_t *ctx, jsexcept_t *ei, UINT id, const WCHAR *str)
468{
469 return throw_error(ctx, ei, id, str, ctx->regexp_error_constr);
470}
471
Piotr Caban469b5972009-07-20 18:18:00 +0200472HRESULT throw_syntax_error(script_ctx_t *ctx, jsexcept_t *ei, UINT id, const WCHAR *str)
473{
474 return throw_error(ctx, ei, id, str, ctx->syntax_error_constr);
475}
476
477HRESULT throw_type_error(script_ctx_t *ctx, jsexcept_t *ei, UINT id, const WCHAR *str)
478{
479 return throw_error(ctx, ei, id, str, ctx->type_error_constr);
480}
481
482HRESULT throw_uri_error(script_ctx_t *ctx, jsexcept_t *ei, UINT id, const WCHAR *str)
483{
484 return throw_error(ctx, ei, id, str, ctx->uri_error_constr);
485}