[PATCH v2 0/2] MR11008: vbscript: Compile class members in a separate namespace from globals.
A class member lives in a separate namespace, so its name may collide with a global Dim or Const. Wine wrongly rejected such a script with "Name redefined". -- v2: vbscript: Compile class members in a separate namespace from globals. https://gitlab.winehq.org/wine/wine/-/merge_requests/11008
From: Francis De Brabandere <francisdb@gmail.com> A class member lives in a separate namespace, so its name may collide with a global Dim or Const. Wine wrongly rejects such a script with "Name redefined", so mark the cases todo_wine for now. --- dlls/vbscript/tests/run.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/dlls/vbscript/tests/run.c b/dlls/vbscript/tests/run.c index f54efd099e2..aedc16f941f 100644 --- a/dlls/vbscript/tests/run.c +++ b/dlls/vbscript/tests/run.c @@ -3592,6 +3592,15 @@ static void test_redefine_scope(void) L"Class S\nEnd Class\nSub Other\nDim s\nEnd Sub\n", L"Sub Other\nDim s\nEnd Sub\nClass S\nEnd Class\n", }; + /* A class member lives in a separate namespace, so its name may collide + * with a global Dim or Const. Each script also calls the member to prove + * it stays usable. */ + static const WCHAR *valid_class_member[] = { + L"Class C\nPublic Function M\nM = 42\nEnd Function\nEnd Class\n" + L"Dim M\nDim o : Set o = New C\nCall ok(o.M = 42, \"o.M = \" & o.M)\n", + L"Class C\nPublic Function M\nM = 42\nEnd Function\nEnd Class\n" + L"Const M = 7\nDim o : Set o = New C\nCall ok(o.M = 42, \"o.M = \" & o.M)\n", + }; HRESULT hres; unsigned i; @@ -3599,6 +3608,13 @@ static void test_redefine_scope(void) hres = parse_script_wr(valid[i]); ok(hres == S_OK, "[%u] parse returned %08lx\n", i, hres); } + + for (i = 0; i < ARRAY_SIZE(valid_class_member); i++) { + SET_EXPECT(OnScriptError); /* Wine wrongly rejects the script; tolerate the error callback */ + hres = parse_script_wr(valid_class_member[i]); + todo_wine ok(hres == S_OK, "[%u] class member parse returned %08lx\n", i, hres); + CLEAR_CALLED(OnScriptError); + } } static void test_getref_error_reporting(void) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11008
From: Francis De Brabandere <francisdb@gmail.com> compile_class() ran with ctx.dim_decls and ctx.const_decls still pointing at the global scope that compile_script() set up, so create_function() rejected a class method whose name matched a global Dim or Const with "Name redefined" reported at the method name. Native VBScript keeps class members in their own namespace and accepts such a script. Drop the global scope before compiling the methods; a member colliding with another member of the same class is still caught when the class properties are processed. --- dlls/vbscript/compile.c | 5 +++++ dlls/vbscript/tests/run.c | 4 +--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/dlls/vbscript/compile.c b/dlls/vbscript/compile.c index 8aef25f21b1..4a52079e1f0 100644 --- a/dlls/vbscript/compile.c +++ b/dlls/vbscript/compile.c @@ -2073,6 +2073,11 @@ static HRESULT compile_class(compile_ctx_t *ctx, class_decl_t *class_decl) return E_OUTOFMEMORY; memset(class_desc->funcs, 0, class_desc->func_cnt*sizeof(*class_desc->funcs)); + /* Class members have their own namespace: drop the global Dim/Const scope + before compiling the methods. Same-class collisions are caught below. */ + ctx->dim_decls = ctx->dim_decls_tail = NULL; + ctx->const_decls = NULL; + 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) { if(func_prop_decl->is_default) { diff --git a/dlls/vbscript/tests/run.c b/dlls/vbscript/tests/run.c index aedc16f941f..d9d7084a887 100644 --- a/dlls/vbscript/tests/run.c +++ b/dlls/vbscript/tests/run.c @@ -3610,10 +3610,8 @@ static void test_redefine_scope(void) } for (i = 0; i < ARRAY_SIZE(valid_class_member); i++) { - SET_EXPECT(OnScriptError); /* Wine wrongly rejects the script; tolerate the error callback */ hres = parse_script_wr(valid_class_member[i]); - todo_wine ok(hres == S_OK, "[%u] class member parse returned %08lx\n", i, hres); - CLEAR_CALLED(OnScriptError); + ok(hres == S_OK, "[%u] class member parse returned %08lx\n", i, hres); } } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11008
This fix is important as a lot of tables do this: ie: ``` Class DebugLogFile Public Sub LogInit() End Sub . . Dim LogInit:LogInit=False ``` -- https://gitlab.winehq.org/wine/wine/-/merge_requests/11008#note_141438
@jacek this is a regression introduced by !10464 and !10965 -- https://gitlab.winehq.org/wine/wine/-/merge_requests/11008#note_141439
This merge request was approved by Jacek Caban. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/11008
participants (4)
-
Francis De Brabandere -
Francis De Brabandere (@francisdb) -
Jacek Caban (@jacek) -
Jason Millard (@jsm174)