source: dev/BasicCompiler32/Compile_Object.cpp@ 75

Last change on this file since 75 was 75, checked in by dai_9181, 17 years ago

TYPEINFO→Typeへのリファクタリングを実施。64bitはほぼ完了。32bitが全般的に未完成。

File size: 7.1 KB
Line 
1#include "../BasicCompiler_Common/common.h"
2#include "opcode.h"
3
4void _call_constructor( const CClass *pobj_c, const char *CreateParameter,int ObjectSize,BOOL bSomeObjects){
5 ////////////////////////////
6 // コンストラクタの呼び出し
7 ////////////////////////////
8
9 //この関数を使用する場合は、
10 //・ebxにオブジェクトの個数
11 //・eaxに先頭ポインタ
12 //をセットしておかなければならない
13
14 int jnz_back;
15
16
17 //jnzの番地
18 jnz_back=obp;
19
20 //push ebx
21 op_push(REG_EBX);
22
23 // ※ここでプッシュされた値はコンストラクタのthisポインタとなる
24 //push eax
25 op_push(REG_EAX);
26
27
28
29 ////////////////////////
30 // オーバーロードを解決
31 ////////////////////////
32
33 std::vector<UserProc *> subs;
34 pobj_c->EnumMethod( pobj_c->name, subs );
35
36 UserProc *pUserProc;
37 if( subs.size() > 0 ){
38 //オーバーロードを解決
39 pUserProc=OverloadSolutionWithStrParam(pobj_c->name,
40 subs,CreateParameter,"");
41
42 if(!pUserProc) return;
43 }
44
45 //コンストラクタを呼び出す
46 Opcode_CallProc(CreateParameter,
47 pUserProc,
48 PROCFLAG_NEW,"",0);
49
50
51
52 //pop eax
53 op_pop(REG_EAX);
54
55 //pop ebx
56 op_pop(REG_EBX);
57
58 if(bSomeObjects){
59 //add eax,TypeSize
60 OpBuffer[obp++]=(char)0x05;
61 *((long *)(OpBuffer+obp))=ObjectSize;
62 obp+=sizeof(long);
63
64 //sub ebx,1
65 OpBuffer[obp++]=(char)0x83;
66 OpBuffer[obp++]=(char)0xEB;
67 OpBuffer[obp++]=(char)0x01;
68
69 //jnz ↑
70 OpBuffer[obp++]=(char)0x0F;
71 OpBuffer[obp++]=(char)0x85;
72 *((long *)(OpBuffer+obp))=jnz_back-(obp+sizeof(long));
73 obp+=sizeof(long);
74 }
75}
76void Operator_New( const CClass &classObj, const char *objectSizeStr, const char *parameter, const Type &baseType ){
77 int typeSize = classObj.GetSize();
78
79 if(classObj.IsAbstract()){
80 //抽象クラスだったとき
81 SetError(125,classObj.name,cp);
82 }
83
84 BOOL bSomeObjects=0;
85 if(objectSizeStr[0]){
86 bSomeObjects=1;
87
88 Type tempType;
89 NumOpe(objectSizeStr,Type(),tempType);
90 if( !tempType.IsWhole() ) SetError(49,NULL,cp);
91 ChangeTypeToLong(tempType.GetBasicType());
92
93 //pop eax
94 op_pop(REG_EAX);
95
96 //※添え字上限値であることを考慮
97 //add eax,1
98 OpBuffer[obp++]=(char)0x83;
99 OpBuffer[obp++]=(char)0xC0;
100 OpBuffer[obp++]=(char)0x01;
101
102 //オブジェクトの個数をebxに一時保持
103 //※ebxは関数が呼ばれても不変
104 //mov ebx,eax
105 OpBuffer[obp++]=(char)0x8B;
106 OpBuffer[obp++]=(char)0xD8;
107
108 //imul eax,size
109 OpBuffer[obp++]=(char)0x69;
110 OpBuffer[obp++]=(char)0xC0;
111 *((long *)(OpBuffer+obp))=typeSize;
112 obp+=sizeof(long);
113
114 //add eax,sizeof(DWORD)*2
115 OpBuffer[obp++]=(char)0x05;
116 *((long *)(OpBuffer+obp))=sizeof(DWORD)*3;
117 obp+=sizeof(long);
118
119 //push eax
120 op_push(REG_EAX);
121 }
122 else{
123 //オブジェクトの個数をebxに一時保持
124 //※ebxは関数が呼ばれても不変
125 //mov ebx,1
126 OpBuffer[obp++]=(char)0xBB;
127 *((long *)(OpBuffer+obp))=1;
128 obp+=sizeof(long);
129
130 //push size
131 OpBuffer[obp++]=(char)0x68;
132 *((long *)(OpBuffer+obp))=typeSize+sizeof(DWORD)*3;
133 obp+=sizeof(long);
134 }
135
136 if( baseType.IsObject() ){
137 // オブジェクト インスタンス
138 // ※DeleteはGCで処理
139
140 //call _System_GC_malloc_ForObject
141 extern UserProc *pSub_System_GC_malloc_ForObject;
142 op_call(pSub_System_GC_malloc_ForObject);
143 }
144 else{
145 // オブジェクトポインタ
146 // ※明示的なDeleteが必要
147
148 //call _System_GC_malloc_ForObjectPtr
149 extern UserProc *pSub_System_GC_malloc_ForObjectPtr;
150 op_call(pSub_System_GC_malloc_ForObjectPtr);
151 }
152
153
154 /*
155 確保されたヒープ領域のポインタ(callocの戻り値eax)をpPtrとすると、
156 pPtr-=sizeof(DWORD)*3
157 pPtr[0]=オブジェクトの個数
158 pPtr[1]=オブジェクトのサイズ
159 pPtr[2]=デストラクタの関数ポインタ
160 */
161
162
163 //mov dword ptr[eax],ebx(オブジェクトの個数)
164 OpBuffer[obp++]=(char)0x89;
165 OpBuffer[obp++]=(char)0x18;
166
167 //add eax,sizeof(DWORD)
168 OpBuffer[obp++]=(char)0x05;
169 *((long *)(OpBuffer+obp))=sizeof(DWORD);
170 obp+=sizeof(long);
171
172
173 //mov ecx,TypeSize
174 OpBuffer[obp++]=(char)0xB9;
175 *((long *)(OpBuffer+obp))=typeSize;
176 obp+=sizeof(long);
177
178 //mov dword ptr[eax],ecx
179 OpBuffer[obp++]=(char)0x89;
180 OpBuffer[obp++]=(char)0x08;
181
182 //add eax,sizeof(DWORD)
183 OpBuffer[obp++]=(char)0x05;
184 *((long *)(OpBuffer+obp))=sizeof(DWORD);
185 obp+=sizeof(long);
186
187
188 CMethod *method = classObj.GetDestructorMethod();
189 if( method == NULL ) return;
190
191 //mov ecx,DestructorProcAddr
192 OpBuffer[obp++]=(char)0xB9;
193 pobj_SubAddrSchedule->add(method->pUserProc,0);
194 method->pUserProc->Using();
195 obp+=sizeof(long);
196
197 //mov dword ptr[eax],ecx
198 OpBuffer[obp++]=(char)0x89;
199 OpBuffer[obp++]=(char)0x08;
200
201 //add eax,sizeof(DWORD)
202 OpBuffer[obp++]=(char)0x05;
203 *((long *)(OpBuffer+obp))=sizeof(DWORD);
204 obp+=sizeof(long);
205
206
207 // ※ここでプッシュされた値はNew演算子の戻り値となる
208 //push eax
209 op_push(REG_EAX);
210
211
212 /////////////////////////////////////////////////////////////////////
213
214 ////////////////////////////
215 // コンストラクタの呼び出し
216 ////////////////////////////
217
218 _call_constructor(&classObj,parameter,typeSize,bSomeObjects);
219}
220void OpcodeDelete(const char *Parameter, bool isSweeping){
221 Type tempType;
222 if( !NumOpe(Parameter,Type(),tempType) ){
223 return;
224 }
225 if(!( tempType.IsObjectPtr() || tempType.IsVoidPtr() )) SetError(122,NULL,cp);
226
227 //pop eax
228 op_pop(REG_EAX);
229
230 //sub eax,sizeof(DWORD)*3
231 OpBuffer[obp++]=(char)0x83;
232 OpBuffer[obp++]=(char)0xE8;
233 OpBuffer[obp++]=(char)0x0C;
234
235 //push eax
236 op_push(REG_EAX);
237
238
239 //mov ebx,dword ptr[eax](オブジェクトの個数)
240 OpBuffer[obp++]=(char)0x8B;
241 OpBuffer[obp++]=(char)0x18;
242
243 //add eax,sizeof(DWORD)
244 OpBuffer[obp++]=(char)0x05;
245 *((long *)(OpBuffer+obp))=sizeof(DWORD);
246 obp+=sizeof(long);
247
248
249 //mov esi,dword ptr[eax](オブジェクトのサイズ)
250 OpBuffer[obp++]=(char)0x8B;
251 OpBuffer[obp++]=(char)0x30;
252
253 //add eax,sizeof(DWORD)
254 OpBuffer[obp++]=(char)0x05;
255 *((long *)(OpBuffer+obp))=sizeof(DWORD);
256 obp+=sizeof(long);
257
258
259 //mov edx,dword ptr[eax](デストラクタの関数ポインタ)
260 OpBuffer[obp++]=(char)0x8B;
261 OpBuffer[obp++]=(char)0x10;
262
263 //add eax,sizeof(DWORD)
264 OpBuffer[obp++]=(char)0x05;
265 *((long *)(OpBuffer+obp))=sizeof(DWORD);
266 obp+=sizeof(long);
267
268
269 //mov ecx,eax
270 OpBuffer[obp++]=(char)0x8B;
271 OpBuffer[obp++]=(char)0xC8;
272
273
274 //jnzの番地
275 int jnz_back;
276 jnz_back=obp;
277
278 //push ecx
279 op_push(REG_ECX);
280
281 //push edx
282 op_push(REG_EDX);
283
284 //push ecx(Thisポインタ ※隠れた第一パラメータ)
285 op_push(REG_ECX);
286
287 //call edx
288 OpBuffer[obp++]=(char)0xFF;
289 OpBuffer[obp++]=(char)0xD2;
290
291 //pop edx
292 op_pop(REG_EDX);
293
294 //pop ecx
295 op_pop(REG_ECX);
296
297 //add ecx,esi
298 OpBuffer[obp++]=(char)0x03;
299 OpBuffer[obp++]=(char)0xCE;
300
301 //sub ebx,1
302 OpBuffer[obp++]=(char)0x83;
303 OpBuffer[obp++]=(char)0xEB;
304 OpBuffer[obp++]=(char)0x01;
305
306 //jnz ↑
307 OpBuffer[obp++]=(char)0x0F;
308 OpBuffer[obp++]=(char)0x85;
309 *((long *)(OpBuffer+obp))=jnz_back-(obp+sizeof(long));
310 obp+=sizeof(long);
311
312
313 //////////////////////////////////////////
314 // オブジェクトメンバ変数用のメモリを解放
315 //////////////////////////////////////////
316
317 if( isSweeping ){
318 //call _System_GC_free_for_SweepingDelete
319 extern UserProc *pSub_System_GC_free_for_SweepingDelete;
320 op_call(pSub_System_GC_free_for_SweepingDelete);
321 }
322 else{
323 //call free
324 extern UserProc *pSub_free;
325 op_call(pSub_free);
326 }
327}
Note: See TracBrowser for help on using the repository browser.