Remove old relation method, replace with specialised LessThan and lessThenEq function...
[WebKit-https.git] / JavaScriptCore / kjs / operations.cpp
1 // -*- c-basic-offset: 2 -*-
2 /*
3  *  This file is part of the KDE libraries
4  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
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 #include "config.h"
24 #include "operations.h"
25
26 #include "object.h"
27 #include <math.h>
28 #include <stdio.h>
29 #include <wtf/MathExtras.h>
30
31 #if HAVE(FUNC_ISINF) && HAVE(IEEEFP_H)
32 #include <ieeefp.h>
33 #endif
34
35 #if HAVE(FLOAT_H)
36 #include <float.h>
37 #endif
38
39 namespace KJS {
40     
41 #if !PLATFORM(DARWIN)
42
43 // FIXME: Should probably be inlined on non-Darwin platforms too, and controlled exclusively
44 // by HAVE macros rather than PLATFORM.
45
46 // FIXME: Merge with isnan in MathExtras.h and remove this one entirely.
47 bool isNaN(double d)
48 {
49 #if HAVE(FUNC_ISNAN)
50     return isnan(d);
51 #elif HAVE(FLOAT_H)
52     return _isnan(d) != 0;
53 #else
54     return !(d == d);
55 #endif
56 }
57
58 // FIXME: Merge with isinf in MathExtras.h and remove this one entirely.
59 bool isInf(double d)
60 {
61     // FIXME: should be HAVE(_FPCLASS)
62 #if PLATFORM(WIN_OS)
63     int fpClass = _fpclass(d);
64     return _FPCLASS_PINF == fpClass || _FPCLASS_NINF == fpClass;
65 #elif 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
76 bool isPosInf(double d)
77 {
78     // FIXME: should be HAVE(_FPCLASS)
79 #if PLATFORM(WIN_OS)
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; // ###
87 #else
88     return false;
89 #endif
90 }
91
92 bool isNegInf(double d)
93 {
94     // FIXME: should be HAVE(_FPCLASS)
95 #if PLATFORM(WIN_OS)
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; // ###
103 #else
104     return false;
105 #endif
106 }
107
108 #endif
109
110 // ECMA 11.9.3
111 bool equal(ExecState *exec, JSValue *v1, JSValue *v2)
112 {
113     JSType t1 = v1->type();
114     JSType t2 = v2->type();
115     
116     if (t1 != t2) {
117         if (t1 == UndefinedType)
118             t1 = NullType;
119         if (t2 == UndefinedType)
120             t2 = NullType;
121         
122         if (t1 == BooleanType)
123             t1 = NumberType;
124         if (t2 == BooleanType)
125             t2 = NumberType;
126         
127         if (t1 == NumberType && t2 == StringType) {
128             // use toNumber
129         } else if (t1 == StringType && t2 == NumberType)
130             t1 = NumberType;
131             // use toNumber
132         else {
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();
141             if (t1 != t2)
142                 return false;
143         }
144     }
145     
146     if (t1 == UndefinedType || t1 == NullType)
147         return true;
148     
149     if (t1 == NumberType) {
150         double d1 = v1->toNumber(exec);
151         double d2 = v2->toNumber(exec);
152         return d1 == d2;
153     }
154     
155     if (t1 == StringType)
156         return v1->toString(exec) == v2->toString(exec);
157     
158     if (t1 == BooleanType)
159         return v1->toBoolean(exec) == v2->toBoolean(exec);
160     
161     // types are Object
162     return v1 == v2;
163 }
164
165 bool strictEqual(ExecState *exec, JSValue *v1, JSValue *v2)
166 {
167     JSType t1 = v1->type();
168     JSType t2 = v2->type();
169     
170     if (t1 != t2)
171         return false;
172     if (t1 == UndefinedType || t1 == NullType)
173         return true;
174     if (t1 == NumberType) {
175         double n1 = v1->toNumber(exec);
176         double n2 = v2->toNumber(exec);
177         if (n1 == n2)
178             return true;
179         return false;
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);
184     
185     if (v1 == v2)
186         return true;
187     /* TODO: joined objects */
188     
189     return false;
190 }
191
192 int maxInt(int d1, int d2)
193 {
194     return (d1 > d2) ? d1 : d2;
195 }
196
197 int minInt(int d1, int d2)
198 {
199     return (d1 < d2) ? d1 : d2;
200 }
201
202 }