ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

engine.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, &regexp);
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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.