d3dcompiler: Move blob and strip functions to blob.c.
[wine.git] / dlls / jscript / engine.c
blob1b56e63968a63caea7acc98ee73a375dc1d4d09a
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 FIXME("Object doesn't support IDispatchEx\n");
888 return E_NOTIMPL;
891 V_VT(&retv) = VT_EMPTY;
893 if(stat->variable)
894 identifier = SysAllocString(stat->variable->identifier);
896 while(1) {
897 hres = IDispatchEx_GetNextDispID(in_obj, fdexEnumDefault, id, &id);
898 if(FAILED(hres) || hres == S_FALSE)
899 break;
901 hres = IDispatchEx_GetMemberName(in_obj, id, &str);
902 if(FAILED(hres))
903 break;
905 TRACE("iter %s\n", debugstr_w(str));
907 if(stat->variable)
908 hres = identifier_eval(ctx, identifier, 0, NULL, &exprval);
909 else
910 hres = expr_eval(ctx, stat->expr, EXPR_NEWREF, &rt->ei, &exprval);
911 if(SUCCEEDED(hres)) {
912 V_VT(&name) = VT_BSTR;
913 V_BSTR(&name) = str;
914 hres = put_value(ctx, &exprval, &name, &rt->ei);
915 exprval_release(&exprval);
917 SysFreeString(str);
918 if(FAILED(hres))
919 break;
921 hres = stat_eval(ctx, stat->statement, rt, &tmp);
922 if(FAILED(hres))
923 break;
925 VariantClear(&retv);
926 retv = tmp;
928 if(rt->type == RT_CONTINUE)
929 rt->type = RT_NORMAL;
930 else if(rt->type != RT_NORMAL)
931 break;
934 SysFreeString(identifier);
935 IDispatchEx_Release(in_obj);
936 if(FAILED(hres)) {
937 VariantClear(&retv);
938 return hres;
941 if(rt->type == RT_BREAK)
942 rt->type = RT_NORMAL;
944 *ret = retv;
945 return S_OK;
948 /* ECMA-262 3rd Edition 12.7 */
949 HRESULT continue_statement_eval(script_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
951 branch_statement_t *stat = (branch_statement_t*)_stat;
953 TRACE("\n");
955 if(stat->identifier) {
956 FIXME("indentifier not implemented\n");
957 return E_NOTIMPL;
960 rt->type = RT_CONTINUE;
961 V_VT(ret) = VT_EMPTY;
962 return S_OK;
965 /* ECMA-262 3rd Edition 12.8 */
966 HRESULT break_statement_eval(script_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
968 branch_statement_t *stat = (branch_statement_t*)_stat;
970 TRACE("\n");
972 if(stat->identifier) {
973 FIXME("indentifier not implemented\n");
974 return E_NOTIMPL;
977 rt->type = RT_BREAK;
978 V_VT(ret) = VT_EMPTY;
979 return S_OK;
982 /* ECMA-262 3rd Edition 12.9 */
983 HRESULT return_statement_eval(script_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
985 expression_statement_t *stat = (expression_statement_t*)_stat;
986 HRESULT hres;
988 TRACE("\n");
990 if(stat->expr) {
991 exprval_t exprval;
993 hres = expr_eval(ctx, stat->expr, 0, &rt->ei, &exprval);
994 if(FAILED(hres))
995 return hres;
997 hres = exprval_to_value(ctx, &exprval, &rt->ei, ret);
998 exprval_release(&exprval);
999 if(FAILED(hres))
1000 return hres;
1001 }else {
1002 V_VT(ret) = VT_EMPTY;
1005 TRACE("= %s\n", debugstr_variant(ret));
1006 rt->type = RT_RETURN;
1007 return S_OK;
1010 /* ECMA-262 3rd Edition 12.10 */
1011 HRESULT with_statement_eval(script_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
1013 with_statement_t *stat = (with_statement_t*)_stat;
1014 exprval_t exprval;
1015 IDispatch *disp;
1016 jsdisp_t *obj;
1017 VARIANT val;
1018 HRESULT hres;
1020 TRACE("\n");
1022 hres = expr_eval(ctx, stat->expr, 0, &rt->ei, &exprval);
1023 if(FAILED(hres))
1024 return hres;
1026 hres = exprval_to_value(ctx, &exprval, &rt->ei, &val);
1027 exprval_release(&exprval);
1028 if(FAILED(hres))
1029 return hres;
1031 hres = to_object(ctx, &val, &disp);
1032 VariantClear(&val);
1033 if(FAILED(hres))
1034 return hres;
1036 obj = iface_to_jsdisp((IUnknown*)disp);
1037 IDispatch_Release(disp);
1038 if(!obj) {
1039 FIXME("disp id not jsdisp\n");
1040 return E_NOTIMPL;
1043 hres = scope_push(ctx->exec_ctx->scope_chain, obj, &ctx->exec_ctx->scope_chain);
1044 jsdisp_release(obj);
1045 if(FAILED(hres))
1046 return hres;
1048 hres = stat_eval(ctx, stat->statement, rt, ret);
1050 scope_pop(&ctx->exec_ctx->scope_chain);
1051 return hres;
1054 /* ECMA-262 3rd Edition 12.12 */
1055 HRESULT labelled_statement_eval(script_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
1057 FIXME("\n");
1058 return E_NOTIMPL;
1061 /* ECMA-262 3rd Edition 12.13 */
1062 HRESULT switch_statement_eval(script_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
1064 switch_statement_t *stat = (switch_statement_t*)_stat;
1065 case_clausule_t *iter, *default_clausule = NULL;
1066 statement_t *stat_iter;
1067 VARIANT val, cval;
1068 exprval_t exprval;
1069 BOOL b;
1070 HRESULT hres;
1072 TRACE("\n");
1074 hres = expr_eval(ctx, stat->expr, 0, &rt->ei, &exprval);
1075 if(FAILED(hres))
1076 return hres;
1078 hres = exprval_to_value(ctx, &exprval, &rt->ei, &val);
1079 exprval_release(&exprval);
1080 if(FAILED(hres))
1081 return hres;
1083 for(iter = stat->case_list; iter; iter = iter->next) {
1084 if(!iter->expr) {
1085 default_clausule = iter;
1086 continue;
1089 hres = expr_eval(ctx, iter->expr, 0, &rt->ei, &exprval);
1090 if(FAILED(hres))
1091 break;
1093 hres = exprval_to_value(ctx, &exprval, &rt->ei, &cval);
1094 exprval_release(&exprval);
1095 if(FAILED(hres))
1096 break;
1098 hres = equal2_values(&val, &cval, &b);
1099 VariantClear(&cval);
1100 if(FAILED(hres) || b)
1101 break;
1104 VariantClear(&val);
1105 if(FAILED(hres))
1106 return hres;
1108 if(!iter)
1109 iter = default_clausule;
1111 V_VT(&val) = VT_EMPTY;
1112 if(iter) {
1113 VARIANT tmp;
1115 for(stat_iter = iter->stat; stat_iter; stat_iter = stat_iter->next) {
1116 hres = stat_eval(ctx, stat_iter, rt, &tmp);
1117 if(FAILED(hres))
1118 break;
1120 VariantClear(&val);
1121 val = tmp;
1123 if(rt->type != RT_NORMAL)
1124 break;
1128 if(FAILED(hres)) {
1129 VariantClear(&val);
1130 return hres;
1133 if(rt->type == RT_BREAK)
1134 rt->type = RT_NORMAL;
1136 *ret = val;
1137 return S_OK;
1140 /* ECMA-262 3rd Edition 12.13 */
1141 HRESULT throw_statement_eval(script_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
1143 expression_statement_t *stat = (expression_statement_t*)_stat;
1144 exprval_t exprval;
1145 VARIANT val;
1146 HRESULT hres;
1148 TRACE("\n");
1150 hres = expr_eval(ctx, stat->expr, 0, &rt->ei, &exprval);
1151 if(FAILED(hres))
1152 return hres;
1154 hres = exprval_to_value(ctx, &exprval, &rt->ei, &val);
1155 exprval_release(&exprval);
1156 if(FAILED(hres))
1157 return hres;
1159 rt->ei.var = val;
1160 return DISP_E_EXCEPTION;
1163 /* ECMA-262 3rd Edition 12.14 */
1164 static HRESULT catch_eval(script_ctx_t *ctx, catch_block_t *block, return_type_t *rt, VARIANT *ret)
1166 jsdisp_t *var_disp;
1167 VARIANT ex, val;
1168 HRESULT hres;
1170 ex = rt->ei.var;
1171 memset(&rt->ei, 0, sizeof(jsexcept_t));
1173 hres = create_dispex(ctx, NULL, NULL, &var_disp);
1174 if(SUCCEEDED(hres)) {
1175 hres = jsdisp_propput_name(var_disp, block->identifier, &ex, &rt->ei, NULL/*FIXME*/);
1176 if(SUCCEEDED(hres)) {
1177 hres = scope_push(ctx->exec_ctx->scope_chain, var_disp, &ctx->exec_ctx->scope_chain);
1178 if(SUCCEEDED(hres)) {
1179 hres = stat_eval(ctx, block->statement, rt, &val);
1180 scope_pop(&ctx->exec_ctx->scope_chain);
1184 jsdisp_release(var_disp);
1187 VariantClear(&ex);
1188 if(FAILED(hres))
1189 return hres;
1191 *ret = val;
1192 return S_OK;
1195 /* ECMA-262 3rd Edition 12.14 */
1196 HRESULT try_statement_eval(script_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
1198 try_statement_t *stat = (try_statement_t*)_stat;
1199 VARIANT val;
1200 HRESULT hres;
1202 TRACE("\n");
1204 hres = stat_eval(ctx, stat->try_statement, rt, &val);
1205 if(FAILED(hres)) {
1206 TRACE("EXCEPTION\n");
1207 if(!stat->catch_block)
1208 return hres;
1210 hres = catch_eval(ctx, stat->catch_block, rt, &val);
1211 if(FAILED(hres))
1212 return hres;
1215 if(stat->finally_statement) {
1216 VariantClear(&val);
1217 hres = stat_eval(ctx, stat->finally_statement, rt, &val);
1218 if(FAILED(hres))
1219 return hres;
1222 *ret = val;
1223 return S_OK;
1226 static HRESULT return_bool(exprval_t *ret, DWORD b)
1228 ret->type = EXPRVAL_VARIANT;
1229 V_VT(&ret->u.var) = VT_BOOL;
1230 V_BOOL(&ret->u.var) = b ? VARIANT_TRUE : VARIANT_FALSE;
1232 return S_OK;
1235 static HRESULT get_binary_expr_values(script_ctx_t *ctx, binary_expression_t *expr, jsexcept_t *ei, VARIANT *lval, VARIANT *rval)
1237 exprval_t exprval;
1238 HRESULT hres;
1240 hres = expr_eval(ctx, expr->expression1, 0, ei, &exprval);
1241 if(FAILED(hres))
1242 return hres;
1244 hres = exprval_to_value(ctx, &exprval, ei, lval);
1245 exprval_release(&exprval);
1246 if(FAILED(hres))
1247 return hres;
1249 hres = expr_eval(ctx, expr->expression2, 0, ei, &exprval);
1250 if(SUCCEEDED(hres)) {
1251 hres = exprval_to_value(ctx, &exprval, ei, rval);
1252 exprval_release(&exprval);
1255 if(FAILED(hres)) {
1256 VariantClear(lval);
1257 return hres;
1260 return S_OK;
1263 typedef HRESULT (*oper_t)(script_ctx_t*,VARIANT*,VARIANT*,jsexcept_t*,VARIANT*);
1265 static HRESULT binary_expr_eval(script_ctx_t *ctx, binary_expression_t *expr, oper_t oper, jsexcept_t *ei,
1266 exprval_t *ret)
1268 VARIANT lval, rval, retv;
1269 HRESULT hres;
1271 hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval);
1272 if(FAILED(hres))
1273 return hres;
1275 hres = oper(ctx, &lval, &rval, ei, &retv);
1276 VariantClear(&lval);
1277 VariantClear(&rval);
1278 if(FAILED(hres))
1279 return hres;
1281 ret->type = EXPRVAL_VARIANT;
1282 ret->u.var = retv;
1283 return S_OK;
1286 /* ECMA-262 3rd Edition 11.13.2 */
1287 static HRESULT assign_oper_eval(script_ctx_t *ctx, expression_t *lexpr, expression_t *rexpr, oper_t oper,
1288 jsexcept_t *ei, exprval_t *ret)
1290 VARIANT retv, lval, rval;
1291 exprval_t exprval, exprvalr;
1292 HRESULT hres;
1294 hres = expr_eval(ctx, lexpr, EXPR_NEWREF, ei, &exprval);
1295 if(FAILED(hres))
1296 return hres;
1298 hres = exprval_value(ctx, &exprval, ei, &lval);
1299 if(SUCCEEDED(hres)) {
1300 hres = expr_eval(ctx, rexpr, 0, ei, &exprvalr);
1301 if(SUCCEEDED(hres)) {
1302 hres = exprval_value(ctx, &exprvalr, ei, &rval);
1303 exprval_release(&exprvalr);
1305 if(SUCCEEDED(hres)) {
1306 hres = oper(ctx, &lval, &rval, ei, &retv);
1307 VariantClear(&rval);
1309 VariantClear(&lval);
1312 if(SUCCEEDED(hres)) {
1313 hres = put_value(ctx, &exprval, &retv, ei);
1314 if(FAILED(hres))
1315 VariantClear(&retv);
1317 exprval_release(&exprval);
1319 if(FAILED(hres))
1320 return hres;
1322 ret->type = EXPRVAL_VARIANT;
1323 ret->u.var = retv;
1324 return S_OK;
1327 /* ECMA-262 3rd Edition 13 */
1328 HRESULT function_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1330 function_expression_t *expr = (function_expression_t*)_expr;
1331 VARIANT var;
1332 HRESULT hres;
1334 TRACE("\n");
1336 if(expr->identifier) {
1337 hres = jsdisp_propget_name(ctx->exec_ctx->var_disp, expr->identifier, &var, ei, NULL/*FIXME*/);
1338 if(FAILED(hres))
1339 return hres;
1340 }else {
1341 jsdisp_t *dispex;
1343 hres = create_source_function(ctx->exec_ctx->parser, expr->parameter_list, expr->source_elements, ctx->exec_ctx->scope_chain,
1344 expr->src_str, expr->src_len, &dispex);
1345 if(FAILED(hres))
1346 return hres;
1348 var_set_jsdisp(&var, dispex);
1351 ret->type = EXPRVAL_VARIANT;
1352 ret->u.var = var;
1353 return S_OK;
1356 /* ECMA-262 3rd Edition 11.12 */
1357 HRESULT conditional_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1359 conditional_expression_t *expr = (conditional_expression_t*)_expr;
1360 exprval_t exprval;
1361 VARIANT_BOOL b;
1362 HRESULT hres;
1364 TRACE("\n");
1366 hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
1367 if(FAILED(hres))
1368 return hres;
1370 hres = exprval_to_boolean(ctx, &exprval, ei, &b);
1371 exprval_release(&exprval);
1372 if(FAILED(hres))
1373 return hres;
1375 return expr_eval(ctx, b ? expr->true_expression : expr->false_expression, flags, ei, ret);
1378 /* ECMA-262 3rd Edition 11.2.1 */
1379 HRESULT array_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1381 array_expression_t *expr = (array_expression_t*)_expr;
1382 exprval_t exprval;
1383 VARIANT member, val;
1384 DISPID id;
1385 BSTR str;
1386 IDispatch *obj = NULL;
1387 HRESULT hres;
1389 TRACE("\n");
1391 hres = expr_eval(ctx, expr->member_expr, 0, ei, &exprval);
1392 if(FAILED(hres))
1393 return hres;
1395 hres = exprval_to_value(ctx, &exprval, ei, &member);
1396 exprval_release(&exprval);
1397 if(FAILED(hres))
1398 return hres;
1400 hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval);
1401 if(SUCCEEDED(hres)) {
1402 hres = exprval_to_value(ctx, &exprval, ei, &val);
1403 exprval_release(&exprval);
1406 if(SUCCEEDED(hres)) {
1407 hres = to_object(ctx, &member, &obj);
1408 if(FAILED(hres))
1409 VariantClear(&val);
1411 VariantClear(&member);
1412 if(SUCCEEDED(hres)) {
1413 hres = to_string(ctx, &val, ei, &str);
1414 VariantClear(&val);
1415 if(SUCCEEDED(hres)) {
1416 if(flags & EXPR_STRREF) {
1417 ret->type = EXPRVAL_NAMEREF;
1418 ret->u.nameref.disp = obj;
1419 ret->u.nameref.name = str;
1420 return S_OK;
1423 hres = disp_get_id(ctx, obj, str, flags & EXPR_NEWREF ? fdexNameEnsure : 0, &id);
1424 SysFreeString(str);
1427 if(SUCCEEDED(hres)) {
1428 exprval_set_idref(ret, obj, id);
1429 }else if(!(flags & EXPR_NEWREF) && hres == DISP_E_UNKNOWNNAME) {
1430 exprval_init(ret);
1431 hres = S_OK;
1434 IDispatch_Release(obj);
1437 return hres;
1440 /* ECMA-262 3rd Edition 11.2.1 */
1441 HRESULT member_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1443 member_expression_t *expr = (member_expression_t*)_expr;
1444 IDispatch *obj = NULL;
1445 exprval_t exprval;
1446 VARIANT member;
1447 DISPID id;
1448 BSTR str;
1449 HRESULT hres;
1451 TRACE("\n");
1453 hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
1454 if(FAILED(hres))
1455 return hres;
1457 hres = exprval_to_value(ctx, &exprval, ei, &member);
1458 exprval_release(&exprval);
1459 if(FAILED(hres))
1460 return hres;
1462 hres = to_object(ctx, &member, &obj);
1463 VariantClear(&member);
1464 if(FAILED(hres))
1465 return hres;
1467 str = SysAllocString(expr->identifier);
1468 if(flags & EXPR_STRREF) {
1469 ret->type = EXPRVAL_NAMEREF;
1470 ret->u.nameref.disp = obj;
1471 ret->u.nameref.name = str;
1472 return S_OK;
1475 hres = disp_get_id(ctx, obj, str, flags & EXPR_NEWREF ? fdexNameEnsure : 0, &id);
1476 SysFreeString(str);
1477 if(SUCCEEDED(hres)) {
1478 exprval_set_idref(ret, obj, id);
1479 }else if(!(flags & EXPR_NEWREF) && hres == DISP_E_UNKNOWNNAME) {
1480 exprval_init(ret);
1481 hres = S_OK;
1484 IDispatch_Release(obj);
1485 return hres;
1488 static void free_dp(DISPPARAMS *dp)
1490 DWORD i;
1492 for(i=0; i < dp->cArgs; i++)
1493 VariantClear(dp->rgvarg+i);
1494 heap_free(dp->rgvarg);
1497 static HRESULT args_to_param(script_ctx_t *ctx, argument_t *args, jsexcept_t *ei, DISPPARAMS *dp)
1499 VARIANTARG *vargs;
1500 exprval_t exprval;
1501 argument_t *iter;
1502 DWORD cnt = 0, i;
1503 HRESULT hres = S_OK;
1505 memset(dp, 0, sizeof(*dp));
1506 if(!args)
1507 return S_OK;
1509 for(iter = args; iter; iter = iter->next)
1510 cnt++;
1512 vargs = heap_alloc_zero(cnt * sizeof(*vargs));
1513 if(!vargs)
1514 return E_OUTOFMEMORY;
1516 for(i = cnt, iter = args; iter; iter = iter->next) {
1517 hres = expr_eval(ctx, iter->expr, 0, ei, &exprval);
1518 if(FAILED(hres))
1519 break;
1521 hres = exprval_to_value(ctx, &exprval, ei, vargs + (--i));
1522 exprval_release(&exprval);
1523 if(FAILED(hres))
1524 break;
1527 if(FAILED(hres)) {
1528 free_dp(dp);
1529 return hres;
1532 dp->rgvarg = vargs;
1533 dp->cArgs = cnt;
1534 return S_OK;
1537 /* ECMA-262 3rd Edition 11.2.2 */
1538 HRESULT new_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1540 call_expression_t *expr = (call_expression_t*)_expr;
1541 exprval_t exprval;
1542 VARIANT constr, var;
1543 DISPPARAMS dp;
1544 HRESULT hres;
1546 TRACE("\n");
1548 hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
1549 if(FAILED(hres))
1550 return hres;
1552 hres = args_to_param(ctx, expr->argument_list, ei, &dp);
1553 if(SUCCEEDED(hres))
1554 hres = exprval_to_value(ctx, &exprval, ei, &constr);
1555 exprval_release(&exprval);
1556 if(FAILED(hres))
1557 return hres;
1559 /* NOTE: Should use to_object here */
1561 if(V_VT(&constr) == VT_NULL) {
1562 VariantClear(&constr);
1563 return throw_type_error(ctx, ei, JS_E_OBJECT_EXPECTED, NULL);
1564 } else if(V_VT(&constr) != VT_DISPATCH) {
1565 VariantClear(&constr);
1566 return throw_type_error(ctx, ei, JS_E_INVALID_ACTION, NULL);
1567 } else if(!V_DISPATCH(&constr)) {
1568 VariantClear(&constr);
1569 return throw_type_error(ctx, ei, JS_E_INVALID_PROPERTY, NULL);
1572 hres = disp_call(ctx, V_DISPATCH(&constr), DISPID_VALUE,
1573 DISPATCH_CONSTRUCT, &dp, &var, ei, NULL/*FIXME*/);
1574 IDispatch_Release(V_DISPATCH(&constr));
1575 free_dp(&dp);
1576 if(FAILED(hres))
1577 return hres;
1579 ret->type = EXPRVAL_VARIANT;
1580 ret->u.var = var;
1581 return S_OK;
1584 /* ECMA-262 3rd Edition 11.2.3 */
1585 HRESULT call_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1587 call_expression_t *expr = (call_expression_t*)_expr;
1588 VARIANT var;
1589 exprval_t exprval;
1590 DISPPARAMS dp;
1591 HRESULT hres;
1593 TRACE("\n");
1595 hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
1596 if(FAILED(hres))
1597 return hres;
1599 hres = args_to_param(ctx, expr->argument_list, ei, &dp);
1600 if(SUCCEEDED(hres)) {
1601 switch(exprval.type) {
1602 case EXPRVAL_VARIANT:
1603 if(V_VT(&exprval.u.var) == VT_DISPATCH)
1604 hres = disp_call(ctx, V_DISPATCH(&exprval.u.var), DISPID_VALUE,
1605 DISPATCH_METHOD, &dp, flags & EXPR_NOVAL ? NULL : &var, ei, NULL/*FIXME*/);
1606 else
1607 hres = throw_type_error(ctx, ei, JS_E_INVALID_PROPERTY, NULL);
1608 break;
1609 case EXPRVAL_IDREF:
1610 hres = disp_call(ctx, exprval.u.idref.disp, exprval.u.idref.id,
1611 DISPATCH_METHOD, &dp, flags & EXPR_NOVAL ? NULL : &var, ei, NULL/*FIXME*/);
1612 break;
1613 case EXPRVAL_INVALID:
1614 hres = throw_type_error(ctx, ei, JS_E_OBJECT_EXPECTED, NULL);
1615 break;
1616 default:
1617 FIXME("unimplemented type %d\n", exprval.type);
1618 hres = E_NOTIMPL;
1621 free_dp(&dp);
1624 exprval_release(&exprval);
1625 if(FAILED(hres))
1626 return hres;
1628 ret->type = EXPRVAL_VARIANT;
1629 if(flags & EXPR_NOVAL) {
1630 V_VT(&ret->u.var) = VT_EMPTY;
1631 }else {
1632 TRACE("= %s\n", debugstr_variant(&var));
1633 ret->u.var = var;
1635 return S_OK;
1638 /* ECMA-262 3rd Edition 11.1.1 */
1639 HRESULT this_expression_eval(script_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1641 TRACE("\n");
1643 ret->type = EXPRVAL_VARIANT;
1644 V_VT(&ret->u.var) = VT_DISPATCH;
1645 V_DISPATCH(&ret->u.var) = ctx->exec_ctx->this_obj;
1646 IDispatch_AddRef(ctx->exec_ctx->this_obj);
1647 return S_OK;
1650 /* ECMA-262 3rd Edition 10.1.4 */
1651 HRESULT identifier_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1653 identifier_expression_t *expr = (identifier_expression_t*)_expr;
1654 BSTR identifier;
1655 HRESULT hres;
1657 TRACE("\n");
1659 identifier = SysAllocString(expr->identifier);
1660 if(!identifier)
1661 return E_OUTOFMEMORY;
1663 hres = identifier_eval(ctx, identifier, flags, ei, ret);
1665 SysFreeString(identifier);
1666 return hres;
1669 /* ECMA-262 3rd Edition 7.8 */
1670 HRESULT literal_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1672 literal_expression_t *expr = (literal_expression_t*)_expr;
1673 VARIANT var;
1674 HRESULT hres;
1676 TRACE("\n");
1678 hres = literal_to_var(ctx, expr->literal, &var);
1679 if(FAILED(hres))
1680 return hres;
1682 ret->type = EXPRVAL_VARIANT;
1683 ret->u.var = var;
1684 return S_OK;
1687 /* ECMA-262 3rd Edition 11.1.4 */
1688 HRESULT array_literal_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1690 array_literal_expression_t *expr = (array_literal_expression_t*)_expr;
1691 DWORD length = 0, i = 0;
1692 array_element_t *elem;
1693 jsdisp_t *array;
1694 exprval_t exprval;
1695 VARIANT val;
1696 HRESULT hres;
1698 TRACE("\n");
1700 for(elem = expr->element_list; elem; elem = elem->next)
1701 length += elem->elision+1;
1702 length += expr->length;
1704 hres = create_array(ctx, length, &array);
1705 if(FAILED(hres))
1706 return hres;
1708 for(elem = expr->element_list; elem; elem = elem->next) {
1709 i += elem->elision;
1711 hres = expr_eval(ctx, elem->expr, 0, ei, &exprval);
1712 if(FAILED(hres))
1713 break;
1715 hres = exprval_to_value(ctx, &exprval, ei, &val);
1716 exprval_release(&exprval);
1717 if(FAILED(hres))
1718 break;
1720 hres = jsdisp_propput_idx(array, i, &val, ei, NULL/*FIXME*/);
1721 VariantClear(&val);
1722 if(FAILED(hres))
1723 break;
1725 i++;
1728 if(FAILED(hres)) {
1729 jsdisp_release(array);
1730 return hres;
1733 ret->type = EXPRVAL_VARIANT;
1734 var_set_jsdisp(&ret->u.var, array);
1735 return S_OK;
1738 /* ECMA-262 3rd Edition 11.1.5 */
1739 HRESULT property_value_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1741 property_value_expression_t *expr = (property_value_expression_t*)_expr;
1742 VARIANT val, tmp;
1743 jsdisp_t *obj;
1744 prop_val_t *iter;
1745 exprval_t exprval;
1746 BSTR name;
1747 HRESULT hres;
1749 TRACE("\n");
1751 hres = create_object(ctx, NULL, &obj);
1752 if(FAILED(hres))
1753 return hres;
1755 for(iter = expr->property_list; iter; iter = iter->next) {
1756 hres = literal_to_var(ctx, iter->name, &tmp);
1757 if(FAILED(hres))
1758 break;
1760 hres = to_string(ctx, &tmp, ei, &name);
1761 VariantClear(&tmp);
1762 if(FAILED(hres))
1763 break;
1765 hres = expr_eval(ctx, iter->value, 0, ei, &exprval);
1766 if(SUCCEEDED(hres)) {
1767 hres = exprval_to_value(ctx, &exprval, ei, &val);
1768 exprval_release(&exprval);
1769 if(SUCCEEDED(hres)) {
1770 hres = jsdisp_propput_name(obj, name, &val, ei, NULL/*FIXME*/);
1771 VariantClear(&val);
1775 SysFreeString(name);
1776 if(FAILED(hres))
1777 break;
1780 if(FAILED(hres)) {
1781 jsdisp_release(obj);
1782 return hres;
1785 ret->type = EXPRVAL_VARIANT;
1786 var_set_jsdisp(&ret->u.var, obj);
1787 return S_OK;
1790 /* ECMA-262 3rd Edition 11.14 */
1791 HRESULT comma_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1793 binary_expression_t *expr = (binary_expression_t*)_expr;
1794 VARIANT lval, rval;
1795 HRESULT hres;
1797 TRACE("\n");
1799 hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval);
1800 if(FAILED(hres))
1801 return hres;
1803 VariantClear(&lval);
1805 ret->type = EXPRVAL_VARIANT;
1806 ret->u.var = rval;
1807 return S_OK;
1810 /* ECMA-262 3rd Edition 11.11 */
1811 HRESULT logical_or_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1813 binary_expression_t *expr = (binary_expression_t*)_expr;
1814 exprval_t exprval;
1815 VARIANT_BOOL b;
1816 VARIANT val;
1817 HRESULT hres;
1819 TRACE("\n");
1821 hres = expr_eval(ctx, expr->expression1, 0, ei, &exprval);
1822 if(FAILED(hres))
1823 return hres;
1825 hres = exprval_to_value(ctx, &exprval, ei, &val);
1826 exprval_release(&exprval);
1827 if(FAILED(hres))
1828 return hres;
1830 hres = to_boolean(&val, &b);
1831 if(SUCCEEDED(hres) && b) {
1832 ret->type = EXPRVAL_VARIANT;
1833 ret->u.var = val;
1834 return S_OK;
1837 VariantClear(&val);
1838 if(FAILED(hres))
1839 return hres;
1841 hres = expr_eval(ctx, expr->expression2, 0, ei, &exprval);
1842 if(FAILED(hres))
1843 return hres;
1845 hres = exprval_to_value(ctx, &exprval, ei, &val);
1846 exprval_release(&exprval);
1847 if(FAILED(hres))
1848 return hres;
1850 ret->type = EXPRVAL_VARIANT;
1851 ret->u.var = val;
1852 return S_OK;
1855 /* ECMA-262 3rd Edition 11.11 */
1856 HRESULT logical_and_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1858 binary_expression_t *expr = (binary_expression_t*)_expr;
1859 exprval_t exprval;
1860 VARIANT_BOOL b;
1861 VARIANT val;
1862 HRESULT hres;
1864 TRACE("\n");
1866 hres = expr_eval(ctx, expr->expression1, 0, ei, &exprval);
1867 if(FAILED(hres))
1868 return hres;
1870 hres = exprval_to_value(ctx, &exprval, ei, &val);
1871 exprval_release(&exprval);
1872 if(FAILED(hres))
1873 return hres;
1875 hres = to_boolean(&val, &b);
1876 if(SUCCEEDED(hres) && !b) {
1877 ret->type = EXPRVAL_VARIANT;
1878 ret->u.var = val;
1879 return S_OK;
1882 VariantClear(&val);
1883 if(FAILED(hres))
1884 return hres;
1886 hres = expr_eval(ctx, expr->expression2, 0, ei, &exprval);
1887 if(FAILED(hres))
1888 return hres;
1890 hres = exprval_to_value(ctx, &exprval, ei, &val);
1891 exprval_release(&exprval);
1892 if(FAILED(hres))
1893 return hres;
1895 ret->type = EXPRVAL_VARIANT;
1896 ret->u.var = val;
1897 return S_OK;
1900 /* ECMA-262 3rd Edition 11.10 */
1901 static HRESULT bitor_eval(script_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
1903 INT li, ri;
1904 HRESULT hres;
1906 hres = to_int32(ctx, lval, ei, &li);
1907 if(FAILED(hres))
1908 return hres;
1910 hres = to_int32(ctx, rval, ei, &ri);
1911 if(FAILED(hres))
1912 return hres;
1914 V_VT(retv) = VT_I4;
1915 V_I4(retv) = li|ri;
1916 return S_OK;
1919 /* ECMA-262 3rd Edition 11.10 */
1920 HRESULT binary_or_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1922 binary_expression_t *expr = (binary_expression_t*)_expr;
1924 TRACE("\n");
1926 return binary_expr_eval(ctx, expr, bitor_eval, ei, ret);
1929 /* ECMA-262 3rd Edition 11.10 */
1930 static HRESULT xor_eval(script_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
1932 INT li, ri;
1933 HRESULT hres;
1935 hres = to_int32(ctx, lval, ei, &li);
1936 if(FAILED(hres))
1937 return hres;
1939 hres = to_int32(ctx, rval, ei, &ri);
1940 if(FAILED(hres))
1941 return hres;
1943 V_VT(retv) = VT_I4;
1944 V_I4(retv) = li^ri;
1945 return S_OK;
1948 /* ECMA-262 3rd Edition 11.10 */
1949 HRESULT binary_xor_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1951 binary_expression_t *expr = (binary_expression_t*)_expr;
1953 TRACE("\n");
1955 return binary_expr_eval(ctx, expr, xor_eval, ei, ret);
1958 /* ECMA-262 3rd Edition 11.10 */
1959 static HRESULT bitand_eval(script_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv)
1961 INT li, ri;
1962 HRESULT hres;
1964 hres = to_int32(ctx, lval, ei, &li);
1965 if(FAILED(hres))
1966 return hres;
1968 hres = to_int32(ctx, rval, ei, &ri);
1969 if(FAILED(hres))
1970 return hres;
1972 V_VT(retv) = VT_I4;
1973 V_I4(retv) = li&ri;
1974 return S_OK;
1977 /* ECMA-262 3rd Edition 11.10 */
1978 HRESULT binary_and_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
1980 binary_expression_t *expr = (binary_expression_t*)_expr;
1982 TRACE("\n");
1984 return binary_expr_eval(ctx, expr, bitand_eval, ei, ret);
1987 /* ECMA-262 3rd Edition 11.8.6 */
1988 static HRESULT instanceof_eval(script_ctx_t *ctx, VARIANT *inst, VARIANT *objv, jsexcept_t *ei, VARIANT *retv)
1990 jsdisp_t *obj, *iter, *tmp = NULL;
1991 VARIANT_BOOL ret = VARIANT_FALSE;
1992 BOOL b;
1993 VARIANT var;
1994 HRESULT hres;
1996 static const WCHAR prototypeW[] = {'p','r','o','t','o','t', 'y', 'p','e',0};
1998 if(V_VT(objv) != VT_DISPATCH || !V_DISPATCH(objv))
1999 return throw_type_error(ctx, ei, JS_E_FUNCTION_EXPECTED, NULL);
2001 obj = iface_to_jsdisp((IUnknown*)V_DISPATCH(objv));
2002 if(!obj) {
2003 FIXME("throw TypeError\n");
2004 return E_FAIL;
2007 if(is_class(obj, JSCLASS_FUNCTION)) {
2008 hres = jsdisp_propget_name(obj, prototypeW, &var, ei, NULL/*FIXME*/);
2009 }else {
2010 FIXME("throw TypeError\n");
2011 hres = E_FAIL;
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);