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