summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/API/JSContextRef.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/JavaScriptCore/API/JSContextRef.cpp')
-rw-r--r--Source/JavaScriptCore/API/JSContextRef.cpp222
1 files changed, 170 insertions, 52 deletions
diff --git a/Source/JavaScriptCore/API/JSContextRef.cpp b/Source/JavaScriptCore/API/JSContextRef.cpp
index 81b61cf47..e7dad19b0 100644
--- a/Source/JavaScriptCore/API/JSContextRef.cpp
+++ b/Source/JavaScriptCore/API/JSContextRef.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2013, 2016 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,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.
@@ -129,30 +133,36 @@ JSGlobalContextRef JSGlobalContextCreateInGroup(JSContextGroupRef group, JSClass
{
initializeThreading();
- RefPtr<VM> vm = group ? PassRefPtr<VM>(toJS(group)) : VM::createContextGroup();
+ Ref<VM> vm = group ? Ref<VM>(*toJS(group)) : VM::createContextGroup();
- APIEntryShim entryShim(vm.get(), false);
- vm->makeUsableFromMultipleThreads();
+ JSLockHolder locker(vm.ptr());
if (!globalObjectClass) {
- JSGlobalObject* globalObject = JSGlobalObject::create(*vm, JSGlobalObject::createStructure(*vm, jsNull()));
- globalObject->setGlobalThis(*vm, JSProxy::create(*vm, JSProxy::createStructure(*vm, globalObject, globalObject->prototype()), globalObject));
+ JSGlobalObject* globalObject = JSGlobalObject::create(vm.get(), JSGlobalObject::createStructure(vm.get(), jsNull()));
+#if ENABLE(REMOTE_INSPECTOR)
+ if (JSRemoteInspectorGetInspectionEnabledByDefault())
+ globalObject->setRemoteDebuggingEnabled(true);
+#endif
return JSGlobalContextRetain(toGlobalRef(globalObject->globalExec()));
}
- JSGlobalObject* globalObject = JSCallbackObject<JSGlobalObject>::create(*vm, globalObjectClass, JSCallbackObject<JSGlobalObject>::createStructure(*vm, 0, jsNull()));
+ JSGlobalObject* globalObject = JSCallbackObject<JSGlobalObject>::create(vm.get(), globalObjectClass, JSCallbackObject<JSGlobalObject>::createStructure(vm.get(), 0, jsNull()));
ExecState* exec = globalObject->globalExec();
JSValue prototype = globalObjectClass->prototype(exec);
if (!prototype)
prototype = jsNull();
- globalObject->resetPrototype(*vm, prototype);
+ globalObject->resetPrototype(vm.get(), 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());
}
@@ -252,12 +255,12 @@ public:
{
}
- StackVisitor::Status operator()(StackVisitor& visitor)
+ StackVisitor::Status operator()(StackVisitor& visitor) const
{
if (m_remainingCapacityForFrameCapture) {
// If callee is unknown, but we've not added any frame yet, we should
// still add the frame, because something called us, and gave us arguments.
- JSObject* callee = visitor->callee();
+ JSCell* callee = visitor->callee();
if (!callee && visitor->index())
return StackVisitor::Done;
@@ -270,7 +273,7 @@ public:
builder.append(visitor->functionName());
builder.appendLiteral("() at ");
builder.append(visitor->sourceURL());
- if (visitor->isJSFrame()) {
+ if (visitor->hasLineAndColumnInfo()) {
builder.append(':');
unsigned lineNumber;
unsigned unusedColumn;
@@ -289,7 +292,7 @@ public:
private:
StringBuilder& m_builder;
- unsigned m_remainingCapacityForFrameCapture;
+ mutable unsigned m_remainingCapacityForFrameCapture;
};
JSStringRef JSContextCreateBacktrace(JSContextRef ctx, unsigned maxStackSize)
@@ -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