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