From: Gabriel Ivăncescu gabrielopcode@gmail.com
They are actual stubs even on native (but avoid throwing when retrieving them, even if unused).
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/dispex.c | 62 +++++++++++++++++++++++++++++++ dlls/mshtml/tests/documentmode.js | 34 +++++++++++++++++ 2 files changed, 96 insertions(+)
diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c index 5cb51ccda2d..f1cbc0a186e 100644 --- a/dlls/mshtml/dispex.c +++ b/dlls/mshtml/dispex.c @@ -98,6 +98,11 @@ typedef struct { func_info_t *info; } func_disp_t;
+typedef struct { + DispatchEx dispex; + const WCHAR *name; +} stub_func_disp_t; + typedef struct { func_disp_t *func_obj; VARIANT val; @@ -927,6 +932,51 @@ static HRESULT format_func_disp_string(const WCHAR *name, IServiceProvider *call return S_OK; }
+static inline stub_func_disp_t *stub_func_disp_from_DispatchEx(DispatchEx *iface) +{ + return CONTAINING_RECORD(iface, stub_func_disp_t, dispex); +} + +static void stub_function_destructor(DispatchEx *dispex) +{ + stub_func_disp_t *This = stub_func_disp_from_DispatchEx(dispex); + free(This); +} + +static HRESULT stub_function_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *params, + VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller) +{ + stub_func_disp_t *This = stub_func_disp_from_DispatchEx(dispex); + HRESULT hres; + + switch(flags) { + case DISPATCH_METHOD|DISPATCH_PROPERTYGET: + if(!res) + return E_INVALIDARG; + /* fall through */ + case DISPATCH_METHOD: + return MSHTML_E_INVALID_PROPERTY; + case DISPATCH_PROPERTYGET: + hres = format_func_disp_string(This->name, caller, res); + break; + default: + FIXME("Unimplemented flags %x\n", flags); + hres = E_NOTIMPL; + } + + return hres; +} + +static const dispex_static_data_vtbl_t stub_function_dispex_vtbl = { + .destructor = stub_function_destructor, + .value = stub_function_value +}; + +static dispex_static_data_t stub_function_dispex = { + .name = "Function", + .vtbl = &stub_function_dispex_vtbl, +}; + static HRESULT function_apply(func_disp_t *func, DISPPARAMS *dp, LCID lcid, VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller) { IWineJSDispatchHost *this_iface; @@ -1124,6 +1174,18 @@ static HRESULT function_invoke(DispatchEx *dispex, DISPID id, LCID lcid, WORD fl /* fall through */ case DISPATCH_METHOD: return function_props[idx].invoke(This, params, lcid, res, ei, caller); + case DISPATCH_PROPERTYGET: { + stub_func_disp_t *disp = calloc(1, sizeof(stub_func_disp_t)); + + if(!disp) + return E_OUTOFMEMORY; + disp->name = function_props[idx].name; + init_dispatch_with_owner(&disp->dispex, &stub_function_dispex, This->obj); + + V_VT(res) = VT_DISPATCH; + V_DISPATCH(res) = (IDispatch*)&disp->dispex.IWineJSDispatchHost_iface; + break; + } default: return MSHTML_E_INVALID_PROPERTY; } diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index f967b36e562..20188f459dd 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -364,6 +364,8 @@ sync_test("builtin_obj", function() { if(v < 9) { ok(!(window instanceof Object), "window instance of Object"); ok(!(document instanceof Object), "document instance of Object"); + ok(!(f.apply instanceof Function), "f.apply instance of Function"); + ok(!(f.call instanceof Function), "f.call instance of Function"); ok(!("arguments" in f), "arguments in f"); ok(!("length" in f), "length in f"); e = 0; @@ -419,6 +421,38 @@ sync_test("builtin_obj", function() { elem1.click.apply(elem2, { length: -1 }); ok(false, "exception expected"); }catch(ex) {} + + if(v < 9) { + ok(!("call" in f.call), "call in f.call"); + ok(!("apply" in f.call), "apply in f.call"); + ok(!("call" in f.apply), "call in f.apply"); + ok(!("apply" in f.apply), "apply in f.apply"); + ok(f.call+"" === "\nfunction call() {\n [native code]\n}\n", "f.call = " + f.call); + ok(f.apply+"" === "\nfunction apply() {\n [native code]\n}\n", "f.apply = " + f.apply); + ok(external.getVT(f.call) === "VT_DISPATCH", "f.call not VT_DISPATCH"); + ok(external.getVT(f.apply) === "VT_DISPATCH", "f.apply not VT_DISPATCH"); + + ok(f.apply !== f.apply, "f.apply == f.apply"); + f = f.apply; + ok(!("arguments" in f), "arguments in f.apply"); + ok(!("length" in f), "length in f.apply"); + ok(!("call" in f), "call in f.apply"); + ok(!("apply" in f), "apply in f.apply"); + e = 0; + try { + f.toString(); + }catch(ex) { + e = ex.number; + } + ok(e === 0xa01b6 - 0x80000000, "[f.apply.toString] e = " + e); + e = 0; + try { + f(document, ["style"]); + }catch(ex) { + e = ex.number; + } + ok(e === 0xa01b6 - 0x80000000, "[f.apply() indirect] e = " + e); + } });
sync_test("elem_props", function() {