source: dev/trunk/ab5.0/abdev/compiler_x86/Compile_Func.cpp@ 689

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

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

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