jscript: Added Array.splice implementation.
This commit is contained in:
parent
a7e8cdf373
commit
176ba8cf95
|
@ -750,11 +750,118 @@ static HRESULT Array_sort(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
/* ECMA-262 3rd Edition 15.4.4.12 */
|
||||
static HRESULT Array_splice(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
|
||||
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
DWORD length, start=0, delete_cnt=0, argc, i, add_args = 0;
|
||||
DispatchEx *ret_array = NULL;
|
||||
VARIANT v;
|
||||
HRESULT hres = S_OK;
|
||||
|
||||
TRACE("\n");
|
||||
|
||||
if(is_class(dispex, JSCLASS_ARRAY)) {
|
||||
length = ((ArrayInstance*)dispex)->length;
|
||||
}else {
|
||||
hres = get_jsdisp_length(dispex, lcid, ei, &length);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
}
|
||||
|
||||
argc = arg_cnt(dp);
|
||||
if(argc >= 1) {
|
||||
hres = to_integer(dispex->ctx, get_arg(dp,0), ei, &v);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
if(V_VT(&v) == VT_I4) {
|
||||
if(V_I4(&v) >= 0)
|
||||
start = min(V_I4(&v), length);
|
||||
else
|
||||
start = -V_I4(&v) > length ? 0 : length + V_I4(&v);
|
||||
}else {
|
||||
start = V_R8(&v) < 0.0 ? 0 : length;
|
||||
}
|
||||
}
|
||||
|
||||
if(argc >= 2) {
|
||||
hres = to_integer(dispex->ctx, get_arg(dp,1), ei, &v);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
if(V_VT(&v) == VT_I4) {
|
||||
if(V_I4(&v) > 0)
|
||||
delete_cnt = min(V_I4(&v), length-start);
|
||||
}else if(V_R8(&v) > 0.0) {
|
||||
delete_cnt = length-start;
|
||||
}
|
||||
|
||||
add_args = argc-2;
|
||||
}
|
||||
|
||||
if(retv) {
|
||||
hres = create_array(dispex->ctx, 0, &ret_array);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
for(i=0; SUCCEEDED(hres) && i < delete_cnt; i++) {
|
||||
hres = jsdisp_propget_idx(dispex, start+i, lcid, &v, ei, caller);
|
||||
if(hres == DISP_E_UNKNOWNNAME)
|
||||
hres = S_OK;
|
||||
else if(SUCCEEDED(hres))
|
||||
hres = jsdisp_propput_idx(ret_array, i, lcid, &v, ei, caller);
|
||||
}
|
||||
|
||||
if(SUCCEEDED(hres)) {
|
||||
V_VT(&v) = VT_I4;
|
||||
V_I4(&v) = delete_cnt;
|
||||
|
||||
hres = jsdisp_propput_name(ret_array, lengthW, lcid, &v, ei, caller);
|
||||
}
|
||||
}
|
||||
|
||||
if(add_args < delete_cnt) {
|
||||
for(i = start; SUCCEEDED(hres) && i < length-delete_cnt; i++) {
|
||||
hres = jsdisp_propget_idx(dispex, i+delete_cnt, lcid, &v, ei, caller);
|
||||
if(hres == DISP_E_UNKNOWNNAME)
|
||||
hres = jsdisp_delete_idx(dispex, i+add_args);
|
||||
else if(SUCCEEDED(hres))
|
||||
hres = jsdisp_propput_idx(dispex, i+add_args, lcid, &v, ei, caller);
|
||||
}
|
||||
|
||||
for(i=length; SUCCEEDED(hres) && i != length-delete_cnt+add_args; i--)
|
||||
hres = jsdisp_delete_idx(dispex, i-1);
|
||||
}else if(add_args > delete_cnt) {
|
||||
for(i=length-delete_cnt; SUCCEEDED(hres) && i != start; i--) {
|
||||
hres = jsdisp_propget_idx(dispex, i+delete_cnt-1, lcid, &v, ei, caller);
|
||||
if(hres == DISP_E_UNKNOWNNAME)
|
||||
hres = jsdisp_delete_idx(dispex, i+add_args-1);
|
||||
else if(SUCCEEDED(hres))
|
||||
hres = jsdisp_propput_idx(dispex, i+add_args-1, lcid, &v, ei, caller);
|
||||
}
|
||||
}
|
||||
|
||||
for(i=0; SUCCEEDED(hres) && i < add_args; i++)
|
||||
hres = jsdisp_propput_idx(dispex, start+i, lcid, get_arg(dp,i+2), ei, caller);
|
||||
|
||||
if(SUCCEEDED(hres)) {
|
||||
V_VT(&v) = VT_I4;
|
||||
V_I4(&v) = length-delete_cnt+add_args;
|
||||
hres = jsdisp_propput_name(dispex, lengthW, lcid, &v, ei, caller);
|
||||
}
|
||||
|
||||
if(FAILED(hres)) {
|
||||
if(ret_array)
|
||||
jsdisp_release(ret_array);
|
||||
return hres;
|
||||
}
|
||||
|
||||
if(retv) {
|
||||
V_VT(retv) = VT_DISPATCH;
|
||||
V_DISPATCH(retv) = (IDispatch*)_IDispatchEx_(ret_array);
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/* ECMA-262 3rd Edition 15.4.4.2 */
|
||||
|
@ -778,6 +885,7 @@ static HRESULT Array_toLocaleString(DispatchEx *dispex, LCID lcid, WORD flags, D
|
|||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
/* ECMA-262 3rd Edition 15.4.4.13 */
|
||||
static HRESULT Array_unshift(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
|
||||
VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
|
||||
{
|
||||
|
|
|
@ -668,6 +668,78 @@ arr[12] = 2;
|
|||
ok(arr.slice(5).toString() === "a,,,,,,,2", "arr.slice(5).toString() = " + arr.slice(5).toString());
|
||||
ok(arr.slice(5).length === 8, "arr.slice(5).length = " + arr.slice(5).length);
|
||||
|
||||
arr = [1,2,3,4,5];
|
||||
tmp = arr.splice(2,2);
|
||||
ok(tmp.toString() == "3,4", "arr.splice(2,2) returned " + tmp.toString());
|
||||
ok(arr.toString() == "1,2,5", "arr.splice(2,2) is " + arr.toString());
|
||||
|
||||
arr = [1,2,3,4,5];
|
||||
tmp = arr.splice(2,2,"a");
|
||||
ok(tmp.toString() == "3,4", "arr.splice(2,2,'a') returned " + tmp.toString());
|
||||
ok(arr.toString() == "1,2,a,5", "arr.splice(2,2,'a') is " + arr.toString());
|
||||
|
||||
arr = [1,2,3,4,5];
|
||||
tmp = arr.splice(2,2,'a','b','c');
|
||||
ok(tmp.toString() == "3,4", "arr.splice(2,2,'a','b','c') returned " + tmp.toString());
|
||||
ok(arr.toString() == "1,2,a,b,c,5", "arr.splice(2,2,'a','b','c') is " + arr.toString());
|
||||
|
||||
arr = [1,2,3,4,];
|
||||
tmp = arr.splice(2,2,'a','b','c');
|
||||
ok(tmp.toString() == "3,4", "arr.splice(2,2,'a','b','c') returned " + tmp.toString());
|
||||
ok(arr.toString() == "1,2,a,b,c,", "arr.splice(2,2,'a','b','c') is " + arr.toString());
|
||||
|
||||
arr = [1,2,3,4,];
|
||||
arr.splice(2,2,'a','b','c');
|
||||
ok(arr.toString() == "1,2,a,b,c,", "arr.splice(2,2,'a','b','c') is " + arr.toString());
|
||||
|
||||
arr = [1,2,3,4,5];
|
||||
tmp = arr.splice(2,2,'a','b');
|
||||
ok(tmp.toString() == "3,4", "arr.splice(2,2,'a','b') returned " + tmp.toString());
|
||||
ok(arr.toString() == "1,2,a,b,5", "arr.splice(2,2,'a','b') is " + arr.toString());
|
||||
|
||||
arr = [1,2,3,4,5];
|
||||
tmp = arr.splice(-1,2);
|
||||
ok(tmp.toString() == "5", "arr.splice(-1,2) returned " + tmp.toString());
|
||||
ok(arr.toString() == "1,2,3,4", "arr.splice(-1,2) is " + arr.toString());
|
||||
|
||||
arr = [1,2,3,4,5];
|
||||
tmp = arr.splice(-10,3);
|
||||
ok(tmp.toString() == "1,2,3", "arr.splice(-10,3) returned " + tmp.toString());
|
||||
ok(arr.toString() == "4,5", "arr.splice(-10,3) is " + arr.toString());
|
||||
|
||||
arr = [1,2,3,4,5];
|
||||
tmp = arr.splice(-10,100);
|
||||
ok(tmp.toString() == "1,2,3,4,5", "arr.splice(-10,100) returned " + tmp.toString());
|
||||
ok(arr.toString() == "", "arr.splice(-10,100) is " + arr.toString());
|
||||
|
||||
arr = [1,2,3,4,5];
|
||||
tmp = arr.splice(2,-1);
|
||||
ok(tmp.toString() == "", "arr.splice(2,-1) returned " + tmp.toString());
|
||||
ok(arr.toString() == "1,2,3,4,5", "arr.splice(2,-1) is " + arr.toString());
|
||||
|
||||
arr = [1,2,3,4,5];
|
||||
tmp = arr.splice(2);
|
||||
ok(tmp.toString() == "", "arr.splice(2,-1) returned " + tmp.toString());
|
||||
ok(arr.toString() == "1,2,3,4,5", "arr.splice(2,-1) is " + arr.toString());
|
||||
|
||||
arr = [1,2,3,4,5];
|
||||
tmp = arr.splice();
|
||||
ok(tmp.toString() == "", "arr.splice(2,-1) returned " + tmp.toString());
|
||||
ok(arr.toString() == "1,2,3,4,5", "arr.splice(2,-1) is " + arr.toString());
|
||||
|
||||
obj = new Object();
|
||||
obj.length = 3;
|
||||
obj[0] = 1;
|
||||
obj[1] = 2;
|
||||
obj[2] = 3;
|
||||
tmp = Array.prototype.splice.call(obj, 1, 1, 'a', 'b');
|
||||
ok(tmp.toString() === "2", "obj.splice returned " + tmp);
|
||||
ok(obj.length === 4, "obj.length = " + obj.length);
|
||||
ok(obj[0] === 1, "obj[0] = " + obj[0]);
|
||||
ok(obj[1] === 'a', "obj[1] = " + obj[1]);
|
||||
ok(obj[2] === 'b', "obj[2] = " + obj[2]);
|
||||
ok(obj[3] === 3, "obj[3] = " + obj[3]);
|
||||
|
||||
obj = new Object();
|
||||
obj.length = 3;
|
||||
obj[0] = 1;
|
||||
|
|
Loading…
Reference in New Issue