Home | History | Annotate | Download | only in JavaScriptGlue
      1 /*
      2  * Copyright (C) 2005, 2009 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 "JSValueWrapper.h"
     31 #include "JSRun.h"
     32 #include <JavaScriptCore/JSArray.h>
     33 #include <JavaScriptCore/PropertyNameArray.h>
     34 #include <pthread.h>
     35 
     36 JSValueWrapper::JSValueWrapper(JSValue inValue)
     37     : fValue(getThreadGlobalExecState()->globalData(), inValue)
     38 {
     39 }
     40 
     41 JSValueWrapper::~JSValueWrapper()
     42 {
     43 }
     44 
     45 JSValue JSValueWrapper::GetValue()
     46 {
     47     return fValue.get();
     48 }
     49 
     50 void JSValueWrapper::GetJSObectCallBacks(JSObjectCallBacks& callBacks)
     51 {
     52     callBacks.dispose = (JSObjectDisposeProcPtr)JSValueWrapper::JSObjectDispose;
     53     callBacks.equal = (JSObjectEqualProcPtr)0;
     54     callBacks.copyPropertyNames = (JSObjectCopyPropertyNamesProcPtr)JSValueWrapper::JSObjectCopyPropertyNames;
     55     callBacks.copyCFValue = (JSObjectCopyCFValueProcPtr)JSValueWrapper::JSObjectCopyCFValue;
     56     callBacks.copyProperty = (JSObjectCopyPropertyProcPtr)JSValueWrapper::JSObjectCopyProperty;
     57     callBacks.setProperty = (JSObjectSetPropertyProcPtr)JSValueWrapper::JSObjectSetProperty;
     58     callBacks.callFunction = (JSObjectCallFunctionProcPtr)JSValueWrapper::JSObjectCallFunction;
     59 }
     60 
     61 void JSValueWrapper::JSObjectDispose(void *data)
     62 {
     63     JSValueWrapper* ptr = (JSValueWrapper*)data;
     64     delete ptr;
     65 }
     66 
     67 
     68 CFArrayRef JSValueWrapper::JSObjectCopyPropertyNames(void *data)
     69 {
     70     JSGlueAPIEntry entry;
     71 
     72     CFMutableArrayRef result = 0;
     73     JSValueWrapper* ptr = (JSValueWrapper*)data;
     74     if (ptr)
     75     {
     76         ExecState* exec = getThreadGlobalExecState();
     77         JSObject* object = ptr->GetValue().toObject(exec);
     78         PropertyNameArray propNames(exec);
     79         object->getPropertyNames(exec, propNames);
     80         PropertyNameArray::const_iterator iterator = propNames.begin();
     81 
     82         while (iterator != propNames.end()) {
     83             Identifier name = *iterator;
     84             CFStringRef nameStr = IdentifierToCFString(name);
     85 
     86             if (!result)
     87             {
     88                 result = CFArrayCreateMutable(0, 0, &kCFTypeArrayCallBacks);
     89             }
     90             if (result && nameStr)
     91             {
     92                 CFArrayAppendValue(result, nameStr);
     93             }
     94             ReleaseCFType(nameStr);
     95             iterator++;
     96         }
     97 
     98     }
     99     return result;
    100 }
    101 
    102 
    103 JSObjectRef JSValueWrapper::JSObjectCopyProperty(void *data, CFStringRef propertyName)
    104 {
    105     JSGlueAPIEntry entry;
    106 
    107     JSObjectRef result = 0;
    108     JSValueWrapper* ptr = (JSValueWrapper*)data;
    109     if (ptr)
    110     {
    111         ExecState* exec = getThreadGlobalExecState();
    112         JSValue propValue = ptr->GetValue().toObject(exec)->get(exec, CFStringToIdentifier(propertyName, exec));
    113         JSValueWrapper* wrapperValue = new JSValueWrapper(propValue);
    114 
    115         JSObjectCallBacks callBacks;
    116         GetJSObectCallBacks(callBacks);
    117         result = JSObjectCreateInternal(wrapperValue, &callBacks, JSValueWrapper::JSObjectMark, kJSUserObjectDataTypeJSValueWrapper);
    118 
    119         if (!result)
    120         {
    121             delete wrapperValue;
    122         }
    123     }
    124     return result;
    125 }
    126 
    127 void JSValueWrapper::JSObjectSetProperty(void *data, CFStringRef propertyName, JSObjectRef jsValue)
    128 {
    129     JSGlueAPIEntry entry;
    130 
    131     JSValueWrapper* ptr = (JSValueWrapper*)data;
    132     if (ptr)
    133     {
    134         ExecState* exec = getThreadGlobalExecState();
    135         JSValue value = JSObjectKJSValue((JSUserObject*)jsValue);
    136         JSObject *objValue = ptr->GetValue().toObject(exec);
    137         PutPropertySlot slot;
    138         objValue->put(exec, CFStringToIdentifier(propertyName, exec), value, slot);
    139     }
    140 }
    141 
    142 JSObjectRef JSValueWrapper::JSObjectCallFunction(void *data, JSObjectRef thisObj, CFArrayRef args)
    143 {
    144     JSGlueAPIEntry entry;
    145 
    146     JSObjectRef result = 0;
    147     JSValueWrapper* ptr = (JSValueWrapper*)data;
    148     if (ptr)
    149     {
    150         ExecState* exec = getThreadGlobalExecState();
    151 
    152         JSValue value = JSObjectKJSValue((JSUserObject*)thisObj);
    153         JSObject* ksjThisObj = value.toObject(exec);
    154         JSObject* objValue = ptr->GetValue().toObject(exec);
    155 
    156         MarkedArgumentBuffer listArgs;
    157         CFIndex argCount = args ? CFArrayGetCount(args) : 0;
    158         for (CFIndex i = 0; i < argCount; i++)
    159         {
    160             JSObjectRef jsArg = (JSObjectRef)CFArrayGetValueAtIndex(args, i);
    161             JSValue kgsArg = JSObjectKJSValue((JSUserObject*)jsArg);
    162             listArgs.append(kgsArg);
    163         }
    164 
    165         CallData callData;
    166         CallType callType = objValue->getCallData(callData);
    167         if (callType == CallTypeNone)
    168             return 0;
    169         JSValue  resultValue = call(exec, objValue, callType, callData, ksjThisObj, listArgs);
    170         JSValueWrapper* wrapperValue = new JSValueWrapper(resultValue);
    171         JSObjectCallBacks callBacks;
    172         GetJSObectCallBacks(callBacks);
    173         result = JSObjectCreate(wrapperValue, &callBacks);
    174         if (!result)
    175         {
    176             delete wrapperValue;
    177         }
    178     }
    179     return result;
    180 }
    181 
    182 CFTypeRef JSValueWrapper::JSObjectCopyCFValue(void *data)
    183 {
    184     JSGlueAPIEntry entry;
    185 
    186     CFTypeRef result = 0;
    187     JSValueWrapper* ptr = (JSValueWrapper*)data;
    188     if (ptr)
    189     {
    190         result = KJSValueToCFType(ptr->GetValue(), getThreadGlobalExecState());
    191     }
    192     return result;
    193 }
    194 
    195 void JSValueWrapper::JSObjectMark(void *data)
    196 {
    197 }
    198