Signed-off-by: Andreas Maier staubim@quantentunnel.de --- dlls/jscript/enumerator.c | 292 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 280 insertions(+), 12 deletions(-)
diff --git a/dlls/jscript/enumerator.c b/dlls/jscript/enumerator.c index aa7737ac52..9d47b70d42 100644 --- a/dlls/jscript/enumerator.c +++ b/dlls/jscript/enumerator.c @@ -17,6 +17,7 @@ */
#include <assert.h> +#include <sal.h>
#include "jscript.h"
@@ -24,8 +25,23 @@
WINE_DEFAULT_DEBUG_CHANNEL(jscript);
+#define DATATYPE_NULL 0 +#define DATATYPE_ARRAY 1 +#define DATATYPE_ENUMVARIANT 2 + typedef struct { jsdisp_t dispex; + int datatype; + BOOL atend; + /* constructor with jsarray e.g. ["A","B"] */ + jsdisp_t *array; + /* current index of jsarray */ + int arrayidx; + int arraylen; + /* IEnumVARIANT returned by _NewEnum */ + IEnumVARIANT *enumvar; + /* IEnumVARIANT current item */ + VARIANT* enumitm; } EnumeratorInstance;
static const WCHAR atEndW[] = {'a','t','E','n','d',0}; @@ -33,43 +49,197 @@ 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 HRESULT enumary_get_item( + _In_ EnumeratorInstance *This, + _Out_ jsval_t *r) +{ + HRESULT hres; + + if (!r) + return S_OK; + + if (This->atend) + { + *r = jsval_undefined(); + return S_OK; + } + + hres = jsdisp_get_idx(This->array, This->arrayidx, r); + if (FAILED(hres)) + *r = jsval_undefined(); + + return S_OK; +} + +static inline HRESULT enumvar_get_next_item( + _In_ IEnumVARIANT* enumvar, + _Inout_ VARIANT* enumitm, + _Inout_ BOOL* atend, + _Out_opt_ jsval_t *r) +{ + HRESULT hres; + + /* not at end ... get next item */ + if (!(*atend)) + { + /* Assume valid variant */ + VariantClear(enumitm); + hres = IEnumVARIANT_Next(enumvar, 1, enumitm, NULL); + if (hres != S_OK) + { + VariantClear(enumitm); + *atend = TRUE; + } + } + + if (*atend) + { + if (r) + *r = jsval_undefined(); + return S_OK; + } + + if (r) + return variant_to_jsval(enumitm, r); + + return S_OK; +} + static void Enumerator_destructor(jsdisp_t *dispex) { + EnumeratorInstance *This; + TRACE("Enumerator_destructor\n");
+ This = enumerator_from_jsdisp(dispex); + + if (This->enumitm) + { + VariantClear(This->enumitm); + heap_free(This->enumitm); + } + heap_free(dispex); }
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; + + This = enumerator_from_vdisp(jsthis); + + if (r) + *r = jsval_bool(This->atend);
- return E_NOTIMPL; + TRACE("Enumerator_atEnd %d\n", This->atend); + + return S_OK; }
HRESULT Enumerator_item(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) { + EnumeratorInstance *This; + HRESULT hres = E_FAIL; + TRACE("Enumerator_item\n");
- return E_NOTIMPL; + This = enumerator_from_vdisp(jsthis); + + if (This->datatype == DATATYPE_ARRAY) + { + hres = enumary_get_item(This, r); + } + else if (This->datatype == DATATYPE_ENUMVARIANT) + { + hres = variant_to_jsval(This->enumitm, r); + } + else if (This->datatype == DATATYPE_NULL) + { + if (r) + *r = jsval_undefined(); + hres = S_OK; + } + + return hres; }
HRESULT Enumerator_moveFirst(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) { + EnumeratorInstance *This; + HRESULT hres = E_FAIL; + TRACE("Enumerator_moveFirst\n");
- return E_NOTIMPL; + This = enumerator_from_vdisp(jsthis); + if (This->datatype == DATATYPE_ARRAY) + { + This->arrayidx = 0; + This->atend = FALSE; + hres = enumary_get_item(This, r); + } + else if (This->datatype == DATATYPE_ENUMVARIANT) + { + IEnumVARIANT_Reset(This->enumvar); + hres = enumvar_get_next_item(This->enumvar, This->enumitm, &This->atend, r); + } + else if (This->datatype == DATATYPE_NULL) + { + if (r) + *r = jsval_undefined(); + hres = S_OK; + } + + return hres; }
HRESULT Enumerator_moveNext(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) { + EnumeratorInstance *This; + HRESULT hres = E_FAIL; + TRACE("Enumerator_moveNext\n");
- return E_NOTIMPL; + This = enumerator_from_vdisp(jsthis); + + if (This->atend) + { + if (r) + *r = jsval_undefined(); + return S_OK; + } + if (This->datatype == DATATYPE_ARRAY) + { + if (This->arrayidx <= This->arraylen) + This->arrayidx++; + This->atend = (This->arrayidx > This->arraylen); + hres = enumary_get_item(This, r); + } + else if (This->datatype == DATATYPE_ENUMVARIANT) + { + hres = enumvar_get_next_item(This->enumvar, This->enumitm, &This->atend, r); + } + else if (This->datatype == DATATYPE_NULL) + { + if (r) + *r = jsval_undefined(); + hres = S_OK; + } + + return hres; }
static const builtin_prop_t Enumerator_props[] = { @@ -101,16 +271,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");
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 +290,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 +312,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 +353,106 @@ HRESULT create_enumerator(script_ctx_t *ctx, jsval_t *argv, jsdisp_t **ret) { EnumeratorInstance *enumerator; HRESULT hres; + BOOL atend; + IDispatch *obj; + DISPPARAMS dispparams = {NULL, NULL, 0, 0}; + VARIANT varresult; + + int datatype = -1; + int arrayidx = 0; + int arraylen = 0; + jsdisp_t *array = NULL; + IEnumVARIANT *enumvar = NULL; + VARIANT *enumitm = NULL; + + /* new Enumerator() */ + if (argv == NULL) + { + datatype = DATATYPE_NULL; + atend = TRUE; + } + else if(is_object_instance(*argv)) + { + obj = get_object(*argv); + array = iface_to_jsdisp(obj); + if ((array) && + (is_class(array, JSCLASS_ARRAY))) + { + datatype = DATATYPE_ARRAY; + arraylen = array_get_length(array); + /* atend is here always FALSE + * MS returns a "undefined"-element after + * the last element of the given array. + * Because of this, there is at least one + * element to return. */ + atend = FALSE; + } + else + { + if (array) + jsdisp_release(array); + + datatype = DATATYPE_ENUMVARIANT; + /* Try to get a IEnumVARIANT by _NewEnum */ + memset(&varresult, 0, sizeof(VARIANT)); + VariantInit(&varresult); + 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"); + VariantClear(&varresult); + return E_INVALIDARG; + } + if (V_VT(&varresult) != VT_DISPATCH) + { + ERR("Enumerator: NewEnum unexpected result.\n"); + VariantClear(&varresult); + return E_INVALIDARG; + } + enumvar = (IEnumVARIANT*)V_DISPATCH(&varresult); + VariantClear(&varresult); + + enumitm = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(VARIANT)); + if (!enumitm) + { + hres = E_OUTOFMEMORY; + goto cleanuperr; + } + VariantInit(enumitm); + + atend = FALSE; + enumvar_get_next_item(enumvar, enumitm, &atend, NULL); + } + } + 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->datatype = datatype; + enumerator->atend = atend; + enumerator->array = array; + enumerator->arraylen = arraylen; + enumerator->arrayidx = arrayidx; + enumerator->enumvar = enumvar; + enumerator->enumitm = enumitm;
*ret = &enumerator->dispex; - return S_OK; + + return S_OK; +cleanuperr: + if (enumitm) + { + VariantClear(enumitm); + HeapFree(GetProcessHeap(), 0, enumitm); + } + return hres; } -- 2.11.0
Patch created by Jacek Caban jacek@codeweavers.com
Signed-off-by: Andreas Maier staubim@quantentunnel.de --- dlls/jscript/tests/run.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/jscript/tests/run.c b/dlls/jscript/tests/run.c index aadb31700d..e79e02f189 100644 --- a/dlls/jscript/tests/run.c +++ b/dlls/jscript/tests/run.c @@ -267,7 +267,7 @@ static HRESULT WINAPI DispatchEx_Invoke(IDispatchEx *iface, DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) { - ok(0, "unexpected call\n"); + ok(0, "unexpected call %d\n", dispIdMember); return E_NOTIMPL; }
-- 2.11.0
On 4/24/19 10:38 PM, Andreas Maier wrote:
Patch created by Jacek Caban jacek@codeweavers.com
Signed-off-by: Andreas Maier staubim@quantentunnel.de
dlls/jscript/tests/run.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/jscript/tests/run.c b/dlls/jscript/tests/run.c index aadb31700d..e79e02f189 100644 --- a/dlls/jscript/tests/run.c +++ b/dlls/jscript/tests/run.c @@ -267,7 +267,7 @@ static HRESULT WINAPI DispatchEx_Invoke(IDispatchEx *iface, DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) {
- ok(0, "unexpected call\n");
- ok(0, "unexpected call %d\n", dispIdMember); return E_NOTIMPL;
Please just skip this, you add a better version in your patch anyway.
Jacek
Signed-off-by: Andreas Maier staubim@quantentunnel.de --- dlls/jscript/tests/api.js | 36 +++++++++ dlls/jscript/tests/run.c | 200 +++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 235 insertions(+), 1 deletion(-)
diff --git a/dlls/jscript/tests/api.js b/dlls/jscript/tests/api.js index f3d07f89f4..c6ffb20714 100644 --- a/dlls/jscript/tests/api.js +++ b/dlls/jscript/tests/api.js @@ -3009,4 +3009,40 @@ 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()); + +obj = new Enumerator([]); +ok(!obj.atEnd(), "atEnd() = " + obj.atEnd()); +obj.moveFirst(); +ok(!obj.atEnd(), "atEnd() = " + obj.atEnd()); +obj.moveNext(); +ok(obj.atEnd(), "atEnd() = " + obj.atEnd()); +obj.moveNext(); + +objdata = ["A","B"]; +obj = new Enumerator(objdata); +ok(obj.atEnd() == false, "atEnd() = " + obj.atEnd()); +ok(obj.item() === objdata[0], "obj.item() = " + obj.item() + + ", expected " + objdata[0]); +obj.moveFirst(); +for (var i1 = 0; i1 < objdata.length; i1++) +{ + if (obj.atEnd()) + { + ok(false, i1 + "missing items!"); + break; + } + ok(obj.item() === objdata[i1], "obj.item() = " + obj.item() + + ", expected " + objdata[i1]); + obj.moveNext(); +} +ok(!obj.atEnd(), "obj.atEnd() = " + obj.atEnd()); +obj.moveNext(); +ok(obj.item() === undefined, "obj.item() = " + obj.item() + + ", expected " + undefined); +ok(obj.atEnd(), "obj.atEnd() = " + obj.atEnd()); + reportSuccess(); diff --git a/dlls/jscript/tests/run.c b/dlls/jscript/tests/run.c index e79e02f189..9b68643d49 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,97 @@ 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 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) + { + 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 +416,29 @@ 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(V_VT(pvarRes) == VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes)); + 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 +572,7 @@ static IDispatchExVtbl testObjVtbl = { DispatchEx_GetTypeInfoCount, DispatchEx_GetTypeInfo, DispatchEx_GetIDsOfNames, - DispatchEx_Invoke, + testObj_Invoke, testObj_GetDispID, testObj_InvokeEx, testObj_DeleteMemberByName, @@ -466,6 +585,9 @@ static IDispatchExVtbl testObjVtbl = {
static IDispatchEx testObj = { &testObjVtbl };
+static VARIANT testEnumObj; +static BOOL testEnumObjValid = FALSE; + static HRESULT WINAPI dispexFunc_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp, VARIANT *res, EXCEPINFO *pei, IServiceProvider *pspCaller) { @@ -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; @@ -1365,6 +1492,54 @@ static HRESULT WINAPI Global_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid,
return S_OK; } + case DISPID_GLOBAL_TESTENUMOBJ: + { + HRESULT hres; + + if (wFlags == (INVOKE_PROPERTYPUT|INVOKE_PROPERTYPUTREF)) + { + ok(wFlags == (INVOKE_PROPERTYPUT|INVOKE_PROPERTYPUTREF), "wFlags = %x\n", wFlags); + ok(pdp != NULL, "pdp == NULL\n"); + ok(pdp->rgvarg != NULL, "rgvarg == NULL\n"); + ok(pdp->rgdispidNamedArgs != NULL, "rgdispidNamedArgs == NULL\n"); + ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs); + ok(pdp->cNamedArgs == 1, "cNamedArgs = %d\n", pdp->cNamedArgs); + ok(!pvarRes, "pvarRes != NULL\n"); + if ((pdp->rgvarg != NULL) && + (pdp->cArgs == 1) && + (pdp->cNamedArgs == 1) && + (pdp->rgdispidNamedArgs[0] == DISPID_PROPERTYPUT)) + { + if (!testEnumObjValid) + { + memset(&testEnumObj, 0, sizeof(VARIANT)); + testEnumObjValid = TRUE; + VariantInit(&testEnumObj); + } + else + VariantClear(&testEnumObj); + hres = VariantCopy(&testEnumObj, pdp->rgvarg); + ok(SUCCEEDED(hres), "VariantCopy failed!\n"); + } + } + else + { + ok(wFlags == INVOKE_PROPERTYGET, "wFlags = %x\n", wFlags); + ok(pdp != NULL, "pdp == NULL\n"); + ok(!pdp->rgvarg, "rgvarg != NULL\n"); + ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n"); + ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs); + ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs); + ok(pvarRes != NULL, "pvarRes == NULL\n"); + + if ((pvarRes != NULL) && (testEnumObjValid)) + { + hres = VariantCopy(pvarRes, &testEnumObj); + ok(SUCCEEDED(hres), "VariantCopy failed!\n"); + } + } + return S_OK; + } }
ok(0, "unexpected call %x\n", id); @@ -2682,6 +2857,29 @@ static BOOL run_tests(void) CHECK_CALLED(global_success_d); CHECK_CALLED(global_success_i);
+ EnumVARIANT_index = 0; + 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; + SET_EXPECT(testobj_newenum); + SET_EXPECT(enumvariant_next_0); + SET_EXPECT(enumvariant_next_1); + parse_script_a("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=51486
Your paranoid android.
=== wxppro (32 bit report) ===
jscript: run.c:429: Test failed: V_VT(pvarRes) = 63272 run.c:429: Test failed: V_VT(pvarRes) = 63272 run.c:429: Test failed: V_VT(pvarRes) = 63272 run.c:429: Test failed: V_VT(pvarRes) = 63272
=== w2003std (32 bit report) ===
jscript: run.c:429: Test failed: V_VT(pvarRes) = 63272 run.c:429: Test failed: V_VT(pvarRes) = 63272 run.c:429: Test failed: V_VT(pvarRes) = 63272 run.c:429: Test failed: V_VT(pvarRes) = 63272
=== wvistau64 (64 bit report) ===
jscript: run.c:429: Test failed: V_VT(pvarRes) = 1 run.c:429: Test failed: V_VT(pvarRes) = 1 run.c:429: Test failed: V_VT(pvarRes) = 1 run.c:429: Test failed: V_VT(pvarRes) = 1
=== w2008s64 (64 bit report) ===
jscript: run.c:429: Test failed: V_VT(pvarRes) = 1 run.c:429: Test failed: V_VT(pvarRes) = 1 run.c:429: Test failed: V_VT(pvarRes) = 1 run.c:429: Test failed: V_VT(pvarRes) = 1
=== w1064 (64 bit report) ===
jscript: run.c:429: Test failed: V_VT(pvarRes) = 23622 run.c:429: Test failed: V_VT(pvarRes) = 23622 run.c:429: Test failed: V_VT(pvarRes) = 23622 run.c:429: Test failed: V_VT(pvarRes) = 23622
Hi Andreas,
On 4/24/19 10:38 PM, Andreas Maier wrote:
Signed-off-by: Andreas Maier staubim@quantentunnel.de
dlls/jscript/enumerator.c | 292 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 280 insertions(+), 12 deletions(-)
diff --git a/dlls/jscript/enumerator.c b/dlls/jscript/enumerator.c index aa7737ac52..9d47b70d42 100644 --- a/dlls/jscript/enumerator.c +++ b/dlls/jscript/enumerator.c @@ -17,6 +17,7 @@ */
#include <assert.h> +#include <sal.h>
We don't use that in Wine. Please avoid _In_, _Out_ in Wine.
#include "jscript.h"
@@ -24,8 +25,23 @@
WINE_DEFAULT_DEBUG_CHANNEL(jscript);
+#define DATATYPE_NULL 0 +#define DATATYPE_ARRAY 1 +#define DATATYPE_ENUMVARIANT 2
- typedef struct { jsdisp_t dispex;
- int datatype;
- BOOL atend;
- /* constructor with jsarray e.g. ["A","B"] */
- jsdisp_t *array;
I tested it a bit more and it looks like builtin array object also exposes DISPID_NEWENUM (see the attached patch). It means that we don't need to special-case it here. It should simplify the code here a lot.
I realize that adding support for DISPID_NEWENUM to builtin arrays may be tricky, but feel free to ignore it for the first iteration. It's probably not needed for the bug you mentioned anyway.
Thanks,
Jacek
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=51595
Your paranoid android.
=== debian9 (32 bit report) ===
jscript: run.c:2385: Test failed: InvokeEx failed: 80020003 run.c:2386: Test failed: V_VT(v) = 0 run.c:2385: Test failed: InvokeEx failed: 80020003 run.c:2386: Test failed: V_VT(v) = 0
=== debian9 (32 bit French report) ===
jscript: run.c:2385: Test failed: InvokeEx failed: 80020003 run.c:2386: Test failed: V_VT(v) = 0 run.c:2385: Test failed: InvokeEx failed: 80020003 run.c:2386: Test failed: V_VT(v) = 0
=== debian9 (32 bit Japanese:Japan report) ===
jscript: run.c:2385: Test failed: InvokeEx failed: 80020003 run.c:2386: Test failed: V_VT(v) = 0 run.c:2385: Test failed: InvokeEx failed: 80020003 run.c:2386: Test failed: V_VT(v) = 0
=== debian9 (32 bit Chinese:China report) ===
jscript: run.c:2385: Test failed: InvokeEx failed: 80020003 run.c:2386: Test failed: V_VT(v) = 0 run.c:2385: Test failed: InvokeEx failed: 80020003 run.c:2386: Test failed: V_VT(v) = 0
=== debian9 (32 bit WoW report) ===
jscript: run.c:2385: Test failed: InvokeEx failed: 80020003 run.c:2386: Test failed: V_VT(v) = 0 run.c:2385: Test failed: InvokeEx failed: 80020003 run.c:2386: Test failed: V_VT(v) = 0
=== debian9 (64 bit WoW report) ===
jscript: run.c:2385: Test failed: InvokeEx failed: 80020003 run.c:2386: Test failed: V_VT(v) = 0 run.c:2385: Test failed: InvokeEx failed: 80020003 run.c:2386: Test failed: V_VT(v) = 0