remobjects / pascalscript

pascalscript
Other
447 stars 178 forks source link

Add none-native calling for class methods/properties. #210

Open User4martin opened 5 years ago

User4martin commented 5 years ago

For plain procedures/functions there are RegisterDelphiFunction which emulates a native call RegisterFunctionName which avoids "playing" with the stack

For methods this does not exist. I added TPSRuntimeClass.RegisterMethodName and TPSRuntimeClass.RegisterPropertyNameHelper

The name RegisterPropertyNameHelper may need to be changed, but RegisterPropertyHelperName was already taken.

Using those functions should be more resistant against changes in the compiler.

According to the fpc mailing list, fpc trunk changes calling convention on i386 linux...

pult commented 4 years ago

please provide an example of use

User4martin commented 4 years ago

https://github.com/User4martin/lazarus/commit/e30b8c8f1c0501b2fd66e5a1fe355cefcea58eac This has been tested on 64bit Win (64 and 32 bit compiled) and Linux (64 bit only). That is the (still existing) self-test in the IDE passes. (And the 64bit build on win, is used daily be me)

Using the InnerfuseCall did IIRC for example not work on arm (raspi) when sets are involved. Though I have not tested the new implementation on arm, as I do not have a test env setup (I am waiting for feedback)

Again not tested, InnerfuseCall might also need work for fpc trunk on linux 32bit, as fpc changed calling convention.

RegisterFunctionName has been available for a long time already. And I had looked at it (in fact I had IFDEF'D code for it) long ago. But since I needed to relay on InnerfuseCall for properties, I had not used it back then.

Given the fact, that at least on fpc, InnerfuseCall would need careful retesting with every fpc release, I had actually always thought the absence of alternative methods for properties was because no one had found the time to do them.

That is why in the IDE I run a self-test at each startup (since a user could have build it with any version of fpc, including future). This self-test is carefully designed to detected if it crashed on its last run. Because if fpc changes calling convention, building older IDE code (with older PascalScript) with newer fpc, has the very real potential of crashing.

pult commented 4 years ago

Need samples of usage. ? What it is: ExtRead1, ExtRead2, ExtWrite1, ExtWrite2 ?

pult commented 4 years ago

FPC + x64 - InnerfuseCall without asm: https://github.com/pult/pascalscript/blob/fix_20170321_x64call/Source/x64.inc This will also must work if the fpc call notification changes

User4martin commented 4 years ago

Unfortunately I don't recall where the examples are, from which I learned about RegisterFunctionName.

With RegisterFunctionName you specify the @HandlerFunc, and Ext1, Ext2. The latter 2 are passed to HandlerFunc. That allows you to reuse the same HandlerFunc for different functions.

For properties you have a read and a write method. So you can specify a pair for each of them.

Of course you can also set 2 (read/write) new HandlerFunc for each of property.

In the linked code the HandlerFunc is ExecBasicHandler.


Btw, the last commit 86a057c8686143ce0443be6995d6515c5c9b705c, seems to change InnerfuseCall to InvokeCall. But that is Delphi only. It does not affect FPC.

pult commented 4 years ago

latest commit not tested and do not work/compilation on previous delphi versions (sample XE3 not compiled). Need fix: https://github.com/remobjects/pascalscript/pull/203#issuecomment-533719894

User4martin commented 4 years ago

About your commit / link: I am not an expert on calling conventions: But your InnerfuseCall must still know what is allowed in a register, and what must be on the stack. And by how many bytes the stack must be aligned, etc.

Those things should be defined per platform. But then (search the recent fpc mail list) fpc changed it for 32bit linux.

pult commented 4 years ago

For x64 platform - simple call notations. The compiler (FPC or Delphi) can generate calls based on the pas-code. For 32 bit - much more confusing.