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