source: dev/branches/egtra/ab5.0/abdev/compiler_x86/Compile_Func.cpp

Last change on this file was 689, checked in by イグトランス (egtra), 16 years ago

#149「デリゲートに非クラスメンバ関数を指定できない」を解消

File size: 23.2 KB
Line 
1#include "stdafx.h"
2
3#include <Compiler.h>
4
5#include "../BasicCompiler_Common/common.h"
6#include "Opcode.h"
7
8#include "FunctionValue.h"
9
10void Opcode_Func_ObjPtr( const char *Parameter, Type &resultType, bool isCallOn );
11
12int GetFunctionFromName(char *FuncName){
13 if( lstrcmpi( FuncName, "CUDbl" ) == 0 ) return FUNC_CUDBL;
14 if( lstrcmpi( FuncName, "Fix" ) == 0 ) return FUNC_FIX;
15 if( lstrcmpi( FuncName, "Len" ) == 0 ) return FUNC_LEN;
16 if( lstrcmpi( FuncName, "AddressOf" ) == 0 ) return FUNC_ADDRESSOF;
17 if( lstrcmpi( FuncName, "SizeOf" ) == 0 ) return FUNC_SIZEOF;
18 if( lstrcmpi( FuncName, "__ClassSizeOf" ) == 0 ) return FUNC_CLASS_SIZEOF;
19 if( lstrcmpi( FuncName, "VarPtr" ) == 0 ) return FUNC_VARPTR;
20 if( lstrcmpi( FuncName, "ObjPtr" ) == 0 ) return FUNC_OBJPTR;
21 if( lstrcmpi( FuncName, "__delegate_dynamicmethod_call" ) == 0 ) return FUNC_DELEGATE_DYNAMICMETHOD_CALL;
22 if( lstrcmpi( FuncName, "__delegate_staticmethod_call" ) == 0 ) return FUNC_DELEGATE_STATICMETHOD_CALL;
23 if( lstrcmpi( FuncName, "_System_GetNowScopeCatchAddresses" ) == 0 )return FUNC_SYSTEM_GET_NOW_SCOPE_CATCH_ADDRESS;
24 if( lstrcmpi( FuncName, "_System_GetNowScopeFinallyAddresses" ) == 0 )return FUNC_SYSTEM_GET_NOW_SCOPE_FINALLY_ADDRESS;
25 if( lstrcmpi( FuncName, "_System_GetBp" ) == 0 ) return FUNC_SYSTEM_GET_BP;
26 if( lstrcmpi( FuncName, "_System_GetSp" ) == 0 ) return FUNC_SYSTEM_GET_SP;
27 if( lstrcmp( FuncName, "_System_GetComVtbl" ) == 0 ) return FUNC_SYSTEM_GET_COM_VTBL;
28 if( lstrcmp( FuncName, "_System_GetVtblList" ) == 0 ) return FUNC_SYSTEM_GET_VTBL_LIST;
29 if( lstrcmp( FuncName, "_System_GetDefaultConstructor" ) == 0 ) return FUNC_SYSTEM_GET_DEFAULT_CONSTRUCTOR;
30 if( lstrcmp( FuncName, "_System_GetDestructor" ) == 0 ) return FUNC_SYSTEM_GET_DESTRUCTOR;
31 if( lstrcmpi( FuncName, "GetDouble" ) == 0 ) return FUNC_GETDOUBLE;
32 if( lstrcmpi( FuncName, "GetSingle" ) == 0 ) return FUNC_GETSINGLE;
33 if( lstrcmpi( FuncName, "GetQWord" ) == 0 ) return FUNC_GETQWORD;
34 if( lstrcmpi( FuncName, "GetDWord" ) == 0 ) return FUNC_GETDWORD;
35 if( lstrcmpi( FuncName, "GetWord" ) == 0 ) return FUNC_GETWORD;
36 if( lstrcmpi( FuncName, "GetByte" ) == 0 ) return FUNC_GETBYTE;
37 return 0;
38}
39
40void Opcode_Func_Fix(const char *lpszParms){
41 Type resultType;
42 if( !NumOpe( lpszParms, Type(), resultType ) ){
43 return;
44 }
45
46 if( resultType.IsDouble() ){
47 //fld qword ptr[esp]
48 compiler.codeGenerator.op_fld_ptr_esp(DEF_DOUBLE);
49
50 //fnstcw word ptr[esp]
51 compiler.codeGenerator.PutOld(
52 (char)0xD9,
53 (char)0x3C,
54 (char)0x24
55 );
56
57 //mov ax,word ptr[esp]
58 compiler.codeGenerator.op_mov_RM( sizeof(short), REG_EAX, REG_ESP, 0, MOD_BASE );
59
60 //or ah,0Ch
61 compiler.codeGenerator.PutOld(
62 (char)0x80,
63 (char)0xCC,
64 (char)0x0C
65 );
66
67 //mov word ptr[esp-2],ax
68 compiler.codeGenerator.op_mov_MR( sizeof(short), REG_EAX, REG_ESP, -2, MOD_BASE_DISP8 );
69
70 //fldcw word ptr[esp-2]
71 compiler.codeGenerator.PutOld(
72 (char)0xD9,
73 (char)0x6C,
74 (char)0x24,
75 (char)0xFE
76 );
77
78 //fistp dword ptr[esp+4]
79 compiler.codeGenerator.PutOld(
80 (char)0xDB,
81 (char)0x5C,
82 (char)0x24,
83 (char)0x04
84 );
85
86 //fldcw word ptr[esp]
87 compiler.codeGenerator.PutOld(
88 (char)0xD9,
89 (char)0x2C,
90 (char)0x24
91 );
92
93 //add esp,4
94 compiler.codeGenerator.op_add_esp(4);
95 }
96 else if( resultType.IsSingle() ){
97 //fld dword ptr[esp]
98 compiler.codeGenerator.op_fld_ptr_esp(DEF_SINGLE);
99
100 //sub esp,4
101 compiler.codeGenerator.op_sub_esp(4);
102
103 //fnstcw word ptr[esp]
104 compiler.codeGenerator.PutOld(
105 (char)0xD9,
106 (char)0x3C,
107 (char)0x24
108 );
109
110 //mov ax,word ptr[esp]
111 compiler.codeGenerator.op_mov_RM( sizeof(short), REG_EAX, REG_ESP, 0, MOD_BASE );
112
113 //or ah,0Ch
114 compiler.codeGenerator.PutOld(
115 (char)0x80,
116 (char)0xCC,
117 (char)0x0C
118 );
119
120 //mov word ptr[esp-2],ax
121 compiler.codeGenerator.op_mov_MR( sizeof(short), REG_EAX, REG_ESP, -2, MOD_BASE_DISP8 );
122
123 //fldcw word ptr[esp-2]
124 compiler.codeGenerator.PutOld(
125 (char)0xD9,
126 (char)0x6C,
127 (char)0x24,
128 (char)0xFE
129 );
130
131 //fistp dword ptr[esp+4]
132 compiler.codeGenerator.PutOld(
133 (char)0xDB,
134 (char)0x5C,
135 (char)0x24,
136 (char)0x04
137 );
138
139 //fldcw word ptr[esp]
140 compiler.codeGenerator.PutOld(
141 (char)0xD9,
142 (char)0x2C,
143 (char)0x24
144 );
145
146 //add esp,4
147 compiler.codeGenerator.op_add_esp(4);
148 }
149 else if( resultType.Is64() ){
150 //pop eax
151 compiler.codeGenerator.op_pop(REG_EAX);
152
153 //add esp,4
154 compiler.codeGenerator.op_add_esp(4);
155
156 //push eax
157 compiler.codeGenerator.op_push(REG_EAX);
158 }
159
160 //pop eax
161 compiler.codeGenerator.op_pop(REG_EAX);
162}
163
164void Opcode_Func_CUDbl(const char *Parameter){
165 Type resultType;
166 if( !NumOpe(Parameter,Type(),resultType) ){
167 return;
168 }
169 ChangeTypeToLong(resultType.GetBasicType());
170
171 //pop eax
172 compiler.codeGenerator.op_pop(REG_EAX);
173
174 //push 0
175 compiler.codeGenerator.op_push_V( 0 );
176
177 //push eax
178 compiler.codeGenerator.op_push(REG_EAX);
179
180 //fild qword ptr[esp]
181 compiler.codeGenerator.op_fld_ptr_esp(DEF_INT64);
182
183 //add esp,8
184 compiler.codeGenerator.op_add_esp(8);
185}
186void Opcode_Func_Len(const char *Parameter){
187 BOOL bArrayHead;
188
189 const char *tempParm=Parameter;
190 char temporary[VN_SIZE];
191 char temp2[32];
192 Type type;
193 if( !GetVarType(Parameter,type,0) ){
194 sprintf(temporary,"_System_DummyStr2=%s",Parameter);
195 OpcodeCalc(temporary);
196
197 lstrcpy(temp2,"_System_DummyStr2");
198 tempParm=temp2;
199
200 type.SetType( DEF_OBJECT, compiler.GetObjectModule().meta.GetClasses().GetStringClassPtr() );
201 }
202
203 if( type.IsStringClass() ){
204 //Stringオブジェクトの場合
205 sprintf(temporary,"%s.Length",tempParm);
206
207 int reg=REG_RAX;
208 NumOpe(temporary,Type(),Type());
209
210 //pop eax
211 compiler.codeGenerator.op_pop(REG_EAX);
212
213 return;
214 }
215
216 Subscripts subscripts;
217 RELATIVE_VAR RelativeVar;
218 if(!GetVarOffsetReadOnly(tempParm,&RelativeVar,type,&subscripts)) return;
219
220 if(type.GetBasicType()&FLAG_PTR){
221 type.SetBasicType( type.GetBasicType() & ( ~FLAG_PTR ) );
222
223 bArrayHead=1;
224 }
225 else bArrayHead=0;
226
227 int typeSize = type.GetSize();
228
229 if(bArrayHead) typeSize*=JumpSubScripts(subscripts);
230
231 //mov eax,typeSize
232 compiler.codeGenerator.op_mov_RV( REG_EAX, typeSize );
233}
234
235void _Opcode_Func_AddressOf( const char *methodInstanceName, const UserProc &userProc )
236{
237 if( userProc.IsVirtual() ){
238 ///////////////////////////////
239 // 仮想関数の場合
240 // thisポインタをrcxにコピー
241 ///////////////////////////////
242
243 const CClass *pobj_c;
244
245 char ObjectName[VN_SIZE];
246 ReferenceKind referenceKind;
247 SplitObjectName( methodInstanceName, ObjectName, referenceKind );
248
249 if(ObjectName[0]){
250 if(lstrcmpi(ObjectName,"Super")==0) goto InClassMember;
251 else{
252 RELATIVE_VAR RelativeVar;
253 Type type;
254 if(!GetVarOffsetReadOnly(ObjectName,&RelativeVar,type)) return;
255 SetVarPtrToEax(&RelativeVar);
256
257 //mov ecx,eax
258 compiler.codeGenerator.op_mov_RR(REG_ECX,REG_EAX);
259
260 //参照タイプが整合しているかをチェック
261 if( !( type.IsObject() && referenceKind == RefDot
262 || type.IsObjectPtr() && referenceKind == RefPointer ) )
263 {
264 compiler.errorMessenger.Output(104,ObjectName,cp);
265 }
266
267 if(type.IsObjectPtr()){
268 //mov ecx,dword ptr[ecx]
269 compiler.codeGenerator.op_mov_RM(sizeof(long),REG_ECX,REG_ECX,0,MOD_BASE);
270 }
271 }
272 }
273 else{
274InClassMember:
275 //自身のオブジェクトのThisポインタをrcxにコピー
276 SetThisPtrToReg(REG_RCX);
277
278 pobj_c = &compiler.GetCompilingClass();
279 }
280
281
282 int vtblIndex;
283 if( pobj_c->IsInterface() )
284 {
285 // インターフェイスメソッド呼び出し
286
287 int offset_vtbl = compiler.GetObjectModule().meta.GetClasses().GetInterfaceInfoClassPtr()->GetMemberOffset( "__vtbl" );
288
289
290 // vtblのポインタを取得
291 //mov edx,dword ptr[ecx+offset_vtbl]
292 compiler.codeGenerator.op_mov_RM( sizeof(long), REG_EDX, REG_ECX, offset_vtbl, MOD_BASE_DISP8 );
293
294 int offset_this = compiler.GetObjectModule().meta.GetClasses().GetInterfaceInfoClassPtr()->GetMemberOffset( "__this" );
295
296
297
298 // インターフェイスの場合は更に__thisを取得する
299 //mov rcx,qword ptr[rcx+offset_this]
300 compiler.codeGenerator.op_mov_RM( sizeof(long), REG_ECX, REG_ECX, offset_this, MOD_BASE_DISP8 );
301
302 int vtblMasterListIndex;
303 pobj_c->GetVtblMasterListIndexAndVtblIndex( &userProc, vtblMasterListIndex, vtblIndex );
304 if( vtblMasterListIndex != 0 )
305 {
306 compiler.errorMessenger.OutputFatalError();
307 }
308 }
309 else if( pobj_c->IsComInterface() )
310 {
311 // COMインターフェイス メソッド呼び出し
312
313 //仮想関数(オブジェクトメソッド)呼び出し
314 // pObj -> vtbl1 -> func1
315 // -> func2
316 // -> func3
317
318 int vtblMasterListIndex;
319 pobj_c->GetVtblMasterListIndexAndVtblIndex( &userProc, vtblMasterListIndex, vtblIndex );
320
321 // vtblのポインタを取得
322 //mov edx,dword ptr[ecx]
323 compiler.codeGenerator.op_mov_RM( sizeof(long), REG_EDX, REG_ECX, 0, MOD_BASE );
324 }
325 else
326 {
327 //仮想関数(オブジェクトメソッド)呼び出し
328 // pObj -> vtbl_master_list -> vtbl1 -> func1
329 // -> func2
330 // -> func3
331 // -> vtbl2 -> func1
332 // -> func2
333 // -> func3
334
335 int vtblMasterListIndex;
336 pobj_c->GetVtblMasterListIndexAndVtblIndex( &userProc, vtblMasterListIndex, vtblIndex );
337
338 // vtblマスターリストのポインタを取得
339 //mov edx,dword ptr[ecx+sizeof(com_vtbl)]
340 compiler.codeGenerator.op_mov_RM( sizeof(long), REG_EDX, REG_ECX, PTR_SIZE, MOD_BASE_DISP8 );
341
342 // vtblのポインタを取得
343 //mov edx,dword ptr[edx+vtblMasterListIndex]
344 compiler.codeGenerator.op_mov_RM( sizeof(long), REG_EDX, REG_EDX, vtblMasterListIndex*PTR_SIZE, MOD_BASE_DISP32 );
345 }
346
347 //mov eax,dword ptr[edx+func_index]
348 if( vtblIndex * PTR_SIZE <= 0x7F )
349 {
350 compiler.codeGenerator.op_mov_RM(sizeof(long),REG_EAX,REG_EDX,vtblIndex*PTR_SIZE,MOD_BASE_DISP8);
351 }
352 else{
353 compiler.codeGenerator.op_mov_RM(sizeof(long),REG_EAX,REG_EDX,vtblIndex*PTR_SIZE,MOD_BASE_DISP32);
354 }
355 }
356 else{
357 //一般の関数
358
359 //mov eax,ProcAddr
360 compiler.codeGenerator.op_addressof( REG_EAX, &userProc );
361 }
362
363 userProc.Using();
364}
365void Opcode_CreateDelegate( const CClass &dgClass, const char *methodInstanceName, const UserProc &userProc )
366{
367 /////////////////////////////////////////////////////////////////
368 // 関数ポインタをpush
369 /////////////////////////////////////////////////////////////////
370
371 //push AddressOf(userProc)
372 _Opcode_Func_AddressOf( methodInstanceName, userProc );
373 compiler.codeGenerator.op_push( REG_EAX );
374
375
376 if( userProc.HasParentClass() && userProc.GetMethod().IsDynamic() )
377 {
378 /////////////////////////////////////////////////////////////////
379 // オブジェクト ポインタをpush
380 /////////////////////////////////////////////////////////////////
381
382 // オブジェクト名を取得
383 char objectName[VN_SIZE];
384 char memberName[VN_SIZE];
385 char *thisPtrName = "This";
386 Type type;
387 if( SplitMemberName( methodInstanceName, objectName, memberName ) )
388 {
389 if( GetVarType( objectName, type, false ) )
390 {
391 thisPtrName = objectName;
392 }
393 }
394
395 // オブジェクト ポインタを取得
396 Opcode_Func_ObjPtr( thisPtrName, type, true );
397
398 //push eax
399 compiler.codeGenerator.op_push( REG_EAX );
400 }
401
402
403 /////////////////////////////////////////////////////////////////
404 // call _CreateDynamicDelegate/_CreateStaticDelegate
405 /////////////////////////////////////////////////////////////////
406
407 std::vector<const UserProc *> subs;
408 if( userProc.HasParentClass() && userProc.GetMethod().IsDynamic() )
409 {
410 dgClass.GetStaticMethods().Enum( "_CreateDynamicDelegate", subs );
411 }
412 else
413 {
414 dgClass.GetStaticMethods().Enum( "_CreateStaticDelegate", subs );
415 }
416
417 // call _CreateDynamicDelegate
418 compiler.codeGenerator.op_call( subs[0] );
419}
420void Opcode_Func_AddressOf( const char *name, const Type &baseType, bool isCallOn, Type &resultType )
421{
422 extern int cp;
423
424 const Parameters *pBaseParams = NULL;
425 const Type *pBaseReturnType = NULL;
426 if( baseType.IsProcPtr() )
427 {
428 // 左辺で関数ポインタを要求されているとき
429 const ProcPointer *pTempProcPointer = compiler.GetObjectModule().meta.GetProcPointers()[baseType.GetIndex()];
430 pBaseParams = &pTempProcPointer->Params();
431 pBaseReturnType = &pTempProcPointer->ReturnType();
432 }
433 else if( baseType.IsDelegate() )
434 {
435 // 左辺でデリゲートを要求されているとき
436 const Delegate *pTempDelegate = &compiler.GetObjectModule().meta.ToDelegate( baseType.GetClass() );
437 pBaseParams = &pTempDelegate->Params();
438 pBaseReturnType = &pTempDelegate->ReturnType();
439 }
440
441 const UserProc *pUserProc;
442 if( pBaseParams && pBaseReturnType )
443 {
444 //左辺の型にのっとり、オーバーロードを解決
445
446 std::vector<const UserProc *> subs;
447 GetOverloadSubHash( name, subs );
448 if( subs.size() == 0 ){
449 compiler.errorMessenger.Output(27,name,cp);
450 return;
451 }
452
453 //オーバーロードを解決
454 pUserProc=OverloadSolution( name, subs, *pBaseParams, Type(), Type() );
455
456 if( isCallOn )
457 {
458 // コード生成を伴う場合はエラーチェックを行う
459
460 if( baseType.IsDelegate() )
461 {
462 // デリゲート
463 // 共変戻り値、反変引数をサポート
464 if( !(
465 pBaseParams->Equals( pUserProc->Params(), true )
466 && ( pBaseReturnType->Equals( pUserProc->ReturnType() ) || pBaseReturnType->IsCovariant( pUserProc->ReturnType() ) )
467 ) )
468 {
469 compiler.errorMessenger.Output(67, name, cp );
470 }
471 }
472 else
473 {
474 // 関数ポインタ
475 if( !(
476 pBaseParams->Equals( pUserProc->Params() )
477 && pBaseReturnType->Equals( pUserProc->ReturnType() )
478 ) )
479 {
480 compiler.errorMessenger.Output(66, name, cp );
481 }
482 }
483 }
484
485 if(!pUserProc){
486 compiler.errorMessenger.Output(27,name,cp);
487 return;
488 }
489 }
490 else{
491 pUserProc=GetSubHash(name);
492 if(!pUserProc){
493 compiler.errorMessenger.Output(27,name,cp);
494 return;
495 }
496 }
497
498 if( baseType.IsDelegate() )
499 {
500 if( isCallOn )
501 {
502 // デリゲートのとき
503 Opcode_CreateDelegate( baseType.GetClass(), name, *pUserProc );
504 }
505 resultType = baseType;
506 }
507 else
508 {
509 if( isCallOn )
510 {
511 // 関数ポインタのとき
512 _Opcode_Func_AddressOf( name, *pUserProc );
513 }
514 resultType.SetBasicType( DEF_PTR_VOID );
515 }
516}
517void Opcode_Func_SizeOf( const std::string &typeName )
518{
519 Type tempType;
520 if( !compiler.StringToType( typeName, tempType ) ){
521 compiler.errorMessenger.Output(3,typeName,cp);
522 return;
523 }
524
525 //mov eax,size
526 compiler.codeGenerator.op_mov_RV( REG_EAX, compiler.SizeOf( tempType ) );
527}
528void Opcode_Func_ClassSizeOf( const std::string &typeName )
529{
530 Type tempType;
531 if( !compiler.StringToType( typeName, tempType ) ){
532 compiler.errorMessenger.Output(3,typeName,cp);
533 return;
534 }
535
536 if( !tempType.IsObject() )
537 {
538 compiler.errorMessenger.Output(1,typeName,cp);
539 return;
540 }
541
542 //mov eax,size
543 compiler.codeGenerator.op_mov_RV( REG_EAX, tempType.GetClass().GetSize() );
544}
545void Opcode_Func_VarPtr( const char *Parameter, Type &resultType, bool isCallOn )
546{
547 if( isCallOn == false )
548 {
549 // 戻り値の型を取得するだけ
550
551 //変数のアドレスを取得
552 if(!GetVarType( Parameter, resultType, true )) return;
553
554 resultType.PtrLevelUp();
555
556 return;
557 }
558
559 if( lstrcmpi( Parameter, "This" )==0 )
560 {
561 compiler.errorMessenger.Output( 144, "", cp );
562 }
563
564 RELATIVE_VAR RelativeVar;
565
566 //変数のアドレスを取得
567 if(!GetVarOffsetReadOnly( Parameter, &RelativeVar, resultType )) return;
568
569 int beforeType = resultType.GetBasicType();
570
571 resultType.PtrLevelUp();
572
573 SetVarPtrToEax(&RelativeVar);
574}
575void Opcode_Func_ObjPtr( const char *Parameter, Type &resultType, bool isCallOn ){
576 if( isCallOn == false ){
577 // 戻り値の型を取得するだけ
578
579 //変数のアドレスを取得
580 if(!GetVarType( Parameter, resultType, true )) return;
581
582 resultType.PtrLevelUp();
583
584 return;
585 }
586
587 RELATIVE_VAR RelativeVar;
588
589 //変数のアドレスを取得
590 if(!GetVarOffsetReadOnly( Parameter, &RelativeVar, resultType )) return;
591
592 int beforeType = resultType.GetBasicType();
593
594 resultType.PtrLevelUp();
595
596 SetVarPtrToEax(&RelativeVar);
597
598 if( lstrcmpi( Parameter, "This" )==0 ){
599 // Thisの場合は特別にオブジェクトポインタが返ってくるので、何もせずに抜ける
600 }
601 else if( beforeType == DEF_OBJECT ){
602 //参照をオブジェクトポインタに変更
603
604 //mov eax,dword ptr[eax]
605 compiler.codeGenerator.op_mov_RM( sizeof(long), REG_EAX, REG_EAX, 0, MOD_BASE );
606 }
607 else{
608 compiler.errorMessenger.Output(134,NULL,cp );
609 }
610}
611
612void Opcode_Func_delegate_call( const char *paramsStr, Type &resultType, bool isDynamicCall, bool isCallOn )
613{
614 if( isCallOn )
615 {
616 int i = 0;
617 char methodPtrParamStr[VN_SIZE];
618 i = GetOneParameter( paramsStr, i, methodPtrParamStr );
619
620 char objPtrValueStr[VN_SIZE]="";
621 if( isDynamicCall )
622 {
623 i = GetOneParameter( paramsStr, i, objPtrValueStr );
624 }
625
626 Opcode_CallDelegate( compiler.GetObjectModule().meta.ToDelegate( compiler.GetCompilingClass() ), methodPtrParamStr, objPtrValueStr, paramsStr + i );
627 }
628
629 resultType = compiler.GetCompilingUserProc().ReturnType();
630}
631void Opcode_Func_System_Get_Bp()
632{
633 //mov eax,ebp
634 compiler.codeGenerator.op_mov_RR(REG_EAX,REG_EBP);
635}
636void Opcode_Func_System_Get_Sp()
637{
638 //mov eax,esp
639 compiler.codeGenerator.op_mov_RR(REG_EAX,REG_ESP);
640}
641
642void Opcode_Func_System_GetComVtbl( const char *parameter )
643{
644 Type classType;
645 compiler.StringToType( parameter, classType );
646
647 // mov eax,com_vtbl
648 compiler.codeGenerator.op_mov_RV_com_vtbl( REG_EAX, &classType.GetClass() );
649}
650void Opcode_Func_System_GetVtblList( const char *parameter )
651{
652 Type classType;
653 compiler.StringToType( parameter, classType );
654
655 // mov eax,com_vtbl
656 compiler.codeGenerator.op_mov_RV_vtbl( REG_EAX, &classType.GetClass() );
657}
658void Opcode_Func_System_GetDefaultConstructor( const char *parameter )
659{
660 Type classType;
661 compiler.StringToType( parameter, classType );
662
663 if( classType.GetClass().GetConstructorMethod() )
664 {
665 //mov eax,ProcAddr
666 compiler.codeGenerator.op_addressof( REG_EAX, &classType.GetClass().GetConstructorMethod()->GetUserProc() );
667 }
668 else
669 {
670 // デフォルトコンストラクタを持たない
671
672 //xor eax,eax
673 compiler.codeGenerator.op_zero_reg( REG_EAX );
674 }
675}
676void Opcode_Func_System_GetDestructor( const char *parameter )
677{
678 Type classType;
679 compiler.StringToType( parameter, classType );
680
681 //mov eax,ProcAddr
682 compiler.codeGenerator.op_addressof( REG_EAX, &classType.GetClass().GetDestructorMethod()->GetUserProc() );
683}
684
685void Opcode_Func_GetPtrData(const char *Parameter,const int type){
686 Type tempType;
687 if( !NumOpe(Parameter,Type(),tempType) ){
688 return;
689 }
690 if(!tempType.IsWhole()){
691 compiler.errorMessenger.Output(11,Parameter,cp);
692 return;
693 }
694 ChangeTypeToLong(tempType.GetBasicType());
695
696 if(type==DEF_DOUBLE){
697 //pop eax
698 compiler.codeGenerator.op_pop(REG_EAX);
699
700 //fld qword ptr[eax]
701 compiler.codeGenerator.PutOld(
702 (char)0xDD,
703 (char)0x00
704 );
705 }
706 else if(type==DEF_SINGLE||type==DEF_DWORD){
707 //pop eax
708 compiler.codeGenerator.op_pop(REG_EAX);
709
710 //mov eax,dword ptr[eax]
711 compiler.codeGenerator.op_mov_RM( sizeof(long), REG_EAX, REG_EAX, 0, MOD_BASE );
712 }
713 else if(type==DEF_QWORD){
714 //pop ecx
715 compiler.codeGenerator.op_pop(REG_ECX);
716
717 //mov eax,dword ptr[ecx]
718 compiler.codeGenerator.op_mov_RM(sizeof(long),REG_EAX,REG_ECX,0,MOD_BASE);
719
720 //mov edx,dword ptr[ecx+sizeof(long)]
721 compiler.codeGenerator.op_mov_RM(sizeof(long),REG_EDX,REG_ECX,sizeof(long),MOD_BASE_DISP8);
722 }
723 else if(type==DEF_WORD){
724 //pop ebx
725 compiler.codeGenerator.op_pop(REG_EBX);
726
727 //xor eax,eax
728 compiler.codeGenerator.op_xor_RR(REG_EAX);
729
730 //mov ax,word ptr[ebx]
731 compiler.codeGenerator.op_mov_RM( sizeof(short), REG_EAX, REG_EBX, 0, MOD_BASE );
732 }
733 else if(type==DEF_BYTE){
734 //pop ebx
735 compiler.codeGenerator.op_pop(REG_EBX);
736
737 //xor eax,eax
738 compiler.codeGenerator.op_xor_RR(REG_EAX);
739
740 //mov al,byte ptr[ebx]
741 compiler.codeGenerator.op_mov_RM( sizeof(char), REG_EAX, REG_EBX, 0, MOD_BASE );
742 }
743}
744
745bool Opcode_CallFunc( const char *Parameter, const int FuncNum, const Type &baseType, Type &resultType, bool isCallOn )
746{
747 switch(FuncNum){
748 case FUNC_FIX:
749 if( isCallOn ) Opcode_Func_Fix(Parameter);
750 resultType.SetBasicType( DEF_LONG );
751 break;
752 case FUNC_CUDBL:
753 if( isCallOn ) Opcode_Func_CUDbl(Parameter);
754 resultType.SetBasicType( DEF_DOUBLE );
755 break;
756 case FUNC_LEN:
757 if( isCallOn ) Opcode_Func_Len(Parameter);
758 resultType.SetBasicType( DEF_LONG );
759 break;
760 case FUNC_ADDRESSOF:
761 Opcode_Func_AddressOf( Parameter, baseType, isCallOn, resultType );
762 break;
763 case FUNC_SIZEOF:
764 if( isCallOn ) Opcode_Func_SizeOf(Parameter);
765 resultType.SetBasicType( DEF_LONG );
766 break;
767 case FUNC_CLASS_SIZEOF:
768 if( isCallOn ) Opcode_Func_ClassSizeOf(Parameter);
769 resultType.SetBasicType( DEF_LONG );
770 break;
771 case FUNC_VARPTR:
772 Opcode_Func_VarPtr( Parameter, resultType, isCallOn );
773 break;
774 case FUNC_OBJPTR:
775 Opcode_Func_ObjPtr( Parameter, resultType, isCallOn );
776 break;
777 case FUNC_DELEGATE_DYNAMICMETHOD_CALL:
778 Opcode_Func_delegate_call( Parameter, resultType, true, isCallOn );
779 break;
780 case FUNC_DELEGATE_STATICMETHOD_CALL:
781 Opcode_Func_delegate_call( Parameter, resultType, false, isCallOn );
782 break;
783 case FUNC_SYSTEM_GET_NOW_SCOPE_CATCH_ADDRESS:
784 if( isCallOn ) Exception::Opcode_Func_System_GetNowScopeCatchAddress();
785 resultType.SetBasicType( DEF_PTR_VOID );
786 break;
787 case FUNC_SYSTEM_GET_NOW_SCOPE_FINALLY_ADDRESS:
788 if( isCallOn ) Exception::Opcode_Func_System_GetNowScopeFinallyAddress();
789 resultType.SetBasicType( DEF_PTR_VOID );
790 break;
791 case FUNC_SYSTEM_GET_BP:
792 if( isCallOn ) Opcode_Func_System_Get_Bp();
793 resultType.SetBasicType( DEF_LONG );
794 break;
795 case FUNC_SYSTEM_GET_SP:
796 if( isCallOn ) Opcode_Func_System_Get_Sp();
797 resultType.SetBasicType( DEF_LONG );
798 break;
799 case FUNC_SYSTEM_GET_COM_VTBL:
800 if( isCallOn ) Opcode_Func_System_GetComVtbl( Parameter );
801 resultType.SetBasicType( DEF_PTR_VOID );
802 break;
803 case FUNC_SYSTEM_GET_VTBL_LIST:
804 if( isCallOn ) Opcode_Func_System_GetVtblList( Parameter );
805 resultType.SetBasicType( DEF_PTR_VOID );
806 break;
807 case FUNC_SYSTEM_GET_DEFAULT_CONSTRUCTOR:
808 if( isCallOn ) Opcode_Func_System_GetDefaultConstructor( Parameter );
809 resultType.SetBasicType( DEF_PTR_VOID );
810 break;
811 case FUNC_SYSTEM_GET_DESTRUCTOR:
812 if( isCallOn ) Opcode_Func_System_GetDestructor( Parameter );
813 resultType.SetBasicType( DEF_PTR_VOID );
814 break;
815
816 case FUNC_GETDOUBLE:
817 if( isCallOn ) Opcode_Func_GetPtrData(Parameter,DEF_DOUBLE);
818 resultType.SetBasicType( DEF_DOUBLE );
819 break;
820 case FUNC_GETSINGLE:
821 if( isCallOn ) Opcode_Func_GetPtrData(Parameter,DEF_SINGLE);
822 resultType.SetBasicType( DEF_SINGLE );
823 break;
824 case FUNC_GETQWORD:
825 if( isCallOn ) Opcode_Func_GetPtrData(Parameter,DEF_QWORD);
826 resultType.SetBasicType( DEF_QWORD );
827 break;
828 case FUNC_GETDWORD:
829 if( isCallOn ) Opcode_Func_GetPtrData(Parameter,DEF_DWORD);
830 resultType.SetBasicType( DEF_DWORD );
831 break;
832 case FUNC_GETWORD:
833 if( isCallOn ) Opcode_Func_GetPtrData(Parameter,DEF_WORD);
834 resultType.SetBasicType( DEF_WORD );
835 break;
836 case FUNC_GETBYTE:
837 if( isCallOn ) Opcode_Func_GetPtrData(Parameter,DEF_BYTE);
838 resultType.SetBasicType( DEF_BYTE );
839 break;
840 default:
841 return false;
842 }
843 return true;
844}
Note: See TracBrowser for help on using the repository browser.