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