| [206] | 1 | #include "stdafx.h"
 | 
|---|
 | 2 | 
 | 
|---|
| [183] | 3 | #include <jenga/include/smoothie/Smoothie.h>
 | 
|---|
 | 4 | 
 | 
|---|
| [193] | 5 | #include <Compiler.h>
 | 
|---|
 | 6 | 
 | 
|---|
| [3] | 7 | #include "../BasicCompiler_Common/common.h"
 | 
|---|
 | 8 | #include "Opcode.h"
 | 
|---|
 | 9 | 
 | 
|---|
 | 10 | void Call_DebugSys_SaveContext(){
 | 
|---|
 | 11 |     //call _System_GetEip
 | 
|---|
| [206] | 12 |     extern const UserProc *pSub_System_GetEip;
 | 
|---|
| [225] | 13 |     compiler.codeGenerator.op_call(pSub_System_GetEip);
 | 
|---|
| [3] | 14 | 
 | 
|---|
 | 15 |     //push eax
 | 
|---|
| [225] | 16 |     compiler.codeGenerator.op_push(REG_EAX);
 | 
|---|
| [3] | 17 | 
 | 
|---|
 | 18 |     //push ebp
 | 
|---|
| [225] | 19 |     compiler.codeGenerator.op_push(REG_EBP);
 | 
|---|
| [3] | 20 | 
 | 
|---|
 | 21 |     //call _DebugSys_SaveContext
 | 
|---|
| [206] | 22 |     extern const UserProc *pSub_DebugSys_SaveContext;
 | 
|---|
| [225] | 23 |     compiler.codeGenerator.op_call(pSub_DebugSys_SaveContext);
 | 
|---|
| [3] | 24 | }
 | 
|---|
 | 25 | 
 | 
|---|
| [76] | 26 | bool Opcode_CallProcPtr( const char *variable, const char *lpszParms,ProcPointer *pProcPointer){
 | 
|---|
| [3] | 27 | 
 | 
|---|
 | 28 |     extern BOOL bDebugCompile;
 | 
|---|
 | 29 |     extern BOOL bDebugSupportProc;
 | 
|---|
 | 30 |     if(bDebugCompile&&bDebugSupportProc==0)
 | 
|---|
 | 31 |         Call_DebugSys_SaveContext();
 | 
|---|
 | 32 | 
 | 
|---|
 | 33 | 
 | 
|---|
 | 34 |     ////////////////////////
 | 
|---|
 | 35 |     // パラメータのセット
 | 
|---|
 | 36 |     ////////////////////////
 | 
|---|
 | 37 | 
 | 
|---|
 | 38 |     //パラメータオブジェクトを生成
 | 
|---|
| [71] | 39 |     ParamImpl *pobj_parameter=0;
 | 
|---|
| [76] | 40 |     pobj_parameter=new ParamImpl(lpszParms);
 | 
|---|
| [3] | 41 | 
 | 
|---|
| [77] | 42 |     // デフォルト引数を適用
 | 
|---|
 | 43 |     pobj_parameter->ApplyDefaultParameters( pProcPointer->Params() );
 | 
|---|
 | 44 | 
 | 
|---|
| [3] | 45 |     //エラーチェック
 | 
|---|
| [75] | 46 |     if( !pobj_parameter->ErrorCheck(variable,pProcPointer->Params() ) ){
 | 
|---|
| [31] | 47 |         //パラメータにエラーがあるときは処理を終える
 | 
|---|
| [76] | 48 |         return false;
 | 
|---|
| [31] | 49 |     }
 | 
|---|
| [3] | 50 | 
 | 
|---|
| [20] | 51 |     //一時オブジェクトを生成
 | 
|---|
| [75] | 52 |     pobj_parameter->NewTempParameters( variable,pProcPointer->Params() );
 | 
|---|
| [20] | 53 | 
 | 
|---|
| [3] | 54 |     //レジスタ、スタックフレームにセット
 | 
|---|
| [75] | 55 |     pobj_parameter->SetParameter(variable,pProcPointer->Params() );
 | 
|---|
| [3] | 56 | 
 | 
|---|
 | 57 | 
 | 
|---|
 | 58 | 
 | 
|---|
| [20] | 59 |     ////////////////////////
 | 
|---|
 | 60 |     // call
 | 
|---|
 | 61 |     ////////////////////////
 | 
|---|
| [3] | 62 |     RELATIVE_VAR RelativeVar;
 | 
|---|
| [76] | 63 |     GetVarOffsetReadOnly(variable,&RelativeVar,Type());
 | 
|---|
| [3] | 64 |     SetVarPtrToEax(&RelativeVar);
 | 
|---|
 | 65 | 
 | 
|---|
 | 66 |     //mov eax,dword ptr[eax]
 | 
|---|
| [235] | 67 |     compiler.codeGenerator.op_mov_RM( sizeof(long), REG_EAX, REG_EAX, 0, MOD_BASE );
 | 
|---|
| [3] | 68 | 
 | 
|---|
 | 69 |     //call eax
 | 
|---|
| [235] | 70 |     compiler.codeGenerator.op_call_R( REG_EAX );
 | 
|---|
| [3] | 71 | 
 | 
|---|
| [20] | 72 | 
 | 
|---|
 | 73 | 
 | 
|---|
 | 74 |     //一時オブジェクトを破棄
 | 
|---|
 | 75 |     pobj_parameter->DeleteTempParameters();
 | 
|---|
 | 76 | 
 | 
|---|
 | 77 |     //パラメータオブジェクトを破棄
 | 
|---|
 | 78 |     delete pobj_parameter;
 | 
|---|
 | 79 | 
 | 
|---|
| [76] | 80 |     return true;
 | 
|---|
| [3] | 81 | }
 | 
|---|
 | 82 | 
 | 
|---|
| [342] | 83 | bool Opcode_CallProc(const char *Parameter,const UserProc *pUserProc,DWORD dwFlags,const char *ObjectName )
 | 
|---|
 | 84 | {
 | 
|---|
| [75] | 85 |     if( pUserProc->IsMacro() ){
 | 
|---|
 | 86 |         if( lstrcmpi( pUserProc->GetName().c_str(), "Print" ) == 0 ){
 | 
|---|
| [3] | 87 |             Opcode_Print(Parameter,0);
 | 
|---|
| [76] | 88 |             return true;
 | 
|---|
| [3] | 89 |         }
 | 
|---|
| [75] | 90 |         if( lstrcmpi( pUserProc->GetName().c_str(), "Input" ) == 0 ){
 | 
|---|
| [3] | 91 |             Opcode_Input(Parameter);
 | 
|---|
| [76] | 92 |             return true;
 | 
|---|
| [3] | 93 |         }
 | 
|---|
| [75] | 94 |         if( lstrcmpi( pUserProc->GetName().c_str(), "Write" ) == 0 ){
 | 
|---|
| [3] | 95 |             Opcode_Print(Parameter,1);
 | 
|---|
| [76] | 96 |             return true;
 | 
|---|
| [3] | 97 |         }
 | 
|---|
 | 98 |     }
 | 
|---|
 | 99 | 
 | 
|---|
| [75] | 100 |     pUserProc->Using();
 | 
|---|
| [3] | 101 | 
 | 
|---|
| [47] | 102 |     bool isStatic = false;
 | 
|---|
| [76] | 103 |     const CClass *pobj_c = NULL;
 | 
|---|
| [135] | 104 |     const CMethod *pMethod = NULL;
 | 
|---|
| [292] | 105 |     Type leftType;
 | 
|---|
| [304] | 106 |     bool isFixedClass = false;
 | 
|---|
| [75] | 107 |     if( pUserProc->GetParentClassPtr() ){
 | 
|---|
| [3] | 108 |         //クラスのメンバ関数を呼び出す場合はアクセスチェックを行う
 | 
|---|
| [304] | 109 |         if(ObjectName[0] && (dwFlags&PROCFLAG_NEW)==0)
 | 
|---|
 | 110 |         {
 | 
|---|
 | 111 |             if(lstrcmpi(ObjectName,"Super")==0)
 | 
|---|
 | 112 |             {
 | 
|---|
| [27] | 113 |                 //クラスメンバ関数内から基底クラスの呼び出し
 | 
|---|
| [304] | 114 |                 pobj_c=&compiler.pCompilingClass->GetSuperClass();
 | 
|---|
 | 115 | 
 | 
|---|
 | 116 |                 isFixedClass = true;
 | 
|---|
| [3] | 117 |             }
 | 
|---|
| [304] | 118 |             else
 | 
|---|
 | 119 |             {
 | 
|---|
| [47] | 120 |                 //"->"によってオブジェクトを指定する通常のメンバ関数呼び出し
 | 
|---|
| [76] | 121 |                 Type varType;
 | 
|---|
 | 122 |                 GetVarType( ObjectName, varType, false );
 | 
|---|
| [290] | 123 |                 if( NATURAL_TYPE( varType.GetBasicType() ) == DEF_OBJECT )
 | 
|---|
 | 124 |                 {
 | 
|---|
 | 125 |                     pobj_c = &varType.GetClass();
 | 
|---|
| [292] | 126 |                     leftType = varType;
 | 
|---|
| [290] | 127 |                 }
 | 
|---|
 | 128 |                 else
 | 
|---|
 | 129 |                 {
 | 
|---|
| [265] | 130 |                     pobj_c=compiler.GetObjectModule().meta.GetClasses().Find(ObjectName);
 | 
|---|
| [47] | 131 |                     if( pobj_c ){
 | 
|---|
 | 132 |                         isStatic = true;
 | 
|---|
 | 133 |                     }
 | 
|---|
 | 134 |                     else{
 | 
|---|
 | 135 |                         SetError(300,NULL,cp);
 | 
|---|
 | 136 |                     }
 | 
|---|
| [3] | 137 |                 }
 | 
|---|
 | 138 |             }
 | 
|---|
 | 139 |         }
 | 
|---|
 | 140 |         else{
 | 
|---|
 | 141 |             if(dwFlags&PROCFLAG_NEW){
 | 
|---|
| [294] | 142 |                 GetVarType( ObjectName, leftType, false );
 | 
|---|
 | 143 | 
 | 
|---|
| [3] | 144 |                 //New演算子によるコンストラクタ呼び出し
 | 
|---|
| [75] | 145 |                 pobj_c=pUserProc->GetParentClassPtr();
 | 
|---|
| [3] | 146 |             }
 | 
|---|
 | 147 |             else{
 | 
|---|
 | 148 |                 //クラスメンバ関数内から同一クラスのメンバ関数の呼び出し
 | 
|---|
| [206] | 149 |                 pobj_c=compiler.pCompilingClass;
 | 
|---|
| [3] | 150 |             }
 | 
|---|
 | 151 |         }
 | 
|---|
 | 152 | 
 | 
|---|
 | 153 | 
 | 
|---|
| [18] | 154 |         /////////////////////////////////
 | 
|---|
 | 155 |         // メソッド情報を取得
 | 
|---|
 | 156 |         /////////////////////////////////
 | 
|---|
| [27] | 157 |         pMethod = NULL;
 | 
|---|
| [350] | 158 |         if( ! isStatic ) pMethod = pobj_c->GetDynamicMethodOrInterfaceMethod( pUserProc );
 | 
|---|
| [27] | 159 |         if( ! pMethod ){
 | 
|---|
| [18] | 160 |             //動的メソッドが取得できなかったときは静的メソッドを当たる
 | 
|---|
| [135] | 161 |             pMethod = pobj_c->GetStaticMethods().GetMethodPtr( pUserProc );
 | 
|---|
| [18] | 162 |             if( !pMethod ){
 | 
|---|
 | 163 |                 SetError(300,NULL,cp);
 | 
|---|
| [76] | 164 |                 return false;
 | 
|---|
| [3] | 165 |             }
 | 
|---|
| [26] | 166 | 
 | 
|---|
 | 167 |             //静的メンバ
 | 
|---|
| [47] | 168 |             isStatic = true;
 | 
|---|
| [3] | 169 |         }
 | 
|---|
 | 170 | 
 | 
|---|
 | 171 | 
 | 
|---|
 | 172 |         //////////////////////////////
 | 
|---|
 | 173 |         // アクセスエラーチェック
 | 
|---|
 | 174 |         //////////////////////////////
 | 
|---|
 | 175 | 
 | 
|---|
 | 176 |         if(ObjectName[0]){
 | 
|---|
 | 177 |             //外部からの呼び出し
 | 
|---|
| [206] | 178 |             if(pobj_c==compiler.pCompilingClass){
 | 
|---|
| [3] | 179 |                 //同一クラスオブジェクトの場合はプライベートアクセスを容認する
 | 
|---|
| [137] | 180 |                 if( pMethod->IsNoneAccess() ){
 | 
|---|
| [75] | 181 |                     SetError(109,pUserProc->GetName(),cp);
 | 
|---|
| [76] | 182 |                     return false;
 | 
|---|
| [3] | 183 |                 }
 | 
|---|
 | 184 |             }
 | 
|---|
 | 185 |             else{
 | 
|---|
| [137] | 186 |                 if( pMethod->IsPrivate()
 | 
|---|
 | 187 |                     || pMethod->IsNoneAccess() ){
 | 
|---|
| [75] | 188 |                     SetError(109,pUserProc->GetName(),cp);
 | 
|---|
| [76] | 189 |                     return false;
 | 
|---|
| [3] | 190 |                 }
 | 
|---|
| [306] | 191 |                 if( !pMethod->GetUserProc().GetParentClass().IsEqualsOrSubClass( pobj_c ) && pMethod->IsProtected() ){
 | 
|---|
| [75] | 192 |                     SetError(110,pUserProc->GetName(),cp);
 | 
|---|
| [76] | 193 |                     return false;
 | 
|---|
| [3] | 194 |                 }
 | 
|---|
 | 195 |             }
 | 
|---|
 | 196 |         }
 | 
|---|
 | 197 |         else{
 | 
|---|
 | 198 |             //クラス内部からの呼び出し(継承によるACCESS_NONのみをエラーとする)
 | 
|---|
| [137] | 199 |             if( pMethod->IsNoneAccess() ){
 | 
|---|
| [75] | 200 |                 SetError(109,pUserProc->GetName(),cp);
 | 
|---|
| [76] | 201 |                 return false;
 | 
|---|
| [3] | 202 |             }
 | 
|---|
 | 203 |         }
 | 
|---|
 | 204 |     }
 | 
|---|
 | 205 | 
 | 
|---|
 | 206 | 
 | 
|---|
 | 207 |     ///////////////////////////////////////////////////////////////
 | 
|---|
| [64] | 208 |     // _System_LocalThisのダミーをセット
 | 
|---|
| [3] | 209 |     ///////////////////////////////////////////////////////////////
 | 
|---|
 | 210 | 
 | 
|---|
 | 211 |     char temporary[VN_SIZE]={0};
 | 
|---|
| [75] | 212 |     if( pUserProc->GetParentClassPtr() && isStatic == false ){
 | 
|---|
| [3] | 213 |         //_System_LocalThis(第一パラメータ)のダミーを作成
 | 
|---|
 | 214 |         lstrcpy(temporary,"0,");
 | 
|---|
 | 215 |     }
 | 
|---|
| [320] | 216 |     if( pUserProc->ReturnType().IsStruct() ){
 | 
|---|
 | 217 |         // ※ByRef _System_ReturnValue パラメータのダミーをセット
 | 
|---|
 | 218 |         lstrcat(temporary,"0,");
 | 
|---|
 | 219 |     }
 | 
|---|
| [3] | 220 | 
 | 
|---|
 | 221 |     if(Parameter[0]=='\0'&&temporary[0])
 | 
|---|
 | 222 |         temporary[lstrlen(temporary)-1]=0;
 | 
|---|
 | 223 |     else lstrcat(temporary,Parameter);
 | 
|---|
 | 224 | 
 | 
|---|
 | 225 | 
 | 
|---|
 | 226 |     ////////////////////////
 | 
|---|
 | 227 |     // パラメータをセット
 | 
|---|
 | 228 |     ////////////////////////
 | 
|---|
 | 229 | 
 | 
|---|
 | 230 |     //パラメータオブジェクトを生成
 | 
|---|
| [71] | 231 |     ParamImpl *pobj_parameter=0;
 | 
|---|
 | 232 |     pobj_parameter=new ParamImpl(temporary);
 | 
|---|
| [3] | 233 | 
 | 
|---|
| [77] | 234 |     // デフォルト引数を適用
 | 
|---|
 | 235 |     pobj_parameter->ApplyDefaultParameters( pUserProc->RealParams() );
 | 
|---|
 | 236 | 
 | 
|---|
| [292] | 237 |     // 型パラメータを適用
 | 
|---|
 | 238 |     pobj_parameter->SetLeftType( leftType );
 | 
|---|
 | 239 | 
 | 
|---|
| [3] | 240 |     //エラーチェック
 | 
|---|
| [75] | 241 |     if( !pobj_parameter->ErrorCheck(pUserProc->GetName(),pUserProc->RealParams(),pUserProc->GetSecondParmNum() ) ){
 | 
|---|
| [31] | 242 |         //パラメータにエラーがあるときは処理を終える
 | 
|---|
| [76] | 243 |         return false;
 | 
|---|
| [31] | 244 |     }
 | 
|---|
| [3] | 245 | 
 | 
|---|
| [75] | 246 |     if(pUserProc->IsMacro()){
 | 
|---|
| [3] | 247 |         //マクロ関数の場合は、パラメータ省略を考慮する
 | 
|---|
| [75] | 248 |         pobj_parameter->MacroParameterSupport( pUserProc->RealParams() );
 | 
|---|
| [3] | 249 |     }
 | 
|---|
 | 250 | 
 | 
|---|
| [20] | 251 |     //一時オブジェクトを生成
 | 
|---|
| [75] | 252 |     int tempSize = pobj_parameter->NewTempParameters( pUserProc->GetName(),pUserProc->RealParams(),pUserProc->GetRealSecondParmNum() );
 | 
|---|
| [20] | 253 | 
 | 
|---|
| [3] | 254 |     //レジスタ、スタックフレームにセット
 | 
|---|
| [301] | 255 |     int ParmSize = pobj_parameter->SetParameter(pUserProc->GetName(),pUserProc->RealParams(),pUserProc->GetRealSecondParmNum(), pUserProc );
 | 
|---|
| [3] | 256 | 
 | 
|---|
| [75] | 257 |     if(pUserProc->ReturnType().IsStruct() ){
 | 
|---|
| [3] | 258 |         //////////////////////////////////////////////////////
 | 
|---|
| [64] | 259 |         // 戻り値に構造体インスタンスを持つ場合
 | 
|---|
 | 260 |         // ※ByRef _System_ReturnValue パラメータをセット
 | 
|---|
| [3] | 261 |         //////////////////////////////////////////////////////
 | 
|---|
 | 262 | 
 | 
|---|
| [75] | 263 |         int object_size = pUserProc->ReturnType().GetClass().GetSize();
 | 
|---|
| [3] | 264 | 
 | 
|---|
 | 265 |         //push object_size
 | 
|---|
| [225] | 266 |         compiler.codeGenerator.op_push_V(object_size);
 | 
|---|
| [3] | 267 | 
 | 
|---|
 | 268 |         //call calloc
 | 
|---|
| [206] | 269 |         extern const UserProc *pSub_calloc;
 | 
|---|
| [225] | 270 |         compiler.codeGenerator.op_call(pSub_calloc);
 | 
|---|
| [3] | 271 | 
 | 
|---|
 | 272 |         //push eax
 | 
|---|
| [225] | 273 |         compiler.codeGenerator.op_push(REG_EAX);
 | 
|---|
| [307] | 274 | 
 | 
|---|
 | 275 |         ParmSize += PTR_SIZE;
 | 
|---|
| [3] | 276 |     }
 | 
|---|
 | 277 | 
 | 
|---|
 | 278 | 
 | 
|---|
| [75] | 279 |     if( pUserProc->GetParentClassPtr() && isStatic == false ){
 | 
|---|
| [3] | 280 |         //////////////////////////////////////////////////////
 | 
|---|
 | 281 |         // メンバ関数の場合
 | 
|---|
| [350] | 282 |         // ※_System_LocalThis パラメータをecxにセット
 | 
|---|
| [3] | 283 |         //////////////////////////////////////////////////////
 | 
|---|
 | 284 | 
 | 
|---|
| [97] | 285 |         if(ObjectName[0] && (dwFlags&PROCFLAG_NEW)==0){
 | 
|---|
| [3] | 286 |             if(lstrcmpi(ObjectName,"Super")==0) goto InClassMember;
 | 
|---|
| [18] | 287 |             else{
 | 
|---|
 | 288 |                 RELATIVE_VAR RelativeVar;
 | 
|---|
| [135] | 289 |                 if( pMethod->IsConst() ){
 | 
|---|
| [18] | 290 |                     //Constアクセスが可能なメソッドの場合
 | 
|---|
| [76] | 291 |                     if( !GetVarOffsetReadOnly( ObjectName, &RelativeVar, Type() ) ){
 | 
|---|
 | 292 |                         return false;
 | 
|---|
 | 293 |                     }
 | 
|---|
| [18] | 294 |                 }
 | 
|---|
 | 295 |                 else{
 | 
|---|
 | 296 |                     //Constアクセスが不可能なメソッドの場合
 | 
|---|
| [76] | 297 |                     if( !GetVarOffsetReadWrite( ObjectName, &RelativeVar, Type() ) ){
 | 
|---|
 | 298 |                         return false;
 | 
|---|
 | 299 |                     }
 | 
|---|
| [18] | 300 |                 }
 | 
|---|
| [3] | 301 | 
 | 
|---|
| [18] | 302 |                 SetVarPtrToEax(&RelativeVar);
 | 
|---|
| [3] | 303 | 
 | 
|---|
| [64] | 304 |                 // 参照を実体ポインタにする
 | 
|---|
| [225] | 305 |                 compiler.codeGenerator.op_mov_RM( sizeof(long), REG_ECX, REG_EAX, 0, MOD_BASE );
 | 
|---|
| [3] | 306 |             }
 | 
|---|
 | 307 |         }
 | 
|---|
 | 308 |         else{
 | 
|---|
 | 309 | InClassMember:
 | 
|---|
 | 310 |             if(dwFlags&PROCFLAG_NEW){
 | 
|---|
 | 311 |                 //New演算子によるコンストラクタ呼び出しの場合
 | 
|---|
| [64] | 312 | 
 | 
|---|
| [3] | 313 |                 //mov ecx,dword ptr[esp+ParmSize]
 | 
|---|
| [225] | 314 |                 compiler.codeGenerator.op_mov_RM( sizeof(long), REG_ECX, REG_ESP, ParmSize + tempSize, MOD_BASE_DISP32 );
 | 
|---|
| [3] | 315 |             }
 | 
|---|
 | 316 |             else{
 | 
|---|
 | 317 |                 //Thisポインタをecxにコピー
 | 
|---|
 | 318 |                 SetThisPtrToReg(REG_ECX);
 | 
|---|
 | 319 |             }
 | 
|---|
 | 320 |         }
 | 
|---|
 | 321 |     }
 | 
|---|
 | 322 | 
 | 
|---|
| [350] | 323 |     if( pUserProc->IsVirtual() && !isFixedClass )
 | 
|---|
 | 324 |     {
 | 
|---|
| [349] | 325 |         int vtblIndex;
 | 
|---|
 | 326 |         if( pobj_c->IsInterface() )
 | 
|---|
 | 327 |         {
 | 
|---|
| [370] | 328 |             // インターフェイス メソッド呼び出し
 | 
|---|
| [348] | 329 | 
 | 
|---|
| [349] | 330 |             int offset_vtbl = compiler.GetObjectModule().meta.GetClasses().GetInterfaceInfoClassPtr()->GetMemberOffset( "__vtbl" );
 | 
|---|
| [3] | 331 | 
 | 
|---|
| [349] | 332 | 
 | 
|---|
 | 333 |             // vtblのポインタを取得
 | 
|---|
 | 334 |             //mov edx,dword ptr[ecx+offset_vtbl]
 | 
|---|
 | 335 |             compiler.codeGenerator.op_mov_RM( sizeof(long), REG_EDX, REG_ECX, offset_vtbl, MOD_BASE_DISP8 );
 | 
|---|
 | 336 | 
 | 
|---|
 | 337 |             int offset_this = compiler.GetObjectModule().meta.GetClasses().GetInterfaceInfoClassPtr()->GetMemberOffset( "__this" );
 | 
|---|
 | 338 | 
 | 
|---|
 | 339 | 
 | 
|---|
 | 340 | 
 | 
|---|
 | 341 |             // インターフェイスの場合は更に__thisを取得する
 | 
|---|
| [350] | 342 |             //mov ecx,qword ptr[ecx+offset_this]
 | 
|---|
| [349] | 343 |             compiler.codeGenerator.op_mov_RM( sizeof(long), REG_ECX, REG_ECX, offset_this, MOD_BASE_DISP8 );
 | 
|---|
 | 344 | 
 | 
|---|
 | 345 |             int vtblMasterListIndex;
 | 
|---|
 | 346 |             pobj_c->GetVtblMasterListIndexAndVtblIndex( pUserProc, vtblMasterListIndex, vtblIndex );
 | 
|---|
 | 347 |             if( vtblMasterListIndex != 0 )
 | 
|---|
 | 348 |             {
 | 
|---|
 | 349 |                 SetError();
 | 
|---|
 | 350 |             }
 | 
|---|
 | 351 |         }
 | 
|---|
| [370] | 352 |         else if( pobj_c->IsComInterface() )
 | 
|---|
 | 353 |         {
 | 
|---|
 | 354 |             // COMインターフェイス メソッド呼び出し
 | 
|---|
 | 355 | 
 | 
|---|
 | 356 |             //仮想関数(オブジェクトメソッド)呼び出し
 | 
|---|
 | 357 |             // pObj -> vtbl1 -> func1
 | 
|---|
 | 358 |             //               -> func2
 | 
|---|
 | 359 |             //               -> func3
 | 
|---|
 | 360 | 
 | 
|---|
 | 361 |             int vtblMasterListIndex;
 | 
|---|
 | 362 |             pobj_c->GetVtblMasterListIndexAndVtblIndex( pUserProc, vtblMasterListIndex, vtblIndex );
 | 
|---|
 | 363 | 
 | 
|---|
 | 364 |             // vtblのポインタを取得
 | 
|---|
 | 365 |             //mov edx,dword ptr[ecx]
 | 
|---|
 | 366 |             compiler.codeGenerator.op_mov_RM( sizeof(long), REG_EDX, REG_ECX, 0, MOD_BASE );
 | 
|---|
 | 367 |         }
 | 
|---|
| [349] | 368 |         else
 | 
|---|
 | 369 |         {
 | 
|---|
 | 370 |             //仮想関数(オブジェクトメソッド)呼び出し
 | 
|---|
 | 371 |             // pObj -> vtbl_master_list -> vtbl1 -> func1
 | 
|---|
 | 372 |             //                                   -> func2
 | 
|---|
 | 373 |             //                                   -> func3
 | 
|---|
 | 374 |             //                          -> vtbl2 -> func1
 | 
|---|
 | 375 |             //                                   -> func2
 | 
|---|
 | 376 |             //                                   -> func3
 | 
|---|
 | 377 | 
 | 
|---|
 | 378 |             int vtblMasterListIndex;
 | 
|---|
 | 379 |             pobj_c->GetVtblMasterListIndexAndVtblIndex( pUserProc, vtblMasterListIndex, vtblIndex );
 | 
|---|
 | 380 | 
 | 
|---|
 | 381 |             // vtblマスターリストのポインタを取得
 | 
|---|
| [370] | 382 |             //mov edx,dword ptr[ecx+sizeof(com_vtbl)]
 | 
|---|
 | 383 |             compiler.codeGenerator.op_mov_RM( sizeof(long), REG_EDX, REG_ECX, PTR_SIZE, MOD_BASE_DISP8 );
 | 
|---|
| [349] | 384 |             
 | 
|---|
 | 385 |             // vtblのポインタを取得
 | 
|---|
 | 386 |             //mov edx,dword ptr[edx+vtblMasterListIndex]
 | 
|---|
| [350] | 387 |             compiler.codeGenerator.op_mov_RM( sizeof(long), REG_EDX, REG_EDX, vtblMasterListIndex*PTR_SIZE, MOD_BASE_DISP32 );
 | 
|---|
| [349] | 388 |         }
 | 
|---|
 | 389 | 
 | 
|---|
| [350] | 390 |         //push ecx
 | 
|---|
 | 391 |         compiler.codeGenerator.op_push(REG_ECX);    
 | 
|---|
 | 392 | 
 | 
|---|
| [3] | 393 |         //call dword ptr[edx+func_index]
 | 
|---|
| [342] | 394 |         if( vtblIndex * PTR_SIZE <= 0x7F )
 | 
|---|
 | 395 |         {
 | 
|---|
| [250] | 396 |             compiler.codeGenerator.PutOld(
 | 
|---|
 | 397 |                 (char)0xFF,
 | 
|---|
 | 398 |                 (char)0x52,
 | 
|---|
| [342] | 399 |                 (char)(vtblIndex*PTR_SIZE)
 | 
|---|
| [250] | 400 |             );
 | 
|---|
| [3] | 401 |         }
 | 
|---|
 | 402 |         else{
 | 
|---|
| [250] | 403 |             compiler.codeGenerator.PutOld(
 | 
|---|
 | 404 |                 (char)0xFF,
 | 
|---|
 | 405 |                 (char)0x92
 | 
|---|
 | 406 |             );
 | 
|---|
| [342] | 407 |             compiler.codeGenerator.PutOld( (long)(vtblIndex*PTR_SIZE), Schedule::None );
 | 
|---|
| [3] | 408 |         }
 | 
|---|
 | 409 |     }
 | 
|---|
 | 410 |     else{
 | 
|---|
 | 411 |         //通常呼び出し
 | 
|---|
 | 412 | 
 | 
|---|
| [350] | 413 |         if( pUserProc->GetParentClassPtr() && isStatic == false )
 | 
|---|
 | 414 |         {
 | 
|---|
 | 415 |             //push ecx
 | 
|---|
 | 416 |             compiler.codeGenerator.op_push(REG_ECX);
 | 
|---|
 | 417 |         }
 | 
|---|
 | 418 | 
 | 
|---|
| [3] | 419 |         //call ProcAddr
 | 
|---|
| [225] | 420 |         compiler.codeGenerator.op_call(pUserProc);
 | 
|---|
| [3] | 421 |     }
 | 
|---|
 | 422 | 
 | 
|---|
| [75] | 423 |     if(pUserProc->IsCdecl()){
 | 
|---|
| [3] | 424 |         //add esp,ParmSize
 | 
|---|
| [225] | 425 |         compiler.codeGenerator.op_add_esp(ParmSize);
 | 
|---|
| [3] | 426 |     }
 | 
|---|
 | 427 | 
 | 
|---|
| [20] | 428 |     //一時オブジェクトを破棄
 | 
|---|
 | 429 |     pobj_parameter->DeleteTempParameters();
 | 
|---|
 | 430 | 
 | 
|---|
 | 431 |     //パラメータオブジェクトを破棄
 | 
|---|
 | 432 |     delete pobj_parameter;
 | 
|---|
| [76] | 433 | 
 | 
|---|
 | 434 |     return true;
 | 
|---|
| [3] | 435 | }
 | 
|---|
 | 436 | 
 | 
|---|
| [250] | 437 | bool Opcode_CallDllProc( const char *lpszParms, const DllProc *pDllProc ){
 | 
|---|
| [3] | 438 | 
 | 
|---|
 | 439 |     extern BOOL bDebugCompile;
 | 
|---|
 | 440 |     extern BOOL bDebugSupportProc;
 | 
|---|
| [113] | 441 |     if(bDebugCompile&&bDebugSupportProc==0&& pDllProc->IsEqualSymbol( "DebugBreak" ) ){
 | 
|---|
| [3] | 442 |         Call_DebugSys_SaveContext();
 | 
|---|
| [75] | 443 |     }
 | 
|---|
| [3] | 444 | 
 | 
|---|
 | 445 | 
 | 
|---|
 | 446 |     ////////////////////////
 | 
|---|
 | 447 |     // パラメータのセット
 | 
|---|
 | 448 |     ////////////////////////
 | 
|---|
 | 449 | 
 | 
|---|
 | 450 |     //パラメータオブジェクトを生成
 | 
|---|
| [71] | 451 |     ParamImpl *pobj_parameter=0;
 | 
|---|
| [76] | 452 |     pobj_parameter=new ParamImpl(lpszParms);
 | 
|---|
| [3] | 453 | 
 | 
|---|
| [77] | 454 |     // デフォルト引数を適用
 | 
|---|
 | 455 |     pobj_parameter->ApplyDefaultParameters( pDllProc->Params() );
 | 
|---|
 | 456 | 
 | 
|---|
| [3] | 457 |     //エラーチェック
 | 
|---|
| [75] | 458 |     if( !pobj_parameter->ErrorCheck( pDllProc->GetName(), pDllProc->Params() ) ){
 | 
|---|
| [31] | 459 |         //パラメータにエラーがあるときは処理を終える
 | 
|---|
| [76] | 460 |         return false;
 | 
|---|
| [31] | 461 |     }
 | 
|---|
| [3] | 462 | 
 | 
|---|
| [45] | 463 |     //一時オブジェクトを生成
 | 
|---|
| [75] | 464 |     pobj_parameter->NewTempParameters( pDllProc->GetName(), pDllProc->Params() );
 | 
|---|
| [45] | 465 | 
 | 
|---|
| [3] | 466 |     //レジスタ、スタックフレームにセット
 | 
|---|
| [75] | 467 |     int ParmSize = pobj_parameter->SetParameter(pDllProc->GetName(), pDllProc->Params() );
 | 
|---|
| [3] | 468 | 
 | 
|---|
 | 469 | 
 | 
|---|
 | 470 |     //動的リンクされたプロシージャの呼び出し
 | 
|---|
 | 471 | 
 | 
|---|
 | 472 |     //call dword ptr[LookupTable]
 | 
|---|
| [250] | 473 |     compiler.codeGenerator.op_call( pDllProc );
 | 
|---|
| [3] | 474 | 
 | 
|---|
| [75] | 475 |     if(pDllProc->IsCdecl()){
 | 
|---|
| [3] | 476 |         //add esp,ParmSize
 | 
|---|
| [225] | 477 |         compiler.codeGenerator.op_add_esp(ParmSize);
 | 
|---|
| [3] | 478 |     }
 | 
|---|
 | 479 | 
 | 
|---|
| [45] | 480 |     //一時オブジェクトを破棄
 | 
|---|
 | 481 |     pobj_parameter->DeleteTempParameters();
 | 
|---|
 | 482 | 
 | 
|---|
 | 483 |     //パラメータオブジェクトを破棄
 | 
|---|
 | 484 |     delete pobj_parameter;
 | 
|---|
 | 485 | 
 | 
|---|
| [76] | 486 |     return true;
 | 
|---|
| [3] | 487 | }
 | 
|---|
| [325] | 488 | 
 | 
|---|
 | 489 | void Opcode_CallDelegate( const Delegate &dg, const char *methodPtrValueStr, const char *objPtrValueStr, const char *params )
 | 
|---|
 | 490 | {
 | 
|---|
| [332] | 491 |     extern BOOL bDebugCompile;
 | 
|---|
 | 492 |     extern BOOL bDebugSupportProc;
 | 
|---|
 | 493 |     if(bDebugCompile&&bDebugSupportProc==0)
 | 
|---|
 | 494 |         Call_DebugSys_SaveContext();
 | 
|---|
 | 495 | 
 | 
|---|
 | 496 | 
 | 
|---|
| [325] | 497 |     ///////////////////////////////////////////////////////////////
 | 
|---|
 | 498 |     // _System_LocalThisのダミーをセット
 | 
|---|
 | 499 |     ///////////////////////////////////////////////////////////////
 | 
|---|
 | 500 | 
 | 
|---|
 | 501 |     char temporary[VN_SIZE]={0};
 | 
|---|
| [339] | 502 |     bool isDynamicCall = false;
 | 
|---|
| [325] | 503 |     if( objPtrValueStr && objPtrValueStr[0] ){
 | 
|---|
 | 504 |         //_System_LocalThis(第一パラメータ)のダミーを作成
 | 
|---|
 | 505 |         lstrcpy(temporary,"0,");
 | 
|---|
| [339] | 506 | 
 | 
|---|
 | 507 |         isDynamicCall = true;
 | 
|---|
| [325] | 508 |     }
 | 
|---|
 | 509 |     if( dg.ReturnType().IsStruct() ){
 | 
|---|
 | 510 |         // ※ByRef _System_ReturnValue パラメータのダミーをセット
 | 
|---|
 | 511 |         lstrcat(temporary,"0,");
 | 
|---|
 | 512 |     }
 | 
|---|
 | 513 | 
 | 
|---|
 | 514 |     if(params[0]=='\0'&&temporary[0])
 | 
|---|
 | 515 |         temporary[lstrlen(temporary)-1]=0;
 | 
|---|
 | 516 |     else lstrcat(temporary,params);
 | 
|---|
 | 517 | 
 | 
|---|
 | 518 | 
 | 
|---|
| [339] | 519 |     const Parameters *pParams = &dg.Params();
 | 
|---|
 | 520 |     if( isDynamicCall )
 | 
|---|
 | 521 |     {
 | 
|---|
 | 522 |         pParams = &dg.GetDynamicParams();
 | 
|---|
 | 523 |     }
 | 
|---|
| [325] | 524 | 
 | 
|---|
| [339] | 525 | 
 | 
|---|
 | 526 |     ParamImpl *pobj_parameter = new ParamImpl( temporary );
 | 
|---|
 | 527 | 
 | 
|---|
| [325] | 528 |     //一時オブジェクトを生成
 | 
|---|
| [339] | 529 |     pobj_parameter->NewTempParameters( dg.GetName(), *pParams );
 | 
|---|
| [325] | 530 | 
 | 
|---|
 | 531 |     //レジスタ、スタックフレームにセット
 | 
|---|
| [339] | 532 |     int ParmSize = pobj_parameter->SetParameter( dg.GetName(), *pParams );
 | 
|---|
| [325] | 533 | 
 | 
|---|
 | 534 | 
 | 
|---|
 | 535 |     if( objPtrValueStr && objPtrValueStr[0] )
 | 
|---|
 | 536 |     {
 | 
|---|
 | 537 |         RELATIVE_VAR RelativeVar;
 | 
|---|
 | 538 |         //Constアクセスが不可能なメソッドの場合
 | 
|---|
 | 539 |         if( !GetVarOffsetReadWrite( objPtrValueStr, &RelativeVar, Type() ) ){
 | 
|---|
 | 540 |             Jenga::Throw( "Opcode_CallDelegate関数内で呼ばれるGetVarOffsetReadWrite関数に失敗" );
 | 
|---|
 | 541 |             return;
 | 
|---|
 | 542 |         }
 | 
|---|
 | 543 | 
 | 
|---|
 | 544 |         SetVarPtrToEax(&RelativeVar);
 | 
|---|
 | 545 | 
 | 
|---|
 | 546 |         // 参照を実体ポインタにする
 | 
|---|
 | 547 |         compiler.codeGenerator.op_mov_RM( sizeof(long), REG_ECX, REG_EAX, 0, MOD_BASE );
 | 
|---|
 | 548 | 
 | 
|---|
 | 549 |         //push ecx
 | 
|---|
 | 550 |         compiler.codeGenerator.op_push(REG_ECX);
 | 
|---|
 | 551 |     }
 | 
|---|
 | 552 | 
 | 
|---|
 | 553 | 
 | 
|---|
 | 554 |     {
 | 
|---|
 | 555 |         ////////////////////////
 | 
|---|
 | 556 |         // call
 | 
|---|
 | 557 |         ////////////////////////
 | 
|---|
 | 558 |         RELATIVE_VAR RelativeVar;
 | 
|---|
 | 559 |         GetVarOffsetReadOnly( methodPtrValueStr, &RelativeVar, Type() );
 | 
|---|
 | 560 |         SetVarPtrToEax( &RelativeVar );
 | 
|---|
 | 561 | 
 | 
|---|
 | 562 |         //mov eax,dword ptr[eax]
 | 
|---|
 | 563 |         compiler.codeGenerator.op_mov_RM( sizeof(long), REG_EAX, REG_EAX, 0, MOD_BASE );
 | 
|---|
 | 564 | 
 | 
|---|
 | 565 |         //call eax
 | 
|---|
 | 566 |         compiler.codeGenerator.op_call_R( REG_EAX );
 | 
|---|
 | 567 |     }
 | 
|---|
 | 568 | 
 | 
|---|
 | 569 | 
 | 
|---|
 | 570 |     //一時オブジェクトを破棄
 | 
|---|
 | 571 |     pobj_parameter->DeleteTempParameters();
 | 
|---|
 | 572 | 
 | 
|---|
 | 573 |     //パラメータオブジェクトを破棄
 | 
|---|
 | 574 |     delete pobj_parameter;
 | 
|---|
 | 575 | }
 | 
|---|