JavaScriptCore:
authordarin@apple.com <darin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 19 Aug 2008 04:39:04 +0000 (04:39 +0000)
committerdarin@apple.com <darin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 19 Aug 2008 04:39:04 +0000 (04:39 +0000)
2008-08-12  Darin Adler  <darin@apple.com>

        Reviewed by Geoff.

        - eliminate JSValue::type()

        This will make it slightly easier to change the JSImmediate design without
        having to touch so many call sites.

        SunSpider says this change is a wash (looked like a slight speedup, but not
        statistically significant).

        * API/JSStringRef.cpp: Removed include of JSType.h.
        * API/JSValueRef.cpp: Removed include of JSType.h.
        (JSValueGetType): Replaced use of JSValue::type() with
        JSValue::is functions.

        * JavaScriptCore.exp: Updated.

        * VM/JSPropertyNameIterator.cpp: Removed type() implementation.
        (KJS::JSPropertyNameIterator::toPrimitive): Changed to take
        PreferredPrimitiveType argument instead of JSType.
        * VM/JSPropertyNameIterator.h: Ditto.

        * VM/Machine.cpp:
        (KJS::fastIsNumber): Updated for name change.
        (KJS::fastToInt32): Ditto.
        (KJS::fastToUInt32): Ditto.
        (KJS::jsAddSlowCase): Updated toPrimitive caller for change from
        JSType to PreferredPrimitiveType.
        (KJS::jsAdd): Replaced calls to JSValue::type() with calls to
        JSValue::isString().
        (KJS::jsTypeStringForValue): Replaced calls to JSValue::type()
        with multiple calls to JSValue::is -- we could make this a
        virtual function instead if we want to have faster performance.
        (KJS::Machine::privateExecute): Renamed JSImmediate::toTruncatedUInt32
        to JSImmediate::getTruncatedUInt32 for consistency with other functions.
        Changed two calls of JSValue::type() to JSValue::isString().

        * kjs/GetterSetter.cpp:
        (KJS::GetterSetter::toPrimitive): Changed to take
        PreferredPrimitiveType argument instead of JSType.
        (KJS::GetterSetter::isGetterSetter): Added.
        * kjs/GetterSetter.h:

        * kjs/JSCell.cpp:
        (KJS::JSCell::isString): Added.
        (KJS::JSCell::isGetterSetter): Added.
        (KJS::JSCell::isObject): Added.

        * kjs/JSCell.h: Eliminated type function. Added isGetterSetter.
        Made isString and isObject virtual. Changed toPrimitive to take
        PreferredPrimitiveType argument instead of JSType.
        (KJS::JSCell::isNumber): Use Heap::isNumber for faster performance.
        (KJS::JSValue::isGetterSetter): Added.
        (KJS::JSValue::toPrimitive): Changed to take
        PreferredPrimitiveType argument instead of JSType.

        * kjs/JSImmediate.h: Removed JSValue::type() and replaced
        JSValue::toTruncatedUInt32 with JSValue::getTruncatedUInt32.
        (KJS::JSImmediate::isEitherImmediate): Added.

        * kjs/JSNotAnObject.cpp:
        (KJS::JSNotAnObject::toPrimitive): Changed to take
        PreferredPrimitiveType argument instead of JSType.
        * kjs/JSNotAnObject.h: Ditto.
        * kjs/JSNumberCell.cpp:
        (KJS::JSNumberCell::toPrimitive): Ditto.
        * kjs/JSNumberCell.h:
        (KJS::JSNumberCell::toInt32): Renamed from fastToInt32. There's no
        other "slow" version of this once you have a JSNumberCell, so there's
        no need for "fast" in the name. It's a feature that this hides the
        base class toInt32, which does the same job less efficiently (and has
        an additional ExecState argument).
        (KJS::JSNumberCell::toUInt32): Ditto.

        * kjs/JSObject.cpp:
        (KJS::callDefaultValueFunction): Use isGetterSetter instead of type.
        (KJS::JSObject::getPrimitiveNumber): Use PreferredPrimitiveType.
        (KJS::JSObject::defaultValue): Ditto.
        (KJS::JSObject::defineGetter): Use isGetterSetter.
        (KJS::JSObject::defineSetter): Ditto.
        (KJS::JSObject::lookupGetter): Ditto.
        (KJS::JSObject::lookupSetter): Ditto.
        (KJS::JSObject::toNumber): Use PreferredPrimitiveType.
        (KJS::JSObject::toString): Ditto.
        (KJS::JSObject::isObject): Added.

        * kjs/JSObject.h:
        (KJS::JSObject::inherits): Call the isObject from JSCell; it's now
        hidden by our override of isObject.
        (KJS::JSObject::getOwnPropertySlotForWrite): Use isGetterSetter
        instead of type.
        (KJS::JSObject::getOwnPropertySlot): Ditto.
        (KJS::JSObject::toPrimitive): Use PreferredPrimitiveType.

        * kjs/JSString.cpp:
        (KJS::JSString::toPrimitive): Use PreferredPrimitiveType.
        (KJS::JSString::isString): Added.
        * kjs/JSString.h: Ditto.

        * kjs/JSValue.h: Removed type(), added isGetterSetter(). Added
        PreferredPrimitiveType enum and used it as the argument for the
        toPrimitive function.
        (KJS::JSValue::getBoolean): Simplified a bit an removed a branch.

        * kjs/collector.cpp:
        (KJS::typeName): Changed to use JSCell::is functions instead of
        calling JSCell::type.

        * kjs/collector.h:
        (KJS::Heap::isNumber): Renamed from fastIsNumber.

        * kjs/nodes.h: Added now-needed include of JSType, since the type
        is used here to record types of values in the tree.

        * kjs/operations.cpp:
        (KJS::equal): Rewrote to no longer depend on type().
        (KJS::strictEqual): Ditto.

JavaScriptGlue:

2008-08-12  Darin Adler  <darin@apple.com>

        Reviewed by Geoff.

        - eliminate JSValue::type()

        * JSUtils.cpp:
        (KJSValueToCFTypeInternal): Replaced uses of JSValue::type() with
        JSValue::is functions.
        * UserObjectImp.cpp:
        (UserObjectImp::getOwnPropertySlot): Ditto.
        (UserObjectImp::toPrimitive): Take PreferredPrimitiveType argument
        instead of JSType argument.
        * UserObjectImp.h: Ditto.

WebCore:

2008-08-12  Darin Adler  <darin@apple.com>

        Reviewed by Geoff.

        - eliminate JSValue::type()

        * bridge/c/c_instance.cpp:
        (KJS::Bindings::CInstance::defaultValue): Take PreferredPrimitiveType
        argument instead of JSType argument. Removed unneeded code to handle
        boolean, since that's never passed.
        * bridge/c/c_instance.h: Ditto.

        * bridge/c/c_utility.cpp:
        (KJS::Bindings::convertValueToNPVariant): Use JSValue::is functions
        instead of JSValue::type(). Removed unneeded code to handle
        "unspecified".

        * bridge/jni/jni_instance.cpp:
        (JavaInstance::defaultValue): Take PreferredPrimitiveType argument
        instead of JSType argument. Removed unneeded code to handle boolean.
        * bridge/jni/jni_instance.h: Ditto.

        * bridge/jni/jni_jsobject.mm:
        (JavaJSObject::convertValueToJObject): Use JSValue::is functions
        instead of JSValue::type().

        * bridge/objc/objc_instance.h: Take PreferredPrimitiveType argument
        instead of JSType argument. Removed unused argument.
        * bridge/objc/objc_instance.mm:
        (ObjcInstance::getValueOfUndefinedField): Removed unused argument.
        (ObjcInstance::defaultValue): Take PreferredPrimitiveType argument
        instead of JSType argument. Removed unneeded code to handle boolean
        and another dead code path for unknown types.

        * bridge/objc/objc_runtime.h: Take PreferredPrimitiveType argument
        instead of JSType argument. Removed override of type() that caused
        the fallback object to return "UndefinedType" when there is no
        invokeUndefinedMethodFromWebScript:withArguments: method defined.
        That didn't accomplish much, since most checks for undefined don't
        ever call type().
        * bridge/objc/objc_runtime.mm:
        (ObjcFallbackObjectImp::defaultValue): Ditto.

        * bridge/qt/qt_instance.cpp:
        (KJS::Bindings::QtInstance::defaultValue): Take PreferredPrimitiveType
        argument instead of JSType argument. Removed unneeded code to handle
        boolean.
        * bridge/qt/qt_instance.h: Ditto.

        * bridge/runtime.h:
        (KJS::Bindings::Instance::getValueOfUndefinedField): Removed
        unsed argument.
        * bridge/runtime_object.cpp:
        (RuntimeObjectImp::defaultValue): Take PreferredPrimitiveType
        argument instead of JSType argument.
        * bridge/runtime_object.h: Ditto.

WebKit/mac:

2008-08-12  Darin Adler  <darin@apple.com>

        Reviewed by Geoff.

        - eliminate JSValue::type()

        * WebView/WebView.mm:
        (aeDescFromJSValue): Rewrite to use the JSValue::is functions instead
        of a switch on JSValue::type().

LayoutTests:

2008-08-12  Darin Adler  <darin@apple.com>

        Reviewed by Geoff.

        - added a test since I had to rewrite the == and === operators

        * fast/js/equality-expected.txt: Added.
        * fast/js/equality.html: Added.
        * fast/js/resources/equality.js: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@35830 268f45cc-cd09-0410-ab3c-d52691b4dbfc

50 files changed:
JavaScriptCore/API/JSValueRef.cpp
JavaScriptCore/ChangeLog
JavaScriptCore/JavaScriptCore.exp
JavaScriptCore/VM/JSPropertyNameIterator.cpp
JavaScriptCore/VM/JSPropertyNameIterator.h
JavaScriptCore/VM/Machine.cpp
JavaScriptCore/kjs/GetterSetter.cpp
JavaScriptCore/kjs/GetterSetter.h
JavaScriptCore/kjs/JSCell.cpp
JavaScriptCore/kjs/JSCell.h
JavaScriptCore/kjs/JSImmediate.h
JavaScriptCore/kjs/JSNotAnObject.cpp
JavaScriptCore/kjs/JSNotAnObject.h
JavaScriptCore/kjs/JSNumberCell.cpp
JavaScriptCore/kjs/JSNumberCell.h
JavaScriptCore/kjs/JSObject.cpp
JavaScriptCore/kjs/JSObject.h
JavaScriptCore/kjs/JSString.cpp
JavaScriptCore/kjs/JSString.h
JavaScriptCore/kjs/JSValue.h
JavaScriptCore/kjs/collector.cpp
JavaScriptCore/kjs/collector.h
JavaScriptCore/kjs/nodes.h
JavaScriptCore/kjs/operations.cpp
JavaScriptGlue/ChangeLog
JavaScriptGlue/JSUtils.cpp
JavaScriptGlue/UserObjectImp.cpp
JavaScriptGlue/UserObjectImp.h
LayoutTests/ChangeLog
LayoutTests/fast/js/equality-expected.txt [new file with mode: 0644]
LayoutTests/fast/js/equality.html [new file with mode: 0644]
LayoutTests/fast/js/resources/equality.js [new file with mode: 0644]
WebCore/ChangeLog
WebCore/bridge/c/c_instance.cpp
WebCore/bridge/c/c_instance.h
WebCore/bridge/c/c_utility.cpp
WebCore/bridge/jni/jni_instance.cpp
WebCore/bridge/jni/jni_instance.h
WebCore/bridge/jni/jni_jsobject.mm
WebCore/bridge/objc/objc_instance.h
WebCore/bridge/objc/objc_instance.mm
WebCore/bridge/objc/objc_runtime.h
WebCore/bridge/objc/objc_runtime.mm
WebCore/bridge/qt/qt_instance.cpp
WebCore/bridge/qt/qt_instance.h
WebCore/bridge/runtime.h
WebCore/bridge/runtime_object.cpp
WebCore/bridge/runtime_object.h
WebKit/mac/ChangeLog
WebKit/mac/WebView/WebView.mm

index 0a6c40f..c920c8b 100644 (file)
@@ -31,7 +31,6 @@
 #include "APICast.h"
 #include "JSCallbackObject.h"
 
-#include <kjs/JSType.h>
 #include <kjs/JSGlobalObject.h>
 #include <kjs/JSString.h>
 #include <kjs/operations.h>
 JSType JSValueGetType(JSContextRef, JSValueRef value)
 {
     KJS::JSValue* jsValue = toJS(value);
-    switch (jsValue->type()) {
-        case KJS::UndefinedType:
-            return kJSTypeUndefined;
-        case KJS::NullType:
-            return kJSTypeNull;
-        case KJS::BooleanType:
-            return kJSTypeBoolean;
-        case KJS::NumberType:
-            return kJSTypeNumber;
-        case KJS::StringType:
-            return kJSTypeString;
-        case KJS::ObjectType:
-            return kJSTypeObject;
-        default:
-            ASSERT(!"JSValueGetType: unknown type code.\n");
-            return kJSTypeUndefined;
-    }
+    if (jsValue->isUndefined())
+        return kJSTypeUndefined;
+    if (jsValue->isNull())
+        return kJSTypeNull;
+    if (jsValue->isBoolean())
+        return kJSTypeBoolean;
+    if (jsValue->isNumber())
+        return kJSTypeNumber;
+    if (jsValue->isString())
+        return kJSTypeString;
+    ASSERT(jsValue->isObject());
+    return kJSTypeObject;
 }
 
 using namespace KJS; // placed here to avoid conflict between KJS::JSType and JSType, above.
index 898d41f..4cb93c1 100644 (file)
@@ -1,3 +1,123 @@
+2008-08-12  Darin Adler  <darin@apple.com>
+
+        Reviewed by Geoff.
+
+        - eliminate JSValue::type()
+
+        This will make it slightly easier to change the JSImmediate design without
+        having to touch so many call sites.
+
+        SunSpider says this change is a wash (looked like a slight speedup, but not
+        statistically significant).
+
+        * API/JSStringRef.cpp: Removed include of JSType.h.
+        * API/JSValueRef.cpp: Removed include of JSType.h.
+        (JSValueGetType): Replaced use of JSValue::type() with
+        JSValue::is functions.
+
+        * JavaScriptCore.exp: Updated.
+
+        * VM/JSPropertyNameIterator.cpp: Removed type() implementation.
+        (KJS::JSPropertyNameIterator::toPrimitive): Changed to take
+        PreferredPrimitiveType argument instead of JSType.
+        * VM/JSPropertyNameIterator.h: Ditto.
+
+        * VM/Machine.cpp:
+        (KJS::fastIsNumber): Updated for name change.
+        (KJS::fastToInt32): Ditto.
+        (KJS::fastToUInt32): Ditto.
+        (KJS::jsAddSlowCase): Updated toPrimitive caller for change from
+        JSType to PreferredPrimitiveType.
+        (KJS::jsAdd): Replaced calls to JSValue::type() with calls to
+        JSValue::isString().
+        (KJS::jsTypeStringForValue): Replaced calls to JSValue::type()
+        with multiple calls to JSValue::is -- we could make this a
+        virtual function instead if we want to have faster performance.
+        (KJS::Machine::privateExecute): Renamed JSImmediate::toTruncatedUInt32
+        to JSImmediate::getTruncatedUInt32 for consistency with other functions.
+        Changed two calls of JSValue::type() to JSValue::isString().
+
+        * kjs/GetterSetter.cpp:
+        (KJS::GetterSetter::toPrimitive): Changed to take
+        PreferredPrimitiveType argument instead of JSType.
+        (KJS::GetterSetter::isGetterSetter): Added.
+        * kjs/GetterSetter.h:
+
+        * kjs/JSCell.cpp:
+        (KJS::JSCell::isString): Added.
+        (KJS::JSCell::isGetterSetter): Added.
+        (KJS::JSCell::isObject): Added.
+
+        * kjs/JSCell.h: Eliminated type function. Added isGetterSetter.
+        Made isString and isObject virtual. Changed toPrimitive to take
+        PreferredPrimitiveType argument instead of JSType.
+        (KJS::JSCell::isNumber): Use Heap::isNumber for faster performance.
+        (KJS::JSValue::isGetterSetter): Added.
+        (KJS::JSValue::toPrimitive): Changed to take
+        PreferredPrimitiveType argument instead of JSType.
+
+        * kjs/JSImmediate.h: Removed JSValue::type() and replaced
+        JSValue::toTruncatedUInt32 with JSValue::getTruncatedUInt32.
+        (KJS::JSImmediate::isEitherImmediate): Added.
+
+        * kjs/JSNotAnObject.cpp:
+        (KJS::JSNotAnObject::toPrimitive): Changed to take
+        PreferredPrimitiveType argument instead of JSType.
+        * kjs/JSNotAnObject.h: Ditto.
+        * kjs/JSNumberCell.cpp:
+        (KJS::JSNumberCell::toPrimitive): Ditto.
+        * kjs/JSNumberCell.h:
+        (KJS::JSNumberCell::toInt32): Renamed from fastToInt32. There's no
+        other "slow" version of this once you have a JSNumberCell, so there's
+        no need for "fast" in the name. It's a feature that this hides the
+        base class toInt32, which does the same job less efficiently (and has
+        an additional ExecState argument).
+        (KJS::JSNumberCell::toUInt32): Ditto.
+
+        * kjs/JSObject.cpp:
+        (KJS::callDefaultValueFunction): Use isGetterSetter instead of type.
+        (KJS::JSObject::getPrimitiveNumber): Use PreferredPrimitiveType.
+        (KJS::JSObject::defaultValue): Ditto.
+        (KJS::JSObject::defineGetter): Use isGetterSetter.
+        (KJS::JSObject::defineSetter): Ditto.
+        (KJS::JSObject::lookupGetter): Ditto.
+        (KJS::JSObject::lookupSetter): Ditto.
+        (KJS::JSObject::toNumber): Use PreferredPrimitiveType.
+        (KJS::JSObject::toString): Ditto.
+        (KJS::JSObject::isObject): Added.
+
+        * kjs/JSObject.h:
+        (KJS::JSObject::inherits): Call the isObject from JSCell; it's now
+        hidden by our override of isObject.
+        (KJS::JSObject::getOwnPropertySlotForWrite): Use isGetterSetter
+        instead of type.
+        (KJS::JSObject::getOwnPropertySlot): Ditto.
+        (KJS::JSObject::toPrimitive): Use PreferredPrimitiveType.
+
+        * kjs/JSString.cpp:
+        (KJS::JSString::toPrimitive): Use PreferredPrimitiveType.
+        (KJS::JSString::isString): Added.
+        * kjs/JSString.h: Ditto.
+
+        * kjs/JSValue.h: Removed type(), added isGetterSetter(). Added
+        PreferredPrimitiveType enum and used it as the argument for the
+        toPrimitive function.
+        (KJS::JSValue::getBoolean): Simplified a bit an removed a branch.
+
+        * kjs/collector.cpp:
+        (KJS::typeName): Changed to use JSCell::is functions instead of
+        calling JSCell::type.
+
+        * kjs/collector.h:
+        (KJS::Heap::isNumber): Renamed from fastIsNumber.
+
+        * kjs/nodes.h: Added now-needed include of JSType, since the type
+        is used here to record types of values in the tree.
+
+        * kjs/operations.cpp:
+        (KJS::equal): Rewrote to no longer depend on type().
+        (KJS::strictEqual): Ditto.
+
 2008-08-18  Kevin McCullough  <kmccullough@apple.com>
 
         Reviewed by Tim.
index 987df08..f55f582 100644 (file)
@@ -275,8 +275,11 @@ __ZNK3KJS17DebuggerCallFrame8evaluateERKNS_7UStringERPNS_7JSValueE
 __ZNK3KJS4Node8toStringEv
 __ZNK3KJS6JSCell12toThisObjectEPNS_9ExecStateE
 __ZNK3KJS6JSCell12toThisStringEPNS_9ExecStateE
+__ZNK3KJS6JSCell14isGetterSetterEv
 __ZNK3KJS6JSCell17getTruncatedInt32ERi
 __ZNK3KJS6JSCell18getTruncatedUInt32ERj
+__ZNK3KJS6JSCell8isObjectEv
+__ZNK3KJS6JSCell8isStringEv
 __ZNK3KJS6JSCell9classInfoEv
 __ZNK3KJS6JSCell9getNumberEv
 __ZNK3KJS6JSCell9getStringERNS_7UStringE
@@ -296,12 +299,12 @@ __ZNK3KJS7UString8toUInt32EPb
 __ZNK3KJS7UString8toUInt32EPbb
 __ZNK3KJS8JSObject11hasPropertyEPNS_9ExecStateERKNS_10IdentifierE
 __ZNK3KJS8JSObject11hasPropertyEPNS_9ExecStateEj
-__ZNK3KJS8JSObject12defaultValueEPNS_9ExecStateENS_6JSTypeE
+__ZNK3KJS8JSObject12defaultValueEPNS_9ExecStateENS_7JSValue22PreferredPrimitiveTypeE
 __ZNK3KJS8JSObject12toThisObjectEPNS_9ExecStateE
 __ZNK3KJS8JSObject14toGlobalObjectEPNS_9ExecStateE
 __ZNK3KJS8JSObject21getPropertyAttributesEPNS_9ExecStateERKNS_10IdentifierERj
 __ZNK3KJS8JSObject21implementsHasInstanceEv
-__ZNK3KJS8JSObject4typeEv
+__ZNK3KJS8JSObject8isObjectEv
 __ZNK3KJS8JSObject8toNumberEPNS_9ExecStateE
 __ZNK3KJS8JSObject8toObjectEPNS_9ExecStateE
 __ZNK3KJS8JSObject8toStringEPNS_9ExecStateE
index b30a5e1..2a7ca83 100644 (file)
@@ -63,12 +63,7 @@ JSPropertyNameIterator::~JSPropertyNameIterator()
     invalidate();
 }
 
-JSType JSPropertyNameIterator::type() const
-{
-    return UnspecifiedType;
-}
-
-JSValue* JSPropertyNameIterator::toPrimitive(ExecState*, JSType) const
+JSValue* JSPropertyNameIterator::toPrimitive(ExecState*, PreferredPrimitiveType) const
 {
     ASSERT_NOT_REACHED();
     return 0;
index e074ed7..d03704c 100644 (file)
@@ -42,8 +42,7 @@ namespace KJS {
 
         virtual ~JSPropertyNameIterator();
 
-        virtual JSType type() const;
-        virtual JSValue* toPrimitive(ExecState*, JSType) const;
+        virtual JSValue* toPrimitive(ExecState*, PreferredPrimitiveType) const;
         virtual bool getPrimitiveNumber(ExecState*, double&, JSValue*&);
         virtual bool toBoolean(ExecState*) const;
         virtual double toNumber(ExecState*) const;
index 5ae33c6..092b1dc 100644 (file)
@@ -98,35 +98,41 @@ static int depth(CodeBlock* codeBlock, ScopeChain& sc)
     return scopeDepth;
 }
 
-static bool fastIsNumber(JSValue* value, double& arg) {
+// FIXME: This operation should be called "getNumber", not "isNumber" (as it is in JSValue.h).
+// FIXME: There's no need to have a "slow" version of this. All versions should be fast.
+static bool fastIsNumber(JSValue* value, double& arg)
+{
     if (JSImmediate::isNumber(value))
         arg = JSImmediate::getTruncatedInt32(value);
-    else if (Heap::fastIsNumber(static_cast<JSCell*>(value)))
+    else if (Heap::isNumber(static_cast<JSCell*>(value)))
         arg = static_cast<JSNumberCell*>(value)->value();
     else
         return false;
     return true;
 }
 
-static bool fastToInt32(JSValue* value, int32_t& arg) {
+// FIXME: Why doesn't JSValue::toInt32 have the Heap::isNumber optimization?
+static bool fastToInt32(JSValue* value, int32_t& arg)
+{
     if (JSImmediate::isNumber(value))
         arg = JSImmediate::getTruncatedInt32(value);
-    else if (Heap::fastIsNumber(static_cast<JSCell*>(value)))
-        arg = static_cast<JSNumberCell*>(value)->fastToInt32();
+    else if (Heap::isNumber(static_cast<JSCell*>(value)))
+        arg = static_cast<JSNumberCell*>(value)->toInt32();
     else
         return false;
     return true;
 }
 
-static ALWAYS_INLINE bool fastToUInt32(JSValue* value, uint32_t& arg) {
+static ALWAYS_INLINE bool fastToUInt32(JSValue* value, uint32_t& arg)
+{
     if (JSImmediate::isNumber(value)) {
         if (JSImmediate::getTruncatedUInt32(value, arg))
             return true;
         bool scratch;
         arg = JSValue::toUInt32SlowCase(JSImmediate::getTruncatedInt32(value), scratch);
         return true;
-    } else if (Heap::fastIsNumber(static_cast<JSCell*>(value)))
-        arg = static_cast<JSNumberCell*>(value)->fastToUInt32();
+    } else if (Heap::isNumber(static_cast<JSCell*>(value)))
+        arg = static_cast<JSNumberCell*>(value)->toUInt32();
     else
         return false;
     return true;
@@ -177,8 +183,8 @@ static inline bool jsLessEq(ExecState* exec, JSValue* v1, JSValue* v2)
 static JSValue* jsAddSlowCase(ExecState* exec, JSValue* v1, JSValue* v2)
 {
     // exception for the Date exception in defaultValue()
-    JSValue* p1 = v1->toPrimitive(exec, UnspecifiedType);
-    JSValue* p2 = v2->toPrimitive(exec, UnspecifiedType);
+    JSValue* p1 = v1->toPrimitive(exec);
+    JSValue* p2 = v2->toPrimitive(exec);
 
     if (p1->isString() || p2->isString()) {
         UString value = p1->toString(exec) + p2->toString(exec);
@@ -203,15 +209,10 @@ static inline JSValue* jsAdd(ExecState* exec, JSValue* v1, JSValue* v2)
 {
     double left;
     double right;
-    
     if (fastIsNumber(v1, left) && fastIsNumber(v2, right))
         return jsNumber(exec, left + right);
     
-    JSType t1 = v1->type();
-    JSType t2 = v2->type();
-    const unsigned bothTypes = (t1 << 3) | t2;
-    ASSERT(bothTypes != ((NumberType << 3) | NumberType));
-    if (bothTypes == ((StringType << 3) | StringType)) {
+    if (v1->isString() && v2->isString()) {
         UString value = static_cast<JSString*>(v1)->value() + static_cast<JSString*>(v2)->value();
         if (value.isNull())
             return throwOutOfMemoryError(exec);
@@ -224,30 +225,24 @@ static inline JSValue* jsAdd(ExecState* exec, JSValue* v1, JSValue* v2)
 
 static JSValue* jsTypeStringForValue(ExecState* exec, JSValue* v)
 {
-    switch (v->type()) {
-        case UndefinedType:
+    if (v->isUndefined())
+        return jsString(exec, "undefined");
+    if (v->isBoolean())
+        return jsString(exec, "boolean");
+    if (v->isNumber())
+        return jsString(exec, "number");
+    if (v->isString())
+        return jsString(exec, "string");
+    if (v->isObject()) {
+        // Return "undefined" for objects that should be treated
+        // as null when doing comparisons.
+        if (static_cast<JSObject*>(v)->masqueradeAsUndefined())
             return jsString(exec, "undefined");
-        case NullType:
-            return jsString(exec, "object");
-        case BooleanType:
-            return jsString(exec, "boolean");
-        case NumberType:
-            return jsString(exec, "number");
-        case StringType:
-            return jsString(exec, "string");
-        default:
-            if (v->isObject()) {
-                // Return "undefined" for objects that should be treated
-                // as null when doing comparisons.
-                if (static_cast<JSObject*>(v)->masqueradeAsUndefined())
-                    return jsString(exec, "undefined");
-                CallData callData;
-                if (static_cast<JSObject*>(v)->getCallData(callData) != CallTypeNone)
-                    return jsString(exec, "function");
-            }
-
-            return jsString(exec, "object");
+        CallData callData;
+        if (static_cast<JSObject*>(v)->getCallData(callData) != CallTypeNone)
+            return jsString(exec, "function");
     }
+    return jsString(exec, "object");
 }
 
 static bool NEVER_INLINE resolve(ExecState* exec, Instruction* vPC, Register* r, ScopeChainNode* scopeChain, CodeBlock* codeBlock, JSValue*& exceptionValue)
@@ -1553,7 +1548,7 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, ExecState* exec, RegisterFi
         int32_t left;
         uint32_t right;
         if (JSImmediate::areBothImmediateNumbers(val, shift))
-            r[dst] = jsNumber(exec, JSImmediate::getTruncatedInt32(val) << (JSImmediate::toTruncatedUInt32(shift) & 0x1f));
+            r[dst] = jsNumber(exec, JSImmediate::getTruncatedInt32(val) << (JSImmediate::getTruncatedUInt32(shift) & 0x1f));
         else if (fastToInt32(val, left) && fastToUInt32(shift, right))
             r[dst] = jsNumber(exec, left << (right & 0x1f));
         else {
@@ -2271,7 +2266,7 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, ExecState* exec, RegisterFi
         int tableIndex = (++vPC)->u.operand;
         int defaultOffset = (++vPC)->u.operand;
         JSValue* scrutinee = r[(++vPC)->u.operand].jsValue(exec);
-        if (scrutinee->type() != StringType)
+        if (!scrutinee->isString())
             vPC += defaultOffset;
         else {
             UString::Rep* value = static_cast<JSString*>(scrutinee)->value().rep();
@@ -2294,7 +2289,7 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, ExecState* exec, RegisterFi
         int tableIndex = (++vPC)->u.operand;
         int defaultOffset = (++vPC)->u.operand;
         JSValue* scrutinee = r[(++vPC)->u.operand].jsValue(exec);
-        if (scrutinee->type() != StringType)
+        if (!scrutinee->isString())
             vPC += defaultOffset;
         else 
             vPC += offsetForStringSwitch(codeBlock->stringSwitchJumpTables[tableIndex], scrutinee, defaultOffset);
index 3912768..7525e7e 100644 (file)
@@ -38,7 +38,7 @@ void GetterSetter::mark()
         m_setter->mark();
 }
 
-JSValue* GetterSetter::toPrimitive(ExecState*, JSType) const
+JSValue* GetterSetter::toPrimitive(ExecState*, PreferredPrimitiveType) const
 {
     ASSERT_NOT_REACHED();
     return jsNull();
@@ -76,4 +76,9 @@ JSObject* GetterSetter::toObject(ExecState* exec) const
     return jsNull()->toObject(exec);
 }
 
+bool GetterSetter::isGetterSetter() const
+{
+    return true;
+}
+
 } // namespace KJS
index 7b4d54d..ffa7012 100644 (file)
@@ -39,8 +39,6 @@ namespace KJS {
         {
         }
 
-        JSType type() const { return GetterSetterType; }
-
         virtual void mark();
 
         JSObject* getter() const { return m_getter; }
@@ -49,7 +47,9 @@ namespace KJS {
         void setSetter(JSObject* setter) { m_setter = setter; }
 
     private:
-        virtual JSValue* toPrimitive(ExecState*, JSType preferred) const;
+        virtual bool isGetterSetter() const;
+
+        virtual JSValue* toPrimitive(ExecState*, PreferredPrimitiveType) const;
         virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue*& value);
         virtual bool toBoolean(ExecState*) const;
         virtual double toNumber(ExecState*) const;
index d6a80eb..3d09a8c 100644 (file)
@@ -215,4 +215,19 @@ JSValue* JSCell::getJSNumber()
     return 0;
 }
 
+bool JSCell::isString() const
+{
+    return false;
+}
+
+bool JSCell::isGetterSetter() const
+{
+    return false;
+}
+
+bool JSCell::isObject() const
+{
+    return false;
+}
+
 } // namespace KJS
index 7d644fb..dc97ba0 100644 (file)
@@ -43,11 +43,11 @@ namespace KJS {
 
     public:
         // Querying the type.
-        virtual JSType type() const = 0;
         bool isNumber() const;
-        bool isString() const;
-        bool isObject() const;
-        bool isObject(const ClassInfo*) const; // FIXME: Merge with inherits.
+        virtual bool isString() const;
+        virtual bool isGetterSetter() const;
+        virtual bool isObject() const;
+        virtual bool isObject(const ClassInfo*) const;
 
         // Extracting the value.
         bool getNumber(double&) const;
@@ -66,7 +66,7 @@ namespace KJS {
         virtual bool getTruncatedUInt32(uint32_t&) const;
 
         // Basic conversions.
-        virtual JSValue* toPrimitive(ExecState*, JSType preferredType = UnspecifiedType) const = 0;
+        virtual JSValue* toPrimitive(ExecState*, PreferredPrimitiveType) const = 0;
         virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue*&) = 0;
         virtual bool toBoolean(ExecState*) const = 0;
         virtual double toNumber(ExecState*) const = 0;
@@ -110,17 +110,7 @@ namespace KJS {
 
     inline bool JSCell::isNumber() const
     {
-        return type() == NumberType;
-    }
-
-    inline bool JSCell::isString() const
-    {
-        return type() == StringType;
-    }
-
-    inline bool JSCell::isObject() const
-    {
-        return type() == ObjectType;
+        return Heap::isNumber(const_cast<JSCell*>(this));
     }
 
     inline bool JSCell::marked() const
@@ -158,6 +148,11 @@ namespace KJS {
         return !JSImmediate::isImmediate(this) && asCell()->isString();
     }
 
+    inline bool JSValue::isGetterSetter() const
+    {
+        return !JSImmediate::isImmediate(this) && asCell()->isGetterSetter();
+    }
+
     inline bool JSValue::isObject() const
     {
         return !JSImmediate::isImmediate(this) && asCell()->isObject();
@@ -233,12 +228,7 @@ namespace KJS {
         return JSImmediate::isImmediate(this) || asCell()->marked();
     }
 
-    inline JSType JSValue::type() const
-    {
-        return JSImmediate::isImmediate(this) ? JSImmediate::type(this) : asCell()->type();
-    }
-
-    inline JSValue* JSValue::toPrimitive(ExecState* exec, JSType preferredType) const
+    inline JSValue* JSValue::toPrimitive(ExecState* exec, PreferredPrimitiveType preferredType) const
     {
         return JSImmediate::isImmediate(this) ? const_cast<JSValue*>(this) : asCell()->toPrimitive(exec, preferredType);
     }
index 55e5f30..5283ded 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
+ *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
  *  Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org)
  *
  *  This library is free software; you can redistribute it and/or
@@ -22,7 +22,6 @@
 #ifndef KJS_JS_IMMEDIATE_H
 #define KJS_JS_IMMEDIATE_H
 
-#include "JSType.h"
 #include <wtf/Assertions.h>
 #include <wtf/AlwaysInline.h>
 #include <wtf/MathExtras.h>
@@ -40,7 +39,7 @@ namespace KJS {
     class UString;
 
     /*
-     * A JSValue*  is either a pointer to a cell (a heap-allocated object) or an immediate (a type-tagged 
+     * A JSValue* is either a pointer to a cell (a heap-allocated object) or an immediate (a type-tagged 
      * value masquerading as a pointer). The low two bits in a JSValue* are available for type tagging
      * because allocator alignment guarantees they will be 00 in cell pointers.
      *
@@ -82,8 +81,9 @@ namespace KJS {
      */
 
     class JSImmediate {
+    private:
         static const uintptr_t TagMask           = 0x3u; // primary tag is 2 bits long
-        static const uintptr_t TagBitTypeInteger = 0x1u; // bottom bit set indicates int, this dominates the following bit
+        static const uintptr_t TagBitTypeInteger = 0x1u; // bottom bit set indicates integer, this dominates the following bit
         static const uintptr_t TagBitTypeOther   = 0x2u; // second bit set indicates immediate other than an integer
 
         static const uintptr_t ExtendedTagMask         = 0xCu; // extended tag holds a further two bits
@@ -103,12 +103,12 @@ namespace KJS {
     public:
         static ALWAYS_INLINE bool isImmediate(const JSValue* v)
         {
-            return (reinterpret_cast<uintptr_t>(v) & TagMask);
+            return reinterpret_cast<uintptr_t>(v) & TagMask;
         }
         
         static ALWAYS_INLINE bool isNumber(const JSValue* v)
         {
-            return (reinterpret_cast<uintptr_t>(v) & TagBitTypeInteger);
+            return reinterpret_cast<uintptr_t>(v) & TagBitTypeInteger;
         }
 
         static ALWAYS_INLINE bool isPositiveNumber(const JSValue* v)
@@ -119,13 +119,13 @@ namespace KJS {
         
         static ALWAYS_INLINE bool isBoolean(const JSValue* v)
         {
-            return ((reinterpret_cast<uintptr_t>(v) & FullTagTypeMask) == FullTagTypeBool);
+            return (reinterpret_cast<uintptr_t>(v) & FullTagTypeMask) == FullTagTypeBool;
         }
         
         static ALWAYS_INLINE bool isUndefinedOrNull(const JSValue* v)
         {
             // Undefined and null share the same value, bar the 'undefined' bit in the extended tag.
-            return ((reinterpret_cast<uintptr_t>(v) & ~ExtendedTagBitUndefined) == FullTagTypeNull);
+            return (reinterpret_cast<uintptr_t>(v) & ~ExtendedTagBitUndefined) == FullTagTypeNull;
         }
 
         static bool isNegative(const JSValue* v)
@@ -147,9 +147,14 @@ namespace KJS {
         static JSValue* from(unsigned long long);
         static JSValue* from(double);
 
+        static ALWAYS_INLINE bool isEitherImmediate(const JSValue* v1, const JSValue* v2)
+        {
+            return (reinterpret_cast<uintptr_t>(v1) | reinterpret_cast<uintptr_t>(v2)) & TagMask;
+        }
+
         static ALWAYS_INLINE bool areBothImmediateNumbers(const JSValue* v1, const JSValue* v2)
         {
-             return (reinterpret_cast<uintptr_t>(v1) & reinterpret_cast<uintptr_t>(v2) & TagBitTypeInteger);
+            return reinterpret_cast<uintptr_t>(v1) & reinterpret_cast<uintptr_t>(v2) & TagBitTypeInteger;
         }
 
         static ALWAYS_INLINE JSValue* andImmediateNumbers(const JSValue* v1, const JSValue* v2)
@@ -213,14 +218,13 @@ namespace KJS {
         static bool toBoolean(const JSValue*);
         static JSObject* toObject(const JSValue*, ExecState*);
         static UString toString(const JSValue*);
-        static uint32_t toTruncatedUInt32(const JSValue*);
-        static JSType type(const JSValue*);
 
         static bool getUInt32(const JSValue*, uint32_t&);
         static bool getTruncatedInt32(const JSValue*, int32_t&);
         static bool getTruncatedUInt32(const JSValue*, uint32_t&);
 
         static int32_t getTruncatedInt32(const JSValue*);
+        static uint32_t getTruncatedUInt32(const JSValue*);
 
         static JSValue* trueImmediate();
         static JSValue* falseImmediate();
@@ -232,7 +236,6 @@ namespace KJS {
         static JSObject* prototype(const JSValue*, ExecState*);
 
     private:
-        // Immediate values are restricted to a 30 bit signed value.
         static const int minImmediateInt = ((-INT_MAX) - 1) >> IntegerPayloadShift;
         static const int maxImmediateInt = INT_MAX >> IntegerPayloadShift;
         static const unsigned maxImmediateUInt = maxImmediateInt;
@@ -269,7 +272,7 @@ namespace KJS {
         
         static ALWAYS_INLINE bool boolValue(const JSValue* v)
         {
-            return (rawValue(v) & ExtendedPayloadBitBoolValue) != 0;
+            return rawValue(v) & ExtendedPayloadBitBoolValue;
         }
         
         static ALWAYS_INLINE uintptr_t rawValue(const JSValue* v)
@@ -290,12 +293,12 @@ namespace KJS {
     {
         ASSERT(isImmediate(v));
         uintptr_t bits = rawValue(v);
-        return
-            (bits & TagBitTypeInteger) ? (bits != TagBitTypeInteger) : // !0 ints
-            (bits == (FullTagTypeBool | ExtendedPayloadBitBoolValue)); // bool true
+        return (bits & TagBitTypeInteger)
+            ? bits != TagBitTypeInteger // !0 ints
+            : bits == (FullTagTypeBool | ExtendedPayloadBitBoolValue); // bool true
     }
 
-    ALWAYS_INLINE uint32_t JSImmediate::toTruncatedUInt32(const JSValue* v)
+    ALWAYS_INLINE uint32_t JSImmediate::getTruncatedUInt32(const JSValue* v)
     {
         ASSERT(isNumber(v));
         return intValue(v);
@@ -376,7 +379,7 @@ namespace KJS {
             return 0;
 
         // Check for data loss from conversion to int.
-        if ((intVal != d) || (!intVal && signbit(d)))
+        if (intVal != d || (!intVal && signbit(d)))
             return 0;
 
         return makeInt(intVal);
@@ -417,19 +420,6 @@ namespace KJS {
         return getUInt32(v, i);
     }
 
-    ALWAYS_INLINE JSType JSImmediate::type(const JSValue* v)
-    {
-        ASSERT(isImmediate(v));
-        
-        if (isNumber(v))
-            return NumberType;
-        if (isBoolean(v))
-            return BooleanType;
-        if (v != undefinedImmediate())
-            return NullType;
-        return UndefinedType;
-    }
-
     ALWAYS_INLINE JSValue* jsUndefined()
     {
         return JSImmediate::undefinedImmediate();
index 6d770ac..42b4534 100644 (file)
@@ -37,7 +37,7 @@ namespace KJS {
 ASSERT_CLASS_FITS_IN_CELL(JSNotAnObject);
 
 // JSValue methods
-JSValue* JSNotAnObject::toPrimitive(ExecState* exec, JSType) const
+JSValue* JSNotAnObject::toPrimitive(ExecState* exec, PreferredPrimitiveType) const
 {
     UNUSED_PARAM(exec);
     ASSERT(exec->hadException() && exec->exception() == m_exception);
index 133f2d7..c52dcf5 100644 (file)
@@ -57,7 +57,7 @@ namespace KJS {
 
      private:
         // JSValue methods
-        virtual JSValue* toPrimitive(ExecState*, JSType preferredType = UnspecifiedType) const;
+        virtual JSValue* toPrimitive(ExecState*, PreferredPrimitiveType) const;
         virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue*&);
         virtual bool toBoolean(ExecState*) const;
         virtual double toNumber(ExecState*) const;
index 144be1c..cab664b 100644 (file)
 #include "config.h"
 #include "JSNumberCell.h"
 
-#include "JSType.h"
 #include "NumberObject.h"
 #include "ustring.h"
 
 namespace KJS {
 
-JSType JSNumberCell::type() const
-{
-    return NumberType;
-}
-
-JSValue* JSNumberCell::toPrimitive(ExecState*, JSType) const
+JSValue* JSNumberCell::toPrimitive(ExecState*, PreferredPrimitiveType) const
 {
     return const_cast<JSNumberCell*>(this);
 }
index e9b00a0..bd1df68 100644 (file)
@@ -46,9 +46,7 @@ namespace KJS {
     public:
         double value() const { return m_value; }
 
-        virtual JSType type() const;
-
-        virtual JSValue* toPrimitive(ExecState*, JSType preferred = UnspecifiedType) const;
+        virtual JSValue* toPrimitive(ExecState*, PreferredPrimitiveType) const;
         virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue*& value);
         virtual bool toBoolean(ExecState*) const;
         virtual double toNumber(ExecState*) const;
@@ -58,8 +56,9 @@ namespace KJS {
         virtual UString toThisString(ExecState*) const;
         virtual JSObject* toThisObject(ExecState*) const;
         virtual JSValue* getJSNumber();
-        int32_t fastToInt32() const;
-        uint32_t fastToUInt32() const;
+
+        int32_t toInt32() const;
+        uint32_t toUInt32() const;
 
         void* operator new(size_t size, ExecState* exec)
         {
@@ -148,7 +147,7 @@ namespace KJS {
         return JSImmediate::isImmediate(this) ? JSImmediate::toDouble(this) : static_cast<const JSNumberCell*>(this)->value();
     }
 
-    inline int32_t JSNumberCell::fastToInt32() const
+    inline int32_t JSNumberCell::toInt32() const
     {
         if (m_value >= -2147483648.0 && m_value < 2147483648.0)
             return static_cast<int32_t>(m_value);
@@ -156,7 +155,7 @@ namespace KJS {
         return JSValue::toInt32SlowCase(m_value, scratch);
     }
 
-    inline uint32_t JSNumberCell::fastToUInt32() const
+    inline uint32_t JSNumberCell::toUInt32() const
     {
         if (m_value >= 0.0 && m_value < 4294967296.0)
             return static_cast<uint32_t>(m_value);
index c309c21..50c253f 100644 (file)
@@ -67,11 +67,6 @@ void JSObject::mark()
 #endif
 }
 
-JSType JSObject::type() const
-{
-    return ObjectType;
-}
-
 UString JSObject::className() const
 {
     const ClassInfo* info = classInfo();
@@ -234,7 +229,7 @@ static ALWAYS_INLINE JSValue* callDefaultValueFunction(ExecState* exec, const JS
         return exec->exception();
 
     JSValue* result = call(exec, function, callType, callData, const_cast<JSObject*>(object), exec->emptyList());
-    ASSERT(result->type() != GetterSetterType);
+    ASSERT(!result->isGetterSetter());
     if (exec->hadException())
         return exec->exception();
     if (result->isObject())
@@ -244,16 +239,16 @@ static ALWAYS_INLINE JSValue* callDefaultValueFunction(ExecState* exec, const JS
 
 bool JSObject::getPrimitiveNumber(ExecState* exec, double& number, JSValue*& result)
 {
-    result = defaultValue(exec, NumberType);
+    result = defaultValue(exec, PreferNumber);
     number = result->toNumber(exec);
     return !result->isString();
 }
 
 // ECMA 8.6.2.6
-JSValue* JSObject::defaultValue(ExecState* exec, JSType hint) const
+JSValue* JSObject::defaultValue(ExecState* exec, PreferredPrimitiveType hint) const
 {
     // Must call toString first for Date objects.
-    if ((hint == StringType) || (hint != NumberType && m_prototype == exec->lexicalGlobalObject()->datePrototype())) {
+    if ((hint == PreferString) || (hint != PreferNumber && m_prototype == exec->lexicalGlobalObject()->datePrototype())) {
         if (JSValue* value = callDefaultValueFunction(exec, this, exec->propertyNames().toString))
             return value;
         if (JSValue* value = callDefaultValueFunction(exec, this, exec->propertyNames().valueOf))
@@ -285,7 +280,7 @@ void JSObject::defineGetter(ExecState* exec, const Identifier& propertyName, JSO
 {
     JSValue* object = getDirect(propertyName);
     GetterSetter* getterSetter;
-    if (object && object->type() == GetterSetterType)
+    if (object && object->isGetterSetter())
         getterSetter = static_cast<GetterSetter*>(object);
     else {
         getterSetter = new (exec) GetterSetter;
@@ -300,7 +295,7 @@ void JSObject::defineSetter(ExecState* exec, const Identifier& propertyName, JSO
 {
     JSValue* object = getDirect(propertyName);
     GetterSetter* getterSetter;
-    if (object && object->type() == GetterSetterType)
+    if (object && object->isGetterSetter())
         getterSetter = static_cast<GetterSetter*>(object);
     else {
         getterSetter = new (exec) GetterSetter;
@@ -317,7 +312,7 @@ JSValue* JSObject::lookupGetter(ExecState*, const Identifier& propertyName)
     while (true) {
         JSValue* value = object->getDirect(propertyName);
         if (value) {
-            if (value->type() != GetterSetterType)
+            if (!value->isGetterSetter())
                 return jsUndefined();
             JSObject* functionObject = static_cast<GetterSetter*>(value)->getter();
             if (!functionObject)
@@ -337,7 +332,7 @@ JSValue* JSObject::lookupSetter(ExecState*, const Identifier& propertyName)
     while (true) {
         JSValue* value = object->getDirect(propertyName);
         if (value) {
-            if (value->type() != GetterSetterType)
+            if (!value->isGetterSetter())
                 return jsUndefined();
             JSObject* functionObject = static_cast<GetterSetter*>(value)->setter();
             if (!functionObject)
@@ -428,7 +423,7 @@ bool JSObject::toBoolean(ExecState*) const
 
 double JSObject::toNumber(ExecState* exec) const
 {
-    JSValue* primitive = toPrimitive(exec, NumberType);
+    JSValue* primitive = toPrimitive(exec, PreferNumber);
     if (exec->hadException()) // should be picked up soon in nodes.cpp
         return 0.0;
     return primitive->toNumber(exec);
@@ -436,7 +431,7 @@ double JSObject::toNumber(ExecState* exec) const
 
 UString JSObject::toString(ExecState* exec) const
 {
-    JSValue* primitive = toPrimitive(exec, StringType);
+    JSValue* primitive = toPrimitive(exec, PreferString);
     if (exec->hadException())
         return "";
     return primitive->toString(exec);
@@ -475,6 +470,11 @@ NEVER_INLINE void JSObject::fillGetterPropertySlot(PropertySlot& slot, JSValue**
         slot.setUndefined();
 }
 
+bool JSObject::isObject() const
+{
+    return true;
+}
+
 JSObject* constructEmptyObject(ExecState* exec)
 {
     return new (exec) JSObject(exec->lexicalGlobalObject()->objectPrototype());
index 9cfffca..848a037 100644 (file)
@@ -28,7 +28,6 @@
 #include "CommonIdentifiers.h"
 #include "ExecState.h"
 #include "JSNumberCell.h"
-#include "JSType.h"
 #include "PropertyMap.h"
 #include "PropertySlot.h"
 #include "ScopeChain.h"
@@ -67,9 +66,8 @@ namespace KJS {
         JSObject();
 
         virtual void mark();
-        virtual JSType type() const;
 
-        bool inherits(const ClassInfo* classInfo) const { return isObject(classInfo); } // FIXME: Merge with isObject.
+        bool inherits(const ClassInfo* classInfo) const { return JSCell::isObject(classInfo); }
 
         JSValue* prototype() const;
         void setPrototype(JSValue* prototype);
@@ -100,14 +98,14 @@ namespace KJS {
         virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
         virtual bool deleteProperty(ExecState*, unsigned propertyName);
 
-        virtual JSValue* defaultValue(ExecState*, JSType hint) const;
+        virtual JSValue* defaultValue(ExecState*, PreferredPrimitiveType) const;
 
         virtual bool implementsHasInstance() const;
         virtual bool hasInstance(ExecState*, JSValue*);
 
         virtual void getPropertyNames(ExecState*, PropertyNameArray&);
 
-        virtual JSValue* toPrimitive(ExecState*, JSType preferredType = UnspecifiedType) const;
+        virtual JSValue* toPrimitive(ExecState*, PreferredPrimitiveType = NoPreference) const;
         virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue*& value);
         virtual bool toBoolean(ExecState*) const;
         virtual double toNumber(ExecState*) const;
@@ -154,6 +152,8 @@ namespace KJS {
         bool getOwnPropertySlotForWrite(ExecState*, const Identifier&, PropertySlot&, bool& slotIsWriteable);
 
     private:
+        virtual bool isObject() const;
+
         const HashEntry* findPropertyHashEntry(ExecState*, const Identifier& propertyName) const;
         JSValue* m_prototype;
     };
@@ -257,7 +257,7 @@ inline bool JSObject::getPropertySlot(ExecState* exec, unsigned propertyName, Pr
 ALWAYS_INLINE bool JSObject::getOwnPropertySlotForWrite(ExecState* exec, const Identifier& propertyName, PropertySlot& slot, bool& slotIsWriteable)
 {
     if (JSValue** location = getDirectLocation(propertyName, slotIsWriteable)) {
-        if (m_propertyMap.hasGetterSetterProperties() && location[0]->type() == GetterSetterType) {
+        if (m_propertyMap.hasGetterSetterProperties() && location[0]->isGetterSetter()) {
             slotIsWriteable = false;
             fillGetterPropertySlot(slot, location);
         } else
@@ -281,7 +281,7 @@ ALWAYS_INLINE bool JSObject::getOwnPropertySlotForWrite(ExecState* exec, const I
 ALWAYS_INLINE bool JSObject::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
 {
     if (JSValue** location = getDirectLocation(propertyName)) {
-        if (m_propertyMap.hasGetterSetterProperties() && location[0]->type() == GetterSetterType)
+        if (m_propertyMap.hasGetterSetterProperties() && location[0]->isGetterSetter())
             fillGetterPropertySlot(slot, location);
         else
             slot.setValueSlot(location);
@@ -309,7 +309,7 @@ inline void JSObject::putDirect(ExecState* exec, const Identifier& propertyName,
     m_propertyMap.put(propertyName, jsNumber(exec, value), attr);
 }
 
-inline JSValue* JSObject::toPrimitive(ExecState* exec, JSType preferredType) const
+inline JSValue* JSObject::toPrimitive(ExecState* exec, PreferredPrimitiveType preferredType) const
 {
     return defaultValue(exec, preferredType);
 }
index 91eae46..608d211 100644 (file)
@@ -30,7 +30,7 @@
 
 namespace KJS {
 
-JSValue* JSString::toPrimitive(ExecState*, JSType) const
+JSValue* JSString::toPrimitive(ExecState*, PreferredPrimitiveType) const
 {
     return const_cast<JSString*>(this);
 }
@@ -109,6 +109,12 @@ bool JSString::getOwnPropertySlot(ExecState* exec, unsigned propertyName, Proper
     return JSString::getOwnPropertySlot(exec, Identifier::from(exec, propertyName), slot);
 }
 
+bool JSString::isString() const
+{
+    // FIXME: Change JSCell::isString to a non-virtual implementation like the one in Machine::isJSString.
+    return true;
+}
+
 JSString* jsString(ExecState* exec, const char* s)
 {
     return new (exec) JSString(s ? s : "");
index 03b2b70..f00a88e 100644 (file)
@@ -61,9 +61,9 @@ namespace KJS {
         }
 
     private:
-        virtual JSType type() const { return StringType; }
+        virtual bool isString() const;
 
-        virtual JSValue* toPrimitive(ExecState*, JSType preferred = UnspecifiedType) const;
+        virtual JSValue* toPrimitive(ExecState*, PreferredPrimitiveType) const;
         virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue*& value);
         virtual bool toBoolean(ExecState*) const;
         virtual double toNumber(ExecState*) const;
index 5c5e938..b779d49 100644 (file)
@@ -58,13 +58,13 @@ namespace KJS {
 
     public:
         // Querying the type.
-        JSType type() const;
         bool isUndefined() const;
         bool isNull() const;
         bool isUndefinedOrNull() const;
         bool isBoolean() const;
         bool isNumber() const;
         bool isString() const;
+        bool isGetterSetter() const;
         bool isObject() const;
         bool isObject(const ClassInfo*) const; // FIXME: Merge with inherits.
 
@@ -88,7 +88,8 @@ namespace KJS {
         bool getTruncatedUInt32(uint32_t&) const;
         
         // Basic conversions.
-        JSValue* toPrimitive(ExecState*, JSType preferredType = UnspecifiedType) const;
+        enum PreferredPrimitiveType { NoPreference, PreferNumber, PreferString };
+        JSValue* toPrimitive(ExecState*, PreferredPrimitiveType = NoPreference) const;
         bool getPrimitiveNumber(ExecState*, double& number, JSValue*&);
 
         bool toBoolean(ExecState*) const;
@@ -187,7 +188,7 @@ namespace KJS {
 
     inline bool JSValue::getBoolean() const
     {
-        return JSImmediate::isBoolean(this) ? JSImmediate::toBoolean(this) : false;
+        return this == jsBoolean(true);
     }
 
     ALWAYS_INLINE int32_t JSValue::toInt32(ExecState* exec) const
index b0b0ae5..d19052e 100644 (file)
@@ -1023,35 +1023,15 @@ size_t Heap::protectedObjectCount()
 
 static const char* typeName(JSCell* val)
 {
-    const char* name = "???";
-    switch (val->type()) {
-        case UnspecifiedType:
-            break;
-        case UndefinedType:
-            name = "undefined";
-            break;
-        case NullType:
-            name = "null";
-            break;
-        case BooleanType:
-            name = "boolean";
-            break;
-        case StringType:
-            name = "string";
-            break;
-        case NumberType:
-            name = "number";
-            break;
-        case ObjectType: {
-            const ClassInfo* info = static_cast<JSObject*>(val)->classInfo();
-            name = info ? info->className : "Object";
-            break;
-        }
-        case GetterSetterType:
-            name = "gettersetter";
-            break;
-    }
-    return name;
+    if (val->isString())
+        return "string";
+    if (val->isNumber())
+        return "number";
+    if (val->isGetterSetter())
+        return "gettersetter";
+    ASSERT(val->isObject());
+    const ClassInfo* info = static_cast<JSObject*>(val)->classInfo();
+    return info ? info->className : "Object";
 }
 
 HashCountedSet<const char*>* Heap::protectedObjectTypeCounts()
index aa4c080..93f59eb 100644 (file)
@@ -107,7 +107,8 @@ namespace KJS {
         HashSet<ArgList*>& markListSet() { if (!m_markListSet) m_markListSet = new HashSet<ArgList*>; return *m_markListSet; }
 
         JSGlobalData* globalData() const { return m_globalData; }
-        static bool fastIsNumber(JSCell*);
+        static bool isNumber(JSCell*);
+
     private:
         template <Heap::HeapType heapType> void* heapAllocate(size_t);
         template <Heap::HeapType heapType> size_t sweep();
@@ -217,7 +218,7 @@ namespace KJS {
         Heap::HeapType type;
     };
     
-    inline bool Heap::fastIsNumber(JSCell* cell)
+    inline bool Heap::isNumber(JSCell* cell)
     {
         CollectorBlock* block = Heap::cellBlock(cell);
         return block && block->type == NumberHeap;
index ab118a1..a8ca6fb 100644 (file)
@@ -28,6 +28,7 @@
 
 #include "Error.h"
 #include "JSString.h"
+#include "JSType.h"
 #include "LabelStack.h"
 #include "Opcode.h"
 #include "RegisterID.h"
index 6884843..0e2c5bd 100644 (file)
 namespace KJS {
 
 // ECMA 11.9.3
-bool equal(ExecState *exec, JSValue *v1, JSValue *v2)
+bool equal(ExecState* exec, JSValue* v1, JSValue* v2)
 {
-    JSType t1 = v1->type();
-    JSType t2 = v2->type();
-    
-    if (t1 != t2) {
-        if (t1 == UndefinedType)
-            t1 = NullType;
-        if (t2 == UndefinedType)
-            t2 = NullType;
-        
-        if (t1 == BooleanType)
-            t1 = NumberType;
-        if (t2 == BooleanType)
-            t2 = NumberType;
-        
-        if (t1 == NumberType && t2 == StringType) {
-            // use toNumber
-        } else if (t1 == StringType && t2 == NumberType)
-            t1 = NumberType;
-            // use toNumber
-        else {
-            if ((t1 == StringType || t1 == NumberType) && t2 == ObjectType) {
-                v2 = v2->toPrimitive(exec);
-                if (exec->hadException())
-                    return false;
-                return equal(exec, v1, v2);
-            }
-            if (t1 == NullType && t2 == ObjectType)
-                return static_cast<JSObject *>(v2)->masqueradeAsUndefined();
-            if (t1 == ObjectType && (t2 == StringType || t2 == NumberType)) {
-                v1 = v1->toPrimitive(exec);
-                if (exec->hadException())
-                    return false;
-                return equal(exec, v1, v2);
-            }
-            if (t1 == ObjectType && t2 == NullType)
-                return static_cast<JSObject *>(v1)->masqueradeAsUndefined();
-            if (t1 != t2)
-                return false;
-        }
+startOver:
+    if (JSImmediate::areBothImmediateNumbers(v1, v2))
+        return v1 == v2;
+
+    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 (!v2->isObject())
+            return false;
+        return static_cast<JSObject*>(v2)->masqueradeAsUndefined();
+    }
+
+    if (v2->isUndefinedOrNull()) {
+        if (!v1->isObject())
+            return false;
+        return static_cast<JSObject*>(v1)->masqueradeAsUndefined();
     }
-    
-    if (t1 == UndefinedType || t1 == NullType)
-        return true;
-    
-    if (t1 == NumberType) {
+
+    if (v1->isObject()) {
+        if (v2->isObject())
+            return v1 == v2;
+        JSValue* p1 = v1->toPrimitive(exec);
+        if (exec->hadException())
+            return false;
+        v1 = p1;
+        goto startOver;
+    }
+
+    if (v2->isObject()) {
+        JSValue* p2 = v2->toPrimitive(exec);
+        if (exec->hadException())
+            return false;
+        v2 = p2;
+        goto startOver;
+    }
+
+    if (s1 || s2) {
         double d1 = v1->toNumber(exec);
         double d2 = v2->toNumber(exec);
         return d1 == d2;
     }
-    
-    if (t1 == StringType)
-        return static_cast<JSString*>(v1)->value() == static_cast<JSString*>(v2)->value();
-    
-    if (t1 == BooleanType)
-        return v1->toBoolean(exec) == v2->toBoolean(exec);
-    
-    // types are Object
+
+    if (v1->isBoolean()) {
+        if (v2->isNumber())
+            return v1->getBoolean() == v2->uncheckedGetNumber();
+    } else if (v2->isBoolean()) {
+        if (v1->isNumber())
+            return v1->uncheckedGetNumber() == v2->getBoolean();
+    }
+
     return v1 == v2;
 }
 
 bool strictEqual(JSValue* v1, JSValue* v2)
 {
-    JSType t1 = v1->type();
-    JSType t2 = v2->type();
-    
-    if (t1 != t2)
-        return false;
-
-    if (t1 == NumberType)
-        return v1->getNumber() == v2->getNumber();
-    
-    if (t1 == StringType)
-        return static_cast<JSString*>(v1)->value() == static_cast<JSString*>(v2)->value();
-    
-    return v1 == v2; // covers object, boolean, null, and undefined types
+    if (JSImmediate::isEitherImmediate(v1, v2)) {
+        if (v1 == v2)
+            return true;
+
+        // The reason we can't just return false here is that 0 === -0,
+        // and while the former is an immediate number, the latter is not.
+        if (v1 == JSImmediate::from(0))
+            return !JSImmediate::isImmediate(v2)
+                && static_cast<JSCell*>(v2)->isNumber()
+                && static_cast<JSNumberCell*>(v2)->value() == 0;
+        return v2 == JSImmediate::from(0)
+            && !JSImmediate::isImmediate(v1)
+            && static_cast<JSCell*>(v1)->isNumber()
+            && static_cast<JSNumberCell*>(v1)->value() == 0;
+    }
+
+    if (static_cast<JSCell*>(v1)->isNumber())
+        return static_cast<JSCell*>(v2)->isNumber()
+            && static_cast<JSNumberCell*>(v1)->value() == static_cast<JSNumberCell*>(v2)->value();
+
+    if (static_cast<JSCell*>(v1)->isString())
+        return static_cast<JSCell*>(v2)->isString()
+            && static_cast<JSString*>(v1)->value() == static_cast<JSString*>(v2)->value();
+
+    return v1 == v2;
 }
 
 JSValue* throwOutOfMemoryError(ExecState* exec)
index 08fd849..16bd2c1 100644 (file)
@@ -1,3 +1,18 @@
+2008-08-12  Darin Adler  <darin@apple.com>
+
+        Reviewed by Geoff.
+
+        - eliminate JSValue::type()
+
+        * JSUtils.cpp:
+        (KJSValueToCFTypeInternal): Replaced uses of JSValue::type() with
+        JSValue::is functions.
+        * UserObjectImp.cpp:
+        (UserObjectImp::getOwnPropertySlot): Ditto.
+        (UserObjectImp::toPrimitive): Take PreferredPrimitiveType argument
+        instead of JSType argument.
+        * UserObjectImp.h: Ditto.
+
 2008-08-17  Geoffrey Garen  <ggaren@apple.com>
 
         Reviewed by Cameron Zwarich.
index 6a1a45e..9e7c790 100644 (file)
@@ -200,23 +200,21 @@ CFTypeRef KJSValueToCFTypeInternal(JSValue *inValue, ExecState *exec, ObjectImpL
 
     CFTypeRef result = 0;
 
-    switch (inValue->type())
-    {
-        case BooleanType:
+        if (inValue->isBoolean())
             {
                 result = inValue->toBoolean(exec) ? kCFBooleanTrue : kCFBooleanFalse;
                 RetainCFType(result);
+                return result;
             }
-            break;
 
-        case StringType:
+        if (inValue->isString())
             {
                 UString uString = inValue->toString(exec);
                 result = UStringToCFString(uString);
+                return result;
             }
-            break;
 
-        case NumberType:
+        if (inValue->isNumber())
             {
                 double number1 = inValue->toNumber(exec);
                 double number2 = (double)inValue->toInteger(exec);
@@ -229,10 +227,10 @@ CFTypeRef KJSValueToCFTypeInternal(JSValue *inValue, ExecState *exec, ObjectImpL
                 {
                     result = CFNumberCreate(0, kCFNumberDoubleType, &number1);
                 }
+                return result;
             }
-            break;
 
-        case ObjectType:
+        if (inValue->isObject())
             {
                             if (inValue->isObject(&UserObjectImp::info)) {
                                 UserObjectImp* userObjectImp = static_cast<UserObjectImp *>(inValue);
@@ -342,21 +340,17 @@ CFTypeRef KJSValueToCFTypeInternal(JSValue *inValue, ExecState *exec, ObjectImpL
                         }
                     }
                 }
+                return result;
             }
-            break;
 
-        case NullType:
-        case UndefinedType:
-        case UnspecifiedType:
+    if (inValue->isUndefinedOrNull())
+        {
             result = RetainCFType(GetCFNull());
-            break;
-
-        default:
-            fprintf(stderr, "KJSValueToCFType: wrong value type %d\n", inValue->type());
-            break;
-    }
+            return result;
+        }
 
-    return result;
+    ASSERT_NOT_REACHED();
+    return 0;
 }
 
 CFTypeRef KJSValueToCFType(JSValue *inValue, ExecState *exec)
index 8e0fb3a..6faaa97 100644 (file)
@@ -135,7 +135,7 @@ bool UserObjectImp::getOwnPropertySlot(ExecState *exec, const Identifier& proper
         return true;
     } else {
         JSValue *kjsValue = toPrimitive(exec);
-        if (kjsValue->type() != NullType && kjsValue->type() != UndefinedType) {
+        if (!kjsValue->isUndefinedOrNull()) {
             JSObject *kjsObject = kjsValue->toObject(exec);
             if (kjsObject->getPropertySlot(exec, propertyName, slot))
                 return true;
@@ -163,7 +163,7 @@ JSUserObject* UserObjectImp::GetJSUserObject() const
     return fJSUserObject;
 }
 
-JSValue *UserObjectImp::toPrimitive(ExecState *exec, JSType preferredType) const
+JSValue *UserObjectImp::toPrimitive(ExecState *exec, PreferredPrimitiveType) const
 {
     JSValue *result = jsUndefined();
     JSUserObject* jsObjPtr = KJSValueToJSObject(toObject(exec), exec);
index 738bcb5..e5f2d07 100644 (file)
@@ -50,7 +50,7 @@ public:
     virtual bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&);
     virtual void put(ExecState *exec, const Identifier &propertyName, JSValue *value, int attr = None);
 
-    JSValue *toPrimitive(ExecState *exec, JSType preferredType = UnspecifiedType) const;
+    JSValue* toPrimitive(ExecState*, PreferredPrimitiveType = NoPreference) const;
     virtual bool toBoolean(ExecState *exec) const;
     virtual double toNumber(ExecState *exec) const;
     virtual UString toString(ExecState *exec) const;
index ac63211..7ec3aed 100644 (file)
@@ -1,3 +1,13 @@
+2008-08-12  Darin Adler  <darin@apple.com>
+
+        Reviewed by Geoff.
+
+        - added a test since I had to rewrite the == and === operators
+
+        * fast/js/equality-expected.txt: Added.
+        * fast/js/equality.html: Added.
+        * fast/js/resources/equality.js: Added.
+
 2008-08-18  Dan Bernstein  <mitz@apple.com>
 
         Reviewed by Dave Hyatt.
diff --git a/LayoutTests/fast/js/equality-expected.txt b/LayoutTests/fast/js/equality-expected.txt
new file mode 100644 (file)
index 0000000..fe9e04e
--- /dev/null
@@ -0,0 +1,401 @@
+Test for equality of many combinations types.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS 0 == 0 is true
+PASS 0 == 1 is false
+PASS 0 == 0.1 is false
+PASS 0 == -0 is true
+PASS 0 == "0" is true
+PASS 0 == "1" is false
+PASS 0 == "0.1" is false
+PASS 0 == "-0" is true
+PASS 0 == null is false
+PASS 0 == undefined is false
+PASS 0 == false is true
+PASS 0 == true is false
+PASS 0 == new String("0") is true
+PASS 0 == new Object is false
+PASS 1 == 0 is false
+PASS 1 == 1 is true
+PASS 1 == 0.1 is false
+PASS 1 == -0 is false
+PASS 1 == "0" is false
+PASS 1 == "1" is true
+PASS 1 == "0.1" is false
+PASS 1 == "-0" is false
+PASS 1 == null is false
+PASS 1 == undefined is false
+PASS 1 == false is false
+PASS 1 == true is true
+PASS 1 == new String("0") is false
+PASS 1 == new Object is false
+PASS 0.1 == 0 is false
+PASS 0.1 == 1 is false
+PASS 0.1 == 0.1 is true
+PASS 0.1 == -0 is false
+PASS 0.1 == "0" is false
+PASS 0.1 == "1" is false
+PASS 0.1 == "0.1" is true
+PASS 0.1 == "-0" is false
+PASS 0.1 == null is false
+PASS 0.1 == undefined is false
+PASS 0.1 == false is false
+PASS 0.1 == true is false
+PASS 0.1 == new String("0") is false
+PASS 0.1 == new Object is false
+PASS -0 == 0 is true
+PASS -0 == 1 is false
+PASS -0 == 0.1 is false
+PASS -0 == -0 is true
+PASS -0 == "0" is true
+PASS -0 == "1" is false
+PASS -0 == "0.1" is false
+PASS -0 == "-0" is true
+PASS -0 == null is false
+PASS -0 == undefined is false
+PASS -0 == false is true
+PASS -0 == true is false
+PASS -0 == new String("0") is true
+PASS -0 == new Object is false
+PASS "0" == 0 is true
+PASS "0" == 1 is false
+PASS "0" == 0.1 is false
+PASS "0" == -0 is true
+PASS "0" == "0" is true
+PASS "0" == "1" is false
+PASS "0" == "0.1" is false
+PASS "0" == "-0" is false
+PASS "0" == null is false
+PASS "0" == undefined is false
+PASS "0" == false is true
+PASS "0" == true is false
+PASS "0" == new String("0") is true
+PASS "0" == new Object is false
+PASS "1" == 0 is false
+PASS "1" == 1 is true
+PASS "1" == 0.1 is false
+PASS "1" == -0 is false
+PASS "1" == "0" is false
+PASS "1" == "1" is true
+PASS "1" == "0.1" is false
+PASS "1" == "-0" is false
+PASS "1" == null is false
+PASS "1" == undefined is false
+PASS "1" == false is false
+PASS "1" == true is true
+PASS "1" == new String("0") is false
+PASS "1" == new Object is false
+PASS "0.1" == 0 is false
+PASS "0.1" == 1 is false
+PASS "0.1" == 0.1 is true
+PASS "0.1" == -0 is false
+PASS "0.1" == "0" is false
+PASS "0.1" == "1" is false
+PASS "0.1" == "0.1" is true
+PASS "0.1" == "-0" is false
+PASS "0.1" == null is false
+PASS "0.1" == undefined is false
+PASS "0.1" == false is false
+PASS "0.1" == true is false
+PASS "0.1" == new String("0") is false
+PASS "0.1" == new Object is false
+PASS "-0" == 0 is true
+PASS "-0" == 1 is false
+PASS "-0" == 0.1 is false
+PASS "-0" == -0 is true
+PASS "-0" == "0" is false
+PASS "-0" == "1" is false
+PASS "-0" == "0.1" is false
+PASS "-0" == "-0" is true
+PASS "-0" == null is false
+PASS "-0" == undefined is false
+PASS "-0" == false is true
+PASS "-0" == true is false
+PASS "-0" == new String("0") is false
+PASS "-0" == new Object is false
+PASS null == 0 is false
+PASS null == 1 is false
+PASS null == 0.1 is false
+PASS null == -0 is false
+PASS null == "0" is false
+PASS null == "1" is false
+PASS null == "0.1" is false
+PASS null == "-0" is false
+PASS null == null is true
+PASS null == undefined is true
+PASS null == false is false
+PASS null == true is false
+PASS null == new String("0") is false
+PASS null == new Object is false
+PASS undefined == 0 is false
+PASS undefined == 1 is false
+PASS undefined == 0.1 is false
+PASS undefined == -0 is false
+PASS undefined == "0" is false
+PASS undefined == "1" is false
+PASS undefined == "0.1" is false
+PASS undefined == "-0" is false
+PASS undefined == null is true
+PASS undefined == undefined is true
+PASS undefined == false is false
+PASS undefined == true is false
+PASS undefined == new String("0") is false
+PASS undefined == new Object is false
+PASS false == 0 is true
+PASS false == 1 is false
+PASS false == 0.1 is false
+PASS false == -0 is true
+PASS false == "0" is true
+PASS false == "1" is false
+PASS false == "0.1" is false
+PASS false == "-0" is true
+PASS false == null is false
+PASS false == undefined is false
+PASS false == false is true
+PASS false == true is false
+PASS false == new String("0") is true
+PASS false == new Object is false
+PASS true == 0 is false
+PASS true == 1 is true
+PASS true == 0.1 is false
+PASS true == -0 is false
+PASS true == "0" is false
+PASS true == "1" is true
+PASS true == "0.1" is false
+PASS true == "-0" is false
+PASS true == null is false
+PASS true == undefined is false
+PASS true == false is false
+PASS true == true is true
+PASS true == new String("0") is false
+PASS true == new Object is false
+PASS new String("0") == 0 is true
+PASS new String("0") == 1 is false
+PASS new String("0") == 0.1 is false
+PASS new String("0") == -0 is true
+PASS new String("0") == "0" is true
+PASS new String("0") == "1" is false
+PASS new String("0") == "0.1" is false
+PASS new String("0") == "-0" is false
+PASS new String("0") == null is false
+PASS new String("0") == undefined is false
+PASS new String("0") == false is true
+PASS new String("0") == true is false
+PASS new String("0") == new String("0") is false
+PASS new String("0") == new Object is false
+PASS new Object == 0 is false
+PASS new Object == 1 is false
+PASS new Object == 0.1 is false
+PASS new Object == -0 is false
+PASS new Object == "0" is false
+PASS new Object == "1" is false
+PASS new Object == "0.1" is false
+PASS new Object == "-0" is false
+PASS new Object == null is false
+PASS new Object == undefined is false
+PASS new Object == false is false
+PASS new Object == true is false
+PASS new Object == new String("0") is false
+PASS new Object == new Object is false
+PASS 0 === 0 is true
+PASS 0 === 1 is false
+PASS 0 === 0.1 is false
+PASS 0 === -0 is true
+PASS 0 === "0" is false
+PASS 0 === "1" is false
+PASS 0 === "0.1" is false
+PASS 0 === "-0" is false
+PASS 0 === null is false
+PASS 0 === undefined is false
+PASS 0 === false is false
+PASS 0 === true is false
+PASS 0 === new String("0") is false
+PASS 0 === new Object is false
+PASS 1 === 0 is false
+PASS 1 === 1 is true
+PASS 1 === 0.1 is false
+PASS 1 === -0 is false
+PASS 1 === "0" is false
+PASS 1 === "1" is false
+PASS 1 === "0.1" is false
+PASS 1 === "-0" is false
+PASS 1 === null is false
+PASS 1 === undefined is false
+PASS 1 === false is false
+PASS 1 === true is false
+PASS 1 === new String("0") is false
+PASS 1 === new Object is false
+PASS 0.1 === 0 is false
+PASS 0.1 === 1 is false
+PASS 0.1 === 0.1 is true
+PASS 0.1 === -0 is false
+PASS 0.1 === "0" is false
+PASS 0.1 === "1" is false
+PASS 0.1 === "0.1" is false
+PASS 0.1 === "-0" is false
+PASS 0.1 === null is false
+PASS 0.1 === undefined is false
+PASS 0.1 === false is false
+PASS 0.1 === true is false
+PASS 0.1 === new String("0") is false
+PASS 0.1 === new Object is false
+PASS -0 === 0 is true
+PASS -0 === 1 is false
+PASS -0 === 0.1 is false
+PASS -0 === -0 is true
+PASS -0 === "0" is false
+PASS -0 === "1" is false
+PASS -0 === "0.1" is false
+PASS -0 === "-0" is false
+PASS -0 === null is false
+PASS -0 === undefined is false
+PASS -0 === false is false
+PASS -0 === true is false
+PASS -0 === new String("0") is false
+PASS -0 === new Object is false
+PASS "0" === 0 is false
+PASS "0" === 1 is false
+PASS "0" === 0.1 is false
+PASS "0" === -0 is false
+PASS "0" === "0" is true
+PASS "0" === "1" is false
+PASS "0" === "0.1" is false
+PASS "0" === "-0" is false
+PASS "0" === null is false
+PASS "0" === undefined is false
+PASS "0" === false is false
+PASS "0" === true is false
+PASS "0" === new String("0") is false
+PASS "0" === new Object is false
+PASS "1" === 0 is false
+PASS "1" === 1 is false
+PASS "1" === 0.1 is false
+PASS "1" === -0 is false
+PASS "1" === "0" is false
+PASS "1" === "1" is true
+PASS "1" === "0.1" is false
+PASS "1" === "-0" is false
+PASS "1" === null is false
+PASS "1" === undefined is false
+PASS "1" === false is false
+PASS "1" === true is false
+PASS "1" === new String("0") is false
+PASS "1" === new Object is false
+PASS "0.1" === 0 is false
+PASS "0.1" === 1 is false
+PASS "0.1" === 0.1 is false
+PASS "0.1" === -0 is false
+PASS "0.1" === "0" is false
+PASS "0.1" === "1" is false
+PASS "0.1" === "0.1" is true
+PASS "0.1" === "-0" is false
+PASS "0.1" === null is false
+PASS "0.1" === undefined is false
+PASS "0.1" === false is false
+PASS "0.1" === true is false
+PASS "0.1" === new String("0") is false
+PASS "0.1" === new Object is false
+PASS "-0" === 0 is false
+PASS "-0" === 1 is false
+PASS "-0" === 0.1 is false
+PASS "-0" === -0 is false
+PASS "-0" === "0" is false
+PASS "-0" === "1" is false
+PASS "-0" === "0.1" is false
+PASS "-0" === "-0" is true
+PASS "-0" === null is false
+PASS "-0" === undefined is false
+PASS "-0" === false is false
+PASS "-0" === true is false
+PASS "-0" === new String("0") is false
+PASS "-0" === new Object is false
+PASS null === 0 is false
+PASS null === 1 is false
+PASS null === 0.1 is false
+PASS null === -0 is false
+PASS null === "0" is false
+PASS null === "1" is false
+PASS null === "0.1" is false
+PASS null === "-0" is false
+PASS null === null is true
+PASS null === undefined is false
+PASS null === false is false
+PASS null === true is false
+PASS null === new String("0") is false
+PASS null === new Object is false
+PASS undefined === 0 is false
+PASS undefined === 1 is false
+PASS undefined === 0.1 is false
+PASS undefined === -0 is false
+PASS undefined === "0" is false
+PASS undefined === "1" is false
+PASS undefined === "0.1" is false
+PASS undefined === "-0" is false
+PASS undefined === null is false
+PASS undefined === undefined is true
+PASS undefined === false is false
+PASS undefined === true is false
+PASS undefined === new String("0") is false
+PASS undefined === new Object is false
+PASS false === 0 is false
+PASS false === 1 is false
+PASS false === 0.1 is false
+PASS false === -0 is false
+PASS false === "0" is false
+PASS false === "1" is false
+PASS false === "0.1" is false
+PASS false === "-0" is false
+PASS false === null is false
+PASS false === undefined is false
+PASS false === false is true
+PASS false === true is false
+PASS false === new String("0") is false
+PASS false === new Object is false
+PASS true === 0 is false
+PASS true === 1 is false
+PASS true === 0.1 is false
+PASS true === -0 is false
+PASS true === "0" is false
+PASS true === "1" is false
+PASS true === "0.1" is false
+PASS true === "-0" is false
+PASS true === null is false
+PASS true === undefined is false
+PASS true === false is false
+PASS true === true is true
+PASS true === new String("0") is false
+PASS true === new Object is false
+PASS new String("0") === 0 is false
+PASS new String("0") === 1 is false
+PASS new String("0") === 0.1 is false
+PASS new String("0") === -0 is false
+PASS new String("0") === "0" is false
+PASS new String("0") === "1" is false
+PASS new String("0") === "0.1" is false
+PASS new String("0") === "-0" is false
+PASS new String("0") === null is false
+PASS new String("0") === undefined is false
+PASS new String("0") === false is false
+PASS new String("0") === true is false
+PASS new String("0") === new String("0") is false
+PASS new String("0") === new Object is false
+PASS new Object === 0 is false
+PASS new Object === 1 is false
+PASS new Object === 0.1 is false
+PASS new Object === -0 is false
+PASS new Object === "0" is false
+PASS new Object === "1" is false
+PASS new Object === "0.1" is false
+PASS new Object === "-0" is false
+PASS new Object === null is false
+PASS new Object === undefined is false
+PASS new Object === false is false
+PASS new Object === true is false
+PASS new Object === new String("0") is false
+PASS new Object === new Object is false
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/js/equality.html b/LayoutTests/fast/js/equality.html
new file mode 100644 (file)
index 0000000..e61cd11
--- /dev/null
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<link rel="stylesheet" href="resources/js-test-style.css">
+<script src="resources/js-test-pre.js"></script>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script src="resources/equality.js"></script>
+<script src="resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/fast/js/resources/equality.js b/LayoutTests/fast/js/resources/equality.js
new file mode 100644 (file)
index 0000000..f1c18ea
--- /dev/null
@@ -0,0 +1,56 @@
+description(
+'Test for equality of many combinations types.'
+);
+
+var values = [ '0', '1', '0.1', '-0', '"0"', '"1"', '"0.1"', '"-0"', 'null', 'undefined', 'false', 'true', 'new String("0")', 'new Object' ];
+
+var exceptions = [
+    '"-0" == false',
+    '"0" == false',
+    '"0" == new String("0")',
+    '"1" == true',
+    '-0 == "-0"',
+    '-0 == "0"',
+    '-0 == false',
+    '-0 == new String("0")',
+    '0 == "-0"',
+    '0 == "0"',
+    '0 == -0',
+    '0 == false',
+    '0 == new String("0")',
+    '0 === -0',
+    '0.1 == "0.1"',
+    '1 == "1"',
+    '1 == true',
+    'new Object == new Object',
+    'new Object === new Object',
+    'new String("0") == false',
+    'new String("0") == new String("0")',
+    'new String("0") === new String("0")',
+    'null == undefined',
+];
+
+var exceptionMap = new Object;
+
+var i, j;
+
+for (i = 0; i < exceptions.length; ++i)
+    exceptionMap[exceptions[i]] = 1;
+
+for (i = 0; i < values.length; ++i) {
+    for (j = 0; j < values.length; ++j) {
+        var expression = values[i] + " == " + values[j];
+        var reversed = values[j] + " == " + values[i];
+        shouldBe(expression, ((i == j) ^ (exceptionMap[expression] || exceptionMap[reversed])) ? "true" : "false");
+    }
+}
+
+for (i = 0; i < values.length; ++i) {
+    for (j = 0; j < values.length; ++j) {
+        var expression = values[i] + " === " + values[j];
+        var reversed = values[j] + " === " + values[i];
+        shouldBe(expression, ((i == j) ^ (exceptionMap[expression] || exceptionMap[reversed])) ? "true" : "false");
+    }
+}
+
+var successfullyParsed = true;
index b432bea..86ca85d 100644 (file)
@@ -1,3 +1,60 @@
+2008-08-12  Darin Adler  <darin@apple.com>
+
+        Reviewed by Geoff.
+
+        - eliminate JSValue::type()
+
+        * bridge/c/c_instance.cpp:
+        (KJS::Bindings::CInstance::defaultValue): Take PreferredPrimitiveType
+        argument instead of JSType argument. Removed unneeded code to handle
+        boolean, since that's never passed.
+        * bridge/c/c_instance.h: Ditto.
+
+        * bridge/c/c_utility.cpp:
+        (KJS::Bindings::convertValueToNPVariant): Use JSValue::is functions
+        instead of JSValue::type(). Removed unneeded code to handle
+        "unspecified".
+
+        * bridge/jni/jni_instance.cpp:
+        (JavaInstance::defaultValue): Take PreferredPrimitiveType argument
+        instead of JSType argument. Removed unneeded code to handle boolean.
+        * bridge/jni/jni_instance.h: Ditto.
+
+        * bridge/jni/jni_jsobject.mm:
+        (JavaJSObject::convertValueToJObject): Use JSValue::is functions
+        instead of JSValue::type().
+
+        * bridge/objc/objc_instance.h: Take PreferredPrimitiveType argument
+        instead of JSType argument. Removed unused argument.
+        * bridge/objc/objc_instance.mm:
+        (ObjcInstance::getValueOfUndefinedField): Removed unused argument.
+        (ObjcInstance::defaultValue): Take PreferredPrimitiveType argument
+        instead of JSType argument. Removed unneeded code to handle boolean
+        and another dead code path for unknown types.
+
+        * bridge/objc/objc_runtime.h: Take PreferredPrimitiveType argument
+        instead of JSType argument. Removed override of type() that caused
+        the fallback object to return "UndefinedType" when there is no
+        invokeUndefinedMethodFromWebScript:withArguments: method defined.
+        That didn't accomplish much, since most checks for undefined don't
+        ever call type().
+        * bridge/objc/objc_runtime.mm:
+        (ObjcFallbackObjectImp::defaultValue): Ditto.
+
+        * bridge/qt/qt_instance.cpp:
+        (KJS::Bindings::QtInstance::defaultValue): Take PreferredPrimitiveType
+        argument instead of JSType argument. Removed unneeded code to handle
+        boolean.
+        * bridge/qt/qt_instance.h: Ditto.
+
+        * bridge/runtime.h:
+        (KJS::Bindings::Instance::getValueOfUndefinedField): Removed
+        unsed argument.
+        * bridge/runtime_object.cpp:
+        (RuntimeObjectImp::defaultValue): Take PreferredPrimitiveType
+        argument instead of JSType argument.
+        * bridge/runtime_object.h: Ditto.
+
 2008-08-18  Maxime Britto  <britto@apple.com>
 
         Reviewed by Adele.
index b854d40..fbd727c 100644 (file)
@@ -129,14 +129,12 @@ JSValue* CInstance::invokeDefaultMethod(ExecState* exec, const ArgList& args)
 }
 
 
-JSValue* CInstance::defaultValue(ExecState* exec, JSType hint) const
+JSValue* CInstance::defaultValue(ExecState* exec, PreferredPrimitiveType hint) const
 {
-    if (hint == StringType)
+    if (hint == JSValue::PreferString)
         return stringValue(exec);
-    if (hint == NumberType)
+    if (hint == JSValue::PreferNumber)
         return numberValue(exec);
-   if (hint == BooleanType)
-        return booleanValue();
     return valueOf(exec);
 }
 
index 97c4179..d7ccdf4 100644 (file)
@@ -51,7 +51,7 @@ public:
     virtual Class *getClass() const;
 
     virtual JSValue* valueOf(ExecState*) const;
-    virtual JSValue* defaultValue(ExecState*, JSType hint) const;
+    virtual JSValue* defaultValue(ExecState*, PreferredPrimitiveType) const;
     
     virtual JSValue *invokeMethod (ExecState *exec, const MethodList &method, const ArgList &args);
     virtual bool supportsInvokeDefaultMethod() const;
index 8127788..d5c980f 100644 (file)
@@ -66,25 +66,21 @@ static String convertUTF8ToUTF16WithLatin1Fallback(const NPUTF8* UTF8Chars, int
 
 // Variant value must be released with NPReleaseVariantValue()
 void convertValueToNPVariant(ExecState* exec, JSValue* value, NPVariant* result)
-{
-    JSType type = value->type();
-    
+{    
     VOID_TO_NPVARIANT(*result);
 
-    if (type == StringType) {
+    if (value->isString()) {
         UString ustring = value->toString(exec);
         CString cstring = ustring.UTF8String();
         NPString string = { (const NPUTF8*)cstring.c_str(), static_cast<uint32_t>(cstring.size()) };
         NPN_InitializeVariantWithStringCopy(result, &string);
-    } else if (type == NumberType) {
+    } else if (value->isNumber()) {
         DOUBLE_TO_NPVARIANT(value->toNumber(exec), *result);
-    } else if (type == BooleanType) {
+    } else if (value->isBoolean()) {
         BOOLEAN_TO_NPVARIANT(value->toBoolean(exec), *result);
-    } else if (type == UnspecifiedType) {
-        VOID_TO_NPVARIANT(*result);
-    } else if (type == NullType) {
+    } else if (value->isNull()) {
         NULL_TO_NPVARIANT(*result);
-    } else if (type == ObjectType) {
+    } else if (value->isObject()) {
         JSObject* object = static_cast<JSObject*>(value);
         if (object->classInfo() == &RuntimeObjectImp::s_info) {
             RuntimeObjectImp* imp = static_cast<RuntimeObjectImp*>(value);
index c051958..1693b4d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2003 Apple Computer, Inc.  All rights reserved.
+ * Copyright (C) 2003, 2008 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -280,24 +280,19 @@ JSValue *JavaInstance::invokeMethod (ExecState *exec, const MethodList &methodLi
     return resultValue;
 }
 
-JSValue* JavaInstance::defaultValue(ExecState* exec, JSType hint) const
+JSValue* JavaInstance::defaultValue(ExecState* exec, PreferredPrimitiveType hint) const
 {
-    if (hint == StringType)
+    if (hint == JSValue::PreferString)
         return stringValue(exec);
-    if (hint == NumberType)
+    if (hint == JSValue::PreferNumber)
         return numberValue(exec);
-    if (hint == BooleanType)
+    JavaClass *aClass = static_cast<JavaClass*>(getClass());
+    if (aClass->isStringClass())
+        return stringValue(exec);
+    if (aClass->isNumberClass())
+        return numberValue(exec);
+    if (aClass->isBooleanClass())
         return booleanValue();
-    if (hint == UnspecifiedType) {
-        JavaClass *aClass = static_cast<JavaClass*>(getClass());
-        if (aClass->isStringClass())
-            return stringValue(exec);
-        if (aClass->isNumberClass())
-            return numberValue(exec);
-        if (aClass->isBooleanClass())
-            return booleanValue();
-    }
-    
     return valueOf(exec);
 }
 
index 965de4d..52e2053 100644 (file)
@@ -78,7 +78,7 @@ public:
     virtual Class *getClass() const;
     
     virtual JSValue* valueOf(ExecState*) const;
-    virtual JSValue* defaultValue(ExecState*, JSType hint) const;
+    virtual JSValue* defaultValue(ExecState*, PreferredPrimitiveType) const;
 
     virtual JSValue* invokeMethod(ExecState* exec, const MethodList& method, const ArgList& args);
 
index 538471f..7bfe7a2 100644 (file)
@@ -490,20 +490,17 @@ jobject JavaJSObject::convertValueToJObject (JSValue *value) const
     // Java instance -> Java instance
     // Everything else -> JavaJSObject
     
-    JSType type = value->type();
-    if (type == NumberType) {
+    if (value->isNumber()) {
         jclass JSObjectClass = env->FindClass ("java/lang/Double");
         jmethodID constructorID = env->GetMethodID (JSObjectClass, "<init>", "(D)V");
         if (constructorID != NULL) {
             result = env->NewObject (JSObjectClass, constructorID, (jdouble)value->toNumber(exec));
         }
-    }
-    else if (type == StringType) {
+    } else if (value->isString()) {
         UString stringValue = value->toString(exec);
         JNIEnv *env = getJNIEnv();
         result = env->NewString ((const jchar *)stringValue.data(), stringValue.size());
-    }
-    else if (type == BooleanType) {
+    } else if (value->isBoolean()) {
         jclass JSObjectClass = env->FindClass ("java/lang/Boolean");
         jmethodID constructorID = env->GetMethodID (JSObjectClass, "<init>", "(Z)V");
         if (constructorID != NULL) {
@@ -514,7 +511,7 @@ jobject JavaJSObject::convertValueToJObject (JSValue *value) const
         // Create a JavaJSObject.
         jlong nativeHandle;
         
-        if (type == ObjectType){
+        if (value->isObject()) {
             JSObject *imp = static_cast<JSObject*>(value);
             
             // We either have a wrapper around a Java instance or a JavaScript
index 9cb3102..db2dec4 100644 (file)
@@ -49,7 +49,7 @@ public:
     virtual Class *getClass() const;
         
     virtual JSValue* valueOf(ExecState*) const;
-    virtual JSValue* defaultValue(ExecState*, JSType hint) const;
+    virtual JSValue* defaultValue(ExecState*, PreferredPrimitiveType) const;
     
     virtual JSValue *invokeMethod(ExecState *exec, const MethodList &method, const ArgList &args);
     virtual bool supportsInvokeDefaultMethod() const;
@@ -58,7 +58,7 @@ public:
     virtual bool supportsSetValueOfUndefinedField();
     virtual void setValueOfUndefinedField(ExecState *exec, const Identifier &property, JSValue *aValue);
     
-    virtual JSValue *getValueOfUndefinedField(ExecState *exec, const Identifier &property, JSType hint) const;
+    virtual JSValue* getValueOfUndefinedField(ExecState*, const Identifier& property) const;
 
     ObjectStructPtr getObject() const { return _instance.get(); }
     
index 79472ab..3b7a7ed 100644 (file)
@@ -318,7 +318,7 @@ void ObjcInstance::setValueOfUndefinedField(ExecState* exec, const Identifier &p
     }
 }
 
-JSValue* ObjcInstance::getValueOfUndefinedField(ExecState* exec, const Identifier& property, JSType) const
+JSValue* ObjcInstance::getValueOfUndefinedField(ExecState* exec, const Identifier& property) const
 {
     JSValue* result = jsUndefined();
     
@@ -343,23 +343,17 @@ JSValue* ObjcInstance::getValueOfUndefinedField(ExecState* exec, const Identifie
     return result;
 }
 
-JSValue* ObjcInstance::defaultValue(ExecState* exec, JSType hint) const
+JSValue* ObjcInstance::defaultValue(ExecState* exec, PreferredPrimitiveType hint) const
 {
-    switch (hint) {
-    case StringType:
+    if (hint == JSValue::PreferString)
         return stringValue(exec);
-    case NumberType:
+    if (hint == JSValue::PreferNumber)
         return numberValue(exec);
-    case BooleanType:
-        return booleanValue();
-    case UnspecifiedType:
-        if ([_instance.get() isKindOfClass:[NSString class]])
-            return stringValue(exec);
-        if ([_instance.get() isKindOfClass:[NSNumber class]])
-            return numberValue(exec);
-    default:
-        return valueOf(exec);
-    }
+    if ([_instance.get() isKindOfClass:[NSString class]])
+        return stringValue(exec);
+    if ([_instance.get() isKindOfClass:[NSNumber class]])
+        return numberValue(exec);
+    return valueOf(exec);
 }
 
 JSValue* ObjcInstance::stringValue(ExecState* exec) const
index fc56bca..95bf51c 100644 (file)
@@ -105,9 +105,8 @@ private:
     virtual void put(ExecState*, const Identifier& propertyName, JSValue*);
     virtual CallType getCallData(CallData&);
     virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
-    virtual JSValue* defaultValue(ExecState*, JSType hint) const;
+    virtual JSValue* defaultValue(ExecState*, PreferredPrimitiveType) const;
 
-    virtual JSType type() const;
     virtual bool toBoolean(ExecState*) const;
 
     virtual const ClassInfo* classInfo() const { return &info; }
index 3ce7980..cf54b30 100644 (file)
@@ -209,16 +209,6 @@ void ObjcFallbackObjectImp::put(ExecState*, const Identifier&, JSValue*)
 {
 }
 
-JSType ObjcFallbackObjectImp::type() const
-{
-    id targetObject = _instance->getObject();
-    
-    if ([targetObject respondsToSelector:@selector(invokeUndefinedMethodFromWebScript:withArguments:)])
-        return ObjectType;
-    
-    return UndefinedType;
-}
-
 static JSValue* callObjCFallbackObject(ExecState* exec, JSObject* function, JSValue* thisValue, const ArgList& args)
 {
     if (!thisValue->isObject(&RuntimeObjectImp::s_info))
@@ -267,9 +257,9 @@ bool ObjcFallbackObjectImp::deleteProperty(ExecState*, const Identifier&)
     return false;
 }
 
-JSValue* ObjcFallbackObjectImp::defaultValue(ExecState* exec, JSType hint) const
+JSValue* ObjcFallbackObjectImp::defaultValue(ExecState* exec, PreferredPrimitiveType) const
 {
-    return _instance->getValueOfUndefinedField(exec, _item, hint);
+    return _instance->getValueOfUndefinedField(exec, _item);
 }
 
 bool ObjcFallbackObjectImp::toBoolean(ExecState *) const
index d7a58cb..fdf11ab 100644 (file)
@@ -285,14 +285,12 @@ JSValue* QtInstance::invokeDefaultMethod(ExecState* exec, const ArgList& args)
         return throwError(exec, TypeError, "not a function");
 }
 
-JSValue* QtInstance::defaultValue(ExecState* exec, JSType hint) const
+JSValue* QtInstance::defaultValue(ExecState* exec, PreferredPrimitiveType hint) const
 {
-    if (hint == StringType)
+    if (hint == PreferString)
         return stringValue(exec);
-    if (hint == NumberType)
+    if (hint == PreferNumber)
         return numberValue(exec);
-    if (hint == BooleanType)
-        return booleanValue();
     return valueOf(exec);
 }
 
index 2ae7d49..cf10595 100644 (file)
@@ -50,7 +50,7 @@ public:
     virtual void end();
 
     virtual JSValue* valueOf(ExecState* exec) const;
-    virtual JSValue* defaultValue(ExecState* exec, JSType hint) const;
+    virtual JSValue* defaultValue(ExecState*, PreferredPrimitiveType) const;
 
     virtual CallType getCallData(CallData&);
 
index 5a5eca8..973bfa8 100644 (file)
@@ -108,7 +108,7 @@ public:
     virtual Class *getClass() const = 0;
     
     virtual JSValue* getValueOfField(ExecState*, const Field*) const;
-    virtual JSValue* getValueOfUndefinedField(ExecState*, const Identifier&, JSType) const { return jsUndefined(); }
+    virtual JSValue* getValueOfUndefinedField(ExecState*, const Identifier&) const { return jsUndefined(); }
     virtual void setValueOfField(ExecState*, const Field*, JSValue*) const;
     virtual bool supportsSetValueOfUndefinedField() { return false; }
     virtual void setValueOfUndefinedField(ExecState*, const Identifier&, JSValue*) {}
@@ -120,7 +120,8 @@ public:
     
     virtual void getPropertyNames(ExecState*, PropertyNameArray&) { }
 
-    virtual JSValue* defaultValue(ExecState*, JSType hint) const = 0;
+    typedef JSValue::PreferredPrimitiveType PreferredPrimitiveType;
+    virtual JSValue* defaultValue(ExecState*, JSValue::PreferredPrimitiveType) const = 0;
     
     virtual JSValue* valueOf(ExecState* exec) const { return jsString(exec, getClass()->name()); }
     
index e713de5..dfd617f 100644 (file)
@@ -179,7 +179,7 @@ bool RuntimeObjectImp::deleteProperty(ExecState*, const Identifier&)
     return false;
 }
 
-JSValue* RuntimeObjectImp::defaultValue(ExecState* exec, JSType hint) const
+JSValue* RuntimeObjectImp::defaultValue(ExecState* exec, PreferredPrimitiveType hint) const
 {
     if (!instance)
         return throwInvalidAccessError(exec);
index 44c8945..b3fb2ff 100644 (file)
@@ -38,8 +38,8 @@ public:
     virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
     virtual void put(ExecState*, const Identifier& propertyName, JSValue*);
     virtual bool deleteProperty(ExecState* , const Identifier& propertyName);
-    virtual JSValue* defaultValue(ExecState*, JSType hint) const;
-    virtual KJS::CallType getCallData(KJS::CallData&);
+    virtual JSValue* defaultValue(ExecState*, PreferredPrimitiveType) const;
+    virtual CallType getCallData(CallData&);
     virtual void getPropertyNames(ExecState*, PropertyNameArray&);
 
     virtual void invalidate();
index 12524b8..c6aeb64 100644 (file)
@@ -1,3 +1,13 @@
+2008-08-12  Darin Adler  <darin@apple.com>
+
+        Reviewed by Geoff.
+
+        - eliminate JSValue::type()
+
+        * WebView/WebView.mm:
+        (aeDescFromJSValue): Rewrite to use the JSValue::is functions instead
+        of a switch on JSValue::type().
+
 2008-08-17  Geoffrey Garen  <ggaren@apple.com>
 
         Reviewed by Cameron Zwarich.
index 9efcb69..9698794 100644 (file)
@@ -3214,73 +3214,56 @@ static WebFrame *incrementFrame(WebFrame *curr, BOOL forward, BOOL wrapFlag)
 static NSAppleEventDescriptor* aeDescFromJSValue(ExecState* exec, JSValue* jsValue)
 {
     NSAppleEventDescriptor* aeDesc = 0;
-    switch (jsValue->type()) {
-        case BooleanType:
-            aeDesc = [NSAppleEventDescriptor descriptorWithBoolean:jsValue->getBoolean()];
-            break;
-        case StringType:
-            aeDesc = [NSAppleEventDescriptor descriptorWithString:String(jsValue->getString())];
-            break;
-        case NumberType: {
-            double value = jsValue->getNumber();
-            int intValue = (int)value;
-            if (value == intValue)
-                aeDesc = [NSAppleEventDescriptor descriptorWithDescriptorType:typeSInt32 bytes:&intValue length:sizeof(intValue)];
-            else
-                aeDesc = [NSAppleEventDescriptor descriptorWithDescriptorType:typeIEEE64BitFloatingPoint bytes:&value length:sizeof(value)];
-            break;
-        }
-        case ObjectType: {
-            JSObject* object = jsValue->getObject();
-            if (object->inherits(&DateInstance::info)) {
-                DateInstance* date = static_cast<DateInstance*>(object);
-                double ms = 0;
-                int tzOffset = 0;
-                if (date->getTime(ms, tzOffset)) {
-                    CFAbsoluteTime utcSeconds = ms / 1000 - kCFAbsoluteTimeIntervalSince1970;
-                    LongDateTime ldt;
-                    if (noErr == UCConvertCFAbsoluteTimeToLongDateTime(utcSeconds, &ldt))
-                        aeDesc = [NSAppleEventDescriptor descriptorWithDescriptorType:typeLongDateTime bytes:&ldt length:sizeof(ldt)];
-                }
-            }
-            else if (object->inherits(&JSArray::info)) {
-                static HashSet<JSObject*> visitedElems;
-                if (!visitedElems.contains(object)) {
-                    visitedElems.add(object);
-                    
-                    JSArray* array = static_cast<JSArray*>(object);
-                    aeDesc = [NSAppleEventDescriptor listDescriptor];
-                    unsigned numItems = array->length();
-                    for (unsigned i = 0; i < numItems; ++i)
-                        [aeDesc insertDescriptor:aeDescFromJSValue(exec, array->get(exec, i)) atIndex:0];
-                    
-                    visitedElems.remove(object);
-                }
+    if (jsValue->isBoolean())
+        return [NSAppleEventDescriptor descriptorWithBoolean:jsValue->getBoolean()];
+    if (jsValue->isString())
+        return [NSAppleEventDescriptor descriptorWithString:String(jsValue->getString())];
+    if (jsValue->isNumber()) {
+        double value = jsValue->getNumber();
+        int intValue = value;
+        if (value == intValue)
+            return [NSAppleEventDescriptor descriptorWithDescriptorType:typeSInt32 bytes:&intValue length:sizeof(intValue)];
+        return [NSAppleEventDescriptor descriptorWithDescriptorType:typeIEEE64BitFloatingPoint bytes:&value length:sizeof(value)];
+    }
+    if (jsValue->isObject()) {
+        JSObject* object = jsValue->getObject();
+        if (object->inherits(&DateInstance::info)) {
+            DateInstance* date = static_cast<DateInstance*>(object);
+            double ms = 0;
+            int tzOffset = 0;
+            if (date->getTime(ms, tzOffset)) {
+                CFAbsoluteTime utcSeconds = ms / 1000 - kCFAbsoluteTimeIntervalSince1970;
+                LongDateTime ldt;
+                if (noErr == UCConvertCFAbsoluteTimeToLongDateTime(utcSeconds, &ldt))
+                    return [NSAppleEventDescriptor descriptorWithDescriptorType:typeLongDateTime bytes:&ldt length:sizeof(ldt)];
             }
-            if (!aeDesc) {
-                JSValue* primitive = object->toPrimitive(exec);
-                if (exec->hadException()) {
-                    exec->clearException();
-                    return [NSAppleEventDescriptor nullDescriptor];
-                }
-                return aeDescFromJSValue(exec, primitive);
+        }
+        else if (object->inherits(&JSArray::info)) {
+            static HashSet<JSObject*> visitedElems;
+            if (!visitedElems.contains(object)) {
+                visitedElems.add(object);
+                
+                JSArray* array = static_cast<JSArray*>(object);
+                aeDesc = [NSAppleEventDescriptor listDescriptor];
+                unsigned numItems = array->length();
+                for (unsigned i = 0; i < numItems; ++i)
+                    [aeDesc insertDescriptor:aeDescFromJSValue(exec, array->get(exec, i)) atIndex:0];
+                
+                visitedElems.remove(object);
+                return aeDesc;
             }
-            break;
         }
-        case UndefinedType:
-            aeDesc = [NSAppleEventDescriptor descriptorWithTypeCode:cMissingValue];
-            break;
-        default:
-            LOG_ERROR("Unknown JavaScript type: %d", jsValue->type());
-            // no break;
-        case UnspecifiedType:
-        case NullType:
-        case GetterSetterType:
-            aeDesc = [NSAppleEventDescriptor nullDescriptor];
-            break;
+        JSValue* primitive = object->toPrimitive(exec);
+        if (exec->hadException()) {
+            exec->clearException();
+            return [NSAppleEventDescriptor nullDescriptor];
+        }
+        return aeDescFromJSValue(exec, primitive);
     }
-    
-    return aeDesc;
+    if (jsValue->isUndefined())
+        return [NSAppleEventDescriptor descriptorWithTypeCode:cMissingValue];
+    ASSERT(jsValue->isNull());
+    return [NSAppleEventDescriptor nullDescriptor];
 }
 
 - (NSAppleEventDescriptor *)aeDescByEvaluatingJavaScriptFromString:(NSString *)script