jscript: Added var statement implementation.
[wine] / dlls / jscript / engine.c
1 /*
2  * Copyright 2008 Jacek Caban for CodeWeavers
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18
19 #include "jscript.h"
20 #include "engine.h"
21
22 #include "wine/debug.h"
23
24 WINE_DEFAULT_DEBUG_CHANNEL(jscript);
25
26 #define EXPR_NOVAL   0x0001
27 #define EXPR_NEWREF  0x0002
28 #define EXPR_STRREF  0x0004
29
30 static inline HRESULT stat_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
31 {
32     return stat->eval(ctx, stat, rt, ret);
33 }
34
35 static inline HRESULT expr_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
36 {
37     return _expr->eval(ctx, _expr, flags, ei, ret);
38 }
39
40 static void exprval_release(exprval_t *val)
41 {
42     switch(val->type) {
43     case EXPRVAL_VARIANT:
44         VariantClear(&val->u.var);
45         return;
46     case EXPRVAL_IDREF:
47         if(val->u.idref.disp)
48             IDispatch_Release(val->u.idref.disp);
49         return;
50     case EXPRVAL_NAMEREF:
51         if(val->u.nameref.disp)
52             IDispatch_Release(val->u.nameref.disp);
53         SysFreeString(val->u.nameref.name);
54     }
55 }
56
57 /* ECMA-262 3rd Edition    8.7.1 */
58 static HRESULT exprval_value(script_ctx_t *ctx, exprval_t *val, jsexcept_t *ei, VARIANT *ret)
59 {
60     V_VT(ret) = VT_EMPTY;
61
62     switch(val->type) {
63     case EXPRVAL_VARIANT:
64         return VariantCopy(ret, &val->u.var);
65     case EXPRVAL_IDREF:
66         if(!val->u.idref.disp) {
67             FIXME("throw ReferenceError\n");
68             return E_FAIL;
69         }
70
71         return disp_propget(val->u.idref.disp, val->u.idref.id, ctx->lcid, ret, ei, NULL/*FIXME*/);
72     default:
73         ERR("type %d\n", val->type);
74         return E_FAIL;
75     }
76 }
77
78 static HRESULT exprval_to_value(script_ctx_t *ctx, exprval_t *val, jsexcept_t *ei, VARIANT *ret)
79 {
80     if(val->type == EXPRVAL_VARIANT) {
81         *ret = val->u.var;
82         V_VT(&val->u.var) = VT_EMPTY;
83         return S_OK;
84     }
85
86     return exprval_value(ctx, val, ei, ret);
87 }
88
89 static HRESULT exprval_to_boolean(script_ctx_t *ctx, exprval_t *exprval, jsexcept_t *ei, VARIANT_BOOL *b)
90 {
91     if(exprval->type != EXPRVAL_VARIANT) {
92         VARIANT val;
93         HRESULT hres;
94
95         hres = exprval_to_value(ctx, exprval, ei, &val);
96         if(FAILED(hres))
97             return hres;
98
99         hres = to_boolean(&val, b);
100         VariantClear(&val);
101         return hres;
102     }
103
104     return to_boolean(&exprval->u.var, b);
105 }
106
107 static void exprval_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 literal_to_var(literal_t *literal, VARIANT *v)
198 {
199     V_VT(v) = literal->vt;
200
201     switch(V_VT(v)) {
202     case VT_EMPTY:
203     case VT_NULL:
204         break;
205     case VT_I4:
206         V_I4(v) = literal->u.lval;
207         break;
208     case VT_R8:
209         V_R8(v) = literal->u.dval;
210         break;
211     case VT_BSTR:
212         V_BSTR(v) = SysAllocString(literal->u.wstr);
213         break;
214     case VT_BOOL:
215         V_BOOL(v) = literal->u.bval;
216         break;
217     case VT_DISPATCH:
218         IDispatch_AddRef(literal->u.disp);
219         V_DISPATCH(v) = literal->u.disp;
220         break;
221     default:
222         ERR("wrong type %d\n", V_VT(v));
223         return E_NOTIMPL;
224     }
225
226     return S_OK;
227 }
228
229 HRESULT exec_source(exec_ctx_t *ctx, parser_ctx_t *parser, source_elements_t *source, jsexcept_t *ei, VARIANT *retv)
230 {
231     script_ctx_t *script = parser->script;
232     parser_ctx_t *prev_parser;
233     VARIANT val, tmp;
234     statement_t *stat;
235     exec_ctx_t *prev_ctx;
236     return_type_t rt;
237     HRESULT hres = S_OK;
238
239     prev_ctx = script->exec_ctx;
240     script->exec_ctx = ctx;
241
242     prev_parser = ctx->parser;
243     ctx->parser = parser;
244
245     V_VT(&val) = VT_EMPTY;
246     memset(&rt, 0, sizeof(rt));
247     rt.type = RT_NORMAL;
248
249     for(stat = source->statement; stat; stat = stat->next) {
250         hres = stat_eval(ctx, stat, &rt, &tmp);
251         if(FAILED(hres))
252             break;
253
254         VariantClear(&val);
255         val = tmp;
256         if(rt.type != RT_NORMAL)
257             break;
258     }
259
260     script->exec_ctx = prev_ctx;
261     ctx->parser = prev_parser;
262
263     if(rt.type != RT_NORMAL && rt.type != RT_RETURN) {
264         FIXME("wrong rt %d\n", rt.type);
265         hres = E_FAIL;
266     }
267
268     *ei = rt.ei;
269     if(FAILED(hres)) {
270         VariantClear(&val);
271         return hres;
272     }
273
274     if(retv)
275         *retv = val;
276     else
277         VariantClear(&val);
278     return S_OK;
279 }
280
281 /* ECMA-262 3rd Edition    10.1.4 */
282 static HRESULT identifier_eval(exec_ctx_t *ctx, BSTR identifier, DWORD flags, exprval_t *ret)
283 {
284     scope_chain_t *scope;
285     named_item_t *item;
286     DISPID id = 0;
287     HRESULT hres;
288
289     TRACE("%s\n", debugstr_w(identifier));
290
291     for(scope = ctx->scope_chain; scope; scope = scope->next) {
292         hres = dispex_get_id(_IDispatchEx_(scope->obj), identifier, 0, &id);
293         if(SUCCEEDED(hres))
294             break;
295     }
296
297     if(scope) {
298         exprval_set_idref(ret, (IDispatch*)_IDispatchEx_(scope->obj), id);
299         return S_OK;
300     }
301
302     hres = dispex_get_id(_IDispatchEx_(ctx->parser->script->global), identifier, 0, &id);
303     if(SUCCEEDED(hres)) {
304         exprval_set_idref(ret, (IDispatch*)_IDispatchEx_(ctx->parser->script->global), id);
305         return S_OK;
306     }
307
308     for(item = ctx->parser->script->named_items; item; item = item->next) {
309         hres = disp_get_id(item->disp, identifier, 0, &id);
310         if(SUCCEEDED(hres))
311             break;
312     }
313
314     if(item) {
315         exprval_set_idref(ret, (IDispatch*)item->disp, id);
316         return S_OK;
317     }
318
319     hres = dispex_get_id(_IDispatchEx_(ctx->parser->script->script_disp), identifier, 0, &id);
320     if(SUCCEEDED(hres)) {
321         exprval_set_idref(ret, (IDispatch*)_IDispatchEx_(ctx->parser->script->script_disp), id);
322         return S_OK;
323     }
324
325     if(flags & EXPR_NEWREF) {
326         hres = dispex_get_id(_IDispatchEx_(ctx->var_disp), identifier, fdexNameEnsure, &id);
327         if(FAILED(hres))
328             return hres;
329
330         exprval_set_idref(ret, (IDispatch*)_IDispatchEx_(ctx->var_disp), id);
331         return S_OK;
332     }
333
334     WARN("Could not find identifier %s\n", debugstr_w(identifier));
335     return E_FAIL;
336 }
337
338 HRESULT block_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
339 {
340     FIXME("\n");
341     return E_NOTIMPL;
342 }
343
344 /* ECMA-262 3rd Edition    12.2 */
345 static HRESULT variable_list_eval(exec_ctx_t *ctx, variable_declaration_t *var_list, jsexcept_t *ei)
346 {
347     variable_declaration_t *iter;
348     HRESULT hres;
349
350     for(iter = var_list; iter; iter = iter->next) {
351         VARIANT val;
352
353         if(iter->expr) {
354             exprval_t exprval;
355
356             hres = expr_eval(ctx, iter->expr, 0, ei, &exprval);
357             if(FAILED(hres))
358                 break;
359
360             hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
361             exprval_release(&exprval);
362             if(FAILED(hres))
363                 break;
364         }else {
365             V_VT(&val) = VT_EMPTY;
366         }
367
368         hres = jsdisp_propput_name(ctx->var_disp, iter->identifier, ctx->parser->script->lcid, &val, ei, NULL/*FIXME*/);
369         VariantClear(&val);
370         if(FAILED(hres))
371             break;
372     }
373
374     return hres;
375 }
376
377 /* ECMA-262 3rd Edition    12.2 */
378 HRESULT var_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
379 {
380     var_statement_t *stat = (var_statement_t*)_stat;
381     HRESULT hres;
382
383     TRACE("\n");
384
385     hres = variable_list_eval(ctx, stat->variable_list, &rt->ei);
386     if(FAILED(hres))
387         return hres;
388
389     V_VT(ret) = VT_EMPTY;
390     return S_OK;
391 }
392
393 /* ECMA-262 3rd Edition    12.3 */
394 HRESULT empty_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
395 {
396     TRACE("\n");
397
398     V_VT(ret) = VT_EMPTY;
399     return S_OK;
400 }
401
402 /* ECMA-262 3rd Edition    12.4 */
403 HRESULT expression_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
404 {
405     expression_statement_t *stat = (expression_statement_t*)_stat;
406     exprval_t exprval;
407     VARIANT val;
408     HRESULT hres;
409
410     TRACE("\n");
411
412     hres = expr_eval(ctx, stat->expr, EXPR_NOVAL, &rt->ei, &exprval);
413     if(FAILED(hres))
414         return hres;
415
416     hres = exprval_to_value(ctx->parser->script, &exprval, &rt->ei, &val);
417     exprval_release(&exprval);
418     if(FAILED(hres))
419         return hres;
420
421     *ret = val;
422     TRACE("= %s\n", debugstr_variant(ret));
423     return S_OK;
424 }
425
426 HRESULT if_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
427 {
428     FIXME("\n");
429     return E_NOTIMPL;
430 }
431
432 HRESULT dowhile_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
433 {
434     FIXME("\n");
435     return E_NOTIMPL;
436 }
437
438 HRESULT while_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
439 {
440     FIXME("\n");
441     return E_NOTIMPL;
442 }
443
444 HRESULT for_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
445 {
446     FIXME("\n");
447     return E_NOTIMPL;
448 }
449
450 HRESULT forin_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
451 {
452     FIXME("\n");
453     return E_NOTIMPL;
454 }
455
456 HRESULT continue_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
457 {
458     FIXME("\n");
459     return E_NOTIMPL;
460 }
461
462 HRESULT break_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
463 {
464     FIXME("\n");
465     return E_NOTIMPL;
466 }
467
468 HRESULT return_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
469 {
470     FIXME("\n");
471     return E_NOTIMPL;
472 }
473
474 HRESULT with_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
475 {
476     FIXME("\n");
477     return E_NOTIMPL;
478 }
479
480 HRESULT labelled_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
481 {
482     FIXME("\n");
483     return E_NOTIMPL;
484 }
485
486 HRESULT switch_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
487 {
488     FIXME("\n");
489     return E_NOTIMPL;
490 }
491
492 HRESULT throw_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
493 {
494     FIXME("\n");
495     return E_NOTIMPL;
496 }
497
498 HRESULT try_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
499 {
500     FIXME("\n");
501     return E_NOTIMPL;
502 }
503
504 static HRESULT return_bool(exprval_t *ret, DWORD b)
505 {
506     ret->type = EXPRVAL_VARIANT;
507     V_VT(&ret->u.var) = VT_BOOL;
508     V_BOOL(&ret->u.var) = b ? VARIANT_TRUE : VARIANT_FALSE;
509
510     return S_OK;
511 }
512
513 HRESULT function_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
514 {
515     FIXME("\n");
516     return E_NOTIMPL;
517 }
518
519 HRESULT conditional_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
520 {
521     FIXME("\n");
522     return E_NOTIMPL;
523 }
524
525 HRESULT array_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
526 {
527     FIXME("\n");
528     return E_NOTIMPL;
529 }
530
531 HRESULT member_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
532 {
533     FIXME("\n");
534     return E_NOTIMPL;
535 }
536
537 static void free_dp(DISPPARAMS *dp)
538 {
539     DWORD i;
540
541     for(i=0; i < dp->cArgs; i++)
542         VariantClear(dp->rgvarg+i);
543     heap_free(dp->rgvarg);
544 }
545
546 static HRESULT args_to_param(exec_ctx_t *ctx, argument_t *args, jsexcept_t *ei, DISPPARAMS *dp)
547 {
548     VARIANTARG *vargs;
549     exprval_t exprval;
550     argument_t *iter;
551     DWORD cnt = 0, i;
552     HRESULT hres = S_OK;
553
554     memset(dp, 0, sizeof(*dp));
555
556     for(iter = args; iter; iter = iter->next)
557         cnt++;
558     if(!cnt)
559         return S_OK;
560
561     vargs = heap_alloc_zero(cnt * sizeof(*vargs));
562     if(!vargs)
563         return E_OUTOFMEMORY;
564
565     for(i = cnt, iter = args; iter; iter = iter->next) {
566         hres = expr_eval(ctx, iter->expr, 0, ei, &exprval);
567         if(FAILED(hres))
568             break;
569
570         hres = exprval_to_value(ctx->parser->script, &exprval, ei, vargs + (--i));
571         exprval_release(&exprval);
572         if(FAILED(hres))
573             break;
574     }
575
576     if(FAILED(hres)) {
577         free_dp(dp);
578         return hres;
579     }
580
581     dp->rgvarg = vargs;
582     dp->cArgs = cnt;
583     return S_OK;
584 }
585
586 HRESULT member_new_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
587 {
588     FIXME("\n");
589     return E_NOTIMPL;
590 }
591
592 HRESULT call_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
593 {
594     call_expression_t *expr = (call_expression_t*)_expr;
595     VARIANT func, var;
596     exprval_t exprval;
597     DISPPARAMS dp;
598     HRESULT hres;
599
600     TRACE("\n");
601
602     hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
603     if(FAILED(hres))
604         return hres;
605
606     hres = args_to_param(ctx, expr->argument_list, ei, &dp);
607     if(SUCCEEDED(hres)) {
608         switch(exprval.type) {
609         case EXPRVAL_IDREF:
610             hres = disp_call(exprval.u.idref.disp, exprval.u.idref.id, ctx->parser->script->lcid, DISPATCH_METHOD,
611                     &dp, flags & EXPR_NOVAL ? NULL : &var, ei, NULL/*FIXME*/);
612             if(flags & EXPR_NOVAL)
613                 V_VT(&var) = VT_EMPTY;
614             break;
615         default:
616             FIXME("unimplemented type %d\n", V_VT(&func));
617             hres = E_NOTIMPL;
618         }
619
620         free_dp(&dp);
621     }
622
623     exprval_release(&exprval);
624     if(FAILED(hres))
625         return hres;
626
627     TRACE("= %s\n", debugstr_variant(&var));
628     ret->type = EXPRVAL_VARIANT;
629     ret->u.var = var;
630     return S_OK;
631 }
632
633 HRESULT this_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
634 {
635     FIXME("\n");
636     return E_NOTIMPL;
637 }
638
639 /* ECMA-262 3rd Edition    10.1.4 */
640 HRESULT identifier_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
641 {
642     identifier_expression_t *expr = (identifier_expression_t*)_expr;
643     BSTR identifier;
644     HRESULT hres;
645
646     TRACE("\n");
647
648     identifier = SysAllocString(expr->identifier);
649     if(!identifier)
650         return E_OUTOFMEMORY;
651
652     hres = identifier_eval(ctx, identifier, flags, ret);
653
654     SysFreeString(identifier);
655     return hres;
656 }
657
658 /* ECMA-262 3rd Edition    7.8 */
659 HRESULT literal_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
660 {
661     literal_expression_t *expr = (literal_expression_t*)_expr;
662     VARIANT var;
663     HRESULT hres;
664
665     TRACE("\n");
666
667     hres = literal_to_var(expr->literal, &var);
668     if(FAILED(hres))
669         return hres;
670
671     ret->type = EXPRVAL_VARIANT;
672     ret->u.var = var;
673     return S_OK;
674 }
675
676 HRESULT array_literal_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
677 {
678     FIXME("\n");
679     return E_NOTIMPL;
680 }
681
682 HRESULT property_value_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
683 {
684     FIXME("\n");
685     return E_NOTIMPL;
686 }
687
688 HRESULT comma_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
689 {
690     FIXME("\n");
691     return E_NOTIMPL;
692 }
693
694 HRESULT logical_or_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
695 {
696     FIXME("\n");
697     return E_NOTIMPL;
698 }
699
700 HRESULT logical_and_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
701 {
702     FIXME("\n");
703     return E_NOTIMPL;
704 }
705
706 HRESULT binary_or_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
707 {
708     FIXME("\n");
709     return E_NOTIMPL;
710 }
711
712 HRESULT binary_xor_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
713 {
714     FIXME("\n");
715     return E_NOTIMPL;
716 }
717
718 HRESULT binary_and_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
719 {
720     FIXME("\n");
721     return E_NOTIMPL;
722 }
723
724 HRESULT instanceof_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
725 {
726     FIXME("\n");
727     return E_NOTIMPL;
728 }
729
730 HRESULT in_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
731 {
732     FIXME("\n");
733     return E_NOTIMPL;
734 }
735
736 HRESULT add_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
737 {
738     FIXME("\n");
739     return E_NOTIMPL;
740 }
741
742 HRESULT sub_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
743 {
744     FIXME("\n");
745     return E_NOTIMPL;
746 }
747
748 HRESULT mul_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
749 {
750     FIXME("\n");
751     return E_NOTIMPL;
752 }
753
754 HRESULT div_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
755 {
756     FIXME("\n");
757     return E_NOTIMPL;
758 }
759
760 HRESULT mod_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
761 {
762     FIXME("\n");
763     return E_NOTIMPL;
764 }
765
766 HRESULT delete_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
767 {
768     FIXME("\n");
769     return E_NOTIMPL;
770 }
771
772 HRESULT void_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
773 {
774     FIXME("\n");
775     return E_NOTIMPL;
776 }
777
778 HRESULT typeof_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
779 {
780     FIXME("\n");
781     return E_NOTIMPL;
782 }
783
784 HRESULT minus_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
785 {
786     FIXME("\n");
787     return E_NOTIMPL;
788 }
789
790 HRESULT plus_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
791 {
792     FIXME("\n");
793     return E_NOTIMPL;
794 }
795
796 HRESULT post_increment_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
797 {
798     FIXME("\n");
799     return E_NOTIMPL;
800 }
801
802 HRESULT post_decrement_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
803 {
804     FIXME("\n");
805     return E_NOTIMPL;
806 }
807
808 HRESULT pre_increment_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
809 {
810     FIXME("\n");
811     return E_NOTIMPL;
812 }
813
814 HRESULT pre_decrement_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
815 {
816     FIXME("\n");
817     return E_NOTIMPL;
818 }
819
820 HRESULT new_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
821 {
822     FIXME("\n");
823     return E_NOTIMPL;
824 }
825
826 HRESULT equal_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
827 {
828     FIXME("\n");
829     return E_NOTIMPL;
830 }
831
832 HRESULT equal2_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
833 {
834     FIXME("\n");
835     return E_NOTIMPL;
836 }
837
838 HRESULT not_equal_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
839 {
840
841     FIXME("\n");
842     return E_NOTIMPL;
843 }
844
845 HRESULT not_equal2_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
846 {
847     FIXME("\n");
848     return E_NOTIMPL;
849 }
850
851 HRESULT less_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
852 {
853     FIXME("\n");
854     return E_NOTIMPL;
855 }
856
857 HRESULT lesseq_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
858 {
859     FIXME("\n");
860     return E_NOTIMPL;
861 }
862
863 HRESULT greater_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
864 {
865     FIXME("\n");
866     return E_NOTIMPL;
867 }
868
869 HRESULT greatereq_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
870 {
871     FIXME("\n");
872     return E_NOTIMPL;
873 }
874
875 HRESULT binary_negation_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
876 {
877     FIXME("\n");
878     return E_NOTIMPL;
879 }
880
881 /* ECMA-262 3rd Edition    11.4.9 */
882 HRESULT logical_negation_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
883 {
884     unary_expression_t *expr = (unary_expression_t*)_expr;
885     exprval_t exprval;
886     VARIANT_BOOL b;
887     HRESULT hres;
888
889     TRACE("\n");
890
891     hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval);
892     if(FAILED(hres))
893         return hres;
894
895     hres = exprval_to_boolean(ctx->parser->script, &exprval, ei, &b);
896     exprval_release(&exprval);
897     if(FAILED(hres))
898         return hres;
899
900     return return_bool(ret, !b);
901 }
902
903 HRESULT left_shift_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 right_shift_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 right2_shift_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 /* ECMA-262 3rd Edition    11.13.1 */
922 HRESULT assign_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
923 {
924     binary_expression_t *expr = (binary_expression_t*)_expr;
925     exprval_t exprval, exprvalr;
926     VARIANT rval;
927     HRESULT hres;
928
929     TRACE("\n");
930
931     hres = expr_eval(ctx, expr->expression1, EXPR_NEWREF, ei, &exprval);
932     if(FAILED(hres))
933         return hres;
934
935     hres = expr_eval(ctx, expr->expression2, 0, ei, &exprvalr);
936     if(SUCCEEDED(hres)) {
937         hres = exprval_to_value(ctx->parser->script, &exprvalr, ei, &rval);
938         exprval_release(&exprvalr);
939     }
940
941     if(SUCCEEDED(hres))
942         hres = put_value(ctx->parser->script, &exprval, &rval, ei);
943
944     exprval_release(&exprval);
945     if(FAILED(hres)) {
946         VariantClear(&rval);
947         return hres;
948     }
949
950     ret->type = EXPRVAL_VARIANT;
951     ret->u.var = rval;
952     return S_OK;
953 }
954
955 HRESULT assign_lshift_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
956 {
957     FIXME("\n");
958     return E_NOTIMPL;
959 }
960
961 HRESULT assign_rshift_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
962 {
963     FIXME("\n");
964     return E_NOTIMPL;
965 }
966
967 HRESULT assign_rrshift_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
968 {
969     FIXME("\n");
970     return E_NOTIMPL;
971 }
972
973 HRESULT assign_add_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
974 {
975     FIXME("\n");
976     return E_NOTIMPL;
977 }
978
979 HRESULT assign_sub_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 assign_mul_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 assign_div_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 assign_mod_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 assign_and_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 assign_or_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 HRESULT assign_xor_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1016 {
1017     FIXME("\n");
1018     return E_NOTIMPL;
1019 }