1 #include "UserObjectImp.h"
2 #include "JavaScriptCore/IdentifierSequencedSet.h"
4 const ClassInfo UserObjectImp::info = {"UserObject", 0, 0, 0};
6 class UserObjectPrototypeImp : public UserObjectImp {
8 UserObjectPrototypeImp();
9 static UserObjectPrototypeImp* GlobalUserObjectPrototypeImp();
11 static UserObjectPrototypeImp* sUserObjectPrototypeImp;
14 UserObjectPrototypeImp* UserObjectPrototypeImp::sUserObjectPrototypeImp = 0;
16 UserObjectPrototypeImp::UserObjectPrototypeImp()
21 UserObjectPrototypeImp* UserObjectPrototypeImp::GlobalUserObjectPrototypeImp()
23 if (!sUserObjectPrototypeImp)
25 sUserObjectPrototypeImp = new UserObjectPrototypeImp();
26 static ProtectedPtr<UserObjectPrototypeImp> protectPrototype;
28 return sUserObjectPrototypeImp;
32 UserObjectImp::UserObjectImp(): ObjectImp(), fJSUserObject(0)
36 UserObjectImp::UserObjectImp(JSUserObject* userObject) :
37 ObjectImp(UserObjectPrototypeImp::GlobalUserObjectPrototypeImp()),
38 fJSUserObject((JSUserObject*)userObject->Retain())
42 UserObjectImp::~UserObjectImp()
46 fJSUserObject->Release();
50 const ClassInfo * UserObjectImp::classInfo() const
55 bool UserObjectImp::implementsCall() const
57 return fJSUserObject ? fJSUserObject->ImplementsCall() : false;
60 ValueImp *UserObjectImp::callAsFunction(ExecState *exec, ObjectImp *thisObj, const List &args)
62 ValueImp *result = Undefined();
63 JSUserObject* jsThisObj = KJSValueToJSObject(thisObj, exec);
65 CFIndex argCount = args.size();
66 CFArrayCallBacks arrayCallBacks;
67 JSTypeGetCFArrayCallBacks(&arrayCallBacks);
68 CFMutableArrayRef jsArgs = CFArrayCreateMutable(0, 0, &arrayCallBacks);
70 for (CFIndex i = 0; i < argCount; i++) {
71 JSUserObject* jsArg = KJSValueToJSObject(args[i], exec);
72 CFArrayAppendValue(jsArgs, (void*)jsArg);
77 int lockCount = Interpreter::lockCount();
79 for (i = 0; i < lockCount; i++) {
80 Interpreter::unlock();
83 JSUserObject* jsResult = fJSUserObject->CallFunction(jsThisObj, jsArgs);
85 for (i = 0; i < lockCount; i++) {
89 result = JSObjectKJSValue(jsResult);
93 ReleaseCFType(jsArgs);
100 void UserObjectImp::getPropertyNames(ExecState *exec, IdentifierSequencedSet& propertyNames)
102 JSUserObject* ptr = GetJSUserObject();
104 CFArrayRef cfPropertyNames = ptr->CopyPropertyNames();
105 if (cfPropertyNames) {
106 CFIndex count = CFArrayGetCount(cfPropertyNames);
108 for (i = 0; i < count; i++) {
109 CFStringRef propertyName = (CFStringRef)CFArrayGetValueAtIndex(cfPropertyNames, i);
110 propertyNames.insert(CFStringToIdentifier(propertyName));
112 CFRelease(cfPropertyNames);
115 ObjectImp::getPropertyNames(exec, propertyNames);
118 ValueImp *UserObjectImp::userObjectGetter(ExecState *, const Identifier& propertyName, const PropertySlot& slot)
120 UserObjectImp *thisObj = static_cast<UserObjectImp *>(slot.slotBase());
121 CFStringRef cfPropName = IdentifierToCFString(propertyName);
122 JSUserObject *jsResult = thisObj->fJSUserObject->CopyProperty(cfPropName);
123 ReleaseCFType(cfPropName);
124 ValueImp *result = JSObjectKJSValue(jsResult);
130 bool UserObjectImp::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot)
132 CFStringRef cfPropName = IdentifierToCFString(propertyName);
133 JSUserObject *jsResult = fJSUserObject->CopyProperty(cfPropName);
134 ReleaseCFType(cfPropName);
136 slot.setCustom(this, userObjectGetter);
140 ValueImp *kjsValue = toPrimitive(exec);
141 if (kjsValue->type() != NullType && kjsValue->type() != UndefinedType) {
142 ObjectImp *kjsObject = kjsValue->toObject(exec);
143 if (kjsObject->getPropertySlot(exec, propertyName, slot))
147 return ObjectImp::getOwnPropertySlot(exec, propertyName, slot);
150 void UserObjectImp::put(ExecState *exec, const Identifier &propertyName, ValueImp *value, int attr)
152 CFStringRef cfPropName = IdentifierToCFString(propertyName);
153 JSUserObject *jsValueObj = KJSValueToJSObject(value, exec);
155 fJSUserObject->SetProperty(cfPropName, jsValueObj);
157 if (jsValueObj) jsValueObj->Release();
158 ReleaseCFType(cfPropName);
161 JSUserObject* UserObjectImp::GetJSUserObject() const
163 return fJSUserObject;
166 ValueImp *UserObjectImp::toPrimitive(ExecState *exec, Type preferredType) const
168 ValueImp *result = Undefined();
169 JSUserObject* jsObjPtr = KJSValueToJSObject(toObject(exec), exec);
170 CFTypeRef cfValue = jsObjPtr ? jsObjPtr->CopyCFValue() : 0;
172 CFTypeID cfType = CFGetTypeID(cfValue); // toPrimitive
173 if (cfValue == GetCFNull()) {
176 else if (cfType == CFBooleanGetTypeID()) {
177 if (cfValue == kCFBooleanTrue) {
178 result = KJS::Boolean(true);
180 result = KJS::Boolean(false);
182 } else if (cfType == CFStringGetTypeID()) {
183 result = KJS::String(CFStringToUString((CFStringRef)cfValue));
184 } else if (cfType == CFNumberGetTypeID()) {
186 CFNumberGetValue((CFNumberRef)cfValue, kCFNumberDoubleType, &d);
187 result = KJS::Number(d);
188 } else if (cfType == CFURLGetTypeID()) {
189 CFURLRef absURL = CFURLCopyAbsoluteURL((CFURLRef)cfValue);
191 result = KJS::String(CFStringToUString(CFURLGetString(absURL)));
192 ReleaseCFType(absURL);
195 ReleaseCFType(cfValue);
203 bool UserObjectImp::toBoolean(ExecState *exec) const
206 JSUserObject* jsObjPtr = KJSValueToJSObject(toObject(exec), exec);
207 CFTypeRef cfValue = jsObjPtr ? jsObjPtr->CopyCFValue() : 0;
210 CFTypeID cfType = CFGetTypeID(cfValue); // toPrimitive
211 if (cfValue == GetCFNull())
215 else if (cfType == CFBooleanGetTypeID())
217 if (cfValue == kCFBooleanTrue)
222 else if (cfType == CFStringGetTypeID())
224 if (CFStringGetLength((CFStringRef)cfValue))
229 else if (cfType == CFNumberGetTypeID())
231 if (cfValue != kCFNumberNaN)
234 if (CFNumberGetValue((CFNumberRef)cfValue, kCFNumberDoubleType, &d))
243 else if (cfType == CFArrayGetTypeID())
245 if (CFArrayGetCount((CFArrayRef)cfValue))
250 else if (cfType == CFDictionaryGetTypeID())
252 if (CFDictionaryGetCount((CFDictionaryRef)cfValue))
257 else if (cfType == CFSetGetTypeID())
259 if (CFSetGetCount((CFSetRef)cfValue))
264 else if (cfType == CFURLGetTypeID())
266 CFURLRef absURL = CFURLCopyAbsoluteURL((CFURLRef)cfValue);
269 CFStringRef cfStr = CFURLGetString(absURL);
270 if (cfStr && CFStringGetLength(cfStr))
274 ReleaseCFType(absURL);
278 if (jsObjPtr) jsObjPtr->Release();
279 ReleaseCFType(cfValue);
283 double UserObjectImp::toNumber(ExecState *exec) const
286 JSUserObject* jsObjPtr = KJSValueToJSObject(toObject(exec), exec);
287 CFTypeRef cfValue = jsObjPtr ? jsObjPtr->CopyCFValue() : 0;
290 CFTypeID cfType = CFGetTypeID(cfValue);
292 if (cfValue == GetCFNull())
296 else if (cfType == CFBooleanGetTypeID())
298 if (cfValue == kCFBooleanTrue)
303 else if (cfType == CFStringGetTypeID())
305 result = CFStringGetDoubleValue((CFStringRef)cfValue);
307 else if (cfType == CFNumberGetTypeID())
309 CFNumberGetValue((CFNumberRef)cfValue, kCFNumberDoubleType, &result);
312 ReleaseCFType(cfValue);
313 if (jsObjPtr) jsObjPtr->Release();
317 UString UserObjectImp::toString(ExecState *exec) const
320 JSUserObject* jsObjPtr = KJSValueToJSObject(toObject(exec), exec);
321 CFTypeRef cfValue = jsObjPtr ? jsObjPtr->CopyCFValue() : 0;
324 CFTypeID cfType = CFGetTypeID(cfValue);
325 if (cfValue == GetCFNull())
329 else if (cfType == CFBooleanGetTypeID())
331 if (cfValue == kCFBooleanTrue)
340 else if (cfType == CFStringGetTypeID())
342 result = CFStringToUString((CFStringRef)cfValue);
344 else if (cfType == CFNumberGetTypeID())
346 if (cfValue == kCFNumberNaN)
350 else if (CFNumberCompare(kCFNumberPositiveInfinity, (CFNumberRef)cfValue, 0) == 0)
354 else if (CFNumberCompare(kCFNumberNegativeInfinity, (CFNumberRef)cfValue, 0) == 0)
356 result = "-Infinity";
360 CFStringRef cfNumStr = 0;
361 if (CFNumberIsFloatType((CFNumberRef)cfValue))
364 CFNumberGetValue((CFNumberRef)cfValue, kCFNumberDoubleType, &d);
365 cfNumStr = CFStringCreateWithFormat(0, 0, CFSTR("%f"), (float)d);
370 CFNumberGetValue((CFNumberRef)cfValue, kCFNumberIntType, &i);
371 cfNumStr = CFStringCreateWithFormat(0, 0, CFSTR("%d"), (int)i);
376 result = CFStringToUString(cfNumStr);
377 ReleaseCFType(cfNumStr);
381 else if (cfType == CFArrayGetTypeID())
385 else if (cfType == CFDictionaryGetTypeID())
389 else if (cfType == CFSetGetTypeID())
393 else if (cfType == CFURLGetTypeID())
395 CFURLRef absURL = CFURLCopyAbsoluteURL((CFURLRef)cfValue);
398 CFStringRef cfStr = CFURLGetString(absURL);
401 result = CFStringToUString(cfStr);
403 ReleaseCFType(absURL);
407 ReleaseCFType(cfValue);
408 if (jsObjPtr) jsObjPtr->Release();
412 void UserObjectImp::mark()
414 ObjectImp::mark(); // call parent to mark self
416 fJSUserObject->Mark(); // mark child