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