Freepascal: Unterschied zwischen den Versionen

Aus OrgaMon Wiki
Zur Navigation springen Zur Suche springen
Zeile 109: Zeile 109:


* http://www.mindfruit.co.uk/2012/01/switch-blocks-jump-tables.html
* http://www.mindfruit.co.uk/2012/01/switch-blocks-jump-tables.html
my way would be (assumed 64-bit mode yet):
;entry in rax and all entries contain a valid address
;a limit check here may not hurt much.
  jmp [table+rax*8]            ;if in the data-seg or
  jmp cs:[table+rax*8]        ;if the table is part of the code section
;also possible if your compiler is able to:
  jmp [rip+table_offset+rax*8] ;RIP access uses CS by default
__
wolfgang

Version vom 9. Oktober 2017, 16:38 Uhr

Freepascal oder fpc ist ein freier Pascal / Delphi(tm) Compiler. Der Entwicklungsstand kann mit Turbo Pascal(tm) 7.0 erweitert um aktuelle Delphi(tm) Sprachelemente verglichen werden. OrgaMon verwendet Freepascal für die Linux-Server-Seite des OrgaMon in den Projekten keepcon, domadd, cOrgaMon. cOrgaMon wird unter Windows mit der Entwicklungsumgebung Lazarus entwickelt.

Installation

  • Für OpenSuse sollten ausschliesslich für diese Plattform compilierte Pakete verwendet werden. Das Standard 64-Bit Paket von Sourceforge wird nicht laufen!
#
# Option 1: aus "Factory"
#
zypper ar --refresh http://download.opensuse.org/repositories/devel:/languages:/pascal/openSUSE_Factory/devel:languages:pascal.repo

#
# Option 2: aus "42.1"
#
zypper ar --refresh http://download.opensuse.org/repositories/devel:languages:pascal/openSUSE_Leap_42.1/devel:languages:pascal.repo

#
# ein erstmaliger Download des Repository-Index, dem "Key" kann man mit 
# Taste <A> dauerhaft vertrauen
#
zypper refresh
#
# die eigentliche Installation
#
zypper install lazarus

Spracherweiterungen

  • hier fasse ich einige Spracherweiterungen auf, die mir so einfallen
  • Intel Parallel Building Blocks (PBB)
  • OpenMP
  • Ev. kommt mir hier das kommende LLVM Target von FreePascal zugute

"param" anstelle von "var"

var
 MomentTimeout : ANFiXDate; Parameter;
 c,i,r : integer; Parameter;
 
begin
   // all zu alte Einträge löschen
   MomentTimeout := DatePlus(DateGet, -10);
   i := 0;
   c := colOf('MOMENT');
   for r := RowCount downto 1 do
     if (StrToIntDef(readCell(r, c), 0) < MomentTimeout) then
     begin
       del(r);
       inc(i);
     end;
   if (i > 0) then
     Log('INFO: ' + 'gebe ' + inttostr(i) +
       ' Dateieinträge frei, da sie älter als 10 Tage sind');
end;

"param" Variable sind wie "var" Variable, die aber erst gesetzt werden, wenn ein (erster) lesender Zugriff erfolgt. Das "Setzen" des VAriablen-Wertes erfolgt gar nicht, an dieser Stelle wird kein Code ausgeführt, erst beim ersten Vergleich wird "MomentTimeout" gesetzt. Danach wird MomentTimeout wie eine normale Variable verwendet. Dadurch lässt sich der Code übersichtlicher gestalten. Man kann die "gathering" Phase schön beisammenhalten - auch wenn die die Kosten hoch sind. Es wird jedoch keine Zeit verbraten, und eine Menge komplexe if-Bedingungen gespart.

nebenläufige Zuweisung

var
 a,b : integer; Concurrent;

begin
 a := sql('count SOULS from EARTH');
 b := sql('count STARS from UNIVERSE');
 if (a>=b) then
   beep;
end;

Die Zuweisung nach a erfolgt in einem eigenen Thread. DIe Codeausführung wird sofort mit der nächsten Zeile fortgesetzt. Auch für die Zuweisung zu b wird ein Thread gestartet. Erst bei einem lesenden Zugriff auf a oder b wird auf das Ergebnis (= Beendigung des Threads) gewartet, ein erneuter schreibender ZUgriff auf a oder b würde den Thread ohne Warten auf das Ergebnis abbrechen.

case statement

Es ist eine Optimierung beim Freepascal Case Statement möglich, wenn z.B. anhand eines enum-Types unterschieden werden soll:

  • case statement ohne "ranges", also KEIN 0..18
  • case statement ohne nennenswerte Lücken

.GLOBAL calculate
calculate:
   pushl %ebp
   movl %esp,%ebp
   movl 12(%ebp),%eax
   movl 8(%ebp),%ecx
   cmpl $2,%ecx
   ja done
   jmp *operations(,%ecx,4)
operation1:
   imull %eax,%eax
   jmp done
operation2:
   negl %eax
   jmp done
operation3:
   addl $0x80,%eax
done:
   leave
   ret
operations:
   .long operation1, operation2, operation3

my way would be (assumed 64-bit mode yet):
;entry in rax and all entries contain a valid address
;a limit check here may not hurt much.

 jmp [table+rax*8]            ;if in the data-seg or
 jmp cs:[table+rax*8]         ;if the table is part of the code section
;also possible if your compiler is able to:
 jmp [rip+table_offset+rax*8] ;RIP access uses CS by default

__
wolfgang