JavaScriptCore:
authordarin@apple.com <darin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 24 Jun 2008 05:23:17 +0000 (05:23 +0000)
committerdarin@apple.com <darin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 24 Jun 2008 05:23:17 +0000 (05:23 +0000)
2008-06-23  Darin Adler  <darin@apple.com>

        Reviewed by Geoff.

        - work toward https://bugs.webkit.org/show_bug.cgi?id=19721

        More preparation toward making functions work on primitive types without
        creating wrapper objects. No speedup this time, but prepares for a future
        speedup without slowing things down.

        SunSpider reports no change.

        - Eliminated the implementsCall, callAsFunction and construct virtual
          functions from JSObject. Instead, the CallData and ConstructData for
          a native function includes a function pointer that the caller can use
          directly. Changed all call sites to use CallData and ConstructData.

        - Changed the "this" argument to native functions to be a JSValue rather
          than a JSObject. This prepares us for passing primitives into these
          functions. The conversion to an object now must be done inside the
          function. Critically, if it's a function that can be called on a DOM
          window object, then we have to be sure to call toThisObject on the
          argument before we use it for anything even if it's already an object.

        - Eliminated the practice of using constructor objects in the global
          object to make objects of the various basic types. Since these
          constructors can't be replaced by script, there's no reason to involve
          a constructor object at all. Added functions to do the construction
          directly.

        - Made some more class members private and protected, including virtual
          function overrides. This can catch code using unnecessarily slow virtual
          function code paths when the type of an object is known statically. If we
          later find a new reason use the members outside the class it's easy to
          make them public again.

        - Moved the declarations of the native implementations for functions out
          of header files. These can have internal linkage and be declared inside
          the source file.

        - Changed PrototypeFunction to take function pointers with the right
          arguments to be put directly into CallData. This eliminates the
          need to have a separate PrototypeReflexiveFunction, and reveals that the
          real purpose of that class included something else specific to eval --
          storage of a cached global object. So renamed PrototypeReflexiveFunction
          to GlobalEvalFunction.

        * API/JSCallbackConstructor.cpp:
        (KJS::constructJSCallback):
        (KJS::JSCallbackConstructor::getConstructData):
        * API/JSCallbackConstructor.h:
        * API/JSCallbackFunction.cpp:
        (KJS::JSCallbackFunction::implementsHasInstance):
        (KJS::JSCallbackFunction::call):
        (KJS::JSCallbackFunction::getCallData):
        * API/JSCallbackFunction.h:
        (KJS::JSCallbackFunction::classInfo):
        * API/JSCallbackObject.h:
        (KJS::JSCallbackObject::classRef):
        (KJS::JSCallbackObject::classInfo):
        * API/JSCallbackObjectFunctions.h:
        (KJS::::getConstructData):
        (KJS::::construct):
        (KJS::::getCallData):
        (KJS::::call):
        * API/JSObjectRef.cpp:
        (JSObjectMakeFunction):
        (JSObjectIsFunction):
        (JSObjectCallAsFunction):
        (JSObjectCallAsConstructor):
        * JavaScriptCore.exp:
        * VM/Machine.cpp:
        (KJS::jsTypeStringForValue):
        (KJS::Machine::privateExecute):
        * kjs/ArrayPrototype.cpp:
        (KJS::arrayProtoFuncToString):
        (KJS::arrayProtoFuncToLocaleString):
        (KJS::arrayProtoFuncJoin):
        (KJS::arrayProtoFuncConcat):
        (KJS::arrayProtoFuncPop):
        (KJS::arrayProtoFuncPush):
        (KJS::arrayProtoFuncReverse):
        (KJS::arrayProtoFuncShift):
        (KJS::arrayProtoFuncSlice):
        (KJS::arrayProtoFuncSort):
        (KJS::arrayProtoFuncSplice):
        (KJS::arrayProtoFuncUnShift):
        (KJS::arrayProtoFuncFilter):
        (KJS::arrayProtoFuncMap):
        (KJS::arrayProtoFuncEvery):
        (KJS::arrayProtoFuncForEach):
        (KJS::arrayProtoFuncSome):
        (KJS::arrayProtoFuncIndexOf):
        (KJS::arrayProtoFuncLastIndexOf):
        (KJS::ArrayConstructor::ArrayConstructor):
        (KJS::constructArrayWithSizeQuirk):
        (KJS::constructWithArrayConstructor):
        (KJS::ArrayConstructor::getConstructData):
        (KJS::callArrayConstructor):
        (KJS::ArrayConstructor::getCallData):
        * kjs/ArrayPrototype.h:
        * kjs/BooleanObject.cpp:
        (KJS::booleanProtoFuncToString):
        (KJS::booleanProtoFuncValueOf):
        (KJS::constructBoolean):
        (KJS::constructWithBooleanConstructor):
        (KJS::BooleanConstructor::getConstructData):
        (KJS::callBooleanConstructor):
        (KJS::BooleanConstructor::getCallData):
        (KJS::constructBooleanFromImmediateBoolean):
        * kjs/BooleanObject.h:
        * kjs/CallData.h:
        (KJS::):
        * kjs/ConstructData.h:
        (KJS::):
        * kjs/FunctionPrototype.cpp:
        (KJS::callFunctionPrototype):
        (KJS::FunctionPrototype::getCallData):
        (KJS::functionProtoFuncToString):
        (KJS::functionProtoFuncApply):
        (KJS::functionProtoFuncCall):
        (KJS::constructWithFunctionConstructor):
        (KJS::FunctionConstructor::getConstructData):
        (KJS::callFunctionConstructor):
        (KJS::FunctionConstructor::getCallData):
        (KJS::constructFunction):
        * kjs/FunctionPrototype.h:
        * kjs/JSArray.cpp:
        (KJS::AVLTreeAbstractorForArrayCompare::compare_key_key):
        (KJS::JSArray::sort):
        (KJS::constructEmptyArray):
        (KJS::constructArray):
        * kjs/JSArray.h:
        (KJS::JSArray::classInfo):
        * kjs/JSFunction.cpp:
        (KJS::JSFunction::call):
        (KJS::globalFuncEval):
        (KJS::globalFuncParseInt):
        (KJS::globalFuncParseFloat):
        (KJS::globalFuncIsNaN):
        (KJS::globalFuncIsFinite):
        (KJS::globalFuncDecodeURI):
        (KJS::globalFuncDecodeURIComponent):
        (KJS::globalFuncEncodeURI):
        (KJS::globalFuncEncodeURIComponent):
        (KJS::globalFuncEscape):
        (KJS::globalFuncUnescape):
        (KJS::globalFuncKJSPrint):
        (KJS::PrototypeFunction::PrototypeFunction):
        (KJS::PrototypeFunction::getCallData):
        (KJS::GlobalEvalFunction::GlobalEvalFunction):
        (KJS::GlobalEvalFunction::mark):
        * kjs/JSFunction.h:
        (KJS::InternalFunction::classInfo):
        (KJS::InternalFunction::functionName):
        (KJS::JSFunction::classInfo):
        (KJS::GlobalEvalFunction::cachedGlobalObject):
        * kjs/JSGlobalObject.cpp:
        (KJS::JSGlobalObject::reset):
        (KJS::JSGlobalObject::mark):
        * kjs/JSGlobalObject.h:
        (KJS::JSGlobalObject::JSGlobalObject):
        (KJS::JSGlobalObject::evalFunction):
        * kjs/JSImmediate.cpp:
        (KJS::JSImmediate::toObject):
        * kjs/JSNotAnObject.cpp:
        * kjs/JSNotAnObject.h:
        * kjs/JSObject.cpp:
        (KJS::JSObject::put):
        (KJS::callDefaultValueFunction):
        (KJS::JSObject::defaultValue):
        (KJS::JSObject::lookupGetter):
        (KJS::JSObject::lookupSetter):
        (KJS::JSObject::hasInstance):
        (KJS::JSObject::fillGetterPropertySlot):
        (KJS::Error::create):
        (KJS::constructEmptyObject):
        * kjs/JSObject.h:
        (KJS::GetterSetter::GetterSetter):
        (KJS::GetterSetter::getter):
        (KJS::GetterSetter::setGetter):
        (KJS::GetterSetter::setter):
        (KJS::GetterSetter::setSetter):
        * kjs/JSValue.cpp:
        (KJS::JSCell::deleteProperty):
        (KJS::call):
        (KJS::construct):
        * kjs/JSValue.h:
        * kjs/MathObject.cpp:
        (KJS::mathProtoFuncAbs):
        (KJS::mathProtoFuncACos):
        (KJS::mathProtoFuncASin):
        (KJS::mathProtoFuncATan):
        (KJS::mathProtoFuncATan2):
        (KJS::mathProtoFuncCeil):
        (KJS::mathProtoFuncCos):
        (KJS::mathProtoFuncExp):
        (KJS::mathProtoFuncFloor):
        (KJS::mathProtoFuncLog):
        (KJS::mathProtoFuncMax):
        (KJS::mathProtoFuncMin):
        (KJS::mathProtoFuncPow):
        (KJS::mathProtoFuncRandom):
        (KJS::mathProtoFuncRound):
        (KJS::mathProtoFuncSin):
        (KJS::mathProtoFuncSqrt):
        (KJS::mathProtoFuncTan):
        * kjs/MathObject.h:
        * kjs/NumberObject.cpp:
        (KJS::numberProtoFuncToString):
        (KJS::numberProtoFuncToLocaleString):
        (KJS::numberProtoFuncValueOf):
        (KJS::numberProtoFuncToFixed):
        (KJS::numberProtoFuncToExponential):
        (KJS::numberProtoFuncToPrecision):
        (KJS::NumberConstructor::NumberConstructor):
        (KJS::constructWithNumberConstructor):
        (KJS::NumberConstructor::getConstructData):
        (KJS::callNumberConstructor):
        (KJS::NumberConstructor::getCallData):
        (KJS::constructNumber):
        (KJS::constructNumberFromImmediateNumber):
        * kjs/NumberObject.h:
        (KJS::NumberObject::classInfo):
        (KJS::NumberConstructor::classInfo):
        * kjs/PropertySlot.cpp:
        (KJS::PropertySlot::functionGetter):
        * kjs/RegExpObject.cpp:
        (KJS::regExpProtoFuncTest):
        (KJS::regExpProtoFuncExec):
        (KJS::regExpProtoFuncCompile):
        (KJS::regExpProtoFuncToString):
        (KJS::callRegExpObject):
        (KJS::RegExpObject::getCallData):
        (KJS::constructRegExp):
        (KJS::constructWithRegExpConstructor):
        (KJS::RegExpConstructor::getConstructData):
        (KJS::callRegExpConstructor):
        (KJS::RegExpConstructor::getCallData):
        * kjs/RegExpObject.h:
        (KJS::RegExpConstructor::classInfo):
        * kjs/Shell.cpp:
        (GlobalObject::GlobalObject):
        (functionPrint):
        (functionDebug):
        (functionGC):
        (functionVersion):
        (functionRun):
        (functionLoad):
        (functionReadline):
        (functionQuit):
        * kjs/date_object.cpp:
        (KJS::gmtoffset):
        (KJS::formatLocaleDate):
        (KJS::fillStructuresUsingDateArgs):
        (KJS::DateInstance::getTime):
        (KJS::DateInstance::getUTCTime):
        (KJS::DateConstructor::DateConstructor):
        (KJS::constructDate):
        (KJS::DateConstructor::getConstructData):
        (KJS::callDate):
        (KJS::DateConstructor::getCallData):
        (KJS::dateParse):
        (KJS::dateNow):
        (KJS::dateUTC):
        (KJS::dateProtoFuncToString):
        (KJS::dateProtoFuncToUTCString):
        (KJS::dateProtoFuncToDateString):
        (KJS::dateProtoFuncToTimeString):
        (KJS::dateProtoFuncToLocaleString):
        (KJS::dateProtoFuncToLocaleDateString):
        (KJS::dateProtoFuncToLocaleTimeString):
        (KJS::dateProtoFuncValueOf):
        (KJS::dateProtoFuncGetTime):
        (KJS::dateProtoFuncGetFullYear):
        (KJS::dateProtoFuncGetUTCFullYear):
        (KJS::dateProtoFuncToGMTString):
        (KJS::dateProtoFuncGetMonth):
        (KJS::dateProtoFuncGetUTCMonth):
        (KJS::dateProtoFuncGetDate):
        (KJS::dateProtoFuncGetUTCDate):
        (KJS::dateProtoFuncGetDay):
        (KJS::dateProtoFuncGetUTCDay):
        (KJS::dateProtoFuncGetHours):
        (KJS::dateProtoFuncGetUTCHours):
        (KJS::dateProtoFuncGetMinutes):
        (KJS::dateProtoFuncGetUTCMinutes):
        (KJS::dateProtoFuncGetSeconds):
        (KJS::dateProtoFuncGetUTCSeconds):
        (KJS::dateProtoFuncGetMilliSeconds):
        (KJS::dateProtoFuncGetUTCMilliseconds):
        (KJS::dateProtoFuncGetTimezoneOffset):
        (KJS::dateProtoFuncSetTime):
        (KJS::setNewValueFromTimeArgs):
        (KJS::setNewValueFromDateArgs):
        (KJS::dateProtoFuncSetMilliSeconds):
        (KJS::dateProtoFuncSetUTCMilliseconds):
        (KJS::dateProtoFuncSetSeconds):
        (KJS::dateProtoFuncSetUTCSeconds):
        (KJS::dateProtoFuncSetMinutes):
        (KJS::dateProtoFuncSetUTCMinutes):
        (KJS::dateProtoFuncSetHours):
        (KJS::dateProtoFuncSetUTCHours):
        (KJS::dateProtoFuncSetDate):
        (KJS::dateProtoFuncSetUTCDate):
        (KJS::dateProtoFuncSetMonth):
        (KJS::dateProtoFuncSetUTCMonth):
        (KJS::dateProtoFuncSetFullYear):
        (KJS::dateProtoFuncSetUTCFullYear):
        (KJS::dateProtoFuncSetYear):
        (KJS::dateProtoFuncGetYear):
        * kjs/date_object.h:
        (KJS::DateInstance::internalNumber):
        (KJS::DateInstance::classInfo):
        * kjs/error_object.cpp:
        (KJS::errorProtoFuncToString):
        (KJS::constructError):
        (KJS::constructWithErrorConstructor):
        (KJS::ErrorConstructor::getConstructData):
        (KJS::callErrorConstructor):
        (KJS::ErrorConstructor::getCallData):
        (KJS::NativeErrorConstructor::construct):
        (KJS::constructWithNativeErrorConstructor):
        (KJS::NativeErrorConstructor::getConstructData):
        (KJS::callNativeErrorConstructor):
        (KJS::NativeErrorConstructor::getCallData):
        * kjs/error_object.h:
        (KJS::NativeErrorConstructor::classInfo):
        * kjs/internal.cpp:
        (KJS::JSNumberCell::toObject):
        (KJS::JSNumberCell::toThisObject):
        (KJS::GetterSetter::mark):
        (KJS::GetterSetter::toPrimitive):
        (KJS::GetterSetter::toBoolean):
        (KJS::GetterSetter::toNumber):
        (KJS::GetterSetter::toString):
        (KJS::GetterSetter::toObject):
        (KJS::InternalFunction::InternalFunction):
        (KJS::InternalFunction::implementsHasInstance):
        * kjs/lookup.h:
        (KJS::HashEntry::):
        * kjs/nodes.cpp:
        (KJS::FuncDeclNode::makeFunction):
        (KJS::FuncExprNode::makeFunction):
        * kjs/object_object.cpp:
        (KJS::objectProtoFuncValueOf):
        (KJS::objectProtoFuncHasOwnProperty):
        (KJS::objectProtoFuncIsPrototypeOf):
        (KJS::objectProtoFuncDefineGetter):
        (KJS::objectProtoFuncDefineSetter):
        (KJS::objectProtoFuncLookupGetter):
        (KJS::objectProtoFuncLookupSetter):
        (KJS::objectProtoFuncPropertyIsEnumerable):
        (KJS::objectProtoFuncToLocaleString):
        (KJS::objectProtoFuncToString):
        (KJS::ObjectConstructor::ObjectConstructor):
        (KJS::constructObject):
        (KJS::constructWithObjectConstructor):
        (KJS::ObjectConstructor::getConstructData):
        (KJS::callObjectConstructor):
        (KJS::ObjectConstructor::getCallData):
        * kjs/object_object.h:
        * kjs/string_object.cpp:
        (KJS::replace):
        (KJS::stringProtoFuncToString):
        (KJS::stringProtoFuncValueOf):
        (KJS::stringProtoFuncCharAt):
        (KJS::stringProtoFuncCharCodeAt):
        (KJS::stringProtoFuncConcat):
        (KJS::stringProtoFuncIndexOf):
        (KJS::stringProtoFuncLastIndexOf):
        (KJS::stringProtoFuncMatch):
        (KJS::stringProtoFuncSearch):
        (KJS::stringProtoFuncReplace):
        (KJS::stringProtoFuncSlice):
        (KJS::stringProtoFuncSplit):
        (KJS::stringProtoFuncSubstr):
        (KJS::stringProtoFuncSubstring):
        (KJS::stringProtoFuncToLowerCase):
        (KJS::stringProtoFuncToUpperCase):
        (KJS::stringProtoFuncToLocaleLowerCase):
        (KJS::stringProtoFuncToLocaleUpperCase):
        (KJS::stringProtoFuncLocaleCompare):
        (KJS::stringProtoFuncBig):
        (KJS::stringProtoFuncSmall):
        (KJS::stringProtoFuncBlink):
        (KJS::stringProtoFuncBold):
        (KJS::stringProtoFuncFixed):
        (KJS::stringProtoFuncItalics):
        (KJS::stringProtoFuncStrike):
        (KJS::stringProtoFuncSub):
        (KJS::stringProtoFuncSup):
        (KJS::stringProtoFuncFontcolor):
        (KJS::stringProtoFuncFontsize):
        (KJS::stringProtoFuncAnchor):
        (KJS::stringProtoFuncLink):
        (KJS::stringFromCharCode):
        (KJS::StringConstructor::StringConstructor):
        (KJS::constructWithStringConstructor):
        (KJS::StringConstructor::getConstructData):
        (KJS::callStringConstructor):
        (KJS::StringConstructor::getCallData):
        * kjs/string_object.h:

JavaScriptGlue:

2008-06-23  Darin Adler  <darin@apple.com>

        Reviewed by Geoff.

        * JSValueWrapper.cpp:
        (JSValueWrapper::JSObjectCallFunction): Updated to use getCallData and call instead
        of the old callAsFunction.

WebCore:

2008-06-23  Darin Adler  <darin@apple.com>

        Reviewed by Geoff.

        Update for JavaScript changes.

        - Use CallData and ConstructData instead of the obsolete implementsCall,
          callAsFunction, and construct functions.

        - Updated native function arguments, specifically to allow a JSValue
          rather than a JSObject for the this argument, and to call toThisObject
          as needed when treating it as an object.

        - Made some more class members private and protected, including virtual
          function overrides.

        - Eliminated the use of getCallData in the JavaScript bridging code as
          a way to check if an instance supports invokeDefaultMethod.

        - Eliminated unnecessary polymorphism in the NodeIterator and TreeWalker
          classes. They were using virtual functions simply to share an instance
          of the RefCounted template, which was not helpful.

        * bindings/js/JSAudioConstructor.cpp:
        (WebCore::constructAudio):
        (WebCore::JSAudioConstructor::getConstructData):
        * bindings/js/JSAudioConstructor.h:
        (WebCore::JSAudioConstructor::document):
        (WebCore::JSAudioConstructor::classInfo):
        * bindings/js/JSClipboardCustom.cpp:
        (WebCore::JSClipboard::types):
        * bindings/js/JSCustomSQLStatementCallback.cpp:
        (WebCore::JSCustomSQLStatementCallback::handleEvent):
        * bindings/js/JSCustomSQLStatementErrorCallback.cpp:
        (WebCore::JSCustomSQLStatementErrorCallback::handleEvent):
        * bindings/js/JSCustomSQLTransactionCallback.cpp:
        (WebCore::JSCustomSQLTransactionCallback::handleEvent):
        * bindings/js/JSCustomSQLTransactionErrorCallback.cpp:
        (WebCore::JSCustomSQLTransactionErrorCallback::handleEvent):
        * bindings/js/JSCustomVoidCallback.cpp:
        (WebCore::JSCustomVoidCallback::handleEvent):
        * bindings/js/JSCustomXPathNSResolver.cpp:
        (WebCore::JSCustomXPathNSResolver::lookupNamespaceURI):
        * bindings/js/JSDOMBinding.h:
        (WebCore::DOMObject::DOMObject):
        * bindings/js/JSDOMWindowBase.cpp:
        (WebCore::windowProtoFuncAToB):
        (WebCore::windowProtoFuncBToA):
        (WebCore::windowProtoFuncOpen):
        (WebCore::windowProtoFuncSetTimeout):
        (WebCore::windowProtoFuncClearTimeout):
        (WebCore::windowProtoFuncSetInterval):
        (WebCore::windowProtoFuncAddEventListener):
        (WebCore::windowProtoFuncRemoveEventListener):
        (WebCore::windowProtoFuncShowModalDialog):
        (WebCore::windowProtoFuncNotImplemented):
        (WebCore::toJSDOMWindow):
        * bindings/js/JSDOMWindowBase.h:
        * bindings/js/JSDOMWindowShell.h:
        (WebCore::JSDOMWindowShell::classInfo):
        * bindings/js/JSEventListener.cpp:
        (WebCore::JSAbstractEventListener::handleEvent):
        (WebCore::JSLazyEventListener::parseCode):
        * bindings/js/JSEventTargetBase.cpp:
        (WebCore::retrieveEventTargetAndCorrespondingNode):
        (WebCore::jsEventTargetAddEventListener):
        (WebCore::jsEventTargetRemoveEventListener):
        (WebCore::jsEventTargetDispatchEvent):
        * bindings/js/JSEventTargetBase.h:
        * bindings/js/JSHTMLAppletElementCustom.cpp:
        (WebCore::JSHTMLAppletElement::customGetOwnPropertySlot):
        (WebCore::JSHTMLAppletElement::customPut):
        (WebCore::JSHTMLAppletElement::getCallData):
        * bindings/js/JSHTMLCollectionCustom.cpp:
        (WebCore::callHTMLCollection):
        (WebCore::JSHTMLCollection::getCallData):
        * bindings/js/JSHTMLDocumentCustom.cpp:
        (WebCore::JSHTMLDocument::open):
        * bindings/js/JSHTMLEmbedElementCustom.cpp:
        (WebCore::JSHTMLEmbedElement::customGetOwnPropertySlot):
        (WebCore::JSHTMLEmbedElement::customPut):
        (WebCore::JSHTMLEmbedElement::getCallData):
        * bindings/js/JSHTMLInputElementBase.cpp:
        (WebCore::jsHTMLInputElementBaseFunctionSetSelectionRange):
        * bindings/js/JSHTMLInputElementBase.h:
        * bindings/js/JSHTMLObjectElementCustom.cpp:
        (WebCore::JSHTMLObjectElement::customGetOwnPropertySlot):
        (WebCore::JSHTMLObjectElement::customPut):
        (WebCore::JSHTMLObjectElement::getCallData):
        * bindings/js/JSHTMLOptionElementConstructor.cpp:
        (WebCore::constructHTMLOptionElement):
        (WebCore::JSHTMLOptionElementConstructor::getConstructData):
        * bindings/js/JSHTMLOptionElementConstructor.h:
        (WebCore::JSHTMLOptionElementConstructor::document):
        (WebCore::JSHTMLOptionElementConstructor::classInfo):
        * bindings/js/JSImageConstructor.cpp:
        (WebCore::constructImage):
        (WebCore::JSImageConstructor::getConstructData):
        * bindings/js/JSImageConstructor.h:
        (WebCore::JSImageConstructor::document):
        (WebCore::JSImageConstructor::classInfo):
        * bindings/js/JSInspectedObjectWrapper.h:
        (WebCore::JSInspectedObjectWrapper::classInfo):
        * bindings/js/JSInspectorCallbackWrapper.cpp:
        (WebCore::JSInspectorCallbackWrapper::prepareIncomingValue):
        * bindings/js/JSJavaScriptCallFrameCustom.cpp:
        (WebCore::JSJavaScriptCallFrame::scopeChain):
        * bindings/js/JSNodeFilterCondition.cpp:
        (WebCore::JSNodeFilterCondition::JSNodeFilterCondition):
        (WebCore::JSNodeFilterCondition::mark):
        (WebCore::JSNodeFilterCondition::acceptNode):
        * bindings/js/JSNodeFilterCondition.h:
        (WebCore::JSNodeFilterCondition::create):
        * bindings/js/JSNodeFilterCustom.cpp:
        (WebCore::toNodeFilter):
        * bindings/js/JSNodeListCustom.cpp:
        (WebCore::callNodeList):
        (WebCore::JSNodeList::getCallData):
        (WebCore::JSNodeList::canGetItemsForName):
        (WebCore::JSNodeList::nameGetter):
        * bindings/js/JSPluginElementFunctions.cpp:
        (WebCore::runtimeObjectGetter):
        (WebCore::runtimeObjectPropertyGetter):
        (WebCore::runtimeObjectCustomGetOwnPropertySlot):
        (WebCore::runtimeObjectCustomPut):
        (WebCore::runtimeObjectGetCallData):
        (WebCore::pluginInstance):
        (WebCore::getRuntimeObject):
        (WebCore::callPlugin):
        * bindings/js/JSPluginElementFunctions.h:
        * bindings/js/JSQuarantinedObjectWrapper.cpp:
        (WebCore::JSQuarantinedObjectWrapper::put):
        (WebCore::JSQuarantinedObjectWrapper::construct):
        (WebCore::JSQuarantinedObjectWrapper::getConstructData):
        (WebCore::JSQuarantinedObjectWrapper::hasInstance):
        (WebCore::JSQuarantinedObjectWrapper::call):
        (WebCore::JSQuarantinedObjectWrapper::getCallData):
        * bindings/js/JSQuarantinedObjectWrapper.h:
        (WebCore::JSQuarantinedObjectWrapper::className):
        * bindings/js/JSRGBColor.cpp:
        * bindings/js/JSXMLHttpRequestConstructor.cpp:
        (WebCore::constructXMLHttpRequest):
        (WebCore::JSXMLHttpRequestConstructor::getConstructData):
        * bindings/js/JSXMLHttpRequestConstructor.h:
        (WebCore::JSXMLHttpRequestConstructor::document):
        (WebCore::JSXMLHttpRequestConstructor::classInfo):
        * bindings/js/JSXSLTProcessorConstructor.cpp:
        (WebCore::constructXSLTProcessor):
        (WebCore::JSXSLTProcessorConstructor::getConstructData):
        * bindings/js/JSXSLTProcessorConstructor.h:
        (WebCore::JSXSLTProcessorConstructor::classInfo):
        * bindings/js/ScheduledAction.cpp:
        (WebCore::ScheduledAction::ScheduledAction):
        (WebCore::ScheduledAction::execute):
        * bindings/js/ScheduledAction.h:
        * bindings/objc/WebScriptObject.mm:
        (-[WebScriptObject callWebScriptMethod:withArguments:]):
        * bindings/scripts/CodeGeneratorJS.pm:
        * bridge/NP_jsobject.cpp:
        (_NPN_InvokeDefault):
        (_NPN_Invoke):
        * bridge/c/c_instance.cpp:
        (KJS::Bindings::CInstance::supportsInvokeDefaultMethod):
        * bridge/c/c_instance.h:
        * bridge/jni/jni_jsobject.mm:
        (JavaJSObject::call):
        * bridge/objc/objc_instance.h:
        * bridge/objc/objc_instance.mm:
        (ObjcInstance::supportsInvokeDefaultMethod):
        * bridge/objc/objc_runtime.h:
        (KJS::Bindings::ObjcFallbackObjectImp::propertyName):
        (KJS::Bindings::ObjcFallbackObjectImp::classInfo):
        * bridge/objc/objc_runtime.mm:
        (Bindings::webScriptObjectClass):
        (Bindings::webUndefinedClass):
        (ObjcFallbackObjectImp::ObjcFallbackObjectImp):
        (callObjCFallbackObject):
        (ObjcFallbackObjectImp::getCallData):
        * bridge/qt/qt_instance.h:
        * bridge/runtime.cpp:
        (KJS::Bindings::Instance::createRuntimeObject):
        (KJS::Bindings::Instance::getInstance):
        * bridge/runtime.h:
        (KJS::Bindings::Field::~Field):
        (KJS::Bindings::Method::~Method):
        (KJS::Bindings::Class::~Class):
        (KJS::Bindings::Instance::supportsInvokeDefaultMethod):
        * bridge/runtime_method.cpp:
        (KJS::callRuntimeMethod):
        (KJS::RuntimeMethod::getCallData):
        * bridge/runtime_method.h:
        (KJS::RuntimeMethod::methods):
        * bridge/runtime_object.cpp:
        (RuntimeObjectImp::defaultValue):
        (callRuntimeObject):
        (RuntimeObjectImp::getCallData):
        * bridge/runtime_object.h:
        (KJS::RuntimeObjectImp::getInternalInstance):
        (KJS::RuntimeObjectImp::classInfo):
        * dom/NodeIterator.h:
        * dom/Traversal.cpp:
        * dom/Traversal.h:
        * dom/TreeWalker.h:

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

120 files changed:
JavaScriptCore/API/JSCallbackConstructor.cpp
JavaScriptCore/API/JSCallbackConstructor.h
JavaScriptCore/API/JSCallbackFunction.cpp
JavaScriptCore/API/JSCallbackFunction.h
JavaScriptCore/API/JSCallbackObject.h
JavaScriptCore/API/JSCallbackObjectFunctions.h
JavaScriptCore/API/JSObjectRef.cpp
JavaScriptCore/ChangeLog
JavaScriptCore/JavaScriptCore.exp
JavaScriptCore/VM/Machine.cpp
JavaScriptCore/kjs/ArrayPrototype.cpp
JavaScriptCore/kjs/ArrayPrototype.h
JavaScriptCore/kjs/BooleanObject.cpp
JavaScriptCore/kjs/BooleanObject.h
JavaScriptCore/kjs/CallData.h
JavaScriptCore/kjs/ConstructData.h
JavaScriptCore/kjs/FunctionPrototype.cpp
JavaScriptCore/kjs/FunctionPrototype.h
JavaScriptCore/kjs/JSArray.cpp
JavaScriptCore/kjs/JSArray.h
JavaScriptCore/kjs/JSFunction.cpp
JavaScriptCore/kjs/JSFunction.h
JavaScriptCore/kjs/JSGlobalObject.cpp
JavaScriptCore/kjs/JSGlobalObject.h
JavaScriptCore/kjs/JSImmediate.cpp
JavaScriptCore/kjs/JSNotAnObject.cpp
JavaScriptCore/kjs/JSNotAnObject.h
JavaScriptCore/kjs/JSObject.cpp
JavaScriptCore/kjs/JSObject.h
JavaScriptCore/kjs/JSValue.cpp
JavaScriptCore/kjs/JSValue.h
JavaScriptCore/kjs/MathObject.cpp
JavaScriptCore/kjs/MathObject.h
JavaScriptCore/kjs/NumberObject.cpp
JavaScriptCore/kjs/NumberObject.h
JavaScriptCore/kjs/PropertySlot.cpp
JavaScriptCore/kjs/RegExpObject.cpp
JavaScriptCore/kjs/RegExpObject.h
JavaScriptCore/kjs/Shell.cpp
JavaScriptCore/kjs/date_object.cpp
JavaScriptCore/kjs/date_object.h
JavaScriptCore/kjs/error_object.cpp
JavaScriptCore/kjs/error_object.h
JavaScriptCore/kjs/internal.cpp
JavaScriptCore/kjs/lookup.h
JavaScriptCore/kjs/nodes.cpp
JavaScriptCore/kjs/object_object.cpp
JavaScriptCore/kjs/object_object.h
JavaScriptCore/kjs/string_object.cpp
JavaScriptCore/kjs/string_object.h
JavaScriptGlue/ChangeLog
JavaScriptGlue/JSValueWrapper.cpp
WebCore/ChangeLog
WebCore/bindings/js/JSAudioConstructor.cpp
WebCore/bindings/js/JSAudioConstructor.h
WebCore/bindings/js/JSCanvasRenderingContext2DCustom.cpp
WebCore/bindings/js/JSClipboardCustom.cpp
WebCore/bindings/js/JSCustomSQLStatementCallback.cpp
WebCore/bindings/js/JSCustomSQLStatementErrorCallback.cpp
WebCore/bindings/js/JSCustomSQLTransactionCallback.cpp
WebCore/bindings/js/JSCustomSQLTransactionErrorCallback.cpp
WebCore/bindings/js/JSCustomVoidCallback.cpp
WebCore/bindings/js/JSCustomXPathNSResolver.cpp
WebCore/bindings/js/JSDOMBinding.h
WebCore/bindings/js/JSDOMWindowBase.cpp
WebCore/bindings/js/JSDOMWindowBase.h
WebCore/bindings/js/JSDOMWindowShell.h
WebCore/bindings/js/JSEventListener.cpp
WebCore/bindings/js/JSEventTargetBase.cpp
WebCore/bindings/js/JSEventTargetBase.h
WebCore/bindings/js/JSHTMLAppletElementCustom.cpp
WebCore/bindings/js/JSHTMLCollectionCustom.cpp
WebCore/bindings/js/JSHTMLDocumentCustom.cpp
WebCore/bindings/js/JSHTMLEmbedElementCustom.cpp
WebCore/bindings/js/JSHTMLInputElementBase.cpp
WebCore/bindings/js/JSHTMLInputElementBase.h
WebCore/bindings/js/JSHTMLObjectElementCustom.cpp
WebCore/bindings/js/JSHTMLOptionElementConstructor.cpp
WebCore/bindings/js/JSHTMLOptionElementConstructor.h
WebCore/bindings/js/JSImageConstructor.cpp
WebCore/bindings/js/JSImageConstructor.h
WebCore/bindings/js/JSInspectedObjectWrapper.h
WebCore/bindings/js/JSInspectorCallbackWrapper.cpp
WebCore/bindings/js/JSJavaScriptCallFrameCustom.cpp
WebCore/bindings/js/JSNodeFilterCondition.cpp
WebCore/bindings/js/JSNodeFilterCondition.h
WebCore/bindings/js/JSNodeFilterCustom.cpp
WebCore/bindings/js/JSNodeListCustom.cpp
WebCore/bindings/js/JSPluginElementFunctions.cpp
WebCore/bindings/js/JSPluginElementFunctions.h
WebCore/bindings/js/JSQuarantinedObjectWrapper.cpp
WebCore/bindings/js/JSQuarantinedObjectWrapper.h
WebCore/bindings/js/JSRGBColor.cpp
WebCore/bindings/js/JSXMLHttpRequestConstructor.cpp
WebCore/bindings/js/JSXMLHttpRequestConstructor.h
WebCore/bindings/js/JSXSLTProcessorConstructor.cpp
WebCore/bindings/js/JSXSLTProcessorConstructor.h
WebCore/bindings/js/ScheduledAction.cpp
WebCore/bindings/js/ScheduledAction.h
WebCore/bindings/objc/WebScriptObject.mm
WebCore/bindings/scripts/CodeGeneratorJS.pm
WebCore/bridge/NP_jsobject.cpp
WebCore/bridge/c/c_instance.cpp
WebCore/bridge/c/c_instance.h
WebCore/bridge/jni/jni_jsobject.mm
WebCore/bridge/objc/objc_instance.h
WebCore/bridge/objc/objc_instance.mm
WebCore/bridge/objc/objc_runtime.h
WebCore/bridge/objc/objc_runtime.mm
WebCore/bridge/qt/qt_instance.h
WebCore/bridge/runtime.cpp
WebCore/bridge/runtime.h
WebCore/bridge/runtime_method.cpp
WebCore/bridge/runtime_method.h
WebCore/bridge/runtime_object.cpp
WebCore/bridge/runtime_object.h
WebCore/dom/NodeIterator.h
WebCore/dom/Traversal.cpp
WebCore/dom/Traversal.h
WebCore/dom/TreeWalker.h

index 65e9d471f54a11835367ac146479fbc2e8ef3472..173ec839bb7dc7fd01820ce658bc25e22e1dfcd4 100644 (file)
@@ -1,6 +1,6 @@
 // -*- mode: c++; c-basic-offset: 4 -*-
 /*
- * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -56,27 +56,29 @@ bool JSCallbackConstructor::implementsHasInstance() const
     return true;
 }
 
-ConstructType JSCallbackConstructor::getConstructData(ConstructData&)
-{
-    return ConstructTypeNative;
-}
-
-JSObject* JSCallbackConstructor::construct(ExecState* exec, const ArgList &args)
+static JSObject* constructJSCallback(ExecState* exec, JSObject* constructor, const ArgList& args)
 {
     JSContextRef ctx = toRef(exec);
-    JSObjectRef thisRef = toRef(this);
+    JSObjectRef constructorRef = toRef(constructor);
 
-    if (m_callback) {
+    JSObjectCallAsConstructorCallback callback = static_cast<JSCallbackConstructor*>(constructor)->callback();
+    if (callback) {
         int argumentCount = static_cast<int>(args.size());
         Vector<JSValueRef, 16> arguments(argumentCount);
         for (int i = 0; i < argumentCount; i++)
             arguments[i] = toRef(args[i]);
             
         JSLock::DropAllLocks dropAllLocks;
-        return toJS(m_callback(ctx, thisRef, argumentCount, arguments.data(), toRef(exec->exceptionSlot())));
+        return toJS(callback(ctx, constructorRef, argumentCount, arguments.data(), toRef(exec->exceptionSlot())));
     }
     
-    return toJS(JSObjectMake(ctx, m_class, 0));
+    return toJS(JSObjectMake(ctx, static_cast<JSCallbackConstructor*>(constructor)->classRef(), 0));
+}
+
+ConstructType JSCallbackConstructor::getConstructData(ConstructData& constructData)
+{
+    constructData.native.function = constructJSCallback;
+    return ConstructTypeNative;
 }
 
 } // namespace KJS
index e1012b4df03337d0ea8691fa8ee181c48b6da2ba..ede502555477633830645e42b008af002e014c44 100644 (file)
@@ -1,6 +1,6 @@
 // -*- mode: c++; c-basic-offset: 4 -*-
 /*
- * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
+ * Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -34,20 +34,16 @@ namespace KJS {
 
 class JSCallbackConstructor : public JSObject {
 public:
-    JSCallbackConstructor(ExecState* exec, JSClassRef jsClass, JSObjectCallAsConstructorCallback callback);
+    JSCallbackConstructor(ExecState*, JSClassRef, JSObjectCallAsConstructorCallback);
     virtual ~JSCallbackConstructor();
-    
-    virtual bool implementsHasInstance() const;
-    
-    virtual ConstructType getConstructData(ConstructData&);
-    virtual JSObject* construct(ExecState*, const ArgList& args);
-    
-    virtual const ClassInfo *classInfo() const { return &info; }
+    JSClassRef classRef() const { return m_class; }
+    JSObjectCallAsConstructorCallback callback() const { return m_callback; }
     static const ClassInfo info;
     
 private:
-    JSCallbackConstructor(); // prevent default construction
-    JSCallbackConstructor(const JSCallbackConstructor&);
+    virtual bool implementsHasInstance() const;    
+    virtual ConstructType getConstructData(ConstructData&);
+    virtual const ClassInfo* classInfo() const { return &info; }
 
     JSClassRef m_class;
     JSObjectCallAsConstructorCallback m_callback;
index 917fffb1735b59dfc61b41871f3554c4e1cb36eb..ced7d9d11e2db049d17c2c1ce8882fd431600e87 100644 (file)
@@ -1,6 +1,6 @@
 // -*- mode: c++; c-basic-offset: 4 -*-
 /*
- * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
+ * Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -46,15 +46,16 @@ JSCallbackFunction::JSCallbackFunction(ExecState* exec, JSObjectCallAsFunctionCa
 
 // InternalFunction mish-mashes constructor and function behavior -- we should 
 // refactor the code so this override isn't necessary
-bool JSCallbackFunction::implementsHasInstance() const { 
+bool JSCallbackFunction::implementsHasInstance() const
+{ 
     return false; 
 }
 
-JSValue* JSCallbackFunction::callAsFunction(ExecState* exec, JSObject* thisObj, const ArgList &args)
+JSValue* JSCallbackFunction::call(ExecState* exec, JSObject* functionObject, JSValue* thisValue, const ArgList& args)
 {
     JSContextRef execRef = toRef(exec);
-    JSObjectRef thisRef = toRef(this);
-    JSObjectRef thisObjRef = toRef(thisObj);
+    JSObjectRef functionRef = toRef(functionObject);
+    JSObjectRef thisObjRef = toRef(thisValue->toThisObject(exec));
 
     int argumentCount = static_cast<int>(args.size());
     Vector<JSValueRef, 16> arguments(argumentCount);
@@ -62,7 +63,13 @@ JSValue* JSCallbackFunction::callAsFunction(ExecState* exec, JSObject* thisObj,
         arguments[i] = toRef(args[i]);
 
     JSLock::DropAllLocks dropAllLocks;
-    return toJS(m_callback(execRef, thisRef, thisObjRef, argumentCount, arguments.data(), toRef(exec->exceptionSlot())));
+    return toJS(static_cast<JSCallbackFunction*>(functionObject)->m_callback(execRef, functionRef, thisObjRef, argumentCount, arguments.data(), toRef(exec->exceptionSlot())));
+}
+
+CallType JSCallbackFunction::getCallData(CallData& callData)
+{
+    callData.native.function = call;
+    return CallTypeNative;
 }
 
 } // namespace KJS
index 53f94055c9cae6a33675f30cb97a051b8aabff2c..2a6e82db6a8ce78bedf7237c9d25e9e72ba36a44 100644 (file)
@@ -1,6 +1,6 @@
 // -*- mode: c++; c-basic-offset: 4 -*-
 /*
- * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
+ * Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #ifndef JSCallbackFunction_h
 #define JSCallbackFunction_h
 
-#include "JSObjectRef.h"
 #include "JSFunction.h"
-#include "JSObject.h"
+#include "JSObjectRef.h"
 
 namespace KJS {
 
-class JSCallbackFunction : public InternalFunction
-{
+class JSCallbackFunction : public InternalFunction {
 public:
-    JSCallbackFunction(ExecState* exec, JSObjectCallAsFunctionCallback callback, const Identifier& name);
-
-    virtual bool implementsHasInstance() const;
-    virtual JSValue* callAsFunction(ExecState*, JSObject* thisObj, const ArgList &args);
+    JSCallbackFunction(ExecState*, JSObjectCallAsFunctionCallback, const Identifier& name);
 
-    virtual const ClassInfo *classInfo() const { return &info; }
     static const ClassInfo info;
     
 private:
-    JSCallbackFunction(); // prevent default construction
-    JSCallbackFunction(const JSCallbackFunction&);
-    
+    virtual bool implementsHasInstance() const;
+    virtual CallType getCallData(CallData&);
+    virtual const ClassInfo* classInfo() const { return &info; }
+
+    static JSValue* call(ExecState*, JSObject*, JSValue*, const ArgList&);
+
     JSObjectCallAsFunctionCallback m_callback;
 };
 
index c640fe0c8f7a03f42bbd6afed9bccc84778dc7b6..00c0f07c1ac129bf1d81aa18de9c574e1fb53e09 100644 (file)
@@ -1,6 +1,6 @@
 // -*- mode: c++; c-basic-offset: 4 -*-
 /*
- * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
+ * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
  * Copyright (C) 2007 Eric Seidel <eric@webkit.org>
  *
  * Redistribution and use in source and binary forms, with or without
 namespace KJS {
 
 template <class Base>
-class JSCallbackObject : public Base
-{
+class JSCallbackObject : public Base {
 public:
     JSCallbackObject(ExecState*, JSClassRef, JSValue* prototype, void* data);
     JSCallbackObject(JSClassRef);
     virtual ~JSCallbackObject();
 
+    void setPrivate(void* data);
+    void* getPrivate();
+
+    static const ClassInfo info;
+
+    JSClassRef classRef() const { return m_class; }
+    bool inherits(JSClassRef) const;
+
+private:
     virtual UString className() const;
 
     virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
@@ -53,31 +61,23 @@ public:
     virtual bool deleteProperty(ExecState*, const Identifier&);
     virtual bool deleteProperty(ExecState*, unsigned);
 
-    virtual ConstructType getConstructData(ConstructData&);
-    virtual JSObject* construct(ExecState*, const ArgList& args);
-
     virtual bool implementsHasInstance() const;
     virtual bool hasInstance(ExecState *exec, JSValue *value);
 
-    virtual CallType getCallData(CallData&);
-    virtual JSValue* callAsFunction(ExecState*, JSObject* thisObj, const ArgList &args);
-
     virtual void getPropertyNames(ExecState*, PropertyNameArray&);
 
     virtual double toNumber(ExecState*) const;
     virtual UString toString(ExecState*) const;
 
-    void setPrivate(void* data);
-    void* getPrivate();
-    
-    virtual const ClassInfo *classInfo() const { return &info; }
-    static const ClassInfo info;
+    virtual ConstructType getConstructData(ConstructData&);
+    virtual CallType getCallData(CallData&);
+    virtual const ClassInfo* classInfo() const { return &info; }
 
-    bool inherits(JSClassRef) const;
-    
-private:
     void init(ExecState*);
-    
+    static JSValue* call(ExecState*, JSObject* functionObject, JSValue* thisValue, const ArgList&);
+    static JSObject* construct(ExecState*, JSObject* constructor, const ArgList&);
+   
     static JSValue* cachedValueGetter(ExecState*, const Identifier&, const PropertySlot&);
     static JSValue* staticValueGetter(ExecState*, const Identifier&, const PropertySlot&);
     static JSValue* staticFunctionGetter(ExecState*, const Identifier&, const PropertySlot&);
index 61eab2e1a3ac54c5763747392e16f57a8a783251..5cf7faee8b7801964396757f6522af914c54b7ed 100644 (file)
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
  */
 
-#include <wtf/Platform.h>
 #include "APICast.h"
 #include "JSCallbackFunction.h"
 #include "JSClassRef.h"
-#include "JSObjectRef.h"
 #include "JSGlobalObject.h"
+#include "JSObjectRef.h"
+#include "JSString.h"
 #include "JSStringRef.h"
 #include "PropertyNameArray.h"
-#include "JSString.h"
 #include <wtf/Vector.h>
 
 namespace KJS {
@@ -47,7 +46,8 @@ JSCallbackObject<Base>::JSCallbackObject(ExecState* exec, JSClassRef jsClass, JS
     init(exec);
 }
 
-// Global object constructor. FIXME: Move this into a JSGlobalCallbackObject subclass.
+// Global object constructor.
+// FIXME: Move this into a separate JSGlobalCallbackObject class derived from this one.
 template <class Base>
 JSCallbackObject<Base>::JSCallbackObject(JSClassRef jsClass)
     : m_privateData(0)
@@ -237,33 +237,35 @@ bool JSCallbackObject<Base>::deleteProperty(ExecState* exec, unsigned propertyNa
 }
 
 template <class Base>
-ConstructType JSCallbackObject<Base>::getConstructData(ConstructData&)
+ConstructType JSCallbackObject<Base>::getConstructData(ConstructData& constructData)
 {
-    for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass)
-        if (jsClass->callAsConstructor)
+    for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass) {
+        if (jsClass->callAsConstructor) {
+            constructData.native.function = construct;
             return ConstructTypeNative;
-    
+        }
+    }
     return ConstructTypeNone;
 }
 
 template <class Base>
-JSObject* JSCallbackObject<Base>::construct(ExecState* exec, const ArgList& args)
+JSObject* JSCallbackObject<Base>::construct(ExecState* exec, JSObject* constructor, const ArgList& args)
 {
     JSContextRef execRef = toRef(exec);
-    JSObjectRef thisRef = toRef(this);
+    JSObjectRef constructorRef = toRef(constructor);
     
-    for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass) {
+    for (JSClassRef jsClass = static_cast<JSCallbackObject<Base>*>(constructor)->classRef(); jsClass; jsClass = jsClass->parentClass) {
         if (JSObjectCallAsConstructorCallback callAsConstructor = jsClass->callAsConstructor) {
             int argumentCount = static_cast<int>(args.size());
             Vector<JSValueRef, 16> arguments(argumentCount);
             for (int i = 0; i < argumentCount; i++)
                 arguments[i] = toRef(args[i]);
             JSLock::DropAllLocks dropAllLocks;
-            return toJS(callAsConstructor(execRef, thisRef, argumentCount, arguments.data(), toRef(exec->exceptionSlot())));
+            return toJS(callAsConstructor(execRef, constructorRef, argumentCount, arguments.data(), toRef(exec->exceptionSlot())));
         }
     }
     
-    ASSERT(0); // getConstructData should prevent us from reaching here
+    ASSERT_NOT_REACHED(); // getConstructData should prevent us from reaching here
     return 0;
 }
 
@@ -294,30 +296,32 @@ bool JSCallbackObject<Base>::hasInstance(ExecState *exec, JSValue *value)
 }
 
 template <class Base>
-CallType JSCallbackObject<Base>::getCallData(CallData&)
+CallType JSCallbackObject<Base>::getCallData(CallData& callData)
 {
-    for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass)
-        if (jsClass->callAsFunction)
+    for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass) {
+        if (jsClass->callAsFunction) {
+            callData.native.function = call;
             return CallTypeNative;
-    
+        }
+    }
     return CallTypeNone;
 }
 
 template <class Base>
-JSValue* JSCallbackObject<Base>::callAsFunction(ExecState* exec, JSObject* thisObj, const ArgList &args)
+JSValue* JSCallbackObject<Base>::call(ExecState* exec, JSObject* functionObject, JSValue* thisValue, const ArgList& args)
 {
     JSContextRef execRef = toRef(exec);
-    JSObjectRef thisRef = toRef(this);
-    JSObjectRef thisObjRef = toRef(thisObj);
+    JSObjectRef functionRef = toRef(functionObject);
+    JSObjectRef thisObjRef = toRef(thisValue->toThisObject(exec));
     
-    for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass) {
+    for (JSClassRef jsClass = static_cast<JSCallbackObject<Base>*>(functionObject)->m_class; jsClass; jsClass = jsClass->parentClass) {
         if (JSObjectCallAsFunctionCallback callAsFunction = jsClass->callAsFunction) {
             int argumentCount = static_cast<int>(args.size());
             Vector<JSValueRef, 16> arguments(argumentCount);
             for (int i = 0; i < argumentCount; i++)
                 arguments[i] = toRef(args[i]);
             JSLock::DropAllLocks dropAllLocks;
-            return toJS(callAsFunction(execRef, thisRef, thisObjRef, argumentCount, arguments.data(), toRef(exec->exceptionSlot())));
+            return toJS(callAsFunction(execRef, functionRef, thisObjRef, argumentCount, arguments.data(), toRef(exec->exceptionSlot())));
         }
     }
     
index 6e7cb5bbde4745b2d5af4d0d233ded5839ce0ab9..bc97a1b38b93046e9d7bf9313ad2f6bd43e9c5de 100644 (file)
@@ -121,7 +121,7 @@ JSObjectRef JSObjectMakeFunction(JSContextRef ctx, JSStringRef name, unsigned pa
         args.append(jsString(exec, UString(toJS(parameterNames[i]))));
     args.append(jsString(exec, UString(bodyRep)));
 
-    JSObject* result = exec->dynamicGlobalObject()->functionConstructor()->construct(exec, args, nameID, UString(sourceURLRep), startingLineNumber);
+    JSObject* result = constructFunction(exec, args, nameID, UString(sourceURLRep), startingLineNumber);
     if (exec->hadException()) {
         if (exception)
             *exception = toRef(exec->exception());
@@ -267,8 +267,8 @@ bool JSObjectSetPrivate(JSObjectRef object, void* data)
 
 bool JSObjectIsFunction(JSContextRef, JSObjectRef object)
 {
-    JSObject* jsObject = toJS(object);
-    return jsObject->implementsCall();
+    CallData callData;
+    return toJS(object)->getCallData(callData) != CallTypeNone;
 }
 
 JSValueRef JSObjectCallAsFunction(JSContextRef ctx, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
@@ -285,7 +285,12 @@ JSValueRef JSObjectCallAsFunction(JSContextRef ctx, JSObjectRef object, JSObject
     for (size_t i = 0; i < argumentCount; i++)
         argList.append(toJS(arguments[i]));
 
-    JSValueRef result = toRef(jsObject->callAsFunction(exec, jsThisObject, argList)); // returns NULL if object->implementsCall() is false
+    CallData callData;
+    CallType callType = jsObject->getCallData(callData);
+    if (callType == CallTypeNone)
+        return 0;
+
+    JSValueRef result = toRef(call(exec, jsObject, callType, callData, jsThisObject, argList));
     if (exec->hadException()) {
         if (exception)
             *exception = toRef(exec->exception());
@@ -307,12 +312,16 @@ JSObjectRef JSObjectCallAsConstructor(JSContextRef ctx, JSObjectRef object, size
     JSLock lock;
     ExecState* exec = toJS(ctx);
     JSObject* jsObject = toJS(object);
-    
+
+    ConstructData constructData;
+    ConstructType constructType = jsObject->getConstructData(constructData);
+    if (constructType == ConstructTypeNone)
+        return 0;
+
     ArgList argList;
     for (size_t i = 0; i < argumentCount; i++)
         argList.append(toJS(arguments[i]));
-    
-    JSObjectRef result = toRef(jsObject->construct(exec, argList)); // returns NULL if object->implementsCall() is false
+    JSObjectRef result = toRef(construct(exec, jsObject, constructType, constructData, argList));
     if (exec->hadException()) {
         if (exception)
             *exception = toRef(exec->exception());
index 963f4f852d27334290c3fc2cd819f196bdc3e395..6a9943747b8253a07122123819730e81101d39d9 100644 (file)
@@ -1,3 +1,407 @@
+2008-06-23  Darin Adler  <darin@apple.com>
+
+        Reviewed by Geoff.
+
+        - work toward https://bugs.webkit.org/show_bug.cgi?id=19721
+
+        More preparation toward making functions work on primitive types without
+        creating wrapper objects. No speedup this time, but prepares for a future
+        speedup without slowing things down.
+
+        SunSpider reports no change.
+
+        - Eliminated the implementsCall, callAsFunction and construct virtual
+          functions from JSObject. Instead, the CallData and ConstructData for
+          a native function includes a function pointer that the caller can use
+          directly. Changed all call sites to use CallData and ConstructData.
+
+        - Changed the "this" argument to native functions to be a JSValue rather
+          than a JSObject. This prepares us for passing primitives into these
+          functions. The conversion to an object now must be done inside the
+          function. Critically, if it's a function that can be called on a DOM
+          window object, then we have to be sure to call toThisObject on the
+          argument before we use it for anything even if it's already an object.
+
+        - Eliminated the practice of using constructor objects in the global
+          object to make objects of the various basic types. Since these
+          constructors can't be replaced by script, there's no reason to involve
+          a constructor object at all. Added functions to do the construction
+          directly.
+
+        - Made some more class members private and protected, including virtual
+          function overrides. This can catch code using unnecessarily slow virtual
+          function code paths when the type of an object is known statically. If we
+          later find a new reason use the members outside the class it's easy to
+          make them public again.
+
+        - Moved the declarations of the native implementations for functions out
+          of header files. These can have internal linkage and be declared inside
+          the source file.
+
+        - Changed PrototypeFunction to take function pointers with the right
+          arguments to be put directly into CallData. This eliminates the
+          need to have a separate PrototypeReflexiveFunction, and reveals that the
+          real purpose of that class included something else specific to eval --
+          storage of a cached global object. So renamed PrototypeReflexiveFunction
+          to GlobalEvalFunction.
+
+        * API/JSCallbackConstructor.cpp:
+        (KJS::constructJSCallback):
+        (KJS::JSCallbackConstructor::getConstructData):
+        * API/JSCallbackConstructor.h:
+        * API/JSCallbackFunction.cpp:
+        (KJS::JSCallbackFunction::implementsHasInstance):
+        (KJS::JSCallbackFunction::call):
+        (KJS::JSCallbackFunction::getCallData):
+        * API/JSCallbackFunction.h:
+        (KJS::JSCallbackFunction::classInfo):
+        * API/JSCallbackObject.h:
+        (KJS::JSCallbackObject::classRef):
+        (KJS::JSCallbackObject::classInfo):
+        * API/JSCallbackObjectFunctions.h:
+        (KJS::::getConstructData):
+        (KJS::::construct):
+        (KJS::::getCallData):
+        (KJS::::call):
+        * API/JSObjectRef.cpp:
+        (JSObjectMakeFunction):
+        (JSObjectIsFunction):
+        (JSObjectCallAsFunction):
+        (JSObjectCallAsConstructor):
+        * JavaScriptCore.exp:
+        * VM/Machine.cpp:
+        (KJS::jsTypeStringForValue):
+        (KJS::Machine::privateExecute):
+        * kjs/ArrayPrototype.cpp:
+        (KJS::arrayProtoFuncToString):
+        (KJS::arrayProtoFuncToLocaleString):
+        (KJS::arrayProtoFuncJoin):
+        (KJS::arrayProtoFuncConcat):
+        (KJS::arrayProtoFuncPop):
+        (KJS::arrayProtoFuncPush):
+        (KJS::arrayProtoFuncReverse):
+        (KJS::arrayProtoFuncShift):
+        (KJS::arrayProtoFuncSlice):
+        (KJS::arrayProtoFuncSort):
+        (KJS::arrayProtoFuncSplice):
+        (KJS::arrayProtoFuncUnShift):
+        (KJS::arrayProtoFuncFilter):
+        (KJS::arrayProtoFuncMap):
+        (KJS::arrayProtoFuncEvery):
+        (KJS::arrayProtoFuncForEach):
+        (KJS::arrayProtoFuncSome):
+        (KJS::arrayProtoFuncIndexOf):
+        (KJS::arrayProtoFuncLastIndexOf):
+        (KJS::ArrayConstructor::ArrayConstructor):
+        (KJS::constructArrayWithSizeQuirk):
+        (KJS::constructWithArrayConstructor):
+        (KJS::ArrayConstructor::getConstructData):
+        (KJS::callArrayConstructor):
+        (KJS::ArrayConstructor::getCallData):
+        * kjs/ArrayPrototype.h:
+        * kjs/BooleanObject.cpp:
+        (KJS::booleanProtoFuncToString):
+        (KJS::booleanProtoFuncValueOf):
+        (KJS::constructBoolean):
+        (KJS::constructWithBooleanConstructor):
+        (KJS::BooleanConstructor::getConstructData):
+        (KJS::callBooleanConstructor):
+        (KJS::BooleanConstructor::getCallData):
+        (KJS::constructBooleanFromImmediateBoolean):
+        * kjs/BooleanObject.h:
+        * kjs/CallData.h:
+        (KJS::):
+        * kjs/ConstructData.h:
+        (KJS::):
+        * kjs/FunctionPrototype.cpp:
+        (KJS::callFunctionPrototype):
+        (KJS::FunctionPrototype::getCallData):
+        (KJS::functionProtoFuncToString):
+        (KJS::functionProtoFuncApply):
+        (KJS::functionProtoFuncCall):
+        (KJS::constructWithFunctionConstructor):
+        (KJS::FunctionConstructor::getConstructData):
+        (KJS::callFunctionConstructor):
+        (KJS::FunctionConstructor::getCallData):
+        (KJS::constructFunction):
+        * kjs/FunctionPrototype.h:
+        * kjs/JSArray.cpp:
+        (KJS::AVLTreeAbstractorForArrayCompare::compare_key_key):
+        (KJS::JSArray::sort):
+        (KJS::constructEmptyArray):
+        (KJS::constructArray):
+        * kjs/JSArray.h:
+        (KJS::JSArray::classInfo):
+        * kjs/JSFunction.cpp:
+        (KJS::JSFunction::call):
+        (KJS::globalFuncEval):
+        (KJS::globalFuncParseInt):
+        (KJS::globalFuncParseFloat):
+        (KJS::globalFuncIsNaN):
+        (KJS::globalFuncIsFinite):
+        (KJS::globalFuncDecodeURI):
+        (KJS::globalFuncDecodeURIComponent):
+        (KJS::globalFuncEncodeURI):
+        (KJS::globalFuncEncodeURIComponent):
+        (KJS::globalFuncEscape):
+        (KJS::globalFuncUnescape):
+        (KJS::globalFuncKJSPrint):
+        (KJS::PrototypeFunction::PrototypeFunction):
+        (KJS::PrototypeFunction::getCallData):
+        (KJS::GlobalEvalFunction::GlobalEvalFunction):
+        (KJS::GlobalEvalFunction::mark):
+        * kjs/JSFunction.h:
+        (KJS::InternalFunction::classInfo):
+        (KJS::InternalFunction::functionName):
+        (KJS::JSFunction::classInfo):
+        (KJS::GlobalEvalFunction::cachedGlobalObject):
+        * kjs/JSGlobalObject.cpp:
+        (KJS::JSGlobalObject::reset):
+        (KJS::JSGlobalObject::mark):
+        * kjs/JSGlobalObject.h:
+        (KJS::JSGlobalObject::JSGlobalObject):
+        (KJS::JSGlobalObject::evalFunction):
+        * kjs/JSImmediate.cpp:
+        (KJS::JSImmediate::toObject):
+        * kjs/JSNotAnObject.cpp:
+        * kjs/JSNotAnObject.h:
+        * kjs/JSObject.cpp:
+        (KJS::JSObject::put):
+        (KJS::callDefaultValueFunction):
+        (KJS::JSObject::defaultValue):
+        (KJS::JSObject::lookupGetter):
+        (KJS::JSObject::lookupSetter):
+        (KJS::JSObject::hasInstance):
+        (KJS::JSObject::fillGetterPropertySlot):
+        (KJS::Error::create):
+        (KJS::constructEmptyObject):
+        * kjs/JSObject.h:
+        (KJS::GetterSetter::GetterSetter):
+        (KJS::GetterSetter::getter):
+        (KJS::GetterSetter::setGetter):
+        (KJS::GetterSetter::setter):
+        (KJS::GetterSetter::setSetter):
+        * kjs/JSValue.cpp:
+        (KJS::JSCell::deleteProperty):
+        (KJS::call):
+        (KJS::construct):
+        * kjs/JSValue.h:
+        * kjs/MathObject.cpp:
+        (KJS::mathProtoFuncAbs):
+        (KJS::mathProtoFuncACos):
+        (KJS::mathProtoFuncASin):
+        (KJS::mathProtoFuncATan):
+        (KJS::mathProtoFuncATan2):
+        (KJS::mathProtoFuncCeil):
+        (KJS::mathProtoFuncCos):
+        (KJS::mathProtoFuncExp):
+        (KJS::mathProtoFuncFloor):
+        (KJS::mathProtoFuncLog):
+        (KJS::mathProtoFuncMax):
+        (KJS::mathProtoFuncMin):
+        (KJS::mathProtoFuncPow):
+        (KJS::mathProtoFuncRandom):
+        (KJS::mathProtoFuncRound):
+        (KJS::mathProtoFuncSin):
+        (KJS::mathProtoFuncSqrt):
+        (KJS::mathProtoFuncTan):
+        * kjs/MathObject.h:
+        * kjs/NumberObject.cpp:
+        (KJS::numberProtoFuncToString):
+        (KJS::numberProtoFuncToLocaleString):
+        (KJS::numberProtoFuncValueOf):
+        (KJS::numberProtoFuncToFixed):
+        (KJS::numberProtoFuncToExponential):
+        (KJS::numberProtoFuncToPrecision):
+        (KJS::NumberConstructor::NumberConstructor):
+        (KJS::constructWithNumberConstructor):
+        (KJS::NumberConstructor::getConstructData):
+        (KJS::callNumberConstructor):
+        (KJS::NumberConstructor::getCallData):
+        (KJS::constructNumber):
+        (KJS::constructNumberFromImmediateNumber):
+        * kjs/NumberObject.h:
+        (KJS::NumberObject::classInfo):
+        (KJS::NumberConstructor::classInfo):
+        * kjs/PropertySlot.cpp:
+        (KJS::PropertySlot::functionGetter):
+        * kjs/RegExpObject.cpp:
+        (KJS::regExpProtoFuncTest):
+        (KJS::regExpProtoFuncExec):
+        (KJS::regExpProtoFuncCompile):
+        (KJS::regExpProtoFuncToString):
+        (KJS::callRegExpObject):
+        (KJS::RegExpObject::getCallData):
+        (KJS::constructRegExp):
+        (KJS::constructWithRegExpConstructor):
+        (KJS::RegExpConstructor::getConstructData):
+        (KJS::callRegExpConstructor):
+        (KJS::RegExpConstructor::getCallData):
+        * kjs/RegExpObject.h:
+        (KJS::RegExpConstructor::classInfo):
+        * kjs/Shell.cpp:
+        (GlobalObject::GlobalObject):
+        (functionPrint):
+        (functionDebug):
+        (functionGC):
+        (functionVersion):
+        (functionRun):
+        (functionLoad):
+        (functionReadline):
+        (functionQuit):
+        * kjs/date_object.cpp:
+        (KJS::gmtoffset):
+        (KJS::formatLocaleDate):
+        (KJS::fillStructuresUsingDateArgs):
+        (KJS::DateInstance::getTime):
+        (KJS::DateInstance::getUTCTime):
+        (KJS::DateConstructor::DateConstructor):
+        (KJS::constructDate):
+        (KJS::DateConstructor::getConstructData):
+        (KJS::callDate):
+        (KJS::DateConstructor::getCallData):
+        (KJS::dateParse):
+        (KJS::dateNow):
+        (KJS::dateUTC):
+        (KJS::dateProtoFuncToString):
+        (KJS::dateProtoFuncToUTCString):
+        (KJS::dateProtoFuncToDateString):
+        (KJS::dateProtoFuncToTimeString):
+        (KJS::dateProtoFuncToLocaleString):
+        (KJS::dateProtoFuncToLocaleDateString):
+        (KJS::dateProtoFuncToLocaleTimeString):
+        (KJS::dateProtoFuncValueOf):
+        (KJS::dateProtoFuncGetTime):
+        (KJS::dateProtoFuncGetFullYear):
+        (KJS::dateProtoFuncGetUTCFullYear):
+        (KJS::dateProtoFuncToGMTString):
+        (KJS::dateProtoFuncGetMonth):
+        (KJS::dateProtoFuncGetUTCMonth):
+        (KJS::dateProtoFuncGetDate):
+        (KJS::dateProtoFuncGetUTCDate):
+        (KJS::dateProtoFuncGetDay):
+        (KJS::dateProtoFuncGetUTCDay):
+        (KJS::dateProtoFuncGetHours):
+        (KJS::dateProtoFuncGetUTCHours):
+        (KJS::dateProtoFuncGetMinutes):
+        (KJS::dateProtoFuncGetUTCMinutes):
+        (KJS::dateProtoFuncGetSeconds):
+        (KJS::dateProtoFuncGetUTCSeconds):
+        (KJS::dateProtoFuncGetMilliSeconds):
+        (KJS::dateProtoFuncGetUTCMilliseconds):
+        (KJS::dateProtoFuncGetTimezoneOffset):
+        (KJS::dateProtoFuncSetTime):
+        (KJS::setNewValueFromTimeArgs):
+        (KJS::setNewValueFromDateArgs):
+        (KJS::dateProtoFuncSetMilliSeconds):
+        (KJS::dateProtoFuncSetUTCMilliseconds):
+        (KJS::dateProtoFuncSetSeconds):
+        (KJS::dateProtoFuncSetUTCSeconds):
+        (KJS::dateProtoFuncSetMinutes):
+        (KJS::dateProtoFuncSetUTCMinutes):
+        (KJS::dateProtoFuncSetHours):
+        (KJS::dateProtoFuncSetUTCHours):
+        (KJS::dateProtoFuncSetDate):
+        (KJS::dateProtoFuncSetUTCDate):
+        (KJS::dateProtoFuncSetMonth):
+        (KJS::dateProtoFuncSetUTCMonth):
+        (KJS::dateProtoFuncSetFullYear):
+        (KJS::dateProtoFuncSetUTCFullYear):
+        (KJS::dateProtoFuncSetYear):
+        (KJS::dateProtoFuncGetYear):
+        * kjs/date_object.h:
+        (KJS::DateInstance::internalNumber):
+        (KJS::DateInstance::classInfo):
+        * kjs/error_object.cpp:
+        (KJS::errorProtoFuncToString):
+        (KJS::constructError):
+        (KJS::constructWithErrorConstructor):
+        (KJS::ErrorConstructor::getConstructData):
+        (KJS::callErrorConstructor):
+        (KJS::ErrorConstructor::getCallData):
+        (KJS::NativeErrorConstructor::construct):
+        (KJS::constructWithNativeErrorConstructor):
+        (KJS::NativeErrorConstructor::getConstructData):
+        (KJS::callNativeErrorConstructor):
+        (KJS::NativeErrorConstructor::getCallData):
+        * kjs/error_object.h:
+        (KJS::NativeErrorConstructor::classInfo):
+        * kjs/internal.cpp:
+        (KJS::JSNumberCell::toObject):
+        (KJS::JSNumberCell::toThisObject):
+        (KJS::GetterSetter::mark):
+        (KJS::GetterSetter::toPrimitive):
+        (KJS::GetterSetter::toBoolean):
+        (KJS::GetterSetter::toNumber):
+        (KJS::GetterSetter::toString):
+        (KJS::GetterSetter::toObject):
+        (KJS::InternalFunction::InternalFunction):
+        (KJS::InternalFunction::implementsHasInstance):
+        * kjs/lookup.h:
+        (KJS::HashEntry::):
+        * kjs/nodes.cpp:
+        (KJS::FuncDeclNode::makeFunction):
+        (KJS::FuncExprNode::makeFunction):
+        * kjs/object_object.cpp:
+        (KJS::objectProtoFuncValueOf):
+        (KJS::objectProtoFuncHasOwnProperty):
+        (KJS::objectProtoFuncIsPrototypeOf):
+        (KJS::objectProtoFuncDefineGetter):
+        (KJS::objectProtoFuncDefineSetter):
+        (KJS::objectProtoFuncLookupGetter):
+        (KJS::objectProtoFuncLookupSetter):
+        (KJS::objectProtoFuncPropertyIsEnumerable):
+        (KJS::objectProtoFuncToLocaleString):
+        (KJS::objectProtoFuncToString):
+        (KJS::ObjectConstructor::ObjectConstructor):
+        (KJS::constructObject):
+        (KJS::constructWithObjectConstructor):
+        (KJS::ObjectConstructor::getConstructData):
+        (KJS::callObjectConstructor):
+        (KJS::ObjectConstructor::getCallData):
+        * kjs/object_object.h:
+        * kjs/string_object.cpp:
+        (KJS::replace):
+        (KJS::stringProtoFuncToString):
+        (KJS::stringProtoFuncValueOf):
+        (KJS::stringProtoFuncCharAt):
+        (KJS::stringProtoFuncCharCodeAt):
+        (KJS::stringProtoFuncConcat):
+        (KJS::stringProtoFuncIndexOf):
+        (KJS::stringProtoFuncLastIndexOf):
+        (KJS::stringProtoFuncMatch):
+        (KJS::stringProtoFuncSearch):
+        (KJS::stringProtoFuncReplace):
+        (KJS::stringProtoFuncSlice):
+        (KJS::stringProtoFuncSplit):
+        (KJS::stringProtoFuncSubstr):
+        (KJS::stringProtoFuncSubstring):
+        (KJS::stringProtoFuncToLowerCase):
+        (KJS::stringProtoFuncToUpperCase):
+        (KJS::stringProtoFuncToLocaleLowerCase):
+        (KJS::stringProtoFuncToLocaleUpperCase):
+        (KJS::stringProtoFuncLocaleCompare):
+        (KJS::stringProtoFuncBig):
+        (KJS::stringProtoFuncSmall):
+        (KJS::stringProtoFuncBlink):
+        (KJS::stringProtoFuncBold):
+        (KJS::stringProtoFuncFixed):
+        (KJS::stringProtoFuncItalics):
+        (KJS::stringProtoFuncStrike):
+        (KJS::stringProtoFuncSub):
+        (KJS::stringProtoFuncSup):
+        (KJS::stringProtoFuncFontcolor):
+        (KJS::stringProtoFuncFontsize):
+        (KJS::stringProtoFuncAnchor):
+        (KJS::stringProtoFuncLink):
+        (KJS::stringFromCharCode):
+        (KJS::StringConstructor::StringConstructor):
+        (KJS::constructWithStringConstructor):
+        (KJS::StringConstructor::getConstructData):
+        (KJS::callStringConstructor):
+        (KJS::StringConstructor::getCallData):
+        * kjs/string_object.h:
+
 2008-06-23  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
 
         Reviewed by Oliver.
index 697ef2a4efc8871e72c46b1f4f0c32d32175f98d..299785cae5f76437fca2c629924921f15fc94f23 100644 (file)
@@ -123,8 +123,8 @@ __ZN3KJS14JSGlobalObject4markEv
 __ZN3KJS14JSGlobalObjectD2Ev
 __ZN3KJS14JSGlobalObjectnwEm
 __ZN3KJS14JSGlobalObjectnwEmNS0_9SharedTagE
+__ZN3KJS14constructArrayEPNS_9ExecStateERKNS_7ArgListE
 __ZN3KJS15JSWrapperObject4markEv
-__ZN3KJS16InternalFunction11getCallDataERNS_8CallDataE
 __ZN3KJS16InternalFunction4infoE
 __ZN3KJS16InternalFunctionC2EPNS_17FunctionPrototypeERKNS_10IdentifierE
 __ZN3KJS16JSVariableObject14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
@@ -132,11 +132,13 @@ __ZN3KJS16JSVariableObject16getPropertyNamesEPNS_9ExecStateERNS_17PropertyNameAr
 __ZN3KJS16ParserRefCounted3refEv
 __ZN3KJS16ParserRefCounted5derefEv
 __ZN3KJS17PropertyNameArray3addEPNS_7UString3RepE
-__ZN3KJS17PrototypeFunctionC1EPNS_9ExecStateEPNS_17FunctionPrototypeEiRKNS_10IdentifierEPFPNS_7JSValueES2_PNS_8JSObjectERKNS_7ArgListEE
-__ZN3KJS17PrototypeFunctionC1EPNS_9ExecStateEiRKNS_10IdentifierEPFPNS_7JSValueES2_PNS_8JSObjectERKNS_7ArgListEE
+__ZN3KJS17PrototypeFunctionC1EPNS_9ExecStateEPNS_17FunctionPrototypeEiRKNS_10IdentifierEPFPNS_7JSValueES2_PNS_8JSObjectES9_RKNS_7ArgListEE
+__ZN3KJS17PrototypeFunctionC1EPNS_9ExecStateEiRKNS_10IdentifierEPFPNS_7JSValueES2_PNS_8JSObjectES7_RKNS_7ArgListEE
 __ZN3KJS17RegisterFileStack20allocateRegisterFileEmPS0_
+__ZN3KJS17constructFunctionEPNS_9ExecStateERKNS_7ArgListERKNS_10IdentifierERKNS_7UStringEi
+__ZN3KJS19constructEmptyArrayEPNS_9ExecStateE
 __ZN3KJS19initializeThreadingEv
-__ZN3KJS23objectProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectERKNS_7ArgListE
+__ZN3KJS23objectProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectEPNS_7JSValueERKNS_7ArgListE
 __ZN3KJS4Heap14allocateNumberEm
 __ZN3KJS4Heap15recordExtraCostEm
 __ZN3KJS4Heap17globalObjectCountEv
@@ -150,8 +152,11 @@ __ZN3KJS4Heap7collectEv
 __ZN3KJS4Heap7protectEPNS_7JSValueE
 __ZN3KJS4Heap8allocateEm
 __ZN3KJS4Heap9unprotectEPNS_7JSValueE
+__ZN3KJS4callEPNS_9ExecStateEPNS_7JSValueENS_8CallTypeERKNS_8CallDataES3_RKNS_7ArgListE
 __ZN3KJS5equalEPKNS_7UString3RepES3_
 __ZN3KJS6JSCell11getCallDataERNS_8CallDataE
+__ZN3KJS6JSCell14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
+__ZN3KJS6JSCell14deletePropertyEPNS_9ExecStateEj
 __ZN3KJS6JSCell16getConstructDataERNS_13ConstructDataE
 __ZN3KJS6JSCell18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
 __ZN3KJS6JSCell18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
@@ -193,10 +198,8 @@ __ZN3KJS8JSObject12defineGetterEPNS_9ExecStateERKNS_10IdentifierEPS0_
 __ZN3KJS8JSObject12defineSetterEPNS_9ExecStateERKNS_10IdentifierEPS0_
 __ZN3KJS8JSObject12lookupGetterEPNS_9ExecStateERKNS_10IdentifierE
 __ZN3KJS8JSObject12lookupSetterEPNS_9ExecStateERKNS_10IdentifierE
-__ZN3KJS8JSObject14callAsFunctionEPNS_9ExecStateEPS0_RKNS_7ArgListE
 __ZN3KJS8JSObject14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
 __ZN3KJS8JSObject14deletePropertyEPNS_9ExecStateEj
-__ZN3KJS8JSObject14implementsCallEv
 __ZN3KJS8JSObject16getPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayE
 __ZN3KJS8JSObject17putDirectFunctionEPNS_16InternalFunctionEi
 __ZN3KJS8JSObject17putWithAttributesEPNS_9ExecStateERKNS_10IdentifierEPNS_7JSValueEj
@@ -207,13 +210,12 @@ __ZN3KJS8JSObject22fillGetterPropertySlotERNS_12PropertySlotEPPNS_7JSValueE
 __ZN3KJS8JSObject3putEPNS_9ExecStateERKNS_10IdentifierEPNS_7JSValueE
 __ZN3KJS8JSObject3putEPNS_9ExecStateEjPNS_7JSValueE
 __ZN3KJS8JSObject4markEv
-__ZN3KJS8JSObject9constructEPNS_9ExecStateERKNS_7ArgListE
-__ZN3KJS8JSObject9constructEPNS_9ExecStateERKNS_7ArgListERKNS_10IdentifierERKNS_7UStringEi
 __ZN3KJS8Profiler13stopProfilingEPNS_9ExecStateERKNS_7UStringE
 __ZN3KJS8Profiler14startProfilingEPNS_9ExecStateERKNS_7UStringEPNS_14ProfilerClientE
 __ZN3KJS8Profiler8profilerEv
 __ZN3KJS8jsStringEPNS_9ExecStateEPKc
 __ZN3KJS8jsStringEPNS_9ExecStateERKNS_7UStringE
+__ZN3KJS9constructEPNS_9ExecStateEPNS_7JSValueENS_13ConstructTypeERKNS_13ConstructDataERKNS_7ArgListE
 __ZN3KJSeqERKNS_7UStringEPKc
 __ZN3KJSgtERKNS_7UStringES2_
 __ZN3KJSltERKNS_7UStringES2_
@@ -259,6 +261,7 @@ __ZNK3KJS4Node8toStringEv
 __ZNK3KJS6JSCell12toThisObjectEPNS_9ExecStateE
 __ZNK3KJS6JSCell17getTruncatedInt32ERi
 __ZNK3KJS6JSCell18getTruncatedUInt32ERj
+__ZNK3KJS6JSCell9classInfoEv
 __ZNK3KJS6JSCell9getNumberEv
 __ZNK3KJS6JSCell9getStringERNS_7UStringE
 __ZNK3KJS6JSCell9getStringEv
@@ -287,7 +290,6 @@ __ZNK3KJS8JSObject4typeEv
 __ZNK3KJS8JSObject8toNumberEPNS_9ExecStateE
 __ZNK3KJS8JSObject8toObjectEPNS_9ExecStateE
 __ZNK3KJS8JSObject8toStringEPNS_9ExecStateE
-__ZNK3KJS8JSObject9classInfoEv
 __ZNK3KJS8JSObject9classNameEv
 __ZNK3KJS8JSObject9toBooleanEPNS_9ExecStateE
 __ZNK3KJS9HashTable11createTableEPNS_12JSGlobalDataE
index 7e3436786df62d13970382bd59fc19dbc6be6c9d..6c9640bc5e1c9aa4a280b60400fe54ae145fbd82 100644 (file)
@@ -184,7 +184,8 @@ static JSValue* jsTypeStringForValue(ExecState* exec, JSValue* v)
                 // as null when doing comparisons.
                 if (static_cast<JSObject*>(v)->masqueradeAsUndefined())
                     return jsString(exec, "undefined");
-                else if (static_cast<JSObject*>(v)->implementsCall())
+                CallData callData;
+                if (static_cast<JSObject*>(v)->getCallData(callData) != CallTypeNone)
                     return jsString(exec, "function");
             }
 
@@ -946,7 +947,7 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, ExecState* exec, RegisterFi
            constructor, and puts the result in register dst.
         */
         int dst = (++vPC)->u.operand;
-        r[dst].u.jsValue = scopeChain->globalObject()->objectConstructor()->construct(exec, exec->emptyList());
+        r[dst].u.jsValue = constructEmptyObject(exec);
 
         ++vPC;
         NEXT_OPCODE;
@@ -958,7 +959,7 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, ExecState* exec, RegisterFi
            constructor, and puts the result in register dst.
         */
         int dst = (++vPC)->u.operand;
-        r[dst].u.jsValue = scopeChain->globalObject()->arrayConstructor()->construct(exec, exec->emptyList());
+        r[dst].u.jsValue = constructEmptyArray(exec);
 
         ++vPC;
         NEXT_OPCODE;
@@ -2114,12 +2115,12 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, ExecState* exec, RegisterFi
             int registerOffset = r - (*registerBase);
 
             r[firstArg].u.jsValue = thisVal == missingThisObjectMarker() ? exec->globalThisValue() : (r[thisVal].u.jsValue)->toObject(exec);
-            JSObject* thisObj = static_cast<JSObject*>(r[firstArg].u.jsValue);
+            JSValue* thisValue = r[firstArg].u.jsValue;
 
             ArgList args(reinterpret_cast<JSValue***>(registerBase), registerOffset + firstArg + 1, argCount - 1);
 
             registerFile->setSafeForReentry(true);
-            JSValue* returnValue = static_cast<JSObject*>(v)->callAsFunction(exec, thisObj, args);
+            JSValue* returnValue = callData.native.function(exec, static_cast<JSObject*>(v), thisValue, args);
             registerFile->setSafeForReentry(false);
 
             r = (*registerBase) + registerOffset;
@@ -2256,7 +2257,7 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, ExecState* exec, RegisterFi
             ArgList args(reinterpret_cast<JSValue***>(registerBase), registerOffset + firstArg + 1, argCount - 1);
 
             registerFile->setSafeForReentry(true);
-            JSValue* returnValue = constructor->construct(exec, args);
+            JSValue* returnValue = constructData.native.function(exec, constructor, args);
             registerFile->setSafeForReentry(false);
 
             r = (*registerBase) + registerOffset;
index 1a4039c83213b2a0c55fb918132891d91bb15c6f..f769cf135a7c11bcf5a83422a9b483b07dd36390 100644 (file)
@@ -23,7 +23,6 @@
 
 #include "config.h"
 #include "ArrayPrototype.h"
-#include "ArrayPrototype.lut.h"
 
 #include "Machine.h"
 #include "error_object.h"
 
 namespace KJS {
 
+static JSValue* arrayProtoFuncToString(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* arrayProtoFuncToLocaleString(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* arrayProtoFuncConcat(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* arrayProtoFuncJoin(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* arrayProtoFuncPop(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* arrayProtoFuncPush(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* arrayProtoFuncReverse(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* arrayProtoFuncShift(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* arrayProtoFuncSlice(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* arrayProtoFuncSort(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* arrayProtoFuncSplice(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* arrayProtoFuncUnShift(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* arrayProtoFuncEvery(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* arrayProtoFuncForEach(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* arrayProtoFuncSome(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* arrayProtoFuncIndexOf(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* arrayProtoFuncFilter(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* arrayProtoFuncMap(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* arrayProtoFuncLastIndexOf(ExecState*, JSObject*, JSValue*, const ArgList&);
+
+}
+
+#include "ArrayPrototype.lut.h"
+
+namespace KJS {
+
 // ------------------------------ ArrayPrototype ----------------------------
 
 const ClassInfo ArrayPrototype::info = {"Array", &JSArray::info, 0, ExecState::arrayTable};
@@ -88,10 +113,11 @@ static JSValue* getProperty(ExecState* exec, JSObject* obj, unsigned index)
     return slot.getValue(exec, index);
 }
 
-JSValue* arrayProtoFuncToString(ExecState* exec, JSObject* thisObj, const ArgList&)
+JSValue* arrayProtoFuncToString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
 {
-    if (!thisObj->inherits(&JSArray::info))
+    if (!thisValue->isObject(&JSArray::info))
         return throwError(exec, TypeError);
+    JSObject* thisObj = static_cast<JSArray*>(thisValue);
 
     HashSet<JSObject*>& arrayVisitedElements = exec->dynamicGlobalObject()->arrayVisitedElements();
     if (arrayVisitedElements.size() > MaxReentryDepth)
@@ -131,10 +157,11 @@ JSValue* arrayProtoFuncToString(ExecState* exec, JSObject* thisObj, const ArgLis
     return jsString(exec, UString(strBuffer.data(), strBuffer.data() ? strBuffer.size() : 0));
 }
 
-JSValue* arrayProtoFuncToLocaleString(ExecState* exec, JSObject* thisObj, const ArgList&)
+JSValue* arrayProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
 {
-    if (!thisObj->inherits(&JSArray::info))
+    if (!thisValue->isObject(&JSArray::info))
         return throwError(exec, TypeError);
+    JSObject* thisObj = static_cast<JSArray*>(thisValue);
 
     HashSet<JSObject*>& arrayVisitedElements = exec->dynamicGlobalObject()->arrayVisitedElements();
     if (arrayVisitedElements.size() > MaxReentryDepth)
@@ -162,8 +189,10 @@ JSValue* arrayProtoFuncToLocaleString(ExecState* exec, JSObject* thisObj, const
         JSObject* o = element->toObject(exec);
         JSValue* conversionFunction = o->get(exec, exec->propertyNames().toLocaleString);
         UString str;
-        if (conversionFunction->isObject() && static_cast<JSObject*>(conversionFunction)->implementsCall())
-            str = static_cast<JSObject*>(conversionFunction)->callAsFunction(exec, o, exec->emptyList())->toString(exec);
+        CallData callData;
+        CallType callType = conversionFunction->getCallData(callData);
+        if (callType != CallTypeNone)
+            str = call(exec, conversionFunction, callType, callData, element, exec->emptyList())->toString(exec);
         else
             str = element->toString(exec);
         strBuffer.append(str.data(), str.size());
@@ -180,8 +209,10 @@ JSValue* arrayProtoFuncToLocaleString(ExecState* exec, JSObject* thisObj, const
     return jsString(exec, UString(strBuffer.data(), strBuffer.data() ? strBuffer.size() : 0));
 }
 
-JSValue* arrayProtoFuncJoin(ExecState* exec, JSObject* thisObj, const ArgList& args)
+JSValue* arrayProtoFuncJoin(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
+    JSObject* thisObj = thisValue->toThisObject(exec);
+
     HashSet<JSObject*>& arrayVisitedElements = exec->dynamicGlobalObject()->arrayVisitedElements();
     if (arrayVisitedElements.size() > MaxReentryDepth)
         return throwError(exec, RangeError, "Maximum call stack size exceeded.");
@@ -223,25 +254,21 @@ JSValue* arrayProtoFuncJoin(ExecState* exec, JSObject* thisObj, const ArgList& a
     return jsString(exec, UString(strBuffer.data(), strBuffer.data() ? strBuffer.size() : 0));
 }
 
-JSValue* arrayProtoFuncConcat(ExecState* exec, JSObject* thisObj, const ArgList& args)
+JSValue* arrayProtoFuncConcat(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
-    JSObject* arr = static_cast<JSObject*>(exec->lexicalGlobalObject()->arrayConstructor()->construct(exec, exec->emptyList()));
+    JSArray* arr = constructEmptyArray(exec);
     int n = 0;
-    JSValue* curArg = thisObj;
-    JSObject* curObj = static_cast<JSObject* >(thisObj);
+    JSValue* curArg = thisValue->toThisObject(exec);
     ArgList::const_iterator it = args.begin();
     ArgList::const_iterator end = args.end();
     while (1) {
-        if (curArg->isObject() && curObj->inherits(&JSArray::info)) {
-            unsigned k = 0;
-            // Older versions tried to optimize out getting the length of thisObj
-            // by checking for n != 0, but that doesn't work if thisObj is an empty array.
-            unsigned length = curObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
-            while (k < length) {
-                if (JSValue* v = getProperty(exec, curObj, k))
+        if (curArg->isObject(&JSArray::info)) {
+            JSArray* curArray = static_cast<JSArray*>(curArg);
+            unsigned length = curArray->getLength();
+            for (unsigned k = 0; k < length; ++k) {
+                if (JSValue* v = curArray->getItem(k))
                     arr->put(exec, n, v);
                 n++;
-                k++;
             }
         } else {
             arr->put(exec, n, curArg);
@@ -250,15 +277,15 @@ JSValue* arrayProtoFuncConcat(ExecState* exec, JSObject* thisObj, const ArgList&
         if (it == end)
             break;
         curArg = *it;
-        curObj = static_cast<JSObject*>(curArg); // may be 0
         ++it;
     }
-    arr->put(exec, exec->propertyNames().length, jsNumber(exec, n));
+    arr->setLength(n);
     return arr;
 }
 
-JSValue* arrayProtoFuncPop(ExecState* exec, JSObject* thisObj, const ArgList&)
+JSValue* arrayProtoFuncPop(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
 {
+    JSObject* thisObj = thisValue->toThisObject(exec);
     JSValue* result = 0;
     unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
     if (length == 0) {
@@ -272,8 +299,9 @@ JSValue* arrayProtoFuncPop(ExecState* exec, JSObject* thisObj, const ArgList&)
     return result;
 }
 
-JSValue* arrayProtoFuncPush(ExecState* exec, JSObject* thisObj, const ArgList& args)
+JSValue* arrayProtoFuncPush(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
+    JSObject* thisObj = thisValue->toThisObject(exec);
     unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
     for (unsigned n = 0; n < args.size(); n++)
         thisObj->put(exec, length + n, args[n]);
@@ -282,8 +310,9 @@ JSValue* arrayProtoFuncPush(ExecState* exec, JSObject* thisObj, const ArgList& a
     return jsNumber(exec, length);
 }
 
-JSValue* arrayProtoFuncReverse(ExecState* exec, JSObject* thisObj, const ArgList&)
+JSValue* arrayProtoFuncReverse(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
 {
+    JSObject* thisObj = thisValue->toThisObject(exec);
     unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
     unsigned middle = length / 2;
 
@@ -305,8 +334,9 @@ JSValue* arrayProtoFuncReverse(ExecState* exec, JSObject* thisObj, const ArgList
     return thisObj;
 }
 
-JSValue* arrayProtoFuncShift(ExecState* exec, JSObject* thisObj, const ArgList&)
+JSValue* arrayProtoFuncShift(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
 {
+    JSObject* thisObj = thisValue->toThisObject(exec);
     JSValue* result = 0;
 
     unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
@@ -327,12 +357,14 @@ JSValue* arrayProtoFuncShift(ExecState* exec, JSObject* thisObj, const ArgList&)
     return result;
 }
 
-JSValue* arrayProtoFuncSlice(ExecState* exec, JSObject* thisObj, const ArgList& args)
+JSValue* arrayProtoFuncSlice(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
     // http://developer.netscape.com/docs/manuals/js/client/jsref/array.htm#1193713 or 15.4.4.10
 
+    JSObject* thisObj = thisValue->toThisObject(exec);
+
     // We return a new array
-    JSObject* resObj = static_cast<JSObject* >(exec->lexicalGlobalObject()->arrayConstructor()->construct(exec, exec->emptyList()));
+    JSArray* resObj = constructEmptyArray(exec);
     JSValue* result = resObj;
     double begin = args[0]->toInteger(exec);
     unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
@@ -366,22 +398,21 @@ JSValue* arrayProtoFuncSlice(ExecState* exec, JSObject* thisObj, const ArgList&
         if (JSValue* v = getProperty(exec, thisObj, k))
             resObj->put(exec, n, v);
     }
-    resObj->put(exec, exec->propertyNames().length, jsNumber(exec, n));
+    resObj->setLength(n);
     return result;
 }
 
-JSValue* arrayProtoFuncSort(ExecState* exec, JSObject* thisObj, const ArgList& args)
+JSValue* arrayProtoFuncSort(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
-    JSObject* sortFunction = 0;
-    if (!args[0]->isUndefined()) {
-        sortFunction = args[0]->toObject(exec);
-        if (!sortFunction->implementsCall())
-            sortFunction = 0;
-    }
+    JSObject* thisObj = thisValue->toThisObject(exec);
+
+    JSValue* function = args[0];
+    CallData callData;
+    CallType callType = function->getCallData(callData);
 
     if (thisObj->classInfo() == &JSArray::info) {
-        if (sortFunction)
-            static_cast<JSArray*>(thisObj)->sort(exec, sortFunction);
+        if (callType != CallTypeNone)
+            static_cast<JSArray*>(thisObj)->sort(exec, function, callType, callData);
         else
             static_cast<JSArray*>(thisObj)->sort(exec);
         return thisObj;
@@ -405,11 +436,11 @@ JSValue* arrayProtoFuncSort(ExecState* exec, JSObject* thisObj, const ArgList& a
                 compareResult = 1; // don't check minObj because there's no need to differentiate == (0) from > (1)
             else if (minObj->isUndefined())
                 compareResult = -1;
-            else if (sortFunction) {
+            else if (callType != CallTypeNone) {
                 ArgList l;
                 l.append(jObj);
                 l.append(minObj);
-                compareResult = sortFunction->callAsFunction(exec, exec->globalThisValue(), l)->toNumber(exec);
+                compareResult = call(exec, function, callType, callData, exec->globalThisValue(), l)->toNumber(exec);
             } else
                 compareResult = (jObj->toString(exec) < minObj->toString(exec)) ? -1 : 1;
 
@@ -427,10 +458,12 @@ JSValue* arrayProtoFuncSort(ExecState* exec, JSObject* thisObj, const ArgList& a
     return thisObj;
 }
 
-JSValue* arrayProtoFuncSplice(ExecState* exec, JSObject* thisObj, const ArgList& args)
+JSValue* arrayProtoFuncSplice(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
+    JSObject* thisObj = thisValue->toThisObject(exec);
+
     // 15.4.4.12
-    JSObject* resObj = static_cast<JSObject* >(exec->lexicalGlobalObject()->arrayConstructor()->construct(exec, exec->emptyList()));
+    JSArray* resObj = constructEmptyArray(exec);
     JSValue* result = resObj;
     unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
     if (!args.size())
@@ -451,7 +484,7 @@ JSValue* arrayProtoFuncSplice(ExecState* exec, JSObject* thisObj, const ArgList&
         if (JSValue* v = getProperty(exec, thisObj, k + begin))
             resObj->put(exec, k, v);
     }
-    resObj->put(exec, exec->propertyNames().length, jsNumber(exec, deleteCount));
+    resObj->setLength(deleteCount);
 
     unsigned additionalArgs = std::max<int>(args.size() - 2, 0);
     if (additionalArgs != deleteCount) {
@@ -480,8 +513,10 @@ JSValue* arrayProtoFuncSplice(ExecState* exec, JSObject* thisObj, const ArgList&
     return result;
 }
 
-JSValue* arrayProtoFuncUnShift(ExecState* exec, JSObject* thisObj, const ArgList& args)
+JSValue* arrayProtoFuncUnShift(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
+    JSObject* thisObj = thisValue->toThisObject(exec);
+
     // 15.4.4.13
     unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
     unsigned nrArgs = args.size();
@@ -500,15 +535,18 @@ JSValue* arrayProtoFuncUnShift(ExecState* exec, JSObject* thisObj, const ArgList
     return result;
 }
 
-JSValue* arrayProtoFuncFilter(ExecState* exec, JSObject* thisObj, const ArgList& args)
+JSValue* arrayProtoFuncFilter(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
-    JSObject* eachFunction = args[0]->toObject(exec);
+    JSObject* thisObj = thisValue->toThisObject(exec);
 
-    if (!eachFunction->implementsCall())
+    JSValue* function = args[0];
+    CallData callData;
+    CallType callType = function->getCallData(callData);
+    if (callType == CallTypeNone)
         return throwError(exec, TypeError);
 
-    JSObject* applyThis = args[1]->isUndefinedOrNull() ? exec->globalThisValue() :  args[1]->toObject(exec);
-    JSObject* resultArray = static_cast<JSObject*>(exec->lexicalGlobalObject()->arrayConstructor()->construct(exec, exec->emptyList()));
+    JSObject* applyThis = args[1]->isUndefinedOrNull() ? exec->globalThisValue() : args[1]->toObject(exec);
+    JSArray* resultArray = constructEmptyArray(exec);
 
     unsigned filterIndex = 0;
     unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
@@ -526,7 +564,7 @@ JSValue* arrayProtoFuncFilter(ExecState* exec, JSObject* thisObj, const ArgList&
         eachArguments.append(jsNumber(exec, k));
         eachArguments.append(thisObj);
 
-        JSValue* result = eachFunction->callAsFunction(exec, applyThis, eachArguments);
+        JSValue* result = call(exec, function, callType, callData, applyThis, eachArguments);
 
         if (result->toBoolean(exec))
             resultArray->put(exec, filterIndex++, v);
@@ -534,19 +572,21 @@ JSValue* arrayProtoFuncFilter(ExecState* exec, JSObject* thisObj, const ArgList&
     return resultArray;
 }
 
-JSValue* arrayProtoFuncMap(ExecState* exec, JSObject* thisObj, const ArgList& args)
+JSValue* arrayProtoFuncMap(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
-    JSObject* eachFunction = args[0]->toObject(exec);
-    if (!eachFunction->implementsCall())
+    JSObject* thisObj = thisValue->toThisObject(exec);
+
+    JSValue* function = args[0];
+    CallData callData;
+    CallType callType = function->getCallData(callData);
+    if (callType == CallTypeNone)
         return throwError(exec, TypeError);
 
-    JSObject* applyThis = args[1]->isUndefinedOrNull() ? exec->globalThisValue() :  args[1]->toObject(exec);
+    JSObject* applyThis = args[1]->isUndefinedOrNull() ? exec->globalThisValue() : args[1]->toObject(exec);
 
     unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
 
-    ArgList mapArgs;
-    mapArgs.append(jsNumber(exec, length));
-    JSObject* resultArray = static_cast<JSObject*>(exec->lexicalGlobalObject()->arrayConstructor()->construct(exec, mapArgs));
+    JSArray* resultArray = constructEmptyArray(exec, length);
 
     for (unsigned k = 0; k < length && !exec->hadException(); ++k) {
         PropertySlot slot(thisObj);
@@ -561,7 +601,7 @@ JSValue* arrayProtoFuncMap(ExecState* exec, JSObject* thisObj, const ArgList& ar
         eachArguments.append(jsNumber(exec, k));
         eachArguments.append(thisObj);
 
-        JSValue* result = eachFunction->callAsFunction(exec, applyThis, eachArguments);
+        JSValue* result = call(exec, function, callType, callData, applyThis, eachArguments);
         resultArray->put(exec, k, result);
     }
 
@@ -573,14 +613,17 @@ JSValue* arrayProtoFuncMap(ExecState* exec, JSObject* thisObj, const ArgList& ar
 // http://developer-test.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Array:forEach
 // http://developer-test.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Array:some
 
-JSValue* arrayProtoFuncEvery(ExecState* exec, JSObject* thisObj, const ArgList& args)
+JSValue* arrayProtoFuncEvery(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
-    JSObject* eachFunction = args[0]->toObject(exec);
+    JSObject* thisObj = thisValue->toThisObject(exec);
 
-    if (!eachFunction->implementsCall())
+    JSValue* function = args[0];
+    CallData callData;
+    CallType callType = function->getCallData(callData);
+    if (callType == CallTypeNone)
         return throwError(exec, TypeError);
 
-    JSObject* applyThis = args[1]->isUndefinedOrNull() ? exec->globalThisValue() :  args[1]->toObject(exec);
+    JSObject* applyThis = args[1]->isUndefinedOrNull() ? exec->globalThisValue() : args[1]->toObject(exec);
 
     JSValue* result = jsBoolean(true);
 
@@ -597,7 +640,7 @@ JSValue* arrayProtoFuncEvery(ExecState* exec, JSObject* thisObj, const ArgList&
         eachArguments.append(jsNumber(exec, k));
         eachArguments.append(thisObj);
 
-        bool predicateResult = eachFunction->callAsFunction(exec, applyThis, eachArguments)->toBoolean(exec);
+        bool predicateResult = call(exec, function, callType, callData, applyThis, eachArguments)->toBoolean(exec);
 
         if (!predicateResult) {
             result = jsBoolean(false);
@@ -608,14 +651,17 @@ JSValue* arrayProtoFuncEvery(ExecState* exec, JSObject* thisObj, const ArgList&
     return result;
 }
 
-JSValue* arrayProtoFuncForEach(ExecState* exec, JSObject* thisObj, const ArgList& args)
+JSValue* arrayProtoFuncForEach(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
-    JSObject* eachFunction = args[0]->toObject(exec);
+    JSObject* thisObj = thisValue->toThisObject(exec);
 
-    if (!eachFunction->implementsCall())
+    JSValue* function = args[0];
+    CallData callData;
+    CallType callType = function->getCallData(callData);
+    if (callType == CallTypeNone)
         return throwError(exec, TypeError);
 
-    JSObject* applyThis = args[1]->isUndefinedOrNull() ? exec->globalThisValue() :  args[1]->toObject(exec);
+    JSObject* applyThis = args[1]->isUndefinedOrNull() ? exec->globalThisValue() : args[1]->toObject(exec);
 
     unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
     for (unsigned k = 0; k < length && !exec->hadException(); ++k) {
@@ -628,19 +674,22 @@ JSValue* arrayProtoFuncForEach(ExecState* exec, JSObject* thisObj, const ArgList
         eachArguments.append(jsNumber(exec, k));
         eachArguments.append(thisObj);
 
-        eachFunction->callAsFunction(exec, applyThis, eachArguments);
+        call(exec, function, callType, callData, applyThis, eachArguments);
     }
     return jsUndefined();
 }
 
-JSValue* arrayProtoFuncSome(ExecState* exec, JSObject* thisObj, const ArgList& args)
+JSValue* arrayProtoFuncSome(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
-    JSObject* eachFunction = args[0]->toObject(exec);
+    JSObject* thisObj = thisValue->toThisObject(exec);
 
-    if (!eachFunction->implementsCall())
+    JSValue* function = args[0];
+    CallData callData;
+    CallType callType = function->getCallData(callData);
+    if (callType == CallTypeNone)
         return throwError(exec, TypeError);
 
-    JSObject* applyThis = args[1]->isUndefinedOrNull() ? exec->globalThisValue() :  args[1]->toObject(exec);
+    JSObject* applyThis = args[1]->isUndefinedOrNull() ? exec->globalThisValue() : args[1]->toObject(exec);
 
     JSValue* result = jsBoolean(false);
 
@@ -655,7 +704,7 @@ JSValue* arrayProtoFuncSome(ExecState* exec, JSObject* thisObj, const ArgList& a
         eachArguments.append(jsNumber(exec, k));
         eachArguments.append(thisObj);
 
-        bool predicateResult = eachFunction->callAsFunction(exec, applyThis, eachArguments)->toBoolean(exec);
+        bool predicateResult = call(exec, function, callType, callData, applyThis, eachArguments)->toBoolean(exec);
 
         if (predicateResult) {
             result = jsBoolean(true);
@@ -665,11 +714,13 @@ JSValue* arrayProtoFuncSome(ExecState* exec, JSObject* thisObj, const ArgList& a
     return result;
 }
 
-JSValue* arrayProtoFuncIndexOf(ExecState* exec, JSObject* thisObj, const ArgList& args)
+JSValue* arrayProtoFuncIndexOf(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
     // JavaScript 1.5 Extension by Mozilla
     // Documentation: http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:indexOf
 
+    JSObject* thisObj = thisValue->toThisObject(exec);
+
     unsigned index = 0;
     double d = args[1]->toInteger(exec);
     unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
@@ -694,11 +745,13 @@ JSValue* arrayProtoFuncIndexOf(ExecState* exec, JSObject* thisObj, const ArgList
     return jsNumber(exec, -1);
 }
 
-JSValue* arrayProtoFuncLastIndexOf(ExecState* exec, JSObject* thisObj, const ArgList& args)
+JSValue* arrayProtoFuncLastIndexOf(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
     // JavaScript 1.6 Extension by Mozilla
     // Documentation: http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:lastIndexOf
 
+    JSObject* thisObj = thisValue->toThisObject(exec);
+
     unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
     int index = length - 1;
     double d = args[1]->toIntegerPreserveNaN(exec);
@@ -732,16 +785,10 @@ ArrayConstructor::ArrayConstructor(ExecState* exec, FunctionPrototype* funcProto
     putDirect(exec->propertyNames().prototype, arrayProto, DontEnum|DontDelete|ReadOnly);
 
     // no. of arguments for constructor
-    putDirect(exec->propertyNames().length, jsNumber(exec, 1), ReadOnly|DontDelete|DontEnum);
+    putDirect(exec->propertyNames().length, jsNumber(exec, 1), ReadOnly | DontEnum | DontDelete);
 }
 
-ConstructType ArrayConstructor::getConstructData(ConstructData&)
-{
-    return ConstructTypeNative;
-}
-
-// ECMA 15.4.2
-JSObject* ArrayConstructor::construct(ExecState* exec, const ArgList& args)
+static JSObject* constructArrayWithSizeQuirk(ExecState* exec, const ArgList& args)
 {
     // a single numeric argument denotes the array size (!)
     if (args.size() == 1 && args[0]->isNumber()) {
@@ -755,11 +802,29 @@ JSObject* ArrayConstructor::construct(ExecState* exec, const ArgList& args)
     return new (exec) JSArray(exec->lexicalGlobalObject()->arrayPrototype(), args);
 }
 
+static JSObject* constructWithArrayConstructor(ExecState* exec, JSObject*, const ArgList& args)
+{
+    return constructArrayWithSizeQuirk(exec, args);
+}
+
+// ECMA 15.4.2
+ConstructType ArrayConstructor::getConstructData(ConstructData& constructData)
+{
+    constructData.native.function = constructWithArrayConstructor;
+    return ConstructTypeNative;
+}
+
+static JSValue* callArrayConstructor(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+{
+    return constructArrayWithSizeQuirk(exec, args);
+}
+
 // ECMA 15.6.1
-JSValue* ArrayConstructor::callAsFunction(ExecState* exec, JSObject*, const ArgList& args)
+CallType ArrayConstructor::getCallData(CallData& callData)
 {
     // equivalent to 'new Array(....)'
-    return construct(exec, args);
+    callData.native.function = callArrayConstructor;
+    return CallTypeNative;
 }
 
 }
index 1f1819cc1304f23a9973554e4cac5e9374bf0f03..842df715d24ea17df65946143c338cf2a3b75066 100644 (file)
@@ -39,34 +39,10 @@ namespace KJS {
   class ArrayConstructor : public InternalFunction {
   public:
     ArrayConstructor(ExecState*, FunctionPrototype*, ArrayPrototype*);
-
     virtual ConstructType getConstructData(ConstructData&);
-    virtual JSObject* construct(ExecState*, const ArgList&);
-
-    virtual JSValue* callAsFunction(ExecState*, JSObject*, const ArgList&);
-
+    virtual CallType getCallData(CallData&);
   };
 
-  JSValue* arrayProtoFuncToString(ExecState*, JSObject*, const ArgList&);
-  JSValue* arrayProtoFuncToLocaleString(ExecState*, JSObject*, const ArgList&);
-  JSValue* arrayProtoFuncConcat(ExecState*, JSObject*, const ArgList&);
-  JSValue* arrayProtoFuncJoin(ExecState*, JSObject*, const ArgList&);
-  JSValue* arrayProtoFuncPop(ExecState*, JSObject*, const ArgList&);
-  JSValue* arrayProtoFuncPush(ExecState*, JSObject*, const ArgList&);
-  JSValue* arrayProtoFuncReverse(ExecState*, JSObject*, const ArgList&);
-  JSValue* arrayProtoFuncShift(ExecState*, JSObject*, const ArgList&);
-  JSValue* arrayProtoFuncSlice(ExecState*, JSObject*, const ArgList&);
-  JSValue* arrayProtoFuncSort(ExecState*, JSObject*, const ArgList&);
-  JSValue* arrayProtoFuncSplice(ExecState*, JSObject*, const ArgList&);
-  JSValue* arrayProtoFuncUnShift(ExecState*, JSObject*, const ArgList&);
-  JSValue* arrayProtoFuncEvery(ExecState*, JSObject*, const ArgList&);
-  JSValue* arrayProtoFuncForEach(ExecState*, JSObject*, const ArgList&);
-  JSValue* arrayProtoFuncSome(ExecState*, JSObject*, const ArgList&);
-  JSValue* arrayProtoFuncIndexOf(ExecState*, JSObject*, const ArgList&);
-  JSValue* arrayProtoFuncFilter(ExecState*, JSObject*, const ArgList&);
-  JSValue* arrayProtoFuncMap(ExecState*, JSObject*, const ArgList&);
-  JSValue* arrayProtoFuncLastIndexOf(ExecState*, JSObject*, const ArgList&);
-
 } // namespace KJS
 
 #endif // ArrayPrototype_h
index b6b3481466fa673774b5a07688102ca38084483c..d70cb36f0141b6ccf16dee3d0a91d9a53587d4cd 100644 (file)
@@ -40,8 +40,8 @@ BooleanObject::BooleanObject(JSObject* proto)
 // ------------------------------ BooleanPrototype --------------------------
 
 // Functions
-static JSValue* booleanProtoFuncToString(ExecState*, JSObject*, const ArgList&);
-static JSValue* booleanProtoFuncValueOf(ExecState*, JSObject*, const ArgList&);
+static JSValue* booleanProtoFuncToString(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* booleanProtoFuncValueOf(ExecState*, JSObject*, JSValue*, const ArgList&);
 
 // ECMA 15.6.4
 
@@ -59,26 +59,26 @@ BooleanPrototype::BooleanPrototype(ExecState* exec, ObjectPrototype* objectProto
 
 // ECMA 15.6.4.2 + 15.6.4.3
 
-JSValue* booleanProtoFuncToString(ExecState* exec, JSObject* thisObj, const ArgList&)
+JSValue* booleanProtoFuncToString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
 {
-    if (!thisObj->inherits(&BooleanObject::info))
-        return throwError(exec, TypeError);
+    if (JSImmediate::isBoolean(thisValue))
+        return jsString(exec, JSImmediate::toString(thisValue));
 
-    JSValue* v = static_cast<BooleanObject*>(thisObj)->internalValue();
-    ASSERT(v);
+    if (!thisValue->isObject(&BooleanObject::info))
+        return throwError(exec, TypeError);
 
-    return jsString(exec, v->toString(exec));
+    return jsString(exec, JSImmediate::toString(static_cast<BooleanObject*>(thisValue)->internalValue()));
 }
-JSValue* booleanProtoFuncValueOf(ExecState* exec, JSObject* thisObj, const ArgList&)
+
+JSValue* booleanProtoFuncValueOf(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
 {
-    if (!thisObj->inherits(&BooleanObject::info))
-        return throwError(exec, TypeError);
+    if (JSImmediate::isBoolean(thisValue))
+        return thisValue;
 
-    JSValue* v = static_cast<BooleanObject*>(thisObj)->internalValue();
-    ASSERT(v);
+    if (!thisValue->isObject(&BooleanObject::info))
+        return throwError(exec, TypeError);
 
-    // TODO: optimize for bool case
-    return jsBoolean(v->toBoolean(exec));
+    return static_cast<BooleanObject*>(thisValue)->internalValue();
 }
 
 // ------------------------------ BooleanConstructor -----------------------------
@@ -93,24 +93,42 @@ BooleanConstructor::BooleanConstructor(ExecState* exec, FunctionPrototype* funct
     putDirect(exec->propertyNames().length, jsNumber(exec, 1), ReadOnly | DontDelete | DontEnum);
 }
 
-ConstructType BooleanConstructor::getConstructData(ConstructData&)
-{
-    return ConstructTypeNative;
-}
-
 // ECMA 15.6.2
-JSObject* BooleanConstructor::construct(ExecState* exec, const ArgList& args)
+JSObject* constructBoolean(ExecState* exec, const ArgList& args)
 {
-    BooleanObject* obj(new (exec) BooleanObject(exec->lexicalGlobalObject()->booleanPrototype()));
+    BooleanObject* obj = new (exec) BooleanObject(exec->lexicalGlobalObject()->booleanPrototype());
     obj->setInternalValue(jsBoolean(args[0]->toBoolean(exec)));
     return obj;
 }
 
+static JSObject* constructWithBooleanConstructor(ExecState* exec, JSObject*, const ArgList& args)
+{
+    return constructBoolean(exec, args);
+}
+
+ConstructType BooleanConstructor::getConstructData(ConstructData& constructData)
+{
+    constructData.native.function = constructWithBooleanConstructor;
+    return ConstructTypeNative;
+}
+
 // ECMA 15.6.1
-JSValue* BooleanConstructor::callAsFunction(ExecState* exec, JSObject*, const ArgList& args)
+static JSValue* callBooleanConstructor(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
 {
-    // TODO: optimize for bool case
     return jsBoolean(args[0]->toBoolean(exec));
 }
 
+CallType BooleanConstructor::getCallData(CallData& callData)
+{
+    callData.native.function = callBooleanConstructor;
+    return CallTypeNative;
+}
+
+JSObject* constructBooleanFromImmediateBoolean(ExecState* exec, JSValue* immediateBooleanValue)
+{
+    BooleanObject* obj = new (exec) BooleanObject(exec->lexicalGlobalObject()->booleanPrototype());
+    obj->setInternalValue(immediateBooleanValue);
+    return obj;
+}
+
 } // namespace KJS
index 80b6709b1574d08f3fb1b158961c13c9a0bfdd78..ed685456be47d1c09b6a7fa0dea45742a74eb49b 100644 (file)
@@ -53,13 +53,14 @@ namespace KJS {
     class BooleanConstructor : public InternalFunction {
     public:
         BooleanConstructor(ExecState*, FunctionPrototype*, BooleanPrototype*);
-
+    private:
         virtual ConstructType getConstructData(ConstructData&);
-        virtual JSObject* construct(ExecState*, const ArgList&);
-
-        virtual JSValue* callAsFunction(ExecState*, JSObject*, const ArgList&);
+        virtual CallType getCallData(CallData&);
     };
 
+    JSObject* constructBooleanFromImmediateBoolean(ExecState*, JSValue*);
+    JSObject* constructBoolean(ExecState*, const ArgList&);
+
 } // namespace KJS
 
 #endif // BooleanObject_h
index 73486f4ca9147351d326802ebc5eeca613cca616..3986fe75c8bc316023a423fe716b6a8e757b355b 100644 (file)
 
 namespace KJS {
 
+    class ArgList;
+    class ExecState;
     class FunctionBodyNode;
+    class JSObject;
+    class JSValue;
     class ScopeChainNode;
 
     enum CallType {
@@ -40,13 +44,20 @@ namespace KJS {
         CallTypeJS
     };
 
+    typedef JSValue* (*NativeFunction)(ExecState*, JSObject*, JSValue* thisValue, const ArgList&);
+
     union CallData {
+        struct {
+            NativeFunction function;
+        } native;
         struct {
             FunctionBodyNode* functionBody;
             ScopeChainNode* scopeChain;
         } js;
     };
 
+    JSValue* call(ExecState*, JSValue* functionObject, CallType, const CallData&, JSValue* thisValue, const ArgList&);
+
 } // namespace KJS
 
 #endif // CallData_h
index 946350379ef67927fb841e51376f28a851696765..5813d49cfa86c00a6985285257390d0f5d76a014 100644 (file)
 
 namespace KJS {
 
+    class ArgList;
+    class ExecState;
     class FunctionBodyNode;
-    class ScopeChain;
+    class JSObject;
+    class JSValue;
+    class ScopeChainNode;
 
     enum ConstructType {
         ConstructTypeNone,
@@ -40,13 +44,20 @@ namespace KJS {
         ConstructTypeJS
     };
 
+    typedef JSObject* (*NativeConstructor)(ExecState*, JSObject*, const ArgList&);
+
     union ConstructData {
+        struct {
+            NativeConstructor function;
+        } native;
         struct {
             FunctionBodyNode* functionBody;
             ScopeChainNode* scopeChain;
         } js;
     };
 
+    JSObject* construct(ExecState*, JSValue* constructor, ConstructType, const ConstructData&, const ArgList&);
+
 } // namespace KJS
 
 #endif // ConstructData_h
index ab9a5c749206d38f0047fae8f8aeea87511e34cc..6cc42ff49c843bd60c6216c2f42577f684266b38 100644 (file)
@@ -38,9 +38,9 @@ namespace KJS {
 
 // ------------------------------ FunctionPrototype -------------------------
 
-static JSValue* functionProtoFuncToString(ExecState*, JSObject*, const ArgList&);
-static JSValue* functionProtoFuncApply(ExecState*, JSObject*, const ArgList&);
-static JSValue* functionProtoFuncCall(ExecState*, JSObject*, const ArgList&);
+static JSValue* functionProtoFuncToString(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* functionProtoFuncApply(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* functionProtoFuncCall(ExecState*, JSObject*, JSValue*, const ArgList&);
 
 FunctionPrototype::FunctionPrototype(ExecState* exec)
 {
@@ -51,40 +51,46 @@ FunctionPrototype::FunctionPrototype(ExecState* exec)
     putDirectFunction(new (exec) PrototypeFunction(exec, this, 1, exec->propertyNames().call, functionProtoFuncCall), DontEnum);
 }
 
-// ECMA 15.3.4
-JSValue* FunctionPrototype::callAsFunction(ExecState*, JSObject*, const ArgList&)
+static JSValue* callFunctionPrototype(ExecState*, JSObject*, JSValue*, const ArgList&)
 {
     return jsUndefined();
 }
 
+// ECMA 15.3.4
+CallType FunctionPrototype::getCallData(CallData& callData)
+{
+    callData.native.function = callFunctionPrototype;
+    return CallTypeNative;
+}
+
 // Functions
 
-JSValue* functionProtoFuncToString(ExecState* exec, JSObject* thisObj, const ArgList&)
+JSValue* functionProtoFuncToString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
 {
-    if (!thisObj || !thisObj->inherits(&InternalFunction::info)) {
-#ifndef NDEBUG
-        fprintf(stderr,"attempted toString() call on null or non-function object\n");
-#endif
+    if (!thisValue->isObject(&InternalFunction::info))
         return throwError(exec, TypeError);
-    }
 
-    if (thisObj->inherits(&JSFunction::info)) {
-        JSFunction* fi = static_cast<JSFunction*>(thisObj);
+    InternalFunction* function = static_cast<InternalFunction*>(thisValue);
+
+    if (function->inherits(&JSFunction::info)) {
+        JSFunction* fi = static_cast<JSFunction*>(thisValue);
         return jsString(exec, "function " + fi->functionName().ustring() + "(" + fi->body->paramString() + ") " + fi->body->toSourceString());
     }
 
-    return jsString(exec, "function " + static_cast<InternalFunction*>(thisObj)->functionName().ustring() + "() {\n    [native code]\n}");
+    return jsString(exec, "function " + function->functionName().ustring() + "() {\n    [native code]\n}");
 }
 
-JSValue* functionProtoFuncApply(ExecState* exec, JSObject* thisObj, const ArgList& args)
+JSValue* functionProtoFuncApply(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
-    if (!thisObj->implementsCall())
+    CallData callData;
+    CallType callType = thisValue->getCallData(callData);
+    if (callType == CallTypeNone)
         return throwError(exec, TypeError);
 
     JSValue* thisArg = args[0];
     JSValue* argArray = args[1];
 
-    JSObject* applyThis;
+    JSValue* applyThis;
     if (thisArg->isUndefinedOrNull())
         applyThis = exec->globalThisValue();
     else
@@ -104,12 +110,14 @@ JSValue* functionProtoFuncApply(ExecState* exec, JSObject* thisObj, const ArgLis
             return throwError(exec, TypeError);
     }
 
-    return thisObj->callAsFunction(exec, applyThis, applyArgs);
+    return call(exec, thisValue, callType, callData, applyThis, applyArgs);
 }
 
-JSValue* functionProtoFuncCall(ExecState* exec, JSObject* thisObj, const ArgList& args)
+JSValue* functionProtoFuncCall(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
-    if (!thisObj->implementsCall())
+    CallData callData;
+    CallType callType = thisValue->getCallData(callData);
+    if (callType == CallTypeNone)
         return throwError(exec, TypeError);
 
     JSValue* thisArg = args[0];
@@ -122,7 +130,7 @@ JSValue* functionProtoFuncCall(ExecState* exec, JSObject* thisObj, const ArgList
 
     ArgList argsTail;
     args.getSlice(1, argsTail);
-    return thisObj->callAsFunction(exec, callThis, argsTail);
+    return call(exec, thisValue, callType, callData, callThis, argsTail);
 }
 
 // ------------------------------ FunctionConstructor ----------------------------
@@ -136,13 +144,31 @@ FunctionConstructor::FunctionConstructor(ExecState* exec, FunctionPrototype* fun
     putDirect(exec->propertyNames().length, jsNumber(exec, 1), ReadOnly | DontDelete | DontEnum);
 }
 
-ConstructType FunctionConstructor::getConstructData(ConstructData&)
+static JSObject* constructWithFunctionConstructor(ExecState* exec, JSObject*, const ArgList& args)
 {
+    return constructFunction(exec, args);
+}
+
+ConstructType FunctionConstructor::getConstructData(ConstructData& constructData)
+{
+    constructData.native.function = constructWithFunctionConstructor;
     return ConstructTypeNative;
 }
 
+static JSValue* callFunctionConstructor(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+{
+    return constructFunction(exec, args);
+}
+
+// ECMA 15.3.1 The Function Constructor Called as a Function
+CallType FunctionConstructor::getCallData(CallData& callData)
+{
+    callData.native.function = callFunctionConstructor;
+    return CallTypeNative;
+}
+
 // ECMA 15.3.2 The Function Constructor
-JSObject* FunctionConstructor::construct(ExecState* exec, const ArgList& args, const Identifier& functionName, const UString& sourceURL, int lineNumber)
+JSObject* constructFunction(ExecState* exec, const ArgList& args, const Identifier& functionName, const UString& sourceURL, int lineNumber)
 {
     UString p("");
     UString body;
@@ -174,7 +200,7 @@ JSObject* FunctionConstructor::construct(ExecState* exec, const ArgList& args, c
     functionBody->setSource(SourceRange(source, 0, source->length()));
     ScopeChain scopeChain(exec->lexicalGlobalObject(), exec->globalThisValue());
 
-    JSFunction* fimp = new (exec) JSFunction(exec, functionName, functionBody.get(), scopeChain.node());
+    JSFunction* function = new (exec) JSFunction(exec, functionName, functionBody.get(), scopeChain.node());
 
     // parse parameter list. throw syntax error on illegal identifiers
     int len = p.size();
@@ -207,23 +233,16 @@ JSObject* FunctionConstructor::construct(ExecState* exec, const ArgList& args, c
         return throwError(exec, SyntaxError, "Syntax error in parameter list");
     }
   
-    JSObject* objCons = exec->lexicalGlobalObject()->objectConstructor();
-    JSObject* prototype = objCons->construct(exec, exec->emptyList());
-    prototype->putDirect(exec->propertyNames().constructor, fimp, DontEnum);
-    fimp->putDirect(exec->propertyNames().prototype, prototype, DontDelete);
-    return fimp;
+    JSObject* prototype = constructEmptyObject(exec);
+    prototype->putDirect(exec->propertyNames().constructor, function, DontEnum);
+    function->putDirect(exec->propertyNames().prototype, prototype, DontDelete);
+    return function;
 }
 
 // ECMA 15.3.2 The Function Constructor
-JSObject* FunctionConstructor::construct(ExecState* exec, const ArgList& args)
-{
-    return construct(exec, args, Identifier(exec, "anonymous"), UString(), 1);
-}
-
-// ECMA 15.3.1 The Function Constructor Called as a Function
-JSValue* FunctionConstructor::callAsFunction(ExecState* exec, JSObject*, const ArgList& args)
+JSObject* constructFunction(ExecState* exec, const ArgList& args)
 {
-    return construct(exec, args);
+    return constructFunction(exec, args, Identifier(exec, "anonymous"), UString(), 1);
 }
 
 } // namespace KJS
index d66e06de7ae3fb71b2bc6929459d6b74d01e525f..a5e2e1c8b3068618e01cccc7a241ca7aa677ce54 100644 (file)
@@ -37,8 +37,8 @@ namespace KJS {
     class FunctionPrototype : public InternalFunction {
     public:
         FunctionPrototype(ExecState*);
-
-        virtual JSValue* callAsFunction(ExecState*, JSObject*, const ArgList&);
+    private:
+        virtual CallType getCallData(CallData&);
     };
 
     /**
@@ -49,14 +49,14 @@ namespace KJS {
     class FunctionConstructor : public InternalFunction {
     public:
         FunctionConstructor(ExecState*, FunctionPrototype*);
-
+    private:
         virtual ConstructType getConstructData(ConstructData&);
-        virtual JSObject* construct(ExecState*, const ArgList&);
-        virtual JSObject* construct(ExecState*, const ArgList&, const Identifier& functionName, const UString& sourceURL, int lineNumber);
-
-        virtual JSValue* callAsFunction(ExecState*, JSObject*, const ArgList&);
+        virtual CallType getCallData(CallData&);
     };
 
+    JSObject* constructFunction(ExecState*, const ArgList&, const Identifier& functionName, const UString& sourceURL, int lineNumber);
+    JSObject* constructFunction(ExecState*, const ArgList&);
+
 } // namespace KJS
 
 #endif // _FUNCTION_OBJECT_H_
index 8f9e5c38fedc9a84d154e26935c3cf7255d6a0c4..1ceb04ee62d2599d88b9a4375a2bc209d0165373 100644 (file)
@@ -23,6 +23,7 @@
 #include "config.h"
 #include "JSArray.h"
 
+#include "ArrayPrototype.h"
 #include "PropertyNameArray.h"
 #include <wtf/Assertions.h>
 #include <wtf/AVLTree.h>
@@ -557,8 +558,10 @@ struct AVLTreeAbstractorForArrayCompare {
 
     Vector<AVLTreeNodeForArrayCompare> m_nodes;
     ExecState* m_exec;
-    JSObject* m_compareFunction;
-    JSObject* m_globalThisValue;
+    JSValue* m_compareFunction;
+    CallType m_compareCallType;
+    const CallData* m_compareCallData;
+    JSValue* m_globalThisValue;
 
     handle get_less(handle h) { return m_nodes[h].lt & 0x7FFFFFFF; }
     void set_less(handle h, handle lh) { m_nodes[h].lt &= 0x80000000; m_nodes[h].lt |= lh; }
@@ -595,7 +598,7 @@ struct AVLTreeAbstractorForArrayCompare {
         ArgList arguments;
         arguments.append(va);
         arguments.append(vb);
-        double compareResult = m_compareFunction->callAsFunction(m_exec, m_globalThisValue, arguments)->toNumber(m_exec);
+        double compareResult = call(m_exec, m_compareFunction, m_compareCallType, *m_compareCallData, m_globalThisValue, arguments)->toNumber(m_exec);
         return (compareResult < 0) ? -1 : 1; // Not passing equality through, because we need to store all values, even if equivalent.
     }
 
@@ -605,7 +608,7 @@ struct AVLTreeAbstractorForArrayCompare {
     static handle null() { return 0x7FFFFFFF; }
 };
 
-void JSArray::sort(ExecState* exec, JSObject* compareFunction)
+void JSArray::sort(ExecState* exec, JSValue* compareFunction, CallType callType, const CallData& callData)
 {
     checkConsistency();
 
@@ -625,6 +628,8 @@ void JSArray::sort(ExecState* exec, JSObject* compareFunction)
     AVLTree<AVLTreeAbstractorForArrayCompare, 44> tree; // Depth 44 is enough for 2^31 items
     tree.abstractor().m_exec = exec;
     tree.abstractor().m_compareFunction = compareFunction;
+    tree.abstractor().m_compareCallType = callType;
+    tree.abstractor().m_compareCallData = &callData;
     tree.abstractor().m_globalThisValue = exec->globalThisValue();
     tree.abstractor().m_nodes.resize(usedVectorLength + (m_storage->m_sparseValueMap ? m_storage->m_sparseValueMap->size() : 0));
 
@@ -810,4 +815,26 @@ void JSArray::checkConsistency(ConsistencyCheckType type)
 
 #endif
 
+JSArray* constructEmptyArray(ExecState* exec)
+{
+    return new (exec) JSArray(exec->lexicalGlobalObject()->arrayPrototype(), 0);
+}
+
+JSArray* constructEmptyArray(ExecState* exec, unsigned initialLength)
+{
+    return new (exec) JSArray(exec->lexicalGlobalObject()->arrayPrototype(), initialLength);
+}
+
+JSArray* constructArray(ExecState* exec, JSValue* singleItemValue)
+{
+    ArgList values;
+    values.append(singleItemValue);
+    return new (exec) JSArray(exec->lexicalGlobalObject()->arrayPrototype(), values);
+}
+
+JSArray* constructArray(ExecState* exec, const ArgList& values)
+{
+    return new (exec) JSArray(exec->lexicalGlobalObject()->arrayPrototype(), values);
+}
+
 }
index 6124374a4499a901584803679dc6de2a804fc4ef..78779965c135c7e2c86d41e0d082cb18c6129014 100644 (file)
@@ -32,36 +32,39 @@ namespace KJS {
   public:
     JSArray(JSObject* prototype, unsigned initialLength);
     JSArray(JSObject* prototype, const ArgList& initialValues);
-    ~JSArray();
+    virtual ~JSArray();
 
     virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
     virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
-    virtual void put(ExecState*, const Identifier& propertyName, JSValue*);
-    virtual void put(ExecState*, unsigned propertyName, JSValue*);
-    virtual bool deleteProperty(ExecState *, const Identifier& propertyName);
-    virtual bool deleteProperty(ExecState *, unsigned propertyName);
-    virtual void getPropertyNames(ExecState*, PropertyNameArray&);
-
-    virtual void mark();
+    virtual void put(ExecState*, unsigned propertyName, JSValue*); // FIXME: Make protected and add setItem.
 
-    virtual const ClassInfo* classInfo() const { return &info; }
     static const ClassInfo info;
 
     unsigned getLength() const { return m_length; }
+    void setLength(unsigned); // OK to use on new arrays, but not if it might be a RegExpMatchArray.
     JSValue* getItem(unsigned) const;
 
     void sort(ExecState*);
-    void sort(ExecState*, JSObject* compareFunction);
+    void sort(ExecState*, JSValue* compareFunction, CallType, const CallData&);
 
   protected:
+    virtual void put(ExecState*, const Identifier& propertyName, JSValue*);
+    virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
+    virtual bool deleteProperty(ExecState*, unsigned propertyName);
+    virtual void getPropertyNames(ExecState*, PropertyNameArray&);
+    virtual void mark();
+
     void* lazyCreationData();
     void setLazyCreationData(void*);
 
   private:
+    using JSObject::get;
+
+    virtual const ClassInfo* classInfo() const { return &info; }
+
     static JSValue* lengthGetter(ExecState*, const Identifier&, const PropertySlot&);
     bool inlineGetOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
 
-    void setLength(unsigned);
     bool increaseVectorLength(unsigned newLength);
     
     unsigned compactForSorting();
@@ -74,6 +77,11 @@ namespace KJS {
     ArrayStorage* m_storage;
   };
 
+  JSArray* constructEmptyArray(ExecState*);
+  JSArray* constructEmptyArray(ExecState*, unsigned initialLength);
+  JSArray* constructArray(ExecState*, JSValue* singleItemValue);
+  JSArray* constructArray(ExecState*, const ArgList& values);
+
 } // namespace KJS
 
 #endif
index d6f9ffbe64d380487f5f3c64ff9324aff7533068..ee8336eed276a90c6fb101c245c11c03964413a0 100644 (file)
@@ -80,19 +80,19 @@ CallType JSFunction::getCallData(CallData& callData)
     return CallTypeJS;
 }
 
-JSValue* JSFunction::callAsFunction(ExecState* exec, JSObject* thisObj, const ArgList& args)
+JSValue* JSFunction::call(ExecState* exec, JSValue* thisValue, const ArgList& args)
 {
     JSValue* exception = 0;
     RegisterFileStack* stack = &exec->dynamicGlobalObject()->registerFileStack();
     RegisterFile* current = stack->current();
     if (!current->safeForReentry()) {
         stack->pushFunctionRegisterFile();
-        JSValue* result = exec->machine()->execute(body.get(), exec, this, thisObj, args, stack, _scope.node(), &exception);
+        JSValue* result = exec->machine()->execute(body.get(), exec, this, thisValue->toThisObject(exec), args, stack, _scope.node(), &exception);
         stack->popFunctionRegisterFile();
         exec->setException(exception);
         return result;
     } else {
-        JSValue* result = exec->machine()->execute(body.get(), exec, this, thisObj, args, stack, _scope.node(), &exception);
+        JSValue* result = exec->machine()->execute(body.get(), exec, this, thisValue->toThisObject(exec), args, stack, _scope.node(), &exception);
         current->setSafeForReentry(true);
         exec->setException(exception);
         return result;
@@ -158,14 +158,14 @@ bool JSFunction::deleteProperty(ExecState* exec, const Identifier& propertyName)
  * it appears associates with it. eg:
  * function f2(x, x): getParameterName(0) --> null
  */
-Identifier JSFunction::getParameterName(int index)
+const Identifier& JSFunction::getParameterName(int index)
 {
     Vector<Identifier>& parameters = body->parameters();
 
     if (static_cast<size_t>(index) >= body->parameters().size())
         return JSGlobalData::threadInstance().propertyNames->nullIdentifier;
   
-    Identifier name = parameters[index];
+    const Identifier& name = parameters[index];
 
     // Are there any subsequent parameters with the same name?
     size_t size = parameters.size();
@@ -555,10 +555,10 @@ static double parseFloat(const UString& s)
     return s.toDouble( true /*tolerant*/, false /* NaN for empty string */ );
 }
 
-JSValue* globalFuncEval(ExecState* exec, PrototypeReflexiveFunction* function, JSObject* thisObj, const ArgList& args)
+JSValue* globalFuncEval(ExecState* exec, JSObject* function, JSValue* thisValue, const ArgList& args)
 {
-    JSGlobalObject* globalObject = thisObj->toGlobalObject(exec);
-
+    JSObject* thisObject = thisValue->toThisObject(exec);
+    JSGlobalObject* globalObject = thisObject->toGlobalObject(exec);
     if (!globalObject || globalObject->evalFunction() != function)
         return throwError(exec, EvalError, "The \"this\" value passed to eval must be the global object from which eval originated");
 
@@ -578,7 +578,7 @@ JSValue* globalFuncEval(ExecState* exec, PrototypeReflexiveFunction* function, J
         return throwError(exec, SyntaxError, errMsg, errLine, sourceId, NULL);
 
     JSValue* exception = 0;
-    JSValue* value = exec->machine()->execute(evalNode.get(), exec, thisObj, &exec->dynamicGlobalObject()->registerFileStack(), globalObject->globalScopeChain().node(), &exception);
+    JSValue* value = exec->machine()->execute(evalNode.get(), exec, thisObject, &exec->dynamicGlobalObject()->registerFileStack(), globalObject->globalScopeChain().node(), &exception);
 
     if (exception) {
         exec->setException(exception);
@@ -588,28 +588,28 @@ JSValue* globalFuncEval(ExecState* exec, PrototypeReflexiveFunction* function, J
     return value ? value : jsUndefined();
 }
 
-JSValue* globalFuncParseInt(ExecState* exec, JSObject*, const ArgList& args)
+JSValue* globalFuncParseInt(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
 {
     return jsNumber(exec, parseInt(args[0]->toString(exec), args[1]->toInt32(exec)));
 }
 
-JSValue* globalFuncParseFloat(ExecState* exec, JSObject*, const ArgList& args)
+JSValue* globalFuncParseFloat(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
 {
     return jsNumber(exec, parseFloat(args[0]->toString(exec)));
 }
 
-JSValue* globalFuncIsNaN(ExecState* exec, JSObject*, const ArgList& args)
+JSValue* globalFuncIsNaN(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
 {
     return jsBoolean(isnan(args[0]->toNumber(exec)));
 }
 
-JSValue* globalFuncIsFinite(ExecState* exec, JSObject*, const ArgList& args)
+JSValue* globalFuncIsFinite(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
 {
     double n = args[0]->toNumber(exec);
     return jsBoolean(!isnan(n) && !isinf(n));
 }
 
-JSValue* globalFuncDecodeURI(ExecState* exec, JSObject*, const ArgList& args)
+JSValue* globalFuncDecodeURI(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
 {
     static const char do_not_unescape_when_decoding_URI[] =
         "#$&+,/:;=?@";
@@ -617,12 +617,12 @@ JSValue* globalFuncDecodeURI(ExecState* exec, JSObject*, const ArgList& args)
     return decode(exec, args, do_not_unescape_when_decoding_URI, true);
 }
 
-JSValue* globalFuncDecodeURIComponent(ExecState* exec, JSObject*, const ArgList& args)
+JSValue* globalFuncDecodeURIComponent(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
 {
     return decode(exec, args, "", true);
 }
 
-JSValue* globalFuncEncodeURI(ExecState* exec, JSObject*, const ArgList& args)
+JSValue* globalFuncEncodeURI(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
 {
     static const char do_not_escape_when_encoding_URI[] =
         "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
@@ -633,7 +633,7 @@ JSValue* globalFuncEncodeURI(ExecState* exec, JSObject*, const ArgList& args)
     return encode(exec, args, do_not_escape_when_encoding_URI);
 }
 
-JSValue* globalFuncEncodeURIComponent(ExecState* exec, JSObject*, const ArgList& args)
+JSValue* globalFuncEncodeURIComponent(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
 {
     static const char do_not_escape_when_encoding_URI_component[] =
         "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
@@ -644,7 +644,7 @@ JSValue* globalFuncEncodeURIComponent(ExecState* exec, JSObject*, const ArgList&
     return encode(exec, args, do_not_escape_when_encoding_URI_component);
 }
 
-JSValue* globalFuncEscape(ExecState* exec, JSObject*, const ArgList& args)
+JSValue* globalFuncEscape(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
 {
     static const char do_not_escape[] =
         "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
@@ -673,7 +673,7 @@ JSValue* globalFuncEscape(ExecState* exec, JSObject*, const ArgList& args)
     return jsString(exec, r);
 }
 
-JSValue* globalFuncUnescape(ExecState* exec, JSObject*, const ArgList& args)
+JSValue* globalFuncUnescape(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
 {
     UString s = "", str = args[0]->toString(exec);
     int k = 0, len = str.size();
@@ -699,7 +699,7 @@ JSValue* globalFuncUnescape(ExecState* exec, JSObject*, const ArgList& args)
 }
 
 #ifndef NDEBUG
-JSValue* globalFuncKJSPrint(ExecState* exec, JSObject*, const ArgList& args)
+JSValue* globalFuncKJSPrint(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
 {
     CStringBuffer string;
     args[0]->toString(exec).getCString(string);
@@ -710,7 +710,7 @@ JSValue* globalFuncKJSPrint(ExecState* exec, JSObject*, const ArgList& args)
 
 // ------------------------------ PrototypeFunction -------------------------------
 
-PrototypeFunction::PrototypeFunction(ExecState* exec, int len, const Identifier& name, JSMemberFunction function)
+PrototypeFunction::PrototypeFunction(ExecState* exec, int len, const Identifier& name, NativeFunction function)
     : InternalFunction(exec->lexicalGlobalObject()->functionPrototype(), name)
     , m_function(function)
 {
@@ -718,7 +718,7 @@ PrototypeFunction::PrototypeFunction(ExecState* exec, int len, const Identifier&
     putDirect(exec->propertyNames().length, jsNumber(exec, len), DontDelete | ReadOnly | DontEnum);
 }
 
-PrototypeFunction::PrototypeFunction(ExecState* exec, FunctionPrototype* functionPrototype, int len, const Identifier& name, JSMemberFunction function)
+PrototypeFunction::PrototypeFunction(ExecState* exec, FunctionPrototype* functionPrototype, int len, const Identifier& name, NativeFunction function)
     : InternalFunction(functionPrototype, name)
     , m_function(function)
 {
@@ -726,31 +726,24 @@ PrototypeFunction::PrototypeFunction(ExecState* exec, FunctionPrototype* functio
     putDirect(exec->propertyNames().length, jsNumber(exec, len), DontDelete | ReadOnly | DontEnum);
 }
 
-JSValue* PrototypeFunction::callAsFunction(ExecState* exec, JSObject* thisObj, const ArgList& args)
+CallType PrototypeFunction::getCallData(CallData& callData)
 {
-    return m_function(exec, thisObj, args);
+    callData.native.function = m_function;
+    return CallTypeNative;
 }
 
 // ------------------------------ PrototypeReflexiveFunction -------------------------------
 
-PrototypeReflexiveFunction::PrototypeReflexiveFunction(ExecState* exec, FunctionPrototype* functionPrototype, int len, const Identifier& name, JSMemberFunction function, JSGlobalObject* cachedGlobalObject)
-    : InternalFunction(functionPrototype, name)
-    , m_function(function)
+GlobalEvalFunction::GlobalEvalFunction(ExecState* exec, FunctionPrototype* functionPrototype, int len, const Identifier& name, NativeFunction function, JSGlobalObject* cachedGlobalObject)
+    : PrototypeFunction(exec, functionPrototype, len, name, function)
     , m_cachedGlobalObject(cachedGlobalObject)
 {
-    ASSERT_ARG(function, function);
     ASSERT_ARG(cachedGlobalObject, cachedGlobalObject);
-    putDirect(exec->propertyNames().length, jsNumber(exec, len), DontDelete | ReadOnly | DontEnum);
 }
 
-JSValue* PrototypeReflexiveFunction::callAsFunction(ExecState* exec, JSObject* thisObj, const ArgList& args)
+void GlobalEvalFunction::mark()
 {
-    return m_function(exec, this, thisObj, args);
-}
-
-void PrototypeReflexiveFunction::mark()
-{
-    InternalFunction::mark();
+    PrototypeFunction::mark();
     if (!m_cachedGlobalObject->marked())
         m_cachedGlobalObject->mark();
 }
index 68aae0526ba86d2c088c5f85d260fb9187236951..567cf1636ad0a317fc159f9001a63ccaee6ee33f 100644 (file)
@@ -39,19 +39,18 @@ namespace KJS {
 
   class InternalFunction : public JSObject {
   public:
+    static const ClassInfo info;
+    virtual const ClassInfo* classInfo() const { return &info; }
+    const Identifier& functionName() const { return m_name; }
+
+  protected:
     InternalFunction();
     InternalFunction(FunctionPrototype*, const Identifier&);
 
-    virtual CallType getCallData(CallData&);
-
-    virtual JSValue* callAsFunction(ExecState*, JSObject* thisObjec, const ArgList& args) = 0;
+  private:
+    virtual CallType getCallData(CallData&) = 0;
     virtual bool implementsHasInstance() const;
 
-    virtual const ClassInfo* classInfo() const { return &info; }
-    static const ClassInfo info;
-    const Identifier& functionName() const { return m_name; }
-
-  private:
     Identifier m_name;
   };
 
@@ -63,17 +62,13 @@ namespace KJS {
     virtual void put(ExecState*, const Identifier& propertyName, JSValue*);
     virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
 
-    virtual ConstructType getConstructData(ConstructData&);
-    virtual JSObject* construct(ExecState*, const ArgList& args);
-
-    virtual CallType getCallData(CallData&);
-    virtual JSValue* callAsFunction(ExecState*, JSObject* thisObj, const ArgList& args);
+    JSObject* construct(ExecState*, const ArgList&);
+    JSValue* call(ExecState*, JSValue* thisValue, const ArgList&);
 
-    // Note: unlike body->paramName, this returns Identifier::null for parameters 
-    // that will never get set, due to later param having the same name
-    Identifier getParameterName(int index);
+    // Note: Returns a null identifier for any parameters that will never get set
+    // due to a later parameter with the same name.
+    const Identifier& getParameterName(int index);
 
-    virtual const ClassInfo* classInfo() const { return &info; }
     static const ClassInfo info;
 
     RefPtr<FunctionBodyNode> body;
@@ -84,6 +79,10 @@ namespace KJS {
     virtual void mark();
 
   private:
+    virtual const ClassInfo* classInfo() const { return &info; }
+    virtual ConstructType getConstructData(ConstructData&);
+    virtual CallType getCallData(CallData&);
+
     ScopeChain _scope;
 
     static JSValue* argumentsGetter(ExecState*, const Identifier&, const PropertySlot&);
@@ -93,7 +92,7 @@ namespace KJS {
 
   class IndexToNameMap {
   public:
-    IndexToNameMap(JSFunction*, const ArgList& args);
+    IndexToNameMap(JSFunction*, const ArgList&);
     ~IndexToNameMap();
     
     Identifier& operator[](const Identifier& index);
@@ -123,49 +122,40 @@ namespace KJS {
 
   class PrototypeFunction : public InternalFunction {
   public:
-    typedef JSValue* (*JSMemberFunction)(ExecState*, JSObject* thisObj, const ArgList&);
-
-    PrototypeFunction(ExecState*, int len, const Identifier&, JSMemberFunction);
-    PrototypeFunction(ExecState*, FunctionPrototype*, int len, const Identifier&, JSMemberFunction);
-
-    virtual JSValue* callAsFunction(ExecState* exec, JSObject* thisObj, const ArgList&);
+    PrototypeFunction(ExecState*, int len, const Identifier&, NativeFunction);
+    PrototypeFunction(ExecState*, FunctionPrototype*, int len, const Identifier&, NativeFunction);
 
   private:
-    const JSMemberFunction m_function;
-  };
-
+    virtual CallType getCallData(CallData&);
 
-  // Just like PrototypeFunction, but callbacks also get passed the JS function object.
-  class PrototypeReflexiveFunction : public InternalFunction {
-  public:
-    typedef JSValue* (*JSMemberFunction)(ExecState*, PrototypeReflexiveFunction*, JSObject* thisObj, const ArgList&);
+    const NativeFunction m_function;
+  };
 
-    PrototypeReflexiveFunction(ExecState*, FunctionPrototype*, int len, const Identifier&, JSMemberFunction, JSGlobalObject* expectedThisObject);
+    class GlobalEvalFunction : public PrototypeFunction {
+    public:
+        GlobalEvalFunction(ExecState*, FunctionPrototype*, int len, const Identifier&, NativeFunction, JSGlobalObject* expectedThisObject);
+        JSGlobalObject* cachedGlobalObject() const { return m_cachedGlobalObject; }
 
-    virtual void mark();
-    virtual JSValue* callAsFunction(ExecState* exec, JSObject* thisObj, const ArgList&);
+    private:
+        virtual void mark();
 
-    JSGlobalObject* cachedGlobalObject() const { return m_cachedGlobalObject; }
-
-  private:
-    const JSMemberFunction m_function;
-    JSGlobalObject* m_cachedGlobalObject;
-  };
+        JSGlobalObject* m_cachedGlobalObject;
+    };
 
     // Global Functions
-    JSValue* globalFuncEval(ExecState*, PrototypeReflexiveFunction*, JSObject*, const ArgList&);
-    JSValue* globalFuncParseInt(ExecState*, JSObject*, const ArgList&);
-    JSValue* globalFuncParseFloat(ExecState*, JSObject*, const ArgList&);
-    JSValue* globalFuncIsNaN(ExecState*, JSObject*, const ArgList&);
-    JSValue* globalFuncIsFinite(ExecState*, JSObject*, const ArgList&);
-    JSValue* globalFuncDecodeURI(ExecState*, JSObject*, const ArgList&);
-    JSValue* globalFuncDecodeURIComponent(ExecState*, JSObject*, const ArgList&);
-    JSValue* globalFuncEncodeURI(ExecState*, JSObject*, const ArgList&);
-    JSValue* globalFuncEncodeURIComponent(ExecState*, JSObject*, const ArgList&);
-    JSValue* globalFuncEscape(ExecState*, JSObject*, const ArgList&);
-    JSValue* globalFuncUnescape(ExecState*, JSObject*, const ArgList&);
+    JSValue* globalFuncEval(ExecState*, JSObject*, JSValue*, const ArgList&);
+    JSValue* globalFuncParseInt(ExecState*, JSObject*, JSValue*, const ArgList&);
+    JSValue* globalFuncParseFloat(ExecState*, JSObject*, JSValue*, const ArgList&);
+    JSValue* globalFuncIsNaN(ExecState*, JSObject*, JSValue*, const ArgList&);
+    JSValue* globalFuncIsFinite(ExecState*, JSObject*, JSValue*, const ArgList&);
+    JSValue* globalFuncDecodeURI(ExecState*, JSObject*, JSValue*, const ArgList&);
+    JSValue* globalFuncDecodeURIComponent(ExecState*, JSObject*, JSValue*, const ArgList&);
+    JSValue* globalFuncEncodeURI(ExecState*, JSObject*, JSValue*, const ArgList&);
+    JSValue* globalFuncEncodeURIComponent(ExecState*, JSObject*, JSValue*, const ArgList&);
+    JSValue* globalFuncEscape(ExecState*, JSObject*, JSValue*, const ArgList&);
+    JSValue* globalFuncUnescape(ExecState*, JSObject*, JSValue*, const ArgList&);
 #ifndef NDEBUG
-    JSValue* globalFuncKJSPrint(ExecState*, JSObject*, const ArgList&);
+    JSValue* globalFuncKJSPrint(ExecState*, JSObject*, JSValue*, const ArgList&);
 #endif
 
     static const double mantissaOverflowLowerBound = 9007199254740992.0;
index f97cbcc98e88cef282e2137ba152dd8f9466df8e..3077ca4193e2d1ef4baa8c75681bab082b0cd3bf 100644 (file)
@@ -212,13 +212,6 @@ void JSGlobalObject::reset(JSValue* prototype)
     d()->URIErrorPrototype = 0;
 
     // Constructors
-    d()->objectConstructor = 0;
-    d()->functionConstructor = 0;
-    d()->arrayConstructor = 0;
-    d()->stringConstructor = 0;
-    d()->booleanConstructor = 0;
-    d()->numberConstructor = 0;
-    d()->dateConstructor = 0;
     d()->regExpConstructor = 0;
     d()->errorConstructor = 0;
     
@@ -234,6 +227,7 @@ void JSGlobalObject::reset(JSValue* prototype)
     ExecState* exec = d()->globalExec.get();
 
     // Prototypes
+
     d()->functionPrototype = new (exec) FunctionPrototype(exec);
     d()->objectPrototype = new (exec) ObjectPrototype(exec, d()->functionPrototype);
     d()->functionPrototype->setPrototype(d()->objectPrototype);
@@ -254,14 +248,17 @@ void JSGlobalObject::reset(JSValue* prototype)
     d()->URIErrorPrototype = new (exec) NativeErrorPrototype(exec, d()->errorPrototype, "URIError", "URIError");
 
     // Constructors
-    d()->objectConstructor = new (exec) ObjectConstructor(exec, d()->objectPrototype, d()->functionPrototype);
-    d()->functionConstructor = new (exec) FunctionConstructor(exec, d()->functionPrototype);
-    d()->arrayConstructor = new (exec) ArrayConstructor(exec, d()->functionPrototype, d()->arrayPrototype);
-    d()->stringConstructor = new (exec) StringConstructor(exec, d()->functionPrototype, d()->stringPrototype);
-    d()->booleanConstructor = new (exec) BooleanConstructor(exec, d()->functionPrototype, d()->booleanPrototype);
-    d()->numberConstructor = new (exec) NumberConstructor(exec, d()->functionPrototype, d()->numberPrototype);
-    d()->dateConstructor = new (exec) DateConstructor(exec, d()->functionPrototype, d()->datePrototype);
+
+    JSValue* objectConstructor = new (exec) ObjectConstructor(exec, d()->objectPrototype, d()->functionPrototype);
+    JSValue* functionConstructor = new (exec) FunctionConstructor(exec, d()->functionPrototype);
+    JSValue* arrayConstructor = new (exec) ArrayConstructor(exec, d()->functionPrototype, d()->arrayPrototype);
+    JSValue* stringConstructor = new (exec) StringConstructor(exec, d()->functionPrototype, d()->stringPrototype);
+    JSValue* booleanConstructor = new (exec) BooleanConstructor(exec, d()->functionPrototype, d()->booleanPrototype);
+    JSValue* numberConstructor = new (exec) NumberConstructor(exec, d()->functionPrototype, d()->numberPrototype);
+    JSValue* dateConstructor = new (exec) DateConstructor(exec, d()->functionPrototype, d()->datePrototype);
+
     d()->regExpConstructor = new (exec) RegExpConstructor(exec, d()->functionPrototype, d()->regExpPrototype);
+
     d()->errorConstructor = new (exec) ErrorConstructor(exec, d()->functionPrototype, d()->errorPrototype);
     
     d()->evalErrorConstructor = new (exec) NativeErrorConstructor(exec, d()->functionPrototype, d()->evalErrorPrototype);
@@ -271,15 +268,15 @@ void JSGlobalObject::reset(JSValue* prototype)
     d()->typeErrorConstructor = new (exec) NativeErrorConstructor(exec, d()->functionPrototype, d()->typeErrorPrototype);
     d()->URIErrorConstructor = new (exec) NativeErrorConstructor(exec, d()->functionPrototype, d()->URIErrorPrototype);
     
-    d()->functionPrototype->putDirect(exec->propertyNames().constructor, d()->functionConstructor, DontEnum);
-
-    d()->objectPrototype->putDirect(exec->propertyNames().constructor, d()->objectConstructor, DontEnum);
-    d()->functionPrototype->putDirect(exec->propertyNames().constructor, d()->functionConstructor, DontEnum);
-    d()->arrayPrototype->putDirect(exec->propertyNames().constructor, d()->arrayConstructor, DontEnum);
-    d()->booleanPrototype->putDirect(exec->propertyNames().constructor, d()->booleanConstructor, DontEnum);
-    d()->stringPrototype->putDirect(exec->propertyNames().constructor, d()->stringConstructor, DontEnum);
-    d()->numberPrototype->putDirect(exec->propertyNames().constructor, d()->numberConstructor, DontEnum);
-    d()->datePrototype->putDirect(exec->propertyNames().constructor, d()->dateConstructor, DontEnum);
+    d()->functionPrototype->putDirect(exec->propertyNames().constructor, functionConstructor, DontEnum);
+
+    d()->objectPrototype->putDirect(exec->propertyNames().constructor, objectConstructor, DontEnum);
+    d()->functionPrototype->putDirect(exec->propertyNames().constructor, functionConstructor, DontEnum);
+    d()->arrayPrototype->putDirect(exec->propertyNames().constructor, arrayConstructor, DontEnum);
+    d()->booleanPrototype->putDirect(exec->propertyNames().constructor, booleanConstructor, DontEnum);
+    d()->stringPrototype->putDirect(exec->propertyNames().constructor, stringConstructor, DontEnum);
+    d()->numberPrototype->putDirect(exec->propertyNames().constructor, numberConstructor, DontEnum);
+    d()->datePrototype->putDirect(exec->propertyNames().constructor, dateConstructor, DontEnum);
     d()->regExpPrototype->putDirect(exec->propertyNames().constructor, d()->regExpConstructor, DontEnum);
     d()->errorPrototype->putDirect(exec->propertyNames().constructor, d()->errorConstructor, DontEnum);
     d()->evalErrorPrototype->putDirect(exec->propertyNames().constructor, d()->evalErrorConstructor, DontEnum);
@@ -293,13 +290,13 @@ void JSGlobalObject::reset(JSValue* prototype)
 
     // FIXME: These properties could be handled by a static hash table.
 
-    putDirect(Identifier(exec, "Object"), d()->objectConstructor, DontEnum);
-    putDirect(Identifier(exec, "Function"), d()->functionConstructor, DontEnum);
-    putDirect(Identifier(exec, "Array"), d()->arrayConstructor, DontEnum);
-    putDirect(Identifier(exec, "Boolean"), d()->booleanConstructor, DontEnum);
-    putDirect(Identifier(exec, "String"), d()->stringConstructor, DontEnum);
-    putDirect(Identifier(exec, "Number"), d()->numberConstructor, DontEnum);
-    putDirect(Identifier(exec, "Date"), d()->dateConstructor, DontEnum);
+    putDirect(Identifier(exec, "Object"), objectConstructor, DontEnum);
+    putDirect(Identifier(exec, "Function"), functionConstructor, DontEnum);
+    putDirect(Identifier(exec, "Array"), arrayConstructor, DontEnum);
+    putDirect(Identifier(exec, "Boolean"), booleanConstructor, DontEnum);
+    putDirect(Identifier(exec, "String"), stringConstructor, DontEnum);
+    putDirect(Identifier(exec, "Number"), numberConstructor, DontEnum);
+    putDirect(Identifier(exec, "Date"), dateConstructor, DontEnum);
     putDirect(Identifier(exec, "RegExp"), d()->regExpConstructor, DontEnum);
     putDirect(Identifier(exec, "Error"), d()->errorConstructor, DontEnum);
     putDirect(Identifier(exec, "EvalError"), d()->evalErrorConstructor);
@@ -321,7 +318,7 @@ void JSGlobalObject::reset(JSValue* prototype)
 
     // Set global functions.
 
-    d()->evalFunction = new (exec) PrototypeReflexiveFunction(exec, d()->functionPrototype, 1, exec->propertyNames().eval, globalFuncEval, this);
+    d()->evalFunction = new (exec) GlobalEvalFunction(exec, d()->functionPrototype, 1, exec->propertyNames().eval, globalFuncEval, this);
     putDirectFunction(d()->evalFunction, DontEnum);
     putDirectFunction(new (exec) PrototypeFunction(exec, d()->functionPrototype, 2, Identifier(exec, "parseInt"), globalFuncParseInt), DontEnum);
     putDirectFunction(new (exec) PrototypeFunction(exec, d()->functionPrototype, 1, Identifier(exec, "parseFloat"), globalFuncParseFloat), DontEnum);
@@ -415,13 +412,6 @@ void JSGlobalObject::mark()
 
     markIfNeeded(d()->globalExec->exception());
 
-    markIfNeeded(d()->objectConstructor);
-    markIfNeeded(d()->functionConstructor);
-    markIfNeeded(d()->arrayConstructor);
-    markIfNeeded(d()->booleanConstructor);
-    markIfNeeded(d()->stringConstructor);
-    markIfNeeded(d()->numberConstructor);
-    markIfNeeded(d()->dateConstructor);
     markIfNeeded(d()->regExpConstructor);
     markIfNeeded(d()->errorConstructor);
     markIfNeeded(d()->evalErrorConstructor);
index 3dbca285f0ce8b7108e00a444937b63140d9314d..7eb83b921d9b389802fde5bda756ddc2edaff07d 100644 (file)
 
 namespace KJS {
 
-    class ArrayConstructor;
     class ArrayPrototype;
-    class BooleanConstructor;
     class BooleanPrototype;
-    class DateConstructor;
     class DatePrototype;
     class Debugger;
     class ErrorConstructor;
     class ErrorPrototype;
     class EvalError;
     class EvalErrorPrototype;
-    class FunctionConstructor;
     class FunctionPrototype;
-    struct HashTable;
+    class GlobalEvalFunction;
     class JSGlobalObject;
     class NativeErrorConstructor;
     class NativeErrorPrototype;
-    class NumberConstructor;
     class NumberPrototype;
-    class ObjectConstructor;
     class ObjectPrototype;
     class ProgramCodeBlock;
-    class PrototypeReflexiveFunction;
     class RangeError;
     class RangeErrorPrototype;
     class ReferenceError;
@@ -64,14 +57,15 @@ namespace KJS {
     class RegExpPrototype;
     class RuntimeMethod;
     class ScopeChain;
-    class StringConstructor;
     class StringPrototype;
     class SyntaxErrorPrototype;
     class TypeError;
     class TypeErrorPrototype;
     class UriError;
     class UriErrorPrototype;
+
     struct ActivationStackNode;
+    struct HashTable;
 
     typedef Vector<ExecState*, 16> ExecStateStack;
 
@@ -104,13 +98,6 @@ namespace KJS {
             unsigned tickCount;
             unsigned ticksUntilNextTimeoutCheck;
 
-            ObjectConstructor* objectConstructor;
-            FunctionConstructor* functionConstructor;
-            ArrayConstructor* arrayConstructor;
-            BooleanConstructor* booleanConstructor;
-            StringConstructor* stringConstructor;
-            NumberConstructor* numberConstructor;
-            DateConstructor* dateConstructor;
             RegExpConstructor* regExpConstructor;
             ErrorConstructor* errorConstructor;
             NativeErrorConstructor* evalErrorConstructor;
@@ -120,7 +107,7 @@ namespace KJS {
             NativeErrorConstructor* typeErrorConstructor;
             NativeErrorConstructor* URIErrorConstructor;
 
-            PrototypeReflexiveFunction* evalFunction;
+            GlobalEvalFunction* evalFunction;
 
             ObjectPrototype* objectPrototype;
             FunctionPrototype* functionPrototype;
@@ -156,8 +143,8 @@ namespace KJS {
         }
 
     protected:
-        JSGlobalObject(JSValue* proto, JSObject* globalThisValue)
-            : JSVariableObject(proto, new JSGlobalObjectData(this, globalThisValue))
+        JSGlobalObject(JSValue* prototype, JSObject* globalThisValue)
+            : JSVariableObject(prototype, new JSGlobalObjectData(this, globalThisValue))
         {
             init(globalThisValue);
         }
@@ -186,14 +173,8 @@ namespace KJS {
         // The following accessors return pristine values, even if a script 
         // replaces the global object's associated property.
 
-        ObjectConstructor* objectConstructor() const { return d()->objectConstructor; }
-        FunctionConstructor* functionConstructor() const { return d()->functionConstructor; }
-        ArrayConstructor* arrayConstructor() const { return d()->arrayConstructor; }
-        BooleanConstructor* booleanConstructor() const { return d()->booleanConstructor; }
-        StringConstructor* stringConstructor() const{ return d()->stringConstructor; }
-        NumberConstructor* numberConstructor() const{ return d()->numberConstructor; }
-        DateConstructor* dateConstructor() const{ return d()->dateConstructor; }
         RegExpConstructor* regExpConstructor() const { return d()->regExpConstructor; }
+
         ErrorConstructor* errorConstructor() const { return d()->errorConstructor; }
         NativeErrorConstructor* evalErrorConstructor() const { return d()->evalErrorConstructor; }
         NativeErrorConstructor* rangeErrorConstructor() const { return d()->rangeErrorConstructor; }
@@ -202,7 +183,7 @@ namespace KJS {
         NativeErrorConstructor* typeErrorConstructor() const { return d()->typeErrorConstructor; }
         NativeErrorConstructor* URIErrorConstructor() const { return d()->URIErrorConstructor; }
 
-        PrototypeReflexiveFunction* evalFunction() const { return d()->evalFunction; }
+        GlobalEvalFunction* evalFunction() const { return d()->evalFunction; }
 
         ObjectPrototype* objectPrototype() const { return d()->objectPrototype; }
         FunctionPrototype* functionPrototype() const { return d()->functionPrototype; }
index abc579d0cb64306a5a86c42be53d0463f9ee1e1f..4270fe58a253f81166b9ac2de60444098d86f6d7 100644 (file)
 
 namespace KJS {
 
-JSObject *JSImmediate::toObject(const JSValue *v, ExecState *exec)
+JSObjectJSImmediate::toObject(const JSValue *v, ExecState *exec)
 {
     ASSERT(isImmediate(v));
     if (v == jsNull())
         return new (exec) JSNotAnObject(throwError(exec, TypeError, "Null value"));
-    else if (v == jsUndefined())
+    if (v == jsUndefined())
         return new (exec) JSNotAnObject(throwError(exec, TypeError, "Undefined value"));
-    else if (isBoolean(v)) {
-        ArgList args;
-        args.append(const_cast<JSValue *>(v));
-        return exec->lexicalGlobalObject()->booleanConstructor()->construct(exec, args);
-    } else {
-        ASSERT(isNumber(v));
-        ArgList args;
-        args.append(const_cast<JSValue *>(v));
-        return exec->lexicalGlobalObject()->numberConstructor()->construct(exec, args);
-    }
+    if (isBoolean(v))
+        return constructBooleanFromImmediateBoolean(exec, const_cast<JSValue*>(v));
+    ASSERT(isNumber(v));
+    return constructNumberFromImmediateNumber(exec, const_cast<JSValue*>(v));
 }
 
 UString JSImmediate::toString(const JSValue* v)
index dc4eeec660cf59a25ddb9cb28ed0ea1584ff7524..4934d49a44aec426546d1c23c60447698d2c313b 100644 (file)
@@ -126,34 +126,6 @@ bool JSNotAnObject::deleteProperty(ExecState* exec, unsigned)
     return false;
 }
 
-JSValue* JSNotAnObject::defaultValue(ExecState* exec, JSType) const
-{
-    UNUSED_PARAM(exec);
-    ASSERT(exec->hadException() && exec->exception() == m_exception);
-    return m_exception;
-}
-
-JSObject* JSNotAnObject::construct(ExecState* exec, const ArgList&)
-{
-    UNUSED_PARAM(exec);
-    ASSERT(exec->hadException() && exec->exception() == m_exception);
-    return m_exception;
-}
-
-JSObject* JSNotAnObject::construct(ExecState* exec, const ArgList&, const Identifier&, const UString&, int)
-{
-    UNUSED_PARAM(exec);
-    ASSERT(exec->hadException() && exec->exception() == m_exception);
-    return m_exception;
-}
-
-JSValue* JSNotAnObject::callAsFunction(ExecState* exec, JSObject*, const ArgList&)
-{
-    UNUSED_PARAM(exec);
-    ASSERT(exec->hadException() && exec->exception() == m_exception);
-    return m_exception;
-}
-
 void JSNotAnObject::getPropertyNames(ExecState* exec, PropertyNameArray&)
 {
     UNUSED_PARAM(exec);
index 0ddf97d538d5fd1ec7392bb3a669f2b5bf38b5fe..3abd83f33e2eb789037c00b57fa2b2855604399e 100644 (file)
@@ -43,7 +43,8 @@ namespace KJS {
         {
         }
 
-        // JSValue methods
+     private:
+       // JSValue methods
         virtual JSValue* toPrimitive(ExecState*, JSType preferredType = UnspecifiedType) const;
         virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue*&);
         virtual bool toBoolean(ExecState*) const;
@@ -64,16 +65,8 @@ namespace KJS {
         virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
         virtual bool deleteProperty(ExecState*, unsigned propertyName);
 
-        virtual JSValue* defaultValue(ExecState*, JSType hint) const;
-
-        virtual JSObject* construct(ExecState*, const ArgList&);
-        virtual JSObject* construct(ExecState*, const ArgList&, const Identifier& functionName, const UString& sourceURL, int lineNumber);
-
-        virtual JSValue* callAsFunction(ExecState*, JSObject* thisObj, const ArgList&);
-
         virtual void getPropertyNames(ExecState*, PropertyNameArray&);
 
-    private:
         JSObject* m_exception;
     };
 
index c55873af5fdcaaeda2b1bfb566837b99950907ee..5f936935cebd0826ed01530f91ad5df6733c6c9e 100644 (file)
@@ -69,11 +69,6 @@ JSType JSObject::type() const
   return ObjectType;
 }
 
-const ClassInfo *JSObject::classInfo() const
-{
-  return 0;
-}
-
 UString JSObject::className() const
 {
   const ClassInfo *ci = classInfo();
@@ -93,7 +88,7 @@ static void throwSetterError(ExecState *exec)
 }
 
 // ECMA 8.6.2.2
-void JSObject::put(ExecState* exec, const Identifier &propertyName, JSValue *value)
+void JSObject::put(ExecState* exec, const Identifier& propertyName, JSValue* value)
 {
   ASSERT(value);
   ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
@@ -101,7 +96,7 @@ void JSObject::put(ExecState* exec, const Identifier &propertyName, JSValue *val
   if (propertyName == exec->propertyNames().underscoreProto) {
     JSObject* proto = value->getObject();
 
-    // Setting __proto__ to a non-object, non-null value is silently ignored to match Mozilla
+    // Setting __proto__ to a non-object, non-null value is silently ignored to match Mozilla.
     if (!proto && value != jsNull())
       return;
 
@@ -112,61 +107,53 @@ void JSObject::put(ExecState* exec, const Identifier &propertyName, JSValue *val
       }
       proto = proto->prototype() ? proto->prototype()->getObject() : 0;
     }
-    
+
     setPrototype(value);
     return;
   }
 
   // Check if there are any setters or getters in the prototype chain
-  JSObject *obj = this;
-  bool hasGettersOrSetters = false;
-  while (true) {
-    if (obj->_prop.hasGetterSetterProperties()) {
-      hasGettersOrSetters = true;
-      break;
+  JSObject* obj;
+  JSValue* prototype;
+  for (obj = this; !obj->_prop.hasGetterSetterProperties(); obj = static_cast<JSObject*>(prototype)) {
+    prototype = obj->_proto;
+    if (prototype == jsNull()) {
+      _prop.put(propertyName, value, 0, true);
+      return;
     }
-      
-    if (obj->_proto == jsNull())
-      break;
-      
-    obj = static_cast<JSObject *>(obj->_proto);
   }
-  
-  if (hasGettersOrSetters) {
-    unsigned attributes;
-    if (_prop.get(propertyName, attributes) && attributes & ReadOnly)
-        return;
 
-    obj = this;
-    while (true) {
-      if (JSValue *gs = obj->_prop.get(propertyName, attributes)) {
-        if (attributes & IsGetterSetter) {
-          JSObject *setterFunc = static_cast<GetterSetter *>(gs)->getSetter();
-        
-          if (!setterFunc) {
-            throwSetterError(exec);
-            return;
-          }
-            
-          ArgList args;
-          args.append(value);
-        
-          setterFunc->callAsFunction(exec, this->toThisObject(exec), args);
+  unsigned attributes;
+  if (_prop.get(propertyName, attributes) && attributes & ReadOnly)
+    return;
+
+  for (; ; obj = static_cast<JSObject*>(prototype)) {
+    if (JSValue* gs = obj->_prop.get(propertyName, attributes)) {
+      if (attributes & IsGetterSetter) {
+        JSObject* setterFunc = static_cast<GetterSetter*>(gs)->setter();        
+        if (!setterFunc) {
+          throwSetterError(exec);
           return;
-        } else {
-          // If there's an existing property on the object or one of its 
-          // prototype it should be replaced, so we just break here.
-          break;
         }
+
+        CallData callData;
+        CallType callType = setterFunc->getCallData(callData);
+        ArgList args;
+        args.append(value);
+        call(exec, setterFunc, callType, callData, this, args);
+        return;
       }
-     
-      if (!obj->_proto->isObject())
-        break;
-        
-      obj = static_cast<JSObject *>(obj->_proto);
+
+      // If there's an existing property on the object or one of its 
+      // prototypes it should be replaced, so break here.
+      break;
     }
+
+    prototype = obj->_proto;
+    if (prototype == jsNull())
+      break;
   }
-  
+
   _prop.put(propertyName, value, 0, true);
 }
 
@@ -230,23 +217,20 @@ bool JSObject::deleteProperty(ExecState *exec, unsigned propertyName)
   return deleteProperty(exec, Identifier::from(exec, propertyName));
 }
 
-static ALWAYS_INLINE JSValue *tryGetAndCallProperty(ExecState *exec, const JSObject *object, const Identifier &propertyName) {
-  JSValue* v = object->get(exec, propertyName);
-  if (v->isObject()) {
-      JSObject* o = static_cast<JSObject*>(v);
-      CallData data;
-      CallType callType = o->getCallData(data);
-      // spec says "not primitive type" but ...
-      if (callType != CallTypeNone) {
-          JSObject* thisObj = const_cast<JSObject*>(object);
-          JSValue* def = o->callAsFunction(exec, thisObj->toThisObject(exec), exec->emptyList());
-          JSType defType = def->type();
-          ASSERT(defType != GetterSetterType);
-          if (defType != ObjectType)
-              return def;
-    }
-  }
-  return NULL;
+static ALWAYS_INLINE JSValue* callDefaultValueFunction(ExecState* exec, const JSObject* object, const Identifier& propertyName)
+{
+    JSValue* function = object->get(exec, propertyName);
+    CallData callData;
+    CallType callType = function->getCallData(callData);
+    if (callType == CallTypeNone)
+        return 0;
+    JSValue* result = call(exec, function, callType, callData, const_cast<JSObject*>(object), exec->emptyList());
+    ASSERT(result->type() != GetterSetterType);
+    if (exec->hadException())
+        return exec->exception();
+    if (result->isObject())
+        return 0;
+    return result;
 }
 
 bool JSObject::getPrimitiveNumber(ExecState* exec, double& number, JSValue*& result)
@@ -259,28 +243,28 @@ bool JSObject::getPrimitiveNumber(ExecState* exec, double& number, JSValue*& res
 // ECMA 8.6.2.6
 JSValue* JSObject::defaultValue(ExecState* exec, JSType hint) const
 {
-  // We need this check to guard against the case where this object is rhs of
-  // a binary expression where lhs threw an exception in its conversion to
-  // primitive
-  if (exec->hadException())
-    return exec->exception();
-  /* Prefer String for Date objects */
-  if ((hint == StringType) || (hint != NumberType && _proto == exec->lexicalGlobalObject()->datePrototype())) {
-    if (JSValue* v = tryGetAndCallProperty(exec, this, exec->propertyNames().toString))
-      return v;
-    if (JSValue* v = tryGetAndCallProperty(exec, this, exec->propertyNames().valueOf))
-      return v;
-  } else {
-    if (JSValue* v = tryGetAndCallProperty(exec, this, exec->propertyNames().valueOf))
-      return v;
-    if (JSValue* v = tryGetAndCallProperty(exec, this, exec->propertyNames().toString))
-      return v;
-  }
+    // We need this check to guard against the case where this object is rhs of
+    // a binary expression where lhs threw an exception in its conversion to
+    // primitive.
+    if (exec->hadException())
+        return exec->exception();
+
+    // Must call toString first for Date objects.
+    if ((hint == StringType) || (hint != NumberType && _proto == exec->lexicalGlobalObject()->datePrototype())) {
+        if (JSValue* value = callDefaultValueFunction(exec, this, exec->propertyNames().toString))
+            return value;
+        if (JSValue* value = callDefaultValueFunction(exec, this, exec->propertyNames().valueOf))
+            return value;
+    } else {
+        if (JSValue* value = callDefaultValueFunction(exec, this, exec->propertyNames().valueOf))
+            return value;
+        if (JSValue* value = callDefaultValueFunction(exec, this, exec->propertyNames().toString))
+            return value;
+    }
 
-  if (exec->hadException())
-    return exec->exception();
+    ASSERT(!exec->hadException());
 
-  return throwError(exec, TypeError, "No default value");
+    return throwError(exec, TypeError, "No default value");
 }
 
 const HashEntry* JSObject::findPropertyHashEntry(ExecState* exec, const Identifier& propertyName) const
@@ -334,7 +318,7 @@ JSValue* JSObject::lookupGetter(ExecState*, const Identifier& propertyName)
         if (v) {
             if (v->type() != GetterSetterType)
                 return jsUndefined();
-            JSObject* funcObj = static_cast<GetterSetter*>(v)->getGetter();
+            JSObject* funcObj = static_cast<GetterSetter*>(v)->getter();
             if (!funcObj)
                 return jsUndefined();
             return funcObj;
@@ -354,7 +338,7 @@ JSValue* JSObject::lookupSetter(ExecState*, const Identifier& propertyName)
         if (v) {
             if (v->type() != GetterSetterType)
                 return jsUndefined();
-            JSObject* funcObj = static_cast<GetterSetter*>(v)->getSetter();
+            JSObject* funcObj = static_cast<GetterSetter*>(v)->setter();
             if (!funcObj)
                 return jsUndefined();
             return funcObj;
@@ -366,29 +350,6 @@ JSValue* JSObject::lookupSetter(ExecState*, const Identifier& propertyName)
     }
 }
 
-JSObject* JSObject::construct(ExecState*, const ArgList& /*args*/)
-{
-  ASSERT(false);
-  return NULL;
-}
-
-JSObject* JSObject::construct(ExecState* exec, const ArgList& args, const Identifier& /*functionName*/, const UString& /*sourceURL*/, int /*lineNumber*/)
-{
-  return construct(exec, args);
-}
-
-bool JSObject::implementsCall()
-{
-    CallData callData;
-    return getCallData(callData) != CallTypeNone;
-}
-
-JSValue *JSObject::callAsFunction(ExecState* /*exec*/, JSObject* /*thisObj*/, const ArgList &/*args*/)
-{
-  ASSERT(false);
-  return NULL;
-}
-
 bool JSObject::implementsHasInstance() const
 {
   return false;
@@ -398,7 +359,7 @@ bool JSObject::hasInstance(ExecState* exec, JSValue* value)
 {
     JSValue* proto = get(exec, exec->propertyNames().prototype);
     if (!proto->isObject()) {
-        throwError(exec, TypeError, "intanceof called on an object with an invalid prototype property.");
+        throwError(exec, TypeError, "instanceof called on an object with an invalid prototype property.");
         return false;
     }
     
@@ -507,11 +468,9 @@ void JSObject::putDirectFunction(InternalFunction* func, int attr)
     putDirect(func->functionName(), func, attr); 
 }
 
-void JSObject::fillGetterPropertySlot(PropertySlot& slot, JSValue **location)
+void JSObject::fillGetterPropertySlot(PropertySlot& slot, JSValue** location)
 {
-    GetterSetter *gs = static_cast<GetterSetter *>(*location);
-    JSObject *getterFunc = gs->getGetter();
-    if (getterFunc)
+    if (JSObject* getterFunc = static_cast<GetterSetter*>(*location)->getter())
         slot.setGetterSlot(getterFunc);
     else
         slot.setUndefined();
@@ -560,7 +519,9 @@ JSObject* Error::create(ExecState* exec, ErrorType errtype, const UString& messa
     args.append(jsString(exec, name));
   else
     args.append(jsString(exec, message));
-  JSObject *err = static_cast<JSObject *>(cons->construct(exec,args));
+  ConstructData constructData;
+  ConstructType constructType = cons->getConstructData(constructData);
+  JSObject* err = construct(exec, cons, constructType, constructData, args);
 
   if (lineno != -1)
     err->put(exec, Identifier(exec, "line"), jsNumber(exec, lineno));
@@ -606,4 +567,9 @@ JSObject *throwError(ExecState *exec, ErrorType type, const UString &message, in
     return error;
 }
 
+JSObject* constructEmptyObject(ExecState* exec)
+{
+    return new (exec) JSObject(exec->lexicalGlobalObject()->objectPrototype());
+}
+
 } // namespace KJS
index cafea4e13fb3896bf32ee3de38b90574c6ebebb9..ca376c7ad6506c2c8964c62169704dc00fd37b69 100644 (file)
@@ -84,32 +84,25 @@ namespace KJS {
   public:
     JSType type() const { return GetterSetterType; }
       
-    GetterSetter() : getter(0), setter(0) { }
-      
-    virtual JSValue* toPrimitive(ExecState*, JSType preferred = UnspecifiedType) const;
-    virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue*& value);
-    virtual bool toBoolean(ExecState *exec) const;
-    virtual double toNumber(ExecState *exec) const;
-    virtual UString toString(ExecState *exec) const;
-    virtual JSObject *toObject(ExecState *exec) const;
+    GetterSetter() : m_getter(0), m_setter(0) { }
       
     virtual void mark();
       
-    JSObject *getGetter() { return getter; }
-    void setGetter(JSObject *g) { getter = g; }
-    JSObject *getSetter() { return setter; }
-    void setSetter(JSObject *s) { setter = s; }
+    JSObject* getter() const { return m_getter; }
+    void setGetter(JSObject* getter) { m_getter = getter; }
+    JSObject* setter() const { return m_setter; }
+    void setSetter(JSObject* setter) { m_setter = setter; }
       
   private:
-    // Object operations, with the toObject operation included.
-    virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
-    virtual bool getOwnPropertySlot(ExecState*, unsigned index, PropertySlot&);
-    virtual void put(ExecState*, const Identifier& propertyName, JSValue*);
-    virtual void put(ExecState*, unsigned propertyName, JSValue*);
-    virtual JSObject* toThisObject(ExecState*) const;
+    virtual JSValue* toPrimitive(ExecState*, JSType preferred) const;
+    virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue*& value);
+    virtual bool toBoolean(ExecState*) const;
+    virtual double toNumber(ExecState*) const;
+    virtual UString toString(ExecState*) const;
+    virtual JSObject* toObject(ExecState*) const;
 
-    JSObject *getter;
-    JSObject *setter;  
+    JSObject* m_getter;
+    JSObject* m_setter;  
   };
   
   class JSObject : public JSCell {
@@ -167,7 +160,6 @@ namespace KJS {
      *
      * @see inherits()
      */
-    virtual const ClassInfo *classInfo() const;
 
     /**
      * Checks whether this object inherits from the class with the specified
@@ -195,7 +187,7 @@ namespace KJS {
      * @return true if this object's class inherits from class with the
      * ClassInfo pointer specified in cinfo
      */
-    bool inherits(const ClassInfo *cinfo) const;
+    bool inherits(const ClassInfo* classInfo) const { return isObject(classInfo); } // FIXME: Merge with isObject.
 
     // internal properties (ECMA 262-3 8.6.2)
 
@@ -230,7 +222,7 @@ namespace KJS {
 
     /**
      * Retrieves the specified property from the object. If neither the object
-     * or any other object in it's prototype chain have the property, this
+     * or any other object in its prototype chain have the property, this
      * function will return Undefined.
      *
      * See ECMA 8.6.2.1
@@ -276,7 +268,7 @@ namespace KJS {
     bool propertyIsEnumerable(ExecState *exec, const Identifier &propertyName) const;
 
     /**
-     * Checks to see whether the object (or any object in it's prototype chain)
+     * Checks to see whether the object (or any object in its prototype chain)
      * has a property with the specified name.
      *
      * See ECMA 8.6.2.4
@@ -319,58 +311,7 @@ namespace KJS {
      * Implementation of the [[DefaultValue]] internal property (implemented by
      * all Objects)
      */
-    virtual JSValue *defaultValue(ExecState *exec, JSType hint) const;
-
-    /**
-     * Creates a new object based on this object. Typically this means the
-     * following:
-     * 1. A new object is created
-     * 2. The prototype of the new object is set to the value of this object's
-     *    "prototype" property
-     * 3. The call() method of this object is called, with the new object
-     *    passed as the this value
-     * 4. The new object is returned
-     *
-     * In some cases, Host objects may differ from these semantics, although
-     * this is discouraged.
-     *
-     * If an error occurs during construction, the execution state's exception
-     * will be set. This can be tested for with ExecState::hadException().
-     * Under some circumstances, the exception object may also be returned.
-     *
-     * Note: This function should not be called if getConstructData() returns
-     * ConstructTypeNone, in which case it will result in an assertion failure.
-     *
-     * @param exec The current execution state
-     * @param args The arguments to be passed to call() once the new object has
-     * been created
-     * @return The newly created &amp; initialized object
-     */
-    /**
-     * Implementation of the [[Construct]] internal property
-     */
-    virtual JSObject* construct(ExecState* exec, const ArgList& args);
-    virtual JSObject* construct(ExecState* exec, const ArgList& args, const Identifier& functionName, const UString& sourceURL, int lineNumber);
-
-    /**
-     * Calls this object as if it is a function.
-     *
-     * Note: This function should not be called if implementsCall() returns
-     * false, in which case it will result in an assertion failure.
-     *
-     * See ECMA 8.6.2.3
-     *
-     * @param exec The current execution state
-     * @param thisObj The obj to be used as "this" within function execution.
-     * Note that in most cases this will be different from the C++ "this"
-     * object. For example, if the ECMAScript code "window.location->toString()"
-     * is executed, call() will be invoked on the C++ object which implements
-     * the toString method, with the thisObj being window.location
-     * @param args ArgList of arguments to be passed to the function
-     * @return The return value from the function
-     */
-    bool implementsCall();
-    virtual JSValue *callAsFunction(ExecState *exec, JSObject *thisObj, const ArgList &args);
+    virtual JSValue* defaultValue(ExecState*, JSType hint) const;
 
     /**
      * Whether or not the object implements the hasInstance() method. If this
@@ -446,6 +387,8 @@ namespace KJS {
     JSValue *_proto;
   };
 
+    JSObject* constructEmptyObject(ExecState*);
+
   /**
    * Types of Native Errors available. For custom errors, GeneralError
    * should be used.
@@ -505,24 +448,19 @@ inline void JSObject::setPrototype(JSValue *proto)
     _proto = proto;
 }
 
-inline bool JSObject::inherits(const ClassInfo *info) const
+inline bool JSCell::isObject(const ClassInfo* info) const
 {
-    for (const ClassInfo *ci = classInfo(); ci; ci = ci->parentClass)
+    for (const ClassInfo* ci = classInfo(); ci; ci = ci->parentClass) {
         if (ci == info)
             return true;
+    }
     return false;
 }
 
-// this method is here to be after the inline declaration of JSObject::inherits
-inline bool JSCell::isObject(const ClassInfo *info) const
-{
-    return isObject() && static_cast<const JSObject *>(this)->inherits(info);
-}
-
 // this method is here to be after the inline declaration of JSCell::isObject
-inline bool JSValue::isObject(const ClassInfo *c) const
+inline bool JSValue::isObject(const ClassInfo* classInfo) const
 {
-    return !JSImmediate::isImmediate(this) && asCell()->isObject(c);
+    return !JSImmediate::isImmediate(this) && asCell()->isObject(classInfo);
 }
 
 inline JSValue *JSObject::get(ExecState *exec, const Identifier &propertyName) const
index 6fa618dbdc5044131c9b286b5592156e2c93a467..d3abe36ae95b396f71e059b97f0f54f00eaa088d 100644 (file)
@@ -255,11 +255,26 @@ void JSCell::put(ExecState* exec, unsigned identifier, JSValue* value)
     toObject(exec)->put(exec, identifier, value);
 }
 
+bool JSCell::deleteProperty(ExecState* exec, const Identifier& identifier)
+{
+    return toObject(exec)->deleteProperty(exec, identifier);
+}
+
+bool JSCell::deleteProperty(ExecState* exec, unsigned identifier)
+{
+    return toObject(exec)->deleteProperty(exec, identifier);
+}
+
 JSObject* JSCell::toThisObject(ExecState* exec) const
 {
     return toObject(exec);
 }
 
+const ClassInfo* JSCell::classInfo() const
+{
+    return 0;
+}
+
 JSCell* jsString(ExecState* exec, const char* s)
 {
     return new (exec) JSString(s ? s : "");
@@ -275,4 +290,22 @@ JSCell* jsOwnedString(ExecState* exec, const UString& s)
     return s.isNull() ? new (exec) JSString("", JSString::HasOtherOwner) : new (exec) JSString(s, JSString::HasOtherOwner);
 }
 
+JSValue* call(ExecState* exec, JSValue* functionObject, CallType callType, const CallData& callData, JSValue* thisValue, const ArgList& args)
+{
+    if (callType == CallTypeNative)
+        return callData.native.function(exec, static_cast<JSObject*>(functionObject), thisValue, args);
+    ASSERT(callType == CallTypeJS);
+    // FIXME: This can be done more efficiently using the callData.
+    return static_cast<JSFunction*>(functionObject)->call(exec, thisValue, args);
+}
+
+JSObject* construct(ExecState* exec, JSValue* object, ConstructType constructType, const ConstructData& constructData, const ArgList& args)
+{
+    if (constructType == ConstructTypeNative)
+        return constructData.native.function(exec, static_cast<JSObject*>(object), args);
+    ASSERT(constructType == ConstructTypeJS);
+    // FIXME: This can be done more efficiently using the constructData.
+    return static_cast<JSFunction*>(object)->construct(exec, args);
+}
+
 } // namespace KJS
index 7d4c5a765ba35288cefa0dad206d1f2479931cc9..ff43ada16eb30fc1aded15eb68ca0725698255c6 100644 (file)
@@ -67,7 +67,7 @@ public:
     bool isNumber() const;
     bool isString() const;
     bool isObject() const;
-    bool isObject(const ClassInfo*) const;
+    bool isObject(const ClassInfo*) const; // FIXME: Merge with inherits.
 
     // Extracting the value.
     bool getBoolean(bool&) const;
@@ -128,6 +128,8 @@ public:
     JSValue* get(ExecState*, unsigned propertyName) const;
     void put(ExecState*, const Identifier& propertyName, JSValue*);
     void put(ExecState*, unsigned propertyName, JSValue*);
+    bool deleteProperty(ExecState*, const Identifier& propertyName);
+    bool deleteProperty(ExecState*, unsigned propertyName);
     JSObject* toThisObject(ExecState*) const;
 
 private:
@@ -159,7 +161,7 @@ public:
     bool isNumber() const;
     bool isString() const;
     bool isObject() const;
-    bool isObject(const ClassInfo*) const;
+    bool isObject(const ClassInfo*) const; // FIXME: Merge with inherits.
 
     // Extracting the value.
     bool getNumber(double&) const;
@@ -191,8 +193,11 @@ public:
     bool marked() const;
 
     // Object operations, with the toObject operation included.
+    virtual const ClassInfo* classInfo() const;
     virtual void put(ExecState*, const Identifier& propertyName, JSValue*);
     virtual void put(ExecState*, unsigned propertyName, JSValue*);
+    virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
+    virtual bool deleteProperty(ExecState*, unsigned propertyName);
     virtual JSObject* toThisObject(ExecState*) const;
 
 private:
index 870c58d4ebb6a5faf42f7567158971b378fd7a2f..e3c4212ada1101d53f004154a2b4674d18d456f7 100644 (file)
@@ -20,7 +20,6 @@
 
 #include "config.h"
 #include "MathObject.h"
-#include "MathObject.lut.h"
 
 #include "operations.h"
 #include <time.h>
 
 namespace KJS {
 
+static JSValue* mathProtoFuncAbs(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* mathProtoFuncACos(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* mathProtoFuncASin(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* mathProtoFuncATan(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* mathProtoFuncATan2(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* mathProtoFuncCeil(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* mathProtoFuncCos(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* mathProtoFuncExp(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* mathProtoFuncFloor(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* mathProtoFuncLog(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* mathProtoFuncMax(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* mathProtoFuncMin(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* mathProtoFuncPow(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* mathProtoFuncRandom(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* mathProtoFuncRound(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* mathProtoFuncSin(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* mathProtoFuncSqrt(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* mathProtoFuncTan(ExecState*, JSObject*, JSValue*, const ArgList&);
+
+}
+
+#include "MathObject.lut.h"
+
+namespace KJS {
+
 // ------------------------------ MathObject --------------------------------
 
 const ClassInfo MathObject::info = { "Math", 0, 0, ExecState::mathTable };
 
 /* Source for MathObject.lut.h
-@begin mathTable 21
+@begin mathTable
   E             MathObject::Euler           DontEnum|DontDelete|ReadOnly
   LN2           MathObject::Ln2             DontEnum|DontDelete|ReadOnly
   LN10          MathObject::Ln10            DontEnum|DontDelete|ReadOnly
@@ -103,33 +127,33 @@ JSValue* MathObject::getValueProperty(ExecState* exec, int token) const
 
 // ------------------------------ Functions --------------------------------
 
-JSValue* mathProtoFuncAbs(ExecState* exec, JSObject*, const ArgList& args)
+JSValue* mathProtoFuncAbs(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
 {
     double arg = args[0]->toNumber(exec);
     return signbit(arg) ? jsNumber(exec, -arg) : jsNumber(exec, arg);
 }
 
-JSValue* mathProtoFuncACos(ExecState* exec, JSObject*, const ArgList& args)
+JSValue* mathProtoFuncACos(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
 {
     return jsNumber(exec, acos(args[0]->toNumber(exec)));
 }
 
-JSValue* mathProtoFuncASin(ExecState* exec, JSObject*, const ArgList& args)
+JSValue* mathProtoFuncASin(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
 {
     return jsNumber(exec, asin(args[0]->toNumber(exec)));
 }
 
-JSValue* mathProtoFuncATan(ExecState* exec, JSObject*, const ArgList& args)
+JSValue* mathProtoFuncATan(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
 {
     return jsNumber(exec, atan(args[0]->toNumber(exec)));
 }
 
-JSValue* mathProtoFuncATan2(ExecState* exec, JSObject*, const ArgList& args)
+JSValue* mathProtoFuncATan2(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
 {
     return jsNumber(exec, atan2(args[0]->toNumber(exec), args[1]->toNumber(exec)));
 }
 
-JSValue* mathProtoFuncCeil(ExecState* exec, JSObject*, const ArgList& args)
+JSValue* mathProtoFuncCeil(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
 {
     double arg = args[0]->toNumber(exec);
     if (signbit(arg) && arg > -1.0)
@@ -137,17 +161,17 @@ JSValue* mathProtoFuncCeil(ExecState* exec, JSObject*, const ArgList& args)
     return jsNumber(exec, ceil(arg));
 }
 
-JSValue* mathProtoFuncCos(ExecState* exec, JSObject*, const ArgList& args)
+JSValue* mathProtoFuncCos(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
 {
     return jsNumber(exec, cos(args[0]->toNumber(exec)));
 }
 
-JSValue* mathProtoFuncExp(ExecState* exec, JSObject*, const ArgList& args)
+JSValue* mathProtoFuncExp(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
 {
     return jsNumber(exec, exp(args[0]->toNumber(exec)));
 }
 
-JSValue* mathProtoFuncFloor(ExecState* exec, JSObject*, const ArgList& args)
+JSValue* mathProtoFuncFloor(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
 {
     double arg = args[0]->toNumber(exec);
     if (signbit(arg) && arg == 0.0)
@@ -155,12 +179,12 @@ JSValue* mathProtoFuncFloor(ExecState* exec, JSObject*, const ArgList& args)
     return jsNumber(exec, floor(arg));
 }
 
-JSValue* mathProtoFuncLog(ExecState* exec, JSObject*, const ArgList& args)
+JSValue* mathProtoFuncLog(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
 {
     return jsNumber(exec, log(args[0]->toNumber(exec)));
 }
 
-JSValue* mathProtoFuncMax(ExecState* exec, JSObject*, const ArgList& args)
+JSValue* mathProtoFuncMax(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
 {
     unsigned argsCount = args.size();
     double result = -Inf;
@@ -176,7 +200,7 @@ JSValue* mathProtoFuncMax(ExecState* exec, JSObject*, const ArgList& args)
     return jsNumber(exec, result);
 }
 
-JSValue* mathProtoFuncMin(ExecState* exec, JSObject*, const ArgList& args)
+JSValue* mathProtoFuncMin(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
 {
     unsigned argsCount = args.size();
     double result = +Inf;
@@ -192,7 +216,7 @@ JSValue* mathProtoFuncMin(ExecState* exec, JSObject*, const ArgList& args)
     return jsNumber(exec, result);
 }
 
-JSValue* mathProtoFuncPow(ExecState* exec, JSObject*, const ArgList& args)
+JSValue* mathProtoFuncPow(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
 {
     // ECMA 15.8.2.1.13
 
@@ -206,7 +230,7 @@ JSValue* mathProtoFuncPow(ExecState* exec, JSObject*, const ArgList& args)
     return jsNumber(exec, pow(arg, arg2));
 }
 
-JSValue* mathProtoFuncRandom(ExecState* exec, JSObject*, const ArgList&)
+JSValue* mathProtoFuncRandom(ExecState* exec, JSObject*, JSValue*, const ArgList&)
 {
 #if !USE(MULTIPLE_THREADS)
     static bool didInitRandom;
@@ -219,7 +243,7 @@ JSValue* mathProtoFuncRandom(ExecState* exec, JSObject*, const ArgList&)
     return jsNumber(exec, wtf_random());
 }
 
-JSValue* mathProtoFuncRound(ExecState* exec, JSObject*, const ArgList& args)
+JSValue* mathProtoFuncRound(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
 {
     double arg = args[0]->toNumber(exec);
     if (signbit(arg) && arg >= -0.5)
@@ -227,17 +251,17 @@ JSValue* mathProtoFuncRound(ExecState* exec, JSObject*, const ArgList& args)
     return jsNumber(exec, floor(arg + 0.5));
 }
 
-JSValue* mathProtoFuncSin(ExecState* exec, JSObject*, const ArgList& args)
+JSValue* mathProtoFuncSin(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
 {
     return jsNumber(exec, sin(args[0]->toNumber(exec)));
 }
 
-JSValue* mathProtoFuncSqrt(ExecState* exec, JSObject*, const ArgList& args)
+JSValue* mathProtoFuncSqrt(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
 {
     return jsNumber(exec, sqrt(args[0]->toNumber(exec)));
 }
 
-JSValue* mathProtoFuncTan(ExecState* exec, JSObject*, const ArgList& args)
+JSValue* mathProtoFuncTan(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
 {
     return jsNumber(exec, tan(args[0]->toNumber(exec)));
 }
index fb542fe820768ea6b50960ea19ac294c0fdf4ba2..43c9ee2343a862c61ffd72c5c3197d1886d4adf0 100644 (file)
@@ -1,6 +1,4 @@
-// -*- c-basic-offset: 2 -*-
 /*
- *  This file is part of the KDE libraries
  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
  *
  *  This library is free software; you can redistribute it and/or
@@ -40,26 +38,6 @@ namespace KJS {
         enum { Euler, Ln2, Ln10, Log2E, Log10E, Pi, Sqrt1_2, Sqrt2 };
     };
 
-    // Functions
-    JSValue* mathProtoFuncAbs(ExecState*, JSObject*, const ArgList&);
-    JSValue* mathProtoFuncACos(ExecState*, JSObject*, const ArgList&);
-    JSValue* mathProtoFuncASin(ExecState*, JSObject*, const ArgList&);
-    JSValue* mathProtoFuncATan(ExecState*, JSObject*, const ArgList&);
-    JSValue* mathProtoFuncATan2(ExecState*, JSObject*, const ArgList&);
-    JSValue* mathProtoFuncCeil(ExecState*, JSObject*, const ArgList&);
-    JSValue* mathProtoFuncCos(ExecState*, JSObject*, const ArgList&);
-    JSValue* mathProtoFuncExp(ExecState*, JSObject*, const ArgList&);
-    JSValue* mathProtoFuncFloor(ExecState*, JSObject*, const ArgList&);
-    JSValue* mathProtoFuncLog(ExecState*, JSObject*, const ArgList&);
-    JSValue* mathProtoFuncMax(ExecState*, JSObject*, const ArgList&);
-    JSValue* mathProtoFuncMin(ExecState*, JSObject*, const ArgList&);
-    JSValue* mathProtoFuncPow(ExecState*, JSObject*, const ArgList&);
-    JSValue* mathProtoFuncRandom(ExecState*, JSObject*, const ArgList&);
-    JSValue* mathProtoFuncRound(ExecState*, JSObject*, const ArgList&);
-    JSValue* mathProtoFuncSin(ExecState*, JSObject*, const ArgList&);
-    JSValue* mathProtoFuncSqrt(ExecState*, JSObject*, const ArgList&);
-    JSValue* mathProtoFuncTan(ExecState*, JSObject*, const ArgList&);
-
 } // namespace KJS
 
 #endif // MathObject_h
index 707fe4a5b00d78905ae236f6ad775ed8ecc3cee0..06980c2813bbe1eba039290d1a8ce6803ad154cf 100644 (file)
@@ -43,12 +43,12 @@ NumberObject::NumberObject(JSObject* proto)
 
 // ------------------------------ NumberPrototype ---------------------------
 
-static JSValue* numberProtoFuncToString(ExecState*, JSObject*, const ArgList&);
-static JSValue* numberProtoFuncToLocaleString(ExecState*, JSObject*, const ArgList&);
-static JSValue* numberProtoFuncValueOf(ExecState*, JSObject*, const ArgList&);
-static JSValue* numberProtoFuncToFixed(ExecState*, JSObject*, const ArgList&);
-static JSValue* numberProtoFuncToExponential(ExecState*, JSObject*, const ArgList&);
-static JSValue* numberProtoFuncToPrecision(ExecState*, JSObject*, const ArgList&);
+static JSValue* numberProtoFuncToString(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* numberProtoFuncToLocaleString(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* numberProtoFuncValueOf(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* numberProtoFuncToFixed(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* numberProtoFuncToExponential(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* numberProtoFuncToPrecision(ExecState*, JSObject*, JSValue*, const ArgList&);
 
 // ECMA 15.7.4
 
@@ -142,12 +142,12 @@ static double intPow10(int e)
 }
 
 
-JSValue* numberProtoFuncToString(ExecState* exec, JSObject* thisObj, const ArgList& args)
+JSValue* numberProtoFuncToString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
-    if (!thisObj->inherits(&NumberObject::info))
+    if (!thisValue->isObject(&NumberObject::info))
         return throwError(exec, TypeError);
 
-    JSValue* v = static_cast<NumberObject*>(thisObj)->internalValue();
+    JSValue* v = static_cast<NumberObject*>(thisValue)->internalValue();
 
     double radixAsDouble = args[0]->toInteger(exec); // nan -> 0
     if (radixAsDouble == 10 || args[0]->isUndefined())
@@ -163,7 +163,7 @@ JSValue* numberProtoFuncToString(ExecState* exec, JSObject* thisObj, const ArgLi
     // unless someone finds a precise rule.
     char s[2048 + 3];
     const char* lastCharInString = s + sizeof(s) - 1;
-    double x = v->toNumber(exec);
+    double x = v->uncheckedGetNumber();
     if (isnan(x) || isinf(x))
         return jsString(exec, UString::from(x));
 
@@ -207,29 +207,29 @@ JSValue* numberProtoFuncToString(ExecState* exec, JSObject* thisObj, const ArgLi
     return jsString(exec, startOfResultString);
 }
 
-JSValue* numberProtoFuncToLocaleString(ExecState* exec, JSObject* thisObj, const ArgList&)
+JSValue* numberProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
 {
-    if (!thisObj->inherits(&NumberObject::info))
+    if (!thisValue->isObject(&NumberObject::info))
         return throwError(exec, TypeError);
 
     // TODO
-    return jsString(exec, static_cast<NumberObject*>(thisObj)->internalValue()->toString(exec));
+    return jsString(exec, static_cast<NumberObject*>(thisValue)->internalValue()->toString(exec));
 }
 
-JSValue* numberProtoFuncValueOf(ExecState* exec, JSObject* thisObj, const ArgList&)
+JSValue* numberProtoFuncValueOf(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
 {
-    if (!thisObj->inherits(&NumberObject::info))
+    if (!thisValue->isObject(&NumberObject::info))
         return throwError(exec, TypeError);
 
-    return static_cast<NumberObject*>(thisObj)->internalValue()->toJSNumber(exec);
+    return static_cast<NumberObject*>(thisValue)->internalValue();
 }
 
-JSValue* numberProtoFuncToFixed(ExecState* exec, JSObject* thisObj, const ArgList& args)
+JSValue* numberProtoFuncToFixed(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
-    if (!thisObj->inherits(&NumberObject::info))
+    if (!thisValue->isObject(&NumberObject::info))
         return throwError(exec, TypeError);
 
-    JSValue* v = static_cast<NumberObject*>(thisObj)->internalValue();
+    JSValue* v = static_cast<NumberObject*>(thisValue)->internalValue();
 
     JSValue* fractionDigits = args[0];
     double df = fractionDigits->toInteger(exec);
@@ -237,7 +237,7 @@ JSValue* numberProtoFuncToFixed(ExecState* exec, JSObject* thisObj, const ArgLis
         return throwError(exec, RangeError, "toFixed() digits argument must be between 0 and 20");
     int f = (int)df;
 
-    double x = v->toNumber(exec);
+    double x = v->uncheckedGetNumber();
     if (isnan(x))
         return jsString(exec, "NaN");
 
@@ -310,14 +310,12 @@ static void exponentialPartToString(char* buf, int& i, int decimalPoint)
     buf[i++] = static_cast<char>('0' + exponential % 10);
 }
 
-JSValue* numberProtoFuncToExponential(ExecState* exec, JSObject* thisObj, const ArgList& args)
+JSValue* numberProtoFuncToExponential(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
-    if (!thisObj->inherits(&NumberObject::info))
+    if (!thisValue->isObject(&NumberObject::info))
         return throwError(exec, TypeError);
 
-    JSValue* v = static_cast<NumberObject*>(thisObj)->internalValue();
-
-    double x = v->toNumber(exec);
+    double x = static_cast<NumberObject*>(thisValue)->internalValue()->uncheckedGetNumber();
 
     if (isnan(x) || isinf(x))
         return jsString(exec, UString::from(x));
@@ -381,15 +379,15 @@ JSValue* numberProtoFuncToExponential(ExecState* exec, JSObject* thisObj, const
     return jsString(exec, buf);
 }
 
-JSValue* numberProtoFuncToPrecision(ExecState* exec, JSObject* thisObj, const ArgList& args)
+JSValue* numberProtoFuncToPrecision(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
-    if (!thisObj->inherits(&NumberObject::info))
+    if (!thisValue->isObject(&NumberObject::info))
         return throwError(exec, TypeError);
 
-    JSValue* v = static_cast<NumberObject*>(thisObj)->internalValue();
+    JSValue* v = static_cast<NumberObject*>(thisValue)->internalValue();
 
     double doublePrecision = args[0]->toIntegerPreserveNaN(exec);
-    double x = v->toNumber(exec);
+    double x = v->uncheckedGetNumber();
     if (args[0]->isUndefined() || isnan(x) || isinf(x))
         return jsString(exec, v->toString(exec));
 
@@ -453,7 +451,7 @@ JSValue* numberProtoFuncToPrecision(ExecState* exec, JSObject* thisObj, const Ar
 const ClassInfo NumberConstructor::info = { "Function", &InternalFunction::info, 0, ExecState::numberTable };
 
 /* Source for NumberObject.lut.h
-@begin numberTable 5
+@begin numberTable
   NaN                   NumberConstructor::NaNValue       DontEnum|DontDelete|ReadOnly
   NEGATIVE_INFINITY     NumberConstructor::NegInfinity    DontEnum|DontDelete|ReadOnly
   POSITIVE_INFINITY     NumberConstructor::PosInfinity    DontEnum|DontDelete|ReadOnly
@@ -462,13 +460,13 @@ const ClassInfo NumberConstructor::info = { "Function", &InternalFunction::info,
 @end
 */
 NumberConstructor::NumberConstructor(ExecState* exec, FunctionPrototype* funcProto, NumberPrototype* numberProto)
-    : InternalFunction(funcProto, Identifier(exec, numberProto->classInfo()->className))
+    : InternalFunction(funcProto, Identifier(exec, numberProto->info.className))
 {
     // Number.Prototype
     putDirect(exec->propertyNames().prototype, numberProto, DontEnum|DontDelete|ReadOnly);
 
     // no. of arguments for constructor
-    putDirect(exec->propertyNames().length, jsNumber(exec, 1), ReadOnly|DontDelete|DontEnum);
+    putDirect(exec->propertyNames().length, jsNumber(exec, 1), ReadOnly | DontEnum | DontDelete);
 }
 
 bool NumberConstructor::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
@@ -495,28 +493,45 @@ JSValue* NumberConstructor::getValueProperty(ExecState* exec, int token) const
     return jsNull();
 }
 
-ConstructType NumberConstructor::getConstructData(ConstructData&)
-{
-    return ConstructTypeNative;
-}
-
 // ECMA 15.7.1
-JSObject* NumberConstructor::construct(ExecState* exec, const ArgList& args)
+static JSObject* constructWithNumberConstructor(ExecState* exec, JSObject*, const ArgList& args)
 {
-    JSObject* proto = exec->lexicalGlobalObject()->numberPrototype();
-    NumberObject* obj = new (exec) NumberObject(proto);
-
-    // FIXME: Check args[0]->isUndefined() instead of args.isEmpty()?
+    NumberObject* obj = new (exec) NumberObject(exec->lexicalGlobalObject()->numberPrototype());
     double n = args.isEmpty() ? 0 : args[0]->toNumber(exec);
     obj->setInternalValue(jsNumber(exec, n));
     return obj;
 }
 
+ConstructType NumberConstructor::getConstructData(ConstructData& constructData)
+{
+    constructData.native.function = constructWithNumberConstructor;
+    return ConstructTypeNative;
+}
+
 // ECMA 15.7.2
-JSValue* NumberConstructor::callAsFunction(ExecState* exec, JSObject*, const ArgList& args)
+static JSValue* callNumberConstructor(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
 {
-    // FIXME: Check args[0]->isUndefined() instead of args.isEmpty()?
     return jsNumber(exec, args.isEmpty() ? 0 : args[0]->toNumber(exec));
 }
 
+CallType NumberConstructor::getCallData(CallData& callData)
+{
+    callData.native.function = callNumberConstructor;
+    return CallTypeNative;
+}
+
+NumberObject* constructNumber(ExecState* exec, JSNumberCell* number)
+{
+    NumberObject* obj = new (exec) NumberObject(exec->lexicalGlobalObject()->numberPrototype());
+    obj->setInternalValue(number);
+    return obj;
+}
+
+NumberObject* constructNumberFromImmediateNumber(ExecState* exec, JSValue* value)
+{
+    NumberObject* obj = new (exec) NumberObject(exec->lexicalGlobalObject()->numberPrototype());
+    obj->setInternalValue(value);
+    return obj;
+}
+
 } // namespace KJS
index 3510fa6aaed541ed3f16b5958f042efd109a640f..a84f40c31f9f9bf6d7bb3aad3778b6421f6ce799 100644 (file)
 
 namespace KJS {
 
+    class JSNumberCell;
+
     class NumberObject : public JSWrapperObject {
     public:
         NumberObject(JSObject* prototype);
+        static const ClassInfo info;
 
+    private:
         virtual const ClassInfo* classInfo() const { return &info; }
-        static const ClassInfo info;
     };
 
+    NumberObject* constructNumber(ExecState*, JSNumberCell*);
+    NumberObject* constructNumberFromImmediateNumber(ExecState*, JSValue*);
+
     /**
      * @internal
      *
@@ -55,20 +61,17 @@ namespace KJS {
     public:
         NumberConstructor(ExecState*, FunctionPrototype*, NumberPrototype*);
 
-        virtual ConstructType getConstructData(ConstructData&);
-        virtual JSObject* construct(ExecState*, const ArgList&);
-
-        virtual JSValue* callAsFunction(ExecState*, JSObject*, const ArgList&);
-
         bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
         JSValue* getValueProperty(ExecState*, int token) const;
 
-        virtual const ClassInfo* classInfo() const { return &info; }
         static const ClassInfo info;
 
         enum { NaNValue, NegInfinity, PosInfinity, MaxValue, MinValue };
 
-        JSObject* construct(const ArgList&);
+    private:
+        virtual ConstructType getConstructData(ConstructData&);
+        virtual CallType getCallData(CallData&);
+        virtual const ClassInfo* classInfo() const { return &info; }
     };
 
 } // namespace KJS
index 8ebbaec837544ce2d897715733f94b9380cfb9d3..5a55fac21d2aafbad053c5862bd061c439429e2d 100644 (file)
@@ -36,16 +36,17 @@ JSValue* PropertySlot::undefinedGetter(ExecState*, const Identifier&, const Prop
 
 JSValue* PropertySlot::functionGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
 {
-    CallData data;
-    CallType callType = slot.m_data.getterFunc->getCallData(data);
+    CallData callData;
+    CallType callType = slot.m_data.getterFunc->getCallData(callData);
     if (callType == CallTypeNative)
-        return slot.m_data.getterFunc->callAsFunction(exec, static_cast<JSObject*>(slot.slotBase()), exec->emptyList());
+        return callData.native.function(exec, slot.m_data.getterFunc, slot.slotBase(), exec->emptyList());
     ASSERT(callType == CallTypeJS);
     RegisterFileStack* stack = &exec->dynamicGlobalObject()->registerFileStack();
     stack->pushFunctionRegisterFile();
-    JSValue* result = slot.m_data.getterFunc->callAsFunction(exec, static_cast<JSObject*>(slot.slotBase()), exec->emptyList());
+    // FIXME: This can be done more efficiently using the callData.
+    JSValue* result = static_cast<JSFunction*>(slot.m_data.getterFunc)->call(exec, slot.slotBase(), exec->emptyList());
     stack->popFunctionRegisterFile();
-    return result;    
+    return result;
 }
 
 }
index e2265edcc8e058186848ef873fcb3222c2605f1d..356894cddfa28c0a8359cde5a8e93950fb5101c7 100644 (file)
@@ -38,10 +38,10 @@ namespace KJS {
 
 // ------------------------------ RegExpPrototype ---------------------------
 
-static JSValue* regExpProtoFuncTest(ExecState*, JSObject*, const ArgList&);
-static JSValue* regExpProtoFuncExec(ExecState*, JSObject*, const ArgList&);
-static JSValue* regExpProtoFuncCompile(ExecState*, JSObject*, const ArgList&);
-static JSValue* regExpProtoFuncToString(ExecState*, JSObject*, const ArgList&);
+static JSValue* regExpProtoFuncTest(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* regExpProtoFuncExec(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* regExpProtoFuncCompile(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* regExpProtoFuncToString(ExecState*, JSObject*, JSValue*, const ArgList&);
 
 // ECMA 15.10.5
 
@@ -58,25 +58,23 @@ RegExpPrototype::RegExpPrototype(ExecState* exec, ObjectPrototype* objectPrototy
 
 // ------------------------------ Functions ---------------------------
     
-JSValue* regExpProtoFuncTest(ExecState* exec, JSObject* thisObj, const ArgList& args)
+JSValue* regExpProtoFuncTest(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
-    if (!thisObj->inherits(&RegExpObject::info))
+    if (!thisValue->isObject(&RegExpObject::info))
         return throwError(exec, TypeError);
-
-    return static_cast<RegExpObject*>(thisObj)->test(exec, args);
+    return static_cast<RegExpObject*>(thisValue)->test(exec, args);
 }
 
-JSValue* regExpProtoFuncExec(ExecState* exec, JSObject* thisObj, const ArgList& args)
+JSValue* regExpProtoFuncExec(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
-    if (!thisObj->inherits(&RegExpObject::info))
+    if (!thisValue->isObject(&RegExpObject::info))
         return throwError(exec, TypeError);
-
-    return static_cast<RegExpObject*>(thisObj)->exec(exec, args);
+    return static_cast<RegExpObject*>(thisValue)->exec(exec, args);
 }
 
-JSValue* regExpProtoFuncCompile(ExecState* exec, JSObject* thisObj, const ArgList& args)
+JSValue* regExpProtoFuncCompile(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
-    if (!thisObj->inherits(&RegExpObject::info))
+    if (!thisValue->isObject(&RegExpObject::info))
         return throwError(exec, TypeError);
 
     RefPtr<RegExp> regExp;
@@ -96,25 +94,25 @@ JSValue* regExpProtoFuncCompile(ExecState* exec, JSObject* thisObj, const ArgLis
     if (!regExp->isValid())
         return throwError(exec, SyntaxError, UString("Invalid regular expression: ").append(regExp->errorMessage()));
 
-    static_cast<RegExpObject*>(thisObj)->setRegExp(regExp.release());
-    static_cast<RegExpObject*>(thisObj)->setLastIndex(0);
+    static_cast<RegExpObject*>(thisValue)->setRegExp(regExp.release());
+    static_cast<RegExpObject*>(thisValue)->setLastIndex(0);
     return jsUndefined();
 }
 
-JSValue* regExpProtoFuncToString(ExecState* exec, JSObject* thisObj, const ArgList&)
+JSValue* regExpProtoFuncToString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
 {
-    if (!thisObj->inherits(&RegExpObject::info)) {
-        if (thisObj->inherits(&RegExpPrototype::info))
+    if (!thisValue->isObject(&RegExpObject::info)) {
+        if (thisValue->isObject(&RegExpPrototype::info))
             return jsString(exec, "//");
         return throwError(exec, TypeError);
     }
 
-    UString result = "/" + thisObj->get(exec, exec->propertyNames().source)->toString(exec) + "/";
-    if (thisObj->get(exec, exec->propertyNames().global)->toBoolean(exec))
+    UString result = "/" + static_cast<RegExpObject*>(thisValue)->get(exec, exec->propertyNames().source)->toString(exec) + "/";
+    if (static_cast<RegExpObject*>(thisValue)->get(exec, exec->propertyNames().global)->toBoolean(exec))
         result += "g";
-    if (thisObj->get(exec, exec->propertyNames().ignoreCase)->toBoolean(exec))
+    if (static_cast<RegExpObject*>(thisValue)->get(exec, exec->propertyNames().ignoreCase)->toBoolean(exec))
         result += "i";
-    if (thisObj->get(exec, exec->propertyNames().multiline)->toBoolean(exec))
+    if (static_cast<RegExpObject*>(thisValue)->get(exec, exec->propertyNames().multiline)->toBoolean(exec))
         result += "m";
     return jsString(exec, result);
 }
@@ -124,7 +122,7 @@ JSValue* regExpProtoFuncToString(ExecState* exec, JSObject* thisObj, const ArgLi
 const ClassInfo RegExpObject::info = { "RegExp", 0, 0, ExecState::regExpTable };
 
 /* Source for RegExpObject.lut.h
-@begin regExpTable 5
+@begin regExpTable
     global        RegExpObject::Global       DontDelete|ReadOnly|DontEnum
     ignoreCase    RegExpObject::IgnoreCase   DontDelete|ReadOnly|DontEnum
     multiline     RegExpObject::Multiline    DontDelete|ReadOnly|DontEnum
@@ -229,14 +227,15 @@ JSValue* RegExpObject::exec(ExecState* exec, const ArgList& args)
         :  jsNull();
 }
 
-CallType RegExpObject::getCallData(CallData&)
+static JSValue* callRegExpObject(ExecState* exec, JSObject* function, JSValue*, const ArgList& args)
 {
-    return CallTypeNative;
+    return static_cast<RegExpObject*>(function)->exec(exec, args);
 }
 
-JSValue* RegExpObject::callAsFunction(ExecState* exec, JSObject*, const ArgList& args)
+CallType RegExpObject::getCallData(CallData& callData)
 {
-    return RegExpObject::exec(exec, args);
+    callData.native.function = callRegExpObject;
+    return CallTypeNative;
 }
 
 // ------------------------------ RegExpConstructor ------------------------------
@@ -244,7 +243,7 @@ JSValue* RegExpObject::callAsFunction(ExecState* exec, JSObject*, const ArgList&
 const ClassInfo RegExpConstructor::info = { "Function", &InternalFunction::info, 0, ExecState::regExpConstructorTable };
 
 /* Source for RegExpObject.lut.h
-@begin regExpConstructorTable 21
+@begin regExpConstructorTable
   input           RegExpConstructor::Input          None
   $_              RegExpConstructor::Input          DontEnum
   multiline       RegExpConstructor::Multiline      None
@@ -316,9 +315,9 @@ void RegExpConstructor::performMatch(RegExp* r, const UString& s, int startOffse
 class RegExpMatchesArray : public JSArray {
 public:
     RegExpMatchesArray(ExecState*, RegExpConstructorPrivate*);
-
     virtual ~RegExpMatchesArray();
 
+private:
     virtual bool getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) { if (lazyCreationData()) fillArrayInstance(exec); return JSArray::getOwnPropertySlot(exec, propertyName, slot); }
     virtual bool getOwnPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot) { if (lazyCreationData()) fillArrayInstance(exec); return JSArray::getOwnPropertySlot(exec, propertyName, slot); }
     virtual void put(ExecState* exec, const Identifier& propertyName, JSValue* v) { if (lazyCreationData()) fillArrayInstance(exec); JSArray::put(exec, propertyName, v); }
@@ -327,7 +326,6 @@ public:
     virtual bool deleteProperty(ExecState* exec, unsigned propertyName) { if (lazyCreationData()) fillArrayInstance(exec); return JSArray::deleteProperty(exec, propertyName); }
     virtual void getPropertyNames(ExecState* exec, PropertyNameArray& arr) { if (lazyCreationData()) fillArrayInstance(exec); JSArray::getPropertyNames(exec, arr); }
 
-private:
     void fillArrayInstance(ExecState*);
 };
 
@@ -471,13 +469,8 @@ void RegExpConstructor::putValueProperty(ExecState *exec, int token, JSValue *va
   }
 }
   
-ConstructType RegExpConstructor::getConstructData(ConstructData&)
-{
-    return ConstructTypeNative;
-}
-
 // ECMA 15.10.4
-JSObject *RegExpConstructor::construct(ExecState *exec, const ArgList &args)
+static JSObject* constructRegExp(ExecState* exec, const ArgList& args)
 {
   JSValue* arg0 = args[0];
   JSValue* arg1 = args[1];
@@ -497,10 +490,27 @@ JSObject *RegExpConstructor::construct(ExecState *exec, const ArgList &args)
     : throwError(exec, SyntaxError, UString("Invalid regular expression: ").append(regExp->errorMessage()));
 }
 
+static JSObject* constructWithRegExpConstructor(ExecState* exec, JSObject*, const ArgList& args)
+{
+    return constructRegExp(exec, args);
+}
+
+ConstructType RegExpConstructor::getConstructData(ConstructData& constructData)
+{
+    constructData.native.function = constructWithRegExpConstructor;
+    return ConstructTypeNative;
+}
+
 // ECMA 15.10.3
-JSValue *RegExpConstructor::callAsFunction(ExecState *exec, JSObject * /*thisObj*/, const ArgList &args)
+static JSValue* callRegExpConstructor(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
 {
-  return construct(exec, args);
+    return constructRegExp(exec, args);
+}
+
+CallType RegExpConstructor::getCallData(CallData& callData)
+{
+    callData.native.function = callRegExpConstructor;
+    return CallTypeNative;
 }
 
 const UString& RegExpConstructor::input() const
index a5f424db722bc3cc9588af414ea1e04b7f1e52d7..764f567b6cbc9634b2fc1a388629434a422deb0d 100644 (file)
@@ -46,11 +46,8 @@ namespace KJS {
         void setRegExp(PassRefPtr<RegExp> r) { m_regExp = r; }
         RegExp* regExp() const { return m_regExp.get(); }
 
-        JSValue* test(ExecState*, const ArgList& args);
-        JSValue* exec(ExecState*, const ArgList& args);
-
-        virtual CallType getCallData(CallData&);
-        virtual JSValue* callAsFunction(ExecState*, JSObject*, const ArgList&);
+        JSValue* test(ExecState*, const ArgList&);
+        JSValue* exec(ExecState*, const ArgList&);
 
         bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
         JSValue* getValueProperty(ExecState*, int token) const;
@@ -63,7 +60,9 @@ namespace KJS {
         void setLastIndex(double lastIndex) { m_lastIndex = lastIndex; }
 
     private:
-        bool match(ExecState*, const ArgList& args);
+        bool match(ExecState*, const ArgList&);
+
+        virtual CallType getCallData(CallData&);
 
         RefPtr<RegExp> m_regExp;
         double m_lastIndex;
@@ -76,17 +75,11 @@ namespace KJS {
 
         RegExpConstructor(ExecState*, FunctionPrototype*, RegExpPrototype*);
 
-        virtual ConstructType getConstructData(ConstructData&);
-        virtual JSObject* construct(ExecState*, const ArgList&);
-
-        virtual JSValue* callAsFunction(ExecState*, JSObject*, const ArgList&);
-
         virtual void put(ExecState*, const Identifier&, JSValue*);
         void putValueProperty(ExecState*, int token, JSValue*);
         virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
         JSValue* getValueProperty(ExecState*, int token) const;
 
-        virtual const ClassInfo* classInfo() const { return &info; }
         static const ClassInfo info;
 
         void performMatch(RegExp*, const UString&, int startOffset, int& position, int& length, int** ovector = 0);
@@ -94,6 +87,10 @@ namespace KJS {
         const UString& input() const;
 
     private:
+        virtual ConstructType getConstructData(ConstructData&);
+        virtual CallType getCallData(CallData&);
+        virtual const ClassInfo* classInfo() const { return &info; }
+
         JSValue* getBackref(ExecState*, unsigned) const;
         JSValue* getLastParen(ExecState*) const;
         JSValue* getLeftContext(ExecState*) const;
index 1095fa88a258ac78a3ba29bc080cacd107b76e65..b99e08d54690002027937a4a61f92d14bc37e758 100644 (file)
@@ -72,14 +72,14 @@ using namespace WTF;
 
 static bool fillBufferWithContentsOfFile(const UString& fileName, Vector<char>& buffer);
 
-static JSValue* functionPrint(ExecState*, JSObject*, const ArgList&);
-static JSValue* functionDebug(ExecState*, JSObject*, const ArgList&);
-static JSValue* functionGC(ExecState*, JSObject*, const ArgList&);
-static JSValue* functionVersion(ExecState*, JSObject*, const ArgList&);
-static JSValue* functionRun(ExecState*, JSObject*, const ArgList&);
-static JSValue* functionLoad(ExecState*, JSObject*, const ArgList&);
-static JSValue* functionReadline(ExecState*, JSObject*, const ArgList&);
-static JSValue* functionQuit(ExecState*, JSObject*, const ArgList&);
+static JSValue* functionPrint(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* functionDebug(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* functionGC(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* functionVersion(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* functionRun(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* functionLoad(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* functionReadline(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* functionQuit(ExecState*, JSObject*, JSValue*, const ArgList&);
 
 struct Options {
     Options()
@@ -173,7 +173,7 @@ GlobalObject::GlobalObject(Vector<UString>& arguments)
     putDirectFunction(new (globalExec()) PrototypeFunction(globalExec(), functionPrototype(), 1, Identifier(globalExec(), "load"), functionLoad));
     putDirectFunction(new (globalExec()) PrototypeFunction(globalExec(), functionPrototype(), 0, Identifier(globalExec(), "readline"), functionReadline));
 
-    JSObject* array = arrayConstructor()->construct(globalExec(), globalExec()->emptyList());
+    JSObject* array = constructEmptyArray(globalExec());
     for (size_t i = 0; i < arguments.size(); ++i)
         array->put(globalExec(), i, jsString(globalExec(), arguments[i]));
     putDirect(Identifier(globalExec(), "arguments"), array);
@@ -181,7 +181,7 @@ GlobalObject::GlobalObject(Vector<UString>& arguments)
     Interpreter::setShouldPrintExceptions(true);
 }
 
-JSValue* functionPrint(ExecState* exec, JSObject*, const ArgList& args)
+JSValue* functionPrint(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
 {
     for (unsigned i = 0; i < args.size(); ++i) {
         if (i != 0)
@@ -195,27 +195,27 @@ JSValue* functionPrint(ExecState* exec, JSObject*, const ArgList& args)
     return jsUndefined();
 }
 
-JSValue* functionDebug(ExecState* exec, JSObject*, const ArgList& args)
+JSValue* functionDebug(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
 {
     fprintf(stderr, "--> %s\n", args[0]->toString(exec).UTF8String().c_str());
     return jsUndefined();
 }
 
-JSValue* functionGC(ExecState* exec, JSObject*, const ArgList&)
+JSValue* functionGC(ExecState* exec, JSObject*, JSValue*, const ArgList&)
 {
     JSLock lock;
     exec->heap()->collect();
     return jsUndefined();
 }
 
-JSValue* functionVersion(ExecState*, JSObject*, const ArgList&)
+JSValue* functionVersion(ExecState*, JSObject*, JSValue*, const ArgList&)
 {
     // We need this function for compatibility with the Mozilla JS tests but for now
     // we don't actually do any version-specific handling
     return jsUndefined();
 }
 
-JSValue* functionRun(ExecState* exec, JSObject*, const ArgList& args)
+JSValue* functionRun(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
 {
     StopWatch stopWatch;
     UString fileName = args[0]->toString(exec);
@@ -232,7 +232,7 @@ JSValue* functionRun(ExecState* exec, JSObject*, const ArgList& args)
     return jsNumber(globalObject->globalExec(), stopWatch.getElapsedMS());
 }
 
-JSValue* functionLoad(ExecState* exec, JSObject*, const ArgList& args)
+JSValue* functionLoad(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
 {
     UString fileName = args[0]->toString(exec);
     Vector<char> script;
@@ -245,7 +245,7 @@ JSValue* functionLoad(ExecState* exec, JSObject*, const ArgList& args)
     return jsUndefined();
 }
 
-JSValue* functionReadline(ExecState* exec, JSObject*, const ArgList&)
+JSValue* functionReadline(ExecState* exec, JSObject*, JSValue*, const ArgList&)
 {
     Vector<char, 256> line;
     int c;
@@ -259,7 +259,7 @@ JSValue* functionReadline(ExecState* exec, JSObject*, const ArgList&)
     return jsString(exec, line.data());
 }
 
-JSValue* functionQuit(ExecState*, JSObject*, const ArgList&)
+JSValue* functionQuit(ExecState*, JSObject*, JSValue*, const ArgList&)
 {
     exit(0);
 #if !COMPILER(MSVC)
index 5057267de76a7fdaab4528d0ca5e2443afcb778c..fad88663b638b32470d407f35e0f8fba815ea6b3 100644 (file)
 
 #include "config.h"
 #include "date_object.h"
-#include "date_object.lut.h"
+
+#include "DateMath.h"
 #include "JSString.h"
+#include "error_object.h"
+#include "operations.h"
+#include <float.h>
+#include <limits.h>
+#include <locale.h>
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <wtf/ASCIICType.h>
+#include <wtf/Assertions.h>
+#include <wtf/MathExtras.h>
+#include <wtf/StringExtras.h>
+#include <wtf/UnusedParam.h>
 
 #if HAVE(ERRNO_H)
 #include <errno.h>
 #include <sys/timeb.h>
 #endif
 
-#include <float.h>
-#include <limits.h>
-#include <locale.h>
-#include <math.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-
-#include "error_object.h"
-#include "operations.h"
-#include "DateMath.h"
-
-#include <wtf/ASCIICType.h>
-#include <wtf/Assertions.h>
-#include <wtf/MathExtras.h>
-#include <wtf/StringExtras.h>
-#include <wtf/UnusedParam.h>
-
 #if PLATFORM(MAC)
-    #include <CoreFoundation/CoreFoundation.h>
+#include <CoreFoundation/CoreFoundation.h>
 #endif
 
 using namespace WTF;
 
 namespace KJS {
 
-static double parseDate(const UString&);
-static double timeClip(double);
+static JSValue* dateProtoFuncGetDate(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncGetDay(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncGetFullYear(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncGetHours(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncGetMilliSeconds(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncGetMinutes(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncGetMonth(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncGetSeconds(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncGetTime(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncGetTimezoneOffset(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncGetUTCDate(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncGetUTCDay(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncGetUTCFullYear(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncGetUTCHours(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncGetUTCMilliseconds(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncGetUTCMinutes(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncGetUTCMonth(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncGetUTCSeconds(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncGetYear(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncSetDate(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncSetFullYear(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncSetHours(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncSetMilliSeconds(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncSetMinutes(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncSetMonth(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncSetSeconds(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncSetTime(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncSetUTCDate(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncSetUTCFullYear(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncSetUTCHours(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncSetUTCMilliseconds(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncSetUTCMinutes(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncSetUTCMonth(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncSetUTCSeconds(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncSetYear(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncToDateString(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncToGMTString(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncToLocaleDateString(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncToLocaleString(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncToLocaleTimeString(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncToString(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncToTimeString(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncToUTCString(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncValueOf(ExecState*, JSObject*, JSValue*, const ArgList&);
 
-inline int gmtoffset(const GregorianDateTime& t)
-{
-    return t.utcOffset;
 }
 
+#include "date_object.lut.h"
 
-/**
- * @internal
- *
- * Class to implement all methods that are properties of the
- * Date object
- */
-class DateFunction : public InternalFunction {
-public:
-    DateFunction(ExecState *, FunctionPrototype *, int i, int len, const Identifier& );
-
-    virtual JSValue *callAsFunction(ExecState *, JSObject *thisObj, const ArgList &args);
+namespace KJS {
 
-    enum { Parse, UTC, Now };
+static double parseDate(const UString&);
+static double timeClip(double);
 
-private:
-    int id;
-};
+static inline int gmtoffset(const GregorianDateTime& t)
+{
+    return t.utcOffset;
+}
 
 struct DateInstance::Cache {
     double m_gregorianDateTimeCachedForMS;
@@ -116,7 +145,7 @@ static CFDateFormatterStyle styleFromArgString(const UString& string, CFDateForm
     return defaultStyle;
 }
 
-static UString formatLocaleDate(ExecState *exec, double time, bool includeDate, bool includeTime, const ArgList &args)
+static UString formatLocaleDate(ExecState *exec, double time, bool includeDate, bool includeTime, const ArgListargs)
 {
     CFDateFormatterStyle dateStyle = (includeDate ? kCFDateFormatterLongStyle : kCFDateFormatterNoStyle);
     CFDateFormatterStyle timeStyle = (includeTime ? kCFDateFormatterLongStyle : kCFDateFormatterNoStyle);
@@ -301,7 +330,7 @@ static bool fillStructuresUsingTimeArgs(ExecState* exec, const ArgList& args, in
 // ms (representing milliseconds) and t (representing the rest of the date structure) appropriately.
 //
 // Format of member function: f([years,] [months,] [days])
-static bool fillStructuresUsingDateArgs(ExecState *exec, const ArgList &args, int maxArgs, double *ms, GregorianDateTime *t)
+static bool fillStructuresUsingDateArgs(ExecState *exec, const ArgListargs, int maxArgs, double *ms, GregorianDateTime *t)
 {
     int idx = 0;
     bool ok = true;
@@ -368,7 +397,7 @@ void DateInstance::msToGregorianDateTime(double milli, bool outputIsUTC, Gregori
 
 bool DateInstance::getTime(GregorianDateTime &t, int &offset) const
 {
-    double milli = internalValue()->getNumber();
+    double milli = internalNumber();
     if (isnan(milli))
         return false;
     
@@ -379,7 +408,7 @@ bool DateInstance::getTime(GregorianDateTime &t, int &offset) const
 
 bool DateInstance::getUTCTime(GregorianDateTime &t) const
 {
-    double milli = internalValue()->getNumber();
+    double milli = internalNumber();
     if (isnan(milli))
         return false;
     
@@ -389,7 +418,7 @@ bool DateInstance::getUTCTime(GregorianDateTime &t) const
 
 bool DateInstance::getTime(double &milli, int &offset) const
 {
-    milli = internalValue()->getNumber();
+    milli = internalNumber();
     if (isnan(milli))
         return false;
     
@@ -401,7 +430,7 @@ bool DateInstance::getTime(double &milli, int &offset) const
 
 bool DateInstance::getUTCTime(double &milli) const
 {
-    milli = internalValue()->getNumber();
+    milli = internalNumber();
     if (isnan(milli))
         return false;
     
@@ -419,8 +448,8 @@ static inline bool isTime_tSigned()
 const ClassInfo DatePrototype::info = {"Date", &DateInstance::info, 0, ExecState::dateTable};
 
 /* Source for date_object.lut.h
-   FIXMEL We could use templates to simplify the UTC variants.
-@begin dateTable 61
+   FIXME: We could use templates to simplify the UTC variants.
+@begin dateTable
   toString              dateProtoFuncToString                DontEnum|Function       0
   toUTCString           dateProtoFuncToUTCString             DontEnum|Function       0
   toDateString          dateProtoFuncToDateString            DontEnum|Function       0
@@ -485,23 +514,22 @@ bool DatePrototype::getOwnPropertySlot(ExecState* exec, const Identifier& proper
 
 // TODO: MakeTime (15.9.11.1) etc. ?
 
+static JSValue* dateParse(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateNow(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateUTC(ExecState*, JSObject*, JSValue*, const ArgList&);
+
 DateConstructor::DateConstructor(ExecState* exec, FunctionPrototype* funcProto, DatePrototype* dateProto)
   : InternalFunction(funcProto, Identifier(exec, dateProto->classInfo()->className))
 {
   putDirect(exec->propertyNames().prototype, dateProto, DontEnum|DontDelete|ReadOnly);
-  putDirectFunction(new (exec) DateFunction(exec, funcProto, DateFunction::Parse, 1, exec->propertyNames().parse), DontEnum);
-  putDirectFunction(new (exec) DateFunction(exec, funcProto, DateFunction::UTC, 7, exec->propertyNames().UTC), DontEnum);
-  putDirectFunction(new (exec) DateFunction(exec, funcProto, DateFunction::Now, 0, exec->propertyNames().now), DontEnum);
-  putDirect(exec, exec->propertyNames().length, 7, ReadOnly|DontDelete|DontEnum);
-}
-
-ConstructType DateConstructor::getConstructData(ConstructData&)
-{
-    return ConstructTypeNative;
+  putDirectFunction(new (exec) PrototypeFunction(exec, funcProto, 1, exec->propertyNames().parse, dateParse), DontEnum);
+  putDirectFunction(new (exec) PrototypeFunction(exec, funcProto, 7, exec->propertyNames().UTC, dateUTC), DontEnum);
+  putDirectFunction(new (exec) PrototypeFunction(exec, funcProto, 0, exec->propertyNames().now, dateNow), DontEnum);
+  putDirect(exec, exec->propertyNames().length, 7, ReadOnly | DontEnum | DontDelete);
 }
 
 // ECMA 15.9.3
-JSObject *DateConstructor::construct(ExecState *exec, const ArgList &args)
+static JSObject* constructDate(ExecState* exec, JSObject*, const ArgList& args)
 {
   int numArgs = args.size();
 
@@ -511,7 +539,7 @@ JSObject *DateConstructor::construct(ExecState *exec, const ArgList &args)
     value = getCurrentUTCTime();
   } else if (numArgs == 1) {
     if (args[0]->isObject(&DateInstance::info))
-      value = static_cast<DateInstance*>(args[0])->internalValue()->toNumber(exec);
+      value = static_cast<DateInstance*>(args[0])->internalNumber();
     else {
       JSValue* primitive = args[0]->toPrimitive(exec);
       if (primitive->isString())
@@ -548,8 +576,14 @@ JSObject *DateConstructor::construct(ExecState *exec, const ArgList &args)
   return ret;
 }
 
+ConstructType DateConstructor::getConstructData(ConstructData& constructData)
+{
+    constructData.native.function = constructDate;
+    return ConstructTypeNative;
+}
+
 // ECMA 15.9.2
-JSValue* DateConstructor::callAsFunction(ExecState* exec, JSObject * /*thisObj*/, const ArgList &/*args*/)
+static JSValue* callDate(ExecState* exec, JSObject*, JSValue*, const ArgList&)
 {
     time_t localTime = time(0);
     tm localTM;
@@ -558,31 +592,33 @@ JSValue* DateConstructor::callAsFunction(ExecState* exec, JSObject * /*thisObj*/
     return jsString(exec, formatDate(ts) + " " + formatTime(ts, false));
 }
 
-// ------------------------------ DateFunction ----------------------------
-
-DateFunction::DateFunction(ExecState* exec, FunctionPrototype* funcProto, int i, int len, const Identifier& name)
-    : InternalFunction(funcProto, name), id(i)
+CallType DateConstructor::getCallData(CallData& callData)
 {
-    putDirect(exec, exec->propertyNames().length, len, DontDelete|ReadOnly|DontEnum);
+    callData.native.function = callDate;
+    return CallTypeNative;
 }
 
-// ECMA 15.9.4.2 - 3
-JSValue *DateFunction::callAsFunction(ExecState* exec, JSObject*, const ArgList& args)
+static JSValue* dateParse(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
 {
-  if (id == Parse)
     return jsNumber(exec, parseDate(args[0]->toString(exec)));
-  else if (id == Now)
+}
+
+static JSValue* dateNow(ExecState* exec, JSObject*, JSValue*, const ArgList&)
+{
     return jsNumber(exec, getCurrentUTCTime());
-  else { // UTC
+}
+
+static JSValue* dateUTC(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+{
     int n = args.size();
     if (isnan(args[0]->toNumber(exec))
-        || isnan(args[1]->toNumber(exec))
-        || (n >= 3 && isnan(args[2]->toNumber(exec)))
-        || (n >= 4 && isnan(args[3]->toNumber(exec)))
-        || (n >= 5 && isnan(args[4]->toNumber(exec)))
-        || (n >= 6 && isnan(args[5]->toNumber(exec)))
-        || (n >= 7 && isnan(args[6]->toNumber(exec)))) {
-      return jsNaN(exec);
+            || isnan(args[1]->toNumber(exec))
+            || (n >= 3 && isnan(args[2]->toNumber(exec)))
+            || (n >= 4 && isnan(args[3]->toNumber(exec)))
+            || (n >= 5 && isnan(args[4]->toNumber(exec)))
+            || (n >= 6 && isnan(args[5]->toNumber(exec)))
+            || (n >= 7 && isnan(args[6]->toNumber(exec)))) {
+        return jsNaN(exec);
     }
 
     GregorianDateTime t;
@@ -595,7 +631,6 @@ JSValue *DateFunction::callAsFunction(ExecState* exec, JSObject*, const ArgList&
     t.second = args[5]->toInt32(exec);
     double ms = (n >= 7) ? args[6]->toNumber(exec) : 0;
     return jsNumber(exec, gregorianDateTimeToMS(t, ms, true));
-  }
 }
 
 // -----------------------------------------------------------------------------
@@ -978,16 +1013,15 @@ double timeClip(double t)
 
 // Functions
 
-JSValue* dateProtoFuncToString(ExecState* exec, JSObject* thisObj, const ArgList&)
+JSValue* dateProtoFuncToString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
 {
-    if (!thisObj->inherits(&DateInstance::info))
+    if (!thisValue->isObject(&DateInstance::info))
         return throwError(exec, TypeError);
 
     const bool utc = false;
 
-    DateInstance* thisDateObj = static_cast<DateInstance*>(thisObj); 
-    JSValue* v = thisDateObj->internalValue();
-    double milli = v->toNumber(exec);
+    DateInstance* thisDateObj = static_cast<DateInstance*>(thisValue); 
+    double milli = thisDateObj->internalNumber();
     if (isnan(milli))
         return jsString(exec, "Invalid Date");
 
@@ -996,16 +1030,15 @@ JSValue* dateProtoFuncToString(ExecState* exec, JSObject* thisObj, const ArgList
     return jsString(exec, formatDate(t) + " " + formatTime(t, utc));
 }
 
-JSValue* dateProtoFuncToUTCString(ExecState* exec, JSObject* thisObj, const ArgList&)
+JSValue* dateProtoFuncToUTCString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
 {
-    if (!thisObj->inherits(&DateInstance::info))
+    if (!thisValue->isObject(&DateInstance::info))
         return throwError(exec, TypeError);
 
     const bool utc = true;
 
-    DateInstance* thisDateObj = static_cast<DateInstance*>(thisObj); 
-    JSValue* v = thisDateObj->internalValue();
-    double milli = v->toNumber(exec);
+    DateInstance* thisDateObj = static_cast<DateInstance*>(thisValue); 
+    double milli = thisDateObj->internalNumber();
     if (isnan(milli))
         return jsString(exec, "Invalid Date");
 
@@ -1014,16 +1047,15 @@ JSValue* dateProtoFuncToUTCString(ExecState* exec, JSObject* thisObj, const ArgL
     return jsString(exec, formatDateUTCVariant(t) + " " + formatTime(t, utc));
 }
 
-JSValue* dateProtoFuncToDateString(ExecState* exec, JSObject* thisObj, const ArgList&)
+JSValue* dateProtoFuncToDateString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
 {
-    if (!thisObj->inherits(&DateInstance::info))
+    if (!thisValue->isObject(&DateInstance::info))
         return throwError(exec, TypeError);
 
     const bool utc = false;
 
-    DateInstance* thisDateObj = static_cast<DateInstance*>(thisObj); 
-    JSValue* v = thisDateObj->internalValue();
-    double milli = v->toNumber(exec);
+    DateInstance* thisDateObj = static_cast<DateInstance*>(thisValue); 
+    double milli = thisDateObj->internalNumber();
     if (isnan(milli))
         return jsString(exec, "Invalid Date");
 
@@ -1032,16 +1064,15 @@ JSValue* dateProtoFuncToDateString(ExecState* exec, JSObject* thisObj, const Arg
     return jsString(exec, formatDate(t));
 }
 
-JSValue* dateProtoFuncToTimeString(ExecState* exec, JSObject* thisObj, const ArgList&)
+JSValue* dateProtoFuncToTimeString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
 {
-    if (!thisObj->inherits(&DateInstance::info))
+    if (!thisValue->isObject(&DateInstance::info))
         return throwError(exec, TypeError);
 
     const bool utc = false;
 
-    DateInstance* thisDateObj = static_cast<DateInstance*>(thisObj); 
-    JSValue* v = thisDateObj->internalValue();
-    double milli = v->toNumber(exec);
+    DateInstance* thisDateObj = static_cast<DateInstance*>(thisValue); 
+    double milli = thisDateObj->internalNumber();
     if (isnan(milli))
         return jsString(exec, "Invalid Date");
 
@@ -1050,14 +1081,13 @@ JSValue* dateProtoFuncToTimeString(ExecState* exec, JSObject* thisObj, const Arg
     return jsString(exec, formatTime(t, utc));
 }
 
-JSValue* dateProtoFuncToLocaleString(ExecState* exec, JSObject* thisObj, const ArgList& args)
+JSValue* dateProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
-    if (!thisObj->inherits(&DateInstance::info))
+    if (!thisValue->isObject(&DateInstance::info))
         return throwError(exec, TypeError);
 
-    DateInstance* thisDateObj = static_cast<DateInstance*>(thisObj); 
-    JSValue* v = thisDateObj->internalValue();
-    double milli = v->toNumber(exec);
+    DateInstance* thisDateObj = static_cast<DateInstance*>(thisValue); 
+    double milli = thisDateObj->internalNumber();
     if (isnan(milli))
         return jsString(exec, "Invalid Date");
 
@@ -1075,14 +1105,13 @@ JSValue* dateProtoFuncToLocaleString(ExecState* exec, JSObject* thisObj, const A
 #endif
 }
 
-JSValue* dateProtoFuncToLocaleDateString(ExecState* exec, JSObject* thisObj, const ArgList& args)
+JSValue* dateProtoFuncToLocaleDateString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
-    if (!thisObj->inherits(&DateInstance::info))
+    if (!thisValue->isObject(&DateInstance::info))
         return throwError(exec, TypeError);
 
-    DateInstance* thisDateObj = static_cast<DateInstance*>(thisObj); 
-    JSValue* v = thisDateObj->internalValue();
-    double milli = v->toNumber(exec);
+    DateInstance* thisDateObj = static_cast<DateInstance*>(thisValue); 
+    double milli = thisDateObj->internalNumber();
     if (isnan(milli))
         return jsString(exec, "Invalid Date");
 
@@ -1100,14 +1129,13 @@ JSValue* dateProtoFuncToLocaleDateString(ExecState* exec, JSObject* thisObj, con
 #endif
 }
 
-JSValue* dateProtoFuncToLocaleTimeString(ExecState* exec, JSObject* thisObj, const ArgList& args)
+JSValue* dateProtoFuncToLocaleTimeString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
-    if (!thisObj->inherits(&DateInstance::info))
+    if (!thisValue->isObject(&DateInstance::info))
         return throwError(exec, TypeError);
 
-    DateInstance* thisDateObj = static_cast<DateInstance*>(thisObj); 
-    JSValue* v = thisDateObj->internalValue();
-    double milli = v->toNumber(exec);
+    DateInstance* thisDateObj = static_cast<DateInstance*>(thisValue); 
+    double milli = thisDateObj->internalNumber();
     if (isnan(milli))
         return jsString(exec, "Invalid Date");
 
@@ -1125,44 +1153,41 @@ JSValue* dateProtoFuncToLocaleTimeString(ExecState* exec, JSObject* thisObj, con
 #endif
 }
 
-JSValue* dateProtoFuncValueOf(ExecState* exec, JSObject* thisObj, const ArgList&)
+JSValue* dateProtoFuncValueOf(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
 {
-    if (!thisObj->inherits(&DateInstance::info))
+    if (!thisValue->isObject(&DateInstance::info))
         return throwError(exec, TypeError);
 
-    DateInstance* thisDateObj = static_cast<DateInstance*>(thisObj); 
-    JSValue* v = thisDateObj->internalValue();
-    double milli = v->toNumber(exec);
+    DateInstance* thisDateObj = static_cast<DateInstance*>(thisValue); 
+    double milli = thisDateObj->internalNumber();
     if (isnan(milli))
         return jsNaN(exec);
 
     return jsNumber(exec, milli);
 }
 
-JSValue* dateProtoFuncGetTime(ExecState* exec, JSObject* thisObj, const ArgList&)
+JSValue* dateProtoFuncGetTime(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
 {
-    if (!thisObj->inherits(&DateInstance::info))
+    if (!thisValue->isObject(&DateInstance::info))
         return throwError(exec, TypeError);
 
-    DateInstance* thisDateObj = static_cast<DateInstance*>(thisObj); 
-    JSValue* v = thisDateObj->internalValue();
-    double milli = v->toNumber(exec);
+    DateInstance* thisDateObj = static_cast<DateInstance*>(thisValue); 
+    double milli = thisDateObj->internalNumber();
     if (isnan(milli))
         return jsNaN(exec);
 
     return jsNumber(exec, milli);
 }
 
-JSValue* dateProtoFuncGetFullYear(ExecState* exec, JSObject* thisObj, const ArgList&)
+JSValue* dateProtoFuncGetFullYear(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
 {
-    if (!thisObj->inherits(&DateInstance::info))
+    if (!thisValue->isObject(&DateInstance::info))
         return throwError(exec, TypeError);
 
     const bool utc = false;
 
-    DateInstance* thisDateObj = static_cast<DateInstance*>(thisObj); 
-    JSValue* v = thisDateObj->internalValue();
-    double milli = v->toNumber(exec);
+    DateInstance* thisDateObj = static_cast<DateInstance*>(thisValue); 
+    double milli = thisDateObj->internalNumber();
     if (isnan(milli))
         return jsNaN(exec);
 
@@ -1171,16 +1196,15 @@ JSValue* dateProtoFuncGetFullYear(ExecState* exec, JSObject* thisObj, const ArgL
     return jsNumber(exec, 1900 + t.year);
 }
 
-JSValue* dateProtoFuncGetUTCFullYear(ExecState* exec, JSObject* thisObj, const ArgList&)
+JSValue* dateProtoFuncGetUTCFullYear(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
 {
-    if (!thisObj->inherits(&DateInstance::info))
+    if (!thisValue->isObject(&DateInstance::info))
         return throwError(exec, TypeError);
 
     const bool utc = true;
 
-    DateInstance* thisDateObj = static_cast<DateInstance*>(thisObj); 
-    JSValue* v = thisDateObj->internalValue();
-    double milli = v->toNumber(exec);
+    DateInstance* thisDateObj = static_cast<DateInstance*>(thisValue); 
+    double milli = thisDateObj->internalNumber();
     if (isnan(milli))
         return jsNaN(exec);
 
@@ -1189,16 +1213,15 @@ JSValue* dateProtoFuncGetUTCFullYear(ExecState* exec, JSObject* thisObj, const A
     return jsNumber(exec, 1900 + t.year);
 }
 
-JSValue* dateProtoFuncToGMTString(ExecState* exec, JSObject* thisObj, const ArgList&)
+JSValue* dateProtoFuncToGMTString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
 {
-    if (!thisObj->inherits(&DateInstance::info))
+    if (!thisValue->isObject(&DateInstance::info))
         return throwError(exec, TypeError);
 
     const bool utc = true;
 
-    DateInstance* thisDateObj = static_cast<DateInstance*>(thisObj); 
-    JSValue* v = thisDateObj->internalValue();
-    double milli = v->toNumber(exec);
+    DateInstance* thisDateObj = static_cast<DateInstance*>(thisValue); 
+    double milli = thisDateObj->internalNumber();
     if (isnan(milli))
         return jsString(exec, "Invalid Date");
 
@@ -1207,16 +1230,15 @@ JSValue* dateProtoFuncToGMTString(ExecState* exec, JSObject* thisObj, const ArgL
     return jsString(exec, formatDateUTCVariant(t) + " " + formatTime(t, utc));
 }
 
-JSValue* dateProtoFuncGetMonth(ExecState* exec, JSObject* thisObj, const ArgList&)
+JSValue* dateProtoFuncGetMonth(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
 {
-    if (!thisObj->inherits(&DateInstance::info))
+    if (!thisValue->isObject(&DateInstance::info))
         return throwError(exec, TypeError);
 
     const bool utc = false;
 
-    DateInstance* thisDateObj = static_cast<DateInstance*>(thisObj); 
-    JSValue* v = thisDateObj->internalValue();
-    double milli = v->toNumber(exec);
+    DateInstance* thisDateObj = static_cast<DateInstance*>(thisValue); 
+    double milli = thisDateObj->internalNumber();
     if (isnan(milli))
         return jsNaN(exec);
 
@@ -1225,16 +1247,15 @@ JSValue* dateProtoFuncGetMonth(ExecState* exec, JSObject* thisObj, const ArgList
     return jsNumber(exec, t.month);
 }
 
-JSValue* dateProtoFuncGetUTCMonth(ExecState* exec, JSObject* thisObj, const ArgList&)
+JSValue* dateProtoFuncGetUTCMonth(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
 {
-    if (!thisObj->inherits(&DateInstance::info))
+    if (!thisValue->isObject(&DateInstance::info))
         return throwError(exec, TypeError);
 
     const bool utc = true;
 
-    DateInstance* thisDateObj = static_cast<DateInstance*>(thisObj); 
-    JSValue* v = thisDateObj->internalValue();
-    double milli = v->toNumber(exec);
+    DateInstance* thisDateObj = static_cast<DateInstance*>(thisValue); 
+    double milli = thisDateObj->internalNumber();
     if (isnan(milli))
         return jsNaN(exec);
 
@@ -1243,16 +1264,15 @@ JSValue* dateProtoFuncGetUTCMonth(ExecState* exec, JSObject* thisObj, const ArgL
     return jsNumber(exec, t.month);
 }
 
-JSValue* dateProtoFuncGetDate(ExecState* exec, JSObject* thisObj, const ArgList&)
+JSValue* dateProtoFuncGetDate(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
 {
-    if (!thisObj->inherits(&DateInstance::info))
+    if (!thisValue->isObject(&DateInstance::info))
         return throwError(exec, TypeError);
 
     const bool utc = false;
 
-    DateInstance* thisDateObj = static_cast<DateInstance*>(thisObj); 
-    JSValue* v = thisDateObj->internalValue();
-    double milli = v->toNumber(exec);
+    DateInstance* thisDateObj = static_cast<DateInstance*>(thisValue); 
+    double milli = thisDateObj->internalNumber();
     if (isnan(milli))
         return jsNaN(exec);
 
@@ -1261,16 +1281,15 @@ JSValue* dateProtoFuncGetDate(ExecState* exec, JSObject* thisObj, const ArgList&
     return jsNumber(exec, t.monthDay);
 }
 
-JSValue* dateProtoFuncGetUTCDate(ExecState* exec, JSObject* thisObj, const ArgList&)
+JSValue* dateProtoFuncGetUTCDate(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
 {
-    if (!thisObj->inherits(&DateInstance::info))
+    if (!thisValue->isObject(&DateInstance::info))
         return throwError(exec, TypeError);
 
     const bool utc = true;
 
-    DateInstance* thisDateObj = static_cast<DateInstance*>(thisObj); 
-    JSValue* v = thisDateObj->internalValue();
-    double milli = v->toNumber(exec);
+    DateInstance* thisDateObj = static_cast<DateInstance*>(thisValue); 
+    double milli = thisDateObj->internalNumber();
     if (isnan(milli))
         return jsNaN(exec);
 
@@ -1279,16 +1298,15 @@ JSValue* dateProtoFuncGetUTCDate(ExecState* exec, JSObject* thisObj, const ArgLi
     return jsNumber(exec, t.monthDay);
 }
 
-JSValue* dateProtoFuncGetDay(ExecState* exec, JSObject* thisObj, const ArgList&)
+JSValue* dateProtoFuncGetDay(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
 {
-    if (!thisObj->inherits(&DateInstance::info))
+    if (!thisValue->isObject(&DateInstance::info))
         return throwError(exec, TypeError);
 
     const bool utc = false;
 
-    DateInstance* thisDateObj = static_cast<DateInstance*>(thisObj); 
-    JSValue* v = thisDateObj->internalValue();
-    double milli = v->toNumber(exec);
+    DateInstance* thisDateObj = static_cast<DateInstance*>(thisValue); 
+    double milli = thisDateObj->internalNumber();
     if (isnan(milli))
         return jsNaN(exec);
 
@@ -1297,16 +1315,15 @@ JSValue* dateProtoFuncGetDay(ExecState* exec, JSObject* thisObj, const ArgList&)
     return jsNumber(exec, t.weekDay);
 }
 
-JSValue* dateProtoFuncGetUTCDay(ExecState* exec, JSObject* thisObj, const ArgList&)
+JSValue* dateProtoFuncGetUTCDay(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
 {
-    if (!thisObj->inherits(&DateInstance::info))
+    if (!thisValue->isObject(&DateInstance::info))
         return throwError(exec, TypeError);
 
     const bool utc = true;
 
-    DateInstance* thisDateObj = static_cast<DateInstance*>(thisObj); 
-    JSValue* v = thisDateObj->internalValue();
-    double milli = v->toNumber(exec);
+    DateInstance* thisDateObj = static_cast<DateInstance*>(thisValue); 
+    double milli = thisDateObj->internalNumber();
     if (isnan(milli))
         return jsNaN(exec);
 
@@ -1315,16 +1332,15 @@ JSValue* dateProtoFuncGetUTCDay(ExecState* exec, JSObject* thisObj, const ArgLis
     return jsNumber(exec, t.weekDay);
 }
 
-JSValue* dateProtoFuncGetHours(ExecState* exec, JSObject* thisObj, const ArgList&)
+JSValue* dateProtoFuncGetHours(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
 {
-    if (!thisObj->inherits(&DateInstance::info))
+    if (!thisValue->isObject(&DateInstance::info))
         return throwError(exec, TypeError);
 
     const bool utc = false;
 
-    DateInstance* thisDateObj = static_cast<DateInstance*>(thisObj); 
-    JSValue* v = thisDateObj->internalValue();
-    double milli = v->toNumber(exec);
+    DateInstance* thisDateObj = static_cast<DateInstance*>(thisValue); 
+    double milli = thisDateObj->internalNumber();
     if (isnan(milli))
         return jsNaN(exec);
 
@@ -1333,16 +1349,15 @@ JSValue* dateProtoFuncGetHours(ExecState* exec, JSObject* thisObj, const ArgList
     return jsNumber(exec, t.hour);
 }
 
-JSValue* dateProtoFuncGetUTCHours(ExecState* exec, JSObject* thisObj, const ArgList&)
+JSValue* dateProtoFuncGetUTCHours(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
 {
-    if (!thisObj->inherits(&DateInstance::info))
+    if (!thisValue->isObject(&DateInstance::info))
         return throwError(exec, TypeError);
 
     const bool utc = true;
 
-    DateInstance* thisDateObj = static_cast<DateInstance*>(thisObj); 
-    JSValue* v = thisDateObj->internalValue();
-    double milli = v->toNumber(exec);
+    DateInstance* thisDateObj = static_cast<DateInstance*>(thisValue); 
+    double milli = thisDateObj->internalNumber();
     if (isnan(milli))
         return jsNaN(exec);
 
@@ -1351,16 +1366,15 @@ JSValue* dateProtoFuncGetUTCHours(ExecState* exec, JSObject* thisObj, const ArgL
     return jsNumber(exec, t.hour);
 }
 
-JSValue* dateProtoFuncGetMinutes(ExecState* exec, JSObject* thisObj, const ArgList&)
+JSValue* dateProtoFuncGetMinutes(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
 {
-    if (!thisObj->inherits(&DateInstance::info))
+    if (!thisValue->isObject(&DateInstance::info))
         return throwError(exec, TypeError);
 
     const bool utc = false;
 
-    DateInstance* thisDateObj = static_cast<DateInstance*>(thisObj); 
-    JSValue* v = thisDateObj->internalValue();
-    double milli = v->toNumber(exec);
+    DateInstance* thisDateObj = static_cast<DateInstance*>(thisValue); 
+    double milli = thisDateObj->internalNumber();
     if (isnan(milli))
         return jsNaN(exec);
 
@@ -1369,16 +1383,15 @@ JSValue* dateProtoFuncGetMinutes(ExecState* exec, JSObject* thisObj, const ArgLi
     return jsNumber(exec, t.minute);
 }
 
-JSValue* dateProtoFuncGetUTCMinutes(ExecState* exec, JSObject* thisObj, const ArgList&)
+JSValue* dateProtoFuncGetUTCMinutes(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
 {
-    if (!thisObj->inherits(&DateInstance::info))
+    if (!thisValue->isObject(&DateInstance::info))
         return throwError(exec, TypeError);
 
     const bool utc = true;
 
-    DateInstance* thisDateObj = static_cast<DateInstance*>(thisObj); 
-    JSValue* v = thisDateObj->internalValue();
-    double milli = v->toNumber(exec);
+    DateInstance* thisDateObj = static_cast<DateInstance*>(thisValue); 
+    double milli = thisDateObj->internalNumber();
     if (isnan(milli))
         return jsNaN(exec);
 
@@ -1387,16 +1400,15 @@ JSValue* dateProtoFuncGetUTCMinutes(ExecState* exec, JSObject* thisObj, const Ar
     return jsNumber(exec, t.minute);
 }
 
-JSValue* dateProtoFuncGetSeconds(ExecState* exec, JSObject* thisObj, const ArgList&)
+JSValue* dateProtoFuncGetSeconds(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
 {
-    if (!thisObj->inherits(&DateInstance::info))
+    if (!thisValue->isObject(&DateInstance::info))
         return throwError(exec, TypeError);
 
     const bool utc = false;
 
-    DateInstance* thisDateObj = static_cast<DateInstance*>(thisObj); 
-    JSValue* v = thisDateObj->internalValue();
-    double milli = v->toNumber(exec);
+    DateInstance* thisDateObj = static_cast<DateInstance*>(thisValue); 
+    double milli = thisDateObj->internalNumber();
     if (isnan(milli))
         return jsNaN(exec);
 
@@ -1405,16 +1417,15 @@ JSValue* dateProtoFuncGetSeconds(ExecState* exec, JSObject* thisObj, const ArgLi
     return jsNumber(exec, t.second);
 }
 
-JSValue* dateProtoFuncGetUTCSeconds(ExecState* exec, JSObject* thisObj, const ArgList&)
+JSValue* dateProtoFuncGetUTCSeconds(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
 {
-    if (!thisObj->inherits(&DateInstance::info))
+    if (!thisValue->isObject(&DateInstance::info))
         return throwError(exec, TypeError);
 
     const bool utc = true;
 
-    DateInstance* thisDateObj = static_cast<DateInstance*>(thisObj); 
-    JSValue* v = thisDateObj->internalValue();
-    double milli = v->toNumber(exec);
+    DateInstance* thisDateObj = static_cast<DateInstance*>(thisValue); 
+    double milli = thisDateObj->internalNumber();
     if (isnan(milli))
         return jsNaN(exec);
 
@@ -1423,14 +1434,13 @@ JSValue* dateProtoFuncGetUTCSeconds(ExecState* exec, JSObject* thisObj, const Ar
     return jsNumber(exec, t.second);
 }
 
-JSValue* dateProtoFuncGetMilliSeconds(ExecState* exec, JSObject* thisObj, const ArgList&)
+JSValue* dateProtoFuncGetMilliSeconds(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
 {
-    if (!thisObj->inherits(&DateInstance::info))
+    if (!thisValue->isObject(&DateInstance::info))
         return throwError(exec, TypeError);
 
-    DateInstance* thisDateObj = static_cast<DateInstance*>(thisObj); 
-    JSValue* v = thisDateObj->internalValue();
-    double milli = v->toNumber(exec);
+    DateInstance* thisDateObj = static_cast<DateInstance*>(thisValue); 
+    double milli = thisDateObj->internalNumber();
     if (isnan(milli))
         return jsNaN(exec);
 
@@ -1439,14 +1449,13 @@ JSValue* dateProtoFuncGetMilliSeconds(ExecState* exec, JSObject* thisObj, const
     return jsNumber(exec, ms);
 }
 
-JSValue* dateProtoFuncGetUTCMilliseconds(ExecState* exec, JSObject* thisObj, const ArgList&)
+JSValue* dateProtoFuncGetUTCMilliseconds(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
 {
-    if (!thisObj->inherits(&DateInstance::info))
+    if (!thisValue->isObject(&DateInstance::info))
         return throwError(exec, TypeError);
 
-    DateInstance* thisDateObj = static_cast<DateInstance*>(thisObj); 
-    JSValue* v = thisDateObj->internalValue();
-    double milli = v->toNumber(exec);
+    DateInstance* thisDateObj = static_cast<DateInstance*>(thisValue); 
+    double milli = thisDateObj->internalNumber();
     if (isnan(milli))
         return jsNaN(exec);
 
@@ -1455,16 +1464,15 @@ JSValue* dateProtoFuncGetUTCMilliseconds(ExecState* exec, JSObject* thisObj, con
     return jsNumber(exec, ms);
 }
 
-JSValue* dateProtoFuncGetTimezoneOffset(ExecState* exec, JSObject* thisObj, const ArgList&)
+JSValue* dateProtoFuncGetTimezoneOffset(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
 {
-    if (!thisObj->inherits(&DateInstance::info))
+    if (!thisValue->isObject(&DateInstance::info))
         return throwError(exec, TypeError);
 
     const bool utc = false;
 
-    DateInstance* thisDateObj = static_cast<DateInstance*>(thisObj); 
-    JSValue* v = thisDateObj->internalValue();
-    double milli = v->toNumber(exec);
+    DateInstance* thisDateObj = static_cast<DateInstance*>(thisValue); 
+    double milli = thisDateObj->internalNumber();
     if (isnan(milli))
         return jsNaN(exec);
 
@@ -1473,12 +1481,12 @@ JSValue* dateProtoFuncGetTimezoneOffset(ExecState* exec, JSObject* thisObj, cons
     return jsNumber(exec, -gmtoffset(t) / minutesPerHour);
 }
 
-JSValue* dateProtoFuncSetTime(ExecState* exec, JSObject* thisObj, const ArgList& args)
+JSValue* dateProtoFuncSetTime(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
-    if (!thisObj->inherits(&DateInstance::info))
+    if (!thisValue->isObject(&DateInstance::info))
         return throwError(exec, TypeError);
 
-    DateInstance* thisDateObj = static_cast<DateInstance*>(thisObj); 
+    DateInstance* thisDateObj = static_cast<DateInstance*>(thisValue); 
 
     double milli = timeClip(args[0]->toNumber(exec));
     JSValue* result = jsNumber(exec, milli);
@@ -1486,14 +1494,13 @@ JSValue* dateProtoFuncSetTime(ExecState* exec, JSObject* thisObj, const ArgList&
     return result;
 }
 
-static JSValue* setNewValueFromTimeArgs(ExecState* exec, JSObject* thisObj, const ArgList& args, int numArgsToUse, bool inputIsUTC)
+static JSValue* setNewValueFromTimeArgs(ExecState* exec, JSValue* thisValue, const ArgList& args, int numArgsToUse, bool inputIsUTC)
 {
-    if (!thisObj->inherits(&DateInstance::info))
+    if (!thisValue->isObject(&DateInstance::info))
         return throwError(exec, TypeError);
 
-    DateInstance* thisDateObj = static_cast<DateInstance*>(thisObj);
-    JSValue* v = thisDateObj->internalValue();
-    double milli = v->toNumber(exec);
+    DateInstance* thisDateObj = static_cast<DateInstance*>(thisValue);
+    double milli = thisDateObj->internalNumber();
     
     if (args.isEmpty() || isnan(milli)) {
         JSValue* result = jsNaN(exec);
@@ -1518,20 +1525,19 @@ static JSValue* setNewValueFromTimeArgs(ExecState* exec, JSObject* thisObj, cons
     return result;
 }
 
-static JSValue* setNewValueFromDateArgs(ExecState* exec, JSObject* thisObj, const ArgList& args, int numArgsToUse, bool inputIsUTC)
+static JSValue* setNewValueFromDateArgs(ExecState* exec, JSValue* thisValue, const ArgList& args, int numArgsToUse, bool inputIsUTC)
 {
-    if (!thisObj->inherits(&DateInstance::info))
+    if (!thisValue->isObject(&DateInstance::info))
         return throwError(exec, TypeError);
 
-    DateInstance* thisDateObj = static_cast<DateInstance*>(thisObj);
+    DateInstance* thisDateObj = static_cast<DateInstance*>(thisValue);
     if (args.isEmpty()) {
         JSValue* result = jsNaN(exec);
         thisDateObj->setInternalValue(result);
         return result;
     }      
     
-    JSValue* v = thisDateObj->internalValue();
-    double milli = v->toNumber(exec);
+    double milli = thisDateObj->internalNumber();
     double ms = 0;
 
     GregorianDateTime t;
@@ -1556,106 +1562,105 @@ static JSValue* setNewValueFromDateArgs(ExecState* exec, JSObject* thisObj, cons
     return result;
 }
 
-JSValue* dateProtoFuncSetMilliSeconds(ExecState* exec, JSObject* thisObj, const ArgList& args)
+JSValue* dateProtoFuncSetMilliSeconds(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
     const bool inputIsUTC = false;
-    return setNewValueFromTimeArgs(exec, thisObj, args, 1, inputIsUTC);
+    return setNewValueFromTimeArgs(exec, thisValue, args, 1, inputIsUTC);
 }
 
-JSValue* dateProtoFuncSetUTCMilliseconds(ExecState* exec, JSObject* thisObj, const ArgList& args)
+JSValue* dateProtoFuncSetUTCMilliseconds(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
     const bool inputIsUTC = true;
-    return setNewValueFromTimeArgs(exec, thisObj, args, 1, inputIsUTC);
+    return setNewValueFromTimeArgs(exec, thisValue, args, 1, inputIsUTC);
 }
 
-JSValue* dateProtoFuncSetSeconds(ExecState* exec, JSObject* thisObj, const ArgList& args)
+JSValue* dateProtoFuncSetSeconds(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
     const bool inputIsUTC = false;
-    return setNewValueFromTimeArgs(exec, thisObj, args, 2, inputIsUTC);
+    return setNewValueFromTimeArgs(exec, thisValue, args, 2, inputIsUTC);
 }
 
-JSValue* dateProtoFuncSetUTCSeconds(ExecState* exec, JSObject* thisObj, const ArgList& args)
+JSValue* dateProtoFuncSetUTCSeconds(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
     const bool inputIsUTC = true;
-    return setNewValueFromTimeArgs(exec, thisObj, args, 2, inputIsUTC);
+    return setNewValueFromTimeArgs(exec, thisValue, args, 2, inputIsUTC);
 }
 
-JSValue* dateProtoFuncSetMinutes(ExecState* exec, JSObject* thisObj, const ArgList& args)
+JSValue* dateProtoFuncSetMinutes(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
     const bool inputIsUTC = false;
-    return setNewValueFromTimeArgs(exec, thisObj, args, 3, inputIsUTC);
+    return setNewValueFromTimeArgs(exec, thisValue, args, 3, inputIsUTC);
 }
 
-JSValue* dateProtoFuncSetUTCMinutes(ExecState* exec, JSObject* thisObj, const ArgList& args)
+JSValue* dateProtoFuncSetUTCMinutes(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
     const bool inputIsUTC = true;
-    return setNewValueFromTimeArgs(exec, thisObj, args, 3, inputIsUTC);
+    return setNewValueFromTimeArgs(exec, thisValue, args, 3, inputIsUTC);
 }
 
-JSValue* dateProtoFuncSetHours(ExecState* exec, JSObject* thisObj, const ArgList& args)
+JSValue* dateProtoFuncSetHours(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
     const bool inputIsUTC = false;
-    return setNewValueFromTimeArgs(exec, thisObj, args, 4, inputIsUTC);
+    return setNewValueFromTimeArgs(exec, thisValue, args, 4, inputIsUTC);
 }
 
-JSValue* dateProtoFuncSetUTCHours(ExecState* exec, JSObject* thisObj, const ArgList& args)
+JSValue* dateProtoFuncSetUTCHours(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
     const bool inputIsUTC = true;
-    return setNewValueFromTimeArgs(exec, thisObj, args, 4, inputIsUTC);
+    return setNewValueFromTimeArgs(exec, thisValue, args, 4, inputIsUTC);
 }
 
-JSValue* dateProtoFuncSetDate(ExecState* exec, JSObject* thisObj, const ArgList& args)
+JSValue* dateProtoFuncSetDate(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
     const bool inputIsUTC = false;
-    return setNewValueFromDateArgs(exec, thisObj, args, 1, inputIsUTC);
+    return setNewValueFromDateArgs(exec, thisValue, args, 1, inputIsUTC);
 }
 
-JSValue* dateProtoFuncSetUTCDate(ExecState* exec, JSObject* thisObj, const ArgList& args)
+JSValue* dateProtoFuncSetUTCDate(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
     const bool inputIsUTC = true;
-    return setNewValueFromDateArgs(exec, thisObj, args, 1, inputIsUTC);
+    return setNewValueFromDateArgs(exec, thisValue, args, 1, inputIsUTC);
 }
 
-JSValue* dateProtoFuncSetMonth(ExecState* exec, JSObject* thisObj, const ArgList& args)
+JSValue* dateProtoFuncSetMonth(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
     const bool inputIsUTC = false;
-    return setNewValueFromDateArgs(exec, thisObj, args, 2, inputIsUTC);
+    return setNewValueFromDateArgs(exec, thisValue, args, 2, inputIsUTC);
 }
 
-JSValue* dateProtoFuncSetUTCMonth(ExecState* exec, JSObject* thisObj, const ArgList& args)
+JSValue* dateProtoFuncSetUTCMonth(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
     const bool inputIsUTC = true;
-    return setNewValueFromDateArgs(exec, thisObj, args, 2, inputIsUTC);
+    return setNewValueFromDateArgs(exec, thisValue, args, 2, inputIsUTC);
 }
 
-JSValue* dateProtoFuncSetFullYear(ExecState* exec, JSObject* thisObj, const ArgList& args)
+JSValue* dateProtoFuncSetFullYear(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
     const bool inputIsUTC = false;
-    return setNewValueFromDateArgs(exec, thisObj, args, 3, inputIsUTC);
+    return setNewValueFromDateArgs(exec, thisValue, args, 3, inputIsUTC);
 }
 
-JSValue* dateProtoFuncSetUTCFullYear(ExecState* exec, JSObject* thisObj, const ArgList& args)
+JSValue* dateProtoFuncSetUTCFullYear(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
     const bool inputIsUTC = true;
-    return setNewValueFromDateArgs(exec, thisObj, args, 3, inputIsUTC);
+    return setNewValueFromDateArgs(exec, thisValue, args, 3, inputIsUTC);
 }
 
-JSValue* dateProtoFuncSetYear(ExecState* exec, JSObject* thisObj, const ArgList& args)
+JSValue* dateProtoFuncSetYear(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
-    if (!thisObj->inherits(&DateInstance::info))
+    if (!thisValue->isObject(&DateInstance::info))
         return throwError(exec, TypeError);
 
     const bool utc = false;
 
-    DateInstance* thisDateObj = static_cast<DateInstance*>(thisObj);     
+    DateInstance* thisDateObj = static_cast<DateInstance*>(thisValue);     
     if (args.isEmpty()) { 
         JSValue* result = jsNaN(exec);
         thisDateObj->setInternalValue(result);
         return result;
     }
     
-    JSValue* v = thisDateObj->internalValue();
-    double milli = v->toNumber(exec);
+    double milli = thisDateObj->internalNumber();
     double ms = 0;
 
     GregorianDateTime t;
@@ -1683,16 +1688,15 @@ JSValue* dateProtoFuncSetYear(ExecState* exec, JSObject* thisObj, const ArgList&
     return result;
 }
 
-JSValue* dateProtoFuncGetYear(ExecState* exec, JSObject* thisObj, const ArgList&)
+JSValue* dateProtoFuncGetYear(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
 {
-    if (!thisObj->inherits(&DateInstance::info))
+    if (!thisValue->isObject(&DateInstance::info))
         return throwError(exec, TypeError);
 
     const bool utc = false;
 
-    DateInstance* thisDateObj = static_cast<DateInstance*>(thisObj); 
-    JSValue* v = thisDateObj->internalValue();
-    double milli = v->toNumber(exec);
+    DateInstance* thisDateObj = static_cast<DateInstance*>(thisValue); 
+    double milli = thisDateObj->internalNumber();
     if (isnan(milli))
         return jsNaN(exec);
 
index be31b142eb38330ec93859371d80d430702106fb..ef68b3c0d8359b9b3995ba286bc437c345f2c462 100644 (file)
@@ -33,20 +33,25 @@ namespace KJS {
 
     class DateInstance : public JSWrapperObject {
     public:
-        DateInstance(JSObject *proto);
+        DateInstance(JSObject* prototype);
         virtual ~DateInstance();
-        
+
+        double internalNumber() const { return internalValue()->uncheckedGetNumber(); }
+
         bool getTime(GregorianDateTime&, int& offset) const;
         bool getUTCTime(GregorianDateTime&) const;
-        bool getTime(double& milli, int& offset) const;
-        bool getUTCTime(double& milli) const;
+        bool getTime(double& milliseconds, int& offset) const;
+        bool getUTCTime(double& milliseconds) const;
         
-        virtual const ClassInfo *classInfo() const { return &info; }
         static const ClassInfo info;
 
         void msToGregorianDateTime(double, bool outputIsUTC, GregorianDateTime&) const;
 
     private:
+        virtual const ClassInfo* classInfo() const { return &info; }
+
+        using JSWrapperObject::internalValue;
+
         struct Cache;
         mutable Cache* m_cache;
     };
@@ -65,61 +70,6 @@ namespace KJS {
         static const ClassInfo info;
     };
 
-    /**
-     * @internal
-     *
-     * Functions to implement all methods that are properties of the
-     * Date.prototype object
-     */
-    
-    // Non-normative properties (Appendix B)
-    // GetYear, SetYear, ToGMTString
-
-    JSValue* dateProtoFuncToString(ExecState*, JSObject*, const ArgList&);
-    JSValue* dateProtoFuncToUTCString(ExecState*, JSObject*, const ArgList&);
-    JSValue* dateProtoFuncToDateString(ExecState*, JSObject*, const ArgList&);
-    JSValue* dateProtoFuncToTimeString(ExecState*, JSObject*, const ArgList&);
-    JSValue* dateProtoFuncToLocaleString(ExecState*, JSObject*, const ArgList&);
-    JSValue* dateProtoFuncToLocaleDateString(ExecState*, JSObject*, const ArgList&);
-    JSValue* dateProtoFuncToLocaleTimeString(ExecState*, JSObject*, const ArgList&);
-    JSValue* dateProtoFuncValueOf(ExecState*, JSObject*, const ArgList&);
-    JSValue* dateProtoFuncGetTime(ExecState*, JSObject*, const ArgList&);
-    JSValue* dateProtoFuncGetFullYear(ExecState*, JSObject*, const ArgList&);
-    JSValue* dateProtoFuncGetUTCFullYear(ExecState*, JSObject*, const ArgList&);
-    JSValue* dateProtoFuncToGMTString(ExecState*, JSObject*, const ArgList&);
-    JSValue* dateProtoFuncGetMonth(ExecState*, JSObject*, const ArgList&);
-    JSValue* dateProtoFuncGetUTCMonth(ExecState*, JSObject*, const ArgList&);
-    JSValue* dateProtoFuncGetDate(ExecState*, JSObject*, const ArgList&);
-    JSValue* dateProtoFuncGetUTCDate(ExecState*, JSObject*, const ArgList&);
-    JSValue* dateProtoFuncGetDay(ExecState*, JSObject*, const ArgList&);
-    JSValue* dateProtoFuncGetUTCDay(ExecState*, JSObject*, const ArgList&);
-    JSValue* dateProtoFuncGetHours(ExecState*, JSObject*, const ArgList&);
-    JSValue* dateProtoFuncGetUTCHours(ExecState*, JSObject*, const ArgList&);
-    JSValue* dateProtoFuncGetMinutes(ExecState*, JSObject*, const ArgList&);
-    JSValue* dateProtoFuncGetUTCMinutes(ExecState*, JSObject*, const ArgList&);
-    JSValue* dateProtoFuncGetSeconds(ExecState*, JSObject*, const ArgList&);
-    JSValue* dateProtoFuncGetUTCSeconds(ExecState*, JSObject*, const ArgList&);
-    JSValue* dateProtoFuncGetMilliSeconds(ExecState*, JSObject*, const ArgList&);
-    JSValue* dateProtoFuncGetUTCMilliseconds(ExecState*, JSObject*, const ArgList&);
-    JSValue* dateProtoFuncGetTimezoneOffset(ExecState*, JSObject*, const ArgList&);
-    JSValue* dateProtoFuncSetTime(ExecState*, JSObject*, const ArgList&);
-    JSValue* dateProtoFuncSetMilliSeconds(ExecState*, JSObject*, const ArgList&);
-    JSValue* dateProtoFuncSetUTCMilliseconds(ExecState*, JSObject*, const ArgList&);
-    JSValue* dateProtoFuncSetSeconds(ExecState*, JSObject*, const ArgList&);
-    JSValue* dateProtoFuncSetUTCSeconds(ExecState*, JSObject*, const ArgList&);
-    JSValue* dateProtoFuncSetMinutes(ExecState*, JSObject*, const ArgList&);
-    JSValue* dateProtoFuncSetUTCMinutes(ExecState*, JSObject*, const ArgList&);
-    JSValue* dateProtoFuncSetHours(ExecState*, JSObject*, const ArgList&);
-    JSValue* dateProtoFuncSetUTCHours(ExecState*, JSObject*, const ArgList&);
-    JSValue* dateProtoFuncSetDate(ExecState*, JSObject*, const ArgList&);
-    JSValue* dateProtoFuncSetUTCDate(ExecState*, JSObject*, const ArgList&);
-    JSValue* dateProtoFuncSetMonth(ExecState*, JSObject*, const ArgList&);
-    JSValue* dateProtoFuncSetUTCMonth(ExecState*, JSObject*, const ArgList&);
-    JSValue* dateProtoFuncSetFullYear(ExecState*, JSObject*, const ArgList&);
-    JSValue* dateProtoFuncSetUTCFullYear(ExecState*, JSObject*, const ArgList&);
-    JSValue* dateProtoFuncSetYear(ExecState*, JSObject*, const ArgList&);
-    JSValue* dateProtoFuncGetYear(ExecState*, JSObject*, const ArgList&);
-
     /**
      * @internal
      *
@@ -128,13 +78,9 @@ namespace KJS {
     class DateConstructor : public InternalFunction {
     public:
         DateConstructor(ExecState*, FunctionPrototype*, DatePrototype*);
-
+    private:
         virtual ConstructType getConstructData(ConstructData&);
-        virtual JSObject* construct(ExecState*, const ArgList& args);
-
-        virtual JSValue* callAsFunction(ExecState*, JSObject* thisObj, const ArgList& args);
-
-        JSObject* construct(const ArgList&);
+        virtual CallType getCallData(CallData&);
     };
 
 } // namespace
index 5e1ce102d7bca7e5c5470bd49e7ec737213e4fa7..cf82290a561ddf905cceb86e02612e779715afd6 100644 (file)
@@ -39,6 +39,8 @@ ErrorInstance::ErrorInstance(JSObject* prototype)
 
 // ------------------------------ ErrorPrototype ----------------------------
 
+static JSValue* errorProtoFuncToString(ExecState*, JSObject*, JSValue*, const ArgList&);
+
 // ECMA 15.9.4
 ErrorPrototype::ErrorPrototype(ExecState* exec, ObjectPrototype* objectPrototype, FunctionPrototype* functionPrototype)
     : ErrorInstance(objectPrototype)
@@ -51,8 +53,10 @@ ErrorPrototype::ErrorPrototype(ExecState* exec, ObjectPrototype* objectPrototype
     putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().toString, errorProtoFuncToString), DontEnum);
 }
 
-JSValue* errorProtoFuncToString(ExecState* exec, JSObject* thisObj, const ArgList&)
+JSValue* errorProtoFuncToString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
 {
+    JSObject* thisObj = thisValue->toThisObject(exec);
+
     UString s = "Error";
 
     JSValue* v = thisObj->get(exec, exec->propertyNames().name);
@@ -60,9 +64,11 @@ JSValue* errorProtoFuncToString(ExecState* exec, JSObject* thisObj, const ArgLis
         s = v->toString(exec);
 
     v = thisObj->get(exec, exec->propertyNames().message);
-    if (!v->isUndefined())
-        // Mozilla compatible format
-        s += ": " + v->toString(exec);
+    if (!v->isUndefined()) {
+        // Mozilla-compatible format.
+        s += ": ";
+        s += v->toString(exec);
+    }
 
     return jsString(exec, s);
 }
@@ -77,29 +83,37 @@ ErrorConstructor::ErrorConstructor(ExecState* exec, FunctionPrototype* funcProto
     putDirect(exec->propertyNames().length, jsNumber(exec, 1), DontDelete|ReadOnly|DontEnum);
 }
 
-ConstructType ErrorConstructor::getConstructData(ConstructData&)
+// ECMA 15.9.3
+static ErrorInstance* constructError(ExecState* exec, const ArgList& args)
 {
-    return ConstructTypeNative;
+    ErrorInstance* obj = new (exec) ErrorInstance(exec->lexicalGlobalObject()->errorPrototype());
+    if (!args[0]->isUndefined())
+        obj->putDirect(exec->propertyNames().message, jsString(exec, args[0]->toString(exec)));
+    return obj;
 }
 
-// ECMA 15.9.3
-JSObject* ErrorConstructor::construct(ExecState* exec, const ArgList& args)
+static JSObject* constructWithErrorConstructor(ExecState* exec, JSObject*, const ArgList& args)
 {
-    JSObject* proto = static_cast<JSObject*>(exec->lexicalGlobalObject()->errorPrototype());
-    JSObject* imp = new (exec) ErrorInstance(proto);
-    JSObject* obj(imp);
-
-    if (!args[0]->isUndefined())
-        imp->putDirect(exec->propertyNames().message, jsString(exec, args[0]->toString(exec)));
+    return constructError(exec, args);
+}
 
-    return obj;
+ConstructType ErrorConstructor::getConstructData(ConstructData& constructData)
+{
+    constructData.native.function = constructWithErrorConstructor;
+    return ConstructTypeNative;
 }
 
 // ECMA 15.9.2
-JSValue* ErrorConstructor::callAsFunction(ExecState* exec, JSObject* /*thisObj*/, const ArgList& args)
+static JSValue* callErrorConstructor(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
 {
     // "Error()" gives the sames result as "new Error()"
-    return construct(exec, args);
+    return constructError(exec, args);
+}
+
+CallType ErrorConstructor::getCallData(CallData& callData)
+{
+    callData.native.function = callErrorConstructor;
+    return CallTypeNative;
 }
 
 // ------------------------------ NativeErrorPrototype ----------------------
@@ -123,23 +137,34 @@ NativeErrorConstructor::NativeErrorConstructor(ExecState* exec, FunctionPrototyp
     putDirect(exec->propertyNames().prototype, proto, DontDelete|ReadOnly|DontEnum);
 }
 
-ConstructType NativeErrorConstructor::getConstructData(ConstructData&)
+ErrorInstance* NativeErrorConstructor::construct(ExecState* exec, const ArgList& args)
 {
+    ErrorInstance* object = new (exec) ErrorInstance(proto);
+    if (!args[0]->isUndefined())
+        object->putDirect(exec->propertyNames().message, jsString(exec, args[0]->toString(exec)));
+    return object;
+}
+
+static JSObject* constructWithNativeErrorConstructor(ExecState* exec, JSObject* constructor, const ArgList& args)
+{
+    return static_cast<NativeErrorConstructor*>(constructor)->construct(exec, args);
+}
+
+ConstructType NativeErrorConstructor::getConstructData(ConstructData& constructData)
+{
+    constructData.native.function = constructWithNativeErrorConstructor;
     return ConstructTypeNative;
 }
 
-JSObject* NativeErrorConstructor::construct(ExecState* exec, const ArgList& args)
+static JSValue* callNativeErrorConstructor(ExecState* exec, JSObject* constructor, JSValue*, const ArgList& args)
 {
-    JSObject* imp = new (exec) ErrorInstance(proto);
-    JSObject* obj(imp);
-    if (!args[0]->isUndefined())
-        imp->putDirect(exec->propertyNames().message, jsString(exec, args[0]->toString(exec)));
-    return obj;
+    return static_cast<NativeErrorConstructor*>(constructor)->construct(exec, args);
 }
 
-JSValue* NativeErrorConstructor::callAsFunction(ExecState* exec, JSObject*, const ArgList& args)
+CallType NativeErrorConstructor::getCallData(CallData& callData)
 {
-    return construct(exec, args);
+    callData.native.function = callNativeErrorConstructor;
+    return CallTypeNative;
 }
 
 void NativeErrorConstructor::mark()
index 4251a22bd5e5e0d88d1905727c1b797499e251b9..2607c684da354224388f181b18f8395b6e20272a 100644 (file)
@@ -38,16 +38,13 @@ namespace KJS {
         ErrorPrototype(ExecState*, ObjectPrototype*, FunctionPrototype*);
     };
 
-    JSValue* errorProtoFuncToString(ExecState*, JSObject*, const ArgList&);
-
     class ErrorConstructor : public InternalFunction {
     public:
         ErrorConstructor(ExecState*, FunctionPrototype*, ErrorPrototype*);
 
+    private:
         virtual ConstructType getConstructData(ConstructData&);
-        virtual JSObject* construct(ExecState*, const ArgList&);
-
-        virtual JSValue* callAsFunction(ExecState*, JSObject*, const ArgList&);
+        virtual CallType getCallData(CallData&);
     };
 
     class NativeErrorPrototype : public JSObject {
@@ -58,19 +55,16 @@ namespace KJS {
     class NativeErrorConstructor : public InternalFunction {
     public:
         NativeErrorConstructor(ExecState*, FunctionPrototype*, NativeErrorPrototype*);
-
-        virtual ConstructType getConstructData(ConstructData&);
-        virtual JSObject* construct(ExecState*, const ArgList&);
-
-        virtual JSValue* callAsFunction(ExecState*, JSObject*, const ArgList&);
-
         virtual void mark();
-
-        virtual const ClassInfo* classInfo() const { return &info; }
         static const ClassInfo info;
+        ErrorInstance* construct(ExecState*, const ArgList&);
 
     private:
-        JSObject* proto;
+        virtual const ClassInfo* classInfo() const { return &info; }
+        virtual ConstructType getConstructData(ConstructData&);
+        virtual CallType getCallData(CallData&);
+
+        NativeErrorPrototype* proto;
     };
 
 } // namespace KJS
index ee9482e25d9e0dfe570d8941b1051775e3251723..3d4f371482c0dd9269103ecc20cfcd0e10dfff91 100644 (file)
@@ -175,18 +175,14 @@ UString JSNumberCell::toString(ExecState *) const
   return UString::from(val);
 }
 
-JSObject *JSNumberCell::toObject(ExecState *exec) const
+JSObject* JSNumberCell::toObject(ExecState* exec) const
 {
-  ArgList args;
-  args.append(const_cast<JSNumberCell*>(this));
-  return static_cast<JSObject *>(exec->lexicalGlobalObject()->numberConstructor()->construct(exec,args));
+    return constructNumber(exec, const_cast<JSNumberCell*>(this));
 }
 
 JSObject* JSNumberCell::toThisObject(ExecState* exec) const
 {
-    ArgList args;
-    args.append(const_cast<JSNumberCell*>(this));
-    return static_cast<JSObject*>(exec->lexicalGlobalObject()->numberConstructor()->construct(exec, args));
+    return constructNumber(exec, const_cast<JSNumberCell*>(this));
 }
 
 bool JSNumberCell::getUInt32(uint32_t& uint32) const
@@ -212,19 +208,20 @@ bool JSNumberCell::getTruncatedUInt32(uint32_t& uint32) const
 }
 
 // --------------------------- GetterSetter ---------------------------------
+
 void GetterSetter::mark()
 {
     JSCell::mark();
-    
-    if (getter && !getter->marked())
-        getter->mark();
-    if (setter && !setter->marked())
-        setter->mark();
+
+    if (m_getter && !m_getter->marked())
+        m_getter->mark();
+    if (m_setter && !m_setter->marked())
+        m_setter->mark();
 }
 
 JSValue* GetterSetter::toPrimitive(ExecState*, JSType) const
 {
-    ASSERT(false);
+    ASSERT_NOT_REACHED();
     return jsNull();
 }
 
@@ -237,55 +234,27 @@ bool GetterSetter::getPrimitiveNumber(ExecState*, double& number, JSValue*& valu
 }
 
 bool GetterSetter::toBoolean(ExecState*) const
-{
-    ASSERT(false);
-    return false;
-}
-
-double GetterSetter::toNumber(ExecState *) const
-{
-    ASSERT(false);
-    return 0.0;
-}
-
-UString GetterSetter::toString(ExecState *) const
-{
-    ASSERT(false);
-    return UString::null();
-}
-
-JSObject *GetterSetter::toObject(ExecState *exec) const
-{
-    ASSERT(false);
-    return jsNull()->toObject(exec);
-}
-
-bool GetterSetter::getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&)
-{
-    ASSERT_NOT_REACHED();
-    return false;
-}
-
-bool GetterSetter::getOwnPropertySlot(ExecState*, unsigned, PropertySlot&)
 {
     ASSERT_NOT_REACHED();
     return false;
 }
 
-void GetterSetter::put(ExecState*, const Identifier&, JSValue*)
+double GetterSetter::toNumber(ExecState*) const
 {
     ASSERT_NOT_REACHED();
+    return 0.0;
 }
 
-void GetterSetter::put(ExecState*, unsigned, JSValue*)
+UString GetterSetter::toString(ExecState*) const
 {
     ASSERT_NOT_REACHED();
+    return UString::null();
 }
 
-JSObject* GetterSetter::toThisObject(ExecState*) const
+JSObject* GetterSetter::toObject(ExecState* exec) const
 {
     ASSERT_NOT_REACHED();
-    return 0;
+    return jsNull()->toObject(exec);
 }
 
 // ------------------------------ LabelStack -----------------------------------
@@ -322,20 +291,15 @@ InternalFunction::InternalFunction()
 {
 }
 
-InternalFunction::InternalFunction(FunctionPrototype* funcProto, const Identifier& name)
-  : JSObject(funcProto)
-  , m_name(name)
-{
-}
-
-CallType InternalFunction::getCallData(CallData&)
+InternalFunction::InternalFunction(FunctionPrototype* prototype, const Identifier& name)
+    : JSObject(prototype)
+    , m_name(name)
 {
-    return CallTypeNative;
 }
 
 bool InternalFunction::implementsHasInstance() const
 {
-  return true;
+    return true;
 }
 
 }
index cfb0e3a8b0d166e8c0a90b7aabd100dc15c99cbf..98dd916ef1c05918a80dc22dd145adb12b1e9d54 100644 (file)
@@ -45,7 +45,7 @@ namespace KJS {
         UString::Rep* key;
         union {
             intptr_t integerValue;
-            PrototypeFunction::JSMemberFunction functionValue;
+            NativeFunction functionValue;
         };
         unsigned char attributes; // JSObject attributes
         unsigned char length; // number of arguments for function
index 6a33698b17e4079d872413976245627da16cb577..9d1e70938b7686f04643c10d77097bc6a151a0d2 100644 (file)
@@ -1682,7 +1682,7 @@ JSFunction* FuncDeclNode::makeFunction(ExecState* exec, ScopeChainNode* scopeCha
 {
     JSFunction* func = new (exec) JSFunction(exec, m_ident, m_body.get(), scopeChain);
 
-    JSObject* proto = exec->lexicalGlobalObject()->objectConstructor()->construct(exec, exec->emptyList());
+    JSObject* proto = constructEmptyObject(exec);
     proto->putDirect(exec->propertyNames().constructor, func, DontEnum);
     func->putDirect(exec->propertyNames().prototype, proto, DontDelete);
     func->putDirect(exec->propertyNames().length, jsNumber(exec, m_body->parameters().size()), ReadOnly | DontDelete | DontEnum);
@@ -1704,7 +1704,7 @@ RegisterID* FuncExprNode::emitCode(CodeGenerator& generator, RegisterID* dst)
 JSFunction* FuncExprNode::makeFunction(ExecState* exec, ScopeChainNode* scopeChain)
 {
     JSFunction* func = new (exec) JSFunction(exec, m_ident, m_body.get(), scopeChain);
-    JSObject* proto = exec->lexicalGlobalObject()->objectConstructor()->construct(exec, exec->emptyList());
+    JSObject* proto = constructEmptyObject(exec);
     proto->putDirect(exec->propertyNames().constructor, func, DontEnum);
     func->putDirect(exec->propertyNames().prototype, proto, DontDelete);
 
index 13abdcb50ba6b4c00313a8d21067dcebb6e40740..22d7b9e2acace12785ca2e0cc0ced17f0b366c7d 100644 (file)
@@ -30,15 +30,15 @@ namespace KJS {
 
 // ------------------------------ ObjectPrototype --------------------------------
 
-static JSValue* objectProtoFuncValueOf(ExecState*, JSObject*, const ArgList&);
-static JSValue* objectProtoFuncHasOwnProperty(ExecState*, JSObject*, const ArgList&);
-static JSValue* objectProtoFuncIsPrototypeOf(ExecState*, JSObject*, const ArgList&);
-static JSValue* objectProtoFuncDefineGetter(ExecState*, JSObject*, const ArgList&);
-static JSValue* objectProtoFuncDefineSetter(ExecState*, JSObject*, const ArgList&);
-static JSValue* objectProtoFuncLookupGetter(ExecState*, JSObject*, const ArgList&);
-static JSValue* objectProtoFuncLookupSetter(ExecState*, JSObject*, const ArgList&);
-static JSValue* objectProtoFuncPropertyIsEnumerable(ExecState*, JSObject*, const ArgList&);
-static JSValue* objectProtoFuncToLocaleString(ExecState*, JSObject*, const ArgList&);
+static JSValue* objectProtoFuncValueOf(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* objectProtoFuncHasOwnProperty(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* objectProtoFuncIsPrototypeOf(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* objectProtoFuncDefineGetter(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* objectProtoFuncDefineSetter(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* objectProtoFuncLookupGetter(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* objectProtoFuncLookupSetter(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* objectProtoFuncPropertyIsEnumerable(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* objectProtoFuncToLocaleString(ExecState*, JSObject*, JSValue*, const ArgList&);
 
 ObjectPrototype::ObjectPrototype(ExecState* exec, FunctionPrototype* functionPrototype)
     : JSObject() // [[Prototype]] is null
@@ -62,18 +62,20 @@ ObjectPrototype::ObjectPrototype(ExecState* exec, FunctionPrototype* functionPro
 
 // ECMA 15.2.4.2, 15.2.4.4, 15.2.4.5, 15.2.4.7
 
-JSValue* objectProtoFuncValueOf(ExecState*, JSObject* thisObj, const ArgList&)
+JSValue* objectProtoFuncValueOf(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
 {
-    return thisObj;
+    return thisValue->toThisObject(exec);
 }
 
-JSValue* objectProtoFuncHasOwnProperty(ExecState* exec, JSObject* thisObj, const ArgList& args)
+JSValue* objectProtoFuncHasOwnProperty(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
-    return jsBoolean(thisObj->hasOwnProperty(exec, Identifier(exec, args[0]->toString(exec))));
+    return jsBoolean(thisValue->toThisObject(exec)->hasOwnProperty(exec, Identifier(exec, args[0]->toString(exec))));
 }
 
-JSValue* objectProtoFuncIsPrototypeOf(ExecState*, JSObject* thisObj, const ArgList& args)
+JSValue* objectProtoFuncIsPrototypeOf(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
+    JSObject* thisObj = thisValue->toThisObject(exec);
+
     if (!args[0]->isObject())
         return jsBoolean(false);
 
@@ -82,53 +84,53 @@ JSValue* objectProtoFuncIsPrototypeOf(ExecState*, JSObject* thisObj, const ArgLi
     while (true) {
         if (!v->isObject())
             return jsBoolean(false);
-        if (thisObj == static_cast<JSObject*>(v))\v
+        if (thisObj == v)\v
             return jsBoolean(true);
         v = static_cast<JSObject*>(v)->prototype();
     }
 }
 
-JSValue* objectProtoFuncDefineGetter(ExecState* exec, JSObject* thisObj, const ArgList& args)
+JSValue* objectProtoFuncDefineGetter(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
-    if (!args[1]->isObject() || !static_cast<JSObject*>(args[1])->implementsCall())
+    CallData callData;
+    if (args[1]->getCallData(callData) == CallTypeNone)
         return throwError(exec, SyntaxError, "invalid getter usage");
-
-    thisObj->defineGetter(exec, Identifier(exec, args[0]->toString(exec)), static_cast<JSObject *>(args[1]));
+    thisValue->toThisObject(exec)->defineGetter(exec, Identifier(exec, args[0]->toString(exec)), static_cast<JSObject*>(args[1]));
     return jsUndefined();
 }
 
-JSValue* objectProtoFuncDefineSetter(ExecState* exec, JSObject* thisObj, const ArgList& args)
+JSValue* objectProtoFuncDefineSetter(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
-    if (!args[1]->isObject() || !static_cast<JSObject*>(args[1])->implementsCall())
+    CallData callData;
+    if (args[1]->getCallData(callData) == CallTypeNone)
         return throwError(exec, SyntaxError, "invalid setter usage");
-
-    thisObj->defineSetter(exec, Identifier(exec, args[0]->toString(exec)), static_cast<JSObject *>(args[1]));
+    thisValue->toThisObject(exec)->defineSetter(exec, Identifier(exec, args[0]->toString(exec)), static_cast<JSObject*>(args[1]));
     return jsUndefined();
 }
 
-JSValue* objectProtoFuncLookupGetter(ExecState* exec, JSObject* thisObj, const ArgList& args)
+JSValue* objectProtoFuncLookupGetter(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
-    return thisObj->lookupGetter(exec, Identifier(exec, args[0]->toString(exec)));
+    return thisValue->toThisObject(exec)->lookupGetter(exec, Identifier(exec, args[0]->toString(exec)));
 }
 
-JSValue* objectProtoFuncLookupSetter(ExecState* exec, JSObject* thisObj, const ArgList& args)
+JSValue* objectProtoFuncLookupSetter(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
-    return thisObj->lookupSetter(exec, Identifier(exec, args[0]->toString(exec)));
+    return thisValue->toThisObject(exec)->lookupSetter(exec, Identifier(exec, args[0]->toString(exec)));
 }
 
-JSValue* objectProtoFuncPropertyIsEnumerable(ExecState* exec, JSObject* thisObj, const ArgList& args)
+JSValue* objectProtoFuncPropertyIsEnumerable(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
-    return jsBoolean(thisObj->propertyIsEnumerable(exec, Identifier(exec, args[0]->toString(exec))));
+    return jsBoolean(thisValue->toThisObject(exec)->propertyIsEnumerable(exec, Identifier(exec, args[0]->toString(exec))));
 }
 
-JSValue* objectProtoFuncToLocaleString(ExecState* exec, JSObject* thisObj, const ArgList&)
+JSValue* objectProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
 {
-    return jsString(exec, thisObj->toString(exec));
+    return jsString(exec, thisValue->toThisObject(exec)->toString(exec));
 }
 
-JSValue* objectProtoFuncToString(ExecState* exec, JSObject* thisObj, const ArgList&)
+JSValue* objectProtoFuncToString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
 {
-    return jsString(exec, "[object " + thisObj->className() + "]");
+    return jsString(exec, "[object " + thisValue->toThisObject(exec)->className() + "]");
 }
 
 // ------------------------------ ObjectConstructor --------------------------------
@@ -140,36 +142,38 @@ ObjectConstructor::ObjectConstructor(ExecState* exec, ObjectPrototype* objProto,
   putDirect(exec->propertyNames().prototype, objProto, DontEnum|DontDelete|ReadOnly);
 
   // no. of arguments for constructor
-  putDirect(exec->propertyNames().length, jsNumber(exec, 1), ReadOnly|DontDelete|DontEnum);
+  putDirect(exec->propertyNames().length, jsNumber(exec, 1), ReadOnly | DontEnum | DontDelete);
+}
+
+// ECMA 15.2.2
+static ALWAYS_INLINE JSObject* constructObject(ExecState* exec, const ArgList& args)
+{
+    JSValue* arg = args[0];
+    if (arg->isUndefinedOrNull())
+        return new (exec) JSObject(exec->lexicalGlobalObject()->objectPrototype());
+    return arg->toObject(exec);
 }
 
-ConstructType ObjectConstructor::getConstructData(ConstructData&)
+static JSObject* constructWithObjectConstructor(ExecState* exec, JSObject*, const ArgList& args)
 {
+    return constructObject(exec, args);
+}
+
+ConstructType ObjectConstructor::getConstructData(ConstructData& constructData)
+{
+    constructData.native.function = constructWithObjectConstructor;
     return ConstructTypeNative;
 }
 
-// ECMA 15.2.2
-JSObject* ObjectConstructor::construct(ExecState* exec, const ArgList& args)
-{
-  JSValue* arg = args[0];
-  switch (arg->type()) {
-  case StringType:
-  case BooleanType:
-  case NumberType:
-  case ObjectType:
-      return arg->toObject(exec);
-  case NullType:
-  case UndefinedType:
-      return new (exec) JSObject(exec->lexicalGlobalObject()->objectPrototype());
-  default:
-      ASSERT_NOT_REACHED();
-      return 0;
-  }
-}
-
-JSValue* ObjectConstructor::callAsFunction(ExecState* exec, JSObject* /*thisObj*/, const ArgList &args)
-{
-    return construct(exec, args);
+static JSValue* callObjectConstructor(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+{
+    return constructObject(exec, args);
+}
+
+CallType ObjectConstructor::getCallData(CallData& callData)
+{
+    callData.native.function = callObjectConstructor;
+    return CallTypeNative;
 }
 
 } // namespace KJS
index ebb4052efb1c87e90d0e5767915d2bcec866bb9d..d5986ea0b5764ad315689018bc37dfb78ec89d58 100644 (file)
@@ -36,7 +36,7 @@ namespace KJS {
         ObjectPrototype(ExecState*, FunctionPrototype*);
     };
 
-    JSValue* objectProtoFuncToString(ExecState*, JSObject*, const ArgList&);
+    JSValue* objectProtoFuncToString(ExecState*, JSObject*, JSValue*, const ArgList&);
 
     /**
      * @internal
@@ -46,11 +46,9 @@ namespace KJS {
     class ObjectConstructor : public InternalFunction {
     public:
         ObjectConstructor(ExecState*, ObjectPrototype*, FunctionPrototype*);
-
+    private:
         virtual ConstructType getConstructData(ConstructData&);
-        virtual JSObject* construct(ExecState*, const ArgList&);
-
-        virtual JSValue* callAsFunction(ExecState*, JSObject*, const ArgList&);
+        virtual CallType getCallData(CallData&);
     };
 
 } // namespace KJS
index d2c48530890fe9497cfa1d5247048b120472c181..b679c2520d193f92b714aa54c4c91411bcb482bd 100644 (file)
@@ -21,7 +21,6 @@
 
 #include "config.h"
 #include "string_object.h"
-#include "string_object.lut.h"
 
 #include "JSWrapperObject.h"
 #include "PropertyNameArray.h"
@@ -36,6 +35,46 @@ using namespace WTF;
 
 namespace KJS {
 
+static JSValue* stringProtoFuncToString(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* stringProtoFuncValueOf(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* stringProtoFuncCharAt(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* stringProtoFuncCharCodeAt(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* stringProtoFuncConcat(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* stringProtoFuncIndexOf(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* stringProtoFuncLastIndexOf(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* stringProtoFuncMatch(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* stringProtoFuncReplace(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* stringProtoFuncSearch(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* stringProtoFuncSlice(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* stringProtoFuncSplit(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* stringProtoFuncSubstr(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* stringProtoFuncSubstring(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* stringProtoFuncToLowerCase(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* stringProtoFuncToUpperCase(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* stringProtoFuncToLocaleLowerCase(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* stringProtoFuncToLocaleUpperCase(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* stringProtoFuncLocaleCompare(ExecState*, JSObject*, JSValue*, const ArgList&);
+
+static JSValue* stringProtoFuncBig(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* stringProtoFuncSmall(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* stringProtoFuncBlink(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* stringProtoFuncBold(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* stringProtoFuncFixed(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* stringProtoFuncItalics(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* stringProtoFuncStrike(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* stringProtoFuncSub(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* stringProtoFuncSup(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* stringProtoFuncFontcolor(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* stringProtoFuncFontsize(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* stringProtoFuncAnchor(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* stringProtoFuncLink(ExecState*, JSObject*, JSValue*, const ArgList&);
+
+}
+
+#include "string_object.lut.h"
+
+namespace KJS {
+
 // ------------------------------ StringObject ----------------------------
 
 const ClassInfo StringObject::info = { "String", 0, 0, 0 };
@@ -98,39 +137,39 @@ void StringObject::getPropertyNames(ExecState* exec, PropertyNameArray& property
 const ClassInfo StringPrototype::info = { "String", &StringObject::info, 0, ExecState::stringTable };
 /* Source for string_object.lut.h
 @begin stringTable 26
-  toString              &stringProtoFuncToString          DontEnum|Function       0
-  valueOf               &stringProtoFuncValueOf           DontEnum|Function       0
-  charAt                &stringProtoFuncCharAt            DontEnum|Function       1
-  charCodeAt            &stringProtoFuncCharCodeAt        DontEnum|Function       1
-  concat                &stringProtoFuncConcat            DontEnum|Function       1
-  indexOf               &stringProtoFuncIndexOf           DontEnum|Function       1
-  lastIndexOf           &stringProtoFuncLastIndexOf       DontEnum|Function       1
-  match                 &stringProtoFuncMatch             DontEnum|Function       1
-  replace               &stringProtoFuncReplace           DontEnum|Function       2
-  search                &stringProtoFuncSearch            DontEnum|Function       1
-  slice                 &stringProtoFuncSlice             DontEnum|Function       2
-  split                 &stringProtoFuncSplit             DontEnum|Function       2
-  substr                &stringProtoFuncSubstr            DontEnum|Function       2
-  substring             &stringProtoFuncSubstring         DontEnum|Function       2
-  toLowerCase           &stringProtoFuncToLowerCase       DontEnum|Function       0
-  toUpperCase           &stringProtoFuncToUpperCase       DontEnum|Function       0
-  toLocaleLowerCase     &stringProtoFuncToLocaleLowerCase DontEnum|Function       0
-  toLocaleUpperCase     &stringProtoFuncToLocaleUpperCase DontEnum|Function       0
-  localeCompare         &stringProtoFuncLocaleCompare     DontEnum|Function       1
-
-  big                   &stringProtoFuncBig               DontEnum|Function       0
-  small                 &stringProtoFuncSmall             DontEnum|Function       0
-  blink                 &stringProtoFuncBlink             DontEnum|Function       0
-  bold                  &stringProtoFuncBold              DontEnum|Function       0
-  fixed                 &stringProtoFuncFixed             DontEnum|Function       0
-  italics               &stringProtoFuncItalics           DontEnum|Function       0
-  strike                &stringProtoFuncStrike            DontEnum|Function       0
-  sub                   &stringProtoFuncSub               DontEnum|Function       0
-  sup                   &stringProtoFuncSup               DontEnum|Function       0
-  fontcolor             &stringProtoFuncFontcolor         DontEnum|Function       1
-  fontsize              &stringProtoFuncFontsize          DontEnum|Function       1
-  anchor                &stringProtoFuncAnchor            DontEnum|Function       1
-  link                  &stringProtoFuncLink              DontEnum|Function       1
+  toString              stringProtoFuncToString          DontEnum|Function       0
+  valueOf               stringProtoFuncValueOf           DontEnum|Function       0
+  charAt                stringProtoFuncCharAt            DontEnum|Function       1
+  charCodeAt            stringProtoFuncCharCodeAt        DontEnum|Function       1
+  concat                stringProtoFuncConcat            DontEnum|Function       1
+  indexOf               stringProtoFuncIndexOf           DontEnum|Function       1
+  lastIndexOf           stringProtoFuncLastIndexOf       DontEnum|Function       1
+  match                 stringProtoFuncMatch             DontEnum|Function       1
+  replace               stringProtoFuncReplace           DontEnum|Function       2
+  search                stringProtoFuncSearch            DontEnum|Function       1
+  slice                 stringProtoFuncSlice             DontEnum|Function       2
+  split                 stringProtoFuncSplit             DontEnum|Function       2
+  substr                stringProtoFuncSubstr            DontEnum|Function       2
+  substring             stringProtoFuncSubstring         DontEnum|Function       2
+  toLowerCase           stringProtoFuncToLowerCase       DontEnum|Function       0
+  toUpperCase           stringProtoFuncToUpperCase       DontEnum|Function       0
+  toLocaleLowerCase     stringProtoFuncToLocaleLowerCase DontEnum|Function       0
+  toLocaleUpperCase     stringProtoFuncToLocaleUpperCase DontEnum|Function       0
+  localeCompare         stringProtoFuncLocaleCompare     DontEnum|Function       1
+
+  big                   stringProtoFuncBig               DontEnum|Function       0
+  small                 stringProtoFuncSmall             DontEnum|Function       0
+  blink                 stringProtoFuncBlink             DontEnum|Function       0
+  bold                  stringProtoFuncBold              DontEnum|Function       0
+  fixed                 stringProtoFuncFixed             DontEnum|Function       0
+  italics               stringProtoFuncItalics           DontEnum|Function       0
+  strike                stringProtoFuncStrike            DontEnum|Function       0
+  sub                   stringProtoFuncSub               DontEnum|Function       0
+  sup                   stringProtoFuncSup               DontEnum|Function       0
+  fontcolor             stringProtoFuncFontcolor         DontEnum|Function       1
+  fontsize              stringProtoFuncFontsize          DontEnum|Function       1
+  anchor                stringProtoFuncAnchor            DontEnum|Function       1
+  link                  stringProtoFuncLink              DontEnum|Function       1
 @end
 */
 // ECMA 15.5.4
@@ -267,12 +306,11 @@ static inline int localeCompare(const UString& a, const UString& b)
 static JSValue *replace(ExecState *exec, JSString* sourceVal, JSValue *pattern, JSValue *replacement)
 {
   UString source = sourceVal->value();
-  JSObject *replacementFunction = 0;
+  CallData callData;
   UString replacementString;
 
-  if (replacement->isObject() && replacement->toObject(exec)->implementsCall())
-    replacementFunction = replacement->toObject(exec);
-  else
+  CallType callType = replacement->getCallData(callData);
+  if (callType == CallTypeNone)
     replacementString = replacement->toString(exec);
 
   if (pattern->isObject() && static_cast<JSObject *>(pattern)->inherits(&RegExpObject::info)) {
@@ -303,7 +341,7 @@ static JSValue *replace(ExecState *exec, JSString* sourceVal, JSValue *pattern,
       pushSourceRange(sourceRanges, sourceRangeCount, sourceRangeCapacity, UString::Range(lastIndex, matchIndex - lastIndex));
 
       UString substitutedReplacement;
-      if (replacementFunction) {
+      if (callType != CallTypeNone) {
           int completeMatchStart = ovector[0];
           ArgList args;
 
@@ -320,7 +358,7 @@ static JSValue *replace(ExecState *exec, JSString* sourceVal, JSValue *pattern,
           args.append(jsNumber(exec, completeMatchStart));
           args.append(sourceVal);
 
-          substitutedReplacement = replacementFunction->callAsFunction(exec, exec->globalThisValue(), args)->toString(exec);
+          substitutedReplacement = call(exec, replacement, callType, callData, exec->globalThisValue(), args)->toString(exec);
       } else
           substitutedReplacement = substituteBackreferences(replacementString, source, ovector, reg);
 
@@ -362,39 +400,39 @@ static JSValue *replace(ExecState *exec, JSString* sourceVal, JSValue *pattern,
   if (matchPos == -1)
     return sourceVal;
   
-  if (replacementFunction) {
+  if (callType != CallTypeNone) {
       ArgList args;
       
       args.append(jsString(exec, source.substr(matchPos, matchLen)));
       args.append(jsNumber(exec, matchPos));
       args.append(sourceVal);
       
-      replacementString = replacementFunction->callAsFunction(exec, exec->globalThisValue(), args)->toString(exec);
+      replacementString = call(exec, replacement, callType, callData, exec->globalThisValue(), args)->toString(exec);
   }
 
   return jsString(exec, source.substr(0, matchPos) + replacementString + source.substr(matchPos + matchLen));
 }
 
-JSValue* stringProtoFuncToString(ExecState* exec, JSObject* thisObj, const ArgList&)
+JSValue* stringProtoFuncToString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
 {
-    if (!thisObj->inherits(&StringObject::info))
+    if (!thisValue->isObject(&StringObject::info))
         return throwError(exec, TypeError);
 
-    return static_cast<StringObject*>(thisObj)->internalValue();
+    return static_cast<StringObject*>(thisValue)->internalValue();
 }
 
-JSValue* stringProtoFuncValueOf(ExecState* exec, JSObject* thisObj, const ArgList&)
+JSValue* stringProtoFuncValueOf(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
 {
-    if (!thisObj->inherits(&StringObject::info))
+    if (!thisValue->isObject(&StringObject::info))
         return throwError(exec, TypeError);
 
-    return static_cast<StringObject*>(thisObj)->internalValue();
+    return static_cast<StringObject*>(thisValue)->internalValue();
 }
 
-JSValue* stringProtoFuncCharAt(ExecState* exec, JSObject* thisObj, const ArgList& args)
+JSValue* stringProtoFuncCharAt(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
     // This optimizes the common case that thisObj is a StringObject
-    UString s = thisObj->inherits(&StringObject::info) ? static_cast<StringObject*>(thisObj)->internalValue()->value() : thisObj->toString(exec);
+    UString s = thisValue->isObject(&StringObject::info) ? static_cast<StringObject*>(thisValue)->internalValue()->value() : thisValue->toThisObject(exec)->toString(exec);
     int len = s.size();
 
     UString u;
@@ -407,10 +445,10 @@ JSValue* stringProtoFuncCharAt(ExecState* exec, JSObject* thisObj, const ArgList
     return jsString(exec, u);
 }
 
-JSValue* stringProtoFuncCharCodeAt(ExecState* exec, JSObject* thisObj, const ArgList& args)
+JSValue* stringProtoFuncCharCodeAt(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
     // This optimizes the common case that thisObj is a StringObject
-    UString s = thisObj->inherits(&StringObject::info) ? static_cast<StringObject*>(thisObj)->internalValue()->value() : thisObj->toString(exec);
+    UString s = thisValue->isObject(&StringObject::info) ? static_cast<StringObject*>(thisValue)->internalValue()->value() : thisValue->toThisObject(exec)->toString(exec);
     int len = s.size();
 
     JSValue* result = 0;
@@ -424,10 +462,10 @@ JSValue* stringProtoFuncCharCodeAt(ExecState* exec, JSObject* thisObj, const Arg
     return result;
 }
 
-JSValue* stringProtoFuncConcat(ExecState* exec, JSObject* thisObj, const ArgList& args)
+JSValue* stringProtoFuncConcat(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
     // This optimizes the common case that thisObj is a StringObject
-    UString s = thisObj->inherits(&StringObject::info) ? static_cast<StringObject*>(thisObj)->internalValue()->value() : thisObj->toString(exec);
+    UString s = thisValue->isObject(&StringObject::info) ? static_cast<StringObject*>(thisValue)->internalValue()->value() : thisValue->toThisObject(exec)->toString(exec);
 
     ArgList::const_iterator end = args.end();
     for (ArgList::const_iterator it = args.begin(); it != end; ++it) {
@@ -436,10 +474,10 @@ JSValue* stringProtoFuncConcat(ExecState* exec, JSObject* thisObj, const ArgList
     return jsString(exec, s);
 }
 
-JSValue* stringProtoFuncIndexOf(ExecState* exec, JSObject* thisObj, const ArgList& args)
+JSValue* stringProtoFuncIndexOf(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
     // This optimizes the common case that thisObj is a StringObject
-    UString s = thisObj->inherits(&StringObject::info) ? static_cast<StringObject*>(thisObj)->internalValue()->value() : thisObj->toString(exec);
+    UString s = thisValue->isObject(&StringObject::info) ? static_cast<StringObject*>(thisValue)->internalValue()->value() : thisValue->toThisObject(exec)->toString(exec);
     int len = s.size();
 
     JSValue* a0 = args[0];
@@ -453,10 +491,10 @@ JSValue* stringProtoFuncIndexOf(ExecState* exec, JSObject* thisObj, const ArgLis
     return jsNumber(exec, s.find(u2, static_cast<int>(dpos)));
 }
 
-JSValue* stringProtoFuncLastIndexOf(ExecState* exec, JSObject* thisObj, const ArgList& args)
+JSValue* stringProtoFuncLastIndexOf(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
     // This optimizes the common case that thisObj is a StringObject
-    UString s = thisObj->inherits(&StringObject::info) ? static_cast<StringObject*>(thisObj)->internalValue()->value() : thisObj->toString(exec);
+    UString s = thisValue->isObject(&StringObject::info) ? static_cast<StringObject*>(thisValue)->internalValue()->value() : thisValue->toThisObject(exec)->toString(exec);
     int len = s.size();
 
     JSValue* a0 = args[0];
@@ -471,10 +509,10 @@ JSValue* stringProtoFuncLastIndexOf(ExecState* exec, JSObject* thisObj, const Ar
     return jsNumber(exec, s.rfind(u2, static_cast<int>(dpos)));
 }
 
-JSValue* stringProtoFuncMatch(ExecState* exec, JSObject* thisObj, const ArgList& args)
+JSValue* stringProtoFuncMatch(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
     // This optimizes the common case that thisObj is a StringObject
-    UString s = thisObj->inherits(&StringObject::info) ? static_cast<StringObject*>(thisObj)->internalValue()->value() : thisObj->toString(exec);
+    UString s = thisValue->isObject(&StringObject::info) ? static_cast<StringObject*>(thisValue)->internalValue()->value() : thisValue->toThisObject(exec)->toString(exec);
 
     JSValue* a0 = args[0];
 
@@ -520,16 +558,16 @@ JSValue* stringProtoFuncMatch(ExecState* exec, JSObject* thisObj, const ArgList&
         // other browsers and because Null is a false value.
         result = jsNull();
       } else {
-        result = exec->lexicalGlobalObject()->arrayConstructor()->construct(exec, list);
+        result = constructArray(exec, list);
       }
     }
     return result;
 }
 
-JSValue* stringProtoFuncSearch(ExecState* exec, JSObject* thisObj, const ArgList& args)
+JSValue* stringProtoFuncSearch(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
     // This optimizes the common case that thisObj is a StringObject
-    UString s = thisObj->inherits(&StringObject::info) ? static_cast<StringObject*>(thisObj)->internalValue()->value() : thisObj->toString(exec);
+    UString s = thisValue->isObject(&StringObject::info) ? static_cast<StringObject*>(thisValue)->internalValue()->value() : thisValue->toThisObject(exec)->toString(exec);
 
     JSValue* a0 = args[0];
 
@@ -552,13 +590,13 @@ JSValue* stringProtoFuncSearch(ExecState* exec, JSObject* thisObj, const ArgList
     return jsNumber(exec, pos);
 }
 
-JSValue* stringProtoFuncReplace(ExecState* exec, JSObject* thisObj, const ArgList& args)
+JSValue* stringProtoFuncReplace(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
     // This optimizes the common case that thisObj is a StringObject
-    UString s = thisObj->inherits(&StringObject::info) ? static_cast<StringObject*>(thisObj)->internalValue()->value() : thisObj->toString(exec);
+    UString s = thisValue->isObject(&StringObject::info) ? static_cast<StringObject*>(thisValue)->internalValue()->value() : thisValue->toThisObject(exec)->toString(exec);
 
-    JSString* sVal = thisObj->inherits(&StringObject::info) ?
-      static_cast<StringObject*>(thisObj)->internalValue() :
+    JSString* sVal = thisValue->isObject(&StringObject::info) ?
+      static_cast<StringObject*>(thisValue)->internalValue() :
       static_cast<JSString*>(jsString(exec, s));
 
     JSValue* a0 = args[0];
@@ -567,10 +605,10 @@ JSValue* stringProtoFuncReplace(ExecState* exec, JSObject* thisObj, const ArgLis
     return replace(exec, sVal, a0, a1);
 }
 
-JSValue* stringProtoFuncSlice(ExecState* exec, JSObject* thisObj, const ArgList& args)
+JSValue* stringProtoFuncSlice(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
     // This optimizes the common case that thisObj is a StringObject
-    UString s = thisObj->inherits(&StringObject::info) ? static_cast<StringObject*>(thisObj)->internalValue()->value() : thisObj->toString(exec);
+    UString s = thisValue->isObject(&StringObject::info) ? static_cast<StringObject*>(thisValue)->internalValue()->value() : thisValue->toThisObject(exec)->toString(exec);
     int len = s.size();
 
     JSValue* a0 = args[0];
@@ -592,16 +630,15 @@ JSValue* stringProtoFuncSlice(ExecState* exec, JSObject* thisObj, const ArgList&
     return jsString(exec, "");
 }
 
-JSValue* stringProtoFuncSplit(ExecState* exec, JSObject* thisObj, const ArgList& args)
+JSValue* stringProtoFuncSplit(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
     // This optimizes the common case that thisObj is a StringObject
-    UString s = thisObj->inherits(&StringObject::info) ? static_cast<StringObject*>(thisObj)->internalValue()->value() : thisObj->toString(exec);
+    UString s = thisValue->isObject(&StringObject::info) ? static_cast<StringObject*>(thisValue)->internalValue()->value() : thisValue->toThisObject(exec)->toString(exec);
 
     JSValue* a0 = args[0];
     JSValue* a1 = args[1];
 
-    JSObject *constructor = exec->lexicalGlobalObject()->arrayConstructor();
-    JSObject* res = static_cast<JSObject*>(constructor->construct(exec, exec->emptyList()));
+    JSObject* res = constructEmptyArray(exec);
     JSValue* result = res;
     UString u = s;
     int pos;
@@ -662,10 +699,10 @@ JSValue* stringProtoFuncSplit(ExecState* exec, JSObject* thisObj, const ArgList&
     return result;
 }
 
-JSValue* stringProtoFuncSubstr(ExecState* exec, JSObject* thisObj, const ArgList& args)
+JSValue* stringProtoFuncSubstr(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
     // This optimizes the common case that thisObj is a StringObject
-    UString s = thisObj->inherits(&StringObject::info) ? static_cast<StringObject*>(thisObj)->internalValue()->value() : thisObj->toString(exec);
+    UString s = thisValue->isObject(&StringObject::info) ? static_cast<StringObject*>(thisValue)->internalValue()->value() : thisValue->toThisObject(exec)->toString(exec);
     int len = s.size();
 
     JSValue* a0 = args[0];
@@ -687,10 +724,10 @@ JSValue* stringProtoFuncSubstr(ExecState* exec, JSObject* thisObj, const ArgList
     return jsString(exec, s.substr(static_cast<int>(start), static_cast<int>(length)));
 }
 
-JSValue* stringProtoFuncSubstring(ExecState* exec, JSObject* thisObj, const ArgList& args)
+JSValue* stringProtoFuncSubstring(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
     // This optimizes the common case that thisObj is a StringObject
-    UString s = thisObj->inherits(&StringObject::info) ? static_cast<StringObject*>(thisObj)->internalValue()->value() : thisObj->toString(exec);
+    UString s = thisValue->isObject(&StringObject::info) ? static_cast<StringObject*>(thisValue)->internalValue()->value() : thisValue->toThisObject(exec)->toString(exec);
     int len = s.size();
 
     JSValue* a0 = args[0];
@@ -720,13 +757,13 @@ JSValue* stringProtoFuncSubstring(ExecState* exec, JSObject* thisObj, const ArgL
     return jsString(exec, s.substr((int)start, (int)end-(int)start));
 }
 
-JSValue* stringProtoFuncToLowerCase(ExecState* exec, JSObject* thisObj, const ArgList&)
+JSValue* stringProtoFuncToLowerCase(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
 {
     // This optimizes the common case that thisObj is a StringObject
-    UString s = thisObj->inherits(&StringObject::info) ? static_cast<StringObject*>(thisObj)->internalValue()->value() : thisObj->toString(exec);
+    UString s = thisValue->isObject(&StringObject::info) ? static_cast<StringObject*>(thisValue)->internalValue()->value() : thisValue->toThisObject(exec)->toString(exec);
     
-    JSString* sVal = thisObj->inherits(&StringObject::info)
-        ? static_cast<StringObject*>(thisObj)->internalValue()
+    JSString* sVal = thisValue->isObject(&StringObject::info)
+        ? static_cast<StringObject*>(thisValue)->internalValue()
         : static_cast<JSString*>(jsString(exec, s));
     int ssize = s.size();
     if (!ssize)
@@ -745,13 +782,13 @@ JSValue* stringProtoFuncToLowerCase(ExecState* exec, JSObject* thisObj, const Ar
     return jsString(exec, UString(buffer.releaseBuffer(), length, false));
 }
 
-JSValue* stringProtoFuncToUpperCase(ExecState* exec, JSObject* thisObj, const ArgList&)
+JSValue* stringProtoFuncToUpperCase(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
 {
     // This optimizes the common case that thisObj is a StringObject
-    UString s = thisObj->inherits(&StringObject::info) ? static_cast<StringObject*>(thisObj)->internalValue()->value() : thisObj->toString(exec);
+    UString s = thisValue->isObject(&StringObject::info) ? static_cast<StringObject*>(thisValue)->internalValue()->value() : thisValue->toThisObject(exec)->toString(exec);
 
-    JSString* sVal = thisObj->inherits(&StringObject::info)
-        ? static_cast<StringObject*>(thisObj)->internalValue()
+    JSString* sVal = thisValue->isObject(&StringObject::info)
+        ? static_cast<StringObject*>(thisValue)->internalValue()
         : static_cast<JSString*>(jsString(exec, s));
     int ssize = s.size();
     if (!ssize)
@@ -770,14 +807,14 @@ JSValue* stringProtoFuncToUpperCase(ExecState* exec, JSObject* thisObj, const Ar
     return jsString(exec, UString(buffer.releaseBuffer(), length, false));
 }
 
-JSValue* stringProtoFuncToLocaleLowerCase(ExecState* exec, JSObject* thisObj, const ArgList&)
+JSValue* stringProtoFuncToLocaleLowerCase(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
 {
     // This optimizes the common case that thisObj is a StringObject
-    UString s = thisObj->inherits(&StringObject::info) ? static_cast<StringObject*>(thisObj)->internalValue()->value() : thisObj->toString(exec);
+    UString s = thisValue->isObject(&StringObject::info) ? static_cast<StringObject*>(thisValue)->internalValue()->value() : thisValue->toThisObject(exec)->toString(exec);
     
     // FIXME: See http://www.unicode.org/Public/UNIDATA/SpecialCasing.txt for locale-sensitive mappings that aren't implemented.
-    JSString* sVal = thisObj->inherits(&StringObject::info)
-        ? static_cast<StringObject*>(thisObj)->internalValue()
+    JSString* sVal = thisValue->isObject(&StringObject::info)
+        ? static_cast<StringObject*>(thisValue)->internalValue()
         : static_cast<JSString*>(jsString(exec, s));
     int ssize = s.size();
     if (!ssize)
@@ -796,13 +833,13 @@ JSValue* stringProtoFuncToLocaleLowerCase(ExecState* exec, JSObject* thisObj, co
     return jsString(exec, UString(buffer.releaseBuffer(), length, false));
 }
 
-JSValue* stringProtoFuncToLocaleUpperCase(ExecState* exec, JSObject* thisObj, const ArgList&)
+JSValue* stringProtoFuncToLocaleUpperCase(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
 {
     // This optimizes the common case that thisObj is a StringObject
-    UString s = thisObj->inherits(&StringObject::info) ? static_cast<StringObject*>(thisObj)->internalValue()->value() : thisObj->toString(exec);
+    UString s = thisValue->isObject(&StringObject::info) ? static_cast<StringObject*>(thisValue)->internalValue()->value() : thisValue->toThisObject(exec)->toString(exec);
 
-    JSString* sVal = thisObj->inherits(&StringObject::info)
-        ? static_cast<StringObject*>(thisObj)->internalValue()
+    JSString* sVal = thisValue->isObject(&StringObject::info)
+        ? static_cast<StringObject*>(thisValue)->internalValue()
         : static_cast<JSString*>(jsString(exec, s));
     int ssize = s.size();
     if (!ssize)
@@ -821,177 +858,170 @@ JSValue* stringProtoFuncToLocaleUpperCase(ExecState* exec, JSObject* thisObj, co
     return jsString(exec, UString(buffer.releaseBuffer(), length, false));
 }
 
-JSValue* stringProtoFuncLocaleCompare(ExecState* exec, JSObject* thisObj, const ArgList& args)
+JSValue* stringProtoFuncLocaleCompare(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
     if (args.size() < 1)
       return jsNumber(exec, 0);
 
     // This optimizes the common case that thisObj is a StringObject
-    UString s = thisObj->inherits(&StringObject::info) ? static_cast<StringObject*>(thisObj)->internalValue()->value() : thisObj->toString(exec);
+    UString s = thisValue->isObject(&StringObject::info) ? static_cast<StringObject*>(thisValue)->internalValue()->value() : thisValue->toThisObject(exec)->toString(exec);
     JSValue* a0 = args[0];
     return jsNumber(exec, localeCompare(s, a0->toString(exec)));
 }
 
-JSValue* stringProtoFuncBig(ExecState* exec, JSObject* thisObj, const ArgList&)
+JSValue* stringProtoFuncBig(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
 {
     // This optimizes the common case that thisObj is a StringObject
-    UString s = thisObj->inherits(&StringObject::info) ? static_cast<StringObject*>(thisObj)->internalValue()->value() : thisObj->toString(exec);
+    UString s = thisValue->isObject(&StringObject::info) ? static_cast<StringObject*>(thisValue)->internalValue()->value() : thisValue->toThisObject(exec)->toString(exec);
     return jsString(exec, "<big>" + s + "</big>");
 }
 
-JSValue* stringProtoFuncSmall(ExecState* exec, JSObject* thisObj, const ArgList&)
+JSValue* stringProtoFuncSmall(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
 {
     // This optimizes the common case that thisObj is a StringObject
-    UString s = thisObj->inherits(&StringObject::info) ? static_cast<StringObject*>(thisObj)->internalValue()->value() : thisObj->toString(exec);
+    UString s = thisValue->isObject(&StringObject::info) ? static_cast<StringObject*>(thisValue)->internalValue()->value() : thisValue->toThisObject(exec)->toString(exec);
     return jsString(exec, "<small>" + s + "</small>");
 }
 
-JSValue* stringProtoFuncBlink(ExecState* exec, JSObject* thisObj, const ArgList&)
+JSValue* stringProtoFuncBlink(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
 {
     // This optimizes the common case that thisObj is a StringObject
-    UString s = thisObj->inherits(&StringObject::info) ? static_cast<StringObject*>(thisObj)->internalValue()->value() : thisObj->toString(exec);
+    UString s = thisValue->isObject(&StringObject::info) ? static_cast<StringObject*>(thisValue)->internalValue()->value() : thisValue->toThisObject(exec)->toString(exec);
     return jsString(exec, "<blink>" + s + "</blink>");
 }
 
-JSValue* stringProtoFuncBold(ExecState* exec, JSObject* thisObj, const ArgList&)
+JSValue* stringProtoFuncBold(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
 {
     // This optimizes the common case that thisObj is a StringObject
-    UString s = thisObj->inherits(&StringObject::info) ? static_cast<StringObject*>(thisObj)->internalValue()->value() : thisObj->toString(exec);
+    UString s = thisValue->isObject(&StringObject::info) ? static_cast<StringObject*>(thisValue)->internalValue()->value() : thisValue->toThisObject(exec)->toString(exec);
     return jsString(exec, "<b>" + s + "</b>");
 }
 
-JSValue* stringProtoFuncFixed(ExecState* exec, JSObject* thisObj, const ArgList&)
+JSValue* stringProtoFuncFixed(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
 {
     // This optimizes the common case that thisObj is a StringObject
-    UString s = thisObj->inherits(&StringObject::info) ? static_cast<StringObject*>(thisObj)->internalValue()->value() : thisObj->toString(exec);
+    UString s = thisValue->isObject(&StringObject::info) ? static_cast<StringObject*>(thisValue)->internalValue()->value() : thisValue->toThisObject(exec)->toString(exec);
     return jsString(exec, "<tt>" + s + "</tt>");
 }
 
-JSValue* stringProtoFuncItalics(ExecState* exec, JSObject* thisObj, const ArgList&)
+JSValue* stringProtoFuncItalics(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
 {
     // This optimizes the common case that thisObj is a StringObject
-    UString s = thisObj->inherits(&StringObject::info) ? static_cast<StringObject*>(thisObj)->internalValue()->value() : thisObj->toString(exec);
+    UString s = thisValue->isObject(&StringObject::info) ? static_cast<StringObject*>(thisValue)->internalValue()->value() : thisValue->toThisObject(exec)->toString(exec);
     return jsString(exec, "<i>" + s + "</i>");
 }
 
-JSValue* stringProtoFuncStrike(ExecState* exec, JSObject* thisObj, const ArgList&)
+JSValue* stringProtoFuncStrike(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
 {
     // This optimizes the common case that thisObj is a StringObject
-    UString s = thisObj->inherits(&StringObject::info) ? static_cast<StringObject*>(thisObj)->internalValue()->value() : thisObj->toString(exec);
+    UString s = thisValue->isObject(&StringObject::info) ? static_cast<StringObject*>(thisValue)->internalValue()->value() : thisValue->toThisObject(exec)->toString(exec);
     return jsString(exec, "<strike>" + s + "</strike>");
 }
 
-JSValue* stringProtoFuncSub(ExecState* exec, JSObject* thisObj, const ArgList&)
+JSValue* stringProtoFuncSub(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
 {
     // This optimizes the common case that thisObj is a StringObject
-    UString s = thisObj->inherits(&StringObject::info) ? static_cast<StringObject*>(thisObj)->internalValue()->value() : thisObj->toString(exec);
+    UString s = thisValue->isObject(&StringObject::info) ? static_cast<StringObject*>(thisValue)->internalValue()->value() : thisValue->toThisObject(exec)->toString(exec);
     return jsString(exec, "<sub>" + s + "</sub>");
 }
 
-JSValue* stringProtoFuncSup(ExecState* exec, JSObject* thisObj, const ArgList&)
+JSValue* stringProtoFuncSup(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
 {
     // This optimizes the common case that thisObj is a StringObject
-    UString s = thisObj->inherits(&StringObject::info) ? static_cast<StringObject*>(thisObj)->internalValue()->value() : thisObj->toString(exec);
+    UString s = thisValue->isObject(&StringObject::info) ? static_cast<StringObject*>(thisValue)->internalValue()->value() : thisValue->toThisObject(exec)->toString(exec);
     return jsString(exec, "<sup>" + s + "</sup>");
 }
 
-JSValue* stringProtoFuncFontcolor(ExecState* exec, JSObject* thisObj, const ArgList& args)
+JSValue* stringProtoFuncFontcolor(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
     // This optimizes the common case that thisObj is a StringObject
-    UString s = thisObj->inherits(&StringObject::info) ? static_cast<StringObject*>(thisObj)->internalValue()->value() : thisObj->toString(exec);
+    UString s = thisValue->isObject(&StringObject::info) ? static_cast<StringObject*>(thisValue)->internalValue()->value() : thisValue->toThisObject(exec)->toString(exec);
     JSValue* a0 = args[0];
     return jsString(exec, "<font color=\"" + a0->toString(exec) + "\">" + s + "</font>");
 }
 
-JSValue* stringProtoFuncFontsize(ExecState* exec, JSObject* thisObj, const ArgList& args)
+JSValue* stringProtoFuncFontsize(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
     // This optimizes the common case that thisObj is a StringObject
-    UString s = thisObj->inherits(&StringObject::info) ? static_cast<StringObject*>(thisObj)->internalValue()->value() : thisObj->toString(exec);
+    UString s = thisValue->isObject(&StringObject::info) ? static_cast<StringObject*>(thisValue)->internalValue()->value() : thisValue->toThisObject(exec)->toString(exec);
     JSValue* a0 = args[0];
     return jsString(exec, "<font size=\"" + a0->toString(exec) + "\">" + s + "</font>");
 }
 
-JSValue* stringProtoFuncAnchor(ExecState* exec, JSObject* thisObj, const ArgList& args)
+JSValue* stringProtoFuncAnchor(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
     // This optimizes the common case that thisObj is a StringObject
-    UString s = thisObj->inherits(&StringObject::info) ? static_cast<StringObject*>(thisObj)->internalValue()->value() : thisObj->toString(exec);
+    UString s = thisValue->isObject(&StringObject::info) ? static_cast<StringObject*>(thisValue)->internalValue()->value() : thisValue->toThisObject(exec)->toString(exec);
     JSValue* a0 = args[0];
     return jsString(exec, "<a name=\"" + a0->toString(exec) + "\">" + s + "</a>");
 }
 
-JSValue* stringProtoFuncLink(ExecState* exec, JSObject* thisObj, const ArgList& args)
+JSValue* stringProtoFuncLink(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
 {
     // This optimizes the common case that thisObj is a StringObject
-    UString s = thisObj->inherits(&StringObject::info) ? static_cast<StringObject*>(thisObj)->internalValue()->value() : thisObj->toString(exec);
+    UString s = thisValue->isObject(&StringObject::info) ? static_cast<StringObject*>(thisValue)->internalValue()->value() : thisValue->toThisObject(exec)->toString(exec);
     JSValue* a0 = args[0];
     return jsString(exec, "<a href=\"" + a0->toString(exec) + "\">" + s + "</a>");
 }
 
 // ------------------------------ StringConstructor ------------------------------
 
+static JSValue* stringFromCharCode(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+{
+    UString s;
+    if (args.size()) {
+        UChar* buf = static_cast<UChar*>(fastMalloc(args.size() * sizeof(UChar)));
+        UChar* p = buf;
+        ArgList::const_iterator end = args.end();
+        for (ArgList::const_iterator it = args.begin(); it != end; ++it)
+          *p++ = static_cast<UChar>((*it)->toUInt32(exec));
+        s = UString(buf, args.size(), false);
+    } else
+        s = "";
+
+    return jsString(exec, s);
+}
+
 StringConstructor::StringConstructor(ExecState* exec, FunctionPrototype* funcProto, StringPrototype* stringProto)
   : InternalFunction(funcProto, Identifier(exec, stringProto->classInfo()->className))
 {
   // ECMA 15.5.3.1 String.prototype
-  putDirect(exec->propertyNames().prototype, stringProto, DontEnum|DontDelete|ReadOnly);
+  putDirect(exec->propertyNames().prototype, stringProto, ReadOnly | DontEnum | DontDelete);
 
-  putDirectFunction(new (exec) StringConstructorFunction(exec, funcProto, exec->propertyNames().fromCharCode), DontEnum);
+  // ECMA 15.5.3.2 fromCharCode()
+  putDirectFunction(new (exec) PrototypeFunction(exec, funcProto, 1, exec->propertyNames().fromCharCode, stringFromCharCode), DontEnum);
 
   // no. of arguments for constructor
-  putDirect(exec->propertyNames().length, jsNumber(exec, 1), ReadOnly|DontDelete|DontEnum);
-}
-
-
-ConstructType StringConstructor::getConstructData(ConstructData&)
-{
-    return ConstructTypeNative;
+  putDirect(exec->propertyNames().length, jsNumber(exec, 1), ReadOnly | DontEnum | DontDelete);
 }
 
 // ECMA 15.5.2
-JSObject* StringConstructor::construct(ExecState* exec, const ArgList& args)
+static JSObject* constructWithStringConstructor(ExecState* exec, JSObject*, const ArgList& args)
 {
-  JSObject* proto = exec->lexicalGlobalObject()->stringPrototype();
-  if (!args.size())
-    return new (exec) StringObject(exec, proto);
-  return new (exec) StringObject(exec, proto, args[0]->toString(exec));
+    JSObject* prototype = exec->lexicalGlobalObject()->stringPrototype();
+    if (args.isEmpty())
+        return new (exec) StringObject(exec, prototype);
+    return new (exec) StringObject(exec, prototype, args[0]->toString(exec));
 }
 
-// ECMA 15.5.1
-JSValue *StringConstructor::callAsFunction(ExecState *exec, JSObject* /*thisObj*/, const ArgList &args)
+ConstructType StringConstructor::getConstructData(ConstructData& constructData)
 {
-  if (args.isEmpty())
-    return jsString(exec, "");
-  else {
-    JSValue *v = args[0];
-    return jsString(exec, v->toString(exec));
-  }
+    constructData.native.function = constructWithStringConstructor;
+    return ConstructTypeNative;
 }
 
-// ------------------------------ StringConstructorFunction --------------------------
-
-// ECMA 15.5.3.2 fromCharCode()
-StringConstructorFunction::StringConstructorFunction(ExecState* exec, FunctionPrototype* funcProto, const Identifier& name)
-  : InternalFunction(funcProto, name)
+// ECMA 15.5.1
+static JSValue* callStringConstructor(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
 {
-  putDirect(exec->propertyNames().length, jsNumber(exec, 1), DontDelete|ReadOnly|DontEnum);
+    if (args.isEmpty())
+        return jsString(exec, "");
+    return jsString(exec, args[0]->toString(exec));
 }
 
-JSValue *StringConstructorFunction::callAsFunction(ExecState *exec, JSObject* /*thisObj*/, const ArgList &args)
+CallType StringConstructor::getCallData(CallData& callData)
 {
-  UString s;
-  if (args.size()) {
-    UChar *buf = static_cast<UChar *>(fastMalloc(args.size() * sizeof(UChar)));
-    UChar *p = buf;
-    ArgList::const_iterator end = args.end();
-    for (ArgList::const_iterator it = args.begin(); it != end; ++it) {
-      unsigned short u = static_cast<unsigned short>((*it)->toUInt32(exec));
-      *p++ = UChar(u);
-    }
-    s = UString(buf, args.size(), false);
-  } else
-    s = "";
-
-  return jsString(exec, s);
+    callData.native.function = callStringConstructor;
+    return CallTypeNative;
 }
 
 } // namespace KJS
index a46b261a33b218724c59a5dec2b79190b3a2edfb..10c408311334ec9391d9df4ecde07fce6da63336 100644 (file)
@@ -76,47 +76,6 @@ namespace KJS {
     static const ClassInfo info;
   };
 
-  /**
-   * @internal
-   *
-   * Functions to implement all methods that are properties of the
-   * String.prototype object
-   */
-
-  JSValue* stringProtoFuncToString(ExecState*, JSObject*, const ArgList&);
-  JSValue* stringProtoFuncValueOf(ExecState*, JSObject*, const ArgList&);
-  JSValue* stringProtoFuncCharAt(ExecState*, JSObject*, const ArgList&);
-  JSValue* stringProtoFuncCharCodeAt(ExecState*, JSObject*, const ArgList&);
-  JSValue* stringProtoFuncConcat(ExecState*, JSObject*, const ArgList&);
-  JSValue* stringProtoFuncIndexOf(ExecState*, JSObject*, const ArgList&);
-  JSValue* stringProtoFuncLastIndexOf(ExecState*, JSObject*, const ArgList&);
-  JSValue* stringProtoFuncMatch(ExecState*, JSObject*, const ArgList&);
-  JSValue* stringProtoFuncReplace(ExecState*, JSObject*, const ArgList&);
-  JSValue* stringProtoFuncSearch(ExecState*, JSObject*, const ArgList&);
-  JSValue* stringProtoFuncSlice(ExecState*, JSObject*, const ArgList&);
-  JSValue* stringProtoFuncSplit(ExecState*, JSObject*, const ArgList&);
-  JSValue* stringProtoFuncSubstr(ExecState*, JSObject*, const ArgList&);
-  JSValue* stringProtoFuncSubstring(ExecState*, JSObject*, const ArgList&);
-  JSValue* stringProtoFuncToLowerCase(ExecState*, JSObject*, const ArgList&);
-  JSValue* stringProtoFuncToUpperCase(ExecState*, JSObject*, const ArgList&);
-  JSValue* stringProtoFuncToLocaleLowerCase(ExecState*, JSObject*, const ArgList&);
-  JSValue* stringProtoFuncToLocaleUpperCase(ExecState*, JSObject*, const ArgList&);
-  JSValue* stringProtoFuncLocaleCompare(ExecState*, JSObject*, const ArgList&);
-
-  JSValue* stringProtoFuncBig(ExecState*, JSObject*, const ArgList&);
-  JSValue* stringProtoFuncSmall(ExecState*, JSObject*, const ArgList&);
-  JSValue* stringProtoFuncBlink(ExecState*, JSObject*, const ArgList&);
-  JSValue* stringProtoFuncBold(ExecState*, JSObject*, const ArgList&);
-  JSValue* stringProtoFuncFixed(ExecState*, JSObject*, const ArgList&);
-  JSValue* stringProtoFuncItalics(ExecState*, JSObject*, const ArgList&);
-  JSValue* stringProtoFuncStrike(ExecState*, JSObject*, const ArgList&);
-  JSValue* stringProtoFuncSub(ExecState*, JSObject*, const ArgList&);
-  JSValue* stringProtoFuncSup(ExecState*, JSObject*, const ArgList&);
-  JSValue* stringProtoFuncFontcolor(ExecState*, JSObject*, const ArgList&);
-  JSValue* stringProtoFuncFontsize(ExecState*, JSObject*, const ArgList&);
-  JSValue* stringProtoFuncAnchor(ExecState*, JSObject*, const ArgList&);
-  JSValue* stringProtoFuncLink(ExecState*, JSObject*, const ArgList&);
-
   /**
    * @internal
    *
@@ -125,11 +84,8 @@ namespace KJS {
   class StringConstructor : public InternalFunction {
   public:
     StringConstructor(ExecState*, FunctionPrototype*, StringPrototype*);
-
     virtual ConstructType getConstructData(ConstructData&);
-    virtual JSObject* construct(ExecState*, const ArgList&);
-
-    virtual JSValue* callAsFunction(ExecState*, JSObject* thisObj, const ArgList& args);
+    virtual CallType getCallData(CallData&);
   };
 
   /**
@@ -141,7 +97,7 @@ namespace KJS {
   class StringConstructorFunction : public InternalFunction {
   public:
     StringConstructorFunction(ExecState*, FunctionPrototype*, const Identifier&);
-    virtual JSValue* callAsFunction(ExecState*, JSObject* thisObj, const ArgList& args);
+    virtual CallType getCallData(CallData&);
   };
 
 } // namespace
index e755902b326e6e0aa13b72c64b8f4671515dc4d0..425b183d2b8808501d0e139dd2c7fd81cd79125d 100644 (file)
@@ -1,3 +1,11 @@
+2008-06-23  Darin Adler  <darin@apple.com>
+
+        Reviewed by Geoff.
+
+        * JSValueWrapper.cpp:
+        (JSValueWrapper::JSObjectCallFunction): Updated to use getCallData and call instead
+        of the old callAsFunction.
+
 2008-06-17  Alexey Proskuryakov  <ap@webkit.org>
 
         Reviewed by Darin.
index 65741b40f3f3d25327d14b2c23f5b097061908b6..ac75977a7783fd5aabd7a0343fc7910cd3fa937a 100644 (file)
@@ -160,7 +160,11 @@ JSObjectRef JSValueWrapper::JSObjectCallFunction(void *data, JSObjectRef thisObj
             listArgs.append(kgsArg);
         }
 
-        JSValue *resultValue = objValue->callAsFunction(exec, ksjThisObj, listArgs);
+        CallData callData;
+        CallType callType = objValue->getCallData(callData);
+        if (callType == CallTypeNone)
+            return 0;
+        JSValue* resultValue = call(exec, objValue, callType, callData, ksjThisObj, listArgs);
         JSValueWrapper* wrapperValue = new JSValueWrapper(resultValue);
         JSObjectCallBacks callBacks;
         GetJSObectCallBacks(callBacks);
index f6c6b911512a5d7ef0c32f4894ade821a7c47547..69138ee3fef49b93e555a65a552eefb4f1935352 100644 (file)
@@ -1,3 +1,207 @@
+2008-06-23  Darin Adler  <darin@apple.com>
+
+        Reviewed by Geoff.
+