jscript: Added global object 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 HRESULT create_exec_ctx(exec_ctx_t **ret)
100 {
101     exec_ctx_t *ctx;
102
103     ctx = heap_alloc_zero(sizeof(exec_ctx_t));
104     if(!ctx)
105         return E_OUTOFMEMORY;
106
107     *ret = ctx;
108     return S_OK;
109 }
110
111 void exec_release(exec_ctx_t *ctx)
112 {
113     if(--ctx->ref)
114         return;
115
116     heap_free(ctx);
117 }
118
119 static HRESULT dispex_get_id(IDispatchEx *dispex, BSTR name, DWORD flags, DISPID *id)
120 {
121     *id = 0;
122
123     return IDispatchEx_GetDispID(dispex, name, flags|fdexNameCaseSensitive, id);
124 }
125
126 static HRESULT disp_get_id(IDispatch *disp, BSTR name, DWORD flags, DISPID *id)
127 {
128     IDispatchEx *dispex;
129     HRESULT hres;
130
131     hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
132     if(FAILED(hres)) {
133         TRACE("unsing IDispatch\n");
134
135         *id = 0;
136         return IDispatch_GetIDsOfNames(disp, &IID_NULL, &name, 1, 0, id);
137     }
138
139     hres = dispex_get_id(dispex, name, flags, id);
140     IDispatchEx_Release(dispex);
141     return hres;
142 }
143
144 HRESULT exec_source(exec_ctx_t *ctx, parser_ctx_t *parser, source_elements_t *source, jsexcept_t *ei, VARIANT *retv)
145 {
146     script_ctx_t *script = parser->script;
147     parser_ctx_t *prev_parser;
148     VARIANT val, tmp;
149     statement_t *stat;
150     exec_ctx_t *prev_ctx;
151     return_type_t rt;
152     HRESULT hres = S_OK;
153
154     prev_ctx = script->exec_ctx;
155     script->exec_ctx = ctx;
156
157     prev_parser = ctx->parser;
158     ctx->parser = parser;
159
160     V_VT(&val) = VT_EMPTY;
161     memset(&rt, 0, sizeof(rt));
162     rt.type = RT_NORMAL;
163
164     for(stat = source->statement; stat; stat = stat->next) {
165         hres = stat_eval(ctx, stat, &rt, &tmp);
166         if(FAILED(hres))
167             break;
168
169         VariantClear(&val);
170         val = tmp;
171         if(rt.type != RT_NORMAL)
172             break;
173     }
174
175     script->exec_ctx = prev_ctx;
176     ctx->parser = prev_parser;
177
178     if(rt.type != RT_NORMAL && rt.type != RT_RETURN) {
179         FIXME("wrong rt %d\n", rt.type);
180         hres = E_FAIL;
181     }
182
183     *ei = rt.ei;
184     if(FAILED(hres)) {
185         VariantClear(&val);
186         return hres;
187     }
188
189     if(retv)
190         *retv = val;
191     else
192         VariantClear(&val);
193     return S_OK;
194 }
195
196 /* ECMA-262 3rd Edition    10.1.4 */
197 static HRESULT identifier_eval(exec_ctx_t *ctx, BSTR identifier, DWORD flags, exprval_t *ret)
198 {
199     named_item_t *item;
200     DISPID id = 0;
201     HRESULT hres;
202
203     TRACE("%s\n", debugstr_w(identifier));
204
205     /* FIXME: scope chain */
206
207     hres = dispex_get_id(_IDispatchEx_(ctx->parser->script->global), identifier, 0, &id);
208     if(SUCCEEDED(hres)) {
209         exprval_set_idref(ret, (IDispatch*)_IDispatchEx_(ctx->parser->script->global), id);
210         return S_OK;
211     }
212
213     for(item = ctx->parser->script->named_items; item; item = item->next) {
214         hres = disp_get_id(item->disp, identifier, 0, &id);
215         if(SUCCEEDED(hres))
216             break;
217     }
218
219     if(item) {
220         exprval_set_idref(ret, (IDispatch*)item->disp, id);
221         return S_OK;
222     }
223
224     hres = dispex_get_id(_IDispatchEx_(ctx->parser->script->script_disp), identifier, 0, &id);
225     if(SUCCEEDED(hres)) {
226         exprval_set_idref(ret, (IDispatch*)_IDispatchEx_(ctx->parser->script->script_disp), id);
227         return S_OK;
228     }
229
230     if(flags & EXPR_NEWREF) {
231         FIXME("create ref\n");
232         return E_NOTIMPL;
233     }
234
235     WARN("Could not find identifier %s\n", debugstr_w(identifier));
236     return E_FAIL;
237 }
238
239 HRESULT block_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
240 {
241     FIXME("\n");
242     return E_NOTIMPL;
243 }
244
245 HRESULT var_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
246 {
247     FIXME("\n");
248     return E_NOTIMPL;
249 }
250
251 /* ECMA-262 3rd Edition    12.3 */
252 HRESULT empty_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
253 {
254     TRACE("\n");
255
256     V_VT(ret) = VT_EMPTY;
257     return S_OK;
258 }
259
260 /* ECMA-262 3rd Edition    12.4 */
261 HRESULT expression_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
262 {
263     expression_statement_t *stat = (expression_statement_t*)_stat;
264     exprval_t exprval;
265     VARIANT val;
266     HRESULT hres;
267
268     TRACE("\n");
269
270     hres = expr_eval(ctx, stat->expr, EXPR_NOVAL, &rt->ei, &exprval);
271     if(FAILED(hres))
272         return hres;
273
274     hres = exprval_to_value(ctx->parser->script, &exprval, &rt->ei, &val);
275     exprval_release(&exprval);
276     if(FAILED(hres))
277         return hres;
278
279     *ret = val;
280     TRACE("= %s\n", debugstr_variant(ret));
281     return S_OK;
282 }
283
284 HRESULT if_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
285 {
286     FIXME("\n");
287     return E_NOTIMPL;
288 }
289
290 HRESULT dowhile_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
291 {
292     FIXME("\n");
293     return E_NOTIMPL;
294 }
295
296 HRESULT while_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
297 {
298     FIXME("\n");
299     return E_NOTIMPL;
300 }
301
302 HRESULT for_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
303 {
304     FIXME("\n");
305     return E_NOTIMPL;
306 }
307
308 HRESULT forin_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
309 {
310     FIXME("\n");
311     return E_NOTIMPL;
312 }
313
314 HRESULT continue_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
315 {
316     FIXME("\n");
317     return E_NOTIMPL;
318 }
319
320 HRESULT break_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 return_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 HRESULT with_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
333 {
334     FIXME("\n");
335     return E_NOTIMPL;
336 }
337
338 HRESULT labelled_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 switch_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 HRESULT throw_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
351 {
352     FIXME("\n");
353     return E_NOTIMPL;
354 }
355
356 HRESULT try_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 function_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
363 {
364     FIXME("\n");
365     return E_NOTIMPL;
366 }
367
368 HRESULT conditional_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
369 {
370     FIXME("\n");
371     return E_NOTIMPL;
372 }
373
374 HRESULT array_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
375 {
376     FIXME("\n");
377     return E_NOTIMPL;
378 }
379
380 HRESULT member_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
381 {
382     FIXME("\n");
383     return E_NOTIMPL;
384 }
385
386 HRESULT member_new_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
387 {
388     FIXME("\n");
389     return E_NOTIMPL;
390 }
391
392 HRESULT call_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
393 {
394     FIXME("\n");
395     return E_NOTIMPL;
396 }
397
398 HRESULT this_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
399 {
400     FIXME("\n");
401     return E_NOTIMPL;
402 }
403
404 /* ECMA-262 3rd Edition    10.1.4 */
405 HRESULT identifier_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
406 {
407     identifier_expression_t *expr = (identifier_expression_t*)_expr;
408     BSTR identifier;
409     HRESULT hres;
410
411     TRACE("\n");
412
413     identifier = SysAllocString(expr->identifier);
414     if(!identifier)
415         return E_OUTOFMEMORY;
416
417     hres = identifier_eval(ctx, identifier, flags, ret);
418
419     SysFreeString(identifier);
420     return hres;
421 }
422
423 HRESULT literal_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
424 {
425     FIXME("\n");
426     return E_NOTIMPL;
427 }
428
429 HRESULT array_literal_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
430 {
431     FIXME("\n");
432     return E_NOTIMPL;
433 }
434
435 HRESULT property_value_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
436 {
437     FIXME("\n");
438     return E_NOTIMPL;
439 }
440
441 HRESULT comma_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
442 {
443     FIXME("\n");
444     return E_NOTIMPL;
445 }
446
447 HRESULT logical_or_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
448 {
449     FIXME("\n");
450     return E_NOTIMPL;
451 }
452
453 HRESULT logical_and_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
454 {
455     FIXME("\n");
456     return E_NOTIMPL;
457 }
458
459 HRESULT binary_or_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
460 {
461     FIXME("\n");
462     return E_NOTIMPL;
463 }
464
465 HRESULT binary_xor_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
466 {
467     FIXME("\n");
468     return E_NOTIMPL;
469 }
470
471 HRESULT binary_and_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
472 {
473     FIXME("\n");
474     return E_NOTIMPL;
475 }
476
477 HRESULT instanceof_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
478 {
479     FIXME("\n");
480     return E_NOTIMPL;
481 }
482
483 HRESULT in_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
484 {
485     FIXME("\n");
486     return E_NOTIMPL;
487 }
488
489 HRESULT add_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
490 {
491     FIXME("\n");
492     return E_NOTIMPL;
493 }
494
495 HRESULT sub_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
496 {
497     FIXME("\n");
498     return E_NOTIMPL;
499 }
500
501 HRESULT mul_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
502 {
503     FIXME("\n");
504     return E_NOTIMPL;
505 }
506
507 HRESULT div_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
508 {
509     FIXME("\n");
510     return E_NOTIMPL;
511 }
512
513 HRESULT mod_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 delete_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 void_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 typeof_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 minus_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 plus_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 post_increment_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 post_decrement_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 pre_increment_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 pre_decrement_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 new_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 equal_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 equal2_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 not_equal_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
592 {
593
594     FIXME("\n");
595     return E_NOTIMPL;
596 }
597
598 HRESULT not_equal2_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
599 {
600     FIXME("\n");
601     return E_NOTIMPL;
602 }
603
604 HRESULT less_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
605 {
606     FIXME("\n");
607     return E_NOTIMPL;
608 }
609
610 HRESULT lesseq_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
611 {
612     FIXME("\n");
613     return E_NOTIMPL;
614 }
615
616 HRESULT greater_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
617 {
618     FIXME("\n");
619     return E_NOTIMPL;
620 }
621
622 HRESULT greatereq_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
623 {
624     FIXME("\n");
625     return E_NOTIMPL;
626 }
627
628 HRESULT binary_negation_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
629 {
630     FIXME("\n");
631     return E_NOTIMPL;
632 }
633
634 HRESULT logical_negation_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
635 {
636     FIXME("\n");
637     return E_NOTIMPL;
638 }
639
640 HRESULT left_shift_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
641 {
642     FIXME("\n");
643     return E_NOTIMPL;
644 }
645
646 HRESULT right_shift_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
647 {
648     FIXME("\n");
649     return E_NOTIMPL;
650 }
651
652 HRESULT right2_shift_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
653 {
654     FIXME("\n");
655     return E_NOTIMPL;
656 }
657
658 HRESULT assign_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
659 {
660     FIXME("\n");
661     return E_NOTIMPL;
662 }
663
664 HRESULT assign_lshift_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
665 {
666     FIXME("\n");
667     return E_NOTIMPL;
668 }
669
670 HRESULT assign_rshift_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
671 {
672     FIXME("\n");
673     return E_NOTIMPL;
674 }
675
676 HRESULT assign_rrshift_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 assign_add_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 assign_sub_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 assign_mul_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 assign_div_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 assign_mod_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 assign_and_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 assign_or_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 assign_xor_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 }