Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenmath.c
Go to the documentation of this file.
00001 /* 00002 * Copyright 2008 Jacek Caban for CodeWeavers 00003 * Copyright 2009 Piotr Caban 00004 * 00005 * This library is free software; you can redistribute it and/or 00006 * modify it under the terms of the GNU Lesser General Public 00007 * License as published by the Free Software Foundation; either 00008 * version 2.1 of the License, or (at your option) any later version. 00009 * 00010 * This library is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 * Lesser General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU Lesser General Public 00016 * License along with this library; if not, write to the Free Software 00017 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00018 */ 00019 00020 #include "config.h" 00021 #include "wine/port.h" 00022 00023 #include <math.h> 00024 #include <limits.h> 00025 00026 #include "jscript.h" 00027 #include "ntsecapi.h" 00028 00029 #include "wine/debug.h" 00030 00031 WINE_DEFAULT_DEBUG_CHANNEL(jscript); 00032 00033 static const WCHAR EW[] = {'E',0}; 00034 static const WCHAR LOG2EW[] = {'L','O','G','2','E',0}; 00035 static const WCHAR LOG10EW[] = {'L','O','G','1','0','E',0}; 00036 static const WCHAR LN2W[] = {'L','N','2',0}; 00037 static const WCHAR LN10W[] = {'L','N','1','0',0}; 00038 static const WCHAR PIW[] = {'P','I',0}; 00039 static const WCHAR SQRT2W[] = {'S','Q','R','T','2',0}; 00040 static const WCHAR SQRT1_2W[] = {'S','Q','R','T','1','_','2',0}; 00041 static const WCHAR absW[] = {'a','b','s',0}; 00042 static const WCHAR acosW[] = {'a','c','o','s',0}; 00043 static const WCHAR asinW[] = {'a','s','i','n',0}; 00044 static const WCHAR atanW[] = {'a','t','a','n',0}; 00045 static const WCHAR atan2W[] = {'a','t','a','n','2',0}; 00046 static const WCHAR ceilW[] = {'c','e','i','l',0}; 00047 static const WCHAR cosW[] = {'c','o','s',0}; 00048 static const WCHAR expW[] = {'e','x','p',0}; 00049 static const WCHAR floorW[] = {'f','l','o','o','r',0}; 00050 static const WCHAR logW[] = {'l','o','g',0}; 00051 static const WCHAR maxW[] = {'m','a','x',0}; 00052 static const WCHAR minW[] = {'m','i','n',0}; 00053 static const WCHAR powW[] = {'p','o','w',0}; 00054 static const WCHAR randomW[] = {'r','a','n','d','o','m',0}; 00055 static const WCHAR roundW[] = {'r','o','u','n','d',0}; 00056 static const WCHAR sinW[] = {'s','i','n',0}; 00057 static const WCHAR sqrtW[] = {'s','q','r','t',0}; 00058 static const WCHAR tanW[] = {'t','a','n',0}; 00059 00060 static HRESULT math_constant(DOUBLE val, WORD flags, VARIANT *retv) 00061 { 00062 switch(flags) { 00063 case DISPATCH_PROPERTYGET: 00064 V_VT(retv) = VT_R8; 00065 V_R8(retv) = val; 00066 return S_OK; 00067 case DISPATCH_PROPERTYPUT: 00068 return S_OK; 00069 } 00070 00071 FIXME("unhandled flags %x\n", flags); 00072 return E_NOTIMPL; 00073 } 00074 00075 /* ECMA-262 3rd Edition 15.8.1.1 */ 00076 static HRESULT Math_E(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 00077 VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) 00078 { 00079 TRACE("\n"); 00080 return math_constant(M_E, flags, retv); 00081 } 00082 00083 /* ECMA-262 3rd Edition 15.8.1.4 */ 00084 static HRESULT Math_LOG2E(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 00085 VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) 00086 { 00087 TRACE("\n"); 00088 return math_constant(M_LOG2E, flags, retv); 00089 } 00090 00091 /* ECMA-262 3rd Edition 15.8.1.4 */ 00092 static HRESULT Math_LOG10E(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 00093 VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) 00094 { 00095 TRACE("\n"); 00096 return math_constant(M_LOG10E, flags, retv); 00097 } 00098 00099 static HRESULT Math_LN2(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 00100 VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) 00101 { 00102 TRACE("\n"); 00103 return math_constant(M_LN2, flags, retv); 00104 } 00105 00106 static HRESULT Math_LN10(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 00107 VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) 00108 { 00109 TRACE("\n"); 00110 return math_constant(M_LN10, flags, retv); 00111 } 00112 00113 /* ECMA-262 3rd Edition 15.8.1.6 */ 00114 static HRESULT Math_PI(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 00115 VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) 00116 { 00117 TRACE("\n"); 00118 return math_constant(M_PI, flags, retv); 00119 } 00120 00121 static HRESULT Math_SQRT2(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 00122 VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) 00123 { 00124 TRACE("\n"); 00125 return math_constant(M_SQRT2, flags, retv); 00126 } 00127 00128 static HRESULT Math_SQRT1_2(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 00129 VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) 00130 { 00131 TRACE("\n"); 00132 return math_constant(M_SQRT1_2, flags, retv); 00133 } 00134 00135 /* ECMA-262 3rd Edition 15.8.2.12 */ 00136 static HRESULT Math_abs(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 00137 VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) 00138 { 00139 VARIANT v; 00140 DOUBLE d; 00141 HRESULT hres; 00142 00143 TRACE("\n"); 00144 00145 if(!arg_cnt(dp)) { 00146 if(retv) 00147 num_set_nan(retv); 00148 return S_OK; 00149 } 00150 00151 hres = to_number(ctx, get_arg(dp, 0), ei, &v); 00152 if(FAILED(hres)) 00153 return hres; 00154 00155 d = num_val(&v); 00156 if(retv) 00157 num_set_val(retv, d < 0.0 ? -d : d); 00158 return S_OK; 00159 } 00160 00161 static HRESULT Math_acos(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 00162 VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) 00163 { 00164 VARIANT v; 00165 HRESULT hres; 00166 00167 TRACE("\n"); 00168 00169 if(!arg_cnt(dp)) { 00170 if(retv) num_set_nan(retv); 00171 return S_OK; 00172 } 00173 00174 hres = to_number(ctx, get_arg(dp, 0), ei, &v); 00175 if(FAILED(hres)) 00176 return hres; 00177 00178 if(retv) num_set_val(retv, acos(num_val(&v))); 00179 return S_OK; 00180 } 00181 00182 static HRESULT Math_asin(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 00183 VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) 00184 { 00185 VARIANT v; 00186 HRESULT hres; 00187 00188 TRACE("\n"); 00189 00190 if(!arg_cnt(dp)) { 00191 if(retv) num_set_nan(retv); 00192 return S_OK; 00193 } 00194 00195 hres = to_number(ctx, get_arg(dp, 0), ei, &v); 00196 if(FAILED(hres)) 00197 return hres; 00198 00199 if(retv) num_set_val(retv, asin(num_val(&v))); 00200 return S_OK; 00201 } 00202 00203 static HRESULT Math_atan(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 00204 VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) 00205 { 00206 VARIANT v; 00207 HRESULT hres; 00208 00209 TRACE("\n"); 00210 00211 if(!arg_cnt(dp)) { 00212 if(retv) num_set_nan(retv); 00213 return S_OK; 00214 } 00215 00216 hres = to_number(ctx, get_arg(dp, 0), ei, &v); 00217 if(FAILED(hres)) 00218 return hres; 00219 00220 if(retv) num_set_val(retv, atan(num_val(&v))); 00221 return S_OK; 00222 } 00223 00224 static HRESULT Math_atan2(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 00225 VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) 00226 { 00227 VARIANT v1, v2; 00228 HRESULT hres; 00229 00230 TRACE("\n"); 00231 00232 if(arg_cnt(dp)<2) { 00233 if(retv) num_set_nan(retv); 00234 return S_OK; 00235 } 00236 00237 hres = to_number(ctx, get_arg(dp, 0), ei, &v1); 00238 if(FAILED(hres)) 00239 return hres; 00240 00241 hres = to_number(ctx, get_arg(dp, 1), ei, &v2); 00242 if(FAILED(hres)) 00243 return hres; 00244 00245 if(retv) num_set_val(retv, atan2(num_val(&v1), num_val(&v2))); 00246 return S_OK; 00247 } 00248 00249 /* ECMA-262 3rd Edition 15.8.2.6 */ 00250 static HRESULT Math_ceil(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 00251 VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) 00252 { 00253 VARIANT v; 00254 HRESULT hres; 00255 00256 TRACE("\n"); 00257 00258 if(!arg_cnt(dp)) { 00259 if(retv) 00260 num_set_nan(retv); 00261 return S_OK; 00262 } 00263 00264 hres = to_number(ctx, get_arg(dp, 0), ei, &v); 00265 if(FAILED(hres)) 00266 return hres; 00267 00268 if(retv) 00269 num_set_val(retv, ceil(num_val(&v))); 00270 return S_OK; 00271 } 00272 00273 static HRESULT Math_cos(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 00274 VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) 00275 { 00276 VARIANT v; 00277 HRESULT hres; 00278 00279 TRACE("\n"); 00280 00281 if(!arg_cnt(dp)) { 00282 if(retv) num_set_nan(retv); 00283 return S_OK; 00284 } 00285 00286 hres = to_number(ctx, get_arg(dp, 0), ei, &v); 00287 if(FAILED(hres)) 00288 return hres; 00289 00290 if(retv) num_set_val(retv, cos(num_val(&v))); 00291 return S_OK; 00292 } 00293 00294 static HRESULT Math_exp(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 00295 VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) 00296 { 00297 VARIANT v; 00298 HRESULT hres; 00299 00300 TRACE("\n"); 00301 00302 if(!arg_cnt(dp)) { 00303 if(retv) num_set_nan(retv); 00304 return S_OK; 00305 } 00306 00307 hres = to_number(ctx, get_arg(dp, 0), ei, &v); 00308 if(FAILED(hres)) 00309 return hres; 00310 00311 if(retv) num_set_val(retv, exp(num_val(&v))); 00312 return S_OK; 00313 } 00314 00315 static HRESULT Math_floor(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 00316 VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) 00317 { 00318 VARIANT v; 00319 HRESULT hres; 00320 00321 TRACE("\n"); 00322 00323 if(!arg_cnt(dp)) { 00324 if(retv) 00325 num_set_nan(retv); 00326 return S_OK; 00327 } 00328 00329 hres = to_number(ctx, get_arg(dp, 0), ei, &v); 00330 if(FAILED(hres)) 00331 return hres; 00332 00333 if(retv) 00334 num_set_val(retv, floor(num_val(&v))); 00335 return S_OK; 00336 } 00337 00338 static HRESULT Math_log(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 00339 VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) 00340 { 00341 VARIANT v; 00342 HRESULT hres; 00343 00344 TRACE("\n"); 00345 00346 if(!arg_cnt(dp)) { 00347 if(retv) 00348 num_set_nan(retv); 00349 return S_OK; 00350 } 00351 00352 hres = to_number(ctx, get_arg(dp, 0), ei, &v); 00353 if(FAILED(hres)) 00354 return hres; 00355 00356 if(retv) 00357 num_set_val(retv, log(num_val(&v))); 00358 return S_OK; 00359 } 00360 00361 /* ECMA-262 3rd Edition 15.8.2.11 */ 00362 static HRESULT Math_max(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 00363 VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) 00364 { 00365 DOUBLE max, d; 00366 VARIANT v; 00367 DWORD i; 00368 HRESULT hres; 00369 00370 TRACE("\n"); 00371 00372 if(!arg_cnt(dp)) { 00373 if(retv) 00374 num_set_inf(retv, FALSE); 00375 return S_OK; 00376 } 00377 00378 hres = to_number(ctx, get_arg(dp, 0), ei, &v); 00379 if(FAILED(hres)) 00380 return hres; 00381 00382 max = num_val(&v); 00383 for(i=1; i < arg_cnt(dp); i++) { 00384 hres = to_number(ctx, get_arg(dp, i), ei, &v); 00385 if(FAILED(hres)) 00386 return hres; 00387 00388 d = num_val(&v); 00389 if(d > max || isnan(d)) 00390 max = d; 00391 } 00392 00393 if(retv) 00394 num_set_val(retv, max); 00395 return S_OK; 00396 } 00397 00398 /* ECMA-262 3rd Edition 15.8.2.12 */ 00399 static HRESULT Math_min(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 00400 VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) 00401 { 00402 DOUBLE min, d; 00403 VARIANT v; 00404 DWORD i; 00405 HRESULT hres; 00406 00407 TRACE("\n"); 00408 00409 if(!arg_cnt(dp)) { 00410 if(retv) 00411 num_set_inf(retv, TRUE); 00412 return S_OK; 00413 } 00414 00415 hres = to_number(ctx, get_arg(dp, 0), ei, &v); 00416 if(FAILED(hres)) 00417 return hres; 00418 00419 min = num_val(&v); 00420 for(i=1; i < arg_cnt(dp); i++) { 00421 hres = to_number(ctx, get_arg(dp, i), ei, &v); 00422 if(FAILED(hres)) 00423 return hres; 00424 00425 d = num_val(&v); 00426 if(d < min || isnan(d)) 00427 min = d; 00428 } 00429 00430 if(retv) 00431 num_set_val(retv, min); 00432 return S_OK; 00433 } 00434 00435 /* ECMA-262 3rd Edition 15.8.2.13 */ 00436 static HRESULT Math_pow(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 00437 VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) 00438 { 00439 VARIANT x, y; 00440 HRESULT hres; 00441 00442 TRACE("\n"); 00443 00444 if(arg_cnt(dp) < 2) { 00445 if(retv) num_set_nan(retv); 00446 return S_OK; 00447 } 00448 00449 hres = to_number(ctx, get_arg(dp, 0), ei, &x); 00450 if(FAILED(hres)) 00451 return hres; 00452 00453 hres = to_number(ctx, get_arg(dp, 1), ei, &y); 00454 if(FAILED(hres)) 00455 return hres; 00456 00457 if(retv) 00458 num_set_val(retv, pow(num_val(&x), num_val(&y))); 00459 return S_OK; 00460 } 00461 00462 /* ECMA-262 3rd Edition 15.8.2.14 */ 00463 static HRESULT Math_random(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 00464 VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) 00465 { 00466 UINT r; 00467 00468 TRACE("\n"); 00469 00470 if(!RtlGenRandom(&r, sizeof(r))) 00471 return E_UNEXPECTED; 00472 00473 if(retv) 00474 num_set_val(retv, (DOUBLE)r/(DOUBLE)UINT_MAX); 00475 00476 return S_OK; 00477 } 00478 00479 /* ECMA-262 3rd Edition 15.8.2.15 */ 00480 static HRESULT Math_round(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 00481 VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) 00482 { 00483 VARIANT v; 00484 HRESULT hres; 00485 00486 TRACE("\n"); 00487 00488 if(!arg_cnt(dp)) { 00489 num_set_nan(retv); 00490 return S_OK; 00491 } 00492 00493 hres = to_number(ctx, get_arg(dp, 0), ei, &v); 00494 if(FAILED(hres)) 00495 return hres; 00496 00497 if(retv) 00498 num_set_val(retv, floor(num_val(&v)+0.5)); 00499 return S_OK; 00500 } 00501 00502 static HRESULT Math_sin(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 00503 VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) 00504 { 00505 VARIANT v; 00506 HRESULT hres; 00507 00508 TRACE("\n"); 00509 00510 if(!arg_cnt(dp)) { 00511 if(retv) num_set_nan(retv); 00512 return S_OK; 00513 } 00514 00515 hres = to_number(ctx, get_arg(dp, 0), ei, &v); 00516 if(FAILED(hres)) 00517 return hres; 00518 00519 if(retv) num_set_val(retv, sin(num_val(&v))); 00520 return S_OK; 00521 } 00522 00523 static HRESULT Math_sqrt(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 00524 VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) 00525 { 00526 VARIANT v; 00527 HRESULT hres; 00528 00529 TRACE("\n"); 00530 00531 if(!arg_cnt(dp)) { 00532 if(retv) num_set_nan(retv); 00533 return S_OK; 00534 } 00535 00536 hres = to_number(ctx, get_arg(dp, 0), ei, &v); 00537 if(FAILED(hres)) 00538 return hres; 00539 00540 if(retv) num_set_val(retv, sqrt(num_val(&v))); 00541 return S_OK; 00542 } 00543 00544 static HRESULT Math_tan(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 00545 VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) 00546 { 00547 VARIANT v; 00548 HRESULT hres; 00549 00550 TRACE("\n"); 00551 00552 if(!arg_cnt(dp)) { 00553 if(retv) num_set_nan(retv); 00554 return S_OK; 00555 } 00556 00557 hres = to_number(ctx, get_arg(dp, 0), ei, &v); 00558 if(FAILED(hres)) 00559 return hres; 00560 00561 if(retv) num_set_val(retv, tan(num_val(&v))); 00562 return S_OK; 00563 } 00564 00565 static const builtin_prop_t Math_props[] = { 00566 {EW, Math_E, 0}, 00567 {LN10W, Math_LN10, 0}, 00568 {LN2W, Math_LN2, 0}, 00569 {LOG10EW, Math_LOG10E, 0}, 00570 {LOG2EW, Math_LOG2E, 0}, 00571 {PIW, Math_PI, 0}, 00572 {SQRT1_2W, Math_SQRT1_2, 0}, 00573 {SQRT2W, Math_SQRT2, 0}, 00574 {absW, Math_abs, PROPF_METHOD|1}, 00575 {acosW, Math_acos, PROPF_METHOD|1}, 00576 {asinW, Math_asin, PROPF_METHOD|1}, 00577 {atanW, Math_atan, PROPF_METHOD|1}, 00578 {atan2W, Math_atan2, PROPF_METHOD|2}, 00579 {ceilW, Math_ceil, PROPF_METHOD|1}, 00580 {cosW, Math_cos, PROPF_METHOD|1}, 00581 {expW, Math_exp, PROPF_METHOD|1}, 00582 {floorW, Math_floor, PROPF_METHOD|1}, 00583 {logW, Math_log, PROPF_METHOD|1}, 00584 {maxW, Math_max, PROPF_METHOD|2}, 00585 {minW, Math_min, PROPF_METHOD|2}, 00586 {powW, Math_pow, PROPF_METHOD|2}, 00587 {randomW, Math_random, PROPF_METHOD}, 00588 {roundW, Math_round, PROPF_METHOD|1}, 00589 {sinW, Math_sin, PROPF_METHOD|1}, 00590 {sqrtW, Math_sqrt, PROPF_METHOD|1}, 00591 {tanW, Math_tan, PROPF_METHOD|1} 00592 }; 00593 00594 static const builtin_info_t Math_info = { 00595 JSCLASS_MATH, 00596 {NULL, NULL, 0}, 00597 sizeof(Math_props)/sizeof(*Math_props), 00598 Math_props, 00599 NULL, 00600 NULL 00601 }; 00602 00603 HRESULT create_math(script_ctx_t *ctx, DispatchEx **ret) 00604 { 00605 DispatchEx *math; 00606 HRESULT hres; 00607 00608 math = heap_alloc_zero(sizeof(DispatchEx)); 00609 if(!math) 00610 return E_OUTOFMEMORY; 00611 00612 hres = init_dispex_from_constr(math, ctx, &Math_info, ctx->object_constr); 00613 if(FAILED(hres)) { 00614 heap_free(math); 00615 return hres; 00616 } 00617 00618 *ret = math; 00619 return S_OK; 00620 } Generated on Sat May 26 2012 04:20:42 for ReactOS by
1.7.6.1
|