JavaScriptCore:
authordarin@apple.com <darin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 18 Oct 2008 23:08:12 +0000 (23:08 +0000)
committerdarin@apple.com <darin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 18 Oct 2008 23:08:12 +0000 (23:08 +0000)
2008-10-18  Darin Adler  <darin@apple.com>

        Reviewed by Oliver Hunt.

        - first step of https://bugs.webkit.org/show_bug.cgi?id=21732
          improve performance by eliminating JSValue as a base class for JSCell

        Remove casts from JSValue* to derived classes, replacing them with
        calls to inline casting functions. These functions are also a bit
        better than aidrect cast because they also do a runtime assertion.

        Removed use of 0 as for JSValue*, changing call sites to use a
        noValue() function instead.

        Move things needed by classes derived from JSValue out of the class,
        since the classes won't be deriving from JSValue any more soon.

        I did most of these changes by changing JSValue to not be JSValue* any
        more, then fixing a lot of the compilation problems, then rolling out
        the JSValue change.

        1.011x as fast on SunSpider (presumably due to some of the Machine.cpp changes)

        * API/APICast.h: Removed unneeded forward declarations.

        * API/JSCallbackObject.h: Added an asCallbackObject function for casting.
        * API/JSCallbackObjectFunctions.h:
        (JSC::JSCallbackObject::asCallbackObject): Added.
        (JSC::JSCallbackObject::getOwnPropertySlot): Use asObject.
        (JSC::JSCallbackObject::call): Use noValue.
        (JSC::JSCallbackObject::staticValueGetter): Use asCallbackObject.
        (JSC::JSCallbackObject::staticFunctionGetter): Ditto.
        (JSC::JSCallbackObject::callbackGetter): Ditto.

        * JavaScriptCore.exp: Updated.

        * JavaScriptCore.xcodeproj/project.pbxproj: Added RegExpMatchesArray.h.

        * VM/CTI.cpp:
        (JSC::CTI::asInteger): Added. For use casting a JSValue to an integer.
        (JSC::CTI::emitGetArg): Use asInteger.
        (JSC::CTI::emitGetPutArg): Ditto.
        (JSC::CTI::getConstantImmediateNumericArg): Ditto. Also use noValue.
        (JSC::CTI::emitInitRegister): Use asInteger.
        (JSC::CTI::getDeTaggedConstantImmediate): Ditto.
        (JSC::CTI::compileOpCallInitializeCallFrame): Ditto.
        (JSC::CTI::compileOpCall): Ditto.
        (JSC::CTI::compileOpStrictEq): Ditto.
        (JSC::CTI::privateCompileMainPass): Ditto.
        (JSC::CTI::privateCompileGetByIdProto): Ditto.
        (JSC::CTI::privateCompileGetByIdChain): Ditto.
        (JSC::CTI::privateCompilePutByIdTransition): Ditto.
        * VM/CTI.h: Rewrite the ARG-related macros to use C++ casts instead of
        C casts and get rid of some extra parentheses. Addd declaration of
        asInteger.

        * VM/CodeGenerator.cpp:
        (JSC::CodeGenerator::emitEqualityOp): Use asString.
        (JSC::CodeGenerator::emitLoad): Use noValue.
        (JSC::CodeGenerator::findScopedProperty): Change globalObject argument
        to JSObject* instead of JSValue*.
        (JSC::CodeGenerator::emitResolve): Remove unneeded cast.
        (JSC::CodeGenerator::emitGetScopedVar): Use asCell.
        (JSC::CodeGenerator::emitPutScopedVar): Ditto.
        * VM/CodeGenerator.h: Changed out argument of findScopedProperty.
        Also change the JSValueMap to use PtrHash explicitly instead of
        getting it from DefaultHash.

        * VM/JSPropertyNameIterator.cpp:
        (JSC::JSPropertyNameIterator::toPrimitive): Use noValue.
        * VM/JSPropertyNameIterator.h:
        (JSC::JSPropertyNameIterator::next): Ditto.

        * VM/Machine.cpp:
        (JSC::fastIsNumber): Moved isImmediate check here instead of
        checking for 0 inside Heap::isNumber. Use asCell and asNumberCell.
        (JSC::fastToInt32): Ditto.
        (JSC::fastToUInt32): Ditto.
        (JSC::jsLess): Use asString.
        (JSC::jsLessEq): Ditto.
        (JSC::jsAdd): Ditto.
        (JSC::jsTypeStringForValue): Use asObject.
        (JSC::jsIsObjectType): Ditto.
        (JSC::jsIsFunctionType): Ditto.
        (JSC::inlineResolveBase): Use noValue.
        (JSC::Machine::callEval): Use asString. Initialize result to
        undefined, not 0.
        (JSC::Machine::Machine): Remove unneeded casts to JSCell*.
        (JSC::Machine::throwException): Use asObject.
        (JSC::Machine::debug): Remove explicit calls to the DebuggerCallFrame
        constructor.
        (JSC::Machine::checkTimeout): Use noValue.
        (JSC::cachePrototypeChain): Use asObject.
        (JSC::Machine::tryCachePutByID): Use asCell.
        (JSC::Machine::tryCacheGetByID): Use aCell and asObject.
        (JSC::Machine::privateExecute): Use noValue, asCell, asObject, asString,
        asArray, asActivation, asFunction. Changed code that creates call frames
        for host functions to pass 0 for the function pointer -- the call frame
        needs a JSFunction* and a host function object is not one. This was
        caught by the assertions in the casting functions. Also remove some
        unneeded casts in cases where two values are compared.
        (JSC::Machine::retrieveLastCaller): Use noValue.
        (JSC::Machine::tryCTICachePutByID): Use asCell.
        (JSC::Machine::tryCTICacheGetByID): Use aCell and asObject.
        (JSC::setUpThrowTrampolineReturnAddress): Added this function to restore
        the PIC-branch-avoidance that was recently lost.
        (JSC::Machine::cti_op_add): Use asString.
        (JSC::Machine::cti_op_instanceof): Use asCell and asObject.
        (JSC::Machine::cti_op_call_JSFunction): Use asFunction.
        (JSC::Machine::cti_op_call_NotJSFunction): Changed code to pass 0 for
        the function pointer, since we don't have a JSFunction. Use asObject.
        (JSC::Machine::cti_op_tear_off_activation): Use asActivation.
        (JSC::Machine::cti_op_construct_JSConstruct): Use asFunction and asObject.
        (JSC::Machine::cti_op_construct_NotJSConstruct): use asObject.
        (JSC::Machine::cti_op_get_by_val): Use asArray and asString.
        (JSC::Machine::cti_op_resolve_func): Use asPointer; this helps prepare
        us for a situation where JSValue is not a pointer.
        (JSC::Machine::cti_op_put_by_val): Use asArray.
        (JSC::Machine::cti_op_put_by_val_array): Ditto.
        (JSC::Machine::cti_op_resolve_global): Use asGlobalObject.
        (JSC::Machine::cti_op_post_inc): Change VM_CHECK_EXCEPTION_2 to
        VM_CHECK_EXCEPTION_AT_END, since there's no observable work done after
        that point. Also use asPointer.
        (JSC::Machine::cti_op_resolve_with_base): Use asPointer.
        (JSC::Machine::cti_op_post_dec): Change VM_CHECK_EXCEPTION_2 to
        VM_CHECK_EXCEPTION_AT_END, since there's no observable work done after
        that point. Also use asPointer.
        (JSC::Machine::cti_op_call_eval): Use asObject, noValue, and change
        VM_CHECK_EXCEPTION_ARG to VM_THROW_EXCEPTION_AT_END.
        (JSC::Machine::cti_op_throw): Change return value to a JSValue*.
        (JSC::Machine::cti_op_in): Use asObject.
        (JSC::Machine::cti_op_switch_char): Use asString.
        (JSC::Machine::cti_op_switch_string): Ditto.
        (JSC::Machine::cti_op_put_getter): Use asObject.
        (JSC::Machine::cti_op_put_setter): Ditto.
        (JSC::Machine::cti_vm_throw): Change return value to a JSValue*.
        Use noValue.
        * VM/Machine.h: Change return values of both cti_op_throw and
        cti_vm_throw to JSValue*.

        * VM/Register.h: Remove nullJSValue, which is the same thing
        as noValue(). Also removed unneeded definition of JSValue.

        * kjs/ArgList.h: Removed unneeded definition of JSValue.

        * kjs/Arguments.h:
        (JSC::asArguments): Added.

        * kjs/ArrayPrototype.cpp:
        (JSC::getProperty): Use noValue.
        (JSC::arrayProtoFuncToString): Use asArray.
        (JSC::arrayProtoFuncToLocaleString): Ditto.
        (JSC::arrayProtoFuncConcat): Ditto.
        (JSC::arrayProtoFuncPop): Ditto. Also removed unneeded initialization
        of the result, which is set in both sides of the branch.
        (JSC::arrayProtoFuncPush): Ditto.
        (JSC::arrayProtoFuncShift): Removed unneeded initialization
        of the result, which is set in both sides of the branch.
        (JSC::arrayProtoFuncSort): Use asArray.

        * kjs/BooleanObject.h:
        (JSC::asBooleanObject): Added.

        * kjs/BooleanPrototype.cpp:
        (JSC::booleanProtoFuncToString): Use asBooleanObject.
        (JSC::booleanProtoFuncValueOf): Ditto.

        * kjs/CallData.cpp:
        (JSC::call): Use asObject and asFunction.
        * kjs/ConstructData.cpp:
        (JSC::construct): Ditto.

        * kjs/DateConstructor.cpp:
        (JSC::constructDate): Use asDateInstance.

        * kjs/DateInstance.h:
        (JSC::asDateInstance): Added.

        * kjs/DatePrototype.cpp:
        (JSC::dateProtoFuncToString): Use asDateInstance.
        (JSC::dateProtoFuncToUTCString): Ditto.
        (JSC::dateProtoFuncToDateString): Ditto.
        (JSC::dateProtoFuncToTimeString): Ditto.
        (JSC::dateProtoFuncToLocaleString): Ditto.
        (JSC::dateProtoFuncToLocaleDateString): Ditto.
        (JSC::dateProtoFuncToLocaleTimeString): Ditto.
        (JSC::dateProtoFuncValueOf): Ditto.
        (JSC::dateProtoFuncGetTime): Ditto.
        (JSC::dateProtoFuncGetFullYear): Ditto.
        (JSC::dateProtoFuncGetUTCFullYear): Ditto.
        (JSC::dateProtoFuncToGMTString): Ditto.
        (JSC::dateProtoFuncGetMonth): Ditto.
        (JSC::dateProtoFuncGetUTCMonth): Ditto.
        (JSC::dateProtoFuncGetDate): Ditto.
        (JSC::dateProtoFuncGetUTCDate): Ditto.
        (JSC::dateProtoFuncGetDay): Ditto.
        (JSC::dateProtoFuncGetUTCDay): Ditto.
        (JSC::dateProtoFuncGetHours): Ditto.
        (JSC::dateProtoFuncGetUTCHours): Ditto.
        (JSC::dateProtoFuncGetMinutes): Ditto.
        (JSC::dateProtoFuncGetUTCMinutes): Ditto.
        (JSC::dateProtoFuncGetSeconds): Ditto.
        (JSC::dateProtoFuncGetUTCSeconds): Ditto.
        (JSC::dateProtoFuncGetMilliSeconds): Ditto.
        (JSC::dateProtoFuncGetUTCMilliseconds): Ditto.
        (JSC::dateProtoFuncGetTimezoneOffset): Ditto.
        (JSC::dateProtoFuncSetTime): Ditto.
        (JSC::setNewValueFromTimeArgs): Ditto.
        (JSC::setNewValueFromDateArgs): Ditto.
        (JSC::dateProtoFuncSetYear): Ditto.
        (JSC::dateProtoFuncGetYear): Ditto.

        * kjs/DebuggerCallFrame.cpp:
        (JSC::DebuggerCallFrame::thisObject): Use asObject.
        (JSC::DebuggerCallFrame::evaluate): Use noValue.
        * kjs/DebuggerCallFrame.h: Added a constructor that
        takes only a callFrame.

        * kjs/ExecState.h:
        (JSC::ExecState::clearException): Use noValue.

        * kjs/FunctionPrototype.cpp:
        (JSC::functionProtoFuncToString): Use asFunction.
        (JSC::functionProtoFuncApply): Use asArguments and asArray.

        * kjs/GetterSetter.cpp:
        (JSC::GetterSetter::getPrimitiveNumber): Use noValue.

        * kjs/GetterSetter.h:
        (JSC::asGetterSetter): Added.

        * kjs/InternalFunction.cpp:
        (JSC::InternalFunction::name): Use asString.

        * kjs/InternalFunction.h:
        (JSC::asInternalFunction): Added.

        * kjs/JSActivation.cpp:
        (JSC::JSActivation::argumentsGetter): Use asActivation.

        * kjs/JSActivation.h:
        (JSC::asActivation): Added.

        * kjs/JSArray.cpp:
        (JSC::JSArray::putSlowCase): Use noValue.
        (JSC::JSArray::deleteProperty): Ditto.
        (JSC::JSArray::increaseVectorLength): Ditto.
        (JSC::JSArray::setLength): Ditto.
        (JSC::JSArray::pop): Ditto.
        (JSC::JSArray::sort): Ditto.
        (JSC::JSArray::compactForSorting): Ditto.
        * kjs/JSArray.h:
        (JSC::asArray): Added.

        * kjs/JSCell.cpp:
        (JSC::JSCell::getJSNumber): Use noValue.

        * kjs/JSCell.h:
        (JSC::asCell): Added.
        (JSC::JSValue::asCell): Changed to not preserve const.
        Given the wide use of JSValue* and JSCell*, it's not
        really useful to use const.
        (JSC::JSValue::isNumber): Use asValue.
        (JSC::JSValue::isString): Ditto.
        (JSC::JSValue::isGetterSetter): Ditto.
        (JSC::JSValue::isObject): Ditto.
        (JSC::JSValue::getNumber): Ditto.
        (JSC::JSValue::getString): Ditto.
        (JSC::JSValue::getObject): Ditto.
        (JSC::JSValue::getCallData): Ditto.
        (JSC::JSValue::getConstructData): Ditto.
        (JSC::JSValue::getUInt32): Ditto.
        (JSC::JSValue::getTruncatedInt32): Ditto.
        (JSC::JSValue::getTruncatedUInt32): Ditto.
        (JSC::JSValue::mark): Ditto.
        (JSC::JSValue::marked): Ditto.
        (JSC::JSValue::toPrimitive): Ditto.
        (JSC::JSValue::getPrimitiveNumber): Ditto.
        (JSC::JSValue::toBoolean): Ditto.
        (JSC::JSValue::toNumber): Ditto.
        (JSC::JSValue::toString): Ditto.
        (JSC::JSValue::toObject): Ditto.
        (JSC::JSValue::toThisObject): Ditto.
        (JSC::JSValue::needsThisConversion): Ditto.
        (JSC::JSValue::toThisString): Ditto.
        (JSC::JSValue::getJSNumber): Ditto.

        * kjs/JSFunction.cpp:
        (JSC::JSFunction::argumentsGetter): Use asFunction.
        (JSC::JSFunction::callerGetter): Ditto.
        (JSC::JSFunction::lengthGetter): Ditto.
        (JSC::JSFunction::construct): Use asObject.

        * kjs/JSFunction.h:
        (JSC::asFunction): Added.

        * kjs/JSGlobalObject.cpp:
        (JSC::lastInPrototypeChain): Use asObject.

        * kjs/JSGlobalObject.h:
        (JSC::asGlobalObject): Added.
        (JSC::ScopeChainNode::globalObject): Use asGlobalObject.

        * kjs/JSImmediate.h: Added noValue, asPointer, and makeValue
        functions. Use rawValue, makeValue, and noValue consistently
        instead of doing reinterpret_cast in various functions.

        * kjs/JSNumberCell.h:
        (JSC::asNumberCell): Added.
        (JSC::JSValue::uncheckedGetNumber): Use asValue and asNumberCell.
        (JSC::JSValue::toJSNumber): Use asValue.

        * kjs/JSObject.cpp:
        (JSC::JSObject::put): Use asObject and asGetterSetter.
        (JSC::callDefaultValueFunction): Use noValue.
        (JSC::JSObject::defineGetter): Use asGetterSetter.
        (JSC::JSObject::defineSetter): Ditto.
        (JSC::JSObject::lookupGetter): Ditto. Also use asObject.
        (JSC::JSObject::lookupSetter): Ditto.
        (JSC::JSObject::hasInstance): Use asObject.
        (JSC::JSObject::fillGetterPropertySlot): Use asGetterSetter.

        * kjs/JSObject.h:
        (JSC::JSObject::getDirect): Use noValue.
        (JSC::asObject): Added.
        (JSC::JSValue::isObject): Use asValue.
        (JSC::JSObject::get): Removed unneeded const_cast.
        (JSC::JSObject::getPropertySlot): Use asObject.
        (JSC::JSValue::get): Removed unneeded const_cast.
        Use asValue, asCell, and asObject.
        (JSC::JSValue::put): Ditto.
        (JSC::JSObject::allocatePropertyStorageInline): Fixed spelling
        of "oldPropertStorage".

        * kjs/JSString.cpp:
        (JSC::JSString::getOwnPropertySlot): Use asObject.

        * kjs/JSString.h:
        (JSC::asString): Added.
        (JSC::JSValue::toThisJSString): Use asValue.

        * kjs/JSValue.h: Make PreferredPrimitiveType a top level enum
        instead of a member of JSValue. Added an asValue function that
        returns this. Removed overload of asCell for const. Use asValue
        instead of getting right at this.

        * kjs/ObjectPrototype.cpp:
        (JSC::objectProtoFuncIsPrototypeOf): Use asObject.
        (JSC::objectProtoFuncDefineGetter): Ditto.
        (JSC::objectProtoFuncDefineSetter): Ditto.

        * kjs/PropertySlot.h:
        (JSC::PropertySlot::PropertySlot): Take a const JSValue* so the
        callers don't have to worry about const.
        (JSC::PropertySlot::clearBase): Use noValue.
        (JSC::PropertySlot::clearValue): Ditto.

        * kjs/RegExpConstructor.cpp:
        (JSC::regExpConstructorDollar1): Use asRegExpConstructor.
        (JSC::regExpConstructorDollar2): Ditto.
        (JSC::regExpConstructorDollar3): Ditto.
        (JSC::regExpConstructorDollar4): Ditto.
        (JSC::regExpConstructorDollar5): Ditto.
        (JSC::regExpConstructorDollar6): Ditto.
        (JSC::regExpConstructorDollar7): Ditto.
        (JSC::regExpConstructorDollar8): Ditto.
        (JSC::regExpConstructorDollar9): Ditto.
        (JSC::regExpConstructorInput): Ditto.
        (JSC::regExpConstructorMultiline): Ditto.
        (JSC::regExpConstructorLastMatch): Ditto.
        (JSC::regExpConstructorLastParen): Ditto.
        (JSC::regExpConstructorLeftContext): Ditto.
        (JSC::regExpConstructorRightContext): Ditto.
        (JSC::setRegExpConstructorInput): Ditto.
        (JSC::setRegExpConstructorMultiline): Ditto.
        (JSC::constructRegExp): Use asObject.

        * kjs/RegExpConstructor.h:
        (JSC::asRegExpConstructor): Added.

        * kjs/RegExpObject.cpp:
        (JSC::regExpObjectGlobal): Use asRegExpObject.
        (JSC::regExpObjectIgnoreCase): Ditto.
        (JSC::regExpObjectMultiline): Ditto.
        (JSC::regExpObjectSource): Ditto.
        (JSC::regExpObjectLastIndex): Ditto.
        (JSC::setRegExpObjectLastIndex): Ditto.
        (JSC::callRegExpObject): Ditto.

        * kjs/RegExpObject.h:
        (JSC::asRegExpObject): Added.

        * kjs/RegExpPrototype.cpp:
        (JSC::regExpProtoFuncTest): Use asRegExpObject.
        (JSC::regExpProtoFuncExec): Ditto.
        (JSC::regExpProtoFuncCompile): Ditto.
        (JSC::regExpProtoFuncToString): Ditto.

        * kjs/StringObject.h:
        (JSC::StringObject::internalValue): Use asString.
        (JSC::asStringObject): Added.

        * kjs/StringPrototype.cpp:
        (JSC::stringProtoFuncReplace): Use asRegExpObject.
        (JSC::stringProtoFuncToString): Ue asStringObject.
        (JSC::stringProtoFuncMatch): Use asRegExpObject.
        (JSC::stringProtoFuncSearch): Ditto.
        (JSC::stringProtoFuncSplit): Ditto.

        * kjs/StructureID.cpp:
        (JSC::StructureID::getEnumerablePropertyNames): Use asObject.
        (JSC::StructureID::createCachedPrototypeChain): Ditto.
        (JSC::StructureIDChain::StructureIDChain): Use asCell and asObject.

        * kjs/collector.h:
        (JSC::Heap::isNumber): Removed null handling. This can only be called
        on valid cells.
        (JSC::Heap::cellBlock): Removed overload for const and non-const.
        Whether the JSCell* is const or not really should have no effect on
        whether you can modify the collector block it's in.

        * kjs/interpreter.cpp:
        (JSC::Interpreter::evaluate): Use noValue and noObject.

        * kjs/nodes.cpp:
        (JSC::FunctionCallResolveNode::emitCode): Use JSObject for the global
        object rather than JSValue.
        (JSC::PostfixResolveNode::emitCode): Ditto.
        (JSC::PrefixResolveNode::emitCode): Ditto.
        (JSC::ReadModifyResolveNode::emitCode): Ditto.
        (JSC::AssignResolveNode::emitCode): Ditto.

        * kjs/operations.h:
        (JSC::equalSlowCaseInline): Use asString, asCell, asNumberCell,
        (JSC::strictEqualSlowCaseInline): Ditto.

WebCore:

2008-10-18  Darin Adler  <darin@apple.com>

        Reviewed by Oliver Hunt.

        - first step of https://bugs.webkit.org/show_bug.cgi?id=21732
          improve performance by eliminating JSValue as a base class for JSCell

        Update for change to make PreferredPrimitiveType no longer
        a member of JSValue.

        * bridge/c/c_instance.cpp:
        (JSC::Bindings::CInstance::defaultValue): Removed JSValue:: prefix.
        * bridge/jni/jni_instance.cpp:
        (JavaInstance::defaultValue): Ditto.
        * bridge/objc/objc_instance.mm:
        (ObjcInstance::defaultValue): Ditto.
        * bridge/qt/qt_instance.cpp:
        (JSC::Bindings::QtInstance::defaultValue): Ditto.
        * bridge/runtime.h: Ditto. Also removed typedef.

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

70 files changed:
JavaScriptCore/API/APICast.h
JavaScriptCore/API/JSCallbackObject.h
JavaScriptCore/API/JSCallbackObjectFunctions.h
JavaScriptCore/ChangeLog
JavaScriptCore/JavaScriptCore.exp
JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
JavaScriptCore/VM/CTI.cpp
JavaScriptCore/VM/CTI.h
JavaScriptCore/VM/CodeGenerator.cpp
JavaScriptCore/VM/CodeGenerator.h
JavaScriptCore/VM/JSPropertyNameIterator.cpp
JavaScriptCore/VM/JSPropertyNameIterator.h
JavaScriptCore/VM/Machine.cpp
JavaScriptCore/VM/Machine.h
JavaScriptCore/VM/Register.h
JavaScriptCore/kjs/ArgList.h
JavaScriptCore/kjs/Arguments.h
JavaScriptCore/kjs/ArrayPrototype.cpp
JavaScriptCore/kjs/BooleanObject.h
JavaScriptCore/kjs/BooleanPrototype.cpp
JavaScriptCore/kjs/CallData.cpp
JavaScriptCore/kjs/ConstructData.cpp
JavaScriptCore/kjs/DateConstructor.cpp
JavaScriptCore/kjs/DateInstance.h
JavaScriptCore/kjs/DatePrototype.cpp
JavaScriptCore/kjs/DebuggerCallFrame.cpp
JavaScriptCore/kjs/DebuggerCallFrame.h
JavaScriptCore/kjs/ExecState.h
JavaScriptCore/kjs/FunctionPrototype.cpp
JavaScriptCore/kjs/GetterSetter.cpp
JavaScriptCore/kjs/GetterSetter.h
JavaScriptCore/kjs/InternalFunction.cpp
JavaScriptCore/kjs/InternalFunction.h
JavaScriptCore/kjs/JSActivation.cpp
JavaScriptCore/kjs/JSActivation.h
JavaScriptCore/kjs/JSArray.cpp
JavaScriptCore/kjs/JSArray.h
JavaScriptCore/kjs/JSCell.cpp
JavaScriptCore/kjs/JSCell.h
JavaScriptCore/kjs/JSFunction.cpp
JavaScriptCore/kjs/JSFunction.h
JavaScriptCore/kjs/JSGlobalObject.cpp
JavaScriptCore/kjs/JSGlobalObject.h
JavaScriptCore/kjs/JSImmediate.h
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/ObjectPrototype.cpp
JavaScriptCore/kjs/PropertySlot.h
JavaScriptCore/kjs/RegExpConstructor.cpp
JavaScriptCore/kjs/RegExpConstructor.h
JavaScriptCore/kjs/RegExpObject.cpp
JavaScriptCore/kjs/RegExpObject.h
JavaScriptCore/kjs/RegExpPrototype.cpp
JavaScriptCore/kjs/StringObject.h
JavaScriptCore/kjs/StringPrototype.cpp
JavaScriptCore/kjs/StructureID.cpp
JavaScriptCore/kjs/collector.h
JavaScriptCore/kjs/interpreter.cpp
JavaScriptCore/kjs/nodes.cpp
JavaScriptCore/kjs/operations.h
WebCore/ChangeLog
WebCore/bridge/c/c_instance.cpp
WebCore/bridge/jni/jni_instance.cpp
WebCore/bridge/objc/objc_instance.mm
WebCore/bridge/qt/qt_instance.cpp
WebCore/bridge/runtime.h

index e975254..ecd524c 100644 (file)
 #include "ustring.h"
 #include "ExecState.h"
 
-namespace JSC {
-    class ExecState;
-    class JSValue;
-    class JSObject;
-    class PropertyNameArray;
-}
-
 typedef const struct OpaqueJSContextGroup* JSContextGroupRef;
 typedef const struct OpaqueJSContext* JSContextRef;
 typedef struct OpaqueJSContext* JSGlobalContextRef;
index 7f52c5f..1c6fabc 100644 (file)
@@ -77,6 +77,8 @@ private:
 
     void init(ExecState*);
  
+    static JSCallbackObject* asCallbackObject(JSValue*);
     static JSValue* call(ExecState*, JSObject* functionObject, JSValue* thisValue, const ArgList&);
     static JSObject* construct(ExecState*, JSObject* constructor, const ArgList&);
    
index c95db24..f2059ac 100644 (file)
 namespace JSC {
 
 template <class Base>
+inline JSCallbackObject<Base>* JSCallbackObject<Base>::asCallbackObject(JSValue* value)
+{
+    ASSERT(asObject(value)->inherits(&info));
+    return static_cast<JSCallbackObject*>(asObject(value));
+}
+
+template <class Base>
 JSCallbackObject<Base>::JSCallbackObject(ExecState* exec, PassRefPtr<StructureID> structure, JSClassRef jsClass, void* data)
     : Base(structure)
     , m_callbackObjectData(new JSCallbackObjectData(data, jsClass))
@@ -123,7 +130,7 @@ bool JSCallbackObject<Base>::getOwnPropertySlot(ExecState* exec, const Identifie
                 // cache the value so we don't have to compute it again
                 // FIXME: This violates the PropertySlot design a little bit.
                 // We should either use this optimization everywhere, or nowhere.
-                slot.setCustom(reinterpret_cast<JSObject*>(toJS(value)), cachedValueGetter);
+                slot.setCustom(asObject(toJS(value)), cachedValueGetter);
                 return true;
             }
         }
@@ -318,7 +325,7 @@ JSValue* JSCallbackObject<Base>::call(ExecState* exec, JSObject* functionObject,
     }
     
     ASSERT_NOT_REACHED(); // getCallData should prevent us from reaching here
-    return 0;
+    return noValue();
 }
 
 template <class Base>
@@ -433,8 +440,7 @@ JSValue* JSCallbackObject<Base>::cachedValueGetter(ExecState*, const Identifier&
 template <class Base>
 JSValue* JSCallbackObject<Base>::staticValueGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
 {
-    ASSERT(slot.slotBase()->isObject(&JSCallbackObject::info));
-    JSCallbackObject* thisObj = static_cast<JSCallbackObject*>(slot.slotBase());
+    JSCallbackObject* thisObj = asCallbackObject(slot.slotBase());
     
     JSObjectRef thisRef = toRef(thisObj);
     RefPtr<OpaqueJSString> propertyNameRef;
@@ -456,8 +462,7 @@ JSValue* JSCallbackObject<Base>::staticValueGetter(ExecState* exec, const Identi
 template <class Base>
 JSValue* JSCallbackObject<Base>::staticFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
 {
-    ASSERT(slot.slotBase()->isObject(&JSCallbackObject::info));
-    JSCallbackObject* thisObj = static_cast<JSCallbackObject*>(slot.slotBase());
+    JSCallbackObject* thisObj = asCallbackObject(slot.slotBase());
     
     // Check for cached or override property.
     PropertySlot slot2(thisObj);
@@ -482,8 +487,7 @@ JSValue* JSCallbackObject<Base>::staticFunctionGetter(ExecState* exec, const Ide
 template <class Base>
 JSValue* JSCallbackObject<Base>::callbackGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
 {
-    ASSERT(slot.slotBase()->isObject(&JSCallbackObject::info));
-    JSCallbackObject* thisObj = static_cast<JSCallbackObject*>(slot.slotBase());
+    JSCallbackObject* thisObj = asCallbackObject(slot.slotBase());
     
     JSObjectRef thisRef = toRef(thisObj);
     RefPtr<OpaqueJSString> propertyNameRef;
index 7962ce5..7662f2d 100644 (file)
@@ -1,3 +1,439 @@
+2008-10-18  Darin Adler  <darin@apple.com>
+
+        Reviewed by Oliver Hunt.
+
+        - first step of https://bugs.webkit.org/show_bug.cgi?id=21732
+          improve performance by eliminating JSValue as a base class for JSCell
+
+        Remove casts from JSValue* to derived classes, replacing them with
+        calls to inline casting functions. These functions are also a bit
+        better than aidrect cast because they also do a runtime assertion.
+
+        Removed use of 0 as for JSValue*, changing call sites to use a
+        noValue() function instead.
+
+        Move things needed by classes derived from JSValue out of the class,
+        since the classes won't be deriving from JSValue any more soon.
+
+        I did most of these changes by changing JSValue to not be JSValue* any
+        more, then fixing a lot of the compilation problems, then rolling out
+        the JSValue change.
+
+        1.011x as fast on SunSpider (presumably due to some of the Machine.cpp changes)
+
+        * API/APICast.h: Removed unneeded forward declarations.
+
+        * API/JSCallbackObject.h: Added an asCallbackObject function for casting.
+        * API/JSCallbackObjectFunctions.h:
+        (JSC::JSCallbackObject::asCallbackObject): Added.
+        (JSC::JSCallbackObject::getOwnPropertySlot): Use asObject.
+        (JSC::JSCallbackObject::call): Use noValue.
+        (JSC::JSCallbackObject::staticValueGetter): Use asCallbackObject.
+        (JSC::JSCallbackObject::staticFunctionGetter): Ditto.
+        (JSC::JSCallbackObject::callbackGetter): Ditto.
+
+        * JavaScriptCore.exp: Updated.
+
+        * JavaScriptCore.xcodeproj/project.pbxproj: Added RegExpMatchesArray.h.
+
+        * VM/CTI.cpp:
+        (JSC::CTI::asInteger): Added. For use casting a JSValue to an integer.
+        (JSC::CTI::emitGetArg): Use asInteger.
+        (JSC::CTI::emitGetPutArg): Ditto.
+        (JSC::CTI::getConstantImmediateNumericArg): Ditto. Also use noValue.
+        (JSC::CTI::emitInitRegister): Use asInteger.
+        (JSC::CTI::getDeTaggedConstantImmediate): Ditto.
+        (JSC::CTI::compileOpCallInitializeCallFrame): Ditto.
+        (JSC::CTI::compileOpCall): Ditto.
+        (JSC::CTI::compileOpStrictEq): Ditto.
+        (JSC::CTI::privateCompileMainPass): Ditto.
+        (JSC::CTI::privateCompileGetByIdProto): Ditto.
+        (JSC::CTI::privateCompileGetByIdChain): Ditto.
+        (JSC::CTI::privateCompilePutByIdTransition): Ditto.
+        * VM/CTI.h: Rewrite the ARG-related macros to use C++ casts instead of
+        C casts and get rid of some extra parentheses. Addd declaration of
+        asInteger.
+
+        * VM/CodeGenerator.cpp:
+        (JSC::CodeGenerator::emitEqualityOp): Use asString.
+        (JSC::CodeGenerator::emitLoad): Use noValue.
+        (JSC::CodeGenerator::findScopedProperty): Change globalObject argument
+        to JSObject* instead of JSValue*.
+        (JSC::CodeGenerator::emitResolve): Remove unneeded cast.
+        (JSC::CodeGenerator::emitGetScopedVar): Use asCell.
+        (JSC::CodeGenerator::emitPutScopedVar): Ditto.
+        * VM/CodeGenerator.h: Changed out argument of findScopedProperty.
+        Also change the JSValueMap to use PtrHash explicitly instead of
+        getting it from DefaultHash.
+
+        * VM/JSPropertyNameIterator.cpp:
+        (JSC::JSPropertyNameIterator::toPrimitive): Use noValue.
+        * VM/JSPropertyNameIterator.h:
+        (JSC::JSPropertyNameIterator::next): Ditto.
+
+        * VM/Machine.cpp:
+        (JSC::fastIsNumber): Moved isImmediate check here instead of
+        checking for 0 inside Heap::isNumber. Use asCell and asNumberCell.
+        (JSC::fastToInt32): Ditto.
+        (JSC::fastToUInt32): Ditto.
+        (JSC::jsLess): Use asString.
+        (JSC::jsLessEq): Ditto.
+        (JSC::jsAdd): Ditto.
+        (JSC::jsTypeStringForValue): Use asObject.
+        (JSC::jsIsObjectType): Ditto.
+        (JSC::jsIsFunctionType): Ditto.
+        (JSC::inlineResolveBase): Use noValue.
+        (JSC::Machine::callEval): Use asString. Initialize result to
+        undefined, not 0.
+        (JSC::Machine::Machine): Remove unneeded casts to JSCell*.
+        (JSC::Machine::throwException): Use asObject.
+        (JSC::Machine::debug): Remove explicit calls to the DebuggerCallFrame
+        constructor.
+        (JSC::Machine::checkTimeout): Use noValue.
+        (JSC::cachePrototypeChain): Use asObject.
+        (JSC::Machine::tryCachePutByID): Use asCell.
+        (JSC::Machine::tryCacheGetByID): Use aCell and asObject.
+        (JSC::Machine::privateExecute): Use noValue, asCell, asObject, asString,
+        asArray, asActivation, asFunction. Changed code that creates call frames
+        for host functions to pass 0 for the function pointer -- the call frame
+        needs a JSFunction* and a host function object is not one. This was
+        caught by the assertions in the casting functions. Also remove some
+        unneeded casts in cases where two values are compared.
+        (JSC::Machine::retrieveLastCaller): Use noValue.
+        (JSC::Machine::tryCTICachePutByID): Use asCell.
+        (JSC::Machine::tryCTICacheGetByID): Use aCell and asObject.
+        (JSC::setUpThrowTrampolineReturnAddress): Added this function to restore
+        the PIC-branch-avoidance that was recently lost.
+        (JSC::Machine::cti_op_add): Use asString.
+        (JSC::Machine::cti_op_instanceof): Use asCell and asObject.
+        (JSC::Machine::cti_op_call_JSFunction): Use asFunction.
+        (JSC::Machine::cti_op_call_NotJSFunction): Changed code to pass 0 for
+        the function pointer, since we don't have a JSFunction. Use asObject.
+        (JSC::Machine::cti_op_tear_off_activation): Use asActivation.
+        (JSC::Machine::cti_op_construct_JSConstruct): Use asFunction and asObject.
+        (JSC::Machine::cti_op_construct_NotJSConstruct): use asObject.
+        (JSC::Machine::cti_op_get_by_val): Use asArray and asString.
+        (JSC::Machine::cti_op_resolve_func): Use asPointer; this helps prepare
+        us for a situation where JSValue is not a pointer.
+        (JSC::Machine::cti_op_put_by_val): Use asArray.
+        (JSC::Machine::cti_op_put_by_val_array): Ditto.
+        (JSC::Machine::cti_op_resolve_global): Use asGlobalObject.
+        (JSC::Machine::cti_op_post_inc): Change VM_CHECK_EXCEPTION_2 to
+        VM_CHECK_EXCEPTION_AT_END, since there's no observable work done after
+        that point. Also use asPointer.
+        (JSC::Machine::cti_op_resolve_with_base): Use asPointer.
+        (JSC::Machine::cti_op_post_dec): Change VM_CHECK_EXCEPTION_2 to
+        VM_CHECK_EXCEPTION_AT_END, since there's no observable work done after
+        that point. Also use asPointer.
+        (JSC::Machine::cti_op_call_eval): Use asObject, noValue, and change
+        VM_CHECK_EXCEPTION_ARG to VM_THROW_EXCEPTION_AT_END.
+        (JSC::Machine::cti_op_throw): Change return value to a JSValue*.
+        (JSC::Machine::cti_op_in): Use asObject.
+        (JSC::Machine::cti_op_switch_char): Use asString.
+        (JSC::Machine::cti_op_switch_string): Ditto.
+        (JSC::Machine::cti_op_put_getter): Use asObject.
+        (JSC::Machine::cti_op_put_setter): Ditto.
+        (JSC::Machine::cti_vm_throw): Change return value to a JSValue*.
+        Use noValue.
+        * VM/Machine.h: Change return values of both cti_op_throw and
+        cti_vm_throw to JSValue*.
+
+        * VM/Register.h: Remove nullJSValue, which is the same thing
+        as noValue(). Also removed unneeded definition of JSValue.
+
+        * kjs/ArgList.h: Removed unneeded definition of JSValue.
+
+        * kjs/Arguments.h:
+        (JSC::asArguments): Added.
+
+        * kjs/ArrayPrototype.cpp:
+        (JSC::getProperty): Use noValue.
+        (JSC::arrayProtoFuncToString): Use asArray.
+        (JSC::arrayProtoFuncToLocaleString): Ditto.
+        (JSC::arrayProtoFuncConcat): Ditto.
+        (JSC::arrayProtoFuncPop): Ditto. Also removed unneeded initialization
+        of the result, which is set in both sides of the branch.
+        (JSC::arrayProtoFuncPush): Ditto.
+        (JSC::arrayProtoFuncShift): Removed unneeded initialization
+        of the result, which is set in both sides of the branch.
+        (JSC::arrayProtoFuncSort): Use asArray.
+
+        * kjs/BooleanObject.h:
+        (JSC::asBooleanObject): Added.
+
+        * kjs/BooleanPrototype.cpp:
+        (JSC::booleanProtoFuncToString): Use asBooleanObject.
+        (JSC::booleanProtoFuncValueOf): Ditto.
+
+        * kjs/CallData.cpp:
+        (JSC::call): Use asObject and asFunction.
+        * kjs/ConstructData.cpp:
+        (JSC::construct): Ditto.
+
+        * kjs/DateConstructor.cpp:
+        (JSC::constructDate): Use asDateInstance.
+
+        * kjs/DateInstance.h:
+        (JSC::asDateInstance): Added.
+
+        * kjs/DatePrototype.cpp:
+        (JSC::dateProtoFuncToString): Use asDateInstance.
+        (JSC::dateProtoFuncToUTCString): Ditto.
+        (JSC::dateProtoFuncToDateString): Ditto.
+        (JSC::dateProtoFuncToTimeString): Ditto.
+        (JSC::dateProtoFuncToLocaleString): Ditto.
+        (JSC::dateProtoFuncToLocaleDateString): Ditto.
+        (JSC::dateProtoFuncToLocaleTimeString): Ditto.
+        (JSC::dateProtoFuncValueOf): Ditto.
+        (JSC::dateProtoFuncGetTime): Ditto.
+        (JSC::dateProtoFuncGetFullYear): Ditto.
+        (JSC::dateProtoFuncGetUTCFullYear): Ditto.
+        (JSC::dateProtoFuncToGMTString): Ditto.
+        (JSC::dateProtoFuncGetMonth): Ditto.
+        (JSC::dateProtoFuncGetUTCMonth): Ditto.
+        (JSC::dateProtoFuncGetDate): Ditto.
+        (JSC::dateProtoFuncGetUTCDate): Ditto.
+        (JSC::dateProtoFuncGetDay): Ditto.
+        (JSC::dateProtoFuncGetUTCDay): Ditto.
+        (JSC::dateProtoFuncGetHours): Ditto.
+        (JSC::dateProtoFuncGetUTCHours): Ditto.
+        (JSC::dateProtoFuncGetMinutes): Ditto.
+        (JSC::dateProtoFuncGetUTCMinutes): Ditto.
+        (JSC::dateProtoFuncGetSeconds): Ditto.
+        (JSC::dateProtoFuncGetUTCSeconds): Ditto.
+        (JSC::dateProtoFuncGetMilliSeconds): Ditto.
+        (JSC::dateProtoFuncGetUTCMilliseconds): Ditto.
+        (JSC::dateProtoFuncGetTimezoneOffset): Ditto.
+        (JSC::dateProtoFuncSetTime): Ditto.
+        (JSC::setNewValueFromTimeArgs): Ditto.
+        (JSC::setNewValueFromDateArgs): Ditto.
+        (JSC::dateProtoFuncSetYear): Ditto.
+        (JSC::dateProtoFuncGetYear): Ditto.
+
+        * kjs/DebuggerCallFrame.cpp:
+        (JSC::DebuggerCallFrame::thisObject): Use asObject.
+        (JSC::DebuggerCallFrame::evaluate): Use noValue.
+        * kjs/DebuggerCallFrame.h: Added a constructor that
+        takes only a callFrame.
+
+        * kjs/ExecState.h:
+        (JSC::ExecState::clearException): Use noValue.
+
+        * kjs/FunctionPrototype.cpp:
+        (JSC::functionProtoFuncToString): Use asFunction.
+        (JSC::functionProtoFuncApply): Use asArguments and asArray.
+
+        * kjs/GetterSetter.cpp:
+        (JSC::GetterSetter::getPrimitiveNumber): Use noValue.
+
+        * kjs/GetterSetter.h:
+        (JSC::asGetterSetter): Added.
+
+        * kjs/InternalFunction.cpp:
+        (JSC::InternalFunction::name): Use asString.
+
+        * kjs/InternalFunction.h:
+        (JSC::asInternalFunction): Added.
+
+        * kjs/JSActivation.cpp:
+        (JSC::JSActivation::argumentsGetter): Use asActivation.
+
+        * kjs/JSActivation.h:
+        (JSC::asActivation): Added.
+
+        * kjs/JSArray.cpp:
+        (JSC::JSArray::putSlowCase): Use noValue.
+        (JSC::JSArray::deleteProperty): Ditto.
+        (JSC::JSArray::increaseVectorLength): Ditto.
+        (JSC::JSArray::setLength): Ditto.
+        (JSC::JSArray::pop): Ditto.
+        (JSC::JSArray::sort): Ditto.
+        (JSC::JSArray::compactForSorting): Ditto.
+        * kjs/JSArray.h:
+        (JSC::asArray): Added.
+
+        * kjs/JSCell.cpp:
+        (JSC::JSCell::getJSNumber): Use noValue.
+
+        * kjs/JSCell.h:
+        (JSC::asCell): Added.
+        (JSC::JSValue::asCell): Changed to not preserve const.
+        Given the wide use of JSValue* and JSCell*, it's not
+        really useful to use const.
+        (JSC::JSValue::isNumber): Use asValue.
+        (JSC::JSValue::isString): Ditto.
+        (JSC::JSValue::isGetterSetter): Ditto.
+        (JSC::JSValue::isObject): Ditto.
+        (JSC::JSValue::getNumber): Ditto.
+        (JSC::JSValue::getString): Ditto.
+        (JSC::JSValue::getObject): Ditto.
+        (JSC::JSValue::getCallData): Ditto.
+        (JSC::JSValue::getConstructData): Ditto.
+        (JSC::JSValue::getUInt32): Ditto.
+        (JSC::JSValue::getTruncatedInt32): Ditto.
+        (JSC::JSValue::getTruncatedUInt32): Ditto.
+        (JSC::JSValue::mark): Ditto.
+        (JSC::JSValue::marked): Ditto.
+        (JSC::JSValue::toPrimitive): Ditto.
+        (JSC::JSValue::getPrimitiveNumber): Ditto.
+        (JSC::JSValue::toBoolean): Ditto.
+        (JSC::JSValue::toNumber): Ditto.
+        (JSC::JSValue::toString): Ditto.
+        (JSC::JSValue::toObject): Ditto.
+        (JSC::JSValue::toThisObject): Ditto.
+        (JSC::JSValue::needsThisConversion): Ditto.
+        (JSC::JSValue::toThisString): Ditto.
+        (JSC::JSValue::getJSNumber): Ditto.
+
+        * kjs/JSFunction.cpp:
+        (JSC::JSFunction::argumentsGetter): Use asFunction.
+        (JSC::JSFunction::callerGetter): Ditto.
+        (JSC::JSFunction::lengthGetter): Ditto.
+        (JSC::JSFunction::construct): Use asObject.
+
+        * kjs/JSFunction.h:
+        (JSC::asFunction): Added.
+
+        * kjs/JSGlobalObject.cpp:
+        (JSC::lastInPrototypeChain): Use asObject.
+
+        * kjs/JSGlobalObject.h:
+        (JSC::asGlobalObject): Added.
+        (JSC::ScopeChainNode::globalObject): Use asGlobalObject.
+
+        * kjs/JSImmediate.h: Added noValue, asPointer, and makeValue
+        functions. Use rawValue, makeValue, and noValue consistently
+        instead of doing reinterpret_cast in various functions.
+
+        * kjs/JSNumberCell.h:
+        (JSC::asNumberCell): Added.
+        (JSC::JSValue::uncheckedGetNumber): Use asValue and asNumberCell.
+        (JSC::JSValue::toJSNumber): Use asValue.
+
+        * kjs/JSObject.cpp:
+        (JSC::JSObject::put): Use asObject and asGetterSetter.
+        (JSC::callDefaultValueFunction): Use noValue.
+        (JSC::JSObject::defineGetter): Use asGetterSetter.
+        (JSC::JSObject::defineSetter): Ditto.
+        (JSC::JSObject::lookupGetter): Ditto. Also use asObject.
+        (JSC::JSObject::lookupSetter): Ditto.
+        (JSC::JSObject::hasInstance): Use asObject.
+        (JSC::JSObject::fillGetterPropertySlot): Use asGetterSetter.
+
+        * kjs/JSObject.h:
+        (JSC::JSObject::getDirect): Use noValue.
+        (JSC::asObject): Added.
+        (JSC::JSValue::isObject): Use asValue.
+        (JSC::JSObject::get): Removed unneeded const_cast.
+        (JSC::JSObject::getPropertySlot): Use asObject.
+        (JSC::JSValue::get): Removed unneeded const_cast.
+        Use asValue, asCell, and asObject.
+        (JSC::JSValue::put): Ditto.
+        (JSC::JSObject::allocatePropertyStorageInline): Fixed spelling
+        of "oldPropertStorage".
+
+        * kjs/JSString.cpp:
+        (JSC::JSString::getOwnPropertySlot): Use asObject.
+
+        * kjs/JSString.h:
+        (JSC::asString): Added.
+        (JSC::JSValue::toThisJSString): Use asValue.
+
+        * kjs/JSValue.h: Make PreferredPrimitiveType a top level enum
+        instead of a member of JSValue. Added an asValue function that
+        returns this. Removed overload of asCell for const. Use asValue
+        instead of getting right at this.
+
+        * kjs/ObjectPrototype.cpp:
+        (JSC::objectProtoFuncIsPrototypeOf): Use asObject.
+        (JSC::objectProtoFuncDefineGetter): Ditto.
+        (JSC::objectProtoFuncDefineSetter): Ditto.
+
+        * kjs/PropertySlot.h:
+        (JSC::PropertySlot::PropertySlot): Take a const JSValue* so the
+        callers don't have to worry about const.
+        (JSC::PropertySlot::clearBase): Use noValue.
+        (JSC::PropertySlot::clearValue): Ditto.
+
+        * kjs/RegExpConstructor.cpp:
+        (JSC::regExpConstructorDollar1): Use asRegExpConstructor.
+        (JSC::regExpConstructorDollar2): Ditto.
+        (JSC::regExpConstructorDollar3): Ditto.
+        (JSC::regExpConstructorDollar4): Ditto.
+        (JSC::regExpConstructorDollar5): Ditto.
+        (JSC::regExpConstructorDollar6): Ditto.
+        (JSC::regExpConstructorDollar7): Ditto.
+        (JSC::regExpConstructorDollar8): Ditto.
+        (JSC::regExpConstructorDollar9): Ditto.
+        (JSC::regExpConstructorInput): Ditto.
+        (JSC::regExpConstructorMultiline): Ditto.
+        (JSC::regExpConstructorLastMatch): Ditto.
+        (JSC::regExpConstructorLastParen): Ditto.
+        (JSC::regExpConstructorLeftContext): Ditto.
+        (JSC::regExpConstructorRightContext): Ditto.
+        (JSC::setRegExpConstructorInput): Ditto.
+        (JSC::setRegExpConstructorMultiline): Ditto.
+        (JSC::constructRegExp): Use asObject.
+
+        * kjs/RegExpConstructor.h:
+        (JSC::asRegExpConstructor): Added.
+
+        * kjs/RegExpObject.cpp:
+        (JSC::regExpObjectGlobal): Use asRegExpObject.
+        (JSC::regExpObjectIgnoreCase): Ditto.
+        (JSC::regExpObjectMultiline): Ditto.
+        (JSC::regExpObjectSource): Ditto.
+        (JSC::regExpObjectLastIndex): Ditto.
+        (JSC::setRegExpObjectLastIndex): Ditto.
+        (JSC::callRegExpObject): Ditto.
+
+        * kjs/RegExpObject.h:
+        (JSC::asRegExpObject): Added.
+
+        * kjs/RegExpPrototype.cpp:
+        (JSC::regExpProtoFuncTest): Use asRegExpObject.
+        (JSC::regExpProtoFuncExec): Ditto.
+        (JSC::regExpProtoFuncCompile): Ditto.
+        (JSC::regExpProtoFuncToString): Ditto.
+
+        * kjs/StringObject.h:
+        (JSC::StringObject::internalValue): Use asString.
+        (JSC::asStringObject): Added.
+
+        * kjs/StringPrototype.cpp:
+        (JSC::stringProtoFuncReplace): Use asRegExpObject.
+        (JSC::stringProtoFuncToString): Ue asStringObject.
+        (JSC::stringProtoFuncMatch): Use asRegExpObject.
+        (JSC::stringProtoFuncSearch): Ditto.
+        (JSC::stringProtoFuncSplit): Ditto.
+
+        * kjs/StructureID.cpp:
+        (JSC::StructureID::getEnumerablePropertyNames): Use asObject.
+        (JSC::StructureID::createCachedPrototypeChain): Ditto.
+        (JSC::StructureIDChain::StructureIDChain): Use asCell and asObject.
+
+        * kjs/collector.h:
+        (JSC::Heap::isNumber): Removed null handling. This can only be called
+        on valid cells.
+        (JSC::Heap::cellBlock): Removed overload for const and non-const.
+        Whether the JSCell* is const or not really should have no effect on
+        whether you can modify the collector block it's in.
+
+        * kjs/interpreter.cpp:
+        (JSC::Interpreter::evaluate): Use noValue and noObject.
+
+        * kjs/nodes.cpp:
+        (JSC::FunctionCallResolveNode::emitCode): Use JSObject for the global
+        object rather than JSValue.
+        (JSC::PostfixResolveNode::emitCode): Ditto.
+        (JSC::PrefixResolveNode::emitCode): Ditto.
+        (JSC::ReadModifyResolveNode::emitCode): Ditto.
+        (JSC::AssignResolveNode::emitCode): Ditto.
+
+        * kjs/operations.h:
+        (JSC::equalSlowCaseInline): Use asString, asCell, asNumberCell, 
+        (JSC::strictEqualSlowCaseInline): Ditto.
+
 2008-10-18  Cameron Zwarich  <zwarich@apple.com>
 
         Reviewed by Oliver Hunt.
index 389e5e4..b18d7e2 100644 (file)
@@ -337,7 +337,7 @@ __ZNK3JSC7UString8toUInt32EPb
 __ZNK3JSC7UString8toUInt32EPbb
 __ZNK3JSC8JSObject11hasPropertyEPNS_9ExecStateERKNS_10IdentifierE
 __ZNK3JSC8JSObject11hasPropertyEPNS_9ExecStateEj
-__ZNK3JSC8JSObject12defaultValueEPNS_9ExecStateENS_7JSValue22PreferredPrimitiveTypeE
+__ZNK3JSC8JSObject12defaultValueEPNS_9ExecStateENS_22PreferredPrimitiveTypeE
 __ZNK3JSC8JSObject12toThisObjectEPNS_9ExecStateE
 __ZNK3JSC8JSObject14toGlobalObjectEPNS_9ExecStateE
 __ZNK3JSC8JSObject21getPropertyAttributesEPNS_9ExecStateERKNS_10IdentifierERj
index fedea43..26d8666 100644 (file)
                93AA4F770957251F0084B3A7 /* AlwaysInline.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = AlwaysInline.h; sourceTree = "<group>"; tabWidth = 8; };
                93ADFCE60CCBD7AC00D30B08 /* JSArray.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSArray.cpp; sourceTree = "<group>"; };
                93B6A0DE0AA64DA40076DE27 /* GetPtr.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = GetPtr.h; sourceTree = "<group>"; };
+               93CEDDFB0EA91EE600258EBE /* RegExpMatchesArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegExpMatchesArray.h; sourceTree = "<group>"; };
                93E26BD308B1514100F85226 /* pcre_xclass.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; name = pcre_xclass.cpp; path = pcre/pcre_xclass.cpp; sourceTree = "<group>"; tabWidth = 8; };
                93E26BE508B1517100F85226 /* pcre_internal.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; name = pcre_internal.h; path = pcre/pcre_internal.h; sourceTree = "<group>"; tabWidth = 8; };
                93E26BFC08B151D400F85226 /* ucpinternal.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; name = ucpinternal.h; path = pcre/ucpinternal.h; sourceTree = "<group>"; tabWidth = 8; };
                                F692A87E0255597D01FF60F7 /* regexp.h */,
                                BCD202BD0E1706A7002C7E82 /* RegExpConstructor.cpp */,
                                BCD202BE0E1706A7002C7E82 /* RegExpConstructor.h */,
+                               93CEDDFB0EA91EE600258EBE /* RegExpMatchesArray.h */,
                                F692A87B0255597D01FF60F7 /* RegExpObject.cpp */,
                                F692A87C0255597D01FF60F7 /* RegExpObject.h */,
                                BCD202BF0E1706A7002C7E82 /* RegExpPrototype.cpp */,
index 62e2bf6..2feeee0 100644 (file)
@@ -177,13 +177,18 @@ ALWAYS_INLINE JSValue* CTI::getConstant(CallFrame* callFrame, int src)
     return m_codeBlock->constantRegisters[src - m_codeBlock->numVars].jsValue(callFrame);
 }
 
+inline uintptr_t CTI::asInteger(JSValue* value)
+{
+    return reinterpret_cast<uintptr_t>(value);
+}
+
 // get arg puts an arg from the SF register array into a h/w register
 ALWAYS_INLINE void CTI::emitGetArg(int src, X86Assembler::RegisterID dst)
 {
     // TODO: we want to reuse values that are already in registers if we can - add a register allocator!
     if (isConstant(src)) {
         JSValue* js = getConstant(m_callFrame, src);
-        m_jit.movl_i32r(reinterpret_cast<unsigned>(js), dst);
+        m_jit.movl_i32r(asInteger(js), dst);
     } else
         m_jit.movl_mr(src * sizeof(Register), X86::edi, dst);
 }
@@ -193,7 +198,7 @@ ALWAYS_INLINE void CTI::emitGetPutArg(unsigned src, unsigned offset, X86Assemble
 {
     if (isConstant(src)) {
         JSValue* js = getConstant(m_callFrame, src);
-        m_jit.movl_i32m(reinterpret_cast<unsigned>(js), offset + sizeof(void*), X86::esp);
+        m_jit.movl_i32m(asInteger(js), offset + sizeof(void*), X86::esp);
     } else {
         m_jit.movl_mr(src * sizeof(Register), X86::edi, scratch);
         m_jit.movl_rm(scratch, offset + sizeof(void*), X86::esp);
@@ -215,9 +220,9 @@ ALWAYS_INLINE JSValue* CTI::getConstantImmediateNumericArg(unsigned src)
 {
     if (isConstant(src)) {
         JSValue* js = getConstant(m_callFrame, src);
-        return JSImmediate::isNumber(js) ? js : 0;
+        return JSImmediate::isNumber(js) ? js : noValue();
     }
-    return 0;
+    return noValue();
 }
 
 ALWAYS_INLINE void CTI::emitPutCTIParam(void* value, unsigned name)
@@ -253,7 +258,7 @@ ALWAYS_INLINE void CTI::emitPutResult(unsigned dst, X86Assembler::RegisterID fro
 
 ALWAYS_INLINE void CTI::emitInitRegister(unsigned dst)
 {
-    m_jit.movl_i32m(reinterpret_cast<unsigned>(jsUndefined()), dst * sizeof(Register), X86::edi);
+    m_jit.movl_i32m(asInteger(jsUndefined()), dst * sizeof(Register), X86::edi);
     // FIXME: #ifndef NDEBUG, Write the correct m_type to the register.
 }
 
@@ -442,7 +447,7 @@ ALWAYS_INLINE void CTI::emitJumpSlowCaseIfNotImmNums(X86Assembler::RegisterID re
 ALWAYS_INLINE unsigned CTI::getDeTaggedConstantImmediate(JSValue* imm)
 {
     ASSERT(JSImmediate::isNumber(imm));
-    return reinterpret_cast<unsigned>(imm) & ~JSImmediate::TagBitTypeInteger;
+    return asInteger(imm) & ~JSImmediate::TagBitTypeInteger;
 }
 
 ALWAYS_INLINE void CTI::emitFastArithDeTagImmediate(X86Assembler::RegisterID reg)
@@ -533,7 +538,7 @@ void CTI::compileOpCallInitializeCallFrame(unsigned callee, unsigned argCount)
 {
     emitGetArg(callee, X86::ecx); // Load callee JSFunction into ecx
     m_jit.movl_rm(X86::eax, RegisterFile::CodeBlock * static_cast<int>(sizeof(Register)), X86::edx); // callee CodeBlock was returned in eax
-    m_jit.movl_i32m(reinterpret_cast<unsigned>(nullJSValue), RegisterFile::OptionalCalleeArguments * static_cast<int>(sizeof(Register)), X86::edx);
+    m_jit.movl_i32m(asInteger(noValue()), RegisterFile::OptionalCalleeArguments * static_cast<int>(sizeof(Register)), X86::edx);
     m_jit.movl_rm(X86::ecx, RegisterFile::Callee * static_cast<int>(sizeof(Register)), X86::edx);
 
     m_jit.movl_mr(OBJECT_OFFSET(JSFunction, m_scopeChain) + OBJECT_OFFSET(ScopeChain, m_node), X86::ecx, X86::ebx); // newScopeChain
@@ -572,7 +577,7 @@ void CTI::compileOpCall(Instruction* instruction, unsigned i, unsigned structure
         int thisVal = instruction[3].u.operand;
         if (thisVal == missingThisObjectMarker()) {
             // FIXME: should this be loaded dynamically off m_callFrame?
-            m_jit.movl_i32m(reinterpret_cast<unsigned>(m_callFrame->globalThisValue()), firstArg * sizeof(Register), X86::edi);
+            m_jit.movl_i32m(asInteger(m_callFrame->globalThisValue()), firstArg * sizeof(Register), X86::edi);
         } else {
             emitGetArg(thisVal, X86::eax);
             emitPutResult(firstArg);
@@ -586,14 +591,14 @@ void CTI::compileOpCall(Instruction* instruction, unsigned i, unsigned structure
         compileOpCallSetupArgs(instruction, false, true);
 
         emitCTICall(i, Machine::cti_op_call_eval);
-        m_jit.cmpl_i32r(reinterpret_cast<unsigned>(JSImmediate::impossibleValue()), X86::eax);
+        m_jit.cmpl_i32r(asInteger(JSImmediate::impossibleValue()), X86::eax);
         wasEval = m_jit.emitUnlinkedJne();
     }
 
     // This plants a check for a cached JSFunction value, so we can plant a fast link to the callee.
     // This deliberately leaves the callee in ecx, used when setting up the stack frame below
     emitGetArg(callee, X86::ecx);
-    m_jit.cmpl_i32r(reinterpret_cast<unsigned>(JSImmediate::impossibleValue()), X86::ecx);
+    m_jit.cmpl_i32r(asInteger(JSImmediate::impossibleValue()), X86::ecx);
     X86Assembler::JmpDst addressOfLinkedFunctionCheck = m_jit.label();
     m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJne(), i));
     ASSERT(X86Assembler::getDifferenceBetweenLabels(addressOfLinkedFunctionCheck, m_jit.label()) == repatchOffsetOpCallCall);
@@ -620,7 +625,7 @@ void CTI::compileOpCall(Instruction* instruction, unsigned i, unsigned structure
 
     // Fast version of stack frame initialization, directly relative to edi.
     // Note that this omits to set up RegisterFile::CodeBlock, which is set in the callee
-    m_jit.movl_i32m(reinterpret_cast<unsigned>(nullJSValue), (registerOffset + RegisterFile::OptionalCalleeArguments) * static_cast<int>(sizeof(Register)), X86::edi);
+    m_jit.movl_i32m(asInteger(noValue()), (registerOffset + RegisterFile::OptionalCalleeArguments) * static_cast<int>(sizeof(Register)), X86::edi);
     m_jit.movl_rm(X86::ecx, (registerOffset + RegisterFile::Callee) * static_cast<int>(sizeof(Register)), X86::edi);
     m_jit.movl_mr(OBJECT_OFFSET(JSFunction, m_scopeChain) + OBJECT_OFFSET(ScopeChain, m_node), X86::ecx, X86::edx); // newScopeChain
     m_jit.movl_i32m(argCount, (registerOffset + RegisterFile::ArgumentCount) * static_cast<int>(sizeof(Register)), X86::edi);
@@ -670,23 +675,23 @@ void CTI::compileOpStrictEq(Instruction* instruction, unsigned i, CompileOpStric
     m_jit.testl_i32r(JSImmediate::TagMask, X86::edx);
     m_jit.setz_r(X86::ecx);
     m_jit.movzbl_rr(X86::ecx, X86::ecx); // ecx is now 1 if edx was nonimmediate
-    m_jit.cmpl_i32r(reinterpret_cast<uint32_t>(JSImmediate::zeroImmediate()), X86::edx);
+    m_jit.cmpl_i32r(asInteger(JSImmediate::zeroImmediate()), X86::edx);
     m_jit.sete_r(X86::edx);
     m_jit.movzbl_rr(X86::edx, X86::edx); // edx is now 1 if edx was the 0 immediate
     m_jit.orl_rr(X86::ecx, X86::edx);
 
     m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJnz(), i));
 
-    m_jit.movl_i32r(reinterpret_cast<uint32_t>(jsBoolean(negated)), X86::eax);
+    m_jit.movl_i32r(asInteger(jsBoolean(negated)), X86::eax);
 
     X86Assembler::JmpSrc firstWasNotImmediate = m_jit.emitUnlinkedJmp();
 
     m_jit.link(secondNotImmediate, m_jit.label());
     // check that eax is not the zero immediate (we know it must be immediate)
-    m_jit.cmpl_i32r(reinterpret_cast<uint32_t>(JSImmediate::zeroImmediate()), X86::eax);
+    m_jit.cmpl_i32r(asInteger(JSImmediate::zeroImmediate()), X86::eax);
     m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJe(), i));
 
-    m_jit.movl_i32r(reinterpret_cast<uint32_t>(jsBoolean(negated)), X86::eax);
+    m_jit.movl_i32r(asInteger(jsBoolean(negated)), X86::eax);
 
     m_jit.link(bothWereImmediates, m_jit.label());
     m_jit.link(firstWasNotImmediate, m_jit.label());
@@ -954,7 +959,7 @@ void CTI::privateCompileMainPass()
         case op_mov: {
             unsigned src = instruction[i + 2].u.operand;
             if (isConstant(src))
-                m_jit.movl_i32r(reinterpret_cast<unsigned>(getConstant(m_callFrame, src)), X86::edx);
+                m_jit.movl_i32r(asInteger(getConstant(m_callFrame, src)), X86::edx);
             else
                 emitGetArg(src, X86::edx);
             emitPutResult(instruction[i + 1].u.operand, X86::edx);
@@ -1037,7 +1042,7 @@ void CTI::privateCompileMainPass()
             if (src2imm) {
                 emitGetArg(instruction[i + 1].u.operand, X86::edx);
                 emitJumpSlowCaseIfNotImmNum(X86::edx, i);
-                m_jit.cmpl_i32r(reinterpret_cast<unsigned>(src2imm), X86::edx);
+                m_jit.cmpl_i32r(asInteger(src2imm), X86::edx);
                 m_jmpTable.append(JmpTable(m_jit.emitUnlinkedJl(), i + 3 + target));
             } else {
                 emitGetArg(instruction[i + 1].u.operand, X86::eax);
@@ -1058,7 +1063,7 @@ void CTI::privateCompileMainPass()
             if (src2imm) {
                 emitGetArg(instruction[i + 1].u.operand, X86::edx);
                 emitJumpSlowCaseIfNotImmNum(X86::edx, i);
-                m_jit.cmpl_i32r(reinterpret_cast<unsigned>(src2imm), X86::edx);
+                m_jit.cmpl_i32r(asInteger(src2imm), X86::edx);
                 m_jmpTable.append(JmpTable(m_jit.emitUnlinkedJle(), i + 3 + target));
             } else {
                 emitGetArg(instruction[i + 1].u.operand, X86::eax);
@@ -1170,7 +1175,7 @@ void CTI::privateCompileMainPass()
             emitGetArg(instruction[i + 4].u.operand, X86::edx); // reload proto
 
             // optimistically load true result
-            m_jit.movl_i32r(reinterpret_cast<int32_t>(jsBoolean(true)), X86::eax);
+            m_jit.movl_i32r(asInteger(jsBoolean(true)), X86::eax);
 
             X86Assembler::JmpDst loop = m_jit.label();
 
@@ -1181,11 +1186,11 @@ void CTI::privateCompileMainPass()
             m_jit.cmpl_rr(X86::ecx, X86::edx);
             X86Assembler::JmpSrc exit = m_jit.emitUnlinkedJe();
 
-            m_jit.cmpl_i32r(reinterpret_cast<int32_t>(jsNull()), X86::ecx);
+            m_jit.cmpl_i32r(asInteger(jsNull()), X86::ecx);
             X86Assembler::JmpSrc goToLoop = m_jit.emitUnlinkedJne();
             m_jit.link(goToLoop, loop);
 
-            m_jit.movl_i32r(reinterpret_cast<int32_t>(jsBoolean(false)), X86::eax);
+            m_jit.movl_i32r(asInteger(jsBoolean(false)), X86::eax);
 
             m_jit.link(exit, m_jit.label());
 
@@ -1249,7 +1254,7 @@ void CTI::privateCompileMainPass()
         }
         case op_get_global_var: {
             JSVariableObject* globalObject = static_cast<JSVariableObject*>(instruction[i + 2].u.jsCell);
-            m_jit.movl_i32r(reinterpret_cast<unsigned>(globalObject), X86::eax);
+            m_jit.movl_i32r(asInteger(globalObject), X86::eax);
             emitGetVariableObjectRegister(X86::eax, instruction[i + 3].u.operand, X86::eax);
             emitPutResult(instruction[i + 1].u.operand, X86::eax);
             i += 4;
@@ -1257,7 +1262,7 @@ void CTI::privateCompileMainPass()
         }
         case op_put_global_var: {
             JSVariableObject* globalObject = static_cast<JSVariableObject*>(instruction[i + 1].u.jsCell);
-            m_jit.movl_i32r(reinterpret_cast<unsigned>(globalObject), X86::eax);
+            m_jit.movl_i32r(asInteger(globalObject), X86::eax);
             emitGetArg(instruction[i + 3].u.operand, X86::edx);
             emitPutVariableObjectRegister(X86::edx, X86::eax, instruction[i + 2].u.operand);
             i += 4;
@@ -1443,14 +1448,14 @@ void CTI::privateCompileMainPass()
             unsigned target = instruction[i + 2].u.operand;
             emitGetArg(instruction[i + 1].u.operand, X86::eax);
 
-            m_jit.cmpl_i32r(reinterpret_cast<uint32_t>(JSImmediate::zeroImmediate()), X86::eax);
+            m_jit.cmpl_i32r(asInteger(JSImmediate::zeroImmediate()), X86::eax);
             X86Assembler::JmpSrc isZero = m_jit.emitUnlinkedJe();
             m_jit.testl_i32r(JSImmediate::TagBitTypeInteger, X86::eax);
             m_jmpTable.append(JmpTable(m_jit.emitUnlinkedJne(), i + 2 + target));
 
-            m_jit.cmpl_i32r(reinterpret_cast<uint32_t>(JSImmediate::trueImmediate()), X86::eax);
+            m_jit.cmpl_i32r(asInteger(JSImmediate::trueImmediate()), X86::eax);
             m_jmpTable.append(JmpTable(m_jit.emitUnlinkedJe(), i + 2 + target));
-            m_jit.cmpl_i32r(reinterpret_cast<uint32_t>(JSImmediate::falseImmediate()), X86::eax);
+            m_jit.cmpl_i32r(asInteger(JSImmediate::falseImmediate()), X86::eax);
             m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJne(), i));
 
             m_jit.link(isZero, m_jit.label());
@@ -1483,7 +1488,7 @@ void CTI::privateCompileMainPass()
         }
         case op_resolve_global: {
             // Fast case
-            unsigned globalObject = reinterpret_cast<unsigned>(instruction[i + 2].u.jsCell);
+            unsigned globalObject = asInteger(instruction[i + 2].u.jsCell);
             Identifier* ident = &(m_codeBlock->identifiers[instruction[i + 3].u.operand]);
             void* structureIDAddr = reinterpret_cast<void*>(instruction + i + 4);
             void* offsetAddr = reinterpret_cast<void*>(instruction + i + 5);
@@ -1531,7 +1536,7 @@ void CTI::privateCompileMainPass()
             if (src2imm) {
                 emitGetArg(instruction[i + 1].u.operand, X86::edx);
                 emitJumpSlowCaseIfNotImmNum(X86::edx, i);
-                m_jit.cmpl_i32r(reinterpret_cast<unsigned>(src2imm), X86::edx);
+                m_jit.cmpl_i32r(asInteger(src2imm), X86::edx);
                 m_jmpTable.append(JmpTable(m_jit.emitUnlinkedJge(), i + 3 + target));
             } else {
                 emitGetArg(instruction[i + 1].u.operand, X86::eax);
@@ -1558,14 +1563,14 @@ void CTI::privateCompileMainPass()
             unsigned target = instruction[i + 2].u.operand;
             emitGetArg(instruction[i + 1].u.operand, X86::eax);
 
-            m_jit.cmpl_i32r(reinterpret_cast<uint32_t>(JSImmediate::zeroImmediate()), X86::eax);
+            m_jit.cmpl_i32r(asInteger(JSImmediate::zeroImmediate()), X86::eax);
             m_jmpTable.append(JmpTable(m_jit.emitUnlinkedJe(), i + 2 + target));
             m_jit.testl_i32r(JSImmediate::TagBitTypeInteger, X86::eax);
             X86Assembler::JmpSrc isNonZero = m_jit.emitUnlinkedJne();
 
-            m_jit.cmpl_i32r(reinterpret_cast<uint32_t>(JSImmediate::falseImmediate()), X86::eax);
+            m_jit.cmpl_i32r(asInteger(JSImmediate::falseImmediate()), X86::eax);
             m_jmpTable.append(JmpTable(m_jit.emitUnlinkedJe(), i + 2 + target));
-            m_jit.cmpl_i32r(reinterpret_cast<uint32_t>(JSImmediate::trueImmediate()), X86::eax);
+            m_jit.cmpl_i32r(asInteger(JSImmediate::trueImmediate()), X86::eax);
             m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJne(), i));
 
             m_jit.link(isNonZero, m_jit.label());
@@ -1586,7 +1591,7 @@ void CTI::privateCompileMainPass()
         }
         case op_unexpected_load: {
             JSValue* v = m_codeBlock->unexpectedConstants[instruction[i + 2].u.operand];
-            m_jit.movl_i32r(reinterpret_cast<unsigned>(v), X86::eax);
+            m_jit.movl_i32r(asInteger(v), X86::eax);
             emitPutResult(instruction[i + 1].u.operand);
             i += 3;
             break;
@@ -1639,12 +1644,12 @@ void CTI::privateCompileMainPass()
             if (JSValue* value = getConstantImmediateNumericArg(src1)) {
                 emitGetArg(src2, X86::eax);
                 emitJumpSlowCaseIfNotImmNum(X86::eax, i);
-                m_jit.andl_i32r(reinterpret_cast<unsigned>(value), X86::eax); // FIXME: make it more obvious this is relying on the format of JSImmediate
+                m_jit.andl_i32r(asInteger(value), X86::eax); // FIXME: make it more obvious this is relying on the format of JSImmediate
                 emitPutResult(dst);
             } else if (JSValue* value = getConstantImmediateNumericArg(src2)) {
                 emitGetArg(src1, X86::eax);
                 emitJumpSlowCaseIfNotImmNum(X86::eax, i);
-                m_jit.andl_i32r(reinterpret_cast<unsigned>(value), X86::eax);
+                m_jit.andl_i32r(asInteger(value), X86::eax);
                 emitPutResult(dst);
             } else {
                 emitGetArg(src1, X86::eax);
@@ -1712,14 +1717,14 @@ void CTI::privateCompileMainPass()
             unsigned target = instruction[i + 2].u.operand;
             emitGetArg(instruction[i + 1].u.operand, X86::eax);
 
-            m_jit.cmpl_i32r(reinterpret_cast<uint32_t>(JSImmediate::zeroImmediate()), X86::eax);
+            m_jit.cmpl_i32r(asInteger(JSImmediate::zeroImmediate()), X86::eax);
             X86Assembler::JmpSrc isZero = m_jit.emitUnlinkedJe();
             m_jit.testl_i32r(JSImmediate::TagBitTypeInteger, X86::eax);
             m_jmpTable.append(JmpTable(m_jit.emitUnlinkedJne(), i + 2 + target));
 
-            m_jit.cmpl_i32r(reinterpret_cast<uint32_t>(JSImmediate::trueImmediate()), X86::eax);
+            m_jit.cmpl_i32r(asInteger(JSImmediate::trueImmediate()), X86::eax);
             m_jmpTable.append(JmpTable(m_jit.emitUnlinkedJe(), i + 2 + target));
-            m_jit.cmpl_i32r(reinterpret_cast<uint32_t>(JSImmediate::falseImmediate()), X86::eax);
+            m_jit.cmpl_i32r(asInteger(JSImmediate::falseImmediate()), X86::eax);
             m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJne(), i));
 
             m_jit.link(isZero, m_jit.label());
@@ -1983,7 +1988,7 @@ void CTI::privateCompileMainPass()
         case op_new_error: {
             JSValue* message = m_codeBlock->unexpectedConstants[instruction[i + 3].u.operand];
             emitPutArgConstant(instruction[i + 2].u.operand, 0);
-            emitPutArgConstant(reinterpret_cast<unsigned>(message), 4);
+            emitPutArgConstant(asInteger(message), 4);
             emitPutArgConstant(m_codeBlock->lineNumberForVPC(&instruction[i]), 8);
             emitCTICall(i, Machine::cti_op_new_error);
             emitPutResult(instruction[i + 1].u.operand);
@@ -2845,7 +2850,7 @@ void CTI::privateCompileGetByIdProto(StructureID* structureID, StructureID* prot
 
     // The prototype object definitely exists (if this stub exists the CodeBlock is referencing a StructureID that is
     // referencing the prototype object - let's speculatively load it's table nice and early!)
-    JSObject* protoObject = static_cast<JSObject*>(structureID->prototypeForLookup(m_callFrame));
+    JSObject* protoObject = asObject(structureID->prototypeForLookup(m_callFrame));
     PropertyStorage* protoPropertyStorage = &protoObject->m_propertyStorage;
     m_jit.movl_mr(static_cast<void*>(protoPropertyStorage), X86::edx);
 
@@ -2888,7 +2893,7 @@ void CTI::privateCompileGetByIdProto(StructureID* structureID, StructureID* prot
 #else
     // The prototype object definitely exists (if this stub exists the CodeBlock is referencing a StructureID that is
     // referencing the prototype object - let's speculatively load it's table nice and early!)
-    JSObject* protoObject = static_cast<JSObject*>(structureID->prototypeForLookup(m_callFrame));
+    JSObject* protoObject = asObject(structureID->prototypeForLookup(m_callFrame));
     PropertyStorage* protoPropertyStorage = &protoObject->m_propertyStorage;
     m_jit.movl_mr(static_cast<void*>(protoPropertyStorage), X86::edx);
 
@@ -2937,7 +2942,7 @@ void CTI::privateCompileGetByIdChain(StructureID* structureID, StructureIDChain*
     RefPtr<StructureID>* chainEntries = chain->head();
     JSObject* protoObject = 0;
     for (unsigned i = 0; i<count; ++i) {
-        protoObject = static_cast<JSObject*>(currStructureID->prototypeForLookup(m_callFrame));
+        protoObject = asObject(currStructureID->prototypeForLookup(m_callFrame));
         currStructureID = chainEntries[i].get();
 
         // Check the prototype object's StructureID had not changed.
@@ -3024,7 +3029,7 @@ void CTI::privateCompilePutByIdTransition(StructureID* oldStructureID, Structure
     // ecx = baseObject->m_structureID
     for (RefPtr<StructureID>* it = sIDC->head(); *it; ++it) {
         // null check the prototype
-        m_jit.cmpl_i32r(reinterpret_cast<intptr_t> (jsNull()), X86::ecx);
+        m_jit.cmpl_i32r(asInteger(jsNull()), X86::ecx);
         successCases.append(m_jit.emitUnlinkedJe());
 
         // Check the structure id
index 73483e6..1cf2462 100644 (file)
 #define CTI_ARGS_exception 0x0F
 #define CTI_ARGS_profilerReference 0x10
 #define CTI_ARGS_globalData 0x11
-#define ARG_callFrame ((CallFrame*)(ARGS)[CTI_ARGS_callFrame])
-#define ARG_registerFile ((RegisterFile*)(ARGS)[CTI_ARGS_registerFile])
-#define ARG_exception ((JSValue**)(ARGS)[CTI_ARGS_exception])
-#define ARG_profilerReference ((Profiler**)(ARGS)[CTI_ARGS_profilerReference])
-#define ARG_globalData ((JSGlobalData*)(ARGS)[CTI_ARGS_globalData])
-
-#define ARG_setCallFrame(newCallFrame) (*(CallFrame**)&(ARGS)[CTI_ARGS_callFrame] = (newCallFrame))
-
-#define ARG_src1 ((JSValue*)((ARGS)[1]))
-#define ARG_src2 ((JSValue*)((ARGS)[2]))
-#define ARG_src3 ((JSValue*)((ARGS)[3]))
-#define ARG_src4 ((JSValue*)((ARGS)[4]))
-#define ARG_src5 ((JSValue*)((ARGS)[5]))
-#define ARG_id1 ((Identifier*)((ARGS)[1]))
-#define ARG_id2 ((Identifier*)((ARGS)[2]))
-#define ARG_id3 ((Identifier*)((ARGS)[3]))
-#define ARG_id4 ((Identifier*)((ARGS)[4]))
-#define ARG_int1 ((int)((ARGS)[1]))
-#define ARG_int2 ((int)((ARGS)[2]))
-#define ARG_int3 ((int)((ARGS)[3]))
-#define ARG_int4 ((int)((ARGS)[4]))
-#define ARG_int5 ((int)((ARGS)[5]))
-#define ARG_int6 ((int)((ARGS)[6]))
-#define ARG_func1 ((FuncDeclNode*)((ARGS)[1]))
-#define ARG_funcexp1 ((FuncExprNode*)((ARGS)[1]))
-#define ARG_registers1 ((Register*)((ARGS)[1]))
-#define ARG_regexp1 ((RegExp*)((ARGS)[1]))
-#define ARG_pni1 ((JSPropertyNameIterator*)((ARGS)[1]))
-#define ARG_instr1 ((Instruction*)((ARGS)[1]))
-#define ARG_instr2 ((Instruction*)((ARGS)[2]))
-#define ARG_instr3 ((Instruction*)((ARGS)[3]))
-#define ARG_instr4 ((Instruction*)((ARGS)[4]))
-#define ARG_instr5 ((Instruction*)((ARGS)[5]))
-#define ARG_instr6 ((Instruction*)((ARGS)[6]))
-
-#define CTI_RETURN_ADDRESS_SLOT ((ARGS)[-1])
+
+#define ARG_callFrame static_cast<CallFrame*>(ARGS[CTI_ARGS_callFrame])
+#define ARG_registerFile static_cast<RegisterFile*>(ARGS[CTI_ARGS_registerFile])
+#define ARG_exception static_cast<JSValue**>(ARGS[CTI_ARGS_exception])
+#define ARG_profilerReference static_cast<Profiler**>(ARGS[CTI_ARGS_profilerReference])
+#define ARG_globalData static_cast<JSGlobalData*>(ARGS[CTI_ARGS_globalData])
+
+#define ARG_setCallFrame(newCallFrame) (ARGS[CTI_ARGS_callFrame] = (newCallFrame))
+
+#define ARG_src1 static_cast<JSValue*>(ARGS[1])
+#define ARG_src2 static_cast<JSValue*>(ARGS[2])
+#define ARG_src3 static_cast<JSValue*>(ARGS[3])
+#define ARG_src4 static_cast<JSValue*>(ARGS[4])
+#define ARG_src5 static_cast<JSValue*>(ARGS[5])
+#define ARG_id1 static_cast<Identifier*>(ARGS[1])
+#define ARG_id2 static_cast<Identifier*>(ARGS[2])
+#define ARG_id3 static_cast<Identifier*>(ARGS[3])
+#define ARG_id4 static_cast<Identifier*>(ARGS[4])
+#define ARG_int1 reinterpret_cast<intptr_t>(ARGS[1])
+#define ARG_int2 reinterpret_cast<intptr_t>(ARGS[2])
+#define ARG_int3 reinterpret_cast<intptr_t>(ARGS[3])
+#define ARG_int4 reinterpret_cast<intptr_t>(ARGS[4])
+#define ARG_int5 reinterpret_cast<intptr_t>(ARGS[5])
+#define ARG_int6 reinterpret_cast<intptr_t>(ARGS[6])
+#define ARG_func1 static_cast<FuncDeclNode*>(ARGS[1])
+#define ARG_funcexp1 static_cast<FuncExprNode*>(ARGS[1])
+#define ARG_registers1 static_cast<Register*>(ARGS[1])
+#define ARG_regexp1 static_cast<RegExp*>(ARGS[1])
+#define ARG_pni1 static_cast<JSPropertyNameIterator*>(ARGS[1])
+#define ARG_instr1 static_cast<Instruction*>(ARGS[1])
+#define ARG_instr2 static_cast<Instruction*>(ARGS[2])
+#define ARG_instr3 static_cast<Instruction*>(ARGS[3])
+#define ARG_instr4 static_cast<Instruction*>(ARGS[4])
+#define ARG_instr5 static_cast<Instruction*>(ARGS[5])
+#define ARG_instr6 static_cast<Instruction*>(ARGS[6])
+
+#define CTI_RETURN_ADDRESS_SLOT (ARGS[-1])
 
 namespace JSC {
 
@@ -93,6 +94,7 @@ namespace JSC {
     class SimpleJumpTable;
     class StringJumpTable;
     class StructureIDChain;
+
     struct Instruction;
     struct OperandTypes;
     struct StructureStubInfo;
@@ -335,7 +337,9 @@ namespace JSC {
 
     private:
         CTI(Machine*, CallFrame*, CodeBlock*);
-        
+
+        static uintptr_t asInteger(JSValue*);
+
         bool isConstant(int src);
         JSValue* getConstant(CallFrame*, int src);
 
index 4e9e5ae..788f2d1 100644 (file)
@@ -719,7 +719,7 @@ RegisterID* CodeGenerator::emitEqualityOp(OpcodeID opcode, RegisterID* dst, Regi
             && src1->isTemporary()
             && static_cast<unsigned>(src2->index()) < m_codeBlock->constantRegisters.size()
             && m_codeBlock->constantRegisters[src2->index()].jsValue(m_scopeChain->globalObject()->globalExec())->isString()) {
-            const UString& value = static_cast<JSString*>(m_codeBlock->constantRegisters[src2->index()].jsValue(m_scopeChain->globalObject()->globalExec()))->value();
+            const UString& value = asString(m_codeBlock->constantRegisters[src2->index()].jsValue(m_scopeChain->globalObject()->globalExec()))->value();
             if (value == "undefined") {
                 rewindUnaryOp();
                 emitOpcode(op_is_undefined);
@@ -783,7 +783,7 @@ RegisterID* CodeGenerator::emitLoad(RegisterID* dst, double number)
     // Later we can do the extra work to handle that like the other cases.
     if (number == HashTraits<double>::emptyValue() || HashTraits<double>::isDeletedValue(number))
         return emitLoad(dst, jsNumber(globalData(), number));
-    JSValue*& valueInMap = m_numberMap.add(number, 0).first->second;
+    JSValue*& valueInMap = m_numberMap.add(number, noValue()).first->second;
     if (!valueInMap)
         valueInMap = jsNumber(globalData(), number);
     return emitLoad(dst, valueInMap);
@@ -821,9 +821,9 @@ RegisterID* CodeGenerator::emitUnexpectedLoad(RegisterID* dst, double d)
     return dst;
 }
 
-bool CodeGenerator::findScopedProperty(const Identifier& property, int& index, size_t& stackDepth, bool forWriting, JSValue*& globalObject)
+bool CodeGenerator::findScopedProperty(const Identifier& property, int& index, size_t& stackDepth, bool forWriting, JSObject*& globalObject)
 {
-    // Cases where we cannot statically optimise the lookup
+    // Cases where we cannot statically optimize the lookup.
     if (property == propertyNames().arguments || !canOptimizeNonLocals()) {
         stackDepth = 0;
         index = missingSymbolMarker();
@@ -866,7 +866,7 @@ bool CodeGenerator::findScopedProperty(const Identifier& property, int& index, s
             break;
     }
 
-    // Can't locate the property but we're able to avoid a few lookups
+    // Can't locate the property but we're able to avoid a few lookups.
     stackDepth = depth;
     index = missingSymbolMarker();
     JSObject* scope = *iter;
@@ -889,7 +889,7 @@ RegisterID* CodeGenerator::emitResolve(RegisterID* dst, const Identifier& proper
 {
     size_t depth = 0;
     int index = 0;
-    JSValue* globalObject = 0;
+    JSObject* globalObject = 0;
     if (!findScopedProperty(property, index, depth, false, globalObject) && !globalObject) {
         // We can't optimise at all :-(
         emitOpcode(op_resolve);
@@ -907,7 +907,7 @@ RegisterID* CodeGenerator::emitResolve(RegisterID* dst, const Identifier& proper
         m_codeBlock->structureIDInstructions.append(instructions().size());
         emitOpcode(op_resolve_global);
         instructions().append(dst->index());
-        instructions().append(static_cast<JSCell*>(globalObject));
+        instructions().append(globalObject);
         instructions().append(addConstant(property));
         instructions().append(0);
         instructions().append(0);
@@ -928,7 +928,7 @@ RegisterID* CodeGenerator::emitGetScopedVar(RegisterID* dst, size_t depth, int i
     if (globalObject) {
         emitOpcode(op_get_global_var);
         instructions().append(dst->index());
-        instructions().append(static_cast<JSCell*>(globalObject));
+        instructions().append(asCell(globalObject));
         instructions().append(index);
         return dst;
     }
@@ -944,7 +944,7 @@ RegisterID* CodeGenerator::emitPutScopedVar(size_t depth, int index, RegisterID*
 {
     if (globalObject) {
         emitOpcode(op_put_global_var);
-        instructions().append(static_cast<JSCell*>(globalObject));
+        instructions().append(asCell(globalObject));
         instructions().append(index);
         instructions().append(value->index());
         return value;
index 6aea7f0..d7be5f6 100644 (file)
@@ -102,7 +102,7 @@ namespace JSC {
         //
         // NB: depth does _not_ include the local scope.  eg. a depth of 0 refers
         // to the scope containing this codeblock.
-        bool findScopedProperty(const Identifier&, int& index, size_t& depth, bool forWriting, JSValue*& globalObject);
+        bool findScopedProperty(const Identifier&, int& index, size_t& depth, bool forWriting, JSObject*& globalObject);
 
         // Returns the register storing "this"
         RegisterID* thisRegister() { return &m_thisRegister; }
@@ -328,12 +328,13 @@ namespace JSC {
         void rewindUnaryOp();
 
         PassRefPtr<LabelID> emitComplexJumpScopes(LabelID* target, ControlFlowContext* topScope, ControlFlowContext* bottomScope);
+
         struct JSValueHashTraits : HashTraits<JSValue*> {
             static void constructDeletedValue(JSValue*& slot) { slot = JSImmediate::impossibleValue(); }
             static bool isDeletedValue(JSValue* value) { return value == JSImmediate::impossibleValue(); }
         };
 
-        typedef HashMap<JSValue*, unsigned, DefaultHash<JSValue*>::Hash, JSValueHashTraits> JSValueMap;
+        typedef HashMap<JSValue*, unsigned, PtrHash<JSValue*>, JSValueHashTraits> JSValueMap;
 
         struct IdentifierMapIndexHashTraits {
             typedef int TraitType;
index 85b0d1d..55f4ced 100644 (file)
@@ -40,7 +40,7 @@ JSPropertyNameIterator::~JSPropertyNameIterator()
 JSValue* JSPropertyNameIterator::toPrimitive(ExecState*, PreferredPrimitiveType) const
 {
     ASSERT_NOT_REACHED();
-    return 0;
+    return noValue();
 }
 
 bool JSPropertyNameIterator::getPrimitiveNumber(ExecState*, double&, JSValue*&)
index 17fead1..1853999 100644 (file)
@@ -97,7 +97,7 @@ inline JSPropertyNameIterator* JSPropertyNameIterator::create(ExecState* exec, J
 inline JSValue* JSPropertyNameIterator::next(ExecState* exec)
 {
     if (m_position == m_end)
-        return 0;
+        return noValue();
 
     if (m_data->cachedStructureID() == m_object->structureID() && structureIDChainsAreEqual(m_data->cachedPrototypeChain(), m_object->structureID()->cachedPrototypeChain()))
         return jsOwnedString(exec, (*m_position++).ustring());
@@ -108,7 +108,7 @@ inline JSValue* JSPropertyNameIterator::next(ExecState* exec)
         m_position++;
     } while (m_position != m_end);
 
-    return 0;
+    return noValue();
 }
 
 } // namespace JSC
index 5d44da0..7f8e445 100644 (file)
@@ -90,7 +90,7 @@ static void* op_call_indirect;
 
 #if ENABLE(CTI)
 
-ALWAYS_INLINE static Instruction* vPCForPC(CodeBlock* codeBlock, void* pc)
+static ALWAYS_INLINE Instruction* vPCForPC(CodeBlock* codeBlock, void* pc)
 {
     if (pc >= codeBlock->instructions.begin() && pc < codeBlock->instructions.end())
         return static_cast<Instruction*>(pc);
@@ -100,14 +100,14 @@ ALWAYS_INLINE static Instruction* vPCForPC(CodeBlock* codeBlock, void* pc)
     return codeBlock->instructions.begin() + vPCIndex;
 }
 
-#else // #ENABLE(CTI)
+#else // ENABLE(CTI)
 
-ALWAYS_INLINE static Instruction* vPCForPC(CodeBlock*, void* pc)
+static ALWAYS_INLINE Instruction* vPCForPC(CodeBlock*, void* pc)
 {
     return static_cast<Instruction*>(pc);
 }
 
-#endif // #ENABLE(CTI)
+#endif // ENABLE(CTI)
 
 // Returns the depth of the scope chain within a given call frame.
 static int depth(CodeBlock* codeBlock, ScopeChain& sc)
@@ -132,20 +132,20 @@ static ALWAYS_INLINE bool fastIsNumber(JSValue* value, double& arg)
 {
     if (JSImmediate::isNumber(value))
         arg = JSImmediate::getTruncatedInt32(value);
-    else if (Heap::isNumber(static_cast<JSCell*>(value)))
-        arg = static_cast<JSNumberCell*>(value)->value();
+    else if (LIKELY(!JSImmediate::isImmediate(value)) && LIKELY(Heap::isNumber(asCell(value))))
+        arg = asNumberCell(value)->value();
     else
         return false;
     return true;
 }
 
-// FIXME: Why doesn't JSValue::toInt32 have the Heap::isNumber optimization?
+// 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::isNumber(static_cast<JSCell*>(value)))
-        arg = static_cast<JSNumberCell*>(value)->toInt32();
+    else if (LIKELY(!JSImmediate::isImmediate(value)) && LIKELY(Heap::isNumber(asCell(value))))
+        arg = asNumberCell(value)->toInt32();
     else
         return false;
     return true;
@@ -159,8 +159,8 @@ static ALWAYS_INLINE bool fastToUInt32(JSValue* value, uint32_t& arg)
         bool scratch;
         arg = JSValue::toUInt32SlowCase(JSImmediate::getTruncatedInt32(value), scratch);
         return true;
-    } else if (Heap::isNumber(static_cast<JSCell*>(value)))
-        arg = static_cast<JSNumberCell*>(value)->toUInt32();
+    } else if (!JSImmediate::isImmediate(value) && Heap::isNumber(asCell(value)))
+        arg = asNumberCell(value)->toUInt32();
     else
         return false;
     return true;
@@ -178,7 +178,7 @@ static inline bool jsLess(CallFrame* callFrame, JSValue* v1, JSValue* v2)
 
     Machine* machine = callFrame->machine();
     if (machine->isJSString(v1) && machine->isJSString(v2))
-        return static_cast<const JSString*>(v1)->value() < static_cast<const JSString*>(v2)->value();
+        return asString(v1)->value() < asString(v2)->value();
 
     JSValue* p1;
     JSValue* p2;
@@ -188,7 +188,7 @@ static inline bool jsLess(CallFrame* callFrame, JSValue* v1, JSValue* v2)
     if (wasNotString1 | wasNotString2)
         return n1 < n2;
 
-    return static_cast<const JSString*>(p1)->value() < static_cast<const JSString*>(p2)->value();
+    return asString(p1)->value() < asString(p2)->value();
 }
 
 static inline bool jsLessEq(CallFrame* callFrame, JSValue* v1, JSValue* v2)
@@ -203,7 +203,7 @@ static inline bool jsLessEq(CallFrame* callFrame, JSValue* v1, JSValue* v2)
 
     Machine* machine = callFrame->machine();
     if (machine->isJSString(v1) && machine->isJSString(v2))
-        return !(static_cast<const JSString*>(v2)->value() < static_cast<const JSString*>(v1)->value());
+        return !(asString(v2)->value() < asString(v1)->value());
 
     JSValue* p1;
     JSValue* p2;
@@ -213,7 +213,7 @@ static inline bool jsLessEq(CallFrame* callFrame, JSValue* v1, JSValue* v2)
     if (wasNotString1 | wasNotString2)
         return n1 <= n2;
 
-    return !(static_cast<const JSString*>(p2)->value() < static_cast<const JSString*>(p1)->value());
+    return !(asString(p2)->value() < asString(p1)->value());
 }
 
 static NEVER_INLINE JSValue* jsAddSlowCase(CallFrame* callFrame, JSValue* v1, JSValue* v2)
@@ -252,7 +252,7 @@ static ALWAYS_INLINE JSValue* jsAdd(CallFrame* callFrame, JSValue* v1, JSValue*
     
     bool leftIsString = v1->isString();
     if (leftIsString && v2->isString()) {
-        RefPtr<UString::Rep> value = concatenate(static_cast<JSString*>(v1)->value().rep(), static_cast<JSString*>(v2)->value().rep());
+        RefPtr<UString::Rep> value = concatenate(asString(v1)->value().rep(), asString(v2)->value().rep());
         if (!value)
             return throwOutOfMemoryError(callFrame);
         return jsString(callFrame, value.release());
@@ -260,8 +260,8 @@ static ALWAYS_INLINE JSValue* jsAdd(CallFrame* callFrame, JSValue* v1, JSValue*
 
     if (rightIsNumber & leftIsString) {
         RefPtr<UString::Rep> value = JSImmediate::isImmediate(v2) ?
-            concatenate(static_cast<JSString*>(v1)->value().rep(), JSImmediate::getTruncatedInt32(v2)) :
-            concatenate(static_cast<JSString*>(v1)->value().rep(), right);
+            concatenate(asString(v1)->value().rep(), JSImmediate::getTruncatedInt32(v2)) :
+            concatenate(asString(v1)->value().rep(), right);
 
         if (!value)
             return throwOutOfMemoryError(callFrame);
@@ -285,10 +285,10 @@ static JSValue* jsTypeStringForValue(CallFrame* callFrame, JSValue* v)
     if (v->isObject()) {
         // Return "undefined" for objects that should be treated
         // as null when doing comparisons.
-        if (static_cast<JSObject*>(v)->structureID()->typeInfo().masqueradesAsUndefined())
+        if (asObject(v)->structureID()->typeInfo().masqueradesAsUndefined())
             return jsNontrivialString(callFrame, "undefined");
         CallData callData;
-        if (static_cast<JSObject*>(v)->getCallData(callData) != CallTypeNone)
+        if (asObject(v)->getCallData(callData) != CallTypeNone)
             return jsNontrivialString(callFrame, "function");
     }
     return jsNontrivialString(callFrame, "object");
@@ -299,14 +299,14 @@ static bool jsIsObjectType(JSValue* v)
     if (JSImmediate::isImmediate(v))
         return v->isNull();
 
-    JSType type = static_cast<JSCell*>(v)->structureID()->typeInfo().type();
+    JSType type = asCell(v)->structureID()->typeInfo().type();
     if (type == NumberType || type == StringType)
         return false;
     if (type == ObjectType) {
-        if (static_cast<JSObject*>(v)->structureID()->typeInfo().masqueradesAsUndefined())
+        if (asObject(v)->structureID()->typeInfo().masqueradesAsUndefined())
             return false;
         CallData callData;
-        if (static_cast<JSObject*>(v)->getCallData(callData) != CallTypeNone)
+        if (asObject(v)->getCallData(callData) != CallTypeNone)
             return false;
     }
     return true;
@@ -316,7 +316,7 @@ static bool jsIsFunctionType(JSValue* v)
 {
     if (v->isObject()) {
         CallData callData;
-        if (static_cast<JSObject*>(v)->getCallData(callData) != CallTypeNone)
+        if (asObject(v)->getCallData(callData) != CallTypeNone)
             return true;
     }
     return false;
@@ -423,7 +423,7 @@ NEVER_INLINE bool Machine::resolveGlobal(CallFrame* callFrame, Instruction* vPC,
     return false;
 }
 
-ALWAYS_INLINE static JSValue* inlineResolveBase(CallFrame* callFrame, Identifier& property, ScopeChainNode* scopeChain)
+static ALWAYS_INLINE JSValue* inlineResolveBase(CallFrame* callFrame, Identifier& property, ScopeChainNode* scopeChain)
 {
     ScopeChainIterator iter = scopeChain->begin();
     ScopeChainIterator next = iter;
@@ -443,7 +443,7 @@ ALWAYS_INLINE static JSValue* inlineResolveBase(CallFrame* callFrame, Identifier
     }
 
     ASSERT_NOT_REACHED();
-    return 0;
+    return noValue();
 }
 
 NEVER_INLINE void Machine::resolveBase(CallFrame* callFrame, Instruction* vPC)
@@ -593,12 +593,12 @@ NEVER_INLINE JSValue* Machine::callEval(CallFrame* callFrame, JSObject* thisObj,
     if (*profiler)
         (*profiler)->willExecute(callFrame, scopeChain->globalObject()->evalFunction());
 
-    UString programSource = static_cast<JSString*>(program)->value();
+    UString programSource = asString(program)->value();
 
     CodeBlock* codeBlock = callFrame->codeBlock();
     RefPtr<EvalNode> evalNode = codeBlock->evalCodeCache.get(callFrame, programSource, scopeChain, exceptionValue);
 
-    JSValue* result = 0;
+    JSValue* result = jsUndefined();
     if (evalNode)
         result = callFrame->globalData().machine->execute(evalNode.get(), callFrame, thisObj, callFrame->registers() - registerFile->start() + argv + 1 + RegisterFile::CallFrameHeaderSize, scopeChain, &exceptionValue);
 
@@ -630,15 +630,15 @@ Machine::Machine()
 
     JSArray* jsArray = new (storage) JSArray(JSArray::createStructureID(jsNull()));
     m_jsArrayVptr = jsArray->vptr();
-    static_cast<JSCell*>(jsArray)->~JSCell();
+    jsArray->~JSCell();
 
     JSString* jsString = new (storage) JSString(JSString::VPtrStealingHack);
     m_jsStringVptr = jsString->vptr();
-    static_cast<JSCell*>(jsString)->~JSCell();
+    jsString->~JSCell();
 
     JSFunction* jsFunction = new (storage) JSFunction(JSFunction::createStructureID(jsNull()));
     m_jsFunctionVptr = jsFunction->vptr();
-    static_cast<JSCell*>(jsFunction)->~JSCell();
+    jsFunction->~JSCell();
     
     fastFree(storage);
 }
@@ -802,7 +802,7 @@ NEVER_INLINE Instruction* Machine::throwException(CallFrame*& callFrame, JSValue
     
     CodeBlock* codeBlock = callFrame->codeBlock();
     if (exceptionValue->isObject()) {
-        JSObject* exception = static_cast<JSObject*>(exceptionValue);
+        JSObject* exception = asObject(exceptionValue);
         if (exception->isNotAnObjectErrorStub()) {
             exception = createNotAnObjectError(callFrame, static_cast<JSNotAnObjectErrorStub*>(exception), vPC, codeBlock);
             exceptionValue = exception;
@@ -1096,22 +1096,22 @@ NEVER_INLINE void Machine::debug(CallFrame* callFrame, DebugHookID debugHookID,
 
     switch (debugHookID) {
         case DidEnterCallFrame:
-            debugger->callEvent(DebuggerCallFrame(callFrame, 0), callFrame->codeBlock()->ownerNode->sourceID(), firstLine);
+            debugger->callEvent(callFrame, callFrame->codeBlock()->ownerNode->sourceID(), firstLine);
             return;
         case WillLeaveCallFrame:
-            debugger->returnEvent(DebuggerCallFrame(callFrame, 0), callFrame->codeBlock()->ownerNode->sourceID(), lastLine);
+            debugger->returnEvent(callFrame, callFrame->codeBlock()->ownerNode->sourceID(), lastLine);
             return;
         case WillExecuteStatement:
-            debugger->atStatement(DebuggerCallFrame(callFrame, 0), callFrame->codeBlock()->ownerNode->sourceID(), firstLine);
+            debugger->atStatement(callFrame, callFrame->codeBlock()->ownerNode->sourceID(), firstLine);
             return;
         case WillExecuteProgram:
-            debugger->willExecuteProgram(DebuggerCallFrame(callFrame, 0), callFrame->codeBlock()->ownerNode->sourceID(), firstLine);
+            debugger->willExecuteProgram(callFrame, callFrame->codeBlock()->ownerNode->sourceID(), firstLine);
             return;
         case DidExecuteProgram:
-            debugger->didExecuteProgram(DebuggerCallFrame(callFrame, 0), callFrame->codeBlock()->ownerNode->sourceID(), lastLine);
+            debugger->didExecuteProgram(callFrame, callFrame->codeBlock()->ownerNode->sourceID(), lastLine);
             return;
         case DidReachBreakpoint:
-            debugger->didReachBreakpoint(DebuggerCallFrame(callFrame, 0), callFrame->codeBlock()->ownerNode->sourceID(), lastLine);
+            debugger->didReachBreakpoint(callFrame, callFrame->codeBlock()->ownerNode->sourceID(), lastLine);
             return;
     }
 }
@@ -1172,7 +1172,7 @@ ALWAYS_INLINE JSValue* Machine::checkTimeout(JSGlobalObject* globalObject)
     if (!m_timeAtLastCheckTimeout) {
         // Suspicious amount of looping in a script -- start timing it
         m_timeAtLastCheckTimeout = currentTime;
-        return 0;
+        return noValue();
     }
     
     unsigned timeDiff = currentTime - m_timeAtLastCheckTimeout;
@@ -1198,7 +1198,7 @@ ALWAYS_INLINE JSValue* Machine::checkTimeout(JSGlobalObject* globalObject)
         resetTimeoutCheck();
     }
     
-    return 0;
+    return noValue();
 }
 
 NEVER_INLINE ScopeChainNode* Machine::createExceptionScope(CallFrame* callFrame, const Instruction* vPC)
@@ -1218,7 +1218,7 @@ static StructureIDChain* cachePrototypeChain(CallFrame* callFrame, StructureID*
     JSValue* prototype = structureID->prototypeForLookup(callFrame);
     if (JSImmediate::isImmediate(prototype))
         return 0;
-    RefPtr<StructureIDChain> chain = StructureIDChain::create(static_cast<JSObject*>(prototype)->structureID());
+    RefPtr<StructureIDChain> chain = StructureIDChain::create(asObject(prototype)->structureID());
     structureID->setCachedPrototypeChain(chain.release());
     return structureID->cachedPrototypeChain();
 }
@@ -1238,7 +1238,7 @@ NEVER_INLINE void Machine::tryCachePutByID(CallFrame* callFrame, CodeBlock* code
         return;
     }
     
-    JSCell* baseCell = static_cast<JSCell*>(baseValue);
+    JSCell* baseCell = asCell(baseValue);
     StructureID* structureID = baseCell->structureID();
 
     if (structureID->isDictionary()) {
@@ -1328,7 +1328,7 @@ NEVER_INLINE void Machine::tryCacheGetByID(CallFrame* callFrame, CodeBlock* code
         return;
     }
 
-    StructureID* structureID = static_cast<JSCell*>(baseValue)->structureID();
+    StructureID* structureID = asCell(baseValue)->structureID();
 
     if (structureID->isDictionary()) {
         vPC[0] = getOpcode(op_get_by_id_generic);
@@ -1362,14 +1362,14 @@ NEVER_INLINE void Machine::tryCacheGetByID(CallFrame* callFrame, CodeBlock* code
     if (slot.slotBase() == structureID->prototypeForLookup(callFrame)) {
         ASSERT(slot.slotBase()->isObject());
 
-        JSObject* baseObject = static_cast<JSObject*>(slot.slotBase());
+        JSObject* baseObject = asObject(slot.slotBase());
 
         // Heavy access to a prototype is a good indication that it's not being
         // used as a dictionary.
         if (baseObject->structureID()->isDictionary()) {
             RefPtr<StructureID> transition = StructureID::fromDictionaryTransition(baseObject->structureID());
             baseObject->setStructureID(transition.release());
-            static_cast<JSObject*>(baseValue)->structureID()->setCachedPrototypeChain(0);
+            asObject(baseValue)->structureID()->setCachedPrototypeChain(0);
         }
 
         vPC[0] = getOpcode(op_get_by_id_proto);
@@ -1381,7 +1381,7 @@ NEVER_INLINE void Machine::tryCacheGetByID(CallFrame* callFrame, CodeBlock* code
     }
 
     size_t count = 0;
-    JSObject* o = static_cast<JSObject*>(baseValue);
+    JSObject* o = asObject(baseValue);
     while (slot.slotBase() != o) {
         JSValue* v = o->structureID()->prototypeForLookup(callFrame);
 
@@ -1392,14 +1392,14 @@ NEVER_INLINE void Machine::tryCacheGetByID(CallFrame* callFrame, CodeBlock* code
             return;
         }
 
-        o = static_cast<JSObject*>(v);
+        o = asObject(v);
 
         // Heavy access to a prototype is a good indication that it's not being
         // used as a dictionary.
         if (o->structureID()->isDictionary()) {
             RefPtr<StructureID> transition = StructureID::fromDictionaryTransition(o->structureID());
             o->setStructureID(transition.release());
-            static_cast<JSObject*>(baseValue)->structureID()->setCachedPrototypeChain(0);
+            asObject(baseValue)->structureID()->setCachedPrototypeChain(0);
         }
 
         ++count;
@@ -1442,7 +1442,7 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
             op_throw_end_indirect = &&op_throw_end;
             op_call_indirect = &&op_call;
         #endif // HAVE(COMPUTED_GOTO)
-        return 0;
+        return noValue();
     }
 
 #if ENABLE(CTI)
@@ -1451,7 +1451,7 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
 #endif
 
     JSGlobalData* globalData = &callFrame->globalData();
-    JSValue* exceptionValue = 0;
+    JSValue* exceptionValue = noValue();
     Instruction* handlerVPC = 0;
 
     Instruction* vPC = callFrame->codeBlock()->instructions.begin();
@@ -1460,7 +1460,7 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
 
 #define VM_CHECK_EXCEPTION() \
     do { \
-        if (UNLIKELY(globalData->exception != 0)) { \
+        if (UNLIKELY(globalData->exception != noValue())) { \
             exceptionValue = globalData->exception; \
             goto vm_throw; \
         } \
@@ -1563,7 +1563,7 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
         JSValue* src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
         JSValue* src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
         if (JSImmediate::areBothImmediateNumbers(src1, src2))
-            callFrame[dst] = jsBoolean(reinterpret_cast<intptr_t>(src1) == reinterpret_cast<intptr_t>(src2));
+            callFrame[dst] = jsBoolean(src1 == src2);
         else {
             JSValue* result = jsBoolean(equalSlowCase(callFrame, src1, src2));
             VM_CHECK_EXCEPTION();
@@ -1628,7 +1628,7 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
             NEXT_OPCODE;
         }
         
-        callFrame[dst] = jsBoolean(JSImmediate::isImmediate(src) || !static_cast<JSCell*>(src)->asCell()->structureID()->typeInfo().masqueradesAsUndefined());
+        callFrame[dst] = jsBoolean(JSImmediate::isImmediate(src) || !asCell(src)->structureID()->typeInfo().masqueradesAsUndefined());
         ++vPC;
         NEXT_OPCODE;
     }
@@ -1643,7 +1643,7 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
         JSValue* src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
         JSValue* src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
         if (JSImmediate::areBothImmediate(src1, src2))
-            callFrame[dst] = jsBoolean(reinterpret_cast<intptr_t>(src1) == reinterpret_cast<intptr_t>(src2));
+            callFrame[dst] = jsBoolean(src1 == src2);
         else if (JSImmediate::isEitherImmediate(src1, src2) & (src1 != JSImmediate::zeroImmediate()) & (src2 != JSImmediate::zeroImmediate()))
             callFrame[dst] = jsBoolean(false);
         else
@@ -1664,7 +1664,7 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
         JSValue* src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
 
         if (JSImmediate::areBothImmediate(src1, src2))
-            callFrame[dst] = jsBoolean(reinterpret_cast<intptr_t>(src1) != reinterpret_cast<intptr_t>(src2));
+            callFrame[dst] = jsBoolean(src1 != src2);
         else if (JSImmediate::isEitherImmediate(src1, src2) & (src1 != JSImmediate::zeroImmediate()) & (src2 != JSImmediate::zeroImmediate()))
             callFrame[dst] = jsBoolean(true);
         else
@@ -2158,7 +2158,7 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
         if (isNotObject(callFrame, true, callFrame->codeBlock(), vPC, baseVal, exceptionValue))
             goto vm_throw;
 
-        JSObject* baseObj = static_cast<JSObject*>(baseVal);
+        JSObject* baseObj = asObject(baseVal);
         callFrame[dst] = jsBoolean(baseObj->structureID()->typeInfo().implementsHasInstance() ? baseObj->hasInstance(callFrame, callFrame[value].jsValue(callFrame), callFrame[baseProto].jsValue(callFrame)) : false);
 
         ++vPC;
@@ -2279,7 +2279,7 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
         if (isNotObject(callFrame, false, callFrame->codeBlock(), vPC, baseVal, exceptionValue))
             goto vm_throw;
 
-        JSObject* baseObj = static_cast<JSObject*>(baseVal);
+        JSObject* baseObj = asObject(baseVal);
 
         JSValue* propName = callFrame[property].jsValue(callFrame);
 
@@ -2499,12 +2499,12 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
         JSValue* baseValue = callFrame[base].jsValue(callFrame);
 
         if (LIKELY(!JSImmediate::isImmediate(baseValue))) {
-            JSCell* baseCell = static_cast<JSCell*>(baseValue);
+            JSCell* baseCell = asCell(baseValue);
             StructureID* structureID = vPC[4].u.structureID;
 
             if (LIKELY(baseCell->structureID() == structureID)) {
                 ASSERT(baseCell->isObject());
-                JSObject* baseObject = static_cast<JSObject*>(baseCell);
+                JSObject* baseObject = asObject(baseCell);
                 int dst = vPC[1].u.operand;
                 int offset = vPC[5].u.operand;
 
@@ -2530,12 +2530,12 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
         JSValue* baseValue = callFrame[base].jsValue(callFrame);
 
         if (LIKELY(!JSImmediate::isImmediate(baseValue))) {
-            JSCell* baseCell = static_cast<JSCell*>(baseValue);
+            JSCell* baseCell = asCell(baseValue);
             StructureID* structureID = vPC[4].u.structureID;
 
             if (LIKELY(baseCell->structureID() == structureID)) {
                 ASSERT(structureID->prototypeForLookup(callFrame)->isObject());
-                JSObject* protoObject = static_cast<JSObject*>(structureID->prototypeForLookup(callFrame));
+                JSObject* protoObject = asObject(structureID->prototypeForLookup(callFrame));
                 StructureID* protoStructureID = vPC[5].u.structureID;
 
                 if (LIKELY(protoObject->structureID() == protoStructureID)) {
@@ -2565,7 +2565,7 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
         JSValue* baseValue = callFrame[base].jsValue(callFrame);
 
         if (LIKELY(!JSImmediate::isImmediate(baseValue))) {
-            JSCell* baseCell = static_cast<JSCell*>(baseValue);
+            JSCell* baseCell = asCell(baseValue);
             StructureID* structureID = vPC[4].u.structureID;
 
             if (LIKELY(baseCell->structureID() == structureID)) {
@@ -2573,9 +2573,9 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
                 size_t count = vPC[6].u.operand;
                 RefPtr<StructureID>* end = it + count;
 
-                JSObject* baseObject = static_cast<JSObject*>(baseCell);
+                JSObject* baseObject = asObject(baseCell);
                 while (1) {
-                    baseObject = static_cast<JSObject*>(baseObject->structureID()->prototypeForLookup(callFrame));
+                    baseObject = asObject(baseObject->structureID()->prototypeForLookup(callFrame));
                     if (UNLIKELY(baseObject->structureID() != (*it).get()))
                         break;
 
@@ -2628,7 +2628,7 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
         JSValue* baseValue = callFrame[base].jsValue(callFrame);
         if (LIKELY(isJSArray(baseValue))) {
             int dst = vPC[1].u.operand;
-            callFrame[dst] = jsNumber(callFrame, static_cast<JSArray*>(baseValue)->length());
+            callFrame[dst] = jsNumber(callFrame, asArray(baseValue)->length());
             vPC += 8;
             NEXT_OPCODE;
         }
@@ -2648,7 +2648,7 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
         JSValue* baseValue = callFrame[base].jsValue(callFrame);
         if (LIKELY(isJSString(baseValue))) {
             int dst = vPC[1].u.operand;
-            callFrame[dst] = jsNumber(callFrame, static_cast<JSString*>(baseValue)->value().size());
+            callFrame[dst] = jsNumber(callFrame, asString(baseValue)->value().size());
             vPC += 8;
             NEXT_OPCODE;
         }
@@ -2697,24 +2697,24 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
         JSValue* baseValue = callFrame[base].jsValue(callFrame);
         
         if (LIKELY(!JSImmediate::isImmediate(baseValue))) {
-            JSCell* baseCell = static_cast<JSCell*>(baseValue);
+            JSCell* baseCell = asCell(baseValue);
             StructureID* oldStructureID = vPC[4].u.structureID;
             StructureID* newStructureID = vPC[5].u.structureID;
             
             if (LIKELY(baseCell->structureID() == oldStructureID)) {
                 ASSERT(baseCell->isObject());
-                JSObject* baseObject = static_cast<JSObject*>(baseCell);
+                JSObject* baseObject = asObject(baseCell);
 
                 RefPtr<StructureID>* it = vPC[6].u.structureIDChain->head();
 
-                JSObject* proto = static_cast<JSObject*>(baseObject->structureID()->prototypeForLookup(callFrame));
+                JSValue* proto = baseObject->structureID()->prototypeForLookup(callFrame);
                 while (!proto->isNull()) {
-                    if (UNLIKELY(proto->structureID() != (*it).get())) {
+                    if (UNLIKELY(asObject(proto)->structureID() != (*it).get())) {
                         uncachePutByID(callFrame->codeBlock(), vPC);
                         NEXT_OPCODE;
                     }
                     ++it;
-                    proto = static_cast<JSObject*>(proto->structureID()->prototypeForLookup(callFrame));
+                    proto = asObject(asObject(proto)->structureID()->prototypeForLookup(callFrame));
                 }
 
                 baseObject->transitionTo(newStructureID);
@@ -2747,12 +2747,12 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
         JSValue* baseValue = callFrame[base].jsValue(callFrame);
 
         if (LIKELY(!JSImmediate::isImmediate(baseValue))) {
-            JSCell* baseCell = static_cast<JSCell*>(baseValue);
+            JSCell* baseCell = asCell(baseValue);
             StructureID* structureID = vPC[4].u.structureID;
 
             if (LIKELY(baseCell->structureID() == structureID)) {
                 ASSERT(baseCell->isObject());
-                JSObject* baseObject = static_cast<JSObject*>(baseCell);
+                JSObject* baseObject = asObject(baseCell);
                 int value = vPC[3].u.operand;
                 unsigned offset = vPC[5].u.operand;
                 
@@ -2830,13 +2830,13 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
         bool isUInt32 = JSImmediate::getUInt32(subscript, i);
         if (LIKELY(isUInt32)) {
             if (isJSArray(baseValue)) {
-                JSArray* jsArray = static_cast<JSArray*>(baseValue);
+                JSArray* jsArray = asArray(baseValue);
                 if (jsArray->canGetIndex(i))
                     result = jsArray->getIndex(i);
                 else
                     result = jsArray->JSArray::get(callFrame, i);
-            } else if (isJSString(baseValue) && static_cast<JSString*>(baseValue)->canGetIndex(i))
-                result = static_cast<JSString*>(baseValue)->getIndex(&callFrame->globalData(), i);
+            } else if (isJSString(baseValue) && asString(baseValue)->canGetIndex(i))
+                result = asString(baseValue)->getIndex(&callFrame->globalData(), i);
             else
                 result = baseValue->get(callFrame, i);
         } else {
@@ -2872,7 +2872,7 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
         bool isUInt32 = JSImmediate::getUInt32(subscript, i);
         if (LIKELY(isUInt32)) {
             if (isJSArray(baseValue)) {
-                JSArray* jsArray = static_cast<JSArray*>(baseValue);
+                JSArray* jsArray = asArray(baseValue);
                 if (jsArray->canSetIndex(i))
                     jsArray->setIndex(i, callFrame[value].jsValue(callFrame));
                 else
@@ -3138,7 +3138,7 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
         if (!scrutinee->isString())
             vPC += defaultOffset;
         else {
-            UString::Rep* value = static_cast<JSString*>(scrutinee)->value().rep();
+            UString::Rep* value = asString(scrutinee)->value().rep();
             if (value->size() != 1)
                 vPC += defaultOffset;
             else
@@ -3161,7 +3161,7 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
         if (!scrutinee->isString())
             vPC += defaultOffset;
         else 
-            vPC += callFrame->codeBlock()->stringSwitchJumpTables[tableIndex].offsetForValue(static_cast<JSString*>(scrutinee)->value().rep(), defaultOffset);
+            vPC += callFrame->codeBlock()->stringSwitchJumpTables[tableIndex].offsetForValue(asString(scrutinee)->value().rep(), defaultOffset);
         NEXT_OPCODE;
     }
     BEGIN_OPCODE(op_new_func) {
@@ -3220,7 +3220,7 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
 
         ScopeChainNode* scopeChain = callFrame->scopeChain();
         if (baseVal == scopeChain->globalObject() && funcVal == scopeChain->globalObject()->evalFunction()) {
-            JSObject* thisObject = static_cast<JSObject*>(callFrame[callFrame->codeBlock()->thisRegister].jsValue(callFrame));
+            JSObject* thisObject = asObject(callFrame[callFrame->codeBlock()->thisRegister].jsValue(callFrame));
             JSValue* result = callEval(callFrame, thisObject, scopeChain, registerFile, firstArg, argCount, exceptionValue);
             if (exceptionValue)
                 goto vm_throw;
@@ -3310,10 +3310,10 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
                 goto vm_throw;
             }
 
-            callFrame->init(newCodeBlock, vPC + 1, callDataScopeChain, previousCallFrame, dst, argCount, static_cast<JSFunction*>(v));
+            callFrame->init(newCodeBlock, vPC + 1, callDataScopeChain, previousCallFrame, dst, argCount, asFunction(v));
     
             if (*enabledProfilerReference)
-                (*enabledProfilerReference)->willExecute(callFrame, static_cast<JSObject*>(v));
+                (*enabledProfilerReference)->willExecute(callFrame, asObject(v));
 
             vPC = newCodeBlock->instructions.begin();
 
@@ -3330,20 +3330,20 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
 
             ScopeChainNode* scopeChain = callFrame->scopeChain();
             CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + registerOffset);
-            newCallFrame->init(0, vPC + 1, scopeChain, callFrame, dst, argCount, static_cast<JSFunction*>(v));
+            newCallFrame->init(0, vPC + 1, scopeChain, callFrame, dst, argCount, 0);
 
             if (*enabledProfilerReference)
-                (*enabledProfilerReference)->willExecute(newCallFrame, static_cast<JSFunction*>(v));
+                (*enabledProfilerReference)->willExecute(newCallFrame, asObject(v));
 
             MACHINE_SAMPLING_callingHostFunction();
 
-            JSValue* returnValue = callData.native.function(newCallFrame, static_cast<JSFunction*>(v), thisValue, args);
+            JSValue* returnValue = callData.native.function(newCallFrame, asObject(v), thisValue, args);
             VM_CHECK_EXCEPTION();
 
             callFrame[dst] = returnValue;
 
             if (*enabledProfilerReference)
-                (*enabledProfilerReference)->didExecute(callFrame, static_cast<JSFunction*>(v));
+                (*enabledProfilerReference)->didExecute(callFrame, asObject(v));
 
             ++vPC;
             NEXT_OPCODE;
@@ -3357,10 +3357,8 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
     BEGIN_OPCODE(op_tear_off_activation) {
         int src = (++vPC)->u.operand;
         ASSERT(callFrame->codeBlock()->needsFullScopeChain);
-        JSActivation* activation = static_cast<JSActivation*>(callFrame[src].getJSValue());
-        ASSERT(activation->isObject(&JSActivation::info));
 
-        activation->copyRegisters(callFrame->optionalCalleeArguments());
+        asActivation(callFrame[src].getJSValue())->copyRegisters(callFrame->optionalCalleeArguments());
 
         ++vPC;
         NEXT_OPCODE;
@@ -3513,7 +3511,7 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
 
         if (constructType == ConstructTypeJS) {
             if (*enabledProfilerReference)
-                (*enabledProfilerReference)->willExecute(callFrame, static_cast<JSObject*>(v));
+                (*enabledProfilerReference)->willExecute(callFrame, asObject(v));
 
             ScopeChainNode* callDataScopeChain = constructData.js.scopeChain;
             FunctionBodyNode* functionBodyNode = constructData.js.functionBody;
@@ -3522,7 +3520,7 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
             StructureID* structure;
             JSValue* prototype = callFrame[constrProto].jsValue(callFrame);
             if (prototype->isObject())
-                structure = static_cast<JSObject*>(prototype)->inheritorID();
+                structure = asObject(prototype)->inheritorID();
             else
                 structure = callDataScopeChain->globalObject()->emptyObjectStructure();
             JSObject* newObject = new (globalData) JSObject(structure);
@@ -3538,10 +3536,10 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
                 goto vm_throw;
             }
 
-            callFrame->init(newCodeBlock, vPC + 1, callDataScopeChain, previousCallFrame, dst, argCount, static_cast<JSFunction*>(v));
+            callFrame->init(newCodeBlock, vPC + 1, callDataScopeChain, previousCallFrame, dst, argCount, asFunction(v));
     
             if (*enabledProfilerReference)
-                (*enabledProfilerReference)->didExecute(callFrame, static_cast<JSObject*>(v));
+                (*enabledProfilerReference)->didExecute(callFrame, asObject(v));
 
             vPC = newCodeBlock->instructions.begin();
 
@@ -3556,22 +3554,22 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
             ArgList args(callFrame->registers() + firstArg + 1, argCount - 1);
 
             ScopeChainNode* scopeChain = callFrame->scopeChain();
-            CallFrame::create(callFrame->registers() + registerOffset)->init(0, vPC + 1, scopeChain, callFrame, dst, argCount, static_cast<JSFunction*>(v));
+            CallFrame::create(callFrame->registers() + registerOffset)->init(0, vPC + 1, scopeChain, callFrame, dst, argCount, 0);
             callFrame = CallFrame::create(callFrame->registers() + registerOffset);
 
             if (*enabledProfilerReference)
-                (*enabledProfilerReference)->willExecute(callFrame, static_cast<JSObject*>(v));
+                (*enabledProfilerReference)->willExecute(callFrame, asObject(v));
 
             MACHINE_SAMPLING_callingHostFunction();
 
-            JSValue* returnValue = constructData.native.function(callFrame, static_cast<JSObject*>(v), args);
+            JSValue* returnValue = constructData.native.function(callFrame, asObject(v), args);
             callFrame = CallFrame::create(callFrame->registers() - registerOffset);
 
             VM_CHECK_EXCEPTION();
             callFrame[dst] = returnValue;
 
             if (*enabledProfilerReference)
-                (*enabledProfilerReference)->didExecute(callFrame, static_cast<JSObject*>(v));
+                (*enabledProfilerReference)->didExecute(callFrame, asObject(v));
 
             ++vPC;
             NEXT_OPCODE;
@@ -3715,7 +3713,7 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
         ASSERT(!globalData->exception);
         int ex = (++vPC)->u.operand;
         callFrame[ex] = exceptionValue;
-        exceptionValue = 0;
+        exceptionValue = noValue();
 
         ++vPC;
         NEXT_OPCODE;
@@ -3813,10 +3811,10 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
         int function = (++vPC)->u.operand;
 
         ASSERT(callFrame[base].jsValue(callFrame)->isObject());
-        JSObject* baseObj = static_cast<JSObject*>(callFrame[base].jsValue(callFrame));
+        JSObject* baseObj = asObject(callFrame[base].jsValue(callFrame));
         Identifier& ident = callFrame->codeBlock()->identifiers[property];
         ASSERT(callFrame[function].jsValue(callFrame)->isObject());
-        baseObj->defineGetter(callFrame, ident, static_cast<JSObject*>(callFrame[function].jsValue(callFrame)));
+        baseObj->defineGetter(callFrame, ident, asObject(callFrame[function].jsValue(callFrame)));
 
         ++vPC;
         NEXT_OPCODE;
@@ -3837,10 +3835,10 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
         int function = (++vPC)->u.operand;
 
         ASSERT(callFrame[base].jsValue(callFrame)->isObject());
-        JSObject* baseObj = static_cast<JSObject*>(callFrame[base].jsValue(callFrame));
+        JSObject* baseObj = asObject(callFrame[base].jsValue(callFrame));
         Identifier& ident = callFrame->codeBlock()->identifiers[property];
         ASSERT(callFrame[function].jsValue(callFrame)->isObject());
-        baseObj->defineSetter(callFrame, ident, static_cast<JSObject*>(callFrame[function].jsValue(callFrame)));
+        baseObj->defineSetter(callFrame, ident, asObject(callFrame[function].jsValue(callFrame)));
 
         ++vPC;
         NEXT_OPCODE;
@@ -3885,7 +3883,7 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
         NEXT_OPCODE;
     }
     vm_throw: {
-        globalData->exception = 0;
+        globalData->exception = noValue();
         if (!tickCount) {
             // The exceptionValue is a lie! (GCC produces bad code for reasons I 
             // cannot fathom if we don't assign to the exceptionValue before branching)
@@ -3952,7 +3950,7 @@ JSValue* Machine::retrieveCaller(CallFrame* callFrame, InternalFunction* functio
 
 void Machine::retrieveLastCaller(CallFrame* callFrame, int& lineNumber, intptr_t& sourceID, UString& sourceURL, JSValue*& function) const
 {
-    function = 0;
+    function = noValue();
     lineNumber = -1;
     sourceURL = UString();
 
@@ -3995,7 +3993,7 @@ NEVER_INLINE void Machine::tryCTICachePutByID(CallFrame* callFrame, CodeBlock* c
         return;
     }
     
-    JSCell* baseCell = static_cast<JSCell*>(baseValue);
+    JSCell* baseCell = asCell(baseValue);
     StructureID* structureID = baseCell->structureID();
 
     if (structureID->isDictionary()) {
@@ -4099,7 +4097,7 @@ NEVER_INLINE void Machine::tryCTICacheGetByID(CallFrame* callFrame, CodeBlock* c
         return;
     }
 
-    JSCell* baseCell = static_cast<JSCell*>(baseValue);
+    JSCell* baseCell = asCell(baseValue);
     StructureID* structureID = baseCell->structureID();
 
     if (structureID->isDictionary()) {
@@ -4133,14 +4131,14 @@ NEVER_INLINE void Machine::tryCTICacheGetByID(CallFrame* callFrame, CodeBlock* c
     if (slot.slotBase() == structureID->prototypeForLookup(callFrame)) {
         ASSERT(slot.slotBase()->isObject());
 
-        JSObject* slotBaseObject = static_cast<JSObject*>(slot.slotBase());
+        JSObject* slotBaseObject = asObject(slot.slotBase());
 
         // Heavy access to a prototype is a good indication that it's not being
         // used as a dictionary.
         if (slotBaseObject->structureID()->isDictionary()) {
             RefPtr<StructureID> transition = StructureID::fromDictionaryTransition(slotBaseObject->structureID());
             slotBaseObject->setStructureID(transition.release());
-            static_cast<JSObject*>(baseValue)->structureID()->setCachedPrototypeChain(0);
+            asObject(baseValue)->structureID()->setCachedPrototypeChain(0);
         }
 
         vPC[0] = getOpcode(op_get_by_id_proto);
@@ -4154,7 +4152,7 @@ NEVER_INLINE void Machine::tryCTICacheGetByID(CallFrame* callFrame, CodeBlock* c
     }
 
     size_t count = 0;
-    JSObject* o = static_cast<JSObject*>(baseValue);
+    JSObject* o = asObject(baseValue);
     while (slot.slotBase() != o) {
         JSValue* v = o->structureID()->prototypeForLookup(callFrame);
 
@@ -4166,14 +4164,14 @@ NEVER_INLINE void Machine::tryCTICacheGetByID(CallFrame* callFrame, CodeBlock* c
             return;
         }
 
-        o = static_cast<JSObject*>(v);
+        o = asObject(v);
 
         // Heavy access to a prototype is a good indication that it's not being
         // used as a dictionary.
         if (o->structureID()->isDictionary()) {
             RefPtr<StructureID> transition = StructureID::fromDictionaryTransition(o->structureID());
             o->setStructureID(transition.release());
-            static_cast<JSObject*>(baseValue)->structureID()->setCachedPrototypeChain(0);
+            asObject(baseValue)->structureID()->setCachedPrototypeChain(0);
         }
 
         ++count;
@@ -4194,20 +4192,15 @@ NEVER_INLINE void Machine::tryCTICacheGetByID(CallFrame* callFrame, CodeBlock* c
     CTI::compileGetByIdChain(this, callFrame, codeBlock, structureID, chain, count, slot.cachedOffset(), returnAddress);
 }
 
-
-NEVER_INLINE static void doSetReturnAddress(void** returnAddress, void* address)
-{
-    ctiSetReturnAddress(returnAddress, address);
-}
-
 #ifndef NDEBUG
+
 extern "C" {
 
 static void jscGeneratedNativeCode() 
 {
-    // when executing a CTI function (which might do an allocation), we hack the return address
+    // When executing a CTI function (which might do an allocation), we hack the return address
     // to pretend to be executing this function, to keep stack logging tools from blowing out
-    // memory
+    // memory.
 }
 
 }
@@ -4217,77 +4210,71 @@ struct StackHack {
     { 
         returnAddressLocation = location;
         savedReturnAddress = *returnAddressLocation;
-        doSetReturnAddress(returnAddressLocation, reinterpret_cast<void*>(jscGeneratedNativeCode));
+        ctiSetReturnAddress(returnAddressLocation, reinterpret_cast<void*>(jscGeneratedNativeCode));
     }
     ALWAYS_INLINE ~StackHack() 
     { 
-        doSetReturnAddress(returnAddressLocation, savedReturnAddress);
+        ctiSetReturnAddress(returnAddressLocation, savedReturnAddress);
     }
-    
+
     void** returnAddressLocation;
     void* savedReturnAddress;
 };
 
 #define CTI_STACK_HACK() StackHack stackHack(&CTI_RETURN_ADDRESS_SLOT)
-#define CTI_SET_RETURN_ADDRESS(addr) stackHack.savedReturnAddress = addr
+#define CTI_SET_RETURN_ADDRESS(address) stackHack.savedReturnAddress = address
 #define CTI_RETURN_ADDRESS stackHack.savedReturnAddress
 
 #else
 
 #define CTI_STACK_HACK() (void)0
-#define CTI_SET_RETURN_ADDRESS(addr) doSetReturnAddress(&CTI_RETURN_ADDRESS_SLOT, addr);
+#define CTI_SET_RETURN_ADDRESS(address) ctiSetReturnAddress(&CTI_RETURN_ADDRESS_SLOT, address);
 #define CTI_RETURN_ADDRESS CTI_RETURN_ADDRESS_SLOT
 
 #endif
 
+// The reason this is not inlined is to avoid having to do a PIC branch
+// to get the address of the ctiVMThrowTrampoline function. It's also
+// good to keep the code size down by leaving as much of the exception
+// handling code out of line as possible.
+static NEVER_INLINE void setUpThrowTrampolineReturnAddress(JSGlobalData* globalData, void*& returnAddress)
+{
+    ASSERT(globalData->exception);
+    globalData->throwReturnAddress = returnAddress;
+    ctiSetReturnAddress(&returnAddress, reinterpret_cast<void*>(ctiVMThrowTrampoline));
+}
+
 #define VM_THROW_EXCEPTION() \
     do { \
         VM_THROW_EXCEPTION_AT_END(); \
-        return 0; \
+        return noValue(); \
     } while (0)
 #define VM_THROW_EXCEPTION_2() \
     do { \
         VM_THROW_EXCEPTION_AT_END(); \
-        VoidPtrPair pair = { (void*)0, (void*)0, }; \
+        VoidPtrPair pair = { 0, 0 }; \
         return pair; \
     } while (0)
 #define VM_THROW_EXCEPTION_AT_END() \
-    do { \
-        ASSERT(ARG_globalData->exception); \
-        ARG_globalData->throwReturnAddress = CTI_RETURN_ADDRESS; \
-        CTI_SET_RETURN_ADDRESS(reinterpret_cast<void*>(ctiVMThrowTrampoline)); \
-    } while (0)
+    setUpThrowTrampolineReturnAddress(ARG_globalData, CTI_RETURN_ADDRESS)
 
 #define VM_CHECK_EXCEPTION() \
     do { \
-        if (UNLIKELY(ARG_globalData->exception != 0)) \
+        if (UNLIKELY(ARG_globalData->exception != noValue())) \
             VM_THROW_EXCEPTION(); \
     } while (0)
-#define VM_CHECK_EXCEPTION_ARG(exceptionValue) \
-    do { \
-        if (UNLIKELY((exceptionValue) != 0)) { \
-            ARG_globalData->exception = (exceptionValue); \
-            VM_THROW_EXCEPTION(); \
-        } \
-    } while (0)
 #define VM_CHECK_EXCEPTION_AT_END() \
     do { \
-        if (UNLIKELY(ARG_globalData->exception != 0)) \
+        if (UNLIKELY(ARG_globalData->exception != noValue())) \
             VM_THROW_EXCEPTION_AT_END(); \
     } while (0)
 #define VM_CHECK_EXCEPTION_VOID() \
     do { \
-        if (UNLIKELY(ARG_globalData->exception != 0)) { \
+        if (UNLIKELY(ARG_globalData->exception != noValue())) { \
             VM_THROW_EXCEPTION_AT_END(); \
             return; \
         } \
     } while (0)
-#define VM_CHECK_EXCEPTION_2() \
-    do { \
-        if (UNLIKELY(ARG_globalData->exception != 0)) { \
-            VM_THROW_EXCEPTION_2(); \
-        } \
-    } while (0)
 
 JSValue* Machine::cti_op_convert_this(CTI_ARGS)
 {
@@ -4328,7 +4315,7 @@ JSValue* Machine::cti_op_add(CTI_ARGS)
 
     bool leftIsString = v1->isString();
     if (leftIsString && v2->isString()) {
-        RefPtr<UString::Rep> value = concatenate(static_cast<JSString*>(v1)->value().rep(), static_cast<JSString*>(v2)->value().rep());
+        RefPtr<UString::Rep> value = concatenate(asString(v1)->value().rep(), asString(v2)->value().rep());
         if (UNLIKELY(!value)) {
             throwOutOfMemoryError(callFrame);
             VM_THROW_EXCEPTION();
@@ -4339,8 +4326,8 @@ JSValue* Machine::cti_op_add(CTI_ARGS)
 
     if (rightIsNumber & leftIsString) {
         RefPtr<UString::Rep> value = JSImmediate::isImmediate(v2) ?
-            concatenate(static_cast<JSString*>(v1)->value().rep(), JSImmediate::getTruncatedInt32(v2)) :
-            concatenate(static_cast<JSString*>(v1)->value().rep(), right);
+            concatenate(asString(v1)->value().rep(), JSImmediate::getTruncatedInt32(v2)) :
+            concatenate(asString(v1)->value().rep(), right);
 
         if (UNLIKELY(!value)) {
             throwOutOfMemoryError(callFrame);
@@ -4377,22 +4364,22 @@ void Machine::cti_timeout_check(CTI_ARGS)
     }
 }
 
+NEVER_INLINE void Machine::throwStackOverflowPreviousFrame(CallFrame* callFrame, JSGlobalData* globalData, void*& returnAddress)
+{
+    globalData->exception = createStackOverflowError(callFrame->callerFrame());
+    globalData->throwReturnAddress = callFrame->returnPC();
+    ctiSetReturnAddress(&returnAddress, reinterpret_cast<void*>(ctiVMThrowTrampoline));
+}
+
 void Machine::cti_register_file_check(CTI_ARGS)
 {
     CTI_STACK_HACK();
 
-    CallFrame* callFrame = ARG_callFrame;
-    CodeBlock* codeBlock = callFrame->codeBlock();
-    RegisterFile* registerFile = ARG_registerFile;
+    if (LIKELY(ARG_registerFile->grow(ARG_callFrame + ARG_callFrame->codeBlock()->numCalleeRegisters)))
+        return;
 
-    if (!registerFile->grow(callFrame + codeBlock->numCalleeRegisters)) {
-        CallFrame* callerFrame = callFrame->callerFrame();
-        ARG_setCallFrame(callerFrame);
-        ARG_globalData->exception = createStackOverflowError(callerFrame);
-        ASSERT(ARG_globalData->exception);
-        ARG_globalData->throwReturnAddress = callFrame->returnPC();
-        CTI_SET_RETURN_ADDRESS(reinterpret_cast<void*>(ctiVMThrowTrampoline));
-    }
+    ARG_setCallFrame(ARG_callFrame->callerFrame());
+    throwStackOverflowPreviousFrame(ARG_callFrame, ARG_globalData, CTI_RETURN_ADDRESS);
 }
 
 int Machine::cti_op_loop_if_less(CTI_ARGS)
@@ -4553,9 +4540,9 @@ JSValue* Machine::cti_op_instanceof(CTI_ARGS)
     JSValue* value = ARG_src1;
     JSValue* baseVal = ARG_src2;
     JSValue* proto = ARG_src3;
-    JSCell* valueCell = static_cast<JSCell*>(value);
-    JSCell* baseCell = static_cast<JSCell*>(baseVal);
-    JSCell* protoCell = static_cast<JSCell*>(proto);
+    JSCell* valueCell = asCell(value);
+    JSCell* baseCell = asCell(baseVal);
+    JSCell* protoCell = asCell(proto);
 
     // at least one of these checks must have failed to get to the slow case
     ASSERT(JSImmediate::isAnyImmediate(valueCell, baseCell, protoCell) 
@@ -4582,7 +4569,7 @@ JSValue* Machine::cti_op_instanceof(CTI_ARGS)
     if (!value->isObject())
         return jsBoolean(false);
 
-    JSValue* result = jsBoolean(static_cast<JSObject*>(baseCell)->hasInstance(callFrame, valueCell, protoCell));
+    JSValue* result = jsBoolean(asObject(baseCell)->hasInstance(callFrame, valueCell, protoCell));
     VM_CHECK_EXCEPTION_AT_END();
 
     return result;
@@ -4644,8 +4631,8 @@ VoidPtrPair Machine::cti_op_call_JSFunction(CTI_ARGS)
     ASSERT(ARG_src1->getCallData(callData) == CallTypeJS);
 #endif
 
-    ScopeChainNode* callDataScopeChain = static_cast<JSFunction*>(ARG_src1)->m_scopeChain.node();
-    CodeBlock* newCodeBlock = &static_cast<JSFunction*>(ARG_src1)->m_body->byteCode(callDataScopeChain);
+    ScopeChainNode* callDataScopeChain = asFunction(ARG_src1)->m_scopeChain.node();
+    CodeBlock* newCodeBlock = &asFunction(ARG_src1)->m_body->byteCode(callDataScopeChain);
     CallFrame* callFrame = ARG_callFrame;
     size_t registerOffset = ARG_int2;
     int argCount = ARG_int3;
@@ -4739,23 +4726,23 @@ JSValue* Machine::cti_op_call_NotJSFunction(CTI_ARGS)
         CallFrame* previousCallFrame = ARG_callFrame;
         CallFrame* callFrame = CallFrame::create(previousCallFrame->registers() + registerOffset);
 
-        callFrame->init(0, ARG_instr4 + 1, previousCallFrame->scopeChain(), previousCallFrame, 0, argCount, static_cast<JSFunction*>(funcVal));
+        callFrame->init(0, ARG_instr4 + 1, previousCallFrame->scopeChain(), previousCallFrame, 0, argCount, 0);
         ARG_setCallFrame(callFrame);
 
         if (*ARG_profilerReference)
-            (*ARG_profilerReference)->willExecute(callFrame, static_cast<JSFunction*>(funcVal));
+            (*ARG_profilerReference)->willExecute(callFrame, asObject(funcVal));
 
         Register* argv = ARG_callFrame->registers() - RegisterFile::CallFrameHeaderSize - argCount;
         ArgList argList(argv + 1, argCount - 1);
 
         CTI_MACHINE_SAMPLING_callingHostFunction();
 
-        JSValue* returnValue = callData.native.function(callFrame, static_cast<JSFunction*>(funcVal), argv[0].jsValue(callFrame), argList);
+        JSValue* returnValue = callData.native.function(callFrame, asObject(funcVal), argv[0].jsValue(callFrame), argList);
         ARG_setCallFrame(previousCallFrame);
         VM_CHECK_EXCEPTION();
 
         if (*ARG_profilerReference)
-            (*ARG_profilerReference)->didExecute(previousCallFrame, static_cast<JSFunction*>(funcVal));
+            (*ARG_profilerReference)->didExecute(previousCallFrame, asObject(funcVal));
 
         return returnValue;
     }
@@ -4787,8 +4774,7 @@ void Machine::cti_op_tear_off_activation(CTI_ARGS)
     CTI_STACK_HACK();
 
     ASSERT(ARG_callFrame->codeBlock()->needsFullScopeChain);
-    ASSERT(ARG_src1->isObject(&JSActivation::info));
-    static_cast<JSActivation*>(ARG_src1)->copyRegisters(ARG_callFrame->optionalCalleeArguments());
+    asActivation(ARG_src1)->copyRegisters(ARG_callFrame->optionalCalleeArguments());
 }
 
 void Machine::cti_op_tear_off_arguments(CTI_ARGS)
@@ -4875,7 +4861,7 @@ VoidPtrPair Machine::cti_op_construct_JSConstruct(CTI_ARGS)
 
     CallFrame* callFrame = ARG_callFrame;
 
-    JSFunction* constructor = static_cast<JSFunction*>(ARG_src1);
+    JSFunction* constructor = asFunction(ARG_src1);
     int registerOffset = ARG_int2;
     int argCount = ARG_int3;
     JSValue* constrProtoVal = ARG_src5;
@@ -4892,7 +4878,7 @@ VoidPtrPair Machine::cti_op_construct_JSConstruct(CTI_ARGS)
 
     StructureID* structure;
     if (constrProtoVal->isObject())
-        structure = static_cast<JSObject*>(constrProtoVal)->inheritorID();
+        structure = asObject(constrProtoVal)->inheritorID();
     else
         structure = callDataScopeChain->globalObject()->emptyObjectStructure();
     JSObject* newObject = new (ARG_globalData) JSObject(structure);
@@ -4944,7 +4930,7 @@ JSValue* Machine::cti_op_construct_NotJSConstruct(CTI_ARGS)
     ConstructData constructData;
     ConstructType constructType = constrVal->getConstructData(constructData);
 
-    JSObject* constructor = static_cast<JSObject*>(constrVal);
+    JSObject* constructor = asObject(constrVal);
 
     if (constructType == ConstructTypeHost) {
         if (*ARG_profilerReference)
@@ -4985,13 +4971,13 @@ JSValue* Machine::cti_op_get_by_val(CTI_ARGS)
     bool isUInt32 = JSImmediate::getUInt32(subscript, i);
     if (LIKELY(isUInt32)) {
         if (machine->isJSArray(baseValue)) {
-            JSArray* jsArray = static_cast<JSArray*>(baseValue);
+            JSArray* jsArray = asArray(baseValue);
             if (jsArray->canGetIndex(i))
                 result = jsArray->getIndex(i);
             else
                 result = jsArray->JSArray::get(callFrame, i);
-        } else if (machine->isJSString(baseValue) && static_cast<JSString*>(baseValue)->canGetIndex(i))
-            result = static_cast<JSString*>(baseValue)->getIndex(ARG_globalData, i);
+        } else if (machine->isJSString(baseValue) && asString(baseValue)->canGetIndex(i))
+            result = asString(baseValue)->getIndex(ARG_globalData, i);
         else
             result = baseValue->get(callFrame, i);
     } else {
@@ -5034,7 +5020,7 @@ VoidPtrPair Machine::cti_op_resolve_func(CTI_ARGS)
             JSValue* result = slot.getValue(callFrame, ident);
             VM_CHECK_EXCEPTION_AT_END();
 
-            VoidPtrPair pair = { thisObj, result };
+            VoidPtrPair pair = { thisObj, asPointer(result) };
             return pair;
         }
         ++iter;
@@ -5081,7 +5067,7 @@ void Machine::cti_op_put_by_val(CTI_ARGS)
     bool isUInt32 = JSImmediate::getUInt32(subscript, i);
     if (LIKELY(isUInt32)) {
         if (machine->isJSArray(baseValue)) {
-            JSArray* jsArray = static_cast<JSArray*>(baseValue);
+            JSArray* jsArray = asArray(baseValue);
             if (jsArray->canSetIndex(i))
                 jsArray->setIndex(i, value);
             else
@@ -5112,7 +5098,7 @@ void Machine::cti_op_put_by_val_array(CTI_ARGS)
     ASSERT(ARG_globalData->machine->isJSArray(baseValue));
 
     if (LIKELY(i >= 0))
-        static_cast<JSArray*>(baseValue)->JSArray::put(callFrame, i, value);
+        asArray(baseValue)->JSArray::put(callFrame, i, value);
     else {
         Identifier property(callFrame, JSImmediate::from(i)->toString(callFrame));
         // FIXME: can toString throw an exception here?
@@ -5210,7 +5196,7 @@ JSValue* Machine::cti_op_resolve_global(CTI_ARGS)
     CTI_STACK_HACK();
 
     CallFrame* callFrame = ARG_callFrame;
-    JSGlobalObject* globalObject = static_cast<JSGlobalObject*>(ARG_src1);
+    JSGlobalObject* globalObject = asGlobalObject(ARG_src1);
     Identifier& ident = *ARG_id2;
     Instruction* vPC = ARG_instr3;
     ASSERT(globalObject->isGlobalObject());
@@ -5313,9 +5299,9 @@ VoidPtrPair Machine::cti_op_post_inc(CTI_ARGS)
     CallFrame* callFrame = ARG_callFrame;
 
     JSValue* number = v->toJSNumber(callFrame);
-    VM_CHECK_EXCEPTION_2();
+    VM_CHECK_EXCEPTION_AT_END();
 
-    VoidPtrPair pair = { number, jsNumber(ARG_globalData, number->uncheckedGetNumber() + 1) };
+    VoidPtrPair pair = { asPointer(number), asPointer(jsNumber(ARG_globalData, number->uncheckedGetNumber() + 1)) };
     return pair;
 }
 
@@ -5431,7 +5417,7 @@ VoidPtrPair Machine::cti_op_resolve_with_base(CTI_ARGS)
             JSValue* result = slot.getValue(callFrame, ident);
             VM_CHECK_EXCEPTION_AT_END();
 
-            VoidPtrPair pair = { base, result };
+            VoidPtrPair pair = { base, asPointer(result) };
             return pair;
         }
         ++iter;
@@ -5499,9 +5485,9 @@ VoidPtrPair Machine::cti_op_post_dec(CTI_ARGS)
     CallFrame* callFrame = ARG_callFrame;
 
     JSValue* number = v->toJSNumber(callFrame);
-    VM_CHECK_EXCEPTION_2();
+    VM_CHECK_EXCEPTION_AT_END();
 
-    VoidPtrPair pair = { number, jsNumber(ARG_globalData, number->uncheckedGetNumber() - 1) };
+    VoidPtrPair pair = { asPointer(number), asPointer(jsNumber(ARG_globalData, number->uncheckedGetNumber() - 1)) };
     return pair;
 }
 
@@ -5575,17 +5561,20 @@ JSValue* Machine::cti_op_call_eval(CTI_ARGS)
     JSValue* baseVal = ARG_src5;
 
     if (baseVal == scopeChain->globalObject() && funcVal == scopeChain->globalObject()->evalFunction()) {
-        JSObject* thisObject = static_cast<JSObject*>(callFrame[codeBlock->thisRegister].jsValue(callFrame));
-        JSValue* exceptionValue = 0;
+        JSObject* thisObject = asObject(callFrame[codeBlock->thisRegister].jsValue(callFrame));
+        JSValue* exceptionValue = noValue();
         JSValue* result = machine->callEval(callFrame, thisObject, scopeChain, registerFile, registerOffset - RegisterFile::CallFrameHeaderSize - argCount, argCount, exceptionValue);
-        VM_CHECK_EXCEPTION_ARG(exceptionValue);
+        if (UNLIKELY(exceptionValue != noValue())) {
+            ARG_globalData->exception = exceptionValue();
+            VM_THROW_EXCEPTION_AT_END();
+        }
         return result;
     }
 
     return JSImmediate::impossibleValue();
 }
 
-void* Machine::cti_op_throw(CTI_ARGS)
+JSValue* Machine::cti_op_throw(CTI_ARGS)
 {
     CTI_STACK_HACK();
 
@@ -5753,7 +5742,7 @@ JSValue* Machine::cti_op_in(CTI_ARGS)
     }
 
     JSValue* propName = ARG_src1;
-    JSObject* baseObj = static_cast<JSObject*>(baseVal);
+    JSObject* baseObj = asObject(baseVal);
 
     uint32_t i;
     if (propName->getUInt32(i))
@@ -5827,7 +5816,7 @@ void* Machine::cti_op_switch_char(CTI_ARGS)
     void* result = codeBlock->characterSwitchJumpTables[tableIndex].ctiDefault;
 
     if (scrutinee->isString()) {
-        UString::Rep* value = static_cast<JSString*>(scrutinee)->value().rep();
+        UString::Rep* value = asString(scrutinee)->value().rep();
         if (value->size() == 1)
             result = codeBlock->characterSwitchJumpTables[tableIndex].ctiForValue(value->data()[0]);
     }
@@ -5847,7 +5836,7 @@ void* Machine::cti_op_switch_string(CTI_ARGS)
     void* result = codeBlock->stringSwitchJumpTables[tableIndex].ctiDefault;
 
     if (scrutinee->isString()) {
-        UString::Rep* value = static_cast<JSString*>(scrutinee)->value().rep();
+        UString::Rep* value = asString(scrutinee)->value().rep();
         result = codeBlock->stringSwitchJumpTables[tableIndex].ctiForValue(value);
     }
 
@@ -5886,10 +5875,10 @@ void Machine::cti_op_put_getter(CTI_ARGS)
     CallFrame* callFrame = ARG_callFrame;
 
     ASSERT(ARG_src1->isObject());
-    JSObject* baseObj = static_cast<JSObject*>(ARG_src1);
+    JSObject* baseObj = asObject(ARG_src1);
     Identifier& ident = *ARG_id2;
     ASSERT(ARG_src3->isObject());
-    baseObj->defineGetter(callFrame, ident, static_cast<JSObject*>(ARG_src3));
+    baseObj->defineGetter(callFrame, ident, asObject(ARG_src3));
 }
 
 void Machine::cti_op_put_setter(CTI_ARGS)
@@ -5899,10 +5888,10 @@ void Machine::cti_op_put_setter(CTI_ARGS)
     CallFrame* callFrame = ARG_callFrame;
 
     ASSERT(ARG_src1->isObject());
-    JSObject* baseObj = static_cast<JSObject*>(ARG_src1);
+    JSObject* baseObj = asObject(ARG_src1);
     Identifier& ident = *ARG_id2;
     ASSERT(ARG_src3->isObject());
-    baseObj->defineSetter(callFrame, ident, static_cast<JSObject*>(ARG_src3));
+    baseObj->defineSetter(callFrame, ident, asObject(ARG_src3));
 }
 
 JSValue* Machine::cti_op_new_error(CTI_ARGS)
@@ -5931,7 +5920,7 @@ void Machine::cti_op_debug(CTI_ARGS)
     ARG_globalData->machine->debug(callFrame, static_cast<DebugHookID>(debugHookID), firstLine, lastLine);
 }
 
-void* Machine::cti_vm_throw(CTI_ARGS)
+JSValue* Machine::cti_vm_throw(CTI_ARGS)
 {
     CTI_STACK_HACK();
 
@@ -5943,7 +5932,7 @@ void* Machine::cti_vm_throw(CTI_ARGS)
 
     JSValue* exceptionValue = ARG_globalData->exception;
     ASSERT(exceptionValue);
-    ARG_globalData->exception = 0;
+    ARG_globalData->exception = noValue();
 
     Instruction* handlerVPC = ARG_globalData->machine->throwException(callFrame, exceptionValue, codeBlock->instructions.begin() + vPCIndex, false);
 
@@ -5959,10 +5948,15 @@ void* Machine::cti_vm_throw(CTI_ARGS)
     return exceptionValue;
 }
 
+#undef CTI_RETURN_ADDRESS
+#undef CTI_SET_RETURN_ADDRESS
+#undef CTI_STACK_HACK
 #undef VM_CHECK_EXCEPTION
-#undef VM_CHECK_EXCEPTION_ARG
 #undef VM_CHECK_EXCEPTION_AT_END
 #undef VM_CHECK_EXCEPTION_VOID
+#undef VM_THROW_EXCEPTION
+#undef VM_THROW_EXCEPTION_2
+#undef VM_THROW_EXCEPTION_AT_END
 
 #endif // ENABLE(CTI)
 
index ce77386..b45743d 100644 (file)
@@ -228,7 +228,7 @@ namespace JSC {
         static JSValue* SFX_CALL cti_op_new_regexp(CTI_ARGS);
         static JSValue* SFX_CALL cti_op_bitor(CTI_ARGS);
         static JSValue* SFX_CALL cti_op_call_eval(CTI_ARGS);
-        static void* SFX_CALL cti_op_throw(CTI_ARGS);
+        static JSValue* SFX_CALL cti_op_throw(CTI_ARGS);
         static JSPropertyNameIterator* SFX_CALL cti_op_get_pnames(CTI_ARGS);
         static JSValue* SFX_CALL cti_op_next_pname(CTI_ARGS);
         static void SFX_CALL cti_op_push_scope(CTI_ARGS);
@@ -259,7 +259,7 @@ namespace JSC {
         static void SFX_CALL cti_op_call_profiler(CTI_ARGS);
         static void SFX_CALL cti_op_ret_profiler(CTI_ARGS);
 
-        static void* SFX_CALL cti_vm_throw(CTI_ARGS);
+        static JSValue* SFX_CALL cti_vm_throw(CTI_ARGS);
         static void* SFX_CALL cti_vm_compile(CTI_ARGS);
         static void* SFX_CALL cti_vm_lazyLinkCall(CTI_ARGS);
         static JSValue* SFX_CALL cti_op_push_activation(CTI_ARGS);
@@ -309,6 +309,8 @@ namespace JSC {
         void uncachePutByID(CodeBlock*, Instruction* vPC);
 
 #if ENABLE(CTI)
+        static void throwStackOverflowPreviousFrame(CallFrame*, JSGlobalData*, void*& returnAddress);
+
         void tryCTICacheGetByID(CallFrame*, CodeBlock*, void* returnAddress, JSValue* baseValue, const Identifier& propertyName, const PropertySlot&);
         void tryCTICachePutByID(CallFrame*, CodeBlock*, void* returnAddress, JSValue* baseValue, const PutPropertySlot&);
 
index 7b5a3bd..c1fee3a 100644 (file)
@@ -40,15 +40,12 @@ namespace JSC {
     class JSActivation;
     class JSFunction;
     class JSPropertyNameIterator;
-    class JSValue;
     class ScopeChainNode;
 
     struct Instruction;
 
     typedef ExecState CallFrame;
 
-    static JSValue* const nullJSValue = 0;
-
     class Register {
     public:
         Register();
@@ -138,7 +135,7 @@ namespace JSC {
     {
 #ifndef NDEBUG
         SET_TYPE(EmptyType);
-        *this = nullJSValue;
+        *this = noValue();
 #endif
     }
 
@@ -147,7 +144,7 @@ namespace JSC {
         SET_TYPE(ValueType);
         u.value = v;
     }
-    
+
     // This function is scaffolding for legacy clients. It will eventually go away.
     ALWAYS_INLINE JSValue* Register::jsValue(CallFrame*) const
     {
index 2fef272..44446aa 100644 (file)
@@ -30,8 +30,6 @@
 #include <wtf/Vector.h>
 
 namespace JSC {
-
-    class JSValue;
     
     class ArgList : Noncopyable {
     private:
index 151f221..b44525c 100644 (file)
@@ -91,6 +91,14 @@ namespace JSC {
         OwnPtr<ArgumentsData> d;
     };
 
+    Arguments* asArguments(JSValue*);
+
+    inline Arguments* asArguments(JSValue* value)
+    {
+        ASSERT(asObject(value)->inherits(&Arguments::info));
+        return static_cast<Arguments*>(asObject(value));
+    }
+
     ALWAYS_INLINE void Arguments::getArgumentsData(CallFrame* callFrame, JSFunction*& function, ptrdiff_t& firstParameterIndex, Register*& argv, int& argc)
     {
         function = callFrame->callee();
index 8dcfba2..5280784 100644 (file)
@@ -101,7 +101,6 @@ bool ArrayPrototype::getOwnPropertySlot(ExecState* exec, const Identifier& prope
     return getStaticFunctionSlot<JSArray>(exec, ExecState::arrayTable(exec), this, propertyName, slot);
 }
 
-
 // ------------------------------ Array Functions ----------------------------
 
 // Helper function
@@ -109,7 +108,7 @@ static JSValue* getProperty(ExecState* exec, JSObject* obj, unsigned index)
 {
     PropertySlot slot(obj);
     if (!obj->getPropertySlot(exec, index, slot))
-        return 0;
+        return noValue();
     return slot.getValue(exec, index);
 }
 
@@ -123,7 +122,7 @@ JSValue* arrayProtoFuncToString(ExecState* exec, JSObject*, JSValue* thisValue,
 {
     if (!thisValue->isObject(&JSArray::info))
         return throwError(exec, TypeError);
-    JSObject* thisObj = static_cast<JSArray*>(thisValue);
+    JSObject* thisObj = asArray(thisValue);
 
     HashSet<JSObject*>& arrayVisitedElements = exec->globalData().arrayVisitedElements;
     if (arrayVisitedElements.size() > MaxReentryDepth)
@@ -167,7 +166,7 @@ JSValue* arrayProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValue* thisV
 {
     if (!thisValue->isObject(&JSArray::info))
         return throwError(exec, TypeError);
-    JSObject* thisObj = static_cast<JSArray*>(thisValue);
+    JSObject* thisObj = asArray(thisValue);
 
     HashSet<JSObject*>& arrayVisitedElements = exec->globalData().arrayVisitedElements;
     if (arrayVisitedElements.size() > MaxReentryDepth)
@@ -270,7 +269,7 @@ JSValue* arrayProtoFuncConcat(ExecState* exec, JSObject*, JSValue* thisValue, co
     ArgList::const_iterator end = args.end();
     while (1) {
         if (curArg->isObject(&JSArray::info)) {
-            JSArray* curArray = static_cast<JSArray*>(curArg);
+            JSArray* curArray = asArray(curArg);
             unsigned length = curArray->length();
             for (unsigned k = 0; k < length; ++k) {
                 if (JSValue* v = getProperty(exec, curArray, k))
@@ -293,10 +292,10 @@ JSValue* arrayProtoFuncConcat(ExecState* exec, JSObject*, JSValue* thisValue, co
 JSValue* arrayProtoFuncPop(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
 {
     if (exec->machine()->isJSArray(thisValue))
-        return static_cast<JSArray*>(thisValue)->pop();
+        return asArray(thisValue)->pop();
 
     JSObject* thisObj = thisValue->toThisObject(exec);
-    JSValue* result = 0;
+    JSValue* result;
     unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
     if (length == 0) {
         putProperty(exec, thisObj, exec->propertyNames().length, jsNumber(exec, length));
@@ -312,7 +311,7 @@ JSValue* arrayProtoFuncPop(ExecState* exec, JSObject*, JSValue* thisValue, const
 JSValue* arrayProtoFuncPush(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
     if (exec->machine()->isJSArray(thisValue) && args.size() == 1) {
-        JSArray* array = static_cast<JSArray*>(thisValue);
+        JSArray* array = asArray(thisValue);
         array->push(exec, args.begin()->jsValue(exec));
         return jsNumber(exec, array->length());
     }
@@ -353,7 +352,7 @@ JSValue* arrayProtoFuncReverse(ExecState* exec, JSObject*, JSValue* thisValue, c
 JSValue* arrayProtoFuncShift(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
 {
     JSObject* thisObj = thisValue->toThisObject(exec);
-    JSValue* result = 0;
+    JSValue* result;
 
     unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
     if (length == 0) {
@@ -428,9 +427,9 @@ JSValue* arrayProtoFuncSort(ExecState* exec, JSObject*, JSValue* thisValue, cons
 
     if (thisObj->classInfo() == &JSArray::info) {
         if (callType != CallTypeNone)
-            static_cast<JSArray*>(thisObj)->sort(exec, function, callType, callData);
+            asArray(thisObj)->sort(exec, function, callType, callData);
         else
-            static_cast<JSArray*>(thisObj)->sort(exec);
+            asArray(thisObj)->sort(exec);
         return thisObj;
     }
 
index 6f432e6..5963b28 100644 (file)
@@ -33,6 +33,14 @@ namespace JSC {
         static const ClassInfo info;
     };
 
+    BooleanObject* asBooleanObject(JSValue*);
+
+    inline BooleanObject* asBooleanObject(JSValue* value)
+    {
+        ASSERT(asObject(value)->inherits(&BooleanObject::info));
+        return static_cast<BooleanObject*>(asObject(value));
+    }
+
 } // namespace JSC
 
 #endif // BooleanObject_h
index 8eed888..9299d78 100644 (file)
@@ -61,10 +61,10 @@ JSValue* booleanProtoFuncToString(ExecState* exec, JSObject*, JSValue* thisValue
     if (!thisValue->isObject(&BooleanObject::info))
         return throwError(exec, TypeError);
 
-    if (static_cast<BooleanObject*>(thisValue)->internalValue() == jsBoolean(false))
+    if (asBooleanObject(thisValue)->internalValue() == jsBoolean(false))
         return jsNontrivialString(exec, "false");
 
-    ASSERT(static_cast<BooleanObject*>(thisValue)->internalValue() == jsBoolean(true));
+    ASSERT(asBooleanObject(thisValue)->internalValue() == jsBoolean(true));
     return jsNontrivialString(exec, "true");
 }
 
@@ -76,7 +76,7 @@ JSValue* booleanProtoFuncValueOf(ExecState* exec, JSObject*, JSValue* thisValue,
     if (!thisValue->isObject(&BooleanObject::info))
         return throwError(exec, TypeError);
 
-    return static_cast<BooleanObject*>(thisValue)->internalValue();
+    return asBooleanObject(thisValue)->internalValue();
 }
 
 } // namespace JSC
index c996f56..572c495 100644 (file)
@@ -33,10 +33,10 @@ namespace JSC {
 JSValue* call(ExecState* exec, JSValue* functionObject, CallType callType, const CallData& callData, JSValue* thisValue, const ArgList& args)
 {
     if (callType == CallTypeHost)
-        return callData.native.function(exec, static_cast<JSObject*>(functionObject), thisValue, args);
+        return callData.native.function(exec, asObject(functionObject), thisValue, args);
     ASSERT(callType == CallTypeJS);
     // FIXME: Can this be done more efficiently using the callData?
-    return static_cast<JSFunction*>(functionObject)->call(exec, thisValue, args);
+    return asFunction(functionObject)->call(exec, thisValue, args);
 }
 
 } // namespace JSC
index 6fbc565..88a8ef6 100644 (file)
@@ -33,10 +33,10 @@ namespace JSC {
 JSObject* construct(ExecState* exec, JSValue* object, ConstructType constructType, const ConstructData& constructData, const ArgList& args)
 {
     if (constructType == ConstructTypeHost)
-        return constructData.native.function(exec, static_cast<JSObject*>(object), args);
+        return constructData.native.function(exec, asObject(object), args);
     ASSERT(constructType == ConstructTypeJS);
     // FIXME: Can this be done more efficiently using the constructData?
-    return static_cast<JSFunction*>(object)->construct(exec, args);
+    return asFunction(object)->construct(exec, args);
 }
 
 } // namespace JSC
index ff498d3..c9d627c 100644 (file)
@@ -74,7 +74,7 @@ JSObject* constructDate(ExecState* exec, const ArgList& args)
         value = getCurrentUTCTime();
     else if (numArgs == 1) {
         if (args.at(exec, 0)->isObject(&DateInstance::info))
-            value = static_cast<DateInstance*>(args.at(exec, 0))->internalNumber();
+            value = asDateInstance(args.at(exec, 0))->internalNumber();
         else {
             JSValue* primitive = args.at(exec, 0)->toPrimitive(exec);
             if (primitive->isString())
index e508fad..98f4b64 100644 (file)
@@ -52,6 +52,14 @@ namespace JSC {
         mutable Cache* m_cache;
     };
 
+    DateInstance* asDateInstance(JSValue*);
+
+    inline DateInstance* asDateInstance(JSValue* value)
+    {
+        ASSERT(asObject(value)->inherits(&DateInstance::info));
+        return static_cast<DateInstance*>(asObject(value));
+    }
+
 } // namespace JSC
 
 #endif // DateInstance_h
index 332e994..a3e792e 100644 (file)
@@ -366,7 +366,7 @@ JSValue* dateProtoFuncToString(ExecState* exec, JSObject*, JSValue* thisValue, c
 
     const bool utc = false;
 
-    DateInstance* thisDateObj = static_cast<DateInstance*>(thisValue); 
+    DateInstance* thisDateObj = asDateInstance(thisValue); 
     double milli = thisDateObj->internalNumber();
     if (isnan(milli))
         return jsNontrivialString(exec, "Invalid Date");
@@ -383,7 +383,7 @@ JSValue* dateProtoFuncToUTCString(ExecState* exec, JSObject*, JSValue* thisValue
 
     const bool utc = true;
 
-    DateInstance* thisDateObj = static_cast<DateInstance*>(thisValue); 
+    DateInstance* thisDateObj = asDateInstance(thisValue); 
     double milli = thisDateObj->internalNumber();
     if (isnan(milli))
         return jsNontrivialString(exec, "Invalid Date");
@@ -400,7 +400,7 @@ JSValue* dateProtoFuncToDateString(ExecState* exec, JSObject*, JSValue* thisValu
 
     const bool utc = false;
 
-    DateInstance* thisDateObj = static_cast<DateInstance*>(thisValue); 
+    DateInstance* thisDateObj = asDateInstance(thisValue); 
     double milli = thisDateObj->internalNumber();
     if (isnan(milli))
         return jsNontrivialString(exec, "Invalid Date");
@@ -417,7 +417,7 @@ JSValue* dateProtoFuncToTimeString(ExecState* exec, JSObject*, JSValue* thisValu
 
     const bool utc = false;
 
-    DateInstance* thisDateObj = static_cast<DateInstance*>(thisValue); 
+    DateInstance* thisDateObj = asDateInstance(thisValue); 
     double milli = thisDateObj->internalNumber();
     if (isnan(milli))
         return jsNontrivialString(exec, "Invalid Date");
@@ -432,7 +432,7 @@ JSValue* dateProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValue* thisVa
     if (!thisValue->isObject(&DateInstance::info))
         return throwError(exec, TypeError);
 
-    DateInstance* thisDateObj = static_cast<DateInstance*>(thisValue); 
+    DateInstance* thisDateObj = asDateInstance(thisValue); 
     double milli = thisDateObj->internalNumber();
     if (isnan(milli))
         return jsNontrivialString(exec, "Invalid Date");
@@ -456,7 +456,7 @@ JSValue* dateProtoFuncToLocaleDateString(ExecState* exec, JSObject*, JSValue* th
     if (!thisValue->isObject(&DateInstance::info))
         return throwError(exec, TypeError);
 
-    DateInstance* thisDateObj = static_cast<DateInstance*>(thisValue); 
+    DateInstance* thisDateObj = asDateInstance(thisValue); 
     double milli = thisDateObj->internalNumber();
     if (isnan(milli))
         return jsNontrivialString(exec, "Invalid Date");
@@ -480,7 +480,7 @@ JSValue* dateProtoFuncToLocaleTimeString(ExecState* exec, JSObject*, JSValue* th
     if (!thisValue->isObject(&DateInstance::info))
         return throwError(exec, TypeError);
 
-    DateInstance* thisDateObj = static_cast<DateInstance*>(thisValue); 
+    DateInstance* thisDateObj = asDateInstance(thisValue); 
     double milli = thisDateObj->internalNumber();
     if (isnan(milli))
         return jsNontrivialString(exec, "Invalid Date");
@@ -504,7 +504,7 @@ JSValue* dateProtoFuncValueOf(ExecState* exec, JSObject*, JSValue* thisValue, co
     if (!thisValue->isObject(&DateInstance::info))
         return throwError(exec, TypeError);
 
-    DateInstance* thisDateObj = static_cast<DateInstance*>(thisValue); 
+    DateInstance* thisDateObj = asDateInstance(thisValue); 
     double milli = thisDateObj->internalNumber();
     if (isnan(milli))
         return jsNaN(exec);
@@ -517,7 +517,7 @@ JSValue* dateProtoFuncGetTime(ExecState* exec, JSObject*, JSValue* thisValue, co
     if (!thisValue->isObject(&DateInstance::info))
         return throwError(exec, TypeError);
 
-    DateInstance* thisDateObj = static_cast<DateInstance*>(thisValue); 
+    DateInstance* thisDateObj = asDateInstance(thisValue); 
     double milli = thisDateObj->internalNumber();
     if (isnan(milli))
         return jsNaN(exec);
@@ -532,7 +532,7 @@ JSValue* dateProtoFuncGetFullYear(ExecState* exec, JSObject*, JSValue* thisValue
 
     const bool utc = false;
 
-    DateInstance* thisDateObj = static_cast<DateInstance*>(thisValue); 
+    DateInstance* thisDateObj = asDateInstance(thisValue); 
     double milli = thisDateObj->internalNumber();
     if (isnan(milli))
         return jsNaN(exec);
@@ -549,7 +549,7 @@ JSValue* dateProtoFuncGetUTCFullYear(ExecState* exec, JSObject*, JSValue* thisVa
 
     const bool utc = true;
 
-    DateInstance* thisDateObj = static_cast<DateInstance*>(thisValue); 
+    DateInstance* thisDateObj = asDateInstance(thisValue); 
     double milli = thisDateObj->internalNumber();
     if (isnan(milli))
         return jsNaN(exec);
@@ -566,7 +566,7 @@ JSValue* dateProtoFuncToGMTString(ExecState* exec, JSObject*, JSValue* thisValue
 
     const bool utc = true;
 
-    DateInstance* thisDateObj = static_cast<DateInstance*>(thisValue); 
+    DateInstance* thisDateObj = asDateInstance(thisValue); 
     double milli = thisDateObj->internalNumber();
     if (isnan(milli))
         return jsNontrivialString(exec, "Invalid Date");
@@ -583,7 +583,7 @@ JSValue* dateProtoFuncGetMonth(ExecState* exec, JSObject*, JSValue* thisValue, c
 
     const bool utc = false;
 
-    DateInstance* thisDateObj = static_cast<DateInstance*>(thisValue); 
+    DateInstance* thisDateObj = asDateInstance(thisValue); 
     double milli = thisDateObj->internalNumber();
     if (isnan(milli))
         return jsNaN(exec);
@@ -600,7 +600,7 @@ JSValue* dateProtoFuncGetUTCMonth(ExecState* exec, JSObject*, JSValue* thisValue
 
     const bool utc = true;
 
-    DateInstance* thisDateObj = static_cast<DateInstance*>(thisValue); 
+    DateInstance* thisDateObj = asDateInstance(thisValue); 
     double milli = thisDateObj->internalNumber();
     if (isnan(milli))
         return jsNaN(exec);
@@ -617,7 +617,7 @@ JSValue* dateProtoFuncGetDate(ExecState* exec, JSObject*, JSValue* thisValue, co
 
     const bool utc = false;
 
-    DateInstance* thisDateObj = static_cast<DateInstance*>(thisValue); 
+    DateInstance* thisDateObj = asDateInstance(thisValue); 
     double milli = thisDateObj->internalNumber();
     if (isnan(milli))
         return jsNaN(exec);
@@ -634,7 +634,7 @@ JSValue* dateProtoFuncGetUTCDate(ExecState* exec, JSObject*, JSValue* thisValue,
 
     const bool utc = true;
 
-    DateInstance* thisDateObj = static_cast<DateInstance*>(thisValue); 
+    DateInstance* thisDateObj = asDateInstance(thisValue); 
     double milli = thisDateObj->internalNumber();
     if (isnan(milli))
         return jsNaN(exec);
@@ -651,7 +651,7 @@ JSValue* dateProtoFuncGetDay(ExecState* exec, JSObject*, JSValue* thisValue, con
 
     const bool utc = false;
 
-    DateInstance* thisDateObj = static_cast<DateInstance*>(thisValue); 
+    DateInstance* thisDateObj = asDateInstance(thisValue); 
     double milli = thisDateObj->internalNumber();
     if (isnan(milli))
         return jsNaN(exec);
@@ -668,7 +668,7 @@ JSValue* dateProtoFuncGetUTCDay(ExecState* exec, JSObject*, JSValue* thisValue,
 
     const bool utc = true;
 
-    DateInstance* thisDateObj = static_cast<DateInstance*>(thisValue); 
+    DateInstance* thisDateObj = asDateInstance(thisValue); 
     double milli = thisDateObj->internalNumber();
     if (isnan(milli))
         return jsNaN(exec);
@@ -685,7 +685,7 @@ JSValue* dateProtoFuncGetHours(ExecState* exec, JSObject*, JSValue* thisValue, c
 
     const bool utc = false;
 
-    DateInstance* thisDateObj = static_cast<DateInstance*>(thisValue); 
+    DateInstance* thisDateObj = asDateInstance(thisValue); 
     double milli = thisDateObj->internalNumber();
     if (isnan(milli))
         return jsNaN(exec);
@@ -702,7 +702,7 @@ JSValue* dateProtoFuncGetUTCHours(ExecState* exec, JSObject*, JSValue* thisValue
 
     const bool utc = true;
 
-    DateInstance* thisDateObj = static_cast<DateInstance*>(thisValue); 
+    DateInstance* thisDateObj = asDateInstance(thisValue); 
     double milli = thisDateObj->internalNumber();
     if (isnan(milli))
         return jsNaN(exec);
@@ -719,7 +719,7 @@ JSValue* dateProtoFuncGetMinutes(ExecState* exec, JSObject*, JSValue* thisValue,
 
     const bool utc = false;
 
-    DateInstance* thisDateObj = static_cast<DateInstance*>(thisValue); 
+    DateInstance* thisDateObj = asDateInstance(thisValue); 
     double milli = thisDateObj->internalNumber();
     if (isnan(milli))
         return jsNaN(exec);
@@ -736,7 +736,7 @@ JSValue* dateProtoFuncGetUTCMinutes(ExecState* exec, JSObject*, JSValue* thisVal
 
     const bool utc = true;
 
-    DateInstance* thisDateObj = static_cast<DateInstance*>(thisValue); 
+    DateInstance* thisDateObj = asDateInstance(thisValue); 
     double milli = thisDateObj->internalNumber();
     if (isnan(milli))
         return jsNaN(exec);
@@ -753,7 +753,7 @@ JSValue* dateProtoFuncGetSeconds(ExecState* exec, JSObject*, JSValue* thisValue,
 
     const bool utc = false;
 
-    DateInstance* thisDateObj = static_cast<DateInstance*>(thisValue); 
+    DateInstance* thisDateObj = asDateInstance(thisValue); 
     double milli = thisDateObj->internalNumber();
     if (isnan(milli))
         return jsNaN(exec);
@@ -770,7 +770,7 @@ JSValue* dateProtoFuncGetUTCSeconds(ExecState* exec, JSObject*, JSValue* thisVal
 
     const bool utc = true;
 
-    DateInstance* thisDateObj = static_cast<DateInstance*>(thisValue); 
+    DateInstance* thisDateObj = asDateInstance(thisValue); 
     double milli = thisDateObj->internalNumber();
     if (isnan(milli))
         return jsNaN(exec);
@@ -785,7 +785,7 @@ JSValue* dateProtoFuncGetMilliSeconds(ExecState* exec, JSObject*, JSValue* thisV
     if (!thisValue->isObject(&DateInstance::info))
         return throwError(exec, TypeError);
 
-    DateInstance* thisDateObj = static_cast<DateInstance*>(thisValue); 
+    DateInstance* thisDateObj = asDateInstance(thisValue); 
     double milli = thisDateObj->internalNumber();
     if (isnan(milli))
         return jsNaN(exec);
@@ -800,7 +800,7 @@ JSValue* dateProtoFuncGetUTCMilliseconds(ExecState* exec, JSObject*, JSValue* th
     if (!thisValue->isObject(&DateInstance::info))
         return throwError(exec, TypeError);
 
-    DateInstance* thisDateObj = static_cast<DateInstance*>(thisValue); 
+    DateInstance* thisDateObj = asDateInstance(thisValue); 
     double milli = thisDateObj->internalNumber();
     if (isnan(milli))
         return jsNaN(exec);
@@ -817,7 +817,7 @@ JSValue* dateProtoFuncGetTimezoneOffset(ExecState* exec, JSObject*, JSValue* thi
 
     const bool utc = false;
 
-    DateInstance* thisDateObj = static_cast<DateInstance*>(thisValue); 
+    DateInstance* thisDateObj = asDateInstance(thisValue); 
     double milli = thisDateObj->internalNumber();
     if (isnan(milli))
         return jsNaN(exec);
@@ -832,7 +832,7 @@ JSValue* dateProtoFuncSetTime(ExecState* exec, JSObject*, JSValue* thisValue, co
     if (!thisValue->isObject(&DateInstance::info))
         return throwError(exec, TypeError);
 
-    DateInstance* thisDateObj = static_cast<DateInstance*>(thisValue); 
+    DateInstance* thisDateObj = asDateInstance(thisValue); 
 
     double milli = timeClip(args.at(exec, 0)->toNumber(exec));
     JSValue* result = jsNumber(exec, milli);
@@ -845,7 +845,7 @@ static JSValue* setNewValueFromTimeArgs(ExecState* exec, JSValue* thisValue, con
     if (!thisValue->isObject(&DateInstance::info))
         return throwError(exec, TypeError);
 
-    DateInstance* thisDateObj = static_cast<DateInstance*>(thisValue);
+    DateInstance* thisDateObj = asDateInstance(thisValue);
     double milli = thisDateObj->internalNumber();
     
     if (args.isEmpty() || isnan(milli)) {
@@ -876,7 +876,7 @@ static JSValue* setNewValueFromDateArgs(ExecState* exec, JSValue* thisValue, con
     if (!thisValue->isObject(&DateInstance::info))
         return throwError(exec, TypeError);
 
-    DateInstance* thisDateObj = static_cast<DateInstance*>(thisValue);
+    DateInstance* thisDateObj = asDateInstance(thisValue);
     if (args.isEmpty()) {
         JSValue* result = jsNaN(exec);
         thisDateObj->setInternalValue(result);
@@ -999,7 +999,7 @@ JSValue* dateProtoFuncSetYear(ExecState* exec, JSObject*, JSValue* thisValue, co
 
     const bool utc = false;
 
-    DateInstance* thisDateObj = static_cast<DateInstance*>(thisValue);     
+    DateInstance* thisDateObj = asDateInstance(thisValue);     
     if (args.isEmpty()) { 
         JSValue* result = jsNaN(exec);
         thisDateObj->setInternalValue(result);
@@ -1041,7 +1041,7 @@ JSValue* dateProtoFuncGetYear(ExecState* exec, JSObject*, JSValue* thisValue, co
 
     const bool utc = false;
 
-    DateInstance* thisDateObj = static_cast<DateInstance*>(thisValue); 
+    DateInstance* thisDateObj = asDateInstance(thisValue); 
     double milli = thisDateObj->internalNumber();
     if (isnan(milli))
         return jsNaN(exec);
index 3564b75..ae62cd3 100644 (file)
@@ -60,14 +60,14 @@ JSObject* DebuggerCallFrame::thisObject() const
     if (!m_callFrame->codeBlock())
         return 0;
 
-    // FIXME: Why is it safe to cast this to JSObject?
-    return static_cast<JSObject*>(m_callFrame->thisValue());
+    // FIXME: Why is it safe to assume this is an object?
+    return asObject(m_callFrame->thisValue());
 }
 
 JSValue* DebuggerCallFrame::evaluate(const UString& script, JSValue*& exception) const
 {
     if (!m_callFrame->codeBlock())
-        return 0;
+        return noValue();
 
     int errLine;
     UString errMsg;
index 96eb63e..ca8fca2 100644 (file)
@@ -37,6 +37,12 @@ namespace JSC {
     public:
         enum Type { ProgramType, FunctionType };
 
+        DebuggerCallFrame(CallFrame* callFrame)
+            : m_callFrame(callFrame)
+            , m_exception(0)
+        {
+        }
+
         DebuggerCallFrame(CallFrame* callFrame, JSValue* exception)
             : m_callFrame(callFrame)
             , m_exception(exception)
index 50d2b95..f1891bb 100644 (file)
@@ -75,7 +75,7 @@ namespace JSC  {
         // But they're used in many places in legacy code, so they're not going away any time soon.
 
         void setException(JSValue* exception) { globalData().exception = exception; }
-        void clearException() { globalData().exception = 0; }
+        void clearException() { globalData().exception = noValue(); }
         JSValue* exception() const { return globalData().exception; }
         JSValue** exceptionSlot() { return &globalData().exception; }
         bool hadException() const { return !!globalData().exception; }
index cac1fd2..49a5a1c 100644 (file)
@@ -66,12 +66,12 @@ CallType FunctionPrototype::getCallData(CallData& callData)
 JSValue* functionProtoFuncToString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
 {
     if (thisValue->isObject(&JSFunction::info)) {
-        JSFunction* function = static_cast<JSFunction*>(thisValue);
+        JSFunction* function = asFunction(thisValue);
         return jsString(exec, "function " + function->name(&exec->globalData()) + "(" + function->m_body->paramString() + ") " + function->m_body->toSourceString());
     }
 
     if (thisValue->isObject(&InternalFunction::info)) {
-        InternalFunction* function = static_cast<InternalFunction*>(thisValue);
+        InternalFunction* function = asInternalFunction(thisValue);
         return jsString(exec, "function " + function->name(&exec->globalData()) + "() {\n    [native code]\n}");
     }
 
@@ -96,17 +96,16 @@ JSValue* functionProtoFuncApply(ExecState* exec, JSObject*, JSValue* thisValue,
 
     ArgList applyArgs;
     if (!argArray->isUndefinedOrNull()) {
-        if (argArray->isObject()) {
-            if (static_cast<JSObject*>(argArray)->classInfo() == &Arguments::info)
-                static_cast<Arguments*>(argArray)->fillArgList(exec, applyArgs);
-            else if (exec->machine()->isJSArray(argArray))
-                static_cast<JSArray*>(argArray)->fillArgList(exec, applyArgs);
-            else if (static_cast<JSObject*>(argArray)->inherits(&JSArray::info)) {
-                unsigned length = static_cast<JSObject*>(argArray)->get(exec, exec->propertyNames().length)->toUInt32(exec);
-                for (unsigned i = 0; i < length; ++i)
-                    applyArgs.append(static_cast<JSObject*>(argArray)->get(exec, i));
-            } else
-                return throwError(exec, TypeError);
+        if (!argArray->isObject())
+            return throwError(exec, TypeError);
+        if (asObject(argArray)->classInfo() == &Arguments::info)
+            asArguments(argArray)->fillArgList(exec, applyArgs);
+        else if (exec->machine()->isJSArray(argArray))
+            asArray(argArray)->fillArgList(exec, applyArgs);
+        else if (asObject(argArray)->inherits(&JSArray::info)) {
+            unsigned length = asArray(argArray)->get(exec, exec->propertyNames().length)->toUInt32(exec);
+            for (unsigned i = 0; i < length; ++i)
+                applyArgs.append(asArray(argArray)->get(exec, i));
         } else
             return throwError(exec, TypeError);
     }
index bcd1b35..c3d089f 100644 (file)
@@ -48,7 +48,7 @@ bool GetterSetter::getPrimitiveNumber(ExecState*, double& number, JSValue*& valu
 {
     ASSERT_NOT_REACHED();
     number = 0;
-    value = 0;
+    value = noValue();
     return true;
 }
 
index e8e6ff6..da968b2 100644 (file)
@@ -61,6 +61,15 @@ namespace JSC {
         JSObject* m_setter;  
     };
 
+    GetterSetter* asGetterSetter(JSValue*);
+
+    inline GetterSetter* asGetterSetter(JSValue* value)
+    {
+        ASSERT(asCell(value)->isGetterSetter());
+        return static_cast<GetterSetter*>(asCell(value));
+    }
+
+
 } // namespace JSC
 
 #endif // GetterSetter_h
index 86954a5..0bd0a26 100644 (file)
@@ -51,9 +51,7 @@ InternalFunction::InternalFunction(JSGlobalData* globalData, PassRefPtr<Structur
 
 const UString& InternalFunction::name(JSGlobalData* globalData)
 {
-    JSValue* v = getDirect(globalData->propertyNames->name);
-    ASSERT(v->isString());
-    return static_cast<JSString*>(v)->value();
+    return asString(getDirect(globalData->propertyNames->name))->value();
 }
 
 } // namespace JSC
index e73128a..8351170 100644 (file)
@@ -52,6 +52,14 @@ namespace JSC {
         virtual CallType getCallData(CallData&) = 0;
     };
 
+    InternalFunction* asInternalFunction(JSValue*);
+
+    inline InternalFunction* asInternalFunction(JSValue* value)
+    {
+        ASSERT(asObject(value)->inherits(&InternalFunction::info));
+        return static_cast<InternalFunction*>(asObject(value));
+    }
+
 } // namespace JSC
 
 #endif // InternalFunction_h
index 339bb0f..9cb77e8 100644 (file)
@@ -153,7 +153,7 @@ bool JSActivation::isDynamicScope() const
 
 JSValue* JSActivation::argumentsGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
 {
-    JSActivation* activation = static_cast<JSActivation*>(slot.slotBase());
+    JSActivation* activation = asActivation(slot.slotBase());
 
     if (activation->d()->functionBody->usesArguments()) {
         PropertySlot slot;
index d6f1a06..16d131b 100644 (file)
@@ -82,7 +82,15 @@ namespace JSC {
 
         JSActivationData* d() const { return static_cast<JSActivationData*>(JSVariableObject::d); }
     };
-    
+
+    JSActivation* asActivation(JSValue*);
+
+    inline JSActivation* asActivation(JSValue* value)
+    {
+        ASSERT(asObject(value)->inherits(&JSActivation::info));
+        return static_cast<JSActivation*>(asObject(value));
+    }
+
 } // namespace JSC
 
 #endif // JSActivation_h
index f43ef31..d2d38a4 100644 (file)
@@ -350,12 +350,12 @@ NEVER_INLINE void JSArray::putSlowCase(ExecState* exec, unsigned i, JSValue* val
     unsigned vectorLength = storage->m_vectorLength;
     if (newNumValuesInVector == storage->m_numValuesInVector + 1) {
         for (unsigned j = vectorLength; j < newVectorLength; ++j)
-            storage->m_vector[j] = 0;
+            storage->m_vector[j] = noValue();
         if (i > MIN_SPARSE_ARRAY_INDEX)
             map->remove(i);
     } else {
         for (unsigned j = vectorLength; j < max(vectorLength, MIN_SPARSE_ARRAY_INDEX); ++j)
-            storage->m_vector[j] = 0;
+            storage->m_vector[j] = noValue();
         for (unsigned j = max(vectorLength, MIN_SPARSE_ARRAY_INDEX); j < newVectorLength; ++j)
             storage->m_vector[j] = map->take(j);
     }
@@ -395,7 +395,7 @@ bool JSArray::deleteProperty(ExecState* exec, unsigned i)
             checkConsistency();
             return false;
         }
-        valueSlot = 0;
+        valueSlot = noValue();
         --storage->m_numValuesInVector;
         if (m_fastAccessCutoff > i)
             m_fastAccessCutoff = i;
@@ -464,7 +464,7 @@ bool JSArray::increaseVectorLength(unsigned newLength)
     storage->m_vectorLength = newVectorLength;
 
     for (unsigned i = vectorLength; i < newVectorLength; ++i)
-        storage->m_vector[i] = 0;
+        storage->m_vector[i] = noValue();
 
     m_storage = storage;
     return true;
@@ -486,7 +486,7 @@ void JSArray::setLength(unsigned newLength)
         for (unsigned i = newLength; i < usedVectorLength; ++i) {
             JSValue*& valueSlot = storage->m_vector[i];
             bool hadValue = valueSlot;
-            valueSlot = 0;
+            valueSlot = noValue();
             storage->m_numValuesInVector -= hadValue;
         }
 
@@ -525,13 +525,13 @@ JSValue* JSArray::pop()
         JSValue*& valueSlot = m_storage->m_vector[length];
         result = valueSlot;
         ASSERT(result);
-        valueSlot = 0;
+        valueSlot = noValue();
         --m_storage->m_numValuesInVector;
         m_fastAccessCutoff = length;
     } else if (length < m_storage->m_vectorLength) {
         JSValue*& valueSlot = m_storage->m_vector[length];
         result = valueSlot;
-        valueSlot = 0;
+        valueSlot = noValue();
         if (result)
             --m_storage->m_numValuesInVector;
         else
@@ -849,7 +849,7 @@ void JSArray::sort(ExecState* exec, JSValue* compareFunction, CallType callType,
 
     // Ensure that unused values in the vector are zeroed out.
     for (unsigned i = newUsedVectorLength; i < usedVectorLength; ++i)
-        m_storage->m_vector[i] = 0;
+        m_storage->m_vector[i] = noValue();
 
     m_fastAccessCutoff = newUsedVectorLength;
     m_storage->m_numValuesInVector = newUsedVectorLength;
@@ -915,7 +915,7 @@ unsigned JSArray::compactForSorting()
     for (unsigned i = numDefined; i < newUsedVectorLength; ++i)
         storage->m_vector[i] = jsUndefined();
     for (unsigned i = newUsedVectorLength; i < usedVectorLength; ++i)
-        storage->m_vector[i] = 0;
+        storage->m_vector[i] = noValue();
 
     m_fastAccessCutoff = newUsedVectorLength;
     storage->m_numValuesInVector = newUsedVectorLength;
index 9a861a2..f4d6fba 100644 (file)
@@ -103,11 +103,19 @@ namespace JSC {
         ArrayStorage* m_storage;
     };
 
+    JSArray* asArray(JSValue*);
+
     JSArray* constructEmptyArray(ExecState*);
     JSArray* constructEmptyArray(ExecState*, unsigned initialLength);
     JSArray* constructArray(ExecState*, JSValue* singleItemValue);
     JSArray* constructArray(ExecState*, const ArgList& values);
 
+    inline JSArray* asArray(JSValue* value)
+    {
+        ASSERT(asObject(value)->inherits(&JSArray::info));
+        return static_cast<JSArray*>(asObject(value));
+    }
+
 } // namespace JSC
 
 #endif // JSArray_h
index 544c27f..cfe2f72 100644 (file)
@@ -212,7 +212,7 @@ const ClassInfo* JSCell::classInfo() const
 
 JSValue* JSCell::getJSNumber()
 {
-    return 0;
+    return noValue();
 }
 
 bool JSCell::isGetterSetter() const
index bced0cd..e9da7ec 100644 (file)
@@ -105,6 +105,14 @@ namespace JSC {
         StructureID* m_structureID;
     };
 
+    JSCell* asCell(JSValue*);
+
+    inline JSCell* asCell(JSValue* value)
+    {
+        ASSERT(!JSImmediate::isImmediate(value));
+        return static_cast<JSCell*>(value);
+    }
+
     inline JSCell::JSCell(StructureID* structureID)
         : m_structureID(structureID)
     {
@@ -144,16 +152,10 @@ namespace JSC {
         return Heap::markCell(this);
     }
 
-    ALWAYS_INLINE JSCell* JSValue::asCell()
+    ALWAYS_INLINE JSCell* JSValue::asCell() const
     {
-        ASSERT(!JSImmediate::isImmediate(this));
-        return static_cast<JSCell*>(this);
-    }
-
-    ALWAYS_INLINE const JSCell* JSValue::asCell() const
-    {
-        ASSERT(!JSImmediate::isImmediate(this));
-        return static_cast<const JSCell*>(this);
+        ASSERT(!JSImmediate::isImmediate(asValue()));
+        return reinterpret_cast<JSCell*>(const_cast<JSValue*>(this));
     }
 
     inline void* JSCell::operator new(size_t size, JSGlobalData* globalData)
@@ -169,28 +171,28 @@ namespace JSC {
 
     inline bool JSValue::isNumber() const
     {
-        return JSImmediate::isNumber(this) || (!JSImmediate::isImmediate(this) && asCell()->isNumber());
+        return JSImmediate::isNumber(asValue()) || (!JSImmediate::isImmediate(asValue()) && asCell()->isNumber());
     }
 
     inline bool JSValue::isString() const
     {
-        return !JSImmediate::isImmediate(this) && asCell()->isString();
+        return !JSImmediate::isImmediate(asValue()) && asCell()->isString();
     }
 
     inline bool JSValue::isGetterSetter() const
     {
-        return !JSImmediate::isImmediate(this) && asCell()->isGetterSetter();
+        return !JSImmediate::isImmediate(asValue()) && asCell()->isGetterSetter();
     }
 
     inline bool JSValue::isObject() const
     {
-        return !JSImmediate::isImmediate(this) && asCell()->isObject();
+        return !JSImmediate::isImmediate(asValue()) && asCell()->isObject();
     }
 
     inline bool JSValue::getNumber(double& v) const
     {
-        if (JSImmediate::isImmediate(this)) {
-            v = JSImmediate::toDouble(this);
+        if (JSImmediate::isImmediate(asValue())) {
+            v = JSImmediate::toDouble(asValue());
             return true;
         }
         return asCell()->getNumber(v);
@@ -198,75 +200,74 @@ namespace JSC {
 
     inline double JSValue::getNumber() const
     {
-        return JSImmediate::isImmediate(this) ? JSImmediate::toDouble(this) : asCell()->getNumber();
+        return JSImmediate::isImmediate(asValue()) ? JSImmediate::toDouble(asValue()) : asCell()->getNumber();
     }
 
     inline bool JSValue::getString(UString& s) const
     {
-        return !JSImmediate::isImmediate(this) && asCell()->getString(s);
+        return !JSImmediate::isImmediate(asValue()) && asCell()->getString(s);
     }
 
     inline UString JSValue::getString() const
     {
-        return JSImmediate::isImmediate(this) ? UString() : asCell()->getString();
+        return JSImmediate::isImmediate(asValue()) ? UString() : asCell()->getString();
     }
 
     inline JSObject* JSValue::getObject()
     {
-        return JSImmediate::isImmediate(this) ? 0 : asCell()->getObject();
+        return JSImmediate::isImmediate(asValue()) ? 0 : asCell()->getObject();
     }
 
     inline const JSObject* JSValue::getObject() const
     {
-        return JSImmediate::isImmediate(this) ? 0 : asCell()->getObject();
+        return JSImmediate::isImmediate(asValue()) ? 0 : asCell()->getObject();
     }
 
     inline CallType JSValue::getCallData(CallData& callData)
     {
-        return JSImmediate::isImmediate(this) ? CallTypeNone : asCell()->getCallData(callData);
+        return JSImmediate::isImmediate(asValue()) ? CallTypeNone : asCell()->getCallData(callData);
     }
 
     inline ConstructType JSValue::getConstructData(ConstructData& constructData)
     {
-        return JSImmediate::isImmediate(this) ? ConstructTypeNone : asCell()->getConstructData(constructData);
+        return JSImmediate::isImmediate(asValue()) ? ConstructTypeNone : asCell()->getConstructData(constructData);
     }
 
     ALWAYS_INLINE bool JSValue::getUInt32(uint32_t& v) const
     {
-        return JSImmediate::isImmediate(this) ? JSImmediate::getUInt32(this, v) : asCell()->getUInt32(v);
+        return JSImmediate::isImmediate(asValue()) ? JSImmediate::getUInt32(asValue(), v) : asCell()->getUInt32(v);
     }
 
     ALWAYS_INLINE bool JSValue::getTruncatedInt32(int32_t& v) const
     {
-        return JSImmediate::isImmediate(this) ? JSImmediate::getTruncatedInt32(this, v) : asCell()->getTruncatedInt32(v);
+        return JSImmediate::isImmediate(asValue()) ? JSImmediate::getTruncatedInt32(asValue(), v) : asCell()->getTruncatedInt32(v);
     }
 
     inline bool JSValue::getTruncatedUInt32(uint32_t& v) const
     {
-        return JSImmediate::isImmediate(this) ? JSImmediate::getTruncatedUInt32(this, v) : asCell()->getTruncatedUInt32(v);
+        return JSImmediate::isImmediate(asValue()) ? JSImmediate::getTruncatedUInt32(asValue(), v) : asCell()->getTruncatedUInt32(v);
     }
 
     inline void JSValue::mark()
     {
-        ASSERT(!JSImmediate::isImmediate(this)); // callers should check !marked() before calling mark()
-        asCell()->mark();
+        asCell()->mark(); // callers should check !marked() before calling mark(), so this should only be called with cells
     }
 
     inline bool JSValue::marked() const
     {
-        return JSImmediate::isImmediate(this) || asCell()->marked();
+        return JSImmediate::isImmediate(asValue()) || asCell()->marked();
     }
 
     inline JSValue* JSValue::toPrimitive(ExecState* exec, PreferredPrimitiveType preferredType) const
     {
-        return JSImmediate::isImmediate(this) ? const_cast<JSValue*>(this) : asCell()->toPrimitive(exec, preferredType);
+        return JSImmediate::isImmediate(asValue()) ? asValue() : asCell()->toPrimitive(exec, preferredType);
     }
 
     inline bool JSValue::getPrimitiveNumber(ExecState* exec, double& number, JSValue*& value)
     {
-        if (JSImmediate::isImmediate(this)) {
-            number = JSImmediate::toDouble(this);
-            value = this;
+        if (JSImmediate::isImmediate(asValue())) {
+            number = JSImmediate::toDouble(asValue());
+            value = asValue();
             return true;
         }
         return asCell()->getPrimitiveNumber(exec, number, value);
@@ -274,48 +275,47 @@ namespace JSC {
 
     inline bool JSValue::toBoolean(ExecState* exec) const
     {
-        return JSImmediate::isImmediate(this) ? JSImmediate::toBoolean(this) : asCell()->toBoolean(exec);
+        return JSImmediate::isImmediate(asValue()) ? JSImmediate::toBoolean(asValue()) : asCell()->toBoolean(exec);
     }
 
     ALWAYS_INLINE double JSValue::toNumber(ExecState* exec) const
     {
-        return JSImmediate::isImmediate(this) ? JSImmediate::toDouble(this) : asCell()->toNumber(exec);
+        return JSImmediate::isImmediate(asValue()) ? JSImmediate::toDouble(asValue()) : asCell()->toNumber(exec);
     }
 
     inline UString JSValue::toString(ExecState* exec) const
     {
-        return JSImmediate::isImmediate(this) ? JSImmediate::toString(this) : asCell()->toString(exec);
+        return JSImmediate::isImmediate(asValue()) ? JSImmediate::toString(asValue()) : asCell()->toString(exec);
     }
 
     inline JSObject* JSValue::toObject(ExecState* exec) const
     {
-        return JSImmediate::isImmediate(this) ? JSImmediate::toObject(this, exec) : asCell()->toObject(exec);
+        return JSImmediate::isImmediate(asValue()) ? JSImmediate::toObject(asValue(), exec) : asCell()->toObject(exec);
     }
 
     inline JSObject* JSValue::toThisObject(ExecState* exec) const
     {
-        if (UNLIKELY(JSImmediate::isImmediate(this)))
-            return JSImmediate::toObject(this, exec);
+        if (UNLIKELY(JSImmediate::isImmediate(asValue())))
+            return JSImmediate::toObject(asValue(), exec);
         return asCell()->toThisObject(exec);
     }
 
     inline bool JSValue::needsThisConversion() const
     {
-        if (UNLIKELY(JSImmediate::isImmediate(this)))
+        if (UNLIKELY(JSImmediate::isImmediate(asValue())))
             return true;
-
         return asCell()->structureID()->typeInfo().needsThisConversion();
     }
 
     inline UString JSValue::toThisString(ExecState* exec) const
     {
-        return JSImmediate::isImmediate(this) ? JSImmediate::toString(this) : asCell()->toThisString(exec);
+        return JSImmediate::isImmediate(asValue()) ? JSImmediate::toString(asValue()) : asCell()->toThisString(exec);
     }
 
     inline JSValue* JSValue::getJSNumber()
     {
 
-        return JSImmediate::isNumber(this) ? this : (JSImmediate::isImmediate(this) ? 0 : asCell()->getJSNumber());
+        return JSImmediate::isNumber(asValue()) ? asValue() : JSImmediate::isImmediate(asValue()) ? noValue() : asCell()->getJSNumber();
     }
 
 } // namespace JSC
index d54f160..81d54b6 100644 (file)
@@ -84,19 +84,19 @@ JSValue* JSFunction::call(ExecState* exec, JSValue* thisValue, const ArgList& ar
 
 JSValue* JSFunction::argumentsGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
 {
-    JSFunction* thisObj = static_cast<JSFunction*>(slot.slotBase());
+    JSFunction* thisObj = asFunction(slot.slotBase());
     return exec->machine()->retrieveArguments(exec, thisObj);
 }
 
 JSValue* JSFunction::callerGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
 {
-    JSFunction* thisObj = static_cast<JSFunction*>(slot.slotBase());
+    JSFunction* thisObj = asFunction(slot.slotBase());
     return exec->machine()->retrieveCaller(exec, thisObj);
 }
 
 JSValue* JSFunction::lengthGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
 {
-    JSFunction* thisObj = static_cast<JSFunction*>(slot.slotBase());
+    JSFunction* thisObj = asFunction(slot.slotBase());
     return jsNumber(exec, thisObj->m_body->parameterCount());
 }
 
@@ -173,7 +173,7 @@ JSObject* JSFunction::construct(ExecState* exec, const ArgList& args)
     StructureID* structure;
     JSValue* prototype = get(exec, exec->propertyNames().prototype);
     if (prototype->isObject())
-        structure = static_cast<JSObject*>(prototype)->inheritorID();
+        structure = asObject(prototype)->inheritorID();
     else
         structure = exec->lexicalGlobalObject()->emptyObjectStructure();
     JSObject* thisObj = new (exec) JSObject(structure);
@@ -181,7 +181,7 @@ JSObject* JSFunction::construct(ExecState* exec, const ArgList& args)
     JSValue* result = exec->machine()->execute(m_body.get(), exec, this, thisObj, args, m_scopeChain.node(), exec->exceptionSlot());
     if (exec->hadException() || !result->isObject())
         return thisObj;
-    return static_cast<JSObject*>(result);
+    return asObject(result);
 }
 
 } // namespace JSC
index aef022d..5b3d04d 100644 (file)
@@ -81,6 +81,14 @@ namespace JSC {
         ScopeChain m_scopeChain;
     };
 
+    JSFunction* asFunction(JSValue*);
+
+    inline JSFunction* asFunction(JSValue* value)
+    {
+        ASSERT(asObject(value)->inherits(&JSFunction::info));
+        return static_cast<JSFunction*>(asObject(value));
+    }
+
 } // namespace kJS
 
 #endif // JSFunction_h
index 6ed98aa..bd13081 100644 (file)
@@ -190,7 +190,7 @@ static inline JSObject* lastInPrototypeChain(JSObject* object)
 {
     JSObject* o = object;
     while (o->prototype()->isObject())
-        o = static_cast<JSObject*>(o->prototype());
+        o = asObject(o->prototype());
     return o;
 }
 
index 22ae6fe..2890fe0 100644 (file)
@@ -274,6 +274,14 @@ namespace JSC {
         void* operator new(size_t); // can only be allocated with JSGlobalData
     };
 
+    JSGlobalObject* asGlobalObject(JSValue*);
+
+    inline JSGlobalObject* asGlobalObject(JSValue* value)
+    {
+        ASSERT(asObject(value)->isGlobalObject());
+        return static_cast<JSGlobalObject*>(asObject(value));
+    }
+
     inline void JSGlobalObject::setRegisters(Register* registers, Register* registerArray, size_t count)
     {
         JSVariableObject::setRegisters(registers, registerArray);
@@ -314,9 +322,7 @@ namespace JSC {
 
     inline JSGlobalObject* ScopeChainNode::globalObject() const
     {
-        JSGlobalObject* globalObject = static_cast<JSGlobalObject*>(bottom());
-        ASSERT(globalObject->isGlobalObject());
-        return globalObject;
+        return asGlobalObject(bottom());
     }
 
     inline JSValue* StructureID::prototypeForLookup(ExecState* exec)
index 23201d8..e72f1b4 100644 (file)
@@ -38,6 +38,9 @@ namespace JSC {
     class JSValue;
     class UString;
 
+    inline JSValue* noValue() { return 0; }
+    inline void* asPointer(JSValue* value) { return value; }
+
     /*
      * 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
@@ -105,35 +108,35 @@ namespace JSC {
     public:
         static ALWAYS_INLINE bool isImmediate(const JSValue* v)
         {
-            return reinterpret_cast<uintptr_t>(v) & TagMask;
+            return rawValue(v) & TagMask;
         }
         
         static ALWAYS_INLINE bool isNumber(const JSValue* v)
         {
-            return reinterpret_cast<uintptr_t>(v) & TagBitTypeInteger;
+            return rawValue(v) & TagBitTypeInteger;
         }
 
         static ALWAYS_INLINE bool isPositiveNumber(const JSValue* v)
         {
             // A single mask to check for the sign bit and the number tag all at once.
-            return (reinterpret_cast<uintptr_t>(v) & (0x80000000 | TagBitTypeInteger)) == TagBitTypeInteger;
+            return (rawValue(v) & (0x80000000 | TagBitTypeInteger)) == TagBitTypeInteger;
         }
         
         static ALWAYS_INLINE bool isBoolean(const JSValue* v)
         {
-            return (reinterpret_cast<uintptr_t>(v) & FullTagTypeMask) == FullTagTypeBool;
+            return (rawValue(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 (rawValue(v) & ~ExtendedTagBitUndefined) == FullTagTypeNull;
         }
 
         static bool isNegative(const JSValue* v)
         {
             ASSERT(isNumber(v));
-            return reinterpret_cast<uintptr_t>(v) & 0x80000000;
+            return rawValue(v) & 0x80000000;
         }
 
         static JSValue* from(char);
@@ -151,12 +154,12 @@ namespace JSC {
 
         static ALWAYS_INLINE bool isEitherImmediate(const JSValue* v1, const JSValue* v2)
         {
-            return (reinterpret_cast<uintptr_t>(v1) | reinterpret_cast<uintptr_t>(v2)) & TagMask;
+            return (rawValue(v1) | rawValue(v2)) & TagMask;
         }
 
         static ALWAYS_INLINE bool isAnyImmediate(const JSValue* v1, const JSValue* v2, JSValue* v3)
         {
-            return (reinterpret_cast<uintptr_t>(v1) | reinterpret_cast<uintptr_t>(v2) | reinterpret_cast<uintptr_t>(v3)) & TagMask;
+            return (rawValue(v1) | rawValue(v2) | rawValue(v3)) & TagMask;
         }
 
         static ALWAYS_INLINE bool areBothImmediate(const JSValue* v1, const JSValue* v2)
@@ -166,64 +169,64 @@ namespace JSC {
 
         static ALWAYS_INLINE bool areBothImmediateNumbers(const JSValue* v1, const JSValue* v2)
         {
-            return reinterpret_cast<uintptr_t>(v1) & reinterpret_cast<uintptr_t>(v2) & TagBitTypeInteger;
+            return rawValue(v1) & rawValue(v2) & TagBitTypeInteger;
         }
 
         static ALWAYS_INLINE JSValue* andImmediateNumbers(const JSValue* v1, const JSValue* v2)
         {
             ASSERT(areBothImmediateNumbers(v1, v2));
-            return reinterpret_cast<JSValue*>(reinterpret_cast<uintptr_t>(v1) & reinterpret_cast<uintptr_t>(v2));
+            return makeValue(rawValue(v1) & rawValue(v2));
         }
 
         static ALWAYS_INLINE JSValue* xorImmediateNumbers(const JSValue* v1, const JSValue* v2)
         {
             ASSERT(areBothImmediateNumbers(v1, v2));
-            return reinterpret_cast<JSValue*>((reinterpret_cast<uintptr_t>(v1) ^ reinterpret_cast<uintptr_t>(v2)) | TagBitTypeInteger);
+            return makeValue((rawValue(v1) ^ rawValue(v2)) | TagBitTypeInteger);
         }
 
         static ALWAYS_INLINE JSValue* orImmediateNumbers(const JSValue* v1, const JSValue* v2)
         {
             ASSERT(areBothImmediateNumbers(v1, v2));
-            return reinterpret_cast<JSValue*>(reinterpret_cast<uintptr_t>(v1) | reinterpret_cast<uintptr_t>(v2));
+            return makeValue(rawValue(v1) | rawValue(v2));
         }
 
         static ALWAYS_INLINE JSValue* rightShiftImmediateNumbers(const JSValue* val, const JSValue* shift)
         {
             ASSERT(areBothImmediateNumbers(val, shift));
-            return reinterpret_cast<JSValue*>((reinterpret_cast<intptr_t>(val) >> ((reinterpret_cast<uintptr_t>(shift) >> IntegerPayloadShift) & 0x1f)) | TagBitTypeInteger);
+            return makeValue((static_cast<intptr_t>(rawValue(val)) >> ((rawValue(shift) >> IntegerPayloadShift) & 0x1f)) | TagBitTypeInteger);
         }
 
         static ALWAYS_INLINE bool canDoFastAdditiveOperations(const JSValue* v)
         {
             // Number is non-negative and an operation involving two of these can't overflow.
             // Checking for allowed negative numbers takes more time than it's worth on SunSpider.
-            return (reinterpret_cast<uintptr_t>(v) & (TagBitTypeInteger + (3u << 30))) == TagBitTypeInteger;
+            return (rawValue(v) & (TagBitTypeInteger + (3u << 30))) == TagBitTypeInteger;
         }
 
         static ALWAYS_INLINE JSValue* addImmediateNumbers(const JSValue* v1, const JSValue* v2)
         {
             ASSERT(canDoFastAdditiveOperations(v1));
             ASSERT(canDoFastAdditiveOperations(v2));
-            return reinterpret_cast<JSValue*>(reinterpret_cast<uintptr_t>(v1) + reinterpret_cast<uintptr_t>(v2) - TagBitTypeInteger);
+            return makeValue(rawValue(v1) + rawValue(v2) - TagBitTypeInteger);
         }
 
         static ALWAYS_INLINE JSValue* subImmediateNumbers(const JSValue* v1, const JSValue* v2)
         {
             ASSERT(canDoFastAdditiveOperations(v1));
             ASSERT(canDoFastAdditiveOperations(v2));
-            return reinterpret_cast<JSValue*>(reinterpret_cast<uintptr_t>(v1) - reinterpret_cast<uintptr_t>(v2) + TagBitTypeInteger);
+            return makeValue(rawValue(v1) - rawValue(v2) + TagBitTypeInteger);
         }
 
         static ALWAYS_INLINE JSValue* incImmediateNumber(const JSValue* v)
         {
             ASSERT(canDoFastAdditiveOperations(v));
-            return reinterpret_cast<JSValue*>(reinterpret_cast<uintptr_t>(v) + (1 << IntegerPayloadShift));
+            return makeValue(rawValue(v) + (1 << IntegerPayloadShift));
         }
 
         static ALWAYS_INLINE JSValue* decImmediateNumber(const JSValue* v)
         {
             ASSERT(canDoFastAdditiveOperations(v));
-            return reinterpret_cast<JSValue*>(reinterpret_cast<uintptr_t>(v) - (1 << IntegerPayloadShift));
+            return makeValue(rawValue(v) - (1 << IntegerPayloadShift));
         }
 
         static double toDouble(const JSValue*);
@@ -253,30 +256,35 @@ namespace JSC {
         static const int minImmediateInt = ((-INT_MAX) - 1) >> IntegerPayloadShift;
         static const int maxImmediateInt = INT_MAX >> IntegerPayloadShift;
         static const unsigned maxImmediateUInt = maxImmediateInt;
-        
+
+        static ALWAYS_INLINE JSValue* makeValue(uintptr_t integer)
+        {
+            return reinterpret_cast<JSValue*>(integer);
+        }
+
         static ALWAYS_INLINE JSValue* makeInt(int32_t value)
         {
-            return reinterpret_cast<JSValue*>((value << IntegerPayloadShift) | TagBitTypeInteger);
+            return makeValue((value << IntegerPayloadShift) | TagBitTypeInteger);
         }
         
         static ALWAYS_INLINE JSValue* makeBool(bool b)
         {
-            return reinterpret_cast<JSValue*>((static_cast<uintptr_t>(b) << ExtendedPayloadShift) | FullTagTypeBool);
+            return makeValue((static_cast<uintptr_t>(b) << ExtendedPayloadShift) | FullTagTypeBool);
         }
         
         static ALWAYS_INLINE JSValue* makeUndefined()
         {
-            return reinterpret_cast<JSValue*>(FullTagTypeUndefined);
+            return makeValue(FullTagTypeUndefined);
         }
         
         static ALWAYS_INLINE JSValue* makeNull()
         {
-            return reinterpret_cast<JSValue*>(FullTagTypeNull);
+            return makeValue(FullTagTypeNull);
         }
         
         static ALWAYS_INLINE int32_t intValue(const JSValue* v)
         {
-            return static_cast<int32_t>(reinterpret_cast<intptr_t>(v) >> IntegerPayloadShift);
+            return static_cast<int32_t>(static_cast<intptr_t>(rawValue(v)) >> IntegerPayloadShift);
         }
         
         static ALWAYS_INLINE uint32_t uintValue(const JSValue* v)
@@ -305,7 +313,7 @@ namespace JSC {
     ALWAYS_INLINE JSValue* JSImmediate::oneImmediate() { return makeInt(1); }
 
     // This value is impossible because 0x4 is not a valid pointer but a tag of 0 would indicate non-immediate
-    ALWAYS_INLINE JSValue* JSImmediate::impossibleValue() { return reinterpret_cast<JSValue*>(0x4); }
+    ALWAYS_INLINE JSValue* JSImmediate::impossibleValue() { return makeValue(0x4); }
 
     ALWAYS_INLINE bool JSImmediate::toBoolean(const JSValue* v)
     {
@@ -350,42 +358,42 @@ namespace JSC {
     ALWAYS_INLINE JSValue* JSImmediate::from(int i)
     {
         if ((i < minImmediateInt) | (i > maxImmediateInt))
-            return 0;
+            return noValue();
         return makeInt(i);
     }
 
     ALWAYS_INLINE JSValue* JSImmediate::from(unsigned i)
     {
         if (i > maxImmediateUInt)
-            return 0;
+            return noValue();
         return makeInt(i);
     }
 
     ALWAYS_INLINE JSValue* JSImmediate::from(long i)
     {
         if ((i < minImmediateInt) | (i > maxImmediateInt))
-            return 0;
+            return noValue();
         return makeInt(i);
     }
 
     ALWAYS_INLINE JSValue* JSImmediate::from(unsigned long i)
     {
         if (i > maxImmediateUInt)
-            return 0;
+            return noValue();
         return makeInt(i);
     }
 
     ALWAYS_INLINE JSValue* JSImmediate::from(long long i)
     {
         if ((i < minImmediateInt) | (i > maxImmediateInt))
-            return 0;
+            return noValue();
         return makeInt(static_cast<uintptr_t>(i));
     }
 
     ALWAYS_INLINE JSValue* JSImmediate::from(unsigned long long i)
     {
         if (i > maxImmediateUInt)
-            return 0;
+            return noValue();
         return makeInt(static_cast<uintptr_t>(i));
     }
 
@@ -394,11 +402,11 @@ namespace JSC {
         const int intVal = static_cast<int>(d);
 
         if ((intVal < minImmediateInt) | (intVal > maxImmediateInt))
-            return 0;
+            return noValue();
 
         // Check for data loss from conversion to int.
         if (intVal != d || (!intVal && signbit(d)))
-            return 0;
+            return noValue();
 
         return makeInt(intVal);
     }
index 1116651..430e5f9 100644 (file)
@@ -107,11 +107,19 @@ namespace JSC {
     extern const double NaN;
     extern const double Inf;
 
+    JSNumberCell* asNumberCell(JSValue*);
+
     JSValue* jsNumberCell(JSGlobalData*, double);
     JSValue* jsNaN(JSGlobalData*);
     JSValue* jsNumberCell(ExecState*, double);
     JSValue* jsNaN(ExecState*);
 
+    inline JSNumberCell* asNumberCell(JSValue* value)
+    {
+        ASSERT(asCell(value)->isNumber());
+        return static_cast<JSNumberCell*>(asCell(value));
+    }
+
     ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, double d)
     {
         JSValue* v = JSImmediate::from(d);
@@ -224,8 +232,8 @@ namespace JSC {
 
     inline double JSValue::uncheckedGetNumber() const
     {
-        ASSERT(JSImmediate::isImmediate(this) || asCell()->isNumber());
-        return JSImmediate::isImmediate(this) ? JSImmediate::toDouble(this) : static_cast<const JSNumberCell*>(this)->value();
+        ASSERT(JSImmediate::isImmediate(asValue()) || asCell()->isNumber());
+        return JSImmediate::isImmediate(asValue()) ? JSImmediate::toDouble(asValue()) : asNumberCell(asValue())->value();
     }
 
     inline int32_t JSNumberCell::toInt32() const
@@ -246,7 +254,7 @@ namespace JSC {
 
     ALWAYS_INLINE JSValue* JSValue::toJSNumber(ExecState* exec) const
     {
-        return JSImmediate::isNumber(this) ? const_cast<JSValue*>(this) : jsNumber(exec, this->toNumber(exec));
+        return JSImmediate::isNumber(asValue()) ? asValue() : jsNumber(exec, this->toNumber(exec));
     }
 
 } // namespace JSC
index 010429e..e8171e3 100644 (file)
@@ -125,7 +125,7 @@ void JSObject::put(ExecState* exec, const Identifier& propertyName, JSValue* val
     
     // Check if there are any setters or getters in the prototype chain
     JSValue* prototype;
-    for (JSObject* obj = this; !obj->structureID()->hasGetterSetterProperties(); obj = static_cast<JSObject*>(prototype)) {
+    for (JSObject* obj = this; !obj->structureID()->hasGetterSetterProperties(); obj = asObject(prototype)) {
         prototype = obj->prototype();
         if (prototype->isNull()) {
             putDirect(propertyName, value, 0, true, slot);
@@ -137,10 +137,10 @@ void JSObject::put(ExecState* exec, const Identifier& propertyName, JSValue* val
     if ((m_structureID->propertyMap().get(propertyName, attributes) != WTF::notFound) && attributes & ReadOnly)
         return;
 
-    for (JSObject* obj = this; ; obj = static_cast<JSObject*>(prototype)) {
+    for (JSObject* obj = this; ; obj = asObject(prototype)) {
         if (JSValue* gs = obj->getDirect(propertyName)) {
             if (gs->isGetterSetter()) {
-                JSObject* setterFunc = static_cast<GetterSetter*>(gs)->setter();        
+                JSObject* setterFunc = asGetterSetter(gs)->setter();        
                 if (!setterFunc) {
                     throwSetterError(exec);
                     return;
@@ -245,7 +245,7 @@ static ALWAYS_INLINE JSValue* callDefaultValueFunction(ExecState* exec, const JS
     if (exec->hadException())
         return exec->exception();
     if (result->isObject())
-        return 0;
+        return noValue();
     return result;
 }
 
@@ -293,8 +293,7 @@ void JSObject::defineGetter(ExecState* exec, const Identifier& propertyName, JSO
     JSValue* object = getDirect(propertyName);
     if (object && object->isGetterSetter()) {
         ASSERT(m_structureID->hasGetterSetterProperties());
-        GetterSetter* getterSetter = static_cast<GetterSetter*>(object);
-        getterSetter->setGetter(getterFunction);
+        asGetterSetter(object)->setGetter(getterFunction);
         return;
     }
 
@@ -321,8 +320,7 @@ void JSObject::defineSetter(ExecState* exec, const Identifier& propertyName, JSO
     JSValue* object = getDirect(propertyName);
     if (object && object->isGetterSetter()) {
         ASSERT(m_structureID->hasGetterSetterProperties());
-        GetterSetter* getterSetter = static_cast<GetterSetter*>(object);
-        getterSetter->setSetter(setterFunction);
+        asGetterSetter(object)->setSetter(setterFunction);
         return;
     }
 
@@ -352,7 +350,7 @@ JSValue* JSObject::lookupGetter(ExecState*, const Identifier& propertyName)
         if (value) {
             if (!value->isGetterSetter())
                 return jsUndefined();
-            JSObject* functionObject = static_cast<GetterSetter*>(value)->getter();
+            JSObject* functionObject = asGetterSetter(value)->getter();
             if (!functionObject)
                 return jsUndefined();
             return functionObject;
@@ -360,7 +358,7 @@ JSValue* JSObject::lookupGetter(ExecState*, const Identifier& propertyName)
 
         if (!object->prototype() || !object->prototype()->isObject())
             return jsUndefined();
-        object = static_cast<JSObject*>(object->prototype());
+        object = asObject(object->prototype());
     }
 }
 
@@ -372,7 +370,7 @@ JSValue* JSObject::lookupSetter(ExecState*, const Identifier& propertyName)
         if (value) {
             if (!value->isGetterSetter())
                 return jsUndefined();
-            JSObject* functionObject = static_cast<GetterSetter*>(value)->setter();
+            JSObject* functionObject = asGetterSetter(value)->setter();
             if (!functionObject)
                 return jsUndefined();
             return functionObject;
@@ -380,7 +378,7 @@ JSValue* JSObject::lookupSetter(ExecState*, const Identifier& propertyName)
 
         if (!object->prototype() || !object->prototype()->isObject())
             return jsUndefined();
-        object = static_cast<JSObject*>(object->prototype());
+        object = asObject(object->prototype());
     }
 }
 
@@ -394,7 +392,7 @@ bool JSObject::hasInstance(ExecState* exec, JSValue* value, JSValue* proto)
     if (!value->isObject())
         return false;
 
-    JSObject* object = static_cast<JSObject*>(value);
+    JSObject* object = asObject(value);
     while ((object = object->prototype()->getObject())) {
         if (object == proto)
             return true;
@@ -497,7 +495,7 @@ void JSObject::putDirectFunctionWithoutTransition(ExecState* exec, InternalFunct
 
 NEVER_INLINE void JSObject::fillGetterPropertySlot(PropertySlot& slot, JSValue** location)
 {
-    if (JSObject* getterFunction = static_cast<GetterSetter*>(*location)->getter())
+    if (JSObject* getterFunction = asGetterSetter(*location)->getter())
         slot.setGetterSlot(getterFunction);
     else
         slot.setUndefined();
index f690fc1..15b576c 100644 (file)
@@ -123,7 +123,7 @@ namespace JSC {
         JSValue* getDirect(const Identifier& propertyName) const
         {
             size_t offset = m_structureID->propertyMap().get(propertyName);
-            return offset != WTF::notFound ? m_propertyStorage[offset] : 0;
+            return offset != WTF::notFound ? m_propertyStorage[offset] : noValue();
         }
 
         JSValue** getDirectLocation(const Identifier& propertyName)
@@ -198,7 +198,15 @@ namespace JSC {
         JSValue* m_inlineStorage[inlineStorageCapacity];
     };
 
-  JSObject* constructEmptyObject(ExecState*);
+    JSObject* asObject(JSValue*);
+
+    JSObject* constructEmptyObject(ExecState*);
+
+inline JSObject* asObject(JSValue* value)
+{
+    ASSERT(asCell(value)->isObject());
+    return static_cast<JSObject*>(asCell(value));
+}
 
 inline JSObject::JSObject(PassRefPtr<StructureID> structureID)
     : JSCell(structureID.releaseRef()) // ~JSObject balances this ref()
@@ -255,12 +263,12 @@ inline bool JSCell::isObject(const ClassInfo* info) const
 // this method is here to be after the inline declaration of JSCell::isObject
 inline bool JSValue::isObject(const ClassInfo* classInfo) const
 {
-    return !JSImmediate::isImmediate(this) && asCell()->isObject(classInfo);
+    return !JSImmediate::isImmediate(asValue()) && asCell()->isObject(classInfo);
 }
 
 inline JSValue* JSObject::get(ExecState* exec, const Identifier& propertyName) const
 {
-    PropertySlot slot(const_cast<JSObject*>(this));
+    PropertySlot slot(this);
     if (const_cast<JSObject*>(this)->getPropertySlot(exec, propertyName, slot))
         return slot.getValue(exec, propertyName);
     
@@ -269,7 +277,7 @@ inline JSValue* JSObject::get(ExecState* exec, const Identifier& propertyName) c
 
 inline JSValue* JSObject::get(ExecState* exec, unsigned propertyName) const
 {
-    PropertySlot slot(const_cast<JSObject*>(this));
+    PropertySlot slot(this);
     if (const_cast<JSObject*>(this)->getPropertySlot(exec, propertyName, slot))
         return slot.getValue(exec, propertyName);
 
@@ -289,7 +297,7 @@ inline bool JSObject::getPropertySlot(ExecState* exec, const Identifier& propert
         if (!prototype->isObject())
             return false;
 
-        object = static_cast<JSObject*>(prototype);
+        object = asObject(prototype);
     }
 }
 
@@ -305,7 +313,7 @@ inline bool JSObject::getPropertySlot(ExecState* exec, unsigned propertyName, Pr
         if (!prototype->isObject())
             break;
 
-        object = static_cast<JSObject*>(prototype);
+        object = asObject(prototype);
     }
 
     return false;
@@ -439,19 +447,19 @@ inline JSValue* JSObject::toPrimitive(ExecState* exec, PreferredPrimitiveType pr
 
 inline JSValue* JSValue::get(ExecState* exec, const Identifier& propertyName) const
 {
-    PropertySlot slot(const_cast<JSValue*>(this));
+    PropertySlot slot(this);
     return get(exec, propertyName, slot);
 }
 
 inline JSValue* JSValue::get(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) const
 {
-    if (UNLIKELY(JSImmediate::isImmediate(this))) {
-        JSObject* prototype = JSImmediate::prototype(this, exec);
+    if (UNLIKELY(JSImmediate::isImmediate(asValue()))) {
+        JSObject* prototype = JSImmediate::prototype(asValue(), exec);
         if (!prototype->getPropertySlot(exec, propertyName, slot))
             return jsUndefined();
         return slot.getValue(exec, propertyName);
     }
-    JSCell* cell = static_cast<JSCell*>(const_cast<JSValue*>(this));
+    JSCell* cell = asCell();
     while (true) {
         if (cell->getOwnPropertySlot(exec, propertyName, slot))
             return slot.getValue(exec, propertyName);
@@ -459,20 +467,20 @@ inline JSValue* JSValue::get(ExecState* exec, const Identifier& propertyName, Pr
         JSValue* prototype = static_cast<JSObject*>(cell)->prototype();
         if (!prototype->isObject())
             return jsUndefined();
-        cell = static_cast<JSCell*>(prototype);
+        cell = asObject(prototype);
     }
 }
 
 inline JSValue* JSValue::get(ExecState* exec, unsigned propertyName) const
 {
-    PropertySlot slot(const_cast<JSValue*>(this));
+    PropertySlot slot(this);
     return get(exec, propertyName, slot);
 }
 
 inline JSValue* JSValue::get(ExecState* exec, unsigned propertyName, PropertySlot& slot) const
 {
-    if (UNLIKELY(JSImmediate::isImmediate(this))) {
-        JSObject* prototype = JSImmediate::prototype(this, exec);
+    if (UNLIKELY(JSImmediate::isImmediate(asValue()))) {
+        JSObject* prototype = JSImmediate::prototype(asValue(), exec);
         if (!prototype->getPropertySlot(exec, propertyName, slot))
             return jsUndefined();
         return slot.getValue(exec, propertyName);
@@ -485,14 +493,14 @@ inline JSValue* JSValue::get(ExecState* exec, unsigned propertyName, PropertySlo
         JSValue* prototype = static_cast<JSObject*>(cell)->prototype();
         if (!prototype->isObject())
             return jsUndefined();
-        cell = static_cast<JSCell*>(prototype);
+        cell = prototype->asCell();
     }
 }
 
 inline void JSValue::put(ExecState* exec, const Identifier& propertyName, JSValue* value, PutPropertySlot& slot)
 {
-    if (UNLIKELY(JSImmediate::isImmediate(this))) {
-        JSImmediate::toObject(this, exec)->put(exec, propertyName, value, slot);
+    if (UNLIKELY(JSImmediate::isImmediate(asValue()))) {
+        JSImmediate::toObject(asValue(), exec)->put(exec, propertyName, value, slot);
         return;
     }
     asCell()->put(exec, propertyName, value, slot);
@@ -500,8 +508,8 @@ inline void JSValue::put(ExecState* exec, const Identifier& propertyName, JSValu
 
 inline void JSValue::put(ExecState* exec, unsigned propertyName, JSValue* value)
 {
-    if (UNLIKELY(JSImmediate::isImmediate(this))) {
-        JSImmediate::toObject(this, exec)->put(exec, propertyName, value);
+    if (UNLIKELY(JSImmediate::isImmediate(asValue()))) {
+        JSImmediate::toObject(asValue(), exec)->put(exec, propertyName, value);
         return;
     }
     asCell()->put(exec, propertyName, value);
@@ -511,14 +519,14 @@ ALWAYS_INLINE void JSObject::allocatePropertyStorageInline(size_t oldSize, size_
 {
     ASSERT(newSize > oldSize);
 
-    JSValue** oldPropertStorage = m_propertyStorage;
+    JSValue** oldPropertyStorage = m_propertyStorage;
     m_propertyStorage = new JSValue*[newSize];
 
     for (unsigned i = 0; i < oldSize; ++i)
-        m_propertyStorage[i] = oldPropertStorage[i];
+        m_propertyStorage[i] = oldPropertyStorage[i];
 
-    if (oldPropertStorage != m_inlineStorage)
-        delete [] oldPropertStorage;
+    if (oldPropertyStorage != m_inlineStorage)
+        delete [] oldPropertyStorage;
 }
 
 } // namespace JSC
index 5844290..49503d5 100644 (file)
@@ -91,8 +91,7 @@ bool JSString::getOwnPropertySlot(ExecState* exec, const Identifier& propertyNam
     slot.setBase(this);
     JSObject* object;
     for (JSValue* prototype = exec->lexicalGlobalObject()->stringPrototype(); !prototype->isNull(); prototype = object->prototype()) {
-        ASSERT(prototype->isObject());
-        object = static_cast<JSObject*>(prototype);
+        object = asObject(prototype);
         if (object->getOwnPropertySlot(exec, propertyName, slot))
             return true;
     }
index d7c37bf..b6275e7 100644 (file)
@@ -117,6 +117,14 @@ namespace JSC {
         UString m_value;
     };
 
+    JSString* asString(JSValue*);
+
+    inline JSString* asString(JSValue* value)
+    {
+        ASSERT(asCell(value)->isString());
+        return static_cast<JSString*>(asCell(value));
+    }
+
     inline JSString* jsEmptyString(JSGlobalData* globalData)
     {
         return globalData->smallStrings.emptyString(globalData);
@@ -198,7 +206,7 @@ namespace JSC {
 
     inline JSString* JSValue::toThisJSString(ExecState* exec)
     {
-        return JSImmediate::isImmediate(this) ? jsString(exec, JSImmediate::toString(this)) : asCell()->toThisJSString(exec);
+        return JSImmediate::isImmediate(asValue()) ? jsString(exec, JSImmediate::toString(asValue())) : asCell()->toThisJSString(exec);
     }
 
 } // namespace JSC
index d0e4513..7b01a06 100644 (file)
@@ -43,9 +43,12 @@ namespace JSC {
     class PropertySlot;
     class PutPropertySlot;
     class StructureID;
+
     struct ClassInfo;
     struct Instruction;
 
+    enum PreferredPrimitiveType { NoPreference, PreferNumber, PreferString };
+
     /**
      * JSValue is the base type for all primitives (Undefined, Null, Boolean,
      * String, Number) and objects in ECMAScript.
@@ -92,7 +95,6 @@ namespace JSC {
         bool getTruncatedUInt32(uint32_t&) const;
         
         // Basic conversions.
-        enum PreferredPrimitiveType { NoPreference, PreferNumber, PreferString };
         JSValue* toPrimitive(ExecState*, PreferredPrimitiveType = NoPreference) const;
         bool getPrimitiveNumber(ExecState*, double& number, JSValue*&);
 
@@ -144,8 +146,9 @@ namespace JSC {
 
         JSValue* getJSNumber(); // 0 if this is not a JSNumber or number object
 
-        JSCell* asCell();
-        const JSCell* asCell() const;
+        JSValue* asValue() const;
+
+        JSCell* asCell() const;
 
     private:
         bool getPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
@@ -162,30 +165,35 @@ namespace JSC {
     {
     }
 
+    inline JSValue* JSValue::asValue() const
+    {
+        return const_cast<JSValue*>(this);
+    }
+
     inline bool JSValue::isUndefined() const
     {
-        return this == jsUndefined();
+        return asValue() == jsUndefined();
     }
 
     inline bool JSValue::isNull() const
     {
-        return this == jsNull();
+        return asValue() == jsNull();
     }
 
     inline bool JSValue::isUndefinedOrNull() const
     {
-        return JSImmediate::isUndefinedOrNull(this);
+        return JSImmediate::isUndefinedOrNull(asValue());
     }
 
     inline bool JSValue::isBoolean() const
     {
-        return JSImmediate::isBoolean(this);
+        return JSImmediate::isBoolean(asValue());
     }
 
     inline bool JSValue::getBoolean(bool& v) const
     {
-        if (JSImmediate::isBoolean(this)) {
-            v = JSImmediate::toBoolean(this);
+        if (JSImmediate::isBoolean(asValue())) {
+            v = JSImmediate::toBoolean(asValue());
             return true;
         }
         
@@ -194,7 +202,7 @@ namespace JSC {
 
     inline bool JSValue::getBoolean() const
     {
-        return this == jsBoolean(true);
+        return asValue() == jsBoolean(true);
     }
 
     ALWAYS_INLINE int32_t JSValue::toInt32(ExecState* exec) const
index a53e798..42a8063 100644 (file)
@@ -77,14 +77,14 @@ JSValue* objectProtoFuncIsPrototypeOf(ExecState* exec, JSObject*, JSValue* thisV
     if (!args.at(exec, 0)->isObject())
         return jsBoolean(false);
 
-    JSValue* v = static_cast<JSObject*>(args.at(exec, 0))->prototype();
+    JSValue* v = asObject(args.at(exec, 0))->prototype();
 
     while (true) {
         if (!v->isObject())
             return jsBoolean(false);
         if (thisObj == v)\v
             return jsBoolean(true);
-        v = static_cast<JSObject*>(v)->prototype();
+        v = asObject(v)->prototype();
     }
 }
 
@@ -93,7 +93,7 @@ JSValue* objectProtoFuncDefineGetter(ExecState* exec, JSObject*, JSValue* thisVa
     CallData callData;
     if (args.at(exec, 1)->getCallData(callData) == CallTypeNone)
         return throwError(exec, SyntaxError, "invalid getter usage");
-    thisValue->toThisObject(exec)->defineGetter(exec, Identifier(exec, args.at(exec, 0)->toString(exec)), static_cast<JSObject*>(args.at(exec, 1)));
+    thisValue->toThisObject(exec)->defineGetter(exec, Identifier(exec, args.at(exec, 0)->toString(exec)), asObject(args.at(exec, 1)));
     return jsUndefined();
 }
 
@@ -102,7 +102,7 @@ JSValue* objectProtoFuncDefineSetter(ExecState* exec, JSObject*, JSValue* thisVa
     CallData callData;
     if (args.at(exec, 1)->getCallData(callData) == CallTypeNone)
         return throwError(exec, SyntaxError, "invalid setter usage");
-    thisValue->toThisObject(exec)->defineSetter(exec, Identifier(exec, args.at(exec, 0)->toString(exec)), static_cast<JSObject*>(args.at(exec, 1)));
+    thisValue->toThisObject(exec)->defineSetter(exec, Identifier(exec, args.at(exec, 0)->toString(exec)), asObject(args.at(exec, 1)));
     return jsUndefined();
 }
 
index bd5312f..29c19d4 100644 (file)
@@ -44,8 +44,8 @@ namespace JSC {
             clearValue();
         }
 
-        explicit PropertySlot(JSValue* base)
-            : m_slotBase(base)
+        explicit PropertySlot(const JSValue* base)
+            : m_slotBase(const_cast<JSValue*>(base))
             , m_offset(WTF::notFound)
         {
             clearValue();
@@ -176,14 +176,14 @@ namespace JSC {
         void clearBase()
         {
 #ifndef NDEBUG
-            m_slotBase = 0;
+            m_slotBase = noValue();
 #endif
         }
 
         void clearValue()
         {
 #ifndef NDEBUG
-            m_value = 0;
+            m_value = noValue();
 #endif
         }
 
index 68a309a..06c8405 100644 (file)
@@ -228,77 +228,77 @@ bool RegExpConstructor::getOwnPropertySlot(ExecState* exec, const Identifier& pr
 
 JSValue* regExpConstructorDollar1(ExecState* exec, const Identifier&, const PropertySlot& slot)
 {
-    return static_cast<RegExpConstructor*>(slot.slotBase())->getBackref(exec, 1);
+    return asRegExpConstructor(slot.slotBase())->getBackref(exec, 1);
 }
 
 JSValue* regExpConstructorDollar2(ExecState* exec, const Identifier&, const PropertySlot& slot)
 {
-    return static_cast<RegExpConstructor*>(slot.slotBase())->getBackref(exec, 2);
+    return asRegExpConstructor(slot.slotBase())->getBackref(exec, 2);
 }
 
 JSValue* regExpConstructorDollar3(ExecState* exec, const Identifier&, const PropertySlot& slot)
 {
-    return static_cast<RegExpConstructor*>(slot.slotBase())->getBackref(exec, 3);
+    return asRegExpConstructor(slot.slotBase())->getBackref(exec, 3);
 }
 
 JSValue* regExpConstructorDollar4(ExecState* exec, const Identifier&, const PropertySlot& slot)
 {
-    return static_cast<RegExpConstructor*>(slot.slotBase())->getBackref(exec, 4);
+    return asRegExpConstructor(slot.slotBase())->getBackref(exec, 4);
 }
 
 JSValue* regExpConstructorDollar5(ExecState* exec, const Identifier&, const PropertySlot& slot)
 {
-    return static_cast<RegExpConstructor*>(slot.slotBase())->getBackref(exec, 5);
+    return asRegExpConstructor(slot.slotBase())->getBackref(exec, 5);
 }
 
 JSValue* regExpConstructorDollar6(ExecState* exec, const Identifier&, const PropertySlot& slot)
 {
-    return static_cast<RegExpConstructor*>(slot.slotBase())->getBackref(exec, 6);
+    return asRegExpConstructor(slot.slotBase())->getBackref(exec, 6);
 }
 
 JSValue* regExpConstructorDollar7(ExecState* exec, const Identifier&, const PropertySlot& slot)
 {
-    return static_cast<RegExpConstructor*>(slot.slotBase())->getBackref(exec, 7);
+    return asRegExpConstructor(slot.slotBase())->getBackref(exec, 7);
 }
 
 JSValue* regExpConstructorDollar8(ExecState* exec, const Identifier&, const PropertySlot& slot)
 {
-    return static_cast<RegExpConstructor*>(slot.slotBase())->getBackref(exec, 8);
+    return asRegExpConstructor(slot.slotBase())->getBackref(exec, 8);
 }
 
 JSValue* regExpConstructorDollar9(ExecState* exec, const Identifier&, const PropertySlot& slot)
 {
-    return static_cast<RegExpConstructor*>(slot.slotBase())->getBackref(exec, 9);
+    return asRegExpConstructor(slot.slotBase())->getBackref(exec, 9);
 }
 
 JSValue* regExpConstructorInput(ExecState* exec, const Identifier&, const PropertySlot& slot)
 {
-    return jsString(exec, static_cast<RegExpConstructor*>(slot.slotBase())->input());
+    return jsString(exec, asRegExpConstructor(slot.slotBase())->input());
 }
 
 JSValue* regExpConstructorMultiline(ExecState*, const Identifier&, const PropertySlot& slot)
 {
-    return jsBoolean(static_cast<RegExpConstructor*>(slot.slotBase())->multiline());
+    return jsBoolean(asRegExpConstructor(slot.slotBase())->multiline());
 }
 
 JSValue* regExpConstructorLastMatch(ExecState* exec, const Identifier&, const PropertySlot& slot)
 {
-    return static_cast<RegExpConstructor*>(slot.slotBase())->getBackref(exec, 0);
+    return asRegExpConstructor(slot.slotBase())->getBackref(exec, 0);
 }
 
 JSValue* regExpConstructorLastParen(ExecState* exec, const Identifier&, const PropertySlot& slot)
 {
-    return static_cast<RegExpConstructor*>(slot.slotBase())->getLastParen(exec);
+    return asRegExpConstructor(slot.slotBase())->getLastParen(exec);
 }
 
 JSValue* regExpConstructorLeftContext(ExecState* exec, const Identifier&, const PropertySlot& slot)
 {
-    return static_cast<RegExpConstructor*>(slot.slotBase())->getLeftContext(exec);
+    return asRegExpConstructor(slot.slotBase())->getLeftContext(exec);
 }
 
 JSValue* regExpConstructorRightContext(ExecState* exec, const Identifier&, const PropertySlot& slot)
 {
-    return static_cast<RegExpConstructor*>(slot.slotBase())->getRightContext(exec);
+    return asRegExpConstructor(slot.slotBase())->getRightContext(exec);
 }
 
 void RegExpConstructor::put(ExecState* exec, const Identifier& propertyName, JSValue* value, PutPropertySlot& slot)
@@ -308,12 +308,12 @@ void RegExpConstructor::put(ExecState* exec, const Identifier& propertyName, JSV
 
 void setRegExpConstructorInput(ExecState* exec, JSObject* baseObject, JSValue* value)
 {
-    static_cast<RegExpConstructor*>(baseObject)->setInput(value->toString(exec));
+    asRegExpConstructor(baseObject)->setInput(value->toString(exec));
 }
 
 void setRegExpConstructorMultiline(ExecState* exec, JSObject* baseObject, JSValue* value)
 {
-    static_cast<RegExpConstructor*>(baseObject)->setMultiline(value->toBoolean(exec));
+    asRegExpConstructor(baseObject)->setMultiline(value->toBoolean(exec));
 }
   
 // ECMA 15.10.4
@@ -325,7 +325,7 @@ JSObject* constructRegExp(ExecState* exec, const ArgList& args)
     if (arg0->isObject(&RegExpObject::info)) {
         if (!arg1->isUndefined())
             return throwError(exec, TypeError, "Cannot supply flags when constructing one RegExp from another.");
-        return static_cast<JSObject*>(arg0);
+        return asObject(arg0);
     }
 
     UString pattern = arg0->isUndefined() ? UString("") : arg0->toString(exec);
index e9665f0..18c1bd2 100644 (file)
@@ -62,8 +62,16 @@ namespace JSC {
         OwnPtr<RegExpConstructorPrivate> d;
     };
 
+    RegExpConstructor* asRegExpConstructor(JSValue*);
+
     JSObject* constructRegExp(ExecState*, const ArgList&);
 
+    inline RegExpConstructor* asRegExpConstructor(JSValue* value)
+    {
+        ASSERT(asObject(value)->inherits(&RegExpConstructor::info));
+        return static_cast<RegExpConstructor*>(asObject(value));
+    }
+
 } // namespace JSC
 
 #endif // RegExpConstructor_h
index 30896a2..127a71e 100644 (file)
@@ -73,27 +73,27 @@ bool RegExpObject::getOwnPropertySlot(ExecState* exec, const Identifier& propert
 
 JSValue* regExpObjectGlobal(ExecState*, const Identifier&, const PropertySlot& slot)
 {
-    return jsBoolean(static_cast<RegExpObject*>(slot.slotBase())->regExp()->global());
+    return jsBoolean(asRegExpObject(slot.slotBase())->regExp()->global());
 }
 
 JSValue* regExpObjectIgnoreCase(ExecState*, const Identifier&, const PropertySlot& slot)
 {
-    return jsBoolean(static_cast<RegExpObject*>(slot.slotBase())->regExp()->ignoreCase());
+    return jsBoolean(asRegExpObject(slot.slotBase())->regExp()->ignoreCase());
 }
  
 JSValue* regExpObjectMultiline(ExecState*, const Identifier&, const PropertySlot& slot)
 {            
-    return jsBoolean(static_cast<RegExpObject*>(slot.slotBase())->regExp()->multiline());
+    return jsBoolean(asRegExpObject(slot.slotBase())->regExp()->multiline());
 }
 
 JSValue* regExpObjectSource(ExecState* exec, const Identifier&, const PropertySlot& slot)
 {
-    return jsString(exec, static_cast<RegExpObject*>(slot.slotBase())->regExp()->pattern());
+    return jsString(exec, asRegExpObject(slot.slotBase())->regExp()->pattern());
 }
 
 JSValue* regExpObjectLastIndex(ExecState* exec, const Identifier&, const PropertySlot& slot)
 {
-    return jsNumber(exec, static_cast<RegExpObject*>(slot.slotBase())->lastIndex());
+    return jsNumber(exec, asRegExpObject(slot.slotBase())->lastIndex());
 }
 
 void RegExpObject::put(ExecState* exec, const Identifier& propertyName, JSValue* value, PutPropertySlot& slot)
@@ -103,7 +103,7 @@ void RegExpObject::put(ExecState* exec, const Identifier& propertyName, JSValue*
 
 void setRegExpObjectLastIndex(ExecState* exec, JSObject* baseObject, JSValue* value)
 {
-    static_cast<RegExpObject*>(baseObject)->setLastIndex(value->toInteger(exec));
+    asRegExpObject(baseObject)->setLastIndex(value->toInteger(exec));
 }
 
 bool RegExpObject::match(ExecState* exec, const ArgList& args)
@@ -157,7 +157,7 @@ JSValue* RegExpObject::exec(ExecState* exec, const ArgList& args)
 
 static JSValue* callRegExpObject(ExecState* exec, JSObject* function, JSValue*, const ArgList& args)
 {
-    return static_cast<RegExpObject*>(function)->exec(exec, args);
+    return asRegExpObject(function)->exec(exec, args);
 }
 
 CallType RegExpObject::getCallData(CallData& callData)
index 7568212..5089f71 100644 (file)
@@ -65,6 +65,14 @@ namespace JSC {
         OwnPtr<RegExpObjectData> d;
     };
 
+    RegExpObject* asRegExpObject(JSValue*);
+
+    inline RegExpObject* asRegExpObject(JSValue* value)
+    {
+        ASSERT(asObject(value)->inherits(&RegExpObject::info));
+        return static_cast<RegExpObject*>(asObject(value));
+    }
+
 } // namespace JSC
 
 #endif // RegExpObject_h
index ee2a2d2..09131f3 100644 (file)
@@ -59,14 +59,14 @@ JSValue* regExpProtoFuncTest(ExecState* exec, JSObject*, JSValue* thisValue, con
 {
     if (!thisValue->isObject(&RegExpObject::info))
         return throwError(exec, TypeError);
-    return static_cast<RegExpObject*>(thisValue)->test(exec, args);
+    return asRegExpObject(thisValue)->test(exec, args);
 }
 
 JSValue* regExpProtoFuncExec(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
     if (!thisValue->isObject(&RegExpObject::info))
         return throwError(exec, TypeError);
-    return static_cast<RegExpObject*>(thisValue)->exec(exec, args);
+    return asRegExpObject(thisValue)->exec(exec, args);
 }
 
 JSValue* regExpProtoFuncCompile(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
@@ -81,7 +81,7 @@ JSValue* regExpProtoFuncCompile(ExecState* exec, JSObject*, JSValue* thisValue,
     if (arg0->isObject(&RegExpObject::info)) {
         if (!arg1->isUndefined())
             return throwError(exec, TypeError, "Cannot supply flags when constructing one RegExp from another.");
-        regExp = static_cast<RegExpObject*>(arg0)->regExp();
+        regExp = asRegExpObject(arg0)->regExp();
     } else {
         UString pattern = args.isEmpty() ? UString("") : arg0->toString(exec);
         UString flags = arg1->isUndefined() ? UString("") : arg1->toString(exec);
@@ -91,8 +91,8 @@ JSValue* regExpProtoFuncCompile(ExecState* exec, JSObject*, JSValue* thisValue,
     if (!regExp->isValid())
         return throwError(exec, SyntaxError, UString("Invalid regular expression: ").append(regExp->errorMessage()));
 
-    static_cast<RegExpObject*>(thisValue)->setRegExp(regExp.release());
-    static_cast<RegExpObject*>(thisValue)->setLastIndex(0);
+    asRegExpObject(thisValue)->setRegExp(regExp.release());
+    asRegExpObject(thisValue)->setLastIndex(0);
     return jsUndefined();
 }
 
@@ -104,13 +104,13 @@ JSValue* regExpProtoFuncToString(ExecState* exec, JSObject*, JSValue* thisValue,
         return throwError(exec, TypeError);
     }
 
-    UString result = "/" + static_cast<RegExpObject*>(thisValue)->get(exec, exec->propertyNames().source)->toString(exec);
+    UString result = "/" + asRegExpObject(thisValue)->get(exec, exec->propertyNames().source)->toString(exec);
     result.append('/');
-    if (static_cast<RegExpObject*>(thisValue)->get(exec, exec->propertyNames().global)->toBoolean(exec))
+    if (asRegExpObject(thisValue)->get(exec, exec->propertyNames().global)->toBoolean(exec))
         result.append('g');
-    if (static_cast<RegExpObject*>(thisValue)->get(exec, exec->propertyNames().ignoreCase)->toBoolean(exec))
+    if (asRegExpObject(thisValue)->get(exec, exec->propertyNames().ignoreCase)->toBoolean(exec))
         result.append('i');
-    if (static_cast<RegExpObject*>(thisValue)->get(exec, exec->propertyNames().multiline)->toBoolean(exec))
+    if (asRegExpObject(thisValue)->get(exec, exec->propertyNames().multiline)->toBoolean(exec))
         result.append('m');
     return jsNontrivialString(exec, result);
 }
index 6a6807e..37d552c 100644 (file)
@@ -43,7 +43,7 @@ namespace JSC {
         virtual const ClassInfo* classInfo() const { return &info; }
         static const ClassInfo info;
 
-        JSString* internalValue() const { return static_cast<JSString*>(JSWrapperObject::internalValue());}
+        JSString* internalValue() const { return asString(JSWrapperObject::internalValue());}
 
     protected:
         StringObject(PassRefPtr<StructureID>, JSString*);
@@ -54,6 +54,14 @@ namespace JSC {
         virtual JSString* toThisJSString(ExecState*);
   };
 
+    StringObject* asStringObject(JSValue*);
+
+    inline StringObject* asStringObject(JSValue* value)
+    {
+        ASSERT(asObject(value)->inherits(&StringObject::info));
+        return static_cast<StringObject*>(asObject(value));
+    }
+
 } // namespace JSC
 
 #endif // StringObject_h
index f34caa9..c9efe7f 100644 (file)
@@ -218,7 +218,7 @@ JSValue* stringProtoFuncReplace(ExecState* exec, JSObject*, JSValue* thisValue,
         replacementString = replacement->toString(exec);
 
     if (pattern->isObject(&RegExpObject::info)) {
-        RegExp* reg = static_cast<RegExpObject*>(pattern)->regExp();
+        RegExp* reg = asRegExpObject(pattern)->regExp();
         bool global = reg->global();
 
         RegExpConstructor* regExpObj = exec->lexicalGlobalObject()->regExpConstructor();
@@ -313,7 +313,7 @@ JSValue* stringProtoFuncToString(ExecState* exec, JSObject*, JSValue* thisValue,
         return thisValue;
 
     if (thisValue->isObject(&StringObject::info))
-        return static_cast<StringObject*>(thisValue)->internalValue();
+        return asStringObject(thisValue)->internalValue();
 
     return throwError(exec, TypeError);
 }
@@ -404,8 +404,8 @@ JSValue* stringProtoFuncMatch(ExecState* exec, JSObject*, JSValue* thisValue, co
     UString u = s;
     RefPtr<RegExp> reg;
     RegExpObject* imp = 0;
-    if (a0->isObject() && static_cast<JSObject *>(a0)->inherits(&RegExpObject::info))
-        reg = static_cast<RegExpObject *>(a0)->regExp();
+    if (a0->isObject(&RegExpObject::info))
+        reg = asRegExpObject(a0)->regExp();
     else {
         /*
          *  ECMA 15.5.4.12 String.prototype.search (regexp)
@@ -454,8 +454,8 @@ JSValue* stringProtoFuncSearch(ExecState* exec, JSObject*, JSValue* thisValue, c
 
     UString u = s;
     RefPtr<RegExp> reg;
-    if (a0->isObject() && static_cast<JSObject*>(a0)->inherits(&RegExpObject::info))
-        reg = static_cast<RegExpObject*>(a0)->regExp();
+    if (a0->isObject(&RegExpObject::info))
+        reg = asRegExpObject(a0)->regExp();
     else { 
         /*
          *  ECMA 15.5.4.12 String.prototype.search (regexp)
@@ -506,8 +506,8 @@ JSValue* stringProtoFuncSplit(ExecState* exec, JSObject*, JSValue* thisValue, co
     unsigned i = 0;
     int p0 = 0;
     unsigned limit = a1->isUndefined() ? 0xFFFFFFFFU : a1->toUInt32(exec);
-    if (a0->isObject() && static_cast<JSObject *>(a0)->inherits(&RegExpObject::info)) {
-        RegExp *reg = static_cast<RegExpObject *>(a0)->regExp();
+    if (a0->isObject(&RegExpObject::info)) {
+        RegExp* reg = asRegExpObject(a0)->regExp();
         if (s.isEmpty() && reg->match(s, 0) >= 0) {
             // empty string matched by regexp -> empty array
             return result;
index 2ca7c9b..3c2c032 100644 (file)
@@ -183,7 +183,7 @@ void StructureID::getEnumerablePropertyNames(ExecState* exec, PropertyNameArray&
     }
 
     if (m_prototype->isObject())
-        static_cast<JSObject*>(m_prototype)->getPropertyNames(exec, propertyNames);
+        asObject(m_prototype)->getPropertyNames(exec, propertyNames);
 
     if (shouldCache) {
         if (m_cachedPropertyNameArrayData)
@@ -334,7 +334,7 @@ StructureIDChain* StructureID::createCachedPrototypeChain()
     if (JSImmediate::isImmediate(prototype))
         return 0;
 
-    RefPtr<StructureIDChain> chain = StructureIDChain::create(static_cast<JSObject*>(prototype)->structureID());
+    RefPtr<StructureIDChain> chain = StructureIDChain::create(asObject(prototype)->structureID());
     setCachedPrototypeChain(chain.release());
     return cachedPrototypeChain();
 }
@@ -346,7 +346,7 @@ StructureIDChain::StructureIDChain(StructureID* structureID)
     StructureID* tmp = structureID;
     while (!tmp->storedPrototype()->isNull()) {
         ++size;
-        tmp = static_cast<JSCell*>(tmp->storedPrototype())->structureID();
+        tmp = asCell(tmp->storedPrototype())->structureID();
     }
     
     m_vector.set(new RefPtr<StructureID>[size + 1]);
@@ -354,7 +354,7 @@ StructureIDChain::StructureIDChain(StructureID* structureID)
     size_t i;
     for (i = 0; i < size - 1; ++i) {
         m_vector[i] = structureID;
-        structureID = static_cast<JSObject*>(structureID->storedPrototype())->structureID();
+        structureID = asObject(structureID->storedPrototype())->structureID();
     }
     m_vector[i] = structureID;
     m_vector[i + 1] = 0;
index 4719465..307337f 100644 (file)
@@ -119,8 +119,7 @@ namespace JSC {
     private:
         template <HeapType heapType> void* heapAllocate(size_t);
         template <HeapType heapType> size_t sweep();
-        static const CollectorBlock* cellBlock(const JSCell*);
-        static CollectorBlock* cellBlock(JSCell*);
+        static CollectorBlock* cellBlock(const JSCell*);
         static size_t cellOffset(const JSCell*);
 
         friend class JSGlobalData;
@@ -244,20 +243,14 @@ namespace JSC {
         typedef SmallCellCollectorBlock Block;
     };
 
-    inline bool Heap::isNumber(JSCell* cell)
+    inline CollectorBlock* Heap::cellBlock(const JSCell* cell)
     {
-        CollectorBlock* block = Heap::cellBlock(cell);
-        return block && block->type == NumberHeap;
+        return reinterpret_cast<CollectorBlock*>(reinterpret_cast<uintptr_t>(cell) & BLOCK_MASK);
     }
 
-    inline const CollectorBlock* Heap::cellBlock(const JSCell* cell)
-    {
-        return reinterpret_cast<const CollectorBlock*>(reinterpret_cast<uintptr_t>(cell) & BLOCK_MASK);
-    }
-
-    inline CollectorBlock* Heap::cellBlock(JSCell* cell)
+    inline bool Heap::isNumber(JSCell* cell)
     {
-        return const_cast<CollectorBlock*>(cellBlock(const_cast<const JSCell*>(cell)));
+        return Heap::cellBlock(cell)->type == NumberHeap;
     }
 
     inline size_t Heap::cellOffset(const JSCell* cell)
index ec24220..0aa562a 100644 (file)
@@ -65,11 +65,11 @@ Completion Interpreter::evaluate(ExecState* exec, ScopeChain& scopeChain, const
 
     JSObject* thisObj = (!thisValue || thisValue->isUndefinedOrNull()) ? exec->dynamicGlobalObject() : thisValue->toObject(exec);
 
-    JSValue* exception = 0;
+    JSValue* exception = noValue();
     JSValue* result = exec->machine()->execute(programNode.get(), exec, scopeChain.node(), thisObj, &exception);
 
     if (exception) {
-        if (exception->isObject() && static_cast<JSObject*>(exception)->isWatchdogException())
+        if (exception->isObject() && asObject(exception)->isWatchdogException())
             return Completion(Interrupted, result);
         return Completion(Throw, exception);
     }
index 8d2f7ce..85502dc 100644 (file)
@@ -407,7 +407,7 @@ RegisterID* FunctionCallResolveNode::emitCode(CodeGenerator& generator, Register
 
     int index = 0;
     size_t depth = 0;
-    JSValue* globalObject = 0;
+    JSObject* globalObject = 0;
     if (generator.findScopedProperty(m_ident, index, depth, false, globalObject) && index != missingSymbolMarker()) {
         RefPtr<RegisterID> func = generator.emitGetScopedVar(generator.newTemporary(), depth, index, globalObject);
         return generator.emitCall(generator.finalDestination(dst), func.get(), 0, m_args.get(), m_divot, m_startOffset, m_endOffset);
@@ -466,7 +466,7 @@ RegisterID* PostfixResolveNode::emitCode(CodeGenerator& generator, RegisterID* d
 
     int index = 0;
     size_t depth = 0;
-    JSValue* globalObject = 0;
+    JSObject* globalObject = 0;
     if (generator.findScopedProperty(m_ident, index, depth, true, globalObject) && index != missingSymbolMarker()) {
         RefPtr<RegisterID> value = generator.emitGetScopedVar(generator.newTemporary(), depth, index, globalObject);
         RegisterID* oldValue;
@@ -650,7 +650,7 @@ RegisterID* PrefixResolveNode::emitCode(CodeGenerator& generator, RegisterID* ds
 
     int index = 0;
     size_t depth = 0;
-    JSValue* globalObject = 0;
+    JSObject* globalObject = 0;
     if (generator.findScopedProperty(m_ident, index, depth, false, globalObject) && index != missingSymbolMarker()) {
         RefPtr<RegisterID> propDst = generator.emitGetScopedVar(generator.tempDestination(dst), depth, index, globalObject);
         emitPreIncOrDec(generator, propDst.get(), m_operator);
@@ -893,7 +893,7 @@ RegisterID* ReadModifyResolveNode::emitCode(CodeGenerator& generator, RegisterID
 
     int index = 0;
     size_t depth = 0;
-    JSValue* globalObject = 0;
+    JSObject* globalObject = 0;
     if (generator.findScopedProperty(m_ident, index, depth, true, globalObject) && index != missingSymbolMarker()) {
         RefPtr<RegisterID> src1 = generator.emitGetScopedVar(generator.tempDestination(dst), depth, index, globalObject);
         RegisterID* src2 = generator.emitNode(m_right.get());
@@ -925,7 +925,7 @@ RegisterID* AssignResolveNode::emitCode(CodeGenerator& generator, RegisterID* ds
 
     int index = 0;
     size_t depth = 0;
-    JSValue* globalObject = 0;
+    JSObject* globalObject = 0;
     if (generator.findScopedProperty(m_ident, index, depth, true, globalObject) && index != missingSymbolMarker()) {
         if (dst == ignoredResult())
             dst = 0;
index ff11ce9..fad9720 100644 (file)
@@ -28,9 +28,6 @@
 
 namespace JSC {
 
-  class ExecState;
-  class JSValue;
-
   // ECMA 11.9.3
   bool equal(ExecState*, JSValue*, JSValue*);
   bool equalSlowCase(ExecState*, JSValue*, JSValue*);
@@ -46,7 +43,7 @@ namespace JSC {
           bool s1 = v1->isString();
           bool s2 = v2->isString();
           if (s1 && s2)
-              return static_cast<JSString*>(v1)->value() == static_cast<JSString*>(v2)->value();
+              return asString(v1)->value() == asString(v2)->value();
 
           if (v1->isUndefinedOrNull()) {
               if (v2->isUndefinedOrNull())
@@ -117,18 +114,18 @@ namespace JSC {
           // 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::zeroImmediate())
-              return static_cast<JSCell*>(v2)->isNumber() && static_cast<JSNumberCell*>(v2)->value() == 0;
-          return static_cast<JSCell*>(v1)->isNumber() && static_cast<JSNumberCell*>(v1)->value() == 0;
+              return asCell(v2)->isNumber() && asNumberCell(v2)->value() == 0;
+          return asCell(v1)->isNumber() && asNumberCell(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 (asCell(v1)->isNumber()) {
+          return asCell(v2)->isNumber()
+              && asNumberCell(v1)->value() == asNumberCell(v2)->value();
       }
 
-      if (static_cast<JSCell*>(v1)->isString()) {
-          return static_cast<JSCell*>(v2)->isString()
-              && static_cast<JSString*>(v1)->value() == static_cast<JSString*>(v2)->value();
+      if (asCell(v1)->isString()) {
+          return asCell(v2)->isString()
+              && asString(v1)->value() == asString(v2)->value();
       }
 
       return v1 == v2;
index 4fb8425..2e64bba 100644 (file)
@@ -1,5 +1,25 @@
 2008-10-18  Darin Adler  <darin@apple.com>
 
+        Reviewed by Oliver Hunt.
+
+        - first step of https://bugs.webkit.org/show_bug.cgi?id=21732
+          improve performance by eliminating JSValue as a base class for JSCell
+
+        Update for change to make PreferredPrimitiveType no longer
+        a member of JSValue.
+
+        * bridge/c/c_instance.cpp:
+        (JSC::Bindings::CInstance::defaultValue): Removed JSValue:: prefix.
+        * bridge/jni/jni_instance.cpp:
+        (JavaInstance::defaultValue): Ditto.
+        * bridge/objc/objc_instance.mm:
+        (ObjcInstance::defaultValue): Ditto.
+        * bridge/qt/qt_instance.cpp:
+        (JSC::Bindings::QtInstance::defaultValue): Ditto.
+        * bridge/runtime.h: Ditto. Also removed typedef.
+
+2008-10-18  Darin Adler  <darin@apple.com>
+
         - try to fix Windows build
 
         * rendering/RenderThemeSafari.cpp:
index 9379dbc..3b3b847 100644 (file)
@@ -138,9 +138,9 @@ JSValue* CInstance::invokeDefaultMethod(ExecState* exec, const ArgList& args)
 
 JSValue* CInstance::defaultValue(ExecState* exec, PreferredPrimitiveType hint) const
 {
-    if (hint == JSValue::PreferString)
+    if (hint == PreferString)
         return stringValue(exec);
-    if (hint == JSValue::PreferNumber)
+    if (hint == PreferNumber)
         return numberValue(exec);
     return valueOf(exec);
 }
index 23c4956..a4d6621 100644 (file)
@@ -285,9 +285,9 @@ JSValue *JavaInstance::invokeMethod (ExecState *exec, const MethodList &methodLi
 
 JSValue* JavaInstance::defaultValue(ExecState* exec, PreferredPrimitiveType hint) const
 {
-    if (hint == JSValue::PreferString)
+    if (hint == PreferString)
         return stringValue(exec);
-    if (hint == JSValue::PreferNumber)
+    if (hint == PreferNumber)
         return numberValue(exec);
     JavaClass *aClass = static_cast<JavaClass*>(getClass());
     if (aClass->isStringClass())
index 1178231..0f70a5a 100644 (file)
@@ -355,9 +355,9 @@ JSValue* ObjcInstance::getValueOfUndefinedField(ExecState* exec, const Identifie
 
 JSValue* ObjcInstance::defaultValue(ExecState* exec, PreferredPrimitiveType hint) const
 {
-    if (hint == JSValue::PreferString)
+    if (hint == PreferString)
         return stringValue(exec);
-    if (hint == JSValue::PreferNumber)
+    if (hint == PreferNumber)
         return numberValue(exec);
     if ([_instance.get() isKindOfClass:[NSString class]])
         return stringValue(exec);
index 5633581..22acca4 100644 (file)
@@ -215,9 +215,9 @@ JSValue* QtInstance::invokeMethod(ExecState*, const MethodList&, const ArgList&)
 
 JSValue* QtInstance::defaultValue(ExecState* exec, PreferredPrimitiveType hint) const
 {
-    if (hint == JSValue::PreferString)
+    if (hint == PreferString)
         return stringValue(exec);
-    if (hint == JSValue::PreferNumber)
+    if (hint == PreferNumber)
         return numberValue(exec);
     return valueOf(exec);
 }
index c258182..6712e42 100644 (file)
@@ -120,8 +120,7 @@ public:
     
     virtual void getPropertyNames(ExecState*, PropertyNameArray&) { }
 
-    typedef JSValue::PreferredPrimitiveType PreferredPrimitiveType;
-    virtual JSValue* defaultValue(ExecState*, JSValue::PreferredPrimitiveType) const = 0;
+    virtual JSValue* defaultValue(ExecState*, PreferredPrimitiveType) const = 0;
     
     virtual JSValue* valueOf(ExecState* exec) const { return jsString(exec, getClass()->name()); }