jscript: Use bytecode for '-' expression implementation.
[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 minus_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2578 {
2579     unary_expression_t *expr = (unary_expression_t*)_expr;
2580     exprval_t exprval;
2581     VARIANT val, num;
2582     HRESULT hres;
2583
2584     TRACE("\n");
2585
2586     hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
2587     if(FAILED(hres))
2588         return hres;
2589
2590     hres = exprval_to_value(ctx, &exprval, ei, &val);
2591     exprval_release(&exprval);
2592     if(FAILED(hres))
2593         return hres;
2594
2595     hres = to_number(ctx, &val, ei, &num);
2596     VariantClear(&val);
2597     if(FAILED(hres))
2598         return hres;
2599
2600     ret->type = EXPRVAL_VARIANT;
2601     num_set_val(&ret->u.var, -num_val(&num));
2602     return S_OK;
2603 }
2604
2605 /* ECMA-262 3rd Edition    11.4.6 */
2606 HRESULT interp_tonum(exec_ctx_t *ctx)
2607 {
2608     VARIANT *v, num;
2609     HRESULT hres;
2610
2611     TRACE("\n");
2612
2613     v = stack_pop(ctx);
2614     hres = to_number(ctx->parser->script, v, &ctx->ei, &num);
2615     VariantClear(v);
2616     if(FAILED(hres))
2617         return hres;
2618
2619     return stack_push(ctx, &num);
2620 }
2621
2622 /* ECMA-262 3rd Edition    11.3.1 */
2623 HRESULT post_increment_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2624 {
2625     unary_expression_t *expr = (unary_expression_t*)_expr;
2626     VARIANT val, num;
2627     exprval_t exprval;
2628     HRESULT hres;
2629
2630     TRACE("\n");
2631
2632     hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval);
2633     if(FAILED(hres))
2634         return hres;
2635
2636     hres = exprval_value(ctx, &exprval, ei, &val);
2637     if(SUCCEEDED(hres)) {
2638         hres = to_number(ctx, &val, ei, &num);
2639         VariantClear(&val);
2640     }
2641
2642     if(SUCCEEDED(hres)) {
2643         VARIANT inc;
2644         num_set_val(&inc, num_val(&num)+1.0);
2645         hres = put_value(ctx, &exprval, &inc, ei);
2646     }
2647
2648     exprval_release(&exprval);
2649     if(FAILED(hres))
2650         return hres;
2651
2652     ret->type = EXPRVAL_VARIANT;
2653     ret->u.var = num;
2654     return S_OK;
2655 }
2656
2657 /* ECMA-262 3rd Edition    11.3.2 */
2658 HRESULT post_decrement_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2659 {
2660     unary_expression_t *expr = (unary_expression_t*)_expr;
2661     VARIANT val, num;
2662     exprval_t exprval;
2663     HRESULT hres;
2664
2665     TRACE("\n");
2666
2667     hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval);
2668     if(FAILED(hres))
2669         return hres;
2670
2671     hres = exprval_value(ctx, &exprval, ei, &val);
2672     if(SUCCEEDED(hres)) {
2673         hres = to_number(ctx, &val, ei, &num);
2674         VariantClear(&val);
2675     }
2676
2677     if(SUCCEEDED(hres)) {
2678         VARIANT dec;
2679         num_set_val(&dec, num_val(&num)-1.0);
2680         hres = put_value(ctx, &exprval, &dec, ei);
2681     }
2682
2683     exprval_release(&exprval);
2684     if(FAILED(hres))
2685         return hres;
2686
2687     ret->type = EXPRVAL_VARIANT;
2688     ret->u.var = num;
2689     return S_OK;
2690 }
2691
2692 /* ECMA-262 3rd Edition    11.4.4 */
2693 HRESULT pre_increment_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2694 {
2695     unary_expression_t *expr = (unary_expression_t*)_expr;
2696     VARIANT val, num;
2697     exprval_t exprval;
2698     HRESULT hres;
2699
2700     TRACE("\n");
2701
2702     hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval);
2703     if(FAILED(hres))
2704         return hres;
2705
2706     hres = exprval_value(ctx, &exprval, ei, &val);
2707     if(SUCCEEDED(hres)) {
2708         hres = to_number(ctx, &val, ei, &num);
2709         VariantClear(&val);
2710     }
2711
2712     if(SUCCEEDED(hres)) {
2713         num_set_val(&val, num_val(&num)+1.0);
2714         hres = put_value(ctx, &exprval, &val, ei);
2715     }
2716
2717     exprval_release(&exprval);
2718     if(FAILED(hres))
2719         return hres;
2720
2721     ret->type = EXPRVAL_VARIANT;
2722     ret->u.var = val;
2723     return S_OK;
2724 }
2725
2726 /* ECMA-262 3rd Edition    11.4.5 */
2727 HRESULT pre_decrement_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2728 {
2729     unary_expression_t *expr = (unary_expression_t*)_expr;
2730     VARIANT val, num;
2731     exprval_t exprval;
2732     HRESULT hres;
2733
2734     TRACE("\n");
2735
2736     hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval);
2737     if(FAILED(hres))
2738         return hres;
2739
2740     hres = exprval_value(ctx, &exprval, ei, &val);
2741     if(SUCCEEDED(hres)) {
2742         hres = to_number(ctx, &val, ei, &num);
2743         VariantClear(&val);
2744     }
2745
2746     if(SUCCEEDED(hres)) {
2747         num_set_val(&val, num_val(&num)-1.0);
2748         hres = put_value(ctx, &exprval, &val, ei);
2749     }
2750
2751     exprval_release(&exprval);
2752     if(FAILED(hres))
2753         return hres;
2754
2755     ret->type = EXPRVAL_VARIANT;
2756     ret->u.var = val;
2757     return S_OK;
2758 }
2759
2760 /* ECMA-262 3rd Edition    11.9.3 */
2761 static HRESULT equal_values(script_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, BOOL *ret)
2762 {
2763     if(V_VT(lval) == V_VT(rval) || (is_num_vt(V_VT(lval)) && is_num_vt(V_VT(rval))))
2764        return equal2_values(lval, rval, ret);
2765
2766     /* FIXME: NULL disps should be handled in more general way */
2767     if(V_VT(lval) == VT_DISPATCH && !V_DISPATCH(lval)) {
2768         VARIANT v;
2769         V_VT(&v) = VT_NULL;
2770         return equal_values(ctx, &v, rval, ei, ret);
2771     }
2772
2773     if(V_VT(rval) == VT_DISPATCH && !V_DISPATCH(rval)) {
2774         VARIANT v;
2775         V_VT(&v) = VT_NULL;
2776         return equal_values(ctx, lval, &v, ei, ret);
2777     }
2778
2779     if((V_VT(lval) == VT_NULL && V_VT(rval) == VT_EMPTY) ||
2780        (V_VT(lval) == VT_EMPTY && V_VT(rval) == VT_NULL)) {
2781         *ret = TRUE;
2782         return S_OK;
2783     }
2784
2785     if(V_VT(lval) == VT_BSTR && is_num_vt(V_VT(rval))) {
2786         VARIANT v;
2787         HRESULT hres;
2788
2789         hres = to_number(ctx, lval, ei, &v);
2790         if(FAILED(hres))
2791             return hres;
2792
2793         return equal_values(ctx, &v, rval, ei, ret);
2794     }
2795
2796     if(V_VT(rval) == VT_BSTR && is_num_vt(V_VT(lval))) {
2797         VARIANT v;
2798         HRESULT hres;
2799
2800         hres = to_number(ctx, rval, ei, &v);
2801         if(FAILED(hres))
2802             return hres;
2803
2804         return equal_values(ctx, lval, &v, ei, ret);
2805     }
2806
2807     if(V_VT(rval) == VT_BOOL) {
2808         VARIANT v;
2809
2810         V_VT(&v) = VT_I4;
2811         V_I4(&v) = V_BOOL(rval) ? 1 : 0;
2812         return equal_values(ctx, lval, &v, ei, ret);
2813     }
2814
2815     if(V_VT(lval) == VT_BOOL) {
2816         VARIANT v;
2817
2818         V_VT(&v) = VT_I4;
2819         V_I4(&v) = V_BOOL(lval) ? 1 : 0;
2820         return equal_values(ctx, &v, rval, ei, ret);
2821     }
2822
2823
2824     if(V_VT(rval) == VT_DISPATCH && (V_VT(lval) == VT_BSTR || is_num_vt(V_VT(lval)))) {
2825         VARIANT v;
2826         HRESULT hres;
2827
2828         hres = to_primitive(ctx, rval, ei, &v, NO_HINT);
2829         if(FAILED(hres))
2830             return hres;
2831
2832         hres = equal_values(ctx, lval, &v, ei, ret);
2833
2834         VariantClear(&v);
2835         return hres;
2836     }
2837
2838
2839     if(V_VT(lval) == VT_DISPATCH && (V_VT(rval) == VT_BSTR || is_num_vt(V_VT(rval)))) {
2840         VARIANT v;
2841         HRESULT hres;
2842
2843         hres = to_primitive(ctx, lval, ei, &v, NO_HINT);
2844         if(FAILED(hres))
2845             return hres;
2846
2847         hres = equal_values(ctx, &v, rval, ei, ret);
2848
2849         VariantClear(&v);
2850         return hres;
2851     }
2852
2853
2854     *ret = FALSE;
2855     return S_OK;
2856 }
2857
2858 /* ECMA-262 3rd Edition    11.9.1 */
2859 HRESULT equal_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2860 {
2861     binary_expression_t *expr = (binary_expression_t*)_expr;
2862     VARIANT rval, lval;
2863     BOOL b;
2864     HRESULT hres;
2865
2866     TRACE("\n");
2867
2868     hres = get_binary_expr_values(ctx, expr, ei, &rval, &lval);
2869     if(FAILED(hres))
2870         return hres;
2871
2872     hres = equal_values(ctx, &rval, &lval, ei, &b);
2873     VariantClear(&lval);
2874     VariantClear(&rval);
2875     if(FAILED(hres))
2876         return hres;
2877
2878     return return_bool(ret, b);
2879 }
2880
2881 /* ECMA-262 3rd Edition    11.9.4 */
2882 static HRESULT interp_eq2(exec_ctx_t *ctx)
2883 {
2884     VARIANT *l, *r;
2885     BOOL b;
2886     HRESULT hres;
2887
2888     TRACE("\n");
2889
2890     r = stack_pop(ctx);
2891     l = stack_pop(ctx);
2892
2893     hres = equal2_values(r, l, &b);
2894     VariantClear(l);
2895     VariantClear(r);
2896     if(FAILED(hres))
2897         return hres;
2898
2899     return stack_push_bool(ctx, b);
2900 }
2901
2902 /* ECMA-262 3rd Edition    11.9.2 */
2903 HRESULT not_equal_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2904 {
2905     binary_expression_t *expr = (binary_expression_t*)_expr;
2906     VARIANT rval, lval;
2907     BOOL b;
2908     HRESULT hres;
2909
2910     TRACE("\n");
2911
2912     hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval);
2913     if(FAILED(hres))
2914         return hres;
2915
2916     hres = equal_values(ctx, &lval, &rval, ei, &b);
2917     VariantClear(&lval);
2918     VariantClear(&rval);
2919     if(FAILED(hres))
2920         return hres;
2921
2922     return return_bool(ret, !b);
2923 }
2924
2925 /* ECMA-262 3rd Edition    11.9.5 */
2926 static HRESULT interp_neq2(exec_ctx_t *ctx)
2927 {
2928     VARIANT *l, *r;
2929     BOOL b;
2930     HRESULT hres;
2931
2932     TRACE("\n");
2933
2934     r = stack_pop(ctx);
2935     l = stack_pop(ctx);
2936
2937     hres = equal2_values(r, l, &b);
2938     VariantClear(l);
2939     VariantClear(r);
2940     if(FAILED(hres))
2941         return hres;
2942
2943     return stack_push_bool(ctx, !b);
2944 }
2945
2946 /* ECMA-262 3rd Edition    11.8.5 */
2947 static HRESULT less_eval(script_ctx_t *ctx, VARIANT *lval, VARIANT *rval, BOOL greater, jsexcept_t *ei, BOOL *ret)
2948 {
2949     VARIANT l, r, ln, rn;
2950     HRESULT hres;
2951
2952     hres = to_primitive(ctx, lval, ei, &l, NO_HINT);
2953     if(FAILED(hres))
2954         return hres;
2955
2956     hres = to_primitive(ctx, rval, ei, &r, NO_HINT);
2957     if(FAILED(hres)) {
2958         VariantClear(&l);
2959         return hres;
2960     }
2961
2962     if(V_VT(&l) == VT_BSTR && V_VT(&r) == VT_BSTR) {
2963         *ret = (strcmpW(V_BSTR(&l), V_BSTR(&r)) < 0) ^ greater;
2964         SysFreeString(V_BSTR(&l));
2965         SysFreeString(V_BSTR(&r));
2966         return S_OK;
2967     }
2968
2969     hres = to_number(ctx, &l, ei, &ln);
2970     VariantClear(&l);
2971     if(SUCCEEDED(hres))
2972         hres = to_number(ctx, &r, ei, &rn);
2973     VariantClear(&r);
2974     if(FAILED(hres))
2975         return hres;
2976
2977     if(V_VT(&ln) == VT_I4 && V_VT(&rn) == VT_I4) {
2978         *ret = (V_I4(&ln) < V_I4(&rn)) ^ greater;
2979     }else  {
2980         DOUBLE ld = num_val(&ln);
2981         DOUBLE rd = num_val(&rn);
2982
2983         *ret = !isnan(ld) && !isnan(rd) && ((ld < rd) ^ greater);
2984     }
2985
2986     return S_OK;
2987 }
2988
2989 /* ECMA-262 3rd Edition    11.8.1 */
2990 HRESULT less_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2991 {
2992     binary_expression_t *expr = (binary_expression_t*)_expr;
2993     VARIANT rval, lval;
2994     BOOL b;
2995     HRESULT hres;
2996
2997     TRACE("\n");
2998
2999     hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval);
3000     if(FAILED(hres))
3001         return hres;
3002
3003     hres = less_eval(ctx, &lval, &rval, FALSE, ei, &b);
3004     VariantClear(&lval);
3005     VariantClear(&rval);
3006     if(FAILED(hres))
3007         return hres;
3008
3009     return return_bool(ret, b);
3010 }
3011
3012 /* ECMA-262 3rd Edition    11.8.3 */
3013 HRESULT lesseq_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3014 {
3015     binary_expression_t *expr = (binary_expression_t*)_expr;
3016     VARIANT rval, lval;
3017     BOOL b;
3018     HRESULT hres;
3019
3020     TRACE("\n");
3021
3022     hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval);
3023     if(FAILED(hres))
3024         return hres;
3025
3026     hres = less_eval(ctx, &rval, &lval, TRUE, ei, &b);
3027     VariantClear(&lval);
3028     VariantClear(&rval);
3029     if(FAILED(hres))
3030         return hres;
3031
3032     return return_bool(ret, b);
3033 }
3034
3035 /* ECMA-262 3rd Edition    11.8.2 */
3036 HRESULT greater_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3037 {
3038     binary_expression_t *expr = (binary_expression_t*)_expr;
3039     VARIANT rval, lval;
3040     BOOL b;
3041     HRESULT hres;
3042
3043     TRACE("\n");
3044
3045     hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval);
3046     if(FAILED(hres))
3047         return hres;
3048
3049     hres = less_eval(ctx, &rval, &lval, FALSE, ei, &b);
3050     VariantClear(&lval);
3051     VariantClear(&rval);
3052     if(FAILED(hres))
3053         return hres;
3054
3055     return return_bool(ret, b);
3056 }
3057
3058 /* ECMA-262 3rd Edition    11.8.4 */
3059 HRESULT greatereq_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3060 {
3061     binary_expression_t *expr = (binary_expression_t*)_expr;
3062     VARIANT rval, lval;
3063     BOOL b;
3064     HRESULT hres;
3065
3066     TRACE("\n");
3067
3068     hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval);
3069     if(FAILED(hres))
3070         return hres;
3071
3072     hres = less_eval(ctx, &lval, &rval, TRUE, ei, &b);
3073     VariantClear(&lval);
3074     VariantClear(&rval);
3075     if(FAILED(hres))
3076         return hres;
3077
3078     return return_bool(ret, b);
3079 }
3080
3081 /* ECMA-262 3rd Edition    11.4.8 */
3082 HRESULT interp_bneg(exec_ctx_t *ctx)
3083 {
3084     VARIANT *v, r;
3085     INT i;
3086     HRESULT hres;
3087
3088     TRACE("\n");
3089
3090     v = stack_pop(ctx);
3091     hres = to_int32(ctx->parser->script, v, &ctx->ei, &i);
3092     VariantClear(v);
3093     if(FAILED(hres))
3094         return hres;
3095
3096     V_VT(&r) = VT_I4;
3097     V_I4(&r) = ~i;
3098     return stack_push(ctx, &r);
3099 }
3100
3101 /* ECMA-262 3rd Edition    11.4.9 */
3102 HRESULT interp_neg(exec_ctx_t *ctx)
3103 {
3104     VARIANT *v;
3105     VARIANT_BOOL b;
3106     HRESULT hres;
3107
3108     TRACE("\n");
3109
3110     v = stack_pop(ctx);
3111     hres = to_boolean(v, &b);
3112     VariantClear(v);
3113     if(FAILED(hres))
3114         return hres;
3115
3116     return stack_push_bool(ctx, !b);
3117 }
3118
3119 /* ECMA-262 3rd Edition    11.7.1 */
3120 static HRESULT lshift_eval(script_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
3121 {
3122     DWORD ri;
3123     INT li;
3124     HRESULT hres;
3125
3126     hres = to_int32(ctx, lval, ei, &li);
3127     if(FAILED(hres))
3128         return hres;
3129
3130     hres = to_uint32(ctx, rval, ei, &ri);
3131     if(FAILED(hres))
3132         return hres;
3133
3134     V_VT(retv) = VT_I4;
3135     V_I4(retv) = li << (ri&0x1f);
3136     return S_OK;
3137 }
3138
3139 /* ECMA-262 3rd Edition    11.7.1 */
3140 HRESULT left_shift_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3141 {
3142     binary_expression_t *expr = (binary_expression_t*)_expr;
3143
3144     TRACE("\n");
3145
3146     return binary_expr_eval(ctx, expr, lshift_eval, ei, ret);
3147 }
3148
3149 /* ECMA-262 3rd Edition    11.7.2 */
3150 static HRESULT rshift_eval(script_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
3151 {
3152     DWORD ri;
3153     INT li;
3154     HRESULT hres;
3155
3156     hres = to_int32(ctx, lval, ei, &li);
3157     if(FAILED(hres))
3158         return hres;
3159
3160     hres = to_uint32(ctx, rval, ei, &ri);
3161     if(FAILED(hres))
3162         return hres;
3163
3164     V_VT(retv) = VT_I4;
3165     V_I4(retv) = li >> (ri&0x1f);
3166     return S_OK;
3167 }
3168
3169 /* ECMA-262 3rd Edition    11.7.2 */
3170 HRESULT right_shift_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3171 {
3172     binary_expression_t *expr = (binary_expression_t*)_expr;
3173
3174     TRACE("\n");
3175
3176     return binary_expr_eval(ctx, expr, rshift_eval, ei, ret);
3177 }
3178
3179 /* ECMA-262 3rd Edition    11.7.3 */
3180 static HRESULT rshift2_eval(script_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
3181 {
3182     DWORD li, ri;
3183     HRESULT hres;
3184
3185     hres = to_uint32(ctx, lval, ei, &li);
3186     if(FAILED(hres))
3187         return hres;
3188
3189     hres = to_uint32(ctx, rval, ei, &ri);
3190     if(FAILED(hres))
3191         return hres;
3192
3193     V_VT(retv) = VT_I4;
3194     V_I4(retv) = li >> (ri&0x1f);
3195     return S_OK;
3196 }
3197
3198 /* ECMA-262 3rd Edition    11.7.3 */
3199 HRESULT right2_shift_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3200 {
3201     binary_expression_t *expr = (binary_expression_t*)_expr;
3202
3203     TRACE("\n");
3204
3205     return binary_expr_eval(ctx, expr, rshift2_eval, ei, ret);
3206 }
3207
3208 /* ECMA-262 3rd Edition    11.13.1 */
3209 HRESULT assign_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3210 {
3211     binary_expression_t *expr = (binary_expression_t*)_expr;
3212     exprval_t exprval, exprvalr;
3213     VARIANT rval;
3214     HRESULT hres;
3215
3216     TRACE("\n");
3217
3218     hres = expr_eval(ctx, expr->expression1, EXPR_NEWREF, ei, &exprval);
3219     if(FAILED(hres))
3220         return hres;
3221
3222     hres = expr_eval(ctx, expr->expression2, 0, ei, &exprvalr);
3223     if(SUCCEEDED(hres)) {
3224         hres = exprval_to_value(ctx, &exprvalr, ei, &rval);
3225         exprval_release(&exprvalr);
3226     }
3227
3228     if(SUCCEEDED(hres)) {
3229         hres = put_value(ctx, &exprval, &rval, ei);
3230         if(FAILED(hres))
3231             VariantClear(&rval);
3232     }
3233
3234     exprval_release(&exprval);
3235     if(FAILED(hres))
3236         return hres;
3237
3238     ret->type = EXPRVAL_VARIANT;
3239     ret->u.var = rval;
3240     return S_OK;
3241 }
3242
3243 /* ECMA-262 3rd Edition    11.13.2 */
3244 HRESULT assign_lshift_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3245 {
3246     binary_expression_t *expr = (binary_expression_t*)_expr;
3247
3248     TRACE("\n");
3249
3250     return assign_oper_eval(ctx, expr->expression1, expr->expression2, lshift_eval, ei, ret);
3251 }
3252
3253 /* ECMA-262 3rd Edition    11.13.2 */
3254 HRESULT assign_rshift_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3255 {
3256     binary_expression_t *expr = (binary_expression_t*)_expr;
3257
3258     TRACE("\n");
3259
3260     return assign_oper_eval(ctx, expr->expression1, expr->expression2, rshift_eval, ei, ret);
3261 }
3262
3263 /* ECMA-262 3rd Edition    11.13.2 */
3264 HRESULT assign_rrshift_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3265 {
3266     binary_expression_t *expr = (binary_expression_t*)_expr;
3267
3268     TRACE("\n");
3269
3270     return assign_oper_eval(ctx, expr->expression1, expr->expression2, rshift2_eval, ei, ret);
3271 }
3272
3273 /* ECMA-262 3rd Edition    11.13.2 */
3274 HRESULT assign_add_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3275 {
3276     binary_expression_t *expr = (binary_expression_t*)_expr;
3277
3278     TRACE("\n");
3279
3280     return assign_oper_eval(ctx, expr->expression1, expr->expression2, add_eval, ei, ret);
3281 }
3282
3283 /* ECMA-262 3rd Edition    11.13.2 */
3284 HRESULT assign_sub_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3285 {
3286     binary_expression_t *expr = (binary_expression_t*)_expr;
3287
3288     TRACE("\n");
3289
3290     return assign_oper_eval(ctx, expr->expression1, expr->expression2, sub_eval, ei, ret);
3291 }
3292
3293 /* ECMA-262 3rd Edition    11.13.2 */
3294 HRESULT assign_mul_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3295 {
3296     binary_expression_t *expr = (binary_expression_t*)_expr;
3297
3298     TRACE("\n");
3299
3300     return assign_oper_eval(ctx, expr->expression1, expr->expression2, mul_eval, ei, ret);
3301 }
3302
3303 /* ECMA-262 3rd Edition    11.13.2 */
3304 HRESULT assign_div_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3305 {
3306     binary_expression_t *expr = (binary_expression_t*)_expr;
3307
3308     TRACE("\n");
3309
3310     return assign_oper_eval(ctx, expr->expression1, expr->expression2, div_eval, ei, ret);
3311 }
3312
3313 /* ECMA-262 3rd Edition    11.13.2 */
3314 HRESULT assign_mod_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3315 {
3316     binary_expression_t *expr = (binary_expression_t*)_expr;
3317
3318     TRACE("\n");
3319
3320     return assign_oper_eval(ctx, expr->expression1, expr->expression2, mod_eval, ei, ret);
3321 }
3322
3323 /* ECMA-262 3rd Edition    11.13.2 */
3324 HRESULT assign_and_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3325 {
3326     binary_expression_t *expr = (binary_expression_t*)_expr;
3327
3328     TRACE("\n");
3329
3330     return assign_oper_eval(ctx, expr->expression1, expr->expression2, bitand_eval, ei, ret);
3331 }
3332
3333 /* ECMA-262 3rd Edition    11.13.2 */
3334 HRESULT assign_or_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3335 {
3336     binary_expression_t *expr = (binary_expression_t*)_expr;
3337
3338     TRACE("\n");
3339
3340     return assign_oper_eval(ctx, expr->expression1, expr->expression2, bitor_eval, ei, ret);
3341 }
3342
3343 /* ECMA-262 3rd Edition    11.13.2 */
3344 HRESULT assign_xor_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3345 {
3346     binary_expression_t *expr = (binary_expression_t*)_expr;
3347
3348     TRACE("\n");
3349
3350     return assign_oper_eval(ctx, expr->expression1, expr->expression2, xor_eval, ei, ret);
3351 }
3352
3353 static HRESULT interp_pop(exec_ctx_t *ctx)
3354 {
3355     TRACE("\n");
3356
3357     stack_popn(ctx, 1);
3358     return S_OK;
3359 }
3360
3361 static HRESULT interp_ret(exec_ctx_t *ctx)
3362 {
3363     TRACE("\n");
3364
3365     ctx->ip = -1;
3366     return S_OK;
3367 }
3368
3369 static HRESULT interp_tree(exec_ctx_t *ctx)
3370 {
3371     instr_t *instr = ctx->parser->code->instrs+ctx->ip;
3372     exprval_t val;
3373     VARIANT v;
3374     HRESULT hres;
3375
3376     TRACE("\n");
3377
3378     hres = expr_eval(ctx->parser->script, instr->arg1.expr, 0, &ctx->ei, &val);
3379     if(FAILED(hres))
3380         return hres;
3381
3382     hres = exprval_to_value(ctx->parser->script, &val, &ctx->ei, &v);
3383     exprval_release(&val);
3384     if(FAILED(hres))
3385         return hres;
3386
3387     return stack_push(ctx, &v);
3388 }
3389
3390 typedef HRESULT (*op_func_t)(exec_ctx_t*);
3391
3392 static const op_func_t op_funcs[] = {
3393 #define X(x,a,b,c) interp_##x,
3394 OP_LIST
3395 #undef X
3396 };
3397
3398 static const unsigned op_move[] = {
3399 #define X(a,x,b,c) x,
3400 OP_LIST
3401 #undef X
3402 };
3403
3404 HRESULT interp_expression_eval(script_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3405 {
3406     exec_ctx_t *exec_ctx = ctx->exec_ctx;
3407     unsigned prev_ip, prev_top;
3408     jsop_t op;
3409     HRESULT hres = S_OK;
3410
3411     TRACE("\n");
3412
3413     prev_top = exec_ctx->top;
3414     prev_ip = exec_ctx->ip;
3415     exec_ctx->ip = expr->instr_off;
3416
3417     while(exec_ctx->ip != -1) {
3418         op = exec_ctx->parser->code->instrs[exec_ctx->ip].op;
3419         hres = op_funcs[op](exec_ctx);
3420         if(FAILED(hres))
3421             break;
3422         exec_ctx->ip += op_move[op];
3423     }
3424
3425     exec_ctx->ip = prev_ip;
3426
3427     if(FAILED(hres)) {
3428         stack_popn(exec_ctx, exec_ctx->top-prev_top);
3429         *ei = exec_ctx->ei;
3430         memset(&exec_ctx->ei, 0, sizeof(exec_ctx->ei));
3431         return hres;
3432     }
3433
3434     assert(exec_ctx->top == prev_top+1);
3435
3436     ret->type = EXPRVAL_VARIANT;
3437     ret->u.var = *stack_pop(exec_ctx);
3438     return S_OK;
3439 }
3440
3441 HRESULT compiled_expression_eval(script_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3442 {
3443     HRESULT hres;
3444
3445     TRACE("\n");
3446
3447     hres = compile_subscript(ctx->exec_ctx->parser, expr, &expr->instr_off);
3448     if(FAILED(hres))
3449         return hres;
3450
3451     return (expr->eval = interp_expression_eval)(ctx, expr, flags, ei, ret);
3452 }