Jacek Caban : jscript: Added AddNamedItem implementation.
Alexandre Julliard
julliard at winehq.org
Tue Sep 9 05:50:42 CDT 2008
Module: wine
Branch: master
Commit: 2bbd9d410509a426b22f59c156daa15a35b78809
URL: http://source.winehq.org/git/wine.git/?a=commit;h=2bbd9d410509a426b22f59c156daa15a35b78809
Author: Jacek Caban <jacek at codeweavers.com>
Date: Tue Sep 9 01:22:31 2008 +0200
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 3633939..422ac7d 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 f8b95c5..ee5dcdf 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 a8cfad2..3a29a8f 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 b9daee4..1213b34 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)
More information about the wine-cvs
mailing list