JavaScriptCore:
authorggaren <ggaren@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 21 Jun 2006 21:09:19 +0000 (21:09 +0000)
committerggaren <ggaren@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 21 Jun 2006 21:09:19 +0000 (21:09 +0000)
        Reviewed by Anders.

        - First cut at C API to JavaScript. Includes a unit test, 'testapi.c',
        and the outline of a test app, 'minidom.c'.

        Includes one change to JSC internals: Rename propList to getPropertyList and have it
        take its target property list by reference so that subclasses can
        add properties to the list before calling through to their superclasses.

        Also, I just ran prepare-ChangeLog in about 10 seconds, and I would like
        to give a shout-out to that.

        * API/APICast.h: Added.
        (toJS):
        (toRef):
        * API/JSBase.h: Added.
        * API/JSCallbackObject.cpp: Added.
        (KJS::):
        (KJS::JSCallbackObject::JSCallbackObject):
        (KJS::JSCallbackObject::~JSCallbackObject):
        (KJS::JSCallbackObject::className):
        (KJS::JSCallbackObject::getOwnPropertySlot):
        (KJS::JSCallbackObject::put):
        (KJS::JSCallbackObject::deleteProperty):
        (KJS::JSCallbackObject::implementsConstruct):
        (KJS::JSCallbackObject::construct):
        (KJS::JSCallbackObject::implementsCall):
        (KJS::JSCallbackObject::callAsFunction):
        (KJS::JSCallbackObject::getPropertyList):
        (KJS::JSCallbackObject::toBoolean):
        (KJS::JSCallbackObject::toNumber):
        (KJS::JSCallbackObject::toString):
        (KJS::JSCallbackObject::setPrivate):
        (KJS::JSCallbackObject::getPrivate):
        (KJS::JSCallbackObject::cachedValueGetter):
        (KJS::JSCallbackObject::callbackGetter):
        * API/JSCallbackObject.h: Added.
        (KJS::JSCallbackObject::classInfo):
        * API/JSCharBufferRef.cpp: Added.
        (JSStringMake):
        (JSCharBufferCreate):
        (JSCharBufferCreateUTF8):
        (JSCharBufferRetain):
        (JSCharBufferRelease):
        (JSValueCopyStringValue):
        (JSCharBufferGetLength):
        (JSCharBufferGetCharactersPtr):
        (JSCharBufferGetCharacters):
        (JSCharBufferGetMaxLengthUTF8):
        (JSCharBufferGetCharactersUTF8):
        (JSCharBufferIsEqual):
        (JSCharBufferIsEqualUTF8):
        (JSCharBufferCreateWithCFString):
        (CFStringCreateWithJSCharBuffer):
        * API/JSCharBufferRef.h: Added.
        * API/JSContextRef.cpp: Added.
        (JSContextCreate):
        (JSContextDestroy):
        (JSContextGetGlobalObject):
        (JSEvaluate):
        (JSCheckSyntax):
        (JSContextHasException):
        (JSContextGetException):
        (JSContextClearException):
        (JSContextSetException):
        * API/JSContextRef.h: Added.
        * API/JSObjectRef.cpp: Added.
        (JSValueToObject):
        (JSObjectMake):
        (JSFunctionMake):
        (JSObjectGetDescription):
        (JSObjectGetPrototype):
        (JSObjectSetPrototype):
        (JSObjectHasProperty):
        (JSObjectGetProperty):
        (JSObjectSetProperty):
        (JSObjectDeleteProperty):
        (JSObjectGetPrivate):
        (JSObjectSetPrivate):
        (JSObjectIsFunction):
        (JSObjectCallAsFunction):
        (JSObjectIsConstructor):
        (JSObjectCallAsConstructor):
        (__JSPropertyListEnumerator::__JSPropertyListEnumerator):
        (JSObjectCreatePropertyEnumerator):
        (JSPropertyEnumeratorGetNext):
        (JSPropertyEnumeratorRetain):
        (JSPropertyEnumeratorRelease):
        (JSPropertyListAdd):
        * API/JSObjectRef.h: Added.
        * API/JSValueRef.cpp: Added.
        (JSValueGetType):
        (JSValueIsUndefined):
        (JSValueIsNull):
        (JSValueIsBoolean):
        (JSValueIsNumber):
        (JSValueIsString):
        (JSValueIsObject):
        (JSValueIsEqual):
        (JSValueIsStrictEqual):
        (JSUndefinedMake):
        (JSNullMake):
        (JSBooleanMake):
        (JSNumberMake):
        (JSValueToBoolean):
        (JSValueToNumber):
        (JSGCProtect):
        (JSGCUnprotect):
        (JSGCCollect):
        * API/JSValueRef.h: Added.
        * API/JavaScriptCore.h: Added.
        * API/minidom.c: Added.
        (main):
        * API/minidom.html: Added.
        * API/minidom.js: Added.
        * API/testapi.c: Added.
        (assertEqualsAsBoolean):
        (assertEqualsAsNumber):
        (assertEqualsAsUTF8String):
        (assertEqualsAsCharactersPtr):
        (assertEqualsAsCharacters):
        (MyObject_initialize):
        (MyObject_copyDescription):
        (MyObject_hasProperty):
        (MyObject_getProperty):
        (MyObject_setProperty):
        (MyObject_deleteProperty):
        (MyObject_getPropertyList):
        (MyObject_callAsFunction):
        (MyObject_callAsConstructor):
        (MyObject_convertToType):
        (MyObject_finalize):
        (print_callAsFunction):
        (main):
        (createStringWithContentsOfFile):
        * API/testapi.js: Added.
        * ChangeLog:
        * JavaScriptCore.xcodeproj/project.pbxproj:
        * bindings/npruntime_impl.h:
        * kjs/array_instance.h:
        * kjs/array_object.cpp:
        (ArrayInstance::getPropertyList):
        * kjs/interpreter.cpp:
        (KJS::Interpreter::evaluate):
        * kjs/nodes.cpp:
        (ForInNode::execute):
        * kjs/object.cpp:
        (KJS::JSObject::put):
        (KJS::JSObject::canPut):
        (KJS::JSObject::deleteProperty):
        (KJS::JSObject::propertyIsEnumerable):
        (KJS::JSObject::getPropertyAttributes):
        (KJS::JSObject::getPropertyList):
        * kjs/object.h:
        * kjs/property_map.cpp:
        (KJS::PropertyMap::get):
        * kjs/property_map.h:
        * kjs/scope_chain.cpp:
        (KJS::ScopeChain::print):
        * kjs/string_object.cpp:
        (StringInstance::getPropertyList):
        * kjs/string_object.h:
        * kjs/ustring.h:
        (KJS::UString::Rep::ref):

JavaScriptGlue:

        Reviewed by Anders.

        - Required for JS API: Rename propList to getPropertyList and have it
        take its target property list by reference so that subclasses can
        add properties to the list before calling through to their superclasses.

        * JSUtils.cpp:
        (KJSValueToCFTypeInternal):
        * JSValueWrapper.cpp:
        (JSValueWrapper::JSObjectCopyPropertyNames):
        * UserObjectImp.cpp:
        (UserObjectImp::getPropertyList):
        * UserObjectImp.h:

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

38 files changed:
JavaScriptCore/API/APICast.h [new file with mode: 0644]
JavaScriptCore/API/JSBase.h [new file with mode: 0644]
JavaScriptCore/API/JSCallbackObject.cpp [new file with mode: 0644]
JavaScriptCore/API/JSCallbackObject.h [new file with mode: 0644]
JavaScriptCore/API/JSCharBufferRef.cpp [new file with mode: 0644]
JavaScriptCore/API/JSCharBufferRef.h [new file with mode: 0644]
JavaScriptCore/API/JSContextRef.cpp [new file with mode: 0644]
JavaScriptCore/API/JSContextRef.h [new file with mode: 0644]
JavaScriptCore/API/JSObjectRef.cpp [new file with mode: 0644]
JavaScriptCore/API/JSObjectRef.h [new file with mode: 0644]
JavaScriptCore/API/JSValueRef.cpp [new file with mode: 0644]
JavaScriptCore/API/JSValueRef.h [new file with mode: 0644]
JavaScriptCore/API/JavaScriptCore.h [new file with mode: 0644]
JavaScriptCore/API/minidom.c [new file with mode: 0644]
JavaScriptCore/API/minidom.html [new file with mode: 0644]
JavaScriptCore/API/minidom.js [new file with mode: 0644]
JavaScriptCore/API/testapi.c [new file with mode: 0644]
JavaScriptCore/API/testapi.js [new file with mode: 0644]
JavaScriptCore/ChangeLog
JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
JavaScriptCore/bindings/npruntime_impl.h
JavaScriptCore/kjs/array_instance.h
JavaScriptCore/kjs/array_object.cpp
JavaScriptCore/kjs/interpreter.cpp
JavaScriptCore/kjs/nodes.cpp
JavaScriptCore/kjs/object.cpp
JavaScriptCore/kjs/object.h
JavaScriptCore/kjs/property_map.cpp
JavaScriptCore/kjs/property_map.h
JavaScriptCore/kjs/scope_chain.cpp
JavaScriptCore/kjs/string_object.cpp
JavaScriptCore/kjs/string_object.h
JavaScriptCore/kjs/ustring.h
JavaScriptGlue/ChangeLog
JavaScriptGlue/JSUtils.cpp
JavaScriptGlue/JSValueWrapper.cpp
JavaScriptGlue/UserObjectImp.cpp
JavaScriptGlue/UserObjectImp.h

diff --git a/JavaScriptCore/API/APICast.h b/JavaScriptCore/API/APICast.h
new file mode 100644 (file)
index 0000000..49d4439
--- /dev/null
@@ -0,0 +1,97 @@
+// -*- mode: c++; c-basic-offset: 4 -*-
+/*
+ * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef APICast_h
+#define APICast_h
+
+#include "JSValueRef.h"
+#include "UString.h"
+
+namespace KJS {
+    class ExecState;
+    class JSValue;
+    class JSObject;
+    class ReferenceList;
+}
+
+/* Opaque typing convenience methods */
+
+inline KJS::ExecState* toJS(JSContextRef c)
+{
+    return reinterpret_cast<KJS::ExecState*>(c);
+}
+
+inline KJS::JSValue* toJS(JSValueRef v)
+{
+    return reinterpret_cast<KJS::JSValue*>(v);
+}
+
+inline KJS::UString::Rep* toJS(JSCharBufferRef b)
+{
+    return reinterpret_cast<KJS::UString::Rep*>(b);
+}
+
+inline KJS::JSObject* toJS(JSObjectRef o)
+{
+    return reinterpret_cast<KJS::JSObject*>(o);
+}
+
+inline KJS::ReferenceList* toJS(JSPropertyListRef l)
+{
+    return reinterpret_cast<KJS::ReferenceList*>(l);
+}
+
+inline JSValueRef toRef(KJS::JSValue* v)
+{
+    return toRef(v);
+}
+
+inline JSCharBufferRef toRef(KJS::UString::Rep* s)
+{
+    return reinterpret_cast<JSCharBufferRef>(s);
+}
+
+inline JSObjectRef toRef(KJS::JSObject* o)
+{
+    return toRef(o);
+}
+
+inline JSObjectRef toRef(const KJS::JSObject* o)
+{
+    return toRef(const_cast<KJS::JSObject*>(o));
+}
+
+inline JSPropertyListRef toRef(KJS::ReferenceList* l)
+{
+    return reinterpret_cast<JSPropertyListRef>(l);
+}
+
+inline JSContextRef toRef(KJS::ExecState* e)
+{
+    return reinterpret_cast<JSContextRef>(e);
+}
+
+#endif // APICast_h
diff --git a/JavaScriptCore/API/JSBase.h b/JavaScriptCore/API/JSBase.h
new file mode 100644 (file)
index 0000000..794da83
--- /dev/null
@@ -0,0 +1,59 @@
+// -*- mode: c++; c-basic-offset: 4 -*-
+/*
+ * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef JSBase_h
+#define JSBase_h
+
+/* JS runtime interface types */
+typedef struct __JSContext* JSContextRef;
+typedef struct __JSCharBuffer* JSCharBufferRef;
+typedef struct __JSPropertyList* JSPropertyListRef;
+typedef struct __JSPropertyListEnumerator* JSPropertyListEnumeratorRef;
+
+/* Base type of all JS values, and polymorphic functions on them */
+typedef void* JSValueRef;
+
+typedef struct __JSObject* JSObjectRef;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Returns true for successful execution, false for uncaught exception. 
+// returnValue will contain value of last evaluated statement or exception value.
+bool JSEvaluate(JSContextRef context, JSValueRef thisValue, JSCharBufferRef script, JSCharBufferRef sourceURL, int startingLineNumber, JSValueRef* returnValue);
+bool JSCheckSyntax(JSContextRef context, JSCharBufferRef script);
+
+// Garbage collection
+void JSGCProtect(JSValueRef value);
+void JSGCUnprotect(JSValueRef value);
+void JSGCCollect(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // JSBase_h
diff --git a/JavaScriptCore/API/JSCallbackObject.cpp b/JavaScriptCore/API/JSCallbackObject.cpp
new file mode 100644 (file)
index 0000000..5b6922e
--- /dev/null
@@ -0,0 +1,304 @@
+// -*- mode: c++; c-basic-offset: 4 -*-
+/*
+ * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "APICast.h"
+#include "JSCallbackObject.h"
+#include "JSCharBufferRef.h"
+#include "JSObjectRef.h"
+#include "internal.h"
+#include "reference_list.h"
+
+namespace KJS {
+
+const ClassInfo JSCallbackObject::info = { "JSCallbackObject", 0, 0, 0 };
+
+JSCallbackObject::JSCallbackObject(const JSObjectCallbacks* callbacks)
+    : JSObject()
+    , m_privateData(0)
+    , m_callbacks(*callbacks)
+{
+    JSObjectRef thisRef = toRef(this);
+    
+    do {
+        if (JSInitializeCallback initialize = callbacks->initialize)
+            initialize(thisRef);
+    } while ((callbacks = callbacks->parentCallbacks));
+}
+
+JSCallbackObject::JSCallbackObject(const JSObjectCallbacks* callbacks, JSObject* prototype)
+    : JSObject(prototype)
+    , m_privateData(0)
+    , m_callbacks(*callbacks)
+{
+    JSObjectRef thisRef = toRef(this);
+    
+    do {
+        if (JSInitializeCallback initialize = callbacks->initialize)
+            initialize(thisRef);
+    } while ((callbacks = callbacks->parentCallbacks));
+}
+
+JSCallbackObject::~JSCallbackObject()
+{
+    JSObjectRef thisRef = toRef(this);
+    
+    for (JSObjectCallbacks* callbacks = &m_callbacks; callbacks; callbacks = callbacks->parentCallbacks)
+        if (JSFinalizeCallback finalize = callbacks->finalize)
+            finalize(thisRef);
+}
+
+UString JSCallbackObject::className() const
+{
+    JSObjectRef thisRef = toRef(this);
+    
+    for (const JSObjectCallbacks* callbacks = &m_callbacks; callbacks; callbacks = callbacks->parentCallbacks) {
+        if (JSCopyDescriptionCallback copyDescriptionCallback = callbacks->copyDescription) {
+            JSCharBufferRef descriptionBuf = copyDescriptionCallback(thisRef);
+            UString description(toJS(descriptionBuf));
+            JSCharBufferRelease(descriptionBuf);
+            return description;
+        }
+    }
+    
+    return JSObject::className();
+}
+
+bool JSCallbackObject::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
+{
+    JSObjectRef thisRef = toRef(this);
+    JSCharBufferRef propertyNameRef = toRef(propertyName.ustring().rep());
+
+    // optional optimization for cases when we only need to know if the property exists, not its value
+    for (const JSObjectCallbacks* callbacks = &m_callbacks; callbacks; callbacks = callbacks->parentCallbacks) {
+        if (JSHasPropertyCallback hasPropertyCallback = callbacks->hasProperty) {
+            if (hasPropertyCallback(thisRef, propertyNameRef)) {
+                slot.setCustom(0, callbackGetter);
+                return true;
+            }
+        }
+    }
+    
+    for (const JSObjectCallbacks* callbacks = &m_callbacks; callbacks; callbacks = callbacks->parentCallbacks) {
+        if (JSGetPropertyCallback getPropertyCallback = callbacks->getProperty) {
+            JSValueRef returnValue;
+            if (getPropertyCallback(thisRef, propertyNameRef, &returnValue)) {
+                slot.setCustom(reinterpret_cast<JSObject*>(returnValue), cachedValueGetter); // cache the value so we don't have to compute it again
+                return true;
+            }
+        }
+    }
+    return JSObject::getOwnPropertySlot(exec, propertyName, slot);
+}
+
+bool JSCallbackObject::getOwnPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot)
+{
+    return getOwnPropertySlot(exec, Identifier::from(propertyName), slot);
+}
+
+void JSCallbackObject::put(ExecState* exec, const Identifier& propertyName, JSValue* value, int attr)
+{
+    JSObjectRef thisRef = toRef(this);
+    JSCharBufferRef propertyNameRef = toRef(propertyName.ustring().rep());
+
+    for (const JSObjectCallbacks* callbacks = &m_callbacks; callbacks; callbacks = callbacks->parentCallbacks) {
+        if (JSSetPropertyCallback setPropertyCallback = callbacks->setProperty) {
+            if (setPropertyCallback(thisRef, propertyNameRef, value))
+                return;
+        }
+    }
+    return JSObject::put(exec, propertyName, value, attr);
+}
+
+void JSCallbackObject::put(ExecState* exec, unsigned propertyName, JSValue* value, int attr)
+{
+    return put(exec, Identifier::from(propertyName), value, attr);
+}
+
+bool JSCallbackObject::deleteProperty(ExecState* exec, const Identifier& propertyName)
+{
+    JSObjectRef thisRef = toRef(this);
+    JSCharBufferRef propertyNameRef = toRef(propertyName.ustring().rep());
+    
+    for (const JSObjectCallbacks* callbacks = &m_callbacks; callbacks; callbacks = callbacks->parentCallbacks) {
+        if (JSDeletePropertyCallback deletePropertyCallback = callbacks->deleteProperty) {
+            if (deletePropertyCallback(thisRef, propertyNameRef))
+                return true;
+        }
+    }
+    return JSObject::deleteProperty(exec, propertyName);
+}
+
+bool JSCallbackObject::deleteProperty(ExecState* exec, unsigned propertyName)
+{
+    return deleteProperty(exec, Identifier::from(propertyName));
+}
+
+bool JSCallbackObject::implementsConstruct() const
+{
+    for (const JSObjectCallbacks* callbacks = &m_callbacks; callbacks; callbacks = callbacks->parentCallbacks)
+        if (callbacks->callAsConstructor)
+            return true;
+
+    return false;
+}
+
+JSObject* JSCallbackObject::construct(ExecState* exec, const List& args)
+{
+    JSContextRef execRef = toRef(exec);
+    JSObjectRef thisRef = toRef(this);
+    
+    for (const JSObjectCallbacks* callbacks = &m_callbacks; callbacks; callbacks = callbacks->parentCallbacks) {
+        if (JSCallAsConstructorCallback callAsConstructorCallback = callbacks->callAsConstructor) {
+            size_t argc = args.size();
+            JSValueRef argv[argc];
+            for (size_t i = 0; i < argc; i++)
+                argv[i] = args[i];
+            return toJS(callAsConstructorCallback(execRef, thisRef, argc, argv));
+        }
+    }
+    
+    ASSERT(false);
+    return 0;
+}
+
+bool JSCallbackObject::implementsCall() const
+{
+    for (const JSObjectCallbacks* callbacks = &m_callbacks; callbacks; callbacks = callbacks->parentCallbacks)
+        if (callbacks->callAsFunction)
+            return true;
+    
+    return false;
+}
+
+JSValue* JSCallbackObject::callAsFunction(ExecState* exec, JSObject* thisObj, const List &args)
+{
+    JSContextRef execRef = toRef(exec);
+    JSObjectRef thisRef = toRef(this);
+    JSObjectRef thisObjRef = toRef(thisObj);
+
+    for (const JSObjectCallbacks* callbacks = &m_callbacks; callbacks; callbacks = callbacks->parentCallbacks) {
+        if (JSCallAsFunctionCallback callAsFunctionCallback = callbacks->callAsFunction) {
+            size_t argc = args.size();
+            JSValueRef argv[argc];
+            for (size_t i = 0; i < argc; i++)
+                argv[i] = args[i];
+            return toJS(callAsFunctionCallback(execRef, thisRef, thisObjRef, argc, argv));
+        }
+    }
+
+    ASSERT(false);
+    return 0;
+}
+
+void JSCallbackObject::getPropertyList(ExecState* exec, ReferenceList& propertyList, bool recursive)
+{
+    JSObjectRef thisRef = toRef(this);
+
+    for (const JSObjectCallbacks* callbacks = &m_callbacks; callbacks; callbacks = callbacks->parentCallbacks)
+        if (JSGetPropertyListCallback getPropertyListCallback = callbacks->getPropertyList)
+            getPropertyListCallback(thisRef, toRef(&propertyList));
+
+    JSObject::getPropertyList(exec, propertyList, recursive);
+}
+
+bool JSCallbackObject::toBoolean(ExecState* exec) const
+{
+    JSObjectRef thisRef = toRef(this);
+
+    for (const JSObjectCallbacks* callbacks = &m_callbacks; callbacks; callbacks = callbacks->parentCallbacks) {
+        if (JSConvertToTypeCallback convertToTypeCallback = callbacks->convertToType) {
+            JSValueRef returnValue;
+            if (convertToTypeCallback(thisRef, kJSTypeBoolean, &returnValue))
+                return toJS(returnValue)->getBoolean();
+        }
+    }
+    return JSObject::toBoolean(exec);
+}
+
+double JSCallbackObject::toNumber(ExecState* exec) const
+{
+    JSObjectRef thisRef = toRef(this);
+
+    for (const JSObjectCallbacks* callbacks = &m_callbacks; callbacks; callbacks = callbacks->parentCallbacks) {
+        if (JSConvertToTypeCallback convertToTypeCallback = callbacks->convertToType) {
+            JSValueRef returnValue;
+            if (convertToTypeCallback(thisRef, kJSTypeNumber, &returnValue))
+                return toJS(returnValue)->getNumber();
+        }
+    }
+    return JSObject::toNumber(exec);
+}
+
+UString JSCallbackObject::toString(ExecState* exec) const
+{
+    JSObjectRef thisRef = toRef(this);
+
+    for (const JSObjectCallbacks* callbacks = &m_callbacks; callbacks; callbacks = callbacks->parentCallbacks) {
+        if (JSConvertToTypeCallback convertToTypeCallback = callbacks->convertToType) {
+            JSValueRef returnValue;
+            if (convertToTypeCallback(thisRef, kJSTypeString, &returnValue))
+                return toJS(returnValue)->getString();
+        }
+    }
+    return JSObject::toString(exec);
+}
+
+void JSCallbackObject::setPrivate(void* data)
+{
+    m_privateData = data;
+}
+
+void* JSCallbackObject::getPrivate()
+{
+    return m_privateData;
+}
+
+JSValue* JSCallbackObject::cachedValueGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot& slot)
+{
+    JSValue* v = slot.slotBase();
+    ASSERT(v);
+    return v;
+}
+
+JSValue* JSCallbackObject::callbackGetter(ExecState*, JSObject* originalObject, const Identifier& propertyName, const PropertySlot&)
+{
+    ASSERT(originalObject->inherits(&JSCallbackObject::info));
+    JSObjectRef thisRef = toRef(originalObject);
+    JSCharBufferRef propertyNameRef= toRef(propertyName.ustring().rep());
+
+    for (const JSObjectCallbacks* callbacks = &static_cast<JSCallbackObject*>(originalObject)->m_callbacks; callbacks; callbacks = callbacks->parentCallbacks) {
+        if (JSGetPropertyCallback getPropertyCallback = callbacks->getProperty) {
+            JSValueRef returnValue;
+            if (getPropertyCallback(thisRef, propertyNameRef, &returnValue)) {
+                return toJS(returnValue);
+            }
+        }
+    }
+
+    return jsUndefined();
+}
+
+} // namespace KJS
diff --git a/JavaScriptCore/API/JSCallbackObject.h b/JavaScriptCore/API/JSCallbackObject.h
new file mode 100644 (file)
index 0000000..f32e79f
--- /dev/null
@@ -0,0 +1,84 @@
+// -*- mode: c++; c-basic-offset: 4 -*-
+/*
+ * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef JSCallbackObject_h
+#define JSCallbackObject_h
+
+#include "JSObjectRef.h"
+#include "JSValueRef.h"
+#include "object.h"
+
+namespace KJS {
+
+class JSCallbackObject : public JSObject
+{
+public:
+    JSCallbackObject(const JSObjectCallbacks* callbacks);
+    JSCallbackObject(const JSObjectCallbacks* callbacks, JSObject* prototype);
+    virtual ~JSCallbackObject();
+        
+    virtual UString className() const;
+
+    virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
+    virtual bool getOwnPropertySlot(ExecState*, unsigned, PropertySlot&);
+    
+    virtual void put(ExecState*, const Identifier&, JSValue*, int attr);
+    virtual void put(ExecState*, unsigned, JSValue*, int attr);
+
+    virtual bool deleteProperty(ExecState*, const Identifier&);
+    virtual bool deleteProperty(ExecState*, unsigned);
+
+    virtual bool implementsConstruct() const;
+    virtual JSObject* construct(ExecState*, const List& args);
+
+    virtual bool implementsCall() const;
+    virtual JSValue* callAsFunction(ExecState*, JSObject* thisObj, const List &args);
+
+    virtual void getPropertyList(ExecState*, ReferenceList& propertyList, bool recursive);
+
+    virtual bool toBoolean(ExecState*) const;
+    virtual double toNumber(ExecState*) const;
+    virtual UString toString(ExecState*) const;
+
+    void setPrivate(void* data);
+    void* getPrivate();
+    
+    virtual const ClassInfo *classInfo() const { return &info; }
+    static const ClassInfo info;
+    
+private:
+    JSCallbackObject(); // prevent default construction
+    JSCallbackObject(const JSCallbackObject&);
+
+    static JSValue* cachedValueGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot&);
+    static JSValue* callbackGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot&);
+    void* m_privateData;
+    JSObjectCallbacks m_callbacks;
+};
+
+} // namespace KJS
+
+#endif // JSCallbackObject_h
diff --git a/JavaScriptCore/API/JSCharBufferRef.cpp b/JavaScriptCore/API/JSCharBufferRef.cpp
new file mode 100644 (file)
index 0000000..b2cd0ec
--- /dev/null
@@ -0,0 +1,166 @@
+// -*- mode: c++; c-basic-offset: 4 -*-
+/*
+ * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "APICast.h"
+#include "JSCharBufferRef.h"
+
+#include <JavaScriptCore/JSLock.h>
+#include <JavaScriptCore/JSType.h>
+#include <JavaScriptCore/internal.h>
+#include <JavaScriptCore/operations.h>
+#include <JavaScriptCore/ustring.h>
+#include <JavaScriptCore/value.h>
+
+using namespace KJS;
+
+JSValueRef JSStringMake(JSCharBufferRef buffer)
+{
+    JSLock lock;
+    UString::Rep* rep = toJS(buffer);
+    return toRef(jsString(UString(rep)));
+}
+
+JSCharBufferRef JSCharBufferCreate(const JSChar* chars, size_t numChars)
+{
+    JSLock lock;
+    return toRef(UString(reinterpret_cast<const UChar*>(chars), numChars).rep()->ref());
+}
+
+JSCharBufferRef JSCharBufferCreateUTF8(const char* string)
+{
+    JSLock lock;
+    // FIXME: Only works with ASCII
+    // Use decodeUTF8Sequence or http://www.unicode.org/Public/PROGRAMS/CVTUTF/ instead
+    return toRef(UString(string).rep()->ref());
+}
+
+JSCharBufferRef JSCharBufferRetain(JSCharBufferRef buffer)
+{
+    UString::Rep* rep = toJS(buffer);
+    return toRef(rep->ref());
+}
+
+void JSCharBufferRelease(JSCharBufferRef buffer)
+{
+    JSLock lock;
+    UString::Rep* rep = toJS(buffer);
+    rep->deref();
+}
+
+JSCharBufferRef JSValueCopyStringValue(JSContextRef context, JSValueRef value)
+{
+    JSLock lock;
+    JSValue* jsValue = toJS(value);
+    ExecState* exec = toJS(context);
+
+    JSCharBufferRef charBufferRef = toRef(jsValue->toString(exec).rep()->ref());
+    // FIXME: What should we do with this exception?
+    if (exec->hadException())
+        exec->clearException();
+    return charBufferRef;
+}
+
+size_t JSCharBufferGetLength(JSCharBufferRef buffer)
+{
+    UString::Rep* rep = toJS(buffer);
+    return rep->size();
+}
+
+const JSChar* JSCharBufferGetCharactersPtr(JSCharBufferRef buffer)
+{
+    UString::Rep* rep = toJS(buffer);
+    return reinterpret_cast<const JSChar*>(rep->data());
+}
+
+void JSCharBufferGetCharacters(JSCharBufferRef inBuffer, JSChar* outBuffer, size_t numChars)
+{
+    UString::Rep* rep = toJS(inBuffer);
+    const JSChar* data = reinterpret_cast<const JSChar*>(rep->data());
+    
+    memcpy(outBuffer, data, numChars * sizeof(JSChar));
+}
+
+size_t JSCharBufferGetMaxLengthUTF8(JSCharBufferRef buffer)
+{
+    UString::Rep* rep = toJS(buffer);
+    
+    // Any UTF8 character > 3 bytes encodes as a UTF16 surrogate pair.
+    return rep->size() * 3 + 1; // + 1 for terminating '\0'
+}
+
+size_t JSCharBufferGetCharactersUTF8(JSCharBufferRef inBuffer, char* outBuffer, size_t bufferSize)
+{
+    JSLock lock;
+    UString::Rep* rep = toJS(inBuffer);
+    CString cString = UString(rep).UTF8String();
+
+    size_t length = std::min(bufferSize, cString.size() + 1); // + 1 for terminating '\0'
+    memcpy(outBuffer, cString.c_str(), length);
+    return length;
+}
+
+bool JSCharBufferIsEqual(JSCharBufferRef a, JSCharBufferRef b)
+{
+    UString::Rep* aRep = toJS(a);
+    UString::Rep* bRep = toJS(b);
+    
+    return UString(aRep) == UString(bRep);
+}
+
+bool JSCharBufferIsEqualUTF8(JSCharBufferRef a, const char* b)
+{
+    JSCharBufferRef bBuf = JSCharBufferCreateUTF8(b);
+    bool result = JSCharBufferIsEqual(a, bBuf);
+    JSCharBufferRelease(bBuf);
+    
+    return result;
+}
+
+#if defined(__APPLE__)
+JSCharBufferRef JSCharBufferCreateWithCFString(CFStringRef string)
+{
+    JSLock lock;
+    CFIndex length = CFStringGetLength(string);
+    
+    // Optimized path for when CFString backing store is a UTF16 buffer
+    if (const UniChar* buffer = CFStringGetCharactersPtr(string)) {
+        UString::Rep* rep = UString(reinterpret_cast<const UChar*>(buffer), length).rep()->ref();
+        return toRef(rep);
+    }
+
+    UniChar* buffer = static_cast<UniChar*>(fastMalloc(sizeof(UniChar) * length));
+    CFStringGetCharacters(string, CFRangeMake(0, length), buffer);
+    UString::Rep* rep = UString(reinterpret_cast<UChar*>(buffer), length, false).rep()->ref();
+    return toRef(rep);
+}
+
+CFStringRef CFStringCreateWithJSCharBuffer(CFAllocatorRef alloc, JSCharBufferRef buffer)
+{
+    UString::Rep* rep = toJS(buffer);
+    return CFStringCreateWithCharacters(alloc, reinterpret_cast<const JSChar*>(rep->data()), rep->size());
+}
+
+#endif // __APPLE__
diff --git a/JavaScriptCore/API/JSCharBufferRef.h b/JavaScriptCore/API/JSCharBufferRef.h
new file mode 100644 (file)
index 0000000..07d5181
--- /dev/null
@@ -0,0 +1,69 @@
+// -*- mode: c++; c-basic-offset: 4 -*-
+/*
+ * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef JSCharBufferRef_h
+#define JSCharBufferRef_h
+
+#include "JSValueRef.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(WIN32) || defined(_WIN32)
+    typedef wchar_t JSChar;
+#else
+    typedef unsigned short JSChar;
+#endif
+    
+JSCharBufferRef JSCharBufferCreate(const JSChar* chars, size_t numChars);
+JSCharBufferRef JSCharBufferCreateUTF8(const char* string);
+
+JSCharBufferRef JSCharBufferRetain(JSCharBufferRef buffer);
+void JSCharBufferRelease(JSCharBufferRef buffer);
+
+size_t JSCharBufferGetLength(JSCharBufferRef buffer);
+const JSChar* JSCharBufferGetCharactersPtr(JSCharBufferRef buffer);
+void JSCharBufferGetCharacters(JSCharBufferRef inBuffer, JSChar* outBuffer, size_t numChars);
+
+size_t JSCharBufferGetMaxLengthUTF8(JSCharBufferRef buffer);
+// Returns the number of bytes written into outBuffer, including the trailing '\0'
+size_t JSCharBufferGetCharactersUTF8(JSCharBufferRef inBuffer, char* outBuffer, size_t bufferSize);
+
+bool JSCharBufferIsEqual(JSCharBufferRef a, JSCharBufferRef b);
+bool JSCharBufferIsEqualUTF8(JSCharBufferRef a, const char* b);
+
+#if defined(__APPLE__)
+#include <CoreFoundation/CoreFoundation.h>
+// CFString convenience methods
+JSCharBufferRef JSCharBufferCreateWithCFString(CFStringRef string);
+CFStringRef CFStringCreateWithJSCharBuffer(CFAllocatorRef alloc, JSCharBufferRef buffer);
+#endif // __APPLE__
+    
+#ifdef __cplusplus
+}
+#endif
+
+#endif // JSCharBufferRef_h
diff --git a/JavaScriptCore/API/JSContextRef.cpp b/JavaScriptCore/API/JSContextRef.cpp
new file mode 100644 (file)
index 0000000..09cb028
--- /dev/null
@@ -0,0 +1,117 @@
+// -*- mode: c++; c-basic-offset: 4 -*-
+/*
+ * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "APICast.h"
+#include "JSContextRef.h"
+
+#include "JSCallbackObject.h"
+#include "completion.h"
+#include "interpreter.h"
+#include "object.h"
+
+using namespace KJS;
+
+JSContextRef JSContextCreate(const JSObjectCallbacks* globalObjectCallbacks, JSObjectRef globalObjectPrototype)
+{
+    JSLock lock;
+
+    JSObject* jsPrototype = toJS(globalObjectPrototype);
+
+    JSObject* globalObject;
+    if (globalObjectCallbacks == &kJSObjectCallbacksNone) // slightly more efficient
+        if (jsPrototype)
+            globalObject = new JSObject(jsPrototype);
+        else
+            globalObject = new JSObject();
+    else if (jsPrototype)
+        globalObject = new JSCallbackObject(globalObjectCallbacks, jsPrototype);
+    else
+        globalObject = new JSCallbackObject(globalObjectCallbacks);
+
+    Interpreter* interpreter = new Interpreter(globalObject); // adds the built-in object prototype to the global object
+    return toRef(interpreter->globalExec());
+}
+
+void JSContextDestroy(JSContextRef context)
+{
+    JSLock lock;
+    ExecState* exec = toJS(context);
+    delete exec->dynamicInterpreter();
+}
+
+JSObjectRef JSContextGetGlobalObject(JSContextRef context)
+{
+    ExecState* exec = toJS(context);
+    return toRef(exec->dynamicInterpreter()->globalObject());
+}
+
+bool JSEvaluate(JSContextRef context, JSValueRef thisValue, JSCharBufferRef script, JSCharBufferRef sourceURL, int startingLineNumber, JSValueRef* returnValue)
+{
+    JSLock lock;
+    ExecState* exec = toJS(context);
+    JSValue* jsThisValue = toJS(thisValue);
+    UString::Rep* scriptRep = toJS(script);
+    UString::Rep* sourceURLRep = toJS(sourceURL);
+    Completion completion = exec->dynamicInterpreter()->evaluate(UString(sourceURLRep), startingLineNumber, UString(scriptRep), jsThisValue);
+
+    *returnValue = toRef(completion.value());
+    return completion.complType() != Throw;
+}
+
+bool JSCheckSyntax(JSContextRef context, JSCharBufferRef script)
+{
+    JSLock lock;
+    ExecState* exec = toJS(context);
+    UString::Rep* rep = toJS(script);
+    return exec->dynamicInterpreter()->checkSyntax(UString(rep));
+}
+
+bool JSContextHasException(JSContextRef context)
+{
+    ExecState* exec = toJS(context);
+    return exec->hadException();
+}
+
+JSValueRef JSContextGetException(JSContextRef context)
+{
+    ExecState* exec = toJS(context);
+    return toRef(exec->exception());
+}
+
+void JSContextClearException(JSContextRef context)
+{
+    ExecState* exec = toJS(context);
+    if (exec->hadException())
+        exec->clearException();
+}
+
+void JSContextSetException(JSContextRef context, JSValueRef value)
+{
+    ExecState* exec = toJS(context);
+    JSValue* jsValue = toJS(value);
+    exec->setException(jsValue);
+}
+
diff --git a/JavaScriptCore/API/JSContextRef.h b/JavaScriptCore/API/JSContextRef.h
new file mode 100644 (file)
index 0000000..50d5b29
--- /dev/null
@@ -0,0 +1,55 @@
+// -*- mode: c++; c-basic-offset: 4 -*-
+/*
+ * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef JSContextRef_h
+#define JSContextRef_h
+
+#include "JSObjectRef.h"
+#include "JSValueRef.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+JSContextRef JSContextCreate(const JSObjectCallbacks* globalObjectCallbacks, JSObjectRef globalObjectPrototype);
+void JSContextDestroy(JSContextRef context);
+
+JSObjectRef JSContextGetGlobalObject(JSContextRef context);
+
+/* FIXME: These probably aren't useful. The exception is sometimes set
+   as a throw completion, other times as a value in the exec state.
+   There's no unified notion of the interpreter's "exception state."
+ */
+bool JSContextHasException(JSContextRef context);
+JSValueRef JSContextGetException(JSContextRef context);
+void JSContextClearException(JSContextRef context);
+void JSContextSetException(JSContextRef context, JSValueRef value);
+    
+#ifdef __cplusplus
+}
+#endif
+        
+#endif // JSContextRef_h
diff --git a/JavaScriptCore/API/JSObjectRef.cpp b/JavaScriptCore/API/JSObjectRef.cpp
new file mode 100644 (file)
index 0000000..938e7a2
--- /dev/null
@@ -0,0 +1,272 @@
+// -*- mode: c++; c-basic-offset: 4 -*-
+/*
+ * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "APICast.h"
+#include "JSValueRef.h"
+#include "JSObjectRef.h"
+#include "JSCallbackObject.h"
+
+#include "Identifier.h"
+#include "internal.h"
+#include "object.h"
+#include "reference_list.h"
+
+using namespace KJS;
+
+const JSObjectCallbacks kJSObjectCallbacksNone = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+
+JSObjectRef JSValueToObject(JSContextRef context, JSValueRef value)
+{
+    JSLock lock;
+    ExecState* exec = toJS(context);
+    JSValue* jsValue = toJS(value);
+
+    JSObjectRef objectRef = toRef(jsValue->toObject(exec));
+    // FIXME: What should we do with this exception?
+    if (exec->hadException())
+        exec->clearException();
+    return objectRef;
+}    
+
+JSObjectRef JSObjectMake(JSContextRef context, const JSObjectCallbacks* callbacks, JSObjectRef prototype)
+{
+    JSLock lock;
+
+    ExecState* exec = toJS(context);
+    JSObject* jsPrototype = toJS(prototype);
+
+    if (!prototype)
+        jsPrototype = exec->lexicalInterpreter()->builtinObjectPrototype();
+
+    if (callbacks == &kJSObjectCallbacksNone)
+        return toRef(new JSObject(jsPrototype)); // slightly more efficient
+    else
+        return toRef(new JSCallbackObject(callbacks, jsPrototype));
+}
+
+JSObjectRef JSFunctionMake(JSContextRef context, JSCallAsFunctionCallback callback)
+{
+    ExecState* exec = toJS(context);
+    JSObjectCallbacks callbacks = kJSObjectCallbacksNone;
+    callbacks.callAsFunction = callback;
+
+    return JSObjectMake(context, &callbacks, toRef(exec->lexicalInterpreter()->builtinFunctionPrototype()));
+}
+
+JSCharBufferRef JSObjectGetDescription(JSObjectRef object)
+{
+    JSLock lock;
+    JSObject* jsObject = toJS(object);
+    return toRef(jsObject->className().rep());
+}
+
+JSValueRef JSObjectGetPrototype(JSObjectRef object)
+{
+    JSObject* jsObject = toJS(object);
+    return toRef(jsObject->prototype());
+}
+
+void JSObjectSetPrototype(JSObjectRef object, JSValueRef value)
+{
+    JSObject* jsObject = toJS(object);
+    JSValue* jsValue = toJS(value);
+
+    jsObject->setPrototype(jsValue);
+}
+
+bool JSObjectHasProperty(JSContextRef context, JSObjectRef object, JSCharBufferRef propertyName)
+{
+    JSLock lock;
+    ExecState* exec = toJS(context);
+    JSObject* jsObject = toJS(object);
+    UString::Rep* nameRep = toJS(propertyName);
+    
+    return jsObject->hasProperty(exec, Identifier(nameRep));
+}
+
+bool JSObjectGetProperty(JSContextRef context, JSObjectRef object, JSCharBufferRef propertyName, JSValueRef* value)
+{
+    JSLock lock;
+    ExecState* exec = toJS(context);
+    JSObject* jsObject = toJS(object);
+    UString::Rep* nameRep = toJS(propertyName);
+
+    *value = toRef(jsObject->get(exec, Identifier(nameRep)));
+    return !JSValueIsUndefined(*value);
+}
+
+bool JSObjectSetProperty(JSContextRef context, JSObjectRef object, JSCharBufferRef propertyName, JSValueRef value, JSPropertyAttributes attributes)
+{
+    JSLock lock;
+    ExecState* exec = toJS(context);
+    JSObject* jsObject = toJS(object);
+    UString::Rep* nameRep = toJS(propertyName);
+    JSValue* jsValue = toJS(value);
+    
+    Identifier jsNameID = Identifier(nameRep);
+    if (jsObject->canPut(exec, jsNameID)) {
+        jsObject->put(exec, jsNameID, jsValue, attributes);
+        return true;
+    } else
+        return false;
+}
+
+bool JSObjectDeleteProperty(JSContextRef context, JSObjectRef object, JSCharBufferRef propertyName)
+{
+    JSLock lock;
+    ExecState* exec = toJS(context);
+    JSObject* jsObject = toJS(object);
+    UString::Rep* nameRep = toJS(propertyName);
+
+    return jsObject->deleteProperty(exec, Identifier(nameRep));
+}
+
+void* JSObjectGetPrivate(JSObjectRef object)
+{
+    JSObject* jsObject = toJS(object);
+    
+    if (!jsObject->inherits(&JSCallbackObject::info))
+        return 0;
+    
+    return static_cast<JSCallbackObject*>(jsObject)->getPrivate();
+}
+
+bool JSObjectSetPrivate(JSObjectRef object, void* data)
+{
+    JSObject* jsObject = toJS(object);
+    
+    if (!jsObject->inherits(&JSCallbackObject::info))
+        return false;
+    
+    static_cast<JSCallbackObject*>(jsObject)->setPrivate(data);
+    return true;
+}
+
+bool JSObjectIsFunction(JSObjectRef object)
+{
+    JSObject* jsObject = toJS(object);
+    return jsObject->implementsCall();
+}
+
+bool JSObjectCallAsFunction(JSContextRef context, JSObjectRef object, JSObjectRef thisObject, size_t argc, JSValueRef argv[], JSValueRef* returnValue)
+{
+    JSLock lock;
+    ExecState* exec = toJS(context);
+    JSObject* jsObject = toJS(object);
+    JSObject* jsThisObject = toJS(thisObject);
+
+    List argList;
+    for (size_t i = 0; i < argc; i++)
+        argList.append(toJS(argv[i]));
+    
+    *returnValue = jsObject->call(exec, jsThisObject, argList);
+    if (exec->hadException()) {
+        exec->clearException();
+        return false;
+    }
+    return true;
+}
+
+bool JSObjectIsConstructor(JSObjectRef object)
+{
+    JSObject* jsObject = toJS(object);
+    return jsObject->implementsConstruct();
+}
+
+bool JSObjectCallAsConstructor(JSContextRef context, JSObjectRef object, size_t argc, JSValueRef argv[], JSValueRef* returnValue)
+{
+    JSLock lock;
+    ExecState* exec = toJS(context);
+    JSObject* jsObject = toJS(object);
+    
+    List argList;
+    for (size_t i = 0; i < argc; i++)
+        argList.append(toJS(argv[i]));
+    
+    *returnValue = jsObject->construct(exec, argList);
+    if (exec->hadException()) {
+        exec->clearException();
+        return false;
+    }
+    return true;
+}
+
+struct __JSPropertyListEnumerator
+{
+    __JSPropertyListEnumerator() : refCount(0), iterator(list.end())
+    {
+    }
+    
+    unsigned refCount;
+    ReferenceList list;
+    ReferenceListIterator iterator;
+};
+
+JSPropertyListEnumeratorRef JSObjectCreatePropertyEnumerator(JSContextRef context, JSObjectRef object)
+{
+    JSLock lock;
+    ExecState* exec = toJS(context);
+    JSObject* jsObject = toJS(object);
+    
+    JSPropertyListEnumeratorRef enumerator = new __JSPropertyListEnumerator();
+    jsObject->getPropertyList(exec, enumerator->list);
+    enumerator->iterator = enumerator->list.begin();
+    
+    return enumerator;
+}
+
+JSCharBufferRef JSPropertyEnumeratorGetNext(JSContextRef context, JSPropertyListEnumeratorRef enumerator)
+{
+    ExecState* exec = toJS(context);
+    ReferenceListIterator& iterator = enumerator->iterator;
+    if (iterator != enumerator->list.end()) {
+        iterator++;
+        return toRef(iterator->getPropertyName(exec).ustring().rep());
+    }
+    return 0;
+}
+
+JSPropertyListEnumeratorRef JSPropertyEnumeratorRetain(JSPropertyListEnumeratorRef enumerator)
+{
+    ++enumerator->refCount;
+    return enumerator;
+}
+
+void JSPropertyEnumeratorRelease(JSPropertyListEnumeratorRef enumerator)
+{
+    if (--enumerator->refCount == 0)
+        delete enumerator;
+}
+
+void JSPropertyListAdd(JSPropertyListRef propertyList, JSObjectRef thisObject, JSCharBufferRef propertyName)
+{
+    JSLock lock;
+    ReferenceList* jsPropertyList = toJS(propertyList);
+    JSObject* jsObject = toJS(thisObject);
+    UString::Rep* rep = toJS(propertyName);
+    
+    jsPropertyList->append(Reference(jsObject, Identifier(rep)));
+}
diff --git a/JavaScriptCore/API/JSObjectRef.h b/JavaScriptCore/API/JSObjectRef.h
new file mode 100644 (file)
index 0000000..8f610fb
--- /dev/null
@@ -0,0 +1,132 @@
+// -*- mode: c++; c-basic-offset: 4 -*-
+/*
+ * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef JSObjectRef_h
+#define JSObjectRef_h
+
+#include "JSBase.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum { 
+    kJSPropertyAttributeNone         = 0,
+    kJSPropertyAttributeReadOnly     = 1 << 1,
+    kJSPropertyAttributeDontEnum     = 1 << 2,
+    kJSPropertyAttributeDontDelete   = 1 << 3
+};
+typedef unsigned JSPropertyAttributes;
+
+typedef void
+(*JSInitializeCallback)         (JSObjectRef object);
+
+typedef void            
+(*JSFinalizeCallback)           (JSObjectRef object);
+
+typedef JSCharBufferRef 
+(*JSCopyDescriptionCallback)    (JSObjectRef object);
+
+typedef bool
+(*JSHasPropertyCallback)        (JSObjectRef object, JSCharBufferRef propertyName);
+
+typedef bool
+(*JSGetPropertyCallback)        (JSObjectRef object, JSCharBufferRef propertyName, JSValueRef* returnValue);
+
+typedef bool
+(*JSSetPropertyCallback)        (JSObjectRef object, JSCharBufferRef propertyName, JSValueRef value);
+
+typedef bool
+(*JSDeletePropertyCallback)     (JSObjectRef object, JSCharBufferRef propertyName);
+
+typedef void
+(*JSGetPropertyListCallback)    (JSObjectRef object, JSPropertyListRef propertyList);
+
+typedef JSValueRef 
+(*JSCallAsFunctionCallback)     (JSContextRef context, JSObjectRef object, JSObjectRef thisObject, size_t argc, JSValueRef argv[]);
+
+typedef JSObjectRef 
+(*JSCallAsConstructorCallback)  (JSContextRef context, JSObjectRef object, size_t argc, JSValueRef argv[]);
+
+typedef bool
+(*JSConvertToTypeCallback)      (JSObjectRef object, JSTypeCode typeCode, JSValueRef* returnValue);
+
+typedef struct __JSObjectCallbacks {
+    int                         version; // current (and only) version is 0
+    struct __JSObjectCallbacks* parentCallbacks; // pass NULL for the default object callbacks
+    JSInitializeCallback        initialize;
+    JSFinalizeCallback          finalize;
+    JSCopyDescriptionCallback   copyDescription;
+    JSHasPropertyCallback       hasProperty;
+    JSGetPropertyCallback       getProperty;
+    JSSetPropertyCallback       setProperty;
+    JSDeletePropertyCallback    deleteProperty;
+    JSGetPropertyListCallback   getPropertyList;
+    JSCallAsFunctionCallback    callAsFunction;
+    JSCallAsConstructorCallback callAsConstructor;
+    JSConvertToTypeCallback     convertToType;
+} JSObjectCallbacks;
+
+extern const JSObjectCallbacks kJSObjectCallbacksNone;
+
+// pass NULL as prototype to get the built-in object prototype
+JSObjectRef JSObjectMake(JSContextRef context, const JSObjectCallbacks* callbacks, JSObjectRef prototype);
+
+// Will be assigned the built-in function prototype
+JSObjectRef JSFunctionMake(JSContextRef context, JSCallAsFunctionCallback callback);
+
+JSCharBufferRef JSObjectGetDescription(JSObjectRef object);
+
+JSValueRef JSObjectGetPrototype(JSObjectRef object);
+void JSObjectSetPrototype(JSObjectRef object, JSValueRef value);
+
+bool JSObjectHasProperty(JSContextRef context, JSObjectRef object, JSCharBufferRef propertyName);
+bool JSObjectGetProperty(JSContextRef context, JSObjectRef object, JSCharBufferRef propertyName, JSValueRef* value);
+bool JSObjectSetProperty(JSContextRef context, JSObjectRef object, JSCharBufferRef propertyName, JSValueRef value, JSPropertyAttributes attributes);
+bool JSObjectDeleteProperty(JSContextRef context, JSObjectRef object, JSCharBufferRef propertyName);
+
+void* JSObjectGetPrivate(JSObjectRef object);
+bool JSObjectSetPrivate(JSObjectRef object, void* data);
+
+bool JSObjectIsFunction(JSObjectRef object);
+bool JSObjectCallAsFunction(JSContextRef context, JSObjectRef object, JSObjectRef thisObject, size_t argc, JSValueRef argv[], JSValueRef* returnValue);
+bool JSObjectIsConstructor(JSObjectRef object);
+bool JSObjectCallAsConstructor(JSContextRef context, JSObjectRef object, size_t argc, JSValueRef argv[], JSValueRef* returnValue);
+
+// Used for enumerating the names of an object's properties like a for...in loop would
+JSPropertyListEnumeratorRef JSObjectCreatePropertyEnumerator(JSContextRef context, JSObjectRef object);
+JSPropertyListEnumeratorRef JSPropertyEnumeratorRetain(JSPropertyListEnumeratorRef enumerator);
+void JSPropertyEnumeratorRelease(JSPropertyListEnumeratorRef enumerator);
+JSCharBufferRef JSPropertyEnumeratorGetNext(JSContextRef context, JSPropertyListEnumeratorRef enumerator);
+
+// Used for adding property names to a for...in enumeration
+void JSPropertyListAdd(JSPropertyListRef propertyList, JSObjectRef thisObject, JSCharBufferRef propertyName);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // JSObjectRef_h
diff --git a/JavaScriptCore/API/JSValueRef.cpp b/JavaScriptCore/API/JSValueRef.cpp
new file mode 100644 (file)
index 0000000..fdaf644
--- /dev/null
@@ -0,0 +1,190 @@
+// -*- mode: c++; c-basic-offset: 4 -*-
+/*
+ * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "JSValueRef.h"
+#include "APICast.h"
+#include <JavaScriptCore/JSType.h>
+#include <JavaScriptCore/internal.h>
+#include <JavaScriptCore/operations.h>
+#include <JavaScriptCore/protect.h>
+#include <JavaScriptCore/ustring.h>
+#include <JavaScriptCore/value.h>
+
+#include <wtf/Assertions.h>
+
+#include <algorithm> // for std::min
+
+using namespace KJS;
+
+JSTypeCode JSValueGetType(JSValueRef value)
+{
+    JSValue* jsValue = toJS(value);
+    switch (jsValue->type()) {
+        case UndefinedType:
+            return kJSTypeUndefined;
+        case NullType:
+            return kJSTypeNull;
+        case BooleanType:
+            return kJSTypeBoolean;
+        case NumberType:
+            return kJSTypeNumber;
+        case StringType:
+            return kJSTypeString;
+        case ObjectType:
+            return kJSTypeObject;
+        default:
+            ASSERT(!"JSValueGetType: unknown type code.\n");
+            return kJSTypeUndefined;
+    }
+}
+
+bool JSValueIsUndefined(JSValueRef value)
+{
+    JSValue* jsValue = toJS(value);
+    return jsValue->isUndefined();
+}
+
+bool JSValueIsNull(JSValueRef value)
+{
+    JSValue* jsValue = toJS(value);
+    return jsValue->isNull();
+}
+
+bool JSValueIsBoolean(JSValueRef value)
+{
+    JSValue* jsValue = toJS(value);
+    return jsValue->isBoolean();
+}
+
+bool JSValueIsNumber(JSValueRef value)
+{
+    JSValue* jsValue = toJS(value);
+    return jsValue->isNumber();
+}
+
+bool JSValueIsString(JSValueRef value)
+{
+    JSValue* jsValue = toJS(value);
+    return jsValue->isString();
+}
+
+bool JSValueIsObject(JSValueRef value)
+{
+    JSValue* jsValue = toJS(value);
+    return jsValue->isObject();
+}
+
+bool JSValueIsEqual(JSContextRef context, JSValueRef a, JSValueRef b)
+{
+    JSLock lock;
+    ExecState* exec = toJS(context);
+    JSValue* jsA = toJS(a);
+    JSValue* jsB = toJS(b);
+
+    bool result = equal(exec, jsA, jsB);
+    if (exec->hadException())
+        exec->clearException();
+    return result;
+}
+
+bool JSValueIsStrictEqual(JSContextRef context, JSValueRef a, JSValueRef b)
+{
+    JSLock lock;
+    ExecState* exec = toJS(context);
+    JSValue* jsA = toJS(a);
+    JSValue* jsB = toJS(b);
+    
+    bool result = strictEqual(exec, jsA, jsB);
+    if (exec->hadException())
+        exec->clearException();
+    return result;
+}
+
+JSValueRef JSUndefinedMake()
+{
+    JSLock lock;
+    return toRef(jsUndefined());
+}
+
+JSValueRef JSNullMake()
+{
+    JSLock lock;
+    return toRef(jsNull());
+}
+
+JSValueRef JSBooleanMake(bool value)
+{
+    JSLock lock;
+    return toRef(jsBoolean(value));
+}
+
+JSValueRef JSNumberMake(double value)
+{
+    JSLock lock;
+    return toRef(jsNumber(value));
+}
+
+bool JSValueToBoolean(JSContextRef context, JSValueRef value)
+{
+    JSLock lock;
+    ExecState* exec = toJS(context);
+    JSValue* jsValue = toJS(value);
+    
+    return jsValue->toBoolean(exec);
+}
+
+double JSValueToNumber(JSContextRef context, JSValueRef value)
+{
+    JSLock lock;
+    JSValue* jsValue = toJS(value);
+    ExecState* exec = toJS(context);
+
+    double number = jsValue->toNumber(exec);
+    // FIXME: What should we do with this exception?
+    if (exec->hadException())
+        exec->clearException();
+    return number;
+}
+
+void JSGCProtect(JSValueRef value)
+{
+    JSLock lock;
+    JSValue* jsValue = toJS(value);
+    gcProtect(jsValue);
+}
+
+void JSGCUnprotect(JSValueRef value)
+{
+    JSLock lock;
+    JSValue* jsValue = toJS(value);
+    gcUnprotect(jsValue);
+}
+
+void JSGCCollect()
+{
+    JSLock lock;
+    Collector::collect();
+}
diff --git a/JavaScriptCore/API/JSValueRef.h b/JavaScriptCore/API/JSValueRef.h
new file mode 100644 (file)
index 0000000..8ef1e6a
--- /dev/null
@@ -0,0 +1,77 @@
+// -*- mode: c++; c-basic-offset: 4 -*-
+/*
+ * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef JSValueRef_h
+#define JSValueRef_h
+
+#include "JSBase.h"
+
+// Value types
+typedef enum {
+    kJSTypeUndefined,
+    kJSTypeNull,
+    kJSTypeBoolean,
+    kJSTypeNumber,
+    kJSTypeString,
+    kJSTypeObject
+} JSTypeCode;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+JSTypeCode JSValueGetType(JSValueRef value);
+
+bool JSValueIsUndefined(JSValueRef value);
+bool JSValueIsNull(JSValueRef value);
+bool JSValueIsBoolean(JSValueRef value);
+bool JSValueIsNumber(JSValueRef value);
+bool JSValueIsString(JSValueRef value);
+bool JSValueIsObject(JSValueRef value);
+
+// Comparing values
+bool JSValueIsEqual(JSContextRef context, JSValueRef a, JSValueRef b);
+bool JSValueIsStrictEqual(JSContextRef context, JSValueRef a, JSValueRef b);
+bool JSValueIsInstanceOf(JSValueRef value, JSObjectRef object);
+
+// Creating values
+JSValueRef JSUndefinedMake(void);
+JSValueRef JSNullMake(void);
+JSValueRef JSBooleanMake(bool value);
+JSValueRef JSNumberMake(double value);
+JSValueRef JSStringMake(JSCharBufferRef buffer);
+
+// Converting to primitive values
+bool JSValueToBoolean(JSContextRef context, JSValueRef value);
+double JSValueToNumber(JSContextRef context, JSValueRef value); // 0.0 if conversion fails
+JSObjectRef JSValueToObject(JSContextRef context, JSValueRef value); // Error object if conversion fails
+JSCharBufferRef JSValueCopyStringValue(JSContextRef context, JSValueRef value); // Empty string if conversion fails
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // JSValueRef_h
diff --git a/JavaScriptCore/API/JavaScriptCore.h b/JavaScriptCore/API/JavaScriptCore.h
new file mode 100644 (file)
index 0000000..21d4cb9
--- /dev/null
@@ -0,0 +1,39 @@
+// -*- mode: c++; c-basic-offset: 4 -*-
+/*
+ * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef JavaScriptCore_h
+#define JavaScriptCore_h
+
+#include <stdbool.h>
+#include <stddef.h> // for size_t
+
+#include "JSBase.h"
+#include "JSCharBufferRef.h"
+#include "JSContextRef.h"
+#include "JSObjectRef.h"
+#include "JSValueRef.h"
+
+#endif // JavaScriptCore_h
diff --git a/JavaScriptCore/API/minidom.c b/JavaScriptCore/API/minidom.c
new file mode 100644 (file)
index 0000000..ac383e6
--- /dev/null
@@ -0,0 +1,36 @@
+// -*- mode: c++; c-basic-offset: 4 -*-
+/*
+ * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "JavaScriptCore.h"
+#include <wtf/UnusedParam.h>
+
+int main(int argc, char* argv[])
+{
+    UNUSED_PARAM(argc);
+    UNUSED_PARAM(argv);
+    
+    return 0;
+}
diff --git a/JavaScriptCore/API/minidom.html b/JavaScriptCore/API/minidom.html
new file mode 100644 (file)
index 0000000..7ea4747
--- /dev/null
@@ -0,0 +1,9 @@
+<html>
+<head>
+<script src="minidom.js"></script>
+</head>
+
+<body onload="test()">
+    <pre id='pre'></pre>
+</body>
+</html>
diff --git a/JavaScriptCore/API/minidom.js b/JavaScriptCore/API/minidom.js
new file mode 100644 (file)
index 0000000..0343e37
--- /dev/null
@@ -0,0 +1,216 @@
+// -*- mode: c++; c-basic-offset: 4 -*-
+/*
+ * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+// For browser-based testing
+if (window) {
+    /* 
+    The methods and constructors below approximate what that the native host should provide
+
+    print(string);
+
+    Node
+        |-- TextNode
+        |-- Element
+            |-- RootElement
+            |-- HeroElement
+            |-- VillainElement
+            |-- NameElement
+            |-- WeaponElement
+        |-- Document
+    */
+      
+    function print(string, indentLevel)
+    {
+        document.getElementById('pre').appendChild(document.createTextNode(string));
+    }
+    
+    Node = function()
+    {
+        this.__defineGetter__("childNodes", function() {
+            if (!this._childNodes)
+                this._childNodes = new Array();
+            return this._childNodes;
+        });
+        this.__defineGetter__("firstChild", function () { 
+            return this.childNodes[0];
+        });
+    }
+
+    Node.prototype.tag = "Node";
+
+    Node.prototype.appendChild = function(child) {
+        this.childNodes.push(child);
+    }
+    
+    Node.prototype.serialize = function(numSpaces) {
+        function printSpaces(n) 
+        {
+            for (var i = 0; i < n; i++) // >
+            print(" ");
+        }
+
+        printSpaces(numSpaces);
+        print('<' + this.tag + '>' + '\n');
+        
+        var childNodesLength = this.childNodes.length;
+        for (var i = 0; i < childNodesLength; i++) //>
+            this.childNodes[i].serialize(numSpaces + 4);
+        
+        printSpaces(numSpaces);
+        print('</' + this.tag + '>\n');
+    }
+
+    TextNode = function(text)
+    {
+        this.text = text;
+    }
+
+    TextNode.prototype = new Node();
+    
+    TextNode.prototype.tag = "Text";
+    
+    TextNode.prototype.serialize = function(numSpaces) {
+        for (var i = 0; i < numSpaces; i++) // >
+            print(" ");
+        print(this.text + '\n');
+    }
+
+    Element = function()
+    {
+    }
+    
+    Element.prototype = new Node();
+    
+    Element.prototype.tag = "Element";
+
+    RootElement = function()
+    {
+    }
+    
+    RootElement.prototype = new Element();
+
+    RootElement.prototype.tag = "Root";
+    
+    HeroElement = function()
+    {
+    }
+    
+    HeroElement.prototype = new Element();
+
+    HeroElement.prototype.tag = "Hero";
+
+    VillainElement = function()
+    {
+    }
+    
+    VillainElement.prototype = new Element();
+
+    VillainElement.prototype.tag = "Villain";
+
+    NameElement = function()
+    {
+    }
+    
+    NameElement.prototype = new Element();
+
+    NameElement.prototype.tag = "Name";
+
+    WeaponElement = function()
+    {
+    }
+    
+    WeaponElement.prototype = new Element();
+
+    WeaponElement.prototype.tag = "Weapon";
+
+    Document = function()
+    {
+    }
+
+    Document.prototype = new Node();
+
+    Document.prototype.serialize = function() {
+        this.firstChild.serialize(0);
+    }
+    
+    Document.prototype.createElement = function(elementType) {
+        return eval('new ' + elementType + 'Element()');
+    }
+
+    Document.prototype.createTextNode = function(text) {
+        return new TextNode(text);
+    }
+}
+
+function test()
+{
+    var element, name, weapon;
+    
+    var document = new Document();
+    document.appendChild(document.createElement('Root'));
+
+    /* Tank Girl */
+    element = document.createElement('Hero');
+
+    name = document.createElement('Name');
+    name.appendChild(document.createTextNode('Tank Girl'));
+    element.appendChild(name);
+    
+    weapon = document.createElement('Weapon');
+    weapon.appendChild(document.createTextNode('Tank'));
+    element.appendChild(weapon);
+    
+    weapon = document.createElement('Weapon');
+    weapon.appendChild(document.createTextNode('Attitude'));
+    element.appendChild(weapon);
+    
+    weapon = document.createElement('Weapon');
+    weapon.appendChild(document.createTextNode('Army of genetically engineered super-kangaroos'));
+    element.appendChild(weapon);
+    
+    document.firstChild.appendChild(element);
+
+
+    /* Skeletor */
+    element = document.createElement('Villain');
+
+    name = document.createElement('Name');
+    name.appendChild(document.createTextNode('Skeletor'));
+    element.appendChild(name);
+    
+    weapon = document.createElement('Weapon');
+    weapon.appendChild(document.createTextNode('Havok Staff'));
+    element.appendChild(weapon);
+    
+    weapon = document.createElement('Weapon');
+    weapon.appendChild(document.createTextNode('Motley crew of henchmen'));
+    element.appendChild(weapon);
+    
+    document.firstChild.appendChild(element);
+
+    /* Serialize */
+    document.serialize();
+}
diff --git a/JavaScriptCore/API/testapi.c b/JavaScriptCore/API/testapi.c
new file mode 100644 (file)
index 0000000..86fd9b5
--- /dev/null
@@ -0,0 +1,552 @@
+// -*- mode: c++; c-basic-offset: 4 -*-
+/*
+ * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "JavaScriptCore.h"
+#include <wtf/UnusedParam.h>
+
+#if defined(__APPLE__)
+#include <CoreFoundation/CoreFoundation.h>
+#endif
+
+#include <assert.h>
+#include <math.h>
+
+static JSContextRef context = 0;
+
+static void assertEqualsAsBoolean(JSValueRef value, bool expectedValue)
+{
+    assert(JSValueToBoolean(context, value) == expectedValue);
+}
+
+static void assertEqualsAsNumber(JSValueRef value, double expectedValue)
+{
+    double number = JSValueToNumber(context, value);
+    assert(number == expectedValue || (isnan(number) && isnan(expectedValue)));
+}
+
+static void assertEqualsAsUTF8String(JSValueRef value, const char* expectedValue)
+{
+    JSCharBufferRef valueAsString = JSValueCopyStringValue(context, value);
+
+    size_t jsSize = JSCharBufferGetMaxLengthUTF8(valueAsString);
+    char jsBuffer[jsSize];
+    JSCharBufferGetCharactersUTF8(valueAsString, jsBuffer, jsSize);
+    
+    assert(strcmp(jsBuffer, expectedValue) == 0);
+    assert(jsSize >= strlen(jsBuffer) + 1);
+
+    JSCharBufferRelease(valueAsString);
+}
+
+#if defined(__APPLE__)
+static void assertEqualsAsCharactersPtr(JSValueRef value, const char* expectedValue)
+{
+    JSCharBufferRef valueAsString = JSValueCopyStringValue(context, value);
+
+    size_t jsLength = JSCharBufferGetLength(valueAsString);
+    const JSChar* jsBuffer = JSCharBufferGetCharactersPtr(valueAsString);
+
+    CFStringRef expectedValueAsCFString = CFStringCreateWithCString(kCFAllocatorDefault, 
+                                                                    expectedValue,
+                                                                    kCFStringEncodingUTF8);    
+    CFIndex cfLength = CFStringGetLength(expectedValueAsCFString);
+    UniChar cfBuffer[cfLength];
+    CFStringGetCharacters(expectedValueAsCFString, CFRangeMake(0, cfLength), cfBuffer);
+    CFRelease(expectedValueAsCFString);
+
+    assert(memcmp(jsBuffer, cfBuffer, cfLength * sizeof(UniChar)) == 0);
+    assert(jsLength == (size_t)cfLength);
+    
+    JSCharBufferRelease(valueAsString);
+}
+
+static void assertEqualsAsCharacters(JSValueRef value, const char* expectedValue)
+{
+    JSCharBufferRef valueAsString = JSValueCopyStringValue(context, value);
+    
+    size_t jsLength = JSCharBufferGetLength(valueAsString);
+    JSChar jsBuffer[jsLength];
+    JSCharBufferGetCharacters(valueAsString, jsBuffer, jsLength);
+    
+    CFStringRef expectedValueAsCFString = CFStringCreateWithCString(kCFAllocatorDefault, 
+                                                                    expectedValue,
+                                                                    kCFStringEncodingUTF8);    
+    CFIndex cfLength = CFStringGetLength(expectedValueAsCFString);
+    UniChar cfBuffer[cfLength];
+    CFStringGetCharacters(expectedValueAsCFString, CFRangeMake(0, cfLength), cfBuffer);
+    CFRelease(expectedValueAsCFString);
+    
+    assert(memcmp(jsBuffer, cfBuffer, cfLength * sizeof(UniChar)) == 0);
+    assert(jsLength == (size_t)cfLength);
+    
+    JSCharBufferRelease(valueAsString);
+}
+#endif // __APPLE__
+
+static JSValueRef jsGlobalValue; // non-stack value for testing JSGCProtect()
+
+/* MyObject pseudo-class */
+
+static bool didInitialize = false;
+static void MyObject_initialize(JSObjectRef object)
+{
+    UNUSED_PARAM(context);
+    UNUSED_PARAM(object);
+    didInitialize = true;
+}
+
+static JSCharBufferRef MyObject_copyDescription(JSObjectRef object)
+{
+    UNUSED_PARAM(object);
+    return JSCharBufferCreateUTF8("MyObject");
+}
+
+static bool MyObject_hasProperty(JSObjectRef object, JSCharBufferRef propertyName)
+{
+    UNUSED_PARAM(object);
+
+    if (JSCharBufferIsEqualUTF8(propertyName, "alwaysOne")
+        || JSCharBufferIsEqualUTF8(propertyName, "cantFind")
+        || JSCharBufferIsEqualUTF8(propertyName, "myPropertyName")) {
+        return true;
+    }
+    
+    return false;
+}
+
+static bool MyObject_getProperty(JSObjectRef object, JSCharBufferRef propertyName, JSValueRef* returnValue)
+{
+    UNUSED_PARAM(object);
+    
+    if (JSCharBufferIsEqualUTF8(propertyName, "alwaysOne")) {
+        *returnValue = JSNumberMake(1);
+        return true;
+    }
+    
+    if (JSCharBufferIsEqualUTF8(propertyName, "myPropertyName")) {
+        *returnValue = JSNumberMake(1);
+        return true;
+    }
+
+    if (JSCharBufferIsEqualUTF8(propertyName, "cantFind")) {
+        *returnValue = JSUndefinedMake();
+        return true;
+    }
+    
+    return false;
+}
+
+static bool MyObject_setProperty(JSObjectRef object, JSCharBufferRef propertyName, JSValueRef value)
+{
+    UNUSED_PARAM(object);
+    UNUSED_PARAM(value);
+
+    if (JSCharBufferIsEqualUTF8(propertyName, "cantSet"))
+        return true; // pretend we set the property in order to swallow it
+    
+    return false;
+}
+
+static bool MyObject_deleteProperty(JSObjectRef object, JSCharBufferRef propertyName)
+{
+    UNUSED_PARAM(object);
+    
+    if (JSCharBufferIsEqualUTF8(propertyName, "cantDelete"))
+        return true;
+    
+    return false;
+}
+
+static void MyObject_getPropertyList(JSObjectRef object, JSPropertyListRef propertyList)
+{
+    JSCharBufferRef propertyNameBuf;
+    
+    propertyNameBuf = JSCharBufferCreateUTF8("alwaysOne");
+    JSPropertyListAdd(propertyList, object, propertyNameBuf);
+    JSCharBufferRelease(propertyNameBuf);
+    
+    propertyNameBuf = JSCharBufferCreateUTF8("myPropertyName");
+    JSPropertyListAdd(propertyList, object, propertyNameBuf);
+    JSCharBufferRelease(propertyNameBuf);
+}
+
+static JSValueRef MyObject_callAsFunction(JSContextRef context, JSObjectRef object, JSObjectRef thisObject, size_t argc, JSValueRef argv[])
+{
+    UNUSED_PARAM(context);
+    UNUSED_PARAM(object);
+    UNUSED_PARAM(thisObject);
+
+    if (argc > 0 && JSValueIsStrictEqual(context, argv[0], JSNumberMake(0)))
+        return JSNumberMake(1);
+    
+    return JSUndefinedMake();
+}
+
+static JSObjectRef MyObject_callAsConstructor(JSContextRef context, JSObjectRef object, size_t argc, JSValueRef argv[])
+{
+    UNUSED_PARAM(context);
+    UNUSED_PARAM(object);
+
+    if (argc > 0 && JSValueIsStrictEqual(context, argv[0], JSNumberMake(0)))
+        return JSValueToObject(context, JSNumberMake(1));
+    
+    return JSValueToObject(context, JSNumberMake(0));
+}
+
+static bool MyObject_convertToType(JSObjectRef object, JSTypeCode typeCode, JSValueRef* returnValue)
+{
+    UNUSED_PARAM(object);
+    
+    switch (typeCode) {
+    case kJSTypeBoolean:
+        *returnValue = JSBooleanMake(false); // default object conversion is 'true'
+        return true;
+    case kJSTypeNumber:
+        *returnValue = JSNumberMake(1);
+        return true;
+    default:
+        break;
+    }
+
+    // string
+    return false;
+}
+
+static bool didFinalize = false;
+static void MyObject_finalize(JSObjectRef object)
+{
+    UNUSED_PARAM(context);
+    UNUSED_PARAM(object);
+    didFinalize = true;
+}
+
+JSObjectCallbacks MyObjectCallbacks = {
+    0,
+    0,
+    &MyObject_initialize,
+    &MyObject_finalize,
+    &MyObject_copyDescription,
+    &MyObject_hasProperty,
+    &MyObject_getProperty,
+    &MyObject_setProperty,
+    &MyObject_deleteProperty,
+    &MyObject_getPropertyList,
+    &MyObject_callAsFunction,
+    &MyObject_callAsConstructor,
+    &MyObject_convertToType,
+};
+
+static JSValueRef print_callAsFunction(JSContextRef context, JSObjectRef functionObject, JSObjectRef thisObject, size_t argc, JSValueRef argv[])
+{
+    UNUSED_PARAM(functionObject);
+    UNUSED_PARAM(thisObject);
+    
+    if (argc > 0) {
+        JSCharBufferRef string = JSValueCopyStringValue(context, argv[0]);
+        size_t sizeUTF8 = JSCharBufferGetMaxLengthUTF8(string);
+        char stringUTF8[sizeUTF8];
+        JSCharBufferGetCharactersUTF8(string, stringUTF8, sizeUTF8);
+        printf("%s\n", stringUTF8);
+        JSCharBufferRelease(string);
+    }
+    
+    return JSUndefinedMake();
+}
+
+static char* createStringWithContentsOfFile(const char* fileName);
+
+int main(int argc, char* argv[])
+{
+    UNUSED_PARAM(argc);
+    UNUSED_PARAM(argv);
+    
+    context = JSContextCreate(&kJSObjectCallbacksNone, 0);
+
+    JSValueRef jsUndefined = JSUndefinedMake();
+    JSValueRef jsNull = JSNullMake();
+    JSValueRef jsTrue = JSBooleanMake(true);
+    JSValueRef jsFalse = JSBooleanMake(false);
+    JSValueRef jsZero = JSNumberMake(0);
+    JSValueRef jsOne = JSNumberMake(1);
+    JSValueRef jsOneThird = JSNumberMake(1.0 / 3.0);
+    // FIXME: test funny utf8 characters
+    JSCharBufferRef jsEmptyStringBuf = JSCharBufferCreateUTF8("");
+    JSValueRef jsEmptyString = JSStringMake(jsEmptyStringBuf);
+    
+    JSCharBufferRef jsOneStringBuf = JSCharBufferCreateUTF8("1");
+    JSValueRef jsOneString = JSStringMake(jsOneStringBuf);
+
+#if defined(__APPLE__)
+    UniChar singleUniChar = 65; // Capital A
+    CFMutableStringRef cfString = 
+        CFStringCreateMutableWithExternalCharactersNoCopy(kCFAllocatorDefault,
+                                                          &singleUniChar,
+                                                          1,
+                                                          1,
+                                                          kCFAllocatorNull);
+
+    JSCharBufferRef jsCFStringBuf = JSCharBufferCreateWithCFString(cfString);
+    JSValueRef jsCFString = JSStringMake(jsCFStringBuf);
+    
+    CFStringRef cfEmptyString = CFStringCreateWithCString(kCFAllocatorDefault, "", kCFStringEncodingUTF8);
+    
+    JSCharBufferRef jsCFEmptyStringBuf = JSCharBufferCreateWithCFString(cfEmptyString);
+    JSValueRef jsCFEmptyString = JSStringMake(jsCFEmptyStringBuf);
+
+    CFIndex cfStringLength = CFStringGetLength(cfString);
+    UniChar buffer[cfStringLength];
+    CFStringGetCharacters(cfString, 
+                          CFRangeMake(0, cfStringLength), 
+                          buffer);
+    JSCharBufferRef jsCFStringWithCharactersBuf = JSCharBufferCreate(buffer, cfStringLength);
+    JSValueRef jsCFStringWithCharacters = JSStringMake(jsCFStringWithCharactersBuf);
+    
+    JSCharBufferRef jsCFEmptyStringWithCharactersBuf = JSCharBufferCreate(buffer, CFStringGetLength(cfEmptyString));
+    JSValueRef jsCFEmptyStringWithCharacters = JSStringMake(jsCFEmptyStringWithCharactersBuf);
+#endif // __APPLE__
+
+    assert(JSValueGetType(jsUndefined) == kJSTypeUndefined);
+    assert(JSValueGetType(jsNull) == kJSTypeNull);
+    assert(JSValueGetType(jsTrue) == kJSTypeBoolean);
+    assert(JSValueGetType(jsFalse) == kJSTypeBoolean);
+    assert(JSValueGetType(jsZero) == kJSTypeNumber);
+    assert(JSValueGetType(jsOne) == kJSTypeNumber);
+    assert(JSValueGetType(jsOneThird) == kJSTypeNumber);
+    assert(JSValueGetType(jsEmptyString) == kJSTypeString);
+    assert(JSValueGetType(jsOneString) == kJSTypeString);
+#if defined(__APPLE__)
+    assert(JSValueGetType(jsCFString) == kJSTypeString);
+    assert(JSValueGetType(jsCFStringWithCharacters) == kJSTypeString);
+    assert(JSValueGetType(jsCFEmptyString) == kJSTypeString);
+    assert(JSValueGetType(jsCFEmptyStringWithCharacters) == kJSTypeString);
+#endif // __APPLE__
+
+    assertEqualsAsBoolean(jsUndefined, false);
+    assertEqualsAsBoolean(jsNull, false);
+    assertEqualsAsBoolean(jsTrue, true);
+    assertEqualsAsBoolean(jsFalse, false);
+    assertEqualsAsBoolean(jsZero, false);
+    assertEqualsAsBoolean(jsOne, true);
+    assertEqualsAsBoolean(jsOneThird, true);
+    assertEqualsAsBoolean(jsEmptyString, false);
+    assertEqualsAsBoolean(jsOneString, true);
+#if defined(__APPLE__)
+    assertEqualsAsBoolean(jsCFString, true);
+    assertEqualsAsBoolean(jsCFStringWithCharacters, true);
+    assertEqualsAsBoolean(jsCFEmptyString, false);
+    assertEqualsAsBoolean(jsCFEmptyStringWithCharacters, false);
+#endif // __APPLE__
+    
+    assertEqualsAsNumber(jsUndefined, nan(""));
+    assertEqualsAsNumber(jsNull, 0);
+    assertEqualsAsNumber(jsTrue, 1);
+    assertEqualsAsNumber(jsFalse, 0);
+    assertEqualsAsNumber(jsZero, 0);
+    assertEqualsAsNumber(jsOne, 1);
+    assertEqualsAsNumber(jsOneThird, 1.0 / 3.0);
+    assertEqualsAsNumber(jsEmptyString, 0);
+    assertEqualsAsNumber(jsOneString, 1);
+#if defined(__APPLE__)
+    assertEqualsAsNumber(jsCFString, nan(""));
+    assertEqualsAsNumber(jsCFStringWithCharacters, nan(""));
+    assertEqualsAsNumber(jsCFEmptyString, 0);
+    assertEqualsAsNumber(jsCFEmptyStringWithCharacters, 0);
+    assert(sizeof(JSChar) == sizeof(UniChar));
+#endif // __APPLE__
+    
+    assertEqualsAsCharactersPtr(jsUndefined, "undefined");
+    assertEqualsAsCharactersPtr(jsNull, "null");
+    assertEqualsAsCharactersPtr(jsTrue, "true");
+    assertEqualsAsCharactersPtr(jsFalse, "false");
+    assertEqualsAsCharactersPtr(jsZero, "0");
+    assertEqualsAsCharactersPtr(jsOne, "1");
+    assertEqualsAsCharactersPtr(jsOneThird, "0.3333333333333333");
+    assertEqualsAsCharactersPtr(jsEmptyString, "");
+    assertEqualsAsCharactersPtr(jsOneString, "1");
+#if defined(__APPLE__)
+    assertEqualsAsCharactersPtr(jsCFString, "A");
+    assertEqualsAsCharactersPtr(jsCFStringWithCharacters, "A");
+    assertEqualsAsCharactersPtr(jsCFEmptyString, "");
+    assertEqualsAsCharactersPtr(jsCFEmptyStringWithCharacters, "");
+#endif // __APPLE__
+    
+    assertEqualsAsCharacters(jsUndefined, "undefined");
+    assertEqualsAsCharacters(jsNull, "null");
+    assertEqualsAsCharacters(jsTrue, "true");
+    assertEqualsAsCharacters(jsFalse, "false");
+    assertEqualsAsCharacters(jsZero, "0");
+    assertEqualsAsCharacters(jsOne, "1");
+    assertEqualsAsCharacters(jsOneThird, "0.3333333333333333");
+    assertEqualsAsCharacters(jsEmptyString, "");
+    assertEqualsAsCharacters(jsOneString, "1");
+#if defined(__APPLE__)
+    assertEqualsAsCharacters(jsCFString, "A");
+    assertEqualsAsCharacters(jsCFStringWithCharacters, "A");
+    assertEqualsAsCharacters(jsCFEmptyString, "");
+    assertEqualsAsCharacters(jsCFEmptyStringWithCharacters, "");
+#endif // __APPLE__
+    
+    assertEqualsAsUTF8String(jsUndefined, "undefined");
+    assertEqualsAsUTF8String(jsNull, "null");
+    assertEqualsAsUTF8String(jsTrue, "true");
+    assertEqualsAsUTF8String(jsFalse, "false");
+    assertEqualsAsUTF8String(jsZero, "0");
+    assertEqualsAsUTF8String(jsOne, "1");
+    assertEqualsAsUTF8String(jsOneThird, "0.3333333333333333");
+    assertEqualsAsUTF8String(jsEmptyString, "");
+    assertEqualsAsUTF8String(jsOneString, "1");
+#if defined(__APPLE__)
+    assertEqualsAsUTF8String(jsCFString, "A");
+    assertEqualsAsUTF8String(jsCFStringWithCharacters, "A");
+    assertEqualsAsUTF8String(jsCFEmptyString, "");
+    assertEqualsAsUTF8String(jsCFEmptyStringWithCharacters, "");
+#endif // __APPLE__
+    
+    assert(JSValueIsStrictEqual(context, jsTrue, jsTrue));
+    assert(!JSValueIsStrictEqual(context, jsOne, jsOneString));
+
+    assert(JSValueIsEqual(context, jsOne, jsOneString));
+    assert(!JSValueIsEqual(context, jsTrue, jsFalse));
+    
+#if defined(__APPLE__)
+    CFStringRef cfJSString = CFStringCreateWithJSCharBuffer(kCFAllocatorDefault, jsCFStringBuf);
+    CFStringRef cfJSEmptyString = CFStringCreateWithJSCharBuffer(kCFAllocatorDefault, jsCFEmptyStringBuf);
+    assert(CFEqual(cfJSString, cfString));
+    assert(CFEqual(cfJSEmptyString, cfEmptyString));
+    CFRelease(cfJSString);
+    CFRelease(cfJSEmptyString);
+
+    CFRelease(cfString);
+    CFRelease(cfEmptyString);
+#endif // __APPLE__
+    
+    // GDB says jsGlobalValue actually ends up being marked by the stack crawl, so this
+    // exercise is a bit academic. Not sure why that happens, or how to avoid it.
+    jsGlobalValue = JSObjectMake(context, &kJSObjectCallbacksNone, 0);
+    JSGCCollect();
+    assert(JSValueIsObject(jsGlobalValue));
+    JSGCUnprotect(jsGlobalValue);
+
+    /* JSInterpreter.h */
+    
+    JSObjectRef globalObject = JSContextGetGlobalObject(context);
+    assert(JSValueIsObject(globalObject));
+
+    JSCharBufferRef goodSyntaxBuf = JSCharBufferCreateUTF8("x = 1;");
+    JSCharBufferRef badSyntaxBuf = JSCharBufferCreateUTF8("x := 1;");
+    assert(JSCheckSyntax(context, goodSyntaxBuf));
+    assert(!JSCheckSyntax(context, badSyntaxBuf));
+
+    JSValueRef result;
+    assert(JSEvaluate(context, globalObject, goodSyntaxBuf, jsEmptyString, 0, &result));
+    assert(JSValueIsEqual(context, result, jsOne));
+    
+    assert(!JSEvaluate(context, globalObject, badSyntaxBuf, jsEmptyString, 0, &result));
+    assert(JSValueIsObject(result));
+    
+    JSContextSetException(context, JSNumberMake(1));
+    assert(JSContextHasException(context));
+    assert(JSValueIsEqual(context, jsOne, JSContextGetException(context)));
+    JSContextClearException(context);
+    assert(!JSContextHasException(context));
+
+    JSCharBufferRelease(jsEmptyStringBuf);
+    JSCharBufferRelease(jsOneStringBuf);
+#if defined(__APPLE__)
+    JSCharBufferRelease(jsCFStringBuf);
+    JSCharBufferRelease(jsCFEmptyStringBuf);
+    JSCharBufferRelease(jsCFStringWithCharactersBuf);
+    JSCharBufferRelease(jsCFEmptyStringWithCharactersBuf);
+#endif // __APPLE__
+    JSCharBufferRelease(goodSyntaxBuf);
+    JSCharBufferRelease(badSyntaxBuf);
+
+    JSObjectRef myObject = JSObjectMake(context, &MyObjectCallbacks, 0);
+    assert(didInitialize);
+    JSCharBufferRef myObjectBuf = JSCharBufferCreateUTF8("MyObject");
+    JSObjectSetProperty(context, globalObject, myObjectBuf, myObject, kJSPropertyAttributeNone);
+    JSCharBufferRelease(myObjectBuf);
+
+    JSCharBufferRef printBuf = JSCharBufferCreateUTF8("print");
+    JSObjectSetProperty(context, globalObject, printBuf, JSFunctionMake(context, print_callAsFunction), kJSPropertyAttributeNone); 
+    JSCharBufferRelease(printBuf);
+
+    char* script = createStringWithContentsOfFile("testapi.js");
+    JSCharBufferRef scriptBuf = JSCharBufferCreateUTF8(script);
+    JSEvaluate(context, globalObject, scriptBuf, jsEmptyString, 0, &result);
+    if (JSValueIsUndefined(result))
+        printf("PASS: Test script executed successfully.\n");
+    else {
+        printf("FAIL: Test script returned unexcpected value:\n");
+        JSCharBufferRef resultBuf = JSValueCopyStringValue(context, result);
+        CFStringRef resultCF = CFStringCreateWithJSCharBuffer(kCFAllocatorDefault, resultBuf);
+        CFShow(resultCF);
+        CFRelease(resultCF);
+        JSCharBufferRelease(resultBuf);
+    }
+    JSCharBufferRelease(scriptBuf);
+    free(script);
+
+    // Allocate a few dummies so that at least one will be collected
+    JSObjectMake(context, &MyObjectCallbacks, 0);
+    JSObjectMake(context, &MyObjectCallbacks, 0);
+    JSGCCollect();
+    assert(didFinalize);
+
+    JSContextDestroy(context);
+    printf("PASS: All assertions passed.\n");
+    return 0;
+}
+
+static char* createStringWithContentsOfFile(const char* fileName)
+{
+    char* buffer;
+    
+    int buffer_size = 0;
+    int buffer_capacity = 1024;
+    buffer = (char*)malloc(buffer_capacity);
+    
+    FILE* f = fopen(fileName, "r");
+    if (!f) {
+        fprintf(stderr, "Could not open file: %s\n", fileName);
+        return 0;
+    }
+    
+    while (!feof(f) && !ferror(f)) {
+        buffer_size += fread(buffer + buffer_size, 1, buffer_capacity - buffer_size, f);
+        if (buffer_size == buffer_capacity) { // guarantees space for trailing '\0'
+            buffer_capacity *= 2;
+            buffer = (char*)realloc(buffer, buffer_capacity);
+            assert(buffer);
+        }
+        
+        assert(buffer_size < buffer_capacity);
+    }
+    fclose(f);
+    buffer[buffer_size] = '\0';
+    
+    return buffer;
+}
diff --git a/JavaScriptCore/API/testapi.js b/JavaScriptCore/API/testapi.js
new file mode 100644 (file)
index 0000000..4177608
--- /dev/null
@@ -0,0 +1,78 @@
+// -*- mode: c++; c-basic-offset: 4 -*-
+/*
+ * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+function shouldBe(a, b)
+{
+    var evalA;
+    try {
+        evalA = eval(a);
+    } catch(e) {
+        evalA = e;
+    }
+    
+    if (evalA == b || isNaN(evalA) && isNaN(b))
+        print("PASS: " + a + " should be " + b + " and is.", "green");
+    else
+        print("__FAIL__: " + a + " should be " + b + " but instead is " + evalA + ".", "red");
+}
+
+shouldBe("typeof MyObject", "function"); // our object implements 'call'
+MyObject.cantFind = 1;
+shouldBe("MyObject.cantFind", undefined);
+MyObject.regularType = 1;
+shouldBe("MyObject.regularType", 1);
+MyObject.alwaysOne = 2;
+shouldBe("MyObject.alwaysOne", 1);
+MyObject.cantDelete = 1;
+delete MyObject.cantDelete;
+shouldBe("MyObject.cantDelete", 1);
+MyObject.cantSet = 1;
+shouldBe("MyObject.cantSet", undefined);
+
+var foundMyPropertyName = false;
+var foundRegularType = false;
+for (var p in MyObject) {
+    if (p == "myPropertyName")
+        foundMyPropertyName = true;
+    if (p == "regularType")
+        foundRegularType = true;
+}
+print(foundMyPropertyName
+      ? "PASS: MyObject.myPropertyName was enumerated"
+      : "__FAIL__: MyObject.myPropertyName was not enumerated");
+print(foundRegularType
+      ? "PASS: MyObject.regularType was enumerated"
+      : "__FAIL__: MyObject.regularType was not enumerated");
+
+shouldBe("delete MyObject.regularType", true);
+shouldBe("MyObject.regularType", undefined);
+shouldBe("MyObject(0)", 1);
+shouldBe("MyObject()", undefined);
+shouldBe("typeof new MyObject()", "object");
+shouldBe("MyObject ? 1 : 0", 0); // toBoolean
+shouldBe("+MyObject", 1); // toNumber
+shouldBe("(MyObject + '').indexOf('MyObject') != -1", true); // toString
+shouldBe("MyObject - 0", NaN); // toPrimitive
index 1b5b8da..9f41a83 100644 (file)
@@ -1,3 +1,170 @@
+2006-06-21  Geoffrey Garen  <ggaren@apple.com>
+
+        Reviewed by Anders.
+        
+        - First cut at C API to JavaScript. Includes a unit test, 'testapi.c', 
+        and the outline of a test app, 'minidom.c'.
+        
+        Includes one change to JSC internals: Rename propList to getPropertyList and have it
+        take its target property list by reference so that subclasses can
+        add properties to the list before calling through to their superclasses.
+        
+        Also, I just ran prepare-ChangeLog in about 10 seconds, and I would like
+        to give a shout-out to that.
+        
+        * API/APICast.h: Added.
+        (toJS):
+        (toRef):
+        * API/JSBase.h: Added.
+        * API/JSCallbackObject.cpp: Added.
+        (KJS::):
+        (KJS::JSCallbackObject::JSCallbackObject):
+        (KJS::JSCallbackObject::~JSCallbackObject):
+        (KJS::JSCallbackObject::className):
+        (KJS::JSCallbackObject::getOwnPropertySlot):
+        (KJS::JSCallbackObject::put):
+        (KJS::JSCallbackObject::deleteProperty):
+        (KJS::JSCallbackObject::implementsConstruct):
+        (KJS::JSCallbackObject::construct):
+        (KJS::JSCallbackObject::implementsCall):
+        (KJS::JSCallbackObject::callAsFunction):
+        (KJS::JSCallbackObject::getPropertyList):
+        (KJS::JSCallbackObject::toBoolean):
+        (KJS::JSCallbackObject::toNumber):
+        (KJS::JSCallbackObject::toString):
+        (KJS::JSCallbackObject::setPrivate):
+        (KJS::JSCallbackObject::getPrivate):
+        (KJS::JSCallbackObject::cachedValueGetter):
+        (KJS::JSCallbackObject::callbackGetter):
+        * API/JSCallbackObject.h: Added.
+        (KJS::JSCallbackObject::classInfo):
+        * API/JSCharBufferRef.cpp: Added.
+        (JSStringMake):
+        (JSCharBufferCreate):
+        (JSCharBufferCreateUTF8):
+        (JSCharBufferRetain):
+        (JSCharBufferRelease):
+        (JSValueCopyStringValue):
+        (JSCharBufferGetLength):
+        (JSCharBufferGetCharactersPtr):
+        (JSCharBufferGetCharacters):
+        (JSCharBufferGetMaxLengthUTF8):
+        (JSCharBufferGetCharactersUTF8):
+        (JSCharBufferIsEqual):
+        (JSCharBufferIsEqualUTF8):
+        (JSCharBufferCreateWithCFString):
+        (CFStringCreateWithJSCharBuffer):
+        * API/JSCharBufferRef.h: Added.
+        * API/JSContextRef.cpp: Added.
+        (JSContextCreate):
+        (JSContextDestroy):
+        (JSContextGetGlobalObject):
+        (JSEvaluate):
+        (JSCheckSyntax):
+        (JSContextHasException):
+        (JSContextGetException):
+        (JSContextClearException):
+        (JSContextSetException):
+        * API/JSContextRef.h: Added.
+        * API/JSObjectRef.cpp: Added.
+        (JSValueToObject):
+        (JSObjectMake):
+        (JSFunctionMake):
+        (JSObjectGetDescription):
+        (JSObjectGetPrototype):
+        (JSObjectSetPrototype):
+        (JSObjectHasProperty):
+        (JSObjectGetProperty):
+        (JSObjectSetProperty):
+        (JSObjectDeleteProperty):
+        (JSObjectGetPrivate):
+        (JSObjectSetPrivate):
+        (JSObjectIsFunction):
+        (JSObjectCallAsFunction):
+        (JSObjectIsConstructor):
+        (JSObjectCallAsConstructor):
+        (__JSPropertyListEnumerator::__JSPropertyListEnumerator):
+        (JSObjectCreatePropertyEnumerator):
+        (JSPropertyEnumeratorGetNext):
+        (JSPropertyEnumeratorRetain):
+        (JSPropertyEnumeratorRelease):
+        (JSPropertyListAdd):
+        * API/JSObjectRef.h: Added.
+        * API/JSValueRef.cpp: Added.
+        (JSValueGetType):
+        (JSValueIsUndefined):
+        (JSValueIsNull):
+        (JSValueIsBoolean):
+        (JSValueIsNumber):
+        (JSValueIsString):
+        (JSValueIsObject):
+        (JSValueIsEqual):
+        (JSValueIsStrictEqual):
+        (JSUndefinedMake):
+        (JSNullMake):
+        (JSBooleanMake):
+        (JSNumberMake):
+        (JSValueToBoolean):
+        (JSValueToNumber):
+        (JSGCProtect):
+        (JSGCUnprotect):
+        (JSGCCollect):
+        * API/JSValueRef.h: Added.
+        * API/JavaScriptCore.h: Added.
+        * API/minidom.c: Added.
+        (main):
+        * API/minidom.html: Added.
+        * API/minidom.js: Added.
+        * API/testapi.c: Added.
+        (assertEqualsAsBoolean):
+        (assertEqualsAsNumber):
+        (assertEqualsAsUTF8String):
+        (assertEqualsAsCharactersPtr):
+        (assertEqualsAsCharacters):
+        (MyObject_initialize):
+        (MyObject_copyDescription):
+        (MyObject_hasProperty):
+        (MyObject_getProperty):
+        (MyObject_setProperty):
+        (MyObject_deleteProperty):
+        (MyObject_getPropertyList):
+        (MyObject_callAsFunction):
+        (MyObject_callAsConstructor):
+        (MyObject_convertToType):
+        (MyObject_finalize):
+        (print_callAsFunction):
+        (main):
+        (createStringWithContentsOfFile):
+        * API/testapi.js: Added.
+        * ChangeLog:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * bindings/npruntime_impl.h:
+        * kjs/array_instance.h:
+        * kjs/array_object.cpp:
+        (ArrayInstance::getPropertyList):
+        * kjs/interpreter.cpp:
+        (KJS::Interpreter::evaluate):
+        * kjs/nodes.cpp:
+        (ForInNode::execute):
+        * kjs/object.cpp:
+        (KJS::JSObject::put):
+        (KJS::JSObject::canPut):
+        (KJS::JSObject::deleteProperty):
+        (KJS::JSObject::propertyIsEnumerable):
+        (KJS::JSObject::getPropertyAttributes):
+        (KJS::JSObject::getPropertyList):
+        * kjs/object.h:
+        * kjs/property_map.cpp:
+        (KJS::PropertyMap::get):
+        * kjs/property_map.h:
+        * kjs/scope_chain.cpp:
+        (KJS::ScopeChain::print):
+        * kjs/string_object.cpp:
+        (StringInstance::getPropertyList):
+        * kjs/string_object.h:
+        * kjs/ustring.h:
+        (KJS::UString::Rep::ref):
+
 2006-06-20  Timothy Hatcher  <timothy@apple.com>
 
         Reviewed by Geoff.
index 01b445a..cef3488 100644 (file)
@@ -23,7 +23,9 @@
                        );
                        dependencies = (
                                932F5BE70822A1C700736975 /* PBXTargetDependency */,
+                               141214BF0A49190E00480255 /* PBXTargetDependency */,
                                932F5BE90822A1C700736975 /* PBXTargetDependency */,
+                               14BD59C70A3E8FA400BAF59C /* PBXTargetDependency */,
                        );
                        name = All;
                        productName = All;
 /* End PBXAggregateTarget section */
 
 /* Begin PBXBuildFile section */
+               141211310A48794D00480255 /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 932F5BD90822A1C700736975 /* JavaScriptCore.framework */; };
+               141211340A48795800480255 /* minidom.c in Sources */ = {isa = PBXBuildFile; fileRef = 141211020A48780900480255 /* minidom.c */; };
+               142711390A460BBB0080EEEA /* JSBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 142711380A460BBB0080EEEA /* JSBase.h */; settings = {ATTRIBUTES = (Private, ); }; };
                14760864099C633800437128 /* JSImmediate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14760863099C633800437128 /* JSImmediate.cpp */; };
+               147FE3B80A3F637E00A1F3F4 /* testapi.c in Sources */ = {isa = PBXBuildFile; fileRef = 14BD5A2D0A3E91F600BAF59C /* testapi.c */; };
+               1482B6EB0A4300B300517CFC /* JSValueRef.h in Headers */ = {isa = PBXBuildFile; fileRef = 1482B6EA0A4300B300517CFC /* JSValueRef.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               1482B74D0A43032800517CFC /* JSCharBufferRef.h in Headers */ = {isa = PBXBuildFile; fileRef = 1482B74B0A43032800517CFC /* JSCharBufferRef.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               1482B74E0A43032800517CFC /* JSCharBufferRef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1482B74C0A43032800517CFC /* JSCharBufferRef.cpp */; };
+               1482B78B0A4305AB00517CFC /* APICast.h in Headers */ = {isa = PBXBuildFile; fileRef = 1482B78A0A4305AB00517CFC /* APICast.h */; };
+               1482B7E30A43076000517CFC /* JSObjectRef.h in Headers */ = {isa = PBXBuildFile; fileRef = 1482B7E10A43076000517CFC /* JSObjectRef.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               1482B7E40A43076000517CFC /* JSObjectRef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1482B7E20A43076000517CFC /* JSObjectRef.cpp */; };
                1483B58A099BC1950016E4F0 /* JSImmediate.h in Headers */ = {isa = PBXBuildFile; fileRef = 1483B589099BC1950016E4F0 /* JSImmediate.h */; settings = {ATTRIBUTES = (Private, ); }; };
                148A1627095D16BB00666D0D /* ListRefPtr.h in Headers */ = {isa = PBXBuildFile; fileRef = 148A1626095D16BB00666D0D /* ListRefPtr.h */; };
                14ABB36F099C076400E2A24F /* value.h in Headers */ = {isa = PBXBuildFile; fileRef = 14ABB36E099C076400E2A24F /* value.h */; settings = {ATTRIBUTES = (Private, ); }; };
                14ABB455099C2A0F00E2A24F /* JSType.h in Headers */ = {isa = PBXBuildFile; fileRef = 14ABB454099C2A0F00E2A24F /* JSType.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               14ABDF5F0A437FEF00ECCA01 /* JSCallbackObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 14ABDF5D0A437FEF00ECCA01 /* JSCallbackObject.h */; };
+               14ABDF600A437FEF00ECCA01 /* JSCallbackObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14ABDF5E0A437FEF00ECCA01 /* JSCallbackObject.cpp */; };
                14BD534C0A3E0AEA00BAF59C /* SavedBuiltins.h in Headers */ = {isa = PBXBuildFile; fileRef = 14BD534A0A3E0AEA00BAF59C /* SavedBuiltins.h */; settings = {ATTRIBUTES = (Private, ); }; };
                14BD53F50A3E12D800BAF59C /* ExecState.h in Headers */ = {isa = PBXBuildFile; fileRef = 14BD53F30A3E12D800BAF59C /* ExecState.h */; settings = {ATTRIBUTES = (Private, ); }; };
                14BD53F60A3E12D800BAF59C /* ExecState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14BD53F40A3E12D800BAF59C /* ExecState.cpp */; };
+               14BD59C50A3E8F9F00BAF59C /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 932F5BD90822A1C700736975 /* JavaScriptCore.framework */; };
+               14BD5A300A3E91F600BAF59C /* JSContextRef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14BD5A290A3E91F600BAF59C /* JSContextRef.cpp */; };
+               14BD5A310A3E91F600BAF59C /* JSContextRef.h in Headers */ = {isa = PBXBuildFile; fileRef = 14BD5A2A0A3E91F600BAF59C /* JSContextRef.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               14BD5A320A3E91F600BAF59C /* JSValueRef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14BD5A2B0A3E91F600BAF59C /* JSValueRef.cpp */; };
+               14BD5A340A3E91F600BAF59C /* testapi.c in Sources */ = {isa = PBXBuildFile; fileRef = 14BD5A2D0A3E91F600BAF59C /* testapi.c */; };
+               14BD5A360A3E91F600BAF59C /* JavaScriptCore.h in Headers */ = {isa = PBXBuildFile; fileRef = 14BD5A2F0A3E91F600BAF59C /* JavaScriptCore.h */; settings = {ATTRIBUTES = (Private, ); }; };
                14F137590A3A727E00F26F90 /* Context.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14F137580A3A727E00F26F90 /* Context.cpp */; };
                14F137830A3A765B00F26F90 /* context.h in Headers */ = {isa = PBXBuildFile; fileRef = 14F137820A3A765B00F26F90 /* context.h */; settings = {ATTRIBUTES = (Private, ); }; };
                652C107F08DA7B1E0020887D /* protected_reference.h in Headers */ = {isa = PBXBuildFile; fileRef = 652C107E08DA7B1E0020887D /* protected_reference.h */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXContainerItemProxy section */
+               141211350A48796100480255 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 932F5B3E0822A1C700736975;
+                       remoteInfo = JavaScriptCore;
+               };
+               141214BE0A49190E00480255 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 1412111F0A48793C00480255;
+                       remoteInfo = minidom;
+               };
+               14270B070A451DA10080EEEA /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 932F5B3E0822A1C700736975;
+                       remoteInfo = JavaScriptCore;
+               };
+               14270B0B0A451DA40080EEEA /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 932F5B3E0822A1C700736975;
+                       remoteInfo = JavaScriptCore;
+               };
+               14BD59C60A3E8FA400BAF59C /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 14BD59BE0A3E8F9000BAF59C;
+                       remoteInfo = testapi;
+               };
                65FB3F7D09D11EF300F49DEB /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
 /* End PBXContainerItemProxy section */
 
 /* Begin PBXFileReference section */
+               141211020A48780900480255 /* minidom.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = minidom.c; sourceTree = "<group>"; };
+               1412110D0A48788700480255 /* minidom.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = minidom.js; sourceTree = "<group>"; };
+               141211200A48793C00480255 /* minidom */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = minidom; sourceTree = BUILT_PRODUCTS_DIR; };
+               142711380A460BBB0080EEEA /* JSBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSBase.h; sourceTree = "<group>"; };
                14760863099C633800437128 /* JSImmediate.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSImmediate.cpp; sourceTree = "<group>"; };
+               1482B6EA0A4300B300517CFC /* JSValueRef.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSValueRef.h; sourceTree = "<group>"; };
+               1482B74B0A43032800517CFC /* JSCharBufferRef.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCharBufferRef.h; sourceTree = "<group>"; };
+               1482B74C0A43032800517CFC /* JSCharBufferRef.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSCharBufferRef.cpp; sourceTree = "<group>"; };
+               1482B78A0A4305AB00517CFC /* APICast.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = APICast.h; sourceTree = "<group>"; };
+               1482B7E10A43076000517CFC /* JSObjectRef.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSObjectRef.h; sourceTree = "<group>"; };
+               1482B7E20A43076000517CFC /* JSObjectRef.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSObjectRef.cpp; sourceTree = "<group>"; };
                1483B589099BC1950016E4F0 /* JSImmediate.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSImmediate.h; sourceTree = "<group>"; };
                148A1626095D16BB00666D0D /* ListRefPtr.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ListRefPtr.h; sourceTree = "<group>"; };
                14ABB36E099C076400E2A24F /* value.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = value.h; sourceTree = "<group>"; };
                14ABB454099C2A0F00E2A24F /* JSType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSType.h; sourceTree = "<group>"; };
+               14ABDF5D0A437FEF00ECCA01 /* JSCallbackObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCallbackObject.h; sourceTree = "<group>"; };
+               14ABDF5E0A437FEF00ECCA01 /* JSCallbackObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSCallbackObject.cpp; sourceTree = "<group>"; };
                14BD534A0A3E0AEA00BAF59C /* SavedBuiltins.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SavedBuiltins.h; sourceTree = "<group>"; };
                14BD53F30A3E12D800BAF59C /* ExecState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExecState.h; sourceTree = "<group>"; };
                14BD53F40A3E12D800BAF59C /* ExecState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExecState.cpp; sourceTree = "<group>"; };
+               14BD59BF0A3E8F9000BAF59C /* testapi */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testapi; sourceTree = BUILT_PRODUCTS_DIR; };
+               14BD5A290A3E91F600BAF59C /* JSContextRef.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JSContextRef.cpp; sourceTree = "<group>"; };
+               14BD5A2A0A3E91F600BAF59C /* JSContextRef.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSContextRef.h; sourceTree = "<group>"; };
+               14BD5A2B0A3E91F600BAF59C /* JSValueRef.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JSValueRef.cpp; sourceTree = "<group>"; };
+               14BD5A2D0A3E91F600BAF59C /* testapi.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = testapi.c; sourceTree = "<group>"; };
+               14BD5A2F0A3E91F600BAF59C /* JavaScriptCore.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JavaScriptCore.h; sourceTree = "<group>"; };
+               14D857740A4696C80032146C /* testapi.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = testapi.js; sourceTree = "<group>"; };
                14F137580A3A727E00F26F90 /* Context.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Context.cpp; sourceTree = "<group>"; };
                14F137820A3A765B00F26F90 /* context.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = context.h; sourceTree = "<group>"; };
                45E12D8806A49B0F00E9DF84 /* testkjs.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = testkjs.cpp; sourceTree = "<group>"; tabWidth = 8; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
+               1412111E0A48793C00480255 /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               141211310A48794D00480255 /* JavaScriptCore.framework in Frameworks */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               14BD59BD0A3E8F9000BAF59C /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               14BD59C50A3E8F9F00BAF59C /* JavaScriptCore.framework in Frameworks */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
                932F5BD20822A1C700736975 /* Frameworks */ = {
                        isa = PBXFrameworksBuildPhase;
                        buildActionMask = 2147483647;
                        children = (
                                932F5BD90822A1C700736975 /* JavaScriptCore.framework */,
                                932F5BE10822A1C700736975 /* testkjs */,
+                               14BD59BF0A3E8F9000BAF59C /* testapi */,
+                               141211200A48793C00480255 /* minidom */,
                        );
                        name = Products;
                        sourceTree = "<group>";
                        isa = PBXGroup;
                        children = (
                                937B63CC09E766D200A671DD /* DerivedSources.make */,
+                               1432EBD70A34CAD400717B9F /* API */,
                                65417200039E01BA0058BFEB /* kjs */,
                                65162EF108E6A21C007556CD /* wtf */,
                                51856D950562EE9C008B9D83 /* bindings */,
                        name = Frameworks;
                        sourceTree = "<group>";
                };
+               141211000A48772600480255 /* tests */ = {
+                       isa = PBXGroup;
+                       children = (
+                               14BD5A2D0A3E91F600BAF59C /* testapi.c */,
+                               14D857740A4696C80032146C /* testapi.js */,
+                               141211020A48780900480255 /* minidom.c */,
+                               1412110D0A48788700480255 /* minidom.js */,
+                       );
+                       name = tests;
+                       sourceTree = "<group>";
+               };
+               1432EBD70A34CAD400717B9F /* API */ = {
+                       isa = PBXGroup;
+                       children = (
+                               1482B78A0A4305AB00517CFC /* APICast.h */,
+                               14BD5A2F0A3E91F600BAF59C /* JavaScriptCore.h */,
+                               142711380A460BBB0080EEEA /* JSBase.h */,
+                               14ABDF5E0A437FEF00ECCA01 /* JSCallbackObject.cpp */,
+                               14ABDF5D0A437FEF00ECCA01 /* JSCallbackObject.h */,
+                               1482B74C0A43032800517CFC /* JSCharBufferRef.cpp */,
+                               1482B74B0A43032800517CFC /* JSCharBufferRef.h */,
+                               14BD5A290A3E91F600BAF59C /* JSContextRef.cpp */,
+                               14BD5A2A0A3E91F600BAF59C /* JSContextRef.h */,
+                               1482B7E20A43076000517CFC /* JSObjectRef.cpp */,
+                               1482B7E10A43076000517CFC /* JSObjectRef.h */,
+                               14BD5A2B0A3E91F600BAF59C /* JSValueRef.cpp */,
+                               1482B6EA0A4300B300517CFC /* JSValueRef.h */,
+                               141211000A48772600480255 /* tests */,
+                       );
+                       path = API;
+                       sourceTree = "<group>";
+               };
                51856D950562EE9C008B9D83 /* bindings */ = {
                        isa = PBXGroup;
                        children = (
                                935AF46E09E9D9DB00ACD1D8 /* UnusedParam.h in Headers */,
                                BCF655590A2049710038A194 /* MathExtras.h in Headers */,
                                14F137830A3A765B00F26F90 /* context.h in Headers */,
+                               14BD5A310A3E91F600BAF59C /* JSContextRef.h in Headers */,
+                               14BD5A360A3E91F600BAF59C /* JavaScriptCore.h in Headers */,
                                14BD534C0A3E0AEA00BAF59C /* SavedBuiltins.h in Headers */,
                                14BD53F50A3E12D800BAF59C /* ExecState.h in Headers */,
+                               1482B6EB0A4300B300517CFC /* JSValueRef.h in Headers */,
+                               1482B74D0A43032800517CFC /* JSCharBufferRef.h in Headers */,
+                               1482B78B0A4305AB00517CFC /* APICast.h in Headers */,
+                               1482B7E30A43076000517CFC /* JSObjectRef.h in Headers */,
+                               14ABDF5F0A437FEF00ECCA01 /* JSCallbackObject.h in Headers */,
+                               142711390A460BBB0080EEEA /* JSBase.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
 /* End PBXHeadersBuildPhase section */
 
 /* Begin PBXNativeTarget section */
+               1412111F0A48793C00480255 /* minidom */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = 141211390A48798400480255 /* Build configuration list for PBXNativeTarget "minidom" */;
+                       buildPhases = (
+                               1412111D0A48793C00480255 /* Sources */,
+                               1412111E0A48793C00480255 /* Frameworks */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                               141211360A48796100480255 /* PBXTargetDependency */,
+                       );
+                       name = minidom;
+                       productName = minidom;
+                       productReference = 141211200A48793C00480255 /* minidom */;
+                       productType = "com.apple.product-type.tool";
+               };
+               14BD59BE0A3E8F9000BAF59C /* testapi */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = 14BD59D60A3E8FC900BAF59C /* Build configuration list for PBXNativeTarget "testapi" */;
+                       buildPhases = (
+                               14BD59BC0A3E8F9000BAF59C /* Sources */,
+                               14D857B50A469C100032146C /* ShellScript */,
+                               14BD59BD0A3E8F9000BAF59C /* Frameworks */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                               14270B080A451DA10080EEEA /* PBXTargetDependency */,
+                       );
+                       name = testapi;
+                       productName = testapi;
+                       productReference = 14BD59BF0A3E8F9000BAF59C /* testapi */;
+                       productType = "com.apple.product-type.tool";
+               };
                932F5B3E0822A1C700736975 /* JavaScriptCore */ = {
                        isa = PBXNativeTarget;
                        buildConfigurationList = 149C275D08902AFE008A9EFC /* Build configuration list for PBXNativeTarget "JavaScriptCore" */;
                        buildRules = (
                        );
                        dependencies = (
+                               14270B0C0A451DA40080EEEA /* PBXTargetDependency */,
                        );
                        name = testkjs;
                        productInstallPath = /usr/local/bin;
                                932F5B3E0822A1C700736975 /* JavaScriptCore */,
                                935F69F508244FEA003D1A45 /* dftables */,
                                65FB3F6609D11E9100F49DEB /* Derived Sources */,
+                               1412111F0A48793C00480255 /* minidom */,
+                               14BD59BE0A3E8F9000BAF59C /* testapi */,
                                932F5BDA0822A1C700736975 /* testkjs */,
                                932F5BE30822A1C700736975 /* All */,
                        );
 /* End PBXProject section */
 
 /* Begin PBXShellScriptBuildPhase section */
+               14D857B50A469C100032146C /* ShellScript */ = {
+                       isa = PBXShellScriptBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       inputPaths = (
+                       );
+                       outputPaths = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+                       shellPath = /bin/sh;
+                       shellScript = "cp ${SRCROOT}/API/testapi.js ${BUILT_PRODUCTS_DIR}";
+               };
                65FB3F6509D11E9100F49DEB /* Generate Derived Sources */ = {
                        isa = PBXShellScriptBuildPhase;
                        buildActionMask = 2147483647;
 /* End PBXShellScriptBuildPhase section */
 
 /* Begin PBXSourcesBuildPhase section */
+               1412111D0A48793C00480255 /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               141211340A48795800480255 /* minidom.c in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               14BD59BC0A3E8F9000BAF59C /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               147FE3B80A3F637E00A1F3F4 /* testapi.c in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
                932F5B910822A1C700736975 /* Sources */ = {
                        isa = PBXSourcesBuildPhase;
                        buildActionMask = 2147483647;
                                93F0B3AB09BB4DC00068FCE3 /* Parser.cpp in Sources */,
                                65FB3F5009D11B2400F49DEB /* grammar.cpp in Sources */,
                                14F137590A3A727E00F26F90 /* Context.cpp in Sources */,
+                               14BD5A300A3E91F600BAF59C /* JSContextRef.cpp in Sources */,
+                               14BD5A320A3E91F600BAF59C /* JSValueRef.cpp in Sources */,
+                               14BD5A340A3E91F600BAF59C /* testapi.c in Sources */,
                                14BD53F60A3E12D800BAF59C /* ExecState.cpp in Sources */,
+                               1482B74E0A43032800517CFC /* JSCharBufferRef.cpp in Sources */,
+                               1482B7E40A43076000517CFC /* JSObjectRef.cpp in Sources */,
+                               14ABDF600A437FEF00ECCA01 /* JSCallbackObject.cpp in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
 /* End PBXSourcesBuildPhase section */
 
 /* Begin PBXTargetDependency section */
+               141211360A48796100480255 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = 932F5B3E0822A1C700736975 /* JavaScriptCore */;
+                       targetProxy = 141211350A48796100480255 /* PBXContainerItemProxy */;
+               };
+               141214BF0A49190E00480255 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = 1412111F0A48793C00480255 /* minidom */;
+                       targetProxy = 141214BE0A49190E00480255 /* PBXContainerItemProxy */;
+               };
+               14270B080A451DA10080EEEA /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = 932F5B3E0822A1C700736975 /* JavaScriptCore */;
+                       targetProxy = 14270B070A451DA10080EEEA /* PBXContainerItemProxy */;
+               };
+               14270B0C0A451DA40080EEEA /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = 932F5B3E0822A1C700736975 /* JavaScriptCore */;
+                       targetProxy = 14270B0B0A451DA40080EEEA /* PBXContainerItemProxy */;
+               };
+               14BD59C70A3E8FA400BAF59C /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = 14BD59BE0A3E8F9000BAF59C /* testapi */;
+                       targetProxy = 14BD59C60A3E8FA400BAF59C /* PBXContainerItemProxy */;
+               };
                65FB3F7E09D11EF300F49DEB /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        target = 65FB3F6609D11E9100F49DEB /* Derived Sources */;
 /* End PBXTargetDependency section */
 
 /* Begin XCBuildConfiguration section */
+               1412113A0A48798400480255 /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               COPY_PHASE_STRIP = NO;
+                               GCC_DYNAMIC_NO_PIC = NO;
+                               GCC_ENABLE_FIX_AND_CONTINUE = YES;
+                               GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+                               GCC_MODEL_TUNING = G5;
+                               GCC_OPTIMIZATION_LEVEL = 0;
+                               HEADER_SEARCH_PATHS = (
+                                       .,
+                                       icu,
+                                       "$(BUILT_PRODUCTS_DIR)/DerivedSources/JavaScriptCore",
+                               );
+                               INSTALL_PATH = "$(HOME)/bin";
+                               PREBINDING = NO;
+                               PRODUCT_NAME = minidom;
+                               ZERO_LINK = YES;
+                       };
+                       name = Debug;
+               };
+               1412113B0A48798400480255 /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               COPY_PHASE_STRIP = YES;
+                               GCC_ENABLE_FIX_AND_CONTINUE = NO;
+                               GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
+                               GCC_MODEL_TUNING = G5;
+                               HEADER_SEARCH_PATHS = (
+                                       .,
+                                       icu,
+                                       "$(BUILT_PRODUCTS_DIR)/DerivedSources/JavaScriptCore",
+                               );
+                               INSTALL_PATH = "$(HOME)/bin";
+                               PREBINDING = NO;
+                               PRODUCT_NAME = minidom;
+                               ZERO_LINK = NO;
+                       };
+                       name = Release;
+               };
+               1412113C0A48798400480255 /* Production */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               GCC_ENABLE_FIX_AND_CONTINUE = YES;
+                               GCC_MODEL_TUNING = G5;
+                               HEADER_SEARCH_PATHS = (
+                                       .,
+                                       icu,
+                                       "$(BUILT_PRODUCTS_DIR)/DerivedSources/JavaScriptCore",
+                               );
+                               INSTALL_PATH = "$(HOME)/bin";
+                               PREBINDING = NO;
+                               PRODUCT_NAME = minidom;
+                               ZERO_LINK = YES;
+                       };
+                       name = Production;
+               };
                149C275908902AFE008A9EFC /* Debug */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
                                DEBUG_DEFINES = "";
+                               DEBUG_INFORMATION_FORMAT = dwarf;
                                DYLIB_COMPATIBILITY_VERSION = 1;
                                DYLIB_CURRENT_VERSION = 1;
                                GCC_PREFIX_HEADER = JavaScriptCorePrefix.h;
                        isa = XCBuildConfiguration;
                        buildSettings = {
                                DEBUG_DEFINES = NDEBUG;
+                               DEBUG_INFORMATION_FORMAT = dwarf;
                                DYLIB_COMPATIBILITY_VERSION = 1;
                                DYLIB_CURRENT_VERSION = 1;
                                GCC_PREFIX_HEADER = JavaScriptCorePrefix.h;
                        isa = XCBuildConfiguration;
                        buildSettings = {
                                DEBUG_DEFINES = NDEBUG;
+                               DEBUG_INFORMATION_FORMAT = dwarf;
                                DYLIB_COMPATIBILITY_VERSION = 1;
                                DYLIB_CURRENT_VERSION = 1;
                                GCC_PREFIX_HEADER = JavaScriptCorePrefix.h;
                        };
                        name = Production;
                };
+               14BD59D70A3E8FC900BAF59C /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               COPY_PHASE_STRIP = NO;
+                               DEBUG_INFORMATION_FORMAT = stabs;
+                               GCC_DYNAMIC_NO_PIC = NO;
+                               GCC_ENABLE_FIX_AND_CONTINUE = YES;
+                               GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+                               GCC_MODEL_TUNING = G5;
+                               GCC_OPTIMIZATION_LEVEL = 0;
+                               HEADER_SEARCH_PATHS = (
+                                       .,
+                                       icu,
+                                       "$(BUILT_PRODUCTS_DIR)/DerivedSources/JavaScriptCore",
+                               );
+                               INSTALL_PATH = "$(HOME)/bin";
+                               PREBINDING = NO;
+                               PRODUCT_NAME = testapi;
+                               ZERO_LINK = YES;
+                       };
+                       name = Debug;
+               };
+               14BD59D80A3E8FC900BAF59C /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               COPY_PHASE_STRIP = YES;
+                               DEBUG_INFORMATION_FORMAT = stabs;
+                               GCC_ENABLE_FIX_AND_CONTINUE = NO;
+                               GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
+                               GCC_MODEL_TUNING = G5;
+                               HEADER_SEARCH_PATHS = (
+                                       .,
+                                       icu,
+                                       "$(BUILT_PRODUCTS_DIR)/DerivedSources/JavaScriptCore",
+                               );
+                               INSTALL_PATH = "$(HOME)/bin";
+                               PREBINDING = NO;
+                               PRODUCT_NAME = testapi;
+                               ZERO_LINK = NO;
+                       };
+                       name = Release;
+               };
+               14BD59D90A3E8FC900BAF59C /* Production */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               DEBUG_INFORMATION_FORMAT = stabs;
+                               GCC_ENABLE_FIX_AND_CONTINUE = YES;
+                               GCC_MODEL_TUNING = G5;
+                               HEADER_SEARCH_PATHS = (
+                                       .,
+                                       icu,
+                                       "$(BUILT_PRODUCTS_DIR)/DerivedSources/JavaScriptCore",
+                               );
+                               INSTALL_PATH = "$(HOME)/bin";
+                               PREBINDING = NO;
+                               PRODUCT_NAME = testapi;
+                               ZERO_LINK = YES;
+                       };
+                       name = Production;
+               };
                65FB3F7809D11EBD00F49DEB /* Debug */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
 /* End XCBuildConfiguration section */
 
 /* Begin XCConfigurationList section */
+               141211390A48798400480255 /* Build configuration list for PBXNativeTarget "minidom" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               1412113A0A48798400480255 /* Debug */,
+                               1412113B0A48798400480255 /* Release */,
+                               1412113C0A48798400480255 /* Production */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Production;
+               };
                149C275808902AFE008A9EFC /* Build configuration list for PBXNativeTarget "dftables" */ = {
                        isa = XCConfigurationList;
                        buildConfigurations = (
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Production;
                };
+               14BD59D60A3E8FC900BAF59C /* Build configuration list for PBXNativeTarget "testapi" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               14BD59D70A3E8FC900BAF59C /* Debug */,
+                               14BD59D80A3E8FC900BAF59C /* Release */,
+                               14BD59D90A3E8FC900BAF59C /* Production */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Production;
+               };
                65FB3F7709D11EBD00F49DEB /* Build configuration list for PBXAggregateTarget "Derived Sources" */ = {
                        isa = XCConfigurationList;
                        buildConfigurations = (
index 913478f..bb4cc73 100644 (file)
@@ -16,8 +16,8 @@
  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
                                       * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
                                       * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
index 4eeb536..f3b13e6 100644 (file)
@@ -39,7 +39,7 @@ namespace KJS {
     virtual void put(ExecState *exec, unsigned propertyName, JSValue *value, int attr = None);
     virtual bool deleteProperty(ExecState *exec, const Identifier &propertyName);
     virtual bool deleteProperty(ExecState *exec, unsigned propertyName);
-    virtual ReferenceList propList(ExecState *exec, bool recursive);
+    virtual void getPropertyList(ExecState*, ReferenceList& propertyList, bool recursive);
 
     virtual void mark();
 
index 89c7f89..e71e290 100644 (file)
@@ -198,10 +198,8 @@ bool ArrayInstance::deleteProperty(ExecState *exec, unsigned index)
   return JSObject::deleteProperty(exec, Identifier::from(index));
 }
 
-ReferenceList ArrayInstance::propList(ExecState *exec, bool recursive)
+void ArrayInstance::getPropertyList(ExecState* exec, ReferenceList& propertyList, bool recursive)
 {
-  ReferenceList properties = JSObject::propList(exec,recursive);
-
   // avoid fetching this every time through the loop
   JSValue *undefined = jsUndefined();
 
@@ -209,10 +207,10 @@ ReferenceList ArrayInstance::propList(ExecState *exec, bool recursive)
   for (unsigned i = 0; i < storageLength; ++i) {
     JSValue *imp = storage[i];
     if (imp && imp != undefined) {
-      properties.append(Reference(this, i));
+      propertyList.append(Reference(this, i));
     }
   }
-  return properties;
+  return JSObject::getPropertyList(exec, propertyList, recursive);
 }
 
 void ArrayInstance::resizeStorage(unsigned newLength)
index 97d1bf9..4640d9e 100644 (file)
@@ -420,9 +420,9 @@ bool Interpreter::checkSyntax(const UString &code)
     return progNode;
 }
 
-Completion Interpreter::evaluate(const UString& sourceURL, int startingLineNumber, const UString& code, JSValue*)
+Completion Interpreter::evaluate(const UString& sourceURL, int startingLineNumber, const UString& code, JSValue* thisV)
 {
-    return evaluate(sourceURL, startingLineNumber, code.data(), code.size());
+    return evaluate(sourceURL, startingLineNumber, code.data(), code.size(), thisV);
 }
 
 Completion Interpreter::evaluate(const UString& sourceURL, int startingLineNumber, const UChar* code, int codeLength, JSValue* thisV)
index bce9eb0..3dce9dc 100644 (file)
@@ -1858,7 +1858,7 @@ Completion ForInNode::execute(ExecState *exec)
   JSValue *retval = 0;
   JSObject *v;
   Completion c;
-  ReferenceList propList;
+  ReferenceList propertyList;
 
   if (varDecl) {
     varDecl->evaluate(exec);
@@ -1877,11 +1877,11 @@ Completion ForInNode::execute(ExecState *exec)
 
   KJS_CHECKEXCEPTION
   v = e->toObject(exec);
-  propList = v->propList(exec);
+  v->getPropertyList(exec, propertyList);
 
-  ReferenceListIterator propIt = propList.begin();
+  ReferenceListIterator propIt = propertyList.begin();
 
-  while (propIt != propList.end()) {
+  while (propIt != propertyList.end()) {
     Identifier name = propIt->getPropertyName(exec);
     if (!v->hasProperty(exec, name)) {
       propIt++;
index 8360c01..0b6d90d 100644 (file)
@@ -236,7 +236,7 @@ void JSObject::put(ExecState *exec, const Identifier &propertyName, JSValue *val
   if (hasGettersOrSetters) {
     obj = this;
     while (true) {
-      int attributes;
+      unsigned attributes;
       if (JSValue *gs = obj->_prop.get(propertyName, attributes)) {
         if (attributes & GetterSetter) {
           JSObject *setterFunc = static_cast<GetterSetterImp *>(gs)->getSetter();
@@ -277,7 +277,7 @@ void JSObject::put(ExecState *exec, unsigned propertyName,
 // ECMA 8.6.2.3
 bool JSObject::canPut(ExecState *, const Identifier &propertyName) const
 {
-  int attributes;
+  unsigned attributes;
     
   // Don't look in the prototype here. We can always put an override
   // in the object, even if the prototype has a ReadOnly property.
@@ -304,7 +304,7 @@ bool JSObject::hasProperty(ExecState *exec, unsigned propertyName) const
 // ECMA 8.6.2.5
 bool JSObject::deleteProperty(ExecState */*exec*/, const Identifier &propertyName)
 {
-  int attributes;
+  unsigned attributes;
   JSValue *v = _prop.get(propertyName, attributes);
   if (v) {
     if ((attributes & DontDelete))
@@ -452,7 +452,7 @@ bool JSObject::hasInstance(ExecState *, JSValue *)
 
 bool JSObject::propertyIsEnumerable(ExecState*, const Identifier& propertyName) const
 {
-  int attributes;
+  unsigned attributes;
  
   if (!getPropertyAttributes(propertyName, attributes))
     return false;
@@ -460,7 +460,7 @@ bool JSObject::propertyIsEnumerable(ExecState*, const Identifier& propertyName)
     return !(attributes & DontEnum);
 }
 
-bool JSObject::getPropertyAttributes(const Identifier& propertyName, int& attributes) const
+bool JSObject::getPropertyAttributes(const Identifier& propertyName, unsigned& attributes) const
 {
   if (_prop.get(propertyName, attributes))
     return true;
@@ -475,13 +475,9 @@ bool JSObject::getPropertyAttributes(const Identifier& propertyName, int& attrib
   return false;
 }
 
-ReferenceList JSObject::propList(ExecState *exec, bool recursive)
+void JSObject::getPropertyList(ExecState *exec, ReferenceList& propertyList, bool recursive)
 {
-  ReferenceList list;
-  if (_proto->isObject() && recursive)
-    list = static_cast<JSObject*>(_proto)->propList(exec,recursive);
-
-  _prop.addEnumerablesToReferenceList(list, this);
+  _prop.addEnumerablesToReferenceList(propertyList, this);
 
   // Add properties from the static hashtable of properties
   const ClassInfo *info = classInfo();
@@ -491,13 +487,13 @@ ReferenceList JSObject::propList(ExecState *exec, bool recursive)
       const HashEntry *e = info->propHashTable->entries;
       for (int i = 0; i < size; ++i, ++e) {
         if ( e->s && !(e->attr & DontEnum) )
-          list.append(Reference(this, e->s)); /// ######### check for duplicates with the propertymap
+          propertyList.append(Reference(this, e->s)); /// ######### check for duplicates with the propertymap
       }
     }
     info = info->parentClass;
   }
-
-  return list;
+  if (_proto->isObject() && recursive)
+      static_cast<JSObject*>(_proto)->getPropertyList(exec, propertyList, recursive);
 }
 
 bool JSObject::toBoolean(ExecState */*exec*/) const
index 115af08..d0c2845 100644 (file)
@@ -456,7 +456,7 @@ namespace KJS {
      * included in the list.
      * @return A List of References to properties of the object.
      **/
-    virtual ReferenceList propList(ExecState *exec, bool recursive = true);
+    virtual void getPropertyList(ExecState *exec, ReferenceList& propertyList, bool recursive = true);
 
     /**
      * Returns the internal value of the object. This is used for objects such
@@ -477,13 +477,13 @@ namespace KJS {
      */
     void setInternalValue(JSValue *v);
 
-    JSValue *toPrimitive(ExecState *exec, JSType preferredType = UnspecifiedType) const;
-    bool toBoolean(ExecState *exec) const;
-    double toNumber(ExecState *exec) const;
-    UString toString(ExecState *exec) const;
-    JSObject *toObject(ExecState *exec) const;
+    virtual JSValue *toPrimitive(ExecState *exec, JSType preferredType = UnspecifiedType) const;
+    virtual bool toBoolean(ExecState *exec) const;
+    virtual double toNumber(ExecState *exec) const;
+    virtual UString toString(ExecState *exec) const;
+    virtual JSObject *toObject(ExecState *exec) const;
     
-    bool getPropertyAttributes(const Identifier& propertyName, int& attributes) const;
+    bool getPropertyAttributes(const Identifier& propertyName, unsigned& attributes) const;
     
     // Returns whether the object should be treated as undefined when doing equality comparisons
     virtual bool masqueradeAsUndefined() const { return false; }
index fa400d8..7b3cba5 100644 (file)
@@ -159,7 +159,7 @@ void PropertyMap::clear()
     _table->sentinelCount = 0;
 }
 
-JSValue *PropertyMap::get(const Identifier &name, int &attributes) const
+JSValue *PropertyMap::get(const Identifier &name, unsigned &attributes) const
 {
     assert(!name.isNull());
     
index 8f9de08..7591b7e 100644 (file)
@@ -76,7 +76,7 @@ namespace KJS {
         void put(const Identifier &name, JSValue *value, int attributes, bool roCheck = false);
         void remove(const Identifier &name);
         JSValue *get(const Identifier &name) const;
-        JSValue *get(const Identifier &name, int &attributes) const;
+        JSValue *get(const Identifier &name, unsigned &attributes) const;
         JSValue **getLocation(const Identifier &name);
 
         void mark() const;
index 72ad595..720b4a0 100644 (file)
@@ -42,11 +42,12 @@ void ScopeChain::print(ExecState* exec)
     ScopeChainIterator scopeEnd = end();
     for (ScopeChainIterator scopeIter = begin(); scopeIter != scopeEnd; ++scopeIter) {
         JSObject* o = *scopeIter;
-        ReferenceList propList = o->propList(exec, false);
-        ReferenceListIterator propEnd = propList.end();
+        ReferenceList propertyList;
+        o->getPropertyList(exec, propertyList, false);
+        ReferenceListIterator propEnd = propertyList.end();
 
         fprintf(stderr, "----- [scope %p] -----\n", o);
-        for (ReferenceListIterator propIter = propList.begin(); propIter != propEnd; propIter++) {
+        for (ReferenceListIterator propIter = propertyList.begin(); propIter != propEnd; propIter++) {
             Identifier name = propIter->getPropertyName(exec);
             fprintf(stderr, "%s, ", name.ascii());
         }
index fa97f76..43c5afa 100644 (file)
@@ -94,15 +94,13 @@ bool StringInstance::deleteProperty(ExecState *exec, const Identifier &propertyN
   return JSObject::deleteProperty(exec, propertyName);
 }
 
-ReferenceList StringInstance::propList(ExecState *exec, bool recursive)
+void StringInstance::getPropertyList(ExecState *exec, ReferenceList& propertyList, bool recursive)
 {
-  ReferenceList properties = JSObject::propList(exec,recursive);
-
   //### FIXME: should avoid duplicates with prototype
   UString str = internalValue()->toString(exec);
   for (int i = 0; i < str.size(); i++)
-    properties.append(Reference(this, i));
-  return properties;
+    propertyList.append(Reference(this, i));
+  return JSObject::getPropertyList(exec, propertyList, recursive);
 }
 
 // ------------------------------ StringPrototype ---------------------------
index cef1917..e4f370e 100644 (file)
@@ -34,7 +34,7 @@ namespace KJS {
     virtual bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&);
     virtual void put(ExecState *exec, const Identifier &propertyName, JSValue *value, int attr = None);
     virtual bool deleteProperty(ExecState *exec, const Identifier &propertyName);
-    virtual ReferenceList propList(ExecState *exec, bool recursive);
+    virtual void getPropertyList(ExecState *exec, ReferenceList& propertyList, bool recursive);
 
     virtual const ClassInfo *classInfo() const { return &info; }
     static const ClassInfo info;
index d24d9c8..53a0827 100644 (file)
@@ -192,7 +192,7 @@ namespace KJS {
       static unsigned computeHash(const UChar *, int length);
       static unsigned computeHash(const char *);
 
-      void ref() { ++rc; }
+      Rep* ref() { ++rc; return this; }
       void deref() { if (--rc == 0) destroy(); }
 
       // unshared data
index ca78b57..f341618 100644 (file)
@@ -1,3 +1,19 @@
+2006-06-20  Geoffrey Garen  <ggaren@apple.com>
+
+        Reviewed by Anders.
+        
+        - Required for JS API: Rename propList to getPropertyList and have it
+        take its target property list by reference so that subclasses can
+        add properties to the list before calling through to their superclasses.
+
+        * JSUtils.cpp:
+        (KJSValueToCFTypeInternal):
+        * JSValueWrapper.cpp:
+        (JSValueWrapper::JSObjectCopyPropertyNames):
+        * UserObjectImp.cpp:
+        (UserObjectImp::getPropertyList):
+        * UserObjectImp.h:
+
 2006-06-15  Timothy Hatcher  <timothy@apple.com>
 
         Reviewed by Geoff and Darin.
index 36fdaed..7883309 100644 (file)
@@ -34,7 +34,7 @@
 #include "UserObjectImp.h"
 #include "JSValueWrapper.h"
 #include "JSObject.h"
-#include "JavaScriptCore/reference_list.h"
+#include <JavaScriptCore/reference_list.h>
 
 struct ObjectImpList {
     JSObject* imp;
@@ -294,7 +294,8 @@ CFTypeRef KJSValueToCFTypeInternal(JSValue *inValue, ExecState *exec, ObjectImpL
                         isArray = true;
                         JSInterpreter* intrepreter = (JSInterpreter*)exec->dynamicInterpreter();
                         if (intrepreter && (intrepreter->Flags() & kJSFlagConvertAssociativeArray)) {
-                            ReferenceList propList = object->propList(exec);
+                            ReferenceList propList;
+                            object->getPropertyList(exec, propList);
                             ReferenceListIterator iter = propList.begin();
                             ReferenceListIterator end = propList.end();
                             while(iter != end && isArray)
@@ -332,7 +333,8 @@ CFTypeRef KJSValueToCFTypeInternal(JSValue *inValue, ExecState *exec, ObjectImpL
                     else
                     {
                         // Not an array, just treat it like a dictionary which contains (property name, property value) pairs
-                        ReferenceList propList = object->propList(exec);
+                        ReferenceList propList;
+                        object->getPropertyList(exec, propList);
                         {
                             result = CFDictionaryCreateMutable(0,
                                                                0,
index 401355d..c6c5ea0 100644 (file)
@@ -117,10 +117,11 @@ CFArrayRef JSValueWrapper::JSObjectCopyPropertyNames(void *data)
     {
         ExecState* exec = getThreadGlobalExecState();
         JSObject *object = ptr->GetValue()->toObject(exec);
-        ReferenceList list = object->propList(exec);
-        ReferenceListIterator iterator = list.begin();
+        ReferenceList propList;
+        object->getPropertyList(exec, propList);
+        ReferenceListIterator iterator = propList.begin();
 
-        while (iterator != list.end()) {
+        while (iterator != propList.end()) {
             Identifier name = iterator->getPropertyName(exec);
             CFStringRef nameStr = IdentifierToCFString(name);
 
index bd55d74..202592f 100644 (file)
@@ -28,7 +28,7 @@
 
 #include "config.h"
 #include "UserObjectImp.h"
-#include "JavaScriptCore/reference_list.h"
+#include <JavaScriptCore/reference_list.h>
 
 const ClassInfo UserObjectImp::info = {"UserObject", 0, 0, 0};
 
@@ -122,9 +122,8 @@ JSValue *UserObjectImp::callAsFunction(ExecState *exec, JSObject *thisObj, const
 }
 
 
-ReferenceList UserObjectImp::propList(ExecState *exec, bool recursive)
+void UserObjectImp::getPropertyList(ExecState *exec, ReferenceList& propertyList, bool recursive)
 {
-    ReferenceList list = JSObject::propList(exec, recursive);
     JSUserObject* ptr = GetJSUserObject();
     if (ptr) {
         CFArrayRef cfPropertyNames = ptr->CopyPropertyNames();
@@ -133,13 +132,12 @@ ReferenceList UserObjectImp::propList(ExecState *exec, bool recursive)
             CFIndex i;
             for (i = 0; i < count; i++) {
                 CFStringRef propertyName = (CFStringRef)CFArrayGetValueAtIndex(cfPropertyNames, i);
-                list.append(Reference(this, CFStringToIdentifier(propertyName)));
+                propertyList.append(Reference(this, CFStringToIdentifier(propertyName)));
             }
             CFRelease(cfPropertyNames);
         }
     }
-
-    return list;
+    JSObject::getPropertyList(exec, propertyList, recursive);
 }
 
 JSValue *UserObjectImp::userObjectGetter(ExecState *, JSObject *, const Identifier& propertyName, const PropertySlot& slot)
index 318c18b..e046123 100644 (file)
@@ -44,7 +44,7 @@ public:
 
     virtual bool implementsCall() const;
 
-    virtual ReferenceList propList(ExecState *exec, bool recursive = true);
+    virtual void getPropertyList(ExecState *exec, ReferenceList& propertyList, bool recursive = true);
 
     virtual JSValue *callAsFunction(ExecState *exec, JSObject *thisObj, const List &args);
     virtual bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&);