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