Changeset 15133 in webkit for trunk/JavaScriptCore/API/JSCallbackObject.cpp
- Timestamp:
- Jul 1, 2006, 9:06:07 PM (19 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/API/JSCallbackObject.cpp
r14951 r15133 28 28 #include "JSCallbackObject.h" 29 29 #include "JSCharBufferRef.h" 30 #include "JSClassRef.h" 30 31 #include "JSObjectRef.h" 31 32 #include "internal.h" 33 #include "reference.h" 32 34 #include "reference_list.h" 33 35 34 36 namespace KJS { 35 37 36 const ClassInfo JSCallbackObject::info = { " JSCallbackObject", 0, 0, 0 };37 38 JSCallbackObject::JSCallbackObject( const JSObjectCallbacks* callbacks)38 const ClassInfo JSCallbackObject::info = { "CallbackObject", 0, 0, 0 }; 39 40 JSCallbackObject::JSCallbackObject(JSClassRef jsClass) 39 41 : JSObject() 40 , m_privateData(0) 41 , m_callbacks(*callbacks) 42 { 42 { 43 init(jsClass); 44 } 45 46 JSCallbackObject::JSCallbackObject(JSClassRef jsClass, JSObject* prototype) 47 : JSObject(prototype) 48 { 49 init(jsClass); 50 } 51 52 void JSCallbackObject::init(JSClassRef jsClass) 53 { 54 m_privateData = 0; 55 m_class = JSClassRetain(jsClass); 56 43 57 JSObjectRef thisRef = toRef(this); 44 58 45 59 do { 46 if (JSInitializeCallback initialize = callbacks->initialize)60 if (JSInitializeCallback initialize = jsClass->callbacks.initialize) 47 61 initialize(thisRef); 48 } while ((callbacks = callbacks->parentCallbacks)); 49 } 50 51 JSCallbackObject::JSCallbackObject(const JSObjectCallbacks* callbacks, JSObject* prototype) 52 : JSObject(prototype) 53 , m_privateData(0) 54 , m_callbacks(*callbacks) 55 { 56 JSObjectRef thisRef = toRef(this); 57 58 do { 59 if (JSInitializeCallback initialize = callbacks->initialize) 60 initialize(thisRef); 61 } while ((callbacks = callbacks->parentCallbacks)); 62 } while ((jsClass = jsClass->parent)); 62 63 } 63 64 … … 66 67 JSObjectRef thisRef = toRef(this); 67 68 68 for (JS ObjectCallbacks* callbacks = &m_callbacks; callbacks; callbacks = callbacks->parentCallbacks)69 if (JSFinalizeCallback finalize = callbacks->finalize)69 for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parent) 70 if (JSFinalizeCallback finalize = jsClass->callbacks.finalize) 70 71 finalize(thisRef); 72 73 JSClassRelease(m_class); 71 74 } 72 75 73 76 UString JSCallbackObject::className() const 74 77 { 75 JSObjectRef thisRef = toRef(this); 76 77 for (const JSObjectCallbacks* callbacks = &m_callbacks; callbacks; callbacks = callbacks->parentCallbacks) { 78 if (JSCopyDescriptionCallback copyDescriptionCallback = callbacks->copyDescription) { 79 JSCharBufferRef descriptionBuf = copyDescriptionCallback(thisRef); 80 UString description(toJS(descriptionBuf)); 81 JSCharBufferRelease(descriptionBuf); 82 return description; 83 } 84 } 85 86 return JSObject::className(); 78 return classInfo()->className; 87 79 } 88 80 … … 91 83 JSObjectRef thisRef = toRef(this); 92 84 JSCharBufferRef propertyNameRef = toRef(propertyName.ustring().rep()); 93 94 // optional optimization for cases when we only need to know if the property exists, not its value95 for (const JSObjectCallbacks* callbacks = &m_callbacks; callbacks; callbacks = callbacks->parentCallbacks) {96 if (JSHasPropertyCallback hasPropertyCallback = callbacks->hasProperty) {85 86 for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parent) { 87 // optional optimization to bypass getProperty in cases when we only need to know if the property exists 88 if (JSHasPropertyCallback hasPropertyCallback = jsClass->callbacks.hasProperty) { 97 89 if (hasPropertyCallback(thisRef, propertyNameRef)) { 98 slot.setCustom(0, callbackGetter); 99 return true; 100 } 101 } 102 } 103 104 for (const JSObjectCallbacks* callbacks = &m_callbacks; callbacks; callbacks = callbacks->parentCallbacks) { 105 if (JSGetPropertyCallback getPropertyCallback = callbacks->getProperty) { 90 slot.setCustom(this, callbackGetter); 91 return true; 92 } 93 } else if (JSGetPropertyCallback getPropertyCallback = jsClass->callbacks.getProperty) { 106 94 JSValueRef returnValue; 107 if (getPropertyCallback(thisRef, propertyNameRef, &returnValue)) { 108 slot.setCustom(reinterpret_cast<JSObject*>(returnValue), cachedValueGetter); // cache the value so we don't have to compute it again 109 return true; 110 } 111 } 112 } 95 if (getPropertyCallback(toRef(exec), thisRef, propertyNameRef, &returnValue)) { 96 // cache the value so we don't have to compute it again 97 // FIXME: This violates the PropertySlot design a little bit. 98 // We should either use this optimization everywhere, or nowhere. 99 slot.setCustom(reinterpret_cast<JSObject*>(returnValue), cachedValueGetter); 100 return true; 101 } 102 } 103 104 if (__JSClass::StaticValuesTable* staticValues = jsClass->staticValues) { 105 if (StaticValueEntry* entry = staticValues->get(propertyName.ustring().rep())) { 106 if (entry->getProperty) { 107 slot.setCustom(this, staticValueGetter); 108 return true; 109 } 110 } 111 } 112 113 if (__JSClass::StaticFunctionsTable* staticFunctions = jsClass->staticFunctions) { 114 if (staticFunctions->contains(propertyName.ustring().rep())) { 115 slot.setCustom(this, staticFunctionGetter); 116 return true; 117 } 118 } 119 } 120 113 121 return JSObject::getOwnPropertySlot(exec, propertyName, slot); 114 122 } … … 124 132 JSCharBufferRef propertyNameRef = toRef(propertyName.ustring().rep()); 125 133 126 for ( const JSObjectCallbacks* callbacks = &m_callbacks; callbacks; callbacks = callbacks->parentCallbacks) {127 if (JSSetPropertyCallback setPropertyCallback = callbacks->setProperty) {134 for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parent) { 135 if (JSSetPropertyCallback setPropertyCallback = jsClass->callbacks.setProperty) { 128 136 if (setPropertyCallback(thisRef, propertyNameRef, value)) 129 137 return; 130 138 } 139 140 if (__JSClass::StaticValuesTable* staticValues = jsClass->staticValues) { 141 if (StaticValueEntry* entry = staticValues->get(propertyName.ustring().rep())) { 142 if (entry->attributes & kJSPropertyAttributeReadOnly) 143 return; 144 if (JSSetPropertyCallback setPropertyCallback = entry->setProperty) { 145 if (setPropertyCallback(thisRef, propertyNameRef, value)) 146 return; 147 } 148 } 149 } 150 151 if (__JSClass::StaticFunctionsTable* staticFunctions = jsClass->staticFunctions) { 152 if (StaticFunctionEntry* entry = staticFunctions->get(propertyName.ustring().rep())) { 153 if (entry->attributes & kJSPropertyAttributeReadOnly) 154 return; 155 putDirect(propertyName, value, attr); // put as override property 156 return; 157 } 158 } 131 159 } 132 160 return JSObject::put(exec, propertyName, value, attr); … … 143 171 JSCharBufferRef propertyNameRef = toRef(propertyName.ustring().rep()); 144 172 145 for ( const JSObjectCallbacks* callbacks = &m_callbacks; callbacks; callbacks = callbacks->parentCallbacks) {146 if (JSDeletePropertyCallback deletePropertyCallback = callbacks->deleteProperty) {173 for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parent) { 174 if (JSDeletePropertyCallback deletePropertyCallback = jsClass->callbacks.deleteProperty) { 147 175 if (deletePropertyCallback(thisRef, propertyNameRef)) 148 176 return true; 149 177 } 178 179 if (__JSClass::StaticValuesTable* staticValues = jsClass->staticValues) { 180 if (StaticValueEntry* entry = staticValues->get(propertyName.ustring().rep())) { 181 if (entry->attributes & kJSPropertyAttributeDontDelete) 182 return false; 183 return true; 184 } 185 } 186 187 if (__JSClass::StaticFunctionsTable* staticFunctions = jsClass->staticFunctions) { 188 if (StaticFunctionEntry* entry = staticFunctions->get(propertyName.ustring().rep())) { 189 if (entry->attributes & kJSPropertyAttributeDontDelete) 190 return false; 191 return true; 192 } 193 } 150 194 } 151 195 return JSObject::deleteProperty(exec, propertyName); … … 159 203 bool JSCallbackObject::implementsConstruct() const 160 204 { 161 for ( const JSObjectCallbacks* callbacks = &m_callbacks; callbacks; callbacks = callbacks->parentCallbacks)162 if ( callbacks->callAsConstructor)205 for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parent) 206 if (jsClass->callbacks.callAsConstructor) 163 207 return true; 164 208 … … 171 215 JSObjectRef thisRef = toRef(this); 172 216 173 for ( const JSObjectCallbacks* callbacks = &m_callbacks; callbacks; callbacks = callbacks->parentCallbacks) {174 if (JSCallAsConstructorCallback callAsConstructorCallback = callbacks->callAsConstructor) {217 for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parent) { 218 if (JSCallAsConstructorCallback callAsConstructorCallback = jsClass->callbacks.callAsConstructor) { 175 219 size_t argc = args.size(); 176 220 JSValueRef argv[argc]; … … 181 225 } 182 226 183 ASSERT( false);227 ASSERT(0); // implementsConstruct should prevent us from reaching here 184 228 return 0; 185 229 } … … 187 231 bool JSCallbackObject::implementsCall() const 188 232 { 189 for ( const JSObjectCallbacks* callbacks = &m_callbacks; callbacks; callbacks = callbacks->parentCallbacks)190 if ( callbacks->callAsFunction)233 for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parent) 234 if (jsClass->callbacks.callAsFunction) 191 235 return true; 192 236 … … 200 244 JSObjectRef thisObjRef = toRef(thisObj); 201 245 202 for ( const JSObjectCallbacks* callbacks = &m_callbacks; callbacks; callbacks = callbacks->parentCallbacks) {203 if (JSCallAsFunctionCallback callAsFunctionCallback = callbacks->callAsFunction) {246 for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parent) { 247 if (JSCallAsFunctionCallback callAsFunctionCallback = jsClass->callbacks.callAsFunction) { 204 248 size_t argc = args.size(); 205 249 JSValueRef argv[argc]; … … 210 254 } 211 255 212 ASSERT( false);256 ASSERT(0); // implementsCall should prevent us from reaching here 213 257 return 0; 214 258 } … … 218 262 JSObjectRef thisRef = toRef(this); 219 263 220 for ( const JSObjectCallbacks* callbacks = &m_callbacks; callbacks; callbacks = callbacks->parentCallbacks)221 if (JSGetPropertyListCallback getPropertyListCallback = callbacks->getPropertyList)264 for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parent) { 265 if (JSGetPropertyListCallback getPropertyListCallback = jsClass->callbacks.getPropertyList) 222 266 getPropertyListCallback(thisRef, toRef(&propertyList)); 223 267 268 if (__JSClass::StaticValuesTable* staticValues = jsClass->staticValues) { 269 typedef __JSClass::StaticValuesTable::const_iterator iterator; 270 iterator end = staticValues->end(); 271 for (iterator it = staticValues->begin(); it != end; ++it) { 272 UString::Rep* name = it->first.get(); 273 StaticValueEntry* entry = it->second; 274 if (entry->getProperty && !(entry->attributes & kJSPropertyAttributeDontEnum)) 275 propertyList.append(Reference(this, Identifier(name))); 276 } 277 } 278 279 if (__JSClass::StaticFunctionsTable* staticFunctions = jsClass->staticFunctions) { 280 typedef __JSClass::StaticFunctionsTable::const_iterator iterator; 281 iterator end = staticFunctions->end(); 282 for (iterator it = staticFunctions->begin(); it != end; ++it) { 283 UString::Rep* name = it->first.get(); 284 StaticFunctionEntry* entry = it->second; 285 if (!(entry->attributes & kJSPropertyAttributeDontEnum)) 286 propertyList.append(Reference(this, Identifier(name))); 287 } 288 } 289 } 290 224 291 JSObject::getPropertyList(exec, propertyList, recursive); 225 292 } … … 229 296 JSObjectRef thisRef = toRef(this); 230 297 231 for ( const JSObjectCallbacks* callbacks = &m_callbacks; callbacks; callbacks = callbacks->parentCallbacks) {232 if (JSConvertToTypeCallback convertToTypeCallback = callbacks->convertToType) {298 for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parent) { 299 if (JSConvertToTypeCallback convertToTypeCallback = jsClass->callbacks.convertToType) { 233 300 JSValueRef returnValue; 234 301 if (convertToTypeCallback(thisRef, kJSTypeBoolean, &returnValue)) … … 243 310 JSObjectRef thisRef = toRef(this); 244 311 245 for ( const JSObjectCallbacks* callbacks = &m_callbacks; callbacks; callbacks = callbacks->parentCallbacks) {246 if (JSConvertToTypeCallback convertToTypeCallback = callbacks->convertToType) {312 for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parent) { 313 if (JSConvertToTypeCallback convertToTypeCallback = jsClass->callbacks.convertToType) { 247 314 JSValueRef returnValue; 248 315 if (convertToTypeCallback(thisRef, kJSTypeNumber, &returnValue)) … … 257 324 JSObjectRef thisRef = toRef(this); 258 325 259 for ( const JSObjectCallbacks* callbacks = &m_callbacks; callbacks; callbacks = callbacks->parentCallbacks) {260 if (JSConvertToTypeCallback convertToTypeCallback = callbacks->convertToType) {326 for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parent) { 327 if (JSConvertToTypeCallback convertToTypeCallback = jsClass->callbacks.convertToType) { 261 328 JSValueRef returnValue; 262 329 if (convertToTypeCallback(thisRef, kJSTypeString, &returnValue)) … … 277 344 } 278 345 346 bool JSCallbackObject::inherits(JSClassRef c) const 347 { 348 for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parent) 349 if (jsClass == c) 350 return true; 351 return false; 352 } 353 279 354 JSValue* JSCallbackObject::cachedValueGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot& slot) 280 355 { … … 284 359 } 285 360 286 JSValue* JSCallbackObject::callbackGetter(ExecState*, JSObject* originalObject, const Identifier& propertyName, const PropertySlot&) 287 { 288 ASSERT(originalObject->inherits(&JSCallbackObject::info)); 289 JSObjectRef thisRef = toRef(originalObject); 290 JSCharBufferRef propertyNameRef= toRef(propertyName.ustring().rep()); 291 292 for (const JSObjectCallbacks* callbacks = &static_cast<JSCallbackObject*>(originalObject)->m_callbacks; callbacks; callbacks = callbacks->parentCallbacks) { 293 if (JSGetPropertyCallback getPropertyCallback = callbacks->getProperty) { 294 JSValueRef returnValue; 295 if (getPropertyCallback(thisRef, propertyNameRef, &returnValue)) { 361 JSValue* JSCallbackObject::staticValueGetter(ExecState* exec, JSObject*, const Identifier& propertyName, const PropertySlot& slot) 362 { 363 ASSERT(slot.slotBase()->inherits(&JSCallbackObject::info)); 364 JSCallbackObject* thisObj = static_cast<JSCallbackObject*>(slot.slotBase()); 365 366 JSObjectRef thisRef = toRef(thisObj); 367 JSCharBufferRef propertyNameRef = toRef(propertyName.ustring().rep()); 368 369 for (JSClassRef jsClass = thisObj->m_class; jsClass; jsClass = jsClass->parent) { 370 JSValueRef returnValue; 371 372 if (__JSClass::StaticValuesTable* staticValues = jsClass->staticValues) 373 if (StaticValueEntry* entry = staticValues->get(propertyName.ustring().rep())) 374 if (JSGetPropertyCallback getPropertyCallback = entry->getProperty) 375 if (getPropertyCallback(toRef(exec), thisRef, propertyNameRef, &returnValue)) 376 return toJS(returnValue); 377 } 378 379 return jsUndefined(); 380 } 381 382 JSValue* JSCallbackObject::staticFunctionGetter(ExecState* exec, JSObject*, const Identifier& propertyName, const PropertySlot& slot) 383 { 384 ASSERT(slot.slotBase()->inherits(&JSCallbackObject::info)); 385 JSCallbackObject* thisObj = static_cast<JSCallbackObject*>(slot.slotBase()); 386 387 if (JSValue* cachedOrOverrideValue = thisObj->getDirect(propertyName)) 388 return toJS(cachedOrOverrideValue); 389 390 for (JSClassRef jsClass = thisObj->m_class; jsClass; jsClass = jsClass->parent) { 391 if (__JSClass::StaticFunctionsTable* staticFunctions = jsClass->staticFunctions) { 392 if (StaticFunctionEntry* entry = staticFunctions->get(propertyName.ustring().rep())) { 393 JSValue* v = toJS(JSFunctionMake(toRef(exec), entry->callAsFunction)); 394 thisObj->putDirect(propertyName, v, entry->attributes); 395 return v; 396 } 397 } 398 } 399 400 return jsUndefined(); 401 } 402 403 JSValue* JSCallbackObject::callbackGetter(ExecState* exec, JSObject*, const Identifier& propertyName, const PropertySlot& slot) 404 { 405 ASSERT(slot.slotBase()->inherits(&JSCallbackObject::info)); 406 JSCallbackObject* thisObj = static_cast<JSCallbackObject*>(slot.slotBase()); 407 408 JSObjectRef thisRef = toRef(thisObj); 409 JSCharBufferRef propertyNameRef = toRef(propertyName.ustring().rep()); 410 411 for (JSClassRef jsClass = thisObj->m_class; jsClass; jsClass = jsClass->parent) { 412 JSValueRef returnValue; 413 414 if (JSGetPropertyCallback getPropertyCallback = jsClass->callbacks.getProperty) 415 if (getPropertyCallback(toRef(exec), thisRef, propertyNameRef, &returnValue)) 296 416 return toJS(returnValue); 297 }298 }299 417 } 300 418
Note:
See TracChangeset
for help on using the changeset viewer.