Recent

Author Topic: Function return parameter code generation misery  (Read 3899 times)

cryborg2

  • New Member
  • *
  • Posts: 14
Function return parameter code generation misery
« on: November 05, 2022, 05:09:25 pm »
How to tell the compiler to generate a code that treat Pointer type function return parameter as a "var" parameter just like it does with string type function return parameters?


function Test1{EAX}: string; assembler;
asm
// from here it is like we have a header like this: procedure Test1(var S{EAX}: string); assembler;
end;

function Test2{EAX}: Pointer; assembler;
asm
// from here it is like we have a header like this: procedure Test2(out P{EAX}: Pointer); assembler;
end;


procedure Test;
  var
    s: string;
    P: Pointer;
begin
  GetMem(P, MemBytes);

  s:=Test1; // In this case we pass the string to Test1 as a "var" parameter! Then Test1 can access the string as it was a real "var" parameter.
  {
    assembler:
    LEA     EAX,DWORD PTR [EBP-12]      (lea -0xc(%ebp),%eax)
    CALL    <TEST1>
  }


  P:=Test2; // In this case we not pass the pointer's address, we just get an address defined by Test2.
  {
    assembler:
    CALL    <TEST2>
    MOV     DWORD PTR [EBP-16],EAX      (mov %eax,-0x10(%ebp))
  }


  FreeMem(P);
end;

 %)
« Last Edit: November 05, 2022, 07:25:29 pm by cryborg2 »

cryborg2

  • New Member
  • *
  • Posts: 14
Re: Function return parameter code generation misery
« Reply #1 on: November 05, 2022, 07:45:29 pm »
This is important to me because I want to use my custom string data type with the same fashion as the built-in strings (except for concatenation of course).

PascalDragon

  • Hero Member
  • *****
  • Posts: 5756
  • Compiler Developer
Re: Function return parameter code generation misery
« Reply #2 on: November 05, 2022, 09:36:27 pm »
How types are passed is fixed by the ABI and is not up to a user. So a Pointer will always be passed by value in the result register.

alpine

  • Hero Member
  • *****
  • Posts: 1302
Re: Function return parameter code generation misery
« Reply #3 on: November 05, 2022, 11:44:37 pm »
This is important to me because I want to use my custom string data type with the same fashion as the built-in strings (except for concatenation of course).
IMO It is due to the fact that String have a special treatment in FPC.
With the help of advanced records and operator/function overloading you can define whatever custom data type you want.
What do you mean with "the same fashion as"?
"I'm sorry Dave, I'm afraid I can't do that."
—HAL 9000

cryborg2

  • New Member
  • *
  • Posts: 14
Re: Function return parameter code generation misery
« Reply #4 on: November 06, 2022, 03:14:28 am »
This is important to me because I want to use my custom string data type with the same fashion as the built-in strings (except for concatenation of course).
IMO It is due to the fact that String have a special treatment in FPC.
With the help of advanced records and operator/function overloading you can define whatever custom data type you want.
What do you mean with "the same fashion as"?

I want to use the ":=" operator to get my virtual string type return value, and to do so, the called function must have acces to my VirtualString object -which have it's own memory management- to transfer data through function return mechanism.
« Last Edit: November 06, 2022, 03:16:14 am by cryborg2 »

PascalDragon

  • Hero Member
  • *****
  • Posts: 5756
  • Compiler Developer
Re: Function return parameter code generation misery
« Reply #5 on: November 06, 2022, 04:06:19 pm »
Then you need to use advanced records with operator overloads. Anything else is just hacks.

ASerge

  • Hero Member
  • *****
  • Posts: 2337
Re: Function return parameter code generation misery
« Reply #6 on: November 06, 2022, 06:01:23 pm »
I want to use the ":=" operator to get my virtual string type return value, and to do so, the called function must have acces to my VirtualString object -which have it's own memory management- to transfer data through function return mechanism.
You can, but not Pointer. Example:
Code: Pascal  [Select][+][-]
  1. {$MODE OBJFPC}
  2. {$LONGSTRINGS ON}
  3. {$MODESWITCH ADVANCEDRECORDS}
  4. {$APPTYPE CONSOLE}
  5. type
  6.   TVirtualString = record
  7.   strict private
  8.     FLength: SizeInt;
  9.     FData: PAnsiChar;
  10.     procedure CopyFrom(const Src; ALength: SizeInt);
  11.     class operator Copy(constref Src: TVirtualString; var Dst: TVirtualString);
  12.     class operator Finalize(var Self: TVirtualString);
  13.     class operator Initialize(var Self: TVirtualString);
  14.   public
  15.     class operator := (const S: string): TVirtualString;
  16.     function AsString: string;
  17.   end;
  18.  
  19. class operator TVirtualString. := (const S: string): TVirtualString;
  20. begin
  21.   Result.CopyFrom(Pointer(S)^, Length(S));
  22. end;
  23.  
  24. function TVirtualString.AsString: string;
  25. begin
  26.   SetString(Result, FData, FLength);
  27. end;
  28.  
  29. class operator TVirtualString.Copy(constref Src: TVirtualString; var Dst: TVirtualString);
  30. begin
  31.   Dst.CopyFrom(Src.FData^, Src.FLength);
  32. end;
  33.  
  34. class operator TVirtualString.Finalize(var Self: TVirtualString);
  35. begin
  36.   ReAllocMem(Self.FData, 0);
  37.   Self.FLength := 0;
  38. end;
  39.  
  40. class operator TVirtualString.Initialize(var Self: TVirtualString);
  41. begin
  42.   Self.FLength := 0;
  43.   Self.FData := nil;
  44. end;
  45.  
  46. procedure TVirtualString.CopyFrom(const Src; ALength: SizeInt);
  47. begin
  48.   FLength := ALength;
  49.   ReAllocMem(FData, FLength);
  50.   if FLength > 0 then
  51.     Move(Src, FData^, FLength)
  52. end;
  53.  
  54. // End TVirtualString
  55.  
  56. function SomeFunction: TVirtualString;
  57. begin
  58.   Result := '123';
  59. end;
  60.  
  61. var
  62.   V: TVirtualString;
  63. begin
  64.   V := '456';
  65.   V := SomeFunction; // As you want
  66.   Writeln(V.AsString);
  67.   Readln;
  68. end.

 

TinyPortal © 2005-2018