jscript: Use bytecode for conditional expressions.
[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.2.1 */
1439 HRESULT array_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1440 {
1441     array_expression_t *expr = (array_expression_t*)_expr;
1442     exprval_t exprval;
1443     VARIANT member, val;
1444     DISPID id;
1445     BSTR str;
1446     IDispatch *obj = NULL;
1447     HRESULT hres;
1448
1449     TRACE("\n");
1450
1451     hres = expr_eval(ctx, expr->member_expr, 0, ei, &exprval);
1452     if(FAILED(hres))
1453         return hres;
1454
1455     hres = exprval_to_value(ctx, &exprval, ei, &member);
1456     exprval_release(&exprval);
1457     if(FAILED(hres))
1458         return hres;
1459
1460     hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval);
1461     if(SUCCEEDED(hres)) {
1462         hres = exprval_to_value(ctx, &exprval, ei, &val);
1463         exprval_release(&exprval);
1464     }
1465
1466     if(SUCCEEDED(hres)) {
1467         hres = to_object(ctx, &member, &obj);
1468         if(FAILED(hres))
1469             VariantClear(&val);
1470     }
1471     VariantClear(&member);
1472     if(SUCCEEDED(hres)) {
1473         hres = to_string(ctx, &val, ei, &str);
1474         VariantClear(&val);
1475         if(SUCCEEDED(hres)) {
1476             if(flags & EXPR_STRREF) {
1477                 ret->type = EXPRVAL_NAMEREF;
1478                 ret->u.nameref.disp = obj;
1479                 ret->u.nameref.name = str;
1480                 return S_OK;
1481             }
1482
1483             hres = disp_get_id(ctx, obj, str, flags & EXPR_NEWREF ? fdexNameEnsure : 0, &id);
1484             SysFreeString(str);
1485         }
1486
1487         if(SUCCEEDED(hres)) {
1488             exprval_set_idref(ret, obj, id);
1489         }else if(!(flags & EXPR_NEWREF) && hres == DISP_E_UNKNOWNNAME) {
1490             exprval_init(ret);
1491             hres = S_OK;
1492         }
1493
1494         IDispatch_Release(obj);
1495     }
1496
1497     return hres;
1498 }
1499
1500 /* ECMA-262 3rd Edition    11.2.1 */
1501 HRESULT member_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1502 {
1503     member_expression_t *expr = (member_expression_t*)_expr;
1504     IDispatch *obj = NULL;
1505     exprval_t exprval;
1506     VARIANT member;
1507     DISPID id;
1508     BSTR str;
1509     HRESULT hres;
1510
1511     TRACE("\n");
1512
1513     hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
1514     if(FAILED(hres))
1515         return hres;
1516
1517     hres = exprval_to_value(ctx, &exprval, ei, &member);
1518     exprval_release(&exprval);
1519     if(FAILED(hres))
1520         return hres;
1521
1522     hres = to_object(ctx, &member, &obj);
1523     VariantClear(&member);
1524     if(FAILED(hres))
1525         return hres;
1526
1527     str = SysAllocString(expr->identifier);
1528     if(flags & EXPR_STRREF) {
1529         ret->type = EXPRVAL_NAMEREF;
1530         ret->u.nameref.disp = obj;
1531         ret->u.nameref.name = str;
1532         return S_OK;
1533     }
1534
1535     hres = disp_get_id(ctx, obj, str, flags & EXPR_NEWREF ? fdexNameEnsure : 0, &id);
1536     SysFreeString(str);
1537     if(SUCCEEDED(hres)) {
1538         exprval_set_idref(ret, obj, id);
1539     }else if(!(flags & EXPR_NEWREF) && hres == DISP_E_UNKNOWNNAME) {
1540         exprval_init(ret);
1541         hres = S_OK;
1542     }
1543
1544     IDispatch_Release(obj);
1545     return hres;
1546 }
1547
1548 static void free_dp(DISPPARAMS *dp)
1549 {
1550     DWORD i;
1551
1552     for(i=0; i < dp->cArgs; i++)
1553         VariantClear(dp->rgvarg+i);
1554     heap_free(dp->rgvarg);
1555 }
1556
1557 static HRESULT args_to_param(script_ctx_t *ctx, argument_t *args, jsexcept_t *ei, DISPPARAMS *dp)
1558 {
1559     VARIANTARG *vargs;
1560     exprval_t exprval;
1561     argument_t *iter;
1562     DWORD cnt = 0, i;
1563     HRESULT hres = S_OK;
1564
1565     memset(dp, 0, sizeof(*dp));
1566     if(!args)
1567         return S_OK;
1568
1569     for(iter = args; iter; iter = iter->next)
1570         cnt++;
1571
1572     vargs = heap_alloc_zero(cnt * sizeof(*vargs));
1573     if(!vargs)
1574         return E_OUTOFMEMORY;
1575
1576     for(i = cnt, iter = args; iter; iter = iter->next) {
1577         hres = expr_eval(ctx, iter->expr, 0, ei, &exprval);
1578         if(FAILED(hres))
1579             break;
1580
1581         hres = exprval_to_value(ctx, &exprval, ei, vargs + (--i));
1582         exprval_release(&exprval);
1583         if(FAILED(hres))
1584             break;
1585     }
1586
1587     if(FAILED(hres)) {
1588         free_dp(dp);
1589         return hres;
1590     }
1591
1592     dp->rgvarg = vargs;
1593     dp->cArgs = cnt;
1594     return S_OK;
1595 }
1596
1597 /* ECMA-262 3rd Edition    11.2.2 */
1598 HRESULT new_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1599 {
1600     call_expression_t *expr = (call_expression_t*)_expr;
1601     exprval_t exprval;
1602     VARIANT constr, var;
1603     DISPPARAMS dp;
1604     HRESULT hres;
1605
1606     TRACE("\n");
1607
1608     hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
1609     if(FAILED(hres))
1610         return hres;
1611
1612     hres = args_to_param(ctx, expr->argument_list, ei, &dp);
1613     if(SUCCEEDED(hres))
1614         hres = exprval_to_value(ctx, &exprval, ei, &constr);
1615     exprval_release(&exprval);
1616     if(FAILED(hres))
1617         return hres;
1618
1619     /* NOTE: Should use to_object here */
1620
1621     if(V_VT(&constr) == VT_NULL) {
1622         VariantClear(&constr);
1623         return throw_type_error(ctx, ei, JS_E_OBJECT_EXPECTED, NULL);
1624     } else if(V_VT(&constr) != VT_DISPATCH) {
1625         VariantClear(&constr);
1626         return throw_type_error(ctx, ei, JS_E_INVALID_ACTION, NULL);
1627     } else if(!V_DISPATCH(&constr)) {
1628         VariantClear(&constr);
1629         return throw_type_error(ctx, ei, JS_E_INVALID_PROPERTY, NULL);
1630     }
1631
1632     hres = disp_call(ctx, V_DISPATCH(&constr), DISPID_VALUE,
1633             DISPATCH_CONSTRUCT, &dp, &var, ei, NULL/*FIXME*/);
1634     IDispatch_Release(V_DISPATCH(&constr));
1635     free_dp(&dp);
1636     if(FAILED(hres))
1637         return hres;
1638
1639     ret->type = EXPRVAL_VARIANT;
1640     ret->u.var = var;
1641     return S_OK;
1642 }
1643
1644 /* ECMA-262 3rd Edition    11.2.3 */
1645 HRESULT call_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1646 {
1647     call_expression_t *expr = (call_expression_t*)_expr;
1648     VARIANT var;
1649     exprval_t exprval;
1650     DISPPARAMS dp;
1651     HRESULT hres;
1652
1653     TRACE("\n");
1654
1655     hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
1656     if(FAILED(hres))
1657         return hres;
1658
1659     hres = args_to_param(ctx, expr->argument_list, ei, &dp);
1660     if(SUCCEEDED(hres)) {
1661         switch(exprval.type) {
1662         case EXPRVAL_VARIANT:
1663             if(V_VT(&exprval.u.var) == VT_DISPATCH)
1664                 hres = disp_call(ctx, V_DISPATCH(&exprval.u.var), DISPID_VALUE,
1665                         DISPATCH_METHOD, &dp, flags & EXPR_NOVAL ? NULL : &var, ei, NULL/*FIXME*/);
1666             else
1667                 hres = throw_type_error(ctx, ei, JS_E_INVALID_PROPERTY, NULL);
1668             break;
1669         case EXPRVAL_IDREF:
1670             hres = disp_call(ctx, exprval.u.idref.disp, exprval.u.idref.id,
1671                     DISPATCH_METHOD, &dp, flags & EXPR_NOVAL ? NULL : &var, ei, NULL/*FIXME*/);
1672             break;
1673         case EXPRVAL_INVALID:
1674             hres = throw_type_error(ctx, ei, JS_E_OBJECT_EXPECTED, NULL);
1675             break;
1676         default:
1677             FIXME("unimplemented type %d\n", exprval.type);
1678             hres = E_NOTIMPL;
1679         }
1680
1681         free_dp(&dp);
1682     }
1683
1684     exprval_release(&exprval);
1685     if(FAILED(hres))
1686         return hres;
1687
1688     ret->type = EXPRVAL_VARIANT;
1689     if(flags & EXPR_NOVAL) {
1690         V_VT(&ret->u.var) = VT_EMPTY;
1691     }else {
1692         TRACE("= %s\n", debugstr_variant(&var));
1693         ret->u.var = var;
1694     }
1695     return S_OK;
1696 }
1697
1698 /* ECMA-262 3rd Edition    11.1.1 */
1699 HRESULT interp_this(exec_ctx_t *ctx)
1700 {
1701     VARIANT v;
1702
1703     TRACE("\n");
1704
1705     V_VT(&v) = VT_DISPATCH;
1706     V_DISPATCH(&v) = ctx->this_obj;
1707     IDispatch_AddRef(ctx->this_obj);
1708     return stack_push(ctx, &v);
1709 }
1710
1711 /* ECMA-262 3rd Edition    10.1.4 */
1712 HRESULT identifier_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1713 {
1714     identifier_expression_t *expr = (identifier_expression_t*)_expr;
1715     BSTR identifier;
1716     HRESULT hres;
1717
1718     TRACE("\n");
1719
1720     identifier = SysAllocString(expr->identifier);
1721     if(!identifier)
1722         return E_OUTOFMEMORY;
1723
1724     hres = identifier_eval(ctx, identifier, flags, ei, ret);
1725
1726     SysFreeString(identifier);
1727     return hres;
1728 }
1729
1730 /* ECMA-262 3rd Edition    7.8.1 */
1731 HRESULT interp_null(exec_ctx_t *ctx)
1732 {
1733     VARIANT v;
1734
1735     TRACE("\n");
1736
1737     V_VT(&v) = VT_NULL;
1738     return stack_push(ctx, &v);
1739 }
1740
1741 /* ECMA-262 3rd Edition    7.8.2 */
1742 HRESULT interp_bool(exec_ctx_t *ctx)
1743 {
1744     const LONG arg = ctx->parser->code->instrs[ctx->ip].arg1.lng;
1745
1746     TRACE("%s\n", arg ? "true" : "false");
1747
1748     return stack_push_bool(ctx, arg);
1749 }
1750
1751 /* ECMA-262 3rd Edition    7.8.3 */
1752 HRESULT interp_int(exec_ctx_t *ctx)
1753 {
1754     const LONG arg = ctx->parser->code->instrs[ctx->ip].arg1.lng;
1755     VARIANT v;
1756
1757     TRACE("%d\n", arg);
1758
1759     V_VT(&v) = VT_I4;
1760     V_I4(&v) = arg;
1761     return stack_push(ctx, &v);
1762 }
1763
1764 /* ECMA-262 3rd Edition    7.8.3 */
1765 HRESULT interp_double(exec_ctx_t *ctx)
1766 {
1767     const double arg = *ctx->parser->code->instrs[ctx->ip].arg1.dbl;
1768     VARIANT v;
1769
1770     TRACE("%lf\n", arg);
1771
1772     V_VT(&v) = VT_R8;
1773     V_R8(&v) = arg;
1774     return stack_push(ctx, &v);
1775 }
1776
1777 /* ECMA-262 3rd Edition    7.8.4 */
1778 HRESULT interp_str(exec_ctx_t *ctx)
1779 {
1780     const WCHAR *str = ctx->parser->code->instrs[ctx->ip].arg1.str;
1781     VARIANT v;
1782
1783     TRACE("%s\n", debugstr_w(str));
1784
1785     V_VT(&v) = VT_BSTR;
1786     V_BSTR(&v) = SysAllocString(str);
1787     if(!V_BSTR(&v))
1788         return E_OUTOFMEMORY;
1789
1790     return stack_push(ctx, &v);
1791 }
1792
1793 /* ECMA-262 3rd Edition    7.8 */
1794 HRESULT interp_regexp(exec_ctx_t *ctx)
1795 {
1796     const WCHAR *source = ctx->parser->code->instrs[ctx->ip].arg1.str;
1797     const LONG flags = ctx->parser->code->instrs[ctx->ip].arg2.lng;
1798     jsdisp_t *regexp;
1799     VARIANT v;
1800     HRESULT hres;
1801
1802     TRACE("%s %x\n", debugstr_w(source), flags);
1803
1804     hres = create_regexp(ctx->parser->script, source, strlenW(source), flags, &regexp);
1805     if(FAILED(hres))
1806         return hres;
1807
1808     var_set_jsdisp(&v, regexp);
1809     return stack_push(ctx, &v);
1810 }
1811
1812 /* ECMA-262 3rd Edition    11.1.4 */
1813 HRESULT array_literal_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1814 {
1815     array_literal_expression_t *expr = (array_literal_expression_t*)_expr;
1816     DWORD length = 0, i = 0;
1817     array_element_t *elem;
1818     jsdisp_t *array;
1819     exprval_t exprval;
1820     VARIANT val;
1821     HRESULT hres;
1822
1823     TRACE("\n");
1824
1825     for(elem = expr->element_list; elem; elem = elem->next)
1826         length += elem->elision+1;
1827     length += expr->length;
1828
1829     hres = create_array(ctx, length, &array);
1830     if(FAILED(hres))
1831         return hres;
1832
1833     for(elem = expr->element_list; elem; elem = elem->next) {
1834         i += elem->elision;
1835
1836         hres = expr_eval(ctx, elem->expr, 0, ei, &exprval);
1837         if(FAILED(hres))
1838             break;
1839
1840         hres = exprval_to_value(ctx, &exprval, ei, &val);
1841         exprval_release(&exprval);
1842         if(FAILED(hres))
1843             break;
1844
1845         hres = jsdisp_propput_idx(array, i, &val, ei, NULL/*FIXME*/);
1846         VariantClear(&val);
1847         if(FAILED(hres))
1848             break;
1849
1850         i++;
1851     }
1852
1853     if(FAILED(hres)) {
1854         jsdisp_release(array);
1855         return hres;
1856     }
1857
1858     ret->type = EXPRVAL_VARIANT;
1859     var_set_jsdisp(&ret->u.var, array);
1860     return S_OK;
1861 }
1862
1863 /* ECMA-262 3rd Edition    11.1.5 */
1864 HRESULT property_value_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1865 {
1866     property_value_expression_t *expr = (property_value_expression_t*)_expr;
1867     VARIANT val, tmp;
1868     jsdisp_t *obj;
1869     prop_val_t *iter;
1870     exprval_t exprval;
1871     BSTR name;
1872     HRESULT hres;
1873
1874     TRACE("\n");
1875
1876     hres = create_object(ctx, NULL, &obj);
1877     if(FAILED(hres))
1878         return hres;
1879
1880     for(iter = expr->property_list; iter; iter = iter->next) {
1881         hres = literal_to_var(ctx, iter->name, &tmp);
1882         if(FAILED(hres))
1883             break;
1884
1885         hres = to_string(ctx, &tmp, ei, &name);
1886         VariantClear(&tmp);
1887         if(FAILED(hres))
1888             break;
1889
1890         hres = expr_eval(ctx, iter->value, 0, ei, &exprval);
1891         if(SUCCEEDED(hres)) {
1892             hres = exprval_to_value(ctx, &exprval, ei, &val);
1893             exprval_release(&exprval);
1894             if(SUCCEEDED(hres)) {
1895                 hres = jsdisp_propput_name(obj, name, &val, ei, NULL/*FIXME*/);
1896                 VariantClear(&val);
1897             }
1898         }
1899
1900         SysFreeString(name);
1901         if(FAILED(hres))
1902             break;
1903     }
1904
1905     if(FAILED(hres)) {
1906         jsdisp_release(obj);
1907         return hres;
1908     }
1909
1910     ret->type = EXPRVAL_VARIANT;
1911     var_set_jsdisp(&ret->u.var, obj);
1912     return S_OK;
1913 }
1914
1915 /* ECMA-262 3rd Edition    11.11 */
1916 HRESULT interp_jmp_nz(exec_ctx_t *ctx)
1917 {
1918     const unsigned arg = ctx->parser->code->instrs[ctx->ip].arg1.uint;
1919     VARIANT_BOOL b;
1920     HRESULT hres;
1921
1922     TRACE("\n");
1923
1924     hres = to_boolean(stack_top(ctx), &b);
1925     if(FAILED(hres))
1926         return hres;
1927
1928     if(b) {
1929         ctx->ip = arg;
1930     }else {
1931         stack_popn(ctx, 1);
1932         ctx->ip++;
1933     }
1934     return S_OK;
1935 }
1936
1937 /* ECMA-262 3rd Edition    11.11 */
1938 HRESULT interp_jmp_z(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         stack_popn(ctx, 1);
1952         ctx->ip++;
1953     }else {
1954         ctx->ip = arg;
1955     }
1956     return S_OK;
1957 }
1958
1959 /* ECMA-262 3rd Edition    11.10 */
1960 static HRESULT bitor_eval(script_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
1961 {
1962     INT li, ri;
1963     HRESULT hres;
1964
1965     hres = to_int32(ctx, lval, ei, &li);
1966     if(FAILED(hres))
1967         return hres;
1968
1969     hres = to_int32(ctx, rval, ei, &ri);
1970     if(FAILED(hres))
1971         return hres;
1972
1973     V_VT(retv) = VT_I4;
1974     V_I4(retv) = li|ri;
1975     return S_OK;
1976 }
1977
1978 /* ECMA-262 3rd Edition    11.10 */
1979 HRESULT binary_or_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1980 {
1981     binary_expression_t *expr = (binary_expression_t*)_expr;
1982
1983     TRACE("\n");
1984
1985     return binary_expr_eval(ctx, expr, bitor_eval, ei, ret);
1986 }
1987
1988 /* ECMA-262 3rd Edition    11.10 */
1989 static HRESULT xor_eval(script_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
1990 {
1991     INT li, ri;
1992     HRESULT hres;
1993
1994     hres = to_int32(ctx, lval, ei, &li);
1995     if(FAILED(hres))
1996         return hres;
1997
1998     hres = to_int32(ctx, rval, ei, &ri);
1999     if(FAILED(hres))
2000         return hres;
2001
2002     V_VT(retv) = VT_I4;
2003     V_I4(retv) = li^ri;
2004     return S_OK;
2005 }
2006
2007 /* ECMA-262 3rd Edition    11.10 */
2008 HRESULT binary_xor_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2009 {
2010     binary_expression_t *expr = (binary_expression_t*)_expr;
2011
2012     TRACE("\n");
2013
2014     return binary_expr_eval(ctx, expr, xor_eval, ei, ret);
2015 }
2016
2017 /* ECMA-262 3rd Edition    11.10 */
2018 static HRESULT bitand_eval(script_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
2019 {
2020     INT li, ri;
2021     HRESULT hres;
2022
2023     hres = to_int32(ctx, lval, ei, &li);
2024     if(FAILED(hres))
2025         return hres;
2026
2027     hres = to_int32(ctx, rval, ei, &ri);
2028     if(FAILED(hres))
2029         return hres;
2030
2031     V_VT(retv) = VT_I4;
2032     V_I4(retv) = li&ri;
2033     return S_OK;
2034 }
2035
2036 /* ECMA-262 3rd Edition    11.10 */
2037 HRESULT binary_and_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2038 {
2039     binary_expression_t *expr = (binary_expression_t*)_expr;
2040
2041     TRACE("\n");
2042
2043     return binary_expr_eval(ctx, expr, bitand_eval, ei, ret);
2044 }
2045
2046 /* ECMA-262 3rd Edition    11.8.6 */
2047 static HRESULT instanceof_eval(script_ctx_t *ctx, VARIANT *inst, VARIANT *objv, jsexcept_t *ei, VARIANT *retv)
2048 {
2049     jsdisp_t *obj, *iter, *tmp = NULL;
2050     VARIANT_BOOL ret = VARIANT_FALSE;
2051     BOOL b;
2052     VARIANT var;
2053     HRESULT hres;
2054
2055     static const WCHAR prototypeW[] = {'p','r','o','t','o','t', 'y', 'p','e',0};
2056
2057     if(V_VT(objv) != VT_DISPATCH || !V_DISPATCH(objv))
2058         return throw_type_error(ctx, ei, JS_E_FUNCTION_EXPECTED, NULL);
2059
2060     obj = iface_to_jsdisp((IUnknown*)V_DISPATCH(objv));
2061     if(!obj) {
2062         FIXME("non-jsdisp objects not supported\n");
2063         return E_FAIL;
2064     }
2065
2066     if(is_class(obj, JSCLASS_FUNCTION)) {
2067         hres = jsdisp_propget_name(obj, prototypeW, &var, ei, NULL/*FIXME*/);
2068     }else {
2069         hres = throw_type_error(ctx, ei, JS_E_FUNCTION_EXPECTED, NULL);
2070     }
2071     jsdisp_release(obj);
2072     if(FAILED(hres))
2073         return hres;
2074
2075     if(V_VT(&var) == VT_DISPATCH) {
2076         if(V_VT(inst) == VT_DISPATCH)
2077             tmp = iface_to_jsdisp((IUnknown*)V_DISPATCH(inst));
2078         for(iter = tmp; iter; iter = iter->prototype) {
2079             hres = disp_cmp(V_DISPATCH(&var), to_disp(iter), &b);
2080             if(FAILED(hres))
2081                 break;
2082             if(b) {
2083                 ret = VARIANT_TRUE;
2084                 break;
2085             }
2086         }
2087
2088         if(tmp)
2089             jsdisp_release(tmp);
2090     }else {
2091         FIXME("prototype is not an object\n");
2092         hres = E_FAIL;
2093     }
2094
2095     VariantClear(&var);
2096     if(FAILED(hres))
2097         return hres;
2098
2099     V_VT(retv) = VT_BOOL;
2100     V_BOOL(retv) = ret;
2101     return S_OK;
2102 }
2103
2104 /* ECMA-262 3rd Edition    11.8.6 */
2105 HRESULT instanceof_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2106 {
2107     binary_expression_t *expr = (binary_expression_t*)_expr;
2108
2109     TRACE("\n");
2110
2111     return binary_expr_eval(ctx, expr, instanceof_eval, ei, ret);
2112 }
2113
2114 /* ECMA-262 3rd Edition    11.8.7 */
2115 HRESULT interp_in(exec_ctx_t *ctx)
2116 {
2117     VARIANT *obj, *v;
2118     DISPID id = 0;
2119     BOOL ret;
2120     BSTR str;
2121     HRESULT hres;
2122
2123     TRACE("\n");
2124
2125     obj = stack_pop(ctx);
2126     v = stack_pop(ctx);
2127
2128     if(V_VT(obj) != VT_DISPATCH || !V_DISPATCH(obj)) {
2129         VariantClear(obj);
2130         VariantClear(v);
2131         return throw_type_error(ctx->parser->script, &ctx->ei, JS_E_OBJECT_EXPECTED, NULL);
2132     }
2133
2134     hres = to_string(ctx->parser->script, v, &ctx->ei, &str);
2135     VariantClear(v);
2136     if(FAILED(hres)) {
2137         IDispatch_Release(V_DISPATCH(obj));
2138         return hres;
2139     }
2140
2141     hres = disp_get_id(ctx->parser->script, V_DISPATCH(obj), str, 0, &id);
2142     IDispatch_Release(V_DISPATCH(obj));
2143     SysFreeString(str);
2144     if(SUCCEEDED(hres))
2145         ret = TRUE;
2146     else if(hres == DISP_E_UNKNOWNNAME)
2147         ret = FALSE;
2148     else
2149         return hres;
2150
2151     return stack_push_bool(ctx, ret);
2152 }
2153
2154 /* ECMA-262 3rd Edition    11.6.1 */
2155 static HRESULT add_eval(script_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
2156 {
2157     VARIANT r, l;
2158     HRESULT hres;
2159
2160     hres = to_primitive(ctx, lval, ei, &l, NO_HINT);
2161     if(FAILED(hres))
2162         return hres;
2163
2164     hres = to_primitive(ctx, rval, ei, &r, NO_HINT);
2165     if(FAILED(hres)) {
2166         VariantClear(&l);
2167         return hres;
2168     }
2169
2170     if(V_VT(&l) == VT_BSTR || V_VT(&r) == VT_BSTR) {
2171         BSTR lstr = NULL, rstr = NULL;
2172
2173         if(V_VT(&l) == VT_BSTR)
2174             lstr = V_BSTR(&l);
2175         else
2176             hres = to_string(ctx, &l, ei, &lstr);
2177
2178         if(SUCCEEDED(hres)) {
2179             if(V_VT(&r) == VT_BSTR)
2180                 rstr = V_BSTR(&r);
2181             else
2182                 hres = to_string(ctx, &r, ei, &rstr);
2183         }
2184
2185         if(SUCCEEDED(hres)) {
2186             int len1, len2;
2187
2188             len1 = SysStringLen(lstr);
2189             len2 = SysStringLen(rstr);
2190
2191             V_VT(retv) = VT_BSTR;
2192             V_BSTR(retv) = SysAllocStringLen(NULL, len1+len2);
2193             memcpy(V_BSTR(retv), lstr, len1*sizeof(WCHAR));
2194             memcpy(V_BSTR(retv)+len1, rstr, (len2+1)*sizeof(WCHAR));
2195         }
2196
2197         if(V_VT(&l) != VT_BSTR)
2198             SysFreeString(lstr);
2199         if(V_VT(&r) != VT_BSTR)
2200             SysFreeString(rstr);
2201     }else {
2202         VARIANT nl, nr;
2203
2204         hres = to_number(ctx, &l, ei, &nl);
2205         if(SUCCEEDED(hres)) {
2206             hres = to_number(ctx, &r, ei, &nr);
2207             if(SUCCEEDED(hres))
2208                 num_set_val(retv, num_val(&nl) + num_val(&nr));
2209         }
2210     }
2211
2212     VariantClear(&r);
2213     VariantClear(&l);
2214     return hres;
2215 }
2216
2217 /* ECMA-262 3rd Edition    11.6.1 */
2218 HRESULT interp_add(exec_ctx_t *ctx)
2219 {
2220     VARIANT *l, *r, ret;
2221     HRESULT hres;
2222
2223     r = stack_pop(ctx);
2224     l = stack_pop(ctx);
2225
2226     TRACE("%s + %s\n", debugstr_variant(l), debugstr_variant(r));
2227
2228     hres = add_eval(ctx->parser->script, l, r, &ctx->ei, &ret);
2229     VariantClear(l);
2230     VariantClear(r);
2231     if(FAILED(hres))
2232         return hres;
2233
2234     return stack_push(ctx, &ret);
2235 }
2236
2237 /* ECMA-262 3rd Edition    11.6.2 */
2238 static HRESULT sub_eval(script_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
2239 {
2240     VARIANT lnum, rnum;
2241     HRESULT hres;
2242
2243     hres = to_number(ctx, lval, ei, &lnum);
2244     if(FAILED(hres))
2245         return hres;
2246
2247     hres = to_number(ctx, rval, ei, &rnum);
2248     if(FAILED(hres))
2249         return hres;
2250
2251     num_set_val(retv, num_val(&lnum) - num_val(&rnum));
2252     return S_OK;
2253 }
2254
2255 /* ECMA-262 3rd Edition    11.6.2 */
2256 HRESULT interp_sub(exec_ctx_t *ctx)
2257 {
2258     VARIANT l, r;
2259     HRESULT hres;
2260
2261     TRACE("\n");
2262
2263     hres = stack_pop_number(ctx, &r);
2264     if(FAILED(hres))
2265         return hres;
2266
2267     hres = stack_pop_number(ctx, &l);
2268     if(FAILED(hres))
2269         return hres;
2270
2271     return stack_push_number(ctx, num_val(&l)-num_val(&r));
2272 }
2273
2274 /* ECMA-262 3rd Edition    11.5.1 */
2275 static HRESULT mul_eval(script_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
2276 {
2277     VARIANT lnum, rnum;
2278     HRESULT hres;
2279
2280     hres = to_number(ctx, lval, ei, &lnum);
2281     if(FAILED(hres))
2282         return hres;
2283
2284     hres = to_number(ctx, rval, ei, &rnum);
2285     if(FAILED(hres))
2286         return hres;
2287
2288     num_set_val(retv, num_val(&lnum) * num_val(&rnum));
2289     return S_OK;
2290 }
2291
2292 /* ECMA-262 3rd Edition    11.5.1 */
2293 HRESULT mul_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2294 {
2295     binary_expression_t *expr = (binary_expression_t*)_expr;
2296
2297     TRACE("\n");
2298
2299     return binary_expr_eval(ctx, expr, mul_eval, ei, ret);
2300 }
2301
2302 /* ECMA-262 3rd Edition    11.5.2 */
2303 static HRESULT div_eval(script_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
2304 {
2305     VARIANT lnum, rnum;
2306     HRESULT hres;
2307
2308     hres = to_number(ctx, lval, ei, &lnum);
2309     if(FAILED(hres))
2310         return hres;
2311
2312     hres = to_number(ctx, rval, ei, &rnum);
2313     if(FAILED(hres))
2314         return hres;
2315
2316     num_set_val(retv, num_val(&lnum) / num_val(&rnum));
2317     return S_OK;
2318 }
2319
2320 /* ECMA-262 3rd Edition    11.5.2 */
2321 HRESULT div_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2322 {
2323     binary_expression_t *expr = (binary_expression_t*)_expr;
2324
2325     TRACE("\n");
2326
2327     return binary_expr_eval(ctx, expr, div_eval, ei, ret);
2328 }
2329
2330 /* ECMA-262 3rd Edition    11.5.3 */
2331 static HRESULT mod_eval(script_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
2332 {
2333     VARIANT lnum, rnum;
2334     HRESULT hres;
2335
2336     hres = to_number(ctx, lval, ei, &lnum);
2337     if(FAILED(hres))
2338         return hres;
2339
2340     hres = to_number(ctx, rval, ei, &rnum);
2341     if(FAILED(hres))
2342         return hres;
2343
2344     num_set_val(retv, fmod(num_val(&lnum), num_val(&rnum)));
2345     return S_OK;
2346 }
2347
2348 /* ECMA-262 3rd Edition    11.5.3 */
2349 HRESULT mod_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2350 {
2351     binary_expression_t *expr = (binary_expression_t*)_expr;
2352
2353     TRACE("\n");
2354
2355     return binary_expr_eval(ctx, expr, mod_eval, ei, ret);
2356 }
2357
2358 /* ECMA-262 3rd Edition    11.4.2 */
2359 HRESULT delete_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2360 {
2361     unary_expression_t *expr = (unary_expression_t*)_expr;
2362     VARIANT_BOOL b = VARIANT_FALSE;
2363     exprval_t exprval;
2364     HRESULT hres;
2365
2366     TRACE("\n");
2367
2368     hres = expr_eval(ctx, expr->expression, EXPR_STRREF, ei, &exprval);
2369     if(FAILED(hres))
2370         return hres;
2371
2372     switch(exprval.type) {
2373     case EXPRVAL_IDREF: {
2374         IDispatchEx *dispex;
2375
2376         hres = IDispatch_QueryInterface(exprval.u.nameref.disp, &IID_IDispatchEx, (void**)&dispex);
2377         if(SUCCEEDED(hres)) {
2378             hres = IDispatchEx_DeleteMemberByDispID(dispex, exprval.u.idref.id);
2379             b = VARIANT_TRUE;
2380             IDispatchEx_Release(dispex);
2381         }
2382         break;
2383     }
2384     case EXPRVAL_NAMEREF: {
2385         IDispatchEx *dispex;
2386
2387         hres = IDispatch_QueryInterface(exprval.u.nameref.disp, &IID_IDispatchEx, (void**)&dispex);
2388         if(SUCCEEDED(hres)) {
2389             hres = IDispatchEx_DeleteMemberByName(dispex, exprval.u.nameref.name,
2390                     make_grfdex(ctx, fdexNameCaseSensitive));
2391             b = VARIANT_TRUE;
2392             IDispatchEx_Release(dispex);
2393         }
2394         break;
2395     }
2396     default:
2397         FIXME("unsupported type %d\n", exprval.type);
2398         hres = E_NOTIMPL;
2399     }
2400
2401     exprval_release(&exprval);
2402     if(FAILED(hres))
2403         return hres;
2404
2405     return return_bool(ret, b);
2406 }
2407
2408 /* ECMA-262 3rd Edition    11.4.2 */
2409 HRESULT interp_void(exec_ctx_t *ctx)
2410 {
2411     VARIANT v;
2412
2413     TRACE("\n");
2414
2415     stack_popn(ctx, 1);
2416
2417     V_VT(&v) = VT_EMPTY;
2418     return stack_push(ctx, &v);
2419 }
2420
2421 /* ECMA-262 3rd Edition    11.4.3 */
2422 static HRESULT typeof_exprval(script_ctx_t *ctx, exprval_t *exprval, jsexcept_t *ei, const WCHAR **ret)
2423 {
2424     VARIANT val;
2425     HRESULT hres;
2426
2427     static const WCHAR booleanW[] = {'b','o','o','l','e','a','n',0};
2428     static const WCHAR functionW[] = {'f','u','n','c','t','i','o','n',0};
2429     static const WCHAR numberW[] = {'n','u','m','b','e','r',0};
2430     static const WCHAR objectW[] = {'o','b','j','e','c','t',0};
2431     static const WCHAR stringW[] = {'s','t','r','i','n','g',0};
2432     static const WCHAR undefinedW[] = {'u','n','d','e','f','i','n','e','d',0};
2433     static const WCHAR unknownW[] = {'u','n','k','n','o','w','n',0};
2434
2435     if(exprval->type == EXPRVAL_INVALID) {
2436         *ret = undefinedW;
2437         return S_OK;
2438     }
2439
2440     hres = exprval_to_value(ctx, exprval, ei, &val);
2441     if(FAILED(hres)) {
2442         if(exprval->type == EXPRVAL_IDREF) {
2443             *ret = unknownW;
2444             return S_OK;
2445         }
2446         return hres;
2447     }
2448
2449     switch(V_VT(&val)) {
2450     case VT_EMPTY:
2451         *ret = undefinedW;
2452         break;
2453     case VT_NULL:
2454         *ret = objectW;
2455         break;
2456     case VT_BOOL:
2457         *ret = booleanW;
2458         break;
2459     case VT_I4:
2460     case VT_R8:
2461         *ret = numberW;
2462         break;
2463     case VT_BSTR:
2464         *ret = stringW;
2465         break;
2466     case VT_DISPATCH: {
2467         jsdisp_t *dispex;
2468
2469         if(V_DISPATCH(&val) && (dispex = iface_to_jsdisp((IUnknown*)V_DISPATCH(&val)))) {
2470             *ret = is_class(dispex, JSCLASS_FUNCTION) ? functionW : objectW;
2471             jsdisp_release(dispex);
2472         }else {
2473             *ret = objectW;
2474         }
2475         break;
2476     }
2477     default:
2478         FIXME("unhandled vt %d\n", V_VT(&val));
2479         hres = E_NOTIMPL;
2480     }
2481
2482     VariantClear(&val);
2483     return hres;
2484 }
2485
2486 HRESULT typeof_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2487 {
2488     unary_expression_t *expr = (unary_expression_t*)_expr;
2489     const WCHAR *str = NULL;
2490     exprval_t exprval;
2491     HRESULT hres;
2492
2493     TRACE("\n");
2494
2495     hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
2496     if(FAILED(hres))
2497         return hres;
2498
2499     hres = typeof_exprval(ctx, &exprval, ei, &str);
2500     exprval_release(&exprval);
2501     if(FAILED(hres))
2502         return hres;
2503
2504     ret->type = EXPRVAL_VARIANT;
2505     V_VT(&ret->u.var) = VT_BSTR;
2506     V_BSTR(&ret->u.var) = SysAllocString(str);
2507     if(!V_BSTR(&ret->u.var))
2508         return E_OUTOFMEMORY;
2509
2510     return S_OK;
2511 }
2512
2513 /* ECMA-262 3rd Edition    11.4.7 */
2514 HRESULT interp_minus(exec_ctx_t *ctx)
2515 {
2516     VARIANT n;
2517     HRESULT hres;
2518
2519     TRACE("\n");
2520
2521     hres = stack_pop_number(ctx, &n);
2522     if(FAILED(hres))
2523         return hres;
2524
2525     return stack_push_number(ctx, -num_val(&n));
2526 }
2527
2528 /* ECMA-262 3rd Edition    11.4.6 */
2529 HRESULT interp_tonum(exec_ctx_t *ctx)
2530 {
2531     VARIANT *v, num;
2532     HRESULT hres;
2533
2534     TRACE("\n");
2535
2536     v = stack_pop(ctx);
2537     hres = to_number(ctx->parser->script, v, &ctx->ei, &num);
2538     VariantClear(v);
2539     if(FAILED(hres))
2540         return hres;
2541
2542     return stack_push(ctx, &num);
2543 }
2544
2545 /* ECMA-262 3rd Edition    11.3.1 */
2546 HRESULT post_increment_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2547 {
2548     unary_expression_t *expr = (unary_expression_t*)_expr;
2549     VARIANT val, num;
2550     exprval_t exprval;
2551     HRESULT hres;
2552
2553     TRACE("\n");
2554
2555     hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval);
2556     if(FAILED(hres))
2557         return hres;
2558
2559     hres = exprval_value(ctx, &exprval, ei, &val);
2560     if(SUCCEEDED(hres)) {
2561         hres = to_number(ctx, &val, ei, &num);
2562         VariantClear(&val);
2563     }
2564
2565     if(SUCCEEDED(hres)) {
2566         VARIANT inc;
2567         num_set_val(&inc, num_val(&num)+1.0);
2568         hres = put_value(ctx, &exprval, &inc, ei);
2569     }
2570
2571     exprval_release(&exprval);
2572     if(FAILED(hres))
2573         return hres;
2574
2575     ret->type = EXPRVAL_VARIANT;
2576     ret->u.var = num;
2577     return S_OK;
2578 }
2579
2580 /* ECMA-262 3rd Edition    11.3.2 */
2581 HRESULT post_decrement_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2582 {
2583     unary_expression_t *expr = (unary_expression_t*)_expr;
2584     VARIANT val, num;
2585     exprval_t exprval;
2586     HRESULT hres;
2587
2588     TRACE("\n");
2589
2590     hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval);
2591     if(FAILED(hres))
2592         return hres;
2593
2594     hres = exprval_value(ctx, &exprval, ei, &val);
2595     if(SUCCEEDED(hres)) {
2596         hres = to_number(ctx, &val, ei, &num);
2597         VariantClear(&val);
2598     }
2599
2600     if(SUCCEEDED(hres)) {
2601         VARIANT dec;
2602         num_set_val(&dec, num_val(&num)-1.0);
2603         hres = put_value(ctx, &exprval, &dec, ei);
2604     }
2605
2606     exprval_release(&exprval);
2607     if(FAILED(hres))
2608         return hres;
2609
2610     ret->type = EXPRVAL_VARIANT;
2611     ret->u.var = num;
2612     return S_OK;
2613 }
2614
2615 /* ECMA-262 3rd Edition    11.4.4 */
2616 HRESULT pre_increment_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2617 {
2618     unary_expression_t *expr = (unary_expression_t*)_expr;
2619     VARIANT val, num;
2620     exprval_t exprval;
2621     HRESULT hres;
2622
2623     TRACE("\n");
2624
2625     hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval);
2626     if(FAILED(hres))
2627         return hres;
2628
2629     hres = exprval_value(ctx, &exprval, ei, &val);
2630     if(SUCCEEDED(hres)) {
2631         hres = to_number(ctx, &val, ei, &num);
2632         VariantClear(&val);
2633     }
2634
2635     if(SUCCEEDED(hres)) {
2636         num_set_val(&val, num_val(&num)+1.0);
2637         hres = put_value(ctx, &exprval, &val, ei);
2638     }
2639
2640     exprval_release(&exprval);
2641     if(FAILED(hres))
2642         return hres;
2643
2644     ret->type = EXPRVAL_VARIANT;
2645     ret->u.var = val;
2646     return S_OK;
2647 }
2648
2649 /* ECMA-262 3rd Edition    11.4.5 */
2650 HRESULT pre_decrement_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2651 {
2652     unary_expression_t *expr = (unary_expression_t*)_expr;
2653     VARIANT val, num;
2654     exprval_t exprval;
2655     HRESULT hres;
2656
2657     TRACE("\n");
2658
2659     hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval);
2660     if(FAILED(hres))
2661         return hres;
2662
2663     hres = exprval_value(ctx, &exprval, ei, &val);
2664     if(SUCCEEDED(hres)) {
2665         hres = to_number(ctx, &val, ei, &num);
2666         VariantClear(&val);
2667     }
2668
2669     if(SUCCEEDED(hres)) {
2670         num_set_val(&val, num_val(&num)-1.0);
2671         hres = put_value(ctx, &exprval, &val, ei);
2672     }
2673
2674     exprval_release(&exprval);
2675     if(FAILED(hres))
2676         return hres;
2677
2678     ret->type = EXPRVAL_VARIANT;
2679     ret->u.var = val;
2680     return S_OK;
2681 }
2682
2683 /* ECMA-262 3rd Edition    11.9.3 */
2684 static HRESULT equal_values(script_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, BOOL *ret)
2685 {
2686     if(V_VT(lval) == V_VT(rval) || (is_num_vt(V_VT(lval)) && is_num_vt(V_VT(rval))))
2687        return equal2_values(lval, rval, ret);
2688
2689     /* FIXME: NULL disps should be handled in more general way */
2690     if(V_VT(lval) == VT_DISPATCH && !V_DISPATCH(lval)) {
2691         VARIANT v;
2692         V_VT(&v) = VT_NULL;
2693         return equal_values(ctx, &v, rval, ei, ret);
2694     }
2695
2696     if(V_VT(rval) == VT_DISPATCH && !V_DISPATCH(rval)) {
2697         VARIANT v;
2698         V_VT(&v) = VT_NULL;
2699         return equal_values(ctx, lval, &v, ei, ret);
2700     }
2701
2702     if((V_VT(lval) == VT_NULL && V_VT(rval) == VT_EMPTY) ||
2703        (V_VT(lval) == VT_EMPTY && V_VT(rval) == VT_NULL)) {
2704         *ret = TRUE;
2705         return S_OK;
2706     }
2707
2708     if(V_VT(lval) == VT_BSTR && is_num_vt(V_VT(rval))) {
2709         VARIANT v;
2710         HRESULT hres;
2711
2712         hres = to_number(ctx, lval, ei, &v);
2713         if(FAILED(hres))
2714             return hres;
2715
2716         return equal_values(ctx, &v, rval, ei, ret);
2717     }
2718
2719     if(V_VT(rval) == VT_BSTR && is_num_vt(V_VT(lval))) {
2720         VARIANT v;
2721         HRESULT hres;
2722
2723         hres = to_number(ctx, rval, ei, &v);
2724         if(FAILED(hres))
2725             return hres;
2726
2727         return equal_values(ctx, lval, &v, ei, ret);
2728     }
2729
2730     if(V_VT(rval) == VT_BOOL) {
2731         VARIANT v;
2732
2733         V_VT(&v) = VT_I4;
2734         V_I4(&v) = V_BOOL(rval) ? 1 : 0;
2735         return equal_values(ctx, lval, &v, ei, ret);
2736     }
2737
2738     if(V_VT(lval) == VT_BOOL) {
2739         VARIANT v;
2740
2741         V_VT(&v) = VT_I4;
2742         V_I4(&v) = V_BOOL(lval) ? 1 : 0;
2743         return equal_values(ctx, &v, rval, ei, ret);
2744     }
2745
2746
2747     if(V_VT(rval) == VT_DISPATCH && (V_VT(lval) == VT_BSTR || is_num_vt(V_VT(lval)))) {
2748         VARIANT v;
2749         HRESULT hres;
2750
2751         hres = to_primitive(ctx, rval, ei, &v, NO_HINT);
2752         if(FAILED(hres))
2753             return hres;
2754
2755         hres = equal_values(ctx, lval, &v, ei, ret);
2756
2757         VariantClear(&v);
2758         return hres;
2759     }
2760
2761
2762     if(V_VT(lval) == VT_DISPATCH && (V_VT(rval) == VT_BSTR || is_num_vt(V_VT(rval)))) {
2763         VARIANT v;
2764         HRESULT hres;
2765
2766         hres = to_primitive(ctx, lval, ei, &v, NO_HINT);
2767         if(FAILED(hres))
2768             return hres;
2769
2770         hres = equal_values(ctx, &v, rval, ei, ret);
2771
2772         VariantClear(&v);
2773         return hres;
2774     }
2775
2776
2777     *ret = FALSE;
2778     return S_OK;
2779 }
2780
2781 /* ECMA-262 3rd Edition    11.9.1 */
2782 HRESULT interp_eq(exec_ctx_t *ctx)
2783 {
2784     VARIANT *l, *r;
2785     BOOL b;
2786     HRESULT hres;
2787
2788     r = stack_pop(ctx);
2789     l = stack_pop(ctx);
2790
2791     TRACE("%s == %s\n", debugstr_variant(l), debugstr_variant(r));
2792
2793     hres = equal_values(ctx->parser->script, l, r, &ctx->ei, &b);
2794     VariantClear(l);
2795     VariantClear(r);
2796     if(FAILED(hres))
2797         return hres;
2798
2799     return stack_push_bool(ctx, b);
2800 }
2801
2802 /* ECMA-262 3rd Edition    11.9.2 */
2803 HRESULT interp_neq(exec_ctx_t *ctx)
2804 {
2805     VARIANT *l, *r;
2806     BOOL b;
2807     HRESULT hres;
2808
2809     r = stack_pop(ctx);
2810     l = stack_pop(ctx);
2811
2812     TRACE("%s != %s\n", debugstr_variant(l), debugstr_variant(r));
2813
2814     hres = equal_values(ctx->parser->script, l, r, &ctx->ei, &b);
2815     VariantClear(l);
2816     VariantClear(r);
2817     if(FAILED(hres))
2818         return hres;
2819
2820     return stack_push_bool(ctx, !b);
2821 }
2822
2823 /* ECMA-262 3rd Edition    11.9.4 */
2824 static HRESULT interp_eq2(exec_ctx_t *ctx)
2825 {
2826     VARIANT *l, *r;
2827     BOOL b;
2828     HRESULT hres;
2829
2830     TRACE("\n");
2831
2832     r = stack_pop(ctx);
2833     l = stack_pop(ctx);
2834
2835     hres = equal2_values(r, l, &b);
2836     VariantClear(l);
2837     VariantClear(r);
2838     if(FAILED(hres))
2839         return hres;
2840
2841     return stack_push_bool(ctx, b);
2842 }
2843
2844 /* ECMA-262 3rd Edition    11.9.5 */
2845 static HRESULT interp_neq2(exec_ctx_t *ctx)
2846 {
2847     VARIANT *l, *r;
2848     BOOL b;
2849     HRESULT hres;
2850
2851     TRACE("\n");
2852
2853     r = stack_pop(ctx);
2854     l = stack_pop(ctx);
2855
2856     hres = equal2_values(r, l, &b);
2857     VariantClear(l);
2858     VariantClear(r);
2859     if(FAILED(hres))
2860         return hres;
2861
2862     return stack_push_bool(ctx, !b);
2863 }
2864
2865 /* ECMA-262 3rd Edition    11.8.5 */
2866 static HRESULT less_eval(script_ctx_t *ctx, VARIANT *lval, VARIANT *rval, BOOL greater, jsexcept_t *ei, BOOL *ret)
2867 {
2868     VARIANT l, r, ln, rn;
2869     HRESULT hres;
2870
2871     hres = to_primitive(ctx, lval, ei, &l, NO_HINT);
2872     if(FAILED(hres))
2873         return hres;
2874
2875     hres = to_primitive(ctx, rval, ei, &r, NO_HINT);
2876     if(FAILED(hres)) {
2877         VariantClear(&l);
2878         return hres;
2879     }
2880
2881     if(V_VT(&l) == VT_BSTR && V_VT(&r) == VT_BSTR) {
2882         *ret = (strcmpW(V_BSTR(&l), V_BSTR(&r)) < 0) ^ greater;
2883         SysFreeString(V_BSTR(&l));
2884         SysFreeString(V_BSTR(&r));
2885         return S_OK;
2886     }
2887
2888     hres = to_number(ctx, &l, ei, &ln);
2889     VariantClear(&l);
2890     if(SUCCEEDED(hres))
2891         hres = to_number(ctx, &r, ei, &rn);
2892     VariantClear(&r);
2893     if(FAILED(hres))
2894         return hres;
2895
2896     if(V_VT(&ln) == VT_I4 && V_VT(&rn) == VT_I4) {
2897         *ret = (V_I4(&ln) < V_I4(&rn)) ^ greater;
2898     }else  {
2899         DOUBLE ld = num_val(&ln);
2900         DOUBLE rd = num_val(&rn);
2901
2902         *ret = !isnan(ld) && !isnan(rd) && ((ld < rd) ^ greater);
2903     }
2904
2905     return S_OK;
2906 }
2907
2908 /* ECMA-262 3rd Edition    11.8.1 */
2909 HRESULT less_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2910 {
2911     binary_expression_t *expr = (binary_expression_t*)_expr;
2912     VARIANT rval, lval;
2913     BOOL b;
2914     HRESULT hres;
2915
2916     TRACE("\n");
2917
2918     hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval);
2919     if(FAILED(hres))
2920         return hres;
2921
2922     hres = less_eval(ctx, &lval, &rval, FALSE, ei, &b);
2923     VariantClear(&lval);
2924     VariantClear(&rval);
2925     if(FAILED(hres))
2926         return hres;
2927
2928     return return_bool(ret, b);
2929 }
2930
2931 /* ECMA-262 3rd Edition    11.8.3 */
2932 HRESULT lesseq_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2933 {
2934     binary_expression_t *expr = (binary_expression_t*)_expr;
2935     VARIANT rval, lval;
2936     BOOL b;
2937     HRESULT hres;
2938
2939     TRACE("\n");
2940
2941     hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval);
2942     if(FAILED(hres))
2943         return hres;
2944
2945     hres = less_eval(ctx, &rval, &lval, TRUE, ei, &b);
2946     VariantClear(&lval);
2947     VariantClear(&rval);
2948     if(FAILED(hres))
2949         return hres;
2950
2951     return return_bool(ret, b);
2952 }
2953
2954 /* ECMA-262 3rd Edition    11.8.2 */
2955 HRESULT greater_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2956 {
2957     binary_expression_t *expr = (binary_expression_t*)_expr;
2958     VARIANT rval, lval;
2959     BOOL b;
2960     HRESULT hres;
2961
2962     TRACE("\n");
2963
2964     hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval);
2965     if(FAILED(hres))
2966         return hres;
2967
2968     hres = less_eval(ctx, &rval, &lval, FALSE, ei, &b);
2969     VariantClear(&lval);
2970     VariantClear(&rval);
2971     if(FAILED(hres))
2972         return hres;
2973
2974     return return_bool(ret, b);
2975 }
2976
2977 /* ECMA-262 3rd Edition    11.8.4 */
2978 HRESULT greatereq_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2979 {
2980     binary_expression_t *expr = (binary_expression_t*)_expr;
2981     VARIANT rval, lval;
2982     BOOL b;
2983     HRESULT hres;
2984
2985     TRACE("\n");
2986
2987     hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval);
2988     if(FAILED(hres))
2989         return hres;
2990
2991     hres = less_eval(ctx, &lval, &rval, TRUE, ei, &b);
2992     VariantClear(&lval);
2993     VariantClear(&rval);
2994     if(FAILED(hres))
2995         return hres;
2996
2997     return return_bool(ret, b);
2998 }
2999
3000 /* ECMA-262 3rd Edition    11.4.8 */
3001 HRESULT interp_bneg(exec_ctx_t *ctx)
3002 {
3003     VARIANT *v, r;
3004     INT i;
3005     HRESULT hres;
3006
3007     TRACE("\n");
3008
3009     v = stack_pop(ctx);
3010     hres = to_int32(ctx->parser->script, v, &ctx->ei, &i);
3011     VariantClear(v);
3012     if(FAILED(hres))
3013         return hres;
3014
3015     V_VT(&r) = VT_I4;
3016     V_I4(&r) = ~i;
3017     return stack_push(ctx, &r);
3018 }
3019
3020 /* ECMA-262 3rd Edition    11.4.9 */
3021 HRESULT interp_neg(exec_ctx_t *ctx)
3022 {
3023     VARIANT *v;
3024     VARIANT_BOOL b;
3025     HRESULT hres;
3026
3027     TRACE("\n");
3028
3029     v = stack_pop(ctx);
3030     hres = to_boolean(v, &b);
3031     VariantClear(v);
3032     if(FAILED(hres))
3033         return hres;
3034
3035     return stack_push_bool(ctx, !b);
3036 }
3037
3038 /* ECMA-262 3rd Edition    11.7.1 */
3039 static HRESULT lshift_eval(script_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
3040 {
3041     DWORD ri;
3042     INT li;
3043     HRESULT hres;
3044
3045     hres = to_int32(ctx, lval, ei, &li);
3046     if(FAILED(hres))
3047         return hres;
3048
3049     hres = to_uint32(ctx, rval, ei, &ri);
3050     if(FAILED(hres))
3051         return hres;
3052
3053     V_VT(retv) = VT_I4;
3054     V_I4(retv) = li << (ri&0x1f);
3055     return S_OK;
3056 }
3057
3058 /* ECMA-262 3rd Edition    11.7.1 */
3059 HRESULT left_shift_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3060 {
3061     binary_expression_t *expr = (binary_expression_t*)_expr;
3062
3063     TRACE("\n");
3064
3065     return binary_expr_eval(ctx, expr, lshift_eval, ei, ret);
3066 }
3067
3068 /* ECMA-262 3rd Edition    11.7.2 */
3069 static HRESULT rshift_eval(script_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
3070 {
3071     DWORD ri;
3072     INT li;
3073     HRESULT hres;
3074
3075     hres = to_int32(ctx, lval, ei, &li);
3076     if(FAILED(hres))
3077         return hres;
3078
3079     hres = to_uint32(ctx, rval, ei, &ri);
3080     if(FAILED(hres))
3081         return hres;
3082
3083     V_VT(retv) = VT_I4;
3084     V_I4(retv) = li >> (ri&0x1f);
3085     return S_OK;
3086 }
3087
3088 /* ECMA-262 3rd Edition    11.7.2 */
3089 HRESULT right_shift_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3090 {
3091     binary_expression_t *expr = (binary_expression_t*)_expr;
3092
3093     TRACE("\n");
3094
3095     return binary_expr_eval(ctx, expr, rshift_eval, ei, ret);
3096 }
3097
3098 /* ECMA-262 3rd Edition    11.7.3 */
3099 static HRESULT rshift2_eval(script_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
3100 {
3101     DWORD li, ri;
3102     HRESULT hres;
3103
3104     hres = to_uint32(ctx, lval, ei, &li);
3105     if(FAILED(hres))
3106         return hres;
3107
3108     hres = to_uint32(ctx, rval, ei, &ri);
3109     if(FAILED(hres))
3110         return hres;
3111
3112     V_VT(retv) = VT_I4;
3113     V_I4(retv) = li >> (ri&0x1f);
3114     return S_OK;
3115 }
3116
3117 /* ECMA-262 3rd Edition    11.7.3 */
3118 HRESULT right2_shift_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3119 {
3120     binary_expression_t *expr = (binary_expression_t*)_expr;
3121
3122     TRACE("\n");
3123
3124     return binary_expr_eval(ctx, expr, rshift2_eval, ei, ret);
3125 }
3126
3127 /* ECMA-262 3rd Edition    11.13.1 */
3128 HRESULT assign_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3129 {
3130     binary_expression_t *expr = (binary_expression_t*)_expr;
3131     exprval_t exprval, exprvalr;
3132     VARIANT rval;
3133     HRESULT hres;
3134
3135     TRACE("\n");
3136
3137     hres = expr_eval(ctx, expr->expression1, EXPR_NEWREF, ei, &exprval);
3138     if(FAILED(hres))
3139         return hres;
3140
3141     hres = expr_eval(ctx, expr->expression2, 0, ei, &exprvalr);
3142     if(SUCCEEDED(hres)) {
3143         hres = exprval_to_value(ctx, &exprvalr, ei, &rval);
3144         exprval_release(&exprvalr);
3145     }
3146
3147     if(SUCCEEDED(hres)) {
3148         hres = put_value(ctx, &exprval, &rval, ei);
3149         if(FAILED(hres))
3150             VariantClear(&rval);
3151     }
3152
3153     exprval_release(&exprval);
3154     if(FAILED(hres))
3155         return hres;
3156
3157     ret->type = EXPRVAL_VARIANT;
3158     ret->u.var = rval;
3159     return S_OK;
3160 }
3161
3162 /* ECMA-262 3rd Edition    11.13.2 */
3163 HRESULT assign_lshift_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 assign_oper_eval(ctx, expr->expression1, expr->expression2, lshift_eval, ei, ret);
3170 }
3171
3172 /* ECMA-262 3rd Edition    11.13.2 */
3173 HRESULT assign_rshift_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
3177     TRACE("\n");
3178
3179     return assign_oper_eval(ctx, expr->expression1, expr->expression2, rshift_eval, ei, ret);
3180 }
3181
3182 /* ECMA-262 3rd Edition    11.13.2 */
3183 HRESULT assign_rrshift_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3184 {
3185     binary_expression_t *expr = (binary_expression_t*)_expr;
3186
3187     TRACE("\n");
3188
3189     return assign_oper_eval(ctx, expr->expression1, expr->expression2, rshift2_eval, ei, ret);
3190 }
3191
3192 /* ECMA-262 3rd Edition    11.13.2 */
3193 HRESULT assign_add_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3194 {
3195     binary_expression_t *expr = (binary_expression_t*)_expr;
3196
3197     TRACE("\n");
3198
3199     return assign_oper_eval(ctx, expr->expression1, expr->expression2, add_eval, ei, ret);
3200 }
3201
3202 /* ECMA-262 3rd Edition    11.13.2 */
3203 HRESULT assign_sub_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3204 {
3205     binary_expression_t *expr = (binary_expression_t*)_expr;
3206
3207     TRACE("\n");
3208
3209     return assign_oper_eval(ctx, expr->expression1, expr->expression2, sub_eval, ei, ret);
3210 }
3211
3212 /* ECMA-262 3rd Edition    11.13.2 */
3213 HRESULT assign_mul_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3214 {
3215     binary_expression_t *expr = (binary_expression_t*)_expr;
3216
3217     TRACE("\n");
3218
3219     return assign_oper_eval(ctx, expr->expression1, expr->expression2, mul_eval, ei, ret);
3220 }
3221
3222 /* ECMA-262 3rd Edition    11.13.2 */
3223 HRESULT assign_div_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3224 {
3225     binary_expression_t *expr = (binary_expression_t*)_expr;
3226
3227     TRACE("\n");
3228
3229     return assign_oper_eval(ctx, expr->expression1, expr->expression2, div_eval, ei, ret);
3230 }
3231
3232 /* ECMA-262 3rd Edition    11.13.2 */
3233 HRESULT assign_mod_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3234 {
3235     binary_expression_t *expr = (binary_expression_t*)_expr;
3236
3237     TRACE("\n");
3238
3239     return assign_oper_eval(ctx, expr->expression1, expr->expression2, mod_eval, ei, ret);
3240 }
3241
3242 /* ECMA-262 3rd Edition    11.13.2 */
3243 HRESULT assign_and_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3244 {
3245     binary_expression_t *expr = (binary_expression_t*)_expr;
3246
3247     TRACE("\n");
3248
3249     return assign_oper_eval(ctx, expr->expression1, expr->expression2, bitand_eval, ei, ret);
3250 }
3251
3252 /* ECMA-262 3rd Edition    11.13.2 */
3253 HRESULT assign_or_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3254 {
3255     binary_expression_t *expr = (binary_expression_t*)_expr;
3256
3257     TRACE("\n");
3258
3259     return assign_oper_eval(ctx, expr->expression1, expr->expression2, bitor_eval, ei, ret);
3260 }
3261
3262 /* ECMA-262 3rd Edition    11.13.2 */
3263 HRESULT assign_xor_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3264 {
3265     binary_expression_t *expr = (binary_expression_t*)_expr;
3266
3267     TRACE("\n");
3268
3269     return assign_oper_eval(ctx, expr->expression1, expr->expression2, xor_eval, ei, ret);
3270 }
3271
3272 HRESULT interp_jmp(exec_ctx_t *ctx)
3273 {
3274     const unsigned arg = ctx->parser->code->instrs[ctx->ip].arg1.uint;
3275
3276     TRACE("\n");
3277
3278     ctx->ip = arg;
3279     return S_OK;
3280 }
3281
3282 static HRESULT interp_pop(exec_ctx_t *ctx)
3283 {
3284     TRACE("\n");
3285
3286     stack_popn(ctx, 1);
3287     return S_OK;
3288 }
3289
3290 static HRESULT interp_ret(exec_ctx_t *ctx)
3291 {
3292     TRACE("\n");
3293
3294     ctx->ip = -1;
3295     return S_OK;
3296 }
3297
3298 static HRESULT interp_tree(exec_ctx_t *ctx)
3299 {
3300     instr_t *instr = ctx->parser->code->instrs+ctx->ip;
3301     exprval_t val;
3302     VARIANT v;
3303     HRESULT hres;
3304
3305     TRACE("\n");
3306
3307     hres = expr_eval(ctx->parser->script, instr->arg1.expr, 0, &ctx->ei, &val);
3308     if(FAILED(hres))
3309         return hres;
3310
3311     hres = exprval_to_value(ctx->parser->script, &val, &ctx->ei, &v);
3312     exprval_release(&val);
3313     if(FAILED(hres))
3314         return hres;
3315
3316     return stack_push(ctx, &v);
3317 }
3318
3319 typedef HRESULT (*op_func_t)(exec_ctx_t*);
3320
3321 static const op_func_t op_funcs[] = {
3322 #define X(x,a,b,c) interp_##x,
3323 OP_LIST
3324 #undef X
3325 };
3326
3327 static const unsigned op_move[] = {
3328 #define X(a,x,b,c) x,
3329 OP_LIST
3330 #undef X
3331 };
3332
3333 HRESULT interp_expression_eval(script_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3334 {
3335     exec_ctx_t *exec_ctx = ctx->exec_ctx;
3336     unsigned prev_ip, prev_top;
3337     jsop_t op;
3338     HRESULT hres = S_OK;
3339
3340     TRACE("\n");
3341
3342     prev_top = exec_ctx->top;
3343     prev_ip = exec_ctx->ip;
3344     exec_ctx->ip = expr->instr_off;
3345
3346     while(exec_ctx->ip != -1) {
3347         op = exec_ctx->parser->code->instrs[exec_ctx->ip].op;
3348         hres = op_funcs[op](exec_ctx);
3349         if(FAILED(hres))
3350             break;
3351         exec_ctx->ip += op_move[op];
3352     }
3353
3354     exec_ctx->ip = prev_ip;
3355
3356     if(FAILED(hres)) {
3357         stack_popn(exec_ctx, exec_ctx->top-prev_top);
3358         *ei = exec_ctx->ei;
3359         memset(&exec_ctx->ei, 0, sizeof(exec_ctx->ei));
3360         return hres;
3361     }
3362
3363     assert(exec_ctx->top == prev_top+1);
3364
3365     ret->type = EXPRVAL_VARIANT;
3366     ret->u.var = *stack_pop(exec_ctx);
3367     return S_OK;
3368 }
3369
3370 HRESULT compiled_expression_eval(script_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3371 {
3372     HRESULT hres;
3373
3374     TRACE("\n");
3375
3376     hres = compile_subscript(ctx->exec_ctx->parser, expr, &expr->instr_off);
3377     if(FAILED(hres))
3378         return hres;
3379
3380     return (expr->eval = interp_expression_eval)(ctx, expr, flags, ei, ret);
3381 }