Skip to content

Commit

Permalink
Add Math.cbrt() built-in function
Browse files Browse the repository at this point in the history
  • Loading branch information
fatcerberus committed Nov 21, 2016
1 parent 59ce1b2 commit 3474ccf
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 16 deletions.
11 changes: 11 additions & 0 deletions config/header-snippets/platform_fillins.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,17 @@
#define DUK_SQRT sqrt
#endif

/* The functions below exist only in C99/C++11 or later and need a workaround
* for platforms that don't include them. MSVC isn't detected as C99, but
* these functions also exist in MSVC 2013 and later so include a clause for
* that too.
*/
#if defined(DUK_F_C99) || defined(DUK_F_CPP11) || (defined(_MSC_VER) && (_MSC_VER >= 1800))
#if !defined(DUK_CBRT)
#define DUK_CBRT cbrt
#endif /* DUK_CBRT */
#endif /* DUK_F_C99 */

/* NetBSD 6.0 x86 (at least) has a few problems with pow() semantics,
* see test-bug-netbsd-math-pow.js. Use NetBSD specific workaround.
* (This might be a wider problem; if so, generalize the define name.)
Expand Down
1 change: 1 addition & 0 deletions config/other-defines/platform_functions.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
- define: DUK_EXP
- define: DUK_LOG
- define: DUK_SQRT
- define: DUK_CBRT

# Memory allocation
- define: DUK_ANSI_MALLOC
Expand Down
8 changes: 8 additions & 0 deletions src-input/builtins.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2277,6 +2277,14 @@ objects:
magic:
type: math_twoarg
funcname: "atan2" # BI_MATH_ATAN2_IDX
- key: "cbrt"
value:
type: function
native: duk_bi_math_object_onearg_shared
length: 1
magic:
type: math_onearg
funcname: "cbrt" # BI_MATH_CBRT_IDX
- key: "ceil"
value:
type: function
Expand Down
56 changes: 41 additions & 15 deletions src-input/duk_bi_math.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,30 @@ DUK_LOCAL double duk__fmax_fixed(double x, double y) {
return duk_double_fmax(x, y);
}

DUK_LOCAL double duk__cbrt_fixed(double x) {
/* cbrt() is C99. To avoid hassling embedders with the need to provide a
* cube root function, we can get by with pow(). The result is not
* identical, but that's OK: ES6 says it's implementation-dependent.
*/

duk_small_int_t c = (duk_small_int_t) DUK_FPCLASSIFY(x);

#if defined(DUK_CBRT)
/* cbrt() matches ES6 requirements. */
return DUK_CBRT(x);
#else
/* pow() does not, however. */
if (c == DUK_FP_NAN || c == DUK_FP_INFINITE || c == DUK_FP_ZERO) {
return x;
}
if (DUK_SIGNBIT(x)) {
return -DUK_POW(-x, 1.0 / 3.0);
} else {
return DUK_POW(x, 1.0 / 3.0);
}
#endif
}

DUK_LOCAL double duk__round_fixed(double x) {
/* Numbers half-way between integers must be rounded towards +Infinity,
* e.g. -3.5 must be rounded to -3 (not -4). When rounded to zero, zero
Expand Down Expand Up @@ -192,7 +216,8 @@ DUK_LOCAL const duk__one_arg_func duk__one_arg_funcs[] = {
duk__round_fixed,
duk__sin,
duk__sqrt,
duk__tan
duk__tan,
duk__cbrt_fixed,
#else
DUK_FABS,
DUK_ACOS,
Expand All @@ -207,6 +232,7 @@ DUK_LOCAL const duk__one_arg_func duk__one_arg_funcs[] = {
DUK_SIN,
DUK_SQRT,
DUK_TAN
duk__cbrt_fixed,
#endif
};

Expand Down Expand Up @@ -249,6 +275,19 @@ DUK_INTERNAL duk_ret_t duk_bi_math_object_twoarg_shared(duk_context *ctx) {
return 1;
}

DUK_INTERNAL duk_ret_t duk_bi_math_object_max(duk_context *ctx) {
return duk__math_minmax(ctx, -DUK_DOUBLE_INFINITY, duk__fmax_fixed);
}

DUK_INTERNAL duk_ret_t duk_bi_math_object_min(duk_context *ctx) {
return duk__math_minmax(ctx, DUK_DOUBLE_INFINITY, duk__fmin_fixed);
}

DUK_INTERNAL duk_ret_t duk_bi_math_object_random(duk_context *ctx) {
duk_push_number(ctx, (duk_double_t) DUK_UTIL_GET_RANDOM_DOUBLE((duk_hthread *) ctx));
return 1;
}

#if defined(DUK_USE_ES6)
DUK_INTERNAL duk_ret_t duk_bi_math_object_hypot(duk_context *ctx) {
/*
Expand Down Expand Up @@ -315,19 +354,6 @@ DUK_INTERNAL duk_ret_t duk_bi_math_object_hypot(duk_context *ctx) {
duk_push_number(ctx, (duk_double_t) DUK_SQRT(sum) * max);
return 1;
}
#endif

DUK_INTERNAL duk_ret_t duk_bi_math_object_max(duk_context *ctx) {
return duk__math_minmax(ctx, -DUK_DOUBLE_INFINITY, duk__fmax_fixed);
}

DUK_INTERNAL duk_ret_t duk_bi_math_object_min(duk_context *ctx) {
return duk__math_minmax(ctx, DUK_DOUBLE_INFINITY, duk__fmin_fixed);
}

DUK_INTERNAL duk_ret_t duk_bi_math_object_random(duk_context *ctx) {
duk_push_number(ctx, (duk_double_t) DUK_UTIL_GET_RANDOM_DOUBLE((duk_hthread *) ctx));
return 1;
}
#endif /* DUK_USE_ES6 */

#endif /* DUK_USE_MATH_BUILTIN */
3 changes: 2 additions & 1 deletion tools/genbuiltins.py
Original file line number Diff line number Diff line change
Expand Up @@ -1201,7 +1201,8 @@ def load_metadata(opts, rom=False, build_info=None, active_opts=None):
'round': 9, # BI_MATH_ROUND_IDX
'sin': 10, # BI_MATH_SIN_IDX
'sqrt': 11, # BI_MATH_SQRT_IDX
'tan': 12 # BI_MATH_TAN_IDX
'tan': 12, # BI_MATH_TAN_IDX
'cbrt': 13 # BI_MATH_CBRT_IDX
}
math_twoarg_magic = {
'atan2': 0, # BI_MATH_ATAN2_IDX
Expand Down
1 change: 1 addition & 0 deletions util/check_code_policy.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ def __init__(self, filename, linenumber, line, reason):
'exp',
'log',
'sqrt',
'cbrt',

# memory functions
'malloc',
Expand Down

0 comments on commit 3474ccf

Please sign in to comment.