r=mkaply, a=blizzard
Code from Javier Pedemonte and Jeff Jones - rewrite of xptcinvoke to  be more efficient
This commit is contained in:
mkaply%us.ibm.com 2001-07-25 04:07:05 +00:00
Родитель 602ec7443d
Коммит 9465aa7f97
2 изменённых файлов: 167 добавлений и 56 удалений

Просмотреть файл

@ -29,9 +29,7 @@ include $(DEPTH)/config/autoconf.mk
MODULE = xpcom
LIBRARY_NAME = xptcmd
ifeq ($(MOZ_OS2_TOOLS),VACPP)
CPPSRCS = xptcinvoke_icc.cpp
else
ifeq ($(MOZ_OS2_TOOLS),EMX)
CPPSRCS = xptcinvoke_emx.cpp
endif

Просмотреть файл

@ -47,22 +47,162 @@ COMMENT | -*- Mode: asm; tab-width: 8; c-basic-offset: 4 -*-
.CODE
EXTERN OPTLINK invoke_copy_to_stack__FPUiUlP13nsXPTCVariant:PROC
; Optlink puts pStack in eax, count in edx, params in ecx
CallMethodFromVTable__FPvUiPUiT1T2iT6T3 PROC OPTLINK EXPORT pStack, count, params,
that, index, ibytes, cpc, cpp, fpc, fpp
push ebx
mov eax, esp ; set up value of pStack for copy call
sub eax, dword ptr [ibytes] ; make room for copied params
mov esp, eax ; adjust stack pointer accordingly
sub esp, 0Ch ; make room for three invoke_copy params
call invoke_copy_to_stack__FPUiUlP13nsXPTCVariant
t_Int4Bytes equ 001004h
t_Int8Bytes equ 001008h
t_Float4Bytes equ 000104h
t_Float8Bytes equ 000108h
add esp, 0Ch ; reset esp
TypesArray dd t_Int4Bytes ; nsXPTType::T_I8
dd t_Int4Bytes ; nsXPTType::T_I16
dd t_Int4Bytes ; nsXPTType::T_I32
dd t_Int8Bytes ; nsXPTType::T_I64 (***)
dd t_Int4Bytes ; nsXPTType::T_U8
dd t_Int4Bytes ; nsXPTType::T_U16
dd t_Int4Bytes ; nsXPTType::T_U32
dd t_Int8Bytes ; nsXPTType::T_U64 (***)
dd t_Float4Bytes ; nsXPTType::T_FLOAT (***)
dd t_Float8Bytes ; nsXPTType::T_DOUBLE (***)
dd t_Int4Bytes ; nsXPTType::T_BOOL
dd t_Int4Bytes ; nsXPTType::T_CHAR
dd t_Int4Bytes ; nsXPTType::T_WCHAR
dd t_Int4Bytes ; TD_VOID
dd t_Int4Bytes ; TD_PNSIID
dd t_Int4Bytes ; TD_DOMSTRING
dd t_Int4Bytes ; TD_PSTRING
dd t_Int4Bytes ; TD_PWSTRING
dd t_Int4Bytes ; TD_INTERFACE_TYPE
dd t_Int4Bytes ; TD_INTERFACE_IS_TYPE
dd t_Int4Bytes ; TD_ARRAY
dd t_Int4Bytes ; TD_PSTRING_SIZE_IS
dd t_Int4Bytes ; TD_PWSTRING_SIZE_IS
; All other values default to 4 byte int/ptr
; Optlink puts 'that' in eax, 'index' in edx, 'paramcount' in ecx
; 'params' is on the stack...
XPTC_InvokeByIndex PROC OPTLINK EXPORT USES ebx edi esi, that, index, paramcount, params
LOCAL cparams:dword, fparams:dword, reg_edx:dword, reg_ecx:dword, count:dword
mov dword ptr [that], eax ; that
mov dword ptr [index], edx ; index
mov dword ptr [paramcount], ecx ; paramcount
mov dword ptr [count], ecx ; save a copy of count
; #define FOURBYTES 4
; #define EIGHTBYTES 8
; #define FLOAT 0x00000100
; #define INT 0x00001000
; #define LENGTH 0x000000ff
;
;types[ ] = {
; FOURBYES | INT, // int/uint/ptr/etc
; EIGHTBYTES | INT, // long long
; FOURBYES | FLOAT, // float
; EIGHTBYTES | FLOAT // double
;};
; params+00h = val // double
; params+08h = ptr
; params+0ch = type
; params+0dh = flags
; PTR_IS_DATA = 0x01
; ecx = params
; edx = src
; edi = dst
; ebx = type (bh = int/float, bl = byte count)
xor eax, eax
mov dword ptr [cparams],eax ; cparams = 0;
mov dword ptr [fparams],eax ; fparams = 0;
shl ecx, 03h
sub esp, ecx ; dst/esp = add esp, paramCount * 8
mov edi, esp
push eax ; push 0 // "end" of floating point register stack...
mov ecx, dword ptr [params] ; // params is a "register" variable
@While1:
mov eax, dword ptr [count] ; while( count-- )
or eax, eax ; // (test for zero)
je @EndWhile1
dec eax
mov dword ptr [count], eax
; {
test byte ptr [ecx+0dh],01h ; if ( params->flags & PTR_IS_DATA ) {
je @IfElse1
lea edx, dword ptr [ecx+08h] ; src = &params->ptr;
mov ebx, 01004h ; type = INT | FOURBYTES;
jmp @EndIf1
@IfElse1: ; } else {
mov edx, ecx ; src = &params->val
movzx eax, byte ptr [ecx+0ch] ; type = types[params->type];
cmp eax, 22 ; // range check params->type... (0 to 22)
jle @TypeOK
mov eax,2 ; // all others default to 4 byte int
@TypeOK:
mov ebx, dword ptr [TypesArray+eax*4]
@EndIf1: ; }
test bh, 001h ; if ( type & FLOAT ) {
je @EndIf2
cmp dword ptr [fparams], 4 ; if ( fparams < 4 ) {
jge @EndIf3
push edx ; push src;
push ebx ; push type
inc dword ptr [fparams] ; fparams++;
;;; movzx eax, bl ; // dst += (type & LENGTH);
;;; add edi, eax ;
;;; xor ebx, ebx ; // type = 0; // "handled"
@EndIf3: ; }
@EndIf2: ; }
; // copy bytes...
@While2: or bl, bl ; while( type & LENGTH ) {
je @EndWhile2
test bh, 010h ; if( type & INT ) {
je @EndIf4
cmp dword ptr [cparams], 8 ; if( cparams < 8 ) {
jge @EndIf5
lea eax, dword ptr [reg_edx] ; (&reg_edx)[cparams] = *src;
sub eax, dword ptr [cparams]
mov esi, dword ptr [edx]
mov dword ptr [eax], esi
add dword ptr [cparams], 4 ; cparams += 4;
;;; jmp @NoCopy ; // goto nocopy;
@EndIf5: ; }
@EndIf4: ; }
mov eax, dword ptr [edx] ; *dst = *src;
mov dword ptr [edi], eax
@NoCopy: ;nocopy:
add edi, 4 ; dst++;
add edx, 4 ; src++;
sub bl, 4 ; type -= 4;
jmp @While2
@EndWhile2: ; }
add ecx, 010h ; params++;
jmp @While1
@EndWhile1: ; }
; // Set up fpu and regs can make the call...
@While3: pop ebx ; while ( pop type ) {
or ebx, ebx
je @EndWhile3
pop edx ; pop src
cmp bl, 08h ; if( type & EIGHTBYTES ) {
jne @IfElse6
fld qword ptr [edx] ; fld qword ptr [src]
jmp @EndIf6
@IfElse6: ; } else {
fld dword ptr [edx] ; fld dword ptr [src]
@EndIf6: ; }
jmp @While3
@EndWhile3: ; }
; make the call
mov eax, dword ptr [that] ; get 'that' ("this" ptr)
mov edx, dword ptr [eax]
mov ebx, dword ptr [index] ; get index
shl ebx, 03h ; index *= 8 bytes per method
add ebx, 08h ; += 8 at head of vtable
@ -70,48 +210,21 @@ CallMethodFromVTable__FPvUiPUiT1T2iT6T3 PROC OPTLINK EXPORT pStack, count, pa
mov ecx, dword ptr [ebx+04h]
add eax, ecx
push eax
sub esp, 04h ; make room for 'this' ptr on stack
mov edx, dword ptr [reg_edx]
mov ecx, dword ptr [reg_ecx]
;**************************************
; Load fpparams into registers
;**************************************
mov ecx, dword ptr [fpc] ; get fpcount
cmp ecx, 0h ; check fp count
je loadcp ; if no fpparams, goto 'loadcp'
call dword ptr [ebx] ; call method
loadfps: dec cl ; ecx--
mov edx, ecx ; get fpparams array offset
shl edx, 03h ; * 8 bytes per fp param
add edx, dword ptr [fpp] ; add base array addr
fld qword ptr [edx] ; add fp param at location 'edx'
cmp cl, 0h ;
jne loadfps ; if more params, loop around
mov ecx, dword ptr [paramcount]
shl ecx, 03h
add esp, ecx ; remove space on stack for params
add esp, 04h ; remove space on stack for 'this' ptr
ret
;*************************************
; Load cparams into registers
;*************************************
loadcp: cmp dword ptr [cpc], 0h ; check param count
je done ; if no params, goto 'done' and call function
mov edx, dword ptr [cpp] ; load params
cmp dword ptr [cpc], 01h ; check param count
je loadone ; only one param to load, goto loadone
mov ecx, [edx + 04h] ; load 2nd param if present
loadone: mov edx, [edx] ; load 1st param if present
;***********************
; Call Function
;***********************
done: call dword ptr [ebx] ; call method
add esp, dword ptr [ibytes] ; deflate stack by ibytes
add esp, 04h ; plus 4
pop ebx;
ret ; method rc in eax
CallMethodFromVTable__FPvUiPUiT1T2iT6T3 ENDP
ENDP
END