jscript: Added variable object handling.
[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 void exprval_set_idref(exprval_t *val, IDispatch *disp, DISPID id)
90 {
91     val->type = EXPRVAL_IDREF;
92     val->u.idref.disp = disp;
93     val->u.idref.id = id;
94
95     if(disp)
96         IDispatch_AddRef(disp);
97 }
98
99 void scope_release(scope_chain_t *scope)
100 {
101     if(--scope->ref)
102         return;
103
104     if(scope->next)
105         scope_release(scope->next);
106
107     IDispatchEx_Release(_IDispatchEx_(scope->obj));
108     heap_free(scope);
109 }
110
111 HRESULT create_exec_ctx(DispatchEx *var_disp, scope_chain_t *scope, exec_ctx_t **ret)
112 {
113     exec_ctx_t *ctx;
114
115     ctx = heap_alloc_zero(sizeof(exec_ctx_t));
116     if(!ctx)
117         return E_OUTOFMEMORY;
118
119     IDispatchEx_AddRef(_IDispatchEx_(var_disp));
120     ctx->var_disp = var_disp;
121
122     if(scope) {
123         scope_addref(scope);
124         ctx->scope_chain = scope;
125     }
126
127     *ret = ctx;
128     return S_OK;
129 }
130
131 void exec_release(exec_ctx_t *ctx)
132 {
133     if(--ctx->ref)
134         return;
135
136     if(ctx->scope_chain)
137         scope_release(ctx->scope_chain);
138     if(ctx->var_disp)
139         IDispatchEx_Release(_IDispatchEx_(ctx->var_disp));
140     heap_free(ctx);
141 }
142
143 static HRESULT dispex_get_id(IDispatchEx *dispex, BSTR name, DWORD flags, DISPID *id)
144 {
145     *id = 0;
146
147     return IDispatchEx_GetDispID(dispex, name, flags|fdexNameCaseSensitive, id);
148 }
149
150 static HRESULT disp_get_id(IDispatch *disp, BSTR name, DWORD flags, DISPID *id)
151 {
152     IDispatchEx *dispex;
153     HRESULT hres;
154
155     hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
156     if(FAILED(hres)) {
157         TRACE("unsing IDispatch\n");
158
159         *id = 0;
160         return IDispatch_GetIDsOfNames(disp, &IID_NULL, &name, 1, 0, id);
161     }
162
163     hres = dispex_get_id(dispex, name, flags, id);
164     IDispatchEx_Release(dispex);
165     return hres;
166 }
167
168 /* ECMA-262 3rd Edition    8.7.2 */
169 static HRESULT put_value(script_ctx_t *ctx, exprval_t *ref, VARIANT *v, jsexcept_t *ei)
170 {
171     if(ref->type != EXPRVAL_IDREF) {
172         FIXME("throw ReferemceError\n");
173         return E_FAIL;
174     }
175
176     return disp_propput(ref->u.idref.disp, ref->u.idref.id, ctx->lcid, v, ei, NULL/*FIXME*/);
177 }
178
179 static HRESULT literal_to_var(literal_t *literal, VARIANT *v)
180 {
181     V_VT(v) = literal->vt;
182
183     switch(V_VT(v)) {
184     case VT_EMPTY:
185     case VT_NULL:
186         break;
187     case VT_I4:
188         V_I4(v) = literal->u.lval;
189         break;
190     case VT_R8:
191         V_R8(v) = literal->u.dval;
192         break;
193     case VT_BSTR:
194         V_BSTR(v) = SysAllocString(literal->u.wstr);
195         break;
196     case VT_BOOL:
197         V_BOOL(v) = literal->u.bval;
198         break;
199     case VT_DISPATCH:
200         IDispatch_AddRef(literal->u.disp);
201         V_DISPATCH(v) = literal->u.disp;
202         break;
203     default:
204         ERR("wrong type %d\n", V_VT(v));
205         return E_NOTIMPL;
206     }
207
208     return S_OK;
209 }
210
211 HRESULT exec_source(exec_ctx_t *ctx, parser_ctx_t *parser, source_elements_t *source, jsexcept_t *ei, VARIANT *retv)
212 {
213     script_ctx_t *script = parser->script;
214     parser_ctx_t *prev_parser;
215     VARIANT val, tmp;
216     statement_t *stat;
217     exec_ctx_t *prev_ctx;
218     return_type_t rt;
219     HRESULT hres = S_OK;
220
221     prev_ctx = script->exec_ctx;
222     script->exec_ctx = ctx;
223
224     prev_parser = ctx->parser;
225     ctx->parser = parser;
226
227     V_VT(&val) = VT_EMPTY;
228     memset(&rt, 0, sizeof(rt));
229     rt.type = RT_NORMAL;
230
231     for(stat = source->statement; stat; stat = stat->next) {
232         hres = stat_eval(ctx, stat, &rt, &tmp);
233         if(FAILED(hres))
234             break;
235
236         VariantClear(&val);
237         val = tmp;
238         if(rt.type != RT_NORMAL)
239             break;
240     }
241
242     script->exec_ctx = prev_ctx;
243     ctx->parser = prev_parser;
244
245     if(rt.type != RT_NORMAL && rt.type != RT_RETURN) {
246         FIXME("wrong rt %d\n", rt.type);
247         hres = E_FAIL;
248     }
249
250     *ei = rt.ei;
251     if(FAILED(hres)) {
252         VariantClear(&val);
253         return hres;
254     }
255
256     if(retv)
257         *retv = val;
258     else
259         VariantClear(&val);
260     return S_OK;
261 }
262
263 /* ECMA-262 3rd Edition    10.1.4 */
264 static HRESULT identifier_eval(exec_ctx_t *ctx, BSTR identifier, DWORD flags, exprval_t *ret)
265 {
266     scope_chain_t *scope;
267     named_item_t *item;
268     DISPID id = 0;
269     HRESULT hres;
270
271     TRACE("%s\n", debugstr_w(identifier));
272
273     for(scope = ctx->scope_chain; scope; scope = scope->next) {
274         hres = dispex_get_id(_IDispatchEx_(scope->obj), identifier, 0, &id);
275         if(SUCCEEDED(hres))
276             break;
277     }
278
279     if(scope) {
280         exprval_set_idref(ret, (IDispatch*)_IDispatchEx_(scope->obj), id);
281         return S_OK;
282     }
283
284     hres = dispex_get_id(_IDispatchEx_(ctx->parser->script->global), identifier, 0, &id);
285     if(SUCCEEDED(hres)) {
286         exprval_set_idref(ret, (IDispatch*)_IDispatchEx_(ctx->parser->script->global), id);
287         return S_OK;
288     }
289
290     for(item = ctx->parser->script->named_items; item; item = item->next) {
291         hres = disp_get_id(item->disp, identifier, 0, &id);
292         if(SUCCEEDED(hres))
293             break;
294     }
295
296     if(item) {
297         exprval_set_idref(ret, (IDispatch*)item->disp, id);
298         return S_OK;
299     }
300
301     hres = dispex_get_id(_IDispatchEx_(ctx->parser->script->script_disp), identifier, 0, &id);
302     if(SUCCEEDED(hres)) {
303         exprval_set_idref(ret, (IDispatch*)_IDispatchEx_(ctx->parser->script->script_disp), id);
304         return S_OK;
305     }
306
307     if(flags & EXPR_NEWREF) {
308         hres = dispex_get_id(_IDispatchEx_(ctx->var_disp), identifier, fdexNameEnsure, &id);
309         if(FAILED(hres))
310             return hres;
311
312         exprval_set_idref(ret, (IDispatch*)_IDispatchEx_(ctx->var_disp), id);
313         return S_OK;
314     }
315
316     WARN("Could not find identifier %s\n", debugstr_w(identifier));
317     return E_FAIL;
318 }
319
320 HRESULT block_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
321 {
322     FIXME("\n");
323     return E_NOTIMPL;
324 }
325
326 HRESULT var_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
327 {
328     FIXME("\n");
329     return E_NOTIMPL;
330 }
331
332 /* ECMA-262 3rd Edition    12.3 */
333 HRESULT empty_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
334 {
335     TRACE("\n");
336
337     V_VT(ret) = VT_EMPTY;
338     return S_OK;
339 }
340
341 /* ECMA-262 3rd Edition    12.4 */
342 HRESULT expression_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
343 {
344     expression_statement_t *stat = (expression_statement_t*)_stat;
345     exprval_t exprval;
346     VARIANT val;
347     HRESULT hres;
348
349     TRACE("\n");
350
351     hres = expr_eval(ctx, stat->expr, EXPR_NOVAL, &rt->ei, &exprval);
352     if(FAILED(hres))
353         return hres;
354
355     hres = exprval_to_value(ctx->parser->script, &exprval, &rt->ei, &val);
356     exprval_release(&exprval);
357     if(FAILED(hres))
358         return hres;
359
360     *ret = val;
361     TRACE("= %s\n", debugstr_variant(ret));
362     return S_OK;
363 }
364
365 HRESULT if_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
366 {
367     FIXME("\n");
368     return E_NOTIMPL;
369 }
370
371 HRESULT dowhile_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
372 {
373     FIXME("\n");
374     return E_NOTIMPL;
375 }
376
377 HRESULT while_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
378 {
379     FIXME("\n");
380     return E_NOTIMPL;
381 }
382
383 HRESULT for_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 forin_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 continue_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 break_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 return_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 with_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 labelled_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 switch_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 throw_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 try_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 function_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
444 {
445     FIXME("\n");
446     return E_NOTIMPL;
447 }
448
449 HRESULT conditional_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
450 {
451     FIXME("\n");
452     return E_NOTIMPL;
453 }
454
455 HRESULT array_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
456 {
457     FIXME("\n");
458     return E_NOTIMPL;
459 }
460
461 HRESULT member_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
462 {
463     FIXME("\n");
464     return E_NOTIMPL;
465 }
466
467 HRESULT member_new_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
468 {
469     FIXME("\n");
470     return E_NOTIMPL;
471 }
472
473 HRESULT call_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
474 {
475     FIXME("\n");
476     return E_NOTIMPL;
477 }
478
479 HRESULT this_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
480 {
481     FIXME("\n");
482     return E_NOTIMPL;
483 }
484
485 /* ECMA-262 3rd Edition    10.1.4 */
486 HRESULT identifier_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
487 {
488     identifier_expression_t *expr = (identifier_expression_t*)_expr;
489     BSTR identifier;
490     HRESULT hres;
491
492     TRACE("\n");
493
494     identifier = SysAllocString(expr->identifier);
495     if(!identifier)
496         return E_OUTOFMEMORY;
497
498     hres = identifier_eval(ctx, identifier, flags, ret);
499
500     SysFreeString(identifier);
501     return hres;
502 }
503
504 /* ECMA-262 3rd Edition    7.8 */
505 HRESULT literal_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
506 {
507     literal_expression_t *expr = (literal_expression_t*)_expr;
508     VARIANT var;
509     HRESULT hres;
510
511     TRACE("\n");
512
513     hres = literal_to_var(expr->literal, &var);
514     if(FAILED(hres))
515         return hres;
516
517     ret->type = EXPRVAL_VARIANT;
518     ret->u.var = var;
519     return S_OK;
520 }
521
522 HRESULT array_literal_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
523 {
524     FIXME("\n");
525     return E_NOTIMPL;
526 }
527
528 HRESULT property_value_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
529 {
530     FIXME("\n");
531     return E_NOTIMPL;
532 }
533
534 HRESULT comma_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
535 {
536     FIXME("\n");
537     return E_NOTIMPL;
538 }
539
540 HRESULT logical_or_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
541 {
542     FIXME("\n");
543     return E_NOTIMPL;
544 }
545
546 HRESULT logical_and_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
547 {
548     FIXME("\n");
549     return E_NOTIMPL;
550 }
551
552 HRESULT binary_or_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
553 {
554     FIXME("\n");
555     return E_NOTIMPL;
556 }
557
558 HRESULT binary_xor_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
559 {
560     FIXME("\n");
561     return E_NOTIMPL;
562 }
563
564 HRESULT binary_and_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
565 {
566     FIXME("\n");
567     return E_NOTIMPL;
568 }
569
570 HRESULT instanceof_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
571 {
572     FIXME("\n");
573     return E_NOTIMPL;
574 }
575
576 HRESULT in_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
577 {
578     FIXME("\n");
579     return E_NOTIMPL;
580 }
581
582 HRESULT add_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
583 {
584     FIXME("\n");
585     return E_NOTIMPL;
586 }
587
588 HRESULT sub_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
589 {
590     FIXME("\n");
591     return E_NOTIMPL;
592 }
593
594 HRESULT mul_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
595 {
596     FIXME("\n");
597     return E_NOTIMPL;
598 }
599
600 HRESULT div_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
601 {
602     FIXME("\n");
603     return E_NOTIMPL;
604 }
605
606 HRESULT mod_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
607 {
608     FIXME("\n");
609     return E_NOTIMPL;
610 }
611
612 HRESULT delete_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
613 {
614     FIXME("\n");
615     return E_NOTIMPL;
616 }
617
618 HRESULT void_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
619 {
620     FIXME("\n");
621     return E_NOTIMPL;
622 }
623
624 HRESULT typeof_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
625 {
626     FIXME("\n");
627     return E_NOTIMPL;
628 }
629
630 HRESULT minus_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
631 {
632     FIXME("\n");
633     return E_NOTIMPL;
634 }
635
636 HRESULT plus_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
637 {
638     FIXME("\n");
639     return E_NOTIMPL;
640 }
641
642 HRESULT post_increment_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
643 {
644     FIXME("\n");
645     return E_NOTIMPL;
646 }
647
648 HRESULT post_decrement_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
649 {
650     FIXME("\n");
651     return E_NOTIMPL;
652 }
653
654 HRESULT pre_increment_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
655 {
656     FIXME("\n");
657     return E_NOTIMPL;
658 }
659
660 HRESULT pre_decrement_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 new_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 equal_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 HRESULT equal2_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
679 {
680     FIXME("\n");
681     return E_NOTIMPL;
682 }
683
684 HRESULT not_equal_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
685 {
686
687     FIXME("\n");
688     return E_NOTIMPL;
689 }
690
691 HRESULT not_equal2_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
692 {
693     FIXME("\n");
694     return E_NOTIMPL;
695 }
696
697 HRESULT less_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
698 {
699     FIXME("\n");
700     return E_NOTIMPL;
701 }
702
703 HRESULT lesseq_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
704 {
705     FIXME("\n");
706     return E_NOTIMPL;
707 }
708
709 HRESULT greater_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
710 {
711     FIXME("\n");
712     return E_NOTIMPL;
713 }
714
715 HRESULT greatereq_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
716 {
717     FIXME("\n");
718     return E_NOTIMPL;
719 }
720
721 HRESULT binary_negation_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
722 {
723     FIXME("\n");
724     return E_NOTIMPL;
725 }
726
727 HRESULT logical_negation_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
728 {
729     FIXME("\n");
730     return E_NOTIMPL;
731 }
732
733 HRESULT left_shift_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
734 {
735     FIXME("\n");
736     return E_NOTIMPL;
737 }
738
739 HRESULT right_shift_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
740 {
741     FIXME("\n");
742     return E_NOTIMPL;
743 }
744
745 HRESULT right2_shift_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
746 {
747     FIXME("\n");
748     return E_NOTIMPL;
749 }
750
751 /* ECMA-262 3rd Edition    11.13.1 */
752 HRESULT assign_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
753 {
754     binary_expression_t *expr = (binary_expression_t*)_expr;
755     exprval_t exprval, exprvalr;
756     VARIANT rval;
757     HRESULT hres;
758
759     TRACE("\n");
760
761     hres = expr_eval(ctx, expr->expression1, EXPR_NEWREF, ei, &exprval);
762     if(FAILED(hres))
763         return hres;
764
765     hres = expr_eval(ctx, expr->expression2, 0, ei, &exprvalr);
766     if(SUCCEEDED(hres)) {
767         hres = exprval_to_value(ctx->parser->script, &exprvalr, ei, &rval);
768         exprval_release(&exprvalr);
769     }
770
771     if(SUCCEEDED(hres))
772         hres = put_value(ctx->parser->script, &exprval, &rval, ei);
773
774     exprval_release(&exprval);
775     if(FAILED(hres)) {
776         VariantClear(&rval);
777         return hres;
778     }
779
780     ret->type = EXPRVAL_VARIANT;
781     ret->u.var = rval;
782     return S_OK;
783 }
784
785 HRESULT assign_lshift_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
786 {
787     FIXME("\n");
788     return E_NOTIMPL;
789 }
790
791 HRESULT assign_rshift_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
792 {
793     FIXME("\n");
794     return E_NOTIMPL;
795 }
796
797 HRESULT assign_rrshift_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
798 {
799     FIXME("\n");
800     return E_NOTIMPL;
801 }
802
803 HRESULT assign_add_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
804 {
805     FIXME("\n");
806     return E_NOTIMPL;
807 }
808
809 HRESULT assign_sub_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
810 {
811     FIXME("\n");
812     return E_NOTIMPL;
813 }
814
815 HRESULT assign_mul_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
816 {
817     FIXME("\n");
818     return E_NOTIMPL;
819 }
820
821 HRESULT assign_div_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
822 {
823     FIXME("\n");
824     return E_NOTIMPL;
825 }
826
827 HRESULT assign_mod_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
828 {
829     FIXME("\n");
830     return E_NOTIMPL;
831 }
832
833 HRESULT assign_and_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
834 {
835     FIXME("\n");
836     return E_NOTIMPL;
837 }
838
839 HRESULT assign_or_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
840 {
841     FIXME("\n");
842     return E_NOTIMPL;
843 }
844
845 HRESULT assign_xor_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 }