jscript: Make Array.sort generic.

This commit is contained in:
Piotr Caban 2010-01-20 17:14:44 +01:00 committed by Alexandre Julliard
parent 91dcc245f9
commit 8644a083a6
2 changed files with 21 additions and 14 deletions

View File

@ -685,10 +685,10 @@ static HRESULT sort_cmp(script_ctx_t *ctx, DispatchEx *cmp_func, VARIANT *v1, VA
} }
/* ECMA-262 3rd Edition 15.4.4.11 */ /* ECMA-262 3rd Edition 15.4.4.11 */
static HRESULT Array_sort(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, static HRESULT Array_sort(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller) VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
{ {
DispatchEx *cmp_func = NULL; DispatchEx *jsthis, *cmp_func = NULL;
VARIANT *vtab, **sorttab = NULL; VARIANT *vtab, **sorttab = NULL;
DWORD length; DWORD length;
DWORD i; DWORD i;
@ -696,12 +696,9 @@ static HRESULT Array_sort(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPA
TRACE("\n"); TRACE("\n");
if(is_vclass(jsthis, JSCLASS_ARRAY)) { hres = get_length(ctx, vthis, ei, &jsthis, &length);
length = array_from_vdisp(jsthis)->length; if(FAILED(hres))
}else { return hres;
FIXME("unsupported this not array\n");
return E_NOTIMPL;
}
if(arg_cnt(dp) > 1) { if(arg_cnt(dp) > 1) {
WARN("invalid arg_cnt %d\n", arg_cnt(dp)); WARN("invalid arg_cnt %d\n", arg_cnt(dp));
@ -731,8 +728,8 @@ static HRESULT Array_sort(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPA
jsdisp_release(cmp_func); jsdisp_release(cmp_func);
if(retv) { if(retv) {
V_VT(retv) = VT_DISPATCH; V_VT(retv) = VT_DISPATCH;
V_DISPATCH(retv) = jsthis->u.disp; V_DISPATCH(retv) = (IDispatch*)_IDispatchEx_(jsthis);
IDispatch_AddRef(jsthis->u.disp); IDispatch_AddRef(V_DISPATCH(retv));
} }
return S_OK; return S_OK;
} }
@ -740,7 +737,7 @@ static HRESULT Array_sort(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPA
vtab = heap_alloc_zero(length * sizeof(VARIANT)); vtab = heap_alloc_zero(length * sizeof(VARIANT));
if(vtab) { if(vtab) {
for(i=0; i<length; i++) { for(i=0; i<length; i++) {
hres = jsdisp_propget_idx(jsthis->u.jsdisp, i, vtab+i, ei, caller); hres = jsdisp_propget_idx(jsthis, i, vtab+i, ei, caller);
if(FAILED(hres) && hres != DISP_E_UNKNOWNNAME) { if(FAILED(hres) && hres != DISP_E_UNKNOWNNAME) {
WARN("Could not get elem %d: %08x\n", i, hres); WARN("Could not get elem %d: %08x\n", i, hres);
break; break;
@ -817,7 +814,7 @@ static HRESULT Array_sort(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPA
} }
for(i=0; SUCCEEDED(hres) && i < length; i++) for(i=0; SUCCEEDED(hres) && i < length; i++)
hres = jsdisp_propput_idx(jsthis->u.jsdisp, i, sorttab[i], ei, caller); hres = jsdisp_propput_idx(jsthis, i, sorttab[i], ei, caller);
} }
if(vtab) { if(vtab) {
@ -834,8 +831,8 @@ static HRESULT Array_sort(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPA
if(retv) { if(retv) {
V_VT(retv) = VT_DISPATCH; V_VT(retv) = VT_DISPATCH;
V_DISPATCH(retv) = jsthis->u.disp; V_DISPATCH(retv) = (IDispatch*)_IDispatchEx_(jsthis);
IDispatch_AddRef(jsthis->u.disp); IDispatch_AddRef(V_DISPATCH(retv));
} }
return S_OK; return S_OK;

View File

@ -695,6 +695,15 @@ ok(arr.sort() === arr, "arr.sort() !== arr");
for(var i=0; i < arr.length; i++) for(var i=0; i < arr.length; i++)
ok(arr[i] === tmp[i], "arr[" + i + "] = " + arr[i] + " expected " + tmp[i]); ok(arr[i] === tmp[i], "arr[" + i + "] = " + arr[i] + " expected " + tmp[i]);
arr = new Object();
arr.length = 3;
arr[0] = 1;
arr[2] = "aa";
arr.sort = Array.prototype.sort;
tmp = arr.sort();
ok(arr === tmp, "tmp !== arr");
ok(arr[0]===1 && arr[1]==="aa" && arr[2]===undefined, "arr is sorted incorectly");
arr = ["1", "2", "3"]; arr = ["1", "2", "3"];
arr.length = 1; arr.length = 1;
ok(arr.length === 1, "arr.length = " + arr.length); ok(arr.length === 1, "arr.length = " + arr.length);
@ -1903,6 +1912,7 @@ testArrayHostThis("unshift");
testArrayHostThis("reverse"); testArrayHostThis("reverse");
testArrayHostThis("join"); testArrayHostThis("join");
testArrayHostThis("pop"); testArrayHostThis("pop");
testArrayHostThis("sort");
function testObjectInherit(obj, constr, ts, tls, vo) { function testObjectInherit(obj, constr, ts, tls, vo) {
ok(obj instanceof Object, "obj is not instance of Object"); ok(obj instanceof Object, "obj is not instance of Object");