From: Jacek Caban jacek@codeweavers.com
--- dlls/jscript/dispex.c | 5 ++++- dlls/jscript/engine.c | 2 +- dlls/jscript/jscript.c | 4 ++-- dlls/jscript/jscript.h | 3 ++- dlls/jscript/jsdisp.idl | 4 +++- dlls/mshtml/dispex.c | 8 +++++--- dlls/mshtml/mshtml_private.h | 1 + dlls/mshtml/script.c | 3 +-- dlls/mshtml/tests/es5.js | 2 ++ 9 files changed, 21 insertions(+), 11 deletions(-)
diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c index eec8bf7c1e9..a99f09776e2 100644 --- a/dlls/jscript/dispex.c +++ b/dlls/jscript/dispex.c @@ -2413,6 +2413,7 @@ HRESULT init_dispex(jsdisp_t *dispex, script_ctx_t *ctx, const builtin_info_t *b dispex->ref = 1; dispex->builtin_info = builtin_info; dispex->extensible = TRUE; + dispex->is_constructor = builtin_info->class == JSCLASS_FUNCTION; dispex->prop_cnt = 0;
dispex->props = calloc(1, sizeof(dispex_prop_t)*(dispex->buf_size=4)); @@ -3496,7 +3497,7 @@ static const builtin_info_t HostObject_info = { };
HRESULT init_host_object(script_ctx_t *ctx, IWineJSDispatchHost *host_iface, IWineJSDispatch *prototype_iface, - IWineJSDispatch **ret) + UINT32 flags, IWineJSDispatch **ret) { HostObject *host_obj; jsdisp_t *prototype; @@ -3516,6 +3517,8 @@ HRESULT init_host_object(script_ctx_t *ctx, IWineJSDispatchHost *host_iface, IWi }
host_obj->host_iface = host_iface; + if(flags & HOSTOBJ_CONSTRUCTOR) + host_obj->jsdisp.is_constructor = TRUE; *ret = &host_obj->jsdisp.IWineJSDispatch_iface; return S_OK; } diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c index 12e53435f16..ca662ae99ff 100644 --- a/dlls/jscript/engine.c +++ b/dlls/jscript/engine.c @@ -2027,7 +2027,7 @@ static HRESULT interp_instanceof(script_ctx_t *ctx) return E_FAIL; }
- if(is_class(obj, JSCLASS_FUNCTION)) { + if(obj->is_constructor) { hres = jsdisp_propget_name(obj, L"prototype", &prot); }else { hres = JS_E_FUNCTION_EXPECTED; diff --git a/dlls/jscript/jscript.c b/dlls/jscript/jscript.c index fac025366e9..5822cf1222f 100644 --- a/dlls/jscript/jscript.c +++ b/dlls/jscript/jscript.c @@ -1452,10 +1452,10 @@ static ULONG WINAPI WineJScript_Release(IWineJScript *iface) }
static HRESULT WINAPI WineJScript_InitHostObject(IWineJScript *iface, IWineJSDispatchHost *host_obj, - IWineJSDispatch *prototype, IWineJSDispatch **ret) + IWineJSDispatch *prototype, UINT32 flags, IWineJSDispatch **ret) { JScript *This = impl_from_IWineJScript(iface); - return init_host_object(This->ctx, host_obj, prototype, ret); + return init_host_object(This->ctx, host_obj, prototype, flags, ret); }
static const IWineJScriptVtbl WineJScriptVtbl = { diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h index 3691ca562f8..5e3640b69b7 100644 --- a/dlls/jscript/jscript.h +++ b/dlls/jscript/jscript.h @@ -204,6 +204,7 @@ struct jsdisp_t { BOOLEAN has_weak_refs; BOOLEAN extensible; BOOLEAN gc_marked; + BOOLEAN is_constructor;
DWORD buf_size; DWORD prop_cnt; @@ -242,7 +243,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*,IWineJSDispatch**); +HRESULT init_host_object(script_ctx_t*,IWineJSDispatchHost*,IWineJSDispatch*,UINT32,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/jsdisp.idl b/dlls/jscript/jsdisp.idl index 35419178e97..a1b63579fce 100644 --- a/dlls/jscript/jsdisp.idl +++ b/dlls/jscript/jsdisp.idl @@ -36,6 +36,8 @@ const unsigned int PROPF_CONFIGURABLE = 0x1000;
const unsigned int PROPF_PUBLIC_MASK = PROPF_ENUMERABLE | PROPF_WRITABLE | PROPF_CONFIGURABLE;
+const unsigned int HOSTOBJ_CONSTRUCTOR = 0x0001; + interface IWineJSDispatchHost;
[ @@ -75,5 +77,5 @@ interface IWineJSDispatchHost : IDispatchEx ] interface IWineJScript : IUnknown { - HRESULT InitHostObject(IWineJSDispatchHost *host_obj, IWineJSDispatch *prototype, IWineJSDispatch **ret); + HRESULT InitHostObject(IWineJSDispatchHost *host_obj, IWineJSDispatch *prototype, UINT32 flags, IWineJSDispatch **ret); } diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c index 1cbb3388f87..1848fef01f2 100644 --- a/dlls/mshtml/dispex.c +++ b/dlls/mshtml/dispex.c @@ -1789,7 +1789,8 @@ static void init_host_object(DispatchEx *dispex, HTMLInnerWindow *script_global, initialize_script_global(script_global); if(script_global->jscript && !dispex->jsdisp) { hres = IWineJScript_InitHostObject(script_global->jscript, &dispex->IWineJSDispatchHost_iface, - prototype ? prototype->jsdisp : NULL, &dispex->jsdisp); + prototype ? prototype->jsdisp : NULL, + dispex->info->desc->js_flags, &dispex->jsdisp); if(FAILED(hres)) ERR("Failed to initialize jsdisp: %08lx\n", hres); } @@ -2888,8 +2889,9 @@ static const dispex_static_data_vtbl_t constructor_dispex_vtbl = { };
static dispex_static_data_t constructor_dispex = { - .name = "Constructor", - .vtbl = &constructor_dispex_vtbl, + .name = "Constructor", + .vtbl = &constructor_dispex_vtbl, + .js_flags = HOSTOBJ_CONSTRUCTOR, };
HRESULT get_constructor(HTMLInnerWindow *script_global, prototype_id_t id, DispatchEx **ret) diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 4f6b0bb11c0..ca8629b64ef 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -427,6 +427,7 @@ typedef struct { dispex_data_t *prototype_info[COMPAT_MODE_CNT - COMPAT_MODE_IE9]; dispex_data_t *delayed_init_info; prototype_id_t id; + UINT32 js_flags; char prototype_name[64]; } dispex_static_data_t;
diff --git a/dlls/mshtml/script.c b/dlls/mshtml/script.c index 2b6abe6d8e2..30571c15fff 100644 --- a/dlls/mshtml/script.c +++ b/dlls/mshtml/script.c @@ -209,8 +209,7 @@ static BOOL init_script_engine(ScriptHost *script_host, IActiveScript *script)
hres = IWineJScript_InitHostObject(jscript, &script_host->window->event_target.dispex.IWineJSDispatchHost_iface, - NULL, - &script_host->window->event_target.dispex.jsdisp); + NULL, 0, &script_host->window->event_target.dispex.jsdisp); if(FAILED(hres)) ERR("Could not initialize script global: %08lx\n", hres);
diff --git a/dlls/mshtml/tests/es5.js b/dlls/mshtml/tests/es5.js index 880b59a85ff..78b50a40ec6 100644 --- a/dlls/mshtml/tests/es5.js +++ b/dlls/mshtml/tests/es5.js @@ -2752,4 +2752,6 @@ sync_test("prototypes", function() { DOMImplementation = 1; ok(DOMImplementation === 1, "DOMImplementation = " + DOMImplementation + " expected 1"); DOMImplementation = constr; + + ok(document.implementation instanceof DOMImplementation, "document.implementation is not an instance of DOMImplementation"); });