/* ECMA-262 3rd Edition 15.5.4.15 */ static HRESULT String_substring(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) { INT start=0, end, length; jsstr_t *str; double d; HRESULT hres; TRACE("\n"); hres = get_string_val(ctx, jsthis, &str); if(FAILED(hres)) return hres; length = jsstr_length(str); if(argc >= 1) { hres = to_integer(ctx, argv[0], &d); if(FAILED(hres)) { jsstr_release(str); return hres; } if(d >= 0) start = is_int32(d) ? min(length, d) : length; } if(argc >= 2) { hres = to_integer(ctx, argv[1], &d); if(FAILED(hres)) { jsstr_release(str); return hres; } if(d >= 0) end = is_int32(d) ? min(length, d) : length; else end = 0; } else { end = length; } if(start > end) { INT tmp = start; start = end; end = tmp; } if(r) { jsstr_t *ret = jsstr_substr(str, start, end-start); if(ret) *r = jsval_string(ret); else hres = E_OUTOFMEMORY; } jsstr_release(str); return hres; }
/* ECMA-262 3rd Edition B.2.3 */ static HRESULT String_substr(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) { int start=0, len, length; jsstr_t *str; double d; HRESULT hres; TRACE("\n"); hres = get_string_val(ctx, jsthis, &str); if(FAILED(hres)) return hres; length = jsstr_length(str); if(argc >= 1) { hres = to_integer(ctx, argv[0], &d); if(FAILED(hres)) { jsstr_release(str); return hres; } if(d >= 0) start = is_int32(d) ? min(length, d) : length; } if(argc >= 2) { hres = to_integer(ctx, argv[1], &d); if(FAILED(hres)) { jsstr_release(str); return hres; } if(d >= 0.0) len = is_int32(d) ? min(length-start, d) : length-start; else len = 0; } else { len = length-start; } hres = S_OK; if(r) { jsstr_t *ret = jsstr_substr(str, start, len); if(ret) *r = jsval_string(ret); else hres = E_OUTOFMEMORY; } jsstr_release(str); return hres; }
int lua_is_array(lua_State *lua) { int top = lua_gettop(lua); long keycount = 0; int maxkey = 0; lua_pushnil(lua); while(lua_next(lua,-2)) { ++keycount; lua_Number number; lua_pop(lua,1); // pop the value int type = lua_type(lua, -1); if( (type != LUA_TNUMBER) || 0 >= (number = lua_tonumber(lua, -1)) || !is_int32(number) ) { lua_settop(lua, top); return 0; } maxkey = (number > maxkey ? number : maxkey); } lua_settop(lua, top); return maxkey == keycount; }
HRESULT double_to_string(double n, jsstr_t **str) { const WCHAR InfinityW[] = {'-','I','n','f','i','n','i','t','y',0}; if(isnan(n)) { *str = jsstr_nan(); }else if(isinf(n)) { *str = jsstr_alloc(n<0 ? InfinityW : InfinityW+1); }else if(is_int32(n)) { *str = int_to_string(n); }else { VARIANT strv, v; HRESULT hres; /* FIXME: Don't use VariantChangeTypeEx */ V_VT(&v) = VT_R8; V_R8(&v) = n; V_VT(&strv) = VT_EMPTY; hres = VariantChangeTypeEx(&strv, &v, MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT), 0, VT_BSTR); if(FAILED(hres)) return hres; *str = jsstr_alloc(V_BSTR(&strv)); SysFreeString(V_BSTR(&strv)); } return *str ? S_OK : E_OUTOFMEMORY; }
void ConfUnit::set_int32(int32_t i) { if (is_int32()) { _union.i = i; } else { throw std::exception(); } }
int32_t ConfUnit::to_int32() const { if (is_int32()) { return _union.i; } else { throw std::exception(); } }
static HRESULT String_indexOf(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) { jsstr_t *search_jsstr, *jsstr; const WCHAR *search_str, *str; int length, pos = 0; INT ret = -1; HRESULT hres; TRACE("\n"); hres = get_string_flat_val(ctx, jsthis, &jsstr, &str); if(FAILED(hres)) return hres; length = jsstr_length(jsstr); if(!argc) { if(r) *r = jsval_number(-1); jsstr_release(jsstr); return S_OK; } hres = to_flat_string(ctx, argv[0], &search_jsstr, &search_str); if(FAILED(hres)) { jsstr_release(jsstr); return hres; } if(argc >= 2) { double d; hres = to_integer(ctx, argv[1], &d); if(SUCCEEDED(hres) && d > 0.0) pos = is_int32(d) ? min(length, d) : length; } if(SUCCEEDED(hres)) { const WCHAR *ptr; ptr = strstrW(str+pos, search_str); if(ptr) ret = ptr - str; else ret = -1; } jsstr_release(search_jsstr); jsstr_release(jsstr); if(FAILED(hres)) return hres; if(r) *r = jsval_number(ret); return S_OK; }
HRESULT jsval_to_variant(jsval_t val, VARIANT *retv) { switch(jsval_type(val)) { case JSV_UNDEFINED: V_VT(retv) = VT_EMPTY; return S_OK; case JSV_NULL: V_VT(retv) = VT_NULL; return S_OK; case JSV_OBJECT: V_VT(retv) = VT_DISPATCH; if(get_object(val)) IDispatch_AddRef(get_object(val)); V_DISPATCH(retv) = get_object(val); return S_OK; case JSV_STRING: { jsstr_t *str = get_string(val); V_VT(retv) = VT_BSTR; if(str->length_flags & JSSTR_FLAG_NULLBSTR) { V_BSTR(retv) = NULL; } else { V_BSTR(retv) = SysAllocStringLen(NULL, jsstr_length(str)); if(V_BSTR(retv)) jsstr_flush(str, V_BSTR(retv)); else return E_OUTOFMEMORY; } return S_OK; } case JSV_NUMBER: { double n = get_number(val); if(is_int32(n)) { V_VT(retv) = VT_I4; V_I4(retv) = n; } else { V_VT(retv) = VT_R8; V_R8(retv) = n; } return S_OK; } case JSV_BOOL: V_VT(retv) = VT_BOOL; V_BOOL(retv) = get_bool(val) ? VARIANT_TRUE : VARIANT_FALSE; return S_OK; case JSV_VARIANT: V_VT(retv) = VT_EMPTY; return VariantCopy(retv, get_variant(val)); } assert(0); return E_FAIL; }
static HRESULT ArrayConstr_value(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) { jsdisp_t *obj; DWORD i; HRESULT hres; TRACE("\n"); switch(flags) { case DISPATCH_METHOD: case DISPATCH_CONSTRUCT: { if(argc == 1 && is_number(argv[0])) { double n = get_number(argv[0]); if(n < 0 || !is_int32(n)) return throw_range_error(ctx, JS_E_INVALID_LENGTH, NULL); hres = create_array(ctx, n, &obj); if(FAILED(hres)) return hres; *r = jsval_obj(obj); return S_OK; } hres = create_array(ctx, argc, &obj); if(FAILED(hres)) return hres; for(i=0; i < argc; i++) { hres = jsdisp_propput_idx(obj, i, argv[i]); if(FAILED(hres)) break; } if(FAILED(hres)) { jsdisp_release(obj); return hres; } *r = jsval_obj(obj); break; } default: FIXME("unimplemented flags: %x\n", flags); return E_NOTIMPL; } return S_OK; }
double ConfUnit::to_double() const { if (is_int32()) { return (double)_union.i; } else if (is_int64()) { return (double)_union.l; } else if (is_double()) { return _union.d; } else { throw std::exception(); } }
static INT index_from_val(script_ctx_t *ctx, jsval_t v) { double n; HRESULT hres; hres = to_number(ctx, v, &n); if(FAILED(hres)) { clear_ei(ctx); /* FIXME: Move ignoring exceptions to to_primitive */ return 0; } n = floor(n); return is_int32(n) ? n : 0; }
/* ECMA-262 3rd Edition 15.5.4.5 */ static HRESULT String_charCodeAt(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) { jsstr_t *str; DWORD idx = 0; HRESULT hres; TRACE("\n"); hres = get_string_val(ctx, jsthis, &str); if(FAILED(hres)) return hres; if(argc > 0) { double d; hres = to_integer(ctx, argv[0], &d); if(FAILED(hres)) { jsstr_release(str); return hres; } if(!is_int32(d) || d < 0 || d >= jsstr_length(str)) { jsstr_release(str); if(r) *r = jsval_number(NAN); return S_OK; } idx = d; } if(r) { WCHAR c; jsstr_extract(str, idx, 1, &c); *r = jsval_number(c); } jsstr_release(str); return S_OK; }
/* ECMA-262 3rd Edition 15.5.4.5 */ static HRESULT String_charAt(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) { jsstr_t *str, *ret; INT pos = 0; HRESULT hres; TRACE("\n"); hres = get_string_val(ctx, jsthis, &str); if(FAILED(hres)) return hres; if(argc) { double d; hres = to_integer(ctx, argv[0], &d); if(FAILED(hres)) { jsstr_release(str); return hres; } pos = is_int32(d) ? d : -1; } if(!r) { jsstr_release(str); return S_OK; } if(0 <= pos && pos < jsstr_length(str)) { ret = jsstr_substr(str, pos, 1); if(!ret) return E_OUTOFMEMORY; } else { ret = jsstr_empty(); } *r = jsval_string(ret); return S_OK; }
/* ECMA-262 3rd Edition 15.5.4.8 */ static HRESULT String_lastIndexOf(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) { unsigned pos = 0, search_len, length; jsstr_t *search_jsstr, *jsstr; const WCHAR *search_str, *str; INT ret = -1; HRESULT hres; TRACE("\n"); hres = get_string_flat_val(ctx, jsthis, &jsstr, &str); if(FAILED(hres)) return hres; if(!argc) { if(r) *r = jsval_number(-1); jsstr_release(jsstr); return S_OK; } hres = to_flat_string(ctx, argv[0], &search_jsstr, &search_str); if(FAILED(hres)) { jsstr_release(jsstr); return hres; } search_len = jsstr_length(search_jsstr); length = jsstr_length(jsstr); if(argc >= 2) { double d; hres = to_integer(ctx, argv[1], &d); if(SUCCEEDED(hres) && d > 0) pos = is_int32(d) ? min(length, d) : length; } else { pos = length; } if(SUCCEEDED(hres) && length >= search_len) { const WCHAR *ptr; for(ptr = str+min(pos, length-search_len); ptr >= str; ptr--) { if(!memcmp(ptr, search_str, search_len*sizeof(WCHAR))) { ret = ptr-str; break; } } } jsstr_release(search_jsstr); jsstr_release(jsstr); if(FAILED(hres)) return hres; if(r) *r = jsval_number(ret); 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; }
/* 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.5.4.13 */ static HRESULT String_slice(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) { int start=0, end, length; jsstr_t *str; double d; HRESULT hres; TRACE("\n"); hres = get_string_val(ctx, jsthis, &str); if(FAILED(hres)) return hres; length = jsstr_length(str); if(argc) { hres = to_integer(ctx, argv[0], &d); if(FAILED(hres)) { jsstr_release(str); return hres; } if(is_int32(d)) { start = d; if(start < 0) { start = length + start; if(start < 0) start = 0; } else if(start > length) { start = length; } } else if(d > 0) { start = length; } } if(argc >= 2) { hres = to_integer(ctx, argv[1], &d); if(FAILED(hres)) { jsstr_release(str); return hres; } if(is_int32(d)) { end = d; if(end < 0) { end = length + end; if(end < 0) end = 0; } else if(end > length) { end = length; } } else { end = d < 0.0 ? 0 : length; } } else { end = length; } if(end < start) end = start; if(r) { jsstr_t *retstr = jsstr_substr(str, start, end-start); if(!retstr) { jsstr_release(str); return E_OUTOFMEMORY; } *r = jsval_string(retstr); } jsstr_release(str); return S_OK; }