Module: wine Branch: master Commit: 909943a6ccc2e20e3925b91388a97e39a839117b URL: https://gitlab.winehq.org/wine/wine/-/commit/909943a6ccc2e20e3925b91388a97e3...
Author: Jacek Caban jacek@codeweavers.com Date: Thu Jun 27 20:38:18 2024 +0200
jscript: Introduce HostObject implementation.
---
dlls/jscript/dispex.c | 104 ++++++++++++++++++++++++++++++++++++++++++++ dlls/jscript/jscript.c | 42 ++++++++++++++++++ dlls/jscript/jscript.h | 1 + dlls/jscript/jscript_main.c | 1 + dlls/jscript/jsdisp.idl | 25 +++++++++++ 5 files changed, 173 insertions(+)
diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c index 911b3ab1d73..b684b9edd99 100644 --- a/dlls/jscript/dispex.c +++ b/dlls/jscript/dispex.c @@ -3273,3 +3273,107 @@ HRESULT jsdisp_get_prop_name(jsdisp_t *obj, DISPID id, jsstr_t **r) *r = jsstr_alloc(prop->name); return *r ? S_OK : E_OUTOFMEMORY; } + +typedef struct { + jsdisp_t jsdisp; + IWineJSDispatchHost *host_iface; +} HostObject; + +static inline HostObject *HostObject_from_jsdisp(jsdisp_t *jsdisp) +{ + return CONTAINING_RECORD(jsdisp, HostObject, jsdisp); +} + +static ULONG HostObject_addref(jsdisp_t *jsdisp) +{ + HostObject *This = HostObject_from_jsdisp(jsdisp); + return IWineJSDispatchHost_AddRef(This->host_iface); +} + +static ULONG HostObject_release(jsdisp_t *jsdisp) +{ + HostObject *This = HostObject_from_jsdisp(jsdisp); + return IWineJSDispatchHost_Release(This->host_iface); +} + +static HRESULT HostObject_lookup_prop(jsdisp_t *jsdisp, const WCHAR *name, unsigned flags, struct property_info *desc) +{ + HostObject *This = HostObject_from_jsdisp(jsdisp); + + return IWineJSDispatchHost_LookupProperty(This->host_iface, name, flags, desc); +} + +static HRESULT HostObject_prop_get(jsdisp_t *jsdisp, unsigned idx, jsval_t *r) +{ + HostObject *This = HostObject_from_jsdisp(jsdisp); + EXCEPINFO ei = { 0 }; + VARIANT v; + HRESULT hres; + + V_VT(&v) = VT_EMPTY; + hres = IWineJSDispatchHost_GetProperty(This->host_iface, idx, jsdisp->ctx->lcid, &v, &ei, + &jsdisp->ctx->jscaller->IServiceProvider_iface); + if(hres == DISP_E_EXCEPTION) + handle_dispatch_exception(jsdisp->ctx, &ei); + if(FAILED(hres)) + return hres; + + hres = variant_to_jsval(jsdisp->ctx, &v, r); + VariantClear(&v); + return hres; +} + +static HRESULT HostObject_prop_put(jsdisp_t *jsdisp, unsigned idx, jsval_t v) +{ + HostObject *This = HostObject_from_jsdisp(jsdisp); + EXCEPINFO ei = { 0 }; + VARIANT var; + HRESULT hres; + + hres = jsval_to_variant(v, &var); + if(FAILED(hres)) + return hres; + + hres = IWineJSDispatchHost_SetProperty(This->host_iface, idx, jsdisp->ctx->lcid, &var, &ei, + &jsdisp->ctx->jscaller->IServiceProvider_iface); + if(hres == DISP_E_EXCEPTION) + handle_dispatch_exception(jsdisp->ctx, &ei); + VariantClear(&var); + return hres; +} + +static HRESULT HostObject_next_prop(jsdisp_t *jsdisp, unsigned id, struct property_info *desc) +{ + HostObject *This = HostObject_from_jsdisp(jsdisp); + + return IWineJSDispatchHost_NextProperty(This->host_iface, id, desc); +} + +static const builtin_info_t HostObject_info = { + .class = JSCLASS_OBJECT, + .addref = HostObject_addref, + .release = HostObject_release, + .lookup_prop = HostObject_lookup_prop, + .prop_get = HostObject_prop_get, + .prop_put = HostObject_prop_put, + .next_prop = HostObject_next_prop, +}; + +HRESULT init_host_object(script_ctx_t *ctx, IWineJSDispatchHost *host_iface, IWineJSDispatch **ret) +{ + HostObject *host_obj; + HRESULT hres; + + if(!(host_obj = calloc(1, sizeof(*host_obj)))) + return E_OUTOFMEMORY; + + hres = init_dispex(&host_obj->jsdisp, ctx, &HostObject_info, ctx->object_prototype); + if(FAILED(hres)) { + free(host_obj); + return hres; + } + + host_obj->host_iface = host_iface; + *ret = &host_obj->jsdisp.IWineJSDispatch_iface; + return S_OK; +} diff --git a/dlls/jscript/jscript.c b/dlls/jscript/jscript.c index fc07c818edf..4d53e8a6832 100644 --- a/dlls/jscript/jscript.c +++ b/dlls/jscript/jscript.c @@ -47,6 +47,7 @@ typedef struct { IActiveScriptProperty IActiveScriptProperty_iface; IObjectSafety IObjectSafety_iface; IVariantChangeType IVariantChangeType_iface; + IWineJScript IWineJScript_iface;
LONG ref;
@@ -669,6 +670,9 @@ static HRESULT WINAPI JScript_QueryInterface(IActiveScript *iface, REFIID riid, }else if(IsEqualGUID(riid, &IID_IVariantChangeType)) { TRACE("(%p)->(IID_IVariantChangeType %p)\n", This, ppv); *ppv = &This->IVariantChangeType_iface; + }else if(IsEqualGUID(riid, &IID_IWineJScript)) { + TRACE("(%p)->(IID_IWineJScript %p)\n", This, ppv); + *ppv = &This->IWineJScript_iface; }
if(*ppv) { @@ -1424,6 +1428,43 @@ static const IVariantChangeTypeVtbl VariantChangeTypeVtbl = { VariantChangeType_ChangeType };
+static inline JScript *impl_from_IWineJScript(IWineJScript *iface) +{ + return CONTAINING_RECORD(iface, JScript, IWineJScript_iface); +} + +static HRESULT WINAPI WineJScript_QueryInterface(IWineJScript *iface, REFIID riid, void **ppv) +{ + JScript *This = impl_from_IWineJScript(iface); + return IActiveScript_QueryInterface(&This->IActiveScript_iface, riid, ppv); +} + +static ULONG WINAPI WineJScript_AddRef(IWineJScript *iface) +{ + JScript *This = impl_from_IWineJScript(iface); + return IActiveScript_AddRef(&This->IActiveScript_iface); +} + +static ULONG WINAPI WineJScript_Release(IWineJScript *iface) +{ + JScript *This = impl_from_IWineJScript(iface); + return IActiveScript_Release(&This->IActiveScript_iface); +} + +static HRESULT WINAPI WineJScript_InitHostObject(IWineJScript *iface, IWineJSDispatchHost *host_obj, + IWineJSDispatch **ret) +{ + JScript *This = impl_from_IWineJScript(iface); + return init_host_object(This->ctx, host_obj, ret); +} + +static const IWineJScriptVtbl WineJScriptVtbl = { + WineJScript_QueryInterface, + WineJScript_AddRef, + WineJScript_Release, + WineJScript_InitHostObject, +}; + HRESULT create_jscript_object(BOOL is_encode, REFIID riid, void **ppv) { JScript *ret; @@ -1441,6 +1482,7 @@ HRESULT create_jscript_object(BOOL is_encode, REFIID riid, void **ppv) ret->IActiveScriptProperty_iface.lpVtbl = &JScriptPropertyVtbl; ret->IObjectSafety_iface.lpVtbl = &JScriptSafetyVtbl; ret->IVariantChangeType_iface.lpVtbl = &VariantChangeTypeVtbl; + ret->IWineJScript_iface.lpVtbl = &WineJScriptVtbl; ret->ref = 1; ret->safeopt = INTERFACE_USES_DISPEX; ret->is_encode = is_encode; diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h index 9454d9e3beb..29dec3297ca 100644 --- a/dlls/jscript/jscript.h +++ b/dlls/jscript/jscript.h @@ -237,6 +237,7 @@ enum jsdisp_enum_type { HRESULT create_dispex(script_ctx_t*,const builtin_info_t*,jsdisp_t*,jsdisp_t**); HRESULT init_dispex(jsdisp_t*,script_ctx_t*,const builtin_info_t*,jsdisp_t*); HRESULT init_dispex_from_constr(jsdisp_t*,script_ctx_t*,const builtin_info_t*,jsdisp_t*); +HRESULT init_host_object(script_ctx_t*,IWineJSDispatchHost*,IWineJSDispatch**);
HRESULT disp_call(script_ctx_t*,IDispatch*,DISPID,WORD,unsigned,jsval_t*,jsval_t*); HRESULT disp_call_name(script_ctx_t*,IDispatch*,const WCHAR*,WORD,unsigned,jsval_t*,jsval_t*); diff --git a/dlls/jscript/jscript_main.c b/dlls/jscript/jscript_main.c index ecbb5a713ab..6ccab362051 100644 --- a/dlls/jscript/jscript_main.c +++ b/dlls/jscript/jscript_main.c @@ -27,6 +27,7 @@ #include "mshtmhst.h" #include "rpcproxy.h" #include "jscript_classes.h" +#include "jsdisp.h"
#include "wine/debug.h"
diff --git a/dlls/jscript/jsdisp.idl b/dlls/jscript/jsdisp.idl index f053149c144..a794dbebe67 100644 --- a/dlls/jscript/jsdisp.idl +++ b/dlls/jscript/jsdisp.idl @@ -42,3 +42,28 @@ interface IWineJSDispatch : IDispatchEx { void Free(); } + +[ + object, + uuid(b1ebc544-6644-40c6-97f6-ccd9cc32bfba), + local +] +interface IWineJSDispatchHost : IDispatchEx +{ + HRESULT GetJSDispatch(IWineJSDispatch **ret); + HRESULT LookupProperty(const WCHAR *name, DWORD flags, struct property_info *desc); + HRESULT NextProperty(DISPID id, struct property_info *desc); + HRESULT GetProperty(DISPID id, LCID lcid, VARIANT *r, EXCEPINFO *ei, IServiceProvider *caller); + HRESULT SetProperty(DISPID id, LCID lcid, VARIANT *v, EXCEPINFO *ei, IServiceProvider *caller); + HRESULT CallFunction(DISPID id, UINT32 iid, DISPPARAMS *dp, VARIANT *ret, EXCEPINFO *ei, IServiceProvider *caller); +} + +[ + object, + uuid(d359f2fe-5531-741b-a41a-5cf92edc971d), + local +] +interface IWineJScript : IUnknown +{ + HRESULT InitHostObject(IWineJSDispatchHost *host_obj, IWineJSDispatch **ret); +}