Changeset 35830 in webkit for trunk/JavaScriptCore/VM/Machine.cpp


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/VM/Machine.cpp

    r35812 r35830  
    9999}
    100100
    101 static bool fastIsNumber(JSValue* value, double& arg) {
     101// FIXME: This operation should be called "getNumber", not "isNumber" (as it is in JSValue.h).
     102// FIXME: There's no need to have a "slow" version of this. All versions should be fast.
     103static bool fastIsNumber(JSValue* value, double& arg)
     104{
    102105    if (JSImmediate::isNumber(value))
    103106        arg = JSImmediate::getTruncatedInt32(value);
    104     else if (Heap::fastIsNumber(static_cast<JSCell*>(value)))
     107    else if (Heap::isNumber(static_cast<JSCell*>(value)))
    105108        arg = static_cast<JSNumberCell*>(value)->value();
    106109    else
     
    109112}
    110113
    111 static bool fastToInt32(JSValue* value, int32_t& arg) {
     114// FIXME: Why doesn't JSValue::toInt32 have the Heap::isNumber optimization?
     115static bool fastToInt32(JSValue* value, int32_t& arg)
     116{
    112117    if (JSImmediate::isNumber(value))
    113118        arg = JSImmediate::getTruncatedInt32(value);
    114     else if (Heap::fastIsNumber(static_cast<JSCell*>(value)))
    115         arg = static_cast<JSNumberCell*>(value)->fastToInt32();
     119    else if (Heap::isNumber(static_cast<JSCell*>(value)))
     120        arg = static_cast<JSNumberCell*>(value)->toInt32();
    116121    else
    117122        return false;
     
    119124}
    120125
    121 static ALWAYS_INLINE bool fastToUInt32(JSValue* value, uint32_t& arg) {
     126static ALWAYS_INLINE bool fastToUInt32(JSValue* value, uint32_t& arg)
     127{
    122128    if (JSImmediate::isNumber(value)) {
    123129        if (JSImmediate::getTruncatedUInt32(value, arg))
     
    126132        arg = JSValue::toUInt32SlowCase(JSImmediate::getTruncatedInt32(value), scratch);
    127133        return true;
    128     } else if (Heap::fastIsNumber(static_cast<JSCell*>(value)))
    129         arg = static_cast<JSNumberCell*>(value)->fastToUInt32();
     134    } else if (Heap::isNumber(static_cast<JSCell*>(value)))
     135        arg = static_cast<JSNumberCell*>(value)->toUInt32();
    130136    else
    131137        return false;
     
    178184{
    179185    // exception for the Date exception in defaultValue()
    180     JSValue* p1 = v1->toPrimitive(exec, UnspecifiedType);
    181     JSValue* p2 = v2->toPrimitive(exec, UnspecifiedType);
     186    JSValue* p1 = v1->toPrimitive(exec);
     187    JSValue* p2 = v2->toPrimitive(exec);
    182188
    183189    if (p1->isString() || p2->isString()) {
     
    204210    double left;
    205211    double right;
    206    
    207212    if (fastIsNumber(v1, left) && fastIsNumber(v2, right))
    208213        return jsNumber(exec, left + right);
    209214   
    210     JSType t1 = v1->type();
    211     JSType t2 = v2->type();
    212     const unsigned bothTypes = (t1 << 3) | t2;
    213     ASSERT(bothTypes != ((NumberType << 3) | NumberType));
    214     if (bothTypes == ((StringType << 3) | StringType)) {
     215    if (v1->isString() && v2->isString()) {
    215216        UString value = static_cast<JSString*>(v1)->value() + static_cast<JSString*>(v2)->value();
    216217        if (value.isNull())
     
    225226static JSValue* jsTypeStringForValue(ExecState* exec, JSValue* v)
    226227{
    227     switch (v->type()) {
    228         case UndefinedType:
     228    if (v->isUndefined())
     229        return jsString(exec, "undefined");
     230    if (v->isBoolean())
     231        return jsString(exec, "boolean");
     232    if (v->isNumber())
     233        return jsString(exec, "number");
     234    if (v->isString())
     235        return jsString(exec, "string");
     236    if (v->isObject()) {
     237        // Return "undefined" for objects that should be treated
     238        // as null when doing comparisons.
     239        if (static_cast<JSObject*>(v)->masqueradeAsUndefined())
    229240            return jsString(exec, "undefined");
    230         case NullType:
    231             return jsString(exec, "object");
    232         case BooleanType:
    233             return jsString(exec, "boolean");
    234         case NumberType:
    235             return jsString(exec, "number");
    236         case StringType:
    237             return jsString(exec, "string");
    238         default:
    239             if (v->isObject()) {
    240                 // Return "undefined" for objects that should be treated
    241                 // as null when doing comparisons.
    242                 if (static_cast<JSObject*>(v)->masqueradeAsUndefined())
    243                     return jsString(exec, "undefined");
    244                 CallData callData;
    245                 if (static_cast<JSObject*>(v)->getCallData(callData) != CallTypeNone)
    246                     return jsString(exec, "function");
    247             }
    248 
    249             return jsString(exec, "object");
    250     }
     241        CallData callData;
     242        if (static_cast<JSObject*>(v)->getCallData(callData) != CallTypeNone)
     243            return jsString(exec, "function");
     244    }
     245    return jsString(exec, "object");
    251246}
    252247
     
    15541549        uint32_t right;
    15551550        if (JSImmediate::areBothImmediateNumbers(val, shift))
    1556             r[dst] = jsNumber(exec, JSImmediate::getTruncatedInt32(val) << (JSImmediate::toTruncatedUInt32(shift) & 0x1f));
     1551            r[dst] = jsNumber(exec, JSImmediate::getTruncatedInt32(val) << (JSImmediate::getTruncatedUInt32(shift) & 0x1f));
    15571552        else if (fastToInt32(val, left) && fastToUInt32(shift, right))
    15581553            r[dst] = jsNumber(exec, left << (right & 0x1f));
     
    22722267        int defaultOffset = (++vPC)->u.operand;
    22732268        JSValue* scrutinee = r[(++vPC)->u.operand].jsValue(exec);
    2274         if (scrutinee->type() != StringType)
     2269        if (!scrutinee->isString())
    22752270            vPC += defaultOffset;
    22762271        else {
     
    22952290        int defaultOffset = (++vPC)->u.operand;
    22962291        JSValue* scrutinee = r[(++vPC)->u.operand].jsValue(exec);
    2297         if (scrutinee->type() != StringType)
     2292        if (!scrutinee->isString())
    22982293            vPC += defaultOffset;
    22992294        else
Note: See TracChangeset for help on using the changeset viewer.