Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50758 Signed-off-by: Robert Wilhelm robert.wilhelm@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
On 10/1/21 8:13 AM, Robert Wilhelm wrote:
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
This will cause a new entry in vbdisp_funcprop_desc_t.
Since the distinction matters only to do_icall, how about fixing the problem there? It could detect check for recursive appropriate and don't call lookup_identifier in that case.
Thanks,
Jacek
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50758 Signed-off-by: Robert Wilhelm robert.wilhelm@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
Hi Robert,
On 10/6/21 10:11 PM, Robert Wilhelm wrote:
-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;
- }
I think it would be easier to handle that in the caller. What do you think about the attached patch?
Thanks,
Jacek
Hi Jacek,
your version avoids the extra parameter to do_icall. This makes the patch smaller and less ugly.
Thanks for fast review and your helpful hints,
Robert
On Thu, 2021-10-07 at 21:55 +0200, Jacek Caban wrote:
Hi Robert,
On 10/6/21 10:11 PM, Robert Wilhelm wrote:
-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; + }
I think it would be easier to handle that in the caller. What do you think about the attached patch?
Thanks,
Jacek
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50758 Signed-off-by: Robert Wilhelm robert.wilhelm@gmx.net --- v2: Try to implement suggestions from Jacek´s review. No changes to vbscript.h anymore. v3: Jacek's version. --- dlls/vbscript/interp.c | 10 +++++++++- dlls/vbscript/tests/lang.vbs | 24 ++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-)
diff --git a/dlls/vbscript/interp.c b/dlls/vbscript/interp.c index e2c1d5cc53d..48863068013 100644 --- a/dlls/vbscript/interp.c +++ b/dlls/vbscript/interp.c @@ -134,7 +134,8 @@ 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) + 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; @@ -800,6 +801,13 @@ static HRESULT interp_ident(exec_ctx_t *ctx)
TRACE("%s\n", debugstr_w(identifier));
+ if((ctx->func->type == FUNC_FUNCTION || ctx->func->type == FUNC_PROPGET) + && !wcsicmp(identifier, ctx->func->name)) { + V_VT(&v) = VT_BYREF|VT_VARIANT; + V_BYREF(&v) = &ctx->ret_val; + return stack_push(ctx, &v); + } + hres = do_icall(ctx, &v, identifier, 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
-- 2.31.1