jscript: Added logical negation 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 HRESULT var_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
345 {
346     FIXME("\n");
347     return E_NOTIMPL;
348 }
349
350 /* ECMA-262 3rd Edition    12.3 */
351 HRESULT empty_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
352 {
353     TRACE("\n");
354
355     V_VT(ret) = VT_EMPTY;
356     return S_OK;
357 }
358
359 /* ECMA-262 3rd Edition    12.4 */
360 HRESULT expression_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
361 {
362     expression_statement_t *stat = (expression_statement_t*)_stat;
363     exprval_t exprval;
364     VARIANT val;
365     HRESULT hres;
366
367     TRACE("\n");
368
369     hres = expr_eval(ctx, stat->expr, EXPR_NOVAL, &rt->ei, &exprval);
370     if(FAILED(hres))
371         return hres;
372
373     hres = exprval_to_value(ctx->parser->script, &exprval, &rt->ei, &val);
374     exprval_release(&exprval);
375     if(FAILED(hres))
376         return hres;
377
378     *ret = val;
379     TRACE("= %s\n", debugstr_variant(ret));
380     return S_OK;
381 }
382
383 HRESULT if_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
384 {
385     FIXME("\n");
386     return E_NOTIMPL;
387 }
388
389 HRESULT dowhile_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
390 {
391     FIXME("\n");
392     return E_NOTIMPL;
393 }
394
395 HRESULT while_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
396 {
397     FIXME("\n");
398     return E_NOTIMPL;
399 }
400
401 HRESULT for_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
402 {
403     FIXME("\n");
404     return E_NOTIMPL;
405 }
406
407 HRESULT forin_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
408 {
409     FIXME("\n");
410     return E_NOTIMPL;
411 }
412
413 HRESULT continue_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
414 {
415     FIXME("\n");
416     return E_NOTIMPL;
417 }
418
419 HRESULT break_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
420 {
421     FIXME("\n");
422     return E_NOTIMPL;
423 }
424
425 HRESULT return_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
426 {
427     FIXME("\n");
428     return E_NOTIMPL;
429 }
430
431 HRESULT with_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
432 {
433     FIXME("\n");
434     return E_NOTIMPL;
435 }
436
437 HRESULT labelled_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
438 {
439     FIXME("\n");
440     return E_NOTIMPL;
441 }
442
443 HRESULT switch_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
444 {
445     FIXME("\n");
446     return E_NOTIMPL;
447 }
448
449 HRESULT throw_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
450 {
451     FIXME("\n");
452     return E_NOTIMPL;
453 }
454
455 HRESULT try_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
456 {
457     FIXME("\n");
458     return E_NOTIMPL;
459 }
460
461 static HRESULT return_bool(exprval_t *ret, DWORD b)
462 {
463     ret->type = EXPRVAL_VARIANT;
464     V_VT(&ret->u.var) = VT_BOOL;
465     V_BOOL(&ret->u.var) = b ? VARIANT_TRUE : VARIANT_FALSE;
466
467     return S_OK;
468 }
469
470 HRESULT function_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
471 {
472     FIXME("\n");
473     return E_NOTIMPL;
474 }
475
476 HRESULT conditional_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
477 {
478     FIXME("\n");
479     return E_NOTIMPL;
480 }
481
482 HRESULT array_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
483 {
484     FIXME("\n");
485     return E_NOTIMPL;
486 }
487
488 HRESULT member_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
489 {
490     FIXME("\n");
491     return E_NOTIMPL;
492 }
493
494 static void free_dp(DISPPARAMS *dp)
495 {
496     DWORD i;
497
498     for(i=0; i < dp->cArgs; i++)
499         VariantClear(dp->rgvarg+i);
500     heap_free(dp->rgvarg);
501 }
502
503 static HRESULT args_to_param(exec_ctx_t *ctx, argument_t *args, jsexcept_t *ei, DISPPARAMS *dp)
504 {
505     VARIANTARG *vargs;
506     exprval_t exprval;
507     argument_t *iter;
508     DWORD cnt = 0, i;
509     HRESULT hres = S_OK;
510
511     memset(dp, 0, sizeof(*dp));
512
513     for(iter = args; iter; iter = iter->next)
514         cnt++;
515     if(!cnt)
516         return S_OK;
517
518     vargs = heap_alloc_zero(cnt * sizeof(*vargs));
519     if(!vargs)
520         return E_OUTOFMEMORY;
521
522     for(i = cnt, iter = args; iter; iter = iter->next) {
523         hres = expr_eval(ctx, iter->expr, 0, ei, &exprval);
524         if(FAILED(hres))
525             break;
526
527         hres = exprval_to_value(ctx->parser->script, &exprval, ei, vargs + (--i));
528         exprval_release(&exprval);
529         if(FAILED(hres))
530             break;
531     }
532
533     if(FAILED(hres)) {
534         free_dp(dp);
535         return hres;
536     }
537
538     dp->rgvarg = vargs;
539     dp->cArgs = cnt;
540     return S_OK;
541 }
542
543 HRESULT member_new_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
544 {
545     FIXME("\n");
546     return E_NOTIMPL;
547 }
548
549 HRESULT call_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
550 {
551     call_expression_t *expr = (call_expression_t*)_expr;
552     VARIANT func, var;
553     exprval_t exprval;
554     DISPPARAMS dp;
555     HRESULT hres;
556
557     TRACE("\n");
558
559     hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
560     if(FAILED(hres))
561         return hres;
562
563     hres = args_to_param(ctx, expr->argument_list, ei, &dp);
564     if(SUCCEEDED(hres)) {
565         switch(exprval.type) {
566         case EXPRVAL_IDREF:
567             hres = disp_call(exprval.u.idref.disp, exprval.u.idref.id, ctx->parser->script->lcid, DISPATCH_METHOD,
568                     &dp, flags & EXPR_NOVAL ? NULL : &var, ei, NULL/*FIXME*/);
569             if(flags & EXPR_NOVAL)
570                 V_VT(&var) = VT_EMPTY;
571             break;
572         default:
573             FIXME("unimplemented type %d\n", V_VT(&func));
574             hres = E_NOTIMPL;
575         }
576
577         free_dp(&dp);
578     }
579
580     exprval_release(&exprval);
581     if(FAILED(hres))
582         return hres;
583
584     TRACE("= %s\n", debugstr_variant(&var));
585     ret->type = EXPRVAL_VARIANT;
586     ret->u.var = var;
587     return S_OK;
588 }
589
590 HRESULT this_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
591 {
592     FIXME("\n");
593     return E_NOTIMPL;
594 }
595
596 /* ECMA-262 3rd Edition    10.1.4 */
597 HRESULT identifier_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
598 {
599     identifier_expression_t *expr = (identifier_expression_t*)_expr;
600     BSTR identifier;
601     HRESULT hres;
602
603     TRACE("\n");
604
605     identifier = SysAllocString(expr->identifier);
606     if(!identifier)
607         return E_OUTOFMEMORY;
608
609     hres = identifier_eval(ctx, identifier, flags, ret);
610
611     SysFreeString(identifier);
612     return hres;
613 }
614
615 /* ECMA-262 3rd Edition    7.8 */
616 HRESULT literal_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
617 {
618     literal_expression_t *expr = (literal_expression_t*)_expr;
619     VARIANT var;
620     HRESULT hres;
621
622     TRACE("\n");
623
624     hres = literal_to_var(expr->literal, &var);
625     if(FAILED(hres))
626         return hres;
627
628     ret->type = EXPRVAL_VARIANT;
629     ret->u.var = var;
630     return S_OK;
631 }
632
633 HRESULT array_literal_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 HRESULT property_value_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
640 {
641     FIXME("\n");
642     return E_NOTIMPL;
643 }
644
645 HRESULT comma_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
646 {
647     FIXME("\n");
648     return E_NOTIMPL;
649 }
650
651 HRESULT logical_or_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
652 {
653     FIXME("\n");
654     return E_NOTIMPL;
655 }
656
657 HRESULT logical_and_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
658 {
659     FIXME("\n");
660     return E_NOTIMPL;
661 }
662
663 HRESULT binary_or_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
664 {
665     FIXME("\n");
666     return E_NOTIMPL;
667 }
668
669 HRESULT binary_xor_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
670 {
671     FIXME("\n");
672     return E_NOTIMPL;
673 }
674
675 HRESULT binary_and_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
676 {
677     FIXME("\n");
678     return E_NOTIMPL;
679 }
680
681 HRESULT instanceof_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
682 {
683     FIXME("\n");
684     return E_NOTIMPL;
685 }
686
687 HRESULT in_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
688 {
689     FIXME("\n");
690     return E_NOTIMPL;
691 }
692
693 HRESULT add_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
694 {
695     FIXME("\n");
696     return E_NOTIMPL;
697 }
698
699 HRESULT sub_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
700 {
701     FIXME("\n");
702     return E_NOTIMPL;
703 }
704
705 HRESULT mul_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
706 {
707     FIXME("\n");
708     return E_NOTIMPL;
709 }
710
711 HRESULT div_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
712 {
713     FIXME("\n");
714     return E_NOTIMPL;
715 }
716
717 HRESULT mod_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
718 {
719     FIXME("\n");
720     return E_NOTIMPL;
721 }
722
723 HRESULT delete_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
724 {
725     FIXME("\n");
726     return E_NOTIMPL;
727 }
728
729 HRESULT void_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
730 {
731     FIXME("\n");
732     return E_NOTIMPL;
733 }
734
735 HRESULT typeof_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
736 {
737     FIXME("\n");
738     return E_NOTIMPL;
739 }
740
741 HRESULT minus_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
742 {
743     FIXME("\n");
744     return E_NOTIMPL;
745 }
746
747 HRESULT plus_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
748 {
749     FIXME("\n");
750     return E_NOTIMPL;
751 }
752
753 HRESULT post_increment_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
754 {
755     FIXME("\n");
756     return E_NOTIMPL;
757 }
758
759 HRESULT post_decrement_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
760 {
761     FIXME("\n");
762     return E_NOTIMPL;
763 }
764
765 HRESULT pre_increment_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
766 {
767     FIXME("\n");
768     return E_NOTIMPL;
769 }
770
771 HRESULT pre_decrement_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
772 {
773     FIXME("\n");
774     return E_NOTIMPL;
775 }
776
777 HRESULT new_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
778 {
779     FIXME("\n");
780     return E_NOTIMPL;
781 }
782
783 HRESULT equal_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
784 {
785     FIXME("\n");
786     return E_NOTIMPL;
787 }
788
789 HRESULT equal2_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
790 {
791     FIXME("\n");
792     return E_NOTIMPL;
793 }
794
795 HRESULT not_equal_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
796 {
797
798     FIXME("\n");
799     return E_NOTIMPL;
800 }
801
802 HRESULT not_equal2_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 less_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 lesseq_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 greater_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 greatereq_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 binary_negation_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 /* ECMA-262 3rd Edition    11.4.9 */
839 HRESULT logical_negation_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
840 {
841     unary_expression_t *expr = (unary_expression_t*)_expr;
842     exprval_t exprval;
843     VARIANT_BOOL b;
844     HRESULT hres;
845
846     TRACE("\n");
847
848     hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval);
849     if(FAILED(hres))
850         return hres;
851
852     hres = exprval_to_boolean(ctx->parser->script, &exprval, ei, &b);
853     exprval_release(&exprval);
854     if(FAILED(hres))
855         return hres;
856
857     return return_bool(ret, !b);
858 }
859
860 HRESULT left_shift_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 right_shift_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 right2_shift_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 /* ECMA-262 3rd Edition    11.13.1 */
879 HRESULT assign_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
880 {
881     binary_expression_t *expr = (binary_expression_t*)_expr;
882     exprval_t exprval, exprvalr;
883     VARIANT rval;
884     HRESULT hres;
885
886     TRACE("\n");
887
888     hres = expr_eval(ctx, expr->expression1, EXPR_NEWREF, ei, &exprval);
889     if(FAILED(hres))
890         return hres;
891
892     hres = expr_eval(ctx, expr->expression2, 0, ei, &exprvalr);
893     if(SUCCEEDED(hres)) {
894         hres = exprval_to_value(ctx->parser->script, &exprvalr, ei, &rval);
895         exprval_release(&exprvalr);
896     }
897
898     if(SUCCEEDED(hres))
899         hres = put_value(ctx->parser->script, &exprval, &rval, ei);
900
901     exprval_release(&exprval);
902     if(FAILED(hres)) {
903         VariantClear(&rval);
904         return hres;
905     }
906
907     ret->type = EXPRVAL_VARIANT;
908     ret->u.var = rval;
909     return S_OK;
910 }
911
912 HRESULT assign_lshift_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 assign_rshift_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 assign_rrshift_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 assign_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 assign_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 assign_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 assign_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 assign_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 assign_and_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 assign_or_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 assign_xor_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
973 {
974     FIXME("\n");
975     return E_NOTIMPL;
976 }