Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
Binary file added JavaScriptCore-ObjC_Bridge.zip
Binary file not shown.
72 changes: 72 additions & 0 deletions JavaScriptCore/API/APICallbackFunction.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
* Copyright (C) 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#ifndef APICallbackFunction_h
#define APICallbackFunction_h

#include "APICast.h"
#include "APIShims.h"
#include "Error.h"
#include <wtf/Vector.h>

namespace JSC {

struct APICallbackFunction {

template <typename T> static EncodedJSValue JSC_HOST_CALL call(ExecState*);

};

template <typename T>
EncodedJSValue JSC_HOST_CALL APICallbackFunction::call(ExecState* exec)
{
JSContextRef execRef = toRef(exec);
JSObjectRef functionRef = toRef(exec->callee());
JSObjectRef thisObjRef = toRef(jsCast<JSObject*>(exec->hostThisValue().toThis(exec, NotStrictMode)));

int argumentCount = static_cast<int>(exec->argumentCount());
Vector<JSValueRef, 16> arguments;
arguments.reserveInitialCapacity(argumentCount);
for (int i = 0; i < argumentCount; i++)
arguments.uncheckedAppend(toRef(exec, exec->argument(i)));

JSValueRef exception = 0;
JSValueRef result;
{
APICallbackShim callbackShim(exec);
result = jsCast<T*>(toJS(functionRef))->m_callback(execRef, functionRef, thisObjRef, argumentCount, arguments.data(), &exception);
}
if (exception)
exec->vm().throwException(exec, toJS(exec, exception));

// result must be a valid JSValue.
if (!result)
return JSValue::encode(jsUndefined());

return JSValue::encode(toJS(exec, result));
}
} // namespace JSC

#endif // APICallbackFunction_h
46 changes: 31 additions & 15 deletions JavaScriptCore/API/APICast.h
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,13 @@
#define APICast_h

#include "JSAPIValueWrapper.h"
#include "JSCJSValue.h"
#include "JSGlobalObject.h"
#include "JSValue.h"
#include <wtf/UnusedParam.h>

namespace JSC {
class ExecState;
class PropertyNameArray;
class JSGlobalData;
class VM;
class JSObject;
class JSValue;
}
Expand Down Expand Up @@ -63,46 +62,63 @@ inline JSC::ExecState* toJS(JSGlobalContextRef c)
inline JSC::JSValue toJS(JSC::ExecState* exec, JSValueRef v)
{
ASSERT_UNUSED(exec, exec);
ASSERT(v);
#if USE(JSVALUE32_64)
JSC::JSCell* jsCell = reinterpret_cast<JSC::JSCell*>(const_cast<OpaqueJSValue*>(v));
if (!jsCell)
return JSC::JSValue();
return JSC::jsNull();
JSC::JSValue result;
if (jsCell->isAPIValueWrapper())
return JSC::jsCast<JSC::JSAPIValueWrapper*>(jsCell)->value();
return jsCell;
result = JSC::jsCast<JSC::JSAPIValueWrapper*>(jsCell)->value();
else
result = jsCell;
#else
return JSC::JSValue::decode(reinterpret_cast<JSC::EncodedJSValue>(const_cast<OpaqueJSValue*>(v)));
JSC::JSValue result = JSC::JSValue::decode(reinterpret_cast<JSC::EncodedJSValue>(const_cast<OpaqueJSValue*>(v)));
#endif
if (!result)
return JSC::jsNull();
if (result.isCell())
RELEASE_ASSERT(result.asCell()->methodTable());
return result;
}

inline JSC::JSValue toJSForGC(JSC::ExecState* exec, JSValueRef v)
{
ASSERT_UNUSED(exec, exec);
ASSERT(v);
#if USE(JSVALUE32_64)
JSC::JSCell* jsCell = reinterpret_cast<JSC::JSCell*>(const_cast<OpaqueJSValue*>(v));
if (!jsCell)
return JSC::JSValue();
return jsCell;
JSC::JSValue result = jsCell;
#else
return JSC::JSValue::decode(reinterpret_cast<JSC::EncodedJSValue>(const_cast<OpaqueJSValue*>(v)));
JSC::JSValue result = JSC::JSValue::decode(reinterpret_cast<JSC::EncodedJSValue>(const_cast<OpaqueJSValue*>(v)));
#endif
if (result && result.isCell())
RELEASE_ASSERT(result.asCell()->methodTable());
return result;
}

inline JSC::JSObject* toJS(JSObjectRef o)
// Used in JSObjectGetPrivate as that may be called during finalization
inline JSC::JSObject* uncheckedToJS(JSObjectRef o)
{
return reinterpret_cast<JSC::JSObject*>(o);
}

inline JSC::JSObject* toJS(JSObjectRef o)
{
JSC::JSObject* object = uncheckedToJS(o);
if (object)
RELEASE_ASSERT(object->methodTable());
return object;
}

inline JSC::PropertyNameArray* toJS(JSPropertyNameAccumulatorRef a)
{
return reinterpret_cast<JSC::PropertyNameArray*>(a);
}

inline JSC::JSGlobalData* toJS(JSContextGroupRef g)
inline JSC::VM* toJS(JSContextGroupRef g)
{
return reinterpret_cast<JSC::JSGlobalData*>(const_cast<OpaqueJSContextGroup*>(g));
return reinterpret_cast<JSC::VM*>(const_cast<OpaqueJSContextGroup*>(g));
}

inline JSValueRef toRef(JSC::ExecState* exec, JSC::JSValue v)
Expand Down Expand Up @@ -145,7 +161,7 @@ inline JSPropertyNameAccumulatorRef toRef(JSC::PropertyNameArray* l)
return reinterpret_cast<JSPropertyNameAccumulatorRef>(l);
}

inline JSContextGroupRef toRef(JSC::JSGlobalData* g)
inline JSContextGroupRef toRef(JSC::VM* g)
{
return reinterpret_cast<JSContextGroupRef>(g);
}
Expand Down
60 changes: 19 additions & 41 deletions JavaScriptCore/API/APIShims.h
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -28,97 +28,75 @@

#include "CallFrame.h"
#include "GCActivityCallback.h"
#include "IncrementalSweeper.h"
#include "JSLock.h"
#include <wtf/WTFThreadData.h>

namespace JSC {

class APIEntryShimWithoutLock {
public:
enum RefGlobalDataTag { DontRefGlobalData = 0, RefGlobalData };

protected:
APIEntryShimWithoutLock(JSGlobalData* globalData, bool registerThread, RefGlobalDataTag shouldRefGlobalData)
: m_shouldRefGlobalData(shouldRefGlobalData)
, m_globalData(globalData)
, m_entryIdentifierTable(wtfThreadData().setCurrentIdentifierTable(globalData->identifierTable))
APIEntryShimWithoutLock(VM* vm, bool registerThread)
: m_vm(vm)
, m_entryIdentifierTable(wtfThreadData().setCurrentIdentifierTable(vm->identifierTable))
{
if (shouldRefGlobalData)
m_globalData->ref();
UNUSED_PARAM(registerThread);
if (registerThread)
globalData->heap.machineThreads().addCurrentThread();
m_globalData->heap.activityCallback()->synchronize();
vm->heap.machineThreads().addCurrentThread();
}

~APIEntryShimWithoutLock()
{
wtfThreadData().setCurrentIdentifierTable(m_entryIdentifierTable);
if (m_shouldRefGlobalData)
m_globalData->deref();
}

protected:
RefGlobalDataTag m_shouldRefGlobalData;
JSGlobalData* m_globalData;
RefPtr<VM> m_vm;
IdentifierTable* m_entryIdentifierTable;
};

class APIEntryShim : public APIEntryShimWithoutLock {
public:
// Normal API entry
APIEntryShim(ExecState* exec, bool registerThread = true)
: APIEntryShimWithoutLock(&exec->globalData(), registerThread, RefGlobalData)
: APIEntryShimWithoutLock(&exec->vm(), registerThread)
, m_lockHolder(exec->vm().exclusiveThread ? 0 : exec)
{
init();
}

// This constructor is necessary for HeapTimer to prevent it from accidentally resurrecting
// the ref count of a "dead" JSGlobalData.
APIEntryShim(JSGlobalData* globalData, RefGlobalDataTag refGlobalData, bool registerThread = true)
: APIEntryShimWithoutLock(globalData, registerThread, refGlobalData)
// JSPropertyNameAccumulator only has a vm.
APIEntryShim(VM* vm, bool registerThread = true)
: APIEntryShimWithoutLock(vm, registerThread)
, m_lockHolder(vm->exclusiveThread ? 0 : vm)
{
init();
}

// JSPropertyNameAccumulator only has a globalData.
APIEntryShim(JSGlobalData* globalData, bool registerThread = true)
: APIEntryShimWithoutLock(globalData, registerThread, RefGlobalData)
{
init();
}

~APIEntryShim()
{
m_globalData->timeoutChecker.stop();
m_globalData->apiLock().unlock();
// Destroying our JSLockHolder should also destroy the VM.
m_vm.clear();
}

private:
void init()
{
m_globalData->apiLock().lock();
m_globalData->timeoutChecker.start();
}
JSLockHolder m_lockHolder;
};

class APICallbackShim {
public:
APICallbackShim(ExecState* exec)
: m_dropAllLocks(exec)
, m_globalData(&exec->globalData())
: m_dropAllLocks(exec->vm().exclusiveThread ? 0 : exec)
, m_vm(&exec->vm())
{
wtfThreadData().resetCurrentIdentifierTable();
}

~APICallbackShim()
{
wtfThreadData().setCurrentIdentifierTable(m_globalData->identifierTable);
wtfThreadData().setCurrentIdentifierTable(m_vm->identifierTable);
}

private:
JSLock::DropAllLocks m_dropAllLocks;
JSGlobalData* m_globalData;
VM* m_vm;
};

}
Expand Down
60 changes: 60 additions & 0 deletions JavaScriptCore/API/JSAPIWrapperObject.h
Original file line number Diff line number Diff line change
@@ -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. 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 JSAPIWrapperObject_h
#define JSAPIWrapperObject_h

#include "JSBase.h"
#include "JSDestructibleObject.h"
#include "WeakReferenceHarvester.h"

#if JSC_OBJC_API_ENABLED

namespace JSC {

class JSAPIWrapperObject : public JSDestructibleObject {
public:
typedef JSDestructibleObject Base;

void finishCreation(VM&);
static void visitChildren(JSCell*, JSC::SlotVisitor&);

void* wrappedObject() { return m_wrappedObject; }
void setWrappedObject(void*);

protected:
static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags;

JSAPIWrapperObject(VM&, Structure*);

private:
void* m_wrappedObject;
};

} // namespace JSC

#endif // JSC_OBJC_API_ENABLED

#endif // JSAPIWrapperObject_h
Loading