webengine/osswebengine/JavaScriptGlue/JavaScriptGlue.cpp
changeset 0 dd21522fd290
equal deleted inserted replaced
-1:000000000000 0:dd21522fd290
       
     1 /*
       
     2  * Copyright (C) 2005 Apple Computer, Inc.  All rights reserved.
       
     3  *
       
     4  * Redistribution and use in source and binary forms, with or without
       
     5  * modification, are permitted provided that the following conditions
       
     6  * are met:
       
     7  *
       
     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. 
       
    13  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
       
    14  *     its contributors may be used to endorse or promote products derived
       
    15  *     from this software without specific prior written permission. 
       
    16  *
       
    17  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
       
    18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
       
    19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
       
    20  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
       
    21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
       
    22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
       
    23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
       
    24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
       
    25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
       
    26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
       
    27  */
       
    28 
       
    29 #include "config.h"
       
    30 #include "JavaScriptGlue.h"
       
    31 #include "JSUtils.h"
       
    32 #include "JSBase.h"
       
    33 #include "JSObject.h"
       
    34 #include "JSRun.h"
       
    35 
       
    36 static CFTypeRef sJSCFNullRef = 0;
       
    37 
       
    38 static void CFJSObjectDispose(void *data);
       
    39 static JSObjectRef CFJSObjectCopyProperty(void *data, CFStringRef propertyName);
       
    40 static void CFJSObjectSetProperty(void *data, CFStringRef propertyName, JSObjectRef jsValue);
       
    41 static CFTypeRef CFJSObjectCopyCFValue(void *data);
       
    42 static UInt8 CFJSObjectEqual(void *data1, void *data2);
       
    43 static CFArrayRef CFJSObjectCopyPropertyNames(void *data);
       
    44 
       
    45 void *JSCFRetain(CFAllocatorRef allocator, const void *value);
       
    46 void JSCFRelease(CFAllocatorRef allocator, const void *value);
       
    47 
       
    48 
       
    49 void JSSetCFNull(CFTypeRef nullRef)
       
    50 {
       
    51     ReleaseCFType(sJSCFNullRef);
       
    52     sJSCFNullRef = RetainCFType(nullRef);
       
    53 }
       
    54 
       
    55 CFTypeRef JSGetCFNull(void)
       
    56 {
       
    57     return sJSCFNullRef;
       
    58 }
       
    59 
       
    60 /*
       
    61     JSRetain
       
    62 */
       
    63 JSTypeRef JSRetain(JSTypeRef ref)
       
    64 {
       
    65     if (ref)
       
    66     {
       
    67         JSBase* ptr = (JSBase*)ref;
       
    68         ptr->Retain();
       
    69     }
       
    70     return ref;
       
    71 }
       
    72 
       
    73 /*
       
    74     JSRelease
       
    75 */
       
    76 void JSRelease(JSTypeRef ref)
       
    77 {
       
    78     if (ref)
       
    79     {
       
    80         JSBase* ptr = (JSBase*)ref;
       
    81         ptr->Release();
       
    82     }
       
    83 }
       
    84 
       
    85 /*
       
    86     JSCopyDescription
       
    87 */
       
    88 CFStringRef JSCopyDescription(JSTypeRef ref)
       
    89 {
       
    90     CFStringRef result = 0;
       
    91     if (ref)
       
    92     {
       
    93         JSBase* ptr = (JSBase*)ref;
       
    94         ptr->CopyDescription();
       
    95     }
       
    96     return result;
       
    97 }
       
    98 
       
    99 /*
       
   100     JSEqual
       
   101 */
       
   102 UInt8 JSEqual(JSTypeRef ref1, JSTypeRef ref2)
       
   103 {
       
   104     UInt8 result = false;
       
   105     if (ref1 && ref2)
       
   106     {
       
   107         JSBase* ptr = (JSBase*)ref1;
       
   108         result = ptr->Equal((JSBase*)ref2);
       
   109     }
       
   110     return result;
       
   111 }
       
   112 
       
   113 
       
   114 /*
       
   115     JSGetTypeID
       
   116 */
       
   117 JSTypeID JSGetTypeID(JSTypeRef ref)
       
   118 {
       
   119     JSTypeID result = kJSInvalidTypeID;
       
   120     if (ref)
       
   121     {
       
   122         JSBase* ptr = (JSBase*)ref;
       
   123         result = ptr->GetTypeID();
       
   124     }
       
   125     return result;
       
   126 }
       
   127 
       
   128 
       
   129 /*
       
   130     JSGetRetainCount
       
   131 */
       
   132 CFIndex JSGetRetainCount(JSTypeRef ref)
       
   133 {
       
   134     CFIndex result = -1;
       
   135     if (ref)
       
   136     {
       
   137         JSBase* ptr = (JSBase*)ref;
       
   138         result = ptr->RetainCount();
       
   139     }
       
   140     return result;
       
   141 }
       
   142 
       
   143 
       
   144 
       
   145 /*
       
   146     JSObjectCreate
       
   147 */
       
   148 JSObjectRef JSObjectCreate(void *data, JSObjectCallBacksPtr callBacks)
       
   149 {
       
   150     JSObjectRef result = JSObjectCreateInternal(data, callBacks, 0, kJSUserObjectDataTypeUnknown);
       
   151     return result;
       
   152 }
       
   153 
       
   154 /*
       
   155     JSObjectCreateInternal
       
   156 */
       
   157 JSObjectRef JSObjectCreateInternal(void *data, JSObjectCallBacksPtr callBacks, JSObjectMarkProcPtr markProc, int type)
       
   158 {
       
   159     JSObjectRef result = 0;
       
   160     JSUserObject* ptr = new JSUserObject(callBacks, markProc, data, type);
       
   161     result = (JSObjectRef)ptr;
       
   162     return result;
       
   163 }
       
   164 
       
   165 /*
       
   166     JSObjectCopyCFValue
       
   167 */
       
   168 CFTypeRef JSObjectCopyCFValue(JSObjectRef ref)
       
   169 {
       
   170     CFTypeRef result = 0;
       
   171     JSUserObject* ptr = (JSUserObject*)ref;
       
   172     if (ptr && (ptr->GetTypeID() == kJSObjectTypeID))
       
   173     {
       
   174         result = ptr->CopyCFValue();
       
   175     }
       
   176     return result;
       
   177 }
       
   178 
       
   179 /*
       
   180     JSObjectGetData
       
   181 */
       
   182 void *JSObjectGetData(JSObjectRef ref)
       
   183 {
       
   184     void *result = 0;
       
   185     JSUserObject* ptr = (JSUserObject*)ref;
       
   186     if (ptr && (ptr->GetTypeID() == kJSObjectTypeID))
       
   187     {
       
   188         result = ptr->GetData();
       
   189     }
       
   190     return result;
       
   191 }
       
   192 
       
   193 
       
   194 /*
       
   195     JSObjectCopyProperty
       
   196 */
       
   197 JSObjectRef JSObjectCopyProperty(JSObjectRef ref, CFStringRef propertyName)
       
   198 {
       
   199     JSObjectRef result = 0;
       
   200     JSUserObject* ptr = (JSUserObject*)ref;
       
   201     if (ptr && (ptr->GetTypeID() == kJSObjectTypeID))
       
   202     {
       
   203         result = (JSObjectRef)ptr->CopyProperty(propertyName);
       
   204     }
       
   205     return result;
       
   206 }
       
   207 
       
   208 
       
   209 /*
       
   210     JSObjectSetProperty
       
   211 */
       
   212 void JSObjectSetProperty(JSObjectRef ref, CFStringRef propertyName, JSObjectRef value)
       
   213 {
       
   214     JSUserObject* ptr = (JSUserObject*)ref;
       
   215     if (ptr && (ptr->GetTypeID() == kJSObjectTypeID))
       
   216     {
       
   217         ptr->SetProperty(propertyName, (JSUserObject*)value);
       
   218     }
       
   219 }
       
   220 
       
   221 
       
   222 /*
       
   223     JSObjectCallFunction
       
   224 */
       
   225 JSObjectRef JSObjectCallFunction(JSObjectRef ref, JSObjectRef thisObj, CFArrayRef args)
       
   226 {
       
   227     JSObjectRef result = 0;
       
   228     JSUserObject* ptr = (JSUserObject*)ref;
       
   229     if (ptr && (ptr->GetTypeID() == kJSObjectTypeID))
       
   230     {
       
   231         result = (JSObjectRef)ptr->CallFunction((JSUserObject*)thisObj, args);
       
   232     }
       
   233     return result;
       
   234 }
       
   235 
       
   236 
       
   237 /*
       
   238     JSRunCreate
       
   239 */
       
   240 JSRunRef JSRunCreate(CFStringRef jsSource, JSFlags inFlags)
       
   241 {
       
   242     JSRunRef result = 0;
       
   243     if (jsSource)
       
   244     {
       
   245         JSLock lock;
       
   246         result = (JSRunRef) new JSRun(jsSource, inFlags);
       
   247     }
       
   248     return result;
       
   249 }
       
   250 
       
   251 /*
       
   252     JSRunCopySource
       
   253 */
       
   254 CFStringRef JSRunCopySource(JSRunRef ref)
       
   255 {
       
   256     CFStringRef result = 0;
       
   257     JSRun* ptr = (JSRun*)ref;
       
   258     if (ptr)
       
   259     {
       
   260         result = UStringToCFString(ptr->GetSource());
       
   261     }
       
   262     return result;
       
   263 }
       
   264 
       
   265 
       
   266 /*
       
   267     JSRunCopyGlobalObject
       
   268 */
       
   269 JSObjectRef JSRunCopyGlobalObject(JSRunRef ref)
       
   270 {
       
   271     JSObjectRef result = 0;
       
   272     JSRun* ptr = (JSRun*)ref;
       
   273     if (ptr)
       
   274     {
       
   275         JSObject *globalObject = ptr->GlobalObject();
       
   276         result = (JSObjectRef)KJSValueToJSObject(globalObject, ptr->GetInterpreter()->globalExec());
       
   277     }
       
   278     return result;
       
   279 }
       
   280 
       
   281 /*
       
   282     JSRunEvaluate
       
   283 */
       
   284 JSObjectRef JSRunEvaluate(JSRunRef ref)
       
   285 {
       
   286     JSObjectRef result = 0;
       
   287     JSRun* ptr = (JSRun*)ref;
       
   288     if (ptr)
       
   289     {
       
   290         JSLock lock;
       
   291         Completion completion = ptr->Evaluate();
       
   292         if (completion.isValueCompletion())
       
   293         {
       
   294             result = (JSObjectRef)KJSValueToJSObject(completion.value(), ptr->GetInterpreter()->globalExec());
       
   295         }
       
   296 
       
   297         if (completion.complType() == Throw)
       
   298         {
       
   299             JSFlags flags = ptr->Flags();
       
   300             if (flags & kJSFlagDebug)
       
   301             {
       
   302                 CFTypeRef error = JSObjectCopyCFValue(result);
       
   303                 if (error)
       
   304                 {
       
   305                     CFShow(error);
       
   306                     CFRelease(error);
       
   307                 }
       
   308             }
       
   309         }
       
   310     }
       
   311     return result;
       
   312 }
       
   313 
       
   314 /*
       
   315     JSRunCheckSyntax
       
   316     Return true if no syntax error
       
   317 */
       
   318 bool JSRunCheckSyntax(JSRunRef ref)
       
   319 {
       
   320     bool result = false;
       
   321     JSRun* ptr = (JSRun*)ref;
       
   322     if (ptr)
       
   323     {
       
   324             JSLock lock;
       
   325             result = ptr->CheckSyntax();
       
   326     }
       
   327     return result;
       
   328 }
       
   329 
       
   330 /*
       
   331     JSCollect - trigger garbage collection
       
   332 */
       
   333 void JSCollect(void)
       
   334 {
       
   335     JSLock lock;
       
   336     Collector::collect();
       
   337 }
       
   338 
       
   339 /*
       
   340     JSTypeGetCFArrayCallBacks
       
   341 */
       
   342 void JSTypeGetCFArrayCallBacks(CFArrayCallBacks* outCallBacks)
       
   343 {
       
   344     if (outCallBacks)
       
   345     {
       
   346         outCallBacks->version = 1;
       
   347         outCallBacks->retain = (CFArrayRetainCallBack)JSCFRetain;
       
   348         outCallBacks->release = (CFArrayReleaseCallBack)JSCFRelease;
       
   349         outCallBacks->copyDescription = (CFArrayCopyDescriptionCallBack)JSCopyDescription;
       
   350         outCallBacks->equal = (CFArrayEqualCallBack)JSEqual;
       
   351     }
       
   352 }
       
   353 
       
   354 
       
   355 /*
       
   356     JSCFRetain
       
   357 */
       
   358 void *JSCFRetain(CFAllocatorRef allocator, const void *value)
       
   359 {
       
   360     JSRetain((JSTypeRef)value);
       
   361     return (void*)value;
       
   362 }
       
   363 
       
   364 /*
       
   365     JSCFRelease
       
   366 */
       
   367 void JSCFRelease(CFAllocatorRef allocator, const void *value)
       
   368 {
       
   369     JSRelease((JSTypeRef)value);
       
   370 }
       
   371 
       
   372 
       
   373 /*
       
   374     JSObjectCreateWithCFType
       
   375 */
       
   376 JSObjectRef JSObjectCreateWithCFType(CFTypeRef inRef)
       
   377 {
       
   378     JSObjectCallBacks callBacks;
       
   379     JSObjectRef cfJSObject = nil;
       
   380     if (inRef)
       
   381     {
       
   382         callBacks.dispose = CFJSObjectDispose;
       
   383         callBacks.equal = CFJSObjectEqual;
       
   384         callBacks.copyCFValue = CFJSObjectCopyCFValue;
       
   385         callBacks.copyProperty = CFJSObjectCopyProperty;
       
   386         callBacks.setProperty = CFJSObjectSetProperty;
       
   387         callBacks.callFunction = 0;
       
   388         callBacks.copyPropertyNames = CFJSObjectCopyPropertyNames;
       
   389         cfJSObject = JSObjectCreateInternal((void*)CFRetain(inRef), &callBacks, 0, kJSUserObjectDataTypeCFType );
       
   390     }
       
   391     return cfJSObject;
       
   392 }
       
   393 
       
   394 /*
       
   395     CFJSObjectDispose
       
   396 */
       
   397 void CFJSObjectDispose(void *data)
       
   398 {
       
   399     if (data)
       
   400     {
       
   401         CFRelease((JSTypeRef)data);
       
   402     }
       
   403 }
       
   404 
       
   405 CFArrayRef JSObjectCopyPropertyNames(JSObjectRef ref)
       
   406 {
       
   407     CFArrayRef result = 0;
       
   408     JSUserObject* ptr = (JSUserObject*)ref;
       
   409     if (ptr && (ptr->GetTypeID() == kJSObjectTypeID))
       
   410     {
       
   411         result = ptr->CopyPropertyNames();
       
   412     }
       
   413     return result;
       
   414 }
       
   415 /*
       
   416     CFJSObjectCopyProperty
       
   417 */
       
   418 JSObjectRef CFJSObjectCopyProperty(void *data, CFStringRef propertyName)
       
   419 {
       
   420     JSObjectRef result = 0;
       
   421     if (data && propertyName)
       
   422     {
       
   423         CFTypeRef cfResult = 0;
       
   424         if (CFGetTypeID(data) == CFDictionaryGetTypeID())
       
   425         {
       
   426             if (CFStringCompare(propertyName, CFSTR("length"), 0) == kCFCompareEqualTo)
       
   427             {
       
   428                 int len = CFDictionaryGetCount((CFDictionaryRef)data);
       
   429                 cfResult = CFNumberCreate(0, kCFNumberIntType, &len);
       
   430             }
       
   431             else
       
   432             {
       
   433                 cfResult = RetainCFType(CFDictionaryGetValue((CFDictionaryRef)data, propertyName));
       
   434             }
       
   435         }
       
   436         else if (CFGetTypeID(data) == CFArrayGetTypeID())
       
   437         {
       
   438             if (CFStringCompare(propertyName, CFSTR("length"), 0) == kCFCompareEqualTo)
       
   439             {
       
   440                 int len = CFArrayGetCount((CFArrayRef)data);
       
   441                 cfResult = CFNumberCreate(0, kCFNumberIntType, &len);
       
   442             }
       
   443             else
       
   444             {
       
   445                 SInt32 index = CFStringGetIntValue(propertyName);
       
   446                 CFIndex arrayCount = CFArrayGetCount((CFArrayRef)data);
       
   447                 if (index >= 0 && index < arrayCount)
       
   448                 {
       
   449                     cfResult = RetainCFType(CFArrayGetValueAtIndex((CFArrayRef)data, index));
       
   450                 }
       
   451             }
       
   452         }
       
   453         else if (CFGetTypeID(data) == CFStringGetTypeID())
       
   454         {
       
   455             if (CFStringCompare(propertyName, CFSTR("length"), 0) == kCFCompareEqualTo)
       
   456             {
       
   457                 int len = CFStringGetLength((CFStringRef)data);
       
   458                 cfResult = CFNumberCreate(0, kCFNumberIntType, &len);
       
   459             }
       
   460         }
       
   461         if (cfResult)
       
   462         {
       
   463             result = JSObjectCreateWithCFType(cfResult);
       
   464             CFRelease(cfResult);
       
   465         }
       
   466     }
       
   467     return result;
       
   468 }
       
   469 
       
   470 
       
   471 /*
       
   472     CFJSObjectSetProperty
       
   473 */
       
   474 void CFJSObjectSetProperty(void *data, CFStringRef propertyName, JSObjectRef jsValue)
       
   475 {
       
   476     if (data && propertyName)
       
   477     {
       
   478         CFTypeRef cfValue = JSObjectCopyCFValue(jsValue);
       
   479 
       
   480         if (cfValue)
       
   481         {
       
   482             if (CFGetTypeID(data) == CFDictionaryGetTypeID())
       
   483             {
       
   484                 CFDictionarySetValue((CFMutableDictionaryRef)data, propertyName, cfValue);
       
   485             }
       
   486             else if (CFGetTypeID(data) == CFArrayGetTypeID())
       
   487             {
       
   488                 SInt32 index = CFStringGetIntValue(propertyName);
       
   489                 CFIndex arrayCount = CFArrayGetCount((CFArrayRef)data);
       
   490                 if (index >= 0)
       
   491                 {
       
   492                     for (; arrayCount < index; arrayCount++)
       
   493                     {
       
   494                         CFArrayAppendValue((CFMutableArrayRef)data, GetCFNull());
       
   495                     }
       
   496                     CFArraySetValueAtIndex((CFMutableArrayRef)data, index, cfValue);
       
   497                 }
       
   498             }
       
   499             CFRelease(cfValue);
       
   500         }
       
   501         else
       
   502         {
       
   503             if (CFGetTypeID(data) == CFDictionaryGetTypeID())
       
   504             {
       
   505                 CFDictionaryRemoveValue((CFMutableDictionaryRef)data, propertyName);
       
   506             }
       
   507             else if (CFGetTypeID(data) == CFArrayGetTypeID())
       
   508             {
       
   509                 SInt32 index = CFStringGetIntValue(propertyName);
       
   510                 CFIndex arrayCount = CFArrayGetCount((CFArrayRef)data);
       
   511                 if (index >= 0)
       
   512                 {
       
   513                     for (; arrayCount < index; arrayCount++)
       
   514                     {
       
   515                         CFArrayAppendValue((CFMutableArrayRef)data, GetCFNull());
       
   516                     }
       
   517                     CFArraySetValueAtIndex((CFMutableArrayRef)data, index, GetCFNull());
       
   518                 }
       
   519             }
       
   520         }
       
   521     }
       
   522 }
       
   523 
       
   524 
       
   525 /*
       
   526     CFJSObjectCopyCFValue
       
   527 */
       
   528 CFTypeRef CFJSObjectCopyCFValue(void *data)
       
   529 {
       
   530     CFTypeRef result = 0;
       
   531     if (data)
       
   532     {
       
   533         result = (CFTypeRef)CFRetain(data);
       
   534     }
       
   535     return result;
       
   536 }
       
   537 
       
   538 /*
       
   539     CFJSObjectCopyCFValue
       
   540 */
       
   541 UInt8 CFJSObjectEqual(void *data1, void *data2)
       
   542 {
       
   543     UInt8 result = false;
       
   544     if (data1 && data2)
       
   545     {
       
   546         CFEqual((CFTypeRef)data1, (CFTypeRef)data2);
       
   547     }
       
   548     return result;
       
   549 }
       
   550 
       
   551 
       
   552 /*
       
   553     CFJSObjectCopyPropertyNames
       
   554 */
       
   555 CFArrayRef CFJSObjectCopyPropertyNames(void *data)
       
   556 {
       
   557     CFMutableArrayRef result = 0;
       
   558     if (data)
       
   559     {
       
   560         CFTypeID cfType = CFGetTypeID(data);
       
   561         if (cfType == CFDictionaryGetTypeID())
       
   562         {
       
   563             CFIndex count = CFDictionaryGetCount((CFDictionaryRef)data);
       
   564             if (count)
       
   565             {
       
   566                 CFTypeRef* keys = (CFTypeRef*)malloc(sizeof(CFTypeRef)*count);
       
   567                 if (keys)
       
   568                 {
       
   569                     int i;
       
   570                     CFDictionaryGetKeysAndValues((CFDictionaryRef)data, (const void **)keys, 0);
       
   571                     for (i = 0; i < count; i++)
       
   572                     {
       
   573                         CFStringRef key = (CFStringRef)keys[i];
       
   574                         if (CFGetTypeID(key) != CFStringGetTypeID()) continue;
       
   575 
       
   576                         if (!result) result = CFArrayCreateMutable(0, 0, &kCFTypeArrayCallBacks);
       
   577                         if (!result) continue;
       
   578 
       
   579                         CFArrayAppendValue(result, key);
       
   580                     }
       
   581                     free(keys);
       
   582                 }
       
   583             }
       
   584         }
       
   585     }
       
   586     return result;
       
   587 }
       
   588 
       
   589 
       
   590 
       
   591 
       
   592 CFMutableArrayRef JSCreateCFArrayFromJSArray(CFArrayRef array)
       
   593 {
       
   594     CFIndex count = array ? CFArrayGetCount(array) : 0;
       
   595     CFMutableArrayRef cfArray = CFArrayCreateMutable(0, 0, &kCFTypeArrayCallBacks);
       
   596     CFIndex i;
       
   597 
       
   598     for (i = 0; cfArray && i <  count; i++)
       
   599     {
       
   600         JSObjectRef jsValue = (JSObjectRef)CFArrayGetValueAtIndex(array, i);
       
   601         CFTypeRef cfvalue = JSObjectCopyCFValue(jsValue);
       
   602         if (cfvalue)
       
   603         {
       
   604             CFArrayAppendValue(cfArray, cfvalue);
       
   605             CFRelease(cfvalue);
       
   606         }
       
   607         else
       
   608         {
       
   609             CFArrayAppendValue(cfArray, GetCFNull());
       
   610         }
       
   611     }
       
   612     return cfArray;
       
   613 }
       
   614 
       
   615 CFMutableArrayRef JSCreateJSArrayFromCFArray(CFArrayRef array)
       
   616 {
       
   617     CFIndex count = array ? CFArrayGetCount(array) : 0;
       
   618     CFArrayCallBacks arrayCallbacks;
       
   619     CFMutableArrayRef jsArray;
       
   620     CFIndex i;
       
   621 
       
   622     JSTypeGetCFArrayCallBacks(&arrayCallbacks);
       
   623     jsArray = CFArrayCreateMutable(0, 0, &arrayCallbacks);
       
   624 
       
   625     for (i = 0; array && i <  count; i++)
       
   626     {
       
   627         CFTypeRef cfValue = (CFTypeRef)CFArrayGetValueAtIndex(array, i);
       
   628         JSObjectRef jsValue = JSObjectCreateWithCFType(cfValue);
       
   629 
       
   630         if (!jsValue) jsValue = JSObjectCreateWithCFType(GetCFNull());
       
   631         if (jsValue)
       
   632         {
       
   633             CFArrayAppendValue(jsArray, jsValue);
       
   634             JSRelease(jsValue);
       
   635         }
       
   636     }
       
   637     return jsArray;
       
   638 }
       
   639 
       
   640 
       
   641 void JSLockInterpreter()
       
   642 {
       
   643     JSLock::lock();
       
   644     JSLock::registerThread();
       
   645 }
       
   646 
       
   647 
       
   648 void JSUnlockInterpreter()
       
   649 {
       
   650     JSLock::unlock();
       
   651 }