2008-09-24 Maciej Stachowiak <mjs@apple.com>
[WebKit.git] / JavaScriptCore / kjs / operations.h
index 5d9975943728e509f8ca68cd57d2f132a518ac44..ff11ce952c30729812335730ad06b106fdd6636e 100644 (file)
@@ -31,7 +31,78 @@ namespace JSC {
   class ExecState;
   class JSValue;
 
+  // ECMA 11.9.3
   bool equal(ExecState*, JSValue*, JSValue*);
+  bool equalSlowCase(ExecState*, JSValue*, JSValue*);
+
+  ALWAYS_INLINE bool equalSlowCaseInline(ExecState* exec, JSValue* v1, JSValue* v2)
+  {
+      ASSERT(!JSImmediate::areBothImmediateNumbers(v1, v2));
+
+      do {
+          if (v1->isNumber() && v2->isNumber())
+              return v1->uncheckedGetNumber() == v2->uncheckedGetNumber();
+
+          bool s1 = v1->isString();
+          bool s2 = v2->isString();
+          if (s1 && s2)
+              return static_cast<JSString*>(v1)->value() == static_cast<JSString*>(v2)->value();
+
+          if (v1->isUndefinedOrNull()) {
+              if (v2->isUndefinedOrNull())
+                  return true;
+              if (JSImmediate::isImmediate(v2))
+                  return false;
+              return v2->asCell()->structureID()->typeInfo().masqueradesAsUndefined();
+          }
+
+          if (v2->isUndefinedOrNull()) {
+              if (JSImmediate::isImmediate(v1))
+                  return false;
+              return v1->asCell()->structureID()->typeInfo().masqueradesAsUndefined();
+          }
+
+          if (v1->isObject()) {
+              if (v2->isObject())
+                  return v1 == v2;
+              JSValue* p1 = v1->toPrimitive(exec);
+              if (exec->hadException())
+                  return false;
+              v1 = p1;
+              if (JSImmediate::areBothImmediateNumbers(v1, v2))
+                  return v1 == v2;
+              continue;
+          }
+
+          if (v2->isObject()) {
+              JSValue* p2 = v2->toPrimitive(exec);
+              if (exec->hadException())
+                  return false;
+              v2 = p2;
+              if (JSImmediate::areBothImmediateNumbers(v1, v2))
+                  return v1 == v2;
+              continue;
+          }
+
+          if (s1 || s2) {
+              double d1 = v1->toNumber(exec);
+              double d2 = v2->toNumber(exec);
+              return d1 == d2;
+          }
+
+          if (v1->isBoolean()) {
+              if (v2->isNumber())
+                  return static_cast<double>(v1->getBoolean()) == v2->uncheckedGetNumber();
+          } else if (v2->isBoolean()) {
+              if (v1->isNumber())
+                  return v1->uncheckedGetNumber() == static_cast<double>(v2->getBoolean());
+          }
+
+          return v1 == v2;
+      } while (true);
+  }
+
+
   bool strictEqual(JSValue*, JSValue*);
   bool strictEqualSlowCase(JSValue*, JSValue*);