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