source: dev/BasicCompiler32/Compile_Object.cpp@ 90

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

実行時型情報の生成にほぼ対応した。

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