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