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