2  * Copyright (C) 2006, 2008 Apple Inc. All rights reserved. 
   3  * Copyright (C) 2007 Eric Seidel <eric@webkit.org> 
   5  * Redistribution and use in source and binary forms, with or without 
   6  * modification, are permitted provided that the following conditions 
   8  * 1. Redistributions of source code must retain the above copyright 
   9  *    notice, this list of conditions and the following disclaimer. 
  10  * 2. Redistributions in binary form must reproduce the above copyright 
  11  *    notice, this list of conditions and the following disclaimer in the 
  12  *    documentation and/or other materials provided with the distribution. 
  14  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 
  15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
  16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
  17  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR 
  18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
  19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
  20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
  21  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
  22  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
  30 #include "ExceptionHelpers.h" 
  31 #include "JSCallbackFunction.h" 
  32 #include "JSClassRef.h" 
  33 #include "JSFunction.h" 
  34 #include "JSGlobalObject.h" 
  36 #include "JSObjectRef.h" 
  38 #include "JSStringRef.h" 
  39 #include "OpaqueJSString.h" 
  40 #include "PropertyNameArray.h" 
  41 #include <wtf/Vector.h> 
  45 template <class Parent
> 
  46 inline JSCallbackObject
<Parent
>* JSCallbackObject
<Parent
>::asCallbackObject(JSValue value
) 
  48     ASSERT(asObject(value
)->inherits(&s_info
)); 
  49     return jsCast
<JSCallbackObject
*>(asObject(value
)); 
  52 template <class Parent
> 
  53 JSCallbackObject
<Parent
>::JSCallbackObject(ExecState
* exec
, Structure
* structure
, JSClassRef jsClass
, void* data
) 
  54     : Parent(exec
->vm(), structure
) 
  55     , m_callbackObjectData(adoptPtr(new JSCallbackObjectData(data
, jsClass
))) 
  59 // Global object constructor. 
  60 // FIXME: Move this into a separate JSGlobalCallbackObject class derived from this one. 
  61 template <class Parent
> 
  62 JSCallbackObject
<Parent
>::JSCallbackObject(VM
& vm
, JSClassRef jsClass
, Structure
* structure
) 
  63     : Parent(vm
, structure
) 
  64     , m_callbackObjectData(adoptPtr(new JSCallbackObjectData(0, jsClass
))) 
  68 template <class Parent
> 
  69 void JSCallbackObject
<Parent
>::finishCreation(ExecState
* exec
) 
  71     Base::finishCreation(exec
->vm()); 
  72     ASSERT(Parent::inherits(&s_info
)); 
  76 // This is just for Global object, so we can assume that Base::finishCreation is JSGlobalObject::finishCreation. 
  77 template <class Parent
> 
  78 void JSCallbackObject
<Parent
>::finishCreation(VM
& vm
) 
  80     ASSERT(Parent::inherits(&s_info
)); 
  81     ASSERT(Parent::isGlobalObject()); 
  82     Base::finishCreation(vm
); 
  83     init(jsCast
<JSGlobalObject
*>(this)->globalExec()); 
  86 template <class Parent
> 
  87 void JSCallbackObject
<Parent
>::init(ExecState
* exec
) 
  91     Vector
<JSObjectInitializeCallback
, 16> initRoutines
; 
  92     JSClassRef jsClass 
= classRef(); 
  94         if (JSObjectInitializeCallback initialize 
= jsClass
->initialize
) 
  95             initRoutines
.append(initialize
); 
  96     } while ((jsClass 
= jsClass
->parentClass
)); 
  98     // initialize from base to derived 
  99     for (int i 
= static_cast<int>(initRoutines
.size()) - 1; i 
>= 0; i
--) { 
 100         APICallbackShim 
callbackShim(exec
); 
 101         JSObjectInitializeCallback initialize 
= initRoutines
[i
]; 
 102         initialize(toRef(exec
), toRef(this)); 
 105     for (JSClassRef jsClassPtr 
= classRef(); jsClassPtr
; jsClassPtr 
= jsClassPtr
->parentClass
) { 
 106         if (jsClassPtr
->finalize
) { 
 107             WeakSet::allocate(this, m_callbackObjectData
.get(), classRef()); 
 113 template <class Parent
> 
 114 String JSCallbackObject
<Parent
>::className(const JSObject
* object
) 
 116     const JSCallbackObject
* thisObject 
= jsCast
<const JSCallbackObject
*>(object
); 
 117     String thisClassName 
= thisObject
->classRef()->className(); 
 118     if (!thisClassName
.isEmpty()) 
 119         return thisClassName
; 
 121     return Parent::className(object
); 
 124 template <class Parent
> 
 125 bool JSCallbackObject
<Parent
>::getOwnPropertySlot(JSCell
* cell
, ExecState
* exec
, PropertyName propertyName
, PropertySlot
& slot
) 
 127     JSCallbackObject
* thisObject 
= jsCast
<JSCallbackObject
*>(cell
); 
 128     JSContextRef ctx 
= toRef(exec
); 
 129     JSObjectRef thisRef 
= toRef(thisObject
); 
 130     RefPtr
<OpaqueJSString
> propertyNameRef
; 
 132     if (StringImpl
* name 
= propertyName
.publicName()) { 
 133         for (JSClassRef jsClass 
= thisObject
->classRef(); jsClass
; jsClass 
= jsClass
->parentClass
) { 
 134             // optional optimization to bypass getProperty in cases when we only need to know if the property exists 
 135             if (JSObjectHasPropertyCallback hasProperty 
= jsClass
->hasProperty
) { 
 136                 if (!propertyNameRef
) 
 137                     propertyNameRef 
= OpaqueJSString::create(name
); 
 138                 APICallbackShim 
callbackShim(exec
); 
 139                 if (hasProperty(ctx
, thisRef
, propertyNameRef
.get())) { 
 140                     slot
.setCustom(thisObject
, callbackGetter
); 
 143             } else if (JSObjectGetPropertyCallback getProperty 
= jsClass
->getProperty
) { 
 144                 if (!propertyNameRef
) 
 145                     propertyNameRef 
= OpaqueJSString::create(name
); 
 146                 JSValueRef exception 
= 0; 
 149                     APICallbackShim 
callbackShim(exec
); 
 150                     value 
= getProperty(ctx
, thisRef
, propertyNameRef
.get(), &exception
); 
 153                     throwError(exec
, toJS(exec
, exception
)); 
 154                     slot
.setValue(jsUndefined()); 
 158                     slot
.setValue(toJS(exec
, value
)); 
 163             if (OpaqueJSClassStaticValuesTable
* staticValues 
= jsClass
->staticValues(exec
)) { 
 164                 if (staticValues
->contains(name
)) { 
 165                     JSValue value 
= thisObject
->getStaticValue(exec
, propertyName
); 
 167                         slot
.setValue(value
); 
 173             if (OpaqueJSClassStaticFunctionsTable
* staticFunctions 
= jsClass
->staticFunctions(exec
)) { 
 174                 if (staticFunctions
->contains(name
)) { 
 175                     slot
.setCustom(thisObject
, staticFunctionGetter
); 
 182     return Parent::getOwnPropertySlot(thisObject
, exec
, propertyName
, slot
); 
 185 template <class Parent
> 
 186 bool JSCallbackObject
<Parent
>::getOwnPropertySlotByIndex(JSCell
* cell
, ExecState
* exec
, unsigned propertyName
, PropertySlot
& slot
) 
 188     return cell
->methodTable()->getOwnPropertySlot(cell
, exec
, Identifier::from(exec
, propertyName
), slot
); 
 191 template <class Parent
> 
 192 JSValue JSCallbackObject
<Parent
>::defaultValue(const JSObject
* object
, ExecState
* exec
, PreferredPrimitiveType hint
) 
 194     const JSCallbackObject
* thisObject 
= jsCast
<const JSCallbackObject
*>(object
); 
 195     JSContextRef ctx 
= toRef(exec
); 
 196     JSObjectRef thisRef 
= toRef(thisObject
); 
 197     ::JSType jsHint 
= hint 
== PreferString 
? kJSTypeString 
: kJSTypeNumber
; 
 199     for (JSClassRef jsClass 
= thisObject
->classRef(); jsClass
; jsClass 
= jsClass
->parentClass
) { 
 200         if (JSObjectConvertToTypeCallback convertToType 
= jsClass
->convertToType
) { 
 201             JSValueRef exception 
= 0; 
 202             JSValueRef result 
= convertToType(ctx
, thisRef
, jsHint
, &exception
); 
 204                 throwError(exec
, toJS(exec
, exception
)); 
 205                 return jsUndefined(); 
 208                 return toJS(exec
, result
); 
 212     return Parent::defaultValue(object
, exec
, hint
); 
 215 template <class Parent
> 
 216 bool JSCallbackObject
<Parent
>::getOwnPropertyDescriptor(JSObject
* object
, ExecState
* exec
, PropertyName propertyName
, PropertyDescriptor
& descriptor
) 
 218     JSCallbackObject
* thisObject 
= jsCast
<JSCallbackObject
*>(object
); 
 219     PropertySlot 
slot(thisObject
); 
 220     if (thisObject
->methodTable()->getOwnPropertySlot(thisObject
, exec
, propertyName
, slot
)) { 
 221         // Ideally we should return an access descriptor, but returning a value descriptor is better than nothing. 
 222         JSValue value 
= slot
.getValue(exec
, propertyName
); 
 223         if (!exec
->hadException()) 
 224             descriptor
.setValue(value
); 
 225         // We don't know whether the property is configurable, but assume it is. 
 226         descriptor
.setConfigurable(true); 
 227         // We don't know whether the property is enumerable (we could call getOwnPropertyNames() to find out), but assume it isn't. 
 228         descriptor
.setEnumerable(false); 
 232     return Parent::getOwnPropertyDescriptor(thisObject
, exec
, propertyName
, descriptor
); 
 235 template <class Parent
> 
 236 void JSCallbackObject
<Parent
>::put(JSCell
* cell
, ExecState
* exec
, PropertyName propertyName
, JSValue value
, PutPropertySlot
& slot
) 
 238     JSCallbackObject
* thisObject 
= jsCast
<JSCallbackObject
*>(cell
); 
 239     JSContextRef ctx 
= toRef(exec
); 
 240     JSObjectRef thisRef 
= toRef(thisObject
); 
 241     RefPtr
<OpaqueJSString
> propertyNameRef
; 
 242     JSValueRef valueRef 
= toRef(exec
, value
); 
 244     if (StringImpl
* name 
= propertyName
.publicName()) { 
 245         for (JSClassRef jsClass 
= thisObject
->classRef(); jsClass
; jsClass 
= jsClass
->parentClass
) { 
 246             if (JSObjectSetPropertyCallback setProperty 
= jsClass
->setProperty
) { 
 247                 if (!propertyNameRef
) 
 248                     propertyNameRef 
= OpaqueJSString::create(name
); 
 249                 JSValueRef exception 
= 0; 
 252                     APICallbackShim 
callbackShim(exec
); 
 253                     result 
= setProperty(ctx
, thisRef
, propertyNameRef
.get(), valueRef
, &exception
); 
 256                     throwError(exec
, toJS(exec
, exception
)); 
 257                 if (result 
|| exception
) 
 261             if (OpaqueJSClassStaticValuesTable
* staticValues 
= jsClass
->staticValues(exec
)) { 
 262                 if (StaticValueEntry
* entry 
= staticValues
->get(name
)) { 
 263                     if (entry
->attributes 
& kJSPropertyAttributeReadOnly
) 
 265                     if (JSObjectSetPropertyCallback setProperty 
= entry
->setProperty
) { 
 266                         if (!propertyNameRef
) 
 267                             propertyNameRef 
= OpaqueJSString::create(name
); 
 268                         JSValueRef exception 
= 0; 
 271                             APICallbackShim 
callbackShim(exec
); 
 272                             result 
= setProperty(ctx
, thisRef
, propertyNameRef
.get(), valueRef
, &exception
); 
 275                             throwError(exec
, toJS(exec
, exception
)); 
 276                         if (result 
|| exception
) 
 282             if (OpaqueJSClassStaticFunctionsTable
* staticFunctions 
= jsClass
->staticFunctions(exec
)) { 
 283                 if (StaticFunctionEntry
* entry 
= staticFunctions
->get(name
)) { 
 284                     if (entry
->attributes 
& kJSPropertyAttributeReadOnly
) 
 286                     thisObject
->JSCallbackObject
<Parent
>::putDirect(exec
->vm(), propertyName
, value
); // put as override property 
 293     return Parent::put(thisObject
, exec
, propertyName
, value
, slot
); 
 296 template <class Parent
> 
 297 void JSCallbackObject
<Parent
>::putByIndex(JSCell
* cell
, ExecState
* exec
, unsigned propertyIndex
, JSValue value
, bool shouldThrow
) 
 299     JSCallbackObject
* thisObject 
= jsCast
<JSCallbackObject
*>(cell
); 
 300     JSContextRef ctx 
= toRef(exec
); 
 301     JSObjectRef thisRef 
= toRef(thisObject
); 
 302     RefPtr
<OpaqueJSString
> propertyNameRef
; 
 303     JSValueRef valueRef 
= toRef(exec
, value
); 
 304     Identifier propertyName 
= Identifier(exec
, String::number(propertyIndex
)); 
 306     for (JSClassRef jsClass 
= thisObject
->classRef(); jsClass
; jsClass 
= jsClass
->parentClass
) { 
 307         if (JSObjectSetPropertyCallback setProperty 
= jsClass
->setProperty
) { 
 308             if (!propertyNameRef
) 
 309                 propertyNameRef 
= OpaqueJSString::create(propertyName
.impl()); 
 310             JSValueRef exception 
= 0; 
 313                 APICallbackShim 
callbackShim(exec
); 
 314                 result 
= setProperty(ctx
, thisRef
, propertyNameRef
.get(), valueRef
, &exception
); 
 317                 throwError(exec
, toJS(exec
, exception
)); 
 318             if (result 
|| exception
) 
 322         if (OpaqueJSClassStaticValuesTable
* staticValues 
= jsClass
->staticValues(exec
)) { 
 323             if (StaticValueEntry
* entry 
= staticValues
->get(propertyName
.impl())) { 
 324                 if (entry
->attributes 
& kJSPropertyAttributeReadOnly
) 
 326                 if (JSObjectSetPropertyCallback setProperty 
= entry
->setProperty
) { 
 327                     if (!propertyNameRef
) 
 328                         propertyNameRef 
= OpaqueJSString::create(propertyName
.impl()); 
 329                     JSValueRef exception 
= 0; 
 332                         APICallbackShim 
callbackShim(exec
); 
 333                         result 
= setProperty(ctx
, thisRef
, propertyNameRef
.get(), valueRef
, &exception
); 
 336                         throwError(exec
, toJS(exec
, exception
)); 
 337                     if (result 
|| exception
) 
 343         if (OpaqueJSClassStaticFunctionsTable
* staticFunctions 
= jsClass
->staticFunctions(exec
)) { 
 344             if (StaticFunctionEntry
* entry 
= staticFunctions
->get(propertyName
.impl())) { 
 345                 if (entry
->attributes 
& kJSPropertyAttributeReadOnly
) 
 352     return Parent::putByIndex(thisObject
, exec
, propertyIndex
, value
, shouldThrow
); 
 355 template <class Parent
> 
 356 bool JSCallbackObject
<Parent
>::deleteProperty(JSCell
* cell
, ExecState
* exec
, PropertyName propertyName
) 
 358     JSCallbackObject
* thisObject 
= jsCast
<JSCallbackObject
*>(cell
); 
 359     JSContextRef ctx 
= toRef(exec
); 
 360     JSObjectRef thisRef 
= toRef(thisObject
); 
 361     RefPtr
<OpaqueJSString
> propertyNameRef
; 
 363     if (StringImpl
* name 
= propertyName
.publicName()) { 
 364         for (JSClassRef jsClass 
= thisObject
->classRef(); jsClass
; jsClass 
= jsClass
->parentClass
) { 
 365             if (JSObjectDeletePropertyCallback deleteProperty 
= jsClass
->deleteProperty
) { 
 366                 if (!propertyNameRef
) 
 367                     propertyNameRef 
= OpaqueJSString::create(name
); 
 368                 JSValueRef exception 
= 0; 
 371                     APICallbackShim 
callbackShim(exec
); 
 372                     result 
= deleteProperty(ctx
, thisRef
, propertyNameRef
.get(), &exception
); 
 375                     throwError(exec
, toJS(exec
, exception
)); 
 376                 if (result 
|| exception
) 
 380             if (OpaqueJSClassStaticValuesTable
* staticValues 
= jsClass
->staticValues(exec
)) { 
 381                 if (StaticValueEntry
* entry 
= staticValues
->get(name
)) { 
 382                     if (entry
->attributes 
& kJSPropertyAttributeDontDelete
) 
 388             if (OpaqueJSClassStaticFunctionsTable
* staticFunctions 
= jsClass
->staticFunctions(exec
)) { 
 389                 if (StaticFunctionEntry
* entry 
= staticFunctions
->get(name
)) { 
 390                     if (entry
->attributes 
& kJSPropertyAttributeDontDelete
) 
 398     return Parent::deleteProperty(thisObject
, exec
, propertyName
); 
 401 template <class Parent
> 
 402 bool JSCallbackObject
<Parent
>::deletePropertyByIndex(JSCell
* cell
, ExecState
* exec
, unsigned propertyName
) 
 404     JSCallbackObject
* thisObject 
= jsCast
<JSCallbackObject
*>(cell
); 
 405     return thisObject
->methodTable()->deleteProperty(thisObject
, exec
, Identifier::from(exec
, propertyName
)); 
 408 template <class Parent
> 
 409 ConstructType JSCallbackObject
<Parent
>::getConstructData(JSCell
* cell
, ConstructData
& constructData
) 
 411     JSCallbackObject
* thisObject 
= jsCast
<JSCallbackObject
*>(cell
); 
 412     for (JSClassRef jsClass 
= thisObject
->classRef(); jsClass
; jsClass 
= jsClass
->parentClass
) { 
 413         if (jsClass
->callAsConstructor
) { 
 414             constructData
.native
.function 
= construct
; 
 415             return ConstructTypeHost
; 
 418     return ConstructTypeNone
; 
 421 template <class Parent
> 
 422 EncodedJSValue JSCallbackObject
<Parent
>::construct(ExecState
* exec
) 
 424     JSObject
* constructor 
= exec
->callee(); 
 425     JSContextRef execRef 
= toRef(exec
); 
 426     JSObjectRef constructorRef 
= toRef(constructor
); 
 428     for (JSClassRef jsClass 
= jsCast
<JSCallbackObject
<Parent
>*>(constructor
)->classRef(); jsClass
; jsClass 
= jsClass
->parentClass
) { 
 429         if (JSObjectCallAsConstructorCallback callAsConstructor 
= jsClass
->callAsConstructor
) { 
 430             size_t argumentCount 
= exec
->argumentCount(); 
 431             Vector
<JSValueRef
, 16> arguments
; 
 432             arguments
.reserveInitialCapacity(argumentCount
); 
 433             for (size_t i 
= 0; i 
< argumentCount
; ++i
) 
 434                 arguments
.uncheckedAppend(toRef(exec
, exec
->argument(i
))); 
 435             JSValueRef exception 
= 0; 
 438                 APICallbackShim 
callbackShim(exec
); 
 439                 result 
= toJS(callAsConstructor(execRef
, constructorRef
, argumentCount
, arguments
.data(), &exception
)); 
 442                 throwError(exec
, toJS(exec
, exception
)); 
 443             return JSValue::encode(result
); 
 447     RELEASE_ASSERT_NOT_REACHED(); // getConstructData should prevent us from reaching here 
 448     return JSValue::encode(JSValue()); 
 451 template <class Parent
> 
 452 bool JSCallbackObject
<Parent
>::customHasInstance(JSObject
* object
, ExecState
* exec
, JSValue value
) 
 454     JSCallbackObject
* thisObject 
= jsCast
<JSCallbackObject
*>(object
); 
 455     JSContextRef execRef 
= toRef(exec
); 
 456     JSObjectRef thisRef 
= toRef(thisObject
); 
 458     for (JSClassRef jsClass 
= thisObject
->classRef(); jsClass
; jsClass 
= jsClass
->parentClass
) { 
 459         if (JSObjectHasInstanceCallback hasInstance 
= jsClass
->hasInstance
) { 
 460             JSValueRef valueRef 
= toRef(exec
, value
); 
 461             JSValueRef exception 
= 0; 
 464                 APICallbackShim 
callbackShim(exec
); 
 465                 result 
= hasInstance(execRef
, thisRef
, valueRef
, &exception
); 
 468                 throwError(exec
, toJS(exec
, exception
)); 
 475 template <class Parent
> 
 476 CallType JSCallbackObject
<Parent
>::getCallData(JSCell
* cell
, CallData
& callData
) 
 478     JSCallbackObject
* thisObject 
= jsCast
<JSCallbackObject
*>(cell
); 
 479     for (JSClassRef jsClass 
= thisObject
->classRef(); jsClass
; jsClass 
= jsClass
->parentClass
) { 
 480         if (jsClass
->callAsFunction
) { 
 481             callData
.native
.function 
= call
; 
 488 template <class Parent
> 
 489 EncodedJSValue JSCallbackObject
<Parent
>::call(ExecState
* exec
) 
 491     JSContextRef execRef 
= toRef(exec
); 
 492     JSObjectRef functionRef 
= toRef(exec
->callee()); 
 493     JSObjectRef thisObjRef 
= toRef(exec
->hostThisValue().toThisObject(exec
)); 
 495     for (JSClassRef jsClass 
= jsCast
<JSCallbackObject
<Parent
>*>(toJS(functionRef
))->classRef(); jsClass
; jsClass 
= jsClass
->parentClass
) { 
 496         if (JSObjectCallAsFunctionCallback callAsFunction 
= jsClass
->callAsFunction
) { 
 497             size_t argumentCount 
= exec
->argumentCount(); 
 498             Vector
<JSValueRef
, 16> arguments
; 
 499             arguments
.reserveInitialCapacity(argumentCount
); 
 500             for (size_t i 
= 0; i 
< argumentCount
; ++i
) 
 501                 arguments
.uncheckedAppend(toRef(exec
, exec
->argument(i
))); 
 502             JSValueRef exception 
= 0; 
 505                 APICallbackShim 
callbackShim(exec
); 
 506                 result 
= toJS(exec
, callAsFunction(execRef
, functionRef
, thisObjRef
, argumentCount
, arguments
.data(), &exception
)); 
 509                 throwError(exec
, toJS(exec
, exception
)); 
 510             return JSValue::encode(result
); 
 514     RELEASE_ASSERT_NOT_REACHED(); // getCallData should prevent us from reaching here 
 515     return JSValue::encode(JSValue()); 
 518 template <class Parent
> 
 519 void JSCallbackObject
<Parent
>::getOwnNonIndexPropertyNames(JSObject
* object
, ExecState
* exec
, PropertyNameArray
& propertyNames
, EnumerationMode mode
) 
 521     JSCallbackObject
* thisObject 
= jsCast
<JSCallbackObject
*>(object
); 
 522     JSContextRef execRef 
= toRef(exec
); 
 523     JSObjectRef thisRef 
= toRef(thisObject
); 
 525     for (JSClassRef jsClass 
= thisObject
->classRef(); jsClass
; jsClass 
= jsClass
->parentClass
) { 
 526         if (JSObjectGetPropertyNamesCallback getPropertyNames 
= jsClass
->getPropertyNames
) { 
 527             APICallbackShim 
callbackShim(exec
); 
 528             getPropertyNames(execRef
, thisRef
, toRef(&propertyNames
)); 
 531         if (OpaqueJSClassStaticValuesTable
* staticValues 
= jsClass
->staticValues(exec
)) { 
 532             typedef OpaqueJSClassStaticValuesTable::const_iterator iterator
; 
 533             iterator end 
= staticValues
->end(); 
 534             for (iterator it 
= staticValues
->begin(); it 
!= end
; ++it
) { 
 535                 StringImpl
* name 
= it
->key
.get(); 
 536                 StaticValueEntry
* entry 
= it
->value
.get(); 
 537                 if (entry
->getProperty 
&& (!(entry
->attributes 
& kJSPropertyAttributeDontEnum
) || (mode 
== IncludeDontEnumProperties
))) 
 538                     propertyNames
.add(Identifier(exec
, name
)); 
 542         if (OpaqueJSClassStaticFunctionsTable
* staticFunctions 
= jsClass
->staticFunctions(exec
)) { 
 543             typedef OpaqueJSClassStaticFunctionsTable::const_iterator iterator
; 
 544             iterator end 
= staticFunctions
->end(); 
 545             for (iterator it 
= staticFunctions
->begin(); it 
!= end
; ++it
) { 
 546                 StringImpl
* name 
= it
->key
.get(); 
 547                 StaticFunctionEntry
* entry 
= it
->value
.get(); 
 548                 if (!(entry
->attributes 
& kJSPropertyAttributeDontEnum
) || (mode 
== IncludeDontEnumProperties
)) 
 549                     propertyNames
.add(Identifier(exec
, name
)); 
 554     Parent::getOwnNonIndexPropertyNames(thisObject
, exec
, propertyNames
, mode
); 
 557 template <class Parent
> 
 558 void JSCallbackObject
<Parent
>::setPrivate(void* data
) 
 560     m_callbackObjectData
->privateData 
= data
; 
 563 template <class Parent
> 
 564 void* JSCallbackObject
<Parent
>::getPrivate() 
 566     return m_callbackObjectData
->privateData
; 
 569 template <class Parent
> 
 570 bool JSCallbackObject
<Parent
>::inherits(JSClassRef c
) const 
 572     for (JSClassRef jsClass 
= classRef(); jsClass
; jsClass 
= jsClass
->parentClass
) { 
 579 template <class Parent
> 
 580 JSValue JSCallbackObject
<Parent
>::getStaticValue(ExecState
* exec
, PropertyName propertyName
) 
 582     JSObjectRef thisRef 
= toRef(this); 
 583     RefPtr
<OpaqueJSString
> propertyNameRef
; 
 585     if (StringImpl
* name 
= propertyName
.publicName()) { 
 586         for (JSClassRef jsClass 
= classRef(); jsClass
; jsClass 
= jsClass
->parentClass
) { 
 587             if (OpaqueJSClassStaticValuesTable
* staticValues 
= jsClass
->staticValues(exec
)) { 
 588                 if (StaticValueEntry
* entry 
= staticValues
->get(name
)) { 
 589                     if (JSObjectGetPropertyCallback getProperty 
= entry
->getProperty
) { 
 590                         if (!propertyNameRef
) 
 591                             propertyNameRef 
= OpaqueJSString::create(name
); 
 592                         JSValueRef exception 
= 0; 
 595                             APICallbackShim 
callbackShim(exec
); 
 596                             value 
= getProperty(toRef(exec
), thisRef
, propertyNameRef
.get(), &exception
); 
 599                             throwError(exec
, toJS(exec
, exception
)); 
 600                             return jsUndefined(); 
 603                             return toJS(exec
, value
); 
 613 template <class Parent
> 
 614 JSValue JSCallbackObject
<Parent
>::staticFunctionGetter(ExecState
* exec
, JSValue slotParent
, PropertyName propertyName
) 
 616     JSCallbackObject
* thisObj 
= asCallbackObject(slotParent
); 
 618     // Check for cached or override property. 
 619     PropertySlot 
slot2(thisObj
); 
 620     if (Parent::getOwnPropertySlot(thisObj
, exec
, propertyName
, slot2
)) 
 621         return slot2
.getValue(exec
, propertyName
); 
 623     if (StringImpl
* name 
= propertyName
.publicName()) { 
 624         for (JSClassRef jsClass 
= thisObj
->classRef(); jsClass
; jsClass 
= jsClass
->parentClass
) { 
 625             if (OpaqueJSClassStaticFunctionsTable
* staticFunctions 
= jsClass
->staticFunctions(exec
)) { 
 626                 if (StaticFunctionEntry
* entry 
= staticFunctions
->get(name
)) { 
 627                     if (JSObjectCallAsFunctionCallback callAsFunction 
= entry
->callAsFunction
) { 
 629                         JSObject
* o 
= JSCallbackFunction::create(exec
, thisObj
->globalObject(), callAsFunction
, name
); 
 630                         thisObj
->putDirect(exec
->vm(), propertyName
, o
, entry
->attributes
); 
 638     return throwError(exec
, createReferenceError(exec
, ASCIILiteral("Static function property defined with NULL callAsFunction callback."))); 
 641 template <class Parent
> 
 642 JSValue JSCallbackObject
<Parent
>::callbackGetter(ExecState
* exec
, JSValue slotParent
, PropertyName propertyName
) 
 644     JSCallbackObject
* thisObj 
= asCallbackObject(slotParent
); 
 646     JSObjectRef thisRef 
= toRef(thisObj
); 
 647     RefPtr
<OpaqueJSString
> propertyNameRef
; 
 649     if (StringImpl
* name 
= propertyName
.publicName()) { 
 650         for (JSClassRef jsClass 
= thisObj
->classRef(); jsClass
; jsClass 
= jsClass
->parentClass
) { 
 651             if (JSObjectGetPropertyCallback getProperty 
= jsClass
->getProperty
) { 
 652                 if (!propertyNameRef
) 
 653                     propertyNameRef 
= OpaqueJSString::create(name
); 
 654                 JSValueRef exception 
= 0; 
 657                     APICallbackShim 
callbackShim(exec
); 
 658                     value 
= getProperty(toRef(exec
), thisRef
, propertyNameRef
.get(), &exception
); 
 661                     throwError(exec
, toJS(exec
, exception
)); 
 662                     return jsUndefined(); 
 665                     return toJS(exec
, value
); 
 670     return throwError(exec
, createReferenceError(exec
, ASCIILiteral("hasProperty callback returned true for a property that doesn't exist.")));