-- v2: mshtml: Get rid of the unused js_flags field. mshtml: Set the name of the non-function constructors to the same as
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/dispex.c | 47 ++++++++++++++++++++++--------- dlls/mshtml/mshtml_private.h | 1 + dlls/mshtml/tests/documentmode.js | 6 ++++ dlls/mshtml/tests/es5.js | 1 - 4 files changed, 41 insertions(+), 14 deletions(-)
diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c index f69f1fe242c..fcfbfc7561a 100644 --- a/dlls/mshtml/dispex.c +++ b/dlls/mshtml/dispex.c @@ -1895,10 +1895,15 @@ static void init_host_object(DispatchEx *dispex, HTMLInnerWindow *script_global, return; hres = IWineJScript_InitHostConstructor(script_global->jscript, &dispex->IWineJSDispatchHost_iface, prototype->jsdisp, &dispex->jsdisp); - }else + }else { + UINT32 js_flags = 0; + + if(dispex->info == dispex->info->desc->constructor_info[dispex->info->compat_mode - COMPAT_MODE_IE9]) + js_flags |= HOSTOBJ_CONSTRUCTOR; + hres = IWineJScript_InitHostObject(script_global->jscript, &dispex->IWineJSDispatchHost_iface, - prototype ? prototype->jsdisp : NULL, - dispex->info->desc->js_flags, &dispex->jsdisp); + prototype ? prototype->jsdisp : NULL, js_flags, &dispex->jsdisp); + } if(FAILED(hres)) ERR("Failed to initialize jsdisp: %08lx\n", hres); } @@ -3072,39 +3077,55 @@ static const dispex_static_data_vtbl_t constructor_dispex_vtbl = { };
static dispex_static_data_t constructor_dispex = { - .name = "Constructor", .vtbl = &constructor_dispex_vtbl, - .js_flags = HOSTOBJ_CONSTRUCTOR, };
HRESULT get_constructor(HTMLInnerWindow *script_global, prototype_id_t id, DispatchEx **ret) { - dispex_static_data_t *info; + compat_mode_t compat_mode = script_global->doc->document_mode; + dispex_static_data_t *desc; + dispex_data_t *info;
- assert(script_global->doc->document_mode >= COMPAT_MODE_IE9); + assert(compat_mode >= COMPAT_MODE_IE9);
if(script_global->constructors[id]) { *ret = script_global->constructors[id]; return S_OK; }
- info = object_descriptors[id]; - if(info->init_constructor) { - HRESULT hres = info->init_constructor(script_global, &script_global->constructors[id]); + desc = object_descriptors[id]; + if(desc->init_constructor) { + HRESULT hres = desc->init_constructor(script_global, &script_global->constructors[id]); if(FAILED(hres)) return hres; }else { struct constructor *constr; + + info = desc->constructor_info[compat_mode - COMPAT_MODE_IE9]; + if(!info) { + EnterCriticalSection(&cs_dispex_static_data); + info = desc->constructor_info[compat_mode - COMPAT_MODE_IE9]; + if(!info) { + info = preprocess_dispex_data(&constructor_dispex, compat_mode, FALSE); + if(info) { + info->name = desc->name; + info->desc = desc; + desc->constructor_info[compat_mode - COMPAT_MODE_IE9] = info; + } + } + LeaveCriticalSection(&cs_dispex_static_data); + if(!info) + return E_OUTOFMEMORY; + } + if(!(constr = calloc(sizeof(*constr), 1))) return E_OUTOFMEMORY;
- init_dispatch(&constr->dispex, &constructor_dispex, script_global, - dispex_compat_mode(&script_global->event_target.dispex)); + init_dispatch_from_desc(&constr->dispex, info, script_global, NULL); constr->id = id; script_global->constructors[id] = &constr->dispex; }
*ret = script_global->constructors[id]; return S_OK; - } diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 11ee0afd3c7..9e5d7ba5240 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -514,6 +514,7 @@ typedef struct { HRESULT (*init_constructor)(HTMLInnerWindow*,DispatchEx**); dispex_data_t *info_cache[COMPAT_MODE_CNT]; dispex_data_t *prototype_info[COMPAT_MODE_CNT - COMPAT_MODE_IE9]; + dispex_data_t *constructor_info[COMPAT_MODE_CNT - COMPAT_MODE_IE9]; dispex_data_t *delayed_init_info; prototype_id_t id; prototype_id_t prototype_id; diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index 9f62ca68f1d..fea12ce1f1a 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -353,6 +353,12 @@ sync_test("builtin_toString", function() { test("SVGSVGElement", document.createElementNS(svg_ns, "svg"), "SVGSVGElement"); test("SVGCircleElement", document.createElementNS(svg_ns, "circle"), "SVGCircleElement"); test("SVGCircleElement", document.createElementNS(svg_ns, "tspan"), "SVGTSpanElement"); + + /* Non-function constructors */ + var props = Object.getOwnPropertyNames(window); + for(i = 0; i < props.length; i++) + if(typeof(window[props[i]]) === "object" && window[props[i]].hasOwnProperty("prototype")) + test(props[i] + " constructor", window[props[i]], props[i]); } });
diff --git a/dlls/mshtml/tests/es5.js b/dlls/mshtml/tests/es5.js index 0033a06fa3c..e15e3f379cd 100644 --- a/dlls/mshtml/tests/es5.js +++ b/dlls/mshtml/tests/es5.js @@ -2907,7 +2907,6 @@ sync_test("prototypes", function() { test_own_data_prop_desc(window, "DOMImplementation", true, false, true); ok(Object.getPrototypeOf(DOMImplementation) === Object.prototype, "Object.getPrototypeOf(DOMImplementation) = " + Object.getPrototypeOf(DOMImplementation)); - todo_wine. ok(DOMImplementation == "[object DOMImplementation]", "DOMImplementation = " + DOMImplementation);
var proto = constr.prototype;
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/mshtml_private.h | 1 - dlls/mshtml/script.c | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-)
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 9e5d7ba5240..1eb20796143 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -519,7 +519,6 @@ typedef struct { prototype_id_t id; prototype_id_t prototype_id; prototype_id_t constructor_id; - UINT32 js_flags; compat_mode_t min_compat_mode; compat_mode_t max_compat_mode; char prototype_name[64]; diff --git a/dlls/mshtml/script.c b/dlls/mshtml/script.c index 3ad1da8cf3c..4fd6136fefd 100644 --- a/dlls/mshtml/script.c +++ b/dlls/mshtml/script.c @@ -214,8 +214,7 @@ static BOOL init_script_engine(ScriptHost *script_host, IActiveScript *script) if(SUCCEEDED(hres)) hres = IWineJScript_InitHostObject(jscript, &script_host->window->event_target.dispex.IWineJSDispatchHost_iface, - prototype->jsdisp, object_descriptors[PROT_Window]->js_flags, - &script_host->window->event_target.dispex.jsdisp); + prototype->jsdisp, 0, &script_host->window->event_target.dispex.jsdisp); if(FAILED(hres)) ERR("Could not initialize script global: %08lx\n", hres);
Jacek Caban (@jacek) commented about dlls/mshtml/mshtml_private.h:
HRESULT (*init_constructor)(HTMLInnerWindow*,DispatchEx**); dispex_data_t *info_cache[COMPAT_MODE_CNT]; dispex_data_t *prototype_info[COMPAT_MODE_CNT - COMPAT_MODE_IE9];
- dispex_data_t *constructor_info[COMPAT_MODE_CNT - COMPAT_MODE_IE9];
Do we need it for something other than the name? For the name, it seems much easier to add `get_name()` to `dispex_static_data_vtbl_t` and just use it in `dispex_to_string`. It wouldn't cover debug traces, but that that may be even an advantage.
On Thu Nov 21 20:05:30 2024 +0000, Jacek Caban wrote:
Do we need it for something other than the name? For the name, it seems much easier to add `get_name()` to `dispex_static_data_vtbl_t` and just use it in `dispex_to_string`. It wouldn't cover debug traces, but that that may be even an advantage.
It's only for the name, yeah. I thought it would be either too much work or a hack because of traces, but I don't have too strong preference there, so if you are fine with it I can do that.
On Thu Nov 21 21:19:51 2024 +0000, Gabriel Ivăncescu wrote:
It's only for the name, yeah. I thought it would be either too much work or a hack because of traces, but I don't have too strong preference there, so if you are fine with it I can do that.
I think that leaving traces alone is fine. Having "Constructor" for traces seems beneficial, otherwise it would be easy to misinterpret logs if constructors and instances use the same name.