Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenengine.c
Go to the documentation of this file.
00001 /* 00002 * Copyright 2008 Jacek Caban for CodeWeavers 00003 * 00004 * This library is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU Lesser General Public 00006 * License as published by the Free Software Foundation; either 00007 * version 2.1 of the License, or (at your option) any later version. 00008 * 00009 * This library is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 * Lesser General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU Lesser General Public 00015 * License along with this library; if not, write to the Free Software 00016 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00017 */ 00018 00019 #include "config.h" 00020 #include "wine/port.h" 00021 00022 #include <math.h> 00023 00024 #include "jscript.h" 00025 #include "engine.h" 00026 00027 #include "wine/debug.h" 00028 00029 WINE_DEFAULT_DEBUG_CHANNEL(jscript); 00030 00031 #define EXPR_NOVAL 0x0001 00032 #define EXPR_NEWREF 0x0002 00033 #define EXPR_STRREF 0x0004 00034 00035 static inline HRESULT stat_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret) 00036 { 00037 return stat->eval(ctx, stat, rt, ret); 00038 } 00039 00040 static inline HRESULT expr_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) 00041 { 00042 return _expr->eval(ctx, _expr, flags, ei, ret); 00043 } 00044 00045 static void exprval_release(exprval_t *val) 00046 { 00047 switch(val->type) { 00048 case EXPRVAL_VARIANT: 00049 if(V_VT(&val->u.var) != VT_EMPTY) 00050 VariantClear(&val->u.var); 00051 return; 00052 case EXPRVAL_IDREF: 00053 if(val->u.idref.disp) 00054 IDispatch_Release(val->u.idref.disp); 00055 return; 00056 case EXPRVAL_NAMEREF: 00057 if(val->u.nameref.disp) 00058 IDispatch_Release(val->u.nameref.disp); 00059 SysFreeString(val->u.nameref.name); 00060 return; 00061 case EXPRVAL_INVALID: 00062 SysFreeString(val->u.identifier); 00063 } 00064 } 00065 00066 /* ECMA-262 3rd Edition 8.7.1 */ 00067 static HRESULT exprval_value(script_ctx_t *ctx, exprval_t *val, jsexcept_t *ei, VARIANT *ret) 00068 { 00069 V_VT(ret) = VT_EMPTY; 00070 00071 switch(val->type) { 00072 case EXPRVAL_VARIANT: 00073 return VariantCopy(ret, &val->u.var); 00074 case EXPRVAL_IDREF: 00075 if(!val->u.idref.disp) { 00076 FIXME("throw ReferenceError\n"); 00077 return E_FAIL; 00078 } 00079 00080 return disp_propget(ctx, val->u.idref.disp, val->u.idref.id, ret, ei, NULL/*FIXME*/); 00081 case EXPRVAL_NAMEREF: 00082 break; 00083 case EXPRVAL_INVALID: 00084 return throw_type_error(ctx, ei, IDS_UNDEFINED, val->u.identifier); 00085 } 00086 00087 ERR("type %d\n", val->type); 00088 return E_FAIL; 00089 } 00090 00091 static HRESULT exprval_to_value(script_ctx_t *ctx, exprval_t *val, jsexcept_t *ei, VARIANT *ret) 00092 { 00093 if(val->type == EXPRVAL_VARIANT) { 00094 *ret = val->u.var; 00095 V_VT(&val->u.var) = VT_EMPTY; 00096 return S_OK; 00097 } 00098 00099 return exprval_value(ctx, val, ei, ret); 00100 } 00101 00102 static HRESULT exprval_to_boolean(script_ctx_t *ctx, exprval_t *exprval, jsexcept_t *ei, VARIANT_BOOL *b) 00103 { 00104 if(exprval->type != EXPRVAL_VARIANT) { 00105 VARIANT val; 00106 HRESULT hres; 00107 00108 hres = exprval_to_value(ctx, exprval, ei, &val); 00109 if(FAILED(hres)) 00110 return hres; 00111 00112 hres = to_boolean(&val, b); 00113 VariantClear(&val); 00114 return hres; 00115 } 00116 00117 return to_boolean(&exprval->u.var, b); 00118 } 00119 00120 static void exprval_init(exprval_t *val) 00121 { 00122 val->type = EXPRVAL_VARIANT; 00123 V_VT(&val->u.var) = VT_EMPTY; 00124 } 00125 00126 static void exprval_set_idref(exprval_t *val, IDispatch *disp, DISPID id) 00127 { 00128 val->type = EXPRVAL_IDREF; 00129 val->u.idref.disp = disp; 00130 val->u.idref.id = id; 00131 00132 if(disp) 00133 IDispatch_AddRef(disp); 00134 } 00135 00136 HRESULT scope_push(scope_chain_t *scope, DispatchEx *obj, scope_chain_t **ret) 00137 { 00138 scope_chain_t *new_scope; 00139 00140 new_scope = heap_alloc(sizeof(scope_chain_t)); 00141 if(!new_scope) 00142 return E_OUTOFMEMORY; 00143 00144 new_scope->ref = 1; 00145 00146 IDispatchEx_AddRef(_IDispatchEx_(obj)); 00147 new_scope->obj = obj; 00148 00149 if(scope) { 00150 scope_addref(scope); 00151 new_scope->next = scope; 00152 }else { 00153 new_scope->next = NULL; 00154 } 00155 00156 *ret = new_scope; 00157 return S_OK; 00158 } 00159 00160 static void scope_pop(scope_chain_t **scope) 00161 { 00162 scope_chain_t *tmp; 00163 00164 tmp = *scope; 00165 *scope = tmp->next; 00166 scope_release(tmp); 00167 } 00168 00169 void scope_release(scope_chain_t *scope) 00170 { 00171 if(--scope->ref) 00172 return; 00173 00174 if(scope->next) 00175 scope_release(scope->next); 00176 00177 jsdisp_release(scope->obj); 00178 heap_free(scope); 00179 } 00180 00181 HRESULT create_exec_ctx(script_ctx_t *script_ctx, IDispatch *this_obj, DispatchEx *var_disp, 00182 scope_chain_t *scope, exec_ctx_t **ret) 00183 { 00184 exec_ctx_t *ctx; 00185 00186 ctx = heap_alloc_zero(sizeof(exec_ctx_t)); 00187 if(!ctx) 00188 return E_OUTOFMEMORY; 00189 00190 ctx->ref = 1; 00191 00192 if(this_obj) 00193 ctx->this_obj = this_obj; 00194 else if(script_ctx->host_global) 00195 ctx->this_obj = script_ctx->host_global; 00196 else 00197 ctx->this_obj = (IDispatch*)_IDispatchEx_(script_ctx->global); 00198 IDispatch_AddRef(ctx->this_obj); 00199 00200 IDispatchEx_AddRef(_IDispatchEx_(var_disp)); 00201 ctx->var_disp = var_disp; 00202 00203 if(scope) { 00204 scope_addref(scope); 00205 ctx->scope_chain = scope; 00206 } 00207 00208 *ret = ctx; 00209 return S_OK; 00210 } 00211 00212 void exec_release(exec_ctx_t *ctx) 00213 { 00214 if(--ctx->ref) 00215 return; 00216 00217 if(ctx->scope_chain) 00218 scope_release(ctx->scope_chain); 00219 if(ctx->var_disp) 00220 jsdisp_release(ctx->var_disp); 00221 if(ctx->this_obj) 00222 IDispatch_Release(ctx->this_obj); 00223 heap_free(ctx); 00224 } 00225 00226 static HRESULT disp_get_id(script_ctx_t *ctx, IDispatch *disp, BSTR name, DWORD flags, DISPID *id) 00227 { 00228 IDispatchEx *dispex; 00229 HRESULT hres; 00230 00231 hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex); 00232 if(FAILED(hres)) { 00233 TRACE("unsing IDispatch\n"); 00234 00235 *id = 0; 00236 return IDispatch_GetIDsOfNames(disp, &IID_NULL, &name, 1, 0, id); 00237 } 00238 00239 *id = 0; 00240 hres = IDispatchEx_GetDispID(dispex, name, make_grfdex(ctx, flags|fdexNameCaseSensitive), id); 00241 IDispatchEx_Release(dispex); 00242 return hres; 00243 } 00244 00245 /* ECMA-262 3rd Edition 8.7.2 */ 00246 static HRESULT put_value(script_ctx_t *ctx, exprval_t *ref, VARIANT *v, jsexcept_t *ei) 00247 { 00248 if(ref->type != EXPRVAL_IDREF) 00249 return throw_reference_error(ctx, ei, IDS_ILLEGAL_ASSIGN, NULL); 00250 00251 return disp_propput(ctx, ref->u.idref.disp, ref->u.idref.id, v, ei, NULL/*FIXME*/); 00252 } 00253 00254 static inline BOOL is_null(const VARIANT *v) 00255 { 00256 return V_VT(v) == VT_NULL || (V_VT(v) == VT_DISPATCH && !V_DISPATCH(v)); 00257 } 00258 00259 static HRESULT disp_cmp(IDispatch *disp1, IDispatch *disp2, BOOL *ret) 00260 { 00261 IObjectIdentity *identity; 00262 IUnknown *unk1, *unk2; 00263 HRESULT hres; 00264 00265 if(disp1 == disp2) { 00266 *ret = TRUE; 00267 return S_OK; 00268 } 00269 00270 if(!disp1 || !disp2) { 00271 *ret = FALSE; 00272 return S_OK; 00273 } 00274 00275 hres = IDispatch_QueryInterface(disp1, &IID_IUnknown, (void**)&unk1); 00276 if(FAILED(hres)) 00277 return hres; 00278 00279 hres = IDispatch_QueryInterface(disp2, &IID_IUnknown, (void**)&unk2); 00280 if(FAILED(hres)) { 00281 IUnknown_Release(unk1); 00282 return hres; 00283 } 00284 00285 if(unk1 == unk2) { 00286 *ret = TRUE; 00287 }else { 00288 hres = IUnknown_QueryInterface(unk1, &IID_IObjectIdentity, (void**)&identity); 00289 if(SUCCEEDED(hres)) { 00290 hres = IObjectIdentity_IsEqualObject(identity, unk2); 00291 IObjectIdentity_Release(identity); 00292 *ret = hres == S_OK; 00293 }else { 00294 *ret = FALSE; 00295 } 00296 } 00297 00298 IUnknown_Release(unk1); 00299 IUnknown_Release(unk2); 00300 return S_OK; 00301 } 00302 00303 /* ECMA-262 3rd Edition 11.9.6 */ 00304 static HRESULT equal2_values(VARIANT *lval, VARIANT *rval, BOOL *ret) 00305 { 00306 TRACE("\n"); 00307 00308 if(V_VT(lval) != V_VT(rval)) { 00309 if(is_num_vt(V_VT(lval)) && is_num_vt(V_VT(rval))) 00310 *ret = num_val(lval) == num_val(rval); 00311 else if(is_null(lval)) 00312 *ret = is_null(rval); 00313 else 00314 *ret = FALSE; 00315 return S_OK; 00316 } 00317 00318 switch(V_VT(lval)) { 00319 case VT_EMPTY: 00320 case VT_NULL: 00321 *ret = VARIANT_TRUE; 00322 break; 00323 case VT_I4: 00324 *ret = V_I4(lval) == V_I4(rval); 00325 break; 00326 case VT_R8: 00327 *ret = V_R8(lval) == V_R8(rval); 00328 break; 00329 case VT_BSTR: 00330 if(!V_BSTR(lval)) 00331 *ret = SysStringLen(V_BSTR(rval))?FALSE:TRUE; 00332 else if(!V_BSTR(rval)) 00333 *ret = SysStringLen(V_BSTR(lval))?FALSE:TRUE; 00334 else 00335 *ret = !strcmpW(V_BSTR(lval), V_BSTR(rval)); 00336 break; 00337 case VT_DISPATCH: 00338 return disp_cmp(V_DISPATCH(lval), V_DISPATCH(rval), ret); 00339 case VT_BOOL: 00340 *ret = !V_BOOL(lval) == !V_BOOL(rval); 00341 break; 00342 default: 00343 FIXME("unimplemented vt %d\n", V_VT(lval)); 00344 return E_NOTIMPL; 00345 } 00346 00347 return S_OK; 00348 } 00349 00350 static HRESULT literal_to_var(script_ctx_t *ctx, literal_t *literal, VARIANT *v) 00351 { 00352 switch(literal->type) { 00353 case LT_NULL: 00354 V_VT(v) = VT_NULL; 00355 break; 00356 case LT_INT: 00357 V_VT(v) = VT_I4; 00358 V_I4(v) = literal->u.lval; 00359 break; 00360 case LT_DOUBLE: 00361 V_VT(v) = VT_R8; 00362 V_R8(v) = literal->u.dval; 00363 break; 00364 case LT_STRING: { 00365 BSTR str = SysAllocString(literal->u.wstr); 00366 if(!str) 00367 return E_OUTOFMEMORY; 00368 00369 V_VT(v) = VT_BSTR; 00370 V_BSTR(v) = str; 00371 break; 00372 } 00373 case LT_BOOL: 00374 V_VT(v) = VT_BOOL; 00375 V_BOOL(v) = literal->u.bval; 00376 break; 00377 case LT_REGEXP: { 00378 DispatchEx *regexp; 00379 HRESULT hres; 00380 00381 hres = create_regexp(ctx, literal->u.regexp.str, literal->u.regexp.str_len, 00382 literal->u.regexp.flags, ®exp); 00383 if(FAILED(hres)) 00384 return hres; 00385 00386 V_VT(v) = VT_DISPATCH; 00387 V_DISPATCH(v) = (IDispatch*)_IDispatchEx_(regexp); 00388 } 00389 } 00390 00391 return S_OK; 00392 } 00393 00394 static BOOL lookup_global_members(script_ctx_t *ctx, BSTR identifier, exprval_t *ret) 00395 { 00396 named_item_t *item; 00397 DISPID id; 00398 HRESULT hres; 00399 00400 for(item = ctx->named_items; item; item = item->next) { 00401 if(item->flags & SCRIPTITEM_GLOBALMEMBERS) { 00402 hres = disp_get_id(ctx, item->disp, identifier, 0, &id); 00403 if(SUCCEEDED(hres)) { 00404 if(ret) 00405 exprval_set_idref(ret, item->disp, id); 00406 return TRUE; 00407 } 00408 } 00409 } 00410 00411 return FALSE; 00412 } 00413 00414 HRESULT exec_source(exec_ctx_t *ctx, parser_ctx_t *parser, source_elements_t *source, exec_type_t exec_type, 00415 jsexcept_t *ei, VARIANT *retv) 00416 { 00417 script_ctx_t *script = parser->script; 00418 function_declaration_t *func; 00419 parser_ctx_t *prev_parser; 00420 var_list_t *var; 00421 VARIANT val, tmp; 00422 statement_t *stat; 00423 exec_ctx_t *prev_ctx; 00424 return_type_t rt; 00425 HRESULT hres = S_OK; 00426 00427 for(func = source->functions; func; func = func->next) { 00428 DispatchEx *func_obj; 00429 VARIANT var; 00430 00431 hres = create_source_function(parser, func->expr->parameter_list, func->expr->source_elements, 00432 ctx->scope_chain, func->expr->src_str, func->expr->src_len, &func_obj); 00433 if(FAILED(hres)) 00434 return hres; 00435 00436 V_VT(&var) = VT_DISPATCH; 00437 V_DISPATCH(&var) = (IDispatch*)_IDispatchEx_(func_obj); 00438 hres = jsdisp_propput_name(ctx->var_disp, func->expr->identifier, &var, ei, NULL); 00439 jsdisp_release(func_obj); 00440 if(FAILED(hres)) 00441 return hres; 00442 } 00443 00444 for(var = source->variables; var; var = var->next) { 00445 DISPID id = 0; 00446 BSTR name; 00447 00448 name = SysAllocString(var->identifier); 00449 if(!name) 00450 return E_OUTOFMEMORY; 00451 00452 if(!lookup_global_members(parser->script, name, NULL)) 00453 hres = jsdisp_get_id(ctx->var_disp, var->identifier, fdexNameEnsure, &id); 00454 SysFreeString(name); 00455 if(FAILED(hres)) 00456 return hres; 00457 } 00458 00459 prev_ctx = script->exec_ctx; 00460 script->exec_ctx = ctx; 00461 00462 prev_parser = ctx->parser; 00463 ctx->parser = parser; 00464 00465 V_VT(&val) = VT_EMPTY; 00466 memset(&rt, 0, sizeof(rt)); 00467 rt.type = RT_NORMAL; 00468 00469 for(stat = source->statement; stat; stat = stat->next) { 00470 hres = stat_eval(ctx, stat, &rt, &tmp); 00471 if(FAILED(hres)) 00472 break; 00473 00474 VariantClear(&val); 00475 val = tmp; 00476 if(rt.type != RT_NORMAL) 00477 break; 00478 } 00479 00480 script->exec_ctx = prev_ctx; 00481 ctx->parser = prev_parser; 00482 00483 if(rt.type != RT_NORMAL && rt.type != RT_RETURN) { 00484 FIXME("wrong rt %d\n", rt.type); 00485 hres = E_FAIL; 00486 } 00487 00488 *ei = rt.ei; 00489 if(FAILED(hres)) { 00490 VariantClear(&val); 00491 return hres; 00492 } 00493 00494 if(retv && (exec_type == EXECT_EVAL || rt.type == RT_RETURN)) 00495 *retv = val; 00496 else { 00497 if (retv) { 00498 VariantInit(retv); 00499 } 00500 VariantClear(&val); 00501 } 00502 return S_OK; 00503 } 00504 00505 /* ECMA-262 3rd Edition 10.1.4 */ 00506 static HRESULT identifier_eval(exec_ctx_t *ctx, BSTR identifier, DWORD flags, jsexcept_t *ei, exprval_t *ret) 00507 { 00508 scope_chain_t *scope; 00509 named_item_t *item; 00510 DISPID id = 0; 00511 HRESULT hres; 00512 00513 TRACE("%s\n", debugstr_w(identifier)); 00514 00515 for(scope = ctx->scope_chain; scope; scope = scope->next) { 00516 hres = jsdisp_get_id(scope->obj, identifier, 0, &id); 00517 if(SUCCEEDED(hres)) 00518 break; 00519 } 00520 00521 if(scope) { 00522 exprval_set_idref(ret, (IDispatch*)_IDispatchEx_(scope->obj), id); 00523 return S_OK; 00524 } 00525 00526 hres = jsdisp_get_id(ctx->parser->script->global, identifier, 0, &id); 00527 if(SUCCEEDED(hres)) { 00528 exprval_set_idref(ret, (IDispatch*)_IDispatchEx_(ctx->parser->script->global), id); 00529 return S_OK; 00530 } 00531 00532 for(item = ctx->parser->script->named_items; item; item = item->next) { 00533 if((item->flags & SCRIPTITEM_ISVISIBLE) && !strcmpW(item->name, identifier)) { 00534 if(!item->disp) { 00535 IUnknown *unk; 00536 00537 if(!ctx->parser->script->site) 00538 break; 00539 00540 hres = IActiveScriptSite_GetItemInfo(ctx->parser->script->site, identifier, 00541 SCRIPTINFO_IUNKNOWN, &unk, NULL); 00542 if(FAILED(hres)) { 00543 WARN("GetItemInfo failed: %08x\n", hres); 00544 break; 00545 } 00546 00547 hres = IUnknown_QueryInterface(unk, &IID_IDispatch, (void**)&item->disp); 00548 IUnknown_Release(unk); 00549 if(FAILED(hres)) { 00550 WARN("object does not implement IDispatch\n"); 00551 break; 00552 } 00553 } 00554 00555 ret->type = EXPRVAL_VARIANT; 00556 V_VT(&ret->u.var) = VT_DISPATCH; 00557 V_DISPATCH(&ret->u.var) = item->disp; 00558 IDispatch_AddRef(item->disp); 00559 return S_OK; 00560 } 00561 } 00562 00563 if(lookup_global_members(ctx->parser->script, identifier, ret)) 00564 return S_OK; 00565 00566 if(flags & EXPR_NEWREF) { 00567 hres = jsdisp_get_id(ctx->parser->script->global, identifier, fdexNameEnsure, &id); 00568 if(FAILED(hres)) 00569 return hres; 00570 00571 exprval_set_idref(ret, (IDispatch*)_IDispatchEx_(ctx->parser->script->global), id); 00572 return S_OK; 00573 } 00574 00575 ret->type = EXPRVAL_INVALID; 00576 ret->u.identifier = SysAllocString(identifier); 00577 if(!ret->u.identifier) 00578 return E_OUTOFMEMORY; 00579 00580 return S_OK; 00581 } 00582 00583 /* ECMA-262 3rd Edition 12.1 */ 00584 HRESULT block_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret) 00585 { 00586 block_statement_t *stat = (block_statement_t*)_stat; 00587 VARIANT val, tmp; 00588 statement_t *iter; 00589 HRESULT hres = S_OK; 00590 00591 TRACE("\n"); 00592 00593 V_VT(&val) = VT_EMPTY; 00594 for(iter = stat->stat_list; iter; iter = iter->next) { 00595 hres = stat_eval(ctx, iter, rt, &tmp); 00596 if(FAILED(hres)) 00597 break; 00598 00599 VariantClear(&val); 00600 val = tmp; 00601 if(rt->type != RT_NORMAL) 00602 break; 00603 } 00604 00605 if(FAILED(hres)) { 00606 VariantClear(&val); 00607 return hres; 00608 } 00609 00610 *ret = val; 00611 return S_OK; 00612 } 00613 00614 /* ECMA-262 3rd Edition 12.2 */ 00615 static HRESULT variable_list_eval(exec_ctx_t *ctx, variable_declaration_t *var_list, jsexcept_t *ei) 00616 { 00617 variable_declaration_t *iter; 00618 HRESULT hres = S_OK; 00619 00620 for(iter = var_list; iter; iter = iter->next) { 00621 exprval_t exprval; 00622 VARIANT val; 00623 00624 if(!iter->expr) 00625 continue; 00626 00627 hres = expr_eval(ctx, iter->expr, 0, ei, &exprval); 00628 if(FAILED(hres)) 00629 break; 00630 00631 hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val); 00632 exprval_release(&exprval); 00633 if(FAILED(hres)) 00634 break; 00635 00636 hres = jsdisp_propput_name(ctx->var_disp, iter->identifier, &val, ei, NULL/*FIXME*/); 00637 VariantClear(&val); 00638 if(FAILED(hres)) 00639 break; 00640 } 00641 00642 return hres; 00643 } 00644 00645 /* ECMA-262 3rd Edition 12.2 */ 00646 HRESULT var_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret) 00647 { 00648 var_statement_t *stat = (var_statement_t*)_stat; 00649 HRESULT hres; 00650 00651 TRACE("\n"); 00652 00653 hres = variable_list_eval(ctx, stat->variable_list, &rt->ei); 00654 if(FAILED(hres)) 00655 return hres; 00656 00657 V_VT(ret) = VT_EMPTY; 00658 return S_OK; 00659 } 00660 00661 /* ECMA-262 3rd Edition 12.3 */ 00662 HRESULT empty_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret) 00663 { 00664 TRACE("\n"); 00665 00666 V_VT(ret) = VT_EMPTY; 00667 return S_OK; 00668 } 00669 00670 /* ECMA-262 3rd Edition 12.4 */ 00671 HRESULT expression_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret) 00672 { 00673 expression_statement_t *stat = (expression_statement_t*)_stat; 00674 exprval_t exprval; 00675 VARIANT val; 00676 HRESULT hres; 00677 00678 TRACE("\n"); 00679 00680 hres = expr_eval(ctx, stat->expr, EXPR_NOVAL, &rt->ei, &exprval); 00681 if(FAILED(hres)) 00682 return hres; 00683 00684 hres = exprval_to_value(ctx->parser->script, &exprval, &rt->ei, &val); 00685 exprval_release(&exprval); 00686 if(FAILED(hres)) 00687 return hres; 00688 00689 *ret = val; 00690 TRACE("= %s\n", debugstr_variant(ret)); 00691 return S_OK; 00692 } 00693 00694 /* ECMA-262 3rd Edition 12.5 */ 00695 HRESULT if_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret) 00696 { 00697 if_statement_t *stat = (if_statement_t*)_stat; 00698 exprval_t exprval; 00699 VARIANT_BOOL b; 00700 HRESULT hres; 00701 00702 TRACE("\n"); 00703 00704 hres = expr_eval(ctx, stat->expr, 0, &rt->ei, &exprval); 00705 if(FAILED(hres)) 00706 return hres; 00707 00708 hres = exprval_to_boolean(ctx->parser->script, &exprval, &rt->ei, &b); 00709 exprval_release(&exprval); 00710 if(FAILED(hres)) 00711 return hres; 00712 00713 if(b) 00714 hres = stat_eval(ctx, stat->if_stat, rt, ret); 00715 else if(stat->else_stat) 00716 hres = stat_eval(ctx, stat->else_stat, rt, ret); 00717 else 00718 V_VT(ret) = VT_EMPTY; 00719 00720 return hres; 00721 } 00722 00723 /* ECMA-262 3rd Edition 12.6.2 */ 00724 HRESULT while_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret) 00725 { 00726 while_statement_t *stat = (while_statement_t*)_stat; 00727 exprval_t exprval; 00728 VARIANT val, tmp; 00729 VARIANT_BOOL b; 00730 BOOL test_expr; 00731 HRESULT hres; 00732 00733 TRACE("\n"); 00734 00735 V_VT(&val) = VT_EMPTY; 00736 test_expr = !stat->do_while; 00737 00738 while(1) { 00739 if(test_expr) { 00740 hres = expr_eval(ctx, stat->expr, 0, &rt->ei, &exprval); 00741 if(FAILED(hres)) 00742 break; 00743 00744 hres = exprval_to_boolean(ctx->parser->script, &exprval, &rt->ei, &b); 00745 exprval_release(&exprval); 00746 if(FAILED(hres) || !b) 00747 break; 00748 }else { 00749 test_expr = TRUE; 00750 } 00751 00752 hres = stat_eval(ctx, stat->statement, rt, &tmp); 00753 if(FAILED(hres)) 00754 break; 00755 00756 VariantClear(&val); 00757 val = tmp; 00758 00759 if(rt->type == RT_CONTINUE) 00760 rt->type = RT_NORMAL; 00761 if(rt->type != RT_NORMAL) 00762 break; 00763 } 00764 00765 if(FAILED(hres)) { 00766 VariantClear(&val); 00767 return hres; 00768 } 00769 00770 if(rt->type == RT_BREAK) 00771 rt->type = RT_NORMAL; 00772 00773 *ret = val; 00774 return S_OK; 00775 } 00776 00777 /* ECMA-262 3rd Edition 12.6.3 */ 00778 HRESULT for_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret) 00779 { 00780 for_statement_t *stat = (for_statement_t*)_stat; 00781 VARIANT val, tmp, retv; 00782 exprval_t exprval; 00783 VARIANT_BOOL b; 00784 HRESULT hres; 00785 00786 TRACE("\n"); 00787 00788 if(stat->variable_list) { 00789 hres = variable_list_eval(ctx, stat->variable_list, &rt->ei); 00790 if(FAILED(hres)) 00791 return hres; 00792 }else if(stat->begin_expr) { 00793 hres = expr_eval(ctx, stat->begin_expr, EXPR_NEWREF, &rt->ei, &exprval); 00794 if(FAILED(hres)) 00795 return hres; 00796 00797 hres = exprval_to_value(ctx->parser->script, &exprval, &rt->ei, &val); 00798 exprval_release(&exprval); 00799 if(FAILED(hres)) 00800 return hres; 00801 00802 VariantClear(&val); 00803 } 00804 00805 V_VT(&retv) = VT_EMPTY; 00806 00807 while(1) { 00808 if(stat->expr) { 00809 hres = expr_eval(ctx, stat->expr, 0, &rt->ei, &exprval); 00810 if(FAILED(hres)) 00811 break; 00812 00813 hres = exprval_to_boolean(ctx->parser->script, &exprval, &rt->ei, &b); 00814 exprval_release(&exprval); 00815 if(FAILED(hres) || !b) 00816 break; 00817 } 00818 00819 hres = stat_eval(ctx, stat->statement, rt, &tmp); 00820 if(FAILED(hres)) 00821 break; 00822 00823 VariantClear(&retv); 00824 retv = tmp; 00825 00826 if(rt->type == RT_CONTINUE) 00827 rt->type = RT_NORMAL; 00828 else if(rt->type != RT_NORMAL) 00829 break; 00830 00831 if(stat->end_expr) { 00832 hres = expr_eval(ctx, stat->end_expr, 0, &rt->ei, &exprval); 00833 if(FAILED(hres)) 00834 break; 00835 00836 hres = exprval_to_value(ctx->parser->script, &exprval, &rt->ei, &val); 00837 exprval_release(&exprval); 00838 if(FAILED(hres)) 00839 break; 00840 00841 VariantClear(&val); 00842 } 00843 } 00844 00845 if(FAILED(hres)) { 00846 VariantClear(&retv); 00847 return hres; 00848 } 00849 00850 if(rt->type == RT_BREAK) 00851 rt->type = RT_NORMAL; 00852 00853 *ret = retv; 00854 return S_OK; 00855 } 00856 00857 /* ECMA-262 3rd Edition 12.6.4 */ 00858 HRESULT forin_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret) 00859 { 00860 forin_statement_t *stat = (forin_statement_t*)_stat; 00861 VARIANT val, name, retv, tmp; 00862 DISPID id = DISPID_STARTENUM; 00863 BSTR str, identifier = NULL; 00864 IDispatchEx *in_obj; 00865 exprval_t exprval; 00866 HRESULT hres; 00867 00868 TRACE("\n"); 00869 00870 if(stat->variable) { 00871 hres = variable_list_eval(ctx, stat->variable, &rt->ei); 00872 if(FAILED(hres)) 00873 return hres; 00874 } 00875 00876 hres = expr_eval(ctx, stat->in_expr, EXPR_NEWREF, &rt->ei, &exprval); 00877 if(FAILED(hres)) 00878 return hres; 00879 00880 hres = exprval_to_value(ctx->parser->script, &exprval, &rt->ei, &val); 00881 exprval_release(&exprval); 00882 if(FAILED(hres)) 00883 return hres; 00884 00885 if(V_VT(&val) != VT_DISPATCH) { 00886 TRACE("in vt %d\n", V_VT(&val)); 00887 VariantClear(&val); 00888 V_VT(ret) = VT_EMPTY; 00889 return S_OK; 00890 } 00891 00892 hres = IDispatch_QueryInterface(V_DISPATCH(&val), &IID_IDispatchEx, (void**)&in_obj); 00893 IDispatch_Release(V_DISPATCH(&val)); 00894 if(FAILED(hres)) { 00895 FIXME("Object doesn't support IDispatchEx\n"); 00896 return E_NOTIMPL; 00897 } 00898 00899 V_VT(&retv) = VT_EMPTY; 00900 00901 if(stat->variable) 00902 identifier = SysAllocString(stat->variable->identifier); 00903 00904 while(1) { 00905 hres = IDispatchEx_GetNextDispID(in_obj, fdexEnumDefault, id, &id); 00906 if(FAILED(hres) || hres == S_FALSE) 00907 break; 00908 00909 hres = IDispatchEx_GetMemberName(in_obj, id, &str); 00910 if(FAILED(hres)) 00911 break; 00912 00913 TRACE("iter %s\n", debugstr_w(str)); 00914 00915 if(stat->variable) 00916 hres = identifier_eval(ctx, identifier, 0, NULL, &exprval); 00917 else 00918 hres = expr_eval(ctx, stat->expr, EXPR_NEWREF, &rt->ei, &exprval); 00919 if(SUCCEEDED(hres)) { 00920 V_VT(&name) = VT_BSTR; 00921 V_BSTR(&name) = str; 00922 hres = put_value(ctx->parser->script, &exprval, &name, &rt->ei); 00923 exprval_release(&exprval); 00924 } 00925 SysFreeString(str); 00926 if(FAILED(hres)) 00927 break; 00928 00929 hres = stat_eval(ctx, stat->statement, rt, &tmp); 00930 if(FAILED(hres)) 00931 break; 00932 00933 VariantClear(&retv); 00934 retv = tmp; 00935 00936 if(rt->type == RT_CONTINUE) 00937 rt->type = RT_NORMAL; 00938 else if(rt->type != RT_NORMAL) 00939 break; 00940 } 00941 00942 SysFreeString(identifier); 00943 IDispatchEx_Release(in_obj); 00944 if(FAILED(hres)) { 00945 VariantClear(&retv); 00946 return hres; 00947 } 00948 00949 if(rt->type == RT_BREAK) 00950 rt->type = RT_NORMAL; 00951 00952 *ret = retv; 00953 return S_OK; 00954 } 00955 00956 /* ECMA-262 3rd Edition 12.7 */ 00957 HRESULT continue_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret) 00958 { 00959 branch_statement_t *stat = (branch_statement_t*)_stat; 00960 00961 TRACE("\n"); 00962 00963 if(stat->identifier) { 00964 FIXME("indentifier not implemented\n"); 00965 return E_NOTIMPL; 00966 } 00967 00968 rt->type = RT_CONTINUE; 00969 V_VT(ret) = VT_EMPTY; 00970 return S_OK; 00971 } 00972 00973 /* ECMA-262 3rd Edition 12.8 */ 00974 HRESULT break_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret) 00975 { 00976 branch_statement_t *stat = (branch_statement_t*)_stat; 00977 00978 TRACE("\n"); 00979 00980 if(stat->identifier) { 00981 FIXME("indentifier not implemented\n"); 00982 return E_NOTIMPL; 00983 } 00984 00985 rt->type = RT_BREAK; 00986 V_VT(ret) = VT_EMPTY; 00987 return S_OK; 00988 } 00989 00990 /* ECMA-262 3rd Edition 12.9 */ 00991 HRESULT return_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret) 00992 { 00993 expression_statement_t *stat = (expression_statement_t*)_stat; 00994 HRESULT hres; 00995 00996 TRACE("\n"); 00997 00998 if(stat->expr) { 00999 exprval_t exprval; 01000 01001 hres = expr_eval(ctx, stat->expr, 0, &rt->ei, &exprval); 01002 if(FAILED(hres)) 01003 return hres; 01004 01005 hres = exprval_to_value(ctx->parser->script, &exprval, &rt->ei, ret); 01006 exprval_release(&exprval); 01007 if(FAILED(hres)) 01008 return hres; 01009 }else { 01010 V_VT(ret) = VT_EMPTY; 01011 } 01012 01013 TRACE("= %s\n", debugstr_variant(ret)); 01014 rt->type = RT_RETURN; 01015 return S_OK; 01016 } 01017 01018 /* ECMA-262 3rd Edition 12.10 */ 01019 HRESULT with_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret) 01020 { 01021 with_statement_t *stat = (with_statement_t*)_stat; 01022 exprval_t exprval; 01023 IDispatch *disp; 01024 DispatchEx *obj; 01025 VARIANT val; 01026 HRESULT hres; 01027 01028 TRACE("\n"); 01029 01030 hres = expr_eval(ctx, stat->expr, 0, &rt->ei, &exprval); 01031 if(FAILED(hres)) 01032 return hres; 01033 01034 hres = exprval_to_value(ctx->parser->script, &exprval, &rt->ei, &val); 01035 exprval_release(&exprval); 01036 if(FAILED(hres)) 01037 return hres; 01038 01039 hres = to_object(ctx->parser->script, &val, &disp); 01040 VariantClear(&val); 01041 if(FAILED(hres)) 01042 return hres; 01043 01044 obj = iface_to_jsdisp((IUnknown*)disp); 01045 IDispatch_Release(disp); 01046 if(!obj) { 01047 FIXME("disp id not jsdisp\n"); 01048 return E_NOTIMPL; 01049 } 01050 01051 hres = scope_push(ctx->scope_chain, obj, &ctx->scope_chain); 01052 jsdisp_release(obj); 01053 if(FAILED(hres)) 01054 return hres; 01055 01056 hres = stat_eval(ctx, stat->statement, rt, ret); 01057 01058 scope_pop(&ctx->scope_chain); 01059 return hres; 01060 } 01061 01062 /* ECMA-262 3rd Edition 12.12 */ 01063 HRESULT labelled_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret) 01064 { 01065 FIXME("\n"); 01066 return E_NOTIMPL; 01067 } 01068 01069 /* ECMA-262 3rd Edition 12.13 */ 01070 HRESULT switch_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret) 01071 { 01072 switch_statement_t *stat = (switch_statement_t*)_stat; 01073 case_clausule_t *iter, *default_clausule = NULL; 01074 statement_t *stat_iter; 01075 VARIANT val, cval; 01076 exprval_t exprval; 01077 BOOL b; 01078 HRESULT hres; 01079 01080 TRACE("\n"); 01081 01082 hres = expr_eval(ctx, stat->expr, 0, &rt->ei, &exprval); 01083 if(FAILED(hres)) 01084 return hres; 01085 01086 hres = exprval_to_value(ctx->parser->script, &exprval, &rt->ei, &val); 01087 exprval_release(&exprval); 01088 if(FAILED(hres)) 01089 return hres; 01090 01091 for(iter = stat->case_list; iter; iter = iter->next) { 01092 if(!iter->expr) { 01093 default_clausule = iter; 01094 continue; 01095 } 01096 01097 hres = expr_eval(ctx, iter->expr, 0, &rt->ei, &exprval); 01098 if(FAILED(hres)) 01099 break; 01100 01101 hres = exprval_to_value(ctx->parser->script, &exprval, &rt->ei, &cval); 01102 exprval_release(&exprval); 01103 if(FAILED(hres)) 01104 break; 01105 01106 hres = equal2_values(&val, &cval, &b); 01107 VariantClear(&cval); 01108 if(FAILED(hres) || b) 01109 break; 01110 } 01111 01112 VariantClear(&val); 01113 if(FAILED(hres)) 01114 return hres; 01115 01116 if(!iter) 01117 iter = default_clausule; 01118 01119 V_VT(&val) = VT_EMPTY; 01120 if(iter) { 01121 VARIANT tmp; 01122 01123 for(stat_iter = iter->stat; stat_iter; stat_iter = stat_iter->next) { 01124 hres = stat_eval(ctx, stat_iter, rt, &tmp); 01125 if(FAILED(hres)) 01126 break; 01127 01128 VariantClear(&val); 01129 val = tmp; 01130 01131 if(rt->type != RT_NORMAL) 01132 break; 01133 } 01134 } 01135 01136 if(FAILED(hres)) { 01137 VariantClear(&val); 01138 return hres; 01139 } 01140 01141 if(rt->type == RT_BREAK) 01142 rt->type = RT_NORMAL; 01143 01144 *ret = val; 01145 return S_OK; 01146 } 01147 01148 /* ECMA-262 3rd Edition 12.13 */ 01149 HRESULT throw_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret) 01150 { 01151 expression_statement_t *stat = (expression_statement_t*)_stat; 01152 exprval_t exprval; 01153 VARIANT val; 01154 HRESULT hres; 01155 01156 TRACE("\n"); 01157 01158 hres = expr_eval(ctx, stat->expr, 0, &rt->ei, &exprval); 01159 if(FAILED(hres)) 01160 return hres; 01161 01162 hres = exprval_to_value(ctx->parser->script, &exprval, &rt->ei, &val); 01163 exprval_release(&exprval); 01164 if(FAILED(hres)) 01165 return hres; 01166 01167 rt->ei.var = val; 01168 return DISP_E_EXCEPTION; 01169 } 01170 01171 /* ECMA-262 3rd Edition 12.14 */ 01172 static HRESULT catch_eval(exec_ctx_t *ctx, catch_block_t *block, return_type_t *rt, VARIANT *ret) 01173 { 01174 DispatchEx *var_disp; 01175 VARIANT ex, val; 01176 HRESULT hres; 01177 01178 ex = rt->ei.var; 01179 memset(&rt->ei, 0, sizeof(jsexcept_t)); 01180 01181 hres = create_dispex(ctx->parser->script, NULL, NULL, &var_disp); 01182 if(SUCCEEDED(hres)) { 01183 hres = jsdisp_propput_name(var_disp, block->identifier, &ex, &rt->ei, NULL/*FIXME*/); 01184 if(SUCCEEDED(hres)) { 01185 hres = scope_push(ctx->scope_chain, var_disp, &ctx->scope_chain); 01186 if(SUCCEEDED(hres)) { 01187 hres = stat_eval(ctx, block->statement, rt, &val); 01188 scope_pop(&ctx->scope_chain); 01189 } 01190 } 01191 01192 jsdisp_release(var_disp); 01193 } 01194 01195 VariantClear(&ex); 01196 if(FAILED(hres)) 01197 return hres; 01198 01199 *ret = val; 01200 return S_OK; 01201 } 01202 01203 /* ECMA-262 3rd Edition 12.14 */ 01204 HRESULT try_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret) 01205 { 01206 try_statement_t *stat = (try_statement_t*)_stat; 01207 VARIANT val; 01208 HRESULT hres; 01209 01210 TRACE("\n"); 01211 01212 hres = stat_eval(ctx, stat->try_statement, rt, &val); 01213 if(FAILED(hres)) { 01214 TRACE("EXCEPTION\n"); 01215 if(!stat->catch_block) 01216 return hres; 01217 01218 hres = catch_eval(ctx, stat->catch_block, rt, &val); 01219 if(FAILED(hres)) 01220 return hres; 01221 } 01222 01223 if(stat->finally_statement) { 01224 VariantClear(&val); 01225 hres = stat_eval(ctx, stat->finally_statement, rt, &val); 01226 if(FAILED(hres)) 01227 return hres; 01228 } 01229 01230 *ret = val; 01231 return S_OK; 01232 } 01233 01234 static HRESULT return_bool(exprval_t *ret, DWORD b) 01235 { 01236 ret->type = EXPRVAL_VARIANT; 01237 V_VT(&ret->u.var) = VT_BOOL; 01238 V_BOOL(&ret->u.var) = b ? VARIANT_TRUE : VARIANT_FALSE; 01239 01240 return S_OK; 01241 } 01242 01243 static HRESULT get_binary_expr_values(exec_ctx_t *ctx, binary_expression_t *expr, jsexcept_t *ei, VARIANT *lval, VARIANT *rval) 01244 { 01245 exprval_t exprval; 01246 HRESULT hres; 01247 01248 hres = expr_eval(ctx, expr->expression1, 0, ei, &exprval); 01249 if(FAILED(hres)) 01250 return hres; 01251 01252 hres = exprval_to_value(ctx->parser->script, &exprval, ei, lval); 01253 exprval_release(&exprval); 01254 if(FAILED(hres)) 01255 return hres; 01256 01257 hres = expr_eval(ctx, expr->expression2, 0, ei, &exprval); 01258 if(SUCCEEDED(hres)) { 01259 hres = exprval_to_value(ctx->parser->script, &exprval, ei, rval); 01260 exprval_release(&exprval); 01261 } 01262 01263 if(FAILED(hres)) { 01264 VariantClear(lval); 01265 return hres; 01266 } 01267 01268 return S_OK; 01269 } 01270 01271 typedef HRESULT (*oper_t)(exec_ctx_t*,VARIANT*,VARIANT*,jsexcept_t*,VARIANT*); 01272 01273 static HRESULT binary_expr_eval(exec_ctx_t *ctx, binary_expression_t *expr, oper_t oper, jsexcept_t *ei, 01274 exprval_t *ret) 01275 { 01276 VARIANT lval, rval, retv; 01277 HRESULT hres; 01278 01279 hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval); 01280 if(FAILED(hres)) 01281 return hres; 01282 01283 hres = oper(ctx, &lval, &rval, ei, &retv); 01284 VariantClear(&lval); 01285 VariantClear(&rval); 01286 if(FAILED(hres)) 01287 return hres; 01288 01289 ret->type = EXPRVAL_VARIANT; 01290 ret->u.var = retv; 01291 return S_OK; 01292 } 01293 01294 /* ECMA-262 3rd Edition 11.13.2 */ 01295 static HRESULT assign_oper_eval(exec_ctx_t *ctx, expression_t *lexpr, expression_t *rexpr, oper_t oper, 01296 jsexcept_t *ei, exprval_t *ret) 01297 { 01298 VARIANT retv, lval, rval; 01299 exprval_t exprval, exprvalr; 01300 HRESULT hres; 01301 01302 hres = expr_eval(ctx, lexpr, EXPR_NEWREF, ei, &exprval); 01303 if(FAILED(hres)) 01304 return hres; 01305 01306 hres = exprval_value(ctx->parser->script, &exprval, ei, &lval); 01307 if(SUCCEEDED(hres)) { 01308 hres = expr_eval(ctx, rexpr, 0, ei, &exprvalr); 01309 if(SUCCEEDED(hres)) { 01310 hres = exprval_value(ctx->parser->script, &exprvalr, ei, &rval); 01311 exprval_release(&exprvalr); 01312 } 01313 if(SUCCEEDED(hres)) { 01314 hres = oper(ctx, &lval, &rval, ei, &retv); 01315 VariantClear(&rval); 01316 } 01317 VariantClear(&lval); 01318 } 01319 01320 if(SUCCEEDED(hres)) { 01321 hres = put_value(ctx->parser->script, &exprval, &retv, ei); 01322 if(FAILED(hres)) 01323 VariantClear(&retv); 01324 } 01325 exprval_release(&exprval); 01326 01327 if(FAILED(hres)) 01328 return hres; 01329 01330 ret->type = EXPRVAL_VARIANT; 01331 ret->u.var = retv; 01332 return S_OK; 01333 } 01334 01335 /* ECMA-262 3rd Edition 13 */ 01336 HRESULT function_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) 01337 { 01338 function_expression_t *expr = (function_expression_t*)_expr; 01339 VARIANT var; 01340 HRESULT hres; 01341 01342 TRACE("\n"); 01343 01344 if(expr->identifier) { 01345 hres = jsdisp_propget_name(ctx->var_disp, expr->identifier, &var, ei, NULL/*FIXME*/); 01346 if(FAILED(hres)) 01347 return hres; 01348 }else { 01349 DispatchEx *dispex; 01350 01351 hres = create_source_function(ctx->parser, expr->parameter_list, expr->source_elements, ctx->scope_chain, 01352 expr->src_str, expr->src_len, &dispex); 01353 if(FAILED(hres)) 01354 return hres; 01355 01356 V_VT(&var) = VT_DISPATCH; 01357 V_DISPATCH(&var) = (IDispatch*)_IDispatchEx_(dispex); 01358 } 01359 01360 ret->type = EXPRVAL_VARIANT; 01361 ret->u.var = var; 01362 return S_OK; 01363 } 01364 01365 /* ECMA-262 3rd Edition 11.12 */ 01366 HRESULT conditional_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) 01367 { 01368 conditional_expression_t *expr = (conditional_expression_t*)_expr; 01369 exprval_t exprval; 01370 VARIANT_BOOL b; 01371 HRESULT hres; 01372 01373 TRACE("\n"); 01374 01375 hres = expr_eval(ctx, expr->expression, 0, ei, &exprval); 01376 if(FAILED(hres)) 01377 return hres; 01378 01379 hres = exprval_to_boolean(ctx->parser->script, &exprval, ei, &b); 01380 exprval_release(&exprval); 01381 if(FAILED(hres)) 01382 return hres; 01383 01384 return expr_eval(ctx, b ? expr->true_expression : expr->false_expression, flags, ei, ret); 01385 } 01386 01387 /* ECMA-262 3rd Edition 11.2.1 */ 01388 HRESULT array_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) 01389 { 01390 array_expression_t *expr = (array_expression_t*)_expr; 01391 exprval_t exprval; 01392 VARIANT member, val; 01393 DISPID id; 01394 BSTR str; 01395 IDispatch *obj = NULL; 01396 HRESULT hres; 01397 01398 TRACE("\n"); 01399 01400 hres = expr_eval(ctx, expr->member_expr, 0, ei, &exprval); 01401 if(FAILED(hres)) 01402 return hres; 01403 01404 hres = exprval_to_value(ctx->parser->script, &exprval, ei, &member); 01405 exprval_release(&exprval); 01406 if(FAILED(hres)) 01407 return hres; 01408 01409 hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval); 01410 if(SUCCEEDED(hres)) { 01411 hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val); 01412 exprval_release(&exprval); 01413 } 01414 01415 if(SUCCEEDED(hres)) { 01416 hres = to_object(ctx->parser->script, &member, &obj); 01417 if(FAILED(hres)) 01418 VariantClear(&val); 01419 } 01420 VariantClear(&member); 01421 if(SUCCEEDED(hres)) { 01422 hres = to_string(ctx->parser->script, &val, ei, &str); 01423 VariantClear(&val); 01424 if(SUCCEEDED(hres)) { 01425 if(flags & EXPR_STRREF) { 01426 ret->type = EXPRVAL_NAMEREF; 01427 ret->u.nameref.disp = obj; 01428 ret->u.nameref.name = str; 01429 return S_OK; 01430 } 01431 01432 hres = disp_get_id(ctx->parser->script, obj, str, flags & EXPR_NEWREF ? fdexNameEnsure : 0, &id); 01433 SysFreeString(str); 01434 } 01435 01436 if(SUCCEEDED(hres)) { 01437 exprval_set_idref(ret, obj, id); 01438 }else if(!(flags & EXPR_NEWREF) && hres == DISP_E_UNKNOWNNAME) { 01439 exprval_init(ret); 01440 hres = S_OK; 01441 } 01442 01443 IDispatch_Release(obj); 01444 } 01445 01446 return hres; 01447 } 01448 01449 /* ECMA-262 3rd Edition 11.2.1 */ 01450 HRESULT member_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) 01451 { 01452 member_expression_t *expr = (member_expression_t*)_expr; 01453 IDispatch *obj = NULL; 01454 exprval_t exprval; 01455 VARIANT member; 01456 DISPID id; 01457 BSTR str; 01458 HRESULT hres; 01459 01460 TRACE("\n"); 01461 01462 hres = expr_eval(ctx, expr->expression, 0, ei, &exprval); 01463 if(FAILED(hres)) 01464 return hres; 01465 01466 hres = exprval_to_value(ctx->parser->script, &exprval, ei, &member); 01467 exprval_release(&exprval); 01468 if(FAILED(hres)) 01469 return hres; 01470 01471 hres = to_object(ctx->parser->script, &member, &obj); 01472 VariantClear(&member); 01473 if(FAILED(hres)) 01474 return hres; 01475 01476 str = SysAllocString(expr->identifier); 01477 if(flags & EXPR_STRREF) { 01478 ret->type = EXPRVAL_NAMEREF; 01479 ret->u.nameref.disp = obj; 01480 ret->u.nameref.name = str; 01481 return S_OK; 01482 } 01483 01484 hres = disp_get_id(ctx->parser->script, obj, str, flags & EXPR_NEWREF ? fdexNameEnsure : 0, &id); 01485 SysFreeString(str); 01486 if(SUCCEEDED(hres)) { 01487 exprval_set_idref(ret, obj, id); 01488 }else if(!(flags & EXPR_NEWREF) && hres == DISP_E_UNKNOWNNAME) { 01489 exprval_init(ret); 01490 hres = S_OK; 01491 } 01492 01493 IDispatch_Release(obj); 01494 return hres; 01495 } 01496 01497 static void free_dp(DISPPARAMS *dp) 01498 { 01499 DWORD i; 01500 01501 for(i=0; i < dp->cArgs; i++) 01502 VariantClear(dp->rgvarg+i); 01503 heap_free(dp->rgvarg); 01504 } 01505 01506 static HRESULT args_to_param(exec_ctx_t *ctx, argument_t *args, jsexcept_t *ei, DISPPARAMS *dp) 01507 { 01508 VARIANTARG *vargs; 01509 exprval_t exprval; 01510 argument_t *iter; 01511 DWORD cnt = 0, i; 01512 HRESULT hres = S_OK; 01513 01514 memset(dp, 0, sizeof(*dp)); 01515 if(!args) 01516 return S_OK; 01517 01518 for(iter = args; iter; iter = iter->next) 01519 cnt++; 01520 01521 vargs = heap_alloc_zero(cnt * sizeof(*vargs)); 01522 if(!vargs) 01523 return E_OUTOFMEMORY; 01524 01525 for(i = cnt, iter = args; iter; iter = iter->next) { 01526 hres = expr_eval(ctx, iter->expr, 0, ei, &exprval); 01527 if(FAILED(hres)) 01528 break; 01529 01530 hres = exprval_to_value(ctx->parser->script, &exprval, ei, vargs + (--i)); 01531 exprval_release(&exprval); 01532 if(FAILED(hres)) 01533 break; 01534 } 01535 01536 if(FAILED(hres)) { 01537 free_dp(dp); 01538 return hres; 01539 } 01540 01541 dp->rgvarg = vargs; 01542 dp->cArgs = cnt; 01543 return S_OK; 01544 } 01545 01546 /* ECMA-262 3rd Edition 11.2.2 */ 01547 HRESULT new_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) 01548 { 01549 call_expression_t *expr = (call_expression_t*)_expr; 01550 exprval_t exprval; 01551 VARIANT constr, var; 01552 DISPPARAMS dp; 01553 HRESULT hres; 01554 01555 TRACE("\n"); 01556 01557 hres = expr_eval(ctx, expr->expression, 0, ei, &exprval); 01558 if(FAILED(hres)) 01559 return hres; 01560 01561 hres = args_to_param(ctx, expr->argument_list, ei, &dp); 01562 if(SUCCEEDED(hres)) 01563 hres = exprval_to_value(ctx->parser->script, &exprval, ei, &constr); 01564 exprval_release(&exprval); 01565 if(FAILED(hres)) 01566 return hres; 01567 01568 if(V_VT(&constr) != VT_DISPATCH) { 01569 FIXME("throw TypeError\n"); 01570 VariantClear(&constr); 01571 return E_FAIL; 01572 } 01573 01574 hres = disp_call(ctx->parser->script, V_DISPATCH(&constr), DISPID_VALUE, 01575 DISPATCH_CONSTRUCT, &dp, &var, ei, NULL/*FIXME*/); 01576 IDispatch_Release(V_DISPATCH(&constr)); 01577 free_dp(&dp); 01578 if(FAILED(hres)) 01579 return hres; 01580 01581 ret->type = EXPRVAL_VARIANT; 01582 ret->u.var = var; 01583 return S_OK; 01584 } 01585 01586 /* ECMA-262 3rd Edition 11.2.3 */ 01587 HRESULT call_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) 01588 { 01589 call_expression_t *expr = (call_expression_t*)_expr; 01590 VARIANT var; 01591 exprval_t exprval; 01592 DISPPARAMS dp; 01593 HRESULT hres; 01594 01595 TRACE("\n"); 01596 01597 hres = expr_eval(ctx, expr->expression, 0, ei, &exprval); 01598 if(FAILED(hres)) 01599 return hres; 01600 01601 hres = args_to_param(ctx, expr->argument_list, ei, &dp); 01602 if(SUCCEEDED(hres)) { 01603 switch(exprval.type) { 01604 case EXPRVAL_VARIANT: 01605 if(V_VT(&exprval.u.var) == VT_DISPATCH) 01606 hres = disp_call(ctx->parser->script, V_DISPATCH(&exprval.u.var), DISPID_VALUE, 01607 DISPATCH_METHOD, &dp, flags & EXPR_NOVAL ? NULL : &var, ei, NULL/*FIXME*/); 01608 else 01609 hres = throw_type_error(ctx->parser->script, ei, IDS_NO_PROPERTY, NULL); 01610 break; 01611 case EXPRVAL_IDREF: 01612 hres = disp_call(ctx->parser->script, exprval.u.idref.disp, exprval.u.idref.id, 01613 DISPATCH_METHOD, &dp, flags & EXPR_NOVAL ? NULL : &var, ei, NULL/*FIXME*/); 01614 break; 01615 case EXPRVAL_INVALID: 01616 hres = throw_type_error(ctx->parser->script, ei, IDS_OBJECT_EXPECTED, NULL); 01617 break; 01618 default: 01619 FIXME("unimplemented type %d\n", exprval.type); 01620 hres = E_NOTIMPL; 01621 } 01622 01623 free_dp(&dp); 01624 } 01625 01626 exprval_release(&exprval); 01627 if(FAILED(hres)) 01628 return hres; 01629 01630 ret->type = EXPRVAL_VARIANT; 01631 if(flags & EXPR_NOVAL) { 01632 V_VT(&ret->u.var) = VT_EMPTY; 01633 }else { 01634 TRACE("= %s\n", debugstr_variant(&var)); 01635 ret->u.var = var; 01636 } 01637 return S_OK; 01638 } 01639 01640 /* ECMA-262 3rd Edition 11.1.1 */ 01641 HRESULT this_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) 01642 { 01643 TRACE("\n"); 01644 01645 ret->type = EXPRVAL_VARIANT; 01646 V_VT(&ret->u.var) = VT_DISPATCH; 01647 V_DISPATCH(&ret->u.var) = ctx->this_obj; 01648 IDispatch_AddRef(ctx->this_obj); 01649 return S_OK; 01650 } 01651 01652 /* ECMA-262 3rd Edition 10.1.4 */ 01653 HRESULT identifier_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) 01654 { 01655 identifier_expression_t *expr = (identifier_expression_t*)_expr; 01656 BSTR identifier; 01657 HRESULT hres; 01658 01659 TRACE("\n"); 01660 01661 identifier = SysAllocString(expr->identifier); 01662 if(!identifier) 01663 return E_OUTOFMEMORY; 01664 01665 hres = identifier_eval(ctx, identifier, flags, ei, ret); 01666 01667 SysFreeString(identifier); 01668 return hres; 01669 } 01670 01671 /* ECMA-262 3rd Edition 7.8 */ 01672 HRESULT literal_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) 01673 { 01674 literal_expression_t *expr = (literal_expression_t*)_expr; 01675 VARIANT var; 01676 HRESULT hres; 01677 01678 TRACE("\n"); 01679 01680 hres = literal_to_var(ctx->parser->script, expr->literal, &var); 01681 if(FAILED(hres)) 01682 return hres; 01683 01684 ret->type = EXPRVAL_VARIANT; 01685 ret->u.var = var; 01686 return S_OK; 01687 } 01688 01689 /* ECMA-262 3rd Edition 11.1.4 */ 01690 HRESULT array_literal_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) 01691 { 01692 array_literal_expression_t *expr = (array_literal_expression_t*)_expr; 01693 DWORD length = 0, i = 0; 01694 array_element_t *elem; 01695 DispatchEx *array; 01696 exprval_t exprval; 01697 VARIANT val; 01698 HRESULT hres; 01699 01700 TRACE("\n"); 01701 01702 for(elem = expr->element_list; elem; elem = elem->next) 01703 length += elem->elision+1; 01704 length += expr->length; 01705 01706 hres = create_array(ctx->parser->script, length, &array); 01707 if(FAILED(hres)) 01708 return hres; 01709 01710 for(elem = expr->element_list; elem; elem = elem->next) { 01711 i += elem->elision; 01712 01713 hres = expr_eval(ctx, elem->expr, 0, ei, &exprval); 01714 if(FAILED(hres)) 01715 break; 01716 01717 hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val); 01718 exprval_release(&exprval); 01719 if(FAILED(hres)) 01720 break; 01721 01722 hres = jsdisp_propput_idx(array, i, &val, ei, NULL/*FIXME*/); 01723 VariantClear(&val); 01724 if(FAILED(hres)) 01725 break; 01726 01727 i++; 01728 } 01729 01730 if(FAILED(hres)) { 01731 jsdisp_release(array); 01732 return hres; 01733 } 01734 01735 ret->type = EXPRVAL_VARIANT; 01736 V_VT(&ret->u.var) = VT_DISPATCH; 01737 V_DISPATCH(&ret->u.var) = (IDispatch*)_IDispatchEx_(array); 01738 return S_OK; 01739 } 01740 01741 /* ECMA-262 3rd Edition 11.1.5 */ 01742 HRESULT property_value_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) 01743 { 01744 property_value_expression_t *expr = (property_value_expression_t*)_expr; 01745 VARIANT val, tmp; 01746 DispatchEx *obj; 01747 prop_val_t *iter; 01748 exprval_t exprval; 01749 BSTR name; 01750 HRESULT hres; 01751 01752 TRACE("\n"); 01753 01754 hres = create_object(ctx->parser->script, NULL, &obj); 01755 if(FAILED(hres)) 01756 return hres; 01757 01758 for(iter = expr->property_list; iter; iter = iter->next) { 01759 hres = literal_to_var(ctx->parser->script, iter->name, &tmp); 01760 if(FAILED(hres)) 01761 break; 01762 01763 hres = to_string(ctx->parser->script, &tmp, ei, &name); 01764 VariantClear(&tmp); 01765 if(FAILED(hres)) 01766 break; 01767 01768 hres = expr_eval(ctx, iter->value, 0, ei, &exprval); 01769 if(SUCCEEDED(hres)) { 01770 hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val); 01771 exprval_release(&exprval); 01772 if(SUCCEEDED(hres)) { 01773 hres = jsdisp_propput_name(obj, name, &val, ei, NULL/*FIXME*/); 01774 VariantClear(&val); 01775 } 01776 } 01777 01778 SysFreeString(name); 01779 if(FAILED(hres)) 01780 break; 01781 } 01782 01783 if(FAILED(hres)) { 01784 jsdisp_release(obj); 01785 return hres; 01786 } 01787 01788 ret->type = EXPRVAL_VARIANT; 01789 V_VT(&ret->u.var) = VT_DISPATCH; 01790 V_DISPATCH(&ret->u.var) = (IDispatch*)_IDispatchEx_(obj); 01791 return S_OK; 01792 } 01793 01794 /* ECMA-262 3rd Edition 11.14 */ 01795 HRESULT comma_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) 01796 { 01797 binary_expression_t *expr = (binary_expression_t*)_expr; 01798 VARIANT lval, rval; 01799 HRESULT hres; 01800 01801 TRACE("\n"); 01802 01803 hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval); 01804 if(FAILED(hres)) 01805 return hres; 01806 01807 VariantClear(&lval); 01808 01809 ret->type = EXPRVAL_VARIANT; 01810 ret->u.var = rval; 01811 return S_OK; 01812 } 01813 01814 /* ECMA-262 3rd Edition 11.11 */ 01815 HRESULT logical_or_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) 01816 { 01817 binary_expression_t *expr = (binary_expression_t*)_expr; 01818 exprval_t exprval; 01819 VARIANT_BOOL b; 01820 VARIANT val; 01821 HRESULT hres; 01822 01823 TRACE("\n"); 01824 01825 hres = expr_eval(ctx, expr->expression1, 0, ei, &exprval); 01826 if(FAILED(hres)) 01827 return hres; 01828 01829 hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val); 01830 exprval_release(&exprval); 01831 if(FAILED(hres)) 01832 return hres; 01833 01834 hres = to_boolean(&val, &b); 01835 if(SUCCEEDED(hres) && b) { 01836 ret->type = EXPRVAL_VARIANT; 01837 ret->u.var = val; 01838 return S_OK; 01839 } 01840 01841 VariantClear(&val); 01842 if(FAILED(hres)) 01843 return hres; 01844 01845 hres = expr_eval(ctx, expr->expression2, 0, ei, &exprval); 01846 if(FAILED(hres)) 01847 return hres; 01848 01849 hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val); 01850 exprval_release(&exprval); 01851 if(FAILED(hres)) 01852 return hres; 01853 01854 ret->type = EXPRVAL_VARIANT; 01855 ret->u.var = val; 01856 return S_OK; 01857 } 01858 01859 /* ECMA-262 3rd Edition 11.11 */ 01860 HRESULT logical_and_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) 01861 { 01862 binary_expression_t *expr = (binary_expression_t*)_expr; 01863 exprval_t exprval; 01864 VARIANT_BOOL b; 01865 VARIANT val; 01866 HRESULT hres; 01867 01868 TRACE("\n"); 01869 01870 hres = expr_eval(ctx, expr->expression1, 0, ei, &exprval); 01871 if(FAILED(hres)) 01872 return hres; 01873 01874 hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val); 01875 exprval_release(&exprval); 01876 if(FAILED(hres)) 01877 return hres; 01878 01879 hres = to_boolean(&val, &b); 01880 if(SUCCEEDED(hres) && !b) { 01881 ret->type = EXPRVAL_VARIANT; 01882 ret->u.var = val; 01883 return S_OK; 01884 } 01885 01886 VariantClear(&val); 01887 if(FAILED(hres)) 01888 return hres; 01889 01890 hres = expr_eval(ctx, expr->expression2, 0, ei, &exprval); 01891 if(FAILED(hres)) 01892 return hres; 01893 01894 hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val); 01895 exprval_release(&exprval); 01896 if(FAILED(hres)) 01897 return hres; 01898 01899 ret->type = EXPRVAL_VARIANT; 01900 ret->u.var = val; 01901 return S_OK; 01902 } 01903 01904 /* ECMA-262 3rd Edition 11.10 */ 01905 static HRESULT bitor_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv) 01906 { 01907 INT li, ri; 01908 HRESULT hres; 01909 01910 hres = to_int32(ctx->parser->script, lval, ei, &li); 01911 if(FAILED(hres)) 01912 return hres; 01913 01914 hres = to_int32(ctx->parser->script, rval, ei, &ri); 01915 if(FAILED(hres)) 01916 return hres; 01917 01918 V_VT(retv) = VT_I4; 01919 V_I4(retv) = li|ri; 01920 return S_OK; 01921 } 01922 01923 /* ECMA-262 3rd Edition 11.10 */ 01924 HRESULT binary_or_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) 01925 { 01926 binary_expression_t *expr = (binary_expression_t*)_expr; 01927 01928 TRACE("\n"); 01929 01930 return binary_expr_eval(ctx, expr, bitor_eval, ei, ret); 01931 } 01932 01933 /* ECMA-262 3rd Edition 11.10 */ 01934 static HRESULT xor_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv) 01935 { 01936 INT li, ri; 01937 HRESULT hres; 01938 01939 hres = to_int32(ctx->parser->script, lval, ei, &li); 01940 if(FAILED(hres)) 01941 return hres; 01942 01943 hres = to_int32(ctx->parser->script, rval, ei, &ri); 01944 if(FAILED(hres)) 01945 return hres; 01946 01947 V_VT(retv) = VT_I4; 01948 V_I4(retv) = li^ri; 01949 return S_OK; 01950 } 01951 01952 /* ECMA-262 3rd Edition 11.10 */ 01953 HRESULT binary_xor_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) 01954 { 01955 binary_expression_t *expr = (binary_expression_t*)_expr; 01956 01957 TRACE("\n"); 01958 01959 return binary_expr_eval(ctx, expr, xor_eval, ei, ret); 01960 } 01961 01962 /* ECMA-262 3rd Edition 11.10 */ 01963 static HRESULT bitand_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv) 01964 { 01965 INT li, ri; 01966 HRESULT hres; 01967 01968 hres = to_int32(ctx->parser->script, lval, ei, &li); 01969 if(FAILED(hres)) 01970 return hres; 01971 01972 hres = to_int32(ctx->parser->script, rval, ei, &ri); 01973 if(FAILED(hres)) 01974 return hres; 01975 01976 V_VT(retv) = VT_I4; 01977 V_I4(retv) = li&ri; 01978 return S_OK; 01979 } 01980 01981 /* ECMA-262 3rd Edition 11.10 */ 01982 HRESULT binary_and_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) 01983 { 01984 binary_expression_t *expr = (binary_expression_t*)_expr; 01985 01986 TRACE("\n"); 01987 01988 return binary_expr_eval(ctx, expr, bitand_eval, ei, ret); 01989 } 01990 01991 /* ECMA-262 3rd Edition 11.8.6 */ 01992 static HRESULT instanceof_eval(exec_ctx_t *ctx, VARIANT *inst, VARIANT *objv, jsexcept_t *ei, VARIANT *retv) 01993 { 01994 DispatchEx *obj, *iter, *tmp = NULL; 01995 VARIANT_BOOL ret = VARIANT_FALSE; 01996 BOOL b; 01997 VARIANT var; 01998 HRESULT hres; 01999 02000 static const WCHAR prototypeW[] = {'p','r','o','t','o','t', 'y', 'p','e',0}; 02001 02002 if(V_VT(objv) != VT_DISPATCH) { 02003 FIXME("throw TypeError\n"); 02004 return E_FAIL; 02005 } 02006 02007 obj = iface_to_jsdisp((IUnknown*)V_DISPATCH(objv)); 02008 if(!obj) { 02009 FIXME("throw TypeError\n"); 02010 return E_FAIL; 02011 } 02012 02013 if(is_class(obj, JSCLASS_FUNCTION)) { 02014 hres = jsdisp_propget_name(obj, prototypeW, &var, ei, NULL/*FIXME*/); 02015 }else { 02016 FIXME("throw TypeError\n"); 02017 hres = E_FAIL; 02018 } 02019 jsdisp_release(obj); 02020 if(FAILED(hres)) 02021 return hres; 02022 02023 if(V_VT(&var) == VT_DISPATCH) { 02024 if(V_VT(inst) == VT_DISPATCH) 02025 tmp = iface_to_jsdisp((IUnknown*)V_DISPATCH(inst)); 02026 for(iter = tmp; iter; iter = iter->prototype) { 02027 hres = disp_cmp(V_DISPATCH(&var), (IDispatch*)_IDispatchEx_(iter), &b); 02028 if(FAILED(hres)) 02029 break; 02030 if(b) { 02031 ret = VARIANT_TRUE; 02032 break; 02033 } 02034 } 02035 02036 if(tmp) 02037 jsdisp_release(tmp); 02038 }else { 02039 FIXME("prototype is not an object\n"); 02040 hres = E_FAIL; 02041 } 02042 02043 VariantClear(&var); 02044 if(FAILED(hres)) 02045 return hres; 02046 02047 V_VT(retv) = VT_BOOL; 02048 V_BOOL(retv) = ret; 02049 return S_OK; 02050 } 02051 02052 /* ECMA-262 3rd Edition 11.8.6 */ 02053 HRESULT instanceof_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) 02054 { 02055 binary_expression_t *expr = (binary_expression_t*)_expr; 02056 02057 TRACE("\n"); 02058 02059 return binary_expr_eval(ctx, expr, instanceof_eval, ei, ret); 02060 } 02061 02062 /* ECMA-262 3rd Edition 11.8.7 */ 02063 static HRESULT in_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *obj, jsexcept_t *ei, VARIANT *retv) 02064 { 02065 VARIANT_BOOL ret; 02066 DISPID id; 02067 BSTR str; 02068 HRESULT hres; 02069 02070 if(V_VT(obj) != VT_DISPATCH) { 02071 FIXME("throw TypeError\n"); 02072 return E_FAIL; 02073 } 02074 02075 hres = to_string(ctx->parser->script, lval, ei, &str); 02076 if(FAILED(hres)) 02077 return hres; 02078 02079 hres = disp_get_id(ctx->parser->script, V_DISPATCH(obj), str, 0, &id); 02080 SysFreeString(str); 02081 if(SUCCEEDED(hres)) 02082 ret = VARIANT_TRUE; 02083 else if(hres == DISP_E_UNKNOWNNAME) 02084 ret = VARIANT_FALSE; 02085 else 02086 return hres; 02087 02088 V_VT(retv) = VT_BOOL; 02089 V_BOOL(retv) = ret; 02090 return S_OK; 02091 } 02092 02093 /* ECMA-262 3rd Edition 11.8.7 */ 02094 HRESULT in_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) 02095 { 02096 binary_expression_t *expr = (binary_expression_t*)_expr; 02097 02098 TRACE("\n"); 02099 02100 return binary_expr_eval(ctx, expr, in_eval, ei, ret); 02101 } 02102 02103 /* ECMA-262 3rd Edition 11.6.1 */ 02104 static HRESULT add_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv) 02105 { 02106 VARIANT r, l; 02107 HRESULT hres; 02108 02109 hres = to_primitive(ctx->parser->script, lval, ei, &l, NO_HINT); 02110 if(FAILED(hres)) 02111 return hres; 02112 02113 hres = to_primitive(ctx->parser->script, rval, ei, &r, NO_HINT); 02114 if(FAILED(hres)) { 02115 VariantClear(&l); 02116 return hres; 02117 } 02118 02119 if(V_VT(&l) == VT_BSTR || V_VT(&r) == VT_BSTR) { 02120 BSTR lstr = NULL, rstr = NULL; 02121 02122 if(V_VT(&l) == VT_BSTR) 02123 lstr = V_BSTR(&l); 02124 else 02125 hres = to_string(ctx->parser->script, &l, ei, &lstr); 02126 02127 if(SUCCEEDED(hres)) { 02128 if(V_VT(&r) == VT_BSTR) 02129 rstr = V_BSTR(&r); 02130 else 02131 hres = to_string(ctx->parser->script, &r, ei, &rstr); 02132 } 02133 02134 if(SUCCEEDED(hres)) { 02135 int len1, len2; 02136 02137 len1 = SysStringLen(lstr); 02138 len2 = SysStringLen(rstr); 02139 02140 V_VT(retv) = VT_BSTR; 02141 V_BSTR(retv) = SysAllocStringLen(NULL, len1+len2); 02142 memcpy(V_BSTR(retv), lstr, len1*sizeof(WCHAR)); 02143 memcpy(V_BSTR(retv)+len1, rstr, (len2+1)*sizeof(WCHAR)); 02144 } 02145 02146 if(V_VT(&l) != VT_BSTR) 02147 SysFreeString(lstr); 02148 if(V_VT(&r) != VT_BSTR) 02149 SysFreeString(rstr); 02150 }else { 02151 VARIANT nl, nr; 02152 02153 hres = to_number(ctx->parser->script, &l, ei, &nl); 02154 if(SUCCEEDED(hres)) { 02155 hres = to_number(ctx->parser->script, &r, ei, &nr); 02156 if(SUCCEEDED(hres)) 02157 num_set_val(retv, num_val(&nl) + num_val(&nr)); 02158 } 02159 } 02160 02161 VariantClear(&r); 02162 VariantClear(&l); 02163 return hres; 02164 } 02165 02166 /* ECMA-262 3rd Edition 11.6.1 */ 02167 HRESULT add_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) 02168 { 02169 binary_expression_t *expr = (binary_expression_t*)_expr; 02170 02171 TRACE("\n"); 02172 02173 return binary_expr_eval(ctx, expr, add_eval, ei, ret); 02174 } 02175 02176 /* ECMA-262 3rd Edition 11.6.2 */ 02177 static HRESULT sub_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv) 02178 { 02179 VARIANT lnum, rnum; 02180 HRESULT hres; 02181 02182 hres = to_number(ctx->parser->script, lval, ei, &lnum); 02183 if(FAILED(hres)) 02184 return hres; 02185 02186 hres = to_number(ctx->parser->script, rval, ei, &rnum); 02187 if(FAILED(hres)) 02188 return hres; 02189 02190 num_set_val(retv, num_val(&lnum) - num_val(&rnum)); 02191 return S_OK; 02192 } 02193 02194 /* ECMA-262 3rd Edition 11.6.2 */ 02195 HRESULT sub_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) 02196 { 02197 binary_expression_t *expr = (binary_expression_t*)_expr; 02198 02199 TRACE("\n"); 02200 02201 return binary_expr_eval(ctx, expr, sub_eval, ei, ret); 02202 } 02203 02204 /* ECMA-262 3rd Edition 11.5.1 */ 02205 static HRESULT mul_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv) 02206 { 02207 VARIANT lnum, rnum; 02208 HRESULT hres; 02209 02210 hres = to_number(ctx->parser->script, lval, ei, &lnum); 02211 if(FAILED(hres)) 02212 return hres; 02213 02214 hres = to_number(ctx->parser->script, rval, ei, &rnum); 02215 if(FAILED(hres)) 02216 return hres; 02217 02218 num_set_val(retv, num_val(&lnum) * num_val(&rnum)); 02219 return S_OK; 02220 } 02221 02222 /* ECMA-262 3rd Edition 11.5.1 */ 02223 HRESULT mul_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) 02224 { 02225 binary_expression_t *expr = (binary_expression_t*)_expr; 02226 02227 TRACE("\n"); 02228 02229 return binary_expr_eval(ctx, expr, mul_eval, ei, ret); 02230 } 02231 02232 /* ECMA-262 3rd Edition 11.5.2 */ 02233 static HRESULT div_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv) 02234 { 02235 VARIANT lnum, rnum; 02236 HRESULT hres; 02237 02238 hres = to_number(ctx->parser->script, lval, ei, &lnum); 02239 if(FAILED(hres)) 02240 return hres; 02241 02242 hres = to_number(ctx->parser->script, rval, ei, &rnum); 02243 if(FAILED(hres)) 02244 return hres; 02245 02246 num_set_val(retv, num_val(&lnum) / num_val(&rnum)); 02247 return S_OK; 02248 } 02249 02250 /* ECMA-262 3rd Edition 11.5.2 */ 02251 HRESULT div_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) 02252 { 02253 binary_expression_t *expr = (binary_expression_t*)_expr; 02254 02255 TRACE("\n"); 02256 02257 return binary_expr_eval(ctx, expr, div_eval, ei, ret); 02258 } 02259 02260 /* ECMA-262 3rd Edition 11.5.3 */ 02261 static HRESULT mod_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv) 02262 { 02263 VARIANT lnum, rnum; 02264 HRESULT hres; 02265 02266 hres = to_number(ctx->parser->script, lval, ei, &lnum); 02267 if(FAILED(hres)) 02268 return hres; 02269 02270 hres = to_number(ctx->parser->script, rval, ei, &rnum); 02271 if(FAILED(hres)) 02272 return hres; 02273 02274 num_set_val(retv, fmod(num_val(&lnum), num_val(&rnum))); 02275 return S_OK; 02276 } 02277 02278 /* ECMA-262 3rd Edition 11.5.3 */ 02279 HRESULT mod_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) 02280 { 02281 binary_expression_t *expr = (binary_expression_t*)_expr; 02282 02283 TRACE("\n"); 02284 02285 return binary_expr_eval(ctx, expr, mod_eval, ei, ret); 02286 } 02287 02288 /* ECMA-262 3rd Edition 11.4.2 */ 02289 HRESULT delete_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) 02290 { 02291 unary_expression_t *expr = (unary_expression_t*)_expr; 02292 VARIANT_BOOL b = VARIANT_FALSE; 02293 exprval_t exprval; 02294 HRESULT hres; 02295 02296 TRACE("\n"); 02297 02298 hres = expr_eval(ctx, expr->expression, EXPR_STRREF, ei, &exprval); 02299 if(FAILED(hres)) 02300 return hres; 02301 02302 switch(exprval.type) { 02303 case EXPRVAL_IDREF: { 02304 IDispatchEx *dispex; 02305 02306 hres = IDispatch_QueryInterface(exprval.u.nameref.disp, &IID_IDispatchEx, (void**)&dispex); 02307 if(SUCCEEDED(hres)) { 02308 hres = IDispatchEx_DeleteMemberByDispID(dispex, exprval.u.idref.id); 02309 b = VARIANT_TRUE; 02310 IDispatchEx_Release(dispex); 02311 } 02312 break; 02313 } 02314 case EXPRVAL_NAMEREF: { 02315 IDispatchEx *dispex; 02316 02317 hres = IDispatch_QueryInterface(exprval.u.nameref.disp, &IID_IDispatchEx, (void**)&dispex); 02318 if(SUCCEEDED(hres)) { 02319 hres = IDispatchEx_DeleteMemberByName(dispex, exprval.u.nameref.name, 02320 make_grfdex(ctx->parser->script, fdexNameCaseSensitive)); 02321 b = VARIANT_TRUE; 02322 IDispatchEx_Release(dispex); 02323 } 02324 break; 02325 } 02326 default: 02327 FIXME("unsupported type %d\n", exprval.type); 02328 hres = E_NOTIMPL; 02329 } 02330 02331 exprval_release(&exprval); 02332 if(FAILED(hres)) 02333 return hres; 02334 02335 return return_bool(ret, b); 02336 } 02337 02338 /* ECMA-262 3rd Edition 11.4.2 */ 02339 HRESULT void_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) 02340 { 02341 unary_expression_t *expr = (unary_expression_t*)_expr; 02342 exprval_t exprval; 02343 VARIANT tmp; 02344 HRESULT hres; 02345 02346 TRACE("\n"); 02347 02348 hres = expr_eval(ctx, expr->expression, 0, ei, &exprval); 02349 if(FAILED(hres)) 02350 return hres; 02351 02352 hres = exprval_to_value(ctx->parser->script, &exprval, ei, &tmp); 02353 exprval_release(&exprval); 02354 if(FAILED(hres)) 02355 return hres; 02356 02357 VariantClear(&tmp); 02358 02359 ret->type = EXPRVAL_VARIANT; 02360 V_VT(&ret->u.var) = VT_EMPTY; 02361 return S_OK; 02362 } 02363 02364 /* ECMA-262 3rd Edition 11.4.3 */ 02365 static HRESULT typeof_exprval(exec_ctx_t *ctx, exprval_t *exprval, jsexcept_t *ei, const WCHAR **ret) 02366 { 02367 VARIANT val; 02368 HRESULT hres; 02369 02370 static const WCHAR booleanW[] = {'b','o','o','l','e','a','n',0}; 02371 static const WCHAR functionW[] = {'f','u','n','c','t','i','o','n',0}; 02372 static const WCHAR numberW[] = {'n','u','m','b','e','r',0}; 02373 static const WCHAR objectW[] = {'o','b','j','e','c','t',0}; 02374 static const WCHAR stringW[] = {'s','t','r','i','n','g',0}; 02375 static const WCHAR undefinedW[] = {'u','n','d','e','f','i','n','e','d',0}; 02376 02377 if(exprval->type == EXPRVAL_INVALID) { 02378 *ret = undefinedW; 02379 return S_OK; 02380 } 02381 02382 hres = exprval_to_value(ctx->parser->script, exprval, ei, &val); 02383 if(FAILED(hres)) 02384 return hres; 02385 02386 switch(V_VT(&val)) { 02387 case VT_EMPTY: 02388 *ret = undefinedW; 02389 break; 02390 case VT_NULL: 02391 *ret = objectW; 02392 break; 02393 case VT_BOOL: 02394 *ret = booleanW; 02395 break; 02396 case VT_I4: 02397 case VT_R8: 02398 *ret = numberW; 02399 break; 02400 case VT_BSTR: 02401 *ret = stringW; 02402 break; 02403 case VT_DISPATCH: { 02404 DispatchEx *dispex; 02405 02406 if(V_DISPATCH(&val) && (dispex = iface_to_jsdisp((IUnknown*)V_DISPATCH(&val)))) { 02407 *ret = is_class(dispex, JSCLASS_FUNCTION) ? functionW : objectW; 02408 jsdisp_release(dispex); 02409 }else { 02410 *ret = objectW; 02411 } 02412 break; 02413 } 02414 default: 02415 FIXME("unhandled vt %d\n", V_VT(&val)); 02416 hres = E_NOTIMPL; 02417 } 02418 02419 VariantClear(&val); 02420 return S_OK; 02421 } 02422 02423 HRESULT typeof_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) 02424 { 02425 unary_expression_t *expr = (unary_expression_t*)_expr; 02426 const WCHAR *str = NULL; 02427 exprval_t exprval; 02428 HRESULT hres; 02429 02430 TRACE("\n"); 02431 02432 hres = expr_eval(ctx, expr->expression, 0, ei, &exprval); 02433 if(FAILED(hres)) 02434 return hres; 02435 02436 hres = typeof_exprval(ctx, &exprval, ei, &str); 02437 exprval_release(&exprval); 02438 if(FAILED(hres)) 02439 return hres; 02440 02441 ret->type = EXPRVAL_VARIANT; 02442 V_VT(&ret->u.var) = VT_BSTR; 02443 V_BSTR(&ret->u.var) = SysAllocString(str); 02444 if(!V_BSTR(&ret->u.var)) 02445 return E_OUTOFMEMORY; 02446 02447 return S_OK; 02448 } 02449 02450 /* ECMA-262 3rd Edition 11.4.7 */ 02451 HRESULT minus_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) 02452 { 02453 unary_expression_t *expr = (unary_expression_t*)_expr; 02454 exprval_t exprval; 02455 VARIANT val, num; 02456 HRESULT hres; 02457 02458 TRACE("\n"); 02459 02460 hres = expr_eval(ctx, expr->expression, 0, ei, &exprval); 02461 if(FAILED(hres)) 02462 return hres; 02463 02464 hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val); 02465 exprval_release(&exprval); 02466 if(FAILED(hres)) 02467 return hres; 02468 02469 hres = to_number(ctx->parser->script, &val, ei, &num); 02470 VariantClear(&val); 02471 if(FAILED(hres)) 02472 return hres; 02473 02474 ret->type = EXPRVAL_VARIANT; 02475 num_set_val(&ret->u.var, -num_val(&num)); 02476 return S_OK; 02477 } 02478 02479 /* ECMA-262 3rd Edition 11.4.6 */ 02480 HRESULT plus_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) 02481 { 02482 unary_expression_t *expr = (unary_expression_t*)_expr; 02483 exprval_t exprval; 02484 VARIANT val, num; 02485 HRESULT hres; 02486 02487 TRACE("\n"); 02488 02489 hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval); 02490 if(FAILED(hres)) 02491 return hres; 02492 02493 hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val); 02494 exprval_release(&exprval); 02495 if(FAILED(hres)) 02496 return hres; 02497 02498 hres = to_number(ctx->parser->script, &val, ei, &num); 02499 VariantClear(&val); 02500 if(FAILED(hres)) 02501 return hres; 02502 02503 ret->type = EXPRVAL_VARIANT; 02504 ret->u.var = num; 02505 return S_OK; 02506 } 02507 02508 /* ECMA-262 3rd Edition 11.3.1 */ 02509 HRESULT post_increment_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) 02510 { 02511 unary_expression_t *expr = (unary_expression_t*)_expr; 02512 VARIANT val, num; 02513 exprval_t exprval; 02514 HRESULT hres; 02515 02516 TRACE("\n"); 02517 02518 hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval); 02519 if(FAILED(hres)) 02520 return hres; 02521 02522 hres = exprval_value(ctx->parser->script, &exprval, ei, &val); 02523 if(SUCCEEDED(hres)) { 02524 hres = to_number(ctx->parser->script, &val, ei, &num); 02525 VariantClear(&val); 02526 } 02527 02528 if(SUCCEEDED(hres)) { 02529 VARIANT inc; 02530 num_set_val(&inc, num_val(&num)+1.0); 02531 hres = put_value(ctx->parser->script, &exprval, &inc, ei); 02532 } 02533 02534 exprval_release(&exprval); 02535 if(FAILED(hres)) 02536 return hres; 02537 02538 ret->type = EXPRVAL_VARIANT; 02539 ret->u.var = num; 02540 return S_OK; 02541 } 02542 02543 /* ECMA-262 3rd Edition 11.3.2 */ 02544 HRESULT post_decrement_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) 02545 { 02546 unary_expression_t *expr = (unary_expression_t*)_expr; 02547 VARIANT val, num; 02548 exprval_t exprval; 02549 HRESULT hres; 02550 02551 TRACE("\n"); 02552 02553 hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval); 02554 if(FAILED(hres)) 02555 return hres; 02556 02557 hres = exprval_value(ctx->parser->script, &exprval, ei, &val); 02558 if(SUCCEEDED(hres)) { 02559 hres = to_number(ctx->parser->script, &val, ei, &num); 02560 VariantClear(&val); 02561 } 02562 02563 if(SUCCEEDED(hres)) { 02564 VARIANT dec; 02565 num_set_val(&dec, num_val(&num)-1.0); 02566 hres = put_value(ctx->parser->script, &exprval, &dec, ei); 02567 } 02568 02569 exprval_release(&exprval); 02570 if(FAILED(hres)) 02571 return hres; 02572 02573 ret->type = EXPRVAL_VARIANT; 02574 ret->u.var = num; 02575 return S_OK; 02576 } 02577 02578 /* ECMA-262 3rd Edition 11.4.4 */ 02579 HRESULT pre_increment_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) 02580 { 02581 unary_expression_t *expr = (unary_expression_t*)_expr; 02582 VARIANT val, num; 02583 exprval_t exprval; 02584 HRESULT hres; 02585 02586 TRACE("\n"); 02587 02588 hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval); 02589 if(FAILED(hres)) 02590 return hres; 02591 02592 hres = exprval_value(ctx->parser->script, &exprval, ei, &val); 02593 if(SUCCEEDED(hres)) { 02594 hres = to_number(ctx->parser->script, &val, ei, &num); 02595 VariantClear(&val); 02596 } 02597 02598 if(SUCCEEDED(hres)) { 02599 num_set_val(&val, num_val(&num)+1.0); 02600 hres = put_value(ctx->parser->script, &exprval, &val, ei); 02601 } 02602 02603 exprval_release(&exprval); 02604 if(FAILED(hres)) 02605 return hres; 02606 02607 ret->type = EXPRVAL_VARIANT; 02608 ret->u.var = val; 02609 return S_OK; 02610 } 02611 02612 /* ECMA-262 3rd Edition 11.4.5 */ 02613 HRESULT pre_decrement_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) 02614 { 02615 unary_expression_t *expr = (unary_expression_t*)_expr; 02616 VARIANT val, num; 02617 exprval_t exprval; 02618 HRESULT hres; 02619 02620 TRACE("\n"); 02621 02622 hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval); 02623 if(FAILED(hres)) 02624 return hres; 02625 02626 hres = exprval_value(ctx->parser->script, &exprval, ei, &val); 02627 if(SUCCEEDED(hres)) { 02628 hres = to_number(ctx->parser->script, &val, ei, &num); 02629 VariantClear(&val); 02630 } 02631 02632 if(SUCCEEDED(hres)) { 02633 num_set_val(&val, num_val(&num)-1.0); 02634 hres = put_value(ctx->parser->script, &exprval, &val, ei); 02635 } 02636 02637 exprval_release(&exprval); 02638 if(FAILED(hres)) 02639 return hres; 02640 02641 ret->type = EXPRVAL_VARIANT; 02642 ret->u.var = val; 02643 return S_OK; 02644 } 02645 02646 /* ECMA-262 3rd Edition 11.9.3 */ 02647 static HRESULT equal_values(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, BOOL *ret) 02648 { 02649 if(V_VT(lval) == V_VT(rval) || (is_num_vt(V_VT(lval)) && is_num_vt(V_VT(rval)))) 02650 return equal2_values(lval, rval, ret); 02651 02652 /* FIXME: NULL disps should be handled in more general way */ 02653 if(V_VT(lval) == VT_DISPATCH && !V_DISPATCH(lval)) { 02654 VARIANT v; 02655 V_VT(&v) = VT_NULL; 02656 return equal_values(ctx, &v, rval, ei, ret); 02657 } 02658 02659 if(V_VT(rval) == VT_DISPATCH && !V_DISPATCH(rval)) { 02660 VARIANT v; 02661 V_VT(&v) = VT_NULL; 02662 return equal_values(ctx, lval, &v, ei, ret); 02663 } 02664 02665 if((V_VT(lval) == VT_NULL && V_VT(rval) == VT_EMPTY) || 02666 (V_VT(lval) == VT_EMPTY && V_VT(rval) == VT_NULL)) { 02667 *ret = TRUE; 02668 return S_OK; 02669 } 02670 02671 if(V_VT(lval) == VT_BSTR && is_num_vt(V_VT(rval))) { 02672 VARIANT v; 02673 HRESULT hres; 02674 02675 hres = to_number(ctx->parser->script, lval, ei, &v); 02676 if(FAILED(hres)) 02677 return hres; 02678 02679 return equal_values(ctx, &v, rval, ei, ret); 02680 } 02681 02682 if(V_VT(rval) == VT_BSTR && is_num_vt(V_VT(lval))) { 02683 VARIANT v; 02684 HRESULT hres; 02685 02686 hres = to_number(ctx->parser->script, rval, ei, &v); 02687 if(FAILED(hres)) 02688 return hres; 02689 02690 return equal_values(ctx, lval, &v, ei, ret); 02691 } 02692 02693 if(V_VT(rval) == VT_BOOL) { 02694 VARIANT v; 02695 02696 V_VT(&v) = VT_I4; 02697 V_I4(&v) = V_BOOL(rval) ? 1 : 0; 02698 return equal_values(ctx, lval, &v, ei, ret); 02699 } 02700 02701 if(V_VT(lval) == VT_BOOL) { 02702 VARIANT v; 02703 02704 V_VT(&v) = VT_I4; 02705 V_I4(&v) = V_BOOL(lval) ? 1 : 0; 02706 return equal_values(ctx, &v, rval, ei, ret); 02707 } 02708 02709 02710 if(V_VT(rval) == VT_DISPATCH && (V_VT(lval) == VT_BSTR || is_num_vt(V_VT(lval)))) { 02711 VARIANT v; 02712 HRESULT hres; 02713 02714 hres = to_primitive(ctx->parser->script, rval, ei, &v, NO_HINT); 02715 if(FAILED(hres)) 02716 return hres; 02717 02718 hres = equal_values(ctx, lval, &v, ei, ret); 02719 02720 VariantClear(&v); 02721 return hres; 02722 } 02723 02724 02725 if(V_VT(lval) == VT_DISPATCH && (V_VT(rval) == VT_BSTR || is_num_vt(V_VT(rval)))) { 02726 VARIANT v; 02727 HRESULT hres; 02728 02729 hres = to_primitive(ctx->parser->script, lval, ei, &v, NO_HINT); 02730 if(FAILED(hres)) 02731 return hres; 02732 02733 hres = equal_values(ctx, &v, rval, ei, ret); 02734 02735 VariantClear(&v); 02736 return hres; 02737 } 02738 02739 02740 *ret = FALSE; 02741 return S_OK; 02742 } 02743 02744 /* ECMA-262 3rd Edition 11.9.1 */ 02745 HRESULT equal_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) 02746 { 02747 binary_expression_t *expr = (binary_expression_t*)_expr; 02748 VARIANT rval, lval; 02749 BOOL b; 02750 HRESULT hres; 02751 02752 TRACE("\n"); 02753 02754 hres = get_binary_expr_values(ctx, expr, ei, &rval, &lval); 02755 if(FAILED(hres)) 02756 return hres; 02757 02758 hres = equal_values(ctx, &rval, &lval, ei, &b); 02759 VariantClear(&lval); 02760 VariantClear(&rval); 02761 if(FAILED(hres)) 02762 return hres; 02763 02764 return return_bool(ret, b); 02765 } 02766 02767 /* ECMA-262 3rd Edition 11.9.4 */ 02768 HRESULT equal2_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) 02769 { 02770 binary_expression_t *expr = (binary_expression_t*)_expr; 02771 VARIANT rval, lval; 02772 BOOL b; 02773 HRESULT hres; 02774 02775 TRACE("\n"); 02776 02777 hres = get_binary_expr_values(ctx, expr, ei, &rval, &lval); 02778 if(FAILED(hres)) 02779 return hres; 02780 02781 hres = equal2_values(&rval, &lval, &b); 02782 VariantClear(&lval); 02783 VariantClear(&rval); 02784 if(FAILED(hres)) 02785 return hres; 02786 02787 return return_bool(ret, b); 02788 } 02789 02790 /* ECMA-262 3rd Edition 11.9.2 */ 02791 HRESULT not_equal_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) 02792 { 02793 binary_expression_t *expr = (binary_expression_t*)_expr; 02794 VARIANT rval, lval; 02795 BOOL b; 02796 HRESULT hres; 02797 02798 TRACE("\n"); 02799 02800 hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval); 02801 if(FAILED(hres)) 02802 return hres; 02803 02804 hres = equal_values(ctx, &lval, &rval, ei, &b); 02805 VariantClear(&lval); 02806 VariantClear(&rval); 02807 if(FAILED(hres)) 02808 return hres; 02809 02810 return return_bool(ret, !b); 02811 } 02812 02813 /* ECMA-262 3rd Edition 11.9.5 */ 02814 HRESULT not_equal2_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) 02815 { 02816 binary_expression_t *expr = (binary_expression_t*)_expr; 02817 VARIANT rval, lval; 02818 BOOL b; 02819 HRESULT hres; 02820 02821 TRACE("\n"); 02822 02823 hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval); 02824 if(FAILED(hres)) 02825 return hres; 02826 02827 hres = equal2_values(&lval, &rval, &b); 02828 VariantClear(&lval); 02829 VariantClear(&rval); 02830 if(FAILED(hres)) 02831 return hres; 02832 02833 return return_bool(ret, !b); 02834 } 02835 02836 /* ECMA-262 3rd Edition 11.8.5 */ 02837 static HRESULT less_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, BOOL greater, jsexcept_t *ei, BOOL *ret) 02838 { 02839 VARIANT l, r, ln, rn; 02840 HRESULT hres; 02841 02842 hres = to_primitive(ctx->parser->script, lval, ei, &l, NO_HINT); 02843 if(FAILED(hres)) 02844 return hres; 02845 02846 hres = to_primitive(ctx->parser->script, rval, ei, &r, NO_HINT); 02847 if(FAILED(hres)) { 02848 VariantClear(&l); 02849 return hres; 02850 } 02851 02852 if(V_VT(&l) == VT_BSTR && V_VT(&r) == VT_BSTR) { 02853 *ret = (strcmpW(V_BSTR(&l), V_BSTR(&r)) < 0) ^ greater; 02854 SysFreeString(V_BSTR(&l)); 02855 SysFreeString(V_BSTR(&r)); 02856 return S_OK; 02857 } 02858 02859 hres = to_number(ctx->parser->script, &l, ei, &ln); 02860 VariantClear(&l); 02861 if(SUCCEEDED(hres)) 02862 hres = to_number(ctx->parser->script, &r, ei, &rn); 02863 VariantClear(&r); 02864 if(FAILED(hres)) 02865 return hres; 02866 02867 if(V_VT(&ln) == VT_I4 && V_VT(&rn) == VT_I4) { 02868 *ret = (V_I4(&ln) < V_I4(&rn)) ^ greater; 02869 }else { 02870 DOUBLE ld = num_val(&ln); 02871 DOUBLE rd = num_val(&rn); 02872 02873 *ret = !isnan(ld) && !isnan(rd) && ((ld < rd) ^ greater); 02874 } 02875 02876 return S_OK; 02877 } 02878 02879 /* ECMA-262 3rd Edition 11.8.1 */ 02880 HRESULT less_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) 02881 { 02882 binary_expression_t *expr = (binary_expression_t*)_expr; 02883 VARIANT rval, lval; 02884 BOOL b; 02885 HRESULT hres; 02886 02887 TRACE("\n"); 02888 02889 hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval); 02890 if(FAILED(hres)) 02891 return hres; 02892 02893 hres = less_eval(ctx, &lval, &rval, FALSE, ei, &b); 02894 VariantClear(&lval); 02895 VariantClear(&rval); 02896 if(FAILED(hres)) 02897 return hres; 02898 02899 return return_bool(ret, b); 02900 } 02901 02902 /* ECMA-262 3rd Edition 11.8.3 */ 02903 HRESULT lesseq_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) 02904 { 02905 binary_expression_t *expr = (binary_expression_t*)_expr; 02906 VARIANT rval, lval; 02907 BOOL b; 02908 HRESULT hres; 02909 02910 TRACE("\n"); 02911 02912 hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval); 02913 if(FAILED(hres)) 02914 return hres; 02915 02916 hres = less_eval(ctx, &rval, &lval, TRUE, ei, &b); 02917 VariantClear(&lval); 02918 VariantClear(&rval); 02919 if(FAILED(hres)) 02920 return hres; 02921 02922 return return_bool(ret, b); 02923 } 02924 02925 /* ECMA-262 3rd Edition 11.8.2 */ 02926 HRESULT greater_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) 02927 { 02928 binary_expression_t *expr = (binary_expression_t*)_expr; 02929 VARIANT rval, lval; 02930 BOOL b; 02931 HRESULT hres; 02932 02933 TRACE("\n"); 02934 02935 hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval); 02936 if(FAILED(hres)) 02937 return hres; 02938 02939 hres = less_eval(ctx, &rval, &lval, FALSE, ei, &b); 02940 VariantClear(&lval); 02941 VariantClear(&rval); 02942 if(FAILED(hres)) 02943 return hres; 02944 02945 return return_bool(ret, b); 02946 } 02947 02948 /* ECMA-262 3rd Edition 11.8.4 */ 02949 HRESULT greatereq_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) 02950 { 02951 binary_expression_t *expr = (binary_expression_t*)_expr; 02952 VARIANT rval, lval; 02953 BOOL b; 02954 HRESULT hres; 02955 02956 TRACE("\n"); 02957 02958 hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval); 02959 if(FAILED(hres)) 02960 return hres; 02961 02962 hres = less_eval(ctx, &lval, &rval, TRUE, ei, &b); 02963 VariantClear(&lval); 02964 VariantClear(&rval); 02965 if(FAILED(hres)) 02966 return hres; 02967 02968 return return_bool(ret, b); 02969 } 02970 02971 /* ECMA-262 3rd Edition 11.4.8 */ 02972 HRESULT binary_negation_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) 02973 { 02974 unary_expression_t *expr = (unary_expression_t*)_expr; 02975 exprval_t exprval; 02976 VARIANT val; 02977 INT i; 02978 HRESULT hres; 02979 02980 TRACE("\n"); 02981 02982 hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval); 02983 if(FAILED(hres)) 02984 return hres; 02985 02986 hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val); 02987 exprval_release(&exprval); 02988 if(FAILED(hres)) 02989 return hres; 02990 02991 hres = to_int32(ctx->parser->script, &val, ei, &i); 02992 if(FAILED(hres)) 02993 return hres; 02994 02995 ret->type = EXPRVAL_VARIANT; 02996 V_VT(&ret->u.var) = VT_I4; 02997 V_I4(&ret->u.var) = ~i; 02998 return S_OK; 02999 } 03000 03001 /* ECMA-262 3rd Edition 11.4.9 */ 03002 HRESULT logical_negation_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) 03003 { 03004 unary_expression_t *expr = (unary_expression_t*)_expr; 03005 exprval_t exprval; 03006 VARIANT_BOOL b; 03007 HRESULT hres; 03008 03009 TRACE("\n"); 03010 03011 hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval); 03012 if(FAILED(hres)) 03013 return hres; 03014 03015 hres = exprval_to_boolean(ctx->parser->script, &exprval, ei, &b); 03016 exprval_release(&exprval); 03017 if(FAILED(hres)) 03018 return hres; 03019 03020 return return_bool(ret, !b); 03021 } 03022 03023 /* ECMA-262 3rd Edition 11.7.1 */ 03024 static HRESULT lshift_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv) 03025 { 03026 DWORD ri; 03027 INT li; 03028 HRESULT hres; 03029 03030 hres = to_int32(ctx->parser->script, lval, ei, &li); 03031 if(FAILED(hres)) 03032 return hres; 03033 03034 hres = to_uint32(ctx->parser->script, rval, ei, &ri); 03035 if(FAILED(hres)) 03036 return hres; 03037 03038 V_VT(retv) = VT_I4; 03039 V_I4(retv) = li << (ri&0x1f); 03040 return S_OK; 03041 } 03042 03043 /* ECMA-262 3rd Edition 11.7.1 */ 03044 HRESULT left_shift_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) 03045 { 03046 binary_expression_t *expr = (binary_expression_t*)_expr; 03047 03048 TRACE("\n"); 03049 03050 return binary_expr_eval(ctx, expr, lshift_eval, ei, ret); 03051 } 03052 03053 /* ECMA-262 3rd Edition 11.7.2 */ 03054 static HRESULT rshift_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv) 03055 { 03056 DWORD ri; 03057 INT li; 03058 HRESULT hres; 03059 03060 hres = to_int32(ctx->parser->script, lval, ei, &li); 03061 if(FAILED(hres)) 03062 return hres; 03063 03064 hres = to_uint32(ctx->parser->script, rval, ei, &ri); 03065 if(FAILED(hres)) 03066 return hres; 03067 03068 V_VT(retv) = VT_I4; 03069 V_I4(retv) = li >> (ri&0x1f); 03070 return S_OK; 03071 } 03072 03073 /* ECMA-262 3rd Edition 11.7.2 */ 03074 HRESULT right_shift_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) 03075 { 03076 binary_expression_t *expr = (binary_expression_t*)_expr; 03077 03078 TRACE("\n"); 03079 03080 return binary_expr_eval(ctx, expr, rshift_eval, ei, ret); 03081 } 03082 03083 /* ECMA-262 3rd Edition 11.7.3 */ 03084 static HRESULT rshift2_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_t *ei, VARIANT *retv) 03085 { 03086 DWORD li, ri; 03087 HRESULT hres; 03088 03089 hres = to_uint32(ctx->parser->script, lval, ei, &li); 03090 if(FAILED(hres)) 03091 return hres; 03092 03093 hres = to_uint32(ctx->parser->script, rval, ei, &ri); 03094 if(FAILED(hres)) 03095 return hres; 03096 03097 V_VT(retv) = VT_I4; 03098 V_I4(retv) = li >> (ri&0x1f); 03099 return S_OK; 03100 } 03101 03102 /* ECMA-262 3rd Edition 11.7.3 */ 03103 HRESULT right2_shift_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) 03104 { 03105 binary_expression_t *expr = (binary_expression_t*)_expr; 03106 03107 TRACE("\n"); 03108 03109 return binary_expr_eval(ctx, expr, rshift2_eval, ei, ret); 03110 } 03111 03112 /* ECMA-262 3rd Edition 11.13.1 */ 03113 HRESULT assign_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) 03114 { 03115 binary_expression_t *expr = (binary_expression_t*)_expr; 03116 exprval_t exprval, exprvalr; 03117 VARIANT rval; 03118 HRESULT hres; 03119 03120 TRACE("\n"); 03121 03122 hres = expr_eval(ctx, expr->expression1, EXPR_NEWREF, ei, &exprval); 03123 if(FAILED(hres)) 03124 return hres; 03125 03126 hres = expr_eval(ctx, expr->expression2, 0, ei, &exprvalr); 03127 if(SUCCEEDED(hres)) { 03128 hres = exprval_to_value(ctx->parser->script, &exprvalr, ei, &rval); 03129 exprval_release(&exprvalr); 03130 } 03131 03132 if(SUCCEEDED(hres)) { 03133 hres = put_value(ctx->parser->script, &exprval, &rval, ei); 03134 if(FAILED(hres)) 03135 VariantClear(&rval); 03136 } 03137 03138 exprval_release(&exprval); 03139 if(FAILED(hres)) 03140 return hres; 03141 03142 ret->type = EXPRVAL_VARIANT; 03143 ret->u.var = rval; 03144 return S_OK; 03145 } 03146 03147 /* ECMA-262 3rd Edition 11.13.2 */ 03148 HRESULT assign_lshift_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) 03149 { 03150 binary_expression_t *expr = (binary_expression_t*)_expr; 03151 03152 TRACE("\n"); 03153 03154 return assign_oper_eval(ctx, expr->expression1, expr->expression2, lshift_eval, ei, ret); 03155 } 03156 03157 /* ECMA-262 3rd Edition 11.13.2 */ 03158 HRESULT assign_rshift_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) 03159 { 03160 binary_expression_t *expr = (binary_expression_t*)_expr; 03161 03162 TRACE("\n"); 03163 03164 return assign_oper_eval(ctx, expr->expression1, expr->expression2, rshift_eval, ei, ret); 03165 } 03166 03167 /* ECMA-262 3rd Edition 11.13.2 */ 03168 HRESULT assign_rrshift_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) 03169 { 03170 binary_expression_t *expr = (binary_expression_t*)_expr; 03171 03172 TRACE("\n"); 03173 03174 return assign_oper_eval(ctx, expr->expression1, expr->expression2, rshift2_eval, ei, ret); 03175 } 03176 03177 /* ECMA-262 3rd Edition 11.13.2 */ 03178 HRESULT assign_add_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) 03179 { 03180 binary_expression_t *expr = (binary_expression_t*)_expr; 03181 03182 TRACE("\n"); 03183 03184 return assign_oper_eval(ctx, expr->expression1, expr->expression2, add_eval, ei, ret); 03185 } 03186 03187 /* ECMA-262 3rd Edition 11.13.2 */ 03188 HRESULT assign_sub_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) 03189 { 03190 binary_expression_t *expr = (binary_expression_t*)_expr; 03191 03192 TRACE("\n"); 03193 03194 return assign_oper_eval(ctx, expr->expression1, expr->expression2, sub_eval, ei, ret); 03195 } 03196 03197 /* ECMA-262 3rd Edition 11.13.2 */ 03198 HRESULT assign_mul_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) 03199 { 03200 binary_expression_t *expr = (binary_expression_t*)_expr; 03201 03202 TRACE("\n"); 03203 03204 return assign_oper_eval(ctx, expr->expression1, expr->expression2, mul_eval, ei, ret); 03205 } 03206 03207 /* ECMA-262 3rd Edition 11.13.2 */ 03208 HRESULT assign_div_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) 03209 { 03210 binary_expression_t *expr = (binary_expression_t*)_expr; 03211 03212 TRACE("\n"); 03213 03214 return assign_oper_eval(ctx, expr->expression1, expr->expression2, div_eval, ei, ret); 03215 } 03216 03217 /* ECMA-262 3rd Edition 11.13.2 */ 03218 HRESULT assign_mod_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) 03219 { 03220 binary_expression_t *expr = (binary_expression_t*)_expr; 03221 03222 TRACE("\n"); 03223 03224 return assign_oper_eval(ctx, expr->expression1, expr->expression2, mod_eval, ei, ret); 03225 } 03226 03227 /* ECMA-262 3rd Edition 11.13.2 */ 03228 HRESULT assign_and_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) 03229 { 03230 binary_expression_t *expr = (binary_expression_t*)_expr; 03231 03232 TRACE("\n"); 03233 03234 return assign_oper_eval(ctx, expr->expression1, expr->expression2, bitand_eval, ei, ret); 03235 } 03236 03237 /* ECMA-262 3rd Edition 11.13.2 */ 03238 HRESULT assign_or_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) 03239 { 03240 binary_expression_t *expr = (binary_expression_t*)_expr; 03241 03242 TRACE("\n"); 03243 03244 return assign_oper_eval(ctx, expr->expression1, expr->expression2, bitor_eval, ei, ret); 03245 } 03246 03247 /* ECMA-262 3rd Edition 11.13.2 */ 03248 HRESULT assign_xor_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) 03249 { 03250 binary_expression_t *expr = (binary_expression_t*)_expr; 03251 03252 TRACE("\n"); 03253 03254 return assign_oper_eval(ctx, expr->expression1, expr->expression2, xor_eval, ei, ret); 03255 } Generated on Sun May 27 2012 04:24:20 for ReactOS by
1.7.6.1
|