1 /* 2 * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) 3 * Copyright (C) 2002, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Library General Public 7 * License as published by the Free Software Foundation; either 8 * version 2 of the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Library General Public License for more details. 14 * 15 * You should have received a copy of the GNU Library General Public License 16 * along with this library; see the file COPYING.LIB. If not, write to 17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 18 * Boston, MA 02110-1301, USA. 19 * 20 */ 21 22 #ifndef Operations_h 23 #define Operations_h 24 25 #include "JSImmediate.h" 26 #include "JSNumberCell.h" 27 #include "JSString.h" 28 29 namespace JSC { 30 31 // ECMA 11.9.3 equal(ExecState * exec,JSValuePtr v1,JSValuePtr v2)32 inline bool JSValuePtr::equal(ExecState* exec, JSValuePtr v1, JSValuePtr v2) 33 { 34 if (JSImmediate::areBothImmediateIntegerNumbers(v1, v2)) 35 return v1 == v2; 36 37 return equalSlowCase(exec, v1, v2); 38 } 39 equalSlowCaseInline(ExecState * exec,JSValuePtr v1,JSValuePtr v2)40 ALWAYS_INLINE bool JSValuePtr::equalSlowCaseInline(ExecState* exec, JSValuePtr v1, JSValuePtr v2) 41 { 42 ASSERT(!JSImmediate::areBothImmediateIntegerNumbers(v1, v2)); 43 44 do { 45 if (v1.isNumber() && v2.isNumber()) 46 return v1.uncheckedGetNumber() == v2.uncheckedGetNumber(); 47 48 bool s1 = v1.isString(); 49 bool s2 = v2.isString(); 50 if (s1 && s2) 51 return asString(v1)->value() == asString(v2)->value(); 52 53 if (v1.isUndefinedOrNull()) { 54 if (v2.isUndefinedOrNull()) 55 return true; 56 if (JSImmediate::isImmediate(v2)) 57 return false; 58 return v2.asCell()->structure()->typeInfo().masqueradesAsUndefined(); 59 } 60 61 if (v2.isUndefinedOrNull()) { 62 if (JSImmediate::isImmediate(v1)) 63 return false; 64 return v1.asCell()->structure()->typeInfo().masqueradesAsUndefined(); 65 } 66 67 if (v1.isObject()) { 68 if (v2.isObject()) 69 return v1 == v2; 70 JSValuePtr p1 = v1.toPrimitive(exec); 71 if (exec->hadException()) 72 return false; 73 v1 = p1; 74 if (JSImmediate::areBothImmediateIntegerNumbers(v1, v2)) 75 return v1 == v2; 76 continue; 77 } 78 79 if (v2.isObject()) { 80 JSValuePtr p2 = v2.toPrimitive(exec); 81 if (exec->hadException()) 82 return false; 83 v2 = p2; 84 if (JSImmediate::areBothImmediateIntegerNumbers(v1, v2)) 85 return v1 == v2; 86 continue; 87 } 88 89 if (s1 || s2) { 90 double d1 = v1.toNumber(exec); 91 double d2 = v2.toNumber(exec); 92 return d1 == d2; 93 } 94 95 if (v1.isBoolean()) { 96 if (v2.isNumber()) 97 return static_cast<double>(v1.getBoolean()) == v2.uncheckedGetNumber(); 98 } else if (v2.isBoolean()) { 99 if (v1.isNumber()) 100 return v1.uncheckedGetNumber() == static_cast<double>(v2.getBoolean()); 101 } 102 103 return v1 == v2; 104 } while (true); 105 } 106 107 // ECMA 11.9.3 strictEqual(JSValuePtr v1,JSValuePtr v2)108 inline bool JSValuePtr::strictEqual(JSValuePtr v1, JSValuePtr v2) 109 { 110 if (JSImmediate::areBothImmediateIntegerNumbers(v1, v2)) 111 return v1 == v2; 112 113 if (v1.isNumber() && v2.isNumber()) 114 return v1.uncheckedGetNumber() == v2.uncheckedGetNumber(); 115 116 if (JSImmediate::isEitherImmediate(v1, v2)) 117 return v1 == v2; 118 119 return strictEqualSlowCase(v1, v2); 120 } 121 strictEqualSlowCaseInline(JSValuePtr v1,JSValuePtr v2)122 ALWAYS_INLINE bool JSValuePtr::strictEqualSlowCaseInline(JSValuePtr v1, JSValuePtr v2) 123 { 124 ASSERT(!JSImmediate::isEitherImmediate(v1, v2)); 125 126 if (v1.asCell()->isString() && v2.asCell()->isString()) 127 return asString(v1)->value() == asString(v2)->value(); 128 129 return v1 == v2; 130 } 131 132 JSValuePtr throwOutOfMemoryError(ExecState*); 133 134 } 135 #endif 136