source: dev/BasicCompiler32/Compile_Object.cpp@ 94

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

New[]を禁止した。
一部の動的型情報が生成されないバグを修正。
As演算子によるダウンキャストを許可(プログラム的なチェックはまだ走っていない)

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