jscript: Added expression statement implementation.
[wine] / dlls / jscript / engine.c
1 /*
2  * Copyright 2008 Jacek Caban for CodeWeavers
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18
19 #include "jscript.h"
20 #include "engine.h"
21
22 #include "wine/debug.h"
23
24 WINE_DEFAULT_DEBUG_CHANNEL(jscript);
25
26 #define EXPR_NOVAL   0x0001
27 #define EXPR_NEWREF  0x0002
28 #define EXPR_STRREF  0x0004
29
30 static inline HRESULT stat_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
31 {
32     return stat->eval(ctx, stat, rt, ret);
33 }
34
35 static inline HRESULT expr_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
36 {
37     return _expr->eval(ctx, _expr, flags, ei, ret);
38 }
39
40 static void exprval_release(exprval_t *val)
41 {
42     switch(val->type) {
43     case EXPRVAL_VARIANT:
44         VariantClear(&val->u.var);
45         return;
46     case EXPRVAL_IDREF:
47         if(val->u.idref.disp)
48             IDispatch_Release(val->u.idref.disp);
49         return;
50     case EXPRVAL_NAMEREF:
51         if(val->u.nameref.disp)
52             IDispatch_Release(val->u.nameref.disp);
53         SysFreeString(val->u.nameref.name);
54     }
55 }
56
57 /* ECMA-262 3rd Edition    8.7.1 */
58 static HRESULT exprval_value(script_ctx_t *ctx, exprval_t *val, jsexcept_t *ei, VARIANT *ret)
59 {
60     V_VT(ret) = VT_EMPTY;
61
62     switch(val->type) {
63     case EXPRVAL_VARIANT:
64         return VariantCopy(ret, &val->u.var);
65     case EXPRVAL_IDREF:
66         if(!val->u.idref.disp) {
67             FIXME("throw ReferenceError\n");
68             return E_FAIL;
69         }
70
71         return disp_propget(val->u.idref.disp, val->u.idref.id, ctx->lcid, ret, ei, NULL/*FIXME*/);
72     default:
73         ERR("type %d\n", val->type);
74         return E_FAIL;
75     }
76 }
77
78 static HRESULT exprval_to_value(script_ctx_t *ctx, exprval_t *val, jsexcept_t *ei, VARIANT *ret)
79 {
80     if(val->type == EXPRVAL_VARIANT) {
81         *ret = val->u.var;
82         V_VT(&val->u.var) = VT_EMPTY;
83         return S_OK;
84     }
85
86     return exprval_value(ctx, val, ei, ret);
87 }
88
89 HRESULT create_exec_ctx(exec_ctx_t **ret)
90 {
91     exec_ctx_t *ctx;
92
93     ctx = heap_alloc_zero(sizeof(exec_ctx_t));
94     if(!ctx)
95         return E_OUTOFMEMORY;
96
97     *ret = ctx;
98     return S_OK;
99 }
100
101 void exec_release(exec_ctx_t *ctx)
102 {
103     if(--ctx->ref)
104         return;
105
106     heap_free(ctx);
107 }
108
109 HRESULT exec_source(exec_ctx_t *ctx, parser_ctx_t *parser, source_elements_t *source, jsexcept_t *ei, VARIANT *retv)
110 {
111     script_ctx_t *script = parser->script;
112     parser_ctx_t *prev_parser;
113     VARIANT val, tmp;
114     statement_t *stat;
115     exec_ctx_t *prev_ctx;
116     return_type_t rt;
117     HRESULT hres = S_OK;
118
119     prev_ctx = script->exec_ctx;
120     script->exec_ctx = ctx;
121
122     prev_parser = ctx->parser;
123     ctx->parser = parser;
124
125     V_VT(&val) = VT_EMPTY;
126     memset(&rt, 0, sizeof(rt));
127     rt.type = RT_NORMAL;
128
129     for(stat = source->statement; stat; stat = stat->next) {
130         hres = stat_eval(ctx, stat, &rt, &tmp);
131         if(FAILED(hres))
132             break;
133
134         VariantClear(&val);
135         val = tmp;
136         if(rt.type != RT_NORMAL)
137             break;
138     }
139
140     script->exec_ctx = prev_ctx;
141     ctx->parser = prev_parser;
142
143     if(rt.type != RT_NORMAL && rt.type != RT_RETURN) {
144         FIXME("wrong rt %d\n", rt.type);
145         hres = E_FAIL;
146     }
147
148     *ei = rt.ei;
149     if(FAILED(hres)) {
150         VariantClear(&val);
151         return hres;
152     }
153
154     if(retv)
155         *retv = val;
156     else
157         VariantClear(&val);
158     return S_OK;
159 }
160
161 HRESULT block_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
162 {
163     FIXME("\n");
164     return E_NOTIMPL;
165 }
166
167 HRESULT var_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
168 {
169     FIXME("\n");
170     return E_NOTIMPL;
171 }
172
173 /* ECMA-262 3rd Edition    12.3 */
174 HRESULT empty_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
175 {
176     TRACE("\n");
177
178     V_VT(ret) = VT_EMPTY;
179     return S_OK;
180 }
181
182 /* ECMA-262 3rd Edition    12.4 */
183 HRESULT expression_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
184 {
185     expression_statement_t *stat = (expression_statement_t*)_stat;
186     exprval_t exprval;
187     VARIANT val;
188     HRESULT hres;
189
190     TRACE("\n");
191
192     hres = expr_eval(ctx, stat->expr, EXPR_NOVAL, &rt->ei, &exprval);
193     if(FAILED(hres))
194         return hres;
195
196     hres = exprval_to_value(ctx->parser->script, &exprval, &rt->ei, &val);
197     exprval_release(&exprval);
198     if(FAILED(hres))
199         return hres;
200
201     *ret = val;
202     TRACE("= %s\n", debugstr_variant(ret));
203     return S_OK;
204 }
205
206 HRESULT if_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
207 {
208     FIXME("\n");
209     return E_NOTIMPL;
210 }
211
212 HRESULT dowhile_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
213 {
214     FIXME("\n");
215     return E_NOTIMPL;
216 }
217
218 HRESULT while_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
219 {
220     FIXME("\n");
221     return E_NOTIMPL;
222 }
223
224 HRESULT for_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
225 {
226     FIXME("\n");
227     return E_NOTIMPL;
228 }
229
230 HRESULT forin_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
231 {
232     FIXME("\n");
233     return E_NOTIMPL;
234 }
235
236 HRESULT continue_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
237 {
238     FIXME("\n");
239     return E_NOTIMPL;
240 }
241
242 HRESULT break_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
243 {
244     FIXME("\n");
245     return E_NOTIMPL;
246 }
247
248 HRESULT return_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
249 {
250     FIXME("\n");
251     return E_NOTIMPL;
252 }
253
254 HRESULT with_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
255 {
256     FIXME("\n");
257     return E_NOTIMPL;
258 }
259
260 HRESULT labelled_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
261 {
262     FIXME("\n");
263     return E_NOTIMPL;
264 }
265
266 HRESULT switch_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
267 {
268     FIXME("\n");
269     return E_NOTIMPL;
270 }
271
272 HRESULT throw_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
273 {
274     FIXME("\n");
275     return E_NOTIMPL;
276 }
277
278 HRESULT try_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
279 {
280     FIXME("\n");
281     return E_NOTIMPL;
282 }
283
284 HRESULT function_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
285 {
286     FIXME("\n");
287     return E_NOTIMPL;
288 }
289
290 HRESULT conditional_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
291 {
292     FIXME("\n");
293     return E_NOTIMPL;
294 }
295
296 HRESULT array_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
297 {
298     FIXME("\n");
299     return E_NOTIMPL;
300 }
301
302 HRESULT member_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
303 {
304     FIXME("\n");
305     return E_NOTIMPL;
306 }
307
308 HRESULT member_new_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
309 {
310     FIXME("\n");
311     return E_NOTIMPL;
312 }
313
314 HRESULT call_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
315 {
316     FIXME("\n");
317     return E_NOTIMPL;
318 }
319
320 HRESULT this_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
321 {
322     FIXME("\n");
323     return E_NOTIMPL;
324 }
325
326 HRESULT identifier_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
327 {
328     FIXME("\n");
329     return E_NOTIMPL;
330 }
331
332 HRESULT literal_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
333 {
334     FIXME("\n");
335     return E_NOTIMPL;
336 }
337
338 HRESULT array_literal_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
339 {
340     FIXME("\n");
341     return E_NOTIMPL;
342 }
343
344 HRESULT property_value_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
345 {
346     FIXME("\n");
347     return E_NOTIMPL;
348 }
349
350 HRESULT comma_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
351 {
352     FIXME("\n");
353     return E_NOTIMPL;
354 }
355
356 HRESULT logical_or_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
357 {
358     FIXME("\n");
359     return E_NOTIMPL;
360 }
361
362 HRESULT logical_and_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 binary_or_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 binary_xor_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 binary_and_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 instanceof_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 in_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 add_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 HRESULT sub_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
405 {
406     FIXME("\n");
407     return E_NOTIMPL;
408 }
409
410 HRESULT mul_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
411 {
412     FIXME("\n");
413     return E_NOTIMPL;
414 }
415
416 HRESULT div_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
417 {
418     FIXME("\n");
419     return E_NOTIMPL;
420 }
421
422 HRESULT mod_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
423 {
424     FIXME("\n");
425     return E_NOTIMPL;
426 }
427
428 HRESULT delete_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
429 {
430     FIXME("\n");
431     return E_NOTIMPL;
432 }
433
434 HRESULT void_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 typeof_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 minus_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 plus_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 post_increment_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 post_decrement_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 pre_increment_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 pre_decrement_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 new_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 equal_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 HRESULT equal2_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
495 {
496     FIXME("\n");
497     return E_NOTIMPL;
498 }
499
500 HRESULT not_equal_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
501 {
502
503     FIXME("\n");
504     return E_NOTIMPL;
505 }
506
507 HRESULT not_equal2_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 less_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 lesseq_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 greater_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 greatereq_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 binary_negation_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 logical_negation_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 left_shift_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 right_shift_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 right2_shift_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 assign_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 assign_lshift_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 assign_rshift_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 assign_rrshift_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 assign_add_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 assign_sub_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 assign_mul_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 assign_div_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 assign_mod_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 assign_and_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 assign_or_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 assign_xor_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 }