Skip to content

Commit

Permalink
修复对象在lua和原生层中相互传递时,部分方法处理行为不一致问题。
Browse files Browse the repository at this point in the history
  • Loading branch information
vimfung committed Nov 1, 2016
1 parent 44fe2d0 commit 2779a37
Show file tree
Hide file tree
Showing 31 changed files with 424 additions and 215 deletions.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file modified Sample/Android/app/src/main/jniLibs/mips/libLuaScriptCore.so
Binary file not shown.
Binary file modified Sample/Android/app/src/main/jniLibs/mips64/libLuaScriptCore.so
Binary file not shown.
Binary file modified Sample/Android/app/src/main/jniLibs/x86/libLuaScriptCore.so
Binary file not shown.
Binary file not shown.
Binary file modified Sample/Android/app/src/main/libs/LuaScriptCore.jar
Binary file not shown.
48 changes: 24 additions & 24 deletions Sample/iOS_OSX/Sample.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
objects = {

/* Begin PBXBuildFile section */
7C236D0E1DC87E7900E1F9CF /* libLuaScriptCore.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7C236D0D1DC87E7900E1F9CF /* libLuaScriptCore.a */; };
7C236D291DC8C60F00E1F9CF /* libLuaScriptCore.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7C236D281DC8C60F00E1F9CF /* libLuaScriptCore.a */; };
7C5A61811D6AE2A3007D4308 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7C5A61801D6AE2A3007D4308 /* AppDelegate.m */; };
7C5A61841D6AE2A3007D4308 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 7C5A61831D6AE2A3007D4308 /* main.m */; };
7C5A61871D6AE2A3007D4308 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 7C5A61861D6AE2A3007D4308 /* ViewController.m */; };
Expand All @@ -33,15 +33,15 @@
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
7C236D051DC87E7900E1F9CF /* LSCContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LSCContext.h; sourceTree = "<group>"; };
7C236D061DC87E7900E1F9CF /* LSCFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LSCFunction.h; sourceTree = "<group>"; };
7C236D071DC87E7900E1F9CF /* LSCModule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LSCModule.h; sourceTree = "<group>"; };
7C236D081DC87E7900E1F9CF /* LSCObjectClass.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LSCObjectClass.h; sourceTree = "<group>"; };
7C236D091DC87E7900E1F9CF /* LSCPointer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LSCPointer.h; sourceTree = "<group>"; };
7C236D0A1DC87E7900E1F9CF /* LSCTypeDefinied.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LSCTypeDefinied.h; sourceTree = "<group>"; };
7C236D0B1DC87E7900E1F9CF /* LSCValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LSCValue.h; sourceTree = "<group>"; };
7C236D0C1DC87E7900E1F9CF /* LuaScriptCore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LuaScriptCore.h; sourceTree = "<group>"; };
7C236D0D1DC87E7900E1F9CF /* libLuaScriptCore.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libLuaScriptCore.a; sourceTree = "<group>"; };
7C236D201DC8C60F00E1F9CF /* LSCContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LSCContext.h; sourceTree = "<group>"; };
7C236D211DC8C60F00E1F9CF /* LSCFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LSCFunction.h; sourceTree = "<group>"; };
7C236D221DC8C60F00E1F9CF /* LSCModule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LSCModule.h; sourceTree = "<group>"; };
7C236D231DC8C60F00E1F9CF /* LSCObjectClass.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LSCObjectClass.h; sourceTree = "<group>"; };
7C236D241DC8C60F00E1F9CF /* LSCPointer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LSCPointer.h; sourceTree = "<group>"; };
7C236D251DC8C60F00E1F9CF /* LSCTypeDefinied.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LSCTypeDefinied.h; sourceTree = "<group>"; };
7C236D261DC8C60F00E1F9CF /* LSCValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LSCValue.h; sourceTree = "<group>"; };
7C236D271DC8C60F00E1F9CF /* LuaScriptCore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LuaScriptCore.h; sourceTree = "<group>"; };
7C236D281DC8C60F00E1F9CF /* libLuaScriptCore.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libLuaScriptCore.a; sourceTree = "<group>"; };
7C5A617D1D6AE2A3007D4308 /* Sample-OSX.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Sample-OSX.app"; sourceTree = BUILT_PRODUCTS_DIR; };
7C5A617F1D6AE2A3007D4308 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
7C5A61801D6AE2A3007D4308 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
Expand Down Expand Up @@ -91,34 +91,34 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
7C236D0E1DC87E7900E1F9CF /* libLuaScriptCore.a in Frameworks */,
7C236D291DC8C60F00E1F9CF /* libLuaScriptCore.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */

/* Begin PBXGroup section */
7C236D031DC87E7900E1F9CF /* LuaScriptCore */ = {
7C236D1E1DC8C60F00E1F9CF /* LuaScriptCore */ = {
isa = PBXGroup;
children = (
7C236D041DC87E7900E1F9CF /* include */,
7C236D0D1DC87E7900E1F9CF /* libLuaScriptCore.a */,
7C236D1F1DC8C60F00E1F9CF /* include */,
7C236D281DC8C60F00E1F9CF /* libLuaScriptCore.a */,
);
name = LuaScriptCore;
path = ../../../Release/iOS;
sourceTree = "<group>";
};
7C236D041DC87E7900E1F9CF /* include */ = {
7C236D1F1DC8C60F00E1F9CF /* include */ = {
isa = PBXGroup;
children = (
7C236D051DC87E7900E1F9CF /* LSCContext.h */,
7C236D061DC87E7900E1F9CF /* LSCFunction.h */,
7C236D071DC87E7900E1F9CF /* LSCModule.h */,
7C236D081DC87E7900E1F9CF /* LSCObjectClass.h */,
7C236D091DC87E7900E1F9CF /* LSCPointer.h */,
7C236D0A1DC87E7900E1F9CF /* LSCTypeDefinied.h */,
7C236D0B1DC87E7900E1F9CF /* LSCValue.h */,
7C236D0C1DC87E7900E1F9CF /* LuaScriptCore.h */,
7C236D201DC8C60F00E1F9CF /* LSCContext.h */,
7C236D211DC8C60F00E1F9CF /* LSCFunction.h */,
7C236D221DC8C60F00E1F9CF /* LSCModule.h */,
7C236D231DC8C60F00E1F9CF /* LSCObjectClass.h */,
7C236D241DC8C60F00E1F9CF /* LSCPointer.h */,
7C236D251DC8C60F00E1F9CF /* LSCTypeDefinied.h */,
7C236D261DC8C60F00E1F9CF /* LSCValue.h */,
7C236D271DC8C60F00E1F9CF /* LuaScriptCore.h */,
);
path = include;
sourceTree = "<group>";
Expand Down Expand Up @@ -150,7 +150,7 @@
7C6B12721D6AFD1400489D9E /* Sample-iOS */ = {
isa = PBXGroup;
children = (
7C236D031DC87E7900E1F9CF /* LuaScriptCore */,
7C236D1E1DC8C60F00E1F9CF /* LuaScriptCore */,
7C6B12731D6AFD1400489D9E /* AppDelegate.h */,
7C6B12741D6AFD1400489D9E /* AppDelegate.m */,
7C6B12751D6AFD1400489D9E /* Assets.xcassets */,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,10 @@ else if (paramType.isAssignableFrom(boolean[].class))
argumentArray.add(item.toArrayList().toArray());
}
}
else
{
argumentArray.add(item.toObject());
}

}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,10 @@ else if (paramType.isAssignableFrom(boolean[].class))
argumentArray.add(item.toArrayList().toArray());
}
}
else
{
argumentArray.add(item.toObject());
}

}

Expand Down
4 changes: 2 additions & 2 deletions Source/Android/luascriptcore/src/main/jni/LuaContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ static int methodRouteHandler(lua_State *state) {
cn::vimfung::luascriptcore::LuaValue *retValue = handler (context, methodName, args);
if (retValue != NULL)
{
retValue -> push(state);
retValue -> push(context);
retValue -> release();
}
else
Expand Down Expand Up @@ -330,7 +330,7 @@ cn::vimfung::luascriptcore::LuaValue* cn::vimfung::luascriptcore::LuaContext::ca
for (LuaArgumentList::iterator i = arguments -> begin(); i != arguments -> end() ; ++i)
{
LuaValue *item = *i;
item->push(_state);
item->push(this);
}

if (lua_pcall(_state, (int)arguments -> size(), 1, 0) == 0)
Expand Down
2 changes: 1 addition & 1 deletion Source/Android/luascriptcore/src/main/jni/LuaFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ cn::vimfung::luascriptcore::LuaValue* cn::vimfung::luascriptcore::LuaFunction::i
for (LuaArgumentList::iterator i = arguments -> begin(); i != arguments -> end() ; ++i)
{
LuaValue *item = *i;
item->push(state);
item->push(_context);
}

if (lua_pcall(state, (int)arguments -> size(), 1, 0) == 0)
Expand Down
34 changes: 34 additions & 0 deletions Source/Android/luascriptcore/src/main/jni/LuaJavaEnv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,40 @@ void LuaJavaEnv::removeAssociateInstance(jobject instance, void **ref)

}

void** LuaJavaEnv::getAssociateInstanceRef(jobject instance)
{
long key = 0;
std::set<jobject>::iterator setIt = _instanceSet.find(instance);
if (setIt == _instanceSet.end())
{
JNIEnv *env = LuaJavaEnv::getEnv();

//没找到对应的实例,则使用遍历方式对比对象
for (std::set<jobject>::iterator it = _instanceSet.begin(); it != _instanceSet.end() ; ++it)
{
if (env -> IsSameObject(instance, (jobject)*it) == JNI_TRUE)
{
key = (long)*it;
break;
}
}

LuaJavaEnv::resetEnv(env);
}
else
{
key = (long)instance;
}

std::map<long, void**>::iterator it = _instanceMap.find(key);
if (it != _instanceMap.end())
{
return it -> second;
}

return NULL;
}

jobject LuaJavaEnv::releaseObject(JNIEnv *env, jint objectId)
{
std::map<jint, jobject>::iterator it = _javaObjectMap.find(objectId);
Expand Down
9 changes: 9 additions & 0 deletions Source/Android/luascriptcore/src/main/jni/LuaJavaEnv.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,15 @@ class LuaJavaEnv
*/
static void removeAssociateInstance(jobject instance, void **ref);

/**
* 获取关联对象实例引用
*
* @param instance Java中的实例对象
*
* @return 关联实例对象的引用
*/
static void** getAssociateInstanceRef(jobject instance);

/**
* 释放对象,由于Java层中对象需要引用本地对象,因此为确保Java对象释放时也释放本地对象,则需要调用该方法。
*
Expand Down
43 changes: 23 additions & 20 deletions Source/Android/luascriptcore/src/main/jni/LuaJavaObjectClass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "LuaDefine.h"
#include "LuaObjectManager.h"
#include "LuaJavaConverter.h"
#include "LuaJavaObjectDescriptor.h"

/**
* 类实例化处理器
Expand All @@ -33,23 +34,26 @@ static void _luaClassObjectCreated (cn::vimfung::luascriptcore::modules::oo::Lua
//创建Java层的实例对象
jobject jcontext = LuaJavaEnv::getJavaLuaContext(env, objectClass->getContext());
jobject jInstance = env->NewObject(cls, initMethodId, jcontext);
jobject jGlobalInstance = env->NewGlobalRef(jInstance);

LuaJavaObjectDescriptor *objDesc = new LuaJavaObjectDescriptor(jInstance);
objDesc -> setUserdata(objectClass);

//先为实例对象在lua中创建内存
void **ref = (void **) lua_newuserdata(state, sizeof(jobject *));
LuaJavaObjectDescriptor **ref = (LuaJavaObjectDescriptor **) lua_newuserdata(state, sizeof(LuaJavaObjectDescriptor *));
*ref = objDesc;

//创建本地实例对象,赋予lua的内存块
*ref = jGlobalInstance;
luaL_getmetatable(state, jobjectClass->getName().c_str());
if (lua_istable(state, -1)) {
if (lua_istable(state, -1))
{
lua_setmetatable(state, -2);
}
else {
else
{
lua_pop(state, 1);
}

//关联对象
LuaJavaEnv::associcateInstance(jGlobalInstance, ref);
LuaJavaEnv::associcateInstance((jobject)objDesc -> getObject(), (void **)ref);

//调用实例对象的init方法
lua_pushvalue(state, 1);
Expand Down Expand Up @@ -78,10 +82,10 @@ static void _luaClassObjectDestroy (cn::vimfung::luascriptcore::modules::oo::Lua
if (lua_gettop(state) > 0 && lua_isuserdata(state, 1))
{
//表示有实例对象传入
void **ref = (void **)lua_touserdata(state, 1);
jobject instance = (jobject)*ref;
LuaJavaObjectDescriptor **ref = (LuaJavaObjectDescriptor **)lua_touserdata(state, 1);
jobject instance = (jobject)(*ref) -> getObject();

LuaJavaEnv::removeAssociateInstance(instance, ref);
LuaJavaEnv::removeAssociateInstance(instance, (void **)ref);

//调用实例对象的destroy方法
lua_pushvalue(state, 1);
Expand All @@ -94,8 +98,7 @@ static void _luaClassObjectDestroy (cn::vimfung::luascriptcore::modules::oo::Lua
lua_pop(state, 2);

//移除Java实例对象引用
env -> DeleteGlobalRef(instance);

(*ref) -> release();
}

LuaJavaEnv::resetEnv(env);
Expand All @@ -112,8 +115,8 @@ static std::string _luaClassObjectDescription (cn::vimfung::luascriptcore::modul
if (lua_gettop(state) > 0 && lua_isuserdata(state, 1))
{
//表示有实例对象传入
void **ref = (void **)lua_touserdata(state, 1);
jobject instance = (jobject)*ref;
LuaJavaObjectDescriptor **ref = (LuaJavaObjectDescriptor **)lua_touserdata(state, 1);
jobject instance = (jobject)(*ref) -> getObject();

jclass cls = env -> GetObjectClass(instance);
jmethodID toStringMethodId = env -> GetMethodID(cls, "toString", "()Ljava/lang/String;");
Expand Down Expand Up @@ -149,8 +152,8 @@ static LuaValue* _luaInstanceMethodHandler (cn::vimfung::luascriptcore::modules:
if (lua_gettop(state) > 0 && lua_isuserdata(state, 1))
{
//表示有实例对象传入
void **ref = (void **)lua_touserdata(state, 1);
jobject instance = (jobject)*ref;
LuaJavaObjectDescriptor **ref = (LuaJavaObjectDescriptor **)lua_touserdata(state, 1);
jobject instance = (jobject)(*ref) -> getObject();

jmethodID invokeMethodID = env -> GetMethodID(LuaJavaType::luaObjectClass(env), "_instanceMethodInvoke", "(Ljava/lang/String;[Lcn/vimfung/luascriptcore/LuaValue;)Lcn/vimfung/luascriptcore/LuaValue;");

Expand Down Expand Up @@ -200,8 +203,8 @@ static LuaValue* _luaClassGetterHandler (cn::vimfung::luascriptcore::modules::oo
if (lua_gettop(state) > 0 && lua_isuserdata(state, 1))
{
//表示有实例对象传入
void **ref = (void **)lua_touserdata(state, 1);
jobject instance = (jobject)*ref;
LuaJavaObjectDescriptor **ref = (LuaJavaObjectDescriptor **)lua_touserdata(state, 1);
jobject instance = (jobject)(*ref) -> getObject();

jmethodID getFieldId = env -> GetMethodID(LuaJavaType::luaObjectClass(env), "_getField", "(Ljava/lang/String;)Lcn/vimfung/luascriptcore/LuaValue;");

Expand Down Expand Up @@ -240,8 +243,8 @@ static void _luaClassSetterHandler (cn::vimfung::luascriptcore::modules::oo::Lua
if (lua_gettop(state) > 0 && lua_isuserdata(state, 1))
{
//表示有实例对象传入
void **ref = (void **)lua_touserdata(state, 1);
jobject instance = (jobject)*ref;
LuaJavaObjectDescriptor **ref = (LuaJavaObjectDescriptor **)lua_touserdata(state, 1);
jobject instance = (jobject)(*ref) -> getObject();

jmethodID setFieldId = env -> GetMethodID(LuaJavaType::luaObjectClass(env), "_setField", "(Ljava/lang/String;Lcn/vimfung/luascriptcore/LuaValue;)V");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,77 @@
//

#include "LuaJavaObjectDescriptor.h"
#include "LuaJavaEnv.h"
#include "LuaDefine.h"
#include "LuaJavaType.h"
#include "LuaObjectClass.h"

LuaJavaObjectDescriptor::LuaJavaObjectDescriptor(jobject object)
: LuaObjectDescriptor(object)
{
JNIEnv *env = LuaJavaEnv::getEnv();

//添加引用
setObject((const void *)env -> NewGlobalRef(object));

LuaJavaEnv::resetEnv(env);
}

LuaJavaObjectDescriptor::~LuaJavaObjectDescriptor()
{
JNIEnv *env = LuaJavaEnv::getEnv();

//移除引用
env -> DeleteGlobalRef((jobject)getObject());

LuaJavaEnv::resetEnv(env);
}

void LuaJavaObjectDescriptor::push(LuaContext *context)
{
bool process = false;

JNIEnv *env = LuaJavaEnv::getEnv();

jobject obj = (jobject)getObject();
if (env -> IsInstanceOf(obj, LuaJavaType::luaObjectClass(env)))
{
//对LuaObjectClass的类型对象需要进行特殊处理
lua_State *state = context -> getLuaState();

//获取关联引用
void **ref = LuaJavaEnv::getAssociateInstanceRef(obj);
if (ref != NULL)
{
lua_pushlightuserdata(state, ref);

LuaJavaObjectDescriptor *objDesc = (LuaJavaObjectDescriptor *)*ref;
cn::vimfung::luascriptcore::modules::oo::LuaObjectClass *objectClass = (cn::vimfung::luascriptcore::modules::oo::LuaObjectClass *)objDesc -> getUserdata();

if (objectClass != NULL)
{
//将其关联元表
luaL_getmetatable(state, objectClass->getName().c_str());
if (lua_istable(state, -1))
{
lua_setmetatable(state, -2);
}
else
{
lua_pop(state, 1);
}
}

process = true;
}

}

LuaJavaEnv::resetEnv(env);

if (!process)
{
//调用父类方法
LuaObjectDescriptor::push(context);
}

}
Loading

0 comments on commit 2779a37

Please sign in to comment.