Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2017-01

ppcjvm issues

35 messages · 11 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Jon Foster

I've been working on building an app for Android using the FPC's JVM target. I'm using fpc 3.0.0. I've run into a couple of things that I'm not sure if they're bugs or I just don't know what I'm doing. I was using fpc to avoid having to learn Java and have discovered that's not entirely possible. :-/

The first issue I ran into is this:

procedure Cppp1Activity.onResume;
begin
     inherited onResume;
     with AAAlertDialog.InnerBuilder(self) do begin
         setTitle(R.strings.app_name);
     end;
end;

Cppp1Activity is a descendant of AAActivity. I'm overriding the onResume method. The problem I ran into was with the AAAlertDialog.InnerBuilder class. I can create an object of that class without incident. However if I try to call any of the methods (tried several) I get a "Class Cast" exception reported in the Android log and the app goes *poof*. I also tried just chaining the call like
"AAAlertDialog.InnerBuilder(self).setTitle(R.strings.app_name);", and I tried this in the "Activity.onCreate" method with the same result. And yes "R.strings.app_name" points to an actual resource and I generated a "resources.pas" with the "R" class fresh for this test.

The second issue I ran into:

function f(x, y: integer): float;
begin
     result:=float(dy)/float(dx)
end;

When attempting to compile this it tells me that "float" is undefined. I think I'm missing something here. "float" is the native Java name for their base floating point type and its a valid type for FPC. If I use "single" instead it will compile. Seems odd.

THX - Jon

Sent from my Debian Linux workstation -- http://www.debian.org/intro/about Jon Foster JF Possibilities, Inc. 541-410-2760 Making computers work for you!

Reply by email

Tomas Hajny
to Jon Foster

On Sat, January 7, 2017 03:12, Jon Foster wrote:

Hello,

You didn't mention that you weren't subscribed to the list, but since this seemed to be the case, I included your address in Cc:.

.
.

Show quoted text 12 lines
The second issue I ran into: function f(x, y: integer): float; begin result:=float(dy)/float(dx) end; When attempting to compile this it tells me that "float" is undefined. I think I'm missing something here. "float" is the native Java name for their base floating point type and its a valid type for FPC. If I use "single" instead it will compile. Seems odd.

I can't comment the first part, but where exactly is a type named "float" defined in FPC (which unit)? E.g. single is defined in unit System and thus available for all FPC programs automatically. If some unit defines "float" (not sure about that, but it might be the case). I can see the System unit for Java defining "jfloat" as an alias to single - maybe you meant that one?

Hope this helps

Tomas

Reply by email

Bart
to Tomas Hajny
Tomas Hajny wrote
I can't comment the first part, but where exactly is a type named "float" defined in FPC (which unit)?

Float is defined in math unit.
It is an alias to float128, if that type exists, else extende, or else to double, or else to single.

Bart

Reply by email

Jon Foster
to Tomas Hajny: You didn't mention that you weren't subscribed to the list, but since this seemed to be…
Tomas Hajny wrote 7 lines
On Sat, January 7, 2017 03:12, Jon Foster wrote: Hello, You didn't mention that you weren't subscribed to the list, but since this seemed to be the case, I included your address in Cc:.

Thanks for this. I get a lot of mail from the FPC lists ... but it looks like its from the devel list. I originally subscribed to this list in Feb.
2015. I must have been evicted. Not sure why. I've re-subscribed. I'll try not to get booted again.

Show quoted text 20 lines
> The second issue I ran into: > > function f(x, y: integer): float; > begin > result:=float(dy)/float(dx) > end; > > When attempting to compile this it tells me that "float" is undefined. I > think I'm missing something here. "float" is the native Java name for > their > base floating point type and its a valid type for FPC. If I use "single" > instead it will compile. Seems odd. I can't comment the first part, but where exactly is a type named "float" defined in FPC (which unit)? E.g. single is defined in unit System and thus available for all FPC programs automatically. If some unit defines "float" (not sure about that, but it might be the case). I can see the System unit for Java defining "jfloat" as an alias to single - maybe you meant that one? Hope this helps

Yes, you're right. Sorry too many languages to deal with. And working in this quasi-java-fpc world is bending my brain. So to sum up:

fpc doesn't have a float type.
Java does. Since its in the "java" namespace its named "Jfloat" in FPC. The native FPC equivalent is single.

THX - Jon

Sent from my Debian Linux laptop -- http://www.debian.org/intro/about Jon Foster JF Possibilities, Inc. 541-410-2760 Making computers work for you!

Reply by email

leledumbo
to Jon Foster: I've been working on building an app for Android using the FPC's JVM target. I'm using…
Show quoted text 9 lines
The first issue I ran into is this: procedure Cppp1Activity.onResume; begin inherited onResume; with AAAlertDialog.InnerBuilder(self) do begin setTitle(R.strings.app_name); end; end;

I don't check by running the code directly, but looking at the source code:

  AAAlertDialog = class external 'android.app' name 'AlertDialog' (AADialog,
ACDialogInterface)
  public
    type
      InnerBuilder = class;
      Arr1InnerBuilder = array of InnerBuilder;
      Arr2InnerBuilder = array of Arr1InnerBuilder;
      Arr3InnerBuilder = array of Arr2InnerBuilder;
      InnerBuilder = class external 'android.app' name 'Builder' (JLObject)

InnerBuilder doesn't look like anything callable.

Reading the offical reference
(https://developer.android.com/guide/topics/ui/dialogs.html#AlertDialog), I guess you need to instantiate it first and only then call its methods:

var
  Builder: AAAlertDialog.InnerBuilder;
  Dialog: AAAlertDialog;
...
  Builder := AAAlertDialog.InnerBuilder.Create(Self); // inside any
Cppp1Activity method so Self refers to Cppp1Activity instance
  Dialog := Builder.setTitle(R.strings.app_name).create_; // note the '_'
Show quoted text 5 lines
When attempting to compile this it tells me that "float" is undefined. I think I'm missing something here. "float" is the native Java name for their base floating point type and its a valid type for FPC. If I use "single" instead it will compile. Seems odd.

Pascal's Single maps to Java's float. There's another float type defined in Math unit but that's created for the routines inside the unit. Java's primitive type is not available in FPC JVM, use Pascal's type after mapping from Java. The class version (which should automatically (un)box) is available, though. So if you insist, simply use JLFloat.

View this message in context: http://free-pascal-general.1045716.n5.nabble.com/ppcjvm-issues-tp5727228p5727238.html Sent from the Free Pascal - General mailing list .

Reply by email

Lars
to Jon Foster: Thanks for this. I get a lot of mail from the FPC lists ... but it looks like its from…
Jon Foster wrote 39 lines
On 01/07/2017 03:06 AM, Tomas Hajny wrote: > On Sat, January 7, 2017 03:12, Jon Foster wrote: > > > > Hello, > > > You didn't mention that you weren't subscribed to the list, but since > this seemed to be the case, I included your address in Cc:. Thanks for this. I get a lot of mail from the FPC lists ... but it looks like its from the devel list. I originally subscribed to this list in Feb. 2015. I must have been evicted. Not sure why. I've re-subscribed. I'll try not to get booted again. >> The second issue I ran into: >> >> >> function f(x, y: integer): float; begin result:=float(dy)/float(dx) >> end; >> >> When attempting to compile this it tells me that "float" is >> undefined. I think I'm missing something here. "float" is the native >> Java name for >> their base floating point type and its a valid type for FPC. If I use >> "single" >> instead it will compile. Seems odd. > I can't comment the first part, but where exactly is a type named > "float" > defined in FPC (which unit)? E.g. single is defined in unit System and > thus available for all FPC programs automatically. If some unit defines > "float" (not sure about that, but it might be the case). I can see the > System unit for Java defining "jfloat" as an alias to single - maybe > you meant that one? > > Hope this helps > Yes, you're right. Sorry too many languages to deal with. And working in this quasi-java-fpc world is bending my brain.

This is one of the main reasons, I'm afraid of things like jvm/llvm and even objectivefpc macOS mode because your brain starts juggling multiple ideologies.. and your brain must have a modeswitch that is fuzzy (not always switched in one mode, sometimes several) ;-)

Show quoted text 5 lines
So to sum up: fpc doesn't have a float type. Java does. Since its in the "java" namespace its named "Jfloat" in FPC. The native FPC equivalent is single.

Well, fpc has Math unit which has float related tools and type that is not quite the same. But as another poster said, that float in math unit doesn't match up to Java's

Reply by email

Sven Barth
to Jon Foster: I've been working on building an app for Android using the FPC's JVM target. I'm using…
Jon Foster wrote 26 lines
I've been working on building an app for Android using the FPC's JVM target. I'm using fpc 3.0.0. I've run into a couple of things that I'm not sure if they're bugs or I just don't know what I'm doing. I was using fpc to avoid having to learn Java and have discovered that's not entirely possible. :-/ The first issue I ran into is this: procedure Cppp1Activity.onResume; begin inherited onResume; with AAAlertDialog.InnerBuilder(self) do begin setTitle(R.strings.app_name); end; end; Cppp1Activity is a descendant of AAActivity. I'm overriding the onResume method. The problem I ran into was with the AAAlertDialog.InnerBuilder class. I can create an object of that class without incident. However if I try to call any of the methods (tried several) I get a "Class Cast" exception reported in the Android log and the app goes *poof*. I also tried just chaining the call like "AAAlertDialog.InnerBuilder(self).setTitle(R.strings.app_name);", and I tried this in the "Activity.onCreate" method with the same result. And yes "R.strings.app_name" points to an actual resource and I generated a "resources.pas" with the "R" class fresh for this test.

Here's what I had done in my Android application way back at Christmas 2011 (
http://lists.lazarus-ide.org/pipermail/lazarus/2011-December/134414.html ):

=== code begin ===

function TTrainTypeActivity.onCreateDialog(aID: jint): AADialog;
var
  builder: AAAlertDialog.InnerBuilder;
begin
  case aID of
    DialogIDDelete: begin
      builder := AAAlertDialog.InnerBuilder.Create(Self);
      builder.setMessage(JLString('Are you sure you want to delete train ' +
        'type ''' + fDataHelper.NameOfTrainType[fSelectedID] + '''?'));
      builder.setPositiveButton(JLString('Yes'), Self);
      builder.setNegativeButton(JLString('No'), Self);
      Result := builder.create_;
    end;
    else
      Result := Nil;
  end;
end;

=== code end ===

I know it's onCreateDialog() and not onResume(), but it should be the same principle.

Though doesn't an activity itself already have a setTitle() method? At least that's what I had used in my onCreate()...

Regards,
Sven

Reply by email

Jon Foster
to leledumbo: I don't check by running the code directly, but looking at the source code: AAAlertDialog…
leledumbo wrote 34 lines
> The first issue I ran into is this: > > procedure Cppp1Activity.onResume; > begin > inherited onResume; > with AAAlertDialog.InnerBuilder(self) do begin > setTitle(R.strings.app_name); > end; > end; I don't check by running the code directly, but looking at the source code: AAAlertDialog = class external 'android.app' name 'AlertDialog' (AADialog, ACDialogInterface) public type InnerBuilder = class; Arr1InnerBuilder = array of InnerBuilder; Arr2InnerBuilder = array of Arr1InnerBuilder; Arr3InnerBuilder = array of Arr2InnerBuilder; InnerBuilder = class external 'android.app' name 'Builder' (JLObject) InnerBuilder doesn't look like anything callable. Reading the offical reference (https://developer.android.com/guide/topics/ui/dialogs.html#AlertDialog), I guess you need to instantiate it first and only then call its methods: var Builder: AAAlertDialog.InnerBuilder; Dialog: AAAlertDialog; ... Builder := AAAlertDialog.InnerBuilder.Create(Self); // inside any Cppp1Activity method so Self refers to Cppp1Activity instance Dialog := Builder.setTitle(R.strings.app_name).create_; // note the '_'

Thanks! Yes, you're right. I'm having a hard time understanding how the FPC semantics fit the Java semantics. This is complicated because I'm trying to learn Android, and to some extent, by extension, I'm getting forced into Java too. So I'm real unclear about what all the Java examples I'm seeing are actually doing. Been working with "object pascal" since Delphi 1/2. :-)

So the take away I see here is that I have to remember to use class.create(...) to create objects from any Java class, not just FPC ones.

So that leaves me with the question: What about destructors? Must I call free/destroy on all objects I create, or do they self-destruct? If so destroy or free? From what I've seen of Java everything self destructs, probably when a usage count hits 0. But I don't know. Perhaps calling "destroy" is needed to release my claim on it? I was going to try calling it and see if it blows. :-D

Yes, I figured out "create_" just as I figured out "InnerBuilder", instead of "Builder". Not sure why that name was changed. I've learned I need to cross reference the Android docs back to androidr14.inc & pas.

Show quoted text 10 lines
> When attempting to compile this it tells me that "float" is undefined. I > think I'm missing something here. "float" is the native Java name for > their > base floating point type and its a valid type for FPC. If I use "single" > instead it will compile. Seems odd. Pascal's Single maps to Java's float. There's another float type defined in Math unit but that's created for the routines inside the unit. Java's primitive type is not available in FPC JVM, use Pascal's type after mapping from Java. The class version (which should automatically (un)box) is available, though. So if you insist, simply use JLFloat.

Yes, thank you. Tomas set me straight on this.

Jon Foster JF Possibilities, Inc.

Reply by email

Jon Foster
to Sven Barth: Here's what I had done in my Android application way back at Christmas 2011 (…
Sven Barth wrote 65 lines
On 07.01.2017 03:12, Jon Foster wrote: > I've been working on building an app for Android using the FPC's JVM > target. I'm using fpc 3.0.0. I've run into a couple of things that I'm > not sure if they're bugs or I just don't know what I'm doing. I was > using fpc to avoid having to learn Java and have discovered that's not > entirely possible. :-/ > > The first issue I ran into is this: > > procedure Cppp1Activity.onResume; > begin > inherited onResume; > with AAAlertDialog.InnerBuilder(self) do begin > setTitle(R.strings.app_name); > end; > end; > > Cppp1Activity is a descendant of AAActivity. I'm overriding the onResume > method. The problem I ran into was with the AAAlertDialog.InnerBuilder > class. I can create an object of that class without incident. However if > I try to call any of the methods (tried several) I get a "Class Cast" > exception reported in the Android log and the app goes *poof*. I also > tried just chaining the call like > "AAAlertDialog.InnerBuilder(self).setTitle(R.strings.app_name);", and I > tried this in the "Activity.onCreate" method with the same result. And > yes "R.strings.app_name" points to an actual resource and I generated a > "resources.pas" with the "R" class fresh for this test. Here's what I had done in my Android application way back at Christmas 2011 ( http://lists.lazarus-ide.org/pipermail/lazarus/2011-December/134414.html ): === code begin === function TTrainTypeActivity.onCreateDialog(aID: jint): AADialog; var builder: AAAlertDialog.InnerBuilder; begin case aID of DialogIDDelete: begin builder := AAAlertDialog.InnerBuilder.Create(Self); builder.setMessage(JLString('Are you sure you want to delete train ' + 'type ''' + fDataHelper.NameOfTrainType[fSelectedID] + '''?')); builder.setPositiveButton(JLString('Yes'), Self); builder.setNegativeButton(JLString('No'), Self); Result := builder.create_; end; else Result := Nil; end; end; === code end === I know it's onCreateDialog() and not onResume(), but it should be the same principle. Though doesn't an activity itself already have a setTitle() method? At least that's what I had used in my onCreate()... Regards, Sven

Yes, same principal. Since this is a one time in the lifetime of the app use dialog I didn't see the point of building it into the onCreateDialog() / onPrepareDialog() methods. Its going to be shown the first time someone launches my app and then never seen again unless uninstalled / reinstalled, data erased, installed on another device, ...

What I don't quite get from your example is using "self" as the second argument to setPositiveButton() & setNegativeButton. That parameter is asking for an OnClickListener() class. When I tried that I received a compile time error as I expected.

Yes, the AAActivity class has a "setTitle()" method. However it sets the title for the activity. Where as the AAAlertDialog.InnnerBuilder.setTitle() method sets a title on the dialog window. I actually decided I like it better without, but I'm still experimenting.

THX - Jon

Jon Foster JF Possibilities, Inc.

Reply by email

Sven Barth
to Jon Foster
"Jon Foster" wrote
What I don't quite get from your example is using "self" as the second

argument to setPositiveButton() & setNegativeButton. That parameter is asking for an OnClickListener() class. When I tried that I received a compile time error as I expected.

That's because in my case the activity also implements the corresponding interface, just ignore that ;)

Yes, the AAActivity class has a "setTitle()" method. However it sets the

title for the activity. Where as the AAAlertDialog.InnnerBuilder.setTitle() method sets a title on the dialog window. I actually decided I like it better without, but I'm still experimenting.

Okay.

Oh and regarding Free: on JVM garbage collection is used also with FPC.

Regards,
Sven

Reply by email

Michael Schnell
to Jon Foster: Thanks! Yes, you're right. I'm having a hard time understanding how the FPC semantics fit…
Jon Foster wrote 5 lines
On 01/07/2017 10:39 AM, leledumbo wrote: So that leaves me with the question: What about destructors? Must I call free/destroy on all objects I create, or do they self-destruct? If so destroy or free?

AFAIU, in fpc destroying any objects is mandatory. And this close to always needs to be done with "Free" (which inside the class finally calls Destroy).

If destroying an object is not necessary, the class should provide a dummy Free procedure. So the application programmer always can/should use Free.

-Michael

Reply by email

Sven Barth
to Michael Schnell
"Michael Schnell" wrote 6 lines
On 10.01.2017 05:13, Jon Foster wrote: > > On 01/07/2017 10:39 AM, leledumbo wrote: > > So that leaves me with the question: What about destructors? Must I call

free/destroy on all objects I create, or do they self-destruct? If so destroy or free?

AFAIU, in fpc destroying any objects is mandatory. And this close to

always needs to be done with "Free" (which inside the class finally calls Destroy).

If destroying an object is not necessary, the class should provide a

dummy Free procedure. So the application programmer always can/should use Free.

We're talking about JVM here where garbage collections *must* be used. So FPC does as well for that target.

Regards,
Sven

Reply by email

Jon Foster
to Sven Barth
Sven Barth wrote 24 lines
Am 11.01.2017 08:54 schrieb "Michael Schnell" < >: > > On 10.01.2017 05:13, Jon Foster wrote: >> >> On 01/07/2017 10:39 AM, leledumbo wrote: >> >> So that leaves me with the question: What about destructors? Must I call free/destroy on all objects I create, or do they self-destruct? If so destroy or free? > > > AFAIU, in fpc destroying any objects is mandatory. And this close to always needs to be done with "Free" (which inside the class finally calls Destroy). > > If destroying an object is not necessary, the class should provide a dummy Free procedure. So the application programmer always can/should use Free. We're talking about JVM here where garbage collections *must* be used. So FPC does as well for that target.

It goes against soooo many years of working with Object Pascal... but I'll let the JVM destroy them.

Thanks!

Jon Foster JF Possibilities, Inc.

Reply by email

Michael Schnell
to Sven Barth: free/destroy on all objects I create, or do they self-destruct? If so destroy or free?…
Sven Barth wrote
We're talking about JVM here where garbage collections *must* be used. So FPC does as well for that target.

This of course is true. But if the class code is in fpc, fpc paradigms should be adhered, as well. and here the fpc code *can* e.g. explicitly allocate stuff that needs to be freed later, or e.g. can open a connection to whatever that needs to be closed later, and so (if not using ref counted objects) with such classes destroy() needs to be called (via the free() chain).

Regarding this, IMHO it would be good practice to always provide destroy and free, and if it's empty it does not harm to call it.

-Michael

Reply by email

Lars
to Michael Schnell
Michael Schnell wrote 17 lines
On 11.01.2017 11:25, Sven Barth wrote: > > We're talking about JVM here where garbage collections *must* be used. > So FPC does as well for that target. > > This of course is true. But if the class code is in fpc, fpc paradigms should be adhered, as well. and here the fpc code *can* e.g. explicitly allocate stuff that needs to be freed later, or e.g. can open a connection to whatever that needs to be closed later, and so (if not using ref counted objects) with such classes destroy() needs to be called (via the free() chain). Regarding this, IMHO it would be good practice to always provide destroy and free, and if it's empty it does not harm to call it.

What if you are porting code to a non jvm... if you copy and paste something and it has no free, you're screwed.

i.e. say you have some JVM algorithms that now need to be used in win32 or bsd using the regular fpc compilation.... can't port them without inspecting the code carefully for missing free's

Reply by email

Michael Schnell
to Lars
Lars wrote
What if you are porting code to a non jvm... if you copy and paste something and it has no free, you're screwed.

Sorry. I don't understand. AFAIK, in a non jvm project, free() always is provided (and used).

i.e. say you have some JVM algorithms that now need to be used in win32 or bsd using the regular fpc compilation.... can't port them without inspecting the code carefully for missing free's

IMHOP, JVM based (or any other) pascal classes, that does not provide free() - even if dummy - simply should not exist.

-Michael

Reply by email

Lars
to Michael Schnell
Michael Schnell wrote 6 lines
On 14.01.2017 20:36, Lars wrote: > What if you are porting code to a non jvm... if you copy and paste > something and it has no free, you're screwed. Sorry. I don't understand. AFAIK, in a non jvm project, free() always is provided (and used).

If you have a jvm project with lots of code and now want to start using this code in another regular mode objfpc unix/win32 application...

Sorry I'm not familiar with the jvm fpc project (I have been meaning to try it).

Delphi has some similar issues with garbage collected iOS development where they have provided some fake release/free system to try solve the issue, which, has the side effect of making garbage collected programming much like non garbage collected programming which in a way defeats the purpose..

i.e. if you have a fake free procedure that can be called, then why program in garbage collection in the first place..

Reply by email

Unknown author
to Lars
Lars wrote
i.e. if you have a fake free procedure that can be called, then why program in garbage collection in the first place..

can you not IFDEF it so that it does actual work in a non-garbage collecting environment? seems to be the obvious answer there...

NOTE: No off-list assistance is given without prior approval. *Please keep mailing list traffic on the list* unless private contact is specifically requested and granted.

Reply by email

Michael Schnell
to Lars: If you have a jvm project with lots of code and now want to start using this code in…
Lars wrote
If you have a jvm project with lots of code and now want to start using this code in another regular mode objfpc unix/win32 application...

Exactly this as the point I wanted to express. Even when coding an fpc application or library for use with jvm, free (and destroy) should be used and provided in the normal way good old Object Pascal requires. If jvm does garbage collection under the hood (and not momentarily adheres to free, as we are used to with Object Pascal) this should be handled as a hidden implementation detail and as little as possible be communicated outside, so that using this code in another regular mode objfpc unix/win32 application can be done as seamlessly as possible .

-Michael

Reply by email

Jon Foster
to Michael Schnell
Michael Schnell wrote 11 lines
On 17.01.2017 19:07, Lars wrote: > If you have a jvm project with lots of code and now want to start using > this code in another regular mode objfpc unix/win32 application... Exactly this as the point I wanted to express. Even when coding an fpc application or library for use with jvm, free (and destroy) should be used and provided in the normal way good old Object Pascal requires. If jvm does garbage collection under the hood (and not momentarily adheres to free, as we are used to with Object Pascal) this should be handled as a hidden implementation detail and as little as possible be communicated outside, so that using this code in another regular mode objfpc unix/win32 application can be done as seamlessly as possible .

I agree for seamless compatibility "free" / "destroy" should be provided. As far as I can tell the JVM implementation of TObject does provide these. Using the native Java/Android objects is a lot like using Lazarus / Delphi / TComponent based classes. You create them and whoever you specify as the owner frees them. In this case the JVM is freeing them. But that's not a detail I need concern myself with.

That said, all of the code in my project was written and tested in plain old native compiled code running on my Linux box. Only the UI code is unique to Android. As such I've not run into any problems creating and freeing my native FPC based components. I haven't tried freeing/destroying Java/Android components. I imagine its going to tell me that those methods don't exist on those objects, since those class libraries don't provide them. But maybe FPC has hidden that detail as well. When I get a moment I'll give it a whirl, 'cause I've had many years of training to free what I create. I started my Pascal journey with Delphi 1/2 in '96.

THX - Jon

Sent from my Debian Linux workstation -- http://www.debian.org/intro/about Jon Foster JF Possibilities, Inc. 541-410-2760 Making computers work for you!

Reply by email

Jon Foster
to Jon Foster
Jon Foster wrote 30 lines
On 01/18/2017 01:16 AM, Michael Schnell wrote: > On 17.01.2017 19:07, Lars wrote: >> If you have a jvm project with lots of code and now want to start using >> this code in another regular mode objfpc unix/win32 application... > Exactly this as the point I wanted to express. Even when coding an fpc > application or library for use with jvm, free (and destroy) should be > used and provided in the normal way good old Object Pascal requires. If > jvm does garbage collection under the hood (and not momentarily adheres > to free, as we are used to with Object Pascal) this should be handled as > a hidden implementation detail and as little as possible be communicated > outside, so that using this code in another regular mode objfpc > unix/win32 application can be done as seamlessly as possible . I agree for seamless compatibility "free" / "destroy" should be provided. As far as I can tell the JVM implementation of TObject does provide these. Using the native Java/Android objects is a lot like using Lazarus / Delphi / TComponent based classes. You create them and whoever you specify as the owner frees them. In this case the JVM is freeing them. But that's not a detail I need concern myself with. That said, all of the code in my project was written and tested in plain old native compiled code running on my Linux box. Only the UI code is unique to Android. As such I've not run into any problems creating and freeing my native FPC based components. I haven't tried freeing/destroying Java/Android components. I imagine its going to tell me that those methods don't exist on those objects, since those class libraries don't provide them. But maybe FPC has hidden that detail as well. When I get a moment I'll give it a whirl, 'cause I've had many years of training to free what I create. I started my Pascal journey with Delphi 1/2 in '96.

So as I thought Java/Android objects don't apparently have a free or destroy method, simulated or otherwise. But any classes defined in Pascal provide those methods, if they descend from the default TObject. I think I read somewhere that classes can be defined that descend from the base Java class but I haven't done it.

- Jon

Sent from my Debian Linux workstation -- http://www.debian.org/intro/about Jon Foster JF Possibilities, Inc. 541-410-2760 Making computers work for you!

Reply by email

Dmitry Boyarintsev
to Michael Schnell: AFAIU, in fpc destroying any objects is mandatory. And this close to always needs to be…
Michael Schnell wrote 5 lines
If destroying an object is not necessary, the class should provide a dummy Free procedure. So the application programmer always can/should use Free. Why dummy? if it should be like this
procedure TObject.Free;
begin
  if Selfnil then Self:=nil;
end;

Destroying object is not necessary, but dereferencing is. If the code keeps the reference to an object, it would not be collected.

For example. In pascal:
var
  b : TSomeClass;
begin
  b := TSomeClass.Create; // allocated
  ..
  b.Free;  // freed (b becomes an invalid pointer)
  ...
end.
JVM with dummy Free
var
  b : TSomeClass;
begin
  b := TSomeClass.Create; // allocated
  ..
  b.Free;  // does nothing (b remains a valid pointer)
  ...
end.// a might be freed after leaving  the scope of visibility
JVM with nil-ing Free.
var
  b : TSomeClass;
begin
  b := TSomeClass.Create; // allocated
  ..
  b.Free;  // derefering a, (a, become nil)
  ... // a might be Freed here somewhere, whenever gc occurs
end.

thanks,
Dmitry

Reply by email

Jonas Maebe
to Jon Foster: So as I thought Java/Android objects don't apparently have a free or destroy method,…
Jon Foster wrote
But any classes defined in Pascal provide those methods, if they descend from the default TObject. I think I read somewhere that classes can be defined that descend from the base Java class but I haven't done it.

All classes on the JVM descend from a Java class. The Java Runtime does not support classes that don't descend directly or indirectly from java.lang.Object.

Jonas

Reply by email

Jon Foster
to Dmitry Boyarintsev: procedure TObject.Free; begin if Selfnil then Self:=nil; end; Destroying object is not…
Dmitry Boyarintsev wrote 18 lines
On Tue, Jan 10, 2017 at 6:14 AM, Michael Schnell < > wrote: If destroying an object is not necessary, the class should provide a dummy Free procedure. So the application programmer always can/should use Free. Why dummy? if it should be like this procedure TObject.Free; begin if Selfnil then Self:=nil; end; Destroying object is not necessary, but dereferencing is. If the code keeps the reference to an object, it would not be collected. [...]

Correct me if I'm wrong: It would seem like that your free implementation doesn't actually do anything, other than fulfilling the obligation of having a "free". If I do this:

var
     o: TObject;
begin
     o:=TObject.create;
     { do something ... }
     o.free;
end.

Wouldn't "o" still contain a reference after "free" is called? In non-JVM FPC "self" is just another variable, who's origin is somewhat hidden by the compiler. The call to "o.free" would do something like "TObject.free(o)" where "o" is passed by *value* into the procedure variable "self". "Self" comes and goes with the scope of the "TObject.free" procedure. Which is why if I'm concerned about detecting whether or not "o" still contains a correct object reference I would need to do something like this: "o.free; o:=nil;" so I can test for "nil" later. Although I think FPC added a procedure to do that some time back. Yup, I see it "SysUtils.FreeAndNil".

I'm not sure of the specific semantics of the JVM calls but from what I read in the various FPC JVM related pages on the wiki it would seem to use similar semantics.

- Jon

Jon Foster JF Possibilities, Inc.

Reply by email

Jon Foster
to Jonas Maebe: All classes on the JVM descend from a Java class. The Java Runtime does not support…
Jonas Maebe wrote 8 lines
On 27/01/17 02:31, Jon Foster wrote: > But any classes defined in Pascal provide those methods, if they descend > from the default TObject. I think I read somewhere that classes can be > defined that descend from the base Java class but I haven't done it. All classes on the JVM descend from a Java class. The Java Runtime does not support classes that don't descend directly or indirectly from java.lang.Object.

Yes, BUT: TObject is provided by the "system" unit in FPC and although it descends from JLObject it provides basic FPC like semantics, including free/destroy. FPC treats " TMyClass = class ..." just like it does in the native code versions and TMyClass would descend from TObject inheriting its methods. So unless you tried to create a class which directly descended from JLObject, instead of TObject you inherit "free" and "destroy", so you can call them as you usually would.

Other than missing unit functionality I've found the JVM implementation makes Java seem very Pascal like. The devs have done a splendid job IMO. It did take me a while to find the Java lib equivalent of StrToInt. :-D

-Jon

Jon Foster JF Possibilities, Inc.

Reply by email

Dmitry Boyarintsev
to Jon Foster: Correct me if I'm wrong: It would seem like that your free implementation doesn't…
Jon Foster wrote 26 lines
Correct me if I'm wrong: It would seem like that your free implementation > doesn't actually do anything, other than fulfilling the obligation of > having a "free". If I do this: > var o: TObject; begin o:=TObject.create; { do something ... } o.free; end. Wouldn't "o" still contain a reference after "free" is called? In non-JVM FPC "self" is just another variable, who's origin is somewhat hidden by the compiler. The call to "o.free" would do something like "TObject.free(o)" where "o" is passed by *value* into the procedure variable "self". "Self" comes and goes with the scope of the "TObject.free" procedure. Which is why if I'm concerned about detecting whether or not "o" still contains a correct object reference I would need to do something like this: "o.free; o:=nil;" so I can test for "nil" later. Although I think FPC added a procedure to do that some time back. Yup, I see it "SysUtils.FreeAndNil". I'm not sure of the specific semantics of the JVM calls but from what I read in the various FPC JVM related pages on the wiki it would seem to use similar semantics.

Object Pascal semantic of calling .Free suggests that "o" would no longer be a valid object.
If a dummy Free method is available for JVM, then such semantic is violated.

However, if JVM free method would at least reset "o" reference to nil, then
the semantic of "o" being an invalid object remains.

It also suggests to the garbage collector that the memory could be recycled earlier, that the variable leaves the scope.

thanks,
Dmitry

Reply by email

Jonas Maebe
to Dmitry Boyarintsev
Dmitry Boyarintsev wrote
Object Pascal semantic of calling .Free suggests that "o" would no longer be a valid object. If a dummy Free method is available for JVM, then such semantic is violated.

Calling Free is not defined as "any further access to this object must now crash or return invalid data". It is defined as "if the instance is not nil, then it calls the destroy method, and next it calls FreeInstance". You could override FreeInstance to not free memory on any platform.

However, if JVM free method would at least reset "o" reference to nil, then the semantic of "o" being an invalid object remains.

There is no need to do this.

It also suggests to the garbage collector that the memory could be recycled earlier, that the variable leaves the scope.

That is true.

Jonas

Reply by email

Dmitry Boyarintsev
to Jonas Maebe
Jonas Maebe wrote 15 lines
It is defined as "if the instance is not nil, then it calls the destroy method, and next it calls FreeInstance". You could override FreeInstance to not free memory on any platform. However, if JVM free method would at least reset "o" reference to nil, > then the semantic of "o" being an invalid object remains. > There is no need to do this. It also suggests to the garbage collector that the memory could be > recycled earlier, that the variable leaves the scope. > That is true.

How about moving "nil"-ing of the reference into default FreeInstance for JVM target?

The whole point of removing the reference, is to let the collector to dispose of the object as soon as possible.

I'm thinking about classes that consume a lot of (system) resources and release them only in during destruction.
Releasing them as soon as possible **might** be a benefit for the code behavior over all.

thanks,
Dmitry

Reply by email

Jonas Maebe
to Dmitry Boyarintsev
Dmitry Boyarintsev wrote
How about moving "nil"-ing of the reference into default FreeInstance for JVM target?

FreeInstance is a regular instance method. Instance methods cannot nil the self pointer (well, they can, but that will just nil the local copy of the self-pointer).

The whole point of removing the reference, is to let the collector to dispose of the object as soon as possible.

The collector only runs very occasionally. If you need instant freeing, a garbage-collected platform is not what you want.

Jonas

Reply by email

Lars
to Dmitry Boyarintsev: On Fri, Jan 27, 2017 at 12:52 PM, Jon Foster Object Pascal semantic of calling .Free…
Dmitry Boyarintsev wrote 47 lines
On Fri, Jan 27, 2017 at 12:52 PM, Jon Foster wrote: > Correct me if I'm wrong: It would seem like that your free > implementation >> doesn't actually do anything, other than fulfilling the obligation of >> having a "free". If I do this: >> > > var o: TObject; > begin o:=TObject.create; > { do something ... } > o.free; end. > > Wouldn't "o" still contain a reference after "free" is called? In > non-JVM FPC "self" is just another variable, who's origin is somewhat > hidden by the compiler. The call to "o.free" would do something like > "TObject.free(o)" > where "o" is passed by *value* into the procedure variable "self". > "Self" > comes and goes with the scope of the "TObject.free" procedure. Which is > why if I'm concerned about detecting whether or not "o" still contains a > correct object reference I would need to do something like this: > "o.free; > o:=nil;" so I can test for "nil" later. Although I think FPC added a > procedure to do that some time back. Yup, I see it > "SysUtils.FreeAndNil". > > > I'm not sure of the specific semantics of the JVM calls but from what I > read in the various FPC JVM related pages on the wiki it would seem to > use similar semantics. Object Pascal semantic of calling .Free suggests that "o" would no longer be a valid object. If a dummy Free method is available for JVM, then such semantic is violated. However, if JVM free method would at least reset "o" reference to nil, then the semantic of "o" being an invalid object remains. It also suggests to the garbage collector that the memory could be recycled earlier, that the variable leaves the scope. thanks, Dmitry

Another interesting idea, from all this discussion, is whether a mixed Garbage Collected/Manually Collected language could exist.

Imagine a garbage collected programming language, that at any point in time, you could take control of with your bare hands and free anything.

This, likely, would be:
1) a bad idea
2) hard to implement
3) or an interesting thesis project for some ivory tower...

I'm not sure if this sort of what Delphi's iOS fake free/release system allows...

I dream of a language that is garbage collected for every day use (most projects) but when I want to have real time control (nuclear power plant or rocket ship that requires code run in real time), this dream language could be handy.

It could also be a confusing nightmare (as Delphi iOS garbage collection/fake release system is getting a bit scary)

Reply by email

Lars
to Jon Foster: Correct me if I'm wrong: It would seem like that your free implementation doesn't…
Jon Foster wrote 26 lines
On 01/27/2017 06:36 AM, Dmitry Boyarintsev wrote: > On Tue, Jan 10, 2017 at 6:14 AM, Michael Schnell < > > wrote: > > > > If destroying an object is not necessary, the class should provide a > dummy Free procedure. So the application programmer always can/should use > Free. > > > Why dummy? if it should be like this > > > procedure TObject.Free; begin if Selfnil then Self:=nil; end; > > Destroying object is not necessary, but dereferencing is. > If the code keeps the reference to an object, it would not be collected. > [...] > Correct me if I'm wrong: It would seem like that your free implementation doesn't actually do anything, other than fulfilling the obligation of having a "free".

That's kind of the point, you aren't actually really freeing the object but emulating something a close as you could get to it... Delphi iOS release/free fake/dummy system does something similar.

But, it's really confusing, as you have to think about what the hell consequences all this causes.

For example see:
http://stackoverflow.com/questions/27818697/how-to-free-a-component-in-android-ios

"DisposeOf breaks ARC. It violates golden rule of ARC Any object reference can be either valid object reference or nil and introduces third state - disposed "zombie" object reference.

Anyone trying to understand ARC memory management should look at DisposeOf like addition that just solves Delphi specific framework issues and not concept that really belongs to ARC itself. "

"Why DisposeOf exists in Delphi ARC compilers?

TComponent class (and all its descendants) was designed with manual memory management in mind. It uses notification mechanism that is not compatible with ARC memory management because it relies on breaking strong reference cycles in destructor. Since TComponent is one of base classes Delphi frameworks rely upon, it must be able to function properly under ARC memory management. "

Reply by email

Michael Schnell
to Jonas Maebe: FreeInstance is a regular instance method. Instance methods cannot nil the self pointer…
Jonas Maebe wrote
The collector only runs very occasionally. If you need instant freeing, a garbage-collected platform is not what you want.

True. It of course should not trigger the garbage collection process (AFAIK, this is possible by a certain API call, but totally inappropriate to do so for every pascalish "free").

Nonetheless it seems viable to instruct the garbage collector that the memory assigned to the instance can be collected when it runs next time.

-Michael

Reply by email