зеркало из https://github.com/mozilla/gecko-dev.git
r=mkaply, a=blizzard Code from Javier Pedemonte and Jeff Jones - rewrite of xptcinvoke to be more efficient
This commit is contained in:
Родитель
602ec7443d
Коммит
9465aa7f97
|
@ -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 = ¶ms->ptr;
|
||||
mov ebx, 01004h ; type = INT | FOURBYTES;
|
||||
jmp @EndIf1
|
||||
@IfElse1: ; } else {
|
||||
mov edx, ecx ; src = ¶ms->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] ; (®_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
|
||||
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче