jscript: Added conditional 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 /* ECMA-262 3rd Edition    11.9.6 */
282 HRESULT equal2_values(VARIANT *lval, VARIANT *rval, BOOL *ret)
283 {
284     TRACE("\n");
285
286     if(V_VT(lval) != V_VT(rval)) {
287         if(is_num_vt(V_VT(lval)) && is_num_vt(V_VT(rval))) {
288             *ret = num_val(lval) == num_val(rval);
289             return S_OK;
290         }
291
292         *ret = FALSE;
293         return S_OK;
294     }
295
296     switch(V_VT(lval)) {
297     case VT_EMPTY:
298     case VT_NULL:
299         *ret = VARIANT_TRUE;
300         break;
301     case VT_I4:
302         *ret = V_I4(lval) == V_I4(rval);
303         break;
304     case VT_R8:
305         *ret = V_R8(lval) == V_R8(rval);
306         break;
307     case VT_BSTR:
308         *ret = !strcmpW(V_BSTR(lval), V_BSTR(rval));
309         break;
310     case VT_DISPATCH:
311         return disp_cmp(V_DISPATCH(lval), V_DISPATCH(rval), ret);
312     case VT_BOOL:
313         *ret = !V_BOOL(lval) == !V_BOOL(rval);
314         break;
315     default:
316         FIXME("unimplemented vt %d\n", V_VT(lval));
317         return E_NOTIMPL;
318     }
319
320     return S_OK;
321 }
322
323 static HRESULT literal_to_var(literal_t *literal, VARIANT *v)
324 {
325     V_VT(v) = literal->vt;
326
327     switch(V_VT(v)) {
328     case VT_EMPTY:
329     case VT_NULL:
330         break;
331     case VT_I4:
332         V_I4(v) = literal->u.lval;
333         break;
334     case VT_R8:
335         V_R8(v) = literal->u.dval;
336         break;
337     case VT_BSTR:
338         V_BSTR(v) = SysAllocString(literal->u.wstr);
339         break;
340     case VT_BOOL:
341         V_BOOL(v) = literal->u.bval;
342         break;
343     case VT_DISPATCH:
344         IDispatch_AddRef(literal->u.disp);
345         V_DISPATCH(v) = literal->u.disp;
346         break;
347     default:
348         ERR("wrong type %d\n", V_VT(v));
349         return E_NOTIMPL;
350     }
351
352     return S_OK;
353 }
354
355 HRESULT exec_source(exec_ctx_t *ctx, parser_ctx_t *parser, source_elements_t *source, jsexcept_t *ei, VARIANT *retv)
356 {
357     script_ctx_t *script = parser->script;
358     function_declaration_t *func;
359     parser_ctx_t *prev_parser;
360     VARIANT val, tmp;
361     statement_t *stat;
362     exec_ctx_t *prev_ctx;
363     return_type_t rt;
364     HRESULT hres = S_OK;
365
366     for(func = source->functions; func; func = func->next) {
367         DispatchEx *func_obj;
368         VARIANT var;
369
370         hres = create_source_function(parser, func->parameter_list, func->source_elements, ctx->scope_chain, &func_obj);
371         if(FAILED(hres))
372             return hres;
373
374         V_VT(&var) = VT_DISPATCH;
375         V_DISPATCH(&var) = (IDispatch*)_IDispatchEx_(func_obj);
376         hres = jsdisp_propput_name(ctx->var_disp, func->identifier, script->lcid, &var, ei, NULL);
377         IDispatchEx_Release(_IDispatchEx_(func_obj));
378         if(FAILED(hres))
379             return hres;
380     }
381
382     prev_ctx = script->exec_ctx;
383     script->exec_ctx = ctx;
384
385     prev_parser = ctx->parser;
386     ctx->parser = parser;
387
388     V_VT(&val) = VT_EMPTY;
389     memset(&rt, 0, sizeof(rt));
390     rt.type = RT_NORMAL;
391
392     for(stat = source->statement; stat; stat = stat->next) {
393         hres = stat_eval(ctx, stat, &rt, &tmp);
394         if(FAILED(hres))
395             break;
396
397         VariantClear(&val);
398         val = tmp;
399         if(rt.type != RT_NORMAL)
400             break;
401     }
402
403     script->exec_ctx = prev_ctx;
404     ctx->parser = prev_parser;
405
406     if(rt.type != RT_NORMAL && rt.type != RT_RETURN) {
407         FIXME("wrong rt %d\n", rt.type);
408         hres = E_FAIL;
409     }
410
411     *ei = rt.ei;
412     if(FAILED(hres)) {
413         VariantClear(&val);
414         return hres;
415     }
416
417     if(retv)
418         *retv = val;
419     else
420         VariantClear(&val);
421     return S_OK;
422 }
423
424 /* ECMA-262 3rd Edition    10.1.4 */
425 static HRESULT identifier_eval(exec_ctx_t *ctx, BSTR identifier, DWORD flags, exprval_t *ret)
426 {
427     scope_chain_t *scope;
428     named_item_t *item;
429     DISPID id = 0;
430     HRESULT hres;
431
432     TRACE("%s\n", debugstr_w(identifier));
433
434     for(scope = ctx->scope_chain; scope; scope = scope->next) {
435         hres = dispex_get_id(_IDispatchEx_(scope->obj), identifier, 0, &id);
436         if(SUCCEEDED(hres))
437             break;
438     }
439
440     if(scope) {
441         exprval_set_idref(ret, (IDispatch*)_IDispatchEx_(scope->obj), id);
442         return S_OK;
443     }
444
445     hres = dispex_get_id(_IDispatchEx_(ctx->parser->script->global), identifier, 0, &id);
446     if(SUCCEEDED(hres)) {
447         exprval_set_idref(ret, (IDispatch*)_IDispatchEx_(ctx->parser->script->global), id);
448         return S_OK;
449     }
450
451     for(item = ctx->parser->script->named_items; item; item = item->next) {
452         hres = disp_get_id(item->disp, identifier, 0, &id);
453         if(SUCCEEDED(hres))
454             break;
455     }
456
457     if(item) {
458         exprval_set_idref(ret, (IDispatch*)item->disp, id);
459         return S_OK;
460     }
461
462     hres = dispex_get_id(_IDispatchEx_(ctx->parser->script->script_disp), identifier, 0, &id);
463     if(SUCCEEDED(hres)) {
464         exprval_set_idref(ret, (IDispatch*)_IDispatchEx_(ctx->parser->script->script_disp), id);
465         return S_OK;
466     }
467
468     if(flags & EXPR_NEWREF) {
469         hres = dispex_get_id(_IDispatchEx_(ctx->var_disp), identifier, fdexNameEnsure, &id);
470         if(FAILED(hres))
471             return hres;
472
473         exprval_set_idref(ret, (IDispatch*)_IDispatchEx_(ctx->var_disp), id);
474         return S_OK;
475     }
476
477     WARN("Could not find identifier %s\n", debugstr_w(identifier));
478     return E_FAIL;
479 }
480
481 /* ECMA-262 3rd Edition    12.1 */
482 HRESULT block_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
483 {
484     block_statement_t *stat = (block_statement_t*)_stat;
485     VARIANT val, tmp;
486     statement_t *iter;
487     HRESULT hres = S_OK;
488
489     TRACE("\n");
490
491     V_VT(&val) = VT_EMPTY;
492     for(iter = stat->stat_list; iter; iter = iter->next) {
493         hres = stat_eval(ctx, iter, rt, &tmp);
494         if(FAILED(hres))
495             break;
496
497         VariantClear(&val);
498         val = tmp;
499         if(rt->type != RT_NORMAL)
500             break;
501     }
502
503     if(FAILED(hres)) {
504         VariantClear(&val);
505         return hres;
506     }
507
508     *ret = val;
509     return S_OK;
510 }
511
512 /* ECMA-262 3rd Edition    12.2 */
513 static HRESULT variable_list_eval(exec_ctx_t *ctx, variable_declaration_t *var_list, jsexcept_t *ei)
514 {
515     variable_declaration_t *iter;
516     HRESULT hres;
517
518     for(iter = var_list; iter; iter = iter->next) {
519         VARIANT val;
520
521         if(iter->expr) {
522             exprval_t exprval;
523
524             hres = expr_eval(ctx, iter->expr, 0, ei, &exprval);
525             if(FAILED(hres))
526                 break;
527
528             hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
529             exprval_release(&exprval);
530             if(FAILED(hres))
531                 break;
532         }else {
533             V_VT(&val) = VT_EMPTY;
534         }
535
536         hres = jsdisp_propput_name(ctx->var_disp, iter->identifier, ctx->parser->script->lcid, &val, ei, NULL/*FIXME*/);
537         VariantClear(&val);
538         if(FAILED(hres))
539             break;
540     }
541
542     return hres;
543 }
544
545 /* ECMA-262 3rd Edition    12.2 */
546 HRESULT var_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
547 {
548     var_statement_t *stat = (var_statement_t*)_stat;
549     HRESULT hres;
550
551     TRACE("\n");
552
553     hres = variable_list_eval(ctx, stat->variable_list, &rt->ei);
554     if(FAILED(hres))
555         return hres;
556
557     V_VT(ret) = VT_EMPTY;
558     return S_OK;
559 }
560
561 /* ECMA-262 3rd Edition    12.3 */
562 HRESULT empty_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
563 {
564     TRACE("\n");
565
566     V_VT(ret) = VT_EMPTY;
567     return S_OK;
568 }
569
570 /* ECMA-262 3rd Edition    12.4 */
571 HRESULT expression_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
572 {
573     expression_statement_t *stat = (expression_statement_t*)_stat;
574     exprval_t exprval;
575     VARIANT val;
576     HRESULT hres;
577
578     TRACE("\n");
579
580     hres = expr_eval(ctx, stat->expr, EXPR_NOVAL, &rt->ei, &exprval);
581     if(FAILED(hres))
582         return hres;
583
584     hres = exprval_to_value(ctx->parser->script, &exprval, &rt->ei, &val);
585     exprval_release(&exprval);
586     if(FAILED(hres))
587         return hres;
588
589     *ret = val;
590     TRACE("= %s\n", debugstr_variant(ret));
591     return S_OK;
592 }
593
594 /* ECMA-262 3rd Edition    12.5 */
595 HRESULT if_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
596 {
597     if_statement_t *stat = (if_statement_t*)_stat;
598     exprval_t exprval;
599     VARIANT_BOOL b;
600     HRESULT hres;
601
602     TRACE("\n");
603
604     hres = expr_eval(ctx, stat->expr, 0, &rt->ei, &exprval);
605     if(FAILED(hres))
606         return hres;
607
608     hres = exprval_to_boolean(ctx->parser->script, &exprval, &rt->ei, &b);
609     exprval_release(&exprval);
610     if(FAILED(hres))
611         return hres;
612
613     if(b)
614         hres = stat_eval(ctx, stat->if_stat, rt, ret);
615     else if(stat->else_stat)
616         hres = stat_eval(ctx, stat->else_stat, rt, ret);
617     else
618         V_VT(ret) = VT_EMPTY;
619
620     return hres;
621 }
622
623 HRESULT dowhile_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
624 {
625     FIXME("\n");
626     return E_NOTIMPL;
627 }
628
629 HRESULT while_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
630 {
631     FIXME("\n");
632     return E_NOTIMPL;
633 }
634
635 HRESULT for_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
636 {
637     FIXME("\n");
638     return E_NOTIMPL;
639 }
640
641 HRESULT forin_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
642 {
643     FIXME("\n");
644     return E_NOTIMPL;
645 }
646
647 HRESULT continue_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
648 {
649     FIXME("\n");
650     return E_NOTIMPL;
651 }
652
653 HRESULT break_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
654 {
655     FIXME("\n");
656     return E_NOTIMPL;
657 }
658
659 /* ECMA-262 3rd Edition    12.9 */
660 HRESULT return_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
661 {
662     expression_statement_t *stat = (expression_statement_t*)_stat;
663     HRESULT hres;
664
665     TRACE("\n");
666
667     if(stat->expr) {
668         exprval_t exprval;
669
670         hres = expr_eval(ctx, stat->expr, 0, &rt->ei, &exprval);
671         if(FAILED(hres))
672             return hres;
673
674         hres = exprval_to_value(ctx->parser->script, &exprval, &rt->ei, ret);
675         exprval_release(&exprval);
676         if(FAILED(hres))
677             return hres;
678     }else {
679         V_VT(ret) = VT_EMPTY;
680     }
681
682     TRACE("= %s\n", debugstr_variant(ret));
683     rt->type = RT_RETURN;
684     return S_OK;
685 }
686
687 HRESULT with_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
688 {
689     FIXME("\n");
690     return E_NOTIMPL;
691 }
692
693 HRESULT labelled_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
694 {
695     FIXME("\n");
696     return E_NOTIMPL;
697 }
698
699 HRESULT switch_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
700 {
701     FIXME("\n");
702     return E_NOTIMPL;
703 }
704
705 HRESULT throw_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
706 {
707     FIXME("\n");
708     return E_NOTIMPL;
709 }
710
711 HRESULT try_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
712 {
713     FIXME("\n");
714     return E_NOTIMPL;
715 }
716
717 static HRESULT return_bool(exprval_t *ret, DWORD b)
718 {
719     ret->type = EXPRVAL_VARIANT;
720     V_VT(&ret->u.var) = VT_BOOL;
721     V_BOOL(&ret->u.var) = b ? VARIANT_TRUE : VARIANT_FALSE;
722
723     return S_OK;
724 }
725
726 static HRESULT get_binary_expr_values(exec_ctx_t *ctx, binary_expression_t *expr, jsexcept_t *ei, VARIANT *lval, VARIANT *rval)
727 {
728     exprval_t exprval;
729     HRESULT hres;
730
731     hres = expr_eval(ctx, expr->expression1, 0, ei, &exprval);
732     if(FAILED(hres))
733         return hres;
734
735     hres = exprval_to_value(ctx->parser->script, &exprval, ei, lval);
736     exprval_release(&exprval);
737     if(FAILED(hres))
738         return hres;
739
740     hres = expr_eval(ctx, expr->expression2, 0, ei, &exprval);
741     if(SUCCEEDED(hres)) {
742         hres = exprval_to_value(ctx->parser->script, &exprval, ei, rval);
743         exprval_release(&exprval);
744     }
745
746     if(FAILED(hres)) {
747         VariantClear(lval);
748         return hres;
749     }
750
751     return S_OK;
752 }
753
754 /* ECMA-262 3rd Edition    13 */
755 HRESULT function_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
756 {
757     function_expression_t *expr = (function_expression_t*)_expr;
758     DispatchEx *dispex;
759     VARIANT var;
760     HRESULT hres;
761
762     TRACE("\n");
763
764     hres = create_source_function(ctx->parser, expr->parameter_list, expr->source_elements, ctx->scope_chain, &dispex);
765     if(FAILED(hres))
766         return hres;
767
768     V_VT(&var) = VT_DISPATCH;
769     V_DISPATCH(&var) = (IDispatch*)_IDispatchEx_(dispex);
770
771     if(expr->identifier) {
772         hres = jsdisp_propput_name(ctx->var_disp, expr->identifier, ctx->parser->script->lcid, &var, ei, NULL/*FIXME*/);
773         if(FAILED(hres)) {
774             jsdisp_release(dispex);
775             return hres;
776         }
777     }
778
779     ret->type = EXPRVAL_VARIANT;
780     ret->u.var = var;
781     return S_OK;
782 }
783
784 /* ECMA-262 3rd Edition    11.12 */
785 HRESULT conditional_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
786 {
787     conditional_expression_t *expr = (conditional_expression_t*)_expr;
788     exprval_t exprval;
789     VARIANT_BOOL b;
790     HRESULT hres;
791
792     TRACE("\n");
793
794     hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
795     if(FAILED(hres))
796         return hres;
797
798     hres = exprval_to_boolean(ctx->parser->script, &exprval, ei, &b);
799     exprval_release(&exprval);
800     if(FAILED(hres))
801         return hres;
802
803     return expr_eval(ctx, b ? expr->true_expression : expr->false_expression, flags, ei, ret);
804 }
805
806 /* ECMA-262 3rd Edition    11.2.1 */
807 HRESULT array_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
808 {
809     array_expression_t *expr = (array_expression_t*)_expr;
810     exprval_t exprval;
811     VARIANT member, val;
812     DISPID id;
813     BSTR str;
814     IDispatch *obj = NULL;
815     HRESULT hres;
816
817     TRACE("\n");
818
819     hres = expr_eval(ctx, expr->member_expr, EXPR_NEWREF, ei, &exprval);
820     if(FAILED(hres))
821         return hres;
822
823     hres = exprval_to_value(ctx->parser->script, &exprval, ei, &member);
824     exprval_release(&exprval);
825     if(FAILED(hres))
826         return hres;
827
828     hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval);
829     if(SUCCEEDED(hres)) {
830         hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
831         exprval_release(&exprval);
832     }
833
834     if(SUCCEEDED(hres))
835         hres = to_object(ctx, &member, &obj);
836     VariantClear(&member);
837     if(SUCCEEDED(hres)) {
838         hres = to_string(ctx->parser->script, &val, ei, &str);
839         if(SUCCEEDED(hres)) {
840             if(flags & EXPR_STRREF) {
841                 ret->type = EXPRVAL_NAMEREF;
842                 ret->u.nameref.disp = obj;
843                 ret->u.nameref.name = str;
844                 return S_OK;
845             }
846
847             hres = disp_get_id(obj, str, flags & EXPR_NEWREF ? fdexNameEnsure : 0, &id);
848         }
849
850         if(SUCCEEDED(hres)) {
851             exprval_set_idref(ret, obj, id);
852         }else if(!(flags & EXPR_NEWREF) && hres == DISP_E_UNKNOWNNAME) {
853             exprval_init(ret);
854             hres = S_OK;
855         }
856
857         IDispatch_Release(obj);
858     }
859
860     return hres;
861 }
862
863 /* ECMA-262 3rd Edition    11.2.1 */
864 HRESULT member_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
865 {
866     member_expression_t *expr = (member_expression_t*)_expr;
867     IDispatch *obj = NULL;
868     exprval_t exprval;
869     VARIANT member;
870     DISPID id;
871     BSTR str;
872     HRESULT hres;
873
874     TRACE("\n");
875
876     hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
877     if(FAILED(hres))
878         return hres;
879
880     hres = exprval_to_value(ctx->parser->script, &exprval, ei, &member);
881     exprval_release(&exprval);
882     if(FAILED(hres))
883         return hres;
884
885     hres = to_object(ctx, &member, &obj);
886     VariantClear(&member);
887     if(FAILED(hres))
888         return hres;
889
890     str = SysAllocString(expr->identifier);
891     if(flags & EXPR_STRREF) {
892         ret->type = EXPRVAL_NAMEREF;
893         ret->u.nameref.disp = obj;
894         ret->u.nameref.name = str;
895         return S_OK;
896     }
897
898     hres = disp_get_id(obj, str, flags & EXPR_NEW ? fdexNameEnsure : 0, &id);
899     SysFreeString(str);
900     if(SUCCEEDED(hres)) {
901         exprval_set_idref(ret, obj, id);
902     }else if(!(flags & EXPR_NEWREF) && hres == DISP_E_UNKNOWNNAME) {
903         exprval_init(ret);
904         hres = S_OK;
905     }
906
907     IDispatch_Release(obj);
908     return hres;
909 }
910
911 static void free_dp(DISPPARAMS *dp)
912 {
913     DWORD i;
914
915     for(i=0; i < dp->cArgs; i++)
916         VariantClear(dp->rgvarg+i);
917     heap_free(dp->rgvarg);
918 }
919
920 static HRESULT args_to_param(exec_ctx_t *ctx, argument_t *args, jsexcept_t *ei, DISPPARAMS *dp)
921 {
922     VARIANTARG *vargs;
923     exprval_t exprval;
924     argument_t *iter;
925     DWORD cnt = 0, i;
926     HRESULT hres = S_OK;
927
928     memset(dp, 0, sizeof(*dp));
929
930     for(iter = args; iter; iter = iter->next)
931         cnt++;
932     if(!cnt)
933         return S_OK;
934
935     vargs = heap_alloc_zero(cnt * sizeof(*vargs));
936     if(!vargs)
937         return E_OUTOFMEMORY;
938
939     for(i = cnt, iter = args; iter; iter = iter->next) {
940         hres = expr_eval(ctx, iter->expr, 0, ei, &exprval);
941         if(FAILED(hres))
942             break;
943
944         hres = exprval_to_value(ctx->parser->script, &exprval, ei, vargs + (--i));
945         exprval_release(&exprval);
946         if(FAILED(hres))
947             break;
948     }
949
950     if(FAILED(hres)) {
951         free_dp(dp);
952         return hres;
953     }
954
955     dp->rgvarg = vargs;
956     dp->cArgs = cnt;
957     return S_OK;
958 }
959
960 /* ECMA-262 3rd Edition    11.2.2 */
961 HRESULT member_new_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
962 {
963     call_expression_t *expr = (call_expression_t*)_expr;
964     exprval_t exprval;
965     VARIANT constr, var;
966     DISPPARAMS dp;
967     HRESULT hres;
968
969     TRACE("\n");
970
971     hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
972     if(FAILED(hres))
973         return hres;
974
975     hres = args_to_param(ctx, expr->argument_list, ei, &dp);
976     if(SUCCEEDED(hres))
977         hres = exprval_to_value(ctx->parser->script, &exprval, ei, &constr);
978     exprval_release(&exprval);
979     if(FAILED(hres))
980         return hres;
981
982     if(V_VT(&constr) != VT_DISPATCH) {
983         FIXME("throw TypeError\n");
984         VariantClear(&constr);
985         return E_FAIL;
986     }
987
988     hres = disp_call(V_DISPATCH(&constr), DISPID_VALUE, ctx->parser->script->lcid,
989                      DISPATCH_CONSTRUCT, &dp, &var, ei, NULL/*FIXME*/);
990     IDispatch_Release(V_DISPATCH(&constr));
991     if(FAILED(hres))
992         return hres;
993
994     ret->type = EXPRVAL_VARIANT;
995     ret->u.var = var;
996     return S_OK;
997 }
998
999 HRESULT call_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1000 {
1001     call_expression_t *expr = (call_expression_t*)_expr;
1002     VARIANT func, var;
1003     exprval_t exprval;
1004     DISPPARAMS dp;
1005     HRESULT hres;
1006
1007     TRACE("\n");
1008
1009     hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
1010     if(FAILED(hres))
1011         return hres;
1012
1013     hres = args_to_param(ctx, expr->argument_list, ei, &dp);
1014     if(SUCCEEDED(hres)) {
1015         switch(exprval.type) {
1016         case EXPRVAL_IDREF:
1017             hres = disp_call(exprval.u.idref.disp, exprval.u.idref.id, ctx->parser->script->lcid, DISPATCH_METHOD,
1018                     &dp, flags & EXPR_NOVAL ? NULL : &var, ei, NULL/*FIXME*/);
1019             if(flags & EXPR_NOVAL)
1020                 V_VT(&var) = VT_EMPTY;
1021             break;
1022         default:
1023             FIXME("unimplemented type %d\n", V_VT(&func));
1024             hres = E_NOTIMPL;
1025         }
1026
1027         free_dp(&dp);
1028     }
1029
1030     exprval_release(&exprval);
1031     if(FAILED(hres))
1032         return hres;
1033
1034     TRACE("= %s\n", debugstr_variant(&var));
1035     ret->type = EXPRVAL_VARIANT;
1036     ret->u.var = var;
1037     return S_OK;
1038 }
1039
1040 HRESULT this_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1041 {
1042     TRACE("\n");
1043
1044     ret->type = EXPRVAL_VARIANT;
1045     V_VT(&ret->u.var) = VT_DISPATCH;
1046     V_DISPATCH(&ret->u.var) = ctx->this_obj;
1047     IDispatch_AddRef(ctx->this_obj);
1048     return S_OK;
1049 }
1050
1051 /* ECMA-262 3rd Edition    10.1.4 */
1052 HRESULT identifier_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1053 {
1054     identifier_expression_t *expr = (identifier_expression_t*)_expr;
1055     BSTR identifier;
1056     HRESULT hres;
1057
1058     TRACE("\n");
1059
1060     identifier = SysAllocString(expr->identifier);
1061     if(!identifier)
1062         return E_OUTOFMEMORY;
1063
1064     hres = identifier_eval(ctx, identifier, flags, ret);
1065
1066     SysFreeString(identifier);
1067     return hres;
1068 }
1069
1070 /* ECMA-262 3rd Edition    7.8 */
1071 HRESULT literal_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1072 {
1073     literal_expression_t *expr = (literal_expression_t*)_expr;
1074     VARIANT var;
1075     HRESULT hres;
1076
1077     TRACE("\n");
1078
1079     hres = literal_to_var(expr->literal, &var);
1080     if(FAILED(hres))
1081         return hres;
1082
1083     ret->type = EXPRVAL_VARIANT;
1084     ret->u.var = var;
1085     return S_OK;
1086 }
1087
1088 HRESULT array_literal_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1089 {
1090     FIXME("\n");
1091     return E_NOTIMPL;
1092 }
1093
1094 /* ECMA-262 3rd Edition    11.1.5 */
1095 HRESULT property_value_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1096 {
1097     property_value_expression_t *expr = (property_value_expression_t*)_expr;
1098     VARIANT val, tmp;
1099     DispatchEx *obj;
1100     prop_val_t *iter;
1101     exprval_t exprval;
1102     BSTR name;
1103     HRESULT hres;
1104
1105     TRACE("\n");
1106
1107     hres = create_object(ctx->parser->script, NULL, &obj);
1108     if(FAILED(hres))
1109         return hres;
1110
1111     for(iter = expr->property_list; iter; iter = iter->next) {
1112         hres = literal_to_var(iter->name, &tmp);
1113         if(FAILED(hres))
1114             break;
1115
1116         hres = to_string(ctx->parser->script, &tmp, ei, &name);
1117         VariantClear(&tmp);
1118         if(FAILED(hres))
1119             break;
1120
1121         hres = expr_eval(ctx, iter->value, 0, ei, &exprval);
1122         if(SUCCEEDED(hres)) {
1123             hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
1124             exprval_release(&exprval);
1125             if(SUCCEEDED(hres)) {
1126                 hres = jsdisp_propput_name(obj, name, ctx->parser->script->lcid, &val, ei, NULL/*FIXME*/);
1127                 VariantClear(&val);
1128             }
1129         }
1130
1131         SysFreeString(name);
1132         if(FAILED(hres))
1133             break;
1134     }
1135
1136     if(FAILED(hres)) {
1137         jsdisp_release(obj);
1138         return hres;
1139     }
1140
1141     ret->type = EXPRVAL_VARIANT;
1142     V_VT(&ret->u.var) = VT_DISPATCH;
1143     V_DISPATCH(&ret->u.var) = (IDispatch*)_IDispatchEx_(obj);
1144     return S_OK;
1145 }
1146
1147 HRESULT comma_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1148 {
1149     FIXME("\n");
1150     return E_NOTIMPL;
1151 }
1152
1153 HRESULT logical_or_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1154 {
1155     FIXME("\n");
1156     return E_NOTIMPL;
1157 }
1158
1159 HRESULT logical_and_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1160 {
1161     FIXME("\n");
1162     return E_NOTIMPL;
1163 }
1164
1165 HRESULT binary_or_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1166 {
1167     FIXME("\n");
1168     return E_NOTIMPL;
1169 }
1170
1171 HRESULT binary_xor_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1172 {
1173     FIXME("\n");
1174     return E_NOTIMPL;
1175 }
1176
1177 HRESULT binary_and_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1178 {
1179     FIXME("\n");
1180     return E_NOTIMPL;
1181 }
1182
1183 HRESULT instanceof_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1184 {
1185     FIXME("\n");
1186     return E_NOTIMPL;
1187 }
1188
1189 HRESULT in_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1190 {
1191     FIXME("\n");
1192     return E_NOTIMPL;
1193 }
1194
1195 HRESULT add_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1196 {
1197     FIXME("\n");
1198     return E_NOTIMPL;
1199 }
1200
1201 HRESULT sub_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1202 {
1203     FIXME("\n");
1204     return E_NOTIMPL;
1205 }
1206
1207 HRESULT mul_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1208 {
1209     FIXME("\n");
1210     return E_NOTIMPL;
1211 }
1212
1213 HRESULT div_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1214 {
1215     FIXME("\n");
1216     return E_NOTIMPL;
1217 }
1218
1219 HRESULT mod_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1220 {
1221     FIXME("\n");
1222     return E_NOTIMPL;
1223 }
1224
1225 HRESULT delete_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1226 {
1227     FIXME("\n");
1228     return E_NOTIMPL;
1229 }
1230
1231 HRESULT void_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1232 {
1233     FIXME("\n");
1234     return E_NOTIMPL;
1235 }
1236
1237 HRESULT typeof_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1238 {
1239     unary_expression_t *expr = (unary_expression_t*)_expr;
1240     const WCHAR *str;
1241     exprval_t exprval;
1242     VARIANT val;
1243     HRESULT hres;
1244
1245     static const WCHAR booleanW[] = {'b','o','o','l','e','a','n',0};
1246     static const WCHAR functionW[] = {'f','u','n','c','t','i','o','n',0};
1247     static const WCHAR numberW[] = {'n','u','m','b','e','r',0};
1248     static const WCHAR objectW[] = {'o','b','j','e','c','t',0};
1249     static const WCHAR stringW[] = {'s','t','r','i','n','g',0};
1250     static const WCHAR undefinedW[] = {'u','n','d','e','f','i','n','e','d',0};
1251
1252     TRACE("\n");
1253
1254     hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
1255     if(FAILED(hres))
1256         return hres;
1257
1258     hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
1259     exprval_release(&exprval);
1260     if(FAILED(hres))
1261         return hres;
1262
1263     switch(V_VT(&val)) {
1264     case VT_EMPTY:
1265         str = undefinedW;
1266         break;
1267     case VT_NULL:
1268         str = objectW;
1269         break;
1270     case VT_BOOL:
1271         str = booleanW;
1272         break;
1273     case VT_I4:
1274     case VT_R8:
1275         str = numberW;
1276         break;
1277     case VT_BSTR:
1278         str = stringW;
1279         break;
1280     case VT_DISPATCH: {
1281         DispatchEx *dispex;
1282
1283         dispex = iface_to_jsdisp((IUnknown*)V_DISPATCH(&val));
1284         if(dispex) {
1285             str = dispex->builtin_info->class == JSCLASS_FUNCTION ? functionW : objectW;
1286             IDispatchEx_Release(_IDispatchEx_(dispex));
1287         }else {
1288             str = objectW;
1289         }
1290         break;
1291     }
1292     default:
1293         FIXME("unhandled vt %d\n", V_VT(&val));
1294         hres = E_NOTIMPL;
1295     }
1296
1297     VariantClear(&val);
1298     if(FAILED(hres))
1299         return hres;
1300
1301     ret->type = EXPRVAL_VARIANT;
1302     V_VT(&ret->u.var) = VT_BSTR;
1303     V_BSTR(&ret->u.var) = SysAllocString(str);
1304     return S_OK;
1305 }
1306
1307 HRESULT minus_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1308 {
1309     FIXME("\n");
1310     return E_NOTIMPL;
1311 }
1312
1313 HRESULT plus_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1314 {
1315     FIXME("\n");
1316     return E_NOTIMPL;
1317 }
1318
1319 HRESULT post_increment_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1320 {
1321     FIXME("\n");
1322     return E_NOTIMPL;
1323 }
1324
1325 HRESULT post_decrement_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1326 {
1327     FIXME("\n");
1328     return E_NOTIMPL;
1329 }
1330
1331 HRESULT pre_increment_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1332 {
1333     FIXME("\n");
1334     return E_NOTIMPL;
1335 }
1336
1337 HRESULT pre_decrement_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1338 {
1339     FIXME("\n");
1340     return E_NOTIMPL;
1341 }
1342
1343 HRESULT new_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1344 {
1345     FIXME("\n");
1346     return E_NOTIMPL;
1347 }
1348
1349 HRESULT equal_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1350 {
1351     FIXME("\n");
1352     return E_NOTIMPL;
1353 }
1354
1355 /* ECMA-262 3rd Edition    11.9.4 */
1356 HRESULT equal2_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1357 {
1358     binary_expression_t *expr = (binary_expression_t*)_expr;
1359     VARIANT rval, lval;
1360     BOOL b;
1361     HRESULT hres;
1362
1363     TRACE("\n");
1364
1365     hres = get_binary_expr_values(ctx, expr, ei, &rval, &lval);
1366     if(FAILED(hres))
1367         return hres;
1368
1369     hres = equal2_values(&rval, &lval, &b);
1370     if(FAILED(hres))
1371         return hres;
1372
1373     return return_bool(ret, b);
1374 }
1375
1376 HRESULT not_equal_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1377 {
1378
1379     FIXME("\n");
1380     return E_NOTIMPL;
1381 }
1382
1383 /* ECMA-262 3rd Edition    11.9.5 */
1384 HRESULT not_equal2_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1385 {
1386     binary_expression_t *expr = (binary_expression_t*)_expr;
1387     VARIANT rval, lval;
1388     BOOL b;
1389     HRESULT hres;
1390
1391     TRACE("\n");
1392
1393     hres = get_binary_expr_values(ctx, expr, ei, &rval, &lval);
1394     if(FAILED(hres))
1395         return hres;
1396
1397     hres = equal2_values(&rval, &lval, &b);
1398     if(FAILED(hres))
1399         return hres;
1400
1401     return return_bool(ret, !b);
1402 }
1403
1404 HRESULT less_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1405 {
1406     FIXME("\n");
1407     return E_NOTIMPL;
1408 }
1409
1410 HRESULT lesseq_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1411 {
1412     FIXME("\n");
1413     return E_NOTIMPL;
1414 }
1415
1416 HRESULT greater_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1417 {
1418     FIXME("\n");
1419     return E_NOTIMPL;
1420 }
1421
1422 HRESULT greatereq_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1423 {
1424     FIXME("\n");
1425     return E_NOTIMPL;
1426 }
1427
1428 HRESULT binary_negation_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1429 {
1430     FIXME("\n");
1431     return E_NOTIMPL;
1432 }
1433
1434 /* ECMA-262 3rd Edition    11.4.9 */
1435 HRESULT logical_negation_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1436 {
1437     unary_expression_t *expr = (unary_expression_t*)_expr;
1438     exprval_t exprval;
1439     VARIANT_BOOL b;
1440     HRESULT hres;
1441
1442     TRACE("\n");
1443
1444     hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval);
1445     if(FAILED(hres))
1446         return hres;
1447
1448     hres = exprval_to_boolean(ctx->parser->script, &exprval, ei, &b);
1449     exprval_release(&exprval);
1450     if(FAILED(hres))
1451         return hres;
1452
1453     return return_bool(ret, !b);
1454 }
1455
1456 HRESULT left_shift_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1457 {
1458     FIXME("\n");
1459     return E_NOTIMPL;
1460 }
1461
1462 HRESULT right_shift_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1463 {
1464     FIXME("\n");
1465     return E_NOTIMPL;
1466 }
1467
1468 HRESULT right2_shift_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1469 {
1470     FIXME("\n");
1471     return E_NOTIMPL;
1472 }
1473
1474 /* ECMA-262 3rd Edition    11.13.1 */
1475 HRESULT assign_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1476 {
1477     binary_expression_t *expr = (binary_expression_t*)_expr;
1478     exprval_t exprval, exprvalr;
1479     VARIANT rval;
1480     HRESULT hres;
1481
1482     TRACE("\n");
1483
1484     hres = expr_eval(ctx, expr->expression1, EXPR_NEWREF, ei, &exprval);
1485     if(FAILED(hres))
1486         return hres;
1487
1488     hres = expr_eval(ctx, expr->expression2, 0, ei, &exprvalr);
1489     if(SUCCEEDED(hres)) {
1490         hres = exprval_to_value(ctx->parser->script, &exprvalr, ei, &rval);
1491         exprval_release(&exprvalr);
1492     }
1493
1494     if(SUCCEEDED(hres))
1495         hres = put_value(ctx->parser->script, &exprval, &rval, ei);
1496
1497     exprval_release(&exprval);
1498     if(FAILED(hres)) {
1499         VariantClear(&rval);
1500         return hres;
1501     }
1502
1503     ret->type = EXPRVAL_VARIANT;
1504     ret->u.var = rval;
1505     return S_OK;
1506 }
1507
1508 HRESULT assign_lshift_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1509 {
1510     FIXME("\n");
1511     return E_NOTIMPL;
1512 }
1513
1514 HRESULT assign_rshift_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1515 {
1516     FIXME("\n");
1517     return E_NOTIMPL;
1518 }
1519
1520 HRESULT assign_rrshift_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1521 {
1522     FIXME("\n");
1523     return E_NOTIMPL;
1524 }
1525
1526 HRESULT assign_add_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1527 {
1528     FIXME("\n");
1529     return E_NOTIMPL;
1530 }
1531
1532 HRESULT assign_sub_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1533 {
1534     FIXME("\n");
1535     return E_NOTIMPL;
1536 }
1537
1538 HRESULT assign_mul_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1539 {
1540     FIXME("\n");
1541     return E_NOTIMPL;
1542 }
1543
1544 HRESULT assign_div_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1545 {
1546     FIXME("\n");
1547     return E_NOTIMPL;
1548 }
1549
1550 HRESULT assign_mod_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1551 {
1552     FIXME("\n");
1553     return E_NOTIMPL;
1554 }
1555
1556 HRESULT assign_and_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1557 {
1558     FIXME("\n");
1559     return E_NOTIMPL;
1560 }
1561
1562 HRESULT assign_or_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1563 {
1564     FIXME("\n");
1565     return E_NOTIMPL;
1566 }
1567
1568 HRESULT assign_xor_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1569 {
1570     FIXME("\n");
1571     return E_NOTIMPL;
1572 }