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