bool CBotInstrCall::Execute(CBotStack* &pj) { CBotVar* ppVars[1000]; CBotStack* pile = pj->AddStack(this); if ( pile->StackOver() ) return pj->Return( pile ); // CBotStack* pile1 = pile; int i = 0; CBotInstr* p = m_Parameters; // evaluates parameters // and places the values on the stack // for allow of interruption at any time if ( p != NULL) while ( true ) { pile = pile->AddStack(); // place on the stack for the results if ( pile->GetState() == 0 ) { if (!p->Execute(pile)) return false; // interrupted here? pile->SetState(1); // mark as special for reknowed parameters \TODO marque spéciale pour reconnaîre parameters } ppVars[i++] = pile->GetVar(); p = p->GetNext(); if ( p == NULL) break; } ppVars[i] = NULL; CBotStack* pile2 = pile->AddStack(); if ( pile2->IfStep() ) return false; if ( !pile2->ExecuteCall(m_nFuncIdent, GetToken(), ppVars, m_typRes)) return false; // interrupt return pj->Return(pile2); // release the entire stack }
bool CBotInstrCall::Execute(CBotStack* &pj) { CBotVar* ppVars[1000]; CBotStack* pile = pj->AddStack(this); if ( pile->StackOver() ) return pj->Return( pile ); CBotStack* pile3 = nullptr; if (m_exprRetVar != nullptr) // func().member { pile3 = pile->AddStack2(); if (pile3->GetState() == 1) // function call is done? { if (!m_exprRetVar->Execute(pile3)) return false; return pj->Return(pile3); } } // CBotStack* pile1 = pile; int i = 0; CBotInstr* p = m_parameters; // evaluates parameters // and places the values on the stack // for allow of interruption at any time if ( p != nullptr) while ( true ) { pile = pile->AddStack(); // place on the stack for the results if ( pile->GetState() == 0 ) { if (!p->Execute(pile)) return false; // interrupted here? pile->SetState(1); // set state to remember that parameters were executed } ppVars[i++] = pile->GetVar(); p = p->GetNext(); if ( p == nullptr) break; } ppVars[i] = nullptr; CBotStack* pile2 = pile->AddStack(); if ( pile2->IfStep() ) return false; if ( !pile2->ExecuteCall(m_nFuncIdent, GetToken(), ppVars, m_typRes)) return false; // interrupt if (m_exprRetVar != nullptr) // func().member { pile3->SetCopyVar( pile2->GetVar() ); // copy the result pile2->SetVar(nullptr); pile3->SetState(1); // set call is done return false; // go back to the top ^^^ } return pj->Return(pile2); // release the entire stack }
bool CBotNew::Execute(CBotStack* &pj) { CBotStack* pile = pj->AddStack(this); //main stack if (m_exprRetVar != nullptr) // new Class().method() { if (pile->GetState() == 2) { CBotStack* pile3 = pile->AddStack(); if (!m_exprRetVar->Execute(pile3)) return false; return pj->Return(pile3); } } if (pile->IfStep()) return false; CBotStack* pile1 = pj->AddStack2(); //secondary stack CBotVar* pThis = nullptr; CBotToken* pt = &m_vartoken; CBotClass* pClass = CBotClass::Find(pt); // create the variable "this" pointer type to the stack if ( pile->GetState()==0) { // create an instance of the requested class // and initialize the pointer to that object pThis = CBotVar::Create("this", pClass); pThis->SetUniqNum(-2) ; pile1->SetVar(pThis); // place on stack1 pile->IncState(); } // fetch the this pointer if it was interrupted if ( pThis == nullptr) { pThis = pile1->GetVar(); // find the pointer } // is there an assignment or parameters (constructor) if ( pile->GetState()==1) { // evaluates the constructor of the instance CBotVar* ppVars[1000]; CBotStack* pile2 = pile; int i = 0; CBotInstr* p = m_parameters; // evaluate the parameters // and places the values on the stack // to be interrupted at any time if (p != nullptr) while ( true) { pile2 = pile2->AddStack(); // space on the stack for the result if (pile2->GetState() == 0) { if (!p->Execute(pile2)) return false; // interrupted here? pile2->SetState(1); } ppVars[i++] = pile2->GetVar(); p = p->GetNext(); if ( p == nullptr) break; } ppVars[i] = nullptr; // create a variable for the result CBotVar* pResult = nullptr; // constructos still void if ( !pClass->ExecuteMethode(m_nMethodeIdent, pClass->GetName(), pThis, ppVars, pResult, pile2, GetToken())) return false; // interrupt pThis->ConstructorSet(); // indicates that the constructor has been called } if (m_exprRetVar != nullptr) // new Class().method() { pile->AddStack()->Delete(); // release pile2 stack CBotStack* pile3 = pile->AddStack(); // add new stack pile3->SetCopyVar(pThis); // copy the pointer (from pile1) pile1->Delete(); // release secondary stack(pile1) pile->SetState(2); return false; // go back to the top ^^^ } return pj->Return(pile1); // passes below }
bool CBotDefArray::Execute(CBotStack* &pj) { CBotStack* pile1 = pj->AddStack(this); CBotStack* pile = pile1; if (pile1->GetState() == 0) { // seek the maximum dimension of the table CBotInstr* p = GetNext3b(); // the different formulas int nb = 0; while (p != nullptr) { pile = pile->AddStack(); // little room to work nb++; if (pile->GetState() == 0) { if (!p->Execute(pile)) return false; // size calculation //interrupted? pile->IncState(); } p = p->GetNext3b(); } p = GetNext3b(); pile = pile1; // returns to the stack int n = 0; int max[100]; while (p != nullptr) { pile = pile->AddStack(); CBotVar* v = pile->GetVar(); // result max[n] = v->GetValInt(); // value if (max[n]>MAXARRAYSIZE) { pile->SetError(CBotErrOutArray, &m_token); return pj->Return (pile); } n++; p = p->GetNext3b(); } while (n<100) max[n++] = 0; m_typevar.SetArray(max); // store the limitations // create simply a nullptr pointer CBotVar* var = CBotVar::Create(*(m_var->GetToken()), m_typevar); var->SetPointer(nullptr); var->SetUniqNum((static_cast<CBotLeftExprVar*>(m_var))->m_nIdent); pj->AddVar(var); #if STACKMEM pile1->AddStack()->Delete(); #else delete pile1->AddStack(); // need more indices #endif pile1->IncState(); } if (pile1->GetState() == 1) { if (m_listass != nullptr) // there is the assignment for this table { CBotVar* pVar = pj->FindVar((static_cast<CBotLeftExprVar*>(m_var))->m_nIdent, false); if (!m_listass->Execute(pile1, pVar)) return false; } pile1->IncState(); } if (pile1->IfStep()) return false; if ( m_next2b && !m_next2b->Execute(pile1 )) return false; return pj->Return(pile1); }
int CBotFunction::DoCall(long& nIdent, const char* name, CBotVar* pThis, CBotVar** ppVars, CBotStack* pStack, CBotToken* pToken, CBotClass* pClass) { CBotTypResult type; CBotProgram* pProgCurrent = pStack->GetBotCall(); CBotFunction* pt = FindLocalOrPublic(nIdent, name, ppVars, type, false); if ( pt != NULL ) { // DEBUG( "CBotFunction::DoCall" + pt->GetName(), 0, pStack); CBotStack* pStk = pStack->AddStack(pt, 2); // if ( pStk == EOX ) return true; pStk->SetBotCall(pt->m_pProg); // it may have changed module CBotStack* pStk3 = pStk->AddStack(NULL, true); // to set parameters passed // preparing parameters on the stack if ( pStk->GetState() == 0 ) { // sets the variable "this" on the stack CBotVar* pthis = CBotVar::Create("this", CBotTypNullPointer); pthis->Copy(pThis, false); pthis->SetUniqNum(-2); // special value pStk->AddVar(pthis); CBotClass* pClass = pThis->GetClass()->GetParent(); if ( pClass ) { // sets the variable "super" on the stack CBotVar* psuper = CBotVar::Create("super", CBotTypNullPointer); psuper->Copy(pThis, false); // in fact identical to "this" psuper->SetUniqNum(-3); // special value pStk->AddVar(psuper); } // initializes the variables as parameters pt->m_Param->Execute(ppVars, pStk3); // cannot be interrupted pStk->IncState(); } if ( pStk->GetState() == 1 ) { if ( pt->m_bSynchro ) { CBotProgram* pProgBase = pStk->GetBotCall(true); if ( !pClass->Lock(pProgBase) ) return false; // expected to power \TODO attend de pouvoir } pStk->IncState(); } // finally calls the found function if ( !pStk3->GetRetVar( // puts the result on the stack pt->m_Block->Execute(pStk3) )) // GetRetVar said if it is interrupted { if ( !pStk3->IsOk() ) { if ( pt->m_bSynchro ) { pClass->Unlock(); // release function } if ( pt->m_pProg != pProgCurrent ) { pStk3->SetPosError(pToken); // indicates the error on the procedure call } } return false; // interrupt ! } if ( pt->m_bSynchro ) { pClass->Unlock(); // release function } return pStack->Return( pStk3 ); } return -1; }