Module: wine Branch: master Commit: 99b4bc2347b4eac6103cc73880188d6463cb4aab URL: http://source.winehq.org/git/wine.git/?a=commit;h=99b4bc2347b4eac6103cc73880...
Author: Jacek Caban jacek@codeweavers.com Date: Tue Sep 9 01:27:18 2008 +0200
jscript: Added member expression implementation.
---
dlls/jscript/engine.c | 54 +++++++++++++++++++++++++++++++++++++++++++++-- dlls/jscript/jscript.h | 1 + dlls/jscript/jsutils.c | 16 ++++++++++++++ 3 files changed, 68 insertions(+), 3 deletions(-)
diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c index 2a98643..183eca4 100644 --- a/dlls/jscript/engine.c +++ b/dlls/jscript/engine.c @@ -104,6 +104,12 @@ static HRESULT exprval_to_boolean(script_ctx_t *ctx, exprval_t *exprval, jsexcep return to_boolean(&exprval->u.var, b); }
+static void exprval_init(exprval_t *val) +{ + val->type = EXPRVAL_VARIANT; + V_VT(&val->u.var) = VT_EMPTY; +} + static void exprval_set_idref(exprval_t *val, IDispatch *disp, DISPID id) { val->type = EXPRVAL_IDREF; @@ -647,10 +653,52 @@ HRESULT array_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, return E_NOTIMPL; }
-HRESULT member_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) +/* ECMA-262 3rd Edition 11.2.1 */ +HRESULT member_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) { - FIXME("\n"); - return E_NOTIMPL; + member_expression_t *expr = (member_expression_t*)_expr; + IDispatch *obj = NULL; + exprval_t exprval; + VARIANT member; + DISPID id; + BSTR str; + HRESULT hres; + + TRACE("\n"); + + hres = expr_eval(ctx, expr->expression, 0, ei, &exprval); + if(FAILED(hres)) + return hres; + + hres = exprval_to_value(ctx->parser->script, &exprval, ei, &member); + exprval_release(&exprval); + if(FAILED(hres)) + return hres; + + hres = to_object(ctx, &member, &obj); + VariantClear(&member); + if(FAILED(hres)) + return hres; + + str = SysAllocString(expr->identifier); + if(flags & EXPR_STRREF) { + ret->type = EXPRVAL_NAMEREF; + ret->u.nameref.disp = obj; + ret->u.nameref.name = str; + return S_OK; + } + + hres = disp_get_id(obj, str, flags & EXPR_NEW ? fdexNameEnsure : 0, &id); + SysFreeString(str); + if(SUCCEEDED(hres)) { + exprval_set_idref(ret, obj, id); + }else if(!(flags & EXPR_NEWREF) && hres == DISP_E_UNKNOWNNAME) { + exprval_init(ret); + hres = S_OK; + } + + IDispatch_Release(obj); + return hres; }
static void free_dp(DISPPARAMS *dp) diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h index a8fc379..0144dbf 100644 --- a/dlls/jscript/jscript.h +++ b/dlls/jscript/jscript.h @@ -98,6 +98,7 @@ HRESULT jsdisp_set_prototype(DispatchEx*,DispatchEx*); HRESULT create_builtin_function(script_ctx_t*,builtin_invoke_t,DWORD,DispatchEx*,DispatchEx**);
HRESULT to_boolean(VARIANT*,VARIANT_BOOL*); +HRESULT to_object(exec_ctx_t*,VARIANT*,IDispatch**);
typedef struct named_item_t { IDispatch *disp; diff --git a/dlls/jscript/jsutils.c b/dlls/jscript/jsutils.c index c29f673..de04dfb 100644 --- a/dlls/jscript/jsutils.c +++ b/dlls/jscript/jsutils.c @@ -163,3 +163,19 @@ HRESULT to_boolean(VARIANT *v, VARIANT_BOOL *b)
return S_OK; } + +/* ECMA-262 3rd Edition 9.9 */ +HRESULT to_object(exec_ctx_t *ctx, VARIANT *v, IDispatch **disp) +{ + switch(V_VT(v)) { + case VT_DISPATCH: + IDispatch_AddRef(V_DISPATCH(v)); + *disp = V_DISPATCH(v); + break; + default: + FIXME("unsupported vt %d\n", V_VT(v)); + return E_NOTIMPL; + } + + return S_OK; +}