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