source: webkit/trunk/JavaScriptCore/kjs/operations.cpp@ 12908

Last change on this file since 12908 was 12848, checked in by darin, 19 years ago

Reviewed by me, change by Peter Kummel.

  • kjs/operations.cpp: (KJS::isNegInf): Fix Windows code, which was checking for positive infinity (rolling in fix from KDE side).
  • Property svn:eol-style set to native
File size: 6.0 KB
Line 
1// -*- c-basic-offset: 2 -*-
2/*
3 * This file is part of the KDE libraries
4 * Copyright (C) 1999-2000 Harri Porten ([email protected])
5 *
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.
10 *
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.
15 *
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.
20 *
21 */
22
23
24#include "JSType.h"
25#include "config.h"
26#include "operations.h"
27
28#include <assert.h>
29#include <math.h>
30#include <stdio.h>
31#include <stdlib.h>
32
33#ifndef HAVE_FUNC_ISINF
34#ifdef HAVE_IEEEFP_H
35#include <ieeefp.h>
36#endif
37#endif /* HAVE_FUNC_ISINF */
38
39#if HAVE_FLOAT_H
40#include <float.h>
41#endif
42
43#include "object.h"
44
45namespace KJS {
46
47#if !__APPLE__
48
49bool isNaN(double d)
50{
51#ifdef HAVE_FUNC_ISNAN
52 return isnan(d);
53#elif defined HAVE_FLOAT_H
54 return _isnan(d) != 0;
55#else
56 return !(d == d);
57#endif
58}
59
60bool isInf(double d)
61{
62#if WIN32
63 int fpClass = _fpclass(d);
64 return _FPCLASS_PINF == fpClass || _FPCLASS_NINF == fpClass;
65#elif defined(HAVE_FUNC_ISINF)
66 return isinf(d);
67#elif HAVE_FUNC_FINITE
68 return finite(d) == 0 && d == d;
69#elif HAVE_FUNC__FINITE
70 return _finite(d) == 0 && d == d;
71#else
72 return false;
73#endif
74}
75
76bool isPosInf(double d)
77{
78#if WIN32
79 return _FPCLASS_PINF == _fpclass(d);
80#elif defined(HAVE_FUNC_ISINF)
81 return (isinf(d) == 1);
82#elif HAVE_FUNC_FINITE
83 return finite(d) == 0 && d == d; // ### can we distinguish between + and - ?
84#elif HAVE_FUNC__FINITE
85 return _finite(d) == 0 && d == d; // ###
86#else
87 return false;
88#endif
89}
90
91bool isNegInf(double d)
92{
93#if WIN32
94 return _FPCLASS_NINF == _fpclass(d);
95#elif defined(HAVE_FUNC_ISINF)
96 return (isinf(d) == -1);
97#elif HAVE_FUNC_FINITE
98 return finite(d) == 0 && d == d; // ###
99#elif HAVE_FUNC__FINITE
100 return _finite(d) == 0 && d == d; // ###
101#else
102 return false;
103#endif
104}
105
106#endif
107
108// ECMA 11.9.3
109bool equal(ExecState *exec, JSValue *v1, JSValue *v2)
110{
111 JSType t1 = v1->type();
112 JSType t2 = v2->type();
113
114 if (t1 != t2) {
115 if (t1 == UndefinedType)
116 t1 = NullType;
117 if (t2 == UndefinedType)
118 t2 = NullType;
119
120 if (t1 == BooleanType)
121 t1 = NumberType;
122 if (t2 == BooleanType)
123 t2 = NumberType;
124
125 if (t1 == NumberType && t2 == StringType) {
126 // use toNumber
127 } else if (t1 == StringType && t2 == NumberType) {
128 t1 = NumberType;
129 // use toNumber
130 } else {
131 if ((t1 == StringType || t1 == NumberType) && t2 >= ObjectType)
132 return equal(exec, v1, v2->toPrimitive(exec));
133 if (t1 == NullType && t2 == ObjectType)
134 return static_cast<JSObject *>(v2)->masqueradeAsUndefined();
135 if (t1 >= ObjectType && (t2 == StringType || t2 == NumberType))
136 return equal(exec, v1->toPrimitive(exec), v2);
137 if (t1 == ObjectType && t2 == NullType)
138 return static_cast<JSObject *>(v1)->masqueradeAsUndefined();
139 if (t1 != t2)
140 return false;
141 }
142 }
143
144 if (t1 == UndefinedType || t1 == NullType)
145 return true;
146
147 if (t1 == NumberType) {
148 double d1 = v1->toNumber(exec);
149 double d2 = v2->toNumber(exec);
150 return d1 == d2;
151 }
152
153 if (t1 == StringType)
154 return v1->toString(exec) == v2->toString(exec);
155
156 if (t1 == BooleanType)
157 return v1->toBoolean(exec) == v2->toBoolean(exec);
158
159 // types are Object
160 return v1 == v2;
161}
162
163bool strictEqual(ExecState *exec, JSValue *v1, JSValue *v2)
164{
165 JSType t1 = v1->type();
166 JSType t2 = v2->type();
167
168 if (t1 != t2)
169 return false;
170 if (t1 == UndefinedType || t1 == NullType)
171 return true;
172 if (t1 == NumberType) {
173 double n1 = v1->toNumber(exec);
174 double n2 = v2->toNumber(exec);
175 if (n1 == n2)
176 return true;
177 return false;
178 } else if (t1 == StringType) {
179 return v1->toString(exec) == v2->toString(exec);
180 } else if (t2 == BooleanType) {
181 return v1->toBoolean(exec) == v2->toBoolean(exec);
182 }
183 if (v1 == v2)
184 return true;
185 /* TODO: joined objects */
186
187 return false;
188}
189
190int relation(ExecState *exec, JSValue *v1, JSValue *v2)
191{
192 JSValue *p1 = v1->toPrimitive(exec,NumberType);
193 JSValue *p2 = v2->toPrimitive(exec,NumberType);
194
195 if (p1->isString() && p2->isString())
196 return p1->toString(exec) < p2->toString(exec) ? 1 : 0;
197
198 double n1 = p1->toNumber(exec);
199 double n2 = p2->toNumber(exec);
200 if (n1 < n2)
201 return 1;
202 if (n1 >= n2)
203 return 0;
204 return -1; // must be NaN, so undefined
205}
206
207int maxInt(int d1, int d2)
208{
209 return (d1 > d2) ? d1 : d2;
210}
211
212int minInt(int d1, int d2)
213{
214 return (d1 < d2) ? d1 : d2;
215}
216
217// ECMA 11.6
218JSValue *add(ExecState *exec, JSValue *v1, JSValue *v2, char oper)
219{
220 // exception for the Date exception in defaultValue()
221 JSType preferred = oper == '+' ? UnspecifiedType : NumberType;
222 JSValue *p1 = v1->toPrimitive(exec, preferred);
223 JSValue *p2 = v2->toPrimitive(exec, preferred);
224
225 if ((p1->isString() || p2->isString()) && oper == '+') {
226 return jsString(p1->toString(exec) + p2->toString(exec));
227 }
228
229 if (oper == '+')
230 return jsNumber(p1->toNumber(exec) + p2->toNumber(exec));
231 else
232 return jsNumber(p1->toNumber(exec) - p2->toNumber(exec));
233}
234
235// ECMA 11.5
236JSValue *mult(ExecState *exec, JSValue *v1, JSValue *v2, char oper)
237{
238 double n1 = v1->toNumber(exec);
239 double n2 = v2->toNumber(exec);
240
241 double result;
242
243 if (oper == '*') {
244 result = n1 * n2;
245 } else if (oper == '/') {
246 result = n1 / n2;
247 } else {
248 result = fmod(n1, n2);
249 }
250
251 return jsNumber(result);
252}
253
254}
Note: See TracBrowser for help on using the repository browser.