mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-10-15 14:26:25 +02:00
392 lines
9.6 KiB
PHP
392 lines
9.6 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 }
|
|
|
|
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
|
|
subb $2,%al
|
|
jz .LDoArrayInit
|
|
decb %al
|
|
jz .LDoRecordInit
|
|
subb $2,%al
|
|
jz .LDoClassInit
|
|
decb %al
|
|
jz .LDoObjectInit
|
|
decb %al
|
|
jz .LDoClassInit
|
|
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 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
|
|
subb $2,%al
|
|
jz .LDoArrayFinal
|
|
decb %al
|
|
jz .LDoRecordFinal
|
|
subb $2,%al
|
|
jz .LDoClassFinal
|
|
decb %al
|
|
jz .LDoObjectFinal
|
|
decb %al
|
|
jz .LDoClassFinal
|
|
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 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 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
|
|
subb $2,%al
|
|
jz .LDoArrayAddRef
|
|
decb %al
|
|
jz .LDoRecordAddRef
|
|
subb $2,%al
|
|
jz .LDoClassAddRef
|
|
decb %al
|
|
jz .LDoObjectAddRef
|
|
decb %al
|
|
jz .LDoClassAddRef
|
|
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
|
|
subb $2,%al
|
|
jz .LDoArrayDecRef
|
|
decb %al
|
|
jz .LDoRecordDecRef
|
|
subb $2,%al
|
|
jz .LDoClassDecRef
|
|
decb %al
|
|
jz .LDoObjectDecRef
|
|
decb %al
|
|
jz .LDoClassDecRef
|
|
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;
|
|
|
|
{
|
|
$Log$
|
|
Revision 1.2 2000-07-13 11:33:41 michael
|
|
+ removed logs
|
|
|
|
}
|