1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
|
;
; Copyright (c) Microsoft. All rights reserved.
; Licensed under the MIT license. See LICENSE file in the project root for full license information.
;
; ==++==
;
;
; ==--==
ifdef FEATURE_COMINTEROP
include AsmMacros.inc
include asmconstants.inc
CTPMethodTable__s_pThunkTable equ ?s_pThunkTable@CTPMethodTable@@0PEAVMethodTable@@EA
InstantiatedMethodDesc__IMD_GetComPlusCallInfo equ ?IMD_GetComPlusCallInfo@InstantiatedMethodDesc@@QEAAPEAUComPlusCallInfo@@XZ
ifdef FEATURE_REMOTING
extern CRemotingServices__DispatchInterfaceCall:proc
extern CTPMethodTable__s_pThunkTable:qword
extern InstantiatedMethodDesc__IMD_GetComPlusCallInfo:proc
endif
extern CLRToCOMWorker:proc
extern ProcessCLRException:proc
ifdef FEATURE_REMOTING
;
; in:
; r10: MethodDesc*
; rcx: 'this' object
;
; out:
; METHODDESC_REGISTER (r10) = MethodDesc* (for IL stubs)
;
LEAF_ENTRY GenericComPlusCallStub, _TEXT
;
; check for a null 'this' pointer and
; then see if this is a TransparentProxy
;
test rcx, rcx
jz do_com_call
mov rax, [CTPMethodTable__s_pThunkTable]
cmp [rcx], rax
jne do_com_call
;
; 'this' is a TransparentProxy
;
jmp CRemotingServices__DispatchInterfaceCall
do_com_call:
;
; Check if the call is being made on an InstantiatedMethodDesc.
;
mov ax, [r10 + OFFSETOF__MethodDesc__m_wFlags]
and ax, MethodDescClassification__mdcClassification
cmp ax, MethodDescClassification__mcInstantiated
je GenericComPlusCallWorkerInstantiated
;
; Check if there is an IL stub.
;
mov rax, [r10 + OFFSETOF__ComPlusCallMethodDesc__m_pComPlusCallInfo]
mov rax, [rax + OFFSETOF__ComPlusCallInfo__m_pILStub]
test rax, rax
jz GenericComPlusCallStubSlow
TAILJMP_RAX
LEAF_END GenericComPlusCallStub, _TEXT
; We could inline IMD_GetComPlusCallInfo here but it would be ugly.
NESTED_ENTRY GenericComPlusCallWorkerInstantiated, _TEXT, ProcessCLRException
alloc_stack 68h
save_reg_postrsp r10, 60h
SAVE_ARGUMENT_REGISTERS 70h
SAVE_FLOAT_ARGUMENT_REGISTERS 20h
END_PROLOGUE
mov rcx, r10
call InstantiatedMethodDesc__IMD_GetComPlusCallInfo
RESTORE_FLOAT_ARGUMENT_REGISTERS 20h
RESTORE_ARGUMENT_REGISTERS 70h
mov r10, [rsp + 60h]
mov rax, [rax + OFFSETOF__ComPlusCallInfo__m_pILStub]
add rsp, 68h
TAILJMP_RAX
NESTED_END GenericComPlusCallWorkerInstantiated, _TEXT
endif
ifdef FEATURE_REMOTING
NESTED_ENTRY GenericComPlusCallStubSlow, _TEXT, ProcessCLRException
else
NESTED_ENTRY GenericComPlusCallStub, _TEXT, ProcessCLRException
endif
PROLOG_WITH_TRANSITION_BLOCK 8
;
; Call CLRToCOMWorker.
;
lea rcx, [rsp + __PWTB_TransitionBlock] ; pTransitionBlock
mov rdx, r10 ; MethodDesc *
call CLRToCOMWorker
; handle FP return values
lea rcx, [rsp + __PWTB_FloatArgumentRegisters - 8]
cmp rax, 4
jne @F
movss xmm0, real4 ptr [rcx]
@@:
cmp rax, 8
jne @F
movsd xmm0, real8 ptr [rcx]
@@:
; load return value
mov rax, [rcx]
EPILOG_WITH_TRANSITION_BLOCK_RETURN
ifdef FEATURE_REMOTING
NESTED_END GenericComPlusCallStubSlow, _TEXT
else
NESTED_END GenericComPlusCallStub, _TEXT
endif
endif ; FEATURE_COMINTEROP
end
|