cabinet/tests: Make some variables static.
[wine.git] / dlls / jscript / engine.c
blob8aed4db963689da02ad942a0f36cd64366510b2b
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);
60 return;
61 case EXPRVAL_INVALID:
62 SysFreeString(val->u.identifier);
66 /* ECMA-262 3rd Edition 8.7.1 */
67 static HRESULT exprval_value(script_ctx_t *ctx, exprval_t *val, jsexcept_t *ei, VARIANT *ret)
69 V_VT(ret) = VT_EMPTY;
71 switch(val->type) {
72 case EXPRVAL_VARIANT:
73 return VariantCopy(ret, &val->u.var);
74 case EXPRVAL_IDREF:
75 if(!val->u.idref.disp) {
76 FIXME("throw ReferenceError\n");
77 return E_FAIL;
80 return disp_propget(ctx, val->u.idref.disp, val->u.idref.id, ret, ei, NULL/*FIXME*/);
81 case EXPRVAL_NAMEREF:
82 break;
83 case EXPRVAL_INVALID:
84 return throw_type_error(ctx, ei, IDS_UNDEFINED, val->u.identifier);
87 ERR("type %d\n", val->type);
88 return E_FAIL;
91 static HRESULT exprval_to_value(script_ctx_t *ctx, exprval_t *val, jsexcept_t *ei, VARIANT *ret)
93 if(val->type == EXPRVAL_VARIANT) {
94 *ret = val->u.var;
95 V_VT(&val->u.var) = VT_EMPTY;
96 return S_OK;
99 return exprval_value(ctx, val, ei, ret);
102 static HRESULT exprval_to_boolean(script_ctx_t *ctx, exprval_t *exprval, jsexcept_t *ei, VARIANT_BOOL *b)
104 if(exprval->type != EXPRVAL_VARIANT) {
105 VARIANT val;
106 HRESULT hres;
108 hres = exprval_to_value(ctx, exprval, ei, &val);
109 if(FAILED(hres))
110 return hres;
112 hres = to_boolean(&val, b);
113 VariantClear(&val);
114 return hres;
117 return to_boolean(&exprval->u.var, b);
120 static void exprval_init(exprval_t *val)
122 val->type = EXPRVAL_VARIANT;
123 V_VT(&val->u.var) = VT_EMPTY;
126 static void exprval_set_idref(exprval_t *val, IDispatch *disp, DISPID id)
128 val->type = EXPRVAL_IDREF;
129 val->u.idref.disp = disp;
130 val->u.idref.id = id;
132 if(disp)
133 IDispatch_AddRef(disp);
136 HRESULT scope_push(scope_chain_t *scope, jsdisp_t *obj, scope_chain_t **ret)
138 scope_chain_t *new_scope;
140 new_scope = heap_alloc(sizeof(scope_chain_t));
141 if(!new_scope)
142 return E_OUTOFMEMORY;
144 new_scope->ref = 1;
146 jsdisp_addref(obj);
147 new_scope->obj = obj;
149 if(scope) {
150 scope_addref(scope);
151 new_scope->next = scope;
152 }else {
153 new_scope->next = NULL;
156 *ret = new_scope;
157 return S_OK;
160 static void scope_pop(scope_chain_t **scope)
162 scope_chain_t *tmp;
164 tmp = *scope;
165 *scope = tmp->next;
166 scope_release(tmp);
169 void scope_release(scope_chain_t *scope)
171 if(--scope->ref)
172 return;
174 if(scope->next)
175 scope_release(scope->next);
177 jsdisp_release(scope->obj);
178 heap_free(scope);
181 HRESULT create_exec_ctx(script_ctx_t *script_ctx, IDispatch *this_obj, jsdisp_t *var_disp,
182 scope_chain_t *scope, exec_ctx_t **ret)
184 exec_ctx_t *ctx;
186 ctx = heap_alloc_zero(sizeof(exec_ctx_t));
187 if(!ctx)
188 return E_OUTOFMEMORY;
190 ctx->ref = 1;
192 if(this_obj)
193 ctx->this_obj = this_obj;
194 else if(script_ctx->host_global)
195 ctx->this_obj = script_ctx->host_global;
196 else
197 ctx->this_obj = to_disp(script_ctx->global);
198 IDispatch_AddRef(ctx->this_obj);
200 jsdisp_addref(var_disp);
201 ctx->var_disp = var_disp;
203 if(scope) {
204 scope_addref(scope);
205 ctx->scope_chain = scope;
208 *ret = ctx;
209 return S_OK;
212 void exec_release(exec_ctx_t *ctx)
214 if(--ctx->ref)
215 return;
217 if(ctx->scope_chain)
218 scope_release(ctx->scope_chain);
219 if(ctx->var_disp)
220 jsdisp_release(ctx->var_disp);
221 if(ctx->this_obj)
222 IDispatch_Release(ctx->this_obj);
223 heap_free(ctx);
226 static HRESULT disp_get_id(script_ctx_t *ctx, IDispatch *disp, BSTR name, DWORD flags, DISPID *id)
228 IDispatchEx *dispex;
229 HRESULT hres;
231 hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
232 if(FAILED(hres)) {
233 TRACE("unsing IDispatch\n");
235 *id = 0;
236 return IDispatch_GetIDsOfNames(disp, &IID_NULL, &name, 1, 0, id);
239 *id = 0;
240 hres = IDispatchEx_GetDispID(dispex, name, make_grfdex(ctx, flags|fdexNameCaseSensitive), id);
241 IDispatchEx_Release(dispex);
242 return hres;
245 /* ECMA-262 3rd Edition 8.7.2 */
246 static HRESULT put_value(script_ctx_t *ctx, exprval_t *ref, VARIANT *v, jsexcept_t *ei)
248 if(ref->type != EXPRVAL_IDREF)
249 return throw_reference_error(ctx, ei, IDS_ILLEGAL_ASSIGN, NULL);
251 return disp_propput(ctx, ref->u.idref.disp, ref->u.idref.id, v, ei, NULL/*FIXME*/);
254 static inline BOOL is_null(const VARIANT *v)
256 return V_VT(v) == VT_NULL || (V_VT(v) == VT_DISPATCH && !V_DISPATCH(v));
259 static HRESULT disp_cmp(IDispatch *disp1, IDispatch *disp2, BOOL *ret)
261 IObjectIdentity *identity;
262 IUnknown *unk1, *unk2;
263 HRESULT hres;
265 if(disp1 == disp2) {
266 *ret = TRUE;
267 return S_OK;
270 if(!disp1 || !disp2) {
271 *ret = FALSE;
272 return S_OK;
275 hres = IDispatch_QueryInterface(disp1, &IID_IUnknown, (void**)&unk1);
276 if(FAILED(hres))
277 return hres;
279 hres = IDispatch_QueryInterface(disp2, &IID_IUnknown, (void**)&unk2);
280 if(FAILED(hres)) {
281 IUnknown_Release(unk1);
282 return hres;
285 if(unk1 == unk2) {
286 *ret = TRUE;
287 }else {
288 hres = IUnknown_QueryInterface(unk1, &IID_IObjectIdentity, (void**)&identity);
289 if(SUCCEEDED(hres)) {
290 hres = IObjectIdentity_IsEqualObject(identity, unk2);
291 IObjectIdentity_Release(identity);
292 *ret = hres == S_OK;
293 }else {
294 *ret = FALSE;
298 IUnknown_Release(unk1);
299 IUnknown_Release(unk2);
300 return S_OK;
303 /* ECMA-262 3rd Edition 11.9.6 */
304 static HRESULT equal2_values(VARIANT *lval, VARIANT *rval, BOOL *ret)
306 TRACE("\n");
308 if(V_VT(lval) != V_VT(rval)) {
309 if(is_num_vt(V_VT(lval)) && is_num_vt(V_VT(rval)))
310 *ret = num_val(lval) == num_val(rval);
311 else if(is_null(lval))
312 *ret = is_null(rval);
313 else
314 *ret = FALSE;
315 return S_OK;
318 switch(V_VT(lval)) {
319 case VT_EMPTY:
320 case VT_NULL:
321 *ret = VARIANT_TRUE;
322 break;
323 case VT_I4:
324 *ret = V_I4(lval) == V_I4(rval);
325 break;
326 case VT_R8:
327 *ret = V_R8(lval) == V_R8(rval);
328 break;
329 case VT_BSTR:
330 if(!V_BSTR(lval))
331 *ret = SysStringLen(V_BSTR(rval))?FALSE:TRUE;
332 else if(!V_BSTR(rval))
333 *ret = SysStringLen(V_BSTR(lval))?FALSE:TRUE;
334 else
335 *ret = !strcmpW(V_BSTR(lval), V_BSTR(rval));
336 break;
337 case VT_DISPATCH:
338 return disp_cmp(V_DISPATCH(lval), V_DISPATCH(rval), ret);
339 case VT_BOOL:
340 *ret = !V_BOOL(lval) == !V_BOOL(rval);
341 break;
342 default:
343 FIXME("unimplemented vt %d\n", V_VT(lval));
344 return E_NOTIMPL;
347 return S_OK;
350 static HRESULT literal_to_var(script_ctx_t *ctx, literal_t *literal, VARIANT *v)
352 switch(literal->type) {
353 case LT_NULL:
354 V_VT(v) = VT_NULL;
355 break;
356 case LT_INT:
357 V_VT(v) = VT_I4;
358 V_I4(v) = literal->u.lval;
359 break;
360 case LT_DOUBLE:
361 V_VT(v) = VT_R8;
362 V_R8(v) = literal->u.dval;
363 break;
364 case LT_STRING: {
365 BSTR str = SysAllocString(literal->u.wstr);
366 if(!str)
367 return E_OUTOFMEMORY;
369 V_VT(v) = VT_BSTR;
370 V_BSTR(v) = str;
371 break;
373 case LT_BOOL:
374 V_VT(v) = VT_BOOL;
375 V_BOOL(v) = literal->u.bval;
376 break;
377 case LT_REGEXP: {
378 jsdisp_t *regexp;
379 HRESULT hres;
381 hres = create_regexp(ctx, literal->u.regexp.str, literal->u.regexp.str_len,
382 literal->u.regexp.flags, &regexp);
383 if(FAILED(hres))
384 return hres;
386 var_set_jsdisp(v, regexp);
390 return S_OK;
393 static BOOL lookup_global_members(script_ctx_t *ctx, BSTR identifier, exprval_t *ret)
395 named_item_t *item;
396 DISPID id;
397 HRESULT hres;
399 for(item = ctx->named_items; item; item = item->next) {
400 if(item->flags & SCRIPTITEM_GLOBALMEMBERS) {
401 hres = disp_get_id(ctx, item->disp, identifier, 0, &id);
402 if(SUCCEEDED(hres)) {
403 if(ret)
404 exprval_set_idref(ret, item->disp, id);
405 return TRUE;
410 return FALSE;
413 HRESULT exec_source(exec_ctx_t *ctx, parser_ctx_t *parser, source_elements_t *source, exec_type_t exec_type,
414 jsexcept_t *ei, VARIANT *retv)
416 script_ctx_t *script = parser->script;
417 function_declaration_t *func;
418 parser_ctx_t *prev_parser;
419 var_list_t *var;
420 VARIANT val, tmp;
421 statement_t *stat;
422 exec_ctx_t *prev_ctx;
423 return_type_t rt;
424 HRESULT hres = S_OK;
426 for(func = source->functions; func; func = func->next) {
427 jsdisp_t *func_obj;
428 VARIANT var;
430 hres = create_source_function(parser, func->expr->parameter_list, func->expr->source_elements,
431 ctx->scope_chain, func->expr->src_str, func->expr->src_len, &func_obj);
432 if(FAILED(hres))
433 return hres;
435 var_set_jsdisp(&var, func_obj);
436 hres = jsdisp_propput_name(ctx->var_disp, func->expr->identifier, &var, ei, NULL);
437 jsdisp_release(func_obj);
438 if(FAILED(hres))
439 return hres;
442 for(var = source->variables; var; var = var->next) {
443 DISPID id = 0;
444 BSTR name;
446 name = SysAllocString(var->identifier);
447 if(!name)
448 return E_OUTOFMEMORY;
450 if(!lookup_global_members(parser->script, name, NULL))
451 hres = jsdisp_get_id(ctx->var_disp, var->identifier, fdexNameEnsure, &id);
452 SysFreeString(name);
453 if(FAILED(hres))
454 return hres;
457 prev_ctx = script->exec_ctx;
458 script->exec_ctx = ctx;
460 prev_parser = ctx->parser;
461 ctx->parser = parser;
463 V_VT(&val) = VT_EMPTY;
464 memset(&rt, 0, sizeof(rt));
465 rt.type = RT_NORMAL;
467 for(stat = source->statement; stat; stat = stat->next) {
468 hres = stat_eval(ctx, stat, &rt, &tmp);
469 if(FAILED(hres))
470 break;
472 VariantClear(&val);
473 val = tmp;
474 if(rt.type != RT_NORMAL)
475 break;
478 script->exec_ctx = prev_ctx;
479 ctx->parser = prev_parser;
481 if(rt.type != RT_NORMAL && rt.type != RT_RETURN) {
482 FIXME("wrong rt %d\n", rt.type);
483 hres = E_FAIL;
486 *ei = rt.ei;
487 if(FAILED(hres)) {
488 VariantClear(&val);
489 return hres;
492 if(retv && (exec_type == EXECT_EVAL || rt.type == RT_RETURN))
493 *retv = val;
494 else {
495 if (retv) {
496 VariantInit(retv);
498 VariantClear(&val);
500 return S_OK;
503 /* ECMA-262 3rd Edition 10.1.4 */
504 static HRESULT identifier_eval(exec_ctx_t *ctx, BSTR identifier, DWORD flags, jsexcept_t *ei, exprval_t *ret)
506 scope_chain_t *scope;
507 named_item_t *item;
508 DISPID id = 0;
509 HRESULT hres;
511 TRACE("%s\n", debugstr_w(identifier));
513 for(scope = ctx->scope_chain; scope; scope = scope->next) {
514 hres = jsdisp_get_id(scope->obj, identifier, 0, &id);
515 if(SUCCEEDED(hres))
516 break;
519 if(scope) {
520 exprval_set_idref(ret, to_disp(scope->obj), id);
521 return S_OK;
524 hres = jsdisp_get_id(ctx->parser->script->global, identifier, 0, &id);
525 if(SUCCEEDED(hres)) {
526 exprval_set_idref(ret, to_disp(ctx->parser->script->global), id);
527 return S_OK;
530 for(item = ctx->parser->script->named_items; item; item = item->next) {
531 if((item->flags & SCRIPTITEM_ISVISIBLE) && !strcmpW(item->name, identifier)) {
532 if(!item->disp) {
533 IUnknown *unk;
535 if(!ctx->parser->script->site)
536 break;
538 hres = IActiveScriptSite_GetItemInfo(ctx->parser->script->site, identifier,
539 SCRIPTINFO_IUNKNOWN, &unk, NULL);
540 if(FAILED(hres)) {
541 WARN("GetItemInfo failed: %08x\n", hres);
542 break;
545 hres = IUnknown_QueryInterface(unk, &IID_IDispatch, (void**)&item->disp);
546 IUnknown_Release(unk);
547 if(FAILED(hres)) {
548 WARN("object does not implement IDispatch\n");
549 break;
553 ret->type = EXPRVAL_VARIANT;
554 V_VT(&ret->u.var) = VT_DISPATCH;
555 V_DISPATCH(&ret->u.var) = item->disp;
556 IDispatch_AddRef(item->disp);
557 return S_OK;
561 if(lookup_global_members(ctx->parser->script, identifier, ret))
562 return S_OK;
564 if(flags & EXPR_NEWREF) {
565 hres = jsdisp_get_id(ctx->parser->script->global, identifier, fdexNameEnsure, &id);
566 if(FAILED(hres))
567 return hres;
569 exprval_set_idref(ret, to_disp(ctx->parser->script->global), id);
570 return S_OK;
573 ret->type = EXPRVAL_INVALID;
574 ret->u.identifier = SysAllocString(identifier);
575 if(!ret->u.identifier)
576 return E_OUTOFMEMORY;
578 return S_OK;
581 /* ECMA-262 3rd Edition 12.1 */
582 HRESULT block_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
584 block_statement_t *stat = (block_statement_t*)_stat;
585 VARIANT val, tmp;
586 statement_t *iter;
587 HRESULT hres = S_OK;
589 TRACE("\n");
591 V_VT(&val) = VT_EMPTY;
592 for(iter = stat->stat_list; iter; iter = iter->next) {
593 hres = stat_eval(ctx, iter, rt, &tmp);
594 if(FAILED(hres))
595 break;
597 VariantClear(&val);
598 val = tmp;
599 if(rt->type != RT_NORMAL)
600 break;
603 if(FAILED(hres)) {
604 VariantClear(&val);
605 return hres;
608 *ret = val;
609 return S_OK;
612 /* ECMA-262 3rd Edition 12.2 */
613 static HRESULT variable_list_eval(exec_ctx_t *ctx, variable_declaration_t *var_list, jsexcept_t *ei)
615 variable_declaration_t *iter;
616 HRESULT hres = S_OK;
618 for(iter = var_list; iter; iter = iter->next) {
619 exprval_t exprval;
620 VARIANT val;
622 if(!iter->expr)
623 continue;
625 hres = expr_eval(ctx, iter->expr, 0, ei, &exprval);
626 if(FAILED(hres))
627 break;
629 hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
630 exprval_release(&exprval);
631 if(FAILED(hres))
632 break;
634 hres = jsdisp_propput_name(ctx->var_disp, iter->identifier, &val, ei, NULL/*FIXME*/);
635 VariantClear(&val);
636 if(FAILED(hres))
637 break;
640 return hres;
643 /* ECMA-262 3rd Edition 12.2 */
644 HRESULT var_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
646 var_statement_t *stat = (var_statement_t*)_stat;
647 HRESULT hres;
649 TRACE("\n");
651 hres = variable_list_eval(ctx, stat->variable_list, &rt->ei);
652 if(FAILED(hres))
653 return hres;
655 V_VT(ret) = VT_EMPTY;
656 return S_OK;
659 /* ECMA-262 3rd Edition 12.3 */
660 HRESULT empty_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
662 TRACE("\n");
664 V_VT(ret) = VT_EMPTY;
665 return S_OK;
668 /* ECMA-262 3rd Edition 12.4 */
669 HRESULT expression_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
671 expression_statement_t *stat = (expression_statement_t*)_stat;
672 exprval_t exprval;
673 VARIANT val;
674 HRESULT hres;
676 TRACE("\n");
678 hres = expr_eval(ctx, stat->expr, EXPR_NOVAL, &rt->ei, &exprval);
679 if(FAILED(hres))
680 return hres;
682 hres = exprval_to_value(ctx->parser->script, &exprval, &rt->ei, &val);
683 exprval_release(&exprval);
684 if(FAILED(hres))
685 return hres;
687 *ret = val;
688 TRACE("= %s\n", debugstr_variant(ret));
689 return S_OK;
692 /* ECMA-262 3rd Edition 12.5 */
693 HRESULT if_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
695 if_statement_t *stat = (if_statement_t*)_stat;
696 exprval_t exprval;
697 VARIANT_BOOL b;
698 HRESULT hres;
700 TRACE("\n");
702 hres = expr_eval(ctx, stat->expr, 0, &rt->ei, &exprval);
703 if(FAILED(hres))
704 return hres;
706 hres = exprval_to_boolean(ctx->parser->script, &exprval, &rt->ei, &b);
707 exprval_release(&exprval);
708 if(FAILED(hres))
709 return hres;
711 if(b)
712 hres = stat_eval(ctx, stat->if_stat, rt, ret);
713 else if(stat->else_stat)
714 hres = stat_eval(ctx, stat->else_stat, rt, ret);
715 else
716 V_VT(ret) = VT_EMPTY;
718 return hres;
721 /* ECMA-262 3rd Edition 12.6.2 */
722 HRESULT while_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
724 while_statement_t *stat = (while_statement_t*)_stat;
725 exprval_t exprval;
726 VARIANT val, tmp;
727 VARIANT_BOOL b;
728 BOOL test_expr;
729 HRESULT hres;
731 TRACE("\n");
733 V_VT(&val) = VT_EMPTY;
734 test_expr = !stat->do_while;
736 while(1) {
737 if(test_expr) {
738 hres = expr_eval(ctx, stat->expr, 0, &rt->ei, &exprval);
739 if(FAILED(hres))
740 break;
742 hres = exprval_to_boolean(ctx->parser->script, &exprval, &rt->ei, &b);
743 exprval_release(&exprval);
744 if(FAILED(hres) || !b)
745 break;
746 }else {
747 test_expr = TRUE;
750 hres = stat_eval(ctx, stat->statement, rt, &tmp);
751 if(FAILED(hres))
752 break;
754 VariantClear(&val);
755 val = tmp;
757 if(rt->type == RT_CONTINUE)
758 rt->type = RT_NORMAL;
759 if(rt->type != RT_NORMAL)
760 break;
763 if(FAILED(hres)) {
764 VariantClear(&val);
765 return hres;
768 if(rt->type == RT_BREAK)
769 rt->type = RT_NORMAL;
771 *ret = val;
772 return S_OK;
775 /* ECMA-262 3rd Edition 12.6.3 */
776 HRESULT for_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
778 for_statement_t *stat = (for_statement_t*)_stat;
779 VARIANT val, tmp, retv;
780 exprval_t exprval;
781 VARIANT_BOOL b;
782 HRESULT hres;
784 TRACE("\n");
786 if(stat->variable_list) {
787 hres = variable_list_eval(ctx, stat->variable_list, &rt->ei);
788 if(FAILED(hres))
789 return hres;
790 }else if(stat->begin_expr) {
791 hres = expr_eval(ctx, stat->begin_expr, EXPR_NEWREF, &rt->ei, &exprval);
792 if(FAILED(hres))
793 return hres;
795 hres = exprval_to_value(ctx->parser->script, &exprval, &rt->ei, &val);
796 exprval_release(&exprval);
797 if(FAILED(hres))
798 return hres;
800 VariantClear(&val);
803 V_VT(&retv) = VT_EMPTY;
805 while(1) {
806 if(stat->expr) {
807 hres = expr_eval(ctx, stat->expr, 0, &rt->ei, &exprval);
808 if(FAILED(hres))
809 break;
811 hres = exprval_to_boolean(ctx->parser->script, &exprval, &rt->ei, &b);
812 exprval_release(&exprval);
813 if(FAILED(hres) || !b)
814 break;
817 hres = stat_eval(ctx, stat->statement, rt, &tmp);
818 if(FAILED(hres))
819 break;
821 VariantClear(&retv);
822 retv = tmp;
824 if(rt->type == RT_CONTINUE)
825 rt->type = RT_NORMAL;
826 else if(rt->type != RT_NORMAL)
827 break;
829 if(stat->end_expr) {
830 hres = expr_eval(ctx, stat->end_expr, 0, &rt->ei, &exprval);
831 if(FAILED(hres))
832 break;
834 hres = exprval_to_value(ctx->parser->script, &exprval, &rt->ei, &val);
835 exprval_release(&exprval);
836 if(FAILED(hres))
837 break;
839 VariantClear(&val);
843 if(FAILED(hres)) {
844 VariantClear(&retv);
845 return hres;
848 if(rt->type == RT_BREAK)
849 rt->type = RT_NORMAL;
851 *ret = retv;
852 return S_OK;
855 /* ECMA-262 3rd Edition 12.6.4 */
856 HRESULT forin_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
858 forin_statement_t *stat = (forin_statement_t*)_stat;
859 VARIANT val, name, retv, tmp;
860 DISPID id = DISPID_STARTENUM;
861 BSTR str, identifier = NULL;
862 IDispatchEx *in_obj;
863 exprval_t exprval;
864 HRESULT hres;
866 TRACE("\n");
868 if(stat->variable) {
869 hres = variable_list_eval(ctx, stat->variable, &rt->ei);
870 if(FAILED(hres))
871 return hres;
874 hres = expr_eval(ctx, stat->in_expr, EXPR_NEWREF, &rt->ei, &exprval);
875 if(FAILED(hres))
876 return hres;
878 hres = exprval_to_value(ctx->parser->script, &exprval, &rt->ei, &val);
879 exprval_release(&exprval);
880 if(FAILED(hres))
881 return hres;
883 if(V_VT(&val) != VT_DISPATCH) {
884 TRACE("in vt %d\n", V_VT(&val));
885 VariantClear(&val);
886 V_VT(ret) = VT_EMPTY;
887 return S_OK;
890 hres = IDispatch_QueryInterface(V_DISPATCH(&val), &IID_IDispatchEx, (void**)&in_obj);
891 IDispatch_Release(V_DISPATCH(&val));
892 if(FAILED(hres)) {
893 FIXME("Object doesn't support IDispatchEx\n");
894 return E_NOTIMPL;
897 V_VT(&retv) = VT_EMPTY;
899 if(stat->variable)
900 identifier = SysAllocString(stat->variable->identifier);
902 while(1) {
903 hres = IDispatchEx_GetNextDispID(in_obj, fdexEnumDefault, id, &id);
904 if(FAILED(hres) || hres == S_FALSE)
905 break;
907 hres = IDispatchEx_GetMemberName(in_obj, id, &str);
908 if(FAILED(hres))
909 break;
911 TRACE("iter %s\n", debugstr_w(str));
913 if(stat->variable)
914 hres = identifier_eval(ctx, identifier, 0, NULL, &exprval);
915 else
916 hres = expr_eval(ctx, stat->expr, EXPR_NEWREF, &rt->ei, &exprval);
917 if(SUCCEEDED(hres)) {
918 V_VT(&name) = VT_BSTR;
919 V_BSTR(&name) = str;
920 hres = put_value(ctx->parser->script, &exprval, &name, &rt->ei);
921 exprval_release(&exprval);
923 SysFreeString(str);
924 if(FAILED(hres))
925 break;
927 hres = stat_eval(ctx, stat->statement, rt, &tmp);
928 if(FAILED(hres))
929 break;
931 VariantClear(&retv);
932 retv = tmp;
934 if(rt->type == RT_CONTINUE)
935 rt->type = RT_NORMAL;
936 else if(rt->type != RT_NORMAL)
937 break;
940 SysFreeString(identifier);
941 IDispatchEx_Release(in_obj);
942 if(FAILED(hres)) {
943 VariantClear(&retv);
944 return hres;
947 if(rt->type == RT_BREAK)
948 rt->type = RT_NORMAL;
950 *ret = retv;
951 return S_OK;
954 /* ECMA-262 3rd Edition 12.7 */
955 HRESULT continue_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
957 branch_statement_t *stat = (branch_statement_t*)_stat;
959 TRACE("\n");
961 if(stat->identifier) {
962 FIXME("indentifier not implemented\n");
963 return E_NOTIMPL;
966 rt->type = RT_CONTINUE;
967 V_VT(ret) = VT_EMPTY;
968 return S_OK;
971 /* ECMA-262 3rd Edition 12.8 */
972 HRESULT break_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
974 branch_statement_t *stat = (branch_statement_t*)_stat;
976 TRACE("\n");
978 if(stat->identifier) {
979 FIXME("indentifier not implemented\n");
980 return E_NOTIMPL;
983 rt->type = RT_BREAK;
984 V_VT(ret) = VT_EMPTY;
985 return S_OK;
988 /* ECMA-262 3rd Edition 12.9 */
989 HRESULT return_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
991 expression_statement_t *stat = (expression_statement_t*)_stat;
992 HRESULT hres;
994 TRACE("\n");
996 if(stat->expr) {
997 exprval_t exprval;
999 hres = expr_eval(ctx, stat->expr, 0, &rt->ei, &exprval);
1000 if(FAILED(hres))
1001 return hres;
1003 hres = exprval_to_value(ctx->parser->script, &exprval, &rt->ei, ret);
1004 exprval_release(&exprval);
1005 if(FAILED(hres))
1006 return hres;
1007 }else {
1008 V_VT(ret) = VT_EMPTY;
1011 TRACE("= %s\n", debugstr_variant(ret));
1012 rt->type = RT_RETURN;
1013 return S_OK;
1016 /* ECMA-262 3rd Edition 12.10 */
1017 HRESULT with_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
1019 with_statement_t *stat = (with_statement_t*)_stat;
1020 exprval_t exprval;
1021 IDispatch *disp;
1022 jsdisp_t *obj;
1023 VARIANT val;
1024 HRESULT hres;
1026 TRACE("\n");
1028 hres = expr_eval(ctx, stat->expr, 0, &rt->ei, &exprval);
1029 if(FAILED(hres))
1030 return hres;
1032 hres = exprval_to_value(ctx->parser->script, &exprval, &rt->ei, &val);
1033 exprval_release(&exprval);
1034 if(FAILED(hres))
1035 return hres;
1037 hres = to_object(ctx->parser->script, &val, &disp);
1038 VariantClear(&val);
1039 if(FAILED(hres))
1040 return hres;
1042 obj = iface_to_jsdisp((IUnknown*)disp);
1043 IDispatch_Release(disp);
1044 if(!obj) {
1045 FIXME("disp id not jsdisp\n");
1046 return E_NOTIMPL;
1049 hres = scope_push(ctx->scope_chain, obj, &ctx->scope_chain);
1050 jsdisp_release(obj);
1051 if(FAILED(hres))
1052 return hres;
1054 hres = stat_eval(ctx, stat->statement, rt, ret);
1056 scope_pop(&ctx->scope_chain);
1057 return hres;
1060 /* ECMA-262 3rd Edition 12.12 */
1061 HRESULT labelled_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
1063 FIXME("\n");
1064 return E_NOTIMPL;
1067 /* ECMA-262 3rd Edition 12.13 */
1068 HRESULT switch_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
1070 switch_statement_t *stat = (switch_statement_t*)_stat;
1071 case_clausule_t *iter, *default_clausule = NULL;
1072 statement_t *stat_iter;
1073 VARIANT val, cval;
1074 exprval_t exprval;
1075 BOOL b;
1076 HRESULT hres;
1078 TRACE("\n");
1080 hres = expr_eval(ctx, stat->expr, 0, &rt->ei, &exprval);
1081 if(FAILED(hres))
1082 return hres;
1084 hres = exprval_to_value(ctx->parser->script, &exprval, &rt->ei, &val);
1085 exprval_release(&exprval);
1086 if(FAILED(hres))
1087 return hres;
1089 for(iter = stat->case_list; iter; iter = iter->next) {
1090 if(!iter->expr) {
1091 default_clausule = iter;
1092 continue;
1095 hres = expr_eval(ctx, iter->expr, 0, &rt->ei, &exprval);
1096 if(FAILED(hres))
1097 break;
1099 hres = exprval_to_value(ctx->parser->script, &exprval, &rt->ei, &cval);
1100 exprval_release(&exprval);
1101 if(FAILED(hres))
1102 break;
1104 hres = equal2_values(&val, &cval, &b);
1105 VariantClear(&cval);
1106 if(FAILED(hres) || b)
1107 break;
1110 VariantClear(&val);
1111 if(FAILED(hres))
1112 return hres;
1114 if(!iter)
1115 iter = default_clausule;
1117 V_VT(&val) = VT_EMPTY;
1118 if(iter) {
1119 VARIANT tmp;
1121 for(stat_iter = iter->stat; stat_iter; stat_iter = stat_iter->next) {
1122 hres = stat_eval(ctx, stat_iter, rt, &tmp);
1123 if(FAILED(hres))
1124 break;
1126 VariantClear(&val);
1127 val = tmp;
1129 if(rt->type != RT_NORMAL)
1130 break;
1134 if(FAILED(hres)) {
1135 VariantClear(&val);
1136 return hres;
1139 if(rt->type == RT_BREAK)
1140 rt->type = RT_NORMAL;
1142 *ret = val;
1143 return S_OK;
1146 /* ECMA-262 3rd Edition 12.13 */
1147 HRESULT throw_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
1149 expression_statement_t *stat = (expression_statement_t*)_stat;
1150 exprval_t exprval;
1151 VARIANT val;
1152 HRESULT hres;
1154 TRACE("\n");
1156 hres = expr_eval(ctx, stat->expr, 0, &rt->ei, &exprval);
1157 if(FAILED(hres))
1158 return hres;
1160 hres = exprval_to_value(ctx->parser->script, &exprval, &rt->ei, &val);
1161 exprval_release(&exprval);
1162 if(FAILED(hres))
1163 return hres;
1165 rt->ei.var = val;
1166 return DISP_E_EXCEPTION;
1169 /* ECMA-262 3rd Edition 12.14 */
1170 static HRESULT catch_eval(exec_ctx_t *ctx, catch_block_t *block, return_type_t *rt, VARIANT *ret)
1172 jsdisp_t *var_disp;
1173 VARIANT ex, val;
1174 HRESULT hres;
1176 ex = rt->ei.var;
1177 memset(&rt->ei, 0, sizeof(jsexcept_t));
1179 hres = create_dispex(ctx->parser->script, NULL, NULL, &var_disp);
1180 if(SUCCEEDED(hres)) {
1181 hres = jsdisp_propput_name(var_disp, block->identifier, &ex, &rt->ei, NULL/*FIXME*/);
1182 if(SUCCEEDED(hres)) {
1183 hres = scope_push(ctx->scope_chain, var_disp, &ctx->scope_chain);
1184 if(SUCCEEDED(hres)) {
1185 hres = stat_eval(ctx, block->statement, rt, &val);
1186 scope_pop(&ctx->scope_chain);
1190 jsdisp_release(var_disp);
1193 VariantClear(&ex);
1194 if(FAILED(hres))
1195 return hres;
1197 *ret = val;
1198 return S_OK;
1201 /* ECMA-262 3rd Edition 12.14 */
1202 HRESULT try_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
1204 try_statement_t *stat = (try_statement_t*)_stat;
1205 VARIANT val;
1206 HRESULT hres;
1208 TRACE("\n");
1210 hres = stat_eval(ctx, stat->try_statement, rt, &val);
1211 if(FAILED(hres)) {
1212 TRACE("EXCEPTION\n");
1213 if(!stat->catch_block)
1214 return hres;
1216 hres = catch_eval(ctx, stat->catch_block, rt, &val);
1217 if(FAILED(hres))
1218 return hres;
1221 if(stat->finally_statement) {
1222 VariantClear(&val);
1223 hres = stat_eval(ctx, stat->finally_statement, rt, &val);
1224 if(FAILED(hres))
1225 return hres;
1228 *ret = val;
1229 return S_OK;
1232 static HRESULT return_bool(exprval_t *ret, DWORD b)
1234 ret->type = EXPRVAL_VARIANT;
1235 V_VT(&ret->u.var) = VT_BOOL;
1236 V_BOOL(&ret->u.var) = b ? VARIANT_TRUE : VARIANT_FALSE;
1238 return S_OK;
1241 static HRESULT get_binary_expr_values(exec_ctx_t *ctx, binary_expression_t *expr, jsexcept_t *ei, VARIANT *lval, VARIANT *rval)
1243 exprval_t exprval;
1244 HRESULT hres;
1246 hres = expr_eval(ctx, expr->expression1, 0, ei, &exprval);
1247 if(FAILED(hres))
1248 return hres;
1250 hres = exprval_to_value(ctx->parser->script, &exprval, ei, lval);
1251 exprval_release(&exprval);
1252 if(FAILED(hres))
1253 return hres;
1255 hres = expr_eval(ctx, expr->expression2, 0, ei, &exprval);
1256 if(SUCCEEDED(hres)) {
1257 hres = exprval_to_value(ctx->parser->script, &exprval, ei, rval);
1258 exprval_release(&exprval);
1261 if(FAILED(hres)) {
1262 VariantClear(lval);
1263 return hres;
1266 return S_OK;
1269 typedef HRESULT (*oper_t)(exec_ctx_t*,VARIANT*,VARIANT*,jsexcept_t*,VARIANT*);
1271 static HRESULT binary_expr_eval(exec_ctx_t *ctx, binary_expression_t *expr, oper_t oper, jsexcept_t *ei,
1272 exprval_t *ret)
1274 VARIANT lval, rval, retv;
1275 HRESULT hres;
1277 hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval);
1278 if(FAILED(hres))
1279 return hres;
1281 hres = oper(ctx, &lval, &rval, ei, &retv);
1282 VariantClear(&lval);
1283 VariantClear(&rval);
1284 if(FAILED(hres))
1285 return hres;
1287 ret->type = EXPRVAL_VARIANT;
1288 ret->u.var = retv;
1289 return S_OK;
1292 /* ECMA-262 3rd Edition 11.13.2 */
1293 static HRESULT assign_oper_eval(exec_ctx_t *ctx, expression_t *lexpr, expression_t *rexpr, oper_t oper,
1294 jsexcept_t *ei, exprval_t *ret)
1296 VARIANT retv, lval, rval;
1297 exprval_t exprval, exprvalr;
1298 HRESULT hres;
1300 hres = expr_eval(ctx, lexpr, EXPR_NEWREF, ei, &exprval);
1301 if(FAILED(hres))
1302 return hres;
1304 hres = exprval_value(ctx->parser->script, &exprval, ei, &lval);
1305 if(SUCCEEDED(hres)) {
1306 hres = expr_eval(ctx, rexpr, 0, ei, &exprvalr);
1307 if(SUCCEEDED(hres)) {
1308 hres = exprval_value(ctx->parser->script, &exprvalr, ei, &rval);
1309 exprval_release(&exprvalr);
1311 if(SUCCEEDED(hres)) {
1312 hres = oper(ctx, &lval, &rval, ei, &retv);
1313 VariantClear(&rval);
1315 VariantClear(&lval);
1318 if(SUCCEEDED(hres)) {
1319 hres = put_value(ctx->parser->script, &exprval, &retv, ei);
1320 if(FAILED(hres))
1321 VariantClear(&retv);
1323 exprval_release(&exprval);
1325 if(FAILED(hres))
1326 return hres;
1328 ret->type = EXPRVAL_VARIANT;
1329 ret->u.var = retv;
1330 return S_OK;
1333 /* ECMA-262 3rd Edition 13 */
1334 HRESULT function_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1336 function_expression_t *expr = (function_expression_t*)_expr;
1337 VARIANT var;
1338 HRESULT hres;
1340 TRACE("\n");
1342 if(expr->identifier) {
1343 hres = jsdisp_propget_name(ctx->var_disp, expr->identifier, &var, ei, NULL/*FIXME*/);
1344 if(FAILED(hres))
1345 return hres;
1346 }else {
1347 jsdisp_t *dispex;
1349 hres = create_source_function(ctx->parser, expr->parameter_list, expr->source_elements, ctx->scope_chain,
1350 expr->src_str, expr->src_len, &dispex);
1351 if(FAILED(hres))
1352 return hres;
1354 var_set_jsdisp(&var, dispex);
1357 ret->type = EXPRVAL_VARIANT;
1358 ret->u.var = var;
1359 return S_OK;
1362 /* ECMA-262 3rd Edition 11.12 */
1363 HRESULT conditional_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1365 conditional_expression_t *expr = (conditional_expression_t*)_expr;
1366 exprval_t exprval;
1367 VARIANT_BOOL b;
1368 HRESULT hres;
1370 TRACE("\n");
1372 hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
1373 if(FAILED(hres))
1374 return hres;
1376 hres = exprval_to_boolean(ctx->parser->script, &exprval, ei, &b);
1377 exprval_release(&exprval);
1378 if(FAILED(hres))
1379 return hres;
1381 return expr_eval(ctx, b ? expr->true_expression : expr->false_expression, flags, ei, ret);
1384 /* ECMA-262 3rd Edition 11.2.1 */
1385 HRESULT array_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1387 array_expression_t *expr = (array_expression_t*)_expr;
1388 exprval_t exprval;
1389 VARIANT member, val;
1390 DISPID id;
1391 BSTR str;
1392 IDispatch *obj = NULL;
1393 HRESULT hres;
1395 TRACE("\n");
1397 hres = expr_eval(ctx, expr->member_expr, 0, ei, &exprval);
1398 if(FAILED(hres))
1399 return hres;
1401 hres = exprval_to_value(ctx->parser->script, &exprval, ei, &member);
1402 exprval_release(&exprval);
1403 if(FAILED(hres))
1404 return hres;
1406 hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval);
1407 if(SUCCEEDED(hres)) {
1408 hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
1409 exprval_release(&exprval);
1412 if(SUCCEEDED(hres)) {
1413 hres = to_object(ctx->parser->script, &member, &obj);
1414 if(FAILED(hres))
1415 VariantClear(&val);
1417 VariantClear(&member);
1418 if(SUCCEEDED(hres)) {
1419 hres = to_string(ctx->parser->script, &val, ei, &str);
1420 VariantClear(&val);
1421 if(SUCCEEDED(hres)) {
1422 if(flags & EXPR_STRREF) {
1423 ret->type = EXPRVAL_NAMEREF;
1424 ret->u.nameref.disp = obj;
1425 ret->u.nameref.name = str;
1426 return S_OK;
1429 hres = disp_get_id(ctx->parser->script, obj, str, flags & EXPR_NEWREF ? fdexNameEnsure : 0, &id);
1430 SysFreeString(str);
1433 if(SUCCEEDED(hres)) {
1434 exprval_set_idref(ret, obj, id);
1435 }else if(!(flags & EXPR_NEWREF) && hres == DISP_E_UNKNOWNNAME) {
1436 exprval_init(ret);
1437 hres = S_OK;
1440 IDispatch_Release(obj);
1443 return hres;
1446 /* ECMA-262 3rd Edition 11.2.1 */
1447 HRESULT member_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1449 member_expression_t *expr = (member_expression_t*)_expr;
1450 IDispatch *obj = NULL;
1451 exprval_t exprval;
1452 VARIANT member;
1453 DISPID id;
1454 BSTR str;
1455 HRESULT hres;
1457 TRACE("\n");
1459 hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
1460 if(FAILED(hres))
1461 return hres;
1463 hres = exprval_to_value(ctx->parser->script, &exprval, ei, &member);
1464 exprval_release(&exprval);
1465 if(FAILED(hres))
1466 return hres;
1468 hres = to_object(ctx->parser->script, &member, &obj);
1469 VariantClear(&member);
1470 if(FAILED(hres))
1471 return hres;
1473 str = SysAllocString(expr->identifier);
1474 if(flags & EXPR_STRREF) {
1475 ret->type = EXPRVAL_NAMEREF;
1476 ret->u.nameref.disp = obj;
1477 ret->u.nameref.name = str;
1478 return S_OK;
1481 hres = disp_get_id(ctx->parser->script, obj, str, flags & EXPR_NEWREF ? fdexNameEnsure : 0, &id);
1482 SysFreeString(str);
1483 if(SUCCEEDED(hres)) {
1484 exprval_set_idref(ret, obj, id);
1485 }else if(!(flags & EXPR_NEWREF) && hres == DISP_E_UNKNOWNNAME) {
1486 exprval_init(ret);
1487 hres = S_OK;
1490 IDispatch_Release(obj);
1491 return hres;
1494 static void free_dp(DISPPARAMS *dp)
1496 DWORD i;
1498 for(i=0; i < dp->cArgs; i++)
1499 VariantClear(dp->rgvarg+i);
1500 heap_free(dp->rgvarg);
1503 static HRESULT args_to_param(exec_ctx_t *ctx, argument_t *args, jsexcept_t *ei, DISPPARAMS *dp)
1505 VARIANTARG *vargs;
1506 exprval_t exprval;
1507 argument_t *iter;
1508 DWORD cnt = 0, i;
1509 HRESULT hres = S_OK;
1511 memset(dp, 0, sizeof(*dp));
1512 if(!args)
1513 return S_OK;
1515 for(iter = args; iter; iter = iter->next)
1516 cnt++;
1518 vargs = heap_alloc_zero(cnt * sizeof(*vargs));
1519 if(!vargs)
1520 return E_OUTOFMEMORY;
1522 for(i = cnt, iter = args; iter; iter = iter->next) {
1523 hres = expr_eval(ctx, iter->expr, 0, ei, &exprval);
1524 if(FAILED(hres))
1525 break;
1527 hres = exprval_to_value(ctx->parser->script, &exprval, ei, vargs + (--i));
1528 exprval_release(&exprval);
1529 if(FAILED(hres))
1530 break;
1533 if(FAILED(hres)) {
1534 free_dp(dp);
1535 return hres;
1538 dp->rgvarg = vargs;
1539 dp->cArgs = cnt;
1540 return S_OK;
1543 /* ECMA-262 3rd Edition 11.2.2 */
1544 HRESULT new_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1546 call_expression_t *expr = (call_expression_t*)_expr;
1547 exprval_t exprval;
1548 VARIANT constr, var;
1549 DISPPARAMS dp;
1550 HRESULT hres;
1552 TRACE("\n");
1554 hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
1555 if(FAILED(hres))
1556 return hres;
1558 hres = args_to_param(ctx, expr->argument_list, ei, &dp);
1559 if(SUCCEEDED(hres))
1560 hres = exprval_to_value(ctx->parser->script, &exprval, ei, &constr);
1561 exprval_release(&exprval);
1562 if(FAILED(hres))
1563 return hres;
1565 if(V_VT(&constr) != VT_DISPATCH) {
1566 FIXME("throw TypeError\n");
1567 VariantClear(&constr);
1568 return E_FAIL;
1571 hres = disp_call(ctx->parser->script, V_DISPATCH(&constr), DISPID_VALUE,
1572 DISPATCH_CONSTRUCT, &dp, &var, ei, NULL/*FIXME*/);
1573 IDispatch_Release(V_DISPATCH(&constr));
1574 free_dp(&dp);
1575 if(FAILED(hres))
1576 return hres;
1578 ret->type = EXPRVAL_VARIANT;
1579 ret->u.var = var;
1580 return S_OK;
1583 /* ECMA-262 3rd Edition 11.2.3 */
1584 HRESULT call_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1586 call_expression_t *expr = (call_expression_t*)_expr;
1587 VARIANT var;
1588 exprval_t exprval;
1589 DISPPARAMS dp;
1590 HRESULT hres;
1592 TRACE("\n");
1594 hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
1595 if(FAILED(hres))
1596 return hres;
1598 hres = args_to_param(ctx, expr->argument_list, ei, &dp);
1599 if(SUCCEEDED(hres)) {
1600 switch(exprval.type) {
1601 case EXPRVAL_VARIANT:
1602 if(V_VT(&exprval.u.var) == VT_DISPATCH)
1603 hres = disp_call(ctx->parser->script, V_DISPATCH(&exprval.u.var), DISPID_VALUE,
1604 DISPATCH_METHOD, &dp, flags & EXPR_NOVAL ? NULL : &var, ei, NULL/*FIXME*/);
1605 else
1606 hres = throw_type_error(ctx->parser->script, ei, IDS_NO_PROPERTY, NULL);
1607 break;
1608 case EXPRVAL_IDREF:
1609 hres = disp_call(ctx->parser->script, exprval.u.idref.disp, exprval.u.idref.id,
1610 DISPATCH_METHOD, &dp, flags & EXPR_NOVAL ? NULL : &var, ei, NULL/*FIXME*/);
1611 break;
1612 case EXPRVAL_INVALID:
1613 hres = throw_type_error(ctx->parser->script, ei, IDS_OBJECT_EXPECTED, NULL);
1614 break;
1615 default:
1616 FIXME("unimplemented type %d\n", exprval.type);
1617 hres = E_NOTIMPL;
1620 free_dp(&dp);
1623 exprval_release(&exprval);
1624 if(FAILED(hres))
1625 return hres;
1627 ret->type = EXPRVAL_VARIANT;
1628 if(flags & EXPR_NOVAL) {
1629 V_VT(&ret->u.var) = VT_EMPTY;
1630 }else {
1631 TRACE("= %s\n", debugstr_variant(&var));
1632 ret->u.var = var;
1634 return S_OK;
1637 /* ECMA-262 3rd Edition 11.1.1 */
1638 HRESULT this_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1640 TRACE("\n");
1642 ret->type = EXPRVAL_VARIANT;
1643 V_VT(&ret->u.var) = VT_DISPATCH;
1644 V_DISPATCH(&ret->u.var) = ctx->this_obj;
1645 IDispatch_AddRef(ctx->this_obj);
1646 return S_OK;
1649 /* ECMA-262 3rd Edition 10.1.4 */
1650 HRESULT identifier_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1652 identifier_expression_t *expr = (identifier_expression_t*)_expr;
1653 BSTR identifier;
1654 HRESULT hres;
1656 TRACE("\n");
1658 identifier = SysAllocString(expr->identifier);
1659 if(!identifier)
1660 return E_OUTOFMEMORY;
1662 hres = identifier_eval(ctx, identifier, flags, ei, ret);
1664 SysFreeString(identifier);
1665 return hres;
1668 /* ECMA-262 3rd Edition 7.8 */
1669 HRESULT literal_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1671 literal_expression_t *expr = (literal_expression_t*)_expr;
1672 VARIANT var;
1673 HRESULT hres;
1675 TRACE("\n");
1677 hres = literal_to_var(ctx->parser->script, expr->literal, &var);
1678 if(FAILED(hres))
1679 return hres;
1681 ret->type = EXPRVAL_VARIANT;
1682 ret->u.var = var;
1683 return S_OK;
1686 /* ECMA-262 3rd Edition 11.1.4 */
1687 HRESULT array_literal_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1689 array_literal_expression_t *expr = (array_literal_expression_t*)_expr;
1690 DWORD length = 0, i = 0;
1691 array_element_t *elem;
1692 jsdisp_t *array;
1693 exprval_t exprval;
1694 VARIANT val;
1695 HRESULT hres;
1697 TRACE("\n");
1699 for(elem = expr->element_list; elem; elem = elem->next)
1700 length += elem->elision+1;
1701 length += expr->length;
1703 hres = create_array(ctx->parser->script, length, &array);
1704 if(FAILED(hres))
1705 return hres;
1707 for(elem = expr->element_list; elem; elem = elem->next) {
1708 i += elem->elision;
1710 hres = expr_eval(ctx, elem->expr, 0, ei, &exprval);
1711 if(FAILED(hres))
1712 break;
1714 hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
1715 exprval_release(&exprval);
1716 if(FAILED(hres))
1717 break;
1719 hres = jsdisp_propput_idx(array, i, &val, ei, NULL/*FIXME*/);
1720 VariantClear(&val);
1721 if(FAILED(hres))
1722 break;
1724 i++;
1727 if(FAILED(hres)) {
1728 jsdisp_release(array);
1729 return hres;
1732 ret->type = EXPRVAL_VARIANT;
1733 var_set_jsdisp(&ret->u.var, array);
1734 return S_OK;
1737 /* ECMA-262 3rd Edition 11.1.5 */
1738 HRESULT property_value_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1740 property_value_expression_t *expr = (property_value_expression_t*)_expr;
1741 VARIANT val, tmp;
1742 jsdisp_t *obj;
1743 prop_val_t *iter;
1744 exprval_t exprval;
1745 BSTR name;
1746 HRESULT hres;
1748 TRACE("\n");
1750 hres = create_object(ctx->parser->script, NULL, &obj);
1751 if(FAILED(hres))
1752 return hres;
1754 for(iter = expr->property_list; iter; iter = iter->next) {
1755 hres = literal_to_var(ctx->parser->script, iter->name, &tmp);
1756 if(FAILED(hres))
1757 break;
1759 hres = to_string(ctx->parser->script, &tmp, ei, &name);
1760 VariantClear(&tmp);
1761 if(FAILED(hres))
1762 break;
1764 hres = expr_eval(ctx, iter->value, 0, ei, &exprval);
1765 if(SUCCEEDED(hres)) {
1766 hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
1767 exprval_release(&exprval);
1768 if(SUCCEEDED(hres)) {
1769 hres = jsdisp_propput_name(obj, name, &val, ei, NULL/*FIXME*/);
1770 VariantClear(&val);
1774 SysFreeString(name);
1775 if(FAILED(hres))
1776 break;
1779 if(FAILED(hres)) {
1780 jsdisp_release(obj);
1781 return hres;
1784 ret->type = EXPRVAL_VARIANT;
1785 var_set_jsdisp(&ret->u.var, obj);
1786 return S_OK;
1789 /* ECMA-262 3rd Edition 11.14 */
1790 HRESULT comma_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1792 binary_expression_t *expr = (binary_expression_t*)_expr;
1793 VARIANT lval, rval;
1794 HRESULT hres;
1796 TRACE("\n");
1798 hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval);
1799 if(FAILED(hres))
1800 return hres;
1802 VariantClear(&lval);
1804 ret->type = EXPRVAL_VARIANT;
1805 ret->u.var = rval;
1806 return S_OK;
1809 /* ECMA-262 3rd Edition 11.11 */
1810 HRESULT logical_or_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1812 binary_expression_t *expr = (binary_expression_t*)_expr;
1813 exprval_t exprval;
1814 VARIANT_BOOL b;
1815 VARIANT val;
1816 HRESULT hres;
1818 TRACE("\n");
1820 hres = expr_eval(ctx, expr->expression1, 0, ei, &exprval);
1821 if(FAILED(hres))
1822 return hres;
1824 hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
1825 exprval_release(&exprval);
1826 if(FAILED(hres))
1827 return hres;
1829 hres = to_boolean(&val, &b);
1830 if(SUCCEEDED(hres) && b) {
1831 ret->type = EXPRVAL_VARIANT;
1832 ret->u.var = val;
1833 return S_OK;
1836 VariantClear(&val);
1837 if(FAILED(hres))
1838 return hres;
1840 hres = expr_eval(ctx, expr->expression2, 0, ei, &exprval);
1841 if(FAILED(hres))
1842 return hres;
1844 hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
1845 exprval_release(&exprval);
1846 if(FAILED(hres))
1847 return hres;
1849 ret->type = EXPRVAL_VARIANT;
1850 ret->u.var = val;
1851 return S_OK;
1854 /* ECMA-262 3rd Edition 11.11 */
1855 HRESULT logical_and_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1857 binary_expression_t *expr = (binary_expression_t*)_expr;
1858 exprval_t exprval;
1859 VARIANT_BOOL b;
1860 VARIANT val;
1861 HRESULT hres;
1863 TRACE("\n");
1865 hres = expr_eval(ctx, expr->expression1, 0, ei, &exprval);
1866 if(FAILED(hres))
1867 return hres;
1869 hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
1870 exprval_release(&exprval);
1871 if(FAILED(hres))
1872 return hres;
1874 hres = to_boolean(&val, &b);
1875 if(SUCCEEDED(hres) && !b) {
1876 ret->type = EXPRVAL_VARIANT;
1877 ret->u.var = val;
1878 return S_OK;
1881 VariantClear(&val);
1882 if(FAILED(hres))
1883 return hres;
1885 hres = expr_eval(ctx, expr->expression2, 0, ei, &exprval);
1886 if(FAILED(hres))
1887 return hres;
1889 hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
1890 exprval_release(&exprval);
1891 if(FAILED(hres))
1892 return hres;
1894 ret->type = EXPRVAL_VARIANT;
1895 ret->u.var = val;
1896 return S_OK;
1899 /* ECMA-262 3rd Edition 11.10 */
1900 static HRESULT bitor_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
1902 INT li, ri;
1903 HRESULT hres;
1905 hres = to_int32(ctx->parser->script, lval, ei, &li);
1906 if(FAILED(hres))
1907 return hres;
1909 hres = to_int32(ctx->parser->script, rval, ei, &ri);
1910 if(FAILED(hres))
1911 return hres;
1913 V_VT(retv) = VT_I4;
1914 V_I4(retv) = li|ri;
1915 return S_OK;
1918 /* ECMA-262 3rd Edition 11.10 */
1919 HRESULT binary_or_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1921 binary_expression_t *expr = (binary_expression_t*)_expr;
1923 TRACE("\n");
1925 return binary_expr_eval(ctx, expr, bitor_eval, ei, ret);
1928 /* ECMA-262 3rd Edition 11.10 */
1929 static HRESULT xor_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
1931 INT li, ri;
1932 HRESULT hres;
1934 hres = to_int32(ctx->parser->script, lval, ei, &li);
1935 if(FAILED(hres))
1936 return hres;
1938 hres = to_int32(ctx->parser->script, rval, ei, &ri);
1939 if(FAILED(hres))
1940 return hres;
1942 V_VT(retv) = VT_I4;
1943 V_I4(retv) = li^ri;
1944 return S_OK;
1947 /* ECMA-262 3rd Edition 11.10 */
1948 HRESULT binary_xor_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1950 binary_expression_t *expr = (binary_expression_t*)_expr;
1952 TRACE("\n");
1954 return binary_expr_eval(ctx, expr, xor_eval, ei, ret);
1957 /* ECMA-262 3rd Edition 11.10 */
1958 static HRESULT bitand_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
1960 INT li, ri;
1961 HRESULT hres;
1963 hres = to_int32(ctx->parser->script, lval, ei, &li);
1964 if(FAILED(hres))
1965 return hres;
1967 hres = to_int32(ctx->parser->script, rval, ei, &ri);
1968 if(FAILED(hres))
1969 return hres;
1971 V_VT(retv) = VT_I4;
1972 V_I4(retv) = li&ri;
1973 return S_OK;
1976 /* ECMA-262 3rd Edition 11.10 */
1977 HRESULT binary_and_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1979 binary_expression_t *expr = (binary_expression_t*)_expr;
1981 TRACE("\n");
1983 return binary_expr_eval(ctx, expr, bitand_eval, ei, ret);
1986 /* ECMA-262 3rd Edition 11.8.6 */
1987 static HRESULT instanceof_eval(exec_ctx_t *ctx, VARIANT *inst, VARIANT *objv, jsexcept_t *ei, VARIANT *retv)
1989 jsdisp_t *obj, *iter, *tmp = NULL;
1990 VARIANT_BOOL ret = VARIANT_FALSE;
1991 BOOL b;
1992 VARIANT var;
1993 HRESULT hres;
1995 static const WCHAR prototypeW[] = {'p','r','o','t','o','t', 'y', 'p','e',0};
1997 if(V_VT(objv) != VT_DISPATCH || !V_DISPATCH(objv))
1998 return throw_type_error(ctx->parser->script, ei, IDS_NOT_FUNC, NULL);
2000 obj = iface_to_jsdisp((IUnknown*)V_DISPATCH(objv));
2001 if(!obj) {
2002 FIXME("throw TypeError\n");
2003 return E_FAIL;
2006 if(is_class(obj, JSCLASS_FUNCTION)) {
2007 hres = jsdisp_propget_name(obj, prototypeW, &var, ei, NULL/*FIXME*/);
2008 }else {
2009 FIXME("throw TypeError\n");
2010 hres = E_FAIL;
2012 jsdisp_release(obj);
2013 if(FAILED(hres))
2014 return hres;
2016 if(V_VT(&var) == VT_DISPATCH) {
2017 if(V_VT(inst) == VT_DISPATCH)
2018 tmp = iface_to_jsdisp((IUnknown*)V_DISPATCH(inst));
2019 for(iter = tmp; iter; iter = iter->prototype) {
2020 hres = disp_cmp(V_DISPATCH(&var), to_disp(iter), &b);
2021 if(FAILED(hres))
2022 break;
2023 if(b) {
2024 ret = VARIANT_TRUE;
2025 break;
2029 if(tmp)
2030 jsdisp_release(tmp);
2031 }else {
2032 FIXME("prototype is not an object\n");
2033 hres = E_FAIL;
2036 VariantClear(&var);
2037 if(FAILED(hres))
2038 return hres;
2040 V_VT(retv) = VT_BOOL;
2041 V_BOOL(retv) = ret;
2042 return S_OK;
2045 /* ECMA-262 3rd Edition 11.8.6 */
2046 HRESULT instanceof_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2048 binary_expression_t *expr = (binary_expression_t*)_expr;
2050 TRACE("\n");
2052 return binary_expr_eval(ctx, expr, instanceof_eval, ei, ret);
2055 /* ECMA-262 3rd Edition 11.8.7 */
2056 static HRESULT in_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *obj, jsexcept_t *ei, VARIANT *retv)
2058 VARIANT_BOOL ret;
2059 DISPID id;
2060 BSTR str;
2061 HRESULT hres;
2063 if(V_VT(obj) != VT_DISPATCH || !V_DISPATCH(obj))
2064 return throw_type_error(ctx->parser->script, ei, IDS_OBJECT_EXPECTED, NULL);
2066 hres = to_string(ctx->parser->script, lval, ei, &str);
2067 if(FAILED(hres))
2068 return hres;
2070 hres = disp_get_id(ctx->parser->script, V_DISPATCH(obj), str, 0, &id);
2071 SysFreeString(str);
2072 if(SUCCEEDED(hres))
2073 ret = VARIANT_TRUE;
2074 else if(hres == DISP_E_UNKNOWNNAME)
2075 ret = VARIANT_FALSE;
2076 else
2077 return hres;
2079 V_VT(retv) = VT_BOOL;
2080 V_BOOL(retv) = ret;
2081 return S_OK;
2084 /* ECMA-262 3rd Edition 11.8.7 */
2085 HRESULT in_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2087 binary_expression_t *expr = (binary_expression_t*)_expr;
2089 TRACE("\n");
2091 return binary_expr_eval(ctx, expr, in_eval, ei, ret);
2094 /* ECMA-262 3rd Edition 11.6.1 */
2095 static HRESULT add_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
2097 VARIANT r, l;
2098 HRESULT hres;
2100 hres = to_primitive(ctx->parser->script, lval, ei, &l, NO_HINT);
2101 if(FAILED(hres))
2102 return hres;
2104 hres = to_primitive(ctx->parser->script, rval, ei, &r, NO_HINT);
2105 if(FAILED(hres)) {
2106 VariantClear(&l);
2107 return hres;
2110 if(V_VT(&l) == VT_BSTR || V_VT(&r) == VT_BSTR) {
2111 BSTR lstr = NULL, rstr = NULL;
2113 if(V_VT(&l) == VT_BSTR)
2114 lstr = V_BSTR(&l);
2115 else
2116 hres = to_string(ctx->parser->script, &l, ei, &lstr);
2118 if(SUCCEEDED(hres)) {
2119 if(V_VT(&r) == VT_BSTR)
2120 rstr = V_BSTR(&r);
2121 else
2122 hres = to_string(ctx->parser->script, &r, ei, &rstr);
2125 if(SUCCEEDED(hres)) {
2126 int len1, len2;
2128 len1 = SysStringLen(lstr);
2129 len2 = SysStringLen(rstr);
2131 V_VT(retv) = VT_BSTR;
2132 V_BSTR(retv) = SysAllocStringLen(NULL, len1+len2);
2133 memcpy(V_BSTR(retv), lstr, len1*sizeof(WCHAR));
2134 memcpy(V_BSTR(retv)+len1, rstr, (len2+1)*sizeof(WCHAR));
2137 if(V_VT(&l) != VT_BSTR)
2138 SysFreeString(lstr);
2139 if(V_VT(&r) != VT_BSTR)
2140 SysFreeString(rstr);
2141 }else {
2142 VARIANT nl, nr;
2144 hres = to_number(ctx->parser->script, &l, ei, &nl);
2145 if(SUCCEEDED(hres)) {
2146 hres = to_number(ctx->parser->script, &r, ei, &nr);
2147 if(SUCCEEDED(hres))
2148 num_set_val(retv, num_val(&nl) + num_val(&nr));
2152 VariantClear(&r);
2153 VariantClear(&l);
2154 return hres;
2157 /* ECMA-262 3rd Edition 11.6.1 */
2158 HRESULT add_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2160 binary_expression_t *expr = (binary_expression_t*)_expr;
2162 TRACE("\n");
2164 return binary_expr_eval(ctx, expr, add_eval, ei, ret);
2167 /* ECMA-262 3rd Edition 11.6.2 */
2168 static HRESULT sub_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
2170 VARIANT lnum, rnum;
2171 HRESULT hres;
2173 hres = to_number(ctx->parser->script, lval, ei, &lnum);
2174 if(FAILED(hres))
2175 return hres;
2177 hres = to_number(ctx->parser->script, rval, ei, &rnum);
2178 if(FAILED(hres))
2179 return hres;
2181 num_set_val(retv, num_val(&lnum) - num_val(&rnum));
2182 return S_OK;
2185 /* ECMA-262 3rd Edition 11.6.2 */
2186 HRESULT sub_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2188 binary_expression_t *expr = (binary_expression_t*)_expr;
2190 TRACE("\n");
2192 return binary_expr_eval(ctx, expr, sub_eval, ei, ret);
2195 /* ECMA-262 3rd Edition 11.5.1 */
2196 static HRESULT mul_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
2198 VARIANT lnum, rnum;
2199 HRESULT hres;
2201 hres = to_number(ctx->parser->script, lval, ei, &lnum);
2202 if(FAILED(hres))
2203 return hres;
2205 hres = to_number(ctx->parser->script, rval, ei, &rnum);
2206 if(FAILED(hres))
2207 return hres;
2209 num_set_val(retv, num_val(&lnum) * num_val(&rnum));
2210 return S_OK;
2213 /* ECMA-262 3rd Edition 11.5.1 */
2214 HRESULT mul_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2216 binary_expression_t *expr = (binary_expression_t*)_expr;
2218 TRACE("\n");
2220 return binary_expr_eval(ctx, expr, mul_eval, ei, ret);
2223 /* ECMA-262 3rd Edition 11.5.2 */
2224 static HRESULT div_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
2226 VARIANT lnum, rnum;
2227 HRESULT hres;
2229 hres = to_number(ctx->parser->script, lval, ei, &lnum);
2230 if(FAILED(hres))
2231 return hres;
2233 hres = to_number(ctx->parser->script, rval, ei, &rnum);
2234 if(FAILED(hres))
2235 return hres;
2237 num_set_val(retv, num_val(&lnum) / num_val(&rnum));
2238 return S_OK;
2241 /* ECMA-262 3rd Edition 11.5.2 */
2242 HRESULT div_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2244 binary_expression_t *expr = (binary_expression_t*)_expr;
2246 TRACE("\n");
2248 return binary_expr_eval(ctx, expr, div_eval, ei, ret);
2251 /* ECMA-262 3rd Edition 11.5.3 */
2252 static HRESULT mod_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
2254 VARIANT lnum, rnum;
2255 HRESULT hres;
2257 hres = to_number(ctx->parser->script, lval, ei, &lnum);
2258 if(FAILED(hres))
2259 return hres;
2261 hres = to_number(ctx->parser->script, rval, ei, &rnum);
2262 if(FAILED(hres))
2263 return hres;
2265 num_set_val(retv, fmod(num_val(&lnum), num_val(&rnum)));
2266 return S_OK;
2269 /* ECMA-262 3rd Edition 11.5.3 */
2270 HRESULT mod_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2272 binary_expression_t *expr = (binary_expression_t*)_expr;
2274 TRACE("\n");
2276 return binary_expr_eval(ctx, expr, mod_eval, ei, ret);
2279 /* ECMA-262 3rd Edition 11.4.2 */
2280 HRESULT delete_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2282 unary_expression_t *expr = (unary_expression_t*)_expr;
2283 VARIANT_BOOL b = VARIANT_FALSE;
2284 exprval_t exprval;
2285 HRESULT hres;
2287 TRACE("\n");
2289 hres = expr_eval(ctx, expr->expression, EXPR_STRREF, ei, &exprval);
2290 if(FAILED(hres))
2291 return hres;
2293 switch(exprval.type) {
2294 case EXPRVAL_IDREF: {
2295 IDispatchEx *dispex;
2297 hres = IDispatch_QueryInterface(exprval.u.nameref.disp, &IID_IDispatchEx, (void**)&dispex);
2298 if(SUCCEEDED(hres)) {
2299 hres = IDispatchEx_DeleteMemberByDispID(dispex, exprval.u.idref.id);
2300 b = VARIANT_TRUE;
2301 IDispatchEx_Release(dispex);
2303 break;
2305 case EXPRVAL_NAMEREF: {
2306 IDispatchEx *dispex;
2308 hres = IDispatch_QueryInterface(exprval.u.nameref.disp, &IID_IDispatchEx, (void**)&dispex);
2309 if(SUCCEEDED(hres)) {
2310 hres = IDispatchEx_DeleteMemberByName(dispex, exprval.u.nameref.name,
2311 make_grfdex(ctx->parser->script, fdexNameCaseSensitive));
2312 b = VARIANT_TRUE;
2313 IDispatchEx_Release(dispex);
2315 break;
2317 default:
2318 FIXME("unsupported type %d\n", exprval.type);
2319 hres = E_NOTIMPL;
2322 exprval_release(&exprval);
2323 if(FAILED(hres))
2324 return hres;
2326 return return_bool(ret, b);
2329 /* ECMA-262 3rd Edition 11.4.2 */
2330 HRESULT void_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2332 unary_expression_t *expr = (unary_expression_t*)_expr;
2333 exprval_t exprval;
2334 VARIANT tmp;
2335 HRESULT hres;
2337 TRACE("\n");
2339 hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
2340 if(FAILED(hres))
2341 return hres;
2343 hres = exprval_to_value(ctx->parser->script, &exprval, ei, &tmp);
2344 exprval_release(&exprval);
2345 if(FAILED(hres))
2346 return hres;
2348 VariantClear(&tmp);
2350 ret->type = EXPRVAL_VARIANT;
2351 V_VT(&ret->u.var) = VT_EMPTY;
2352 return S_OK;
2355 /* ECMA-262 3rd Edition 11.4.3 */
2356 static HRESULT typeof_exprval(exec_ctx_t *ctx, exprval_t *exprval, jsexcept_t *ei, const WCHAR **ret)
2358 VARIANT val;
2359 HRESULT hres;
2361 static const WCHAR booleanW[] = {'b','o','o','l','e','a','n',0};
2362 static const WCHAR functionW[] = {'f','u','n','c','t','i','o','n',0};
2363 static const WCHAR numberW[] = {'n','u','m','b','e','r',0};
2364 static const WCHAR objectW[] = {'o','b','j','e','c','t',0};
2365 static const WCHAR stringW[] = {'s','t','r','i','n','g',0};
2366 static const WCHAR undefinedW[] = {'u','n','d','e','f','i','n','e','d',0};
2368 if(exprval->type == EXPRVAL_INVALID) {
2369 *ret = undefinedW;
2370 return S_OK;
2373 hres = exprval_to_value(ctx->parser->script, exprval, ei, &val);
2374 if(FAILED(hres))
2375 return hres;
2377 switch(V_VT(&val)) {
2378 case VT_EMPTY:
2379 *ret = undefinedW;
2380 break;
2381 case VT_NULL:
2382 *ret = objectW;
2383 break;
2384 case VT_BOOL:
2385 *ret = booleanW;
2386 break;
2387 case VT_I4:
2388 case VT_R8:
2389 *ret = numberW;
2390 break;
2391 case VT_BSTR:
2392 *ret = stringW;
2393 break;
2394 case VT_DISPATCH: {
2395 jsdisp_t *dispex;
2397 if(V_DISPATCH(&val) && (dispex = iface_to_jsdisp((IUnknown*)V_DISPATCH(&val)))) {
2398 *ret = is_class(dispex, JSCLASS_FUNCTION) ? functionW : objectW;
2399 jsdisp_release(dispex);
2400 }else {
2401 *ret = objectW;
2403 break;
2405 default:
2406 FIXME("unhandled vt %d\n", V_VT(&val));
2407 hres = E_NOTIMPL;
2410 VariantClear(&val);
2411 return S_OK;
2414 HRESULT typeof_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2416 unary_expression_t *expr = (unary_expression_t*)_expr;
2417 const WCHAR *str = NULL;
2418 exprval_t exprval;
2419 HRESULT hres;
2421 TRACE("\n");
2423 hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
2424 if(FAILED(hres))
2425 return hres;
2427 hres = typeof_exprval(ctx, &exprval, ei, &str);
2428 exprval_release(&exprval);
2429 if(FAILED(hres))
2430 return hres;
2432 ret->type = EXPRVAL_VARIANT;
2433 V_VT(&ret->u.var) = VT_BSTR;
2434 V_BSTR(&ret->u.var) = SysAllocString(str);
2435 if(!V_BSTR(&ret->u.var))
2436 return E_OUTOFMEMORY;
2438 return S_OK;
2441 /* ECMA-262 3rd Edition 11.4.7 */
2442 HRESULT minus_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2444 unary_expression_t *expr = (unary_expression_t*)_expr;
2445 exprval_t exprval;
2446 VARIANT val, num;
2447 HRESULT hres;
2449 TRACE("\n");
2451 hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
2452 if(FAILED(hres))
2453 return hres;
2455 hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
2456 exprval_release(&exprval);
2457 if(FAILED(hres))
2458 return hres;
2460 hres = to_number(ctx->parser->script, &val, ei, &num);
2461 VariantClear(&val);
2462 if(FAILED(hres))
2463 return hres;
2465 ret->type = EXPRVAL_VARIANT;
2466 num_set_val(&ret->u.var, -num_val(&num));
2467 return S_OK;
2470 /* ECMA-262 3rd Edition 11.4.6 */
2471 HRESULT plus_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2473 unary_expression_t *expr = (unary_expression_t*)_expr;
2474 exprval_t exprval;
2475 VARIANT val, num;
2476 HRESULT hres;
2478 TRACE("\n");
2480 hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval);
2481 if(FAILED(hres))
2482 return hres;
2484 hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
2485 exprval_release(&exprval);
2486 if(FAILED(hres))
2487 return hres;
2489 hres = to_number(ctx->parser->script, &val, ei, &num);
2490 VariantClear(&val);
2491 if(FAILED(hres))
2492 return hres;
2494 ret->type = EXPRVAL_VARIANT;
2495 ret->u.var = num;
2496 return S_OK;
2499 /* ECMA-262 3rd Edition 11.3.1 */
2500 HRESULT post_increment_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2502 unary_expression_t *expr = (unary_expression_t*)_expr;
2503 VARIANT val, num;
2504 exprval_t exprval;
2505 HRESULT hres;
2507 TRACE("\n");
2509 hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval);
2510 if(FAILED(hres))
2511 return hres;
2513 hres = exprval_value(ctx->parser->script, &exprval, ei, &val);
2514 if(SUCCEEDED(hres)) {
2515 hres = to_number(ctx->parser->script, &val, ei, &num);
2516 VariantClear(&val);
2519 if(SUCCEEDED(hres)) {
2520 VARIANT inc;
2521 num_set_val(&inc, num_val(&num)+1.0);
2522 hres = put_value(ctx->parser->script, &exprval, &inc, ei);
2525 exprval_release(&exprval);
2526 if(FAILED(hres))
2527 return hres;
2529 ret->type = EXPRVAL_VARIANT;
2530 ret->u.var = num;
2531 return S_OK;
2534 /* ECMA-262 3rd Edition 11.3.2 */
2535 HRESULT post_decrement_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2537 unary_expression_t *expr = (unary_expression_t*)_expr;
2538 VARIANT val, num;
2539 exprval_t exprval;
2540 HRESULT hres;
2542 TRACE("\n");
2544 hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval);
2545 if(FAILED(hres))
2546 return hres;
2548 hres = exprval_value(ctx->parser->script, &exprval, ei, &val);
2549 if(SUCCEEDED(hres)) {
2550 hres = to_number(ctx->parser->script, &val, ei, &num);
2551 VariantClear(&val);
2554 if(SUCCEEDED(hres)) {
2555 VARIANT dec;
2556 num_set_val(&dec, num_val(&num)-1.0);
2557 hres = put_value(ctx->parser->script, &exprval, &dec, ei);
2560 exprval_release(&exprval);
2561 if(FAILED(hres))
2562 return hres;
2564 ret->type = EXPRVAL_VARIANT;
2565 ret->u.var = num;
2566 return S_OK;
2569 /* ECMA-262 3rd Edition 11.4.4 */
2570 HRESULT pre_increment_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2572 unary_expression_t *expr = (unary_expression_t*)_expr;
2573 VARIANT val, num;
2574 exprval_t exprval;
2575 HRESULT hres;
2577 TRACE("\n");
2579 hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval);
2580 if(FAILED(hres))
2581 return hres;
2583 hres = exprval_value(ctx->parser->script, &exprval, ei, &val);
2584 if(SUCCEEDED(hres)) {
2585 hres = to_number(ctx->parser->script, &val, ei, &num);
2586 VariantClear(&val);
2589 if(SUCCEEDED(hres)) {
2590 num_set_val(&val, num_val(&num)+1.0);
2591 hres = put_value(ctx->parser->script, &exprval, &val, ei);
2594 exprval_release(&exprval);
2595 if(FAILED(hres))
2596 return hres;
2598 ret->type = EXPRVAL_VARIANT;
2599 ret->u.var = val;
2600 return S_OK;
2603 /* ECMA-262 3rd Edition 11.4.5 */
2604 HRESULT pre_decrement_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2606 unary_expression_t *expr = (unary_expression_t*)_expr;
2607 VARIANT val, num;
2608 exprval_t exprval;
2609 HRESULT hres;
2611 TRACE("\n");
2613 hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval);
2614 if(FAILED(hres))
2615 return hres;
2617 hres = exprval_value(ctx->parser->script, &exprval, ei, &val);
2618 if(SUCCEEDED(hres)) {
2619 hres = to_number(ctx->parser->script, &val, ei, &num);
2620 VariantClear(&val);
2623 if(SUCCEEDED(hres)) {
2624 num_set_val(&val, num_val(&num)-1.0);
2625 hres = put_value(ctx->parser->script, &exprval, &val, ei);
2628 exprval_release(&exprval);
2629 if(FAILED(hres))
2630 return hres;
2632 ret->type = EXPRVAL_VARIANT;
2633 ret->u.var = val;
2634 return S_OK;
2637 /* ECMA-262 3rd Edition 11.9.3 */
2638 static HRESULT equal_values(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, BOOL *ret)
2640 if(V_VT(lval) == V_VT(rval) || (is_num_vt(V_VT(lval)) && is_num_vt(V_VT(rval))))
2641 return equal2_values(lval, rval, ret);
2643 /* FIXME: NULL disps should be handled in more general way */
2644 if(V_VT(lval) == VT_DISPATCH && !V_DISPATCH(lval)) {
2645 VARIANT v;
2646 V_VT(&v) = VT_NULL;
2647 return equal_values(ctx, &v, rval, ei, ret);
2650 if(V_VT(rval) == VT_DISPATCH && !V_DISPATCH(rval)) {
2651 VARIANT v;
2652 V_VT(&v) = VT_NULL;
2653 return equal_values(ctx, lval, &v, ei, ret);
2656 if((V_VT(lval) == VT_NULL && V_VT(rval) == VT_EMPTY) ||
2657 (V_VT(lval) == VT_EMPTY && V_VT(rval) == VT_NULL)) {
2658 *ret = TRUE;
2659 return S_OK;
2662 if(V_VT(lval) == VT_BSTR && is_num_vt(V_VT(rval))) {
2663 VARIANT v;
2664 HRESULT hres;
2666 hres = to_number(ctx->parser->script, lval, ei, &v);
2667 if(FAILED(hres))
2668 return hres;
2670 return equal_values(ctx, &v, rval, ei, ret);
2673 if(V_VT(rval) == VT_BSTR && is_num_vt(V_VT(lval))) {
2674 VARIANT v;
2675 HRESULT hres;
2677 hres = to_number(ctx->parser->script, rval, ei, &v);
2678 if(FAILED(hres))
2679 return hres;
2681 return equal_values(ctx, lval, &v, ei, ret);
2684 if(V_VT(rval) == VT_BOOL) {
2685 VARIANT v;
2687 V_VT(&v) = VT_I4;
2688 V_I4(&v) = V_BOOL(rval) ? 1 : 0;
2689 return equal_values(ctx, lval, &v, ei, ret);
2692 if(V_VT(lval) == VT_BOOL) {
2693 VARIANT v;
2695 V_VT(&v) = VT_I4;
2696 V_I4(&v) = V_BOOL(lval) ? 1 : 0;
2697 return equal_values(ctx, &v, rval, ei, ret);
2701 if(V_VT(rval) == VT_DISPATCH && (V_VT(lval) == VT_BSTR || is_num_vt(V_VT(lval)))) {
2702 VARIANT v;
2703 HRESULT hres;
2705 hres = to_primitive(ctx->parser->script, rval, ei, &v, NO_HINT);
2706 if(FAILED(hres))
2707 return hres;
2709 hres = equal_values(ctx, lval, &v, ei, ret);
2711 VariantClear(&v);
2712 return hres;
2716 if(V_VT(lval) == VT_DISPATCH && (V_VT(rval) == VT_BSTR || is_num_vt(V_VT(rval)))) {
2717 VARIANT v;
2718 HRESULT hres;
2720 hres = to_primitive(ctx->parser->script, lval, ei, &v, NO_HINT);
2721 if(FAILED(hres))
2722 return hres;
2724 hres = equal_values(ctx, &v, rval, ei, ret);
2726 VariantClear(&v);
2727 return hres;
2731 *ret = FALSE;
2732 return S_OK;
2735 /* ECMA-262 3rd Edition 11.9.1 */
2736 HRESULT equal_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2738 binary_expression_t *expr = (binary_expression_t*)_expr;
2739 VARIANT rval, lval;
2740 BOOL b;
2741 HRESULT hres;
2743 TRACE("\n");
2745 hres = get_binary_expr_values(ctx, expr, ei, &rval, &lval);
2746 if(FAILED(hres))
2747 return hres;
2749 hres = equal_values(ctx, &rval, &lval, ei, &b);
2750 VariantClear(&lval);
2751 VariantClear(&rval);
2752 if(FAILED(hres))
2753 return hres;
2755 return return_bool(ret, b);
2758 /* ECMA-262 3rd Edition 11.9.4 */
2759 HRESULT equal2_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2761 binary_expression_t *expr = (binary_expression_t*)_expr;
2762 VARIANT rval, lval;
2763 BOOL b;
2764 HRESULT hres;
2766 TRACE("\n");
2768 hres = get_binary_expr_values(ctx, expr, ei, &rval, &lval);
2769 if(FAILED(hres))
2770 return hres;
2772 hres = equal2_values(&rval, &lval, &b);
2773 VariantClear(&lval);
2774 VariantClear(&rval);
2775 if(FAILED(hres))
2776 return hres;
2778 return return_bool(ret, b);
2781 /* ECMA-262 3rd Edition 11.9.2 */
2782 HRESULT not_equal_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2784 binary_expression_t *expr = (binary_expression_t*)_expr;
2785 VARIANT rval, lval;
2786 BOOL b;
2787 HRESULT hres;
2789 TRACE("\n");
2791 hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval);
2792 if(FAILED(hres))
2793 return hres;
2795 hres = equal_values(ctx, &lval, &rval, ei, &b);
2796 VariantClear(&lval);
2797 VariantClear(&rval);
2798 if(FAILED(hres))
2799 return hres;
2801 return return_bool(ret, !b);
2804 /* ECMA-262 3rd Edition 11.9.5 */
2805 HRESULT not_equal2_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2807 binary_expression_t *expr = (binary_expression_t*)_expr;
2808 VARIANT rval, lval;
2809 BOOL b;
2810 HRESULT hres;
2812 TRACE("\n");
2814 hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval);
2815 if(FAILED(hres))
2816 return hres;
2818 hres = equal2_values(&lval, &rval, &b);
2819 VariantClear(&lval);
2820 VariantClear(&rval);
2821 if(FAILED(hres))
2822 return hres;
2824 return return_bool(ret, !b);
2827 /* ECMA-262 3rd Edition 11.8.5 */
2828 static HRESULT less_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, BOOL greater, jsexcept_t *ei, BOOL *ret)
2830 VARIANT l, r, ln, rn;
2831 HRESULT hres;
2833 hres = to_primitive(ctx->parser->script, lval, ei, &l, NO_HINT);
2834 if(FAILED(hres))
2835 return hres;
2837 hres = to_primitive(ctx->parser->script, rval, ei, &r, NO_HINT);
2838 if(FAILED(hres)) {
2839 VariantClear(&l);
2840 return hres;
2843 if(V_VT(&l) == VT_BSTR && V_VT(&r) == VT_BSTR) {
2844 *ret = (strcmpW(V_BSTR(&l), V_BSTR(&r)) < 0) ^ greater;
2845 SysFreeString(V_BSTR(&l));
2846 SysFreeString(V_BSTR(&r));
2847 return S_OK;
2850 hres = to_number(ctx->parser->script, &l, ei, &ln);
2851 VariantClear(&l);
2852 if(SUCCEEDED(hres))
2853 hres = to_number(ctx->parser->script, &r, ei, &rn);
2854 VariantClear(&r);
2855 if(FAILED(hres))
2856 return hres;
2858 if(V_VT(&ln) == VT_I4 && V_VT(&rn) == VT_I4) {
2859 *ret = (V_I4(&ln) < V_I4(&rn)) ^ greater;
2860 }else {
2861 DOUBLE ld = num_val(&ln);
2862 DOUBLE rd = num_val(&rn);
2864 *ret = !isnan(ld) && !isnan(rd) && ((ld < rd) ^ greater);
2867 return S_OK;
2870 /* ECMA-262 3rd Edition 11.8.1 */
2871 HRESULT less_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2873 binary_expression_t *expr = (binary_expression_t*)_expr;
2874 VARIANT rval, lval;
2875 BOOL b;
2876 HRESULT hres;
2878 TRACE("\n");
2880 hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval);
2881 if(FAILED(hres))
2882 return hres;
2884 hres = less_eval(ctx, &lval, &rval, FALSE, ei, &b);
2885 VariantClear(&lval);
2886 VariantClear(&rval);
2887 if(FAILED(hres))
2888 return hres;
2890 return return_bool(ret, b);
2893 /* ECMA-262 3rd Edition 11.8.3 */
2894 HRESULT lesseq_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2896 binary_expression_t *expr = (binary_expression_t*)_expr;
2897 VARIANT rval, lval;
2898 BOOL b;
2899 HRESULT hres;
2901 TRACE("\n");
2903 hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval);
2904 if(FAILED(hres))
2905 return hres;
2907 hres = less_eval(ctx, &rval, &lval, TRUE, ei, &b);
2908 VariantClear(&lval);
2909 VariantClear(&rval);
2910 if(FAILED(hres))
2911 return hres;
2913 return return_bool(ret, b);
2916 /* ECMA-262 3rd Edition 11.8.2 */
2917 HRESULT greater_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2919 binary_expression_t *expr = (binary_expression_t*)_expr;
2920 VARIANT rval, lval;
2921 BOOL b;
2922 HRESULT hres;
2924 TRACE("\n");
2926 hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval);
2927 if(FAILED(hres))
2928 return hres;
2930 hres = less_eval(ctx, &rval, &lval, FALSE, ei, &b);
2931 VariantClear(&lval);
2932 VariantClear(&rval);
2933 if(FAILED(hres))
2934 return hres;
2936 return return_bool(ret, b);
2939 /* ECMA-262 3rd Edition 11.8.4 */
2940 HRESULT greatereq_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2942 binary_expression_t *expr = (binary_expression_t*)_expr;
2943 VARIANT rval, lval;
2944 BOOL b;
2945 HRESULT hres;
2947 TRACE("\n");
2949 hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval);
2950 if(FAILED(hres))
2951 return hres;
2953 hres = less_eval(ctx, &lval, &rval, TRUE, ei, &b);
2954 VariantClear(&lval);
2955 VariantClear(&rval);
2956 if(FAILED(hres))
2957 return hres;
2959 return return_bool(ret, b);
2962 /* ECMA-262 3rd Edition 11.4.8 */
2963 HRESULT binary_negation_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2965 unary_expression_t *expr = (unary_expression_t*)_expr;
2966 exprval_t exprval;
2967 VARIANT val;
2968 INT i;
2969 HRESULT hres;
2971 TRACE("\n");
2973 hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval);
2974 if(FAILED(hres))
2975 return hres;
2977 hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
2978 exprval_release(&exprval);
2979 if(FAILED(hres))
2980 return hres;
2982 hres = to_int32(ctx->parser->script, &val, ei, &i);
2983 if(FAILED(hres))
2984 return hres;
2986 ret->type = EXPRVAL_VARIANT;
2987 V_VT(&ret->u.var) = VT_I4;
2988 V_I4(&ret->u.var) = ~i;
2989 return S_OK;
2992 /* ECMA-262 3rd Edition 11.4.9 */
2993 HRESULT logical_negation_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2995 unary_expression_t *expr = (unary_expression_t*)_expr;
2996 exprval_t exprval;
2997 VARIANT_BOOL b;
2998 HRESULT hres;
3000 TRACE("\n");
3002 hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval);
3003 if(FAILED(hres))
3004 return hres;
3006 hres = exprval_to_boolean(ctx->parser->script, &exprval, ei, &b);
3007 exprval_release(&exprval);
3008 if(FAILED(hres))
3009 return hres;
3011 return return_bool(ret, !b);
3014 /* ECMA-262 3rd Edition 11.7.1 */
3015 static HRESULT lshift_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
3017 DWORD ri;
3018 INT li;
3019 HRESULT hres;
3021 hres = to_int32(ctx->parser->script, lval, ei, &li);
3022 if(FAILED(hres))
3023 return hres;
3025 hres = to_uint32(ctx->parser->script, rval, ei, &ri);
3026 if(FAILED(hres))
3027 return hres;
3029 V_VT(retv) = VT_I4;
3030 V_I4(retv) = li << (ri&0x1f);
3031 return S_OK;
3034 /* ECMA-262 3rd Edition 11.7.1 */
3035 HRESULT left_shift_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3037 binary_expression_t *expr = (binary_expression_t*)_expr;
3039 TRACE("\n");
3041 return binary_expr_eval(ctx, expr, lshift_eval, ei, ret);
3044 /* ECMA-262 3rd Edition 11.7.2 */
3045 static HRESULT rshift_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
3047 DWORD ri;
3048 INT li;
3049 HRESULT hres;
3051 hres = to_int32(ctx->parser->script, lval, ei, &li);
3052 if(FAILED(hres))
3053 return hres;
3055 hres = to_uint32(ctx->parser->script, rval, ei, &ri);
3056 if(FAILED(hres))
3057 return hres;
3059 V_VT(retv) = VT_I4;
3060 V_I4(retv) = li >> (ri&0x1f);
3061 return S_OK;
3064 /* ECMA-262 3rd Edition 11.7.2 */
3065 HRESULT right_shift_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3067 binary_expression_t *expr = (binary_expression_t*)_expr;
3069 TRACE("\n");
3071 return binary_expr_eval(ctx, expr, rshift_eval, ei, ret);
3074 /* ECMA-262 3rd Edition 11.7.3 */
3075 static HRESULT rshift2_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
3077 DWORD li, ri;
3078 HRESULT hres;
3080 hres = to_uint32(ctx->parser->script, lval, ei, &li);
3081 if(FAILED(hres))
3082 return hres;
3084 hres = to_uint32(ctx->parser->script, rval, ei, &ri);
3085 if(FAILED(hres))
3086 return hres;
3088 V_VT(retv) = VT_I4;
3089 V_I4(retv) = li >> (ri&0x1f);
3090 return S_OK;
3093 /* ECMA-262 3rd Edition 11.7.3 */
3094 HRESULT right2_shift_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3096 binary_expression_t *expr = (binary_expression_t*)_expr;
3098 TRACE("\n");
3100 return binary_expr_eval(ctx, expr, rshift2_eval, ei, ret);
3103 /* ECMA-262 3rd Edition 11.13.1 */
3104 HRESULT assign_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3106 binary_expression_t *expr = (binary_expression_t*)_expr;
3107 exprval_t exprval, exprvalr;
3108 VARIANT rval;
3109 HRESULT hres;
3111 TRACE("\n");
3113 hres = expr_eval(ctx, expr->expression1, EXPR_NEWREF, ei, &exprval);
3114 if(FAILED(hres))
3115 return hres;
3117 hres = expr_eval(ctx, expr->expression2, 0, ei, &exprvalr);
3118 if(SUCCEEDED(hres)) {
3119 hres = exprval_to_value(ctx->parser->script, &exprvalr, ei, &rval);
3120 exprval_release(&exprvalr);
3123 if(SUCCEEDED(hres)) {
3124 hres = put_value(ctx->parser->script, &exprval, &rval, ei);
3125 if(FAILED(hres))
3126 VariantClear(&rval);
3129 exprval_release(&exprval);
3130 if(FAILED(hres))
3131 return hres;
3133 ret->type = EXPRVAL_VARIANT;
3134 ret->u.var = rval;
3135 return S_OK;
3138 /* ECMA-262 3rd Edition 11.13.2 */
3139 HRESULT assign_lshift_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3141 binary_expression_t *expr = (binary_expression_t*)_expr;
3143 TRACE("\n");
3145 return assign_oper_eval(ctx, expr->expression1, expr->expression2, lshift_eval, ei, ret);
3148 /* ECMA-262 3rd Edition 11.13.2 */
3149 HRESULT assign_rshift_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3151 binary_expression_t *expr = (binary_expression_t*)_expr;
3153 TRACE("\n");
3155 return assign_oper_eval(ctx, expr->expression1, expr->expression2, rshift_eval, ei, ret);
3158 /* ECMA-262 3rd Edition 11.13.2 */
3159 HRESULT assign_rrshift_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3161 binary_expression_t *expr = (binary_expression_t*)_expr;
3163 TRACE("\n");
3165 return assign_oper_eval(ctx, expr->expression1, expr->expression2, rshift2_eval, ei, ret);
3168 /* ECMA-262 3rd Edition 11.13.2 */
3169 HRESULT assign_add_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3171 binary_expression_t *expr = (binary_expression_t*)_expr;
3173 TRACE("\n");
3175 return assign_oper_eval(ctx, expr->expression1, expr->expression2, add_eval, ei, ret);
3178 /* ECMA-262 3rd Edition 11.13.2 */
3179 HRESULT assign_sub_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3181 binary_expression_t *expr = (binary_expression_t*)_expr;
3183 TRACE("\n");
3185 return assign_oper_eval(ctx, expr->expression1, expr->expression2, sub_eval, ei, ret);
3188 /* ECMA-262 3rd Edition 11.13.2 */
3189 HRESULT assign_mul_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3191 binary_expression_t *expr = (binary_expression_t*)_expr;
3193 TRACE("\n");
3195 return assign_oper_eval(ctx, expr->expression1, expr->expression2, mul_eval, ei, ret);
3198 /* ECMA-262 3rd Edition 11.13.2 */
3199 HRESULT assign_div_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3201 binary_expression_t *expr = (binary_expression_t*)_expr;
3203 TRACE("\n");
3205 return assign_oper_eval(ctx, expr->expression1, expr->expression2, div_eval, ei, ret);
3208 /* ECMA-262 3rd Edition 11.13.2 */
3209 HRESULT assign_mod_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3211 binary_expression_t *expr = (binary_expression_t*)_expr;
3213 TRACE("\n");
3215 return assign_oper_eval(ctx, expr->expression1, expr->expression2, mod_eval, ei, ret);
3218 /* ECMA-262 3rd Edition 11.13.2 */
3219 HRESULT assign_and_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3221 binary_expression_t *expr = (binary_expression_t*)_expr;
3223 TRACE("\n");
3225 return assign_oper_eval(ctx, expr->expression1, expr->expression2, bitand_eval, ei, ret);
3228 /* ECMA-262 3rd Edition 11.13.2 */
3229 HRESULT assign_or_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3231 binary_expression_t *expr = (binary_expression_t*)_expr;
3233 TRACE("\n");
3235 return assign_oper_eval(ctx, expr->expression1, expr->expression2, bitor_eval, ei, ret);
3238 /* ECMA-262 3rd Edition 11.13.2 */
3239 HRESULT assign_xor_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3241 binary_expression_t *expr = (binary_expression_t*)_expr;
3243 TRACE("\n");
3245 return assign_oper_eval(ctx, expr->expression1, expr->expression2, xor_eval, ei, ret);