File indexing completed on 2024-05-12 15:43:31
0001 /* 0002 * This file is part of the KDE libraries 0003 * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) 0004 * 0005 * This library is free software; you can redistribute it and/or 0006 * modify it under the terms of the GNU Library General Public 0007 * License as published by the Free Software Foundation; either 0008 * version 2 of the License, or (at your option) any later version. 0009 * 0010 * This library is distributed in the hope that it will be useful, 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0013 * Library General Public License for more details. 0014 * 0015 * You should have received a copy of the GNU Library General Public License 0016 * along with this library; see the file COPYING.LIB. If not, write to 0017 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0018 * Boston, MA 02110-1301, USA. 0019 * 0020 */ 0021 0022 #ifndef _KJS_OPERATIONS_H_ 0023 #define _KJS_OPERATIONS_H_ 0024 0025 #include "global.h" 0026 #include <math.h> 0027 #include <cmath> 0028 #include <stdio.h> 0029 #include <wtf/MathExtras.h> 0030 0031 #if HAVE(IEEEFP_H) 0032 # if HAVE(FUNC_ISINF) || HAVE(FUNC_FINITE) 0033 # include <ieeefp.h> 0034 # endif 0035 #endif 0036 0037 #if HAVE(FLOAT_H) 0038 # include <float.h> 0039 #endif 0040 0041 namespace KJS 0042 { 0043 0044 class ExecState; 0045 class JSValue; 0046 0047 enum Operator { OpEqual, 0048 OpEqEq, 0049 OpPlus, 0050 OpMinus, 0051 OpMult, 0052 OpDiv, 0053 OpMod, 0054 OpExp, 0055 OpNotEq, 0056 OpStrEq, 0057 OpStrNEq, 0058 OpPlusEq, 0059 OpMinusEq, 0060 OpMultEq, 0061 OpDivEq, 0062 OpExpEq, 0063 OpPlusPlus, 0064 OpMinusMinus, 0065 OpLess, 0066 OpLessEq, 0067 OpGreater, 0068 OpGreaterEq, 0069 OpAndEq, 0070 OpXOrEq, 0071 OpOrEq, 0072 OpModEq, 0073 OpAnd, 0074 OpOr, 0075 OpBitAnd, 0076 OpBitXOr, 0077 OpBitOr, 0078 OpLShift, 0079 OpRShift, 0080 OpURShift, 0081 OpIn, 0082 OpInstanceOf 0083 }; 0084 0085 inline bool isNaN(double d); 0086 inline bool isFinite(double d); 0087 inline bool isInf(double d); 0088 inline double signBit(double d); 0089 inline bool isPosInf(double d); 0090 inline bool isNegInf(double d); 0091 0092 inline int clz32(unsigned int d) 0093 { 0094 #if HAVE(FUNC_BUILTIN_CLZ) 0095 //NOTE: __builtin_clz(0); is undefined 0096 //buschinski: and returns 1 for me, for whatever reason 0097 if (d == 0) 0098 return 32; 0099 return __builtin_clz(d); 0100 #else 0101 int count = 0; 0102 while (d != 0) 0103 { 0104 ++count; 0105 d >>= 1; 0106 } 0107 return 32 - count; 0108 #endif 0109 } 0110 0111 inline bool isNaN(double d) 0112 { 0113 #if HAVE(FUNC_STD_ISNAN) 0114 return std::isnan(d); 0115 #elif HAVE(FUNC_ISNAN) 0116 return isnan(d) != 0; 0117 #elif HAVE(FLOAT_H) 0118 return _isnan(d) != 0; 0119 #else 0120 return !(d == d); 0121 #endif 0122 } 0123 0124 inline bool isFinite(double d) 0125 { 0126 #if HAVE(FUNC_STD_ISFINITE) 0127 return std::isfinite(d) != 0; 0128 #elif HAVE(FUNC_FINITE) 0129 return finite(d) != 0; 0130 #elif HAVE(FUNC__FINITE) 0131 return _finite(d) != 0; 0132 #else 0133 return !isNaN(d) && !isInf(d); 0134 #endif 0135 } 0136 0137 inline bool isInf(double d) 0138 { 0139 #if HAVE(FUNC_STD_ISINF) 0140 return std::isinf(d); 0141 #elif HAVE(FUNC_ISINF) 0142 return isinf(d); 0143 #elif HAVE(FUNC_FINITE) 0144 return finite(d) == 0 && d == d; 0145 #elif HAVE(FUNC__FINITE) 0146 return _finite(d) == 0 && d == d; 0147 #elif HAVE(FUNC__FPCLASS) 0148 int fpClass = _fpclass(d); 0149 return _FPCLASS_PINF == fpClass || _FPCLASS_NINF == fpClass; 0150 #else 0151 # error "Your platform does not provide a Infinity checking function." 0152 return false; 0153 #endif 0154 } 0155 0156 inline double signBit(double d) 0157 { 0158 #if HAVE(FUNC_STD_SIGNBIT) 0159 return std::signbit(d); 0160 #elif HAVE(FUNC_SIGNBIT) 0161 return signbit(d); 0162 #elif HAVE(FUNC___SIGNBIT) 0163 return __signbit(d); 0164 #elif HAVE(FUNC__COPYSIGN) 0165 return _copysign(1.0, d) < 0 ? 1.0 : 0.0; 0166 #elif HAVE(FUNC_COPYSIGN) 0167 return copysign(1.0, d) < 0 ? 1.0 : 0.0; 0168 #else 0169 # error "Your platform does not provide a signbit/copysign function." 0170 return false; 0171 #endif 0172 } 0173 0174 inline bool isPosInf(double d) 0175 { 0176 #if HAVE(FPCLASS) 0177 return _FPCLASS_PINF == _fpclass(d); 0178 #else 0179 return isInf(d) && !signBit(d); 0180 #endif 0181 } 0182 0183 inline bool isNegInf(double d) 0184 { 0185 #if HAVE(FUNC_FPCLASS) 0186 return _FPCLASS_PINF == _fpclass(d); 0187 #else 0188 return isInf(d) && signBit(d); 0189 #endif 0190 } 0191 0192 bool equal(ExecState *exec, JSValue *v1, JSValue *v2); 0193 bool strictEqual(ExecState *exec, JSValue *v1, JSValue *v2); 0194 // Same as strictEqual, except for "-0" and "0" difference. 0195 // Used in PropertyDescriptor::equalTo and Object::defineOwnProperty to check 0196 // if the value changed and we need to update. 0197 bool sameValue(ExecState *exec, JSValue *v1, JSValue *v2); 0198 /** 0199 * This operator performs an abstract relational comparison of the two 0200 * arguments that can be of arbitrary type. If possible, conversions to the 0201 * string or number type will take place before the comparison. 0202 * 0203 * @return 1 if v1 is "less-than" v2, 0 if the relation is "greater-than-or- 0204 * equal". -1 if the result is undefined. 0205 */ 0206 int relation(ExecState *exec, JSValue *v1, JSValue *v2, bool leftFirst = true); 0207 int relation(ExecState *exec, JSValue *v1, double n2); 0208 int maxInt(int d1, int d2); 0209 int minInt(int d1, int d2); 0210 0211 // differs from standard C libraries pow() functions in a couple of 0212 // aspects 0213 double exponentiation(double base, double exponent); 0214 0215 } 0216 0217 #endif