Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   excepciones con raise at (https://www.clubdelphi.com/foros/showthread.php?t=59071)

Lord Delfos 12-08-2008 13:53:27

excepciones con raise at
 
Buenas, gente.

Ayer estaba revisando la gramática de Pascal que viene en Delphi 7, y me encontré con una regla que decía

NoMeAcuerdo -> RAISE [Object] AT [Address]

Que ahora que me fijo no está en Delphi 5...

Y me agarró la inquietud, ¿Alguien sabe qué se hace con ese "AT"? Porque lo de "raise" lo conozco, pero el AT, ni idea, y no encunetro nada en la red...

Gracias miles.

Al González 12-08-2008 16:36:21

¡Hola!

Hasta hoy me entero de la palabra reservada At. Es interesante lo que dice la ayuda al respecto:
Cita:

Use this option to raise the exception from an earlier point in the stack than the one where the error actually occurred.
[Utilice esta opción para elevar la excepción desde un punto previo en la pila que desde donde ocurrió realmente el error.]

Todavía no lo tengo claro del todo, pero, al buscar la expresión regular "Raise .* At " en la carpeta C:\Archivos de programa\Borland\Delphi7\Source, encontré que Borland lo utilizó en varias ocasiones.

Al ver el código fuente del famoso procedimiento Abort en la unidad SysUtils:
Código Delphi [-]
procedure Abort;

  function ReturnAddr: Pointer;
  asm
          MOV     EAX,[EBP + 4]
  end;

begin
  raise EAbort.CreateRes(@SOperationAborted) at ReturnAddr;
end;
Se observa que la excepción es elevada en la dirección de memoria devuelta por la función anidada ReturnAddr. Esta función le asigna al registro de la CPU EAX el valor que se encuentra en la dirección de memoria EBP + 4. Y ese es el valor que devuelve, ya que normalmente una función regresa el valor que se encuentra en el registro EAX. Ahora sólo habría que investigar qué suele guardar el registro de CPU EBP en Delphi para tener una idea más precisa de qué dirección en concreto se está usando para elevar la excepción.

Mientras tanto infiero que al ejecutar el procedimiento Abort de esta manera:
Código Delphi [-]
Procedure MiRutina;
Begin
  ...
  Abort;
la excepción se elevará en la dirección de memoria donde hemos hecho la llamada a Abort y no donde Abort ejecuta la instrucción Raise. Lo cual, para fines de depuración es muy conveniente, ya que el depurador nos dirá que se elevó una excepción formalmente dentro de MiRutina y no dentro del procedimiento Abort. Abort es un procedimiento utilitario para simplificar la elevación de una excepción silenciosa, pero la manera en que hace dicha elevación (con At), ayuda a que suceda como si en lugar de Abort hubiésemos escrito nosotros mismos una instrucción Raise, según parece.

Encontré este interesante artículo relacionado con el tema:
http://www.latiumsoftware.com/es/pascal/0014.php

Y este par de referencias adicionales que hablan del registro EBP:
http://akimpech.izt.uam.mx/Web_jr/ami05/convC.pdf
http://www.hackemate.com.ar/ezines/d...nts004/0X1.txt

Espero haber ayudado.

Al. :)

Lord Delfos 12-08-2008 17:42:28

¡Ajá! Tu búsqueda fue mucho más frutífera que la mía...

Habrá que investigar el asunto.

Graciocles, Al.


La franja horaria es GMT +2. Ahora son las 14:49:12.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi