Ignore:
Timestamp:
Aug 18, 2008, 9:39:04 PM (17 years ago)
Author:
Darin Adler
Message:

JavaScriptCore:

2008-08-12 Darin Adler <Darin Adler>

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.
  • 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 Adler>

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 Adler>

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 Adler>

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 Adler>

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.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/kjs/operations.cpp

    r35027 r35830  
    3737
    3838// ECMA 11.9.3
    39 bool equal(ExecState *exec, JSValue *v1, JSValue *v2)
     39bool equal(ExecState* exec, JSValue* v1, JSValue* v2)
    4040{
    41     JSType t1 = v1->type();
    42     JSType t2 = v2->type();
    43    
    44     if (t1 != t2) {
    45         if (t1 == UndefinedType)
    46             t1 = NullType;
    47         if (t2 == UndefinedType)
    48             t2 = NullType;
    49        
    50         if (t1 == BooleanType)
    51             t1 = NumberType;
    52         if (t2 == BooleanType)
    53             t2 = NumberType;
    54        
    55         if (t1 == NumberType && t2 == StringType) {
    56             // use toNumber
    57         } else if (t1 == StringType && t2 == NumberType)
    58             t1 = NumberType;
    59             // use toNumber
    60         else {
    61             if ((t1 == StringType || t1 == NumberType) && t2 == ObjectType) {
    62                 v2 = v2->toPrimitive(exec);
    63                 if (exec->hadException())
    64                     return false;
    65                 return equal(exec, v1, v2);
    66             }
    67             if (t1 == NullType && t2 == ObjectType)
    68                 return static_cast<JSObject *>(v2)->masqueradeAsUndefined();
    69             if (t1 == ObjectType && (t2 == StringType || t2 == NumberType)) {
    70                 v1 = v1->toPrimitive(exec);
    71                 if (exec->hadException())
    72                     return false;
    73                 return equal(exec, v1, v2);
    74             }
    75             if (t1 == ObjectType && t2 == NullType)
    76                 return static_cast<JSObject *>(v1)->masqueradeAsUndefined();
    77             if (t1 != t2)
    78                 return false;
    79         }
     41startOver:
     42    if (JSImmediate::areBothImmediateNumbers(v1, v2))
     43        return v1 == v2;
     44
     45    if (v1->isNumber() && v2->isNumber())
     46        return v1->uncheckedGetNumber() == v2->uncheckedGetNumber();
     47
     48    bool s1 = v1->isString();
     49    bool s2 = v2->isString();
     50    if (s1 && s2)
     51        return static_cast<JSString*>(v1)->value() == static_cast<JSString*>(v2)->value();
     52
     53    if (v1->isUndefinedOrNull()) {
     54        if (v2->isUndefinedOrNull())
     55            return true;
     56        if (!v2->isObject())
     57            return false;
     58        return static_cast<JSObject*>(v2)->masqueradeAsUndefined();
    8059    }
    81    
    82     if (t1 == UndefinedType || t1 == NullType)
    83         return true;
    84    
    85     if (t1 == NumberType) {
     60
     61    if (v2->isUndefinedOrNull()) {
     62        if (!v1->isObject())
     63            return false;
     64        return static_cast<JSObject*>(v1)->masqueradeAsUndefined();
     65    }
     66
     67    if (v1->isObject()) {
     68        if (v2->isObject())
     69            return v1 == v2;
     70        JSValue* p1 = v1->toPrimitive(exec);
     71        if (exec->hadException())
     72            return false;
     73        v1 = p1;
     74        goto startOver;
     75    }
     76
     77    if (v2->isObject()) {
     78        JSValue* p2 = v2->toPrimitive(exec);
     79        if (exec->hadException())
     80            return false;
     81        v2 = p2;
     82        goto startOver;
     83    }
     84
     85    if (s1 || s2) {
    8686        double d1 = v1->toNumber(exec);
    8787        double d2 = v2->toNumber(exec);
    8888        return d1 == d2;
    8989    }
    90    
    91     if (t1 == StringType)
    92         return static_cast<JSString*>(v1)->value() == static_cast<JSString*>(v2)->value();
    93    
    94     if (t1 == BooleanType)
    95         return v1->toBoolean(exec) == v2->toBoolean(exec);
    96    
    97     // types are Object
     90
     91    if (v1->isBoolean()) {
     92        if (v2->isNumber())
     93            return v1->getBoolean() == v2->uncheckedGetNumber();
     94    } else if (v2->isBoolean()) {
     95        if (v1->isNumber())
     96            return v1->uncheckedGetNumber() == v2->getBoolean();
     97    }
     98
    9899    return v1 == v2;
    99100}
     
    101102bool strictEqual(JSValue* v1, JSValue* v2)
    102103{
    103     JSType t1 = v1->type();
    104     JSType t2 = v2->type();
    105    
    106     if (t1 != t2)
    107         return false;
     104    if (JSImmediate::isEitherImmediate(v1, v2)) {
     105        if (v1 == v2)
     106            return true;
    108107
    109     if (t1 == NumberType)
    110         return v1->getNumber() == v2->getNumber();
    111    
    112     if (t1 == StringType)
    113         return static_cast<JSString*>(v1)->value() == static_cast<JSString*>(v2)->value();
    114    
    115     return v1 == v2; // covers object, boolean, null, and undefined types
     108        // The reason we can't just return false here is that 0 === -0,
     109        // and while the former is an immediate number, the latter is not.
     110        if (v1 == JSImmediate::from(0))
     111            return !JSImmediate::isImmediate(v2)
     112                && static_cast<JSCell*>(v2)->isNumber()
     113                && static_cast<JSNumberCell*>(v2)->value() == 0;
     114        return v2 == JSImmediate::from(0)
     115            && !JSImmediate::isImmediate(v1)
     116            && static_cast<JSCell*>(v1)->isNumber()
     117            && static_cast<JSNumberCell*>(v1)->value() == 0;
     118    }
     119
     120    if (static_cast<JSCell*>(v1)->isNumber())
     121        return static_cast<JSCell*>(v2)->isNumber()
     122            && static_cast<JSNumberCell*>(v1)->value() == static_cast<JSNumberCell*>(v2)->value();
     123
     124    if (static_cast<JSCell*>(v1)->isString())
     125        return static_cast<JSCell*>(v2)->isString()
     126            && static_cast<JSString*>(v1)->value() == static_cast<JSString*>(v2)->value();
     127
     128    return v1 == v2;
    116129}
    117130
Note: See TracChangeset for help on using the changeset viewer.