|
@@ -1,361 +0,0 @@
|
|
|
-{
|
|
|
- $Id$
|
|
|
-
|
|
|
- This unit provides compiler-independent mechanisms to call special
|
|
|
- functions, i.e. local functions/procedures, constructors, methods,
|
|
|
- destructors, etc. As there are no procedural variables for these
|
|
|
- special functions, there is no Pascal way to call them directly.
|
|
|
-
|
|
|
- Copyright (c) 1997 Matthias K"oppe <[email protected]>
|
|
|
-
|
|
|
- This library is free software; you can redistribute it and/or
|
|
|
- modify it under the terms of the GNU Library General Public
|
|
|
- License as published by the Free Software Foundation; either
|
|
|
- version 2 of the License, or (at your option) any later version.
|
|
|
-
|
|
|
-
|
|
|
- This library is distributed in the hope that it will be useful,
|
|
|
- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
- Library General Public License for more details.
|
|
|
-
|
|
|
- You should have received a copy of the GNU Library General Public
|
|
|
- License along with this library; if not, write to the Free
|
|
|
- Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
-
|
|
|
- ****************************************************************************}
|
|
|
-unit CallSpec;
|
|
|
-
|
|
|
-{
|
|
|
- As of this version, the following compilers are supported. Please
|
|
|
- port CallSpec to other compilers (including earlier versions) and
|
|
|
- send your code to the above address.
|
|
|
-
|
|
|
- Compiler Comments
|
|
|
- --------------------------- -------------------------------------
|
|
|
- Turbo Pascal 6.0
|
|
|
- Borland/Turbo Pascal 7.0
|
|
|
- FPC Pascal 0.99.8
|
|
|
-}
|
|
|
-
|
|
|
-interface
|
|
|
-
|
|
|
-{$i platform.inc}
|
|
|
-
|
|
|
-{
|
|
|
- The frame pointer points to the local variables of a procedure.
|
|
|
- Use CurrentFramePointer to address the locals of the current procedure;
|
|
|
- use PreviousFramePointer to addess the locals of the calling procedure.
|
|
|
-}
|
|
|
-type
|
|
|
-{$ifdef BIT_16}
|
|
|
- FramePointer = Word;
|
|
|
-{$endif}
|
|
|
-{$ifdef BIT_32}
|
|
|
- FramePointer = pointer;
|
|
|
-{$endif}
|
|
|
-
|
|
|
-function CurrentFramePointer: FramePointer;
|
|
|
-function PreviousFramePointer: FramePointer;
|
|
|
-
|
|
|
-{ This version of CallSpec supports four classes of special functions.
|
|
|
- (Please write if you need other classes.)
|
|
|
- For each, two types of argument lists are allowed:
|
|
|
-
|
|
|
- `Void' indicates special functions with no explicit arguments.
|
|
|
- Sample: constructor T.Init;
|
|
|
- `Pointer' indicates special functions with one explicit pointer argument.
|
|
|
- Sample: constructor T.Load(var S: TStream);
|
|
|
-}
|
|
|
-
|
|
|
-{ Constructor calls.
|
|
|
-
|
|
|
- Ctor Pointer to the constructor.
|
|
|
- Obj Pointer to the instance. NIL if new instance to be allocated.
|
|
|
- VMT Pointer to the VMT (obtained by TypeOf()).
|
|
|
- returns Pointer to the instance.
|
|
|
-}
|
|
|
-function CallVoidConstructor(Ctor: pointer; Obj: pointer; VMT: pointer): pointer;
|
|
|
-function CallPointerConstructor(Ctor: pointer; Obj: pointer; VMT: pointer; Param1: pointer): pointer;
|
|
|
-
|
|
|
-{ Method calls.
|
|
|
-
|
|
|
- Method Pointer to the method.
|
|
|
- Obj Pointer to the instance. NIL if new instance to be allocated.
|
|
|
- returns Pointer to the instance.
|
|
|
-}
|
|
|
-function CallVoidMethod(Method: pointer; Obj: pointer): pointer;
|
|
|
-function CallPointerMethod(Method: pointer; Obj: pointer; Param1: pointer): pointer;
|
|
|
-
|
|
|
-{ Local-function/procedure calls.
|
|
|
-
|
|
|
- Func Pointer to the local function (which must be far-coded).
|
|
|
- Frame Frame pointer of the wrapping function.
|
|
|
-}
|
|
|
-
|
|
|
-function CallVoidLocal(Func: pointer; Frame: FramePointer): pointer;
|
|
|
-function CallPointerLocal(Func: pointer; Frame: FramePointer; Param1: pointer): pointer;
|
|
|
-
|
|
|
-{ Calls of functions/procedures local to methods.
|
|
|
-
|
|
|
- Func Pointer to the local function (which must be far-coded).
|
|
|
- Frame Frame pointer of the wrapping method.
|
|
|
- Obj Pointer to the object that the method belongs to.
|
|
|
-}
|
|
|
-function CallVoidMethodLocal(Func: pointer; Frame: FramePointer; Obj: pointer): pointer;
|
|
|
-function CallPointerMethodLocal(Func: pointer; Frame: FramePointer; Obj: pointer; Param1: pointer): pointer;
|
|
|
-
|
|
|
-
|
|
|
-implementation
|
|
|
-
|
|
|
-{$ifdef PPC_FPC}
|
|
|
-
|
|
|
-{$ASMMODE ATT}
|
|
|
-
|
|
|
-{ This indicates an FPC version which uses the same call scheme for
|
|
|
- method-local and procedure-local procedures, but which expects the
|
|
|
- ESI register be loaded with the Self pointer in method-local procs. }
|
|
|
-
|
|
|
-type
|
|
|
- VoidLocal = function(_EBP: FramePointer): pointer;
|
|
|
- PointerLocal = function(_EBP: FramePointer; Param1: pointer): pointer;
|
|
|
- VoidMethodLocal = function(_EBP: FRAMEPOINTER): pointer;
|
|
|
- PointerMethodLocal = function(_EBP: FRAMEPOINTER; Param1: pointer): pointer;
|
|
|
- VoidConstructor = function(VMT: pointer; Obj: pointer): pointer;
|
|
|
- PointerConstructor = function(VMT: pointer; Obj: pointer; Param1: pointer): pointer;
|
|
|
- VoidMethod = function(Obj: pointer): pointer;
|
|
|
- PointerMethod = function(Obj: pointer; Param1: pointer): pointer;
|
|
|
-
|
|
|
-
|
|
|
-function CallVoidConstructor(Ctor: pointer; Obj: pointer; VMT: pointer): pointer;
|
|
|
-begin
|
|
|
- { load the object pointer }
|
|
|
- asm
|
|
|
- movl Obj, %esi
|
|
|
- end;
|
|
|
- CallVoidConstructor := VoidConstructor(Ctor)(VMT, Obj)
|
|
|
-end;
|
|
|
-
|
|
|
-
|
|
|
-function CallPointerConstructor(Ctor: pointer; Obj: pointer; VMT: pointer; Param1: pointer): pointer;
|
|
|
-begin
|
|
|
- { load the object pointer }
|
|
|
- asm
|
|
|
- movl Obj, %esi
|
|
|
- end;
|
|
|
- CallPointerConstructor := PointerConstructor(Ctor)(VMT, Obj, Param1)
|
|
|
-end;
|
|
|
-
|
|
|
-
|
|
|
-function CallVoidMethod(Method: pointer; Obj: pointer): pointer;
|
|
|
-begin
|
|
|
- { load the object pointer }
|
|
|
- asm
|
|
|
- movl Obj, %esi
|
|
|
- end;
|
|
|
- CallVoidMethod := VoidMethod(Method)(Obj)
|
|
|
-end;
|
|
|
-
|
|
|
-
|
|
|
-function CallPointerMethod(Method: pointer; Obj: pointer; Param1: pointer): pointer;
|
|
|
-begin
|
|
|
- { load the object pointer }
|
|
|
- asm
|
|
|
- movl Obj, %esi
|
|
|
- end;
|
|
|
- CallPointerMethod := PointerMethod(Method)(Obj, Param1)
|
|
|
-end;
|
|
|
-
|
|
|
-
|
|
|
-function CallVoidLocal(Func: pointer; Frame: FramePointer): pointer;
|
|
|
-begin
|
|
|
- CallVoidLocal := VoidLocal(Func)(Frame)
|
|
|
-end;
|
|
|
-
|
|
|
-
|
|
|
-function CallPointerLocal(Func: pointer; Frame: FramePointer; Param1: pointer): pointer;
|
|
|
-begin
|
|
|
- CallPointerLocal := PointerLocal(Func)(Frame, Param1)
|
|
|
-end;
|
|
|
-
|
|
|
-
|
|
|
-function CallVoidMethodLocal(Func: pointer; Frame: FramePointer; Obj: pointer): pointer;
|
|
|
-begin
|
|
|
- { load the object pointer }
|
|
|
- asm
|
|
|
- movl Obj, %esi
|
|
|
- end;
|
|
|
- CallVoidMethodLocal := VoidMethodLocal(Func)(Frame)
|
|
|
-end;
|
|
|
-
|
|
|
-
|
|
|
-function CallPointerMethodLocal(Func: pointer; Frame: FramePointer; Obj: pointer; Param1: pointer): pointer;
|
|
|
-begin
|
|
|
- { load the object pointer }
|
|
|
- asm
|
|
|
- movl Obj, %esi
|
|
|
- end;
|
|
|
- CallPointerMethodLocal := PointerMethodLocal(Func)(Frame, Param1)
|
|
|
-end;
|
|
|
-
|
|
|
-
|
|
|
-function CurrentFramePointer: FramePointer;assembler;
|
|
|
-asm
|
|
|
- movl %ebp,%eax
|
|
|
-end ['EAX'];
|
|
|
-
|
|
|
-
|
|
|
-function PreviousFramePointer: FramePointer;assembler;
|
|
|
-asm
|
|
|
- movl (%ebp), %eax
|
|
|
-end ['EAX'];
|
|
|
-
|
|
|
-{$endif PPC_FPC}
|
|
|
-
|
|
|
-
|
|
|
-{$ifdef PPC_BP}
|
|
|
-type
|
|
|
- VoidConstructor = function(VmtOfs: Word; Obj: pointer): pointer;
|
|
|
- PointerConstructor = function(Param1: pointer; VmtOfs: Word; Obj: pointer): pointer;
|
|
|
- VoidMethod = function(Obj: pointer): pointer;
|
|
|
- PointerMethod = function(Param1: pointer; Obj: pointer): pointer;
|
|
|
-
|
|
|
-function CallVoidConstructor(Ctor: pointer; Obj: pointer; VMT: pointer): pointer;
|
|
|
-begin
|
|
|
- CallVoidConstructor := VoidConstructor(Ctor)(Ofs(VMT^), Obj)
|
|
|
-end;
|
|
|
-
|
|
|
-
|
|
|
-function CallPointerConstructor(Ctor: pointer; Obj: pointer; VMT: pointer; Param1: pointer): pointer;
|
|
|
-begin
|
|
|
- CallPointerConstructor := PointerConstructor(Ctor)(Param1, Ofs(VMT^), Obj)
|
|
|
-end;
|
|
|
-
|
|
|
-
|
|
|
-function CallVoidMethod(Method: pointer; Obj: pointer): pointer;
|
|
|
-begin
|
|
|
- CallVoidMethod := VoidMethod(Method)(Obj)
|
|
|
-end;
|
|
|
-
|
|
|
-
|
|
|
-function CallPointerMethod(Method: pointer; Obj: pointer; Param1: pointer): pointer;
|
|
|
-begin
|
|
|
- CallPointerMethod := PointerMethod(Method)(Param1, Obj)
|
|
|
-end;
|
|
|
-
|
|
|
-
|
|
|
-function CallVoidLocal(Func: pointer; Frame: FramePointer): pointer; assembler;
|
|
|
-asm
|
|
|
-{$IFDEF Windows}
|
|
|
- MOV AX,[Frame]
|
|
|
- AND AL,0FEH
|
|
|
- PUSH AX
|
|
|
-{$ELSE}
|
|
|
- push [Frame]
|
|
|
-{$ENDIF}
|
|
|
- call dword ptr Func
|
|
|
-end;
|
|
|
-
|
|
|
-
|
|
|
-function CallPointerLocal(Func: pointer; Frame: FramePointer; Param1: pointer): pointer; assembler;
|
|
|
-asm
|
|
|
- mov ax, word ptr Param1
|
|
|
- mov dx, word ptr Param1+2
|
|
|
- push dx
|
|
|
- push ax
|
|
|
-{$IFDEF Windows}
|
|
|
- MOV AX,[Frame]
|
|
|
- AND AL,0FEH
|
|
|
- PUSH AX
|
|
|
-{$ELSE}
|
|
|
- push [Frame]
|
|
|
-{$ENDIF}
|
|
|
- call dword ptr Func
|
|
|
-end;
|
|
|
-
|
|
|
-
|
|
|
-function CallVoidMethodLocal(Func: pointer; Frame: FramePointer; Obj: pointer): pointer; assembler;
|
|
|
-asm
|
|
|
-{$IFDEF Windows}
|
|
|
- MOV AX,[Frame]
|
|
|
- AND AL,0FEH
|
|
|
- PUSH AX
|
|
|
-{$ELSE}
|
|
|
- push [Frame]
|
|
|
-{$ENDIF}
|
|
|
- call dword ptr Func
|
|
|
-end;
|
|
|
-
|
|
|
-
|
|
|
-function CallPointerMethodLocal(Func: pointer; Frame: FramePointer; Obj: pointer; Param1: pointer): pointer; assembler;
|
|
|
-asm
|
|
|
- mov ax, word ptr Param1
|
|
|
- mov dx, word ptr Param1+2
|
|
|
- push dx
|
|
|
- push ax
|
|
|
-{$IFDEF Windows}
|
|
|
- MOV AX,[Frame]
|
|
|
- AND AL,0FEH
|
|
|
- PUSH AX
|
|
|
-{$ELSE}
|
|
|
- push [Frame]
|
|
|
-{$ENDIF}
|
|
|
- call dword ptr Func
|
|
|
-end;
|
|
|
-
|
|
|
-
|
|
|
-function CurrentFramePointer: FramePointer; assembler;
|
|
|
-asm
|
|
|
- mov ax, bp
|
|
|
-end;
|
|
|
-
|
|
|
-
|
|
|
-function PreviousFramePointer: FramePointer; assembler;
|
|
|
-asm
|
|
|
- mov ax, ss:[bp]
|
|
|
-end;
|
|
|
-
|
|
|
-{$endif PPC_BP}
|
|
|
-
|
|
|
-
|
|
|
-end.
|
|
|
-{
|
|
|
- $Log$
|
|
|
- Revision 1.1 2001-01-29 11:31:26 marco
|
|
|
- * added from API. callspec renamed to .pp
|
|
|
-
|
|
|
- Revision 1.1 2000/07/13 06:29:38 michael
|
|
|
- + Initial import
|
|
|
-
|
|
|
- Revision 1.1 2000/01/06 01:20:30 peter
|
|
|
- * moved out of packages/ back to topdir
|
|
|
-
|
|
|
- Revision 1.1 1999/12/23 19:36:47 peter
|
|
|
- * place unitfiles in target dirs
|
|
|
-
|
|
|
- Revision 1.1 1999/11/24 23:36:37 peter
|
|
|
- * moved to packages dir
|
|
|
-
|
|
|
- Revision 1.2 1998/12/16 21:57:16 peter
|
|
|
- * fixed currentframe,previousframe
|
|
|
- + testcall to test the callspec unit
|
|
|
-
|
|
|
- Revision 1.1 1998/12/04 12:48:24 peter
|
|
|
- * moved some dirs
|
|
|
-
|
|
|
- Revision 1.5 1998/12/04 09:53:44 peter
|
|
|
- * removed objtemp global var
|
|
|
-
|
|
|
- Revision 1.4 1998/11/24 17:14:24 peter
|
|
|
- * fixed esi loading
|
|
|
-
|
|
|
-
|
|
|
- Date Version Who Comments
|
|
|
- ---------- -------- ------- -------------------------------------
|
|
|
- 19-Sep-97 0.1 mkoeppe Initial version.
|
|
|
- 22-Sep-97 0.11 fk 0.9.3 support added, self isn't expected
|
|
|
- on the stack in local procedures of methods
|
|
|
- 23-Sep-97 0.12 mkoeppe Cleaned up 0.9.3 conditionals.
|
|
|
- 03-Oct-97 0.13 mkoeppe Fixed esi load in FPC 0.9
|
|
|
- 22-Oct-98 0.14 pfv 0.99.8 support for FPC
|
|
|
-}
|