* pas2jni: Fixed memory leaks when using method pointers.

git-svn-id: trunk@32561 -
This commit is contained in:
yury 2015-12-01 14:22:31 +00:00
parent cddbe1b83d
commit 3c32f814de

View File

@ -742,8 +742,11 @@ begin
if s <> '' then
Fps.WriteLn(s);
end;
if UseTempObjVar then
if UseTempObjVar then begin
Fps.WriteLn('__objvar: ' + d.Parent.Name + ';');
if Variable.VarType.DefType = dtProcType then
Fps.WriteLn('__mvar: TMethod;');
end;
if TempRes <> '' then begin
s:=TempRes + ': ';
if IsObj and (ProcType in [ptConstructor, ptDestructor]) then
@ -836,8 +839,8 @@ begin
if ProcType = ptProcedure then begin
ASSERT(Count = i + 1);
if Variable.VarType.DefType = dtProcType then begin
Fps.WriteLn(Format('_RefMethodPtr(_env, TMethod(%s), False);', [s]));
ss:=Format('_RefMethodPtr(_env, TMethod(%s), True);', [s]);
Fps.WriteLn(Format('__mvar:=TMethod(%s);', [s]));
ss:=Format('_RefMethodPtr(_env, TMethod(%s), True); _RefMethodPtr(_env, __mvar, False);', [s]);
end;
s:=s + ':=' + JniToPasType(TVarDef(Items[i]).VarType, Items[i].Name, False);
end;
@ -1218,20 +1221,8 @@ begin
Fps.WriteLn;
Fps.WriteLn(Format('function %sGetHandler(env: PJNIEnv; jobj: jobject; const ci: _TJavaClassInfo): %s.%s;',
[GetClassPrefix(d), d.Parent.Name, d.Name]));
Fps.WriteLn('var mpi: _TMethodPtrInfo;');
Fps.WriteLn('begin');
Fps.IncI;
Fps.WriteLn('Result:=nil;');
Fps.WriteLn('mpi:=_TMethodPtrInfo(_GetPasObj(env, jobj, ci, False));');
Fps.WriteLn('if mpi = nil then exit;');
Fps.WriteLn('if mpi.Index = 0 then');
Fps.WriteLn('TMethod(Result):=mpi.RealMethod', 1);
Fps.WriteLn('else');
Fps.WriteLn('with TMethod(Result) do begin', 1);
Fps.WriteLn('Data:=pointer(ptruint(-integer(mpi.Index)));', 2);
Fps.WriteLn(Format('Code:=@%s.Handler;', [hclass]), 2);
Fps.WriteLn('end;', 1);
Fps.DecI;
Fps.WriteLn(Format('TMethod(Result):=_GetMethodPtrHandler(env, jobj, @%s.Handler, %s);', [hclass, GetTypeInfoVar(d)]), 1);
Fps.WriteLn('end;');
exit;
@ -1247,10 +1238,10 @@ begin
Fjs.WriteLn(Format('public static class %s extends %s.system.MethodPtr {', [d.Name, JavaPackage]));
Fjs.IncI;
Fjs.WriteLn(Format('private String HandlerSig = "%s";', [GetProcSignature(d)]));
Fjs.WriteLn(Format('protected %s(long objptr, boolean cleanup) { }', [d.Name]));
Fjs.WriteLn(Format('public %s(Object Obj, String MethodName) { Init(Obj, MethodName, HandlerSig); }', [d.Name]));
Fjs.WriteLn(Format('public %s() { Init(this, "Execute", HandlerSig); }', [d.Name]));
Fjs.WriteLn(Format('{ mSignature = "%s"; }', [GetProcSignature(d)]));
Fjs.WriteLn(Format('protected %s(long objptr, boolean cleanup) { _pasobj=objptr; }', [d.Name]));
Fjs.WriteLn(Format('public %s(Object Obj, String MethodName) { mObject=Obj; mName=MethodName; }', [d.Name]));
Fjs.WriteLn(Format('public %s() { mObject=this; mName="Execute"; }', [d.Name]));
Fjs.WriteLn(Format('protected %s throws NoSuchMethodException { throw new NoSuchMethodException(); }', [GetJavaProcDeclaration(d, 'Execute')]));
Fjs.DecI;
Fjs.WriteLn('}');
@ -1456,7 +1447,7 @@ begin
Fps.DecI;
Fps.WriteLn('end;');
AddNativeMethod(d, '_TMethodPtrInfo_Init', 'Init', Format('(Ljava/lang/Object;%s%s)V', [JNITypeSig[btString], JNITypeSig[btString]]));
AddNativeMethod(d, '_TMethodPtrInfo_Init', '__Init', Format('(Ljava/lang/Object;%s%s)V', [JNITypeSig[btString], JNITypeSig[btString]]));
Fps.WriteLn;
Fps.WriteLn('procedure _TMethodPtrInfo_Release(env: PJNIEnv; _self: JObject);' + JniCaliing);
@ -1473,11 +1464,14 @@ begin
Fjs.WriteLn;
Fjs.WriteLn('public static class MethodPtr extends PascalObjectEx {');
Fjs.IncI;
Fjs.WriteLn('private native void __Init(Object Obj, String MethodName, String MethodSignature);');
Fjs.WriteLn('private native void __Destroy();');
Fjs.WriteLn('protected native void Init(Object Obj, String MethodName, String MethodSignature);');
Fjs.WriteLn('protected MethodPtr() { _cleanup=true; }');
Fjs.WriteLn('public void __Release() { if (_pasobj != 0) __Destroy(); }');
Fjs.WriteLn('protected Object mObject;');
Fjs.WriteLn('protected String mName;');
Fjs.WriteLn('protected String mSignature;');
Fjs.WriteLn('protected void Init() { __Init(mObject, mName, mSignature); }');
Fjs.WriteLn('protected MethodPtr() { _cleanup=true; _pasobj=-1; }');
Fjs.WriteLn('public void __Release() { if (_pasobj > 0) __Destroy(); }');
Fjs.DecI;
Fjs.WriteLn('}');
Fjs.WriteLn;
@ -2283,7 +2277,6 @@ begin
Fps.WriteLn('var c: JClass;');
Fps.WriteLn('begin');
Fps.IncI;
Fps.WriteLn('RefCnt:=1;');
Fps.WriteLn('if (JavaObj = nil) or (AMethodName = '''') then exit;');
Fps.WriteLn('c:=env^^.GetObjectClass(env, JavaObj);');
Fps.WriteLn('if c = nil then exit;');
@ -2363,11 +2356,11 @@ begin
Fps.WriteLn('i:=-integer(ptruint(m.Data));');
Fps.WriteLn(Format('if (i > 0) and (i <= %d) then begin', [MaxMethodPointers]));
Fps.WriteLn('mpi:=_MethodPointers[i - 1];', 1);
Fps.WriteLn('InterlockedIncrement(mpi.RefCnt);', 1);
Fps.WriteLn('end');
Fps.WriteLn('else begin');
Fps.WriteLn('mpi:=_TMethodPtrInfo.Create(env, nil, '''', '''');', 1);
Fps.WriteLn('mpi.RealMethod:=m;', 1);
Fps.WriteLn('InterlockedIncrement(mpi.RefCnt);', 1);
Fps.WriteLn('end;');
Fps.WriteLn('finally', -1);
Fps.WriteLn('_MethodPointersCS.Leave;');
@ -2377,6 +2370,29 @@ begin
Fps.DecI;
Fps.WriteLn('end;');
Fps.WriteLn;
Fps.WriteLn('function _GetMethodPtrHandler(env: PJNIEnv; jobj: jobject; hptr: pointer; const ci: _TJavaClassInfo): TMethod;');
Fps.WriteLn('var mpi: _TMethodPtrInfo;');
Fps.WriteLn('begin');
Fps.IncI;
Fps.WriteLn( 'Result.Data:=nil; Result.Code:=nil;');
Fps.WriteLn( 'mpi:=_TMethodPtrInfo(_GetPasObj(env, jobj, ci, False));');
Fps.WriteLn( 'if mpi = nil then exit;');
Fps.WriteLn( 'if pointer(mpi) = pointer(ptruint(-1)) then begin');
Fps.WriteLn( 'env^^.CallVoidMethodA(env, jobj, env^^.GetMethodID(env, ci.ClassRef, ''Init'', ''()V''), nil);', 1);
Fps.WriteLn( 'Result:=_GetMethodPtrHandler(env, jobj, hptr, ci);', 1);
Fps.WriteLn( 'exit;', 1);
Fps.WriteLn( 'end;');
Fps.WriteLn( 'if mpi.Index = 0 then');
Fps.WriteLn( 'TMethod(Result):=mpi.RealMethod', 1);
Fps.WriteLn( 'else');
Fps.WriteLn( 'with TMethod(Result) do begin', 1);
Fps.WriteLn( 'Data:=pointer(ptruint(-integer(mpi.Index)));', 2);
Fps.WriteLn( 'Code:=hptr;', 2);
Fps.WriteLn( 'end;', 1);
Fps.DecI;
Fps.WriteLn('end;');
// Set support
Fps.WriteLn;
Fps.WriteLn('function _GetIntObjValue(env: PJNIEnv; jobj: jobject; const ci: _TJavaClassInfo): longint;');