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