From 512505f9085781521c2e6693dde5e3d4bfbfee0d Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Tue, 9 Sep 2008 01:23:21 +0200 Subject: [PATCH] jscript: Added assign expression implementation. --- dlls/jscript/dispex.c | 36 ++++++++++++++++++++++++++++++++++++ dlls/jscript/engine.c | 45 ++++++++++++++++++++++++++++++++++++++++++--- dlls/jscript/jscript.h | 1 + 3 files changed, 79 insertions(+), 3 deletions(-) diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c index f27965500e6..5286b615731 100644 --- a/dlls/jscript/dispex.c +++ b/dlls/jscript/dispex.c @@ -838,6 +838,42 @@ HRESULT disp_call(IDispatch *disp, DISPID id, LCID lcid, WORD flags, DISPPARAMS return hres; } +HRESULT disp_propput(IDispatch *disp, DISPID id, LCID lcid, VARIANT *val, jsexcept_t *ei, IServiceProvider *caller) +{ + DISPID dispid = DISPID_PROPERTYPUT; + DISPPARAMS dp = {val, &dispid, 1, 1}; + IDispatchEx *dispex; + DispatchEx *jsdisp; + HRESULT hres; + + jsdisp = iface_to_jsdisp((IUnknown*)disp); + if(jsdisp) { + dispex_prop_t *prop; + + prop = get_prop(jsdisp, id); + if(prop) + hres = prop_put(jsdisp, prop, lcid, &dp, ei, caller); + else + hres = DISP_E_MEMBERNOTFOUND; + + IDispatchEx_Release(_IDispatchEx_(jsdisp)); + return hres; + } + + hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex); + if(FAILED(hres)) { + ULONG err = 0; + + TRACE("using IDispatch\n"); + return IDispatch_Invoke(disp, id, &IID_NULL, DISPATCH_PROPERTYPUT, lcid, &dp, NULL, &ei->ei, &err); + } + + hres = IDispatchEx_InvokeEx(dispex, id, lcid, DISPATCH_PROPERTYPUT, &dp, NULL, &ei->ei, caller); + + IDispatchEx_Release(dispex); + return hres; +} + HRESULT disp_propget(IDispatch *disp, DISPID id, LCID lcid, VARIANT *val, jsexcept_t *ei, IServiceProvider *caller) { DISPPARAMS dp = {NULL,NULL,0,0}; diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c index e77993ed066..3f3d331ac44 100644 --- a/dlls/jscript/engine.c +++ b/dlls/jscript/engine.c @@ -141,6 +141,17 @@ static HRESULT disp_get_id(IDispatch *disp, BSTR name, DWORD flags, DISPID *id) return hres; } +/* ECMA-262 3rd Edition 8.7.2 */ +static HRESULT put_value(script_ctx_t *ctx, exprval_t *ref, VARIANT *v, jsexcept_t *ei) +{ + if(ref->type != EXPRVAL_IDREF) { + FIXME("throw ReferemceError\n"); + return E_FAIL; + } + + return disp_propput(ref->u.idref.disp, ref->u.idref.id, ctx->lcid, v, ei, NULL/*FIXME*/); +} + HRESULT exec_source(exec_ctx_t *ctx, parser_ctx_t *parser, source_elements_t *source, jsexcept_t *ei, VARIANT *retv) { script_ctx_t *script = parser->script; @@ -655,10 +666,38 @@ HRESULT right2_shift_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD return E_NOTIMPL; } -HRESULT assign_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) +/* ECMA-262 3rd Edition 11.13.1 */ +HRESULT assign_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) { - FIXME("\n"); - return E_NOTIMPL; + binary_expression_t *expr = (binary_expression_t*)_expr; + exprval_t exprval, exprvalr; + VARIANT rval; + HRESULT hres; + + TRACE("\n"); + + hres = expr_eval(ctx, expr->expression1, EXPR_NEWREF, ei, &exprval); + if(FAILED(hres)) + return hres; + + hres = expr_eval(ctx, expr->expression2, 0, ei, &exprvalr); + if(SUCCEEDED(hres)) { + hres = exprval_to_value(ctx->parser->script, &exprvalr, ei, &rval); + exprval_release(&exprvalr); + } + + if(SUCCEEDED(hres)) + hres = put_value(ctx->parser->script, &exprval, &rval, ei); + + exprval_release(&exprval); + if(FAILED(hres)) { + VariantClear(&rval); + return hres; + } + + ret->type = EXPRVAL_VARIANT; + ret->u.var = rval; + return S_OK; } HRESULT assign_lshift_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h index d1bfa9dbae8..45d7bca7685 100644 --- a/dlls/jscript/jscript.h +++ b/dlls/jscript/jscript.h @@ -89,6 +89,7 @@ struct DispatchEx { HRESULT create_dispex(script_ctx_t*,const builtin_info_t*,DispatchEx*,DispatchEx**); HRESULT disp_call(IDispatch*,DISPID,LCID,WORD,DISPPARAMS*,VARIANT*,jsexcept_t*,IServiceProvider*); HRESULT disp_propget(IDispatch*,DISPID,LCID,VARIANT*,jsexcept_t*,IServiceProvider*); +HRESULT disp_propput(IDispatch*,DISPID,LCID,VARIANT*,jsexcept_t*,IServiceProvider*); typedef struct named_item_t { IDispatch *disp; -- 2.11.4.GIT