Signed-off-by: Andreas Maier staubim@quantentunnel.de --- dlls/jscript/enumerator.c | 212 ++++++++++++++++++++++++++++++++++++++++++---- dlls/jscript/jscript.h | 2 + dlls/jscript/object.c | 2 +- dlls/jscript/resource.h | 1 + 4 files changed, 198 insertions(+), 19 deletions(-)
diff --git a/dlls/jscript/enumerator.c b/dlls/jscript/enumerator.c index d0502f6afa..e72da78cbb 100644 --- a/dlls/jscript/enumerator.c +++ b/dlls/jscript/enumerator.c @@ -26,6 +26,11 @@ WINE_DEFAULT_DEBUG_CHANNEL(jscript);
typedef struct { jsdisp_t dispex; + /* IEnumVARIANT returned by _NewEnum */ + IEnumVARIANT *enumvar; + /* current item */ + jsval_t item; + BOOL atend; } EnumeratorInstance;
static const WCHAR atEndW[] = {'a','t','E','n','d',0}; @@ -33,43 +38,139 @@ static const WCHAR itemW[] = {'i','t','e','m',0}; static const WCHAR moveFirstW[] = {'m','o','v','e','F','i','r','s','t',0}; static const WCHAR moveNextW[] = {'m','o','v','e','N','e','x','t',0};
+static inline EnumeratorInstance *enumerator_from_jsdisp(jsdisp_t *jsdisp) +{ + return CONTAINING_RECORD(jsdisp, EnumeratorInstance, dispex); +} + +static inline EnumeratorInstance *enumerator_from_vdisp(vdisp_t *vdisp) +{ + return enumerator_from_jsdisp(vdisp->u.jsdisp); +} + +static inline EnumeratorInstance *enumerator_this(vdisp_t *jsthis) +{ + return is_vclass(jsthis, JSCLASS_ENUMERATOR) ? enumerator_from_vdisp(jsthis) : NULL; +} + +static inline HRESULT enumvar_get_next_item(EnumeratorInstance *This) +{ + HRESULT hres; + VARIANT nextitem; + + if (This->atend) + { + This->item = jsval_undefined(); + return S_OK; + } + + /* dont leak pervious value */ + jsval_release(This->item); + + /* not at end ... get next item */ + VariantInit(&nextitem); + hres = IEnumVARIANT_Next(This->enumvar, 1, &nextitem, NULL); + if (hres == S_OK) + { + hres = variant_to_jsval(&nextitem, &This->item); + if (FAILED(hres)) + { + ERR("failed to convert jsval to variant!"); + This->item = jsval_undefined(); + } + } + else + { + This->item = jsval_undefined(); + This->atend = TRUE; + } + VariantClear(&nextitem); + + return S_OK; +} + static void Enumerator_destructor(jsdisp_t *dispex) { - TRACE("Enumerator_destructor\n"); + EnumeratorInstance *This = enumerator_from_jsdisp(dispex);
+ TRACE("\n"); + + jsval_release(This->item); heap_free(dispex); }
static HRESULT Enumerator_atEnd(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) { - TRACE("Enumerator_atEnd\n"); + EnumeratorInstance *This; + + if (!(This = enumerator_this(jsthis))) + return throw_type_error(ctx, JS_E_ENUMERATOR_EXPECTED, NULL); + + if (r) + *r = jsval_bool(This->atend);
- return E_NOTIMPL; + TRACE("%d\n", This->atend); + + return S_OK; }
static HRESULT Enumerator_item(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) { - TRACE("Enumerator_item\n"); + EnumeratorInstance *This; + + TRACE("\n");
- return E_NOTIMPL; + if (!(This = enumerator_this(jsthis))) + return throw_type_error(ctx, JS_E_ENUMERATOR_EXPECTED, NULL); + + return r ? jsval_copy(This->item, r) : S_OK; }
static HRESULT Enumerator_moveFirst(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) { - TRACE("Enumerator_moveFirst\n"); + EnumeratorInstance *This; + HRESULT hres = S_OK; + + TRACE("\n");
- return E_NOTIMPL; + if (!(This = enumerator_this(jsthis))) + return throw_type_error(ctx, JS_E_ENUMERATOR_EXPECTED, NULL); + + if (This->enumvar) + { + This->atend = FALSE; + hres = IEnumVARIANT_Reset(This->enumvar); + if (!FAILED(hres)) + hres = enumvar_get_next_item(This); + } + + if (r) + *r = jsval_undefined(); + + return hres; }
static HRESULT Enumerator_moveNext(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) { - TRACE("Enumerator_moveNext\n"); + EnumeratorInstance *This; + HRESULT hres = S_OK;
- return E_NOTIMPL; + TRACE("\n"); + + if (!(This = enumerator_this(jsthis))) + return throw_type_error(ctx, JS_E_ENUMERATOR_EXPECTED, NULL); + + if (This->enumvar) + hres = enumvar_get_next_item(This); + + if (r) + *r = jsval_undefined(); + + return hres; }
static const builtin_prop_t Enumerator_props[] = { @@ -80,7 +181,7 @@ static const builtin_prop_t Enumerator_props[] = { };
static const builtin_info_t Enumerator_info = { - JSCLASS_OBJECT, + JSCLASS_ENUMERATOR, {NULL, NULL, 0}, ARRAY_SIZE(Enumerator_props), Enumerator_props, @@ -89,7 +190,7 @@ static const builtin_info_t Enumerator_info = { };
static const builtin_info_t EnumeratorInst_info = { - JSCLASS_OBJECT, + JSCLASS_ENUMERATOR, {NULL, NULL, 0, NULL}, 0, NULL, @@ -101,16 +202,18 @@ static HRESULT EnumeratorConstr_value(script_ctx_t *ctx, vdisp_t *vthis, WORD fl jsval_t *r) { jsdisp_t *obj; + jsval_t *arg0; HRESULT hres;
- TRACE("EnumeratorConstr_value\n"); + TRACE("\n");
switch(flags) { case DISPATCH_CONSTRUCT: { - if (argc != 1) - return throw_syntax_error(ctx, JS_E_MISSING_ARG, NULL); + if (argc > 1) + return throw_syntax_error(ctx, JS_E_INVALIDARG, NULL);
- hres = create_enumerator(ctx, &argv[0], &obj); + arg0 = (argc == 1) ? &argv[0] : 0; + hres = create_enumerator(ctx, arg0, &obj); if(FAILED(hres)) return hres;
@@ -118,7 +221,7 @@ static HRESULT EnumeratorConstr_value(script_ctx_t *ctx, vdisp_t *vthis, WORD fl break; } default: - FIXME("unimplemented flags: %x\n", flags); + ERR("unimplemented flags: %x\n", flags); return E_NOTIMPL; }
@@ -140,7 +243,8 @@ static HRESULT alloc_enumerator(script_ctx_t *ctx, jsdisp_t *object_prototype, E hres = init_dispex_from_constr(&enumerator->dispex, ctx, &EnumeratorInst_info, ctx->enumerator_constr);
- if(FAILED(hres)) { + if(FAILED(hres)) + { heap_free(enumerator); return hres; } @@ -180,11 +284,83 @@ HRESULT create_enumerator(script_ctx_t *ctx, jsval_t *argv, jsdisp_t **ret) { EnumeratorInstance *enumerator; HRESULT hres; + IDispatch *obj; + DISPPARAMS dispparams = {NULL, NULL, 0, 0}; + VARIANT varresult; + BOOL atend; + + IEnumVARIANT *enumvar; + + memset(&varresult, 0, sizeof(VARIANT)); + VariantInit(&varresult); + + /* new Enumerator() */ + if (argv == NULL) + { + enumvar = NULL; + atend = TRUE; + } + else if (is_object_instance(*argv)) + { + obj = get_object(*argv); + + /* Try to get a IEnumVARIANT by _NewEnum */ + hres = IDispatch_Invoke(obj, + DISPID_NEWENUM, &IID_NULL, LOCALE_NEUTRAL, + DISPATCH_METHOD, &dispparams, &varresult, + NULL, NULL); + if (FAILED(hres)) + { + ERR("Enumerator: no DISPID_NEWENUM.\n"); + hres = E_INVALIDARG; + goto cleanuperr; + } + + if ((V_VT(&varresult) == VT_DISPATCH) || + (V_VT(&varresult) == VT_UNKNOWN)) + { + hres = IUnknown_QueryInterface(V_UNKNOWN(&varresult), + &IID_IEnumVARIANT, (void**)&enumvar); + if (FAILED(hres)) + { + hres = E_INVALIDARG; + goto cleanuperr; + } + } + else + { + ERR("Enumerator: NewEnum unexpected type of varresult (%d).\n", V_VT(&varresult)); + hres = E_INVALIDARG; + goto cleanuperr; + } + VariantClear(&varresult); + + atend = FALSE; + } + else + { + ERR("I don't know how to handle this type!\n"); + hres = E_NOTIMPL; + goto cleanuperr; + }
hres = alloc_enumerator(ctx, NULL, &enumerator); if(FAILED(hres)) - return hres; + goto cleanuperr; + + enumerator->atend = atend; + enumerator->enumvar = enumvar; + + hres = enumvar_get_next_item(enumerator); + if (FAILED(hres)) + goto cleanuperr;
*ret = &enumerator->dispex; + return S_OK; +cleanuperr: + VariantClear(&varresult); + if (enumerator) + heap_free(enumerator); + return hres; } diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h index baebcc4b6c..879b2b837b 100644 --- a/dlls/jscript/jscript.h +++ b/dlls/jscript/jscript.h @@ -116,6 +116,7 @@ typedef enum { JSCLASS_ARRAY, JSCLASS_BOOLEAN, JSCLASS_DATE, + JSCLASS_ENUMERATOR, JSCLASS_ERROR, JSCLASS_FUNCTION, JSCLASS_GLOBAL, @@ -561,6 +562,7 @@ static inline DWORD make_grfdex(script_ctx_t *ctx, DWORD flags) #define JS_E_VBARRAY_EXPECTED MAKE_JSERROR(IDS_NOT_VBARRAY) #define JS_E_INVALID_DELETE MAKE_JSERROR(IDS_INVALID_DELETE) #define JS_E_JSCRIPT_EXPECTED MAKE_JSERROR(IDS_JSCRIPT_EXPECTED) +#define JS_E_ENUMERATOR_EXPECTED MAKE_JSERROR(IDS_NOT_ENUMERATOR) #define JS_E_REGEXP_SYNTAX MAKE_JSERROR(IDS_REGEXP_SYNTAX_ERROR) #define JS_E_INVALID_URI_CODING MAKE_JSERROR(IDS_URI_INVALID_CODING) #define JS_E_INVALID_URI_CHAR MAKE_JSERROR(IDS_URI_INVALID_CHAR) diff --git a/dlls/jscript/object.c b/dlls/jscript/object.c index 19d67b514f..3fa93c7d66 100644 --- a/dlls/jscript/object.c +++ b/dlls/jscript/object.c @@ -69,7 +69,7 @@ static HRESULT Object_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, u static const WCHAR regexpW[] = {'R','e','g','E','x','p',0}; static const WCHAR stringW[] = {'S','t','r','i','n','g',0}; /* Keep in sync with jsclass_t enum */ - static const WCHAR *names[] = {NULL, arrayW, booleanW, dateW, errorW, + static const WCHAR *names[] = {NULL, arrayW, booleanW, dateW, objectW, errorW, functionW, NULL, mathW, numberW, objectW, regexpW, stringW, objectW, objectW, objectW};
TRACE("\n"); diff --git a/dlls/jscript/resource.h b/dlls/jscript/resource.h index d15dd7a033..d171ce20f8 100644 --- a/dlls/jscript/resource.h +++ b/dlls/jscript/resource.h @@ -56,6 +56,7 @@ #define IDS_INVALID_DELETE 0x1394 #define IDS_NOT_VBARRAY 0x1395 #define IDS_JSCRIPT_EXPECTED 0x1396 +#define IDS_NOT_ENUMERATOR 0x1397 #define IDS_REGEXP_SYNTAX_ERROR 0x1399 #define IDS_URI_INVALID_CHAR 0x13A0 #define IDS_URI_INVALID_CODING 0x13A1 -- 2.11.0
Signed-off-by: Andreas Maier staubim@quantentunnel.de --- dlls/jscript/tests/api.js | 21 +++++- dlls/jscript/tests/run.c | 169 +++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 186 insertions(+), 4 deletions(-)
diff --git a/dlls/jscript/tests/api.js b/dlls/jscript/tests/api.js index f3d07f89f4..40a1b2d92f 100644 --- a/dlls/jscript/tests/api.js +++ b/dlls/jscript/tests/api.js @@ -58,8 +58,8 @@ testNoEnumerables("Function"); testNoEnumerables("Function.prototype"); testNoEnumerables("testNoEnumerates"); testNoEnumerables("VBArray"); -testNoEnumerables("new Enumerator([])"); -testNoEnumerables("Enumerator([])"); +testNoEnumerables("new Enumerator()"); +testNoEnumerables("Enumerator()");
ok(Object.propertyIsEnumerable("prototype") === false, "Object.prototype is enumerable"); ok(Math.propertyIsEnumerable("E") === false, "Math.E is enumerable"); @@ -343,7 +343,7 @@ ok(tmp === "[object Object]", "toString.call(this) = " + tmp); ok(tmp === "[object Object]", "toString.call(arguments) = " + tmp); tmp = Object.prototype.toString.call(new VBArray(createArray())); ok(tmp === "[object Object]", "toString.call(new VBArray()) = " + tmp); -(tmp = new Enumerator([])).f = Object.prototype.toString; +(tmp = new Enumerator()).f = Object.prototype.toString; ok(tmp.f() === "[object Object]", "tmp.f() = " + tmp.f());
function TSTestConstr() {} @@ -2452,6 +2452,7 @@ var exception_array = { E_OBJECT_EXPECTED: { type: "TypeError", number: -2146823281 }, E_OBJECT_REQUIRED: { type: "TypeError", number: -2146827864 }, E_UNSUPPORTED_ACTION: { type: "TypeError", number: -2146827843 }, + E_NOT_ENUMERATOR: { type: "TypeError", number: -2146823273 }, E_NOT_VBARRAY: { type: "TypeError", number: -2146823275 }, E_INVALID_DELETE: { type: "TypeError", number: -2146823276 }, E_UNDEFINED: { type: "TypeError", number: -2146823279 }, @@ -2717,6 +2718,15 @@ testArrayHostThis("join"); testArrayHostThis("pop"); testArrayHostThis("sort");
+function testEnumeratorThis(func) { + testThisExcept(Enumerator.prototype[func], "E_NOT_ENUMERATOR"); +} + +testEnumeratorThis("atEnd"); +testEnumeratorThis("item"); +testEnumeratorThis("moveFirst"); +testEnumeratorThis("moveNext"); + function testObjectInherit(obj, constr, ts, tls, vo) { ok(obj instanceof Object, "obj is not instance of Object"); ok(obj instanceof constr, "obj is not instance of its constructor"); @@ -3009,4 +3019,9 @@ ok(tmp.toArray() == "2,3,12,13,22,23,32,33,42,43", "tmp.toArray() = " + tmp.toAr ok(createArray().toArray() == "2,3,12,13,22,23,32,33,42,43", "createArray.toArray()=" + createArray().toArray());
+obj = new Enumerator(); +ok(obj.atEnd(), "atEnd() = " + obj.atEnd()); +obj.moveFirst(); +ok(obj.atEnd(), "atEnd() = " + obj.atEnd()); + reportSuccess(); diff --git a/dlls/jscript/tests/run.c b/dlls/jscript/tests/run.c index aadb31700d..c8a143beba 100644 --- a/dlls/jscript/tests/run.c +++ b/dlls/jscript/tests/run.c @@ -106,6 +106,10 @@ DEFINE_EXPECT(testobj_noprop_d); DEFINE_EXPECT(testobj_onlydispid_d); DEFINE_EXPECT(testobj_onlydispid_i); DEFINE_EXPECT(testobj_notexists_d); +DEFINE_EXPECT(testobj_newenum); +DEFINE_EXPECT(enumvariant_next_0); +DEFINE_EXPECT(enumvariant_next_1); +DEFINE_EXPECT(enumvariant_reset); DEFINE_EXPECT(GetItemInfo_testVal); DEFINE_EXPECT(ActiveScriptSite_OnScriptError); DEFINE_EXPECT(invoke_func); @@ -144,6 +148,7 @@ DEFINE_EXPECT(BindHandler); #define DISPID_GLOBAL_TESTPROPPUTREF 0x101b #define DISPID_GLOBAL_GETSCRIPTSTATE 0x101c #define DISPID_GLOBAL_BINDEVENTHANDLER 0x101d +#define DISPID_GLOBAL_TESTENUMOBJ 0x101e
#define DISPID_GLOBAL_TESTPROPDELETE 0x2000 #define DISPID_GLOBAL_TESTNOPROPDELETE 0x2001 @@ -219,6 +224,101 @@ static void _test_grfdex(unsigned line, DWORD grfdex, DWORD expect) ok_(__FILE__,line)(grfdex == expect, "grfdex = %x, expected %x\n", grfdex, expect); }
+static HRESULT WINAPI EnumVARIANT_QueryInterface(IEnumVARIANT *iface, REFIID riid, void **ppv) +{ + *ppv = NULL; + + if (IsEqualGUID(riid, &IID_IEnumVARIANT)) + *ppv = iface; + else + return E_NOINTERFACE; + + return S_OK; +} + +static ULONG WINAPI EnumVARIANT_AddRef(IEnumVARIANT *iface) +{ + return 2; +} + +static ULONG WINAPI EnumVARIANT_Release(IEnumVARIANT *iface) +{ + return 1; +} + +static int EnumVARIANT_index = 0; +static int EnumVARIANT_next_0_count = 0; +static HRESULT WINAPI EnumVARIANT_Next( + IEnumVARIANT *This, + ULONG celt, + VARIANT *rgVar, + ULONG *pCeltFetched) +{ + ok(rgVar != NULL, "rgVar is NULL\n"); + ok(celt == 1, "celt = %d\n", celt); + ok(pCeltFetched == NULL, "pCeltFetched is not NULL\n"); + + if (!rgVar) + return S_FALSE; + + if (EnumVARIANT_index == 0) + { + EnumVARIANT_next_0_count--; + if (EnumVARIANT_next_0_count <= 0) + CHECK_EXPECT(enumvariant_next_0); + + V_VT(rgVar) = VT_I4; + V_I4(rgVar) = 123; + + if (pCeltFetched) + *pCeltFetched = 1; + EnumVARIANT_index++; + return S_OK; + } + + CHECK_EXPECT(enumvariant_next_1); + + if (pCeltFetched) + *pCeltFetched = 0; + return S_FALSE; + +} + +static HRESULT WINAPI EnumVARIANT_Skip( + IEnumVARIANT *This, + ULONG celt) +{ + ok(0, "EnumVariant_Skip: unexpected call\n"); + return E_NOTIMPL; +} +static HRESULT WINAPI EnumVARIANT_Reset( + IEnumVARIANT *This) +{ + CHECK_EXPECT(enumvariant_reset); + EnumVARIANT_index = 0; + return S_OK; +} + +static HRESULT WINAPI EnumVARIANT_Clone( + IEnumVARIANT *This, + IEnumVARIANT **ppEnum) +{ + ok(0, "EnumVariant_Clone: unexpected call\n"); + return E_NOTIMPL; +} + +static IEnumVARIANTVtbl testEnumVARIANTVtbl = { + EnumVARIANT_QueryInterface, + EnumVARIANT_AddRef, + EnumVARIANT_Release, + EnumVARIANT_Next, + EnumVARIANT_Skip, + EnumVARIANT_Reset, + EnumVARIANT_Clone +}; + +static IEnumVARIANT testEnumVARIANT = { &testEnumVARIANTVtbl }; + static HRESULT WINAPI DispatchEx_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv) { *ppv = NULL; @@ -320,6 +420,28 @@ static HRESULT WINAPI DispatchEx_GetNameSpaceParent(IDispatchEx *iface, IUnknown return E_NOTIMPL; }
+static HRESULT WINAPI testObj_Invoke(IDispatchEx *iface, DISPID id, + REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pdp, + VARIANT *pvarRes, EXCEPINFO *pei, UINT *puArgErr) +{ + switch(id) { + case DISPID_NEWENUM: + ok(pdp != NULL, "pdp == NULL\n"); + ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n"); + ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs); + ok(pvarRes != NULL, "pvarRes == NULL\n"); + ok(pei == NULL, "pei != NULL\n"); + + CHECK_EXPECT(testobj_newenum); + V_VT(pvarRes) = VT_DISPATCH; + V_DISPATCH(pvarRes) = (IDispatch*)&testEnumVARIANT; + return S_OK; + } + + ok(0, "unexpected call %x\n", id); + return DISP_E_MEMBERNOTFOUND; +} + static HRESULT WINAPI testObj_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid) { if(!strcmp_wa(bstrName, "prop")) { @@ -453,7 +575,7 @@ static IDispatchExVtbl testObjVtbl = { DispatchEx_GetTypeInfoCount, DispatchEx_GetTypeInfo, DispatchEx_GetIDsOfNames, - DispatchEx_Invoke, + testObj_Invoke, testObj_GetDispID, testObj_InvokeEx, testObj_DeleteMemberByName, @@ -861,6 +983,11 @@ static HRESULT WINAPI Global_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD return S_OK; }
+ if(!strcmp_wa(bstrName, "testEnumObj")) { + *pid = DISPID_GLOBAL_TESTENUMOBJ; + return S_OK; + } + if(strict_dispid_check && strcmp_wa(bstrName, "t")) ok(0, "unexpected call %s\n", wine_dbgstr_w(bstrName)); return DISP_E_UNKNOWNNAME; @@ -2682,6 +2809,46 @@ static BOOL run_tests(void) CHECK_CALLED(global_success_d); CHECK_CALLED(global_success_i);
+ EnumVARIANT_index = 0; + EnumVARIANT_next_0_count = 1; + SET_EXPECT(testobj_newenum); + SET_EXPECT(enumvariant_next_0); + parse_script_a("new Enumerator(testObj);"); + CHECK_CALLED(testobj_newenum); + CHECK_CALLED(enumvariant_next_0); + + EnumVARIANT_index = 0; + EnumVARIANT_next_0_count = 2; + SET_EXPECT(testobj_newenum); + SET_EXPECT(enumvariant_next_0); + SET_EXPECT(enumvariant_reset); + parse_script_a("(function () {" + " var testEnumObj = new Enumerator(testObj);" + " var tmp = testEnumObj.moveFirst();" + " ok(tmp == undefined, "testEnumObj.moveFirst() = " + tmp);" + "})()"); + CHECK_CALLED(testobj_newenum); + CHECK_CALLED(enumvariant_next_0); + CHECK_CALLED(enumvariant_reset); + + EnumVARIANT_index = 0; + EnumVARIANT_next_0_count = 1; + SET_EXPECT(testobj_newenum); + SET_EXPECT(enumvariant_next_0); + SET_EXPECT(enumvariant_next_1); + parse_script_a("(function () {" + " var testEnumObj = new Enumerator(testObj);" + " while (!testEnumObj.atEnd())" + " {" + " ok(testEnumObj.item() == 123, " + " "testEnumObj.item() = "+testEnumObj.item());" + " testEnumObj.moveNext();" + " }" + "})()"); + CHECK_CALLED(testobj_newenum); + CHECK_CALLED(enumvariant_next_0); + CHECK_CALLED(enumvariant_next_1); + run_from_res("lang.js"); run_from_res("api.js"); run_from_res("regexp.js"); -- 2.11.0
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=52320
Your paranoid android.
=== debian9 (32 bit report) ===
jscript: run.c:1997: Test failed: expected global_success_d run.c:1998: Test failed: expected global_success_i run.c:2000: Test failed: parse_script failed: 80070057 run.c:1997: Test failed: expected global_success_d run.c:1998: Test failed: expected global_success_i run.c:2000: Test failed: parse_script failed: 80070057
=== debian9 (32 bit Chinese:China report) ===
jscript: run.c:1997: Test failed: expected global_success_d run.c:1998: Test failed: expected global_success_i run.c:2000: Test failed: parse_script failed: 80070057 run.c:1997: Test failed: expected global_success_d run.c:1998: Test failed: expected global_success_i run.c:2000: Test failed: parse_script failed: 80070057
=== debian9 (32 bit WoW report) ===
jscript: run.c:1997: Test failed: expected global_success_d run.c:1998: Test failed: expected global_success_i run.c:2000: Test failed: parse_script failed: 80070057 run.c:1997: Test failed: expected global_success_d run.c:1998: Test failed: expected global_success_i run.c:2000: Test failed: parse_script failed: 80070057
=== debian9 (64 bit WoW report) ===
jscript: run.c:1997: Test failed: expected global_success_d run.c:1998: Test failed: expected global_success_i run.c:2000: Test failed: parse_script failed: 80070057 run.c:1997: Test failed: expected global_success_d run.c:1998: Test failed: expected global_success_i run.c:2000: Test failed: parse_script failed: 80070057
Andreas Maier staubim@quantentunnel.de wrote:
+static inline HRESULT enumvar_get_next_item(EnumeratorInstance *This) +{
- HRESULT hres;
- VARIANT nextitem;
- if (This->atend)
- {
This->item = jsval_undefined();
return S_OK;
- }
- /* dont leak pervious value */
- jsval_release(This->item);
- /* not at end ... get next item */
- VariantInit(&nextitem);
- hres = IEnumVARIANT_Next(This->enumvar, 1, &nextitem, NULL);
- if (hres == S_OK)
- {
hres = variant_to_jsval(&nextitem, &This->item);
if (FAILED(hres))
{
ERR("failed to convert jsval to variant!");
This->item = jsval_undefined();
}
- }
- else
- {
This->item = jsval_undefined();
This->atend = TRUE;
- }
- VariantClear(&nextitem);
- return S_OK;
+}
It should be possible to get rid of the 'atend' variable.
default:
FIXME("unimplemented flags: %x\n", flags);
ERR("unimplemented flags: %x\n", flags);
It still should be FIXME. Also all the remaining ERR()s should be changed either to a WARN() or a FIXME().
On 16/05/2019 08:52, Dmitry Timoshkov wrote:
Andreas Maier staubim@quantentunnel.de wrote:
+static inline HRESULT enumvar_get_next_item(EnumeratorInstance *This) +{
- HRESULT hres;
- VARIANT nextitem;
- if (This->atend)
- {
This->item = jsval_undefined();
return S_OK;
- }
- /* dont leak pervious value */
- jsval_release(This->item);
- /* not at end ... get next item */
- VariantInit(&nextitem);
- hres = IEnumVARIANT_Next(This->enumvar, 1, &nextitem, NULL);
- if (hres == S_OK)
- {
hres = variant_to_jsval(&nextitem, &This->item);
if (FAILED(hres))
{
ERR("failed to convert jsval to variant!");
This->item = jsval_undefined();
}
- }
- else
- {
This->item = jsval_undefined();
This->atend = TRUE;
- }
- VariantClear(&nextitem);
- return S_OK;
+}
It should be possible to get rid of the 'atend' variable.
Not really, we shouldn't call Next() if we know we're at the end of collection. It's also needed in other places. However, there is no need to set item value in early return case. It should be already set by previous call.
Jacek