Delete only affects own properties.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/jscript/dispex.c | 5 +++++ dlls/jscript/tests/lang.js | 5 +++++ dlls/mshtml/tests/documentmode.js | 1 - 3 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c index e64a520..df81e1a 100644 --- a/dlls/jscript/dispex.c +++ b/dlls/jscript/dispex.c @@ -1621,6 +1621,11 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc
static HRESULT delete_prop(dispex_prop_t *prop, BOOL *ret) { + if(prop->type == PROP_PROTREF) { + *ret = TRUE; + return S_OK; + } + if(!(prop->flags & PROPF_CONFIGURABLE)) { *ret = FALSE; return S_OK; diff --git a/dlls/jscript/tests/lang.js b/dlls/jscript/tests/lang.js index 63aa669..f259c70 100644 --- a/dlls/jscript/tests/lang.js +++ b/dlls/jscript/tests/lang.js @@ -1565,6 +1565,11 @@ ok(arr["test1"] === true, "arr[test1] !== true"); ok(arr["test2"] === true, "arr[test2] !== true"); ok(arr["test3"] === true, "arr[test3] !== true");
+ok((delete inobj.test1) === true, "delete inobj.test1 returned false"); +ok(!("test1" in inobj), "test1 is still in inobj after delete"); +ok((delete inobj.test3) === true, "delete inobj.test3 returned false"); +ok("test3" in inobj, "test3 is not in inobj after delete"); + tmp = new Object(); tmp.test = false; ok((delete tmp.test) === true, "delete returned false"); diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index d5f33dd..041025c 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -1192,7 +1192,6 @@ sync_test("__proto__", function() { ok(obj.__proto__ === ctor.prototype, "obj.__proto__ !== ctor.prototype");
r = (delete x.__proto__); - todo_wine. ok(r, "delete x.__proto__ returned " + r); ok(Object.prototype.hasOwnProperty("__proto__"), "__proto__ is not a property of Object.prototype after delete"); r = Object.getPrototypeOf(x);
Convert them to PROP_DELETE if the referenced prop in the prototype chain doesn't exist anymore.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/jscript/dispex.c | 26 +++++++++++++++++++++++--- dlls/jscript/tests/lang.js | 2 ++ 2 files changed, 25 insertions(+), 3 deletions(-)
diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c index df81e1a..ad6623f 100644 --- a/dlls/jscript/dispex.c +++ b/dlls/jscript/dispex.c @@ -60,6 +60,24 @@ struct _dispex_prop_t { int bucket_next; };
+static void fix_protref_prop(jsdisp_t *jsdisp, dispex_prop_t *prop) +{ + DWORD ref; + + if(prop->type != PROP_PROTREF) + return; + ref = prop->u.ref; + + while((jsdisp = jsdisp->prototype)) { + if(ref >= jsdisp->prop_cnt || jsdisp->props[ref].type == PROP_DELETED) + break; + if(jsdisp->props[ref].type != PROP_PROTREF) + return; + ref = jsdisp->props[ref].u.ref; + } + prop->type = PROP_DELETED; +} + static inline DISPID prop_to_id(jsdisp_t *This, dispex_prop_t *prop) { return prop - This->props; @@ -67,10 +85,11 @@ static inline DISPID prop_to_id(jsdisp_t *This, dispex_prop_t *prop)
static inline dispex_prop_t *get_prop(jsdisp_t *This, DISPID id) { - if(id < 0 || id >= This->prop_cnt || This->props[id].type == PROP_DELETED) + if(id < 0 || id >= This->prop_cnt) return NULL; + fix_protref_prop(This, &This->props[id]);
- return This->props+id; + return This->props[id].type == PROP_DELETED ? NULL : &This->props[id]; }
static inline BOOL is_function_prop(dispex_prop_t *prop) @@ -284,6 +303,7 @@ static HRESULT find_prop_name_prot(jsdisp_t *This, unsigned hash, const WCHAR *n if(prop && prop->type==PROP_DELETED) { del = prop; } else if(prop) { + fix_protref_prop(This, prop); *ret = prop; return S_OK; } @@ -292,7 +312,7 @@ static HRESULT find_prop_name_prot(jsdisp_t *This, unsigned hash, const WCHAR *n hres = find_prop_name_prot(This->prototype, hash, name, &prop); if(FAILED(hres)) return hres; - if(prop) { + if(prop && prop->type != PROP_DELETED) { if(del) { del->type = PROP_PROTREF; del->u.ref = prop - This->prototype->props; diff --git a/dlls/jscript/tests/lang.js b/dlls/jscript/tests/lang.js index f259c70..e4f5882 100644 --- a/dlls/jscript/tests/lang.js +++ b/dlls/jscript/tests/lang.js @@ -1569,6 +1569,8 @@ ok((delete inobj.test1) === true, "delete inobj.test1 returned false"); ok(!("test1" in inobj), "test1 is still in inobj after delete"); ok((delete inobj.test3) === true, "delete inobj.test3 returned false"); ok("test3" in inobj, "test3 is not in inobj after delete"); +ok((delete forinTestObj.prototype.test3) === true, "delete forinTestObj.prototype.test3 returned false"); +ok(!("test3" in inobj), "test3 is still in inobj after delete on prototype");
tmp = new Object(); tmp.test = false;
Signed-off-by: Jacek Caban jacek@codeweavers.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/jscript/dispex.c | 2 +- dlls/mshtml/tests/es5.js | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c index ad6623f..8c0d84b 100644 --- a/dlls/jscript/dispex.c +++ b/dlls/jscript/dispex.c @@ -2555,7 +2555,7 @@ HRESULT jsdisp_define_property(jsdisp_t *obj, const WCHAR *name, property_desc_t if(FAILED(hres)) return hres;
- if((!prop || prop->type == PROP_DELETED) && !obj->extensible) + if((!prop || prop->type == PROP_DELETED || prop->type == PROP_PROTREF) && !obj->extensible) return throw_error(obj->ctx, JS_E_OBJECT_NONEXTENSIBLE, name);
if(!prop && !(prop = alloc_prop(obj, name, PROP_DELETED, 0))) diff --git a/dlls/mshtml/tests/es5.js b/dlls/mshtml/tests/es5.js index 81c06a4..ede9419 100644 --- a/dlls/mshtml/tests/es5.js +++ b/dlls/mshtml/tests/es5.js @@ -999,6 +999,12 @@ sync_test("preventExtensions", function() { ok(o.prop === 1, "o.prop = " + o.prop); r = Object.isExtensible(o); ok(r === false, "isExtensible(o) returned " + r); + try { + Object.defineProperty(o, "prop", { value: true }); + ok(false, "expected exception"); + }catch(e) { + ok(e.name === "TypeError", "got " + e.name + " exception"); + }
r = Object.isExtensible({}); ok(r === true, "isExtensible(o) returned " + r);
Signed-off-by: Jacek Caban jacek@codeweavers.com
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=102632
Your paranoid android.
=== w10pro64 (32 bit report) ===
mshtml: htmldoc.c:2541: Test failed: unexpected call UpdateUI htmldoc.c:2853: Test failed: unexpected call Exec_UPDATECOMMANDS
=== w1064_tsign (64 bit report) ===
mshtml: htmldoc.c:2541: Test failed: unexpected call UpdateUI htmldoc.c:2853: Test failed: unexpected call Exec_UPDATECOMMANDS htmldoc.c:350: Test failed: expected Exec_SETTITLE htmldoc.c:2859: Test failed: unexpected call Exec_SETTITLE
=== w7u_adm (32 bit report) ===
mshtml: script.c:624: Test failed: L"/index.html?es5.js:date_now: unexpected Date.now() result 1637779246857 expected 1637779246935"
IDX props are not configurable, thus they cannot be deleted, so it makes no sense to special-case them anyway.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/jscript/dispex.c | 13 ++++++++----- dlls/jscript/tests/lang.js | 7 +++++++ dlls/mshtml/tests/es5.js | 15 ++++++++++++++- 3 files changed, 29 insertions(+), 6 deletions(-)
diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c index 8c0d84b..5cf1e0a 100644 --- a/dlls/jscript/dispex.c +++ b/dlls/jscript/dispex.c @@ -1651,14 +1651,17 @@ static HRESULT delete_prop(dispex_prop_t *prop, BOOL *ret) return S_OK; }
- *ret = TRUE; /* FIXME: not exactly right */ + *ret = TRUE;
- if(prop->type == PROP_JSVAL) { + if(prop->type == PROP_JSVAL) jsval_release(prop->u.val); - prop->type = PROP_DELETED; + if(prop->type == PROP_ACCESSOR) { + if(prop->u.accessor.getter) + jsdisp_release(prop->u.accessor.getter); + if(prop->u.accessor.setter) + jsdisp_release(prop->u.accessor.setter); } - if(prop->type == PROP_ACCESSOR) - FIXME("not supported on accessor property\n"); + prop->type = PROP_DELETED; return S_OK; }
diff --git a/dlls/jscript/tests/lang.js b/dlls/jscript/tests/lang.js index e4f5882..23c9c79 100644 --- a/dlls/jscript/tests/lang.js +++ b/dlls/jscript/tests/lang.js @@ -1589,6 +1589,13 @@ ok((delete tmp["test"]) === true, "delete returned false"); ok(typeof(tmp.test) === "undefined", "tmp.test type = " + typeof(tmp.test)); ok(!("test" in tmp), "test is still in tmp after delete?");
+arr = [1, 2, 3]; +ok(arr.length === 3, "arr.length = " + arr.length); +ok((delete arr.length) === false, "delete arr.length returned true"); +ok("reverse" in arr, "reverse not in arr"); +ok((delete Array.prototype.reverse) === true, "delete Array.prototype.reverse returned false"); +ok(!("reverse" in arr), "reverse is still in arr after delete from prototype"); + tmp.testWith = true; with(tmp) ok(testWith === true, "testWith !== true"); diff --git a/dlls/mshtml/tests/es5.js b/dlls/mshtml/tests/es5.js index ede9419..58b0d43 100644 --- a/dlls/mshtml/tests/es5.js +++ b/dlls/mshtml/tests/es5.js @@ -342,7 +342,8 @@ sync_test("defineProperty", function() { }, set: function(v) { getsetprop_value = v; - } + }, + configurable: true }; Object.defineProperty(obj, "getsetprop", desc); test_accessor_prop_desc(obj, "getsetprop", desc); @@ -353,6 +354,9 @@ sync_test("defineProperty", function() { test_accessor_prop_desc(obj, "getsetprop", desc); ok(obj.getsetprop === 2, "getsetprop = " + obj.getsetprop);
+ ok((delete obj.getsetprop) === true, "delete getsetprop returned false"); + ok(!("getsetprop" in obj), "getsetprop still in obj after delete"); + Object.defineProperty(obj, "notConf", {writable: true, enumerable: true, configurable: false, value: 1}); test_own_data_prop_desc(obj, "notConf", true, true, false);
@@ -631,6 +635,15 @@ sync_test("property_definitions", function() { ok(obj[0] === 7, "obj.prop = " + obj[0]); });
+sync_test("string_idx", function() { + var s = "foobar"; + ok(s[0] === "f", "s[0] = " + s[0]); + ok(s[5] === "r", "s[5] = " + s[5]); + ok(s[6] === undefined, "s[6] = " + s[6]); + ok((delete s[0]) === false, "delete s[0] returned true"); + ok((delete s[6]) === true, "delete s[6] returned false"); +}); + sync_test("string_trim", function() { function test_trim(value, expected) { var r = String.prototype.trim.call(value);
Signed-off-by: Jacek Caban jacek@codeweavers.com
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=102633
Your paranoid android.
=== w8adm (32 bit report) ===
mshtml: events.c:1089: Test failed: unexpected call img_onerror events: Timeout
=== w10pro64 (32 bit report) ===
mshtml: htmldoc.c:2541: Test failed: unexpected call UpdateUI htmldoc.c:2853: Test failed: unexpected call Exec_UPDATECOMMANDS
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com ---
The check at the top of InvokeEx is there only temporarily for next patches, it will get removed and it will be clean once the value_prop is removed.
dlls/jscript/dispex.c | 16 ++++++- dlls/jscript/tests/run.c | 92 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+), 1 deletion(-)
diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c index 5cf1e0a..6e1463b 100644 --- a/dlls/jscript/dispex.c +++ b/dlls/jscript/dispex.c @@ -1572,6 +1572,8 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc TRACE("invalid id\n"); return DISP_E_MEMBERNOTFOUND; } + if(id == DISPID_VALUE && wFlags & (DISPATCH_PROPERTYGET | DISPATCH_PROPERTYPUT)) + prop = NULL;
enter_script(This->ctx, &ei);
@@ -1600,7 +1602,14 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc case DISPATCH_PROPERTYGET: { jsval_t r;
- hres = prop_get(This, prop, &r); + if(prop) + hres = prop_get(This, prop, &r); + else { + hres = to_primitive(This->ctx, jsval_obj(This), &r, NO_HINT); + if(hres == JS_E_TO_PRIMITIVE) + hres = DISP_E_MEMBERNOTFOUND; + } + if(SUCCEEDED(hres)) { hres = jsval_to_variant(r, pvarRes); jsval_release(r); @@ -1611,6 +1620,11 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc jsval_t val; DWORD i;
+ if(!prop) { + hres = DISP_E_MEMBERNOTFOUND; + break; + } + for(i=0; i < pdp->cNamedArgs; i++) { if(pdp->rgdispidNamedArgs[i] == DISPID_PROPERTYPUT) break; diff --git a/dlls/jscript/tests/run.c b/dlls/jscript/tests/run.c index ef0f39f..0e2f633 100644 --- a/dlls/jscript/tests/run.c +++ b/dlls/jscript/tests/run.c @@ -2789,6 +2789,8 @@ static void test_retval(void)
static void test_default_value(void) { + static DISPID propput_dispid = DISPID_PROPERTYPUT; + IActiveScript *script; DISPPARAMS dp = {0}; IDispatch *disp; VARIANT v; @@ -2806,9 +2808,99 @@ static void test_default_value(void) { ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v)); } + VariantClear(&v); + IDispatch_Release(disp); + + hres = parse_script_expr(L"var arr = [5]; arr.toString = function() {return "foo";}; arr.valueOf = function() {return 42;}; arr", &v, &script); + ok(hres == S_OK, "parse_script_expr failed: %08x\n", hres); + ok(V_VT(&v) == VT_DISPATCH, "V_VT(v) = %d\n", V_VT(&v)); + disp = V_DISPATCH(&v); + + V_VT(&v) = VT_EMPTY; + hres = IDispatch_Invoke(disp, DISPID_VALUE, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dp, &v, NULL, NULL); + ok(hres == S_OK, "Invoke failed: %08x\n", hres); + ok(V_VT(&v) == VT_I4, "V_VT(v) = %d\n", V_VT(&v)); + ok(V_I4(&v) == 42, "V_I4(v) = %s\n", wine_dbgstr_w(V_BSTR(&v))); + IDispatch_Release(disp); + close_script(script); + + hres = parse_script_expr(L"var arr = [5]; arr.toString = function() {return "foo";}; arr", &v, &script); + ok(hres == S_OK, "parse_script_expr failed: %08x\n", hres); + ok(V_VT(&v) == VT_DISPATCH, "V_VT(v) = %d\n", V_VT(&v)); + disp = V_DISPATCH(&v);
+ V_VT(&v) = VT_EMPTY; + hres = IDispatch_Invoke(disp, DISPID_VALUE, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dp, &v, NULL, NULL); + ok(hres == S_OK, "Invoke failed: %08x\n", hres); + ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v)); + ok(!lstrcmpW(V_BSTR(&v), L"foo"), "V_BSTR(v) = %s\n", wine_dbgstr_w(V_BSTR(&v))); VariantClear(&v); IDispatch_Release(disp); + close_script(script); + + hres = parse_script_expr(L"var arr = [5]; arr", &v, &script); + ok(hres == S_OK, "parse_script_expr failed: %08x\n", hres); + ok(V_VT(&v) == VT_DISPATCH, "V_VT(v) = %d\n", V_VT(&v)); + disp = V_DISPATCH(&v); + + V_VT(&v) = VT_EMPTY; + hres = IDispatch_Invoke(disp, DISPID_VALUE, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dp, &v, NULL, NULL); + ok(hres == S_OK, "Invoke failed: %08x\n", hres); + ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v)); + ok(!lstrcmpW(V_BSTR(&v), L"5"), "V_BSTR(v) = %s\n", wine_dbgstr_w(V_BSTR(&v))); + VariantClear(&v); + IDispatch_Release(disp); + close_script(script); + + hres = parse_script_expr(L"var obj = Object.prototype; delete obj.valueOf; obj", &v, &script); + ok(hres == S_OK, "parse_script_expr failed: %08x\n", hres); + ok(V_VT(&v) == VT_DISPATCH, "V_VT(v) = %d\n", V_VT(&v)); + disp = V_DISPATCH(&v); + + V_VT(&v) = VT_EMPTY; + hres = IDispatch_Invoke(disp, DISPID_VALUE, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dp, &v, NULL, NULL); + ok(hres == S_OK, "Invoke failed: %08x\n", hres); + ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v)); + ok(!lstrcmpW(V_BSTR(&v), L"[object Object]"), "V_BSTR(v) = %s\n", wine_dbgstr_w(V_BSTR(&v))); + VariantClear(&v); + IDispatch_Release(disp); + close_script(script); + + hres = parse_script_expr(L"var obj = Object.prototype; delete obj.toString; obj", &v, &script); + ok(hres == S_OK, "parse_script_expr failed: %08x\n", hres); + ok(V_VT(&v) == VT_DISPATCH, "V_VT(v) = %d\n", V_VT(&v)); + disp = V_DISPATCH(&v); + + V_VT(&v) = VT_EMPTY; + hres = IDispatch_Invoke(disp, DISPID_VALUE, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dp, &v, NULL, NULL); + ok(hres == DISP_E_MEMBERNOTFOUND, "Invoke failed: %08x\n", hres); + IDispatch_Release(disp); + close_script(script); + + hres = parse_script_expr(L"Object.prototype", &v, &script); + ok(hres == S_OK, "parse_script_expr failed: %08x\n", hres); + ok(V_VT(&v) == VT_DISPATCH, "V_VT(v) = %d\n", V_VT(&v)); + disp = V_DISPATCH(&v); + + dp.cArgs = dp.cNamedArgs = 1; + dp.rgdispidNamedArgs = &propput_dispid; + dp.rgvarg = &v; + V_VT(&v) = VT_EMPTY; + hres = IDispatch_Invoke(disp, DISPID_VALUE, &IID_NULL, 0, DISPATCH_PROPERTYPUT, &dp, NULL, NULL, NULL); + ok(hres == DISP_E_MEMBERNOTFOUND, "Invoke failed: %08x\n", hres); + IDispatch_Release(disp); + close_script(script); + + hres = parse_script_expr(L"var f = function() {return 42;}; f", &v, &script); + ok(hres == S_OK, "parse_script_expr failed: %08x\n", hres); + ok(V_VT(&v) == VT_DISPATCH, "V_VT(v) = %d\n", V_VT(&v)); + disp = V_DISPATCH(&v); + + V_VT(&v) = VT_EMPTY; + hres = IDispatch_Invoke(disp, DISPID_VALUE, &IID_NULL, 0, DISPATCH_PROPERTYPUT, &dp, NULL, NULL, NULL); + ok(hres == DISP_E_MEMBERNOTFOUND, "Invoke failed: %08x\n", hres); + IDispatch_Release(disp); + close_script(script); }
static void test_script_exprs(void)
Signed-off-by: Jacek Caban jacek@codeweavers.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com ---
0 will be a valid index once the value_prop is removed.
dlls/jscript/dispex.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-)
diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c index 6e1463b..eba3b73 100644 --- a/dlls/jscript/dispex.c +++ b/dlls/jscript/dispex.c @@ -181,8 +181,8 @@ static inline HRESULT resize_props(jsdisp_t *This) This->props = props;
for(i=0; i<This->buf_size; i++) { - This->props[i].bucket_head = 0; - This->props[i].bucket_next = 0; + This->props[i].bucket_head = ~0; + This->props[i].bucket_next = ~0; }
for(i=1; i<This->prop_cnt; i++) { @@ -233,14 +233,14 @@ static dispex_prop_t *alloc_protref(jsdisp_t *This, const WCHAR *name, DWORD ref static HRESULT find_prop_name(jsdisp_t *This, unsigned hash, const WCHAR *name, dispex_prop_t **ret) { const builtin_prop_t *builtin; - unsigned bucket, pos, prev = 0; + unsigned bucket, pos, prev = ~0; dispex_prop_t *prop;
bucket = get_props_idx(This, hash); pos = This->props[bucket].bucket_head; - while(pos != 0) { + while(pos != ~0) { if(!wcscmp(name, This->props[pos].name)) { - if(prev != 0) { + if(prev != ~0) { This->props[prev].bucket_next = This->props[pos].bucket_next; This->props[pos].bucket_next = This->props[bucket].bucket_head; This->props[bucket].bucket_head = pos; @@ -1423,7 +1423,7 @@ static HRESULT WINAPI DispatchEx_GetTypeInfo(IDispatchEx *iface, UINT iTInfo, LC
/* If two identifiers differ only by case, the TypeInfo fails */ pos = This->props[get_props_idx(This, prop->hash)].bucket_head; - while (pos) + while (pos != ~0) { cur = This->props + pos;
@@ -1795,6 +1795,8 @@ jsdisp_t *to_jsdisp(IDispatch *disp)
HRESULT init_dispex(jsdisp_t *dispex, script_ctx_t *ctx, const builtin_info_t *builtin_info, jsdisp_t *prototype) { + unsigned i; + TRACE("%p (%p)\n", dispex, prototype);
dispex->IDispatchEx_iface.lpVtbl = &DispatchExVtbl; @@ -1806,6 +1808,11 @@ HRESULT init_dispex(jsdisp_t *dispex, script_ctx_t *ctx, const builtin_info_t *b if(!dispex->props) return E_OUTOFMEMORY;
+ for(i = 0; i < dispex->buf_size; i++) { + dispex->props[i].bucket_head = ~0; + dispex->props[i].bucket_next = ~0; + } + dispex->prototype = prototype; if(prototype) jsdisp_addref(prototype);
Signed-off-by: Jacek Caban jacek@codeweavers.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com ---
get_prop is based on DISPID, not index. This is fragile and works right now, but not after the value_prop is removed in next patch and DISPIDs don't map directly to indices anymore.
dlls/jscript/dispex.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c index eba3b73..a00e36b 100644 --- a/dlls/jscript/dispex.c +++ b/dlls/jscript/dispex.c @@ -109,8 +109,12 @@ static inline BOOL is_function_prop(dispex_prop_t *prop) static DWORD get_flags(jsdisp_t *This, dispex_prop_t *prop) { if(prop->type == PROP_PROTREF) { - dispex_prop_t *parent = get_prop(This->prototype, prop->u.ref); - if(!parent) { + dispex_prop_t *parent = NULL; + + if(prop->u.ref < This->prototype->prop_cnt) + parent = &This->prototype->props[prop->u.ref]; + + if(!parent || parent->type == PROP_DELETED) { prop->type = PROP_DELETED; return 0; }
Signed-off-by: Jacek Caban jacek@codeweavers.com
The mapping between DISPID and index into props has to be adjusted since the value_prop (props[0]) is now gone.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com ---
All !prop->name checks have been removed since there are no props without a name anymore. I also removed redundant prop->type == PROP_DELETED checks after get_prop, since get_prop already checks that, and it touched the same code.
dlls/jscript/dispex.c | 86 +++++++++++++++++++++---------------------- 1 file changed, 43 insertions(+), 43 deletions(-)
diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c index a00e36b..76b4cb4 100644 --- a/dlls/jscript/dispex.c +++ b/dlls/jscript/dispex.c @@ -80,16 +80,19 @@ static void fix_protref_prop(jsdisp_t *jsdisp, dispex_prop_t *prop)
static inline DISPID prop_to_id(jsdisp_t *This, dispex_prop_t *prop) { - return prop - This->props; + /* don't overlap with DISPID_VALUE */ + return prop - This->props + 1; }
static inline dispex_prop_t *get_prop(jsdisp_t *This, DISPID id) { - if(id < 0 || id >= This->prop_cnt) + DWORD idx = id - 1; + + if(idx >= This->prop_cnt) return NULL; - fix_protref_prop(This, &This->props[id]); + fix_protref_prop(This, &This->props[idx]);
- return This->props[id].type == PROP_DELETED ? NULL : &This->props[id]; + return This->props[idx].type == PROP_DELETED ? NULL : &This->props[idx]; }
static inline BOOL is_function_prop(dispex_prop_t *prop) @@ -189,7 +192,7 @@ static inline HRESULT resize_props(jsdisp_t *This) This->props[i].bucket_next = ~0; }
- for(i=1; i<This->prop_cnt; i++) { + for(i=0; i<This->prop_cnt; i++) { props = This->props+i;
bucket = get_props_idx(This, props->hash); @@ -547,26 +550,22 @@ static HRESULT invoke_prop_func(jsdisp_t *This, IDispatch *jsthis, dispex_prop_t
switch(prop->type) { case PROP_BUILTIN: { + vdisp_t vthis; + if(flags == DISPATCH_CONSTRUCT && (prop->flags & PROPF_METHOD)) { WARN("%s is not a constructor\n", debugstr_w(prop->name)); return E_INVALIDARG; }
- if(prop->name || This->builtin_info->class != JSCLASS_FUNCTION) { - vdisp_t vthis; + if(This->builtin_info->class != JSCLASS_FUNCTION && prop->u.p->invoke != JSGlobal_eval) + flags &= ~DISPATCH_JSCRIPT_INTERNAL_MASK; + if(jsthis) + set_disp(&vthis, jsthis); + else + set_jsdisp(&vthis, This); + hres = prop->u.p->invoke(This->ctx, &vthis, flags, argc, argv, r); + vdisp_release(&vthis);
- if(This->builtin_info->class != JSCLASS_FUNCTION && prop->u.p->invoke != JSGlobal_eval) - flags &= ~DISPATCH_JSCRIPT_INTERNAL_MASK; - if(jsthis) - set_disp(&vthis, jsthis); - else - set_jsdisp(&vthis, This); - hres = prop->u.p->invoke(This->ctx, &vthis, flags, argc, argv, r); - vdisp_release(&vthis); - }else { - /* Function object calls are special case */ - hres = Function_invoke(This, jsthis, flags, argc, argv, r); - } return hres; } case PROP_PROTREF: @@ -629,8 +628,6 @@ static HRESULT fill_protrefs(jsdisp_t *This) fill_protrefs(This->prototype);
for(iter = This->prototype->props; iter < This->prototype->props+This->prototype->prop_cnt; iter++) { - if(!iter->name) - continue; hres = find_prop_name(This, iter->hash, iter->name, &prop); if(FAILED(hres)) return hres; @@ -1422,7 +1419,7 @@ static HRESULT WINAPI DispatchEx_GetTypeInfo(IDispatchEx *iface, UINT iTInfo, LC
for (prop = This->props, end = prop + This->prop_cnt; prop != end; prop++) { - if (!prop->name || prop->type != PROP_JSVAL || !(prop->flags & PROPF_ENUMERABLE)) + if (prop->type != PROP_JSVAL || !(prop->flags & PROPF_ENUMERABLE)) continue;
/* If two identifiers differ only by case, the TypeInfo fails */ @@ -1477,7 +1474,7 @@ static HRESULT WINAPI DispatchEx_GetTypeInfo(IDispatchEx *iface, UINT iTInfo, LC typevar = typeinfo->vars; for (prop = This->props; prop != end; prop++) { - if (!prop->name || prop->type != PROP_JSVAL || !(prop->flags & PROPF_ENUMERABLE)) + if (prop->type != PROP_JSVAL || !(prop->flags & PROPF_ENUMERABLE)) continue;
if (is_function_prop(prop)) @@ -1572,12 +1569,10 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc V_VT(pvarRes) = VT_EMPTY;
prop = get_prop(This, id); - if(!prop || prop->type == PROP_DELETED) { + if(!prop && id != DISPID_VALUE) { TRACE("invalid id\n"); return DISP_E_MEMBERNOTFOUND; } - if(id == DISPID_VALUE && wFlags & (DISPATCH_PROPERTYGET | DISPATCH_PROPERTYPUT)) - prop = NULL;
enter_script(This->ctx, &ei);
@@ -1594,7 +1589,11 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc if(FAILED(hres)) break;
- hres = invoke_prop_func(This, get_this(pdp), prop, wFlags, argc, argv, pvarRes ? &r : NULL, pspCaller); + if(prop) + hres = invoke_prop_func(This, get_this(pdp), prop, wFlags, argc, argv, pvarRes ? &r : NULL, pspCaller); + else + hres = jsdisp_call_value(This, get_this(pdp), wFlags, argc, argv, pvarRes ? &r : NULL); + if(argv != buf) heap_free(argv); if(SUCCEEDED(hres) && pvarRes) { @@ -1738,7 +1737,7 @@ static HRESULT WINAPI DispatchEx_GetMemberName(IDispatchEx *iface, DISPID id, BS TRACE("(%p)->(%x %p)\n", This, id, pbstrName);
prop = get_prop(This, id); - if(!prop || !prop->name || prop->type == PROP_DELETED) + if(!prop) return DISP_E_MEMBERNOTFOUND;
*pbstrName = SysAllocString(prop->name); @@ -1751,11 +1750,12 @@ static HRESULT WINAPI DispatchEx_GetMemberName(IDispatchEx *iface, DISPID id, BS static HRESULT WINAPI DispatchEx_GetNextDispID(IDispatchEx *iface, DWORD grfdex, DISPID id, DISPID *pid) { jsdisp_t *This = impl_from_IDispatchEx(iface); - HRESULT hres; + HRESULT hres = S_FALSE;
TRACE("(%p)->(%x %x %p)\n", This, grfdex, id, pid);
- hres = jsdisp_next_prop(This, id, JSDISP_ENUM_ALL, pid); + if(id != DISPID_VALUE) + hres = jsdisp_next_prop(This, id, JSDISP_ENUM_ALL, pid); if(hres == S_FALSE) *pid = DISPID_STARTENUM; return hres; @@ -1807,6 +1807,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->prop_cnt = 0;
dispex->props = heap_alloc_zero(sizeof(dispex_prop_t)*(dispex->buf_size=4)); if(!dispex->props) @@ -1821,14 +1822,6 @@ HRESULT init_dispex(jsdisp_t *dispex, script_ctx_t *ctx, const builtin_info_t *b if(prototype) jsdisp_addref(prototype);
- dispex->prop_cnt = 1; - if(builtin_info->value_prop.invoke || builtin_info->value_prop.getter) { - dispex->props[0].type = PROP_BUILTIN; - dispex->props[0].u.p = &builtin_info->value_prop; - }else { - dispex->props[0].type = PROP_DELETED; - } - script_addref(ctx); dispex->ctx = ctx;
@@ -2088,7 +2081,10 @@ HRESULT disp_call(script_ctx_t *ctx, IDispatch *disp, DISPID id, WORD flags, uns
if(ctx != jsdisp->ctx) flags &= ~DISPATCH_JSCRIPT_INTERNAL_MASK; - hres = jsdisp_call(jsdisp, id, flags, argc, argv, ret); + if(id == DISPID_VALUE) + hres = jsdisp_call_value(jsdisp, to_disp(jsdisp), flags, argc, argv, ret); + else + hres = jsdisp_call(jsdisp, id, flags, argc, argv, ret); jsdisp_release(jsdisp); return hres; } @@ -2446,6 +2442,7 @@ HRESULT disp_delete(IDispatch *disp, DISPID id, BOOL *ret) HRESULT jsdisp_next_prop(jsdisp_t *obj, DISPID id, enum jsdisp_enum_type enum_type, DISPID *ret) { dispex_prop_t *iter; + DWORD idx = id - 1; HRESULT hres;
if(id == DISPID_STARTENUM && enum_type == JSDISP_ENUM_ALL) { @@ -2454,11 +2451,14 @@ HRESULT jsdisp_next_prop(jsdisp_t *obj, DISPID id, enum jsdisp_enum_type enum_ty return hres; }
- if(id + 1 < 0 || id+1 >= obj->prop_cnt) + if(id == DISPID_STARTENUM) + idx = -1; + + if(idx + 1 >= obj->prop_cnt) return S_FALSE;
- for(iter = &obj->props[id + 1]; iter < obj->props + obj->prop_cnt; iter++) { - if(!iter->name || iter->type == PROP_DELETED) + for(iter = &obj->props[idx + 1]; iter < obj->props + obj->prop_cnt; iter++) { + if(iter->type == PROP_DELETED) continue; if(enum_type != JSDISP_ENUM_ALL && iter->type == PROP_PROTREF) continue; @@ -2765,7 +2765,7 @@ HRESULT jsdisp_get_prop_name(jsdisp_t *obj, DISPID id, jsstr_t **r) { dispex_prop_t *prop = get_prop(obj, id);
- if(!prop || !prop->name || prop->type == PROP_DELETED) + if(!prop) return DISP_E_MEMBERNOTFOUND;
*r = jsstr_alloc(prop->name);
Hi Gabriel,
On 11/24/21 3:10 PM, Gabriel Ivăncescu wrote:
@@ -2088,7 +2081,10 @@ HRESULT disp_call(script_ctx_t *ctx, IDispatch *disp, DISPID id, WORD flags, uns
if(ctx != jsdisp->ctx) flags &= ~DISPATCH_JSCRIPT_INTERNAL_MASK;
hres = jsdisp_call(jsdisp, id, flags, argc, argv, ret);
if(id == DISPID_VALUE)
hres = jsdisp_call_value(jsdisp, to_disp(jsdisp), flags, argc, argv, ret);
else
hres = jsdisp_call(jsdisp, id, flags, argc, argv, ret);
Why do we need it here? Do we ever call disp_call(DISPID_VALUE)?
Also, with your implementation, get_prop(DISPID_VALUE) works because of integer overflow, but it would be nice to restructure it to not depend on that.
Thanks,
Jaeck
On 24/11/2021 19:36, Jacek Caban wrote:
Hi Gabriel,
On 11/24/21 3:10 PM, Gabriel Ivăncescu wrote:
@@ -2088,7 +2081,10 @@ HRESULT disp_call(script_ctx_t *ctx, IDispatch *disp, DISPID id, WORD flags, uns if(ctx != jsdisp->ctx) flags &= ~DISPATCH_JSCRIPT_INTERNAL_MASK; - hres = jsdisp_call(jsdisp, id, flags, argc, argv, ret); + if(id == DISPID_VALUE) + hres = jsdisp_call_value(jsdisp, to_disp(jsdisp), flags, argc, argv, ret); + else + hres = jsdisp_call(jsdisp, id, flags, argc, argv, ret);
Why do we need it here? Do we ever call disp_call(DISPID_VALUE)?
Yes, apparently it is needed and can happen, otherwise some of the mshtml tests will fail. I added an assertion when testing it and it triggered. This happens from engine.c's exprval_call of course.
Also, with your implementation, get_prop(DISPID_VALUE) works because of integer overflow, but it would be nice to restructure it to not depend on that.
Oh, I thought it was an idiomatic pattern to check unsigned sizes without having to worry about negative values—since it's specified in the standard. (which is why sizeof() returns an unsigned type)
i.e. if(index < count) is guaranteed to fit within bounds if it's unsigned comparison.
I thought it would simplify the code, do you really want to avoid it?
On 11/24/21 6:53 PM, Gabriel Ivăncescu wrote:
On 24/11/2021 19:36, Jacek Caban wrote:
Hi Gabriel,
On 11/24/21 3:10 PM, Gabriel Ivăncescu wrote:
@@ -2088,7 +2081,10 @@ HRESULT disp_call(script_ctx_t *ctx, IDispatch *disp, DISPID id, WORD flags, uns if(ctx != jsdisp->ctx) flags &= ~DISPATCH_JSCRIPT_INTERNAL_MASK; - hres = jsdisp_call(jsdisp, id, flags, argc, argv, ret); + if(id == DISPID_VALUE) + hres = jsdisp_call_value(jsdisp, to_disp(jsdisp), flags, argc, argv, ret); + else + hres = jsdisp_call(jsdisp, id, flags, argc, argv, ret);
Why do we need it here? Do we ever call disp_call(DISPID_VALUE)?
Yes, apparently it is needed and can happen, otherwise some of the mshtml tests will fail. I added an assertion when testing it and it triggered. This happens from engine.c's exprval_call of course.
That seems weird, is it with jdsidp_t? Since we should never return DISPID_VALUE as a property ID, I would not expect us to call it like that. It's probably worth a closer look.
Also, with your implementation, get_prop(DISPID_VALUE) works because of integer overflow, but it would be nice to restructure it to not depend on that.
Oh, I thought it was an idiomatic pattern to check unsigned sizes without having to worry about negative values—since it's specified in the standard. (which is why sizeof() returns an unsigned type)
i.e. if(index < count) is guaranteed to fit within bounds if it's unsigned comparison.
I thought it would simplify the code, do you really want to avoid it?
I meant the conversion from abstraction (which is also guaranteed but well...). Anyway, it's not a big deal.
Jacek
On 24/11/2021 20:07, Jacek Caban wrote:
On 11/24/21 6:53 PM, Gabriel Ivăncescu wrote:
On 24/11/2021 19:36, Jacek Caban wrote:
Hi Gabriel,
On 11/24/21 3:10 PM, Gabriel Ivăncescu wrote:
@@ -2088,7 +2081,10 @@ HRESULT disp_call(script_ctx_t *ctx, IDispatch *disp, DISPID id, WORD flags, uns if(ctx != jsdisp->ctx) flags &= ~DISPATCH_JSCRIPT_INTERNAL_MASK; - hres = jsdisp_call(jsdisp, id, flags, argc, argv, ret); + if(id == DISPID_VALUE) + hres = jsdisp_call_value(jsdisp, to_disp(jsdisp), flags, argc, argv, ret); + else + hres = jsdisp_call(jsdisp, id, flags, argc, argv, ret);
Why do we need it here? Do we ever call disp_call(DISPID_VALUE)?
Yes, apparently it is needed and can happen, otherwise some of the mshtml tests will fail. I added an assertion when testing it and it triggered. This happens from engine.c's exprval_call of course.
That seems weird, is it with jdsidp_t? Since we should never return DISPID_VALUE as a property ID, I would not expect us to call it like that. It's probably worth a closer look.
It seems it's with normal disps, not jsdisp. Looks like it happens in mshtml `scripts` test in dom.js in the "stylesheets" test. We have this line:
var stylesheet = document.styleSheets.item(0);
But DISPID_IHTMLSTYLESHEETSCOLLECTION_ITEM is same as DISPID_VALUE, so of course it gets triggered.
I'm guessing that this is not possible for jsdisp, since all the (named) props now have a positive DISPID, so I'll remove it.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/jscript/array.c | 15 +++------------ dlls/jscript/bool.c | 4 ++-- dlls/jscript/date.c | 13 +++---------- dlls/jscript/dispex.c | 6 +++--- dlls/jscript/enumerator.c | 6 +++--- dlls/jscript/error.c | 4 ++-- dlls/jscript/function.c | 6 +++--- dlls/jscript/global.c | 2 +- dlls/jscript/jscript.c | 2 +- dlls/jscript/jscript.h | 3 +-- dlls/jscript/json.c | 2 +- dlls/jscript/jsregexp.c | 6 +++--- dlls/jscript/math.c | 2 +- dlls/jscript/number.c | 14 ++------------ dlls/jscript/object.c | 20 +++----------------- dlls/jscript/set.c | 8 ++++---- dlls/jscript/string.c | 16 +++------------- dlls/jscript/vbarray.c | 2 +- 18 files changed, 40 insertions(+), 91 deletions(-)
diff --git a/dlls/jscript/array.c b/dlls/jscript/array.c index 7941031..5f61f99 100644 --- a/dlls/jscript/array.c +++ b/dlls/jscript/array.c @@ -1222,15 +1222,6 @@ static HRESULT Array_unshift(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsi return S_OK; }
-static HRESULT Array_get_value(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t *r) -{ - ArrayInstance *array = array_from_jsdisp(jsthis); - - TRACE("\n"); - - return array_join(ctx, &array->dispex, array->length, L",", 1, r); -} - static void Array_destructor(jsdisp_t *dispex) { heap_free(dispex); @@ -1279,7 +1270,7 @@ static const builtin_prop_t Array_props[] = {
static const builtin_info_t Array_info = { JSCLASS_ARRAY, - {NULL, NULL,0, Array_get_value}, + NULL, ARRAY_SIZE(Array_props), Array_props, Array_destructor, @@ -1292,7 +1283,7 @@ static const builtin_prop_t ArrayInst_props[] = {
static const builtin_info_t ArrayInst_info = { JSCLASS_ARRAY, - {NULL, NULL,0, Array_get_value}, + NULL, ARRAY_SIZE(ArrayInst_props), ArrayInst_props, Array_destructor, @@ -1397,7 +1388,7 @@ static const builtin_prop_t ArrayConstr_props[] = {
static const builtin_info_t ArrayConstr_info = { JSCLASS_FUNCTION, - DEFAULT_FUNCTION_VALUE, + Function_value, ARRAY_SIZE(ArrayConstr_props), ArrayConstr_props, NULL, diff --git a/dlls/jscript/bool.c b/dlls/jscript/bool.c index 44a8b72..184d8d0 100644 --- a/dlls/jscript/bool.c +++ b/dlls/jscript/bool.c @@ -114,7 +114,7 @@ static const builtin_prop_t Bool_props[] = {
static const builtin_info_t Bool_info = { JSCLASS_BOOLEAN, - {NULL, Bool_value, 0}, + Bool_value, ARRAY_SIZE(Bool_props), Bool_props, NULL, @@ -123,7 +123,7 @@ static const builtin_info_t Bool_info = {
static const builtin_info_t BoolInst_info = { JSCLASS_BOOLEAN, - {NULL, Bool_value, 0}, + Bool_value, 0, NULL, NULL, NULL diff --git a/dlls/jscript/date.c b/dlls/jscript/date.c index 96d366c..b130c83 100644 --- a/dlls/jscript/date.c +++ b/dlls/jscript/date.c @@ -1846,13 +1846,6 @@ static HRESULT Date_setYear(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsi return S_OK; }
-static HRESULT Date_get_value(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t *r) -{ - TRACE("\n"); - - return dateobj_to_string(date_from_jsdisp(jsthis), r); -} - static const builtin_prop_t Date_props[] = { {L"getDate", Date_getDate, PROPF_METHOD}, {L"getDay", Date_getDay, PROPF_METHOD}, @@ -1903,7 +1896,7 @@ static const builtin_prop_t Date_props[] = {
static const builtin_info_t Date_info = { JSCLASS_DATE, - {NULL, NULL,0, Date_get_value}, + NULL, ARRAY_SIZE(Date_props), Date_props, NULL, @@ -1912,7 +1905,7 @@ static const builtin_info_t Date_info = {
static const builtin_info_t DateInst_info = { JSCLASS_DATE, - {NULL, NULL,0, Date_get_value}, + NULL, 0, NULL, NULL, NULL @@ -2440,7 +2433,7 @@ static const builtin_prop_t DateConstr_props[] = {
static const builtin_info_t DateConstr_info = { JSCLASS_FUNCTION, - DEFAULT_FUNCTION_VALUE, + Function_value, ARRAY_SIZE(DateConstr_props), DateConstr_props, NULL, diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c index 76b4cb4..544d679 100644 --- a/dlls/jscript/dispex.c +++ b/dlls/jscript/dispex.c @@ -1830,7 +1830,7 @@ HRESULT init_dispex(jsdisp_t *dispex, script_ctx_t *ctx, const builtin_info_t *b
static const builtin_info_t dispex_info = { JSCLASS_NONE, - {NULL, NULL, 0}, + NULL, 0, NULL, NULL, NULL @@ -1981,14 +1981,14 @@ HRESULT jsdisp_call_value(jsdisp_t *jsfunc, IDispatch *jsthis, WORD flags, unsig }else { vdisp_t vdisp;
- if(!jsfunc->builtin_info->value_prop.invoke) { + if(!jsfunc->builtin_info->call) { WARN("Not a function\n"); return JS_E_FUNCTION_EXPECTED; }
set_disp(&vdisp, jsthis); flags &= ~DISPATCH_JSCRIPT_INTERNAL_MASK; - hres = jsfunc->builtin_info->value_prop.invoke(jsfunc->ctx, &vdisp, flags, argc, argv, r); + hres = jsfunc->builtin_info->call(jsfunc->ctx, &vdisp, flags, argc, argv, r); vdisp_release(&vdisp); } return hres; diff --git a/dlls/jscript/enumerator.c b/dlls/jscript/enumerator.c index dea1940..038b474 100644 --- a/dlls/jscript/enumerator.c +++ b/dlls/jscript/enumerator.c @@ -180,7 +180,7 @@ static const builtin_prop_t Enumerator_props[] = {
static const builtin_info_t Enumerator_info = { JSCLASS_ENUMERATOR, - {NULL, NULL, 0}, + NULL, ARRAY_SIZE(Enumerator_props), Enumerator_props, NULL, @@ -189,7 +189,7 @@ static const builtin_info_t Enumerator_info = {
static const builtin_info_t EnumeratorInst_info = { JSCLASS_ENUMERATOR, - {NULL, NULL, 0, NULL}, + NULL, 0, NULL, Enumerator_destructor, @@ -317,7 +317,7 @@ static HRESULT EnumeratorConstr_value(script_ctx_t *ctx, vdisp_t *vthis, WORD fl
static const builtin_info_t EnumeratorConstr_info = { JSCLASS_FUNCTION, - DEFAULT_FUNCTION_VALUE, + Function_value, 0, NULL, NULL, diff --git a/dlls/jscript/error.c b/dlls/jscript/error.c index bb9e5a2..49adaeb 100644 --- a/dlls/jscript/error.c +++ b/dlls/jscript/error.c @@ -136,7 +136,7 @@ static const builtin_prop_t Error_props[] = {
static const builtin_info_t Error_info = { JSCLASS_ERROR, - {NULL, Error_value, 0}, + Error_value, ARRAY_SIZE(Error_props), Error_props, NULL, @@ -145,7 +145,7 @@ static const builtin_info_t Error_info = {
static const builtin_info_t ErrorInst_info = { JSCLASS_ERROR, - {NULL, Error_value, 0}, + Error_value, 0, NULL, NULL, diff --git a/dlls/jscript/function.c b/dlls/jscript/function.c index 318d6be..3eef1aa 100644 --- a/dlls/jscript/function.c +++ b/dlls/jscript/function.c @@ -172,7 +172,7 @@ static HRESULT Arguments_idx_put(jsdisp_t *jsdisp, unsigned idx, jsval_t val)
static const builtin_info_t Arguments_info = { JSCLASS_ARGUMENTS, - {NULL, Arguments_value, 0}, + Arguments_value, 0, NULL, Arguments_destructor, NULL, @@ -545,7 +545,7 @@ static const builtin_prop_t Function_props[] = {
static const builtin_info_t Function_info = { JSCLASS_FUNCTION, - DEFAULT_FUNCTION_VALUE, + Function_value, ARRAY_SIZE(Function_props), Function_props, Function_destructor, @@ -559,7 +559,7 @@ static const builtin_prop_t FunctionInst_props[] = {
static const builtin_info_t FunctionInst_info = { JSCLASS_FUNCTION, - DEFAULT_FUNCTION_VALUE, + Function_value, ARRAY_SIZE(FunctionInst_props), FunctionInst_props, Function_destructor, diff --git a/dlls/jscript/global.c b/dlls/jscript/global.c index 2665bec..c9a00d1 100644 --- a/dlls/jscript/global.c +++ b/dlls/jscript/global.c @@ -904,7 +904,7 @@ static const builtin_prop_t JSGlobal_props[] = {
static const builtin_info_t JSGlobal_info = { JSCLASS_GLOBAL, - {NULL, NULL, 0}, + NULL, ARRAY_SIZE(JSGlobal_props), JSGlobal_props, NULL, diff --git a/dlls/jscript/jscript.c b/dlls/jscript/jscript.c index 9148451..160269c 100644 --- a/dlls/jscript/jscript.c +++ b/dlls/jscript/jscript.c @@ -112,7 +112,7 @@ HRESULT create_named_item_script_obj(script_ctx_t *ctx, named_item_t *item) { static const builtin_info_t disp_info = { JSCLASS_GLOBAL, - {NULL, NULL, 0}, + NULL, 0, NULL, NULL, NULL diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h index 69897cd..c192ec7 100644 --- a/dlls/jscript/jscript.h +++ b/dlls/jscript/jscript.h @@ -232,7 +232,7 @@ typedef struct {
typedef struct { jsclass_t class; - builtin_prop_t value_prop; + builtin_invoke_t call; DWORD props_cnt; const builtin_prop_t *props; void (*destructor)(jsdisp_t*); @@ -340,7 +340,6 @@ HRESULT Function_invoke(jsdisp_t*,IDispatch*,WORD,unsigned,jsval_t*,jsval_t*) DE HRESULT Function_value(script_ctx_t*,vdisp_t*,WORD,unsigned,jsval_t*,jsval_t*) DECLSPEC_HIDDEN; HRESULT Function_get_value(script_ctx_t*,jsdisp_t*,jsval_t*) DECLSPEC_HIDDEN; struct _function_code_t *Function_get_code(jsdisp_t*) DECLSPEC_HIDDEN; -#define DEFAULT_FUNCTION_VALUE {NULL, Function_value,0, Function_get_value}
HRESULT throw_error(script_ctx_t*,HRESULT,const WCHAR*) DECLSPEC_HIDDEN; jsdisp_t *create_builtin_error(script_ctx_t *ctx) DECLSPEC_HIDDEN; diff --git a/dlls/jscript/json.c b/dlls/jscript/json.c index f2fbb80..d3896ca 100644 --- a/dlls/jscript/json.c +++ b/dlls/jscript/json.c @@ -839,7 +839,7 @@ static const builtin_prop_t JSON_props[] = {
static const builtin_info_t JSON_info = { JSCLASS_JSON, - {NULL, NULL, 0}, + NULL, ARRAY_SIZE(JSON_props), JSON_props, NULL, diff --git a/dlls/jscript/jsregexp.c b/dlls/jscript/jsregexp.c index f80452d..cb6c051 100644 --- a/dlls/jscript/jsregexp.c +++ b/dlls/jscript/jsregexp.c @@ -563,7 +563,7 @@ static const builtin_prop_t RegExp_props[] = {
static const builtin_info_t RegExp_info = { JSCLASS_REGEXP, - {NULL, RegExp_value, 0}, + RegExp_value, ARRAY_SIZE(RegExp_props), RegExp_props, RegExp_destructor, @@ -580,7 +580,7 @@ static const builtin_prop_t RegExpInst_props[] = {
static const builtin_info_t RegExpInst_info = { JSCLASS_REGEXP, - {NULL, RegExp_value, 0}, + RegExp_value, ARRAY_SIZE(RegExpInst_props), RegExpInst_props, RegExp_destructor, @@ -952,7 +952,7 @@ static const builtin_prop_t RegExpConstr_props[] = {
static const builtin_info_t RegExpConstr_info = { JSCLASS_FUNCTION, - DEFAULT_FUNCTION_VALUE, + Function_value, ARRAY_SIZE(RegExpConstr_props), RegExpConstr_props, NULL, diff --git a/dlls/jscript/math.c b/dlls/jscript/math.c index 475b9b2..c65bbaf 100644 --- a/dlls/jscript/math.c +++ b/dlls/jscript/math.c @@ -492,7 +492,7 @@ static const builtin_prop_t Math_props[] = {
static const builtin_info_t Math_info = { JSCLASS_MATH, - {NULL, NULL, 0}, + NULL, ARRAY_SIZE(Math_props), Math_props, NULL, diff --git a/dlls/jscript/number.c b/dlls/jscript/number.c index 3c96532..410f27b 100644 --- a/dlls/jscript/number.c +++ b/dlls/jscript/number.c @@ -494,16 +494,6 @@ static HRESULT Number_valueOf(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un return S_OK; }
-static HRESULT Number_get_value(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t *r) -{ - NumberInstance *number = number_from_jsdisp(jsthis); - - TRACE("(%p)\n", number); - - *r = jsval_number(number->value); - return S_OK; -} - static const builtin_prop_t Number_props[] = { {L"toExponential", Number_toExponential, PROPF_METHOD|1}, {L"toFixed", Number_toFixed, PROPF_METHOD}, @@ -515,7 +505,7 @@ static const builtin_prop_t Number_props[] = {
static const builtin_info_t Number_info = { JSCLASS_NUMBER, - {NULL, NULL,0, Number_get_value}, + NULL, ARRAY_SIZE(Number_props), Number_props, NULL, @@ -524,7 +514,7 @@ static const builtin_info_t Number_info = {
static const builtin_info_t NumberInst_info = { JSCLASS_NUMBER, - {NULL, NULL,0, Number_get_value}, + NULL, 0, NULL, NULL, NULL diff --git a/dlls/jscript/object.c b/dlls/jscript/object.c index 89684f5..24692f8 100644 --- a/dlls/jscript/object.c +++ b/dlls/jscript/object.c @@ -243,20 +243,6 @@ static HRESULT Object_set_proto_(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t va return jsdisp_change_prototype(jsthis, proto); }
-static HRESULT Object_get_value(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t *r) -{ - jsstr_t *ret; - - TRACE("\n"); - - ret = jsstr_alloc(L"[object Object]"); - if(!ret) - return E_OUTOFMEMORY; - - *r = jsval_string(ret); - return S_OK; -} - static void Object_destructor(jsdisp_t *dispex) { heap_free(dispex); @@ -274,7 +260,7 @@ static const builtin_prop_t Object_props[] = {
static const builtin_info_t Object_info = { JSCLASS_OBJECT, - {NULL, NULL,0, Object_get_value}, + NULL, ARRAY_SIZE(Object_props), Object_props, Object_destructor, @@ -283,7 +269,7 @@ static const builtin_info_t Object_info = {
static const builtin_info_t ObjectInst_info = { JSCLASS_OBJECT, - {NULL, NULL,0, Object_get_value}, + NULL, 0, NULL, Object_destructor, NULL @@ -889,7 +875,7 @@ static const builtin_prop_t ObjectConstr_props[] = {
static const builtin_info_t ObjectConstr_info = { JSCLASS_FUNCTION, - DEFAULT_FUNCTION_VALUE, + Function_value, ARRAY_SIZE(ObjectConstr_props), ObjectConstr_props, NULL, diff --git a/dlls/jscript/set.c b/dlls/jscript/set.c index 8f355f4..5ae41d8 100644 --- a/dlls/jscript/set.c +++ b/dlls/jscript/set.c @@ -89,7 +89,7 @@ static const builtin_prop_t Set_props[] = {
static const builtin_info_t Set_prototype_info = { JSCLASS_SET, - {NULL, Set_value, 0}, + Set_value, ARRAY_SIZE(Set_props), Set_props, NULL, @@ -98,7 +98,7 @@ static const builtin_info_t Set_prototype_info = {
static const builtin_info_t Set_info = { JSCLASS_SET, - {NULL, Set_value, 0}, + Set_value, 0, NULL, NULL, NULL @@ -414,7 +414,7 @@ static const builtin_prop_t Map_props[] = {
static const builtin_info_t Map_prototype_info = { JSCLASS_OBJECT, - {NULL, Map_value, 0}, + Map_value, ARRAY_SIZE(Map_prototype_props), Map_prototype_props, NULL, @@ -423,7 +423,7 @@ static const builtin_info_t Map_prototype_info = {
static const builtin_info_t Map_info = { JSCLASS_MAP, - {NULL, Map_value, 0}, + Map_value, ARRAY_SIZE(Map_props), Map_props, Map_destructor, diff --git a/dlls/jscript/string.c b/dlls/jscript/string.c index 4f6d8cd..5958216 100644 --- a/dlls/jscript/string.c +++ b/dlls/jscript/string.c @@ -1493,16 +1493,6 @@ static HRESULT String_localeCompare(script_ctx_t *ctx, vdisp_t *jsthis, WORD fla return E_NOTIMPL; }
-static HRESULT String_get_value(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t *r) -{ - StringInstance *This = string_from_jsdisp(jsthis); - - TRACE("\n"); - - *r = jsval_string(jsstr_addref(This->str)); - return S_OK; -} - static void String_destructor(jsdisp_t *dispex) { StringInstance *This = string_from_jsdisp(dispex); @@ -1579,7 +1569,7 @@ static const builtin_prop_t String_props[] = {
static const builtin_info_t String_info = { JSCLASS_STRING, - {NULL, NULL,0, String_get_value}, + NULL, ARRAY_SIZE(String_props), String_props, String_destructor, @@ -1592,7 +1582,7 @@ static const builtin_prop_t StringInst_props[] = {
static const builtin_info_t StringInst_info = { JSCLASS_STRING, - {NULL, NULL,0, String_get_value}, + NULL, ARRAY_SIZE(StringInst_props), StringInst_props, String_destructor, @@ -1710,7 +1700,7 @@ static const builtin_prop_t StringConstr_props[] = {
static const builtin_info_t StringConstr_info = { JSCLASS_FUNCTION, - DEFAULT_FUNCTION_VALUE, + Function_value, ARRAY_SIZE(StringConstr_props), StringConstr_props, NULL, diff --git a/dlls/jscript/vbarray.c b/dlls/jscript/vbarray.c index 69a77f1..41faa20 100644 --- a/dlls/jscript/vbarray.c +++ b/dlls/jscript/vbarray.c @@ -251,7 +251,7 @@ static const builtin_prop_t VBArray_props[] = {
static const builtin_info_t VBArray_info = { JSCLASS_VBARRAY, - {NULL, VBArray_value, 0}, + VBArray_value, ARRAY_SIZE(VBArray_props), VBArray_props, VBArray_destructor,
Some javascript libraries such as prototype.js use this (by setting to an array) to examine setAttribute quirks.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/nsembed.c | 3 +- dlls/mshtml/tests/documentmode.js | 77 +++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+), 1 deletion(-)
diff --git a/dlls/mshtml/nsembed.c b/dlls/mshtml/nsembed.c index 4224d6a..25ad92d 100644 --- a/dlls/mshtml/nsembed.c +++ b/dlls/mshtml/nsembed.c @@ -1013,7 +1013,8 @@ HRESULT variant_to_nsstr(VARIANT *v, BOOL hex_int, nsAString *nsstr) nsAString_Init(nsstr, buf); break;
- case VT_R8: { + case VT_R8: + case VT_DISPATCH: { VARIANT strv; HRESULT hres;
diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index 041025c..08fcde4 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -1088,6 +1088,72 @@ sync_test("elem_attr", function() { r = elem.getAttribute("className"); ok(r === "cls3", "className attr = " + r);
+ var arr = [3]; + elem.setAttribute("testattr", arr); + r = elem.getAttribute("testattr"); + ok(r === (v < 8 ? arr : "3"), "testattr = " + r); + todo_wine_if(v === 8). + ok(elem.testattr === (v < 9 ? arr : undefined), "elem.testattr = " + elem.testattr); + r = elem.removeAttribute("testattr"); + ok(r === (v < 9 ? true : undefined), "testattr removeAttribute returned " + r); + ok(elem.testattr === undefined, "removed testattr = " + elem.testattr); + + arr[0] = 9; + elem.setAttribute("testattr", "string"); + elem.testattr = arr; + r = elem.getAttribute("testattr"); + todo_wine_if(v === 8). + ok(r === (v < 8 ? arr : (v < 9 ? "9" : "string")), "testattr = " + r); + ok(elem.testattr === arr, "elem.testattr = " + elem.testattr); + arr[0] = 3; + r = elem.getAttribute("testattr"); + todo_wine_if(v === 8). + ok(r === (v < 8 ? arr : (v < 9 ? "3" : "string")), "testattr = " + r); + ok(elem.testattr === arr, "elem.testattr = " + elem.testattr); + r = elem.removeAttribute("testattr"); + ok(r === (v < 9 ? true : undefined), "testattr removeAttribute returned " + r); + todo_wine_if(v === 8). + ok(elem.testattr === (v < 9 ? undefined : arr), "removed testattr = " + elem.testattr); + + arr.toString = function() { return 42; } + elem.testattr = arr; + r = elem.getAttribute("testattr"); + todo_wine_if(v === 8). + ok(r === (v < 8 ? arr : (v < 9 ? "42" : null)), "testattr with custom toString = " + r); + elem.setAttribute("testattr", arr); + r = elem.getAttribute("testattr"); + ok(r === (v < 8 ? arr : "42"), "testattr after setAttribute with custom toString = " + r); + ok(elem.testattr === arr, "elem.testattr after setAttribute with custom toString = " + elem.testattr); + r = elem.removeAttribute("testattr"); + ok(r === (v < 9 ? true : undefined), "testattr removeAttribute with custom toString returned " + r); + todo_wine_if(v === 8). + ok(elem.testattr === (v < 9 ? undefined : arr), "removed testattr with custom toString = " + elem.testattr); + + arr.valueOf = function() { return "arrval"; } + elem.testattr = arr; + r = elem.getAttribute("testattr"); + todo_wine_if(v === 8). + ok(r === (v < 8 ? arr : (v < 9 ? "arrval" : null)), "testattr with custom valueOf = " + r); + elem.setAttribute("testattr", arr); + r = elem.getAttribute("testattr"); + todo_wine_if(v >= 10). + ok(r === (v < 8 ? arr : (v < 10 ? "arrval" : "42")), "testattr after setAttribute with custom valueOf = " + r); + ok(elem.testattr === arr, "elem.testattr after setAttribute with custom valueOf = " + elem.testattr); + r = elem.removeAttribute("testattr"); + ok(r === (v < 9 ? true : undefined), "testattr removeAttribute with custom valueOf returned " + r); + todo_wine_if(v === 8). + ok(elem.testattr === (v < 9 ? undefined : arr), "removed testattr with custom valueOf = " + elem.testattr); + delete arr.valueOf; + delete arr.toString; + + elem.setAttribute("id", arr); + r = elem.getAttribute("id"); + todo_wine_if(v >= 8 && v < 10). + ok(r === (v < 8 || v >= 10 ? "3" : "[object]"), "id = " + r); + r = elem.removeAttribute("id"); + ok(r === (v < 9 ? true : undefined), "id removeAttribute returned " + r); + ok(elem.id === "", "removed id = " + elem.id); + var func = function() { }; elem.onclick = func; ok(elem.onclick === func, "onclick = " + elem.onclick); @@ -1136,6 +1202,17 @@ sync_test("elem_attr", function() { todo_wine_if(v >= 8). ok(elem.onclick === null, "removed onclick = " + elem.onclick);
+ elem.setAttribute("ondblclick", arr); + r = elem.getAttribute("ondblclick"); + todo_wine_if(v >= 8 && v < 10). + ok(r === (v < 8 ? arr : (v < 10 ? "[object]" : "3")), "ondblclick = " + r); + r = elem.removeAttribute("ondblclick"); + ok(r === (v < 8 ? false : (v < 9 ? true : undefined)), "ondblclick removeAttribute returned " + r); + r = Object.prototype.toString.call(elem.ondblclick); + todo_wine_if(v >= 9). + ok(r === (v < 8 ? "[object Array]" : (v < 9 ? "[object Object]" : (v < 11 ? "[object Null]" : "[object Function]"))), + "removed ondblclick Object.toString returned " + r); + elem.setAttribute("ondblclick", "string"); r = elem.getAttribute("ondblclick"); ok(r === "string", "ondblclick string = " + r);
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=102639
Your paranoid android.
=== w10pro64_ja (64 bit report) ===
mshtml: htmldoc.c:2541: Test failed: unexpected call UpdateUI htmldoc.c:2853: Test failed: unexpected call Exec_UPDATECOMMANDS htmldoc.c:2541: Test failed: unexpected call UpdateUI htmldoc.c:2853: Test failed: unexpected call Exec_UPDATECOMMANDS htmldoc.c:350: Test failed: expected Exec_SETTITLE htmldoc.c:2859: Test failed: unexpected call Exec_SETTITLE
=== w1064 (testbot log) ===
WineRunTask.pl:error: The previous 1 run(s) terminated abnormally
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/jscript/dispex.c | 3 ++- dlls/jscript/jscript.h | 3 ++- dlls/mshtml/script.c | 5 ++++- dlls/mshtml/tests/documentmode.js | 1 - 4 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c index 544d679..ee16452 100644 --- a/dlls/jscript/dispex.c +++ b/dlls/jscript/dispex.c @@ -1608,7 +1608,8 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc if(prop) hres = prop_get(This, prop, &r); else { - hres = to_primitive(This->ctx, jsval_obj(This), &r, NO_HINT); + hres = to_primitive(This->ctx, jsval_obj(This), &r, + This->ctx->version > SCRIPTLANGUAGEVERSION_ES5 ? HINT_STRING : NO_HINT); if(hres == JS_E_TO_PRIMITIVE) hres = DISP_E_MEMBERNOTFOUND; } diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h index c192ec7..47ca3da 100644 --- a/dlls/jscript/jscript.h +++ b/dlls/jscript/jscript.h @@ -45,7 +45,8 @@ * This is Wine jscript extension for ES5 and ES6 compatible mode. Allowed only in HTML mode. */ #define SCRIPTLANGUAGEVERSION_ES5 0x102 -#define SCRIPTLANGUAGEVERSION_ES6 0x103 +#define SCRIPTLANGUAGEVERSION_ES5b 0x103 +#define SCRIPTLANGUAGEVERSION_ES6 0x104
typedef struct _jsval_t jsval_t; typedef struct _jsstr_t jsstr_t; diff --git a/dlls/mshtml/script.c b/dlls/mshtml/script.c index 28e07a5..cc6a25b 100644 --- a/dlls/mshtml/script.c +++ b/dlls/mshtml/script.c @@ -65,7 +65,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(mshtml); /* See jscript.h in jscript.dll. */ #define SCRIPTLANGUAGEVERSION_HTML 0x400 #define SCRIPTLANGUAGEVERSION_ES5 0x102 -#define SCRIPTLANGUAGEVERSION_ES6 0x103 +#define SCRIPTLANGUAGEVERSION_ES5b 0x103 +#define SCRIPTLANGUAGEVERSION_ES6 0x104
struct ScriptHost { IActiveScriptSite IActiveScriptSite_iface; @@ -156,6 +157,8 @@ static BOOL init_script_engine(ScriptHost *script_host) if(IsEqualGUID(&script_host->guid, &CLSID_JScript)) { if(compat_mode >= COMPAT_MODE_IE11) script_mode = SCRIPTLANGUAGEVERSION_ES6; + else if(compat_mode >= COMPAT_MODE_IE10) + script_mode = SCRIPTLANGUAGEVERSION_ES5b; else if(compat_mode >= COMPAT_MODE_IE9) script_mode = SCRIPTLANGUAGEVERSION_ES5; script_mode |= SCRIPTLANGUAGEVERSION_HTML; diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index 08fcde4..c2fd8bd 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -1136,7 +1136,6 @@ sync_test("elem_attr", function() { ok(r === (v < 8 ? arr : (v < 9 ? "arrval" : null)), "testattr with custom valueOf = " + r); elem.setAttribute("testattr", arr); r = elem.getAttribute("testattr"); - todo_wine_if(v >= 10). ok(r === (v < 8 ? arr : (v < 10 ? "arrval" : "42")), "testattr after setAttribute with custom valueOf = " + r); ok(elem.testattr === arr, "elem.testattr after setAttribute with custom valueOf = " + elem.testattr); r = elem.removeAttribute("testattr");
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=102640
Your paranoid android.
=== w10pro64 (64 bit report) ===
mshtml: htmldoc.c:2541: Test failed: unexpected call UpdateUI htmldoc.c:2853: Test failed: unexpected call Exec_UPDATECOMMANDS
=== w10pro64_ja (64 bit report) ===
mshtml: htmldoc.c:2541: Test failed: unexpected call UpdateUI htmldoc.c:2853: Test failed: unexpected call Exec_UPDATECOMMANDS htmldoc.c:350: Test failed: expected Exec_SETTITLE htmldoc.c:2859: Test failed: unexpected call Exec_SETTITLE
=== w10pro64_zh_CN (64 bit report) ===
mshtml: htmldoc.c:2541: Test failed: unexpected call UpdateUI htmldoc.c:2853: Test failed: unexpected call Exec_UPDATECOMMANDS
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=102630
Your paranoid android.
=== w8adm (32 bit report) ===
mshtml: events.c:1089: Test failed: unexpected call img_onerror events: Timeout
=== w10pro64 (32 bit report) ===
mshtml: htmldoc.c:2541: Test failed: unexpected call UpdateUI htmldoc.c:2853: Test failed: unexpected call Exec_UPDATECOMMANDS htmldoc.c:350: Test failed: expected Exec_SETTITLE htmldoc.c:2859: Test failed: unexpected call Exec_SETTITLE
=== w10pro64_ar (64 bit report) ===
mshtml: htmldoc.c:2541: Test failed: unexpected call UpdateUI htmldoc.c:2853: Test failed: unexpected call Exec_UPDATECOMMANDS
=== w10pro64_zh_CN (64 bit report) ===
mshtml: htmldoc.c:2541: Test failed: unexpected call UpdateUI htmldoc.c:2853: Test failed: unexpected call Exec_UPDATECOMMANDS htmldoc.c:2541: Test failed: unexpected call UpdateUI htmldoc.c:2853: Test failed: unexpected call Exec_UPDATECOMMANDS htmldoc.c:350: Test failed: expected Exec_SETTITLE htmldoc.c:2859: Test failed: unexpected call Exec_SETTITLE
=== w7u_adm (32 bit report) ===
mshtml: script.c:624: Test failed: L"/index.html?es5.js:date_now: unexpected Date.now() result 1637771362112 expected 1637771362175"