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