browseui/tests: Skip some tests if IEnumACString is not supported.
[wine/multimedia.git] / dlls / jscript / engine.c
blob160a67b9675aa30eb3d0968e75dce2c9f9df4238
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(script_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(script_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, JS_E_UNDEFINED_VARIABLE, 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, BOOL is_global, 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;
191 ctx->is_global = is_global;
193 if(this_obj)
194 ctx->this_obj = this_obj;
195 else if(script_ctx->host_global)
196 ctx->this_obj = script_ctx->host_global;
197 else
198 ctx->this_obj = to_disp(script_ctx->global);
199 IDispatch_AddRef(ctx->this_obj);
201 jsdisp_addref(var_disp);
202 ctx->var_disp = var_disp;
204 if(scope) {
205 scope_addref(scope);
206 ctx->scope_chain = scope;
209 *ret = ctx;
210 return S_OK;
213 void exec_release(exec_ctx_t *ctx)
215 if(--ctx->ref)
216 return;
218 if(ctx->scope_chain)
219 scope_release(ctx->scope_chain);
220 if(ctx->var_disp)
221 jsdisp_release(ctx->var_disp);
222 if(ctx->this_obj)
223 IDispatch_Release(ctx->this_obj);
224 heap_free(ctx);
227 static HRESULT disp_get_id(script_ctx_t *ctx, IDispatch *disp, BSTR name, DWORD flags, DISPID *id)
229 IDispatchEx *dispex;
230 HRESULT hres;
232 hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
233 if(FAILED(hres)) {
234 TRACE("unsing IDispatch\n");
236 *id = 0;
237 return IDispatch_GetIDsOfNames(disp, &IID_NULL, &name, 1, 0, id);
240 *id = 0;
241 hres = IDispatchEx_GetDispID(dispex, name, make_grfdex(ctx, flags|fdexNameCaseSensitive), id);
242 IDispatchEx_Release(dispex);
243 return hres;
246 /* ECMA-262 3rd Edition 8.7.2 */
247 static HRESULT put_value(script_ctx_t *ctx, exprval_t *ref, VARIANT *v, jsexcept_t *ei)
249 if(ref->type != EXPRVAL_IDREF)
250 return throw_reference_error(ctx, ei, JS_E_ILLEGAL_ASSIGN, NULL);
252 return disp_propput(ctx, ref->u.idref.disp, ref->u.idref.id, v, ei, NULL/*FIXME*/);
255 static inline BOOL is_null(const VARIANT *v)
257 return V_VT(v) == VT_NULL || (V_VT(v) == VT_DISPATCH && !V_DISPATCH(v));
260 static HRESULT disp_cmp(IDispatch *disp1, IDispatch *disp2, BOOL *ret)
262 IObjectIdentity *identity;
263 IUnknown *unk1, *unk2;
264 HRESULT hres;
266 if(disp1 == disp2) {
267 *ret = TRUE;
268 return S_OK;
271 if(!disp1 || !disp2) {
272 *ret = FALSE;
273 return S_OK;
276 hres = IDispatch_QueryInterface(disp1, &IID_IUnknown, (void**)&unk1);
277 if(FAILED(hres))
278 return hres;
280 hres = IDispatch_QueryInterface(disp2, &IID_IUnknown, (void**)&unk2);
281 if(FAILED(hres)) {
282 IUnknown_Release(unk1);
283 return hres;
286 if(unk1 == unk2) {
287 *ret = TRUE;
288 }else {
289 hres = IUnknown_QueryInterface(unk1, &IID_IObjectIdentity, (void**)&identity);
290 if(SUCCEEDED(hres)) {
291 hres = IObjectIdentity_IsEqualObject(identity, unk2);
292 IObjectIdentity_Release(identity);
293 *ret = hres == S_OK;
294 }else {
295 *ret = FALSE;
299 IUnknown_Release(unk1);
300 IUnknown_Release(unk2);
301 return S_OK;
304 /* ECMA-262 3rd Edition 11.9.6 */
305 static HRESULT equal2_values(VARIANT *lval, VARIANT *rval, BOOL *ret)
307 TRACE("\n");
309 if(V_VT(lval) != V_VT(rval)) {
310 if(is_num_vt(V_VT(lval)) && is_num_vt(V_VT(rval)))
311 *ret = num_val(lval) == num_val(rval);
312 else if(is_null(lval))
313 *ret = is_null(rval);
314 else
315 *ret = FALSE;
316 return S_OK;
319 switch(V_VT(lval)) {
320 case VT_EMPTY:
321 case VT_NULL:
322 *ret = VARIANT_TRUE;
323 break;
324 case VT_I4:
325 *ret = V_I4(lval) == V_I4(rval);
326 break;
327 case VT_R8:
328 *ret = V_R8(lval) == V_R8(rval);
329 break;
330 case VT_BSTR:
331 if(!V_BSTR(lval))
332 *ret = SysStringLen(V_BSTR(rval))?FALSE:TRUE;
333 else if(!V_BSTR(rval))
334 *ret = SysStringLen(V_BSTR(lval))?FALSE:TRUE;
335 else
336 *ret = !strcmpW(V_BSTR(lval), V_BSTR(rval));
337 break;
338 case VT_DISPATCH:
339 return disp_cmp(V_DISPATCH(lval), V_DISPATCH(rval), ret);
340 case VT_BOOL:
341 *ret = !V_BOOL(lval) == !V_BOOL(rval);
342 break;
343 default:
344 FIXME("unimplemented vt %d\n", V_VT(lval));
345 return E_NOTIMPL;
348 return S_OK;
351 static HRESULT literal_to_var(script_ctx_t *ctx, literal_t *literal, VARIANT *v)
353 switch(literal->type) {
354 case LT_NULL:
355 V_VT(v) = VT_NULL;
356 break;
357 case LT_INT:
358 V_VT(v) = VT_I4;
359 V_I4(v) = literal->u.lval;
360 break;
361 case LT_DOUBLE:
362 V_VT(v) = VT_R8;
363 V_R8(v) = literal->u.dval;
364 break;
365 case LT_STRING: {
366 BSTR str = SysAllocString(literal->u.wstr);
367 if(!str)
368 return E_OUTOFMEMORY;
370 V_VT(v) = VT_BSTR;
371 V_BSTR(v) = str;
372 break;
374 case LT_BOOL:
375 V_VT(v) = VT_BOOL;
376 V_BOOL(v) = literal->u.bval;
377 break;
378 case LT_REGEXP: {
379 jsdisp_t *regexp;
380 HRESULT hres;
382 hres = create_regexp(ctx, literal->u.regexp.str, literal->u.regexp.str_len,
383 literal->u.regexp.flags, &regexp);
384 if(FAILED(hres))
385 return hres;
387 var_set_jsdisp(v, regexp);
391 return S_OK;
394 static BOOL lookup_global_members(script_ctx_t *ctx, BSTR identifier, exprval_t *ret)
396 named_item_t *item;
397 DISPID id;
398 HRESULT hres;
400 for(item = ctx->named_items; item; item = item->next) {
401 if(item->flags & SCRIPTITEM_GLOBALMEMBERS) {
402 hres = disp_get_id(ctx, item->disp, identifier, 0, &id);
403 if(SUCCEEDED(hres)) {
404 if(ret)
405 exprval_set_idref(ret, item->disp, id);
406 return TRUE;
411 return FALSE;
414 HRESULT exec_source(exec_ctx_t *ctx, parser_ctx_t *parser, source_elements_t *source, BOOL from_eval,
415 jsexcept_t *ei, VARIANT *retv)
417 script_ctx_t *script = parser->script;
418 function_declaration_t *func;
419 parser_ctx_t *prev_parser;
420 var_list_t *var;
421 VARIANT val, tmp;
422 statement_t *stat;
423 exec_ctx_t *prev_ctx;
424 return_type_t rt;
425 HRESULT hres = S_OK;
427 for(func = source->functions; func; func = func->next) {
428 jsdisp_t *func_obj;
429 VARIANT var;
431 hres = create_source_function(parser, func->expr->parameter_list, func->expr->source_elements,
432 ctx->scope_chain, func->expr->src_str, func->expr->src_len, &func_obj);
433 if(FAILED(hres))
434 return hres;
436 var_set_jsdisp(&var, func_obj);
437 hres = jsdisp_propput_name(ctx->var_disp, func->expr->identifier, &var, ei, NULL);
438 jsdisp_release(func_obj);
439 if(FAILED(hres))
440 return hres;
443 for(var = source->variables; var; var = var->next) {
444 DISPID id = 0;
445 BSTR name;
447 name = SysAllocString(var->identifier);
448 if(!name)
449 return E_OUTOFMEMORY;
451 if(!ctx->is_global || !lookup_global_members(parser->script, name, NULL))
452 hres = jsdisp_get_id(ctx->var_disp, var->identifier, fdexNameEnsure, &id);
453 SysFreeString(name);
454 if(FAILED(hres))
455 return hres;
458 prev_ctx = script->exec_ctx;
459 script->exec_ctx = ctx;
461 prev_parser = ctx->parser;
462 ctx->parser = parser;
464 V_VT(&val) = VT_EMPTY;
465 memset(&rt, 0, sizeof(rt));
466 rt.type = RT_NORMAL;
468 for(stat = source->statement; stat; stat = stat->next) {
469 hres = stat_eval(script, stat, &rt, &tmp);
470 if(FAILED(hres))
471 break;
473 VariantClear(&val);
474 val = tmp;
475 if(rt.type != RT_NORMAL)
476 break;
479 script->exec_ctx = prev_ctx;
480 ctx->parser = prev_parser;
482 if(rt.type != RT_NORMAL && rt.type != RT_RETURN) {
483 FIXME("wrong rt %d\n", rt.type);
484 hres = E_FAIL;
487 *ei = rt.ei;
488 if(FAILED(hres)) {
489 VariantClear(&val);
490 return hres;
493 if(!retv || (!from_eval && rt.type != RT_RETURN))
494 VariantClear(&val);
495 if(retv)
496 *retv = val;
497 return S_OK;
500 /* ECMA-262 3rd Edition 10.1.4 */
501 static HRESULT identifier_eval(script_ctx_t *ctx, BSTR identifier, DWORD flags, jsexcept_t *ei, exprval_t *ret)
503 scope_chain_t *scope;
504 named_item_t *item;
505 DISPID id = 0;
506 HRESULT hres;
508 TRACE("%s\n", debugstr_w(identifier));
510 for(scope = ctx->exec_ctx->scope_chain; scope; scope = scope->next) {
511 hres = jsdisp_get_id(scope->obj, identifier, 0, &id);
512 if(SUCCEEDED(hres)) {
513 exprval_set_idref(ret, to_disp(scope->obj), id);
514 return S_OK;
518 hres = jsdisp_get_id(ctx->global, identifier, 0, &id);
519 if(SUCCEEDED(hres)) {
520 exprval_set_idref(ret, to_disp(ctx->global), id);
521 return S_OK;
524 for(item = ctx->named_items; item; item = item->next) {
525 if((item->flags & SCRIPTITEM_ISVISIBLE) && !strcmpW(item->name, identifier)) {
526 if(!item->disp) {
527 IUnknown *unk;
529 if(!ctx->site)
530 break;
532 hres = IActiveScriptSite_GetItemInfo(ctx->site, identifier,
533 SCRIPTINFO_IUNKNOWN, &unk, NULL);
534 if(FAILED(hres)) {
535 WARN("GetItemInfo failed: %08x\n", hres);
536 break;
539 hres = IUnknown_QueryInterface(unk, &IID_IDispatch, (void**)&item->disp);
540 IUnknown_Release(unk);
541 if(FAILED(hres)) {
542 WARN("object does not implement IDispatch\n");
543 break;
547 ret->type = EXPRVAL_VARIANT;
548 V_VT(&ret->u.var) = VT_DISPATCH;
549 V_DISPATCH(&ret->u.var) = item->disp;
550 IDispatch_AddRef(item->disp);
551 return S_OK;
555 if(lookup_global_members(ctx, identifier, ret))
556 return S_OK;
558 if(flags & EXPR_NEWREF) {
559 hres = jsdisp_get_id(ctx->global, identifier, fdexNameEnsure, &id);
560 if(FAILED(hres))
561 return hres;
563 exprval_set_idref(ret, to_disp(ctx->global), id);
564 return S_OK;
567 ret->type = EXPRVAL_INVALID;
568 ret->u.identifier = SysAllocString(identifier);
569 if(!ret->u.identifier)
570 return E_OUTOFMEMORY;
572 return S_OK;
575 /* ECMA-262 3rd Edition 12.1 */
576 HRESULT block_statement_eval(script_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
578 block_statement_t *stat = (block_statement_t*)_stat;
579 VARIANT val, tmp;
580 statement_t *iter;
581 HRESULT hres = S_OK;
583 TRACE("\n");
585 V_VT(&val) = VT_EMPTY;
586 for(iter = stat->stat_list; iter; iter = iter->next) {
587 hres = stat_eval(ctx, iter, rt, &tmp);
588 if(FAILED(hres))
589 break;
591 VariantClear(&val);
592 val = tmp;
593 if(rt->type != RT_NORMAL)
594 break;
597 if(FAILED(hres)) {
598 VariantClear(&val);
599 return hres;
602 *ret = val;
603 return S_OK;
606 /* ECMA-262 3rd Edition 12.2 */
607 static HRESULT variable_list_eval(script_ctx_t *ctx, variable_declaration_t *var_list, jsexcept_t *ei)
609 variable_declaration_t *iter;
610 HRESULT hres = S_OK;
612 for(iter = var_list; iter; iter = iter->next) {
613 exprval_t exprval;
614 VARIANT val;
616 if(!iter->expr)
617 continue;
619 hres = expr_eval(ctx, iter->expr, 0, ei, &exprval);
620 if(FAILED(hres))
621 break;
623 hres = exprval_to_value(ctx, &exprval, ei, &val);
624 exprval_release(&exprval);
625 if(FAILED(hres))
626 break;
628 hres = jsdisp_propput_name(ctx->exec_ctx->var_disp, iter->identifier, &val, ei, NULL/*FIXME*/);
629 VariantClear(&val);
630 if(FAILED(hres))
631 break;
634 return hres;
637 /* ECMA-262 3rd Edition 12.2 */
638 HRESULT var_statement_eval(script_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
640 var_statement_t *stat = (var_statement_t*)_stat;
641 HRESULT hres;
643 TRACE("\n");
645 hres = variable_list_eval(ctx, stat->variable_list, &rt->ei);
646 if(FAILED(hres))
647 return hres;
649 V_VT(ret) = VT_EMPTY;
650 return S_OK;
653 /* ECMA-262 3rd Edition 12.3 */
654 HRESULT empty_statement_eval(script_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
656 TRACE("\n");
658 V_VT(ret) = VT_EMPTY;
659 return S_OK;
662 /* ECMA-262 3rd Edition 12.4 */
663 HRESULT expression_statement_eval(script_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
665 expression_statement_t *stat = (expression_statement_t*)_stat;
666 exprval_t exprval;
667 VARIANT val;
668 HRESULT hres;
670 TRACE("\n");
672 hres = expr_eval(ctx, stat->expr, EXPR_NOVAL, &rt->ei, &exprval);
673 if(FAILED(hres))
674 return hres;
676 hres = exprval_to_value(ctx, &exprval, &rt->ei, &val);
677 exprval_release(&exprval);
678 if(FAILED(hres))
679 return hres;
681 *ret = val;
682 TRACE("= %s\n", debugstr_variant(ret));
683 return S_OK;
686 /* ECMA-262 3rd Edition 12.5 */
687 HRESULT if_statement_eval(script_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
689 if_statement_t *stat = (if_statement_t*)_stat;
690 exprval_t exprval;
691 VARIANT_BOOL b;
692 HRESULT hres;
694 TRACE("\n");
696 hres = expr_eval(ctx, stat->expr, 0, &rt->ei, &exprval);
697 if(FAILED(hres))
698 return hres;
700 hres = exprval_to_boolean(ctx, &exprval, &rt->ei, &b);
701 exprval_release(&exprval);
702 if(FAILED(hres))
703 return hres;
705 if(b)
706 hres = stat_eval(ctx, stat->if_stat, rt, ret);
707 else if(stat->else_stat)
708 hres = stat_eval(ctx, stat->else_stat, rt, ret);
709 else
710 V_VT(ret) = VT_EMPTY;
712 return hres;
715 /* ECMA-262 3rd Edition 12.6.2 */
716 HRESULT while_statement_eval(script_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
718 while_statement_t *stat = (while_statement_t*)_stat;
719 exprval_t exprval;
720 VARIANT val, tmp;
721 VARIANT_BOOL b;
722 BOOL test_expr;
723 HRESULT hres;
725 TRACE("\n");
727 V_VT(&val) = VT_EMPTY;
728 test_expr = !stat->do_while;
730 while(1) {
731 if(test_expr) {
732 hres = expr_eval(ctx, stat->expr, 0, &rt->ei, &exprval);
733 if(FAILED(hres))
734 break;
736 hres = exprval_to_boolean(ctx, &exprval, &rt->ei, &b);
737 exprval_release(&exprval);
738 if(FAILED(hres) || !b)
739 break;
740 }else {
741 test_expr = TRUE;
744 hres = stat_eval(ctx, stat->statement, rt, &tmp);
745 if(FAILED(hres))
746 break;
748 VariantClear(&val);
749 val = tmp;
751 if(rt->type == RT_CONTINUE)
752 rt->type = RT_NORMAL;
753 if(rt->type != RT_NORMAL)
754 break;
757 if(FAILED(hres)) {
758 VariantClear(&val);
759 return hres;
762 if(rt->type == RT_BREAK)
763 rt->type = RT_NORMAL;
765 *ret = val;
766 return S_OK;
769 /* ECMA-262 3rd Edition 12.6.3 */
770 HRESULT for_statement_eval(script_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
772 for_statement_t *stat = (for_statement_t*)_stat;
773 VARIANT val, tmp, retv;
774 exprval_t exprval;
775 VARIANT_BOOL b;
776 HRESULT hres;
778 TRACE("\n");
780 if(stat->variable_list) {
781 hres = variable_list_eval(ctx, stat->variable_list, &rt->ei);
782 if(FAILED(hres))
783 return hres;
784 }else if(stat->begin_expr) {
785 hres = expr_eval(ctx, stat->begin_expr, EXPR_NEWREF, &rt->ei, &exprval);
786 if(FAILED(hres))
787 return hres;
789 hres = exprval_to_value(ctx, &exprval, &rt->ei, &val);
790 exprval_release(&exprval);
791 if(FAILED(hres))
792 return hres;
794 VariantClear(&val);
797 V_VT(&retv) = VT_EMPTY;
799 while(1) {
800 if(stat->expr) {
801 hres = expr_eval(ctx, stat->expr, 0, &rt->ei, &exprval);
802 if(FAILED(hres))
803 break;
805 hres = exprval_to_boolean(ctx, &exprval, &rt->ei, &b);
806 exprval_release(&exprval);
807 if(FAILED(hres) || !b)
808 break;
811 hres = stat_eval(ctx, stat->statement, rt, &tmp);
812 if(FAILED(hres))
813 break;
815 VariantClear(&retv);
816 retv = tmp;
818 if(rt->type == RT_CONTINUE)
819 rt->type = RT_NORMAL;
820 else if(rt->type != RT_NORMAL)
821 break;
823 if(stat->end_expr) {
824 hres = expr_eval(ctx, stat->end_expr, 0, &rt->ei, &exprval);
825 if(FAILED(hres))
826 break;
828 hres = exprval_to_value(ctx, &exprval, &rt->ei, &val);
829 exprval_release(&exprval);
830 if(FAILED(hres))
831 break;
833 VariantClear(&val);
837 if(FAILED(hres)) {
838 VariantClear(&retv);
839 return hres;
842 if(rt->type == RT_BREAK)
843 rt->type = RT_NORMAL;
845 *ret = retv;
846 return S_OK;
849 /* ECMA-262 3rd Edition 12.6.4 */
850 HRESULT forin_statement_eval(script_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
852 forin_statement_t *stat = (forin_statement_t*)_stat;
853 VARIANT val, name, retv, tmp;
854 DISPID id = DISPID_STARTENUM;
855 BSTR str, identifier = NULL;
856 IDispatchEx *in_obj;
857 exprval_t exprval;
858 HRESULT hres;
860 TRACE("\n");
862 if(stat->variable) {
863 hres = variable_list_eval(ctx, stat->variable, &rt->ei);
864 if(FAILED(hres))
865 return hres;
868 hres = expr_eval(ctx, stat->in_expr, EXPR_NEWREF, &rt->ei, &exprval);
869 if(FAILED(hres))
870 return hres;
872 hres = exprval_to_value(ctx, &exprval, &rt->ei, &val);
873 exprval_release(&exprval);
874 if(FAILED(hres))
875 return hres;
877 if(V_VT(&val) != VT_DISPATCH) {
878 TRACE("in vt %d\n", V_VT(&val));
879 VariantClear(&val);
880 V_VT(ret) = VT_EMPTY;
881 return S_OK;
884 hres = IDispatch_QueryInterface(V_DISPATCH(&val), &IID_IDispatchEx, (void**)&in_obj);
885 IDispatch_Release(V_DISPATCH(&val));
886 if(FAILED(hres)) {
887 TRACE("Object doesn't support IDispatchEx\n");
888 V_VT(ret) = VT_EMPTY;
889 return S_OK;
892 V_VT(&retv) = VT_EMPTY;
894 if(stat->variable)
895 identifier = SysAllocString(stat->variable->identifier);
897 while(1) {
898 hres = IDispatchEx_GetNextDispID(in_obj, fdexEnumDefault, id, &id);
899 if(FAILED(hres) || hres == S_FALSE)
900 break;
902 hres = IDispatchEx_GetMemberName(in_obj, id, &str);
903 if(FAILED(hres))
904 break;
906 TRACE("iter %s\n", debugstr_w(str));
908 if(stat->variable)
909 hres = identifier_eval(ctx, identifier, 0, NULL, &exprval);
910 else
911 hres = expr_eval(ctx, stat->expr, EXPR_NEWREF, &rt->ei, &exprval);
912 if(SUCCEEDED(hres)) {
913 V_VT(&name) = VT_BSTR;
914 V_BSTR(&name) = str;
915 hres = put_value(ctx, &exprval, &name, &rt->ei);
916 exprval_release(&exprval);
918 SysFreeString(str);
919 if(FAILED(hres))
920 break;
922 hres = stat_eval(ctx, stat->statement, rt, &tmp);
923 if(FAILED(hres))
924 break;
926 VariantClear(&retv);
927 retv = tmp;
929 if(rt->type == RT_CONTINUE)
930 rt->type = RT_NORMAL;
931 else if(rt->type != RT_NORMAL)
932 break;
935 SysFreeString(identifier);
936 IDispatchEx_Release(in_obj);
937 if(FAILED(hres)) {
938 VariantClear(&retv);
939 return hres;
942 if(rt->type == RT_BREAK)
943 rt->type = RT_NORMAL;
945 *ret = retv;
946 return S_OK;
949 /* ECMA-262 3rd Edition 12.7 */
950 HRESULT continue_statement_eval(script_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
952 branch_statement_t *stat = (branch_statement_t*)_stat;
954 TRACE("\n");
956 if(stat->identifier) {
957 FIXME("indentifier not implemented\n");
958 return E_NOTIMPL;
961 rt->type = RT_CONTINUE;
962 V_VT(ret) = VT_EMPTY;
963 return S_OK;
966 /* ECMA-262 3rd Edition 12.8 */
967 HRESULT break_statement_eval(script_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
969 branch_statement_t *stat = (branch_statement_t*)_stat;
971 TRACE("\n");
973 if(stat->identifier) {
974 FIXME("indentifier not implemented\n");
975 return E_NOTIMPL;
978 rt->type = RT_BREAK;
979 V_VT(ret) = VT_EMPTY;
980 return S_OK;
983 /* ECMA-262 3rd Edition 12.9 */
984 HRESULT return_statement_eval(script_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
986 expression_statement_t *stat = (expression_statement_t*)_stat;
987 HRESULT hres;
989 TRACE("\n");
991 if(stat->expr) {
992 exprval_t exprval;
994 hres = expr_eval(ctx, stat->expr, 0, &rt->ei, &exprval);
995 if(FAILED(hres))
996 return hres;
998 hres = exprval_to_value(ctx, &exprval, &rt->ei, ret);
999 exprval_release(&exprval);
1000 if(FAILED(hres))
1001 return hres;
1002 }else {
1003 V_VT(ret) = VT_EMPTY;
1006 TRACE("= %s\n", debugstr_variant(ret));
1007 rt->type = RT_RETURN;
1008 return S_OK;
1011 /* ECMA-262 3rd Edition 12.10 */
1012 HRESULT with_statement_eval(script_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
1014 with_statement_t *stat = (with_statement_t*)_stat;
1015 exprval_t exprval;
1016 IDispatch *disp;
1017 jsdisp_t *obj;
1018 VARIANT val;
1019 HRESULT hres;
1021 TRACE("\n");
1023 hres = expr_eval(ctx, stat->expr, 0, &rt->ei, &exprval);
1024 if(FAILED(hres))
1025 return hres;
1027 hres = exprval_to_value(ctx, &exprval, &rt->ei, &val);
1028 exprval_release(&exprval);
1029 if(FAILED(hres))
1030 return hres;
1032 hres = to_object(ctx, &val, &disp);
1033 VariantClear(&val);
1034 if(FAILED(hres))
1035 return hres;
1037 obj = iface_to_jsdisp((IUnknown*)disp);
1038 IDispatch_Release(disp);
1039 if(!obj) {
1040 FIXME("disp id not jsdisp\n");
1041 return E_NOTIMPL;
1044 hres = scope_push(ctx->exec_ctx->scope_chain, obj, &ctx->exec_ctx->scope_chain);
1045 jsdisp_release(obj);
1046 if(FAILED(hres))
1047 return hres;
1049 hres = stat_eval(ctx, stat->statement, rt, ret);
1051 scope_pop(&ctx->exec_ctx->scope_chain);
1052 return hres;
1055 /* ECMA-262 3rd Edition 12.12 */
1056 HRESULT labelled_statement_eval(script_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
1058 FIXME("\n");
1059 return E_NOTIMPL;
1062 /* ECMA-262 3rd Edition 12.13 */
1063 HRESULT switch_statement_eval(script_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
1065 switch_statement_t *stat = (switch_statement_t*)_stat;
1066 case_clausule_t *iter, *default_clausule = NULL;
1067 statement_t *stat_iter;
1068 VARIANT val, cval;
1069 exprval_t exprval;
1070 BOOL b;
1071 HRESULT hres;
1073 TRACE("\n");
1075 hres = expr_eval(ctx, stat->expr, 0, &rt->ei, &exprval);
1076 if(FAILED(hres))
1077 return hres;
1079 hres = exprval_to_value(ctx, &exprval, &rt->ei, &val);
1080 exprval_release(&exprval);
1081 if(FAILED(hres))
1082 return hres;
1084 for(iter = stat->case_list; iter; iter = iter->next) {
1085 if(!iter->expr) {
1086 default_clausule = iter;
1087 continue;
1090 hres = expr_eval(ctx, iter->expr, 0, &rt->ei, &exprval);
1091 if(FAILED(hres))
1092 break;
1094 hres = exprval_to_value(ctx, &exprval, &rt->ei, &cval);
1095 exprval_release(&exprval);
1096 if(FAILED(hres))
1097 break;
1099 hres = equal2_values(&val, &cval, &b);
1100 VariantClear(&cval);
1101 if(FAILED(hres) || b)
1102 break;
1105 VariantClear(&val);
1106 if(FAILED(hres))
1107 return hres;
1109 if(!iter)
1110 iter = default_clausule;
1112 V_VT(&val) = VT_EMPTY;
1113 if(iter) {
1114 VARIANT tmp;
1116 for(stat_iter = iter->stat; stat_iter; stat_iter = stat_iter->next) {
1117 hres = stat_eval(ctx, stat_iter, rt, &tmp);
1118 if(FAILED(hres))
1119 break;
1121 VariantClear(&val);
1122 val = tmp;
1124 if(rt->type != RT_NORMAL)
1125 break;
1129 if(FAILED(hres)) {
1130 VariantClear(&val);
1131 return hres;
1134 if(rt->type == RT_BREAK)
1135 rt->type = RT_NORMAL;
1137 *ret = val;
1138 return S_OK;
1141 /* ECMA-262 3rd Edition 12.13 */
1142 HRESULT throw_statement_eval(script_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
1144 expression_statement_t *stat = (expression_statement_t*)_stat;
1145 exprval_t exprval;
1146 VARIANT val;
1147 HRESULT hres;
1149 TRACE("\n");
1151 hres = expr_eval(ctx, stat->expr, 0, &rt->ei, &exprval);
1152 if(FAILED(hres))
1153 return hres;
1155 hres = exprval_to_value(ctx, &exprval, &rt->ei, &val);
1156 exprval_release(&exprval);
1157 if(FAILED(hres))
1158 return hres;
1160 rt->ei.var = val;
1161 return DISP_E_EXCEPTION;
1164 /* ECMA-262 3rd Edition 12.14 */
1165 static HRESULT catch_eval(script_ctx_t *ctx, catch_block_t *block, return_type_t *rt, VARIANT *ret)
1167 jsdisp_t *var_disp;
1168 VARIANT ex, val;
1169 HRESULT hres;
1171 ex = rt->ei.var;
1172 memset(&rt->ei, 0, sizeof(jsexcept_t));
1174 hres = create_dispex(ctx, NULL, NULL, &var_disp);
1175 if(SUCCEEDED(hres)) {
1176 hres = jsdisp_propput_name(var_disp, block->identifier, &ex, &rt->ei, NULL/*FIXME*/);
1177 if(SUCCEEDED(hres)) {
1178 hres = scope_push(ctx->exec_ctx->scope_chain, var_disp, &ctx->exec_ctx->scope_chain);
1179 if(SUCCEEDED(hres)) {
1180 hres = stat_eval(ctx, block->statement, rt, &val);
1181 scope_pop(&ctx->exec_ctx->scope_chain);
1185 jsdisp_release(var_disp);
1188 VariantClear(&ex);
1189 if(FAILED(hres))
1190 return hres;
1192 *ret = val;
1193 return S_OK;
1196 /* ECMA-262 3rd Edition 12.14 */
1197 HRESULT try_statement_eval(script_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
1199 try_statement_t *stat = (try_statement_t*)_stat;
1200 VARIANT val;
1201 HRESULT hres;
1203 TRACE("\n");
1205 hres = stat_eval(ctx, stat->try_statement, rt, &val);
1206 if(FAILED(hres)) {
1207 TRACE("EXCEPTION\n");
1208 if(!stat->catch_block)
1209 return hres;
1211 hres = catch_eval(ctx, stat->catch_block, rt, &val);
1212 if(FAILED(hres))
1213 return hres;
1216 if(stat->finally_statement) {
1217 VariantClear(&val);
1218 hres = stat_eval(ctx, stat->finally_statement, rt, &val);
1219 if(FAILED(hres))
1220 return hres;
1223 *ret = val;
1224 return S_OK;
1227 static HRESULT return_bool(exprval_t *ret, DWORD b)
1229 ret->type = EXPRVAL_VARIANT;
1230 V_VT(&ret->u.var) = VT_BOOL;
1231 V_BOOL(&ret->u.var) = b ? VARIANT_TRUE : VARIANT_FALSE;
1233 return S_OK;
1236 static HRESULT get_binary_expr_values(script_ctx_t *ctx, binary_expression_t *expr, jsexcept_t *ei, VARIANT *lval, VARIANT *rval)
1238 exprval_t exprval;
1239 HRESULT hres;
1241 hres = expr_eval(ctx, expr->expression1, 0, ei, &exprval);
1242 if(FAILED(hres))
1243 return hres;
1245 hres = exprval_to_value(ctx, &exprval, ei, lval);
1246 exprval_release(&exprval);
1247 if(FAILED(hres))
1248 return hres;
1250 hres = expr_eval(ctx, expr->expression2, 0, ei, &exprval);
1251 if(SUCCEEDED(hres)) {
1252 hres = exprval_to_value(ctx, &exprval, ei, rval);
1253 exprval_release(&exprval);
1256 if(FAILED(hres)) {
1257 VariantClear(lval);
1258 return hres;
1261 return S_OK;
1264 typedef HRESULT (*oper_t)(script_ctx_t*,VARIANT*,VARIANT*,jsexcept_t*,VARIANT*);
1266 static HRESULT binary_expr_eval(script_ctx_t *ctx, binary_expression_t *expr, oper_t oper, jsexcept_t *ei,
1267 exprval_t *ret)
1269 VARIANT lval, rval, retv;
1270 HRESULT hres;
1272 hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval);
1273 if(FAILED(hres))
1274 return hres;
1276 hres = oper(ctx, &lval, &rval, ei, &retv);
1277 VariantClear(&lval);
1278 VariantClear(&rval);
1279 if(FAILED(hres))
1280 return hres;
1282 ret->type = EXPRVAL_VARIANT;
1283 ret->u.var = retv;
1284 return S_OK;
1287 /* ECMA-262 3rd Edition 11.13.2 */
1288 static HRESULT assign_oper_eval(script_ctx_t *ctx, expression_t *lexpr, expression_t *rexpr, oper_t oper,
1289 jsexcept_t *ei, exprval_t *ret)
1291 VARIANT retv, lval, rval;
1292 exprval_t exprval, exprvalr;
1293 HRESULT hres;
1295 hres = expr_eval(ctx, lexpr, EXPR_NEWREF, ei, &exprval);
1296 if(FAILED(hres))
1297 return hres;
1299 hres = exprval_value(ctx, &exprval, ei, &lval);
1300 if(SUCCEEDED(hres)) {
1301 hres = expr_eval(ctx, rexpr, 0, ei, &exprvalr);
1302 if(SUCCEEDED(hres)) {
1303 hres = exprval_value(ctx, &exprvalr, ei, &rval);
1304 exprval_release(&exprvalr);
1306 if(SUCCEEDED(hres)) {
1307 hres = oper(ctx, &lval, &rval, ei, &retv);
1308 VariantClear(&rval);
1310 VariantClear(&lval);
1313 if(SUCCEEDED(hres)) {
1314 hres = put_value(ctx, &exprval, &retv, ei);
1315 if(FAILED(hres))
1316 VariantClear(&retv);
1318 exprval_release(&exprval);
1320 if(FAILED(hres))
1321 return hres;
1323 ret->type = EXPRVAL_VARIANT;
1324 ret->u.var = retv;
1325 return S_OK;
1328 /* ECMA-262 3rd Edition 13 */
1329 HRESULT function_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1331 function_expression_t *expr = (function_expression_t*)_expr;
1332 VARIANT var;
1333 HRESULT hres;
1335 TRACE("\n");
1337 if(expr->identifier) {
1338 hres = jsdisp_propget_name(ctx->exec_ctx->var_disp, expr->identifier, &var, ei, NULL/*FIXME*/);
1339 if(FAILED(hres))
1340 return hres;
1341 }else {
1342 jsdisp_t *dispex;
1344 hres = create_source_function(ctx->exec_ctx->parser, expr->parameter_list, expr->source_elements, ctx->exec_ctx->scope_chain,
1345 expr->src_str, expr->src_len, &dispex);
1346 if(FAILED(hres))
1347 return hres;
1349 var_set_jsdisp(&var, dispex);
1352 ret->type = EXPRVAL_VARIANT;
1353 ret->u.var = var;
1354 return S_OK;
1357 /* ECMA-262 3rd Edition 11.12 */
1358 HRESULT conditional_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1360 conditional_expression_t *expr = (conditional_expression_t*)_expr;
1361 exprval_t exprval;
1362 VARIANT_BOOL b;
1363 HRESULT hres;
1365 TRACE("\n");
1367 hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
1368 if(FAILED(hres))
1369 return hres;
1371 hres = exprval_to_boolean(ctx, &exprval, ei, &b);
1372 exprval_release(&exprval);
1373 if(FAILED(hres))
1374 return hres;
1376 return expr_eval(ctx, b ? expr->true_expression : expr->false_expression, flags, ei, ret);
1379 /* ECMA-262 3rd Edition 11.2.1 */
1380 HRESULT array_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1382 array_expression_t *expr = (array_expression_t*)_expr;
1383 exprval_t exprval;
1384 VARIANT member, val;
1385 DISPID id;
1386 BSTR str;
1387 IDispatch *obj = NULL;
1388 HRESULT hres;
1390 TRACE("\n");
1392 hres = expr_eval(ctx, expr->member_expr, 0, ei, &exprval);
1393 if(FAILED(hres))
1394 return hres;
1396 hres = exprval_to_value(ctx, &exprval, ei, &member);
1397 exprval_release(&exprval);
1398 if(FAILED(hres))
1399 return hres;
1401 hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval);
1402 if(SUCCEEDED(hres)) {
1403 hres = exprval_to_value(ctx, &exprval, ei, &val);
1404 exprval_release(&exprval);
1407 if(SUCCEEDED(hres)) {
1408 hres = to_object(ctx, &member, &obj);
1409 if(FAILED(hres))
1410 VariantClear(&val);
1412 VariantClear(&member);
1413 if(SUCCEEDED(hres)) {
1414 hres = to_string(ctx, &val, ei, &str);
1415 VariantClear(&val);
1416 if(SUCCEEDED(hres)) {
1417 if(flags & EXPR_STRREF) {
1418 ret->type = EXPRVAL_NAMEREF;
1419 ret->u.nameref.disp = obj;
1420 ret->u.nameref.name = str;
1421 return S_OK;
1424 hres = disp_get_id(ctx, obj, str, flags & EXPR_NEWREF ? fdexNameEnsure : 0, &id);
1425 SysFreeString(str);
1428 if(SUCCEEDED(hres)) {
1429 exprval_set_idref(ret, obj, id);
1430 }else if(!(flags & EXPR_NEWREF) && hres == DISP_E_UNKNOWNNAME) {
1431 exprval_init(ret);
1432 hres = S_OK;
1435 IDispatch_Release(obj);
1438 return hres;
1441 /* ECMA-262 3rd Edition 11.2.1 */
1442 HRESULT member_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1444 member_expression_t *expr = (member_expression_t*)_expr;
1445 IDispatch *obj = NULL;
1446 exprval_t exprval;
1447 VARIANT member;
1448 DISPID id;
1449 BSTR str;
1450 HRESULT hres;
1452 TRACE("\n");
1454 hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
1455 if(FAILED(hres))
1456 return hres;
1458 hres = exprval_to_value(ctx, &exprval, ei, &member);
1459 exprval_release(&exprval);
1460 if(FAILED(hres))
1461 return hres;
1463 hres = to_object(ctx, &member, &obj);
1464 VariantClear(&member);
1465 if(FAILED(hres))
1466 return hres;
1468 str = SysAllocString(expr->identifier);
1469 if(flags & EXPR_STRREF) {
1470 ret->type = EXPRVAL_NAMEREF;
1471 ret->u.nameref.disp = obj;
1472 ret->u.nameref.name = str;
1473 return S_OK;
1476 hres = disp_get_id(ctx, obj, str, flags & EXPR_NEWREF ? fdexNameEnsure : 0, &id);
1477 SysFreeString(str);
1478 if(SUCCEEDED(hres)) {
1479 exprval_set_idref(ret, obj, id);
1480 }else if(!(flags & EXPR_NEWREF) && hres == DISP_E_UNKNOWNNAME) {
1481 exprval_init(ret);
1482 hres = S_OK;
1485 IDispatch_Release(obj);
1486 return hres;
1489 static void free_dp(DISPPARAMS *dp)
1491 DWORD i;
1493 for(i=0; i < dp->cArgs; i++)
1494 VariantClear(dp->rgvarg+i);
1495 heap_free(dp->rgvarg);
1498 static HRESULT args_to_param(script_ctx_t *ctx, argument_t *args, jsexcept_t *ei, DISPPARAMS *dp)
1500 VARIANTARG *vargs;
1501 exprval_t exprval;
1502 argument_t *iter;
1503 DWORD cnt = 0, i;
1504 HRESULT hres = S_OK;
1506 memset(dp, 0, sizeof(*dp));
1507 if(!args)
1508 return S_OK;
1510 for(iter = args; iter; iter = iter->next)
1511 cnt++;
1513 vargs = heap_alloc_zero(cnt * sizeof(*vargs));
1514 if(!vargs)
1515 return E_OUTOFMEMORY;
1517 for(i = cnt, iter = args; iter; iter = iter->next) {
1518 hres = expr_eval(ctx, iter->expr, 0, ei, &exprval);
1519 if(FAILED(hres))
1520 break;
1522 hres = exprval_to_value(ctx, &exprval, ei, vargs + (--i));
1523 exprval_release(&exprval);
1524 if(FAILED(hres))
1525 break;
1528 if(FAILED(hres)) {
1529 free_dp(dp);
1530 return hres;
1533 dp->rgvarg = vargs;
1534 dp->cArgs = cnt;
1535 return S_OK;
1538 /* ECMA-262 3rd Edition 11.2.2 */
1539 HRESULT new_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1541 call_expression_t *expr = (call_expression_t*)_expr;
1542 exprval_t exprval;
1543 VARIANT constr, var;
1544 DISPPARAMS dp;
1545 HRESULT hres;
1547 TRACE("\n");
1549 hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
1550 if(FAILED(hres))
1551 return hres;
1553 hres = args_to_param(ctx, expr->argument_list, ei, &dp);
1554 if(SUCCEEDED(hres))
1555 hres = exprval_to_value(ctx, &exprval, ei, &constr);
1556 exprval_release(&exprval);
1557 if(FAILED(hres))
1558 return hres;
1560 /* NOTE: Should use to_object here */
1562 if(V_VT(&constr) == VT_NULL) {
1563 VariantClear(&constr);
1564 return throw_type_error(ctx, ei, JS_E_OBJECT_EXPECTED, NULL);
1565 } else if(V_VT(&constr) != VT_DISPATCH) {
1566 VariantClear(&constr);
1567 return throw_type_error(ctx, ei, JS_E_INVALID_ACTION, NULL);
1568 } else if(!V_DISPATCH(&constr)) {
1569 VariantClear(&constr);
1570 return throw_type_error(ctx, ei, JS_E_INVALID_PROPERTY, NULL);
1573 hres = disp_call(ctx, V_DISPATCH(&constr), DISPID_VALUE,
1574 DISPATCH_CONSTRUCT, &dp, &var, ei, NULL/*FIXME*/);
1575 IDispatch_Release(V_DISPATCH(&constr));
1576 free_dp(&dp);
1577 if(FAILED(hres))
1578 return hres;
1580 ret->type = EXPRVAL_VARIANT;
1581 ret->u.var = var;
1582 return S_OK;
1585 /* ECMA-262 3rd Edition 11.2.3 */
1586 HRESULT call_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1588 call_expression_t *expr = (call_expression_t*)_expr;
1589 VARIANT var;
1590 exprval_t exprval;
1591 DISPPARAMS dp;
1592 HRESULT hres;
1594 TRACE("\n");
1596 hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
1597 if(FAILED(hres))
1598 return hres;
1600 hres = args_to_param(ctx, expr->argument_list, ei, &dp);
1601 if(SUCCEEDED(hres)) {
1602 switch(exprval.type) {
1603 case EXPRVAL_VARIANT:
1604 if(V_VT(&exprval.u.var) == VT_DISPATCH)
1605 hres = disp_call(ctx, V_DISPATCH(&exprval.u.var), DISPID_VALUE,
1606 DISPATCH_METHOD, &dp, flags & EXPR_NOVAL ? NULL : &var, ei, NULL/*FIXME*/);
1607 else
1608 hres = throw_type_error(ctx, ei, JS_E_INVALID_PROPERTY, NULL);
1609 break;
1610 case EXPRVAL_IDREF:
1611 hres = disp_call(ctx, exprval.u.idref.disp, exprval.u.idref.id,
1612 DISPATCH_METHOD, &dp, flags & EXPR_NOVAL ? NULL : &var, ei, NULL/*FIXME*/);
1613 break;
1614 case EXPRVAL_INVALID:
1615 hres = throw_type_error(ctx, ei, JS_E_OBJECT_EXPECTED, NULL);
1616 break;
1617 default:
1618 FIXME("unimplemented type %d\n", exprval.type);
1619 hres = E_NOTIMPL;
1622 free_dp(&dp);
1625 exprval_release(&exprval);
1626 if(FAILED(hres))
1627 return hres;
1629 ret->type = EXPRVAL_VARIANT;
1630 if(flags & EXPR_NOVAL) {
1631 V_VT(&ret->u.var) = VT_EMPTY;
1632 }else {
1633 TRACE("= %s\n", debugstr_variant(&var));
1634 ret->u.var = var;
1636 return S_OK;
1639 /* ECMA-262 3rd Edition 11.1.1 */
1640 HRESULT this_expression_eval(script_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1642 TRACE("\n");
1644 ret->type = EXPRVAL_VARIANT;
1645 V_VT(&ret->u.var) = VT_DISPATCH;
1646 V_DISPATCH(&ret->u.var) = ctx->exec_ctx->this_obj;
1647 IDispatch_AddRef(ctx->exec_ctx->this_obj);
1648 return S_OK;
1651 /* ECMA-262 3rd Edition 10.1.4 */
1652 HRESULT identifier_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1654 identifier_expression_t *expr = (identifier_expression_t*)_expr;
1655 BSTR identifier;
1656 HRESULT hres;
1658 TRACE("\n");
1660 identifier = SysAllocString(expr->identifier);
1661 if(!identifier)
1662 return E_OUTOFMEMORY;
1664 hres = identifier_eval(ctx, identifier, flags, ei, ret);
1666 SysFreeString(identifier);
1667 return hres;
1670 /* ECMA-262 3rd Edition 7.8 */
1671 HRESULT literal_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1673 literal_expression_t *expr = (literal_expression_t*)_expr;
1674 VARIANT var;
1675 HRESULT hres;
1677 TRACE("\n");
1679 hres = literal_to_var(ctx, expr->literal, &var);
1680 if(FAILED(hres))
1681 return hres;
1683 ret->type = EXPRVAL_VARIANT;
1684 ret->u.var = var;
1685 return S_OK;
1688 /* ECMA-262 3rd Edition 11.1.4 */
1689 HRESULT array_literal_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1691 array_literal_expression_t *expr = (array_literal_expression_t*)_expr;
1692 DWORD length = 0, i = 0;
1693 array_element_t *elem;
1694 jsdisp_t *array;
1695 exprval_t exprval;
1696 VARIANT val;
1697 HRESULT hres;
1699 TRACE("\n");
1701 for(elem = expr->element_list; elem; elem = elem->next)
1702 length += elem->elision+1;
1703 length += expr->length;
1705 hres = create_array(ctx, length, &array);
1706 if(FAILED(hres))
1707 return hres;
1709 for(elem = expr->element_list; elem; elem = elem->next) {
1710 i += elem->elision;
1712 hres = expr_eval(ctx, elem->expr, 0, ei, &exprval);
1713 if(FAILED(hres))
1714 break;
1716 hres = exprval_to_value(ctx, &exprval, ei, &val);
1717 exprval_release(&exprval);
1718 if(FAILED(hres))
1719 break;
1721 hres = jsdisp_propput_idx(array, i, &val, ei, NULL/*FIXME*/);
1722 VariantClear(&val);
1723 if(FAILED(hres))
1724 break;
1726 i++;
1729 if(FAILED(hres)) {
1730 jsdisp_release(array);
1731 return hres;
1734 ret->type = EXPRVAL_VARIANT;
1735 var_set_jsdisp(&ret->u.var, array);
1736 return S_OK;
1739 /* ECMA-262 3rd Edition 11.1.5 */
1740 HRESULT property_value_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1742 property_value_expression_t *expr = (property_value_expression_t*)_expr;
1743 VARIANT val, tmp;
1744 jsdisp_t *obj;
1745 prop_val_t *iter;
1746 exprval_t exprval;
1747 BSTR name;
1748 HRESULT hres;
1750 TRACE("\n");
1752 hres = create_object(ctx, NULL, &obj);
1753 if(FAILED(hres))
1754 return hres;
1756 for(iter = expr->property_list; iter; iter = iter->next) {
1757 hres = literal_to_var(ctx, iter->name, &tmp);
1758 if(FAILED(hres))
1759 break;
1761 hres = to_string(ctx, &tmp, ei, &name);
1762 VariantClear(&tmp);
1763 if(FAILED(hres))
1764 break;
1766 hres = expr_eval(ctx, iter->value, 0, ei, &exprval);
1767 if(SUCCEEDED(hres)) {
1768 hres = exprval_to_value(ctx, &exprval, ei, &val);
1769 exprval_release(&exprval);
1770 if(SUCCEEDED(hres)) {
1771 hres = jsdisp_propput_name(obj, name, &val, ei, NULL/*FIXME*/);
1772 VariantClear(&val);
1776 SysFreeString(name);
1777 if(FAILED(hres))
1778 break;
1781 if(FAILED(hres)) {
1782 jsdisp_release(obj);
1783 return hres;
1786 ret->type = EXPRVAL_VARIANT;
1787 var_set_jsdisp(&ret->u.var, obj);
1788 return S_OK;
1791 /* ECMA-262 3rd Edition 11.14 */
1792 HRESULT comma_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1794 binary_expression_t *expr = (binary_expression_t*)_expr;
1795 VARIANT lval, rval;
1796 HRESULT hres;
1798 TRACE("\n");
1800 hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval);
1801 if(FAILED(hres))
1802 return hres;
1804 VariantClear(&lval);
1806 ret->type = EXPRVAL_VARIANT;
1807 ret->u.var = rval;
1808 return S_OK;
1811 /* ECMA-262 3rd Edition 11.11 */
1812 HRESULT logical_or_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1814 binary_expression_t *expr = (binary_expression_t*)_expr;
1815 exprval_t exprval;
1816 VARIANT_BOOL b;
1817 VARIANT val;
1818 HRESULT hres;
1820 TRACE("\n");
1822 hres = expr_eval(ctx, expr->expression1, 0, ei, &exprval);
1823 if(FAILED(hres))
1824 return hres;
1826 hres = exprval_to_value(ctx, &exprval, ei, &val);
1827 exprval_release(&exprval);
1828 if(FAILED(hres))
1829 return hres;
1831 hres = to_boolean(&val, &b);
1832 if(SUCCEEDED(hres) && b) {
1833 ret->type = EXPRVAL_VARIANT;
1834 ret->u.var = val;
1835 return S_OK;
1838 VariantClear(&val);
1839 if(FAILED(hres))
1840 return hres;
1842 hres = expr_eval(ctx, expr->expression2, 0, ei, &exprval);
1843 if(FAILED(hres))
1844 return hres;
1846 hres = exprval_to_value(ctx, &exprval, ei, &val);
1847 exprval_release(&exprval);
1848 if(FAILED(hres))
1849 return hres;
1851 ret->type = EXPRVAL_VARIANT;
1852 ret->u.var = val;
1853 return S_OK;
1856 /* ECMA-262 3rd Edition 11.11 */
1857 HRESULT logical_and_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1859 binary_expression_t *expr = (binary_expression_t*)_expr;
1860 exprval_t exprval;
1861 VARIANT_BOOL b;
1862 VARIANT val;
1863 HRESULT hres;
1865 TRACE("\n");
1867 hres = expr_eval(ctx, expr->expression1, 0, ei, &exprval);
1868 if(FAILED(hres))
1869 return hres;
1871 hres = exprval_to_value(ctx, &exprval, ei, &val);
1872 exprval_release(&exprval);
1873 if(FAILED(hres))
1874 return hres;
1876 hres = to_boolean(&val, &b);
1877 if(SUCCEEDED(hres) && !b) {
1878 ret->type = EXPRVAL_VARIANT;
1879 ret->u.var = val;
1880 return S_OK;
1883 VariantClear(&val);
1884 if(FAILED(hres))
1885 return hres;
1887 hres = expr_eval(ctx, expr->expression2, 0, ei, &exprval);
1888 if(FAILED(hres))
1889 return hres;
1891 hres = exprval_to_value(ctx, &exprval, ei, &val);
1892 exprval_release(&exprval);
1893 if(FAILED(hres))
1894 return hres;
1896 ret->type = EXPRVAL_VARIANT;
1897 ret->u.var = val;
1898 return S_OK;
1901 /* ECMA-262 3rd Edition 11.10 */
1902 static HRESULT bitor_eval(script_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
1904 INT li, ri;
1905 HRESULT hres;
1907 hres = to_int32(ctx, lval, ei, &li);
1908 if(FAILED(hres))
1909 return hres;
1911 hres = to_int32(ctx, rval, ei, &ri);
1912 if(FAILED(hres))
1913 return hres;
1915 V_VT(retv) = VT_I4;
1916 V_I4(retv) = li|ri;
1917 return S_OK;
1920 /* ECMA-262 3rd Edition 11.10 */
1921 HRESULT binary_or_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1923 binary_expression_t *expr = (binary_expression_t*)_expr;
1925 TRACE("\n");
1927 return binary_expr_eval(ctx, expr, bitor_eval, ei, ret);
1930 /* ECMA-262 3rd Edition 11.10 */
1931 static HRESULT xor_eval(script_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
1933 INT li, ri;
1934 HRESULT hres;
1936 hres = to_int32(ctx, lval, ei, &li);
1937 if(FAILED(hres))
1938 return hres;
1940 hres = to_int32(ctx, rval, ei, &ri);
1941 if(FAILED(hres))
1942 return hres;
1944 V_VT(retv) = VT_I4;
1945 V_I4(retv) = li^ri;
1946 return S_OK;
1949 /* ECMA-262 3rd Edition 11.10 */
1950 HRESULT binary_xor_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1952 binary_expression_t *expr = (binary_expression_t*)_expr;
1954 TRACE("\n");
1956 return binary_expr_eval(ctx, expr, xor_eval, ei, ret);
1959 /* ECMA-262 3rd Edition 11.10 */
1960 static HRESULT bitand_eval(script_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
1962 INT li, ri;
1963 HRESULT hres;
1965 hres = to_int32(ctx, lval, ei, &li);
1966 if(FAILED(hres))
1967 return hres;
1969 hres = to_int32(ctx, rval, ei, &ri);
1970 if(FAILED(hres))
1971 return hres;
1973 V_VT(retv) = VT_I4;
1974 V_I4(retv) = li&ri;
1975 return S_OK;
1978 /* ECMA-262 3rd Edition 11.10 */
1979 HRESULT binary_and_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1981 binary_expression_t *expr = (binary_expression_t*)_expr;
1983 TRACE("\n");
1985 return binary_expr_eval(ctx, expr, bitand_eval, ei, ret);
1988 /* ECMA-262 3rd Edition 11.8.6 */
1989 static HRESULT instanceof_eval(script_ctx_t *ctx, VARIANT *inst, VARIANT *objv, jsexcept_t *ei, VARIANT *retv)
1991 jsdisp_t *obj, *iter, *tmp = NULL;
1992 VARIANT_BOOL ret = VARIANT_FALSE;
1993 BOOL b;
1994 VARIANT var;
1995 HRESULT hres;
1997 static const WCHAR prototypeW[] = {'p','r','o','t','o','t', 'y', 'p','e',0};
1999 if(V_VT(objv) != VT_DISPATCH || !V_DISPATCH(objv))
2000 return throw_type_error(ctx, ei, JS_E_FUNCTION_EXPECTED, NULL);
2002 obj = iface_to_jsdisp((IUnknown*)V_DISPATCH(objv));
2003 if(!obj) {
2004 FIXME("non-jsdisp objects not supported\n");
2005 return E_FAIL;
2008 if(is_class(obj, JSCLASS_FUNCTION)) {
2009 hres = jsdisp_propget_name(obj, prototypeW, &var, ei, NULL/*FIXME*/);
2010 }else {
2011 hres = throw_type_error(ctx, ei, JS_E_FUNCTION_EXPECTED, NULL);
2013 jsdisp_release(obj);
2014 if(FAILED(hres))
2015 return hres;
2017 if(V_VT(&var) == VT_DISPATCH) {
2018 if(V_VT(inst) == VT_DISPATCH)
2019 tmp = iface_to_jsdisp((IUnknown*)V_DISPATCH(inst));
2020 for(iter = tmp; iter; iter = iter->prototype) {
2021 hres = disp_cmp(V_DISPATCH(&var), to_disp(iter), &b);
2022 if(FAILED(hres))
2023 break;
2024 if(b) {
2025 ret = VARIANT_TRUE;
2026 break;
2030 if(tmp)
2031 jsdisp_release(tmp);
2032 }else {
2033 FIXME("prototype is not an object\n");
2034 hres = E_FAIL;
2037 VariantClear(&var);
2038 if(FAILED(hres))
2039 return hres;
2041 V_VT(retv) = VT_BOOL;
2042 V_BOOL(retv) = ret;
2043 return S_OK;
2046 /* ECMA-262 3rd Edition 11.8.6 */
2047 HRESULT instanceof_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2049 binary_expression_t *expr = (binary_expression_t*)_expr;
2051 TRACE("\n");
2053 return binary_expr_eval(ctx, expr, instanceof_eval, ei, ret);
2056 /* ECMA-262 3rd Edition 11.8.7 */
2057 static HRESULT in_eval(script_ctx_t *ctx, VARIANT *lval, VARIANT *obj, jsexcept_t *ei, VARIANT *retv)
2059 VARIANT_BOOL ret;
2060 DISPID id;
2061 BSTR str;
2062 HRESULT hres;
2064 if(V_VT(obj) != VT_DISPATCH || !V_DISPATCH(obj))
2065 return throw_type_error(ctx, ei, JS_E_OBJECT_EXPECTED, NULL);
2067 hres = to_string(ctx, lval, ei, &str);
2068 if(FAILED(hres))
2069 return hres;
2071 hres = disp_get_id(ctx, V_DISPATCH(obj), str, 0, &id);
2072 SysFreeString(str);
2073 if(SUCCEEDED(hres))
2074 ret = VARIANT_TRUE;
2075 else if(hres == DISP_E_UNKNOWNNAME)
2076 ret = VARIANT_FALSE;
2077 else
2078 return hres;
2080 V_VT(retv) = VT_BOOL;
2081 V_BOOL(retv) = ret;
2082 return S_OK;
2085 /* ECMA-262 3rd Edition 11.8.7 */
2086 HRESULT in_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2088 binary_expression_t *expr = (binary_expression_t*)_expr;
2090 TRACE("\n");
2092 return binary_expr_eval(ctx, expr, in_eval, ei, ret);
2095 /* ECMA-262 3rd Edition 11.6.1 */
2096 static HRESULT add_eval(script_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
2098 VARIANT r, l;
2099 HRESULT hres;
2101 hres = to_primitive(ctx, lval, ei, &l, NO_HINT);
2102 if(FAILED(hres))
2103 return hres;
2105 hres = to_primitive(ctx, rval, ei, &r, NO_HINT);
2106 if(FAILED(hres)) {
2107 VariantClear(&l);
2108 return hres;
2111 if(V_VT(&l) == VT_BSTR || V_VT(&r) == VT_BSTR) {
2112 BSTR lstr = NULL, rstr = NULL;
2114 if(V_VT(&l) == VT_BSTR)
2115 lstr = V_BSTR(&l);
2116 else
2117 hres = to_string(ctx, &l, ei, &lstr);
2119 if(SUCCEEDED(hres)) {
2120 if(V_VT(&r) == VT_BSTR)
2121 rstr = V_BSTR(&r);
2122 else
2123 hres = to_string(ctx, &r, ei, &rstr);
2126 if(SUCCEEDED(hres)) {
2127 int len1, len2;
2129 len1 = SysStringLen(lstr);
2130 len2 = SysStringLen(rstr);
2132 V_VT(retv) = VT_BSTR;
2133 V_BSTR(retv) = SysAllocStringLen(NULL, len1+len2);
2134 memcpy(V_BSTR(retv), lstr, len1*sizeof(WCHAR));
2135 memcpy(V_BSTR(retv)+len1, rstr, (len2+1)*sizeof(WCHAR));
2138 if(V_VT(&l) != VT_BSTR)
2139 SysFreeString(lstr);
2140 if(V_VT(&r) != VT_BSTR)
2141 SysFreeString(rstr);
2142 }else {
2143 VARIANT nl, nr;
2145 hres = to_number(ctx, &l, ei, &nl);
2146 if(SUCCEEDED(hres)) {
2147 hres = to_number(ctx, &r, ei, &nr);
2148 if(SUCCEEDED(hres))
2149 num_set_val(retv, num_val(&nl) + num_val(&nr));
2153 VariantClear(&r);
2154 VariantClear(&l);
2155 return hres;
2158 /* ECMA-262 3rd Edition 11.6.1 */
2159 HRESULT add_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2161 binary_expression_t *expr = (binary_expression_t*)_expr;
2163 TRACE("\n");
2165 return binary_expr_eval(ctx, expr, add_eval, ei, ret);
2168 /* ECMA-262 3rd Edition 11.6.2 */
2169 static HRESULT sub_eval(script_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
2171 VARIANT lnum, rnum;
2172 HRESULT hres;
2174 hres = to_number(ctx, lval, ei, &lnum);
2175 if(FAILED(hres))
2176 return hres;
2178 hres = to_number(ctx, rval, ei, &rnum);
2179 if(FAILED(hres))
2180 return hres;
2182 num_set_val(retv, num_val(&lnum) - num_val(&rnum));
2183 return S_OK;
2186 /* ECMA-262 3rd Edition 11.6.2 */
2187 HRESULT sub_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2189 binary_expression_t *expr = (binary_expression_t*)_expr;
2191 TRACE("\n");
2193 return binary_expr_eval(ctx, expr, sub_eval, ei, ret);
2196 /* ECMA-262 3rd Edition 11.5.1 */
2197 static HRESULT mul_eval(script_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
2199 VARIANT lnum, rnum;
2200 HRESULT hres;
2202 hres = to_number(ctx, lval, ei, &lnum);
2203 if(FAILED(hres))
2204 return hres;
2206 hres = to_number(ctx, rval, ei, &rnum);
2207 if(FAILED(hres))
2208 return hres;
2210 num_set_val(retv, num_val(&lnum) * num_val(&rnum));
2211 return S_OK;
2214 /* ECMA-262 3rd Edition 11.5.1 */
2215 HRESULT mul_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2217 binary_expression_t *expr = (binary_expression_t*)_expr;
2219 TRACE("\n");
2221 return binary_expr_eval(ctx, expr, mul_eval, ei, ret);
2224 /* ECMA-262 3rd Edition 11.5.2 */
2225 static HRESULT div_eval(script_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
2227 VARIANT lnum, rnum;
2228 HRESULT hres;
2230 hres = to_number(ctx, lval, ei, &lnum);
2231 if(FAILED(hres))
2232 return hres;
2234 hres = to_number(ctx, rval, ei, &rnum);
2235 if(FAILED(hres))
2236 return hres;
2238 num_set_val(retv, num_val(&lnum) / num_val(&rnum));
2239 return S_OK;
2242 /* ECMA-262 3rd Edition 11.5.2 */
2243 HRESULT div_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2245 binary_expression_t *expr = (binary_expression_t*)_expr;
2247 TRACE("\n");
2249 return binary_expr_eval(ctx, expr, div_eval, ei, ret);
2252 /* ECMA-262 3rd Edition 11.5.3 */
2253 static HRESULT mod_eval(script_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
2255 VARIANT lnum, rnum;
2256 HRESULT hres;
2258 hres = to_number(ctx, lval, ei, &lnum);
2259 if(FAILED(hres))
2260 return hres;
2262 hres = to_number(ctx, rval, ei, &rnum);
2263 if(FAILED(hres))
2264 return hres;
2266 num_set_val(retv, fmod(num_val(&lnum), num_val(&rnum)));
2267 return S_OK;
2270 /* ECMA-262 3rd Edition 11.5.3 */
2271 HRESULT mod_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2273 binary_expression_t *expr = (binary_expression_t*)_expr;
2275 TRACE("\n");
2277 return binary_expr_eval(ctx, expr, mod_eval, ei, ret);
2280 /* ECMA-262 3rd Edition 11.4.2 */
2281 HRESULT delete_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2283 unary_expression_t *expr = (unary_expression_t*)_expr;
2284 VARIANT_BOOL b = VARIANT_FALSE;
2285 exprval_t exprval;
2286 HRESULT hres;
2288 TRACE("\n");
2290 hres = expr_eval(ctx, expr->expression, EXPR_STRREF, ei, &exprval);
2291 if(FAILED(hres))
2292 return hres;
2294 switch(exprval.type) {
2295 case EXPRVAL_IDREF: {
2296 IDispatchEx *dispex;
2298 hres = IDispatch_QueryInterface(exprval.u.nameref.disp, &IID_IDispatchEx, (void**)&dispex);
2299 if(SUCCEEDED(hres)) {
2300 hres = IDispatchEx_DeleteMemberByDispID(dispex, exprval.u.idref.id);
2301 b = VARIANT_TRUE;
2302 IDispatchEx_Release(dispex);
2304 break;
2306 case EXPRVAL_NAMEREF: {
2307 IDispatchEx *dispex;
2309 hres = IDispatch_QueryInterface(exprval.u.nameref.disp, &IID_IDispatchEx, (void**)&dispex);
2310 if(SUCCEEDED(hres)) {
2311 hres = IDispatchEx_DeleteMemberByName(dispex, exprval.u.nameref.name,
2312 make_grfdex(ctx, fdexNameCaseSensitive));
2313 b = VARIANT_TRUE;
2314 IDispatchEx_Release(dispex);
2316 break;
2318 default:
2319 FIXME("unsupported type %d\n", exprval.type);
2320 hres = E_NOTIMPL;
2323 exprval_release(&exprval);
2324 if(FAILED(hres))
2325 return hres;
2327 return return_bool(ret, b);
2330 /* ECMA-262 3rd Edition 11.4.2 */
2331 HRESULT void_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2333 unary_expression_t *expr = (unary_expression_t*)_expr;
2334 exprval_t exprval;
2335 VARIANT tmp;
2336 HRESULT hres;
2338 TRACE("\n");
2340 hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
2341 if(FAILED(hres))
2342 return hres;
2344 hres = exprval_to_value(ctx, &exprval, ei, &tmp);
2345 exprval_release(&exprval);
2346 if(FAILED(hres))
2347 return hres;
2349 VariantClear(&tmp);
2351 ret->type = EXPRVAL_VARIANT;
2352 V_VT(&ret->u.var) = VT_EMPTY;
2353 return S_OK;
2356 /* ECMA-262 3rd Edition 11.4.3 */
2357 static HRESULT typeof_exprval(script_ctx_t *ctx, exprval_t *exprval, jsexcept_t *ei, const WCHAR **ret)
2359 VARIANT val;
2360 HRESULT hres;
2362 static const WCHAR booleanW[] = {'b','o','o','l','e','a','n',0};
2363 static const WCHAR functionW[] = {'f','u','n','c','t','i','o','n',0};
2364 static const WCHAR numberW[] = {'n','u','m','b','e','r',0};
2365 static const WCHAR objectW[] = {'o','b','j','e','c','t',0};
2366 static const WCHAR stringW[] = {'s','t','r','i','n','g',0};
2367 static const WCHAR undefinedW[] = {'u','n','d','e','f','i','n','e','d',0};
2368 static const WCHAR unknownW[] = {'u','n','k','n','o','w','n',0};
2370 if(exprval->type == EXPRVAL_INVALID) {
2371 *ret = undefinedW;
2372 return S_OK;
2375 hres = exprval_to_value(ctx, exprval, ei, &val);
2376 if(FAILED(hres)) {
2377 if(exprval->type == EXPRVAL_IDREF) {
2378 *ret = unknownW;
2379 return S_OK;
2381 return hres;
2384 switch(V_VT(&val)) {
2385 case VT_EMPTY:
2386 *ret = undefinedW;
2387 break;
2388 case VT_NULL:
2389 *ret = objectW;
2390 break;
2391 case VT_BOOL:
2392 *ret = booleanW;
2393 break;
2394 case VT_I4:
2395 case VT_R8:
2396 *ret = numberW;
2397 break;
2398 case VT_BSTR:
2399 *ret = stringW;
2400 break;
2401 case VT_DISPATCH: {
2402 jsdisp_t *dispex;
2404 if(V_DISPATCH(&val) && (dispex = iface_to_jsdisp((IUnknown*)V_DISPATCH(&val)))) {
2405 *ret = is_class(dispex, JSCLASS_FUNCTION) ? functionW : objectW;
2406 jsdisp_release(dispex);
2407 }else {
2408 *ret = objectW;
2410 break;
2412 default:
2413 FIXME("unhandled vt %d\n", V_VT(&val));
2414 hres = E_NOTIMPL;
2417 VariantClear(&val);
2418 return hres;
2421 HRESULT typeof_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2423 unary_expression_t *expr = (unary_expression_t*)_expr;
2424 const WCHAR *str = NULL;
2425 exprval_t exprval;
2426 HRESULT hres;
2428 TRACE("\n");
2430 hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
2431 if(FAILED(hres))
2432 return hres;
2434 hres = typeof_exprval(ctx, &exprval, ei, &str);
2435 exprval_release(&exprval);
2436 if(FAILED(hres))
2437 return hres;
2439 ret->type = EXPRVAL_VARIANT;
2440 V_VT(&ret->u.var) = VT_BSTR;
2441 V_BSTR(&ret->u.var) = SysAllocString(str);
2442 if(!V_BSTR(&ret->u.var))
2443 return E_OUTOFMEMORY;
2445 return S_OK;
2448 /* ECMA-262 3rd Edition 11.4.7 */
2449 HRESULT minus_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2451 unary_expression_t *expr = (unary_expression_t*)_expr;
2452 exprval_t exprval;
2453 VARIANT val, num;
2454 HRESULT hres;
2456 TRACE("\n");
2458 hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
2459 if(FAILED(hres))
2460 return hres;
2462 hres = exprval_to_value(ctx, &exprval, ei, &val);
2463 exprval_release(&exprval);
2464 if(FAILED(hres))
2465 return hres;
2467 hres = to_number(ctx, &val, ei, &num);
2468 VariantClear(&val);
2469 if(FAILED(hres))
2470 return hres;
2472 ret->type = EXPRVAL_VARIANT;
2473 num_set_val(&ret->u.var, -num_val(&num));
2474 return S_OK;
2477 /* ECMA-262 3rd Edition 11.4.6 */
2478 HRESULT plus_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2480 unary_expression_t *expr = (unary_expression_t*)_expr;
2481 exprval_t exprval;
2482 VARIANT val, num;
2483 HRESULT hres;
2485 TRACE("\n");
2487 hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval);
2488 if(FAILED(hres))
2489 return hres;
2491 hres = exprval_to_value(ctx, &exprval, ei, &val);
2492 exprval_release(&exprval);
2493 if(FAILED(hres))
2494 return hres;
2496 hres = to_number(ctx, &val, ei, &num);
2497 VariantClear(&val);
2498 if(FAILED(hres))
2499 return hres;
2501 ret->type = EXPRVAL_VARIANT;
2502 ret->u.var = num;
2503 return S_OK;
2506 /* ECMA-262 3rd Edition 11.3.1 */
2507 HRESULT post_increment_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2509 unary_expression_t *expr = (unary_expression_t*)_expr;
2510 VARIANT val, num;
2511 exprval_t exprval;
2512 HRESULT hres;
2514 TRACE("\n");
2516 hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval);
2517 if(FAILED(hres))
2518 return hres;
2520 hres = exprval_value(ctx, &exprval, ei, &val);
2521 if(SUCCEEDED(hres)) {
2522 hres = to_number(ctx, &val, ei, &num);
2523 VariantClear(&val);
2526 if(SUCCEEDED(hres)) {
2527 VARIANT inc;
2528 num_set_val(&inc, num_val(&num)+1.0);
2529 hres = put_value(ctx, &exprval, &inc, ei);
2532 exprval_release(&exprval);
2533 if(FAILED(hres))
2534 return hres;
2536 ret->type = EXPRVAL_VARIANT;
2537 ret->u.var = num;
2538 return S_OK;
2541 /* ECMA-262 3rd Edition 11.3.2 */
2542 HRESULT post_decrement_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2544 unary_expression_t *expr = (unary_expression_t*)_expr;
2545 VARIANT val, num;
2546 exprval_t exprval;
2547 HRESULT hres;
2549 TRACE("\n");
2551 hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval);
2552 if(FAILED(hres))
2553 return hres;
2555 hres = exprval_value(ctx, &exprval, ei, &val);
2556 if(SUCCEEDED(hres)) {
2557 hres = to_number(ctx, &val, ei, &num);
2558 VariantClear(&val);
2561 if(SUCCEEDED(hres)) {
2562 VARIANT dec;
2563 num_set_val(&dec, num_val(&num)-1.0);
2564 hres = put_value(ctx, &exprval, &dec, ei);
2567 exprval_release(&exprval);
2568 if(FAILED(hres))
2569 return hres;
2571 ret->type = EXPRVAL_VARIANT;
2572 ret->u.var = num;
2573 return S_OK;
2576 /* ECMA-262 3rd Edition 11.4.4 */
2577 HRESULT pre_increment_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2579 unary_expression_t *expr = (unary_expression_t*)_expr;
2580 VARIANT val, num;
2581 exprval_t exprval;
2582 HRESULT hres;
2584 TRACE("\n");
2586 hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval);
2587 if(FAILED(hres))
2588 return hres;
2590 hres = exprval_value(ctx, &exprval, ei, &val);
2591 if(SUCCEEDED(hres)) {
2592 hres = to_number(ctx, &val, ei, &num);
2593 VariantClear(&val);
2596 if(SUCCEEDED(hres)) {
2597 num_set_val(&val, num_val(&num)+1.0);
2598 hres = put_value(ctx, &exprval, &val, ei);
2601 exprval_release(&exprval);
2602 if(FAILED(hres))
2603 return hres;
2605 ret->type = EXPRVAL_VARIANT;
2606 ret->u.var = val;
2607 return S_OK;
2610 /* ECMA-262 3rd Edition 11.4.5 */
2611 HRESULT pre_decrement_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2613 unary_expression_t *expr = (unary_expression_t*)_expr;
2614 VARIANT val, num;
2615 exprval_t exprval;
2616 HRESULT hres;
2618 TRACE("\n");
2620 hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval);
2621 if(FAILED(hres))
2622 return hres;
2624 hres = exprval_value(ctx, &exprval, ei, &val);
2625 if(SUCCEEDED(hres)) {
2626 hres = to_number(ctx, &val, ei, &num);
2627 VariantClear(&val);
2630 if(SUCCEEDED(hres)) {
2631 num_set_val(&val, num_val(&num)-1.0);
2632 hres = put_value(ctx, &exprval, &val, ei);
2635 exprval_release(&exprval);
2636 if(FAILED(hres))
2637 return hres;
2639 ret->type = EXPRVAL_VARIANT;
2640 ret->u.var = val;
2641 return S_OK;
2644 /* ECMA-262 3rd Edition 11.9.3 */
2645 static HRESULT equal_values(script_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, BOOL *ret)
2647 if(V_VT(lval) == V_VT(rval) || (is_num_vt(V_VT(lval)) && is_num_vt(V_VT(rval))))
2648 return equal2_values(lval, rval, ret);
2650 /* FIXME: NULL disps should be handled in more general way */
2651 if(V_VT(lval) == VT_DISPATCH && !V_DISPATCH(lval)) {
2652 VARIANT v;
2653 V_VT(&v) = VT_NULL;
2654 return equal_values(ctx, &v, rval, ei, ret);
2657 if(V_VT(rval) == VT_DISPATCH && !V_DISPATCH(rval)) {
2658 VARIANT v;
2659 V_VT(&v) = VT_NULL;
2660 return equal_values(ctx, lval, &v, ei, ret);
2663 if((V_VT(lval) == VT_NULL && V_VT(rval) == VT_EMPTY) ||
2664 (V_VT(lval) == VT_EMPTY && V_VT(rval) == VT_NULL)) {
2665 *ret = TRUE;
2666 return S_OK;
2669 if(V_VT(lval) == VT_BSTR && is_num_vt(V_VT(rval))) {
2670 VARIANT v;
2671 HRESULT hres;
2673 hres = to_number(ctx, lval, ei, &v);
2674 if(FAILED(hres))
2675 return hres;
2677 return equal_values(ctx, &v, rval, ei, ret);
2680 if(V_VT(rval) == VT_BSTR && is_num_vt(V_VT(lval))) {
2681 VARIANT v;
2682 HRESULT hres;
2684 hres = to_number(ctx, rval, ei, &v);
2685 if(FAILED(hres))
2686 return hres;
2688 return equal_values(ctx, lval, &v, ei, ret);
2691 if(V_VT(rval) == VT_BOOL) {
2692 VARIANT v;
2694 V_VT(&v) = VT_I4;
2695 V_I4(&v) = V_BOOL(rval) ? 1 : 0;
2696 return equal_values(ctx, lval, &v, ei, ret);
2699 if(V_VT(lval) == VT_BOOL) {
2700 VARIANT v;
2702 V_VT(&v) = VT_I4;
2703 V_I4(&v) = V_BOOL(lval) ? 1 : 0;
2704 return equal_values(ctx, &v, rval, ei, ret);
2708 if(V_VT(rval) == VT_DISPATCH && (V_VT(lval) == VT_BSTR || is_num_vt(V_VT(lval)))) {
2709 VARIANT v;
2710 HRESULT hres;
2712 hres = to_primitive(ctx, rval, ei, &v, NO_HINT);
2713 if(FAILED(hres))
2714 return hres;
2716 hres = equal_values(ctx, lval, &v, ei, ret);
2718 VariantClear(&v);
2719 return hres;
2723 if(V_VT(lval) == VT_DISPATCH && (V_VT(rval) == VT_BSTR || is_num_vt(V_VT(rval)))) {
2724 VARIANT v;
2725 HRESULT hres;
2727 hres = to_primitive(ctx, lval, ei, &v, NO_HINT);
2728 if(FAILED(hres))
2729 return hres;
2731 hres = equal_values(ctx, &v, rval, ei, ret);
2733 VariantClear(&v);
2734 return hres;
2738 *ret = FALSE;
2739 return S_OK;
2742 /* ECMA-262 3rd Edition 11.9.1 */
2743 HRESULT equal_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2745 binary_expression_t *expr = (binary_expression_t*)_expr;
2746 VARIANT rval, lval;
2747 BOOL b;
2748 HRESULT hres;
2750 TRACE("\n");
2752 hres = get_binary_expr_values(ctx, expr, ei, &rval, &lval);
2753 if(FAILED(hres))
2754 return hres;
2756 hres = equal_values(ctx, &rval, &lval, ei, &b);
2757 VariantClear(&lval);
2758 VariantClear(&rval);
2759 if(FAILED(hres))
2760 return hres;
2762 return return_bool(ret, b);
2765 /* ECMA-262 3rd Edition 11.9.4 */
2766 HRESULT equal2_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2768 binary_expression_t *expr = (binary_expression_t*)_expr;
2769 VARIANT rval, lval;
2770 BOOL b;
2771 HRESULT hres;
2773 TRACE("\n");
2775 hres = get_binary_expr_values(ctx, expr, ei, &rval, &lval);
2776 if(FAILED(hres))
2777 return hres;
2779 hres = equal2_values(&rval, &lval, &b);
2780 VariantClear(&lval);
2781 VariantClear(&rval);
2782 if(FAILED(hres))
2783 return hres;
2785 return return_bool(ret, b);
2788 /* ECMA-262 3rd Edition 11.9.2 */
2789 HRESULT not_equal_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2791 binary_expression_t *expr = (binary_expression_t*)_expr;
2792 VARIANT rval, lval;
2793 BOOL b;
2794 HRESULT hres;
2796 TRACE("\n");
2798 hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval);
2799 if(FAILED(hres))
2800 return hres;
2802 hres = equal_values(ctx, &lval, &rval, ei, &b);
2803 VariantClear(&lval);
2804 VariantClear(&rval);
2805 if(FAILED(hres))
2806 return hres;
2808 return return_bool(ret, !b);
2811 /* ECMA-262 3rd Edition 11.9.5 */
2812 HRESULT not_equal2_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2814 binary_expression_t *expr = (binary_expression_t*)_expr;
2815 VARIANT rval, lval;
2816 BOOL b;
2817 HRESULT hres;
2819 TRACE("\n");
2821 hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval);
2822 if(FAILED(hres))
2823 return hres;
2825 hres = equal2_values(&lval, &rval, &b);
2826 VariantClear(&lval);
2827 VariantClear(&rval);
2828 if(FAILED(hres))
2829 return hres;
2831 return return_bool(ret, !b);
2834 /* ECMA-262 3rd Edition 11.8.5 */
2835 static HRESULT less_eval(script_ctx_t *ctx, VARIANT *lval, VARIANT *rval, BOOL greater, jsexcept_t *ei, BOOL *ret)
2837 VARIANT l, r, ln, rn;
2838 HRESULT hres;
2840 hres = to_primitive(ctx, lval, ei, &l, NO_HINT);
2841 if(FAILED(hres))
2842 return hres;
2844 hres = to_primitive(ctx, rval, ei, &r, NO_HINT);
2845 if(FAILED(hres)) {
2846 VariantClear(&l);
2847 return hres;
2850 if(V_VT(&l) == VT_BSTR && V_VT(&r) == VT_BSTR) {
2851 *ret = (strcmpW(V_BSTR(&l), V_BSTR(&r)) < 0) ^ greater;
2852 SysFreeString(V_BSTR(&l));
2853 SysFreeString(V_BSTR(&r));
2854 return S_OK;
2857 hres = to_number(ctx, &l, ei, &ln);
2858 VariantClear(&l);
2859 if(SUCCEEDED(hres))
2860 hres = to_number(ctx, &r, ei, &rn);
2861 VariantClear(&r);
2862 if(FAILED(hres))
2863 return hres;
2865 if(V_VT(&ln) == VT_I4 && V_VT(&rn) == VT_I4) {
2866 *ret = (V_I4(&ln) < V_I4(&rn)) ^ greater;
2867 }else {
2868 DOUBLE ld = num_val(&ln);
2869 DOUBLE rd = num_val(&rn);
2871 *ret = !isnan(ld) && !isnan(rd) && ((ld < rd) ^ greater);
2874 return S_OK;
2877 /* ECMA-262 3rd Edition 11.8.1 */
2878 HRESULT less_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2880 binary_expression_t *expr = (binary_expression_t*)_expr;
2881 VARIANT rval, lval;
2882 BOOL b;
2883 HRESULT hres;
2885 TRACE("\n");
2887 hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval);
2888 if(FAILED(hres))
2889 return hres;
2891 hres = less_eval(ctx, &lval, &rval, FALSE, ei, &b);
2892 VariantClear(&lval);
2893 VariantClear(&rval);
2894 if(FAILED(hres))
2895 return hres;
2897 return return_bool(ret, b);
2900 /* ECMA-262 3rd Edition 11.8.3 */
2901 HRESULT lesseq_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2903 binary_expression_t *expr = (binary_expression_t*)_expr;
2904 VARIANT rval, lval;
2905 BOOL b;
2906 HRESULT hres;
2908 TRACE("\n");
2910 hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval);
2911 if(FAILED(hres))
2912 return hres;
2914 hres = less_eval(ctx, &rval, &lval, TRUE, ei, &b);
2915 VariantClear(&lval);
2916 VariantClear(&rval);
2917 if(FAILED(hres))
2918 return hres;
2920 return return_bool(ret, b);
2923 /* ECMA-262 3rd Edition 11.8.2 */
2924 HRESULT greater_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2926 binary_expression_t *expr = (binary_expression_t*)_expr;
2927 VARIANT rval, lval;
2928 BOOL b;
2929 HRESULT hres;
2931 TRACE("\n");
2933 hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval);
2934 if(FAILED(hres))
2935 return hres;
2937 hres = less_eval(ctx, &rval, &lval, FALSE, ei, &b);
2938 VariantClear(&lval);
2939 VariantClear(&rval);
2940 if(FAILED(hres))
2941 return hres;
2943 return return_bool(ret, b);
2946 /* ECMA-262 3rd Edition 11.8.4 */
2947 HRESULT greatereq_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2949 binary_expression_t *expr = (binary_expression_t*)_expr;
2950 VARIANT rval, lval;
2951 BOOL b;
2952 HRESULT hres;
2954 TRACE("\n");
2956 hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval);
2957 if(FAILED(hres))
2958 return hres;
2960 hres = less_eval(ctx, &lval, &rval, TRUE, ei, &b);
2961 VariantClear(&lval);
2962 VariantClear(&rval);
2963 if(FAILED(hres))
2964 return hres;
2966 return return_bool(ret, b);
2969 /* ECMA-262 3rd Edition 11.4.8 */
2970 HRESULT binary_negation_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
2972 unary_expression_t *expr = (unary_expression_t*)_expr;
2973 exprval_t exprval;
2974 VARIANT val;
2975 INT i;
2976 HRESULT hres;
2978 TRACE("\n");
2980 hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval);
2981 if(FAILED(hres))
2982 return hres;
2984 hres = exprval_to_value(ctx, &exprval, ei, &val);
2985 exprval_release(&exprval);
2986 if(FAILED(hres))
2987 return hres;
2989 hres = to_int32(ctx, &val, ei, &i);
2990 if(FAILED(hres))
2991 return hres;
2993 ret->type = EXPRVAL_VARIANT;
2994 V_VT(&ret->u.var) = VT_I4;
2995 V_I4(&ret->u.var) = ~i;
2996 return S_OK;
2999 /* ECMA-262 3rd Edition 11.4.9 */
3000 HRESULT logical_negation_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3002 unary_expression_t *expr = (unary_expression_t*)_expr;
3003 exprval_t exprval;
3004 VARIANT_BOOL b;
3005 HRESULT hres;
3007 TRACE("\n");
3009 hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval);
3010 if(FAILED(hres))
3011 return hres;
3013 hres = exprval_to_boolean(ctx, &exprval, ei, &b);
3014 exprval_release(&exprval);
3015 if(FAILED(hres))
3016 return hres;
3018 return return_bool(ret, !b);
3021 /* ECMA-262 3rd Edition 11.7.1 */
3022 static HRESULT lshift_eval(script_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
3024 DWORD ri;
3025 INT li;
3026 HRESULT hres;
3028 hres = to_int32(ctx, lval, ei, &li);
3029 if(FAILED(hres))
3030 return hres;
3032 hres = to_uint32(ctx, rval, ei, &ri);
3033 if(FAILED(hres))
3034 return hres;
3036 V_VT(retv) = VT_I4;
3037 V_I4(retv) = li << (ri&0x1f);
3038 return S_OK;
3041 /* ECMA-262 3rd Edition 11.7.1 */
3042 HRESULT left_shift_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3044 binary_expression_t *expr = (binary_expression_t*)_expr;
3046 TRACE("\n");
3048 return binary_expr_eval(ctx, expr, lshift_eval, ei, ret);
3051 /* ECMA-262 3rd Edition 11.7.2 */
3052 static HRESULT rshift_eval(script_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
3054 DWORD ri;
3055 INT li;
3056 HRESULT hres;
3058 hres = to_int32(ctx, lval, ei, &li);
3059 if(FAILED(hres))
3060 return hres;
3062 hres = to_uint32(ctx, rval, ei, &ri);
3063 if(FAILED(hres))
3064 return hres;
3066 V_VT(retv) = VT_I4;
3067 V_I4(retv) = li >> (ri&0x1f);
3068 return S_OK;
3071 /* ECMA-262 3rd Edition 11.7.2 */
3072 HRESULT right_shift_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3074 binary_expression_t *expr = (binary_expression_t*)_expr;
3076 TRACE("\n");
3078 return binary_expr_eval(ctx, expr, rshift_eval, ei, ret);
3081 /* ECMA-262 3rd Edition 11.7.3 */
3082 static HRESULT rshift2_eval(script_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
3084 DWORD li, ri;
3085 HRESULT hres;
3087 hres = to_uint32(ctx, lval, ei, &li);
3088 if(FAILED(hres))
3089 return hres;
3091 hres = to_uint32(ctx, rval, ei, &ri);
3092 if(FAILED(hres))
3093 return hres;
3095 V_VT(retv) = VT_I4;
3096 V_I4(retv) = li >> (ri&0x1f);
3097 return S_OK;
3100 /* ECMA-262 3rd Edition 11.7.3 */
3101 HRESULT right2_shift_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3103 binary_expression_t *expr = (binary_expression_t*)_expr;
3105 TRACE("\n");
3107 return binary_expr_eval(ctx, expr, rshift2_eval, ei, ret);
3110 /* ECMA-262 3rd Edition 11.13.1 */
3111 HRESULT assign_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3113 binary_expression_t *expr = (binary_expression_t*)_expr;
3114 exprval_t exprval, exprvalr;
3115 VARIANT rval;
3116 HRESULT hres;
3118 TRACE("\n");
3120 hres = expr_eval(ctx, expr->expression1, EXPR_NEWREF, ei, &exprval);
3121 if(FAILED(hres))
3122 return hres;
3124 hres = expr_eval(ctx, expr->expression2, 0, ei, &exprvalr);
3125 if(SUCCEEDED(hres)) {
3126 hres = exprval_to_value(ctx, &exprvalr, ei, &rval);
3127 exprval_release(&exprvalr);
3130 if(SUCCEEDED(hres)) {
3131 hres = put_value(ctx, &exprval, &rval, ei);
3132 if(FAILED(hres))
3133 VariantClear(&rval);
3136 exprval_release(&exprval);
3137 if(FAILED(hres))
3138 return hres;
3140 ret->type = EXPRVAL_VARIANT;
3141 ret->u.var = rval;
3142 return S_OK;
3145 /* ECMA-262 3rd Edition 11.13.2 */
3146 HRESULT assign_lshift_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3148 binary_expression_t *expr = (binary_expression_t*)_expr;
3150 TRACE("\n");
3152 return assign_oper_eval(ctx, expr->expression1, expr->expression2, lshift_eval, ei, ret);
3155 /* ECMA-262 3rd Edition 11.13.2 */
3156 HRESULT assign_rshift_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3158 binary_expression_t *expr = (binary_expression_t*)_expr;
3160 TRACE("\n");
3162 return assign_oper_eval(ctx, expr->expression1, expr->expression2, rshift_eval, ei, ret);
3165 /* ECMA-262 3rd Edition 11.13.2 */
3166 HRESULT assign_rrshift_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3168 binary_expression_t *expr = (binary_expression_t*)_expr;
3170 TRACE("\n");
3172 return assign_oper_eval(ctx, expr->expression1, expr->expression2, rshift2_eval, ei, ret);
3175 /* ECMA-262 3rd Edition 11.13.2 */
3176 HRESULT assign_add_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3178 binary_expression_t *expr = (binary_expression_t*)_expr;
3180 TRACE("\n");
3182 return assign_oper_eval(ctx, expr->expression1, expr->expression2, add_eval, ei, ret);
3185 /* ECMA-262 3rd Edition 11.13.2 */
3186 HRESULT assign_sub_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3188 binary_expression_t *expr = (binary_expression_t*)_expr;
3190 TRACE("\n");
3192 return assign_oper_eval(ctx, expr->expression1, expr->expression2, sub_eval, ei, ret);
3195 /* ECMA-262 3rd Edition 11.13.2 */
3196 HRESULT assign_mul_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3198 binary_expression_t *expr = (binary_expression_t*)_expr;
3200 TRACE("\n");
3202 return assign_oper_eval(ctx, expr->expression1, expr->expression2, mul_eval, ei, ret);
3205 /* ECMA-262 3rd Edition 11.13.2 */
3206 HRESULT assign_div_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3208 binary_expression_t *expr = (binary_expression_t*)_expr;
3210 TRACE("\n");
3212 return assign_oper_eval(ctx, expr->expression1, expr->expression2, div_eval, ei, ret);
3215 /* ECMA-262 3rd Edition 11.13.2 */
3216 HRESULT assign_mod_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3218 binary_expression_t *expr = (binary_expression_t*)_expr;
3220 TRACE("\n");
3222 return assign_oper_eval(ctx, expr->expression1, expr->expression2, mod_eval, ei, ret);
3225 /* ECMA-262 3rd Edition 11.13.2 */
3226 HRESULT assign_and_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3228 binary_expression_t *expr = (binary_expression_t*)_expr;
3230 TRACE("\n");
3232 return assign_oper_eval(ctx, expr->expression1, expr->expression2, bitand_eval, ei, ret);
3235 /* ECMA-262 3rd Edition 11.13.2 */
3236 HRESULT assign_or_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3238 binary_expression_t *expr = (binary_expression_t*)_expr;
3240 TRACE("\n");
3242 return assign_oper_eval(ctx, expr->expression1, expr->expression2, bitor_eval, ei, ret);
3245 /* ECMA-262 3rd Edition 11.13.2 */
3246 HRESULT assign_xor_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
3248 binary_expression_t *expr = (binary_expression_t*)_expr;
3250 TRACE("\n");
3252 return assign_oper_eval(ctx, expr->expression1, expr->expression2, xor_eval, ei, ret);