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