| [206] | 1 | #include "stdafx.h" | 
|---|
|  | 2 |  | 
|---|
| [183] | 3 | #include <jenga/include/smoothie/Smoothie.h> | 
|---|
|  | 4 |  | 
|---|
| [169] | 5 | #include <Program.h> | 
|---|
| [198] | 6 | #include <Compiler.h> | 
|---|
| [206] | 7 | #include <Class.h> | 
|---|
| [169] | 8 |  | 
|---|
| [3] | 9 | #include "../BasicCompiler_Common/common.h" | 
|---|
|  | 10 | #include "Opcode.h" | 
|---|
|  | 11 |  | 
|---|
| [86] | 12 | void SystemProc( const UserProc &userProc ){ | 
|---|
|  | 13 | if( userProc.GetName() == "_System_GetEip" ){ | 
|---|
| [3] | 14 | //mov rax,qword ptr[rsp] | 
|---|
| [226] | 15 | compiler.codeGenerator.op_mov_RM(sizeof(_int64),REG_RAX,REG_RSP,0,MOD_BASE); | 
|---|
| [3] | 16 |  | 
|---|
|  | 17 | //ret | 
|---|
| [226] | 18 | compiler.codeGenerator.op_ret(); | 
|---|
| [3] | 19 | } | 
|---|
| [86] | 20 | else if( userProc.GetName() == "_System_InitDllGlobalVariables" ){ | 
|---|
| [3] | 21 | //////////////////////////////////////// | 
|---|
|  | 22 | // DLLのグローバル領域をコンパイル | 
|---|
|  | 23 | //////////////////////////////////////// | 
|---|
| [266] | 24 | if(!compiler.IsDll()){ | 
|---|
| [3] | 25 | //ret | 
|---|
| [226] | 26 | compiler.codeGenerator.op_ret(); | 
|---|
| [3] | 27 |  | 
|---|
|  | 28 | return; | 
|---|
|  | 29 | } | 
|---|
|  | 30 |  | 
|---|
| [206] | 31 | const UserProc *pBackUserProc = &UserProc::CompilingUserProc(); | 
|---|
| [75] | 32 | UserProc::CompileStartForGlobalArea(); | 
|---|
| [3] | 33 |  | 
|---|
|  | 34 | int BackCp; | 
|---|
|  | 35 | BackCp=cp; | 
|---|
|  | 36 | cp=-1; | 
|---|
|  | 37 |  | 
|---|
|  | 38 | //sub rsp,スタックフレームサイズ | 
|---|
| [255] | 39 | const PertialSchedule *pStackFramePertialSchedule = compiler.codeGenerator.op_sub_rsp( 0, true ); | 
|---|
| [3] | 40 |  | 
|---|
|  | 41 | extern BOOL bDebugCompile; | 
|---|
|  | 42 | if(bDebugCompile){ | 
|---|
|  | 43 | //デバッグ用の変数を定義 | 
|---|
|  | 44 | DebugVariable(); | 
|---|
|  | 45 | } | 
|---|
|  | 46 |  | 
|---|
|  | 47 | //GC用の変数を定義 | 
|---|
|  | 48 | InitGCVariables(); | 
|---|
|  | 49 |  | 
|---|
| [129] | 50 | //_System_StartupProgramの呼び出し | 
|---|
| [206] | 51 | extern const UserProc *pSub_System_StartupProgram; | 
|---|
| [226] | 52 | compiler.codeGenerator.op_call(pSub_System_StartupProgram); | 
|---|
| [129] | 53 |  | 
|---|
| [42] | 54 | //クラスに属する静的メンバを定義 | 
|---|
| [266] | 55 | compiler.GetObjectModule().meta.GetClasses().InitStaticMember(); | 
|---|
| [42] | 56 |  | 
|---|
| [3] | 57 | GetGlobalDataForDll(); | 
|---|
|  | 58 |  | 
|---|
|  | 59 | //add rsp,スタックフレームサイズ | 
|---|
| [226] | 60 | compiler.codeGenerator.op_add_RV(REG_RSP,pobj_sf->GetFrameSize(0)); | 
|---|
| [3] | 61 |  | 
|---|
|  | 62 | //スタックフレームスケジュール(subコマンドに渡す値) | 
|---|
| [255] | 63 | compiler.codeGenerator.opfix( pStackFramePertialSchedule, pobj_sf->GetFrameSize(0) ); | 
|---|
| [3] | 64 |  | 
|---|
| [75] | 65 | UserProc::CompileStartForUserProc( pBackUserProc ); | 
|---|
| [3] | 66 | cp=BackCp; | 
|---|
|  | 67 |  | 
|---|
|  | 68 | //ret | 
|---|
| [226] | 69 | compiler.codeGenerator.op_ret(); | 
|---|
| [3] | 70 | } | 
|---|
| [86] | 71 | else if( userProc.GetName() == "_System_InitStaticLocalVariables" ){ | 
|---|
| [3] | 72 | //静的ローカルオブジェクトのコンストラクタ呼び出し | 
|---|
|  | 73 |  | 
|---|
|  | 74 | //sub rsp,スタックフレームサイズ | 
|---|
| [255] | 75 | const PertialSchedule *pStackFramePertialSchedule = compiler.codeGenerator.op_sub_rsp( 0, true ); | 
|---|
| [3] | 76 |  | 
|---|
| [266] | 77 | BOOST_FOREACH( Variable *pVar, compiler.GetObjectModule().meta.GetGlobalVars() ){ | 
|---|
| [75] | 78 | if(memicmp(pVar->GetName().c_str(),"Static%",7)==0){ | 
|---|
| [3] | 79 | //コンストラクタ呼び出し | 
|---|
| [206] | 80 | if( pVar->GetType().IsObject() ){ | 
|---|
| [3] | 81 |  | 
|---|
|  | 82 | //エラー用 | 
|---|
| [75] | 83 | cp=pVar->source_code_address; | 
|---|
| [3] | 84 |  | 
|---|
| [50] | 85 | CallConstructor( | 
|---|
| [75] | 86 | pVar->GetName().c_str(), | 
|---|
| [206] | 87 | pVar->GetSubscripts(), | 
|---|
|  | 88 | pVar->GetType(), | 
|---|
|  | 89 | pVar->GetParamStrForConstructor().c_str()); | 
|---|
| [3] | 90 | } | 
|---|
|  | 91 | } | 
|---|
|  | 92 | } | 
|---|
|  | 93 |  | 
|---|
|  | 94 | //add rsp,スタックフレームサイズ | 
|---|
| [226] | 95 | compiler.codeGenerator.op_add_RV(REG_RSP,pobj_sf->GetFrameSize(0)); | 
|---|
| [3] | 96 |  | 
|---|
|  | 97 | //スタックフレームスケジュール(subコマンドに渡す値) | 
|---|
| [255] | 98 | compiler.codeGenerator.opfix( pStackFramePertialSchedule, pobj_sf->GetFrameSize(0) ); | 
|---|
| [3] | 99 |  | 
|---|
|  | 100 | //ret | 
|---|
| [226] | 101 | compiler.codeGenerator.op_ret(); | 
|---|
| [3] | 102 | } | 
|---|
| [86] | 103 | else if( userProc.GetName() == "_System_Call_Destructor_of_GlobalObject" ){ | 
|---|
| [3] | 104 | //sub rsp,8(※RSPを16バイト境界にあわせるため) | 
|---|
| [226] | 105 | compiler.codeGenerator.op_sub_rsp(0x8); | 
|---|
| [3] | 106 |  | 
|---|
|  | 107 |  | 
|---|
| [206] | 108 | const UserProc *pBackUserProc = &UserProc::CompilingUserProc(); | 
|---|
| [75] | 109 | UserProc::CompileStartForGlobalArea(); | 
|---|
| [3] | 110 |  | 
|---|
| [254] | 111 | compiler.codeGenerator.lexicalScopes.CallDestructorsOfScopeEnd(); | 
|---|
| [3] | 112 |  | 
|---|
| [75] | 113 | UserProc::CompileStartForUserProc( pBackUserProc ); | 
|---|
| [3] | 114 |  | 
|---|
|  | 115 |  | 
|---|
|  | 116 | //add rsp,8 | 
|---|
| [226] | 117 | compiler.codeGenerator.op_add_RV(REG_RSP,0x8); | 
|---|
| [3] | 118 |  | 
|---|
|  | 119 | //ret | 
|---|
| [226] | 120 | compiler.codeGenerator.op_ret(); | 
|---|
| [3] | 121 | } | 
|---|
| [90] | 122 | else{ | 
|---|
|  | 123 | SetError(); | 
|---|
|  | 124 | } | 
|---|
|  | 125 | } | 
|---|
| [206] | 126 | void AutoGeneration(const UserProc &userProc){ | 
|---|
| [90] | 127 | if( userProc.GetName() == "InitializeUserTypes" | 
|---|
| [89] | 128 | && userProc.HasParentClass() | 
|---|
| [353] | 129 | && userProc.GetParentClass().GetName() == "_System_TypeBase" ) | 
|---|
|  | 130 | { | 
|---|
|  | 131 | compiler.GetObjectModule().meta.GetClasses().Compile_System_InitializeUserTypes(); | 
|---|
| [86] | 132 | } | 
|---|
| [355] | 133 | else if( userProc.GetName() == "InitializeUserTypesForBaseType" | 
|---|
|  | 134 | && userProc.HasParentClass() | 
|---|
|  | 135 | && userProc.GetParentClass().GetName() == "_System_TypeBase" ) | 
|---|
|  | 136 | { | 
|---|
|  | 137 | compiler.GetObjectModule().meta.GetClasses().Compile_System_InitializeUserTypesForBaseType(); | 
|---|
|  | 138 | } | 
|---|
| [95] | 139 | else if( userProc.GetName() == "RegisterGlobalRoots" | 
|---|
|  | 140 | && userProc.HasParentClass() | 
|---|
| [353] | 141 | && userProc.GetParentClass().GetName() == "_System_CGarbageCollection" ) | 
|---|
|  | 142 | { | 
|---|
|  | 143 | Compile_AddGlobalRootsForGc(); | 
|---|
| [95] | 144 | } | 
|---|
| [309] | 145 | else if( userProc.GetName() == compiler.globalAreaProcName ){ | 
|---|
|  | 146 | //////////////////////////////////////// | 
|---|
|  | 147 | // グローバル領域をコンパイル | 
|---|
|  | 148 | //////////////////////////////////////// | 
|---|
|  | 149 |  | 
|---|
| [364] | 150 | UserProc::pGlobalProc = &userProc; | 
|---|
|  | 151 |  | 
|---|
| [309] | 152 | const UserProc *pBackUserProc = &UserProc::CompilingUserProc(); | 
|---|
|  | 153 | UserProc::CompileStartForGlobalArea(); | 
|---|
|  | 154 |  | 
|---|
|  | 155 | int BackCp = cp; | 
|---|
|  | 156 | cp=-1; | 
|---|
|  | 157 |  | 
|---|
|  | 158 | //クラスに属する静的メンバを定義 | 
|---|
|  | 159 | compiler.GetObjectModule().meta.GetClasses().InitStaticMember(); | 
|---|
|  | 160 |  | 
|---|
|  | 161 | //グローバル実行領域をコンパイル開始 | 
|---|
|  | 162 | CompileBuffer(0,0); | 
|---|
|  | 163 |  | 
|---|
|  | 164 | //Goto未知ラベルスケジュールが存在したらエラーにする | 
|---|
|  | 165 | BOOST_FOREACH( const GotoLabelSchedule *pGotoLabelSchedule, compiler.codeGenerator.gotoLabelSchedules ) | 
|---|
|  | 166 | { | 
|---|
|  | 167 | if(pGotoLabelSchedule->GetName().size()>0){ | 
|---|
|  | 168 | SetError(6,pGotoLabelSchedule->GetName(),pGotoLabelSchedule->GetSourceCodePos()); | 
|---|
|  | 169 | } | 
|---|
|  | 170 | else{ | 
|---|
|  | 171 | char temporary[255]; | 
|---|
|  | 172 | sprintf(temporary,"%d",pGotoLabelSchedule->GetLineNum()); | 
|---|
|  | 173 | SetError(6,temporary,pGotoLabelSchedule->GetSourceCodePos()); | 
|---|
|  | 174 | } | 
|---|
|  | 175 | } | 
|---|
|  | 176 |  | 
|---|
|  | 177 | UserProc::CompileStartForUserProc( pBackUserProc ); | 
|---|
|  | 178 | cp=BackCp; | 
|---|
|  | 179 | } | 
|---|
| [350] | 180 | else if( userProc.HasParentClass() | 
|---|
|  | 181 | && userProc.IsCastOperator() | 
|---|
|  | 182 | && userProc.ReturnType().IsInterface() ) | 
|---|
|  | 183 | { | 
|---|
|  | 184 | // インターフェイス型にキャストするためのメソッド | 
|---|
|  | 185 |  | 
|---|
|  | 186 | int vtblMasterListIndex = userProc.GetParentClass().GetVtblMasterListIndex( &userProc.ReturnType().GetClass() ); | 
|---|
|  | 187 |  | 
|---|
|  | 188 | char temporary[1024]; | 
|---|
|  | 189 | sprintf( temporary, | 
|---|
| [370] | 190 | "Return New %s(ObjPtr( This ),Get_LONG_PTR( (Get_LONG_PTR( ObjPtr(This)+SizeOf(VoidPtr) ) + SizeOf(LONG_PTR)*%d) As VoidPtr ) As VoidPtr )", | 
|---|
| [350] | 191 | userProc.ReturnType().GetClass().GetName().c_str(), | 
|---|
|  | 192 | vtblMasterListIndex | 
|---|
|  | 193 | ); | 
|---|
|  | 194 | MakeMiddleCode( temporary ); | 
|---|
|  | 195 |  | 
|---|
|  | 196 | ChangeOpcode( temporary ); | 
|---|
|  | 197 | } | 
|---|
| [86] | 198 | else{ | 
|---|
|  | 199 | SetError(); | 
|---|
|  | 200 | } | 
|---|
| [3] | 201 | } | 
|---|
| [206] | 202 | void _compile_proc(const UserProc *pUserProc){ | 
|---|
| [3] | 203 | extern char *basbuf; | 
|---|
|  | 204 | extern HANDLE hHeap; | 
|---|
|  | 205 | extern BOOL bDebugCompile; | 
|---|
| [76] | 206 | int i3,i4; | 
|---|
| [3] | 207 | char temporary[VN_SIZE]; | 
|---|
|  | 208 |  | 
|---|
| [206] | 209 | if( pUserProc->GetLocalVars().size() ){ | 
|---|
| [76] | 210 | SetError(); | 
|---|
|  | 211 | return; | 
|---|
|  | 212 | } | 
|---|
|  | 213 |  | 
|---|
| [206] | 214 | trace_for_sourcecodestep( "★★★ " << pUserProc->GetFullName() << "のコンパイルを開始" ); | 
|---|
|  | 215 |  | 
|---|
| [75] | 216 | pUserProc->CompleteCompile(); | 
|---|
| [3] | 217 |  | 
|---|
|  | 218 | extern BOOL bSystemProc; | 
|---|
| [75] | 219 | if(memcmp(pUserProc->GetName().c_str(),"_System_",8)==0) bSystemProc=1; | 
|---|
| [3] | 220 | else bSystemProc=0; | 
|---|
|  | 221 |  | 
|---|
|  | 222 | extern BOOL bDebugSupportProc; | 
|---|
| [75] | 223 | if(memcmp(pUserProc->GetName().c_str(),"_DebugSys_",10)==0){ | 
|---|
| [3] | 224 | if(!bDebugCompile){ | 
|---|
|  | 225 | return; | 
|---|
|  | 226 | } | 
|---|
|  | 227 | bDebugSupportProc=1; | 
|---|
|  | 228 | } | 
|---|
|  | 229 | else bDebugSupportProc=0; | 
|---|
|  | 230 |  | 
|---|
| [89] | 231 | //コンパイル中の関数が属するクラス | 
|---|
| [206] | 232 | compiler.pCompilingClass=pUserProc->GetParentClassPtr(); | 
|---|
| [89] | 233 |  | 
|---|
|  | 234 | //コンパイルスタートをクラス管理クラスに追加 | 
|---|
| [266] | 235 | compiler.GetObjectModule().meta.GetClasses().StartCompile( pUserProc ); | 
|---|
| [89] | 236 |  | 
|---|
|  | 237 | //コンパイル中の関数 | 
|---|
|  | 238 | UserProc::CompileStartForUserProc( pUserProc ); | 
|---|
|  | 239 |  | 
|---|
| [101] | 240 | // コンパイル中の関数が属する名前空間 | 
|---|
| [202] | 241 | compiler.GetNamespaceSupporter().SetLivingNamespaceScopes( pUserProc->GetNamespaceScopes() ); | 
|---|
| [101] | 242 |  | 
|---|
| [108] | 243 | // コンパイル中の関数でImportsされている名前空間 | 
|---|
| [202] | 244 | compiler.GetNamespaceSupporter().SetImportedNamespaces( pUserProc->GetImportedNamespaces() ); | 
|---|
| [108] | 245 |  | 
|---|
| [226] | 246 | // コード生成対象を選択 | 
|---|
|  | 247 | compiler.codeGenerator.Select( (const_cast<UserProc *>(pUserProc))->GetNativeCode() ); | 
|---|
|  | 248 |  | 
|---|
| [75] | 249 | if(pUserProc->IsSystem()){ | 
|---|
| [3] | 250 | //////////////////// | 
|---|
|  | 251 | // 特殊関数 | 
|---|
|  | 252 | //////////////////// | 
|---|
|  | 253 |  | 
|---|
|  | 254 | extern int AllLocalVarSize; | 
|---|
|  | 255 | AllLocalVarSize=0; | 
|---|
|  | 256 |  | 
|---|
|  | 257 | //スタックフレーム管理用オブジェクトを初期化 | 
|---|
| [308] | 258 | extern StackFrame *pobj_sf; | 
|---|
|  | 259 | pobj_sf=new StackFrame(); | 
|---|
| [3] | 260 |  | 
|---|
| [86] | 261 | SystemProc(*pUserProc); | 
|---|
| [3] | 262 |  | 
|---|
|  | 263 | //スタックフレーム管理用オブジェクトを破棄 | 
|---|
|  | 264 | delete pobj_sf; | 
|---|
|  | 265 | pobj_sf=0; | 
|---|
|  | 266 |  | 
|---|
|  | 267 | return; | 
|---|
|  | 268 | } | 
|---|
|  | 269 |  | 
|---|
| [353] | 270 | if( !pUserProc->IsAutoGeneration() ) | 
|---|
|  | 271 | { | 
|---|
|  | 272 | cp=pUserProc->GetCodePos(); | 
|---|
|  | 273 | for(;;cp++){ | 
|---|
|  | 274 | if(IsCommandDelimitation(basbuf[cp])) break; | 
|---|
|  | 275 | } | 
|---|
|  | 276 | cp--; | 
|---|
| [3] | 277 | } | 
|---|
|  | 278 |  | 
|---|
|  | 279 | //プロシージャ抜け出しスケジュール(Exit Sub/Function) | 
|---|
| [254] | 280 | compiler.codeGenerator.exitSubCodePositions.clear(); | 
|---|
| [3] | 281 |  | 
|---|
|  | 282 | //ラベル用のメモリを確保 | 
|---|
| [262] | 283 | compiler.codeGenerator.gotoLabels.clear(); | 
|---|
| [3] | 284 |  | 
|---|
|  | 285 | //Gotoラベルスケジュール | 
|---|
| [254] | 286 | compiler.codeGenerator.gotoLabelSchedules.clear(); | 
|---|
| [3] | 287 |  | 
|---|
|  | 288 | //With情報のメモリを確保 | 
|---|
|  | 289 | extern WITHINFO WithInfo; | 
|---|
|  | 290 | WithInfo.ppName=(char **)HeapAlloc(hHeap,0,1); | 
|---|
|  | 291 | WithInfo.pWithCp=(int *)HeapAlloc(hHeap,0,1); | 
|---|
|  | 292 | WithInfo.num=0; | 
|---|
|  | 293 |  | 
|---|
|  | 294 | //重複エラー情報管理のメモリを確保 | 
|---|
|  | 295 | extern char **SynonymErrorWords; | 
|---|
|  | 296 | extern int SynonymErrorNum; | 
|---|
|  | 297 | SynonymErrorNum=0; | 
|---|
|  | 298 | SynonymErrorWords=(char **)HeapAlloc(hHeap,0,1); | 
|---|
|  | 299 |  | 
|---|
|  | 300 | //Continueアドレスを初期化 | 
|---|
| [242] | 301 | compiler.codeGenerator.ClearContinueArea(); | 
|---|
| [3] | 302 |  | 
|---|
|  | 303 | //ローカル変数に関する情報 | 
|---|
|  | 304 | extern int AllLocalVarSize; | 
|---|
|  | 305 | AllLocalVarSize=0; | 
|---|
|  | 306 |  | 
|---|
|  | 307 | //レキシカルスコープ情報を初期化 | 
|---|
| [308] | 308 | compiler.codeGenerator.lexicalScopes.Init( compiler.codeGenerator.GetNativeCodeSize() ); | 
|---|
| [3] | 309 |  | 
|---|
|  | 310 |  | 
|---|
|  | 311 | ///////////////////////////////////// | 
|---|
|  | 312 | // パラメータ用の変数データを考慮 | 
|---|
|  | 313 | ///////////////////////////////////// | 
|---|
|  | 314 |  | 
|---|
| [75] | 315 | //パラメータ用の変数データを考慮 | 
|---|
|  | 316 | for(i3=(int)pUserProc->RealParams().size()-1;i3>=0;i3--){ | 
|---|
|  | 317 | Parameter ¶m = *pUserProc->RealParams()[i3]; | 
|---|
| [3] | 318 |  | 
|---|
| [308] | 319 | Variable *pVar = new Variable( param.GetVarName(), param, false, param.IsRef(), "", false ); | 
|---|
| [3] | 320 |  | 
|---|
| [75] | 321 | if( param.IsArray() ){ | 
|---|
| [206] | 322 | pVar->SetArray( param.GetSubscripts() ); | 
|---|
| [3] | 323 | } | 
|---|
|  | 324 |  | 
|---|
| [75] | 325 | int varSize; | 
|---|
|  | 326 | if( param.IsRef() == false && param.IsStruct() ){ | 
|---|
| [64] | 327 | //構造体のByValパラメータ | 
|---|
| [75] | 328 | pVar->ThisIsParameter(); | 
|---|
|  | 329 | varSize=PTR_SIZE; | 
|---|
| [3] | 330 | } | 
|---|
|  | 331 | else{ | 
|---|
| [75] | 332 | if( param.IsArray() == false ){ | 
|---|
|  | 333 | varSize = pVar->GetMemorySize(); | 
|---|
| [3] | 334 | } | 
|---|
|  | 335 | else{ | 
|---|
| [75] | 336 | varSize=PTR_SIZE; | 
|---|
| [3] | 337 | } | 
|---|
|  | 338 | } | 
|---|
| [75] | 339 | AllLocalVarSize+=varSize; | 
|---|
| [206] | 340 | pVar->SetOffsetAddress( AllLocalVarSize ); | 
|---|
| [3] | 341 |  | 
|---|
|  | 342 | //レキシカルスコープ情報 | 
|---|
| [254] | 343 | pVar->SetScopeLevel( compiler.codeGenerator.lexicalScopes.GetNowLevel() ); | 
|---|
|  | 344 | pVar->SetScopeStartAddress( compiler.codeGenerator.lexicalScopes.GetStartAddress() ); | 
|---|
| [392] | 345 | pVar->isLiving = true; | 
|---|
| [3] | 346 |  | 
|---|
| [206] | 347 | pUserProc->GetLocalVars().push_back( pVar ); | 
|---|
| [3] | 348 | } | 
|---|
|  | 349 |  | 
|---|
|  | 350 | //Thisポインタを示すローカルオフセット値をセット | 
|---|
|  | 351 | extern int LocalVar_ThisPtrOffset; | 
|---|
|  | 352 | LocalVar_ThisPtrOffset=AllLocalVarSize; | 
|---|
|  | 353 |  | 
|---|
|  | 354 | //スタックフレーム管理用クラスを初期化 | 
|---|
| [308] | 355 | extern StackFrame *pobj_sf; | 
|---|
|  | 356 | pobj_sf=new StackFrame(); | 
|---|
| [3] | 357 |  | 
|---|
|  | 358 |  | 
|---|
|  | 359 | /////////////////////// | 
|---|
|  | 360 | // ここからコード生成 | 
|---|
|  | 361 |  | 
|---|
| [75] | 362 | for(i3=(int)pUserProc->RealParams().size()-1;i3>=0;i3--){ | 
|---|
|  | 363 | Parameter ¶m = *pUserProc->RealParams()[i3]; | 
|---|
| [3] | 364 | if(i3==3){ | 
|---|
| [75] | 365 | if(param.IsReal()&¶m.IsRef() == false){ | 
|---|
| [3] | 366 | //movsd qword ptr[rsp+0x20],xmm3 | 
|---|
| [226] | 367 | compiler.codeGenerator.op_movsd_MR(REG_XMM3,REG_RSP,0x20,MOD_BASE_DISP32); | 
|---|
| [3] | 368 | } | 
|---|
|  | 369 | else{ | 
|---|
|  | 370 | //mov qword ptr[rsp+0x20],r9 | 
|---|
| [226] | 371 | compiler.codeGenerator.op_mov_MR(sizeof(_int64),REG_R9,REG_RSP,0x20,MOD_BASE_DISP32); | 
|---|
| [3] | 372 | } | 
|---|
|  | 373 | } | 
|---|
|  | 374 | if(i3==2){ | 
|---|
| [75] | 375 | if(param.IsReal()&¶m.IsRef() == false){ | 
|---|
| [3] | 376 | //movsd qword ptr[rsp+0x18],xmm2 | 
|---|
| [226] | 377 | compiler.codeGenerator.op_movsd_MR(REG_XMM2,REG_RSP,0x18,MOD_BASE_DISP32); | 
|---|
| [3] | 378 | } | 
|---|
|  | 379 | else{ | 
|---|
|  | 380 | //mov qword ptr[rsp+0x18],r8 | 
|---|
| [226] | 381 | compiler.codeGenerator.op_mov_MR(sizeof(_int64),REG_R8,REG_RSP,0x18,MOD_BASE_DISP32); | 
|---|
| [3] | 382 | } | 
|---|
|  | 383 | } | 
|---|
|  | 384 | if(i3==1){ | 
|---|
| [75] | 385 | if(param.IsReal()&¶m.IsRef() == false){ | 
|---|
| [3] | 386 | //movsd qword ptr[rsp+0x10],xmm1 | 
|---|
| [226] | 387 | compiler.codeGenerator.op_movsd_MR(REG_XMM1,REG_RSP,0x10,MOD_BASE_DISP32); | 
|---|
| [3] | 388 | } | 
|---|
|  | 389 | else{ | 
|---|
|  | 390 | //mov qword ptr[rsp+0x10],rdx | 
|---|
| [226] | 391 | compiler.codeGenerator.op_mov_MR(sizeof(_int64),REG_RDX,REG_RSP,0x10,MOD_BASE_DISP32); | 
|---|
| [3] | 392 | } | 
|---|
|  | 393 | } | 
|---|
|  | 394 | if(i3==0){ | 
|---|
| [75] | 395 | if(param.IsReal()&¶m.IsRef() == false){ | 
|---|
| [3] | 396 | //movsd qword ptr[rsp+0x8],xmm0 | 
|---|
| [226] | 397 | compiler.codeGenerator.op_movsd_MR(REG_XMM0,REG_RSP,0x8,MOD_BASE_DISP32); | 
|---|
| [3] | 398 | } | 
|---|
|  | 399 | else{ | 
|---|
|  | 400 | //mov qword ptr[rsp+0x8],rcx | 
|---|
| [226] | 401 | compiler.codeGenerator.op_mov_MR(sizeof(_int64),REG_RCX,REG_RSP,0x8,MOD_BASE_DISP32); | 
|---|
| [3] | 402 | } | 
|---|
|  | 403 | } | 
|---|
|  | 404 | } | 
|---|
|  | 405 |  | 
|---|
|  | 406 | //ret用のアドレスを考慮 | 
|---|
|  | 407 | AllLocalVarSize+=sizeof(_int64); | 
|---|
|  | 408 |  | 
|---|
|  | 409 | //sub rsp,スタックフレームサイズ | 
|---|
| [255] | 410 | const PertialSchedule *pStackFramePertialSchedule = compiler.codeGenerator.op_sub_rsp( 0, true ); | 
|---|
| [3] | 411 |  | 
|---|
|  | 412 | //mov qword ptr[rsp+offset],reg     ※スタックフレームを利用 | 
|---|
|  | 413 | pobj_sf->push(REG_RBX); | 
|---|
|  | 414 | pobj_sf->push(REG_RSI); | 
|---|
|  | 415 | pobj_sf->push(REG_RDI); | 
|---|
|  | 416 | pobj_sf->push(REG_R12); | 
|---|
|  | 417 | pobj_sf->push(REG_R13); | 
|---|
|  | 418 | pobj_sf->push(REG_R14); | 
|---|
|  | 419 | pobj_sf->push(REG_R15); | 
|---|
|  | 420 |  | 
|---|
|  | 421 | //ローカル変数のベース値 | 
|---|
|  | 422 | int BaseLocalVar; | 
|---|
|  | 423 | BaseLocalVar=AllLocalVarSize; | 
|---|
|  | 424 |  | 
|---|
| [75] | 425 | if( !pUserProc->ReturnType().IsNull() ){ | 
|---|
| [3] | 426 | //戻り値が存在するとき | 
|---|
|  | 427 |  | 
|---|
| [75] | 428 | const char *temp = pUserProc->GetName().c_str(); | 
|---|
|  | 429 | if( temp[0]==1&&temp[1]==ESC_OPERATOR ){ | 
|---|
|  | 430 | temp = "_System_ReturnValue"; | 
|---|
|  | 431 | } | 
|---|
| [3] | 432 |  | 
|---|
| [75] | 433 | if( pUserProc->ReturnType().IsStruct() ){ | 
|---|
| [64] | 434 | //戻り値用の構造体(値型)はパラメータで引き渡される | 
|---|
| [3] | 435 | } | 
|---|
|  | 436 | else{ | 
|---|
| [89] | 437 | if( pUserProc->ReturnType().IsObject() ){ | 
|---|
| [308] | 438 | sprintf(temporary,"%s=Nothing%c%c%s",temp,1,ESC_AS, compiler.TypeToString( pUserProc->ReturnType() ).c_str() ); | 
|---|
| [89] | 439 | } | 
|---|
|  | 440 | else{ | 
|---|
|  | 441 | //戻り値用の変数の定義 | 
|---|
| [308] | 442 | sprintf(temporary,"%s%c%c%s",temp,1,ESC_AS, compiler.TypeToString( pUserProc->ReturnType() ).c_str() ); | 
|---|
| [89] | 443 | } | 
|---|
| [40] | 444 |  | 
|---|
| [3] | 445 | OpcodeDim(temporary,0); | 
|---|
|  | 446 | } | 
|---|
|  | 447 | } | 
|---|
|  | 448 |  | 
|---|
| [255] | 449 | const PertialSchedule *pRspOffsetPertialSchedule1 = NULL; | 
|---|
|  | 450 | const PertialSchedule *pRspOffsetPertialSchedule2 = NULL; | 
|---|
| [3] | 451 | if(bDebugCompile&&bDebugSupportProc==0){ | 
|---|
|  | 452 | //mov rdx, qword ptr[rsp+スタックフレームサイズ] | 
|---|
| [255] | 453 | pRspOffsetPertialSchedule1 = compiler.codeGenerator.op_mov_RM(sizeof(_int64),REG_RDX,REG_RSP,0,MOD_BASE_DISP32, Schedule::None, true ); | 
|---|
| [3] | 454 |  | 
|---|
|  | 455 | //mov rcx,rsp | 
|---|
| [226] | 456 | compiler.codeGenerator.op_mov_RR(REG_RCX,REG_RSP); | 
|---|
| [3] | 457 |  | 
|---|
|  | 458 | //add rcx,スタックフレームサイズ+sizeof(_int64) ※ret用のサイズを考慮 | 
|---|
| [255] | 459 | pRspOffsetPertialSchedule2 = compiler.codeGenerator.op_add_RV(REG_RCX,0, Schedule::None, true ); | 
|---|
| [3] | 460 |  | 
|---|
|  | 461 | //call _DebugSys_StartProc | 
|---|
| [206] | 462 | extern const UserProc *pSub_DebugSys_StartProc; | 
|---|
| [226] | 463 | compiler.codeGenerator.op_call(pSub_DebugSys_StartProc); | 
|---|
| [3] | 464 | } | 
|---|
|  | 465 |  | 
|---|
| [206] | 466 | if(compiler.pCompilingClass){ | 
|---|
|  | 467 | if( pUserProc->GetName() == compiler.pCompilingClass->GetName() ){ | 
|---|
| [3] | 468 | //////////////////////////////////// | 
|---|
|  | 469 | // コンストラクタをコンパイルするとき | 
|---|
|  | 470 | //////////////////////////////////// | 
|---|
|  | 471 |  | 
|---|
| [17] | 472 | //コンストラクタのコンパイル開始を通知 | 
|---|
| [206] | 473 | compiler.pCompilingClass->NotifyStartConstructorCompile(); | 
|---|
| [17] | 474 |  | 
|---|
| [27] | 475 | //基底クラスかどうかの識別 | 
|---|
|  | 476 | //(継承元がインターフェイスの場合も基底クラスと見なす) | 
|---|
| [3] | 477 | BOOL bThisIsSuperClass; | 
|---|
| [206] | 478 | if( !compiler.pCompilingClass->HasSuperClass() ) bThisIsSuperClass=1; | 
|---|
|  | 479 | else if( compiler.pCompilingClass->GetSuperClass().GetConstructorMethod() == NULL ){ | 
|---|
| [3] | 480 | //インターフェイスを継承したときはコンストラクタを持たない | 
|---|
|  | 481 | bThisIsSuperClass=1; | 
|---|
|  | 482 | } | 
|---|
|  | 483 | else bThisIsSuperClass=0; | 
|---|
|  | 484 |  | 
|---|
|  | 485 | if(!bThisIsSuperClass){ | 
|---|
|  | 486 | /* サブクラスコンストラクタをコンパイルしているときは、 | 
|---|
| [27] | 487 | 基底クラスのコンストラクタを呼び出す */ | 
|---|
| [3] | 488 |  | 
|---|
|  | 489 | i3=cp+1; | 
|---|
|  | 490 | while(IsCommandDelimitation(basbuf[i3])) i3++; | 
|---|
|  | 491 | for(i4=0;;i3++,i4++){ | 
|---|
|  | 492 | if(!IsVariableChar(basbuf[i3])){ | 
|---|
|  | 493 | temporary[i4]=0; | 
|---|
|  | 494 | break; | 
|---|
|  | 495 | } | 
|---|
|  | 496 | temporary[i4]=basbuf[i3]; | 
|---|
|  | 497 | } | 
|---|
| [206] | 498 | if( compiler.pCompilingClass->GetSuperClass().GetName() == temporary ){ | 
|---|
| [27] | 499 | //基底クラスのコンストラクタを呼び出す | 
|---|
| [3] | 500 | cp=i3; | 
|---|
|  | 501 | for(i4=0;;cp++,i4++){ | 
|---|
|  | 502 | if(IsCommandDelimitation(basbuf[cp])){ | 
|---|
|  | 503 | temporary[i4]=0; | 
|---|
|  | 504 | break; | 
|---|
|  | 505 | } | 
|---|
|  | 506 | temporary[i4]=basbuf[cp]; | 
|---|
|  | 507 | } | 
|---|
|  | 508 | if(!(temporary[0]=='('&&temporary[lstrlen(temporary)-1]==')')){ | 
|---|
|  | 509 | SetError(1,NULL,cp); | 
|---|
|  | 510 | } | 
|---|
|  | 511 | RemoveStringPare(temporary); | 
|---|
|  | 512 |  | 
|---|
| [89] | 513 | Type dummyType; | 
|---|
|  | 514 | CallProc( PROC_DEFAULT | 
|---|
| [206] | 515 | , &compiler.pCompilingClass->GetSuperClass().GetConstructorMethod()->GetUserProc() | 
|---|
|  | 516 | , compiler.pCompilingClass->GetSuperClass().GetConstructorMethod()->GetUserProc().GetName().c_str() | 
|---|
| [89] | 517 | , temporary | 
|---|
| [331] | 518 | , Type()        // baseTypeはなし | 
|---|
|  | 519 | , dummyType | 
|---|
|  | 520 | ); | 
|---|
| [3] | 521 | } | 
|---|
|  | 522 | else{ | 
|---|
| [27] | 523 | //基底クラスのコンストラクタを暗黙的に呼び出す | 
|---|
| [3] | 524 | Opcode_CallProc("", | 
|---|
| [206] | 525 | &compiler.pCompilingClass->GetSuperClass().GetConstructorMethod()->GetUserProc(), | 
|---|
| [3] | 526 | 0, | 
|---|
| [308] | 527 | ""); | 
|---|
| [3] | 528 | } | 
|---|
|  | 529 | } | 
|---|
|  | 530 | } | 
|---|
| [75] | 531 | else if( pUserProc->IsDestructor() ){ | 
|---|
| [18] | 532 | //デストラクタをコンパイルしたとき | 
|---|
|  | 533 |  | 
|---|
|  | 534 | //デストラクタのコンパイル開始を通知 | 
|---|
| [206] | 535 | compiler.pCompilingClass->NotifyStartDestructorCompile(); | 
|---|
| [18] | 536 | } | 
|---|
| [3] | 537 | } | 
|---|
|  | 538 |  | 
|---|
|  | 539 | ////////////////////////////////////////// | 
|---|
|  | 540 | ////////////////////////////////////////// | 
|---|
|  | 541 | ////// プロシージャ内をコンパイル //////// | 
|---|
| [90] | 542 | if( pUserProc->IsAutoGeneration() ){ | 
|---|
|  | 543 | AutoGeneration( *pUserProc ); | 
|---|
|  | 544 | } | 
|---|
| [75] | 545 | else{ | 
|---|
| [90] | 546 | if(pUserProc->IsMacro()){ | 
|---|
|  | 547 | CompileBuffer(ESC_ENDMACRO,0); | 
|---|
|  | 548 | } | 
|---|
|  | 549 | else{ | 
|---|
|  | 550 | if(pUserProc->IsSub()){ | 
|---|
|  | 551 | CompileBuffer(ESC_ENDSUB,0); | 
|---|
|  | 552 | } | 
|---|
|  | 553 | else if(pUserProc->IsFunction()){ | 
|---|
|  | 554 | CompileBuffer(ESC_ENDFUNCTION,0); | 
|---|
|  | 555 | } | 
|---|
|  | 556 | } | 
|---|
| [75] | 557 | } | 
|---|
| [3] | 558 | ////////////////////////////////////////// | 
|---|
|  | 559 | ////////////////////////////////////////// | 
|---|
|  | 560 |  | 
|---|
| [206] | 561 | if( compiler.pCompilingClass ){ | 
|---|
| [17] | 562 |  | 
|---|
| [206] | 563 | if( compiler.pCompilingClass->IsCompilingConstructor() ){ | 
|---|
| [17] | 564 | // コンストラクタをコンパイルしていたとき | 
|---|
| [18] | 565 |  | 
|---|
| [17] | 566 | // コンストラクタのコンパイルが完了したことを通知 | 
|---|
| [206] | 567 | compiler.pCompilingClass->NotifyFinishConstructorCompile(); | 
|---|
| [17] | 568 | } | 
|---|
| [75] | 569 | else if( pUserProc->IsDestructor() ){ | 
|---|
| [3] | 570 | //////////////////////////////////// | 
|---|
|  | 571 | //デストラクタをコンパイルしたとき | 
|---|
|  | 572 | //////////////////////////////////// | 
|---|
|  | 573 |  | 
|---|
| [18] | 574 | // デストラクタのコンパイルが完了したことを通知 | 
|---|
| [206] | 575 | compiler.pCompilingClass->NotifyFinishDestructorCompile(); | 
|---|
| [18] | 576 |  | 
|---|
| [206] | 577 | if( compiler.pCompilingClass->HasSuperClass() ){ | 
|---|
| [3] | 578 | /* サブクラスのデストラクタをコンパイルしているときは、 | 
|---|
| [27] | 579 | 基底クラスのデストラクタを呼び出す */ | 
|---|
| [3] | 580 |  | 
|---|
| [206] | 581 | const CMethod *method = compiler.pCompilingClass->GetSuperClass().GetDestructorMethod(); | 
|---|
| [51] | 582 | if( method ){ | 
|---|
| [3] | 583 | Opcode_CallProc("", | 
|---|
| [206] | 584 | &method->GetUserProc(), | 
|---|
| [3] | 585 | 0, | 
|---|
| [308] | 586 | ""); | 
|---|
| [3] | 587 | } | 
|---|
|  | 588 | } | 
|---|
|  | 589 | } | 
|---|
|  | 590 | } | 
|---|
|  | 591 |  | 
|---|
| [366] | 592 | // Tryスコープの検証 | 
|---|
|  | 593 | Exception::InspectTryScope(); | 
|---|
|  | 594 |  | 
|---|
| [3] | 595 | //With情報のメモリを解放 | 
|---|
|  | 596 | for(i3=0;i3<WithInfo.num;i3++){ | 
|---|
|  | 597 | SetError(22,"With",WithInfo.pWithCp[i3]); | 
|---|
|  | 598 | HeapDefaultFree(WithInfo.ppName[i3]); | 
|---|
|  | 599 | } | 
|---|
|  | 600 | HeapDefaultFree(WithInfo.ppName); | 
|---|
|  | 601 | HeapDefaultFree(WithInfo.pWithCp); | 
|---|
|  | 602 |  | 
|---|
|  | 603 | //ローカルオブジェクト(レキシカルスコープレベル=0)の解放処理 | 
|---|
| [254] | 604 | compiler.codeGenerator.lexicalScopes.CallDestructorsOfScopeEnd(); | 
|---|
| [3] | 605 |  | 
|---|
| [34] | 606 | //プロシージャ抜け出しスケジュール(Exit Sub/Function) | 
|---|
| [254] | 607 | compiler.codeGenerator.ResolveExitSubSchedule(); | 
|---|
| [34] | 608 |  | 
|---|
|  | 609 | if(bDebugCompile&&bDebugSupportProc==0){ | 
|---|
|  | 610 | //call _DebugSys_EndProc | 
|---|
| [206] | 611 | extern const UserProc *pSub_DebugSys_EndProc; | 
|---|
| [226] | 612 | compiler.codeGenerator.op_call(pSub_DebugSys_EndProc); | 
|---|
| [34] | 613 | } | 
|---|
|  | 614 |  | 
|---|
| [75] | 615 | if( !pUserProc->ReturnType().IsNull() ){ | 
|---|
| [3] | 616 | ////////////////////////////////// | 
|---|
|  | 617 | // 戻り値をraxまたはxmm0に設定 | 
|---|
|  | 618 | ////////////////////////////////// | 
|---|
|  | 619 |  | 
|---|
|  | 620 | RELATIVE_VAR RelativeVar; | 
|---|
|  | 621 |  | 
|---|
| [75] | 622 | const char *temp = pUserProc->GetName().c_str(); | 
|---|
|  | 623 | if( temp[0]==1 && temp[1]==ESC_OPERATOR ){ | 
|---|
| [3] | 624 | temp="_System_ReturnValue"; | 
|---|
| [75] | 625 | } | 
|---|
|  | 626 | GetVarOffsetReadWrite(temp,&RelativeVar,Type()); | 
|---|
| [3] | 627 |  | 
|---|
| [316] | 628 | const Type &returnType = pUserProc->ReturnType(); | 
|---|
|  | 629 | if( returnType.IsObject() || returnType.IsStruct() ) | 
|---|
|  | 630 | { | 
|---|
| [3] | 631 | SetVarPtrToReg(REG_RAX,&RelativeVar); | 
|---|
| [316] | 632 | if( returnType.IsObject() ) | 
|---|
|  | 633 | { | 
|---|
| [64] | 634 | //mov rax,qword ptr[rax] | 
|---|
| [226] | 635 | compiler.codeGenerator.op_mov_RM( sizeof(_int64), REG_RAX, REG_RAX, 0, MOD_BASE ); | 
|---|
| [64] | 636 | } | 
|---|
| [3] | 637 | } | 
|---|
| [316] | 638 | else if( returnType.IsDouble() ) | 
|---|
|  | 639 | { | 
|---|
| [3] | 640 | //64ビット実数型 | 
|---|
|  | 641 | SetXmmReg_DoubleVariable(&RelativeVar,REG_XMM0); | 
|---|
|  | 642 | } | 
|---|
| [316] | 643 | else if( returnType.IsSingle() ) | 
|---|
|  | 644 | { | 
|---|
| [3] | 645 | //32ビット実数型 | 
|---|
|  | 646 | SetXmmReg_SingleVariable(&RelativeVar,REG_XMM0); | 
|---|
|  | 647 | } | 
|---|
| [316] | 648 | else if( returnType.IsWhole() ) | 
|---|
|  | 649 | { | 
|---|
| [3] | 650 | //整数型 | 
|---|
| [318] | 651 | SetReg_WholeVariable(returnType,&RelativeVar,REG_RAX); | 
|---|
| [3] | 652 | } | 
|---|
|  | 653 | else SetError(300,NULL,cp); | 
|---|
|  | 654 | } | 
|---|
|  | 655 |  | 
|---|
|  | 656 | //ローカル変数領域のサイズをスタックフレームに通知 | 
|---|
| [220] | 657 | int localParmSize = AllLocalVarSize - BaseLocalVar; | 
|---|
| [232] | 658 | int stackFrameSize = pobj_sf->GetFrameSize( localParmSize ); | 
|---|
| [3] | 659 |  | 
|---|
|  | 660 | //ローカル変数アドレススケジュール | 
|---|
| [254] | 661 | BOOST_FOREACH( const PertialSchedule *pPertialSchedule, compiler.codeGenerator.localVarPertialSchedules ) | 
|---|
|  | 662 | { | 
|---|
| [255] | 663 | compiler.codeGenerator.opfix_offset( pPertialSchedule, AllLocalVarSize + stackFrameSize ); | 
|---|
| [3] | 664 | } | 
|---|
| [254] | 665 | compiler.codeGenerator.localVarPertialSchedules.clear(); | 
|---|
| [206] | 666 | BOOST_FOREACH( Variable *pVar, pUserProc->GetLocalVars() ){ | 
|---|
| [3] | 667 | //後にデバッグで利用する | 
|---|
| [206] | 668 | pVar->SetOffsetAddress( | 
|---|
| [220] | 669 | AllLocalVarSize + stackFrameSize - pVar->GetOffsetAddress() | 
|---|
| [206] | 670 | ); | 
|---|
| [3] | 671 | } | 
|---|
|  | 672 |  | 
|---|
|  | 673 | //mov reg,qword ptr[rsp+offset]     ※スタックフレームを利用 | 
|---|
|  | 674 | pobj_sf->pop(REG_R15); | 
|---|
|  | 675 | pobj_sf->pop(REG_R14); | 
|---|
|  | 676 | pobj_sf->pop(REG_R13); | 
|---|
|  | 677 | pobj_sf->pop(REG_R12); | 
|---|
|  | 678 | pobj_sf->pop(REG_RDI); | 
|---|
|  | 679 | pobj_sf->pop(REG_RSI); | 
|---|
|  | 680 | pobj_sf->pop(REG_RBX); | 
|---|
|  | 681 |  | 
|---|
| [220] | 682 | int stackFrameAndLocalParamSize = localParmSize + stackFrameSize; | 
|---|
| [3] | 683 |  | 
|---|
|  | 684 | //add rsp,スタックフレームサイズ | 
|---|
| [226] | 685 | compiler.codeGenerator.op_add_rsp(stackFrameAndLocalParamSize); | 
|---|
| [3] | 686 |  | 
|---|
| [142] | 687 | //ret | 
|---|
| [226] | 688 | compiler.codeGenerator.op_ret(); | 
|---|
| [3] | 689 |  | 
|---|
|  | 690 |  | 
|---|
|  | 691 | //デバッグ用 | 
|---|
| [255] | 692 | if( pRspOffsetPertialSchedule1 ){ | 
|---|
|  | 693 | compiler.codeGenerator.opfix( pRspOffsetPertialSchedule1, stackFrameAndLocalParamSize ); | 
|---|
|  | 694 | compiler.codeGenerator.opfix( pRspOffsetPertialSchedule2, stackFrameAndLocalParamSize + sizeof(_int64) ); | 
|---|
| [3] | 695 | } | 
|---|
|  | 696 |  | 
|---|
|  | 697 |  | 
|---|
|  | 698 | //スタックフレームスケジュール(subコマンド) | 
|---|
| [255] | 699 | compiler.codeGenerator.opfix( pStackFramePertialSchedule, stackFrameAndLocalParamSize ); | 
|---|
| [3] | 700 |  | 
|---|
|  | 701 | //スタックフレームスケジュールを実行 | 
|---|
| [220] | 702 | pobj_sf->RunningSchedule( stackFrameSize ); | 
|---|
| [3] | 703 | delete pobj_sf; | 
|---|
|  | 704 | pobj_sf=0; | 
|---|
|  | 705 |  | 
|---|
|  | 706 |  | 
|---|
| [75] | 707 | //重複エラー情報管理のメモリを解放 | 
|---|
|  | 708 | for(i3=0;i3<SynonymErrorNum;i3++) HeapDefaultFree(SynonymErrorWords[i3]); | 
|---|
|  | 709 | HeapDefaultFree(SynonymErrorWords); | 
|---|
| [3] | 710 | } | 
|---|