18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2005, 2008 Apple Inc. All rights reserved.
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Redistribution and use in source and binary forms, with or without
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modification, are permitted provided that the following conditions
68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * are met:
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 1.  Redistributions of source code must retain the above copyright
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *     notice, this list of conditions and the following disclaimer.
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 2.  Redistributions in binary form must reproduce the above copyright
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *     notice, this list of conditions and the following disclaimer in the
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *     documentation and/or other materials provided with the distribution.
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *     its contributors may be used to endorse or promote products derived
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *     from this software without specific prior written permission.
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h"
308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "JSUtils.h"
318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "JSBase.h"
338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "JSObject.h"
348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "JSRun.h"
358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "JSValueWrapper.h"
368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "UserObjectImp.h"
378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <JavaScriptCore/JSString.h>
388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <JavaScriptCore/PropertyNameArray.h>
39dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include <JavaScriptCore/WTFThreadData.h>
408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstruct ObjectImpList {
428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSObject* imp;
438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ObjectImpList* next;
448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CFTypeRef data;
458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project};
468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
470bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochstatic CFTypeRef KJSValueToCFTypeInternal(JSValue inValue, ExecState *exec, ObjectImpList* inImps);
488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic JSGlueGlobalObject* getThreadGlobalObject();
498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project//--------------------------------------------------------------------------
518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// CFStringToUString
528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project//--------------------------------------------------------------------------
538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectUString CFStringToUString(CFStringRef inCFString)
558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UString result;
578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (inCFString) {
588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        CFIndex len = CFStringGetLength(inCFString);
598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        UniChar* buffer = (UniChar*)malloc(sizeof(UniChar) * len);
608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (buffer)
618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        {
628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            CFStringGetCharacters(inCFString, CFRangeMake(0, len), buffer);
638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            result = UString((const UChar *)buffer, len);
648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            free(buffer);
658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return result;
688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project//--------------------------------------------------------------------------
728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// UStringToCFString
738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project//--------------------------------------------------------------------------
748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// Caller is responsible for releasing the returned CFStringRef
758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectCFStringRef UStringToCFString(const UString& inUString)
768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
77f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    return CFStringCreateWithCharacters(0, (const UniChar*)inUString.characters(), inUString.length());
788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project//--------------------------------------------------------------------------
828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// CFStringToIdentifier
838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project//--------------------------------------------------------------------------
848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectIdentifier CFStringToIdentifier(CFStringRef inCFString, ExecState* exec)
868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return Identifier(exec, CFStringToUString(inCFString));
888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project//--------------------------------------------------------------------------
928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// IdentifierToCFString
938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project//--------------------------------------------------------------------------
948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// Caller is responsible for releasing the returned CFStringRef
958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectCFStringRef IdentifierToCFString(const Identifier& inIdentifier)
968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return UStringToCFString(inIdentifier.ustring());
988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project//--------------------------------------------------------------------------
1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// KJSValueToJSObject
1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project//--------------------------------------------------------------------------
1040bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben MurdochJSUserObject* KJSValueToJSObject(JSValue inValue, ExecState *exec)
1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSUserObject* result = 0;
1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (inValue.inherits(&UserObjectImp::s_info)) {
1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        UserObjectImp* userObjectImp = static_cast<UserObjectImp *>(asObject(inValue));
1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        result = userObjectImp->GetJSUserObject();
1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (result)
1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            result->Retain();
1138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else {
1148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        JSValueWrapper* wrapperValue = new JSValueWrapper(inValue);
1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (wrapperValue) {
1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            JSObjectCallBacks callBacks;
1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            JSValueWrapper::GetJSObectCallBacks(callBacks);
1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            result = (JSUserObject*)JSObjectCreate(wrapperValue, &callBacks);
1198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!result) {
1208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                delete wrapperValue;
1218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
1228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return result;
1258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project//--------------------------------------------------------------------------
1288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// JSObjectKJSValue
1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project//--------------------------------------------------------------------------
1300bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben MurdochJSValue JSObjectKJSValue(JSUserObject* ptr)
1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
132d0825bca7fe65beaee391d30da42e937db621564Steve Block    JSGlueAPIEntry entry;
1338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1340bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    JSValue result = jsUndefined();
1358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (ptr)
1368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    {
1378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        bool handled = false;
1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        switch (ptr->DataType())
1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        {
1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            case kJSUserObjectDataTypeJSValueWrapper:
1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            {
1438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                JSValueWrapper* wrapper = (JSValueWrapper*)ptr->GetData();
1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (wrapper)
1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                {
1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    result = wrapper->GetValue();
1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    handled = true;
1488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
1498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                break;
1508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
1518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            case kJSUserObjectDataTypeCFType:
1538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            {
1548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                CFTypeRef cfType = (CFTypeRef*)ptr->GetData();
1558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (cfType)
1568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                {
1578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    CFTypeID typeID = CFGetTypeID(cfType);
1588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (typeID == CFStringGetTypeID())
1598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    {
1608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        result = jsString(getThreadGlobalExecState(), CFStringToUString((CFStringRef)cfType));
1618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        handled = true;
1628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    }
1638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    else if (typeID == CFNumberGetTypeID())
1648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    {
1658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        double num;
1668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        CFNumberGetValue((CFNumberRef)cfType, kCFNumberDoubleType, &num);
167e14391e94c850b8bd03680c23b38978db68687a8John Reck                        result = jsNumber(num);
1688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        handled = true;
1698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    }
1708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    else if (typeID == CFBooleanGetTypeID())
1718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    {
1728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        result = jsBoolean(CFBooleanGetValue((CFBooleanRef)cfType));
1738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        handled = true;
1748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    }
1758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    else if (typeID == CFNullGetTypeID())
1768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    {
1778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        result = jsNull();
1788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        handled = true;
1798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    }
1808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
1818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                break;
1828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
1838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!handled)
1858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        {
1868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            ExecState* exec = getThreadGlobalExecState();
1872daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            result = new (exec) UserObjectImp(exec->globalData(), getThreadGlobalObject()->userObjectStructure(), ptr);
1888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return result;
1918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project//--------------------------------------------------------------------------
1978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// KJSValueToCFTypeInternal
1988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project//--------------------------------------------------------------------------
1998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// Caller is responsible for releasing the returned CFTypeRef
2000bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben MurdochCFTypeRef KJSValueToCFTypeInternal(JSValue inValue, ExecState *exec, ObjectImpList* inImps)
2018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!inValue)
2038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
2048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CFTypeRef result = 0;
2068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
207d0825bca7fe65beaee391d30da42e937db621564Steve Block    JSGlueAPIEntry entry;
2088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
209635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        if (inValue.isBoolean())
2108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            {
211635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                result = inValue.toBoolean(exec) ? kCFBooleanTrue : kCFBooleanFalse;
2128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                RetainCFType(result);
2138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return result;
2148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
2158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
216635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        if (inValue.isString())
2178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            {
218635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                UString uString = inValue.toString(exec);
2198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                result = UStringToCFString(uString);
2208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return result;
2218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
2228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
223635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        if (inValue.isNumber())
2248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            {
225635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                double number1 = inValue.toNumber(exec);
226635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                double number2 = (double)inValue.toInteger(exec);
2278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (number1 ==  number2)
2288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                {
2298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    int intValue = (int)number2;
2308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    result = CFNumberCreate(0, kCFNumberIntType, &intValue);
2318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
2328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                else
2338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                {
2348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    result = CFNumberCreate(0, kCFNumberDoubleType, &number1);
2358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
2368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return result;
2378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
2388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
239635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        if (inValue.isObject())
2408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            {
24181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                if (inValue.inherits(&UserObjectImp::s_info)) {
242231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    UserObjectImp* userObjectImp = static_cast<UserObjectImp *>(asObject(inValue));
2438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    JSUserObject* ptr = userObjectImp->GetJSUserObject();
2448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (ptr)
2458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    {
2468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        result = ptr->CopyCFValue();
2478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    }
2488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
2498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                else
2508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                {
251635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                    JSObject *object = inValue.toObject(exec);
2528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    UInt8 isArray = false;
2538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    // if two objects reference each
2558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    JSObject* imp = object;
2568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    ObjectImpList* temp = inImps;
2578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    while (temp) {
2588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        if (imp == temp->imp) {
2598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            return CFRetain(GetCFNull());
2608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        }
2618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        temp = temp->next;
2628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    }
2638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    ObjectImpList imps;
2658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    imps.next = inImps;
2668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    imps.imp = imp;
2678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project//[...] HACK since we do not have access to the class info we use class name instead
2708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if 0
27181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    if (object->inherits(&ArrayInstanceImp::s_info))
2728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#else
2738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (object->className() == "Array")
2748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
2758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    {
2768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        isArray = true;
2778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        JSGlueGlobalObject* globalObject = static_cast<JSGlueGlobalObject*>(exec->dynamicGlobalObject());
2788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        if (globalObject && (globalObject->Flags() & kJSFlagConvertAssociativeArray)) {
2798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            PropertyNameArray propNames(exec);
2808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            object->getPropertyNames(exec, propNames);
2818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            PropertyNameArray::const_iterator iter = propNames.begin();
2828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            PropertyNameArray::const_iterator end = propNames.end();
2838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            while(iter != end && isArray)
2848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            {
2858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                Identifier propName = *iter;
2868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                UString ustr = propName.ustring();
287f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick                                const UniChar* uniChars = (const UniChar*)ustr.characters();
288f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick                                int size = ustr.length();
2898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                while (size--) {
2908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                    if (uniChars[size] < '0' || uniChars[size] > '9') {
2918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                        isArray = false;
2928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                        break;
2938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                    }
2948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                }
2958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                iter++;
2968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            }
2978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        }
2988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    }
2998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (isArray)
3018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    {
3028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        // This is an KJS array
303635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                        unsigned int length = object->get(exec, Identifier(exec, "length")).toUInt32(exec);
3048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        result = CFArrayCreateMutable(0, 0, &kCFTypeArrayCallBacks);
3058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        if (result)
3068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        {
3078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            for (unsigned i = 0; i < length; i++)
3088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            {
3098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                CFTypeRef cfValue = KJSValueToCFTypeInternal(object->get(exec, i), exec, &imps);
3108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                CFArrayAppendValue((CFMutableArrayRef)result, cfValue);
3118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                ReleaseCFType(cfValue);
3128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            }
3138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        }
3148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    }
3158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    else
3168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    {
3178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        // Not an array, just treat it like a dictionary which contains (property name, property value) pairs
3188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        PropertyNameArray propNames(exec);
3198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        object->getPropertyNames(exec, propNames);
3208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        {
3218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            result = CFDictionaryCreateMutable(0,
3228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                                               0,
3238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                                               &kCFTypeDictionaryKeyCallBacks,
3248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                                               &kCFTypeDictionaryValueCallBacks);
3258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            if (result)
3268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            {
3278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                PropertyNameArray::const_iterator iter = propNames.begin();
3288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                PropertyNameArray::const_iterator end = propNames.end();
3298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                while(iter != end)
3308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                {
3318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                    Identifier propName = *iter;
3328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                    if (object->hasProperty(exec, propName))
3338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                    {
3348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                        CFStringRef cfKey = IdentifierToCFString(propName);
3358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                        CFTypeRef cfValue = KJSValueToCFTypeInternal(object->get(exec, propName), exec, &imps);
3368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                        if (cfKey && cfValue)
3378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                        {
3388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                            CFDictionaryAddValue((CFMutableDictionaryRef)result, cfKey, cfValue);
3398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                        }
3408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                        ReleaseCFType(cfKey);
3418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                        ReleaseCFType(cfValue);
3428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                    }
3438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                    iter++;
3448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                }
3458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            }
3468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        }
3478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    }
3488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
3498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return result;
3508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
3518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
352635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (inValue.isUndefinedOrNull())
3538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        {
3548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            result = RetainCFType(GetCFNull());
3558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return result;
3568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
3578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT_NOT_REACHED();
3598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return 0;
3608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3620bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben MurdochCFTypeRef KJSValueToCFType(JSValue inValue, ExecState *exec)
3638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return KJSValueToCFTypeInternal(inValue, exec, 0);
3658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectCFTypeRef GetCFNull(void)
3688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    static CFArrayRef sCFNull = CFArrayCreate(0, 0, 0, 0);
3708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CFTypeRef result = JSGetCFNull();
3718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!result)
3728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    {
3738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        result = sCFNull;
3748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return result;
3768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
3798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This is a slight hack. The JSGlue API has no concept of execution state.
3808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * However, execution state is an inherent part of JS, and JSCore requires it.
3818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * So, we keep a single execution state for the whole thread and supply it
3828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * where necessary.
3838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * The execution state holds two things: (1) exceptions; (2) the global object.
3858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * JSGlue has no API for accessing exceptions, so we just discard them. As for
3868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * the global object, JSGlue includes no calls that depend on it. Its property
3878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * getters and setters are per-object; they don't walk up the enclosing scope.
3888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Functions called by JSObjectCallFunction may reference values in the enclosing
3898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * scope, but they do so through an internally stored scope chain, so we don't
3908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * need to supply the global scope.
3918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
3928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic pthread_key_t globalObjectKey;
3948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic pthread_once_t globalObjectKeyOnce = PTHREAD_ONCE_INIT;
3958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic void unprotectGlobalObject(void* data)
3978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
39821939df44de1705786c545cd1bf519d47250322dBen Murdoch    JSGlueAPIEntry entry;
39921939df44de1705786c545cd1bf519d47250322dBen Murdoch    gcUnprotect(static_cast<JSGlueGlobalObject*>(data));
4008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic void initializeGlobalObjectKey()
4038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    pthread_key_create(&globalObjectKey, unprotectGlobalObject);
4058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
40721939df44de1705786c545cd1bf519d47250322dBen MurdochJSGlobalData* getThreadGlobalData()
40821939df44de1705786c545cd1bf519d47250322dBen Murdoch{
40921939df44de1705786c545cd1bf519d47250322dBen Murdoch    return &JSGlobalData::sharedInstance();
41021939df44de1705786c545cd1bf519d47250322dBen Murdoch}
41121939df44de1705786c545cd1bf519d47250322dBen Murdoch
4128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic JSGlueGlobalObject* getThreadGlobalObject()
4138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    pthread_once(&globalObjectKeyOnce, initializeGlobalObjectKey);
4158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSGlueGlobalObject* globalObject = static_cast<JSGlueGlobalObject*>(pthread_getspecific(globalObjectKey));
4168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!globalObject) {
4172bde8e466a4451c7319e3a072d118917957d6554Steve Block        globalObject = new (getThreadGlobalData()) JSGlueGlobalObject(*getThreadGlobalData(), JSGlueGlobalObject::createStructure(*getThreadGlobalData(), jsNull()));
4188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gcProtect(globalObject);
4198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        pthread_setspecific(globalObjectKey, globalObject);
4208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
4218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return globalObject;
4228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectExecState* getThreadGlobalExecState()
4258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ExecState* exec = getThreadGlobalObject()->globalExec();
4278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Discard exceptions -- otherwise an exception would forestall JS
4298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // evaluation throughout the thread
4308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    exec->clearException();
4318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return exec;
4328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
433d0825bca7fe65beaee391d30da42e937db621564Steve Block
434d0825bca7fe65beaee391d30da42e937db621564Steve BlockJSGlueAPIEntry::JSGlueAPIEntry()
435d0825bca7fe65beaee391d30da42e937db621564Steve Block    : m_lock(LockForReal)
436dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    , m_storedIdentifierTable(wtfThreadData().currentIdentifierTable())
437dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{
43821939df44de1705786c545cd1bf519d47250322dBen Murdoch    wtfThreadData().setCurrentIdentifierTable(getThreadGlobalData()->identifierTable);
439d0825bca7fe65beaee391d30da42e937db621564Steve Block}
440d0825bca7fe65beaee391d30da42e937db621564Steve Block
441d0825bca7fe65beaee391d30da42e937db621564Steve BlockJSGlueAPIEntry::~JSGlueAPIEntry()
442d0825bca7fe65beaee391d30da42e937db621564Steve Block{
443dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    wtfThreadData().setCurrentIdentifierTable(m_storedIdentifierTable);
444d0825bca7fe65beaee391d30da42e937db621564Steve Block}
445d0825bca7fe65beaee391d30da42e937db621564Steve Block
446d0825bca7fe65beaee391d30da42e937db621564Steve BlockJSGlueAPICallback::JSGlueAPICallback(ExecState* exec)
447d0825bca7fe65beaee391d30da42e937db621564Steve Block    : m_dropLocks(exec)
448d0825bca7fe65beaee391d30da42e937db621564Steve Block{
449dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    wtfThreadData().resetCurrentIdentifierTable();
450d0825bca7fe65beaee391d30da42e937db621564Steve Block}
451d0825bca7fe65beaee391d30da42e937db621564Steve Block
452d0825bca7fe65beaee391d30da42e937db621564Steve BlockJSGlueAPICallback::~JSGlueAPICallback()
453d0825bca7fe65beaee391d30da42e937db621564Steve Block{
45421939df44de1705786c545cd1bf519d47250322dBen Murdoch    wtfThreadData().setCurrentIdentifierTable(getThreadGlobalData()->identifierTable);
455d0825bca7fe65beaee391d30da42e937db621564Steve Block}
456