jscript: Added postfix increment expression implementation.
[wine] / dlls / jscript / engine.c
1 /*
2  * Copyright 2008 Jacek Caban for CodeWeavers
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18
19 #include "jscript.h"
20 #include "engine.h"
21
22 #include "wine/debug.h"
23
24 WINE_DEFAULT_DEBUG_CHANNEL(jscript);
25
26 #define EXPR_NOVAL   0x0001
27 #define EXPR_NEWREF  0x0002
28 #define EXPR_STRREF  0x0004
29
30 static inline HRESULT stat_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
31 {
32     return stat->eval(ctx, stat, rt, ret);
33 }
34
35 static inline HRESULT expr_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
36 {
37     return _expr->eval(ctx, _expr, flags, ei, ret);
38 }
39
40 static void exprval_release(exprval_t *val)
41 {
42     switch(val->type) {
43     case EXPRVAL_VARIANT:
44         VariantClear(&val->u.var);
45         return;
46     case EXPRVAL_IDREF:
47         if(val->u.idref.disp)
48             IDispatch_Release(val->u.idref.disp);
49         return;
50     case EXPRVAL_NAMEREF:
51         if(val->u.nameref.disp)
52             IDispatch_Release(val->u.nameref.disp);
53         SysFreeString(val->u.nameref.name);
54     }
55 }
56
57 /* ECMA-262 3rd Edition    8.7.1 */
58 static HRESULT exprval_value(script_ctx_t *ctx, exprval_t *val, jsexcept_t *ei, VARIANT *ret)
59 {
60     V_VT(ret) = VT_EMPTY;
61
62     switch(val->type) {
63     case EXPRVAL_VARIANT:
64         return VariantCopy(ret, &val->u.var);
65     case EXPRVAL_IDREF:
66         if(!val->u.idref.disp) {
67             FIXME("throw ReferenceError\n");
68             return E_FAIL;
69         }
70
71         return disp_propget(val->u.idref.disp, val->u.idref.id, ctx->lcid, ret, ei, NULL/*FIXME*/);
72     default:
73         ERR("type %d\n", val->type);
74         return E_FAIL;
75     }
76 }
77
78 static HRESULT exprval_to_value(script_ctx_t *ctx, exprval_t *val, jsexcept_t *ei, VARIANT *ret)
79 {
80     if(val->type == EXPRVAL_VARIANT) {
81         *ret = val->u.var;
82         V_VT(&val->u.var) = VT_EMPTY;
83         return S_OK;
84     }
85
86     return exprval_value(ctx, val, ei, ret);
87 }
88
89 static HRESULT exprval_to_boolean(script_ctx_t *ctx, exprval_t *exprval, jsexcept_t *ei, VARIANT_BOOL *b)
90 {
91     if(exprval->type != EXPRVAL_VARIANT) {
92         VARIANT val;
93         HRESULT hres;
94
95         hres = exprval_to_value(ctx, exprval, ei, &val);
96         if(FAILED(hres))
97             return hres;
98
99         hres = to_boolean(&val, b);
100         VariantClear(&val);
101         return hres;
102     }
103
104     return to_boolean(&exprval->u.var, b);
105 }
106
107 static void exprval_init(exprval_t *val)
108 {
109     val->type = EXPRVAL_VARIANT;
110     V_VT(&val->u.var) = VT_EMPTY;
111 }
112
113 static void exprval_set_idref(exprval_t *val, IDispatch *disp, DISPID id)
114 {
115     val->type = EXPRVAL_IDREF;
116     val->u.idref.disp = disp;
117     val->u.idref.id = id;
118
119     if(disp)
120         IDispatch_AddRef(disp);
121 }
122
123 HRESULT scope_push(scope_chain_t *scope, DispatchEx *obj, scope_chain_t **ret)
124 {
125     scope_chain_t *new_scope;
126
127     new_scope = heap_alloc(sizeof(scope_chain_t));
128     if(!new_scope)
129         return E_OUTOFMEMORY;
130
131     new_scope->ref = 1;
132
133     IDispatchEx_AddRef(_IDispatchEx_(obj));
134     new_scope->obj = obj;
135
136     if(scope) {
137         scope_addref(scope);
138         new_scope->next = scope;
139     }else {
140         new_scope->next = NULL;
141     }
142
143     *ret = new_scope;
144     return S_OK;
145 }
146
147 void scope_release(scope_chain_t *scope)
148 {
149     if(--scope->ref)
150         return;
151
152     if(scope->next)
153         scope_release(scope->next);
154
155     IDispatchEx_Release(_IDispatchEx_(scope->obj));
156     heap_free(scope);
157 }
158
159 HRESULT create_exec_ctx(IDispatch *this_obj, DispatchEx *var_disp, scope_chain_t *scope, exec_ctx_t **ret)
160 {
161     exec_ctx_t *ctx;
162
163     ctx = heap_alloc_zero(sizeof(exec_ctx_t));
164     if(!ctx)
165         return E_OUTOFMEMORY;
166
167     IDispatch_AddRef(this_obj);
168     ctx->this_obj = this_obj;
169
170     IDispatchEx_AddRef(_IDispatchEx_(var_disp));
171     ctx->var_disp = var_disp;
172
173     if(scope) {
174         scope_addref(scope);
175         ctx->scope_chain = scope;
176     }
177
178     *ret = ctx;
179     return S_OK;
180 }
181
182 void exec_release(exec_ctx_t *ctx)
183 {
184     if(--ctx->ref)
185         return;
186
187     if(ctx->scope_chain)
188         scope_release(ctx->scope_chain);
189     if(ctx->var_disp)
190         IDispatchEx_Release(_IDispatchEx_(ctx->var_disp));
191     if(ctx->this_obj)
192         IDispatch_Release(ctx->this_obj);
193     heap_free(ctx);
194 }
195
196 static HRESULT dispex_get_id(IDispatchEx *dispex, BSTR name, DWORD flags, DISPID *id)
197 {
198     *id = 0;
199
200     return IDispatchEx_GetDispID(dispex, name, flags|fdexNameCaseSensitive, id);
201 }
202
203 static HRESULT disp_get_id(IDispatch *disp, BSTR name, DWORD flags, DISPID *id)
204 {
205     IDispatchEx *dispex;
206     HRESULT hres;
207
208     hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
209     if(FAILED(hres)) {
210         TRACE("unsing IDispatch\n");
211
212         *id = 0;
213         return IDispatch_GetIDsOfNames(disp, &IID_NULL, &name, 1, 0, id);
214     }
215
216     hres = dispex_get_id(dispex, name, flags, id);
217     IDispatchEx_Release(dispex);
218     return hres;
219 }
220
221 /* ECMA-262 3rd Edition    8.7.2 */
222 static HRESULT put_value(script_ctx_t *ctx, exprval_t *ref, VARIANT *v, jsexcept_t *ei)
223 {
224     if(ref->type != EXPRVAL_IDREF) {
225         FIXME("throw ReferemceError\n");
226         return E_FAIL;
227     }
228
229     return disp_propput(ref->u.idref.disp, ref->u.idref.id, ctx->lcid, v, ei, NULL/*FIXME*/);
230 }
231
232 static HRESULT disp_cmp(IDispatch *disp1, IDispatch *disp2, BOOL *ret)
233 {
234     IObjectIdentity *identity;
235     IUnknown *unk1, *unk2;
236     HRESULT hres;
237
238     if(disp1 == disp2) {
239         *ret = TRUE;
240         return S_OK;
241     }
242
243     hres = IDispatch_QueryInterface(disp1, &IID_IUnknown, (void**)&unk1);
244     if(FAILED(hres))
245         return hres;
246
247     hres = IDispatch_QueryInterface(disp2, &IID_IUnknown, (void**)&unk2);
248     if(FAILED(hres)) {
249         IUnknown_Release(unk1);
250         return hres;
251     }
252
253     if(unk1 == unk2) {
254         *ret = TRUE;
255     }else {
256         hres = IUnknown_QueryInterface(unk1, &IID_IObjectIdentity, (void**)&identity);
257         if(SUCCEEDED(hres)) {
258             hres = IObjectIdentity_IsEqualObject(identity, unk2);
259             IObjectIdentity_Release(identity);
260             *ret = hres == S_OK;
261         }else {
262             *ret = FALSE;
263         }
264     }
265
266     IUnknown_Release(unk1);
267     IUnknown_Release(unk2);
268     return S_OK;
269 }
270
271 static inline BOOL is_num_vt(enum VARENUM vt)
272 {
273     return vt == VT_I4 || vt == VT_R8;
274 }
275
276 static inline DOUBLE num_val(const VARIANT *v)
277 {
278     return V_VT(v) == VT_I4 ? V_I4(v) : V_R8(v);
279 }
280
281 static inline void num_set_val(VARIANT *v, DOUBLE d)
282 {
283     if(d == (DOUBLE)(INT)d) {
284         V_VT(v) = VT_I4;
285         V_I4(v) = d;
286     }else {
287         V_VT(v) = VT_R8;
288         V_R8(v) = d;
289     }
290 }
291
292 /* ECMA-262 3rd Edition    11.9.6 */
293 HRESULT equal2_values(VARIANT *lval, VARIANT *rval, BOOL *ret)
294 {
295     TRACE("\n");
296
297     if(V_VT(lval) != V_VT(rval)) {
298         if(is_num_vt(V_VT(lval)) && is_num_vt(V_VT(rval))) {
299             *ret = num_val(lval) == num_val(rval);
300             return S_OK;
301         }
302
303         *ret = FALSE;
304         return S_OK;
305     }
306
307     switch(V_VT(lval)) {
308     case VT_EMPTY:
309     case VT_NULL:
310         *ret = VARIANT_TRUE;
311         break;
312     case VT_I4:
313         *ret = V_I4(lval) == V_I4(rval);
314         break;
315     case VT_R8:
316         *ret = V_R8(lval) == V_R8(rval);
317         break;
318     case VT_BSTR:
319         *ret = !strcmpW(V_BSTR(lval), V_BSTR(rval));
320         break;
321     case VT_DISPATCH:
322         return disp_cmp(V_DISPATCH(lval), V_DISPATCH(rval), ret);
323     case VT_BOOL:
324         *ret = !V_BOOL(lval) == !V_BOOL(rval);
325         break;
326     default:
327         FIXME("unimplemented vt %d\n", V_VT(lval));
328         return E_NOTIMPL;
329     }
330
331     return S_OK;
332 }
333
334 static HRESULT literal_to_var(literal_t *literal, VARIANT *v)
335 {
336     V_VT(v) = literal->vt;
337
338     switch(V_VT(v)) {
339     case VT_EMPTY:
340     case VT_NULL:
341         break;
342     case VT_I4:
343         V_I4(v) = literal->u.lval;
344         break;
345     case VT_R8:
346         V_R8(v) = literal->u.dval;
347         break;
348     case VT_BSTR:
349         V_BSTR(v) = SysAllocString(literal->u.wstr);
350         break;
351     case VT_BOOL:
352         V_BOOL(v) = literal->u.bval;
353         break;
354     case VT_DISPATCH:
355         IDispatch_AddRef(literal->u.disp);
356         V_DISPATCH(v) = literal->u.disp;
357         break;
358     default:
359         ERR("wrong type %d\n", V_VT(v));
360         return E_NOTIMPL;
361     }
362
363     return S_OK;
364 }
365
366 HRESULT exec_source(exec_ctx_t *ctx, parser_ctx_t *parser, source_elements_t *source, jsexcept_t *ei, VARIANT *retv)
367 {
368     script_ctx_t *script = parser->script;
369     function_declaration_t *func;
370     parser_ctx_t *prev_parser;
371     VARIANT val, tmp;
372     statement_t *stat;
373     exec_ctx_t *prev_ctx;
374     return_type_t rt;
375     HRESULT hres = S_OK;
376
377     for(func = source->functions; func; func = func->next) {
378         DispatchEx *func_obj;
379         VARIANT var;
380
381         hres = create_source_function(parser, func->parameter_list, func->source_elements, ctx->scope_chain, &func_obj);
382         if(FAILED(hres))
383             return hres;
384
385         V_VT(&var) = VT_DISPATCH;
386         V_DISPATCH(&var) = (IDispatch*)_IDispatchEx_(func_obj);
387         hres = jsdisp_propput_name(ctx->var_disp, func->identifier, script->lcid, &var, ei, NULL);
388         IDispatchEx_Release(_IDispatchEx_(func_obj));
389         if(FAILED(hres))
390             return hres;
391     }
392
393     prev_ctx = script->exec_ctx;
394     script->exec_ctx = ctx;
395
396     prev_parser = ctx->parser;
397     ctx->parser = parser;
398
399     V_VT(&val) = VT_EMPTY;
400     memset(&rt, 0, sizeof(rt));
401     rt.type = RT_NORMAL;
402
403     for(stat = source->statement; stat; stat = stat->next) {
404         hres = stat_eval(ctx, stat, &rt, &tmp);
405         if(FAILED(hres))
406             break;
407
408         VariantClear(&val);
409         val = tmp;
410         if(rt.type != RT_NORMAL)
411             break;
412     }
413
414     script->exec_ctx = prev_ctx;
415     ctx->parser = prev_parser;
416
417     if(rt.type != RT_NORMAL && rt.type != RT_RETURN) {
418         FIXME("wrong rt %d\n", rt.type);
419         hres = E_FAIL;
420     }
421
422     *ei = rt.ei;
423     if(FAILED(hres)) {
424         VariantClear(&val);
425         return hres;
426     }
427
428     if(retv)
429         *retv = val;
430     else
431         VariantClear(&val);
432     return S_OK;
433 }
434
435 /* ECMA-262 3rd Edition    10.1.4 */
436 static HRESULT identifier_eval(exec_ctx_t *ctx, BSTR identifier, DWORD flags, exprval_t *ret)
437 {
438     scope_chain_t *scope;
439     named_item_t *item;
440     DISPID id = 0;
441     HRESULT hres;
442
443     TRACE("%s\n", debugstr_w(identifier));
444
445     for(scope = ctx->scope_chain; scope; scope = scope->next) {
446         hres = dispex_get_id(_IDispatchEx_(scope->obj), identifier, 0, &id);
447         if(SUCCEEDED(hres))
448             break;
449     }
450
451     if(scope) {
452         exprval_set_idref(ret, (IDispatch*)_IDispatchEx_(scope->obj), id);
453         return S_OK;
454     }
455
456     hres = dispex_get_id(_IDispatchEx_(ctx->parser->script->global), identifier, 0, &id);
457     if(SUCCEEDED(hres)) {
458         exprval_set_idref(ret, (IDispatch*)_IDispatchEx_(ctx->parser->script->global), id);
459         return S_OK;
460     }
461
462     for(item = ctx->parser->script->named_items; item; item = item->next) {
463         hres = disp_get_id(item->disp, identifier, 0, &id);
464         if(SUCCEEDED(hres))
465             break;
466     }
467
468     if(item) {
469         exprval_set_idref(ret, (IDispatch*)item->disp, id);
470         return S_OK;
471     }
472
473     hres = dispex_get_id(_IDispatchEx_(ctx->parser->script->script_disp), identifier, 0, &id);
474     if(SUCCEEDED(hres)) {
475         exprval_set_idref(ret, (IDispatch*)_IDispatchEx_(ctx->parser->script->script_disp), id);
476         return S_OK;
477     }
478
479     if(flags & EXPR_NEWREF) {
480         hres = dispex_get_id(_IDispatchEx_(ctx->var_disp), identifier, fdexNameEnsure, &id);
481         if(FAILED(hres))
482             return hres;
483
484         exprval_set_idref(ret, (IDispatch*)_IDispatchEx_(ctx->var_disp), id);
485         return S_OK;
486     }
487
488     WARN("Could not find identifier %s\n", debugstr_w(identifier));
489     return E_FAIL;
490 }
491
492 /* ECMA-262 3rd Edition    12.1 */
493 HRESULT block_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
494 {
495     block_statement_t *stat = (block_statement_t*)_stat;
496     VARIANT val, tmp;
497     statement_t *iter;
498     HRESULT hres = S_OK;
499
500     TRACE("\n");
501
502     V_VT(&val) = VT_EMPTY;
503     for(iter = stat->stat_list; iter; iter = iter->next) {
504         hres = stat_eval(ctx, iter, rt, &tmp);
505         if(FAILED(hres))
506             break;
507
508         VariantClear(&val);
509         val = tmp;
510         if(rt->type != RT_NORMAL)
511             break;
512     }
513
514     if(FAILED(hres)) {
515         VariantClear(&val);
516         return hres;
517     }
518
519     *ret = val;
520     return S_OK;
521 }
522
523 /* ECMA-262 3rd Edition    12.2 */
524 static HRESULT variable_list_eval(exec_ctx_t *ctx, variable_declaration_t *var_list, jsexcept_t *ei)
525 {
526     variable_declaration_t *iter;
527     HRESULT hres;
528
529     for(iter = var_list; iter; iter = iter->next) {
530         VARIANT val;
531
532         if(iter->expr) {
533             exprval_t exprval;
534
535             hres = expr_eval(ctx, iter->expr, 0, ei, &exprval);
536             if(FAILED(hres))
537                 break;
538
539             hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
540             exprval_release(&exprval);
541             if(FAILED(hres))
542                 break;
543         }else {
544             V_VT(&val) = VT_EMPTY;
545         }
546
547         hres = jsdisp_propput_name(ctx->var_disp, iter->identifier, ctx->parser->script->lcid, &val, ei, NULL/*FIXME*/);
548         VariantClear(&val);
549         if(FAILED(hres))
550             break;
551     }
552
553     return hres;
554 }
555
556 /* ECMA-262 3rd Edition    12.2 */
557 HRESULT var_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
558 {
559     var_statement_t *stat = (var_statement_t*)_stat;
560     HRESULT hres;
561
562     TRACE("\n");
563
564     hres = variable_list_eval(ctx, stat->variable_list, &rt->ei);
565     if(FAILED(hres))
566         return hres;
567
568     V_VT(ret) = VT_EMPTY;
569     return S_OK;
570 }
571
572 /* ECMA-262 3rd Edition    12.3 */
573 HRESULT empty_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
574 {
575     TRACE("\n");
576
577     V_VT(ret) = VT_EMPTY;
578     return S_OK;
579 }
580
581 /* ECMA-262 3rd Edition    12.4 */
582 HRESULT expression_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
583 {
584     expression_statement_t *stat = (expression_statement_t*)_stat;
585     exprval_t exprval;
586     VARIANT val;
587     HRESULT hres;
588
589     TRACE("\n");
590
591     hres = expr_eval(ctx, stat->expr, EXPR_NOVAL, &rt->ei, &exprval);
592     if(FAILED(hres))
593         return hres;
594
595     hres = exprval_to_value(ctx->parser->script, &exprval, &rt->ei, &val);
596     exprval_release(&exprval);
597     if(FAILED(hres))
598         return hres;
599
600     *ret = val;
601     TRACE("= %s\n", debugstr_variant(ret));
602     return S_OK;
603 }
604
605 /* ECMA-262 3rd Edition    12.5 */
606 HRESULT if_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
607 {
608     if_statement_t *stat = (if_statement_t*)_stat;
609     exprval_t exprval;
610     VARIANT_BOOL b;
611     HRESULT hres;
612
613     TRACE("\n");
614
615     hres = expr_eval(ctx, stat->expr, 0, &rt->ei, &exprval);
616     if(FAILED(hres))
617         return hres;
618
619     hres = exprval_to_boolean(ctx->parser->script, &exprval, &rt->ei, &b);
620     exprval_release(&exprval);
621     if(FAILED(hres))
622         return hres;
623
624     if(b)
625         hres = stat_eval(ctx, stat->if_stat, rt, ret);
626     else if(stat->else_stat)
627         hres = stat_eval(ctx, stat->else_stat, rt, ret);
628     else
629         V_VT(ret) = VT_EMPTY;
630
631     return hres;
632 }
633
634 HRESULT dowhile_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
635 {
636     FIXME("\n");
637     return E_NOTIMPL;
638 }
639
640 HRESULT while_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
641 {
642     FIXME("\n");
643     return E_NOTIMPL;
644 }
645
646 HRESULT for_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
647 {
648     FIXME("\n");
649     return E_NOTIMPL;
650 }
651
652 HRESULT forin_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
653 {
654     FIXME("\n");
655     return E_NOTIMPL;
656 }
657
658 HRESULT continue_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
659 {
660     FIXME("\n");
661     return E_NOTIMPL;
662 }
663
664 HRESULT break_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
665 {
666     FIXME("\n");
667     return E_NOTIMPL;
668 }
669
670 /* ECMA-262 3rd Edition    12.9 */
671 HRESULT return_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
672 {
673     expression_statement_t *stat = (expression_statement_t*)_stat;
674     HRESULT hres;
675
676     TRACE("\n");
677
678     if(stat->expr) {
679         exprval_t exprval;
680
681         hres = expr_eval(ctx, stat->expr, 0, &rt->ei, &exprval);
682         if(FAILED(hres))
683             return hres;
684
685         hres = exprval_to_value(ctx->parser->script, &exprval, &rt->ei, ret);
686         exprval_release(&exprval);
687         if(FAILED(hres))
688             return hres;
689     }else {
690         V_VT(ret) = VT_EMPTY;
691     }
692
693     TRACE("= %s\n", debugstr_variant(ret));
694     rt->type = RT_RETURN;
695     return S_OK;
696 }
697
698 HRESULT with_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
699 {
700     FIXME("\n");
701     return E_NOTIMPL;
702 }
703
704 HRESULT labelled_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
705 {
706     FIXME("\n");
707     return E_NOTIMPL;
708 }
709
710 HRESULT switch_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
711 {
712     FIXME("\n");
713     return E_NOTIMPL;
714 }
715
716 HRESULT throw_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
717 {
718     FIXME("\n");
719     return E_NOTIMPL;
720 }
721
722 HRESULT try_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
723 {
724     FIXME("\n");
725     return E_NOTIMPL;
726 }
727
728 static HRESULT return_bool(exprval_t *ret, DWORD b)
729 {
730     ret->type = EXPRVAL_VARIANT;
731     V_VT(&ret->u.var) = VT_BOOL;
732     V_BOOL(&ret->u.var) = b ? VARIANT_TRUE : VARIANT_FALSE;
733
734     return S_OK;
735 }
736
737 static HRESULT get_binary_expr_values(exec_ctx_t *ctx, binary_expression_t *expr, jsexcept_t *ei, VARIANT *lval, VARIANT *rval)
738 {
739     exprval_t exprval;
740     HRESULT hres;
741
742     hres = expr_eval(ctx, expr->expression1, 0, ei, &exprval);
743     if(FAILED(hres))
744         return hres;
745
746     hres = exprval_to_value(ctx->parser->script, &exprval, ei, lval);
747     exprval_release(&exprval);
748     if(FAILED(hres))
749         return hres;
750
751     hres = expr_eval(ctx, expr->expression2, 0, ei, &exprval);
752     if(SUCCEEDED(hres)) {
753         hres = exprval_to_value(ctx->parser->script, &exprval, ei, rval);
754         exprval_release(&exprval);
755     }
756
757     if(FAILED(hres)) {
758         VariantClear(lval);
759         return hres;
760     }
761
762     return S_OK;
763 }
764
765 typedef HRESULT (*oper_t)(exec_ctx_t*,VARIANT*,VARIANT*,jsexcept_t*,VARIANT*);
766
767 static HRESULT binary_expr_eval(exec_ctx_t *ctx, binary_expression_t *expr, oper_t oper, jsexcept_t *ei,
768         exprval_t *ret)
769 {
770     VARIANT lval, rval, retv;
771     HRESULT hres;
772
773     hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval);
774     if(FAILED(hres))
775         return hres;
776
777     hres = oper(ctx, &lval, &rval, ei, &retv);
778     VariantClear(&lval);
779     VariantClear(&rval);
780     if(FAILED(hres))
781         return hres;
782
783     ret->type = EXPRVAL_VARIANT;
784     ret->u.var = retv;
785     return S_OK;
786 }
787
788 /* ECMA-262 3rd Edition    11.13.2 */
789 static HRESULT assign_oper_eval(exec_ctx_t *ctx, expression_t *lexpr, expression_t *rexpr, oper_t oper,
790                                 jsexcept_t *ei, exprval_t *ret)
791 {
792     VARIANT retv, lval, rval;
793     exprval_t exprval, exprvalr;
794     HRESULT hres;
795
796     hres = expr_eval(ctx, lexpr, EXPR_NEWREF, ei, &exprval);
797     if(FAILED(hres))
798         return hres;
799
800     hres = exprval_value(ctx->parser->script, &exprval, ei, &lval);
801     if(SUCCEEDED(hres)) {
802         hres = expr_eval(ctx, rexpr, 0, ei, &exprvalr);
803         if(SUCCEEDED(hres)) {
804             hres = exprval_value(ctx->parser->script, &exprvalr, ei, &rval);
805             exprval_release(&exprvalr);
806         }
807         if(SUCCEEDED(hres)) {
808             hres = oper(ctx, &lval, &rval, ei, &retv);
809             VariantClear(&rval);
810         }
811         VariantClear(&lval);
812     }
813
814     if(SUCCEEDED(hres)) {
815         hres = put_value(ctx->parser->script, &exprval, &retv, ei);
816         if(FAILED(hres))
817             VariantClear(&retv);
818     }
819     exprval_release(&exprval);
820
821     if(FAILED(hres))
822         return hres;
823
824     ret->type = EXPRVAL_VARIANT;
825     ret->u.var = retv;
826     return S_OK;
827 }
828
829 /* ECMA-262 3rd Edition    13 */
830 HRESULT function_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
831 {
832     function_expression_t *expr = (function_expression_t*)_expr;
833     DispatchEx *dispex;
834     VARIANT var;
835     HRESULT hres;
836
837     TRACE("\n");
838
839     hres = create_source_function(ctx->parser, expr->parameter_list, expr->source_elements, ctx->scope_chain, &dispex);
840     if(FAILED(hres))
841         return hres;
842
843     V_VT(&var) = VT_DISPATCH;
844     V_DISPATCH(&var) = (IDispatch*)_IDispatchEx_(dispex);
845
846     if(expr->identifier) {
847         hres = jsdisp_propput_name(ctx->var_disp, expr->identifier, ctx->parser->script->lcid, &var, ei, NULL/*FIXME*/);
848         if(FAILED(hres)) {
849             jsdisp_release(dispex);
850             return hres;
851         }
852     }
853
854     ret->type = EXPRVAL_VARIANT;
855     ret->u.var = var;
856     return S_OK;
857 }
858
859 /* ECMA-262 3rd Edition    11.12 */
860 HRESULT conditional_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
861 {
862     conditional_expression_t *expr = (conditional_expression_t*)_expr;
863     exprval_t exprval;
864     VARIANT_BOOL b;
865     HRESULT hres;
866
867     TRACE("\n");
868
869     hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
870     if(FAILED(hres))
871         return hres;
872
873     hres = exprval_to_boolean(ctx->parser->script, &exprval, ei, &b);
874     exprval_release(&exprval);
875     if(FAILED(hres))
876         return hres;
877
878     return expr_eval(ctx, b ? expr->true_expression : expr->false_expression, flags, ei, ret);
879 }
880
881 /* ECMA-262 3rd Edition    11.2.1 */
882 HRESULT array_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
883 {
884     array_expression_t *expr = (array_expression_t*)_expr;
885     exprval_t exprval;
886     VARIANT member, val;
887     DISPID id;
888     BSTR str;
889     IDispatch *obj = NULL;
890     HRESULT hres;
891
892     TRACE("\n");
893
894     hres = expr_eval(ctx, expr->member_expr, EXPR_NEWREF, ei, &exprval);
895     if(FAILED(hres))
896         return hres;
897
898     hres = exprval_to_value(ctx->parser->script, &exprval, ei, &member);
899     exprval_release(&exprval);
900     if(FAILED(hres))
901         return hres;
902
903     hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval);
904     if(SUCCEEDED(hres)) {
905         hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
906         exprval_release(&exprval);
907     }
908
909     if(SUCCEEDED(hres))
910         hres = to_object(ctx, &member, &obj);
911     VariantClear(&member);
912     if(SUCCEEDED(hres)) {
913         hres = to_string(ctx->parser->script, &val, ei, &str);
914         if(SUCCEEDED(hres)) {
915             if(flags & EXPR_STRREF) {
916                 ret->type = EXPRVAL_NAMEREF;
917                 ret->u.nameref.disp = obj;
918                 ret->u.nameref.name = str;
919                 return S_OK;
920             }
921
922             hres = disp_get_id(obj, str, flags & EXPR_NEWREF ? fdexNameEnsure : 0, &id);
923         }
924
925         if(SUCCEEDED(hres)) {
926             exprval_set_idref(ret, obj, id);
927         }else if(!(flags & EXPR_NEWREF) && hres == DISP_E_UNKNOWNNAME) {
928             exprval_init(ret);
929             hres = S_OK;
930         }
931
932         IDispatch_Release(obj);
933     }
934
935     return hres;
936 }
937
938 /* ECMA-262 3rd Edition    11.2.1 */
939 HRESULT member_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
940 {
941     member_expression_t *expr = (member_expression_t*)_expr;
942     IDispatch *obj = NULL;
943     exprval_t exprval;
944     VARIANT member;
945     DISPID id;
946     BSTR str;
947     HRESULT hres;
948
949     TRACE("\n");
950
951     hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
952     if(FAILED(hres))
953         return hres;
954
955     hres = exprval_to_value(ctx->parser->script, &exprval, ei, &member);
956     exprval_release(&exprval);
957     if(FAILED(hres))
958         return hres;
959
960     hres = to_object(ctx, &member, &obj);
961     VariantClear(&member);
962     if(FAILED(hres))
963         return hres;
964
965     str = SysAllocString(expr->identifier);
966     if(flags & EXPR_STRREF) {
967         ret->type = EXPRVAL_NAMEREF;
968         ret->u.nameref.disp = obj;
969         ret->u.nameref.name = str;
970         return S_OK;
971     }
972
973     hres = disp_get_id(obj, str, flags & EXPR_NEW ? fdexNameEnsure : 0, &id);
974     SysFreeString(str);
975     if(SUCCEEDED(hres)) {
976         exprval_set_idref(ret, obj, id);
977     }else if(!(flags & EXPR_NEWREF) && hres == DISP_E_UNKNOWNNAME) {
978         exprval_init(ret);
979         hres = S_OK;
980     }
981
982     IDispatch_Release(obj);
983     return hres;
984 }
985
986 static void free_dp(DISPPARAMS *dp)
987 {
988     DWORD i;
989
990     for(i=0; i < dp->cArgs; i++)
991         VariantClear(dp->rgvarg+i);
992     heap_free(dp->rgvarg);
993 }
994
995 static HRESULT args_to_param(exec_ctx_t *ctx, argument_t *args, jsexcept_t *ei, DISPPARAMS *dp)
996 {
997     VARIANTARG *vargs;
998     exprval_t exprval;
999     argument_t *iter;
1000     DWORD cnt = 0, i;
1001     HRESULT hres = S_OK;
1002
1003     memset(dp, 0, sizeof(*dp));
1004
1005     for(iter = args; iter; iter = iter->next)
1006         cnt++;
1007     if(!cnt)
1008         return S_OK;
1009
1010     vargs = heap_alloc_zero(cnt * sizeof(*vargs));
1011     if(!vargs)
1012         return E_OUTOFMEMORY;
1013
1014     for(i = cnt, iter = args; iter; iter = iter->next) {
1015         hres = expr_eval(ctx, iter->expr, 0, ei, &exprval);
1016         if(FAILED(hres))
1017             break;
1018
1019         hres = exprval_to_value(ctx->parser->script, &exprval, ei, vargs + (--i));
1020         exprval_release(&exprval);
1021         if(FAILED(hres))
1022             break;
1023     }
1024
1025     if(FAILED(hres)) {
1026         free_dp(dp);
1027         return hres;
1028     }
1029
1030     dp->rgvarg = vargs;
1031     dp->cArgs = cnt;
1032     return S_OK;
1033 }
1034
1035 /* ECMA-262 3rd Edition    11.2.2 */
1036 HRESULT member_new_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1037 {
1038     call_expression_t *expr = (call_expression_t*)_expr;
1039     exprval_t exprval;
1040     VARIANT constr, var;
1041     DISPPARAMS dp;
1042     HRESULT hres;
1043
1044     TRACE("\n");
1045
1046     hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
1047     if(FAILED(hres))
1048         return hres;
1049
1050     hres = args_to_param(ctx, expr->argument_list, ei, &dp);
1051     if(SUCCEEDED(hres))
1052         hres = exprval_to_value(ctx->parser->script, &exprval, ei, &constr);
1053     exprval_release(&exprval);
1054     if(FAILED(hres))
1055         return hres;
1056
1057     if(V_VT(&constr) != VT_DISPATCH) {
1058         FIXME("throw TypeError\n");
1059         VariantClear(&constr);
1060         return E_FAIL;
1061     }
1062
1063     hres = disp_call(V_DISPATCH(&constr), DISPID_VALUE, ctx->parser->script->lcid,
1064                      DISPATCH_CONSTRUCT, &dp, &var, ei, NULL/*FIXME*/);
1065     IDispatch_Release(V_DISPATCH(&constr));
1066     if(FAILED(hres))
1067         return hres;
1068
1069     ret->type = EXPRVAL_VARIANT;
1070     ret->u.var = var;
1071     return S_OK;
1072 }
1073
1074 HRESULT call_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1075 {
1076     call_expression_t *expr = (call_expression_t*)_expr;
1077     VARIANT func, var;
1078     exprval_t exprval;
1079     DISPPARAMS dp;
1080     HRESULT hres;
1081
1082     TRACE("\n");
1083
1084     hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
1085     if(FAILED(hres))
1086         return hres;
1087
1088     hres = args_to_param(ctx, expr->argument_list, ei, &dp);
1089     if(SUCCEEDED(hres)) {
1090         switch(exprval.type) {
1091         case EXPRVAL_IDREF:
1092             hres = disp_call(exprval.u.idref.disp, exprval.u.idref.id, ctx->parser->script->lcid, DISPATCH_METHOD,
1093                     &dp, flags & EXPR_NOVAL ? NULL : &var, ei, NULL/*FIXME*/);
1094             if(flags & EXPR_NOVAL)
1095                 V_VT(&var) = VT_EMPTY;
1096             break;
1097         default:
1098             FIXME("unimplemented type %d\n", V_VT(&func));
1099             hres = E_NOTIMPL;
1100         }
1101
1102         free_dp(&dp);
1103     }
1104
1105     exprval_release(&exprval);
1106     if(FAILED(hres))
1107         return hres;
1108
1109     TRACE("= %s\n", debugstr_variant(&var));
1110     ret->type = EXPRVAL_VARIANT;
1111     ret->u.var = var;
1112     return S_OK;
1113 }
1114
1115 HRESULT this_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1116 {
1117     TRACE("\n");
1118
1119     ret->type = EXPRVAL_VARIANT;
1120     V_VT(&ret->u.var) = VT_DISPATCH;
1121     V_DISPATCH(&ret->u.var) = ctx->this_obj;
1122     IDispatch_AddRef(ctx->this_obj);
1123     return S_OK;
1124 }
1125
1126 /* ECMA-262 3rd Edition    10.1.4 */
1127 HRESULT identifier_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1128 {
1129     identifier_expression_t *expr = (identifier_expression_t*)_expr;
1130     BSTR identifier;
1131     HRESULT hres;
1132
1133     TRACE("\n");
1134
1135     identifier = SysAllocString(expr->identifier);
1136     if(!identifier)
1137         return E_OUTOFMEMORY;
1138
1139     hres = identifier_eval(ctx, identifier, flags, ret);
1140
1141     SysFreeString(identifier);
1142     return hres;
1143 }
1144
1145 /* ECMA-262 3rd Edition    7.8 */
1146 HRESULT literal_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1147 {
1148     literal_expression_t *expr = (literal_expression_t*)_expr;
1149     VARIANT var;
1150     HRESULT hres;
1151
1152     TRACE("\n");
1153
1154     hres = literal_to_var(expr->literal, &var);
1155     if(FAILED(hres))
1156         return hres;
1157
1158     ret->type = EXPRVAL_VARIANT;
1159     ret->u.var = var;
1160     return S_OK;
1161 }
1162
1163 HRESULT array_literal_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1164 {
1165     FIXME("\n");
1166     return E_NOTIMPL;
1167 }
1168
1169 /* ECMA-262 3rd Edition    11.1.5 */
1170 HRESULT property_value_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1171 {
1172     property_value_expression_t *expr = (property_value_expression_t*)_expr;
1173     VARIANT val, tmp;
1174     DispatchEx *obj;
1175     prop_val_t *iter;
1176     exprval_t exprval;
1177     BSTR name;
1178     HRESULT hres;
1179
1180     TRACE("\n");
1181
1182     hres = create_object(ctx->parser->script, NULL, &obj);
1183     if(FAILED(hres))
1184         return hres;
1185
1186     for(iter = expr->property_list; iter; iter = iter->next) {
1187         hres = literal_to_var(iter->name, &tmp);
1188         if(FAILED(hres))
1189             break;
1190
1191         hres = to_string(ctx->parser->script, &tmp, ei, &name);
1192         VariantClear(&tmp);
1193         if(FAILED(hres))
1194             break;
1195
1196         hres = expr_eval(ctx, iter->value, 0, ei, &exprval);
1197         if(SUCCEEDED(hres)) {
1198             hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
1199             exprval_release(&exprval);
1200             if(SUCCEEDED(hres)) {
1201                 hres = jsdisp_propput_name(obj, name, ctx->parser->script->lcid, &val, ei, NULL/*FIXME*/);
1202                 VariantClear(&val);
1203             }
1204         }
1205
1206         SysFreeString(name);
1207         if(FAILED(hres))
1208             break;
1209     }
1210
1211     if(FAILED(hres)) {
1212         jsdisp_release(obj);
1213         return hres;
1214     }
1215
1216     ret->type = EXPRVAL_VARIANT;
1217     V_VT(&ret->u.var) = VT_DISPATCH;
1218     V_DISPATCH(&ret->u.var) = (IDispatch*)_IDispatchEx_(obj);
1219     return S_OK;
1220 }
1221
1222 HRESULT comma_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1223 {
1224     FIXME("\n");
1225     return E_NOTIMPL;
1226 }
1227
1228 /* ECMA-262 3rd Edition    11.11 */
1229 HRESULT logical_or_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1230 {
1231     binary_expression_t *expr = (binary_expression_t*)_expr;
1232     exprval_t exprval;
1233     VARIANT_BOOL b;
1234     VARIANT val;
1235     HRESULT hres;
1236
1237     TRACE("\n");
1238
1239     hres = expr_eval(ctx, expr->expression1, 0, ei, &exprval);
1240     if(FAILED(hres))
1241         return hres;
1242
1243     hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
1244     exprval_release(&exprval);
1245     if(FAILED(hres))
1246         return hres;
1247
1248     hres = to_boolean(&val, &b);
1249     if(SUCCEEDED(hres) && b) {
1250         ret->type = EXPRVAL_VARIANT;
1251         ret->u.var = val;
1252         return S_OK;
1253     }
1254
1255     VariantClear(&val);
1256     if(FAILED(hres))
1257         return hres;
1258
1259     hres = expr_eval(ctx, expr->expression2, 0, ei, &exprval);
1260     if(FAILED(hres))
1261         return hres;
1262
1263     hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
1264     exprval_release(&exprval);
1265     if(FAILED(hres))
1266         return hres;
1267
1268     ret->type = EXPRVAL_VARIANT;
1269     ret->u.var = val;
1270     return S_OK;
1271 }
1272
1273 /* ECMA-262 3rd Edition    11.11 */
1274 HRESULT logical_and_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1275 {
1276     binary_expression_t *expr = (binary_expression_t*)_expr;
1277     exprval_t exprval;
1278     VARIANT_BOOL b;
1279     VARIANT val;
1280     HRESULT hres;
1281
1282     TRACE("\n");
1283
1284     hres = expr_eval(ctx, expr->expression1, 0, ei, &exprval);
1285     if(FAILED(hres))
1286         return hres;
1287
1288     hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
1289     exprval_release(&exprval);
1290     if(FAILED(hres))
1291         return hres;
1292
1293     hres = to_boolean(&val, &b);
1294     if(SUCCEEDED(hres) && !b) {
1295         ret->type = EXPRVAL_VARIANT;
1296         ret->u.var = val;
1297         return S_OK;
1298     }
1299
1300     VariantClear(&val);
1301     if(FAILED(hres))
1302         return hres;
1303
1304     hres = expr_eval(ctx, expr->expression2, 0, ei, &exprval);
1305     if(FAILED(hres))
1306         return hres;
1307
1308     hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
1309     exprval_release(&exprval);
1310     if(FAILED(hres))
1311         return hres;
1312
1313     ret->type = EXPRVAL_VARIANT;
1314     ret->u.var = val;
1315     return S_OK;
1316 }
1317
1318 HRESULT binary_or_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1319 {
1320     FIXME("\n");
1321     return E_NOTIMPL;
1322 }
1323
1324 HRESULT binary_xor_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1325 {
1326     FIXME("\n");
1327     return E_NOTIMPL;
1328 }
1329
1330 HRESULT binary_and_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1331 {
1332     FIXME("\n");
1333     return E_NOTIMPL;
1334 }
1335
1336 HRESULT instanceof_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1337 {
1338     FIXME("\n");
1339     return E_NOTIMPL;
1340 }
1341
1342 HRESULT in_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1343 {
1344     FIXME("\n");
1345     return E_NOTIMPL;
1346 }
1347
1348 /* ECMA-262 3rd Edition    11.6.1 */
1349 static HRESULT add_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
1350 {
1351     VARIANT r, l;
1352     HRESULT hres;
1353
1354     hres = to_primitive(ctx->parser->script, lval, ei, &l);
1355     if(FAILED(hres))
1356         return hres;
1357
1358     hres = to_primitive(ctx->parser->script, rval, ei, &r);
1359     if(FAILED(hres)) {
1360         VariantClear(&l);
1361         return hres;
1362     }
1363
1364     if(V_VT(&l) == VT_BSTR || V_VT(&r) == VT_BSTR) {
1365         BSTR lstr = NULL, rstr = NULL;
1366
1367         if(V_VT(&l) == VT_BSTR)
1368             lstr = V_BSTR(&l);
1369         else
1370             hres = to_string(ctx->parser->script, &l, ei, &lstr);
1371
1372         if(SUCCEEDED(hres)) {
1373             if(V_VT(&r) == VT_BSTR)
1374                 rstr = V_BSTR(&r);
1375             else
1376                 hres = to_string(ctx->parser->script, &r, ei, &rstr);
1377         }
1378
1379         if(SUCCEEDED(hres)) {
1380             int len1, len2;
1381
1382             len1 = SysStringLen(lstr);
1383             len2 = SysStringLen(rstr);
1384
1385             V_VT(retv) = VT_BSTR;
1386             V_BSTR(retv) = SysAllocStringLen(NULL, len1+len2);
1387             memcpy(V_BSTR(retv), lstr, len1*sizeof(WCHAR));
1388             memcpy(V_BSTR(retv)+len1, rstr, (len2+1)*sizeof(WCHAR));
1389         }
1390
1391         if(lstr && V_VT(&l) != VT_BSTR)
1392             SysFreeString(lstr);
1393         if(rstr && V_VT(&r) != VT_BSTR)
1394             SysFreeString(rstr);
1395     }else {
1396         VARIANT nl, nr;
1397
1398         hres = to_number(ctx->parser->script, &l, ei, &nl);
1399         if(SUCCEEDED(hres)) {
1400             hres = to_number(ctx->parser->script, &r, ei, &nr);
1401             if(SUCCEEDED(hres))
1402                 num_set_val(retv, num_val(&nl) + num_val(&nr));
1403         }
1404     }
1405
1406     VariantClear(&r);
1407     VariantClear(&l);
1408     return hres;
1409 }
1410
1411 /* ECMA-262 3rd Edition    11.6.1 */
1412 HRESULT add_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1413 {
1414     binary_expression_t *expr = (binary_expression_t*)_expr;
1415
1416     TRACE("\n");
1417
1418     return binary_expr_eval(ctx, expr, add_eval, ei, ret);
1419 }
1420
1421 HRESULT sub_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1422 {
1423     FIXME("\n");
1424     return E_NOTIMPL;
1425 }
1426
1427 HRESULT mul_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1428 {
1429     FIXME("\n");
1430     return E_NOTIMPL;
1431 }
1432
1433 HRESULT div_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1434 {
1435     FIXME("\n");
1436     return E_NOTIMPL;
1437 }
1438
1439 HRESULT mod_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1440 {
1441     FIXME("\n");
1442     return E_NOTIMPL;
1443 }
1444
1445 HRESULT delete_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1446 {
1447     FIXME("\n");
1448     return E_NOTIMPL;
1449 }
1450
1451 HRESULT void_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1452 {
1453     FIXME("\n");
1454     return E_NOTIMPL;
1455 }
1456
1457 HRESULT typeof_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1458 {
1459     unary_expression_t *expr = (unary_expression_t*)_expr;
1460     const WCHAR *str;
1461     exprval_t exprval;
1462     VARIANT val;
1463     HRESULT hres;
1464
1465     static const WCHAR booleanW[] = {'b','o','o','l','e','a','n',0};
1466     static const WCHAR functionW[] = {'f','u','n','c','t','i','o','n',0};
1467     static const WCHAR numberW[] = {'n','u','m','b','e','r',0};
1468     static const WCHAR objectW[] = {'o','b','j','e','c','t',0};
1469     static const WCHAR stringW[] = {'s','t','r','i','n','g',0};
1470     static const WCHAR undefinedW[] = {'u','n','d','e','f','i','n','e','d',0};
1471
1472     TRACE("\n");
1473
1474     hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
1475     if(FAILED(hres))
1476         return hres;
1477
1478     hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
1479     exprval_release(&exprval);
1480     if(FAILED(hres))
1481         return hres;
1482
1483     switch(V_VT(&val)) {
1484     case VT_EMPTY:
1485         str = undefinedW;
1486         break;
1487     case VT_NULL:
1488         str = objectW;
1489         break;
1490     case VT_BOOL:
1491         str = booleanW;
1492         break;
1493     case VT_I4:
1494     case VT_R8:
1495         str = numberW;
1496         break;
1497     case VT_BSTR:
1498         str = stringW;
1499         break;
1500     case VT_DISPATCH: {
1501         DispatchEx *dispex;
1502
1503         dispex = iface_to_jsdisp((IUnknown*)V_DISPATCH(&val));
1504         if(dispex) {
1505             str = dispex->builtin_info->class == JSCLASS_FUNCTION ? functionW : objectW;
1506             IDispatchEx_Release(_IDispatchEx_(dispex));
1507         }else {
1508             str = objectW;
1509         }
1510         break;
1511     }
1512     default:
1513         FIXME("unhandled vt %d\n", V_VT(&val));
1514         hres = E_NOTIMPL;
1515     }
1516
1517     VariantClear(&val);
1518     if(FAILED(hres))
1519         return hres;
1520
1521     ret->type = EXPRVAL_VARIANT;
1522     V_VT(&ret->u.var) = VT_BSTR;
1523     V_BSTR(&ret->u.var) = SysAllocString(str);
1524     return S_OK;
1525 }
1526
1527 HRESULT minus_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1528 {
1529     FIXME("\n");
1530     return E_NOTIMPL;
1531 }
1532
1533 HRESULT plus_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1534 {
1535     FIXME("\n");
1536     return E_NOTIMPL;
1537 }
1538
1539 /* ECMA-262 3rd Edition    11.3.1 */
1540 HRESULT post_increment_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1541 {
1542     unary_expression_t *expr = (unary_expression_t*)_expr;
1543     VARIANT val, num;
1544     exprval_t exprval;
1545     HRESULT hres;
1546
1547     TRACE("\n");
1548
1549     hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval);
1550     if(FAILED(hres))
1551         return hres;
1552
1553     hres = exprval_value(ctx->parser->script, &exprval, ei, &val);
1554     if(SUCCEEDED(hres)) {
1555         hres = to_number(ctx->parser->script, &val, ei, &num);
1556         VariantClear(&val);
1557     }
1558
1559     if(SUCCEEDED(hres)) {
1560         VARIANT inc;
1561         num_set_val(&inc, num_val(&num)+1.0);
1562         hres = put_value(ctx->parser->script, &exprval, &inc, ei);
1563     }
1564
1565     exprval_release(&exprval);
1566     if(FAILED(hres))
1567         return hres;
1568
1569     ret->type = EXPRVAL_VARIANT;
1570     ret->u.var = num;
1571     return S_OK;
1572 }
1573
1574 HRESULT post_decrement_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1575 {
1576     FIXME("\n");
1577     return E_NOTIMPL;
1578 }
1579
1580 /* ECMA-262 3rd Edition    11.4.4 */
1581 HRESULT pre_increment_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1582 {
1583     unary_expression_t *expr = (unary_expression_t*)_expr;
1584     VARIANT val, num;
1585     exprval_t exprval;
1586     HRESULT hres;
1587
1588     TRACE("\n");
1589
1590     hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval);
1591     if(FAILED(hres))
1592         return hres;
1593
1594     hres = exprval_value(ctx->parser->script, &exprval, ei, &val);
1595     if(SUCCEEDED(hres)) {
1596         hres = to_number(ctx->parser->script, &val, ei, &num);
1597         VariantClear(&val);
1598     }
1599
1600     if(SUCCEEDED(hres)) {
1601         num_set_val(&val, num_val(&num)+1.0);
1602         hres = put_value(ctx->parser->script, &exprval, &val, ei);
1603     }
1604
1605     exprval_release(&exprval);
1606     if(FAILED(hres))
1607         return hres;
1608
1609     ret->type = EXPRVAL_VARIANT;
1610     ret->u.var = val;
1611     return S_OK;
1612 }
1613
1614 /* ECMA-262 3rd Edition    11.4.5 */
1615 HRESULT pre_decrement_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1616 {
1617     unary_expression_t *expr = (unary_expression_t*)_expr;
1618     VARIANT val, num;
1619     exprval_t exprval;
1620     HRESULT hres;
1621
1622     TRACE("\n");
1623
1624     hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval);
1625     if(FAILED(hres))
1626         return hres;
1627
1628     hres = exprval_value(ctx->parser->script, &exprval, ei, &val);
1629     if(SUCCEEDED(hres)) {
1630         hres = to_number(ctx->parser->script, &val, ei, &num);
1631         VariantClear(&val);
1632     }
1633
1634     if(SUCCEEDED(hres)) {
1635         num_set_val(&val, num_val(&num)-1.0);
1636         hres = put_value(ctx->parser->script, &exprval, &val, ei);
1637     }
1638
1639     exprval_release(&exprval);
1640     if(FAILED(hres))
1641         return hres;
1642
1643     ret->type = EXPRVAL_VARIANT;
1644     ret->u.var = val;
1645     return S_OK;
1646 }
1647
1648 HRESULT new_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1649 {
1650     FIXME("\n");
1651     return E_NOTIMPL;
1652 }
1653
1654 HRESULT equal_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1655 {
1656     FIXME("\n");
1657     return E_NOTIMPL;
1658 }
1659
1660 /* ECMA-262 3rd Edition    11.9.4 */
1661 HRESULT equal2_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1662 {
1663     binary_expression_t *expr = (binary_expression_t*)_expr;
1664     VARIANT rval, lval;
1665     BOOL b;
1666     HRESULT hres;
1667
1668     TRACE("\n");
1669
1670     hres = get_binary_expr_values(ctx, expr, ei, &rval, &lval);
1671     if(FAILED(hres))
1672         return hres;
1673
1674     hres = equal2_values(&rval, &lval, &b);
1675     if(FAILED(hres))
1676         return hres;
1677
1678     return return_bool(ret, b);
1679 }
1680
1681 HRESULT not_equal_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1682 {
1683
1684     FIXME("\n");
1685     return E_NOTIMPL;
1686 }
1687
1688 /* ECMA-262 3rd Edition    11.9.5 */
1689 HRESULT not_equal2_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1690 {
1691     binary_expression_t *expr = (binary_expression_t*)_expr;
1692     VARIANT rval, lval;
1693     BOOL b;
1694     HRESULT hres;
1695
1696     TRACE("\n");
1697
1698     hres = get_binary_expr_values(ctx, expr, ei, &rval, &lval);
1699     if(FAILED(hres))
1700         return hres;
1701
1702     hres = equal2_values(&rval, &lval, &b);
1703     if(FAILED(hres))
1704         return hres;
1705
1706     return return_bool(ret, !b);
1707 }
1708
1709 /* ECMA-262 3rd Edition    11.8.5 */
1710 static HRESULT less_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, BOOL *ret)
1711 {
1712     VARIANT l, r, ln, rn;
1713     HRESULT hres;
1714
1715     hres = to_primitive(ctx->parser->script, lval, ei, &l);
1716     if(FAILED(hres))
1717         return hres;
1718
1719     hres = to_primitive(ctx->parser->script, rval, ei, &r);
1720     if(FAILED(hres)) {
1721         VariantClear(&l);
1722         return hres;
1723     }
1724
1725     if(V_VT(&l) == VT_BSTR && V_VT(&r) == VT_BSTR) {
1726         *ret = strcmpW(V_BSTR(&l), V_BSTR(&r)) < 0;
1727         SysFreeString(V_BSTR(&l));
1728         SysFreeString(V_BSTR(&r));
1729         return S_OK;
1730     }
1731
1732     hres = to_number(ctx->parser->script, &l, ei, &ln);
1733     VariantClear(&l);
1734     if(SUCCEEDED(hres))
1735         hres = to_number(ctx->parser->script, &r, ei, &rn);
1736     VariantClear(&r);
1737     if(FAILED(hres))
1738         return hres;
1739
1740     if(V_VT(&ln) == VT_I4 && V_VT(&rn) == VT_I4)
1741         *ret = V_I4(&ln) < V_I4(&rn);
1742     else
1743         *ret = num_val(&ln) < num_val(&rn);
1744
1745     return S_OK;
1746 }
1747
1748 /* ECMA-262 3rd Edition    11.8.1 */
1749 HRESULT less_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1750 {
1751     binary_expression_t *expr = (binary_expression_t*)_expr;
1752     VARIANT rval, lval;
1753     BOOL b;
1754     HRESULT hres;
1755
1756     TRACE("\n");
1757
1758     hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval);
1759     if(FAILED(hres))
1760         return hres;
1761
1762     hres = less_eval(ctx, &lval, &rval, ei, &b);
1763     VariantClear(&lval);
1764     VariantClear(&rval);
1765     if(FAILED(hres))
1766         return hres;
1767
1768     return return_bool(ret, b);
1769 }
1770
1771 /* ECMA-262 3rd Edition    11.8.3 */
1772 HRESULT lesseq_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1773 {
1774     binary_expression_t *expr = (binary_expression_t*)_expr;
1775     VARIANT rval, lval;
1776     BOOL b;
1777     HRESULT hres;
1778
1779     TRACE("\n");
1780
1781     hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval);
1782     if(FAILED(hres))
1783         return hres;
1784
1785     hres = less_eval(ctx, &rval, &lval, ei, &b);
1786     VariantClear(&lval);
1787     VariantClear(&rval);
1788     if(FAILED(hres))
1789         return hres;
1790
1791     return return_bool(ret, !b);
1792 }
1793
1794 /* ECMA-262 3rd Edition    11.8.2 */
1795 HRESULT greater_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1796 {
1797     binary_expression_t *expr = (binary_expression_t*)_expr;
1798     VARIANT rval, lval;
1799     BOOL b;
1800     HRESULT hres;
1801
1802     TRACE("\n");
1803
1804     hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval);
1805     if(FAILED(hres))
1806         return hres;
1807
1808     hres = less_eval(ctx, &rval, &lval, ei, &b);
1809     VariantClear(&lval);
1810     VariantClear(&rval);
1811     if(FAILED(hres))
1812         return hres;
1813
1814     return return_bool(ret, b);
1815 }
1816
1817 /* ECMA-262 3rd Edition    11.8.4 */
1818 HRESULT greatereq_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1819 {
1820     binary_expression_t *expr = (binary_expression_t*)_expr;
1821     VARIANT rval, lval;
1822     BOOL b;
1823     HRESULT hres;
1824
1825     TRACE("\n");
1826
1827     hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval);
1828     if(FAILED(hres))
1829         return hres;
1830
1831     hres = less_eval(ctx, &lval, &rval, ei, &b);
1832     VariantClear(&lval);
1833     VariantClear(&rval);
1834     if(FAILED(hres))
1835         return hres;
1836
1837     return return_bool(ret, !b);
1838 }
1839
1840 HRESULT binary_negation_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1841 {
1842     FIXME("\n");
1843     return E_NOTIMPL;
1844 }
1845
1846 /* ECMA-262 3rd Edition    11.4.9 */
1847 HRESULT logical_negation_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1848 {
1849     unary_expression_t *expr = (unary_expression_t*)_expr;
1850     exprval_t exprval;
1851     VARIANT_BOOL b;
1852     HRESULT hres;
1853
1854     TRACE("\n");
1855
1856     hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval);
1857     if(FAILED(hres))
1858         return hres;
1859
1860     hres = exprval_to_boolean(ctx->parser->script, &exprval, ei, &b);
1861     exprval_release(&exprval);
1862     if(FAILED(hres))
1863         return hres;
1864
1865     return return_bool(ret, !b);
1866 }
1867
1868 HRESULT left_shift_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1869 {
1870     FIXME("\n");
1871     return E_NOTIMPL;
1872 }
1873
1874 HRESULT right_shift_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1875 {
1876     FIXME("\n");
1877     return E_NOTIMPL;
1878 }
1879
1880 HRESULT right2_shift_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1881 {
1882     FIXME("\n");
1883     return E_NOTIMPL;
1884 }
1885
1886 /* ECMA-262 3rd Edition    11.13.1 */
1887 HRESULT assign_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1888 {
1889     binary_expression_t *expr = (binary_expression_t*)_expr;
1890     exprval_t exprval, exprvalr;
1891     VARIANT rval;
1892     HRESULT hres;
1893
1894     TRACE("\n");
1895
1896     hres = expr_eval(ctx, expr->expression1, EXPR_NEWREF, ei, &exprval);
1897     if(FAILED(hres))
1898         return hres;
1899
1900     hres = expr_eval(ctx, expr->expression2, 0, ei, &exprvalr);
1901     if(SUCCEEDED(hres)) {
1902         hres = exprval_to_value(ctx->parser->script, &exprvalr, ei, &rval);
1903         exprval_release(&exprvalr);
1904     }
1905
1906     if(SUCCEEDED(hres))
1907         hres = put_value(ctx->parser->script, &exprval, &rval, ei);
1908
1909     exprval_release(&exprval);
1910     if(FAILED(hres)) {
1911         VariantClear(&rval);
1912         return hres;
1913     }
1914
1915     ret->type = EXPRVAL_VARIANT;
1916     ret->u.var = rval;
1917     return S_OK;
1918 }
1919
1920 HRESULT assign_lshift_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1921 {
1922     FIXME("\n");
1923     return E_NOTIMPL;
1924 }
1925
1926 HRESULT assign_rshift_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1927 {
1928     FIXME("\n");
1929     return E_NOTIMPL;
1930 }
1931
1932 HRESULT assign_rrshift_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1933 {
1934     FIXME("\n");
1935     return E_NOTIMPL;
1936 }
1937
1938 /* ECMA-262 3rd Edition    11.13.2 */
1939 HRESULT assign_add_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1940 {
1941     binary_expression_t *expr = (binary_expression_t*)_expr;
1942
1943     TRACE("\n");
1944
1945     return assign_oper_eval(ctx, expr->expression1, expr->expression2, add_eval, ei, ret);
1946 }
1947
1948 HRESULT assign_sub_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1949 {
1950     FIXME("\n");
1951     return E_NOTIMPL;
1952 }
1953
1954 HRESULT assign_mul_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1955 {
1956     FIXME("\n");
1957     return E_NOTIMPL;
1958 }
1959
1960 HRESULT assign_div_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1961 {
1962     FIXME("\n");
1963     return E_NOTIMPL;
1964 }
1965
1966 HRESULT assign_mod_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1967 {
1968     FIXME("\n");
1969     return E_NOTIMPL;
1970 }
1971
1972 HRESULT assign_and_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1973 {
1974     FIXME("\n");
1975     return E_NOTIMPL;
1976 }
1977
1978 HRESULT assign_or_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1979 {
1980     FIXME("\n");
1981     return E_NOTIMPL;
1982 }
1983
1984 HRESULT assign_xor_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1985 {
1986     FIXME("\n");
1987     return E_NOTIMPL;
1988 }