jscript: Added '===' 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_set_idref(exprval_t *val, IDispatch *disp, DISPID id)
108 {
109     val->type = EXPRVAL_IDREF;
110     val->u.idref.disp = disp;
111     val->u.idref.id = id;
112
113     if(disp)
114         IDispatch_AddRef(disp);
115 }
116
117 void scope_release(scope_chain_t *scope)
118 {
119     if(--scope->ref)
120         return;
121
122     if(scope->next)
123         scope_release(scope->next);
124
125     IDispatchEx_Release(_IDispatchEx_(scope->obj));
126     heap_free(scope);
127 }
128
129 HRESULT create_exec_ctx(DispatchEx *var_disp, scope_chain_t *scope, exec_ctx_t **ret)
130 {
131     exec_ctx_t *ctx;
132
133     ctx = heap_alloc_zero(sizeof(exec_ctx_t));
134     if(!ctx)
135         return E_OUTOFMEMORY;
136
137     IDispatchEx_AddRef(_IDispatchEx_(var_disp));
138     ctx->var_disp = var_disp;
139
140     if(scope) {
141         scope_addref(scope);
142         ctx->scope_chain = scope;
143     }
144
145     *ret = ctx;
146     return S_OK;
147 }
148
149 void exec_release(exec_ctx_t *ctx)
150 {
151     if(--ctx->ref)
152         return;
153
154     if(ctx->scope_chain)
155         scope_release(ctx->scope_chain);
156     if(ctx->var_disp)
157         IDispatchEx_Release(_IDispatchEx_(ctx->var_disp));
158     heap_free(ctx);
159 }
160
161 static HRESULT dispex_get_id(IDispatchEx *dispex, BSTR name, DWORD flags, DISPID *id)
162 {
163     *id = 0;
164
165     return IDispatchEx_GetDispID(dispex, name, flags|fdexNameCaseSensitive, id);
166 }
167
168 static HRESULT disp_get_id(IDispatch *disp, BSTR name, DWORD flags, DISPID *id)
169 {
170     IDispatchEx *dispex;
171     HRESULT hres;
172
173     hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
174     if(FAILED(hres)) {
175         TRACE("unsing IDispatch\n");
176
177         *id = 0;
178         return IDispatch_GetIDsOfNames(disp, &IID_NULL, &name, 1, 0, id);
179     }
180
181     hres = dispex_get_id(dispex, name, flags, id);
182     IDispatchEx_Release(dispex);
183     return hres;
184 }
185
186 /* ECMA-262 3rd Edition    8.7.2 */
187 static HRESULT put_value(script_ctx_t *ctx, exprval_t *ref, VARIANT *v, jsexcept_t *ei)
188 {
189     if(ref->type != EXPRVAL_IDREF) {
190         FIXME("throw ReferemceError\n");
191         return E_FAIL;
192     }
193
194     return disp_propput(ref->u.idref.disp, ref->u.idref.id, ctx->lcid, v, ei, NULL/*FIXME*/);
195 }
196
197 static HRESULT disp_cmp(IDispatch *disp1, IDispatch *disp2, BOOL *ret)
198 {
199     IObjectIdentity *identity;
200     IUnknown *unk1, *unk2;
201     HRESULT hres;
202
203     if(disp1 == disp2) {
204         *ret = TRUE;
205         return S_OK;
206     }
207
208     hres = IDispatch_QueryInterface(disp1, &IID_IUnknown, (void**)&unk1);
209     if(FAILED(hres))
210         return hres;
211
212     hres = IDispatch_QueryInterface(disp2, &IID_IUnknown, (void**)&unk2);
213     if(FAILED(hres)) {
214         IUnknown_Release(unk1);
215         return hres;
216     }
217
218     if(unk1 == unk2) {
219         *ret = TRUE;
220     }else {
221         hres = IUnknown_QueryInterface(unk1, &IID_IObjectIdentity, (void**)&identity);
222         if(SUCCEEDED(hres)) {
223             hres = IObjectIdentity_IsEqualObject(identity, unk2);
224             IObjectIdentity_Release(identity);
225             *ret = hres == S_OK;
226         }else {
227             *ret = FALSE;
228         }
229     }
230
231     IUnknown_Release(unk1);
232     IUnknown_Release(unk2);
233     return S_OK;
234 }
235
236 static inline BOOL is_num_vt(enum VARENUM vt)
237 {
238     return vt == VT_I4 || vt == VT_R8;
239 }
240
241 static inline DOUBLE num_val(const VARIANT *v)
242 {
243     return V_VT(v) == VT_I4 ? V_I4(v) : V_R8(v);
244 }
245
246 /* ECMA-262 3rd Edition    11.9.6 */
247 HRESULT equal2_values(VARIANT *lval, VARIANT *rval, BOOL *ret)
248 {
249     TRACE("\n");
250
251     if(V_VT(lval) != V_VT(rval)) {
252         if(is_num_vt(V_VT(lval)) && is_num_vt(V_VT(rval))) {
253             *ret = num_val(lval) == num_val(rval);
254             return S_OK;
255         }
256
257         *ret = FALSE;
258         return S_OK;
259     }
260
261     switch(V_VT(lval)) {
262     case VT_EMPTY:
263     case VT_NULL:
264         *ret = VARIANT_TRUE;
265         break;
266     case VT_I4:
267         *ret = V_I4(lval) == V_I4(rval);
268         break;
269     case VT_R8:
270         *ret = V_R8(lval) == V_R8(rval);
271         break;
272     case VT_BSTR:
273         *ret = !strcmpW(V_BSTR(lval), V_BSTR(rval));
274         break;
275     case VT_DISPATCH:
276         return disp_cmp(V_DISPATCH(lval), V_DISPATCH(rval), ret);
277     case VT_BOOL:
278         *ret = !V_BOOL(lval) == !V_BOOL(rval);
279         break;
280     default:
281         FIXME("unimplemented vt %d\n", V_VT(lval));
282         return E_NOTIMPL;
283     }
284
285     return S_OK;
286 }
287
288 static HRESULT literal_to_var(literal_t *literal, VARIANT *v)
289 {
290     V_VT(v) = literal->vt;
291
292     switch(V_VT(v)) {
293     case VT_EMPTY:
294     case VT_NULL:
295         break;
296     case VT_I4:
297         V_I4(v) = literal->u.lval;
298         break;
299     case VT_R8:
300         V_R8(v) = literal->u.dval;
301         break;
302     case VT_BSTR:
303         V_BSTR(v) = SysAllocString(literal->u.wstr);
304         break;
305     case VT_BOOL:
306         V_BOOL(v) = literal->u.bval;
307         break;
308     case VT_DISPATCH:
309         IDispatch_AddRef(literal->u.disp);
310         V_DISPATCH(v) = literal->u.disp;
311         break;
312     default:
313         ERR("wrong type %d\n", V_VT(v));
314         return E_NOTIMPL;
315     }
316
317     return S_OK;
318 }
319
320 HRESULT exec_source(exec_ctx_t *ctx, parser_ctx_t *parser, source_elements_t *source, jsexcept_t *ei, VARIANT *retv)
321 {
322     script_ctx_t *script = parser->script;
323     parser_ctx_t *prev_parser;
324     VARIANT val, tmp;
325     statement_t *stat;
326     exec_ctx_t *prev_ctx;
327     return_type_t rt;
328     HRESULT hres = S_OK;
329
330     prev_ctx = script->exec_ctx;
331     script->exec_ctx = ctx;
332
333     prev_parser = ctx->parser;
334     ctx->parser = parser;
335
336     V_VT(&val) = VT_EMPTY;
337     memset(&rt, 0, sizeof(rt));
338     rt.type = RT_NORMAL;
339
340     for(stat = source->statement; stat; stat = stat->next) {
341         hres = stat_eval(ctx, stat, &rt, &tmp);
342         if(FAILED(hres))
343             break;
344
345         VariantClear(&val);
346         val = tmp;
347         if(rt.type != RT_NORMAL)
348             break;
349     }
350
351     script->exec_ctx = prev_ctx;
352     ctx->parser = prev_parser;
353
354     if(rt.type != RT_NORMAL && rt.type != RT_RETURN) {
355         FIXME("wrong rt %d\n", rt.type);
356         hres = E_FAIL;
357     }
358
359     *ei = rt.ei;
360     if(FAILED(hres)) {
361         VariantClear(&val);
362         return hres;
363     }
364
365     if(retv)
366         *retv = val;
367     else
368         VariantClear(&val);
369     return S_OK;
370 }
371
372 /* ECMA-262 3rd Edition    10.1.4 */
373 static HRESULT identifier_eval(exec_ctx_t *ctx, BSTR identifier, DWORD flags, exprval_t *ret)
374 {
375     scope_chain_t *scope;
376     named_item_t *item;
377     DISPID id = 0;
378     HRESULT hres;
379
380     TRACE("%s\n", debugstr_w(identifier));
381
382     for(scope = ctx->scope_chain; scope; scope = scope->next) {
383         hres = dispex_get_id(_IDispatchEx_(scope->obj), identifier, 0, &id);
384         if(SUCCEEDED(hres))
385             break;
386     }
387
388     if(scope) {
389         exprval_set_idref(ret, (IDispatch*)_IDispatchEx_(scope->obj), id);
390         return S_OK;
391     }
392
393     hres = dispex_get_id(_IDispatchEx_(ctx->parser->script->global), identifier, 0, &id);
394     if(SUCCEEDED(hres)) {
395         exprval_set_idref(ret, (IDispatch*)_IDispatchEx_(ctx->parser->script->global), id);
396         return S_OK;
397     }
398
399     for(item = ctx->parser->script->named_items; item; item = item->next) {
400         hres = disp_get_id(item->disp, identifier, 0, &id);
401         if(SUCCEEDED(hres))
402             break;
403     }
404
405     if(item) {
406         exprval_set_idref(ret, (IDispatch*)item->disp, id);
407         return S_OK;
408     }
409
410     hres = dispex_get_id(_IDispatchEx_(ctx->parser->script->script_disp), identifier, 0, &id);
411     if(SUCCEEDED(hres)) {
412         exprval_set_idref(ret, (IDispatch*)_IDispatchEx_(ctx->parser->script->script_disp), id);
413         return S_OK;
414     }
415
416     if(flags & EXPR_NEWREF) {
417         hres = dispex_get_id(_IDispatchEx_(ctx->var_disp), identifier, fdexNameEnsure, &id);
418         if(FAILED(hres))
419             return hres;
420
421         exprval_set_idref(ret, (IDispatch*)_IDispatchEx_(ctx->var_disp), id);
422         return S_OK;
423     }
424
425     WARN("Could not find identifier %s\n", debugstr_w(identifier));
426     return E_FAIL;
427 }
428
429 HRESULT block_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
430 {
431     FIXME("\n");
432     return E_NOTIMPL;
433 }
434
435 /* ECMA-262 3rd Edition    12.2 */
436 static HRESULT variable_list_eval(exec_ctx_t *ctx, variable_declaration_t *var_list, jsexcept_t *ei)
437 {
438     variable_declaration_t *iter;
439     HRESULT hres;
440
441     for(iter = var_list; iter; iter = iter->next) {
442         VARIANT val;
443
444         if(iter->expr) {
445             exprval_t exprval;
446
447             hres = expr_eval(ctx, iter->expr, 0, ei, &exprval);
448             if(FAILED(hres))
449                 break;
450
451             hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
452             exprval_release(&exprval);
453             if(FAILED(hres))
454                 break;
455         }else {
456             V_VT(&val) = VT_EMPTY;
457         }
458
459         hres = jsdisp_propput_name(ctx->var_disp, iter->identifier, ctx->parser->script->lcid, &val, ei, NULL/*FIXME*/);
460         VariantClear(&val);
461         if(FAILED(hres))
462             break;
463     }
464
465     return hres;
466 }
467
468 /* ECMA-262 3rd Edition    12.2 */
469 HRESULT var_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
470 {
471     var_statement_t *stat = (var_statement_t*)_stat;
472     HRESULT hres;
473
474     TRACE("\n");
475
476     hres = variable_list_eval(ctx, stat->variable_list, &rt->ei);
477     if(FAILED(hres))
478         return hres;
479
480     V_VT(ret) = VT_EMPTY;
481     return S_OK;
482 }
483
484 /* ECMA-262 3rd Edition    12.3 */
485 HRESULT empty_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
486 {
487     TRACE("\n");
488
489     V_VT(ret) = VT_EMPTY;
490     return S_OK;
491 }
492
493 /* ECMA-262 3rd Edition    12.4 */
494 HRESULT expression_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
495 {
496     expression_statement_t *stat = (expression_statement_t*)_stat;
497     exprval_t exprval;
498     VARIANT val;
499     HRESULT hres;
500
501     TRACE("\n");
502
503     hres = expr_eval(ctx, stat->expr, EXPR_NOVAL, &rt->ei, &exprval);
504     if(FAILED(hres))
505         return hres;
506
507     hres = exprval_to_value(ctx->parser->script, &exprval, &rt->ei, &val);
508     exprval_release(&exprval);
509     if(FAILED(hres))
510         return hres;
511
512     *ret = val;
513     TRACE("= %s\n", debugstr_variant(ret));
514     return S_OK;
515 }
516
517 HRESULT if_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
518 {
519     FIXME("\n");
520     return E_NOTIMPL;
521 }
522
523 HRESULT dowhile_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
524 {
525     FIXME("\n");
526     return E_NOTIMPL;
527 }
528
529 HRESULT while_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
530 {
531     FIXME("\n");
532     return E_NOTIMPL;
533 }
534
535 HRESULT for_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
536 {
537     FIXME("\n");
538     return E_NOTIMPL;
539 }
540
541 HRESULT forin_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
542 {
543     FIXME("\n");
544     return E_NOTIMPL;
545 }
546
547 HRESULT continue_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
548 {
549     FIXME("\n");
550     return E_NOTIMPL;
551 }
552
553 HRESULT break_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
554 {
555     FIXME("\n");
556     return E_NOTIMPL;
557 }
558
559 HRESULT return_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
560 {
561     FIXME("\n");
562     return E_NOTIMPL;
563 }
564
565 HRESULT with_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
566 {
567     FIXME("\n");
568     return E_NOTIMPL;
569 }
570
571 HRESULT labelled_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
572 {
573     FIXME("\n");
574     return E_NOTIMPL;
575 }
576
577 HRESULT switch_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
578 {
579     FIXME("\n");
580     return E_NOTIMPL;
581 }
582
583 HRESULT throw_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
584 {
585     FIXME("\n");
586     return E_NOTIMPL;
587 }
588
589 HRESULT try_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
590 {
591     FIXME("\n");
592     return E_NOTIMPL;
593 }
594
595 static HRESULT return_bool(exprval_t *ret, DWORD b)
596 {
597     ret->type = EXPRVAL_VARIANT;
598     V_VT(&ret->u.var) = VT_BOOL;
599     V_BOOL(&ret->u.var) = b ? VARIANT_TRUE : VARIANT_FALSE;
600
601     return S_OK;
602 }
603
604 static HRESULT get_binary_expr_values(exec_ctx_t *ctx, binary_expression_t *expr, jsexcept_t *ei, VARIANT *lval, VARIANT *rval)
605 {
606     exprval_t exprval;
607     HRESULT hres;
608
609     hres = expr_eval(ctx, expr->expression1, 0, ei, &exprval);
610     if(FAILED(hres))
611         return hres;
612
613     hres = exprval_to_value(ctx->parser->script, &exprval, ei, lval);
614     exprval_release(&exprval);
615     if(FAILED(hres))
616         return hres;
617
618     hres = expr_eval(ctx, expr->expression2, 0, ei, &exprval);
619     if(SUCCEEDED(hres)) {
620         hres = exprval_to_value(ctx->parser->script, &exprval, ei, rval);
621         exprval_release(&exprval);
622     }
623
624     if(FAILED(hres)) {
625         VariantClear(lval);
626         return hres;
627     }
628
629     return S_OK;
630 }
631
632 HRESULT function_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
633 {
634     FIXME("\n");
635     return E_NOTIMPL;
636 }
637
638 HRESULT conditional_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
639 {
640     FIXME("\n");
641     return E_NOTIMPL;
642 }
643
644 HRESULT array_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
645 {
646     FIXME("\n");
647     return E_NOTIMPL;
648 }
649
650 HRESULT member_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
651 {
652     FIXME("\n");
653     return E_NOTIMPL;
654 }
655
656 static void free_dp(DISPPARAMS *dp)
657 {
658     DWORD i;
659
660     for(i=0; i < dp->cArgs; i++)
661         VariantClear(dp->rgvarg+i);
662     heap_free(dp->rgvarg);
663 }
664
665 static HRESULT args_to_param(exec_ctx_t *ctx, argument_t *args, jsexcept_t *ei, DISPPARAMS *dp)
666 {
667     VARIANTARG *vargs;
668     exprval_t exprval;
669     argument_t *iter;
670     DWORD cnt = 0, i;
671     HRESULT hres = S_OK;
672
673     memset(dp, 0, sizeof(*dp));
674
675     for(iter = args; iter; iter = iter->next)
676         cnt++;
677     if(!cnt)
678         return S_OK;
679
680     vargs = heap_alloc_zero(cnt * sizeof(*vargs));
681     if(!vargs)
682         return E_OUTOFMEMORY;
683
684     for(i = cnt, iter = args; iter; iter = iter->next) {
685         hres = expr_eval(ctx, iter->expr, 0, ei, &exprval);
686         if(FAILED(hres))
687             break;
688
689         hres = exprval_to_value(ctx->parser->script, &exprval, ei, vargs + (--i));
690         exprval_release(&exprval);
691         if(FAILED(hres))
692             break;
693     }
694
695     if(FAILED(hres)) {
696         free_dp(dp);
697         return hres;
698     }
699
700     dp->rgvarg = vargs;
701     dp->cArgs = cnt;
702     return S_OK;
703 }
704
705 HRESULT member_new_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
706 {
707     FIXME("\n");
708     return E_NOTIMPL;
709 }
710
711 HRESULT call_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
712 {
713     call_expression_t *expr = (call_expression_t*)_expr;
714     VARIANT func, var;
715     exprval_t exprval;
716     DISPPARAMS dp;
717     HRESULT hres;
718
719     TRACE("\n");
720
721     hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
722     if(FAILED(hres))
723         return hres;
724
725     hres = args_to_param(ctx, expr->argument_list, ei, &dp);
726     if(SUCCEEDED(hres)) {
727         switch(exprval.type) {
728         case EXPRVAL_IDREF:
729             hres = disp_call(exprval.u.idref.disp, exprval.u.idref.id, ctx->parser->script->lcid, DISPATCH_METHOD,
730                     &dp, flags & EXPR_NOVAL ? NULL : &var, ei, NULL/*FIXME*/);
731             if(flags & EXPR_NOVAL)
732                 V_VT(&var) = VT_EMPTY;
733             break;
734         default:
735             FIXME("unimplemented type %d\n", V_VT(&func));
736             hres = E_NOTIMPL;
737         }
738
739         free_dp(&dp);
740     }
741
742     exprval_release(&exprval);
743     if(FAILED(hres))
744         return hres;
745
746     TRACE("= %s\n", debugstr_variant(&var));
747     ret->type = EXPRVAL_VARIANT;
748     ret->u.var = var;
749     return S_OK;
750 }
751
752 HRESULT this_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
753 {
754     FIXME("\n");
755     return E_NOTIMPL;
756 }
757
758 /* ECMA-262 3rd Edition    10.1.4 */
759 HRESULT identifier_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
760 {
761     identifier_expression_t *expr = (identifier_expression_t*)_expr;
762     BSTR identifier;
763     HRESULT hres;
764
765     TRACE("\n");
766
767     identifier = SysAllocString(expr->identifier);
768     if(!identifier)
769         return E_OUTOFMEMORY;
770
771     hres = identifier_eval(ctx, identifier, flags, ret);
772
773     SysFreeString(identifier);
774     return hres;
775 }
776
777 /* ECMA-262 3rd Edition    7.8 */
778 HRESULT literal_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
779 {
780     literal_expression_t *expr = (literal_expression_t*)_expr;
781     VARIANT var;
782     HRESULT hres;
783
784     TRACE("\n");
785
786     hres = literal_to_var(expr->literal, &var);
787     if(FAILED(hres))
788         return hres;
789
790     ret->type = EXPRVAL_VARIANT;
791     ret->u.var = var;
792     return S_OK;
793 }
794
795 HRESULT array_literal_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
796 {
797     FIXME("\n");
798     return E_NOTIMPL;
799 }
800
801 HRESULT property_value_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
802 {
803     FIXME("\n");
804     return E_NOTIMPL;
805 }
806
807 HRESULT comma_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
808 {
809     FIXME("\n");
810     return E_NOTIMPL;
811 }
812
813 HRESULT logical_or_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
814 {
815     FIXME("\n");
816     return E_NOTIMPL;
817 }
818
819 HRESULT logical_and_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
820 {
821     FIXME("\n");
822     return E_NOTIMPL;
823 }
824
825 HRESULT binary_or_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
826 {
827     FIXME("\n");
828     return E_NOTIMPL;
829 }
830
831 HRESULT binary_xor_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
832 {
833     FIXME("\n");
834     return E_NOTIMPL;
835 }
836
837 HRESULT binary_and_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
838 {
839     FIXME("\n");
840     return E_NOTIMPL;
841 }
842
843 HRESULT instanceof_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
844 {
845     FIXME("\n");
846     return E_NOTIMPL;
847 }
848
849 HRESULT in_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
850 {
851     FIXME("\n");
852     return E_NOTIMPL;
853 }
854
855 HRESULT add_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
856 {
857     FIXME("\n");
858     return E_NOTIMPL;
859 }
860
861 HRESULT sub_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
862 {
863     FIXME("\n");
864     return E_NOTIMPL;
865 }
866
867 HRESULT mul_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
868 {
869     FIXME("\n");
870     return E_NOTIMPL;
871 }
872
873 HRESULT div_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
874 {
875     FIXME("\n");
876     return E_NOTIMPL;
877 }
878
879 HRESULT mod_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
880 {
881     FIXME("\n");
882     return E_NOTIMPL;
883 }
884
885 HRESULT delete_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
886 {
887     FIXME("\n");
888     return E_NOTIMPL;
889 }
890
891 HRESULT void_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
892 {
893     FIXME("\n");
894     return E_NOTIMPL;
895 }
896
897 HRESULT typeof_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
898 {
899     FIXME("\n");
900     return E_NOTIMPL;
901 }
902
903 HRESULT minus_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
904 {
905     FIXME("\n");
906     return E_NOTIMPL;
907 }
908
909 HRESULT plus_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
910 {
911     FIXME("\n");
912     return E_NOTIMPL;
913 }
914
915 HRESULT post_increment_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
916 {
917     FIXME("\n");
918     return E_NOTIMPL;
919 }
920
921 HRESULT post_decrement_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
922 {
923     FIXME("\n");
924     return E_NOTIMPL;
925 }
926
927 HRESULT pre_increment_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
928 {
929     FIXME("\n");
930     return E_NOTIMPL;
931 }
932
933 HRESULT pre_decrement_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
934 {
935     FIXME("\n");
936     return E_NOTIMPL;
937 }
938
939 HRESULT new_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
940 {
941     FIXME("\n");
942     return E_NOTIMPL;
943 }
944
945 HRESULT equal_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
946 {
947     FIXME("\n");
948     return E_NOTIMPL;
949 }
950
951 /* ECMA-262 3rd Edition    11.9.4 */
952 HRESULT equal2_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
953 {
954     binary_expression_t *expr = (binary_expression_t*)_expr;
955     VARIANT rval, lval;
956     BOOL b;
957     HRESULT hres;
958
959     TRACE("\n");
960
961     hres = get_binary_expr_values(ctx, expr, ei, &rval, &lval);
962     if(FAILED(hres))
963         return hres;
964
965     hres = equal2_values(&rval, &lval, &b);
966     if(FAILED(hres))
967         return hres;
968
969     return return_bool(ret, b);
970 }
971
972 HRESULT not_equal_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
973 {
974
975     FIXME("\n");
976     return E_NOTIMPL;
977 }
978
979 HRESULT not_equal2_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
980 {
981     FIXME("\n");
982     return E_NOTIMPL;
983 }
984
985 HRESULT less_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
986 {
987     FIXME("\n");
988     return E_NOTIMPL;
989 }
990
991 HRESULT lesseq_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
992 {
993     FIXME("\n");
994     return E_NOTIMPL;
995 }
996
997 HRESULT greater_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
998 {
999     FIXME("\n");
1000     return E_NOTIMPL;
1001 }
1002
1003 HRESULT greatereq_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1004 {
1005     FIXME("\n");
1006     return E_NOTIMPL;
1007 }
1008
1009 HRESULT binary_negation_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1010 {
1011     FIXME("\n");
1012     return E_NOTIMPL;
1013 }
1014
1015 /* ECMA-262 3rd Edition    11.4.9 */
1016 HRESULT logical_negation_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1017 {
1018     unary_expression_t *expr = (unary_expression_t*)_expr;
1019     exprval_t exprval;
1020     VARIANT_BOOL b;
1021     HRESULT hres;
1022
1023     TRACE("\n");
1024
1025     hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval);
1026     if(FAILED(hres))
1027         return hres;
1028
1029     hres = exprval_to_boolean(ctx->parser->script, &exprval, ei, &b);
1030     exprval_release(&exprval);
1031     if(FAILED(hres))
1032         return hres;
1033
1034     return return_bool(ret, !b);
1035 }
1036
1037 HRESULT left_shift_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1038 {
1039     FIXME("\n");
1040     return E_NOTIMPL;
1041 }
1042
1043 HRESULT right_shift_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1044 {
1045     FIXME("\n");
1046     return E_NOTIMPL;
1047 }
1048
1049 HRESULT right2_shift_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1050 {
1051     FIXME("\n");
1052     return E_NOTIMPL;
1053 }
1054
1055 /* ECMA-262 3rd Edition    11.13.1 */
1056 HRESULT assign_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1057 {
1058     binary_expression_t *expr = (binary_expression_t*)_expr;
1059     exprval_t exprval, exprvalr;
1060     VARIANT rval;
1061     HRESULT hres;
1062
1063     TRACE("\n");
1064
1065     hres = expr_eval(ctx, expr->expression1, EXPR_NEWREF, ei, &exprval);
1066     if(FAILED(hres))
1067         return hres;
1068
1069     hres = expr_eval(ctx, expr->expression2, 0, ei, &exprvalr);
1070     if(SUCCEEDED(hres)) {
1071         hres = exprval_to_value(ctx->parser->script, &exprvalr, ei, &rval);
1072         exprval_release(&exprvalr);
1073     }
1074
1075     if(SUCCEEDED(hres))
1076         hres = put_value(ctx->parser->script, &exprval, &rval, ei);
1077
1078     exprval_release(&exprval);
1079     if(FAILED(hres)) {
1080         VariantClear(&rval);
1081         return hres;
1082     }
1083
1084     ret->type = EXPRVAL_VARIANT;
1085     ret->u.var = rval;
1086     return S_OK;
1087 }
1088
1089 HRESULT assign_lshift_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1090 {
1091     FIXME("\n");
1092     return E_NOTIMPL;
1093 }
1094
1095 HRESULT assign_rshift_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1096 {
1097     FIXME("\n");
1098     return E_NOTIMPL;
1099 }
1100
1101 HRESULT assign_rrshift_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1102 {
1103     FIXME("\n");
1104     return E_NOTIMPL;
1105 }
1106
1107 HRESULT assign_add_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1108 {
1109     FIXME("\n");
1110     return E_NOTIMPL;
1111 }
1112
1113 HRESULT assign_sub_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1114 {
1115     FIXME("\n");
1116     return E_NOTIMPL;
1117 }
1118
1119 HRESULT assign_mul_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1120 {
1121     FIXME("\n");
1122     return E_NOTIMPL;
1123 }
1124
1125 HRESULT assign_div_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1126 {
1127     FIXME("\n");
1128     return E_NOTIMPL;
1129 }
1130
1131 HRESULT assign_mod_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1132 {
1133     FIXME("\n");
1134     return E_NOTIMPL;
1135 }
1136
1137 HRESULT assign_and_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1138 {
1139     FIXME("\n");
1140     return E_NOTIMPL;
1141 }
1142
1143 HRESULT assign_or_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1144 {
1145     FIXME("\n");
1146     return E_NOTIMPL;
1147 }
1148
1149 HRESULT assign_xor_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1150 {
1151     FIXME("\n");
1152     return E_NOTIMPL;
1153 }