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