2007-11-05 Mark Rowe <mrowe@apple.com>
[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 "internal.h"
27 #include "object.h"
28 #include <math.h>
29 #include <stdio.h>
30 #include <wtf/MathExtras.h>
31
32 #if HAVE(FLOAT_H)
33 #include <float.h>
34 #endif
35
36 namespace KJS {
37
38 // ECMA 11.9.3
39 bool equal(ExecState *exec, JSValue *v1, JSValue *v2)
40 {
41     JSType t1 = v1->type();
42     JSType t2 = v2->type();
43     
44     if (t1 != t2) {
45         if (t1 == UndefinedType)
46             t1 = NullType;
47         if (t2 == UndefinedType)
48             t2 = NullType;
49         
50         if (t1 == BooleanType)
51             t1 = NumberType;
52         if (t2 == BooleanType)
53             t2 = NumberType;
54         
55         if (t1 == NumberType && t2 == StringType) {
56             // use toNumber
57         } else if (t1 == StringType && t2 == NumberType)
58             t1 = NumberType;
59             // use toNumber
60         else {
61             if ((t1 == StringType || t1 == NumberType) && t2 >= ObjectType)
62                 return equal(exec, v1, v2->toPrimitive(exec));
63             if (t1 == NullType && t2 == ObjectType)
64                 return static_cast<JSObject *>(v2)->masqueradeAsUndefined();
65             if (t1 >= ObjectType && (t2 == StringType || t2 == NumberType))
66                 return equal(exec, v1->toPrimitive(exec), v2);
67             if (t1 == ObjectType && t2 == NullType)
68                 return static_cast<JSObject *>(v1)->masqueradeAsUndefined();
69             if (t1 != t2)
70                 return false;
71         }
72     }
73     
74     if (t1 == UndefinedType || t1 == NullType)
75         return true;
76     
77     if (t1 == NumberType) {
78         double d1 = v1->toNumber(exec);
79         double d2 = v2->toNumber(exec);
80         return d1 == d2;
81     }
82     
83     if (t1 == StringType)
84         return static_cast<StringImp*>(v1)->value() == static_cast<StringImp*>(v2)->value();
85     
86     if (t1 == BooleanType)
87         return v1->toBoolean(exec) == v2->toBoolean(exec);
88     
89     // types are Object
90     return v1 == v2;
91 }
92
93 bool strictEqual(ExecState *exec, JSValue *v1, JSValue *v2)
94 {
95     JSType t1 = v1->type();
96     JSType t2 = v2->type();
97     
98     if (t1 != t2)
99         return false;
100     if (t1 == UndefinedType || t1 == NullType)
101         return true;
102     if (t1 == NumberType) {
103         double n1 = v1->toNumber(exec);
104         double n2 = v2->toNumber(exec);
105         if (n1 == n2)
106             return true;
107         return false;
108     } else if (t1 == StringType)
109         return v1->toString(exec) == v2->toString(exec);
110     else if (t2 == BooleanType)
111         return v1->toBoolean(exec) == v2->toBoolean(exec);
112     
113     if (v1 == v2)
114         return true;
115     /* TODO: joined objects */
116     
117     return false;
118 }
119
120 int maxInt(int d1, int d2)
121 {
122     return (d1 > d2) ? d1 : d2;
123 }
124
125 int minInt(int d1, int d2)
126 {
127     return (d1 < d2) ? d1 : d2;
128 }
129
130 }