summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/API
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2016-05-24 08:28:08 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2016-05-24 08:28:08 +0000
commita4e969f4965059196ca948db781e52f7cfebf19e (patch)
tree6ca352808c8fdc52006a0f33f6ae3c593b23867d /Source/JavaScriptCore/API
parent41386e9cb918eed93b3f13648cbef387e371e451 (diff)
downloadWebKitGtk-tarball-a4e969f4965059196ca948db781e52f7cfebf19e.tar.gz
webkitgtk-2.12.3webkitgtk-2.12.3
Diffstat (limited to 'Source/JavaScriptCore/API')
-rw-r--r--Source/JavaScriptCore/API/APICallbackFunction.h8
-rw-r--r--Source/JavaScriptCore/API/APICast.h7
-rw-r--r--Source/JavaScriptCore/API/APIShims.h125
-rw-r--r--Source/JavaScriptCore/API/JSAPIWrapperObject.h2
-rw-r--r--Source/JavaScriptCore/API/JSBase.cpp59
-rw-r--r--Source/JavaScriptCore/API/JSBase.h19
-rw-r--r--Source/JavaScriptCore/API/JSBasePrivate.h6
-rw-r--r--Source/JavaScriptCore/API/JSCTestRunnerUtils.cpp19
-rw-r--r--Source/JavaScriptCore/API/JSCTestRunnerUtils.h2
-rw-r--r--Source/JavaScriptCore/API/JSCallbackConstructor.cpp9
-rw-r--r--Source/JavaScriptCore/API/JSCallbackConstructor.h6
-rw-r--r--Source/JavaScriptCore/API/JSCallbackFunction.cpp9
-rw-r--r--Source/JavaScriptCore/API/JSCallbackFunction.h4
-rw-r--r--Source/JavaScriptCore/API/JSCallbackObject.cpp23
-rw-r--r--Source/JavaScriptCore/API/JSCallbackObject.h34
-rw-r--r--Source/JavaScriptCore/API/JSCallbackObjectFunctions.h93
-rw-r--r--Source/JavaScriptCore/API/JSClassRef.cpp30
-rw-r--r--Source/JavaScriptCore/API/JSClassRef.h16
-rw-r--r--Source/JavaScriptCore/API/JSContext.h241
-rw-r--r--Source/JavaScriptCore/API/JSContextInternal.h80
-rw-r--r--Source/JavaScriptCore/API/JSContextPrivate.h57
-rw-r--r--Source/JavaScriptCore/API/JSContextRef.cpp204
-rw-r--r--Source/JavaScriptCore/API/JSContextRef.h12
-rw-r--r--Source/JavaScriptCore/API/JSContextRefInspectorSupport.h43
-rw-r--r--Source/JavaScriptCore/API/JSContextRefInternal.h60
-rw-r--r--Source/JavaScriptCore/API/JSContextRefPrivate.h42
-rw-r--r--Source/JavaScriptCore/API/JSExport.h146
-rw-r--r--Source/JavaScriptCore/API/JSManagedValue.h83
-rw-r--r--Source/JavaScriptCore/API/JSManagedValueInternal.h42
-rw-r--r--Source/JavaScriptCore/API/JSObjectRef.cpp210
-rw-r--r--Source/JavaScriptCore/API/JSObjectRef.h4
-rw-r--r--Source/JavaScriptCore/API/JSProfilerPrivate.cpp50
-rw-r--r--Source/JavaScriptCore/API/JSProfilerPrivate.h63
-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.cpp58
-rw-r--r--Source/JavaScriptCore/API/JSStringRef.cpp18
-rw-r--r--Source/JavaScriptCore/API/JSStringRef.h6
-rw-r--r--Source/JavaScriptCore/API/JSStringRefBSTR.cpp42
-rw-r--r--Source/JavaScriptCore/API/JSStringRefBSTR.h62
-rw-r--r--Source/JavaScriptCore/API/JSStringRefCF.cpp67
-rw-r--r--Source/JavaScriptCore/API/JSStringRefCF.h60
-rw-r--r--Source/JavaScriptCore/API/JSValue.h673
-rw-r--r--Source/JavaScriptCore/API/JSValueInternal.h58
-rw-r--r--Source/JavaScriptCore/API/JSValueRef.cpp191
-rw-r--r--Source/JavaScriptCore/API/JSValueRef.h24
-rw-r--r--Source/JavaScriptCore/API/JSVirtualMachine.h82
-rw-r--r--Source/JavaScriptCore/API/JSVirtualMachineInternal.h60
-rw-r--r--Source/JavaScriptCore/API/JSWeakObjectMapRefInternal.h9
-rw-r--r--Source/JavaScriptCore/API/JSWeakObjectMapRefPrivate.cpp103
-rw-r--r--Source/JavaScriptCore/API/JSWeakObjectMapRefPrivate.h92
-rw-r--r--Source/JavaScriptCore/API/JSWrapperMap.h48
-rw-r--r--Source/JavaScriptCore/API/JavaScript.h4
-rw-r--r--Source/JavaScriptCore/API/JavaScriptCore.h42
-rw-r--r--Source/JavaScriptCore/API/ObjCCallbackFunction.h6
-rw-r--r--Source/JavaScriptCore/API/ObjcRuntimeExtras.h242
-rw-r--r--Source/JavaScriptCore/API/OpaqueJSString.cpp29
-rw-r--r--Source/JavaScriptCore/API/OpaqueJSString.h26
-rw-r--r--Source/JavaScriptCore/API/WebKitAvailability.h42
-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.c8
-rw-r--r--Source/JavaScriptCore/API/tests/minidom.html9
-rw-r--r--Source/JavaScriptCore/API/tests/minidom.js110
-rw-r--r--Source/JavaScriptCore/API/tests/testapi.c1994
-rw-r--r--Source/JavaScriptCore/API/tests/testapi.js307
88 files changed, 7081 insertions, 636 deletions
diff --git a/Source/JavaScriptCore/API/APICallbackFunction.h b/Source/JavaScriptCore/API/APICallbackFunction.h
index 65c519b7a..94b10c420 100644
--- a/Source/JavaScriptCore/API/APICallbackFunction.h
+++ b/Source/JavaScriptCore/API/APICallbackFunction.h
@@ -27,9 +27,9 @@
#define APICallbackFunction_h
#include "APICast.h"
-#include "APIShims.h"
#include "Error.h"
#include "JSCallbackConstructor.h"
+#include "JSLock.h"
#include <wtf/Vector.h>
namespace JSC {
@@ -46,7 +46,7 @@ EncodedJSValue JSC_HOST_CALL APICallbackFunction::call(ExecState* exec)
{
JSContextRef execRef = toRef(exec);
JSObjectRef functionRef = toRef(exec->callee());
- JSObjectRef thisObjRef = toRef(jsCast<JSObject*>(exec->hostThisValue().toThis(exec, NotStrictMode)));
+ JSObjectRef thisObjRef = toRef(jsCast<JSObject*>(exec->thisValue().toThis(exec, NotStrictMode)));
int argumentCount = static_cast<int>(exec->argumentCount());
Vector<JSValueRef, 16> arguments;
@@ -57,7 +57,7 @@ EncodedJSValue JSC_HOST_CALL APICallbackFunction::call(ExecState* exec)
JSValueRef exception = 0;
JSValueRef result;
{
- APICallbackShim callbackShim(exec);
+ JSLock::DropAllLocks dropAllLocks(exec);
result = jsCast<T*>(toJS(functionRef))->functionCallback()(execRef, functionRef, thisObjRef, argumentCount, arguments.data(), &exception);
}
if (exception)
@@ -88,7 +88,7 @@ EncodedJSValue JSC_HOST_CALL APICallbackFunction::construct(ExecState* exec)
JSValueRef exception = 0;
JSObjectRef result;
{
- APICallbackShim callbackShim(exec);
+ JSLock::DropAllLocks dropAllLocks(exec);
result = callback(ctx, constructorRef, argumentCount, arguments.data(), &exception);
}
if (exception) {
diff --git a/Source/JavaScriptCore/API/APICast.h b/Source/JavaScriptCore/API/APICast.h
index 6526d8907..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
@@ -124,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 a133b8ed4..000000000
--- a/Source/JavaScriptCore/API/APIShims.h
+++ /dev/null
@@ -1,125 +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->vm().exclusiveThread ? 0 : exec)
- {
- }
-
- // JSPropertyNameAccumulator only has a vm.
- APIEntryShim(VM* vm, bool registerThread = true)
- : APIEntryShimWithoutLock(vm, registerThread)
- , m_lockHolder(vm->exclusiveThread ? 0 : 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(shouldDropAllLocks(exec->vm()) ? exec : nullptr)
- , m_vm(&exec->vm())
- {
- wtfThreadData().resetCurrentIdentifierTable();
- }
-
- APICallbackShim(VM& vm)
- : m_dropAllLocks(shouldDropAllLocks(vm) ? &vm : nullptr)
- , m_vm(&vm)
- {
- wtfThreadData().resetCurrentIdentifierTable();
- }
-
- ~APICallbackShim()
- {
- wtfThreadData().setCurrentIdentifierTable(m_vm->identifierTable);
- }
-
-private:
- static bool shouldDropAllLocks(VM& vm)
- {
- if (vm.exclusiveThread)
- return false;
-
- // If the VM is in the middle of being destroyed then we don't want to resurrect it
- // by allowing DropAllLocks to ref it. By this point the APILock has already been
- // released anyways, so it doesn't matter that DropAllLocks is a no-op.
- if (!vm.refCount())
- return false;
-
- return true;
- }
-
- 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/JSBase.cpp b/Source/JavaScriptCore/API/JSBase.cpp
index 506561573..6b2a907f1 100644
--- a/Source/JavaScriptCore/API/JSBase.cpp
+++ b/Source/JavaScriptCore/API/JSBase.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
@@ -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,7 +54,7 @@ JSValueRef JSEvaluateScript(JSContextRef ctx, JSStringRef script, JSObjectRef th
return 0;
}
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
+ JSLockHolder locker(exec);
JSObject* jsThisObject = toJS(thisObject);
@@ -57,14 +62,22 @@ JSValueRef JSEvaluateScript(JSContextRef ctx, JSStringRef script, JSObjectRef th
// evaluate sets "this" to the global object if it is NULL
JSGlobalObject* globalObject = exec->vmEntryGlobalObject();
- SourceCode source = makeSource(script->string(), sourceURL->string(), TextPosition(OrdinalNumber::fromOneBasedInt(startingLineNumber), OrdinalNumber::first()));
+ 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;
}
@@ -82,11 +95,11 @@ bool JSCheckScriptSyntax(JSContextRef ctx, JSStringRef script, JSStringRef sourc
return false;
}
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
+ JSLockHolder locker(exec);
startingLineNumber = std::max(1, startingLineNumber);
- SourceCode source = makeSource(script->string(), sourceURL->string(), TextPosition(OrdinalNumber::fromOneBasedInt(startingLineNumber), OrdinalNumber::first()));
+ SourceCode source = makeSource(script->string(), sourceURL ? sourceURL->string() : String(), TextPosition(OrdinalNumber::fromOneBasedInt(startingLineNumber), OrdinalNumber::first()));
JSValue syntaxException;
bool isValidSyntax = checkSyntax(exec->vmEntryGlobalObject()->globalExec(), source, &syntaxException);
@@ -94,6 +107,10 @@ bool JSCheckScriptSyntax(JSContextRef ctx, JSStringRef script, JSStringRef sourc
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;
}
@@ -111,7 +128,7 @@ void JSGarbageCollect(JSContextRef ctx)
return;
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec, false);
+ JSLockHolder locker(exec);
exec->vm().heap.reportAbandonedObjectGraph();
}
@@ -123,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)
{
@@ -135,10 +154,20 @@ 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;
diff --git a/Source/JavaScriptCore/API/JSBase.h b/Source/JavaScriptCore/API/JSBase.h
index 153d359d4..b91743c57 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,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
@@ -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,7 +96,7 @@ 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 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.
@@ -141,11 +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)
-#ifndef JSC_OBJC_API_AVAILABLE_MAC_OS_X_1080
-#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__)) || (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE)))
-#else
-#define JSC_OBJC_API_ENABLED (defined(__clang__) && defined(__APPLE__) && ((defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1080 && !defined(__i386__)) || (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE)))
-#endif
+#define JSC_OBJC_API_ENABLED (defined(__clang__) && defined(__APPLE__) && !defined(BUILDING_GTK__) && ((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 133176e1c..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
diff --git a/Source/JavaScriptCore/API/JSCTestRunnerUtils.cpp b/Source/JavaScriptCore/API/JSCTestRunnerUtils.cpp
index 2e93ac114..d314c5d48 100644
--- a/Source/JavaScriptCore/API/JSCTestRunnerUtils.cpp
+++ b/Source/JavaScriptCore/API/JSCTestRunnerUtils.cpp
@@ -27,22 +27,39 @@
#include "JSCTestRunnerUtils.h"
#include "APICast.h"
-#include "Operations.h"
+#include "JSCInlines.h"
#include "TestRunnerUtils.h"
namespace JSC {
+
+JSValueRef failNextNewCodeBlock(JSContextRef context)
+{
+ ExecState* exec= toJS(context);
+ JSLockHolder holder(exec);
+ return toRef(exec, failNextNewCodeBlock(exec));
+}
+
JSValueRef numberOfDFGCompiles(JSContextRef context, JSValueRef theFunctionValueRef)
{
ExecState* exec= toJS(context);
+ JSLockHolder holder(exec);
return toRef(exec, numberOfDFGCompiles(toJS(exec, theFunctionValueRef)));
}
JSValueRef setNeverInline(JSContextRef context, JSValueRef theFunctionValueRef)
{
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 8ea97a447..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
@@ -28,17 +28,16 @@
#include "APICallbackFunction.h"
#include "APICast.h"
-#include "APIShims.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)
diff --git a/Source/JavaScriptCore/API/JSCallbackConstructor.h b/Source/JavaScriptCore/API/JSCallbackConstructor.h
index 7eedb52e4..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)
{
@@ -56,7 +57,6 @@ public:
protected:
JSCallbackConstructor(JSGlobalObject*, Structure*, JSClassRef, JSObjectCallAsConstructorCallback);
void finishCreation(JSGlobalObject*, JSClassRef);
- static const unsigned StructureFlags = ImplementsHasInstance | JSObject::StructureFlags;
private:
friend struct APICallbackFunction;
diff --git a/Source/JavaScriptCore/API/JSCallbackFunction.cpp b/Source/JavaScriptCore/API/JSCallbackFunction.cpp
index 1996991f7..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
@@ -28,7 +28,6 @@
#include "APICallbackFunction.h"
#include "APICast.h"
-#include "APIShims.h"
#include "CodeBlock.h"
#include "Error.h"
#include "ExceptionHelpers.h"
@@ -36,14 +35,14 @@
#include "JSFunction.h"
#include "JSGlobalObject.h"
#include "JSLock.h"
-#include "Operations.h"
+#include "JSCInlines.h"
#include <wtf/Vector.h>
namespace JSC {
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(VM& vm, Structure* structure, JSObjectCallAsFunctionCallback callback)
: InternalFunction(vm, structure)
diff --git a/Source/JavaScriptCore/API/JSCallbackFunction.h b/Source/JavaScriptCore/API/JSCallbackFunction.h
index dff18de56..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
diff --git a/Source/JavaScriptCore/API/JSCallbackObject.cpp b/Source/JavaScriptCore/API/JSCallbackObject.cpp
index 94713da36..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;
@@ -61,15 +61,4 @@ Structure* JSCallbackObject<JSGlobalObject>::createStructure(VM& vm, JSGlobalObj
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 3f58906d9..addd21986 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)
@@ -42,7 +43,7 @@ struct JSCallbackObjectData : WeakHandleOwner {
JSClassRetain(jsClass);
}
- virtual ~JSCallbackObjectData()
+ ~JSCallbackObjectData()
{
JSClassRelease(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*) override;
+ 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)
{
@@ -168,9 +173,6 @@ public:
using Parent::methodTable;
-protected:
- static const unsigned StructureFlags = ProhibitsPropertyCaching | OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | ImplementsHasInstance | OverridesHasInstance | OverridesVisitChildren | OverridesGetPropertyNames | Parent::StructureFlags;
-
private:
static String className(const JSObject*);
@@ -196,8 +198,6 @@ private:
{
JSCallbackObject* thisObject = jsCast<JSCallbackObject*>(cell);
ASSERT_GC_OBJECT_INHERITS((static_cast<Parent*>(thisObject)), JSCallbackObject<Parent>::info());
- COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
- ASSERT(thisObject->Parent::structure()->typeInfo().overridesVisitChildren());
Parent::visitChildren(thisObject, visitor);
thisObject->m_callbackObjectData->visitChildren(visitor);
}
@@ -211,10 +211,10 @@ private:
static EncodedJSValue JSC_HOST_CALL construct(ExecState*);
JSValue getStaticValue(ExecState*, PropertyName);
- static EncodedJSValue staticFunctionGetter(ExecState*, EncodedJSValue, EncodedJSValue, PropertyName);
- static EncodedJSValue callbackGetter(ExecState*, EncodedJSValue, EncodedJSValue, 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 5be053f1e..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"
@@ -59,7 +58,7 @@ inline JSCallbackObject<Parent>* JSCallbackObject<Parent>::asCallbackObject(Enco
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))
{
}
@@ -68,11 +67,21 @@ 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());
@@ -104,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>
@@ -136,13 +138,13 @@ bool JSCallbackObject<Parent>::getOwnPropertySlot(JSObject* object, ExecState* e
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, ReadOnly | DontEnum, callbackGetter);
return true;
@@ -153,7 +155,7 @@ bool JSCallbackObject<Parent>::getOwnPropertySlot(JSObject* object, ExecState* e
JSValueRef exception = 0;
JSValueRef value;
{
- APICallbackShim callbackShim(exec);
+ JSLock::DropAllLocks dropAllLocks(exec);
value = getProperty(ctx, thisRef, propertyNameRef.get(), &exception);
}
if (exception) {
@@ -228,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)
@@ -236,7 +238,7 @@ 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)
@@ -253,7 +255,7 @@ 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, entry->propertyNameRef.get(), valueRef, &exception);
}
if (exception)
@@ -266,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
@@ -295,7 +300,7 @@ 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)
@@ -312,7 +317,7 @@ 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, entry->propertyNameRef.get(), valueRef, &exception);
}
if (exception)
@@ -343,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)
@@ -351,7 +356,7 @@ 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)
@@ -418,7 +423,7 @@ EncodedJSValue JSCallbackObject<Parent>::construct(ExecState* exec)
JSValueRef exception = 0;
JSObject* result;
{
- APICallbackShim callbackShim(exec);
+ JSLock::DropAllLocks dropAllLocks(exec);
result = toJS(callAsConstructor(execRef, constructorRef, argumentCount, arguments.data(), &exception));
}
if (exception)
@@ -444,7 +449,7 @@ 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)
@@ -473,7 +478,7 @@ EncodedJSValue JSCallbackObject<Parent>::call(ExecState* exec)
{
JSContextRef execRef = toRef(exec);
JSObjectRef functionRef = toRef(exec->callee());
- JSObjectRef thisObjRef = toRef(jsCast<JSObject*>(exec->hostThisValue().toThis(exec, NotStrictMode)));
+ 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) {
@@ -485,7 +490,7 @@ EncodedJSValue JSCallbackObject<Parent>::call(ExecState* exec)
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)
@@ -507,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));
}
@@ -517,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)));
+ }
}
}
@@ -528,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)));
+ }
}
}
}
@@ -564,7 +573,7 @@ JSValue JSCallbackObject<Parent>::getStaticValue(ExecState* exec, PropertyName p
{
JSObjectRef thisRef = toRef(this);
- 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)) {
@@ -572,7 +581,7 @@ JSValue JSCallbackObject<Parent>::getStaticValue(ExecState* exec, PropertyName p
JSValueRef exception = 0;
JSValueRef value;
{
- APICallbackShim callbackShim(exec);
+ JSLock::DropAllLocks dropAllLocks(exec);
value = getProperty(toRef(exec), thisRef, entry->propertyNameRef.get(), &exception);
}
if (exception) {
@@ -591,16 +600,16 @@ JSValue JSCallbackObject<Parent>::getStaticValue(ExecState* exec, PropertyName p
}
template <class Parent>
-EncodedJSValue JSCallbackObject<Parent>::staticFunctionGetter(ExecState* exec, EncodedJSValue slotParent, EncodedJSValue, 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 JSValue::encode(slot2.getValue(exec, propertyName));
- if (StringImpl* name = propertyName.publicName()) {
+ 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)) {
@@ -619,14 +628,14 @@ EncodedJSValue JSCallbackObject<Parent>::staticFunctionGetter(ExecState* exec, E
}
template <class Parent>
-EncodedJSValue JSCallbackObject<Parent>::callbackGetter(ExecState* exec, EncodedJSValue slotParent, EncodedJSValue, 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)
@@ -634,7 +643,7 @@ EncodedJSValue JSCallbackObject<Parent>::callbackGetter(ExecState* exec, Encoded
JSValueRef exception = 0;
JSValueRef value;
{
- APICallbackShim callbackShim(exec);
+ JSLock::DropAllLocks dropAllLocks(exec);
value = getProperty(toRef(exec), thisRef, propertyNameRef.get(), &exception);
}
if (exception) {
diff --git a/Source/JavaScriptCore/API/JSClassRef.cpp b/Source/JavaScriptCore/API/JSClassRef.cpp
index 544c359b1..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,7 +62,7 @@ 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())
@@ -72,7 +72,7 @@ OpaqueJSClass::OpaqueJSClass(const JSClassDefinition* definition, OpaqueJSClass*
}
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())
@@ -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,7 +124,7 @@ 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)
@@ -134,7 +134,7 @@ OpaqueJSClassContextData::OpaqueJSClassContextData(JSC::VM&, OpaqueJSClass* jsCl
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());
+ 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));
}
@@ -144,7 +144,7 @@ OpaqueJSClassContextData::OpaqueJSClassContextData(JSC::VM&, OpaqueJSClass* jsCl
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());
+ ASSERT(!it->key->isAtomic());
staticFunctions->add(it->key->isolatedCopy(), std::make_unique<StaticFunctionEntry>(it->value->callAsFunction, it->value->attributes));
}
}
@@ -160,7 +160,7 @@ OpaqueJSClassContextData& OpaqueJSClass::contextData(ExecState* exec)
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();
}
diff --git a/Source/JavaScriptCore/API/JSClassRef.h b/Source/JavaScriptCore/API/JSClassRef.h
index f979f3b2c..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
@@ -85,8 +85,8 @@ public:
};
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();
@@ -118,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
new file mode 100644
index 000000000..ddb51adfe
--- /dev/null
+++ b/Source/JavaScriptCore/API/JSContext.h
@@ -0,0 +1,241 @@
+/*
+ * 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 JSContext_h
+#define JSContext_h
+
+#include <JavaScriptCore/JavaScript.h>
+#include <JavaScriptCore/WebKitAvailability.h>
+
+#if JSC_OBJC_API_ENABLED
+
+@class JSVirtualMachine, JSValue;
+
+/*!
+@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
+
+/*!
+@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;
+
+/*!
+@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;
+
+/*!
+@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;
+
+/*!
+@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;
+
+/*!
+@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
+
+/*!
+@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
+
+/*!
+@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;
+
+/*!
+@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
+
+#endif // JSContext_h
diff --git a/Source/JavaScriptCore/API/JSContextInternal.h b/Source/JavaScriptCore/API/JSContextInternal.h
new file mode 100644
index 000000000..5308fbb92
--- /dev/null
+++ b/Source/JavaScriptCore/API/JSContextInternal.h
@@ -0,0 +1,80 @@
+/*
+ * 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 JSContextInternal_h
+#define JSContextInternal_h
+
+#import <JavaScriptCore/JavaScriptCore.h>
+
+#if JSC_OBJC_API_ENABLED
+
+#import <JavaScriptCore/JSContext.h>
+
+struct CallbackData {
+ CallbackData *next;
+ JSContext *context;
+ JSValue *preservedException;
+ JSValueRef calleeValue;
+ JSValueRef thisValue;
+ size_t argumentCount;
+ const JSValueRef *arguments;
+ NSArray *currentArguments;
+};
+
+class WeakContextRef {
+public:
+ WeakContextRef(JSContext * = nil);
+ ~WeakContextRef();
+
+ JSContext * get();
+ void set(JSContext *);
+
+private:
+ JSContext *m_weakContext;
+};
+
+@class JSWrapperMap;
+
+@interface JSContext(Internal)
+
+- (id)initWithGlobalContextRef:(JSGlobalContextRef)context;
+
+- (void)notifyException:(JSValueRef)exception;
+- (JSValue *)valueFromNotifyException:(JSValueRef)exception;
+- (BOOL)boolFromNotifyException:(JSValueRef)exception;
+
+- (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;
+- (JSValue *)wrapperForJSObject:(JSValueRef)value;
+
+@property (readonly, retain) JSWrapperMap *wrapperMap;
+
+@end
+
+#endif
+
+#endif // JSContextInternal_h
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 81b61cf47..98cd8b030 100644
--- a/Source/JavaScriptCore/API/JSContextRef.cpp
+++ b/Source/JavaScriptCore/API/JSContextRef.cpp
@@ -10,37 +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 "CallFrameInlines.h"
#include "InitializeThreading.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>
@@ -57,7 +67,7 @@ using namespace JSC;
JSContextGroupRef JSContextGroupCreate()
{
initializeThreading();
- return toRef(VM::createContextGroup().leakRef());
+ return toRef(&VM::createContextGroup().leakRef());
}
JSContextGroupRef JSContextGroupRetain(JSContextGroupRef group)
@@ -68,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)
@@ -91,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.
@@ -131,12 +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()));
- globalObject->setGlobalThis(*vm, JSProxy::create(*vm, JSProxy::createStructure(*vm, globalObject, globalObject->prototype()), globalObject));
+#if ENABLE(REMOTE_INSPECTOR)
+ if (JSRemoteInspectorGetInspectionEnabledByDefault())
+ globalObject->setRemoteDebuggingEnabled(true);
+#endif
return JSGlobalContextRetain(toGlobalRef(globalObject->globalExec()));
}
@@ -146,13 +152,17 @@ 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->vmEntryGlobalObject());
@@ -162,21 +172,14 @@ JSGlobalContextRef JSGlobalContextRetain(JSGlobalContextRef ctx)
void JSGlobalContextRelease(JSGlobalContextRef ctx)
{
- IdentifierTable* savedIdentifierTable;
ExecState* exec = toJS(ctx);
- {
- JSLockHolder lock(exec);
-
- VM& vm = exec->vm();
- savedIdentifierTable = wtfThreadData().setCurrentIdentifierTable(vm.identifierTable);
+ JSLockHolder locker(exec);
- bool protectCountIsZero = Heap::heap(exec->vmEntryGlobalObject())->unprotect(exec->vmEntryGlobalObject());
- if (protectCountIsZero)
- vm.heap.reportAbandonedObjectGraph();
- vm.deref();
- }
-
- 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)
@@ -186,7 +189,7 @@ JSObjectRef JSContextGetGlobalObject(JSContextRef ctx)
return 0;
}
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
+ JSLockHolder locker(exec);
return toRef(jsCast<JSObject*>(exec->lexicalGlobalObject()->methodTable()->toThis(exec->lexicalGlobalObject(), exec, NotStrictMode)));
}
@@ -208,7 +211,7 @@ JSGlobalContextRef JSContextGetGlobalContext(JSContextRef ctx)
return 0;
}
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
+ JSLockHolder locker(exec);
return toGlobalRef(exec->lexicalGlobalObject()->globalExec());
}
@@ -221,7 +224,7 @@ JSStringRef JSGlobalContextCopyName(JSGlobalContextRef ctx)
}
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
+ JSLockHolder locker(exec);
String name = exec->vmEntryGlobalObject()->name();
if (name.isNull())
@@ -238,7 +241,7 @@ void JSGlobalContextSetName(JSGlobalContextRef ctx, JSStringRef name)
}
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
+ JSLockHolder locker(exec);
exec->vmEntryGlobalObject()->setName(name ? name->string() : String());
}
@@ -310,4 +313,119 @@ JSStringRef JSContextCreateBacktrace(JSContextRef ctx, unsigned maxStackSize)
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 c8db1e56d..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,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
@@ -48,7 +48,7 @@ extern "C" {
synchronization is required.
@result The created JSContextGroup.
*/
-JS_EXPORT JSContextGroupRef JSContextGroupCreate() CF_AVAILABLE(10_6, 7_0);
+JS_EXPORT JSContextGroupRef JSContextGroupCreate(void) CF_AVAILABLE(10_6, 7_0);
/*!
@function
@@ -141,7 +141,7 @@ JS_EXPORT JSGlobalContextRef JSContextGetGlobalContext(JSContextRef ctx) CF_AVAI
@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);
+JS_EXPORT JSStringRef JSGlobalContextCopyName(JSGlobalContextRef ctx) CF_AVAILABLE(10_10, 8_0);
/*!
@function
@@ -149,7 +149,7 @@ JS_EXPORT JSStringRef JSGlobalContextCopyName(JSGlobalContextRef ctx);
@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);
+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 780a60306..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
@@ -94,6 +94,40 @@ JS_EXPORT void JSContextGroupSetExecutionTimeLimit(JSContextGroupRef, double lim
*/
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
}
#endif
diff --git a/Source/JavaScriptCore/API/JSExport.h b/Source/JavaScriptCore/API/JSExport.h
new file mode 100644
index 000000000..b8a484909
--- /dev/null
+++ b/Source/JavaScriptCore/API/JSExport.h
@@ -0,0 +1,146 @@
+/*
+ * 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>
+
+#if JSC_OBJC_API_ENABLED
+
+/*!
+@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
+
+/*!
+@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
+
+#endif
diff --git a/Source/JavaScriptCore/API/JSManagedValue.h b/Source/JavaScriptCore/API/JSManagedValue.h
new file mode 100644
index 000000000..d13733d08
--- /dev/null
+++ b/Source/JavaScriptCore/API/JSManagedValue.h
@@ -0,0 +1,83 @@
+/*
+ * 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 JSManagedValue_h
+#define JSManagedValue_h
+
+#import <JavaScriptCore/JSBase.h>
+#import <JavaScriptCore/WebKitAvailability.h>
+
+#if JSC_OBJC_API_ENABLED
+
+@class JSValue;
+@class JSContext;
+
+/*!
+@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
+
+/*!
+@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);
+
+/*!
+@method
+@abstract Create a JSManagedValue.
+@param value
+@result The new JSManagedValue.
+*/
+- (instancetype)initWithValue:(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
+
+#endif // JSC_OBJC_API_ENABLED
+
+#endif // JSManagedValue_h
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 56fe90b47..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,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
@@ -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,7 +129,7 @@ JSObjectRef JSObjectMakeFunctionWithCallback(JSContextRef ctx, JSStringRef name,
return 0;
}
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
+ JSLockHolder locker(exec);
return toRef(JSCallbackFunction::create(exec->vm(), exec->lexicalGlobalObject(), callAsFunction, name ? name->string() : ASCIILiteral("anonymous")));
}
@@ -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,23 +158,19 @@ JSObjectRef JSObjectMakeFunction(JSContextRef ctx, JSStringRef name, unsigned pa
return 0;
}
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
+ JSLockHolder locker(exec);
startingLineNumber = std::max(1, startingLineNumber);
- Identifier nameID = name ? name->identifier(&exec->vm()) : Identifier(exec, "anonymous");
+ 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);
}
@@ -160,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) {
@@ -172,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);
}
@@ -189,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);
}
@@ -213,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);
}
@@ -236,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);
}
@@ -260,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());
@@ -273,11 +278,19 @@ 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);
+ 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());
}
@@ -288,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);
@@ -302,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);
}
@@ -322,7 +331,7 @@ 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()));
@@ -336,11 +345,7 @@ void JSObjectSetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef prope
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)
@@ -350,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);
}
@@ -371,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)
@@ -391,23 +388,23 @@ 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);
-
+
+ // 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>::info()))
@@ -423,7 +420,11 @@ void* JSObjectGetPrivate(JSObjectRef object)
bool JSObjectSetPrivate(JSObjectRef object, void* data)
{
JSObject* jsObject = uncheckedToJS(object);
-
+
+ // 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;
@@ -445,10 +446,15 @@ 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()));
+
+ // 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>::info()))
@@ -463,10 +469,15 @@ 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()));
+
+ // 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;
@@ -487,9 +498,14 @@ 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()));
+
+ // 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;
@@ -507,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;
@@ -519,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;
@@ -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;
}
@@ -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 5e7fd69a9..754dff363 100644
--- a/Source/JavaScriptCore/API/JSObjectRef.h
+++ b/Source/JavaScriptCore/API/JSObjectRef.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/JSProfilerPrivate.cpp b/Source/JavaScriptCore/API/JSProfilerPrivate.cpp
new file mode 100644
index 000000000..ac112ae6e
--- /dev/null
+++ b/Source/JavaScriptCore/API/JSProfilerPrivate.cpp
@@ -0,0 +1,50 @@
+/*
+ * 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
+ * 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 "JSProfilerPrivate.h"
+
+#include "APICast.h"
+#include "LegacyProfiler.h"
+#include "OpaqueJSString.h"
+
+using namespace JSC;
+
+void JSStartProfiling(JSContextRef ctx, JSStringRef title)
+{
+ // 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)
+{
+ ExecState* exec = toJS(ctx);
+ LegacyProfiler* profiler = LegacyProfiler::profiler();
+ profiler->stopProfiling(exec, title->string());
+}
+
diff --git a/Source/JavaScriptCore/API/JSProfilerPrivate.h b/Source/JavaScriptCore/API/JSProfilerPrivate.h
new file mode 100644
index 000000000..34f26a202
--- /dev/null
+++ b/Source/JavaScriptCore/API/JSProfilerPrivate.h
@@ -0,0 +1,63 @@
+/*
+ * 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
+ * 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 JSProfiler_h
+#define JSProfiler_h
+
+#include <JavaScriptCore/JSBase.h>
+
+#ifndef __cplusplus
+#include <stdbool.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*!
+@function JSStartProfiling
+@abstract Enables the profler.
+@param ctx The execution context to use.
+@param title The title of the profile.
+@result The profiler is turned on.
+*/
+JS_EXPORT void JSStartProfiling(JSContextRef ctx, JSStringRef title);
+
+/*!
+@function JSEndProfiling
+@abstract Disables the profler.
+@param ctx The execution context to use.
+@param title The title of the profile.
+@result The profiler is turned off. If there is no name, the most recently started
+ profile is stopped. If the name does not match any profile then no profile
+ is stopped.
+*/
+JS_EXPORT void JSEndProfiling(JSContextRef ctx, JSStringRef title);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* JSProfiler_h */
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 9277001d2..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));
}
- virtual 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())
{
}
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,7 +85,7 @@ 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;
@@ -85,15 +93,15 @@ JSScriptRef JSScriptCreateReferencingImmortalASCIIText(JSContextGroupRef context
startingLineNumber = std::max(1, startingLineNumber);
- RefPtr<OpaqueJSScript> result = OpaqueJSScript::create(vm, url->string(), startingLineNumber, String(StringImpl::createFromLiteral(source, length)));
+ 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();
@@ -102,19 +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();
@@ -122,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/JSStringRef.cpp b/Source/JavaScriptCore/API/JSStringRef.cpp
index 25b84c7d2..c9b380ce6 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(chars, numChars).leakRef();
}
JSStringRef JSStringCreateWithUTF8CString(const char* string)
@@ -51,12 +51,12 @@ 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)
@@ -78,11 +78,15 @@ void JSStringRelease(JSStringRef string)
size_t JSStringGetLength(JSStringRef string)
{
+ if (!string)
+ return 0;
return string->length();
}
const JSChar* JSStringGetCharactersPtr(JSStringRef string)
{
+ if (!string)
+ return nullptr;
return string->characters();
}
@@ -94,7 +98,7 @@ size_t JSStringGetMaximumUTF8CStringSize(JSStringRef string)
size_t JSStringGetUTF8CString(JSStringRef string, char* buffer, size_t bufferSize)
{
- if (!bufferSize)
+ if (!string || !buffer || !bufferSize)
return 0;
char* destination = buffer;
diff --git a/Source/JavaScriptCore/API/JSStringRef.h b/Source/JavaScriptCore/API/JSStringRef.h
index aded73626..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,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/JSStringRefBSTR.cpp b/Source/JavaScriptCore/API/JSStringRefBSTR.cpp
new file mode 100644
index 000000000..e900d24d8
--- /dev/null
+++ b/Source/JavaScriptCore/API/JSStringRefBSTR.cpp
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 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
+ * 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.
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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 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 "JSStringRefBSTR.h"
+
+#include "JSStringRef.h"
+
+JSStringRef JSStringCreateWithBSTR(BSTR string)
+{
+ return JSStringCreateWithCharacters(string ? string : L"", string ? SysStringLen(string) : 0);
+}
+
+BSTR JSStringCopyBSTR(const JSStringRef string)
+{
+ return SysAllocStringLen(JSStringGetCharactersPtr(string), JSStringGetLength(string));
+}
diff --git a/Source/JavaScriptCore/API/JSStringRefBSTR.h b/Source/JavaScriptCore/API/JSStringRefBSTR.h
new file mode 100644
index 000000000..066c68d53
--- /dev/null
+++ b/Source/JavaScriptCore/API/JSStringRefBSTR.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 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
+ * 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.
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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 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 JSStringRefBSTR_h
+#define JSStringRefBSTR_h
+
+#include "JSBase.h"
+
+#include <windows.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* COM convenience methods */
+
+/*!
+@function
+@abstract Creates a JavaScript string from a BSTR.
+@param string The BSTR to copy into the new JSString.
+@result A JSString containing string. Ownership follows the Create Rule.
+*/
+JS_EXPORT JSStringRef JSStringCreateWithBSTR(const BSTR string);
+
+/*!
+@function
+@abstract Creates a BSTR from a JavaScript string.
+@param string The JSString to copy into the new BSTR.
+@result A BSTR containing string. Ownership follows the Create Rule.
+*/
+JS_EXPORT BSTR JSStringCopyBSTR(const JSStringRef string);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* JSStringRefBSTR_h */
diff --git a/Source/JavaScriptCore/API/JSStringRefCF.cpp b/Source/JavaScriptCore/API/JSStringRefCF.cpp
new file mode 100644
index 000000000..05872593f
--- /dev/null
+++ b/Source/JavaScriptCore/API/JSStringRefCF.cpp
@@ -0,0 +1,67 @@
+/*
+ * 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
+ * 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 "JSStringRefCF.h"
+
+#include "APICast.h"
+#include "InitializeThreading.h"
+#include "JSCJSValue.h"
+#include "JSStringRef.h"
+#include "OpaqueJSString.h"
+#include <wtf/StdLibExtras.h>
+
+JSStringRef JSStringCreateWithCFString(CFStringRef string)
+{
+ JSC::initializeThreading();
+
+ // 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)
+ 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 allocator, JSStringRef string)
+{
+ 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
new file mode 100644
index 000000000..1e210c7a9
--- /dev/null
+++ b/Source/JavaScriptCore/API/JSStringRefCF.h
@@ -0,0 +1,60 @@
+/*
+ * 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
+ * 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 JSStringRefCF_h
+#define JSStringRefCF_h
+
+#include "JSBase.h"
+#include <CoreFoundation/CoreFoundation.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* CFString convenience methods */
+
+/*!
+@function
+@abstract Creates a JavaScript string from a CFString.
+@discussion This function is optimized to take advantage of cases when
+ CFStringGetCharactersPtr returns a valid pointer.
+@param string The CFString to copy into the new JSString.
+@result A JSString containing string. Ownership follows the Create Rule.
+*/
+JS_EXPORT JSStringRef JSStringCreateWithCFString(CFStringRef string);
+/*!
+@function
+@abstract Creates a CFString from a JavaScript string.
+@param alloc The alloc parameter to pass to CFStringCreate.
+@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) CF_RETURNS_RETAINED;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* JSStringRefCF_h */
diff --git a/Source/JavaScriptCore/API/JSValue.h b/Source/JavaScriptCore/API/JSValue.h
new file mode 100644
index 000000000..37d759407
--- /dev/null
+++ b/Source/JavaScriptCore/API/JSValue.h
@@ -0,0 +1,673 @@
+/*
+ * 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 JSValue_h
+#define JSValue_h
+
+#if JSC_OBJC_API_ENABLED
+
+#import <CoreGraphics/CGGeometry.h>
+
+@class JSContext;
+
+/*!
+@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
+
+/*!
+@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;
+
+/*!
+@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;
+
+/*!
+@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;
+
+/*!
+@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;
+
+/*!
+@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;
+
+/*!
+@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;
+
+/*!
+@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;
+
+/*!
+@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;
+
+/*!
+@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;
+
+/*!
+@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;
+
+/*!
+@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;
+
+/*!
+@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;
+
+/*!
+@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;
+
+/*!
+@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;
+
+/*!
+@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;
+
+/*!
+@method
+@abstract Set a property on a JSValue.
+*/
+- (void)setValue:(id)value forProperty:(NSString *)property;
+
+/*!
+@method
+@abstract Delete a property from a JSValue.
+@result YES if deletion is successful, NO otherwise.
+*/
+- (BOOL)deleteProperty:(NSString *)property;
+
+/*!
+@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;
+
+/*!
+@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;
+
+/*!
+@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;
+
+/*!
+@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;
+
+/*!
+@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;
+
+/*!
+@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;
+
+/*!
+@method
+@abstract Compare two JSValues using JavaScript's <code>==</code> operator.
+*/
+- (BOOL)isEqualWithTypeCoercionToObject:(id)value;
+
+/*!
+@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;
+
+/*!
+@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;
+
+/*!
+@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;
+
+/*!
+@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
+
+/*!
+@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;
+
+/*!
+@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;
+
+/*!
+@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;
+
+/*!
+@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;
+
+/*!
+@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;
+
+/*!
+@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;
+
+/*!
+@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;
+
+/*!
+@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
+
+/*!
+@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;
+- (void)setObject:(id)object forKeyedSubscript:(NSObject <NSCopying> *)key;
+- (void)setObject:(id)object atIndexedSubscript:(NSUInteger)index;
+
+@end
+
+/*!
+@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;
+
+/*!
+@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
+
+/*!
+@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
+} // extern "C"
+#endif
+
+#endif
+
+#endif // JSValue_h
diff --git a/Source/JavaScriptCore/API/JSValueInternal.h b/Source/JavaScriptCore/API/JSValueInternal.h
new file mode 100644
index 000000000..4f1a8f69c
--- /dev/null
+++ b/Source/JavaScriptCore/API/JSValueInternal.h
@@ -0,0 +1,58 @@
+/*
+ * 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 JSValueInternal_h
+#define JSValueInternal_h
+
+#import <JavaScriptCore/JavaScriptCore.h>
+#import <JavaScriptCore/JSValue.h>
+
+#if JSC_OBJC_API_ENABLED
+
+@interface JSValue(Internal)
+
+JSValueRef valueInternalValue(JSValue *);
+
+- (JSValue *)initWithValue:(JSValueRef)value inContext:(JSContext *)context;
+
+JSValueRef objectToValue(JSContext *, id);
+id valueToObject(JSContext *, JSValueRef);
+id valueToNumber(JSGlobalContextRef, JSValueRef, JSValueRef* exception);
+id valueToString(JSGlobalContextRef, JSValueRef, JSValueRef* exception);
+id valueToDate(JSGlobalContextRef, JSValueRef, JSValueRef* exception);
+id valueToArray(JSGlobalContextRef, JSValueRef, JSValueRef* exception);
+id valueToDictionary(JSGlobalContextRef, JSValueRef, JSValueRef* exception);
+
++ (SEL)selectorForStructToValue:(const char *)structTag;
++ (SEL)selectorForValueToStruct:(const char *)structTag;
+
+@end
+
+NSInvocation *typeToValueInvocationFor(const char* encodedType);
+NSInvocation *valueToTypeInvocationFor(const char* encodedType);
+
+#endif
+
+#endif // JSValueInternal_h
diff --git a/Source/JavaScriptCore/API/JSValueRef.cpp b/Source/JavaScriptCore/API/JSValueRef.cpp
index 3e0cbbd7a..54405e2af 100644
--- a/Source/JavaScriptCore/API/JSValueRef.cpp
+++ b/Source/JavaScriptCore/API/JSValueRef.cpp
@@ -10,46 +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 "JSGlobalObject.h"
#include "JSONObject.h"
#include "JSString.h"
#include "LiteralParser.h"
-#include "Operations.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()
{
@@ -68,7 +91,7 @@ static bool evernoteHackNeeded()
return kJSTypeUndefined;
}
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
+ JSLockHolder locker(exec);
JSValue jsValue = toJS(exec, value);
@@ -93,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)
@@ -106,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)
@@ -119,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)
@@ -132,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)
@@ -145,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)
@@ -158,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)
@@ -171,11 +212,14 @@ 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(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>::info()))
@@ -195,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;
}
@@ -216,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);
@@ -231,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);
@@ -239,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;
}
@@ -254,7 +291,7 @@ JSValueRef JSValueMakeUndefined(JSContextRef ctx)
return 0;
}
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
+ JSLockHolder locker(exec);
return toRef(exec, jsUndefined());
}
@@ -266,7 +303,7 @@ JSValueRef JSValueMakeNull(JSContextRef ctx)
return 0;
}
ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
+ JSLockHolder locker(exec);
return toRef(exec, jsNull());
}
@@ -278,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));
}
@@ -290,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)
@@ -308,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)
@@ -320,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.deprecatedCharacters(), length, StrictJSON);
+ LiteralParser<UChar> parser(exec, str.characters16(), length, StrictJSON);
return toRef(exec, parser.tryLiteralParse());
}
@@ -338,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();
}
@@ -359,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);
@@ -369,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;
}
@@ -393,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();
}
@@ -414,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)
{
@@ -435,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);
@@ -449,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 97385c01e..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 */
/*!
diff --git a/Source/JavaScriptCore/API/JSVirtualMachine.h b/Source/JavaScriptCore/API/JSVirtualMachine.h
new file mode 100644
index 000000000..ccf9264d5
--- /dev/null
+++ b/Source/JavaScriptCore/API/JSVirtualMachine.h
@@ -0,0 +1,82 @@
+/*
+ * 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>
+
+#if JSC_OBJC_API_ENABLED
+
+/*!
+@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
+
+/*!
+@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
+
+#endif
diff --git a/Source/JavaScriptCore/API/JSVirtualMachineInternal.h b/Source/JavaScriptCore/API/JSVirtualMachineInternal.h
new file mode 100644
index 000000000..5a4fbefa5
--- /dev/null
+++ b/Source/JavaScriptCore/API/JSVirtualMachineInternal.h
@@ -0,0 +1,60 @@
+/*
+ * 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 JSVirtualMachineInternal_h
+#define JSVirtualMachineInternal_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 *);
+
++ (JSVirtualMachine *)virtualMachineWithContextGroupRef:(JSContextGroupRef)group;
+
+- (JSContext *)contextForGlobalContextRef:(JSGlobalContextRef)globalContext;
+- (void)addContext:(JSContext *)wrapper forGlobalContextRef:(JSGlobalContextRef)globalContext;
+
+- (NSMapTable *)externalObjectGraph;
+
+@end
+#endif // defined(__OBJC__)
+
+void scanExternalObjectGraph(JSC::VM&, JSC::SlotVisitor&, void* root);
+void scanExternalRememberedSet(JSC::VM&, JSC::SlotVisitor&);
+
+#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
new file mode 100644
index 000000000..925c00f0b
--- /dev/null
+++ b/Source/JavaScriptCore/API/JSWeakObjectMapRefPrivate.cpp
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "JSWeakObjectMapRefPrivate.h"
+
+#include "APICast.h"
+#include "JSCJSValue.h"
+#include "JSCallbackObject.h"
+#include "JSWeakObjectMapRefInternal.h"
+#include "JSCInlines.h"
+#include "Weak.h"
+#include "WeakGCMapInlines.h"
+#include <wtf/HashMap.h>
+#include <wtf/text/StringHash.h>
+
+using namespace WTF;
+using namespace JSC;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+JSWeakObjectMapRef JSWeakObjectMapCreate(JSContextRef context, void* privateData, JSWeakMapDestroyedCallback callback)
+{
+ ExecState* exec = toJS(context);
+ JSLockHolder locker(exec);
+ RefPtr<OpaqueJSWeakObjectMap> map = OpaqueJSWeakObjectMap::create(exec->vm(), privateData, callback);
+ exec->lexicalGlobalObject()->registerWeakMap(map.get());
+ return map.get();
+}
+
+void JSWeakObjectMapSet(JSContextRef ctx, JSWeakObjectMapRef map, void* key, JSObjectRef object)
+{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return;
+ }
+ ExecState* exec = toJS(ctx);
+ JSLockHolder locker(exec);
+ JSObject* obj = toJS(object);
+ if (!obj)
+ return;
+ ASSERT(obj->inherits(JSProxy::info())
+ || obj->inherits(JSCallbackObject<JSGlobalObject>::info())
+ || obj->inherits(JSCallbackObject<JSDestructibleObject>::info()));
+ map->map().set(key, obj);
+}
+
+JSObjectRef JSWeakObjectMapGet(JSContextRef ctx, JSWeakObjectMapRef map, void* key)
+{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
+ ExecState* exec = toJS(ctx);
+ JSLockHolder locker(exec);
+ return toRef(jsCast<JSObject*>(map->map().get(key)));
+}
+
+void JSWeakObjectMapRemove(JSContextRef ctx, JSWeakObjectMapRef map, void* key)
+{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return;
+ }
+ ExecState* exec = toJS(ctx);
+ JSLockHolder locker(exec);
+ map->map().remove(key);
+}
+
+// We need to keep this function in the build to keep the nightlies running.
+JS_EXPORT bool JSWeakObjectMapClear(JSContextRef, JSWeakObjectMapRef, void*, JSObjectRef);
+bool JSWeakObjectMapClear(JSContextRef, JSWeakObjectMapRef, void*, JSObjectRef)
+{
+ return true;
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/Source/JavaScriptCore/API/JSWeakObjectMapRefPrivate.h b/Source/JavaScriptCore/API/JSWeakObjectMapRefPrivate.h
new file mode 100644
index 000000000..5a07cf7c4
--- /dev/null
+++ b/Source/JavaScriptCore/API/JSWeakObjectMapRefPrivate.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef JSWeakObjectMapRefPrivate_h
+#define JSWeakObjectMapRefPrivate_h
+
+#include <JavaScriptCore/JSContextRef.h>
+#include <JavaScriptCore/JSValueRef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*! @typedef JSWeakObjectMapRef A weak map for storing JSObjectRefs */
+typedef struct OpaqueJSWeakObjectMap* JSWeakObjectMapRef;
+
+/*!
+ @typedef JSWeakMapDestroyedCallback
+ @abstract The callback invoked when a JSWeakObjectMapRef is being destroyed.
+ @param map The map that is being destroyed.
+ @param data The private data (if any) that was associated with the map instance.
+ */
+typedef void (*JSWeakMapDestroyedCallback)(JSWeakObjectMapRef map, void* data);
+
+/*!
+ @function
+ @abstract Creates a weak value map that can be used to reference user defined objects without preventing them from being collected.
+ @param ctx The execution context to use.
+ @param data A void* to set as the map's private data. Pass NULL to specify no private data.
+ @param destructor A function to call when the weak map is destroyed.
+ @result A JSWeakObjectMapRef bound to the given context, data and destructor.
+ @discussion The JSWeakObjectMapRef can be used as a storage mechanism to hold custom JS objects without forcing those objects to
+ remain live as JSValueProtect would.
+ */
+JS_EXPORT JSWeakObjectMapRef JSWeakObjectMapCreate(JSContextRef ctx, void* data, JSWeakMapDestroyedCallback destructor);
+
+/*!
+ @function
+ @abstract Associates a JSObjectRef with the given key in a JSWeakObjectMap.
+ @param ctx The execution context to use.
+ @param map The map to operate on.
+ @param key The key to associate a weak reference with.
+ @param object The user defined object to associate with the key.
+ */
+JS_EXPORT void JSWeakObjectMapSet(JSContextRef ctx, JSWeakObjectMapRef map, void* key, JSObjectRef);
+
+/*!
+ @function
+ @abstract Retrieves the JSObjectRef associated with a key.
+ @param ctx The execution context to use.
+ @param map The map to query.
+ @param key The key to search for.
+ @result Either the live object associated with the provided key, or NULL.
+ */
+JS_EXPORT JSObjectRef JSWeakObjectMapGet(JSContextRef ctx, JSWeakObjectMapRef map, void* key);
+
+/*!
+ @function
+ @abstract Removes the entry for the given key if the key is present, otherwise it has no effect.
+ @param ctx The execution context to use.
+ @param map The map to use.
+ @param key The key to remove.
+ */
+JS_EXPORT void JSWeakObjectMapRemove(JSContextRef ctx, JSWeakObjectMapRef map, void* key);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // JSWeakObjectMapPrivate_h
diff --git a/Source/JavaScriptCore/API/JSWrapperMap.h b/Source/JavaScriptCore/API/JSWrapperMap.h
new file mode 100644
index 000000000..c6aa1af13
--- /dev/null
+++ b/Source/JavaScriptCore/API/JSWrapperMap.h
@@ -0,0 +1,48 @@
+/*
+ * 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>
+#import <JSValueInternal.h>
+#import <objc/objc-runtime.h>
+
+#if JSC_OBJC_API_ENABLED
+
+@interface JSWrapperMap : NSObject
+
+- (id)initWithContext:(JSContext *)context;
+
+- (JSValue *)jsWrapperForObject:(id)object;
+
+- (JSValue *)objcWrapperForJSValueRef:(JSValueRef)value;
+
+@end
+
+id tryUnwrapObjcObject(JSGlobalContextRef, JSValueRef);
+
+bool supportsInitMethodConstructors();
+Protocol *getJSExportProtocol();
+Class getNSBlockClass();
+
+#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
new file mode 100644
index 000000000..b2fde1dbe
--- /dev/null
+++ b/Source/JavaScriptCore/API/JavaScriptCore.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2006, 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
+ * 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 JavaScriptCore_h
+#define JavaScriptCore_h
+
+#include <JavaScriptCore/JavaScript.h>
+#include <JavaScriptCore/JSStringRefCF.h>
+
+#if defined(__OBJC__) && JSC_OBJC_API_ENABLED
+
+#import "JSContext.h"
+#import "JSValue.h"
+#import "JSManagedValue.h"
+#import "JSVirtualMachine.h"
+#import "JSExport.h"
+
+#endif
+
+#endif /* JavaScriptCore_h */
diff --git a/Source/JavaScriptCore/API/ObjCCallbackFunction.h b/Source/JavaScriptCore/API/ObjCCallbackFunction.h
index 046bf650d..adb167c76 100644
--- a/Source/JavaScriptCore/API/ObjCCallbackFunction.h
+++ b/Source/JavaScriptCore/API/ObjCCallbackFunction.h
@@ -48,7 +48,7 @@ class ObjCCallbackFunction : public InternalFunction {
public:
typedef InternalFunction Base;
- static ObjCCallbackFunction* create(VM&, 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)
@@ -62,7 +62,7 @@ public:
ObjCCallbackFunctionImpl* impl() const { return m_impl.get(); }
protected:
- ObjCCallbackFunction(VM&, JSGlobalObject*, JSObjectCallAsFunctionCallback, JSObjectCallAsConstructorCallback, PassOwnPtr<ObjCCallbackFunctionImpl>);
+ ObjCCallbackFunction(VM&, JSGlobalObject*, JSObjectCallAsFunctionCallback, JSObjectCallAsConstructorCallback, std::unique_ptr<ObjCCallbackFunctionImpl>);
private:
static CallType getCallData(JSCell*, CallData&);
@@ -73,7 +73,7 @@ private:
JSObjectCallAsFunctionCallback m_functionCallback;
JSObjectCallAsConstructorCallback m_constructCallback;
- OwnPtr<ObjCCallbackFunctionImpl> m_impl;
+ std::unique_ptr<ObjCCallbackFunctionImpl> m_impl;
};
} // namespace JSC
diff --git a/Source/JavaScriptCore/API/ObjcRuntimeExtras.h b/Source/JavaScriptCore/API/ObjcRuntimeExtras.h
new file mode 100644
index 000000000..128df5c90
--- /dev/null
+++ b/Source/JavaScriptCore/API/ObjcRuntimeExtras.h
@@ -0,0 +1,242 @@
+/*
+ * 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 <objc/Protocol.h>
+#import <objc/runtime.h>
+#import <wtf/HashSet.h>
+#import <wtf/Vector.h>
+
+inline bool protocolImplementsProtocol(Protocol *candidate, Protocol *target)
+{
+ unsigned protocolProtocolsCount;
+ Protocol ** protocolProtocols = protocol_copyProtocolList(candidate, &protocolProtocolsCount);
+ for (unsigned i = 0; i < protocolProtocolsCount; ++i) {
+ if (protocol_isEqual(protocolProtocols[i], target)) {
+ free(protocolProtocols);
+ return true;
+ }
+ }
+ free(protocolProtocols);
+ return false;
+}
+
+inline void forEachProtocolImplementingProtocol(Class cls, Protocol *target, void (^callback)(Protocol *))
+{
+ ASSERT(cls);
+ ASSERT(target);
+
+ Vector<Protocol *> worklist;
+ HashSet<void*> visited;
+
+ // Initially fill the worklist with the Class's protocols.
+ unsigned protocolsCount;
+ Protocol ** protocols = class_copyProtocolList(cls, &protocolsCount);
+ worklist.append(protocols, protocolsCount);
+ free(protocols);
+
+ while (!worklist.isEmpty()) {
+ Protocol *protocol = worklist.last();
+ worklist.removeLast();
+
+ // Are we encountering this Protocol for the first time?
+ if (!visited.add(protocol).isNewEntry)
+ continue;
+
+ // If it implements the protocol, make the callback.
+ if (protocolImplementsProtocol(protocol, target))
+ callback(protocol);
+
+ // Add incorporated protocols to the worklist.
+ protocols = protocol_copyProtocolList(protocol, &protocolsCount);
+ worklist.append(protocols, protocolsCount);
+ free(protocols);
+ }
+}
+
+inline void forEachMethodInClass(Class cls, void (^callback)(Method))
+{
+ unsigned count;
+ Method* methods = class_copyMethodList(cls, &count);
+ for (unsigned i = 0; i < count; ++i)
+ callback(methods[i]);
+ free(methods);
+}
+
+inline void forEachMethodInProtocol(Protocol *protocol, BOOL isRequiredMethod, BOOL isInstanceMethod, void (^callback)(SEL, const char*))
+{
+ unsigned count;
+ struct objc_method_description* methods = protocol_copyMethodDescriptionList(protocol, isRequiredMethod, isInstanceMethod, &count);
+ for (unsigned i = 0; i < count; ++i)
+ callback(methods[i].name, methods[i].types);
+ free(methods);
+}
+
+inline void forEachPropertyInProtocol(Protocol *protocol, void (^callback)(objc_property_t))
+{
+ unsigned count;
+ objc_property_t* properties = protocol_copyPropertyList(protocol, &count);
+ for (unsigned i = 0; i < count; ++i)
+ callback(properties[i]);
+ free(properties);
+}
+
+template<char open, char close>
+void skipPair(const char*& position)
+{
+ size_t count = 1;
+ do {
+ char c = *position++;
+ if (!c)
+ @throw [NSException exceptionWithName:NSInternalInconsistencyException reason:@"Malformed type encoding" userInfo:nil];
+ if (c == open)
+ ++count;
+ else if (c == close)
+ --count;
+ } while (count);
+}
+
+class StringRange {
+ WTF_MAKE_NONCOPYABLE(StringRange);
+public:
+ StringRange(const char* begin, const char* end) : m_ptr(strndup(begin, end - begin)) { }
+ ~StringRange() { free(m_ptr); }
+ operator const char*() const { return m_ptr; }
+ const char* get() const { return m_ptr; }
+
+private:
+ char* m_ptr;
+};
+
+class StructBuffer {
+ WTF_MAKE_NONCOPYABLE(StructBuffer);
+public:
+ StructBuffer(const char* encodedType)
+ {
+ NSUInteger size, alignment;
+ NSGetSizeAndAlignment(encodedType, &size, &alignment);
+ --alignment;
+ m_allocation = static_cast<char*>(malloc(size + alignment));
+ m_buffer = reinterpret_cast<char*>((reinterpret_cast<intptr_t>(m_allocation) + alignment) & ~alignment);
+ }
+
+ ~StructBuffer() { free(m_allocation); }
+ operator void*() const { return m_buffer; }
+
+private:
+ void* m_allocation;
+ void* m_buffer;
+};
+
+template<typename DelegateType>
+typename DelegateType::ResultType parseObjCType(const char*& position)
+{
+ ASSERT(*position);
+
+ switch (*position++) {
+ case 'c':
+ return DelegateType::template typeInteger<char>();
+ case 'i':
+ return DelegateType::template typeInteger<int>();
+ case 's':
+ return DelegateType::template typeInteger<short>();
+ case 'l':
+ return DelegateType::template typeInteger<long>();
+ case 'q':
+ return DelegateType::template typeDouble<long long>();
+ case 'C':
+ return DelegateType::template typeInteger<unsigned char>();
+ case 'I':
+ return DelegateType::template typeInteger<unsigned>();
+ case 'S':
+ return DelegateType::template typeInteger<unsigned short>();
+ case 'L':
+ return DelegateType::template typeInteger<unsigned long>();
+ case 'Q':
+ return DelegateType::template typeDouble<unsigned long long>();
+ case 'f':
+ return DelegateType::template typeDouble<float>();
+ case 'd':
+ return DelegateType::template typeDouble<double>();
+ case 'B':
+ return DelegateType::typeBool();
+ case 'v':
+ return DelegateType::typeVoid();
+
+ case '@': { // An object (whether statically typed or typed id)
+ if (position[0] == '?' && position[1] == '<') {
+ position += 2;
+ const char* begin = position;
+ skipPair<'<','>'>(position);
+ return DelegateType::typeBlock(begin, position - 1);
+ }
+
+ if (*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();
+ }
+
+ case '{': { // {name=type...} A structure
+ const char* begin = position - 1;
+ skipPair<'{','}'>(position);
+ return DelegateType::typeStruct(begin, position);
+ }
+
+ // NOT supporting C strings, arrays, pointers, unions, bitfields, function pointers.
+ case '*': // A character string (char *)
+ case '[': // [array type] An array
+ case '(': // (name=type...) A union
+ case 'b': // bnum A bit field of num bits
+ case '^': // ^type A pointer to type
+ case '?': // An unknown type (among other things, this code is used for function pointers)
+ // NOT supporting Objective-C Class, SEL
+ case '#': // A class object (Class)
+ case ':': // A method selector (SEL)
+ default:
+ return nil;
+ }
+}
+
+extern "C" {
+ // Forward declare some Objective-C runtime internal methods that are not API.
+ const char *_protocol_getMethodTypeEncoding(Protocol *, SEL, BOOL isRequiredMethod, BOOL isInstanceMethod);
+ id objc_initWeak(id *, id);
+ void objc_destroyWeak(id *);
+ bool _Block_has_signature(void *);
+ const char * _Block_signature(void *);
+}
diff --git a/Source/JavaScriptCore/API/OpaqueJSString.cpp b/Source/JavaScriptCore/API/OpaqueJSString.cpp
index 5cc2e0ab8..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
@@ -28,11 +28,13 @@
#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 nullptr;
@@ -47,7 +49,7 @@ OpaqueJSString::~OpaqueJSString()
if (!characters)
return;
- if (!m_string.is8Bit() && m_string.deprecatedCharacters() == characters)
+ if (!m_string.is8Bit() && m_string.characters16() == characters)
return;
fastFree(characters);
@@ -55,32 +57,26 @@ OpaqueJSString::~OpaqueJSString()
String OpaqueJSString::string() const
{
- if (!this)
- return String();
-
// 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(vm, m_string.characters16(), m_string.length());
+ return Identifier::fromString(vm, m_string.characters16(), m_string.length());
}
const UChar* OpaqueJSString::characters()
{
- if (!this)
- return nullptr;
-
// m_characters is put in a local here to avoid an extra atomic load.
UChar* characters = m_characters;
if (characters)
@@ -91,12 +87,7 @@ const UChar* OpaqueJSString::characters()
unsigned length = m_string.length();
UChar* newCharacters = static_cast<UChar*>(fastMalloc(length * sizeof(UChar)));
-
- if (m_string.is8Bit()) {
- for (size_t i = 0; i < length; ++i)
- newCharacters[i] = m_string.characters8()[i];
- } else
- memcpy(newCharacters, m_string.characters16(), length * sizeof(UChar));
+ StringView(m_string).getCharactersWithUpconvert(newCharacters);
if (!m_characters.compare_exchange_strong(characters, newCharacters)) {
fastFree(newCharacters);
diff --git a/Source/JavaScriptCore/API/OpaqueJSString.h b/Source/JavaScriptCore/API/OpaqueJSString.h
index f1dd6a43d..208131b3b 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
@@ -36,29 +36,29 @@ namespace JSC {
}
struct OpaqueJSString : public ThreadSafeRefCounted<OpaqueJSString> {
- static PassRefPtr<OpaqueJSString> create()
+ 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 this ? m_string.is8Bit() : false; }
- const LChar* characters8() { return this ? m_string.characters8() : nullptr; }
- const UChar* characters16() { return this ? m_string.characters16() : nullptr; }
- unsigned length() { return this ? m_string.length() : 0; }
+ 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();
diff --git a/Source/JavaScriptCore/API/WebKitAvailability.h b/Source/JavaScriptCore/API/WebKitAvailability.h
index 6af619825..f878beae9 100644
--- a/Source/JavaScriptCore/API/WebKitAvailability.h
+++ b/Source/JavaScriptCore/API/WebKitAvailability.h
@@ -26,9 +26,49 @@
#ifndef __WebKitAvailability__
#define __WebKitAvailability__
-#if defined(__APPLE__) && !defined(BUILDING_GTK__)
+#if defined(__APPLE__)
+
#include <AvailabilityMacros.h>
#include <CoreFoundation/CoreFoundation.h>
+
+#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.
+*/
+
+#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
+
+#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
+
+#ifndef __AVAILABILITY_INTERNAL__MAC_10_9
+#define __AVAILABILITY_INTERNAL__MAC_10_9
+#endif
+
+#ifndef __AVAILABILITY_INTERNAL__MAC_10_10
+#define __AVAILABILITY_INTERNAL__MAC_10_10
+#endif
+
+#ifndef AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER
+#define AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER
+#endif
+
+#ifndef AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER
+#define AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER
+#endif
+
+#endif /* __MAC_OS_X_VERSION_MIN_REQUIRED <= 101100 */
+
+#if defined(BUILDING_GTK__)
+#undef CF_AVAILABLE
+#define CF_AVAILABLE(_mac, _ios)
+#endif
+
#else
#define CF_AVAILABLE(_mac, _ios)
#endif
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 f4ccf91e4..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"
diff --git a/Source/JavaScriptCore/API/tests/minidom.html b/Source/JavaScriptCore/API/tests/minidom.html
new file mode 100644
index 000000000..7ea474752
--- /dev/null
+++ b/Source/JavaScriptCore/API/tests/minidom.html
@@ -0,0 +1,9 @@
+<html>
+<head>
+<script src="minidom.js"></script>
+</head>
+
+<body onload="test()">
+ <pre id='pre'></pre>
+</body>
+</html>
diff --git a/Source/JavaScriptCore/API/tests/minidom.js b/Source/JavaScriptCore/API/tests/minidom.js
new file mode 100644
index 000000000..85134d7cb
--- /dev/null
+++ b/Source/JavaScriptCore/API/tests/minidom.js
@@ -0,0 +1,110 @@
+/*
+ * 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
+ * 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.
+ */
+
+function shouldBe(a, b)
+{
+ var evalA;
+ try {
+ evalA = eval(a);
+ } catch(e) {
+ evalA = e;
+ }
+
+ if (evalA == b || isNaN(evalA) && typeof evalA == 'number' && isNaN(b) && typeof b == 'number')
+ print("PASS: " + a + " should be " + b + " and is.", "green");
+ else
+ print("__FAIL__: " + a + " should be " + b + " but instead is " + evalA + ".", "red");
+}
+
+function test()
+{
+ print("Node is " + Node);
+ for (var p in Node)
+ print(p + ": " + Node[p]);
+
+ node = new Node();
+ print("node is " + node);
+ for (var p in node)
+ print(p + ": " + node[p]);
+
+ child1 = new Node();
+ child2 = new Node();
+ child3 = new Node();
+
+ node.appendChild(child1);
+ node.appendChild(child2);
+
+ var childNodes = node.childNodes;
+
+ for (var i = 0; i < childNodes.length + 1; i++) {
+ print("item " + i + ": " + childNodes.item(i));
+ }
+
+ for (var i = 0; i < childNodes.length + 1; i++) {
+ print(i + ": " + childNodes[i]);
+ }
+
+ node.removeChild(child1);
+ node.replaceChild(child3, child2);
+
+ for (var i = 0; i < childNodes.length + 1; i++) {
+ print("item " + i + ": " + childNodes.item(i));
+ }
+
+ for (var i = 0; i < childNodes.length + 1; i++) {
+ print(i + ": " + childNodes[i]);
+ }
+
+ try {
+ node.appendChild(null);
+ } catch(e) {
+ print("caught: " + e);
+ }
+
+ try {
+ var o = new Object();
+ o.appendChild = node.appendChild;
+ o.appendChild(node);
+ } catch(e) {
+ print("caught: " + e);
+ }
+
+ try {
+ node.appendChild();
+ } catch(e) {
+ print("caught: " + e);
+ }
+
+ oldNodeType = node.nodeType;
+ node.nodeType = 1;
+ shouldBe("node.nodeType", oldNodeType);
+
+ shouldBe("node instanceof Node", true);
+ shouldBe("new Object() instanceof Node", false);
+
+ print(Node);
+}
+
+test();
diff --git a/Source/JavaScriptCore/API/tests/testapi.c b/Source/JavaScriptCore/API/tests/testapi.c
new file mode 100644
index 000000000..cbf9daf18
--- /dev/null
+++ b/Source/JavaScriptCore/API/tests/testapi.c
@@ -0,0 +1,1994 @@
+/*
+ * 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
+ * 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 <wtf/Platform.h>
+
+#include "JavaScriptCore.h"
+#include "JSBasePrivate.h"
+#include "JSContextRefPrivate.h"
+#include "JSObjectRefPrivate.h"
+#include "JSScriptRefPrivate.h"
+#include "JSStringRefPrivate.h"
+#include <math.h>
+#define ASSERT_DISABLED 0
+#include <wtf/Assertions.h>
+
+#if OS(WINDOWS)
+#include <windows.h>
+#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;
+int failed;
+static void assertEqualsAsBoolean(JSValueRef value, bool expectedValue)
+{
+ if (JSValueToBoolean(context, value) != expectedValue) {
+ fprintf(stderr, "assertEqualsAsBoolean failed: %p, %d\n", value, expectedValue);
+ failed = 1;
+ }
+}
+
+static void assertEqualsAsNumber(JSValueRef value, double expectedValue)
+{
+ double number = JSValueToNumber(context, value, NULL);
+
+ // FIXME <rdar://4668451> - On i386 the isnan(double) macro tries to map to the isnan(float) function,
+ // causing a build break with -Wshorten-64-to-32 enabled. The issue is known by the appropriate team.
+ // After that's resolved, we can remove these casts
+ if (number != expectedValue && !(isnan((float)number) && isnan((float)expectedValue))) {
+ fprintf(stderr, "assertEqualsAsNumber failed: %p, %lf\n", value, expectedValue);
+ failed = 1;
+ }
+}
+
+static void assertEqualsAsUTF8String(JSValueRef value, const char* expectedValue)
+{
+ JSStringRef valueAsString = JSValueToStringCopy(context, value, NULL);
+
+ 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;
+ }
+ }
+
+ if (jsSize < strlen(jsBuffer) + 1) {
+ fprintf(stderr, "assertEqualsAsUTF8String failed: jsSize was too small\n");
+ failed = 1;
+ }
+
+ free(jsBuffer);
+ JSStringRelease(valueAsString);
+}
+
+static void assertEqualsAsCharactersPtr(JSValueRef value, const char* expectedValue)
+{
+ JSStringRef valueAsString = JSValueToStringCopy(context, value, NULL);
+
+ size_t jsLength = JSStringGetLength(valueAsString);
+ const JSChar* jsBuffer = JSStringGetCharactersPtr(valueAsString);
+
+ CFStringRef expectedValueAsCFString = CFStringCreateWithCString(kCFAllocatorDefault,
+ expectedValue,
+ kCFStringEncodingUTF8);
+ CFIndex cfLength = CFStringGetLength(expectedValueAsCFString);
+ UniChar* cfBuffer = (UniChar*)malloc(cfLength * sizeof(UniChar));
+ CFStringGetCharacters(expectedValueAsCFString, CFRangeMake(0, cfLength), cfBuffer);
+ CFRelease(expectedValueAsCFString);
+
+ if (memcmp(jsBuffer, cfBuffer, cfLength * sizeof(UniChar)) != 0) {
+ fprintf(stderr, "assertEqualsAsCharactersPtr failed: jsBuffer != cfBuffer\n");
+ failed = 1;
+ }
+
+ if (jsLength != (size_t)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;
+ }
+
+ free(cfBuffer);
+ JSStringRelease(valueAsString);
+}
+
+static bool timeZoneIsPST()
+{
+ char timeZoneName[70];
+ struct tm gtm;
+ memset(&gtm, 0, sizeof(gtm));
+ strftime(timeZoneName, sizeof(timeZoneName), "%Z", &gtm);
+
+ return 0 == strcmp("PST", timeZoneName);
+}
+
+static JSValueRef jsGlobalValue; // non-stack value for testing JSValueProtect()
+
+/* MyObject pseudo-class */
+
+static bool MyObject_hasProperty(JSContextRef context, JSObjectRef object, JSStringRef propertyName)
+{
+ UNUSED_PARAM(context);
+ UNUSED_PARAM(object);
+
+ if (JSStringIsEqualToUTF8CString(propertyName, "alwaysOne")
+ || JSStringIsEqualToUTF8CString(propertyName, "cantFind")
+ || JSStringIsEqualToUTF8CString(propertyName, "throwOnGet")
+ || JSStringIsEqualToUTF8CString(propertyName, "myPropertyName")
+ || JSStringIsEqualToUTF8CString(propertyName, "hasPropertyLie")
+ || JSStringIsEqualToUTF8CString(propertyName, "0")) {
+ return true;
+ }
+
+ return false;
+}
+
+static JSValueRef MyObject_getProperty(JSContextRef context, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception)
+{
+ UNUSED_PARAM(context);
+ UNUSED_PARAM(object);
+
+ if (JSStringIsEqualToUTF8CString(propertyName, "alwaysOne")) {
+ return JSValueMakeNumber(context, 1);
+ }
+
+ if (JSStringIsEqualToUTF8CString(propertyName, "myPropertyName")) {
+ return JSValueMakeNumber(context, 1);
+ }
+
+ if (JSStringIsEqualToUTF8CString(propertyName, "cantFind")) {
+ return JSValueMakeUndefined(context);
+ }
+
+ if (JSStringIsEqualToUTF8CString(propertyName, "hasPropertyLie")) {
+ return 0;
+ }
+
+ if (JSStringIsEqualToUTF8CString(propertyName, "throwOnGet")) {
+ return JSEvaluateScript(context, JSStringCreateWithUTF8CString("throw 'an exception'"), object, JSStringCreateWithUTF8CString("test script"), 1, exception);
+ }
+
+ if (JSStringIsEqualToUTF8CString(propertyName, "0")) {
+ *exception = JSValueMakeNumber(context, 1);
+ return JSValueMakeNumber(context, 1);
+ }
+
+ return JSValueMakeNull(context);
+}
+
+static bool MyObject_setProperty(JSContextRef context, JSObjectRef object, JSStringRef propertyName, JSValueRef value, JSValueRef* exception)
+{
+ UNUSED_PARAM(context);
+ UNUSED_PARAM(object);
+ UNUSED_PARAM(value);
+ UNUSED_PARAM(exception);
+
+ if (JSStringIsEqualToUTF8CString(propertyName, "cantSet"))
+ return true; // pretend we set the property in order to swallow it
+
+ if (JSStringIsEqualToUTF8CString(propertyName, "throwOnSet")) {
+ JSEvaluateScript(context, JSStringCreateWithUTF8CString("throw 'an exception'"), object, JSStringCreateWithUTF8CString("test script"), 1, exception);
+ }
+
+ return false;
+}
+
+static bool MyObject_deleteProperty(JSContextRef context, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception)
+{
+ UNUSED_PARAM(context);
+ UNUSED_PARAM(object);
+
+ if (JSStringIsEqualToUTF8CString(propertyName, "cantDelete"))
+ return true;
+
+ if (JSStringIsEqualToUTF8CString(propertyName, "throwOnDelete")) {
+ JSEvaluateScript(context, JSStringCreateWithUTF8CString("throw 'an exception'"), object, JSStringCreateWithUTF8CString("test script"), 1, exception);
+ return false;
+ }
+
+ return false;
+}
+
+static void MyObject_getPropertyNames(JSContextRef context, JSObjectRef object, JSPropertyNameAccumulatorRef propertyNames)
+{
+ UNUSED_PARAM(context);
+ UNUSED_PARAM(object);
+
+ JSStringRef propertyName;
+
+ propertyName = JSStringCreateWithUTF8CString("alwaysOne");
+ JSPropertyNameAccumulatorAddName(propertyNames, propertyName);
+ JSStringRelease(propertyName);
+
+ propertyName = JSStringCreateWithUTF8CString("myPropertyName");
+ JSPropertyNameAccumulatorAddName(propertyNames, propertyName);
+ JSStringRelease(propertyName);
+}
+
+static JSValueRef MyObject_callAsFunction(JSContextRef context, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ UNUSED_PARAM(context);
+ UNUSED_PARAM(object);
+ UNUSED_PARAM(thisObject);
+ UNUSED_PARAM(exception);
+
+ if (argumentCount > 0 && JSValueIsString(context, arguments[0]) && JSStringIsEqualToUTF8CString(JSValueToStringCopy(context, arguments[0], 0), "throwOnCall")) {
+ JSEvaluateScript(context, JSStringCreateWithUTF8CString("throw 'an exception'"), object, JSStringCreateWithUTF8CString("test script"), 1, exception);
+ return JSValueMakeUndefined(context);
+ }
+
+ if (argumentCount > 0 && JSValueIsStrictEqual(context, arguments[0], JSValueMakeNumber(context, 0)))
+ return JSValueMakeNumber(context, 1);
+
+ return JSValueMakeUndefined(context);
+}
+
+static JSObjectRef MyObject_callAsConstructor(JSContextRef context, JSObjectRef object, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ UNUSED_PARAM(context);
+ UNUSED_PARAM(object);
+
+ if (argumentCount > 0 && JSValueIsString(context, arguments[0]) && JSStringIsEqualToUTF8CString(JSValueToStringCopy(context, arguments[0], 0), "throwOnConstruct")) {
+ JSEvaluateScript(context, JSStringCreateWithUTF8CString("throw 'an exception'"), object, JSStringCreateWithUTF8CString("test script"), 1, exception);
+ return object;
+ }
+
+ if (argumentCount > 0 && JSValueIsStrictEqual(context, arguments[0], JSValueMakeNumber(context, 0)))
+ return JSValueToObject(context, JSValueMakeNumber(context, 1), exception);
+
+ return JSValueToObject(context, JSValueMakeNumber(context, 0), exception);
+}
+
+static bool MyObject_hasInstance(JSContextRef context, JSObjectRef constructor, JSValueRef possibleValue, JSValueRef* exception)
+{
+ UNUSED_PARAM(context);
+ UNUSED_PARAM(constructor);
+
+ if (JSValueIsString(context, possibleValue) && JSStringIsEqualToUTF8CString(JSValueToStringCopy(context, possibleValue, 0), "throwOnHasInstance")) {
+ JSEvaluateScript(context, JSStringCreateWithUTF8CString("throw 'an exception'"), constructor, JSStringCreateWithUTF8CString("test script"), 1, exception);
+ return false;
+ }
+
+ JSStringRef numberString = JSStringCreateWithUTF8CString("Number");
+ JSObjectRef numberConstructor = JSValueToObject(context, JSObjectGetProperty(context, JSContextGetGlobalObject(context), numberString, exception), exception);
+ JSStringRelease(numberString);
+
+ return JSValueIsInstanceOfConstructor(context, possibleValue, numberConstructor, exception);
+}
+
+static JSValueRef MyObject_convertToType(JSContextRef context, JSObjectRef object, JSType type, JSValueRef* exception)
+{
+ UNUSED_PARAM(object);
+ UNUSED_PARAM(exception);
+
+ switch (type) {
+ case kJSTypeNumber:
+ return JSValueMakeNumber(context, 1);
+ case kJSTypeString:
+ {
+ JSStringRef string = JSStringCreateWithUTF8CString("MyObjectAsString");
+ JSValueRef result = JSValueMakeString(context, string);
+ JSStringRelease(string);
+ return result;
+ }
+ default:
+ break;
+ }
+
+ // string conversion -- forward to default object class
+ return JSValueMakeNull(context);
+}
+
+static JSValueRef MyObject_convertToTypeWrapper(JSContextRef context, JSObjectRef object, JSType type, JSValueRef* exception)
+{
+ UNUSED_PARAM(context);
+ UNUSED_PARAM(object);
+ UNUSED_PARAM(type);
+ UNUSED_PARAM(exception);
+ // Forward to default object class
+ return 0;
+}
+
+static bool MyObject_set_nullGetForwardSet(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef value, JSValueRef* exception)
+{
+ UNUSED_PARAM(ctx);
+ UNUSED_PARAM(object);
+ UNUSED_PARAM(propertyName);
+ UNUSED_PARAM(value);
+ UNUSED_PARAM(exception);
+ return false; // Forward to parent class.
+}
+
+static JSStaticValue evilStaticValues[] = {
+ { "nullGetSet", 0, 0, kJSPropertyAttributeNone },
+ { "nullGetForwardSet", 0, MyObject_set_nullGetForwardSet, kJSPropertyAttributeNone },
+ { 0, 0, 0, 0 }
+};
+
+static JSStaticFunction evilStaticFunctions[] = {
+ { "nullCall", 0, kJSPropertyAttributeNone },
+ { 0, 0, 0 }
+};
+
+JSClassDefinition MyObject_definition = {
+ 0,
+ kJSClassAttributeNone,
+
+ "MyObject",
+ NULL,
+
+ evilStaticValues,
+ evilStaticFunctions,
+
+ NULL,
+ NULL,
+ MyObject_hasProperty,
+ MyObject_getProperty,
+ MyObject_setProperty,
+ MyObject_deleteProperty,
+ MyObject_getPropertyNames,
+ MyObject_callAsFunction,
+ MyObject_callAsConstructor,
+ MyObject_hasInstance,
+ MyObject_convertToType,
+};
+
+JSClassDefinition MyObject_convertToTypeWrapperDefinition = {
+ 0,
+ kJSClassAttributeNone,
+
+ "MyObject",
+ NULL,
+
+ NULL,
+ NULL,
+
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ MyObject_convertToTypeWrapper,
+};
+
+JSClassDefinition MyObject_nullWrapperDefinition = {
+ 0,
+ kJSClassAttributeNone,
+
+ "MyObject",
+ NULL,
+
+ NULL,
+ NULL,
+
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+};
+
+static JSClassRef MyObject_class(JSContextRef context)
+{
+ UNUSED_PARAM(context);
+
+ static JSClassRef jsClass;
+ if (!jsClass) {
+ JSClassRef baseClass = JSClassCreate(&MyObject_definition);
+ MyObject_convertToTypeWrapperDefinition.parentClass = baseClass;
+ JSClassRef wrapperClass = JSClassCreate(&MyObject_convertToTypeWrapperDefinition);
+ MyObject_nullWrapperDefinition.parentClass = wrapperClass;
+ jsClass = JSClassCreate(&MyObject_nullWrapperDefinition);
+ }
+
+ return jsClass;
+}
+
+static JSValueRef PropertyCatchalls_getProperty(JSContextRef context, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception)
+{
+ UNUSED_PARAM(context);
+ UNUSED_PARAM(object);
+ UNUSED_PARAM(propertyName);
+ UNUSED_PARAM(exception);
+
+ if (JSStringIsEqualToUTF8CString(propertyName, "x")) {
+ static size_t count;
+ if (count++ < 5)
+ return NULL;
+
+ // Swallow all .x gets after 5, returning null.
+ return JSValueMakeNull(context);
+ }
+
+ if (JSStringIsEqualToUTF8CString(propertyName, "y")) {
+ static size_t count;
+ if (count++ < 5)
+ return NULL;
+
+ // Swallow all .y gets after 5, returning null.
+ return JSValueMakeNull(context);
+ }
+
+ if (JSStringIsEqualToUTF8CString(propertyName, "z")) {
+ static size_t count;
+ if (count++ < 5)
+ return NULL;
+
+ // Swallow all .y gets after 5, returning null.
+ return JSValueMakeNull(context);
+ }
+
+ return NULL;
+}
+
+static bool PropertyCatchalls_setProperty(JSContextRef context, JSObjectRef object, JSStringRef propertyName, JSValueRef value, JSValueRef* exception)
+{
+ UNUSED_PARAM(context);
+ UNUSED_PARAM(object);
+ UNUSED_PARAM(propertyName);
+ UNUSED_PARAM(value);
+ UNUSED_PARAM(exception);
+
+ if (JSStringIsEqualToUTF8CString(propertyName, "x")) {
+ static size_t count;
+ if (count++ < 5)
+ return false;
+
+ // Swallow all .x sets after 4.
+ return true;
+ }
+
+ if (JSStringIsEqualToUTF8CString(propertyName, "make_throw") || JSStringIsEqualToUTF8CString(propertyName, "0")) {
+ *exception = JSValueMakeNumber(context, 5);
+ return true;
+ }
+
+ return false;
+}
+
+static void PropertyCatchalls_getPropertyNames(JSContextRef context, JSObjectRef object, JSPropertyNameAccumulatorRef propertyNames)
+{
+ UNUSED_PARAM(context);
+ UNUSED_PARAM(object);
+
+ static size_t count;
+ static const char* numbers[] = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };
+
+ // Provide a property of a different name every time.
+ JSStringRef propertyName = JSStringCreateWithUTF8CString(numbers[count++ % 10]);
+ JSPropertyNameAccumulatorAddName(propertyNames, propertyName);
+ JSStringRelease(propertyName);
+}
+
+JSClassDefinition PropertyCatchalls_definition = {
+ 0,
+ kJSClassAttributeNone,
+
+ "PropertyCatchalls",
+ NULL,
+
+ NULL,
+ NULL,
+
+ NULL,
+ NULL,
+ NULL,
+ PropertyCatchalls_getProperty,
+ PropertyCatchalls_setProperty,
+ NULL,
+ PropertyCatchalls_getPropertyNames,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+};
+
+static JSClassRef PropertyCatchalls_class(JSContextRef context)
+{
+ UNUSED_PARAM(context);
+
+ static JSClassRef jsClass;
+ if (!jsClass)
+ jsClass = JSClassCreate(&PropertyCatchalls_definition);
+
+ return jsClass;
+}
+
+static bool EvilExceptionObject_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;
+ JSObjectRef function = JSValueToObject(context, hasInstance, exception);
+ JSValueRef result = JSObjectCallAsFunction(context, function, constructor, 1, &possibleValue, exception);
+ return result && JSValueToBoolean(context, result);
+}
+
+static JSValueRef EvilExceptionObject_convertToType(JSContextRef context, JSObjectRef object, JSType type, JSValueRef* exception)
+{
+ UNUSED_PARAM(object);
+ UNUSED_PARAM(exception);
+ JSStringRef funcName;
+ switch (type) {
+ case kJSTypeNumber:
+ funcName = JSStringCreateWithUTF8CString("toNumber");
+ break;
+ case kJSTypeString:
+ funcName = JSStringCreateWithUTF8CString("toStringExplicit");
+ break;
+ default:
+ return JSValueMakeNull(context);
+ }
+
+ JSValueRef func = JSObjectGetProperty(context, object, funcName, exception);
+ JSStringRelease(funcName);
+ JSObjectRef function = JSValueToObject(context, func, exception);
+ if (!function)
+ return JSValueMakeNull(context);
+ JSValueRef value = JSObjectCallAsFunction(context, function, object, 0, NULL, exception);
+ if (!value) {
+ JSStringRef errorString = JSStringCreateWithUTF8CString("convertToType failed");
+ JSValueRef errorStringRef = JSValueMakeString(context, errorString);
+ JSStringRelease(errorString);
+ return errorStringRef;
+ }
+ return value;
+}
+
+JSClassDefinition EvilExceptionObject_definition = {
+ 0,
+ kJSClassAttributeNone,
+
+ "EvilExceptionObject",
+ NULL,
+
+ NULL,
+ NULL,
+
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ EvilExceptionObject_hasInstance,
+ EvilExceptionObject_convertToType,
+};
+
+static JSClassRef EvilExceptionObject_class(JSContextRef context)
+{
+ UNUSED_PARAM(context);
+
+ static JSClassRef jsClass;
+ if (!jsClass)
+ jsClass = JSClassCreate(&EvilExceptionObject_definition);
+
+ return jsClass;
+}
+
+JSClassDefinition EmptyObject_definition = {
+ 0,
+ kJSClassAttributeNone,
+
+ NULL,
+ NULL,
+
+ NULL,
+ NULL,
+
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+};
+
+static JSClassRef EmptyObject_class(JSContextRef context)
+{
+ UNUSED_PARAM(context);
+
+ static JSClassRef jsClass;
+ if (!jsClass)
+ jsClass = JSClassCreate(&EmptyObject_definition);
+
+ return jsClass;
+}
+
+
+static JSValueRef Base_get(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception)
+{
+ UNUSED_PARAM(object);
+ UNUSED_PARAM(propertyName);
+ UNUSED_PARAM(exception);
+
+ return JSValueMakeNumber(ctx, 1); // distinguish base get form derived get
+}
+
+static bool Base_set(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef value, JSValueRef* exception)
+{
+ UNUSED_PARAM(object);
+ UNUSED_PARAM(propertyName);
+ UNUSED_PARAM(value);
+
+ *exception = JSValueMakeNumber(ctx, 1); // distinguish base set from derived set
+ return true;
+}
+
+static JSValueRef Base_callAsFunction(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ UNUSED_PARAM(function);
+ UNUSED_PARAM(thisObject);
+ UNUSED_PARAM(argumentCount);
+ UNUSED_PARAM(arguments);
+ UNUSED_PARAM(exception);
+
+ return JSValueMakeNumber(ctx, 1); // distinguish base call from derived call
+}
+
+static JSValueRef Base_returnHardNull(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ UNUSED_PARAM(ctx);
+ UNUSED_PARAM(function);
+ UNUSED_PARAM(thisObject);
+ UNUSED_PARAM(argumentCount);
+ UNUSED_PARAM(arguments);
+ UNUSED_PARAM(exception);
+
+ return 0; // should convert to undefined!
+}
+
+static JSStaticFunction Base_staticFunctions[] = {
+ { "baseProtoDup", NULL, kJSPropertyAttributeNone },
+ { "baseProto", Base_callAsFunction, kJSPropertyAttributeNone },
+ { "baseHardNull", Base_returnHardNull, kJSPropertyAttributeNone },
+ { 0, 0, 0 }
+};
+
+static JSStaticValue Base_staticValues[] = {
+ { "baseDup", Base_get, Base_set, kJSPropertyAttributeNone },
+ { "baseOnly", Base_get, Base_set, kJSPropertyAttributeNone },
+ { 0, 0, 0, 0 }
+};
+
+static bool TestInitializeFinalize;
+static void Base_initialize(JSContextRef context, JSObjectRef object)
+{
+ UNUSED_PARAM(context);
+
+ if (TestInitializeFinalize) {
+ ASSERT((void*)1 == JSObjectGetPrivate(object));
+ JSObjectSetPrivate(object, (void*)2);
+ }
+}
+
+static unsigned Base_didFinalize;
+static void Base_finalize(JSObjectRef object)
+{
+ UNUSED_PARAM(object);
+ if (TestInitializeFinalize) {
+ ASSERT((void*)4 == JSObjectGetPrivate(object));
+ Base_didFinalize = true;
+ }
+}
+
+static JSClassRef Base_class(JSContextRef context)
+{
+ UNUSED_PARAM(context);
+
+ static JSClassRef jsClass;
+ if (!jsClass) {
+ JSClassDefinition definition = kJSClassDefinitionEmpty;
+ definition.staticValues = Base_staticValues;
+ definition.staticFunctions = Base_staticFunctions;
+ definition.initialize = Base_initialize;
+ definition.finalize = Base_finalize;
+ jsClass = JSClassCreate(&definition);
+ }
+ return jsClass;
+}
+
+static JSValueRef Derived_get(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception)
+{
+ UNUSED_PARAM(object);
+ UNUSED_PARAM(propertyName);
+ UNUSED_PARAM(exception);
+
+ return JSValueMakeNumber(ctx, 2); // distinguish base get form derived get
+}
+
+static bool Derived_set(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef value, JSValueRef* exception)
+{
+ UNUSED_PARAM(ctx);
+ UNUSED_PARAM(object);
+ UNUSED_PARAM(propertyName);
+ UNUSED_PARAM(value);
+
+ *exception = JSValueMakeNumber(ctx, 2); // distinguish base set from derived set
+ return true;
+}
+
+static JSValueRef Derived_callAsFunction(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ UNUSED_PARAM(function);
+ UNUSED_PARAM(thisObject);
+ UNUSED_PARAM(argumentCount);
+ UNUSED_PARAM(arguments);
+ UNUSED_PARAM(exception);
+
+ return JSValueMakeNumber(ctx, 2); // distinguish base call from derived call
+}
+
+static JSStaticFunction Derived_staticFunctions[] = {
+ { "protoOnly", Derived_callAsFunction, kJSPropertyAttributeNone },
+ { "protoDup", NULL, kJSPropertyAttributeNone },
+ { "baseProtoDup", Derived_callAsFunction, kJSPropertyAttributeNone },
+ { 0, 0, 0 }
+};
+
+static JSStaticValue Derived_staticValues[] = {
+ { "derivedOnly", Derived_get, Derived_set, kJSPropertyAttributeNone },
+ { "protoDup", Derived_get, Derived_set, kJSPropertyAttributeNone },
+ { "baseDup", Derived_get, Derived_set, kJSPropertyAttributeNone },
+ { 0, 0, 0, 0 }
+};
+
+static void Derived_initialize(JSContextRef context, JSObjectRef object)
+{
+ UNUSED_PARAM(context);
+
+ if (TestInitializeFinalize) {
+ ASSERT((void*)2 == JSObjectGetPrivate(object));
+ JSObjectSetPrivate(object, (void*)3);
+ }
+}
+
+static void Derived_finalize(JSObjectRef object)
+{
+ if (TestInitializeFinalize) {
+ ASSERT((void*)3 == JSObjectGetPrivate(object));
+ JSObjectSetPrivate(object, (void*)4);
+ }
+}
+
+static JSClassRef Derived_class(JSContextRef context)
+{
+ static JSClassRef jsClass;
+ if (!jsClass) {
+ JSClassDefinition definition = kJSClassDefinitionEmpty;
+ definition.parentClass = Base_class(context);
+ definition.staticValues = Derived_staticValues;
+ definition.staticFunctions = Derived_staticFunctions;
+ definition.initialize = Derived_initialize;
+ definition.finalize = Derived_finalize;
+ jsClass = JSClassCreate(&definition);
+ }
+ return jsClass;
+}
+
+static JSClassRef Derived2_class(JSContextRef context)
+{
+ static JSClassRef jsClass;
+ if (!jsClass) {
+ JSClassDefinition definition = kJSClassDefinitionEmpty;
+ definition.parentClass = Derived_class(context);
+ jsClass = JSClassCreate(&definition);
+ }
+ return jsClass;
+}
+
+static JSValueRef print_callAsFunction(JSContextRef ctx, JSObjectRef functionObject, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ UNUSED_PARAM(functionObject);
+ UNUSED_PARAM(thisObject);
+ UNUSED_PARAM(exception);
+
+ ASSERT(JSContextGetGlobalContext(ctx) == context);
+
+ if (argumentCount > 0) {
+ JSStringRef string = JSValueToStringCopy(ctx, arguments[0], NULL);
+ size_t sizeUTF8 = JSStringGetMaximumUTF8CStringSize(string);
+ char* stringUTF8 = (char*)malloc(sizeUTF8);
+ JSStringGetUTF8CString(string, stringUTF8, sizeUTF8);
+ printf("%s\n", stringUTF8);
+ free(stringUTF8);
+ JSStringRelease(string);
+ }
+
+ return JSValueMakeUndefined(ctx);
+}
+
+static JSObjectRef myConstructor_callAsConstructor(JSContextRef context, JSObjectRef constructorObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ UNUSED_PARAM(constructorObject);
+ UNUSED_PARAM(exception);
+
+ JSObjectRef result = JSObjectMake(context, NULL, NULL);
+ if (argumentCount > 0) {
+ JSStringRef value = JSStringCreateWithUTF8CString("value");
+ JSObjectSetProperty(context, result, value, arguments[0], kJSPropertyAttributeNone, NULL);
+ JSStringRelease(value);
+ }
+
+ return result;
+}
+
+static JSObjectRef myBadConstructor_callAsConstructor(JSContextRef context, JSObjectRef constructorObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ UNUSED_PARAM(context);
+ UNUSED_PARAM(constructorObject);
+ UNUSED_PARAM(argumentCount);
+ UNUSED_PARAM(arguments);
+ UNUSED_PARAM(exception);
+
+ return 0;
+}
+
+
+static void globalObject_initialize(JSContextRef context, JSObjectRef object)
+{
+ UNUSED_PARAM(object);
+ // Ensure that an execution context is passed in
+ ASSERT(context);
+
+ JSObjectRef globalObject = JSContextGetGlobalObject(context);
+ ASSERT(globalObject);
+
+ // Ensure that the standard global properties have been set on the global object
+ JSStringRef array = JSStringCreateWithUTF8CString("Array");
+ JSObjectRef arrayConstructor = JSValueToObject(context, JSObjectGetProperty(context, globalObject, array, NULL), NULL);
+ JSStringRelease(array);
+
+ UNUSED_PARAM(arrayConstructor);
+ ASSERT(arrayConstructor);
+}
+
+static JSValueRef globalObject_get(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception)
+{
+ UNUSED_PARAM(object);
+ UNUSED_PARAM(propertyName);
+ UNUSED_PARAM(exception);
+
+ return JSValueMakeNumber(ctx, 3);
+}
+
+static bool globalObject_set(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef value, JSValueRef* exception)
+{
+ UNUSED_PARAM(object);
+ UNUSED_PARAM(propertyName);
+ UNUSED_PARAM(value);
+
+ *exception = JSValueMakeNumber(ctx, 3);
+ return true;
+}
+
+static JSValueRef globalObject_call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ UNUSED_PARAM(function);
+ UNUSED_PARAM(thisObject);
+ UNUSED_PARAM(argumentCount);
+ UNUSED_PARAM(arguments);
+ UNUSED_PARAM(exception);
+
+ return JSValueMakeNumber(ctx, 3);
+}
+
+static JSValueRef functionGC(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ UNUSED_PARAM(function);
+ UNUSED_PARAM(thisObject);
+ UNUSED_PARAM(argumentCount);
+ UNUSED_PARAM(arguments);
+ UNUSED_PARAM(exception);
+ JSGarbageCollect(context);
+ return JSValueMakeUndefined(context);
+}
+
+static JSStaticValue globalObject_staticValues[] = {
+ { "globalStaticValue", globalObject_get, globalObject_set, kJSPropertyAttributeNone },
+ { 0, 0, 0, 0 }
+};
+
+static JSStaticFunction globalObject_staticFunctions[] = {
+ { "globalStaticFunction", globalObject_call, kJSPropertyAttributeNone },
+ { "globalStaticFunction2", globalObject_call, kJSPropertyAttributeNone },
+ { "gc", functionGC, kJSPropertyAttributeNone },
+ { 0, 0, 0 }
+};
+
+static char* createStringWithContentsOfFile(const char* fileName);
+
+static void testInitializeFinalize()
+{
+ JSObjectRef o = JSObjectMake(context, Derived_class(context), (void*)1);
+ UNUSED_PARAM(o);
+ ASSERT(JSObjectGetPrivate(o) == (void*)3);
+}
+
+static JSValueRef jsNumberValue = NULL;
+
+static JSObjectRef aHeapRef = NULL;
+
+static void makeGlobalNumberValue(JSContextRef context) {
+ JSValueRef v = JSValueMakeNumber(context, 420);
+ JSValueProtect(context, v);
+ jsNumberValue = v;
+ v = NULL;
+}
+
+bool assertTrue(bool value, const char* message)
+{
+ if (!value) {
+ if (message)
+ fprintf(stderr, "assertTrue failed: '%s'\n", message);
+ else
+ fprintf(stderr, "assertTrue failed.\n");
+ failed = 1;
+ }
+ return value;
+}
+
+static bool checkForCycleInPrototypeChain()
+{
+ bool result = true;
+ JSGlobalContextRef context = JSGlobalContextCreate(0);
+ JSObjectRef object1 = JSObjectMake(context, /* jsClass */ 0, /* data */ 0);
+ JSObjectRef object2 = JSObjectMake(context, /* jsClass */ 0, /* data */ 0);
+ JSObjectRef object3 = JSObjectMake(context, /* jsClass */ 0, /* data */ 0);
+
+ JSObjectSetPrototype(context, object1, JSValueMakeNull(context));
+ ASSERT(JSValueIsNull(context, JSObjectGetPrototype(context, object1)));
+
+ // object1 -> object1
+ JSObjectSetPrototype(context, object1, object1);
+ result &= assertTrue(JSValueIsNull(context, JSObjectGetPrototype(context, object1)), "It is possible to assign self as a prototype");
+
+ // object1 -> object2 -> object1
+ JSObjectSetPrototype(context, object2, object1);
+ ASSERT(JSValueIsStrictEqual(context, JSObjectGetPrototype(context, object2), object1));
+ JSObjectSetPrototype(context, object1, object2);
+ result &= assertTrue(JSValueIsNull(context, JSObjectGetPrototype(context, object1)), "It is possible to close a prototype chain cycle");
+
+ // object1 -> object2 -> object3 -> object1
+ JSObjectSetPrototype(context, object2, object3);
+ ASSERT(JSValueIsStrictEqual(context, JSObjectGetPrototype(context, object2), object3));
+ JSObjectSetPrototype(context, object1, object2);
+ ASSERT(JSValueIsStrictEqual(context, JSObjectGetPrototype(context, object1), object2));
+ JSObjectSetPrototype(context, object3, object1);
+ result &= assertTrue(!JSValueIsStrictEqual(context, JSObjectGetPrototype(context, object3), object1), "It is possible to close a prototype chain cycle");
+
+ JSValueRef exception;
+ JSStringRef code = JSStringCreateWithUTF8CString("o = { }; p = { }; o.__proto__ = p; p.__proto__ = o");
+ JSStringRef file = JSStringCreateWithUTF8CString("");
+ result &= assertTrue(!JSEvaluateScript(context, code, /* thisObject*/ 0, file, 1, &exception)
+ , "An exception should be thrown");
+
+ JSStringRelease(code);
+ JSStringRelease(file);
+ JSGlobalContextRelease(context);
+ return result;
+}
+
+static JSValueRef valueToObjectExceptionCallAsFunction(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ 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);
+}
+static bool valueToObjectExceptionTest()
+{
+ 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);
+
+ 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);
+
+ JSStringRelease(test);
+ JSClassRelease(globalObjectClass);
+ JSGlobalContextRelease(testContext);
+
+ return true;
+}
+
+static bool globalContextNameTest()
+{
+ bool result = true;
+ JSGlobalContextRef context = JSGlobalContextCreate(0);
+
+ JSStringRef str = JSGlobalContextCopyName(context);
+ result &= assertTrue(!str, "Default context name is NULL");
+
+ JSStringRef name1 = JSStringCreateWithUTF8CString("name1");
+ JSStringRef name2 = JSStringCreateWithUTF8CString("name2");
+
+ 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;
+}
+
+static void checkConstnessInJSObjectNames()
+{
+ JSStaticFunction fun;
+ fun.name = "something";
+ JSStaticValue val;
+ val.name = "something";
+}
+
+
+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
+
+ const char *scriptPath = "testapi.js";
+ if (argc > 1) {
+ scriptPath = argv[1];
+ }
+
+ // Test garbage collection with a fresh context
+ context = JSGlobalContextCreateInGroup(NULL, NULL);
+ TestInitializeFinalize = true;
+ testInitializeFinalize();
+ JSGlobalContextRelease(context);
+ TestInitializeFinalize = false;
+
+ ASSERT(Base_didFinalize);
+
+ JSClassDefinition globalObjectClassDefinition = kJSClassDefinitionEmpty;
+ globalObjectClassDefinition.initialize = globalObject_initialize;
+ globalObjectClassDefinition.staticValues = globalObject_staticValues;
+ globalObjectClassDefinition.staticFunctions = globalObject_staticFunctions;
+ globalObjectClassDefinition.attributes = kJSClassAttributeNoAutomaticPrototype;
+ JSClassRef globalObjectClass = JSClassCreate(&globalObjectClassDefinition);
+ context = JSGlobalContextCreateInGroup(NULL, globalObjectClass);
+
+ JSContextGroupRef contextGroup = JSContextGetGroup(context);
+
+ JSGlobalContextRetain(context);
+ JSGlobalContextRelease(context);
+ ASSERT(JSContextGetGlobalContext(context) == context);
+
+ JSReportExtraMemoryCost(context, 0);
+ JSReportExtraMemoryCost(context, 1);
+ JSReportExtraMemoryCost(context, 1024);
+
+ JSObjectRef globalObject = JSContextGetGlobalObject(context);
+ ASSERT(JSValueIsObject(context, globalObject));
+
+ JSValueRef jsUndefined = JSValueMakeUndefined(context);
+ JSValueRef jsNull = JSValueMakeNull(context);
+ JSValueRef jsTrue = JSValueMakeBoolean(context, true);
+ JSValueRef jsFalse = JSValueMakeBoolean(context, false);
+ JSValueRef jsZero = JSValueMakeNumber(context, 0);
+ JSValueRef jsOne = JSValueMakeNumber(context, 1);
+ JSValueRef jsOneThird = JSValueMakeNumber(context, 1.0 / 3.0);
+ 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);
+
+ JSStringRef jsOneIString = JSStringCreateWithUTF8CString("1");
+ JSValueRef jsOneString = JSValueMakeString(context, jsOneIString);
+
+ UniChar singleUniChar = 65; // Capital A
+ CFMutableStringRef cfString =
+ CFStringCreateMutableWithExternalCharactersNoCopy(kCFAllocatorDefault,
+ &singleUniChar,
+ 1,
+ 1,
+ kCFAllocatorNull);
+
+ JSStringRef jsCFIString = JSStringCreateWithCFString(cfString);
+ JSValueRef jsCFString = JSValueMakeString(context, jsCFIString);
+
+ CFStringRef cfEmptyString = CFStringCreateWithCString(kCFAllocatorDefault, "", kCFStringEncodingUTF8);
+
+ JSStringRef jsCFEmptyIString = JSStringCreateWithCFString(cfEmptyString);
+ JSValueRef jsCFEmptyString = JSValueMakeString(context, jsCFEmptyIString);
+
+ CFIndex cfStringLength = CFStringGetLength(cfString);
+ UniChar* buffer = (UniChar*)malloc(cfStringLength * sizeof(UniChar));
+ CFStringGetCharacters(cfString,
+ CFRangeMake(0, cfStringLength),
+ buffer);
+ JSStringRef jsCFIStringWithCharacters = JSStringCreateWithCharacters((JSChar*)buffer, cfStringLength);
+ JSValueRef jsCFStringWithCharacters = JSValueMakeString(context, jsCFIStringWithCharacters);
+
+ JSStringRef jsCFEmptyIStringWithCharacters = JSStringCreateWithCharacters((JSChar*)buffer, CFStringGetLength(cfEmptyString));
+ free(buffer);
+ JSValueRef jsCFEmptyStringWithCharacters = JSValueMakeString(context, jsCFEmptyIStringWithCharacters);
+
+ JSChar constantString[] = { 'H', 'e', 'l', 'l', 'o', };
+ JSStringRef constantStringRef = JSStringCreateWithCharactersNoCopy(constantString, sizeof(constantString) / sizeof(constantString[0]));
+ ASSERT(JSStringGetCharactersPtr(constantStringRef) == constantString);
+ JSStringRelease(constantStringRef);
+
+ ASSERT(JSValueGetType(context, NULL) == kJSTypeNull);
+ ASSERT(JSValueGetType(context, jsUndefined) == kJSTypeUndefined);
+ ASSERT(JSValueGetType(context, jsNull) == kJSTypeNull);
+ ASSERT(JSValueGetType(context, jsTrue) == kJSTypeBoolean);
+ ASSERT(JSValueGetType(context, jsFalse) == kJSTypeBoolean);
+ ASSERT(JSValueGetType(context, jsZero) == kJSTypeNumber);
+ ASSERT(JSValueGetType(context, jsOne) == kJSTypeNumber);
+ ASSERT(JSValueGetType(context, jsOneThird) == kJSTypeNumber);
+ ASSERT(JSValueGetType(context, jsEmptyString) == kJSTypeString);
+ ASSERT(JSValueGetType(context, jsOneString) == kJSTypeString);
+ ASSERT(JSValueGetType(context, jsCFString) == kJSTypeString);
+ ASSERT(JSValueGetType(context, jsCFStringWithCharacters) == kJSTypeString);
+ ASSERT(JSValueGetType(context, jsCFEmptyString) == kJSTypeString);
+ ASSERT(JSValueGetType(context, jsCFEmptyStringWithCharacters) == kJSTypeString);
+
+ 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));
+ ASSERT(JSValueIsNull(context, NULL));
+ ASSERT(!JSObjectCallAsFunction(context, NULL, NULL, 0, NULL, NULL));
+ ASSERT(!JSObjectCallAsConstructor(context, NULL, 0, NULL, NULL));
+ ASSERT(!JSObjectIsConstructor(context, NULL));
+ ASSERT(!JSObjectIsFunction(context, NULL));
+
+ JSStringRef nullString = JSStringCreateWithUTF8CString(0);
+ const JSChar* characters = JSStringGetCharactersPtr(nullString);
+ if (characters) {
+ printf("FAIL: Didn't return null when accessing character pointer of a null String.\n");
+ failed = 1;
+ } else
+ printf("PASS: returned null when accessing character pointer of a null String.\n");
+
+ JSStringRef emptyString = JSStringCreateWithCFString(CFSTR(""));
+ characters = JSStringGetCharactersPtr(emptyString);
+ if (!characters) {
+ printf("FAIL: Returned null when accessing character pointer of an empty String.\n");
+ failed = 1;
+ } else
+ printf("PASS: returned empty when accessing character pointer of an empty String.\n");
+
+ size_t length = JSStringGetLength(nullString);
+ if (length) {
+ printf("FAIL: Didn't return 0 length for null String.\n");
+ failed = 1;
+ } else
+ printf("PASS: returned 0 length for null String.\n");
+ JSStringRelease(nullString);
+
+ length = JSStringGetLength(emptyString);
+ if (length) {
+ printf("FAIL: Didn't return 0 length for empty String.\n");
+ failed = 1;
+ } else
+ printf("PASS: returned 0 length for empty String.\n");
+ JSStringRelease(emptyString);
+
+ JSObjectRef propertyCatchalls = JSObjectMake(context, PropertyCatchalls_class(context), NULL);
+ JSStringRef propertyCatchallsString = JSStringCreateWithUTF8CString("PropertyCatchalls");
+ JSObjectSetProperty(context, globalObject, propertyCatchallsString, propertyCatchalls, kJSPropertyAttributeNone, NULL);
+ JSStringRelease(propertyCatchallsString);
+
+ JSObjectRef myObject = JSObjectMake(context, MyObject_class(context), NULL);
+ JSStringRef myObjectIString = JSStringCreateWithUTF8CString("MyObject");
+ JSObjectSetProperty(context, globalObject, myObjectIString, myObject, kJSPropertyAttributeNone, NULL);
+ JSStringRelease(myObjectIString);
+
+ JSObjectRef EvilExceptionObject = JSObjectMake(context, EvilExceptionObject_class(context), NULL);
+ JSStringRef EvilExceptionObjectIString = JSStringCreateWithUTF8CString("EvilExceptionObject");
+ JSObjectSetProperty(context, globalObject, EvilExceptionObjectIString, EvilExceptionObject, kJSPropertyAttributeNone, NULL);
+ JSStringRelease(EvilExceptionObjectIString);
+
+ JSObjectRef EmptyObject = JSObjectMake(context, EmptyObject_class(context), NULL);
+ JSStringRef EmptyObjectIString = JSStringCreateWithUTF8CString("EmptyObject");
+ JSObjectSetProperty(context, globalObject, EmptyObjectIString, EmptyObject, kJSPropertyAttributeNone, NULL);
+ JSStringRelease(EmptyObjectIString);
+
+ JSStringRef lengthStr = JSStringCreateWithUTF8CString("length");
+ JSObjectRef aStackRef = JSObjectMakeArray(context, 0, 0, 0);
+ aHeapRef = aStackRef;
+ JSObjectSetProperty(context, aHeapRef, lengthStr, JSValueMakeNumber(context, 10), 0, 0);
+ JSStringRef privatePropertyName = JSStringCreateWithUTF8CString("privateProperty");
+ if (!JSObjectSetPrivateProperty(context, myObject, privatePropertyName, aHeapRef)) {
+ printf("FAIL: Could not set private property.\n");
+ failed = 1;
+ } else
+ printf("PASS: Set private property.\n");
+ aStackRef = 0;
+ if (JSObjectSetPrivateProperty(context, aHeapRef, privatePropertyName, aHeapRef)) {
+ printf("FAIL: JSObjectSetPrivateProperty should fail on non-API objects.\n");
+ failed = 1;
+ } else
+ printf("PASS: Did not allow JSObjectSetPrivateProperty on a non-API object.\n");
+ if (JSObjectGetPrivateProperty(context, myObject, privatePropertyName) != aHeapRef) {
+ printf("FAIL: Could not retrieve private property.\n");
+ failed = 1;
+ } else
+ printf("PASS: Retrieved private property.\n");
+ if (JSObjectGetPrivateProperty(context, aHeapRef, privatePropertyName)) {
+ printf("FAIL: JSObjectGetPrivateProperty should return NULL when called on a non-API object.\n");
+ failed = 1;
+ } else
+ printf("PASS: JSObjectGetPrivateProperty return NULL.\n");
+
+ if (JSObjectGetProperty(context, myObject, privatePropertyName, 0) == aHeapRef) {
+ printf("FAIL: Accessed private property through ordinary property lookup.\n");
+ failed = 1;
+ } else
+ printf("PASS: Cannot access private property through ordinary property lookup.\n");
+
+ JSGarbageCollect(context);
+
+ for (int i = 0; i < 10000; i++)
+ JSObjectMake(context, 0, 0);
+
+ aHeapRef = JSValueToObject(context, JSObjectGetPrivateProperty(context, myObject, privatePropertyName), 0);
+ if (JSValueToNumber(context, JSObjectGetProperty(context, aHeapRef, lengthStr, 0), 0) != 10) {
+ printf("FAIL: Private property has been collected.\n");
+ failed = 1;
+ } else
+ printf("PASS: Private property does not appear to have been collected.\n");
+ JSStringRelease(lengthStr);
+
+ if (!JSObjectSetPrivateProperty(context, myObject, privatePropertyName, 0)) {
+ printf("FAIL: Could not set private property to NULL.\n");
+ failed = 1;
+ } else
+ printf("PASS: Set private property to NULL.\n");
+ if (JSObjectGetPrivateProperty(context, myObject, privatePropertyName)) {
+ printf("FAIL: Could not retrieve private property.\n");
+ failed = 1;
+ } else
+ printf("PASS: Retrieved private property.\n");
+
+ JSStringRef nullJSON = JSStringCreateWithUTF8CString(0);
+ JSValueRef nullJSONObject = JSValueMakeFromJSONString(context, nullJSON);
+ if (nullJSONObject) {
+ printf("FAIL: Did not parse null String as JSON correctly\n");
+ failed = 1;
+ } else
+ printf("PASS: Parsed null String as JSON correctly.\n");
+ JSStringRelease(nullJSON);
+
+ JSStringRef validJSON = JSStringCreateWithUTF8CString("{\"aProperty\":true}");
+ JSValueRef jsonObject = JSValueMakeFromJSONString(context, validJSON);
+ JSStringRelease(validJSON);
+ if (!JSValueIsObject(context, jsonObject)) {
+ printf("FAIL: Did not parse valid JSON correctly\n");
+ failed = 1;
+ } else
+ printf("PASS: Parsed valid JSON string.\n");
+ JSStringRef propertyName = JSStringCreateWithUTF8CString("aProperty");
+ assertEqualsAsBoolean(JSObjectGetProperty(context, JSValueToObject(context, jsonObject, 0), propertyName, 0), true);
+ JSStringRelease(propertyName);
+ JSStringRef invalidJSON = JSStringCreateWithUTF8CString("fail!");
+ if (JSValueMakeFromJSONString(context, invalidJSON)) {
+ printf("FAIL: Should return null for invalid JSON data\n");
+ failed = 1;
+ } else
+ printf("PASS: Correctly returned null for invalid JSON data.\n");
+ JSValueRef exception;
+ JSStringRef str = JSValueCreateJSONString(context, jsonObject, 0, 0);
+ if (!JSStringIsEqualToUTF8CString(str, "{\"aProperty\":true}")) {
+ printf("FAIL: Did not correctly serialise with indent of 0.\n");
+ failed = 1;
+ } else
+ printf("PASS: Correctly serialised with indent of 0.\n");
+ JSStringRelease(str);
+
+ str = JSValueCreateJSONString(context, jsonObject, 4, 0);
+ if (!JSStringIsEqualToUTF8CString(str, "{\n \"aProperty\": true\n}")) {
+ printf("FAIL: Did not correctly serialise with indent of 4.\n");
+ failed = 1;
+ } else
+ printf("PASS: Correctly serialised with indent of 4.\n");
+ JSStringRelease(str);
+
+ str = JSStringCreateWithUTF8CString("({get a(){ throw '';}})");
+ JSValueRef unstringifiableObj = JSEvaluateScript(context, str, NULL, NULL, 1, NULL);
+ JSStringRelease(str);
+
+ str = JSValueCreateJSONString(context, unstringifiableObj, 4, 0);
+ if (str) {
+ printf("FAIL: Didn't return null when attempting to serialize unserializable value.\n");
+ JSStringRelease(str);
+ failed = 1;
+ } else
+ printf("PASS: returned null when attempting to serialize unserializable value.\n");
+
+ str = JSValueCreateJSONString(context, unstringifiableObj, 4, &exception);
+ if (str) {
+ printf("FAIL: Didn't return null when attempting to serialize unserializable value.\n");
+ JSStringRelease(str);
+ failed = 1;
+ } else
+ printf("PASS: returned null when attempting to serialize unserializable value.\n");
+ if (!exception) {
+ printf("FAIL: Did not set exception on serialisation error\n");
+ failed = 1;
+ } else
+ printf("PASS: set exception on serialisation error\n");
+ // Conversions that throw exceptions
+ exception = NULL;
+ ASSERT(NULL == JSValueToObject(context, jsNull, &exception));
+ ASSERT(exception);
+
+ exception = NULL;
+ // FIXME <rdar://4668451> - On i386 the isnan(double) macro tries to map to the isnan(float) function,
+ // causing a build break with -Wshorten-64-to-32 enabled. The issue is known by the appropriate team.
+ // After that's resolved, we can remove these casts
+ ASSERT(isnan((float)JSValueToNumber(context, jsObjectNoProto, &exception)));
+ ASSERT(exception);
+
+ exception = NULL;
+ ASSERT(!JSValueToStringCopy(context, jsObjectNoProto, &exception));
+ ASSERT(exception);
+
+ ASSERT(JSValueToBoolean(context, myObject));
+
+ exception = NULL;
+ ASSERT(!JSValueIsEqual(context, jsObjectNoProto, JSValueMakeNumber(context, 1), &exception));
+ ASSERT(exception);
+
+ exception = NULL;
+ JSObjectGetPropertyAtIndex(context, myObject, 0, &exception);
+ ASSERT(1 == JSValueToNumber(context, exception, NULL));
+
+ assertEqualsAsBoolean(jsUndefined, false);
+ assertEqualsAsBoolean(jsNull, false);
+ assertEqualsAsBoolean(jsTrue, true);
+ assertEqualsAsBoolean(jsFalse, false);
+ assertEqualsAsBoolean(jsZero, false);
+ assertEqualsAsBoolean(jsOne, true);
+ assertEqualsAsBoolean(jsOneThird, true);
+ assertEqualsAsBoolean(jsEmptyString, false);
+ assertEqualsAsBoolean(jsOneString, true);
+ assertEqualsAsBoolean(jsCFString, true);
+ assertEqualsAsBoolean(jsCFStringWithCharacters, true);
+ assertEqualsAsBoolean(jsCFEmptyString, false);
+ assertEqualsAsBoolean(jsCFEmptyStringWithCharacters, false);
+
+ assertEqualsAsNumber(jsUndefined, nan(""));
+ assertEqualsAsNumber(jsNull, 0);
+ assertEqualsAsNumber(jsTrue, 1);
+ assertEqualsAsNumber(jsFalse, 0);
+ assertEqualsAsNumber(jsZero, 0);
+ assertEqualsAsNumber(jsOne, 1);
+ assertEqualsAsNumber(jsOneThird, 1.0 / 3.0);
+ assertEqualsAsNumber(jsEmptyString, 0);
+ assertEqualsAsNumber(jsOneString, 1);
+ assertEqualsAsNumber(jsCFString, nan(""));
+ assertEqualsAsNumber(jsCFStringWithCharacters, nan(""));
+ assertEqualsAsNumber(jsCFEmptyString, 0);
+ assertEqualsAsNumber(jsCFEmptyStringWithCharacters, 0);
+ ASSERT(sizeof(JSChar) == sizeof(UniChar));
+
+ assertEqualsAsCharactersPtr(jsUndefined, "undefined");
+ assertEqualsAsCharactersPtr(jsNull, "null");
+ assertEqualsAsCharactersPtr(jsTrue, "true");
+ assertEqualsAsCharactersPtr(jsFalse, "false");
+ assertEqualsAsCharactersPtr(jsZero, "0");
+ assertEqualsAsCharactersPtr(jsOne, "1");
+ assertEqualsAsCharactersPtr(jsOneThird, "0.3333333333333333");
+ assertEqualsAsCharactersPtr(jsEmptyString, "");
+ assertEqualsAsCharactersPtr(jsOneString, "1");
+ assertEqualsAsCharactersPtr(jsCFString, "A");
+ assertEqualsAsCharactersPtr(jsCFStringWithCharacters, "A");
+ assertEqualsAsCharactersPtr(jsCFEmptyString, "");
+ assertEqualsAsCharactersPtr(jsCFEmptyStringWithCharacters, "");
+
+ assertEqualsAsUTF8String(jsUndefined, "undefined");
+ assertEqualsAsUTF8String(jsNull, "null");
+ assertEqualsAsUTF8String(jsTrue, "true");
+ assertEqualsAsUTF8String(jsFalse, "false");
+ assertEqualsAsUTF8String(jsZero, "0");
+ assertEqualsAsUTF8String(jsOne, "1");
+ assertEqualsAsUTF8String(jsOneThird, "0.3333333333333333");
+ assertEqualsAsUTF8String(jsEmptyString, "");
+ assertEqualsAsUTF8String(jsOneString, "1");
+ assertEqualsAsUTF8String(jsCFString, "A");
+ assertEqualsAsUTF8String(jsCFStringWithCharacters, "A");
+ assertEqualsAsUTF8String(jsCFEmptyString, "");
+ assertEqualsAsUTF8String(jsCFEmptyStringWithCharacters, "");
+
+ checkConstnessInJSObjectNames();
+
+ ASSERT(JSValueIsStrictEqual(context, jsTrue, jsTrue));
+ ASSERT(!JSValueIsStrictEqual(context, jsOne, jsOneString));
+
+ ASSERT(JSValueIsEqual(context, jsOne, jsOneString, NULL));
+ ASSERT(!JSValueIsEqual(context, jsTrue, jsFalse, NULL));
+
+ CFStringRef cfJSString = JSStringCopyCFString(kCFAllocatorDefault, jsCFIString);
+ CFStringRef cfJSEmptyString = JSStringCopyCFString(kCFAllocatorDefault, jsCFEmptyIString);
+ ASSERT(CFEqual(cfJSString, cfString));
+ ASSERT(CFEqual(cfJSEmptyString, cfEmptyString));
+ CFRelease(cfJSString);
+ CFRelease(cfJSEmptyString);
+
+ CFRelease(cfString);
+ CFRelease(cfEmptyString);
+
+ jsGlobalValue = JSObjectMake(context, NULL, NULL);
+ makeGlobalNumberValue(context);
+ JSValueProtect(context, jsGlobalValue);
+ JSGarbageCollect(context);
+ ASSERT(JSValueIsObject(context, jsGlobalValue));
+ JSValueUnprotect(context, jsGlobalValue);
+ JSValueUnprotect(context, jsNumberValue);
+
+ JSStringRef goodSyntax = JSStringCreateWithUTF8CString("x = 1;");
+ const char* badSyntaxConstant = "x := 1;";
+ JSStringRef badSyntax = JSStringCreateWithUTF8CString(badSyntaxConstant);
+ ASSERT(JSCheckScriptSyntax(context, goodSyntax, NULL, 0, NULL));
+ ASSERT(!JSCheckScriptSyntax(context, badSyntax, NULL, 0, NULL));
+ ASSERT(!JSScriptCreateFromString(contextGroup, 0, 0, badSyntax, 0, 0));
+ ASSERT(!JSScriptCreateReferencingImmortalASCIIText(contextGroup, 0, 0, badSyntaxConstant, strlen(badSyntaxConstant), 0, 0));
+
+ JSValueRef result;
+ JSValueRef v;
+ JSObjectRef o;
+ JSStringRef string;
+
+ result = JSEvaluateScript(context, goodSyntax, NULL, NULL, 1, NULL);
+ ASSERT(result);
+ ASSERT(JSValueIsEqual(context, result, jsOne, NULL));
+
+ exception = NULL;
+ result = JSEvaluateScript(context, badSyntax, NULL, NULL, 1, &exception);
+ ASSERT(!result);
+ ASSERT(JSValueIsObject(context, exception));
+
+ JSStringRef array = JSStringCreateWithUTF8CString("Array");
+ JSObjectRef arrayConstructor = JSValueToObject(context, JSObjectGetProperty(context, globalObject, array, NULL), NULL);
+ JSStringRelease(array);
+ result = JSObjectCallAsConstructor(context, arrayConstructor, 0, NULL, NULL);
+ ASSERT(result);
+ ASSERT(JSValueIsObject(context, result));
+ ASSERT(JSValueIsInstanceOfConstructor(context, result, arrayConstructor, NULL));
+ ASSERT(!JSValueIsInstanceOfConstructor(context, JSValueMakeNull(context), arrayConstructor, NULL));
+
+ o = JSValueToObject(context, result, NULL);
+ exception = NULL;
+ ASSERT(JSValueIsUndefined(context, JSObjectGetPropertyAtIndex(context, o, 0, &exception)));
+ ASSERT(!exception);
+
+ JSObjectSetPropertyAtIndex(context, o, 0, JSValueMakeNumber(context, 1), &exception);
+ ASSERT(!exception);
+
+ exception = NULL;
+ ASSERT(1 == JSValueToNumber(context, JSObjectGetPropertyAtIndex(context, o, 0, &exception), &exception));
+ ASSERT(!exception);
+
+ JSStringRef functionBody;
+ JSObjectRef function;
+
+ exception = NULL;
+ functionBody = JSStringCreateWithUTF8CString("rreturn Array;");
+ JSStringRef 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, 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);
+
+ exception = NULL;
+ functionBody = JSStringCreateWithUTF8CString("return Array;");
+ function = JSObjectMakeFunction(context, NULL, 0, NULL, functionBody, NULL, 1, &exception);
+ JSStringRelease(functionBody);
+ ASSERT(!exception);
+ ASSERT(JSObjectIsFunction(context, function));
+ v = JSObjectCallAsFunction(context, function, NULL, 0, NULL, NULL);
+ ASSERT(v);
+ ASSERT(JSValueIsEqual(context, v, arrayConstructor, NULL));
+
+ exception = NULL;
+ function = JSObjectMakeFunction(context, NULL, 0, NULL, jsEmptyIString, NULL, 0, &exception);
+ ASSERT(!exception);
+ v = JSObjectCallAsFunction(context, function, NULL, 0, NULL, &exception);
+ ASSERT(v && !exception);
+ ASSERT(JSValueIsUndefined(context, v));
+
+ exception = NULL;
+ v = NULL;
+ JSStringRef foo = JSStringCreateWithUTF8CString("foo");
+ JSStringRef argumentNames[] = { foo };
+ functionBody = JSStringCreateWithUTF8CString("return foo;");
+ function = JSObjectMakeFunction(context, foo, 1, argumentNames, functionBody, NULL, 1, &exception);
+ ASSERT(function && !exception);
+ JSValueRef arguments[] = { JSValueMakeNumber(context, 2) };
+ JSObjectCallAsFunction(context, function, NULL, 1, arguments, &exception);
+ JSStringRelease(foo);
+ JSStringRelease(functionBody);
+
+ string = JSValueToStringCopy(context, function, NULL);
+ assertEqualsAsUTF8String(JSValueMakeString(context, string), "function foo(foo) {\nreturn foo;\n}");
+ JSStringRelease(string);
+
+ JSStringRef print = JSStringCreateWithUTF8CString("print");
+ JSObjectRef printFunction = JSObjectMakeFunctionWithCallback(context, print, print_callAsFunction);
+ JSObjectSetProperty(context, globalObject, print, printFunction, kJSPropertyAttributeNone, NULL);
+ JSStringRelease(print);
+
+ ASSERT(!JSObjectSetPrivate(printFunction, (void*)1));
+ ASSERT(!JSObjectGetPrivate(printFunction));
+
+ JSStringRef myConstructorIString = JSStringCreateWithUTF8CString("MyConstructor");
+ JSObjectRef myConstructor = JSObjectMakeConstructor(context, NULL, myConstructor_callAsConstructor);
+ JSObjectSetProperty(context, globalObject, myConstructorIString, myConstructor, kJSPropertyAttributeNone, NULL);
+ JSStringRelease(myConstructorIString);
+
+ JSStringRef myBadConstructorIString = JSStringCreateWithUTF8CString("MyBadConstructor");
+ JSObjectRef myBadConstructor = JSObjectMakeConstructor(context, NULL, myBadConstructor_callAsConstructor);
+ JSObjectSetProperty(context, globalObject, myBadConstructorIString, myBadConstructor, kJSPropertyAttributeNone, NULL);
+ JSStringRelease(myBadConstructorIString);
+
+ ASSERT(!JSObjectSetPrivate(myConstructor, (void*)1));
+ ASSERT(!JSObjectGetPrivate(myConstructor));
+
+ string = JSStringCreateWithUTF8CString("Base");
+ JSObjectRef baseConstructor = JSObjectMakeConstructor(context, Base_class(context), NULL);
+ JSObjectSetProperty(context, globalObject, string, baseConstructor, kJSPropertyAttributeNone, NULL);
+ JSStringRelease(string);
+
+ string = JSStringCreateWithUTF8CString("Derived");
+ JSObjectRef derivedConstructor = JSObjectMakeConstructor(context, Derived_class(context), NULL);
+ JSObjectSetProperty(context, globalObject, string, derivedConstructor, kJSPropertyAttributeNone, NULL);
+ JSStringRelease(string);
+
+ string = JSStringCreateWithUTF8CString("Derived2");
+ JSObjectRef derived2Constructor = JSObjectMakeConstructor(context, Derived2_class(context), NULL);
+ JSObjectSetProperty(context, globalObject, string, derived2Constructor, kJSPropertyAttributeNone, NULL);
+ JSStringRelease(string);
+
+ o = JSObjectMake(context, NULL, NULL);
+ JSObjectSetProperty(context, o, jsOneIString, JSValueMakeNumber(context, 1), kJSPropertyAttributeNone, NULL);
+ JSObjectSetProperty(context, o, jsCFIString, JSValueMakeNumber(context, 1), kJSPropertyAttributeDontEnum, NULL);
+ JSPropertyNameArrayRef nameArray = JSObjectCopyPropertyNames(context, o);
+ size_t expectedCount = JSPropertyNameArrayGetCount(nameArray);
+ size_t count;
+ for (count = 0; count < expectedCount; ++count)
+ JSPropertyNameArrayGetNameAtIndex(nameArray, count);
+ JSPropertyNameArrayRelease(nameArray);
+ ASSERT(count == 1); // jsCFString should not be enumerated
+
+ JSValueRef argumentsArrayValues[] = { JSValueMakeNumber(context, 10), JSValueMakeNumber(context, 20) };
+ o = JSObjectMakeArray(context, sizeof(argumentsArrayValues) / sizeof(JSValueRef), argumentsArrayValues, NULL);
+ string = JSStringCreateWithUTF8CString("length");
+ v = JSObjectGetProperty(context, o, string, NULL);
+ assertEqualsAsNumber(v, 2);
+ v = JSObjectGetPropertyAtIndex(context, o, 0, NULL);
+ assertEqualsAsNumber(v, 10);
+ v = JSObjectGetPropertyAtIndex(context, o, 1, NULL);
+ assertEqualsAsNumber(v, 20);
+
+ o = JSObjectMakeArray(context, 0, NULL, NULL);
+ v = JSObjectGetProperty(context, o, string, NULL);
+ assertEqualsAsNumber(v, 0);
+ JSStringRelease(string);
+
+ JSValueRef argumentsDateValues[] = { JSValueMakeNumber(context, 0) };
+ o = JSObjectMakeDate(context, 1, argumentsDateValues, NULL);
+ if (timeZoneIsPST())
+ assertEqualsAsUTF8String(o, "Wed Dec 31 1969 16:00:00 GMT-0800 (PST)");
+
+ string = JSStringCreateWithUTF8CString("an error message");
+ JSValueRef argumentsErrorValues[] = { JSValueMakeString(context, string) };
+ o = JSObjectMakeError(context, 1, argumentsErrorValues, NULL);
+ assertEqualsAsUTF8String(o, "Error: an error message");
+ JSStringRelease(string);
+
+ string = JSStringCreateWithUTF8CString("foo");
+ JSStringRef string2 = JSStringCreateWithUTF8CString("gi");
+ JSValueRef argumentsRegExpValues[] = { JSValueMakeString(context, string), JSValueMakeString(context, string2) };
+ o = JSObjectMakeRegExp(context, 2, argumentsRegExpValues, NULL);
+ assertEqualsAsUTF8String(o, "/foo/gi");
+ JSStringRelease(string);
+ JSStringRelease(string2);
+
+ JSClassDefinition nullDefinition = kJSClassDefinitionEmpty;
+ nullDefinition.attributes = kJSClassAttributeNoAutomaticPrototype;
+ JSClassRef nullClass = JSClassCreate(&nullDefinition);
+ JSClassRelease(nullClass);
+
+ nullDefinition = kJSClassDefinitionEmpty;
+ nullClass = JSClassCreate(&nullDefinition);
+ JSClassRelease(nullClass);
+
+ functionBody = JSStringCreateWithUTF8CString("return this;");
+ function = JSObjectMakeFunction(context, NULL, 0, NULL, functionBody, NULL, 1, NULL);
+ JSStringRelease(functionBody);
+ v = JSObjectCallAsFunction(context, function, NULL, 0, NULL, NULL);
+ ASSERT(JSValueIsEqual(context, v, globalObject, NULL));
+ v = JSObjectCallAsFunction(context, function, o, 0, NULL, NULL);
+ ASSERT(JSValueIsEqual(context, v, o, NULL));
+
+ functionBody = JSStringCreateWithUTF8CString("return eval(\"this\");");
+ function = JSObjectMakeFunction(context, NULL, 0, NULL, functionBody, NULL, 1, NULL);
+ JSStringRelease(functionBody);
+ v = JSObjectCallAsFunction(context, function, NULL, 0, NULL, NULL);
+ ASSERT(JSValueIsEqual(context, v, globalObject, NULL));
+ v = JSObjectCallAsFunction(context, function, o, 0, NULL, NULL);
+ ASSERT(JSValueIsEqual(context, v, o, NULL));
+
+ const char* thisScript = "this;";
+ JSStringRef script = JSStringCreateWithUTF8CString(thisScript);
+ v = JSEvaluateScript(context, script, NULL, NULL, 1, NULL);
+ ASSERT(JSValueIsEqual(context, v, globalObject, NULL));
+ v = JSEvaluateScript(context, script, o, NULL, 1, NULL);
+ ASSERT(JSValueIsEqual(context, v, o, NULL));
+ JSStringRelease(script);
+
+ JSScriptRef scriptObject = JSScriptCreateReferencingImmortalASCIIText(contextGroup, 0, 0, thisScript, strlen(thisScript), 0, 0);
+ v = JSScriptEvaluate(context, scriptObject, NULL, NULL);
+ ASSERT(JSValueIsEqual(context, v, globalObject, NULL));
+ v = JSScriptEvaluate(context, scriptObject, o, NULL);
+ ASSERT(JSValueIsEqual(context, v, o, NULL));
+ JSScriptRelease(scriptObject);
+
+ script = JSStringCreateWithUTF8CString("eval(this);");
+ v = JSEvaluateScript(context, script, NULL, NULL, 1, NULL);
+ ASSERT(JSValueIsEqual(context, v, globalObject, NULL));
+ v = JSEvaluateScript(context, script, o, NULL, 1, NULL);
+ 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;
+ nullClass = JSClassCreate(&nullDefinition);
+ JSObjectMakeConstructor(context, nullClass, 0);
+ JSClassRelease(nullClass);
+
+ char* scriptUTF8 = createStringWithContentsOfFile(scriptPath);
+ if (!scriptUTF8) {
+ printf("FAIL: Test script could not be loaded.\n");
+ failed = 1;
+ } else {
+ JSStringRef url = JSStringCreateWithUTF8CString(scriptPath);
+ JSStringRef script = JSStringCreateWithUTF8CString(scriptUTF8);
+ JSStringRef errorMessage = 0;
+ int errorLine = 0;
+ JSScriptRef scriptObject = JSScriptCreateFromString(contextGroup, url, 1, script, &errorMessage, &errorLine);
+ ASSERT((!scriptObject) != (!errorMessage));
+ if (!scriptObject) {
+ printf("FAIL: Test script did not parse\n\t%s:%d\n\t", scriptPath, errorLine);
+ CFStringRef errorCF = JSStringCopyCFString(kCFAllocatorDefault, errorMessage);
+ CFShow(errorCF);
+ CFRelease(errorCF);
+ JSStringRelease(errorMessage);
+ failed = 1;
+ }
+
+ JSStringRelease(script);
+ exception = NULL;
+ result = scriptObject ? JSScriptEvaluate(context, scriptObject, 0, &exception) : 0;
+ if (result && JSValueIsUndefined(context, result))
+ printf("PASS: Test script executed successfully.\n");
+ else {
+ printf("FAIL: Test script returned unexpected value:\n");
+ JSStringRef exceptionIString = JSValueToStringCopy(context, exception, NULL);
+ CFStringRef exceptionCF = JSStringCopyCFString(kCFAllocatorDefault, exceptionIString);
+ CFShow(exceptionCF);
+ CFRelease(exceptionCF);
+ JSStringRelease(exceptionIString);
+ failed = 1;
+ }
+ JSScriptRelease(scriptObject);
+ free(scriptUTF8);
+ }
+
+ // Check Promise is not exposed.
+ {
+ JSObjectRef globalObject = JSContextGetGlobalObject(context);
+ {
+ JSStringRef promiseProperty = JSStringCreateWithUTF8CString("Promise");
+ ASSERT(JSObjectHasProperty(context, globalObject, promiseProperty));
+ JSStringRelease(promiseProperty);
+ }
+ {
+ 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");
+ }
+
+ // Check microtasks.
+ {
+ 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);
+ }
+
+ 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;
+ v = NULL;
+ o = NULL;
+ globalObject = NULL;
+ myConstructor = NULL;
+
+ JSStringRelease(jsEmptyIString);
+ JSStringRelease(jsOneIString);
+ JSStringRelease(jsCFIString);
+ JSStringRelease(jsCFEmptyIString);
+ JSStringRelease(jsCFIStringWithCharacters);
+ JSStringRelease(jsCFEmptyIStringWithCharacters);
+ JSStringRelease(goodSyntax);
+ JSStringRelease(badSyntax);
+
+ JSGlobalContextRelease(context);
+ JSClassRelease(globalObjectClass);
+
+ // Test for an infinite prototype chain that used to be created. This test
+ // passes if the call to JSObjectHasProperty() does not hang.
+
+ JSClassDefinition prototypeLoopClassDefinition = kJSClassDefinitionEmpty;
+ prototypeLoopClassDefinition.staticFunctions = globalObject_staticFunctions;
+ JSClassRef prototypeLoopClass = JSClassCreate(&prototypeLoopClassDefinition);
+ JSGlobalContextRef prototypeLoopContext = JSGlobalContextCreateInGroup(NULL, prototypeLoopClass);
+
+ JSStringRef nameProperty = JSStringCreateWithUTF8CString("name");
+ JSObjectHasProperty(prototypeLoopContext, JSContextGetGlobalObject(prototypeLoopContext), nameProperty);
+
+ JSGlobalContextRelease(prototypeLoopContext);
+ JSClassRelease(prototypeLoopClass);
+
+ printf("PASS: Infinite prototype chain does not occur.\n");
+
+ if (checkForCycleInPrototypeChain())
+ printf("PASS: A cycle in a prototype chain can't be created.\n");
+ else {
+ 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");
+ return 1;
+ }
+
+ printf("PASS: Program exited normally.\n");
+ return 0;
+}
+
+static char* createStringWithContentsOfFile(const char* fileName)
+{
+ char* buffer;
+
+ size_t buffer_size = 0;
+ size_t buffer_capacity = 1024;
+ buffer = (char*)malloc(buffer_capacity);
+
+ FILE* f = fopen(fileName, "r");
+ if (!f) {
+ fprintf(stderr, "Could not open file: %s\n", fileName);
+ free(buffer);
+ return 0;
+ }
+
+ while (!feof(f) && !ferror(f)) {
+ buffer_size += fread(buffer + buffer_size, 1, buffer_capacity - buffer_size, f);
+ if (buffer_size == buffer_capacity) { // guarantees space for trailing '\0'
+ buffer_capacity *= 2;
+ buffer = (char*)realloc(buffer, buffer_capacity);
+ ASSERT(buffer);
+ }
+
+ ASSERT(buffer_size < buffer_capacity);
+ }
+ fclose(f);
+ buffer[buffer_size] = '\0';
+
+ return buffer;
+}
+
+#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
new file mode 100644
index 000000000..88d3701c2
--- /dev/null
+++ b/Source/JavaScriptCore/API/tests/testapi.js
@@ -0,0 +1,307 @@
+/*
+ * 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
+ * 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.
+ */
+
+function bludgeonArguments() { if (0) arguments; return function g() {} }
+h = bludgeonArguments();
+gc();
+
+var failed = false;
+function pass(msg)
+{
+ print("PASS: " + msg, "green");
+}
+
+function fail(msg)
+{
+ print("FAIL: " + msg, "red");
+ failed = true;
+}
+
+function shouldBe(a, b)
+{
+ var evalA;
+ try {
+ evalA = eval(a);
+ } catch(e) {
+ evalA = e;
+ }
+
+ if (evalA == b || isNaN(evalA) && typeof evalA == 'number' && isNaN(b) && typeof b == 'number')
+ pass(a + " should be " + b + " and is.");
+ else
+ fail(a + " should be " + b + " but instead is " + evalA + ".");
+}
+
+function shouldThrow(a)
+{
+ var evalA;
+ try {
+ eval(a);
+ } catch(e) {
+ pass(a + " threw: " + e);
+ return;
+ }
+
+ fail(a + " did not throw an exception.");
+}
+
+function globalStaticFunction()
+{
+ return 4;
+}
+
+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;
+shouldBe("MyObject.cantFind", undefined);
+MyObject.regularType = 1;
+shouldBe("MyObject.regularType", 1);
+MyObject.alwaysOne = 2;
+shouldBe("MyObject.alwaysOne", 1);
+MyObject.cantDelete = 1;
+delete MyObject.cantDelete;
+shouldBe("MyObject.cantDelete", 1);
+shouldBe("delete MyObject.throwOnDelete", "an exception");
+MyObject.cantSet = 1;
+shouldBe("MyObject.cantSet", undefined);
+shouldBe("MyObject.throwOnGet", "an exception");
+shouldBe("MyObject.throwOnSet = 5", "an exception");
+shouldBe("MyObject('throwOnCall')", "an exception");
+shouldBe("new MyObject('throwOnConstruct')", "an exception");
+shouldBe("'throwOnHasInstance' instanceof MyObject", "an exception");
+
+MyObject.nullGetForwardSet = 1;
+shouldBe("MyObject.nullGetForwardSet", 1);
+
+var foundMyPropertyName = false;
+var foundRegularType = false;
+for (var p in MyObject) {
+ if (p == "myPropertyName")
+ foundMyPropertyName = true;
+ if (p == "regularType")
+ foundRegularType = true;
+}
+
+if (foundMyPropertyName)
+ pass("MyObject.myPropertyName was enumerated");
+else
+ fail("MyObject.myPropertyName was not enumerated");
+
+if (foundRegularType)
+ pass("MyObject.regularType was enumerated");
+else
+ fail("MyObject.regularType was not enumerated");
+
+var alwaysOneDescriptor = Object.getOwnPropertyDescriptor(MyObject, "alwaysOne");
+shouldBe('typeof alwaysOneDescriptor', "object");
+shouldBe('alwaysOneDescriptor.value', MyObject.alwaysOne);
+shouldBe('alwaysOneDescriptor.configurable', true);
+shouldBe('alwaysOneDescriptor.enumerable', false); // Actually it is.
+var cantFindDescriptor = Object.getOwnPropertyDescriptor(MyObject, "cantFind");
+shouldBe('typeof cantFindDescriptor', "object");
+shouldBe('cantFindDescriptor.value', MyObject.cantFind);
+shouldBe('cantFindDescriptor.configurable', true);
+shouldBe('cantFindDescriptor.enumerable', false);
+try {
+ // If getOwnPropertyDescriptor() returned an access descriptor, this wouldn't throw.
+ Object.getOwnPropertyDescriptor(MyObject, "throwOnGet");
+} catch (e) {
+ pass("getting property descriptor of throwOnGet threw exception");
+}
+var myPropertyNameDescriptor = Object.getOwnPropertyDescriptor(MyObject, "myPropertyName");
+shouldBe('typeof myPropertyNameDescriptor', "object");
+shouldBe('myPropertyNameDescriptor.value', MyObject.myPropertyName);
+shouldBe('myPropertyNameDescriptor.configurable', true);
+shouldBe('myPropertyNameDescriptor.enumerable', false); // Actually it is.
+try {
+ // if getOwnPropertyDescriptor() returned an access descriptor, this wouldn't throw.
+ Object.getOwnPropertyDescriptor(MyObject, "hasPropertyLie");
+} catch (e) {
+ pass("getting property descriptor of hasPropertyLie threw exception");
+}
+shouldBe('Object.getOwnPropertyDescriptor(MyObject, "doesNotExist")', undefined);
+
+myObject = new MyObject();
+
+shouldBe("delete MyObject.regularType", true);
+shouldBe("MyObject.regularType", undefined);
+shouldBe("MyObject(0)", 1);
+shouldBe("MyObject()", undefined);
+shouldBe("typeof myObject", "object");
+shouldBe("MyObject ? 1 : 0", true); // toBoolean
+shouldBe("+MyObject", 1); // toNumber
+shouldBe("(Object.prototype.toString.call(MyObject))", "[object MyObject]"); // Object.prototype.toString
+shouldBe("(MyObject.toString())", "[object MyObject]"); // toString
+shouldBe("String(MyObject)", "MyObjectAsString"); // toString
+shouldBe("MyObject - 0", 1); // toNumber
+shouldBe("MyObject.valueOf()", 1); // valueOf
+
+shouldBe("typeof MyConstructor", "object");
+constructedObject = new MyConstructor(1);
+shouldBe("typeof constructedObject", "object");
+shouldBe("constructedObject.value", 1);
+shouldBe("myObject instanceof MyObject", true);
+shouldBe("(new Object()) instanceof MyObject", false);
+
+shouldThrow("new MyBadConstructor()");
+
+MyObject.nullGetSet = 1;
+shouldBe("MyObject.nullGetSet", 1);
+shouldThrow("MyObject.nullCall()");
+shouldThrow("MyObject.hasPropertyLie");
+
+derived = new Derived();
+
+shouldBe("derived instanceof Derived", true);
+shouldBe("derived instanceof Base", true);
+
+// base properties and functions return 1 when called/gotten; derived, 2
+shouldBe("derived.baseProtoDup()", 2);
+shouldBe("derived.baseProto()", 1);
+shouldBe("derived.baseDup", 2);
+shouldBe("derived.baseOnly", 1);
+shouldBe("derived.protoOnly()", 2);
+shouldBe("derived.protoDup", 2);
+shouldBe("derived.derivedOnly", 2)
+
+shouldBe("derived.baseHardNull()", undefined)
+
+// base properties throw 1 when set; derived, 2
+shouldBe("derived.baseDup = 0", 2);
+shouldBe("derived.baseOnly = 0", 1);
+shouldBe("derived.derivedOnly = 0", 2)
+shouldBe("derived.protoDup = 0", 2);
+
+derived2 = new Derived2();
+
+shouldBe("derived2 instanceof Derived2", true);
+shouldBe("derived2 instanceof Derived", true);
+shouldBe("derived2 instanceof Base", true);
+
+// base properties and functions return 1 when called/gotten; derived, 2
+shouldBe("derived2.baseProtoDup()", 2);
+shouldBe("derived2.baseProto()", 1);
+shouldBe("derived2.baseDup", 2);
+shouldBe("derived2.baseOnly", 1);
+shouldBe("derived2.protoOnly()", 2);
+shouldBe("derived2.protoDup", 2);
+shouldBe("derived2.derivedOnly", 2)
+
+// base properties throw 1 when set; derived, 2
+shouldBe("derived2.baseDup = 0", 2);
+shouldBe("derived2.baseOnly = 0", 1);
+shouldBe("derived2.derivedOnly = 0", 2)
+shouldBe("derived2.protoDup = 0", 2);
+
+shouldBe('Object.getOwnPropertyDescriptor(derived, "baseProto")', undefined);
+shouldBe('Object.getOwnPropertyDescriptor(derived, "baseProtoDup")', undefined);
+var baseDupDescriptor = Object.getOwnPropertyDescriptor(derived, "baseDup");
+shouldBe('typeof baseDupDescriptor', "object");
+shouldBe('baseDupDescriptor.value', derived.baseDup);
+shouldBe('baseDupDescriptor.configurable', true);
+shouldBe('baseDupDescriptor.enumerable', false);
+var baseOnlyDescriptor = Object.getOwnPropertyDescriptor(derived, "baseOnly");
+shouldBe('typeof baseOnlyDescriptor', "object");
+shouldBe('baseOnlyDescriptor.value', derived.baseOnly);
+shouldBe('baseOnlyDescriptor.configurable', true);
+shouldBe('baseOnlyDescriptor.enumerable', false);
+shouldBe('Object.getOwnPropertyDescriptor(derived, "protoOnly")', undefined);
+var protoDupDescriptor = Object.getOwnPropertyDescriptor(derived, "protoDup");
+shouldBe('typeof protoDupDescriptor', "object");
+shouldBe('protoDupDescriptor.value', derived.protoDup);
+shouldBe('protoDupDescriptor.configurable', true);
+shouldBe('protoDupDescriptor.enumerable', false);
+var derivedOnlyDescriptor = Object.getOwnPropertyDescriptor(derived, "derivedOnly");
+shouldBe('typeof derivedOnlyDescriptor', "object");
+shouldBe('derivedOnlyDescriptor.value', derived.derivedOnly);
+shouldBe('derivedOnlyDescriptor.configurable', true);
+shouldBe('derivedOnlyDescriptor.enumerable', false);
+
+shouldBe("undefined instanceof MyObject", false);
+EvilExceptionObject.hasInstance = function f() { return f(); };
+EvilExceptionObject.__proto__ = undefined;
+shouldThrow("undefined instanceof EvilExceptionObject");
+EvilExceptionObject.hasInstance = function () { return true; };
+shouldBe("undefined instanceof EvilExceptionObject", true);
+
+EvilExceptionObject.toNumber = function f() { return f(); }
+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)
+ PropertyCatchalls.x = i;
+shouldBe("PropertyCatchalls.x", 4);
+
+for (var i = 0; i < 6; ++i)
+ var x = PropertyCatchalls.x;
+shouldBe("x", null);
+var make_throw = 'make_throw';
+shouldThrow("PropertyCatchalls[make_throw]=1");
+make_throw = 0;
+shouldThrow("PropertyCatchalls[make_throw]=1");
+
+for (var i = 0; i < 10; ++i) {
+ for (var p in PropertyCatchalls) {
+ if (p == "x")
+ continue;
+ shouldBe("p", i % 10);
+ break;
+ }
+}
+
+PropertyCatchalls.__proto__ = { y: 1 };
+for (var i = 0; i < 6; ++i)
+ var y = PropertyCatchalls.y;
+shouldBe("y", null);
+
+var o = { __proto__: PropertyCatchalls };
+for (var i = 0; i < 6; ++i)
+ var z = PropertyCatchalls.z;
+shouldBe("z", null);
+
+if (failed)
+ throw "Some tests failed";