static HRESULT Math_acos(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei) { double x; HRESULT hres; TRACE("\n"); if(!arg_cnt(dp)) { if(retv) num_set_nan(retv); return S_OK; } hres = to_number(ctx, get_arg(dp, 0), ei, &x); if(FAILED(hres)) return hres; if(retv) { if(x < -1.0 || x > 1.0) num_set_nan(retv); else num_set_val(retv, acos(x)); } return S_OK; }
/* ECMA-262 3rd Edition 15.8.2.13 */ static HRESULT Math_pow(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei) { double x, y; HRESULT hres; TRACE("\n"); if(arg_cnt(dp) < 2) { if(retv) num_set_nan(retv); return S_OK; } hres = to_number(ctx, get_arg(dp, 0), ei, &x); if(FAILED(hres)) return hres; hres = to_number(ctx, get_arg(dp, 1), ei, &y); if(FAILED(hres)) return hres; if(retv) num_set_val(retv, pow(x, y)); return S_OK; }
static HRESULT JSGlobal_NaN(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) { TRACE("\n"); switch(flags) { case DISPATCH_PROPERTYGET: num_set_nan(retv); break; default: FIXME("unimplemented flags %x\n", flags); return E_NOTIMPL; } return S_OK; }
/* ECMA-262 3rd Edition 15.8.2.15 */ static HRESULT Math_round(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei) { double x; HRESULT hres; TRACE("\n"); if(!arg_cnt(dp)) { num_set_nan(retv); return S_OK; } hres = to_number(ctx, get_arg(dp, 0), ei, &x); if(FAILED(hres)) return hres; if(retv) num_set_val(retv, floor(x+0.5)); return S_OK; }
/* ECMA-262 3rd Edition 9.3 */ HRESULT to_number(script_ctx_t *ctx, VARIANT *v, jsexcept_t *ei, VARIANT *ret) { switch(V_VT(v)) { case VT_EMPTY: num_set_nan(ret); break; case VT_NULL: V_VT(ret) = VT_I4; V_I4(ret) = 0; break; case VT_I4: case VT_R8: *ret = *v; break; case VT_BSTR: return str_to_number(V_BSTR(v), ret); case VT_DISPATCH: { VARIANT prim; HRESULT hres; hres = to_primitive(ctx, v, ei, &prim); if(FAILED(hres)) return hres; hres = to_number(ctx, &prim, ei, ret); VariantClear(&prim); return hres; } case VT_BOOL: V_VT(ret) = VT_I4; V_I4(ret) = V_BOOL(v) ? 1 : 0; break; default: FIXME("unimplemented for vt %d\n", V_VT(v)); return E_NOTIMPL; } return S_OK; }
/* ECMA-262 3rd Edition 9.3.1 */ static HRESULT str_to_number(BSTR str, VARIANT *ret) { const WCHAR *ptr = str; BOOL neg = FALSE; DOUBLE d = 0.0; static const WCHAR infinityW[] = {'I','n','f','i','n','i','t','y'}; while(isspaceW(*ptr)) ptr++; if(*ptr == '-') { neg = TRUE; ptr++; }else if(*ptr == '+') { ptr++; } if(!strncmpW(ptr, infinityW, sizeof(infinityW)/sizeof(WCHAR))) { ptr += sizeof(infinityW)/sizeof(WCHAR); while(*ptr && isspaceW(*ptr)) ptr++; if(*ptr) num_set_nan(ret); else num_set_inf(ret, !neg); return S_OK; } if(*ptr == '0' && ptr[1] == 'x') { DWORD l = 0; ptr += 2; while((l = hex_to_int(*ptr)) != -1) { d = d*16 + l; ptr++; } num_set_val(ret, d); return S_OK; } while(isdigitW(*ptr)) d = d*10 + (*ptr++ - '0'); if(*ptr == 'e' || *ptr == 'E') { BOOL eneg = FALSE; LONG l = 0; ptr++; if(*ptr == '-') { ptr++; eneg = TRUE; }else if(*ptr == '+') { ptr++; } while(isdigitW(*ptr)) l = l*10 + (*ptr++ - '0'); if(eneg) l = -l; d *= pow(10, l); }else if(*ptr == '.') { DOUBLE dec = 0.1; ptr++; while(isdigitW(*ptr)) { d += dec * (*ptr++ - '0'); dec *= 0.1; } } while(isspaceW(*ptr)) ptr++; if(*ptr) { num_set_nan(ret); return S_OK; } if(neg) d = -d; num_set_val(ret, d); return S_OK; }