Ignore:
Timestamp:
Oct 24, 2007, 11:38:35 PM (18 years ago)
Author:
eseidel
Message:

2007-10-24 Eric Seidel <[email protected]>

Reviewed by Maciej.


Add a JSGlobalObject class and remove the InterpreterMap
http://bugs.webkit.org/show_bug.cgi?id=15681


This required making JSCallbackObject a template class to allow for
JSGlobalObjects with JSCallbackObject functionality.


SunSpider claims this was a 0.5% speedup.

  • API/JSCallbackObject.cpp: (KJS::):
  • API/JSCallbackObject.h:
  • API/JSCallbackObjectFunctions.h: Copied from API/JSCallbackObject.cpp. (KJS::::JSCallbackObject): (KJS::::init): (KJS::::~JSCallbackObject): (KJS::::initializeIfNeeded): (KJS::::className): (KJS::::getOwnPropertySlot): (KJS::::put): (KJS::::deleteProperty): (KJS::::implementsConstruct): (KJS::::construct): (KJS::::implementsHasInstance): (KJS::::hasInstance): (KJS::::implementsCall): (KJS::::callAsFunction): (KJS::::getPropertyNames): (KJS::::toNumber): (KJS::::toString): (KJS::::setPrivate): (KJS::::getPrivate): (KJS::::inherits): (KJS::::cachedValueGetter): (KJS::::staticValueGetter): (KJS::::staticFunctionGetter): (KJS::::callbackGetter):
  • API/JSClassRef.cpp: (OpaqueJSClass::prototype):
  • API/JSContextRef.cpp: (JSGlobalContextCreate):
  • API/JSObjectRef.cpp: (JSObjectMake): (JSObjectGetPrivate): (JSObjectSetPrivate):
  • API/JSValueRef.cpp: (JSValueIsObjectOfClass):
  • JavaScriptCore.exp:
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • bindings/c/c_utility.cpp: (KJS::Bindings::convertValueToNPVariant):
  • bindings/jni/jni_jsobject.cpp:
  • bindings/objc/objc_utility.mm: (KJS::Bindings::convertValueToObjcValue):
  • kjs/Context.cpp: (KJS::Context::Context):
  • kjs/ExecState.cpp: (KJS::ExecState::lexicalInterpreter):
  • kjs/JSGlobalObject.h: Added. (KJS::JSGlobalObject::JSGlobalObject): (KJS::JSGlobalObject::isGlobalObject): (KJS::JSGlobalObject::interpreter): (KJS::JSGlobalObject::setInterpreter):
  • kjs/array_instance.cpp:
  • kjs/context.h:
  • kjs/function.cpp: (KJS::FunctionImp::callAsFunction): (KJS::GlobalFuncImp::callAsFunction):
  • kjs/interpreter.cpp: (KJS::Interpreter::Interpreter): (KJS::Interpreter::init): (KJS::Interpreter::~Interpreter): (KJS::Interpreter::globalObject): (KJS::Interpreter::initGlobalObject): (KJS::Interpreter::evaluate):
  • kjs/interpreter.h:
  • kjs/lookup.h: (KJS::cacheGlobalObject):
  • kjs/object.h: (KJS::JSObject::isGlobalObject):
  • kjs/testkjs.cpp:
File:
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/API/JSCallbackObjectFunctions.h

    r27021 r27022  
    22/*
    33 * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
     4 * Copyright (C) 2007 Eric Seidel <[email protected]>
    45 *
    56 * Redistribution and use in source and binary forms, with or without
     
    2627
    2728#include <wtf/Platform.h>
    28 #include "JSCallbackObject.h"
    29 
    3029#include "APICast.h"
    3130#include "JSCallbackFunction.h"
    3231#include "JSClassRef.h"
    3332#include "JSObjectRef.h"
     33#include "JSGlobalObject.h"
    3434#include "JSStringRef.h"
    3535#include "PropertyNameArray.h"
     
    3939namespace KJS {
    4040
    41 const ClassInfo JSCallbackObject::info = { "CallbackObject", 0, 0, 0 };
    42 
    43 JSCallbackObject::JSCallbackObject(ExecState* exec, JSClassRef jsClass, JSValue* prototype, void* data)
    44     : JSObject(prototype)
     41template <class Base>
     42JSCallbackObject<Base>::JSCallbackObject(ExecState* exec, JSClassRef jsClass, JSValue* prototype, void* data)
     43    : Base(prototype)
    4544    , m_class(0)
    4645    , m_isInitialized(false)
     
    4948}
    5049
    51 void JSCallbackObject::init(ExecState* exec, JSClassRef jsClass, void* data)
     50template <class Base>
     51void JSCallbackObject<Base>::init(ExecState* exec, JSClassRef jsClass, void* data)
    5252{
    5353    m_privateData = data;
     
    5656    if (oldClass)
    5757        JSClassRelease(oldClass);
    58 
     58   
    5959    if (!exec)
    6060        return;
    61 
     61   
    6262    Vector<JSObjectInitializeCallback, 16> initRoutines;
    6363    do {
     
    7575}
    7676
    77 JSCallbackObject::~JSCallbackObject()
     77template <class Base>
     78JSCallbackObject<Base>::~JSCallbackObject()
    7879{
    7980    JSObjectRef thisRef = toRef(this);
     
    8384            finalize(thisRef);
    8485        }
    85    
     86           
    8687    JSClassRelease(m_class);
    8788}
    8889
    89 void JSCallbackObject::initializeIfNeeded(ExecState* exec)
     90template <class Base>
     91void JSCallbackObject<Base>::initializeIfNeeded(ExecState* exec)
    9092{
    9193    if (m_isInitialized)
     
    9496}
    9597
    96 UString JSCallbackObject::className() const
     98template <class Base>
     99UString JSCallbackObject<Base>::className() const
    97100{
    98101    if (!m_class->className.isNull())
     
    102105}
    103106
    104 bool JSCallbackObject::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
     107template <class Base>
     108bool JSCallbackObject<Base>::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
    105109{
    106110    JSContextRef ctx = toRef(exec);
    107111    JSObjectRef thisRef = toRef(this);
    108112    JSStringRef propertyNameRef = toRef(propertyName.ustring().rep());
    109 
     113   
    110114    for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass) {
    111115        // optional optimization to bypass getProperty in cases when we only need to know if the property exists
     
    126130            }
    127131        }
    128 
     132       
    129133        if (OpaqueJSClass::StaticValuesTable* staticValues = jsClass->staticValues) {
    130134            if (staticValues->contains(propertyName.ustring().rep())) {
     
    141145        }
    142146    }
    143 
     147   
    144148    return JSObject::getOwnPropertySlot(exec, propertyName, slot);
    145149}
    146150
    147 bool JSCallbackObject::getOwnPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot)
     151template <class Base>
     152bool JSCallbackObject<Base>::getOwnPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot)
    148153{
    149154    return getOwnPropertySlot(exec, Identifier::from(propertyName), slot);
    150155}
    151156
    152 void JSCallbackObject::put(ExecState* exec, const Identifier& propertyName, JSValue* value, int attr)
     157template <class Base>
     158void JSCallbackObject<Base>::put(ExecState* exec, const Identifier& propertyName, JSValue* value, int attr)
    153159{
    154160    JSContextRef ctx = toRef(exec);
     
    156162    JSStringRef propertyNameRef = toRef(propertyName.ustring().rep());
    157163    JSValueRef valueRef = toRef(value);
    158 
     164   
    159165    for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass) {
    160166        if (JSObjectSetPropertyCallback setProperty = jsClass->setProperty) {
     
    163169                return;
    164170        }
    165    
     171       
    166172        if (OpaqueJSClass::StaticValuesTable* staticValues = jsClass->staticValues) {
    167173            if (StaticValueEntry* entry = staticValues->get(propertyName.ustring().rep())) {
     
    181187                if (entry->attributes & kJSPropertyAttributeReadOnly)
    182188                    return;
    183                 putDirect(propertyName, value, attr); // put as override property
     189                JSCallbackObject<Base>::putDirect(propertyName, value, attr); // put as override property
    184190                return;
    185191            }
    186192        }
    187193    }
    188 
     194   
    189195    return JSObject::put(exec, propertyName, value, attr);
    190196}
    191197
    192 void JSCallbackObject::put(ExecState* exec, unsigned propertyName, JSValue* value, int attr)
     198template <class Base>
     199void JSCallbackObject<Base>::put(ExecState* exec, unsigned propertyName, JSValue* value, int attr)
    193200{
    194201    return put(exec, Identifier::from(propertyName), value, attr);
    195202}
    196203
    197 bool JSCallbackObject::deleteProperty(ExecState* exec, const Identifier& propertyName)
     204template <class Base>
     205bool JSCallbackObject<Base>::deleteProperty(ExecState* exec, const Identifier& propertyName)
    198206{
    199207    JSContextRef ctx = toRef(exec);
     
    207215                return true;
    208216        }
    209 
     217       
    210218        if (OpaqueJSClass::StaticValuesTable* staticValues = jsClass->staticValues) {
    211219            if (StaticValueEntry* entry = staticValues->get(propertyName.ustring().rep())) {
     
    224232        }
    225233    }
    226 
     234   
    227235    return JSObject::deleteProperty(exec, propertyName);
    228236}
    229237
    230 bool JSCallbackObject::deleteProperty(ExecState* exec, unsigned propertyName)
     238template <class Base>
     239bool JSCallbackObject<Base>::deleteProperty(ExecState* exec, unsigned propertyName)
    231240{
    232241    return deleteProperty(exec, Identifier::from(propertyName));
    233242}
    234243
    235 bool JSCallbackObject::implementsConstruct() const
     244template <class Base>
     245bool JSCallbackObject<Base>::implementsConstruct() const
    236246{
    237247    for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass)
    238248        if (jsClass->callAsConstructor)
    239249            return true;
    240 
     250   
    241251    return false;
    242252}
    243253
    244 JSObject* JSCallbackObject::construct(ExecState* exec, const List& args)
     254template <class Base>
     255JSObject* JSCallbackObject<Base>::construct(ExecState* exec, const List& args)
    245256{
    246257    JSContextRef execRef = toRef(exec);
     
    262273}
    263274
    264 bool JSCallbackObject::implementsHasInstance() const
     275template <class Base>
     276bool JSCallbackObject<Base>::implementsHasInstance() const
    265277{
    266278    for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass)
    267279        if (jsClass->hasInstance)
    268280            return true;
    269 
     281   
    270282    return false;
    271283}
    272284
    273 bool JSCallbackObject::hasInstance(ExecState *exec, JSValue *value)
     285template <class Base>
     286bool JSCallbackObject<Base>::hasInstance(ExecState *exec, JSValue *value)
    274287{
    275288    JSContextRef execRef = toRef(exec);
    276289    JSObjectRef thisRef = toRef(this);
    277 
     290   
    278291    for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass)
    279292        if (JSObjectHasInstanceCallback hasInstance = jsClass->hasInstance) {
     
    281294            return hasInstance(execRef, thisRef, toRef(value), toRef(exec->exceptionSlot()));
    282295        }
    283 
    284     ASSERT(0); // implementsHasInstance should prevent us from reaching here
     296           
     297    ASSERT_NOT_REACHED(); // implementsHasInstance should prevent us from reaching here
    285298    return 0;
    286299}
    287300
    288301
    289 bool JSCallbackObject::implementsCall() const
     302template <class Base>
     303bool JSCallbackObject<Base>::implementsCall() const
    290304{
    291305    for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass)
     
    296310}
    297311
    298 JSValue* JSCallbackObject::callAsFunction(ExecState* exec, JSObject* thisObj, const List &args)
     312template <class Base>
     313JSValue* JSCallbackObject<Base>::callAsFunction(ExecState* exec, JSObject* thisObj, const List &args)
    299314{
    300315    JSContextRef execRef = toRef(exec);
    301316    JSObjectRef thisRef = toRef(this);
    302317    JSObjectRef thisObjRef = toRef(thisObj);
    303 
     318   
    304319    for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass) {
    305320        if (JSObjectCallAsFunctionCallback callAsFunction = jsClass->callAsFunction) {
     
    312327        }
    313328    }
    314 
    315     ASSERT(0); // implementsCall should prevent us from reaching here
     329   
     330    ASSERT_NOT_REACHED(); // implementsCall should prevent us from reaching here
    316331    return 0;
    317332}
    318333
    319 void JSCallbackObject::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
     334template <class Base>
     335void JSCallbackObject<Base>::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
    320336{
    321337    JSContextRef execRef = toRef(exec);
    322338    JSObjectRef thisRef = toRef(this);
    323 
     339   
    324340    for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass) {
    325341        if (JSObjectGetPropertyNamesCallback getPropertyNames = jsClass->getPropertyNames) {
     
    327343            getPropertyNames(execRef, thisRef, toRef(&propertyNames));
    328344        }
    329 
     345       
    330346        if (OpaqueJSClass::StaticValuesTable* staticValues = jsClass->staticValues) {
    331347            typedef OpaqueJSClass::StaticValuesTable::const_iterator iterator;
     
    338354            }
    339355        }
    340 
     356       
    341357        if (OpaqueJSClass::StaticFunctionsTable* staticFunctions = jsClass->staticFunctions) {
    342358            typedef OpaqueJSClass::StaticFunctionsTable::const_iterator iterator;
     
    350366        }
    351367    }
    352 
     368   
    353369    JSObject::getPropertyNames(exec, propertyNames);
    354370}
    355371
    356 double JSCallbackObject::toNumber(ExecState* exec) const
     372template <class Base>
     373double JSCallbackObject<Base>::toNumber(ExecState* exec) const
    357374{
    358375    JSContextRef ctx = toRef(exec);
    359376    JSObjectRef thisRef = toRef(this);
    360 
     377   
    361378    for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass)
    362379        if (JSObjectConvertToTypeCallback convertToType = jsClass->convertToType) {
     
    365382                return toJS(value)->getNumber();
    366383        }
    367 
     384           
    368385    return JSObject::toNumber(exec);
    369386}
    370387
    371 UString JSCallbackObject::toString(ExecState* exec) const
     388template <class Base>
     389UString JSCallbackObject<Base>::toString(ExecState* exec) const
    372390{
    373391    JSContextRef ctx = toRef(exec);
    374392    JSObjectRef thisRef = toRef(this);
    375 
     393   
    376394    for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass)
    377395        if (JSObjectConvertToTypeCallback convertToType = jsClass->convertToType) {
     
    380398                return toJS(value)->getString();
    381399        }
    382 
     400           
    383401    return JSObject::toString(exec);
    384402}
    385403
    386 void JSCallbackObject::setPrivate(void* data)
     404template <class Base>
     405void JSCallbackObject<Base>::setPrivate(void* data)
    387406{
    388407    m_privateData = data;
    389408}
    390409
    391 void* JSCallbackObject::getPrivate()
     410template <class Base>
     411void* JSCallbackObject<Base>::getPrivate()
    392412{
    393413    return m_privateData;
    394414}
    395415
    396 bool JSCallbackObject::inherits(JSClassRef c) const
     416template <class Base>
     417bool JSCallbackObject<Base>::inherits(JSClassRef c) const
    397418{
    398419    for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass)
    399420        if (jsClass == c)
    400421            return true;
    401 
     422   
    402423    return false;
    403424}
    404425
    405 JSValue* JSCallbackObject::cachedValueGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot& slot)
     426template <class Base>
     427JSValue* JSCallbackObject<Base>::cachedValueGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot& slot)
    406428{
    407429    JSValue* v = slot.slotBase();
     
    410432}
    411433
    412 JSValue* JSCallbackObject::staticValueGetter(ExecState* exec, JSObject*, const Identifier& propertyName, const PropertySlot& slot)
     434template <class Base>
     435JSValue* JSCallbackObject<Base>::staticValueGetter(ExecState* exec, JSObject*, const Identifier& propertyName, const PropertySlot& slot)
    413436{
    414437    ASSERT(slot.slotBase()->inherits(&JSCallbackObject::info));
    415438    JSCallbackObject* thisObj = static_cast<JSCallbackObject*>(slot.slotBase());
    416 
     439   
    417440    JSObjectRef thisRef = toRef(thisObj);
    418441    JSStringRef propertyNameRef = toRef(propertyName.ustring().rep());
    419 
     442   
    420443    for (JSClassRef jsClass = thisObj->m_class; jsClass; jsClass = jsClass->parentClass)
    421444        if (OpaqueJSClass::StaticValuesTable* staticValues = jsClass->staticValues)
     
    426449                        return toJS(value);
    427450                }
    428 
     451                   
    429452    return throwError(exec, ReferenceError, "Static value property defined with NULL getProperty callback.");
    430453}
    431454
    432 JSValue* JSCallbackObject::staticFunctionGetter(ExecState* exec, JSObject*, const Identifier& propertyName, const PropertySlot& slot)
     455template <class Base>
     456JSValue* JSCallbackObject<Base>::staticFunctionGetter(ExecState* exec, JSObject*, const Identifier& propertyName, const PropertySlot& slot)
    433457{
    434458    ASSERT(slot.slotBase()->inherits(&JSCallbackObject::info));
    435459    JSCallbackObject* thisObj = static_cast<JSCallbackObject*>(slot.slotBase());
    436 
     460   
    437461    if (JSValue* cachedOrOverrideValue = thisObj->getDirect(propertyName))
    438462        return cachedOrOverrideValue;
    439 
     463   
    440464    for (JSClassRef jsClass = thisObj->m_class; jsClass; jsClass = jsClass->parentClass) {
    441465        if (OpaqueJSClass::StaticFunctionsTable* staticFunctions = jsClass->staticFunctions) {
     
    449473        }
    450474    }
    451 
     475   
    452476    return throwError(exec, ReferenceError, "Static function property defined with NULL callAsFunction callback.");
    453477}
    454478
    455 JSValue* JSCallbackObject::callbackGetter(ExecState* exec, JSObject*, const Identifier& propertyName, const PropertySlot& slot)
     479template <class Base>
     480JSValue* JSCallbackObject<Base>::callbackGetter(ExecState* exec, JSObject*, const Identifier& propertyName, const PropertySlot& slot)
    456481{
    457482    ASSERT(slot.slotBase()->inherits(&JSCallbackObject::info));
    458483    JSCallbackObject* thisObj = static_cast<JSCallbackObject*>(slot.slotBase());
    459 
     484   
    460485    JSObjectRef thisRef = toRef(thisObj);
    461486    JSStringRef propertyNameRef = toRef(propertyName.ustring().rep());
    462 
     487   
    463488    for (JSClassRef jsClass = thisObj->m_class; jsClass; jsClass = jsClass->parentClass)
    464489        if (JSObjectGetPropertyCallback getProperty = jsClass->getProperty) {
     
    467492                return toJS(value);
    468493        }
    469 
     494           
    470495    return throwError(exec, ReferenceError, "hasProperty callback returned true for a property that doesn't exist.");
    471496}
Note: See TracChangeset for help on using the changeset viewer.