Jacek Caban : scrobj: Lookup object members implementations in scripts when createating scriptlet instance.

Alexandre Julliard julliard at winehq.org
Wed Sep 25 16:45:19 CDT 2019


Module: wine
Branch: master
Commit: b3b78b4226f6307369d5412084c17ae59301b19d
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=b3b78b4226f6307369d5412084c17ae59301b19d

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Wed Sep 25 19:22:56 2019 +0200

scrobj: Lookup object members implementations in scripts when createating scriptlet instance.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/scrobj/scrobj.c       | 92 ++++++++++++++++++++++++++++++++++++++++++++++
 dlls/scrobj/tests/scrobj.c |  9 -----
 2 files changed, 92 insertions(+), 9 deletions(-)

diff --git a/dlls/scrobj/scrobj.c b/dlls/scrobj/scrobj.c
index 946dd685f5..350efd9340 100644
--- a/dlls/scrobj/scrobj.c
+++ b/dlls/scrobj/scrobj.c
@@ -118,12 +118,35 @@ struct scriptlet_factory
     struct list scripts;
 };
 
+struct script_reference
+{
+    struct script_host *host;
+    DISPID id;
+};
+
+struct object_member
+{
+    enum member_type type;
+    BSTR name;
+    union
+    {
+        struct script_reference method;
+        struct
+        {
+            struct script_reference get;
+            struct script_reference put;
+        } property;
+    } u;
+};
+
 struct scriptlet_instance
 {
     IDispatchEx IDispatchEx_iface;
     LONG ref;
     struct list hosts;
     struct scriptlet_global *global;
+    unsigned member_cnt;
+    struct object_member *members;
 };
 
 struct script_host
@@ -705,6 +728,70 @@ static HRESULT parse_scripts(struct scriptlet_factory *factory, struct list *hos
     return S_OK;
 }
 
+static HRESULT lookup_script_properties(struct scriptlet_instance *object, BSTR name, struct script_reference *ret)
+{
+    struct script_host *host;
+    HRESULT hres;
+
+    LIST_FOR_EACH_ENTRY(host, &object->hosts, struct script_host, entry)
+    {
+        hres = IDispatchEx_GetDispID(host->script_dispatch, name, 0, &ret->id);
+        if (FAILED(hres)) continue;
+        ret->host = host;
+        return S_OK;
+    }
+
+    FIXME("Could not find %s in scripts\n", debugstr_w(name));
+    return E_FAIL;
+}
+
+static HRESULT lookup_object_properties(struct scriptlet_instance *object, struct scriptlet_factory *factory)
+{
+    struct scriptlet_member *member;
+    unsigned i = 0, member_cnt = 0;
+    size_t len;
+    BSTR name;
+    HRESULT hres;
+
+    LIST_FOR_EACH_ENTRY(member, &factory->members, struct scriptlet_member, entry)
+        member_cnt++;
+
+    if (!member_cnt) return S_OK;
+
+    if (!(object->members = heap_alloc_zero(member_cnt * sizeof(*object->members)))) return E_OUTOFMEMORY;
+    object->member_cnt = member_cnt;
+
+    LIST_FOR_EACH_ENTRY(member, &factory->members, struct scriptlet_member, entry)
+    {
+        object->members[i].type = member->type;
+        if (!(object->members[i].name = SysAllocString(member->name))) return E_OUTOFMEMORY;
+        switch (member->type)
+        {
+        case MEMBER_METHOD:
+            hres = lookup_script_properties(object, object->members[i].name, &object->members[i].u.method);
+            if (FAILED(hres)) return hres;
+            break;
+        case MEMBER_PROPERTY:
+            len = wcslen(member->name);
+            if (!(name = SysAllocStringLen(NULL, len + 4))) return E_OUTOFMEMORY;
+            wcscpy(name, L"get_");
+            wcscat(name, member->name);
+            hres = lookup_script_properties(object, name, &object->members[i].u.property.get);
+            if (SUCCEEDED(hres))
+            {
+                memcpy(name, L"put", 3 * sizeof(WCHAR));
+                hres = lookup_script_properties(object, name, &object->members[i].u.property.put);
+            }
+            SysFreeString(name);
+            if (FAILED(hres)) return hres;
+            break;
+        }
+        i++;
+    }
+
+    return S_OK;
+}
+
 static HRESULT init_script_host(struct script_host *host, IActiveScript *clone)
 {
     HRESULT hres;
@@ -900,6 +987,10 @@ static ULONG WINAPI scriptlet_Release(IDispatchEx *iface)
 
     if (!ref)
     {
+        unsigned i;
+        for (i = 0; i < This->member_cnt; i++)
+            SysFreeString(This->members[i].name);
+        heap_free(This->members);
         detach_script_hosts(&This->hosts);
         if (This->global) IDispatchEx_Release(&This->global->IDispatchEx_iface);
         heap_free(This);
@@ -1074,6 +1165,7 @@ static HRESULT create_scriptlet_instance(struct scriptlet_factory *factory, IDis
     }
 
     if (SUCCEEDED(hres)) hres = parse_scripts(factory, &obj->hosts, TRUE);
+    if (SUCCEEDED(hres)) hres = lookup_object_properties(obj, factory);
     if (FAILED(hres))
     {
         IDispatchEx_Release(&obj->IDispatchEx_iface);
diff --git a/dlls/scrobj/tests/scrobj.c b/dlls/scrobj/tests/scrobj.c
index 37b5769368..340e08874c 100644
--- a/dlls/scrobj/tests/scrobj.c
+++ b/dlls/scrobj/tests/scrobj.c
@@ -832,11 +832,8 @@ static void test_create_object(void)
     CHECK_CALLED(GetScriptDispatch);
     todo_wine
     CHECK_CALLED(GetDispID_vbAddOne);
-    todo_wine
     CHECK_CALLED(GetDispID_wtTest);
-    todo_wine
     CHECK_CALLED(GetDispID_get_gsProp);
-    todo_wine
     CHECK_CALLED(GetDispID_put_gsProp);
     CHECK_CALLED(SetScriptState_STARTED);
     CHECK_CALLED(ParseScriptText);
@@ -1038,11 +1035,8 @@ static void test_create_object(void)
     CHECK_CALLED(GetScriptDispatch);
     todo_wine
     CHECK_CALLED(GetDispID_vbAddOne);
-    todo_wine
     CHECK_CALLED(GetDispID_wtTest);
-    todo_wine
     CHECK_CALLED(GetDispID_get_gsProp);
-    todo_wine
     CHECK_CALLED(GetDispID_put_gsProp);
     CHECK_CALLED(SetScriptState_STARTED);
     CHECK_CALLED(ParseScriptText);
@@ -1075,11 +1069,8 @@ static void test_create_object(void)
     CHECK_CALLED(GetScriptDispatch);
     todo_wine
     CHECK_CALLED(GetDispID_vbAddOne);
-    todo_wine
     CHECK_CALLED(GetDispID_wtTest);
-    todo_wine
     CHECK_CALLED(GetDispID_get_gsProp);
-    todo_wine
     CHECK_CALLED(GetDispID_put_gsProp);
     CHECK_CALLED(SetScriptState_STARTED);
 




More information about the wine-cvs mailing list