summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/API
diff options
context:
space:
mode:
authorOswald Buddenhagen <oswald.buddenhagen@qt.io>2017-05-30 12:48:17 +0200
committerOswald Buddenhagen <oswald.buddenhagen@qt.io>2017-05-30 12:48:17 +0200
commit881da28418d380042aa95a97f0cbd42560a64f7c (patch)
treea794dff3274695e99c651902dde93d934ea7a5af /Source/JavaScriptCore/API
parent7e104c57a70fdf551bb3d22a5d637cdcbc69dbea (diff)
parent0fcedcd17cc00d3dd44c718b3cb36c1033319671 (diff)
downloadqtwebkit-881da28418d380042aa95a97f0cbd42560a64f7c.tar.gz
Merge 'wip/next' into dev
Change-Id: Iff9ee5e23bb326c4371ec8ed81d56f2f05d680e9
Diffstat (limited to 'Source/JavaScriptCore/API')
-rw-r--r--Source/JavaScriptCore/API/APICallbackFunction.h109
-rw-r--r--Source/JavaScriptCore/API/APICast.h8
-rw-r--r--Source/JavaScriptCore/API/APIShims.h104
-rw-r--r--Source/JavaScriptCore/API/JSAPIWrapperObject.h2
-rw-r--r--Source/JavaScriptCore/API/JSAPIWrapperObject.mm112
-rw-r--r--Source/JavaScriptCore/API/JSBase.cpp91
-rw-r--r--Source/JavaScriptCore/API/JSBase.h29
-rw-r--r--Source/JavaScriptCore/API/JSBasePrivate.h10
-rw-r--r--Source/JavaScriptCore/API/JSCTestRunnerUtils.cpp47
-rw-r--r--Source/JavaScriptCore/API/JSCTestRunnerUtils.h2
-rw-r--r--Source/JavaScriptCore/API/JSCallbackConstructor.cpp45
-rw-r--r--Source/JavaScriptCore/API/JSCallbackConstructor.h14
-rw-r--r--Source/JavaScriptCore/API/JSCallbackFunction.cpp54
-rw-r--r--Source/JavaScriptCore/API/JSCallbackFunction.h23
-rw-r--r--Source/JavaScriptCore/API/JSCallbackObject.cpp29
-rw-r--r--Source/JavaScriptCore/API/JSCallbackObject.h54
-rw-r--r--Source/JavaScriptCore/API/JSCallbackObjectFunctions.h207
-rw-r--r--Source/JavaScriptCore/API/JSClassRef.cpp49
-rw-r--r--Source/JavaScriptCore/API/JSClassRef.h35
-rw-r--r--Source/JavaScriptCore/API/JSContext.h260
-rw-r--r--Source/JavaScriptCore/API/JSContext.mm289
-rw-r--r--Source/JavaScriptCore/API/JSContextInternal.h4
-rw-r--r--Source/JavaScriptCore/API/JSContextPrivate.h57
-rw-r--r--Source/JavaScriptCore/API/JSContextRef.cpp330
-rw-r--r--Source/JavaScriptCore/API/JSContextRef.h46
-rw-r--r--Source/JavaScriptCore/API/JSContextRefInspectorSupport.h43
-rw-r--r--Source/JavaScriptCore/API/JSContextRefInternal.h60
-rw-r--r--Source/JavaScriptCore/API/JSContextRefPrivate.h57
-rw-r--r--Source/JavaScriptCore/API/JSExport.h204
-rw-r--r--Source/JavaScriptCore/API/JSManagedValue.h57
-rw-r--r--Source/JavaScriptCore/API/JSManagedValue.mm117
-rw-r--r--Source/JavaScriptCore/API/JSManagedValueInternal.h42
-rw-r--r--Source/JavaScriptCore/API/JSObjectRef.cpp260
-rw-r--r--Source/JavaScriptCore/API/JSObjectRef.h16
-rw-r--r--Source/JavaScriptCore/API/JSProfilerPrivate.cpp10
-rw-r--r--Source/JavaScriptCore/API/JSProfilerPrivate.h4
-rw-r--r--Source/JavaScriptCore/API/JSRemoteInspector.cpp78
-rw-r--r--Source/JavaScriptCore/API/JSRemoteInspector.h49
-rw-r--r--Source/JavaScriptCore/API/JSRetainPtr.h17
-rw-r--r--Source/JavaScriptCore/API/JSScriptRef.cpp64
-rw-r--r--Source/JavaScriptCore/API/JSScriptRefPrivate.h4
-rw-r--r--Source/JavaScriptCore/API/JSStringRef.cpp42
-rw-r--r--Source/JavaScriptCore/API/JSStringRef.h8
-rw-r--r--Source/JavaScriptCore/API/JSStringRefBSTR.cpp2
-rw-r--r--Source/JavaScriptCore/API/JSStringRefBSTR.h2
-rw-r--r--Source/JavaScriptCore/API/JSStringRefCF.cpp47
-rw-r--r--Source/JavaScriptCore/API/JSStringRefCF.h8
-rw-r--r--Source/JavaScriptCore/API/JSStringRefQt.cpp3
-rw-r--r--Source/JavaScriptCore/API/JSStringRefQt.h2
-rw-r--r--Source/JavaScriptCore/API/JSValue.h741
-rw-r--r--Source/JavaScriptCore/API/JSValue.mm1131
-rw-r--r--Source/JavaScriptCore/API/JSValueRef.cpp210
-rw-r--r--Source/JavaScriptCore/API/JSValueRef.h28
-rw-r--r--Source/JavaScriptCore/API/JSVirtualMachine.h66
-rw-r--r--Source/JavaScriptCore/API/JSVirtualMachine.mm255
-rw-r--r--Source/JavaScriptCore/API/JSVirtualMachineInternal.h9
-rw-r--r--Source/JavaScriptCore/API/JSWeakObjectMapRefInternal.h9
-rw-r--r--Source/JavaScriptCore/API/JSWeakObjectMapRefPrivate.cpp18
-rw-r--r--Source/JavaScriptCore/API/JSWrapperMap.h1
-rw-r--r--Source/JavaScriptCore/API/JSWrapperMap.mm521
-rw-r--r--Source/JavaScriptCore/API/JavaScript.h4
-rw-r--r--Source/JavaScriptCore/API/JavaScriptCore.h4
-rw-r--r--Source/JavaScriptCore/API/ObjCCallbackFunction.h28
-rw-r--r--Source/JavaScriptCore/API/ObjCCallbackFunction.mm615
-rw-r--r--Source/JavaScriptCore/API/ObjcRuntimeExtras.h19
-rw-r--r--Source/JavaScriptCore/API/OpaqueJSString.cpp76
-rw-r--r--Source/JavaScriptCore/API/OpaqueJSString.h43
-rw-r--r--Source/JavaScriptCore/API/WebKitAvailability.h897
-rw-r--r--Source/JavaScriptCore/API/tests/CompareAndSwapTest.cpp118
-rw-r--r--Source/JavaScriptCore/API/tests/CompareAndSwapTest.h40
-rw-r--r--Source/JavaScriptCore/API/tests/CurrentThisInsideBlockGetterTest.h38
-rw-r--r--Source/JavaScriptCore/API/tests/CustomGlobalObjectClassTest.c145
-rw-r--r--Source/JavaScriptCore/API/tests/CustomGlobalObjectClassTest.h33
-rw-r--r--Source/JavaScriptCore/API/tests/DateTests.h32
-rw-r--r--Source/JavaScriptCore/API/tests/ExecutionTimeLimitTest.cpp374
-rw-r--r--Source/JavaScriptCore/API/tests/ExecutionTimeLimitTest.h40
-rw-r--r--Source/JavaScriptCore/API/tests/GlobalContextWithFinalizerTest.cpp56
-rw-r--r--Source/JavaScriptCore/API/tests/GlobalContextWithFinalizerTest.h42
-rw-r--r--Source/JavaScriptCore/API/tests/JSExportTests.h34
-rw-r--r--Source/JavaScriptCore/API/tests/JSNode.c8
-rw-r--r--Source/JavaScriptCore/API/tests/JSNode.h6
-rw-r--r--Source/JavaScriptCore/API/tests/JSNodeList.c8
-rw-r--r--Source/JavaScriptCore/API/tests/JSNodeList.h6
-rw-r--r--Source/JavaScriptCore/API/tests/Node.c6
-rw-r--r--Source/JavaScriptCore/API/tests/Node.h6
-rw-r--r--Source/JavaScriptCore/API/tests/NodeList.c6
-rw-r--r--Source/JavaScriptCore/API/tests/NodeList.h6
-rw-r--r--Source/JavaScriptCore/API/tests/PingPongStackOverflowTest.cpp182
-rw-r--r--Source/JavaScriptCore/API/tests/PingPongStackOverflowTest.h39
-rw-r--r--Source/JavaScriptCore/API/tests/Regress141275.h34
-rw-r--r--Source/JavaScriptCore/API/tests/Regress141809.h34
-rw-r--r--Source/JavaScriptCore/API/tests/minidom.c9
-rw-r--r--Source/JavaScriptCore/API/tests/minidom.js6
-rw-r--r--Source/JavaScriptCore/API/tests/testapi.c434
-rw-r--r--Source/JavaScriptCore/API/tests/testapi.js25
-rw-r--r--Source/JavaScriptCore/API/tests/testapi.mm841
96 files changed, 4123 insertions, 6366 deletions
diff --git a/Source/JavaScriptCore/API/APICallbackFunction.h b/Source/JavaScriptCore/API/APICallbackFunction.h
new file mode 100644
index 000000000..94b10c420
--- /dev/null
+++ b/Source/JavaScriptCore/API/APICallbackFunction.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2013 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. ``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
+ * 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 APICallbackFunction_h
+#define APICallbackFunction_h
+
+#include "APICast.h"
+#include "Error.h"
+#include "JSCallbackConstructor.h"
+#include "JSLock.h"
+#include <wtf/Vector.h>
+
+namespace JSC {
+
+struct APICallbackFunction {
+
+template <typename T> static EncodedJSValue JSC_HOST_CALL call(ExecState*);
+template <typename T> static EncodedJSValue JSC_HOST_CALL construct(ExecState*);
+
+};
+
+template <typename T>
+EncodedJSValue JSC_HOST_CALL APICallbackFunction::call(ExecState* exec)
+{
+ JSContextRef execRef = toRef(exec);
+ JSObjectRef functionRef = toRef(exec->callee());
+ JSObjectRef thisObjRef = toRef(jsCast<JSObject*>(exec->thisValue().toThis(exec, NotStrictMode)));
+
+ int argumentCount = static_cast<int>(exec->argumentCount());
+ Vector<JSValueRef, 16> arguments;
+ arguments.reserveInitialCapacity(argumentCount);
+ for (int i = 0; i < argumentCount; i++)
+ arguments.uncheckedAppend(toRef(exec, exec->uncheckedArgument(i)));
+
+ JSValueRef exception = 0;
+ JSValueRef result;
+ {
+ JSLock::DropAllLocks dropAllLocks(exec);
+ result = jsCast<T*>(toJS(functionRef))->functionCallback()(execRef, functionRef, thisObjRef, argumentCount, arguments.data(), &exception);
+ }
+ if (exception)
+ exec->vm().throwException(exec, toJS(exec, exception));
+
+ // result must be a valid JSValue.
+ if (!result)
+ return JSValue::encode(jsUndefined());
+
+ return JSValue::encode(toJS(exec, result));
+}
+
+template <typename T>
+EncodedJSValue JSC_HOST_CALL APICallbackFunction::construct(ExecState* exec)
+{
+ JSObject* constructor = exec->callee();
+ JSContextRef ctx = toRef(exec);
+ JSObjectRef constructorRef = toRef(constructor);
+
+ JSObjectCallAsConstructorCallback callback = jsCast<T*>(constructor)->constructCallback();
+ if (callback) {
+ size_t argumentCount = exec->argumentCount();
+ Vector<JSValueRef, 16> arguments;
+ arguments.reserveInitialCapacity(argumentCount);
+ for (size_t i = 0; i < argumentCount; ++i)
+ arguments.uncheckedAppend(toRef(exec, exec->uncheckedArgument(i)));
+
+ JSValueRef exception = 0;
+ JSObjectRef result;
+ {
+ JSLock::DropAllLocks dropAllLocks(exec);
+ result = callback(ctx, constructorRef, argumentCount, arguments.data(), &exception);
+ }
+ if (exception) {
+ exec->vm().throwException(exec, toJS(exec, exception));
+ return JSValue::encode(toJS(exec, exception));
+ }
+ // result must be a valid JSValue.
+ if (!result)
+ return throwVMTypeError(exec);
+ return JSValue::encode(toJS(result));
+ }
+
+ return JSValue::encode(toJS(JSObjectMake(ctx, jsCast<JSCallbackConstructor*>(constructor)->classRef(), 0)));
+}
+
+} // namespace JSC
+
+#endif // APICallbackFunction_h
diff --git a/Source/JavaScriptCore/API/APICast.h b/Source/JavaScriptCore/API/APICast.h
index fc5d71b2e..8fe8d6034 100644
--- a/Source/JavaScriptCore/API/APICast.h
+++ b/Source/JavaScriptCore/API/APICast.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
@@ -28,6 +28,7 @@
#include "JSAPIValueWrapper.h"
#include "JSCJSValue.h"
+#include "JSCJSValueInlines.h"
#include "JSGlobalObject.h"
namespace JSC {
@@ -123,6 +124,7 @@ inline JSC::VM* toJS(JSContextGroupRef g)
inline JSValueRef toRef(JSC::ExecState* exec, JSC::JSValue v)
{
+ ASSERT(exec->vm().currentThreadIsHoldingAPILock());
#if USE(JSVALUE32_64)
if (!v)
return 0;
diff --git a/Source/JavaScriptCore/API/APIShims.h b/Source/JavaScriptCore/API/APIShims.h
deleted file mode 100644
index d8e1fb790..000000000
--- a/Source/JavaScriptCore/API/APIShims.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (C) 2009 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 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 APIShims_h
-#define APIShims_h
-
-#include "CallFrame.h"
-#include "GCActivityCallback.h"
-#include "IncrementalSweeper.h"
-#include "JSLock.h"
-#include <wtf/WTFThreadData.h>
-
-namespace JSC {
-
-class APIEntryShimWithoutLock {
-protected:
- APIEntryShimWithoutLock(VM* vm, bool registerThread)
- : m_vm(vm)
- , m_entryIdentifierTable(wtfThreadData().setCurrentIdentifierTable(vm->identifierTable))
- {
- if (registerThread)
- vm->heap.machineThreads().addCurrentThread();
- }
-
- ~APIEntryShimWithoutLock()
- {
- wtfThreadData().setCurrentIdentifierTable(m_entryIdentifierTable);
- }
-
-protected:
- RefPtr<VM> m_vm;
- IdentifierTable* m_entryIdentifierTable;
-};
-
-class APIEntryShim : public APIEntryShimWithoutLock {
-public:
- // Normal API entry
- APIEntryShim(ExecState* exec, bool registerThread = true)
- : APIEntryShimWithoutLock(&exec->vm(), registerThread)
- , m_lockHolder(exec)
- {
- }
-
- // JSPropertyNameAccumulator only has a vm.
- APIEntryShim(VM* vm, bool registerThread = true)
- : APIEntryShimWithoutLock(vm, registerThread)
- , m_lockHolder(vm)
- {
- }
-
- ~APIEntryShim()
- {
- // Destroying our JSLockHolder should also destroy the VM.
- m_vm.clear();
- }
-
-private:
- JSLockHolder m_lockHolder;
-};
-
-class APICallbackShim {
-public:
- APICallbackShim(ExecState* exec)
- : m_dropAllLocks(exec)
- , m_vm(&exec->vm())
- {
- wtfThreadData().resetCurrentIdentifierTable();
- }
-
- ~APICallbackShim()
- {
- wtfThreadData().setCurrentIdentifierTable(m_vm->identifierTable);
- }
-
-private:
- JSLock::DropAllLocks m_dropAllLocks;
- VM* m_vm;
-};
-
-}
-
-#endif
diff --git a/Source/JavaScriptCore/API/JSAPIWrapperObject.h b/Source/JavaScriptCore/API/JSAPIWrapperObject.h
index 909039771..14194b6f9 100644
--- a/Source/JavaScriptCore/API/JSAPIWrapperObject.h
+++ b/Source/JavaScriptCore/API/JSAPIWrapperObject.h
@@ -45,8 +45,6 @@ public:
void setWrappedObject(void*);
protected:
- static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags;
-
JSAPIWrapperObject(VM&, Structure*);
private:
diff --git a/Source/JavaScriptCore/API/JSAPIWrapperObject.mm b/Source/JavaScriptCore/API/JSAPIWrapperObject.mm
deleted file mode 100644
index c06de3978..000000000
--- a/Source/JavaScriptCore/API/JSAPIWrapperObject.mm
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (C) 2013 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 "JSAPIWrapperObject.h"
-
-#include "JSCJSValueInlines.h"
-#include "JSCallbackObject.h"
-#include "JSCellInlines.h"
-#include "JSVirtualMachineInternal.h"
-#include "SlotVisitorInlines.h"
-#include "Structure.h"
-#include "StructureInlines.h"
-
-#if JSC_OBJC_API_ENABLED
-
-class JSAPIWrapperObjectHandleOwner : public JSC::WeakHandleOwner {
-public:
- virtual void finalize(JSC::Handle<JSC::Unknown>, void*);
- virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&);
-};
-
-static JSAPIWrapperObjectHandleOwner* jsAPIWrapperObjectHandleOwner()
-{
- DEFINE_STATIC_LOCAL(JSAPIWrapperObjectHandleOwner, jsWrapperObjectHandleOwner, ());
- return &jsWrapperObjectHandleOwner;
-}
-
-void JSAPIWrapperObjectHandleOwner::finalize(JSC::Handle<JSC::Unknown> handle, void*)
-{
- JSC::JSAPIWrapperObject* wrapperObject = JSC::jsCast<JSC::JSAPIWrapperObject*>(handle.get().asCell());
- if (!wrapperObject->wrappedObject())
- return;
- [static_cast<id>(wrapperObject->wrappedObject()) release];
- JSC::WeakSet::deallocate(JSC::WeakImpl::asWeakImpl(handle.slot()));
-}
-
-bool JSAPIWrapperObjectHandleOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, JSC::SlotVisitor& visitor)
-{
- JSC::JSAPIWrapperObject* wrapperObject = JSC::jsCast<JSC::JSAPIWrapperObject*>(handle.get().asCell());
- // We use the JSGlobalObject when processing weak handles to prevent the situation where using
- // the same Objective-C object in multiple global objects keeps all of the global objects alive.
- if (!wrapperObject->wrappedObject())
- return false;
- return JSC::Heap::isMarked(wrapperObject->structure()->globalObject()) && visitor.containsOpaqueRoot(wrapperObject->wrappedObject());
-}
-
-namespace JSC {
-
-template <> const ClassInfo JSCallbackObject<JSAPIWrapperObject>::s_info = { "JSAPIWrapperObject", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSCallbackObject) };
-
-template<> const bool JSCallbackObject<JSAPIWrapperObject>::needsDestruction = true;
-
-template <>
-Structure* JSCallbackObject<JSAPIWrapperObject>::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
-{
- return Structure::create(vm, globalObject, proto, TypeInfo(ObjectType, StructureFlags), &s_info);
-}
-
-JSAPIWrapperObject::JSAPIWrapperObject(VM& vm, Structure* structure)
- : Base(vm, structure)
- , m_wrappedObject(0)
-{
-}
-
-void JSAPIWrapperObject::finishCreation(VM& vm)
-{
- Base::finishCreation(vm);
- WeakSet::allocate(this, jsAPIWrapperObjectHandleOwner(), 0); // Balanced in JSAPIWrapperObjectHandleOwner::finalize.
-}
-
-void JSAPIWrapperObject::setWrappedObject(void* wrappedObject)
-{
- ASSERT(!m_wrappedObject);
- m_wrappedObject = [static_cast<id>(wrappedObject) retain];
-}
-
-void JSAPIWrapperObject::visitChildren(JSCell* cell, JSC::SlotVisitor& visitor)
-{
- JSAPIWrapperObject* thisObject = JSC::jsCast<JSAPIWrapperObject*>(cell);
- COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
- Base::visitChildren(cell, visitor);
-
- if (thisObject->wrappedObject())
- scanExternalObjectGraph(cell->structure()->globalObject()->vm(), visitor, thisObject->wrappedObject());
-}
-
-} // namespace JSC
-
-#endif // JSC_OBJC_API_ENABLED
diff --git a/Source/JavaScriptCore/API/JSBase.cpp b/Source/JavaScriptCore/API/JSBase.cpp
index 7669ff1a9..6b2a907f1 100644
--- a/Source/JavaScriptCore/API/JSBase.cpp
+++ b/Source/JavaScriptCore/API/JSBase.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
@@ -28,18 +28,23 @@
#include "JSBasePrivate.h"
#include "APICast.h"
-#include "APIShims.h"
#include "CallFrame.h"
#include "Completion.h"
+#include "Exception.h"
+#include "GCActivityCallback.h"
#include "InitializeThreading.h"
#include "JSGlobalObject.h"
#include "JSLock.h"
#include "JSObject.h"
#include "OpaqueJSString.h"
-#include "Operations.h"
+#include "JSCInlines.h"
#include "SourceCode.h"
#include <wtf/text/StringHash.h>
+#if ENABLE(REMOTE_INSPECTOR)
+#include "JSGlobalObjectInspectorController.h"
+#endif
+
using namespace JSC;
JSValueRef JSEvaluateScript(JSContextRef ctx, JSStringRef script, JSObjectRef thisObject, JSStringRef sourceURL, int startingLineNumber, JSValueRef* exception)
@@ -49,20 +54,30 @@ JSValueRef JSEvaluateScript(JSContextRef ctx, JSStringRef script, JSObjectRef th
return 0;
}
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
+ JSLockHolder locker(exec);
JSObject* jsThisObject = toJS(thisObject);
+ startingLineNumber = std::max(1, startingLineNumber);
+
// evaluate sets "this" to the global object if it is NULL
- JSGlobalObject* globalObject = exec->dynamicGlobalObject();
- SourceCode source = makeSource(script->string(), sourceURL->string(), TextPosition(OrdinalNumber::fromOneBasedInt(startingLineNumber), OrdinalNumber::first()));
+ JSGlobalObject* globalObject = exec->vmEntryGlobalObject();
+ SourceCode source = makeSource(script->string(), sourceURL ? sourceURL->string() : String(), TextPosition(OrdinalNumber::fromOneBasedInt(startingLineNumber), OrdinalNumber::first()));
- JSValue evaluationException;
- JSValue returnValue = evaluate(globalObject->globalExec(), source, jsThisObject, &evaluationException);
+ NakedPtr<Exception> evaluationException;
+ JSValue returnValue = profiledEvaluate(globalObject->globalExec(), ProfilingReason::API, source, jsThisObject, evaluationException);
if (evaluationException) {
if (exception)
- *exception = toRef(exec, evaluationException);
+ *exception = toRef(exec, evaluationException->value());
+#if ENABLE(REMOTE_INSPECTOR)
+ // FIXME: If we have a debugger attached we could learn about ParseError exceptions through
+ // ScriptDebugServer::sourceParsed and this path could produce a duplicate warning. The
+ // Debugger path is currently ignored by inspector.
+ // NOTE: If we don't have a debugger, this SourceCode will be forever lost to the inspector.
+ // We could stash it in the inspector in case an inspector is ever opened.
+ globalObject->inspectorController().reportAPIException(exec, evaluationException);
+#endif
return 0;
}
@@ -80,16 +95,22 @@ bool JSCheckScriptSyntax(JSContextRef ctx, JSStringRef script, JSStringRef sourc
return false;
}
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
+ JSLockHolder locker(exec);
- SourceCode source = makeSource(script->string(), sourceURL->string(), TextPosition(OrdinalNumber::fromOneBasedInt(startingLineNumber), OrdinalNumber::first()));
+ startingLineNumber = std::max(1, startingLineNumber);
+
+ SourceCode source = makeSource(script->string(), sourceURL ? sourceURL->string() : String(), TextPosition(OrdinalNumber::fromOneBasedInt(startingLineNumber), OrdinalNumber::first()));
JSValue syntaxException;
- bool isValidSyntax = checkSyntax(exec->dynamicGlobalObject()->globalExec(), source, &syntaxException);
+ bool isValidSyntax = checkSyntax(exec->vmEntryGlobalObject()->globalExec(), source, &syntaxException);
if (!isValidSyntax) {
if (exception)
*exception = toRef(exec, syntaxException);
+#if ENABLE(REMOTE_INSPECTOR)
+ Exception* exception = Exception::create(exec->vm(), syntaxException);
+ exec->vmEntryGlobalObject()->inspectorController().reportAPIException(exec, exception);
+#endif
return false;
}
@@ -107,7 +128,7 @@ void JSGarbageCollect(JSContextRef ctx)
return;
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec, false);
+ JSLockHolder locker(exec);
exec->vm().heap.reportAbandonedObjectGraph();
}
@@ -119,11 +140,13 @@ void JSReportExtraMemoryCost(JSContextRef ctx, size_t size)
return;
}
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
- exec->vm().heap.reportExtraMemoryCost(size);
+ JSLockHolder locker(exec);
+
+ exec->vm().heap.deprecatedReportExtraMemory(size);
}
extern "C" JS_EXPORT void JSSynchronousGarbageCollectForDebugging(JSContextRef);
+extern "C" JS_EXPORT void JSSynchronousEdenCollectForDebugging(JSContextRef);
void JSSynchronousGarbageCollectForDebugging(JSContextRef ctx)
{
@@ -131,6 +154,38 @@ void JSSynchronousGarbageCollectForDebugging(JSContextRef ctx)
return;
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
+ JSLockHolder locker(exec);
exec->vm().heap.collectAllGarbage();
}
+
+void JSSynchronousEdenCollectForDebugging(JSContextRef ctx)
+{
+ if (!ctx)
+ return;
+
+ ExecState* exec = toJS(ctx);
+ JSLockHolder locker(exec);
+ exec->vm().heap.collect(EdenCollection);
+}
+
+void JSDisableGCTimer(void)
+{
+ GCActivityCallback::s_shouldCreateGCTimer = false;
+}
+
+#if PLATFORM(IOS)
+// FIXME: Expose symbols to tell dyld where to find JavaScriptCore on older versions of
+// iOS (< 7.0). We should remove these symbols once we no longer need to support such
+// versions of iOS. See <rdar://problem/13696872> for more details.
+JS_EXPORT extern const char iosInstallName43 __asm("$ld$install_name$os4.3$/System/Library/PrivateFrameworks/JavaScriptCore.framework/JavaScriptCore");
+JS_EXPORT extern const char iosInstallName50 __asm("$ld$install_name$os5.0$/System/Library/PrivateFrameworks/JavaScriptCore.framework/JavaScriptCore");
+JS_EXPORT extern const char iosInstallName51 __asm("$ld$install_name$os5.1$/System/Library/PrivateFrameworks/JavaScriptCore.framework/JavaScriptCore");
+JS_EXPORT extern const char iosInstallName60 __asm("$ld$install_name$os6.0$/System/Library/PrivateFrameworks/JavaScriptCore.framework/JavaScriptCore");
+JS_EXPORT extern const char iosInstallName61 __asm("$ld$install_name$os6.1$/System/Library/PrivateFrameworks/JavaScriptCore.framework/JavaScriptCore");
+
+const char iosInstallName43 = 0;
+const char iosInstallName50 = 0;
+const char iosInstallName51 = 0;
+const char iosInstallName60 = 0;
+const char iosInstallName61 = 0;
+#endif
diff --git a/Source/JavaScriptCore/API/JSBase.h b/Source/JavaScriptCore/API/JSBase.h
index 50e8f1e64..f15271353 100644
--- a/Source/JavaScriptCore/API/JSBase.h
+++ b/Source/JavaScriptCore/API/JSBase.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,17 +10,17 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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.
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef JSBase_h
@@ -84,11 +84,6 @@ typedef struct OpaqueJSValue* JSObjectRef;
#define JS_EXPORT
#endif /* defined(JS_NO_EXPORT) */
-/* JS tests uses WTF but has no config.h, so we need to set the export defines here. */
-#ifndef WTF_EXPORT_PRIVATE
-#define WTF_EXPORT_PRIVATE JS_EXPORT
-#endif
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -101,8 +96,8 @@ extern "C" {
@param ctx The execution context to use.
@param script A JSString containing the script to evaluate.
@param thisObject The object to use as "this," or NULL to use the global object as "this."
-@param sourceURL A JSString containing a URL for the script's source file. This is only used when reporting exceptions. Pass NULL if you do not care to include source file information in exceptions.
-@param startingLineNumber An integer value specifying the script's starting line number in the file located at sourceURL. This is only used when reporting exceptions.
+@param sourceURL A JSString containing a URL for the script's source file. This is used by debuggers and when reporting exceptions. Pass NULL if you do not care to include source file information.
+@param startingLineNumber An integer value specifying the script's starting line number in the file located at sourceURL. This is only used when reporting exceptions. The value is one-based, so the first line is line 1 and invalid values are clamped to 1.
@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 The JSValue that results from evaluating script, or NULL if an exception is thrown.
*/
@@ -114,7 +109,7 @@ JS_EXPORT JSValueRef JSEvaluateScript(JSContextRef ctx, JSStringRef script, JSOb
@param ctx The execution context to use.
@param script A JSString containing the script to check for syntax errors.
@param sourceURL A JSString containing a URL for the script's source file. This is only used when reporting exceptions. Pass NULL if you do not care to include source file information in exceptions.
-@param startingLineNumber An integer value specifying the script's starting line number in the file located at sourceURL. This is only used when reporting exceptions.
+@param startingLineNumber An integer value specifying the script's starting line number in the file located at sourceURL. This is only used when reporting exceptions. The value is one-based, so the first line is line 1 and invalid values are clamped to 1.
@param exception A pointer to a JSValueRef in which to store a syntax error exception, if any. Pass NULL if you do not care to store a syntax error exception.
@result true if the script is syntactically correct, otherwise false.
*/
@@ -122,13 +117,13 @@ JS_EXPORT bool JSCheckScriptSyntax(JSContextRef ctx, JSStringRef script, JSStrin
/*!
@function JSGarbageCollect
-@abstract Performs a JavaScript garbage collection.
+@abstract Performs a JavaScript garbage collection.
@param ctx The execution context to use.
-@discussion JavaScript values that are on the machine stack, in a register,
- protected by JSValueProtect, set as the global object of an execution context,
+@discussion JavaScript values that are on the machine stack, in a register,
+ protected by JSValueProtect, set as the global object of an execution context,
or reachable from any such value will not be collected.
- During JavaScript execution, you are not required to call this function; the
+ During JavaScript execution, you are not required to call this function; the
JavaScript engine will garbage collect as needed. JavaScript values created
within a context group are automatically destroyed when the last reference
to the context group is released.
@@ -141,7 +136,7 @@ JS_EXPORT void JSGarbageCollect(JSContextRef ctx);
/* Enable the Objective-C API for platforms with a modern runtime. */
#if !defined(JSC_OBJC_API_ENABLED)
-#define JSC_OBJC_API_ENABLED (defined(__clang__) && defined(__APPLE__) && defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090 && !defined(__i386__))
+#define JSC_OBJC_API_ENABLED (defined(__clang__) && defined(__APPLE__) && ((defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && !defined(__i386__)) || (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE)))
#endif
#endif /* JSBase_h */
diff --git a/Source/JavaScriptCore/API/JSBasePrivate.h b/Source/JavaScriptCore/API/JSBasePrivate.h
index befa31643..137594972 100644
--- a/Source/JavaScriptCore/API/JSBasePrivate.h
+++ b/Source/JavaScriptCore/API/JSBasePrivate.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
@@ -43,7 +43,9 @@ owns a large non-GC memory region. Calling this function will encourage the
garbage collector to collect soon, hoping to reclaim that large non-GC memory
region.
*/
-JS_EXPORT void JSReportExtraMemoryCost(JSContextRef ctx, size_t size) AVAILABLE_IN_WEBKIT_VERSION_4_0;
+JS_EXPORT void JSReportExtraMemoryCost(JSContextRef ctx, size_t size) CF_AVAILABLE(10_6, 7_0);
+
+JS_EXPORT void JSDisableGCTimer(void);
#ifdef __cplusplus
}
diff --git a/Source/JavaScriptCore/API/JSCTestRunnerUtils.cpp b/Source/JavaScriptCore/API/JSCTestRunnerUtils.cpp
index 394246711..d314c5d48 100644
--- a/Source/JavaScriptCore/API/JSCTestRunnerUtils.cpp
+++ b/Source/JavaScriptCore/API/JSCTestRunnerUtils.cpp
@@ -27,45 +27,38 @@
#include "JSCTestRunnerUtils.h"
#include "APICast.h"
-#include "CodeBlock.h"
-#include "Operations.h"
+#include "JSCInlines.h"
+#include "TestRunnerUtils.h"
namespace JSC {
-static FunctionExecutable* getExecutable(JSContextRef context, JSValueRef theFunctionValueRef)
+
+JSValueRef failNextNewCodeBlock(JSContextRef context)
{
- ExecState* exec = toJS(context);
- JSValue theFunctionValue = toJS(exec, theFunctionValueRef);
-
- JSFunction* theFunction = jsDynamicCast<JSFunction*>(theFunctionValue);
- if (!theFunction)
- return 0;
-
- FunctionExecutable* executable = jsDynamicCast<FunctionExecutable*>(
- theFunction->executable());
- return executable;
+ ExecState* exec= toJS(context);
+ JSLockHolder holder(exec);
+ return toRef(exec, failNextNewCodeBlock(exec));
}
JSValueRef numberOfDFGCompiles(JSContextRef context, JSValueRef theFunctionValueRef)
{
- if (FunctionExecutable* executable = getExecutable(context, theFunctionValueRef)) {
- CodeBlock* baselineCodeBlock = executable->baselineCodeBlockFor(CodeForCall);
-
- if (!baselineCodeBlock)
- return JSValueMakeNumber(context, 0);
-
- return JSValueMakeNumber(context, baselineCodeBlock->numberOfDFGCompiles());
- }
-
- return JSValueMakeUndefined(context);
+ ExecState* exec= toJS(context);
+ JSLockHolder holder(exec);
+ return toRef(exec, numberOfDFGCompiles(toJS(exec, theFunctionValueRef)));
}
JSValueRef setNeverInline(JSContextRef context, JSValueRef theFunctionValueRef)
{
- if (FunctionExecutable* executable = getExecutable(context, theFunctionValueRef))
- executable->setNeverInline(true);
-
- return JSValueMakeUndefined(context);
+ ExecState* exec= toJS(context);
+ JSLockHolder holder(exec);
+ return toRef(exec, setNeverInline(toJS(exec, theFunctionValueRef)));
+}
+
+JSValueRef setNeverOptimize(JSContextRef context, JSValueRef theFunctionValueRef)
+{
+ ExecState* exec= toJS(context);
+ JSLockHolder holder(exec);
+ return toRef(exec, setNeverOptimize(toJS(exec, theFunctionValueRef)));
}
} // namespace JSC
diff --git a/Source/JavaScriptCore/API/JSCTestRunnerUtils.h b/Source/JavaScriptCore/API/JSCTestRunnerUtils.h
index aaecdd5c9..c52da524b 100644
--- a/Source/JavaScriptCore/API/JSCTestRunnerUtils.h
+++ b/Source/JavaScriptCore/API/JSCTestRunnerUtils.h
@@ -31,8 +31,10 @@
namespace JSC {
+JS_EXPORT_PRIVATE JSValueRef failNextNewCodeBlock(JSContextRef);
JS_EXPORT_PRIVATE JSValueRef numberOfDFGCompiles(JSContextRef, JSValueRef theFunction);
JS_EXPORT_PRIVATE JSValueRef setNeverInline(JSContextRef, JSValueRef theFunction);
+JS_EXPORT_PRIVATE JSValueRef setNeverOptimize(JSContextRef, JSValueRef theFunction);
} // namespace JSC
diff --git a/Source/JavaScriptCore/API/JSCallbackConstructor.cpp b/Source/JavaScriptCore/API/JSCallbackConstructor.cpp
index 8340c10b4..65e66dc13 100644
--- a/Source/JavaScriptCore/API/JSCallbackConstructor.cpp
+++ b/Source/JavaScriptCore/API/JSCallbackConstructor.cpp
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
@@ -26,18 +26,18 @@
#include "config.h"
#include "JSCallbackConstructor.h"
-#include "APIShims.h"
+#include "APICallbackFunction.h"
#include "APICast.h"
#include "Error.h"
#include "JSGlobalObject.h"
#include "JSLock.h"
#include "ObjectPrototype.h"
-#include "Operations.h"
+#include "JSCInlines.h"
#include <wtf/Vector.h>
namespace JSC {
-const ClassInfo JSCallbackConstructor::s_info = { "CallbackConstructor", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSCallbackConstructor) };
+const ClassInfo JSCallbackConstructor::s_info = { "CallbackConstructor", &Base::s_info, 0, CREATE_METHOD_TABLE(JSCallbackConstructor) };
JSCallbackConstructor::JSCallbackConstructor(JSGlobalObject* globalObject, Structure* structure, JSClassRef jsClass, JSObjectCallAsConstructorCallback callback)
: JSDestructibleObject(globalObject->vm(), structure)
@@ -49,7 +49,7 @@ JSCallbackConstructor::JSCallbackConstructor(JSGlobalObject* globalObject, Struc
void JSCallbackConstructor::finishCreation(JSGlobalObject* globalObject, JSClassRef jsClass)
{
Base::finishCreation(globalObject->vm());
- ASSERT(inherits(&s_info));
+ ASSERT(inherits(info()));
if (m_class)
JSClassRetain(jsClass);
}
@@ -65,40 +65,9 @@ void JSCallbackConstructor::destroy(JSCell* cell)
static_cast<JSCallbackConstructor*>(cell)->JSCallbackConstructor::~JSCallbackConstructor();
}
-static EncodedJSValue JSC_HOST_CALL constructJSCallback(ExecState* exec)
-{
- JSObject* constructor = exec->callee();
- JSContextRef ctx = toRef(exec);
- JSObjectRef constructorRef = toRef(constructor);
-
- JSObjectCallAsConstructorCallback callback = jsCast<JSCallbackConstructor*>(constructor)->callback();
- if (callback) {
- size_t argumentCount = exec->argumentCount();
- Vector<JSValueRef, 16> arguments;
- arguments.reserveInitialCapacity(argumentCount);
- for (size_t i = 0; i < argumentCount; ++i)
- arguments.uncheckedAppend(toRef(exec, exec->argument(i)));
-
- JSValueRef exception = 0;
- JSObjectRef result;
- {
- APICallbackShim callbackShim(exec);
- result = callback(ctx, constructorRef, argumentCount, arguments.data(), &exception);
- }
- if (exception)
- throwError(exec, toJS(exec, exception));
- // result must be a valid JSValue.
- if (!result)
- return throwVMTypeError(exec);
- return JSValue::encode(toJS(result));
- }
-
- return JSValue::encode(toJS(JSObjectMake(ctx, jsCast<JSCallbackConstructor*>(constructor)->classRef(), 0)));
-}
-
ConstructType JSCallbackConstructor::getConstructData(JSCell*, ConstructData& constructData)
{
- constructData.native.function = constructJSCallback;
+ constructData.native.function = APICallbackFunction::construct<JSCallbackConstructor>;
return ConstructTypeHost;
}
diff --git a/Source/JavaScriptCore/API/JSCallbackConstructor.h b/Source/JavaScriptCore/API/JSCallbackConstructor.h
index 72100e672..d730ad779 100644
--- a/Source/JavaScriptCore/API/JSCallbackConstructor.h
+++ b/Source/JavaScriptCore/API/JSCallbackConstructor.h
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
@@ -34,6 +34,7 @@ namespace JSC {
class JSCallbackConstructor : public JSDestructibleObject {
public:
typedef JSDestructibleObject Base;
+ static const unsigned StructureFlags = Base::StructureFlags | ImplementsHasInstance | ImplementsDefaultHasInstance;
static JSCallbackConstructor* create(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, JSClassRef classRef, JSObjectCallAsConstructorCallback callback)
{
@@ -46,21 +47,24 @@ public:
static void destroy(JSCell*);
JSClassRef classRef() const { return m_class; }
JSObjectCallAsConstructorCallback callback() const { return m_callback; }
- static const ClassInfo s_info;
+ DECLARE_INFO;
static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
{
- return Structure::create(vm, globalObject, proto, TypeInfo(ObjectType, StructureFlags), &s_info);
+ return Structure::create(vm, globalObject, proto, TypeInfo(ObjectType, StructureFlags), info());
}
protected:
JSCallbackConstructor(JSGlobalObject*, Structure*, JSClassRef, JSObjectCallAsConstructorCallback);
void finishCreation(JSGlobalObject*, JSClassRef);
- static const unsigned StructureFlags = ImplementsHasInstance | JSObject::StructureFlags;
private:
+ friend struct APICallbackFunction;
+
static ConstructType getConstructData(JSCell*, ConstructData&);
+ JSObjectCallAsConstructorCallback constructCallback() { return m_callback; }
+
JSClassRef m_class;
JSObjectCallAsConstructorCallback m_callback;
};
diff --git a/Source/JavaScriptCore/API/JSCallbackFunction.cpp b/Source/JavaScriptCore/API/JSCallbackFunction.cpp
index c29b9077c..047fcd01c 100644
--- a/Source/JavaScriptCore/API/JSCallbackFunction.cpp
+++ b/Source/JavaScriptCore/API/JSCallbackFunction.cpp
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
@@ -26,7 +26,7 @@
#include "config.h"
#include "JSCallbackFunction.h"
-#include "APIShims.h"
+#include "APICallbackFunction.h"
#include "APICast.h"
#include "CodeBlock.h"
#include "Error.h"
@@ -35,17 +35,17 @@
#include "JSFunction.h"
#include "JSGlobalObject.h"
#include "JSLock.h"
-#include "Operations.h"
+#include "JSCInlines.h"
#include <wtf/Vector.h>
namespace JSC {
-ASSERT_HAS_TRIVIAL_DESTRUCTOR(JSCallbackFunction);
+STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(JSCallbackFunction);
-const ClassInfo JSCallbackFunction::s_info = { "CallbackFunction", &InternalFunction::s_info, 0, 0, CREATE_METHOD_TABLE(JSCallbackFunction) };
+const ClassInfo JSCallbackFunction::s_info = { "CallbackFunction", &InternalFunction::s_info, 0, CREATE_METHOD_TABLE(JSCallbackFunction) };
-JSCallbackFunction::JSCallbackFunction(JSGlobalObject* globalObject, Structure* structure, JSObjectCallAsFunctionCallback callback)
- : InternalFunction(globalObject, structure)
+JSCallbackFunction::JSCallbackFunction(VM& vm, Structure* structure, JSObjectCallAsFunctionCallback callback)
+ : InternalFunction(vm, structure)
, m_callback(callback)
{
}
@@ -53,47 +53,19 @@ JSCallbackFunction::JSCallbackFunction(JSGlobalObject* globalObject, Structure*
void JSCallbackFunction::finishCreation(VM& vm, const String& name)
{
Base::finishCreation(vm, name);
- ASSERT(inherits(&s_info));
+ ASSERT(inherits(info()));
}
-JSCallbackFunction* JSCallbackFunction::create(ExecState* exec, JSGlobalObject* globalObject, JSObjectCallAsFunctionCallback callback, const String& name)
+JSCallbackFunction* JSCallbackFunction::create(VM& vm, JSGlobalObject* globalObject, JSObjectCallAsFunctionCallback callback, const String& name)
{
- JSCallbackFunction* function = new (NotNull, allocateCell<JSCallbackFunction>(*exec->heap())) JSCallbackFunction(globalObject, globalObject->callbackFunctionStructure(), callback);
- function->finishCreation(exec->vm(), name);
+ JSCallbackFunction* function = new (NotNull, allocateCell<JSCallbackFunction>(vm.heap)) JSCallbackFunction(vm, globalObject->callbackFunctionStructure(), callback);
+ function->finishCreation(vm, name);
return function;
}
-EncodedJSValue JSCallbackFunction::call(ExecState* exec)
-{
- JSContextRef execRef = toRef(exec);
- JSObjectRef functionRef = toRef(exec->callee());
- JSObjectRef thisObjRef = toRef(exec->hostThisValue().toThisObject(exec));
-
- size_t argumentCount = exec->argumentCount();
- Vector<JSValueRef, 16> arguments;
- arguments.reserveInitialCapacity(argumentCount);
- for (size_t i = 0; i < argumentCount; ++i)
- arguments.uncheckedAppend(toRef(exec, exec->argument(i)));
-
- JSValueRef exception = 0;
- JSValueRef result;
- {
- APICallbackShim callbackShim(exec);
- result = jsCast<JSCallbackFunction*>(toJS(functionRef))->m_callback(execRef, functionRef, thisObjRef, argumentCount, arguments.data(), &exception);
- }
- if (exception)
- throwError(exec, toJS(exec, exception));
-
- // result must be a valid JSValue.
- if (!result)
- return JSValue::encode(jsUndefined());
-
- return JSValue::encode(toJS(exec, result));
-}
-
CallType JSCallbackFunction::getCallData(JSCell*, CallData& callData)
{
- callData.native.function = call;
+ callData.native.function = APICallbackFunction::call<JSCallbackFunction>;
return CallTypeHost;
}
diff --git a/Source/JavaScriptCore/API/JSCallbackFunction.h b/Source/JavaScriptCore/API/JSCallbackFunction.h
index 885ef949d..a4fdd068f 100644
--- a/Source/JavaScriptCore/API/JSCallbackFunction.h
+++ b/Source/JavaScriptCore/API/JSCallbackFunction.h
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
@@ -32,29 +32,28 @@
namespace JSC {
class JSCallbackFunction : public InternalFunction {
-protected:
- JSCallbackFunction(JSGlobalObject*, Structure*, JSObjectCallAsFunctionCallback);
- void finishCreation(VM&, const String& name);
-
+ friend struct APICallbackFunction;
public:
typedef InternalFunction Base;
- static JSCallbackFunction* create(ExecState*, JSGlobalObject*, JSObjectCallAsFunctionCallback, const String& name);
+ static JSCallbackFunction* create(VM&, JSGlobalObject*, JSObjectCallAsFunctionCallback, const String& name);
- static const ClassInfo s_info;
+ DECLARE_INFO;
// InternalFunction mish-mashes constructor and function behavior -- we should
// refactor the code so this override isn't necessary
static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
{
- return Structure::create(vm, globalObject, proto, TypeInfo(ObjectType, StructureFlags), &s_info);
+ return Structure::create(vm, globalObject, proto, TypeInfo(ObjectType, StructureFlags), info());
}
-protected:
+private:
+ JSCallbackFunction(VM&, Structure*, JSObjectCallAsFunctionCallback);
+ void finishCreation(VM&, const String& name);
+
static CallType getCallData(JSCell*, CallData&);
-private:
- static EncodedJSValue JSC_HOST_CALL call(ExecState*);
+ JSObjectCallAsFunctionCallback functionCallback() { return m_callback; }
JSObjectCallAsFunctionCallback m_callback;
};
diff --git a/Source/JavaScriptCore/API/JSCallbackObject.cpp b/Source/JavaScriptCore/API/JSCallbackObject.cpp
index 7436e71f7..02b38fde7 100644
--- a/Source/JavaScriptCore/API/JSCallbackObject.cpp
+++ b/Source/JavaScriptCore/API/JSCallbackObject.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006 Apple Inc. All rights reserved.
* Copyright (C) 2007 Eric Seidel <eric@webkit.org>
*
* Redistribution and use in source and binary forms, with or without
@@ -11,10 +11,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
@@ -28,14 +28,14 @@
#include "JSCallbackObject.h"
#include "Heap.h"
-#include "Operations.h"
+#include "JSCInlines.h"
#include <wtf/text/StringHash.h>
namespace JSC {
// Define the two types of JSCallbackObjects we support.
-template <> const ClassInfo JSCallbackObject<JSDestructibleObject>::s_info = { "CallbackObject", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSCallbackObject) };
-template <> const ClassInfo JSCallbackObject<JSGlobalObject>::s_info = { "CallbackGlobalObject", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSCallbackObject) };
+template <> const ClassInfo JSCallbackObject<JSDestructibleObject>::s_info = { "CallbackObject", &Base::s_info, 0, CREATE_METHOD_TABLE(JSCallbackObject) };
+template <> const ClassInfo JSCallbackObject<JSGlobalObject>::s_info = { "CallbackGlobalObject", &Base::s_info, 0, CREATE_METHOD_TABLE(JSCallbackObject) };
template<> const bool JSCallbackObject<JSDestructibleObject>::needsDestruction = true;
template<> const bool JSCallbackObject<JSGlobalObject>::needsDestruction = false;
@@ -43,7 +43,7 @@ template<> const bool JSCallbackObject<JSGlobalObject>::needsDestruction = false
template<>
JSCallbackObject<JSGlobalObject>* JSCallbackObject<JSGlobalObject>::create(VM& vm, JSClassRef classRef, Structure* structure)
{
- JSCallbackObject<JSGlobalObject>* callbackObject = new (NotNull, allocateCell<JSCallbackObject<JSGlobalObject> >(vm.heap)) JSCallbackObject(vm, classRef, structure);
+ JSCallbackObject<JSGlobalObject>* callbackObject = new (NotNull, allocateCell<JSCallbackObject<JSGlobalObject>>(vm.heap)) JSCallbackObject(vm, classRef, structure);
callbackObject->finishCreation(vm);
vm.heap.addFinalizer(callbackObject, destroy);
return callbackObject;
@@ -52,24 +52,13 @@ JSCallbackObject<JSGlobalObject>* JSCallbackObject<JSGlobalObject>::create(VM& v
template <>
Structure* JSCallbackObject<JSDestructibleObject>::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
{
- return Structure::create(vm, globalObject, proto, TypeInfo(ObjectType, StructureFlags), &s_info);
+ return Structure::create(vm, globalObject, proto, TypeInfo(ObjectType, StructureFlags), info());
}
template <>
Structure* JSCallbackObject<JSGlobalObject>::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
{
- return Structure::create(vm, globalObject, proto, TypeInfo(GlobalObjectType, StructureFlags), &s_info);
+ return Structure::create(vm, globalObject, proto, TypeInfo(GlobalObjectType, StructureFlags), info());
}
-void JSCallbackObjectData::finalize(Handle<Unknown> handle, void* context)
-{
- JSClassRef jsClass = static_cast<JSClassRef>(context);
- JSObjectRef thisRef = toRef(static_cast<JSObject*>(handle.get().asCell()));
-
- for (; jsClass; jsClass = jsClass->parentClass)
- if (JSObjectFinalizeCallback finalize = jsClass->finalize)
- finalize(thisRef);
- WeakSet::deallocate(WeakImpl::asWeakImpl(handle.slot()));
-}
-
} // namespace JSC
diff --git a/Source/JavaScriptCore/API/JSCallbackObject.h b/Source/JavaScriptCore/API/JSCallbackObject.h
index 16d8aa2c6..8356e704d 100644
--- a/Source/JavaScriptCore/API/JSCallbackObject.h
+++ b/Source/JavaScriptCore/API/JSCallbackObject.h
@@ -11,10 +11,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
@@ -30,11 +30,12 @@
#include "JSObjectRef.h"
#include "JSValueRef.h"
#include "JSObject.h"
-#include <wtf/PassOwnPtr.h>
namespace JSC {
-struct JSCallbackObjectData : WeakHandleOwner {
+struct JSCallbackObjectData {
+ WTF_MAKE_FAST_ALLOCATED;
+public:
JSCallbackObjectData(void* privateData, JSClassRef jsClass)
: privateData(privateData)
, jsClass(jsClass)
@@ -57,7 +58,7 @@ struct JSCallbackObjectData : WeakHandleOwner {
void setPrivateProperty(VM& vm, JSCell* owner, const Identifier& propertyName, JSValue value)
{
if (!m_privateProperties)
- m_privateProperties = adoptPtr(new JSPrivatePropertyMap);
+ m_privateProperties = std::make_unique<JSPrivatePropertyMap>();
m_privateProperties->setPrivateProperty(vm, owner, propertyName, value);
}
@@ -78,6 +79,8 @@ struct JSCallbackObjectData : WeakHandleOwner {
void* privateData;
JSClassRef jsClass;
struct JSPrivatePropertyMap {
+ WTF_MAKE_FAST_ALLOCATED;
+ public:
JSValue getPrivateProperty(const Identifier& propertyName) const
{
PrivatePropertyMap::const_iterator location = m_propertyMap.find(propertyName.impl());
@@ -106,11 +109,10 @@ struct JSCallbackObjectData : WeakHandleOwner {
}
private:
- typedef HashMap<RefPtr<StringImpl>, WriteBarrier<Unknown>, IdentifierRepHash> PrivatePropertyMap;
+ typedef HashMap<RefPtr<UniquedStringImpl>, WriteBarrier<Unknown>, IdentifierRepHash> PrivatePropertyMap;
PrivatePropertyMap m_propertyMap;
};
- OwnPtr<JSPrivatePropertyMap> m_privateProperties;
- virtual void finalize(Handle<Unknown>, void*);
+ std::unique_ptr<JSPrivatePropertyMap> m_privateProperties;
};
@@ -125,6 +127,9 @@ protected:
public:
typedef Parent Base;
+ static const unsigned StructureFlags = Base::StructureFlags | ProhibitsPropertyCaching | OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | ImplementsHasInstance | OverridesGetPropertyNames | TypeOfShouldCallGetCallData;
+
+ ~JSCallbackObject();
static JSCallbackObject* create(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, JSClassRef classRef, void* data)
{
@@ -144,7 +149,19 @@ public:
void setPrivate(void* data);
void* getPrivate();
- static const ClassInfo s_info;
+ // FIXME: We should fix the warnings for extern-template in JSObject template classes: https://bugs.webkit.org/show_bug.cgi?id=161979
+#if COMPILER(CLANG)
+#if __has_warning("-Wundefined-var-template")
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wundefined-var-template"
+#endif
+#endif
+ DECLARE_INFO;
+#if COMPILER(CLANG)
+#if __has_warning("-Wundefined-var-template")
+#pragma clang diagnostic pop
+#endif
+#endif
JSClassRef classRef() const { return m_callbackObjectData->jsClass; }
bool inherits(JSClassRef) const;
@@ -168,17 +185,13 @@ public:
using Parent::methodTable;
-protected:
- static const unsigned StructureFlags = ProhibitsPropertyCaching | OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | ImplementsHasInstance | OverridesHasInstance | OverridesVisitChildren | OverridesGetPropertyNames | Parent::StructureFlags;
-
private:
static String className(const JSObject*);
static JSValue defaultValue(const JSObject*, ExecState*, PreferredPrimitiveType);
- static bool getOwnPropertySlot(JSCell*, ExecState*, PropertyName, PropertySlot&);
- static bool getOwnPropertySlotByIndex(JSCell*, ExecState*, unsigned propertyName, PropertySlot&);
- static bool getOwnPropertyDescriptor(JSObject*, ExecState*, PropertyName, PropertyDescriptor&);
+ static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
+ static bool getOwnPropertySlotByIndex(JSObject*, ExecState*, unsigned propertyName, PropertySlot&);
static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
static void putByIndex(JSCell*, ExecState*, unsigned, JSValue, bool shouldThrow);
@@ -196,9 +209,7 @@ private:
static void visitChildren(JSCell* cell, SlotVisitor& visitor)
{
JSCallbackObject* thisObject = jsCast<JSCallbackObject*>(cell);
- ASSERT_GC_OBJECT_INHERITS((static_cast<Parent*>(thisObject)), &JSCallbackObject<Parent>::s_info);
- COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
- ASSERT(thisObject->Parent::structure()->typeInfo().overridesVisitChildren());
+ ASSERT_GC_OBJECT_INHERITS((static_cast<Parent*>(thisObject)), JSCallbackObject<Parent>::info());
Parent::visitChildren(thisObject, visitor);
thisObject->m_callbackObjectData->visitChildren(visitor);
}
@@ -206,15 +217,16 @@ private:
void init(ExecState*);
static JSCallbackObject* asCallbackObject(JSValue);
+ static JSCallbackObject* asCallbackObject(EncodedJSValue);
static EncodedJSValue JSC_HOST_CALL call(ExecState*);
static EncodedJSValue JSC_HOST_CALL construct(ExecState*);
JSValue getStaticValue(ExecState*, PropertyName);
- static JSValue staticFunctionGetter(ExecState*, JSValue, PropertyName);
- static JSValue callbackGetter(ExecState*, JSValue, PropertyName);
+ static EncodedJSValue staticFunctionGetter(ExecState*, EncodedJSValue, PropertyName);
+ static EncodedJSValue callbackGetter(ExecState*, EncodedJSValue, PropertyName);
- OwnPtr<JSCallbackObjectData> m_callbackObjectData;
+ std::unique_ptr<JSCallbackObjectData> m_callbackObjectData;
};
} // namespace JSC
diff --git a/Source/JavaScriptCore/API/JSCallbackObjectFunctions.h b/Source/JavaScriptCore/API/JSCallbackObjectFunctions.h
index b92e3161e..6e0a6ceb4 100644
--- a/Source/JavaScriptCore/API/JSCallbackObjectFunctions.h
+++ b/Source/JavaScriptCore/API/JSCallbackObjectFunctions.h
@@ -11,10 +11,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
@@ -24,7 +24,6 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "APIShims.h"
#include "APICast.h"
#include "Error.h"
#include "ExceptionHelpers.h"
@@ -45,14 +44,21 @@ namespace JSC {
template <class Parent>
inline JSCallbackObject<Parent>* JSCallbackObject<Parent>::asCallbackObject(JSValue value)
{
- ASSERT(asObject(value)->inherits(&s_info));
+ ASSERT(asObject(value)->inherits(info()));
return jsCast<JSCallbackObject*>(asObject(value));
}
template <class Parent>
+inline JSCallbackObject<Parent>* JSCallbackObject<Parent>::asCallbackObject(EncodedJSValue value)
+{
+ ASSERT(asObject(JSValue::decode(value))->inherits(info()));
+ return jsCast<JSCallbackObject*>(asObject(JSValue::decode(value)));
+}
+
+template <class Parent>
JSCallbackObject<Parent>::JSCallbackObject(ExecState* exec, Structure* structure, JSClassRef jsClass, void* data)
: Parent(exec->vm(), structure)
- , m_callbackObjectData(adoptPtr(new JSCallbackObjectData(data, jsClass)))
+ , m_callbackObjectData(std::make_unique<JSCallbackObjectData>(data, jsClass))
{
}
@@ -61,15 +67,25 @@ JSCallbackObject<Parent>::JSCallbackObject(ExecState* exec, Structure* structure
template <class Parent>
JSCallbackObject<Parent>::JSCallbackObject(VM& vm, JSClassRef jsClass, Structure* structure)
: Parent(vm, structure)
- , m_callbackObjectData(adoptPtr(new JSCallbackObjectData(0, jsClass)))
+ , m_callbackObjectData(std::make_unique<JSCallbackObjectData>(nullptr, jsClass))
{
}
template <class Parent>
+JSCallbackObject<Parent>::~JSCallbackObject()
+{
+ JSObjectRef thisRef = toRef(static_cast<JSObject*>(this));
+ for (JSClassRef jsClass = classRef(); jsClass; jsClass = jsClass->parentClass) {
+ if (JSObjectFinalizeCallback finalize = jsClass->finalize)
+ finalize(thisRef);
+ }
+}
+
+template <class Parent>
void JSCallbackObject<Parent>::finishCreation(ExecState* exec)
{
Base::finishCreation(exec->vm());
- ASSERT(Parent::inherits(&s_info));
+ ASSERT(Parent::inherits(info()));
init(exec);
}
@@ -77,7 +93,7 @@ void JSCallbackObject<Parent>::finishCreation(ExecState* exec)
template <class Parent>
void JSCallbackObject<Parent>::finishCreation(VM& vm)
{
- ASSERT(Parent::inherits(&s_info));
+ ASSERT(Parent::inherits(info()));
ASSERT(Parent::isGlobalObject());
Base::finishCreation(vm);
init(jsCast<JSGlobalObject*>(this)->globalExec());
@@ -97,17 +113,10 @@ void JSCallbackObject<Parent>::init(ExecState* exec)
// initialize from base to derived
for (int i = static_cast<int>(initRoutines.size()) - 1; i >= 0; i--) {
- APICallbackShim callbackShim(exec);
+ JSLock::DropAllLocks dropAllLocks(exec);
JSObjectInitializeCallback initialize = initRoutines[i];
initialize(toRef(exec), toRef(this));
}
-
- for (JSClassRef jsClassPtr = classRef(); jsClassPtr; jsClassPtr = jsClassPtr->parentClass) {
- if (jsClassPtr->finalize) {
- WeakSet::allocate(this, m_callbackObjectData.get(), classRef());
- break;
- }
- }
}
template <class Parent>
@@ -122,22 +131,22 @@ String JSCallbackObject<Parent>::className(const JSObject* object)
}
template <class Parent>
-bool JSCallbackObject<Parent>::getOwnPropertySlot(JSCell* cell, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
+bool JSCallbackObject<Parent>::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
{
- JSCallbackObject* thisObject = jsCast<JSCallbackObject*>(cell);
+ JSCallbackObject* thisObject = jsCast<JSCallbackObject*>(object);
JSContextRef ctx = toRef(exec);
JSObjectRef thisRef = toRef(thisObject);
RefPtr<OpaqueJSString> propertyNameRef;
- if (StringImpl* name = propertyName.publicName()) {
+ if (StringImpl* name = propertyName.uid()) {
for (JSClassRef jsClass = thisObject->classRef(); jsClass; jsClass = jsClass->parentClass) {
// optional optimization to bypass getProperty in cases when we only need to know if the property exists
if (JSObjectHasPropertyCallback hasProperty = jsClass->hasProperty) {
if (!propertyNameRef)
propertyNameRef = OpaqueJSString::create(name);
- APICallbackShim callbackShim(exec);
+ JSLock::DropAllLocks dropAllLocks(exec);
if (hasProperty(ctx, thisRef, propertyNameRef.get())) {
- slot.setCustom(thisObject, callbackGetter);
+ slot.setCustom(thisObject, ReadOnly | DontEnum, callbackGetter);
return true;
}
} else if (JSObjectGetPropertyCallback getProperty = jsClass->getProperty) {
@@ -146,16 +155,16 @@ bool JSCallbackObject<Parent>::getOwnPropertySlot(JSCell* cell, ExecState* exec,
JSValueRef exception = 0;
JSValueRef value;
{
- APICallbackShim callbackShim(exec);
+ JSLock::DropAllLocks dropAllLocks(exec);
value = getProperty(ctx, thisRef, propertyNameRef.get(), &exception);
}
if (exception) {
- throwError(exec, toJS(exec, exception));
- slot.setValue(jsUndefined());
+ exec->vm().throwException(exec, toJS(exec, exception));
+ slot.setValue(thisObject, ReadOnly | DontEnum, jsUndefined());
return true;
}
if (value) {
- slot.setValue(toJS(exec, value));
+ slot.setValue(thisObject, ReadOnly | DontEnum, toJS(exec, value));
return true;
}
}
@@ -164,7 +173,7 @@ bool JSCallbackObject<Parent>::getOwnPropertySlot(JSCell* cell, ExecState* exec,
if (staticValues->contains(name)) {
JSValue value = thisObject->getStaticValue(exec, propertyName);
if (value) {
- slot.setValue(value);
+ slot.setValue(thisObject, ReadOnly | DontEnum, value);
return true;
}
}
@@ -172,7 +181,7 @@ bool JSCallbackObject<Parent>::getOwnPropertySlot(JSCell* cell, ExecState* exec,
if (OpaqueJSClassStaticFunctionsTable* staticFunctions = jsClass->staticFunctions(exec)) {
if (staticFunctions->contains(name)) {
- slot.setCustom(thisObject, staticFunctionGetter);
+ slot.setCustom(thisObject, ReadOnly | DontEnum, staticFunctionGetter);
return true;
}
}
@@ -183,9 +192,9 @@ bool JSCallbackObject<Parent>::getOwnPropertySlot(JSCell* cell, ExecState* exec,
}
template <class Parent>
-bool JSCallbackObject<Parent>::getOwnPropertySlotByIndex(JSCell* cell, ExecState* exec, unsigned propertyName, PropertySlot& slot)
+bool JSCallbackObject<Parent>::getOwnPropertySlotByIndex(JSObject* object, ExecState* exec, unsigned propertyName, PropertySlot& slot)
{
- return cell->methodTable()->getOwnPropertySlot(cell, exec, Identifier::from(exec, propertyName), slot);
+ return object->methodTable()->getOwnPropertySlot(object, exec, Identifier::from(exec, propertyName), slot);
}
template <class Parent>
@@ -201,7 +210,7 @@ JSValue JSCallbackObject<Parent>::defaultValue(const JSObject* object, ExecState
JSValueRef exception = 0;
JSValueRef result = convertToType(ctx, thisRef, jsHint, &exception);
if (exception) {
- throwError(exec, toJS(exec, exception));
+ exec->vm().throwException(exec, toJS(exec, exception));
return jsUndefined();
}
if (result)
@@ -213,26 +222,6 @@ JSValue JSCallbackObject<Parent>::defaultValue(const JSObject* object, ExecState
}
template <class Parent>
-bool JSCallbackObject<Parent>::getOwnPropertyDescriptor(JSObject* object, ExecState* exec, PropertyName propertyName, PropertyDescriptor& descriptor)
-{
- JSCallbackObject* thisObject = jsCast<JSCallbackObject*>(object);
- PropertySlot slot(thisObject);
- if (thisObject->methodTable()->getOwnPropertySlot(thisObject, exec, propertyName, slot)) {
- // Ideally we should return an access descriptor, but returning a value descriptor is better than nothing.
- JSValue value = slot.getValue(exec, propertyName);
- if (!exec->hadException())
- descriptor.setValue(value);
- // We don't know whether the property is configurable, but assume it is.
- descriptor.setConfigurable(true);
- // We don't know whether the property is enumerable (we could call getOwnPropertyNames() to find out), but assume it isn't.
- descriptor.setEnumerable(false);
- return true;
- }
-
- return Parent::getOwnPropertyDescriptor(thisObject, exec, propertyName, descriptor);
-}
-
-template <class Parent>
void JSCallbackObject<Parent>::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot& slot)
{
JSCallbackObject* thisObject = jsCast<JSCallbackObject*>(cell);
@@ -241,7 +230,7 @@ void JSCallbackObject<Parent>::put(JSCell* cell, ExecState* exec, PropertyName p
RefPtr<OpaqueJSString> propertyNameRef;
JSValueRef valueRef = toRef(exec, value);
- if (StringImpl* name = propertyName.publicName()) {
+ if (StringImpl* name = propertyName.uid()) {
for (JSClassRef jsClass = thisObject->classRef(); jsClass; jsClass = jsClass->parentClass) {
if (JSObjectSetPropertyCallback setProperty = jsClass->setProperty) {
if (!propertyNameRef)
@@ -249,11 +238,11 @@ void JSCallbackObject<Parent>::put(JSCell* cell, ExecState* exec, PropertyName p
JSValueRef exception = 0;
bool result;
{
- APICallbackShim callbackShim(exec);
+ JSLock::DropAllLocks dropAllLocks(exec);
result = setProperty(ctx, thisRef, propertyNameRef.get(), valueRef, &exception);
}
if (exception)
- throwError(exec, toJS(exec, exception));
+ exec->vm().throwException(exec, toJS(exec, exception));
if (result || exception)
return;
}
@@ -263,16 +252,14 @@ void JSCallbackObject<Parent>::put(JSCell* cell, ExecState* exec, PropertyName p
if (entry->attributes & kJSPropertyAttributeReadOnly)
return;
if (JSObjectSetPropertyCallback setProperty = entry->setProperty) {
- if (!propertyNameRef)
- propertyNameRef = OpaqueJSString::create(name);
JSValueRef exception = 0;
bool result;
{
- APICallbackShim callbackShim(exec);
- result = setProperty(ctx, thisRef, propertyNameRef.get(), valueRef, &exception);
+ JSLock::DropAllLocks dropAllLocks(exec);
+ result = setProperty(ctx, thisRef, entry->propertyNameRef.get(), valueRef, &exception);
}
if (exception)
- throwError(exec, toJS(exec, exception));
+ exec->vm().throwException(exec, toJS(exec, exception));
if (result || exception)
return;
}
@@ -281,6 +268,9 @@ void JSCallbackObject<Parent>::put(JSCell* cell, ExecState* exec, PropertyName p
if (OpaqueJSClassStaticFunctionsTable* staticFunctions = jsClass->staticFunctions(exec)) {
if (StaticFunctionEntry* entry = staticFunctions->get(name)) {
+ PropertySlot getSlot(thisObject, PropertySlot::InternalMethodType::VMInquiry);
+ if (Parent::getOwnPropertySlot(thisObject, exec, propertyName, getSlot))
+ return Parent::put(thisObject, exec, propertyName, value, slot);
if (entry->attributes & kJSPropertyAttributeReadOnly)
return;
thisObject->JSCallbackObject<Parent>::putDirect(exec->vm(), propertyName, value); // put as override property
@@ -301,7 +291,7 @@ void JSCallbackObject<Parent>::putByIndex(JSCell* cell, ExecState* exec, unsigne
JSObjectRef thisRef = toRef(thisObject);
RefPtr<OpaqueJSString> propertyNameRef;
JSValueRef valueRef = toRef(exec, value);
- Identifier propertyName = Identifier(exec, String::number(propertyIndex));
+ Identifier propertyName = Identifier::from(exec, propertyIndex);
for (JSClassRef jsClass = thisObject->classRef(); jsClass; jsClass = jsClass->parentClass) {
if (JSObjectSetPropertyCallback setProperty = jsClass->setProperty) {
@@ -310,11 +300,11 @@ void JSCallbackObject<Parent>::putByIndex(JSCell* cell, ExecState* exec, unsigne
JSValueRef exception = 0;
bool result;
{
- APICallbackShim callbackShim(exec);
+ JSLock::DropAllLocks dropAllLocks(exec);
result = setProperty(ctx, thisRef, propertyNameRef.get(), valueRef, &exception);
}
if (exception)
- throwError(exec, toJS(exec, exception));
+ exec->vm().throwException(exec, toJS(exec, exception));
if (result || exception)
return;
}
@@ -324,16 +314,14 @@ void JSCallbackObject<Parent>::putByIndex(JSCell* cell, ExecState* exec, unsigne
if (entry->attributes & kJSPropertyAttributeReadOnly)
return;
if (JSObjectSetPropertyCallback setProperty = entry->setProperty) {
- if (!propertyNameRef)
- propertyNameRef = OpaqueJSString::create(propertyName.impl());
JSValueRef exception = 0;
bool result;
{
- APICallbackShim callbackShim(exec);
- result = setProperty(ctx, thisRef, propertyNameRef.get(), valueRef, &exception);
+ JSLock::DropAllLocks dropAllLocks(exec);
+ result = setProperty(ctx, thisRef, entry->propertyNameRef.get(), valueRef, &exception);
}
if (exception)
- throwError(exec, toJS(exec, exception));
+ exec->vm().throwException(exec, toJS(exec, exception));
if (result || exception)
return;
}
@@ -360,7 +348,7 @@ bool JSCallbackObject<Parent>::deleteProperty(JSCell* cell, ExecState* exec, Pro
JSObjectRef thisRef = toRef(thisObject);
RefPtr<OpaqueJSString> propertyNameRef;
- if (StringImpl* name = propertyName.publicName()) {
+ if (StringImpl* name = propertyName.uid()) {
for (JSClassRef jsClass = thisObject->classRef(); jsClass; jsClass = jsClass->parentClass) {
if (JSObjectDeletePropertyCallback deleteProperty = jsClass->deleteProperty) {
if (!propertyNameRef)
@@ -368,11 +356,11 @@ bool JSCallbackObject<Parent>::deleteProperty(JSCell* cell, ExecState* exec, Pro
JSValueRef exception = 0;
bool result;
{
- APICallbackShim callbackShim(exec);
+ JSLock::DropAllLocks dropAllLocks(exec);
result = deleteProperty(ctx, thisRef, propertyNameRef.get(), &exception);
}
if (exception)
- throwError(exec, toJS(exec, exception));
+ exec->vm().throwException(exec, toJS(exec, exception));
if (result || exception)
return true;
}
@@ -431,15 +419,15 @@ EncodedJSValue JSCallbackObject<Parent>::construct(ExecState* exec)
Vector<JSValueRef, 16> arguments;
arguments.reserveInitialCapacity(argumentCount);
for (size_t i = 0; i < argumentCount; ++i)
- arguments.uncheckedAppend(toRef(exec, exec->argument(i)));
+ arguments.uncheckedAppend(toRef(exec, exec->uncheckedArgument(i)));
JSValueRef exception = 0;
JSObject* result;
{
- APICallbackShim callbackShim(exec);
+ JSLock::DropAllLocks dropAllLocks(exec);
result = toJS(callAsConstructor(execRef, constructorRef, argumentCount, arguments.data(), &exception));
}
if (exception)
- throwError(exec, toJS(exec, exception));
+ exec->vm().throwException(exec, toJS(exec, exception));
return JSValue::encode(result);
}
}
@@ -461,11 +449,11 @@ bool JSCallbackObject<Parent>::customHasInstance(JSObject* object, ExecState* ex
JSValueRef exception = 0;
bool result;
{
- APICallbackShim callbackShim(exec);
+ JSLock::DropAllLocks dropAllLocks(exec);
result = hasInstance(execRef, thisRef, valueRef, &exception);
}
if (exception)
- throwError(exec, toJS(exec, exception));
+ exec->vm().throwException(exec, toJS(exec, exception));
return result;
}
}
@@ -490,7 +478,7 @@ EncodedJSValue JSCallbackObject<Parent>::call(ExecState* exec)
{
JSContextRef execRef = toRef(exec);
JSObjectRef functionRef = toRef(exec->callee());
- JSObjectRef thisObjRef = toRef(exec->hostThisValue().toThisObject(exec));
+ JSObjectRef thisObjRef = toRef(jsCast<JSObject*>(exec->thisValue().toThis(exec, NotStrictMode)));
for (JSClassRef jsClass = jsCast<JSCallbackObject<Parent>*>(toJS(functionRef))->classRef(); jsClass; jsClass = jsClass->parentClass) {
if (JSObjectCallAsFunctionCallback callAsFunction = jsClass->callAsFunction) {
@@ -498,15 +486,15 @@ EncodedJSValue JSCallbackObject<Parent>::call(ExecState* exec)
Vector<JSValueRef, 16> arguments;
arguments.reserveInitialCapacity(argumentCount);
for (size_t i = 0; i < argumentCount; ++i)
- arguments.uncheckedAppend(toRef(exec, exec->argument(i)));
+ arguments.uncheckedAppend(toRef(exec, exec->uncheckedArgument(i)));
JSValueRef exception = 0;
JSValue result;
{
- APICallbackShim callbackShim(exec);
+ JSLock::DropAllLocks dropAllLocks(exec);
result = toJS(exec, callAsFunction(execRef, functionRef, thisObjRef, argumentCount, arguments.data(), &exception));
}
if (exception)
- throwError(exec, toJS(exec, exception));
+ exec->vm().throwException(exec, toJS(exec, exception));
return JSValue::encode(result);
}
}
@@ -524,7 +512,7 @@ void JSCallbackObject<Parent>::getOwnNonIndexPropertyNames(JSObject* object, Exe
for (JSClassRef jsClass = thisObject->classRef(); jsClass; jsClass = jsClass->parentClass) {
if (JSObjectGetPropertyNamesCallback getPropertyNames = jsClass->getPropertyNames) {
- APICallbackShim callbackShim(exec);
+ JSLock::DropAllLocks dropAllLocks(exec);
getPropertyNames(execRef, thisRef, toRef(&propertyNames));
}
@@ -534,8 +522,10 @@ void JSCallbackObject<Parent>::getOwnNonIndexPropertyNames(JSObject* object, Exe
for (iterator it = staticValues->begin(); it != end; ++it) {
StringImpl* name = it->key.get();
StaticValueEntry* entry = it->value.get();
- if (entry->getProperty && (!(entry->attributes & kJSPropertyAttributeDontEnum) || (mode == IncludeDontEnumProperties)))
- propertyNames.add(Identifier(exec, name));
+ if (entry->getProperty && (!(entry->attributes & kJSPropertyAttributeDontEnum) || mode.includeDontEnumProperties())) {
+ ASSERT(!name->isSymbol());
+ propertyNames.add(Identifier::fromString(exec, String(name)));
+ }
}
}
@@ -545,8 +535,10 @@ void JSCallbackObject<Parent>::getOwnNonIndexPropertyNames(JSObject* object, Exe
for (iterator it = staticFunctions->begin(); it != end; ++it) {
StringImpl* name = it->key.get();
StaticFunctionEntry* entry = it->value.get();
- if (!(entry->attributes & kJSPropertyAttributeDontEnum) || (mode == IncludeDontEnumProperties))
- propertyNames.add(Identifier(exec, name));
+ if (!(entry->attributes & kJSPropertyAttributeDontEnum) || mode.includeDontEnumProperties()) {
+ ASSERT(!name->isSymbol());
+ propertyNames.add(Identifier::fromString(exec, String(name)));
+ }
}
}
}
@@ -580,23 +572,20 @@ template <class Parent>
JSValue JSCallbackObject<Parent>::getStaticValue(ExecState* exec, PropertyName propertyName)
{
JSObjectRef thisRef = toRef(this);
- RefPtr<OpaqueJSString> propertyNameRef;
- if (StringImpl* name = propertyName.publicName()) {
+ if (StringImpl* name = propertyName.uid()) {
for (JSClassRef jsClass = classRef(); jsClass; jsClass = jsClass->parentClass) {
if (OpaqueJSClassStaticValuesTable* staticValues = jsClass->staticValues(exec)) {
if (StaticValueEntry* entry = staticValues->get(name)) {
if (JSObjectGetPropertyCallback getProperty = entry->getProperty) {
- if (!propertyNameRef)
- propertyNameRef = OpaqueJSString::create(name);
JSValueRef exception = 0;
JSValueRef value;
{
- APICallbackShim callbackShim(exec);
- value = getProperty(toRef(exec), thisRef, propertyNameRef.get(), &exception);
+ JSLock::DropAllLocks dropAllLocks(exec);
+ value = getProperty(toRef(exec), thisRef, entry->propertyNameRef.get(), &exception);
}
if (exception) {
- throwError(exec, toJS(exec, exception));
+ exec->vm().throwException(exec, toJS(exec, exception));
return jsUndefined();
}
if (value)
@@ -611,42 +600,42 @@ JSValue JSCallbackObject<Parent>::getStaticValue(ExecState* exec, PropertyName p
}
template <class Parent>
-JSValue JSCallbackObject<Parent>::staticFunctionGetter(ExecState* exec, JSValue slotParent, PropertyName propertyName)
+EncodedJSValue JSCallbackObject<Parent>::staticFunctionGetter(ExecState* exec, EncodedJSValue thisValue, PropertyName propertyName)
{
- JSCallbackObject* thisObj = asCallbackObject(slotParent);
+ JSCallbackObject* thisObj = asCallbackObject(thisValue);
// Check for cached or override property.
- PropertySlot slot2(thisObj);
+ PropertySlot slot2(thisObj, PropertySlot::InternalMethodType::VMInquiry);
if (Parent::getOwnPropertySlot(thisObj, exec, propertyName, slot2))
- return slot2.getValue(exec, propertyName);
-
- if (StringImpl* name = propertyName.publicName()) {
+ return JSValue::encode(slot2.getValue(exec, propertyName));
+
+ if (StringImpl* name = propertyName.uid()) {
for (JSClassRef jsClass = thisObj->classRef(); jsClass; jsClass = jsClass->parentClass) {
if (OpaqueJSClassStaticFunctionsTable* staticFunctions = jsClass->staticFunctions(exec)) {
if (StaticFunctionEntry* entry = staticFunctions->get(name)) {
if (JSObjectCallAsFunctionCallback callAsFunction = entry->callAsFunction) {
-
- JSObject* o = JSCallbackFunction::create(exec, thisObj->globalObject(), callAsFunction, name);
- thisObj->putDirect(exec->vm(), propertyName, o, entry->attributes);
- return o;
+ VM& vm = exec->vm();
+ JSObject* o = JSCallbackFunction::create(vm, thisObj->globalObject(), callAsFunction, name);
+ thisObj->putDirect(vm, propertyName, o, entry->attributes);
+ return JSValue::encode(o);
}
}
}
}
}
- return throwError(exec, createReferenceError(exec, ASCIILiteral("Static function property defined with NULL callAsFunction callback.")));
+ return JSValue::encode(exec->vm().throwException(exec, createReferenceError(exec, ASCIILiteral("Static function property defined with NULL callAsFunction callback."))));
}
template <class Parent>
-JSValue JSCallbackObject<Parent>::callbackGetter(ExecState* exec, JSValue slotParent, PropertyName propertyName)
+EncodedJSValue JSCallbackObject<Parent>::callbackGetter(ExecState* exec, EncodedJSValue thisValue, PropertyName propertyName)
{
- JSCallbackObject* thisObj = asCallbackObject(slotParent);
+ JSCallbackObject* thisObj = asCallbackObject(thisValue);
JSObjectRef thisRef = toRef(thisObj);
RefPtr<OpaqueJSString> propertyNameRef;
- if (StringImpl* name = propertyName.publicName()) {
+ if (StringImpl* name = propertyName.uid()) {
for (JSClassRef jsClass = thisObj->classRef(); jsClass; jsClass = jsClass->parentClass) {
if (JSObjectGetPropertyCallback getProperty = jsClass->getProperty) {
if (!propertyNameRef)
@@ -654,20 +643,20 @@ JSValue JSCallbackObject<Parent>::callbackGetter(ExecState* exec, JSValue slotPa
JSValueRef exception = 0;
JSValueRef value;
{
- APICallbackShim callbackShim(exec);
+ JSLock::DropAllLocks dropAllLocks(exec);
value = getProperty(toRef(exec), thisRef, propertyNameRef.get(), &exception);
}
if (exception) {
- throwError(exec, toJS(exec, exception));
- return jsUndefined();
+ exec->vm().throwException(exec, toJS(exec, exception));
+ return JSValue::encode(jsUndefined());
}
if (value)
- return toJS(exec, value);
+ return JSValue::encode(toJS(exec, value));
}
}
}
- return throwError(exec, createReferenceError(exec, ASCIILiteral("hasProperty callback returned true for a property that doesn't exist.")));
+ return JSValue::encode(exec->vm().throwException(exec, createReferenceError(exec, ASCIILiteral("hasProperty callback returned true for a property that doesn't exist."))));
}
} // namespace JSC
diff --git a/Source/JavaScriptCore/API/JSClassRef.cpp b/Source/JavaScriptCore/API/JSClassRef.cpp
index c77f63cf9..e0dbe6043 100644
--- a/Source/JavaScriptCore/API/JSClassRef.cpp
+++ b/Source/JavaScriptCore/API/JSClassRef.cpp
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
@@ -33,7 +33,7 @@
#include "JSGlobalObject.h"
#include "JSObjectRef.h"
#include "ObjectPrototype.h"
-#include "Operations.h"
+#include "JSCInlines.h"
#include <wtf/text/StringHash.h>
#include <wtf/unicode/UTF8.h>
@@ -62,21 +62,21 @@ OpaqueJSClass::OpaqueJSClass(const JSClassDefinition* definition, OpaqueJSClass*
initializeThreading();
if (const JSStaticValue* staticValue = definition->staticValues) {
- m_staticValues = adoptPtr(new OpaqueJSClassStaticValuesTable);
+ m_staticValues = std::make_unique<OpaqueJSClassStaticValuesTable>();
while (staticValue->name) {
String valueName = String::fromUTF8(staticValue->name);
if (!valueName.isNull())
- m_staticValues->set(valueName.impl(), adoptPtr(new StaticValueEntry(staticValue->getProperty, staticValue->setProperty, staticValue->attributes)));
+ m_staticValues->set(valueName.impl(), std::make_unique<StaticValueEntry>(staticValue->getProperty, staticValue->setProperty, staticValue->attributes, valueName));
++staticValue;
}
}
if (const JSStaticFunction* staticFunction = definition->staticFunctions) {
- m_staticFunctions = adoptPtr(new OpaqueJSClassStaticFunctionsTable);
+ m_staticFunctions = std::make_unique<OpaqueJSClassStaticFunctionsTable>();
while (staticFunction->name) {
String functionName = String::fromUTF8(staticFunction->name);
if (!functionName.isNull())
- m_staticFunctions->set(functionName.impl(), adoptPtr(new StaticFunctionEntry(staticFunction->callAsFunction, staticFunction->attributes)));
+ m_staticFunctions->set(functionName.impl(), std::make_unique<StaticFunctionEntry>(staticFunction->callAsFunction, staticFunction->attributes));
++staticFunction;
}
}
@@ -88,19 +88,19 @@ OpaqueJSClass::OpaqueJSClass(const JSClassDefinition* definition, OpaqueJSClass*
OpaqueJSClass::~OpaqueJSClass()
{
// 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.length() || !m_className.impl()->isIdentifier());
+ ASSERT(!m_className.length() || !m_className.impl()->isAtomic());
#ifndef NDEBUG
if (m_staticValues) {
OpaqueJSClassStaticValuesTable::const_iterator end = m_staticValues->end();
for (OpaqueJSClassStaticValuesTable::const_iterator it = m_staticValues->begin(); it != end; ++it)
- ASSERT(!it->key->isIdentifier());
+ ASSERT(!it->key->isAtomic());
}
if (m_staticFunctions) {
OpaqueJSClassStaticFunctionsTable::const_iterator end = m_staticFunctions->end();
for (OpaqueJSClassStaticFunctionsTable::const_iterator it = m_staticFunctions->begin(); it != end; ++it)
- ASSERT(!it->key->isIdentifier());
+ ASSERT(!it->key->isAtomic());
}
#endif
@@ -108,12 +108,12 @@ OpaqueJSClass::~OpaqueJSClass()
JSClassRelease(prototypeClass);
}
-PassRefPtr<OpaqueJSClass> OpaqueJSClass::createNoAutomaticPrototype(const JSClassDefinition* definition)
+Ref<OpaqueJSClass> OpaqueJSClass::createNoAutomaticPrototype(const JSClassDefinition* definition)
{
- return adoptRef(new OpaqueJSClass(definition, 0));
+ return adoptRef(*new OpaqueJSClass(definition, 0));
}
-PassRefPtr<OpaqueJSClass> OpaqueJSClass::create(const JSClassDefinition* clientDefinition)
+Ref<OpaqueJSClass> OpaqueJSClass::create(const JSClassDefinition* clientDefinition)
{
JSClassDefinition definition = *clientDefinition; // Avoid modifying client copy.
@@ -124,42 +124,43 @@ PassRefPtr<OpaqueJSClass> OpaqueJSClass::create(const JSClassDefinition* clientD
// We are supposed to use JSClassRetain/Release but since we know that we currently have
// the only reference to this class object we cheat and use a RefPtr instead.
RefPtr<OpaqueJSClass> protoClass = adoptRef(new OpaqueJSClass(&protoDefinition, 0));
- return adoptRef(new OpaqueJSClass(&definition, protoClass.get()));
+ return adoptRef(*new OpaqueJSClass(&definition, protoClass.get()));
}
OpaqueJSClassContextData::OpaqueJSClassContextData(JSC::VM&, OpaqueJSClass* jsClass)
: m_class(jsClass)
{
if (jsClass->m_staticValues) {
- staticValues = adoptPtr(new OpaqueJSClassStaticValuesTable);
+ staticValues = std::make_unique<OpaqueJSClassStaticValuesTable>();
OpaqueJSClassStaticValuesTable::const_iterator end = jsClass->m_staticValues->end();
for (OpaqueJSClassStaticValuesTable::const_iterator it = jsClass->m_staticValues->begin(); it != end; ++it) {
- ASSERT(!it->key->isIdentifier());
- staticValues->add(it->key->isolatedCopy(), adoptPtr(new StaticValueEntry(it->value->getProperty, it->value->setProperty, it->value->attributes)));
+ ASSERT(!it->key->isAtomic());
+ String valueName = it->key->isolatedCopy();
+ staticValues->add(valueName.impl(), std::make_unique<StaticValueEntry>(it->value->getProperty, it->value->setProperty, it->value->attributes, valueName));
}
}
if (jsClass->m_staticFunctions) {
- staticFunctions = adoptPtr(new OpaqueJSClassStaticFunctionsTable);
+ staticFunctions = std::make_unique<OpaqueJSClassStaticFunctionsTable>();
OpaqueJSClassStaticFunctionsTable::const_iterator end = jsClass->m_staticFunctions->end();
for (OpaqueJSClassStaticFunctionsTable::const_iterator it = jsClass->m_staticFunctions->begin(); it != end; ++it) {
- ASSERT(!it->key->isIdentifier());
- staticFunctions->add(it->key->isolatedCopy(), adoptPtr(new StaticFunctionEntry(it->value->callAsFunction, it->value->attributes)));
+ ASSERT(!it->key->isAtomic());
+ staticFunctions->add(it->key->isolatedCopy(), std::make_unique<StaticFunctionEntry>(it->value->callAsFunction, it->value->attributes));
}
}
}
OpaqueJSClassContextData& OpaqueJSClass::contextData(ExecState* exec)
{
- OwnPtr<OpaqueJSClassContextData>& contextData = exec->lexicalGlobalObject()->opaqueJSClassData().add(this, nullptr).iterator->value;
+ std::unique_ptr<OpaqueJSClassContextData>& contextData = exec->lexicalGlobalObject()->opaqueJSClassData().add(this, nullptr).iterator->value;
if (!contextData)
- contextData = adoptPtr(new OpaqueJSClassContextData(exec->vm(), this));
+ contextData = std::make_unique<OpaqueJSClassContextData>(exec->vm(), this);
return *contextData;
}
String OpaqueJSClass::className()
{
- // Make a deep copy, so that the caller has no chance to put the original into IdentifierTable.
+ // Make a deep copy, so that the caller has no chance to put the original into AtomicStringTable.
return m_className.isolatedCopy();
}
@@ -206,6 +207,6 @@ JSObject* OpaqueJSClass::prototype(ExecState* exec)
prototype->setPrototype(exec->vm(), parentPrototype);
}
- jsClassData.cachedPrototype = PassWeak<JSObject>(prototype);
+ jsClassData.cachedPrototype = Weak<JSObject>(prototype);
return prototype;
}
diff --git a/Source/JavaScriptCore/API/JSClassRef.h b/Source/JavaScriptCore/API/JSClassRef.h
index 7bf18e758..fa024d344 100644
--- a/Source/JavaScriptCore/API/JSClassRef.h
+++ b/Source/JavaScriptCore/API/JSClassRef.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
@@ -26,24 +26,25 @@
#ifndef JSClassRef_h
#define JSClassRef_h
-#include <JavaScriptCore/JSObjectRef.h>
-
-#include "Weak.h"
+#include "OpaqueJSString.h"
#include "Protect.h"
+#include "Weak.h"
+#include <JavaScriptCore/JSObjectRef.h>
#include <wtf/HashMap.h>
#include <wtf/text/WTFString.h>
struct StaticValueEntry {
WTF_MAKE_FAST_ALLOCATED;
public:
- StaticValueEntry(JSObjectGetPropertyCallback _getProperty, JSObjectSetPropertyCallback _setProperty, JSPropertyAttributes _attributes)
- : getProperty(_getProperty), setProperty(_setProperty), attributes(_attributes)
+ StaticValueEntry(JSObjectGetPropertyCallback _getProperty, JSObjectSetPropertyCallback _setProperty, JSPropertyAttributes _attributes, String& propertyName)
+ : getProperty(_getProperty), setProperty(_setProperty), attributes(_attributes), propertyNameRef(OpaqueJSString::create(propertyName))
{
}
JSObjectGetPropertyCallback getProperty;
JSObjectSetPropertyCallback setProperty;
JSPropertyAttributes attributes;
+ RefPtr<OpaqueJSString> propertyNameRef;
};
struct StaticFunctionEntry {
@@ -58,8 +59,8 @@ public:
JSPropertyAttributes attributes;
};
-typedef HashMap<RefPtr<StringImpl>, OwnPtr<StaticValueEntry> > OpaqueJSClassStaticValuesTable;
-typedef HashMap<RefPtr<StringImpl>, OwnPtr<StaticFunctionEntry> > OpaqueJSClassStaticFunctionsTable;
+typedef HashMap<RefPtr<StringImpl>, std::unique_ptr<StaticValueEntry>> OpaqueJSClassStaticValuesTable;
+typedef HashMap<RefPtr<StringImpl>, std::unique_ptr<StaticFunctionEntry>> OpaqueJSClassStaticFunctionsTable;
struct OpaqueJSClass;
@@ -78,14 +79,14 @@ public:
// 4. When it is used, the old context data is found in VM and used.
RefPtr<OpaqueJSClass> m_class;
- OwnPtr<OpaqueJSClassStaticValuesTable> staticValues;
- OwnPtr<OpaqueJSClassStaticFunctionsTable> staticFunctions;
+ std::unique_ptr<OpaqueJSClassStaticValuesTable> staticValues;
+ std::unique_ptr<OpaqueJSClassStaticFunctionsTable> staticFunctions;
JSC::Weak<JSC::JSObject> cachedPrototype;
};
struct OpaqueJSClass : public ThreadSafeRefCounted<OpaqueJSClass> {
- static PassRefPtr<OpaqueJSClass> create(const JSClassDefinition*);
- static PassRefPtr<OpaqueJSClass> createNoAutomaticPrototype(const JSClassDefinition*);
+ static Ref<OpaqueJSClass> create(const JSClassDefinition*);
+ static Ref<OpaqueJSClass> createNoAutomaticPrototype(const JSClassDefinition*);
JS_EXPORT_PRIVATE ~OpaqueJSClass();
String className();
@@ -117,10 +118,10 @@ private:
OpaqueJSClassContextData& contextData(JSC::ExecState*);
- // Strings in these data members should not be put into any IdentifierTable.
+ // Strings in these data members should not be put into any AtomicStringTable.
String m_className;
- OwnPtr<OpaqueJSClassStaticValuesTable> m_staticValues;
- OwnPtr<OpaqueJSClassStaticFunctionsTable> m_staticFunctions;
+ std::unique_ptr<OpaqueJSClassStaticValuesTable> m_staticValues;
+ std::unique_ptr<OpaqueJSClassStaticFunctionsTable> m_staticFunctions;
};
#endif // JSClassRef_h
diff --git a/Source/JavaScriptCore/API/JSContext.h b/Source/JavaScriptCore/API/JSContext.h
index ef3e51f17..ddb51adfe 100644
--- a/Source/JavaScriptCore/API/JSContext.h
+++ b/Source/JavaScriptCore/API/JSContext.h
@@ -20,108 +20,220 @@
* 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.
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef JSContext_h
#define JSContext_h
#include <JavaScriptCore/JavaScript.h>
+#include <JavaScriptCore/WebKitAvailability.h>
#if JSC_OBJC_API_ENABLED
@class JSVirtualMachine, JSValue;
-// An instance of JSContext represents a JavaScript execution environment. All
-// JavaScript execution takes place within a context.
-// JSContext is also used to manage the life-cycle of objects within the
-// JavaScript virtual machine. Every instance of JSValue is associated with a
-// JSContext via a strong reference. The JSValue will keep the JSContext it
-// references alive so long as the JSValue remains alive. When all of the JSValues
-// that reference a particular JSContext have been deallocated the JSContext
-// will be deallocated unless it has been previously retained.
-
-NS_CLASS_AVAILABLE(10_9, NA)
+/*!
+@interface
+@discussion A JSContext is a JavaScript execution environment. All
+ JavaScript execution takes place within a context, and all JavaScript values
+ are tied to a context.
+*/
+NS_CLASS_AVAILABLE(10_9, 7_0)
@interface JSContext : NSObject
-// Create a JSContext.
-- (id)init;
-// Create a JSContext in the specified virtual machine.
-- (id)initWithVirtualMachine:(JSVirtualMachine *)virtualMachine;
-
-// Evaluate a string of JavaScript code.
+/*!
+@methodgroup Creating New JSContexts
+*/
+/*!
+@method
+@abstract Create a JSContext.
+@result The new context.
+*/
+- (instancetype)init;
+
+/*!
+@method
+@abstract Create a JSContext in the specified virtual machine.
+@param virtualMachine The JSVirtualMachine in which the context will be created.
+@result The new context.
+*/
+- (instancetype)initWithVirtualMachine:(JSVirtualMachine *)virtualMachine;
+
+/*!
+@methodgroup Evaluating Scripts
+*/
+/*!
+@method
+@abstract Evaluate a string of JavaScript code.
+@param script A string containing the JavaScript code to evaluate.
+@result The last value generated by the script.
+*/
- (JSValue *)evaluateScript:(NSString *)script;
-// This method retrieves the global object of the JavaScript execution context.
-// Instances of JSContext originating from WebKit will return a reference to the
-// WindowProxy object.
-- (JSValue *)globalObject;
-
-// This method may be called from within an Objective-C block or method invoked
-// as a callback from JavaScript to retrieve the callback's context. Outside of
-// a callback from JavaScript this method will return nil.
+/*!
+@method
+@abstract Evaluate a string of JavaScript code, with a URL for the script's source file.
+@param script A string containing the JavaScript code to evaluate.
+@param sourceURL A URL for the script's source file. Used by debuggers and when reporting exceptions. This parameter is informative only: it does not change the behavior of the script.
+@result The last value generated by the script.
+*/
+- (JSValue *)evaluateScript:(NSString *)script withSourceURL:(NSURL *)sourceURL NS_AVAILABLE(10_10, 8_0);
+
+/*!
+@methodgroup Callback Accessors
+*/
+/*!
+@method
+@abstract Get the JSContext that is currently executing.
+@discussion This method may be called from within an Objective-C block or method invoked
+ as a callback from JavaScript to retrieve the callback's context. Outside of
+ a callback from JavaScript this method will return nil.
+@result The currently executing JSContext or nil if there isn't one.
+*/
+ (JSContext *)currentContext;
-// This method may be called from within an Objective-C block or method invoked
-// as a callback from JavaScript to retrieve the callback's this value. Outside
-// of a callback from JavaScript this method will return nil.
+
+/*!
+@method
+@abstract Get the JavaScript function that is currently executing.
+@discussion This method may be called from within an Objective-C block or method invoked
+ as a callback from JavaScript to retrieve the callback's context. Outside of
+ a callback from JavaScript this method will return nil.
+@result The currently executing JavaScript function or nil if there isn't one.
+*/
++ (JSValue *)currentCallee NS_AVAILABLE(10_10, 8_0);
+
+/*!
+@method
+@abstract Get the <code>this</code> value of the currently executing method.
+@discussion This method may be called from within an Objective-C block or method invoked
+ as a callback from JavaScript to retrieve the callback's this value. Outside
+ of a callback from JavaScript this method will return nil.
+@result The current <code>this</code> value or nil if there isn't one.
+*/
+ (JSValue *)currentThis;
-// This method may be called from within an Objective-C block or method invoked
-// as a callback from JavaScript to retrieve the callback's arguments, objects
-// in the returned array are instances of JSValue. Outside of a callback from
-// JavaScript this method will return nil.
+
+/*!
+@method
+@abstract Get the arguments to the current callback.
+@discussion This method may be called from within an Objective-C block or method invoked
+ as a callback from JavaScript to retrieve the callback's arguments, objects
+ in the returned array are instances of JSValue. Outside of a callback from
+ JavaScript this method will return nil.
+@result An NSArray of the arguments nil if there is no current callback.
+*/
+ (NSArray *)currentArguments;
-// The "exception" property may be used to throw an exception to JavaScript.
-// Before a callback is made from JavaScript to an Objective-C block or method,
-// the prior value of the exception property will be preserved and the property
-// will be set to nil. After the callback has completed the new value of the
-// exception property will be read, and prior value restored. If the new value
-// of exception is not nil, the callback will result in that value being thrown.
-// This property may also be used to check for uncaught exceptions arising from
-// API function calls (since the default behaviour of "exceptionHandler" is to
-// assign an uncaught exception to this property).
-// If a JSValue originating from a different JSVirtualMachine than this context
-// is assigned to this property, an Objective-C exception will be raised.
-@property(retain) JSValue *exception;
-
-// If a call to an API function results in an uncaught JavaScript exception, the
-// "exceptionHandler" block will be invoked. The default implementation for the
-// exception handler will store the exception to the exception property on
-// context. As a consequence the default behaviour is for unhandled exceptions
-// occurring within a callback from JavaScript to be rethrown upon return.
-// Setting this value to nil will result in all uncaught exceptions thrown from
-// the API being silently consumed.
-@property(copy) void(^exceptionHandler)(JSContext *context, JSValue *exception);
-
-// All instances of JSContext are associated with a single JSVirtualMachine. The
-// virtual machine provides an "object space" or set of execution resources.
-@property(readonly, retain) JSVirtualMachine *virtualMachine;
+/*!
+@methodgroup Global Properties
+*/
+/*!
+@property
+@abstract Get the global object of the context.
+@discussion This method retrieves the global object of the JavaScript execution context.
+ Instances of JSContext originating from WebKit will return a reference to the
+ WindowProxy object.
+@result The global object.
+*/
+@property (readonly, strong) JSValue *globalObject;
+
+/*!
+@property
+@discussion The <code>exception</code> property may be used to throw an exception to JavaScript.
+
+ Before a callback is made from JavaScript to an Objective-C block or method,
+ the prior value of the exception property will be preserved and the property
+ will be set to nil. After the callback has completed the new value of the
+ exception property will be read, and prior value restored. If the new value
+ of exception is not nil, the callback will result in that value being thrown.
+
+ This property may also be used to check for uncaught exceptions arising from
+ API function calls (since the default behaviour of <code>exceptionHandler</code> is to
+ assign an uncaught exception to this property).
+*/
+@property (strong) JSValue *exception;
+
+/*!
+@property
+@discussion If a call to an API function results in an uncaught JavaScript exception, the
+ <code>exceptionHandler</code> block will be invoked. The default implementation for the
+ exception handler will store the exception to the exception property on
+ context. As a consequence the default behaviour is for uncaught exceptions
+ occurring within a callback from JavaScript to be rethrown upon return.
+ Setting this value to nil will cause all exceptions occurring
+ within a callback from JavaScript to be silently caught.
+*/
+@property (copy) void(^exceptionHandler)(JSContext *context, JSValue *exception);
+
+/*!
+@property
+@discussion All instances of JSContext are associated with a JSVirtualMachine.
+*/
+@property (readonly, strong) JSVirtualMachine *virtualMachine;
+
+/*!
+@property
+@discussion Name of the JSContext. Exposed when remote debugging the context.
+*/
+@property (copy) NSString *name NS_AVAILABLE(10_10, 8_0);
@end
-// Instances of JSContext implement the following methods in order to enable
-// support for subscript access by key and index, for example:
-//
-// JSContext *context;
-// JSValue *v = context[@"X"]; // Get value for "X" from the global object.
-// context[@"Y"] = v; // Assign 'v' to "Y" on the global object.
-//
-// An object key passed as a subscript will be converted to a JavaScript value,
-// and then the value converted to a string used to resolve a property of the
-// global object.
-@interface JSContext(SubscriptSupport)
-
+/*!
+@category
+@discussion Instances of JSContext implement the following methods in order to enable
+ support for subscript access by key and index, for example:
+
+@textblock
+ JSContext *context;
+ JSValue *v = context[@"X"]; // Get value for "X" from the global object.
+ context[@"Y"] = v; // Assign 'v' to "Y" on the global object.
+@/textblock
+
+ An object key passed as a subscript will be converted to a JavaScript value,
+ and then the value converted to a string used to resolve a property of the
+ global object.
+*/
+@interface JSContext (SubscriptSupport)
+
+/*!
+method
+@abstract Get a particular property on the global object.
+@param key
+@result The JSValue for the global object's property.
+*/
- (JSValue *)objectForKeyedSubscript:(id)key;
+
+/*!
+method
+@abstract Set a particular property on the global object.
+@param object
+@param key
+*/
- (void)setObject:(id)object forKeyedSubscript:(NSObject <NSCopying> *)key;
@end
-// These functions are for bridging between the C API and the Objective-C API.
-@interface JSContext(JSContextRefSupport)
-// Creates a JSContext, wrapping its C API counterpart.
+/*!
+@category
+@discussion These functions are for bridging between the C API and the Objective-C API.
+*/
+@interface JSContext (JSContextRefSupport)
+
+/*!
+@method
+@abstract Create a JSContext, wrapping its C API counterpart.
+@param jsGlobalContextRef
+@result The JSContext equivalent of the provided JSGlobalContextRef.
+*/
+ (JSContext *)contextWithJSGlobalContextRef:(JSGlobalContextRef)jsGlobalContextRef;
-// Returns the C API counterpart wrapped by a JSContext.
-- (JSGlobalContextRef)JSGlobalContextRef;
+
+/*!
+@property
+@abstract Get the C API counterpart wrapped by a JSContext.
+@result The C API equivalent of this JSContext.
+*/
+@property (readonly) JSGlobalContextRef JSGlobalContextRef;
@end
#endif
diff --git a/Source/JavaScriptCore/API/JSContext.mm b/Source/JavaScriptCore/API/JSContext.mm
deleted file mode 100644
index 58754b38c..000000000
--- a/Source/JavaScriptCore/API/JSContext.mm
+++ /dev/null
@@ -1,289 +0,0 @@
-/*
- * Copyright (C) 2013 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. ``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
- * 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"
-
-#import "APICast.h"
-#import "APIShims.h"
-#import "JSContextInternal.h"
-#import "JSGlobalObject.h"
-#import "JSValueInternal.h"
-#import "JSVirtualMachineInternal.h"
-#import "JSWrapperMap.h"
-#import "JavaScriptCore.h"
-#import "ObjcRuntimeExtras.h"
-#import "Operations.h"
-#import "StrongInlines.h"
-#import <wtf/HashSet.h>
-
-#if JSC_OBJC_API_ENABLED
-
-@implementation JSContext {
- JSVirtualMachine *m_virtualMachine;
- JSGlobalContextRef m_context;
- JSWrapperMap *m_wrapperMap;
- JSC::Strong<JSC::JSObject> m_exception;
-}
-
-@synthesize exceptionHandler;
-
-- (JSGlobalContextRef)JSGlobalContextRef
-{
- return m_context;
-}
-
-- (id)init
-{
- return [self initWithVirtualMachine:[[[JSVirtualMachine alloc] init] autorelease]];
-}
-
-- (id)initWithVirtualMachine:(JSVirtualMachine *)virtualMachine
-{
- self = [super init];
- if (!self)
- return nil;
-
- m_virtualMachine = [virtualMachine retain];
- m_context = JSGlobalContextCreateInGroup(getGroupFromVirtualMachine(virtualMachine), 0);
- m_wrapperMap = [[JSWrapperMap alloc] initWithContext:self];
-
- self.exceptionHandler = ^(JSContext *context, JSValue *exceptionValue) {
- context.exception = exceptionValue;
- };
-
- [m_virtualMachine addContext:self forGlobalContextRef:m_context];
-
- return self;
-}
-
-- (void)dealloc
-{
- [m_wrapperMap release];
- JSGlobalContextRelease(m_context);
- [m_virtualMachine release];
- [self.exceptionHandler release];
- [super dealloc];
-}
-
-- (JSValue *)evaluateScript:(NSString *)script
-{
- JSValueRef exceptionValue = 0;
- JSStringRef scriptJS = JSStringCreateWithCFString((CFStringRef)script);
- JSValueRef result = JSEvaluateScript(m_context, scriptJS, 0, 0, 0, &exceptionValue);
- JSStringRelease(scriptJS);
-
- if (exceptionValue)
- return [self valueFromNotifyException:exceptionValue];
-
- return [JSValue valueWithJSValueRef:result inContext:self];
-}
-
-- (void)setException:(JSValue *)value
-{
- if (value)
- m_exception.set(toJS(m_context)->vm(), toJS(JSValueToObject(m_context, valueInternalValue(value), 0)));
- else
- m_exception.clear();
-}
-
-- (JSValue *)exception
-{
- if (!m_exception)
- return nil;
- return [JSValue valueWithJSValueRef:toRef(m_exception.get()) inContext:self];
-}
-
-- (JSWrapperMap *)wrapperMap
-{
- return m_wrapperMap;
-}
-
-- (JSValue *)globalObject
-{
- return [JSValue valueWithJSValueRef:JSContextGetGlobalObject(m_context) inContext:self];
-}
-
-+ (JSContext *)currentContext
-{
- WTFThreadData& threadData = wtfThreadData();
- CallbackData *entry = (CallbackData *)threadData.m_apiData;
- return entry ? entry->context : nil;
-}
-
-+ (JSValue *)currentThis
-{
- WTFThreadData& threadData = wtfThreadData();
- CallbackData *entry = (CallbackData *)threadData.m_apiData;
-
- if (!entry->currentThis)
- entry->currentThis = [[JSValue alloc] initWithValue:entry->thisValue inContext:[JSContext currentContext]];
-
- return entry->currentThis;
-}
-
-+ (NSArray *)currentArguments
-{
- WTFThreadData& threadData = wtfThreadData();
- CallbackData *entry = (CallbackData *)threadData.m_apiData;
-
- if (!entry->currentArguments) {
- JSContext *context = [JSContext currentContext];
- size_t count = entry->argumentCount;
- JSValue * argumentArray[count];
- for (size_t i =0; i < count; ++i)
- argumentArray[i] = [JSValue valueWithJSValueRef:entry->arguments[i] inContext:context];
- entry->currentArguments = [[NSArray alloc] initWithObjects:argumentArray count:count];
- }
-
- return entry->currentArguments;
-}
-
-- (JSVirtualMachine *)virtualMachine
-{
- return m_virtualMachine;
-}
-
-@end
-
-@implementation JSContext(SubscriptSupport)
-
-- (JSValue *)objectForKeyedSubscript:(id)key
-{
- return [self globalObject][key];
-}
-
-- (void)setObject:(id)object forKeyedSubscript:(NSObject <NSCopying> *)key
-{
- [self globalObject][key] = object;
-}
-
-@end
-
-@implementation JSContext(Internal)
-
-- (id)initWithGlobalContextRef:(JSGlobalContextRef)context
-{
- self = [super init];
- if (!self)
- return nil;
-
- JSC::JSGlobalObject* globalObject = toJS(context)->lexicalGlobalObject();
- m_virtualMachine = [[JSVirtualMachine virtualMachineWithContextGroupRef:toRef(&globalObject->vm())] retain];
- ASSERT(m_virtualMachine);
- m_context = JSGlobalContextRetain(context);
- m_wrapperMap = [[JSWrapperMap alloc] initWithContext:self];
-
- self.exceptionHandler = ^(JSContext *context, JSValue *exceptionValue) {
- context.exception = exceptionValue;
- };
-
- [m_virtualMachine addContext:self forGlobalContextRef:m_context];
-
- return self;
-}
-
-- (void)notifyException:(JSValueRef)exceptionValue
-{
- self.exceptionHandler(self, [JSValue valueWithJSValueRef:exceptionValue inContext:self]);
-}
-
-- (JSValue *)valueFromNotifyException:(JSValueRef)exceptionValue
-{
- [self notifyException:exceptionValue];
- return [JSValue valueWithUndefinedInContext:self];
-}
-
-- (BOOL)boolFromNotifyException:(JSValueRef)exceptionValue
-{
- [self notifyException:exceptionValue];
- return NO;
-}
-
-- (void)beginCallbackWithData:(CallbackData *)callbackData thisValue:(JSValueRef)thisValue argumentCount:(size_t)argumentCount arguments:(const JSValueRef *)arguments
-{
- WTFThreadData& threadData = wtfThreadData();
- [self retain];
- CallbackData *prevStack = (CallbackData *)threadData.m_apiData;
- *callbackData = (CallbackData){ prevStack, self, [self.exception retain], thisValue, nil, argumentCount, arguments, nil };
- threadData.m_apiData = callbackData;
- self.exception = nil;
-}
-
-- (void)endCallbackWithData:(CallbackData *)callbackData
-{
- WTFThreadData& threadData = wtfThreadData();
- self.exception = callbackData->preservedException;
- [callbackData->preservedException release];
- [callbackData->currentThis release];
- [callbackData->currentArguments release];
- threadData.m_apiData = callbackData->next;
- [self release];
-}
-
-- (JSValue *)wrapperForObjCObject:(id)object
-{
- // Lock access to m_wrapperMap
- JSC::JSLockHolder lock(toJS(m_context));
- return [m_wrapperMap jsWrapperForObject:object];
-}
-
-- (JSValue *)wrapperForJSObject:(JSValueRef)value
-{
- JSC::JSLockHolder lock(toJS(m_context));
- return [m_wrapperMap objcWrapperForJSValueRef:value];
-}
-
-+ (JSContext *)contextWithJSGlobalContextRef:(JSGlobalContextRef)globalContext
-{
- JSVirtualMachine *virtualMachine = [JSVirtualMachine virtualMachineWithContextGroupRef:toRef(&toJS(globalContext)->vm())];
- JSContext *context = [virtualMachine contextForGlobalContextRef:globalContext];
- if (!context)
- context = [[[JSContext alloc] initWithGlobalContextRef:globalContext] autorelease];
- return context;
-}
-
-@end
-
-WeakContextRef::WeakContextRef(JSContext *context)
-{
- objc_initWeak(&m_weakContext, context);
-}
-
-WeakContextRef::~WeakContextRef()
-{
- objc_destroyWeak(&m_weakContext);
-}
-
-JSContext * WeakContextRef::get()
-{
- return objc_loadWeak(&m_weakContext);
-}
-
-void WeakContextRef::set(JSContext *context)
-{
- objc_storeWeak(&m_weakContext, context);
-}
-
-#endif
diff --git a/Source/JavaScriptCore/API/JSContextInternal.h b/Source/JavaScriptCore/API/JSContextInternal.h
index d08e97d93..5308fbb92 100644
--- a/Source/JavaScriptCore/API/JSContextInternal.h
+++ b/Source/JavaScriptCore/API/JSContextInternal.h
@@ -36,8 +36,8 @@ struct CallbackData {
CallbackData *next;
JSContext *context;
JSValue *preservedException;
+ JSValueRef calleeValue;
JSValueRef thisValue;
- JSValue *currentThis;
size_t argumentCount;
const JSValueRef *arguments;
NSArray *currentArguments;
@@ -65,7 +65,7 @@ private:
- (JSValue *)valueFromNotifyException:(JSValueRef)exception;
- (BOOL)boolFromNotifyException:(JSValueRef)exception;
-- (void)beginCallbackWithData:(CallbackData *)callbackData thisValue:(JSValueRef)thisValue argumentCount:(size_t)argumentCount arguments:(const JSValueRef *)arguments;
+- (void)beginCallbackWithData:(CallbackData *)callbackData calleeValue:(JSValueRef)calleeValue thisValue:(JSValueRef)thisValue argumentCount:(size_t)argumentCount arguments:(const JSValueRef *)arguments;
- (void)endCallbackWithData:(CallbackData *)callbackData;
- (JSValue *)wrapperForObjCObject:(id)object;
diff --git a/Source/JavaScriptCore/API/JSContextPrivate.h b/Source/JavaScriptCore/API/JSContextPrivate.h
new file mode 100644
index 000000000..7d1d0cbdb
--- /dev/null
+++ b/Source/JavaScriptCore/API/JSContextPrivate.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2014 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. ``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
+ * 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 JSContextPrivate_h
+#define JSContextPrivate_h
+
+#if JSC_OBJC_API_ENABLED
+
+#import <JavaScriptCore/JSContext.h>
+
+@interface JSContext(Private)
+
+/*!
+@property
+@discussion Remote inspection setting of the JSContext. Default value is YES.
+*/
+@property (setter=_setRemoteInspectionEnabled:) BOOL _remoteInspectionEnabled NS_AVAILABLE(10_10, 8_0);
+
+/*!
+@property
+@discussion Set whether or not the native call stack is included when reporting exceptions. Default value is YES.
+*/
+@property (setter=_setIncludesNativeCallStackWhenReportingExceptions:) BOOL _includesNativeCallStackWhenReportingExceptions NS_AVAILABLE(10_10, 8_0);
+
+/*!
+@property
+@discussion Set the run loop the Web Inspector debugger should use when evaluating JavaScript in the JSContext.
+*/
+@property (setter=_setDebuggerRunLoop:) CFRunLoopRef _debuggerRunLoop NS_AVAILABLE(10_10, 8_0);
+
+@end
+
+#endif
+
+#endif // JSContextInternal_h
diff --git a/Source/JavaScriptCore/API/JSContextRef.cpp b/Source/JavaScriptCore/API/JSContextRef.cpp
index 3869e87bf..98cd8b030 100644
--- a/Source/JavaScriptCore/API/JSContextRef.cpp
+++ b/Source/JavaScriptCore/API/JSContextRef.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,36 +10,47 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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.
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "JSContextRef.h"
-#include "JSContextRefPrivate.h"
+#include "JSContextRefInternal.h"
#include "APICast.h"
+#include "CallFrame.h"
#include "InitializeThreading.h"
-#include <interpreter/CallFrame.h>
-#include <interpreter/Interpreter.h>
#include "JSCallbackObject.h"
#include "JSClassRef.h"
#include "JSGlobalObject.h"
#include "JSObject.h"
-#include "Operations.h"
+#include "JSCInlines.h"
#include "SourceProvider.h"
+#include "StackVisitor.h"
+#include "Watchdog.h"
#include <wtf/text/StringBuilder.h>
#include <wtf/text/StringHash.h>
+#if ENABLE(REMOTE_INSPECTOR)
+#include "JSGlobalObjectDebuggable.h"
+#include "JSGlobalObjectInspectorController.h"
+#include "JSRemoteInspector.h"
+#endif
+
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+#include "JSContextRefInspectorSupport.h"
+#endif
+
#if OS(DARWIN)
#include <mach-o/dyld.h>
@@ -56,7 +67,7 @@ using namespace JSC;
JSContextGroupRef JSContextGroupCreate()
{
initializeThreading();
- return toRef(VM::createContextGroup().leakRef());
+ return toRef(&VM::createContextGroup().leakRef());
}
JSContextGroupRef JSContextGroupRetain(JSContextGroupRef group)
@@ -67,16 +78,10 @@ JSContextGroupRef JSContextGroupRetain(JSContextGroupRef group)
void JSContextGroupRelease(JSContextGroupRef group)
{
- IdentifierTable* savedIdentifierTable;
VM& vm = *toJS(group);
- {
- JSLockHolder lock(vm);
- savedIdentifierTable = wtfThreadData().setCurrentIdentifierTable(vm.identifierTable);
- vm.deref();
- }
-
- wtfThreadData().setCurrentIdentifierTable(savedIdentifierTable);
+ JSLockHolder locker(&vm);
+ vm.deref();
}
static bool internalScriptTimeoutCallback(ExecState* exec, void* callbackPtr, void* callbackData)
@@ -90,21 +95,21 @@ static bool internalScriptTimeoutCallback(ExecState* exec, void* callbackPtr, vo
void JSContextGroupSetExecutionTimeLimit(JSContextGroupRef group, double limit, JSShouldTerminateCallback callback, void* callbackData)
{
VM& vm = *toJS(group);
- APIEntryShim entryShim(&vm);
- Watchdog& watchdog = vm.watchdog;
+ JSLockHolder locker(&vm);
+ Watchdog& watchdog = vm.ensureWatchdog();
if (callback) {
void* callbackPtr = reinterpret_cast<void*>(callback);
- watchdog.setTimeLimit(vm, limit, internalScriptTimeoutCallback, callbackPtr, callbackData);
+ watchdog.setTimeLimit(std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::duration<double>(limit)), internalScriptTimeoutCallback, callbackPtr, callbackData);
} else
- watchdog.setTimeLimit(vm, limit);
+ watchdog.setTimeLimit(std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::duration<double>(limit)));
}
void JSContextGroupClearExecutionTimeLimit(JSContextGroupRef group)
{
VM& vm = *toJS(group);
- APIEntryShim entryShim(&vm);
- Watchdog& watchdog = vm.watchdog;
- watchdog.setTimeLimit(vm, std::numeric_limits<double>::infinity());
+ JSLockHolder locker(&vm);
+ if (vm.watchdog())
+ vm.watchdog()->setTimeLimit(Watchdog::noTimeLimit);
}
// From the API's perspective, a global context remains alive iff it has been JSGlobalContextRetained.
@@ -130,11 +135,14 @@ JSGlobalContextRef JSGlobalContextCreateInGroup(JSContextGroupRef group, JSClass
RefPtr<VM> vm = group ? PassRefPtr<VM>(toJS(group)) : VM::createContextGroup();
- APIEntryShim entryShim(vm.get(), false);
- vm->makeUsableFromMultipleThreads();
+ JSLockHolder locker(vm.get());
if (!globalObjectClass) {
JSGlobalObject* globalObject = JSGlobalObject::create(*vm, JSGlobalObject::createStructure(*vm, jsNull()));
+#if ENABLE(REMOTE_INSPECTOR)
+ if (JSRemoteInspectorGetInspectionEnabledByDefault())
+ globalObject->setRemoteDebuggingEnabled(true);
+#endif
return JSGlobalContextRetain(toGlobalRef(globalObject->globalExec()));
}
@@ -144,37 +152,34 @@ JSGlobalContextRef JSGlobalContextCreateInGroup(JSContextGroupRef group, JSClass
if (!prototype)
prototype = jsNull();
globalObject->resetPrototype(*vm, prototype);
+#if ENABLE(REMOTE_INSPECTOR)
+ if (JSRemoteInspectorGetInspectionEnabledByDefault())
+ globalObject->setRemoteDebuggingEnabled(true);
+#endif
return JSGlobalContextRetain(toGlobalRef(exec));
}
JSGlobalContextRef JSGlobalContextRetain(JSGlobalContextRef ctx)
{
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
+ JSLockHolder locker(exec);
VM& vm = exec->vm();
- gcProtect(exec->dynamicGlobalObject());
+ gcProtect(exec->vmEntryGlobalObject());
vm.ref();
return ctx;
}
void JSGlobalContextRelease(JSGlobalContextRef ctx)
{
- IdentifierTable* savedIdentifierTable;
ExecState* exec = toJS(ctx);
- {
- JSLockHolder lock(exec);
-
- VM& vm = exec->vm();
- savedIdentifierTable = wtfThreadData().setCurrentIdentifierTable(vm.identifierTable);
-
- bool protectCountIsZero = Heap::heap(exec->dynamicGlobalObject())->unprotect(exec->dynamicGlobalObject());
- if (protectCountIsZero)
- vm.heap.reportAbandonedObjectGraph();
- vm.deref();
- }
+ JSLockHolder locker(exec);
- wtfThreadData().setCurrentIdentifierTable(savedIdentifierTable);
+ VM& vm = exec->vm();
+ bool protectCountIsZero = Heap::heap(exec->vmEntryGlobalObject())->unprotect(exec->vmEntryGlobalObject());
+ if (protectCountIsZero)
+ vm.heap.reportAbandonedObjectGraph();
+ vm.deref();
}
JSObjectRef JSContextGetGlobalObject(JSContextRef ctx)
@@ -184,10 +189,9 @@ JSObjectRef JSContextGetGlobalObject(JSContextRef ctx)
return 0;
}
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
+ JSLockHolder locker(exec);
- // It is necessary to call toThisObject to get the wrapper object when used with WebCore.
- return toRef(exec->lexicalGlobalObject()->methodTable()->toThisObject(exec->lexicalGlobalObject(), exec));
+ return toRef(jsCast<JSObject*>(exec->lexicalGlobalObject()->methodTable()->toThis(exec->lexicalGlobalObject(), exec, NotStrictMode)));
}
JSContextGroupRef JSContextGetGroup(JSContextRef ctx)
@@ -207,11 +211,90 @@ JSGlobalContextRef JSContextGetGlobalContext(JSContextRef ctx)
return 0;
}
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
+ JSLockHolder locker(exec);
return toGlobalRef(exec->lexicalGlobalObject()->globalExec());
}
-
+
+JSStringRef JSGlobalContextCopyName(JSGlobalContextRef ctx)
+{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
+
+ ExecState* exec = toJS(ctx);
+ JSLockHolder locker(exec);
+
+ String name = exec->vmEntryGlobalObject()->name();
+ if (name.isNull())
+ return 0;
+
+ return OpaqueJSString::create(name).leakRef();
+}
+
+void JSGlobalContextSetName(JSGlobalContextRef ctx, JSStringRef name)
+{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return;
+ }
+
+ ExecState* exec = toJS(ctx);
+ JSLockHolder locker(exec);
+
+ exec->vmEntryGlobalObject()->setName(name ? name->string() : String());
+}
+
+
+class BacktraceFunctor {
+public:
+ BacktraceFunctor(StringBuilder& builder, unsigned remainingCapacityForFrameCapture)
+ : m_builder(builder)
+ , m_remainingCapacityForFrameCapture(remainingCapacityForFrameCapture)
+ {
+ }
+
+ StackVisitor::Status operator()(StackVisitor& visitor)
+ {
+ if (m_remainingCapacityForFrameCapture) {
+ // If callee is unknown, but we've not added any frame yet, we should
+ // still add the frame, because something called us, and gave us arguments.
+ JSObject* callee = visitor->callee();
+ if (!callee && visitor->index())
+ return StackVisitor::Done;
+
+ StringBuilder& builder = m_builder;
+ if (!builder.isEmpty())
+ builder.append('\n');
+ builder.append('#');
+ builder.appendNumber(visitor->index());
+ builder.append(' ');
+ builder.append(visitor->functionName());
+ builder.appendLiteral("() at ");
+ builder.append(visitor->sourceURL());
+ if (visitor->isJSFrame()) {
+ builder.append(':');
+ unsigned lineNumber;
+ unsigned unusedColumn;
+ visitor->computeLineAndColumn(lineNumber, unusedColumn);
+ builder.appendNumber(lineNumber);
+ }
+
+ if (!callee)
+ return StackVisitor::Done;
+
+ m_remainingCapacityForFrameCapture--;
+ return StackVisitor::Continue;
+ }
+ return StackVisitor::Done;
+ }
+
+private:
+ StringBuilder& m_builder;
+ unsigned m_remainingCapacityForFrameCapture;
+};
+
JSStringRef JSContextCreateBacktrace(JSContextRef ctx, unsigned maxStackSize)
{
if (!ctx) {
@@ -221,41 +304,128 @@ JSStringRef JSContextCreateBacktrace(JSContextRef ctx, unsigned maxStackSize)
ExecState* exec = toJS(ctx);
JSLockHolder lock(exec);
StringBuilder builder;
- Vector<StackFrame> stackTrace;
- Interpreter::getStackTrace(&exec->vm(), stackTrace, maxStackSize);
-
- for (size_t i = 0; i < stackTrace.size(); i++) {
- String urlString;
- String functionName;
- StackFrame& frame = stackTrace[i];
- JSValue function = frame.callee.get();
- if (frame.callee)
- functionName = frame.friendlyFunctionName(exec);
- else {
- // Caller is unknown, but if frame is empty we should still add the frame, because
- // something called us, and gave us arguments.
- if (i)
- break;
- }
- unsigned lineNumber;
- unsigned column;
- frame.computeLineAndColumn(lineNumber, column);
- if (!builder.isEmpty())
- builder.append('\n');
- builder.append('#');
- builder.appendNumber(i);
- builder.append(' ');
- builder.append(functionName);
- builder.appendLiteral("() at ");
- builder.append(urlString);
- if (frame.codeType != StackFrameNativeCode) {
- builder.append(':');
- builder.appendNumber(lineNumber);
- }
- if (!function)
- break;
- }
+ CallFrame* frame = exec->vm().topCallFrame;
+
+ ASSERT(maxStackSize);
+ BacktraceFunctor functor(builder, maxStackSize);
+ frame->iterate(functor);
+
return OpaqueJSString::create(builder.toString()).leakRef();
}
+bool JSGlobalContextGetRemoteInspectionEnabled(JSGlobalContextRef ctx)
+{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return false;
+ }
+ ExecState* exec = toJS(ctx);
+ JSLockHolder lock(exec);
+
+ return exec->vmEntryGlobalObject()->remoteDebuggingEnabled();
+}
+
+void JSGlobalContextSetRemoteInspectionEnabled(JSGlobalContextRef ctx, bool enabled)
+{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return;
+ }
+
+ ExecState* exec = toJS(ctx);
+ JSLockHolder lock(exec);
+
+ exec->vmEntryGlobalObject()->setRemoteDebuggingEnabled(enabled);
+}
+
+bool JSGlobalContextGetIncludesNativeCallStackWhenReportingExceptions(JSGlobalContextRef ctx)
+{
+#if ENABLE(REMOTE_INSPECTOR)
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return false;
+ }
+
+ ExecState* exec = toJS(ctx);
+ JSLockHolder lock(exec);
+
+ JSGlobalObject* globalObject = exec->vmEntryGlobalObject();
+ return globalObject->inspectorController().includesNativeCallStackWhenReportingExceptions();
+#else
+ UNUSED_PARAM(ctx);
+ return false;
+#endif
+}
+
+void JSGlobalContextSetIncludesNativeCallStackWhenReportingExceptions(JSGlobalContextRef ctx, bool includesNativeCallStack)
+{
+#if ENABLE(REMOTE_INSPECTOR)
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return;
+ }
+
+ ExecState* exec = toJS(ctx);
+ JSLockHolder lock(exec);
+
+ JSGlobalObject* globalObject = exec->vmEntryGlobalObject();
+ globalObject->inspectorController().setIncludesNativeCallStackWhenReportingExceptions(includesNativeCallStack);
+#else
+ UNUSED_PARAM(ctx);
+ UNUSED_PARAM(includesNativeCallStack);
+#endif
+}
+
+#if USE(CF)
+CFRunLoopRef JSGlobalContextGetDebuggerRunLoop(JSGlobalContextRef ctx)
+{
+#if ENABLE(REMOTE_INSPECTOR)
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return nullptr;
+ }
+
+ ExecState* exec = toJS(ctx);
+ JSLockHolder lock(exec);
+
+ return exec->vmEntryGlobalObject()->inspectorDebuggable().targetRunLoop();
+#else
+ UNUSED_PARAM(ctx);
+ return nullptr;
+#endif
+}
+
+void JSGlobalContextSetDebuggerRunLoop(JSGlobalContextRef ctx, CFRunLoopRef runLoop)
+{
+#if ENABLE(REMOTE_INSPECTOR)
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return;
+ }
+
+ ExecState* exec = toJS(ctx);
+ JSLockHolder lock(exec);
+
+ exec->vmEntryGlobalObject()->inspectorDebuggable().setTargetRunLoop(runLoop);
+#else
+ UNUSED_PARAM(ctx);
+ UNUSED_PARAM(runLoop);
+#endif
+}
+#endif // USE(CF)
+
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+Inspector::AugmentableInspectorController* JSGlobalContextGetAugmentableInspectorController(JSGlobalContextRef ctx)
+{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return nullptr;
+ }
+
+ ExecState* exec = toJS(ctx);
+ JSLockHolder lock(exec);
+
+ return &exec->vmEntryGlobalObject()->inspectorController();
+}
+#endif
diff --git a/Source/JavaScriptCore/API/JSContextRef.h b/Source/JavaScriptCore/API/JSContextRef.h
index c5c8a71e6..0c800bced 100644
--- a/Source/JavaScriptCore/API/JSContextRef.h
+++ b/Source/JavaScriptCore/API/JSContextRef.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,17 +10,17 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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.
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef JSContextRef_h
@@ -48,7 +48,7 @@ extern "C" {
synchronization is required.
@result The created JSContextGroup.
*/
-JS_EXPORT JSContextGroupRef JSContextGroupCreate() AVAILABLE_IN_WEBKIT_VERSION_4_0;
+JS_EXPORT JSContextGroupRef JSContextGroupCreate(void) CF_AVAILABLE(10_6, 7_0);
/*!
@function
@@ -56,14 +56,14 @@ JS_EXPORT JSContextGroupRef JSContextGroupCreate() AVAILABLE_IN_WEBKIT_VERSION_4
@param group The JSContextGroup to retain.
@result A JSContextGroup that is the same as group.
*/
-JS_EXPORT JSContextGroupRef JSContextGroupRetain(JSContextGroupRef group) AVAILABLE_IN_WEBKIT_VERSION_4_0;
+JS_EXPORT JSContextGroupRef JSContextGroupRetain(JSContextGroupRef group) CF_AVAILABLE(10_6, 7_0);
/*!
@function
@abstract Releases a JavaScript context group.
@param group The JSContextGroup to release.
*/
-JS_EXPORT void JSContextGroupRelease(JSContextGroupRef group) AVAILABLE_IN_WEBKIT_VERSION_4_0;
+JS_EXPORT void JSContextGroupRelease(JSContextGroupRef group) CF_AVAILABLE(10_6, 7_0);
/*!
@function
@@ -78,7 +78,7 @@ JS_EXPORT void JSContextGroupRelease(JSContextGroupRef group) AVAILABLE_IN_WEBKI
NULL to use the default object class.
@result A JSGlobalContext with a global object of class globalObjectClass.
*/
-JS_EXPORT JSGlobalContextRef JSGlobalContextCreate(JSClassRef globalObjectClass) AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER;
+JS_EXPORT JSGlobalContextRef JSGlobalContextCreate(JSClassRef globalObjectClass) CF_AVAILABLE(10_5, 7_0);
/*!
@function
@@ -92,7 +92,7 @@ JS_EXPORT JSGlobalContextRef JSGlobalContextCreate(JSClassRef globalObjectClass)
@result A JSGlobalContext with a global object of class globalObjectClass and a context
group equal to group.
*/
-JS_EXPORT JSGlobalContextRef JSGlobalContextCreateInGroup(JSContextGroupRef group, JSClassRef globalObjectClass) AVAILABLE_IN_WEBKIT_VERSION_4_0;
+JS_EXPORT JSGlobalContextRef JSGlobalContextCreateInGroup(JSContextGroupRef group, JSClassRef globalObjectClass) CF_AVAILABLE(10_6, 7_0);
/*!
@function
@@ -123,7 +123,33 @@ JS_EXPORT JSObjectRef JSContextGetGlobalObject(JSContextRef ctx);
@param ctx The JSContext whose group you want to get.
@result ctx's group.
*/
-JS_EXPORT JSContextGroupRef JSContextGetGroup(JSContextRef ctx) AVAILABLE_IN_WEBKIT_VERSION_4_0;
+JS_EXPORT JSContextGroupRef JSContextGetGroup(JSContextRef ctx) CF_AVAILABLE(10_6, 7_0);
+
+/*!
+@function
+@abstract Gets the global context of a JavaScript execution context.
+@param ctx The JSContext whose global context you want to get.
+@result ctx's global context.
+*/
+JS_EXPORT JSGlobalContextRef JSContextGetGlobalContext(JSContextRef ctx) CF_AVAILABLE(10_7, 7_0);
+
+/*!
+@function
+@abstract Gets a copy of the name of a context.
+@param ctx The JSGlobalContext whose name you want to get.
+@result The name for ctx.
+@discussion A JSGlobalContext's name is exposed for remote debugging to make it
+easier to identify the context you would like to attach to.
+*/
+JS_EXPORT JSStringRef JSGlobalContextCopyName(JSGlobalContextRef ctx) CF_AVAILABLE(10_10, 8_0);
+
+/*!
+@function
+@abstract Sets the remote debugging name for a context.
+@param ctx The JSGlobalContext that you want to name.
+@param name The remote debugging name to set on ctx.
+*/
+JS_EXPORT void JSGlobalContextSetName(JSGlobalContextRef ctx, JSStringRef name) CF_AVAILABLE(10_10, 8_0);
#ifdef __cplusplus
}
diff --git a/Source/JavaScriptCore/API/JSContextRefInspectorSupport.h b/Source/JavaScriptCore/API/JSContextRefInspectorSupport.h
new file mode 100644
index 000000000..a09d828bd
--- /dev/null
+++ b/Source/JavaScriptCore/API/JSContextRefInspectorSupport.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2014 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. ``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
+ * 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 JSContextRefInspectorSupport_h
+#define JSContextRefInspectorSupport_h
+
+#ifndef __cplusplus
+#error Requires C++ Support.
+#endif
+
+#include <JavaScriptCore/JSContextRefPrivate.h>
+
+namespace Inspector {
+class AugmentableInspectorController;
+}
+
+extern "C" {
+JS_EXPORT Inspector::AugmentableInspectorController* JSGlobalContextGetAugmentableInspectorController(JSGlobalContextRef);
+}
+
+#endif // JSContextRefInspectorSupport_h
diff --git a/Source/JavaScriptCore/API/JSContextRefInternal.h b/Source/JavaScriptCore/API/JSContextRefInternal.h
new file mode 100644
index 000000000..85632b8c7
--- /dev/null
+++ b/Source/JavaScriptCore/API/JSContextRefInternal.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2014 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. ``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
+ * 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 JSContextRefInternal_h
+#define JSContextRefInternal_h
+
+#include "JSContextRefPrivate.h"
+
+#if USE(CF)
+#include <CoreFoundation/CFRunLoop.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if USE(CF)
+/*!
+@function
+@abstract Gets the run loop used by the Web Inspector debugger when evaluating JavaScript in this context.
+@param ctx The JSGlobalContext whose setting you want to get.
+*/
+JS_EXPORT CFRunLoopRef JSGlobalContextGetDebuggerRunLoop(JSGlobalContextRef ctx) CF_AVAILABLE(10_10, 8_0);
+
+/*!
+@function
+@abstract Sets the run loop used by the Web Inspector debugger when evaluating JavaScript in this context.
+@param ctx The JSGlobalContext that you want to change.
+@param runLoop The new value of the setting for the context.
+*/
+JS_EXPORT void JSGlobalContextSetDebuggerRunLoop(JSGlobalContextRef ctx, CFRunLoopRef) CF_AVAILABLE(10_10, 8_0);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // JSContextRefInternal_h
diff --git a/Source/JavaScriptCore/API/JSContextRefPrivate.h b/Source/JavaScriptCore/API/JSContextRefPrivate.h
index 8d7684ac0..5a5bebd42 100644
--- a/Source/JavaScriptCore/API/JSContextRefPrivate.h
+++ b/Source/JavaScriptCore/API/JSContextRefPrivate.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,17 +10,17 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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.
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef JSContextRefPrivate_h
@@ -40,20 +40,11 @@ extern "C" {
/*!
@function
-@abstract Gets the global context of a JavaScript execution context.
-@param ctx The JSContext whose global context you want to get.
-@result ctx's global context.
-*/
-JS_EXPORT JSGlobalContextRef JSContextGetGlobalContext(JSContextRef ctx);
-
-
-/*!
-@function
@abstract Gets a Backtrace for the existing context
@param ctx The JSContext whose backtrace you want to get
@result A string containing the backtrace
*/
-JS_EXPORT JSStringRef JSContextCreateBacktrace(JSContextRef ctx, unsigned maxStackSize) AVAILABLE_IN_WEBKIT_VERSION_4_0;
+JS_EXPORT JSStringRef JSContextCreateBacktrace(JSContextRef ctx, unsigned maxStackSize) CF_AVAILABLE(10_6, 7_0);
/*!
@@ -94,14 +85,48 @@ typedef bool
need to call JSContextGroupSetExecutionTimeLimit before you start executing
any scripts.
*/
-JS_EXPORT void JSContextGroupSetExecutionTimeLimit(JSContextGroupRef, double limit, JSShouldTerminateCallback, void* context) AVAILABLE_IN_WEBKIT_VERSION_4_0;
+JS_EXPORT void JSContextGroupSetExecutionTimeLimit(JSContextGroupRef, double limit, JSShouldTerminateCallback, void* context) CF_AVAILABLE(10_6, 7_0);
/*!
@function
@abstract Clears the script execution time limit.
@param group The JavaScript context group that the time limit is cleared on.
*/
-JS_EXPORT void JSContextGroupClearExecutionTimeLimit(JSContextGroupRef) AVAILABLE_IN_WEBKIT_VERSION_4_0;
+JS_EXPORT void JSContextGroupClearExecutionTimeLimit(JSContextGroupRef) CF_AVAILABLE(10_6, 7_0);
+
+/*!
+@function
+@abstract Gets a whether or not remote inspection is enabled on the context.
+@param ctx The JSGlobalContext whose setting you want to get.
+@result The value of the setting, true if remote inspection is enabled, otherwise false.
+@discussion Remote inspection is true by default.
+*/
+JS_EXPORT bool JSGlobalContextGetRemoteInspectionEnabled(JSGlobalContextRef ctx) CF_AVAILABLE(10_10, 8_0);
+
+/*!
+@function
+@abstract Sets the remote inspection setting for a context.
+@param ctx The JSGlobalContext that you want to change.
+@param enabled The new remote inspection enabled setting for the context.
+*/
+JS_EXPORT void JSGlobalContextSetRemoteInspectionEnabled(JSGlobalContextRef ctx, bool enabled) CF_AVAILABLE(10_10, 8_0);
+
+/*!
+@function
+@abstract Gets the include native call stack when reporting exceptions setting for a context.
+@param ctx The JSGlobalContext whose setting you want to get.
+@result The value of the setting, true if remote inspection is enabled, otherwise false.
+@discussion This setting is true by default.
+*/
+JS_EXPORT bool JSGlobalContextGetIncludesNativeCallStackWhenReportingExceptions(JSGlobalContextRef ctx) CF_AVAILABLE(10_10, 8_0);
+
+/*!
+@function
+@abstract Sets the include native call stack when reporting exceptions setting for a context.
+@param ctx The JSGlobalContext that you want to change.
+@param includeNativeCallStack The new value of the setting for the context.
+*/
+JS_EXPORT void JSGlobalContextSetIncludesNativeCallStackWhenReportingExceptions(JSGlobalContextRef ctx, bool includesNativeCallStack) CF_AVAILABLE(10_10, 8_0);
#ifdef __cplusplus
}
diff --git a/Source/JavaScriptCore/API/JSExport.h b/Source/JavaScriptCore/API/JSExport.h
index 96e9fec35..b8a484909 100644
--- a/Source/JavaScriptCore/API/JSExport.h
+++ b/Source/JavaScriptCore/API/JSExport.h
@@ -27,103 +27,119 @@
#if JSC_OBJC_API_ENABLED
-// When a JavaScript value is created from an instance of an Objective-C class
-// for which no copying conversion is specified a JavaScript wrapper object will
-// be created.
-//
-// In JavaScript inheritance is supported via a chain of prototype objects, and
-// for each Objective-C class (and per JSContext) an object appropriate for use
-// as a prototype will be provided. For the class NSObject the prototype object
-// will be the JavaScript context's Object Prototype. For all other Objective-C
-// classes a Prototype object will be created. The Prototype object for a given
-// Objective-C class will have its internal [Prototype] property set to point to
-// the Prototype object of the Objective-C class's superclass. As such the
-// prototype chain for a JavaScript wrapper object will reflect the wrapped
-// Objective-C type's inheritance hierarchy.
-//
-// In addition to the Prototype object a JavaScript Constructor object will also
-// be produced for each Objective-C class. The Constructor object has a property
-// named 'prototype' that references the Prototype object, and the Prototype
-// object has a property named 'constructor' that references the Constructor.
-// The Constructor object is not callable.
-//
-// By default no methods or properties of the Objective-C class will be exposed
-// to JavaScript, however methods and properties may explicitly be exported.
-// For each protocol that a class conforms to, if the protocol incorporates the
-// protocol JSExport, then the protocol will be interpreted as a list of methods
-// and properties to be exported to JavaScript.
-//
-// For each instance method being exported, a corresponding JavaScript function
-// will be assigned as a property of the Prototype object, for each Objective-C
-// property being exported a JavaScript accessor property will be created on the
-// Prototype, and for each class method exported a JavaScript function will be
-// created on the Constructor object. For example:
-//
-// @protocol MyClassJavaScriptMethods <JSExport>
-// - (void)foo;
-// @end
-//
-// @interface MyClass : NSObject <MyClassJavaScriptMethods>
-// - (void)foo;
-// - (void)bar;
-// @end
-//
-// Data properties that are created on the prototype or constructor objects have
-// the attributes: writable:true, enumerable:false, configurable:true. Accessor
-// properties have the attributes: enumerable:false and configurable:true.
-//
-// If an instance of MyClass is converted to a JavaScript value, the resulting
-// wrapper object will (via its prototype) export the method "foo" to JavaScript,
-// since the class conforms to the MyClassJavaScriptMethods protocol, and this
-// protocol incorporates JSExport. "bar" will not be exported.
-//
-// Properties, arguments, and return values of the following types are
-// supported:
-//
-// Primitive numbers: signed values of up to 32-bits are converted in a manner
-// consistent with valueWithInt32/toInt32, unsigned values of up to 32-bits
-// are converted in a manner consistent with valueWithUInt32/toUInt32, all
-// other numeric values are converted consistently with valueWithDouble/
-// toDouble.
-// BOOL: values are converted consistently with valueWithBool/toBool.
-// id: values are converted consistently with valueWithObject/toObject.
-// <Objective-C Class>: - where the type is a pointer to a specified Objective-C
-// class, conversion is consistent with valueWithObjectOfClass/toObject.
-// struct types: C struct types are supported, where JSValue provides support
-// for the given type. Support is built in for CGPoint, NSRange, CGRect, and
-// CGSize.
-// block types: In addition to support provided by valueWithObject/toObject for
-// block types, if a JavaScript Function is passed as an argument, where the
-// type required is a block with a void return value (and where the block's
-// arguments are all of supported types), then a special adaptor block
-// will be created, allowing the JavaScript function to be used in the place
-// of a block.
-//
-// For any interface that conforms to JSExport the normal copying conversion for
-// built in types will be inhibited - so, for example, if an instance that
-// derives from NSString but conforms to JSExport is passed to valueWithObject:
-// then a wrapper object for the Objective-C object will be returned rather than
-// a JavaScript string primitive.
+/*!
+@protocol
+@abstract JSExport provides a declarative way to export Objective-C objects and
+ classes -- including properties, instance methods, class methods, and
+ initializers -- to JavaScript.
+
+@discussion When an Objective-C object is exported to JavaScript, a JavaScript
+ wrapper object is created.
+
+ In JavaScript, inheritance works via a chain of prototype objects.
+ For each Objective-C class in each JSContext, an object appropriate for use
+ as a prototype will be provided. For the class NSObject the prototype
+ will be the Object prototype. For all other Objective-C
+ classes a prototype will be created. The prototype for a given
+ Objective-C class will have its internal [Prototype] property set to point to
+ the prototype created for the Objective-C class's superclass. As such the
+ prototype chain for a JavaScript wrapper object will reflect the wrapped
+ Objective-C type's inheritance hierarchy.
+
+ JavaScriptCore also produces a constructor for each Objective-C class. The
+ constructor has a property named 'prototype' that references the prototype,
+ and the prototype has a property named 'constructor' that references the
+ constructor.
+
+ By default JavaScriptCore does not export any methods or properties from an
+ Objective-C class to JavaScript; however methods and properties may be exported
+ explicitly using JSExport. For each protocol that a class conforms to, if the
+ protocol incorporates the protocol JSExport, JavaScriptCore exports the methods
+ and properties in that protocol to JavaScript
+
+ For each exported instance method JavaScriptCore will assign a corresponding
+ JavaScript function to the prototype. For each exported Objective-C property
+ JavaScriptCore will assign a corresponding JavaScript accessor to the prototype.
+ For each exported class method JavaScriptCore will assign a corresponding
+ JavaScript function to the constructor. For example:
+
+<pre>
+@textblock
+ @protocol MyClassJavaScriptMethods <JSExport>
+ - (void)foo;
+ @end
+
+ @interface MyClass : NSObject <MyClassJavaScriptMethods>
+ - (void)foo;
+ - (void)bar;
+ @end
+@/textblock
+</pre>
+
+ Data properties that are created on the prototype or constructor objects have
+ the attributes: <code>writable:true</code>, <code>enumerable:false</code>, <code>configurable:true</code>.
+ Accessor properties have the attributes: <code>enumerable:false</code> and <code>configurable:true</code>.
+
+ If an instance of <code>MyClass</code> is converted to a JavaScript value, the resulting
+ wrapper object will (via its prototype) export the method <code>foo</code> to JavaScript,
+ since the class conforms to the <code>MyClassJavaScriptMethods</code> protocol, and this
+ protocol incorporates <code>JSExport</code>. <code>bar</code> will not be exported.
+
+ JSExport supports properties, arguments, and return values of the following types:
+
+ Primitive numbers: signed values up to 32-bits convert using JSValue's
+ valueWithInt32/toInt32. Unsigned values up to 32-bits convert using JSValue's
+ valueWithUInt32/toUInt32. All other numeric values convert using JSValue's
+ valueWithDouble/toDouble.
+
+ BOOL: values convert using JSValue's valueWithBool/toBool.
+
+ id: values convert using JSValue's valueWithObject/toObject.
+
+ Objective-C instance pointers: Pointers convert using JSValue's
+ valueWithObjectOfClass/toObject.
+
+ C structs: C structs for CGPoint, NSRange, CGRect, and CGSize convert using
+ JSValue's appropriate methods. Other C structs are not supported.
+
+ Blocks: Blocks convert using JSValue's valueWithObject/toObject.
+
+ All objects that conform to JSExport convert to JavaScript wrapper objects,
+ even if they subclass classes that would otherwise behave differently. For
+ example, if a subclass of NSString conforms to JSExport, it converts to
+ JavaScript as a wrapper object rather than a JavaScript string.
+*/
@protocol JSExport
@end
-// When a selector that takes one or more arguments is converted to a JavaScript
-// property name, by default a property name will be generated by performing the
-// following conversion:
-// - All colons are removed from the selector
-// - Any lowercase letter that had followed a colon will be capitalized.
-// Under the default conversion a selector "doFoo:withBar:" will be exported as
-// "doFooWithBar". The default conversion may be overriden using the JSExportAs
-// macro, for example to export a method "doFoo:withBar:" as "doFoo":
-//
-// @protocol MyClassJavaScriptMethods <JSExport>
-// JSExportAs(doFoo,
-// - (void)doFoo:(id)foo withBar:(id)bar
-// );
-// @end
-//
-// Note that the JSExport macro may only be applied to a selector that takes one
-// or more argument.
+/*!
+@define
+@abstract Rename a selector when it's exported to JavaScript.
+@discussion When a selector that takes one or more arguments is converted to a JavaScript
+ property name, by default a property name will be generated by performing the
+ following conversion:
+
+ - All colons are removed from the selector
+
+ - Any lowercase letter that had followed a colon will be capitalized.
+
+ Under the default conversion a selector <code>doFoo:withBar:</code> will be exported as
+ <code>doFooWithBar</code>. The default conversion may be overriden using the JSExportAs
+ macro, for example to export a method <code>doFoo:withBar:</code> as <code>doFoo</code>:
+
+<pre>
+@textblock
+ @protocol MyClassJavaScriptMethods <JSExport>
+ JSExportAs(doFoo,
+ - (void)doFoo:(id)foo withBar:(id)bar
+ );
+ @end
+@/textblock
+</pre>
+
+ Note that the JSExport macro may only be applied to a selector that takes one
+ or more argument.
+*/
#define JSExportAs(PropertyName, Selector) \
@optional Selector __JS_EXPORT_AS__##PropertyName:(id)argument; @required Selector
diff --git a/Source/JavaScriptCore/API/JSManagedValue.h b/Source/JavaScriptCore/API/JSManagedValue.h
index 5ff3f83cb..d13733d08 100644
--- a/Source/JavaScriptCore/API/JSManagedValue.h
+++ b/Source/JavaScriptCore/API/JSManagedValue.h
@@ -27,37 +27,54 @@
#define JSManagedValue_h
#import <JavaScriptCore/JSBase.h>
+#import <JavaScriptCore/WebKitAvailability.h>
#if JSC_OBJC_API_ENABLED
@class JSValue;
@class JSContext;
-// JSManagedValue represents a "conditionally retained" JSValue.
-// "Conditionally retained" means that as long as either the JSManagedValue
-// JavaScript value is reachable through the JavaScript object graph
-// or the JSManagedValue object is reachable through the external Objective-C
-// object graph as reported to the JSVirtualMachine using
-// addManagedReference:withOwner:, the corresponding JavaScript value will
-// be retained. However, if neither of these conditions are true, the
-// corresponding JSValue will be released and set to nil.
-//
-// The primary use case for JSManagedValue is for safely referencing JSValues
-// from the Objective-C heap. It is incorrect to store a JSValue into an
-// Objective-C heap object, as this can very easily create a reference cycle,
-// keeping the entire JSContext alive.
-NS_CLASS_AVAILABLE(10_9, NA)
+/*!
+@interface
+@discussion JSManagedValue represents a "conditionally retained" JSValue.
+ "Conditionally retained" means that as long as the JSManagedValue's
+ JSValue is reachable through the JavaScript object graph,
+ or through the Objective-C object graph reported to the JSVirtualMachine using
+ addManagedReference:withOwner:, the corresponding JSValue will
+ be retained. However, if neither graph reaches the JSManagedValue, the
+ corresponding JSValue will be released and set to nil.
+
+The primary use for a JSManagedValue is to store a JSValue in an Objective-C
+or Swift object that is exported to JavaScript. It is incorrect to store a JSValue
+in an object that is exported to JavaScript, since doing so creates a retain cycle.
+*/
+NS_CLASS_AVAILABLE(10_9, 7_0)
@interface JSManagedValue : NSObject
-// Convenience method for creating JSManagedValues from JSValues.
+/*!
+@method
+@abstract Create a JSManagedValue from a JSValue.
+@param value
+@result The new JSManagedValue.
+*/
+ (JSManagedValue *)managedValueWithValue:(JSValue *)value;
++ (JSManagedValue *)managedValueWithValue:(JSValue *)value andOwner:(id)owner NS_AVAILABLE(10_10, 8_0);
-// Create a JSManagedValue.
-- (id)initWithValue:(JSValue *)value;
+/*!
+@method
+@abstract Create a JSManagedValue.
+@param value
+@result The new JSManagedValue.
+*/
+- (instancetype)initWithValue:(JSValue *)value;
-// Get the JSValue to which this JSManagedValue refers. If the JavaScript value has been collected,
-// this method returns nil.
-- (JSValue *)value;
+/*!
+@property
+@abstract Get the JSValue from the JSManagedValue.
+@result The corresponding JSValue for this JSManagedValue or
+ nil if the JSValue has been collected.
+*/
+@property (readonly, strong) JSValue *value;
@end
diff --git a/Source/JavaScriptCore/API/JSManagedValue.mm b/Source/JavaScriptCore/API/JSManagedValue.mm
deleted file mode 100644
index f336ba662..000000000
--- a/Source/JavaScriptCore/API/JSManagedValue.mm
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) 2013 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.
- */
-
-
-#import "config.h"
-#import "JSManagedValue.h"
-
-#if JSC_OBJC_API_ENABLED
-
-#import "APICast.h"
-#import "Heap.h"
-#import "JSCJSValueInlines.h"
-#import "JSContextInternal.h"
-#import "JSValueInternal.h"
-#import "Weak.h"
-#import "WeakHandleOwner.h"
-#import "ObjcRuntimeExtras.h"
-
-class JSManagedValueHandleOwner : public JSC::WeakHandleOwner {
-public:
- virtual void finalize(JSC::Handle<JSC::Unknown>, void* context);
- virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&);
-};
-
-static JSManagedValueHandleOwner* managedValueHandleOwner()
-{
- DEFINE_STATIC_LOCAL(JSManagedValueHandleOwner, jsManagedValueHandleOwner, ());
- return &jsManagedValueHandleOwner;
-}
-
-@implementation JSManagedValue {
- JSC::Weak<JSC::JSObject> m_value;
-}
-
-+ (JSManagedValue *)managedValueWithValue:(JSValue *)value
-{
- return [[[self alloc] initWithValue:value] autorelease];
-}
-
-- (id)init
-{
- return [self initWithValue:nil];
-}
-
-- (id)initWithValue:(JSValue *)value
-{
- self = [super init];
- if (!self)
- return nil;
-
- if (!value || !JSValueIsObject([value.context JSGlobalContextRef], [value JSValueRef])) {
- JSC::Weak<JSC::JSObject> weak;
- m_value.swap(weak);
- } else {
- JSC::JSObject* object = toJS(const_cast<OpaqueJSValue*>([value JSValueRef]));
- JSC::Weak<JSC::JSObject> weak(object, managedValueHandleOwner(), self);
- m_value.swap(weak);
- }
-
- return self;
-}
-
-- (JSValue *)value
-{
- if (!m_value)
- return nil;
- JSC::JSObject* object = m_value.get();
- JSContext *context = [JSContext contextWithJSGlobalContextRef:toGlobalRef(object->structure()->globalObject()->globalExec())];
- return [JSValue valueWithJSValueRef:toRef(object) inContext:context];
-}
-
-- (void)disconnectValue
-{
- m_value.clear();
-}
-
-@end
-
-@interface JSManagedValue (PrivateMethods)
-- (void)disconnectValue;
-@end
-
-bool JSManagedValueHandleOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor& visitor)
-{
- JSManagedValue *managedValue = static_cast<JSManagedValue *>(context);
- return visitor.containsOpaqueRoot(managedValue);
-}
-
-void JSManagedValueHandleOwner::finalize(JSC::Handle<JSC::Unknown>, void* context)
-{
- JSManagedValue *managedValue = static_cast<JSManagedValue *>(context);
- [managedValue disconnectValue];
-}
-
-#endif // JSC_OBJC_API_ENABLED
diff --git a/Source/JavaScriptCore/API/JSManagedValueInternal.h b/Source/JavaScriptCore/API/JSManagedValueInternal.h
new file mode 100644
index 000000000..2443fe5a9
--- /dev/null
+++ b/Source/JavaScriptCore/API/JSManagedValueInternal.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2013 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 JSManagedValueInternal_h
+#define JSManagedValueInternal_h
+
+#import <JavaScriptCore/JSBase.h>
+
+#if JSC_OBJC_API_ENABLED
+
+@interface JSManagedValue(Internal)
+
+- (void)didAddOwner:(id)owner;
+- (void)didRemoveOwner:(id)owner;
+
+@end
+
+#endif // JSC_OBJC_API_ENABLED
+
+#endif // JSManagedValueInternal_h
diff --git a/Source/JavaScriptCore/API/JSObjectRef.cpp b/Source/JavaScriptCore/API/JSObjectRef.cpp
index 5ba446513..78efc2461 100644
--- a/Source/JavaScriptCore/API/JSObjectRef.cpp
+++ b/Source/JavaScriptCore/API/JSObjectRef.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008, 2016 Apple Inc. All rights reserved.
* Copyright (C) 2008 Kelvin W Sherlock (ksherlock@gmail.com)
*
* Redistribution and use in source and binary forms, with or without
@@ -11,17 +11,17 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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.
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
@@ -34,6 +34,7 @@
#include "CopiedSpaceInlines.h"
#include "DateConstructor.h"
#include "ErrorConstructor.h"
+#include "Exception.h"
#include "FunctionConstructor.h"
#include "Identifier.h"
#include "InitializeThreading.h"
@@ -51,12 +52,36 @@
#include "JSValueRef.h"
#include "ObjectConstructor.h"
#include "ObjectPrototype.h"
-#include "Operations.h"
+#include "JSCInlines.h"
#include "PropertyNameArray.h"
#include "RegExpConstructor.h"
+#if ENABLE(REMOTE_INSPECTOR)
+#include "JSGlobalObjectInspectorController.h"
+#endif
+
using namespace JSC;
+enum class ExceptionStatus {
+ DidThrow,
+ DidNotThrow
+};
+
+static ExceptionStatus handleExceptionIfNeeded(ExecState* exec, JSValueRef* returnedExceptionRef)
+{
+ if (exec->hadException()) {
+ Exception* exception = exec->exception();
+ if (returnedExceptionRef)
+ *returnedExceptionRef = toRef(exec, exception->value());
+ exec->clearException();
+#if ENABLE(REMOTE_INSPECTOR)
+ exec->vmEntryGlobalObject()->inspectorController().reportAPIException(exec, exception);
+#endif
+ return ExceptionStatus::DidThrow;
+ }
+ return ExceptionStatus::DidNotThrow;
+}
+
JSClassRef JSClassCreate(const JSClassDefinition* definition)
{
initializeThreading();
@@ -85,7 +110,7 @@ JSObjectRef JSObjectMake(JSContextRef ctx, JSClassRef jsClass, void* data)
return 0;
}
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
+ JSLockHolder locker(exec);
if (!jsClass)
return toRef(constructEmptyObject(exec));
@@ -104,8 +129,8 @@ JSObjectRef JSObjectMakeFunctionWithCallback(JSContextRef ctx, JSStringRef name,
return 0;
}
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
- return toRef(JSCallbackFunction::create(exec, exec->lexicalGlobalObject(), callAsFunction, name ? name->string() : ASCIILiteral("anonymous")));
+ JSLockHolder locker(exec);
+ return toRef(JSCallbackFunction::create(exec->vm(), exec->lexicalGlobalObject(), callAsFunction, name ? name->string() : ASCIILiteral("anonymous")));
}
JSObjectRef JSObjectMakeConstructor(JSContextRef ctx, JSClassRef jsClass, JSObjectCallAsConstructorCallback callAsConstructor)
@@ -115,7 +140,7 @@ JSObjectRef JSObjectMakeConstructor(JSContextRef ctx, JSClassRef jsClass, JSObje
return 0;
}
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
+ JSLockHolder locker(exec);
JSValue jsPrototype = jsClass ? jsClass->prototype(exec) : 0;
if (!jsPrototype)
@@ -133,22 +158,19 @@ JSObjectRef JSObjectMakeFunction(JSContextRef ctx, JSStringRef name, unsigned pa
return 0;
}
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
+ JSLockHolder locker(exec);
- Identifier nameID = name ? name->identifier(&exec->vm()) : Identifier(exec, "anonymous");
+ startingLineNumber = std::max(1, startingLineNumber);
+ Identifier nameID = name ? name->identifier(&exec->vm()) : Identifier::fromString(exec, "anonymous");
MarkedArgumentBuffer args;
for (unsigned i = 0; i < parameterCount; i++)
args.append(jsString(exec, parameterNames[i]->string()));
args.append(jsString(exec, body->string()));
- JSObject* result = constructFunction(exec, exec->lexicalGlobalObject(), args, nameID, sourceURL->string(), TextPosition(OrdinalNumber::fromOneBasedInt(startingLineNumber), OrdinalNumber::first()));
- if (exec->hadException()) {
- if (exception)
- *exception = toRef(exec, exec->exception());
- exec->clearException();
+ JSObject* result = constructFunction(exec, exec->lexicalGlobalObject(), args, nameID, sourceURL ? sourceURL->string() : String(), TextPosition(OrdinalNumber::fromOneBasedInt(startingLineNumber), OrdinalNumber::first()));
+ if (handleExceptionIfNeeded(exec, exception) == ExceptionStatus::DidThrow)
result = 0;
- }
return toRef(result);
}
@@ -159,7 +181,7 @@ JSObjectRef JSObjectMakeArray(JSContextRef ctx, size_t argumentCount, const JSVa
return 0;
}
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
+ JSLockHolder locker(exec);
JSObject* result;
if (argumentCount) {
@@ -171,12 +193,8 @@ JSObjectRef JSObjectMakeArray(JSContextRef ctx, size_t argumentCount, const JSVa
} else
result = constructEmptyArray(exec, 0);
- if (exec->hadException()) {
- if (exception)
- *exception = toRef(exec, exec->exception());
- exec->clearException();
+ if (handleExceptionIfNeeded(exec, exception) == ExceptionStatus::DidThrow)
result = 0;
- }
return toRef(result);
}
@@ -188,19 +206,15 @@ JSObjectRef JSObjectMakeDate(JSContextRef ctx, size_t argumentCount, const JSVal
return 0;
}
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
+ JSLockHolder locker(exec);
MarkedArgumentBuffer argList;
for (size_t i = 0; i < argumentCount; ++i)
argList.append(toJS(exec, arguments[i]));
- JSObject* result = constructDate(exec, exec->lexicalGlobalObject(), argList);
- if (exec->hadException()) {
- if (exception)
- *exception = toRef(exec, exec->exception());
- exec->clearException();
+ JSObject* result = constructDate(exec, exec->lexicalGlobalObject(), JSValue(), argList);
+ if (handleExceptionIfNeeded(exec, exception) == ExceptionStatus::DidThrow)
result = 0;
- }
return toRef(result);
}
@@ -212,18 +226,14 @@ JSObjectRef JSObjectMakeError(JSContextRef ctx, size_t argumentCount, const JSVa
return 0;
}
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
+ JSLockHolder locker(exec);
JSValue message = argumentCount ? toJS(exec, arguments[0]) : jsUndefined();
Structure* errorStructure = exec->lexicalGlobalObject()->errorStructure();
JSObject* result = ErrorInstance::create(exec, errorStructure, message);
- if (exec->hadException()) {
- if (exception)
- *exception = toRef(exec, exec->exception());
- exec->clearException();
+ if (handleExceptionIfNeeded(exec, exception) == ExceptionStatus::DidThrow)
result = 0;
- }
return toRef(result);
}
@@ -235,19 +245,15 @@ JSObjectRef JSObjectMakeRegExp(JSContextRef ctx, size_t argumentCount, const JSV
return 0;
}
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
+ JSLockHolder locker(exec);
MarkedArgumentBuffer argList;
for (size_t i = 0; i < argumentCount; ++i)
argList.append(toJS(exec, arguments[i]));
- JSObject* result = constructRegExp(exec, exec->lexicalGlobalObject(), argList);
- if (exec->hadException()) {
- if (exception)
- *exception = toRef(exec, exec->exception());
- exec->clearException();
+ JSObject* result = constructRegExp(exec, exec->lexicalGlobalObject(), argList);
+ if (handleExceptionIfNeeded(exec, exception) == ExceptionStatus::DidThrow)
result = 0;
- }
return toRef(result);
}
@@ -259,7 +265,7 @@ JSValueRef JSObjectGetPrototype(JSContextRef ctx, JSObjectRef object)
return 0;
}
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
+ JSLockHolder locker(exec);
JSObject* jsObject = toJS(object);
return toRef(exec, jsObject->prototype());
@@ -272,12 +278,20 @@ void JSObjectSetPrototype(JSContextRef ctx, JSObjectRef object, JSValueRef value
return;
}
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
+ JSLockHolder locker(exec);
JSObject* jsObject = toJS(object);
JSValue jsValue = toJS(exec, value);
- jsObject->setPrototypeWithCycleCheck(exec->vm(), jsValue.isObject() ? jsValue : jsNull());
+ if (JSProxy* proxy = jsDynamicCast<JSProxy*>(jsObject)) {
+ if (JSGlobalObject* globalObject = jsDynamicCast<JSGlobalObject*>(proxy->target())) {
+ globalObject->resetPrototype(exec->vm(), jsValue.isObject() ? jsValue : jsNull());
+ return;
+ }
+ // Someday we might use proxies for something other than JSGlobalObjects, but today is not that day.
+ RELEASE_ASSERT_NOT_REACHED();
+ }
+ jsObject->setPrototypeWithCycleCheck(exec, jsValue.isObject() ? jsValue : jsNull());
}
bool JSObjectHasProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName)
@@ -287,7 +301,7 @@ bool JSObjectHasProperty(JSContextRef ctx, JSObjectRef object, JSStringRef prope
return false;
}
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
+ JSLockHolder locker(exec);
JSObject* jsObject = toJS(object);
@@ -301,16 +315,12 @@ JSValueRef JSObjectGetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef
return 0;
}
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
+ JSLockHolder locker(exec);
JSObject* jsObject = toJS(object);
JSValue jsValue = jsObject->get(exec, propertyName->identifier(&exec->vm()));
- if (exec->hadException()) {
- if (exception)
- *exception = toRef(exec, exec->exception());
- exec->clearException();
- }
+ handleExceptionIfNeeded(exec, exception);
return toRef(exec, jsValue);
}
@@ -321,24 +331,21 @@ void JSObjectSetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef prope
return;
}
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
+ JSLockHolder locker(exec);
JSObject* jsObject = toJS(object);
Identifier name(propertyName->identifier(&exec->vm()));
JSValue jsValue = toJS(exec, value);
- if (attributes && !jsObject->hasProperty(exec, name))
- jsObject->methodTable()->putDirectVirtual(jsObject, exec, name, jsValue, attributes);
- else {
- PutPropertySlot slot;
+ if (attributes && !jsObject->hasProperty(exec, name)) {
+ PropertyDescriptor desc(jsValue, attributes);
+ jsObject->methodTable()->defineOwnProperty(jsObject, exec, name, desc, false);
+ } else {
+ PutPropertySlot slot(jsObject);
jsObject->methodTable()->put(jsObject, exec, name, jsValue, slot);
}
- if (exec->hadException()) {
- if (exception)
- *exception = toRef(exec, exec->exception());
- exec->clearException();
- }
+ handleExceptionIfNeeded(exec, exception);
}
JSValueRef JSObjectGetPropertyAtIndex(JSContextRef ctx, JSObjectRef object, unsigned propertyIndex, JSValueRef* exception)
@@ -348,16 +355,12 @@ JSValueRef JSObjectGetPropertyAtIndex(JSContextRef ctx, JSObjectRef object, unsi
return 0;
}
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
+ JSLockHolder locker(exec);
JSObject* jsObject = toJS(object);
JSValue jsValue = jsObject->get(exec, propertyIndex);
- if (exec->hadException()) {
- if (exception)
- *exception = toRef(exec, exec->exception());
- exec->clearException();
- }
+ handleExceptionIfNeeded(exec, exception);
return toRef(exec, jsValue);
}
@@ -369,17 +372,13 @@ void JSObjectSetPropertyAtIndex(JSContextRef ctx, JSObjectRef object, unsigned p
return;
}
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
+ JSLockHolder locker(exec);
JSObject* jsObject = toJS(object);
JSValue jsValue = toJS(exec, value);
jsObject->methodTable()->putByIndex(jsObject, exec, propertyIndex, jsValue, false);
- if (exec->hadException()) {
- if (exception)
- *exception = toRef(exec, exec->exception());
- exec->clearException();
- }
+ handleExceptionIfNeeded(exec, exception);
}
bool JSObjectDeleteProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception)
@@ -389,29 +388,29 @@ bool JSObjectDeleteProperty(JSContextRef ctx, JSObjectRef object, JSStringRef pr
return false;
}
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
+ JSLockHolder locker(exec);
JSObject* jsObject = toJS(object);
bool result = jsObject->methodTable()->deleteProperty(jsObject, exec, propertyName->identifier(&exec->vm()));
- if (exec->hadException()) {
- if (exception)
- *exception = toRef(exec, exec->exception());
- exec->clearException();
- }
+ handleExceptionIfNeeded(exec, exception);
return result;
}
void* JSObjectGetPrivate(JSObjectRef object)
{
JSObject* jsObject = uncheckedToJS(object);
-
- if (jsObject->inherits(&JSCallbackObject<JSGlobalObject>::s_info))
+
+ // Get wrapped object if proxied
+ if (jsObject->inherits(JSProxy::info()))
+ jsObject = jsCast<JSProxy*>(jsObject)->target();
+
+ if (jsObject->inherits(JSCallbackObject<JSGlobalObject>::info()))
return jsCast<JSCallbackObject<JSGlobalObject>*>(jsObject)->getPrivate();
- if (jsObject->inherits(&JSCallbackObject<JSDestructibleObject>::s_info))
+ if (jsObject->inherits(JSCallbackObject<JSDestructibleObject>::info()))
return jsCast<JSCallbackObject<JSDestructibleObject>*>(jsObject)->getPrivate();
#if JSC_OBJC_API_ENABLED
- if (jsObject->inherits(&JSCallbackObject<JSAPIWrapperObject>::s_info))
+ if (jsObject->inherits(JSCallbackObject<JSAPIWrapperObject>::info()))
return jsCast<JSCallbackObject<JSAPIWrapperObject>*>(jsObject)->getPrivate();
#endif
@@ -421,17 +420,21 @@ void* JSObjectGetPrivate(JSObjectRef object)
bool JSObjectSetPrivate(JSObjectRef object, void* data)
{
JSObject* jsObject = uncheckedToJS(object);
-
- if (jsObject->inherits(&JSCallbackObject<JSGlobalObject>::s_info)) {
+
+ // Get wrapped object if proxied
+ if (jsObject->inherits(JSProxy::info()))
+ jsObject = jsCast<JSProxy*>(jsObject)->target();
+
+ if (jsObject->inherits(JSCallbackObject<JSGlobalObject>::info())) {
jsCast<JSCallbackObject<JSGlobalObject>*>(jsObject)->setPrivate(data);
return true;
}
- if (jsObject->inherits(&JSCallbackObject<JSDestructibleObject>::s_info)) {
+ if (jsObject->inherits(JSCallbackObject<JSDestructibleObject>::info())) {
jsCast<JSCallbackObject<JSDestructibleObject>*>(jsObject)->setPrivate(data);
return true;
}
#if JSC_OBJC_API_ENABLED
- if (jsObject->inherits(&JSCallbackObject<JSAPIWrapperObject>::s_info)) {
+ if (jsObject->inherits(JSCallbackObject<JSAPIWrapperObject>::info())) {
jsCast<JSCallbackObject<JSAPIWrapperObject>*>(jsObject)->setPrivate(data);
return true;
}
@@ -443,16 +446,21 @@ bool JSObjectSetPrivate(JSObjectRef object, void* data)
JSValueRef JSObjectGetPrivateProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName)
{
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
+ JSLockHolder locker(exec);
JSObject* jsObject = toJS(object);
JSValue result;
Identifier name(propertyName->identifier(&exec->vm()));
- if (jsObject->inherits(&JSCallbackObject<JSGlobalObject>::s_info))
+
+ // Get wrapped object if proxied
+ if (jsObject->inherits(JSProxy::info()))
+ jsObject = jsCast<JSProxy*>(jsObject)->target();
+
+ if (jsObject->inherits(JSCallbackObject<JSGlobalObject>::info()))
result = jsCast<JSCallbackObject<JSGlobalObject>*>(jsObject)->getPrivateProperty(name);
- else if (jsObject->inherits(&JSCallbackObject<JSDestructibleObject>::s_info))
+ else if (jsObject->inherits(JSCallbackObject<JSDestructibleObject>::info()))
result = jsCast<JSCallbackObject<JSDestructibleObject>*>(jsObject)->getPrivateProperty(name);
#if JSC_OBJC_API_ENABLED
- else if (jsObject->inherits(&JSCallbackObject<JSAPIWrapperObject>::s_info))
+ else if (jsObject->inherits(JSCallbackObject<JSAPIWrapperObject>::info()))
result = jsCast<JSCallbackObject<JSAPIWrapperObject>*>(jsObject)->getPrivateProperty(name);
#endif
return toRef(exec, result);
@@ -461,20 +469,25 @@ JSValueRef JSObjectGetPrivateProperty(JSContextRef ctx, JSObjectRef object, JSSt
bool JSObjectSetPrivateProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef value)
{
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
+ JSLockHolder locker(exec);
JSObject* jsObject = toJS(object);
JSValue jsValue = value ? toJS(exec, value) : JSValue();
Identifier name(propertyName->identifier(&exec->vm()));
- if (jsObject->inherits(&JSCallbackObject<JSGlobalObject>::s_info)) {
+
+ // Get wrapped object if proxied
+ if (jsObject->inherits(JSProxy::info()))
+ jsObject = jsCast<JSProxy*>(jsObject)->target();
+
+ if (jsObject->inherits(JSCallbackObject<JSGlobalObject>::info())) {
jsCast<JSCallbackObject<JSGlobalObject>*>(jsObject)->setPrivateProperty(exec->vm(), name, jsValue);
return true;
}
- if (jsObject->inherits(&JSCallbackObject<JSDestructibleObject>::s_info)) {
+ if (jsObject->inherits(JSCallbackObject<JSDestructibleObject>::info())) {
jsCast<JSCallbackObject<JSDestructibleObject>*>(jsObject)->setPrivateProperty(exec->vm(), name, jsValue);
return true;
}
#if JSC_OBJC_API_ENABLED
- if (jsObject->inherits(&JSCallbackObject<JSAPIWrapperObject>::s_info)) {
+ if (jsObject->inherits(JSCallbackObject<JSAPIWrapperObject>::info())) {
jsCast<JSCallbackObject<JSAPIWrapperObject>*>(jsObject)->setPrivateProperty(exec->vm(), name, jsValue);
return true;
}
@@ -485,19 +498,24 @@ bool JSObjectSetPrivateProperty(JSContextRef ctx, JSObjectRef object, JSStringRe
bool JSObjectDeletePrivateProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName)
{
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
+ JSLockHolder locker(exec);
JSObject* jsObject = toJS(object);
Identifier name(propertyName->identifier(&exec->vm()));
- if (jsObject->inherits(&JSCallbackObject<JSGlobalObject>::s_info)) {
+
+ // Get wrapped object if proxied
+ if (jsObject->inherits(JSProxy::info()))
+ jsObject = jsCast<JSProxy*>(jsObject)->target();
+
+ if (jsObject->inherits(JSCallbackObject<JSGlobalObject>::info())) {
jsCast<JSCallbackObject<JSGlobalObject>*>(jsObject)->deletePrivateProperty(name);
return true;
}
- if (jsObject->inherits(&JSCallbackObject<JSDestructibleObject>::s_info)) {
+ if (jsObject->inherits(JSCallbackObject<JSDestructibleObject>::info())) {
jsCast<JSCallbackObject<JSDestructibleObject>*>(jsObject)->deletePrivateProperty(name);
return true;
}
#if JSC_OBJC_API_ENABLED
- if (jsObject->inherits(&JSCallbackObject<JSAPIWrapperObject>::s_info)) {
+ if (jsObject->inherits(JSCallbackObject<JSAPIWrapperObject>::info())) {
jsCast<JSCallbackObject<JSAPIWrapperObject>*>(jsObject)->deletePrivateProperty(name);
return true;
}
@@ -505,10 +523,11 @@ bool JSObjectDeletePrivateProperty(JSContextRef ctx, JSObjectRef object, JSStrin
return false;
}
-bool JSObjectIsFunction(JSContextRef, JSObjectRef object)
+bool JSObjectIsFunction(JSContextRef ctx, JSObjectRef object)
{
if (!object)
return false;
+ JSLockHolder locker(toJS(ctx));
CallData callData;
JSCell* cell = toJS(object);
return cell->methodTable()->getCallData(cell, callData) != CallTypeNone;
@@ -517,7 +536,7 @@ bool JSObjectIsFunction(JSContextRef, JSObjectRef object)
JSValueRef JSObjectCallAsFunction(JSContextRef ctx, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
+ JSLockHolder locker(exec);
if (!object)
return 0;
@@ -528,8 +547,6 @@ JSValueRef JSObjectCallAsFunction(JSContextRef ctx, JSObjectRef object, JSObject
if (!jsThisObject)
jsThisObject = exec->globalThisValue();
- jsThisObject = jsThisObject->methodTable()->toThisObject(jsThisObject, exec);
-
MarkedArgumentBuffer argList;
for (size_t i = 0; i < argumentCount; i++)
argList.append(toJS(exec, arguments[i]));
@@ -539,13 +556,9 @@ JSValueRef JSObjectCallAsFunction(JSContextRef ctx, JSObjectRef object, JSObject
if (callType == CallTypeNone)
return 0;
- JSValueRef result = toRef(exec, call(exec, jsObject, callType, callData, jsThisObject, argList));
- if (exec->hadException()) {
- if (exception)
- *exception = toRef(exec, exec->exception());
- exec->clearException();
+ JSValueRef result = toRef(exec, profiledCall(exec, ProfilingReason::API, jsObject, callType, callData, jsThisObject, argList));
+ if (handleExceptionIfNeeded(exec, exception) == ExceptionStatus::DidThrow)
result = 0;
- }
return result;
}
@@ -561,7 +574,7 @@ bool JSObjectIsConstructor(JSContextRef, JSObjectRef object)
JSObjectRef JSObjectCallAsConstructor(JSContextRef ctx, JSObjectRef object, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
+ JSLockHolder locker(exec);
if (!object)
return 0;
@@ -576,13 +589,10 @@ JSObjectRef JSObjectCallAsConstructor(JSContextRef ctx, JSObjectRef object, size
MarkedArgumentBuffer argList;
for (size_t i = 0; i < argumentCount; i++)
argList.append(toJS(exec, arguments[i]));
- JSObjectRef result = toRef(construct(exec, jsObject, constructType, constructData, argList));
- if (exec->hadException()) {
- if (exception)
- *exception = toRef(exec, exec->exception());
- exec->clearException();
+
+ JSObjectRef result = toRef(profiledConstruct(exec, ProfilingReason::API, jsObject, constructType, constructData, argList));
+ if (handleExceptionIfNeeded(exec, exception) == ExceptionStatus::DidThrow)
result = 0;
- }
return result;
}
@@ -597,7 +607,7 @@ public:
unsigned refCount;
VM* vm;
- Vector<JSRetainPtr<JSStringRef> > array;
+ Vector<JSRetainPtr<JSStringRef>> array;
};
JSPropertyNameArrayRef JSObjectCopyPropertyNames(JSContextRef ctx, JSObjectRef object)
@@ -606,15 +616,15 @@ JSPropertyNameArrayRef JSObjectCopyPropertyNames(JSContextRef ctx, JSObjectRef o
ASSERT_NOT_REACHED();
return 0;
}
- JSObject* jsObject = toJS(object);
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
+ JSLockHolder locker(exec);
VM* vm = &exec->vm();
+ JSObject* jsObject = toJS(object);
JSPropertyNameArrayRef propertyNames = new OpaqueJSPropertyNameArray(vm);
- PropertyNameArray array(vm);
- jsObject->methodTable()->getPropertyNames(jsObject, exec, array, ExcludeDontEnumProperties);
+ PropertyNameArray array(vm, PropertyNameMode::Strings);
+ jsObject->methodTable()->getPropertyNames(jsObject, exec, array, EnumerationMode());
size_t size = array.size();
propertyNames->array.reserveInitialCapacity(size);
@@ -633,7 +643,7 @@ JSPropertyNameArrayRef JSPropertyNameArrayRetain(JSPropertyNameArrayRef array)
void JSPropertyNameArrayRelease(JSPropertyNameArrayRef array)
{
if (--array->refCount == 0) {
- APIEntryShim entryShim(array->vm, false);
+ JSLockHolder locker(array->vm);
delete array;
}
}
@@ -651,6 +661,6 @@ JSStringRef JSPropertyNameArrayGetNameAtIndex(JSPropertyNameArrayRef array, size
void JSPropertyNameAccumulatorAddName(JSPropertyNameAccumulatorRef array, JSStringRef propertyName)
{
PropertyNameArray* propertyNames = toJS(array);
- APIEntryShim entryShim(propertyNames->vm());
+ JSLockHolder locker(propertyNames->vm());
propertyNames->add(propertyName->identifier(propertyNames->vm()));
}
diff --git a/Source/JavaScriptCore/API/JSObjectRef.h b/Source/JavaScriptCore/API/JSObjectRef.h
index 5014726bc..754dff363 100644
--- a/Source/JavaScriptCore/API/JSObjectRef.h
+++ b/Source/JavaScriptCore/API/JSObjectRef.h
@@ -11,17 +11,17 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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.
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef JSObjectRef_h
@@ -441,7 +441,7 @@ JS_EXPORT JSObjectRef JSObjectMakeConstructor(JSContextRef ctx, JSClassRef jsCla
@discussion The behavior of this function does not exactly match the behavior of the built-in Array constructor. Specifically, if one argument
is supplied, this function returns an array with one element.
*/
-JS_EXPORT JSObjectRef JSObjectMakeArray(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) AVAILABLE_IN_WEBKIT_VERSION_4_0;
+JS_EXPORT JSObjectRef JSObjectMakeArray(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) CF_AVAILABLE(10_6, 7_0);
/*!
@function
@@ -452,7 +452,7 @@ JS_EXPORT JSObjectRef JSObjectMakeArray(JSContextRef ctx, size_t argumentCount,
@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 JSObject that is a Date.
*/
-JS_EXPORT JSObjectRef JSObjectMakeDate(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) AVAILABLE_IN_WEBKIT_VERSION_4_0;
+JS_EXPORT JSObjectRef JSObjectMakeDate(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) CF_AVAILABLE(10_6, 7_0);
/*!
@function
@@ -463,7 +463,7 @@ JS_EXPORT JSObjectRef JSObjectMakeDate(JSContextRef ctx, size_t argumentCount, c
@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 JSObject that is a Error.
*/
-JS_EXPORT JSObjectRef JSObjectMakeError(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) AVAILABLE_IN_WEBKIT_VERSION_4_0;
+JS_EXPORT JSObjectRef JSObjectMakeError(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) CF_AVAILABLE(10_6, 7_0);
/*!
@function
@@ -474,7 +474,7 @@ JS_EXPORT JSObjectRef JSObjectMakeError(JSContextRef ctx, size_t argumentCount,
@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 JSObject that is a RegExp.
*/
-JS_EXPORT JSObjectRef JSObjectMakeRegExp(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) AVAILABLE_IN_WEBKIT_VERSION_4_0;
+JS_EXPORT JSObjectRef JSObjectMakeRegExp(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) CF_AVAILABLE(10_6, 7_0);
/*!
@function
@@ -485,7 +485,7 @@ JS_EXPORT JSObjectRef JSObjectMakeRegExp(JSContextRef ctx, size_t argumentCount,
@param parameterNames A JSString array containing the names of the function's parameters. Pass NULL if parameterCount is 0.
@param body A JSString containing the script to use as the function's body.
@param sourceURL A JSString containing a URL for the script's source file. This is only used when reporting exceptions. Pass NULL if you do not care to include source file information in exceptions.
-@param startingLineNumber An integer value specifying the script's starting line number in the file located at sourceURL. This is only used when reporting exceptions.
+@param startingLineNumber An integer value specifying the script's starting line number in the file located at sourceURL. This is only used when reporting exceptions. The value is one-based, so the first line is line 1 and invalid values are clamped to 1.
@param exception A pointer to a JSValueRef in which to store a syntax error exception, if any. Pass NULL if you do not care to store a syntax error exception.
@result A JSObject that is a function, or NULL if either body or parameterNames contains a syntax error. The object's prototype will be the default function prototype.
@discussion Use this method when you want to execute a script repeatedly, to avoid the cost of re-parsing the script before each execution.
diff --git a/Source/JavaScriptCore/API/JSProfilerPrivate.cpp b/Source/JavaScriptCore/API/JSProfilerPrivate.cpp
index 0405b4b26..ac112ae6e 100644
--- a/Source/JavaScriptCore/API/JSProfilerPrivate.cpp
+++ b/Source/JavaScriptCore/API/JSProfilerPrivate.cpp
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
@@ -34,7 +34,11 @@ using namespace JSC;
void JSStartProfiling(JSContextRef ctx, JSStringRef title)
{
- LegacyProfiler::profiler()->startProfiling(toJS(ctx), title->string());
+ // Use an independent stopwatch for API-initiated profiling, since the user will expect it
+ // to be relative to when their command was issued.
+ RefPtr<Stopwatch> stopwatch = Stopwatch::create();
+ stopwatch->start();
+ LegacyProfiler::profiler()->startProfiling(toJS(ctx), title->string(), stopwatch.release());
}
void JSEndProfiling(JSContextRef ctx, JSStringRef title)
diff --git a/Source/JavaScriptCore/API/JSProfilerPrivate.h b/Source/JavaScriptCore/API/JSProfilerPrivate.h
index b3fe533a3..34f26a202 100644
--- a/Source/JavaScriptCore/API/JSProfilerPrivate.h
+++ b/Source/JavaScriptCore/API/JSProfilerPrivate.h
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
diff --git a/Source/JavaScriptCore/API/JSRemoteInspector.cpp b/Source/JavaScriptCore/API/JSRemoteInspector.cpp
new file mode 100644
index 000000000..faebc5de3
--- /dev/null
+++ b/Source/JavaScriptCore/API/JSRemoteInspector.cpp
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2015 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. ``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
+ * 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 "JSRemoteInspector.h"
+
+#include "JSGlobalObjectConsoleClient.h"
+
+#if ENABLE(REMOTE_INSPECTOR)
+#include "RemoteInspector.h"
+#endif
+
+using namespace Inspector;
+
+static bool remoteInspectionEnabledByDefault = true;
+
+void JSRemoteInspectorDisableAutoStart(void)
+{
+#if ENABLE(REMOTE_INSPECTOR)
+ RemoteInspector::startDisabled();
+#endif
+}
+
+void JSRemoteInspectorStart(void)
+{
+#if ENABLE(REMOTE_INSPECTOR)
+ RemoteInspector::singleton();
+#endif
+}
+
+void JSRemoteInspectorSetParentProcessInformation(pid_t pid, const UInt8* auditData, size_t auditLength)
+{
+#if ENABLE(REMOTE_INSPECTOR)
+ RetainPtr<CFDataRef> auditDataRef = adoptCF(CFDataCreate(kCFAllocatorDefault, auditData, auditLength));
+ RemoteInspector::singleton().setParentProcessInformation(pid, auditDataRef);
+#else
+ UNUSED_PARAM(pid);
+ UNUSED_PARAM(auditData);
+ UNUSED_PARAM(auditLength);
+#endif
+}
+
+void JSRemoteInspectorSetLogToSystemConsole(bool logToSystemConsole)
+{
+ JSGlobalObjectConsoleClient::setLogToSystemConsole(logToSystemConsole);
+}
+
+bool JSRemoteInspectorGetInspectionEnabledByDefault(void)
+{
+ return remoteInspectionEnabledByDefault;
+}
+
+void JSRemoteInspectorSetInspectionEnabledByDefault(bool enabledByDefault)
+{
+ remoteInspectionEnabledByDefault = enabledByDefault;
+}
diff --git a/Source/JavaScriptCore/API/JSRemoteInspector.h b/Source/JavaScriptCore/API/JSRemoteInspector.h
new file mode 100644
index 000000000..2bde47949
--- /dev/null
+++ b/Source/JavaScriptCore/API/JSRemoteInspector.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2015 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. ``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
+ * 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 JSRemoteInspector_h
+#define JSRemoteInspector_h
+
+#include <JavaScriptCore/JSBase.h>
+#include <JavaScriptCore/WebKitAvailability.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+JS_EXPORT void JSRemoteInspectorDisableAutoStart(void) CF_AVAILABLE(10_11, 9_0);
+JS_EXPORT void JSRemoteInspectorStart(void) CF_AVAILABLE(10_11, 9_0);
+JS_EXPORT void JSRemoteInspectorSetParentProcessInformation(pid_t, const uint8_t* auditData, size_t auditLength) CF_AVAILABLE(10_11, 9_0);
+
+JS_EXPORT void JSRemoteInspectorSetLogToSystemConsole(bool) CF_AVAILABLE(10_11, 9_0);
+
+JS_EXPORT bool JSRemoteInspectorGetInspectionEnabledByDefault(void) CF_AVAILABLE(10_11, 9_0);
+JS_EXPORT void JSRemoteInspectorSetInspectionEnabledByDefault(bool) CF_AVAILABLE(10_11, 9_0);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* JSRemoteInspector_h */
diff --git a/Source/JavaScriptCore/API/JSRetainPtr.h b/Source/JavaScriptCore/API/JSRetainPtr.h
index 574f7aaf1..e40084080 100644
--- a/Source/JavaScriptCore/API/JSRetainPtr.h
+++ b/Source/JavaScriptCore/API/JSRetainPtr.h
@@ -10,7 +10,7 @@
* 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.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * 3. Neither the name of Apple Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
@@ -57,11 +57,8 @@ public:
T operator->() const { return m_ptr; }
bool operator!() const { return !m_ptr; }
+ explicit operator bool() const { return m_ptr; }
- // This conversion operator allows implicit conversion to bool but not to other integer types.
- typedef T JSRetainPtr::*UnspecifiedBoolType;
- operator UnspecifiedBoolType() const { return m_ptr ? &JSRetainPtr::m_ptr : 0; }
-
JSRetainPtr& operator=(const JSRetainPtr&);
template<typename U> JSRetainPtr& operator=(const JSRetainPtr<U>&);
JSRetainPtr& operator=(T);
@@ -75,6 +72,16 @@ private:
T m_ptr;
};
+inline JSRetainPtr<JSStringRef> adopt(JSStringRef o)
+{
+ return JSRetainPtr<JSStringRef>(Adopt, o);
+}
+
+inline JSRetainPtr<JSGlobalContextRef> adopt(JSGlobalContextRef o)
+{
+ return JSRetainPtr<JSGlobalContextRef>(Adopt, o);
+}
+
template<typename T> inline JSRetainPtr<T>::JSRetainPtr(const JSRetainPtr& o)
: m_ptr(o.m_ptr)
{
diff --git a/Source/JavaScriptCore/API/JSScriptRef.cpp b/Source/JavaScriptCore/API/JSScriptRef.cpp
index 8a5f3caf3..60bde604e 100644
--- a/Source/JavaScriptCore/API/JSScriptRef.cpp
+++ b/Source/JavaScriptCore/API/JSScriptRef.cpp
@@ -26,13 +26,13 @@
#include "config.h"
#include "APICast.h"
-#include "APIShims.h"
#include "Completion.h"
+#include "Exception.h"
#include "JSBasePrivate.h"
#include "VM.h"
#include "JSScriptRefPrivate.h"
#include "OpaqueJSString.h"
-#include "Operations.h"
+#include "JSCInlines.h"
#include "Parser.h"
#include "SourceCode.h"
#include "SourceProvider.h"
@@ -41,14 +41,19 @@ using namespace JSC;
struct OpaqueJSScript : public SourceProvider {
public:
- static WTF::PassRefPtr<OpaqueJSScript> create(VM* vm, const String& url, int startingLineNumber, const String& source)
+ static WTF::RefPtr<OpaqueJSScript> create(VM* vm, const String& url, int startingLineNumber, const String& source)
{
- return WTF::adoptRef(new OpaqueJSScript(vm, url, startingLineNumber, source));
+ return WTF::adoptRef(*new OpaqueJSScript(vm, url, startingLineNumber, source));
}
- const String& source() const OVERRIDE
+ unsigned hash() const override
{
- return m_source;
+ return m_source.get().hash();
+ }
+
+ StringView source() const override
+ {
+ return m_source.get();
}
VM* vm() const { return m_vm; }
@@ -57,19 +62,22 @@ private:
OpaqueJSScript(VM* vm, const String& url, int startingLineNumber, const String& source)
: SourceProvider(url, TextPosition(OrdinalNumber::fromOneBasedInt(startingLineNumber), OrdinalNumber::first()))
, m_vm(vm)
- , m_source(source)
+ , m_source(source.isNull() ? *StringImpl::empty() : *source.impl())
{
}
- ~OpaqueJSScript() { }
+ virtual ~OpaqueJSScript() { }
VM* m_vm;
- String m_source;
+ Ref<StringImpl> m_source;
};
static bool parseScript(VM* vm, const SourceCode& source, ParserError& error)
{
- return JSC::parse<JSC::ProgramNode>(vm, source, 0, Identifier(), JSParseNormal, JSParseProgramCode, error);
+ return !!JSC::parse<JSC::ProgramNode>(
+ vm, source, Identifier(), JSParserBuiltinMode::NotBuiltin,
+ JSParserStrictMode::NotStrict, SourceParseMode::ProgramMode, SuperBinding::NotNeeded,
+ error);
}
extern "C" {
@@ -77,21 +85,23 @@ extern "C" {
JSScriptRef JSScriptCreateReferencingImmortalASCIIText(JSContextGroupRef contextGroup, JSStringRef url, int startingLineNumber, const char* source, size_t length, JSStringRef* errorMessage, int* errorLine)
{
VM* vm = toJS(contextGroup);
- APIEntryShim entryShim(vm);
+ JSLockHolder locker(vm);
for (size_t i = 0; i < length; i++) {
if (!isASCII(source[i]))
return 0;
}
- RefPtr<OpaqueJSScript> result = OpaqueJSScript::create(vm, url->string(), startingLineNumber, String(StringImpl::createFromLiteral(source, length)));
+ startingLineNumber = std::max(1, startingLineNumber);
+
+ RefPtr<OpaqueJSScript> result = OpaqueJSScript::create(vm, url ? url->string() : String(), startingLineNumber, String(StringImpl::createFromLiteral(source, length)));
ParserError error;
if (!parseScript(vm, SourceCode(result), error)) {
if (errorMessage)
- *errorMessage = OpaqueJSString::create(error.m_message).leakRef();
+ *errorMessage = OpaqueJSString::create(error.message()).leakRef();
if (errorLine)
- *errorLine = error.m_line;
- return 0;
+ *errorLine = error.line();
+ return nullptr;
}
return result.release().leakRef();
@@ -100,17 +110,19 @@ JSScriptRef JSScriptCreateReferencingImmortalASCIIText(JSContextGroupRef context
JSScriptRef JSScriptCreateFromString(JSContextGroupRef contextGroup, JSStringRef url, int startingLineNumber, JSStringRef source, JSStringRef* errorMessage, int* errorLine)
{
VM* vm = toJS(contextGroup);
- APIEntryShim entryShim(vm);
+ JSLockHolder locker(vm);
+
+ startingLineNumber = std::max(1, startingLineNumber);
- RefPtr<OpaqueJSScript> result = OpaqueJSScript::create(vm, url->string(), startingLineNumber, source->string());
+ RefPtr<OpaqueJSScript> result = OpaqueJSScript::create(vm, url ? url->string() : String(), startingLineNumber, source->string());
ParserError error;
if (!parseScript(vm, SourceCode(result), error)) {
if (errorMessage)
- *errorMessage = OpaqueJSString::create(error.m_message).leakRef();
+ *errorMessage = OpaqueJSString::create(error.message()).leakRef();
if (errorLine)
- *errorLine = error.m_line;
- return 0;
+ *errorLine = error.line();
+ return nullptr;
}
return result.release().leakRef();
@@ -118,30 +130,30 @@ JSScriptRef JSScriptCreateFromString(JSContextGroupRef contextGroup, JSStringRef
void JSScriptRetain(JSScriptRef script)
{
- APIEntryShim entryShim(script->vm());
+ JSLockHolder locker(script->vm());
script->ref();
}
void JSScriptRelease(JSScriptRef script)
{
- APIEntryShim entryShim(script->vm());
+ JSLockHolder locker(script->vm());
script->deref();
}
JSValueRef JSScriptEvaluate(JSContextRef context, JSScriptRef script, JSValueRef thisValueRef, JSValueRef* exception)
{
ExecState* exec = toJS(context);
- APIEntryShim entryShim(exec);
+ JSLockHolder locker(exec);
if (script->vm() != &exec->vm()) {
RELEASE_ASSERT_NOT_REACHED();
return 0;
}
- JSValue internalException;
+ NakedPtr<Exception> internalException;
JSValue thisValue = thisValueRef ? toJS(exec, thisValueRef) : jsUndefined();
- JSValue result = evaluate(exec, SourceCode(script), thisValue, &internalException);
+ JSValue result = evaluate(exec, SourceCode(script), thisValue, internalException);
if (internalException) {
if (exception)
- *exception = toRef(exec, internalException);
+ *exception = toRef(exec, internalException->value());
return 0;
}
ASSERT(result);
diff --git a/Source/JavaScriptCore/API/JSScriptRefPrivate.h b/Source/JavaScriptCore/API/JSScriptRefPrivate.h
index e1992052a..e6224ce37 100644
--- a/Source/JavaScriptCore/API/JSScriptRefPrivate.h
+++ b/Source/JavaScriptCore/API/JSScriptRefPrivate.h
@@ -42,7 +42,7 @@ extern "C" {
@abstract Creates a script reference from an ascii string, without copying or taking ownership of the string
@param contextGroup The context group the script is to be used in.
@param url The source url to be reported in errors and exceptions.
- @param startingLineNumber An integer value specifying the script's starting line number in the file located at sourceURL. This is only used when reporting exceptions.
+ @param startingLineNumber An integer value specifying the script's starting line number in the file located at sourceURL. This is only used when reporting exceptions. The value is one-based, so the first line is line 1 and invalid values are clamped to 1.
@param source The source string. This is required to be pure ASCII and to never be deallocated.
@param length The length of the source string.
@param errorMessage A pointer to a JSStringRef in which to store the parse error message if the source is not valid. Pass NULL if you do not care to store an error message.
@@ -58,7 +58,7 @@ JS_EXPORT JSScriptRef JSScriptCreateReferencingImmortalASCIIText(JSContextGroupR
@abstract Creates a script reference from a string
@param contextGroup The context group the script is to be used in.
@param url The source url to be reported in errors and exceptions.
- @param startingLineNumber An integer value specifying the script's starting line number in the file located at sourceURL. This is only used when reporting exceptions.
+ @param startingLineNumber An integer value specifying the script's starting line number in the file located at sourceURL. This is only used when reporting exceptions. The value is one-based, so the first line is line 1 and invalid values are clamped to 1.
@param source The source string.
@param errorMessage A pointer to a JSStringRef in which to store the parse error message if the source is not valid. Pass NULL if you do not care to store an error message.
@param errorLine A pointer to an int in which to store the line number of a parser error. Pass NULL if you do not care to store an error line.
diff --git a/Source/JavaScriptCore/API/JSStringRef.cpp b/Source/JavaScriptCore/API/JSStringRef.cpp
index 812f3d413..909540481 100644
--- a/Source/JavaScriptCore/API/JSStringRef.cpp
+++ b/Source/JavaScriptCore/API/JSStringRef.cpp
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
@@ -37,7 +37,7 @@ using namespace WTF::Unicode;
JSStringRef JSStringCreateWithCharacters(const JSChar* chars, size_t numChars)
{
initializeThreading();
- return OpaqueJSString::create(chars, numChars).leakRef();
+ return &OpaqueJSString::create(reinterpret_cast<const UChar*>(chars), numChars).leakRef();
}
JSStringRef JSStringCreateWithUTF8CString(const char* string)
@@ -51,18 +51,18 @@ JSStringRef JSStringCreateWithUTF8CString(const char* string)
const LChar* stringStart = reinterpret_cast<const LChar*>(string);
if (conversionOK == convertUTF8ToUTF16(&string, string + length, &p, p + length, &sourceIsAllASCII)) {
if (sourceIsAllASCII)
- return OpaqueJSString::create(stringStart, length).leakRef();
- return OpaqueJSString::create(buffer.data(), p - buffer.data()).leakRef();
+ return &OpaqueJSString::create(stringStart, length).leakRef();
+ return &OpaqueJSString::create(buffer.data(), p - buffer.data()).leakRef();
}
}
- return OpaqueJSString::create().leakRef();
+ return &OpaqueJSString::create().leakRef();
}
JSStringRef JSStringCreateWithCharactersNoCopy(const JSChar* chars, size_t numChars)
{
initializeThreading();
- return OpaqueJSString::create(StringImpl::createWithoutCopying(chars, numChars, WTF::DoesNotHaveTerminatingNullCharacter)).leakRef();
+ return OpaqueJSString::create(StringImpl::createWithoutCopying(reinterpret_cast<const UChar*>(chars), numChars)).leakRef();
}
JSStringRef JSStringRetain(JSStringRef string)
@@ -78,12 +78,16 @@ void JSStringRelease(JSStringRef string)
size_t JSStringGetLength(JSStringRef string)
{
+ if (!string)
+ return 0;
return string->length();
}
const JSChar* JSStringGetCharactersPtr(JSStringRef string)
{
- return string->characters();
+ if (!string)
+ return nullptr;
+ return reinterpret_cast<const JSChar*>(string->characters());
}
size_t JSStringGetMaximumUTF8CStringSize(JSStringRef string)
@@ -94,23 +98,29 @@ size_t JSStringGetMaximumUTF8CStringSize(JSStringRef string)
size_t JSStringGetUTF8CString(JSStringRef string, char* buffer, size_t bufferSize)
{
- if (!bufferSize)
+ if (!string || !buffer || !bufferSize)
return 0;
- char* p = buffer;
- const UChar* d = string->characters();
- ConversionResult result = convertUTF16ToUTF8(&d, d + string->length(), &p, p + bufferSize - 1, true);
- *p++ = '\0';
+ char* destination = buffer;
+ ConversionResult result;
+ if (string->is8Bit()) {
+ const LChar* source = string->characters8();
+ result = convertLatin1ToUTF8(&source, source + string->length(), &destination, destination + bufferSize - 1);
+ } else {
+ const UChar* source = string->characters16();
+ result = convertUTF16ToUTF8(&source, source + string->length(), &destination, destination + bufferSize - 1, true);
+ }
+
+ *destination++ = '\0';
if (result != conversionOK && result != targetExhausted)
return 0;
- return p - buffer;
+ return destination - buffer;
}
bool JSStringIsEqual(JSStringRef a, JSStringRef b)
{
- unsigned len = a->length();
- return len == b->length() && 0 == memcmp(a->characters(), b->characters(), len * sizeof(UChar));
+ return OpaqueJSString::equal(a, b);
}
bool JSStringIsEqualToUTF8CString(JSStringRef a, const char* b)
diff --git a/Source/JavaScriptCore/API/JSStringRef.h b/Source/JavaScriptCore/API/JSStringRef.h
index 75d73c919..6f45fcbd8 100644
--- a/Source/JavaScriptCore/API/JSStringRef.h
+++ b/Source/JavaScriptCore/API/JSStringRef.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,17 +10,17 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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.
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef JSStringRef_h
diff --git a/Source/JavaScriptCore/API/JSStringRefBSTR.cpp b/Source/JavaScriptCore/API/JSStringRefBSTR.cpp
index 70f42540b..e900d24d8 100644
--- a/Source/JavaScriptCore/API/JSStringRefBSTR.cpp
+++ b/Source/JavaScriptCore/API/JSStringRefBSTR.cpp
@@ -10,7 +10,7 @@
* 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.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * 3. Neither the name of Apple Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
diff --git a/Source/JavaScriptCore/API/JSStringRefBSTR.h b/Source/JavaScriptCore/API/JSStringRefBSTR.h
index 59f19b763..066c68d53 100644
--- a/Source/JavaScriptCore/API/JSStringRefBSTR.h
+++ b/Source/JavaScriptCore/API/JSStringRefBSTR.h
@@ -10,7 +10,7 @@
* 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.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * 3. Neither the name of Apple Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
diff --git a/Source/JavaScriptCore/API/JSStringRefCF.cpp b/Source/JavaScriptCore/API/JSStringRefCF.cpp
index 64d2d6251..05872593f 100644
--- a/Source/JavaScriptCore/API/JSStringRefCF.cpp
+++ b/Source/JavaScriptCore/API/JSStringRefCF.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
@@ -28,10 +28,10 @@
#include "APICast.h"
#include "InitializeThreading.h"
+#include "JSCJSValue.h"
#include "JSStringRef.h"
#include "OpaqueJSString.h"
-#include <runtime/JSCJSValue.h>
-#include <wtf/OwnArrayPtr.h>
+#include <wtf/StdLibExtras.h>
JSStringRef JSStringCreateWithCFString(CFStringRef string)
{
@@ -40,23 +40,28 @@ JSStringRef JSStringCreateWithCFString(CFStringRef string)
// We cannot use CFIndex here since CFStringGetLength can return values larger than
// it can hold. (<rdar://problem/6806478>)
size_t length = CFStringGetLength(string);
- if (length) {
- Vector<LChar, 1024> lcharBuffer(length);
- CFIndex usedBufferLength;
- CFIndex convertedSize = CFStringGetBytes(string, CFRangeMake(0, length), kCFStringEncodingISOLatin1, 0, false, lcharBuffer.data(), length, &usedBufferLength);
- if (static_cast<size_t>(convertedSize) == length && static_cast<size_t>(usedBufferLength) == length)
- return OpaqueJSString::create(lcharBuffer.data(), length).leakRef();
-
- OwnArrayPtr<UniChar> buffer = adoptArrayPtr(new UniChar[length]);
- CFStringGetCharacters(string, CFRangeMake(0, length), buffer.get());
- COMPILE_ASSERT(sizeof(UniChar) == sizeof(UChar), unichar_and_uchar_must_be_same_size);
- return OpaqueJSString::create(reinterpret_cast<UChar*>(buffer.get()), length).leakRef();
- }
-
- return OpaqueJSString::create(reinterpret_cast<const LChar*>(""), 0).leakRef();
+ if (!length)
+ return &OpaqueJSString::create(reinterpret_cast<const LChar*>(""), 0).leakRef();
+
+ Vector<LChar, 1024> lcharBuffer(length);
+ CFIndex usedBufferLength;
+ CFIndex convertedSize = CFStringGetBytes(string, CFRangeMake(0, length), kCFStringEncodingISOLatin1, 0, false, lcharBuffer.data(), length, &usedBufferLength);
+ if (static_cast<size_t>(convertedSize) == length && static_cast<size_t>(usedBufferLength) == length)
+ return &OpaqueJSString::create(lcharBuffer.data(), length).leakRef();
+
+ auto buffer = std::make_unique<UniChar[]>(length);
+ CFStringGetCharacters(string, CFRangeMake(0, length), buffer.get());
+ static_assert(sizeof(UniChar) == sizeof(UChar), "UniChar and UChar must be same size");
+ return &OpaqueJSString::create(reinterpret_cast<UChar*>(buffer.get()), length).leakRef();
}
-CFStringRef JSStringCopyCFString(CFAllocatorRef alloc, JSStringRef string)
+CFStringRef JSStringCopyCFString(CFAllocatorRef allocator, JSStringRef string)
{
- return CFStringCreateWithCharacters(alloc, reinterpret_cast<const UniChar*>(string->characters()), string->length());
+ if (!string || !string->length())
+ return CFSTR("");
+
+ if (string->is8Bit())
+ return CFStringCreateWithBytes(allocator, reinterpret_cast<const UInt8*>(string->characters8()), string->length(), kCFStringEncodingISOLatin1, false);
+
+ return CFStringCreateWithCharacters(allocator, reinterpret_cast<const UniChar*>(string->characters16()), string->length());
}
diff --git a/Source/JavaScriptCore/API/JSStringRefCF.h b/Source/JavaScriptCore/API/JSStringRefCF.h
index a42476561..1e210c7a9 100644
--- a/Source/JavaScriptCore/API/JSStringRefCF.h
+++ b/Source/JavaScriptCore/API/JSStringRefCF.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
@@ -51,7 +51,7 @@ JS_EXPORT JSStringRef JSStringCreateWithCFString(CFStringRef string);
@param string The JSString to copy into the new CFString.
@result A CFString containing string. Ownership follows the Create Rule.
*/
-JS_EXPORT CFStringRef JSStringCopyCFString(CFAllocatorRef alloc, JSStringRef string);
+JS_EXPORT CFStringRef JSStringCopyCFString(CFAllocatorRef alloc, JSStringRef string) CF_RETURNS_RETAINED;
#ifdef __cplusplus
}
diff --git a/Source/JavaScriptCore/API/JSStringRefQt.cpp b/Source/JavaScriptCore/API/JSStringRefQt.cpp
index c1ce761f7..2d5792e21 100644
--- a/Source/JavaScriptCore/API/JSStringRefQt.cpp
+++ b/Source/JavaScriptCore/API/JSStringRefQt.cpp
@@ -32,7 +32,6 @@
#include "JSStringRef.h"
#include "OpaqueJSString.h"
#include <runtime/JSCJSValue.h>
-#include <wtf/OwnArrayPtr.h>
QString JSStringCopyQString(JSStringRef string)
{
@@ -46,5 +45,5 @@ JSRetainPtr<JSStringRef> JSStringCreateWithQString(const QString& qString)
if (jsString)
return JSRetainPtr<JSStringRef>(Adopt, jsString.release().leakRef());
- return JSRetainPtr<JSStringRef>(Adopt, OpaqueJSString::create().leakRef());
+ return JSRetainPtr<JSStringRef>(Adopt, &OpaqueJSString::create().leakRef());
}
diff --git a/Source/JavaScriptCore/API/JSStringRefQt.h b/Source/JavaScriptCore/API/JSStringRefQt.h
index b4f934a3b..6a3963209 100644
--- a/Source/JavaScriptCore/API/JSStringRefQt.h
+++ b/Source/JavaScriptCore/API/JSStringRefQt.h
@@ -39,7 +39,7 @@
@param string The JSString to copy into the new QString.
@result A QString containing string.
*/
-JS_EXPORT QString JSStringCopyQString(JSStringRef string);
+JS_EXPORT QString JSStringCopyQString(JSStringRef);
JS_EXPORT JSRetainPtr<JSStringRef> JSStringCreateWithQString(const QString&);
#endif /* JSStringRefQt_h */
diff --git a/Source/JavaScriptCore/API/JSValue.h b/Source/JavaScriptCore/API/JSValue.h
index c77707538..37d759407 100644
--- a/Source/JavaScriptCore/API/JSValue.h
+++ b/Source/JavaScriptCore/API/JSValue.h
@@ -28,225 +28,553 @@
#if JSC_OBJC_API_ENABLED
+#import <CoreGraphics/CGGeometry.h>
+
@class JSContext;
-// A JSValue is a reference to a value within the JavaScript object space of a
-// JSVirtualMachine. All instances of JSValue originate from a JSContext and
-// hold a strong reference to this JSContext. As long as any value associated with
-// a particular JSContext is retained, that JSContext will remain alive.
-// Where an instance method is invoked upon a JSValue, and this returns another
-// JSValue, the returned JSValue will originate from the same JSContext as the
-// JSValue on which the method was invoked.
-//
-// For all methods taking arguments of type id, arguments will be converted
-// into a JavaScript value according to the conversion specified below.
-// All JavaScript values are associated with a particular JSVirtualMachine
-// (the associated JSVirtualMachine is available indirectly via the context
-// property). An instance of JSValue may only be passed as an argument to
-// methods on instances of JSValue and JSContext that belong to the same
-// JSVirtualMachine - passing a JSValue to a method on an object originating
-// from a different JSVirtualMachine will result in an Objective-C exception
-// being raised.
-//
-// Conversion between Objective-C and JavaScript types.
-//
-// When converting between JavaScript values and Objective-C objects a copy is
-// performed. Values of types listed below are copied to the corresponding
-// types on conversion in each direction. For NSDictionaries, entries in the
-// dictionary that are keyed by strings are copied onto a JavaScript object.
-// For dictionaries and arrays, conversion is recursive, with the same object
-// conversion being applied to all entries in the collection.
-//
-// Objective-C type | JavaScript type
-// --------------------+---------------------
-// nil | undefined
-// NSNull | null
-// NSString | string
-// NSNumber | number, boolean
-// NSDictionary | Object object
-// NSArray | Array object
-// NSDate | Date object
-// NSBlock * | Function object *
-// id ** | Wrapper object **
-// Class *** | Constructor object ***
-//
-// * Instances of NSBlock with supported arguments types will be presented to
-// JavaScript as a callable Function object. For more information on supported
-// argument types see JSExport.h. If a JavaScript Function originating from an
-// Objective-C block is converted back to an Objective-C object the block will
-// be returned. All other JavaScript functions will be converted in the same
-// manner as a JavaScript object of type Object.
-//
-// ** For Objective-C instances that do not derive from the set of types listed
-// above, a wrapper object to provide a retaining handle to the Objective-C
-// instance from JavaScript. For more information on these wrapper objects, see
-// JSExport.h. When a JavaScript wrapper object is converted back to Objective-C
-// the Objective-C instance being retained by the wrapper is returned.
-//
-// *** For Objective-C Class objects a constructor object containing exported
-// class methods will be returned. See JSExport.h for more information on
-// constructor objects.
-
-NS_CLASS_AVAILABLE(10_9, NA)
+/*!
+@interface
+@discussion A JSValue is a reference to a JavaScript value. Every JSValue
+ originates from a JSContext and holds a strong reference to it.
+ When a JSValue instance method creates a new JSValue, the new value
+ originates from the same JSContext.
+
+ All JSValues values also originate from a JSVirtualMachine
+ (available indirectly via the context property). It is an error to pass a
+ JSValue to a method or property of a JSValue or JSContext originating from a
+ different JSVirtualMachine. Doing so will raise an Objective-C exception.
+*/
+NS_CLASS_AVAILABLE(10_9, 7_0)
@interface JSValue : NSObject
-// Create a JSValue by converting an Objective-C object.
+/*!
+@property
+@abstract The JSContext that this value originates from.
+*/
+@property (readonly, strong) JSContext *context;
+
+/*!
+@methodgroup Creating JavaScript Values
+*/
+/*!
+@method
+@abstract Create a JSValue by converting an Objective-C object.
+@discussion The resulting JSValue retains the provided Objective-C object.
+@param value The Objective-C object to be converted.
+@result The new JSValue.
+*/
+ (JSValue *)valueWithObject:(id)value inContext:(JSContext *)context;
-// Create a JavaScript value from an Objective-C primitive type.
+
+/*!
+@method
+@abstract Create a JavaScript value from a BOOL primitive.
+@param value
+@param context The JSContext in which the resulting JSValue will be created.
+@result The new JSValue representing the equivalent boolean value.
+*/
+ (JSValue *)valueWithBool:(BOOL)value inContext:(JSContext *)context;
+
+/*!
+@method
+@abstract Create a JavaScript value from a double primitive.
+@param value
+@param context The JSContext in which the resulting JSValue will be created.
+@result The new JSValue representing the equivalent boolean value.
+*/
+ (JSValue *)valueWithDouble:(double)value inContext:(JSContext *)context;
+
+/*!
+@method
+@abstract Create a JavaScript value from an <code>int32_t</code> primitive.
+@param value
+@param context The JSContext in which the resulting JSValue will be created.
+@result The new JSValue representing the equivalent boolean value.
+*/
+ (JSValue *)valueWithInt32:(int32_t)value inContext:(JSContext *)context;
+
+/*!
+@method
+@abstract Create a JavaScript value from a <code>uint32_t</code> primitive.
+@param value
+@param context The JSContext in which the resulting JSValue will be created.
+@result The new JSValue representing the equivalent boolean value.
+*/
+ (JSValue *)valueWithUInt32:(uint32_t)value inContext:(JSContext *)context;
-// Create a JavaScript value in this context.
+
+/*!
+@method
+@abstract Create a new, empty JavaScript object.
+@param context The JSContext in which the resulting object will be created.
+@result The new JavaScript object.
+*/
+ (JSValue *)valueWithNewObjectInContext:(JSContext *)context;
+
+/*!
+@method
+@abstract Create a new, empty JavaScript array.
+@param context The JSContext in which the resulting array will be created.
+@result The new JavaScript array.
+*/
+ (JSValue *)valueWithNewArrayInContext:(JSContext *)context;
+
+/*!
+@method
+@abstract Create a new JavaScript regular expression object.
+@param pattern The regular expression pattern.
+@param flags The regular expression flags.
+@param context The JSContext in which the resulting regular expression object will be created.
+@result The new JavaScript regular expression object.
+*/
+ (JSValue *)valueWithNewRegularExpressionFromPattern:(NSString *)pattern flags:(NSString *)flags inContext:(JSContext *)context;
+
+/*!
+@method
+@abstract Create a new JavaScript error object.
+@param message The error message.
+@param context The JSContext in which the resulting error object will be created.
+@result The new JavaScript error object.
+*/
+ (JSValue *)valueWithNewErrorFromMessage:(NSString *)message inContext:(JSContext *)context;
+
+/*!
+@method
+@abstract Create the JavaScript value <code>null</code>.
+@param context The JSContext to which the resulting JSValue belongs.
+@result The JSValue representing the JavaScript value <code>null</code>.
+*/
+ (JSValue *)valueWithNullInContext:(JSContext *)context;
+
+/*!
+@method
+@abstract Create the JavaScript value <code>undefined</code>.
+@param context The JSContext to which the resulting JSValue belongs.
+@result The JSValue representing the JavaScript value <code>undefined</code>.
+*/
+ (JSValue *)valueWithUndefinedInContext:(JSContext *)context;
-// Convert this value to a corresponding Objective-C object, according to the
-// conversion specified above.
+/*!
+@methodgroup Converting to Objective-C Types
+@discussion When converting between JavaScript values and Objective-C objects a copy is
+ performed. Values of types listed below are copied to the corresponding
+ types on conversion in each direction. For NSDictionaries, entries in the
+ dictionary that are keyed by strings are copied onto a JavaScript object.
+ For dictionaries and arrays, conversion is recursive, with the same object
+ conversion being applied to all entries in the collection.
+
+<pre>
+@textblock
+ Objective-C type | JavaScript type
+ --------------------+---------------------
+ nil | undefined
+ NSNull | null
+ NSString | string
+ NSNumber | number, boolean
+ NSDictionary | Object object
+ NSArray | Array object
+ NSDate | Date object
+ NSBlock (1) | Function object (1)
+ id (2) | Wrapper object (2)
+ Class (3) | Constructor object (3)
+@/textblock
+</pre>
+
+ (1) Instances of NSBlock with supported arguments types will be presented to
+ JavaScript as a callable Function object. For more information on supported
+ argument types see JSExport.h. If a JavaScript Function originating from an
+ Objective-C block is converted back to an Objective-C object the block will
+ be returned. All other JavaScript functions will be converted in the same
+ manner as a JavaScript object of type Object.
+
+ (2) For Objective-C instances that do not derive from the set of types listed
+ above, a wrapper object to provide a retaining handle to the Objective-C
+ instance from JavaScript. For more information on these wrapper objects, see
+ JSExport.h. When a JavaScript wrapper object is converted back to Objective-C
+ the Objective-C instance being retained by the wrapper is returned.
+
+ (3) For Objective-C Class objects a constructor object containing exported
+ class methods will be returned. See JSExport.h for more information on
+ constructor objects.
+
+ For all methods taking arguments of type id, arguments will be converted
+ into a JavaScript value according to the above conversion.
+*/
+/*!
+@method
+@abstract Convert this JSValue to an Objective-C object.
+@discussion The JSValue is converted to an Objective-C object according
+ to the conversion rules specified above.
+@result The Objective-C representation of this JSValue.
+*/
- (id)toObject;
-// Convert this value to a corresponding Objective-C object, if the result is
-// not of the specified class then nil will be returned.
+
+/*!
+@method
+@abstract Convert a JSValue to an Objective-C object of a specific class.
+@discussion The JSValue is converted to an Objective-C object of the specified Class.
+ If the result is not of the specified Class then <code>nil</code> will be returned.
+@result An Objective-C object of the specified Class or <code>nil</code>.
+*/
- (id)toObjectOfClass:(Class)expectedClass;
-// The value is copied to a boolean according to the conversion specified by the
-// JavaScript language.
+
+/*!
+@method
+@abstract Convert a JSValue to a boolean.
+@discussion The JSValue is converted to a boolean according to the rules specified
+ by the JavaScript language.
+@result The boolean result of the conversion.
+*/
- (BOOL)toBool;
-// The value is copied to a number according to the conversion specified by the
-// JavaScript language.
+
+/*!
+@method
+@abstract Convert a JSValue to a double.
+@discussion The JSValue is converted to a number according to the rules specified
+ by the JavaScript language.
+@result The double result of the conversion.
+*/
- (double)toDouble;
-// The value is copied to an integer according to the conversion specified by
-// the JavaScript language.
+
+/*!
+@method
+@abstract Convert a JSValue to an <code>int32_t</code>.
+@discussion The JSValue is converted to an integer according to the rules specified
+ by the JavaScript language.
+@result The <code>int32_t</code> result of the conversion.
+*/
- (int32_t)toInt32;
-// The value is copied to an integer according to the conversion specified by
-// the JavaScript language.
+
+/*!
+@method
+@abstract Convert a JSValue to a <code>uint32_t</code>.
+@discussion The JSValue is converted to an integer according to the rules specified
+ by the JavaScript language.
+@result The <code>uint32_t</code> result of the conversion.
+*/
- (uint32_t)toUInt32;
-// If the value is a boolean, a NSNumber value of @YES or @NO will be returned.
-// For all other types the value will be copied to a number according to the
-// conversion specified by the JavaScript language.
+
+/*!
+@method
+@abstract Convert a JSValue to a NSNumber.
+@discussion If the JSValue represents a boolean, a NSNumber value of YES or NO
+ will be returned. For all other types the value will be converted to a number according
+ to the rules specified by the JavaScript language.
+@result The NSNumber result of the conversion.
+*/
- (NSNumber *)toNumber;
-// The value is copied to a string according to the conversion specified by the
-// JavaScript language.
+
+/*!
+@method
+@abstract Convert a JSValue to a NSString.
+@discussion The JSValue is converted to a string according to the rules specified
+ by the JavaScript language.
+@result The NSString containing the result of the conversion.
+*/
- (NSString *)toString;
-// The value is converted to a number representing a time interval since 1970,
-// and a new NSDate instance is returned.
+
+/*!
+@method
+@abstract Convert a JSValue to a NSDate.
+@discussion The value is converted to a number representing a time interval
+ since 1970 which is then used to create a new NSDate instance.
+@result The NSDate created using the converted time interval.
+*/
- (NSDate *)toDate;
-// If the value is null or undefined then nil is returned.
-// If the value is not an object then a JavaScript TypeError will be thrown.
-// The property "length" is read from the object, converted to an unsigned
-// integer, and an NSArray of this size is allocated. Properties corresponding
-// to indicies within the array bounds will be copied to the array, with
-// Objective-C objects converted to equivalent JSValues as specified.
+
+/*!
+@method
+@abstract Convert a JSValue to a NSArray.
+@discussion If the value is <code>null</code> or <code>undefined</code> then <code>nil</code> is returned.
+ If the value is not an object then a JavaScript TypeError will be thrown.
+ The property <code>length</code> is read from the object, converted to an unsigned
+ integer, and an NSArray of this size is allocated. Properties corresponding
+ to indicies within the array bounds will be copied to the array, with
+ JSValues converted to equivalent Objective-C objects as specified.
+@result The NSArray containing the recursively converted contents of the
+ converted JavaScript array.
+*/
- (NSArray *)toArray;
-// If the value is null or undefined then nil is returned.
-// If the value is not an object then a JavaScript TypeError will be thrown.
-// All enumerable properties of the object are copied to the dictionary, with
-// Objective-C objects converted to equivalent JSValues as specified.
+
+/*!
+@method
+@abstract Convert a JSValue to a NSDictionary.
+@discussion If the value is <code>null</code> or <code>undefined</code> then <code>nil</code> is returned.
+ If the value is not an object then a JavaScript TypeError will be thrown.
+ All enumerable properties of the object are copied to the dictionary, with
+ JSValues converted to equivalent Objective-C objects as specified.
+@result The NSDictionary containing the recursively converted contents of
+ the converted JavaScript object.
+*/
- (NSDictionary *)toDictionary;
-// Access a property from the value. This method will return the JavaScript value
-// 'undefined' if the property does not exist.
+/*!
+@methodgroup Accessing Properties
+*/
+/*!
+@method
+@abstract Access a property of a JSValue.
+@result The JSValue for the requested property or the JSValue <code>undefined</code>
+ if the property does not exist.
+*/
- (JSValue *)valueForProperty:(NSString *)property;
-// Set a property on the value.
+
+/*!
+@method
+@abstract Set a property on a JSValue.
+*/
- (void)setValue:(id)value forProperty:(NSString *)property;
-// Delete a property from the value, returns YES if deletion is successful.
+
+/*!
+@method
+@abstract Delete a property from a JSValue.
+@result YES if deletion is successful, NO otherwise.
+*/
- (BOOL)deleteProperty:(NSString *)property;
-// Returns YES if property is present on the value.
-// This method has the same function as the JavaScript operator "in".
+
+/*!
+@method
+@abstract Check if a JSValue has a property.
+@discussion This method has the same function as the JavaScript operator <code>in</code>.
+@result Returns YES if property is present on the value.
+*/
- (BOOL)hasProperty:(NSString *)property;
-// This method may be used to create a data or accessor property on an object;
-// this method operates in accordance with the Object.defineProperty method in
-// the JavaScript language.
+
+/*!
+@method
+@abstract Define properties with custom descriptors on JSValues.
+@discussion This method may be used to create a data or accessor property on an object.
+ This method operates in accordance with the Object.defineProperty method in the
+ JavaScript language.
+*/
- (void)defineProperty:(NSString *)property descriptor:(id)descriptor;
-// Access an indexed property from the value. This method will return the
-// JavaScript value 'undefined' if no property exists at that index.
+/*!
+@method
+@abstract Access an indexed (numerical) property on a JSValue.
+@result The JSValue for the property at the specified index.
+ Returns the JavaScript value <code>undefined</code> if no property exists at that index.
+*/
- (JSValue *)valueAtIndex:(NSUInteger)index;
-// Set an indexed property on the value. For JSValues that are JavaScript arrays,
-// indices greater than UINT_MAX - 1 will not affect the length of the array.
+
+/*!
+@method
+@abstract Set an indexed (numerical) property on a JSValue.
+@discussion For JSValues that are JavaScript arrays, indices greater than
+ UINT_MAX - 1 will not affect the length of the array.
+*/
- (void)setValue:(id)value atIndex:(NSUInteger)index;
-// All JavaScript values are precisely one of these types.
-- (BOOL)isUndefined;
-- (BOOL)isNull;
-- (BOOL)isBoolean;
-- (BOOL)isNumber;
-- (BOOL)isString;
-- (BOOL)isObject;
+/*!
+@methodgroup Checking JavaScript Types
+*/
+/*!
+@method
+@abstract Check if a JSValue corresponds to the JavaScript value <code>undefined</code>.
+*/
+@property (readonly) BOOL isUndefined;
+
+/*!
+@method
+@abstract Check if a JSValue corresponds to the JavaScript value <code>null</code>.
+*/
+@property (readonly) BOOL isNull;
+
+/*!
+@method
+@abstract Check if a JSValue is a boolean.
+*/
+@property (readonly) BOOL isBoolean;
+
+/*!
+@method
+@abstract Check if a JSValue is a number.
+@discussion In JavaScript, there is no differentiation between types of numbers.
+ Semantically all numbers behave like doubles except in special cases like bit
+ operations.
+*/
+@property (readonly) BOOL isNumber;
+
+/*!
+@method
+@abstract Check if a JSValue is a string.
+*/
+@property (readonly) BOOL isString;
+
+/*!
+@method
+@abstract Check if a JSValue is an object.
+*/
+@property (readonly) BOOL isObject;
-// This method has the same function as the JavaScript operator "===".
+/*!
+@method
+@abstract Check if a JSValue is an array.
+*/
+@property (readonly) BOOL isArray NS_AVAILABLE(10_11, 9_0);
+
+/*!
+@method
+@abstract Check if a JSValue is a date.
+*/
+@property (readonly) BOOL isDate NS_AVAILABLE(10_11, 9_0);
+
+/*!
+@method
+@abstract Compare two JSValues using JavaScript's <code>===</code> operator.
+*/
- (BOOL)isEqualToObject:(id)value;
-// This method has the same function as the JavaScript operator "==".
+
+/*!
+@method
+@abstract Compare two JSValues using JavaScript's <code>==</code> operator.
+*/
- (BOOL)isEqualWithTypeCoercionToObject:(id)value;
-// This method has the same function as the JavaScript operator "instanceof".
+
+/*!
+@method
+@abstract Check if a JSValue is an instance of another object.
+@discussion This method has the same function as the JavaScript operator <code>instanceof</code>.
+ If an object other than a JSValue is passed, it will first be converted according to
+ the aforementioned rules.
+*/
- (BOOL)isInstanceOf:(id)value;
-// Call this value as a function passing the specified arguments.
+/*!
+@methodgroup Calling Functions and Constructors
+*/
+/*!
+@method
+@abstract Invoke a JSValue as a function.
+@discussion In JavaScript, if a function doesn't explicitly return a value then it
+ implicitly returns the JavaScript value <code>undefined</code>.
+@param arguments The arguments to pass to the function.
+@result The return value of the function call.
+*/
- (JSValue *)callWithArguments:(NSArray *)arguments;
-// Call this value as a constructor passing the specified arguments.
+
+/*!
+@method
+@abstract Invoke a JSValue as a constructor.
+@discussion This is equivalent to using the <code>new</code> syntax in JavaScript.
+@param arguments The arguments to pass to the constructor.
+@result The return value of the constructor call.
+*/
- (JSValue *)constructWithArguments:(NSArray *)arguments;
-// Access the property named "method" from this value; call the value resulting
-// from the property access as a function, passing this value as the "this"
-// value, and the specified arguments.
-- (JSValue *)invokeMethod:(NSString *)method withArguments:(NSArray *)arguments;
-// The JSContext that this value originates from.
-@property(readonly, retain) JSContext *context;
+/*!
+@method
+@abstract Invoke a method on a JSValue.
+@discussion Accesses the property named <code>method</code> from this value and
+ calls the resulting value as a function, passing this JSValue as the <code>this</code>
+ value along with the specified arguments.
+@param method The name of the method to be invoked.
+@param arguments The arguments to pass to the method.
+@result The return value of the method call.
+*/
+- (JSValue *)invokeMethod:(NSString *)method withArguments:(NSArray *)arguments;
@end
-// Objective-C methods exported to JavaScript may have argument and/or return
-// values of struct types, provided that conversion to and from the struct is
-// supported by JSValue. Support is provided for any types where JSValue
-// contains both a class method "valueWith<Type>:inContext:", and and instance
-// method "to<Type>" - where the string "<Type>" in these selector names match,
-// with the first argument to the former being of the same struct type as the
-// return type of the latter.
-// Support is provided for structs of type CGPoint, NSRange, CGRect and CGSize.
-@interface JSValue(StructSupport)
-
-// This method returns a newly allocated JavaScript object containing properties
-// named "x" and "y", with values from the CGPoint.
+/*!
+@category
+@discussion Objective-C methods exported to JavaScript may have argument and/or return
+ values of struct types, provided that conversion to and from the struct is
+ supported by JSValue. Support is provided for any types where JSValue
+ contains both a class method <code>valueWith<Type>:inContext:</code>, and and instance
+ method <code>to<Type></code>- where the string <code><Type></code> in these selector names match,
+ with the first argument to the former being of the same struct type as the
+ return type of the latter.
+ Support is provided for structs of type CGPoint, NSRange, CGRect and CGSize.
+*/
+@interface JSValue (StructSupport)
+
+/*!
+@method
+@abstract Create a JSValue from a CGPoint.
+@result A newly allocated JavaScript object containing properties
+ named <code>x</code> and <code>y</code>, with values from the CGPoint.
+*/
+ (JSValue *)valueWithPoint:(CGPoint)point inContext:(JSContext *)context;
-// This method returns a newly allocated JavaScript object containing properties
-// named "location" and "length", with values from the NSRange.
+
+/*!
+@method
+@abstract Create a JSValue from a NSRange.
+@result A newly allocated JavaScript object containing properties
+ named <code>location</code> and <code>length</code>, with values from the NSRange.
+*/
+ (JSValue *)valueWithRange:(NSRange)range inContext:(JSContext *)context;
-// This method returns a newly allocated JavaScript object containing properties
-// named "x", "y", "width", and "height", with values from the CGRect.
+
+/*!
+@method
+@abstract
+Create a JSValue from a CGRect.
+@result A newly allocated JavaScript object containing properties
+ named <code>x</code>, <code>y</code>, <code>width</code>, and <code>height</code>, with values from the CGRect.
+*/
+ (JSValue *)valueWithRect:(CGRect)rect inContext:(JSContext *)context;
-// This method returns a newly allocated JavaScript object containing properties
-// named "width" and "height", with values from the CGSize.
+
+/*!
+@method
+@abstract Create a JSValue from a CGSize.
+@result A newly allocated JavaScript object containing properties
+ named <code>width</code> and <code>height</code>, with values from the CGSize.
+*/
+ (JSValue *)valueWithSize:(CGSize)size inContext:(JSContext *)context;
-// Convert a value to type CGPoint by reading properties named "x" and "y" from
-// this value, and converting the results to double.
+/*!
+@method
+@abstract Convert a JSValue to a CGPoint.
+@discussion Reads the properties named <code>x</code> and <code>y</code> from
+ this JSValue, and converts the results to double.
+@result The new CGPoint.
+*/
- (CGPoint)toPoint;
-// Convert a value to type NSRange by accessing properties named "location" and
-// "length" from this value converting the results to double.
+
+/*!
+@method
+@abstract Convert a JSValue to an NSRange.
+@discussion Reads the properties named <code>location</code> and
+ <code>length</code> from this JSValue and converts the results to double.
+@result The new NSRange.
+*/
- (NSRange)toRange;
-// Convert a value to type CGRect by reading properties named "x", "y", "width",
-// and "height" from this value, and converting the results to double.
+
+/*!
+@method
+@abstract Convert a JSValue to a CGRect.
+@discussion Reads the properties named <code>x</code>, <code>y</code>,
+ <code>width</code>, and <code>height</code> from this JSValue and converts the results to double.
+@result The new CGRect.
+*/
- (CGRect)toRect;
-// Convert a value to type CGSize by accessing properties named "width" and
-// "height" from this value converting the results to double.
+
+/*!
+@method
+@abstract Convert a JSValue to a CGSize.
+@discussion Reads the properties named <code>width</code> and
+ <code>height</code> from this JSValue and converts the results to double.
+@result The new CGSize.
+*/
- (CGSize)toSize;
@end
-// Instances of JSValue implement the following methods in order to enable
-// support for subscript access by key and index, for example:
-//
-// JSValue *objectA, *objectB;
-// JSValue *v1 = object[@"X"]; // Get value for property "X" from 'object'.
-// JSValue *v2 = object[42]; // Get value for index 42 from 'object'.
-// object[@"Y"] = v1; // Assign 'v1' to property "Y" of 'object'.
-// object[101] = v2; // Assign 'v2' to index 101 of 'object'.
-//
-// An object key passed as a subscript will be converted to a JavaScript value,
-// and then the value converted to a string used as a property name.
-@interface JSValue(SubscriptSupport)
+/*!
+@category
+@discussion Instances of JSValue implement the following methods in order to enable
+ support for subscript access by key and index, for example:
+
+@textblock
+ JSValue *objectA, *objectB;
+ JSValue *v1 = object[@"X"]; // Get value for property "X" from 'object'.
+ JSValue *v2 = object[42]; // Get value for index 42 from 'object'.
+ object[@"Y"] = v1; // Assign 'v1' to property "Y" of 'object'.
+ object[101] = v2; // Assign 'v2' to index 101 of 'object'.
+@/textblock
+
+ An object key passed as a subscript will be converted to a JavaScript value,
+ and then the value converted to a string used as a property name.
+*/
+@interface JSValue (SubscriptSupport)
- (JSValue *)objectForKeyedSubscript:(id)key;
- (JSValue *)objectAtIndexedSubscript:(NSUInteger)index;
@@ -255,46 +583,85 @@ NS_CLASS_AVAILABLE(10_9, NA)
@end
-// These functions are for bridging between the C API and the Objective-C API.
-@interface JSValue(JSValueRefSupport)
-// Creates a JSValue, wrapping its C API counterpart.
+/*!
+@category
+@discussion These functions are for bridging between the C API and the Objective-C API.
+*/
+@interface JSValue (JSValueRefSupport)
+
+/*!
+@method
+@abstract Creates a JSValue, wrapping its C API counterpart.
+@param value
+@param context
+@result The Objective-C API equivalent of the specified JSValueRef.
+*/
+ (JSValue *)valueWithJSValueRef:(JSValueRef)value inContext:(JSContext *)context;
-// Returns the C API counterpart wrapped by a JSContext.
-- (JSValueRef)JSValueRef;
+
+/*!
+@property
+@abstract Returns the C API counterpart wrapped by a JSContext.
+@result The C API equivalent of this JSValue.
+*/
+@property (readonly) JSValueRef JSValueRef;
@end
#ifdef __cplusplus
extern "C" {
#endif
-// These keys may assist in creating a property descriptor for use with the
-// defineProperty method on JSValue.
-// Property descriptors must fit one of three descriptions:
-// Data Descriptor:
-// - A descriptor containing one or both of the keys "value" and "writable",
-// and optionally containing one or both of the keys "enumerable" and
-// "configurable". A data descriptor may not contain either the "get" or
-// "set" key.
-// A data descriptor may be used to create or modify the attributes of a
-// data property on an object (replacing any existing accessor property).
-// Accessor Descriptor:
-// - A descriptor containing one or both of the keys "get" and "set", and
-// optionally containing one or both of the keys "enumerable" and
-// "configurable". An accessor descriptor may not contain either the "value"
-// or "writable" key.
-// An accessor descriptor may be used to create or modify the attributes of
-// an accessor property on an object (replacing any existing data property).
-// Generic Descriptor:
-// - A descriptor containing one or both of the keys "enumerable" and
-// "configurable". A generic descriptor may not contain any of the keys
-// "value", " writable", "get", or "set".
-// A generic descriptor may be used to modify the attributes of an existing
-// data or accessor property, or to create a new data property.
+/*!
+@group Property Descriptor Constants
+@discussion These keys may assist in creating a property descriptor for use with the
+ defineProperty method on JSValue.
+ Property descriptors must fit one of three descriptions:
+
+ Data Descriptor:
+ - A descriptor containing one or both of the keys <code>value</code> and <code>writable</code>,
+ and optionally containing one or both of the keys <code>enumerable</code> and
+ <code>configurable</code>. A data descriptor may not contain either the <code>get</code> or
+ <code>set</code> key.
+ A data descriptor may be used to create or modify the attributes of a
+ data property on an object (replacing any existing accessor property).
+
+ Accessor Descriptor:
+ - A descriptor containing one or both of the keys <code>get</code> and <code>set</code>, and
+ optionally containing one or both of the keys <code>enumerable</code> and
+ <code>configurable</code>. An accessor descriptor may not contain either the <code>value</code>
+ or <code>writable</code> key.
+ An accessor descriptor may be used to create or modify the attributes of
+ an accessor property on an object (replacing any existing data property).
+
+ Generic Descriptor:
+ - A descriptor containing one or both of the keys <code>enumerable</code> and
+ <code>configurable</code>. A generic descriptor may not contain any of the keys
+ <code>value</code>, <code>writable</code>, <code>get</code>, or <code>set</code>.
+ A generic descriptor may be used to modify the attributes of an existing
+ data or accessor property, or to create a new data property.
+*/
+/*!
+@const
+*/
JS_EXPORT extern NSString * const JSPropertyDescriptorWritableKey;
+/*!
+@const
+*/
JS_EXPORT extern NSString * const JSPropertyDescriptorEnumerableKey;
+/*!
+@const
+*/
JS_EXPORT extern NSString * const JSPropertyDescriptorConfigurableKey;
+/*!
+@const
+*/
JS_EXPORT extern NSString * const JSPropertyDescriptorValueKey;
+/*!
+@const
+*/
JS_EXPORT extern NSString * const JSPropertyDescriptorGetKey;
+/*!
+@const
+*/
JS_EXPORT extern NSString * const JSPropertyDescriptorSetKey;
#ifdef __cplusplus
diff --git a/Source/JavaScriptCore/API/JSValue.mm b/Source/JavaScriptCore/API/JSValue.mm
deleted file mode 100644
index e708cc674..000000000
--- a/Source/JavaScriptCore/API/JSValue.mm
+++ /dev/null
@@ -1,1131 +0,0 @@
-/*
- * Copyright (C) 2013 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. ``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
- * 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"
-
-#import "APICast.h"
-#import "APIShims.h"
-#import "DateInstance.h"
-#import "Error.h"
-#import "JavaScriptCore.h"
-#import "JSContextInternal.h"
-#import "JSVirtualMachineInternal.h"
-#import "JSValueInternal.h"
-#import "JSWrapperMap.h"
-#import "ObjcRuntimeExtras.h"
-#import "Operations.h"
-#import "JSCJSValue.h"
-#import <wtf/HashMap.h>
-#import <wtf/HashSet.h>
-#import <wtf/Vector.h>
-#import <wtf/TCSpinLock.h>
-#import <wtf/text/WTFString.h>
-#import <wtf/text/StringHash.h>
-
-#if JSC_OBJC_API_ENABLED
-
-NSString * const JSPropertyDescriptorWritableKey = @"writable";
-NSString * const JSPropertyDescriptorEnumerableKey = @"enumerable";
-NSString * const JSPropertyDescriptorConfigurableKey = @"configurable";
-NSString * const JSPropertyDescriptorValueKey = @"value";
-NSString * const JSPropertyDescriptorGetKey = @"get";
-NSString * const JSPropertyDescriptorSetKey = @"set";
-
-@implementation JSValue {
- JSValueRef m_value;
-}
-
-- (JSValueRef)JSValueRef
-{
- return m_value;
-}
-
-+ (JSValue *)valueWithObject:(id)value inContext:(JSContext *)context
-{
- return [JSValue valueWithJSValueRef:objectToValue(context, value) inContext:context];
-}
-
-+ (JSValue *)valueWithBool:(BOOL)value inContext:(JSContext *)context
-{
- return [JSValue valueWithJSValueRef:JSValueMakeBoolean([context JSGlobalContextRef], value) inContext:context];
-}
-
-+ (JSValue *)valueWithDouble:(double)value inContext:(JSContext *)context
-{
- return [JSValue valueWithJSValueRef:JSValueMakeNumber([context JSGlobalContextRef], value) inContext:context];
-}
-
-+ (JSValue *)valueWithInt32:(int32_t)value inContext:(JSContext *)context
-{
- return [JSValue valueWithJSValueRef:JSValueMakeNumber([context JSGlobalContextRef], value) inContext:context];
-}
-
-+ (JSValue *)valueWithUInt32:(uint32_t)value inContext:(JSContext *)context
-{
- return [JSValue valueWithJSValueRef:JSValueMakeNumber([context JSGlobalContextRef], value) inContext:context];
-}
-
-+ (JSValue *)valueWithNewObjectInContext:(JSContext *)context
-{
- return [JSValue valueWithJSValueRef:JSObjectMake([context JSGlobalContextRef], 0, 0) inContext:context];
-}
-
-+ (JSValue *)valueWithNewArrayInContext:(JSContext *)context
-{
- return [JSValue valueWithJSValueRef:JSObjectMakeArray([context JSGlobalContextRef], 0, NULL, 0) inContext:context];
-}
-
-+ (JSValue *)valueWithNewRegularExpressionFromPattern:(NSString *)pattern flags:(NSString *)flags inContext:(JSContext *)context
-{
- JSStringRef patternString = JSStringCreateWithCFString((CFStringRef)pattern);
- JSStringRef flagsString = JSStringCreateWithCFString((CFStringRef)flags);
- JSValueRef arguments[2] = { JSValueMakeString([context JSGlobalContextRef], patternString), JSValueMakeString([context JSGlobalContextRef], flagsString) };
- JSStringRelease(patternString);
- JSStringRelease(flagsString);
-
- return [JSValue valueWithJSValueRef:JSObjectMakeRegExp([context JSGlobalContextRef], 2, arguments, 0) inContext:context];
-}
-
-+ (JSValue *)valueWithNewErrorFromMessage:(NSString *)message inContext:(JSContext *)context
-{
- JSStringRef string = JSStringCreateWithCFString((CFStringRef)message);
- JSValueRef argument = JSValueMakeString([context JSGlobalContextRef], string);
- JSStringRelease(string);
-
- return [JSValue valueWithJSValueRef:JSObjectMakeError([context JSGlobalContextRef], 1, &argument, 0) inContext:context];
-}
-
-+ (JSValue *)valueWithNullInContext:(JSContext *)context
-{
- return [JSValue valueWithJSValueRef:JSValueMakeNull([context JSGlobalContextRef]) inContext:context];
-}
-
-+ (JSValue *)valueWithUndefinedInContext:(JSContext *)context
-{
- return [JSValue valueWithJSValueRef:JSValueMakeUndefined([context JSGlobalContextRef]) inContext:context];
-}
-
-- (id)toObject
-{
- return valueToObject(_context, m_value);
-}
-
-- (id)toObjectOfClass:(Class)expectedClass
-{
- id result = [self toObject];
- return [result isKindOfClass:expectedClass] ? result : nil;
-}
-
-- (BOOL)toBool
-{
- return JSValueToBoolean([_context JSGlobalContextRef], m_value);
-}
-
-- (double)toDouble
-{
- JSValueRef exception = 0;
- double result = JSValueToNumber([_context JSGlobalContextRef], m_value, &exception);
- if (exception) {
- [_context notifyException:exception];
- return std::numeric_limits<double>::quiet_NaN();
- }
-
- return result;
-}
-
-- (int32_t)toInt32
-{
- return JSC::toInt32([self toDouble]);
-}
-
-- (uint32_t)toUInt32
-{
- return JSC::toUInt32([self toDouble]);
-}
-
-- (NSNumber *)toNumber
-{
- JSValueRef exception = 0;
- id result = valueToNumber([_context JSGlobalContextRef], m_value, &exception);
- if (exception)
- [_context notifyException:exception];
- return result;
-}
-
-- (NSString *)toString
-{
- JSValueRef exception = 0;
- id result = valueToString([_context JSGlobalContextRef], m_value, &exception);
- if (exception)
- [_context notifyException:exception];
- return result;
-}
-
-- (NSDate *)toDate
-{
- JSValueRef exception = 0;
- id result = valueToDate([_context JSGlobalContextRef], m_value, &exception);
- if (exception)
- [_context notifyException:exception];
- return result;
-}
-
-- (NSArray *)toArray
-{
- JSValueRef exception = 0;
- id result = valueToArray([_context JSGlobalContextRef], m_value, &exception);
- if (exception)
- [_context notifyException:exception];
- return result;
-}
-
-- (NSDictionary *)toDictionary
-{
- JSValueRef exception = 0;
- id result = valueToDictionary([_context JSGlobalContextRef], m_value, &exception);
- if (exception)
- [_context notifyException:exception];
- return result;
-}
-
-- (JSValue *)valueForProperty:(NSString *)propertyName
-{
- JSValueRef exception = 0;
- JSObjectRef object = JSValueToObject([_context JSGlobalContextRef], m_value, &exception);
- if (exception)
- return [_context valueFromNotifyException:exception];
-
- JSStringRef name = JSStringCreateWithCFString((CFStringRef)propertyName);
- JSValueRef result = JSObjectGetProperty([_context JSGlobalContextRef], object, name, &exception);
- JSStringRelease(name);
- if (exception)
- return [_context valueFromNotifyException:exception];
-
- return [JSValue valueWithJSValueRef:result inContext:_context];
-}
-
-- (void)setValue:(id)value forProperty:(NSString *)propertyName
-{
- JSValueRef exception = 0;
- JSObjectRef object = JSValueToObject([_context JSGlobalContextRef], m_value, &exception);
- if (exception) {
- [_context notifyException:exception];
- return;
- }
-
- JSStringRef name = JSStringCreateWithCFString((CFStringRef)propertyName);
- JSObjectSetProperty([_context JSGlobalContextRef], object, name, objectToValue(_context, value), 0, &exception);
- JSStringRelease(name);
- if (exception) {
- [_context notifyException:exception];
- return;
- }
-}
-
-- (BOOL)deleteProperty:(NSString *)propertyName
-{
- JSValueRef exception = 0;
- JSObjectRef object = JSValueToObject([_context JSGlobalContextRef], m_value, &exception);
- if (exception)
- return [_context boolFromNotifyException:exception];
-
- JSStringRef name = JSStringCreateWithCFString((CFStringRef)propertyName);
- BOOL result = JSObjectDeleteProperty([_context JSGlobalContextRef], object, name, &exception);
- JSStringRelease(name);
- if (exception)
- return [_context boolFromNotifyException:exception];
-
- return result;
-}
-
-- (BOOL)hasProperty:(NSString *)propertyName
-{
- JSValueRef exception = 0;
- JSObjectRef object = JSValueToObject([_context JSGlobalContextRef], m_value, &exception);
- if (exception)
- return [_context boolFromNotifyException:exception];
-
- JSStringRef name = JSStringCreateWithCFString((CFStringRef)propertyName);
- BOOL result = JSObjectHasProperty([_context JSGlobalContextRef], object, name);
- JSStringRelease(name);
- return result;
-}
-
-- (void)defineProperty:(NSString *)property descriptor:(id)descriptor
-{
- [[_context globalObject][@"Object"] invokeMethod:@"defineProperty" withArguments:@[ self, property, descriptor ]];
-}
-
-- (JSValue *)valueAtIndex:(NSUInteger)index
-{
- // Properties that are higher than an unsigned value can hold are converted to a double then inserted as a normal property.
- // Indices that are bigger than the max allowed index size (UINT_MAX - 1) will be handled internally in get().
- if (index != (unsigned)index)
- return [self valueForProperty:[[JSValue valueWithDouble:index inContext:_context] toString]];
-
- JSValueRef exception = 0;
- JSObjectRef object = JSValueToObject([_context JSGlobalContextRef], m_value, &exception);
- if (exception)
- return [_context valueFromNotifyException:exception];
-
- JSValueRef result = JSObjectGetPropertyAtIndex([_context JSGlobalContextRef], object, (unsigned)index, &exception);
- if (exception)
- return [_context valueFromNotifyException:exception];
-
- return [JSValue valueWithJSValueRef:result inContext:_context];
-}
-
-- (void)setValue:(id)value atIndex:(NSUInteger)index
-{
- // Properties that are higher than an unsigned value can hold are converted to a double, then inserted as a normal property.
- // Indices that are bigger than the max allowed index size (UINT_MAX - 1) will be handled internally in putByIndex().
- if (index != (unsigned)index)
- return [self setValue:value forProperty:[[JSValue valueWithDouble:index inContext:_context] toString]];
-
- JSValueRef exception = 0;
- JSObjectRef object = JSValueToObject([_context JSGlobalContextRef], m_value, &exception);
- if (exception) {
- [_context notifyException:exception];
- return;
- }
-
- JSObjectSetPropertyAtIndex([_context JSGlobalContextRef], object, (unsigned)index, objectToValue(_context, value), &exception);
- if (exception) {
- [_context notifyException:exception];
- return;
- }
-}
-
-- (BOOL)isUndefined
-{
- return JSValueIsUndefined([_context JSGlobalContextRef], m_value);
-}
-
-- (BOOL)isNull
-{
- return JSValueIsNull([_context JSGlobalContextRef], m_value);
-}
-
-- (BOOL)isBoolean
-{
- return JSValueIsBoolean([_context JSGlobalContextRef], m_value);
-}
-
-- (BOOL)isNumber
-{
- return JSValueIsNumber([_context JSGlobalContextRef], m_value);
-}
-
-- (BOOL)isString
-{
- return JSValueIsString([_context JSGlobalContextRef], m_value);
-}
-
-- (BOOL)isObject
-{
- return JSValueIsObject([_context JSGlobalContextRef], m_value);
-}
-
-- (BOOL)isEqualToObject:(id)value
-{
- return JSValueIsStrictEqual([_context JSGlobalContextRef], m_value, objectToValue(_context, value));
-}
-
-- (BOOL)isEqualWithTypeCoercionToObject:(id)value
-{
- JSValueRef exception = 0;
- BOOL result = JSValueIsEqual([_context JSGlobalContextRef], m_value, objectToValue(_context, value), &exception);
- if (exception)
- return [_context boolFromNotifyException:exception];
-
- return result;
-}
-
-- (BOOL)isInstanceOf:(id)value
-{
- JSValueRef exception = 0;
- JSObjectRef constructor = JSValueToObject([_context JSGlobalContextRef], objectToValue(_context, value), &exception);
- if (exception)
- return [_context boolFromNotifyException:exception];
-
- BOOL result = JSValueIsInstanceOfConstructor([_context JSGlobalContextRef], m_value, constructor, &exception);
- if (exception)
- return [_context boolFromNotifyException:exception];
-
- return result;
-}
-
-- (JSValue *)callWithArguments:(NSArray *)argumentArray
-{
- NSUInteger argumentCount = [argumentArray count];
- JSValueRef arguments[argumentCount];
- for (unsigned i = 0; i < argumentCount; ++i)
- arguments[i] = objectToValue(_context, [argumentArray objectAtIndex:i]);
-
- JSValueRef exception = 0;
- JSObjectRef object = JSValueToObject([_context JSGlobalContextRef], m_value, &exception);
- if (exception)
- return [_context valueFromNotifyException:exception];
-
- JSValueRef result = JSObjectCallAsFunction([_context JSGlobalContextRef], object, 0, argumentCount, arguments, &exception);
- if (exception)
- return [_context valueFromNotifyException:exception];
-
- return [JSValue valueWithJSValueRef:result inContext:_context];
-}
-
-- (JSValue *)constructWithArguments:(NSArray *)argumentArray
-{
- NSUInteger argumentCount = [argumentArray count];
- JSValueRef arguments[argumentCount];
- for (unsigned i = 0; i < argumentCount; ++i)
- arguments[i] = objectToValue(_context, [argumentArray objectAtIndex:i]);
-
- JSValueRef exception = 0;
- JSObjectRef object = JSValueToObject([_context JSGlobalContextRef], m_value, &exception);
- if (exception)
- return [_context valueFromNotifyException:exception];
-
- JSObjectRef result = JSObjectCallAsConstructor([_context JSGlobalContextRef], object, argumentCount, arguments, &exception);
- if (exception)
- return [_context valueFromNotifyException:exception];
-
- return [JSValue valueWithJSValueRef:result inContext:_context];
-}
-
-- (JSValue *)invokeMethod:(NSString *)method withArguments:(NSArray *)arguments
-{
- NSUInteger argumentCount = [arguments count];
- JSValueRef argumentArray[argumentCount];
- for (unsigned i = 0; i < argumentCount; ++i)
- argumentArray[i] = objectToValue(_context, [arguments objectAtIndex:i]);
-
- JSValueRef exception = 0;
- JSObjectRef thisObject = JSValueToObject([_context JSGlobalContextRef], m_value, &exception);
- if (exception)
- return [_context valueFromNotifyException:exception];
-
- JSStringRef name = JSStringCreateWithCFString((CFStringRef)method);
- JSValueRef function = JSObjectGetProperty([_context JSGlobalContextRef], thisObject, name, &exception);
- JSStringRelease(name);
- if (exception)
- return [_context valueFromNotifyException:exception];
-
- JSObjectRef object = JSValueToObject([_context JSGlobalContextRef], function, &exception);
- if (exception)
- return [_context valueFromNotifyException:exception];
-
- JSValueRef result = JSObjectCallAsFunction([_context JSGlobalContextRef], object, thisObject, argumentCount, argumentArray, &exception);
- if (exception)
- return [_context valueFromNotifyException:exception];
-
- return [JSValue valueWithJSValueRef:result inContext:_context];
-}
-
-@end
-
-@implementation JSValue(StructSupport)
-
-- (CGPoint)toPoint
-{
- return (CGPoint){
- [self[@"x"] toDouble],
- [self[@"y"] toDouble]
- };
-}
-
-- (NSRange)toRange
-{
- return (NSRange){
- [[self[@"location"] toNumber] unsignedIntegerValue],
- [[self[@"length"] toNumber] unsignedIntegerValue]
- };
-}
-
-- (CGRect)toRect
-{
- return (CGRect){
- [self toPoint],
- [self toSize]
- };
-}
-
-- (CGSize)toSize
-{
- return (CGSize){
- [self[@"width"] toDouble],
- [self[@"height"] toDouble]
- };
-}
-
-+ (JSValue *)valueWithPoint:(CGPoint)point inContext:(JSContext *)context
-{
- return [JSValue valueWithObject:@{
- @"x":@(point.x),
- @"y":@(point.y)
- } inContext:context];
-}
-
-+ (JSValue *)valueWithRange:(NSRange)range inContext:(JSContext *)context
-{
- return [JSValue valueWithObject:@{
- @"location":@(range.location),
- @"length":@(range.length)
- } inContext:context];
-}
-
-+ (JSValue *)valueWithRect:(CGRect)rect inContext:(JSContext *)context
-{
- return [JSValue valueWithObject:@{
- @"x":@(rect.origin.x),
- @"y":@(rect.origin.y),
- @"width":@(rect.size.width),
- @"height":@(rect.size.height)
- } inContext:context];
-}
-
-+ (JSValue *)valueWithSize:(CGSize)size inContext:(JSContext *)context
-{
- return [JSValue valueWithObject:@{
- @"width":@(size.width),
- @"height":@(size.height)
- } inContext:context];
-}
-
-@end
-
-@implementation JSValue(SubscriptSupport)
-
-- (JSValue *)objectForKeyedSubscript:(id)key
-{
- if (![key isKindOfClass:[NSString class]]) {
- key = [[JSValue valueWithObject:key inContext:_context] toString];
- if (!key)
- return [JSValue valueWithUndefinedInContext:_context];
- }
-
- return [self valueForProperty:(NSString *)key];
-}
-
-- (JSValue *)objectAtIndexedSubscript:(NSUInteger)index
-{
- return [self valueAtIndex:index];
-}
-
-- (void)setObject:(id)object forKeyedSubscript:(NSObject <NSCopying> *)key
-{
- if (![key isKindOfClass:[NSString class]]) {
- key = [[JSValue valueWithObject:key inContext:_context] toString];
- if (!key)
- return;
- }
-
- [self setValue:object forProperty:(NSString *)key];
-}
-
-- (void)setObject:(id)object atIndexedSubscript:(NSUInteger)index
-{
- [self setValue:object atIndex:index];
-}
-
-@end
-
-inline bool isDate(JSObjectRef object, JSGlobalContextRef context)
-{
- JSC::APIEntryShim entryShim(toJS(context));
- return toJS(object)->inherits(&JSC::DateInstance::s_info);
-}
-
-inline bool isArray(JSObjectRef object, JSGlobalContextRef context)
-{
- JSC::APIEntryShim entryShim(toJS(context));
- return toJS(object)->inherits(&JSC::JSArray::s_info);
-}
-
-@implementation JSValue(Internal)
-
-enum ConversionType {
- ContainerNone,
- ContainerArray,
- ContainerDictionary
-};
-
-class JSContainerConvertor {
-public:
- struct Task {
- JSValueRef js;
- id objc;
- ConversionType type;
- };
-
- JSContainerConvertor(JSGlobalContextRef context)
- : m_context(context)
- {
- }
-
- id convert(JSValueRef property);
- void add(Task);
- Task take();
- bool isWorkListEmpty() const { return !m_worklist.size(); }
-
-private:
- JSGlobalContextRef m_context;
- HashMap<JSValueRef, id> m_objectMap;
- Vector<Task> m_worklist;
-};
-
-inline id JSContainerConvertor::convert(JSValueRef value)
-{
- HashMap<JSValueRef, id>::iterator iter = m_objectMap.find(value);
- if (iter != m_objectMap.end())
- return iter->value;
-
- Task result = valueToObjectWithoutCopy(m_context, value);
- if (result.js)
- add(result);
- return result.objc;
-}
-
-void JSContainerConvertor::add(Task task)
-{
- m_objectMap.add(task.js, task.objc);
- if (task.type != ContainerNone)
- m_worklist.append(task);
-}
-
-JSContainerConvertor::Task JSContainerConvertor::take()
-{
- ASSERT(!isWorkListEmpty());
- Task last = m_worklist.last();
- m_worklist.removeLast();
- return last;
-}
-
-static JSContainerConvertor::Task valueToObjectWithoutCopy(JSGlobalContextRef context, JSValueRef value)
-{
- if (!JSValueIsObject(context, value)) {
- id primitive;
- if (JSValueIsBoolean(context, value))
- primitive = JSValueToBoolean(context, value) ? @YES : @NO;
- else if (JSValueIsNumber(context, value)) {
- // Normalize the number, so it will unique correctly in the hash map -
- // it's nicer not to leak this internal implementation detail!
- value = JSValueMakeNumber(context, JSValueToNumber(context, value, 0));
- primitive = [NSNumber numberWithDouble:JSValueToNumber(context, value, 0)];
- } else if (JSValueIsString(context, value)) {
- // Would be nice to unique strings, too.
- JSStringRef jsstring = JSValueToStringCopy(context, value, 0);
- NSString * stringNS = (NSString *)JSStringCopyCFString(kCFAllocatorDefault, jsstring);
- JSStringRelease(jsstring);
- primitive = [stringNS autorelease];
- } else if (JSValueIsNull(context, value))
- primitive = [NSNull null];
- else {
- ASSERT(JSValueIsUndefined(context, value));
- primitive = nil;
- }
- return (JSContainerConvertor::Task){ value, primitive, ContainerNone };
- }
-
- JSObjectRef object = JSValueToObject(context, value, 0);
-
- if (id wrapped = tryUnwrapObjcObject(context, object))
- return (JSContainerConvertor::Task){ object, wrapped, ContainerNone };
-
- if (isDate(object, context))
- return (JSContainerConvertor::Task){ object, [NSDate dateWithTimeIntervalSince1970:JSValueToNumber(context, object, 0)], ContainerNone };
-
- if (isArray(object, context))
- return (JSContainerConvertor::Task){ object, [NSMutableArray array], ContainerArray };
-
- return (JSContainerConvertor::Task){ object, [NSMutableDictionary dictionary], ContainerDictionary };
-}
-
-static id containerValueToObject(JSGlobalContextRef context, JSContainerConvertor::Task task)
-{
- ASSERT(task.type != ContainerNone);
- JSContainerConvertor convertor(context);
- convertor.add(task);
- ASSERT(!convertor.isWorkListEmpty());
-
- do {
- JSContainerConvertor::Task current = convertor.take();
- ASSERT(JSValueIsObject(context, current.js));
- JSObjectRef js = JSValueToObject(context, current.js, 0);
-
- if (current.type == ContainerArray) {
- ASSERT([current.objc isKindOfClass:[NSMutableArray class]]);
- NSMutableArray *array = (NSMutableArray *)current.objc;
-
- JSStringRef lengthString = JSStringCreateWithUTF8CString("length");
- unsigned length = JSC::toUInt32(JSValueToNumber(context, JSObjectGetProperty(context, js, lengthString, 0), 0));
- JSStringRelease(lengthString);
-
- for (unsigned i = 0; i < length; ++i) {
- id objc = convertor.convert(JSObjectGetPropertyAtIndex(context, js, i, 0));
- [array addObject:objc ? objc : [NSNull null]];
- }
- } else {
- ASSERT([current.objc isKindOfClass:[NSMutableDictionary class]]);
- NSMutableDictionary *dictionary = (NSMutableDictionary *)current.objc;
-
- JSPropertyNameArrayRef propertyNameArray = JSObjectCopyPropertyNames(context, js);
- size_t length = JSPropertyNameArrayGetCount(propertyNameArray);
-
- for (size_t i = 0; i < length; ++i) {
- JSStringRef propertyName = JSPropertyNameArrayGetNameAtIndex(propertyNameArray, i);
- if (id objc = convertor.convert(JSObjectGetProperty(context, js, propertyName, 0)))
- dictionary[[(NSString *)JSStringCopyCFString(kCFAllocatorDefault, propertyName) autorelease]] = objc;
- }
-
- JSPropertyNameArrayRelease(propertyNameArray);
- }
-
- } while (!convertor.isWorkListEmpty());
-
- return task.objc;
-}
-
-id valueToObject(JSContext *context, JSValueRef value)
-{
- JSContainerConvertor::Task result = valueToObjectWithoutCopy([context JSGlobalContextRef], value);
- if (result.type == ContainerNone)
- return result.objc;
- return containerValueToObject([context JSGlobalContextRef], result);
-}
-
-id valueToNumber(JSGlobalContextRef context, JSValueRef value, JSValueRef* exception)
-{
- ASSERT(!*exception);
- if (id wrapped = tryUnwrapObjcObject(context, value)) {
- if ([wrapped isKindOfClass:[NSNumber class]])
- return wrapped;
- }
-
- if (JSValueIsBoolean(context, value))
- return JSValueToBoolean(context, value) ? @YES : @NO;
-
- double result = JSValueToNumber(context, value, exception);
- return [NSNumber numberWithDouble:*exception ? std::numeric_limits<double>::quiet_NaN() : result];
-}
-
-id valueToString(JSGlobalContextRef context, JSValueRef value, JSValueRef* exception)
-{
- ASSERT(!*exception);
- if (id wrapped = tryUnwrapObjcObject(context, value)) {
- if ([wrapped isKindOfClass:[NSString class]])
- return wrapped;
- }
-
- JSStringRef jsstring = JSValueToStringCopy(context, value, exception);
- if (*exception) {
- ASSERT(!jsstring);
- return nil;
- }
-
- NSString *stringNS = [(NSString *)JSStringCopyCFString(kCFAllocatorDefault, jsstring) autorelease];
- JSStringRelease(jsstring);
- return stringNS;
-}
-
-id valueToDate(JSGlobalContextRef context, JSValueRef value, JSValueRef* exception)
-{
- ASSERT(!*exception);
- if (id wrapped = tryUnwrapObjcObject(context, value)) {
- if ([wrapped isKindOfClass:[NSDate class]])
- return wrapped;
- }
-
- double result = JSValueToNumber(context, value, exception);
- return *exception ? nil : [NSDate dateWithTimeIntervalSince1970:result];
-}
-
-id valueToArray(JSGlobalContextRef context, JSValueRef value, JSValueRef* exception)
-{
- ASSERT(!*exception);
- if (id wrapped = tryUnwrapObjcObject(context, value)) {
- if ([wrapped isKindOfClass:[NSArray class]])
- return wrapped;
- }
-
- if (JSValueIsObject(context, value))
- return containerValueToObject(context, (JSContainerConvertor::Task){ value, [NSMutableArray array], ContainerArray});
-
- if (!(JSValueIsNull(context, value) || JSValueIsUndefined(context, value)))
- *exception = toRef(JSC::createTypeError(toJS(context), "Cannot convert primitive to NSArray"));
- return nil;
-}
-
-id valueToDictionary(JSGlobalContextRef context, JSValueRef value, JSValueRef* exception)
-{
- ASSERT(!*exception);
- if (id wrapped = tryUnwrapObjcObject(context, value)) {
- if ([wrapped isKindOfClass:[NSDictionary class]])
- return wrapped;
- }
-
- if (JSValueIsObject(context, value))
- return containerValueToObject(context, (JSContainerConvertor::Task){ value, [NSMutableDictionary dictionary], ContainerDictionary});
-
- if (!(JSValueIsNull(context, value) || JSValueIsUndefined(context, value)))
- *exception = toRef(JSC::createTypeError(toJS(context), "Cannot convert primitive to NSDictionary"));
- return nil;
-}
-
-class ObjcContainerConvertor {
-public:
- struct Task {
- id objc;
- JSValueRef js;
- ConversionType type;
- };
-
- ObjcContainerConvertor(JSContext *context)
- : m_context(context)
- {
- }
-
- JSValueRef convert(id object);
- void add(Task);
- Task take();
- bool isWorkListEmpty() const { return !m_worklist.size(); }
-
-private:
- JSContext *m_context;
- HashMap<id, JSValueRef> m_objectMap;
- Vector<Task> m_worklist;
-};
-
-JSValueRef ObjcContainerConvertor::convert(id object)
-{
- ASSERT(object);
-
- auto it = m_objectMap.find(object);
- if (it != m_objectMap.end())
- return it->value;
-
- ObjcContainerConvertor::Task task = objectToValueWithoutCopy(m_context, object);
- add(task);
- return task.js;
-}
-
-void ObjcContainerConvertor::add(ObjcContainerConvertor::Task task)
-{
- m_objectMap.add(task.objc, task.js);
- if (task.type != ContainerNone)
- m_worklist.append(task);
-}
-
-ObjcContainerConvertor::Task ObjcContainerConvertor::take()
-{
- ASSERT(!isWorkListEmpty());
- Task last = m_worklist.last();
- m_worklist.removeLast();
- return last;
-}
-
-inline bool isNSBoolean(id object)
-{
- ASSERT([@YES class] == [@NO class]);
- ASSERT([@YES class] != [NSNumber class]);
- ASSERT([[@YES class] isSubclassOfClass:[NSNumber class]]);
- return [object isKindOfClass:[@YES class]];
-}
-
-static ObjcContainerConvertor::Task objectToValueWithoutCopy(JSContext *context, id object)
-{
- JSGlobalContextRef contextRef = [context JSGlobalContextRef];
-
- if (!object)
- return (ObjcContainerConvertor::Task){ object, JSValueMakeUndefined(contextRef), ContainerNone };
-
- if (!class_conformsToProtocol(object_getClass(object), getJSExportProtocol())) {
- if ([object isKindOfClass:[NSArray class]])
- return (ObjcContainerConvertor::Task){ object, JSObjectMakeArray(contextRef, 0, NULL, 0), ContainerArray };
-
- if ([object isKindOfClass:[NSDictionary class]])
- return (ObjcContainerConvertor::Task){ object, JSObjectMake(contextRef, 0, 0), ContainerDictionary };
-
- if ([object isKindOfClass:[NSNull class]])
- return (ObjcContainerConvertor::Task){ object, JSValueMakeNull(contextRef), ContainerNone };
-
- if ([object isKindOfClass:[JSValue class]])
- return (ObjcContainerConvertor::Task){ object, ((JSValue *)object)->m_value, ContainerNone };
-
- if ([object isKindOfClass:[NSString class]]) {
- JSStringRef string = JSStringCreateWithCFString((CFStringRef)object);
- JSValueRef js = JSValueMakeString(contextRef, string);
- JSStringRelease(string);
- return (ObjcContainerConvertor::Task){ object, js, ContainerNone };
- }
-
- if ([object isKindOfClass:[NSNumber class]]) {
- if (isNSBoolean(object))
- return (ObjcContainerConvertor::Task){ object, JSValueMakeBoolean(contextRef, [object boolValue]), ContainerNone };
- return (ObjcContainerConvertor::Task){ object, JSValueMakeNumber(contextRef, [object doubleValue]), ContainerNone };
- }
-
- if ([object isKindOfClass:[NSDate class]]) {
- JSValueRef argument = JSValueMakeNumber(contextRef, [object timeIntervalSince1970]);
- JSObjectRef result = JSObjectMakeDate(contextRef, 1, &argument, 0);
- return (ObjcContainerConvertor::Task){ object, result, ContainerNone };
- }
-
- if ([object isKindOfClass:[JSManagedValue class]]) {
- JSValue *value = [static_cast<JSManagedValue *>(object) value];
- if (!value)
- return (ObjcContainerConvertor::Task) { object, JSValueMakeUndefined(contextRef), ContainerNone };
- return (ObjcContainerConvertor::Task){ object, value->m_value, ContainerNone };
- }
- }
-
- return (ObjcContainerConvertor::Task){ object, valueInternalValue([context wrapperForObjCObject:object]), ContainerNone };
-}
-
-JSValueRef objectToValue(JSContext *context, id object)
-{
- JSGlobalContextRef contextRef = [context JSGlobalContextRef];
-
- ObjcContainerConvertor::Task task = objectToValueWithoutCopy(context, object);
- if (task.type == ContainerNone)
- return task.js;
-
- ObjcContainerConvertor convertor(context);
- convertor.add(task);
- ASSERT(!convertor.isWorkListEmpty());
-
- do {
- ObjcContainerConvertor::Task current = convertor.take();
- ASSERT(JSValueIsObject(contextRef, current.js));
- JSObjectRef js = JSValueToObject(contextRef, current.js, 0);
-
- if (current.type == ContainerArray) {
- ASSERT([current.objc isKindOfClass:[NSArray class]]);
- NSArray *array = (NSArray *)current.objc;
- NSUInteger count = [array count];
- for (NSUInteger index = 0; index < count; ++index)
- JSObjectSetPropertyAtIndex(contextRef, js, index, convertor.convert([array objectAtIndex:index]), 0);
- } else {
- ASSERT(current.type == ContainerDictionary);
- ASSERT([current.objc isKindOfClass:[NSDictionary class]]);
- NSDictionary *dictionary = (NSDictionary *)current.objc;
- for (id key in [dictionary keyEnumerator]) {
- if ([key isKindOfClass:[NSString class]]) {
- JSStringRef propertyName = JSStringCreateWithCFString((CFStringRef)key);
- JSObjectSetProperty(contextRef, js, propertyName, convertor.convert([dictionary objectForKey:key]), 0, 0);
- JSStringRelease(propertyName);
- }
- }
- }
-
- } while (!convertor.isWorkListEmpty());
-
- return task.js;
-}
-
-JSValueRef valueInternalValue(JSValue * value)
-{
- return value->m_value;
-}
-
-+ (JSValue *)valueWithJSValueRef:(JSValueRef)value inContext:(JSContext *)context
-{
- return [context wrapperForJSObject:value];
-}
-
-- (JSValue *)init
-{
- return nil;
-}
-
-- (JSValue *)initWithValue:(JSValueRef)value inContext:(JSContext *)context
-{
- if (!value || !context)
- return nil;
-
- self = [super init];
- if (!self)
- return nil;
-
- _context = [context retain];
- m_value = value;
- JSValueProtect([_context JSGlobalContextRef], m_value);
- return self;
-}
-
-struct StructTagHandler {
- SEL typeToValueSEL;
- SEL valueToTypeSEL;
-};
-typedef HashMap<String, StructTagHandler> StructHandlers;
-
-static StructHandlers* createStructHandlerMap()
-{
- StructHandlers* structHandlers = new StructHandlers();
-
- size_t valueWithXinContextLength = strlen("valueWithX:inContext:");
- size_t toXLength = strlen("toX");
-
- // Step 1: find all valueWith<Foo>:inContext: class methods in JSValue.
- forEachMethodInClass(object_getClass([JSValue class]), ^(Method method){
- SEL selector = method_getName(method);
- const char* name = sel_getName(selector);
- size_t nameLength = strlen(name);
- // Check for valueWith<Foo>:context:
- if (nameLength < valueWithXinContextLength || memcmp(name, "valueWith", 9) || memcmp(name + nameLength - 11, ":inContext:", 11))
- return;
- // Check for [ id, SEL, <type>, <contextType> ]
- if (method_getNumberOfArguments(method) != 4)
- return;
- char idType[3];
- // Check 2nd argument type is "@"
- char* secondType = method_copyArgumentType(method, 3);
- if (strcmp(secondType, "@") != 0) {
- free(secondType);
- return;
- }
- free(secondType);
- // Check result type is also "@"
- method_getReturnType(method, idType, 3);
- if (strcmp(idType, "@") != 0)
- return;
- char* type = method_copyArgumentType(method, 2);
- structHandlers->add(StringImpl::create(type), (StructTagHandler){ selector, 0 });
- free(type);
- });
-
- // Step 2: find all to<Foo> instance methods in JSValue.
- forEachMethodInClass([JSValue class], ^(Method method){
- SEL selector = method_getName(method);
- const char* name = sel_getName(selector);
- size_t nameLength = strlen(name);
- // Check for to<Foo>
- if (nameLength < toXLength || memcmp(name, "to", 2))
- return;
- // Check for [ id, SEL ]
- if (method_getNumberOfArguments(method) != 2)
- return;
- // Try to find a matching valueWith<Foo>:context: method.
- char* type = method_copyReturnType(method);
-
- StructHandlers::iterator iter = structHandlers->find(type);
- free(type);
- if (iter == structHandlers->end())
- return;
- StructTagHandler& handler = iter->value;
-
- // check that strlen(<foo>) == strlen(<Foo>)
- const char* valueWithName = sel_getName(handler.typeToValueSEL);
- size_t valueWithLength = strlen(valueWithName);
- if (valueWithLength - valueWithXinContextLength != nameLength - toXLength)
- return;
- // Check that <Foo> == <Foo>
- if (memcmp(valueWithName + 9, name + 2, nameLength - toXLength - 1))
- return;
- handler.valueToTypeSEL = selector;
- });
-
- // Step 3: clean up - remove entries where we found prospective valueWith<Foo>:inContext: conversions, but no matching to<Foo> methods.
- typedef HashSet<String> RemoveSet;
- RemoveSet removeSet;
- for (StructHandlers::iterator iter = structHandlers->begin(); iter != structHandlers->end(); ++iter) {
- StructTagHandler& handler = iter->value;
- if (!handler.valueToTypeSEL)
- removeSet.add(iter->key);
- }
-
- for (RemoveSet::iterator iter = removeSet.begin(); iter != removeSet.end(); ++iter)
- structHandlers->remove(*iter);
-
- return structHandlers;
-}
-
-static StructTagHandler* handerForStructTag(const char* encodedType)
-{
- static SpinLock handerForStructTagLock = SPINLOCK_INITIALIZER;
- SpinLockHolder lockHolder(&handerForStructTagLock);
-
- static StructHandlers* structHandlers = createStructHandlerMap();
-
- StructHandlers::iterator iter = structHandlers->find(encodedType);
- if (iter == structHandlers->end())
- return 0;
- return &iter->value;
-}
-
-+ (SEL)selectorForStructToValue:(const char *)structTag
-{
- StructTagHandler* handler = handerForStructTag(structTag);
- return handler ? handler->typeToValueSEL : nil;
-}
-
-+ (SEL)selectorForValueToStruct:(const char *)structTag
-{
- StructTagHandler* handler = handerForStructTag(structTag);
- return handler ? handler->valueToTypeSEL : nil;
-}
-
-- (void)dealloc
-{
- JSValueUnprotect([_context JSGlobalContextRef], m_value);
- [_context release];
- _context = nil;
- [super dealloc];
-}
-
-- (NSString *)description
-{
- if (id wrapped = tryUnwrapObjcObject([_context JSGlobalContextRef], m_value))
- return [wrapped description];
- return [self toString];
-}
-
-NSInvocation *typeToValueInvocationFor(const char* encodedType)
-{
- SEL selector = [JSValue selectorForStructToValue:encodedType];
- if (!selector)
- return 0;
-
- const char* methodTypes = method_getTypeEncoding(class_getClassMethod([JSValue class], selector));
- NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[NSMethodSignature signatureWithObjCTypes:methodTypes]];
- [invocation setSelector:selector];
- return invocation;
-}
-
-NSInvocation *valueToTypeInvocationFor(const char* encodedType)
-{
- SEL selector = [JSValue selectorForValueToStruct:encodedType];
- if (!selector)
- return 0;
-
- const char* methodTypes = method_getTypeEncoding(class_getInstanceMethod([JSValue class], selector));
- NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[NSMethodSignature signatureWithObjCTypes:methodTypes]];
- [invocation setSelector:selector];
- return invocation;
-}
-
-@end
-
-#endif
diff --git a/Source/JavaScriptCore/API/JSValueRef.cpp b/Source/JavaScriptCore/API/JSValueRef.cpp
index 81a2db7b7..54405e2af 100644
--- a/Source/JavaScriptCore/API/JSValueRef.cpp
+++ b/Source/JavaScriptCore/API/JSValueRef.cpp
@@ -10,47 +10,69 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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.
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "JSValueRef.h"
#include "APICast.h"
-#include "APIShims.h"
+#include "DateInstance.h"
+#include "Exception.h"
#include "JSAPIWrapperObject.h"
+#include "JSCInlines.h"
+#include "JSCJSValue.h"
#include "JSCallbackObject.h"
-
-#include <runtime/JSCJSValue.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 "JSGlobalObject.h"
+#include "JSONObject.h"
+#include "JSString.h"
+#include "LiteralParser.h"
+#include "Protect.h"
+#include <algorithm>
#include <wtf/Assertions.h>
#include <wtf/text/StringHash.h>
#include <wtf/text/WTFString.h>
-#include <algorithm> // for std::min
-
#if PLATFORM(MAC)
#include <mach-o/dyld.h>
#endif
+#if ENABLE(REMOTE_INSPECTOR)
+#include "JSGlobalObjectInspectorController.h"
+#endif
+
using namespace JSC;
+enum class ExceptionStatus {
+ DidThrow,
+ DidNotThrow
+};
+
+static ExceptionStatus handleExceptionIfNeeded(ExecState* exec, JSValueRef* returnedExceptionRef)
+{
+ if (exec->hadException()) {
+ Exception* exception = exec->exception();
+ if (returnedExceptionRef)
+ *returnedExceptionRef = toRef(exec, exception->value());
+ exec->clearException();
+#if ENABLE(REMOTE_INSPECTOR)
+ exec->vmEntryGlobalObject()->inspectorController().reportAPIException(exec, exception);
+#endif
+ return ExceptionStatus::DidThrow;
+ }
+ return ExceptionStatus::DidNotThrow;
+}
+
#if PLATFORM(MAC)
static bool evernoteHackNeeded()
{
@@ -69,7 +91,7 @@ static bool evernoteHackNeeded()
return kJSTypeUndefined;
}
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
+ JSLockHolder locker(exec);
JSValue jsValue = toJS(exec, value);
@@ -94,10 +116,9 @@ bool JSValueIsUndefined(JSContextRef ctx, JSValueRef value)
return false;
}
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
+ JSLockHolder locker(exec);
- JSValue jsValue = toJS(exec, value);
- return jsValue.isUndefined();
+ return toJS(exec, value).isUndefined();
}
bool JSValueIsNull(JSContextRef ctx, JSValueRef value)
@@ -107,10 +128,9 @@ bool JSValueIsNull(JSContextRef ctx, JSValueRef value)
return false;
}
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
+ JSLockHolder locker(exec);
- JSValue jsValue = toJS(exec, value);
- return jsValue.isNull();
+ return toJS(exec, value).isNull();
}
bool JSValueIsBoolean(JSContextRef ctx, JSValueRef value)
@@ -120,10 +140,9 @@ bool JSValueIsBoolean(JSContextRef ctx, JSValueRef value)
return false;
}
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
+ JSLockHolder locker(exec);
- JSValue jsValue = toJS(exec, value);
- return jsValue.isBoolean();
+ return toJS(exec, value).isBoolean();
}
bool JSValueIsNumber(JSContextRef ctx, JSValueRef value)
@@ -133,10 +152,9 @@ bool JSValueIsNumber(JSContextRef ctx, JSValueRef value)
return false;
}
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
+ JSLockHolder locker(exec);
- JSValue jsValue = toJS(exec, value);
- return jsValue.isNumber();
+ return toJS(exec, value).isNumber();
}
bool JSValueIsString(JSContextRef ctx, JSValueRef value)
@@ -146,10 +164,9 @@ bool JSValueIsString(JSContextRef ctx, JSValueRef value)
return false;
}
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
+ JSLockHolder locker(exec);
- JSValue jsValue = toJS(exec, value);
- return jsValue.isString();
+ return toJS(exec, value).isString();
}
bool JSValueIsObject(JSContextRef ctx, JSValueRef value)
@@ -159,10 +176,33 @@ bool JSValueIsObject(JSContextRef ctx, JSValueRef value)
return false;
}
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
+ JSLockHolder locker(exec);
- JSValue jsValue = toJS(exec, value);
- return jsValue.isObject();
+ return toJS(exec, value).isObject();
+}
+
+bool JSValueIsArray(JSContextRef ctx, JSValueRef value)
+{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return false;
+ }
+ ExecState* exec = toJS(ctx);
+ JSLockHolder locker(exec);
+
+ return toJS(exec, value).inherits(JSArray::info());
+}
+
+bool JSValueIsDate(JSContextRef ctx, JSValueRef value)
+{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return false;
+ }
+ ExecState* exec = toJS(ctx);
+ JSLockHolder locker(exec);
+
+ return toJS(exec, value).inherits(DateInstance::info());
}
bool JSValueIsObjectOfClass(JSContextRef ctx, JSValueRef value, JSClassRef jsClass)
@@ -172,17 +212,20 @@ bool JSValueIsObjectOfClass(JSContextRef ctx, JSValueRef value, JSClassRef jsCla
return false;
}
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
+ JSLockHolder locker(exec);
JSValue jsValue = toJS(exec, value);
if (JSObject* o = jsValue.getObject()) {
- if (o->inherits(&JSCallbackObject<JSGlobalObject>::s_info))
+ if (o->inherits(JSProxy::info()))
+ o = jsCast<JSProxy*>(o)->target();
+
+ if (o->inherits(JSCallbackObject<JSGlobalObject>::info()))
return jsCast<JSCallbackObject<JSGlobalObject>*>(o)->inherits(jsClass);
- if (o->inherits(&JSCallbackObject<JSDestructibleObject>::s_info))
+ if (o->inherits(JSCallbackObject<JSDestructibleObject>::info()))
return jsCast<JSCallbackObject<JSDestructibleObject>*>(o)->inherits(jsClass);
#if JSC_OBJC_API_ENABLED
- if (o->inherits(&JSCallbackObject<JSAPIWrapperObject>::s_info))
+ if (o->inherits(JSCallbackObject<JSAPIWrapperObject>::info()))
return jsCast<JSCallbackObject<JSAPIWrapperObject>*>(o)->inherits(jsClass);
#endif
}
@@ -196,17 +239,14 @@ bool JSValueIsEqual(JSContextRef ctx, JSValueRef a, JSValueRef b, JSValueRef* ex
return false;
}
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
+ JSLockHolder locker(exec);
JSValue jsA = toJS(exec, a);
JSValue jsB = toJS(exec, b);
bool result = JSValue::equal(exec, jsA, jsB); // false if an exception is thrown
- if (exec->hadException()) {
- if (exception)
- *exception = toRef(exec, exec->exception());
- exec->clearException();
- }
+ handleExceptionIfNeeded(exec, exception);
+
return result;
}
@@ -217,7 +257,7 @@ bool JSValueIsStrictEqual(JSContextRef ctx, JSValueRef a, JSValueRef b)
return false;
}
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
+ JSLockHolder locker(exec);
JSValue jsA = toJS(exec, a);
JSValue jsB = toJS(exec, b);
@@ -232,7 +272,7 @@ bool JSValueIsInstanceOfConstructor(JSContextRef ctx, JSValueRef value, JSObject
return false;
}
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
+ JSLockHolder locker(exec);
JSValue jsValue = toJS(exec, value);
@@ -240,11 +280,7 @@ bool JSValueIsInstanceOfConstructor(JSContextRef ctx, JSValueRef value, JSObject
if (!jsConstructor->structure()->typeInfo().implementsHasInstance())
return false;
bool result = jsConstructor->hasInstance(exec, jsValue); // false if an exception is thrown
- if (exec->hadException()) {
- if (exception)
- *exception = toRef(exec, exec->exception());
- exec->clearException();
- }
+ handleExceptionIfNeeded(exec, exception);
return result;
}
@@ -255,7 +291,7 @@ JSValueRef JSValueMakeUndefined(JSContextRef ctx)
return 0;
}
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
+ JSLockHolder locker(exec);
return toRef(exec, jsUndefined());
}
@@ -267,7 +303,7 @@ JSValueRef JSValueMakeNull(JSContextRef ctx)
return 0;
}
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
+ JSLockHolder locker(exec);
return toRef(exec, jsNull());
}
@@ -279,7 +315,7 @@ JSValueRef JSValueMakeBoolean(JSContextRef ctx, bool value)
return 0;
}
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
+ JSLockHolder locker(exec);
return toRef(exec, jsBoolean(value));
}
@@ -291,15 +327,9 @@ JSValueRef JSValueMakeNumber(JSContextRef ctx, double value)
return 0;
}
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
+ JSLockHolder locker(exec);
- // Our JSValue representation relies on a standard bit pattern for NaN. NaNs
- // generated internally to JavaScriptCore naturally have that representation,
- // but an external NaN might not.
- if (std::isnan(value))
- value = QNaN;
-
- return toRef(exec, jsNumber(value));
+ return toRef(exec, jsNumber(purifyNaN(value)));
}
JSValueRef JSValueMakeString(JSContextRef ctx, JSStringRef string)
@@ -309,9 +339,9 @@ JSValueRef JSValueMakeString(JSContextRef ctx, JSStringRef string)
return 0;
}
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
+ JSLockHolder locker(exec);
- return toRef(exec, jsString(exec, string->string()));
+ return toRef(exec, jsString(exec, string ? string->string() : String()));
}
JSValueRef JSValueMakeFromJSONString(JSContextRef ctx, JSStringRef string)
@@ -321,14 +351,14 @@ JSValueRef JSValueMakeFromJSONString(JSContextRef ctx, JSStringRef string)
return 0;
}
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
+ JSLockHolder locker(exec);
String str = string->string();
unsigned length = str.length();
- if (length && str.is8Bit()) {
+ if (!length || str.is8Bit()) {
LiteralParser<LChar> parser(exec, str.characters8(), length, StrictJSON);
return toRef(exec, parser.tryLiteralParse());
}
- LiteralParser<UChar> parser(exec, str.characters(), length, StrictJSON);
+ LiteralParser<UChar> parser(exec, str.characters16(), length, StrictJSON);
return toRef(exec, parser.tryLiteralParse());
}
@@ -339,17 +369,13 @@ JSStringRef JSValueCreateJSONString(JSContextRef ctx, JSValueRef apiValue, unsig
return 0;
}
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
+ JSLockHolder locker(exec);
JSValue value = toJS(exec, apiValue);
String result = JSONStringify(exec, value, indent);
if (exception)
*exception = 0;
- if (exec->hadException()) {
- if (exception)
- *exception = toRef(exec, exec->exception());
- exec->clearException();
+ if (handleExceptionIfNeeded(exec, exception) == ExceptionStatus::DidThrow)
return 0;
- }
return OpaqueJSString::create(result).leakRef();
}
@@ -360,7 +386,7 @@ bool JSValueToBoolean(JSContextRef ctx, JSValueRef value)
return false;
}
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
+ JSLockHolder locker(exec);
JSValue jsValue = toJS(exec, value);
return jsValue.toBoolean(exec);
@@ -370,20 +396,16 @@ double JSValueToNumber(JSContextRef ctx, JSValueRef value, JSValueRef* exception
{
if (!ctx) {
ASSERT_NOT_REACHED();
- return QNaN;
+ return PNaN;
}
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
+ JSLockHolder locker(exec);
JSValue jsValue = toJS(exec, value);
double number = jsValue.toNumber(exec);
- if (exec->hadException()) {
- if (exception)
- *exception = toRef(exec, exec->exception());
- exec->clearException();
- number = QNaN;
- }
+ if (handleExceptionIfNeeded(exec, exception) == ExceptionStatus::DidThrow)
+ number = PNaN;
return number;
}
@@ -394,17 +416,13 @@ JSStringRef JSValueToStringCopy(JSContextRef ctx, JSValueRef value, JSValueRef*
return 0;
}
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
+ JSLockHolder locker(exec);
JSValue jsValue = toJS(exec, value);
RefPtr<OpaqueJSString> stringRef(OpaqueJSString::create(jsValue.toString(exec)->value(exec)));
- if (exec->hadException()) {
- if (exception)
- *exception = toRef(exec, exec->exception());
- exec->clearException();
- stringRef.clear();
- }
+ if (handleExceptionIfNeeded(exec, exception) == ExceptionStatus::DidThrow)
+ stringRef = nullptr;
return stringRef.release().leakRef();
}
@@ -415,19 +433,15 @@ JSObjectRef JSValueToObject(JSContextRef ctx, JSValueRef value, JSValueRef* exce
return 0;
}
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
+ JSLockHolder locker(exec);
JSValue jsValue = toJS(exec, value);
JSObjectRef objectRef = toRef(jsValue.toObject(exec));
- if (exec->hadException()) {
- if (exception)
- *exception = toRef(exec, exec->exception());
- exec->clearException();
+ if (handleExceptionIfNeeded(exec, exception) == ExceptionStatus::DidThrow)
objectRef = 0;
- }
return objectRef;
-}
+}
void JSValueProtect(JSContextRef ctx, JSValueRef value)
{
@@ -436,7 +450,7 @@ void JSValueProtect(JSContextRef ctx, JSValueRef value)
return;
}
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
+ JSLockHolder locker(exec);
JSValue jsValue = toJSForGC(exec, value);
gcProtect(jsValue);
@@ -450,7 +464,7 @@ void JSValueUnprotect(JSContextRef ctx, JSValueRef value)
#endif
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
+ JSLockHolder locker(exec);
JSValue jsValue = toJSForGC(exec, value);
gcUnprotect(jsValue);
diff --git a/Source/JavaScriptCore/API/JSValueRef.h b/Source/JavaScriptCore/API/JSValueRef.h
index 125e4028a..9c4fa58cd 100644
--- a/Source/JavaScriptCore/API/JSValueRef.h
+++ b/Source/JavaScriptCore/API/JSValueRef.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
@@ -129,6 +129,24 @@ JS_EXPORT bool JSValueIsObject(JSContextRef ctx, JSValueRef value);
*/
JS_EXPORT bool JSValueIsObjectOfClass(JSContextRef ctx, JSValueRef value, JSClassRef jsClass);
+/*!
+@function
+@abstract Tests whether a JavaScript value is an array.
+@param ctx The execution context to use.
+@param value The JSValue to test.
+@result true if value is an array, otherwise false.
+*/
+JS_EXPORT bool JSValueIsArray(JSContextRef ctx, JSValueRef value) CF_AVAILABLE(10_11, 9_0);
+
+/*!
+@function
+@abstract Tests whether a JavaScript value is a date.
+@param ctx The execution context to use.
+@param value The JSValue to test.
+@result true if value is a date, otherwise false.
+*/
+JS_EXPORT bool JSValueIsDate(JSContextRef ctx, JSValueRef value) CF_AVAILABLE(10_11, 9_0);
+
/* Comparing values */
/*!
@@ -218,7 +236,7 @@ JS_EXPORT JSValueRef JSValueMakeString(JSContextRef ctx, JSStringRef string);
@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;
+JS_EXPORT JSValueRef JSValueMakeFromJSONString(JSContextRef ctx, JSStringRef string) CF_AVAILABLE(10_7, 7_0);
/*!
@function
@@ -229,7 +247,7 @@ JS_EXPORT JSValueRef JSValueMakeFromJSONString(JSContextRef ctx, JSStringRef str
@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;
+JS_EXPORT JSStringRef JSValueCreateJSONString(JSContextRef ctx, JSValueRef value, unsigned indent, JSValueRef* exception) CF_AVAILABLE(10_7, 7_0);
/* Converting to primitive values */
diff --git a/Source/JavaScriptCore/API/JSVirtualMachine.h b/Source/JavaScriptCore/API/JSVirtualMachine.h
index b50616f4c..ccf9264d5 100644
--- a/Source/JavaScriptCore/API/JSVirtualMachine.h
+++ b/Source/JavaScriptCore/API/JSVirtualMachine.h
@@ -27,30 +27,54 @@
#if JSC_OBJC_API_ENABLED
-// An instance of JSVirtualMachine represents a single JavaScript "object space"
-// or set of execution resources. Thread safety is supported by locking the
-// virtual machine, with concurrent JavaScript execution supported by allocating
-// separate instances of JSVirtualMachine.
-
-NS_CLASS_AVAILABLE(10_9, NA)
+/*!
+@interface
+@discussion An instance of JSVirtualMachine represents a single JavaScript "object space"
+ or set of execution resources. Thread safety is supported by locking the
+ virtual machine, with concurrent JavaScript execution supported by allocating
+ separate instances of JSVirtualMachine.
+*/
+NS_CLASS_AVAILABLE(10_9, 7_0)
@interface JSVirtualMachine : NSObject
-// Create a new JSVirtualMachine.
-- (id)init;
-
-// addManagedReference:withOwner and removeManagedReference:withOwner allow
-// clients of JSVirtualMachine to make the JavaScript runtime aware of
-// arbitrary external Objective-C object graphs. The runtime can then use
-// this information to retain any JavaScript values that are referenced
-// from somewhere in said object graph.
-//
-// For correct behavior clients must make their external object graphs
-// reachable from within the JavaScript runtime. If an Objective-C object is
-// reachable from within the JavaScript runtime, all managed references
-// transitively reachable from it as recorded with
-// addManagedReference:withOwner: will be scanned by the garbage collector.
-//
+/*!
+@methodgroup Creating New Virtual Machines
+*/
+/*!
+@method
+@abstract Create a new JSVirtualMachine.
+*/
+- (instancetype)init;
+
+/*!
+@methodgroup Memory Management
+*/
+/*!
+@method
+@abstract Notify the JSVirtualMachine of an external object relationship.
+@discussion Allows clients of JSVirtualMachine to make the JavaScript runtime aware of
+ arbitrary external Objective-C object graphs. The runtime can then use
+ this information to retain any JavaScript values that are referenced
+ from somewhere in said object graph.
+
+ For correct behavior clients must make their external object graphs
+ reachable from within the JavaScript runtime. If an Objective-C object is
+ reachable from within the JavaScript runtime, all managed references
+ transitively reachable from it as recorded using
+ -addManagedReference:withOwner: will be scanned by the garbage collector.
+@param object The object that the owner points to.
+@param owner The object that owns the pointed to object.
+*/
- (void)addManagedReference:(id)object withOwner:(id)owner;
+
+/*!
+@method
+@abstract Notify the JSVirtualMachine that a previous object relationship no longer exists.
+@discussion The JavaScript runtime will continue to scan any references that were
+ reported to it by -addManagedReference:withOwner: until those references are removed.
+@param object The object that was formerly owned.
+@param owner The former owner.
+*/
- (void)removeManagedReference:(id)object withOwner:(id)owner;
@end
diff --git a/Source/JavaScriptCore/API/JSVirtualMachine.mm b/Source/JavaScriptCore/API/JSVirtualMachine.mm
deleted file mode 100644
index 6bada34a6..000000000
--- a/Source/JavaScriptCore/API/JSVirtualMachine.mm
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * Copyright (C) 2013 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. ``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
- * 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"
-
-#import "JavaScriptCore.h"
-
-#if JSC_OBJC_API_ENABLED
-
-#import "APICast.h"
-#import "APIShims.h"
-#import "JSVirtualMachine.h"
-#import "JSVirtualMachineInternal.h"
-#import "JSWrapperMap.h"
-
-static NSMapTable *globalWrapperCache = 0;
-
-static Mutex& wrapperCacheLock()
-{
- DEFINE_STATIC_LOCAL(Mutex, mutex, ());
- return mutex;
-}
-
-static void initWrapperCache()
-{
- ASSERT(!globalWrapperCache);
- NSPointerFunctionsOptions keyOptions = NSPointerFunctionsOpaqueMemory | NSPointerFunctionsOpaquePersonality;
- NSPointerFunctionsOptions valueOptions = NSPointerFunctionsWeakMemory | NSPointerFunctionsObjectPersonality;
- globalWrapperCache = [[NSMapTable alloc] initWithKeyOptions:keyOptions valueOptions:valueOptions capacity:0];
-}
-
-static NSMapTable *wrapperCache()
-{
- if (!globalWrapperCache)
- initWrapperCache();
- return globalWrapperCache;
-}
-
-@interface JSVMWrapperCache : NSObject
-+ (void)addWrapper:(JSVirtualMachine *)wrapper forJSContextGroupRef:(JSContextGroupRef)group;
-+ (JSVirtualMachine *)wrapperForJSContextGroupRef:(JSContextGroupRef)group;
-@end
-
-@implementation JSVMWrapperCache
-
-+ (void)addWrapper:(JSVirtualMachine *)wrapper forJSContextGroupRef:(JSContextGroupRef)group
-{
- MutexLocker locker(wrapperCacheLock());
- NSMapInsert(wrapperCache(), group, wrapper);
-}
-
-+ (JSVirtualMachine *)wrapperForJSContextGroupRef:(JSContextGroupRef)group
-{
- MutexLocker locker(wrapperCacheLock());
- return static_cast<JSVirtualMachine *>(NSMapGet(wrapperCache(), group));
-}
-
-@end
-
-@implementation JSVirtualMachine {
- JSContextGroupRef m_group;
- NSMapTable *m_contextCache;
- NSMapTable *m_externalObjectGraph;
-}
-
-- (id)init
-{
- JSContextGroupRef group = JSContextGroupCreate();
- self = [self initWithContextGroupRef:group];
- // The extra JSContextGroupRetain is balanced here.
- JSContextGroupRelease(group);
- return self;
-}
-
-- (id)initWithContextGroupRef:(JSContextGroupRef)group
-{
- self = [super init];
- if (!self)
- return nil;
-
- m_group = JSContextGroupRetain(group);
-
- NSPointerFunctionsOptions keyOptions = NSPointerFunctionsOpaqueMemory | NSPointerFunctionsOpaquePersonality;
- NSPointerFunctionsOptions valueOptions = NSPointerFunctionsWeakMemory | NSPointerFunctionsObjectPersonality;
- m_contextCache = [[NSMapTable alloc] initWithKeyOptions:keyOptions valueOptions:valueOptions capacity:0];
-
- NSPointerFunctionsOptions weakIDOptions = NSPointerFunctionsWeakMemory | NSPointerFunctionsObjectPersonality;
- NSPointerFunctionsOptions strongIDOptions = NSPointerFunctionsStrongMemory | NSPointerFunctionsObjectPersonality;
- m_externalObjectGraph = [[NSMapTable alloc] initWithKeyOptions:weakIDOptions valueOptions:strongIDOptions capacity:0];
-
- [JSVMWrapperCache addWrapper:self forJSContextGroupRef:group];
-
- return self;
-}
-
-- (void)dealloc
-{
- JSContextGroupRelease(m_group);
- [m_contextCache release];
- [m_externalObjectGraph release];
- [super dealloc];
-}
-
-static id getInternalObjcObject(id object)
-{
- if ([object isKindOfClass:[JSManagedValue class]]) {
- JSValue* value = [static_cast<JSManagedValue *>(object) value];
- id temp = tryUnwrapObjcObject([value.context JSGlobalContextRef], [value JSValueRef]);
- if (temp)
- return temp;
- return object;
- }
-
- if ([object isKindOfClass:[JSValue class]]) {
- JSValue *value = static_cast<JSValue *>(object);
- object = tryUnwrapObjcObject([value.context JSGlobalContextRef], [value JSValueRef]);
- }
-
- return object;
-}
-
-- (void)addManagedReference:(id)object withOwner:(id)owner
-{
- object = getInternalObjcObject(object);
- owner = getInternalObjcObject(owner);
-
- if (!object || !owner)
- return;
-
- JSC::APIEntryShim shim(toJS(m_group));
-
- NSMapTable *ownedObjects = [m_externalObjectGraph objectForKey:owner];
- if (!ownedObjects) {
- NSPointerFunctionsOptions weakIDOptions = NSPointerFunctionsWeakMemory | NSPointerFunctionsObjectPersonality;
- NSPointerFunctionsOptions integerOptions = NSPointerFunctionsOpaqueMemory | NSPointerFunctionsIntegerPersonality;
- ownedObjects = [[NSMapTable alloc] initWithKeyOptions:weakIDOptions valueOptions:integerOptions capacity:1];
-
- [m_externalObjectGraph setObject:ownedObjects forKey:owner];
- [ownedObjects release];
- }
- NSMapInsert(ownedObjects, object, reinterpret_cast<void*>(reinterpret_cast<size_t>(NSMapGet(ownedObjects, object)) + 1));
-}
-
-- (void)removeManagedReference:(id)object withOwner:(id)owner
-{
- object = getInternalObjcObject(object);
- owner = getInternalObjcObject(owner);
-
- if (!object || !owner)
- return;
-
- JSC::APIEntryShim shim(toJS(m_group));
-
- NSMapTable *ownedObjects = [m_externalObjectGraph objectForKey:owner];
- if (!ownedObjects)
- return;
-
- size_t count = reinterpret_cast<size_t>(NSMapGet(ownedObjects, object));
- if (count > 1) {
- NSMapInsert(ownedObjects, object, reinterpret_cast<void*>(count - 1));
- return;
- }
-
- if (count == 1)
- NSMapRemove(ownedObjects, object);
-
- if (![ownedObjects count])
- [m_externalObjectGraph removeObjectForKey:owner];
-}
-
-@end
-
-@implementation JSVirtualMachine(Internal)
-
-JSContextGroupRef getGroupFromVirtualMachine(JSVirtualMachine *virtualMachine)
-{
- return virtualMachine->m_group;
-}
-
-+ (JSVirtualMachine *)virtualMachineWithContextGroupRef:(JSContextGroupRef)group
-{
- JSVirtualMachine *virtualMachine = [JSVMWrapperCache wrapperForJSContextGroupRef:group];
- if (!virtualMachine)
- virtualMachine = [[[JSVirtualMachine alloc] initWithContextGroupRef:group] autorelease];
- return virtualMachine;
-}
-
-- (JSContext *)contextForGlobalContextRef:(JSGlobalContextRef)globalContext
-{
- return static_cast<JSContext *>(NSMapGet(m_contextCache, globalContext));
-}
-
-- (void)addContext:(JSContext *)wrapper forGlobalContextRef:(JSGlobalContextRef)globalContext
-{
- NSMapInsert(m_contextCache, globalContext, wrapper);
-}
-
-- (NSMapTable *)externalObjectGraph
-{
- return m_externalObjectGraph;
-}
-
-@end
-
-void scanExternalObjectGraph(JSC::VM& vm, JSC::SlotVisitor& visitor, void* root)
-{
- @autoreleasepool {
- JSVirtualMachine *virtualMachine = [JSVMWrapperCache wrapperForJSContextGroupRef:toRef(&vm)];
- if (!virtualMachine)
- return;
- NSMapTable *externalObjectGraph = [virtualMachine externalObjectGraph];
- Vector<void*> stack;
- stack.append(root);
- while (!stack.isEmpty()) {
- void* nextRoot = stack.last();
- stack.removeLast();
- if (visitor.containsOpaqueRootTriState(nextRoot) == TrueTriState)
- continue;
- visitor.addOpaqueRoot(nextRoot);
-
- NSMapTable *ownedObjects = [externalObjectGraph objectForKey:static_cast<id>(nextRoot)];
- id ownedObject;
- NSEnumerator *enumerator = [ownedObjects keyEnumerator];
- while ((ownedObject = [enumerator nextObject])) {
- ASSERT(reinterpret_cast<size_t>(NSMapGet(ownedObjects, ownedObject)) == 1);
- stack.append(static_cast<void*>(ownedObject));
- }
- }
- }
-}
-
-#endif
-
diff --git a/Source/JavaScriptCore/API/JSVirtualMachineInternal.h b/Source/JavaScriptCore/API/JSVirtualMachineInternal.h
index 729226566..5a4fbefa5 100644
--- a/Source/JavaScriptCore/API/JSVirtualMachineInternal.h
+++ b/Source/JavaScriptCore/API/JSVirtualMachineInternal.h
@@ -26,16 +26,18 @@
#ifndef JSVirtualMachineInternal_h
#define JSVirtualMachineInternal_h
-#import <JavaScriptCore/JavaScriptCore.h>
-
#if JSC_OBJC_API_ENABLED
+#import <JavaScriptCore/JavaScriptCore.h>
+
namespace JSC {
class VM;
class SlotVisitor;
}
#if defined(__OBJC__)
+@class NSMapTable;
+
@interface JSVirtualMachine(Internal)
JSContextGroupRef getGroupFromVirtualMachine(JSVirtualMachine *);
@@ -51,7 +53,8 @@ JSContextGroupRef getGroupFromVirtualMachine(JSVirtualMachine *);
#endif // defined(__OBJC__)
void scanExternalObjectGraph(JSC::VM&, JSC::SlotVisitor&, void* root);
+void scanExternalRememberedSet(JSC::VM&, JSC::SlotVisitor&);
-#endif
+#endif // JSC_OBJC_API_ENABLED
#endif // JSVirtualMachineInternal_h
diff --git a/Source/JavaScriptCore/API/JSWeakObjectMapRefInternal.h b/Source/JavaScriptCore/API/JSWeakObjectMapRefInternal.h
index f7b91da51..9037947d7 100644
--- a/Source/JavaScriptCore/API/JSWeakObjectMapRefInternal.h
+++ b/Source/JavaScriptCore/API/JSWeakObjectMapRefInternal.h
@@ -41,9 +41,9 @@ typedef JSC::WeakGCMap<void*, JSC::JSObject> WeakMapType;
struct OpaqueJSWeakObjectMap : public RefCounted<OpaqueJSWeakObjectMap> {
public:
- static PassRefPtr<OpaqueJSWeakObjectMap> create(void* data, JSWeakMapDestroyedCallback callback)
+ static Ref<OpaqueJSWeakObjectMap> create(JSC::VM& vm, void* data, JSWeakMapDestroyedCallback callback)
{
- return adoptRef(new OpaqueJSWeakObjectMap(data, callback));
+ return adoptRef(*new OpaqueJSWeakObjectMap(vm, data, callback));
}
WeakMapType& map() { return m_map; }
@@ -54,8 +54,9 @@ public:
}
private:
- OpaqueJSWeakObjectMap(void* data, JSWeakMapDestroyedCallback callback)
- : m_data(data)
+ OpaqueJSWeakObjectMap(JSC::VM& vm, void* data, JSWeakMapDestroyedCallback callback)
+ : m_map(vm)
+ , m_data(data)
, m_callback(callback)
{
}
diff --git a/Source/JavaScriptCore/API/JSWeakObjectMapRefPrivate.cpp b/Source/JavaScriptCore/API/JSWeakObjectMapRefPrivate.cpp
index 8cbe263a7..925c00f0b 100644
--- a/Source/JavaScriptCore/API/JSWeakObjectMapRefPrivate.cpp
+++ b/Source/JavaScriptCore/API/JSWeakObjectMapRefPrivate.cpp
@@ -27,12 +27,12 @@
#include "JSWeakObjectMapRefPrivate.h"
#include "APICast.h"
-#include "APIShims.h"
#include "JSCJSValue.h"
#include "JSCallbackObject.h"
#include "JSWeakObjectMapRefInternal.h"
-#include "Operations.h"
+#include "JSCInlines.h"
#include "Weak.h"
+#include "WeakGCMapInlines.h"
#include <wtf/HashMap.h>
#include <wtf/text/StringHash.h>
@@ -46,8 +46,8 @@ extern "C" {
JSWeakObjectMapRef JSWeakObjectMapCreate(JSContextRef context, void* privateData, JSWeakMapDestroyedCallback callback)
{
ExecState* exec = toJS(context);
- APIEntryShim entryShim(exec);
- RefPtr<OpaqueJSWeakObjectMap> map = OpaqueJSWeakObjectMap::create(privateData, callback);
+ JSLockHolder locker(exec);
+ RefPtr<OpaqueJSWeakObjectMap> map = OpaqueJSWeakObjectMap::create(exec->vm(), privateData, callback);
exec->lexicalGlobalObject()->registerWeakMap(map.get());
return map.get();
}
@@ -59,11 +59,13 @@ void JSWeakObjectMapSet(JSContextRef ctx, JSWeakObjectMapRef map, void* key, JSO
return;
}
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
+ JSLockHolder locker(exec);
JSObject* obj = toJS(object);
if (!obj)
return;
- ASSERT(obj->inherits(&JSCallbackObject<JSGlobalObject>::s_info) || obj->inherits(&JSCallbackObject<JSDestructibleObject>::s_info));
+ ASSERT(obj->inherits(JSProxy::info())
+ || obj->inherits(JSCallbackObject<JSGlobalObject>::info())
+ || obj->inherits(JSCallbackObject<JSDestructibleObject>::info()));
map->map().set(key, obj);
}
@@ -74,7 +76,7 @@ JSObjectRef JSWeakObjectMapGet(JSContextRef ctx, JSWeakObjectMapRef map, void* k
return 0;
}
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
+ JSLockHolder locker(exec);
return toRef(jsCast<JSObject*>(map->map().get(key)));
}
@@ -85,7 +87,7 @@ void JSWeakObjectMapRemove(JSContextRef ctx, JSWeakObjectMapRef map, void* key)
return;
}
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
+ JSLockHolder locker(exec);
map->map().remove(key);
}
diff --git a/Source/JavaScriptCore/API/JSWrapperMap.h b/Source/JavaScriptCore/API/JSWrapperMap.h
index ce74a9c61..c6aa1af13 100644
--- a/Source/JavaScriptCore/API/JSWrapperMap.h
+++ b/Source/JavaScriptCore/API/JSWrapperMap.h
@@ -41,6 +41,7 @@
id tryUnwrapObjcObject(JSGlobalContextRef, JSValueRef);
+bool supportsInitMethodConstructors();
Protocol *getJSExportProtocol();
Class getNSBlockClass();
diff --git a/Source/JavaScriptCore/API/JSWrapperMap.mm b/Source/JavaScriptCore/API/JSWrapperMap.mm
deleted file mode 100644
index 4dde1a659..000000000
--- a/Source/JavaScriptCore/API/JSWrapperMap.mm
+++ /dev/null
@@ -1,521 +0,0 @@
-/*
- * Copyright (C) 2013 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. ``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
- * 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"
-#import "JavaScriptCore.h"
-
-#if JSC_OBJC_API_ENABLED
-
-#import "APICast.h"
-#import "APIShims.h"
-#import "JSAPIWrapperObject.h"
-#import "JSCallbackObject.h"
-#import "JSContextInternal.h"
-#import "JSWrapperMap.h"
-#import "ObjCCallbackFunction.h"
-#import "ObjcRuntimeExtras.h"
-#import "Operations.h"
-#import "WeakGCMap.h"
-#import <wtf/TCSpinLock.h>
-#import <wtf/Vector.h>
-
-@class JSObjCClassInfo;
-
-@interface JSWrapperMap ()
-
-- (JSObjCClassInfo*)classInfoForClass:(Class)cls;
-
-@end
-
-// Default conversion of selectors to property names.
-// All semicolons are removed, lowercase letters following a semicolon are capitalized.
-static NSString *selectorToPropertyName(const char* start)
-{
- // Use 'index' to check for colons, if there are none, this is easy!
- const char* firstColon = index(start, ':');
- if (!firstColon)
- return [NSString stringWithUTF8String:start];
-
- // 'header' is the length of string up to the first colon.
- size_t header = firstColon - start;
- // The new string needs to be long enough to hold 'header', plus the remainder of the string, excluding
- // at least one ':', but including a '\0'. (This is conservative if there are more than one ':').
- char* buffer = static_cast<char*>(malloc(header + strlen(firstColon + 1) + 1));
- // Copy 'header' characters, set output to point to the end of this & input to point past the first ':'.
- memcpy(buffer, start, header);
- char* output = buffer + header;
- const char* input = start + header + 1;
-
- // On entry to the loop, we have already skipped over a ':' from the input.
- while (true) {
- char c;
- // Skip over any additional ':'s. We'll leave c holding the next character after the
- // last ':', and input pointing past c.
- while ((c = *(input++)) == ':');
- // Copy the character, converting to upper case if necessary.
- // If the character we copy is '\0', then we're done!
- if (!(*(output++) = toupper(c)))
- goto done;
- // Loop over characters other than ':'.
- while ((c = *(input++)) != ':') {
- // Copy the character.
- // If the character we copy is '\0', then we're done!
- if (!(*(output++) = c))
- goto done;
- }
- // If we get here, we've consumed a ':' - wash, rinse, repeat.
- }
-done:
- NSString *result = [NSString stringWithUTF8String:buffer];
- free(buffer);
- return result;
-}
-
-static JSObjectRef makeWrapper(JSContextRef ctx, JSClassRef jsClass, id wrappedObject)
-{
- JSC::ExecState* exec = toJS(ctx);
- JSC::APIEntryShim entryShim(exec);
-
- ASSERT(jsClass);
- JSC::JSCallbackObject<JSC::JSAPIWrapperObject>* object = JSC::JSCallbackObject<JSC::JSAPIWrapperObject>::create(exec, exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->objcWrapperObjectStructure(), jsClass, 0);
- object->setWrappedObject(wrappedObject);
- if (JSC::JSObject* prototype = jsClass->prototype(exec))
- object->setPrototype(exec->vm(), prototype);
-
- return toRef(object);
-}
-
-// Make an object that is in all ways a completely vanilla JavaScript object,
-// other than that it has a native brand set that will be displayed by the default
-// Object.prototype.toString conversion.
-static JSValue *objectWithCustomBrand(JSContext *context, NSString *brand, Class cls = 0)
-{
- JSClassDefinition definition;
- definition = kJSClassDefinitionEmpty;
- definition.className = [brand UTF8String];
- JSClassRef classRef = JSClassCreate(&definition);
- JSObjectRef result = makeWrapper([context JSGlobalContextRef], classRef, cls);
- JSClassRelease(classRef);
- return [JSValue valueWithJSValueRef:result inContext:context];
-}
-
-// Look for @optional properties in the prototype containing a selector to property
-// name mapping, separated by a __JS_EXPORT_AS__ delimiter.
-static NSMutableDictionary *createRenameMap(Protocol *protocol, BOOL isInstanceMethod)
-{
- NSMutableDictionary *renameMap = [[NSMutableDictionary alloc] init];
-
- forEachMethodInProtocol(protocol, NO, isInstanceMethod, ^(SEL sel, const char*){
- NSString *rename = @(sel_getName(sel));
- NSRange range = [rename rangeOfString:@"__JS_EXPORT_AS__"];
- if (range.location == NSNotFound)
- return;
- NSString *selector = [rename substringToIndex:range.location];
- NSUInteger begin = range.location + range.length;
- NSUInteger length = [rename length] - begin - 1;
- NSString *name = [rename substringWithRange:(NSRange){ begin, length }];
- renameMap[selector] = name;
- });
-
- return renameMap;
-}
-
-inline void putNonEnumerable(JSValue *base, NSString *propertyName, JSValue *value)
-{
- [base defineProperty:propertyName descriptor:@{
- JSPropertyDescriptorValueKey: value,
- JSPropertyDescriptorWritableKey: @YES,
- JSPropertyDescriptorEnumerableKey: @NO,
- JSPropertyDescriptorConfigurableKey: @YES
- }];
-}
-
-// This method will iterate over the set of required methods in the protocol, and:
-// * Determine a property name (either via a renameMap or default conversion).
-// * If an accessorMap is provided, and contains this name, store the method in the map.
-// * Otherwise, if the object doesn't already contain a property with name, create it.
-static void copyMethodsToObject(JSContext *context, Class objcClass, Protocol *protocol, BOOL isInstanceMethod, JSValue *object, NSMutableDictionary *accessorMethods = nil)
-{
- NSMutableDictionary *renameMap = createRenameMap(protocol, isInstanceMethod);
-
- forEachMethodInProtocol(protocol, YES, isInstanceMethod, ^(SEL sel, const char* types){
- const char* nameCStr = sel_getName(sel);
- NSString *name = @(nameCStr);
- if (accessorMethods && accessorMethods[name]) {
- JSObjectRef method = objCCallbackFunctionForMethod(context, objcClass, protocol, isInstanceMethod, sel, types);
- if (!method)
- return;
- accessorMethods[name] = [JSValue valueWithJSValueRef:method inContext:context];
- } else {
- name = renameMap[name];
- if (!name)
- name = selectorToPropertyName(nameCStr);
- if ([object hasProperty:name])
- return;
- JSObjectRef method = objCCallbackFunctionForMethod(context, objcClass, protocol, isInstanceMethod, sel, types);
- if (method)
- putNonEnumerable(object, name, [JSValue valueWithJSValueRef:method inContext:context]);
- }
- });
-
- [renameMap release];
-}
-
-static bool parsePropertyAttributes(objc_property_t property, char*& getterName, char*& setterName)
-{
- bool readonly = false;
- unsigned attributeCount;
- objc_property_attribute_t* attributes = property_copyAttributeList(property, &attributeCount);
- if (attributeCount) {
- for (unsigned i = 0; i < attributeCount; ++i) {
- switch (*(attributes[i].name)) {
- case 'G':
- getterName = strdup(attributes[i].value);
- break;
- case 'S':
- setterName = strdup(attributes[i].value);
- break;
- case 'R':
- readonly = true;
- break;
- default:
- break;
- }
- }
- free(attributes);
- }
- return readonly;
-}
-
-static char* makeSetterName(const char* name)
-{
- size_t nameLength = strlen(name);
- char* setterName = (char*)malloc(nameLength + 5); // "set" Name ":\0"
- setterName[0] = 's';
- setterName[1] = 'e';
- setterName[2] = 't';
- setterName[3] = toupper(*name);
- memcpy(setterName + 4, name + 1, nameLength - 1);
- setterName[nameLength + 3] = ':';
- setterName[nameLength + 4] = '\0';
- return setterName;
-}
-
-static void copyPrototypeProperties(JSContext *context, Class objcClass, Protocol *protocol, JSValue *prototypeValue)
-{
- // First gather propreties into this list, then handle the methods (capturing the accessor methods).
- struct Property {
- const char* name;
- char* getterName;
- char* setterName;
- };
- __block Vector<Property> propertyList;
-
- // Map recording the methods used as getters/setters.
- NSMutableDictionary *accessorMethods = [NSMutableDictionary dictionary];
-
- // Useful value.
- JSValue *undefined = [JSValue valueWithUndefinedInContext:context];
-
- forEachPropertyInProtocol(protocol, ^(objc_property_t property){
- char* getterName = 0;
- char* setterName = 0;
- bool readonly = parsePropertyAttributes(property, getterName, setterName);
- const char* name = property_getName(property);
-
- // Add the names of the getter & setter methods to
- if (!getterName)
- getterName = strdup(name);
- accessorMethods[@(getterName)] = undefined;
- if (!readonly) {
- if (!setterName)
- setterName = makeSetterName(name);
- accessorMethods[@(setterName)] = undefined;
- }
-
- // Add the properties to a list.
- propertyList.append((Property){ name, getterName, setterName });
- });
-
- // Copy methods to the prototype, capturing accessors in the accessorMethods map.
- copyMethodsToObject(context, objcClass, protocol, YES, prototypeValue, accessorMethods);
-
- // Iterate the propertyList & generate accessor properties.
- for (size_t i = 0; i < propertyList.size(); ++i) {
- Property& property = propertyList[i];
-
- JSValue *getter = accessorMethods[@(property.getterName)];
- free(property.getterName);
- ASSERT(![getter isUndefined]);
-
- JSValue *setter = undefined;
- if (property.setterName) {
- setter = accessorMethods[@(property.setterName)];
- free(property.setterName);
- ASSERT(![setter isUndefined]);
- }
-
- [prototypeValue defineProperty:@(property.name) descriptor:@{
- JSPropertyDescriptorGetKey: getter,
- JSPropertyDescriptorSetKey: setter,
- JSPropertyDescriptorEnumerableKey: @NO,
- JSPropertyDescriptorConfigurableKey: @YES
- }];
- }
-}
-
-@interface JSObjCClassInfo : NSObject {
- JSContext *m_context;
- Class m_class;
- bool m_block;
- JSClassRef m_classRef;
- JSC::Weak<JSC::JSObject> m_prototype;
- JSC::Weak<JSC::JSObject> m_constructor;
-}
-
-- (id)initWithContext:(JSContext *)context forClass:(Class)cls superClassInfo:(JSObjCClassInfo*)superClassInfo;
-- (JSValue *)wrapperForObject:(id)object;
-- (JSValue *)constructor;
-
-@end
-
-@implementation JSObjCClassInfo
-
-- (id)initWithContext:(JSContext *)context forClass:(Class)cls superClassInfo:(JSObjCClassInfo*)superClassInfo
-{
- self = [super init];
- if (!self)
- return nil;
-
- const char* className = class_getName(cls);
- m_context = context;
- m_class = cls;
- m_block = [cls isSubclassOfClass:getNSBlockClass()];
- JSClassDefinition definition;
- definition = kJSClassDefinitionEmpty;
- definition.className = className;
- m_classRef = JSClassCreate(&definition);
-
- [self allocateConstructorAndPrototypeWithSuperClassInfo:superClassInfo];
-
- return self;
-}
-
-- (void)dealloc
-{
- JSClassRelease(m_classRef);
- [super dealloc];
-}
-
-- (void)allocateConstructorAndPrototypeWithSuperClassInfo:(JSObjCClassInfo*)superClassInfo
-{
- ASSERT(!m_constructor || !m_prototype);
- ASSERT((m_class == [NSObject class]) == !superClassInfo);
- if (!superClassInfo) {
- JSContextRef cContext = [m_context JSGlobalContextRef];
- JSValue *constructor = m_context[@"Object"];
- if (!m_constructor)
- m_constructor = toJS(JSValueToObject(cContext, valueInternalValue(constructor), 0));
-
- if (!m_prototype) {
- JSValue *prototype = constructor[@"prototype"];
- m_prototype = toJS(JSValueToObject(cContext, valueInternalValue(prototype), 0));
- }
- } else {
- const char* className = class_getName(m_class);
-
- // Create or grab the prototype/constructor pair.
- JSValue *prototype;
- JSValue *constructor;
- if (m_prototype)
- prototype = [JSValue valueWithJSValueRef:toRef(m_prototype.get()) inContext:m_context];
- else
- prototype = objectWithCustomBrand(m_context, [NSString stringWithFormat:@"%sPrototype", className]);
-
- if (m_constructor)
- constructor = [JSValue valueWithJSValueRef:toRef(m_constructor.get()) inContext:m_context];
- else
- constructor = objectWithCustomBrand(m_context, [NSString stringWithFormat:@"%sConstructor", className], m_class);
-
- JSContextRef cContext = [m_context JSGlobalContextRef];
- m_prototype = toJS(JSValueToObject(cContext, valueInternalValue(prototype), 0));
- m_constructor = toJS(JSValueToObject(cContext, valueInternalValue(constructor), 0));
-
- putNonEnumerable(prototype, @"constructor", constructor);
- putNonEnumerable(constructor, @"prototype", prototype);
-
- Protocol *exportProtocol = getJSExportProtocol();
- forEachProtocolImplementingProtocol(m_class, exportProtocol, ^(Protocol *protocol){
- copyPrototypeProperties(m_context, m_class, protocol, prototype);
- copyMethodsToObject(m_context, m_class, protocol, NO, constructor);
- });
-
- // Set [Prototype].
- JSObjectSetPrototype([m_context JSGlobalContextRef], toRef(m_prototype.get()), toRef(superClassInfo->m_prototype.get()));
- }
-}
-
-- (void)reallocateConstructorAndOrPrototype
-{
- [self allocateConstructorAndPrototypeWithSuperClassInfo:[m_context.wrapperMap classInfoForClass:class_getSuperclass(m_class)]];
-}
-
-- (JSValue *)wrapperForObject:(id)object
-{
- ASSERT([object isKindOfClass:m_class]);
- ASSERT(m_block == [object isKindOfClass:getNSBlockClass()]);
- if (m_block) {
- if (JSObjectRef method = objCCallbackFunctionForBlock(m_context, object))
- return [JSValue valueWithJSValueRef:method inContext:m_context];
- }
-
- if (!m_prototype)
- [self reallocateConstructorAndOrPrototype];
- ASSERT(!!m_prototype);
-
- JSObjectRef wrapper = makeWrapper([m_context JSGlobalContextRef], m_classRef, object);
- JSObjectSetPrototype([m_context JSGlobalContextRef], wrapper, toRef(m_prototype.get()));
- return [JSValue valueWithJSValueRef:wrapper inContext:m_context];
-}
-
-- (JSValue *)constructor
-{
- if (!m_constructor)
- [self reallocateConstructorAndOrPrototype];
- ASSERT(!!m_constructor);
- return [JSValue valueWithJSValueRef:toRef(m_constructor.get()) inContext:m_context];
-}
-
-@end
-
-@implementation JSWrapperMap {
- JSContext *m_context;
- NSMutableDictionary *m_classMap;
- JSC::WeakGCMap<id, JSC::JSObject> m_cachedJSWrappers;
- NSMapTable *m_cachedObjCWrappers;
-}
-
-- (id)initWithContext:(JSContext *)context
-{
- self = [super init];
- if (!self)
- return nil;
-
- NSPointerFunctionsOptions keyOptions = NSPointerFunctionsOpaqueMemory | NSPointerFunctionsOpaquePersonality;
- NSPointerFunctionsOptions valueOptions = NSPointerFunctionsWeakMemory | NSPointerFunctionsObjectPersonality;
- m_cachedObjCWrappers = [[NSMapTable alloc] initWithKeyOptions:keyOptions valueOptions:valueOptions capacity:0];
-
- m_context = context;
- m_classMap = [[NSMutableDictionary alloc] init];
- return self;
-}
-
-- (void)dealloc
-{
- [m_cachedObjCWrappers release];
- [m_classMap release];
- [super dealloc];
-}
-
-- (JSObjCClassInfo*)classInfoForClass:(Class)cls
-{
- if (!cls)
- return nil;
-
- // Check if we've already created a JSObjCClassInfo for this Class.
- if (JSObjCClassInfo* classInfo = (JSObjCClassInfo*)m_classMap[cls])
- return classInfo;
-
- // Skip internal classes beginning with '_' - just copy link to the parent class's info.
- if ('_' == *class_getName(cls))
- return m_classMap[cls] = [self classInfoForClass:class_getSuperclass(cls)];
-
- return m_classMap[cls] = [[[JSObjCClassInfo alloc] initWithContext:m_context forClass:cls superClassInfo:[self classInfoForClass:class_getSuperclass(cls)]] autorelease];
-}
-
-- (JSValue *)jsWrapperForObject:(id)object
-{
- JSC::JSObject* jsWrapper = m_cachedJSWrappers.get(object);
- if (jsWrapper)
- return [JSValue valueWithJSValueRef:toRef(jsWrapper) inContext:m_context];
-
- JSValue *wrapper;
- if (class_isMetaClass(object_getClass(object)))
- wrapper = [[self classInfoForClass:(Class)object] constructor];
- else {
- JSObjCClassInfo* classInfo = [self classInfoForClass:[object class]];
- wrapper = [classInfo wrapperForObject:object];
- }
-
- // FIXME: https://bugs.webkit.org/show_bug.cgi?id=105891
- // This general approach to wrapper caching is pretty effective, but there are a couple of problems:
- // (1) For immortal objects JSValues will effectively leak and this results in error output being logged - we should avoid adding associated objects to immortal objects.
- // (2) A long lived object may rack up many JSValues. When the contexts are released these will unprotect the associated JavaScript objects,
- // but still, would probably nicer if we made it so that only one associated object was required, broadcasting object dealloc.
- JSC::ExecState* exec = toJS([m_context JSGlobalContextRef]);
- jsWrapper = toJS(exec, valueInternalValue(wrapper)).toObject(exec);
- m_cachedJSWrappers.set(object, jsWrapper);
- return wrapper;
-}
-
-- (JSValue *)objcWrapperForJSValueRef:(JSValueRef)value
-{
- JSValue *wrapper = static_cast<JSValue *>(NSMapGet(m_cachedObjCWrappers, value));
- if (!wrapper) {
- wrapper = [[[JSValue alloc] initWithValue:value inContext:m_context] autorelease];
- NSMapInsert(m_cachedObjCWrappers, value, wrapper);
- }
- return wrapper;
-}
-
-@end
-
-id tryUnwrapObjcObject(JSGlobalContextRef context, JSValueRef value)
-{
- if (!JSValueIsObject(context, value))
- return nil;
- JSValueRef exception = 0;
- JSObjectRef object = JSValueToObject(context, value, &exception);
- ASSERT(!exception);
- if (toJS(object)->inherits(&JSC::JSCallbackObject<JSC::JSAPIWrapperObject>::s_info))
- return (id)JSC::jsCast<JSC::JSAPIWrapperObject*>(toJS(object))->wrappedObject();
- if (id target = tryUnwrapBlock(object))
- return target;
- return nil;
-}
-
-Protocol *getJSExportProtocol()
-{
- static Protocol *protocol = objc_getProtocol("JSExport");
- return protocol;
-}
-
-Class getNSBlockClass()
-{
- static Class cls = objc_getClass("NSBlock");
- return cls;
-}
-
-#endif
diff --git a/Source/JavaScriptCore/API/JavaScript.h b/Source/JavaScriptCore/API/JavaScript.h
index f8d92d8f9..ffe7b83fc 100644
--- a/Source/JavaScriptCore/API/JavaScript.h
+++ b/Source/JavaScriptCore/API/JavaScript.h
@@ -11,10 +11,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
diff --git a/Source/JavaScriptCore/API/JavaScriptCore.h b/Source/JavaScriptCore/API/JavaScriptCore.h
index 40bea9c3d..b2fde1dbe 100644
--- a/Source/JavaScriptCore/API/JavaScriptCore.h
+++ b/Source/JavaScriptCore/API/JavaScriptCore.h
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
diff --git a/Source/JavaScriptCore/API/ObjCCallbackFunction.h b/Source/JavaScriptCore/API/ObjCCallbackFunction.h
index 0218cd8b4..adb167c76 100644
--- a/Source/JavaScriptCore/API/ObjCCallbackFunction.h
+++ b/Source/JavaScriptCore/API/ObjCCallbackFunction.h
@@ -34,36 +34,46 @@
#if defined(__OBJC__)
JSObjectRef objCCallbackFunctionForMethod(JSContext *, Class, Protocol *, BOOL isInstanceMethod, SEL, const char* types);
JSObjectRef objCCallbackFunctionForBlock(JSContext *, id);
+JSObjectRef objCCallbackFunctionForInit(JSContext *, Class, Protocol *, SEL, const char* types);
-id tryUnwrapBlock(JSObjectRef);
+id tryUnwrapConstructor(JSObjectRef);
#endif
namespace JSC {
class ObjCCallbackFunctionImpl;
-class ObjCCallbackFunction : public JSCallbackFunction {
+class ObjCCallbackFunction : public InternalFunction {
+ friend struct APICallbackFunction;
public:
- typedef JSCallbackFunction Base;
+ typedef InternalFunction Base;
- static ObjCCallbackFunction* create(ExecState*, JSGlobalObject*, const String& name, PassOwnPtr<ObjCCallbackFunctionImpl>);
+ static ObjCCallbackFunction* create(VM&, JSGlobalObject*, const String& name, std::unique_ptr<ObjCCallbackFunctionImpl>);
static void destroy(JSCell*);
static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
{
ASSERT(globalObject);
- return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
+ return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
}
- static JS_EXPORTDATA const ClassInfo s_info;
+ DECLARE_EXPORT_INFO;
- ObjCCallbackFunctionImpl* impl() { return m_impl.get(); }
+ ObjCCallbackFunctionImpl* impl() const { return m_impl.get(); }
protected:
- ObjCCallbackFunction(JSGlobalObject*, JSObjectCallAsFunctionCallback, PassOwnPtr<ObjCCallbackFunctionImpl>);
+ ObjCCallbackFunction(VM&, JSGlobalObject*, JSObjectCallAsFunctionCallback, JSObjectCallAsConstructorCallback, std::unique_ptr<ObjCCallbackFunctionImpl>);
private:
- OwnPtr<ObjCCallbackFunctionImpl> m_impl;
+ static CallType getCallData(JSCell*, CallData&);
+ static ConstructType getConstructData(JSCell*, ConstructData&);
+
+ JSObjectCallAsFunctionCallback functionCallback() { return m_functionCallback; }
+ JSObjectCallAsConstructorCallback constructCallback() { return m_constructCallback; }
+
+ JSObjectCallAsFunctionCallback m_functionCallback;
+ JSObjectCallAsConstructorCallback m_constructCallback;
+ std::unique_ptr<ObjCCallbackFunctionImpl> m_impl;
};
} // namespace JSC
diff --git a/Source/JavaScriptCore/API/ObjCCallbackFunction.mm b/Source/JavaScriptCore/API/ObjCCallbackFunction.mm
deleted file mode 100644
index cc342f59e..000000000
--- a/Source/JavaScriptCore/API/ObjCCallbackFunction.mm
+++ /dev/null
@@ -1,615 +0,0 @@
-/*
- * Copyright (C) 2013 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. ``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
- * 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"
-#import "JavaScriptCore.h"
-
-#if JSC_OBJC_API_ENABLED
-
-#import "APICast.h"
-#import "APIShims.h"
-#import "Error.h"
-#import "JSCJSValueInlines.h"
-#import "JSCell.h"
-#import "JSCellInlines.h"
-#import "JSContextInternal.h"
-#import "JSWrapperMap.h"
-#import "JSValueInternal.h"
-#import "ObjCCallbackFunction.h"
-#import "ObjcRuntimeExtras.h"
-#import <objc/runtime.h>
-#import <wtf/RetainPtr.h>
-
-class CallbackArgument {
-public:
- virtual ~CallbackArgument();
- virtual void set(NSInvocation *, NSInteger, JSContext *, JSValueRef, JSValueRef*) = 0;
-
- OwnPtr<CallbackArgument> m_next;
-};
-
-CallbackArgument::~CallbackArgument()
-{
-}
-
-class CallbackArgumentBoolean : public CallbackArgument {
- virtual void set(NSInvocation *invocation, NSInteger argumentNumber, JSContext *context, JSValueRef argument, JSValueRef*) override
- {
- bool value = JSValueToBoolean([context JSGlobalContextRef], argument);
- [invocation setArgument:&value atIndex:argumentNumber];
- }
-};
-
-template<typename T>
-class CallbackArgumentInteger : public CallbackArgument {
- virtual void set(NSInvocation *invocation, NSInteger argumentNumber, JSContext *context, JSValueRef argument, JSValueRef* exception) override
- {
- T value = (T)JSC::toInt32(JSValueToNumber([context JSGlobalContextRef], argument, exception));
- [invocation setArgument:&value atIndex:argumentNumber];
- }
-};
-
-template<typename T>
-class CallbackArgumentDouble : public CallbackArgument {
- virtual void set(NSInvocation *invocation, NSInteger argumentNumber, JSContext *context, JSValueRef argument, JSValueRef* exception) override
- {
- T value = (T)JSValueToNumber([context JSGlobalContextRef], argument, exception);
- [invocation setArgument:&value atIndex:argumentNumber];
- }
-};
-
-class CallbackArgumentJSValue : public CallbackArgument {
- virtual void set(NSInvocation *invocation, NSInteger argumentNumber, JSContext *context, JSValueRef argument, JSValueRef*) override
- {
- JSValue *value = [JSValue valueWithJSValueRef:argument inContext:context];
- [invocation setArgument:&value atIndex:argumentNumber];
- }
-};
-
-class CallbackArgumentId : public CallbackArgument {
- virtual void set(NSInvocation *invocation, NSInteger argumentNumber, JSContext *context, JSValueRef argument, JSValueRef*) override
- {
- id value = valueToObject(context, argument);
- [invocation setArgument:&value atIndex:argumentNumber];
- }
-};
-
-class CallbackArgumentOfClass : public CallbackArgument {
-public:
- CallbackArgumentOfClass(Class cls)
- : CallbackArgument()
- , m_class(cls)
- {
- [m_class retain];
- }
-
-private:
- virtual ~CallbackArgumentOfClass()
- {
- [m_class release];
- }
-
- virtual void set(NSInvocation *invocation, NSInteger argumentNumber, JSContext *context, JSValueRef argument, JSValueRef* exception) override
- {
- JSGlobalContextRef contextRef = [context JSGlobalContextRef];
-
- id object = tryUnwrapObjcObject(contextRef, argument);
- if (object && [object isKindOfClass:m_class]) {
- [invocation setArgument:&object atIndex:argumentNumber];
- return;
- }
-
- if (JSValueIsNull(contextRef, argument) || JSValueIsUndefined(contextRef, argument)) {
- object = nil;
- [invocation setArgument:&object atIndex:argumentNumber];
- return;
- }
-
- *exception = toRef(JSC::createTypeError(toJS(contextRef), "Argument does not match Objective-C Class"));
- }
-
- Class m_class;
-};
-
-class CallbackArgumentNSNumber : public CallbackArgument {
- virtual void set(NSInvocation *invocation, NSInteger argumentNumber, JSContext *context, JSValueRef argument, JSValueRef* exception) override
- {
- id value = valueToNumber([context JSGlobalContextRef], argument, exception);
- [invocation setArgument:&value atIndex:argumentNumber];
- }
-};
-
-class CallbackArgumentNSString : public CallbackArgument {
- virtual void set(NSInvocation *invocation, NSInteger argumentNumber, JSContext *context, JSValueRef argument, JSValueRef* exception) override
- {
- id value = valueToString([context JSGlobalContextRef], argument, exception);
- [invocation setArgument:&value atIndex:argumentNumber];
- }
-};
-
-class CallbackArgumentNSDate : public CallbackArgument {
- virtual void set(NSInvocation *invocation, NSInteger argumentNumber, JSContext *context, JSValueRef argument, JSValueRef* exception) override
- {
- id value = valueToDate([context JSGlobalContextRef], argument, exception);
- [invocation setArgument:&value atIndex:argumentNumber];
- }
-};
-
-class CallbackArgumentNSArray : public CallbackArgument {
- virtual void set(NSInvocation *invocation, NSInteger argumentNumber, JSContext *context, JSValueRef argument, JSValueRef* exception) override
- {
- id value = valueToArray([context JSGlobalContextRef], argument, exception);
- [invocation setArgument:&value atIndex:argumentNumber];
- }
-};
-
-class CallbackArgumentNSDictionary : public CallbackArgument {
- virtual void set(NSInvocation *invocation, NSInteger argumentNumber, JSContext *context, JSValueRef argument, JSValueRef* exception) override
- {
- id value = valueToDictionary([context JSGlobalContextRef], argument, exception);
- [invocation setArgument:&value atIndex:argumentNumber];
- }
-};
-
-class CallbackArgumentStruct : public CallbackArgument {
-public:
- CallbackArgumentStruct(NSInvocation *conversionInvocation, const char* encodedType)
- : m_conversionInvocation(conversionInvocation)
- , m_buffer(encodedType)
- {
- }
-
-private:
- virtual void set(NSInvocation *invocation, NSInteger argumentNumber, JSContext *context, JSValueRef argument, JSValueRef*) override
- {
- JSValue *value = [JSValue valueWithJSValueRef:argument inContext:context];
- [m_conversionInvocation invokeWithTarget:value];
- [m_conversionInvocation getReturnValue:m_buffer];
- [invocation setArgument:m_buffer atIndex:argumentNumber];
- }
-
- RetainPtr<NSInvocation> m_conversionInvocation;
- StructBuffer m_buffer;
-};
-
-class ArgumentTypeDelegate {
-public:
- typedef CallbackArgument* ResultType;
-
- template<typename T>
- static ResultType typeInteger()
- {
- return new CallbackArgumentInteger<T>;
- }
-
- template<typename T>
- static ResultType typeDouble()
- {
- return new CallbackArgumentDouble<T>;
- }
-
- static ResultType typeBool()
- {
- return new CallbackArgumentBoolean;
- }
-
- static ResultType typeVoid()
- {
- RELEASE_ASSERT_NOT_REACHED();
- return 0;
- }
-
- static ResultType typeId()
- {
- return new CallbackArgumentId;
- }
-
- static ResultType typeOfClass(const char* begin, const char* end)
- {
- StringRange copy(begin, end);
- Class cls = objc_getClass(copy);
- if (!cls)
- return 0;
-
- if (cls == [JSValue class])
- return new CallbackArgumentJSValue;
- if (cls == [NSString class])
- return new CallbackArgumentNSString;
- if (cls == [NSNumber class])
- return new CallbackArgumentNSNumber;
- if (cls == [NSDate class])
- return new CallbackArgumentNSDate;
- if (cls == [NSArray class])
- return new CallbackArgumentNSArray;
- if (cls == [NSDictionary class])
- return new CallbackArgumentNSDictionary;
-
- return new CallbackArgumentOfClass(cls);
- }
-
- static ResultType typeBlock(const char*, const char*)
- {
- return nil;
- }
-
- static ResultType typeStruct(const char* begin, const char* end)
- {
- StringRange copy(begin, end);
- if (NSInvocation *invocation = valueToTypeInvocationFor(copy))
- return new CallbackArgumentStruct(invocation, copy);
- return 0;
- }
-};
-
-class CallbackResult {
-public:
- virtual ~CallbackResult()
- {
- }
-
- virtual JSValueRef get(NSInvocation *, JSContext *, JSValueRef*) = 0;
-};
-
-class CallbackResultVoid : public CallbackResult {
- virtual JSValueRef get(NSInvocation *, JSContext *context, JSValueRef*) override
- {
- return JSValueMakeUndefined([context JSGlobalContextRef]);
- }
-};
-
-class CallbackResultId : public CallbackResult {
- virtual JSValueRef get(NSInvocation *invocation, JSContext *context, JSValueRef*) override
- {
- id value;
- [invocation getReturnValue:&value];
- return objectToValue(context, value);
- }
-};
-
-template<typename T>
-class CallbackResultNumeric : public CallbackResult {
- virtual JSValueRef get(NSInvocation *invocation, JSContext *context, JSValueRef*) override
- {
- T value;
- [invocation getReturnValue:&value];
- return JSValueMakeNumber([context JSGlobalContextRef], value);
- }
-};
-
-class CallbackResultBoolean : public CallbackResult {
- virtual JSValueRef get(NSInvocation *invocation, JSContext *context, JSValueRef*) override
- {
- bool value;
- [invocation getReturnValue:&value];
- return JSValueMakeBoolean([context JSGlobalContextRef], value);
- }
-};
-
-class CallbackResultStruct : public CallbackResult {
-public:
- CallbackResultStruct(NSInvocation *conversionInvocation, const char* encodedType)
- : m_conversionInvocation(conversionInvocation)
- , m_buffer(encodedType)
- {
- }
-
-private:
- virtual JSValueRef get(NSInvocation *invocation, JSContext *context, JSValueRef*) override
- {
- [invocation getReturnValue:m_buffer];
-
- [m_conversionInvocation setArgument:m_buffer atIndex:2];
- [m_conversionInvocation setArgument:&context atIndex:3];
- [m_conversionInvocation invokeWithTarget:[JSValue class]];
-
- JSValue *value;
- [m_conversionInvocation getReturnValue:&value];
- return valueInternalValue(value);
- }
-
- RetainPtr<NSInvocation> m_conversionInvocation;
- StructBuffer m_buffer;
-};
-
-class ResultTypeDelegate {
-public:
- typedef CallbackResult* ResultType;
-
- template<typename T>
- static ResultType typeInteger()
- {
- return new CallbackResultNumeric<T>;
- }
-
- template<typename T>
- static ResultType typeDouble()
- {
- return new CallbackResultNumeric<T>;
- }
-
- static ResultType typeBool()
- {
- return new CallbackResultBoolean;
- }
-
- static ResultType typeVoid()
- {
- return new CallbackResultVoid;
- }
-
- static ResultType typeId()
- {
- return new CallbackResultId();
- }
-
- static ResultType typeOfClass(const char*, const char*)
- {
- return new CallbackResultId();
- }
-
- static ResultType typeBlock(const char*, const char*)
- {
- return new CallbackResultId();
- }
-
- static ResultType typeStruct(const char* begin, const char* end)
- {
- StringRange copy(begin, end);
- if (NSInvocation *invocation = typeToValueInvocationFor(copy))
- return new CallbackResultStruct(invocation, copy);
- return 0;
- }
-};
-
-enum CallbackType {
- CallbackInstanceMethod,
- CallbackClassMethod,
- CallbackBlock
-};
-
-namespace JSC {
-
-class ObjCCallbackFunctionImpl {
-public:
- ObjCCallbackFunctionImpl(JSContext *context, NSInvocation *invocation, CallbackType type, Class instanceClass, PassOwnPtr<CallbackArgument> arguments, PassOwnPtr<CallbackResult> result)
- : m_context(context)
- , m_type(type)
- , m_instanceClass([instanceClass retain])
- , m_invocation(invocation)
- , m_arguments(arguments)
- , m_result(result)
- {
- ASSERT(type != CallbackInstanceMethod || instanceClass);
- }
-
- ~ObjCCallbackFunctionImpl()
- {
- if (m_type != CallbackInstanceMethod)
- [[m_invocation.get() target] release];
- [m_instanceClass release];
- }
-
- JSValueRef call(JSContext *context, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception);
-
- JSContext *context()
- {
- return m_context.get();
- }
-
- void setContext(JSContext *context)
- {
- ASSERT(!m_context.get());
- m_context.set(context);
- }
-
- id wrappedBlock()
- {
- return m_type == CallbackBlock ? [m_invocation target] : nil;
- }
-
-private:
- WeakContextRef m_context;
- CallbackType m_type;
- Class m_instanceClass;
- RetainPtr<NSInvocation> m_invocation;
- OwnPtr<CallbackArgument> m_arguments;
- OwnPtr<CallbackResult> m_result;
-};
-
-static JSValueRef objCCallbackFunctionCallAsFunction(JSContextRef callerContext, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
-{
- // Retake the API lock - we need this for a few reasons:
- // (1) We don't want to support the C-API's confusing drops-locks-once policy - should only drop locks if we can do so recursively.
- // (2) We're calling some JSC internals that require us to be on the 'inside' - e.g. createTypeError.
- // (3) We need to be locked (per context would be fine) against conflicting usage of the ObjCCallbackFunction's NSInvocation.
- JSC::APIEntryShim entryShim(toJS(callerContext));
-
- ObjCCallbackFunction* callback = static_cast<ObjCCallbackFunction*>(toJS(function));
- ObjCCallbackFunctionImpl* impl = callback->impl();
- JSContext *context = impl->context();
- if (!context) {
- context = [JSContext contextWithJSGlobalContextRef:toGlobalRef(toJS(callerContext)->lexicalGlobalObject()->globalExec())];
- impl->setContext(context);
- }
-
- CallbackData callbackData;
- JSValueRef result;
- @autoreleasepool {
- [context beginCallbackWithData:&callbackData thisValue:thisObject argumentCount:argumentCount arguments:arguments];
- result = impl->call(context, thisObject, argumentCount, arguments, exception);
- if (context.exception)
- *exception = valueInternalValue(context.exception);
- [context endCallbackWithData:&callbackData];
- }
- return result;
-}
-
-const JSC::ClassInfo ObjCCallbackFunction::s_info = { "CallbackFunction", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(ObjCCallbackFunction) };
-
-ObjCCallbackFunction::ObjCCallbackFunction(JSC::JSGlobalObject* globalObject, JSObjectCallAsFunctionCallback callback, PassOwnPtr<ObjCCallbackFunctionImpl> impl)
- : Base(globalObject, globalObject->objcCallbackFunctionStructure(), callback)
- , m_impl(impl)
-{
-}
-
-ObjCCallbackFunction* ObjCCallbackFunction::create(JSC::ExecState* exec, JSC::JSGlobalObject* globalObject, const String& name, PassOwnPtr<ObjCCallbackFunctionImpl> impl)
-{
- ObjCCallbackFunction* function = new (NotNull, allocateCell<ObjCCallbackFunction>(*exec->heap())) ObjCCallbackFunction(globalObject, objCCallbackFunctionCallAsFunction, impl);
- function->finishCreation(exec->vm(), name);
- return function;
-}
-
-void ObjCCallbackFunction::destroy(JSCell* cell)
-{
- static_cast<ObjCCallbackFunction*>(cell)->ObjCCallbackFunction::~ObjCCallbackFunction();
-}
-
-JSValueRef ObjCCallbackFunctionImpl::call(JSContext *context, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
-{
- JSGlobalContextRef contextRef = [context JSGlobalContextRef];
-
- size_t firstArgument;
- switch (m_type) {
- case CallbackInstanceMethod: {
- id target = tryUnwrapObjcObject(contextRef, thisObject);
- if (!target || ![target isKindOfClass:m_instanceClass]) {
- *exception = toRef(JSC::createTypeError(toJS(contextRef), "self type check failed for Objective-C instance method"));
- return JSValueMakeUndefined(contextRef);
- }
- [m_invocation setTarget:target];
- }
- // fallthrough - firstArgument for CallbackInstanceMethod is also 2!
- case CallbackClassMethod:
- firstArgument = 2;
- break;
- case CallbackBlock:
- firstArgument = 1;
- }
-
- size_t argumentNumber = 0;
- for (CallbackArgument* argument = m_arguments.get(); argument; argument = argument->m_next.get()) {
- JSValueRef value = argumentNumber < argumentCount ? arguments[argumentNumber] : JSValueMakeUndefined(contextRef);
- argument->set(m_invocation.get(), argumentNumber + firstArgument, context, value, exception);
- if (*exception)
- return JSValueMakeUndefined(contextRef);
- ++argumentNumber;
- }
-
- [m_invocation invoke];
-
- return m_result->get(m_invocation.get(), context, exception);
-}
-
-} // namespace JSC
-
-static bool blockSignatureContainsClass()
-{
- static bool containsClass = ^{
- id block = ^(NSString *string){ return string; };
- return _Block_has_signature(block) && strstr(_Block_signature(block), "NSString");
- }();
- return containsClass;
-}
-
-inline bool skipNumber(const char*& position)
-{
- if (!isASCIIDigit(*position))
- return false;
- while (isASCIIDigit(*++position)) { }
- return true;
-}
-
-static JSObjectRef objCCallbackFunctionForInvocation(JSContext *context, NSInvocation *invocation, CallbackType type, Class instanceClass, const char* signatureWithObjcClasses)
-{
- const char* position = signatureWithObjcClasses;
-
- OwnPtr<CallbackResult> result = adoptPtr(parseObjCType<ResultTypeDelegate>(position));
- if (!result || !skipNumber(position))
- return nil;
-
- switch (type) {
- case CallbackInstanceMethod:
- case CallbackClassMethod:
- // Methods are passed two implicit arguments - (id)self, and the selector.
- if ('@' != *position++ || !skipNumber(position) || ':' != *position++ || !skipNumber(position))
- return nil;
- break;
- case CallbackBlock:
- // Blocks are passed one implicit argument - the block, of type "@?".
- if (('@' != *position++) || ('?' != *position++) || !skipNumber(position))
- return nil;
- // Only allow arguments of type 'id' if the block signature contains the NS type information.
- if ((!blockSignatureContainsClass() && strchr(position, '@')))
- return nil;
- break;
- }
-
- OwnPtr<CallbackArgument> arguments = 0;
- OwnPtr<CallbackArgument>* nextArgument = &arguments;
- unsigned argumentCount = 0;
- while (*position) {
- OwnPtr<CallbackArgument> argument = adoptPtr(parseObjCType<ArgumentTypeDelegate>(position));
- if (!argument || !skipNumber(position))
- return nil;
-
- *nextArgument = argument.release();
- nextArgument = &(*nextArgument)->m_next;
- ++argumentCount;
- }
-
- JSC::ExecState* exec = toJS([context JSGlobalContextRef]);
- JSC::APIEntryShim shim(exec);
- OwnPtr<JSC::ObjCCallbackFunctionImpl> impl = adoptPtr(new JSC::ObjCCallbackFunctionImpl(context, invocation, type, instanceClass, arguments.release(), result.release()));
- // FIXME: Maybe we could support having the selector as the name of the function to make it a bit more user-friendly from the JS side?
- return toRef(JSC::ObjCCallbackFunction::create(exec, exec->lexicalGlobalObject(), "", impl.release()));
-}
-
-JSObjectRef objCCallbackFunctionForMethod(JSContext *context, Class cls, Protocol *protocol, BOOL isInstanceMethod, SEL sel, const char* types)
-{
- NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[NSMethodSignature signatureWithObjCTypes:types]];
- [invocation setSelector:sel];
- if (!isInstanceMethod)
- [invocation setTarget:cls];
- return objCCallbackFunctionForInvocation(context, invocation, isInstanceMethod ? CallbackInstanceMethod : CallbackClassMethod, isInstanceMethod ? cls : nil, _protocol_getMethodTypeEncoding(protocol, sel, YES, isInstanceMethod));
-}
-
-JSObjectRef objCCallbackFunctionForBlock(JSContext *context, id target)
-{
- if (!_Block_has_signature(target))
- return 0;
- const char* signature = _Block_signature(target);
- NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[NSMethodSignature signatureWithObjCTypes:signature]];
- [invocation setTarget:[target copy]];
- return objCCallbackFunctionForInvocation(context, invocation, CallbackBlock, nil, signature);
-}
-
-id tryUnwrapBlock(JSObjectRef object)
-{
- if (!toJS(object)->inherits(&JSC::ObjCCallbackFunction::s_info))
- return nil;
- return static_cast<JSC::ObjCCallbackFunction*>(toJS(object))->impl()->wrappedBlock();
-}
-
-#endif
diff --git a/Source/JavaScriptCore/API/ObjcRuntimeExtras.h b/Source/JavaScriptCore/API/ObjcRuntimeExtras.h
index 48c112093..128df5c90 100644
--- a/Source/JavaScriptCore/API/ObjcRuntimeExtras.h
+++ b/Source/JavaScriptCore/API/ObjcRuntimeExtras.h
@@ -23,6 +23,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#import <objc/Protocol.h>
#import <objc/runtime.h>
#import <wtf/HashSet.h>
#import <wtf/Vector.h>
@@ -163,7 +164,7 @@ typename DelegateType::ResultType parseObjCType(const char*& position)
case 'l':
return DelegateType::template typeInteger<long>();
case 'q':
- return DelegateType::template typeDouble<unsigned long long>();
+ return DelegateType::template typeDouble<long long>();
case 'C':
return DelegateType::template typeInteger<unsigned char>();
case 'I':
@@ -192,9 +193,19 @@ typename DelegateType::ResultType parseObjCType(const char*& position)
}
if (*position == '"') {
- const char* begin = ++position;
- position = index(position, '"');
- return DelegateType::typeOfClass(begin, position++);
+ const char* begin = position + 1;
+ const char* protocolPosition = strchr(begin, '<');
+ const char* endOfType = strchr(begin, '"');
+ position = endOfType + 1;
+
+ // There's no protocol involved in this type, so just handle the class name.
+ if (!protocolPosition || protocolPosition > endOfType)
+ return DelegateType::typeOfClass(begin, endOfType);
+ // We skipped the class name and went straight to the protocol, so this is an id type.
+ if (begin == protocolPosition)
+ return DelegateType::typeId();
+ // We have a class name with a protocol. For now, ignore the protocol.
+ return DelegateType::typeOfClass(begin, protocolPosition);
}
return DelegateType::typeId();
diff --git a/Source/JavaScriptCore/API/OpaqueJSString.cpp b/Source/JavaScriptCore/API/OpaqueJSString.cpp
index a7cef8d9a..07a79ad99 100644
--- a/Source/JavaScriptCore/API/OpaqueJSString.cpp
+++ b/Source/JavaScriptCore/API/OpaqueJSString.cpp
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
@@ -26,38 +26,84 @@
#include "config.h"
#include "OpaqueJSString.h"
-#include <interpreter/CallFrame.h>
-#include <runtime/JSGlobalObject.h>
-#include <runtime/Identifier.h>
+#include "CallFrame.h"
+#include "Identifier.h"
+#include "IdentifierInlines.h"
+#include "JSGlobalObject.h"
+#include <wtf/text/StringView.h>
using namespace JSC;
-PassRefPtr<OpaqueJSString> OpaqueJSString::create(const String& string)
+RefPtr<OpaqueJSString> OpaqueJSString::create(const String& string)
{
- if (!string.isNull())
- return adoptRef(new OpaqueJSString(string));
- return 0;
+ if (string.isNull())
+ return nullptr;
+
+ return adoptRef(new OpaqueJSString(string));
}
-String OpaqueJSString::string() const
+OpaqueJSString::~OpaqueJSString()
{
- if (!this)
- return String();
+ // m_characters is put in a local here to avoid an extra atomic load.
+ UChar* characters = m_characters;
+ if (!characters)
+ return;
+
+ if (!m_string.is8Bit() && m_string.characters16() == characters)
+ return;
+
+ fastFree(characters);
+}
+String OpaqueJSString::string() const
+{
// Return a copy of the wrapped string, because the caller may make it an Identifier.
return m_string.isolatedCopy();
}
Identifier OpaqueJSString::identifier(VM* vm) const
{
- if (!this || m_string.isNull())
+ if (m_string.isNull())
return Identifier();
if (m_string.isEmpty())
return Identifier(Identifier::EmptyIdentifier);
if (m_string.is8Bit())
- return Identifier(vm, m_string.characters8(), m_string.length());
+ return Identifier::fromString(vm, m_string.characters8(), m_string.length());
+
+ return Identifier::fromString(vm, m_string.characters16(), m_string.length());
+}
+
+const UChar* OpaqueJSString::characters()
+{
+ // m_characters is put in a local here to avoid an extra atomic load.
+ UChar* characters = m_characters;
+ if (characters)
+ return characters;
+
+ if (m_string.isNull())
+ return nullptr;
+
+ unsigned length = m_string.length();
+ UChar* newCharacters = static_cast<UChar*>(fastMalloc(length * sizeof(UChar)));
+ StringView(m_string).getCharactersWithUpconvert(newCharacters);
+
+ if (!m_characters.compare_exchange_strong(characters, newCharacters)) {
+ fastFree(newCharacters);
+ return characters;
+ }
+
+ return newCharacters;
+}
+
+bool OpaqueJSString::equal(const OpaqueJSString* a, const OpaqueJSString* b)
+{
+ if (a == b)
+ return true;
+
+ if (!a || !b)
+ return false;
- return Identifier(vm, m_string.characters16(), m_string.length());
+ return a->m_string == b->m_string;
}
diff --git a/Source/JavaScriptCore/API/OpaqueJSString.h b/Source/JavaScriptCore/API/OpaqueJSString.h
index c374b567a..ec4fd7f6a 100644
--- a/Source/JavaScriptCore/API/OpaqueJSString.h
+++ b/Source/JavaScriptCore/API/OpaqueJSString.h
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
@@ -26,6 +26,7 @@
#ifndef OpaqueJSString_h
#define OpaqueJSString_h
+#include <atomic>
#include <wtf/ThreadSafeRefCounted.h>
#include <wtf/text/WTFString.h>
@@ -35,26 +36,31 @@ namespace JSC {
}
struct OpaqueJSString : public ThreadSafeRefCounted<OpaqueJSString> {
-
- static PassRefPtr<OpaqueJSString> create() // null
+ static Ref<OpaqueJSString> create()
{
- return adoptRef(new OpaqueJSString);
+ return adoptRef(*new OpaqueJSString);
}
- static PassRefPtr<OpaqueJSString> create(const LChar* characters, unsigned length)
+ static Ref<OpaqueJSString> create(const LChar* characters, unsigned length)
{
- return adoptRef(new OpaqueJSString(characters, length));
+ return adoptRef(*new OpaqueJSString(characters, length));
}
- static PassRefPtr<OpaqueJSString> create(const UChar* characters, unsigned length)
+ static Ref<OpaqueJSString> create(const UChar* characters, unsigned length)
{
- return adoptRef(new OpaqueJSString(characters, length));
+ return adoptRef(*new OpaqueJSString(characters, length));
}
- JS_EXPORT_PRIVATE static PassRefPtr<OpaqueJSString> create(const String&);
+ JS_EXPORT_PRIVATE static RefPtr<OpaqueJSString> create(const String&);
+
+ JS_EXPORT_PRIVATE ~OpaqueJSString();
+
+ bool is8Bit() { return m_string.is8Bit(); }
+ const LChar* characters8() { return m_string.characters8(); }
+ const UChar* characters16() { return m_string.characters16(); }
+ unsigned length() { return m_string.length(); }
- const UChar* characters() { return !!this ? m_string.characters() : 0; }
- unsigned length() { return !!this ? m_string.length() : 0; }
+ const UChar* characters();
JS_EXPORT_PRIVATE String string() const;
JSC::Identifier identifier(JSC::VM*) const;
@@ -62,29 +68,38 @@ struct OpaqueJSString : public ThreadSafeRefCounted<OpaqueJSString> {
QString qString() const { return m_string; }
#endif
+ static bool equal(const OpaqueJSString*, const OpaqueJSString*);
+
private:
friend class WTF::ThreadSafeRefCounted<OpaqueJSString>;
OpaqueJSString()
+ : m_characters(nullptr)
{
}
OpaqueJSString(const String& string)
: m_string(string.isolatedCopy())
+ , m_characters(m_string.impl() && m_string.is8Bit() ? nullptr : const_cast<UChar*>(m_string.characters16()))
{
}
OpaqueJSString(const LChar* characters, unsigned length)
+ : m_string(characters, length)
+ , m_characters(nullptr)
{
- m_string = String(characters, length);
}
OpaqueJSString(const UChar* characters, unsigned length)
+ : m_string(characters, length)
+ , m_characters(m_string.impl() && m_string.is8Bit() ? nullptr : const_cast<UChar*>(m_string.characters16()))
{
- m_string = String(characters, length);
}
String m_string;
+
+ // This will be initialized on demand when characters() is called if the string needs up-conversion.
+ std::atomic<UChar*> m_characters;
};
#endif
diff --git a/Source/JavaScriptCore/API/WebKitAvailability.h b/Source/JavaScriptCore/API/WebKitAvailability.h
index 7846058fa..f878beae9 100644
--- a/Source/JavaScriptCore/API/WebKitAvailability.h
+++ b/Source/JavaScriptCore/API/WebKitAvailability.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008, 2009, 2010 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2008, 2009, 2010, 2014 Apple Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -26,898 +26,51 @@
#ifndef __WebKitAvailability__
#define __WebKitAvailability__
-/* The structure of this header is based on AvailabilityMacros.h. The major difference is that the availability
- macros are defined in terms of WebKit version numbers rather than Mac OS X system version numbers, as WebKit
- releases span multiple versions of Mac OS X.
-*/
-
-#define WEBKIT_VERSION_1_0 0x0100
-#define WEBKIT_VERSION_1_1 0x0110
-#define WEBKIT_VERSION_1_2 0x0120
-#define WEBKIT_VERSION_1_3 0x0130
-#define WEBKIT_VERSION_2_0 0x0200
-#define WEBKIT_VERSION_3_0 0x0300
-#define WEBKIT_VERSION_3_1 0x0310
-#define WEBKIT_VERSION_4_0 0x0400
-#define WEBKIT_VERSION_LATEST 0x9999
+#if defined(__APPLE__)
-#ifdef __APPLE__
#include <AvailabilityMacros.h>
-#else
-/*
- * For non-Mac platforms, require the newest version.
- */
-#define WEBKIT_VERSION_MIN_REQUIRED WEBKIT_VERSION_LATEST
-/*
- * only certain compilers support __attribute__((deprecated))
- */
-#if defined(__GNUC__) && ((__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1)))
- #define DEPRECATED_ATTRIBUTE __attribute__((deprecated))
-#else
- #define DEPRECATED_ATTRIBUTE
-#endif
-#endif
+#include <CoreFoundation/CoreFoundation.h>
-/* The versions of GCC that shipped with Xcode prior to 3.0 (GCC build number < 5400) did not support attributes on methods.
- If we are building with one of these versions, we need to omit the attribute. We achieve this by wrapping the annotation
- in WEBKIT_OBJC_METHOD_ANNOTATION, which will remove the annotation when an old version of GCC is in use and will otherwise
- expand to the annotation. The same is needed for protocol methods.
+#if !TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED < 101100
+/* To support availability macros that mention newer OS X versions when building on older OS X versions,
+ we provide our own definitions of the underlying macros that the availability macros expand to. We're
+ free to expand the macros as no-ops since frameworks built on older OS X versions only ship bundled with
+ an application rather than as part of the system.
*/
-#if defined(__APPLE_CC__) && __APPLE_CC__ < 5400
- #define WEBKIT_OBJC_METHOD_ANNOTATION(ANNOTATION)
-#else
- #define WEBKIT_OBJC_METHOD_ANNOTATION(ANNOTATION) ANNOTATION
-#endif
-
-
-/* If minimum WebKit version is not specified, assume the version that shipped with the target Mac OS X version */
-#ifndef WEBKIT_VERSION_MIN_REQUIRED
- #if !defined(MAC_OS_X_VERSION_10_2) || MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_2
- #error WebKit was not available prior to Mac OS X 10.2
- #elif !defined(MAC_OS_X_VERSION_10_3) || MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_3
- /* WebKit 1.0 is the only version available on Mac OS X 10.2. */
- #define WEBKIT_VERSION_MIN_REQUIRED WEBKIT_VERSION_1_0
- #elif !defined(MAC_OS_X_VERSION_10_4) || MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_4
- /* WebKit 1.1 is the version that shipped on Mac OS X 10.3. */
- #define WEBKIT_VERSION_MIN_REQUIRED WEBKIT_VERSION_1_1
- #elif !defined(MAC_OS_X_VERSION_10_5) || MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
- /* WebKit 2.0 is the version that shipped on Mac OS X 10.4. */
- #define WEBKIT_VERSION_MIN_REQUIRED WEBKIT_VERSION_2_0
- #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
-#endif
-
-
-/* If maximum WebKit version is not specified, assume largerof(latest, minimum) */
-#ifndef WEBKIT_VERSION_MAX_ALLOWED
- #if WEBKIT_VERSION_MIN_REQUIRED > WEBKIT_VERSION_LATEST
- #define WEBKIT_VERSION_MAX_ALLOWED WEBKIT_VERSION_MIN_REQUIRED
- #else
- #define WEBKIT_VERSION_MAX_ALLOWED WEBKIT_VERSION_LATEST
- #endif
-#endif
-
-
-/* Sanity check the configured values */
-#if WEBKIT_VERSION_MAX_ALLOWED < WEBKIT_VERSION_MIN_REQUIRED
- #error WEBKIT_VERSION_MAX_ALLOWED must be >= WEBKIT_VERSION_MIN_REQUIRED
-#endif
-#if WEBKIT_VERSION_MIN_REQUIRED < WEBKIT_VERSION_1_0
- #error WEBKIT_VERSION_MIN_REQUIRED must be >= WEBKIT_VERSION_1_0
-#endif
-
-
-
-
-
-
-/*
- * AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER
- *
- * Used on functions introduced in WebKit 1.0
- */
-#define AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER
-
-/*
- * AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED
- *
- * Used on functions introduced in WebKit 1.0,
- * and deprecated in WebKit 1.0
- */
-#define AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED DEPRECATED_ATTRIBUTE
-
-/*
- * DEPRECATED_IN_WEBKIT_VERSION_1_0_AND_LATER
- *
- * Used on types deprecated in WebKit 1.0
- */
-#define DEPRECATED_IN_WEBKIT_VERSION_1_0_AND_LATER DEPRECATED_ATTRIBUTE
-
-
-
-
-
-
-/*
- * AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER
- *
- * Used on declarations introduced in WebKit 1.1
- */
-#if WEBKIT_VERSION_MAX_ALLOWED < WEBKIT_VERSION_1_1
- #define AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER UNAVAILABLE_ATTRIBUTE
-#elif WEBKIT_VERSION_MIN_REQUIRED < WEBKIT_VERSION_1_1
- #define AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER WEAK_IMPORT_ATTRIBUTE
-#else
- #define AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER
-#endif
-
-/*
- * AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER_BUT_DEPRECATED
- *
- * Used on declarations introduced in WebKit 1.1,
- * and deprecated in WebKit 1.1
- */
-#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_1_1
- #define AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER_BUT_DEPRECATED DEPRECATED_ATTRIBUTE
-#else
- #define AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER_BUT_DEPRECATED AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER
-#endif
-
-/*
- * AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_1_1
- *
- * Used on declarations introduced in WebKit 1.0,
- * but later deprecated in WebKit 1.1
- */
-#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_1_1
- #define AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_1_1 DEPRECATED_ATTRIBUTE
-#else
- #define AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_1_1 AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER
-#endif
-
-/*
- * DEPRECATED_IN_WEBKIT_VERSION_1_1_AND_LATER
- *
- * Used on types deprecated in WebKit 1.1
- */
-#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_1_1
- #define DEPRECATED_IN_WEBKIT_VERSION_1_1_AND_LATER DEPRECATED_ATTRIBUTE
-#else
- #define DEPRECATED_IN_WEBKIT_VERSION_1_1_AND_LATER
-#endif
-
-
-
-
-
-
-/*
- * AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER
- *
- * Used on declarations introduced in WebKit 1.2
- */
-#if WEBKIT_VERSION_MAX_ALLOWED < WEBKIT_VERSION_1_2
- #define AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER UNAVAILABLE_ATTRIBUTE
-#elif WEBKIT_VERSION_MIN_REQUIRED < WEBKIT_VERSION_1_2
- #define AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER WEAK_IMPORT_ATTRIBUTE
-#else
- #define AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER
-#endif
-
-/*
- * AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER_BUT_DEPRECATED
- *
- * Used on declarations introduced in WebKit 1.2,
- * and deprecated in WebKit 1.2
- */
-#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_1_2
- #define AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER_BUT_DEPRECATED DEPRECATED_ATTRIBUTE
-#else
- #define AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER_BUT_DEPRECATED AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER
-#endif
-
-/*
- * AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_1_2
- *
- * Used on declarations introduced in WebKit 1.0,
- * but later deprecated in WebKit 1.2
- */
-#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_1_2
- #define AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_1_2 DEPRECATED_ATTRIBUTE
-#else
- #define AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_1_2 AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER
-#endif
-
-/*
- * AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_1_2
- *
- * Used on declarations introduced in WebKit 1.1,
- * but later deprecated in WebKit 1.2
- */
-#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_1_2
- #define AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_1_2 DEPRECATED_ATTRIBUTE
-#else
- #define AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_1_2 AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER
-#endif
-
-/*
- * DEPRECATED_IN_WEBKIT_VERSION_1_2_AND_LATER
- *
- * Used on types deprecated in WebKit 1.2
- */
-#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_1_2
- #define DEPRECATED_IN_WEBKIT_VERSION_1_2_AND_LATER DEPRECATED_ATTRIBUTE
-#else
- #define DEPRECATED_IN_WEBKIT_VERSION_1_2_AND_LATER
-#endif
-
-
-
-
-
-
-/*
- * AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER
- *
- * Used on declarations introduced in WebKit 1.3
- */
-#if WEBKIT_VERSION_MAX_ALLOWED < WEBKIT_VERSION_1_3
- #define AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER UNAVAILABLE_ATTRIBUTE
-#elif WEBKIT_VERSION_MIN_REQUIRED < WEBKIT_VERSION_1_3
- #define AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER WEAK_IMPORT_ATTRIBUTE
-#else
- #define AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER
-#endif
-
-/*
- * AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER_BUT_DEPRECATED
- *
- * Used on declarations introduced in WebKit 1.3,
- * and deprecated in WebKit 1.3
- */
-#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_1_3
- #define AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER_BUT_DEPRECATED DEPRECATED_ATTRIBUTE
-#else
- #define AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER_BUT_DEPRECATED AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER
-#endif
-
-/*
- * AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_1_3
- *
- * Used on declarations introduced in WebKit 1.0,
- * but later deprecated in WebKit 1.3
- */
-#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_1_3
- #define AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_1_3 DEPRECATED_ATTRIBUTE
-#else
- #define AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_1_3 AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER
-#endif
-
-/*
- * AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_1_3
- *
- * Used on declarations introduced in WebKit 1.1,
- * but later deprecated in WebKit 1.3
- */
-#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_1_3
- #define AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_1_3 DEPRECATED_ATTRIBUTE
-#else
- #define AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_1_3 AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER
-#endif
-
-/*
- * AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_1_3
- *
- * Used on declarations introduced in WebKit 1.2,
- * but later deprecated in WebKit 1.3
- */
-#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_1_3
- #define AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_1_3 DEPRECATED_ATTRIBUTE
-#else
- #define AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_1_3 AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER
-#endif
-
-/*
- * DEPRECATED_IN_WEBKIT_VERSION_1_3_AND_LATER
- *
- * Used on types deprecated in WebKit 1.3
- */
-#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_1_3
- #define DEPRECATED_IN_WEBKIT_VERSION_1_3_AND_LATER DEPRECATED_ATTRIBUTE
-#else
- #define DEPRECATED_IN_WEBKIT_VERSION_1_3_AND_LATER
-#endif
-
-
-
-
-
-
-/*
- * AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER
- *
- * Used on declarations introduced in WebKit 2.0
- */
-#if WEBKIT_VERSION_MAX_ALLOWED < WEBKIT_VERSION_2_0
- #define AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER UNAVAILABLE_ATTRIBUTE
-#elif WEBKIT_VERSION_MIN_REQUIRED < WEBKIT_VERSION_2_0
- #define AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER WEAK_IMPORT_ATTRIBUTE
-#else
- #define AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER
-#endif
-
-/*
- * AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER_BUT_DEPRECATED
- *
- * Used on declarations introduced in WebKit 2.0,
- * and deprecated in WebKit 2.0
- */
-#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_2_0
- #define AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER_BUT_DEPRECATED DEPRECATED_ATTRIBUTE
-#else
- #define AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER_BUT_DEPRECATED AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER
-#endif
-
-/*
- * AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_2_0
- *
- * Used on declarations introduced in WebKit 1.0,
- * but later deprecated in WebKit 2.0
- */
-#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_2_0
- #define AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_2_0 DEPRECATED_ATTRIBUTE
-#else
- #define AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_2_0 AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER
-#endif
-
-/*
- * AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_2_0
- *
- * Used on declarations introduced in WebKit 1.1,
- * but later deprecated in WebKit 2.0
- */
-#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_2_0
- #define AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_2_0 DEPRECATED_ATTRIBUTE
-#else
- #define AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_2_0 AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER
-#endif
-
-/*
- * AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_2_0
- *
- * Used on declarations introduced in WebKit 1.2,
- * but later deprecated in WebKit 2.0
- */
-#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_2_0
- #define AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_2_0 DEPRECATED_ATTRIBUTE
-#else
- #define AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_2_0 AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER
-#endif
-
-/*
- * AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_2_0
- *
- * Used on declarations introduced in WebKit 1.3,
- * but later deprecated in WebKit 2.0
- */
-#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_2_0
- #define AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_2_0 DEPRECATED_ATTRIBUTE
-#else
- #define AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_2_0 AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER
-#endif
-
-/*
- * DEPRECATED_IN_WEBKIT_VERSION_2_0_AND_LATER
- *
- * Used on types deprecated in WebKit 2.0
- */
-#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_2_0
- #define DEPRECATED_IN_WEBKIT_VERSION_2_0_AND_LATER DEPRECATED_ATTRIBUTE
-#else
- #define DEPRECATED_IN_WEBKIT_VERSION_2_0_AND_LATER
-#endif
-
-
-
-
-
-
-/*
- * AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER
- *
- * Used on declarations introduced in WebKit 3.0
- */
-#if WEBKIT_VERSION_MAX_ALLOWED < WEBKIT_VERSION_3_0
- #define AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER UNAVAILABLE_ATTRIBUTE
-#elif WEBKIT_VERSION_MIN_REQUIRED < WEBKIT_VERSION_3_0
- #define AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER WEAK_IMPORT_ATTRIBUTE
-#else
- #define AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER
-#endif
-
-/*
- * AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER_BUT_DEPRECATED
- *
- * Used on declarations introduced in WebKit 3.0,
- * and deprecated in WebKit 3.0
- */
-#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_3_0
- #define AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER_BUT_DEPRECATED DEPRECATED_ATTRIBUTE
-#else
- #define AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER_BUT_DEPRECATED AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER
-#endif
-
-/*
- * AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_0
- *
- * Used on declarations introduced in WebKit 1.0,
- * but later deprecated in WebKit 3.0
- */
-#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_3_0
- #define AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_0 DEPRECATED_ATTRIBUTE
-#else
- #define AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_0 AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER
-#endif
-/*
- * AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_0
- *
- * Used on declarations introduced in WebKit 1.1,
- * but later deprecated in WebKit 3.0
- */
-#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_3_0
- #define AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_0 DEPRECATED_ATTRIBUTE
-#else
- #define AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_0 AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER
+#ifndef __NSi_10_10 // Building from trunk rather than SDK.
+#define __NSi_10_10 introduced=10.0 // Use 10.0 to indicate that everything is available.
#endif
-/*
- * AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_0
- *
- * Used on declarations introduced in WebKit 1.2,
- * but later deprecated in WebKit 3.0
- */
-#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_3_0
- #define AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_0 DEPRECATED_ATTRIBUTE
-#else
- #define AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_0 AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER
+#ifndef __NSi_10_11 // Building from trunk rather than SDK.
+#define __NSi_10_11 introduced=10.0 // Use 10.0 to indicate that everything is available.
#endif
-/*
- * AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_0
- *
- * Used on declarations introduced in WebKit 1.3,
- * but later deprecated in WebKit 3.0
- */
-#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_3_0
- #define AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_0 DEPRECATED_ATTRIBUTE
-#else
- #define AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_0 AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER
+#ifndef __AVAILABILITY_INTERNAL__MAC_10_9
+#define __AVAILABILITY_INTERNAL__MAC_10_9
#endif
-/*
- * AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_0
- *
- * Used on declarations introduced in WebKit 2.0,
- * but later deprecated in WebKit 3.0
- */
-#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_3_0
- #define AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_0 DEPRECATED_ATTRIBUTE
-#else
- #define AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_0 AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER
+#ifndef __AVAILABILITY_INTERNAL__MAC_10_10
+#define __AVAILABILITY_INTERNAL__MAC_10_10
#endif
-/*
- * DEPRECATED_IN_WEBKIT_VERSION_3_0_AND_LATER
- *
- * Used on types deprecated in WebKit 3.0
- */
-#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_3_0
- #define DEPRECATED_IN_WEBKIT_VERSION_3_0_AND_LATER DEPRECATED_ATTRIBUTE
-#else
- #define DEPRECATED_IN_WEBKIT_VERSION_3_0_AND_LATER
+#ifndef AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER
+#define AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER
#endif
-
-
-
-
-
-/*
- * AVAILABLE_WEBKIT_VERSION_3_1_AND_LATER
- *
- * Used on declarations introduced in WebKit 3.1
- */
-#if WEBKIT_VERSION_MAX_ALLOWED < WEBKIT_VERSION_3_1
- #define AVAILABLE_WEBKIT_VERSION_3_1_AND_LATER UNAVAILABLE_ATTRIBUTE
-#elif WEBKIT_VERSION_MIN_REQUIRED < WEBKIT_VERSION_3_1
- #define AVAILABLE_WEBKIT_VERSION_3_1_AND_LATER WEAK_IMPORT_ATTRIBUTE
-#else
- #define AVAILABLE_WEBKIT_VERSION_3_1_AND_LATER
+#ifndef AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER
+#define AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER
#endif
-/*
- * AVAILABLE_WEBKIT_VERSION_3_1_AND_LATER_BUT_DEPRECATED
- *
- * Used on declarations introduced in WebKit 3.1,
- * and deprecated in WebKit 3.1
- */
-#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_3_1
- #define AVAILABLE_WEBKIT_VERSION_3_1_AND_LATER_BUT_DEPRECATED DEPRECATED_ATTRIBUTE
-#else
- #define AVAILABLE_WEBKIT_VERSION_3_1_AND_LATER_BUT_DEPRECATED AVAILABLE_WEBKIT_VERSION_3_1_AND_LATER
-#endif
-
-/*
- * AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_1
- *
- * Used on declarations introduced in WebKit 1.0,
- * but later deprecated in WebKit 3.1
- */
-#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_3_1
- #define AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_1 DEPRECATED_ATTRIBUTE
-#else
- #define AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_1 AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER
-#endif
+#endif /* __MAC_OS_X_VERSION_MIN_REQUIRED <= 101100 */
-/*
- * AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_1
- *
- * Used on declarations introduced in WebKit 1.1,
- * but later deprecated in WebKit 3.1
- */
-#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_3_1
- #define AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_1 DEPRECATED_ATTRIBUTE
-#else
- #define AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_1 AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER
+#if defined(BUILDING_GTK__)
+#undef CF_AVAILABLE
+#define CF_AVAILABLE(_mac, _ios)
#endif
-/*
- * AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_1
- *
- * Used on declarations introduced in WebKit 1.2,
- * but later deprecated in WebKit 3.1
- */
-#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_3_1
- #define AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_1 DEPRECATED_ATTRIBUTE
-#else
- #define AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_1 AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER
-#endif
-
-/*
- * AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_1
- *
- * Used on declarations introduced in WebKit 1.3,
- * but later deprecated in WebKit 3.1
- */
-#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_3_1
- #define AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_1 DEPRECATED_ATTRIBUTE
-#else
- #define AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_1 AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER
-#endif
-
-/*
- * AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_1
- *
- * Used on declarations introduced in WebKit 2.0,
- * but later deprecated in WebKit 3.1
- */
-#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_3_1
- #define AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_1 DEPRECATED_ATTRIBUTE
-#else
- #define AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_1 AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER
-#endif
-
-/*
- * AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_1
- *
- * Used on declarations introduced in WebKit 3.0,
- * but later deprecated in WebKit 3.1
- */
-#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_3_1
- #define AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_1 DEPRECATED_ATTRIBUTE
-#else
- #define AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_1 AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER
-#endif
-
-/*
- * DEPRECATED_IN_WEBKIT_VERSION_3_1_AND_LATER
- *
- * Used on types deprecated in WebKit 3.1
- */
-#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_3_1
- #define DEPRECATED_IN_WEBKIT_VERSION_3_1_AND_LATER DEPRECATED_ATTRIBUTE
-#else
- #define DEPRECATED_IN_WEBKIT_VERSION_3_1_AND_LATER
-#endif
-
-
-
-
-
-
-/*
- * AVAILABLE_IN_WEBKIT_VERSION_4_0
- *
- * Used on declarations introduced in WebKit 4.0
- */
-#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_4_0
- #define AVAILABLE_IN_WEBKIT_VERSION_4_0 WEAK_IMPORT_ATTRIBUTE
-#else
- #define AVAILABLE_IN_WEBKIT_VERSION_4_0
-#endif
-
-/*
- * AVAILABLE_IN_WEBKIT_VERSION_4_0_BUT_DEPRECATED
- *
- * Used on declarations introduced in WebKit 4.0,
- * and deprecated in WebKit 4.0
- */
-#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
-#endif
-
-/*
- * AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0
- *
- * Used on declarations introduced in WebKit 1.0,
- * but later deprecated in WebKit 4.0
- */
-#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
-#endif
-
-/*
- * AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0
- *
- * Used on declarations introduced in WebKit 1.1,
- * but later deprecated in WebKit 4.0
- */
-#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
-#endif
-
-/*
- * AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0
- *
- * Used on declarations introduced in WebKit 1.2,
- * but later deprecated in WebKit 4.0
- */
-#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
-#endif
-
-/*
- * AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0
- *
- * Used on declarations introduced in WebKit 1.3,
- * but later deprecated in WebKit 4.0
- */
-#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
+#define CF_AVAILABLE(_mac, _ios)
#endif
-/*
- * AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0
- *
- * Used on declarations introduced in WebKit 2.0,
- * but later deprecated in WebKit 4.0
- */
-#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
-#endif
-
-/*
- * AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0
- *
- * Used on declarations introduced in WebKit 3.0,
- * but later deprecated in WebKit 4.0
- */
-#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
-#endif
-
-/*
- * AVAILABLE_WEBKIT_VERSION_3_1_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0
- *
- * Used on declarations introduced in WebKit 3.1,
- * but later deprecated in WebKit 4.0
- */
-#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
-#endif
-
-/*
- * DEPRECATED_IN_WEBKIT_VERSION_4_0
- *
- * Used on types deprecated in WebKit 4.0
- */
-#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
-
-
-
-
-
-
-/*
- * AVAILABLE_AFTER_WEBKIT_VERSION_5_1
- *
- * Used on functions introduced after WebKit 5.1
- */
-#define AVAILABLE_AFTER_WEBKIT_VERSION_5_1
-
-/* AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_5_1
- *
- * Used on declarations introduced in WebKit 1.3,
- * but later deprecated after WebKit 5.1
- */
-#define AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_5_1
-
-
#endif /* __WebKitAvailability__ */
diff --git a/Source/JavaScriptCore/API/tests/CompareAndSwapTest.cpp b/Source/JavaScriptCore/API/tests/CompareAndSwapTest.cpp
new file mode 100644
index 000000000..525ebc9cc
--- /dev/null
+++ b/Source/JavaScriptCore/API/tests/CompareAndSwapTest.cpp
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2015 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 "CompareAndSwapTest.h"
+
+#include <stdio.h>
+#include <wtf/Atomics.h>
+#include <wtf/Threading.h>
+
+class Bitmap {
+public:
+ Bitmap() { clearAll(); }
+
+ inline void clearAll();
+ inline bool concurrentTestAndSet(size_t n);
+ inline size_t numBits() const { return words * wordSize; }
+
+private:
+ static const size_t Size = 4096*10;
+
+ static const unsigned wordSize = sizeof(uint8_t) * 8;
+ static const unsigned words = (Size + wordSize - 1) / wordSize;
+ static const uint8_t one = 1;
+
+ uint8_t bits[words];
+};
+
+inline void Bitmap::clearAll()
+{
+ memset(&bits, 0, sizeof(bits));
+}
+
+inline bool Bitmap::concurrentTestAndSet(size_t n)
+{
+ uint8_t mask = one << (n % wordSize);
+ size_t index = n / wordSize;
+ uint8_t* wordPtr = &bits[index];
+ uint8_t oldValue;
+ do {
+ oldValue = *wordPtr;
+ if (oldValue & mask)
+ return true;
+ } while (!WTF::weakCompareAndSwap(wordPtr, oldValue, static_cast<uint8_t>(oldValue | mask)));
+ return false;
+}
+
+struct Data {
+ Bitmap* bitmap;
+ int id;
+ int numThreads;
+};
+
+static void setBitThreadFunc(void* p)
+{
+ Data* data = reinterpret_cast<Data*>(p);
+ Bitmap* bitmap = data->bitmap;
+ size_t numBits = bitmap->numBits();
+
+ // The computed start index here is heuristic that seems to maximize (anecdotally)
+ // the chance for the CAS issue to manifest.
+ size_t start = (numBits * (data->numThreads - data->id)) / data->numThreads;
+
+ printf(" started Thread %d\n", data->id);
+ for (size_t i = start; i < numBits; i++)
+ while (!bitmap->concurrentTestAndSet(i)) { }
+ for (size_t i = 0; i < start; i++)
+ while (!bitmap->concurrentTestAndSet(i)) { }
+
+ printf(" finished Thread %d\n", data->id);
+}
+
+void testCompareAndSwap()
+{
+ Bitmap bitmap;
+ const int numThreads = 5;
+ ThreadIdentifier threadIDs[numThreads];
+ Data data[numThreads];
+
+ WTF::initializeThreading();
+
+ printf("Starting %d threads for CompareAndSwap test. Test should complete without hanging.\n", numThreads);
+ for (int i = 0; i < numThreads; i++) {
+ data[i].bitmap = &bitmap;
+ data[i].id = i;
+ data[i].numThreads = numThreads;
+ std::function<void()> threadFunc = std::bind(setBitThreadFunc, &data[i]);
+ threadIDs[i] = createThread("setBitThreadFunc", threadFunc);
+ }
+
+ printf("Waiting for %d threads to join\n", numThreads);
+ for (int i = 0; i < numThreads; i++)
+ waitForThreadCompletion(threadIDs[i]);
+
+ printf("PASS: CompareAndSwap test completed without a hang\n");
+}
diff --git a/Source/JavaScriptCore/API/tests/CompareAndSwapTest.h b/Source/JavaScriptCore/API/tests/CompareAndSwapTest.h
new file mode 100644
index 000000000..73fa0de13
--- /dev/null
+++ b/Source/JavaScriptCore/API/tests/CompareAndSwapTest.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2015 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 CompareAndSwapTest_h
+#define CompareAndSwapTest_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Regression test for webkit.org/b/142513 */
+void testCompareAndSwap();
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* CompareAndSwapTest_h */
diff --git a/Source/JavaScriptCore/API/tests/CurrentThisInsideBlockGetterTest.h b/Source/JavaScriptCore/API/tests/CurrentThisInsideBlockGetterTest.h
new file mode 100644
index 000000000..f228333c4
--- /dev/null
+++ b/Source/JavaScriptCore/API/tests/CurrentThisInsideBlockGetterTest.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2013 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 CurrentThisInsideBlockGetterTest_h
+#define CurrentThisInsideBlockGetterTest_h
+
+#include <JavaScriptCore/JavaScriptCore.h>
+
+#if JSC_OBJC_API_ENABLED
+
+void currentThisInsideBlockGetterTest();
+
+#endif // JSC_OBJC_API_ENABLED
+
+
+#endif // CurrentThisInsideBlockGetterTest_h
diff --git a/Source/JavaScriptCore/API/tests/CustomGlobalObjectClassTest.c b/Source/JavaScriptCore/API/tests/CustomGlobalObjectClassTest.c
new file mode 100644
index 000000000..62e63978e
--- /dev/null
+++ b/Source/JavaScriptCore/API/tests/CustomGlobalObjectClassTest.c
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2014 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. ``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
+ * 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 "CustomGlobalObjectClassTest.h"
+
+#include <JavaScriptCore/JSObjectRefPrivate.h>
+#include <JavaScriptCore/JavaScriptCore.h>
+#include <stdio.h>
+
+extern bool assertTrue(bool value, const char* message);
+
+static bool executedCallback = false;
+
+static JSValueRef jsDoSomething(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argc, const JSValueRef args[], JSValueRef* exception)
+{
+ (void)function;
+ (void)thisObject;
+ (void)argc;
+ (void)args;
+ (void)exception;
+ executedCallback = true;
+ return JSValueMakeNull(ctx);
+}
+
+static JSStaticFunction bridgedFunctions[] = {
+ {"doSomething", jsDoSomething, kJSPropertyAttributeDontDelete},
+ {0, 0, 0},
+};
+
+static JSClassRef bridgedObjectClass = NULL;
+static JSClassDefinition bridgedClassDef;
+
+static JSClassRef jsClassRef()
+{
+ if (!bridgedObjectClass) {
+ bridgedClassDef = kJSClassDefinitionEmpty;
+ bridgedClassDef.className = "BridgedObject";
+ bridgedClassDef.staticFunctions = bridgedFunctions;
+ bridgedObjectClass = JSClassCreate(&bridgedClassDef);
+ }
+ return bridgedObjectClass;
+}
+
+void customGlobalObjectClassTest()
+{
+ JSClassRef bridgedObjectJsClassRef = jsClassRef();
+ JSGlobalContextRef globalContext = JSGlobalContextCreate(bridgedObjectJsClassRef);
+
+ JSObjectRef globalObj = JSContextGetGlobalObject(globalContext);
+
+ JSPropertyNameArrayRef propertyNames = JSObjectCopyPropertyNames(globalContext, globalObj);
+ size_t propertyCount = JSPropertyNameArrayGetCount(propertyNames);
+ assertTrue(propertyCount == 1, "Property count == 1");
+
+ JSStringRef propertyNameRef = JSPropertyNameArrayGetNameAtIndex(propertyNames, 0);
+ size_t propertyNameLength = JSStringGetLength(propertyNameRef);
+ size_t bufferSize = sizeof(char) * (propertyNameLength + 1);
+ char* buffer = (char*)malloc(bufferSize);
+ JSStringGetUTF8CString(propertyNameRef, buffer, bufferSize);
+ buffer[propertyNameLength] = '\0';
+ assertTrue(!strncmp(buffer, "doSomething", propertyNameLength), "First property name is doSomething");
+ free(buffer);
+
+ bool hasMethod = JSObjectHasProperty(globalContext, globalObj, propertyNameRef);
+ assertTrue(hasMethod, "Property found by name");
+
+ JSValueRef doSomethingProperty =
+ JSObjectGetProperty(globalContext, globalObj, propertyNameRef, NULL);
+ assertTrue(!JSValueIsUndefined(globalContext, doSomethingProperty), "Property is defined");
+
+ bool globalObjectClassMatchesClassRef = JSValueIsObjectOfClass(globalContext, globalObj, bridgedObjectJsClassRef);
+ assertTrue(globalObjectClassMatchesClassRef, "Global object is the right class");
+
+ JSStringRef script = JSStringCreateWithUTF8CString("doSomething();");
+ JSEvaluateScript(globalContext, script, NULL, NULL, 1, NULL);
+ JSStringRelease(script);
+
+ assertTrue(executedCallback, "Executed custom global object callback");
+}
+
+void globalObjectSetPrototypeTest()
+{
+ JSClassDefinition definition = kJSClassDefinitionEmpty;
+ definition.className = "Global";
+ JSClassRef global = JSClassCreate(&definition);
+ JSGlobalContextRef context = JSGlobalContextCreate(global);
+ JSObjectRef object = JSContextGetGlobalObject(context);
+
+ JSObjectRef above = JSObjectMake(context, 0, 0);
+ JSStringRef test = JSStringCreateWithUTF8CString("test");
+ JSValueRef value = JSValueMakeString(context, test);
+ JSObjectSetProperty(context, above, test, value, kJSPropertyAttributeDontEnum, 0);
+
+ JSObjectSetPrototype(context, object, above);
+ JSStringRef script = JSStringCreateWithUTF8CString("test === \"test\"");
+ JSValueRef result = JSEvaluateScript(context, script, 0, 0, 0, 0);
+
+ assertTrue(JSValueToBoolean(context, result), "test === \"test\"");
+
+ JSStringRelease(test);
+ JSStringRelease(script);
+}
+
+void globalObjectPrivatePropertyTest()
+{
+ JSClassDefinition definition = kJSClassDefinitionEmpty;
+ definition.className = "Global";
+ JSClassRef global = JSClassCreate(&definition);
+ JSGlobalContextRef context = JSGlobalContextCreate(global);
+ JSObjectRef globalObject = JSContextGetGlobalObject(context);
+
+ JSStringRef privateName = JSStringCreateWithUTF8CString("private");
+ JSValueRef privateValue = JSValueMakeString(context, privateName);
+ assertTrue(JSObjectSetPrivateProperty(context, globalObject, privateName, privateValue), "JSObjectSetPrivateProperty succeeded");
+ JSValueRef result = JSObjectGetPrivateProperty(context, globalObject, privateName);
+ assertTrue(JSValueIsStrictEqual(context, privateValue, result), "privateValue === \"private\"");
+
+ assertTrue(JSObjectDeletePrivateProperty(context, globalObject, privateName), "JSObjectDeletePrivateProperty succeeded");
+ result = JSObjectGetPrivateProperty(context, globalObject, privateName);
+ assertTrue(JSValueIsNull(context, result), "Deleted private property is indeed no longer present");
+
+ JSStringRelease(privateName);
+}
diff --git a/Source/JavaScriptCore/API/tests/CustomGlobalObjectClassTest.h b/Source/JavaScriptCore/API/tests/CustomGlobalObjectClassTest.h
new file mode 100644
index 000000000..86914ca6f
--- /dev/null
+++ b/Source/JavaScriptCore/API/tests/CustomGlobalObjectClassTest.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2014 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. ``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
+ * 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 CustomGlobalObjectClassTest_h
+#define CustomGlobalObjectClassTest_h
+
+void customGlobalObjectClassTest(void);
+void globalObjectSetPrototypeTest(void);
+void globalObjectPrivatePropertyTest(void);
+
+#endif // CustomGlobalObjectClassTest_h
diff --git a/Source/JavaScriptCore/API/tests/DateTests.h b/Source/JavaScriptCore/API/tests/DateTests.h
new file mode 100644
index 000000000..eeb47a165
--- /dev/null
+++ b/Source/JavaScriptCore/API/tests/DateTests.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#import <JavaScriptCore/JavaScriptCore.h>
+
+#if JSC_OBJC_API_ENABLED
+
+void runDateTests();
+
+#endif // JSC_OBJC_API_ENABLED
diff --git a/Source/JavaScriptCore/API/tests/ExecutionTimeLimitTest.cpp b/Source/JavaScriptCore/API/tests/ExecutionTimeLimitTest.cpp
new file mode 100644
index 000000000..fc8cc10aa
--- /dev/null
+++ b/Source/JavaScriptCore/API/tests/ExecutionTimeLimitTest.cpp
@@ -0,0 +1,374 @@
+/*
+ * Copyright (C) 2015 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 "ExecutionTimeLimitTest.h"
+
+#include "InitializeThreading.h"
+#include "JSContextRefPrivate.h"
+#include "JavaScriptCore.h"
+#include "Options.h"
+#include <chrono>
+#include <wtf/CurrentTime.h>
+#include <wtf/text/StringBuilder.h>
+
+using namespace std::chrono;
+using JSC::Options;
+
+static JSGlobalContextRef context = nullptr;
+
+static JSValueRef currentCPUTimeAsJSFunctionCallback(JSContextRef ctx, JSObjectRef functionObject, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ UNUSED_PARAM(functionObject);
+ UNUSED_PARAM(thisObject);
+ UNUSED_PARAM(argumentCount);
+ UNUSED_PARAM(arguments);
+ UNUSED_PARAM(exception);
+
+ ASSERT(JSContextGetGlobalContext(ctx) == context);
+ return JSValueMakeNumber(ctx, currentCPUTime().count() / 1000000.);
+}
+
+bool shouldTerminateCallbackWasCalled = false;
+static bool shouldTerminateCallback(JSContextRef, void*)
+{
+ shouldTerminateCallbackWasCalled = true;
+ return true;
+}
+
+bool cancelTerminateCallbackWasCalled = false;
+static bool cancelTerminateCallback(JSContextRef, void*)
+{
+ cancelTerminateCallbackWasCalled = true;
+ return false;
+}
+
+int extendTerminateCallbackCalled = 0;
+static bool extendTerminateCallback(JSContextRef ctx, void*)
+{
+ extendTerminateCallbackCalled++;
+ if (extendTerminateCallbackCalled == 1) {
+ JSContextGroupRef contextGroup = JSContextGetGroup(ctx);
+ JSContextGroupSetExecutionTimeLimit(contextGroup, .200f, extendTerminateCallback, 0);
+ return false;
+ }
+ return true;
+}
+
+struct TierOptions {
+ const char* tier;
+ unsigned timeLimitAdjustmentMillis;
+ const char* optionsStr;
+};
+
+static void testResetAfterTimeout(bool& failed)
+{
+ JSValueRef v = nullptr;
+ JSValueRef exception = nullptr;
+ const char* reentryScript = "100";
+ JSStringRef script = JSStringCreateWithUTF8CString(reentryScript);
+ v = JSEvaluateScript(context, script, nullptr, nullptr, 1, &exception);
+ if (exception) {
+ printf("FAIL: Watchdog timeout was not reset.\n");
+ failed = true;
+ } else if (!JSValueIsNumber(context, v) || JSValueToNumber(context, v, nullptr) != 100) {
+ printf("FAIL: Script result is not as expected.\n");
+ failed = true;
+ }
+}
+
+int testExecutionTimeLimit()
+{
+ static const TierOptions tierOptionsList[] = {
+ { "LLINT", 0, "--useConcurrentJIT=false --useLLInt=true --useJIT=false" },
+ { "Baseline", 0, "--useConcurrentJIT=false --useLLInt=true --useJIT=true --useDFGJIT=false" },
+ { "DFG", 0, "--useConcurrentJIT=false --useLLInt=true --useJIT=true --useDFGJIT=true --useFTLJIT=false" },
+ { "FTL", 200, "--useConcurrentJIT=false --useLLInt=true --useJIT=true --useDFGJIT=true --useFTLJIT=true" },
+ };
+
+ bool failed = false;
+
+ JSC::initializeThreading();
+ Options::initialize(); // Ensure options is initialized first.
+
+ for (auto tierOptions : tierOptionsList) {
+ StringBuilder savedOptionsBuilder;
+ Options::dumpAllOptionsInALine(savedOptionsBuilder);
+
+ Options::setOptions(tierOptions.optionsStr);
+
+ unsigned tierAdjustmentMillis = tierOptions.timeLimitAdjustmentMillis;
+ double timeLimit;
+
+ context = JSGlobalContextCreateInGroup(nullptr, nullptr);
+
+ JSContextGroupRef contextGroup = JSContextGetGroup(context);
+ JSObjectRef globalObject = JSContextGetGlobalObject(context);
+ ASSERT(JSValueIsObject(context, globalObject));
+
+ JSValueRef exception = nullptr;
+
+ JSStringRef currentCPUTimeStr = JSStringCreateWithUTF8CString("currentCPUTime");
+ JSObjectRef currentCPUTimeFunction = JSObjectMakeFunctionWithCallback(context, currentCPUTimeStr, currentCPUTimeAsJSFunctionCallback);
+ JSObjectSetProperty(context, globalObject, currentCPUTimeStr, currentCPUTimeFunction, kJSPropertyAttributeNone, nullptr);
+ JSStringRelease(currentCPUTimeStr);
+
+ /* Test script timeout: */
+ timeLimit = (100 + tierAdjustmentMillis) / 1000.0;
+ JSContextGroupSetExecutionTimeLimit(contextGroup, timeLimit, shouldTerminateCallback, 0);
+ {
+ unsigned timeAfterWatchdogShouldHaveFired = 300 + tierAdjustmentMillis;
+
+ StringBuilder scriptBuilder;
+ scriptBuilder.append("function foo() { var startTime = currentCPUTime(); while (true) { for (var i = 0; i < 1000; i++); if (currentCPUTime() - startTime > ");
+ scriptBuilder.appendNumber(timeAfterWatchdogShouldHaveFired / 1000.0);
+ scriptBuilder.append(") break; } } foo();");
+
+ JSStringRef script = JSStringCreateWithUTF8CString(scriptBuilder.toString().utf8().data());
+ exception = nullptr;
+ shouldTerminateCallbackWasCalled = false;
+ auto startTime = currentCPUTime();
+ JSEvaluateScript(context, script, nullptr, nullptr, 1, &exception);
+ auto endTime = currentCPUTime();
+
+ if (((endTime - startTime) < milliseconds(timeAfterWatchdogShouldHaveFired)) && shouldTerminateCallbackWasCalled)
+ printf("PASS: %s script timed out as expected.\n", tierOptions.tier);
+ else {
+ if ((endTime - startTime) >= milliseconds(timeAfterWatchdogShouldHaveFired))
+ printf("FAIL: %s script did not time out as expected.\n", tierOptions.tier);
+ if (!shouldTerminateCallbackWasCalled)
+ printf("FAIL: %s script timeout callback was not called.\n", tierOptions.tier);
+ failed = true;
+ }
+
+ if (!exception) {
+ printf("FAIL: %s TerminatedExecutionException was not thrown.\n", tierOptions.tier);
+ failed = true;
+ }
+
+ testResetAfterTimeout(failed);
+ }
+
+ /* Test script timeout with tail calls: */
+ timeLimit = (100 + tierAdjustmentMillis) / 1000.0;
+ JSContextGroupSetExecutionTimeLimit(contextGroup, timeLimit, shouldTerminateCallback, 0);
+ {
+ unsigned timeAfterWatchdogShouldHaveFired = 300 + tierAdjustmentMillis;
+
+ StringBuilder scriptBuilder;
+ scriptBuilder.append("var startTime = currentCPUTime();"
+ "function recurse(i) {"
+ "'use strict';"
+ "if (i % 1000 === 0) {"
+ "if (currentCPUTime() - startTime >");
+ scriptBuilder.appendNumber(timeAfterWatchdogShouldHaveFired / 1000.0);
+ scriptBuilder.append(" ) { return; }");
+ scriptBuilder.append(" }");
+ scriptBuilder.append(" return recurse(i + 1); }");
+ scriptBuilder.append("recurse(0);");
+
+ JSStringRef script = JSStringCreateWithUTF8CString(scriptBuilder.toString().utf8().data());
+ exception = nullptr;
+ shouldTerminateCallbackWasCalled = false;
+ auto startTime = currentCPUTime();
+ JSEvaluateScript(context, script, nullptr, nullptr, 1, &exception);
+ auto endTime = currentCPUTime();
+
+ if (((endTime - startTime) < milliseconds(timeAfterWatchdogShouldHaveFired)) && shouldTerminateCallbackWasCalled)
+ printf("PASS: %s script with infinite tail calls timed out as expected .\n", tierOptions.tier);
+ else {
+ if ((endTime - startTime) >= milliseconds(timeAfterWatchdogShouldHaveFired))
+ printf("FAIL: %s script with infinite tail calls did not time out as expected.\n", tierOptions.tier);
+ if (!shouldTerminateCallbackWasCalled)
+ printf("FAIL: %s script with infinite tail calls' timeout callback was not called.\n", tierOptions.tier);
+ failed = true;
+ }
+
+ if (!exception) {
+ printf("FAIL: %s TerminatedExecutionException was not thrown.\n", tierOptions.tier);
+ failed = true;
+ }
+
+ testResetAfterTimeout(failed);
+ }
+
+ /* Test the script timeout's TerminatedExecutionException should NOT be catchable: */
+ timeLimit = (100 + tierAdjustmentMillis) / 1000.0;
+ JSContextGroupSetExecutionTimeLimit(contextGroup, timeLimit, shouldTerminateCallback, 0);
+ {
+ unsigned timeAfterWatchdogShouldHaveFired = 300 + tierAdjustmentMillis;
+
+ StringBuilder scriptBuilder;
+ scriptBuilder.append("function foo() { var startTime = currentCPUTime(); try { while (true) { for (var i = 0; i < 1000; i++); if (currentCPUTime() - startTime > ");
+ scriptBuilder.appendNumber(timeAfterWatchdogShouldHaveFired / 1000.0);
+ scriptBuilder.append(") break; } } catch(e) { } } foo();");
+
+ JSStringRef script = JSStringCreateWithUTF8CString(scriptBuilder.toString().utf8().data());
+ exception = nullptr;
+ shouldTerminateCallbackWasCalled = false;
+
+ auto startTime = currentCPUTime();
+ JSEvaluateScript(context, script, nullptr, nullptr, 1, &exception);
+ auto endTime = currentCPUTime();
+
+ if (((endTime - startTime) >= milliseconds(timeAfterWatchdogShouldHaveFired)) || !shouldTerminateCallbackWasCalled) {
+ if (!((endTime - startTime) < milliseconds(timeAfterWatchdogShouldHaveFired)))
+ printf("FAIL: %s script did not time out as expected.\n", tierOptions.tier);
+ if (!shouldTerminateCallbackWasCalled)
+ printf("FAIL: %s script timeout callback was not called.\n", tierOptions.tier);
+ failed = true;
+ }
+
+ if (exception)
+ printf("PASS: %s TerminatedExecutionException was not catchable as expected.\n", tierOptions.tier);
+ else {
+ printf("FAIL: %s TerminatedExecutionException was caught.\n", tierOptions.tier);
+ failed = true;
+ }
+
+ testResetAfterTimeout(failed);
+ }
+
+ /* Test script timeout with no callback: */
+ timeLimit = (100 + tierAdjustmentMillis) / 1000.0;
+ JSContextGroupSetExecutionTimeLimit(contextGroup, timeLimit, 0, 0);
+ {
+ unsigned timeAfterWatchdogShouldHaveFired = 300 + tierAdjustmentMillis;
+
+ StringBuilder scriptBuilder;
+ scriptBuilder.append("function foo() { var startTime = currentCPUTime(); while (true) { for (var i = 0; i < 1000; i++); if (currentCPUTime() - startTime > ");
+ scriptBuilder.appendNumber(timeAfterWatchdogShouldHaveFired / 1000.0);
+ scriptBuilder.append(") break; } } foo();");
+
+ JSStringRef script = JSStringCreateWithUTF8CString(scriptBuilder.toString().utf8().data());
+ exception = nullptr;
+ shouldTerminateCallbackWasCalled = false;
+
+ auto startTime = currentCPUTime();
+ JSEvaluateScript(context, script, nullptr, nullptr, 1, &exception);
+ auto endTime = currentCPUTime();
+
+ if (((endTime - startTime) < milliseconds(timeAfterWatchdogShouldHaveFired)) && !shouldTerminateCallbackWasCalled)
+ printf("PASS: %s script timed out as expected when no callback is specified.\n", tierOptions.tier);
+ else {
+ if ((endTime - startTime) >= milliseconds(timeAfterWatchdogShouldHaveFired))
+ printf("FAIL: %s script did not time out as expected when no callback is specified.\n", tierOptions.tier);
+ else
+ printf("FAIL: %s script called stale callback function.\n", tierOptions.tier);
+ failed = true;
+ }
+
+ if (!exception) {
+ printf("FAIL: %s TerminatedExecutionException was not thrown.\n", tierOptions.tier);
+ failed = true;
+ }
+
+ testResetAfterTimeout(failed);
+ }
+
+ /* Test script timeout cancellation: */
+ timeLimit = (100 + tierAdjustmentMillis) / 1000.0;
+ JSContextGroupSetExecutionTimeLimit(contextGroup, timeLimit, cancelTerminateCallback, 0);
+ {
+ unsigned timeAfterWatchdogShouldHaveFired = 300 + tierAdjustmentMillis;
+
+ StringBuilder scriptBuilder;
+ scriptBuilder.append("function foo() { var startTime = currentCPUTime(); while (true) { for (var i = 0; i < 1000; i++); if (currentCPUTime() - startTime > ");
+ scriptBuilder.appendNumber(timeAfterWatchdogShouldHaveFired / 1000.0);
+ scriptBuilder.append(") break; } } foo();");
+
+ JSStringRef script = JSStringCreateWithUTF8CString(scriptBuilder.toString().utf8().data());
+ exception = nullptr;
+ cancelTerminateCallbackWasCalled = false;
+
+ auto startTime = currentCPUTime();
+ JSEvaluateScript(context, script, nullptr, nullptr, 1, &exception);
+ auto endTime = currentCPUTime();
+
+ if (((endTime - startTime) >= milliseconds(timeAfterWatchdogShouldHaveFired)) && cancelTerminateCallbackWasCalled && !exception)
+ printf("PASS: %s script timeout was cancelled as expected.\n", tierOptions.tier);
+ else {
+ if (((endTime - startTime) < milliseconds(timeAfterWatchdogShouldHaveFired)) || exception)
+ printf("FAIL: %s script timeout was not cancelled.\n", tierOptions.tier);
+ if (!cancelTerminateCallbackWasCalled)
+ printf("FAIL: %s script timeout callback was not called.\n", tierOptions.tier);
+ failed = true;
+ }
+
+ if (exception) {
+ printf("FAIL: %s Unexpected TerminatedExecutionException thrown.\n", tierOptions.tier);
+ failed = true;
+ }
+ }
+
+ /* Test script timeout extension: */
+ timeLimit = (100 + tierAdjustmentMillis) / 1000.0;
+ JSContextGroupSetExecutionTimeLimit(contextGroup, timeLimit, extendTerminateCallback, 0);
+ {
+ unsigned timeBeforeExtendedDeadline = 250 + tierAdjustmentMillis;
+ unsigned timeAfterExtendedDeadline = 600 + tierAdjustmentMillis;
+ unsigned maxBusyLoopTime = 750 + tierAdjustmentMillis;
+
+ StringBuilder scriptBuilder;
+ scriptBuilder.append("function foo() { var startTime = currentCPUTime(); while (true) { for (var i = 0; i < 1000; i++); if (currentCPUTime() - startTime > ");
+ scriptBuilder.appendNumber(maxBusyLoopTime / 1000.0); // in seconds.
+ scriptBuilder.append(") break; } } foo();");
+
+ JSStringRef script = JSStringCreateWithUTF8CString(scriptBuilder.toString().utf8().data());
+ exception = nullptr;
+ extendTerminateCallbackCalled = 0;
+
+ auto startTime = currentCPUTime();
+ JSEvaluateScript(context, script, nullptr, nullptr, 1, &exception);
+ auto endTime = currentCPUTime();
+ auto deltaTime = endTime - startTime;
+
+ if ((deltaTime >= milliseconds(timeBeforeExtendedDeadline)) && (deltaTime < milliseconds(timeAfterExtendedDeadline)) && (extendTerminateCallbackCalled == 2) && exception)
+ printf("PASS: %s script timeout was extended as expected.\n", tierOptions.tier);
+ else {
+ if (deltaTime < milliseconds(timeBeforeExtendedDeadline))
+ printf("FAIL: %s script timeout was not extended as expected.\n", tierOptions.tier);
+ else if (deltaTime >= milliseconds(timeAfterExtendedDeadline))
+ printf("FAIL: %s script did not timeout.\n", tierOptions.tier);
+
+ if (extendTerminateCallbackCalled < 1)
+ printf("FAIL: %s script timeout callback was not called.\n", tierOptions.tier);
+ if (extendTerminateCallbackCalled < 2)
+ printf("FAIL: %s script timeout callback was not called after timeout extension.\n", tierOptions.tier);
+
+ if (!exception)
+ printf("FAIL: %s TerminatedExecutionException was not thrown during timeout extension test.\n", tierOptions.tier);
+
+ failed = true;
+ }
+ }
+
+ JSGlobalContextRelease(context);
+
+ Options::setOptions(savedOptionsBuilder.toString().ascii().data());
+ }
+
+ return failed;
+}
diff --git a/Source/JavaScriptCore/API/tests/ExecutionTimeLimitTest.h b/Source/JavaScriptCore/API/tests/ExecutionTimeLimitTest.h
new file mode 100644
index 000000000..8294a86a6
--- /dev/null
+++ b/Source/JavaScriptCore/API/tests/ExecutionTimeLimitTest.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2015 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 ExecutionTimeLimitTest_h
+#define ExecutionTimeLimitTest_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Returns 1 if failures were encountered. Else, returns 0. */
+int testExecutionTimeLimit();
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* ExecutionTimeLimitTest_h */
diff --git a/Source/JavaScriptCore/API/tests/GlobalContextWithFinalizerTest.cpp b/Source/JavaScriptCore/API/tests/GlobalContextWithFinalizerTest.cpp
new file mode 100644
index 000000000..7023bc365
--- /dev/null
+++ b/Source/JavaScriptCore/API/tests/GlobalContextWithFinalizerTest.cpp
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2015 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 "GlobalContextWithFinalizerTest.h"
+
+#include "JavaScriptCore.h"
+#include <wtf/DataLog.h>
+
+static bool failed = true;
+
+static void finalize(JSObjectRef)
+{
+ failed = false;
+}
+
+int testGlobalContextWithFinalizer()
+{
+ JSClassDefinition def = kJSClassDefinitionEmpty;
+ def.className = "testClass";
+ def.finalize = finalize;
+ JSClassRef classRef = JSClassCreate(&def);
+
+ JSGlobalContextRef ref = JSGlobalContextCreateInGroup(nullptr, classRef);
+ JSGlobalContextRelease(ref);
+ JSClassRelease(classRef);
+
+ if (failed)
+ printf("FAIL: JSGlobalContextRef did not call its JSClassRef finalizer.\n");
+ else
+ printf("PASS: JSGlobalContextRef called its JSClassRef finalizer as expected.\n");
+
+ return failed;
+}
diff --git a/Source/JavaScriptCore/API/tests/GlobalContextWithFinalizerTest.h b/Source/JavaScriptCore/API/tests/GlobalContextWithFinalizerTest.h
new file mode 100644
index 000000000..55b439fff
--- /dev/null
+++ b/Source/JavaScriptCore/API/tests/GlobalContextWithFinalizerTest.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2015 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 GlobalContextWithFinalizerTest_h
+#define GlobalContextWithFinalizerTest_h
+
+#include "JSContextRefPrivate.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Returns 1 if failures were encountered. Else, returns 0. */
+int testGlobalContextWithFinalizer();
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* GlobalContextWithFinalizerTest_h */
diff --git a/Source/JavaScriptCore/API/tests/JSExportTests.h b/Source/JavaScriptCore/API/tests/JSExportTests.h
new file mode 100644
index 000000000..9d501ee7e
--- /dev/null
+++ b/Source/JavaScriptCore/API/tests/JSExportTests.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#import <Foundation/Foundation.h>
+#import <JavaScriptCore/JavaScriptCore.h>
+
+#if JSC_OBJC_API_ENABLED
+
+void runJSExportTests();
+
+#endif // JSC_OBJC_API_ENABLED
+
diff --git a/Source/JavaScriptCore/API/tests/JSNode.c b/Source/JavaScriptCore/API/tests/JSNode.c
index d9a40bea6..d0a0dc3ec 100644
--- a/Source/JavaScriptCore/API/tests/JSNode.c
+++ b/Source/JavaScriptCore/API/tests/JSNode.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
@@ -23,6 +23,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include <wtf/Platform.h>
+
#include "JSNode.h"
#include "JSNodeList.h"
#include "JSObjectRef.h"
diff --git a/Source/JavaScriptCore/API/tests/JSNode.h b/Source/JavaScriptCore/API/tests/JSNode.h
index 7725733ca..a6aee2f7b 100644
--- a/Source/JavaScriptCore/API/tests/JSNode.h
+++ b/Source/JavaScriptCore/API/tests/JSNode.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
diff --git a/Source/JavaScriptCore/API/tests/JSNodeList.c b/Source/JavaScriptCore/API/tests/JSNodeList.c
index 61d7041a4..f037e094a 100644
--- a/Source/JavaScriptCore/API/tests/JSNodeList.c
+++ b/Source/JavaScriptCore/API/tests/JSNodeList.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
@@ -23,6 +23,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include <wtf/Platform.h>
+
#include "JSNode.h"
#include "JSNodeList.h"
#include "JSObjectRef.h"
diff --git a/Source/JavaScriptCore/API/tests/JSNodeList.h b/Source/JavaScriptCore/API/tests/JSNodeList.h
index f9309142e..d3eb52bb9 100644
--- a/Source/JavaScriptCore/API/tests/JSNodeList.h
+++ b/Source/JavaScriptCore/API/tests/JSNodeList.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
diff --git a/Source/JavaScriptCore/API/tests/Node.c b/Source/JavaScriptCore/API/tests/Node.c
index 913da0a2a..db687e952 100644
--- a/Source/JavaScriptCore/API/tests/Node.c
+++ b/Source/JavaScriptCore/API/tests/Node.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
diff --git a/Source/JavaScriptCore/API/tests/Node.h b/Source/JavaScriptCore/API/tests/Node.h
index e9250b3ae..41b5d493a 100644
--- a/Source/JavaScriptCore/API/tests/Node.h
+++ b/Source/JavaScriptCore/API/tests/Node.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
diff --git a/Source/JavaScriptCore/API/tests/NodeList.c b/Source/JavaScriptCore/API/tests/NodeList.c
index ae4c17062..69f4cd5c4 100644
--- a/Source/JavaScriptCore/API/tests/NodeList.c
+++ b/Source/JavaScriptCore/API/tests/NodeList.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
diff --git a/Source/JavaScriptCore/API/tests/NodeList.h b/Source/JavaScriptCore/API/tests/NodeList.h
index 25b95bf4d..020b76f59 100644
--- a/Source/JavaScriptCore/API/tests/NodeList.h
+++ b/Source/JavaScriptCore/API/tests/NodeList.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
diff --git a/Source/JavaScriptCore/API/tests/PingPongStackOverflowTest.cpp b/Source/JavaScriptCore/API/tests/PingPongStackOverflowTest.cpp
new file mode 100644
index 000000000..33f0772b3
--- /dev/null
+++ b/Source/JavaScriptCore/API/tests/PingPongStackOverflowTest.cpp
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2015 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 "PingPongStackOverflowTest.h"
+
+#include "InitializeThreading.h"
+#include "JSContextRefPrivate.h"
+#include "JavaScriptCore.h"
+#include "Options.h"
+#include <wtf/text/StringBuilder.h>
+
+using JSC::Options;
+
+static JSGlobalContextRef context = nullptr;
+static int nativeRecursionCount = 0;
+
+static bool PingPongStackOverflowObject_hasInstance(JSContextRef context, JSObjectRef constructor, JSValueRef possibleValue, JSValueRef* exception)
+{
+ UNUSED_PARAM(context);
+ UNUSED_PARAM(constructor);
+
+ JSStringRef hasInstanceName = JSStringCreateWithUTF8CString("hasInstance");
+ JSValueRef hasInstance = JSObjectGetProperty(context, constructor, hasInstanceName, exception);
+ JSStringRelease(hasInstanceName);
+ if (!hasInstance)
+ return false;
+
+ int countAtEntry = nativeRecursionCount++;
+
+ JSValueRef result = 0;
+ if (nativeRecursionCount < 100) {
+ JSObjectRef function = JSValueToObject(context, hasInstance, exception);
+ result = JSObjectCallAsFunction(context, function, constructor, 1, &possibleValue, exception);
+ } else {
+ StringBuilder builder;
+ builder.append("dummy.valueOf([0]");
+ for (int i = 1; i < 35000; i++) {
+ builder.append(", [");
+ builder.appendNumber(i);
+ builder.append("]");
+ }
+ builder.append(");");
+
+ JSStringRef script = JSStringCreateWithUTF8CString(builder.toString().utf8().data());
+ result = JSEvaluateScript(context, script, NULL, NULL, 1, exception);
+ JSStringRelease(script);
+ }
+
+ --nativeRecursionCount;
+ if (nativeRecursionCount != countAtEntry)
+ printf(" ERROR: PingPongStackOverflow test saw a recursion count mismatch\n");
+
+ return result && JSValueToBoolean(context, result);
+}
+
+JSClassDefinition PingPongStackOverflowObject_definition = {
+ 0,
+ kJSClassAttributeNone,
+
+ "PingPongStackOverflowObject",
+ NULL,
+
+ NULL,
+ NULL,
+
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ PingPongStackOverflowObject_hasInstance,
+ NULL,
+};
+
+static JSClassRef PingPongStackOverflowObject_class(JSContextRef context)
+{
+ UNUSED_PARAM(context);
+
+ static JSClassRef jsClass;
+ if (!jsClass)
+ jsClass = JSClassCreate(&PingPongStackOverflowObject_definition);
+
+ return jsClass;
+}
+
+// This tests tests a stack overflow on VM reentry into a JS function from a native function
+// after ping-pong'ing back and forth between JS and native functions multiple times.
+// This test should not hang or crash.
+int testPingPongStackOverflow()
+{
+ bool failed = false;
+
+ JSC::initializeThreading();
+ Options::initialize(); // Ensure options is initialized first.
+
+ auto origReservedZoneSize = Options::reservedZoneSize();
+ auto origErrorModeReservedZoneSize = Options::errorModeReservedZoneSize();
+ auto origUseLLInt = Options::useLLInt();
+ auto origMaxPerThreadStackUsage = Options::maxPerThreadStackUsage();
+
+ Options::reservedZoneSize() = 128 * KB;
+ Options::errorModeReservedZoneSize() = 64 * KB;
+#if ENABLE(JIT)
+ // Normally, we want to disable the LLINT to force the use of JITted code which is necessary for
+ // reproducing the regression in https://bugs.webkit.org/show_bug.cgi?id=148749. However, we only
+ // want to do this if the LLINT isn't the only available execution engine.
+ Options::useLLInt() = false;
+#endif
+
+ const char* scriptString =
+ "var count = 0;" \
+ "PingPongStackOverflowObject.hasInstance = function f() {" \
+ " return (undefined instanceof PingPongStackOverflowObject);" \
+ "};" \
+ "PingPongStackOverflowObject.__proto__ = undefined;" \
+ "undefined instanceof PingPongStackOverflowObject;";
+
+ JSValueRef scriptResult = nullptr;
+ JSValueRef exception = nullptr;
+ JSStringRef script = JSStringCreateWithUTF8CString(scriptString);
+
+ nativeRecursionCount = 0;
+ context = JSGlobalContextCreateInGroup(nullptr, nullptr);
+
+ JSObjectRef globalObject = JSContextGetGlobalObject(context);
+ ASSERT(JSValueIsObject(context, globalObject));
+
+ JSObjectRef PingPongStackOverflowObject = JSObjectMake(context, PingPongStackOverflowObject_class(context), NULL);
+ JSStringRef PingPongStackOverflowObjectString = JSStringCreateWithUTF8CString("PingPongStackOverflowObject");
+ JSObjectSetProperty(context, globalObject, PingPongStackOverflowObjectString, PingPongStackOverflowObject, kJSPropertyAttributeNone, NULL);
+ JSStringRelease(PingPongStackOverflowObjectString);
+
+ unsigned stackSize = 32 * KB;
+ Options::maxPerThreadStackUsage() = stackSize + Options::reservedZoneSize();
+
+ exception = nullptr;
+ scriptResult = JSEvaluateScript(context, script, nullptr, nullptr, 1, &exception);
+
+ if (!exception) {
+ printf("FAIL: PingPongStackOverflowError not thrown in PingPongStackOverflow test\n");
+ failed = true;
+ } else if (nativeRecursionCount) {
+ printf("FAIL: Unbalanced native recursion count: %d in PingPongStackOverflow test\n", nativeRecursionCount);
+ failed = true;
+ } else {
+ printf("PASS: PingPongStackOverflow test.\n");
+ }
+
+ Options::reservedZoneSize() = origReservedZoneSize;
+ Options::errorModeReservedZoneSize() = origErrorModeReservedZoneSize;
+ Options::useLLInt() = origUseLLInt;
+ Options::maxPerThreadStackUsage() = origMaxPerThreadStackUsage;
+
+ return failed;
+}
diff --git a/Source/JavaScriptCore/API/tests/PingPongStackOverflowTest.h b/Source/JavaScriptCore/API/tests/PingPongStackOverflowTest.h
new file mode 100644
index 000000000..7f5911bcf
--- /dev/null
+++ b/Source/JavaScriptCore/API/tests/PingPongStackOverflowTest.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2015 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 PingPongStackOverflowTest_h
+#define PingPongStackOverflowTest_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int testPingPongStackOverflow();
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* PingPongStackOverflowTest_h */
diff --git a/Source/JavaScriptCore/API/tests/Regress141275.h b/Source/JavaScriptCore/API/tests/Regress141275.h
new file mode 100644
index 000000000..bf3492afa
--- /dev/null
+++ b/Source/JavaScriptCore/API/tests/Regress141275.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+#import <Foundation/Foundation.h>
+#import <JavaScriptCore/JavaScriptCore.h>
+
+#if JSC_OBJC_API_ENABLED
+
+void runRegress141275();
+
+#endif // JSC_OBJC_API_ENABLED
+
diff --git a/Source/JavaScriptCore/API/tests/Regress141809.h b/Source/JavaScriptCore/API/tests/Regress141809.h
new file mode 100644
index 000000000..43b099c94
--- /dev/null
+++ b/Source/JavaScriptCore/API/tests/Regress141809.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+#import <Foundation/Foundation.h>
+#import <JavaScriptCore/JavaScriptCore.h>
+
+#if JSC_OBJC_API_ENABLED
+
+void runRegress141809();
+
+#endif // JSC_OBJC_API_ENABLED
+
diff --git a/Source/JavaScriptCore/API/tests/minidom.c b/Source/JavaScriptCore/API/tests/minidom.c
index 8614e51e9..02b41a9c7 100644
--- a/Source/JavaScriptCore/API/tests/minidom.c
+++ b/Source/JavaScriptCore/API/tests/minidom.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006 Apple Inc. All rights reserved.
* Copyright (C) 2007 Alp Toker <alp@atoker.com>
*
* Redistribution and use in source and binary forms, with or without
@@ -11,10 +11,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
@@ -24,6 +24,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include <wtf/Platform.h>
+
#include "JSContextRef.h"
#include "JSNode.h"
#include "JSObjectRef.h"
@@ -105,6 +107,7 @@ static char* createStringWithContentsOfFile(const char* fileName)
FILE* f = fopen(fileName, "r");
if (!f) {
fprintf(stderr, "Could not open file: %s\n", fileName);
+ free(buffer);
return 0;
}
diff --git a/Source/JavaScriptCore/API/tests/minidom.js b/Source/JavaScriptCore/API/tests/minidom.js
index 480896052..85134d7cb 100644
--- a/Source/JavaScriptCore/API/tests/minidom.js
+++ b/Source/JavaScriptCore/API/tests/minidom.js
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +10,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
diff --git a/Source/JavaScriptCore/API/tests/testapi.c b/Source/JavaScriptCore/API/tests/testapi.c
index be18b2bf7..cbf9daf18 100644
--- a/Source/JavaScriptCore/API/tests/testapi.c
+++ b/Source/JavaScriptCore/API/tests/testapi.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006, 2015 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,19 +10,21 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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.
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include <wtf/Platform.h>
+
#include "JavaScriptCore.h"
#include "JSBasePrivate.h"
#include "JSContextRefPrivate.h"
@@ -33,34 +35,21 @@
#define ASSERT_DISABLED 0
#include <wtf/Assertions.h>
-#if PLATFORM(MAC) || PLATFORM(IOS)
-#include <mach/mach.h>
-#include <mach/mach_time.h>
-#include <sys/time.h>
-#endif
-
#if OS(WINDOWS)
#include <windows.h>
#endif
-#if COMPILER(MSVC)
-
-#include <wtf/MathExtras.h>
-
-static double nan(const char*)
-{
- return std::numeric_limits<double>::quiet_NaN();
-}
-
-using std::isinf;
-using std::isnan;
-
-#endif
+#include "CompareAndSwapTest.h"
+#include "CustomGlobalObjectClassTest.h"
+#include "ExecutionTimeLimitTest.h"
+#include "GlobalContextWithFinalizerTest.h"
+#include "PingPongStackOverflowTest.h"
#if JSC_OBJC_API_ENABLED
void testObjectiveCAPI(void);
#endif
+bool assertTrue(bool value, const char* message);
extern void JSSynchronousGarbageCollectForDebugging(JSContextRef);
static JSGlobalContextRef context;
@@ -93,11 +82,13 @@ static void assertEqualsAsUTF8String(JSValueRef value, const char* expectedValue
size_t jsSize = JSStringGetMaximumUTF8CStringSize(valueAsString);
char* jsBuffer = (char*)malloc(jsSize);
JSStringGetUTF8CString(valueAsString, jsBuffer, jsSize);
-
+
unsigned i;
for (i = 0; jsBuffer[i]; i++) {
if (jsBuffer[i] != expectedValue[i]) {
fprintf(stderr, "assertEqualsAsUTF8String failed at character %d: %c(%d) != %c(%d)\n", i, jsBuffer[i], jsBuffer[i], expectedValue[i], expectedValue[i]);
+ fprintf(stderr, "value: %s\n", jsBuffer);
+ fprintf(stderr, "expectedValue: %s\n", expectedValue);
failed = 1;
}
}
@@ -132,7 +123,11 @@ static void assertEqualsAsCharactersPtr(JSValueRef value, const char* expectedVa
}
if (jsLength != (size_t)cfLength) {
- fprintf(stderr, "assertEqualsAsCharactersPtr failed: jsLength(%ld) != cfLength(%ld)\n", jsLength, cfLength);
+#if OS(WINDOWS)
+ fprintf(stderr, "assertEqualsAsCharactersPtr failed: jsLength(%Iu) != cfLength(%Iu)\n", jsLength, (size_t)cfLength);
+#else
+ fprintf(stderr, "assertEqualsAsCharactersPtr failed: jsLength(%zu) != cfLength(%zu)\n", jsLength, (size_t)cfLength);
+#endif
failed = 1;
}
@@ -582,7 +577,6 @@ static JSValueRef EvilExceptionObject_convertToType(JSContextRef context, JSObje
break;
default:
return JSValueMakeNull(context);
- break;
}
JSValueRef func = JSObjectGetProperty(context, object, funcName, exception);
@@ -904,10 +898,8 @@ static void globalObject_initialize(JSContextRef context, JSObjectRef object)
// Ensure that an execution context is passed in
ASSERT(context);
- // Ensure that the global object is set to the object that we were passed
JSObjectRef globalObject = JSContextGetGlobalObject(context);
ASSERT(globalObject);
- ASSERT(object == globalObject);
// Ensure that the standard global properties have been set on the global object
JSStringRef array = JSStringCreateWithUTF8CString("Array");
@@ -966,6 +958,7 @@ static JSStaticValue globalObject_staticValues[] = {
static JSStaticFunction globalObject_staticFunctions[] = {
{ "globalStaticFunction", globalObject_call, kJSPropertyAttributeNone },
+ { "globalStaticFunction2", globalObject_call, kJSPropertyAttributeNone },
{ "gc", functionGC, kJSPropertyAttributeNone },
{ 0, 0, 0 }
};
@@ -990,7 +983,7 @@ static void makeGlobalNumberValue(JSContextRef context) {
v = NULL;
}
-static bool assertTrue(bool value, const char* message)
+bool assertTrue(bool value, const char* message)
{
if (!value) {
if (message)
@@ -1043,85 +1036,104 @@ static bool checkForCycleInPrototypeChain()
return result;
}
-static void checkConstnessInJSObjectNames()
+static JSValueRef valueToObjectExceptionCallAsFunction(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
- JSStaticFunction fun;
- fun.name = "something";
- JSStaticValue val;
- val.name = "something";
+ UNUSED_PARAM(function);
+ UNUSED_PARAM(thisObject);
+ UNUSED_PARAM(argumentCount);
+ UNUSED_PARAM(arguments);
+ JSValueRef jsUndefined = JSValueMakeUndefined(JSContextGetGlobalContext(ctx));
+ JSValueToObject(JSContextGetGlobalContext(ctx), jsUndefined, exception);
+
+ return JSValueMakeUndefined(ctx);
}
-
-#if PLATFORM(MAC) || PLATFORM(IOS)
-static double currentCPUTime()
+static bool valueToObjectExceptionTest()
{
- mach_msg_type_number_t infoCount = THREAD_BASIC_INFO_COUNT;
- thread_basic_info_data_t info;
+ JSGlobalContextRef testContext;
+ JSClassDefinition globalObjectClassDefinition = kJSClassDefinitionEmpty;
+ globalObjectClassDefinition.initialize = globalObject_initialize;
+ globalObjectClassDefinition.staticValues = globalObject_staticValues;
+ globalObjectClassDefinition.staticFunctions = globalObject_staticFunctions;
+ globalObjectClassDefinition.attributes = kJSClassAttributeNoAutomaticPrototype;
+ JSClassRef globalObjectClass = JSClassCreate(&globalObjectClassDefinition);
+ testContext = JSGlobalContextCreateInGroup(NULL, globalObjectClass);
+ JSObjectRef globalObject = JSContextGetGlobalObject(testContext);
- /* Get thread information */
- mach_port_t threadPort = mach_thread_self();
- thread_info(threadPort, THREAD_BASIC_INFO, (thread_info_t)(&info), &infoCount);
- mach_port_deallocate(mach_task_self(), threadPort);
+ JSStringRef valueToObject = JSStringCreateWithUTF8CString("valueToObject");
+ JSObjectRef valueToObjectFunction = JSObjectMakeFunctionWithCallback(testContext, valueToObject, valueToObjectExceptionCallAsFunction);
+ JSObjectSetProperty(testContext, globalObject, valueToObject, valueToObjectFunction, kJSPropertyAttributeNone, NULL);
+ JSStringRelease(valueToObject);
+
+ JSStringRef test = JSStringCreateWithUTF8CString("valueToObject();");
+ JSEvaluateScript(testContext, test, NULL, NULL, 1, NULL);
- double time = info.user_time.seconds + info.user_time.microseconds / 1000000.;
- time += info.system_time.seconds + info.system_time.microseconds / 1000000.;
+ JSStringRelease(test);
+ JSClassRelease(globalObjectClass);
+ JSGlobalContextRelease(testContext);
- return time;
+ return true;
}
-static JSValueRef currentCPUTime_callAsFunction(JSContextRef ctx, JSObjectRef functionObject, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+static bool globalContextNameTest()
{
- UNUSED_PARAM(functionObject);
- UNUSED_PARAM(thisObject);
- UNUSED_PARAM(argumentCount);
- UNUSED_PARAM(arguments);
- UNUSED_PARAM(exception);
+ bool result = true;
+ JSGlobalContextRef context = JSGlobalContextCreate(0);
- ASSERT(JSContextGetGlobalContext(ctx) == context);
- return JSValueMakeNumber(ctx, currentCPUTime());
-}
+ JSStringRef str = JSGlobalContextCopyName(context);
+ result &= assertTrue(!str, "Default context name is NULL");
-bool shouldTerminateCallbackWasCalled = false;
-static bool shouldTerminateCallback(JSContextRef ctx, void* context)
-{
- UNUSED_PARAM(ctx);
- UNUSED_PARAM(context);
- shouldTerminateCallbackWasCalled = true;
- return true;
-}
+ JSStringRef name1 = JSStringCreateWithUTF8CString("name1");
+ JSStringRef name2 = JSStringCreateWithUTF8CString("name2");
-bool cancelTerminateCallbackWasCalled = false;
-static bool cancelTerminateCallback(JSContextRef ctx, void* context)
-{
- UNUSED_PARAM(ctx);
- UNUSED_PARAM(context);
- cancelTerminateCallbackWasCalled = true;
- return false;
+ JSGlobalContextSetName(context, name1);
+ JSStringRef fetchName1 = JSGlobalContextCopyName(context);
+ JSGlobalContextSetName(context, name2);
+ JSStringRef fetchName2 = JSGlobalContextCopyName(context);
+ JSGlobalContextSetName(context, NULL);
+ JSStringRef fetchName3 = JSGlobalContextCopyName(context);
+
+ result &= assertTrue(JSStringIsEqual(name1, fetchName1), "Unexpected Context name");
+ result &= assertTrue(JSStringIsEqual(name2, fetchName2), "Unexpected Context name");
+ result &= assertTrue(!JSStringIsEqual(fetchName1, fetchName2), "Unexpected Context name");
+ result &= assertTrue(!fetchName3, "Unexpected Context name");
+
+ JSStringRelease(name1);
+ JSStringRelease(name2);
+ JSStringRelease(fetchName1);
+ JSStringRelease(fetchName2);
+
+ return result;
}
-int extendTerminateCallbackCalled = 0;
-static bool extendTerminateCallback(JSContextRef ctx, void* context)
+static void checkConstnessInJSObjectNames()
{
- UNUSED_PARAM(context);
- extendTerminateCallbackCalled++;
- if (extendTerminateCallbackCalled == 1) {
- JSContextGroupRef contextGroup = JSContextGetGroup(ctx);
- JSContextGroupSetExecutionTimeLimit(contextGroup, .200f, extendTerminateCallback, 0);
- return false;
- }
- return true;
+ JSStaticFunction fun;
+ fun.name = "something";
+ JSStaticValue val;
+ val.name = "something";
}
-#endif /* PLATFORM(MAC) || PLATFORM(IOS) */
int main(int argc, char* argv[])
{
#if OS(WINDOWS)
+#if defined(_M_X64) || defined(__x86_64__)
+ // The VS2013 runtime has a bug where it mis-detects AVX-capable processors
+ // if the feature has been disabled in firmware. This causes us to crash
+ // in some of the math functions. For now, we disable those optimizations
+ // because Microsoft is not going to fix the problem in VS2013.
+ // FIXME: http://webkit.org/b/141449: Remove this workaround when we switch to VS2015+.
+ _set_FMA3_enable(0);
+#endif
+
// Cygwin calls ::SetErrorMode(SEM_FAILCRITICALERRORS), which we will inherit. This is bad for
// testing/debugging, as it causes the post-mortem debugger not to be invoked. We reset the
// error mode here to work around Cygwin's behavior. See <http://webkit.org/b/55222>.
::SetErrorMode(0);
#endif
+ testCompareAndSwap();
+
#if JSC_OBJC_API_ENABLED
testObjectiveCAPI();
#endif
@@ -1171,6 +1183,13 @@ int main(int argc, char* argv[])
JSObjectRef jsObjectNoProto = JSObjectMake(context, NULL, NULL);
JSObjectSetPrototype(context, jsObjectNoProto, JSValueMakeNull(context));
+ JSObjectSetPrivate(globalObject, (void*)123);
+ if (JSObjectGetPrivate(globalObject) != (void*)123) {
+ printf("FAIL: Didn't return private data when set by JSObjectSetPrivate().\n");
+ failed = 1;
+ } else
+ printf("PASS: returned private data when set by JSObjectSetPrivate().\n");
+
// FIXME: test funny utf8 characters
JSStringRef jsEmptyIString = JSStringCreateWithUTF8CString("");
JSValueRef jsEmptyString = JSValueMakeString(context, jsEmptyIString);
@@ -1228,6 +1247,8 @@ int main(int argc, char* argv[])
ASSERT(!JSValueIsBoolean(context, NULL));
ASSERT(!JSValueIsObject(context, NULL));
+ ASSERT(!JSValueIsArray(context, NULL));
+ ASSERT(!JSValueIsDate(context, NULL));
ASSERT(!JSValueIsString(context, NULL));
ASSERT(!JSValueIsNumber(context, NULL));
ASSERT(!JSValueIsUndefined(context, NULL));
@@ -1388,8 +1409,10 @@ int main(int argc, char* argv[])
} 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 = JSStringCreateWithUTF8CString("({get a(){ throw '';}})");
+ JSValueRef unstringifiableObj = JSEvaluateScript(context, str, NULL, NULL, 1, NULL);
+ JSStringRelease(str);
str = JSValueCreateJSONString(context, unstringifiableObj, 4, 0);
if (str) {
@@ -1572,7 +1595,27 @@ int main(int argc, char* argv[])
ASSERT(!JSObjectMakeFunction(context, NULL, 0, NULL, functionBody, NULL, 1, &exception));
ASSERT(JSValueIsObject(context, exception));
v = JSObjectGetProperty(context, JSValueToObject(context, exception, NULL), line, NULL);
- assertEqualsAsNumber(v, 1);
+ assertEqualsAsNumber(v, 2);
+ JSStringRelease(functionBody);
+ JSStringRelease(line);
+
+ exception = NULL;
+ functionBody = JSStringCreateWithUTF8CString("rreturn Array;");
+ line = JSStringCreateWithUTF8CString("line");
+ ASSERT(!JSObjectMakeFunction(context, NULL, 0, NULL, functionBody, NULL, -42, &exception));
+ ASSERT(JSValueIsObject(context, exception));
+ v = JSObjectGetProperty(context, JSValueToObject(context, exception, NULL), line, NULL);
+ assertEqualsAsNumber(v, 2);
+ JSStringRelease(functionBody);
+ JSStringRelease(line);
+
+ exception = NULL;
+ functionBody = JSStringCreateWithUTF8CString("// Line one.\nrreturn Array;");
+ line = JSStringCreateWithUTF8CString("line");
+ ASSERT(!JSObjectMakeFunction(context, NULL, 0, NULL, functionBody, NULL, 1, &exception));
+ ASSERT(JSValueIsObject(context, exception));
+ v = JSObjectGetProperty(context, JSValueToObject(context, exception, NULL), line, NULL);
+ assertEqualsAsNumber(v, 3);
JSStringRelease(functionBody);
JSStringRelease(line);
@@ -1606,7 +1649,7 @@ int main(int argc, char* argv[])
JSStringRelease(functionBody);
string = JSValueToStringCopy(context, function, NULL);
- assertEqualsAsUTF8String(JSValueMakeString(context, string), "function foo(foo) { return foo;\n}");
+ assertEqualsAsUTF8String(JSValueMakeString(context, string), "function foo(foo) {\nreturn foo;\n}");
JSStringRelease(string);
JSStringRef print = JSStringCreateWithUTF8CString("print");
@@ -1737,6 +1780,28 @@ int main(int argc, char* argv[])
ASSERT(JSValueIsEqual(context, v, o, NULL));
JSStringRelease(script);
+ script = JSStringCreateWithUTF8CString("[ ]");
+ v = JSEvaluateScript(context, script, NULL, NULL, 1, NULL);
+ ASSERT(JSValueIsArray(context, v));
+ JSStringRelease(script);
+
+ script = JSStringCreateWithUTF8CString("new Date");
+ v = JSEvaluateScript(context, script, NULL, NULL, 1, NULL);
+ ASSERT(JSValueIsDate(context, v));
+ JSStringRelease(script);
+
+ exception = NULL;
+ script = JSStringCreateWithUTF8CString("rreturn Array;");
+ JSStringRef sourceURL = JSStringCreateWithUTF8CString("file:///foo/bar.js");
+ JSStringRef sourceURLKey = JSStringCreateWithUTF8CString("sourceURL");
+ JSEvaluateScript(context, script, NULL, sourceURL, 1, &exception);
+ ASSERT(exception);
+ v = JSObjectGetProperty(context, JSValueToObject(context, exception, NULL), sourceURLKey, NULL);
+ assertEqualsAsUTF8String(v, "file:///foo/bar.js");
+ JSStringRelease(script);
+ JSStringRelease(sourceURL);
+ JSStringRelease(sourceURLKey);
+
// Verify that creating a constructor for a class with no static functions does not trigger
// an assert inside putDirect or lead to a crash during GC. <https://bugs.webkit.org/show_bug.cgi?id=25785>
nullDefinition = kJSClassDefinitionEmpty;
@@ -1765,6 +1830,7 @@ int main(int argc, char* argv[])
}
JSStringRelease(script);
+ exception = NULL;
result = scriptObject ? JSScriptEvaluate(context, scriptObject, 0, &exception) : 0;
if (result && JSValueIsUndefined(context, result))
printf("PASS: Test script executed successfully.\n");
@@ -1781,158 +1847,53 @@ int main(int argc, char* argv[])
free(scriptUTF8);
}
-#if PLATFORM(MAC) || PLATFORM(IOS)
- JSStringRef currentCPUTimeStr = JSStringCreateWithUTF8CString("currentCPUTime");
- JSObjectRef currentCPUTimeFunction = JSObjectMakeFunctionWithCallback(context, currentCPUTimeStr, currentCPUTime_callAsFunction);
- JSObjectSetProperty(context, globalObject, currentCPUTimeStr, currentCPUTimeFunction, kJSPropertyAttributeNone, NULL);
- JSStringRelease(currentCPUTimeStr);
-
- /* Test script timeout: */
- JSContextGroupSetExecutionTimeLimit(contextGroup, .10f, shouldTerminateCallback, 0);
- {
- const char* loopForeverScript = "var startTime = currentCPUTime(); while (true) { if (currentCPUTime() - startTime > .150) break; } ";
- JSStringRef script = JSStringCreateWithUTF8CString(loopForeverScript);
- double startTime;
- double endTime;
- exception = NULL;
- shouldTerminateCallbackWasCalled = false;
- startTime = currentCPUTime();
- v = JSEvaluateScript(context, script, NULL, NULL, 1, &exception);
- endTime = currentCPUTime();
-
- if (((endTime - startTime) < .150f) && shouldTerminateCallbackWasCalled)
- printf("PASS: script timed out as expected.\n");
- else {
- if (!((endTime - startTime) < .150f))
- printf("FAIL: script did not timed out as expected.\n");
- if (!shouldTerminateCallbackWasCalled)
- printf("FAIL: script timeout callback was not called.\n");
- failed = true;
- }
-
- if (!exception) {
- printf("FAIL: TerminatedExecutionException was not thrown.\n");
- failed = true;
- }
- }
-
- /* Test the script timeout's TerminatedExecutionException should NOT be catchable: */
- JSContextGroupSetExecutionTimeLimit(contextGroup, 0.10f, shouldTerminateCallback, 0);
- {
- const char* loopForeverScript = "var startTime = currentCPUTime(); try { while (true) { if (currentCPUTime() - startTime > .150) break; } } catch(e) { }";
- JSStringRef script = JSStringCreateWithUTF8CString(loopForeverScript);
- double startTime;
- double endTime;
- exception = NULL;
- shouldTerminateCallbackWasCalled = false;
- startTime = currentCPUTime();
- v = JSEvaluateScript(context, script, NULL, NULL, 1, &exception);
- endTime = currentCPUTime();
-
- if (((endTime - startTime) >= .150f) || !shouldTerminateCallbackWasCalled) {
- if (!((endTime - startTime) < .150f))
- printf("FAIL: script did not timed out as expected.\n");
- if (!shouldTerminateCallbackWasCalled)
- printf("FAIL: script timeout callback was not called.\n");
- failed = true;
- }
-
- if (exception)
- printf("PASS: TerminatedExecutionException was not catchable as expected.\n");
- else {
- printf("FAIL: TerminatedExecutionException was caught.\n");
- failed = true;
- }
- }
-
- /* Test script timeout with no callback: */
- JSContextGroupSetExecutionTimeLimit(contextGroup, .10f, 0, 0);
+ // Check Promise is not exposed.
{
- const char* loopForeverScript = "var startTime = currentCPUTime(); while (true) { if (currentCPUTime() - startTime > .150) break; } ";
- JSStringRef script = JSStringCreateWithUTF8CString(loopForeverScript);
- double startTime;
- double endTime;
- exception = NULL;
- startTime = currentCPUTime();
- v = JSEvaluateScript(context, script, NULL, NULL, 1, &exception);
- endTime = currentCPUTime();
-
- if (((endTime - startTime) < .150f) && shouldTerminateCallbackWasCalled)
- printf("PASS: script timed out as expected when no callback is specified.\n");
- else {
- if (!((endTime - startTime) < .150f))
- printf("FAIL: script did not timed out as expected when no callback is specified.\n");
- failed = true;
+ JSObjectRef globalObject = JSContextGetGlobalObject(context);
+ {
+ JSStringRef promiseProperty = JSStringCreateWithUTF8CString("Promise");
+ ASSERT(JSObjectHasProperty(context, globalObject, promiseProperty));
+ JSStringRelease(promiseProperty);
}
-
- if (!exception) {
- printf("FAIL: TerminatedExecutionException was not thrown.\n");
- failed = true;
+ {
+ JSStringRef script = JSStringCreateWithUTF8CString("typeof Promise");
+ JSStringRef function = JSStringCreateWithUTF8CString("function");
+ JSValueRef value = JSEvaluateScript(context, script, NULL, NULL, 1, NULL);
+ ASSERT(JSValueIsString(context, value));
+ JSStringRef valueAsString = JSValueToStringCopy(context, value, NULL);
+ ASSERT(JSStringIsEqual(valueAsString, function));
+ JSStringRelease(valueAsString);
+ JSStringRelease(function);
+ JSStringRelease(script);
}
+ printf("PASS: Promise is exposed under JSContext API.\n");
}
- /* Test script timeout cancellation: */
- JSContextGroupSetExecutionTimeLimit(contextGroup, 0.10f, cancelTerminateCallback, 0);
+ // Check microtasks.
{
- const char* loopForeverScript = "var startTime = currentCPUTime(); while (true) { if (currentCPUTime() - startTime > .150) break; } ";
- JSStringRef script = JSStringCreateWithUTF8CString(loopForeverScript);
- double startTime;
- double endTime;
- exception = NULL;
- startTime = currentCPUTime();
- v = JSEvaluateScript(context, script, NULL, NULL, 1, &exception);
- endTime = currentCPUTime();
-
- if (((endTime - startTime) >= .150f) && cancelTerminateCallbackWasCalled && !exception)
- printf("PASS: script timeout was cancelled as expected.\n");
- else {
- if (((endTime - startTime) < .150) || exception)
- printf("FAIL: script timeout was not cancelled.\n");
- if (!cancelTerminateCallbackWasCalled)
- printf("FAIL: script timeout callback was not called.\n");
- failed = true;
- }
-
- if (exception) {
- printf("FAIL: Unexpected TerminatedExecutionException thrown.\n");
- failed = true;
+ JSGlobalContextRef context = JSGlobalContextCreateInGroup(NULL, NULL);
+ {
+ JSObjectRef globalObject = JSContextGetGlobalObject(context);
+ JSValueRef exception;
+ JSStringRef code = JSStringCreateWithUTF8CString("result = 0; Promise.resolve(42).then(function (value) { result = value; });");
+ JSStringRef file = JSStringCreateWithUTF8CString("");
+ assertTrue(JSEvaluateScript(context, code, globalObject, file, 1, &exception), "An exception should not be thrown");
+ JSStringRelease(code);
+ JSStringRelease(file);
+
+ JSStringRef resultProperty = JSStringCreateWithUTF8CString("result");
+ ASSERT(JSObjectHasProperty(context, globalObject, resultProperty));
+
+ JSValueRef resultValue = JSObjectGetProperty(context, globalObject, resultProperty, &exception);
+ assertEqualsAsNumber(resultValue, 42);
+ JSStringRelease(resultProperty);
}
+ JSGlobalContextRelease(context);
}
- /* Test script timeout extension: */
- JSContextGroupSetExecutionTimeLimit(contextGroup, 0.100f, extendTerminateCallback, 0);
- {
- const char* loopForeverScript = "var startTime = currentCPUTime(); while (true) { if (currentCPUTime() - startTime > .500) break; } ";
- JSStringRef script = JSStringCreateWithUTF8CString(loopForeverScript);
- double startTime;
- double endTime;
- double deltaTime;
- exception = NULL;
- startTime = currentCPUTime();
- v = JSEvaluateScript(context, script, NULL, NULL, 1, &exception);
- endTime = currentCPUTime();
- deltaTime = endTime - startTime;
-
- if ((deltaTime >= .300f) && (deltaTime < .500f) && (extendTerminateCallbackCalled == 2) && exception)
- printf("PASS: script timeout was extended as expected.\n");
- else {
- if (deltaTime < .200f)
- printf("FAIL: script timeout was not extended as expected.\n");
- else if (deltaTime >= .500f)
- printf("FAIL: script did not timeout.\n");
-
- if (extendTerminateCallbackCalled < 1)
- printf("FAIL: script timeout callback was not called.\n");
- if (extendTerminateCallbackCalled < 2)
- printf("FAIL: script timeout callback was not called after timeout extension.\n");
-
- if (!exception)
- printf("FAIL: TerminatedExecutionException was not thrown during timeout extension test.\n");
-
- failed = true;
- }
- }
-#endif /* PLATFORM(MAC) || PLATFORM(IOS) */
+ failed = testExecutionTimeLimit() || failed;
+ failed = testGlobalContextWithFinalizer() || failed;
+ failed = testPingPongStackOverflow() || failed;
// Clear out local variables pointing at JSObjectRefs to allow their values to be collected
function = NULL;
@@ -1975,6 +1936,15 @@ int main(int argc, char* argv[])
printf("FAIL: A cycle in a prototype chain can be created.\n");
failed = true;
}
+ if (valueToObjectExceptionTest())
+ printf("PASS: throwException did not crash when handling an error with appendMessageToError set and no codeBlock available.\n");
+
+ if (globalContextNameTest())
+ printf("PASS: global context name behaves as expected.\n");
+
+ customGlobalObjectClassTest();
+ globalObjectSetPrototypeTest();
+ globalObjectPrivatePropertyTest();
if (failed) {
printf("FAIL: Some tests failed.\n");
@@ -1996,6 +1966,7 @@ static char* createStringWithContentsOfFile(const char* fileName)
FILE* f = fopen(fileName, "r");
if (!f) {
fprintf(stderr, "Could not open file: %s\n", fileName);
+ free(buffer);
return 0;
}
@@ -2014,3 +1985,10 @@ static char* createStringWithContentsOfFile(const char* fileName)
return buffer;
}
+
+#if OS(WINDOWS)
+extern "C" __declspec(dllexport) int WINAPI dllLauncherEntryPoint(int argc, const char* argv[])
+{
+ return main(argc, const_cast<char**>(argv));
+}
+#endif
diff --git a/Source/JavaScriptCore/API/tests/testapi.js b/Source/JavaScriptCore/API/tests/testapi.js
index 47c20a830..88d3701c2 100644
--- a/Source/JavaScriptCore/API/tests/testapi.js
+++ b/Source/JavaScriptCore/API/tests/testapi.js
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,17 +10,17 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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.
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
function bludgeonArguments() { if (0) arguments; return function g() {} }
@@ -74,6 +74,20 @@ function globalStaticFunction()
shouldBe("globalStaticValue", 3);
shouldBe("globalStaticFunction()", 4);
+shouldBe("this.globalStaticFunction()", 4);
+
+function globalStaticFunction2() {
+ return 10;
+}
+shouldBe("globalStaticFunction2();", 10);
+this.globalStaticFunction2 = function() { return 20; }
+shouldBe("globalStaticFunction2();", 20);
+shouldBe("this.globalStaticFunction2();", 20);
+
+function iAmNotAStaticFunction() { return 10; }
+shouldBe("iAmNotAStaticFunction();", 10);
+this.iAmNotAStaticFunction = function() { return 20; }
+shouldBe("iAmNotAStaticFunction();", 20);
shouldBe("typeof MyObject", "function"); // our object implements 'call'
MyObject.cantFind = 1;
@@ -253,6 +267,9 @@ shouldThrow("EvilExceptionObject*5");
EvilExceptionObject.toStringExplicit = function f() { return f(); }
shouldThrow("String(EvilExceptionObject)");
+shouldBe("console", "[object Console]");
+shouldBe("typeof console.log", "function");
+
shouldBe("EmptyObject", "[object CallbackObject]");
for (var i = 0; i < 6; ++i)
diff --git a/Source/JavaScriptCore/API/tests/testapi.mm b/Source/JavaScriptCore/API/tests/testapi.mm
deleted file mode 100644
index defb46e70..000000000
--- a/Source/JavaScriptCore/API/tests/testapi.mm
+++ /dev/null
@@ -1,841 +0,0 @@
-/*
- * Copyright (C) 2013 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. ``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
- * 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.
- */
-
-#import <JavaScriptCore/JavaScriptCore.h>
-
-extern "C" void JSSynchronousGarbageCollectForDebugging(JSContextRef);
-
-extern "C" bool _Block_has_signature(id);
-extern "C" const char * _Block_signature(id);
-
-extern int failed;
-extern "C" void testObjectiveCAPI(void);
-
-#if JSC_OBJC_API_ENABLED
-
-@protocol ParentObject <JSExport>
-@end
-
-@interface ParentObject : NSObject<ParentObject>
-+ (NSString *)parentTest;
-@end
-
-@implementation ParentObject
-+ (NSString *)parentTest
-{
- return [self description];
-}
-@end
-
-@protocol TestObject <JSExport>
-@property int variable;
-@property (readonly) int six;
-@property CGPoint point;
-+ (NSString *)classTest;
-+ (NSString *)parentTest;
-- (NSString *)getString;
-JSExportAs(testArgumentTypes,
-- (NSString *)testArgumentTypesWithInt:(int)i double:(double)d boolean:(BOOL)b string:(NSString *)s number:(NSNumber *)n array:(NSArray *)a dictionary:(NSDictionary *)o
-);
-- (void)callback:(JSValue *)function;
-- (void)bogusCallback:(void(^)(int))function;
-@end
-
-@interface TestObject : ParentObject <TestObject>
-@property int six;
-+ (id)testObject;
-@end
-
-@implementation TestObject
-@synthesize variable;
-@synthesize six;
-@synthesize point;
-+ (id)testObject
-{
- return [[TestObject alloc] init];
-}
-+ (NSString *)classTest
-{
- return @"classTest - okay";
-}
-- (NSString *)getString
-{
- return @"42";
-}
-- (NSString *)testArgumentTypesWithInt:(int)i double:(double)d boolean:(BOOL)b string:(NSString *)s number:(NSNumber *)n array:(NSArray *)a dictionary:(NSDictionary *)o
-{
- return [NSString stringWithFormat:@"%d,%g,%d,%@,%d,%@,%@", i, d, b==YES?true:false,s,[n intValue],a[1],o[@"x"]];
-}
-- (void)callback:(JSValue *)function
-{
- [function callWithArguments:[NSArray arrayWithObject:[NSNumber numberWithInt:42]]];
-}
-- (void)bogusCallback:(void(^)(int))function
-{
- function(42);
-}
-@end
-
-bool testXYZTested = false;
-
-@protocol TextXYZ <JSExport>
-@property int x;
-@property (readonly) int y;
-@property (assign) JSValue *onclick;
-@property (assign) JSValue *weakOnclick;
-- (void)test:(NSString *)message;
-@end
-
-@interface TextXYZ : NSObject <TextXYZ>
-@property int x;
-@property int y;
-@property int z;
-- (void)click;
-@end
-
-@implementation TextXYZ {
- JSManagedValue *m_weakOnclickHandler;
- JSManagedValue *m_onclickHandler;
-}
-@synthesize x;
-@synthesize y;
-@synthesize z;
-- (void)test:(NSString *)message
-{
- testXYZTested = [message isEqual:@"test"] && x == 13 & y == 4 && z == 5;
-}
-- (void)setWeakOnclick:(JSValue *)value
-{
- m_weakOnclickHandler = [JSManagedValue managedValueWithValue:value];
-}
-
-- (void)setOnclick:(JSValue *)value
-{
- m_onclickHandler = [JSManagedValue managedValueWithValue:value];
- [value.context.virtualMachine addManagedReference:m_onclickHandler withOwner:self];
-}
-- (JSValue *)weakOnclick
-{
- return [m_weakOnclickHandler value];
-}
-- (JSValue *)onclick
-{
- return [m_onclickHandler value];
-}
-- (void)click
-{
- if (!m_onclickHandler)
- return;
-
- JSValue *function = [m_onclickHandler value];
- [function callWithArguments:[NSArray array]];
-}
-- (void)dealloc
-{
- [[m_onclickHandler value].context.virtualMachine removeManagedReference:m_onclickHandler withOwner:self];
-}
-@end
-
-@class TinyDOMNode;
-
-@protocol TinyDOMNode <JSExport>
-- (void)appendChild:(TinyDOMNode *)child;
-- (NSUInteger)numberOfChildren;
-- (TinyDOMNode *)childAtIndex:(NSUInteger)index;
-- (void)removeChildAtIndex:(NSUInteger)index;
-@end
-
-@interface TinyDOMNode : NSObject<TinyDOMNode>
-+ (JSVirtualMachine *)sharedVirtualMachine;
-+ (void)clearSharedVirtualMachine;
-@end
-
-@implementation TinyDOMNode {
- NSMutableArray *m_children;
-}
-
-static JSVirtualMachine *sharedInstance = nil;
-
-+ (JSVirtualMachine *)sharedVirtualMachine
-{
- if (!sharedInstance)
- sharedInstance = [[JSVirtualMachine alloc] init];
- return sharedInstance;
-}
-
-+ (void)clearSharedVirtualMachine
-{
- sharedInstance = nil;
-}
-
-- (id)init
-{
- self = [super init];
- if (!self)
- return nil;
-
- m_children = [[NSMutableArray alloc] initWithCapacity:0];
-
- return self;
-}
-
-- (void)dealloc
-{
- NSEnumerator *enumerator = [m_children objectEnumerator];
- id nextChild;
- while ((nextChild = [enumerator nextObject]))
- [[TinyDOMNode sharedVirtualMachine] removeManagedReference:nextChild withOwner:self];
-
-#if !__has_feature(objc_arc)
- [super dealloc];
-#endif
-}
-
-- (void)appendChild:(TinyDOMNode *)child
-{
- [[TinyDOMNode sharedVirtualMachine] addManagedReference:child withOwner:self];
- [m_children addObject:child];
-}
-
-- (NSUInteger)numberOfChildren
-{
- return [m_children count];
-}
-
-- (TinyDOMNode *)childAtIndex:(NSUInteger)index
-{
- if (index >= [m_children count])
- return nil;
- return [m_children objectAtIndex:index];
-}
-
-- (void)removeChildAtIndex:(NSUInteger)index
-{
- if (index >= [m_children count])
- return;
- [[TinyDOMNode sharedVirtualMachine] removeManagedReference:[m_children objectAtIndex:index] withOwner:self];
- [m_children removeObjectAtIndex:index];
-}
-
-@end
-
-static void checkResult(NSString *description, bool passed)
-{
- NSLog(@"TEST: \"%@\": %@", description, passed ? @"PASSED" : @"FAILED");
- if (!passed)
- failed = 1;
-}
-
-static bool blockSignatureContainsClass()
-{
- static bool containsClass = ^{
- id block = ^(NSString *string){ return string; };
- return _Block_has_signature(block) && strstr(_Block_signature(block), "NSString");
- }();
- return containsClass;
-}
-
-void testObjectiveCAPI()
-{
- NSLog(@"Testing Objective-C API");
-
- @autoreleasepool {
- JSContext *context = [[JSContext alloc] init];
- JSValue *result = [context evaluateScript:@"2 + 2"];
- checkResult(@"2 + 2", [result isNumber] && [result toInt32] == 4);
- }
-
- @autoreleasepool {
- JSContext *context = [[JSContext alloc] init];
- NSString *result = [NSString stringWithFormat:@"Two plus two is %@", [context evaluateScript:@"2 + 2"]];
- checkResult(@"stringWithFormat", [result isEqual:@"Two plus two is 4"]);
- }
-
- @autoreleasepool {
- JSContext *context = [[JSContext alloc] init];
- context[@"message"] = @"Hello";
- JSValue *result = [context evaluateScript:@"message + ', World!'"];
- checkResult(@"Hello, World!", [result isString] && [result isEqualToObject:@"Hello, World!"]);
- }
-
- @autoreleasepool {
- JSContext *context = [[JSContext alloc] init];
- JSValue *result = [context evaluateScript:@"({ x:42 })"];
- checkResult(@"({ x:42 })", [result isObject] && [result[@"x"] isEqualToObject:@42]);
- id obj = [result toObject];
- checkResult(@"Check dictionary literal", [obj isKindOfClass:[NSDictionary class]]);
- id num = (NSDictionary *)obj[@"x"];
- checkResult(@"Check numeric literal", [num isKindOfClass:[NSNumber class]]);
- }
-
- @autoreleasepool {
- JSContext *context = [[JSContext alloc] init];
- __block int result;
- context[@"blockCallback"] = ^(int value){
- result = value;
- };
- [context evaluateScript:@"blockCallback(42)"];
- checkResult(@"blockCallback", result == 42);
- }
-
- if (blockSignatureContainsClass()) {
- @autoreleasepool {
- JSContext *context = [[JSContext alloc] init];
- __block bool result = false;
- context[@"blockCallback"] = ^(NSString *value){
- result = [@"42" isEqualToString:value] == YES;
- };
- [context evaluateScript:@"blockCallback(42)"];
- checkResult(@"blockCallback(NSString *)", result);
- }
- } else
- NSLog(@"Skipping 'blockCallback(NSString *)' test case");
-
- @autoreleasepool {
- JSContext *context = [[JSContext alloc] init];
- checkResult(@"!context.exception", !context.exception);
- [context evaluateScript:@"!@#$%^&*() THIS IS NOT VALID JAVASCRIPT SYNTAX !@#$%^&*()"];
- checkResult(@"context.exception", context.exception);
- }
-
- @autoreleasepool {
- JSContext *context = [[JSContext alloc] init];
- __block bool caught = false;
- context.exceptionHandler = ^(JSContext *context, JSValue *exception) {
- (void)context;
- (void)exception;
- caught = true;
- };
- [context evaluateScript:@"!@#$%^&*() THIS IS NOT VALID JAVASCRIPT SYNTAX !@#$%^&*()"];
- checkResult(@"JSContext.exceptionHandler", caught);
- }
-
- @autoreleasepool {
- JSContext *context = [[JSContext alloc] init];
- context[@"callback"] = ^{
- JSContext *context = [JSContext currentContext];
- context.exception = [JSValue valueWithNewErrorFromMessage:@"Something went wrong." inContext:context];
- };
- JSValue *result = [context evaluateScript:@"var result; try { callback(); } catch (e) { result = 'Caught exception'; }"];
- checkResult(@"Explicit throw in callback - was caught by JavaScript", [result isEqualToObject:@"Caught exception"]);
- checkResult(@"Explicit throw in callback - not thrown to Objective-C", !context.exception);
- }
-
- @autoreleasepool {
- JSContext *context = [[JSContext alloc] init];
- context[@"callback"] = ^{
- JSContext *context = [JSContext currentContext];
- [context evaluateScript:@"!@#$%^&*() THIS IS NOT VALID JAVASCRIPT SYNTAX !@#$%^&*()"];
- };
- JSValue *result = [context evaluateScript:@"var result; try { callback(); } catch (e) { result = 'Caught exception'; }"];
- checkResult(@"Implicit throw in callback - was caught by JavaScript", [result isEqualToObject:@"Caught exception"]);
- checkResult(@"Implicit throw in callback - not thrown to Objective-C", !context.exception);
- }
-
- @autoreleasepool {
- JSContext *context = [[JSContext alloc] init];
- [context evaluateScript:
- @"function sum(array) { \
- var result = 0; \
- for (var i in array) \
- result += array[i]; \
- return result; \
- }"];
- JSValue *array = [JSValue valueWithObject:@[@13, @2, @7] inContext:context];
- JSValue *sumFunction = context[@"sum"];
- JSValue *result = [sumFunction callWithArguments:@[ array ]];
- checkResult(@"sum([13, 2, 7])", [result toInt32] == 22);
- }
-
- @autoreleasepool {
- JSContext *context = [[JSContext alloc] init];
- JSValue *mulAddFunction = [context evaluateScript:
- @"(function(array, object) { \
- var result = []; \
- for (var i in array) \
- result.push(array[i] * object.x + object.y); \
- return result; \
- })"];
- JSValue *result = [mulAddFunction callWithArguments:@[ @[ @2, @4, @8 ], @{ @"x":@0.5, @"y":@42 } ]];
- checkResult(@"mulAddFunction", [result isObject] && [[result toString] isEqual:@"43,44,46"]);
- }
-
- @autoreleasepool {
- JSContext *context = [[JSContext alloc] init];
- JSValue *array = [JSValue valueWithNewArrayInContext:context];
- checkResult(@"arrayLengthEmpty", [[array[@"length"] toNumber] unsignedIntegerValue] == 0);
- JSValue *value1 = [JSValue valueWithInt32:42 inContext:context];
- JSValue *value2 = [JSValue valueWithInt32:24 inContext:context];
- NSUInteger lowIndex = 5;
- NSUInteger maxLength = UINT_MAX;
-
- [array setValue:value1 atIndex:lowIndex];
- checkResult(@"array.length after put to low index", [[array[@"length"] toNumber] unsignedIntegerValue] == (lowIndex + 1));
-
- [array setValue:value1 atIndex:(maxLength - 1)];
- checkResult(@"array.length after put to maxLength - 1", [[array[@"length"] toNumber] unsignedIntegerValue] == maxLength);
-
- [array setValue:value2 atIndex:maxLength];
- checkResult(@"array.length after put to maxLength", [[array[@"length"] toNumber] unsignedIntegerValue] == maxLength);
-
- [array setValue:value2 atIndex:(maxLength + 1)];
- checkResult(@"array.length after put to maxLength + 1", [[array[@"length"] toNumber] unsignedIntegerValue] == maxLength);
-
- checkResult(@"valueAtIndex:0 is undefined", [[array valueAtIndex:0] isUndefined]);
- checkResult(@"valueAtIndex:lowIndex", [[array valueAtIndex:lowIndex] toInt32] == 42);
- checkResult(@"valueAtIndex:maxLength - 1", [[array valueAtIndex:(maxLength - 1)] toInt32] == 42);
- checkResult(@"valueAtIndex:maxLength", [[array valueAtIndex:maxLength] toInt32] == 24);
- checkResult(@"valueAtIndex:maxLength + 1", [[array valueAtIndex:(maxLength + 1)] toInt32] == 24);
- }
-
- @autoreleasepool {
- JSContext *context = [[JSContext alloc] init];
- JSValue *object = [JSValue valueWithNewObjectInContext:context];
-
- object[@"point"] = @{ @"x":@1, @"y":@2 };
- object[@"point"][@"x"] = @3;
- CGPoint point = [object[@"point"] toPoint];
- checkResult(@"toPoint", point.x == 3 && point.y == 2);
-
- object[@{ @"toString":^{ return @"foo"; } }] = @"bar";
- checkResult(@"toString in object literal used as subscript", [[object[@"foo"] toString] isEqual:@"bar"]);
-
- object[[@"foobar" substringToIndex:3]] = @"bar";
- checkResult(@"substring used as subscript", [[object[@"foo"] toString] isEqual:@"bar"]);
- }
-
- @autoreleasepool {
- JSContext *context = [[JSContext alloc] init];
- TextXYZ *testXYZ = [[TextXYZ alloc] init];
- context[@"testXYZ"] = testXYZ;
- testXYZ.x = 3;
- testXYZ.y = 4;
- testXYZ.z = 5;
- [context evaluateScript:@"testXYZ.x = 13; testXYZ.y = 14;"];
- [context evaluateScript:@"testXYZ.test('test')"];
- checkResult(@"TextXYZ - testXYZTested", testXYZTested);
- JSValue *result = [context evaluateScript:@"testXYZ.x + ',' + testXYZ.y + ',' + testXYZ.z"];
- checkResult(@"TextXYZ - result", [result isEqualToObject:@"13,4,undefined"]);
- }
-
- @autoreleasepool {
- JSContext *context = [[JSContext alloc] init];
- [context[@"Object"][@"prototype"] defineProperty:@"getterProperty" descriptor:@{
- JSPropertyDescriptorGetKey:^{
- return [JSContext currentThis][@"x"];
- }
- }];
- JSValue *object = [JSValue valueWithObject:@{ @"x":@101 } inContext:context];
- int result = [object [@"getterProperty"] toInt32];
- checkResult(@"getterProperty", result == 101);
- }
-
- @autoreleasepool {
- JSContext *context = [[JSContext alloc] init];
- context[@"concatenate"] = ^{
- NSArray *arguments = [JSContext currentArguments];
- if (![arguments count])
- return @"";
- NSString *message = [arguments[0] description];
- for (NSUInteger index = 1; index < [arguments count]; ++index)
- message = [NSString stringWithFormat:@"%@ %@", message, arguments[index]];
- return message;
- };
- JSValue *result = [context evaluateScript:@"concatenate('Hello,', 'World!')"];
- checkResult(@"concatenate", [result isEqualToObject:@"Hello, World!"]);
- }
-
- @autoreleasepool {
- JSContext *context = [[JSContext alloc] init];
- context[@"foo"] = @YES;
- checkResult(@"@YES is boolean", [context[@"foo"] isBoolean]);
- JSValue *result = [context evaluateScript:@"typeof foo"];
- checkResult(@"@YES is boolean", [result isEqualToObject:@"boolean"]);
- }
-
- @autoreleasepool {
- JSContext *context = [[JSContext alloc] init];
- TestObject* testObject = [TestObject testObject];
- context[@"testObject"] = testObject;
- JSValue *result = [context evaluateScript:@"String(testObject)"];
- checkResult(@"String(testObject)", [result isEqualToObject:@"[object TestObject]"]);
- }
-
- @autoreleasepool {
- JSContext *context = [[JSContext alloc] init];
- TestObject* testObject = [TestObject testObject];
- context[@"testObject"] = testObject;
- JSValue *result = [context evaluateScript:@"String(testObject.__proto__)"];
- checkResult(@"String(testObject.__proto__)", [result isEqualToObject:@"[object TestObjectPrototype]"]);
- }
-
- @autoreleasepool {
- JSContext *context = [[JSContext alloc] init];
- context[@"TestObject"] = [TestObject class];
- JSValue *result = [context evaluateScript:@"String(TestObject)"];
- checkResult(@"String(TestObject)", [result isEqualToObject:@"[object TestObjectConstructor]"]);
- }
-
- @autoreleasepool {
- JSContext *context = [[JSContext alloc] init];
- JSValue* value = [JSValue valueWithObject:[TestObject class] inContext:context];
- checkResult(@"[value toObject] == [TestObject class]", [value toObject] == [TestObject class]);
- }
-
- @autoreleasepool {
- JSContext *context = [[JSContext alloc] init];
- context[@"TestObject"] = [TestObject class];
- JSValue *result = [context evaluateScript:@"TestObject.parentTest()"];
- checkResult(@"TestObject.parentTest()", [result isEqualToObject:@"TestObject"]);
- }
-
- @autoreleasepool {
- JSContext *context = [[JSContext alloc] init];
- TestObject* testObject = [TestObject testObject];
- context[@"testObjectA"] = testObject;
- context[@"testObjectB"] = testObject;
- JSValue *result = [context evaluateScript:@"testObjectA == testObjectB"];
- checkResult(@"testObjectA == testObjectB", [result isBoolean] && [result toBool]);
- }
-
- @autoreleasepool {
- JSContext *context = [[JSContext alloc] init];
- TestObject* testObject = [TestObject testObject];
- context[@"testObject"] = testObject;
- testObject.point = (CGPoint){3,4};
- JSValue *result = [context evaluateScript:@"var result = JSON.stringify(testObject.point); testObject.point = {x:12,y:14}; result"];
- checkResult(@"testObject.point - result", [result isEqualToObject:@"{\"x\":3,\"y\":4}"]);
- checkResult(@"testObject.point - {x:12,y:14}", testObject.point.x == 12 && testObject.point.y == 14);
- }
-
- @autoreleasepool {
- JSContext *context = [[JSContext alloc] init];
- TestObject* testObject = [TestObject testObject];
- testObject.six = 6;
- context[@"testObject"] = testObject;
- context[@"mul"] = ^(int x, int y){ return x * y; };
- JSValue *result = [context evaluateScript:@"mul(testObject.six, 7)"];
- checkResult(@"mul(testObject.six, 7)", [result isNumber] && [result toInt32] == 42);
- }
-
- @autoreleasepool {
- JSContext *context = [[JSContext alloc] init];
- TestObject* testObject = [TestObject testObject];
- context[@"testObject"] = testObject;
- context[@"testObject"][@"variable"] = @4;
- [context evaluateScript:@"++testObject.variable"];
- checkResult(@"++testObject.variable", testObject.variable == 5);
- }
-
- @autoreleasepool {
- JSContext *context = [[JSContext alloc] init];
- context[@"point"] = @{ @"x":@6, @"y":@7 };
- JSValue *result = [context evaluateScript:@"point.x + ',' + point.y"];
- checkResult(@"point.x + ',' + point.y", [result isEqualToObject:@"6,7"]);
- }
-
- @autoreleasepool {
- JSContext *context = [[JSContext alloc] init];
- context[@"point"] = @{ @"x":@6, @"y":@7 };
- JSValue *result = [context evaluateScript:@"point.x + ',' + point.y"];
- checkResult(@"point.x + ',' + point.y", [result isEqualToObject:@"6,7"]);
- }
-
- @autoreleasepool {
- JSContext *context = [[JSContext alloc] init];
- TestObject* testObject = [TestObject testObject];
- context[@"testObject"] = testObject;
- JSValue *result = [context evaluateScript:@"testObject.getString()"];
- checkResult(@"testObject.getString()", [result isString] && [result toInt32] == 42);
- }
-
- @autoreleasepool {
- JSContext *context = [[JSContext alloc] init];
- TestObject* testObject = [TestObject testObject];
- context[@"testObject"] = testObject;
- JSValue *result = [context evaluateScript:@"testObject.testArgumentTypes(101,0.5,true,'foo',666,[false,'bar',false],{x:'baz'})"];
- checkResult(@"testObject.testArgumentTypes", [result isEqualToObject:@"101,0.5,1,foo,666,bar,baz"]);
- }
-
- @autoreleasepool {
- JSContext *context = [[JSContext alloc] init];
- TestObject* testObject = [TestObject testObject];
- context[@"testObject"] = testObject;
- JSValue *result = [context evaluateScript:@"testObject.getString.call(testObject)"];
- checkResult(@"testObject.getString.call(testObject)", [result isString] && [result toInt32] == 42);
- }
-
- @autoreleasepool {
- JSContext *context = [[JSContext alloc] init];
- TestObject* testObject = [TestObject testObject];
- context[@"testObject"] = testObject;
- checkResult(@"testObject.getString.call({}) pre", !context.exception);
- [context evaluateScript:@"testObject.getString.call({})"];
- checkResult(@"testObject.getString.call({}) post", context.exception);
- }
-
- @autoreleasepool {
- JSContext *context = [[JSContext alloc] init];
- TestObject* testObject = [TestObject testObject];
- context[@"testObject"] = testObject;
- JSValue *result = [context evaluateScript:@"var result = 0; testObject.callback(function(x){ result = x; }); result"];
- checkResult(@"testObject.callback", [result isNumber] && [result toInt32] == 42);
- result = [context evaluateScript:@"testObject.bogusCallback"];
- checkResult(@"testObject.bogusCallback == undefined", [result isUndefined]);
- }
-
- @autoreleasepool {
- JSContext *context = [[JSContext alloc] init];
- TestObject *testObject = [TestObject testObject];
- context[@"testObject"] = testObject;
- JSValue *result = [context evaluateScript:@"Function.prototype.toString.call(testObject.callback)"];
- checkResult(@"Function.prototype.toString", !context.exception && ![result isUndefined]);
- }
-
- @autoreleasepool {
- JSContext *context1 = [[JSContext alloc] init];
- JSContext *context2 = [[JSContext alloc] initWithVirtualMachine:context1.virtualMachine];
- JSValue *value = [JSValue valueWithDouble:42 inContext:context2];
- context1[@"passValueBetweenContexts"] = value;
- JSValue *result = [context1 evaluateScript:@"passValueBetweenContexts"];
- checkResult(@"[value isEqualToObject:result]", [value isEqualToObject:result]);
- }
-
- @autoreleasepool {
- JSContext *context = [[JSContext alloc] init];
- context[@"handleTheDictionary"] = ^(NSDictionary *dict) {
- NSDictionary *expectedDict = @{
- @"foo" : [NSNumber numberWithInt:1],
- @"bar" : @{
- @"baz": [NSNumber numberWithInt:2]
- }
- };
- checkResult(@"recursively convert nested dictionaries", [dict isEqualToDictionary:expectedDict]);
- };
- [context evaluateScript:@"var myDict = { \
- 'foo': 1, \
- 'bar': {'baz': 2} \
- }; \
- handleTheDictionary(myDict);"];
-
- context[@"handleTheArray"] = ^(NSArray *array) {
- NSArray *expectedArray = @[@"foo", @"bar", @[@"baz"]];
- checkResult(@"recursively convert nested arrays", [array isEqualToArray:expectedArray]);
- };
- [context evaluateScript:@"var myArray = ['foo', 'bar', ['baz']]; handleTheArray(myArray);"];
- }
-
- @autoreleasepool {
- JSContext *context = [[JSContext alloc] init];
- TestObject *testObject = [TestObject testObject];
- @autoreleasepool {
- context[@"testObject"] = testObject;
- [context evaluateScript:@"var constructor = Object.getPrototypeOf(testObject).constructor; constructor.prototype = undefined;"];
- [context evaluateScript:@"testObject = undefined"];
- }
-
- JSSynchronousGarbageCollectForDebugging([context JSGlobalContextRef]);
-
- @autoreleasepool {
- context[@"testObject"] = testObject;
- }
- }
-
- @autoreleasepool {
- JSContext *context = [[JSContext alloc] init];
- TextXYZ *testXYZ = [[TextXYZ alloc] init];
-
- @autoreleasepool {
- context[@"testXYZ"] = testXYZ;
-
- [context evaluateScript:@" \
- didClick = false; \
- testXYZ.onclick = function() { \
- didClick = true; \
- }; \
- \
- testXYZ.weakOnclick = function() { \
- return 'foo'; \
- }; \
- "];
- }
-
- @autoreleasepool {
- [testXYZ click];
- JSValue *result = [context evaluateScript:@"didClick"];
- checkResult(@"Event handler onclick", [result toBool]);
- }
-
- JSSynchronousGarbageCollectForDebugging([context JSGlobalContextRef]);
-
- @autoreleasepool {
- JSValue *result = [context evaluateScript:@"testXYZ.onclick"];
- checkResult(@"onclick still around after GC", !([result isNull] || [result isUndefined]));
- }
-
-
- @autoreleasepool {
- JSValue *result = [context evaluateScript:@"testXYZ.weakOnclick"];
- checkResult(@"weakOnclick not around after GC", [result isNull] || [result isUndefined]);
- }
-
- @autoreleasepool {
- [context evaluateScript:@" \
- didClick = false; \
- testXYZ = null; \
- "];
- }
-
- JSSynchronousGarbageCollectForDebugging([context JSGlobalContextRef]);
-
- @autoreleasepool {
- [testXYZ click];
- JSValue *result = [context evaluateScript:@"didClick"];
- checkResult(@"Event handler onclick doesn't fire", ![result toBool]);
- }
- }
-
- @autoreleasepool {
- JSVirtualMachine *vm = [[JSVirtualMachine alloc] init];
- TestObject *testObject = [TestObject testObject];
- JSManagedValue *weakValue;
- @autoreleasepool {
- JSContext *context = [[JSContext alloc] initWithVirtualMachine:vm];
- context[@"testObject"] = testObject;
- weakValue = [[JSManagedValue alloc] initWithValue:context[@"testObject"]];
- }
-
- @autoreleasepool {
- JSContext *context = [[JSContext alloc] initWithVirtualMachine:vm];
- context[@"testObject"] = testObject;
- JSSynchronousGarbageCollectForDebugging([context JSGlobalContextRef]);
- checkResult(@"weak value == nil", ![weakValue value]);
- checkResult(@"root is still alive", ![context[@"testObject"] isUndefined]);
- }
- }
-
- @autoreleasepool {
- JSVirtualMachine *vm = [TinyDOMNode sharedVirtualMachine];
- JSContext *context = [[JSContext alloc] initWithVirtualMachine:vm];
- TinyDOMNode *root = [[TinyDOMNode alloc] init];
- TinyDOMNode *lastNode = root;
- for (NSUInteger i = 0; i < 3; i++) {
- TinyDOMNode *newNode = [[TinyDOMNode alloc] init];
- [lastNode appendChild:newNode];
- lastNode = newNode;
- }
-
- @autoreleasepool {
- context[@"root"] = root;
- context[@"getLastNodeInChain"] = ^(TinyDOMNode *head){
- TinyDOMNode *lastNode = nil;
- while (head) {
- lastNode = head;
- head = [lastNode childAtIndex:0];
- }
- return lastNode;
- };
- [context evaluateScript:@"getLastNodeInChain(root).myCustomProperty = 42;"];
- }
-
- JSSynchronousGarbageCollectForDebugging([context JSGlobalContextRef]);
-
- JSValue *myCustomProperty = [context evaluateScript:@"getLastNodeInChain(root).myCustomProperty"];
- checkResult(@"My custom property == 42", [myCustomProperty isNumber] && [myCustomProperty toInt32] == 42);
-
- [TinyDOMNode clearSharedVirtualMachine];
- }
-
- @autoreleasepool {
- JSVirtualMachine *vm = [TinyDOMNode sharedVirtualMachine];
- JSContext *context = [[JSContext alloc] initWithVirtualMachine:vm];
- TinyDOMNode *root = [[TinyDOMNode alloc] init];
- TinyDOMNode *lastNode = root;
- for (NSUInteger i = 0; i < 3; i++) {
- TinyDOMNode *newNode = [[TinyDOMNode alloc] init];
- [lastNode appendChild:newNode];
- lastNode = newNode;
- }
-
- @autoreleasepool {
- context[@"root"] = root;
- context[@"getLastNodeInChain"] = ^(TinyDOMNode *head){
- TinyDOMNode *lastNode = nil;
- while (head) {
- lastNode = head;
- head = [lastNode childAtIndex:0];
- }
- return lastNode;
- };
- [context evaluateScript:@"getLastNodeInChain(root).myCustomProperty = 42;"];
-
- [root appendChild:[root childAtIndex:0]];
- [root removeChildAtIndex:0];
- }
-
- JSSynchronousGarbageCollectForDebugging([context JSGlobalContextRef]);
-
- JSValue *myCustomProperty = [context evaluateScript:@"getLastNodeInChain(root).myCustomProperty"];
- checkResult(@"duplicate calls to addManagedReference don't cause things to die", [myCustomProperty isNumber] && [myCustomProperty toInt32] == 42);
-
- [TinyDOMNode clearSharedVirtualMachine];
- }
-
- @autoreleasepool {
- JSContext *context = [[JSContext alloc] init];
- JSValue *o = [JSValue valueWithNewObjectInContext:context];
- o[@"foo"] = @"foo";
- JSSynchronousGarbageCollectForDebugging([context JSGlobalContextRef]);
-
- checkResult(@"JSValue correctly protected its internal value", [[o[@"foo"] toString] isEqualToString:@"foo"]);
- }
-
- @autoreleasepool {
- JSContext *context = [[JSContext alloc] init];
- TestObject *testObject = [TestObject testObject];
- context[@"testObject"] = testObject;
- [context evaluateScript:@"testObject.__lookupGetter__('variable').call({})"];
- checkResult(@"Make sure we throw an exception when calling getter on incorrect |this|", context.exception);
- }
-
- @autoreleasepool {
- TestObject *testObject = [TestObject testObject];
- JSManagedValue *managedTestObject;
- @autoreleasepool {
- JSContext *context = [[JSContext alloc] init];
- context[@"testObject"] = testObject;
- managedTestObject = [JSManagedValue managedValueWithValue:context[@"testObject"]];
- [context.virtualMachine addManagedReference:managedTestObject withOwner:testObject];
- }
- }
-}
-
-#else
-
-void testObjectiveCAPI()
-{
-}
-
-#endif