[Bug 54221] New: vbscript: missing support for GetRef
https://bugs.winehq.org/show_bug.cgi?id=54221 Bug ID: 54221 Summary: vbscript: missing support for GetRef Product: Wine Version: unspecified Hardware: x86-64 OS: Linux Status: UNCONFIRMED Severity: normal Priority: P2 Component: vbscript Assignee: wine-bugs(a)winehq.org Reporter: jsm174(a)gmail.com Distribution: --- While working on porting Visual Pinball to cross platform, many table scripts use "GetRef". I tried to implement this by returning the script dispatch interface, but I realize this is wrong as "GetRef" is supposed to return a reference to a function. Does anyone have any suggestions on what would need to be returned, and I can work on creating a patch. -- Do not reply to this email, post in Bugzilla using the above URL to reply. You are receiving this mail because: You are watching all bug changes.
https://bugs.winehq.org/show_bug.cgi?id=54221 --- Comment #1 from Jason Millard <jsm174(a)gmail.com> --- static HRESULT Global_GetRef(BuiltinDisp *This, VARIANT *arg, unsigned args_cnt, VARIANT *res) { BSTR str; HRESULT hres; hres = to_string(arg, &str); function_t **funcs = This->ctx->script_obj->global_funcs; size_t i, cnt = This->ctx->script_obj->global_funcs_cnt; for(i = 0; i < cnt; i++) { if(!wcsicmp(funcs[i]->name, str)) { // ? return S_OK; } } return E_FAIL; } -- Do not reply to this email, post in Bugzilla using the above URL to reply. You are receiving this mail because: You are watching all bug changes.
https://bugs.winehq.org/show_bug.cgi?id=54221 --- Comment #2 from Nikolay Sivov <bunglehead(a)gmail.com> --- This should be testable. What does it return, VT_DISPATCH? You could probably inspect that value using some test host method, to pass GetRef() result out of the script. -- Do not reply to this email, post in Bugzilla using the above URL to reply. You are receiving this mail because: You are watching all bug changes.
https://bugs.winehq.org/show_bug.cgi?id=54221 --- Comment #3 from Jason Millard <jsm174(a)gmail.com> --- It needs to point to a function or subroutine in the script. Would that be a VT_DISPATCH? -- Do not reply to this email, post in Bugzilla using the above URL to reply. You are receiving this mail because: You are watching all bug changes.
https://bugs.winehq.org/show_bug.cgi?id=54221 --- Comment #4 from Nikolay Sivov <bunglehead(a)gmail.com> --- (In reply to Jason Millard from comment #3)
It needs to point to a function or subroutine in the script. Would that be a VT_DISPATCH?
I don't know, but I suspect GetRef() result is still a variant like everything else. If that's a case, there is no need to guess - you can use getVT() and see what happens. -- Do not reply to this email, post in Bugzilla using the above URL to reply. You are receiving this mail because: You are watching all bug changes.
https://bugs.winehq.org/show_bug.cgi?id=54221 --- Comment #5 from Jason Millard <jsm174(a)gmail.com> --- Ok. I will keep plugging away. Just trying to figure out where the mapping to a function comes in to play. Like a dispatch to a aliased dispid. (Sorry that I’m not explaining this well) -- Do not reply to this email, post in Bugzilla using the above URL to reply. You are receiving this mail because: You are watching all bug changes.
https://bugs.winehq.org/show_bug.cgi?id=54221 --- Comment #6 from Nikolay Sivov <bunglehead(a)gmail.com> --- Like I said, what I would do is to pass a return value from GetRef() to some host function, and inspect what you get. If it's a dispatch, you can inspect its typeinfo. -- Do not reply to this email, post in Bugzilla using the above URL to reply. You are receiving this mail because: You are watching all bug changes.
https://bugs.winehq.org/show_bug.cgi?id=54221 --- Comment #7 from Jason Millard <jsm174(a)gmail.com> --- Sorry, it took me a while to understand what you were telling me. In windows, I did this: m_pScript->SetScriptState(SCRIPTSTATE_CONNECTED); EXCEPINFO exception = {}; VARIANT var; WCHAR* wzText = new WCHAR[1024]; swprintf_s(wzText, 1024, L"GetRef(\"Table1_KeyDown\")"); m_pScriptParse->ParseScriptText(wzText, 0, 0, 0, CONTEXTCOOKIE_NORMAL, 0, SCRIPTTEXT_ISEXPRESSION, &var, &exception); Looking at var it's definitely a dispatch into vbscript.dll I tried to look at the typeinfo with: IDispatch* disp = V_DISPATCH(&var); ITypeInfo* ti; HRESULT hr = disp->GetTypeInfo(0, LOCALE_USER_DEFAULT, &ti); but HR comes back with DISP_E_BADINDEX -- Do not reply to this email, post in Bugzilla using the above URL to reply. You are receiving this mail because: You are watching all bug changes.
https://bugs.winehq.org/show_bug.cgi?id=54221 --- Comment #8 from Nikolay Sivov <bunglehead(a)gmail.com> --- We have some code in vbdisp.c that looks related and good start to figure out how this works. -- Do not reply to this email, post in Bugzilla using the above URL to reply. You are receiving this mail because: You are watching all bug changes.
https://bugs.winehq.org/show_bug.cgi?id=54221 --- Comment #9 from Jason Millard <jsm174(a)gmail.com> --- (In reply to Nikolay Sivov from comment #8)
We have some code in vbdisp.c that looks related and good start to figure out how this works.
Okay, I will dig in. This is where I'm at now: static HRESULT Global_GetRef(BuiltinDisp *This, VARIANT *arg, unsigned args_cnt, VARIANT *res) { BSTR str; HRESULT hres; hres = to_string(arg, &str); if(FAILED(hres)) return hres; function_t **funcs = This->ctx->script_obj->global_funcs; size_t i, cnt = This->ctx->script_obj->global_funcs_cnt; for(i = 0; i < cnt; i++) { if(!wcsicmp(funcs[i]->name, str)) { IDispatch* disp = (IDispatch*) &This->ctx->script_obj->IDispatchEx_iface; DISPID dispid; hres = disp->lpVtbl->GetIDsOfNames(disp, 0, (LPOLESTR*)&funcs[i]->name, 1, 0, &dispid); if(FAILED(hres)) return hres; V_VT(res) = VT_DISPATCH; V_DISPATCH(res) = disp; IDispatch_AddRef(disp); return hres; } } return DISP_E_UNKNOWNNAME; } -- Do not reply to this email, post in Bugzilla using the above URL to reply. You are receiving this mail because: You are watching all bug changes.
https://bugs.winehq.org/show_bug.cgi?id=54221 --- Comment #10 from Jason Millard <jsm174(a)gmail.com> --- So this is probably the worst hack ever, but I leveraged VARIANT's wReserved2 to store the function index. static HRESULT Global_GetRef(BuiltinDisp *This, VARIANT *arg, unsigned args_cnt, VARIANT *res) { BSTR str; HRESULT hres; hres = to_string(arg, &str); if(FAILED(hres)) return hres; function_t **funcs = This->ctx->script_obj->global_funcs; size_t i, cnt = This->ctx->script_obj->global_funcs_cnt; for(i = 0; i < cnt; i++) { if(!wcsicmp(funcs[i]->name, str)) { IDispatch* disp = (IDispatch*) &This->ctx->script_obj->IDispatchEx_iface; DISPID dispid; hres = disp->lpVtbl->GetIDsOfNames(disp, 0, (LPOLESTR*)&funcs[i]->name, 1, 0, &dispid); if(FAILED(hres)) return hres; V_VT(res) = VT_DISPATCH; V_DISPATCH(res) = disp; res->n1.n2.wReserved1 = 0xFF; res->n1.n2.wReserved2 = i; IDispatch_AddRef(disp); return hres; } } return DISP_E_UNKNOWNNAME; } Then in do_icall: static HRESULT do_icall(exec_ctx_t *ctx, VARIANT *res, BSTR identifier, unsigned arg_cnt) { DISPPARAMS dp; ref_t ref; HRESULT hres; TRACE("%s %u\n", debugstr_w(identifier), arg_cnt); hres = lookup_identifier(ctx, identifier, VBDISP_CALLGET, &ref); if(FAILED(hres)) return hres; switch(ref.type) { case REF_VAR: case REF_CONST: if (V_VT(ref.u.v) == VT_DISPATCH && ref.u.v->n1.n2.wReserved1 == 0xFF) { vbstack_to_dp(ctx, arg_cnt, FALSE, &dp); ref.type = REF_FUNC; ref.u.f = ctx->script->script_obj->global_funcs[ref.u.v->n1.n2.wReserved2]; hres = exec_script(ctx->script, FALSE, ref.u.f, NULL, &dp, res); if(FAILED(hres)) return hres; break; } if(arg_cnt) return variant_call(ctx, ref.u.v, arg_cnt, res); This allows the following code to work: Sub test Debug.print "test call" End Sub Dim funcAlias set funcAlias = GetRef("test") If Not IsObject(GetRef("test")) Then Debug.print "getref test not object" funcAlias -- Do not reply to this email, post in Bugzilla using the above URL to reply. You are receiving this mail because: You are watching all bug changes.
participants (1)
-
WineHQ Bugzilla