mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-21 01:29:29 +02:00
* pas2jni: Fixed memory leaks when using method pointers.
git-svn-id: trunk@32561 -
This commit is contained in:
parent
cddbe1b83d
commit
3c32f814de
@ -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;');
|
||||
|
Loading…
Reference in New Issue
Block a user