Hi Robert, This version looks better. On 11.10.2020 22:46, Robert Wilhelm wrote:
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=35744 Signed-off-by: Robert Wilhelm <robert.wilhelm(a)gmx.net> --- dlls/vbscript/compile.c | 26 +++++++++++++++++++++----- dlls/vbscript/parser.y | 2 +- dlls/vbscript/tests/lang.vbs | 30 ++++++++++++++++++++++++++++++ dlls/vbscript/vbdisp.c | 2 +- 4 files changed, 53 insertions(+), 7 deletions(-)
diff --git a/dlls/vbscript/compile.c b/dlls/vbscript/compile.c index e9f6361aee9..2d75f4d4a5f 100644 --- a/dlls/vbscript/compile.c +++ b/dlls/vbscript/compile.c @@ -1670,7 +1670,8 @@ static HRESULT compile_class(compile_ctx_t *ctx, class_decl_t *class_decl) function_decl_t *func_decl, *func_prop_decl; class_desc_t *class_desc; dim_decl_t *prop_decl; - unsigned i; + unsigned i, def=0; + BOOL is_default; HRESULT hres;
static const WCHAR class_initializeW[] = {'c','l','a','s','s','_','i','n','i','t','i','a','l','i','z','e',0}; @@ -1690,15 +1691,25 @@ static HRESULT compile_class(compile_ctx_t *ctx, class_decl_t *class_decl) if(!class_desc->name) return E_OUTOFMEMORY;
- class_desc->func_cnt = 1; /* always allocate slot for default getter */ + class_desc->func_cnt = 1; /* always allocate slot for default getter or method */
for(func_decl = class_decl->funcs; func_decl; func_decl = func_decl->next) { + is_default = FALSE; + if (func_decl->is_default) is_default = TRUE; for(func_prop_decl = func_decl; func_prop_decl; func_prop_decl = func_prop_decl->next_prop_func) { if(func_prop_decl->is_default) + is_default = TRUE; break; } - if(!func_prop_decl) + if(!is_default) class_desc->func_cnt++; + else + def++; + } + + if(def > 1) { + FIXME("multiple default getters or methods\n"); + return E_FAIL; }
class_desc->funcs = compiler_alloc(ctx->code, class_desc->func_cnt*sizeof(*class_desc->funcs)); @@ -1707,12 +1718,17 @@ static HRESULT compile_class(compile_ctx_t *ctx, class_decl_t *class_decl) memset(class_desc->funcs, 0, class_desc->func_cnt*sizeof(*class_desc->funcs));
for(func_decl = class_decl->funcs, i=1; func_decl; func_decl = func_decl->next, i++) { + is_default = FALSE; + if (func_decl->is_default) is_default = TRUE;
It looks redundant, it will be set in the 'if' below anyway.
for(func_prop_decl = func_decl; func_prop_decl; func_prop_decl = func_prop_decl->next_prop_func) { if(func_prop_decl->is_default) { - i--; + is_default = TRUE; break; } } + if(is_default) { + i--; + }
This move is also not needed.
diff --git a/dlls/vbscript/vbdisp.c b/dlls/vbscript/vbdisp.c index 1ff1110e56b..864c36681e3 100644 --- a/dlls/vbscript/vbdisp.c +++ b/dlls/vbscript/vbdisp.c @@ -38,7 +38,7 @@ static BOOL get_func_id(vbdisp_t *This, const WCHAR *name, vbdisp_invoke_type_t { unsigned i;
- for(i = invoke_type == VBDISP_ANY ? 0 : 1; i < This->desc->func_cnt; i++) { + for(i = 0; i < This->desc->func_cnt; i++) { if(invoke_type == VBDISP_ANY) { if(!search_private && !This->desc->funcs[i].is_public) continue;
This part looks fine, but note that we should then make sure that name is not NULL before comparing to it, like we do in invoke_type == VBDISP_ANY if branch. I'd suggest to replace it by doing the check directly before name comparison, something like: if(This->desc->funcs[i].name && !wcsicmp( ... ))) { Thanks, Jacek