Skip to content

Commit

Permalink
Webkit SVN Tag 538.4
Browse files Browse the repository at this point in the history
  • Loading branch information
phoboslab committed Nov 5, 2013
1 parent a775d4b commit 3895c67
Show file tree
Hide file tree
Showing 1,828 changed files with 429,888 additions and 177,441 deletions.
109 changes: 109 additions & 0 deletions JavaScriptCore/API/APICallbackFunction.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/*
* Copyright (C) 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#ifndef APICallbackFunction_h
#define APICallbackFunction_h

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

namespace JSC {

struct APICallbackFunction {

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

};

template <typename T>
EncodedJSValue JSC_HOST_CALL APICallbackFunction::call(ExecState* exec)
{
JSContextRef execRef = toRef(exec);
JSObjectRef functionRef = toRef(exec->callee());
JSObjectRef thisObjRef = toRef(jsCast<JSObject*>(exec->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->uncheckedArgument(i)));

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

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

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

template <typename T>
EncodedJSValue JSC_HOST_CALL APICallbackFunction::construct(ExecState* exec)
{
JSObject* constructor = exec->callee();
JSContextRef ctx = toRef(exec);
JSObjectRef constructorRef = toRef(constructor);

JSObjectCallAsConstructorCallback callback = jsCast<T*>(constructor)->constructCallback();
if (callback) {
size_t argumentCount = exec->argumentCount();
Vector<JSValueRef, 16> arguments;
arguments.reserveInitialCapacity(argumentCount);
for (size_t i = 0; i < argumentCount; ++i)
arguments.uncheckedAppend(toRef(exec, exec->uncheckedArgument(i)));

JSValueRef exception = 0;
JSObjectRef result;
{
APICallbackShim callbackShim(exec);
result = callback(ctx, constructorRef, argumentCount, arguments.data(), &exception);
}
if (exception) {
exec->vm().throwException(exec, toJS(exec, exception));
return JSValue::encode(toJS(exec, exception));
}
// result must be a valid JSValue.
if (!result)
return throwVMTypeError(exec);
return JSValue::encode(toJS(result));
}

return JSValue::encode(toJS(JSObjectMake(ctx, jsCast<JSCallbackConstructor*>(constructor)->classRef(), 0)));
}

} // namespace JSC

#endif // APICallbackFunction_h
47 changes: 32 additions & 15 deletions JavaScriptCore/API/APICast.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,14 @@
#define APICast_h

#include "JSAPIValueWrapper.h"
#include "JSCJSValue.h"
#include "JSCJSValueInlines.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 +63,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 +162,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
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

0 comments on commit 3895c67

Please sign in to comment.