1
// -*- c-basic-offset: 2 -*-
3
* This file is part of the KDE libraries
4
* Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
6
* This library is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU Library General Public
8
* License as published by the Free Software Foundation; either
9
* version 2 of the License, or (at your option) any later version.
11
* This library is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
* Library General Public License for more details.
16
* You should have received a copy of the GNU Library General Public License
17
* along with this library; see the file COPYING.LIB. If not, write to
18
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19
* Boston, MA 02110-1301, USA.
24
#include "operations.h"
29
#include <wtf/MathExtras.h>
31
#if HAVE(FUNC_ISINF) && HAVE(IEEEFP_H)
43
// FIXME: Should probably be inlined on non-Darwin platforms too, and controlled exclusively
44
// by HAVE macros rather than PLATFORM.
46
// FIXME: Merge with isnan in MathExtras.h and remove this one entirely.
52
return _isnan(d) != 0;
58
// FIXME: Merge with isinf in MathExtras.h and remove this one entirely.
61
// FIXME: should be HAVE(_FPCLASS)
63
int fpClass = _fpclass(d);
64
return _FPCLASS_PINF == fpClass || _FPCLASS_NINF == fpClass;
65
#elif HAVE(FUNC_ISINF)
67
#elif HAVE(FUNC_FINITE)
68
return finite(d) == 0 && d == d;
69
#elif HAVE(FUNC__FINITE)
70
return _finite(d) == 0 && d == d;
76
bool isPosInf(double d)
78
// FIXME: should be HAVE(_FPCLASS)
80
return _FPCLASS_PINF == _fpclass(d);
81
#elif HAVE(FUNC_ISINF)
82
return (isinf(d) == 1);
83
#elif HAVE(FUNC_FINITE)
84
return !finite(d) && d == d; // ### can we distinguish between + and - ?
85
#elif HAVE(FUNC__FINITE)
86
return !_finite(d) && d == d; // ###
92
bool isNegInf(double d)
94
// FIXME: should be HAVE(_FPCLASS)
96
return _FPCLASS_NINF == _fpclass(d);
97
#elif HAVE(FUNC_ISINF)
98
return (isinf(d) == -1);
99
#elif HAVE(FUNC_FINITE)
100
return finite(d) == 0 && d == d; // ###
101
#elif HAVE(FUNC__FINITE)
102
return _finite(d) == 0 && d == d; // ###
111
bool equal(ExecState *exec, JSValue *v1, JSValue *v2)
113
JSType t1 = v1->type();
114
JSType t2 = v2->type();
117
if (t1 == UndefinedType)
119
if (t2 == UndefinedType)
122
if (t1 == BooleanType)
124
if (t2 == BooleanType)
127
if (t1 == NumberType && t2 == StringType) {
129
} else if (t1 == StringType && t2 == NumberType)
133
if ((t1 == StringType || t1 == NumberType) && t2 >= ObjectType)
134
return equal(exec, v1, v2->toPrimitive(exec));
135
if (t1 == NullType && t2 == ObjectType)
136
return static_cast<JSObject *>(v2)->masqueradeAsUndefined();
137
if (t1 >= ObjectType && (t2 == StringType || t2 == NumberType))
138
return equal(exec, v1->toPrimitive(exec), v2);
139
if (t1 == ObjectType && t2 == NullType)
140
return static_cast<JSObject *>(v1)->masqueradeAsUndefined();
146
if (t1 == UndefinedType || t1 == NullType)
149
if (t1 == NumberType) {
150
double d1 = v1->toNumber(exec);
151
double d2 = v2->toNumber(exec);
155
if (t1 == StringType)
156
return v1->toString(exec) == v2->toString(exec);
158
if (t1 == BooleanType)
159
return v1->toBoolean(exec) == v2->toBoolean(exec);
165
bool strictEqual(ExecState *exec, JSValue *v1, JSValue *v2)
167
JSType t1 = v1->type();
168
JSType t2 = v2->type();
172
if (t1 == UndefinedType || t1 == NullType)
174
if (t1 == NumberType) {
175
double n1 = v1->toNumber(exec);
176
double n2 = v2->toNumber(exec);
180
} else if (t1 == StringType)
181
return v1->toString(exec) == v2->toString(exec);
182
else if (t2 == BooleanType)
183
return v1->toBoolean(exec) == v2->toBoolean(exec);
187
/* TODO: joined objects */
192
int relation(ExecState *exec, JSValue *v1, JSValue *v2)
194
JSValue *p1 = v1->toPrimitive(exec,NumberType);
195
JSValue *p2 = v2->toPrimitive(exec,NumberType);
197
if (p1->isString() && p2->isString())
198
return p1->toString(exec) < p2->toString(exec) ? 1 : 0;
200
double n1 = p1->toNumber(exec);
201
double n2 = p2->toNumber(exec);
206
return -1; // must be NaN, so undefined
209
int maxInt(int d1, int d2)
211
return (d1 > d2) ? d1 : d2;
214
int minInt(int d1, int d2)
216
return (d1 < d2) ? d1 : d2;
220
JSValue *add(ExecState *exec, JSValue *v1, JSValue *v2, char oper)
222
// exception for the Date exception in defaultValue()
223
JSType preferred = oper == '+' ? UnspecifiedType : NumberType;
224
JSValue *p1 = v1->toPrimitive(exec, preferred);
225
JSValue *p2 = v2->toPrimitive(exec, preferred);
227
if ((p1->isString() || p2->isString()) && oper == '+') {
228
UString value = p1->toString(exec) + p2->toString(exec);
229
if (value.isNull()) {
230
JSObject *error = Error::create(exec, GeneralError, "Out of memory");
231
exec->setException(error);
234
return jsString(value);
238
return jsNumber(p1->toNumber(exec) + p2->toNumber(exec));
240
return jsNumber(p1->toNumber(exec) - p2->toNumber(exec));
244
JSValue *mult(ExecState *exec, JSValue *v1, JSValue *v2, char oper)
246
double n1 = v1->toNumber(exec);
247
double n2 = v2->toNumber(exec);
253
else if (oper == '/')
256
result = fmod(n1, n2);
258
return jsNumber(result);