[PATCH v2 2/2] vbscript: Handle recursive calls.
Robert Wilhelm
robert.wilhelm at gmx.net
Wed Oct 6 15:11:36 CDT 2021
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50758
Signed-off-by: Robert Wilhelm <robert.wilhelm at gmx.net>
---
v2: Try to implement suggestions from Jacek´s review. No changes to vbscript.h anymore.
---
dlls/vbscript/interp.c | 27 ++++++++++++++++++---------
dlls/vbscript/tests/lang.vbs | 24 ++++++++++++++++++++++++
2 files changed, 42 insertions(+), 9 deletions(-)
diff --git a/dlls/vbscript/interp.c b/dlls/vbscript/interp.c
index e2c1d5cc53d..651767b0390 100644
--- a/dlls/vbscript/interp.c
+++ b/dlls/vbscript/interp.c
@@ -134,7 +134,9 @@ static HRESULT lookup_identifier(exec_ctx_t *ctx, BSTR name, vbdisp_invoke_type_
DISPID id;
HRESULT hres;
- if((ctx->func->type == FUNC_FUNCTION || ctx->func->type == FUNC_PROPGET)
+ TRACE("%s %d\n", debugstr_w(name), invoke_type);
+
+ if((invoke_type != VBDISP_CALLGET) && (ctx->func->type == FUNC_FUNCTION || ctx->func->type == FUNC_PROPGET)
&& !wcsicmp(name, ctx->func->name)) {
ref->type = REF_VAR;
ref->u.v = &ctx->ret_val;
@@ -615,17 +617,24 @@ static HRESULT variant_call(exec_ctx_t *ctx, VARIANT *v, unsigned arg_cnt, VARIA
return S_OK;
}
-static HRESULT do_icall(exec_ctx_t *ctx, VARIANT *res, BSTR identifier, unsigned arg_cnt)
+static HRESULT do_icall(exec_ctx_t *ctx, VARIANT *res, BSTR identifier, unsigned arg_cnt, BOOL ident)
{
DISPPARAMS dp;
ref_t ref;
HRESULT hres;
- TRACE("%s %u\n", debugstr_w(identifier), arg_cnt);
+ TRACE("%s %u %d\n", debugstr_w(identifier), arg_cnt, ident);
- hres = lookup_identifier(ctx, identifier, VBDISP_CALLGET, &ref);
- if(FAILED(hres))
- return hres;
+ if( ident && (ctx->func->type == FUNC_FUNCTION || ctx->func->type == FUNC_PROPGET)
+ && !wcsicmp(identifier, ctx->func->name)) {
+ ref.type = REF_VAR;
+ ref.u.v = &ctx->ret_val;
+ }
+ else {
+ hres = lookup_identifier(ctx, identifier, VBDISP_CALLGET, &ref);
+ if(FAILED(hres))
+ return hres;
+ }
switch(ref.type) {
case REF_VAR:
@@ -692,7 +701,7 @@ static HRESULT interp_icall(exec_ctx_t *ctx)
TRACE("\n");
- hres = do_icall(ctx, &v, identifier, arg_cnt);
+ hres = do_icall(ctx, &v, identifier, arg_cnt, FALSE);
if(FAILED(hres))
return hres;
@@ -706,7 +715,7 @@ static HRESULT interp_icallv(exec_ctx_t *ctx)
TRACE("\n");
- return do_icall(ctx, NULL, identifier, arg_cnt);
+ return do_icall(ctx, NULL, identifier, arg_cnt, FALSE);
}
static HRESULT interp_vcall(exec_ctx_t *ctx)
@@ -800,7 +809,7 @@ static HRESULT interp_ident(exec_ctx_t *ctx)
TRACE("%s\n", debugstr_w(identifier));
- hres = do_icall(ctx, &v, identifier, 0);
+ hres = do_icall(ctx, &v, identifier, 0, TRUE);
if(FAILED(hres))
return hres;
diff --git a/dlls/vbscript/tests/lang.vbs b/dlls/vbscript/tests/lang.vbs
index d7865301784..dc2acbae69c 100644
--- a/dlls/vbscript/tests/lang.vbs
+++ b/dlls/vbscript/tests/lang.vbs
@@ -1882,6 +1882,30 @@ set arr(0) = new TestPropSyntax
arr(0).prop = 1
ok arr(0).prop = 1, "arr(0) = " & arr(0).prop
+function recursingfunction(x)
+ if (x) then exit function
+ recursingfunction = 2
+ dim y
+ y = recursingfunction
+ call ok(y = 2, "y = " & y)
+ recursingfunction = 1
+ call recursingfunction(True)
+end function
+call ok(recursingfunction(False) = 1, "unexpected return value " & recursingfunction(False))
+
+x = false
+function recursingfunction2
+ if (x) then exit function
+ recursingfunction2 = 2
+ dim y
+ y = recursingfunction2
+ call ok(y = 2, "y = " & y)
+ recursingfunction2 = 1
+ x = true
+ recursingfunction2()
+end function
+call ok(recursingfunction2() = 1, "unexpected return value " & recursingfunction2())
+
function f2(x,y)
end function
--
2.31.1
More information about the wine-devel
mailing list