[PATCH 2/2] vbscript: Handle Recursive calls.

Robert Wilhelm robert.wilhelm at gmx.net
Fri Oct 1 01:13:48 CDT 2021


Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50758
Signed-off-by: Robert Wilhelm <robert.wilhelm at gmx.net>
---
 dlls/vbscript/interp.c       | 14 ++++++++------
 dlls/vbscript/tests/lang.vbs | 24 ++++++++++++++++++++++++
 dlls/vbscript/vbscript.h     |  1 +
 3 files changed, 33 insertions(+), 6 deletions(-)

diff --git a/dlls/vbscript/interp.c b/dlls/vbscript/interp.c
index e2c1d5cc53d..6064eea5bb0 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,7 +617,7 @@ 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, vbdisp_invoke_type_t invoke_type, unsigned arg_cnt)
 {
     DISPPARAMS dp;
     ref_t ref;
@@ -623,7 +625,7 @@ static HRESULT do_icall(exec_ctx_t *ctx, VARIANT *res, BSTR identifier, unsigned

     TRACE("%s %u\n", debugstr_w(identifier), arg_cnt);

-    hres = lookup_identifier(ctx, identifier, VBDISP_CALLGET, &ref);
+    hres = lookup_identifier(ctx, identifier, invoke_type, &ref);
     if(FAILED(hres))
         return hres;

@@ -692,7 +694,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, VBDISP_CALLGET, arg_cnt);
     if(FAILED(hres))
         return hres;

@@ -706,7 +708,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, VBDISP_CALLGET, arg_cnt);
 }

 static HRESULT interp_vcall(exec_ctx_t *ctx)
@@ -800,7 +802,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, VBDISP_IDENT, 0);
     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

diff --git a/dlls/vbscript/vbscript.h b/dlls/vbscript/vbscript.h
index f5353b33cae..b23df0fc589 100644
--- a/dlls/vbscript/vbscript.h
+++ b/dlls/vbscript/vbscript.h
@@ -57,6 +57,7 @@ typedef struct _vbdisp_t vbdisp_t;

 typedef enum {
     VBDISP_CALLGET,
+    VBDISP_IDENT,
     VBDISP_LET,
     VBDISP_SET,
     VBDISP_ANY
--
2.31.1






More information about the wine-devel mailing list