static HRESULT Array_reverse(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei) { jsdisp_t *jsthis; DWORD length, k, l; VARIANT v1, v2; HRESULT hres1, hres2; TRACE("\n"); hres1 = get_length(ctx, vthis, ei, &jsthis, &length); if(FAILED(hres1)) return hres1; for(k=0; k<length/2; k++) { l = length-k-1; hres1 = jsdisp_get_idx(jsthis, k, &v1, ei); if(FAILED(hres1) && hres1!=DISP_E_UNKNOWNNAME) return hres1; hres2 = jsdisp_get_idx(jsthis, l, &v2, ei); if(FAILED(hres2) && hres2!=DISP_E_UNKNOWNNAME) { VariantClear(&v1); return hres2; } if(hres1 == DISP_E_UNKNOWNNAME) hres1 = jsdisp_delete_idx(jsthis, l); else hres1 = jsdisp_propput_idx(jsthis, l, &v1, ei); if(FAILED(hres1)) { VariantClear(&v1); VariantClear(&v2); return hres1; } if(hres2 == DISP_E_UNKNOWNNAME) hres2 = jsdisp_delete_idx(jsthis, k); else hres2 = jsdisp_propput_idx(jsthis, k, &v2, ei); if(FAILED(hres2)) { VariantClear(&v2); return hres2; } } if(retv) { jsdisp_addref(jsthis); var_set_jsdisp(retv, jsthis); } return S_OK; }
/* ECMA-262 3rd Edition 15.4.4.9 */ static HRESULT Array_shift(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) { jsdisp_t *jsthis; DWORD length = 0, i; jsval_t v, ret; HRESULT hres; TRACE("\n"); hres = get_length(ctx, vthis, &jsthis, &length); if(FAILED(hres)) return hres; if(!length) { hres = set_length(jsthis, 0); if(FAILED(hres)) return hres; } if(!length) { if(r) *r = jsval_undefined(); return S_OK; } hres = jsdisp_get_idx(jsthis, 0, &ret); if(hres == DISP_E_UNKNOWNNAME) { ret = jsval_undefined(); hres = S_OK; } for(i=1; SUCCEEDED(hres) && i<length; i++) { hres = jsdisp_get_idx(jsthis, i, &v); if(hres == DISP_E_UNKNOWNNAME) hres = jsdisp_delete_idx(jsthis, i-1); else if(SUCCEEDED(hres)) hres = jsdisp_propput_idx(jsthis, i-1, v); } if(SUCCEEDED(hres)) { hres = jsdisp_delete_idx(jsthis, length-1); if(SUCCEEDED(hres)) hres = set_length(jsthis, length-1); } if(FAILED(hres)) return hres; if(r) *r = ret; else jsval_release(ret); return hres; }
static HRESULT Array_reverse(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) { jsdisp_t *jsthis; DWORD length, k, l; jsval_t v1, v2; HRESULT hres1, hres2; TRACE("\n"); hres1 = get_length(ctx, vthis, &jsthis, &length); if(FAILED(hres1)) return hres1; for(k=0; k<length/2; k++) { l = length-k-1; hres1 = jsdisp_get_idx(jsthis, k, &v1); if(FAILED(hres1) && hres1!=DISP_E_UNKNOWNNAME) return hres1; hres2 = jsdisp_get_idx(jsthis, l, &v2); if(FAILED(hres2) && hres2!=DISP_E_UNKNOWNNAME) { jsval_release(v1); return hres2; } if(hres1 == DISP_E_UNKNOWNNAME) hres1 = jsdisp_delete_idx(jsthis, l); else hres1 = jsdisp_propput_idx(jsthis, l, v1); if(FAILED(hres1)) { jsval_release(v1); jsval_release(v2); return hres1; } if(hres2 == DISP_E_UNKNOWNNAME) hres2 = jsdisp_delete_idx(jsthis, k); else hres2 = jsdisp_propput_idx(jsthis, k, v2); if(FAILED(hres2)) { jsval_release(v2); return hres2; } } if(r) *r = jsval_obj(jsdisp_addref(jsthis)); return S_OK; }
/* ECMA-262 3rd Edition 15.4.4.9 */ static HRESULT Array_shift(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei) { jsdisp_t *jsthis; DWORD length = 0, i; VARIANT v, ret; HRESULT hres; TRACE("\n"); hres = get_length(ctx, vthis, ei, &jsthis, &length); if(FAILED(hres)) return hres; if(!length) { hres = set_length(jsthis, ei, 0); if(FAILED(hres)) return hres; } if(!length) { if(retv) V_VT(retv) = VT_EMPTY; return S_OK; } hres = jsdisp_get_idx(jsthis, 0, &ret, ei); if(hres == DISP_E_UNKNOWNNAME) { V_VT(&ret) = VT_EMPTY; hres = S_OK; } for(i=1; SUCCEEDED(hres) && i<length; i++) { hres = jsdisp_get_idx(jsthis, i, &v, ei); if(hres == DISP_E_UNKNOWNNAME) hres = jsdisp_delete_idx(jsthis, i-1); else if(SUCCEEDED(hres)) hres = jsdisp_propput_idx(jsthis, i-1, &v, ei); } if(SUCCEEDED(hres)) { hres = jsdisp_delete_idx(jsthis, length-1); if(SUCCEEDED(hres)) hres = set_length(jsthis, ei, length-1); } if(SUCCEEDED(hres) && retv) *retv = ret; else VariantClear(&ret); return hres; }
static HRESULT Array_set_length(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t value) { ArrayInstance *This = array_from_jsdisp(jsthis); DOUBLE len = -1; DWORD i; HRESULT hres; TRACE("%p %d\n", This, This->length); hres = to_number(ctx, value, &len); if(FAILED(hres)) return hres; len = floor(len); if(len!=(DWORD)len) return throw_range_error(ctx, JS_E_INVALID_LENGTH, NULL); for(i=len; i < This->length; i++) { hres = jsdisp_delete_idx(&This->dispex, i); if(FAILED(hres)) return hres; } This->length = len; return S_OK; }
static HRESULT Array_pop(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei) { jsdisp_t *jsthis; VARIANT val; DWORD length; HRESULT hres; TRACE("\n"); hres = get_length(ctx, vthis, ei, &jsthis, &length); if(FAILED(hres)) return hres; if(!length) { hres = set_length(jsthis, ei, 0); if(FAILED(hres)) return hres; if(retv) V_VT(retv) = VT_EMPTY; return S_OK; } length--; hres = jsdisp_get_idx(jsthis, length, &val, ei); if(SUCCEEDED(hres)) { hres = jsdisp_delete_idx(jsthis, length); } else if(hres == DISP_E_UNKNOWNNAME) { V_VT(&val) = VT_EMPTY; hres = S_OK; } else return hres; if(SUCCEEDED(hres)) hres = set_length(jsthis, ei, length); if(FAILED(hres)) { VariantClear(&val); return hres; } if(retv) *retv = val; else VariantClear(&val); return S_OK; }
static HRESULT Array_pop(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) { jsdisp_t *jsthis; jsval_t val; DWORD length; HRESULT hres; TRACE("\n"); hres = get_length(ctx, vthis, &jsthis, &length); if(FAILED(hres)) return hres; if(!length) { hres = set_length(jsthis, 0); if(FAILED(hres)) return hres; if(r) *r = jsval_undefined(); return S_OK; } length--; hres = jsdisp_get_idx(jsthis, length, &val); if(SUCCEEDED(hres)) hres = jsdisp_delete_idx(jsthis, length); else if(hres == DISP_E_UNKNOWNNAME) { val = jsval_undefined(); hres = S_OK; }else return hres; if(SUCCEEDED(hres)) hres = set_length(jsthis, length); if(FAILED(hres)) { jsval_release(val); return hres; } if(r) *r = val; else jsval_release(val); return hres; }
static HRESULT Array_length(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei) { ArrayInstance *This = array_from_vdisp(jsthis); TRACE("%p %d\n", This, This->length); switch(flags) { case DISPATCH_PROPERTYGET: V_VT(retv) = VT_I4; V_I4(retv) = This->length; break; case DISPATCH_PROPERTYPUT: { DOUBLE len = -1; DWORD i; HRESULT hres; hres = to_number(ctx, get_arg(dp, 0), ei, &len); if(FAILED(hres)) return hres; len = floor(len); if(len!=(DWORD)len) return throw_range_error(ctx, ei, JS_E_INVALID_LENGTH, NULL); for(i=len; i<This->length; i++) { hres = jsdisp_delete_idx(&This->dispex, i); if(FAILED(hres)) return hres; } This->length = len; break; } default: FIXME("unimplemented flags %x\n", flags); return E_NOTIMPL; } return S_OK; }
static HRESULT Array_length(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) { ArrayInstance *This = array_from_vdisp(jsthis); TRACE("%p %d\n", This, This->length); switch(flags) { case DISPATCH_PROPERTYGET: *r = jsval_number(This->length); break; case DISPATCH_PROPERTYPUT: { DOUBLE len = -1; DWORD i; HRESULT hres; hres = to_number(ctx, argv[0], &len); if(FAILED(hres)) return hres; len = floor(len); if(len!=(DWORD)len) return throw_range_error(ctx, JS_E_INVALID_LENGTH, NULL); for(i=len; i<This->length; i++) { hres = jsdisp_delete_idx(&This->dispex, i); if(FAILED(hres)) return hres; } This->length = len; break; } default: FIXME("unimplemented flags %x\n", flags); return E_NOTIMPL; } return S_OK; }
/* ECMA-262 3rd Edition 15.4.4.12 */ static HRESULT Array_splice(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei) { DWORD length, start=0, delete_cnt=0, argc, i, add_args = 0; jsdisp_t *ret_array = NULL, *jsthis; VARIANT v; double d; int n; HRESULT hres = S_OK; TRACE("\n"); hres = get_length(ctx, vthis, ei, &jsthis, &length); if(FAILED(hres)) return hres; argc = arg_cnt(dp); if(argc >= 1) { hres = to_integer(ctx, get_arg(dp,0), ei, &d); if(FAILED(hres)) return hres; if(is_int32(d)) { if((n = d) >= 0) start = min(n, length); else start = -n > length ? 0 : length + n; }else { start = d < 0.0 ? 0 : length; } } if(argc >= 2) { hres = to_integer(ctx, get_arg(dp,1), ei, &d); if(FAILED(hres)) return hres; if(is_int32(d)) { if((n = d) > 0) delete_cnt = min(n, length-start); }else if(d > 0.0) { delete_cnt = length-start; } add_args = argc-2; } if(retv) { hres = create_array(ctx, 0, &ret_array); if(FAILED(hres)) return hres; for(i=0; SUCCEEDED(hres) && i < delete_cnt; i++) { hres = jsdisp_get_idx(jsthis, start+i, &v, ei); if(hres == DISP_E_UNKNOWNNAME) hres = S_OK; else if(SUCCEEDED(hres)) hres = jsdisp_propput_idx(ret_array, i, &v, ei); } if(SUCCEEDED(hres)) { V_VT(&v) = VT_I4; V_I4(&v) = delete_cnt; hres = jsdisp_propput_name(ret_array, lengthW, &v, ei); } } if(add_args < delete_cnt) { for(i = start; SUCCEEDED(hres) && i < length-delete_cnt; i++) { hres = jsdisp_get_idx(jsthis, i+delete_cnt, &v, ei); if(hres == DISP_E_UNKNOWNNAME) hres = jsdisp_delete_idx(jsthis, i+add_args); else if(SUCCEEDED(hres)) hres = jsdisp_propput_idx(jsthis, i+add_args, &v, ei); } for(i=length; SUCCEEDED(hres) && i != length-delete_cnt+add_args; i--) hres = jsdisp_delete_idx(jsthis, i-1); }else if(add_args > delete_cnt) { for(i=length-delete_cnt; SUCCEEDED(hres) && i != start; i--) { hres = jsdisp_get_idx(jsthis, i+delete_cnt-1, &v, ei); if(hres == DISP_E_UNKNOWNNAME) hres = jsdisp_delete_idx(jsthis, i+add_args-1); else if(SUCCEEDED(hres)) hres = jsdisp_propput_idx(jsthis, i+add_args-1, &v, ei); } } for(i=0; SUCCEEDED(hres) && i < add_args; i++) hres = jsdisp_propput_idx(jsthis, start+i, get_arg(dp,i+2), ei); if(SUCCEEDED(hres)) { V_VT(&v) = VT_I4; V_I4(&v) = length-delete_cnt+add_args; hres = jsdisp_propput_name(jsthis, lengthW, &v, ei); } if(FAILED(hres)) { if(ret_array) jsdisp_release(ret_array); return hres; } if(retv) var_set_jsdisp(retv, ret_array); return S_OK; }
/* ECMA-262 3rd Edition 15.4.4.12 */ static HRESULT Array_splice(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) { DWORD length, start=0, delete_cnt=0, i, add_args = 0; jsdisp_t *ret_array = NULL, *jsthis; jsval_t val; double d; int n; HRESULT hres = S_OK; TRACE("\n"); hres = get_length(ctx, vthis, &jsthis, &length); if(FAILED(hres)) return hres; if(argc) { hres = to_integer(ctx, argv[0], &d); if(FAILED(hres)) return hres; if(is_int32(d)) { if((n = d) >= 0) start = min(n, length); else start = -n > length ? 0 : length + n; }else { start = d < 0.0 ? 0 : length; } } if(argc >= 2) { hres = to_integer(ctx, argv[1], &d); if(FAILED(hres)) return hres; if(is_int32(d)) { if((n = d) > 0) delete_cnt = min(n, length-start); }else if(d > 0.0) { delete_cnt = length-start; } add_args = argc-2; } if(r) { hres = create_array(ctx, 0, &ret_array); if(FAILED(hres)) return hres; for(i=0; SUCCEEDED(hres) && i < delete_cnt; i++) { hres = jsdisp_get_idx(jsthis, start+i, &val); if(hres == DISP_E_UNKNOWNNAME) { hres = S_OK; }else if(SUCCEEDED(hres)) { hres = jsdisp_propput_idx(ret_array, i, val); jsval_release(val); } } if(SUCCEEDED(hres)) hres = jsdisp_propput_name(ret_array, lengthW, jsval_number(delete_cnt)); } if(add_args < delete_cnt) { for(i = start; SUCCEEDED(hres) && i < length-delete_cnt; i++) { hres = jsdisp_get_idx(jsthis, i+delete_cnt, &val); if(hres == DISP_E_UNKNOWNNAME) { hres = jsdisp_delete_idx(jsthis, i+add_args); }else if(SUCCEEDED(hres)) { hres = jsdisp_propput_idx(jsthis, i+add_args, val); jsval_release(val); } } for(i=length; SUCCEEDED(hres) && i != length-delete_cnt+add_args; i--) hres = jsdisp_delete_idx(jsthis, i-1); }else if(add_args > delete_cnt) { for(i=length-delete_cnt; SUCCEEDED(hres) && i != start; i--) { hres = jsdisp_get_idx(jsthis, i+delete_cnt-1, &val); if(hres == DISP_E_UNKNOWNNAME) { hres = jsdisp_delete_idx(jsthis, i+add_args-1); }else if(SUCCEEDED(hres)) { hres = jsdisp_propput_idx(jsthis, i+add_args-1, val); jsval_release(val); } } } for(i=0; SUCCEEDED(hres) && i < add_args; i++) hres = jsdisp_propput_idx(jsthis, start+i, argv[i+2]); if(SUCCEEDED(hres)) hres = jsdisp_propput_name(jsthis, lengthW, jsval_number(length-delete_cnt+add_args)); if(FAILED(hres)) { if(ret_array) jsdisp_release(ret_array); return hres; } if(r) *r = jsval_obj(ret_array); return S_OK; }