From 2bbd9d410509a426b22f59c156daa15a35b78809 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Tue, 9 Sep 2008 01:22:31 +0200 Subject: [PATCH] jscript: Added AddNamedItem implementation. --- dlls/jscript/engine.c | 31 +++++++++++++++++++++++++- dlls/jscript/jscript.c | 37 +++++++++++++++++++++++++++++-- dlls/jscript/jscript.h | 8 +++++++ dlls/jscript/tests/run.c | 48 +++++++++++++++++++++++++++++++++++++++- 4 files changed, 120 insertions(+), 4 deletions(-) diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c index 36339398e89..422ac7d8309 100644 --- a/dlls/jscript/engine.c +++ b/dlls/jscript/engine.c @@ -123,6 +123,24 @@ static HRESULT dispex_get_id(IDispatchEx *dispex, BSTR name, DWORD flags, DISPID return IDispatchEx_GetDispID(dispex, name, flags|fdexNameCaseSensitive, id); } +static HRESULT disp_get_id(IDispatch *disp, BSTR name, DWORD flags, DISPID *id) +{ + IDispatchEx *dispex; + HRESULT hres; + + hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex); + if(FAILED(hres)) { + TRACE("unsing IDispatch\n"); + + *id = 0; + return IDispatch_GetIDsOfNames(disp, &IID_NULL, &name, 1, 0, id); + } + + hres = dispex_get_id(dispex, name, flags, id); + IDispatchEx_Release(dispex); + return hres; +} + 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; @@ -178,6 +196,7 @@ HRESULT exec_source(exec_ctx_t *ctx, parser_ctx_t *parser, source_elements_t *so /* ECMA-262 3rd Edition 10.1.4 */ static HRESULT identifier_eval(exec_ctx_t *ctx, BSTR identifier, DWORD flags, exprval_t *ret) { + named_item_t *item; DISPID id = 0; HRESULT hres; @@ -185,7 +204,17 @@ static HRESULT identifier_eval(exec_ctx_t *ctx, BSTR identifier, DWORD flags, ex /* FIXME: scope chain */ /* FIXME: global */ - /* FIXME: named items */ + + for(item = ctx->parser->script->named_items; item; item = item->next) { + hres = disp_get_id(item->disp, identifier, 0, &id); + if(SUCCEEDED(hres)) + break; + } + + if(item) { + exprval_set_idref(ret, (IDispatch*)item->disp, id); + return S_OK; + } hres = dispex_get_id(_IDispatchEx_(ctx->parser->script->script_disp), identifier, 0, &id); if(SUCCEEDED(hres)) { diff --git a/dlls/jscript/jscript.c b/dlls/jscript/jscript.c index f8b95c561f5..ee5dcdf8eeb 100644 --- a/dlls/jscript/jscript.c +++ b/dlls/jscript/jscript.c @@ -320,8 +320,41 @@ static HRESULT WINAPI JScript_AddNamedItem(IActiveScript *iface, LPCOLESTR pstrName, DWORD dwFlags) { JScript *This = ACTSCRIPT_THIS(iface); - FIXME("(%p)->(%s %x)\n", This, debugstr_w(pstrName), dwFlags); - return E_NOTIMPL; + named_item_t *item; + IDispatch *disp; + IUnknown *unk; + HRESULT hres; + + TRACE("(%p)->(%s %x)\n", This, debugstr_w(pstrName), dwFlags); + + if(This->thread_id != GetCurrentThreadId() || !This->ctx || This->ctx->state == SCRIPTSTATE_CLOSED) + return E_UNEXPECTED; + + hres = IActiveScriptSite_GetItemInfo(This->site, pstrName, SCRIPTINFO_IUNKNOWN, &unk, NULL); + if(FAILED(hres)) { + WARN("GetItemInfo failed: %08x\n", hres); + return hres; + } + + hres = IUnknown_QueryInterface(unk, &IID_IDispatch, (void**)&disp); + IUnknown_Release(unk); + if(FAILED(hres)) { + WARN("object does not implement IDispatch\n"); + return hres; + } + + item = heap_alloc(sizeof(*item)); + if(!item) { + IDispatch_Release(disp); + return E_OUTOFMEMORY; + } + + item->disp = disp; + item->flags = dwFlags; + item->next = This->ctx->named_items; + This->ctx->named_items = item; + + return S_OK; } static HRESULT WINAPI JScript_AddTypeLib(IActiveScript *iface, REFGUID rguidTypeLib, diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h index a8cfad27ff7..3a29a8f500b 100644 --- a/dlls/jscript/jscript.h +++ b/dlls/jscript/jscript.h @@ -89,11 +89,19 @@ 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*); +typedef struct named_item_t { + IDispatch *disp; + DWORD flags; + + struct named_item_t *next; +} named_item_t; + struct _script_ctx_t { LONG ref; SCRIPTSTATE state; exec_ctx_t *exec_ctx; + named_item_t *named_items; LCID lcid; DispatchEx *script_disp; diff --git a/dlls/jscript/tests/run.c b/dlls/jscript/tests/run.c index b9daee42a9e..1213b34f277 100644 --- a/dlls/jscript/tests/run.c +++ b/dlls/jscript/tests/run.c @@ -57,6 +57,11 @@ static const CLSID CLSID_JScript = expect_ ## func = called_ ## func = FALSE; \ }while(0) +DEFINE_EXPECT(global_propget_d); +DEFINE_EXPECT(global_propget_i); + +#define DISPID_GLOBAL_TESTPROPGET 0x1000 + static const WCHAR testW[] = {'t','e','s','t',0}; static const char *debugstr_w(LPCWSTR str) @@ -82,6 +87,13 @@ static BSTR a2bstr(const char *str) return ret; } +static int strcmp_wa(LPCWSTR strw, const char *stra) +{ + WCHAR buf[512]; + MultiByteToWideChar(CP_ACP, 0, stra, -1, buf, sizeof(buf)/sizeof(WCHAR)); + return lstrcmpW(strw, buf); +} + static HRESULT WINAPI DispatchEx_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv) { *ppv = NULL; @@ -173,12 +185,41 @@ static HRESULT WINAPI DispatchEx_GetNameSpaceParent(IDispatchEx *iface, IUnknown static HRESULT WINAPI Global_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid) { + if(!strcmp_wa(bstrName, "testPropGet")) { + CHECK_EXPECT(global_propget_d); + ok(grfdex == fdexNameCaseSensitive, "grfdex = %x\n", grfdex); + *pid = DISPID_GLOBAL_TESTPROPGET; + return S_OK; + } + + ok(0, "unexpected call %s\n", debugstr_w(bstrName)); return DISP_E_UNKNOWNNAME; } static HRESULT WINAPI Global_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp, VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller) { + switch(id) { + case DISPID_GLOBAL_TESTPROPGET: + CHECK_EXPECT(global_propget_i); + + ok(wFlags == INVOKE_PROPERTYGET, "wFlags = %x\n", wFlags); + ok(pdp != NULL, "pdp == NULL\n"); + ok(!pdp->rgvarg, "rgvarg != NULL\n"); + ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n"); + ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs); + ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs); + ok(pvarRes != NULL, "pvarRes == NULL\n"); + ok(V_VT(pvarRes) == VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes)); + ok(pei != NULL, "pei == NULL\n"); + + V_VT(pvarRes) = VT_I4; + V_I4(pvarRes) = 1; + + return S_OK; + } + + ok(0, "unexpected call %x\n", id); return DISP_E_MEMBERNOTFOUND; } @@ -326,7 +367,6 @@ static void parse_script(BSTR script_str) hres = IActiveScript_AddNamedItem(engine, testW, SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|SCRIPTITEM_GLOBALMEMBERS); - todo_wine ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres); hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED); @@ -350,6 +390,12 @@ static void run_tests(void) { parse_script_a(""); parse_script_a("/* empty */ ;"); + + SET_EXPECT(global_propget_d); + SET_EXPECT(global_propget_i); + parse_script_a("testPropGet;"); + CHECK_CALLED(global_propget_d); + CHECK_CALLED(global_propget_i); } START_TEST(run)