PureBoard
https://www.purebasic.fr/german/

Rücksprung über mehrere Prozeduraufrufe
https://www.purebasic.fr/german/viewtopic.php?f=3&t=31101
Seite 2 von 2

Autor:  #NULL [ 05.10.2018 15:20 ]
Betreff des Beitrags:  Re: Rücksprung über mehrere Prozeduraufrufe

Man kann auch den Fehler/Status als Rückgabewert, und Funktionsergebnisse über Ausgabeparameter zurückgeben.
Code:
Procedure.i f(x.i, *out.Integer)
  If x <= 100
    *out\i = 2 * x
    ProcedureReturn #True
  EndIf
  ProcedureReturn #False
EndProcedure

Define xx.i

If f(3, @ xx)
  Debug "xx: " + xx
Else
  Debug "error"
EndIf

If f(300, @ xx)
  Debug "xx: " + xx
Else
  Debug "error"
EndIf


Oder auch andersherum, oder beides über Ausgabeparameter. Oder auch beides in einer Struktur (\result, \error) als Rückgabewert. Ändert aber nichts am grundlegend C-like error handling. Ich würde aber lokales handling gegenüber irgendwelchen globalen flags vorziehen.
Gab es nicht auch mal eine try/catch lib für PB? Kommt aber wahrscheinlich am Ende aufs Selbe raus.

Autor:  RSBasic [ 05.10.2018 15:23 ]
Betreff des Beitrags:  Re: Rücksprung über mehrere Prozeduraufrufe

#NULL hat geschrieben:
Gab es nicht auch mal eine try/catch lib für PB?

Meinst du diesen Code? viewtopic.php?f=8&t=20370

Autor:  #NULL [ 05.10.2018 15:37 ]
Betreff des Beitrags:  Re: Rücksprung über mehrere Prozeduraufrufe

Was ich in Erinnerung hatte war wahrscheinlich eher was hier in der purearea gelistet ist. Ich sehe aber im englischen Forum gab es da einige Versuche. Ich hab sowas selbst aber nie verwendet.

Autor:  Josh [ 05.10.2018 17:17 ]
Betreff des Beitrags:  Re: Rücksprung über mehrere Prozeduraufrufe

Danke mal für eure zahlreichen Antworten:

@juergenkulow
Interessanter Code. Hab mich schon mal ein bisschen damit rumgespielt, damit ich überhaupt kapiere um was es da geht. Ob ich es dann auch so mache, kann ich noch nicht sagen, auf jeden Fall will ich mal ein paar Tests machen.
Code:
MOV rsp,rsp_reg
MOV rax,rip_reg
JMP rax ; Springe zur Fehlerbehandlung
Was ich noch nicht verstehe, warum stellst du die Sprungadresse zuerst in ein Register? Würde der folgende Code nicht das gleiche machen?
Code:
MOV rsp,rsp_reg
JMP rip_reg


@GPI
Ja, das war mir schon klar geworden, dass ohne EndProcedure / ProcedureReturn ein paar Probleme auftauchen könnten. Ich muss mir mein eigenes Programm mal genauer ansehen, ich glaube, dass in den betroffenen Prozeduren keine Array, Lists und Maps erstellt werden. Da wird nur Daten aus der bereits geöffneten Datei gelesen und diese Daten dann in aufbereiteter Form in globale Listen und Maps gestellt. Lokale Variablen dürften nach meiner Meinung ja kein Speicherleck hinterlassen, wenn ich die Prozedur ohne EndProcedure bzw. ProcedureReturn verlasse (Wichtig: Falls ihr anderer Meinung seid, bitte posten). Zur Zeit habe ich das auch über ein Macro gelöst, um die Rücksprünge möglichst übersichtlich zu halten. Wie schon zu Jürgen gesagt, ich muss mir das ganze mit ASM erst mal ansehen.


@¯\_(ツ)_/¯
Bitte erschlag mich nicht, wenn es nicht stimmt. Habe auch keine Ahnung von ASM und hab mich auch erst ein wenig einlesen müssen:
Code:
MOV rsp,rsp_reg ; Setzt den Stackpointer auf die vorher gemerkte Adresse zurück
MOV rax,rip_reg ; Stellt die Sprungadresse ins Register rax
JMP rax         ; Springe zur Fehlerbehandlung

Autor:  DarkDragon [ 05.10.2018 17:40 ]
Betreff des Beitrags:  Re: Rücksprung über mehrere Prozeduraufrufe

Bei sowas wäre ich allerdings sehr vorsichtig, denn Speicherbereiche und Objekte werden ggf. nicht mehr automatisch durch PB aufgeräumt. Man stelle sich sowas vor:

Code:
Procedure C()
  Throw ; Springe zu A zurück
EndProcedure

Procedure B()
  ; Die Variablen liegen dann auf dem Stack, der aber einfach wieder zurückgesetzt wird, und Pointer auf Heapobjekte sind dann für immer verloren:
  Protected *Memory = AllocateMemory(1024)
  Protected String.s = "Ich weiß nicht" + #LF$ + "was mit solchen Strings passieren würde"
  Protected Font.i = LoadFont(#PB_Any, "Arial", 16)
 
  C()
EndProcedure

Procedure A()
  Try
  B()
  Catch
  ; Hier wurde nun einfach der Stack und Instruction Pointer zurückgesetzt.
  ; - *Memory wurde nicht freigegeben und der Pointer ist auch verloren.
  ; - Es ist mir unklar was mit dem String passiert (kenne die Internas aktuell nicht)
  ; - Der Font wäre auch verloren, genau wie andere PB Objekte.
  EndTry
EndProcedure

A()

Autor:  mk-soft [ 05.10.2018 18:45 ]
Betreff des Beitrags:  Re: Rücksprung über mehrere Prozeduraufrufe

Ich finde #NULLs Methode mit den Rückgabewert als Status noch am besten.
Ist eigentlich oft auch bei API-Funktionen so oder bei Objektprogrammierung als Result #S_OK oder der Fehlercode.

Man muss sich nur daran gewöhnen das man bei PB nicht mehr Strings verwendet, sondern String-Pointer...
Code:

#P_Ok = 0

Enumeration Errors $80000000 Step 1
  #Err_OutOfMemory
  #Err_Pointer
  ; etc
EndEnumeration

Define LastError

Procedure Foo(Var.i, *Result.String)
  Shared LastError 
  If *Result = 0
    LastError = #Err_Pointer
    ProcedureReturn LastError
  EndIf
 
  *Result\s + Str(Var)
 
  ProcedureReturn #P_Ok
EndProcedure

Define t1.String\s ; = "Value = "

r1 = Foo(100, @t1)
If r1 = #P_Ok
  Debug t1\s
Else
  Debug "Errorcode: " + Hex(r1)
EndIf

r1 = Foo(100, @t1)
If foo(200, 0)
  Debug "LastError: " + Hex(LastError)
Else
  Debug t1\s
EndIf

Autor:  GPI [ 05.10.2018 21:02 ]
Betreff des Beitrags:  Re: Rücksprung über mehrere Prozeduraufrufe

Josh hat geschrieben:
@GPI
Ja, das war mir schon klar geworden, dass ohne EndProcedure / ProcedureReturn ein paar Probleme auftauchen könnten. Ich muss mir mein eigenes Programm mal genauer ansehen, ich glaube, dass in den betroffenen Prozeduren keine Array, Lists und Maps erstellt werden.


Ich kann mir vorstellen, das Strings auch Probleme machen. Wie gesagt, keiner hier weis, wie PB das alles intern behandelt. Und ich bin noch nie ein großer Fan davon gewesen, Assembler a) so tiefgreifend zu benutzen und b) wenn man Assembler nicht selber kann :)

Autor:  Josh [ 05.10.2018 21:50 ]
Betreff des Beitrags:  Re: Rücksprung über mehrere Prozeduraufrufe

Ja, ihr habt natürlich recht, Strings würden Probleme machen, da bin ich mir fast zu 100% sicher. Also ist das ganze mit dem Zurücksetzen des Stacks hinfällig.

Danke allen für die Antworten, war trotzdem interessant ein bisschen reinzugucken, was man mit ASM alles machen kann.

Seite 2 von 2 Alle Zeiten sind UTC + 1 Stunde [ Sommerzeit ]
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/