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