jscript: Added throw 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 /* ECMA-262 3rd Edition    12.13 */
726 HRESULT throw_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
727 {
728     expression_statement_t *stat = (expression_statement_t*)_stat;
729     exprval_t exprval;
730     VARIANT val;
731     HRESULT hres;
732
733     TRACE("\n");
734
735     hres = expr_eval(ctx, stat->expr, 0, &rt->ei, &exprval);
736     if(FAILED(hres))
737         return hres;
738
739     hres = exprval_to_value(ctx->parser->script, &exprval, &rt->ei, &val);
740     exprval_release(&exprval);
741     if(FAILED(hres))
742         return hres;
743
744     rt->ei.var = val;
745     return DISP_E_EXCEPTION;
746 }
747
748 /* ECMA-262 3rd Edition    12.14 */
749 static HRESULT catch_eval(exec_ctx_t *ctx, catch_block_t *block, return_type_t *rt, VARIANT *ret)
750 {
751     DispatchEx *var_disp;
752     VARIANT ex, val;
753     HRESULT hres;
754
755     ex = rt->ei.var;
756     memset(&rt->ei, 0, sizeof(jsexcept_t));
757
758     hres = create_dispex(ctx->parser->script, NULL, NULL, &var_disp);
759     if(SUCCEEDED(hres)) {
760         hres = jsdisp_propput_name(var_disp, block->identifier, ctx->parser->script->lcid,
761                 &ex, &rt->ei, NULL/*FIXME*/);
762         if(SUCCEEDED(hres)) {
763             hres = scope_push(ctx->scope_chain, var_disp, &ctx->scope_chain);
764             if(SUCCEEDED(hres)) {
765                 hres = stat_eval(ctx, block->statement, rt, &val);
766                 scope_pop(&ctx->scope_chain);
767             }
768         }
769
770         jsdisp_release(var_disp);
771     }
772
773     VariantClear(&ex);
774     if(FAILED(hres))
775         return hres;
776
777     *ret = val;
778     return S_OK;
779 }
780
781 /* ECMA-262 3rd Edition    12.14 */
782 HRESULT try_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
783 {
784     try_statement_t *stat = (try_statement_t*)_stat;
785     VARIANT val;
786     HRESULT hres;
787
788     TRACE("\n");
789
790     hres = stat_eval(ctx, stat->try_statement, rt, &val);
791     if(FAILED(hres)) {
792         TRACE("EXCEPTION\n");
793         if(!stat->catch_block)
794             return hres;
795
796         hres = catch_eval(ctx, stat->catch_block, rt, &val);
797         if(FAILED(hres))
798             return hres;
799     }
800
801     if(stat->finally_statement) {
802         VariantClear(&val);
803         hres = stat_eval(ctx, stat->finally_statement, rt, &val);
804         if(FAILED(hres))
805             return hres;
806     }
807
808     *ret = val;
809     return S_OK;
810 }
811
812 static HRESULT return_bool(exprval_t *ret, DWORD b)
813 {
814     ret->type = EXPRVAL_VARIANT;
815     V_VT(&ret->u.var) = VT_BOOL;
816     V_BOOL(&ret->u.var) = b ? VARIANT_TRUE : VARIANT_FALSE;
817
818     return S_OK;
819 }
820
821 static HRESULT get_binary_expr_values(exec_ctx_t *ctx, binary_expression_t *expr, jsexcept_t *ei, VARIANT *lval, VARIANT *rval)
822 {
823     exprval_t exprval;
824     HRESULT hres;
825
826     hres = expr_eval(ctx, expr->expression1, 0, ei, &exprval);
827     if(FAILED(hres))
828         return hres;
829
830     hres = exprval_to_value(ctx->parser->script, &exprval, ei, lval);
831     exprval_release(&exprval);
832     if(FAILED(hres))
833         return hres;
834
835     hres = expr_eval(ctx, expr->expression2, 0, ei, &exprval);
836     if(SUCCEEDED(hres)) {
837         hres = exprval_to_value(ctx->parser->script, &exprval, ei, rval);
838         exprval_release(&exprval);
839     }
840
841     if(FAILED(hres)) {
842         VariantClear(lval);
843         return hres;
844     }
845
846     return S_OK;
847 }
848
849 typedef HRESULT (*oper_t)(exec_ctx_t*,VARIANT*,VARIANT*,jsexcept_t*,VARIANT*);
850
851 static HRESULT binary_expr_eval(exec_ctx_t *ctx, binary_expression_t *expr, oper_t oper, jsexcept_t *ei,
852         exprval_t *ret)
853 {
854     VARIANT lval, rval, retv;
855     HRESULT hres;
856
857     hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval);
858     if(FAILED(hres))
859         return hres;
860
861     hres = oper(ctx, &lval, &rval, ei, &retv);
862     VariantClear(&lval);
863     VariantClear(&rval);
864     if(FAILED(hres))
865         return hres;
866
867     ret->type = EXPRVAL_VARIANT;
868     ret->u.var = retv;
869     return S_OK;
870 }
871
872 /* ECMA-262 3rd Edition    11.13.2 */
873 static HRESULT assign_oper_eval(exec_ctx_t *ctx, expression_t *lexpr, expression_t *rexpr, oper_t oper,
874                                 jsexcept_t *ei, exprval_t *ret)
875 {
876     VARIANT retv, lval, rval;
877     exprval_t exprval, exprvalr;
878     HRESULT hres;
879
880     hres = expr_eval(ctx, lexpr, EXPR_NEWREF, ei, &exprval);
881     if(FAILED(hres))
882         return hres;
883
884     hres = exprval_value(ctx->parser->script, &exprval, ei, &lval);
885     if(SUCCEEDED(hres)) {
886         hres = expr_eval(ctx, rexpr, 0, ei, &exprvalr);
887         if(SUCCEEDED(hres)) {
888             hres = exprval_value(ctx->parser->script, &exprvalr, ei, &rval);
889             exprval_release(&exprvalr);
890         }
891         if(SUCCEEDED(hres)) {
892             hres = oper(ctx, &lval, &rval, ei, &retv);
893             VariantClear(&rval);
894         }
895         VariantClear(&lval);
896     }
897
898     if(SUCCEEDED(hres)) {
899         hres = put_value(ctx->parser->script, &exprval, &retv, ei);
900         if(FAILED(hres))
901             VariantClear(&retv);
902     }
903     exprval_release(&exprval);
904
905     if(FAILED(hres))
906         return hres;
907
908     ret->type = EXPRVAL_VARIANT;
909     ret->u.var = retv;
910     return S_OK;
911 }
912
913 /* ECMA-262 3rd Edition    13 */
914 HRESULT function_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
915 {
916     function_expression_t *expr = (function_expression_t*)_expr;
917     DispatchEx *dispex;
918     VARIANT var;
919     HRESULT hres;
920
921     TRACE("\n");
922
923     hres = create_source_function(ctx->parser, expr->parameter_list, expr->source_elements, ctx->scope_chain, &dispex);
924     if(FAILED(hres))
925         return hres;
926
927     V_VT(&var) = VT_DISPATCH;
928     V_DISPATCH(&var) = (IDispatch*)_IDispatchEx_(dispex);
929
930     if(expr->identifier) {
931         hres = jsdisp_propput_name(ctx->var_disp, expr->identifier, ctx->parser->script->lcid, &var, ei, NULL/*FIXME*/);
932         if(FAILED(hres)) {
933             jsdisp_release(dispex);
934             return hres;
935         }
936     }
937
938     ret->type = EXPRVAL_VARIANT;
939     ret->u.var = var;
940     return S_OK;
941 }
942
943 /* ECMA-262 3rd Edition    11.12 */
944 HRESULT conditional_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
945 {
946     conditional_expression_t *expr = (conditional_expression_t*)_expr;
947     exprval_t exprval;
948     VARIANT_BOOL b;
949     HRESULT hres;
950
951     TRACE("\n");
952
953     hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
954     if(FAILED(hres))
955         return hres;
956
957     hres = exprval_to_boolean(ctx->parser->script, &exprval, ei, &b);
958     exprval_release(&exprval);
959     if(FAILED(hres))
960         return hres;
961
962     return expr_eval(ctx, b ? expr->true_expression : expr->false_expression, flags, ei, ret);
963 }
964
965 /* ECMA-262 3rd Edition    11.2.1 */
966 HRESULT array_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
967 {
968     array_expression_t *expr = (array_expression_t*)_expr;
969     exprval_t exprval;
970     VARIANT member, val;
971     DISPID id;
972     BSTR str;
973     IDispatch *obj = NULL;
974     HRESULT hres;
975
976     TRACE("\n");
977
978     hres = expr_eval(ctx, expr->member_expr, EXPR_NEWREF, ei, &exprval);
979     if(FAILED(hres))
980         return hres;
981
982     hres = exprval_to_value(ctx->parser->script, &exprval, ei, &member);
983     exprval_release(&exprval);
984     if(FAILED(hres))
985         return hres;
986
987     hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval);
988     if(SUCCEEDED(hres)) {
989         hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
990         exprval_release(&exprval);
991     }
992
993     if(SUCCEEDED(hres))
994         hres = to_object(ctx, &member, &obj);
995     VariantClear(&member);
996     if(SUCCEEDED(hres)) {
997         hres = to_string(ctx->parser->script, &val, ei, &str);
998         if(SUCCEEDED(hres)) {
999             if(flags & EXPR_STRREF) {
1000                 ret->type = EXPRVAL_NAMEREF;
1001                 ret->u.nameref.disp = obj;
1002                 ret->u.nameref.name = str;
1003                 return S_OK;
1004             }
1005
1006             hres = disp_get_id(obj, str, flags & EXPR_NEWREF ? fdexNameEnsure : 0, &id);
1007         }
1008
1009         if(SUCCEEDED(hres)) {
1010             exprval_set_idref(ret, obj, id);
1011         }else if(!(flags & EXPR_NEWREF) && hres == DISP_E_UNKNOWNNAME) {
1012             exprval_init(ret);
1013             hres = S_OK;
1014         }
1015
1016         IDispatch_Release(obj);
1017     }
1018
1019     return hres;
1020 }
1021
1022 /* ECMA-262 3rd Edition    11.2.1 */
1023 HRESULT member_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1024 {
1025     member_expression_t *expr = (member_expression_t*)_expr;
1026     IDispatch *obj = NULL;
1027     exprval_t exprval;
1028     VARIANT member;
1029     DISPID id;
1030     BSTR str;
1031     HRESULT hres;
1032
1033     TRACE("\n");
1034
1035     hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
1036     if(FAILED(hres))
1037         return hres;
1038
1039     hres = exprval_to_value(ctx->parser->script, &exprval, ei, &member);
1040     exprval_release(&exprval);
1041     if(FAILED(hres))
1042         return hres;
1043
1044     hres = to_object(ctx, &member, &obj);
1045     VariantClear(&member);
1046     if(FAILED(hres))
1047         return hres;
1048
1049     str = SysAllocString(expr->identifier);
1050     if(flags & EXPR_STRREF) {
1051         ret->type = EXPRVAL_NAMEREF;
1052         ret->u.nameref.disp = obj;
1053         ret->u.nameref.name = str;
1054         return S_OK;
1055     }
1056
1057     hres = disp_get_id(obj, str, flags & EXPR_NEW ? fdexNameEnsure : 0, &id);
1058     SysFreeString(str);
1059     if(SUCCEEDED(hres)) {
1060         exprval_set_idref(ret, obj, id);
1061     }else if(!(flags & EXPR_NEWREF) && hres == DISP_E_UNKNOWNNAME) {
1062         exprval_init(ret);
1063         hres = S_OK;
1064     }
1065
1066     IDispatch_Release(obj);
1067     return hres;
1068 }
1069
1070 static void free_dp(DISPPARAMS *dp)
1071 {
1072     DWORD i;
1073
1074     for(i=0; i < dp->cArgs; i++)
1075         VariantClear(dp->rgvarg+i);
1076     heap_free(dp->rgvarg);
1077 }
1078
1079 static HRESULT args_to_param(exec_ctx_t *ctx, argument_t *args, jsexcept_t *ei, DISPPARAMS *dp)
1080 {
1081     VARIANTARG *vargs;
1082     exprval_t exprval;
1083     argument_t *iter;
1084     DWORD cnt = 0, i;
1085     HRESULT hres = S_OK;
1086
1087     memset(dp, 0, sizeof(*dp));
1088
1089     for(iter = args; iter; iter = iter->next)
1090         cnt++;
1091     if(!cnt)
1092         return S_OK;
1093
1094     vargs = heap_alloc_zero(cnt * sizeof(*vargs));
1095     if(!vargs)
1096         return E_OUTOFMEMORY;
1097
1098     for(i = cnt, iter = args; iter; iter = iter->next) {
1099         hres = expr_eval(ctx, iter->expr, 0, ei, &exprval);
1100         if(FAILED(hres))
1101             break;
1102
1103         hres = exprval_to_value(ctx->parser->script, &exprval, ei, vargs + (--i));
1104         exprval_release(&exprval);
1105         if(FAILED(hres))
1106             break;
1107     }
1108
1109     if(FAILED(hres)) {
1110         free_dp(dp);
1111         return hres;
1112     }
1113
1114     dp->rgvarg = vargs;
1115     dp->cArgs = cnt;
1116     return S_OK;
1117 }
1118
1119 /* ECMA-262 3rd Edition    11.2.2 */
1120 HRESULT member_new_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1121 {
1122     call_expression_t *expr = (call_expression_t*)_expr;
1123     exprval_t exprval;
1124     VARIANT constr, var;
1125     DISPPARAMS dp;
1126     HRESULT hres;
1127
1128     TRACE("\n");
1129
1130     hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
1131     if(FAILED(hres))
1132         return hres;
1133
1134     hres = args_to_param(ctx, expr->argument_list, ei, &dp);
1135     if(SUCCEEDED(hres))
1136         hres = exprval_to_value(ctx->parser->script, &exprval, ei, &constr);
1137     exprval_release(&exprval);
1138     if(FAILED(hres))
1139         return hres;
1140
1141     if(V_VT(&constr) != VT_DISPATCH) {
1142         FIXME("throw TypeError\n");
1143         VariantClear(&constr);
1144         return E_FAIL;
1145     }
1146
1147     hres = disp_call(V_DISPATCH(&constr), DISPID_VALUE, ctx->parser->script->lcid,
1148                      DISPATCH_CONSTRUCT, &dp, &var, ei, NULL/*FIXME*/);
1149     IDispatch_Release(V_DISPATCH(&constr));
1150     if(FAILED(hres))
1151         return hres;
1152
1153     ret->type = EXPRVAL_VARIANT;
1154     ret->u.var = var;
1155     return S_OK;
1156 }
1157
1158 HRESULT call_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1159 {
1160     call_expression_t *expr = (call_expression_t*)_expr;
1161     VARIANT func, var;
1162     exprval_t exprval;
1163     DISPPARAMS dp;
1164     HRESULT hres;
1165
1166     TRACE("\n");
1167
1168     hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
1169     if(FAILED(hres))
1170         return hres;
1171
1172     hres = args_to_param(ctx, expr->argument_list, ei, &dp);
1173     if(SUCCEEDED(hres)) {
1174         switch(exprval.type) {
1175         case EXPRVAL_IDREF:
1176             hres = disp_call(exprval.u.idref.disp, exprval.u.idref.id, ctx->parser->script->lcid, DISPATCH_METHOD,
1177                     &dp, flags & EXPR_NOVAL ? NULL : &var, ei, NULL/*FIXME*/);
1178             if(flags & EXPR_NOVAL)
1179                 V_VT(&var) = VT_EMPTY;
1180             break;
1181         default:
1182             FIXME("unimplemented type %d\n", V_VT(&func));
1183             hres = E_NOTIMPL;
1184         }
1185
1186         free_dp(&dp);
1187     }
1188
1189     exprval_release(&exprval);
1190     if(FAILED(hres))
1191         return hres;
1192
1193     TRACE("= %s\n", debugstr_variant(&var));
1194     ret->type = EXPRVAL_VARIANT;
1195     ret->u.var = var;
1196     return S_OK;
1197 }
1198
1199 HRESULT this_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1200 {
1201     TRACE("\n");
1202
1203     ret->type = EXPRVAL_VARIANT;
1204     V_VT(&ret->u.var) = VT_DISPATCH;
1205     V_DISPATCH(&ret->u.var) = ctx->this_obj;
1206     IDispatch_AddRef(ctx->this_obj);
1207     return S_OK;
1208 }
1209
1210 /* ECMA-262 3rd Edition    10.1.4 */
1211 HRESULT identifier_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1212 {
1213     identifier_expression_t *expr = (identifier_expression_t*)_expr;
1214     BSTR identifier;
1215     HRESULT hres;
1216
1217     TRACE("\n");
1218
1219     identifier = SysAllocString(expr->identifier);
1220     if(!identifier)
1221         return E_OUTOFMEMORY;
1222
1223     hres = identifier_eval(ctx, identifier, flags, ret);
1224
1225     SysFreeString(identifier);
1226     return hres;
1227 }
1228
1229 /* ECMA-262 3rd Edition    7.8 */
1230 HRESULT literal_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1231 {
1232     literal_expression_t *expr = (literal_expression_t*)_expr;
1233     VARIANT var;
1234     HRESULT hres;
1235
1236     TRACE("\n");
1237
1238     hres = literal_to_var(expr->literal, &var);
1239     if(FAILED(hres))
1240         return hres;
1241
1242     ret->type = EXPRVAL_VARIANT;
1243     ret->u.var = var;
1244     return S_OK;
1245 }
1246
1247 HRESULT array_literal_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1248 {
1249     FIXME("\n");
1250     return E_NOTIMPL;
1251 }
1252
1253 /* ECMA-262 3rd Edition    11.1.5 */
1254 HRESULT property_value_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1255 {
1256     property_value_expression_t *expr = (property_value_expression_t*)_expr;
1257     VARIANT val, tmp;
1258     DispatchEx *obj;
1259     prop_val_t *iter;
1260     exprval_t exprval;
1261     BSTR name;
1262     HRESULT hres;
1263
1264     TRACE("\n");
1265
1266     hres = create_object(ctx->parser->script, NULL, &obj);
1267     if(FAILED(hres))
1268         return hres;
1269
1270     for(iter = expr->property_list; iter; iter = iter->next) {
1271         hres = literal_to_var(iter->name, &tmp);
1272         if(FAILED(hres))
1273             break;
1274
1275         hres = to_string(ctx->parser->script, &tmp, ei, &name);
1276         VariantClear(&tmp);
1277         if(FAILED(hres))
1278             break;
1279
1280         hres = expr_eval(ctx, iter->value, 0, ei, &exprval);
1281         if(SUCCEEDED(hres)) {
1282             hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
1283             exprval_release(&exprval);
1284             if(SUCCEEDED(hres)) {
1285                 hres = jsdisp_propput_name(obj, name, ctx->parser->script->lcid, &val, ei, NULL/*FIXME*/);
1286                 VariantClear(&val);
1287             }
1288         }
1289
1290         SysFreeString(name);
1291         if(FAILED(hres))
1292             break;
1293     }
1294
1295     if(FAILED(hres)) {
1296         jsdisp_release(obj);
1297         return hres;
1298     }
1299
1300     ret->type = EXPRVAL_VARIANT;
1301     V_VT(&ret->u.var) = VT_DISPATCH;
1302     V_DISPATCH(&ret->u.var) = (IDispatch*)_IDispatchEx_(obj);
1303     return S_OK;
1304 }
1305
1306 HRESULT comma_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1307 {
1308     FIXME("\n");
1309     return E_NOTIMPL;
1310 }
1311
1312 /* ECMA-262 3rd Edition    11.11 */
1313 HRESULT logical_or_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1314 {
1315     binary_expression_t *expr = (binary_expression_t*)_expr;
1316     exprval_t exprval;
1317     VARIANT_BOOL b;
1318     VARIANT val;
1319     HRESULT hres;
1320
1321     TRACE("\n");
1322
1323     hres = expr_eval(ctx, expr->expression1, 0, ei, &exprval);
1324     if(FAILED(hres))
1325         return hres;
1326
1327     hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
1328     exprval_release(&exprval);
1329     if(FAILED(hres))
1330         return hres;
1331
1332     hres = to_boolean(&val, &b);
1333     if(SUCCEEDED(hres) && b) {
1334         ret->type = EXPRVAL_VARIANT;
1335         ret->u.var = val;
1336         return S_OK;
1337     }
1338
1339     VariantClear(&val);
1340     if(FAILED(hres))
1341         return hres;
1342
1343     hres = expr_eval(ctx, expr->expression2, 0, ei, &exprval);
1344     if(FAILED(hres))
1345         return hres;
1346
1347     hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
1348     exprval_release(&exprval);
1349     if(FAILED(hres))
1350         return hres;
1351
1352     ret->type = EXPRVAL_VARIANT;
1353     ret->u.var = val;
1354     return S_OK;
1355 }
1356
1357 /* ECMA-262 3rd Edition    11.11 */
1358 HRESULT logical_and_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1359 {
1360     binary_expression_t *expr = (binary_expression_t*)_expr;
1361     exprval_t exprval;
1362     VARIANT_BOOL b;
1363     VARIANT val;
1364     HRESULT hres;
1365
1366     TRACE("\n");
1367
1368     hres = expr_eval(ctx, expr->expression1, 0, ei, &exprval);
1369     if(FAILED(hres))
1370         return hres;
1371
1372     hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
1373     exprval_release(&exprval);
1374     if(FAILED(hres))
1375         return hres;
1376
1377     hres = to_boolean(&val, &b);
1378     if(SUCCEEDED(hres) && !b) {
1379         ret->type = EXPRVAL_VARIANT;
1380         ret->u.var = val;
1381         return S_OK;
1382     }
1383
1384     VariantClear(&val);
1385     if(FAILED(hres))
1386         return hres;
1387
1388     hres = expr_eval(ctx, expr->expression2, 0, ei, &exprval);
1389     if(FAILED(hres))
1390         return hres;
1391
1392     hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
1393     exprval_release(&exprval);
1394     if(FAILED(hres))
1395         return hres;
1396
1397     ret->type = EXPRVAL_VARIANT;
1398     ret->u.var = val;
1399     return S_OK;
1400 }
1401
1402 HRESULT binary_or_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1403 {
1404     FIXME("\n");
1405     return E_NOTIMPL;
1406 }
1407
1408 HRESULT binary_xor_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1409 {
1410     FIXME("\n");
1411     return E_NOTIMPL;
1412 }
1413
1414 HRESULT binary_and_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1415 {
1416     FIXME("\n");
1417     return E_NOTIMPL;
1418 }
1419
1420 HRESULT instanceof_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1421 {
1422     FIXME("\n");
1423     return E_NOTIMPL;
1424 }
1425
1426 HRESULT in_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1427 {
1428     FIXME("\n");
1429     return E_NOTIMPL;
1430 }
1431
1432 /* ECMA-262 3rd Edition    11.6.1 */
1433 static HRESULT add_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
1434 {
1435     VARIANT r, l;
1436     HRESULT hres;
1437
1438     hres = to_primitive(ctx->parser->script, lval, ei, &l);
1439     if(FAILED(hres))
1440         return hres;
1441
1442     hres = to_primitive(ctx->parser->script, rval, ei, &r);
1443     if(FAILED(hres)) {
1444         VariantClear(&l);
1445         return hres;
1446     }
1447
1448     if(V_VT(&l) == VT_BSTR || V_VT(&r) == VT_BSTR) {
1449         BSTR lstr = NULL, rstr = NULL;
1450
1451         if(V_VT(&l) == VT_BSTR)
1452             lstr = V_BSTR(&l);
1453         else
1454             hres = to_string(ctx->parser->script, &l, ei, &lstr);
1455
1456         if(SUCCEEDED(hres)) {
1457             if(V_VT(&r) == VT_BSTR)
1458                 rstr = V_BSTR(&r);
1459             else
1460                 hres = to_string(ctx->parser->script, &r, ei, &rstr);
1461         }
1462
1463         if(SUCCEEDED(hres)) {
1464             int len1, len2;
1465
1466             len1 = SysStringLen(lstr);
1467             len2 = SysStringLen(rstr);
1468
1469             V_VT(retv) = VT_BSTR;
1470             V_BSTR(retv) = SysAllocStringLen(NULL, len1+len2);
1471             memcpy(V_BSTR(retv), lstr, len1*sizeof(WCHAR));
1472             memcpy(V_BSTR(retv)+len1, rstr, (len2+1)*sizeof(WCHAR));
1473         }
1474
1475         if(lstr && V_VT(&l) != VT_BSTR)
1476             SysFreeString(lstr);
1477         if(rstr && V_VT(&r) != VT_BSTR)
1478             SysFreeString(rstr);
1479     }else {
1480         VARIANT nl, nr;
1481
1482         hres = to_number(ctx->parser->script, &l, ei, &nl);
1483         if(SUCCEEDED(hres)) {
1484             hres = to_number(ctx->parser->script, &r, ei, &nr);
1485             if(SUCCEEDED(hres))
1486                 num_set_val(retv, num_val(&nl) + num_val(&nr));
1487         }
1488     }
1489
1490     VariantClear(&r);
1491     VariantClear(&l);
1492     return hres;
1493 }
1494
1495 /* ECMA-262 3rd Edition    11.6.1 */
1496 HRESULT add_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1497 {
1498     binary_expression_t *expr = (binary_expression_t*)_expr;
1499
1500     TRACE("\n");
1501
1502     return binary_expr_eval(ctx, expr, add_eval, ei, ret);
1503 }
1504
1505 HRESULT sub_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1506 {
1507     FIXME("\n");
1508     return E_NOTIMPL;
1509 }
1510
1511 HRESULT mul_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1512 {
1513     FIXME("\n");
1514     return E_NOTIMPL;
1515 }
1516
1517 HRESULT div_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1518 {
1519     FIXME("\n");
1520     return E_NOTIMPL;
1521 }
1522
1523 HRESULT mod_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1524 {
1525     FIXME("\n");
1526     return E_NOTIMPL;
1527 }
1528
1529 HRESULT delete_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1530 {
1531     FIXME("\n");
1532     return E_NOTIMPL;
1533 }
1534
1535 HRESULT void_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1536 {
1537     FIXME("\n");
1538     return E_NOTIMPL;
1539 }
1540
1541 HRESULT typeof_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1542 {
1543     unary_expression_t *expr = (unary_expression_t*)_expr;
1544     const WCHAR *str;
1545     exprval_t exprval;
1546     VARIANT val;
1547     HRESULT hres;
1548
1549     static const WCHAR booleanW[] = {'b','o','o','l','e','a','n',0};
1550     static const WCHAR functionW[] = {'f','u','n','c','t','i','o','n',0};
1551     static const WCHAR numberW[] = {'n','u','m','b','e','r',0};
1552     static const WCHAR objectW[] = {'o','b','j','e','c','t',0};
1553     static const WCHAR stringW[] = {'s','t','r','i','n','g',0};
1554     static const WCHAR undefinedW[] = {'u','n','d','e','f','i','n','e','d',0};
1555
1556     TRACE("\n");
1557
1558     hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
1559     if(FAILED(hres))
1560         return hres;
1561
1562     hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
1563     exprval_release(&exprval);
1564     if(FAILED(hres))
1565         return hres;
1566
1567     switch(V_VT(&val)) {
1568     case VT_EMPTY:
1569         str = undefinedW;
1570         break;
1571     case VT_NULL:
1572         str = objectW;
1573         break;
1574     case VT_BOOL:
1575         str = booleanW;
1576         break;
1577     case VT_I4:
1578     case VT_R8:
1579         str = numberW;
1580         break;
1581     case VT_BSTR:
1582         str = stringW;
1583         break;
1584     case VT_DISPATCH: {
1585         DispatchEx *dispex;
1586
1587         dispex = iface_to_jsdisp((IUnknown*)V_DISPATCH(&val));
1588         if(dispex) {
1589             str = dispex->builtin_info->class == JSCLASS_FUNCTION ? functionW : objectW;
1590             IDispatchEx_Release(_IDispatchEx_(dispex));
1591         }else {
1592             str = objectW;
1593         }
1594         break;
1595     }
1596     default:
1597         FIXME("unhandled vt %d\n", V_VT(&val));
1598         hres = E_NOTIMPL;
1599     }
1600
1601     VariantClear(&val);
1602     if(FAILED(hres))
1603         return hres;
1604
1605     ret->type = EXPRVAL_VARIANT;
1606     V_VT(&ret->u.var) = VT_BSTR;
1607     V_BSTR(&ret->u.var) = SysAllocString(str);
1608     return S_OK;
1609 }
1610
1611 HRESULT minus_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1612 {
1613     FIXME("\n");
1614     return E_NOTIMPL;
1615 }
1616
1617 HRESULT plus_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1618 {
1619     FIXME("\n");
1620     return E_NOTIMPL;
1621 }
1622
1623 /* ECMA-262 3rd Edition    11.3.1 */
1624 HRESULT post_increment_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1625 {
1626     unary_expression_t *expr = (unary_expression_t*)_expr;
1627     VARIANT val, num;
1628     exprval_t exprval;
1629     HRESULT hres;
1630
1631     TRACE("\n");
1632
1633     hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval);
1634     if(FAILED(hres))
1635         return hres;
1636
1637     hres = exprval_value(ctx->parser->script, &exprval, ei, &val);
1638     if(SUCCEEDED(hres)) {
1639         hres = to_number(ctx->parser->script, &val, ei, &num);
1640         VariantClear(&val);
1641     }
1642
1643     if(SUCCEEDED(hres)) {
1644         VARIANT inc;
1645         num_set_val(&inc, num_val(&num)+1.0);
1646         hres = put_value(ctx->parser->script, &exprval, &inc, ei);
1647     }
1648
1649     exprval_release(&exprval);
1650     if(FAILED(hres))
1651         return hres;
1652
1653     ret->type = EXPRVAL_VARIANT;
1654     ret->u.var = num;
1655     return S_OK;
1656 }
1657
1658 /* ECMA-262 3rd Edition    11.3.2 */
1659 HRESULT post_decrement_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1660 {
1661     unary_expression_t *expr = (unary_expression_t*)_expr;
1662     VARIANT val, num;
1663     exprval_t exprval;
1664     HRESULT hres;
1665
1666     TRACE("\n");
1667
1668     hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval);
1669     if(FAILED(hres))
1670         return hres;
1671
1672     hres = exprval_value(ctx->parser->script, &exprval, ei, &val);
1673     if(SUCCEEDED(hres)) {
1674         hres = to_number(ctx->parser->script, &val, ei, &num);
1675         VariantClear(&val);
1676     }
1677
1678     if(SUCCEEDED(hres)) {
1679         VARIANT dec;
1680         num_set_val(&dec, num_val(&num)-1.0);
1681         hres = put_value(ctx->parser->script, &exprval, &dec, ei);
1682     }
1683
1684     exprval_release(&exprval);
1685     if(FAILED(hres))
1686         return hres;
1687
1688     ret->type = EXPRVAL_VARIANT;
1689     ret->u.var = num;
1690     return S_OK;
1691 }
1692
1693 /* ECMA-262 3rd Edition    11.4.4 */
1694 HRESULT pre_increment_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1695 {
1696     unary_expression_t *expr = (unary_expression_t*)_expr;
1697     VARIANT val, num;
1698     exprval_t exprval;
1699     HRESULT hres;
1700
1701     TRACE("\n");
1702
1703     hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval);
1704     if(FAILED(hres))
1705         return hres;
1706
1707     hres = exprval_value(ctx->parser->script, &exprval, ei, &val);
1708     if(SUCCEEDED(hres)) {
1709         hres = to_number(ctx->parser->script, &val, ei, &num);
1710         VariantClear(&val);
1711     }
1712
1713     if(SUCCEEDED(hres)) {
1714         num_set_val(&val, num_val(&num)+1.0);
1715         hres = put_value(ctx->parser->script, &exprval, &val, ei);
1716     }
1717
1718     exprval_release(&exprval);
1719     if(FAILED(hres))
1720         return hres;
1721
1722     ret->type = EXPRVAL_VARIANT;
1723     ret->u.var = val;
1724     return S_OK;
1725 }
1726
1727 /* ECMA-262 3rd Edition    11.4.5 */
1728 HRESULT pre_decrement_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1729 {
1730     unary_expression_t *expr = (unary_expression_t*)_expr;
1731     VARIANT val, num;
1732     exprval_t exprval;
1733     HRESULT hres;
1734
1735     TRACE("\n");
1736
1737     hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval);
1738     if(FAILED(hres))
1739         return hres;
1740
1741     hres = exprval_value(ctx->parser->script, &exprval, ei, &val);
1742     if(SUCCEEDED(hres)) {
1743         hres = to_number(ctx->parser->script, &val, ei, &num);
1744         VariantClear(&val);
1745     }
1746
1747     if(SUCCEEDED(hres)) {
1748         num_set_val(&val, num_val(&num)-1.0);
1749         hres = put_value(ctx->parser->script, &exprval, &val, ei);
1750     }
1751
1752     exprval_release(&exprval);
1753     if(FAILED(hres))
1754         return hres;
1755
1756     ret->type = EXPRVAL_VARIANT;
1757     ret->u.var = val;
1758     return S_OK;
1759 }
1760
1761 HRESULT new_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1762 {
1763     FIXME("\n");
1764     return E_NOTIMPL;
1765 }
1766
1767 HRESULT equal_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1768 {
1769     FIXME("\n");
1770     return E_NOTIMPL;
1771 }
1772
1773 /* ECMA-262 3rd Edition    11.9.4 */
1774 HRESULT equal2_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1775 {
1776     binary_expression_t *expr = (binary_expression_t*)_expr;
1777     VARIANT rval, lval;
1778     BOOL b;
1779     HRESULT hres;
1780
1781     TRACE("\n");
1782
1783     hres = get_binary_expr_values(ctx, expr, ei, &rval, &lval);
1784     if(FAILED(hres))
1785         return hres;
1786
1787     hres = equal2_values(&rval, &lval, &b);
1788     if(FAILED(hres))
1789         return hres;
1790
1791     return return_bool(ret, b);
1792 }
1793
1794 HRESULT not_equal_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1795 {
1796
1797     FIXME("\n");
1798     return E_NOTIMPL;
1799 }
1800
1801 /* ECMA-262 3rd Edition    11.9.5 */
1802 HRESULT not_equal2_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1803 {
1804     binary_expression_t *expr = (binary_expression_t*)_expr;
1805     VARIANT rval, lval;
1806     BOOL b;
1807     HRESULT hres;
1808
1809     TRACE("\n");
1810
1811     hres = get_binary_expr_values(ctx, expr, ei, &rval, &lval);
1812     if(FAILED(hres))
1813         return hres;
1814
1815     hres = equal2_values(&rval, &lval, &b);
1816     if(FAILED(hres))
1817         return hres;
1818
1819     return return_bool(ret, !b);
1820 }
1821
1822 /* ECMA-262 3rd Edition    11.8.5 */
1823 static HRESULT less_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, BOOL *ret)
1824 {
1825     VARIANT l, r, ln, rn;
1826     HRESULT hres;
1827
1828     hres = to_primitive(ctx->parser->script, lval, ei, &l);
1829     if(FAILED(hres))
1830         return hres;
1831
1832     hres = to_primitive(ctx->parser->script, rval, ei, &r);
1833     if(FAILED(hres)) {
1834         VariantClear(&l);
1835         return hres;
1836     }
1837
1838     if(V_VT(&l) == VT_BSTR && V_VT(&r) == VT_BSTR) {
1839         *ret = strcmpW(V_BSTR(&l), V_BSTR(&r)) < 0;
1840         SysFreeString(V_BSTR(&l));
1841         SysFreeString(V_BSTR(&r));
1842         return S_OK;
1843     }
1844
1845     hres = to_number(ctx->parser->script, &l, ei, &ln);
1846     VariantClear(&l);
1847     if(SUCCEEDED(hres))
1848         hres = to_number(ctx->parser->script, &r, ei, &rn);
1849     VariantClear(&r);
1850     if(FAILED(hres))
1851         return hres;
1852
1853     if(V_VT(&ln) == VT_I4 && V_VT(&rn) == VT_I4)
1854         *ret = V_I4(&ln) < V_I4(&rn);
1855     else
1856         *ret = num_val(&ln) < num_val(&rn);
1857
1858     return S_OK;
1859 }
1860
1861 /* ECMA-262 3rd Edition    11.8.1 */
1862 HRESULT less_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1863 {
1864     binary_expression_t *expr = (binary_expression_t*)_expr;
1865     VARIANT rval, lval;
1866     BOOL b;
1867     HRESULT hres;
1868
1869     TRACE("\n");
1870
1871     hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval);
1872     if(FAILED(hres))
1873         return hres;
1874
1875     hres = less_eval(ctx, &lval, &rval, ei, &b);
1876     VariantClear(&lval);
1877     VariantClear(&rval);
1878     if(FAILED(hres))
1879         return hres;
1880
1881     return return_bool(ret, b);
1882 }
1883
1884 /* ECMA-262 3rd Edition    11.8.3 */
1885 HRESULT lesseq_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1886 {
1887     binary_expression_t *expr = (binary_expression_t*)_expr;
1888     VARIANT rval, lval;
1889     BOOL b;
1890     HRESULT hres;
1891
1892     TRACE("\n");
1893
1894     hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval);
1895     if(FAILED(hres))
1896         return hres;
1897
1898     hres = less_eval(ctx, &rval, &lval, ei, &b);
1899     VariantClear(&lval);
1900     VariantClear(&rval);
1901     if(FAILED(hres))
1902         return hres;
1903
1904     return return_bool(ret, !b);
1905 }
1906
1907 /* ECMA-262 3rd Edition    11.8.2 */
1908 HRESULT greater_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1909 {
1910     binary_expression_t *expr = (binary_expression_t*)_expr;
1911     VARIANT rval, lval;
1912     BOOL b;
1913     HRESULT hres;
1914
1915     TRACE("\n");
1916
1917     hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval);
1918     if(FAILED(hres))
1919         return hres;
1920
1921     hres = less_eval(ctx, &rval, &lval, ei, &b);
1922     VariantClear(&lval);
1923     VariantClear(&rval);
1924     if(FAILED(hres))
1925         return hres;
1926
1927     return return_bool(ret, b);
1928 }
1929
1930 /* ECMA-262 3rd Edition    11.8.4 */
1931 HRESULT greatereq_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1932 {
1933     binary_expression_t *expr = (binary_expression_t*)_expr;
1934     VARIANT rval, lval;
1935     BOOL b;
1936     HRESULT hres;
1937
1938     TRACE("\n");
1939
1940     hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval);
1941     if(FAILED(hres))
1942         return hres;
1943
1944     hres = less_eval(ctx, &lval, &rval, ei, &b);
1945     VariantClear(&lval);
1946     VariantClear(&rval);
1947     if(FAILED(hres))
1948         return hres;
1949
1950     return return_bool(ret, !b);
1951 }
1952
1953 HRESULT binary_negation_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1954 {
1955     FIXME("\n");
1956     return E_NOTIMPL;
1957 }
1958
1959 /* ECMA-262 3rd Edition    11.4.9 */
1960 HRESULT logical_negation_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1961 {
1962     unary_expression_t *expr = (unary_expression_t*)_expr;
1963     exprval_t exprval;
1964     VARIANT_BOOL b;
1965     HRESULT hres;
1966
1967     TRACE("\n");
1968
1969     hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval);
1970     if(FAILED(hres))
1971         return hres;
1972
1973     hres = exprval_to_boolean(ctx->parser->script, &exprval, ei, &b);
1974     exprval_release(&exprval);
1975     if(FAILED(hres))
1976         return hres;
1977
1978     return return_bool(ret, !b);
1979 }
1980
1981 HRESULT left_shift_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1982 {
1983     FIXME("\n");
1984     return E_NOTIMPL;
1985 }
1986
1987 HRESULT right_shift_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1988 {
1989     FIXME("\n");
1990     return E_NOTIMPL;
1991 }
1992
1993 HRESULT right2_shift_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1994 {
1995     FIXME("\n");
1996     return E_NOTIMPL;
1997 }
1998
1999 /* ECMA-262 3rd Edition    11.13.1 */
2000 HRESULT assign_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2001 {
2002     binary_expression_t *expr = (binary_expression_t*)_expr;
2003     exprval_t exprval, exprvalr;
2004     VARIANT rval;
2005     HRESULT hres;
2006
2007     TRACE("\n");
2008
2009     hres = expr_eval(ctx, expr->expression1, EXPR_NEWREF, ei, &exprval);
2010     if(FAILED(hres))
2011         return hres;
2012
2013     hres = expr_eval(ctx, expr->expression2, 0, ei, &exprvalr);
2014     if(SUCCEEDED(hres)) {
2015         hres = exprval_to_value(ctx->parser->script, &exprvalr, ei, &rval);
2016         exprval_release(&exprvalr);
2017     }
2018
2019     if(SUCCEEDED(hres))
2020         hres = put_value(ctx->parser->script, &exprval, &rval, ei);
2021
2022     exprval_release(&exprval);
2023     if(FAILED(hres)) {
2024         VariantClear(&rval);
2025         return hres;
2026     }
2027
2028     ret->type = EXPRVAL_VARIANT;
2029     ret->u.var = rval;
2030     return S_OK;
2031 }
2032
2033 HRESULT assign_lshift_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2034 {
2035     FIXME("\n");
2036     return E_NOTIMPL;
2037 }
2038
2039 HRESULT assign_rshift_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2040 {
2041     FIXME("\n");
2042     return E_NOTIMPL;
2043 }
2044
2045 HRESULT assign_rrshift_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2046 {
2047     FIXME("\n");
2048     return E_NOTIMPL;
2049 }
2050
2051 /* ECMA-262 3rd Edition    11.13.2 */
2052 HRESULT assign_add_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2053 {
2054     binary_expression_t *expr = (binary_expression_t*)_expr;
2055
2056     TRACE("\n");
2057
2058     return assign_oper_eval(ctx, expr->expression1, expr->expression2, add_eval, ei, ret);
2059 }
2060
2061 HRESULT assign_sub_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2062 {
2063     FIXME("\n");
2064     return E_NOTIMPL;
2065 }
2066
2067 HRESULT assign_mul_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2068 {
2069     FIXME("\n");
2070     return E_NOTIMPL;
2071 }
2072
2073 HRESULT assign_div_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2074 {
2075     FIXME("\n");
2076     return E_NOTIMPL;
2077 }
2078
2079 HRESULT assign_mod_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2080 {
2081     FIXME("\n");
2082     return E_NOTIMPL;
2083 }
2084
2085 HRESULT assign_and_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2086 {
2087     FIXME("\n");
2088     return E_NOTIMPL;
2089 }
2090
2091 HRESULT assign_or_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2092 {
2093     FIXME("\n");
2094     return E_NOTIMPL;
2095 }
2096
2097 HRESULT assign_xor_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2098 {
2099     FIXME("\n");
2100     return E_NOTIMPL;
2101 }