Jacek Caban : vbscript: Added ScriptDisp::GetDispID implementation.

Alexandre Julliard julliard at winehq.org
Fri Sep 7 13:26:21 CDT 2012


Module: wine
Branch: master
Commit: 40001df45db90b70710b9fec7fad419322301ad3
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=40001df45db90b70710b9fec7fad419322301ad3

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Fri Sep  7 15:09:59 2012 +0200

vbscript: Added ScriptDisp::GetDispID implementation.

---

 dlls/vbscript/vbdisp.c   |   85 ++++++++++++++++++++++++++++++++++++++++++++-
 dlls/vbscript/vbscript.h |    7 ++++
 2 files changed, 90 insertions(+), 2 deletions(-)

diff --git a/dlls/vbscript/vbdisp.c b/dlls/vbscript/vbdisp.c
index b7945d8..4f473e2 100644
--- a/dlls/vbscript/vbdisp.c
+++ b/dlls/vbscript/vbdisp.c
@@ -565,6 +565,44 @@ HRESULT create_procedure_disp(script_ctx_t *ctx, vbscode_t *code, IDispatch **re
     return S_OK;
 }
 
+struct _ident_map_t {
+    const WCHAR *name;
+    BOOL is_var;
+    union {
+        dynamic_var_t *var;
+        function_t *func;
+    } u;
+};
+
+static inline DISPID ident_to_id(ScriptDisp *This, ident_map_t *ident)
+{
+    return (ident-This->ident_map)+1;
+}
+
+static ident_map_t *add_ident(ScriptDisp *This, const WCHAR *name)
+{
+    ident_map_t *ret;
+
+    if(!This->ident_map_size) {
+        This->ident_map = heap_alloc(4 * sizeof(*This->ident_map));
+        if(!This->ident_map)
+            return NULL;
+        This->ident_map_size = 4;
+    }else if(This->ident_map_cnt == This->ident_map_size) {
+        ident_map_t *new_map;
+
+        new_map = heap_realloc(This->ident_map, 2*This->ident_map_size*sizeof(*new_map));
+        if(!new_map)
+            return NULL;
+        This->ident_map = new_map;
+        This->ident_map_size *= 2;
+    }
+
+    ret = This->ident_map + This->ident_map_cnt++;
+    ret->name = name;
+    return ret;
+}
+
 static inline ScriptDisp *ScriptDisp_from_IDispatchEx(IDispatchEx *iface)
 {
     return CONTAINING_RECORD(iface, ScriptDisp, IDispatchEx_iface);
@@ -612,6 +650,7 @@ static ULONG WINAPI ScriptDisp_Release(IDispatchEx *iface)
 
     if(!ref) {
         assert(!This->ctx);
+        heap_free(This->ident_map);
         heap_free(This);
     }
 
@@ -659,7 +698,49 @@ static HRESULT WINAPI ScriptDisp_Invoke(IDispatchEx *iface, DISPID dispIdMember,
 static HRESULT WINAPI ScriptDisp_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
 {
     ScriptDisp *This = ScriptDisp_from_IDispatchEx(iface);
-    FIXME("(%p)->(%s %x %p)\n", This, debugstr_w(bstrName), grfdex, pid);
+    dynamic_var_t *var;
+    ident_map_t *ident;
+    function_t *func;
+
+    TRACE("(%p)->(%s %x %p)\n", This, debugstr_w(bstrName), grfdex, pid);
+
+    if(!This->ctx)
+        return E_UNEXPECTED;
+
+    for(ident = This->ident_map; ident < This->ident_map+This->ident_map_cnt; ident++) {
+        if(!strcmpiW(ident->name, bstrName)) {
+            *pid = ident_to_id(This, ident);
+            return S_OK;
+        }
+    }
+
+    for(var = This->ctx->global_vars; var; var = var->next) {
+        if(!strcmpiW(var->name, bstrName)) {
+            ident = add_ident(This, var->name);
+            if(!ident)
+                return E_OUTOFMEMORY;
+
+            ident->is_var = TRUE;
+            ident->u.var = var;
+            *pid = ident_to_id(This, ident);
+            return S_OK;
+        }
+    }
+
+    for(func = This->ctx->global_funcs; func; func = func->next) {
+        if(!strcmpiW(func->name, bstrName)) {
+            ident = add_ident(This, func->name);
+            if(!ident)
+                return E_OUTOFMEMORY;
+
+            ident->is_var = FALSE;
+            ident->u.func = func;
+            *pid =  ident_to_id(This, ident);
+            return S_OK;
+        }
+    }
+
+    *pid = -1;
     return DISP_E_UNKNOWNNAME;
 }
 
@@ -735,7 +816,7 @@ HRESULT create_script_disp(script_ctx_t *ctx, ScriptDisp **ret)
 {
     ScriptDisp *script_disp;
 
-    script_disp = heap_alloc(sizeof(*script_disp));
+    script_disp = heap_alloc_zero(sizeof(*script_disp));
     if(!script_disp)
         return E_OUTOFMEMORY;
 
diff --git a/dlls/vbscript/vbscript.h b/dlls/vbscript/vbscript.h
index 306cfed..77cf0e7 100644
--- a/dlls/vbscript/vbscript.h
+++ b/dlls/vbscript/vbscript.h
@@ -116,9 +116,16 @@ struct _vbdisp_t {
     VARIANT props[1];
 };
 
+typedef struct _ident_map_t ident_map_t;
+
 typedef struct {
     IDispatchEx IDispatchEx_iface;
     LONG ref;
+
+    ident_map_t *ident_map;
+    unsigned ident_map_cnt;
+    unsigned ident_map_size;
+
     script_ctx_t *ctx;
 } ScriptDisp;
 




More information about the wine-cvs mailing list