Changeset 27022 in webkit for trunk/JavaScriptCore/API
- Timestamp:
- Oct 24, 2007, 11:38:35 PM (18 years ago)
- Location:
- trunk/JavaScriptCore/API
- Files:
-
- 6 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/API/JSCallbackObject.cpp
r25258 r27022 2 2 /* 3 3 * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. 4 * Copyright (C) 2007 Eric Seidel <[email protected]> 4 5 * 5 6 * Redistribution and use in source and binary forms, with or without … … 25 26 */ 26 27 27 #include <wtf/Platform.h>28 28 #include "JSCallbackObject.h" 29 30 #include "APICast.h"31 #include "JSCallbackFunction.h"32 #include "JSClassRef.h"33 #include "JSObjectRef.h"34 #include "JSStringRef.h"35 #include "PropertyNameArray.h"36 #include "internal.h"37 #include <wtf/Vector.h>38 29 39 30 namespace KJS { 40 31 41 const ClassInfo JSCallbackObject::info = { "CallbackObject", 0, 0, 0 }; 42 43 JSCallbackObject::JSCallbackObject(ExecState* exec, JSClassRef jsClass, JSValue* prototype, void* data) 44 : JSObject(prototype) 45 , m_class(0) 46 , m_isInitialized(false) 47 { 48 init(exec, jsClass, data); 49 } 50 51 void JSCallbackObject::init(ExecState* exec, JSClassRef jsClass, void* data) 52 { 53 m_privateData = data; 54 JSClassRef oldClass = m_class; 55 m_class = JSClassRetain(jsClass); 56 if (oldClass) 57 JSClassRelease(oldClass); 58 59 if (!exec) 60 return; 61 62 Vector<JSObjectInitializeCallback, 16> initRoutines; 63 do { 64 if (JSObjectInitializeCallback initialize = jsClass->initialize) 65 initRoutines.append(initialize); 66 } while ((jsClass = jsClass->parentClass)); 67 68 // initialize from base to derived 69 for (int i = static_cast<int>(initRoutines.size()) - 1; i >= 0; i--) { 70 JSLock::DropAllLocks dropAllLocks; 71 JSObjectInitializeCallback initialize = initRoutines[i]; 72 initialize(toRef(exec), toRef(this)); 73 } 74 m_isInitialized = true; 75 } 76 77 JSCallbackObject::~JSCallbackObject() 78 { 79 JSObjectRef thisRef = toRef(this); 80 81 for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass) 82 if (JSObjectFinalizeCallback finalize = jsClass->finalize) { 83 finalize(thisRef); 84 } 85 86 JSClassRelease(m_class); 87 } 88 89 void JSCallbackObject::initializeIfNeeded(ExecState* exec) 90 { 91 if (m_isInitialized) 92 return; 93 init(exec, m_class, m_privateData); 94 } 95 96 UString JSCallbackObject::className() const 97 { 98 if (!m_class->className.isNull()) 99 return m_class->className; 100 101 return JSObject::className(); 102 } 103 104 bool JSCallbackObject::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) 105 { 106 JSContextRef ctx = toRef(exec); 107 JSObjectRef thisRef = toRef(this); 108 JSStringRef propertyNameRef = toRef(propertyName.ustring().rep()); 109 110 for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass) { 111 // optional optimization to bypass getProperty in cases when we only need to know if the property exists 112 if (JSObjectHasPropertyCallback hasProperty = jsClass->hasProperty) { 113 JSLock::DropAllLocks dropAllLocks; 114 if (hasProperty(ctx, thisRef, propertyNameRef)) { 115 slot.setCustom(this, callbackGetter); 116 return true; 117 } 118 } else if (JSObjectGetPropertyCallback getProperty = jsClass->getProperty) { 119 JSLock::DropAllLocks dropAllLocks; 120 if (JSValueRef value = getProperty(ctx, thisRef, propertyNameRef, toRef(exec->exceptionSlot()))) { 121 // cache the value so we don't have to compute it again 122 // FIXME: This violates the PropertySlot design a little bit. 123 // We should either use this optimization everywhere, or nowhere. 124 slot.setCustom(reinterpret_cast<JSObject*>(toJS(value)), cachedValueGetter); 125 return true; 126 } 127 } 128 129 if (OpaqueJSClass::StaticValuesTable* staticValues = jsClass->staticValues) { 130 if (staticValues->contains(propertyName.ustring().rep())) { 131 slot.setCustom(this, staticValueGetter); 132 return true; 133 } 134 } 135 136 if (OpaqueJSClass::StaticFunctionsTable* staticFunctions = jsClass->staticFunctions) { 137 if (staticFunctions->contains(propertyName.ustring().rep())) { 138 slot.setCustom(this, staticFunctionGetter); 139 return true; 140 } 141 } 142 } 143 144 return JSObject::getOwnPropertySlot(exec, propertyName, slot); 145 } 146 147 bool JSCallbackObject::getOwnPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot) 148 { 149 return getOwnPropertySlot(exec, Identifier::from(propertyName), slot); 150 } 151 152 void JSCallbackObject::put(ExecState* exec, const Identifier& propertyName, JSValue* value, int attr) 153 { 154 JSContextRef ctx = toRef(exec); 155 JSObjectRef thisRef = toRef(this); 156 JSStringRef propertyNameRef = toRef(propertyName.ustring().rep()); 157 JSValueRef valueRef = toRef(value); 158 159 for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass) { 160 if (JSObjectSetPropertyCallback setProperty = jsClass->setProperty) { 161 JSLock::DropAllLocks dropAllLocks; 162 if (setProperty(ctx, thisRef, propertyNameRef, valueRef, toRef(exec->exceptionSlot()))) 163 return; 164 } 165 166 if (OpaqueJSClass::StaticValuesTable* staticValues = jsClass->staticValues) { 167 if (StaticValueEntry* entry = staticValues->get(propertyName.ustring().rep())) { 168 if (entry->attributes & kJSPropertyAttributeReadOnly) 169 return; 170 if (JSObjectSetPropertyCallback setProperty = entry->setProperty) { 171 JSLock::DropAllLocks dropAllLocks; 172 if (setProperty(ctx, thisRef, propertyNameRef, valueRef, toRef(exec->exceptionSlot()))) 173 return; 174 } else 175 throwError(exec, ReferenceError, "Attempt to set a property that is not settable."); 176 } 177 } 178 179 if (OpaqueJSClass::StaticFunctionsTable* staticFunctions = jsClass->staticFunctions) { 180 if (StaticFunctionEntry* entry = staticFunctions->get(propertyName.ustring().rep())) { 181 if (entry->attributes & kJSPropertyAttributeReadOnly) 182 return; 183 putDirect(propertyName, value, attr); // put as override property 184 return; 185 } 186 } 187 } 188 189 return JSObject::put(exec, propertyName, value, attr); 190 } 191 192 void JSCallbackObject::put(ExecState* exec, unsigned propertyName, JSValue* value, int attr) 193 { 194 return put(exec, Identifier::from(propertyName), value, attr); 195 } 196 197 bool JSCallbackObject::deleteProperty(ExecState* exec, const Identifier& propertyName) 198 { 199 JSContextRef ctx = toRef(exec); 200 JSObjectRef thisRef = toRef(this); 201 JSStringRef propertyNameRef = toRef(propertyName.ustring().rep()); 202 203 for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass) { 204 if (JSObjectDeletePropertyCallback deleteProperty = jsClass->deleteProperty) { 205 JSLock::DropAllLocks dropAllLocks; 206 if (deleteProperty(ctx, thisRef, propertyNameRef, toRef(exec->exceptionSlot()))) 207 return true; 208 } 209 210 if (OpaqueJSClass::StaticValuesTable* staticValues = jsClass->staticValues) { 211 if (StaticValueEntry* entry = staticValues->get(propertyName.ustring().rep())) { 212 if (entry->attributes & kJSPropertyAttributeDontDelete) 213 return false; 214 return true; 215 } 216 } 217 218 if (OpaqueJSClass::StaticFunctionsTable* staticFunctions = jsClass->staticFunctions) { 219 if (StaticFunctionEntry* entry = staticFunctions->get(propertyName.ustring().rep())) { 220 if (entry->attributes & kJSPropertyAttributeDontDelete) 221 return false; 222 return true; 223 } 224 } 225 } 226 227 return JSObject::deleteProperty(exec, propertyName); 228 } 229 230 bool JSCallbackObject::deleteProperty(ExecState* exec, unsigned propertyName) 231 { 232 return deleteProperty(exec, Identifier::from(propertyName)); 233 } 234 235 bool JSCallbackObject::implementsConstruct() const 236 { 237 for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass) 238 if (jsClass->callAsConstructor) 239 return true; 240 241 return false; 242 } 243 244 JSObject* JSCallbackObject::construct(ExecState* exec, const List& args) 245 { 246 JSContextRef execRef = toRef(exec); 247 JSObjectRef thisRef = toRef(this); 248 249 for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass) { 250 if (JSObjectCallAsConstructorCallback callAsConstructor = jsClass->callAsConstructor) { 251 int argumentCount = static_cast<int>(args.size()); 252 Vector<JSValueRef, 16> arguments(argumentCount); 253 for (int i = 0; i < argumentCount; i++) 254 arguments[i] = toRef(args[i]); 255 JSLock::DropAllLocks dropAllLocks; 256 return toJS(callAsConstructor(execRef, thisRef, argumentCount, arguments.data(), toRef(exec->exceptionSlot()))); 257 } 258 } 259 260 ASSERT(0); // implementsConstruct should prevent us from reaching here 261 return 0; 262 } 263 264 bool JSCallbackObject::implementsHasInstance() const 265 { 266 for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass) 267 if (jsClass->hasInstance) 268 return true; 269 270 return false; 271 } 272 273 bool JSCallbackObject::hasInstance(ExecState *exec, JSValue *value) 274 { 275 JSContextRef execRef = toRef(exec); 276 JSObjectRef thisRef = toRef(this); 277 278 for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass) 279 if (JSObjectHasInstanceCallback hasInstance = jsClass->hasInstance) { 280 JSLock::DropAllLocks dropAllLocks; 281 return hasInstance(execRef, thisRef, toRef(value), toRef(exec->exceptionSlot())); 282 } 283 284 ASSERT(0); // implementsHasInstance should prevent us from reaching here 285 return 0; 286 } 287 288 289 bool JSCallbackObject::implementsCall() const 290 { 291 for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass) 292 if (jsClass->callAsFunction) 293 return true; 294 295 return false; 296 } 297 298 JSValue* JSCallbackObject::callAsFunction(ExecState* exec, JSObject* thisObj, const List &args) 299 { 300 JSContextRef execRef = toRef(exec); 301 JSObjectRef thisRef = toRef(this); 302 JSObjectRef thisObjRef = toRef(thisObj); 303 304 for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass) { 305 if (JSObjectCallAsFunctionCallback callAsFunction = jsClass->callAsFunction) { 306 int argumentCount = static_cast<int>(args.size()); 307 Vector<JSValueRef, 16> arguments(argumentCount); 308 for (int i = 0; i < argumentCount; i++) 309 arguments[i] = toRef(args[i]); 310 JSLock::DropAllLocks dropAllLocks; 311 return toJS(callAsFunction(execRef, thisRef, thisObjRef, argumentCount, arguments.data(), toRef(exec->exceptionSlot()))); 312 } 313 } 314 315 ASSERT(0); // implementsCall should prevent us from reaching here 316 return 0; 317 } 318 319 void JSCallbackObject::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames) 320 { 321 JSContextRef execRef = toRef(exec); 322 JSObjectRef thisRef = toRef(this); 323 324 for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass) { 325 if (JSObjectGetPropertyNamesCallback getPropertyNames = jsClass->getPropertyNames) { 326 JSLock::DropAllLocks dropAllLocks; 327 getPropertyNames(execRef, thisRef, toRef(&propertyNames)); 328 } 329 330 if (OpaqueJSClass::StaticValuesTable* staticValues = jsClass->staticValues) { 331 typedef OpaqueJSClass::StaticValuesTable::const_iterator iterator; 332 iterator end = staticValues->end(); 333 for (iterator it = staticValues->begin(); it != end; ++it) { 334 UString::Rep* name = it->first.get(); 335 StaticValueEntry* entry = it->second; 336 if (entry->getProperty && !(entry->attributes & kJSPropertyAttributeDontEnum)) 337 propertyNames.add(Identifier(name)); 338 } 339 } 340 341 if (OpaqueJSClass::StaticFunctionsTable* staticFunctions = jsClass->staticFunctions) { 342 typedef OpaqueJSClass::StaticFunctionsTable::const_iterator iterator; 343 iterator end = staticFunctions->end(); 344 for (iterator it = staticFunctions->begin(); it != end; ++it) { 345 UString::Rep* name = it->first.get(); 346 StaticFunctionEntry* entry = it->second; 347 if (!(entry->attributes & kJSPropertyAttributeDontEnum)) 348 propertyNames.add(Identifier(name)); 349 } 350 } 351 } 352 353 JSObject::getPropertyNames(exec, propertyNames); 354 } 355 356 double JSCallbackObject::toNumber(ExecState* exec) const 357 { 358 JSContextRef ctx = toRef(exec); 359 JSObjectRef thisRef = toRef(this); 360 361 for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass) 362 if (JSObjectConvertToTypeCallback convertToType = jsClass->convertToType) { 363 JSLock::DropAllLocks dropAllLocks; 364 if (JSValueRef value = convertToType(ctx, thisRef, kJSTypeNumber, toRef(exec->exceptionSlot()))) 365 return toJS(value)->getNumber(); 366 } 367 368 return JSObject::toNumber(exec); 369 } 370 371 UString JSCallbackObject::toString(ExecState* exec) const 372 { 373 JSContextRef ctx = toRef(exec); 374 JSObjectRef thisRef = toRef(this); 375 376 for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass) 377 if (JSObjectConvertToTypeCallback convertToType = jsClass->convertToType) { 378 JSLock::DropAllLocks dropAllLocks; 379 if (JSValueRef value = convertToType(ctx, thisRef, kJSTypeString, toRef(exec->exceptionSlot()))) 380 return toJS(value)->getString(); 381 } 382 383 return JSObject::toString(exec); 384 } 385 386 void JSCallbackObject::setPrivate(void* data) 387 { 388 m_privateData = data; 389 } 390 391 void* JSCallbackObject::getPrivate() 392 { 393 return m_privateData; 394 } 395 396 bool JSCallbackObject::inherits(JSClassRef c) const 397 { 398 for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass) 399 if (jsClass == c) 400 return true; 401 402 return false; 403 } 404 405 JSValue* JSCallbackObject::cachedValueGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot& slot) 406 { 407 JSValue* v = slot.slotBase(); 408 ASSERT(v); 409 return v; 410 } 411 412 JSValue* JSCallbackObject::staticValueGetter(ExecState* exec, JSObject*, const Identifier& propertyName, const PropertySlot& slot) 413 { 414 ASSERT(slot.slotBase()->inherits(&JSCallbackObject::info)); 415 JSCallbackObject* thisObj = static_cast<JSCallbackObject*>(slot.slotBase()); 416 417 JSObjectRef thisRef = toRef(thisObj); 418 JSStringRef propertyNameRef = toRef(propertyName.ustring().rep()); 419 420 for (JSClassRef jsClass = thisObj->m_class; jsClass; jsClass = jsClass->parentClass) 421 if (OpaqueJSClass::StaticValuesTable* staticValues = jsClass->staticValues) 422 if (StaticValueEntry* entry = staticValues->get(propertyName.ustring().rep())) 423 if (JSObjectGetPropertyCallback getProperty = entry->getProperty) { 424 JSLock::DropAllLocks dropAllLocks; 425 if (JSValueRef value = getProperty(toRef(exec), thisRef, propertyNameRef, toRef(exec->exceptionSlot()))) 426 return toJS(value); 427 } 428 429 return throwError(exec, ReferenceError, "Static value property defined with NULL getProperty callback."); 430 } 431 432 JSValue* JSCallbackObject::staticFunctionGetter(ExecState* exec, JSObject*, const Identifier& propertyName, const PropertySlot& slot) 433 { 434 ASSERT(slot.slotBase()->inherits(&JSCallbackObject::info)); 435 JSCallbackObject* thisObj = static_cast<JSCallbackObject*>(slot.slotBase()); 436 437 if (JSValue* cachedOrOverrideValue = thisObj->getDirect(propertyName)) 438 return cachedOrOverrideValue; 439 440 for (JSClassRef jsClass = thisObj->m_class; jsClass; jsClass = jsClass->parentClass) { 441 if (OpaqueJSClass::StaticFunctionsTable* staticFunctions = jsClass->staticFunctions) { 442 if (StaticFunctionEntry* entry = staticFunctions->get(propertyName.ustring().rep())) { 443 if (JSObjectCallAsFunctionCallback callAsFunction = entry->callAsFunction) { 444 JSObject* o = new JSCallbackFunction(exec, callAsFunction, propertyName); 445 thisObj->putDirect(propertyName, o, entry->attributes); 446 return o; 447 } 448 } 449 } 450 } 451 452 return throwError(exec, ReferenceError, "Static function property defined with NULL callAsFunction callback."); 453 } 454 455 JSValue* JSCallbackObject::callbackGetter(ExecState* exec, JSObject*, const Identifier& propertyName, const PropertySlot& slot) 456 { 457 ASSERT(slot.slotBase()->inherits(&JSCallbackObject::info)); 458 JSCallbackObject* thisObj = static_cast<JSCallbackObject*>(slot.slotBase()); 459 460 JSObjectRef thisRef = toRef(thisObj); 461 JSStringRef propertyNameRef = toRef(propertyName.ustring().rep()); 462 463 for (JSClassRef jsClass = thisObj->m_class; jsClass; jsClass = jsClass->parentClass) 464 if (JSObjectGetPropertyCallback getProperty = jsClass->getProperty) { 465 JSLock::DropAllLocks dropAllLocks; 466 if (JSValueRef value = getProperty(toRef(exec), thisRef, propertyNameRef, toRef(exec->exceptionSlot()))) 467 return toJS(value); 468 } 469 470 return throwError(exec, ReferenceError, "hasProperty callback returned true for a property that doesn't exist."); 471 } 32 // Define the two types of JSCallbackObjects we support. 33 template <> const ClassInfo JSCallbackObject<JSObject>::info = { "CallbackObject", 0, 0, 0 }; 34 template <> const ClassInfo JSCallbackObject<JSGlobalObject>::info = { "CallbackGlobalObject", 0, 0, 0 }; 472 35 473 36 } // namespace KJS -
trunk/JavaScriptCore/API/JSCallbackObject.h
r25257 r27022 2 2 /* 3 3 * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. 4 * Copyright (C) 2007 Eric Seidel <[email protected]> 4 5 * 5 6 * Redistribution and use in source and binary forms, with or without … … 34 35 namespace KJS { 35 36 36 class JSCallbackObject : public JSObject 37 template <class Base> 38 class JSCallbackObject : public Base 37 39 { 38 40 public: … … 93 95 } // namespace KJS 94 96 97 // include the actual template class implementation 98 #include "JSCallbackObjectFunctions.h" 99 95 100 #endif // JSCallbackObject_h -
trunk/JavaScriptCore/API/JSCallbackObjectFunctions.h
r27021 r27022 2 2 /* 3 3 * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. 4 * Copyright (C) 2007 Eric Seidel <[email protected]> 4 5 * 5 6 * Redistribution and use in source and binary forms, with or without … … 26 27 27 28 #include <wtf/Platform.h> 28 #include "JSCallbackObject.h"29 30 29 #include "APICast.h" 31 30 #include "JSCallbackFunction.h" 32 31 #include "JSClassRef.h" 33 32 #include "JSObjectRef.h" 33 #include "JSGlobalObject.h" 34 34 #include "JSStringRef.h" 35 35 #include "PropertyNameArray.h" … … 39 39 namespace KJS { 40 40 41 const ClassInfo JSCallbackObject::info = { "CallbackObject", 0, 0, 0 }; 42 43 JSCallbackObject::JSCallbackObject(ExecState* exec, JSClassRef jsClass, JSValue* prototype, void* data) 44 : JSObject(prototype) 41 template <class Base> 42 JSCallbackObject<Base>::JSCallbackObject(ExecState* exec, JSClassRef jsClass, JSValue* prototype, void* data) 43 : Base(prototype) 45 44 , m_class(0) 46 45 , m_isInitialized(false) … … 49 48 } 50 49 51 void JSCallbackObject::init(ExecState* exec, JSClassRef jsClass, void* data) 50 template <class Base> 51 void JSCallbackObject<Base>::init(ExecState* exec, JSClassRef jsClass, void* data) 52 52 { 53 53 m_privateData = data; … … 56 56 if (oldClass) 57 57 JSClassRelease(oldClass); 58 58 59 59 if (!exec) 60 60 return; 61 61 62 62 Vector<JSObjectInitializeCallback, 16> initRoutines; 63 63 do { … … 75 75 } 76 76 77 JSCallbackObject::~JSCallbackObject() 77 template <class Base> 78 JSCallbackObject<Base>::~JSCallbackObject() 78 79 { 79 80 JSObjectRef thisRef = toRef(this); … … 83 84 finalize(thisRef); 84 85 } 85 86 86 87 JSClassRelease(m_class); 87 88 } 88 89 89 void JSCallbackObject::initializeIfNeeded(ExecState* exec) 90 template <class Base> 91 void JSCallbackObject<Base>::initializeIfNeeded(ExecState* exec) 90 92 { 91 93 if (m_isInitialized) … … 94 96 } 95 97 96 UString JSCallbackObject::className() const 98 template <class Base> 99 UString JSCallbackObject<Base>::className() const 97 100 { 98 101 if (!m_class->className.isNull()) … … 102 105 } 103 106 104 bool JSCallbackObject::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) 107 template <class Base> 108 bool JSCallbackObject<Base>::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) 105 109 { 106 110 JSContextRef ctx = toRef(exec); 107 111 JSObjectRef thisRef = toRef(this); 108 112 JSStringRef propertyNameRef = toRef(propertyName.ustring().rep()); 109 113 110 114 for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass) { 111 115 // optional optimization to bypass getProperty in cases when we only need to know if the property exists … … 126 130 } 127 131 } 128 132 129 133 if (OpaqueJSClass::StaticValuesTable* staticValues = jsClass->staticValues) { 130 134 if (staticValues->contains(propertyName.ustring().rep())) { … … 141 145 } 142 146 } 143 147 144 148 return JSObject::getOwnPropertySlot(exec, propertyName, slot); 145 149 } 146 150 147 bool JSCallbackObject::getOwnPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot) 151 template <class Base> 152 bool JSCallbackObject<Base>::getOwnPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot) 148 153 { 149 154 return getOwnPropertySlot(exec, Identifier::from(propertyName), slot); 150 155 } 151 156 152 void JSCallbackObject::put(ExecState* exec, const Identifier& propertyName, JSValue* value, int attr) 157 template <class Base> 158 void JSCallbackObject<Base>::put(ExecState* exec, const Identifier& propertyName, JSValue* value, int attr) 153 159 { 154 160 JSContextRef ctx = toRef(exec); … … 156 162 JSStringRef propertyNameRef = toRef(propertyName.ustring().rep()); 157 163 JSValueRef valueRef = toRef(value); 158 164 159 165 for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass) { 160 166 if (JSObjectSetPropertyCallback setProperty = jsClass->setProperty) { … … 163 169 return; 164 170 } 165 171 166 172 if (OpaqueJSClass::StaticValuesTable* staticValues = jsClass->staticValues) { 167 173 if (StaticValueEntry* entry = staticValues->get(propertyName.ustring().rep())) { … … 181 187 if (entry->attributes & kJSPropertyAttributeReadOnly) 182 188 return; 183 putDirect(propertyName, value, attr); // put as override property189 JSCallbackObject<Base>::putDirect(propertyName, value, attr); // put as override property 184 190 return; 185 191 } 186 192 } 187 193 } 188 194 189 195 return JSObject::put(exec, propertyName, value, attr); 190 196 } 191 197 192 void JSCallbackObject::put(ExecState* exec, unsigned propertyName, JSValue* value, int attr) 198 template <class Base> 199 void JSCallbackObject<Base>::put(ExecState* exec, unsigned propertyName, JSValue* value, int attr) 193 200 { 194 201 return put(exec, Identifier::from(propertyName), value, attr); 195 202 } 196 203 197 bool JSCallbackObject::deleteProperty(ExecState* exec, const Identifier& propertyName) 204 template <class Base> 205 bool JSCallbackObject<Base>::deleteProperty(ExecState* exec, const Identifier& propertyName) 198 206 { 199 207 JSContextRef ctx = toRef(exec); … … 207 215 return true; 208 216 } 209 217 210 218 if (OpaqueJSClass::StaticValuesTable* staticValues = jsClass->staticValues) { 211 219 if (StaticValueEntry* entry = staticValues->get(propertyName.ustring().rep())) { … … 224 232 } 225 233 } 226 234 227 235 return JSObject::deleteProperty(exec, propertyName); 228 236 } 229 237 230 bool JSCallbackObject::deleteProperty(ExecState* exec, unsigned propertyName) 238 template <class Base> 239 bool JSCallbackObject<Base>::deleteProperty(ExecState* exec, unsigned propertyName) 231 240 { 232 241 return deleteProperty(exec, Identifier::from(propertyName)); 233 242 } 234 243 235 bool JSCallbackObject::implementsConstruct() const 244 template <class Base> 245 bool JSCallbackObject<Base>::implementsConstruct() const 236 246 { 237 247 for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass) 238 248 if (jsClass->callAsConstructor) 239 249 return true; 240 250 241 251 return false; 242 252 } 243 253 244 JSObject* JSCallbackObject::construct(ExecState* exec, const List& args) 254 template <class Base> 255 JSObject* JSCallbackObject<Base>::construct(ExecState* exec, const List& args) 245 256 { 246 257 JSContextRef execRef = toRef(exec); … … 262 273 } 263 274 264 bool JSCallbackObject::implementsHasInstance() const 275 template <class Base> 276 bool JSCallbackObject<Base>::implementsHasInstance() const 265 277 { 266 278 for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass) 267 279 if (jsClass->hasInstance) 268 280 return true; 269 281 270 282 return false; 271 283 } 272 284 273 bool JSCallbackObject::hasInstance(ExecState *exec, JSValue *value) 285 template <class Base> 286 bool JSCallbackObject<Base>::hasInstance(ExecState *exec, JSValue *value) 274 287 { 275 288 JSContextRef execRef = toRef(exec); 276 289 JSObjectRef thisRef = toRef(this); 277 290 278 291 for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass) 279 292 if (JSObjectHasInstanceCallback hasInstance = jsClass->hasInstance) { … … 281 294 return hasInstance(execRef, thisRef, toRef(value), toRef(exec->exceptionSlot())); 282 295 } 283 284 ASSERT (0); // implementsHasInstance should prevent us from reaching here296 297 ASSERT_NOT_REACHED(); // implementsHasInstance should prevent us from reaching here 285 298 return 0; 286 299 } 287 300 288 301 289 bool JSCallbackObject::implementsCall() const 302 template <class Base> 303 bool JSCallbackObject<Base>::implementsCall() const 290 304 { 291 305 for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass) … … 296 310 } 297 311 298 JSValue* JSCallbackObject::callAsFunction(ExecState* exec, JSObject* thisObj, const List &args) 312 template <class Base> 313 JSValue* JSCallbackObject<Base>::callAsFunction(ExecState* exec, JSObject* thisObj, const List &args) 299 314 { 300 315 JSContextRef execRef = toRef(exec); 301 316 JSObjectRef thisRef = toRef(this); 302 317 JSObjectRef thisObjRef = toRef(thisObj); 303 318 304 319 for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass) { 305 320 if (JSObjectCallAsFunctionCallback callAsFunction = jsClass->callAsFunction) { … … 312 327 } 313 328 } 314 315 ASSERT (0); // implementsCall should prevent us from reaching here329 330 ASSERT_NOT_REACHED(); // implementsCall should prevent us from reaching here 316 331 return 0; 317 332 } 318 333 319 void JSCallbackObject::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames) 334 template <class Base> 335 void JSCallbackObject<Base>::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames) 320 336 { 321 337 JSContextRef execRef = toRef(exec); 322 338 JSObjectRef thisRef = toRef(this); 323 339 324 340 for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass) { 325 341 if (JSObjectGetPropertyNamesCallback getPropertyNames = jsClass->getPropertyNames) { … … 327 343 getPropertyNames(execRef, thisRef, toRef(&propertyNames)); 328 344 } 329 345 330 346 if (OpaqueJSClass::StaticValuesTable* staticValues = jsClass->staticValues) { 331 347 typedef OpaqueJSClass::StaticValuesTable::const_iterator iterator; … … 338 354 } 339 355 } 340 356 341 357 if (OpaqueJSClass::StaticFunctionsTable* staticFunctions = jsClass->staticFunctions) { 342 358 typedef OpaqueJSClass::StaticFunctionsTable::const_iterator iterator; … … 350 366 } 351 367 } 352 368 353 369 JSObject::getPropertyNames(exec, propertyNames); 354 370 } 355 371 356 double JSCallbackObject::toNumber(ExecState* exec) const 372 template <class Base> 373 double JSCallbackObject<Base>::toNumber(ExecState* exec) const 357 374 { 358 375 JSContextRef ctx = toRef(exec); 359 376 JSObjectRef thisRef = toRef(this); 360 377 361 378 for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass) 362 379 if (JSObjectConvertToTypeCallback convertToType = jsClass->convertToType) { … … 365 382 return toJS(value)->getNumber(); 366 383 } 367 384 368 385 return JSObject::toNumber(exec); 369 386 } 370 387 371 UString JSCallbackObject::toString(ExecState* exec) const 388 template <class Base> 389 UString JSCallbackObject<Base>::toString(ExecState* exec) const 372 390 { 373 391 JSContextRef ctx = toRef(exec); 374 392 JSObjectRef thisRef = toRef(this); 375 393 376 394 for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass) 377 395 if (JSObjectConvertToTypeCallback convertToType = jsClass->convertToType) { … … 380 398 return toJS(value)->getString(); 381 399 } 382 400 383 401 return JSObject::toString(exec); 384 402 } 385 403 386 void JSCallbackObject::setPrivate(void* data) 404 template <class Base> 405 void JSCallbackObject<Base>::setPrivate(void* data) 387 406 { 388 407 m_privateData = data; 389 408 } 390 409 391 void* JSCallbackObject::getPrivate() 410 template <class Base> 411 void* JSCallbackObject<Base>::getPrivate() 392 412 { 393 413 return m_privateData; 394 414 } 395 415 396 bool JSCallbackObject::inherits(JSClassRef c) const 416 template <class Base> 417 bool JSCallbackObject<Base>::inherits(JSClassRef c) const 397 418 { 398 419 for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass) 399 420 if (jsClass == c) 400 421 return true; 401 422 402 423 return false; 403 424 } 404 425 405 JSValue* JSCallbackObject::cachedValueGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot& slot) 426 template <class Base> 427 JSValue* JSCallbackObject<Base>::cachedValueGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot& slot) 406 428 { 407 429 JSValue* v = slot.slotBase(); … … 410 432 } 411 433 412 JSValue* JSCallbackObject::staticValueGetter(ExecState* exec, JSObject*, const Identifier& propertyName, const PropertySlot& slot) 434 template <class Base> 435 JSValue* JSCallbackObject<Base>::staticValueGetter(ExecState* exec, JSObject*, const Identifier& propertyName, const PropertySlot& slot) 413 436 { 414 437 ASSERT(slot.slotBase()->inherits(&JSCallbackObject::info)); 415 438 JSCallbackObject* thisObj = static_cast<JSCallbackObject*>(slot.slotBase()); 416 439 417 440 JSObjectRef thisRef = toRef(thisObj); 418 441 JSStringRef propertyNameRef = toRef(propertyName.ustring().rep()); 419 442 420 443 for (JSClassRef jsClass = thisObj->m_class; jsClass; jsClass = jsClass->parentClass) 421 444 if (OpaqueJSClass::StaticValuesTable* staticValues = jsClass->staticValues) … … 426 449 return toJS(value); 427 450 } 428 451 429 452 return throwError(exec, ReferenceError, "Static value property defined with NULL getProperty callback."); 430 453 } 431 454 432 JSValue* JSCallbackObject::staticFunctionGetter(ExecState* exec, JSObject*, const Identifier& propertyName, const PropertySlot& slot) 455 template <class Base> 456 JSValue* JSCallbackObject<Base>::staticFunctionGetter(ExecState* exec, JSObject*, const Identifier& propertyName, const PropertySlot& slot) 433 457 { 434 458 ASSERT(slot.slotBase()->inherits(&JSCallbackObject::info)); 435 459 JSCallbackObject* thisObj = static_cast<JSCallbackObject*>(slot.slotBase()); 436 460 437 461 if (JSValue* cachedOrOverrideValue = thisObj->getDirect(propertyName)) 438 462 return cachedOrOverrideValue; 439 463 440 464 for (JSClassRef jsClass = thisObj->m_class; jsClass; jsClass = jsClass->parentClass) { 441 465 if (OpaqueJSClass::StaticFunctionsTable* staticFunctions = jsClass->staticFunctions) { … … 449 473 } 450 474 } 451 475 452 476 return throwError(exec, ReferenceError, "Static function property defined with NULL callAsFunction callback."); 453 477 } 454 478 455 JSValue* JSCallbackObject::callbackGetter(ExecState* exec, JSObject*, const Identifier& propertyName, const PropertySlot& slot) 479 template <class Base> 480 JSValue* JSCallbackObject<Base>::callbackGetter(ExecState* exec, JSObject*, const Identifier& propertyName, const PropertySlot& slot) 456 481 { 457 482 ASSERT(slot.slotBase()->inherits(&JSCallbackObject::info)); 458 483 JSCallbackObject* thisObj = static_cast<JSCallbackObject*>(slot.slotBase()); 459 484 460 485 JSObjectRef thisRef = toRef(thisObj); 461 486 JSStringRef propertyNameRef = toRef(propertyName.ustring().rep()); 462 487 463 488 for (JSClassRef jsClass = thisObj->m_class; jsClass; jsClass = jsClass->parentClass) 464 489 if (JSObjectGetPropertyCallback getProperty = jsClass->getProperty) { … … 467 492 return toJS(value); 468 493 } 469 494 470 495 return throwError(exec, ReferenceError, "hasProperty callback returned true for a property that doesn't exist."); 471 496 } -
trunk/JavaScriptCore/API/JSClassRef.cpp
r24809 r27022 157 157 if (!parentPrototype) 158 158 parentPrototype = exec->dynamicInterpreter()->builtinObjectPrototype(); 159 cachedPrototype = new JSCallbackObject (exec, prototypeClass, parentPrototype, this); // set ourself as the object's private data, so it can clear our reference on destruction159 cachedPrototype = new JSCallbackObject<JSObject>(exec, prototypeClass, parentPrototype, this); // set ourself as the object's private data, so it can clear our reference on destruction 160 160 } 161 161 return cachedPrototype; -
trunk/JavaScriptCore/API/JSContextRef.cpp
r25257 r27022 30 30 31 31 #include "JSCallbackObject.h" 32 #include "JSGlobalObject.h" 32 33 #include "completion.h" 33 34 #include "interpreter.h" … … 40 41 JSLock lock; 41 42 42 JS Object* globalObject;43 JSGlobalObject* globalObject; 43 44 if (globalObjectClass) 44 45 // Specify jsNull() as the prototype. Interpreter will fix it up to point at builtinObjectPrototype() in its constructor 45 globalObject = new JSCallbackObject (0, globalObjectClass, jsNull(), 0);46 globalObject = new JSCallbackObject<JSGlobalObject>(0, globalObjectClass, jsNull(), 0); 46 47 else 47 globalObject = new JS Object();48 globalObject = new JSGlobalObject(); 48 49 49 50 Interpreter* interpreter = new Interpreter(globalObject); // adds the built-in object prototype to the global object 50 51 if (globalObjectClass) 51 static_cast<JSCallbackObject *>(globalObject)->initializeIfNeeded(interpreter->globalExec());52 static_cast<JSCallbackObject<JSGlobalObject>*>(globalObject)->initializeIfNeeded(interpreter->globalExec()); 52 53 JSGlobalContextRef ctx = reinterpret_cast<JSGlobalContextRef>(interpreter->globalExec()); 53 54 return JSGlobalContextRetain(ctx); -
trunk/JavaScriptCore/API/JSObjectRef.cpp
r26625 r27022 33 33 #include "JSCallbackObject.h" 34 34 #include "JSClassRef.h" 35 #include "JSGlobalObject.h" 35 36 36 37 #include "identifier.h" … … 78 79 jsPrototype = exec->lexicalInterpreter()->builtinObjectPrototype(); 79 80 80 return toRef(new JSCallbackObject (exec, jsClass, jsPrototype, data));81 return toRef(new JSCallbackObject<JSObject>(exec, jsClass, jsPrototype, data)); 81 82 } 82 83 … … 236 237 JSObject* jsObject = toJS(object); 237 238 238 if (jsObject->inherits(&JSCallbackObject::info)) 239 return static_cast<JSCallbackObject*>(jsObject)->getPrivate(); 239 if (jsObject->inherits(&JSCallbackObject<JSGlobalObject>::info)) 240 return static_cast<JSCallbackObject<JSGlobalObject>*>(jsObject)->getPrivate(); 241 else if (jsObject->inherits(&JSCallbackObject<JSObject>::info)) 242 return static_cast<JSCallbackObject<JSObject>*>(jsObject)->getPrivate(); 240 243 241 244 return 0; … … 246 249 JSObject* jsObject = toJS(object); 247 250 248 if (jsObject->inherits(&JSCallbackObject::info)) { 249 static_cast<JSCallbackObject*>(jsObject)->setPrivate(data); 251 if (jsObject->inherits(&JSCallbackObject<JSGlobalObject>::info)) { 252 static_cast<JSCallbackObject<JSGlobalObject>*>(jsObject)->setPrivate(data); 253 return true; 254 } else if (jsObject->inherits(&JSCallbackObject<JSObject>::info)) { 255 static_cast<JSCallbackObject<JSObject>*>(jsObject)->setPrivate(data); 250 256 return true; 251 257 } -
trunk/JavaScriptCore/API/JSValueRef.cpp
r19193 r27022 31 31 32 32 #include <kjs/JSType.h> 33 #include <kjs/JSGlobalObject.h> 33 34 #include <kjs/internal.h> 34 35 #include <kjs/operations.h> … … 105 106 JSValue* jsValue = toJS(value); 106 107 107 if (JSObject* o = jsValue->getObject()) 108 if (o->inherits(&JSCallbackObject::info)) 109 return static_cast<JSCallbackObject*>(o)->inherits(jsClass); 108 if (JSObject* o = jsValue->getObject()) { 109 if (o->inherits(&JSCallbackObject<JSGlobalObject>::info)) 110 return static_cast<JSCallbackObject<JSGlobalObject>*>(o)->inherits(jsClass); 111 else if (o->inherits(&JSCallbackObject<JSObject>::info)) 112 return static_cast<JSCallbackObject<JSObject>*>(o)->inherits(jsClass); 113 } 110 114 return false; 111 115 }
Note:
See TracChangeset
for help on using the changeset viewer.