Recent

Author Topic: "class" without inheritance (Solved)  (Read 3358 times)

PascalDragon

  • Hero Member
  • *****
  • Posts: 5481
  • Compiler Developer
Re: "class" without inheritance
« Reply #15 on: September 15, 2022, 09:33:07 am »
My recollection is that there's a small per-instance difference depending on whether something's been defined as

TSomeClass = class end is equivalent to TSomeClass = class(TObject) end.

MarkMLl

  • Hero Member
  • *****
  • Posts: 6686
Re: "class" without inheritance (Solved)
« Reply #16 on: September 15, 2022, 09:42:34 am »
OK, TFT.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

Arioch

  • Sr. Member
  • ****
  • Posts: 421
Re: "class" without inheritance
« Reply #17 on: September 15, 2022, 07:47:45 pm »
My understanding is that VMT is per /class/ rather than per /instance/.

More so, at least in Delphi instance.ClassType function returns the the pointer to VMT. This does not seem to be explicitly documented (contracted to be always so), but it also never changed.

This was a cause of weird effect, when novice devs moved objects from monolyth application to DLLs (not BPLs)  - and had all the logic broken. Suddenly DLL.TObject and EXE.TObject were DIFFERENT classes (copies of same VMT, but different copies), and so were all the derived classes.

Probably the same was it is implemented in FPC. Just because it seems reasonable choice with few drawbacks if any.

Comparison of class instance types, henceforth, is the comparison of VMT pointers. Would per-instance VMT's differ - is/as operators would get broken.

This also opens a way to hack in a non-TObject rooted objects: create them as is, but then patch the instance's VMT pointer in memory. This hack was used in Delphi to retroactively "attach" classes from DLLs, however this totally deactivates all the type safety checks provided by the compiler.

MarkMLl

  • Hero Member
  • *****
  • Posts: 6686
Re: "class" without inheritance
« Reply #18 on: September 15, 2022, 08:19:12 pm »
This was a cause of weird effect, when novice devs moved objects from monolyth application to DLLs (not BPLs)  - and had all the logic broken. Suddenly DLL.TObject and EXE.TObject were DIFFERENT classes (copies of same VMT, but different copies), and so were all the derived classes.

Interesting, TFT. I can say that with FPC circa v3.0 on x86 (specifically, 32-bit) Linux I was able to e.g. recognise and move data between a TMenu in a shared object library (i.e. analogous to a DLL) and a TMenu in the main app in order to merge a plugin's UI into the main menu structure. This was probably because I was explicitly using the cmem heap which is common to both main app and explicitly-loaded libraries... I hope PascalDragon will correct me if I'm wrong.

Worryingly, there were things I was able to do with 32-bit code in that area that I've not managed to achieve with 64-bit: I /really/ must see if I can get to the bottom of that.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

Arioch

  • Sr. Member
  • ****
  • Posts: 421
Re: "class" without inheritance (Solved)
« Reply #19 on: September 15, 2022, 08:25:41 pm »
Lack of BPL is personally the biggest miss in FPC for me yet. Albeit i understand than x-platform BPL is much harder to do than Win32-only.
Lambda-functions too, but those hopefully would arrive soon :-)

Also, i do not want EXACT cloning of Delphi BPL too, it is flawed (too much exposed, no incapsulation).

Frankly, i believe with and uses should become synonims and work on packages too. In some ideal "modern pascal".

PascalDragon

  • Hero Member
  • *****
  • Posts: 5481
  • Compiler Developer
Re: "class" without inheritance
« Reply #20 on: September 16, 2022, 03:58:23 pm »
Interesting, TFT. I can say that with FPC circa v3.0 on x86 (specifically, 32-bit) Linux I was able to e.g. recognise and move data between a TMenu in a shared object library (i.e. analogous to a DLL) and a TMenu in the main app in order to merge a plugin's UI into the main menu structure. This was probably because I was explicitly using the cmem heap which is common to both main app and explicitly-loaded libraries... I hope PascalDragon will correct me if I'm wrong.

Did you use any is or as across module boundaries? Cause Arioch is right here: if it worked for you, then absolutely by accident. (And using cmem or not has nothing to do with that part)

Lack of BPL is personally the biggest miss in FPC for me yet. Albeit i understand than x-platform BPL is much harder to do than Win32-only.

Compile time packages are essentially working already. What's still missing is runtime loading before I can enable this by default for those platforms that are already adjusted (x86_64-win64, i386-win32, aarch64-win64, all macOS and x86_64-linux).

Lambda-functions too, but those hopefully would arrive soon :-)

Lambda-functions are nowhere planned. What is supported since end of May however are Anonymous Functions and Function References.

Also, i do not want EXACT cloning of Delphi BPL too, it is flawed (too much exposed, no incapsulation).

Though luck then, cause the implementation will be source compatible with Delphi.

Frankly, i believe with and uses should become synonims and work on packages too. In some ideal "modern pascal".

Won't be FPC then.

Arioch

  • Sr. Member
  • ****
  • Posts: 421
Re: "class" without inheritance
« Reply #21 on: September 16, 2022, 04:55:15 pm »
Also, i do not want EXACT cloning of Delphi BPL too, it is flawed (too much exposed, no incapsulation).

Though luck then, cause the implementation will be source compatible with Delphi.

Frankly, i believe with and uses should become synonims and work on packages too. In some ideal "modern pascal".

Won't be FPC then.

You have ObjFPC flavour that intentionally deviates from Delphi

Including discouraging methods parameter names coinciding with class memebr vars names. Which was "always so in Object PAscal" but not in ObjFPC

So i hope strict-mode packages cold be implemented too.

From practice, tyring to refactor a big messy legacy apps into BPLs had a lot of problems of units implicitly imported.
Some of those BPLs were dynamically loaded/unloaded, through a statically linked dynamically loaded "crossbar" BPL.

And those source units had - historically - $ifDef - makign their records and classes have different signatures when compiled into different binaries

You don't know how many times i wished for Delphi just fail compilation if some unit gets pulled into other BPLs, because it soon lead ot "diamond problem" that only mnanifested in ruyntimes and manifested very randomly

Heilsberg was spot on that too permissive a language fails to help to reduce chaos. Sadly, he did not pushed it through when BPLs were designed in Delphi 3...

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11452
  • FPC developer.
Re: "class" without inheritance
« Reply #22 on: September 16, 2022, 05:05:07 pm »
My understanding is that VMT is per /class/ rather than per /instance/.

More so, at least in Delphi instance.ClassType function returns the the pointer to VMT. This does not seem to be explicitly documented (contracted to be always so), but it also never changed.

This was a cause of weird effect, when novice devs moved objects from monolyth application to DLLs (not BPLs)  - and had all the logic broken. Suddenly DLL.TObject and EXE.TObject were DIFFERENT classes (copies of same VMT, but different copies), and so were all the derived classes.

Yes. See https://wiki.freepascal.org/packages

PascalDragon

  • Hero Member
  • *****
  • Posts: 5481
  • Compiler Developer
Re: "class" without inheritance
« Reply #23 on: September 16, 2022, 05:23:29 pm »
Also, i do not want EXACT cloning of Delphi BPL too, it is flawed (too much exposed, no incapsulation).

Though luck then, cause the implementation will be source compatible with Delphi.

Frankly, i believe with and uses should become synonims and work on packages too. In some ideal "modern pascal".

Won't be FPC then.

You have ObjFPC flavour that intentionally deviates from Delphi

Not everything can be solved with different modes. Modes are per unit and thus a package can contain units with different modes.

You don't know how many times i wished for Delphi just fail compilation if some unit gets pulled into other BPLs, because it soon lead ot "diamond problem" that only mnanifested in ruyntimes and manifested very randomly

My plan is to make the loading more robust (which is especially necessary as one must not be able to mix packages from 3.3.1 commit XYZ with ones from 3.3.1 commit ABC), but the general way how packages work stays.

MarkMLl

  • Hero Member
  • *****
  • Posts: 6686
Re: "class" without inheritance
« Reply #24 on: September 16, 2022, 05:50:05 pm »
Did you use any is or as across module boundaries? Cause Arioch is right here: if it worked for you, then absolutely by accident. (And using cmem or not has nothing to do with that part)

Hmm. investigation suggests not.

Am I correct in interpreting what you're saying as that the VMT isn't stored on the heap?

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

PascalDragon

  • Hero Member
  • *****
  • Posts: 5481
  • Compiler Developer
Re: "class" without inheritance
« Reply #25 on: September 16, 2022, 05:59:40 pm »
Am I correct in interpreting what you're saying as that the VMT isn't stored on the heap?

Any VMT generated by the compiler is part of the read-only data of the module. Though a VMT can in principle be on the heap (after all in the instance it's only a pointer, which is abused by the Lazarus IDE for the form designer as well as the TVirtualMethodInterceptor (which FPC does not yet support)).

MarkMLl

  • Hero Member
  • *****
  • Posts: 6686
Re: "class" without inheritance
« Reply #26 on: September 16, 2022, 06:29:31 pm »
Am I correct in interpreting what you're saying as that the VMT isn't stored on the heap?

Any VMT generated by the compiler is part of the read-only data of the module. Though a VMT can in principle be on the heap (after all in the instance it's only a pointer, which is abused by the Lazarus IDE for the form designer as well as the TVirtualMethodInterceptor (which FPC does not yet support)).

Thanks for that, so a global or similar. I should have anticipated that, since after all a class isn't an instance of anything (unlike e.g. Smalltalk).

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

BrunoK

  • Sr. Member
  • ****
  • Posts: 452
  • Retired programmer
Re: "class" without inheritance (Solved)
« Reply #27 on: September 16, 2022, 06:57:45 pm »
If I remember well, TWSLCLComponent registered descendents are dynamically created and allocated through the heap.

Arioch

  • Sr. Member
  • ****
  • Posts: 421
Re: "class" without inheritance
« Reply #28 on: September 16, 2022, 07:07:32 pm »
one must not be able to mix packages from 3.3.1 commit XYZ with ones from 3.3.1 commit ABC), but the general way how packages work stays.

technically it is not necessarily always so

unless SemVer is enforced, what is absolutely needed is type compaticility (or actually ABI compatibility for all what ABI includes).

as long as ABI is binary the same - it is responsibility for programmer to fo it or nor (think of commercial software updates, updating one DLL/BPL while retaining others)

If updated function/class/unit was not used, then it seems to be plausible scenarion to still load packages

granteed, different Lazarus versions would probably have different ABIs somewhere in the RTL code, which would then "by dependencies tree" make everything else incompatible too.

so it seems that formally correct approach would be to have some nested hash, like TigerTree was p2p programs, and then use it to sign all the exported things. Or like today fashionable blockchains

including all the name mangling, compiler switches, architcture and what not
and including the hashes of the interfaces they depend on

i tried to make a very simplified image of data structures required and code points when they would be checked and... frankly, failed.

this OTOH seems to be intimately connected to debug inoformation generations.  The amount of formalized specs that describe ABI with details enough to "sign" it for compativility sake - should also be enough for debugger to operate Evaluate, Watch, Call Stack, etc

Like, if there is no comprehensive information on interface types, then neither debugger can introspect, not BPL dnamic loader can do runtime type safety checks

Plus it is complicated by unit initializatoin/finalizations made in a mixed environment of BPLs statically and dynamically loaded.
I met bugs in XE2 Delphi, rather obscure ones. Deleting of const values in some edge cases.

It all sounds pretty easy before you start thinking, then it is snowballing

----

Granted, with Delphi/FPC speed and today internet bandwidth and disk sizes - the stupid "just recompile them all" solution is practical enough, even if annoying
« Last Edit: September 16, 2022, 07:12:59 pm by Arioch »

MarkMLl

  • Hero Member
  • *****
  • Posts: 6686
Re: "class" without inheritance (Solved)
« Reply #29 on: September 16, 2022, 09:28:22 pm »
If I remember well, TWSLCLComponent registered descendents are dynamically created and allocated through the heap.

What would that be used for in practice?

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

 

TinyPortal © 2005-2018