diff options
Diffstat (limited to 'JavaScriptCore/API')
-rw-r--r-- | JavaScriptCore/API/APICast.h | 1 | ||||
-rw-r--r-- | JavaScriptCore/API/APIShims.h | 9 | ||||
-rw-r--r-- | JavaScriptCore/API/JSCallbackFunction.cpp | 1 | ||||
-rw-r--r-- | JavaScriptCore/API/JSCallbackObject.h | 124 | ||||
-rw-r--r-- | JavaScriptCore/API/JSCallbackObjectFunctions.h | 12 | ||||
-rw-r--r-- | JavaScriptCore/API/JSClassRef.cpp | 8 | ||||
-rw-r--r-- | JavaScriptCore/API/JSContextRef.cpp | 35 | ||||
-rw-r--r-- | JavaScriptCore/API/JSObjectRef.cpp | 51 | ||||
-rw-r--r-- | JavaScriptCore/API/JSObjectRefPrivate.h | 74 | ||||
-rw-r--r-- | JavaScriptCore/API/JSValueRef.cpp | 29 | ||||
-rw-r--r-- | JavaScriptCore/API/JSValueRef.h | 23 | ||||
-rw-r--r-- | JavaScriptCore/API/JSWeakObjectMapRefInternal.h | 68 | ||||
-rw-r--r-- | JavaScriptCore/API/JSWeakObjectMapRefPrivate.cpp | 83 | ||||
-rw-r--r-- | JavaScriptCore/API/JSWeakObjectMapRefPrivate.h | 95 | ||||
-rw-r--r-- | JavaScriptCore/API/WebKitAvailability.h | 166 | ||||
-rw-r--r-- | JavaScriptCore/API/tests/testapi.c | 102 |
16 files changed, 819 insertions, 62 deletions
diff --git a/JavaScriptCore/API/APICast.h b/JavaScriptCore/API/APICast.h index 4284c44..ba00d02 100644 --- a/JavaScriptCore/API/APICast.h +++ b/JavaScriptCore/API/APICast.h @@ -29,7 +29,6 @@ #include "JSAPIValueWrapper.h" #include "JSGlobalObject.h" #include "JSValue.h" -#include <wtf/Platform.h> #include <wtf/UnusedParam.h> namespace JSC { diff --git a/JavaScriptCore/API/APIShims.h b/JavaScriptCore/API/APIShims.h index 9a6cacb..3d42ca2 100644 --- a/JavaScriptCore/API/APIShims.h +++ b/JavaScriptCore/API/APIShims.h @@ -28,6 +28,7 @@ #include "CallFrame.h" #include "JSLock.h" +#include <wtf/WTFThreadData.h> namespace JSC { @@ -35,7 +36,7 @@ class APIEntryShimWithoutLock { protected: APIEntryShimWithoutLock(JSGlobalData* globalData, bool registerThread) : m_globalData(globalData) - , m_entryIdentifierTable(setCurrentIdentifierTable(globalData->identifierTable)) + , m_entryIdentifierTable(wtfThreadData().setCurrentIdentifierTable(globalData->identifierTable)) { if (registerThread) globalData->heap.registerThread(); @@ -45,7 +46,7 @@ protected: ~APIEntryShimWithoutLock() { m_globalData->timeoutChecker.stop(); - setCurrentIdentifierTable(m_entryIdentifierTable); + wtfThreadData().setCurrentIdentifierTable(m_entryIdentifierTable); } private: @@ -79,12 +80,12 @@ public: : m_dropAllLocks(exec) , m_globalData(&exec->globalData()) { - resetCurrentIdentifierTable(); + wtfThreadData().resetCurrentIdentifierTable(); } ~APICallbackShim() { - setCurrentIdentifierTable(m_globalData->identifierTable); + wtfThreadData().setCurrentIdentifierTable(m_globalData->identifierTable); } private: diff --git a/JavaScriptCore/API/JSCallbackFunction.cpp b/JavaScriptCore/API/JSCallbackFunction.cpp index 0e434d9..63c8add 100644 --- a/JavaScriptCore/API/JSCallbackFunction.cpp +++ b/JavaScriptCore/API/JSCallbackFunction.cpp @@ -24,7 +24,6 @@ */ #include "config.h" -#include <wtf/Platform.h> #include "JSCallbackFunction.h" #include "APIShims.h" diff --git a/JavaScriptCore/API/JSCallbackObject.h b/JavaScriptCore/API/JSCallbackObject.h index adb5b60..1cf7a02 100644 --- a/JavaScriptCore/API/JSCallbackObject.h +++ b/JavaScriptCore/API/JSCallbackObject.h @@ -33,6 +33,84 @@ namespace JSC { +struct JSCallbackObjectData { + JSCallbackObjectData(void* privateData, JSClassRef jsClass) + : privateData(privateData) + , jsClass(jsClass) + { + JSClassRetain(jsClass); + } + + ~JSCallbackObjectData() + { + JSClassRelease(jsClass); + } + + JSValue getPrivateProperty(const Identifier& propertyName) const + { + if (!m_privateProperties) + return JSValue(); + return m_privateProperties->getPrivateProperty(propertyName); + } + + void setPrivateProperty(const Identifier& propertyName, JSValue value) + { + if (!m_privateProperties) + m_privateProperties.set(new JSPrivatePropertyMap); + m_privateProperties->setPrivateProperty(propertyName, value); + } + + void deletePrivateProperty(const Identifier& propertyName) + { + if (!m_privateProperties) + return; + m_privateProperties->deletePrivateProperty(propertyName); + } + + void markChildren(MarkStack& markStack) + { + if (!m_privateProperties) + return; + m_privateProperties->markChildren(markStack); + } + + void* privateData; + JSClassRef jsClass; + struct JSPrivatePropertyMap { + JSValue getPrivateProperty(const Identifier& propertyName) const + { + PrivatePropertyMap::const_iterator location = m_propertyMap.find(propertyName.ustring().rep()); + if (location == m_propertyMap.end()) + return JSValue(); + return location->second; + } + + void setPrivateProperty(const Identifier& propertyName, JSValue value) + { + m_propertyMap.set(propertyName.ustring().rep(), value); + } + + void deletePrivateProperty(const Identifier& propertyName) + { + m_propertyMap.remove(propertyName.ustring().rep()); + } + + void markChildren(MarkStack& markStack) + { + for (PrivatePropertyMap::iterator ptr = m_propertyMap.begin(); ptr != m_propertyMap.end(); ++ptr) { + if (ptr->second) + markStack.append(ptr->second); + } + } + + private: + typedef HashMap<RefPtr<UString::Rep>, JSValue, IdentifierRepHash> PrivatePropertyMap; + PrivatePropertyMap m_propertyMap; + }; + OwnPtr<JSPrivatePropertyMap> m_privateProperties; +}; + + template <class Base> class JSCallbackObject : public Base { public: @@ -52,6 +130,21 @@ public: { return Structure::create(proto, TypeInfo(ObjectType, StructureFlags), Base::AnonymousSlotCount); } + + JSValue getPrivateProperty(const Identifier& propertyName) const + { + return m_callbackObjectData->getPrivateProperty(propertyName); + } + + void setPrivateProperty(const Identifier& propertyName, JSValue value) + { + m_callbackObjectData->setPrivateProperty(propertyName, value); + } + + void deletePrivateProperty(const Identifier& propertyName) + { + m_callbackObjectData->deletePrivateProperty(propertyName); + } protected: static const unsigned StructureFlags = OverridesGetOwnPropertySlot | ImplementsHasInstance | OverridesHasInstance | OverridesMarkChildren | OverridesGetPropertyNames | Base::StructureFlags; @@ -79,6 +172,12 @@ private: virtual CallType getCallData(CallData&); virtual const ClassInfo* classInfo() const { return &info; } + virtual void markChildren(MarkStack& markStack) + { + Base::markChildren(markStack); + m_callbackObjectData->markChildren(markStack); + } + void init(ExecState*); static JSCallbackObject* asCallbackObject(JSValue); @@ -86,27 +185,10 @@ private: static JSValue JSC_HOST_CALL call(ExecState*, JSObject* functionObject, JSValue thisValue, const ArgList&); static JSObject* construct(ExecState*, JSObject* constructor, const ArgList&); - static JSValue staticValueGetter(ExecState*, const Identifier&, const PropertySlot&); - static JSValue staticFunctionGetter(ExecState*, const Identifier&, const PropertySlot&); - static JSValue callbackGetter(ExecState*, const Identifier&, const PropertySlot&); - - struct JSCallbackObjectData { - JSCallbackObjectData(void* privateData, JSClassRef jsClass) - : privateData(privateData) - , jsClass(jsClass) - { - JSClassRetain(jsClass); - } - - ~JSCallbackObjectData() - { - JSClassRelease(jsClass); - } - - void* privateData; - JSClassRef jsClass; - }; - + static JSValue staticValueGetter(ExecState*, JSValue, const Identifier&); + static JSValue staticFunctionGetter(ExecState*, JSValue, const Identifier&); + static JSValue callbackGetter(ExecState*, JSValue, const Identifier&); + OwnPtr<JSCallbackObjectData> m_callbackObjectData; }; diff --git a/JavaScriptCore/API/JSCallbackObjectFunctions.h b/JavaScriptCore/API/JSCallbackObjectFunctions.h index 4b28a99..6c83eb4 100644 --- a/JavaScriptCore/API/JSCallbackObjectFunctions.h +++ b/JavaScriptCore/API/JSCallbackObjectFunctions.h @@ -516,9 +516,9 @@ bool JSCallbackObject<Base>::inherits(JSClassRef c) const } template <class Base> -JSValue JSCallbackObject<Base>::staticValueGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) +JSValue JSCallbackObject<Base>::staticValueGetter(ExecState* exec, JSValue slotBase, const Identifier& propertyName) { - JSCallbackObject* thisObj = asCallbackObject(slot.slotBase()); + JSCallbackObject* thisObj = asCallbackObject(slotBase); JSObjectRef thisRef = toRef(thisObj); RefPtr<OpaqueJSString> propertyNameRef; @@ -547,9 +547,9 @@ JSValue JSCallbackObject<Base>::staticValueGetter(ExecState* exec, const Identif } template <class Base> -JSValue JSCallbackObject<Base>::staticFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) +JSValue JSCallbackObject<Base>::staticFunctionGetter(ExecState* exec, JSValue slotBase, const Identifier& propertyName) { - JSCallbackObject* thisObj = asCallbackObject(slot.slotBase()); + JSCallbackObject* thisObj = asCallbackObject(slotBase); // Check for cached or override property. PropertySlot slot2(thisObj); @@ -572,9 +572,9 @@ JSValue JSCallbackObject<Base>::staticFunctionGetter(ExecState* exec, const Iden } template <class Base> -JSValue JSCallbackObject<Base>::callbackGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) +JSValue JSCallbackObject<Base>::callbackGetter(ExecState* exec, JSValue slotBase, const Identifier& propertyName) { - JSCallbackObject* thisObj = asCallbackObject(slot.slotBase()); + JSCallbackObject* thisObj = asCallbackObject(slotBase); JSObjectRef thisRef = toRef(thisObj); RefPtr<OpaqueJSString> propertyNameRef; diff --git a/JavaScriptCore/API/JSClassRef.cpp b/JavaScriptCore/API/JSClassRef.cpp index 717488f..3e65b75 100644 --- a/JavaScriptCore/API/JSClassRef.cpp +++ b/JavaScriptCore/API/JSClassRef.cpp @@ -33,6 +33,7 @@ #include <runtime/JSGlobalObject.h> #include <runtime/ObjectPrototype.h> #include <runtime/Identifier.h> +#include <wtf/text/StringHash.h> #include <wtf/unicode/UTF8.h> using namespace std; @@ -111,7 +112,8 @@ OpaqueJSClass::OpaqueJSClass(const JSClassDefinition* definition, OpaqueJSClass* OpaqueJSClass::~OpaqueJSClass() { - ASSERT(!m_className.rep()->isIdentifier()); + // The empty string is shared across threads & is an identifier, in all other cases we should have done a deep copy in className(), below. + ASSERT(!m_className.size() || !m_className.rep()->isIdentifier()); if (m_staticValues) { OpaqueJSClassStaticValuesTable::const_iterator end = m_staticValues->end(); @@ -171,7 +173,7 @@ OpaqueJSClassContextData::OpaqueJSClassContextData(OpaqueJSClass* jsClass) ASSERT(!it->first->isIdentifier()); // Use a local variable here to sidestep an RVCT compiler bug. StaticValueEntry* entry = new StaticValueEntry(it->second->getProperty, it->second->setProperty, it->second->attributes); - staticValues->add(UString::Rep::create(it->first->data(), it->first->length()), entry); + staticValues->add(UString::Rep::create(it->first->characters(), it->first->length()), entry); } } else staticValues = 0; @@ -183,7 +185,7 @@ OpaqueJSClassContextData::OpaqueJSClassContextData(OpaqueJSClass* jsClass) ASSERT(!it->first->isIdentifier()); // Use a local variable here to sidestep an RVCT compiler bug. StaticFunctionEntry* entry = new StaticFunctionEntry(it->second->callAsFunction, it->second->attributes); - staticFunctions->add(UString::Rep::create(it->first->data(), it->first->length()), entry); + staticFunctions->add(UString::Rep::create(it->first->characters(), it->first->length()), entry); } } else diff --git a/JavaScriptCore/API/JSContextRef.cpp b/JavaScriptCore/API/JSContextRef.cpp index 2c76338..06f9274 100644 --- a/JavaScriptCore/API/JSContextRef.cpp +++ b/JavaScriptCore/API/JSContextRef.cpp @@ -33,7 +33,7 @@ #include "JSClassRef.h" #include "JSGlobalObject.h" #include "JSObject.h" -#include <wtf/Platform.h> +#include <wtf/text/StringHash.h> #if OS(DARWIN) #include <mach-o/dyld.h> @@ -46,7 +46,7 @@ using namespace JSC; JSContextGroupRef JSContextGroupCreate() { initializeThreading(); - return toRef(JSGlobalData::createNonDefault().releaseRef()); + return toRef(JSGlobalData::createNonDefault(ThreadStackTypeSmall).releaseRef()); } JSContextGroupRef JSContextGroupRetain(JSContextGroupRef group) @@ -84,7 +84,7 @@ JSGlobalContextRef JSGlobalContextCreateInGroup(JSContextGroupRef group, JSClass initializeThreading(); JSLock lock(LockForReal); - RefPtr<JSGlobalData> globalData = group ? PassRefPtr<JSGlobalData>(toJS(group)) : JSGlobalData::createNonDefault(); + RefPtr<JSGlobalData> globalData = group ? PassRefPtr<JSGlobalData>(toJS(group)) : JSGlobalData::createNonDefault(ThreadStackTypeSmall); APIEntryShim entryShim(globalData.get(), false); @@ -123,19 +123,32 @@ void JSGlobalContextRelease(JSGlobalContextRef ctx) JSLock lock(exec); JSGlobalData& globalData = exec->globalData(); - IdentifierTable* savedIdentifierTable = setCurrentIdentifierTable(globalData.identifierTable); - - gcUnprotect(exec->dynamicGlobalObject()); - - if (globalData.refCount() == 2) { // One reference is held by JSGlobalObject, another added by JSGlobalContextRetain(). - // The last reference was released, this is our last chance to collect. + JSGlobalObject* dgo = exec->dynamicGlobalObject(); + IdentifierTable* savedIdentifierTable = wtfThreadData().setCurrentIdentifierTable(globalData.identifierTable); + + // One reference is held by JSGlobalObject, another added by JSGlobalContextRetain(). + bool releasingContextGroup = globalData.refCount() == 2; + bool releasingGlobalObject = Heap::heap(dgo)->unprotect(dgo); + // If this is the last reference to a global data, it should also + // be the only remaining reference to the global object too! + ASSERT(!releasingContextGroup || releasingGlobalObject); + + // An API 'JSGlobalContextRef' retains two things - a global object and a + // global data (or context group, in API terminology). + // * If this is the last reference to any contexts in the given context group, + // call destroy on the heap (the global data is being freed). + // * If this was the last reference to the global object, then unprotecting + // it may release a lot of GC memory - run the garbage collector now. + // * If there are more references remaining the the global object, then do nothing + // (specifically that is more protects, which we assume come from other JSGlobalContextRefs). + if (releasingContextGroup) globalData.heap.destroy(); - } else + else if (releasingGlobalObject) globalData.heap.collectAllGarbage(); globalData.deref(); - setCurrentIdentifierTable(savedIdentifierTable); + wtfThreadData().setCurrentIdentifierTable(savedIdentifierTable); } JSObjectRef JSContextGetGlobalObject(JSContextRef ctx) diff --git a/JavaScriptCore/API/JSObjectRef.cpp b/JavaScriptCore/API/JSObjectRef.cpp index faaa4eb..8fdbdab 100644 --- a/JavaScriptCore/API/JSObjectRef.cpp +++ b/JavaScriptCore/API/JSObjectRef.cpp @@ -26,6 +26,7 @@ #include "config.h" #include "JSObjectRef.h" +#include "JSObjectRefPrivate.h" #include "APICast.h" #include "CodeBlock.h" @@ -48,7 +49,6 @@ #include "ObjectPrototype.h" #include "PropertyNameArray.h" #include "RegExpConstructor.h" -#include <wtf/Platform.h> using namespace JSC; @@ -364,6 +364,55 @@ bool JSObjectSetPrivate(JSObjectRef object, void* data) return false; } +JSValueRef JSObjectGetPrivateProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName) +{ + ExecState* exec = toJS(ctx); + APIEntryShim entryShim(exec); + JSObject* jsObject = toJS(object); + JSValue result; + Identifier name(propertyName->identifier(&exec->globalData())); + if (jsObject->inherits(&JSCallbackObject<JSGlobalObject>::info)) + result = static_cast<JSCallbackObject<JSGlobalObject>*>(jsObject)->getPrivateProperty(name); + else if (jsObject->inherits(&JSCallbackObject<JSObject>::info)) + result = static_cast<JSCallbackObject<JSObject>*>(jsObject)->getPrivateProperty(name); + return toRef(exec, result); +} + +bool JSObjectSetPrivateProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef value) +{ + ExecState* exec = toJS(ctx); + APIEntryShim entryShim(exec); + JSObject* jsObject = toJS(object); + JSValue jsValue = toJS(exec, value); + Identifier name(propertyName->identifier(&exec->globalData())); + if (jsObject->inherits(&JSCallbackObject<JSGlobalObject>::info)) { + static_cast<JSCallbackObject<JSGlobalObject>*>(jsObject)->setPrivateProperty(name, jsValue); + return true; + } + if (jsObject->inherits(&JSCallbackObject<JSObject>::info)) { + static_cast<JSCallbackObject<JSObject>*>(jsObject)->setPrivateProperty(name, jsValue); + return true; + } + return false; +} + +bool JSObjectDeletePrivateProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName) +{ + ExecState* exec = toJS(ctx); + APIEntryShim entryShim(exec); + JSObject* jsObject = toJS(object); + Identifier name(propertyName->identifier(&exec->globalData())); + if (jsObject->inherits(&JSCallbackObject<JSGlobalObject>::info)) { + static_cast<JSCallbackObject<JSGlobalObject>*>(jsObject)->deletePrivateProperty(name); + return true; + } + if (jsObject->inherits(&JSCallbackObject<JSObject>::info)) { + static_cast<JSCallbackObject<JSObject>*>(jsObject)->deletePrivateProperty(name); + return true; + } + return false; +} + bool JSObjectIsFunction(JSContextRef, JSObjectRef object) { CallData callData; diff --git a/JavaScriptCore/API/JSObjectRefPrivate.h b/JavaScriptCore/API/JSObjectRefPrivate.h new file mode 100644 index 0000000..32e80ab --- /dev/null +++ b/JavaScriptCore/API/JSObjectRefPrivate.h @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2010 Apple 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 INC. AND ITS CONTRIBUTORS ``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 INC. OR ITS 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 JSObjectRefPrivate_h +#define JSObjectRefPrivate_h + +#include <JavaScriptCore/JSObjectRef.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/*! + @function + @abstract Sets a private property on an object. This private property cannot be accessed from within JavaScript. + @param ctx The execution context to use. + @param object The JSObject whose private property you want to set. + @param propertyName A JSString containing the property's name. + @param value A JSValue to use as the property's value. This may be NULL. + @result true if object can store private data, otherwise false. + @discussion This API allows you to store JS values directly an object in a way that will be ensure that they are kept alive without exposing them to JavaScript code and without introducing the reference cycles that may occur when using JSValueProtect. + + The default object class does not allocate storage for private data. Only objects created with a non-NULL JSClass can store private properties. + */ +JS_EXPORT bool JSObjectSetPrivateProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef value); + +/*! + @function + @abstract Gets a private property from an object. + @param ctx The execution context to use. + @param object The JSObject whose private property you want to get. + @param propertyName A JSString containing the property's name. + @result The property's value if object has the property, otherwise NULL. + */ +JS_EXPORT JSValueRef JSObjectGetPrivateProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName); + +/*! + @function + @abstract Deletes a private property from an object. + @param ctx The execution context to use. + @param object The JSObject whose private property you want to delete. + @param propertyName A JSString containing the property's name. + @result true if object can store private data, otherwise false. + @discussion The default object class does not allocate storage for private data. Only objects created with a non-NULL JSClass can store private data. + */ +JS_EXPORT bool JSObjectDeletePrivateProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName); + +#ifdef __cplusplus +} +#endif + +#endif // JSObjectRefPrivate_h diff --git a/JavaScriptCore/API/JSValueRef.cpp b/JavaScriptCore/API/JSValueRef.cpp index a12cc34..f5dcccc 100644 --- a/JavaScriptCore/API/JSValueRef.cpp +++ b/JavaScriptCore/API/JSValueRef.cpp @@ -26,19 +26,21 @@ #include "config.h" #include "JSValueRef.h" -#include <wtf/Platform.h> #include "APICast.h" #include "APIShims.h" #include "JSCallbackObject.h" #include <runtime/JSGlobalObject.h> +#include <runtime/JSONObject.h> #include <runtime/JSString.h> +#include <runtime/LiteralParser.h> #include <runtime/Operations.h> #include <runtime/Protect.h> #include <runtime/UString.h> #include <runtime/JSValue.h> #include <wtf/Assertions.h> +#include <wtf/text/StringHash.h> #include <algorithm> // for std::min @@ -222,6 +224,31 @@ JSValueRef JSValueMakeString(JSContextRef ctx, JSStringRef string) return toRef(exec, jsString(exec, string->ustring())); } +JSValueRef JSValueMakeFromJSONString(JSContextRef ctx, JSStringRef string) +{ + ExecState* exec = toJS(ctx); + APIEntryShim entryShim(exec); + LiteralParser parser(exec, string->ustring(), LiteralParser::StrictJSON); + return toRef(exec, parser.tryLiteralParse()); +} + +JSStringRef JSValueCreateJSONString(JSContextRef ctx, JSValueRef apiValue, unsigned indent, JSValueRef* exception) +{ + ExecState* exec = toJS(ctx); + APIEntryShim entryShim(exec); + JSValue value = toJS(exec, apiValue); + UString result = JSONStringify(exec, value, indent); + if (exception) + *exception = 0; + if (exec->hadException()) { + if (exception) + *exception = toRef(exec, exec->exception()); + exec->clearException(); + return 0; + } + return OpaqueJSString::create(result).releaseRef(); +} + bool JSValueToBoolean(JSContextRef ctx, JSValueRef value) { ExecState* exec = toJS(ctx); diff --git a/JavaScriptCore/API/JSValueRef.h b/JavaScriptCore/API/JSValueRef.h index 7a7bf93..4186db8 100644 --- a/JavaScriptCore/API/JSValueRef.h +++ b/JavaScriptCore/API/JSValueRef.h @@ -27,6 +27,7 @@ #define JSValueRef_h #include <JavaScriptCore/JSBase.h> +#include <JavaScriptCore/WebKitAvailability.h> #ifndef __cplusplus #include <stdbool.h> @@ -208,6 +209,28 @@ JS_EXPORT JSValueRef JSValueMakeNumber(JSContextRef ctx, double number); */ JS_EXPORT JSValueRef JSValueMakeString(JSContextRef ctx, JSStringRef string); +/* Converting to and from JSON formatted strings */ + +/*! + @function + @abstract Creates a JavaScript value from a JSON formatted string. + @param ctx The execution context to use. + @param string The JSString containing the JSON string to be parsed. + @result A JSValue containing the parsed value, or NULL if the input is invalid. + */ +JS_EXPORT JSValueRef JSValueMakeFromJSONString(JSContextRef ctx, JSStringRef string) AVAILABLE_AFTER_WEBKIT_VERSION_4_0; + +/*! + @function + @abstract Creates a JavaScript string containing the JSON serialized representation of a JS value. + @param ctx The execution context to use. + @param value The value to serialize. + @param indent The number of spaces to indent when nesting. If 0, the resulting JSON will not contains newlines. The size of the indent is clamped to 10 spaces. + @param exception A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception. + @result A JSString with the result of serialization, or NULL if an exception is thrown. + */ +JS_EXPORT JSStringRef JSValueCreateJSONString(JSContextRef ctx, JSValueRef value, unsigned indent, JSValueRef* exception) AVAILABLE_AFTER_WEBKIT_VERSION_4_0; + /* Converting to primitive values */ /*! diff --git a/JavaScriptCore/API/JSWeakObjectMapRefInternal.h b/JavaScriptCore/API/JSWeakObjectMapRefInternal.h new file mode 100644 index 0000000..64e1f4d --- /dev/null +++ b/JavaScriptCore/API/JSWeakObjectMapRefInternal.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2010 Apple 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 INC. AND ITS CONTRIBUTORS ``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 INC. OR ITS 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 JSWeakObjectMapRefInternal_h +#define JSWeakObjectMapRefInternal_h + +#include "WeakGCMap.h" +#include <wtf/RefCounted.h> + +namespace JSC { + +class JSObject; + +} + +typedef void (*JSWeakMapDestroyedCallback)(struct OpaqueJSWeakObjectMap*, void*); + +typedef JSC::WeakGCMap<void*, JSC::JSObject*> WeakMapType; + +struct OpaqueJSWeakObjectMap : public RefCounted<OpaqueJSWeakObjectMap> { +public: + static PassRefPtr<OpaqueJSWeakObjectMap> create(void* data, JSWeakMapDestroyedCallback callback) + { + return adoptRef(new OpaqueJSWeakObjectMap(data, callback)); + } + + WeakMapType& map() { return m_map; } + + ~OpaqueJSWeakObjectMap() + { + m_callback(this, m_data); + } + +private: + OpaqueJSWeakObjectMap(void* data, JSWeakMapDestroyedCallback callback) + : m_data(data) + , m_callback(callback) + { + } + WeakMapType m_map; + void* m_data; + JSWeakMapDestroyedCallback m_callback; +}; + + +#endif // JSWeakObjectMapInternal_h diff --git a/JavaScriptCore/API/JSWeakObjectMapRefPrivate.cpp b/JavaScriptCore/API/JSWeakObjectMapRefPrivate.cpp new file mode 100644 index 0000000..e377ea0 --- /dev/null +++ b/JavaScriptCore/API/JSWeakObjectMapRefPrivate.cpp @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2010 Apple 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 INC. AND ITS CONTRIBUTORS ``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 INC. OR ITS 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 "config.h" +#include "JSWeakObjectMapRefPrivate.h" + +#include "APICast.h" +#include "APIShims.h" +#include "JSCallbackObject.h" +#include "JSValue.h" +#include "JSWeakObjectMapRefInternal.h" +#include <wtf/HashMap.h> +#include <wtf/RefCounted.h> + +using namespace WTF; +using namespace JSC; + +#ifdef __cplusplus +extern "C" { +#endif + +JSWeakObjectMapRef JSWeakObjectMapCreate(JSContextRef context, void* privateData, JSWeakMapDestroyedCallback callback) +{ + ExecState* exec = toJS(context); + APIEntryShim entryShim(exec); + RefPtr<OpaqueJSWeakObjectMap> map = OpaqueJSWeakObjectMap::create(privateData, callback); + exec->lexicalGlobalObject()->registerWeakMap(map.get()); + return map.get(); +} + +void JSWeakObjectMapSet(JSContextRef ctx, JSWeakObjectMapRef map, void* key, JSObjectRef object) +{ + ExecState* exec = toJS(ctx); + APIEntryShim entryShim(exec); + JSObject* obj = toJS(object); + if (!obj) + return; + ASSERT(obj->inherits(&JSCallbackObject<JSGlobalObject>::info) || obj->inherits(&JSCallbackObject<JSObject>::info)); + map->map().set(key, obj); +} + +JSObjectRef JSWeakObjectMapGet(JSContextRef ctx, JSWeakObjectMapRef map, void* key) +{ + ExecState* exec = toJS(ctx); + APIEntryShim entryShim(exec); + return toRef(static_cast<JSObject*>(map->map().get(key))); +} + +bool JSWeakObjectMapClear(JSContextRef ctx, JSWeakObjectMapRef map, void* key, JSObjectRef object) +{ + ExecState* exec = toJS(ctx); + APIEntryShim entryShim(exec); + JSObject* obj = toJS(object); + if (map->map().uncheckedRemove(key, obj)) + return true; + return false; +} + +#ifdef __cplusplus +} +#endif diff --git a/JavaScriptCore/API/JSWeakObjectMapRefPrivate.h b/JavaScriptCore/API/JSWeakObjectMapRefPrivate.h new file mode 100644 index 0000000..d36111c --- /dev/null +++ b/JavaScriptCore/API/JSWeakObjectMapRefPrivate.h @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2010 Apple 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 INC. AND ITS CONTRIBUTORS ``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 INC. OR ITS 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 JSWeakObjectMapRefPrivate_h +#define JSWeakObjectMapRefPrivate_h + +#include <JavaScriptCore/JSContextRef.h> +#include <JavaScriptCore/JSValueRef.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/*! @typedef JSWeakObjectMapRef A weak map for storing JSObjectRefs */ +typedef struct OpaqueJSWeakObjectMap* JSWeakObjectMapRef; + +/*! + @typedef JSWeakMapDestroyedCallback + @abstract The callback invoked when a JSWeakObjectMapRef is being destroyed. + @param map The map that is being destroyed. + @param data The private data (if any) that was associated with the map instance. + */ +typedef void (*JSWeakMapDestroyedCallback)(JSWeakObjectMapRef map, void* data); + +/*! + @function + @abstract Creates a weak value map that can be used to reference user defined objects without preventing them from being collected. + @param ctx The execution context to use. + @param data A void* to set as the map's private data. Pass NULL to specify no private data. + @param destructor A function to call when the weak map is destroyed. + @result A JSWeakObjectMapRef bound to the given context, data and destructor. + @discussion The JSWeakObjectMapRef can be used as a storage mechanism to hold custom JS objects without forcing those objects to + remain live as JSValueProtect would. Any objects that are intended to be stored in a weak map must be user defined objects that + remove themselves from the map in their finalizer. + */ +JS_EXPORT JSWeakObjectMapRef JSWeakObjectMapCreate(JSContextRef ctx, void* data, JSWeakMapDestroyedCallback destructor); + +/*! + @function + @abstract Associates a JSObjectRef with the given key in a JSWeakObjectMap. + @param ctx The execution context to use. + @param map The map to operate on. + @param key The key to associate a weak reference with. + @param object The user defined object to associate with the key. + */ +JS_EXPORT void JSWeakObjectMapSet(JSContextRef ctx, JSWeakObjectMapRef map, void* key, JSObjectRef); + +/*! + @function + @abstract Retrieves the JSObjectRef associated with a key. + @param ctx The execution context to use. + @param map The map to query. + @param key The key to search for. + @result Either the live object associated with the provided key, or NULL. + */ +JS_EXPORT JSObjectRef JSWeakObjectMapGet(JSContextRef ctx, JSWeakObjectMapRef map, void* key); + +/*! + @function + @abstract Clears the association between a key and an object in a JSWeakObjectMapRef + @param ctx The execution context to use. + @param map The map to clear the key association from. + @param key The key to use. + @param object The old object value. + @result Returns true if the key/object association was present in map, and has been removed. + */ +JS_EXPORT bool JSWeakObjectMapClear(JSContextRef ctx, JSWeakObjectMapRef map, void* key, JSObjectRef object); + +#ifdef __cplusplus +} +#endif + +#endif // JSWeakObjectMapPrivate_h diff --git a/JavaScriptCore/API/WebKitAvailability.h b/JavaScriptCore/API/WebKitAvailability.h index 8402528..0e4f091 100644 --- a/JavaScriptCore/API/WebKitAvailability.h +++ b/JavaScriptCore/API/WebKitAvailability.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Apple Inc. All Rights Reserved. + * Copyright (C) 2008, 2009, 2010 Apple Inc. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -42,7 +42,7 @@ #define WEBKIT_VERSION_LATEST 0x9999 #ifdef __APPLE__ -#import <AvailabilityMacros.h> +#include <AvailabilityMacros.h> #else /* * For non-Mac platforms, require the newest version. @@ -86,6 +86,9 @@ #elif !defined(MAC_OS_X_VERSION_10_6) || MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_6 /* WebKit 3.0 is the version that shipped on Mac OS X 10.5. */ #define WEBKIT_VERSION_MIN_REQUIRED WEBKIT_VERSION_3_0 + #elif !defined(MAC_OS_X_VERSION_10_7) || MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_7 + /* WebKit 4.0 is the version that shipped on Mac OS X 10.6. */ + #define WEBKIT_VERSION_MIN_REQUIRED WEBKIT_VERSION_4_0 #else #define WEBKIT_VERSION_MIN_REQUIRED WEBKIT_VERSION_LATEST #endif @@ -645,9 +648,9 @@ * * Used on declarations introduced in WebKit 4.0 */ -#if WEBKIT_VERSION_MAX_ALLOWED < WEBKIT_VERSION_LATEST +#if WEBKIT_VERSION_MAX_ALLOWED < WEBKIT_VERSION_4_0 #define AVAILABLE_IN_WEBKIT_VERSION_4_0 UNAVAILABLE_ATTRIBUTE -#elif WEBKIT_VERSION_MIN_REQUIRED < WEBKIT_VERSION_LATEST +#elif WEBKIT_VERSION_MIN_REQUIRED < WEBKIT_VERSION_4_0 #define AVAILABLE_IN_WEBKIT_VERSION_4_0 WEAK_IMPORT_ATTRIBUTE #else #define AVAILABLE_IN_WEBKIT_VERSION_4_0 @@ -659,7 +662,7 @@ * Used on declarations introduced in WebKit 4.0, * and deprecated in WebKit 4.0 */ -#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_LATEST +#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_4_0 #define AVAILABLE_IN_WEBKIT_VERSION_4_0_BUT_DEPRECATED DEPRECATED_ATTRIBUTE #else #define AVAILABLE_IN_WEBKIT_VERSION_4_0_BUT_DEPRECATED AVAILABLE_IN_WEBKIT_VERSION_4_0 @@ -671,7 +674,7 @@ * Used on declarations introduced in WebKit 1.0, * but later deprecated in WebKit 4.0 */ -#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_LATEST +#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_4_0 #define AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0 DEPRECATED_ATTRIBUTE #else #define AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0 AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER @@ -683,7 +686,7 @@ * Used on declarations introduced in WebKit 1.1, * but later deprecated in WebKit 4.0 */ -#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_LATEST +#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_4_0 #define AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0 DEPRECATED_ATTRIBUTE #else #define AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0 AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER @@ -695,7 +698,7 @@ * Used on declarations introduced in WebKit 1.2, * but later deprecated in WebKit 4.0 */ -#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_LATEST +#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_4_0 #define AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0 DEPRECATED_ATTRIBUTE #else #define AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0 AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER @@ -707,7 +710,7 @@ * Used on declarations introduced in WebKit 1.3, * but later deprecated in WebKit 4.0 */ -#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_LATEST +#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_4_0 #define AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0 DEPRECATED_ATTRIBUTE #else #define AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0 AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER @@ -719,7 +722,7 @@ * Used on declarations introduced in WebKit 2.0, * but later deprecated in WebKit 4.0 */ -#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_LATEST +#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_4_0 #define AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0 DEPRECATED_ATTRIBUTE #else #define AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0 AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER @@ -731,7 +734,7 @@ * Used on declarations introduced in WebKit 3.0, * but later deprecated in WebKit 4.0 */ -#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_LATEST +#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_4_0 #define AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0 DEPRECATED_ATTRIBUTE #else #define AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0 AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER @@ -743,7 +746,7 @@ * Used on declarations introduced in WebKit 3.1, * but later deprecated in WebKit 4.0 */ -#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_LATEST +#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_4_0 #define AVAILABLE_WEBKIT_VERSION_3_1_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0 DEPRECATED_ATTRIBUTE #else #define AVAILABLE_WEBKIT_VERSION_3_1_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0 AVAILABLE_WEBKIT_VERSION_3_1_AND_LATER @@ -754,11 +757,148 @@ * * Used on types deprecated in WebKit 4.0 */ -#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_LATEST +#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_4_0 #define DEPRECATED_IN_WEBKIT_VERSION_4_0 DEPRECATED_ATTRIBUTE #else #define DEPRECATED_IN_WEBKIT_VERSION_4_0 #endif + + + + +/* + * AVAILABLE_AFTER_WEBKIT_VERSION_4_0 + * + * Used on declarations introduced after WebKit 4.0 + */ +#if WEBKIT_VERSION_MAX_ALLOWED < WEBKIT_VERSION_LATEST + #define AVAILABLE_AFTER_WEBKIT_VERSION_4_0 UNAVAILABLE_ATTRIBUTE +#elif WEBKIT_VERSION_MIN_REQUIRED < WEBKIT_VERSION_LATEST + #define AVAILABLE_AFTER_WEBKIT_VERSION_4_0 WEAK_IMPORT_ATTRIBUTE +#else + #define AVAILABLE_AFTER_WEBKIT_VERSION_4_0 +#endif + +/* + * AVAILABLE_AFTER_WEBKIT_VERSION_4_0_BUT_DEPRECATED + * + * Used on declarations introduced after WebKit 4.0, + * and deprecated after WebKit 4.0 + */ +#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_LATEST + #define AVAILABLE_AFTER_WEBKIT_VERSION_4_0_BUT_DEPRECATED DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_AFTER_WEBKIT_VERSION_4_0_BUT_DEPRECATED AVAILABLE_AFTER_WEBKIT_VERSION_4_0 +#endif + +/* + * AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0 + * + * Used on declarations introduced in WebKit 1.0, + * but later deprecated after WebKit 4.0 + */ +#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_LATEST + #define AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0 AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER +#endif + +/* + * AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0 + * + * Used on declarations introduced in WebKit 1.1, + * but later deprecated after WebKit 4.0 + */ +#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_LATEST + #define AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0 AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER +#endif + +/* + * AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0 + * + * Used on declarations introduced in WebKit 1.2, + * but later deprecated after WebKit 4.0 + */ +#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_LATEST + #define AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0 AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER +#endif + +/* + * AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0 + * + * Used on declarations introduced in WebKit 1.3, + * but later deprecated after WebKit 4.0 + */ +#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_LATEST + #define AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0 AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER +#endif + +/* + * AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0 + * + * Used on declarations introduced in WebKit 2.0, + * but later deprecated after WebKit 4.0 + */ +#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_LATEST + #define AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0 AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER +#endif + +/* + * AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0 + * + * Used on declarations introduced in WebKit 3.0, + * but later deprecated after WebKit 4.0 + */ +#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_LATEST + #define AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0 AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER +#endif + +/* + * AVAILABLE_WEBKIT_VERSION_3_1_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0 + * + * Used on declarations introduced in WebKit 3.1, + * but later deprecated after WebKit 4.0 + */ +#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_LATEST + #define AVAILABLE_WEBKIT_VERSION_3_1_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_WEBKIT_VERSION_3_1_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0 AVAILABLE_WEBKIT_VERSION_3_1_AND_LATER +#endif + +/* + * AVAILABLE_WEBKIT_VERSION_4_0_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0 + * + * Used on declarations introduced in WebKit 4.0 + * but later deprecated after WebKit 4.0 + */ +#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_LATEST + #define AVAILABLE_WEBKIT_VERSION_4_0_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_WEBKIT_VERSION_4_0_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0 AVAILABLE_WEBKIT_VERSION_4_0_AND_LATER +#endif + +/* + * DEPRECATED_AFTER_WEBKIT_VERSION_4_0 + * + * Used on types deprecated after WebKit 4.0 + */ +#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_LATEST + #define DEPRECATED_AFTER_WEBKIT_VERSION_4_0 DEPRECATED_ATTRIBUTE +#else + #define DEPRECATED_AFTER_WEBKIT_VERSION_4_0 +#endif + + #endif /* __WebKitAvailability__ */ diff --git a/JavaScriptCore/API/tests/testapi.c b/JavaScriptCore/API/tests/testapi.c index ebc0cfb..28b4ec8 100644 --- a/JavaScriptCore/API/tests/testapi.c +++ b/JavaScriptCore/API/tests/testapi.c @@ -26,6 +26,7 @@ #include "JavaScriptCore.h" #include "JSBasePrivate.h" #include "JSContextRefPrivate.h" +#include "JSObjectRefPrivate.h" #include <math.h> #define ASSERT_DISABLED 0 #include <wtf/Assertions.h> @@ -754,6 +755,8 @@ static void testInitializeFinalize() static JSValueRef jsNumberValue = NULL; +static JSObjectRef aHeapRef = NULL; + static void makeGlobalNumberValue(JSContextRef context) { JSValueRef v = JSValueMakeNumber(context, 420); JSValueProtect(context, v); @@ -870,8 +873,107 @@ int main(int argc, char* argv[]) JSObjectSetProperty(context, globalObject, EmptyObjectIString, EmptyObject, kJSPropertyAttributeNone, NULL); JSStringRelease(EmptyObjectIString); + JSStringRef lengthStr = JSStringCreateWithUTF8CString("length"); + aHeapRef = JSObjectMakeArray(context, 0, 0, 0); + JSObjectSetProperty(context, aHeapRef, lengthStr, JSValueMakeNumber(context, 10), 0, 0); + JSStringRef privatePropertyName = JSStringCreateWithUTF8CString("privateProperty"); + if (!JSObjectSetPrivateProperty(context, myObject, privatePropertyName, aHeapRef)) { + printf("FAIL: Could not set private property.\n"); + failed = 1; + } else { + printf("PASS: Set private property.\n"); + } + if (JSObjectSetPrivateProperty(context, aHeapRef, privatePropertyName, aHeapRef)) { + printf("FAIL: JSObjectSetPrivateProperty should fail on non-API objects.\n"); + failed = 1; + } else { + printf("PASS: Did not allow JSObjectSetPrivateProperty on a non-API object.\n"); + } + if (JSObjectGetPrivateProperty(context, myObject, privatePropertyName) != aHeapRef) { + printf("FAIL: Could not retrieve private property.\n"); + failed = 1; + } else + printf("PASS: Retrieved private property.\n"); + if (JSObjectGetPrivateProperty(context, aHeapRef, privatePropertyName)) { + printf("FAIL: JSObjectGetPrivateProperty should return NULL when called on a non-API object.\n"); + failed = 1; + } else + printf("PASS: JSObjectGetPrivateProperty return NULL.\n"); + + if (JSObjectGetProperty(context, myObject, privatePropertyName, 0) == aHeapRef) { + printf("FAIL: Accessed private property through ordinary property lookup.\n"); + failed = 1; + } else + printf("PASS: Cannot access private property through ordinary property lookup.\n"); + + JSGarbageCollect(context); + + for (int i = 0; i < 10000; i++) + JSObjectMake(context, 0, 0); + + if (JSValueToNumber(context, JSObjectGetProperty(context, aHeapRef, lengthStr, 0), 0) != 10) { + printf("FAIL: Private property has been collected.\n"); + failed = 1; + } else + printf("PASS: Private property does not appear to have been collected.\n"); + JSStringRelease(lengthStr); + + JSStringRef validJSON = JSStringCreateWithUTF8CString("{\"aProperty\":true}"); + JSValueRef jsonObject = JSValueMakeFromJSONString(context, validJSON); + JSStringRelease(validJSON); + if (!JSValueIsObject(context, jsonObject)) { + printf("FAIL: Did not parse valid JSON correctly\n"); + failed = 1; + } else + printf("PASS: Parsed valid JSON string.\n"); + JSStringRef propertyName = JSStringCreateWithUTF8CString("aProperty"); + assertEqualsAsBoolean(JSObjectGetProperty(context, JSValueToObject(context, jsonObject, 0), propertyName, 0), true); + JSStringRelease(propertyName); + JSStringRef invalidJSON = JSStringCreateWithUTF8CString("fail!"); + if (JSValueMakeFromJSONString(context, invalidJSON)) { + printf("FAIL: Should return null for invalid JSON data\n"); + failed = 1; + } else + printf("PASS: Correctly returned null for invalid JSON data.\n"); JSValueRef exception; + JSStringRef str = JSValueCreateJSONString(context, jsonObject, 0, 0); + if (!JSStringIsEqualToUTF8CString(str, "{\"aProperty\":true}")) { + printf("FAIL: Did not correctly serialise with indent of 0.\n"); + failed = 1; + } else + printf("PASS: Correctly serialised with indent of 0.\n"); + JSStringRelease(str); + str = JSValueCreateJSONString(context, jsonObject, 4, 0); + if (!JSStringIsEqualToUTF8CString(str, "{\n \"aProperty\": true\n}")) { + printf("FAIL: Did not correctly serialise with indent of 4.\n"); + failed = 1; + } else + printf("PASS: Correctly serialised with indent of 4.\n"); + JSStringRelease(str); + JSStringRef src = JSStringCreateWithUTF8CString("({get a(){ throw '';}})"); + JSValueRef unstringifiableObj = JSEvaluateScript(context, src, NULL, NULL, 1, NULL); + + str = JSValueCreateJSONString(context, unstringifiableObj, 4, 0); + if (str) { + printf("FAIL: Didn't return null when attempting to serialize unserializable value.\n"); + JSStringRelease(str); + failed = 1; + } else + printf("PASS: returned null when attempting to serialize unserializable value.\n"); + + str = JSValueCreateJSONString(context, unstringifiableObj, 4, &exception); + if (str) { + printf("FAIL: Didn't return null when attempting to serialize unserializable value.\n"); + JSStringRelease(str); + failed = 1; + } else + printf("PASS: returned null when attempting to serialize unserializable value.\n"); + if (!exception) { + printf("FAIL: Did not set exception on serialisation error\n"); + failed = 1; + } else + printf("PASS: set exception on serialisation error\n"); // Conversions that throw exceptions exception = NULL; ASSERT(NULL == JSValueToObject(context, jsNull, &exception)); |