2 * Copyright 2008 Jacek Caban for CodeWeavers
3 * Copyright 2009 Piotr Caban
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
27 #include "wine/debug.h"
29 WINE_DEFAULT_DEBUG_CHANNEL(jscript
);
31 /* ECMA-262 3rd Edition 15.8.2.12 */
32 static HRESULT
Math_abs(script_ctx_t
*ctx
, vdisp_t
*jsthis
, WORD flags
, unsigned argc
, jsval_t
*argv
,
42 *r
= jsval_number(NAN
);
46 hres
= to_number(ctx
, argv
[0], &d
);
51 *r
= jsval_number(d
< 0.0 ? -d
: d
);
55 static HRESULT
Math_acos(script_ctx_t
*ctx
, vdisp_t
*jsthis
, WORD flags
, unsigned argc
, jsval_t
*argv
,
65 *r
= jsval_number(NAN
);
69 hres
= to_number(ctx
, argv
[0], &x
);
74 *r
= jsval_number(x
< -1.0 || x
> 1.0 ? NAN
: acos(x
));
78 static HRESULT
Math_asin(script_ctx_t
*ctx
, vdisp_t
*jsthis
, WORD flags
, unsigned argc
, jsval_t
*argv
,
88 *r
= jsval_number(NAN
);
92 hres
= to_number(ctx
, argv
[0], &x
);
97 *r
= jsval_number(x
< -1.0 || x
> 1.0 ? NAN
: asin(x
));
101 static HRESULT
Math_atan(script_ctx_t
*ctx
, vdisp_t
*jsthis
, WORD flags
, unsigned argc
, jsval_t
*argv
,
111 *r
= jsval_number(NAN
);
115 hres
= to_number(ctx
, argv
[0], &x
);
120 *r
= jsval_number(atan(x
));
124 static HRESULT
Math_atan2(script_ctx_t
*ctx
, vdisp_t
*jsthis
, WORD flags
, unsigned argc
, jsval_t
*argv
,
134 *r
= jsval_number(NAN
);
138 hres
= to_number(ctx
, argv
[0], &y
);
142 hres
= to_number(ctx
, argv
[1], &x
);
147 *r
= jsval_number(atan2(y
, x
));
151 /* ECMA-262 3rd Edition 15.8.2.6 */
152 static HRESULT
Math_ceil(script_ctx_t
*ctx
, vdisp_t
*jsthis
, WORD flags
, unsigned argc
, jsval_t
*argv
,
162 *r
= jsval_number(NAN
);
166 hres
= to_number(ctx
, argv
[0], &x
);
171 *r
= jsval_number(ceil(x
));
175 static HRESULT
Math_cos(script_ctx_t
*ctx
, vdisp_t
*jsthis
, WORD flags
, unsigned argc
, jsval_t
*argv
,
185 *r
= jsval_number(NAN
);
189 hres
= to_number(ctx
, argv
[0], &x
);
194 *r
= jsval_number(cos(x
));
198 static HRESULT
Math_exp(script_ctx_t
*ctx
, vdisp_t
*jsthis
, WORD flags
, unsigned argc
, jsval_t
*argv
,
208 *r
= jsval_number(NAN
);
212 hres
= to_number(ctx
, argv
[0], &x
);
217 *r
= jsval_number(exp(x
));
221 static HRESULT
Math_floor(script_ctx_t
*ctx
, vdisp_t
*jsthis
, WORD flags
, unsigned argc
, jsval_t
*argv
,
231 *r
= jsval_number(NAN
);
235 hres
= to_number(ctx
, argv
[0], &x
);
240 *r
= jsval_number(floor(x
));
244 static HRESULT
Math_log(script_ctx_t
*ctx
, vdisp_t
*jsthis
, WORD flags
, unsigned argc
, jsval_t
*argv
,
254 *r
= jsval_number(NAN
);
258 hres
= to_number(ctx
, argv
[0], &x
);
263 *r
= jsval_number(x
< -0.0 ? NAN
: log(x
));
267 /* ECMA-262 3rd Edition 15.8.2.11 */
268 static HRESULT
Math_max(script_ctx_t
*ctx
, vdisp_t
*jsthis
, WORD flags
, unsigned argc
, jsval_t
*argv
,
279 *r
= jsval_number(-INFINITY
);
283 hres
= to_number(ctx
, argv
[0], &max
);
287 for(i
=1; i
< argc
; i
++) {
288 hres
= to_number(ctx
, argv
[i
], &d
);
292 if(d
> max
|| isnan(d
))
297 *r
= jsval_number(max
);
301 /* ECMA-262 3rd Edition 15.8.2.12 */
302 static HRESULT
Math_min(script_ctx_t
*ctx
, vdisp_t
*jsthis
, WORD flags
, unsigned argc
, jsval_t
*argv
,
313 *r
= jsval_number(INFINITY
);
317 hres
= to_number(ctx
, argv
[0], &min
);
321 for(i
=1; i
< argc
; i
++) {
322 hres
= to_number(ctx
, argv
[i
], &d
);
326 if(d
< min
|| isnan(d
))
331 *r
= jsval_number(min
);
335 /* ECMA-262 3rd Edition 15.8.2.13 */
336 static HRESULT
Math_pow(script_ctx_t
*ctx
, vdisp_t
*jsthis
, WORD flags
, unsigned argc
, jsval_t
*argv
,
346 *r
= jsval_number(NAN
);
350 hres
= to_number(ctx
, argv
[0], &x
);
354 hres
= to_number(ctx
, argv
[1], &y
);
359 *r
= jsval_number(pow(x
, y
));
363 /* ECMA-262 3rd Edition 15.8.2.14 */
364 static HRESULT
Math_random(script_ctx_t
*ctx
, vdisp_t
*jsthis
, WORD flags
, unsigned argc
, jsval_t
*argv
,
371 if(!RtlGenRandom(&x
, sizeof(x
)))
375 *r
= jsval_number((double)x
/(double)UINT_MAX
);
379 /* ECMA-262 3rd Edition 15.8.2.15 */
380 static HRESULT
Math_round(script_ctx_t
*ctx
, vdisp_t
*jsthis
, WORD flags
, unsigned argc
, jsval_t
*argv
,
390 *r
= jsval_number(NAN
);
394 hres
= to_number(ctx
, argv
[0], &x
);
399 *r
= jsval_number(floor(x
+0.5));
403 static HRESULT
Math_sin(script_ctx_t
*ctx
, vdisp_t
*jsthis
, WORD flags
, unsigned argc
, jsval_t
*argv
,
413 *r
= jsval_number(NAN
);
417 hres
= to_number(ctx
, argv
[0], &x
);
422 *r
= jsval_number(sin(x
));
426 static HRESULT
Math_sqrt(script_ctx_t
*ctx
, vdisp_t
*jsthis
, WORD flags
, unsigned argc
, jsval_t
*argv
,
436 *r
= jsval_number(NAN
);
440 hres
= to_number(ctx
, argv
[0], &x
);
445 *r
= jsval_number(sqrt(x
));
449 static HRESULT
Math_tan(script_ctx_t
*ctx
, vdisp_t
*jsthis
, WORD flags
, unsigned argc
, jsval_t
*argv
,
459 *r
= jsval_number(NAN
);
463 hres
= to_number(ctx
, argv
[0], &x
);
468 *r
= jsval_number(tan(x
));
472 static const builtin_prop_t Math_props
[] = {
473 {L
"abs", Math_abs
, PROPF_METHOD
|1},
474 {L
"acos", Math_acos
, PROPF_METHOD
|1},
475 {L
"asin", Math_asin
, PROPF_METHOD
|1},
476 {L
"atan", Math_atan
, PROPF_METHOD
|1},
477 {L
"atan2", Math_atan2
, PROPF_METHOD
|2},
478 {L
"ceil", Math_ceil
, PROPF_METHOD
|1},
479 {L
"cos", Math_cos
, PROPF_METHOD
|1},
480 {L
"exp", Math_exp
, PROPF_METHOD
|1},
481 {L
"floor", Math_floor
, PROPF_METHOD
|1},
482 {L
"log", Math_log
, PROPF_METHOD
|1},
483 {L
"max", Math_max
, PROPF_METHOD
|2},
484 {L
"min", Math_min
, PROPF_METHOD
|2},
485 {L
"pow", Math_pow
, PROPF_METHOD
|2},
486 {L
"random", Math_random
, PROPF_METHOD
},
487 {L
"round", Math_round
, PROPF_METHOD
|1},
488 {L
"sin", Math_sin
, PROPF_METHOD
|1},
489 {L
"sqrt", Math_sqrt
, PROPF_METHOD
|1},
490 {L
"tan", Math_tan
, PROPF_METHOD
|1}
493 static const builtin_info_t Math_info
= {
496 ARRAY_SIZE(Math_props
),
502 HRESULT
create_math(script_ctx_t
*ctx
, jsdisp_t
**ret
)
512 {L
"E", M_E
}, /* ECMA-262 3rd Edition 15.8.1.1 */
513 {L
"LN10", M_LN10
}, /* ECMA-262 3rd Edition 15.8.1.2 */
514 {L
"LN2", M_LN2
}, /* ECMA-262 3rd Edition 15.8.1.3 */
515 {L
"LOG2E", M_LOG2E
}, /* ECMA-262 3rd Edition 15.8.1.4 */
516 {L
"LOG10E", M_LOG10E
}, /* ECMA-262 3rd Edition 15.8.1.5 */
517 {L
"PI", M_PI
}, /* ECMA-262 3rd Edition 15.8.1.6 */
518 {L
"SQRT1_2", M_SQRT1_2
}, /* ECMA-262 3rd Edition 15.8.1.7 */
519 {L
"SQRT2", M_SQRT2
}, /* ECMA-262 3rd Edition 15.8.1.8 */
522 math
= heap_alloc_zero(sizeof(jsdisp_t
));
524 return E_OUTOFMEMORY
;
526 hres
= init_dispex_from_constr(math
, ctx
, &Math_info
, ctx
->object_constr
);
532 for(i
=0; i
< ARRAY_SIZE(constants
); i
++) {
533 hres
= jsdisp_define_data_property(math
, constants
[i
].name
, 0,
534 jsval_number(constants
[i
].val
));
536 jsdisp_release(math
);