Sign in Join

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

Mailing lists / fpc-pascal / 2001-12

Minimum size of parameters

7 messages · 2 people ·

Reply by email Subscribe to this list Your subscription

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

Aitor Santamaria Merino

Hi,

I explain the problem, then my solution, then my questions: (Platform: GO32V2, although I think it could be independent)

Problem: if I have a record like this:
RECORD

      Pt: PointerToCertainProcedure;
      Sz: SizeInBytesOfProcedureArgs;
      Arg: PointerToARecordContainingArgs;

END;
then I would like to make a Call procedure to interpretate this all. The parameters of the procedures and the record containing args specify both in the same order.

My solution (briefly):
(a) typecast the RecordContainingArgs to an ARRAY OF WORD (using pointers, etc.)(why? because it seems that I can only PUSH words!) (b) push that array REVERSING the order
(c) ASM_CALL the procedure
It worked.

Notes:
I noted that I typecasted to words because inline ASM did only allow me to push WORDs.
I have also discovered the following "funny" behaviour of calls when I have to use BYTES:

{This works!!}
{$ASMMODE Intel}
VAR
    Par1, Par2: word;
BEGIN
      Par1 := 1;
      Par2 := 2;
      ASM
         PUSH Par2
         PUSH Par1
         CALL P
      END
END.
Where P is a PROCEDURE (a,b: BYTE);
ATTENTION: I push WORDS and P "pops" BYTES!

Questions:
For which kind of basic bytes should I expect such behaviour? (boolean?,)
How are STRINGS popped? will this trick of reversing parameter data work? If the answer to the previous was NO, then do you have another idea to solve my initial problem, execute this:
RECORD

      Pt: PointerToCertainProcedure;
      Sz: SizeInBytesOfProcedureArgs;
      Arg: PointerToARecordContainingArgs;

END;

Aitor

Reply by email

Aitor Santamaria Merino

Hi,

I explain the problem, then my solution, then my questions: (Platform: GO32V2, although I think it could be independent)

Problem: if I have a record like this:
RECORD

      Pt: PointerToCertainProcedure;
      Sz: SizeInBytesOfProcedureArgs;
      Arg: PointerToARecordContainingArgs;

END;
then I would like to make a Call procedure to interpretate this all. The parameters of the procedures and the record containing args specify both in the same order.

My solution (briefly):
(a) typecast the RecordContainingArgs to an ARRAY OF WORD (using pointers, etc.)(why? because it seems that I can only PUSH words!) (b) push that array REVERSING the order
(c) ASM_CALL the procedure
It worked.

Notes:
I noted that I typecasted to words because inline ASM did only allow me to push WORDs.
I also tried with types bigger than WORD (CARDINAL, ARRAYs, RECORDs), and reversing DID work.
I have also discovered the following "funny" behaviour of calls when I have to use BYTES:

{This works!!}
{$ASMMODE Intel}
VAR
    Par1, Par2: word;
BEGIN
      Par1 := 1;
      Par2 := 2;
      ASM
         PUSH Par2
         PUSH Par1
         CALL P
      END
END.
Where P is a PROCEDURE (a,b: BYTE);
ATTENTION: I push WORDS and P "pops" BYTES!

Questions:
For which kind of basic bytes should I expect such behaviour? (boolean?,sortint?) I would say for those types whose size is not a multiple of 2 bytes, am I right?

Aitor

Reply by email

Jonas Maebe
to Aitor Santamaria Merino: I explain the problem, then my solution, then my questions: (Platform: GO32V2, although I…
Aitor Santamaria Merino wrote 7 lines
If the answer to the previous was NO, then do you have another idea to solve my initial problem, execute this: RECORD Pt: PointerToCertainProcedure; Sz: SizeInBytesOfProcedureArgs; Arg: PointerToARecordContainingArgs; END;

Pascal (Delphi-style pascal) has a generic solution for this. It's called an "array of const". You use it like this:

***
procedure p(args: array of const);
var
   i: longint;
begin
   for i := low(args) to high(args) do
     case args[i].vtype of
       vtInteger:
         writeln(args[i].vInteger);
       ...
     end;
end;
begin
   p(["string",'c',1354]);
end.
***

I suppose this is all explained in the reference manual, though I'm not sure.

Jonas

Reply by email

Jonas Maebe
to Aitor Santamaria Merino
Aitor Santamaria Merino wrote
Sorry for multiple posting! I thought the first one was cancelled, and it was sent twice instead. Disregard it, only the last one is valid. (and thanks, Jonas, I hope that's also valid for GO32!)

As I said, it's a Pascal construct, so it's available on all platforms.

Jonas

Reply by email

Aitor Santamaria Merino
to Jonas Maebe: Pascal (Delphi-style pascal) has a generic solution for this. It's called an "array of…

Many thanks for the piece of advice.
Two more problems:

Show quoted text 10 lines
On donderdag, december 6, 2001, at 04:47 , Aitor Santamaria Merino wrote: > If the answer to the previous was NO, then do you have another idea to > solve my initial problem, execute this: > RECORD > Pt: PointerToCertainProcedure; > Sz: SizeInBytesOfProcedureArgs; > Arg: PointerToARecordContainingArgs; > END;
This would be, then
RECORD
      Pt: Procedure (args: array of const);
      Arg: args;
END;
right?

Problem 1) This wouldn't be transparent for procedures/functions, and it is my wish that it should be so.
Ok, I could wrap it...

Show quoted text 20 lines
Pascal (Delphi-style pascal) has a generic solution for this. It's called an "array of const". You use it like this: *** procedure p(args: array of const); var i: longint; begin for i := low(args) to high(args) do case args[i].vtype of vtInteger: writeln(args[i].vInteger); ... end; end; begin p(["string",'c',1354]); end. ***
Problem 2) How would I fill into such structure? Could I do
Var A: args;
begin
      a[1] := 'string';  {why "?}
      a[2] := 'c';
      a[3] := 1234;
end;

Problem 3) Which are the fields of a[i]? You seemed to mention vtype, vInteger?

I suppose this is all explained in the reference manual, though I'm not sure.

I coulnd't find it as a first glance... (I looked at the open arrays section, although my compiler version is still rather outdated...

Aitor

Reply by email

Jonas Maebe
to Aitor Santamaria Merino
Aitor Santamaria Merino wrote 6 lines
This would be, then RECORD Pt: Procedure (args: array of const); Arg: args; END; right?

I suppose you mean "args: array of const". But that won't work, an "array of const" can only be an argument, not a variable type. I also didn't realise you wanted to store the arguments together with the procedure to call, because in that case you can't use an array of const. You'll have to create your own variant type (FCP variant support isn't complete yet), like this:

***
{$mode objfpc}
type
   tmyvariant = record
     case typ: longint of
       0: (i: integer);
       1: (s: string);
   end;
   tproccallrec = record
     pt: procedure (const args: array of tmyvariant);
     args: array of tmyvariant;
   end;
procedure test(const a: array of tmyvariant);
begin
   writeln(high(a));
   writeln(a[0].i);
end;
var
   pcr: tproccallrec;
   v: tmyvariant;
begin
   pcr.pt := @test;
   setlength(pcr.args,2);
   v.typ := vtInteger; { you can also create your own constants for
denoting the type, but since these already exist... }
   v.i := 5;
   pcr.args[0] := v;
   v.typ := vtString;
   v.s := 'test';
   pcr.args[1] := v;
   pcr.pt(pcr.args);
end.
***

Note however that

a) you need a 1.1 snapshot to compile this
b) it DOES NOT WORK :)

The reason for b is that there are apparently bugs in the compiler for a conversion of a "dynamic array" to an open array...

Show quoted text 5 lines
> I suppose this is all explained in the reference manual, though I'm > not sure. I coulnd't find it as a first glance... (I looked at the open arrays section, although my compiler version is still rather outdated...

An "array of const" is something completely different from an "open array" (and both are different from a "dynamic array"). I assume "array of const" will only be explained in the 1.1 manual.

Jonas

Reply by email