jscript: Added scope chain 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 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(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     if(scope) {
120         scope_addref(scope);
121         ctx->scope_chain = scope;
122     }
123
124     *ret = ctx;
125     return S_OK;
126 }
127
128 void exec_release(exec_ctx_t *ctx)
129 {
130     if(--ctx->ref)
131         return;
132
133     if(ctx->scope_chain)
134         scope_release(ctx->scope_chain);
135     heap_free(ctx);
136 }
137
138 static HRESULT dispex_get_id(IDispatchEx *dispex, BSTR name, DWORD flags, DISPID *id)
139 {
140     *id = 0;
141
142     return IDispatchEx_GetDispID(dispex, name, flags|fdexNameCaseSensitive, id);
143 }
144
145 static HRESULT disp_get_id(IDispatch *disp, BSTR name, DWORD flags, DISPID *id)
146 {
147     IDispatchEx *dispex;
148     HRESULT hres;
149
150     hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
151     if(FAILED(hres)) {
152         TRACE("unsing IDispatch\n");
153
154         *id = 0;
155         return IDispatch_GetIDsOfNames(disp, &IID_NULL, &name, 1, 0, id);
156     }
157
158     hres = dispex_get_id(dispex, name, flags, id);
159     IDispatchEx_Release(dispex);
160     return hres;
161 }
162
163 /* ECMA-262 3rd Edition    8.7.2 */
164 static HRESULT put_value(script_ctx_t *ctx, exprval_t *ref, VARIANT *v, jsexcept_t *ei)
165 {
166     if(ref->type != EXPRVAL_IDREF) {
167         FIXME("throw ReferemceError\n");
168         return E_FAIL;
169     }
170
171     return disp_propput(ref->u.idref.disp, ref->u.idref.id, ctx->lcid, v, ei, NULL/*FIXME*/);
172 }
173
174 static HRESULT literal_to_var(literal_t *literal, VARIANT *v)
175 {
176     V_VT(v) = literal->vt;
177
178     switch(V_VT(v)) {
179     case VT_EMPTY:
180     case VT_NULL:
181         break;
182     case VT_I4:
183         V_I4(v) = literal->u.lval;
184         break;
185     case VT_R8:
186         V_R8(v) = literal->u.dval;
187         break;
188     case VT_BSTR:
189         V_BSTR(v) = SysAllocString(literal->u.wstr);
190         break;
191     case VT_BOOL:
192         V_BOOL(v) = literal->u.bval;
193         break;
194     case VT_DISPATCH:
195         IDispatch_AddRef(literal->u.disp);
196         V_DISPATCH(v) = literal->u.disp;
197         break;
198     default:
199         ERR("wrong type %d\n", V_VT(v));
200         return E_NOTIMPL;
201     }
202
203     return S_OK;
204 }
205
206 HRESULT exec_source(exec_ctx_t *ctx, parser_ctx_t *parser, source_elements_t *source, jsexcept_t *ei, VARIANT *retv)
207 {
208     script_ctx_t *script = parser->script;
209     parser_ctx_t *prev_parser;
210     VARIANT val, tmp;
211     statement_t *stat;
212     exec_ctx_t *prev_ctx;
213     return_type_t rt;
214     HRESULT hres = S_OK;
215
216     prev_ctx = script->exec_ctx;
217     script->exec_ctx = ctx;
218
219     prev_parser = ctx->parser;
220     ctx->parser = parser;
221
222     V_VT(&val) = VT_EMPTY;
223     memset(&rt, 0, sizeof(rt));
224     rt.type = RT_NORMAL;
225
226     for(stat = source->statement; stat; stat = stat->next) {
227         hres = stat_eval(ctx, stat, &rt, &tmp);
228         if(FAILED(hres))
229             break;
230
231         VariantClear(&val);
232         val = tmp;
233         if(rt.type != RT_NORMAL)
234             break;
235     }
236
237     script->exec_ctx = prev_ctx;
238     ctx->parser = prev_parser;
239
240     if(rt.type != RT_NORMAL && rt.type != RT_RETURN) {
241         FIXME("wrong rt %d\n", rt.type);
242         hres = E_FAIL;
243     }
244
245     *ei = rt.ei;
246     if(FAILED(hres)) {
247         VariantClear(&val);
248         return hres;
249     }
250
251     if(retv)
252         *retv = val;
253     else
254         VariantClear(&val);
255     return S_OK;
256 }
257
258 /* ECMA-262 3rd Edition    10.1.4 */
259 static HRESULT identifier_eval(exec_ctx_t *ctx, BSTR identifier, DWORD flags, exprval_t *ret)
260 {
261     scope_chain_t *scope;
262     named_item_t *item;
263     DISPID id = 0;
264     HRESULT hres;
265
266     TRACE("%s\n", debugstr_w(identifier));
267
268     for(scope = ctx->scope_chain; scope; scope = scope->next) {
269         hres = dispex_get_id(_IDispatchEx_(scope->obj), identifier, 0, &id);
270         if(SUCCEEDED(hres))
271             break;
272     }
273
274     if(scope) {
275         exprval_set_idref(ret, (IDispatch*)_IDispatchEx_(scope->obj), id);
276         return S_OK;
277     }
278
279     hres = dispex_get_id(_IDispatchEx_(ctx->parser->script->global), identifier, 0, &id);
280     if(SUCCEEDED(hres)) {
281         exprval_set_idref(ret, (IDispatch*)_IDispatchEx_(ctx->parser->script->global), id);
282         return S_OK;
283     }
284
285     for(item = ctx->parser->script->named_items; item; item = item->next) {
286         hres = disp_get_id(item->disp, identifier, 0, &id);
287         if(SUCCEEDED(hres))
288             break;
289     }
290
291     if(item) {
292         exprval_set_idref(ret, (IDispatch*)item->disp, id);
293         return S_OK;
294     }
295
296     hres = dispex_get_id(_IDispatchEx_(ctx->parser->script->script_disp), identifier, 0, &id);
297     if(SUCCEEDED(hres)) {
298         exprval_set_idref(ret, (IDispatch*)_IDispatchEx_(ctx->parser->script->script_disp), id);
299         return S_OK;
300     }
301
302     if(flags & EXPR_NEWREF) {
303         FIXME("create ref\n");
304         return E_NOTIMPL;
305     }
306
307     WARN("Could not find identifier %s\n", debugstr_w(identifier));
308     return E_FAIL;
309 }
310
311 HRESULT block_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
312 {
313     FIXME("\n");
314     return E_NOTIMPL;
315 }
316
317 HRESULT var_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
318 {
319     FIXME("\n");
320     return E_NOTIMPL;
321 }
322
323 /* ECMA-262 3rd Edition    12.3 */
324 HRESULT empty_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
325 {
326     TRACE("\n");
327
328     V_VT(ret) = VT_EMPTY;
329     return S_OK;
330 }
331
332 /* ECMA-262 3rd Edition    12.4 */
333 HRESULT expression_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
334 {
335     expression_statement_t *stat = (expression_statement_t*)_stat;
336     exprval_t exprval;
337     VARIANT val;
338     HRESULT hres;
339
340     TRACE("\n");
341
342     hres = expr_eval(ctx, stat->expr, EXPR_NOVAL, &rt->ei, &exprval);
343     if(FAILED(hres))
344         return hres;
345
346     hres = exprval_to_value(ctx->parser->script, &exprval, &rt->ei, &val);
347     exprval_release(&exprval);
348     if(FAILED(hres))
349         return hres;
350
351     *ret = val;
352     TRACE("= %s\n", debugstr_variant(ret));
353     return S_OK;
354 }
355
356 HRESULT if_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
357 {
358     FIXME("\n");
359     return E_NOTIMPL;
360 }
361
362 HRESULT dowhile_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
363 {
364     FIXME("\n");
365     return E_NOTIMPL;
366 }
367
368 HRESULT while_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
369 {
370     FIXME("\n");
371     return E_NOTIMPL;
372 }
373
374 HRESULT for_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
375 {
376     FIXME("\n");
377     return E_NOTIMPL;
378 }
379
380 HRESULT forin_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
381 {
382     FIXME("\n");
383     return E_NOTIMPL;
384 }
385
386 HRESULT continue_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
387 {
388     FIXME("\n");
389     return E_NOTIMPL;
390 }
391
392 HRESULT break_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
393 {
394     FIXME("\n");
395     return E_NOTIMPL;
396 }
397
398 HRESULT return_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
399 {
400     FIXME("\n");
401     return E_NOTIMPL;
402 }
403
404 HRESULT with_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
405 {
406     FIXME("\n");
407     return E_NOTIMPL;
408 }
409
410 HRESULT labelled_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
411 {
412     FIXME("\n");
413     return E_NOTIMPL;
414 }
415
416 HRESULT switch_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
417 {
418     FIXME("\n");
419     return E_NOTIMPL;
420 }
421
422 HRESULT throw_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
423 {
424     FIXME("\n");
425     return E_NOTIMPL;
426 }
427
428 HRESULT try_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
429 {
430     FIXME("\n");
431     return E_NOTIMPL;
432 }
433
434 HRESULT function_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
435 {
436     FIXME("\n");
437     return E_NOTIMPL;
438 }
439
440 HRESULT conditional_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
441 {
442     FIXME("\n");
443     return E_NOTIMPL;
444 }
445
446 HRESULT array_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
447 {
448     FIXME("\n");
449     return E_NOTIMPL;
450 }
451
452 HRESULT member_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
453 {
454     FIXME("\n");
455     return E_NOTIMPL;
456 }
457
458 HRESULT member_new_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
459 {
460     FIXME("\n");
461     return E_NOTIMPL;
462 }
463
464 HRESULT call_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
465 {
466     FIXME("\n");
467     return E_NOTIMPL;
468 }
469
470 HRESULT this_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 /* ECMA-262 3rd Edition    10.1.4 */
477 HRESULT identifier_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
478 {
479     identifier_expression_t *expr = (identifier_expression_t*)_expr;
480     BSTR identifier;
481     HRESULT hres;
482
483     TRACE("\n");
484
485     identifier = SysAllocString(expr->identifier);
486     if(!identifier)
487         return E_OUTOFMEMORY;
488
489     hres = identifier_eval(ctx, identifier, flags, ret);
490
491     SysFreeString(identifier);
492     return hres;
493 }
494
495 /* ECMA-262 3rd Edition    7.8 */
496 HRESULT literal_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
497 {
498     literal_expression_t *expr = (literal_expression_t*)_expr;
499     VARIANT var;
500     HRESULT hres;
501
502     TRACE("\n");
503
504     hres = literal_to_var(expr->literal, &var);
505     if(FAILED(hres))
506         return hres;
507
508     ret->type = EXPRVAL_VARIANT;
509     ret->u.var = var;
510     return S_OK;
511 }
512
513 HRESULT array_literal_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 property_value_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 comma_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 logical_or_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 HRESULT logical_and_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
538 {
539     FIXME("\n");
540     return E_NOTIMPL;
541 }
542
543 HRESULT binary_or_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 binary_xor_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
550 {
551     FIXME("\n");
552     return E_NOTIMPL;
553 }
554
555 HRESULT binary_and_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
556 {
557     FIXME("\n");
558     return E_NOTIMPL;
559 }
560
561 HRESULT instanceof_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
562 {
563     FIXME("\n");
564     return E_NOTIMPL;
565 }
566
567 HRESULT in_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
568 {
569     FIXME("\n");
570     return E_NOTIMPL;
571 }
572
573 HRESULT add_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
574 {
575     FIXME("\n");
576     return E_NOTIMPL;
577 }
578
579 HRESULT sub_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
580 {
581     FIXME("\n");
582     return E_NOTIMPL;
583 }
584
585 HRESULT mul_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
586 {
587     FIXME("\n");
588     return E_NOTIMPL;
589 }
590
591 HRESULT div_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
592 {
593     FIXME("\n");
594     return E_NOTIMPL;
595 }
596
597 HRESULT mod_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
598 {
599     FIXME("\n");
600     return E_NOTIMPL;
601 }
602
603 HRESULT delete_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
604 {
605     FIXME("\n");
606     return E_NOTIMPL;
607 }
608
609 HRESULT void_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
610 {
611     FIXME("\n");
612     return E_NOTIMPL;
613 }
614
615 HRESULT typeof_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
616 {
617     FIXME("\n");
618     return E_NOTIMPL;
619 }
620
621 HRESULT minus_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
622 {
623     FIXME("\n");
624     return E_NOTIMPL;
625 }
626
627 HRESULT plus_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
628 {
629     FIXME("\n");
630     return E_NOTIMPL;
631 }
632
633 HRESULT post_increment_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 post_decrement_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 pre_increment_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 pre_decrement_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 new_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 equal_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 equal2_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 not_equal_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
676 {
677
678     FIXME("\n");
679     return E_NOTIMPL;
680 }
681
682 HRESULT not_equal2_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 less_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 lesseq_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 greater_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 greatereq_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_negation_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 logical_negation_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 left_shift_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 right_shift_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 right2_shift_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 /* ECMA-262 3rd Edition    11.13.1 */
743 HRESULT assign_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
744 {
745     binary_expression_t *expr = (binary_expression_t*)_expr;
746     exprval_t exprval, exprvalr;
747     VARIANT rval;
748     HRESULT hres;
749
750     TRACE("\n");
751
752     hres = expr_eval(ctx, expr->expression1, EXPR_NEWREF, ei, &exprval);
753     if(FAILED(hres))
754         return hres;
755
756     hres = expr_eval(ctx, expr->expression2, 0, ei, &exprvalr);
757     if(SUCCEEDED(hres)) {
758         hres = exprval_to_value(ctx->parser->script, &exprvalr, ei, &rval);
759         exprval_release(&exprvalr);
760     }
761
762     if(SUCCEEDED(hres))
763         hres = put_value(ctx->parser->script, &exprval, &rval, ei);
764
765     exprval_release(&exprval);
766     if(FAILED(hres)) {
767         VariantClear(&rval);
768         return hres;
769     }
770
771     ret->type = EXPRVAL_VARIANT;
772     ret->u.var = rval;
773     return S_OK;
774 }
775
776 HRESULT assign_lshift_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
777 {
778     FIXME("\n");
779     return E_NOTIMPL;
780 }
781
782 HRESULT assign_rshift_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
783 {
784     FIXME("\n");
785     return E_NOTIMPL;
786 }
787
788 HRESULT assign_rrshift_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
789 {
790     FIXME("\n");
791     return E_NOTIMPL;
792 }
793
794 HRESULT assign_add_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
795 {
796     FIXME("\n");
797     return E_NOTIMPL;
798 }
799
800 HRESULT assign_sub_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
801 {
802     FIXME("\n");
803     return E_NOTIMPL;
804 }
805
806 HRESULT assign_mul_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
807 {
808     FIXME("\n");
809     return E_NOTIMPL;
810 }
811
812 HRESULT assign_div_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
813 {
814     FIXME("\n");
815     return E_NOTIMPL;
816 }
817
818 HRESULT assign_mod_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
819 {
820     FIXME("\n");
821     return E_NOTIMPL;
822 }
823
824 HRESULT assign_and_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
825 {
826     FIXME("\n");
827     return E_NOTIMPL;
828 }
829
830 HRESULT assign_or_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
831 {
832     FIXME("\n");
833     return E_NOTIMPL;
834 }
835
836 HRESULT assign_xor_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
837 {
838     FIXME("\n");
839     return E_NOTIMPL;
840 }