jscript: Added add 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    13 */
789 HRESULT function_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
790 {
791     function_expression_t *expr = (function_expression_t*)_expr;
792     DispatchEx *dispex;
793     VARIANT var;
794     HRESULT hres;
795
796     TRACE("\n");
797
798     hres = create_source_function(ctx->parser, expr->parameter_list, expr->source_elements, ctx->scope_chain, &dispex);
799     if(FAILED(hres))
800         return hres;
801
802     V_VT(&var) = VT_DISPATCH;
803     V_DISPATCH(&var) = (IDispatch*)_IDispatchEx_(dispex);
804
805     if(expr->identifier) {
806         hres = jsdisp_propput_name(ctx->var_disp, expr->identifier, ctx->parser->script->lcid, &var, ei, NULL/*FIXME*/);
807         if(FAILED(hres)) {
808             jsdisp_release(dispex);
809             return hres;
810         }
811     }
812
813     ret->type = EXPRVAL_VARIANT;
814     ret->u.var = var;
815     return S_OK;
816 }
817
818 /* ECMA-262 3rd Edition    11.12 */
819 HRESULT conditional_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
820 {
821     conditional_expression_t *expr = (conditional_expression_t*)_expr;
822     exprval_t exprval;
823     VARIANT_BOOL b;
824     HRESULT hres;
825
826     TRACE("\n");
827
828     hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
829     if(FAILED(hres))
830         return hres;
831
832     hres = exprval_to_boolean(ctx->parser->script, &exprval, ei, &b);
833     exprval_release(&exprval);
834     if(FAILED(hres))
835         return hres;
836
837     return expr_eval(ctx, b ? expr->true_expression : expr->false_expression, flags, ei, ret);
838 }
839
840 /* ECMA-262 3rd Edition    11.2.1 */
841 HRESULT array_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
842 {
843     array_expression_t *expr = (array_expression_t*)_expr;
844     exprval_t exprval;
845     VARIANT member, val;
846     DISPID id;
847     BSTR str;
848     IDispatch *obj = NULL;
849     HRESULT hres;
850
851     TRACE("\n");
852
853     hres = expr_eval(ctx, expr->member_expr, EXPR_NEWREF, ei, &exprval);
854     if(FAILED(hres))
855         return hres;
856
857     hres = exprval_to_value(ctx->parser->script, &exprval, ei, &member);
858     exprval_release(&exprval);
859     if(FAILED(hres))
860         return hres;
861
862     hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval);
863     if(SUCCEEDED(hres)) {
864         hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
865         exprval_release(&exprval);
866     }
867
868     if(SUCCEEDED(hres))
869         hres = to_object(ctx, &member, &obj);
870     VariantClear(&member);
871     if(SUCCEEDED(hres)) {
872         hres = to_string(ctx->parser->script, &val, ei, &str);
873         if(SUCCEEDED(hres)) {
874             if(flags & EXPR_STRREF) {
875                 ret->type = EXPRVAL_NAMEREF;
876                 ret->u.nameref.disp = obj;
877                 ret->u.nameref.name = str;
878                 return S_OK;
879             }
880
881             hres = disp_get_id(obj, str, flags & EXPR_NEWREF ? fdexNameEnsure : 0, &id);
882         }
883
884         if(SUCCEEDED(hres)) {
885             exprval_set_idref(ret, obj, id);
886         }else if(!(flags & EXPR_NEWREF) && hres == DISP_E_UNKNOWNNAME) {
887             exprval_init(ret);
888             hres = S_OK;
889         }
890
891         IDispatch_Release(obj);
892     }
893
894     return hres;
895 }
896
897 /* ECMA-262 3rd Edition    11.2.1 */
898 HRESULT member_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
899 {
900     member_expression_t *expr = (member_expression_t*)_expr;
901     IDispatch *obj = NULL;
902     exprval_t exprval;
903     VARIANT member;
904     DISPID id;
905     BSTR str;
906     HRESULT hres;
907
908     TRACE("\n");
909
910     hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
911     if(FAILED(hres))
912         return hres;
913
914     hres = exprval_to_value(ctx->parser->script, &exprval, ei, &member);
915     exprval_release(&exprval);
916     if(FAILED(hres))
917         return hres;
918
919     hres = to_object(ctx, &member, &obj);
920     VariantClear(&member);
921     if(FAILED(hres))
922         return hres;
923
924     str = SysAllocString(expr->identifier);
925     if(flags & EXPR_STRREF) {
926         ret->type = EXPRVAL_NAMEREF;
927         ret->u.nameref.disp = obj;
928         ret->u.nameref.name = str;
929         return S_OK;
930     }
931
932     hres = disp_get_id(obj, str, flags & EXPR_NEW ? fdexNameEnsure : 0, &id);
933     SysFreeString(str);
934     if(SUCCEEDED(hres)) {
935         exprval_set_idref(ret, obj, id);
936     }else if(!(flags & EXPR_NEWREF) && hres == DISP_E_UNKNOWNNAME) {
937         exprval_init(ret);
938         hres = S_OK;
939     }
940
941     IDispatch_Release(obj);
942     return hres;
943 }
944
945 static void free_dp(DISPPARAMS *dp)
946 {
947     DWORD i;
948
949     for(i=0; i < dp->cArgs; i++)
950         VariantClear(dp->rgvarg+i);
951     heap_free(dp->rgvarg);
952 }
953
954 static HRESULT args_to_param(exec_ctx_t *ctx, argument_t *args, jsexcept_t *ei, DISPPARAMS *dp)
955 {
956     VARIANTARG *vargs;
957     exprval_t exprval;
958     argument_t *iter;
959     DWORD cnt = 0, i;
960     HRESULT hres = S_OK;
961
962     memset(dp, 0, sizeof(*dp));
963
964     for(iter = args; iter; iter = iter->next)
965         cnt++;
966     if(!cnt)
967         return S_OK;
968
969     vargs = heap_alloc_zero(cnt * sizeof(*vargs));
970     if(!vargs)
971         return E_OUTOFMEMORY;
972
973     for(i = cnt, iter = args; iter; iter = iter->next) {
974         hres = expr_eval(ctx, iter->expr, 0, ei, &exprval);
975         if(FAILED(hres))
976             break;
977
978         hres = exprval_to_value(ctx->parser->script, &exprval, ei, vargs + (--i));
979         exprval_release(&exprval);
980         if(FAILED(hres))
981             break;
982     }
983
984     if(FAILED(hres)) {
985         free_dp(dp);
986         return hres;
987     }
988
989     dp->rgvarg = vargs;
990     dp->cArgs = cnt;
991     return S_OK;
992 }
993
994 /* ECMA-262 3rd Edition    11.2.2 */
995 HRESULT member_new_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
996 {
997     call_expression_t *expr = (call_expression_t*)_expr;
998     exprval_t exprval;
999     VARIANT constr, var;
1000     DISPPARAMS dp;
1001     HRESULT hres;
1002
1003     TRACE("\n");
1004
1005     hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
1006     if(FAILED(hres))
1007         return hres;
1008
1009     hres = args_to_param(ctx, expr->argument_list, ei, &dp);
1010     if(SUCCEEDED(hres))
1011         hres = exprval_to_value(ctx->parser->script, &exprval, ei, &constr);
1012     exprval_release(&exprval);
1013     if(FAILED(hres))
1014         return hres;
1015
1016     if(V_VT(&constr) != VT_DISPATCH) {
1017         FIXME("throw TypeError\n");
1018         VariantClear(&constr);
1019         return E_FAIL;
1020     }
1021
1022     hres = disp_call(V_DISPATCH(&constr), DISPID_VALUE, ctx->parser->script->lcid,
1023                      DISPATCH_CONSTRUCT, &dp, &var, ei, NULL/*FIXME*/);
1024     IDispatch_Release(V_DISPATCH(&constr));
1025     if(FAILED(hres))
1026         return hres;
1027
1028     ret->type = EXPRVAL_VARIANT;
1029     ret->u.var = var;
1030     return S_OK;
1031 }
1032
1033 HRESULT call_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1034 {
1035     call_expression_t *expr = (call_expression_t*)_expr;
1036     VARIANT func, var;
1037     exprval_t exprval;
1038     DISPPARAMS dp;
1039     HRESULT hres;
1040
1041     TRACE("\n");
1042
1043     hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
1044     if(FAILED(hres))
1045         return hres;
1046
1047     hres = args_to_param(ctx, expr->argument_list, ei, &dp);
1048     if(SUCCEEDED(hres)) {
1049         switch(exprval.type) {
1050         case EXPRVAL_IDREF:
1051             hres = disp_call(exprval.u.idref.disp, exprval.u.idref.id, ctx->parser->script->lcid, DISPATCH_METHOD,
1052                     &dp, flags & EXPR_NOVAL ? NULL : &var, ei, NULL/*FIXME*/);
1053             if(flags & EXPR_NOVAL)
1054                 V_VT(&var) = VT_EMPTY;
1055             break;
1056         default:
1057             FIXME("unimplemented type %d\n", V_VT(&func));
1058             hres = E_NOTIMPL;
1059         }
1060
1061         free_dp(&dp);
1062     }
1063
1064     exprval_release(&exprval);
1065     if(FAILED(hres))
1066         return hres;
1067
1068     TRACE("= %s\n", debugstr_variant(&var));
1069     ret->type = EXPRVAL_VARIANT;
1070     ret->u.var = var;
1071     return S_OK;
1072 }
1073
1074 HRESULT this_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1075 {
1076     TRACE("\n");
1077
1078     ret->type = EXPRVAL_VARIANT;
1079     V_VT(&ret->u.var) = VT_DISPATCH;
1080     V_DISPATCH(&ret->u.var) = ctx->this_obj;
1081     IDispatch_AddRef(ctx->this_obj);
1082     return S_OK;
1083 }
1084
1085 /* ECMA-262 3rd Edition    10.1.4 */
1086 HRESULT identifier_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1087 {
1088     identifier_expression_t *expr = (identifier_expression_t*)_expr;
1089     BSTR identifier;
1090     HRESULT hres;
1091
1092     TRACE("\n");
1093
1094     identifier = SysAllocString(expr->identifier);
1095     if(!identifier)
1096         return E_OUTOFMEMORY;
1097
1098     hres = identifier_eval(ctx, identifier, flags, ret);
1099
1100     SysFreeString(identifier);
1101     return hres;
1102 }
1103
1104 /* ECMA-262 3rd Edition    7.8 */
1105 HRESULT literal_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1106 {
1107     literal_expression_t *expr = (literal_expression_t*)_expr;
1108     VARIANT var;
1109     HRESULT hres;
1110
1111     TRACE("\n");
1112
1113     hres = literal_to_var(expr->literal, &var);
1114     if(FAILED(hres))
1115         return hres;
1116
1117     ret->type = EXPRVAL_VARIANT;
1118     ret->u.var = var;
1119     return S_OK;
1120 }
1121
1122 HRESULT array_literal_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1123 {
1124     FIXME("\n");
1125     return E_NOTIMPL;
1126 }
1127
1128 /* ECMA-262 3rd Edition    11.1.5 */
1129 HRESULT property_value_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1130 {
1131     property_value_expression_t *expr = (property_value_expression_t*)_expr;
1132     VARIANT val, tmp;
1133     DispatchEx *obj;
1134     prop_val_t *iter;
1135     exprval_t exprval;
1136     BSTR name;
1137     HRESULT hres;
1138
1139     TRACE("\n");
1140
1141     hres = create_object(ctx->parser->script, NULL, &obj);
1142     if(FAILED(hres))
1143         return hres;
1144
1145     for(iter = expr->property_list; iter; iter = iter->next) {
1146         hres = literal_to_var(iter->name, &tmp);
1147         if(FAILED(hres))
1148             break;
1149
1150         hres = to_string(ctx->parser->script, &tmp, ei, &name);
1151         VariantClear(&tmp);
1152         if(FAILED(hres))
1153             break;
1154
1155         hres = expr_eval(ctx, iter->value, 0, ei, &exprval);
1156         if(SUCCEEDED(hres)) {
1157             hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
1158             exprval_release(&exprval);
1159             if(SUCCEEDED(hres)) {
1160                 hres = jsdisp_propput_name(obj, name, ctx->parser->script->lcid, &val, ei, NULL/*FIXME*/);
1161                 VariantClear(&val);
1162             }
1163         }
1164
1165         SysFreeString(name);
1166         if(FAILED(hres))
1167             break;
1168     }
1169
1170     if(FAILED(hres)) {
1171         jsdisp_release(obj);
1172         return hres;
1173     }
1174
1175     ret->type = EXPRVAL_VARIANT;
1176     V_VT(&ret->u.var) = VT_DISPATCH;
1177     V_DISPATCH(&ret->u.var) = (IDispatch*)_IDispatchEx_(obj);
1178     return S_OK;
1179 }
1180
1181 HRESULT comma_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1182 {
1183     FIXME("\n");
1184     return E_NOTIMPL;
1185 }
1186
1187 HRESULT logical_or_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1188 {
1189     FIXME("\n");
1190     return E_NOTIMPL;
1191 }
1192
1193 HRESULT logical_and_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1194 {
1195     FIXME("\n");
1196     return E_NOTIMPL;
1197 }
1198
1199 HRESULT binary_or_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1200 {
1201     FIXME("\n");
1202     return E_NOTIMPL;
1203 }
1204
1205 HRESULT binary_xor_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1206 {
1207     FIXME("\n");
1208     return E_NOTIMPL;
1209 }
1210
1211 HRESULT binary_and_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1212 {
1213     FIXME("\n");
1214     return E_NOTIMPL;
1215 }
1216
1217 HRESULT instanceof_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1218 {
1219     FIXME("\n");
1220     return E_NOTIMPL;
1221 }
1222
1223 HRESULT in_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1224 {
1225     FIXME("\n");
1226     return E_NOTIMPL;
1227 }
1228
1229 /* ECMA-262 3rd Edition    11.6.1 */
1230 static HRESULT add_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
1231 {
1232     VARIANT r, l;
1233     HRESULT hres;
1234
1235     hres = to_primitive(ctx->parser->script, lval, ei, &l);
1236     if(FAILED(hres))
1237         return hres;
1238
1239     hres = to_primitive(ctx->parser->script, rval, ei, &r);
1240     if(FAILED(hres)) {
1241         VariantClear(&l);
1242         return hres;
1243     }
1244
1245     if(V_VT(&l) == VT_BSTR || V_VT(&r) == VT_BSTR) {
1246         BSTR lstr = NULL, rstr = NULL;
1247
1248         if(V_VT(&l) == VT_BSTR)
1249             lstr = V_BSTR(&l);
1250         else
1251             hres = to_string(ctx->parser->script, &l, ei, &lstr);
1252
1253         if(SUCCEEDED(hres)) {
1254             if(V_VT(&r) == VT_BSTR)
1255                 rstr = V_BSTR(&r);
1256             else
1257                 hres = to_string(ctx->parser->script, &r, ei, &rstr);
1258         }
1259
1260         if(SUCCEEDED(hres)) {
1261             int len1, len2;
1262
1263             len1 = SysStringLen(lstr);
1264             len2 = SysStringLen(rstr);
1265
1266             V_VT(retv) = VT_BSTR;
1267             V_BSTR(retv) = SysAllocStringLen(NULL, len1+len2);
1268             memcpy(V_BSTR(retv), lstr, len1*sizeof(WCHAR));
1269             memcpy(V_BSTR(retv)+len1, rstr, (len2+1)*sizeof(WCHAR));
1270         }
1271
1272         if(lstr && V_VT(&l) != VT_BSTR)
1273             SysFreeString(lstr);
1274         if(rstr && V_VT(&r) != VT_BSTR)
1275             SysFreeString(rstr);
1276     }else {
1277         VARIANT nl, nr;
1278
1279         hres = to_number(ctx->parser->script, &l, ei, &nl);
1280         if(SUCCEEDED(hres)) {
1281             hres = to_number(ctx->parser->script, &r, ei, &nr);
1282             if(SUCCEEDED(hres))
1283                 num_set_val(retv, num_val(&nl) + num_val(&nr));
1284         }
1285     }
1286
1287     VariantClear(&r);
1288     VariantClear(&l);
1289     return hres;
1290 }
1291
1292 /* ECMA-262 3rd Edition    11.6.1 */
1293 HRESULT add_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1294 {
1295     binary_expression_t *expr = (binary_expression_t*)_expr;
1296
1297     TRACE("\n");
1298
1299     return binary_expr_eval(ctx, expr, add_eval, ei, ret);
1300 }
1301
1302 HRESULT sub_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1303 {
1304     FIXME("\n");
1305     return E_NOTIMPL;
1306 }
1307
1308 HRESULT mul_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1309 {
1310     FIXME("\n");
1311     return E_NOTIMPL;
1312 }
1313
1314 HRESULT div_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1315 {
1316     FIXME("\n");
1317     return E_NOTIMPL;
1318 }
1319
1320 HRESULT mod_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1321 {
1322     FIXME("\n");
1323     return E_NOTIMPL;
1324 }
1325
1326 HRESULT delete_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1327 {
1328     FIXME("\n");
1329     return E_NOTIMPL;
1330 }
1331
1332 HRESULT void_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1333 {
1334     FIXME("\n");
1335     return E_NOTIMPL;
1336 }
1337
1338 HRESULT typeof_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1339 {
1340     unary_expression_t *expr = (unary_expression_t*)_expr;
1341     const WCHAR *str;
1342     exprval_t exprval;
1343     VARIANT val;
1344     HRESULT hres;
1345
1346     static const WCHAR booleanW[] = {'b','o','o','l','e','a','n',0};
1347     static const WCHAR functionW[] = {'f','u','n','c','t','i','o','n',0};
1348     static const WCHAR numberW[] = {'n','u','m','b','e','r',0};
1349     static const WCHAR objectW[] = {'o','b','j','e','c','t',0};
1350     static const WCHAR stringW[] = {'s','t','r','i','n','g',0};
1351     static const WCHAR undefinedW[] = {'u','n','d','e','f','i','n','e','d',0};
1352
1353     TRACE("\n");
1354
1355     hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
1356     if(FAILED(hres))
1357         return hres;
1358
1359     hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
1360     exprval_release(&exprval);
1361     if(FAILED(hres))
1362         return hres;
1363
1364     switch(V_VT(&val)) {
1365     case VT_EMPTY:
1366         str = undefinedW;
1367         break;
1368     case VT_NULL:
1369         str = objectW;
1370         break;
1371     case VT_BOOL:
1372         str = booleanW;
1373         break;
1374     case VT_I4:
1375     case VT_R8:
1376         str = numberW;
1377         break;
1378     case VT_BSTR:
1379         str = stringW;
1380         break;
1381     case VT_DISPATCH: {
1382         DispatchEx *dispex;
1383
1384         dispex = iface_to_jsdisp((IUnknown*)V_DISPATCH(&val));
1385         if(dispex) {
1386             str = dispex->builtin_info->class == JSCLASS_FUNCTION ? functionW : objectW;
1387             IDispatchEx_Release(_IDispatchEx_(dispex));
1388         }else {
1389             str = objectW;
1390         }
1391         break;
1392     }
1393     default:
1394         FIXME("unhandled vt %d\n", V_VT(&val));
1395         hres = E_NOTIMPL;
1396     }
1397
1398     VariantClear(&val);
1399     if(FAILED(hres))
1400         return hres;
1401
1402     ret->type = EXPRVAL_VARIANT;
1403     V_VT(&ret->u.var) = VT_BSTR;
1404     V_BSTR(&ret->u.var) = SysAllocString(str);
1405     return S_OK;
1406 }
1407
1408 HRESULT minus_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1409 {
1410     FIXME("\n");
1411     return E_NOTIMPL;
1412 }
1413
1414 HRESULT plus_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1415 {
1416     FIXME("\n");
1417     return E_NOTIMPL;
1418 }
1419
1420 HRESULT post_increment_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1421 {
1422     FIXME("\n");
1423     return E_NOTIMPL;
1424 }
1425
1426 HRESULT post_decrement_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1427 {
1428     FIXME("\n");
1429     return E_NOTIMPL;
1430 }
1431
1432 HRESULT pre_increment_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1433 {
1434     FIXME("\n");
1435     return E_NOTIMPL;
1436 }
1437
1438 HRESULT pre_decrement_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1439 {
1440     FIXME("\n");
1441     return E_NOTIMPL;
1442 }
1443
1444 HRESULT new_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1445 {
1446     FIXME("\n");
1447     return E_NOTIMPL;
1448 }
1449
1450 HRESULT equal_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1451 {
1452     FIXME("\n");
1453     return E_NOTIMPL;
1454 }
1455
1456 /* ECMA-262 3rd Edition    11.9.4 */
1457 HRESULT equal2_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1458 {
1459     binary_expression_t *expr = (binary_expression_t*)_expr;
1460     VARIANT rval, lval;
1461     BOOL b;
1462     HRESULT hres;
1463
1464     TRACE("\n");
1465
1466     hres = get_binary_expr_values(ctx, expr, ei, &rval, &lval);
1467     if(FAILED(hres))
1468         return hres;
1469
1470     hres = equal2_values(&rval, &lval, &b);
1471     if(FAILED(hres))
1472         return hres;
1473
1474     return return_bool(ret, b);
1475 }
1476
1477 HRESULT not_equal_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1478 {
1479
1480     FIXME("\n");
1481     return E_NOTIMPL;
1482 }
1483
1484 /* ECMA-262 3rd Edition    11.9.5 */
1485 HRESULT not_equal2_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1486 {
1487     binary_expression_t *expr = (binary_expression_t*)_expr;
1488     VARIANT rval, lval;
1489     BOOL b;
1490     HRESULT hres;
1491
1492     TRACE("\n");
1493
1494     hres = get_binary_expr_values(ctx, expr, ei, &rval, &lval);
1495     if(FAILED(hres))
1496         return hres;
1497
1498     hres = equal2_values(&rval, &lval, &b);
1499     if(FAILED(hres))
1500         return hres;
1501
1502     return return_bool(ret, !b);
1503 }
1504
1505 HRESULT less_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1506 {
1507     FIXME("\n");
1508     return E_NOTIMPL;
1509 }
1510
1511 HRESULT lesseq_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1512 {
1513     FIXME("\n");
1514     return E_NOTIMPL;
1515 }
1516
1517 HRESULT greater_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1518 {
1519     FIXME("\n");
1520     return E_NOTIMPL;
1521 }
1522
1523 HRESULT greatereq_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1524 {
1525     FIXME("\n");
1526     return E_NOTIMPL;
1527 }
1528
1529 HRESULT binary_negation_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1530 {
1531     FIXME("\n");
1532     return E_NOTIMPL;
1533 }
1534
1535 /* ECMA-262 3rd Edition    11.4.9 */
1536 HRESULT logical_negation_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1537 {
1538     unary_expression_t *expr = (unary_expression_t*)_expr;
1539     exprval_t exprval;
1540     VARIANT_BOOL b;
1541     HRESULT hres;
1542
1543     TRACE("\n");
1544
1545     hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval);
1546     if(FAILED(hres))
1547         return hres;
1548
1549     hres = exprval_to_boolean(ctx->parser->script, &exprval, ei, &b);
1550     exprval_release(&exprval);
1551     if(FAILED(hres))
1552         return hres;
1553
1554     return return_bool(ret, !b);
1555 }
1556
1557 HRESULT left_shift_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1558 {
1559     FIXME("\n");
1560     return E_NOTIMPL;
1561 }
1562
1563 HRESULT right_shift_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1564 {
1565     FIXME("\n");
1566     return E_NOTIMPL;
1567 }
1568
1569 HRESULT right2_shift_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1570 {
1571     FIXME("\n");
1572     return E_NOTIMPL;
1573 }
1574
1575 /* ECMA-262 3rd Edition    11.13.1 */
1576 HRESULT assign_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1577 {
1578     binary_expression_t *expr = (binary_expression_t*)_expr;
1579     exprval_t exprval, exprvalr;
1580     VARIANT rval;
1581     HRESULT hres;
1582
1583     TRACE("\n");
1584
1585     hres = expr_eval(ctx, expr->expression1, EXPR_NEWREF, ei, &exprval);
1586     if(FAILED(hres))
1587         return hres;
1588
1589     hres = expr_eval(ctx, expr->expression2, 0, ei, &exprvalr);
1590     if(SUCCEEDED(hres)) {
1591         hres = exprval_to_value(ctx->parser->script, &exprvalr, ei, &rval);
1592         exprval_release(&exprvalr);
1593     }
1594
1595     if(SUCCEEDED(hres))
1596         hres = put_value(ctx->parser->script, &exprval, &rval, ei);
1597
1598     exprval_release(&exprval);
1599     if(FAILED(hres)) {
1600         VariantClear(&rval);
1601         return hres;
1602     }
1603
1604     ret->type = EXPRVAL_VARIANT;
1605     ret->u.var = rval;
1606     return S_OK;
1607 }
1608
1609 HRESULT assign_lshift_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1610 {
1611     FIXME("\n");
1612     return E_NOTIMPL;
1613 }
1614
1615 HRESULT assign_rshift_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1616 {
1617     FIXME("\n");
1618     return E_NOTIMPL;
1619 }
1620
1621 HRESULT assign_rrshift_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1622 {
1623     FIXME("\n");
1624     return E_NOTIMPL;
1625 }
1626
1627 HRESULT assign_add_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1628 {
1629     FIXME("\n");
1630     return E_NOTIMPL;
1631 }
1632
1633 HRESULT assign_sub_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1634 {
1635     FIXME("\n");
1636     return E_NOTIMPL;
1637 }
1638
1639 HRESULT assign_mul_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1640 {
1641     FIXME("\n");
1642     return E_NOTIMPL;
1643 }
1644
1645 HRESULT assign_div_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1646 {
1647     FIXME("\n");
1648     return E_NOTIMPL;
1649 }
1650
1651 HRESULT assign_mod_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1652 {
1653     FIXME("\n");
1654     return E_NOTIMPL;
1655 }
1656
1657 HRESULT assign_and_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1658 {
1659     FIXME("\n");
1660     return E_NOTIMPL;
1661 }
1662
1663 HRESULT assign_or_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1664 {
1665     FIXME("\n");
1666     return E_NOTIMPL;
1667 }
1668
1669 HRESULT assign_xor_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1670 {
1671     FIXME("\n");
1672     return E_NOTIMPL;
1673 }