[PATCH v2 2/2] vbscript: support for class default sub.
Robert Wilhelm
robert.wilhelm at gmx.net
Mon Oct 12 16:50:42 CDT 2020
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=35744
Signed-off-by: Robert Wilhelm <robert.wilhelm at gmx.net>
---
v2:refactor after Jacek's review.
---
dlls/vbscript/compile.c | 21 +++++++++++++++++----
dlls/vbscript/parser.y | 2 +-
dlls/vbscript/tests/lang.vbs | 30 ++++++++++++++++++++++++++++++
dlls/vbscript/vbdisp.c | 6 ++----
4 files changed, 50 insertions(+), 9 deletions(-)
diff --git a/dlls/vbscript/compile.c b/dlls/vbscript/compile.c
index e9f6361aee9..858edff7e4c 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,7 +1718,9 @@ 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++) {
- for(func_prop_decl = func_decl; func_prop_decl; func_prop_decl = func_prop_decl->next_prop_func) {
+ func_prop_decl = func_decl;
+ if (func_decl->is_default) i--;
+ for(; func_prop_decl; func_prop_decl = func_prop_decl->next_prop_func) {
if(func_prop_decl->is_default) {
i--;
break;
diff --git a/dlls/vbscript/parser.y b/dlls/vbscript/parser.y
index 7e6cc17efd6..942e76459c2 100644
--- a/dlls/vbscript/parser.y
+++ b/dlls/vbscript/parser.y
@@ -993,7 +993,7 @@ static function_decl_t *new_function_decl(parser_ctx_t *ctx, const WCHAR *name,
BOOL is_default = FALSE;
if(storage_flags & STORAGE_IS_DEFAULT) {
- if(type == FUNC_PROPGET) {
+ if(type == FUNC_PROPGET || type == FUNC_FUNCTION || type == FUNC_SUB) {
is_default = TRUE;
}else {
FIXME("Invalid default property\n");
diff --git a/dlls/vbscript/tests/lang.vbs b/dlls/vbscript/tests/lang.vbs
index fc762450a3b..65f8a458cd7 100644
--- a/dlls/vbscript/tests/lang.vbs
+++ b/dlls/vbscript/tests/lang.vbs
@@ -1750,6 +1750,36 @@ call ok(x.getprop.getprop().prop is obj, "x.getprop.getprop().prop is not obj (e
ok getVT(x) = "VT_DISPATCH*", "getVT(x) = " & getVT(x)
todo_wine_ok getVT(x()) = "VT_BSTR", "getVT(x()) = " & getVT(x())
+funcCalled = ""
+class DefaultSubTest1
+ Public default Sub init(a)
+ funcCalled = "init" & a
+ end sub
+end class
+
+Set obj = New DefaultSubTest1
+obj.init(1)
+call ok(funcCalled = "init1","funcCalled=" & funcCalled)
+funcCalled = ""
+obj(2)
+call ok(funcCalled = "init2","funcCalled=" & funcCalled)
+
+class DefaultSubTest2
+ Public Default Function init
+ funcCalled = "init"
+ end function
+end class
+
+Set obj = New DefaultSubTest2
+funcCalled = ""
+obj.init()
+call ok(funcCalled = "init","funcCalled=" & funcCalled)
+funcCalled = ""
+' todo this is not yet supported
+'funcCalled = ""
+'obj()
+'call ok(funcCalled = "init","funcCalled=" & funcCalled)
+
with nothing
end with
diff --git a/dlls/vbscript/vbdisp.c b/dlls/vbscript/vbdisp.c
index 1ff1110e56b..5f493d420bd 100644
--- a/dlls/vbscript/vbdisp.c
+++ b/dlls/vbscript/vbdisp.c
@@ -38,19 +38,17 @@ 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;
- if(!i && !This->desc->funcs[0].name) /* default value may not exist */
- continue;
}else {
if(!This->desc->funcs[i].entries[invoke_type]
|| (!search_private && !This->desc->funcs[i].entries[invoke_type]->is_public))
continue;
}
- if(!wcsicmp(This->desc->funcs[i].name, name)) {
+ if(This->desc->funcs[i].name && !wcsicmp(This->desc->funcs[i].name, name)) {
*id = i;
return TRUE;
}
--
2.26.2
More information about the wine-devel
mailing list