]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/jaegertracing/opentelemetry-cpp/third_party/prometheus-cpp/3rdparty/civetweb/src/third_party/duktape-1.8.0/src-separate/duk_bi_math.c
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / jaegertracing / opentelemetry-cpp / third_party / prometheus-cpp / 3rdparty / civetweb / src / third_party / duktape-1.8.0 / src-separate / duk_bi_math.c
diff --git a/ceph/src/jaegertracing/opentelemetry-cpp/third_party/prometheus-cpp/3rdparty/civetweb/src/third_party/duktape-1.8.0/src-separate/duk_bi_math.c b/ceph/src/jaegertracing/opentelemetry-cpp/third_party/prometheus-cpp/3rdparty/civetweb/src/third_party/duktape-1.8.0/src-separate/duk_bi_math.c
new file mode 100644 (file)
index 0000000..62c9341
--- /dev/null
@@ -0,0 +1,348 @@
+/*
+ *  Math built-ins
+ */
+
+#include "duk_internal.h"
+
+#if defined(DUK_USE_MATH_BUILTIN)
+
+/*
+ *  Use static helpers which can work with math.h functions matching
+ *  the following signatures. This is not portable if any of these math
+ *  functions is actually a macro.
+ *
+ *  Typing here is intentionally 'double' wherever values interact with
+ *  the standard library APIs.
+ */
+
+typedef double (*duk__one_arg_func)(double);
+typedef double (*duk__two_arg_func)(double, double);
+
+DUK_LOCAL duk_ret_t duk__math_minmax(duk_context *ctx, duk_double_t initial, duk__two_arg_func min_max) {
+       duk_idx_t n = duk_get_top(ctx);
+       duk_idx_t i;
+       duk_double_t res = initial;
+       duk_double_t t;
+
+       /*
+        *  Note: fmax() does not match the E5 semantics.  E5 requires
+        *  that if -any- input to Math.max() is a NaN, the result is a
+        *  NaN.  fmax() will return a NaN only if -both- inputs are NaN.
+        *  Same applies to fmin().
+        *
+        *  Note: every input value must be coerced with ToNumber(), even
+        *  if we know the result will be a NaN anyway: ToNumber() may have
+        *  side effects for which even order of evaluation matters.
+        */
+
+       for (i = 0; i < n; i++) {
+               t = duk_to_number(ctx, i);
+               if (DUK_FPCLASSIFY(t) == DUK_FP_NAN || DUK_FPCLASSIFY(res) == DUK_FP_NAN) {
+                       /* Note: not normalized, but duk_push_number() will normalize */
+                       res = (duk_double_t) DUK_DOUBLE_NAN;
+               } else {
+                       res = (duk_double_t) min_max(res, (double) t);
+               }
+       }
+
+       duk_push_number(ctx, res);
+       return 1;
+}
+
+DUK_LOCAL double duk__fmin_fixed(double x, double y) {
+       /* fmin() with args -0 and +0 is not guaranteed to return
+        * -0 as Ecmascript requires.
+        */
+       if (x == 0 && y == 0) {
+               /* XXX: what's the safest way of creating a negative zero? */
+               if (DUK_SIGNBIT(x) != 0 || DUK_SIGNBIT(y) != 0) {
+                       return -0.0;
+               } else {
+                       return +0.0;
+               }
+       }
+#ifdef DUK_USE_MATH_FMIN
+       return DUK_FMIN(x, y);
+#else
+       return (x < y ? x : y);
+#endif
+}
+
+DUK_LOCAL double duk__fmax_fixed(double x, double y) {
+       /* fmax() with args -0 and +0 is not guaranteed to return
+        * +0 as Ecmascript requires.
+        */
+       if (x == 0 && y == 0) {
+               if (DUK_SIGNBIT(x) == 0 || DUK_SIGNBIT(y) == 0) {
+                       return +0.0;
+               } else {
+                       return -0.0;
+               }
+       }
+#ifdef DUK_USE_MATH_FMAX
+       return DUK_FMAX(x, y);
+#else
+       return (x > y ? x : y);
+#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
+        * sign must be set appropriately.  E5.1 Section 15.8.2.15.
+        *
+        * Note that ANSI C round() is "round to nearest integer, away from zero",
+        * which is incorrect for negative values.  Here we make do with floor().
+        */
+
+       duk_small_int_t c = (duk_small_int_t) DUK_FPCLASSIFY(x);
+       if (c == DUK_FP_NAN || c == DUK_FP_INFINITE || c == DUK_FP_ZERO) {
+               return x;
+       }
+
+       /*
+        *  x is finite and non-zero
+        *
+        *  -1.6 -> floor(-1.1) -> -2
+        *  -1.5 -> floor(-1.0) -> -1  (towards +Inf)
+        *  -1.4 -> floor(-0.9) -> -1
+        *  -0.5 -> -0.0               (special case)
+        *  -0.1 -> -0.0               (special case)
+        *  +0.1 -> +0.0               (special case)
+        *  +0.5 -> floor(+1.0) -> 1   (towards +Inf)
+        *  +1.4 -> floor(+1.9) -> 1
+        *  +1.5 -> floor(+2.0) -> 2   (towards +Inf)
+        *  +1.6 -> floor(+2.1) -> 2
+        */
+
+       if (x >= -0.5 && x < 0.5) {
+               /* +0.5 is handled by floor, this is on purpose */
+               if (x < 0.0) {
+                       return -0.0;
+               } else {
+                       return +0.0;
+               }
+       }
+
+       return DUK_FLOOR(x + 0.5);
+}
+
+DUK_LOCAL double duk__pow_fixed(double x, double y) {
+       /* The ANSI C pow() semantics differ from Ecmascript.
+        *
+        * E.g. when x==1 and y is +/- infinite, the Ecmascript required
+        * result is NaN, while at least Linux pow() returns 1.
+        */
+
+       duk_small_int_t cx, cy, sx;
+
+       DUK_UNREF(cx);
+       DUK_UNREF(sx);
+       cy = (duk_small_int_t) DUK_FPCLASSIFY(y);
+
+       if (cy == DUK_FP_NAN) {
+               goto ret_nan;
+       }
+       if (DUK_FABS(x) == 1.0 && cy == DUK_FP_INFINITE) {
+               goto ret_nan;
+       }
+#if defined(DUK_USE_POW_NETBSD_WORKAROUND)
+       /* See test-bug-netbsd-math-pow.js: NetBSD 6.0 on x86 (at least) does not
+        * correctly handle some cases where x=+/-0.  Specific fixes to these
+        * here.
+        */
+       cx = (duk_small_int_t) DUK_FPCLASSIFY(x);
+       if (cx == DUK_FP_ZERO && y < 0.0) {
+               sx = (duk_small_int_t) DUK_SIGNBIT(x);
+               if (sx == 0) {
+                       /* Math.pow(+0,y) should be Infinity when y<0.  NetBSD pow()
+                        * returns -Infinity instead when y is <0 and finite.  The
+                        * if-clause also catches y == -Infinity (which works even
+                        * without the fix).
+                        */
+                       return DUK_DOUBLE_INFINITY;
+               } else {
+                       /* Math.pow(-0,y) where y<0 should be:
+                        *   - -Infinity if y<0 and an odd integer
+                        *   - Infinity otherwise
+                        * NetBSD pow() returns -Infinity for all finite y<0.  The
+                        * if-clause also catches y == -Infinity (which works even
+                        * without the fix).
+                        */
+
+                       /* fmod() return value has same sign as input (negative) so
+                        * the result here will be in the range ]-2,0], 1 indicates
+                        * odd.  If x is -Infinity, NaN is returned and the odd check
+                        * always concludes "not odd" which results in desired outcome.
+                        */
+                       double tmp = DUK_FMOD(y, 2);
+                       if (tmp == -1.0) {
+                               return -DUK_DOUBLE_INFINITY;
+                       } else {
+                               /* Not odd, or y == -Infinity */
+                               return DUK_DOUBLE_INFINITY;
+                       }
+               }
+       }
+#endif
+       return DUK_POW(x, y);
+
+ ret_nan:
+       return DUK_DOUBLE_NAN;
+}
+
+/* Wrappers for calling standard math library methods.  These may be required
+ * on platforms where one or more of the math built-ins are defined as macros
+ * or inline functions and are thus not suitable to be used as function pointers.
+ */
+#if defined(DUK_USE_AVOID_PLATFORM_FUNCPTRS)
+DUK_LOCAL double duk__fabs(double x) {
+       return DUK_FABS(x);
+}
+DUK_LOCAL double duk__acos(double x) {
+       return DUK_ACOS(x);
+}
+DUK_LOCAL double duk__asin(double x) {
+       return DUK_ASIN(x);
+}
+DUK_LOCAL double duk__atan(double x) {
+       return DUK_ATAN(x);
+}
+DUK_LOCAL double duk__ceil(double x) {
+       return DUK_CEIL(x);
+}
+DUK_LOCAL double duk__cos(double x) {
+       return DUK_COS(x);
+}
+DUK_LOCAL double duk__exp(double x) {
+       return DUK_EXP(x);
+}
+DUK_LOCAL double duk__floor(double x) {
+       return DUK_FLOOR(x);
+}
+DUK_LOCAL double duk__log(double x) {
+       return DUK_LOG(x);
+}
+DUK_LOCAL double duk__sin(double x) {
+       return DUK_SIN(x);
+}
+DUK_LOCAL double duk__sqrt(double x) {
+       return DUK_SQRT(x);
+}
+DUK_LOCAL double duk__tan(double x) {
+       return DUK_TAN(x);
+}
+DUK_LOCAL double duk__atan2(double x, double y) {
+       return DUK_ATAN2(x, y);
+}
+#endif  /* DUK_USE_AVOID_PLATFORM_FUNCPTRS */
+
+/* order must match constants in genbuiltins.py */
+DUK_LOCAL const duk__one_arg_func duk__one_arg_funcs[] = {
+#if defined(DUK_USE_AVOID_PLATFORM_FUNCPTRS)
+       duk__fabs,
+       duk__acos,
+       duk__asin,
+       duk__atan,
+       duk__ceil,
+       duk__cos,
+       duk__exp,
+       duk__floor,
+       duk__log,
+       duk__round_fixed,
+       duk__sin,
+       duk__sqrt,
+       duk__tan
+#else
+       DUK_FABS,
+       DUK_ACOS,
+       DUK_ASIN,
+       DUK_ATAN,
+       DUK_CEIL,
+       DUK_COS,
+       DUK_EXP,
+       DUK_FLOOR,
+       DUK_LOG,
+       duk__round_fixed,
+       DUK_SIN,
+       DUK_SQRT,
+       DUK_TAN
+#endif
+};
+
+/* order must match constants in genbuiltins.py */
+DUK_LOCAL const duk__two_arg_func duk__two_arg_funcs[] = {
+#if defined(DUK_USE_AVOID_PLATFORM_FUNCPTRS)
+       duk__atan2,
+       duk__pow_fixed
+#else
+       DUK_ATAN2,
+       duk__pow_fixed
+#endif
+};
+
+DUK_INTERNAL duk_ret_t duk_bi_math_object_onearg_shared(duk_context *ctx) {
+       duk_small_int_t fun_idx = duk_get_current_magic(ctx);
+       duk__one_arg_func fun;
+
+       DUK_ASSERT(fun_idx >= 0);
+       DUK_ASSERT(fun_idx < (duk_small_int_t) (sizeof(duk__one_arg_funcs) / sizeof(duk__one_arg_func)));
+       fun = duk__one_arg_funcs[fun_idx];
+       duk_push_number(ctx, (duk_double_t) fun((double) duk_to_number(ctx, 0)));
+       return 1;
+}
+
+DUK_INTERNAL duk_ret_t duk_bi_math_object_twoarg_shared(duk_context *ctx) {
+       duk_small_int_t fun_idx = duk_get_current_magic(ctx);
+       duk__two_arg_func fun;
+
+       DUK_ASSERT(fun_idx >= 0);
+       DUK_ASSERT(fun_idx < (duk_small_int_t) (sizeof(duk__two_arg_funcs) / sizeof(duk__two_arg_func)));
+       fun = duk__two_arg_funcs[fun_idx];
+       duk_push_number(ctx, (duk_double_t) fun((double) duk_to_number(ctx, 0), (double) duk_to_number(ctx, 1)));
+       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_tinyrandom_get_double((duk_hthread *) ctx));
+       return 1;
+}
+
+#else  /* DUK_USE_MATH_BUILTIN */
+
+/* A stubbed built-in is useful for e.g. compilation torture testing with BCC. */
+
+DUK_INTERNAL duk_ret_t duk_bi_math_object_onearg_shared(duk_context *ctx) {
+       DUK_UNREF(ctx);
+       return DUK_RET_UNIMPLEMENTED_ERROR;
+}
+
+DUK_INTERNAL duk_ret_t duk_bi_math_object_twoarg_shared(duk_context *ctx) {
+       DUK_UNREF(ctx);
+       return DUK_RET_UNIMPLEMENTED_ERROR;
+}
+
+DUK_INTERNAL duk_ret_t duk_bi_math_object_max(duk_context *ctx) {
+       DUK_UNREF(ctx);
+       return DUK_RET_UNIMPLEMENTED_ERROR;
+}
+
+DUK_INTERNAL duk_ret_t duk_bi_math_object_min(duk_context *ctx) {
+       DUK_UNREF(ctx);
+       return DUK_RET_UNIMPLEMENTED_ERROR;
+}
+
+DUK_INTERNAL duk_ret_t duk_bi_math_object_random(duk_context *ctx) {
+       DUK_UNREF(ctx);
+       return DUK_RET_UNIMPLEMENTED_ERROR;
+}
+
+#endif  /* DUK_USE_MATH_BUILTIN */