jscript: Lookup global members after script_disp.
[wine/wine-gecko.git] / dlls / jscript / engine.c
blobdbb186fe582df73a870dca60cb89ac31e9689f12
1 /*
2 * Copyright 2008 Jacek Caban for CodeWeavers
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.
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.
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
19 #include "config.h"
20 #include "wine/port.h"
22 #include <math.h>
24 #include "jscript.h"
25 #include "engine.h"
27 #include "wine/debug.h"
29 WINE_DEFAULT_DEBUG_CHANNEL(jscript);
31 #define EXPR_NOVAL 0x0001
32 #define EXPR_NEWREF 0x0002
33 #define EXPR_STRREF 0x0004
35 static inline HRESULT stat_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
37 return stat->eval(ctx, stat, rt, ret);
40 static inline HRESULT expr_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
42 return _expr->eval(ctx, _expr, flags, ei, ret);
45 static void exprval_release(exprval_t *val)
47 switch(val->type) {
48 case EXPRVAL_VARIANT:
49 if(V_VT(&val->u.var) != VT_EMPTY)
50 VariantClear(&val->u.var);
51 return;
52 case EXPRVAL_IDREF:
53 if(val->u.idref.disp)
54 IDispatch_Release(val->u.idref.disp);
55 return;
56 case EXPRVAL_NAMEREF:
57 if(val->u.nameref.disp)
58 IDispatch_Release(val->u.nameref.disp);
59 SysFreeString(val->u.nameref.name);
63 /* ECMA-262 3rd Edition 8.7.1 */
64 static HRESULT exprval_value(script_ctx_t *ctx, exprval_t *val, jsexcept_t *ei, VARIANT *ret)
66 V_VT(ret) = VT_EMPTY;
68 switch(val->type) {
69 case EXPRVAL_VARIANT:
70 return VariantCopy(ret, &val->u.var);
71 case EXPRVAL_IDREF:
72 if(!val->u.idref.disp) {
73 FIXME("throw ReferenceError\n");
74 return E_FAIL;
77 return disp_propget(val->u.idref.disp, val->u.idref.id, ctx->lcid, ret, ei, NULL/*FIXME*/);
78 default:
79 ERR("type %d\n", val->type);
80 return E_FAIL;
84 static HRESULT exprval_to_value(script_ctx_t *ctx, exprval_t *val, jsexcept_t *ei, VARIANT *ret)
86 if(val->type == EXPRVAL_VARIANT) {
87 *ret = val->u.var;
88 V_VT(&val->u.var) = VT_EMPTY;
89 return S_OK;
92 return exprval_value(ctx, val, ei, ret);
95 static HRESULT exprval_to_boolean(script_ctx_t *ctx, exprval_t *exprval, jsexcept_t *ei, VARIANT_BOOL *b)
97 if(exprval->type != EXPRVAL_VARIANT) {
98 VARIANT val;
99 HRESULT hres;
101 hres = exprval_to_value(ctx, exprval, ei, &val);
102 if(FAILED(hres))
103 return hres;
105 hres = to_boolean(&val, b);
106 VariantClear(&val);
107 return hres;
110 return to_boolean(&exprval->u.var, b);
113 static void exprval_init(exprval_t *val)
115 val->type = EXPRVAL_VARIANT;
116 V_VT(&val->u.var) = VT_EMPTY;
119 static void exprval_set_idref(exprval_t *val, IDispatch *disp, DISPID id)
121 val->type = EXPRVAL_IDREF;
122 val->u.idref.disp = disp;
123 val->u.idref.id = id;
125 if(disp)
126 IDispatch_AddRef(disp);
129 HRESULT scope_push(scope_chain_t *scope, DispatchEx *obj, scope_chain_t **ret)
131 scope_chain_t *new_scope;
133 new_scope = heap_alloc(sizeof(scope_chain_t));
134 if(!new_scope)
135 return E_OUTOFMEMORY;
137 new_scope->ref = 1;
139 IDispatchEx_AddRef(_IDispatchEx_(obj));
140 new_scope->obj = obj;
142 if(scope) {
143 scope_addref(scope);
144 new_scope->next = scope;
145 }else {
146 new_scope->next = NULL;
149 *ret = new_scope;
150 return S_OK;
153 static void scope_pop(scope_chain_t **scope)
155 scope_chain_t *tmp;
157 tmp = *scope;
158 *scope = tmp->next;
159 scope_release(tmp);
162 void scope_release(scope_chain_t *scope)
164 if(--scope->ref)
165 return;
167 if(scope->next)
168 scope_release(scope->next);
170 IDispatchEx_Release(_IDispatchEx_(scope->obj));
171 heap_free(scope);
174 HRESULT create_exec_ctx(IDispatch *this_obj, DispatchEx *var_disp, scope_chain_t *scope, exec_ctx_t **ret)
176 exec_ctx_t *ctx;
178 ctx = heap_alloc_zero(sizeof(exec_ctx_t));
179 if(!ctx)
180 return E_OUTOFMEMORY;
182 ctx->ref = 1;
184 IDispatch_AddRef(this_obj);
185 ctx->this_obj = this_obj;
187 IDispatchEx_AddRef(_IDispatchEx_(var_disp));
188 ctx->var_disp = var_disp;
190 if(scope) {
191 scope_addref(scope);
192 ctx->scope_chain = scope;
195 *ret = ctx;
196 return S_OK;
199 void exec_release(exec_ctx_t *ctx)
201 if(--ctx->ref)
202 return;
204 if(ctx->scope_chain)
205 scope_release(ctx->scope_chain);
206 if(ctx->var_disp)
207 IDispatchEx_Release(_IDispatchEx_(ctx->var_disp));
208 if(ctx->this_obj)
209 IDispatch_Release(ctx->this_obj);
210 heap_free(ctx);
213 static HRESULT disp_get_id(IDispatch *disp, BSTR name, DWORD flags, DISPID *id)
215 IDispatchEx *dispex;
216 HRESULT hres;
218 hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
219 if(FAILED(hres)) {
220 TRACE("unsing IDispatch\n");
222 *id = 0;
223 return IDispatch_GetIDsOfNames(disp, &IID_NULL, &name, 1, 0, id);
226 *id = 0;
227 hres = IDispatchEx_GetDispID(dispex, name, flags|fdexNameCaseSensitive, id);
228 IDispatchEx_Release(dispex);
229 return hres;
232 /* ECMA-262 3rd Edition 8.7.2 */
233 static HRESULT put_value(script_ctx_t *ctx, exprval_t *ref, VARIANT *v, jsexcept_t *ei)
235 if(ref->type != EXPRVAL_IDREF)
236 return throw_reference_error(ctx, ei, IDS_ILLEGAL_ASSIGN, NULL);
238 return disp_propput(ref->u.idref.disp, ref->u.idref.id, ctx->lcid, v, ei, NULL/*FIXME*/);
241 static HRESULT disp_cmp(IDispatch *disp1, IDispatch *disp2, BOOL *ret)
243 IObjectIdentity *identity;
244 IUnknown *unk1, *unk2;
245 HRESULT hres;
247 if(disp1 == disp2) {
248 *ret = TRUE;
249 return S_OK;
252 hres = IDispatch_QueryInterface(disp1, &IID_IUnknown, (void**)&unk1);
253 if(FAILED(hres))
254 return hres;
256 hres = IDispatch_QueryInterface(disp2, &IID_IUnknown, (void**)&unk2);
257 if(FAILED(hres)) {
258 IUnknown_Release(unk1);
259 return hres;
262 if(unk1 == unk2) {
263 *ret = TRUE;
264 }else {
265 hres = IUnknown_QueryInterface(unk1, &IID_IObjectIdentity, (void**)&identity);
266 if(SUCCEEDED(hres)) {
267 hres = IObjectIdentity_IsEqualObject(identity, unk2);
268 IObjectIdentity_Release(identity);
269 *ret = hres == S_OK;
270 }else {
271 *ret = FALSE;
275 IUnknown_Release(unk1);
276 IUnknown_Release(unk2);
277 return S_OK;
280 /* ECMA-262 3rd Edition 11.9.6 */
281 static HRESULT equal2_values(VARIANT *lval, VARIANT *rval, BOOL *ret)
283 TRACE("\n");
285 if(V_VT(lval) != V_VT(rval)) {
286 if(is_num_vt(V_VT(lval)) && is_num_vt(V_VT(rval))) {
287 *ret = num_val(lval) == num_val(rval);
288 return S_OK;
291 *ret = FALSE;
292 return S_OK;
295 switch(V_VT(lval)) {
296 case VT_EMPTY:
297 case VT_NULL:
298 *ret = VARIANT_TRUE;
299 break;
300 case VT_I4:
301 *ret = V_I4(lval) == V_I4(rval);
302 break;
303 case VT_R8:
304 *ret = V_R8(lval) == V_R8(rval);
305 break;
306 case VT_BSTR:
307 if(!V_BSTR(lval))
308 *ret = SysStringLen(V_BSTR(rval))?FALSE:TRUE;
309 else if(!V_BSTR(rval))
310 *ret = SysStringLen(V_BSTR(lval))?FALSE:TRUE;
311 else
312 *ret = !strcmpW(V_BSTR(lval), V_BSTR(rval));
313 break;
314 case VT_DISPATCH:
315 return disp_cmp(V_DISPATCH(lval), V_DISPATCH(rval), ret);
316 case VT_BOOL:
317 *ret = !V_BOOL(lval) == !V_BOOL(rval);
318 break;
319 default:
320 FIXME("unimplemented vt %d\n", V_VT(lval));
321 return E_NOTIMPL;
324 return S_OK;
327 static HRESULT literal_to_var(literal_t *literal, VARIANT *v)
329 V_VT(v) = literal->vt;
331 switch(V_VT(v)) {
332 case VT_EMPTY:
333 case VT_NULL:
334 break;
335 case VT_I4:
336 V_I4(v) = literal->u.lval;
337 break;
338 case VT_R8:
339 V_R8(v) = literal->u.dval;
340 break;
341 case VT_BSTR:
342 V_BSTR(v) = SysAllocString(literal->u.wstr);
343 break;
344 case VT_BOOL:
345 V_BOOL(v) = literal->u.bval;
346 break;
347 case VT_DISPATCH:
348 IDispatch_AddRef(literal->u.disp);
349 V_DISPATCH(v) = literal->u.disp;
350 break;
351 default:
352 ERR("wrong type %d\n", V_VT(v));
353 return E_NOTIMPL;
356 return S_OK;
359 static BOOL lookup_global_members(script_ctx_t *ctx, BSTR identifier, exprval_t *ret)
361 named_item_t *item;
362 DISPID id;
363 HRESULT hres;
365 for(item = ctx->named_items; item; item = item->next) {
366 if(item->flags & SCRIPTITEM_GLOBALMEMBERS) {
367 hres = disp_get_id(item->disp, identifier, 0, &id);
368 if(SUCCEEDED(hres)) {
369 if(ret)
370 exprval_set_idref(ret, item->disp, id);
371 return TRUE;
376 return FALSE;
379 HRESULT exec_source(exec_ctx_t *ctx, parser_ctx_t *parser, source_elements_t *source, jsexcept_t *ei, VARIANT *retv)
381 script_ctx_t *script = parser->script;
382 function_declaration_t *func;
383 parser_ctx_t *prev_parser;
384 var_list_t *var;
385 VARIANT val, tmp;
386 statement_t *stat;
387 exec_ctx_t *prev_ctx;
388 return_type_t rt;
389 HRESULT hres = S_OK;
391 for(func = source->functions; func; func = func->next) {
392 DispatchEx *func_obj;
393 VARIANT var;
395 hres = create_source_function(parser, func->expr->parameter_list, func->expr->source_elements,
396 ctx->scope_chain, func->expr->src_str, func->expr->src_len, &func_obj);
397 if(FAILED(hres))
398 return hres;
400 V_VT(&var) = VT_DISPATCH;
401 V_DISPATCH(&var) = (IDispatch*)_IDispatchEx_(func_obj);
402 hres = jsdisp_propput_name(ctx->var_disp, func->expr->identifier, script->lcid, &var, ei, NULL);
403 jsdisp_release(func_obj);
404 if(FAILED(hres))
405 return hres;
408 for(var = source->variables; var; var = var->next) {
409 DISPID id = 0;
411 hres = jsdisp_get_id(ctx->var_disp, var->identifier, fdexNameEnsure, &id);
412 if(FAILED(hres))
413 return hres;
416 prev_ctx = script->exec_ctx;
417 script->exec_ctx = ctx;
419 prev_parser = ctx->parser;
420 ctx->parser = parser;
422 V_VT(&val) = VT_EMPTY;
423 memset(&rt, 0, sizeof(rt));
424 rt.type = RT_NORMAL;
426 for(stat = source->statement; stat; stat = stat->next) {
427 hres = stat_eval(ctx, stat, &rt, &tmp);
428 if(FAILED(hres))
429 break;
431 VariantClear(&val);
432 val = tmp;
433 if(rt.type != RT_NORMAL)
434 break;
437 script->exec_ctx = prev_ctx;
438 ctx->parser = prev_parser;
440 if(rt.type != RT_NORMAL && rt.type != RT_RETURN) {
441 FIXME("wrong rt %d\n", rt.type);
442 hres = E_FAIL;
445 *ei = rt.ei;
446 if(FAILED(hres)) {
447 VariantClear(&val);
448 return hres;
451 if(retv)
452 *retv = val;
453 else
454 VariantClear(&val);
455 return S_OK;
458 /* ECMA-262 3rd Edition 10.1.4 */
459 static HRESULT identifier_eval(exec_ctx_t *ctx, BSTR identifier, DWORD flags, jsexcept_t *ei, exprval_t *ret)
461 scope_chain_t *scope;
462 named_item_t *item;
463 DISPID id = 0;
464 HRESULT hres;
466 TRACE("%s\n", debugstr_w(identifier));
468 for(scope = ctx->scope_chain; scope; scope = scope->next) {
469 hres = jsdisp_get_id(scope->obj, identifier, 0, &id);
470 if(SUCCEEDED(hres))
471 break;
474 if(scope) {
475 exprval_set_idref(ret, (IDispatch*)_IDispatchEx_(scope->obj), id);
476 return S_OK;
479 hres = jsdisp_get_id(ctx->parser->script->global, identifier, 0, &id);
480 if(SUCCEEDED(hres)) {
481 exprval_set_idref(ret, (IDispatch*)_IDispatchEx_(ctx->parser->script->global), id);
482 return S_OK;
485 for(item = ctx->parser->script->named_items; item; item = item->next) {
486 if((item->flags & SCRIPTITEM_ISVISIBLE) && !strcmpW(item->name, identifier)) {
487 if(!item->disp) {
488 IUnknown *unk;
490 if(!ctx->parser->script->site)
491 break;
493 hres = IActiveScriptSite_GetItemInfo(ctx->parser->script->site, identifier,
494 SCRIPTINFO_IUNKNOWN, &unk, NULL);
495 if(FAILED(hres)) {
496 WARN("GetItemInfo failed: %08x\n", hres);
497 break;
500 hres = IUnknown_QueryInterface(unk, &IID_IDispatch, (void**)&item->disp);
501 IUnknown_Release(unk);
502 if(FAILED(hres)) {
503 WARN("object does not implement IDispatch\n");
504 break;
508 ret->type = EXPRVAL_VARIANT;
509 V_VT(&ret->u.var) = VT_DISPATCH;
510 V_DISPATCH(&ret->u.var) = item->disp;
511 IDispatch_AddRef(item->disp);
512 return S_OK;
516 hres = jsdisp_get_id(ctx->parser->script->script_disp, identifier, 0, &id);
517 if(SUCCEEDED(hres)) {
518 exprval_set_idref(ret, (IDispatch*)_IDispatchEx_(ctx->parser->script->script_disp), id);
519 return S_OK;
522 if(lookup_global_members(ctx->parser->script, identifier, ret))
523 return S_OK;
525 if(flags & EXPR_NEWREF) {
526 hres = jsdisp_get_id(ctx->var_disp, identifier, fdexNameEnsure, &id);
527 if(FAILED(hres))
528 return hres;
530 exprval_set_idref(ret, (IDispatch*)_IDispatchEx_(ctx->var_disp), id);
531 return S_OK;
534 return throw_type_error(ctx->var_disp->ctx, ei, IDS_UNDEFINED, identifier);
537 /* ECMA-262 3rd Edition 12.1 */
538 HRESULT block_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
540 block_statement_t *stat = (block_statement_t*)_stat;
541 VARIANT val, tmp;
542 statement_t *iter;
543 HRESULT hres = S_OK;
545 TRACE("\n");
547 V_VT(&val) = VT_EMPTY;
548 for(iter = stat->stat_list; iter; iter = iter->next) {
549 hres = stat_eval(ctx, iter, rt, &tmp);
550 if(FAILED(hres))
551 break;
553 VariantClear(&val);
554 val = tmp;
555 if(rt->type != RT_NORMAL)
556 break;
559 if(FAILED(hres)) {
560 VariantClear(&val);
561 return hres;
564 *ret = val;
565 return S_OK;
568 /* ECMA-262 3rd Edition 12.2 */
569 static HRESULT variable_list_eval(exec_ctx_t *ctx, variable_declaration_t *var_list, jsexcept_t *ei)
571 variable_declaration_t *iter;
572 HRESULT hres = S_OK;
574 for(iter = var_list; iter; iter = iter->next) {
575 exprval_t exprval;
576 VARIANT val;
578 if(!iter->expr)
579 continue;
581 hres = expr_eval(ctx, iter->expr, 0, ei, &exprval);
582 if(FAILED(hres))
583 break;
585 hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
586 exprval_release(&exprval);
587 if(FAILED(hres))
588 break;
590 hres = jsdisp_propput_name(ctx->var_disp, iter->identifier, ctx->parser->script->lcid, &val, ei, NULL/*FIXME*/);
591 VariantClear(&val);
592 if(FAILED(hres))
593 break;
596 return hres;
599 /* ECMA-262 3rd Edition 12.2 */
600 HRESULT var_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
602 var_statement_t *stat = (var_statement_t*)_stat;
603 HRESULT hres;
605 TRACE("\n");
607 hres = variable_list_eval(ctx, stat->variable_list, &rt->ei);
608 if(FAILED(hres))
609 return hres;
611 V_VT(ret) = VT_EMPTY;
612 return S_OK;
615 /* ECMA-262 3rd Edition 12.3 */
616 HRESULT empty_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
618 TRACE("\n");
620 V_VT(ret) = VT_EMPTY;
621 return S_OK;
624 /* ECMA-262 3rd Edition 12.4 */
625 HRESULT expression_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
627 expression_statement_t *stat = (expression_statement_t*)_stat;
628 exprval_t exprval;
629 VARIANT val;
630 HRESULT hres;
632 TRACE("\n");
634 hres = expr_eval(ctx, stat->expr, EXPR_NOVAL, &rt->ei, &exprval);
635 if(FAILED(hres))
636 return hres;
638 hres = exprval_to_value(ctx->parser->script, &exprval, &rt->ei, &val);
639 exprval_release(&exprval);
640 if(FAILED(hres))
641 return hres;
643 *ret = val;
644 TRACE("= %s\n", debugstr_variant(ret));
645 return S_OK;
648 /* ECMA-262 3rd Edition 12.5 */
649 HRESULT if_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
651 if_statement_t *stat = (if_statement_t*)_stat;
652 exprval_t exprval;
653 VARIANT_BOOL b;
654 HRESULT hres;
656 TRACE("\n");
658 hres = expr_eval(ctx, stat->expr, 0, &rt->ei, &exprval);
659 if(FAILED(hres))
660 return hres;
662 hres = exprval_to_boolean(ctx->parser->script, &exprval, &rt->ei, &b);
663 exprval_release(&exprval);
664 if(FAILED(hres))
665 return hres;
667 if(b)
668 hres = stat_eval(ctx, stat->if_stat, rt, ret);
669 else if(stat->else_stat)
670 hres = stat_eval(ctx, stat->else_stat, rt, ret);
671 else
672 V_VT(ret) = VT_EMPTY;
674 return hres;
677 /* ECMA-262 3rd Edition 12.6.2 */
678 HRESULT while_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
680 while_statement_t *stat = (while_statement_t*)_stat;
681 exprval_t exprval;
682 VARIANT val, tmp;
683 VARIANT_BOOL b;
684 BOOL test_expr;
685 HRESULT hres;
687 TRACE("\n");
689 V_VT(&val) = VT_EMPTY;
690 test_expr = !stat->do_while;
692 while(1) {
693 if(test_expr) {
694 hres = expr_eval(ctx, stat->expr, 0, &rt->ei, &exprval);
695 if(FAILED(hres))
696 break;
698 hres = exprval_to_boolean(ctx->parser->script, &exprval, &rt->ei, &b);
699 exprval_release(&exprval);
700 if(FAILED(hres) || !b)
701 break;
702 }else {
703 test_expr = TRUE;
706 hres = stat_eval(ctx, stat->statement, rt, &tmp);
707 if(FAILED(hres))
708 break;
710 VariantClear(&val);
711 val = tmp;
713 if(rt->type == RT_CONTINUE)
714 rt->type = RT_NORMAL;
715 if(rt->type != RT_NORMAL)
716 break;
719 if(FAILED(hres)) {
720 VariantClear(&val);
721 return hres;
724 if(rt->type == RT_BREAK)
725 rt->type = RT_NORMAL;
727 *ret = val;
728 return S_OK;
731 /* ECMA-262 3rd Edition 12.6.3 */
732 HRESULT for_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
734 for_statement_t *stat = (for_statement_t*)_stat;
735 VARIANT val, tmp, retv;
736 exprval_t exprval;
737 VARIANT_BOOL b;
738 HRESULT hres;
740 TRACE("\n");
742 if(stat->variable_list) {
743 hres = variable_list_eval(ctx, stat->variable_list, &rt->ei);
744 if(FAILED(hres))
745 return hres;
746 }else if(stat->begin_expr) {
747 hres = expr_eval(ctx, stat->begin_expr, EXPR_NEWREF, &rt->ei, &exprval);
748 if(FAILED(hres))
749 return hres;
751 hres = exprval_to_value(ctx->parser->script, &exprval, &rt->ei, &val);
752 exprval_release(&exprval);
753 if(FAILED(hres))
754 return hres;
756 VariantClear(&val);
759 V_VT(&retv) = VT_EMPTY;
761 while(1) {
762 if(stat->expr) {
763 hres = expr_eval(ctx, stat->expr, 0, &rt->ei, &exprval);
764 if(FAILED(hres))
765 break;
767 hres = exprval_to_boolean(ctx->parser->script, &exprval, &rt->ei, &b);
768 exprval_release(&exprval);
769 if(FAILED(hres) || !b)
770 break;
773 hres = stat_eval(ctx, stat->statement, rt, &tmp);
774 if(FAILED(hres))
775 break;
777 VariantClear(&retv);
778 retv = tmp;
780 if(rt->type == RT_CONTINUE)
781 rt->type = RT_NORMAL;
782 else if(rt->type != RT_NORMAL)
783 break;
785 if(stat->end_expr) {
786 hres = expr_eval(ctx, stat->end_expr, 0, &rt->ei, &exprval);
787 if(FAILED(hres))
788 break;
790 hres = exprval_to_value(ctx->parser->script, &exprval, &rt->ei, &val);
791 exprval_release(&exprval);
792 if(FAILED(hres))
793 break;
795 VariantClear(&val);
799 if(FAILED(hres)) {
800 VariantClear(&retv);
801 return hres;
804 if(rt->type == RT_BREAK)
805 rt->type = RT_NORMAL;
807 *ret = retv;
808 return S_OK;
811 /* ECMA-262 3rd Edition 12.6.4 */
812 HRESULT forin_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
814 forin_statement_t *stat = (forin_statement_t*)_stat;
815 VARIANT val, name, retv, tmp;
816 DISPID id = DISPID_STARTENUM;
817 BSTR str, identifier = NULL;
818 IDispatchEx *in_obj;
819 exprval_t exprval;
820 HRESULT hres;
822 TRACE("\n");
824 if(stat->variable) {
825 hres = variable_list_eval(ctx, stat->variable, &rt->ei);
826 if(FAILED(hres))
827 return hres;
830 hres = expr_eval(ctx, stat->in_expr, EXPR_NEWREF, &rt->ei, &exprval);
831 if(FAILED(hres))
832 return hres;
834 hres = exprval_to_value(ctx->parser->script, &exprval, &rt->ei, &val);
835 exprval_release(&exprval);
836 if(FAILED(hres))
837 return hres;
839 if(V_VT(&val) != VT_DISPATCH) {
840 TRACE("in vt %d\n", V_VT(&val));
841 VariantClear(&val);
842 V_VT(ret) = VT_EMPTY;
843 return S_OK;
846 hres = IDispatch_QueryInterface(V_DISPATCH(&val), &IID_IDispatchEx, (void**)&in_obj);
847 IDispatch_Release(V_DISPATCH(&val));
848 if(FAILED(hres)) {
849 FIXME("Object doesn't support IDispatchEx\n");
850 return E_NOTIMPL;
853 V_VT(&retv) = VT_EMPTY;
855 if(stat->variable)
856 identifier = SysAllocString(stat->variable->identifier);
858 while(1) {
859 hres = IDispatchEx_GetNextDispID(in_obj, fdexEnumDefault, id, &id);
860 if(FAILED(hres) || hres == S_FALSE)
861 break;
863 hres = IDispatchEx_GetMemberName(in_obj, id, &str);
864 if(FAILED(hres))
865 break;
867 TRACE("iter %s\n", debugstr_w(str));
869 if(stat->variable)
870 hres = identifier_eval(ctx, identifier, 0, NULL, &exprval);
871 else
872 hres = expr_eval(ctx, stat->expr, EXPR_NEWREF, &rt->ei, &exprval);
873 if(SUCCEEDED(hres)) {
874 V_VT(&name) = VT_BSTR;
875 V_BSTR(&name) = str;
876 hres = put_value(ctx->parser->script, &exprval, &name, &rt->ei);
877 exprval_release(&exprval);
879 SysFreeString(str);
880 if(FAILED(hres))
881 break;
883 hres = stat_eval(ctx, stat->statement, rt, &tmp);
884 if(FAILED(hres))
885 break;
887 VariantClear(&retv);
888 retv = tmp;
890 if(rt->type == RT_CONTINUE)
891 rt->type = RT_NORMAL;
892 else if(rt->type != RT_NORMAL)
893 break;
896 SysFreeString(identifier);
897 IDispatchEx_Release(in_obj);
898 if(FAILED(hres)) {
899 VariantClear(&retv);
900 return hres;
903 if(rt->type == RT_BREAK)
904 rt->type = RT_NORMAL;
906 *ret = retv;
907 return S_OK;
910 /* ECMA-262 3rd Edition 12.7 */
911 HRESULT continue_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
913 branch_statement_t *stat = (branch_statement_t*)_stat;
915 TRACE("\n");
917 if(stat->identifier) {
918 FIXME("indentifier not implemented\n");
919 return E_NOTIMPL;
922 rt->type = RT_CONTINUE;
923 V_VT(ret) = VT_EMPTY;
924 return S_OK;
927 /* ECMA-262 3rd Edition 12.8 */
928 HRESULT break_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
930 branch_statement_t *stat = (branch_statement_t*)_stat;
932 TRACE("\n");
934 if(stat->identifier) {
935 FIXME("indentifier not implemented\n");
936 return E_NOTIMPL;
939 rt->type = RT_BREAK;
940 V_VT(ret) = VT_EMPTY;
941 return S_OK;
944 /* ECMA-262 3rd Edition 12.9 */
945 HRESULT return_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
947 expression_statement_t *stat = (expression_statement_t*)_stat;
948 HRESULT hres;
950 TRACE("\n");
952 if(stat->expr) {
953 exprval_t exprval;
955 hres = expr_eval(ctx, stat->expr, 0, &rt->ei, &exprval);
956 if(FAILED(hres))
957 return hres;
959 hres = exprval_to_value(ctx->parser->script, &exprval, &rt->ei, ret);
960 exprval_release(&exprval);
961 if(FAILED(hres))
962 return hres;
963 }else {
964 V_VT(ret) = VT_EMPTY;
967 TRACE("= %s\n", debugstr_variant(ret));
968 rt->type = RT_RETURN;
969 return S_OK;
972 /* ECMA-262 3rd Edition 12.10 */
973 HRESULT with_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
975 with_statement_t *stat = (with_statement_t*)_stat;
976 exprval_t exprval;
977 IDispatch *disp;
978 DispatchEx *obj;
979 VARIANT val;
980 HRESULT hres;
982 TRACE("\n");
984 hres = expr_eval(ctx, stat->expr, 0, &rt->ei, &exprval);
985 if(FAILED(hres))
986 return hres;
988 hres = exprval_to_value(ctx->parser->script, &exprval, &rt->ei, &val);
989 exprval_release(&exprval);
990 if(FAILED(hres))
991 return hres;
993 hres = to_object(ctx, &val, &disp);
994 VariantClear(&val);
995 if(FAILED(hres))
996 return hres;
998 obj = iface_to_jsdisp((IUnknown*)disp);
999 IDispatch_Release(disp);
1000 if(!obj) {
1001 FIXME("disp id not jsdisp\n");
1002 return E_NOTIMPL;
1005 hres = scope_push(ctx->scope_chain, obj, &ctx->scope_chain);
1006 jsdisp_release(obj);
1007 if(FAILED(hres))
1008 return hres;
1010 hres = stat_eval(ctx, stat->statement, rt, ret);
1012 scope_pop(&ctx->scope_chain);
1013 return hres;
1016 /* ECMA-262 3rd Edition 12.12 */
1017 HRESULT labelled_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
1019 FIXME("\n");
1020 return E_NOTIMPL;
1023 /* ECMA-262 3rd Edition 12.13 */
1024 HRESULT switch_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
1026 switch_statement_t *stat = (switch_statement_t*)_stat;
1027 case_clausule_t *iter, *default_clausule = NULL;
1028 statement_t *stat_iter;
1029 VARIANT val, cval;
1030 exprval_t exprval;
1031 BOOL b;
1032 HRESULT hres;
1034 TRACE("\n");
1036 hres = expr_eval(ctx, stat->expr, 0, &rt->ei, &exprval);
1037 if(FAILED(hres))
1038 return hres;
1040 hres = exprval_to_value(ctx->parser->script, &exprval, &rt->ei, &val);
1041 exprval_release(&exprval);
1042 if(FAILED(hres))
1043 return hres;
1045 for(iter = stat->case_list; iter; iter = iter->next) {
1046 if(!iter->expr) {
1047 default_clausule = iter;
1048 continue;
1051 hres = expr_eval(ctx, iter->expr, 0, &rt->ei, &exprval);
1052 if(FAILED(hres))
1053 break;
1055 hres = exprval_to_value(ctx->parser->script, &exprval, &rt->ei, &cval);
1056 exprval_release(&exprval);
1057 if(FAILED(hres))
1058 break;
1060 hres = equal2_values(&val, &cval, &b);
1061 VariantClear(&cval);
1062 if(FAILED(hres) || b)
1063 break;
1066 VariantClear(&val);
1067 if(FAILED(hres))
1068 return hres;
1070 if(!iter)
1071 iter = default_clausule;
1073 V_VT(&val) = VT_EMPTY;
1074 if(iter) {
1075 VARIANT tmp;
1077 for(stat_iter = iter->stat; stat_iter; stat_iter = stat_iter->next) {
1078 hres = stat_eval(ctx, stat_iter, rt, &tmp);
1079 if(FAILED(hres))
1080 break;
1082 VariantClear(&val);
1083 val = tmp;
1085 if(rt->type != RT_NORMAL)
1086 break;
1090 if(FAILED(hres)) {
1091 VariantClear(&val);
1092 return hres;
1095 if(rt->type == RT_BREAK)
1096 rt->type = RT_NORMAL;
1098 *ret = val;
1099 return S_OK;
1102 /* ECMA-262 3rd Edition 12.13 */
1103 HRESULT throw_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
1105 expression_statement_t *stat = (expression_statement_t*)_stat;
1106 exprval_t exprval;
1107 VARIANT val;
1108 HRESULT hres;
1110 TRACE("\n");
1112 hres = expr_eval(ctx, stat->expr, 0, &rt->ei, &exprval);
1113 if(FAILED(hres))
1114 return hres;
1116 hres = exprval_to_value(ctx->parser->script, &exprval, &rt->ei, &val);
1117 exprval_release(&exprval);
1118 if(FAILED(hres))
1119 return hres;
1121 rt->ei.var = val;
1122 return DISP_E_EXCEPTION;
1125 /* ECMA-262 3rd Edition 12.14 */
1126 static HRESULT catch_eval(exec_ctx_t *ctx, catch_block_t *block, return_type_t *rt, VARIANT *ret)
1128 DispatchEx *var_disp;
1129 VARIANT ex, val;
1130 HRESULT hres;
1132 ex = rt->ei.var;
1133 memset(&rt->ei, 0, sizeof(jsexcept_t));
1135 hres = create_dispex(ctx->parser->script, NULL, NULL, &var_disp);
1136 if(SUCCEEDED(hres)) {
1137 hres = jsdisp_propput_name(var_disp, block->identifier, ctx->parser->script->lcid,
1138 &ex, &rt->ei, NULL/*FIXME*/);
1139 if(SUCCEEDED(hres)) {
1140 hres = scope_push(ctx->scope_chain, var_disp, &ctx->scope_chain);
1141 if(SUCCEEDED(hres)) {
1142 hres = stat_eval(ctx, block->statement, rt, &val);
1143 scope_pop(&ctx->scope_chain);
1147 jsdisp_release(var_disp);
1150 VariantClear(&ex);
1151 if(FAILED(hres))
1152 return hres;
1154 *ret = val;
1155 return S_OK;
1158 /* ECMA-262 3rd Edition 12.14 */
1159 HRESULT try_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
1161 try_statement_t *stat = (try_statement_t*)_stat;
1162 VARIANT val;
1163 HRESULT hres;
1165 TRACE("\n");
1167 hres = stat_eval(ctx, stat->try_statement, rt, &val);
1168 if(FAILED(hres)) {
1169 TRACE("EXCEPTION\n");
1170 if(!stat->catch_block)
1171 return hres;
1173 hres = catch_eval(ctx, stat->catch_block, rt, &val);
1174 if(FAILED(hres))
1175 return hres;
1178 if(stat->finally_statement) {
1179 VariantClear(&val);
1180 hres = stat_eval(ctx, stat->finally_statement, rt, &val);
1181 if(FAILED(hres))
1182 return hres;
1185 *ret = val;
1186 return S_OK;
1189 static HRESULT return_bool(exprval_t *ret, DWORD b)
1191 ret->type = EXPRVAL_VARIANT;
1192 V_VT(&ret->u.var) = VT_BOOL;
1193 V_BOOL(&ret->u.var) = b ? VARIANT_TRUE : VARIANT_FALSE;
1195 return S_OK;
1198 static HRESULT get_binary_expr_values(exec_ctx_t *ctx, binary_expression_t *expr, jsexcept_t *ei, VARIANT *lval, VARIANT *rval)
1200 exprval_t exprval;
1201 HRESULT hres;
1203 hres = expr_eval(ctx, expr->expression1, 0, ei, &exprval);
1204 if(FAILED(hres))
1205 return hres;
1207 hres = exprval_to_value(ctx->parser->script, &exprval, ei, lval);
1208 exprval_release(&exprval);
1209 if(FAILED(hres))
1210 return hres;
1212 hres = expr_eval(ctx, expr->expression2, 0, ei, &exprval);
1213 if(SUCCEEDED(hres)) {
1214 hres = exprval_to_value(ctx->parser->script, &exprval, ei, rval);
1215 exprval_release(&exprval);
1218 if(FAILED(hres)) {
1219 VariantClear(lval);
1220 return hres;
1223 return S_OK;
1226 typedef HRESULT (*oper_t)(exec_ctx_t*,VARIANT*,VARIANT*,jsexcept_t*,VARIANT*);
1228 static HRESULT binary_expr_eval(exec_ctx_t *ctx, binary_expression_t *expr, oper_t oper, jsexcept_t *ei,
1229 exprval_t *ret)
1231 VARIANT lval, rval, retv;
1232 HRESULT hres;
1234 hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval);
1235 if(FAILED(hres))
1236 return hres;
1238 hres = oper(ctx, &lval, &rval, ei, &retv);
1239 VariantClear(&lval);
1240 VariantClear(&rval);
1241 if(FAILED(hres))
1242 return hres;
1244 ret->type = EXPRVAL_VARIANT;
1245 ret->u.var = retv;
1246 return S_OK;
1249 /* ECMA-262 3rd Edition 11.13.2 */
1250 static HRESULT assign_oper_eval(exec_ctx_t *ctx, expression_t *lexpr, expression_t *rexpr, oper_t oper,
1251 jsexcept_t *ei, exprval_t *ret)
1253 VARIANT retv, lval, rval;
1254 exprval_t exprval, exprvalr;
1255 HRESULT hres;
1257 hres = expr_eval(ctx, lexpr, EXPR_NEWREF, ei, &exprval);
1258 if(FAILED(hres))
1259 return hres;
1261 hres = exprval_value(ctx->parser->script, &exprval, ei, &lval);
1262 if(SUCCEEDED(hres)) {
1263 hres = expr_eval(ctx, rexpr, 0, ei, &exprvalr);
1264 if(SUCCEEDED(hres)) {
1265 hres = exprval_value(ctx->parser->script, &exprvalr, ei, &rval);
1266 exprval_release(&exprvalr);
1268 if(SUCCEEDED(hres)) {
1269 hres = oper(ctx, &lval, &rval, ei, &retv);
1270 VariantClear(&rval);
1272 VariantClear(&lval);
1275 if(SUCCEEDED(hres)) {
1276 hres = put_value(ctx->parser->script, &exprval, &retv, ei);
1277 if(FAILED(hres))
1278 VariantClear(&retv);
1280 exprval_release(&exprval);
1282 if(FAILED(hres))
1283 return hres;
1285 ret->type = EXPRVAL_VARIANT;
1286 ret->u.var = retv;
1287 return S_OK;
1290 /* ECMA-262 3rd Edition 13 */
1291 HRESULT function_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1293 function_expression_t *expr = (function_expression_t*)_expr;
1294 VARIANT var;
1295 HRESULT hres;
1297 TRACE("\n");
1299 if(expr->identifier) {
1300 hres = jsdisp_propget_name(ctx->var_disp, expr->identifier, ctx->parser->script->lcid, &var, ei, NULL/*FIXME*/);
1301 if(FAILED(hres))
1302 return hres;
1303 }else {
1304 DispatchEx *dispex;
1306 hres = create_source_function(ctx->parser, expr->parameter_list, expr->source_elements, ctx->scope_chain,
1307 expr->src_str, expr->src_len, &dispex);
1308 if(FAILED(hres))
1309 return hres;
1311 V_VT(&var) = VT_DISPATCH;
1312 V_DISPATCH(&var) = (IDispatch*)_IDispatchEx_(dispex);
1315 ret->type = EXPRVAL_VARIANT;
1316 ret->u.var = var;
1317 return S_OK;
1320 /* ECMA-262 3rd Edition 11.12 */
1321 HRESULT conditional_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1323 conditional_expression_t *expr = (conditional_expression_t*)_expr;
1324 exprval_t exprval;
1325 VARIANT_BOOL b;
1326 HRESULT hres;
1328 TRACE("\n");
1330 hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
1331 if(FAILED(hres))
1332 return hres;
1334 hres = exprval_to_boolean(ctx->parser->script, &exprval, ei, &b);
1335 exprval_release(&exprval);
1336 if(FAILED(hres))
1337 return hres;
1339 return expr_eval(ctx, b ? expr->true_expression : expr->false_expression, flags, ei, ret);
1342 /* ECMA-262 3rd Edition 11.2.1 */
1343 HRESULT array_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1345 array_expression_t *expr = (array_expression_t*)_expr;
1346 exprval_t exprval;
1347 VARIANT member, val;
1348 DISPID id;
1349 BSTR str;
1350 IDispatch *obj = NULL;
1351 HRESULT hres;
1353 TRACE("\n");
1355 hres = expr_eval(ctx, expr->member_expr, EXPR_NEWREF, ei, &exprval);
1356 if(FAILED(hres))
1357 return hres;
1359 hres = exprval_to_value(ctx->parser->script, &exprval, ei, &member);
1360 exprval_release(&exprval);
1361 if(FAILED(hres))
1362 return hres;
1364 hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval);
1365 if(SUCCEEDED(hres)) {
1366 hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
1367 exprval_release(&exprval);
1370 if(SUCCEEDED(hres))
1371 hres = to_object(ctx, &member, &obj);
1372 VariantClear(&member);
1373 if(SUCCEEDED(hres)) {
1374 hres = to_string(ctx->parser->script, &val, ei, &str);
1375 if(SUCCEEDED(hres)) {
1376 if(flags & EXPR_STRREF) {
1377 ret->type = EXPRVAL_NAMEREF;
1378 ret->u.nameref.disp = obj;
1379 ret->u.nameref.name = str;
1380 return S_OK;
1383 hres = disp_get_id(obj, str, flags & EXPR_NEWREF ? fdexNameEnsure : 0, &id);
1386 if(SUCCEEDED(hres)) {
1387 exprval_set_idref(ret, obj, id);
1388 }else if(!(flags & EXPR_NEWREF) && hres == DISP_E_UNKNOWNNAME) {
1389 exprval_init(ret);
1390 hres = S_OK;
1393 IDispatch_Release(obj);
1396 return hres;
1399 /* ECMA-262 3rd Edition 11.2.1 */
1400 HRESULT member_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1402 member_expression_t *expr = (member_expression_t*)_expr;
1403 IDispatch *obj = NULL;
1404 exprval_t exprval;
1405 VARIANT member;
1406 DISPID id;
1407 BSTR str;
1408 HRESULT hres;
1410 TRACE("\n");
1412 hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
1413 if(FAILED(hres))
1414 return hres;
1416 hres = exprval_to_value(ctx->parser->script, &exprval, ei, &member);
1417 exprval_release(&exprval);
1418 if(FAILED(hres))
1419 return hres;
1421 hres = to_object(ctx, &member, &obj);
1422 VariantClear(&member);
1423 if(FAILED(hres))
1424 return hres;
1426 str = SysAllocString(expr->identifier);
1427 if(flags & EXPR_STRREF) {
1428 ret->type = EXPRVAL_NAMEREF;
1429 ret->u.nameref.disp = obj;
1430 ret->u.nameref.name = str;
1431 return S_OK;
1434 hres = disp_get_id(obj, str, flags & EXPR_NEWREF ? fdexNameEnsure : 0, &id);
1435 SysFreeString(str);
1436 if(SUCCEEDED(hres)) {
1437 exprval_set_idref(ret, obj, id);
1438 }else if(!(flags & EXPR_NEWREF) && hres == DISP_E_UNKNOWNNAME) {
1439 exprval_init(ret);
1440 hres = S_OK;
1443 IDispatch_Release(obj);
1444 return hres;
1447 static void free_dp(DISPPARAMS *dp)
1449 DWORD i;
1451 for(i=0; i < dp->cArgs; i++)
1452 VariantClear(dp->rgvarg+i);
1453 heap_free(dp->rgvarg);
1456 static HRESULT args_to_param(exec_ctx_t *ctx, argument_t *args, jsexcept_t *ei, DISPPARAMS *dp)
1458 VARIANTARG *vargs;
1459 exprval_t exprval;
1460 argument_t *iter;
1461 DWORD cnt = 0, i;
1462 HRESULT hres = S_OK;
1464 memset(dp, 0, sizeof(*dp));
1465 if(!args)
1466 return S_OK;
1468 for(iter = args; iter; iter = iter->next)
1469 cnt++;
1471 vargs = heap_alloc_zero(cnt * sizeof(*vargs));
1472 if(!vargs)
1473 return E_OUTOFMEMORY;
1475 for(i = cnt, iter = args; iter; iter = iter->next) {
1476 hres = expr_eval(ctx, iter->expr, 0, ei, &exprval);
1477 if(FAILED(hres))
1478 break;
1480 hres = exprval_to_value(ctx->parser->script, &exprval, ei, vargs + (--i));
1481 exprval_release(&exprval);
1482 if(FAILED(hres))
1483 break;
1486 if(FAILED(hres)) {
1487 free_dp(dp);
1488 return hres;
1491 dp->rgvarg = vargs;
1492 dp->cArgs = cnt;
1493 return S_OK;
1496 /* ECMA-262 3rd Edition 11.2.2 */
1497 HRESULT new_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1499 call_expression_t *expr = (call_expression_t*)_expr;
1500 exprval_t exprval;
1501 VARIANT constr, var;
1502 DISPPARAMS dp;
1503 HRESULT hres;
1505 TRACE("\n");
1507 hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
1508 if(FAILED(hres))
1509 return hres;
1511 hres = args_to_param(ctx, expr->argument_list, ei, &dp);
1512 if(SUCCEEDED(hres))
1513 hres = exprval_to_value(ctx->parser->script, &exprval, ei, &constr);
1514 exprval_release(&exprval);
1515 if(FAILED(hres))
1516 return hres;
1518 if(V_VT(&constr) != VT_DISPATCH) {
1519 FIXME("throw TypeError\n");
1520 VariantClear(&constr);
1521 return E_FAIL;
1524 hres = disp_call(V_DISPATCH(&constr), DISPID_VALUE, ctx->parser->script->lcid,
1525 DISPATCH_CONSTRUCT, &dp, &var, ei, NULL/*FIXME*/);
1526 IDispatch_Release(V_DISPATCH(&constr));
1527 if(FAILED(hres))
1528 return hres;
1530 ret->type = EXPRVAL_VARIANT;
1531 ret->u.var = var;
1532 return S_OK;
1535 /* ECMA-262 3rd Edition 11.2.3 */
1536 HRESULT call_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1538 call_expression_t *expr = (call_expression_t*)_expr;
1539 VARIANT var;
1540 exprval_t exprval;
1541 DISPPARAMS dp;
1542 HRESULT hres;
1544 TRACE("\n");
1546 hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
1547 if(FAILED(hres))
1548 return hres;
1550 hres = args_to_param(ctx, expr->argument_list, ei, &dp);
1551 if(SUCCEEDED(hres)) {
1552 switch(exprval.type) {
1553 case EXPRVAL_VARIANT:
1554 if(V_VT(&exprval.u.var) != VT_DISPATCH)
1555 return throw_type_error(ctx->var_disp->ctx, ei, IDS_NO_PROPERTY, NULL);
1557 hres = disp_call(V_DISPATCH(&exprval.u.var), DISPID_VALUE, ctx->parser->script->lcid,
1558 DISPATCH_METHOD, &dp, flags & EXPR_NOVAL ? NULL : &var, ei, NULL/*FIXME*/);
1559 break;
1560 case EXPRVAL_IDREF:
1561 hres = disp_call(exprval.u.idref.disp, exprval.u.idref.id, ctx->parser->script->lcid,
1562 DISPATCH_METHOD, &dp, flags & EXPR_NOVAL ? NULL : &var, ei, NULL/*FIXME*/);
1563 break;
1564 default:
1565 FIXME("unimplemented type %d\n", exprval.type);
1566 hres = E_NOTIMPL;
1569 free_dp(&dp);
1572 exprval_release(&exprval);
1573 if(FAILED(hres))
1574 return hres;
1576 ret->type = EXPRVAL_VARIANT;
1577 if(flags & EXPR_NOVAL) {
1578 V_VT(&ret->u.var) = VT_EMPTY;
1579 }else {
1580 TRACE("= %s\n", debugstr_variant(&var));
1581 ret->u.var = var;
1583 return S_OK;
1586 /* ECMA-262 3rd Edition 11.1.1 */
1587 HRESULT this_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1589 TRACE("\n");
1591 ret->type = EXPRVAL_VARIANT;
1592 V_VT(&ret->u.var) = VT_DISPATCH;
1593 V_DISPATCH(&ret->u.var) = ctx->this_obj;
1594 IDispatch_AddRef(ctx->this_obj);
1595 return S_OK;
1598 /* ECMA-262 3rd Edition 10.1.4 */
1599 HRESULT identifier_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1601 identifier_expression_t *expr = (identifier_expression_t*)_expr;
1602 BSTR identifier;
1603 HRESULT hres;
1605 TRACE("\n");
1607 identifier = SysAllocString(expr->identifier);
1608 if(!identifier)
1609 return E_OUTOFMEMORY;
1611 hres = identifier_eval(ctx, identifier, flags, ei, ret);
1613 SysFreeString(identifier);
1614 return hres;
1617 /* ECMA-262 3rd Edition 7.8 */
1618 HRESULT literal_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1620 literal_expression_t *expr = (literal_expression_t*)_expr;
1621 VARIANT var;
1622 HRESULT hres;
1624 TRACE("\n");
1626 hres = literal_to_var(expr->literal, &var);
1627 if(FAILED(hres))
1628 return hres;
1630 ret->type = EXPRVAL_VARIANT;
1631 ret->u.var = var;
1632 return S_OK;
1635 /* ECMA-262 3rd Edition 11.1.4 */
1636 HRESULT array_literal_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1638 array_literal_expression_t *expr = (array_literal_expression_t*)_expr;
1639 DWORD length = 0, i = 0;
1640 array_element_t *elem;
1641 DispatchEx *array;
1642 exprval_t exprval;
1643 VARIANT val;
1644 HRESULT hres;
1646 TRACE("\n");
1648 for(elem = expr->element_list; elem; elem = elem->next)
1649 length += elem->elision+1;
1650 length += expr->length;
1652 hres = create_array(ctx->parser->script, length, &array);
1653 if(FAILED(hres))
1654 return hres;
1656 for(elem = expr->element_list; elem; elem = elem->next) {
1657 i += elem->elision;
1659 hres = expr_eval(ctx, elem->expr, 0, ei, &exprval);
1660 if(FAILED(hres))
1661 break;
1663 hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
1664 exprval_release(&exprval);
1665 if(FAILED(hres))
1666 break;
1668 hres = jsdisp_propput_idx(array, i, ctx->parser->script->lcid, &val, ei, NULL/*FIXME*/);
1669 VariantClear(&val);
1670 if(FAILED(hres))
1671 break;
1673 i++;
1676 if(FAILED(hres)) {
1677 jsdisp_release(array);
1678 return hres;
1681 ret->type = EXPRVAL_VARIANT;
1682 V_VT(&ret->u.var) = VT_DISPATCH;
1683 V_DISPATCH(&ret->u.var) = (IDispatch*)_IDispatchEx_(array);
1684 return S_OK;
1687 /* ECMA-262 3rd Edition 11.1.5 */
1688 HRESULT property_value_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1690 property_value_expression_t *expr = (property_value_expression_t*)_expr;
1691 VARIANT val, tmp;
1692 DispatchEx *obj;
1693 prop_val_t *iter;
1694 exprval_t exprval;
1695 BSTR name;
1696 HRESULT hres;
1698 TRACE("\n");
1700 hres = create_object(ctx->parser->script, NULL, &obj);
1701 if(FAILED(hres))
1702 return hres;
1704 for(iter = expr->property_list; iter; iter = iter->next) {
1705 hres = literal_to_var(iter->name, &tmp);
1706 if(FAILED(hres))
1707 break;
1709 hres = to_string(ctx->parser->script, &tmp, ei, &name);
1710 VariantClear(&tmp);
1711 if(FAILED(hres))
1712 break;
1714 hres = expr_eval(ctx, iter->value, 0, ei, &exprval);
1715 if(SUCCEEDED(hres)) {
1716 hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
1717 exprval_release(&exprval);
1718 if(SUCCEEDED(hres)) {
1719 hres = jsdisp_propput_name(obj, name, ctx->parser->script->lcid, &val, ei, NULL/*FIXME*/);
1720 VariantClear(&val);
1724 SysFreeString(name);
1725 if(FAILED(hres))
1726 break;
1729 if(FAILED(hres)) {
1730 jsdisp_release(obj);
1731 return hres;
1734 ret->type = EXPRVAL_VARIANT;
1735 V_VT(&ret->u.var) = VT_DISPATCH;
1736 V_DISPATCH(&ret->u.var) = (IDispatch*)_IDispatchEx_(obj);
1737 return S_OK;
1740 /* ECMA-262 3rd Edition 11.14 */
1741 HRESULT comma_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1743 binary_expression_t *expr = (binary_expression_t*)_expr;
1744 VARIANT lval, rval;
1745 HRESULT hres;
1747 TRACE("\n");
1749 hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval);
1750 if(FAILED(hres))
1751 return hres;
1753 VariantClear(&lval);
1755 ret->type = EXPRVAL_VARIANT;
1756 ret->u.var = rval;
1757 return S_OK;
1760 /* ECMA-262 3rd Edition 11.11 */
1761 HRESULT logical_or_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1763 binary_expression_t *expr = (binary_expression_t*)_expr;
1764 exprval_t exprval;
1765 VARIANT_BOOL b;
1766 VARIANT val;
1767 HRESULT hres;
1769 TRACE("\n");
1771 hres = expr_eval(ctx, expr->expression1, 0, ei, &exprval);
1772 if(FAILED(hres))
1773 return hres;
1775 hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
1776 exprval_release(&exprval);
1777 if(FAILED(hres))
1778 return hres;
1780 hres = to_boolean(&val, &b);
1781 if(SUCCEEDED(hres) && b) {
1782 ret->type = EXPRVAL_VARIANT;
1783 ret->u.var = val;
1784 return S_OK;
1787 VariantClear(&val);
1788 if(FAILED(hres))
1789 return hres;
1791 hres = expr_eval(ctx, expr->expression2, 0, ei, &exprval);
1792 if(FAILED(hres))
1793 return hres;
1795 hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
1796 exprval_release(&exprval);
1797 if(FAILED(hres))
1798 return hres;
1800 ret->type = EXPRVAL_VARIANT;
1801 ret->u.var = val;
1802 return S_OK;
1805 /* ECMA-262 3rd Edition 11.11 */
1806 HRESULT logical_and_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1808 binary_expression_t *expr = (binary_expression_t*)_expr;
1809 exprval_t exprval;
1810 VARIANT_BOOL b;
1811 VARIANT val;
1812 HRESULT hres;
1814 TRACE("\n");
1816 hres = expr_eval(ctx, expr->expression1, 0, ei, &exprval);
1817 if(FAILED(hres))
1818 return hres;
1820 hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
1821 exprval_release(&exprval);
1822 if(FAILED(hres))
1823 return hres;
1825 hres = to_boolean(&val, &b);
1826 if(SUCCEEDED(hres) && !b) {
1827 ret->type = EXPRVAL_VARIANT;
1828 ret->u.var = val;
1829 return S_OK;
1832 VariantClear(&val);
1833 if(FAILED(hres))
1834 return hres;
1836 hres = expr_eval(ctx, expr->expression2, 0, ei, &exprval);
1837 if(FAILED(hres))
1838 return hres;
1840 hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
1841 exprval_release(&exprval);
1842 if(FAILED(hres))
1843 return hres;
1845 ret->type = EXPRVAL_VARIANT;
1846 ret->u.var = val;
1847 return S_OK;
1850 /* ECMA-262 3rd Edition 11.10 */
1851 static HRESULT bitor_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
1853 INT li, ri;
1854 HRESULT hres;
1856 hres = to_int32(ctx->parser->script, lval, ei, &li);
1857 if(FAILED(hres))
1858 return hres;
1860 hres = to_int32(ctx->parser->script, rval, ei, &ri);
1861 if(FAILED(hres))
1862 return hres;
1864 V_VT(retv) = VT_I4;
1865 V_I4(retv) = li|ri;
1866 return S_OK;
1869 /* ECMA-262 3rd Edition 11.10 */
1870 HRESULT binary_or_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1872 binary_expression_t *expr = (binary_expression_t*)_expr;
1874 TRACE("\n");
1876 return binary_expr_eval(ctx, expr, bitor_eval, ei, ret);
1879 /* ECMA-262 3rd Edition 11.10 */
1880 static HRESULT xor_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
1882 INT li, ri;
1883 HRESULT hres;
1885 hres = to_int32(ctx->parser->script, lval, ei, &li);
1886 if(FAILED(hres))
1887 return hres;
1889 hres = to_int32(ctx->parser->script, rval, ei, &ri);
1890 if(FAILED(hres))
1891 return hres;
1893 V_VT(retv) = VT_I4;
1894 V_I4(retv) = li^ri;
1895 return S_OK;
1898 /* ECMA-262 3rd Edition 11.10 */
1899 HRESULT binary_xor_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1901 binary_expression_t *expr = (binary_expression_t*)_expr;
1903 TRACE("\n");
1905 return binary_expr_eval(ctx, expr, xor_eval, ei, ret);
1908 /* ECMA-262 3rd Edition 11.10 */
1909 static HRESULT bitand_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
1911 INT li, ri;
1912 HRESULT hres;
1914 hres = to_int32(ctx->parser->script, lval, ei, &li);
1915 if(FAILED(hres))
1916 return hres;
1918 hres = to_int32(ctx->parser->script, rval, ei, &ri);
1919 if(FAILED(hres))
1920 return hres;
1922 V_VT(retv) = VT_I4;
1923 V_I4(retv) = li&ri;
1924 return S_OK;
1927 /* ECMA-262 3rd Edition 11.10 */
1928 HRESULT binary_and_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1930 binary_expression_t *expr = (binary_expression_t*)_expr;
1932 TRACE("\n");
1934 return binary_expr_eval(ctx, expr, bitand_eval, ei, ret);
1937 /* ECMA-262 3rd Edition 11.8.6 */
1938 HRESULT instanceof_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1940 FIXME("\n");
1941 return E_NOTIMPL;
1944 /* ECMA-262 3rd Edition 11.8.7 */
1945 HRESULT in_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1947 FIXME("\n");
1948 return E_NOTIMPL;
1951 /* ECMA-262 3rd Edition 11.6.1 */
1952 static HRESULT add_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
1954 VARIANT r, l;
1955 HRESULT hres;
1957 hres = to_primitive(ctx->parser->script, lval, ei, &l, NO_HINT);
1958 if(FAILED(hres))
1959 return hres;
1961 hres = to_primitive(ctx->parser->script, rval, ei, &r, NO_HINT);
1962 if(FAILED(hres)) {
1963 VariantClear(&l);
1964 return hres;
1967 if(V_VT(&l) == VT_BSTR || V_VT(&r) == VT_BSTR) {
1968 BSTR lstr = NULL, rstr = NULL;
1970 if(V_VT(&l) == VT_BSTR)
1971 lstr = V_BSTR(&l);
1972 else
1973 hres = to_string(ctx->parser->script, &l, ei, &lstr);
1975 if(SUCCEEDED(hres)) {
1976 if(V_VT(&r) == VT_BSTR)
1977 rstr = V_BSTR(&r);
1978 else
1979 hres = to_string(ctx->parser->script, &r, ei, &rstr);
1982 if(SUCCEEDED(hres)) {
1983 int len1, len2;
1985 len1 = SysStringLen(lstr);
1986 len2 = SysStringLen(rstr);
1988 V_VT(retv) = VT_BSTR;
1989 V_BSTR(retv) = SysAllocStringLen(NULL, len1+len2);
1990 memcpy(V_BSTR(retv), lstr, len1*sizeof(WCHAR));
1991 memcpy(V_BSTR(retv)+len1, rstr, (len2+1)*sizeof(WCHAR));
1994 if(V_VT(&l) != VT_BSTR)
1995 SysFreeString(lstr);
1996 if(V_VT(&r) != VT_BSTR)
1997 SysFreeString(rstr);
1998 }else {
1999 VARIANT nl, nr;
2001 hres = to_number(ctx->parser->script, &l, ei, &nl);
2002 if(SUCCEEDED(hres)) {
2003 hres = to_number(ctx->parser->script, &r, ei, &nr);
2004 if(SUCCEEDED(hres))
2005 num_set_val(retv, num_val(&nl) + num_val(&nr));
2009 VariantClear(&r);
2010 VariantClear(&l);
2011 return hres;
2014 /* ECMA-262 3rd Edition 11.6.1 */
2015 HRESULT add_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2017 binary_expression_t *expr = (binary_expression_t*)_expr;
2019 TRACE("\n");
2021 return binary_expr_eval(ctx, expr, add_eval, ei, ret);
2024 /* ECMA-262 3rd Edition 11.6.2 */
2025 static HRESULT sub_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
2027 VARIANT lnum, rnum;
2028 HRESULT hres;
2030 hres = to_number(ctx->parser->script, lval, ei, &lnum);
2031 if(FAILED(hres))
2032 return hres;
2034 hres = to_number(ctx->parser->script, rval, ei, &rnum);
2035 if(FAILED(hres))
2036 return hres;
2038 num_set_val(retv, num_val(&lnum) - num_val(&rnum));
2039 return S_OK;
2042 /* ECMA-262 3rd Edition 11.6.2 */
2043 HRESULT sub_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2045 binary_expression_t *expr = (binary_expression_t*)_expr;
2047 TRACE("\n");
2049 return binary_expr_eval(ctx, expr, sub_eval, ei, ret);
2052 /* ECMA-262 3rd Edition 11.5.1 */
2053 static HRESULT mul_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
2055 VARIANT lnum, rnum;
2056 HRESULT hres;
2058 hres = to_number(ctx->parser->script, lval, ei, &lnum);
2059 if(FAILED(hres))
2060 return hres;
2062 hres = to_number(ctx->parser->script, rval, ei, &rnum);
2063 if(FAILED(hres))
2064 return hres;
2066 num_set_val(retv, num_val(&lnum) * num_val(&rnum));
2067 return S_OK;
2070 /* ECMA-262 3rd Edition 11.5.1 */
2071 HRESULT mul_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2073 binary_expression_t *expr = (binary_expression_t*)_expr;
2075 TRACE("\n");
2077 return binary_expr_eval(ctx, expr, mul_eval, ei, ret);
2080 /* ECMA-262 3rd Edition 11.5.2 */
2081 static HRESULT div_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
2083 VARIANT lnum, rnum;
2084 HRESULT hres;
2086 hres = to_number(ctx->parser->script, lval, ei, &lnum);
2087 if(FAILED(hres))
2088 return hres;
2090 hres = to_number(ctx->parser->script, rval, ei, &rnum);
2091 if(FAILED(hres))
2092 return hres;
2094 num_set_val(retv, num_val(&lnum) / num_val(&rnum));
2095 return S_OK;
2098 /* ECMA-262 3rd Edition 11.5.2 */
2099 HRESULT div_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2101 binary_expression_t *expr = (binary_expression_t*)_expr;
2103 TRACE("\n");
2105 return binary_expr_eval(ctx, expr, div_eval, ei, ret);
2108 /* ECMA-262 3rd Edition 11.5.3 */
2109 static HRESULT mod_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
2111 VARIANT lnum, rnum;
2112 HRESULT hres;
2114 hres = to_number(ctx->parser->script, lval, ei, &lnum);
2115 if(FAILED(hres))
2116 return hres;
2118 hres = to_number(ctx->parser->script, rval, ei, &rnum);
2119 if(FAILED(hres))
2120 return hres;
2122 num_set_val(retv, fmod(num_val(&lnum), num_val(&rnum)));
2123 return S_OK;
2126 /* ECMA-262 3rd Edition 11.5.3 */
2127 HRESULT mod_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2129 binary_expression_t *expr = (binary_expression_t*)_expr;
2131 TRACE("\n");
2133 return binary_expr_eval(ctx, expr, mod_eval, ei, ret);
2136 /* ECMA-262 3rd Edition 11.4.2 */
2137 HRESULT delete_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2139 unary_expression_t *expr = (unary_expression_t*)_expr;
2140 VARIANT_BOOL b = VARIANT_FALSE;
2141 exprval_t exprval;
2142 HRESULT hres;
2144 TRACE("\n");
2146 hres = expr_eval(ctx, expr->expression, EXPR_STRREF, ei, &exprval);
2147 if(FAILED(hres))
2148 return hres;
2150 switch(exprval.type) {
2151 case EXPRVAL_IDREF: {
2152 IDispatchEx *dispex;
2154 hres = IDispatch_QueryInterface(exprval.u.nameref.disp, &IID_IDispatchEx, (void**)&dispex);
2155 if(SUCCEEDED(hres)) {
2156 hres = IDispatchEx_DeleteMemberByDispID(dispex, exprval.u.idref.id);
2157 b = VARIANT_TRUE;
2158 IDispatchEx_Release(dispex);
2160 break;
2162 case EXPRVAL_NAMEREF: {
2163 IDispatchEx *dispex;
2165 hres = IDispatch_QueryInterface(exprval.u.nameref.disp, &IID_IDispatchEx, (void**)&dispex);
2166 if(SUCCEEDED(hres)) {
2167 hres = IDispatchEx_DeleteMemberByName(dispex, exprval.u.nameref.name, fdexNameCaseSensitive);
2168 b = VARIANT_TRUE;
2169 IDispatchEx_Release(dispex);
2171 break;
2173 default:
2174 FIXME("unsupported type %d\n", exprval.type);
2175 hres = E_NOTIMPL;
2178 exprval_release(&exprval);
2179 if(FAILED(hres))
2180 return hres;
2182 return return_bool(ret, b);
2185 /* ECMA-262 3rd Edition 11.4.2 */
2186 HRESULT void_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2188 unary_expression_t *expr = (unary_expression_t*)_expr;
2189 exprval_t exprval;
2190 VARIANT tmp;
2191 HRESULT hres;
2193 TRACE("\n");
2195 hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
2196 if(FAILED(hres))
2197 return hres;
2199 hres = exprval_to_value(ctx->parser->script, &exprval, ei, &tmp);
2200 exprval_release(&exprval);
2201 if(FAILED(hres))
2202 return hres;
2204 VariantClear(&tmp);
2206 ret->type = EXPRVAL_VARIANT;
2207 V_VT(&ret->u.var) = VT_EMPTY;
2208 return S_OK;
2211 /* ECMA-262 3rd Edition 11.4.3 */
2212 HRESULT typeof_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2214 unary_expression_t *expr = (unary_expression_t*)_expr;
2215 const WCHAR *str;
2216 exprval_t exprval;
2217 VARIANT val;
2218 HRESULT hres;
2220 static const WCHAR booleanW[] = {'b','o','o','l','e','a','n',0};
2221 static const WCHAR functionW[] = {'f','u','n','c','t','i','o','n',0};
2222 static const WCHAR numberW[] = {'n','u','m','b','e','r',0};
2223 static const WCHAR objectW[] = {'o','b','j','e','c','t',0};
2224 static const WCHAR stringW[] = {'s','t','r','i','n','g',0};
2225 static const WCHAR undefinedW[] = {'u','n','d','e','f','i','n','e','d',0};
2227 TRACE("\n");
2229 hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
2230 if(FAILED(hres))
2231 return hres;
2233 hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
2234 exprval_release(&exprval);
2235 if(FAILED(hres))
2236 return hres;
2238 switch(V_VT(&val)) {
2239 case VT_EMPTY:
2240 str = undefinedW;
2241 break;
2242 case VT_NULL:
2243 str = objectW;
2244 break;
2245 case VT_BOOL:
2246 str = booleanW;
2247 break;
2248 case VT_I4:
2249 case VT_R8:
2250 str = numberW;
2251 break;
2252 case VT_BSTR:
2253 str = stringW;
2254 break;
2255 case VT_DISPATCH: {
2256 DispatchEx *dispex;
2258 dispex = iface_to_jsdisp((IUnknown*)V_DISPATCH(&val));
2259 if(dispex) {
2260 str = dispex->builtin_info->class == JSCLASS_FUNCTION ? functionW : objectW;
2261 IDispatchEx_Release(_IDispatchEx_(dispex));
2262 }else {
2263 str = objectW;
2265 break;
2267 default:
2268 FIXME("unhandled vt %d\n", V_VT(&val));
2269 VariantClear(&val);
2270 return E_NOTIMPL;
2273 VariantClear(&val);
2275 ret->type = EXPRVAL_VARIANT;
2276 V_VT(&ret->u.var) = VT_BSTR;
2277 V_BSTR(&ret->u.var) = SysAllocString(str);
2278 return S_OK;
2281 /* ECMA-262 3rd Edition 11.4.7 */
2282 HRESULT minus_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2284 unary_expression_t *expr = (unary_expression_t*)_expr;
2285 exprval_t exprval;
2286 VARIANT val, num;
2287 HRESULT hres;
2289 TRACE("\n");
2291 hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
2292 if(FAILED(hres))
2293 return hres;
2295 hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
2296 exprval_release(&exprval);
2297 if(FAILED(hres))
2298 return hres;
2300 hres = to_number(ctx->parser->script, &val, ei, &num);
2301 VariantClear(&val);
2302 if(FAILED(hres))
2303 return hres;
2305 ret->type = EXPRVAL_VARIANT;
2306 num_set_val(&ret->u.var, -num_val(&num));
2307 return S_OK;
2310 /* ECMA-262 3rd Edition 11.4.6 */
2311 HRESULT plus_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2313 unary_expression_t *expr = (unary_expression_t*)_expr;
2314 exprval_t exprval;
2315 VARIANT val, num;
2316 HRESULT hres;
2318 TRACE("\n");
2320 hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval);
2321 if(FAILED(hres))
2322 return hres;
2324 hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
2325 exprval_release(&exprval);
2326 if(FAILED(hres))
2327 return hres;
2329 hres = to_number(ctx->parser->script, &val, ei, &num);
2330 if(FAILED(hres))
2331 return hres;
2333 ret->type = EXPRVAL_VARIANT;
2334 ret->u.var = num;
2335 return S_OK;
2338 /* ECMA-262 3rd Edition 11.3.1 */
2339 HRESULT post_increment_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2341 unary_expression_t *expr = (unary_expression_t*)_expr;
2342 VARIANT val, num;
2343 exprval_t exprval;
2344 HRESULT hres;
2346 TRACE("\n");
2348 hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval);
2349 if(FAILED(hres))
2350 return hres;
2352 hres = exprval_value(ctx->parser->script, &exprval, ei, &val);
2353 if(SUCCEEDED(hres)) {
2354 hres = to_number(ctx->parser->script, &val, ei, &num);
2355 VariantClear(&val);
2358 if(SUCCEEDED(hres)) {
2359 VARIANT inc;
2360 num_set_val(&inc, num_val(&num)+1.0);
2361 hres = put_value(ctx->parser->script, &exprval, &inc, ei);
2364 exprval_release(&exprval);
2365 if(FAILED(hres))
2366 return hres;
2368 ret->type = EXPRVAL_VARIANT;
2369 ret->u.var = num;
2370 return S_OK;
2373 /* ECMA-262 3rd Edition 11.3.2 */
2374 HRESULT post_decrement_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2376 unary_expression_t *expr = (unary_expression_t*)_expr;
2377 VARIANT val, num;
2378 exprval_t exprval;
2379 HRESULT hres;
2381 TRACE("\n");
2383 hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval);
2384 if(FAILED(hres))
2385 return hres;
2387 hres = exprval_value(ctx->parser->script, &exprval, ei, &val);
2388 if(SUCCEEDED(hres)) {
2389 hres = to_number(ctx->parser->script, &val, ei, &num);
2390 VariantClear(&val);
2393 if(SUCCEEDED(hres)) {
2394 VARIANT dec;
2395 num_set_val(&dec, num_val(&num)-1.0);
2396 hres = put_value(ctx->parser->script, &exprval, &dec, ei);
2399 exprval_release(&exprval);
2400 if(FAILED(hres))
2401 return hres;
2403 ret->type = EXPRVAL_VARIANT;
2404 ret->u.var = num;
2405 return S_OK;
2408 /* ECMA-262 3rd Edition 11.4.4 */
2409 HRESULT pre_increment_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2411 unary_expression_t *expr = (unary_expression_t*)_expr;
2412 VARIANT val, num;
2413 exprval_t exprval;
2414 HRESULT hres;
2416 TRACE("\n");
2418 hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval);
2419 if(FAILED(hres))
2420 return hres;
2422 hres = exprval_value(ctx->parser->script, &exprval, ei, &val);
2423 if(SUCCEEDED(hres)) {
2424 hres = to_number(ctx->parser->script, &val, ei, &num);
2425 VariantClear(&val);
2428 if(SUCCEEDED(hres)) {
2429 num_set_val(&val, num_val(&num)+1.0);
2430 hres = put_value(ctx->parser->script, &exprval, &val, ei);
2433 exprval_release(&exprval);
2434 if(FAILED(hres))
2435 return hres;
2437 ret->type = EXPRVAL_VARIANT;
2438 ret->u.var = val;
2439 return S_OK;
2442 /* ECMA-262 3rd Edition 11.4.5 */
2443 HRESULT pre_decrement_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2445 unary_expression_t *expr = (unary_expression_t*)_expr;
2446 VARIANT val, num;
2447 exprval_t exprval;
2448 HRESULT hres;
2450 TRACE("\n");
2452 hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval);
2453 if(FAILED(hres))
2454 return hres;
2456 hres = exprval_value(ctx->parser->script, &exprval, ei, &val);
2457 if(SUCCEEDED(hres)) {
2458 hres = to_number(ctx->parser->script, &val, ei, &num);
2459 VariantClear(&val);
2462 if(SUCCEEDED(hres)) {
2463 num_set_val(&val, num_val(&num)-1.0);
2464 hres = put_value(ctx->parser->script, &exprval, &val, ei);
2467 exprval_release(&exprval);
2468 if(FAILED(hres))
2469 return hres;
2471 ret->type = EXPRVAL_VARIANT;
2472 ret->u.var = val;
2473 return S_OK;
2476 /* ECMA-262 3rd Edition 11.9.3 */
2477 static HRESULT equal_values(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, BOOL *ret)
2479 if(V_VT(lval) == V_VT(rval) || (is_num_vt(V_VT(lval)) && is_num_vt(V_VT(rval))))
2480 return equal2_values(lval, rval, ret);
2482 /* FIXME: NULL disps should be handled in more general way */
2483 if(V_VT(lval) == VT_DISPATCH && !V_DISPATCH(lval)) {
2484 VARIANT v;
2485 V_VT(&v) = VT_NULL;
2486 return equal_values(ctx, &v, rval, ei, ret);
2489 if(V_VT(rval) == VT_DISPATCH && !V_DISPATCH(rval)) {
2490 VARIANT v;
2491 V_VT(&v) = VT_NULL;
2492 return equal_values(ctx, lval, &v, ei, ret);
2495 if((V_VT(lval) == VT_NULL && V_VT(rval) == VT_EMPTY) ||
2496 (V_VT(lval) == VT_EMPTY && V_VT(rval) == VT_NULL)) {
2497 *ret = TRUE;
2498 return S_OK;
2501 if(V_VT(lval) == VT_BSTR && is_num_vt(V_VT(rval))) {
2502 VARIANT v;
2503 HRESULT hres;
2505 hres = to_number(ctx->parser->script, lval, ei, &v);
2506 if(FAILED(hres))
2507 return hres;
2509 return equal_values(ctx, &v, rval, ei, ret);
2512 if(V_VT(rval) == VT_BSTR && is_num_vt(V_VT(lval))) {
2513 VARIANT v;
2514 HRESULT hres;
2516 hres = to_number(ctx->parser->script, rval, ei, &v);
2517 if(FAILED(hres))
2518 return hres;
2520 return equal_values(ctx, lval, &v, ei, ret);
2523 if(V_VT(rval) == VT_BOOL) {
2524 VARIANT v;
2526 V_VT(&v) = VT_I4;
2527 V_I4(&v) = V_BOOL(rval) ? 1 : 0;
2528 return equal_values(ctx, lval, &v, ei, ret);
2531 if(V_VT(lval) == VT_BOOL) {
2532 VARIANT v;
2534 V_VT(&v) = VT_I4;
2535 V_I4(&v) = V_BOOL(lval) ? 1 : 0;
2536 return equal_values(ctx, &v, rval, ei, ret);
2540 if(V_VT(rval) == VT_DISPATCH && (V_VT(lval) == VT_BSTR || is_num_vt(V_VT(lval)))) {
2541 VARIANT v;
2542 HRESULT hres;
2544 hres = to_primitive(ctx->parser->script, rval, ei, &v, NO_HINT);
2545 if(FAILED(hres))
2546 return hres;
2548 hres = equal_values(ctx, lval, &v, ei, ret);
2550 VariantClear(&v);
2551 return hres;
2555 if(V_VT(lval) == VT_DISPATCH && (V_VT(rval) == VT_BSTR || is_num_vt(V_VT(rval)))) {
2556 VARIANT v;
2557 HRESULT hres;
2559 hres = to_primitive(ctx->parser->script, lval, ei, &v, NO_HINT);
2560 if(FAILED(hres))
2561 return hres;
2563 hres = equal_values(ctx, &v, rval, ei, ret);
2565 VariantClear(&v);
2566 return hres;
2570 *ret = FALSE;
2571 return S_OK;
2574 /* ECMA-262 3rd Edition 11.9.1 */
2575 HRESULT equal_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2577 binary_expression_t *expr = (binary_expression_t*)_expr;
2578 VARIANT rval, lval;
2579 BOOL b;
2580 HRESULT hres;
2582 TRACE("\n");
2584 hres = get_binary_expr_values(ctx, expr, ei, &rval, &lval);
2585 if(FAILED(hres))
2586 return hres;
2588 hres = equal_values(ctx, &rval, &lval, ei, &b);
2589 if(FAILED(hres))
2590 return hres;
2592 return return_bool(ret, b);
2595 /* ECMA-262 3rd Edition 11.9.4 */
2596 HRESULT equal2_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2598 binary_expression_t *expr = (binary_expression_t*)_expr;
2599 VARIANT rval, lval;
2600 BOOL b;
2601 HRESULT hres;
2603 TRACE("\n");
2605 hres = get_binary_expr_values(ctx, expr, ei, &rval, &lval);
2606 if(FAILED(hres))
2607 return hres;
2609 hres = equal2_values(&rval, &lval, &b);
2610 if(FAILED(hres))
2611 return hres;
2613 return return_bool(ret, b);
2616 /* ECMA-262 3rd Edition 11.9.2 */
2617 HRESULT not_equal_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2619 binary_expression_t *expr = (binary_expression_t*)_expr;
2620 VARIANT rval, lval;
2621 BOOL b;
2622 HRESULT hres;
2624 TRACE("\n");
2626 hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval);
2627 if(FAILED(hres))
2628 return hres;
2630 hres = equal_values(ctx, &lval, &rval, ei, &b);
2631 if(FAILED(hres))
2632 return hres;
2634 return return_bool(ret, !b);
2637 /* ECMA-262 3rd Edition 11.9.5 */
2638 HRESULT not_equal2_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2640 binary_expression_t *expr = (binary_expression_t*)_expr;
2641 VARIANT rval, lval;
2642 BOOL b;
2643 HRESULT hres;
2645 TRACE("\n");
2647 hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval);
2648 if(FAILED(hres))
2649 return hres;
2651 hres = equal2_values(&lval, &rval, &b);
2652 if(FAILED(hres))
2653 return hres;
2655 return return_bool(ret, !b);
2658 /* ECMA-262 3rd Edition 11.8.5 */
2659 static HRESULT less_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, BOOL greater, jsexcept_t *ei, BOOL *ret)
2661 VARIANT l, r, ln, rn;
2662 HRESULT hres;
2664 hres = to_primitive(ctx->parser->script, lval, ei, &l, NO_HINT);
2665 if(FAILED(hres))
2666 return hres;
2668 hres = to_primitive(ctx->parser->script, rval, ei, &r, NO_HINT);
2669 if(FAILED(hres)) {
2670 VariantClear(&l);
2671 return hres;
2674 if(V_VT(&l) == VT_BSTR && V_VT(&r) == VT_BSTR) {
2675 *ret = (strcmpW(V_BSTR(&l), V_BSTR(&r)) < 0) ^ greater;
2676 SysFreeString(V_BSTR(&l));
2677 SysFreeString(V_BSTR(&r));
2678 return S_OK;
2681 hres = to_number(ctx->parser->script, &l, ei, &ln);
2682 VariantClear(&l);
2683 if(SUCCEEDED(hres))
2684 hres = to_number(ctx->parser->script, &r, ei, &rn);
2685 VariantClear(&r);
2686 if(FAILED(hres))
2687 return hres;
2689 if(V_VT(&ln) == VT_I4 && V_VT(&rn) == VT_I4) {
2690 *ret = (V_I4(&ln) < V_I4(&rn)) ^ greater;
2691 }else {
2692 DOUBLE ld = num_val(&ln);
2693 DOUBLE rd = num_val(&rn);
2695 *ret = !isnan(ld) && !isnan(rd) && ((ld < rd) ^ greater);
2698 return S_OK;
2701 /* ECMA-262 3rd Edition 11.8.1 */
2702 HRESULT less_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2704 binary_expression_t *expr = (binary_expression_t*)_expr;
2705 VARIANT rval, lval;
2706 BOOL b;
2707 HRESULT hres;
2709 TRACE("\n");
2711 hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval);
2712 if(FAILED(hres))
2713 return hres;
2715 hres = less_eval(ctx, &lval, &rval, FALSE, ei, &b);
2716 VariantClear(&lval);
2717 VariantClear(&rval);
2718 if(FAILED(hres))
2719 return hres;
2721 return return_bool(ret, b);
2724 /* ECMA-262 3rd Edition 11.8.3 */
2725 HRESULT lesseq_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2727 binary_expression_t *expr = (binary_expression_t*)_expr;
2728 VARIANT rval, lval;
2729 BOOL b;
2730 HRESULT hres;
2732 TRACE("\n");
2734 hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval);
2735 if(FAILED(hres))
2736 return hres;
2738 hres = less_eval(ctx, &rval, &lval, TRUE, ei, &b);
2739 VariantClear(&lval);
2740 VariantClear(&rval);
2741 if(FAILED(hres))
2742 return hres;
2744 return return_bool(ret, b);
2747 /* ECMA-262 3rd Edition 11.8.2 */
2748 HRESULT greater_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2750 binary_expression_t *expr = (binary_expression_t*)_expr;
2751 VARIANT rval, lval;
2752 BOOL b;
2753 HRESULT hres;
2755 TRACE("\n");
2757 hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval);
2758 if(FAILED(hres))
2759 return hres;
2761 hres = less_eval(ctx, &rval, &lval, FALSE, ei, &b);
2762 VariantClear(&lval);
2763 VariantClear(&rval);
2764 if(FAILED(hres))
2765 return hres;
2767 return return_bool(ret, b);
2770 /* ECMA-262 3rd Edition 11.8.4 */
2771 HRESULT greatereq_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2773 binary_expression_t *expr = (binary_expression_t*)_expr;
2774 VARIANT rval, lval;
2775 BOOL b;
2776 HRESULT hres;
2778 TRACE("\n");
2780 hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval);
2781 if(FAILED(hres))
2782 return hres;
2784 hres = less_eval(ctx, &lval, &rval, TRUE, ei, &b);
2785 VariantClear(&lval);
2786 VariantClear(&rval);
2787 if(FAILED(hres))
2788 return hres;
2790 return return_bool(ret, b);
2793 /* ECMA-262 3rd Edition 11.4.8 */
2794 HRESULT binary_negation_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2796 unary_expression_t *expr = (unary_expression_t*)_expr;
2797 exprval_t exprval;
2798 VARIANT val;
2799 INT i;
2800 HRESULT hres;
2802 TRACE("\n");
2804 hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval);
2805 if(FAILED(hres))
2806 return hres;
2808 hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
2809 exprval_release(&exprval);
2810 if(FAILED(hres))
2811 return hres;
2813 hres = to_int32(ctx->parser->script, &val, ei, &i);
2814 if(FAILED(hres))
2815 return hres;
2817 ret->type = EXPRVAL_VARIANT;
2818 V_VT(&ret->u.var) = VT_I4;
2819 V_I4(&ret->u.var) = ~i;
2820 return S_OK;
2823 /* ECMA-262 3rd Edition 11.4.9 */
2824 HRESULT logical_negation_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2826 unary_expression_t *expr = (unary_expression_t*)_expr;
2827 exprval_t exprval;
2828 VARIANT_BOOL b;
2829 HRESULT hres;
2831 TRACE("\n");
2833 hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval);
2834 if(FAILED(hres))
2835 return hres;
2837 hres = exprval_to_boolean(ctx->parser->script, &exprval, ei, &b);
2838 exprval_release(&exprval);
2839 if(FAILED(hres))
2840 return hres;
2842 return return_bool(ret, !b);
2845 /* ECMA-262 3rd Edition 11.7.1 */
2846 static HRESULT lshift_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
2848 DWORD ri;
2849 INT li;
2850 HRESULT hres;
2852 hres = to_int32(ctx->parser->script, lval, ei, &li);
2853 if(FAILED(hres))
2854 return hres;
2856 hres = to_uint32(ctx->parser->script, rval, ei, &ri);
2857 if(FAILED(hres))
2858 return hres;
2860 V_VT(retv) = VT_I4;
2861 V_I4(retv) = li << (ri&0x1f);
2862 return S_OK;
2865 /* ECMA-262 3rd Edition 11.7.1 */
2866 HRESULT left_shift_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2868 binary_expression_t *expr = (binary_expression_t*)_expr;
2870 TRACE("\n");
2872 return binary_expr_eval(ctx, expr, lshift_eval, ei, ret);
2875 /* ECMA-262 3rd Edition 11.7.2 */
2876 static HRESULT rshift_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
2878 DWORD ri;
2879 INT li;
2880 HRESULT hres;
2882 hres = to_int32(ctx->parser->script, lval, ei, &li);
2883 if(FAILED(hres))
2884 return hres;
2886 hres = to_uint32(ctx->parser->script, rval, ei, &ri);
2887 if(FAILED(hres))
2888 return hres;
2890 V_VT(retv) = VT_I4;
2891 V_I4(retv) = li >> (ri&0x1f);
2892 return S_OK;
2895 /* ECMA-262 3rd Edition 11.7.2 */
2896 HRESULT right_shift_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2898 binary_expression_t *expr = (binary_expression_t*)_expr;
2900 TRACE("\n");
2902 return binary_expr_eval(ctx, expr, rshift_eval, ei, ret);
2905 /* ECMA-262 3rd Edition 11.7.3 */
2906 static HRESULT rshift2_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
2908 DWORD li, ri;
2909 HRESULT hres;
2911 hres = to_uint32(ctx->parser->script, lval, ei, &li);
2912 if(FAILED(hres))
2913 return hres;
2915 hres = to_uint32(ctx->parser->script, rval, ei, &ri);
2916 if(FAILED(hres))
2917 return hres;
2919 V_VT(retv) = VT_I4;
2920 V_I4(retv) = li >> (ri&0x1f);
2921 return S_OK;
2924 /* ECMA-262 3rd Edition 11.7.3 */
2925 HRESULT right2_shift_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2927 binary_expression_t *expr = (binary_expression_t*)_expr;
2929 TRACE("\n");
2931 return binary_expr_eval(ctx, expr, rshift2_eval, ei, ret);
2934 /* ECMA-262 3rd Edition 11.13.1 */
2935 HRESULT assign_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2937 binary_expression_t *expr = (binary_expression_t*)_expr;
2938 exprval_t exprval, exprvalr;
2939 VARIANT rval;
2940 HRESULT hres;
2942 TRACE("\n");
2944 hres = expr_eval(ctx, expr->expression1, EXPR_NEWREF, ei, &exprval);
2945 if(FAILED(hres))
2946 return hres;
2948 hres = expr_eval(ctx, expr->expression2, 0, ei, &exprvalr);
2949 if(SUCCEEDED(hres)) {
2950 hres = exprval_to_value(ctx->parser->script, &exprvalr, ei, &rval);
2951 exprval_release(&exprvalr);
2954 if(SUCCEEDED(hres))
2955 hres = put_value(ctx->parser->script, &exprval, &rval, ei);
2957 exprval_release(&exprval);
2958 if(FAILED(hres))
2959 return hres;
2961 ret->type = EXPRVAL_VARIANT;
2962 ret->u.var = rval;
2963 return S_OK;
2966 /* ECMA-262 3rd Edition 11.13.2 */
2967 HRESULT assign_lshift_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2969 binary_expression_t *expr = (binary_expression_t*)_expr;
2971 TRACE("\n");
2973 return assign_oper_eval(ctx, expr->expression1, expr->expression2, lshift_eval, ei, ret);
2976 /* ECMA-262 3rd Edition 11.13.2 */
2977 HRESULT assign_rshift_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2979 binary_expression_t *expr = (binary_expression_t*)_expr;
2981 TRACE("\n");
2983 return assign_oper_eval(ctx, expr->expression1, expr->expression2, rshift_eval, ei, ret);
2986 /* ECMA-262 3rd Edition 11.13.2 */
2987 HRESULT assign_rrshift_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2989 binary_expression_t *expr = (binary_expression_t*)_expr;
2991 TRACE("\n");
2993 return assign_oper_eval(ctx, expr->expression1, expr->expression2, rshift2_eval, ei, ret);
2996 /* ECMA-262 3rd Edition 11.13.2 */
2997 HRESULT assign_add_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2999 binary_expression_t *expr = (binary_expression_t*)_expr;
3001 TRACE("\n");
3003 return assign_oper_eval(ctx, expr->expression1, expr->expression2, add_eval, ei, ret);
3006 /* ECMA-262 3rd Edition 11.13.2 */
3007 HRESULT assign_sub_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3009 binary_expression_t *expr = (binary_expression_t*)_expr;
3011 TRACE("\n");
3013 return assign_oper_eval(ctx, expr->expression1, expr->expression2, sub_eval, ei, ret);
3016 /* ECMA-262 3rd Edition 11.13.2 */
3017 HRESULT assign_mul_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3019 binary_expression_t *expr = (binary_expression_t*)_expr;
3021 TRACE("\n");
3023 return assign_oper_eval(ctx, expr->expression1, expr->expression2, mul_eval, ei, ret);
3026 /* ECMA-262 3rd Edition 11.13.2 */
3027 HRESULT assign_div_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3029 binary_expression_t *expr = (binary_expression_t*)_expr;
3031 TRACE("\n");
3033 return assign_oper_eval(ctx, expr->expression1, expr->expression2, div_eval, ei, ret);
3036 /* ECMA-262 3rd Edition 11.13.2 */
3037 HRESULT assign_mod_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3039 binary_expression_t *expr = (binary_expression_t*)_expr;
3041 TRACE("\n");
3043 return assign_oper_eval(ctx, expr->expression1, expr->expression2, mod_eval, ei, ret);
3046 /* ECMA-262 3rd Edition 11.13.2 */
3047 HRESULT assign_and_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3049 binary_expression_t *expr = (binary_expression_t*)_expr;
3051 TRACE("\n");
3053 return assign_oper_eval(ctx, expr->expression1, expr->expression2, bitand_eval, ei, ret);
3056 /* ECMA-262 3rd Edition 11.13.2 */
3057 HRESULT assign_or_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3059 binary_expression_t *expr = (binary_expression_t*)_expr;
3061 TRACE("\n");
3063 return assign_oper_eval(ctx, expr->expression1, expr->expression2, bitor_eval, ei, ret);
3066 /* ECMA-262 3rd Edition 11.13.2 */
3067 HRESULT assign_xor_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3069 binary_expression_t *expr = (binary_expression_t*)_expr;
3071 TRACE("\n");
3073 return assign_oper_eval(ctx, expr->expression1, expr->expression2, xor_eval, ei, ret);