Rubber stamped by hyatt.
authormjs <mjs@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 6 Sep 2005 08:10:03 +0000 (08:10 +0000)
committermjs <mjs@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 6 Sep 2005 08:10:03 +0000 (08:10 +0000)
- initial import of JavaScriptGlue into our repository

        * English.lproj/InfoPlist.strings: Added.
        * JSBase.cpp: Added.
        (JSBase::JSBase):
        (JSBase::~JSBase):
        (JSBase::Retain):
        (JSBase::Release):
        (JSBase::RetainCount):
        (JSBase::GetTypeID):
        (JSBase::CopyDescription):
        (JSBase::Equal):
        * JSBase.h: Added.
        * JSObject.cpp: Added.
        (JSUserObject::JSUserObject):
        (JSUserObject::~JSUserObject):
        (JSUserObject::CopyPropertyNames):
        (JSUserObject::CopyProperty):
        (JSUserObject::SetProperty):
        (JSUserObject::ImplementsCall):
        (JSUserObject::CallFunction):
        (JSUserObject::CopyCFValue):
        (JSUserObject::Equal):
        (JSUserObject::Mark):
        (JSUserObject::GetData):
        * JSObject.h: Added.
        (JSUserObject::DataType):
        * JSRun.cpp: Added.
        (JSRun::JSRun):
        (JSRun::~JSRun):
        (JSRun::Flags):
        (JSRun::GetSource):
        (JSRun::GlobalObject):
        (JSRun::GetInterpreter):
        (JSRun::Evaluate):
        (JSRun::CheckSyntax):
        * JSRun.h: Added.
        (JSInterpreter::JSInterpreter):
        (JSInterpreter::JSInterpreter::~JSInterpreter):
        (JSInterpreter::Flags):
        * JSUtils.cpp: Added.
        (CFStringToUString):
        (UStringToCFString):
        (CFStringToIdentifier):
        (IdentifierToCFString):
        (KJSValueToJSObject):
        (JSObjectKJSValue):
        (KJSValueToCFTypeInternal):
        (KJSValueToCFType):
        (GetCFNull):
        * JSUtils.h: Added.
        (RetainCFType):
        (ReleaseCFType):
        * JSValueWrapper.cpp: Added.
        (JSValueWrapper::JSValueWrapper):
        (JSValueWrapper::~JSValueWrapper):
        (JSValueWrapper::GetValue):
        (JSValueWrapper::GetExecState):
        (JSValueWrapper::GetJSObectCallBacks):
        (JSValueWrapper::JSObjectDispose):
        (JSValueWrapper::JSObjectCopyPropertyNames):
        (JSValueWrapper::JSObjectCopyProperty):
        (JSValueWrapper::JSObjectSetProperty):
        (JSValueWrapper::JSObjectCallFunction):
        (JSValueWrapper::JSObjectCopyCFValue):
        (JSValueWrapper::JSObjectMark):
        * JSValueWrapper.h: Added.
        * JavaScriptGlue.cpp: Added.
        (JSSetCFNull):
        (JSGetCFNull):
        (JSRetain):
        (JSRelease):
        (JSCopyDescription):
        (JSEqual):
        (JSGetTypeID):
        (JSGetRetainCount):
        (JSObjectCreate):
        (JSObjectCreateInternal):
        (JSObjectCopyCFValue):
        (JSObjectGetData):
        (JSObjectCopyProperty):
        (JSObjectSetProperty):
        (JSObjectCallFunction):
        (JSRunCreate):
        (JSRunCopySource):
        (JSRunCopyGlobalObject):
        (JSRunEvaluate):
        (JSRunCheckSyntax):
        (JSCollect):
        (JSTypeGetCFArrayCallBacks):
        (JSCFRetain):
        (JSCFRelease):
        (JSObjectCreateWithCFType):
        (CFJSObjectDispose):
        (JSObjectCopyPropertyNames):
        (CFJSObjectCopyProperty):
        (CFJSObjectSetProperty):
        (CFJSObjectCopyCFValue):
        (CFJSObjectEqual):
        (CFJSObjectCopyPropertyNames):
        (JSCreateCFArrayFromJSArray):
        (JSCreateJSArrayFromCFArray):
        (JSLockInterpreter):
        (JSUnlockInterpreter):
        * JavaScriptGlue.exp: Added.
        * JavaScriptGlue.h: Added.
        * JavaScriptGlue.pbproj/project.pbxproj: Added.
        * UserObjectImp.cpp: Added.
        (UserObjectPrototypeImp::UserObjectPrototypeImp):
        (UserObjectPrototypeImp::GlobalUserObjectPrototypeImp):
        (UserObjectImp::UserObjectImp):
        (UserObjectImp::~UserObjectImp):
        (UserObjectImp::classInfo):
        (UserObjectImp::implementsCall):
        (UserObjectImp::call):
        (UserObjectImp::propList):
        (UserObjectImp::hasProperty):
        (UserObjectImp::get):
        (UserObjectImp::put):
        (UserObjectImp::GetJSUserObject):
        (UserObjectImp::toPrimitive):
        (UserObjectImp::toBoolean):
        (UserObjectImp::toNumber):
        (UserObjectImp::toString):
        (UserObjectImp::mark):
        * UserObjectImp.h: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@12191 268f45cc-cd09-0410-ab3c-d52691b4dbfc

18 files changed:
JavaScriptGlue/ChangeLog [new file with mode: 0644]
JavaScriptGlue/English.lproj/InfoPlist.strings [new file with mode: 0644]
JavaScriptGlue/JSBase.cpp [new file with mode: 0644]
JavaScriptGlue/JSBase.h [new file with mode: 0644]
JavaScriptGlue/JSObject.cpp [new file with mode: 0644]
JavaScriptGlue/JSObject.h [new file with mode: 0644]
JavaScriptGlue/JSRun.cpp [new file with mode: 0644]
JavaScriptGlue/JSRun.h [new file with mode: 0644]
JavaScriptGlue/JSUtils.cpp [new file with mode: 0644]
JavaScriptGlue/JSUtils.h [new file with mode: 0644]
JavaScriptGlue/JSValueWrapper.cpp [new file with mode: 0644]
JavaScriptGlue/JSValueWrapper.h [new file with mode: 0644]
JavaScriptGlue/JavaScriptGlue.cpp [new file with mode: 0644]
JavaScriptGlue/JavaScriptGlue.exp [new file with mode: 0644]
JavaScriptGlue/JavaScriptGlue.h [new file with mode: 0644]
JavaScriptGlue/JavaScriptGlue.pbproj/project.pbxproj [new file with mode: 0644]
JavaScriptGlue/UserObjectImp.cpp [new file with mode: 0644]
JavaScriptGlue/UserObjectImp.h [new file with mode: 0644]

diff --git a/JavaScriptGlue/ChangeLog b/JavaScriptGlue/ChangeLog
new file mode 100644 (file)
index 0000000..2ef639b
--- /dev/null
@@ -0,0 +1,131 @@
+2005-09-01  Maciej Stachowiak  <mjs@apple.com>
+
+        Rubber stamped by hyatt.
+
+       - initial import of JavaScriptGlue into our repository
+
+        * English.lproj/InfoPlist.strings: Added.
+        * JSBase.cpp: Added.
+        (JSBase::JSBase):
+        (JSBase::~JSBase):
+        (JSBase::Retain):
+        (JSBase::Release):
+        (JSBase::RetainCount):
+        (JSBase::GetTypeID):
+        (JSBase::CopyDescription):
+        (JSBase::Equal):
+        * JSBase.h: Added.
+        * JSObject.cpp: Added.
+        (JSUserObject::JSUserObject):
+        (JSUserObject::~JSUserObject):
+        (JSUserObject::CopyPropertyNames):
+        (JSUserObject::CopyProperty):
+        (JSUserObject::SetProperty):
+        (JSUserObject::ImplementsCall):
+        (JSUserObject::CallFunction):
+        (JSUserObject::CopyCFValue):
+        (JSUserObject::Equal):
+        (JSUserObject::Mark):
+        (JSUserObject::GetData):
+        * JSObject.h: Added.
+        (JSUserObject::DataType):
+        * JSRun.cpp: Added.
+        (JSRun::JSRun):
+        (JSRun::~JSRun):
+        (JSRun::Flags):
+        (JSRun::GetSource):
+        (JSRun::GlobalObject):
+        (JSRun::GetInterpreter):
+        (JSRun::Evaluate):
+        (JSRun::CheckSyntax):
+        * JSRun.h: Added.
+        (JSInterpreter::JSInterpreter):
+        (JSInterpreter::JSInterpreter::~JSInterpreter):
+        (JSInterpreter::Flags):
+        * JSUtils.cpp: Added.
+        (CFStringToUString):
+        (UStringToCFString):
+        (CFStringToIdentifier):
+        (IdentifierToCFString):
+        (KJSValueToJSObject):
+        (JSObjectKJSValue):
+        (KJSValueToCFTypeInternal):
+        (KJSValueToCFType):
+        (GetCFNull):
+        * JSUtils.h: Added.
+        (RetainCFType):
+        (ReleaseCFType):
+        * JSValueWrapper.cpp: Added.
+        (JSValueWrapper::JSValueWrapper):
+        (JSValueWrapper::~JSValueWrapper):
+        (JSValueWrapper::GetValue):
+        (JSValueWrapper::GetExecState):
+        (JSValueWrapper::GetJSObectCallBacks):
+        (JSValueWrapper::JSObjectDispose):
+        (JSValueWrapper::JSObjectCopyPropertyNames):
+        (JSValueWrapper::JSObjectCopyProperty):
+        (JSValueWrapper::JSObjectSetProperty):
+        (JSValueWrapper::JSObjectCallFunction):
+        (JSValueWrapper::JSObjectCopyCFValue):
+        (JSValueWrapper::JSObjectMark):
+        * JSValueWrapper.h: Added.
+        * JavaScriptGlue.cpp: Added.
+        (JSSetCFNull):
+        (JSGetCFNull):
+        (JSRetain):
+        (JSRelease):
+        (JSCopyDescription):
+        (JSEqual):
+        (JSGetTypeID):
+        (JSGetRetainCount):
+        (JSObjectCreate):
+        (JSObjectCreateInternal):
+        (JSObjectCopyCFValue):
+        (JSObjectGetData):
+        (JSObjectCopyProperty):
+        (JSObjectSetProperty):
+        (JSObjectCallFunction):
+        (JSRunCreate):
+        (JSRunCopySource):
+        (JSRunCopyGlobalObject):
+        (JSRunEvaluate):
+        (JSRunCheckSyntax):
+        (JSCollect):
+        (JSTypeGetCFArrayCallBacks):
+        (JSCFRetain):
+        (JSCFRelease):
+        (JSObjectCreateWithCFType):
+        (CFJSObjectDispose):
+        (JSObjectCopyPropertyNames):
+        (CFJSObjectCopyProperty):
+        (CFJSObjectSetProperty):
+        (CFJSObjectCopyCFValue):
+        (CFJSObjectEqual):
+        (CFJSObjectCopyPropertyNames):
+        (JSCreateCFArrayFromJSArray):
+        (JSCreateJSArrayFromCFArray):
+        (JSLockInterpreter):
+        (JSUnlockInterpreter):
+        * JavaScriptGlue.exp: Added.
+        * JavaScriptGlue.h: Added.
+        * JavaScriptGlue.pbproj/project.pbxproj: Added.
+        * UserObjectImp.cpp: Added.
+        (UserObjectPrototypeImp::UserObjectPrototypeImp):
+        (UserObjectPrototypeImp::GlobalUserObjectPrototypeImp):
+        (UserObjectImp::UserObjectImp):
+        (UserObjectImp::~UserObjectImp):
+        (UserObjectImp::classInfo):
+        (UserObjectImp::implementsCall):
+        (UserObjectImp::call):
+        (UserObjectImp::propList):
+        (UserObjectImp::hasProperty):
+        (UserObjectImp::get):
+        (UserObjectImp::put):
+        (UserObjectImp::GetJSUserObject):
+        (UserObjectImp::toPrimitive):
+        (UserObjectImp::toBoolean):
+        (UserObjectImp::toNumber):
+        (UserObjectImp::toString):
+        (UserObjectImp::mark):
+        * UserObjectImp.h: Added.
+
diff --git a/JavaScriptGlue/English.lproj/InfoPlist.strings b/JavaScriptGlue/English.lproj/InfoPlist.strings
new file mode 100644 (file)
index 0000000..5a35b05
Binary files /dev/null and b/JavaScriptGlue/English.lproj/InfoPlist.strings differ
diff --git a/JavaScriptGlue/JSBase.cpp b/JavaScriptGlue/JSBase.cpp
new file mode 100644 (file)
index 0000000..8007c8f
--- /dev/null
@@ -0,0 +1,52 @@
+//
+// JSBase.cpp
+//
+
+#include "JSBase.h"
+
+JSBase::JSBase(JSTypeID type) : fTypeID(type), fRetainCount(1) 
+{ 
+}
+
+JSBase::~JSBase() 
+{
+}
+       
+JSBase* JSBase::Retain() 
+{
+       fRetainCount++; return this; 
+}
+
+void JSBase::Release() 
+{ 
+       if (--fRetainCount == 0) 
+       {
+               delete this;
+       } 
+}
+
+CFIndex JSBase::RetainCount() const
+{
+       return fRetainCount; 
+}
+
+JSTypeID JSBase::GetTypeID() const 
+{ 
+       return fTypeID; 
+}
+               
+CFStringRef JSBase::CopyDescription() 
+{ 
+       return CFStringCreateWithFormat(
+                               NULL,
+                               NULL,
+                               CFSTR("<JSTypeRef- ptr:0x%lx type: %d, retaincount: %ld>"), 
+                               (long)this,
+                               (int)fTypeID,
+                               (long)fRetainCount); 
+}
+
+UInt8 JSBase::Equal(JSBase* other) 
+{ 
+       return this == other; 
+}
diff --git a/JavaScriptGlue/JSBase.h b/JavaScriptGlue/JSBase.h
new file mode 100644 (file)
index 0000000..de59869
--- /dev/null
@@ -0,0 +1,28 @@
+//
+// JSBase.h
+//
+
+#ifndef __JSBase_h
+#define __JSBase_h
+
+#include "JSUtils.h"
+
+class JSBase {
+       public:
+               JSBase(JSTypeID type);
+               virtual ~JSBase();
+       
+               JSBase* Retain();
+               void Release();
+               CFIndex RetainCount() const;
+               JSTypeID GetTypeID() const;
+               
+               virtual CFStringRef CopyDescription();
+               virtual UInt8 Equal(JSBase* other);
+               
+       private:
+               JSTypeID fTypeID;
+               CFIndex fRetainCount;
+};
+
+#endif
\ No newline at end of file
diff --git a/JavaScriptGlue/JSObject.cpp b/JavaScriptGlue/JSObject.cpp
new file mode 100644 (file)
index 0000000..1c0a078
--- /dev/null
@@ -0,0 +1,113 @@
+//
+//     JSObject.cpp
+//
+
+#include "JSObject.h"
+
+JSUserObject::JSUserObject(JSObjectCallBacksPtr callBacks, JSObjectMarkProcPtr markProc, void* data, int dataType) 
+       : JSBase(kJSObjectTypeID), fCallBacks(*callBacks), fMarkProc(markProc), fData(data), fDataType(dataType)
+{ 
+}
+
+JSUserObject::~JSUserObject()
+{
+       if (fCallBacks.dispose)
+       {
+               fCallBacks.dispose(fData);
+       }
+}
+
+CFArrayRef JSUserObject::CopyPropertyNames(void)
+{
+       CFArrayRef result = NULL;
+       if (fCallBacks.copyPropertyNames)
+       {
+               result = fCallBacks.copyPropertyNames(fData);
+       }
+       return result;
+}
+               
+JSUserObject* JSUserObject::CopyProperty(CFStringRef propertyName)
+{
+       JSUserObject* result = NULL;
+       if (fCallBacks.copyProperty)
+       {
+               result = (JSUserObject*)fCallBacks.copyProperty(fData, propertyName);
+       }
+       return result;
+}
+
+void JSUserObject::SetProperty(CFStringRef propertyName, JSUserObject* value)
+{
+       if (fCallBacks.setProperty)
+       {
+               fCallBacks.setProperty(fData, propertyName, (JSObjectRef)value);
+       }
+
+}
+
+bool JSUserObject::ImplementsCall()
+{
+       return fCallBacks.callFunction ? true : false;
+}
+
+JSUserObject* JSUserObject::CallFunction(JSUserObject* thisObj, CFArrayRef args)
+{
+       JSUserObject* result = NULL;
+       if (fCallBacks.callFunction)
+       {
+               result = (JSUserObject*)fCallBacks.callFunction(fData, (JSObjectRef)thisObj, args);
+       }
+       return result;
+
+}
+
+CFTypeRef JSUserObject::CopyCFValue() const
+{
+       CFTypeRef result = NULL;
+       if (fCallBacks.copyCFValue)
+       {
+               result = (JSUserObject*)fCallBacks.copyCFValue(fData);
+       }
+       return result;
+}
+
+UInt8 JSUserObject::Equal(JSBase* other)
+{
+       UInt8 result = false;
+       JSUserObject* obj = (JSUserObject*)other;
+       if (obj->GetTypeID() == kJSObjectTypeID)
+       {
+               if (fCallBacks.equal)
+               {
+                       result = fCallBacks.equal(GetData(), obj->GetData());
+               }
+               else
+               {
+                       CFTypeRef cf1 = CopyCFValue();
+                       CFTypeRef cf2 = obj->CopyCFValue();
+                       if (cf1 && cf2)
+                       {
+                               result = CFEqual(cf1, cf2);
+                       }
+                       ReleaseCFType(cf2);
+                       ReleaseCFType(cf1);
+               }
+       }
+       return result;
+}
+
+void JSUserObject::Mark()
+{
+       if (fMarkProc)
+       {
+               fMarkProc(fData);
+       }
+}
+
+void* JSUserObject::GetData() 
+{
+       return fData; 
+}
+
+
diff --git a/JavaScriptGlue/JSObject.h b/JavaScriptGlue/JSObject.h
new file mode 100644 (file)
index 0000000..eb8548a
--- /dev/null
@@ -0,0 +1,38 @@
+//
+// JSObject.h
+//
+
+#ifndef __JSObject_h
+#define __JSObject_h
+
+#include "JSBase.h"
+#include "JSUtils.h"
+
+typedef void (*JSObjectMarkProcPtr)(void* data);
+JSObjectRef JSObjectCreateInternal(void* data, JSObjectCallBacksPtr callBacks, JSObjectMarkProcPtr markProc, int dataType);
+
+class JSUserObject : public JSBase {
+       public:
+//             JSUserObject(JSObjectCallBacksPtr callBacks, JSObjectMarkProcPtr markProc, void* data, int dataType = kJSUserObjectDataTypeUnknown);
+               JSUserObject(JSObjectCallBacksPtr callBacks, JSObjectMarkProcPtr markProc, void* data, int dataType);
+               virtual ~JSUserObject();
+               
+               CFArrayRef CopyPropertyNames(void);
+               JSUserObject* CopyProperty(CFStringRef propertyName);
+               void SetProperty(CFStringRef propertyName, JSUserObject* value);
+               bool ImplementsCall();
+               JSUserObject* CallFunction(JSUserObject* thisObj, CFArrayRef args);
+               CFTypeRef CopyCFValue() const;
+               virtual UInt8 Equal(JSBase* other);
+               void* GetData();
+               void Mark();
+               
+                int DataType() const { return fDataType; }
+       private:
+               JSObjectCallBacks fCallBacks;
+               JSObjectMarkProcPtr fMarkProc;
+               void* fData;
+                int fDataType;
+};
+
+#endif
\ No newline at end of file
diff --git a/JavaScriptGlue/JSRun.cpp b/JavaScriptGlue/JSRun.cpp
new file mode 100644 (file)
index 0000000..1548710
--- /dev/null
@@ -0,0 +1,49 @@
+//
+// JSRun.h
+//
+
+#include "JSRun.h"
+
+JSRun::JSRun(CFStringRef source, JSFlags inFlags) 
+       :       JSBase(kJSRunTypeID), 
+               fSource(CFStringToUString(source)), 
+               fGlobalObject(Object(new ObjectImp())),
+               fInterpreter(fGlobalObject, inFlags),
+               fFlags(inFlags)
+{
+}
+                               
+JSRun::~JSRun() 
+{ 
+}
+
+JSFlags JSRun::Flags() const
+{
+       return fFlags;
+}
+
+UString JSRun::GetSource() const
+{
+       return fSource;
+}
+
+Object JSRun::GlobalObject() const
+{
+       return fGlobalObject;
+}
+
+JSInterpreter* JSRun::GetInterpreter() 
+{
+       return &fInterpreter; 
+}
+
+Completion JSRun::Evaluate() 
+{ 
+       return fInterpreter.evaluate(fSource); 
+}
+
+
+bool JSRun::CheckSyntax() 
+{ 
+       return fInterpreter.checkSyntax(fSource); 
+}
diff --git a/JavaScriptGlue/JSRun.h b/JavaScriptGlue/JSRun.h
new file mode 100644 (file)
index 0000000..6d6f76c
--- /dev/null
@@ -0,0 +1,40 @@
+#ifndef __JSRun_h
+#define __JSRun_h
+
+/*
+       JSRun.h
+*/
+
+#include "JSBase.h"
+#include "JSUtils.h"
+
+class JSInterpreter : public Interpreter {
+       public:
+               JSInterpreter(const Object &global, JSFlags flags) : Interpreter(global), fJSFlags(flags) { }
+               JSInterpreter(const Object &global) : Interpreter(global), fJSFlags(kJSFlagNone) { }
+               JSInterpreter() : Interpreter(), fJSFlags(kJSFlagNone) { }
+               JSInterpreter::~JSInterpreter() { }
+               JSFlags Flags() const { return fJSFlags; }
+       private:
+               JSFlags fJSFlags;
+};
+
+class JSRun : public JSBase {
+       public:
+               JSRun(CFStringRef source, JSFlags inFlags);
+               virtual ~JSRun();
+
+               UString GetSource() const;
+               Object GlobalObject() const;
+               JSInterpreter* GetInterpreter();
+               Completion Evaluate();
+               bool CheckSyntax();
+               JSFlags Flags() const;
+       private:
+               UString fSource;                
+               ProtectedObject fGlobalObject;
+               JSInterpreter fInterpreter;
+               JSFlags fFlags;
+};
+
+#endif
\ No newline at end of file
diff --git a/JavaScriptGlue/JSUtils.cpp b/JavaScriptGlue/JSUtils.cpp
new file mode 100644 (file)
index 0000000..59277bd
--- /dev/null
@@ -0,0 +1,466 @@
+//
+// JSUtils.cpp
+//
+
+#include "JSUtils.h"
+#include "JSBase.h"
+#include "JSObject.h"
+#include "JSRun.h"
+#include "UserObjectImp.h"
+#include "JSValueWrapper.h"
+#include "JSObject.h"
+
+struct ObjectImpList {
+       ObjectImp* imp;
+       ObjectImpList* next;
+       CFTypeRef data;
+};
+
+static CFTypeRef KJSValueToCFTypeInternal(const Value& inValue, ExecState *exec, ObjectImpList* inImps);
+
+
+//--------------------------------------------------------------------------
+//     CFStringToUString
+//--------------------------------------------------------------------------
+
+UString CFStringToUString(CFStringRef inCFString)
+{
+       UString result;
+    if (inCFString)
+    {
+        CFIndex len = CFStringGetLength(inCFString);
+        UniChar* buffer = (UniChar*)malloc(sizeof(UniChar) * len);
+        if (buffer)
+        {
+            CFStringGetCharacters(inCFString, CFRangeMake(0, len), buffer);
+            result = UString((const UChar *)buffer, len);
+            free(buffer);
+        }
+    }
+       return result;
+}
+
+
+//--------------------------------------------------------------------------
+//     UStringToCFString
+//--------------------------------------------------------------------------
+// Caller is responsible for releasing the returned CFStringRef
+CFStringRef UStringToCFString(const UString& inUString)
+{
+       return CFStringCreateWithCharacters(NULL, (const UniChar*)inUString.data(), inUString.size());
+}
+
+
+#if JAG_PINK_OR_LATER
+//--------------------------------------------------------------------------
+//     CFStringToIdentifier
+//--------------------------------------------------------------------------
+
+Identifier CFStringToIdentifier(CFStringRef inCFString)
+{
+       return Identifier(CFStringToUString(inCFString));
+}
+
+
+//--------------------------------------------------------------------------
+//     IdentifierToCFString
+//--------------------------------------------------------------------------
+// Caller is responsible for releasing the returned CFStringRef
+CFStringRef IdentifierToCFString(const Identifier& inIdentifier)
+{
+       return UStringToCFString(inIdentifier.ustring());
+}
+#endif
+
+
+//--------------------------------------------------------------------------
+//     KJSValueToJSObject
+//--------------------------------------------------------------------------
+JSUserObject*          KJSValueToJSObject(const Value& inValue, ExecState *exec)
+{
+       JSUserObject* result = NULL;
+#if JAG_PINK_OR_LATER
+       UserObjectImp* userObjectImp;
+       if (inValue.type() == ObjectType && (userObjectImp = dynamic_cast<UserObjectImp*>(inValue.imp())))
+#else
+       if (UserObjectImp* userObjectImp = dynamic_cast<UserObjectImp*>(inValue.imp()))
+#endif
+       {
+               result =  userObjectImp->GetJSUserObject();
+               if (result) result->Retain();
+       }
+       else
+       {
+               JSValueWrapper* wrapperValue = new JSValueWrapper(inValue, exec);
+               if (wrapperValue)
+               {
+                       JSObjectCallBacks callBacks;
+                       JSValueWrapper::GetJSObectCallBacks(callBacks);
+                       result = (JSUserObject*)JSObjectCreate(wrapperValue, &callBacks);
+                       if (!result)
+                       {
+                               delete wrapperValue;
+                       }
+               }
+       }
+       return result;
+}
+
+//--------------------------------------------------------------------------
+//     JSObjectKJSValue
+//--------------------------------------------------------------------------
+Value JSObjectKJSValue(JSUserObject* ptr)
+{
+    Value result = Undefined();
+    if (ptr)
+    {
+        bool handled = false;
+        
+        switch (ptr->DataType())
+        {
+            case kJSUserObjectDataTypeJSValueWrapper:
+            {
+                JSValueWrapper* wrapper = (JSValueWrapper*)ptr->GetData();
+                if (wrapper)
+                {
+                    result = wrapper->GetValue();
+                    handled = true;
+                }
+                break;
+            }
+                
+            case kJSUserObjectDataTypeCFType:
+            {
+                CFTypeRef cfType = (CFTypeRef*)ptr->GetData();
+                if (cfType)
+                {
+                    CFTypeID typeID = CFGetTypeID(cfType);
+                    if (typeID == CFStringGetTypeID())
+                    {
+                        result = String(CFStringToUString((CFStringRef)cfType));
+                        handled = true;
+                    }
+                    else if (typeID == CFNumberGetTypeID())
+                    {
+                        if (CFNumberIsFloatType((CFNumberRef)cfType))
+                        {
+                            double num;
+                            if (CFNumberGetValue((CFNumberRef)cfType, kCFNumberDoubleType, &num))
+                            {
+                                result = Number(num);
+                                handled = true;
+                            }
+                        }
+                        else
+                        {
+                            long num;
+                            if (CFNumberGetValue((CFNumberRef)cfType, kCFNumberLongType, &num))
+                            {
+                                result = Number(num);
+                                handled = true;
+                            }
+                        }
+                    }
+                    else if (typeID == CFBooleanGetTypeID())
+                    {
+                        result = KJS::Boolean(CFBooleanGetValue((CFBooleanRef)cfType));
+                        handled = true;
+                    }
+                    else if (typeID == CFDateGetTypeID())
+                    {
+                    }
+                    else if (typeID == CFNullGetTypeID())
+                    {
+                        result = Null();
+                        handled = true;
+                    }
+                }
+                break;
+            }
+        }
+        if (!handled)
+        {
+            result = Object(new UserObjectImp(ptr));
+        }
+    }
+    return result;
+}
+
+
+
+
+//--------------------------------------------------------------------------
+//     KJSValueToCFTypeInternal
+//--------------------------------------------------------------------------
+// Caller is responsible for releasing the returned CFTypeRef
+CFTypeRef KJSValueToCFTypeInternal(const Value& inValue, ExecState *exec, ObjectImpList* inImps)
+{
+#if JAG_PINK_OR_LATER
+       if (inValue.isNull())
+               return NULL;
+#endif
+               
+       CFTypeRef result = NULL;
+       
+       switch (inValue.type())
+       {
+               case BooleanType:
+                       {
+                               result = inValue.toBoolean(exec) ? kCFBooleanTrue : kCFBooleanFalse;
+                               RetainCFType(result);
+                       }
+                       break;
+                       
+               case StringType:
+                       {
+                               UString uString = inValue.toString(exec);
+                               result = UStringToCFString(uString);
+                       }
+                       break;
+                       
+               case NumberType:
+                       {
+                               double number1 = inValue.toNumber(exec);
+                               double number2 = (double)inValue.toInteger(exec);
+                               if (number1 ==  number2)
+                               {
+                                       int intValue = (int)number2;
+                                       result = CFNumberCreate(NULL, kCFNumberIntType, &intValue);
+                               }
+                               else
+                               {
+                                       result = CFNumberCreate(NULL, kCFNumberDoubleType, &number1);
+                               }
+                       }
+                       break;
+                       
+               case ObjectType:
+                       {
+                               if (UserObjectImp* userObjectImp = dynamic_cast<UserObjectImp*>(inValue.imp()))
+                               {
+                                       JSUserObject* ptr = userObjectImp->GetJSUserObject();
+                                       if (ptr)
+                                       {
+                                               result = ptr->CopyCFValue();
+                                       }
+                               }
+                               else
+                               {
+                                       Object object = inValue.toObject(exec);
+                                       UInt8 isArray = false;
+
+                                       // if two objects reference each
+                                       ObjectImp* imp = object.imp();
+                                       ObjectImpList* temp = inImps;
+                                       while (temp) {
+                                               if (imp == temp->imp) {
+                                                       return CFRetain(GetCFNull());
+                                               }
+                                               temp = temp->next;
+                                       }
+
+                                       ObjectImpList imps;
+                                       imps.next = inImps;
+                                       imps.imp = imp;
+
+                                       
+//[...] HACK since we do not have access to the class info we use class name instead
+#if 0
+                                       if (object.inherits(&ArrayInstanceImp::info))
+#else
+                                       if (object.className() == "Array")
+#endif
+                                       {
+                                               isArray = true;                                 
+#if JAG_PINK_OR_LATER
+                                               JSInterpreter* intrepreter = (JSInterpreter*)exec->dynamicInterpreter();
+                                               if (intrepreter && (intrepreter->Flags() & kJSFlagConvertAssociativeArray)) {
+                                                       ReferenceList propList = object.propList(exec, false);
+                                                       ReferenceListIterator iter = propList.begin();
+                                                       ReferenceListIterator end = propList.end();
+                                                       while(iter != end && isArray)
+                                                       {
+                                                               Identifier propName = iter->getPropertyName(exec);
+                                                               UString ustr = propName.ustring();
+                                                               const UniChar* uniChars = (const UniChar*)ustr.data();
+                                                               int size = ustr.size();
+                                                               while (size--) {
+                                                                       if (uniChars[size] < '0' || uniChars[size] > '9') {
+                                                                               isArray = false;
+                                                                               break;
+                                                                       }
+                                                               }
+                                                               iter++;
+                                                       }
+                                               }
+#endif
+                                       }
+                                       
+                                       if (isArray)
+                                       {                               
+                                               // This is an KJS array
+                                               unsigned int length = object.get(exec, "length").toUInt32(exec);
+                                               result = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+                                               if (result)
+                                               {
+#if JAG_PINK_OR_LATER
+                                                       for (unsigned i = 0; i < length; i++)
+                                                       {
+                                                               CFTypeRef cfValue = KJSValueToCFTypeInternal(object.get(exec, i), exec, &imps);
+                                                               CFArrayAppendValue((CFMutableArrayRef)result, cfValue);
+                                                               ReleaseCFType(cfValue);
+                                                       }
+#else
+                                                       for (unsigned int i = 0; i < length; i++)
+                                                       {
+                                                               UString propertyName = UString::from(i);
+                                                               CFTypeRef cfValue = KJSValueToCFTypeInternal(object.get(exec, propertyName), exec, &imps);
+                                                               CFArrayAppendValue((CFMutableArrayRef)result, cfValue);
+                                                               ReleaseCFType(cfValue);
+                                                       }
+#endif
+                                               }
+                                       }
+                                       else
+                                       {
+#if JAG_PINK_OR_LATER
+                                               // Not an arry, just treat it like a dictionary which contains (property name, property value) paiars
+                                               ReferenceList propList = object.propList(exec, false);
+                                               {
+                                                       result = CFDictionaryCreateMutable(NULL, 
+                                                                                                                          0, 
+                                                                                                                          &kCFTypeDictionaryKeyCallBacks, 
+                                                                                                                          &kCFTypeDictionaryValueCallBacks);
+                                                       if (result)
+                                                       {
+                                                               ReferenceListIterator iter = propList.begin();
+                                                               ReferenceListIterator end = propList.end();
+                                                               while(iter != end)
+                                                               {
+                                                                       Identifier propName = iter->getPropertyName(exec);
+                                                                       if (object.hasProperty(exec, propName))
+                                                                       {
+                                                                               CFStringRef cfKey = IdentifierToCFString(propName);
+                                                                               CFTypeRef cfValue = KJSValueToCFTypeInternal(object.get(exec, propName), exec, &imps);
+                                                                               if (cfKey && cfValue)
+                                                                               {
+                                                                                       CFDictionaryAddValue((CFMutableDictionaryRef)result, cfKey, cfValue);
+                                                                               }
+                                                                               ReleaseCFType(cfKey);
+                                                                               ReleaseCFType(cfValue);
+                                                                       }
+                                                                       iter++;
+                                                               }
+                                                       }
+                                               }
+#else
+                                               List propList = object.propList(exec);
+                                               if (propList.size() > 0)
+                                               {
+                                                       result = CFDictionaryCreateMutable(NULL, 
+                                                                                                                          0, 
+                                                                                                                          &kCFTypeDictionaryKeyCallBacks, 
+                                                                                                                          &kCFTypeDictionaryValueCallBacks);
+                                                       if (result)
+                                                       {
+                                                               ListIterator iter = propList.begin();
+                                                               ListIterator end = propList.end();
+                                                               while(iter != end)
+                                                               {
+                                                                       UString propName = iter->getPropertyName(exec);
+                                                                       if (object.hasProperty(exec, propName))
+                                                                       {
+                                                                               CFStringRef cfKey = UStringToCFString(propName);
+                                                                               CFTypeRef cfValue = KJSValueToCFTypeInternal(iter->getValue(exec), exec, &imps);
+                                                                               if (cfKey && cfValue)
+                                                                               {
+                                                                                       CFDictionaryAddValue((CFMutableDictionaryRef)result, cfKey, cfValue);
+                                                                               }
+                                                                               ReleaseCFType(cfKey);
+                                                                               ReleaseCFType(cfValue);
+                                                                       }
+                                                                       ++iter;
+                                                               }
+                                                       }
+                                               }
+#endif
+                                       }
+                               }
+                       }
+                       break;
+
+#if !JAG_PINK_OR_LATER
+               case ReferenceType:
+                       {
+                               Value value = inValue.getValue(exec);
+                               result = KJSValueToCFTypeInternal(value, exec, NULL);
+                       }
+                       break;
+
+               case ListType:
+                       {
+                               List list = List::dynamicCast(inValue);
+                               if (!list.isNull())
+                               {
+                                       result = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+                                       if (result)
+                                       {
+                                               ListIterator iter = list.begin();
+                                               ListIterator end = list.end();
+                                               while (iter != end)
+                                               {
+                                                       CFTypeRef cfTypeRef = KJSValueToCFTypeInternal(*iter, exec, NULL);
+                                                       if (cfTypeRef)
+                                                               CFArrayAppendValue((CFMutableArrayRef)result, cfTypeRef);
+                                                       ++iter;
+                                               }
+                                       }
+                               }
+                       }
+                       break;
+#endif
+               
+               case NullType:
+               case UndefinedType:
+               case UnspecifiedType:
+                       result = RetainCFType(GetCFNull());
+                       break;
+                       
+#if !JAG_PINK_OR_LATER
+               case CompletionType:
+                       {
+                               Completion completion = Completion::dynamicCast(inValue);
+                               if (completion.isValueCompletion())
+                               {
+                                       result = KJSValueToCFTypeInternal(completion.value(), exec, NULL);
+                               }
+                       }
+                       break;
+#endif
+
+#if JAG_PINK_OR_LATER
+               default:
+                       fprintf(stderr, "KJSValueToCFType: wrong value type %d\n", inValue.type());
+                       break;
+#endif
+       }
+       
+       return result;
+}
+
+CFTypeRef KJSValueToCFType(const Value& inValue, ExecState *exec)
+{
+       return KJSValueToCFTypeInternal(inValue, exec, NULL);
+}
+
+CFTypeRef GetCFNull(void)
+{
+       static CFArrayRef sCFNull = CFArrayCreate(NULL, NULL, 0, NULL);
+       CFTypeRef result = JSGetCFNull();
+       if (!result)
+       {
+               result = sCFNull;
+       }
+       return result;
+}
+
diff --git a/JavaScriptGlue/JSUtils.h b/JavaScriptGlue/JSUtils.h
new file mode 100644 (file)
index 0000000..9f5fa6e
--- /dev/null
@@ -0,0 +1,66 @@
+#ifndef __JSUtils_h
+#define __JSUtils_h
+
+/*
+       JSUtils.h
+*/
+
+#ifndef __CORESERVICES__
+#include <CoreServices/CoreServices.h>
+#endif
+
+#include <JavaScriptGlue/JavaScriptGlue.h>
+
+#ifdef USE_JSHACK
+#include <JSHack/value.h>
+#include <JSHack/object.h>
+#include <JSHack/types.h>
+#include <JSHack/interpreter.h>
+#include <JSHack/ustring.h>
+#else
+#include <JavaScriptCore/value.h>
+#include <JavaScriptCore/object.h>
+#include <JavaScriptCore/types.h>
+#include <JavaScriptCore/interpreter.h>
+#include <JavaScriptCore/collector.h>
+#include <JavaScriptCore/ustring.h>
+#endif
+
+#define JAG_PINK_OR_LATER      1 /* %%% turn on for new JavaScriptCore */
+
+using namespace KJS;
+
+class JSBase;
+class JSUserObject;
+class JSRun;
+class JSValueWrapper;
+class JSUserObjectImp;
+
+UString CFStringToUString(CFStringRef inCFString);
+CFStringRef UStringToCFString(const UString& inUString);
+#if JAG_PINK_OR_LATER
+Identifier CFStringToIdentifier(CFStringRef inCFString);
+CFStringRef IdentifierToCFString(const Identifier& inIdentifier);
+#endif
+JSUserObject* KJSValueToJSObject(const Value& inValue, ExecState *exec);
+CFTypeRef KJSValueToCFType(const Value& inValue, ExecState *exec);
+Value JSObjectKJSValue(JSUserObject* ptr);
+CFTypeRef GetCFNull(void);
+
+inline CFTypeRef RetainCFType(CFTypeRef x) { if (x) x = CFRetain(x); return x; }
+inline void ReleaseCFType(CFTypeRef x) { if (x) CFRelease(x);  }
+
+enum {
+       kJSInvalidTypeID = 0,
+       kJSObjectTypeID,
+       kJSRunTypeID
+};
+
+enum {
+    kJSUserObjectDataTypeUnknown,
+    kJSUserObjectDataTypeJSValueWrapper,
+    kJSUserObjectDataTypeCFType
+};
+
+
+#endif
diff --git a/JavaScriptGlue/JSValueWrapper.cpp b/JavaScriptGlue/JSValueWrapper.cpp
new file mode 100644 (file)
index 0000000..1cecf8a
--- /dev/null
@@ -0,0 +1,186 @@
+//
+// JSValueWrapper.cpp
+//
+#include "JSValueWrapper.h"
+
+JSValueWrapper::JSValueWrapper(const Value& inValue, ExecState *inExec) 
+       : fValue(inValue), fExec(inExec) 
+{ 
+}
+
+JSValueWrapper::~JSValueWrapper()
+{ 
+}
+
+Value& JSValueWrapper::GetValue() 
+{ 
+       return fValue; 
+}
+ExecState* JSValueWrapper::GetExecState() const 
+{
+       return fExec; 
+}
+       
+
+void JSValueWrapper::GetJSObectCallBacks(JSObjectCallBacks& callBacks)
+{
+       callBacks.dispose = (JSObjectDisposeProcPtr)JSValueWrapper::JSObjectDispose;
+       callBacks.equal = (JSObjectEqualProcPtr)NULL;
+       callBacks.copyPropertyNames = (JSObjectCopyPropertyNamesProcPtr)JSValueWrapper::JSObjectCopyPropertyNames;
+       callBacks.copyCFValue = (JSObjectCopyCFValueProcPtr)JSValueWrapper::JSObjectCopyCFValue;
+       callBacks.copyProperty = (JSObjectCopyPropertyProcPtr)JSValueWrapper::JSObjectCopyProperty;
+       callBacks.setProperty = (JSObjectSetPropertyProcPtr)JSValueWrapper::JSObjectSetProperty;
+       callBacks.callFunction = (JSObjectCallFunctionProcPtr)JSValueWrapper::JSObjectCallFunction;
+}
+                       
+void JSValueWrapper::JSObjectDispose(void* data)
+{
+       JSValueWrapper* ptr = (JSValueWrapper*)data;
+       delete ptr;
+}
+       
+
+CFArrayRef JSValueWrapper::JSObjectCopyPropertyNames(void* data)
+{
+       CFMutableArrayRef result = NULL;
+       JSValueWrapper* ptr = (JSValueWrapper*)data;
+       if (ptr)
+       {
+               ExecState* exec = ptr->GetExecState();
+#if JAG_PINK_OR_LATER
+               Object object = ptr->GetValue().toObject(exec);
+               ReferenceList list = object.propList(exec, false);
+               ReferenceListIterator iterator = list.begin();
+#else
+               Object object = ptr->GetValue().imp()->toObject(exec);
+                List list = object.propList(exec, false);
+               ListIterator iterator = list.begin();
+#endif
+
+
+               while (iterator != list.end()) {
+#if JAG_PINK_OR_LATER
+                       Identifier name = iterator->getPropertyName(exec);
+                       CFStringRef nameStr = IdentifierToCFString(name);
+#else
+                       UString name = iterator->getPropertyName(exec);
+                       CFStringRef nameStr = UStringToCFString(name);
+#endif
+                       if (!result)
+                       {
+                               result = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+                       }
+                       if (result && nameStr)
+                       {
+                               CFArrayAppendValue(result, nameStr);
+                       }
+                       ReleaseCFType(nameStr);
+                       iterator++;
+               }
+
+       }
+       return result;
+}
+
+
+JSObjectRef JSValueWrapper::JSObjectCopyProperty(void* data, CFStringRef propertyName)
+{
+       JSObjectRef result = NULL;
+       JSValueWrapper* ptr = (JSValueWrapper*)data;
+       if (ptr)
+       {
+               ExecState* exec = ptr->GetExecState();
+#if JAG_PINK_OR_LATER
+               Value propValue = ptr->GetValue().toObject(exec).get(exec, CFStringToIdentifier(propertyName));
+#else
+               Value propValue = ptr->GetValue().imp()->toObject(exec).get(exec, CFStringToUString(propertyName));
+#endif
+               JSValueWrapper* wrapperValue = new JSValueWrapper(propValue, exec);
+
+               JSObjectCallBacks callBacks;
+               GetJSObectCallBacks(callBacks);
+               result = JSObjectCreateInternal(wrapperValue, &callBacks, JSValueWrapper::JSObjectMark, kJSUserObjectDataTypeJSValueWrapper);
+
+               if (!result)
+               {
+                       delete wrapperValue;
+               }
+       }
+       return result;
+}
+
+void JSValueWrapper::JSObjectSetProperty(void* data, CFStringRef propertyName, JSObjectRef jsValue)
+{
+       JSValueWrapper* ptr = (JSValueWrapper*)data;
+       if (ptr)
+       {
+               ExecState* exec = ptr->GetExecState();  
+               Value value = JSObjectKJSValue((JSUserObject*)jsValue);
+#if JAG_PINK_OR_LATER
+               Object objValue = ptr->GetValue().toObject(exec);
+               objValue.put(exec, CFStringToIdentifier(propertyName), value);
+#else
+               Object objValue = ptr->GetValue().imp()->toObject(exec);
+               objValue.put(exec, CFStringToUString(propertyName), value);
+#endif
+       }
+}
+
+JSObjectRef JSValueWrapper::JSObjectCallFunction(void* data, JSObjectRef thisObj, CFArrayRef args)
+{
+       JSObjectRef result = NULL;
+       JSValueWrapper* ptr = (JSValueWrapper*)data;
+       if (ptr)
+       {
+               ExecState* exec = ptr->GetExecState();  
+       
+               Value value = JSObjectKJSValue((JSUserObject*)thisObj);
+#if JAG_PINK_OR_LATER
+               Object ksjThisObj = value.toObject(exec);
+               Object objValue = ptr->GetValue().toObject(exec);
+#else
+               Object ksjThisObj = value.imp()->toObject(exec);
+               Object objValue = ptr->GetValue().imp()->toObject(exec);
+#endif
+
+               List listArgs;
+               CFIndex argCount = args ? CFArrayGetCount(args) : 0;
+               for (CFIndex i = 0; i < argCount; i++)
+               {
+                       JSObjectRef jsArg = (JSObjectRef)CFArrayGetValueAtIndex(args, i);
+                       Value kgsArg = JSObjectKJSValue((JSUserObject*)jsArg);
+                       listArgs.append(kgsArg);
+               }
+
+               Value resultValue = objValue.call(exec, ksjThisObj, listArgs);
+               JSValueWrapper* wrapperValue = new JSValueWrapper(resultValue, ptr->GetExecState());
+               JSObjectCallBacks callBacks;
+               GetJSObectCallBacks(callBacks);
+               result = JSObjectCreate(wrapperValue, &callBacks);
+               if (!result)
+               {
+                       delete wrapperValue;
+               }
+       }
+       return result;
+}
+
+CFTypeRef JSValueWrapper::JSObjectCopyCFValue(void* data)
+{
+       CFTypeRef result = NULL;
+       JSValueWrapper* ptr = (JSValueWrapper*)data;
+       if (ptr)
+       {
+               result = KJSValueToCFType(ptr->fValue, ptr->fExec);
+       }
+       return result;
+}
+
+void JSValueWrapper::JSObjectMark(void* data)
+{
+       JSValueWrapper* ptr = (JSValueWrapper*)data;
+       if (ptr)
+       {
+               ptr->fValue.imp()->mark();
+       }
+}
diff --git a/JavaScriptGlue/JSValueWrapper.h b/JavaScriptGlue/JSValueWrapper.h
new file mode 100644 (file)
index 0000000..6ce469e
--- /dev/null
@@ -0,0 +1,36 @@
+#ifndef __JSValueWrapper_h
+#define __JSValueWrapper_h
+
+/*
+       JSValueWrapper.h
+*/
+
+#include "JSUtils.h"
+#include "JSBase.h"
+#include "JSObject.h"
+
+class JSValueWrapper {
+       public:
+               JSValueWrapper(const Value& inValue, ExecState *inExec);
+               virtual ~JSValueWrapper();
+
+               Value& GetValue();
+               ExecState* GetExecState() const;
+       
+               ProtectedValue fValue;
+               ExecState* fExec;
+
+               static void GetJSObectCallBacks(JSObjectCallBacks& callBacks);
+                       
+       private:
+               static void JSObjectDispose(void* data);
+               static CFArrayRef JSObjectCopyPropertyNames(void* data);
+               static JSObjectRef JSObjectCopyProperty(void* data, CFStringRef propertyName);
+               static void JSObjectSetProperty(void* data, CFStringRef propertyName, JSObjectRef jsValue);
+               static JSObjectRef JSObjectCallFunction(void* data, JSObjectRef thisObj, CFArrayRef args);
+               static CFTypeRef JSObjectCopyCFValue(void* data);
+               static void JSObjectMark(void* data);
+};
+
+
+#endif
\ No newline at end of file
diff --git a/JavaScriptGlue/JavaScriptGlue.cpp b/JavaScriptGlue/JavaScriptGlue.cpp
new file mode 100644 (file)
index 0000000..8900704
--- /dev/null
@@ -0,0 +1,642 @@
+/*
+       JSGlue.cpp
+*/
+
+#include "JavaScriptGlue.h"
+#include "JSUtils.h"
+#include "JSBase.h"
+#include "JSObject.h"
+#include "JSRun.h"
+
+static CFTypeRef sJSCFNullRef = NULL;
+
+static void CFJSObjectDispose(void* data);
+static JSObjectRef CFJSObjectCopyProperty(void* data, CFStringRef propertyName);
+static void CFJSObjectSetProperty(void* data, CFStringRef propertyName, JSObjectRef jsValue);
+static CFTypeRef CFJSObjectCopyCFValue(void* data);
+static UInt8 CFJSObjectEqual(void* data1, void* data2);
+static CFArrayRef CFJSObjectCopyPropertyNames(void* data);
+
+void* JSCFRetain(CFAllocatorRef allocator, const void *value);
+void JSCFRelease(CFAllocatorRef allocator, const void *value);
+
+
+void JSSetCFNull(CFTypeRef nullRef)
+{
+       ReleaseCFType(sJSCFNullRef);
+       sJSCFNullRef = RetainCFType(nullRef);
+}
+
+CFTypeRef JSGetCFNull(void)
+{
+       return sJSCFNullRef;
+}
+
+/*
+       JSRetain
+*/
+JSTypeRef JSRetain(JSTypeRef ref)
+{
+       if (ref)
+       {
+               JSBase* ptr = (JSBase*)ref;
+               ptr->Retain();
+       }
+       return ref;
+}
+
+/*
+       JSRelease
+*/
+void JSRelease(JSTypeRef ref)
+{
+       if (ref)
+       {
+               JSBase* ptr = (JSBase*)ref;
+               ptr->Release();
+       }
+}
+
+/*
+       JSCopyDescription
+*/
+CFStringRef    JSCopyDescription(JSTypeRef ref)
+{
+       CFStringRef result = NULL;
+       if (ref)
+       {
+               JSBase* ptr = (JSBase*)ref;
+               ptr->CopyDescription();
+       }
+       return result;
+}
+
+/*
+       JSEqual
+*/
+UInt8  JSEqual(JSTypeRef ref1, JSTypeRef ref2)
+{
+       UInt8 result = false;
+       if (ref1 && ref2)
+       {
+               JSBase* ptr = (JSBase*)ref1;
+               result = ptr->Equal((JSBase*)ref2);
+       }
+       return result;
+}
+
+
+/*
+       JSGetTypeID
+*/
+JSTypeID JSGetTypeID(JSTypeRef ref)
+{
+       JSTypeID result = kJSInvalidTypeID;
+       if (ref)
+       {
+               JSBase* ptr = (JSBase*)ref;
+               result = ptr->GetTypeID();
+       }
+       return result;
+}
+
+
+/*
+       JSGetRetainCount
+*/
+CFIndex JSGetRetainCount(JSTypeRef ref)
+{
+       CFIndex result = -1;
+       if (ref)
+       {
+               JSBase* ptr = (JSBase*)ref;
+               result = ptr->RetainCount();
+       }
+       return result;
+}
+
+
+
+/*
+       JSObjectCreate
+*/
+JSObjectRef JSObjectCreate(void* data, JSObjectCallBacksPtr callBacks)
+{
+       JSObjectRef result = JSObjectCreateInternal(data, callBacks, NULL, kJSUserObjectDataTypeUnknown);
+       return result;
+}
+
+/*
+       JSObjectCreateInternal
+*/
+JSObjectRef JSObjectCreateInternal(void* data, JSObjectCallBacksPtr callBacks, JSObjectMarkProcPtr markProc, int type)
+{
+       JSObjectRef result = NULL;
+       JSUserObject* ptr = new JSUserObject(callBacks, markProc, data, type);
+       result = (JSObjectRef)ptr;
+       return result;
+}
+
+/*
+       JSObjectCopyCFValue
+*/
+CFTypeRef JSObjectCopyCFValue(JSObjectRef ref)
+{
+       CFTypeRef result = NULL;
+       JSUserObject* ptr = (JSUserObject*)ref;
+       if (ptr && (ptr->GetTypeID() == kJSObjectTypeID))
+       {
+               result = ptr->CopyCFValue();
+       }
+       return result;
+}
+
+/*
+       JSObjectGetData
+*/
+void* JSObjectGetData(JSObjectRef ref)
+{
+       void* result = NULL;
+       JSUserObject* ptr = (JSUserObject*)ref;
+       if (ptr && (ptr->GetTypeID() == kJSObjectTypeID))
+       {
+               result = ptr->GetData();
+       }
+       return result;
+}
+
+
+/*
+       JSObjectCopyProperty
+*/
+JSObjectRef JSObjectCopyProperty(JSObjectRef ref, CFStringRef propertyName)
+{
+       JSObjectRef result = NULL;
+       JSUserObject* ptr = (JSUserObject*)ref;
+       if (ptr && (ptr->GetTypeID() == kJSObjectTypeID))
+       {
+               result = (JSObjectRef)ptr->CopyProperty(propertyName);
+       }
+       return result;
+}
+
+
+/*
+       JSObjectSetProperty
+*/
+void JSObjectSetProperty(JSObjectRef ref, CFStringRef propertyName, JSObjectRef value)
+{
+       JSUserObject* ptr = (JSUserObject*)ref;
+       if (ptr && (ptr->GetTypeID() == kJSObjectTypeID))
+       {
+               ptr->SetProperty(propertyName, (JSUserObject*)value);
+       }
+}
+
+
+/*
+       JSObjectCallFunction
+*/
+JSObjectRef JSObjectCallFunction(JSObjectRef ref, JSObjectRef thisObj, CFArrayRef args)
+{
+       JSObjectRef result = NULL;
+       JSUserObject* ptr = (JSUserObject*)ref;
+       if (ptr && (ptr->GetTypeID() == kJSObjectTypeID))
+       {
+               result = (JSObjectRef)ptr->CallFunction((JSUserObject*)thisObj, args);
+       }
+       return result;
+}
+
+
+/*
+       JSRunCreate
+*/
+JSRunRef JSRunCreate(CFStringRef jsSource, JSFlags inFlags)
+{
+       JSRunRef result = NULL;
+       if (jsSource)
+       {
+               result = (JSRunRef) new JSRun(jsSource, inFlags);
+       }
+       return result;
+}
+
+/*
+       JSRunCopySource
+*/
+CFStringRef JSRunCopySource(JSRunRef ref)
+{
+       CFStringRef result = NULL;
+       JSRun* ptr = (JSRun*)ref;
+       if (ptr)
+       {
+               result = UStringToCFString(ptr->GetSource());
+       }
+       return result;
+}
+
+
+/*
+       JSRunCopyGlobalObject
+*/
+JSObjectRef JSRunCopyGlobalObject(JSRunRef ref)
+{
+       JSObjectRef result = NULL;
+       JSRun* ptr = (JSRun*)ref;
+       if (ptr)
+       {
+               Object globalObject = ptr->GlobalObject();
+               result = (JSObjectRef)KJSValueToJSObject(globalObject, ptr->GetInterpreter()->globalExec());
+       }
+       return result;
+}
+
+/*
+       JSRunEvaluate
+*/
+JSObjectRef JSRunEvaluate(JSRunRef ref)
+{
+       JSObjectRef result = NULL;
+       JSRun* ptr = (JSRun*)ref;
+       if (ptr)
+       {
+               Completion completion = ptr->Evaluate();
+#if JAG_PINK_OR_LATER
+
+               if (completion.isValueCompletion())
+               {
+                       result = (JSObjectRef)KJSValueToJSObject(completion.value(), ptr->GetInterpreter()->globalExec());
+               }
+
+               if (completion.complType() == Throw)    
+               {
+                       JSFlags flags = ptr->Flags();
+                       if (flags & kJSFlagDebug)
+                       {
+                               CFTypeRef error = JSObjectCopyCFValue(result);
+                               if (error)
+                               {
+                                       CFShow(error);
+                                       CFRelease(error);
+                               }
+                       }
+               }
+
+#else
+               result = (JSObjectRef)KJSValueToJSObject(completion, ptr->GetInterpreter()->globalExec());              
+#endif
+       }
+       return result;
+}
+
+/*
+       JSRunCheckSyntax
+       Return true if no syntax error
+*/
+bool JSRunCheckSyntax(JSRunRef ref)
+{
+#if JAG_PINK_OR_LATER
+       bool result = false;
+       JSRun* ptr = (JSRun*)ref;
+       if (ptr)
+       {
+            JSLockInterpreter();
+            result = ptr->CheckSyntax();
+            JSUnlockInterpreter();
+       }
+       return result;
+#else
+       return true;
+#endif
+}
+
+/*
+       JSCollect - trigger garbage collection
+*/
+void JSCollect(void)
+{
+#if JAG_PINK_OR_LATER
+       Interpreter::lock();
+       Collector::collect();
+       Interpreter::unlock(); 
+#endif
+}
+
+/*
+       JSTypeGetCFArrayCallBacks
+*/
+void JSTypeGetCFArrayCallBacks(CFArrayCallBacks* outCallBacks)
+{
+       if (outCallBacks)
+       {
+               outCallBacks->version = 1;
+               outCallBacks->retain = (CFArrayRetainCallBack)JSCFRetain;
+               outCallBacks->release = (CFArrayReleaseCallBack)JSCFRelease;
+               outCallBacks->copyDescription = (CFArrayCopyDescriptionCallBack)JSCopyDescription;
+               outCallBacks->equal = (CFArrayEqualCallBack)JSEqual;
+       }
+}
+
+
+/*
+       JSCFRetain
+*/
+void* JSCFRetain(CFAllocatorRef allocator, const void *value)
+{
+       JSRetain((JSTypeRef)value);
+       return (void*)value;
+}
+
+/*
+       JSCFRelease
+*/
+void JSCFRelease(CFAllocatorRef allocator, const void *value)
+{
+       JSRelease((JSTypeRef)value);
+}
+
+
+/*
+       JSObjectCreateWithCFType
+*/
+JSObjectRef JSObjectCreateWithCFType(CFTypeRef inRef)
+{
+       JSObjectCallBacks callBacks;
+       JSObjectRef cfJSObject = nil;
+       if (inRef)
+       {
+               callBacks.dispose = CFJSObjectDispose;
+               callBacks.equal = CFJSObjectEqual;
+               callBacks.copyCFValue = CFJSObjectCopyCFValue;
+               callBacks.copyProperty = CFJSObjectCopyProperty;
+               callBacks.setProperty = CFJSObjectSetProperty;
+               callBacks.callFunction = NULL;
+               callBacks.copyPropertyNames = CFJSObjectCopyPropertyNames;
+               cfJSObject = JSObjectCreateInternal((void*)CFRetain(inRef), &callBacks, NULL, kJSUserObjectDataTypeCFType );
+       }
+       return cfJSObject;
+}
+
+/*
+       CFJSObjectDispose
+*/
+void CFJSObjectDispose(void* data)
+{
+       if (data)
+       {
+               CFRelease((JSTypeRef)data);
+       }
+}
+
+CFArrayRef JSObjectCopyPropertyNames(JSObjectRef ref)
+{
+       CFArrayRef result = NULL;
+       JSUserObject* ptr = (JSUserObject*)ref;
+       if (ptr && (ptr->GetTypeID() == kJSObjectTypeID))
+       {
+               result = ptr->CopyPropertyNames();
+       }
+       return result;
+}
+/*
+       CFJSObjectCopyProperty
+*/
+JSObjectRef CFJSObjectCopyProperty(void* data, CFStringRef propertyName)
+{
+       JSObjectRef result = NULL;
+       if (data && propertyName)
+       {
+               CFTypeRef cfResult = NULL;
+               if (CFGetTypeID(data) == CFDictionaryGetTypeID())
+               {
+                       if (CFStringCompare(propertyName, CFSTR("length"), 0) == kCFCompareEqualTo)
+                       {
+                               int len = CFDictionaryGetCount((CFDictionaryRef)data);
+                               cfResult = CFNumberCreate(NULL, kCFNumberIntType, &len);
+                       }
+                       else
+                       {
+                               cfResult = RetainCFType(CFDictionaryGetValue((CFDictionaryRef)data, propertyName));
+                       }
+               }
+               else if (CFGetTypeID(data) == CFArrayGetTypeID())
+               {
+                       if (CFStringCompare(propertyName, CFSTR("length"), 0) == kCFCompareEqualTo)
+                       {
+                               int len = CFArrayGetCount((CFArrayRef)data);
+                               cfResult = CFNumberCreate(NULL, kCFNumberIntType, &len);
+                       }
+                       else
+                       {
+                               SInt32 index = CFStringGetIntValue(propertyName);       
+                               CFIndex arrayCount = CFArrayGetCount((CFArrayRef)data);
+                               if (index >= 0 && index < arrayCount)
+                               {
+                                       cfResult = RetainCFType(CFArrayGetValueAtIndex((CFArrayRef)data, index));
+                               }
+                       }
+               }
+               else if (CFGetTypeID(data) == CFStringGetTypeID())
+               {
+                       if (CFStringCompare(propertyName, CFSTR("length"), 0) == kCFCompareEqualTo)
+                       {
+                               int len = CFStringGetLength((CFStringRef)data);
+                               cfResult = CFNumberCreate(NULL, kCFNumberIntType, &len);
+                       }
+               }
+               if (cfResult)
+               {
+                       result = JSObjectCreateWithCFType(cfResult);
+                       CFRelease(cfResult);
+               }
+       }
+       return result;
+}
+
+
+/*
+       CFJSObjectSetProperty
+*/
+void CFJSObjectSetProperty(void* data, CFStringRef propertyName, JSObjectRef jsValue)
+{
+       if (data && propertyName)
+       {
+               CFTypeRef cfValue = JSObjectCopyCFValue(jsValue);
+
+               if (cfValue)
+               {
+                       if (CFGetTypeID(data) == CFDictionaryGetTypeID())
+                       {
+                               CFDictionarySetValue((CFMutableDictionaryRef)data, propertyName, cfValue);
+                       }
+                       else if (CFGetTypeID(data) == CFArrayGetTypeID())
+                       {
+                               SInt32 index = CFStringGetIntValue(propertyName);       
+                               CFIndex arrayCount = CFArrayGetCount((CFArrayRef)data);
+                               if (index >= 0)
+                               {
+                                       for (; arrayCount < index; arrayCount++)
+                                       {
+                                               CFArrayAppendValue((CFMutableArrayRef)data, GetCFNull());
+                                       }
+                                       CFArraySetValueAtIndex((CFMutableArrayRef)data, index, cfValue);                                        
+                               }
+                       }               
+                       CFRelease(cfValue);
+               }
+               else
+               {
+                       if (CFGetTypeID(data) == CFDictionaryGetTypeID())
+                       {
+                               CFDictionaryRemoveValue((CFMutableDictionaryRef)data, propertyName);
+                       }
+                       else if (CFGetTypeID(data) == CFArrayGetTypeID())
+                       {
+                               SInt32 index = CFStringGetIntValue(propertyName);                               
+                               CFIndex arrayCount = CFArrayGetCount((CFArrayRef)data);
+                               if (index >= 0)
+                               {
+                                       for (; arrayCount < index; arrayCount++)
+                                       {
+                                               CFArrayAppendValue((CFMutableArrayRef)data, GetCFNull());
+                                       }
+                                       CFArraySetValueAtIndex((CFMutableArrayRef)data, index, GetCFNull());                                    
+                               }                               
+                       }
+               }
+       }
+}
+
+
+/*
+       CFJSObjectCopyCFValue
+*/
+CFTypeRef CFJSObjectCopyCFValue(void* data)
+{
+       CFTypeRef result = NULL;
+       if (data)
+       {
+               result = (CFTypeRef)CFRetain(data);
+       }
+       return result;
+}
+
+/*
+       CFJSObjectCopyCFValue
+*/
+UInt8 CFJSObjectEqual(void* data1, void* data2)
+{
+       UInt8 result = false;
+       if (data1 && data2)
+       {
+               CFEqual((CFTypeRef)data1, (CFTypeRef)data2);
+       }
+       return result;
+}
+
+
+/*
+       CFJSObjectCopyPropertyNames
+*/
+CFArrayRef CFJSObjectCopyPropertyNames(void* data)
+{
+       CFMutableArrayRef result = NULL;
+       if (data)
+       {
+               CFTypeID cfType = CFGetTypeID(data);
+               if (cfType == CFDictionaryGetTypeID())
+               {
+                       CFIndex count = CFDictionaryGetCount((CFDictionaryRef)data);
+                       if (count)
+                       {
+                               CFTypeRef* keys = (CFTypeRef*)malloc(sizeof(CFTypeRef)*count);
+                               if (keys)
+                               {
+                                       int i;
+                                       CFDictionaryGetKeysAndValues((CFDictionaryRef)data, (const void **)keys, NULL);
+                                       for (i = 0; i < count; i++)
+                                       {
+                                               CFStringRef key = (CFStringRef)keys[i];
+                                               if (CFGetTypeID(key) != CFStringGetTypeID()) continue;
+
+                                               if (!result) result = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+                                               if (!result) continue;
+                                               
+                                               CFArrayAppendValue(result, key);
+                                       }
+                                       free(keys);
+                               }
+                       }
+               }
+       }
+       return result;
+}
+
+
+
+
+CFMutableArrayRef JSCreateCFArrayFromJSArray(CFArrayRef array)
+{
+       CFIndex count = array ? CFArrayGetCount(array) : 0;
+       CFMutableArrayRef cfArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+       CFIndex i;
+
+       for (i = 0; cfArray && i <  count; i++)
+       {
+               JSObjectRef jsValue = (JSObjectRef)CFArrayGetValueAtIndex(array, i);
+               CFTypeRef cfvalue = JSObjectCopyCFValue(jsValue);
+               if (cfvalue)
+               {
+                       CFArrayAppendValue(cfArray, cfvalue);
+                       CFRelease(cfvalue);
+               }
+               else
+               {
+                       CFArrayAppendValue(cfArray, GetCFNull());
+               }
+       }
+       return cfArray;
+}
+
+CFMutableArrayRef JSCreateJSArrayFromCFArray(CFArrayRef array)
+{
+       CFIndex count = array ? CFArrayGetCount(array) : 0;
+       CFArrayCallBacks arrayCallbacks;
+       CFMutableArrayRef jsArray;
+       CFIndex i;
+
+       JSTypeGetCFArrayCallBacks(&arrayCallbacks);
+       jsArray = CFArrayCreateMutable(NULL, 0, &arrayCallbacks);
+
+       for (i = 0; array && i <  count; i++)
+       {
+               CFTypeRef cfValue = (CFTypeRef)CFArrayGetValueAtIndex(array, i);
+               JSObjectRef jsValue = JSObjectCreateWithCFType(cfValue);
+               
+               if (!jsValue) jsValue = JSObjectCreateWithCFType(GetCFNull());
+               if (jsValue)
+               {
+                       CFArrayAppendValue(jsArray, jsValue);
+                       JSRelease(jsValue);
+               }
+       }
+       return jsArray;
+}
+
+
+void JSLockInterpreter()
+{
+#if JAG_PINK_OR_LATER
+       Interpreter::lock();
+#endif
+}
+
+
+void JSUnlockInterpreter()
+{
+#if JAG_PINK_OR_LATER
+       Interpreter::unlock();
+#endif
+}
+
diff --git a/JavaScriptGlue/JavaScriptGlue.exp b/JavaScriptGlue/JavaScriptGlue.exp
new file mode 100644 (file)
index 0000000..c33f9d8
--- /dev/null
@@ -0,0 +1,35 @@
+_JSSetCFNull
+_JSGetCFNull
+
+_JSRetain
+_JSRelease
+_JSGetTypeID
+_JSGetRetainCount
+_JSCopyDescription
+_JSEqual
+
+_JSObjectCreate
+_JSObjectCreateWithCFType
+_JSObjectCopyCFValue
+_JSObjectGetData
+
+_JSObjectCopyProperty
+_JSObjectSetProperty
+_JSObjectCallFunction
+_JSObjectCopyPropertyNames
+
+_JSRunCreate
+_JSRunCopySource
+_JSRunCopyGlobalObject
+_JSRunEvaluate
+
+_JSTypeGetCFArrayCallBacks
+
+_JSCreateCFArrayFromJSArray
+_JSCreateJSArrayFromCFArray
+
+_JSRunCheckSyntax
+
+_JSLockInterpreter
+_JSUnlockInterpreter
+_JSCollect
diff --git a/JavaScriptGlue/JavaScriptGlue.h b/JavaScriptGlue/JavaScriptGlue.h
new file mode 100644 (file)
index 0000000..aa396db
--- /dev/null
@@ -0,0 +1,87 @@
+#ifndef __JAVASCRIPTGLUE__
+#define __JAVASCRIPTGLUE__
+
+/*
+       JavaScriptGlue.h
+*/
+
+#ifndef __CORESERVICES__
+#include <CoreServices/CoreServices.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* typedefs/structs */
+typedef enum {
+       kJSFlagNone = 0,
+       kJSFlagDebug = 1 << 0,
+       kJSFlagConvertAssociativeArray = 1 << 1 /* associative arrays will be converted to dictionaries */
+} JSFlags;
+
+typedef struct OpaqueJSTypeRef* JSTypeRef;
+typedef JSTypeRef JSObjectRef;
+typedef JSTypeRef JSRunRef;
+typedef UInt32 JSTypeID;
+
+typedef void (*JSObjectDisposeProcPtr)(void* data);
+typedef CFArrayRef (*JSObjectCopyPropertyNamesProcPtr)(void* data);
+typedef JSObjectRef (*JSObjectCopyPropertyProcPtr)(void* data, CFStringRef propertyName);
+typedef void (*JSObjectSetPropertyProcPtr)(void* data, CFStringRef propertyName, JSObjectRef jsValue);
+typedef JSObjectRef (*JSObjectCallFunctionProcPtr)(void* data, JSObjectRef thisObj, CFArrayRef args);
+typedef CFTypeRef (*JSObjectCopyCFValueProcPtr)(void* data);
+typedef UInt8 (*JSObjectEqualProcPtr)(void* data1, void* data2);
+
+struct JSObjectCallBacks {
+       JSObjectDisposeProcPtr dispose;
+       JSObjectEqualProcPtr equal;
+       JSObjectCopyCFValueProcPtr copyCFValue;
+       JSObjectCopyPropertyProcPtr copyProperty;
+       JSObjectSetPropertyProcPtr setProperty;
+       JSObjectCallFunctionProcPtr callFunction;
+       JSObjectCopyPropertyNamesProcPtr copyPropertyNames;
+};
+typedef struct JSObjectCallBacks JSObjectCallBacks, *JSObjectCallBacksPtr;
+
+void JSSetCFNull(CFTypeRef nullRef);
+CFTypeRef JSGetCFNull(void);
+
+JSTypeRef JSRetain(JSTypeRef ref);
+void JSRelease(JSTypeRef ref);
+JSTypeID JSGetTypeID(JSTypeRef ref);
+CFIndex JSGetRetainCount(JSTypeRef ref);
+CFStringRef    JSCopyDescription(JSTypeRef ref);
+UInt8 JSEqual(JSTypeRef ref1, JSTypeRef ref2);
+
+JSObjectRef JSObjectCreate(void* data, JSObjectCallBacksPtr callBacks);
+JSObjectRef JSObjectCreateWithCFType(CFTypeRef inRef);
+CFTypeRef JSObjectCopyCFValue(JSObjectRef ref);
+void* JSObjectGetData(JSObjectRef ref);
+
+CFArrayRef JSObjectCopyPropertyNames(JSObjectRef ref);
+JSObjectRef JSObjectCopyProperty(JSObjectRef ref, CFStringRef propertyName);
+void JSObjectSetProperty(JSObjectRef ref, CFStringRef propertyName, JSObjectRef value);
+JSObjectRef JSObjectCallFunction(JSObjectRef ref, JSObjectRef thisObj, CFArrayRef args);
+
+JSRunRef JSRunCreate(CFStringRef jsSource, JSFlags inFlags);
+CFStringRef JSRunCopySource(JSRunRef ref);
+JSObjectRef JSRunCopyGlobalObject(JSRunRef ref);
+JSObjectRef JSRunEvaluate(JSRunRef ref);
+bool JSRunCheckSyntax(JSRunRef ref);
+
+void JSCollect(void);
+
+void JSTypeGetCFArrayCallBacks(CFArrayCallBacks* outCallBacks);
+
+CFMutableArrayRef JSCreateCFArrayFromJSArray(CFArrayRef array); 
+CFMutableArrayRef JSCreateJSArrayFromCFArray(CFArrayRef array);
+
+void JSLockInterpreter();
+void JSUnlockInterpreter();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/JavaScriptGlue/JavaScriptGlue.pbproj/project.pbxproj b/JavaScriptGlue/JavaScriptGlue.pbproj/project.pbxproj
new file mode 100644 (file)
index 0000000..492ed8a
--- /dev/null
@@ -0,0 +1,578 @@
+// !$*UTF8*$!
+{
+       archiveVersion = 1;
+       classes = {
+       };
+       objectVersion = 39;
+       objects = {
+               014CEA440018CDF011CA2923 = {
+                       buildSettings = {
+                               COPY_PHASE_STRIP = NO;
+                               GCC_DYNAMIC_NO_PIC = NO;
+                               GCC_ENABLE_FIX_AND_CONTINUE = YES;
+                               GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+                               GCC_OPTIMIZATION_LEVEL = 0;
+                               OPTIMIZATION_CFLAGS = "-O0";
+                               ZERO_LINK = YES;
+                       };
+                       isa = PBXBuildStyle;
+                       name = Development;
+               };
+               014CEA450018CDF011CA2923 = {
+                       buildSettings = {
+                               COPY_PHASE_STRIP = YES;
+                               GCC_ENABLE_FIX_AND_CONTINUE = NO;
+                               ZERO_LINK = NO;
+                       };
+                       isa = PBXBuildStyle;
+                       name = Deployment;
+               };
+//010
+//011
+//012
+//013
+//014
+//030
+//031
+//032
+//033
+//034
+               034768DFFF38A50411DB9C8B = {
+                       children = (
+                               8CBD4F2A074D303A00719ADA,
+                       );
+                       isa = PBXGroup;
+                       name = Products;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+//030
+//031
+//032
+//033
+//034
+//080
+//081
+//082
+//083
+//084
+               0867D690FE84028FC02AAC07 = {
+                       buildSettings = {
+                       };
+                       buildStyles = (
+                               014CEA440018CDF011CA2923,
+                               014CEA450018CDF011CA2923,
+                       );
+                       hasScannedForEncodings = 1;
+                       isa = PBXProject;
+                       mainGroup = 0867D691FE84028FC02AAC07;
+                       productRefGroup = 034768DFFF38A50411DB9C8B;
+                       projectDirPath = "";
+                       targets = (
+                               0867D69CFE84028FC02AAC07,
+                       );
+               };
+               0867D691FE84028FC02AAC07 = {
+                       children = (
+                               08FB77AEFE84172EC02AAC07,
+                               089C1665FE841158C02AAC07,
+                               0867D69AFE84028FC02AAC07,
+                               034768DFFF38A50411DB9C8B,
+                       );
+                       isa = PBXGroup;
+                       name = JavaScriptGlue;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               0867D69AFE84028FC02AAC07 = {
+                       children = (
+                               1058C7B0FEA5585E11CA2CBB,
+                               1058C7B2FEA5585E11CA2CBB,
+                       );
+                       isa = PBXGroup;
+                       name = "External Frameworks and Libraries";
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               0867D69BFE84028FC02AAC07 = {
+                       isa = PBXFileReference;
+                       lastKnownFileType = wrapper.framework;
+                       name = Foundation.framework;
+                       path = /System/Library/Frameworks/Foundation.framework;
+                       refType = 0;
+                       sourceTree = "<absolute>";
+               };
+               0867D69CFE84028FC02AAC07 = {
+                       buildPhases = (
+                               0867D69DFE84028FC02AAC07,
+                               0867D69EFE84028FC02AAC07,
+                               0867D69FFE84028FC02AAC07,
+                               0867D6A0FE84028FC02AAC07,
+                               0867D6A2FE84028FC02AAC07,
+                       );
+                       buildSettings = {
+                               DYLIB_COMPATIBILITY_VERSION = 1;
+                               DYLIB_CURRENT_VERSION = 1;
+                               EXPORTED_SYMBOLS_FILE = JavaScriptGlue.exp;
+                               FRAMEWORK_SEARCH_PATHS = "\"$(SYSTEM_LIBRARY_DIR)/Frameworks/WebKit.framework/Frameworks\" \"$(SYSTEM_LIBRARY_DIR)/Frameworks/WebKit.framework/Versions/A/Frameworks\"";
+                               FRAMEWORK_VERSION = A;
+                               HEADER_SEARCH_PATHS = "";
+                               INSTALL_PATH = "$(NEXT_ROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks";
+                               LIBRARY_SEARCH_PATHS = "";
+                               OTHER_CFLAGS = "";
+                               OTHER_LDFLAGS = "";
+                               PRODUCT_NAME = JavaScriptGlue;
+                               SECTORDER_FLAGS = "-sectorder __TEXT __text \"$(APPLE_INTERNAL_DIR)/OrderFiles/JavaScriptGlue.order\"";
+                               WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+                               WRAPPER_EXTENSION = framework;
+                       };
+                       dependencies = (
+                       );
+                       isa = PBXFrameworkTarget;
+                       name = JavaScriptGlue;
+                       productInstallPath = "$(NEXT_ROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks";
+                       productName = JavaScriptGlue;
+                       productReference = 8CBD4F2A074D303A00719ADA;
+                       productSettingsXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
+<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">
+<plist version=\"1.0\">
+<dict>
+       <key>CFBundleDevelopmentRegion</key>
+       <string>English</string>
+       <key>CFBundleExecutable</key>
+       <string>JavaScriptGlue</string>
+       <key>CFBundleGetInfoString</key>
+       <string>JavaScriptGlue version 1.1.0, Copyright 2004, Apple Computer Inc.</string>
+       <key>CFBundleIconFile</key>
+       <string></string>
+       <key>CFBundleIdentifier</key>
+       <string>com.apple.JavaScriptGlue</string>
+       <key>CFBundleInfoDictionaryVersion</key>
+       <string>6.0</string>
+       <key>CFBundlePackageType</key>
+       <string>FMWK</string>
+       <key>CFBundleShortVersionString</key>
+       <string>1.1.0</string>
+       <key>CFBundleSignature</key>
+       <string>????</string>
+       <key>CFBundleVersion</key>
+       <string>1.1.0</string>
+       <key>NSPrincipalClass</key>
+       <string></string>
+</dict>
+</plist>
+";
+               };
+               0867D69DFE84028FC02AAC07 = {
+                       buildActionMask = 2147483647;
+                       files = (
+                               F11798B40262465703CA149D,
+                               F11798BE026246FD03CA149D,
+                               F11798BF026246FD03CA149D,
+                               F11798C0026246FD03CA149D,
+                               F11798C1026246FD03CA149D,
+                               F11798CB0262545403CA149D,
+                               F11798D00262579C03CA149D,
+                       );
+                       isa = PBXHeadersBuildPhase;
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               0867D69EFE84028FC02AAC07 = {
+                       buildActionMask = 2147483647;
+                       files = (
+                               089C1668FE841158C02AAC07,
+                       );
+                       isa = PBXResourcesBuildPhase;
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               0867D69FFE84028FC02AAC07 = {
+                       buildActionMask = 2147483647;
+                       files = (
+                               F1EB7EAC02621EAF03CA149D,
+                               F11798B50262465703CA149D,
+                               F11798C2026246FD03CA149D,
+                               F11798C3026246FD03CA149D,
+                               F11798C4026246FD03CA149D,
+                               F11798C5026246FD03CA149D,
+                               F11798CD0262545403CA149D,
+                               F11798D10262579C03CA149D,
+                       );
+                       isa = PBXSourcesBuildPhase;
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               0867D6A0FE84028FC02AAC07 = {
+                       buildActionMask = 2147483647;
+                       files = (
+                               F14FC9F40258E9A603CA149D,
+                               8C6C2BBA04E05AD30031EC3B,
+                       );
+                       isa = PBXFrameworksBuildPhase;
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               0867D6A2FE84028FC02AAC07 = {
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       isa = PBXRezBuildPhase;
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               0867D6A5FE840307C02AAC07 = {
+                       isa = PBXFileReference;
+                       lastKnownFileType = wrapper.framework;
+                       name = AppKit.framework;
+                       path = /System/Library/Frameworks/AppKit.framework;
+                       refType = 0;
+                       sourceTree = "<absolute>";
+               };
+               089C1665FE841158C02AAC07 = {
+                       children = (
+                               089C1666FE841158C02AAC07,
+                       );
+                       isa = PBXGroup;
+                       name = Resources;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               089C1666FE841158C02AAC07 = {
+                       children = (
+                               089C1667FE841158C02AAC07,
+                       );
+                       isa = PBXVariantGroup;
+                       name = InfoPlist.strings;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               089C1667FE841158C02AAC07 = {
+                       fileEncoding = 10;
+                       isa = PBXFileReference;
+                       lastKnownFileType = text.plist.strings;
+                       name = English;
+                       path = English.lproj/InfoPlist.strings;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               089C1668FE841158C02AAC07 = {
+                       fileRef = 089C1666FE841158C02AAC07;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               08FB77AEFE84172EC02AAC07 = {
+                       children = (
+                               F1EB7EAB02621EAF03CA149D,
+                               F11798B20262465703CA149D,
+                               F11798B30262465703CA149D,
+                               F11798B8026246FD03CA149D,
+                               F11798B9026246FD03CA149D,
+                               F11798BA026246FD03CA149D,
+                               F11798BB026246FD03CA149D,
+                               F11798BC026246FD03CA149D,
+                               F11798BD026246FD03CA149D,
+                               F11798B6026246FD03CA149D,
+                               F11798B7026246FD03CA149D,
+                               F11798C80262545403CA149D,
+                               F11798C90262545403CA149D,
+                               F11798CE0262579C03CA149D,
+                               F11798CF0262579C03CA149D,
+                       );
+                       isa = PBXGroup;
+                       name = Classes;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+//080
+//081
+//082
+//083
+//084
+//100
+//101
+//102
+//103
+//104
+               1058C7B0FEA5585E11CA2CBB = {
+                       children = (
+                               F14FC9F30258E9A603CA149D,
+                               8C6C2BB904E05AD30031EC3B,
+                               8C7C00A6046B01F1002EB936,
+                       );
+                       isa = PBXGroup;
+                       name = "Linked Frameworks";
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               1058C7B2FEA5585E11CA2CBB = {
+                       children = (
+                               0867D69BFE84028FC02AAC07,
+                               0867D6A5FE840307C02AAC07,
+                       );
+                       isa = PBXGroup;
+                       name = "Other Frameworks";
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+//100
+//101
+//102
+//103
+//104
+//8C0
+//8C1
+//8C2
+//8C3
+//8C4
+               8C6C2BB904E05AD30031EC3B = {
+                       isa = PBXFileReference;
+                       lastKnownFileType = wrapper.framework;
+                       name = JavaScriptCore.framework;
+                       path = /System/Library/Frameworks/WebKit.framework/Versions/A/Frameworks/JavaScriptCore.framework;
+                       refType = 0;
+                       sourceTree = "<absolute>";
+               };
+               8C6C2BBA04E05AD30031EC3B = {
+                       fileRef = 8C6C2BB904E05AD30031EC3B;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               8C7C00A6046B01F1002EB936 = {
+                       isa = PBXFileReference;
+                       lastKnownFileType = wrapper.framework;
+                       name = WebKit.framework;
+                       path = /System/Library/Frameworks/WebKit.framework;
+                       refType = 0;
+                       sourceTree = "<absolute>";
+               };
+               8CBD4F2A074D303A00719ADA = {
+                       explicitFileType = wrapper.framework;
+                       includeInIndex = 0;
+                       isa = PBXFileReference;
+                       path = JavaScriptGlue.framework;
+                       refType = 3;
+                       sourceTree = BUILT_PRODUCTS_DIR;
+               };
+//8C0
+//8C1
+//8C2
+//8C3
+//8C4
+//F10
+//F11
+//F12
+//F13
+//F14
+               F11798B20262465703CA149D = {
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.cpp.cpp;
+                       path = JavaScriptGlue.cpp;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               F11798B30262465703CA149D = {
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       path = JavaScriptGlue.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               F11798B40262465703CA149D = {
+                       fileRef = F11798B30262465703CA149D;
+                       isa = PBXBuildFile;
+                       settings = {
+                               ATTRIBUTES = (
+                                       Public,
+                               );
+                       };
+               };
+               F11798B50262465703CA149D = {
+                       fileRef = F11798B20262465703CA149D;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               F11798B6026246FD03CA149D = {
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.cpp.cpp;
+                       path = JSUtils.cpp;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               F11798B7026246FD03CA149D = {
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       path = JSUtils.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               F11798B8026246FD03CA149D = {
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.cpp.cpp;
+                       path = JSBase.cpp;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               F11798B9026246FD03CA149D = {
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       path = JSBase.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               F11798BA026246FD03CA149D = {
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.cpp.cpp;
+                       path = JSObject.cpp;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               F11798BB026246FD03CA149D = {
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       path = JSObject.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               F11798BC026246FD03CA149D = {
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.cpp.cpp;
+                       path = JSRun.cpp;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               F11798BD026246FD03CA149D = {
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       path = JSRun.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               F11798BE026246FD03CA149D = {
+                       fileRef = F11798B9026246FD03CA149D;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               F11798BF026246FD03CA149D = {
+                       fileRef = F11798B7026246FD03CA149D;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               F11798C0026246FD03CA149D = {
+                       fileRef = F11798BB026246FD03CA149D;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               F11798C1026246FD03CA149D = {
+                       fileRef = F11798BD026246FD03CA149D;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               F11798C2026246FD03CA149D = {
+                       fileRef = F11798BC026246FD03CA149D;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               F11798C3026246FD03CA149D = {
+                       fileRef = F11798B6026246FD03CA149D;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               F11798C4026246FD03CA149D = {
+                       fileRef = F11798B8026246FD03CA149D;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               F11798C5026246FD03CA149D = {
+                       fileRef = F11798BA026246FD03CA149D;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               F11798C80262545403CA149D = {
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.cpp.cpp;
+                       path = JSValueWrapper.cpp;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               F11798C90262545403CA149D = {
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       path = JSValueWrapper.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               F11798CB0262545403CA149D = {
+                       fileRef = F11798C90262545403CA149D;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               F11798CD0262545403CA149D = {
+                       fileRef = F11798C80262545403CA149D;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               F11798CE0262579C03CA149D = {
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.cpp.cpp;
+                       path = UserObjectImp.cpp;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               F11798CF0262579C03CA149D = {
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       path = UserObjectImp.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               F11798D00262579C03CA149D = {
+                       fileRef = F11798CF0262579C03CA149D;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               F11798D10262579C03CA149D = {
+                       fileRef = F11798CE0262579C03CA149D;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               F14FC9F30258E9A603CA149D = {
+                       isa = PBXFileReference;
+                       lastKnownFileType = wrapper.framework;
+                       name = CoreServices.framework;
+                       path = /System/Library/Frameworks/CoreServices.framework;
+                       refType = 0;
+                       sourceTree = "<absolute>";
+               };
+               F14FC9F40258E9A603CA149D = {
+                       fileRef = F14FC9F30258E9A603CA149D;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               F1EB7EAB02621EAF03CA149D = {
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.exports;
+                       path = JavaScriptGlue.exp;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               F1EB7EAC02621EAF03CA149D = {
+                       fileRef = F1EB7EAB02621EAF03CA149D;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+       };
+       rootObject = 0867D690FE84028FC02AAC07;
+}
diff --git a/JavaScriptGlue/UserObjectImp.cpp b/JavaScriptGlue/UserObjectImp.cpp
new file mode 100644 (file)
index 0000000..224d9a5
--- /dev/null
@@ -0,0 +1,488 @@
+#include "UserObjectImp.h"
+
+const ClassInfo UserObjectImp::info = {"UserObject", 0, 0, 0};
+
+class UserObjectPrototypeImp : public UserObjectImp {
+  public:
+    UserObjectPrototypeImp();
+       static UserObjectPrototypeImp* GlobalUserObjectPrototypeImp();
+  private:
+       static UserObjectPrototypeImp* sUserObjectPrototypeImp;
+};
+
+UserObjectPrototypeImp* UserObjectPrototypeImp::sUserObjectPrototypeImp = NULL;
+
+UserObjectPrototypeImp::UserObjectPrototypeImp()
+  : UserObjectImp()
+{
+}
+
+UserObjectPrototypeImp* UserObjectPrototypeImp::GlobalUserObjectPrototypeImp()
+{
+       if (!sUserObjectPrototypeImp)
+       {
+               sUserObjectPrototypeImp = new UserObjectPrototypeImp();
+               static ProtectedValue protectPrototype = Value(sUserObjectPrototypeImp);
+       }
+       return sUserObjectPrototypeImp;
+}
+
+
+UserObjectImp::UserObjectImp(): ObjectImp(), fJSUserObject(NULL)
+{
+}
+
+UserObjectImp::UserObjectImp(JSUserObject* userObject) : 
+       ObjectImp(Object(UserObjectPrototypeImp::GlobalUserObjectPrototypeImp())), 
+       fJSUserObject((JSUserObject*)userObject->Retain()) 
+{ 
+}
+
+UserObjectImp::~UserObjectImp() 
+{
+       if (fJSUserObject)
+       {
+               fJSUserObject->Release(); 
+       }
+}
+    
+const ClassInfo        * UserObjectImp::classInfo() const 
+{
+       return &info; 
+}
+        
+bool   UserObjectImp::implementsCall() const 
+{
+       return fJSUserObject ? fJSUserObject->ImplementsCall() : false; 
+}
+
+Value  UserObjectImp::call(ExecState *exec, Object &thisObj, const List &args)
+{
+       Value result = Undefined();
+       JSUserObject* jsThisObj = KJSValueToJSObject(thisObj, exec);
+       if (jsThisObj)
+       {
+               CFIndex argCount = args.size();
+               CFArrayCallBacks arrayCallBacks;
+               JSTypeGetCFArrayCallBacks(&arrayCallBacks);
+               CFMutableArrayRef jsArgs = CFArrayCreateMutable(NULL, 0, &arrayCallBacks);
+               if (jsArgs)
+               {
+                       for (CFIndex i = 0; i < argCount;  i++)
+                       {
+                               JSUserObject* jsArg = KJSValueToJSObject(args[i], exec);
+                               CFArrayAppendValue(jsArgs, (void*)jsArg);
+                               jsArg->Release();
+                       }
+               }
+
+#if 0
+               JSUserObject* jsResult = fJSUserObject->CallFunction(jsThisObj, jsArgs);
+#else
+               int lockCount = Interpreter::lockCount();
+               int i;
+               for (i = 0; i < lockCount; i++)
+               {
+                       Interpreter::unlock();
+               }
+
+               JSUserObject* jsResult = fJSUserObject->CallFunction(jsThisObj, jsArgs);
+
+               for (i = 0; i < lockCount; i++)
+               {
+                       Interpreter::lock();
+               }
+#endif
+               if (jsResult)
+               {
+                       result = JSObjectKJSValue(jsResult);
+                       jsResult->Release();
+               }
+
+               ReleaseCFType(jsArgs);
+               jsThisObj->Release();
+       }
+       return result;
+}
+
+
+ReferenceList UserObjectImp::propList(ExecState *exec, bool recursive)
+{
+       ReferenceList propList;
+       JSUserObject* ptr = GetJSUserObject();
+       if (ptr)
+       {
+               Object theObject = toObject(exec);
+               CFArrayRef propertyNames = ptr->CopyPropertyNames();
+               if (propertyNames)
+               {
+                       CFIndex count = CFArrayGetCount(propertyNames);
+                       CFIndex i;
+                       for (i = 0; i < count; i++)
+                       {
+                               CFStringRef propertyName = (CFStringRef)CFArrayGetValueAtIndex(propertyNames, i);
+                               propList.append(Reference(theObject, CFStringToIdentifier(propertyName)));
+                       }
+                       CFRelease(propertyNames);
+               }
+       }
+       return propList;
+}
+
+bool UserObjectImp::hasProperty(ExecState *exec, const Identifier &propertyName) const
+{
+       Value prop = get(exec, propertyName);
+       if (prop.type() != UndefinedType)
+       {
+               return true;
+       }
+       return ObjectImp::hasProperty(exec, propertyName);
+}
+
+#if JAG_PINK_OR_LATER
+Value  UserObjectImp::get(ExecState *exec, const Identifier &propertyName) const
+{
+       Value result = Undefined();
+       CFStringRef     cfPropName = IdentifierToCFString(propertyName);
+       JSUserObject* jsResult = fJSUserObject->CopyProperty(cfPropName);
+       if (jsResult)
+       {
+               result = JSObjectKJSValue(jsResult);
+               jsResult->Release();
+       }
+       else
+       {
+               Value kjsValue = toPrimitive(exec);
+               if (kjsValue.type() != NullType && kjsValue.type() != UndefinedType)
+               {
+                       Object kjsObject = kjsValue.toObject(exec);
+                       Value kjsObjectProp = kjsObject.get(exec, propertyName);
+                       result = kjsObjectProp;
+               }
+       }
+       ReleaseCFType(cfPropName);
+       return result;
+
+}
+
+void   UserObjectImp::put(ExecState *exec, const Identifier &propertyName, const Value &value, int attr)
+{
+       CFStringRef     cfPropName = IdentifierToCFString(propertyName);
+       JSUserObject* jsValueObj = KJSValueToJSObject(value, exec);
+
+       fJSUserObject->SetProperty(cfPropName, jsValueObj);
+
+       if (jsValueObj) jsValueObj->Release();  
+       ReleaseCFType(cfPropName);
+}
+#else  //JAG_PINK_OR_LATER
+Value  UserObjectImp::get(ExecState* exec, const UString& propertyName) const
+{
+       Value result = Undefined();
+       CFStringRef     cfPropName = UStringToCFString(propertyName);
+       JSUserObject* jsResult = fJSUserObject->CopyProperty(cfPropName);
+       if (jsResult)
+       {
+               result = JSObjectKJSValue(jsResult);
+               jsResult->Release();
+       }
+       else
+       {
+               Value kjsValue = toPrimitive(exec);
+               if (kjsValue != Null() && kjsValue != Undefined())
+               {
+                       Object kjsObject = kjsValue.toObject(exec);
+                       Value kjsObjectProp = kjsObject.get(exec, propertyName);
+                       result = kjsObjectProp;
+               }
+       }
+       ReleaseCFType(cfPropName);
+       return result;
+
+}
+
+void   UserObjectImp::put(ExecState* exec, const UString& propertyName, const Value& value, int attr)
+{
+       CFStringRef     cfPropName = UStringToCFString(propertyName);
+       JSUserObject* jsValueObj = KJSValueToJSObject(value, exec);
+
+       fJSUserObject->SetProperty(cfPropName, jsValueObj);
+
+       if (jsValueObj) jsValueObj->Release();  
+       ReleaseCFType(cfPropName);
+}
+#endif //JAG_PINK_OR_LATER
+        
+JSUserObject* UserObjectImp::GetJSUserObject() const 
+{ 
+       return fJSUserObject; 
+}
+
+
+
+Value UserObjectImp::toPrimitive(ExecState *exec, Type preferredType) const
+{
+       Value result = Undefined();
+       JSUserObject* jsObjPtr = KJSValueToJSObject(toObject(exec), exec);
+       CFTypeRef cfValue = jsObjPtr ? jsObjPtr->CopyCFValue() : NULL;
+       if (cfValue)
+       {
+               CFTypeID cfType = CFGetTypeID(cfValue);  // toPrimitive
+               if (cfValue == GetCFNull())
+               {
+                       result = Null();
+               }
+               else if (cfType == CFBooleanGetTypeID())
+               {
+                       if (cfValue == kCFBooleanTrue)
+                       {
+                               result = KJS::Boolean(true);
+                       }
+                       else 
+                       {
+                               result = KJS::Boolean(false);
+                       }
+               }
+               else if (cfType == CFStringGetTypeID())
+               {
+                       result = KJS::String(CFStringToUString((CFStringRef)cfValue));
+               }
+               else if (cfType == CFNumberGetTypeID())
+               {
+                       double d = 0.0;
+                       CFNumberGetValue((CFNumberRef)cfValue, kCFNumberDoubleType, &d);
+                       result = KJS::Number(d);
+               }
+               else if (cfType == CFURLGetTypeID())
+               {
+                       CFURLRef absURL = CFURLCopyAbsoluteURL((CFURLRef)cfValue);
+                       if (absURL)
+                       {
+                               result = KJS::String(CFStringToUString(CFURLGetString(absURL)));
+                               ReleaseCFType(absURL);
+                       }
+               }               
+               ReleaseCFType(cfValue);
+       }
+       if (jsObjPtr) jsObjPtr->Release();
+       return result;
+}
+
+
+bool UserObjectImp::toBoolean(ExecState *exec) const
+{
+       bool result = false;
+       JSUserObject* jsObjPtr = KJSValueToJSObject(toObject(exec), exec);
+       CFTypeRef cfValue = jsObjPtr ? jsObjPtr->CopyCFValue() : NULL;
+       if (cfValue)
+       {
+               CFTypeID cfType = CFGetTypeID(cfValue);  // toPrimitive
+               if (cfValue == GetCFNull())
+               {
+                       //
+               }
+               else if (cfType == CFBooleanGetTypeID())
+               {
+                       if (cfValue == kCFBooleanTrue)
+                       {
+                               result = true;
+                       }
+               }
+               else if (cfType == CFStringGetTypeID())
+               {
+                       if (CFStringGetLength((CFStringRef)cfValue))
+                       {
+                               result = true;
+                       }
+               }
+               else if (cfType == CFNumberGetTypeID())
+               {
+                       if (cfValue != kCFNumberNaN)
+                       {
+                               double d;
+                               if (CFNumberGetValue((CFNumberRef)cfValue, kCFNumberDoubleType, &d))
+                               {
+                                       if (d != 0)
+                                       {
+                                               result = true;
+                                       }
+                               }
+                       }
+               }
+               else if (cfType == CFArrayGetTypeID())
+               {
+                       if (CFArrayGetCount((CFArrayRef)cfValue))
+                       {
+                               result = true;
+                       }
+               }
+               else if (cfType == CFDictionaryGetTypeID())
+               {
+                       if (CFDictionaryGetCount((CFDictionaryRef)cfValue))
+                       {
+                               result = true;
+                       }
+               }
+               else if (cfType == CFSetGetTypeID())
+               {
+                       if (CFSetGetCount((CFSetRef)cfValue))
+                       {
+                               result = true;
+                       }
+               }
+               else if (cfType == CFURLGetTypeID())
+               {
+                       CFURLRef absURL = CFURLCopyAbsoluteURL((CFURLRef)cfValue);
+                       if (absURL)
+                       {
+                               CFStringRef cfStr = CFURLGetString(absURL);
+                               if (cfStr && CFStringGetLength(cfStr))
+                               {
+                                       result = true;
+                               }
+                               ReleaseCFType(absURL);
+                       }
+               }
+       }
+       if (jsObjPtr) jsObjPtr->Release();
+       ReleaseCFType(cfValue);
+       return result;
+}
+
+double UserObjectImp::toNumber(ExecState *exec) const
+{
+       double result = 0;
+       JSUserObject* jsObjPtr = KJSValueToJSObject(toObject(exec), exec);
+       CFTypeRef cfValue = jsObjPtr ? jsObjPtr->CopyCFValue() : NULL;
+       if (cfValue)
+       {
+               CFTypeID cfType = CFGetTypeID(cfValue);
+               
+               if (cfValue == GetCFNull())
+               {
+                       //
+               }
+               else if (cfType == CFBooleanGetTypeID())
+               {
+                       if (cfValue == kCFBooleanTrue)
+                       {
+                               result = 1;
+                       }
+               }
+               else if (cfType == CFStringGetTypeID())
+               {
+                       result = CFStringGetDoubleValue((CFStringRef)cfValue);
+               }
+               else if (cfType == CFNumberGetTypeID())
+               {
+                       CFNumberGetValue((CFNumberRef)cfValue, kCFNumberDoubleType, &result);           
+               }
+       }
+       ReleaseCFType(cfValue);
+       if (jsObjPtr) jsObjPtr->Release();
+       return result;
+}
+
+UString UserObjectImp::toString(ExecState *exec) const
+{
+       UString result;
+       JSUserObject* jsObjPtr = KJSValueToJSObject(toObject(exec), exec);
+       CFTypeRef cfValue = jsObjPtr ? jsObjPtr->CopyCFValue() : NULL;
+       if (cfValue)
+       {
+               CFTypeID cfType = CFGetTypeID(cfValue);
+               if (cfValue == GetCFNull())
+               {
+                       //
+               }
+               else if (cfType == CFBooleanGetTypeID())
+               {
+                       if (cfValue == kCFBooleanTrue)
+                       {
+                               result = "true";
+                       }
+                       else
+                       {
+                               result = "false";
+                       }
+               }
+               else if (cfType == CFStringGetTypeID())
+               {
+                       result = CFStringToUString((CFStringRef)cfValue);
+               }
+               else if (cfType == CFNumberGetTypeID())
+               {
+                       if (cfValue == kCFNumberNaN)
+                       {
+                               result = "Nan";
+                       }
+                       else if (CFNumberCompare(kCFNumberPositiveInfinity, (CFNumberRef)cfValue, NULL) == 0)
+                       {
+                               result = "Infinity";
+                       }
+                       else if (CFNumberCompare(kCFNumberNegativeInfinity, (CFNumberRef)cfValue, NULL) == 0)
+                       {
+                               result = "-Infinity";
+                       }
+                       else
+                       {
+                               CFStringRef cfNumStr = NULL;
+                               if (CFNumberIsFloatType((CFNumberRef)cfValue))
+                               {
+                                       double d = 0;
+                                       CFNumberGetValue((CFNumberRef)cfValue, kCFNumberDoubleType, &d);
+                                       cfNumStr = CFStringCreateWithFormat(NULL, NULL, CFSTR("%f"), (float)d);
+                               }
+                               else
+                               {
+                                       int i = 0;
+                                       CFNumberGetValue((CFNumberRef)cfValue, kCFNumberIntType, &i);
+                                       cfNumStr = CFStringCreateWithFormat(NULL, NULL, CFSTR("%d"), (int)i);
+                               }
+                               
+                               if (cfNumStr)
+                               {
+                                       result = CFStringToUString(cfNumStr);
+                                       ReleaseCFType(cfNumStr);
+                               }                               
+                       }
+               }
+               else if (cfType == CFArrayGetTypeID())
+               {
+                       //
+               }
+               else if (cfType == CFDictionaryGetTypeID())
+               {
+                       //
+               }
+               else if (cfType == CFSetGetTypeID())
+               {
+                       //
+               }
+               else if (cfType == CFURLGetTypeID())
+               {
+                       CFURLRef absURL = CFURLCopyAbsoluteURL((CFURLRef)cfValue);
+                       if (absURL)
+                       {
+                               CFStringRef cfStr = CFURLGetString(absURL);
+                               if (cfStr)
+                               {
+                                       result = CFStringToUString(cfStr);
+                               }
+                               ReleaseCFType(absURL);
+                       }
+               }               
+       }
+       ReleaseCFType(cfValue);
+       if (jsObjPtr) jsObjPtr->Release();
+       return result;
+}
+
+void UserObjectImp::mark()
+{
+       ObjectImp::mark(); // call parent to mark self
+       if (fJSUserObject)
+       {
+               fJSUserObject->Mark(); // mark child
+       }
+}
diff --git a/JavaScriptGlue/UserObjectImp.h b/JavaScriptGlue/UserObjectImp.h
new file mode 100644 (file)
index 0000000..6d4650c
--- /dev/null
@@ -0,0 +1,51 @@
+#ifndef __UserObjectImp_h
+#define __UserObjectImp_h
+
+/*
+       UserObjectImp.h
+*/
+
+#include "JSUtils.h"
+#include "JSBase.h"
+#include "JSObject.h"
+
+class UserObjectImp : public ObjectImp
+{
+    public:
+        UserObjectImp(JSUserObject* userObject);
+        virtual                        ~UserObjectImp();
+    
+        virtual        const ClassInfo *classInfo() const;
+        static const ClassInfo info;
+        
+        virtual bool   implementsCall() const;
+
+               virtual bool hasProperty(ExecState *exec, const Identifier &propertyName) const;
+               virtual ReferenceList UserObjectImp::propList(ExecState *exec, bool recursive=true);
+
+        virtual Value  call(ExecState *exec, Object &thisObj, const List &args);
+#if JAG_PINK_OR_LATER
+               virtual Value   get(ExecState *exec, const Identifier &propertyName) const;
+               virtual void    put(ExecState *exec, const Identifier &propertyName, const Value &value, int attr = None);
+#else
+        virtual Value  get(ExecState* exec, const UString& propertyName) const;
+        virtual void   put(ExecState* exec, const UString& propertyName, const Value& value, int attr = None);
+#endif
+
+               virtual Value toPrimitive(ExecState *exec, Type preferredType = UnspecifiedType) const;
+               virtual bool toBoolean(ExecState *exec) const;
+               virtual double toNumber(ExecState *exec) const;
+               virtual UString toString(ExecState *exec) const;
+
+        
+               virtual void mark();
+               
+        JSUserObject* GetJSUserObject() const;
+       protected:
+               UserObjectImp();
+    private:
+        JSUserObject* fJSUserObject;
+};
+
+
+#endif
\ No newline at end of file