open source

This commit is contained in:
lvfulong
2020-11-11 16:17:13 +08:00
parent 4d989f3ecb
commit bc4ca748de
2441 changed files with 623057 additions and 2 deletions
@@ -0,0 +1,141 @@
#ifdef JS_JSC
#include "JSCArrayBuffer.h"
#include <JavaScriptCore/JSTypedArray.h>
#include "JSCProxyTLS.h"
#include "util/Log.h"
#include <vector>
#include "JSCProxyType.h"
namespace laya {
//TODO 这里没有考虑多线程的问题,如果js要支持多线程的话,需要修改。
struct JsStrBuff {
char* _buff;
int _len;
static std::vector<JsStrBuff> jsstrbuffs;
static int curIdx;
JsStrBuff() {
_buff = NULL;
_len = 0;
}
static JsStrBuff& getAData() {
if (JsStrBuff::curIdx >= JsStrBuff::jsstrbuffs.size()) {
JsStrBuff::jsstrbuffs.push_back(JsStrBuff());
JsStrBuff::curIdx++;
return JsStrBuff::jsstrbuffs.back();
}
else {
return JsStrBuff::jsstrbuffs[JsStrBuff::curIdx++];
}
}
};
std::vector<JsStrBuff> JsStrBuff::jsstrbuffs;
int JsStrBuff::curIdx = 0;
void resetJsStrBuf() {
JsStrBuff::curIdx = 0;
}
char* JsCharToC(JSStringRef str) {
int len = 0;
if (str == nullptr)
return nullptr;//return "";
len = JSStringGetMaximumUTF8CStringSize(str);
if (len <= 0)
return nullptr;//return "";
JsStrBuff& curdata = JsStrBuff::getAData();
char*& tocharBuf = curdata._buff;
int& tocharBufLen = curdata._len;
//tocharBuf= new char[len + 1];
if (len > tocharBufLen) {
tocharBufLen = len;
if (tocharBuf != NULL)
delete[] tocharBuf;
tocharBuf = new char[len+1];
}
else {
//如果占用空间太大,也要重新分配
if (tocharBufLen > 1024 ) {
tocharBufLen = len;
if (tocharBuf != NULL)
delete[] tocharBuf;
tocharBuf = new char[len+1];
}
}
JSStringGetUTF8CString(str,tocharBuf,len);
return tocharBuf;
}
char* JsCharToC(JSValueRef p_vl) {
JSContextRef ctx = __TlsData::GetInstance()->GetCurContext();
JSStringRef str = JSValueToStringCopy(ctx, p_vl, nullptr);
if (str == nullptr)
return nullptr;//return "";
char* ret = JsCharToC(str);
JSStringRelease(str);
return ret;
}
}
namespace laya{
static void deallocator(void* bytes, void* deallocatorContext)
{
if (bytes){
delete (char*)bytes;
}
}
JSValueRef createJSAB(char* pData, int len)
{
JSContextRef ctx = __TlsData::GetInstance()->GetCurContext();
char* pBuffer = new char[len];
memcpy(pBuffer, pData, len);
return JSObjectMakeArrayBufferWithBytesNoCopy(ctx, pBuffer, len, deallocator, pBuffer, NULL);
}
JSValueRef createJSABAligned(char* pData, int len)
{
int asz = (len+3) & 0xfffffffc;
JSContextRef ctx = __TlsData::GetInstance()->GetCurContext();
char* pBuffer = new char[asz];
memcpy(pBuffer, pData, len);
for( int i = len; i < asz; i++ )
{
pBuffer[i] = 0;
}
return JSObjectMakeArrayBufferWithBytesNoCopy(ctx, pBuffer, asz, deallocator, pBuffer, NULL);
}
bool extractJSAB(JSValueRef ab, char*& data, int& len)
{
JSContextRef ctx = __TlsData::GetInstance()->GetCurContext();
JSObjectRef arrayObj = JSValueToObject(ctx,ab,NULL);
JSTypedArrayType arrayType = JSValueGetTypedArrayType(ctx, ab, NULL);
switch(arrayType)
{
case kJSTypedArrayTypeNone:
{
data = NULL;
len = 0;
return false;
}
break;
case kJSTypedArrayTypeArrayBuffer:
{
data = (char*)JSObjectGetArrayBufferBytesPtr(ctx, arrayObj, NULL);
len = (int)JSObjectGetArrayBufferByteLength(ctx, arrayObj, NULL);
return true;
}
break;
default:
{
data = (char*)JSObjectGetTypedArrayBytesPtr(ctx, arrayObj, NULL) + JSObjectGetTypedArrayByteOffset(ctx, arrayObj, NULL);
len = (int)JSObjectGetTypedArrayByteLength(ctx, arrayObj, NULL);
return true;
}
break;
}
}
}
#endif
@@ -0,0 +1,16 @@
#ifndef _JSC_ARRAYBUFFER_H_
#define _JSC_ARRAYBUFFER_H_
#include <memory>
#include <JavaScriptCore/JSValueRef.h>
namespace laya{
JSValueRef createJSAB(char* pData, int len);
JSValueRef createJSABAligned(char* pData, int len);
bool extractJSAB(JSValueRef ab, char*& data, int& len);
}
#endif
@@ -0,0 +1,44 @@
#ifdef JS_JSC
#include "JSCBinder.h"
pthread_key_t JSClassMgr::s_tls_curThread;
JSObjBaseJSC::JSObjBaseJSC() {
m_bWeakThis = true;
}
JSObjBaseJSC::~JSObjBaseJSC() {
if (!m_bWeakThis){
JSContextRef ctx = __TlsData::GetInstance()->GetCurContext();
JSValueUnprotect(ctx, mpJsThis);
}
}
void JSObjBaseJSC::retainThis() {
JSContextRef ctx = __TlsData::GetInstance()->GetCurContext();
JSValueProtect(ctx, mpJsThis);
}
void JSObjBaseJSC::releaseThis() {
JSContextRef ctx = __TlsData::GetInstance()->GetCurContext();
JSValueUnprotect(ctx, mpJsThis);
}
void JSObjBaseJSC::createJSObj(){
JSContextRef ctx = __TlsData::GetInstance()->GetCurContext();
mpJsThis = JSObjectMake(ctx,nullptr,nullptr);
JSValueProtect(ctx, mpJsThis);
m_bWeakThis = false;
}
JSValueRef JSObjBaseJSC::callJsFunc(JSValueRef func) {
return _callJsFunc(func, 0, nullptr);
}
bool JsObjHandleJSC::Empty() {
if (!m_pObj)
return true;
return m_pValue == nullptr;
}
#endif
@@ -0,0 +1,373 @@
#ifndef _JSC_BINDER_H__
#define _JSC_BINDER_H__
#include <JavaScriptCore/JSObjectRef.h>
#include "JSCProxyTransfer.h"
#include "JSCProxyType.h"
#include "JSCProxyClass.h"
#include <pthread.h>
using namespace laya;
class JSClassMgr{
public:
static pthread_key_t s_tls_curThread;
typedef void (*RESETFUNC)();
static JSClassMgr* GetThreadInstance(){
JSClassMgr* pIns =(JSClassMgr*)pthread_getspecific(s_tls_curThread);
if(!pIns){
pIns = new JSClassMgr();
pthread_setspecific(s_tls_curThread,(void*)pIns);
}
return pIns;
}
std::vector<RESETFUNC> allCls;
void resetAllRegClass(){
for( int i=0,sz=allCls.size(); i<sz; i++){
allCls[i]();
}
allCls.clear();
}
};
#define JSP_GLOBAL_START1()
#define JSP_ADD_GLOBAL_FUNCTION(name, func, ...) \
JSCGlobal::getInstance()->addFunction( #name, func );
#define JSP_ADD_GLOBAL_PROPERTY(name, v) \
JSCGlobal::getInstance()->addProperty( #name, v );
#define JSP_CLASS(name, cls) \
JSCClass<cls>* pJSCClass = JSCClass<cls>::getInstance();
#define JSP_GLOBAL_CLASS(name, cls) \
JSCClass<cls>* pJSCClass = JSCClass<cls>::getInstance();
#define JSP_ADD_FIXED_PROPERTY(name,cls,val) \
pJSCClass->addFixedProperty(#name,val)
#define JSP_ADD_METHOD(name,fn) \
pJSCClass->addMethod(name,&fn);
#define JSP_ADD_PROPERTY_RO(name,cls,getter) \
pJSCClass->addProperty(#name,&cls::getter,nullptr);
#define JSP_ADD_PROPERTY(name,cls,getter,setter) \
pJSCClass->addProperty(#name,&cls::getter,&cls::setter);
#define JSP_REG_CONSTRUCTOR(cls,...) \
pJSCClass->addConstructor(laya::regConstructor<cls,##__VA_ARGS__>());
#define JSP_INSTALL_CLASS(name,cls) \
pJSCClass->finish(name); \
JSClassMgr::GetThreadInstance()->allCls.push_back(JSCClass<cls>::reset);
#define JSP_INSTALL_GLOBAL_CLASS(name,cls,inst) \
pJSCClass->finishToGlobal(name,inst); \
JSClassMgr::GetThreadInstance()->allCls.push_back(JSCClass<cls>::reset);
class JSObjBaseJSC {
friend class JsObjHandleJSC;
public:
JSObjBaseJSC();
virtual ~JSObjBaseJSC();
void retainThis();
void releaseThis();
void createJSObj();
bool IsMyJsEnv() {
return true;
}
inline JSValueRef _callJsFunc(JSValueRef func, size_t argumentCount, const JSValueRef arguments[]) {
JSContextRef ctx = __TlsData::GetInstance()->GetCurContext();
JSValueRef exception = nullptr;
JSObjectRef funcObj = JSValueToObject(ctx,func,&exception);
if (exception != nullptr){
__JSRun::OutputException(exception);
}
JSValueRef ret = JSObjectCallAsFunction(ctx,funcObj,mpJsThis,argumentCount,arguments,&exception);
if (exception != nullptr){
__JSRun::OutputException(exception);
}
return ret;
}
JSValueRef callJsFunc(JSValueRef func);
template<class P1>
JSValueRef callJsFunc(JSValueRef func, P1 p1) {
int argc = 1;
JSValueRef argv[1];
argv[0] = __TransferToJs<P1>::ToJs(p1);
return _callJsFunc(func, argc, argv);
}
template<class P1, class P2>
JSValueRef callJsFunc(JSValueRef func, P1 p1, P2 p2) {
int argc = 2;
JSValueRef argv[2];
argv[0] = __TransferToJs<P1>::ToJs(p1);
argv[1] = __TransferToJs<P2>::ToJs(p2);
return _callJsFunc(func, argc, argv);
}
template<class P1, class P2, class P3>
JSValueRef callJsFunc(JSValueRef func, P1 p1, P2 p2, P3 p3) {
int argc = 3;
JSValueRef argv[3];
argv[0] = __TransferToJs<P1>::ToJs(p1);
argv[1] = __TransferToJs<P2>::ToJs(p2);
argv[2] = __TransferToJs<P3>::ToJs(p3);
return _callJsFunc(func, argc, argv);
}
template<class P1, class P2, class P3, class P4>
JSValueRef callJsFunc(JSValueRef func, P1 p1, P2 p2, P3 p3, P4 p4) {
int argc = 4;
JSValueRef argv[4];
argv[0] = __TransferToJs<P1>::ToJs(p1);
argv[1] = __TransferToJs<P2>::ToJs(p2);
argv[2] = __TransferToJs<P3>::ToJs(p3);
argv[3] = __TransferToJs<P4>::ToJs(p4);
return _callJsFunc(func, argc, argv);
}
template<class P1, class P2, class P3, class P4, class P5>
JSValueRef callJsFunc(JSValueRef func, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) {
int argc = 5;
JSValueRef argv[5];
argv[0] = __TransferToJs<P1>::ToJs(p1);
argv[1] = __TransferToJs<P2>::ToJs(p2);
argv[2] = __TransferToJs<P3>::ToJs(p3);
argv[3] = __TransferToJs<P4>::ToJs(p4);
argv[4] = __TransferToJs<P5>::ToJs(p5);
return _callJsFunc(func, argc, argv);
}
template<class P1, class P2, class P3, class P4, class P5, class P6>
JSValueRef callJsFunc(JSValueRef func, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) {
int argc = 6;
JSValueRef argv[6];
argv[0] = __TransferToJs<P1>::ToJs(p1);
argv[1] = __TransferToJs<P2>::ToJs(p2);
argv[2] = __TransferToJs<P3>::ToJs(p3);
argv[3] = __TransferToJs<P4>::ToJs(p4);
argv[4] = __TransferToJs<P5>::ToJs(p5);
argv[5] = __TransferToJs<P6>::ToJs(p6);
return _callJsFunc(func, argc, argv);
}
template<class P1, class P2, class P3, class P4, class P5, class P6, class P7>
JSValueRef callJsFunc(JSValueRef func, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7) {
int argc = 7;
JSValueRef argv[7];
argv[0] = __TransferToJs<P1>::ToJs(p1);
argv[1] = __TransferToJs<P2>::ToJs(p2);
argv[2] = __TransferToJs<P3>::ToJs(p3);
argv[3] = __TransferToJs<P4>::ToJs(p4);
argv[4] = __TransferToJs<P5>::ToJs(p5);
argv[5] = __TransferToJs<P6>::ToJs(p6);
argv[6] = __TransferToJs<P7>::ToJs(p7);
return _callJsFunc(func, argc, argv);
}
template<class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8>
JSValueRef callJsFunc(JSValueRef func, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8) {
int argc = 8;
JSValueRef argv[8];
argv[0] = __TransferToJs<P1>::ToJs(p1);
argv[1] = __TransferToJs<P2>::ToJs(p2);
argv[2] = __TransferToJs<P3>::ToJs(p3);
argv[3] = __TransferToJs<P4>::ToJs(p4);
argv[4] = __TransferToJs<P5>::ToJs(p5);
argv[5] = __TransferToJs<P6>::ToJs(p6);
argv[6] = __TransferToJs<P7>::ToJs(p7);
argv[7] = __TransferToJs<P8>::ToJs(p8);
return _callJsFunc(func, argc, argv);
}
template<class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class P9, class P10, class P11, class P12>
JSValueRef callJsFunc(JSValueRef func, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9, P10 p10, P11 p11, P12 p12) {
int argc = 12;
JSValueRef argv[12];
argv[0] = __TransferToJs<P1>::ToJs(p1);
argv[1] = __TransferToJs<P2>::ToJs(p2);
argv[2] = __TransferToJs<P3>::ToJs(p3);
argv[3] = __TransferToJs<P4>::ToJs(p4);
argv[4] = __TransferToJs<P5>::ToJs(p5);
argv[5] = __TransferToJs<P6>::ToJs(p6);
argv[6] = __TransferToJs<P7>::ToJs(p7);
argv[7] = __TransferToJs<P8>::ToJs(p8);
argv[8] = __TransferToJs<P8>::ToJs(p9);
argv[9] = __TransferToJs<P8>::ToJs(p10);
argv[10] = __TransferToJs<P8>::ToJs(p11);
argv[11] = __TransferToJs<P8>::ToJs(p12);
return _callJsFunc(func, argc, argv);
}
public:
JSObjectRef mpJsThis;
bool m_bWeakThis;
};
class JsObjHandleJSC
{
public:
JsObjHandleJSC() {
m_pObj = nullptr;
m_pValue = nullptr;
m_pReturn = nullptr;
}
~JsObjHandleJSC(){
JSContextRef ctx = __TlsData::GetInstance()->GetCurContext();
if (m_pValue != nullptr && ctx != nullptr)
{
JSValueUnprotect(ctx, m_pValue);
}
}
JSObjBaseJSC* m_pObj;
JSValueRef m_pValue;
JSValueRef m_pReturn;
bool Empty();
JSValueRef getJsObj() {
return m_pValue;
}
void set(int id, JSObjBaseJSC* pobj, JSValueRef v) {
if (m_pValue != nullptr){
Reset();
}
m_pValue = v;
JSValueProtect(__TlsData::GetInstance()->GetCurContext(), m_pValue);
m_pObj = pobj;
}
template <typename _Tp>
static bool IsTypeof(JSValueRef val) {
if (val == nullptr)
return false;
JSContextRef ctx = __TlsData::GetInstance()->GetCurContext();
__InferType<_Tp> _it;
switch (_it.iType) {
case __VT_void:
return false;
case __VT_string:
return JSValueIsString(ctx, val);
case __VT_bool:
return JSValueIsBoolean(ctx, val);
case __VT_int:
case __VT_long:
case __VT_float:
case __VT_double:
case __VT_longlong:
return JSValueIsNumber(ctx,val);
default: {
return __CheckClassType::IsTypeOf<_Tp>(val);
}
}
}
template <typename _Tp>
bool IsTypeof() {
return IsTypeof<_Tp>(m_pValue);
}
template <typename _R>
static bool tryGet(JSValueRef val, _R **pRet) {
if (val == nullptr) {
*pRet = 0;
return false;
}
if (!__TransferToCpp<_R>::is(val))
return false;
*pRet = __TransferToCpp<_R*>::ToCpp(val);
return true;
}
static bool tryGetStr(JSValueRef val, char** ppRet) {
if (JSValueIsString(__TlsData::GetInstance()->GetCurContext(), val)) {
*ppRet = JsCharToC(val);
return true;
}
return false;
}
void Reset() {
JSContextRef ctx = __TlsData::GetInstance()->GetCurContext();
if (m_pValue != nullptr && ctx != nullptr){
JSValueUnprotect(ctx, m_pValue);
m_pValue = nullptr;
}
}
void __BindThis(JsObjHandleJSC &p_This) {}
bool IsFunction() {
if (!m_pObj)return false;
JSContextRef ctx = __TlsData::GetInstance()->GetCurContext();
JSObjectRef valueObj = JSValueToObject(ctx, m_pValue, nullptr);
if (!JSObjectIsFunction(ctx, valueObj))
return false;
return true;
}
bool isValid() {
return m_pValue != nullptr && m_pObj != nullptr && m_pObj->IsMyJsEnv();
}
#define CALLJSPRE \
if (!m_pObj)return false; \
JSContextRef ctx = __TlsData::GetInstance()->GetCurContext(); \
JSObjectRef func = JSValueToObject(ctx, m_pValue, nullptr); \
if (!JSObjectIsFunction(ctx,func)) \
return false;
bool Call() {
CALLJSPRE
m_pReturn = m_pObj->callJsFunc(func);
return true;
}
template <typename P1>
bool Call(P1 p1) {
CALLJSPRE
m_pReturn = m_pObj->callJsFunc(func,p1);
return true;
}
template <typename P1, typename P2>
bool Call(P1 p1, P2 p2) {
CALLJSPRE
m_pReturn = m_pObj->callJsFunc(func, p1, p2);
return true;
}
template <typename P1, typename P2, typename P3>
bool Call(P1 p1, P2 p2, P3 p3) {
CALLJSPRE
m_pReturn = m_pObj->callJsFunc(func, p1, p2, p3);
return true;
}
template <typename P1, typename P2, typename P3, typename P4>
bool Call(P1 p1, P2 p2, P3 p3, P4 p4) {
CALLJSPRE
m_pReturn = m_pObj->callJsFunc(func, p1, p2, p3, p4);
return true;
}
template <typename P1, typename P2, typename P3, typename P4, typename P5>
bool Call(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) {
CALLJSPRE
m_pReturn = m_pObj->callJsFunc(func, p1, p2, p3, p4, p5);
return true;
}
template <typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>
bool Call(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) {
CALLJSPRE
m_pReturn = m_pObj->callJsFunc(func, p1, p2, p3, p4, p5, p6);
return true;
}
template <typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7>
bool Call(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7) {
CALLJSPRE
m_pReturn = m_pObj->callJsFunc(func, p1, p2, p3, p4, p5, p6, p7);
return true;
}
};
#endif
@@ -0,0 +1,97 @@
/**
@file JSCEnv.cpp
@brief
@author James
@version 1.0
@date 2018_8_23
*/
#include "JSCEnv.h"
#include "../../../CToObjectC.h"
#ifdef __APPLE__
#include <pthread.h>
#endif
namespace laya
{
pthread_key_t __TlsData::s_tls_curThread;
static JSValueRef gcCallback( JSContextRef ctx, JSObjectRef functionObject, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception )
{
JSGlobalContextRef pCtx = JSContextGetGlobalContext(ctx);
JSGarbageCollect( pCtx );
//JSSynchronousEdenCollectForDebugging(pCtx);
//JSSynchronousGarbageCollectForDebugging(pCtx);
return JSValueMakeUndefined(ctx);
}
void AlertOnJsException(bool b)
{
}
void Javascript::initJSEngine()
{
m_pGlobalContext = JSGlobalContextCreateInGroup(NULL, NULL);
m_pUndefined = JSValueMakeUndefined(m_pGlobalContext);
JSValueProtect(m_pGlobalContext, m_pUndefined);
__TlsData::GetInstance()->SetCurContext(m_pGlobalContext);
// expose gc()
JSStringRef pJSName = JSStringCreateWithUTF8CString("gc");
JSObjectRef pFunc = JSObjectMakeFunctionWithCallback(m_pGlobalContext, pJSName, gcCallback);
JSValueRef exception = 0;
JSObjectSetProperty(m_pGlobalContext, JSContextGetGlobalObject(m_pGlobalContext), pJSName, pFunc, kJSPropertyAttributeDontDelete, &exception);
if (0 != exception)
{
__JSRun::OutputException(exception);
}
JSStringRelease(pJSName);
}
void Javascript::uninitJSEngine()
{
__TlsData::GetInstance()->SetCurContext(NULL);
JSValueUnprotect(m_pGlobalContext, m_pUndefined);
JSGlobalContextRelease(m_pGlobalContext);
}
//------------------------------------------------------------------------------
JSCWorker::JSCWorker()
{
}
JSCWorker::~JSCWorker()
{
}
void JSCWorker::stop()
{
if (m_bStop)return;
m_bStop = true;
m_ThreadTasks.Stop();
m_bdbgThreadStarted = false;
}
void JSCWorker::_defRunLoop()
{
//设置tls
pthread_setspecific(s_tls_curThread, (void*)this);
//开始事件
JCEventEmitter::evtPtr startEvt(new JCEventBase);
startEvt->m_nID = JCWorkerThread::Event_threadStart;
emit(startEvt);
CToObjectCRunJSLoop();
//退出事件
JCEventEmitter::evtPtr stopEvt(new JCEventBase);
stopEvt->m_nID = JCWorkerThread::Event_threadStop;
emit(stopEvt);
}
void JSCWorker::_runLoop()
{
m_pJS->initJSEngine();
_defRunLoop();
m_pJS->uninitJSEngine();
}
};
//------------------------------------------------------------------------------
//-----------------------------END FILE--------------------------------
@@ -0,0 +1,301 @@
/**
@file JSCEnv.h
@brief
@author James
@version 1.0
@date 2018_8_23
*/
#ifndef __JSCEnv_H__
#define __JSCEnv_H__
#include <JavaScriptCore/JavaScriptCore.h>
#include "JSCProxyTLS.h"
#include <misc/JCWorkerThread.h>
namespace laya
{
void JSPrint( const char* p_sBuffer );
void JSAlert( const char* p_sBuffer );
void JSAlertExit( const char* p_sBuffer );
void evalJS( const char* p_sSource );
class Javascript
{
public:
typedef void(*voidfun)(void* data);
Javascript()
{
}
void init(int nPort)
{
}
void run(const char* sSource)
{
}
void run(const char* sSource, std::function<void(void)> preRunFunc)
{
}
void run(voidfun func, void* pdata)
{
}
void uninit()
{
}
void initJSEngine();
void uninitJSEngine();
public:
JSGlobalContextRef m_pGlobalContext;
JSValueRef m_pUndefined;
};
class JSThreadInterface
{
public:
JSThreadInterface()
{
}
virtual ~JSThreadInterface()
{
}
virtual void post(std::function<void(void)> func) = 0;
virtual void on(int nEvent, JCEventEmitter::EventHandler func, void* pInThread = 0) = 0;
virtual void start() = 0;
virtual void stop() = 0;
virtual void initialize(int nPort) = 0;
virtual void uninitialize() = 0;
virtual void setLoopFunc(std::function<bool(void)> func) = 0;
virtual void pushDbgFunc(std::function<void(void)> task) = 0;
virtual void runDbgFuncs() = 0;
virtual void waitAndRunDbgFuncs() = 0;
virtual bool hasDbgFuncs() = 0;
virtual JCWorkerThread* getWorker() = 0;
virtual void run(Javascript::voidfun func, void* pData) = 0;
virtual void clearFunc() = 0;
};
class JSCWorker : public JCWorkerThread
{
public:
JSCWorker();
~JSCWorker();
virtual void _defRunLoop();
virtual void _runLoop();
virtual void stop();
public:
Javascript* m_pJS;
};
class JSMulThread : public JSThreadInterface
{
public:
JSMulThread()
{
m_kWorker.setThreadName("JavaScript Main");
m_kWorker.m_pJS = &m_kJS;
}
~JSMulThread()
{
}
void post(std::function<void(void)> func)
{
if (m_kWorker.m_bStop)return;
CToObjectCPostFunc(func);
}
void on(int nEvent, JCEventEmitter::EventHandler func, void* pInThread = 0)
{
m_kWorker.on(nEvent, func, (JCWorkerThread*)pInThread);
}
void start()
{
m_kWorker.start();
}
void stop()
{
m_kWorker.stop();
}
void initialize(int nPort)
{
m_kJS.init(nPort);
}
void uninitialize()
{
m_kJS.uninit();
}
void setLoopFunc(std::function<bool(void)> func)
{
m_kWorker.setLoopFunc(func);
}
void pushDbgFunc(std::function<void(void)> task)
{
}
void runDbgFuncs()
{
}
void waitAndRunDbgFuncs()
{
}
bool hasDbgFuncs()
{
return false;
}
JCWorkerThread* getWorker()
{
return &m_kWorker;
}
void run(Javascript::voidfun func, void* pData)
{
m_kWorker.runQueue();
m_kWorker.m_funcLoop();
}
void clearFunc()
{
}
public:
Javascript m_kJS;
JSCWorker m_kWorker;
};
class JSSingleThread : public JSThreadInterface
{
public:
JSSingleThread()
{
}
~JSSingleThread()
{
}
void post(std::function<void(void)> func)
{
//if (m_kWorker.m_bStop)return;
//CToObjectCPostFunc(func);
m_kQueueLock.lock();
m_vFuncQueue.push_back(func);
m_kQueueLock.unlock();
}
void on(int nEvent, JCEventEmitter::EventHandler func, void* pInThread = 0)
{
switch (nEvent)
{
case JCWorkerThread::Event_threadStart:
m_kStartFunc.func = func;
m_kStartFunc.bDel = false;
break;
case JCWorkerThread::Event_threadStop:
m_kStopFunc.func = func;
m_kStopFunc.bDel = false;
break;
default:
LOGE("JSSingleThread on() event type error");
break;
}
}
void start()
{
m_kStartFunc.func(NULL);
}
void stop()
{
m_kStopFunc.func(NULL);
}
void initialize(int nPort)
{
clearFunc();
m_kJS.init(nPort);
m_kJS.initJSEngine();
}
void uninitialize()
{
clearFunc();
m_kJS.uninitJSEngine();
m_kJS.uninit();
}
void setLoopFunc(std::function<bool(void)> func)
{
m_kLoopFunc = func;
}
void pushDbgFunc(std::function<void(void)> task)
{
}
void runDbgFuncs()
{
}
void waitAndRunDbgFuncs()
{
}
bool hasDbgFuncs()
{
return false;
}
JCWorkerThread* getWorker()
{
return NULL;
}
void run(Javascript::voidfun func, void* pData)
{
runFunQueue();
m_kLoopFunc();
}
void clearFunc()
{
m_kQueueLock.lock();
m_vFuncQueue.clear();
m_kQueueLock.unlock();
}
public:
void runFunQueue()
{
std::vector<std::function<void(void)>> vWorkQueue;
m_kQueueLock.lock();
std::swap(vWorkQueue, m_vFuncQueue);
m_kQueueLock.unlock();
for (int i = 0; i < (int)vWorkQueue.size(); i++)
{
vWorkQueue[i]();
}
}
public:
Javascript m_kJS;
JCEventEmitter::EvtHandlerPack m_kStartFunc;
JCEventEmitter::EvtHandlerPack m_kStopFunc;
std::vector<std::function<void(void)>> m_vFuncQueue;
std::mutex m_kQueueLock;
std::function<bool(void)> m_kLoopFunc;
};
};
//------------------------------------------------------------------------------
#endif //__JSCEnv_H__
//-----------------------------END FILE--------------------------------
@@ -0,0 +1,73 @@
//
// JSCPropertyHandle.h
// conch
//
// Created by joychina on 15/6/27.
// Copyright (c) 2015年 LayaBox. All rights reserved.
//
#ifndef conch_JSCPropertyHandle_h
#define conch_JSCPropertyHandle_h
#include <JavaScriptCore/JavaScriptCore.h>
#include <JavaScriptCore/JavaScript.h>
#include <JavaScriptCore/JSObjectRef.h>
#include "JSCProxyTLS.h"
namespace laya
{
class JSCProxyArray
{
public:
JSValueRef pJSArray;
JSContextRef pContext;
JSValueRef pTmp;
public:
void initArrayByScript(const char* szScript)
{
__JSRun::Run(szScript,&pJSArray);
pContext = __TlsData::GetInstance()->GetCurContext();
}
int getLength()
{
JSStringRef pname = JSStringCreateWithUTF8CString("length");
JSValueRef exception = 0;
JSValueRef val = JSObjectGetProperty(pContext, (JSObjectRef)pJSArray, pname, &exception);
if( 0 != exception )
{
__JSRun::OutputException( exception );
}
double _len =JSValueToNumber(pContext, val, &exception);
if( 0 != exception )
{
__JSRun::OutputException( exception );
}
JSStringRelease(pname);
return (int)_len;
}
JSValueRef &operator [](int nIndex)
{
JSValueRef exception = 0;
pTmp = JSObjectGetPropertyAtIndex(pContext, (JSObjectRef)pJSArray, nIndex, &exception);
if( 0 != exception )
{
__JSRun::OutputException( exception );
}
return pTmp;
}
void setPropertyValue(unsigned int index,JSValueRef value){
JSValueRef exception = 0;
JSObjectSetPropertyAtIndex(pContext, (JSObjectRef)pJSArray, index, value, &exception);
if( 0 != exception )
{
__JSRun::OutputException( exception );
}
}
};
}
#endif
@@ -0,0 +1,615 @@
#ifndef _JSCProxyClass_h
#define _JSCProxyClass_h
#include <unordered_map>
#include "JSCProxyTransfer.h"
#include "JSCProxyFunction.h"
#include "JSCProxyType.h"
namespace laya
{
class JSCGlobal
{
public:
JSCGlobal(){}
~JSCGlobal(){
reset();
}
template <typename T>
void addProperty( const std::string& name, T value ){
assert( !name.empty());
JSContextRef pCtx = __TlsData::GetInstance()->GetCurContext();
JSStringRef pJSStrName = JSStringCreateWithUTF8CString( name.c_str() );
JSValueRef pVal = __TransferToJs<T>::ToJs( value );
JSObjectSetProperty( pCtx, JSContextGetGlobalObject( pCtx ), pJSStrName, pVal, kJSPropertyAttributeDontDelete|kJSPropertyAttributeReadOnly, nullptr );
JSStringRelease( pJSStrName );
}
template <typename T>
void addFunction( const std::string& name, T fun ){
assert( !name.empty() );
IJSCFunction* pJSCFunction = new JSCFunction<T>( fun );
JSContextRef pCtx = __TlsData::GetInstance()->GetCurContext();
JSStringRef pjsName = JSStringCreateWithUTF8CString( name.c_str() );
JSObjectRef pFunc = JSObjectMakeFunctionWithCallback(pCtx, pjsName, JSObjectCallAsFunctionCallback);
JSObjectSetProperty(pCtx, JSContextGetGlobalObject(pCtx), pjsName, pFunc, kJSPropertyAttributeDontDelete|kJSPropertyAttributeReadOnly, nullptr);
JSStringRelease( pjsName );
FunctionMapRes rs = m_FunctionMap.insert(FunctionMapValue((unsigned long)pFunc, pJSCFunction));
assert( rs.second );
}
IJSCFunction* getFunction(unsigned long func){
FunctionMapItr itrFun = m_FunctionMap.find( func );
if ( itrFun != m_FunctionMap.end() ){
return itrFun->second;
}
else {
return nullptr;
}
}
static JSValueRef JSObjectCallAsFunctionCallback(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
IJSCFunction* pJSCFunction = JSCGlobal::getInstance()->getFunction( (unsigned long)function );
if ( pJSCFunction == nullptr ){
__JsThrow::Throw(exception,"JSCGlobal::JSObjectCallAsFunctionCallback can't find function");
return nullptr;
}
return pJSCFunction->call(ctx, function, thisObject, argumentCount, arguments, exception);
}
static JSCGlobal* getInstance(){
static JSCGlobal instance;
return &instance;
}
void reset(){
FunctionMapItr iter = m_FunctionMap.begin();
for (; iter != m_FunctionMap.end(); iter++){
delete iter->second;
}
m_FunctionMap.clear();
}
private:
typedef std::unordered_map<unsigned long,IJSCFunction*> FunctionMap;
typedef FunctionMap::value_type FunctionMapValue;
typedef FunctionMap::iterator FunctionMapItr;
typedef std::pair<FunctionMapItr,bool> FunctionMapRes;
FunctionMap m_FunctionMap;
};
template<typename T>
class JSCClass
{
public:
inline unsigned int __hash_BKDR(const char *p_str){
if( 0 == p_str )
return 0;
unsigned int seed = 131; // 31 131 1313 13131 131313 etc..
unsigned int hash = 0;
for(;0!=*p_str;){
hash = hash * seed + (*p_str++);
}
return (hash & 0x7FFFFFFF);
}
class FuncEntry
{
enum
{
Max_Arg_Size = 12,
Invalid_size = -1,
};
IJSCCallback *m_funcs[Max_Arg_Size+1];
int m_iMaxArgSize;
public:
FuncEntry(){
m_iMaxArgSize = Invalid_size;
memset( m_funcs, 0, sizeof(m_funcs) );
}
~FuncEntry(){
reset();
}
void reset(){
for(int i=0;i<=Max_Arg_Size;++i){
if( 0 != m_funcs[i] ){
delete m_funcs[i];
m_funcs[i] = 0;
}
}
}
void add( IJSCCallback *p_fn ){
assert(p_fn != nullptr && p_fn->getNumArgs() <= Max_Arg_Size && m_funcs[p_fn->getNumArgs()] == nullptr );
if( m_iMaxArgSize < p_fn->getNumArgs() )
m_iMaxArgSize = p_fn->getNumArgs();
m_funcs[p_fn->getNumArgs()] = p_fn;
}
IJSCCallback *get( int p_iArgNum ){
if( Invalid_size == m_iMaxArgSize ){
return 0;
}
if( p_iArgNum > m_iMaxArgSize )
p_iArgNum = m_iMaxArgSize;
for(;p_iArgNum>=0;p_iArgNum--){
if( 0 != m_funcs[p_iArgNum] )
return m_funcs[p_iArgNum];
}
return 0;
}
};
enum
{
CallbackType_Property,
CallbackType_Function,
};
struct CallbackDefine
{
int m_iType;
std::string m_name;
IJSCCallback* m_pSetter;
IJSCCallback* m_pGetter;
FuncEntry m_Method;
JSValueRef m_pCallAsFunction;
CallbackDefine(const std::string& name, IJSCCallback* setter, IJSCCallback* getter)
:m_name(name), m_iType(CallbackType_Property), m_pSetter(setter), m_pGetter(getter),m_pCallAsFunction(nullptr){
}
CallbackDefine(const std::string& name,IJSCCallback* method)
:m_name(name), m_iType(CallbackType_Function), m_pSetter(nullptr), m_pGetter(nullptr),m_pCallAsFunction(nullptr){
m_Method.add(method);
}
void addMethod( IJSCCallback *p_pfn ){
m_Method.add(p_pfn);
}
IJSCCallback *getMethod( size_t p_iArgNum ){
return m_Method.get( (int)p_iArgNum );
}
~CallbackDefine(){
if (m_pGetter){
delete m_pGetter;
m_pGetter = nullptr;
}
if (m_pSetter){
delete m_pSetter;
m_pSetter = nullptr;
}
m_Method.reset();
JSContextRef ctx = __TlsData::GetInstance()->GetCurContext();
if (ctx != nullptr && m_pCallAsFunction != nullptr){
JSValueUnprotect(ctx, m_pCallAsFunction);
}
}
};
struct FixedProperty
{
private:
JSValueRef m_pszName;
JSValueRef m_pValue;
public:
template <typename _Tp>
explicit FixedProperty( const char *p_pszName, _Tp p_Val )
{
JSContextRef pCtx = __TlsData::GetInstance()->GetCurContext();
JSStringRef pszName = JSStringCreateWithUTF8CString(p_pszName);
m_pszName = JSValueMakeString(pCtx, pszName);
JSStringRelease(pszName);
m_pValue = __TransferToJs<_Tp>::ToJs(p_Val);
JSValueProtect( pCtx, m_pszName );
JSValueProtect( pCtx, m_pValue );
}
~FixedProperty()
{
JSContextRef pCtx = __TlsData::GetInstance()->GetCurContext();
if( 0 != pCtx )
{
if( 0 != m_pszName )
{
JSValueUnprotect( pCtx, m_pszName );
}
if( 0 != m_pValue )
{
JSValueUnprotect( pCtx, m_pValue );
}
}
}
JSStringRef GetName()
{
return JSValueToStringCopy(__TlsData::GetInstance()->GetCurContext(), m_pszName, 0);
}
JSValueRef GetValue()
{
return m_pValue;
}
};
typedef std::vector<FixedProperty *> FixedProperties;
typedef typename FixedProperties::iterator FixedPropertiesIter;
FixedProperties m_FixedProperties;
JSCClass(){
m_bIsGlobal = false;
m_ClassDefine = kJSClassDefinitionEmpty;
m_ClassObject = nullptr;
m_iTypeID = __hash_BKDR(typeid(T).name());
}
~JSCClass(){
_reset();
}
unsigned int getTypeID(){
return m_iTypeID;
}
static JSCClass* getInstance(){
static JSCClass<T> instance;
return &instance;
}
template <typename P>
void addFixedProperty(const std::string& name,const P& val){
assert(!name.empty());
m_FixedProperties.push_back(new FixedProperty(name.c_str(),val));
}
template <typename G,typename S>
void addProperty( const std::string& name, G getter, S setter){
assert( !name.empty() );
IJSCCallback* pGetter = new JSCCallback<G>(getter);
IJSCCallback* pSetter = nullptr;
if (setter != nullptr){
pSetter = new JSCCallback<S>(setter);
}
PropertyMapRes rs = m_PropertyMap.insert(PropertyMapValue(name,new CallbackDefine(name,pSetter,pGetter)));
assert(rs.second && "JSCClass::addProperty name is dumplicate value");
}
void addConstructor( IJSCCallback* constructor ){
m_Constructor.add(constructor);
}
template<typename M>
void addMethod( const std::string& name, M method ){
PropertyMapItr iter = m_PropertyMap.find(name);
if ( iter != m_PropertyMap.end() ){
assert( iter->second->m_iType == CallbackType_Function );
iter->second->addMethod(new JSCCallback<M>(method));
return;
}
CallbackDefine* pProperty = new CallbackDefine(name,new JSCCallback<M>(method));
JSStringRef pName = JSStringCreateWithUTF8CString(name.c_str());
JSContextRef pCtx = __TlsData::GetInstance()->GetCurContext();
pProperty->m_pCallAsFunction = JSObjectMakeFunctionWithCallback(pCtx, pName, JSCClass<T>::callAsFunctionCallback);
JSStringRelease(pName);
JSValueProtect(pCtx, pProperty->m_pCallAsFunction);
PropertyMapRes rsp = m_PropertyMap.insert(PropertyMapValue(name,pProperty));
assert(rsp.second);
FunctionMapRes rsf = m_FunctionMap.insert(FunctionMapValue((unsigned long)pProperty->m_pCallAsFunction,pProperty));
assert(rsf.second);
}
void finish( const std::string& name ){
m_bIsGlobal = false;
finishImpl( name, nullptr);
}
void finishToGlobal( const std::string& name, T* pIns){
assert(pIns != nullptr);
m_bIsGlobal = false;
finishImpl( name, pIns);
m_bIsGlobal = true;
}
JSObjectRef transferObjPtrToJS( T *p_pIns ){
assert( !m_bIsGlobal );
JSContextRef pCtx = __TlsData::GetInstance()->GetCurContext();
JSObjectRef pRet = JSObjectMake( pCtx, m_ClassObject, p_pIns );
p_pIns->mpJsThis = pRet;
JSValueRef pProperty = JSValueMakeNumber(pCtx, (double)getTypeID());
JSStringRef pszName = JSStringCreateWithUTF8CString(__Js_class_typeid_property);
JSObjectSetProperty(pCtx, pRet, pszName, pProperty, kJSPropertyAttributeReadOnly|kJSPropertyAttributeDontDelete, 0);
JSStringRelease(pszName);
if( m_FixedProperties.size() ){
FixedPropertiesIter iter;
for(iter=m_FixedProperties.begin();iter!=m_FixedProperties.end();iter++){
JSStringRef sName = (*iter)->GetName();
JSObjectSetProperty(pCtx, pRet, sName, (*iter)->GetValue(), kJSPropertyAttributeReadOnly/*|kJSPropertyAttributeDontDelete*/, 0);
//kJSPropertyAttributeDontDelete 就意味着这个值不能改了 fuck
JSStringRelease(sName);
}
}
return pRet;
}
static void reset(){
JSCClass<T>::getInstance()->_reset();
}
private:
static JSObjectRef newWrap(JSContextRef ctx, JSObjectRef constructor, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
if( JSCClass<T>::getInstance()->m_bIsGlobal ){
__JsThrow::Throw(exception,"can't new a global object");
return NULL;
}
IJSCCallback *pfn = JSCClass<T>::getInstance()->m_Constructor.get( (int)argumentCount );
if( 0 == pfn ){
return JSCClass<T>::getInstance()->transferObjPtrToJS(new T);
}
else{
return pfn->constructor(ctx, constructor, argumentCount, arguments, exception);
}
}
static void destroyWrap(JSObjectRef object){
T *p = (T *)JSObjectGetPrivate(object);
delete p;
}
static bool isInstanceOf(JSContextRef ctx, JSObjectRef constructor, JSValueRef possibleInstance, JSValueRef* exception){
if( !JSValueIsObject(ctx, possibleInstance) ){
return false;
}
bool bRet = __CheckClassType::IsTypeOf<T>((JSObjectRef)possibleInstance);
return bRet;
}
static bool hasProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName){
std::string strPropertyName = __TransferToCpp<char *>::ToCpp(propertyName);
resetJsStrBuf();
if( !strPropertyName.length() ){
return false;
}
return (0 != JSCClass<T>::getInstance()->findProperty(strPropertyName.c_str()));
}
static JSValueRef getProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception){
T *pThis = (T *)JSObjectGetPrivate( object );
if( 0 == pThis ){
__JsThrow::Throw(exception,"not a global object");
return NULL;
}
std::string strPropertyName = __TransferToCpp<char *>::ToCpp(propertyName);
resetJsStrBuf();
if( !strPropertyName.length() ){
__JsThrow::Throw(exception,"GetProperty PropertyName is null");
return NULL;
}
CallbackDefine *pProperty = JSCClass<T>::getInstance()->findProperty(strPropertyName.c_str());
if( 0 == pProperty ){
__JsThrow::Throw(exception,"GetProperty can't find property");
return NULL;
}
JSValueRef pRet = NULL;
if( CallbackType_Property == pProperty->m_iType ){
// is property
pRet = pProperty->m_pGetter->call(ctx, nullptr, object, 0, nullptr, nullptr);//?????????????????????
}
else
{ // is function
pRet = pProperty->m_pCallAsFunction;
}
return pRet;
}
static bool setProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef value, JSValueRef* exception){
T *pThis = (T *)JSObjectGetPrivate( object );
if( 0 == pThis ){
__JsThrow::Throw(exception,"not a global object");
return false;
}
std::string sPropertyName = __TransferToCpp<char *>::ToCpp(propertyName);
resetJsStrBuf();
if( sPropertyName.empty() ){
__JsThrow::Throw(exception,"SetProperty PropertyName is null");
return false;
}
CallbackDefine *pProperty = JSCClass<T>::getInstance()->findProperty(sPropertyName);
if( 0 == pProperty ){
return false;
}
if( CallbackType_Property != pProperty->m_iType )
{
if( pProperty->m_iType == CallbackType_Function ){
JSObjectRef _obj = JSValueToObject(ctx, value, 0);
if( JSObjectIsFunction(ctx,_obj) ){
getInstance()->JSDefineFunction[sPropertyName] = _obj;
return true;
}
}
__JsThrow::Throw(exception,"SetProperty property is function object");
return false;
}
if( 0 == pProperty->m_pSetter ){
__JsThrow::Throw(exception,"SetProperty property is read only");
return false;
}
JSValueRef arguments[1];
arguments[0] = value;
pProperty->m_pSetter->call(ctx, nullptr, object, 1, arguments, nullptr);
return true;
}
static JSValueRef callAsFunctionCallback(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
T *pThis = (T *)JSObjectGetPrivate( thisObject );
if( nullptr == pThis ){
__JsThrow::Throw(exception,"CallAsFunctionCallback this is null");
return JSValueMakeUndefined(ctx);
}
CallbackDefine *pProperty = JSCClass<T>::getInstance()->findFunction((unsigned long)function);
if( pProperty != NULL ){
JSDefineFunctionIter it = getInstance()->JSDefineFunction.find(pProperty->m_name);
if( it != getInstance()->JSDefineFunction.end() ){
return JSObjectCallAsFunction(ctx,it->second,thisObject,argumentCount,arguments,0);
}
}
if( nullptr == pProperty ){
__JsThrow::Throw(exception,"CallAsFunctionCallback can't find function");
return JSValueMakeUndefined(ctx);
}
IJSCCallback *pMethod = pProperty->getMethod(argumentCount);
if( 0 != pMethod ){
//__JsThrow::GetInstance()->UpdateException(exception);
return pMethod->call(ctx, function, thisObject, argumentCount, arguments, exception);
}
else
{
__JsThrow::Throw(exception,"callAsFunctionCallback can't find function");
return JSValueMakeUndefined(ctx);
}
}
private:
void _reset(){
if( m_FixedProperties.size() ){
FixedPropertiesIter iter;
for(iter=m_FixedProperties.begin();iter!=m_FixedProperties.end();iter++){
delete *iter;
}
m_FixedProperties.clear();
}
for (PropertyMapItr itr = m_PropertyMap.begin(); itr != m_PropertyMap.end(); itr++ ){
delete itr->second;
}
m_PropertyMap.clear();
m_FunctionMap.clear();
m_bIsGlobal = false;
m_ClassDefine = kJSClassDefinitionEmpty;
if ( m_ClassObject != nullptr ){
JSClassRelease(m_ClassObject);
m_ClassObject = nullptr;
}
JSDefineFunction.clear();
m_Constructor.reset();
}
void finishImpl( const std::string& name, T *p_pIns ){
assert(!name.empty());
m_ClassDefine = kJSClassDefinitionEmpty;
m_ClassDefine.attributes = kJSClassAttributeNone;
m_ClassDefine.className = name.c_str();
m_ClassDefine.callAsConstructor = JSCClass<T>::newWrap;
m_ClassDefine.finalize = JSCClass<T>::destroyWrap;
m_ClassDefine.hasProperty = JSCClass<T>::hasProperty;
m_ClassDefine.hasInstance = JSCClass<T>::isInstanceOf;
m_ClassDefine.getProperty = JSCClass<T>::getProperty;
m_ClassDefine.setProperty = JSCClass<T>::setProperty;
m_ClassDefine.callAsFunction = JSCClass<T>::callAsFunctionCallback;
m_ClassObject = JSClassCreate(&m_ClassDefine);
JSContextRef pCtx = __TlsData::GetInstance()->GetCurContext();
JSStringRef jsName = JSStringCreateWithUTF8CString(name.c_str());
JSObjectRef myObject;
if( 0 != p_pIns ){
myObject = transferObjPtrToJS( p_pIns );
p_pIns->mpJsThis = myObject;
}
else
{
myObject = JSObjectMake(pCtx, m_ClassObject, 0);
}
JSObjectSetProperty( pCtx, JSContextGetGlobalObject(pCtx), jsName, myObject, kJSPropertyAttributeNone, NULL );//???
JSStringRelease(jsName);
}
CallbackDefine *findFunction( unsigned long p_ulObj ){
FunctionMapItr iter = m_FunctionMap.find(p_ulObj);
if( iter == m_FunctionMap.end() ){
return nullptr;
}
else
{
return (*iter).second;
}
}
CallbackDefine *findProperty( const std::string& name ){
PropertyMapItr iter = m_PropertyMap.find(name);
if( iter == m_PropertyMap.end() ){
return nullptr;
}
else
{
return (*iter).second;
}
}
private:
typedef std::unordered_map<std::string,CallbackDefine*> PropertyMap;
typedef typename PropertyMap::value_type PropertyMapValue;
typedef typename PropertyMap::iterator PropertyMapItr;
typedef std::pair<PropertyMapItr,bool> PropertyMapRes;
PropertyMap m_PropertyMap;
typedef std::unordered_map<unsigned long,CallbackDefine*> FunctionMap;
typedef typename FunctionMap::value_type FunctionMapValue;
typedef typename FunctionMap::iterator FunctionMapItr;
typedef std::pair<FunctionMapItr,bool> FunctionMapRes;
FunctionMap m_FunctionMap;
bool m_bIsGlobal;
JSClassDefinition m_ClassDefine;
JSClassRef m_ClassObject;
typedef std::unordered_map<std::string,JSObjectRef>::iterator JSDefineFunctionIter;
std::unordered_map<std::string, JSObjectRef> JSDefineFunction;
unsigned int m_iTypeID;
FuncEntry m_Constructor;
};
}
#endif
@@ -0,0 +1,826 @@
#ifndef _JSCProxyFunction_h
#define _JSCProxyFunction_h
namespace laya
{
template<class T>
JSValueRef ToJSValue(T t) {
return __TransferToJs<T>::ToJs(t);
}
inline bool checkJSToCArgs(size_t given, size_t expect) {
assert(given >= expect);
if (given >= expect)
return true;
static char buff[512];
sprintf(buff, "console.log('arguments number err: %d:%d');var e = new Error();console.log(e.stack);", expect, given);
//__JSRun::Run(buff);
return false;
}
#define JS2CCALL_GET_COBJ \
Cls* pThis = (Cls*)JSObjectGetPrivate( thisObject );
#define JS2CCALL_GET_PARAMS1 \
if(!checkJSToCArgs(argumentCount,1))return JSValueMakeUndefined(ctx);\
P1 p1 = __TransferToCpp<P1>::ToCpp(arguments[0]);
#define JS2CCALL_GET_PARAMS2 \
if(!checkJSToCArgs(argumentCount,2))return JSValueMakeUndefined(ctx);\
P1 p1 = __TransferToCpp<P1>::ToCpp(arguments[0]);\
P2 p2 = __TransferToCpp<P2>::ToCpp(arguments[1]);
#define JS2CCALL_GET_PARAMS3 \
if(!checkJSToCArgs(argumentCount,3))return JSValueMakeUndefined(ctx);\
P1 p1 = __TransferToCpp<P1>::ToCpp(arguments[0]);\
P2 p2 = __TransferToCpp<P2>::ToCpp(arguments[1]);\
P3 p3 = __TransferToCpp<P3>::ToCpp(arguments[2]);
#define JS2CCALL_GET_PARAMS4 \
if(!checkJSToCArgs(argumentCount,4))return JSValueMakeUndefined(ctx);\
P1 p1 = __TransferToCpp<P1>::ToCpp(arguments[0]);\
P2 p2 = __TransferToCpp<P2>::ToCpp(arguments[1]);\
P3 p3 = __TransferToCpp<P3>::ToCpp(arguments[2]);\
P4 p4 = __TransferToCpp<P4>::ToCpp(arguments[3]);
#define JS2CCALL_GET_PARAMS5 \
if(!checkJSToCArgs(argumentCount,5))return JSValueMakeUndefined(ctx);\
P1 p1 = __TransferToCpp<P1>::ToCpp(arguments[0]);\
P2 p2 = __TransferToCpp<P2>::ToCpp(arguments[1]);\
P3 p3 = __TransferToCpp<P3>::ToCpp(arguments[2]);\
P4 p4 = __TransferToCpp<P4>::ToCpp(arguments[3]);\
P5 p5 = __TransferToCpp<P5>::ToCpp(arguments[4]);
#define JS2CCALL_GET_PARAMS6 \
if(!checkJSToCArgs(argumentCount,6))return JSValueMakeUndefined(ctx);\
P1 p1 = __TransferToCpp<P1>::ToCpp(arguments[0]);\
P2 p2 = __TransferToCpp<P2>::ToCpp(arguments[1]);\
P3 p3 = __TransferToCpp<P3>::ToCpp(arguments[2]);\
P4 p4 = __TransferToCpp<P4>::ToCpp(arguments[3]);\
P5 p5 = __TransferToCpp<P5>::ToCpp(arguments[4]);\
P6 p6 = __TransferToCpp<P6>::ToCpp(arguments[5]);
#define JS2CCALL_GET_PARAMS7 \
if(!checkJSToCArgs(argumentCount,7))return JSValueMakeUndefined(ctx);\
P1 p1 = __TransferToCpp<P1>::ToCpp(arguments[0]);\
P2 p2 = __TransferToCpp<P2>::ToCpp(arguments[1]);\
P3 p3 = __TransferToCpp<P3>::ToCpp(arguments[2]);\
P4 p4 = __TransferToCpp<P4>::ToCpp(arguments[3]);\
P5 p5 = __TransferToCpp<P5>::ToCpp(arguments[4]);\
P6 p6 = __TransferToCpp<P6>::ToCpp(arguments[5]);\
P7 p7 = __TransferToCpp<P7>::ToCpp(arguments[6]);
#define JS2CCALL_GET_PARAMS8 \
if(!checkJSToCArgs(argumentCount,8))return JSValueMakeUndefined(ctx);\
P1 p1 = __TransferToCpp<P1>::ToCpp(arguments[0]);\
P2 p2 = __TransferToCpp<P2>::ToCpp(arguments[1]);\
P3 p3 = __TransferToCpp<P3>::ToCpp(arguments[2]);\
P4 p4 = __TransferToCpp<P4>::ToCpp(arguments[3]);\
P5 p5 = __TransferToCpp<P5>::ToCpp(arguments[4]);\
P6 p6 = __TransferToCpp<P6>::ToCpp(arguments[5]);\
P7 p7 = __TransferToCpp<P7>::ToCpp(arguments[6]);\
P8 p8 = __TransferToCpp<P8>::ToCpp(arguments[7]);
#define JS2CCALL_GET_PARAMS9 \
if(!checkJSToCArgs(argumentCount,9))return JSValueMakeUndefined(ctx);\
P1 p1 = __TransferToCpp<P1>::ToCpp(arguments[0]);\
P2 p2 = __TransferToCpp<P2>::ToCpp(arguments[1]);\
P3 p3 = __TransferToCpp<P3>::ToCpp(arguments[2]);\
P4 p4 = __TransferToCpp<P4>::ToCpp(arguments[3]);\
P5 p5 = __TransferToCpp<P5>::ToCpp(arguments[4]);\
P6 p6 = __TransferToCpp<P6>::ToCpp(arguments[5]);\
P7 p7 = __TransferToCpp<P7>::ToCpp(arguments[6]);\
P8 p8 = __TransferToCpp<P8>::ToCpp(arguments[7]);\
P9 p9 = __TransferToCpp<P9>::ToCpp(arguments[8]);
#define JS2CCALL_GET_PARAMS11 \
if(!checkJSToCArgs(argumentCount,11))return JSValueMakeUndefined(ctx);\
P1 p1 = __TransferToCpp<P1>::ToCpp(arguments[0]);\
P2 p2 = __TransferToCpp<P2>::ToCpp(arguments[1]);\
P3 p3 = __TransferToCpp<P3>::ToCpp(arguments[2]);\
P4 p4 = __TransferToCpp<P4>::ToCpp(arguments[3]);\
P5 p5 = __TransferToCpp<P5>::ToCpp(arguments[4]);\
P6 p6 = __TransferToCpp<P6>::ToCpp(arguments[5]);\
P7 p7 = __TransferToCpp<P7>::ToCpp(arguments[6]);\
P8 p8 = __TransferToCpp<P8>::ToCpp(arguments[7]);\
P9 p9 = __TransferToCpp<P9>::ToCpp(arguments[8]);\
P10 p10 = __TransferToCpp<P10>::ToCpp(arguments[9]);\
P11 p11 = __TransferToCpp<P11>::ToCpp(arguments[10]);
#define JS2CCALL_GET_PARAMS12 \
if(!checkJSToCArgs(argumentCount,12))return JSValueMakeUndefined(ctx);\
P1 p1 = __TransferToCpp<P1>::ToCpp(arguments[0]);\
P2 p2 = __TransferToCpp<P2>::ToCpp(arguments[1]);\
P3 p3 = __TransferToCpp<P3>::ToCpp(arguments[2]);\
P4 p4 = __TransferToCpp<P4>::ToCpp(arguments[3]);\
P5 p5 = __TransferToCpp<P5>::ToCpp(arguments[4]);\
P6 p6 = __TransferToCpp<P6>::ToCpp(arguments[5]);\
P7 p7 = __TransferToCpp<P7>::ToCpp(arguments[6]);\
P8 p8 = __TransferToCpp<P8>::ToCpp(arguments[7]);\
P9 p9 = __TransferToCpp<P9>::ToCpp(arguments[8]);\
P10 p10 = __TransferToCpp<P10>::ToCpp(arguments[9]);\
P11 p11 = __TransferToCpp<P11>::ToCpp(arguments[10]);\
P11 p12 = __TransferToCpp<P11>::ToCpp(arguments[11]);
struct IJSCCallback
{
virtual ~IJSCCallback(){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){assert(false);return nullptr;}
virtual JSObjectRef constructor(JSContextRef ctx, JSObjectRef constructor, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){assert(false);return nullptr;}
virtual uint16_t getNumArgs() = 0;
};
template<typename T>
struct JSCCallback: public IJSCCallback {
JSCCallback(T func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
assert(false && "JSCCallback::call not implemented");
return nullptr;
}
virtual uint16_t getNumArgs() { return 0; }
};
template<typename R, typename Cls>
struct JSCCallback<R(Cls::*)(void)> :public IJSCCallback{
typedef R(Cls::*F)(void);
JSCCallback(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_COBJ;
JSValueRef ret = ToJSValue<R>((pThis->*m_func)());
resetJsStrBuf();
return ret;
}
virtual uint16_t getNumArgs() { return 0; }
F m_func;
};
template<typename R, typename Cls, typename P1>
struct JSCCallback<R(Cls::*)(P1)>: public IJSCCallback {
typedef R(Cls::*F)(P1);
JSCCallback(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_COBJ;
JS2CCALL_GET_PARAMS1;
JSValueRef ret = ToJSValue<R>((pThis->*m_func)(p1));
resetJsStrBuf();
return ret;
}
virtual uint16_t getNumArgs() { return 1; }
F m_func;
};
template<typename R, typename Cls, typename P1, typename P2>//2
struct JSCCallback<R(Cls::*)(P1, P2)>:public IJSCCallback {
typedef R(Cls::*F)(P1, P2);
JSCCallback(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_COBJ;
JS2CCALL_GET_PARAMS2;
JSValueRef ret = ToJSValue<R>((pThis->*m_func)(p1,p2));
resetJsStrBuf();
return ret;
}
virtual uint16_t getNumArgs() { return 2; }
F m_func;
};
template<typename R, typename Cls, typename P1, typename P2, typename P3>//3
struct JSCCallback<R(Cls::*)(P1, P2, P3)>:public IJSCCallback {
typedef R(Cls::*F)(P1, P2, P3);
JSCCallback(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_COBJ;
JS2CCALL_GET_PARAMS3;
JSValueRef ret = ToJSValue<R>((pThis->*m_func)(p1, p2,p3));
resetJsStrBuf();
return ret;
}
virtual uint16_t getNumArgs() { return 3; }
F m_func;
};
template<typename R, typename Cls, typename P1, typename P2, typename P3, typename P4>//4
struct JSCCallback<R(Cls::*)(P1, P2, P3, P4)>:public IJSCCallback {
typedef R(Cls::*F)(P1, P2, P3, P4);
JSCCallback(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_COBJ;
JS2CCALL_GET_PARAMS4;
JSValueRef ret = ToJSValue<R>((pThis->*m_func)(p1, p2, p3, p4));
resetJsStrBuf();
return ret;
}
virtual uint16_t getNumArgs() { return 4; }
F m_func;
};
template<typename R, typename Cls, typename P1, typename P2, typename P3, typename P4, typename P5>//5
struct JSCCallback<R(Cls::*)(P1, P2, P3, P4, P5)>:public IJSCCallback {
typedef R(Cls::*F)(P1, P2, P3, P4, P5);
JSCCallback(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_COBJ;
JS2CCALL_GET_PARAMS5;
JSValueRef ret = ToJSValue<R>((pThis->*m_func)(p1, p2, p3, p4,p5));
resetJsStrBuf();
return ret;
}
virtual uint16_t getNumArgs() { return 5; }
F m_func;
};
template<typename R, typename Cls, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>//6
struct JSCCallback<R(Cls::*)(P1, P2, P3, P4, P5, P6)>:public IJSCCallback {
typedef R(Cls::*F)(P1, P2, P3, P4, P5, P6);
JSCCallback(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_COBJ;
JS2CCALL_GET_PARAMS6;
JSValueRef ret = ToJSValue<R>((pThis->*m_func)(p1, p2, p3, p4, p5,p6));
resetJsStrBuf();
return ret;
}
virtual uint16_t getNumArgs() { return 6; }
F m_func;
};
template<typename R, typename Cls, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7>//7
struct JSCCallback<R(Cls::*)(P1, P2, P3, P4, P5, P6, P7)>:public IJSCCallback {
typedef R(Cls::*F)(P1, P2, P3, P4, P5, P6, P7);
JSCCallback(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_COBJ;
JS2CCALL_GET_PARAMS7;
JSValueRef ret = ToJSValue<R>((pThis->*m_func)(p1, p2, p3, p4, p5,p7));
resetJsStrBuf();
return ret;
}
virtual uint16_t getNumArgs() { return 7; }
F m_func;
};
template<typename R, typename Cls, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9, typename P10, typename P11, typename P12>//12
struct JSCCallback<R(Cls::*)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12)>:public IJSCCallback {
typedef R(Cls::*F)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12);
JSCCallback(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_COBJ;
JS2CCALL_GET_PARAMS12;
JSValueRef ret = ToJSValue<R>((pThis->*m_func)(p1, p2, p3, p4, p5, p7, p8, p9, p10, p11, p12));
resetJsStrBuf();
return ret;
}
virtual uint16_t getNumArgs() { return 12; }
F m_func;
};
template<typename Cls>
struct JSCCallback<void(Cls::*)(void)>:public IJSCCallback {
typedef void(Cls::*F)(void);
JSCCallback(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_COBJ;
(pThis->*m_func)();
resetJsStrBuf();
return JSValueMakeUndefined(ctx);
}
virtual uint16_t getNumArgs() { return 0; }
F m_func;
};
template< typename P1, typename Cls>//1
struct JSCCallback<void(Cls::*)(P1)> :public IJSCCallback{
typedef void(Cls::*F)(P1);
JSCCallback(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_COBJ;
JS2CCALL_GET_PARAMS1;
(pThis->*m_func)(p1);
resetJsStrBuf();
return JSValueMakeUndefined(ctx);
}
virtual uint16_t getNumArgs() { return 1; }
F m_func;
};
template<typename Cls, typename P1, typename P2>//2
struct JSCCallback<void(Cls::*)(P1, P2)>:public IJSCCallback {
typedef void(Cls::*F)(P1, P2);
JSCCallback(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_COBJ;
JS2CCALL_GET_PARAMS2;
(pThis->*m_func)(p1,p2);
resetJsStrBuf();
return JSValueMakeUndefined(ctx);
}
virtual uint16_t getNumArgs() { return 2; }
F m_func;
};
template<typename Cls, typename P1, typename P2, typename P3>//3
struct JSCCallback<void(Cls::*)(P1, P2, P3)>:public IJSCCallback {
typedef void(Cls::*F)(P1, P2, P3);
JSCCallback(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_COBJ;
JS2CCALL_GET_PARAMS3;
(pThis->*m_func)(p1,p2,p3);
resetJsStrBuf();
return JSValueMakeUndefined(ctx);
}
virtual uint16_t getNumArgs() { return 3; }
F m_func;
};
template< typename Cls, typename P1, typename P2, typename P3, typename P4>//4
struct JSCCallback<void(Cls::*)(P1, P2, P3, P4)>:public IJSCCallback {
typedef void(Cls::*F)(P1, P2, P3, P4);
JSCCallback(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_COBJ;
JS2CCALL_GET_PARAMS4;
(pThis->*m_func)(p1, p2, p3, p4);
resetJsStrBuf();
return JSValueMakeUndefined(ctx);
}
virtual uint16_t getNumArgs() { return 4; }
F m_func;
};
template< typename Cls, typename P1, typename P2, typename P3, typename P4, typename P5>//5
struct JSCCallback<void(Cls::*)(P1, P2, P3, P4, P5)>:public IJSCCallback {
typedef void(Cls::*F)(P1, P2, P3, P4, P5);
JSCCallback(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_COBJ;
JS2CCALL_GET_PARAMS5;
(pThis->*m_func)(p1, p2, p3, p4, p5);
resetJsStrBuf();
return JSValueMakeUndefined(ctx);
}
virtual uint16_t getNumArgs() { return 5; }
F m_func;
};
template< typename Cls, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>//6
struct JSCCallback<void(Cls::*)(P1, P2, P3, P4, P5, P6)>:public IJSCCallback {
typedef void(Cls::*F)(P1, P2, P3, P4, P5, P6);
JSCCallback(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_COBJ;
JS2CCALL_GET_PARAMS6;
(pThis->*m_func)(p1, p2, p3, p4, p5, p6);
resetJsStrBuf();
return JSValueMakeUndefined(ctx);
}
virtual uint16_t getNumArgs() { return 6; }
F m_func;
};
template< typename Cls, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7>//7
struct JSCCallback<void(Cls::*)(P1, P2, P3, P4, P5, P6, P7)>:public IJSCCallback {
typedef void(Cls::*F)(P1, P2, P3, P4, P5, P6, P7);
JSCCallback(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_COBJ;
JS2CCALL_GET_PARAMS7;
(pThis->*m_func)(p1, p2, p3, p4, p5, p6, p7);
resetJsStrBuf();
return JSValueMakeUndefined(ctx);
}
virtual uint16_t getNumArgs() { return 7; }
F m_func;
};
template< typename Cls, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9>//9
struct JSCCallback<void(Cls::*)(P1, P2, P3, P4, P5, P6, P7, P8, P9)>:public IJSCCallback {
typedef void(Cls::*F)(P1, P2, P3, P4, P5, P6, P7, P8, P9);
JSCCallback(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_COBJ;
JS2CCALL_GET_PARAMS9;
(pThis->*m_func)(p1, p2, p3, p4, p5, p6, p7, p8, p9);
resetJsStrBuf();
return JSValueMakeUndefined(ctx);
}
virtual uint16_t getNumArgs() { return 9; }
F m_func;
};
template< typename Cls, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9, typename P10, typename P11>//11
struct JSCCallback<void(Cls::*)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11)>:public IJSCCallback {
typedef void(Cls::*F)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11);
JSCCallback(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_COBJ;
JS2CCALL_GET_PARAMS11;
(pThis->*m_func)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11);
resetJsStrBuf();
return JSValueMakeUndefined(ctx);
}
virtual uint16_t getNumArgs() { return 11; }
F m_func;
};
template< typename Cls, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9, typename P10, typename P11, typename P12>//12
struct JSCCallback<void(Cls::*)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12)>:public IJSCCallback {
typedef void(Cls::*F)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12);
JSCCallback(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_COBJ;
JS2CCALL_GET_PARAMS12;
(pThis->*m_func)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12);
resetJsStrBuf();
return JSValueMakeUndefined(ctx);
}
virtual uint16_t getNumArgs() { return 12; }
F m_func;
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
#define JS2CCONSTRUCTOR_GET_PARAMS1 \
P1 p1 = __TransferToCpp<P1>::ToCpp(arguments[0]);
#define JS2CCONSTRUCTOR_GET_PARAMS2 \
P1 p1 = __TransferToCpp<P1>::ToCpp(arguments[0]);\
P2 p2 = __TransferToCpp<P2>::ToCpp(arguments[1]);
#define JS2CCONSTRUCTOR_GET_PARAMS3 \
P1 p1 = __TransferToCpp<P1>::ToCpp(arguments[0]);\
P2 p2 = __TransferToCpp<P2>::ToCpp(arguments[1]);\
P3 p3 = __TransferToCpp<P3>::ToCpp(arguments[2]);
template<typename Cls>
struct JSCConstructor0: public IJSCCallback {
virtual JSObjectRef constructor(JSContextRef ctx, JSObjectRef constructor, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
return JSCClass<Cls>::getInstance()->transferObjPtrToJS(new Cls());
}
virtual uint16_t getNumArgs() { return 0; }
};
template<typename Cls>
IJSCCallback* regConstructor(){
return new JSCConstructor0<Cls>();
}
template<typename Cls, typename P1>
struct JSCConstructor1:public IJSCCallback{
virtual JSObjectRef constructor(JSContextRef ctx, JSObjectRef constructor, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCONSTRUCTOR_GET_PARAMS1;
return JSCClass<Cls>::getInstance()->transferObjPtrToJS(new Cls(p1));
}
virtual uint16_t getNumArgs() { return 1; }
};
template<typename Cls,typename P1>
IJSCCallback* regConstructor(){
return new JSCConstructor1<Cls,P1>();
}
template<typename Cls, typename P1,typename P2>
struct JSCConstructor2:public IJSCCallback{
virtual JSObjectRef constructor(JSContextRef ctx, JSObjectRef constructor, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCONSTRUCTOR_GET_PARAMS2;
return JSCClass<Cls>::getInstance()->transferObjPtrToJS(new Cls(p1,p2));
}
virtual uint16_t getNumArgs() { return 2; }
};
template<typename Cls,typename P1,typename P2>
IJSCCallback* regConstructor(){
return new JSCConstructor2<Cls,P1,P2>();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
struct IJSCFunction
{
virtual ~IJSCFunction(){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) = 0;
virtual uint16_t getNumArgs() = 0;
};
template<typename T>
struct JSCFunction: public IJSCFunction {
JSCFunction(T func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
assert(false && "JSCFunction::call not implemented");
return nullptr;
}
virtual uint16_t getNumArgs() { return 0; }
};
template<typename R>//R(void)
struct JSCFunction<R(*)(void)>: public IJSCFunction {
typedef R(*F)(void);
JSCFunction(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JSValueRef ret = ToJSValue<R>((*m_func)());
resetJsStrBuf();
return ret;
}
virtual uint16_t getNumArgs() { return 0; }
F m_func;
};
template<typename R, typename P1>//R(p1)
struct JSCFunction<R(*)(P1)>: public IJSCFunction {
typedef R(*F)(P1);
JSCFunction(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_PARAMS1;
JSValueRef ret = ToJSValue<R>((*m_func)(p1));
resetJsStrBuf();
return ret;
}
virtual uint16_t getNumArgs() { return 1; }
F m_func;
};
template<typename R, typename P1>//const R(p1)
struct JSCFunction<const R(*)(P1)>:public IJSCFunction {
typedef const R(*F)(P1);
JSCFunction(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_PARAMS1;
JSValueRef ret = ToJSValue<R>((*m_func)(p1));
resetJsStrBuf();
return ret;
}
virtual uint16_t getNumArgs() { return 1; }
F m_func;
};
template<typename R, typename P1, typename P2>//R(p1,p2)
struct JSCFunction<R(*)(P1, P2)>: public IJSCFunction {
typedef R(*F)(P1,P2);
JSCFunction(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_PARAMS2;
JSValueRef ret = ToJSValue<R>((*m_func)(p1, p2));
resetJsStrBuf();
return ret;
}
virtual uint16_t getNumArgs() { return 2; }
F m_func;
};
template<typename R, typename P1, typename P2, typename P3>//3
struct JSCFunction<R(*)(P1, P2, P3)>: public IJSCFunction {
typedef R(*F)(P1, P2, P3);
JSCFunction(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_PARAMS3;
JSValueRef ret = ToJSValue<R>((*m_func)(p1, p2, p3));
resetJsStrBuf();
return ret;
}
virtual uint16_t getNumArgs() { return 3; }
F m_func;
};
template<typename R, typename P1, typename P2, typename P3, typename P4>//4
struct JSCFunction<R(*)(P1, P2, P3, P4)>: public IJSCFunction {
typedef R(*F)(P1, P2, P3, P4);
JSCFunction(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_PARAMS4;
JSValueRef ret = ToJSValue<R>((*m_func)(p1, p2, p3, p4));
resetJsStrBuf();
return ret;
}
virtual uint16_t getNumArgs() { return 4; }
F m_func;
};
template<typename R, typename P1, typename P2, typename P3, typename P4, typename P5>//5
struct JSCFunction<R(*)(P1, P2, P3, P4, P5)>: public IJSCFunction {
typedef R(*F)(P1, P2, P3, P4, P5);
JSCFunction(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_PARAMS5;
JSValueRef ret = ToJSValue<R>((*m_func)(p1, p2, p3, p4, p5));
resetJsStrBuf();
return ret;
}
virtual uint16_t getNumArgs() { return 5; }
F m_func;
};
template<typename R, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>//6
struct JSCFunction<R(*)(P1, P2, P3, P4, P5, P6)>: public IJSCFunction {
typedef R(*F)(P1, P2, P3, P4, P5, P6);
JSCFunction(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_PARAMS6;
JSValueRef ret = ToJSValue<R>((*m_func)(p1, p2, p3, p4, p5, p6));
resetJsStrBuf();
return ret;
}
virtual uint16_t getNumArgs() { return 6; }
F m_func;
};
template<typename R, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7>//7
struct JSCFunction<R(*)(P1, P2, P3, P4, P5, P6, P7)>: public IJSCFunction {
typedef R(*F)(P1, P2, P3, P4, P5, P6, P7);
JSCFunction(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_PARAMS7;
JSValueRef ret = ToJSValue<R>((*m_func)(p1, p2, p3, p4, p5, p6, p7));
resetJsStrBuf();
return ret;
}
virtual uint16_t getNumArgs() { return 7; }
F m_func;
};
template<typename R, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8>//8
struct JSCFunction<R(*)(P1, P2, P3, P4, P5, P6, P7, P8)>: public IJSCFunction {
typedef R(*F)(P1, P2, P3, P4, P5, P6, P7, P8);
JSCFunction(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_PARAMS8;
JSValueRef ret = ToJSValue<R>((*m_func)(p1, p2, p3, p4, p5, p6, p7, p8));
resetJsStrBuf();
return ret;
}
virtual uint16_t getNumArgs() { return 8; }
F m_func;
};
template<typename R, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9>//9
struct JSCFunction<R(*)(P1, P2, P3, P4, P5, P6, P7, P8, P9)>: public IJSCFunction {
typedef R(*F)(P1, P2, P3, P4, P5, P6, P7, P8, P9);
JSCFunction(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_PARAMS9;
JSValueRef ret = ToJSValue<R>((*m_func)(p1, p2, p3, p4, p5, p6, p7, p8, p9));
resetJsStrBuf();
return ret;
}
virtual uint16_t getNumArgs() { return 9; }
F m_func;
};
//void
template<> //void(void)
struct JSCFunction<void(*)(void)>: public IJSCFunction {
typedef void(*F)(void);
JSCFunction(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
(*m_func)();
resetJsStrBuf();
return JSValueMakeUndefined(ctx);
}
virtual uint16_t getNumArgs() { return 0; }
F m_func;
};
template<typename P1>
struct JSCFunction<void(*)(P1)>: public IJSCFunction {//void(p1)
typedef void(*F)(P1);
JSCFunction(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_PARAMS1;
(*m_func)(p1);
resetJsStrBuf();
return JSValueMakeUndefined(ctx);
}
virtual uint16_t getNumArgs() { return 1; }
F m_func;
};
template<typename P1, typename P2>//void(p1,p2)
struct JSCFunction<void(*)(P1, P2)>: public IJSCFunction {
typedef void(*F)(P1, P2);
JSCFunction(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_PARAMS2;
(*m_func)(p1, p2);
resetJsStrBuf();
return JSValueMakeUndefined(ctx);
}
virtual uint16_t getNumArgs() { return 2; }
F m_func;
};
template< typename P1, typename P2, typename P3>//3
struct JSCFunction<void(*)(P1, P2, P3)>: public IJSCFunction {
typedef void(*F)(P1, P2, P3);
JSCFunction(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_PARAMS3;
(*m_func)(p1, p2, p3);
resetJsStrBuf();
return JSValueMakeUndefined(ctx);
}
virtual uint16_t getNumArgs() { return 3; }
F m_func;
};
template<typename P1, typename P2, typename P3, typename P4>//4
struct JSCFunction<void(*)(P1, P2, P3, P4)>: public IJSCFunction {
typedef void(*F)(P1, P2, P3, P4);
JSCFunction(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_PARAMS4;
(*m_func)(p1, p2, p3, p4);
resetJsStrBuf();
return JSValueMakeUndefined(ctx);
}
virtual uint16_t getNumArgs() { return 4; }
F m_func;
};
template<typename P1, typename P2, typename P3, typename P4, typename P5>//5
struct JSCFunction<void(*)(P1, P2, P3, P4, P5)>: public IJSCFunction {
typedef void(*F)(P1, P2, P3, P4, P5);
JSCFunction(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_PARAMS5;
(*m_func)(p1, p2, p3, p4, p5);
resetJsStrBuf();
return JSValueMakeUndefined(ctx);
}
virtual uint16_t getNumArgs() { return 5; }
F m_func;
};
template<typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>//6
struct JSCFunction<void(*)(P1, P2, P3, P4, P5, P6)>: public IJSCFunction {
typedef void(*F)(P1, P2, P3, P4, P5, P6);
JSCFunction(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_PARAMS6;
(*m_func)(p1, p2, p3, p4, p5, p6);
resetJsStrBuf();
return JSValueMakeUndefined(ctx);
}
virtual uint16_t getNumArgs() { return 6; }
F m_func;
};
template< typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7>//7
struct JSCFunction<void(*)(P1, P2, P3, P4, P5, P6, P7)>: public IJSCFunction {
typedef void(*F)(P1, P2, P3, P4, P5, P6, P7);
JSCFunction(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_PARAMS7;
(*m_func)(p1, p2, p3, p4, p5, p6, p7);
resetJsStrBuf();
return JSValueMakeUndefined(ctx);
}
virtual uint16_t getNumArgs() { return 7; }
F m_func;
};
template<typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8>//8
struct JSCFunction<void(*)(P1, P2, P3, P4, P5, P6, P7, P8)>: public IJSCFunction {
typedef void(*F)(P1, P2, P3, P4, P5, P6, P7, P8);
JSCFunction(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_PARAMS8;
(*m_func)(p1, p2, p3, p4, p5, p6, p7, p8);
resetJsStrBuf();
return JSValueMakeUndefined(ctx);
}
virtual uint16_t getNumArgs() { return 8; }
F m_func;
};
template<typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9>//9
struct JSCFunction<void(*)(P1, P2, P3, P4, P5, P6, P7, P8, P9)>: public IJSCFunction {
typedef void(*F)(P1, P2, P3, P4, P5, P6, P7, P8, P9);
JSCFunction(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_PARAMS9;
(*m_func)(p1, p2, p3, p4, p5, p6, p7, p8, p9);
resetJsStrBuf();
return JSValueMakeUndefined(ctx);
}
virtual uint16_t getNumArgs() { return 9; }
F m_func;
};
template<typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9, typename P10, typename P11, typename P12>//12
struct JSCFunction<void(*)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12)>: public IJSCFunction {
typedef void(*F)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12);
JSCFunction(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_PARAMS12;
(*m_func)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12);
resetJsStrBuf();
return JSValueMakeUndefined(ctx);
}
virtual uint16_t getNumArgs() { return 12; }
F m_func;
};
} // namespace __JSCProxy
#endif
@@ -0,0 +1,172 @@
#ifndef _JSCProxyTLS_h
#define _JSCProxyTLS_h
#include <JavaScriptCore/JSContextRef.h>
#include <JavaScriptCore/JSStringRef.h>
#include <JavaScriptCore/JSValueRef.h>
#include "../../../CToObjectC.h"
#include <util/JCCommonMethod.h>
#include <util/Log.h>
#include <pthread.h>
namespace laya
{
class __TlsData
{
__TlsData(){}
~__TlsData(){}
public:
static pthread_key_t s_tls_curThread;
static __TlsData *GetInstance()
{
static __TlsData _Ins;
return &_Ins;
}
void *SetCurContext( JSContextRef p_pContext )
{
void *pRet = (void *)pthread_getspecific(s_tls_curThread);
pthread_setspecific(s_tls_curThread,(void*)p_pContext);
return pRet;
}
JSContextRef GetCurContext()
{
return (JSContextRef)pthread_getspecific(s_tls_curThread);
}
};
class __JsThrow
{
JSValueRef *m_pException;
public:
__JsThrow()
{
m_pException = 0;
}
static __JsThrow *GetInstance()
{
static __JsThrow _Ins;
return &_Ins;
}
static void Throw( JSValueRef* exception, const char *p_pszInfo=0 )
{
if( 0 != exception )
{
JSStringRef message = JSStringCreateWithUTF8CString((0==p_pszInfo)?"unknown error":p_pszInfo);
*exception = JSValueMakeString(__TlsData::GetInstance()->GetCurContext(), message);
JSStringRelease(message);
}
}
void UpdateException( JSValueRef* exception )
{
m_pException = exception;
}
void RuntimeThrow( const char *p_pszInfo )
{
__JsThrow::Throw(m_pException,p_pszInfo);
}
};
extern bool gbAlertException;
class __JSRun
{
static char *__ToCppString( JSValueRef p_vl, JSContextRef p_pContext )
{
char *pRet = 0;
JSStringRef _jsStr = JSValueToStringCopy(p_pContext, p_vl, 0);
if( _jsStr )
{
size_t iSize = JSStringGetMaximumUTF8CStringSize(_jsStr);
if(iSize>0)
{
pRet=new char[iSize+1];
JSStringGetUTF8CString( _jsStr, pRet, iSize+1 );
}
JSStringRelease( _jsStr );
}
return pRet;
}
public:
static void OutputException( JSValueRef exception )
{
if( NULL != exception )
{
JSContextRef pContext = __TlsData::GetInstance()->GetCurContext();
JSStringRef jsLinePropertyName = JSStringCreateWithUTF8CString("line");
JSStringRef jsColumnPropertyName = JSStringCreateWithUTF8CString("column");
JSStringRef jsUrlPropertyName = JSStringCreateWithUTF8CString("sourceURL");
JSObjectRef exObject = JSValueToObject( pContext, exception, NULL );
JSValueRef line = JSObjectGetProperty( pContext, exObject, jsLinePropertyName, NULL );
JSValueRef column = JSObjectGetProperty( pContext, exObject, jsColumnPropertyName, NULL );
JSValueRef url = JSObjectGetProperty( pContext, exObject, jsUrlPropertyName, NULL );
char *pEx = __ToCppString(exception,pContext);
char *pLine = __ToCppString(line,pContext);
char *pColumn = __ToCppString(column,pContext);
char *pUrl = __ToCppString(url,pContext);
//通知全局错误处理脚本
std::string kBuf = "if(conch.onerror){conch.onerror('";
kBuf += UrlEncode(pEx);
kBuf += "','undefined','";
kBuf += UrlEncode(pLine);
kBuf += "','";
kBuf += UrlEncode(pColumn);
kBuf += "','";
kBuf += UrlEncode(pEx);
kBuf += "');};";
__JSRun::Run(kBuf.c_str());
static char sBuffer[10240]={0};
sprintf( sBuffer,"exception info: [%s] at line %s\n", pEx, pLine );
if (gbAlertException)
CToObjectCAlert( sBuffer );
else {
LOGE("==JSERROR:\n%s", sBuffer);
}
delete[] pEx;
delete[] pLine;
delete[] pColumn;
delete[] pUrl;
JSStringRelease(jsLinePropertyName);
JSStringRelease(jsColumnPropertyName);
JSStringRelease(jsUrlPropertyName);
}
}
static bool Run( const char *p_pszScript,JSValueRef* result = NULL )
{
bool bRet = true;
JSContextRef pContext = __TlsData::GetInstance()->GetCurContext();
JSStringRef pScript = JSStringCreateWithUTF8CString( p_pszScript );
JSValueRef exception = NULL;
JSValueRef ret = JSEvaluateScript(pContext, pScript, NULL, NULL, 0, &exception );
if( 0 != exception )
{
OutputException( exception );
bRet = false;
}
if( ret != NULL && result != NULL ){
*result = ret;
}
JSStringRelease( pScript );
return bRet;
}
};
}
#endif
@@ -0,0 +1,443 @@
#ifndef _JSCProxyTrnasfer_h
#define _JSCProxyTrnasfer_h
#include <JavaScriptCore/JSContextRef.h>
#include <JavaScriptCore/JSStringRef.h>
#include <JavaScriptCore/JSValueRef.h>
#include <string>
#include <vector>
#include "JSCProxyTLS.h"
#include "JSCProxyType.h"
namespace laya
{
void resetJsStrBuf();
template <typename T>class JSCClass;
template <typename T> class __TransferToCpp
{
public:
static T ToCpp( JSValueRef p_vl ){
assert(false && "type not supported!");
}
static bool is( JSValueRef p_vl ){
return __CheckClassType::IsTypeOf<T>(p_vl);
}
};
template <typename T> class __TransferToCpp<T*>
{
public:
static T* ToCpp( JSValueRef p_vl ){
JSContextRef pCtx = __TlsData::GetInstance()->GetCurContext();
if( 0 == p_vl || JSValueIsUndefined(pCtx, p_vl) || JSValueIsNull(pCtx, p_vl) )
return nullptr;
else
return (T*)JSObjectGetPrivate((JSObjectRef)p_vl);
}
static bool is( JSValueRef p_vl ){
return __CheckClassType::IsTypeOf<T>(p_vl);
}
};
template <> class __TransferToCpp<int>
{
public:
static int ToCpp( JSValueRef p_vl ){
JSContextRef pCtx = __TlsData::GetInstance()->GetCurContext();
if(0!=p_vl)
return (int)JSValueToNumber(pCtx,p_vl,0);
else return 0;
}
static bool is( JSValueRef p_vl ){
JSContextRef pCtx = __TlsData::GetInstance()->GetCurContext();
return JSValueIsNumber(pCtx, p_vl);
}
};
template <> class __TransferToCpp<short>
{
public:
static int ToCpp( JSValueRef p_vl ){
JSContextRef pCtx = __TlsData::GetInstance()->GetCurContext();
if(0!=p_vl)
return (short)JSValueToNumber(pCtx,p_vl,0);
else return 0;
}
static bool is( JSValueRef p_vl ){
JSContextRef pCtx = __TlsData::GetInstance()->GetCurContext();
return JSValueIsNumber(pCtx, p_vl);
}
};
template <> class __TransferToCpp<unsigned int>
{
public:
static unsigned int ToCpp( JSValueRef p_vl ){
JSContextRef pCtx=__TlsData::GetInstance()->GetCurContext();
if(0!=p_vl)
return (unsigned int)JSValueToNumber(pCtx,p_vl,0);
else
return 0;
}
static bool is( JSValueRef p_vl ){
JSContextRef pCtx = __TlsData::GetInstance()->GetCurContext();
return JSValueIsNumber(pCtx, p_vl);
}
};
template <> class __TransferToCpp<long>
{
public:
static long ToCpp( JSValueRef p_vl ){
JSContextRef pCtx=__TlsData::GetInstance()->GetCurContext();
if(0!=p_vl)
return (long)JSValueToNumber(pCtx,p_vl,0);
else
return 0;
}
static bool is( JSValueRef p_vl ){
JSContextRef pCtx = __TlsData::GetInstance()->GetCurContext();
return JSValueIsNumber(pCtx, p_vl);
}
};
template <> class __TransferToCpp<unsigned long>
{
public:
static unsigned long ToCpp( JSValueRef p_vl ){
JSContextRef pCtx=__TlsData::GetInstance()->GetCurContext();
if(0!=p_vl)
return (unsigned long)JSValueToNumber(pCtx,p_vl,0);
else
return 0;
}
static bool is( JSValueRef p_vl ){
JSContextRef pCtx = __TlsData::GetInstance()->GetCurContext();
return JSValueIsNumber(pCtx, p_vl);
}
};
template <> class __TransferToCpp<bool>
{
public:
static bool ToCpp( JSValueRef p_vl ){
JSContextRef pCtx=__TlsData::GetInstance()->GetCurContext();
if(0!=p_vl)
return JSValueToBoolean(pCtx,p_vl);
else
return false;
}
static bool is( JSValueRef p_vl ){
JSContextRef pCtx = __TlsData::GetInstance()->GetCurContext();
return JSValueIsBoolean(pCtx, p_vl);
}
};
template <> class __TransferToCpp<float>
{
public:
static float ToCpp( JSValueRef p_vl ){
JSContextRef pCtx=__TlsData::GetInstance()->GetCurContext();
if(0!=p_vl)
return (float)JSValueToNumber(pCtx,p_vl,0);
else
return 0;
}
static bool is( JSValueRef p_vl ){
JSContextRef pCtx = __TlsData::GetInstance()->GetCurContext();
return JSValueIsNumber(pCtx, p_vl);
}
};
template <> class __TransferToCpp<double>
{
public:
static double ToCpp( JSValueRef p_vl ){
JSContextRef pCtx=__TlsData::GetInstance()->GetCurContext();
if(0!=p_vl)
return JSValueToNumber(pCtx,p_vl,0);
else
return 0;
}
static bool is( JSValueRef p_vl ){
JSContextRef pCtx = __TlsData::GetInstance()->GetCurContext();
return JSValueIsNumber(pCtx, p_vl);
}
};
template <> class __TransferToCpp<long long>
{
public:
static long long ToCpp( JSValueRef p_vl ){
JSContextRef pCtx=__TlsData::GetInstance()->GetCurContext();
if(0!=p_vl)
return (long long)JSValueToNumber(pCtx,p_vl,0);
else
return 0;
}
static bool is( JSValueRef p_vl ){
JSContextRef pCtx = __TlsData::GetInstance()->GetCurContext();
return JSValueIsNumber(pCtx, p_vl);
}
};
template <> class __TransferToCpp<unsigned long long>
{
public:
static unsigned long long ToCpp( JSValueRef p_vl ){
JSContextRef pCtx=__TlsData::GetInstance()->GetCurContext();
if(0!=p_vl)return (unsigned long long)JSValueToNumber(pCtx,p_vl,0);
else return 0;
}
static bool is( JSValueRef p_vl ){
JSContextRef pCtx = __TlsData::GetInstance()->GetCurContext();
return JSValueIsNumber(pCtx, p_vl);
}
};
template <> class __TransferToCpp<JSValueRef>
{
public:
static JSValueRef ToCpp( JSValueRef p_vl ){
return p_vl;
}
static bool is( JSValueRef p_vl ){
return true;
}
};
char* JsCharToC(JSValueRef p_vl);
char* JsCharToC(JSStringRef p_vl);
#define __DeclareStringTransferToCpp(Tp) \
template <> class __TransferToCpp<Tp> \
{ \
public: \
static char *ToCpp( JSValueRef p_vl ) \
{ \
return JsCharToC(p_vl); \
} \
static char *ToCpp( JSStringRef p_vl ) \
{ \
return JsCharToC(p_vl); \
} \
static std::string ToCppStd( JSValueRef p_vl ) \
{ \
return JsCharToC(p_vl); \
} \
static std::string ToCppStd( JSStringRef p_vl ) \
{ \
return JsCharToC(p_vl); \
} \
static bool is( JSValueRef p_vl ){ \
JSContextRef pCtx = __TlsData::GetInstance()->GetCurContext(); \
return JSValueIsString(pCtx, p_vl); \
} \
};
__DeclareStringTransferToCpp(char *);
__DeclareStringTransferToCpp(const char *);
__DeclareStringTransferToCpp(unsigned char *);
__DeclareStringTransferToCpp(const unsigned char *);
template <typename T> class __TransferToJs
{
public:
static JSValueRef ToJs( T *p_vl ){
return JSCClass<T>::getInstance()->transferObjPtrToJS(p_vl);
}
};
template <> class __TransferToJs<void>
{public:static JSValueRef ToJs( int p_vl )
{
JSContextRef pCtx=__TlsData::GetInstance()->GetCurContext();
if(0==p_vl)
return JSValueMakeUndefined(pCtx);
else
return JSValueMakeNull(pCtx);
}};
template <> class __TransferToJs<JSValueRef>
{public:static JSValueRef ToJs( JSValueRef p_vl ){return p_vl;}};
template <> class __TransferToJs<bool>
{public:static JSValueRef ToJs( bool p_vl ){return JSValueMakeBoolean(__TlsData::GetInstance()->GetCurContext(),p_vl);}};
template <> class __TransferToJs<int>
{public:static JSValueRef ToJs( int p_vl ){return JSValueMakeNumber(__TlsData::GetInstance()->GetCurContext(),(double)p_vl);}};
template <> class __TransferToJs<unsigned int>
{public:static JSValueRef ToJs( unsigned int p_vl ){return JSValueMakeNumber(__TlsData::GetInstance()->GetCurContext(),(double)p_vl);}};
template <> class __TransferToJs<float>
{public:static JSValueRef ToJs( float p_vl ){return JSValueMakeNumber(__TlsData::GetInstance()->GetCurContext(),(double)p_vl);}};
template <> class __TransferToJs<double>
{public:static JSValueRef ToJs( double p_vl ){return JSValueMakeNumber(__TlsData::GetInstance()->GetCurContext(),p_vl);}};
template <> class __TransferToJs<long long>
{
public:
static JSValueRef ToJs( long long p_vl ){return JSValueMakeNumber(__TlsData::GetInstance()->GetCurContext(),(double)p_vl);}
static JSValueRef ToJsDate( long long p_vl )
{
JSValueRef n = ToJs(p_vl);
return JSObjectMakeDate(__TlsData::GetInstance()->GetCurContext(), 1, &n, 0);
}
};
template <> class __TransferToJs<long>
{
public:
static JSValueRef ToJs( long p_vl ){return JSValueMakeNumber(__TlsData::GetInstance()->GetCurContext(),(double)p_vl);}
static JSValueRef ToJsDate( long p_vl )
{
JSValueRef n = ToJs(p_vl);
return JSObjectMakeDate(__TlsData::GetInstance()->GetCurContext(), 1, &n, 0);
}
};
template <> class __TransferToJs<unsigned long long>
{
public:
static JSValueRef ToJs( unsigned long long p_vl ){return JSValueMakeNumber(__TlsData::GetInstance()->GetCurContext(),(double)p_vl);}
static JSValueRef ToJsDate( unsigned long long p_vl )
{
JSValueRef n = ToJs(p_vl);
return JSObjectMakeDate(__TlsData::GetInstance()->GetCurContext(), 1, &n, 0);
}
};
template <> class __TransferToJs<char *>
{public:static JSValueRef ToJs( char *p_vl )
{
JSStringRef pStr = JSStringCreateWithUTF8CString(p_vl);
JSValueRef pRet = JSValueMakeString(__TlsData::GetInstance()->GetCurContext(), pStr);
JSStringRelease(pStr);
return pRet;
}};
template <> class __TransferToJs<const char *>
{public:static JSValueRef ToJs( const char *p_vl )
{
JSStringRef pStr = JSStringCreateWithUTF8CString(p_vl);
JSValueRef pRet = JSValueMakeString(__TlsData::GetInstance()->GetCurContext(), pStr);
JSStringRelease(pStr);
return pRet;
}};
template <> class __TransferToJs<unsigned char *>
{public:static JSValueRef ToJs( unsigned char *p_vl )
{
JSStringRef pStr = JSStringCreateWithUTF8CString((char *)p_vl);
JSValueRef pRet = JSValueMakeString(__TlsData::GetInstance()->GetCurContext(), pStr);
JSStringRelease(pStr);
return pRet;
}};
template <> class __TransferToJs<const unsigned char *>
{public:static JSValueRef ToJs( const unsigned char *p_vl )
{
JSStringRef pStr = JSStringCreateWithUTF8CString((char *)p_vl);
JSValueRef pRet = JSValueMakeString(__TlsData::GetInstance()->GetCurContext(), pStr);
JSStringRelease(pStr);
return pRet;
}};
template <> class __TransferToJs<std::string>
{public:static JSValueRef ToJs( std::string p_vl )
{
JSStringRef pStr = JSStringCreateWithUTF8CString(p_vl.c_str());
JSValueRef pRet = JSValueMakeString(__TlsData::GetInstance()->GetCurContext(), pStr);
JSStringRelease(pStr);
return pRet;
}};
template <typename T> class __JsArray{
public:
static JSObjectRef ToJsArray(const std::vector<T*>& p_vl)
{
int p_iSize = p_vl.size();
JSValueRef pValArray[p_iSize];
for(int i=0;i<p_iSize;++i)
{
pValArray[i] = __TransferToJs<T>::ToJs(p_vl[i]);
}
JSObjectRef pRet = JSObjectMakeArray( __TlsData::GetInstance()->GetCurContext(), p_iSize, pValArray, 0 );
return pRet;
}
static JSObjectRef ToJsArray(const std::vector<T>& p_vl)
{
int p_iSize = p_vl.size();
JSValueRef pValArray[p_iSize];
for(int i=0;i<p_iSize;++i)
{
pValArray[i] = __TransferToJs<T>::ToJs(p_vl[i]);
}
JSObjectRef pRet = JSObjectMakeArray( __TlsData::GetInstance()->GetCurContext(), p_iSize, pValArray, 0 );
return pRet;
}
};
class __JsByteArray
{
public:
static JSObjectRef ToJsByteArray( const unsigned char *p_vl, int p_iSize )
{
if( 0 == p_vl || p_iSize <= 0 )
{
return NULL;
}
else
{
JSValueRef pValArray[p_iSize];
for(int i=0;i<p_iSize;++i)
{
pValArray[i] = __TransferToJs<unsigned int>::ToJs(p_vl[i]);
}
JSObjectRef pRet = JSObjectMakeArray( __TlsData::GetInstance()->GetCurContext(), p_iSize, pValArray, 0 );
return pRet;
}
}
};
template <typename T> class __TransferToJs<std::vector<T*> >
{
public:static JSObjectRef ToJs( const std::vector<T*>& p_vl )
{
return __JsArray<T>::ToJsArray(p_vl);
}
};
template <typename T> class __TransferToJs<std::vector<T> >
{
public:static JSObjectRef ToJs(const std::vector<T>& p_vl)
{
return __JsArray<T>::ToJsArray(p_vl);
}
};
}
#endif
@@ -0,0 +1,121 @@
#ifndef __JSCProxyType_h
#define __JSCProxyType_h
#define NDEBUG
#include <assert.h>
#include "JSCProxyTLS.h"
#define __Js_class_typeid_property "__cppclstypeid"
namespace laya
{
typedef enum
{
__VT_void = 0,
__VT_string,
__VT_bool,
__VT_int,
__VT_long,
__VT_float,
__VT_double,
__VT_longlong,
__VT_ArrayBuffer,
__VT_object,
} __ValueType;
template <class _Key> struct __InferType
{__ValueType iType;__InferType(){iType=__VT_object;}};
template<> struct __InferType<void>
{__ValueType iType;__InferType(){iType=__VT_void;}};
template<> struct __InferType<bool>
{__ValueType iType;__InferType(){iType=__VT_bool;}};
template<> struct __InferType<char *>
{__ValueType iType;__InferType(){iType=__VT_string;}};
template<> struct __InferType<const char *>
{__ValueType iType;__InferType(){iType=__VT_string;}};
template<> struct __InferType<unsigned char *>
{__ValueType iType;__InferType(){iType=__VT_string;}};
template<> struct __InferType<const unsigned char *>
{__ValueType iType;__InferType(){iType=__VT_string;}};
template<> struct __InferType<int>
{__ValueType iType;__InferType(){iType=__VT_int;}};
template<> struct __InferType<unsigned int>
{__ValueType iType;__InferType(){iType=__VT_int;}};
template<> struct __InferType<long>
{__ValueType iType;__InferType(){iType=__VT_long;}};
template<> struct __InferType<unsigned long>
{__ValueType iType;__InferType(){iType=__VT_long;}};
template<> struct __InferType<float>
{__ValueType iType;__InferType(){iType=__VT_float;}};
template<> struct __InferType<double>
{__ValueType iType;__InferType(){iType=__VT_double;}};
template<> struct __InferType<long long>
{__ValueType iType;__InferType(){iType=__VT_longlong;}};
template<> struct __InferType<unsigned long long>
{__ValueType iType;__InferType(){iType=__VT_longlong;}};
template<typename T>
class JSCClass;
class __CheckClassType
{
public:
template <typename T>
static bool IsTypeOf( JSObjectRef p_pObj )
{
if( 0 == p_pObj )
return false;
JSStringRef pszName = JSStringCreateWithUTF8CString(__Js_class_typeid_property);
JSValueRef pProperty = JSObjectGetProperty(__TlsData::GetInstance()->GetCurContext(), p_pObj, pszName, 0);
JSStringRelease(pszName);
if( 0 == pProperty )
{
return false;
}
else
{
JSContextRef pCtx = __TlsData::GetInstance()->GetCurContext();
int nID = (int)JSValueToNumber(pCtx,pProperty,0);
return (nID == (JSCClass<T>::getInstance()->getTypeID()));
}
}
template <typename T>
static bool IsTypeOf( JSValueRef p_pVal )
{
if( 0 == p_pVal )
return false;
JSContextRef pCtx = __TlsData::GetInstance()->GetCurContext();
if( !JSValueIsObject(pCtx, p_pVal) )
{
return false;
}
return IsTypeOf<T>((JSObjectRef)p_pVal);
}
};
} // namespace __JSCProxy
#endif