/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * vim: set ts=8 sts=4 et sw=4 tw=99: * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef jsmath_h #define jsmath_h #include "jsapi.h" namespace js { typedef double (*UnaryFunType)(double); class MathCache { static const unsigned SizeLog2 = 12; static const unsigned Size = 1 << SizeLog2; struct Entry { double in; UnaryFunType f; double out; }; Entry table[Size]; public: MathCache(); unsigned hash(double x) { union { double d; struct { uint32_t one, two; } s; } u = { x }; uint32_t hash32 = u.s.one ^ u.s.two; uint16_t hash16 = uint16_t(hash32 ^ (hash32 >> 16)); return (hash16 & (Size - 1)) ^ (hash16 >> (16 - SizeLog2)); } /* * N.B. lookup uses double-equality. This is only safe if hash() maps +0 * and -0 to different table entries, which is asserted in MathCache(). */ double lookup(UnaryFunType f, double x) { unsigned index = hash(x); Entry &e = table[index]; if (e.in == x && e.f == f) return e.out; e.in = x; e.f = f; return (e.out = f(x)); } size_t sizeOfIncludingThis(JSMallocSizeOfFun mallocSizeOf); }; } /* namespace js */ /* * JS math functions. */ extern JSObject * js_InitMathClass(JSContext *cx, js::HandleObject obj); extern double math_random_no_outparam(JSContext *cx); extern JSBool js_math_random(JSContext *cx, unsigned argc, js::Value *vp); extern JSBool js_math_abs(JSContext *cx, unsigned argc, js::Value *vp); extern JSBool js_math_ceil(JSContext *cx, unsigned argc, js::Value *vp); extern JSBool js_math_floor(JSContext *cx, unsigned argc, js::Value *vp); extern JSBool js_math_max(JSContext *cx, unsigned argc, js::Value *vp); extern JSBool js_math_min(JSContext *cx, unsigned argc, js::Value *vp); extern JSBool js_math_round(JSContext *cx, unsigned argc, js::Value *vp); extern JSBool js_math_sqrt(JSContext *cx, unsigned argc, js::Value *vp); extern JSBool js_math_pow(JSContext *cx, unsigned argc, js::Value *vp); extern double js_math_ceil_impl(double x); extern double js_math_floor_impl(double x); namespace js { extern JSBool math_exp(JSContext *cx, unsigned argc, Value *vp); extern JSBool math_imul(JSContext *cx, unsigned argc, js::Value *vp); extern JSBool math_log(JSContext *cx, unsigned argc, js::Value *vp); extern double math_log_impl(MathCache *cache, double x); extern JSBool math_sin(JSContext *cx, unsigned argc, js::Value *vp); extern double math_sin_impl(MathCache *cache, double x); extern JSBool math_cos(JSContext *cx, unsigned argc, js::Value *vp); extern double math_cos_impl(MathCache *cache, double x); extern JSBool math_exp(JSContext *cx, unsigned argc, js::Value *vp); extern double math_exp_impl(MathCache *cache, double x); extern JSBool math_tan(JSContext *cx, unsigned argc, js::Value *vp); extern double math_tan_impl(MathCache *cache, double x); extern JSBool math_asin(JSContext *cx, unsigned argc, Value *vp); extern JSBool math_acos(JSContext *cx, unsigned argc, Value *vp); extern JSBool math_atan(JSContext *cx, unsigned argc, Value *vp); extern JSBool math_atan2(JSContext *cx, unsigned argc, Value *vp); extern double ecmaAtan2(double x, double y); extern double math_atan_impl(MathCache *cache, double x); extern JSBool math_atan(JSContext *cx, unsigned argc, js::Value *vp); extern double math_asin_impl(MathCache *cache, double x); extern JSBool math_asin(JSContext *cx, unsigned argc, js::Value *vp); extern double math_acos_impl(MathCache *cache, double x); extern JSBool math_acos(JSContext *cx, unsigned argc, js::Value *vp); extern double powi(double x, int y); extern double ecmaPow(double x, double y); extern JSBool math_imul(JSContext *cx, unsigned argc, Value *vp); } /* namespace js */ #endif /* jsmath_h */