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