Sign in Join

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

Mailing lists / fpc-devel / 2018-08

Adding procedures using nodes

3 messages · 2 people · –

Reply by email Subscribe to this list Your subscription

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

Ryan Joseph

So the way FreeInstance is called by adding it within a destructor isn’t exactly what I needed because it requires a destructor actually be present in the class.

The next thing I’d like to try is adding a procedure dynamically using nodes. I’ve seen how if statements are made doing things like:

                        addstatement(newstatement,cifnode.create(
                            caddnode.create(andn,
                                caddnode.create(unequaln,
                                    load_self_pointer_node,
                                    cnilnode.create),
                                caddnode.create(unequaln,
                                    ctypeconvnode.create(
                                        load_vmt_pointer_node,
                                        voidpointertype),
                                    cpointerconstnode.create(0,voidpointertype))),
                            ccallnode.create(nil,tprocsym(srsym),srsym.owner,load_self_node,[],nil),
                            nil));

but are there any examples of creating a procedural with nodes someone could point me to? I’d like to do something like:

procedure DoSomething(param);
begin
end;

so I could call the procedure with a parameter and have a block node (I think begin/end is a block node) so I could add some statements inside that. I’m having fun learning how the compiler works but it’s pretty complicated without any guidance.

Thanks.

Regards,
Ryan Joseph

Reply by email

Ryan Joseph
to Ryan Joseph
Show quoted text 5 lines
On Aug 2, 2018, at 2:41 PM, Ryan Joseph wrote: So the way FreeInstance is called by adding it within a destructor isn’t exactly what I needed because it requires a destructor actually be present in the class. The next thing I’d like to try is adding a procedure dynamically using nodes. I’ve seen how if statements are made doing things like:

Once again I think this is not useful so it can be disregarded.

I wanted to learn how I could call Free on class fields (like management operators call Finalize on records) but it’s more complicated than I thought (again). Records with management operators hook into the RTTI system it looks like, but how does a record with management operators get added to the classes RTTI information? I mean in TObject.CleanupInstance there is a vInitTable which gets set if the record has management operators in them but I can’t find where.

Regards,
Ryan Joseph

Reply by email

Sven Barth
to Ryan Joseph
Ryan Joseph wrote 9 lines
> On Aug 2, 2018, at 2:41 PM, Ryan Joseph wrote: > > So the way FreeInstance is called by adding it within a destructor isn’t exactly what I needed because it requires a destructor actually be present in the class. > > The next thing I’d like to try is adding a procedure dynamically using nodes. I’ve seen how if statements are made doing things like: Once again I think this is not useful so it can be disregarded. I wanted to learn how I could call Free on class fields (like management operators call Finalize on records) but it’s more complicated than I thought (again). Records with management operators hook into the RTTI system it looks like, but how does a record with management operators get added to the classes RTTI information? I mean in TObject.CleanupInstance there is a vInitTable which gets set if the record has management operators in them but I can’t find where.

The whole VMT including vInitTable is generated by the compiler in ncgvmt. Take this example:

=== code begin ===

program thelloworld;
{$mode objfpc}
{$modeswitch advancedrecords}
type
   TTestRec = record
     f: LongInt;
     class operator Initialize(var aRec: TTestRec);
   end;
   TTest = class
     fRec: TTestRec;
   end;
class operator TTestRec.Initialize(var aRec: TTestRec);
begin
end;
var
   t: TTest;
begin
   t := TTest.Create;
end.

=== code end ===

If you compile this with -al you'll see the following symbols in the assembly code:

VMT_$P$THELLOWORLD_$$_TTEST: The VMT of the TTest class (look at rtl/inc/objpash.inc for the type TVmt to see how a VMT is structured) INIT_$P$THELLOWORLD_$$_TTEST: The init table of the TTest class (referenced from the VMT)
INIT_$P$THELLOWORLD_$$_TTESTREC: The init table of the TTestRec record (referenced from TTest's init table using an indirect reference)

Regards,
Sven

Reply by email