mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-07-22 02:20:25 +02:00
508 lines
13 KiB
PHP
508 lines
13 KiB
PHP
{
|
|
$Id$
|
|
This file is part of the Free Pascal run time library.
|
|
Copyright (c) 1999-2000 by Michael Van Canneyt
|
|
member of the Free Pascal development team
|
|
|
|
See the file COPYING.FPC, included in this distribution,
|
|
for details about the copyright.
|
|
|
|
This program 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.
|
|
|
|
**********************************************************************}
|
|
|
|
{ Run-Time type information routines - processor dependent part }
|
|
{ I think we should use the pascal version, this code isn't }
|
|
{ much faster }
|
|
|
|
Procedure Initialize (Data,TypeInfo : pointer);[Public,Alias:'FPC_INITIALIZE'];assembler;
|
|
asm
|
|
// Save registers
|
|
push %eax
|
|
push %ebx
|
|
push %ecx
|
|
push %edx
|
|
// decide what type it is
|
|
movl TypeInfo,%ebx
|
|
movb (%ebx),%al
|
|
// This is MANIFESTLY wrong
|
|
subb $9,%al
|
|
jz .LDoAnsiStringInit
|
|
decb %al
|
|
jz .LDoAnsiStringInit
|
|
decb %al
|
|
jz .LDoVariantInit
|
|
decb %al
|
|
jz .LDoArrayInit
|
|
decb %al
|
|
jz .LDoRecordInit
|
|
decb %al
|
|
jz .LDoInterfaceInit
|
|
decb %al
|
|
jz .LDoClassInit
|
|
decb %al
|
|
jz .LDoObjectInit
|
|
decb %al
|
|
// what is called here ??? FK
|
|
jz .LDoClassInit
|
|
subb $4,%al
|
|
jz .LDoDynArrayInit
|
|
jmp .LExitInitialize
|
|
// Interfaces
|
|
.LDoInterfaceInit:
|
|
movl Data, %eax
|
|
movl $0,(%eax)
|
|
jmp .LExitInitialize
|
|
// Variants
|
|
.LDoVariantInit:
|
|
jmp .LExitInitialize
|
|
// dynamic Array
|
|
.LDoDynArrayInit:
|
|
movl Data, %eax
|
|
movl $0,(%eax)
|
|
jmp .LExitInitialize
|
|
.LDoObjectInit:
|
|
.LDoClassInit:
|
|
.LDoRecordInit:
|
|
incl %ebx
|
|
movzbl (%ebx),%eax
|
|
// Skip also recordsize.
|
|
addl $5,%eax
|
|
addl %eax,%ebx
|
|
// %ebx points to element count. Set in %edx
|
|
movl (%ebx),%edx
|
|
addl $4,%ebx
|
|
// %ebx points to First element in record
|
|
.LMyRecordInitLoop:
|
|
decl %edx
|
|
jl .LExitInitialize
|
|
// %ebx points to typeinfo pointer
|
|
// Push type
|
|
pushl (%ebx)
|
|
addl $4,%ebx
|
|
// %ebx points to offset in record.
|
|
// Us it to calculate data
|
|
movl Data,%eax
|
|
addl (%ebx),%eax
|
|
addl $4,%ebx
|
|
// push data
|
|
pushl %eax
|
|
call Initialize
|
|
jmp .LMyRecordInitLoop
|
|
// Array handling
|
|
.LDoArrayInit:
|
|
// Skip array name !!
|
|
incl %ebx
|
|
movzbl (%ebx),%eax
|
|
incl %eax
|
|
addl %eax,%ebx
|
|
// %ebx points to size. Put size in ecx
|
|
movl (%ebx),%ecx
|
|
addl $4, %ebx
|
|
// %ebx points to count. Put count in %edx
|
|
movl (%ebx),%edx
|
|
addl $4, %ebx
|
|
// %ebx points to type. Put into ebx.
|
|
// Start treating elements.
|
|
.LMyArrayInitLoop:
|
|
decl %edx
|
|
jl .LExitInitialize
|
|
// push type
|
|
pushl (%ebx)
|
|
// calculate data
|
|
movl %ecx,%eax
|
|
imull %edx,%eax
|
|
addl Data,%eax
|
|
// push data
|
|
pushl %eax
|
|
call Initialize
|
|
jmp .LMyArrayInitLoop
|
|
// AnsiString handling :
|
|
.LDoAnsiStringInit:
|
|
movl Data, %eax
|
|
movl $0,(%eax)
|
|
.LExitInitialize:
|
|
pop %edx
|
|
pop %ecx
|
|
pop %ebx
|
|
pop %eax
|
|
end;
|
|
|
|
|
|
Procedure int_finalize (Data,TypeInfo: Pointer);[Public,Alias:'FPC_FINALIZE'];assembler;
|
|
asm
|
|
push %eax
|
|
push %ebx
|
|
push %ecx
|
|
push %edx
|
|
// decide what type it is
|
|
movl TypeInfo,%ebx
|
|
movb (%ebx),%al
|
|
subb $9,%al
|
|
jz .LDoAnsiStringFinal
|
|
decb %al
|
|
jz .LDoAnsiStringFinal
|
|
decb %al
|
|
jz .LDoVariantFinal
|
|
decb %al
|
|
jz .LDoArrayFinal
|
|
decb %al
|
|
jz .LDoRecordFinal
|
|
decb %al
|
|
jz .LDoInterfaceFinal
|
|
decb %al
|
|
jz .LDoClassFinal
|
|
decb %al
|
|
jz .LDoObjectFinal
|
|
decb %al
|
|
// what is called here ??? FK
|
|
jz .LDoClassFinal
|
|
subb $4,%al
|
|
jz .LDoDynArrayFinal
|
|
jmp .LExitFinalize
|
|
// Interfaces
|
|
.LDoInterfaceFinal:
|
|
pushl Data
|
|
call Int_Intf_Decr_Ref
|
|
jmp .LExitFinalize
|
|
// Variants
|
|
.LDoVariantFinal:
|
|
jmp .LExitFinalize
|
|
// dynamic Array
|
|
.LDoDynArrayFinal:
|
|
pushl TypeInfo
|
|
pushl Data
|
|
call DYNARRAY_DECR_REF
|
|
jmp .LExitFinalize
|
|
.LDoClassFinal:
|
|
.LDoObjectFinal:
|
|
.LDoRecordFinal:
|
|
incl %ebx
|
|
movzbl (%ebx),%eax
|
|
// Skip also recordsize.
|
|
addl $5,%eax
|
|
addl %eax,%ebx
|
|
// %ebx points to element count. Set in %edx
|
|
movl (%ebx),%edx
|
|
addl $4,%ebx
|
|
// %ebx points to First element in record
|
|
.LMyRecordFinalLoop:
|
|
decl %edx
|
|
jl .LExitFinalize
|
|
// %ebx points to typeinfo pointer
|
|
// Push type
|
|
pushl (%ebx)
|
|
addl $4,%ebx
|
|
// %ebx points to offset.
|
|
// Use to calculate data
|
|
movl Data,%eax
|
|
addl (%ebx),%eax
|
|
addl $4,%ebx
|
|
// push data
|
|
pushl %eax
|
|
call INT_FINALIZE
|
|
jmp .LMyRecordFinalLoop
|
|
// Array handling
|
|
.LDoArrayFinal:
|
|
// Skip array name !!
|
|
incl %ebx
|
|
movzbl (%ebx),%eax
|
|
incl %eax
|
|
addl %eax,%ebx
|
|
// %ebx points to size. Put size in ecx
|
|
movl (%ebx),%ecx
|
|
addl $4, %ebx
|
|
// %ebx points to count. Put count in %edx
|
|
movl (%ebx),%edx
|
|
addl $4, %ebx
|
|
// %ebx points to type. Put into ebx.
|
|
// Start treating elements.
|
|
.LMyArrayFinalLoop:
|
|
decl %edx
|
|
jl .LExitFinalize
|
|
// push type
|
|
pushl (%ebx)
|
|
// calculate data
|
|
movl %ecx,%eax
|
|
imull %edx,%eax
|
|
addl Data,%eax
|
|
// push data
|
|
pushl %eax
|
|
call INT_FINALIZE
|
|
jmp .LMyArrayFinalLoop
|
|
// AnsiString handling :
|
|
.LDoAnsiStringFinal:
|
|
pushl Data
|
|
call ANSISTR_DECR_REF
|
|
.LExitFinalize:
|
|
pop %edx
|
|
pop %ecx
|
|
pop %ebx
|
|
pop %eax
|
|
end;
|
|
|
|
|
|
Procedure Addref (Data,TypeInfo : Pointer); [Public,alias : 'FPC_ADDREF'];Assembler;
|
|
asm
|
|
// Save registers
|
|
push %eax
|
|
push %ebx
|
|
push %ecx
|
|
push %edx
|
|
// decide what type it is
|
|
movl TypeInfo,%ebx
|
|
movb (%ebx),%al
|
|
subb $9,%al
|
|
jz .LDoAnsiStringAddRef
|
|
decb %al
|
|
jz .LDoAnsiStringAddRef
|
|
decb %al
|
|
jz .LDoVariantAddRef
|
|
decb %al
|
|
jz .LDoArrayAddRef
|
|
decb %al
|
|
jz .LDoRecordAddRef
|
|
decb %al
|
|
jz .LDoInterfaceAddRef
|
|
decb %al
|
|
jz .LDoClassAddRef
|
|
decb %al
|
|
jz .LDoObjectAddRef
|
|
decb %al
|
|
// what is called here ??? FK
|
|
jz .LDoClassAddRef
|
|
subb $4,%al
|
|
jz .LDoDynArrayAddRef
|
|
jmp .LExitAddRef
|
|
// Interfaces
|
|
.LDoInterfaceAddRef:
|
|
pushl Data
|
|
call INT_INTF_INCR_REF
|
|
jmp .LExitAddRef
|
|
// Variants
|
|
.LDoVariantAddRef:
|
|
jmp .LExitAddRef
|
|
// Dynamic Arrays
|
|
.LDoDynArrayAddRef:
|
|
movl Data,%eax
|
|
orl %eax,%eax
|
|
jz .LExitAddRef
|
|
lock
|
|
incl -8(%eax)
|
|
jmp .LExitAddRef
|
|
.LDoClassAddRef:
|
|
.LDoObjectAddRef:
|
|
.LDoRecordAddRef:
|
|
incl %ebx
|
|
movzbl (%ebx),%eax
|
|
// Skip also recordsize.
|
|
addl $5,%eax
|
|
addl %eax,%ebx
|
|
// %ebx points to element count. Set in %edx
|
|
movl (%ebx),%edx
|
|
addl $4,%ebx
|
|
// %ebx points to First element in record
|
|
.LMyRecordAddRefLoop:
|
|
decl %edx
|
|
jl .LExitAddRef
|
|
// Push type
|
|
pushl (%ebx)
|
|
addl $4,%ebx
|
|
// Calculate data
|
|
movl Data,%eax
|
|
addl (%ebx),%eax
|
|
addl $4,%ebx
|
|
// push data
|
|
pushl %eax
|
|
call ADDREF
|
|
jmp .LMyRecordAddRefLoop
|
|
// Array handling
|
|
.LDoArrayAddRef:
|
|
// Skip array name !!
|
|
incl %ebx
|
|
movzbl (%ebx),%eax
|
|
incl %eax
|
|
addl %eax,%ebx
|
|
// %ebx points to size. Put size in ecx
|
|
movl (%ebx),%ecx
|
|
addl $4, %ebx
|
|
// %ebx points to count. Put count in %edx
|
|
movl (%ebx),%edx
|
|
addl $4, %ebx
|
|
// %ebx points to type. Put into ebx.
|
|
// Start treating elements.
|
|
.LMyArrayAddRefLoop:
|
|
decl %edx
|
|
jl .LExitAddRef
|
|
// push type
|
|
pushl (%ebx)
|
|
// calculate data
|
|
movl %ecx,%eax
|
|
imull %edx,%eax
|
|
addl Data,%eax
|
|
// push data
|
|
pushl %eax
|
|
call ADDREF
|
|
jmp .LMyArrayAddRefLoop
|
|
// AnsiString handling :
|
|
.LDoAnsiStringAddRef:
|
|
pushl Data
|
|
call ANSISTR_INCR_REF
|
|
.LExitAddRef:
|
|
pop %edx
|
|
pop %ecx
|
|
pop %ebx
|
|
pop %eax
|
|
end;
|
|
|
|
|
|
Procedure DecRef (Data,TypeInfo : Pointer); [Public,alias : 'FPC_DECREF'];Assembler;
|
|
asm
|
|
// Save registers
|
|
push %eax
|
|
push %ebx
|
|
push %ecx
|
|
push %edx
|
|
// decide what type it is
|
|
movl TypeInfo,%ebx
|
|
movb (%ebx),%al
|
|
subb $9,%al
|
|
jz .LDoAnsiStringDecRef
|
|
decb %al
|
|
jz .LDoAnsiStringDecRef
|
|
decb %al
|
|
jz .LDoVariantDecRef
|
|
decb %al
|
|
jz .LDoArrayDecRef
|
|
decb %al
|
|
jz .LDoRecordDecRef
|
|
decb %al
|
|
jz .LDoInterfaceDecRef
|
|
decb %al
|
|
jz .LDoClassDecRef
|
|
decb %al
|
|
jz .LDoObjectDecRef
|
|
decb %al
|
|
// what is called here ??? FK
|
|
jz .LDoClassDecRef
|
|
subb $4,%al
|
|
jz .LDoDynArrayDecRef
|
|
jmp .LExitDecRef
|
|
// Interfaces
|
|
.LDoInterfaceDecRef:
|
|
pushl Data
|
|
call INT_INTF_DECR_REF
|
|
jmp .LExitDecRef
|
|
// Variants
|
|
.LDoVariantDecRef:
|
|
jmp .LExitDecRef
|
|
// Dynamic Arrays
|
|
.LDoDynArrayDecRef:
|
|
pushl TypeInfo
|
|
pushl Data
|
|
call DYNARRAY_DECR_REF
|
|
jmp .LExitDecRef
|
|
.LDoClassDecRef:
|
|
.LDoObjectDecRef:
|
|
.LDoRecordDecRef:
|
|
incl %ebx
|
|
movzbl (%ebx),%eax
|
|
// Skip also recordsize.
|
|
addl $5,%eax
|
|
addl %eax,%ebx
|
|
// %ebx points to element count. Set in %edx
|
|
movl (%ebx),%edx
|
|
addl $4,%ebx
|
|
// %ebx points to First element in record
|
|
.LMyRecordDecRefLoop:
|
|
decl %edx
|
|
jl .LExitDecRef
|
|
// Push type
|
|
pushl (%ebx)
|
|
addl $4,%ebx
|
|
// Calculate data
|
|
movl Data,%eax
|
|
addl (%ebx),%eax
|
|
addl $4,%ebx
|
|
// push data
|
|
pushl %eax
|
|
call DECREF
|
|
jmp .LMyRecordDecRefLoop
|
|
// Array handling
|
|
.LDoArrayDecRef:
|
|
// Skip array name !!
|
|
incl %ebx
|
|
movzbl (%ebx),%eax
|
|
incl %eax
|
|
addl %eax,%ebx
|
|
// %ebx points to size. Put size in ecx
|
|
movl (%ebx),%ecx
|
|
addl $4, %ebx
|
|
// %ebx points to count. Put count in %edx
|
|
movl (%ebx),%edx
|
|
addl $4, %ebx
|
|
// %ebx points to type. Put into ebx.
|
|
// Start treating elements.
|
|
.LMyArrayDecRefLoop:
|
|
decl %edx
|
|
jl .LExitDecRef
|
|
// push type
|
|
pushl (%ebx)
|
|
// calculate data
|
|
movl %ecx,%eax
|
|
imull %edx,%eax
|
|
addl Data,%eax
|
|
// push data
|
|
pushl %eax
|
|
call DECREF
|
|
jmp .LMyArrayDecRefLoop
|
|
// AnsiString handling :
|
|
.LDoAnsiStringDecRef:
|
|
movl Data,%eax
|
|
pushl %eax
|
|
call ANSISTR_DECR_REF
|
|
.LExitDecRef:
|
|
pop %edx
|
|
pop %ecx
|
|
pop %ebx
|
|
pop %eax
|
|
end;
|
|
|
|
procedure FinalizeArray(data,typeinfo : pointer;count,size : longint);
|
|
[Public,Alias:'FPC_FINALIZEARRAY'];
|
|
|
|
var
|
|
i : longint;
|
|
|
|
begin
|
|
for i:=0 to count-1 do
|
|
int_finalize(data+size*i,typeinfo);
|
|
end;
|
|
|
|
{
|
|
$Log$
|
|
Revision 1.7 2000-11-09 17:49:34 florian
|
|
+ FPC_FINALIZEARRAY
|
|
* Finalize to int_finalize renamed
|
|
|
|
Revision 1.6 2000/11/06 21:52:21 florian
|
|
* another fix for interfaces
|
|
|
|
Revision 1.5 2000/11/06 21:35:59 peter
|
|
* removed some warnings
|
|
|
|
Revision 1.4 2000/11/04 16:30:35 florian
|
|
+ interfaces support
|
|
|
|
Revision 1.3 2000/10/21 18:20:17 florian
|
|
* a lot of small changes:
|
|
- setlength is internal
|
|
- win32 graph unit extended
|
|
....
|
|
|
|
Revision 1.2 2000/07/13 11:33:41 michael
|
|
+ removed logs
|
|
}
|