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