jscript: Added switch statement implementation.
[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 "jscript.h"
20 #include "engine.h"
21
22 #include "wine/debug.h"
23
24 WINE_DEFAULT_DEBUG_CHANNEL(jscript);
25
26 #define EXPR_NOVAL   0x0001
27 #define EXPR_NEWREF  0x0002
28 #define EXPR_STRREF  0x0004
29
30 static inline HRESULT stat_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
31 {
32     return stat->eval(ctx, stat, rt, ret);
33 }
34
35 static inline HRESULT expr_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
36 {
37     return _expr->eval(ctx, _expr, flags, ei, ret);
38 }
39
40 static void exprval_release(exprval_t *val)
41 {
42     switch(val->type) {
43     case EXPRVAL_VARIANT:
44         if(V_VT(&val->u.var) != VT_EMPTY)
45             VariantClear(&val->u.var);
46         return;
47     case EXPRVAL_IDREF:
48         if(val->u.idref.disp)
49             IDispatch_Release(val->u.idref.disp);
50         return;
51     case EXPRVAL_NAMEREF:
52         if(val->u.nameref.disp)
53             IDispatch_Release(val->u.nameref.disp);
54         SysFreeString(val->u.nameref.name);
55     }
56 }
57
58 /* ECMA-262 3rd Edition    8.7.1 */
59 static HRESULT exprval_value(script_ctx_t *ctx, exprval_t *val, jsexcept_t *ei, VARIANT *ret)
60 {
61     V_VT(ret) = VT_EMPTY;
62
63     switch(val->type) {
64     case EXPRVAL_VARIANT:
65         return VariantCopy(ret, &val->u.var);
66     case EXPRVAL_IDREF:
67         if(!val->u.idref.disp) {
68             FIXME("throw ReferenceError\n");
69             return E_FAIL;
70         }
71
72         return disp_propget(val->u.idref.disp, val->u.idref.id, ctx->lcid, ret, ei, NULL/*FIXME*/);
73     default:
74         ERR("type %d\n", val->type);
75         return E_FAIL;
76     }
77 }
78
79 static HRESULT exprval_to_value(script_ctx_t *ctx, exprval_t *val, jsexcept_t *ei, VARIANT *ret)
80 {
81     if(val->type == EXPRVAL_VARIANT) {
82         *ret = val->u.var;
83         V_VT(&val->u.var) = VT_EMPTY;
84         return S_OK;
85     }
86
87     return exprval_value(ctx, val, ei, ret);
88 }
89
90 static HRESULT exprval_to_boolean(script_ctx_t *ctx, exprval_t *exprval, jsexcept_t *ei, VARIANT_BOOL *b)
91 {
92     if(exprval->type != EXPRVAL_VARIANT) {
93         VARIANT val;
94         HRESULT hres;
95
96         hres = exprval_to_value(ctx, exprval, ei, &val);
97         if(FAILED(hres))
98             return hres;
99
100         hres = to_boolean(&val, b);
101         VariantClear(&val);
102         return hres;
103     }
104
105     return to_boolean(&exprval->u.var, b);
106 }
107
108 static void exprval_init(exprval_t *val)
109 {
110     val->type = EXPRVAL_VARIANT;
111     V_VT(&val->u.var) = VT_EMPTY;
112 }
113
114 static void exprval_set_idref(exprval_t *val, IDispatch *disp, DISPID id)
115 {
116     val->type = EXPRVAL_IDREF;
117     val->u.idref.disp = disp;
118     val->u.idref.id = id;
119
120     if(disp)
121         IDispatch_AddRef(disp);
122 }
123
124 HRESULT scope_push(scope_chain_t *scope, DispatchEx *obj, scope_chain_t **ret)
125 {
126     scope_chain_t *new_scope;
127
128     new_scope = heap_alloc(sizeof(scope_chain_t));
129     if(!new_scope)
130         return E_OUTOFMEMORY;
131
132     new_scope->ref = 1;
133
134     IDispatchEx_AddRef(_IDispatchEx_(obj));
135     new_scope->obj = obj;
136
137     if(scope) {
138         scope_addref(scope);
139         new_scope->next = scope;
140     }else {
141         new_scope->next = NULL;
142     }
143
144     *ret = new_scope;
145     return S_OK;
146 }
147
148 static void scope_pop(scope_chain_t **scope)
149 {
150     scope_chain_t *tmp;
151
152     tmp = *scope;
153     *scope = tmp->next;
154     scope_release(tmp);
155 }
156
157 void scope_release(scope_chain_t *scope)
158 {
159     if(--scope->ref)
160         return;
161
162     if(scope->next)
163         scope_release(scope->next);
164
165     IDispatchEx_Release(_IDispatchEx_(scope->obj));
166     heap_free(scope);
167 }
168
169 HRESULT create_exec_ctx(IDispatch *this_obj, DispatchEx *var_disp, scope_chain_t *scope, exec_ctx_t **ret)
170 {
171     exec_ctx_t *ctx;
172
173     ctx = heap_alloc_zero(sizeof(exec_ctx_t));
174     if(!ctx)
175         return E_OUTOFMEMORY;
176
177     IDispatch_AddRef(this_obj);
178     ctx->this_obj = this_obj;
179
180     IDispatchEx_AddRef(_IDispatchEx_(var_disp));
181     ctx->var_disp = var_disp;
182
183     if(scope) {
184         scope_addref(scope);
185         ctx->scope_chain = scope;
186     }
187
188     *ret = ctx;
189     return S_OK;
190 }
191
192 void exec_release(exec_ctx_t *ctx)
193 {
194     if(--ctx->ref)
195         return;
196
197     if(ctx->scope_chain)
198         scope_release(ctx->scope_chain);
199     if(ctx->var_disp)
200         IDispatchEx_Release(_IDispatchEx_(ctx->var_disp));
201     if(ctx->this_obj)
202         IDispatch_Release(ctx->this_obj);
203     heap_free(ctx);
204 }
205
206 static HRESULT dispex_get_id(IDispatchEx *dispex, BSTR name, DWORD flags, DISPID *id)
207 {
208     *id = 0;
209
210     return IDispatchEx_GetDispID(dispex, name, flags|fdexNameCaseSensitive, id);
211 }
212
213 static HRESULT disp_get_id(IDispatch *disp, BSTR name, DWORD flags, DISPID *id)
214 {
215     IDispatchEx *dispex;
216     HRESULT hres;
217
218     hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
219     if(FAILED(hres)) {
220         TRACE("unsing IDispatch\n");
221
222         *id = 0;
223         return IDispatch_GetIDsOfNames(disp, &IID_NULL, &name, 1, 0, id);
224     }
225
226     hres = dispex_get_id(dispex, name, flags, id);
227     IDispatchEx_Release(dispex);
228     return hres;
229 }
230
231 /* ECMA-262 3rd Edition    8.7.2 */
232 static HRESULT put_value(script_ctx_t *ctx, exprval_t *ref, VARIANT *v, jsexcept_t *ei)
233 {
234     if(ref->type != EXPRVAL_IDREF) {
235         FIXME("throw ReferemceError\n");
236         return E_FAIL;
237     }
238
239     return disp_propput(ref->u.idref.disp, ref->u.idref.id, ctx->lcid, v, ei, NULL/*FIXME*/);
240 }
241
242 static HRESULT disp_cmp(IDispatch *disp1, IDispatch *disp2, BOOL *ret)
243 {
244     IObjectIdentity *identity;
245     IUnknown *unk1, *unk2;
246     HRESULT hres;
247
248     if(disp1 == disp2) {
249         *ret = TRUE;
250         return S_OK;
251     }
252
253     hres = IDispatch_QueryInterface(disp1, &IID_IUnknown, (void**)&unk1);
254     if(FAILED(hres))
255         return hres;
256
257     hres = IDispatch_QueryInterface(disp2, &IID_IUnknown, (void**)&unk2);
258     if(FAILED(hres)) {
259         IUnknown_Release(unk1);
260         return hres;
261     }
262
263     if(unk1 == unk2) {
264         *ret = TRUE;
265     }else {
266         hres = IUnknown_QueryInterface(unk1, &IID_IObjectIdentity, (void**)&identity);
267         if(SUCCEEDED(hres)) {
268             hres = IObjectIdentity_IsEqualObject(identity, unk2);
269             IObjectIdentity_Release(identity);
270             *ret = hres == S_OK;
271         }else {
272             *ret = FALSE;
273         }
274     }
275
276     IUnknown_Release(unk1);
277     IUnknown_Release(unk2);
278     return S_OK;
279 }
280
281 static inline BOOL is_num_vt(enum VARENUM vt)
282 {
283     return vt == VT_I4 || vt == VT_R8;
284 }
285
286 static inline DOUBLE num_val(const VARIANT *v)
287 {
288     return V_VT(v) == VT_I4 ? V_I4(v) : V_R8(v);
289 }
290
291 static inline void num_set_val(VARIANT *v, DOUBLE d)
292 {
293     if(d == (DOUBLE)(INT)d) {
294         V_VT(v) = VT_I4;
295         V_I4(v) = d;
296     }else {
297         V_VT(v) = VT_R8;
298         V_R8(v) = d;
299     }
300 }
301
302 /* ECMA-262 3rd Edition    11.9.6 */
303 HRESULT equal2_values(VARIANT *lval, VARIANT *rval, BOOL *ret)
304 {
305     TRACE("\n");
306
307     if(V_VT(lval) != V_VT(rval)) {
308         if(is_num_vt(V_VT(lval)) && is_num_vt(V_VT(rval))) {
309             *ret = num_val(lval) == num_val(rval);
310             return S_OK;
311         }
312
313         *ret = FALSE;
314         return S_OK;
315     }
316
317     switch(V_VT(lval)) {
318     case VT_EMPTY:
319     case VT_NULL:
320         *ret = VARIANT_TRUE;
321         break;
322     case VT_I4:
323         *ret = V_I4(lval) == V_I4(rval);
324         break;
325     case VT_R8:
326         *ret = V_R8(lval) == V_R8(rval);
327         break;
328     case VT_BSTR:
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 HRESULT exec_source(exec_ctx_t *ctx, parser_ctx_t *parser, source_elements_t *source, jsexcept_t *ei, VARIANT *retv)
377 {
378     script_ctx_t *script = parser->script;
379     function_declaration_t *func;
380     parser_ctx_t *prev_parser;
381     VARIANT val, tmp;
382     statement_t *stat;
383     exec_ctx_t *prev_ctx;
384     return_type_t rt;
385     HRESULT hres = S_OK;
386
387     for(func = source->functions; func; func = func->next) {
388         DispatchEx *func_obj;
389         VARIANT var;
390
391         hres = create_source_function(parser, func->parameter_list, func->source_elements, ctx->scope_chain, &func_obj);
392         if(FAILED(hres))
393             return hres;
394
395         V_VT(&var) = VT_DISPATCH;
396         V_DISPATCH(&var) = (IDispatch*)_IDispatchEx_(func_obj);
397         hres = jsdisp_propput_name(ctx->var_disp, func->identifier, script->lcid, &var, ei, NULL);
398         IDispatchEx_Release(_IDispatchEx_(func_obj));
399         if(FAILED(hres))
400             return hres;
401     }
402
403     prev_ctx = script->exec_ctx;
404     script->exec_ctx = ctx;
405
406     prev_parser = ctx->parser;
407     ctx->parser = parser;
408
409     V_VT(&val) = VT_EMPTY;
410     memset(&rt, 0, sizeof(rt));
411     rt.type = RT_NORMAL;
412
413     for(stat = source->statement; stat; stat = stat->next) {
414         hres = stat_eval(ctx, stat, &rt, &tmp);
415         if(FAILED(hres))
416             break;
417
418         VariantClear(&val);
419         val = tmp;
420         if(rt.type != RT_NORMAL)
421             break;
422     }
423
424     script->exec_ctx = prev_ctx;
425     ctx->parser = prev_parser;
426
427     if(rt.type != RT_NORMAL && rt.type != RT_RETURN) {
428         FIXME("wrong rt %d\n", rt.type);
429         hres = E_FAIL;
430     }
431
432     *ei = rt.ei;
433     if(FAILED(hres)) {
434         VariantClear(&val);
435         return hres;
436     }
437
438     if(retv)
439         *retv = val;
440     else
441         VariantClear(&val);
442     return S_OK;
443 }
444
445 /* ECMA-262 3rd Edition    10.1.4 */
446 static HRESULT identifier_eval(exec_ctx_t *ctx, BSTR identifier, DWORD flags, exprval_t *ret)
447 {
448     scope_chain_t *scope;
449     named_item_t *item;
450     DISPID id = 0;
451     HRESULT hres;
452
453     TRACE("%s\n", debugstr_w(identifier));
454
455     for(scope = ctx->scope_chain; scope; scope = scope->next) {
456         hres = dispex_get_id(_IDispatchEx_(scope->obj), identifier, 0, &id);
457         if(SUCCEEDED(hres))
458             break;
459     }
460
461     if(scope) {
462         exprval_set_idref(ret, (IDispatch*)_IDispatchEx_(scope->obj), id);
463         return S_OK;
464     }
465
466     hres = dispex_get_id(_IDispatchEx_(ctx->parser->script->global), identifier, 0, &id);
467     if(SUCCEEDED(hres)) {
468         exprval_set_idref(ret, (IDispatch*)_IDispatchEx_(ctx->parser->script->global), id);
469         return S_OK;
470     }
471
472     for(item = ctx->parser->script->named_items; item; item = item->next) {
473         hres = disp_get_id(item->disp, identifier, 0, &id);
474         if(SUCCEEDED(hres))
475             break;
476     }
477
478     if(item) {
479         exprval_set_idref(ret, (IDispatch*)item->disp, id);
480         return S_OK;
481     }
482
483     hres = dispex_get_id(_IDispatchEx_(ctx->parser->script->script_disp), identifier, 0, &id);
484     if(SUCCEEDED(hres)) {
485         exprval_set_idref(ret, (IDispatch*)_IDispatchEx_(ctx->parser->script->script_disp), id);
486         return S_OK;
487     }
488
489     if(flags & EXPR_NEWREF) {
490         hres = dispex_get_id(_IDispatchEx_(ctx->var_disp), identifier, fdexNameEnsure, &id);
491         if(FAILED(hres))
492             return hres;
493
494         exprval_set_idref(ret, (IDispatch*)_IDispatchEx_(ctx->var_disp), id);
495         return S_OK;
496     }
497
498     WARN("Could not find identifier %s\n", debugstr_w(identifier));
499     return E_FAIL;
500 }
501
502 /* ECMA-262 3rd Edition    12.1 */
503 HRESULT block_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
504 {
505     block_statement_t *stat = (block_statement_t*)_stat;
506     VARIANT val, tmp;
507     statement_t *iter;
508     HRESULT hres = S_OK;
509
510     TRACE("\n");
511
512     V_VT(&val) = VT_EMPTY;
513     for(iter = stat->stat_list; iter; iter = iter->next) {
514         hres = stat_eval(ctx, iter, rt, &tmp);
515         if(FAILED(hres))
516             break;
517
518         VariantClear(&val);
519         val = tmp;
520         if(rt->type != RT_NORMAL)
521             break;
522     }
523
524     if(FAILED(hres)) {
525         VariantClear(&val);
526         return hres;
527     }
528
529     *ret = val;
530     return S_OK;
531 }
532
533 /* ECMA-262 3rd Edition    12.2 */
534 static HRESULT variable_list_eval(exec_ctx_t *ctx, variable_declaration_t *var_list, jsexcept_t *ei)
535 {
536     variable_declaration_t *iter;
537     HRESULT hres = E_FAIL;
538
539     for(iter = var_list; iter; iter = iter->next) {
540         VARIANT val;
541
542         if(iter->expr) {
543             exprval_t exprval;
544
545             hres = expr_eval(ctx, iter->expr, 0, ei, &exprval);
546             if(FAILED(hres))
547                 break;
548
549             hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
550             exprval_release(&exprval);
551             if(FAILED(hres))
552                 break;
553         }else {
554             V_VT(&val) = VT_EMPTY;
555         }
556
557         hres = jsdisp_propput_name(ctx->var_disp, iter->identifier, ctx->parser->script->lcid, &val, ei, NULL/*FIXME*/);
558         VariantClear(&val);
559         if(FAILED(hres))
560             break;
561     }
562
563     return hres;
564 }
565
566 /* ECMA-262 3rd Edition    12.2 */
567 HRESULT var_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
568 {
569     var_statement_t *stat = (var_statement_t*)_stat;
570     HRESULT hres;
571
572     TRACE("\n");
573
574     hres = variable_list_eval(ctx, stat->variable_list, &rt->ei);
575     if(FAILED(hres))
576         return hres;
577
578     V_VT(ret) = VT_EMPTY;
579     return S_OK;
580 }
581
582 /* ECMA-262 3rd Edition    12.3 */
583 HRESULT empty_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
584 {
585     TRACE("\n");
586
587     V_VT(ret) = VT_EMPTY;
588     return S_OK;
589 }
590
591 /* ECMA-262 3rd Edition    12.4 */
592 HRESULT expression_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
593 {
594     expression_statement_t *stat = (expression_statement_t*)_stat;
595     exprval_t exprval;
596     VARIANT val;
597     HRESULT hres;
598
599     TRACE("\n");
600
601     hres = expr_eval(ctx, stat->expr, EXPR_NOVAL, &rt->ei, &exprval);
602     if(FAILED(hres))
603         return hres;
604
605     hres = exprval_to_value(ctx->parser->script, &exprval, &rt->ei, &val);
606     exprval_release(&exprval);
607     if(FAILED(hres))
608         return hres;
609
610     *ret = val;
611     TRACE("= %s\n", debugstr_variant(ret));
612     return S_OK;
613 }
614
615 /* ECMA-262 3rd Edition    12.5 */
616 HRESULT if_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
617 {
618     if_statement_t *stat = (if_statement_t*)_stat;
619     exprval_t exprval;
620     VARIANT_BOOL b;
621     HRESULT hres;
622
623     TRACE("\n");
624
625     hres = expr_eval(ctx, stat->expr, 0, &rt->ei, &exprval);
626     if(FAILED(hres))
627         return hres;
628
629     hres = exprval_to_boolean(ctx->parser->script, &exprval, &rt->ei, &b);
630     exprval_release(&exprval);
631     if(FAILED(hres))
632         return hres;
633
634     if(b)
635         hres = stat_eval(ctx, stat->if_stat, rt, ret);
636     else if(stat->else_stat)
637         hres = stat_eval(ctx, stat->else_stat, rt, ret);
638     else
639         V_VT(ret) = VT_EMPTY;
640
641     return hres;
642 }
643
644 HRESULT dowhile_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
645 {
646     FIXME("\n");
647     return E_NOTIMPL;
648 }
649
650 HRESULT while_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
651 {
652     FIXME("\n");
653     return E_NOTIMPL;
654 }
655
656 HRESULT for_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
657 {
658     FIXME("\n");
659     return E_NOTIMPL;
660 }
661
662 HRESULT forin_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
663 {
664     FIXME("\n");
665     return E_NOTIMPL;
666 }
667
668 HRESULT continue_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
669 {
670     FIXME("\n");
671     return E_NOTIMPL;
672 }
673
674 HRESULT break_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
675 {
676     FIXME("\n");
677     return E_NOTIMPL;
678 }
679
680 /* ECMA-262 3rd Edition    12.9 */
681 HRESULT return_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
682 {
683     expression_statement_t *stat = (expression_statement_t*)_stat;
684     HRESULT hres;
685
686     TRACE("\n");
687
688     if(stat->expr) {
689         exprval_t exprval;
690
691         hres = expr_eval(ctx, stat->expr, 0, &rt->ei, &exprval);
692         if(FAILED(hres))
693             return hres;
694
695         hres = exprval_to_value(ctx->parser->script, &exprval, &rt->ei, ret);
696         exprval_release(&exprval);
697         if(FAILED(hres))
698             return hres;
699     }else {
700         V_VT(ret) = VT_EMPTY;
701     }
702
703     TRACE("= %s\n", debugstr_variant(ret));
704     rt->type = RT_RETURN;
705     return S_OK;
706 }
707
708 HRESULT with_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
709 {
710     FIXME("\n");
711     return E_NOTIMPL;
712 }
713
714 HRESULT labelled_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
715 {
716     FIXME("\n");
717     return E_NOTIMPL;
718 }
719
720 /* ECMA-262 3rd Edition    12.13 */
721 HRESULT switch_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
722 {
723     switch_statement_t *stat = (switch_statement_t*)_stat;
724     case_clausule_t *iter, *default_clausule = NULL;
725     statement_t *stat_iter;
726     VARIANT val, cval;
727     exprval_t exprval;
728     BOOL b;
729     HRESULT hres;
730
731     TRACE("\n");
732
733     hres = expr_eval(ctx, stat->expr, 0, &rt->ei, &exprval);
734     if(FAILED(hres))
735         return hres;
736
737     hres = exprval_to_value(ctx->parser->script, &exprval, &rt->ei, &val);
738     exprval_release(&exprval);
739     if(FAILED(hres))
740         return hres;
741
742     for(iter = stat->case_list; iter; iter = iter->next) {
743         if(!iter->expr) {
744             default_clausule = iter;
745             continue;
746         }
747
748         hres = expr_eval(ctx, iter->expr, 0, &rt->ei, &exprval);
749         if(FAILED(hres))
750             break;
751
752         hres = exprval_to_value(ctx->parser->script, &exprval, &rt->ei, &cval);
753         exprval_release(&exprval);
754         if(FAILED(hres))
755             break;
756
757         hres = equal2_values(&val, &cval, &b);
758         VariantClear(&cval);
759         if(FAILED(hres) || b)
760             break;
761     }
762
763     VariantClear(&val);
764     if(FAILED(hres))
765         return hres;
766
767     if(!iter)
768         iter = default_clausule;
769
770     V_VT(&val) = VT_EMPTY;
771     if(iter) {
772         VARIANT tmp;
773
774         for(stat_iter = iter->stat; stat_iter; stat_iter = stat_iter->next) {
775             hres = stat_eval(ctx, stat_iter, rt, &tmp);
776             if(FAILED(hres))
777                 break;
778
779             VariantClear(&val);
780             val = tmp;
781
782             if(rt->type != RT_NORMAL)
783                 break;
784         }
785     }
786
787     if(FAILED(hres)) {
788         VariantClear(&val);
789         return hres;
790     }
791
792     if(rt->type == RT_BREAK)
793         rt->type = RT_NORMAL;
794
795     *ret = val;
796     return S_OK;
797 }
798
799 /* ECMA-262 3rd Edition    12.13 */
800 HRESULT throw_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
801 {
802     expression_statement_t *stat = (expression_statement_t*)_stat;
803     exprval_t exprval;
804     VARIANT val;
805     HRESULT hres;
806
807     TRACE("\n");
808
809     hres = expr_eval(ctx, stat->expr, 0, &rt->ei, &exprval);
810     if(FAILED(hres))
811         return hres;
812
813     hres = exprval_to_value(ctx->parser->script, &exprval, &rt->ei, &val);
814     exprval_release(&exprval);
815     if(FAILED(hres))
816         return hres;
817
818     rt->ei.var = val;
819     return DISP_E_EXCEPTION;
820 }
821
822 /* ECMA-262 3rd Edition    12.14 */
823 static HRESULT catch_eval(exec_ctx_t *ctx, catch_block_t *block, return_type_t *rt, VARIANT *ret)
824 {
825     DispatchEx *var_disp;
826     VARIANT ex, val;
827     HRESULT hres;
828
829     ex = rt->ei.var;
830     memset(&rt->ei, 0, sizeof(jsexcept_t));
831
832     hres = create_dispex(ctx->parser->script, NULL, NULL, &var_disp);
833     if(SUCCEEDED(hres)) {
834         hres = jsdisp_propput_name(var_disp, block->identifier, ctx->parser->script->lcid,
835                 &ex, &rt->ei, NULL/*FIXME*/);
836         if(SUCCEEDED(hres)) {
837             hres = scope_push(ctx->scope_chain, var_disp, &ctx->scope_chain);
838             if(SUCCEEDED(hres)) {
839                 hres = stat_eval(ctx, block->statement, rt, &val);
840                 scope_pop(&ctx->scope_chain);
841             }
842         }
843
844         jsdisp_release(var_disp);
845     }
846
847     VariantClear(&ex);
848     if(FAILED(hres))
849         return hres;
850
851     *ret = val;
852     return S_OK;
853 }
854
855 /* ECMA-262 3rd Edition    12.14 */
856 HRESULT try_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
857 {
858     try_statement_t *stat = (try_statement_t*)_stat;
859     VARIANT val;
860     HRESULT hres;
861
862     TRACE("\n");
863
864     hres = stat_eval(ctx, stat->try_statement, rt, &val);
865     if(FAILED(hres)) {
866         TRACE("EXCEPTION\n");
867         if(!stat->catch_block)
868             return hres;
869
870         hres = catch_eval(ctx, stat->catch_block, rt, &val);
871         if(FAILED(hres))
872             return hres;
873     }
874
875     if(stat->finally_statement) {
876         VariantClear(&val);
877         hres = stat_eval(ctx, stat->finally_statement, rt, &val);
878         if(FAILED(hres))
879             return hres;
880     }
881
882     *ret = val;
883     return S_OK;
884 }
885
886 static HRESULT return_bool(exprval_t *ret, DWORD b)
887 {
888     ret->type = EXPRVAL_VARIANT;
889     V_VT(&ret->u.var) = VT_BOOL;
890     V_BOOL(&ret->u.var) = b ? VARIANT_TRUE : VARIANT_FALSE;
891
892     return S_OK;
893 }
894
895 static HRESULT get_binary_expr_values(exec_ctx_t *ctx, binary_expression_t *expr, jsexcept_t *ei, VARIANT *lval, VARIANT *rval)
896 {
897     exprval_t exprval;
898     HRESULT hres;
899
900     hres = expr_eval(ctx, expr->expression1, 0, ei, &exprval);
901     if(FAILED(hres))
902         return hres;
903
904     hres = exprval_to_value(ctx->parser->script, &exprval, ei, lval);
905     exprval_release(&exprval);
906     if(FAILED(hres))
907         return hres;
908
909     hres = expr_eval(ctx, expr->expression2, 0, ei, &exprval);
910     if(SUCCEEDED(hres)) {
911         hres = exprval_to_value(ctx->parser->script, &exprval, ei, rval);
912         exprval_release(&exprval);
913     }
914
915     if(FAILED(hres)) {
916         VariantClear(lval);
917         return hres;
918     }
919
920     return S_OK;
921 }
922
923 typedef HRESULT (*oper_t)(exec_ctx_t*,VARIANT*,VARIANT*,jsexcept_t*,VARIANT*);
924
925 static HRESULT binary_expr_eval(exec_ctx_t *ctx, binary_expression_t *expr, oper_t oper, jsexcept_t *ei,
926         exprval_t *ret)
927 {
928     VARIANT lval, rval, retv;
929     HRESULT hres;
930
931     hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval);
932     if(FAILED(hres))
933         return hres;
934
935     hres = oper(ctx, &lval, &rval, ei, &retv);
936     VariantClear(&lval);
937     VariantClear(&rval);
938     if(FAILED(hres))
939         return hres;
940
941     ret->type = EXPRVAL_VARIANT;
942     ret->u.var = retv;
943     return S_OK;
944 }
945
946 /* ECMA-262 3rd Edition    11.13.2 */
947 static HRESULT assign_oper_eval(exec_ctx_t *ctx, expression_t *lexpr, expression_t *rexpr, oper_t oper,
948                                 jsexcept_t *ei, exprval_t *ret)
949 {
950     VARIANT retv, lval, rval;
951     exprval_t exprval, exprvalr;
952     HRESULT hres;
953
954     hres = expr_eval(ctx, lexpr, EXPR_NEWREF, ei, &exprval);
955     if(FAILED(hres))
956         return hres;
957
958     hres = exprval_value(ctx->parser->script, &exprval, ei, &lval);
959     if(SUCCEEDED(hres)) {
960         hres = expr_eval(ctx, rexpr, 0, ei, &exprvalr);
961         if(SUCCEEDED(hres)) {
962             hres = exprval_value(ctx->parser->script, &exprvalr, ei, &rval);
963             exprval_release(&exprvalr);
964         }
965         if(SUCCEEDED(hres)) {
966             hres = oper(ctx, &lval, &rval, ei, &retv);
967             VariantClear(&rval);
968         }
969         VariantClear(&lval);
970     }
971
972     if(SUCCEEDED(hres)) {
973         hres = put_value(ctx->parser->script, &exprval, &retv, ei);
974         if(FAILED(hres))
975             VariantClear(&retv);
976     }
977     exprval_release(&exprval);
978
979     if(FAILED(hres))
980         return hres;
981
982     ret->type = EXPRVAL_VARIANT;
983     ret->u.var = retv;
984     return S_OK;
985 }
986
987 /* ECMA-262 3rd Edition    13 */
988 HRESULT function_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
989 {
990     function_expression_t *expr = (function_expression_t*)_expr;
991     DispatchEx *dispex;
992     VARIANT var;
993     HRESULT hres;
994
995     TRACE("\n");
996
997     hres = create_source_function(ctx->parser, expr->parameter_list, expr->source_elements, ctx->scope_chain, &dispex);
998     if(FAILED(hres))
999         return hres;
1000
1001     V_VT(&var) = VT_DISPATCH;
1002     V_DISPATCH(&var) = (IDispatch*)_IDispatchEx_(dispex);
1003
1004     if(expr->identifier) {
1005         hres = jsdisp_propput_name(ctx->var_disp, expr->identifier, ctx->parser->script->lcid, &var, ei, NULL/*FIXME*/);
1006         if(FAILED(hres)) {
1007             jsdisp_release(dispex);
1008             return hres;
1009         }
1010     }
1011
1012     ret->type = EXPRVAL_VARIANT;
1013     ret->u.var = var;
1014     return S_OK;
1015 }
1016
1017 /* ECMA-262 3rd Edition    11.12 */
1018 HRESULT conditional_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1019 {
1020     conditional_expression_t *expr = (conditional_expression_t*)_expr;
1021     exprval_t exprval;
1022     VARIANT_BOOL b;
1023     HRESULT hres;
1024
1025     TRACE("\n");
1026
1027     hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
1028     if(FAILED(hres))
1029         return hres;
1030
1031     hres = exprval_to_boolean(ctx->parser->script, &exprval, ei, &b);
1032     exprval_release(&exprval);
1033     if(FAILED(hres))
1034         return hres;
1035
1036     return expr_eval(ctx, b ? expr->true_expression : expr->false_expression, flags, ei, ret);
1037 }
1038
1039 /* ECMA-262 3rd Edition    11.2.1 */
1040 HRESULT array_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1041 {
1042     array_expression_t *expr = (array_expression_t*)_expr;
1043     exprval_t exprval;
1044     VARIANT member, val;
1045     DISPID id;
1046     BSTR str;
1047     IDispatch *obj = NULL;
1048     HRESULT hres;
1049
1050     TRACE("\n");
1051
1052     hres = expr_eval(ctx, expr->member_expr, EXPR_NEWREF, ei, &exprval);
1053     if(FAILED(hres))
1054         return hres;
1055
1056     hres = exprval_to_value(ctx->parser->script, &exprval, ei, &member);
1057     exprval_release(&exprval);
1058     if(FAILED(hres))
1059         return hres;
1060
1061     hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval);
1062     if(SUCCEEDED(hres)) {
1063         hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
1064         exprval_release(&exprval);
1065     }
1066
1067     if(SUCCEEDED(hres))
1068         hres = to_object(ctx, &member, &obj);
1069     VariantClear(&member);
1070     if(SUCCEEDED(hres)) {
1071         hres = to_string(ctx->parser->script, &val, ei, &str);
1072         if(SUCCEEDED(hres)) {
1073             if(flags & EXPR_STRREF) {
1074                 ret->type = EXPRVAL_NAMEREF;
1075                 ret->u.nameref.disp = obj;
1076                 ret->u.nameref.name = str;
1077                 return S_OK;
1078             }
1079
1080             hres = disp_get_id(obj, str, flags & EXPR_NEWREF ? fdexNameEnsure : 0, &id);
1081         }
1082
1083         if(SUCCEEDED(hres)) {
1084             exprval_set_idref(ret, obj, id);
1085         }else if(!(flags & EXPR_NEWREF) && hres == DISP_E_UNKNOWNNAME) {
1086             exprval_init(ret);
1087             hres = S_OK;
1088         }
1089
1090         IDispatch_Release(obj);
1091     }
1092
1093     return hres;
1094 }
1095
1096 /* ECMA-262 3rd Edition    11.2.1 */
1097 HRESULT member_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1098 {
1099     member_expression_t *expr = (member_expression_t*)_expr;
1100     IDispatch *obj = NULL;
1101     exprval_t exprval;
1102     VARIANT member;
1103     DISPID id;
1104     BSTR str;
1105     HRESULT hres;
1106
1107     TRACE("\n");
1108
1109     hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
1110     if(FAILED(hres))
1111         return hres;
1112
1113     hres = exprval_to_value(ctx->parser->script, &exprval, ei, &member);
1114     exprval_release(&exprval);
1115     if(FAILED(hres))
1116         return hres;
1117
1118     hres = to_object(ctx, &member, &obj);
1119     VariantClear(&member);
1120     if(FAILED(hres))
1121         return hres;
1122
1123     str = SysAllocString(expr->identifier);
1124     if(flags & EXPR_STRREF) {
1125         ret->type = EXPRVAL_NAMEREF;
1126         ret->u.nameref.disp = obj;
1127         ret->u.nameref.name = str;
1128         return S_OK;
1129     }
1130
1131     hres = disp_get_id(obj, str, flags & EXPR_NEWREF ? fdexNameEnsure : 0, &id);
1132     SysFreeString(str);
1133     if(SUCCEEDED(hres)) {
1134         exprval_set_idref(ret, obj, id);
1135     }else if(!(flags & EXPR_NEWREF) && hres == DISP_E_UNKNOWNNAME) {
1136         exprval_init(ret);
1137         hres = S_OK;
1138     }
1139
1140     IDispatch_Release(obj);
1141     return hres;
1142 }
1143
1144 static void free_dp(DISPPARAMS *dp)
1145 {
1146     DWORD i;
1147
1148     for(i=0; i < dp->cArgs; i++)
1149         VariantClear(dp->rgvarg+i);
1150     heap_free(dp->rgvarg);
1151 }
1152
1153 static HRESULT args_to_param(exec_ctx_t *ctx, argument_t *args, jsexcept_t *ei, DISPPARAMS *dp)
1154 {
1155     VARIANTARG *vargs;
1156     exprval_t exprval;
1157     argument_t *iter;
1158     DWORD cnt = 0, i;
1159     HRESULT hres = S_OK;
1160
1161     memset(dp, 0, sizeof(*dp));
1162     if(!args)
1163         return S_OK;
1164
1165     for(iter = args; iter; iter = iter->next)
1166         cnt++;
1167
1168     vargs = heap_alloc_zero(cnt * sizeof(*vargs));
1169     if(!vargs)
1170         return E_OUTOFMEMORY;
1171
1172     for(i = cnt, iter = args; iter; iter = iter->next) {
1173         hres = expr_eval(ctx, iter->expr, 0, ei, &exprval);
1174         if(FAILED(hres))
1175             break;
1176
1177         hres = exprval_to_value(ctx->parser->script, &exprval, ei, vargs + (--i));
1178         exprval_release(&exprval);
1179         if(FAILED(hres))
1180             break;
1181     }
1182
1183     if(FAILED(hres)) {
1184         free_dp(dp);
1185         return hres;
1186     }
1187
1188     dp->rgvarg = vargs;
1189     dp->cArgs = cnt;
1190     return S_OK;
1191 }
1192
1193 /* ECMA-262 3rd Edition    11.2.2 */
1194 HRESULT new_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1195 {
1196     call_expression_t *expr = (call_expression_t*)_expr;
1197     exprval_t exprval;
1198     VARIANT constr, var;
1199     DISPPARAMS dp;
1200     HRESULT hres;
1201
1202     TRACE("\n");
1203
1204     hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
1205     if(FAILED(hres))
1206         return hres;
1207
1208     hres = args_to_param(ctx, expr->argument_list, ei, &dp);
1209     if(SUCCEEDED(hres))
1210         hres = exprval_to_value(ctx->parser->script, &exprval, ei, &constr);
1211     exprval_release(&exprval);
1212     if(FAILED(hres))
1213         return hres;
1214
1215     if(V_VT(&constr) != VT_DISPATCH) {
1216         FIXME("throw TypeError\n");
1217         VariantClear(&constr);
1218         return E_FAIL;
1219     }
1220
1221     hres = disp_call(V_DISPATCH(&constr), DISPID_VALUE, ctx->parser->script->lcid,
1222                      DISPATCH_CONSTRUCT, &dp, &var, ei, NULL/*FIXME*/);
1223     IDispatch_Release(V_DISPATCH(&constr));
1224     if(FAILED(hres))
1225         return hres;
1226
1227     ret->type = EXPRVAL_VARIANT;
1228     ret->u.var = var;
1229     return S_OK;
1230 }
1231
1232 HRESULT call_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1233 {
1234     call_expression_t *expr = (call_expression_t*)_expr;
1235     VARIANT func, var;
1236     exprval_t exprval;
1237     DISPPARAMS dp;
1238     HRESULT hres;
1239
1240     TRACE("\n");
1241
1242     hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
1243     if(FAILED(hres))
1244         return hres;
1245
1246     hres = args_to_param(ctx, expr->argument_list, ei, &dp);
1247     if(SUCCEEDED(hres)) {
1248         switch(exprval.type) {
1249         case EXPRVAL_IDREF:
1250             hres = disp_call(exprval.u.idref.disp, exprval.u.idref.id, ctx->parser->script->lcid, DISPATCH_METHOD,
1251                     &dp, flags & EXPR_NOVAL ? NULL : &var, ei, NULL/*FIXME*/);
1252             if(flags & EXPR_NOVAL)
1253                 V_VT(&var) = VT_EMPTY;
1254             break;
1255         default:
1256             FIXME("unimplemented type %d\n", V_VT(&func));
1257             hres = E_NOTIMPL;
1258         }
1259
1260         free_dp(&dp);
1261     }
1262
1263     exprval_release(&exprval);
1264     if(FAILED(hres))
1265         return hres;
1266
1267     TRACE("= %s\n", debugstr_variant(&var));
1268     ret->type = EXPRVAL_VARIANT;
1269     ret->u.var = var;
1270     return S_OK;
1271 }
1272
1273 HRESULT this_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1274 {
1275     TRACE("\n");
1276
1277     ret->type = EXPRVAL_VARIANT;
1278     V_VT(&ret->u.var) = VT_DISPATCH;
1279     V_DISPATCH(&ret->u.var) = ctx->this_obj;
1280     IDispatch_AddRef(ctx->this_obj);
1281     return S_OK;
1282 }
1283
1284 /* ECMA-262 3rd Edition    10.1.4 */
1285 HRESULT identifier_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1286 {
1287     identifier_expression_t *expr = (identifier_expression_t*)_expr;
1288     BSTR identifier;
1289     HRESULT hres;
1290
1291     TRACE("\n");
1292
1293     identifier = SysAllocString(expr->identifier);
1294     if(!identifier)
1295         return E_OUTOFMEMORY;
1296
1297     hres = identifier_eval(ctx, identifier, flags, ret);
1298
1299     SysFreeString(identifier);
1300     return hres;
1301 }
1302
1303 /* ECMA-262 3rd Edition    7.8 */
1304 HRESULT literal_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1305 {
1306     literal_expression_t *expr = (literal_expression_t*)_expr;
1307     VARIANT var;
1308     HRESULT hres;
1309
1310     TRACE("\n");
1311
1312     hres = literal_to_var(expr->literal, &var);
1313     if(FAILED(hres))
1314         return hres;
1315
1316     ret->type = EXPRVAL_VARIANT;
1317     ret->u.var = var;
1318     return S_OK;
1319 }
1320
1321 HRESULT array_literal_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1322 {
1323     FIXME("\n");
1324     return E_NOTIMPL;
1325 }
1326
1327 /* ECMA-262 3rd Edition    11.1.5 */
1328 HRESULT property_value_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1329 {
1330     property_value_expression_t *expr = (property_value_expression_t*)_expr;
1331     VARIANT val, tmp;
1332     DispatchEx *obj;
1333     prop_val_t *iter;
1334     exprval_t exprval;
1335     BSTR name;
1336     HRESULT hres;
1337
1338     TRACE("\n");
1339
1340     hres = create_object(ctx->parser->script, NULL, &obj);
1341     if(FAILED(hres))
1342         return hres;
1343
1344     for(iter = expr->property_list; iter; iter = iter->next) {
1345         hres = literal_to_var(iter->name, &tmp);
1346         if(FAILED(hres))
1347             break;
1348
1349         hres = to_string(ctx->parser->script, &tmp, ei, &name);
1350         VariantClear(&tmp);
1351         if(FAILED(hres))
1352             break;
1353
1354         hres = expr_eval(ctx, iter->value, 0, ei, &exprval);
1355         if(SUCCEEDED(hres)) {
1356             hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
1357             exprval_release(&exprval);
1358             if(SUCCEEDED(hres)) {
1359                 hres = jsdisp_propput_name(obj, name, ctx->parser->script->lcid, &val, ei, NULL/*FIXME*/);
1360                 VariantClear(&val);
1361             }
1362         }
1363
1364         SysFreeString(name);
1365         if(FAILED(hres))
1366             break;
1367     }
1368
1369     if(FAILED(hres)) {
1370         jsdisp_release(obj);
1371         return hres;
1372     }
1373
1374     ret->type = EXPRVAL_VARIANT;
1375     V_VT(&ret->u.var) = VT_DISPATCH;
1376     V_DISPATCH(&ret->u.var) = (IDispatch*)_IDispatchEx_(obj);
1377     return S_OK;
1378 }
1379
1380 HRESULT comma_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1381 {
1382     FIXME("\n");
1383     return E_NOTIMPL;
1384 }
1385
1386 /* ECMA-262 3rd Edition    11.11 */
1387 HRESULT logical_or_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1388 {
1389     binary_expression_t *expr = (binary_expression_t*)_expr;
1390     exprval_t exprval;
1391     VARIANT_BOOL b;
1392     VARIANT val;
1393     HRESULT hres;
1394
1395     TRACE("\n");
1396
1397     hres = expr_eval(ctx, expr->expression1, 0, ei, &exprval);
1398     if(FAILED(hres))
1399         return hres;
1400
1401     hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
1402     exprval_release(&exprval);
1403     if(FAILED(hres))
1404         return hres;
1405
1406     hres = to_boolean(&val, &b);
1407     if(SUCCEEDED(hres) && b) {
1408         ret->type = EXPRVAL_VARIANT;
1409         ret->u.var = val;
1410         return S_OK;
1411     }
1412
1413     VariantClear(&val);
1414     if(FAILED(hres))
1415         return hres;
1416
1417     hres = expr_eval(ctx, expr->expression2, 0, ei, &exprval);
1418     if(FAILED(hres))
1419         return hres;
1420
1421     hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
1422     exprval_release(&exprval);
1423     if(FAILED(hres))
1424         return hres;
1425
1426     ret->type = EXPRVAL_VARIANT;
1427     ret->u.var = val;
1428     return S_OK;
1429 }
1430
1431 /* ECMA-262 3rd Edition    11.11 */
1432 HRESULT logical_and_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1433 {
1434     binary_expression_t *expr = (binary_expression_t*)_expr;
1435     exprval_t exprval;
1436     VARIANT_BOOL b;
1437     VARIANT val;
1438     HRESULT hres;
1439
1440     TRACE("\n");
1441
1442     hres = expr_eval(ctx, expr->expression1, 0, ei, &exprval);
1443     if(FAILED(hres))
1444         return hres;
1445
1446     hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
1447     exprval_release(&exprval);
1448     if(FAILED(hres))
1449         return hres;
1450
1451     hres = to_boolean(&val, &b);
1452     if(SUCCEEDED(hres) && !b) {
1453         ret->type = EXPRVAL_VARIANT;
1454         ret->u.var = val;
1455         return S_OK;
1456     }
1457
1458     VariantClear(&val);
1459     if(FAILED(hres))
1460         return hres;
1461
1462     hres = expr_eval(ctx, expr->expression2, 0, ei, &exprval);
1463     if(FAILED(hres))
1464         return hres;
1465
1466     hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
1467     exprval_release(&exprval);
1468     if(FAILED(hres))
1469         return hres;
1470
1471     ret->type = EXPRVAL_VARIANT;
1472     ret->u.var = val;
1473     return S_OK;
1474 }
1475
1476 HRESULT binary_or_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1477 {
1478     FIXME("\n");
1479     return E_NOTIMPL;
1480 }
1481
1482 HRESULT binary_xor_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1483 {
1484     FIXME("\n");
1485     return E_NOTIMPL;
1486 }
1487
1488 HRESULT binary_and_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1489 {
1490     FIXME("\n");
1491     return E_NOTIMPL;
1492 }
1493
1494 HRESULT instanceof_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1495 {
1496     FIXME("\n");
1497     return E_NOTIMPL;
1498 }
1499
1500 HRESULT in_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1501 {
1502     FIXME("\n");
1503     return E_NOTIMPL;
1504 }
1505
1506 /* ECMA-262 3rd Edition    11.6.1 */
1507 static HRESULT add_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
1508 {
1509     VARIANT r, l;
1510     HRESULT hres;
1511
1512     hres = to_primitive(ctx->parser->script, lval, ei, &l);
1513     if(FAILED(hres))
1514         return hres;
1515
1516     hres = to_primitive(ctx->parser->script, rval, ei, &r);
1517     if(FAILED(hres)) {
1518         VariantClear(&l);
1519         return hres;
1520     }
1521
1522     if(V_VT(&l) == VT_BSTR || V_VT(&r) == VT_BSTR) {
1523         BSTR lstr = NULL, rstr = NULL;
1524
1525         if(V_VT(&l) == VT_BSTR)
1526             lstr = V_BSTR(&l);
1527         else
1528             hres = to_string(ctx->parser->script, &l, ei, &lstr);
1529
1530         if(SUCCEEDED(hres)) {
1531             if(V_VT(&r) == VT_BSTR)
1532                 rstr = V_BSTR(&r);
1533             else
1534                 hres = to_string(ctx->parser->script, &r, ei, &rstr);
1535         }
1536
1537         if(SUCCEEDED(hres)) {
1538             int len1, len2;
1539
1540             len1 = SysStringLen(lstr);
1541             len2 = SysStringLen(rstr);
1542
1543             V_VT(retv) = VT_BSTR;
1544             V_BSTR(retv) = SysAllocStringLen(NULL, len1+len2);
1545             memcpy(V_BSTR(retv), lstr, len1*sizeof(WCHAR));
1546             memcpy(V_BSTR(retv)+len1, rstr, (len2+1)*sizeof(WCHAR));
1547         }
1548
1549         if(lstr && V_VT(&l) != VT_BSTR)
1550             SysFreeString(lstr);
1551         if(rstr && V_VT(&r) != VT_BSTR)
1552             SysFreeString(rstr);
1553     }else {
1554         VARIANT nl, nr;
1555
1556         hres = to_number(ctx->parser->script, &l, ei, &nl);
1557         if(SUCCEEDED(hres)) {
1558             hres = to_number(ctx->parser->script, &r, ei, &nr);
1559             if(SUCCEEDED(hres))
1560                 num_set_val(retv, num_val(&nl) + num_val(&nr));
1561         }
1562     }
1563
1564     VariantClear(&r);
1565     VariantClear(&l);
1566     return hres;
1567 }
1568
1569 /* ECMA-262 3rd Edition    11.6.1 */
1570 HRESULT add_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1571 {
1572     binary_expression_t *expr = (binary_expression_t*)_expr;
1573
1574     TRACE("\n");
1575
1576     return binary_expr_eval(ctx, expr, add_eval, ei, ret);
1577 }
1578
1579 /* ECMA-262 3rd Edition    11.6.2 */
1580 static HRESULT sub_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
1581 {
1582     VARIANT lnum, rnum;
1583     HRESULT hres;
1584
1585     hres = to_number(ctx->parser->script, lval, ei, &lnum);
1586     if(FAILED(hres))
1587         return hres;
1588
1589     hres = to_number(ctx->parser->script, rval, ei, &rnum);
1590     if(FAILED(hres))
1591         return hres;
1592
1593     num_set_val(retv, num_val(&lnum) - num_val(&rnum));
1594     return S_OK;
1595 }
1596
1597 /* ECMA-262 3rd Edition    11.6.2 */
1598 HRESULT sub_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1599 {
1600     binary_expression_t *expr = (binary_expression_t*)_expr;
1601
1602     TRACE("\n");
1603
1604     return binary_expr_eval(ctx, expr, sub_eval, ei, ret);
1605 }
1606
1607 /* ECMA-262 3rd Edition    11.5.1 */
1608 static HRESULT mul_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
1609 {
1610     VARIANT lnum, rnum;
1611     HRESULT hres;
1612
1613     hres = to_number(ctx->parser->script, lval, ei, &lnum);
1614     if(FAILED(hres))
1615         return hres;
1616
1617     hres = to_number(ctx->parser->script, rval, ei, &rnum);
1618     if(FAILED(hres))
1619         return hres;
1620
1621     num_set_val(retv, num_val(&lnum) * num_val(&rnum));
1622     return S_OK;
1623 }
1624
1625 /* ECMA-262 3rd Edition    11.5.1 */
1626 HRESULT mul_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1627 {
1628     binary_expression_t *expr = (binary_expression_t*)_expr;
1629
1630     TRACE("\n");
1631
1632     return binary_expr_eval(ctx, expr, mul_eval, ei, ret);
1633 }
1634
1635 /* ECMA-262 3rd Edition    11.5.2 */
1636 static HRESULT div_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
1637 {
1638     VARIANT lnum, rnum;
1639     HRESULT hres;
1640
1641     hres = to_number(ctx->parser->script, lval, ei, &lnum);
1642     if(FAILED(hres))
1643         return hres;
1644
1645     hres = to_number(ctx->parser->script, rval, ei, &rnum);
1646     if(FAILED(hres))
1647         return hres;
1648
1649     num_set_val(retv, num_val(&lnum) / num_val(&rnum));
1650     return S_OK;
1651 }
1652
1653 /* ECMA-262 3rd Edition    11.5.2 */
1654 HRESULT div_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1655 {
1656     binary_expression_t *expr = (binary_expression_t*)_expr;
1657
1658     TRACE("\n");
1659
1660     return binary_expr_eval(ctx, expr, div_eval, ei, ret);
1661 }
1662
1663 HRESULT mod_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1664 {
1665     FIXME("\n");
1666     return E_NOTIMPL;
1667 }
1668
1669 HRESULT delete_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1670 {
1671     FIXME("\n");
1672     return E_NOTIMPL;
1673 }
1674
1675 HRESULT void_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1676 {
1677     FIXME("\n");
1678     return E_NOTIMPL;
1679 }
1680
1681 HRESULT typeof_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1682 {
1683     unary_expression_t *expr = (unary_expression_t*)_expr;
1684     const WCHAR *str;
1685     exprval_t exprval;
1686     VARIANT val;
1687     HRESULT hres;
1688
1689     static const WCHAR booleanW[] = {'b','o','o','l','e','a','n',0};
1690     static const WCHAR functionW[] = {'f','u','n','c','t','i','o','n',0};
1691     static const WCHAR numberW[] = {'n','u','m','b','e','r',0};
1692     static const WCHAR objectW[] = {'o','b','j','e','c','t',0};
1693     static const WCHAR stringW[] = {'s','t','r','i','n','g',0};
1694     static const WCHAR undefinedW[] = {'u','n','d','e','f','i','n','e','d',0};
1695
1696     TRACE("\n");
1697
1698     hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
1699     if(FAILED(hres))
1700         return hres;
1701
1702     hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
1703     exprval_release(&exprval);
1704     if(FAILED(hres))
1705         return hres;
1706
1707     switch(V_VT(&val)) {
1708     case VT_EMPTY:
1709         str = undefinedW;
1710         break;
1711     case VT_NULL:
1712         str = objectW;
1713         break;
1714     case VT_BOOL:
1715         str = booleanW;
1716         break;
1717     case VT_I4:
1718     case VT_R8:
1719         str = numberW;
1720         break;
1721     case VT_BSTR:
1722         str = stringW;
1723         break;
1724     case VT_DISPATCH: {
1725         DispatchEx *dispex;
1726
1727         dispex = iface_to_jsdisp((IUnknown*)V_DISPATCH(&val));
1728         if(dispex) {
1729             str = dispex->builtin_info->class == JSCLASS_FUNCTION ? functionW : objectW;
1730             IDispatchEx_Release(_IDispatchEx_(dispex));
1731         }else {
1732             str = objectW;
1733         }
1734         break;
1735     }
1736     default:
1737         FIXME("unhandled vt %d\n", V_VT(&val));
1738         hres = E_NOTIMPL;
1739     }
1740
1741     VariantClear(&val);
1742     if(FAILED(hres))
1743         return hres;
1744
1745     ret->type = EXPRVAL_VARIANT;
1746     V_VT(&ret->u.var) = VT_BSTR;
1747     V_BSTR(&ret->u.var) = SysAllocString(str);
1748     return S_OK;
1749 }
1750
1751 /* ECMA-262 3rd Edition    11.4.7 */
1752 HRESULT minus_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1753 {
1754     unary_expression_t *expr = (unary_expression_t*)_expr;
1755     exprval_t exprval;
1756     VARIANT val, num;
1757     HRESULT hres;
1758
1759     TRACE("\n");
1760
1761     hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
1762     if(FAILED(hres))
1763         return hres;
1764
1765     hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
1766     exprval_release(&exprval);
1767     if(FAILED(hres))
1768         return hres;
1769
1770     hres = to_number(ctx->parser->script, &val, ei, &num);
1771     VariantClear(&val);
1772     if(FAILED(hres))
1773         return hres;
1774
1775     ret->type = EXPRVAL_VARIANT;
1776     num_set_val(&ret->u.var, -num_val(&num));
1777     return S_OK;
1778 }
1779
1780 HRESULT plus_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1781 {
1782     FIXME("\n");
1783     return E_NOTIMPL;
1784 }
1785
1786 /* ECMA-262 3rd Edition    11.3.1 */
1787 HRESULT post_increment_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1788 {
1789     unary_expression_t *expr = (unary_expression_t*)_expr;
1790     VARIANT val, num;
1791     exprval_t exprval;
1792     HRESULT hres;
1793
1794     TRACE("\n");
1795
1796     hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval);
1797     if(FAILED(hres))
1798         return hres;
1799
1800     hres = exprval_value(ctx->parser->script, &exprval, ei, &val);
1801     if(SUCCEEDED(hres)) {
1802         hres = to_number(ctx->parser->script, &val, ei, &num);
1803         VariantClear(&val);
1804     }
1805
1806     if(SUCCEEDED(hres)) {
1807         VARIANT inc;
1808         num_set_val(&inc, num_val(&num)+1.0);
1809         hres = put_value(ctx->parser->script, &exprval, &inc, ei);
1810     }
1811
1812     exprval_release(&exprval);
1813     if(FAILED(hres))
1814         return hres;
1815
1816     ret->type = EXPRVAL_VARIANT;
1817     ret->u.var = num;
1818     return S_OK;
1819 }
1820
1821 /* ECMA-262 3rd Edition    11.3.2 */
1822 HRESULT post_decrement_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1823 {
1824     unary_expression_t *expr = (unary_expression_t*)_expr;
1825     VARIANT val, num;
1826     exprval_t exprval;
1827     HRESULT hres;
1828
1829     TRACE("\n");
1830
1831     hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval);
1832     if(FAILED(hres))
1833         return hres;
1834
1835     hres = exprval_value(ctx->parser->script, &exprval, ei, &val);
1836     if(SUCCEEDED(hres)) {
1837         hres = to_number(ctx->parser->script, &val, ei, &num);
1838         VariantClear(&val);
1839     }
1840
1841     if(SUCCEEDED(hres)) {
1842         VARIANT dec;
1843         num_set_val(&dec, num_val(&num)-1.0);
1844         hres = put_value(ctx->parser->script, &exprval, &dec, ei);
1845     }
1846
1847     exprval_release(&exprval);
1848     if(FAILED(hres))
1849         return hres;
1850
1851     ret->type = EXPRVAL_VARIANT;
1852     ret->u.var = num;
1853     return S_OK;
1854 }
1855
1856 /* ECMA-262 3rd Edition    11.4.4 */
1857 HRESULT pre_increment_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1858 {
1859     unary_expression_t *expr = (unary_expression_t*)_expr;
1860     VARIANT val, num;
1861     exprval_t exprval;
1862     HRESULT hres;
1863
1864     TRACE("\n");
1865
1866     hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval);
1867     if(FAILED(hres))
1868         return hres;
1869
1870     hres = exprval_value(ctx->parser->script, &exprval, ei, &val);
1871     if(SUCCEEDED(hres)) {
1872         hres = to_number(ctx->parser->script, &val, ei, &num);
1873         VariantClear(&val);
1874     }
1875
1876     if(SUCCEEDED(hres)) {
1877         num_set_val(&val, num_val(&num)+1.0);
1878         hres = put_value(ctx->parser->script, &exprval, &val, ei);
1879     }
1880
1881     exprval_release(&exprval);
1882     if(FAILED(hres))
1883         return hres;
1884
1885     ret->type = EXPRVAL_VARIANT;
1886     ret->u.var = val;
1887     return S_OK;
1888 }
1889
1890 /* ECMA-262 3rd Edition    11.4.5 */
1891 HRESULT pre_decrement_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1892 {
1893     unary_expression_t *expr = (unary_expression_t*)_expr;
1894     VARIANT val, num;
1895     exprval_t exprval;
1896     HRESULT hres;
1897
1898     TRACE("\n");
1899
1900     hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval);
1901     if(FAILED(hres))
1902         return hres;
1903
1904     hres = exprval_value(ctx->parser->script, &exprval, ei, &val);
1905     if(SUCCEEDED(hres)) {
1906         hres = to_number(ctx->parser->script, &val, ei, &num);
1907         VariantClear(&val);
1908     }
1909
1910     if(SUCCEEDED(hres)) {
1911         num_set_val(&val, num_val(&num)-1.0);
1912         hres = put_value(ctx->parser->script, &exprval, &val, ei);
1913     }
1914
1915     exprval_release(&exprval);
1916     if(FAILED(hres))
1917         return hres;
1918
1919     ret->type = EXPRVAL_VARIANT;
1920     ret->u.var = val;
1921     return S_OK;
1922 }
1923
1924 /* ECMA-262 3rd Edition    11.9.3 */
1925 static HRESULT equal_values(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, BOOL *ret)
1926 {
1927     if(V_VT(lval) == V_VT(rval) || (is_num_vt(V_VT(lval)) && is_num_vt(V_VT(rval))))
1928        return equal2_values(lval, rval, ret);
1929
1930     /* FIXME: NULL disps should be handled in more general way */
1931     if(V_VT(lval) == VT_DISPATCH && !V_DISPATCH(lval)) {
1932         VARIANT v;
1933         V_VT(&v) = VT_NULL;
1934         return equal_values(ctx, &v, rval, ei, ret);
1935     }
1936
1937     if(V_VT(rval) == VT_DISPATCH && !V_DISPATCH(rval)) {
1938         VARIANT v;
1939         V_VT(&v) = VT_NULL;
1940         return equal_values(ctx, lval, &v, ei, ret);
1941     }
1942
1943     if((V_VT(lval) == VT_NULL && V_VT(rval) == VT_EMPTY) ||
1944        (V_VT(lval) == VT_EMPTY && V_VT(rval) == VT_NULL)) {
1945         *ret = TRUE;
1946         return S_OK;
1947     }
1948
1949     if(V_VT(lval) == VT_BSTR && is_num_vt(V_VT(rval))) {
1950         VARIANT v;
1951         HRESULT hres;
1952
1953         hres = to_number(ctx->parser->script, lval, ei, &v);
1954         if(FAILED(hres))
1955             return hres;
1956
1957         return equal_values(ctx, &v, rval, ei, ret);
1958     }
1959
1960     if(V_VT(rval) == VT_BSTR && is_num_vt(V_VT(lval))) {
1961         VARIANT v;
1962         HRESULT hres;
1963
1964         hres = to_number(ctx->parser->script, rval, ei, &v);
1965         if(FAILED(hres))
1966             return hres;
1967
1968         return equal_values(ctx, lval, &v, ei, ret);
1969     }
1970
1971     if(V_VT(rval) == VT_BOOL) {
1972         VARIANT v;
1973
1974         V_VT(&v) = VT_I4;
1975         V_I4(&v) = V_BOOL(rval) ? 1 : 0;
1976         return equal_values(ctx, lval, &v, ei, ret);
1977     }
1978
1979     if(V_VT(lval) == VT_BOOL) {
1980         VARIANT v;
1981
1982         V_VT(&v) = VT_I4;
1983         V_I4(&v) = V_BOOL(lval) ? 1 : 0;
1984         return equal_values(ctx, &v, rval, ei, ret);
1985     }
1986
1987
1988     if(V_VT(rval) == VT_DISPATCH && (V_VT(lval) == VT_BSTR || is_num_vt(V_VT(lval)))) {
1989         VARIANT v;
1990         HRESULT hres;
1991
1992         hres = to_primitive(ctx->parser->script, rval, ei, &v);
1993         if(FAILED(hres))
1994             return hres;
1995
1996         hres = equal_values(ctx, lval, &v, ei, ret);
1997
1998         VariantClear(&v);
1999         return hres;
2000     }
2001
2002
2003     if(V_VT(lval) == VT_DISPATCH && (V_VT(rval) == VT_BSTR || is_num_vt(V_VT(rval)))) {
2004         VARIANT v;
2005         HRESULT hres;
2006
2007         hres = to_primitive(ctx->parser->script, lval, ei, &v);
2008         if(FAILED(hres))
2009             return hres;
2010
2011         hres = equal_values(ctx, &v, rval, ei, ret);
2012
2013         VariantClear(&v);
2014         return hres;
2015     }
2016
2017
2018     *ret = FALSE;
2019     return S_OK;
2020 }
2021
2022 /* ECMA-262 3rd Edition    11.9.1 */
2023 HRESULT equal_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2024 {
2025     binary_expression_t *expr = (binary_expression_t*)_expr;
2026     VARIANT rval, lval;
2027     BOOL b;
2028     HRESULT hres;
2029
2030     TRACE("\n");
2031
2032     hres = get_binary_expr_values(ctx, expr, ei, &rval, &lval);
2033     if(FAILED(hres))
2034         return hres;
2035
2036     hres = equal_values(ctx, &rval, &lval, ei, &b);
2037     if(FAILED(hres))
2038         return hres;
2039
2040     return return_bool(ret, b);
2041 }
2042
2043 /* ECMA-262 3rd Edition    11.9.4 */
2044 HRESULT equal2_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2045 {
2046     binary_expression_t *expr = (binary_expression_t*)_expr;
2047     VARIANT rval, lval;
2048     BOOL b;
2049     HRESULT hres;
2050
2051     TRACE("\n");
2052
2053     hres = get_binary_expr_values(ctx, expr, ei, &rval, &lval);
2054     if(FAILED(hres))
2055         return hres;
2056
2057     hres = equal2_values(&rval, &lval, &b);
2058     if(FAILED(hres))
2059         return hres;
2060
2061     return return_bool(ret, b);
2062 }
2063
2064 /* ECMA-262 3rd Edition    11.9.2 */
2065 HRESULT not_equal_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2066 {
2067     binary_expression_t *expr = (binary_expression_t*)_expr;
2068     VARIANT rval, lval;
2069     BOOL b;
2070     HRESULT hres;
2071
2072     TRACE("\n");
2073
2074     hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval);
2075     if(FAILED(hres))
2076         return hres;
2077
2078     hres = equal_values(ctx, &lval, &rval, ei, &b);
2079     if(FAILED(hres))
2080         return hres;
2081
2082     return return_bool(ret, !b);
2083 }
2084
2085 /* ECMA-262 3rd Edition    11.9.5 */
2086 HRESULT not_equal2_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2087 {
2088     binary_expression_t *expr = (binary_expression_t*)_expr;
2089     VARIANT rval, lval;
2090     BOOL b;
2091     HRESULT hres;
2092
2093     TRACE("\n");
2094
2095     hres = get_binary_expr_values(ctx, expr, ei, &rval, &lval);
2096     if(FAILED(hres))
2097         return hres;
2098
2099     hres = equal2_values(&rval, &lval, &b);
2100     if(FAILED(hres))
2101         return hres;
2102
2103     return return_bool(ret, !b);
2104 }
2105
2106 /* ECMA-262 3rd Edition    11.8.5 */
2107 static HRESULT less_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, BOOL *ret)
2108 {
2109     VARIANT l, r, ln, rn;
2110     HRESULT hres;
2111
2112     hres = to_primitive(ctx->parser->script, lval, ei, &l);
2113     if(FAILED(hres))
2114         return hres;
2115
2116     hres = to_primitive(ctx->parser->script, rval, ei, &r);
2117     if(FAILED(hres)) {
2118         VariantClear(&l);
2119         return hres;
2120     }
2121
2122     if(V_VT(&l) == VT_BSTR && V_VT(&r) == VT_BSTR) {
2123         *ret = strcmpW(V_BSTR(&l), V_BSTR(&r)) < 0;
2124         SysFreeString(V_BSTR(&l));
2125         SysFreeString(V_BSTR(&r));
2126         return S_OK;
2127     }
2128
2129     hres = to_number(ctx->parser->script, &l, ei, &ln);
2130     VariantClear(&l);
2131     if(SUCCEEDED(hres))
2132         hres = to_number(ctx->parser->script, &r, ei, &rn);
2133     VariantClear(&r);
2134     if(FAILED(hres))
2135         return hres;
2136
2137     if(V_VT(&ln) == VT_I4 && V_VT(&rn) == VT_I4)
2138         *ret = V_I4(&ln) < V_I4(&rn);
2139     else
2140         *ret = num_val(&ln) < num_val(&rn);
2141
2142     return S_OK;
2143 }
2144
2145 /* ECMA-262 3rd Edition    11.8.1 */
2146 HRESULT less_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2147 {
2148     binary_expression_t *expr = (binary_expression_t*)_expr;
2149     VARIANT rval, lval;
2150     BOOL b;
2151     HRESULT hres;
2152
2153     TRACE("\n");
2154
2155     hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval);
2156     if(FAILED(hres))
2157         return hres;
2158
2159     hres = less_eval(ctx, &lval, &rval, ei, &b);
2160     VariantClear(&lval);
2161     VariantClear(&rval);
2162     if(FAILED(hres))
2163         return hres;
2164
2165     return return_bool(ret, b);
2166 }
2167
2168 /* ECMA-262 3rd Edition    11.8.3 */
2169 HRESULT lesseq_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2170 {
2171     binary_expression_t *expr = (binary_expression_t*)_expr;
2172     VARIANT rval, lval;
2173     BOOL b;
2174     HRESULT hres;
2175
2176     TRACE("\n");
2177
2178     hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval);
2179     if(FAILED(hres))
2180         return hres;
2181
2182     hres = less_eval(ctx, &rval, &lval, ei, &b);
2183     VariantClear(&lval);
2184     VariantClear(&rval);
2185     if(FAILED(hres))
2186         return hres;
2187
2188     return return_bool(ret, !b);
2189 }
2190
2191 /* ECMA-262 3rd Edition    11.8.2 */
2192 HRESULT greater_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2193 {
2194     binary_expression_t *expr = (binary_expression_t*)_expr;
2195     VARIANT rval, lval;
2196     BOOL b;
2197     HRESULT hres;
2198
2199     TRACE("\n");
2200
2201     hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval);
2202     if(FAILED(hres))
2203         return hres;
2204
2205     hres = less_eval(ctx, &rval, &lval, ei, &b);
2206     VariantClear(&lval);
2207     VariantClear(&rval);
2208     if(FAILED(hres))
2209         return hres;
2210
2211     return return_bool(ret, b);
2212 }
2213
2214 /* ECMA-262 3rd Edition    11.8.4 */
2215 HRESULT greatereq_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2216 {
2217     binary_expression_t *expr = (binary_expression_t*)_expr;
2218     VARIANT rval, lval;
2219     BOOL b;
2220     HRESULT hres;
2221
2222     TRACE("\n");
2223
2224     hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval);
2225     if(FAILED(hres))
2226         return hres;
2227
2228     hres = less_eval(ctx, &lval, &rval, ei, &b);
2229     VariantClear(&lval);
2230     VariantClear(&rval);
2231     if(FAILED(hres))
2232         return hres;
2233
2234     return return_bool(ret, !b);
2235 }
2236
2237 HRESULT binary_negation_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2238 {
2239     FIXME("\n");
2240     return E_NOTIMPL;
2241 }
2242
2243 /* ECMA-262 3rd Edition    11.4.9 */
2244 HRESULT logical_negation_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2245 {
2246     unary_expression_t *expr = (unary_expression_t*)_expr;
2247     exprval_t exprval;
2248     VARIANT_BOOL b;
2249     HRESULT hres;
2250
2251     TRACE("\n");
2252
2253     hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval);
2254     if(FAILED(hres))
2255         return hres;
2256
2257     hres = exprval_to_boolean(ctx->parser->script, &exprval, ei, &b);
2258     exprval_release(&exprval);
2259     if(FAILED(hres))
2260         return hres;
2261
2262     return return_bool(ret, !b);
2263 }
2264
2265 HRESULT left_shift_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2266 {
2267     FIXME("\n");
2268     return E_NOTIMPL;
2269 }
2270
2271 HRESULT right_shift_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2272 {
2273     FIXME("\n");
2274     return E_NOTIMPL;
2275 }
2276
2277 HRESULT right2_shift_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2278 {
2279     FIXME("\n");
2280     return E_NOTIMPL;
2281 }
2282
2283 /* ECMA-262 3rd Edition    11.13.1 */
2284 HRESULT assign_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2285 {
2286     binary_expression_t *expr = (binary_expression_t*)_expr;
2287     exprval_t exprval, exprvalr;
2288     VARIANT rval;
2289     HRESULT hres;
2290
2291     TRACE("\n");
2292
2293     hres = expr_eval(ctx, expr->expression1, EXPR_NEWREF, ei, &exprval);
2294     if(FAILED(hres))
2295         return hres;
2296
2297     hres = expr_eval(ctx, expr->expression2, 0, ei, &exprvalr);
2298     if(SUCCEEDED(hres)) {
2299         hres = exprval_to_value(ctx->parser->script, &exprvalr, ei, &rval);
2300         exprval_release(&exprvalr);
2301     }
2302
2303     if(SUCCEEDED(hres))
2304         hres = put_value(ctx->parser->script, &exprval, &rval, ei);
2305
2306     exprval_release(&exprval);
2307     if(FAILED(hres)) {
2308         VariantClear(&rval);
2309         return hres;
2310     }
2311
2312     ret->type = EXPRVAL_VARIANT;
2313     ret->u.var = rval;
2314     return S_OK;
2315 }
2316
2317 HRESULT assign_lshift_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2318 {
2319     FIXME("\n");
2320     return E_NOTIMPL;
2321 }
2322
2323 HRESULT assign_rshift_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2324 {
2325     FIXME("\n");
2326     return E_NOTIMPL;
2327 }
2328
2329 HRESULT assign_rrshift_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2330 {
2331     FIXME("\n");
2332     return E_NOTIMPL;
2333 }
2334
2335 /* ECMA-262 3rd Edition    11.13.2 */
2336 HRESULT assign_add_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2337 {
2338     binary_expression_t *expr = (binary_expression_t*)_expr;
2339
2340     TRACE("\n");
2341
2342     return assign_oper_eval(ctx, expr->expression1, expr->expression2, add_eval, ei, ret);
2343 }
2344
2345 /* ECMA-262 3rd Edition    11.13.2 */
2346 HRESULT assign_sub_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2347 {
2348     binary_expression_t *expr = (binary_expression_t*)_expr;
2349
2350     TRACE("\n");
2351
2352     return assign_oper_eval(ctx, expr->expression1, expr->expression2, sub_eval, ei, ret);
2353 }
2354
2355 /* ECMA-262 3rd Edition    11.13.2 */
2356 HRESULT assign_mul_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2357 {
2358     binary_expression_t *expr = (binary_expression_t*)_expr;
2359
2360     TRACE("\n");
2361
2362     return assign_oper_eval(ctx, expr->expression1, expr->expression2, mul_eval, ei, ret);
2363 }
2364
2365 /* ECMA-262 3rd Edition    11.13.2 */
2366 HRESULT assign_div_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2367 {
2368     binary_expression_t *expr = (binary_expression_t*)_expr;
2369
2370     TRACE("\n");
2371
2372     return assign_oper_eval(ctx, expr->expression1, expr->expression2, div_eval, ei, ret);
2373 }
2374
2375 HRESULT assign_mod_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2376 {
2377     FIXME("\n");
2378     return E_NOTIMPL;
2379 }
2380
2381 HRESULT assign_and_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2382 {
2383     FIXME("\n");
2384     return E_NOTIMPL;
2385 }
2386
2387 HRESULT assign_or_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2388 {
2389     FIXME("\n");
2390     return E_NOTIMPL;
2391 }
2392
2393 HRESULT assign_xor_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2394 {
2395     FIXME("\n");
2396     return E_NOTIMPL;
2397 }