5 #include "JavaScriptGlue.h"
11 static CFTypeRef sJSCFNullRef = 0;
13 static void CFJSObjectDispose(void *data);
14 static JSObjectRef CFJSObjectCopyProperty(void *data, CFStringRef propertyName);
15 static void CFJSObjectSetProperty(void *data, CFStringRef propertyName, JSObjectRef jsValue);
16 static CFTypeRef CFJSObjectCopyCFValue(void *data);
17 static UInt8 CFJSObjectEqual(void *data1, void *data2);
18 static CFArrayRef CFJSObjectCopyPropertyNames(void *data);
20 void *JSCFRetain(CFAllocatorRef allocator, const void *value);
21 void JSCFRelease(CFAllocatorRef allocator, const void *value);
24 void JSSetCFNull(CFTypeRef nullRef)
26 ReleaseCFType(sJSCFNullRef);
27 sJSCFNullRef = RetainCFType(nullRef);
30 CFTypeRef JSGetCFNull(void)
38 JSTypeRef JSRetain(JSTypeRef ref)
42 JSBase* ptr = (JSBase*)ref;
51 void JSRelease(JSTypeRef ref)
55 JSBase* ptr = (JSBase*)ref;
63 CFStringRef JSCopyDescription(JSTypeRef ref)
65 CFStringRef result = 0;
68 JSBase* ptr = (JSBase*)ref;
69 ptr->CopyDescription();
77 UInt8 JSEqual(JSTypeRef ref1, JSTypeRef ref2)
82 JSBase* ptr = (JSBase*)ref1;
83 result = ptr->Equal((JSBase*)ref2);
92 JSTypeID JSGetTypeID(JSTypeRef ref)
94 JSTypeID result = kJSInvalidTypeID;
97 JSBase* ptr = (JSBase*)ref;
98 result = ptr->GetTypeID();
107 CFIndex JSGetRetainCount(JSTypeRef ref)
112 JSBase* ptr = (JSBase*)ref;
113 result = ptr->RetainCount();
123 JSObjectRef JSObjectCreate(void *data, JSObjectCallBacksPtr callBacks)
125 JSObjectRef result = JSObjectCreateInternal(data, callBacks, 0, kJSUserObjectDataTypeUnknown);
130 JSObjectCreateInternal
132 JSObjectRef JSObjectCreateInternal(void *data, JSObjectCallBacksPtr callBacks, JSObjectMarkProcPtr markProc, int type)
134 JSObjectRef result = 0;
135 JSUserObject* ptr = new JSUserObject(callBacks, markProc, data, type);
136 result = (JSObjectRef)ptr;
143 CFTypeRef JSObjectCopyCFValue(JSObjectRef ref)
145 CFTypeRef result = 0;
146 JSUserObject* ptr = (JSUserObject*)ref;
147 if (ptr && (ptr->GetTypeID() == kJSObjectTypeID))
149 result = ptr->CopyCFValue();
157 void *JSObjectGetData(JSObjectRef ref)
160 JSUserObject* ptr = (JSUserObject*)ref;
161 if (ptr && (ptr->GetTypeID() == kJSObjectTypeID))
163 result = ptr->GetData();
172 JSObjectRef JSObjectCopyProperty(JSObjectRef ref, CFStringRef propertyName)
174 JSObjectRef result = 0;
175 JSUserObject* ptr = (JSUserObject*)ref;
176 if (ptr && (ptr->GetTypeID() == kJSObjectTypeID))
178 result = (JSObjectRef)ptr->CopyProperty(propertyName);
187 void JSObjectSetProperty(JSObjectRef ref, CFStringRef propertyName, JSObjectRef value)
189 JSUserObject* ptr = (JSUserObject*)ref;
190 if (ptr && (ptr->GetTypeID() == kJSObjectTypeID))
192 ptr->SetProperty(propertyName, (JSUserObject*)value);
200 JSObjectRef JSObjectCallFunction(JSObjectRef ref, JSObjectRef thisObj, CFArrayRef args)
202 JSObjectRef result = 0;
203 JSUserObject* ptr = (JSUserObject*)ref;
204 if (ptr && (ptr->GetTypeID() == kJSObjectTypeID))
206 result = (JSObjectRef)ptr->CallFunction((JSUserObject*)thisObj, args);
215 JSRunRef JSRunCreate(CFStringRef jsSource, JSFlags inFlags)
220 result = (JSRunRef) new JSRun(jsSource, inFlags);
228 CFStringRef JSRunCopySource(JSRunRef ref)
230 CFStringRef result = 0;
231 JSRun* ptr = (JSRun*)ref;
234 result = UStringToCFString(ptr->GetSource());
241 JSRunCopyGlobalObject
243 JSObjectRef JSRunCopyGlobalObject(JSRunRef ref)
245 JSObjectRef result = 0;
246 JSRun* ptr = (JSRun*)ref;
249 ObjectImp *globalObject = ptr->GlobalObject();
250 result = (JSObjectRef)KJSValueToJSObject(globalObject, ptr->GetInterpreter()->globalExec());
258 JSObjectRef JSRunEvaluate(JSRunRef ref)
260 JSObjectRef result = 0;
261 JSRun* ptr = (JSRun*)ref;
264 Completion completion = ptr->Evaluate();
265 if (completion.isValueCompletion())
267 result = (JSObjectRef)KJSValueToJSObject(completion.value(), ptr->GetInterpreter()->globalExec());
270 if (completion.complType() == Throw)
272 JSFlags flags = ptr->Flags();
273 if (flags & kJSFlagDebug)
275 CFTypeRef error = JSObjectCopyCFValue(result);
289 Return true if no syntax error
291 bool JSRunCheckSyntax(JSRunRef ref)
294 JSRun* ptr = (JSRun*)ref;
298 result = ptr->CheckSyntax();
299 JSUnlockInterpreter();
305 JSCollect - trigger garbage collection
309 InterpreterLock lock;
310 Collector::collect();
314 JSTypeGetCFArrayCallBacks
316 void JSTypeGetCFArrayCallBacks(CFArrayCallBacks* outCallBacks)
320 outCallBacks->version = 1;
321 outCallBacks->retain = (CFArrayRetainCallBack)JSCFRetain;
322 outCallBacks->release = (CFArrayReleaseCallBack)JSCFRelease;
323 outCallBacks->copyDescription = (CFArrayCopyDescriptionCallBack)JSCopyDescription;
324 outCallBacks->equal = (CFArrayEqualCallBack)JSEqual;
332 void *JSCFRetain(CFAllocatorRef allocator, const void *value)
334 JSRetain((JSTypeRef)value);
341 void JSCFRelease(CFAllocatorRef allocator, const void *value)
343 JSRelease((JSTypeRef)value);
348 JSObjectCreateWithCFType
350 JSObjectRef JSObjectCreateWithCFType(CFTypeRef inRef)
352 JSObjectCallBacks callBacks;
353 JSObjectRef cfJSObject = nil;
356 callBacks.dispose = CFJSObjectDispose;
357 callBacks.equal = CFJSObjectEqual;
358 callBacks.copyCFValue = CFJSObjectCopyCFValue;
359 callBacks.copyProperty = CFJSObjectCopyProperty;
360 callBacks.setProperty = CFJSObjectSetProperty;
361 callBacks.callFunction = 0;
362 callBacks.copyPropertyNames = CFJSObjectCopyPropertyNames;
363 cfJSObject = JSObjectCreateInternal((void*)CFRetain(inRef), &callBacks, 0, kJSUserObjectDataTypeCFType );
371 void CFJSObjectDispose(void *data)
375 CFRelease((JSTypeRef)data);
379 CFArrayRef JSObjectCopyPropertyNames(JSObjectRef ref)
381 CFArrayRef result = 0;
382 JSUserObject* ptr = (JSUserObject*)ref;
383 if (ptr && (ptr->GetTypeID() == kJSObjectTypeID))
385 result = ptr->CopyPropertyNames();
390 CFJSObjectCopyProperty
392 JSObjectRef CFJSObjectCopyProperty(void *data, CFStringRef propertyName)
394 JSObjectRef result = 0;
395 if (data && propertyName)
397 CFTypeRef cfResult = 0;
398 if (CFGetTypeID(data) == CFDictionaryGetTypeID())
400 if (CFStringCompare(propertyName, CFSTR("length"), 0) == kCFCompareEqualTo)
402 int len = CFDictionaryGetCount((CFDictionaryRef)data);
403 cfResult = CFNumberCreate(0, kCFNumberIntType, &len);
407 cfResult = RetainCFType(CFDictionaryGetValue((CFDictionaryRef)data, propertyName));
410 else if (CFGetTypeID(data) == CFArrayGetTypeID())
412 if (CFStringCompare(propertyName, CFSTR("length"), 0) == kCFCompareEqualTo)
414 int len = CFArrayGetCount((CFArrayRef)data);
415 cfResult = CFNumberCreate(0, kCFNumberIntType, &len);
419 SInt32 index = CFStringGetIntValue(propertyName);
420 CFIndex arrayCount = CFArrayGetCount((CFArrayRef)data);
421 if (index >= 0 && index < arrayCount)
423 cfResult = RetainCFType(CFArrayGetValueAtIndex((CFArrayRef)data, index));
427 else if (CFGetTypeID(data) == CFStringGetTypeID())
429 if (CFStringCompare(propertyName, CFSTR("length"), 0) == kCFCompareEqualTo)
431 int len = CFStringGetLength((CFStringRef)data);
432 cfResult = CFNumberCreate(0, kCFNumberIntType, &len);
437 result = JSObjectCreateWithCFType(cfResult);
446 CFJSObjectSetProperty
448 void CFJSObjectSetProperty(void *data, CFStringRef propertyName, JSObjectRef jsValue)
450 if (data && propertyName)
452 CFTypeRef cfValue = JSObjectCopyCFValue(jsValue);
456 if (CFGetTypeID(data) == CFDictionaryGetTypeID())
458 CFDictionarySetValue((CFMutableDictionaryRef)data, propertyName, cfValue);
460 else if (CFGetTypeID(data) == CFArrayGetTypeID())
462 SInt32 index = CFStringGetIntValue(propertyName);
463 CFIndex arrayCount = CFArrayGetCount((CFArrayRef)data);
466 for (; arrayCount < index; arrayCount++)
468 CFArrayAppendValue((CFMutableArrayRef)data, GetCFNull());
470 CFArraySetValueAtIndex((CFMutableArrayRef)data, index, cfValue);
477 if (CFGetTypeID(data) == CFDictionaryGetTypeID())
479 CFDictionaryRemoveValue((CFMutableDictionaryRef)data, propertyName);
481 else if (CFGetTypeID(data) == CFArrayGetTypeID())
483 SInt32 index = CFStringGetIntValue(propertyName);
484 CFIndex arrayCount = CFArrayGetCount((CFArrayRef)data);
487 for (; arrayCount < index; arrayCount++)
489 CFArrayAppendValue((CFMutableArrayRef)data, GetCFNull());
491 CFArraySetValueAtIndex((CFMutableArrayRef)data, index, GetCFNull());
500 CFJSObjectCopyCFValue
502 CFTypeRef CFJSObjectCopyCFValue(void *data)
504 CFTypeRef result = 0;
507 result = (CFTypeRef)CFRetain(data);
513 CFJSObjectCopyCFValue
515 UInt8 CFJSObjectEqual(void *data1, void *data2)
517 UInt8 result = false;
520 CFEqual((CFTypeRef)data1, (CFTypeRef)data2);
527 CFJSObjectCopyPropertyNames
529 CFArrayRef CFJSObjectCopyPropertyNames(void *data)
531 CFMutableArrayRef result = 0;
534 CFTypeID cfType = CFGetTypeID(data);
535 if (cfType == CFDictionaryGetTypeID())
537 CFIndex count = CFDictionaryGetCount((CFDictionaryRef)data);
540 CFTypeRef* keys = (CFTypeRef*)malloc(sizeof(CFTypeRef)*count);
544 CFDictionaryGetKeysAndValues((CFDictionaryRef)data, (const void **)keys, 0);
545 for (i = 0; i < count; i++)
547 CFStringRef key = (CFStringRef)keys[i];
548 if (CFGetTypeID(key) != CFStringGetTypeID()) continue;
550 if (!result) result = CFArrayCreateMutable(0, 0, &kCFTypeArrayCallBacks);
551 if (!result) continue;
553 CFArrayAppendValue(result, key);
566 CFMutableArrayRef JSCreateCFArrayFromJSArray(CFArrayRef array)
568 CFIndex count = array ? CFArrayGetCount(array) : 0;
569 CFMutableArrayRef cfArray = CFArrayCreateMutable(0, 0, &kCFTypeArrayCallBacks);
572 for (i = 0; cfArray && i < count; i++)
574 JSObjectRef jsValue = (JSObjectRef)CFArrayGetValueAtIndex(array, i);
575 CFTypeRef cfvalue = JSObjectCopyCFValue(jsValue);
578 CFArrayAppendValue(cfArray, cfvalue);
583 CFArrayAppendValue(cfArray, GetCFNull());
589 CFMutableArrayRef JSCreateJSArrayFromCFArray(CFArrayRef array)
591 CFIndex count = array ? CFArrayGetCount(array) : 0;
592 CFArrayCallBacks arrayCallbacks;
593 CFMutableArrayRef jsArray;
596 JSTypeGetCFArrayCallBacks(&arrayCallbacks);
597 jsArray = CFArrayCreateMutable(0, 0, &arrayCallbacks);
599 for (i = 0; array && i < count; i++)
601 CFTypeRef cfValue = (CFTypeRef)CFArrayGetValueAtIndex(array, i);
602 JSObjectRef jsValue = JSObjectCreateWithCFType(cfValue);
604 if (!jsValue) jsValue = JSObjectCreateWithCFType(GetCFNull());
607 CFArrayAppendValue(jsArray, jsValue);
615 void JSLockInterpreter()
621 void JSUnlockInterpreter()
623 Interpreter::unlock();