jscript: Use script global LCID in *disp_call* functions.
[wine] / dlls / jscript / engine.c
1 /*
2  * Copyright 2008 Jacek Caban for CodeWeavers
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  */
18
19 #include "config.h"
20 #include "wine/port.h"
21
22 #include <math.h>
23
24 #include "jscript.h"
25 #include "engine.h"
26
27 #include "wine/debug.h"
28
29 WINE_DEFAULT_DEBUG_CHANNEL(jscript);
30
31 #define EXPR_NOVAL   0x0001
32 #define EXPR_NEWREF  0x0002
33 #define EXPR_STRREF  0x0004
34
35 static inline HRESULT stat_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
36 {
37     return stat->eval(ctx, stat, rt, ret);
38 }
39
40 static inline HRESULT expr_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
41 {
42     return _expr->eval(ctx, _expr, flags, ei, ret);
43 }
44
45 static void exprval_release(exprval_t *val)
46 {
47     switch(val->type) {
48     case EXPRVAL_VARIANT:
49         if(V_VT(&val->u.var) != VT_EMPTY)
50             VariantClear(&val->u.var);
51         return;
52     case EXPRVAL_IDREF:
53         if(val->u.idref.disp)
54             IDispatch_Release(val->u.idref.disp);
55         return;
56     case EXPRVAL_NAMEREF:
57         if(val->u.nameref.disp)
58             IDispatch_Release(val->u.nameref.disp);
59         SysFreeString(val->u.nameref.name);
60         return;
61     case EXPRVAL_INVALID:
62         SysFreeString(val->u.identifier);
63     }
64 }
65
66 /* ECMA-262 3rd Edition    8.7.1 */
67 static HRESULT exprval_value(script_ctx_t *ctx, exprval_t *val, jsexcept_t *ei, VARIANT *ret)
68 {
69     V_VT(ret) = VT_EMPTY;
70
71     switch(val->type) {
72     case EXPRVAL_VARIANT:
73         return VariantCopy(ret, &val->u.var);
74     case EXPRVAL_IDREF:
75         if(!val->u.idref.disp) {
76             FIXME("throw ReferenceError\n");
77             return E_FAIL;
78         }
79
80         return disp_propget(val->u.idref.disp, val->u.idref.id, ctx->lcid, ret, ei, NULL/*FIXME*/);
81     case EXPRVAL_NAMEREF:
82         break;
83     case EXPRVAL_INVALID:
84         return throw_type_error(ctx, ei, IDS_UNDEFINED, val->u.identifier);
85     }
86
87     ERR("type %d\n", val->type);
88     return E_FAIL;
89 }
90
91 static HRESULT exprval_to_value(script_ctx_t *ctx, exprval_t *val, jsexcept_t *ei, VARIANT *ret)
92 {
93     if(val->type == EXPRVAL_VARIANT) {
94         *ret = val->u.var;
95         V_VT(&val->u.var) = VT_EMPTY;
96         return S_OK;
97     }
98
99     return exprval_value(ctx, val, ei, ret);
100 }
101
102 static HRESULT exprval_to_boolean(script_ctx_t *ctx, exprval_t *exprval, jsexcept_t *ei, VARIANT_BOOL *b)
103 {
104     if(exprval->type != EXPRVAL_VARIANT) {
105         VARIANT val;
106         HRESULT hres;
107
108         hres = exprval_to_value(ctx, exprval, ei, &val);
109         if(FAILED(hres))
110             return hres;
111
112         hres = to_boolean(&val, b);
113         VariantClear(&val);
114         return hres;
115     }
116
117     return to_boolean(&exprval->u.var, b);
118 }
119
120 static void exprval_init(exprval_t *val)
121 {
122     val->type = EXPRVAL_VARIANT;
123     V_VT(&val->u.var) = VT_EMPTY;
124 }
125
126 static void exprval_set_idref(exprval_t *val, IDispatch *disp, DISPID id)
127 {
128     val->type = EXPRVAL_IDREF;
129     val->u.idref.disp = disp;
130     val->u.idref.id = id;
131
132     if(disp)
133         IDispatch_AddRef(disp);
134 }
135
136 HRESULT scope_push(scope_chain_t *scope, DispatchEx *obj, scope_chain_t **ret)
137 {
138     scope_chain_t *new_scope;
139
140     new_scope = heap_alloc(sizeof(scope_chain_t));
141     if(!new_scope)
142         return E_OUTOFMEMORY;
143
144     new_scope->ref = 1;
145
146     IDispatchEx_AddRef(_IDispatchEx_(obj));
147     new_scope->obj = obj;
148
149     if(scope) {
150         scope_addref(scope);
151         new_scope->next = scope;
152     }else {
153         new_scope->next = NULL;
154     }
155
156     *ret = new_scope;
157     return S_OK;
158 }
159
160 static void scope_pop(scope_chain_t **scope)
161 {
162     scope_chain_t *tmp;
163
164     tmp = *scope;
165     *scope = tmp->next;
166     scope_release(tmp);
167 }
168
169 void scope_release(scope_chain_t *scope)
170 {
171     if(--scope->ref)
172         return;
173
174     if(scope->next)
175         scope_release(scope->next);
176
177     jsdisp_release(scope->obj);
178     heap_free(scope);
179 }
180
181 HRESULT create_exec_ctx(IDispatch *this_obj, DispatchEx *var_disp, scope_chain_t *scope, exec_ctx_t **ret)
182 {
183     exec_ctx_t *ctx;
184
185     ctx = heap_alloc_zero(sizeof(exec_ctx_t));
186     if(!ctx)
187         return E_OUTOFMEMORY;
188
189     ctx->ref = 1;
190
191     IDispatch_AddRef(this_obj);
192     ctx->this_obj = this_obj;
193
194     IDispatchEx_AddRef(_IDispatchEx_(var_disp));
195     ctx->var_disp = var_disp;
196
197     if(scope) {
198         scope_addref(scope);
199         ctx->scope_chain = scope;
200     }
201
202     *ret = ctx;
203     return S_OK;
204 }
205
206 void exec_release(exec_ctx_t *ctx)
207 {
208     if(--ctx->ref)
209         return;
210
211     if(ctx->scope_chain)
212         scope_release(ctx->scope_chain);
213     if(ctx->var_disp)
214         jsdisp_release(ctx->var_disp);
215     if(ctx->this_obj)
216         IDispatch_Release(ctx->this_obj);
217     heap_free(ctx);
218 }
219
220 static HRESULT disp_get_id(IDispatch *disp, BSTR name, DWORD flags, DISPID *id)
221 {
222     IDispatchEx *dispex;
223     HRESULT hres;
224
225     hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
226     if(FAILED(hres)) {
227         TRACE("unsing IDispatch\n");
228
229         *id = 0;
230         return IDispatch_GetIDsOfNames(disp, &IID_NULL, &name, 1, 0, id);
231     }
232
233     *id = 0;
234     hres = IDispatchEx_GetDispID(dispex, name, flags|fdexNameCaseSensitive, id);
235     IDispatchEx_Release(dispex);
236     return hres;
237 }
238
239 /* ECMA-262 3rd Edition    8.7.2 */
240 static HRESULT put_value(script_ctx_t *ctx, exprval_t *ref, VARIANT *v, jsexcept_t *ei)
241 {
242     if(ref->type != EXPRVAL_IDREF)
243         return throw_reference_error(ctx, ei, IDS_ILLEGAL_ASSIGN, NULL);
244
245     return disp_propput(ref->u.idref.disp, ref->u.idref.id, ctx->lcid, v, ei, NULL/*FIXME*/);
246 }
247
248 static inline BOOL is_null(const VARIANT *v)
249 {
250     return V_VT(v) == VT_NULL || (V_VT(v) == VT_DISPATCH && !V_DISPATCH(v));
251 }
252
253 static HRESULT disp_cmp(IDispatch *disp1, IDispatch *disp2, BOOL *ret)
254 {
255     IObjectIdentity *identity;
256     IUnknown *unk1, *unk2;
257     HRESULT hres;
258
259     if(disp1 == disp2) {
260         *ret = TRUE;
261         return S_OK;
262     }
263
264     if(!disp1 || !disp2) {
265         *ret = FALSE;
266         return S_OK;
267     }
268
269     hres = IDispatch_QueryInterface(disp1, &IID_IUnknown, (void**)&unk1);
270     if(FAILED(hres))
271         return hres;
272
273     hres = IDispatch_QueryInterface(disp2, &IID_IUnknown, (void**)&unk2);
274     if(FAILED(hres)) {
275         IUnknown_Release(unk1);
276         return hres;
277     }
278
279     if(unk1 == unk2) {
280         *ret = TRUE;
281     }else {
282         hres = IUnknown_QueryInterface(unk1, &IID_IObjectIdentity, (void**)&identity);
283         if(SUCCEEDED(hres)) {
284             hres = IObjectIdentity_IsEqualObject(identity, unk2);
285             IObjectIdentity_Release(identity);
286             *ret = hres == S_OK;
287         }else {
288             *ret = FALSE;
289         }
290     }
291
292     IUnknown_Release(unk1);
293     IUnknown_Release(unk2);
294     return S_OK;
295 }
296
297 /* ECMA-262 3rd Edition    11.9.6 */
298 static HRESULT equal2_values(VARIANT *lval, VARIANT *rval, BOOL *ret)
299 {
300     TRACE("\n");
301
302     if(V_VT(lval) != V_VT(rval)) {
303         if(is_num_vt(V_VT(lval)) && is_num_vt(V_VT(rval)))
304             *ret = num_val(lval) == num_val(rval);
305         else if(is_null(lval))
306             *ret = is_null(rval);
307         else
308             *ret = FALSE;
309         return S_OK;
310     }
311
312     switch(V_VT(lval)) {
313     case VT_EMPTY:
314     case VT_NULL:
315         *ret = VARIANT_TRUE;
316         break;
317     case VT_I4:
318         *ret = V_I4(lval) == V_I4(rval);
319         break;
320     case VT_R8:
321         *ret = V_R8(lval) == V_R8(rval);
322         break;
323     case VT_BSTR:
324         if(!V_BSTR(lval))
325             *ret = SysStringLen(V_BSTR(rval))?FALSE:TRUE;
326         else if(!V_BSTR(rval))
327             *ret = SysStringLen(V_BSTR(lval))?FALSE:TRUE;
328         else
329             *ret = !strcmpW(V_BSTR(lval), V_BSTR(rval));
330         break;
331     case VT_DISPATCH:
332         return disp_cmp(V_DISPATCH(lval), V_DISPATCH(rval), ret);
333     case VT_BOOL:
334         *ret = !V_BOOL(lval) == !V_BOOL(rval);
335         break;
336     default:
337         FIXME("unimplemented vt %d\n", V_VT(lval));
338         return E_NOTIMPL;
339     }
340
341     return S_OK;
342 }
343
344 static HRESULT literal_to_var(literal_t *literal, VARIANT *v)
345 {
346     V_VT(v) = literal->vt;
347
348     switch(V_VT(v)) {
349     case VT_EMPTY:
350     case VT_NULL:
351         break;
352     case VT_I4:
353         V_I4(v) = literal->u.lval;
354         break;
355     case VT_R8:
356         V_R8(v) = literal->u.dval;
357         break;
358     case VT_BSTR:
359         V_BSTR(v) = SysAllocString(literal->u.wstr);
360         break;
361     case VT_BOOL:
362         V_BOOL(v) = literal->u.bval;
363         break;
364     case VT_DISPATCH:
365         IDispatch_AddRef(literal->u.disp);
366         V_DISPATCH(v) = literal->u.disp;
367         break;
368     default:
369         ERR("wrong type %d\n", V_VT(v));
370         return E_NOTIMPL;
371     }
372
373     return S_OK;
374 }
375
376 static BOOL lookup_global_members(script_ctx_t *ctx, BSTR identifier, exprval_t *ret)
377 {
378     named_item_t *item;
379     DISPID id;
380     HRESULT hres;
381
382     for(item = ctx->named_items; item; item = item->next) {
383         if(item->flags & SCRIPTITEM_GLOBALMEMBERS) {
384             hres = disp_get_id(item->disp, identifier, 0, &id);
385             if(SUCCEEDED(hres)) {
386                 if(ret)
387                     exprval_set_idref(ret, item->disp, id);
388                 return TRUE;
389             }
390         }
391     }
392
393     return FALSE;
394 }
395
396 HRESULT exec_source(exec_ctx_t *ctx, parser_ctx_t *parser, source_elements_t *source, jsexcept_t *ei, VARIANT *retv)
397 {
398     script_ctx_t *script = parser->script;
399     function_declaration_t *func;
400     parser_ctx_t *prev_parser;
401     var_list_t *var;
402     VARIANT val, tmp;
403     statement_t *stat;
404     exec_ctx_t *prev_ctx;
405     return_type_t rt;
406     HRESULT hres = S_OK;
407
408     for(func = source->functions; func; func = func->next) {
409         DispatchEx *func_obj;
410         VARIANT var;
411
412         hres = create_source_function(parser, func->expr->parameter_list, func->expr->source_elements,
413                 ctx->scope_chain, func->expr->src_str, func->expr->src_len, &func_obj);
414         if(FAILED(hres))
415             return hres;
416
417         V_VT(&var) = VT_DISPATCH;
418         V_DISPATCH(&var) = (IDispatch*)_IDispatchEx_(func_obj);
419         hres = jsdisp_propput_name(ctx->var_disp, func->expr->identifier, script->lcid, &var, ei, NULL);
420         jsdisp_release(func_obj);
421         if(FAILED(hres))
422             return hres;
423     }
424
425     for(var = source->variables; var; var = var->next) {
426         DISPID id = 0;
427         BSTR name;
428
429         name = SysAllocString(var->identifier);
430         if(!name)
431             return E_OUTOFMEMORY;
432
433         if(!lookup_global_members(parser->script, name, NULL))
434             hres = jsdisp_get_id(ctx->var_disp, var->identifier, fdexNameEnsure, &id);
435         SysFreeString(name);
436         if(FAILED(hres))
437             return hres;
438     }
439
440     prev_ctx = script->exec_ctx;
441     script->exec_ctx = ctx;
442
443     prev_parser = ctx->parser;
444     ctx->parser = parser;
445
446     V_VT(&val) = VT_EMPTY;
447     memset(&rt, 0, sizeof(rt));
448     rt.type = RT_NORMAL;
449
450     for(stat = source->statement; stat; stat = stat->next) {
451         hres = stat_eval(ctx, stat, &rt, &tmp);
452         if(FAILED(hres))
453             break;
454
455         VariantClear(&val);
456         val = tmp;
457         if(rt.type != RT_NORMAL)
458             break;
459     }
460
461     script->exec_ctx = prev_ctx;
462     ctx->parser = prev_parser;
463
464     if(rt.type != RT_NORMAL && rt.type != RT_RETURN) {
465         FIXME("wrong rt %d\n", rt.type);
466         hres = E_FAIL;
467     }
468
469     *ei = rt.ei;
470     if(FAILED(hres)) {
471         VariantClear(&val);
472         return hres;
473     }
474
475     if(retv)
476         *retv = val;
477     else
478         VariantClear(&val);
479     return S_OK;
480 }
481
482 /* ECMA-262 3rd Edition    10.1.4 */
483 static HRESULT identifier_eval(exec_ctx_t *ctx, BSTR identifier, DWORD flags, jsexcept_t *ei, exprval_t *ret)
484 {
485     scope_chain_t *scope;
486     named_item_t *item;
487     DISPID id = 0;
488     HRESULT hres;
489
490     TRACE("%s\n", debugstr_w(identifier));
491
492     for(scope = ctx->scope_chain; scope; scope = scope->next) {
493         hres = jsdisp_get_id(scope->obj, identifier, 0, &id);
494         if(SUCCEEDED(hres))
495             break;
496     }
497
498     if(scope) {
499         exprval_set_idref(ret, (IDispatch*)_IDispatchEx_(scope->obj), id);
500         return S_OK;
501     }
502
503     hres = jsdisp_get_id(ctx->parser->script->global, identifier, 0, &id);
504     if(SUCCEEDED(hres)) {
505         exprval_set_idref(ret, (IDispatch*)_IDispatchEx_(ctx->parser->script->global), id);
506         return S_OK;
507     }
508
509     for(item = ctx->parser->script->named_items; item; item = item->next) {
510         if((item->flags & SCRIPTITEM_ISVISIBLE) && !strcmpW(item->name, identifier)) {
511             if(!item->disp) {
512                 IUnknown *unk;
513
514                 if(!ctx->parser->script->site)
515                     break;
516
517                 hres = IActiveScriptSite_GetItemInfo(ctx->parser->script->site, identifier,
518                                                      SCRIPTINFO_IUNKNOWN, &unk, NULL);
519                 if(FAILED(hres)) {
520                     WARN("GetItemInfo failed: %08x\n", hres);
521                     break;
522                 }
523
524                 hres = IUnknown_QueryInterface(unk, &IID_IDispatch, (void**)&item->disp);
525                 IUnknown_Release(unk);
526                 if(FAILED(hres)) {
527                     WARN("object does not implement IDispatch\n");
528                     break;
529                 }
530             }
531
532             ret->type = EXPRVAL_VARIANT;
533             V_VT(&ret->u.var) = VT_DISPATCH;
534             V_DISPATCH(&ret->u.var) = item->disp;
535             IDispatch_AddRef(item->disp);
536             return S_OK;
537         }
538     }
539
540     hres = jsdisp_get_id(ctx->parser->script->script_disp, identifier, 0, &id);
541     if(SUCCEEDED(hres)) {
542         exprval_set_idref(ret, (IDispatch*)_IDispatchEx_(ctx->parser->script->script_disp), id);
543         return S_OK;
544     }
545
546     if(lookup_global_members(ctx->parser->script, identifier, ret))
547         return S_OK;
548
549     if(flags & EXPR_NEWREF) {
550         hres = jsdisp_get_id(ctx->parser->script->script_disp, identifier, fdexNameEnsure, &id);
551         if(FAILED(hres))
552             return hres;
553
554         exprval_set_idref(ret, (IDispatch*)_IDispatchEx_(ctx->parser->script->script_disp), id);
555         return S_OK;
556     }
557
558     ret->type = EXPRVAL_INVALID;
559     ret->u.identifier = SysAllocString(identifier);
560     if(!ret->u.identifier)
561         return E_OUTOFMEMORY;
562
563     return S_OK;
564 }
565
566 /* ECMA-262 3rd Edition    12.1 */
567 HRESULT block_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
568 {
569     block_statement_t *stat = (block_statement_t*)_stat;
570     VARIANT val, tmp;
571     statement_t *iter;
572     HRESULT hres = S_OK;
573
574     TRACE("\n");
575
576     V_VT(&val) = VT_EMPTY;
577     for(iter = stat->stat_list; iter; iter = iter->next) {
578         hres = stat_eval(ctx, iter, rt, &tmp);
579         if(FAILED(hres))
580             break;
581
582         VariantClear(&val);
583         val = tmp;
584         if(rt->type != RT_NORMAL)
585             break;
586     }
587
588     if(FAILED(hres)) {
589         VariantClear(&val);
590         return hres;
591     }
592
593     *ret = val;
594     return S_OK;
595 }
596
597 /* ECMA-262 3rd Edition    12.2 */
598 static HRESULT variable_list_eval(exec_ctx_t *ctx, variable_declaration_t *var_list, jsexcept_t *ei)
599 {
600     variable_declaration_t *iter;
601     HRESULT hres = S_OK;
602
603     for(iter = var_list; iter; iter = iter->next) {
604         exprval_t exprval;
605         VARIANT val;
606
607         if(!iter->expr)
608             continue;
609
610         hres = expr_eval(ctx, iter->expr, 0, ei, &exprval);
611         if(FAILED(hres))
612             break;
613
614         hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
615         exprval_release(&exprval);
616         if(FAILED(hres))
617             break;
618
619         hres = jsdisp_propput_name(ctx->var_disp, iter->identifier, ctx->parser->script->lcid, &val, ei, NULL/*FIXME*/);
620         VariantClear(&val);
621         if(FAILED(hres))
622             break;
623     }
624
625     return hres;
626 }
627
628 /* ECMA-262 3rd Edition    12.2 */
629 HRESULT var_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
630 {
631     var_statement_t *stat = (var_statement_t*)_stat;
632     HRESULT hres;
633
634     TRACE("\n");
635
636     hres = variable_list_eval(ctx, stat->variable_list, &rt->ei);
637     if(FAILED(hres))
638         return hres;
639
640     V_VT(ret) = VT_EMPTY;
641     return S_OK;
642 }
643
644 /* ECMA-262 3rd Edition    12.3 */
645 HRESULT empty_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
646 {
647     TRACE("\n");
648
649     V_VT(ret) = VT_EMPTY;
650     return S_OK;
651 }
652
653 /* ECMA-262 3rd Edition    12.4 */
654 HRESULT expression_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
655 {
656     expression_statement_t *stat = (expression_statement_t*)_stat;
657     exprval_t exprval;
658     VARIANT val;
659     HRESULT hres;
660
661     TRACE("\n");
662
663     hres = expr_eval(ctx, stat->expr, EXPR_NOVAL, &rt->ei, &exprval);
664     if(FAILED(hres))
665         return hres;
666
667     hres = exprval_to_value(ctx->parser->script, &exprval, &rt->ei, &val);
668     exprval_release(&exprval);
669     if(FAILED(hres))
670         return hres;
671
672     *ret = val;
673     TRACE("= %s\n", debugstr_variant(ret));
674     return S_OK;
675 }
676
677 /* ECMA-262 3rd Edition    12.5 */
678 HRESULT if_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
679 {
680     if_statement_t *stat = (if_statement_t*)_stat;
681     exprval_t exprval;
682     VARIANT_BOOL b;
683     HRESULT hres;
684
685     TRACE("\n");
686
687     hres = expr_eval(ctx, stat->expr, 0, &rt->ei, &exprval);
688     if(FAILED(hres))
689         return hres;
690
691     hres = exprval_to_boolean(ctx->parser->script, &exprval, &rt->ei, &b);
692     exprval_release(&exprval);
693     if(FAILED(hres))
694         return hres;
695
696     if(b)
697         hres = stat_eval(ctx, stat->if_stat, rt, ret);
698     else if(stat->else_stat)
699         hres = stat_eval(ctx, stat->else_stat, rt, ret);
700     else
701         V_VT(ret) = VT_EMPTY;
702
703     return hres;
704 }
705
706 /* ECMA-262 3rd Edition    12.6.2 */
707 HRESULT while_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
708 {
709     while_statement_t *stat = (while_statement_t*)_stat;
710     exprval_t exprval;
711     VARIANT val, tmp;
712     VARIANT_BOOL b;
713     BOOL test_expr;
714     HRESULT hres;
715
716     TRACE("\n");
717
718     V_VT(&val) = VT_EMPTY;
719     test_expr = !stat->do_while;
720
721     while(1) {
722         if(test_expr) {
723             hres = expr_eval(ctx, stat->expr, 0, &rt->ei, &exprval);
724             if(FAILED(hres))
725                 break;
726
727             hres = exprval_to_boolean(ctx->parser->script, &exprval, &rt->ei, &b);
728             exprval_release(&exprval);
729             if(FAILED(hres) || !b)
730                 break;
731         }else {
732             test_expr = TRUE;
733         }
734
735         hres = stat_eval(ctx, stat->statement, rt, &tmp);
736         if(FAILED(hres))
737             break;
738
739         VariantClear(&val);
740         val = tmp;
741
742         if(rt->type == RT_CONTINUE)
743             rt->type = RT_NORMAL;
744         if(rt->type != RT_NORMAL)
745             break;
746     }
747
748     if(FAILED(hres)) {
749         VariantClear(&val);
750         return hres;
751     }
752
753     if(rt->type == RT_BREAK)
754         rt->type = RT_NORMAL;
755
756     *ret = val;
757     return S_OK;
758 }
759
760 /* ECMA-262 3rd Edition    12.6.3 */
761 HRESULT for_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
762 {
763     for_statement_t *stat = (for_statement_t*)_stat;
764     VARIANT val, tmp, retv;
765     exprval_t exprval;
766     VARIANT_BOOL b;
767     HRESULT hres;
768
769     TRACE("\n");
770
771     if(stat->variable_list) {
772         hres = variable_list_eval(ctx, stat->variable_list, &rt->ei);
773         if(FAILED(hres))
774             return hres;
775     }else if(stat->begin_expr) {
776         hres = expr_eval(ctx, stat->begin_expr, EXPR_NEWREF, &rt->ei, &exprval);
777         if(FAILED(hres))
778             return hres;
779
780         hres = exprval_to_value(ctx->parser->script, &exprval, &rt->ei, &val);
781         exprval_release(&exprval);
782         if(FAILED(hres))
783             return hres;
784
785         VariantClear(&val);
786     }
787
788     V_VT(&retv) = VT_EMPTY;
789
790     while(1) {
791         if(stat->expr) {
792             hres = expr_eval(ctx, stat->expr, 0, &rt->ei, &exprval);
793             if(FAILED(hres))
794                 break;
795
796             hres = exprval_to_boolean(ctx->parser->script, &exprval, &rt->ei, &b);
797             exprval_release(&exprval);
798             if(FAILED(hres) || !b)
799                 break;
800         }
801
802         hres = stat_eval(ctx, stat->statement, rt, &tmp);
803         if(FAILED(hres))
804             break;
805
806         VariantClear(&retv);
807         retv = tmp;
808
809         if(rt->type == RT_CONTINUE)
810             rt->type = RT_NORMAL;
811         else if(rt->type != RT_NORMAL)
812             break;
813
814         if(stat->end_expr) {
815             hres = expr_eval(ctx, stat->end_expr, 0, &rt->ei, &exprval);
816             if(FAILED(hres))
817                 break;
818
819             hres = exprval_to_value(ctx->parser->script, &exprval, &rt->ei, &val);
820             exprval_release(&exprval);
821             if(FAILED(hres))
822                 break;
823
824             VariantClear(&val);
825         }
826     }
827
828     if(FAILED(hres)) {
829         VariantClear(&retv);
830         return hres;
831     }
832
833     if(rt->type == RT_BREAK)
834         rt->type = RT_NORMAL;
835
836     *ret = retv;
837     return S_OK;
838 }
839
840 /* ECMA-262 3rd Edition    12.6.4 */
841 HRESULT forin_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
842 {
843     forin_statement_t *stat = (forin_statement_t*)_stat;
844     VARIANT val, name, retv, tmp;
845     DISPID id = DISPID_STARTENUM;
846     BSTR str, identifier = NULL;
847     IDispatchEx *in_obj;
848     exprval_t exprval;
849     HRESULT hres;
850
851     TRACE("\n");
852
853     if(stat->variable) {
854         hres = variable_list_eval(ctx, stat->variable, &rt->ei);
855         if(FAILED(hres))
856             return hres;
857     }
858
859     hres = expr_eval(ctx, stat->in_expr, EXPR_NEWREF, &rt->ei, &exprval);
860     if(FAILED(hres))
861         return hres;
862
863     hres = exprval_to_value(ctx->parser->script, &exprval, &rt->ei, &val);
864     exprval_release(&exprval);
865     if(FAILED(hres))
866         return hres;
867
868     if(V_VT(&val) != VT_DISPATCH) {
869         TRACE("in vt %d\n", V_VT(&val));
870         VariantClear(&val);
871         V_VT(ret) = VT_EMPTY;
872         return S_OK;
873     }
874
875     hres = IDispatch_QueryInterface(V_DISPATCH(&val), &IID_IDispatchEx, (void**)&in_obj);
876     IDispatch_Release(V_DISPATCH(&val));
877     if(FAILED(hres)) {
878         FIXME("Object doesn't support IDispatchEx\n");
879         return E_NOTIMPL;
880     }
881
882     V_VT(&retv) = VT_EMPTY;
883
884     if(stat->variable)
885         identifier = SysAllocString(stat->variable->identifier);
886
887     while(1) {
888         hres = IDispatchEx_GetNextDispID(in_obj, fdexEnumDefault, id, &id);
889         if(FAILED(hres) || hres == S_FALSE)
890             break;
891
892         hres = IDispatchEx_GetMemberName(in_obj, id, &str);
893         if(FAILED(hres))
894             break;
895
896         TRACE("iter %s\n", debugstr_w(str));
897
898         if(stat->variable)
899             hres = identifier_eval(ctx, identifier, 0, NULL, &exprval);
900         else
901             hres = expr_eval(ctx, stat->expr, EXPR_NEWREF, &rt->ei, &exprval);
902         if(SUCCEEDED(hres)) {
903             V_VT(&name) = VT_BSTR;
904             V_BSTR(&name) = str;
905             hres = put_value(ctx->parser->script, &exprval, &name, &rt->ei);
906             exprval_release(&exprval);
907         }
908         SysFreeString(str);
909         if(FAILED(hres))
910             break;
911
912         hres = stat_eval(ctx, stat->statement, rt, &tmp);
913         if(FAILED(hres))
914             break;
915
916         VariantClear(&retv);
917         retv = tmp;
918
919         if(rt->type == RT_CONTINUE)
920             rt->type = RT_NORMAL;
921         else if(rt->type != RT_NORMAL)
922             break;
923     }
924
925     SysFreeString(identifier);
926     IDispatchEx_Release(in_obj);
927     if(FAILED(hres)) {
928         VariantClear(&retv);
929         return hres;
930     }
931
932     if(rt->type == RT_BREAK)
933         rt->type = RT_NORMAL;
934
935     *ret = retv;
936     return S_OK;
937 }
938
939 /* ECMA-262 3rd Edition    12.7 */
940 HRESULT continue_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
941 {
942     branch_statement_t *stat = (branch_statement_t*)_stat;
943
944     TRACE("\n");
945
946     if(stat->identifier) {
947         FIXME("indentifier not implemented\n");
948         return E_NOTIMPL;
949     }
950
951     rt->type = RT_CONTINUE;
952     V_VT(ret) = VT_EMPTY;
953     return S_OK;
954 }
955
956 /* ECMA-262 3rd Edition    12.8 */
957 HRESULT break_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
958 {
959     branch_statement_t *stat = (branch_statement_t*)_stat;
960
961     TRACE("\n");
962
963     if(stat->identifier) {
964         FIXME("indentifier not implemented\n");
965         return E_NOTIMPL;
966     }
967
968     rt->type = RT_BREAK;
969     V_VT(ret) = VT_EMPTY;
970     return S_OK;
971 }
972
973 /* ECMA-262 3rd Edition    12.9 */
974 HRESULT return_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
975 {
976     expression_statement_t *stat = (expression_statement_t*)_stat;
977     HRESULT hres;
978
979     TRACE("\n");
980
981     if(stat->expr) {
982         exprval_t exprval;
983
984         hres = expr_eval(ctx, stat->expr, 0, &rt->ei, &exprval);
985         if(FAILED(hres))
986             return hres;
987
988         hres = exprval_to_value(ctx->parser->script, &exprval, &rt->ei, ret);
989         exprval_release(&exprval);
990         if(FAILED(hres))
991             return hres;
992     }else {
993         V_VT(ret) = VT_EMPTY;
994     }
995
996     TRACE("= %s\n", debugstr_variant(ret));
997     rt->type = RT_RETURN;
998     return S_OK;
999 }
1000
1001 /* ECMA-262 3rd Edition    12.10 */
1002 HRESULT with_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
1003 {
1004     with_statement_t *stat = (with_statement_t*)_stat;
1005     exprval_t exprval;
1006     IDispatch *disp;
1007     DispatchEx *obj;
1008     VARIANT val;
1009     HRESULT hres;
1010
1011     TRACE("\n");
1012
1013     hres = expr_eval(ctx, stat->expr, 0, &rt->ei, &exprval);
1014     if(FAILED(hres))
1015         return hres;
1016
1017     hres = exprval_to_value(ctx->parser->script, &exprval, &rt->ei, &val);
1018     exprval_release(&exprval);
1019     if(FAILED(hres))
1020         return hres;
1021
1022     hres = to_object(ctx->parser->script, &val, &disp);
1023     VariantClear(&val);
1024     if(FAILED(hres))
1025         return hres;
1026
1027     obj = iface_to_jsdisp((IUnknown*)disp);
1028     IDispatch_Release(disp);
1029     if(!obj) {
1030         FIXME("disp id not jsdisp\n");
1031         return E_NOTIMPL;
1032     }
1033
1034     hres = scope_push(ctx->scope_chain, obj, &ctx->scope_chain);
1035     jsdisp_release(obj);
1036     if(FAILED(hres))
1037         return hres;
1038
1039     hres = stat_eval(ctx, stat->statement, rt, ret);
1040
1041     scope_pop(&ctx->scope_chain);
1042     return hres;
1043 }
1044
1045 /* ECMA-262 3rd Edition    12.12 */
1046 HRESULT labelled_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
1047 {
1048     FIXME("\n");
1049     return E_NOTIMPL;
1050 }
1051
1052 /* ECMA-262 3rd Edition    12.13 */
1053 HRESULT switch_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
1054 {
1055     switch_statement_t *stat = (switch_statement_t*)_stat;
1056     case_clausule_t *iter, *default_clausule = NULL;
1057     statement_t *stat_iter;
1058     VARIANT val, cval;
1059     exprval_t exprval;
1060     BOOL b;
1061     HRESULT hres;
1062
1063     TRACE("\n");
1064
1065     hres = expr_eval(ctx, stat->expr, 0, &rt->ei, &exprval);
1066     if(FAILED(hres))
1067         return hres;
1068
1069     hres = exprval_to_value(ctx->parser->script, &exprval, &rt->ei, &val);
1070     exprval_release(&exprval);
1071     if(FAILED(hres))
1072         return hres;
1073
1074     for(iter = stat->case_list; iter; iter = iter->next) {
1075         if(!iter->expr) {
1076             default_clausule = iter;
1077             continue;
1078         }
1079
1080         hres = expr_eval(ctx, iter->expr, 0, &rt->ei, &exprval);
1081         if(FAILED(hres))
1082             break;
1083
1084         hres = exprval_to_value(ctx->parser->script, &exprval, &rt->ei, &cval);
1085         exprval_release(&exprval);
1086         if(FAILED(hres))
1087             break;
1088
1089         hres = equal2_values(&val, &cval, &b);
1090         VariantClear(&cval);
1091         if(FAILED(hres) || b)
1092             break;
1093     }
1094
1095     VariantClear(&val);
1096     if(FAILED(hres))
1097         return hres;
1098
1099     if(!iter)
1100         iter = default_clausule;
1101
1102     V_VT(&val) = VT_EMPTY;
1103     if(iter) {
1104         VARIANT tmp;
1105
1106         for(stat_iter = iter->stat; stat_iter; stat_iter = stat_iter->next) {
1107             hres = stat_eval(ctx, stat_iter, rt, &tmp);
1108             if(FAILED(hres))
1109                 break;
1110
1111             VariantClear(&val);
1112             val = tmp;
1113
1114             if(rt->type != RT_NORMAL)
1115                 break;
1116         }
1117     }
1118
1119     if(FAILED(hres)) {
1120         VariantClear(&val);
1121         return hres;
1122     }
1123
1124     if(rt->type == RT_BREAK)
1125         rt->type = RT_NORMAL;
1126
1127     *ret = val;
1128     return S_OK;
1129 }
1130
1131 /* ECMA-262 3rd Edition    12.13 */
1132 HRESULT throw_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
1133 {
1134     expression_statement_t *stat = (expression_statement_t*)_stat;
1135     exprval_t exprval;
1136     VARIANT val;
1137     HRESULT hres;
1138
1139     TRACE("\n");
1140
1141     hres = expr_eval(ctx, stat->expr, 0, &rt->ei, &exprval);
1142     if(FAILED(hres))
1143         return hres;
1144
1145     hres = exprval_to_value(ctx->parser->script, &exprval, &rt->ei, &val);
1146     exprval_release(&exprval);
1147     if(FAILED(hres))
1148         return hres;
1149
1150     rt->ei.var = val;
1151     return DISP_E_EXCEPTION;
1152 }
1153
1154 /* ECMA-262 3rd Edition    12.14 */
1155 static HRESULT catch_eval(exec_ctx_t *ctx, catch_block_t *block, return_type_t *rt, VARIANT *ret)
1156 {
1157     DispatchEx *var_disp;
1158     VARIANT ex, val;
1159     HRESULT hres;
1160
1161     ex = rt->ei.var;
1162     memset(&rt->ei, 0, sizeof(jsexcept_t));
1163
1164     hres = create_dispex(ctx->parser->script, NULL, NULL, &var_disp);
1165     if(SUCCEEDED(hres)) {
1166         hres = jsdisp_propput_name(var_disp, block->identifier, ctx->parser->script->lcid,
1167                 &ex, &rt->ei, NULL/*FIXME*/);
1168         if(SUCCEEDED(hres)) {
1169             hres = scope_push(ctx->scope_chain, var_disp, &ctx->scope_chain);
1170             if(SUCCEEDED(hres)) {
1171                 hres = stat_eval(ctx, block->statement, rt, &val);
1172                 scope_pop(&ctx->scope_chain);
1173             }
1174         }
1175
1176         jsdisp_release(var_disp);
1177     }
1178
1179     VariantClear(&ex);
1180     if(FAILED(hres))
1181         return hres;
1182
1183     *ret = val;
1184     return S_OK;
1185 }
1186
1187 /* ECMA-262 3rd Edition    12.14 */
1188 HRESULT try_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
1189 {
1190     try_statement_t *stat = (try_statement_t*)_stat;
1191     VARIANT val;
1192     HRESULT hres;
1193
1194     TRACE("\n");
1195
1196     hres = stat_eval(ctx, stat->try_statement, rt, &val);
1197     if(FAILED(hres)) {
1198         TRACE("EXCEPTION\n");
1199         if(!stat->catch_block)
1200             return hres;
1201
1202         hres = catch_eval(ctx, stat->catch_block, rt, &val);
1203         if(FAILED(hres))
1204             return hres;
1205     }
1206
1207     if(stat->finally_statement) {
1208         VariantClear(&val);
1209         hres = stat_eval(ctx, stat->finally_statement, rt, &val);
1210         if(FAILED(hres))
1211             return hres;
1212     }
1213
1214     *ret = val;
1215     return S_OK;
1216 }
1217
1218 static HRESULT return_bool(exprval_t *ret, DWORD b)
1219 {
1220     ret->type = EXPRVAL_VARIANT;
1221     V_VT(&ret->u.var) = VT_BOOL;
1222     V_BOOL(&ret->u.var) = b ? VARIANT_TRUE : VARIANT_FALSE;
1223
1224     return S_OK;
1225 }
1226
1227 static HRESULT get_binary_expr_values(exec_ctx_t *ctx, binary_expression_t *expr, jsexcept_t *ei, VARIANT *lval, VARIANT *rval)
1228 {
1229     exprval_t exprval;
1230     HRESULT hres;
1231
1232     hres = expr_eval(ctx, expr->expression1, 0, ei, &exprval);
1233     if(FAILED(hres))
1234         return hres;
1235
1236     hres = exprval_to_value(ctx->parser->script, &exprval, ei, lval);
1237     exprval_release(&exprval);
1238     if(FAILED(hres))
1239         return hres;
1240
1241     hres = expr_eval(ctx, expr->expression2, 0, ei, &exprval);
1242     if(SUCCEEDED(hres)) {
1243         hres = exprval_to_value(ctx->parser->script, &exprval, ei, rval);
1244         exprval_release(&exprval);
1245     }
1246
1247     if(FAILED(hres)) {
1248         VariantClear(lval);
1249         return hres;
1250     }
1251
1252     return S_OK;
1253 }
1254
1255 typedef HRESULT (*oper_t)(exec_ctx_t*,VARIANT*,VARIANT*,jsexcept_t*,VARIANT*);
1256
1257 static HRESULT binary_expr_eval(exec_ctx_t *ctx, binary_expression_t *expr, oper_t oper, jsexcept_t *ei,
1258         exprval_t *ret)
1259 {
1260     VARIANT lval, rval, retv;
1261     HRESULT hres;
1262
1263     hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval);
1264     if(FAILED(hres))
1265         return hres;
1266
1267     hres = oper(ctx, &lval, &rval, ei, &retv);
1268     VariantClear(&lval);
1269     VariantClear(&rval);
1270     if(FAILED(hres))
1271         return hres;
1272
1273     ret->type = EXPRVAL_VARIANT;
1274     ret->u.var = retv;
1275     return S_OK;
1276 }
1277
1278 /* ECMA-262 3rd Edition    11.13.2 */
1279 static HRESULT assign_oper_eval(exec_ctx_t *ctx, expression_t *lexpr, expression_t *rexpr, oper_t oper,
1280                                 jsexcept_t *ei, exprval_t *ret)
1281 {
1282     VARIANT retv, lval, rval;
1283     exprval_t exprval, exprvalr;
1284     HRESULT hres;
1285
1286     hres = expr_eval(ctx, lexpr, EXPR_NEWREF, ei, &exprval);
1287     if(FAILED(hres))
1288         return hres;
1289
1290     hres = exprval_value(ctx->parser->script, &exprval, ei, &lval);
1291     if(SUCCEEDED(hres)) {
1292         hres = expr_eval(ctx, rexpr, 0, ei, &exprvalr);
1293         if(SUCCEEDED(hres)) {
1294             hres = exprval_value(ctx->parser->script, &exprvalr, ei, &rval);
1295             exprval_release(&exprvalr);
1296         }
1297         if(SUCCEEDED(hres)) {
1298             hres = oper(ctx, &lval, &rval, ei, &retv);
1299             VariantClear(&rval);
1300         }
1301         VariantClear(&lval);
1302     }
1303
1304     if(SUCCEEDED(hres)) {
1305         hres = put_value(ctx->parser->script, &exprval, &retv, ei);
1306         if(FAILED(hres))
1307             VariantClear(&retv);
1308     }
1309     exprval_release(&exprval);
1310
1311     if(FAILED(hres))
1312         return hres;
1313
1314     ret->type = EXPRVAL_VARIANT;
1315     ret->u.var = retv;
1316     return S_OK;
1317 }
1318
1319 /* ECMA-262 3rd Edition    13 */
1320 HRESULT function_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1321 {
1322     function_expression_t *expr = (function_expression_t*)_expr;
1323     VARIANT var;
1324     HRESULT hres;
1325
1326     TRACE("\n");
1327
1328     if(expr->identifier) {
1329         hres = jsdisp_propget_name(ctx->var_disp, expr->identifier, ctx->parser->script->lcid, &var, ei, NULL/*FIXME*/);
1330         if(FAILED(hres))
1331             return hres;
1332     }else {
1333         DispatchEx *dispex;
1334
1335         hres = create_source_function(ctx->parser, expr->parameter_list, expr->source_elements, ctx->scope_chain,
1336                 expr->src_str, expr->src_len, &dispex);
1337         if(FAILED(hres))
1338             return hres;
1339
1340         V_VT(&var) = VT_DISPATCH;
1341         V_DISPATCH(&var) = (IDispatch*)_IDispatchEx_(dispex);
1342     }
1343
1344     ret->type = EXPRVAL_VARIANT;
1345     ret->u.var = var;
1346     return S_OK;
1347 }
1348
1349 /* ECMA-262 3rd Edition    11.12 */
1350 HRESULT conditional_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1351 {
1352     conditional_expression_t *expr = (conditional_expression_t*)_expr;
1353     exprval_t exprval;
1354     VARIANT_BOOL b;
1355     HRESULT hres;
1356
1357     TRACE("\n");
1358
1359     hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
1360     if(FAILED(hres))
1361         return hres;
1362
1363     hres = exprval_to_boolean(ctx->parser->script, &exprval, ei, &b);
1364     exprval_release(&exprval);
1365     if(FAILED(hres))
1366         return hres;
1367
1368     return expr_eval(ctx, b ? expr->true_expression : expr->false_expression, flags, ei, ret);
1369 }
1370
1371 /* ECMA-262 3rd Edition    11.2.1 */
1372 HRESULT array_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1373 {
1374     array_expression_t *expr = (array_expression_t*)_expr;
1375     exprval_t exprval;
1376     VARIANT member, val;
1377     DISPID id;
1378     BSTR str;
1379     IDispatch *obj = NULL;
1380     HRESULT hres;
1381
1382     TRACE("\n");
1383
1384     hres = expr_eval(ctx, expr->member_expr, EXPR_NEWREF, ei, &exprval);
1385     if(FAILED(hres))
1386         return hres;
1387
1388     hres = exprval_to_value(ctx->parser->script, &exprval, ei, &member);
1389     exprval_release(&exprval);
1390     if(FAILED(hres))
1391         return hres;
1392
1393     hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval);
1394     if(SUCCEEDED(hres)) {
1395         hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
1396         exprval_release(&exprval);
1397     }
1398
1399     if(SUCCEEDED(hres))
1400         hres = to_object(ctx->parser->script, &member, &obj);
1401     VariantClear(&member);
1402     if(SUCCEEDED(hres)) {
1403         hres = to_string(ctx->parser->script, &val, ei, &str);
1404         if(SUCCEEDED(hres)) {
1405             if(flags & EXPR_STRREF) {
1406                 ret->type = EXPRVAL_NAMEREF;
1407                 ret->u.nameref.disp = obj;
1408                 ret->u.nameref.name = str;
1409                 return S_OK;
1410             }
1411
1412             hres = disp_get_id(obj, str, flags & EXPR_NEWREF ? fdexNameEnsure : 0, &id);
1413         }
1414
1415         if(SUCCEEDED(hres)) {
1416             exprval_set_idref(ret, obj, id);
1417         }else if(!(flags & EXPR_NEWREF) && hres == DISP_E_UNKNOWNNAME) {
1418             exprval_init(ret);
1419             hres = S_OK;
1420         }
1421
1422         IDispatch_Release(obj);
1423     }
1424
1425     return hres;
1426 }
1427
1428 /* ECMA-262 3rd Edition    11.2.1 */
1429 HRESULT member_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1430 {
1431     member_expression_t *expr = (member_expression_t*)_expr;
1432     IDispatch *obj = NULL;
1433     exprval_t exprval;
1434     VARIANT member;
1435     DISPID id;
1436     BSTR str;
1437     HRESULT hres;
1438
1439     TRACE("\n");
1440
1441     hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
1442     if(FAILED(hres))
1443         return hres;
1444
1445     hres = exprval_to_value(ctx->parser->script, &exprval, ei, &member);
1446     exprval_release(&exprval);
1447     if(FAILED(hres))
1448         return hres;
1449
1450     hres = to_object(ctx->parser->script, &member, &obj);
1451     VariantClear(&member);
1452     if(FAILED(hres))
1453         return hres;
1454
1455     str = SysAllocString(expr->identifier);
1456     if(flags & EXPR_STRREF) {
1457         ret->type = EXPRVAL_NAMEREF;
1458         ret->u.nameref.disp = obj;
1459         ret->u.nameref.name = str;
1460         return S_OK;
1461     }
1462
1463     hres = disp_get_id(obj, str, flags & EXPR_NEWREF ? fdexNameEnsure : 0, &id);
1464     SysFreeString(str);
1465     if(SUCCEEDED(hres)) {
1466         exprval_set_idref(ret, obj, id);
1467     }else if(!(flags & EXPR_NEWREF) && hres == DISP_E_UNKNOWNNAME) {
1468         exprval_init(ret);
1469         hres = S_OK;
1470     }
1471
1472     IDispatch_Release(obj);
1473     return hres;
1474 }
1475
1476 static void free_dp(DISPPARAMS *dp)
1477 {
1478     DWORD i;
1479
1480     for(i=0; i < dp->cArgs; i++)
1481         VariantClear(dp->rgvarg+i);
1482     heap_free(dp->rgvarg);
1483 }
1484
1485 static HRESULT args_to_param(exec_ctx_t *ctx, argument_t *args, jsexcept_t *ei, DISPPARAMS *dp)
1486 {
1487     VARIANTARG *vargs;
1488     exprval_t exprval;
1489     argument_t *iter;
1490     DWORD cnt = 0, i;
1491     HRESULT hres = S_OK;
1492
1493     memset(dp, 0, sizeof(*dp));
1494     if(!args)
1495         return S_OK;
1496
1497     for(iter = args; iter; iter = iter->next)
1498         cnt++;
1499
1500     vargs = heap_alloc_zero(cnt * sizeof(*vargs));
1501     if(!vargs)
1502         return E_OUTOFMEMORY;
1503
1504     for(i = cnt, iter = args; iter; iter = iter->next) {
1505         hres = expr_eval(ctx, iter->expr, 0, ei, &exprval);
1506         if(FAILED(hres))
1507             break;
1508
1509         hres = exprval_to_value(ctx->parser->script, &exprval, ei, vargs + (--i));
1510         exprval_release(&exprval);
1511         if(FAILED(hres))
1512             break;
1513     }
1514
1515     if(FAILED(hres)) {
1516         free_dp(dp);
1517         return hres;
1518     }
1519
1520     dp->rgvarg = vargs;
1521     dp->cArgs = cnt;
1522     return S_OK;
1523 }
1524
1525 /* ECMA-262 3rd Edition    11.2.2 */
1526 HRESULT new_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1527 {
1528     call_expression_t *expr = (call_expression_t*)_expr;
1529     exprval_t exprval;
1530     VARIANT constr, var;
1531     DISPPARAMS dp;
1532     HRESULT hres;
1533
1534     TRACE("\n");
1535
1536     hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
1537     if(FAILED(hres))
1538         return hres;
1539
1540     hres = args_to_param(ctx, expr->argument_list, ei, &dp);
1541     if(SUCCEEDED(hres))
1542         hres = exprval_to_value(ctx->parser->script, &exprval, ei, &constr);
1543     exprval_release(&exprval);
1544     if(FAILED(hres))
1545         return hres;
1546
1547     if(V_VT(&constr) != VT_DISPATCH) {
1548         FIXME("throw TypeError\n");
1549         VariantClear(&constr);
1550         return E_FAIL;
1551     }
1552
1553     hres = disp_call(ctx->parser->script, V_DISPATCH(&constr), DISPID_VALUE,
1554                      DISPATCH_CONSTRUCT, &dp, &var, ei, NULL/*FIXME*/);
1555     IDispatch_Release(V_DISPATCH(&constr));
1556     if(FAILED(hres))
1557         return hres;
1558
1559     ret->type = EXPRVAL_VARIANT;
1560     ret->u.var = var;
1561     return S_OK;
1562 }
1563
1564 /* ECMA-262 3rd Edition    11.2.3 */
1565 HRESULT call_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1566 {
1567     call_expression_t *expr = (call_expression_t*)_expr;
1568     VARIANT var;
1569     exprval_t exprval;
1570     DISPPARAMS dp;
1571     HRESULT hres;
1572
1573     TRACE("\n");
1574
1575     hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
1576     if(FAILED(hres))
1577         return hres;
1578
1579     hres = args_to_param(ctx, expr->argument_list, ei, &dp);
1580     if(SUCCEEDED(hres)) {
1581         switch(exprval.type) {
1582         case EXPRVAL_VARIANT:
1583             if(V_VT(&exprval.u.var) == VT_DISPATCH)
1584                 hres = disp_call(ctx->parser->script, V_DISPATCH(&exprval.u.var), DISPID_VALUE,
1585                         DISPATCH_METHOD, &dp, flags & EXPR_NOVAL ? NULL : &var, ei, NULL/*FIXME*/);
1586             else
1587                 hres = throw_type_error(ctx->var_disp->ctx, ei, IDS_NO_PROPERTY, NULL);
1588             break;
1589         case EXPRVAL_IDREF:
1590             hres = disp_call(ctx->parser->script, exprval.u.idref.disp, exprval.u.idref.id,
1591                     DISPATCH_METHOD, &dp, flags & EXPR_NOVAL ? NULL : &var, ei, NULL/*FIXME*/);
1592             break;
1593         case EXPRVAL_INVALID:
1594             hres = throw_type_error(ctx->var_disp->ctx, ei, IDS_OBJECT_EXPECTED, NULL);
1595             break;
1596         default:
1597             FIXME("unimplemented type %d\n", exprval.type);
1598             hres = E_NOTIMPL;
1599         }
1600
1601         free_dp(&dp);
1602     }
1603
1604     exprval_release(&exprval);
1605     if(FAILED(hres))
1606         return hres;
1607
1608     ret->type = EXPRVAL_VARIANT;
1609     if(flags & EXPR_NOVAL) {
1610         V_VT(&ret->u.var) = VT_EMPTY;
1611     }else {
1612         TRACE("= %s\n", debugstr_variant(&var));
1613         ret->u.var = var;
1614     }
1615     return S_OK;
1616 }
1617
1618 /* ECMA-262 3rd Edition    11.1.1 */
1619 HRESULT this_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1620 {
1621     TRACE("\n");
1622
1623     ret->type = EXPRVAL_VARIANT;
1624     V_VT(&ret->u.var) = VT_DISPATCH;
1625     V_DISPATCH(&ret->u.var) = ctx->this_obj;
1626     IDispatch_AddRef(ctx->this_obj);
1627     return S_OK;
1628 }
1629
1630 /* ECMA-262 3rd Edition    10.1.4 */
1631 HRESULT identifier_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1632 {
1633     identifier_expression_t *expr = (identifier_expression_t*)_expr;
1634     BSTR identifier;
1635     HRESULT hres;
1636
1637     TRACE("\n");
1638
1639     identifier = SysAllocString(expr->identifier);
1640     if(!identifier)
1641         return E_OUTOFMEMORY;
1642
1643     hres = identifier_eval(ctx, identifier, flags, ei, ret);
1644
1645     SysFreeString(identifier);
1646     return hres;
1647 }
1648
1649 /* ECMA-262 3rd Edition    7.8 */
1650 HRESULT literal_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1651 {
1652     literal_expression_t *expr = (literal_expression_t*)_expr;
1653     VARIANT var;
1654     HRESULT hres;
1655
1656     TRACE("\n");
1657
1658     hres = literal_to_var(expr->literal, &var);
1659     if(FAILED(hres))
1660         return hres;
1661
1662     ret->type = EXPRVAL_VARIANT;
1663     ret->u.var = var;
1664     return S_OK;
1665 }
1666
1667 /* ECMA-262 3rd Edition    11.1.4 */
1668 HRESULT array_literal_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1669 {
1670     array_literal_expression_t *expr = (array_literal_expression_t*)_expr;
1671     DWORD length = 0, i = 0;
1672     array_element_t *elem;
1673     DispatchEx *array;
1674     exprval_t exprval;
1675     VARIANT val;
1676     HRESULT hres;
1677
1678     TRACE("\n");
1679
1680     for(elem = expr->element_list; elem; elem = elem->next)
1681         length += elem->elision+1;
1682     length += expr->length;
1683
1684     hres = create_array(ctx->parser->script, length, &array);
1685     if(FAILED(hres))
1686         return hres;
1687
1688     for(elem = expr->element_list; elem; elem = elem->next) {
1689         i += elem->elision;
1690
1691         hres = expr_eval(ctx, elem->expr, 0, ei, &exprval);
1692         if(FAILED(hres))
1693             break;
1694
1695         hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
1696         exprval_release(&exprval);
1697         if(FAILED(hres))
1698             break;
1699
1700         hres = jsdisp_propput_idx(array, i, ctx->parser->script->lcid, &val, ei, NULL/*FIXME*/);
1701         VariantClear(&val);
1702         if(FAILED(hres))
1703             break;
1704
1705         i++;
1706     }
1707
1708     if(FAILED(hres)) {
1709         jsdisp_release(array);
1710         return hres;
1711     }
1712
1713     ret->type = EXPRVAL_VARIANT;
1714     V_VT(&ret->u.var) = VT_DISPATCH;
1715     V_DISPATCH(&ret->u.var) = (IDispatch*)_IDispatchEx_(array);
1716     return S_OK;
1717 }
1718
1719 /* ECMA-262 3rd Edition    11.1.5 */
1720 HRESULT property_value_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1721 {
1722     property_value_expression_t *expr = (property_value_expression_t*)_expr;
1723     VARIANT val, tmp;
1724     DispatchEx *obj;
1725     prop_val_t *iter;
1726     exprval_t exprval;
1727     BSTR name;
1728     HRESULT hres;
1729
1730     TRACE("\n");
1731
1732     hres = create_object(ctx->parser->script, NULL, &obj);
1733     if(FAILED(hres))
1734         return hres;
1735
1736     for(iter = expr->property_list; iter; iter = iter->next) {
1737         hres = literal_to_var(iter->name, &tmp);
1738         if(FAILED(hres))
1739             break;
1740
1741         hres = to_string(ctx->parser->script, &tmp, ei, &name);
1742         VariantClear(&tmp);
1743         if(FAILED(hres))
1744             break;
1745
1746         hres = expr_eval(ctx, iter->value, 0, ei, &exprval);
1747         if(SUCCEEDED(hres)) {
1748             hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
1749             exprval_release(&exprval);
1750             if(SUCCEEDED(hres)) {
1751                 hres = jsdisp_propput_name(obj, name, ctx->parser->script->lcid, &val, ei, NULL/*FIXME*/);
1752                 VariantClear(&val);
1753             }
1754         }
1755
1756         SysFreeString(name);
1757         if(FAILED(hres))
1758             break;
1759     }
1760
1761     if(FAILED(hres)) {
1762         jsdisp_release(obj);
1763         return hres;
1764     }
1765
1766     ret->type = EXPRVAL_VARIANT;
1767     V_VT(&ret->u.var) = VT_DISPATCH;
1768     V_DISPATCH(&ret->u.var) = (IDispatch*)_IDispatchEx_(obj);
1769     return S_OK;
1770 }
1771
1772 /* ECMA-262 3rd Edition    11.14 */
1773 HRESULT comma_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1774 {
1775     binary_expression_t *expr = (binary_expression_t*)_expr;
1776     VARIANT lval, rval;
1777     HRESULT hres;
1778
1779     TRACE("\n");
1780
1781     hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval);
1782     if(FAILED(hres))
1783         return hres;
1784
1785     VariantClear(&lval);
1786
1787     ret->type = EXPRVAL_VARIANT;
1788     ret->u.var = rval;
1789     return S_OK;
1790 }
1791
1792 /* ECMA-262 3rd Edition    11.11 */
1793 HRESULT logical_or_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1794 {
1795     binary_expression_t *expr = (binary_expression_t*)_expr;
1796     exprval_t exprval;
1797     VARIANT_BOOL b;
1798     VARIANT val;
1799     HRESULT hres;
1800
1801     TRACE("\n");
1802
1803     hres = expr_eval(ctx, expr->expression1, 0, ei, &exprval);
1804     if(FAILED(hres))
1805         return hres;
1806
1807     hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
1808     exprval_release(&exprval);
1809     if(FAILED(hres))
1810         return hres;
1811
1812     hres = to_boolean(&val, &b);
1813     if(SUCCEEDED(hres) && b) {
1814         ret->type = EXPRVAL_VARIANT;
1815         ret->u.var = val;
1816         return S_OK;
1817     }
1818
1819     VariantClear(&val);
1820     if(FAILED(hres))
1821         return hres;
1822
1823     hres = expr_eval(ctx, expr->expression2, 0, ei, &exprval);
1824     if(FAILED(hres))
1825         return hres;
1826
1827     hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
1828     exprval_release(&exprval);
1829     if(FAILED(hres))
1830         return hres;
1831
1832     ret->type = EXPRVAL_VARIANT;
1833     ret->u.var = val;
1834     return S_OK;
1835 }
1836
1837 /* ECMA-262 3rd Edition    11.11 */
1838 HRESULT logical_and_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1839 {
1840     binary_expression_t *expr = (binary_expression_t*)_expr;
1841     exprval_t exprval;
1842     VARIANT_BOOL b;
1843     VARIANT val;
1844     HRESULT hres;
1845
1846     TRACE("\n");
1847
1848     hres = expr_eval(ctx, expr->expression1, 0, ei, &exprval);
1849     if(FAILED(hres))
1850         return hres;
1851
1852     hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
1853     exprval_release(&exprval);
1854     if(FAILED(hres))
1855         return hres;
1856
1857     hres = to_boolean(&val, &b);
1858     if(SUCCEEDED(hres) && !b) {
1859         ret->type = EXPRVAL_VARIANT;
1860         ret->u.var = val;
1861         return S_OK;
1862     }
1863
1864     VariantClear(&val);
1865     if(FAILED(hres))
1866         return hres;
1867
1868     hres = expr_eval(ctx, expr->expression2, 0, ei, &exprval);
1869     if(FAILED(hres))
1870         return hres;
1871
1872     hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
1873     exprval_release(&exprval);
1874     if(FAILED(hres))
1875         return hres;
1876
1877     ret->type = EXPRVAL_VARIANT;
1878     ret->u.var = val;
1879     return S_OK;
1880 }
1881
1882 /* ECMA-262 3rd Edition    11.10 */
1883 static HRESULT bitor_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
1884 {
1885     INT li, ri;
1886     HRESULT hres;
1887
1888     hres = to_int32(ctx->parser->script, lval, ei, &li);
1889     if(FAILED(hres))
1890         return hres;
1891
1892     hres = to_int32(ctx->parser->script, rval, ei, &ri);
1893     if(FAILED(hres))
1894         return hres;
1895
1896     V_VT(retv) = VT_I4;
1897     V_I4(retv) = li|ri;
1898     return S_OK;
1899 }
1900
1901 /* ECMA-262 3rd Edition    11.10 */
1902 HRESULT binary_or_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1903 {
1904     binary_expression_t *expr = (binary_expression_t*)_expr;
1905
1906     TRACE("\n");
1907
1908     return binary_expr_eval(ctx, expr, bitor_eval, ei, ret);
1909 }
1910
1911 /* ECMA-262 3rd Edition    11.10 */
1912 static HRESULT xor_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
1913 {
1914     INT li, ri;
1915     HRESULT hres;
1916
1917     hres = to_int32(ctx->parser->script, lval, ei, &li);
1918     if(FAILED(hres))
1919         return hres;
1920
1921     hres = to_int32(ctx->parser->script, rval, ei, &ri);
1922     if(FAILED(hres))
1923         return hres;
1924
1925     V_VT(retv) = VT_I4;
1926     V_I4(retv) = li^ri;
1927     return S_OK;
1928 }
1929
1930 /* ECMA-262 3rd Edition    11.10 */
1931 HRESULT binary_xor_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1932 {
1933     binary_expression_t *expr = (binary_expression_t*)_expr;
1934
1935     TRACE("\n");
1936
1937     return binary_expr_eval(ctx, expr, xor_eval, ei, ret);
1938 }
1939
1940 /* ECMA-262 3rd Edition    11.10 */
1941 static HRESULT bitand_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
1942 {
1943     INT li, ri;
1944     HRESULT hres;
1945
1946     hres = to_int32(ctx->parser->script, lval, ei, &li);
1947     if(FAILED(hres))
1948         return hres;
1949
1950     hres = to_int32(ctx->parser->script, rval, ei, &ri);
1951     if(FAILED(hres))
1952         return hres;
1953
1954     V_VT(retv) = VT_I4;
1955     V_I4(retv) = li&ri;
1956     return S_OK;
1957 }
1958
1959 /* ECMA-262 3rd Edition    11.10 */
1960 HRESULT binary_and_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1961 {
1962     binary_expression_t *expr = (binary_expression_t*)_expr;
1963
1964     TRACE("\n");
1965
1966     return binary_expr_eval(ctx, expr, bitand_eval, ei, ret);
1967 }
1968
1969 /* ECMA-262 3rd Edition    11.8.6 */
1970 static HRESULT instanceof_eval(exec_ctx_t *ctx, VARIANT *inst, VARIANT *objv, jsexcept_t *ei, VARIANT *retv)
1971 {
1972     DispatchEx *obj, *iter, *tmp = NULL;
1973     VARIANT_BOOL ret = VARIANT_FALSE;
1974     BOOL b;
1975     VARIANT var;
1976     HRESULT hres;
1977
1978     static const WCHAR prototypeW[] = {'p','r','o','t','o','t', 'y', 'p','e',0};
1979
1980     if(V_VT(objv) != VT_DISPATCH) {
1981         FIXME("throw TypeError\n");
1982         return E_FAIL;
1983     }
1984
1985     obj = iface_to_jsdisp((IUnknown*)V_DISPATCH(objv));
1986     if(!obj) {
1987         FIXME("throw TypeError\n");
1988         return E_FAIL;
1989     }
1990
1991     if(is_class(obj, JSCLASS_FUNCTION)) {
1992         hres = jsdisp_propget_name(obj, prototypeW, ctx->parser->script->lcid, &var, ei, NULL/*FIXME*/);
1993     }else {
1994         FIXME("throw TypeError\n");
1995         hres = E_FAIL;
1996     }
1997     jsdisp_release(obj);
1998     if(FAILED(hres))
1999         return hres;
2000
2001     if(V_VT(&var) == VT_DISPATCH) {
2002         if(V_VT(inst) == VT_DISPATCH)
2003             tmp = iface_to_jsdisp((IUnknown*)V_DISPATCH(inst));
2004         for(iter = tmp; iter; iter = iter->prototype) {
2005             hres = disp_cmp(V_DISPATCH(&var), (IDispatch*)_IDispatchEx_(iter), &b);
2006             if(FAILED(hres))
2007                 break;
2008             if(b) {
2009                 ret = VARIANT_TRUE;
2010                 break;
2011             }
2012         }
2013
2014         if(tmp)
2015             jsdisp_release(tmp);
2016     }else {
2017         FIXME("prototype is not an object\n");
2018         hres = E_FAIL;
2019     }
2020
2021     VariantClear(&var);
2022     if(FAILED(hres))
2023         return hres;
2024
2025     V_VT(retv) = VT_BOOL;
2026     V_BOOL(retv) = ret;
2027     return S_OK;
2028 }
2029
2030 /* ECMA-262 3rd Edition    11.8.6 */
2031 HRESULT instanceof_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2032 {
2033     binary_expression_t *expr = (binary_expression_t*)_expr;
2034
2035     TRACE("\n");
2036
2037     return binary_expr_eval(ctx, expr, instanceof_eval, ei, ret);
2038 }
2039
2040 /* ECMA-262 3rd Edition    11.8.7 */
2041 static HRESULT in_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *obj, jsexcept_t *ei, VARIANT *retv)
2042 {
2043     VARIANT_BOOL ret;
2044     DISPID id;
2045     BSTR str;
2046     HRESULT hres;
2047
2048     if(V_VT(obj) != VT_DISPATCH) {
2049         FIXME("throw TypeError\n");
2050         return E_FAIL;
2051     }
2052
2053     hres = to_string(ctx->parser->script, lval, ei, &str);
2054     if(FAILED(hres))
2055         return hres;
2056
2057     hres = disp_get_id(V_DISPATCH(obj), str, 0, &id);
2058     SysFreeString(str);
2059     if(SUCCEEDED(hres))
2060         ret = VARIANT_TRUE;
2061     else if(hres == DISP_E_UNKNOWNNAME)
2062         ret = VARIANT_FALSE;
2063     else
2064         return hres;
2065
2066     V_VT(retv) = VT_BOOL;
2067     V_BOOL(retv) = ret;
2068     return S_OK;
2069 }
2070
2071 /* ECMA-262 3rd Edition    11.8.7 */
2072 HRESULT in_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2073 {
2074     binary_expression_t *expr = (binary_expression_t*)_expr;
2075
2076     TRACE("\n");
2077
2078     return binary_expr_eval(ctx, expr, in_eval, ei, ret);
2079 }
2080
2081 /* ECMA-262 3rd Edition    11.6.1 */
2082 static HRESULT add_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
2083 {
2084     VARIANT r, l;
2085     HRESULT hres;
2086
2087     hres = to_primitive(ctx->parser->script, lval, ei, &l, NO_HINT);
2088     if(FAILED(hres))
2089         return hres;
2090
2091     hres = to_primitive(ctx->parser->script, rval, ei, &r, NO_HINT);
2092     if(FAILED(hres)) {
2093         VariantClear(&l);
2094         return hres;
2095     }
2096
2097     if(V_VT(&l) == VT_BSTR || V_VT(&r) == VT_BSTR) {
2098         BSTR lstr = NULL, rstr = NULL;
2099
2100         if(V_VT(&l) == VT_BSTR)
2101             lstr = V_BSTR(&l);
2102         else
2103             hres = to_string(ctx->parser->script, &l, ei, &lstr);
2104
2105         if(SUCCEEDED(hres)) {
2106             if(V_VT(&r) == VT_BSTR)
2107                 rstr = V_BSTR(&r);
2108             else
2109                 hres = to_string(ctx->parser->script, &r, ei, &rstr);
2110         }
2111
2112         if(SUCCEEDED(hres)) {
2113             int len1, len2;
2114
2115             len1 = SysStringLen(lstr);
2116             len2 = SysStringLen(rstr);
2117
2118             V_VT(retv) = VT_BSTR;
2119             V_BSTR(retv) = SysAllocStringLen(NULL, len1+len2);
2120             memcpy(V_BSTR(retv), lstr, len1*sizeof(WCHAR));
2121             memcpy(V_BSTR(retv)+len1, rstr, (len2+1)*sizeof(WCHAR));
2122         }
2123
2124         if(V_VT(&l) != VT_BSTR)
2125             SysFreeString(lstr);
2126         if(V_VT(&r) != VT_BSTR)
2127             SysFreeString(rstr);
2128     }else {
2129         VARIANT nl, nr;
2130
2131         hres = to_number(ctx->parser->script, &l, ei, &nl);
2132         if(SUCCEEDED(hres)) {
2133             hres = to_number(ctx->parser->script, &r, ei, &nr);
2134             if(SUCCEEDED(hres))
2135                 num_set_val(retv, num_val(&nl) + num_val(&nr));
2136         }
2137     }
2138
2139     VariantClear(&r);
2140     VariantClear(&l);
2141     return hres;
2142 }
2143
2144 /* ECMA-262 3rd Edition    11.6.1 */
2145 HRESULT add_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2146 {
2147     binary_expression_t *expr = (binary_expression_t*)_expr;
2148
2149     TRACE("\n");
2150
2151     return binary_expr_eval(ctx, expr, add_eval, ei, ret);
2152 }
2153
2154 /* ECMA-262 3rd Edition    11.6.2 */
2155 static HRESULT sub_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
2156 {
2157     VARIANT lnum, rnum;
2158     HRESULT hres;
2159
2160     hres = to_number(ctx->parser->script, lval, ei, &lnum);
2161     if(FAILED(hres))
2162         return hres;
2163
2164     hres = to_number(ctx->parser->script, rval, ei, &rnum);
2165     if(FAILED(hres))
2166         return hres;
2167
2168     num_set_val(retv, num_val(&lnum) - num_val(&rnum));
2169     return S_OK;
2170 }
2171
2172 /* ECMA-262 3rd Edition    11.6.2 */
2173 HRESULT sub_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2174 {
2175     binary_expression_t *expr = (binary_expression_t*)_expr;
2176
2177     TRACE("\n");
2178
2179     return binary_expr_eval(ctx, expr, sub_eval, ei, ret);
2180 }
2181
2182 /* ECMA-262 3rd Edition    11.5.1 */
2183 static HRESULT mul_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
2184 {
2185     VARIANT lnum, rnum;
2186     HRESULT hres;
2187
2188     hres = to_number(ctx->parser->script, lval, ei, &lnum);
2189     if(FAILED(hres))
2190         return hres;
2191
2192     hres = to_number(ctx->parser->script, rval, ei, &rnum);
2193     if(FAILED(hres))
2194         return hres;
2195
2196     num_set_val(retv, num_val(&lnum) * num_val(&rnum));
2197     return S_OK;
2198 }
2199
2200 /* ECMA-262 3rd Edition    11.5.1 */
2201 HRESULT mul_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2202 {
2203     binary_expression_t *expr = (binary_expression_t*)_expr;
2204
2205     TRACE("\n");
2206
2207     return binary_expr_eval(ctx, expr, mul_eval, ei, ret);
2208 }
2209
2210 /* ECMA-262 3rd Edition    11.5.2 */
2211 static HRESULT div_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
2212 {
2213     VARIANT lnum, rnum;
2214     HRESULT hres;
2215
2216     hres = to_number(ctx->parser->script, lval, ei, &lnum);
2217     if(FAILED(hres))
2218         return hres;
2219
2220     hres = to_number(ctx->parser->script, rval, ei, &rnum);
2221     if(FAILED(hres))
2222         return hres;
2223
2224     num_set_val(retv, num_val(&lnum) / num_val(&rnum));
2225     return S_OK;
2226 }
2227
2228 /* ECMA-262 3rd Edition    11.5.2 */
2229 HRESULT div_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2230 {
2231     binary_expression_t *expr = (binary_expression_t*)_expr;
2232
2233     TRACE("\n");
2234
2235     return binary_expr_eval(ctx, expr, div_eval, ei, ret);
2236 }
2237
2238 /* ECMA-262 3rd Edition    11.5.3 */
2239 static HRESULT mod_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
2240 {
2241     VARIANT lnum, rnum;
2242     HRESULT hres;
2243
2244     hres = to_number(ctx->parser->script, lval, ei, &lnum);
2245     if(FAILED(hres))
2246         return hres;
2247
2248     hres = to_number(ctx->parser->script, rval, ei, &rnum);
2249     if(FAILED(hres))
2250         return hres;
2251
2252     num_set_val(retv, fmod(num_val(&lnum), num_val(&rnum)));
2253     return S_OK;
2254 }
2255
2256 /* ECMA-262 3rd Edition    11.5.3 */
2257 HRESULT mod_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2258 {
2259     binary_expression_t *expr = (binary_expression_t*)_expr;
2260
2261     TRACE("\n");
2262
2263     return binary_expr_eval(ctx, expr, mod_eval, ei, ret);
2264 }
2265
2266 /* ECMA-262 3rd Edition    11.4.2 */
2267 HRESULT delete_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2268 {
2269     unary_expression_t *expr = (unary_expression_t*)_expr;
2270     VARIANT_BOOL b = VARIANT_FALSE;
2271     exprval_t exprval;
2272     HRESULT hres;
2273
2274     TRACE("\n");
2275
2276     hres = expr_eval(ctx, expr->expression, EXPR_STRREF, ei, &exprval);
2277     if(FAILED(hres))
2278         return hres;
2279
2280     switch(exprval.type) {
2281     case EXPRVAL_IDREF: {
2282         IDispatchEx *dispex;
2283
2284         hres = IDispatch_QueryInterface(exprval.u.nameref.disp, &IID_IDispatchEx, (void**)&dispex);
2285         if(SUCCEEDED(hres)) {
2286             hres = IDispatchEx_DeleteMemberByDispID(dispex, exprval.u.idref.id);
2287             b = VARIANT_TRUE;
2288             IDispatchEx_Release(dispex);
2289         }
2290         break;
2291     }
2292     case EXPRVAL_NAMEREF: {
2293         IDispatchEx *dispex;
2294
2295         hres = IDispatch_QueryInterface(exprval.u.nameref.disp, &IID_IDispatchEx, (void**)&dispex);
2296         if(SUCCEEDED(hres)) {
2297             hres = IDispatchEx_DeleteMemberByName(dispex, exprval.u.nameref.name, fdexNameCaseSensitive);
2298             b = VARIANT_TRUE;
2299             IDispatchEx_Release(dispex);
2300         }
2301         break;
2302     }
2303     default:
2304         FIXME("unsupported type %d\n", exprval.type);
2305         hres = E_NOTIMPL;
2306     }
2307
2308     exprval_release(&exprval);
2309     if(FAILED(hres))
2310         return hres;
2311
2312     return return_bool(ret, b);
2313 }
2314
2315 /* ECMA-262 3rd Edition    11.4.2 */
2316 HRESULT void_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2317 {
2318     unary_expression_t *expr = (unary_expression_t*)_expr;
2319     exprval_t exprval;
2320     VARIANT tmp;
2321     HRESULT hres;
2322
2323     TRACE("\n");
2324
2325     hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
2326     if(FAILED(hres))
2327         return hres;
2328
2329     hres = exprval_to_value(ctx->parser->script, &exprval, ei, &tmp);
2330     exprval_release(&exprval);
2331     if(FAILED(hres))
2332         return hres;
2333
2334     VariantClear(&tmp);
2335
2336     ret->type = EXPRVAL_VARIANT;
2337     V_VT(&ret->u.var) = VT_EMPTY;
2338     return S_OK;
2339 }
2340
2341 /* ECMA-262 3rd Edition    11.4.3 */
2342 static HRESULT typeof_exprval(exec_ctx_t *ctx, exprval_t *exprval, jsexcept_t *ei, const WCHAR **ret)
2343 {
2344     VARIANT val;
2345     HRESULT hres;
2346
2347     static const WCHAR booleanW[] = {'b','o','o','l','e','a','n',0};
2348     static const WCHAR functionW[] = {'f','u','n','c','t','i','o','n',0};
2349     static const WCHAR numberW[] = {'n','u','m','b','e','r',0};
2350     static const WCHAR objectW[] = {'o','b','j','e','c','t',0};
2351     static const WCHAR stringW[] = {'s','t','r','i','n','g',0};
2352     static const WCHAR undefinedW[] = {'u','n','d','e','f','i','n','e','d',0};
2353
2354     if(exprval->type == EXPRVAL_INVALID) {
2355         *ret = undefinedW;
2356         return S_OK;
2357     }
2358
2359     hres = exprval_to_value(ctx->parser->script, exprval, ei, &val);
2360     if(FAILED(hres))
2361         return hres;
2362
2363     switch(V_VT(&val)) {
2364     case VT_EMPTY:
2365         *ret = undefinedW;
2366         break;
2367     case VT_NULL:
2368         *ret = objectW;
2369         break;
2370     case VT_BOOL:
2371         *ret = booleanW;
2372         break;
2373     case VT_I4:
2374     case VT_R8:
2375         *ret = numberW;
2376         break;
2377     case VT_BSTR:
2378         *ret = stringW;
2379         break;
2380     case VT_DISPATCH: {
2381         DispatchEx *dispex;
2382
2383         if(V_DISPATCH(&val) && (dispex = iface_to_jsdisp((IUnknown*)V_DISPATCH(&val)))) {
2384             *ret = is_class(dispex, JSCLASS_FUNCTION) ? functionW : objectW;
2385             jsdisp_release(dispex);
2386         }else {
2387             *ret = objectW;
2388         }
2389         break;
2390     }
2391     default:
2392         FIXME("unhandled vt %d\n", V_VT(&val));
2393         hres = E_NOTIMPL;
2394     }
2395
2396     VariantClear(&val);
2397     return S_OK;
2398 }
2399
2400 HRESULT typeof_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2401 {
2402     unary_expression_t *expr = (unary_expression_t*)_expr;
2403     const WCHAR *str = NULL;
2404     exprval_t exprval;
2405     HRESULT hres;
2406
2407     TRACE("\n");
2408
2409     hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
2410     if(FAILED(hres))
2411         return hres;
2412
2413     hres = typeof_exprval(ctx, &exprval, ei, &str);
2414     exprval_release(&exprval);
2415     if(FAILED(hres))
2416         return hres;
2417
2418     ret->type = EXPRVAL_VARIANT;
2419     V_VT(&ret->u.var) = VT_BSTR;
2420     V_BSTR(&ret->u.var) = SysAllocString(str);
2421     if(!V_BSTR(&ret->u.var))
2422         return E_OUTOFMEMORY;
2423
2424     return S_OK;
2425 }
2426
2427 /* ECMA-262 3rd Edition    11.4.7 */
2428 HRESULT minus_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2429 {
2430     unary_expression_t *expr = (unary_expression_t*)_expr;
2431     exprval_t exprval;
2432     VARIANT val, num;
2433     HRESULT hres;
2434
2435     TRACE("\n");
2436
2437     hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
2438     if(FAILED(hres))
2439         return hres;
2440
2441     hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
2442     exprval_release(&exprval);
2443     if(FAILED(hres))
2444         return hres;
2445
2446     hres = to_number(ctx->parser->script, &val, ei, &num);
2447     VariantClear(&val);
2448     if(FAILED(hres))
2449         return hres;
2450
2451     ret->type = EXPRVAL_VARIANT;
2452     num_set_val(&ret->u.var, -num_val(&num));
2453     return S_OK;
2454 }
2455
2456 /* ECMA-262 3rd Edition    11.4.6 */
2457 HRESULT plus_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2458 {
2459     unary_expression_t *expr = (unary_expression_t*)_expr;
2460     exprval_t exprval;
2461     VARIANT val, num;
2462     HRESULT hres;
2463
2464     TRACE("\n");
2465
2466     hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval);
2467     if(FAILED(hres))
2468         return hres;
2469
2470     hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
2471     exprval_release(&exprval);
2472     if(FAILED(hres))
2473         return hres;
2474
2475     hres = to_number(ctx->parser->script, &val, ei, &num);
2476     if(FAILED(hres))
2477         return hres;
2478
2479     ret->type = EXPRVAL_VARIANT;
2480     ret->u.var = num;
2481     return S_OK;
2482 }
2483
2484 /* ECMA-262 3rd Edition    11.3.1 */
2485 HRESULT post_increment_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2486 {
2487     unary_expression_t *expr = (unary_expression_t*)_expr;
2488     VARIANT val, num;
2489     exprval_t exprval;
2490     HRESULT hres;
2491
2492     TRACE("\n");
2493
2494     hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval);
2495     if(FAILED(hres))
2496         return hres;
2497
2498     hres = exprval_value(ctx->parser->script, &exprval, ei, &val);
2499     if(SUCCEEDED(hres)) {
2500         hres = to_number(ctx->parser->script, &val, ei, &num);
2501         VariantClear(&val);
2502     }
2503
2504     if(SUCCEEDED(hres)) {
2505         VARIANT inc;
2506         num_set_val(&inc, num_val(&num)+1.0);
2507         hres = put_value(ctx->parser->script, &exprval, &inc, ei);
2508     }
2509
2510     exprval_release(&exprval);
2511     if(FAILED(hres))
2512         return hres;
2513
2514     ret->type = EXPRVAL_VARIANT;
2515     ret->u.var = num;
2516     return S_OK;
2517 }
2518
2519 /* ECMA-262 3rd Edition    11.3.2 */
2520 HRESULT post_decrement_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2521 {
2522     unary_expression_t *expr = (unary_expression_t*)_expr;
2523     VARIANT val, num;
2524     exprval_t exprval;
2525     HRESULT hres;
2526
2527     TRACE("\n");
2528
2529     hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval);
2530     if(FAILED(hres))
2531         return hres;
2532
2533     hres = exprval_value(ctx->parser->script, &exprval, ei, &val);
2534     if(SUCCEEDED(hres)) {
2535         hres = to_number(ctx->parser->script, &val, ei, &num);
2536         VariantClear(&val);
2537     }
2538
2539     if(SUCCEEDED(hres)) {
2540         VARIANT dec;
2541         num_set_val(&dec, num_val(&num)-1.0);
2542         hres = put_value(ctx->parser->script, &exprval, &dec, ei);
2543     }
2544
2545     exprval_release(&exprval);
2546     if(FAILED(hres))
2547         return hres;
2548
2549     ret->type = EXPRVAL_VARIANT;
2550     ret->u.var = num;
2551     return S_OK;
2552 }
2553
2554 /* ECMA-262 3rd Edition    11.4.4 */
2555 HRESULT pre_increment_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2556 {
2557     unary_expression_t *expr = (unary_expression_t*)_expr;
2558     VARIANT val, num;
2559     exprval_t exprval;
2560     HRESULT hres;
2561
2562     TRACE("\n");
2563
2564     hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval);
2565     if(FAILED(hres))
2566         return hres;
2567
2568     hres = exprval_value(ctx->parser->script, &exprval, ei, &val);
2569     if(SUCCEEDED(hres)) {
2570         hres = to_number(ctx->parser->script, &val, ei, &num);
2571         VariantClear(&val);
2572     }
2573
2574     if(SUCCEEDED(hres)) {
2575         num_set_val(&val, num_val(&num)+1.0);
2576         hres = put_value(ctx->parser->script, &exprval, &val, ei);
2577     }
2578
2579     exprval_release(&exprval);
2580     if(FAILED(hres))
2581         return hres;
2582
2583     ret->type = EXPRVAL_VARIANT;
2584     ret->u.var = val;
2585     return S_OK;
2586 }
2587
2588 /* ECMA-262 3rd Edition    11.4.5 */
2589 HRESULT pre_decrement_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2590 {
2591     unary_expression_t *expr = (unary_expression_t*)_expr;
2592     VARIANT val, num;
2593     exprval_t exprval;
2594     HRESULT hres;
2595
2596     TRACE("\n");
2597
2598     hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval);
2599     if(FAILED(hres))
2600         return hres;
2601
2602     hres = exprval_value(ctx->parser->script, &exprval, ei, &val);
2603     if(SUCCEEDED(hres)) {
2604         hres = to_number(ctx->parser->script, &val, ei, &num);
2605         VariantClear(&val);
2606     }
2607
2608     if(SUCCEEDED(hres)) {
2609         num_set_val(&val, num_val(&num)-1.0);
2610         hres = put_value(ctx->parser->script, &exprval, &val, ei);
2611     }
2612
2613     exprval_release(&exprval);
2614     if(FAILED(hres))
2615         return hres;
2616
2617     ret->type = EXPRVAL_VARIANT;
2618     ret->u.var = val;
2619     return S_OK;
2620 }
2621
2622 /* ECMA-262 3rd Edition    11.9.3 */
2623 static HRESULT equal_values(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, BOOL *ret)
2624 {
2625     if(V_VT(lval) == V_VT(rval) || (is_num_vt(V_VT(lval)) && is_num_vt(V_VT(rval))))
2626        return equal2_values(lval, rval, ret);
2627
2628     /* FIXME: NULL disps should be handled in more general way */
2629     if(V_VT(lval) == VT_DISPATCH && !V_DISPATCH(lval)) {
2630         VARIANT v;
2631         V_VT(&v) = VT_NULL;
2632         return equal_values(ctx, &v, rval, ei, ret);
2633     }
2634
2635     if(V_VT(rval) == VT_DISPATCH && !V_DISPATCH(rval)) {
2636         VARIANT v;
2637         V_VT(&v) = VT_NULL;
2638         return equal_values(ctx, lval, &v, ei, ret);
2639     }
2640
2641     if((V_VT(lval) == VT_NULL && V_VT(rval) == VT_EMPTY) ||
2642        (V_VT(lval) == VT_EMPTY && V_VT(rval) == VT_NULL)) {
2643         *ret = TRUE;
2644         return S_OK;
2645     }
2646
2647     if(V_VT(lval) == VT_BSTR && is_num_vt(V_VT(rval))) {
2648         VARIANT v;
2649         HRESULT hres;
2650
2651         hres = to_number(ctx->parser->script, lval, ei, &v);
2652         if(FAILED(hres))
2653             return hres;
2654
2655         return equal_values(ctx, &v, rval, ei, ret);
2656     }
2657
2658     if(V_VT(rval) == VT_BSTR && is_num_vt(V_VT(lval))) {
2659         VARIANT v;
2660         HRESULT hres;
2661
2662         hres = to_number(ctx->parser->script, rval, ei, &v);
2663         if(FAILED(hres))
2664             return hres;
2665
2666         return equal_values(ctx, lval, &v, ei, ret);
2667     }
2668
2669     if(V_VT(rval) == VT_BOOL) {
2670         VARIANT v;
2671
2672         V_VT(&v) = VT_I4;
2673         V_I4(&v) = V_BOOL(rval) ? 1 : 0;
2674         return equal_values(ctx, lval, &v, ei, ret);
2675     }
2676
2677     if(V_VT(lval) == VT_BOOL) {
2678         VARIANT v;
2679
2680         V_VT(&v) = VT_I4;
2681         V_I4(&v) = V_BOOL(lval) ? 1 : 0;
2682         return equal_values(ctx, &v, rval, ei, ret);
2683     }
2684
2685
2686     if(V_VT(rval) == VT_DISPATCH && (V_VT(lval) == VT_BSTR || is_num_vt(V_VT(lval)))) {
2687         VARIANT v;
2688         HRESULT hres;
2689
2690         hres = to_primitive(ctx->parser->script, rval, ei, &v, NO_HINT);
2691         if(FAILED(hres))
2692             return hres;
2693
2694         hres = equal_values(ctx, lval, &v, ei, ret);
2695
2696         VariantClear(&v);
2697         return hres;
2698     }
2699
2700
2701     if(V_VT(lval) == VT_DISPATCH && (V_VT(rval) == VT_BSTR || is_num_vt(V_VT(rval)))) {
2702         VARIANT v;
2703         HRESULT hres;
2704
2705         hres = to_primitive(ctx->parser->script, lval, ei, &v, NO_HINT);
2706         if(FAILED(hres))
2707             return hres;
2708
2709         hres = equal_values(ctx, &v, rval, ei, ret);
2710
2711         VariantClear(&v);
2712         return hres;
2713     }
2714
2715
2716     *ret = FALSE;
2717     return S_OK;
2718 }
2719
2720 /* ECMA-262 3rd Edition    11.9.1 */
2721 HRESULT equal_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2722 {
2723     binary_expression_t *expr = (binary_expression_t*)_expr;
2724     VARIANT rval, lval;
2725     BOOL b;
2726     HRESULT hres;
2727
2728     TRACE("\n");
2729
2730     hres = get_binary_expr_values(ctx, expr, ei, &rval, &lval);
2731     if(FAILED(hres))
2732         return hres;
2733
2734     hres = equal_values(ctx, &rval, &lval, ei, &b);
2735     if(FAILED(hres))
2736         return hres;
2737
2738     return return_bool(ret, b);
2739 }
2740
2741 /* ECMA-262 3rd Edition    11.9.4 */
2742 HRESULT equal2_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2743 {
2744     binary_expression_t *expr = (binary_expression_t*)_expr;
2745     VARIANT rval, lval;
2746     BOOL b;
2747     HRESULT hres;
2748
2749     TRACE("\n");
2750
2751     hres = get_binary_expr_values(ctx, expr, ei, &rval, &lval);
2752     if(FAILED(hres))
2753         return hres;
2754
2755     hres = equal2_values(&rval, &lval, &b);
2756     if(FAILED(hres))
2757         return hres;
2758
2759     return return_bool(ret, b);
2760 }
2761
2762 /* ECMA-262 3rd Edition    11.9.2 */
2763 HRESULT not_equal_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2764 {
2765     binary_expression_t *expr = (binary_expression_t*)_expr;
2766     VARIANT rval, lval;
2767     BOOL b;
2768     HRESULT hres;
2769
2770     TRACE("\n");
2771
2772     hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval);
2773     if(FAILED(hres))
2774         return hres;
2775
2776     hres = equal_values(ctx, &lval, &rval, ei, &b);
2777     if(FAILED(hres))
2778         return hres;
2779
2780     return return_bool(ret, !b);
2781 }
2782
2783 /* ECMA-262 3rd Edition    11.9.5 */
2784 HRESULT not_equal2_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2785 {
2786     binary_expression_t *expr = (binary_expression_t*)_expr;
2787     VARIANT rval, lval;
2788     BOOL b;
2789     HRESULT hres;
2790
2791     TRACE("\n");
2792
2793     hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval);
2794     if(FAILED(hres))
2795         return hres;
2796
2797     hres = equal2_values(&lval, &rval, &b);
2798     if(FAILED(hres))
2799         return hres;
2800
2801     return return_bool(ret, !b);
2802 }
2803
2804 /* ECMA-262 3rd Edition    11.8.5 */
2805 static HRESULT less_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, BOOL greater, jsexcept_t *ei, BOOL *ret)
2806 {
2807     VARIANT l, r, ln, rn;
2808     HRESULT hres;
2809
2810     hres = to_primitive(ctx->parser->script, lval, ei, &l, NO_HINT);
2811     if(FAILED(hres))
2812         return hres;
2813
2814     hres = to_primitive(ctx->parser->script, rval, ei, &r, NO_HINT);
2815     if(FAILED(hres)) {
2816         VariantClear(&l);
2817         return hres;
2818     }
2819
2820     if(V_VT(&l) == VT_BSTR && V_VT(&r) == VT_BSTR) {
2821         *ret = (strcmpW(V_BSTR(&l), V_BSTR(&r)) < 0) ^ greater;
2822         SysFreeString(V_BSTR(&l));
2823         SysFreeString(V_BSTR(&r));
2824         return S_OK;
2825     }
2826
2827     hres = to_number(ctx->parser->script, &l, ei, &ln);
2828     VariantClear(&l);
2829     if(SUCCEEDED(hres))
2830         hres = to_number(ctx->parser->script, &r, ei, &rn);
2831     VariantClear(&r);
2832     if(FAILED(hres))
2833         return hres;
2834
2835     if(V_VT(&ln) == VT_I4 && V_VT(&rn) == VT_I4) {
2836         *ret = (V_I4(&ln) < V_I4(&rn)) ^ greater;
2837     }else  {
2838         DOUBLE ld = num_val(&ln);
2839         DOUBLE rd = num_val(&rn);
2840
2841         *ret = !isnan(ld) && !isnan(rd) && ((ld < rd) ^ greater);
2842     }
2843
2844     return S_OK;
2845 }
2846
2847 /* ECMA-262 3rd Edition    11.8.1 */
2848 HRESULT less_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2849 {
2850     binary_expression_t *expr = (binary_expression_t*)_expr;
2851     VARIANT rval, lval;
2852     BOOL b;
2853     HRESULT hres;
2854
2855     TRACE("\n");
2856
2857     hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval);
2858     if(FAILED(hres))
2859         return hres;
2860
2861     hres = less_eval(ctx, &lval, &rval, FALSE, ei, &b);
2862     VariantClear(&lval);
2863     VariantClear(&rval);
2864     if(FAILED(hres))
2865         return hres;
2866
2867     return return_bool(ret, b);
2868 }
2869
2870 /* ECMA-262 3rd Edition    11.8.3 */
2871 HRESULT lesseq_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2872 {
2873     binary_expression_t *expr = (binary_expression_t*)_expr;
2874     VARIANT rval, lval;
2875     BOOL b;
2876     HRESULT hres;
2877
2878     TRACE("\n");
2879
2880     hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval);
2881     if(FAILED(hres))
2882         return hres;
2883
2884     hres = less_eval(ctx, &rval, &lval, TRUE, ei, &b);
2885     VariantClear(&lval);
2886     VariantClear(&rval);
2887     if(FAILED(hres))
2888         return hres;
2889
2890     return return_bool(ret, b);
2891 }
2892
2893 /* ECMA-262 3rd Edition    11.8.2 */
2894 HRESULT greater_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2895 {
2896     binary_expression_t *expr = (binary_expression_t*)_expr;
2897     VARIANT rval, lval;
2898     BOOL b;
2899     HRESULT hres;
2900
2901     TRACE("\n");
2902
2903     hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval);
2904     if(FAILED(hres))
2905         return hres;
2906
2907     hres = less_eval(ctx, &rval, &lval, FALSE, ei, &b);
2908     VariantClear(&lval);
2909     VariantClear(&rval);
2910     if(FAILED(hres))
2911         return hres;
2912
2913     return return_bool(ret, b);
2914 }
2915
2916 /* ECMA-262 3rd Edition    11.8.4 */
2917 HRESULT greatereq_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2918 {
2919     binary_expression_t *expr = (binary_expression_t*)_expr;
2920     VARIANT rval, lval;
2921     BOOL b;
2922     HRESULT hres;
2923
2924     TRACE("\n");
2925
2926     hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval);
2927     if(FAILED(hres))
2928         return hres;
2929
2930     hres = less_eval(ctx, &lval, &rval, TRUE, ei, &b);
2931     VariantClear(&lval);
2932     VariantClear(&rval);
2933     if(FAILED(hres))
2934         return hres;
2935
2936     return return_bool(ret, b);
2937 }
2938
2939 /* ECMA-262 3rd Edition    11.4.8 */
2940 HRESULT binary_negation_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2941 {
2942     unary_expression_t *expr = (unary_expression_t*)_expr;
2943     exprval_t exprval;
2944     VARIANT val;
2945     INT i;
2946     HRESULT hres;
2947
2948     TRACE("\n");
2949
2950     hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval);
2951     if(FAILED(hres))
2952         return hres;
2953
2954     hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
2955     exprval_release(&exprval);
2956     if(FAILED(hres))
2957         return hres;
2958
2959     hres = to_int32(ctx->parser->script, &val, ei, &i);
2960     if(FAILED(hres))
2961         return hres;
2962
2963     ret->type = EXPRVAL_VARIANT;
2964     V_VT(&ret->u.var) = VT_I4;
2965     V_I4(&ret->u.var) = ~i;
2966     return S_OK;
2967 }
2968
2969 /* ECMA-262 3rd Edition    11.4.9 */
2970 HRESULT logical_negation_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2971 {
2972     unary_expression_t *expr = (unary_expression_t*)_expr;
2973     exprval_t exprval;
2974     VARIANT_BOOL b;
2975     HRESULT hres;
2976
2977     TRACE("\n");
2978
2979     hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval);
2980     if(FAILED(hres))
2981         return hres;
2982
2983     hres = exprval_to_boolean(ctx->parser->script, &exprval, ei, &b);
2984     exprval_release(&exprval);
2985     if(FAILED(hres))
2986         return hres;
2987
2988     return return_bool(ret, !b);
2989 }
2990
2991 /* ECMA-262 3rd Edition    11.7.1 */
2992 static HRESULT lshift_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
2993 {
2994     DWORD ri;
2995     INT li;
2996     HRESULT hres;
2997
2998     hres = to_int32(ctx->parser->script, lval, ei, &li);
2999     if(FAILED(hres))
3000         return hres;
3001
3002     hres = to_uint32(ctx->parser->script, rval, ei, &ri);
3003     if(FAILED(hres))
3004         return hres;
3005
3006     V_VT(retv) = VT_I4;
3007     V_I4(retv) = li << (ri&0x1f);
3008     return S_OK;
3009 }
3010
3011 /* ECMA-262 3rd Edition    11.7.1 */
3012 HRESULT left_shift_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3013 {
3014     binary_expression_t *expr = (binary_expression_t*)_expr;
3015
3016     TRACE("\n");
3017
3018     return binary_expr_eval(ctx, expr, lshift_eval, ei, ret);
3019 }
3020
3021 /* ECMA-262 3rd Edition    11.7.2 */
3022 static HRESULT rshift_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
3023 {
3024     DWORD ri;
3025     INT li;
3026     HRESULT hres;
3027
3028     hres = to_int32(ctx->parser->script, lval, ei, &li);
3029     if(FAILED(hres))
3030         return hres;
3031
3032     hres = to_uint32(ctx->parser->script, rval, ei, &ri);
3033     if(FAILED(hres))
3034         return hres;
3035
3036     V_VT(retv) = VT_I4;
3037     V_I4(retv) = li >> (ri&0x1f);
3038     return S_OK;
3039 }
3040
3041 /* ECMA-262 3rd Edition    11.7.2 */
3042 HRESULT right_shift_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3043 {
3044     binary_expression_t *expr = (binary_expression_t*)_expr;
3045
3046     TRACE("\n");
3047
3048     return binary_expr_eval(ctx, expr, rshift_eval, ei, ret);
3049 }
3050
3051 /* ECMA-262 3rd Edition    11.7.3 */
3052 static HRESULT rshift2_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
3053 {
3054     DWORD li, ri;
3055     HRESULT hres;
3056
3057     hres = to_uint32(ctx->parser->script, lval, ei, &li);
3058     if(FAILED(hres))
3059         return hres;
3060
3061     hres = to_uint32(ctx->parser->script, rval, ei, &ri);
3062     if(FAILED(hres))
3063         return hres;
3064
3065     V_VT(retv) = VT_I4;
3066     V_I4(retv) = li >> (ri&0x1f);
3067     return S_OK;
3068 }
3069
3070 /* ECMA-262 3rd Edition    11.7.3 */
3071 HRESULT right2_shift_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3072 {
3073     binary_expression_t *expr = (binary_expression_t*)_expr;
3074
3075     TRACE("\n");
3076
3077     return binary_expr_eval(ctx, expr, rshift2_eval, ei, ret);
3078 }
3079
3080 /* ECMA-262 3rd Edition    11.13.1 */
3081 HRESULT assign_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3082 {
3083     binary_expression_t *expr = (binary_expression_t*)_expr;
3084     exprval_t exprval, exprvalr;
3085     VARIANT rval;
3086     HRESULT hres;
3087
3088     TRACE("\n");
3089
3090     hres = expr_eval(ctx, expr->expression1, EXPR_NEWREF, ei, &exprval);
3091     if(FAILED(hres))
3092         return hres;
3093
3094     hres = expr_eval(ctx, expr->expression2, 0, ei, &exprvalr);
3095     if(SUCCEEDED(hres)) {
3096         hres = exprval_to_value(ctx->parser->script, &exprvalr, ei, &rval);
3097         exprval_release(&exprvalr);
3098     }
3099
3100     if(SUCCEEDED(hres))
3101         hres = put_value(ctx->parser->script, &exprval, &rval, ei);
3102
3103     exprval_release(&exprval);
3104     if(FAILED(hres))
3105         return hres;
3106
3107     ret->type = EXPRVAL_VARIANT;
3108     ret->u.var = rval;
3109     return S_OK;
3110 }
3111
3112 /* ECMA-262 3rd Edition    11.13.2 */
3113 HRESULT assign_lshift_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3114 {
3115     binary_expression_t *expr = (binary_expression_t*)_expr;
3116
3117     TRACE("\n");
3118
3119     return assign_oper_eval(ctx, expr->expression1, expr->expression2, lshift_eval, ei, ret);
3120 }
3121
3122 /* ECMA-262 3rd Edition    11.13.2 */
3123 HRESULT assign_rshift_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3124 {
3125     binary_expression_t *expr = (binary_expression_t*)_expr;
3126
3127     TRACE("\n");
3128
3129     return assign_oper_eval(ctx, expr->expression1, expr->expression2, rshift_eval, ei, ret);
3130 }
3131
3132 /* ECMA-262 3rd Edition    11.13.2 */
3133 HRESULT assign_rrshift_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3134 {
3135     binary_expression_t *expr = (binary_expression_t*)_expr;
3136
3137     TRACE("\n");
3138
3139     return assign_oper_eval(ctx, expr->expression1, expr->expression2, rshift2_eval, ei, ret);
3140 }
3141
3142 /* ECMA-262 3rd Edition    11.13.2 */
3143 HRESULT assign_add_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3144 {
3145     binary_expression_t *expr = (binary_expression_t*)_expr;
3146
3147     TRACE("\n");
3148
3149     return assign_oper_eval(ctx, expr->expression1, expr->expression2, add_eval, ei, ret);
3150 }
3151
3152 /* ECMA-262 3rd Edition    11.13.2 */
3153 HRESULT assign_sub_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3154 {
3155     binary_expression_t *expr = (binary_expression_t*)_expr;
3156
3157     TRACE("\n");
3158
3159     return assign_oper_eval(ctx, expr->expression1, expr->expression2, sub_eval, ei, ret);
3160 }
3161
3162 /* ECMA-262 3rd Edition    11.13.2 */
3163 HRESULT assign_mul_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3164 {
3165     binary_expression_t *expr = (binary_expression_t*)_expr;
3166
3167     TRACE("\n");
3168
3169     return assign_oper_eval(ctx, expr->expression1, expr->expression2, mul_eval, ei, ret);
3170 }
3171
3172 /* ECMA-262 3rd Edition    11.13.2 */
3173 HRESULT assign_div_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3174 {
3175     binary_expression_t *expr = (binary_expression_t*)_expr;
3176
3177     TRACE("\n");
3178
3179     return assign_oper_eval(ctx, expr->expression1, expr->expression2, div_eval, ei, ret);
3180 }
3181
3182 /* ECMA-262 3rd Edition    11.13.2 */
3183 HRESULT assign_mod_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3184 {
3185     binary_expression_t *expr = (binary_expression_t*)_expr;
3186
3187     TRACE("\n");
3188
3189     return assign_oper_eval(ctx, expr->expression1, expr->expression2, mod_eval, ei, ret);
3190 }
3191
3192 /* ECMA-262 3rd Edition    11.13.2 */
3193 HRESULT assign_and_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3194 {
3195     binary_expression_t *expr = (binary_expression_t*)_expr;
3196
3197     TRACE("\n");
3198
3199     return assign_oper_eval(ctx, expr->expression1, expr->expression2, bitand_eval, ei, ret);
3200 }
3201
3202 /* ECMA-262 3rd Edition    11.13.2 */
3203 HRESULT assign_or_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3204 {
3205     binary_expression_t *expr = (binary_expression_t*)_expr;
3206
3207     TRACE("\n");
3208
3209     return assign_oper_eval(ctx, expr->expression1, expr->expression2, bitor_eval, ei, ret);
3210 }
3211
3212 /* ECMA-262 3rd Edition    11.13.2 */
3213 HRESULT assign_xor_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3214 {
3215     binary_expression_t *expr = (binary_expression_t*)_expr;
3216
3217     TRACE("\n");
3218
3219     return assign_oper_eval(ctx, expr->expression1, expr->expression2, xor_eval, ei, ret);
3220 }