comparison dyncall/dyncall_callvm_x64.c @ 84:67961454902b

- bigger cleanup in callvm code * changed init of most callvms to reuse code and for consistency * removed unused functions * general changes for consistency * added some missing cconv defines do mode calls - fixed potential buffer overrun on arm64 - fixed sparc and x64 mode setting (only one mode, but wasn't (pointlessly) resettable) - error code handling (dcGetError) changes, flag is now cleared (work still underway) - Changelog update
author cslag
date Wed, 06 Apr 2016 00:21:51 +0200
parents 3e629dc19168
children f5577f6bf97a
comparison
equal deleted inserted replaced
83:54930a037e8a 84:67961454902b
31 31
32 #include "dyncall_callvm_x64.h" 32 #include "dyncall_callvm_x64.h"
33 #include "dyncall_alloc.h" 33 #include "dyncall_alloc.h"
34 #include "dyncall_struct.h" 34 #include "dyncall_struct.h"
35 35
36 static DCCallVM* dc_callvm_new_x64(DCCallVM_vt* vt, DCsize size)
37 {
38 DCCallVM_x64* self = (DCCallVM_x64*)dcAllocMem(sizeof(DCCallVM_x64)+size);
39
40 dc_callvm_base_init(&self->mInterface, vt);
41
42 /* Since we store register parameters in DCCallVM_x64 directly, adjust the stack size. */
43 size -= sizeof(DCRegData_x64);
44 size = (((signed long)size) < 0) ? 0 : size;
45
46
47 self->mRegCount.i = self->mRegCount.f = 0;
48
49 dcVecInit(&self->mVecHead, size);
50 return (DCCallVM*)self;
51 }
52
53 36
54 static void dc_callvm_free_x64(DCCallVM* in_self) 37 static void dc_callvm_free_x64(DCCallVM* in_self)
55 { 38 {
56 dcFreeMem(in_self); 39 dcFreeMem(in_self);
57 } 40 }
59 42
60 static void dc_callvm_reset_x64(DCCallVM* in_self) 43 static void dc_callvm_reset_x64(DCCallVM* in_self)
61 { 44 {
62 DCCallVM_x64* self = (DCCallVM_x64*)in_self; 45 DCCallVM_x64* self = (DCCallVM_x64*)in_self;
63 dcVecReset(&self->mVecHead); 46 dcVecReset(&self->mVecHead);
64 self->mRegCount.i = self->mRegCount.f = 0; 47 self->mRegCount.i = self->mRegCount.f = 0;
65 }
66
67
68 static void dc_callvm_mode_x64(DCCallVM* self, DCint mode)
69 {
70 switch(mode) {
71 case DC_CALL_C_DEFAULT:
72 case DC_CALL_C_ELLIPSIS:
73 break;
74 default:
75 self->mError = DC_ERROR_UNSUPPORTED_MODE;
76 break;
77 }
78 } 48 }
79 49
80 50
81 static void dc_callvm_argLongLong_x64(DCCallVM* in_self, DClonglong x) 51 static void dc_callvm_argLongLong_x64(DCCallVM* in_self, DClonglong x)
82 { 52 {
185 #endif 155 #endif
186 target 156 target
187 ); 157 );
188 } 158 }
189 159
160
161 static void dc_callvm_mode_x64(DCCallVM* in_self, DCint mode);
190 162
191 DCCallVM_vt gVT_x64 = 163 DCCallVM_vt gVT_x64 =
192 { 164 {
193 &dc_callvm_free_x64 165 &dc_callvm_free_x64
194 , &dc_callvm_reset_x64 166 , &dc_callvm_reset_x64
214 , (DCdoublevmfunc*) &dc_callvm_call_x64 186 , (DCdoublevmfunc*) &dc_callvm_call_x64
215 , (DCpointervmfunc*) &dc_callvm_call_x64 187 , (DCpointervmfunc*) &dc_callvm_call_x64
216 , NULL /* callStruct */ 188 , NULL /* callStruct */
217 }; 189 };
218 190
219 191 /* mode: only a single mode available currently. */
220 DCCallVM* dcNewCallVM_x64(DCsize size) 192 static void dc_callvm_mode_x64(DCCallVM* in_self, DCint mode)
221 { 193 {
222 return dc_callvm_new_x64(&gVT_x64, size); 194 DCCallVM_x64* self = (DCCallVM_x64*)in_self;
223 } 195 DCCallVM_vt* vt;
224 196
197 switch(mode) {
198 case DC_CALL_C_DEFAULT:
199 #if defined(DC_UNIX)
200 case DC_CALL_C_X64_SYSV:
201 #else
202 case DC_CALL_C_X64_WIN64:
203 #endif
204 case DC_CALL_C_ELLIPSIS:
205 case DC_CALL_C_ELLIPSIS_VARARGS:
206 vt = &gVT_x64;
207 break;
208 default:
209 self->mInterface.mError = DC_ERROR_UNSUPPORTED_MODE;
210 return;
211 }
212 dc_callvm_base_init(&self->mInterface, vt);
213 }
214
215 /* Public API. */
225 DCCallVM* dcNewCallVM(DCsize size) 216 DCCallVM* dcNewCallVM(DCsize size)
226 { 217 {
227 return dcNewCallVM_x64(size); 218 DCCallVM_x64* p = (DCCallVM_x64*)dcAllocMem(sizeof(DCCallVM_x64)+size);
228 } 219
229 220 dc_callvm_mode_x64((DCCallVM*)p, DC_CALL_C_DEFAULT);
221
222 /* Since we store register parameters in DCCallVM_x64 directly, adjust the stack size. */
223 size -= sizeof(DCRegData_x64);
224 size = (((signed long)size) < 0) ? 0 : size;
225 dcVecInit(&p->mVecHead, size);
226 dc_callvm_reset_x64((DCCallVM*)p);
227
228 return (DCCallVM*)p;
229 }
230