JavaScriptGlue/JSValueWrapper.cpp
changeset 0 4f2f89ce4247
equal deleted inserted replaced
-1:000000000000 0:4f2f89ce4247
       
     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(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     JSValueWrapper* ptr = (JSValueWrapper*)data;
       
   198     if (ptr)
       
   199     {
       
   200         // This results in recursive marking but will be otherwise safe and correct.
       
   201         // We claim the array vptr is 0 because we don't have access to it here, and
       
   202         // claiming 0 is functionally harmless -- it merely means that we can't
       
   203         // devirtualise marking of arrays when recursing from this point.
       
   204         MarkStack markStack(0);
       
   205         markStack.append(ptr->fValue.get());
       
   206         markStack.drain();
       
   207     }
       
   208 }