MathObject.cpp revision 635860845790a19bf50bbc51ba8fb66a96dde068
1/* 2 * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) 3 * Copyright (C) 2007, 2008 Apple Inc. All Rights Reserved. 4 * 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 of the License, or (at your option) any later version. 9 * 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. 14 * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA 18 * 19 */ 20 21#include "config.h" 22#include "MathObject.h" 23 24#include "ObjectPrototype.h" 25#include "Operations.h" 26#include <time.h> 27#include <wtf/Assertions.h> 28#include <wtf/MathExtras.h> 29#include <wtf/RandomNumber.h> 30#include <wtf/RandomNumberSeed.h> 31 32namespace JSC { 33 34ASSERT_CLASS_FITS_IN_CELL(MathObject); 35 36static JSValuePtr mathProtoFuncAbs(ExecState*, JSObject*, JSValuePtr, const ArgList&); 37static JSValuePtr mathProtoFuncACos(ExecState*, JSObject*, JSValuePtr, const ArgList&); 38static JSValuePtr mathProtoFuncASin(ExecState*, JSObject*, JSValuePtr, const ArgList&); 39static JSValuePtr mathProtoFuncATan(ExecState*, JSObject*, JSValuePtr, const ArgList&); 40static JSValuePtr mathProtoFuncATan2(ExecState*, JSObject*, JSValuePtr, const ArgList&); 41static JSValuePtr mathProtoFuncCeil(ExecState*, JSObject*, JSValuePtr, const ArgList&); 42static JSValuePtr mathProtoFuncCos(ExecState*, JSObject*, JSValuePtr, const ArgList&); 43static JSValuePtr mathProtoFuncExp(ExecState*, JSObject*, JSValuePtr, const ArgList&); 44static JSValuePtr mathProtoFuncFloor(ExecState*, JSObject*, JSValuePtr, const ArgList&); 45static JSValuePtr mathProtoFuncLog(ExecState*, JSObject*, JSValuePtr, const ArgList&); 46static JSValuePtr mathProtoFuncMax(ExecState*, JSObject*, JSValuePtr, const ArgList&); 47static JSValuePtr mathProtoFuncMin(ExecState*, JSObject*, JSValuePtr, const ArgList&); 48static JSValuePtr mathProtoFuncPow(ExecState*, JSObject*, JSValuePtr, const ArgList&); 49static JSValuePtr mathProtoFuncRandom(ExecState*, JSObject*, JSValuePtr, const ArgList&); 50static JSValuePtr mathProtoFuncRound(ExecState*, JSObject*, JSValuePtr, const ArgList&); 51static JSValuePtr mathProtoFuncSin(ExecState*, JSObject*, JSValuePtr, const ArgList&); 52static JSValuePtr mathProtoFuncSqrt(ExecState*, JSObject*, JSValuePtr, const ArgList&); 53static JSValuePtr mathProtoFuncTan(ExecState*, JSObject*, JSValuePtr, const ArgList&); 54 55} 56 57#include "MathObject.lut.h" 58 59namespace JSC { 60 61// ------------------------------ MathObject -------------------------------- 62 63const ClassInfo MathObject::info = { "Math", 0, 0, ExecState::mathTable }; 64 65/* Source for MathObject.lut.h 66@begin mathTable 67 abs mathProtoFuncAbs DontEnum|Function 1 68 acos mathProtoFuncACos DontEnum|Function 1 69 asin mathProtoFuncASin DontEnum|Function 1 70 atan mathProtoFuncATan DontEnum|Function 1 71 atan2 mathProtoFuncATan2 DontEnum|Function 2 72 ceil mathProtoFuncCeil DontEnum|Function 1 73 cos mathProtoFuncCos DontEnum|Function 1 74 exp mathProtoFuncExp DontEnum|Function 1 75 floor mathProtoFuncFloor DontEnum|Function 1 76 log mathProtoFuncLog DontEnum|Function 1 77 max mathProtoFuncMax DontEnum|Function 2 78 min mathProtoFuncMin DontEnum|Function 2 79 pow mathProtoFuncPow DontEnum|Function 2 80 random mathProtoFuncRandom DontEnum|Function 0 81 round mathProtoFuncRound DontEnum|Function 1 82 sin mathProtoFuncSin DontEnum|Function 1 83 sqrt mathProtoFuncSqrt DontEnum|Function 1 84 tan mathProtoFuncTan DontEnum|Function 1 85@end 86*/ 87 88MathObject::MathObject(ExecState* exec, PassRefPtr<Structure> structure) 89 : JSObject(structure) 90{ 91 putDirectWithoutTransition(Identifier(exec, "E"), jsNumber(exec, exp(1.0)), DontDelete | DontEnum | ReadOnly); 92 putDirectWithoutTransition(Identifier(exec, "LN2"), jsNumber(exec, log(2.0)), DontDelete | DontEnum | ReadOnly); 93 putDirectWithoutTransition(Identifier(exec, "LN10"), jsNumber(exec, log(10.0)), DontDelete | DontEnum | ReadOnly); 94 putDirectWithoutTransition(Identifier(exec, "LOG2E"), jsNumber(exec, 1.0 / log(2.0)), DontDelete | DontEnum | ReadOnly); 95 putDirectWithoutTransition(Identifier(exec, "LOG10E"), jsNumber(exec, 1.0 / log(10.0)), DontDelete | DontEnum | ReadOnly); 96 putDirectWithoutTransition(Identifier(exec, "PI"), jsNumber(exec, piDouble), DontDelete | DontEnum | ReadOnly); 97 putDirectWithoutTransition(Identifier(exec, "SQRT1_2"), jsNumber(exec, sqrt(0.5)), DontDelete | DontEnum | ReadOnly); 98 putDirectWithoutTransition(Identifier(exec, "SQRT2"), jsNumber(exec, sqrt(2.0)), DontDelete | DontEnum | ReadOnly); 99 WTF::initializeWeakRandomNumberGenerator(); 100} 101 102// ECMA 15.8 103 104bool MathObject::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot &slot) 105{ 106 const HashEntry* entry = ExecState::mathTable(exec)->entry(exec, propertyName); 107 108 if (!entry) 109 return JSObject::getOwnPropertySlot(exec, propertyName, slot); 110 111 ASSERT(entry->attributes() & Function); 112 setUpStaticFunctionSlot(exec, entry, this, propertyName, slot); 113 return true; 114} 115 116// ------------------------------ Functions -------------------------------- 117 118JSValuePtr mathProtoFuncAbs(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args) 119{ 120 return jsNumber(exec, fabs(args.at(exec, 0).toNumber(exec))); 121} 122 123JSValuePtr mathProtoFuncACos(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args) 124{ 125 return jsNumber(exec, acos(args.at(exec, 0).toNumber(exec))); 126} 127 128JSValuePtr mathProtoFuncASin(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args) 129{ 130 return jsNumber(exec, asin(args.at(exec, 0).toNumber(exec))); 131} 132 133JSValuePtr mathProtoFuncATan(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args) 134{ 135 return jsNumber(exec, atan(args.at(exec, 0).toNumber(exec))); 136} 137 138JSValuePtr mathProtoFuncATan2(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args) 139{ 140 return jsNumber(exec, atan2(args.at(exec, 0).toNumber(exec), args.at(exec, 1).toNumber(exec))); 141} 142 143JSValuePtr mathProtoFuncCeil(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args) 144{ 145 return jsNumber(exec, ceil(args.at(exec, 0).toNumber(exec))); 146} 147 148JSValuePtr mathProtoFuncCos(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args) 149{ 150 return jsNumber(exec, cos(args.at(exec, 0).toNumber(exec))); 151} 152 153JSValuePtr mathProtoFuncExp(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args) 154{ 155 return jsNumber(exec, exp(args.at(exec, 0).toNumber(exec))); 156} 157 158JSValuePtr mathProtoFuncFloor(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args) 159{ 160 return jsNumber(exec, floor(args.at(exec, 0).toNumber(exec))); 161} 162 163JSValuePtr mathProtoFuncLog(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args) 164{ 165 return jsNumber(exec, log(args.at(exec, 0).toNumber(exec))); 166} 167 168JSValuePtr mathProtoFuncMax(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args) 169{ 170 unsigned argsCount = args.size(); 171 double result = -Inf; 172 for (unsigned k = 0; k < argsCount; ++k) { 173 double val = args.at(exec, k).toNumber(exec); 174 if (isnan(val)) { 175 result = NaN; 176 break; 177 } 178 if (val > result || (val == 0 && result == 0 && !signbit(val))) 179 result = val; 180 } 181 return jsNumber(exec, result); 182} 183 184JSValuePtr mathProtoFuncMin(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args) 185{ 186 unsigned argsCount = args.size(); 187 double result = +Inf; 188 for (unsigned k = 0; k < argsCount; ++k) { 189 double val = args.at(exec, k).toNumber(exec); 190 if (isnan(val)) { 191 result = NaN; 192 break; 193 } 194 if (val < result || (val == 0 && result == 0 && signbit(val))) 195 result = val; 196 } 197 return jsNumber(exec, result); 198} 199 200JSValuePtr mathProtoFuncPow(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args) 201{ 202 // ECMA 15.8.2.1.13 203 204 double arg = args.at(exec, 0).toNumber(exec); 205 double arg2 = args.at(exec, 1).toNumber(exec); 206 207 if (isnan(arg2)) 208 return jsNaN(exec); 209 if (isinf(arg2) && fabs(arg) == 1) 210 return jsNaN(exec); 211 return jsNumber(exec, pow(arg, arg2)); 212} 213 214JSValuePtr mathProtoFuncRandom(ExecState* exec, JSObject*, JSValuePtr, const ArgList&) 215{ 216 return jsNumber(exec, WTF::weakRandomNumber()); 217} 218 219JSValuePtr mathProtoFuncRound(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args) 220{ 221 double arg = args.at(exec, 0).toNumber(exec); 222 if (signbit(arg) && arg >= -0.5) 223 return jsNumber(exec, -0.0); 224 return jsNumber(exec, floor(arg + 0.5)); 225} 226 227JSValuePtr mathProtoFuncSin(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args) 228{ 229 return jsNumber(exec, sin(args.at(exec, 0).toNumber(exec))); 230} 231 232JSValuePtr mathProtoFuncSqrt(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args) 233{ 234 return jsNumber(exec, sqrt(args.at(exec, 0).toNumber(exec))); 235} 236 237JSValuePtr mathProtoFuncTan(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args) 238{ 239 return jsNumber(exec, tan(args.at(exec, 0).toNumber(exec))); 240} 241 242} // namespace JSC 243