void Visit(Exp *lval) { // match any access which uses a GC thing type as an rvalue, // including those where the thing is not actually dereferenced. // we are watching not just for direct accesses to the thing, // but to places where it is copied to arguments, a return value, // a variable or heap location. any use of an GC thing pointer // not protected against GC is considered to be an error, and adding // these asserts aggressively lets us discharge reports easier and // generate reports close to the site of the actual problem. if (!lval->IsDrf()) return; ExpDrf *nlval = lval->AsDrf(); Type *type = nlval->GetType(); if (type && type->IsCSU() && TypeIsGCThing(type->AsCSU())) { AssertInfo info; info.kind = ASK_GCSafe; info.cls = ASC_Check; info.point = point; Exp *target = nlval->GetTarget(); if (target->IsFld() && BlockSummary::FieldIsGCSafe(target->AsFld()->GetField())) { info.bit = Bit::MakeConstant(true); } else { Exp *gcsafe = Exp::MakeGCSafe(nlval->GetTarget(), false); info.bit = Bit::MakeVar(gcsafe); } asserts.PushBack(info); } }
void guiyue11() { for (int i = 0; i < 3; i++) { stateStack.pop(); } Element E1, rop, E2; E2 = resultStack.top(); resultStack.pop(); rop = resultStack.top(); resultStack.pop(); E1 = resultStack.top(); resultStack.pop(); vector<Exp> & E1_exps = E1.getSegment(); vector<Exp> & E2_exps = E2.getSegment(); for(int i = 0; i < E2.getLength(); i++) { E1_exps.push_back(E2_exps[i]); } Exp exp; exp.setOpcode("j" + rop.getResult()); exp.setArg1(E1.getResult()); exp.setArg2(E2.getResult()); exp.setResult("1"); E1_exps.push_back(exp); E1.setLength(E1.getLength() + E2.getLength() + 1); printElement(E1); resultStack.push(E1); }
// Substitute s into all members of the set void LocationSet::substitute(Assign& a) { Exp* lhs = a.getLeft(); if (lhs == NULL) return; Exp* rhs = a.getRight(); if (rhs == NULL) return; // ? Will this ever happen? std::set<Exp*, lessExpStar>::iterator it; // Note: it's important not to change the pointer in the set of pointers to expressions, without removing and // inserting again. Otherwise, the set becomes out of order, and operations such as set comparison fail! // To avoid any funny behaviour when iterating the loop, we use the following two sets LocationSet removeSet; // These will be removed after the loop LocationSet removeAndDelete; // These will be removed then deleted LocationSet insertSet; // These will be inserted after the loop bool change; for (it = lset.begin(); it != lset.end(); it++) { Exp* loc = *it; Exp* replace; if (loc->search(lhs, replace)) { if (rhs->isTerminal()) { // This is no longer a location of interest (e.g. %pc) removeSet.insert(loc); continue; } loc = loc->clone()->searchReplaceAll(lhs, rhs, change); if (change) { loc = loc->simplifyArith(); loc = loc->simplify(); // If the result is no longer a register or memory (e.g. // r[28]-4), then delete this expression and insert any // components it uses (in the example, just r[28]) if (!loc->isRegOf() && !loc->isMemOf()) { // Note: can't delete the expression yet, because the // act of insertion into the remove set requires silent // calls to the compare function removeAndDelete.insert(*it); loc->addUsedLocs(insertSet); continue; } // Else we just want to replace it // Regardless of whether the top level expression pointer has // changed, remove and insert it from the set of pointers removeSet.insert(*it); // Note: remove the unmodified ptr insertSet.insert(loc); } } } makeDiff(removeSet); // Remove the items to be removed makeDiff(removeAndDelete); // These are to be removed as well makeUnion(insertSet); // Insert the items to be added // Now delete the expressions that are no longer needed std::set<Exp*, lessExpStar>::iterator dd; for (dd = removeAndDelete.lset.begin(); dd != removeAndDelete.lset.end(); dd++) delete *dd; // Plug that memory leak }
void RemoveValExp(FrameId frame, BlockMemory *mcfg, const GuardExpVector &input, GuardExpVector *output) { for (size_t iind = 0; iind < input.Size(); iind++) { const GuardExp &igt = input[iind]; RemoveFrameMapper mapper(frame); Exp *nexp = igt.exp->DoMap(&mapper); GuardExpVector remove_res; mcfg->TranslateExp(TRK_RemoveVal, 0, nexp, &remove_res); nexp->DecRef(); for (size_t rind = 0; rind < remove_res.Size(); rind++) { const GuardExp &rgt = remove_res[rind]; rgt.IncRef(); igt.guard->IncRef(); Bit *new_guard = Bit::MakeAnd(igt.guard, rgt.guard); output->PushBack(GuardExp(rgt.exp, new_guard)); } } output->SortCombine(); }
void WherePostcondition::PrintUI(OutStream &out) const { PEdge *edge = m_frame->CFG()->GetSingleOutgoingEdge(m_point); Location *loc = m_frame->CFG()->GetPointLocation(m_point); if (edge->IsLoop()) { const char *loop_name = edge->AsLoop()->GetLoopId()->LoopName(); out << "LoopInvariant [" << loop_name << "]"; } else { out << "Postcondition ["; PEdgeCall *nedge = edge->AsCall(); Exp *function = nedge->GetFunction(); function->PrintUI(out, true); out << ":" << loc->Line() << "]"; } if (m_bit) { Bit *new_bit = BitConvertExitClobber(m_bit); out << " :: "; new_bit->PrintUI(out, true); new_bit->DecRef(); } }
inline void output_value_on_line(const std::string& filename, // Domain_<Float, Float, 2>& domain, // Axes aix, Float v, st idx) { //typedef Domain_<Float, Float, 2> Domain; typedef Domain_<Float, Float, 2>::pNode pNode; typedef Interpolate_<Float, Float, 2> Inter; typedef Point_<Float, 2> Point; typedef Expression_<Float, Float,2> Exp; // build an array st n = 300; ArrayListV<Float> arr = Linspace( // domain.grid().min(VerticalAxes2D(aix)), // domain.grid().max(VerticalAxes2D(aix)), n); // Interpolate ArrayListV<Float> arrval(n); std::fstream fss; fss.open(filename, std::fstream::out); for (st i = 0; i < n; ++i) { Point p; p[aix] = v; p[VerticalAxes2D(aix)] = arr[i]; pNode pn = domain.grid().get_pnode(p.x(), p.y()); Exp exp = Inter::OnPlane(pn, _X_, _Y_, p.x(), p.y(), 1); arrval[i] = exp.substitute(idx); fss << arr[i] << " " << arrval[i] << "\n"; } fss.close(); }
/*============================================================================== * FUNCTION: NJMCDecoder::instantiateNamedParam * OVERVIEW: Similarly to the above, given a parameter name and a list of Exp*'s representing sub-parameters, * return a fully substituted Exp for the whole expression * NOTE: Caller must delete result * PARAMETERS: name - parameter name * ... - Exp* representing actual operands * RETURNS: an instantiated list of Exps *============================================================================*/ Exp* NJMCDecoder::instantiateNamedParam(char* name, ...) { if (RTLDict.ParamSet.find(name) == RTLDict.ParamSet.end()) { std::cerr << "No entry for named parameter '" << name << "'\n"; return 0; } assert(RTLDict.DetParamMap.find(name) != RTLDict.DetParamMap.end()); ParamEntry &ent = RTLDict.DetParamMap[name]; if (ent.kind != PARAM_ASGN && ent.kind != PARAM_LAMBDA ) { std::cerr << "Attempt to instantiate expressionless parameter '" << name << "'\n"; return 0; } // Start with the RHS assert(ent.asgn->getKind() == STMT_ASSIGN); Exp* result = ((Assign*)ent.asgn)->getRight()->clone(); va_list args; va_start(args,name); for( std::list<std::string>::iterator it = ent.params.begin(); it != ent.params.end(); it++ ) { Exp* formal = new Location(opParam, new Const((char*)it->c_str()), NULL); Exp* actual = va_arg(args, Exp*); bool change; result = result->searchReplaceAll(formal, actual, change); delete formal; } return result; }
Exp *autoParent() { Exp *current = this; while (current->auto_paren) { current = current->parent(); } if (current==NULL) { return current; } return current->parent(); }
/*============================================================================== * FUNCTION: RtlTest::testIsCompare * OVERVIEW: Test the isCompare function *============================================================================*/ void RtlTest::testIsCompare () { BinaryFileFactory bff; BinaryFile *pBF = bff.Load(SWITCH_SPARC); CPPUNIT_ASSERT(pBF != 0); CPPUNIT_ASSERT(pBF->GetMachine() == MACHINE_SPARC); Prog* prog = new Prog; FrontEnd *pFE = new SparcFrontEnd(pBF, prog, &bff); prog->setFrontEnd(pFE); // Decode second instruction: "sub %i0, 2, %o1" int iReg; Exp* eOperand = NULL; DecodeResult inst = pFE->decodeInstruction(0x10910); CPPUNIT_ASSERT(inst.rtl != NULL); CPPUNIT_ASSERT(inst.rtl->isCompare(iReg, eOperand) == false); // Decode fifth instruction: "cmp %o1, 5" inst = pFE->decodeInstruction(0x1091c); CPPUNIT_ASSERT(inst.rtl != NULL); CPPUNIT_ASSERT(inst.rtl->isCompare(iReg, eOperand) == true); CPPUNIT_ASSERT_EQUAL(9, iReg); std::string expected("5"); std::ostringstream ost1; eOperand->print(ost1); std::string actual(ost1.str()); CPPUNIT_ASSERT_EQUAL(expected, actual); pBF->UnLoad(); delete pBF; delete pFE; pBF = bff.Load(SWITCH_PENT); CPPUNIT_ASSERT(pBF != 0); CPPUNIT_ASSERT(pBF->GetMachine() == MACHINE_PENTIUM); pFE = new PentiumFrontEnd(pBF, prog, &bff); prog->setFrontEnd(pFE); // Decode fifth instruction: "cmp $0x5,%eax" inst = pFE->decodeInstruction(0x80488fb); CPPUNIT_ASSERT(inst.rtl != NULL); CPPUNIT_ASSERT(inst.rtl->isCompare(iReg, eOperand) == true); CPPUNIT_ASSERT_EQUAL(24, iReg); std::ostringstream ost2; eOperand->print(ost2); actual = ost2.str(); CPPUNIT_ASSERT_EQUAL(expected, actual); // Decode instruction: "add $0x4,%esp" inst = pFE->decodeInstruction(0x804890c); CPPUNIT_ASSERT(inst.rtl != NULL); CPPUNIT_ASSERT(inst.rtl->isCompare(iReg, eOperand) == false); pBF->UnLoad(); delete pFE; }
// if exp is a subtraction (exp0 - exp1) and exp1 is an lvalue, return exp1. static inline Exp* GetSubtractedExp(Exp *exp) { ExpBinop *nexp = exp->IfBinop(); if (!nexp) return NULL; BinopKind kind = nexp->GetBinopKind(); if (kind != B_Minus && kind != B_MinusPP) return NULL; Exp *right = nexp->GetRightOperand(); if (right->IsLvalue()) return right; return NULL; }
MM::VOID MM::PoolNodeInstance::initExp(MM::Exp * exp) { if(exp != MM_NULL) { Vector<MM::Exp *> exps; exps.add(exp); MM::PoolNodeInstance * other = MM_NULL; MM::VarExp * varExp = MM_NULL; while(exps.isEmpty() == MM_FALSE) { Exp * curExp = exps.pop(); switch(curExp->getTypeId()) { case MM::T_BinExp: exps.add(((MM::BinExp*)curExp)->getLhsExp()); exps.add(((MM::BinExp*)curExp)->getRhsExp()); break; case MM::T_OverrideExp: exps.add(((MM::OverrideExp*)curExp)->getExp()); break; case MM::T_UnExp: exps.add(((MM::UnExp*)curExp)->getExp()); break; case MM::T_VarExp: varExp = (MM::VarExp *) curExp; other = instance->findPoolNodeInstance(varExp); if(other != MM_NULL) { printf("%lu poolNodeInstance %s observes poolNodeInstance %s %lu\n", this, poolNode->getName()->getBuffer(), other->getNode()->getName()->getBuffer(), other); fflush(stdout); other->addObserver(this); observing->add(other); } else { //TODO: runtime exception printf("Missing poolNodeInstance on expression %s\n", poolNode->getName()->getBuffer()); fflush(stdout); //other = instance->findPoolNodeInstance(varExp); } break; default: break; } } } }
void Constraints::alphaSubst() { std::list<Exp*>::iterator it; for (it = disjunctions.begin(); it != disjunctions.end(); it++) { // This should be a conjuction of terms if (!(*it)->isConjunction()) // A single term will do no good... continue; // Look for a term like alphaX* == fixedType* Exp* temp = (*it)->clone(); Exp* term; bool found = false; Exp* trm1 = NULL; Exp* trm2 = NULL; Type* t1 = NULL, *t2; while ((term = nextConjunct(temp)) != NULL) { if (!term->isEquality()) continue; trm1 = ((Binary*)term)->getSubExp1(); if (!trm1->isTypeVal()) continue; trm2 = ((Binary*)term)->getSubExp2(); if (!trm2->isTypeVal()) continue; // One of them has to be a pointer to an alpha t1 = ((TypeVal*)trm1)->getType(); if (t1->isPointerToAlpha()) { found = true; break; } t2 = ((TypeVal*)trm2)->getType(); if (t2->isPointerToAlpha()) { found = true; break; } } if (!found) continue; // We have a alpha value; get the value Exp* val, *alpha; if (t1->isPointerToAlpha()) { alpha = trm1; val = trm2; } else { val = trm1; alpha = trm2; } // Now substitute bool change; *it = (*it)->searchReplaceAll(alpha, val, change); *it = (*it)->simplifyConstraint(); } }
void guiyue5() { for (int i = 0; i < 6; i++) { stateStack.pop(); } Element B, S1, S2; S2 = resultStack.top(); resultStack.pop(); resultStack.pop(); S1 = resultStack.top(); resultStack.pop(); resultStack.pop(); B = resultStack.top(); resultStack.pop(); resultStack.pop(); printElement(B); cout<<endl; printElement(S1); cout<<endl; printElement(S2); cout<<endl; vector<Exp> & B_exps = B.getSegment(); vector<Exp> & S1_exps = S1.getSegment(); vector<Exp> & S2_exps = S2.getSegment(); string destAddr = ""; char buf[20] = ""; sprintf(buf, "%d", S2.getLength()+2); destAddr.append(buf); B_exps[B_exps.size()-1].setResult(destAddr); for(unsigned i = 0; i < S2_exps.size(); i++) { B_exps.push_back(S2_exps[i]); } Exp exp; exp.setOpcode("j"); exp.setArg1("None"); exp.setArg2("None"); buf[0] = '\0'; sprintf(buf, "%d", S1.getLength()+1); destAddr.clear(); destAddr.append(buf); exp.setResult(destAddr); B_exps.push_back(exp); for(int i = 0; i < S1.getLength(); i++) { B_exps.push_back(S1_exps[i]); } B.setLength(B.getLength()+S1.getLength()+S2.getLength()+1); printElement(B); resultStack.push(B); }
Exp* MatchEquality(Exp *base, const BaseCompare &equality) { Exp *source = equality.source; Exp *target = equality.target; // check for the source and base being the same value. if (source == base) return target; // check for the source and base begin different bounds on the same lvalue. if (source->IsBound() && base->IsBound()) { ExpBound *nsource = source->AsBound(); ExpBound *nbase = base->AsBound(); if (nsource->GetTarget() != nbase->GetTarget()) return NULL; if (nsource->GetBoundKind() != nbase->GetBoundKind()) return NULL; size_t base_width = nbase->GetStrideType()->Width(); size_t source_width = nsource->GetStrideType()->Width(); if (source_width == base_width) return target; // only handling upper bounds where the base's width is an even multiple // of the source's width. this is to handle cases where there is an // equality due to calling a primitive allocation function. if (nbase->GetBoundKind() != BND_Upper) return NULL; if (source_width == 0) return NULL; if (base_width < source_width) return NULL; size_t factor = base_width / source_width; if (source_width * factor != base_width) return NULL; // construct a new equality and recurse on it. the base's bound // can be compared with (target / factor). Exp *factor_exp = Exp::MakeInt(factor); return Exp::MakeBinop(B_Div, target, factor_exp); } return NULL; }
void AST2DotTranslater::visit(SeqExp *exp) { string sseq, sresult; string name = "SeqExp" + getid(); Seq::iterator it = exp->seq->begin(); while (it != exp->seq->end()) { Exp *e = *it; if (e) { e->accept(this); sseq = pop(); sresult += name + " -> " + sseq; } ++it; } push(sresult); }
// Find the first Assignment with loc on the LHS Assignment * StatementList::findOnLeft(Exp *loc) const { for (const auto &s : slist) { auto as = (Assignment *)s; Exp *left = as->getLeft(); if (*left == *loc) return as; if (left->isLocal()) { auto l = (Location *)left; Exp *e = l->getProc()->expFromSymbol(((Const *)l->getSubExp1())->getStr()); if (e && ((*e == *loc) || (e->isSubscript() && *e->getSubExp1() == *loc))) { return as; } } } return nullptr; }
Exp* Parser::exp(){ if (checkToken(Token::BRACKETOPEN) || checkToken(Token::IDENTIFIER) || checkToken(Token::INTEGER) || checkToken(Token::MINUS) || checkToken(Token::EXMARK)) { Exp* myExp = new Exp(); if (error) { return myExp; } myExp->addNode(expII()); if (error) { return myExp; } myExp->addNode(opExp()); return myExp; } else { syntaxError(); } return NULL; }
Exp *GenericExpTransformer::applyTo(Exp *e, bool &bMod) { bool change; Exp *bindings = e->match(match); if (bindings == NULL) { #if 0 if (e->getOper() == match->getOper()) LOG << "match failed: " << e << " with " << match << "\n"; #endif return e; } if (where) { Exp *cond = where->clone(); if (checkCond(cond, bindings) == false) return e; } LOG << "applying generic exp transformer match: " << match; if (where) LOG << " where: " << where; LOG << " become: " << become; LOG << " to: " << e; LOG << " bindings: " << bindings << "\n"; e = become->clone(); for (Exp *l = bindings; l->getOper() != opNil; l = l->getSubExp2()) e = e->searchReplaceAll(l->getSubExp1()->getSubExp1(), l->getSubExp1()->getSubExp2(), change); LOG << "calculated result: " << e << "\n"; bMod = true; Exp *r; if (e->search(new Unary(opVar, new Terminal(opWild)), r)) { LOG << "error: variable " << r << " in result!\n"; assert(false); } return e; }
void AST2DotTranslater::visit(CallExp *exp) { string sfunc, sexps, sresult; string name = "CallExp" + getid(); sfunc = exp->func->name + getid() + ";\n"; sresult = name + " -> " + sfunc; ExpList::iterator it = exp->explist->begin(); while (it != exp->explist->end()) { Exp *e = *it; if (e) { e->accept(this); sexps = pop(); sresult += name + " -> " + sexps; } ++it; } push(sresult); }
//--------------------------------------------------------- void GameObj::Explode() { Exp *e = NULL; switch(m_type) { case OBJ_ASTEROID: case OBJ_SHIP: case OBJ_SAUCER: e = new Exp(this); e->setPosition(getPosition()); Game.PostGameObj(e); break; case OBJ_NONE: case OBJ_BULLET: case OBJ_EXP: case OBJ_POWERUP: default: break; } }
// Find the first Assignment with loc on the LHS Assignment* StatementList::findOnLeft(Exp* loc) { if (slist.size() == 0) return NULL; for (iterator it = slist.begin(); it != slist.end(); it++) { Exp *left = ((Assignment*)*it)->getLeft(); if (*left == *loc) return (Assignment*)*it; if (left->isLocal()) { Location *l = (Location*)left; Exp *e = l->getProc()->expFromSymbol(((Const*)l->getSubExp1())->getStr()); if (e && ((*e == *loc) || (e->isSubscript() && *e->getSubExp1() == *loc))) { return (Assignment*)*it; } } } return NULL; }
void TreePrinter::visit(CALL *call) { FUNCLOG; BGN; result += tab; result += "CALL(\n"; assert(call->func); call->func->accept(this); std::list<Exp*>::iterator it; it = call->args.li.begin(); while (it != call->args.li.end()) { Exp *e = *it; result += ",\n"; assert(e); e->accept(this); ++it; } result += tab; result += ")\n"; END; }
void guiyue4() { for (int i = 0; i < 3; i++) { stateStack.pop(); } Element ret, id, e2, E; E = resultStack.top(); resultStack.pop(); e2 = resultStack.top(); resultStack.pop(); id = resultStack.top(); resultStack.pop(); vector<Exp> & E_exps = E.getSegment(); Exp exp; exp.setOpcode(":="); exp.setArg1(E.getResult()); exp.setArg2("None"); exp.setResult(id.getResult()); E_exps.push_back(exp); E.setLength(E.getLength() + 1); printElement(E); resultStack.push(E); }
bool GetCallMemoryZero(PEdgeCall *edge, Exp **target, Exp **length) { Variable *name = edge->GetDirectFunction(); if (!name) return false; MemsetFunctionInfo *cur_memset = g_memset_functions; while (cur_memset->name) { if (TextNameMatch(name, cur_memset->name)) { // only handling the case where the value argument passed in is zero. if (cur_memset->value_arg < edge->GetArgumentCount()) { Exp *value = edge->GetArgument(cur_memset->value_arg); if (ExpInt *nvalue = value->IfInt()) { long value_int; if (nvalue->GetInt(&value_int) && value_int == 0) { *target = GetArgumentValue(cur_memset->target_arg); *length = GetArgumentValue(cur_memset->length_arg); return true; } } } } cur_memset++; } const char **cur_zero_allocator = g_zero_allocator_functions; while (*cur_zero_allocator) { if (TextNameMatch(name, *cur_zero_allocator)) { Try(GetAllocationFunction(name, target, length)); return true; } cur_zero_allocator++; } return false; }
Exp *ExpTransformer::applyAllTo(Exp *p, bool &bMod) { for (std::list<Exp*>::iterator it = cache.begin(); it != cache.end(); it++) if (*(*it)->getSubExp1() == *p) return (*it)->getSubExp2()->clone(); Exp *e = p->clone(); Exp *subs[3]; subs[0] = e->getSubExp1(); subs[1] = e->getSubExp2(); subs[2] = e->getSubExp3(); for (int i = 0; i < 3; i++) if (subs[i]) { bool mod = false; subs[i] = applyAllTo(subs[i], mod); if (mod && i == 0) e->setSubExp1(subs[i]); if (mod && i == 1) e->setSubExp2(subs[i]); if (mod && i == 2) e->setSubExp3(subs[i]); bMod |= mod; // if (mod) i--; } #if 0 LOG << "applyAllTo called on " << e << "\n"; #endif bool mod; //do { mod = false; for (std::list<ExpTransformer *>::iterator it = transformers.begin(); it != transformers.end(); it++) { e = (*it)->applyTo(e, mod); bMod |= mod; } //} while (mod); cache.push_back(new Binary(opEquals, p->clone(), e->clone())); return e; }
void main() { Exp E; E.read(); cout << E.pow1(E.getN()) << " " << E.pow2(E.getN()) << endl; Arith A; A.read(); A.print(A.getL()); cout << endl; A.printR(A.getL()); cout << endl; cout << A.eval(A.getL()) << endl; }
void guiyue6() { for (int i = 0; i < 4; i++) { stateStack.pop(); } Element B, S; S = resultStack.top(); resultStack.pop(); resultStack.pop(); B = resultStack.top(); resultStack.pop(); resultStack.pop(); vector<Exp> & B_exps = B.getSegment(); vector<Exp> & S_exps = S.getSegment(); B_exps[B_exps.size()-1].setResult("2"); Exp exp; exp.setOpcode("j"); exp.setArg1("None"); exp.setArg2("None"); string destAddr = ""; char buf[20] = ""; sprintf(buf, "%d", S.getLength()+2); destAddr.append(buf); exp.setResult(destAddr); B_exps.push_back(exp); for(int i = 0; i < S.getLength(); i++) { B_exps.push_back(S_exps[i]); } destAddr.clear(); buf[0] = '\0'; sprintf(buf, "%d", -B.getLength() - S.getLength() - 1); destAddr.append(buf); exp.setOpcode("j"); exp.setResult(destAddr); B_exps.push_back(exp); B.setLength(B.getLength() + S.getLength() + 2); printElement(B); resultStack.push(B); }
void DataFlow::convertImplicits(Cfg *cfg) { // Convert statements in A_phi from m[...]{-} to m[...]{0} std::map<Exp *, std::set<int>, lessExpStar> A_phi_copy = A_phi; // Object copy std::map<Exp *, std::set<int>, lessExpStar>::iterator it; ImplicitConverter ic(cfg); A_phi.clear(); for (it = A_phi_copy.begin(); it != A_phi_copy.end(); ++it) { Exp *e = it->first->clone(); e = e->accept(&ic); A_phi[e] = it->second; // Copy the set (doesn't have to be deep) } std::map<Exp *, std::set<int>, lessExpStar> defsites_copy = defsites; // Object copy std::map<Exp *, std::set<int>, lessExpStar>::iterator dd; defsites.clear(); for (dd = A_phi_copy.begin(); dd != A_phi_copy.end(); ++dd) { Exp *e = dd->first->clone(); e = e->accept(&ic); defsites[e] = dd->second; // Copy the set (doesn't have to be deep) } std::vector<std::set<Exp *, lessExpStar> > A_orig_copy; std::vector<std::set<Exp *, lessExpStar> >::iterator oo; A_orig.clear(); for (oo = A_orig_copy.begin(); oo != A_orig_copy.end(); ++oo) { std::set<Exp *, lessExpStar> &se = *oo; std::set<Exp *, lessExpStar> se_new; std::set<Exp *, lessExpStar>::iterator ee; for (ee = se.begin(); ee != se.end(); ++ee) { Exp *e = (*ee)->clone(); e = e->accept(&ic); se_new.insert(e); } A_orig.insert(A_orig.end(), se_new); // Copy the set (doesn't have to be a deep copy) } }
void RunVisitorT<T>::visitprivate(const CallExp &e) { CoverageInstance::invokeAndStartChrono((void*)&e); types::typed_list outTmp; types::typed_list inTmp; std::vector<std::wstring> vectOptName; std::vector<int> vectNbResult; int iRetCount = getExpectedSize(); int iSaveExpectedSize = iRetCount; //get function arguments exps_t args = e.getArgs(); try { for (auto& arg : args) { int iSize = getExpectedSize(); if (arg->isAssignExp()) { AssignExp* pAssign = static_cast<AssignExp*>(arg); //optional parameter Exp* pL = &pAssign->getLeftExp(); if (!pL->isSimpleVar()) { std::wostringstream os; os << _W("left side of optional parameter must be a variable") << std::endl; CoverageInstance::stopChrono((void*)&e); throw ast::InternalError(os.str(), 999, e.getLocation()); } SimpleVar* pVar = pL->getAs<SimpleVar>(); Exp* pR = &pAssign->getRightExp(); // optional parameter have only one output argument setExpectedSize(1); try { pR->accept(*this); } catch (ScilabException &) { CoverageInstance::stopChrono((void*)&e); throw; } setExpectedSize(iSize); types::InternalType* pITR = getResult(); // IncreaseRef to protect opt argument of scope_end delete // It will be deleted by clear_opt pITR->IncreaseRef(); vectOptName.push_back(pVar->getSymbol().getName()); inTmp.push_back(pITR); vectNbResult.push_back(1); clearResult(); continue; } setExpectedSize(-1); try { arg->accept(*this); } catch (ScilabException &) { CoverageInstance::stopChrono((void*)&e); throw; } setExpectedSize(iSize); if (getResult() == NULL) { //special case for empty extraction of list ( list()(:) ) vectNbResult.push_back(0); continue; } if (isSingleResult()) { inTmp.push_back(getResult()); getResult()->IncreaseRef(); } else { for (int i = 0; i < getResultSize(); i++) { types::InternalType * pITArg = getResult(i); pITArg->IncreaseRef(); inTmp.push_back(pITArg); } } vectNbResult.push_back(getResultSize()); clearResult(); } } catch (const InternalError& ie) { clearResult(); cleanIn(inTmp, outTmp); CoverageInstance::stopChrono((void*)&e); throw ie; } // get function/variable try { e.getName().accept(*this); } catch (ScilabException &) { CoverageInstance::stopChrono((void*)&e); throw; } types::InternalType* pIT = getResult(); // pIT can be NULL if one of call return nothing. foo()(1) with foo return nothing. if(pIT == NULL) { clearResult(); std::wostringstream os; os << _W("Cannot extract from nothing.") << std::endl; CoverageInstance::stopChrono((void*)&e); throw ast::InternalError(os.str(), 999, e.getLocation()); } types::typed_list out; types::typed_list in; types::optional_list opt; // manage case [a,b]=foo() where foo is defined as a=foo() if (pIT->getInvokeNbOut() != -1 && pIT->getInvokeNbOut() < iRetCount) { clearResult(); std::wostringstream os; os << _W("Wrong number of output arguments.\n") << std::endl; CoverageInstance::stopChrono((void*)&e); throw ast::InternalError(os.str(), 999, e.getLocation()); } if (pIT->isCallable()) { CoverageInstance::invoke(static_cast<types::Callable *>(pIT)); } // manage input according the function/variable int iLoop = -1; int iterIn = 0; int iterOptName = 0; for (auto& arg : args) { iLoop++; //special case for empty extraction of list ( list()(:) ) if (vectNbResult[iLoop] == 0) { continue; } //extract implicit list for call() if (pIT->isCallable() || pIT->isUserType()) { if (inTmp[iterIn]->isImplicitList()) { types::ImplicitList* pIL = inTmp[iterIn]->getAs<types::ImplicitList>(); if (pIL->isComputable()) { types::InternalType* pITExtract = pIL->extractFullMatrix(); pITExtract->IncreaseRef(); inTmp[iterIn] = pITExtract; pIL->DecreaseRef(); pIL->killMe(); } } } // management of optional input if (arg->isAssignExp()) { if (pIT->hasInvokeOption()) { opt[vectOptName[iterOptName++]] = inTmp[iterIn++]; //in case of macro/macrofile, we have to shift input param //so add NULL item in in list to keep initial order if (pIT->isMacro() || pIT->isMacroFile()) { in.push_back(NULL); } } else { in.push_back(inTmp[iterIn++]); } continue; } // default case for (int i = 0; i < vectNbResult[iLoop]; i++, iterIn++) { in.push_back(inTmp[iterIn]); } } try { // Extraction with a List in input argument. // This extraction must be a recursive extract. int iLoopSize = 1; types::List* pListArg = NULL; if (pIT->isCallable() == false && in.size() == 1 && in[0]->isList()) { pListArg = in[0]->getAs<types::List>(); iLoopSize = pListArg->getSize(); cleanOpt(opt, out); } setExpectedSize(iSaveExpectedSize); iRetCount = std::max(1, iRetCount); for (int i = 0; i < iLoopSize; i++) { if (pListArg) { in[0] = pListArg->get(i); if (in[0]->isList()) { if (pIT->isCallable()) { // list used like "varargin" types::List* pLFuncArgs = in[0]->getAs<types::List>(); types::typed_list input; for (int j = 0; j < pLFuncArgs->getSize(); j++) { input.push_back(pLFuncArgs->get(j)); input.back()->IncreaseRef(); } in = input; } else { pListArg->DecreaseRef(); pListArg->killMe(); std::wostringstream os; os << _W("Invalid index.\n"); throw ast::InternalError(os.str(), 999, e.getFirstLocation()); } } else { in[0]->IncreaseRef(); } } bool ret = false; if (pIT->isInvokable() == false) { // call overload ret = Overload::call(L"%" + pIT->getShortTypeStr() + L"_e", in, iRetCount, out, true); } else { ret = pIT->invoke(in, opt, iRetCount, out, e); if (ret == false && pIT->isUserType()) { // call overload ret = Overload::call(L"%" + pIT->getShortTypeStr() + L"_e", in, iRetCount, out, true); } } if (ret) { if (iSaveExpectedSize != -1 && iSaveExpectedSize > out.size()) { char szError[bsiz]; if (pIT->isCallable()) { char* strFName = wide_string_to_UTF8(pIT->getAs<types::Callable>()->getName().c_str()); os_sprintf(szError, _("%s: Wrong number of output argument(s): %d expected.\n"), strFName, out.size()); FREE(strFName); } else { os_sprintf(szError, _("%s: Wrong number of output argument(s): %d expected.\n"), "extract", out.size()); } wchar_t* wError = to_wide_string(szError); std::wstring err(wError); FREE(wError); throw InternalError(err, 999, e.getLocation()); } setExpectedSize(iSaveExpectedSize); setResult(out); cleanIn(in, out); cleanOpt(opt, out); // In case a.b(), getResult contain pIT ("b"). // If out == pIT, do not delete it. if (getResult() != pIT) { // protect element of out in case where // out contain elements of pIT for (int i = 0; i < out.size(); i++) { out[i]->IncreaseRef(); } pIT->killMe(); // unprotect for (int i = 0; i < out.size(); i++) { out[i]->DecreaseRef(); } } if (pListArg && i + 1 != iLoopSize) { pIT = out[0]; out.clear(); setResult(NULL); } } else { std::wostringstream os; os << _W("Invalid index.\n"); throw ast::InternalError(os.str(), 999, e.getFirstLocation()); } } if (pListArg) { pListArg->DecreaseRef(); pListArg->killMe(); } } catch (InternalAbort & ia) { setExpectedSize(iSaveExpectedSize); if (pIT != getResult()) { pIT->killMe(); } clearResult(); cleanInOut(in, out); cleanOpt(opt, out); CoverageInstance::stopChrono((void*)&e); throw ia; } catch (const InternalError& ie) { setExpectedSize(iSaveExpectedSize); if (pIT != getResult()) { pIT->killMe(); } clearResult(); cleanInOut(in, out); cleanOpt(opt, out); CoverageInstance::stopChrono((void*)&e); throw ie; } CoverageInstance::stopChrono((void*)&e); }
Exp *GenericExpTransformer::applyFuncs(Exp *rhs) { Exp *call, *callw = new Binary(opFlagCall, new Const((char *)"memberAtOffset"), new Terminal(opWild)); if (rhs->search(callw, call)) { assert(call->getSubExp2()->getOper() == opList); Exp *p1 = applyFuncs(call->getSubExp2()->getSubExp1()); Exp *p2 = applyFuncs(call->getSubExp2()->getSubExp2()->getSubExp1()); assert(p1->getOper() == opTypeVal); assert(p2->getOper() == opIntConst); #if 0 Type *ty = p1->getType(); assert(ty && ty->resolvesToCompound()); #else Type *ty = NULL; // Note: will cause a segfault #endif // probably need to make this func take bits in future int offset = ((Const *)p2)->getInt() * 8; const char *member = ty->asCompound()->getNameAtOffset(offset); Exp *result = new Const((char *)member); bool change; rhs = rhs->searchReplace(callw->clone(), result->clone(), change); assert(change); #if 0 LOG << "replaced " << call << " with " << result << "\n"; #endif } callw = new Binary(opFlagCall, new Const((char *)"offsetToMember"), new Terminal(opWild)); if (rhs->search(callw, call)) { assert(call->getSubExp2()->getOper() == opList); Exp *p1 = applyFuncs(call->getSubExp2()->getSubExp1()); Exp *p2 = applyFuncs(call->getSubExp2()->getSubExp2()->getSubExp1()); assert(p1->getOper() == opTypeVal); assert(p2->getOper() == opStrConst); #if 0 // ADHOC TA Type *ty = p1->getType(); assert(ty && ty->resolvesToCompound()); #else Type *ty = NULL; // Note: will cause a segfault #endif char *member = ((Const *)p2)->getStr(); int offset = ty->asCompound()->getOffsetTo(member) / 8; Exp *result = new Const(offset); bool change; rhs = rhs->searchReplace(callw->clone(), result->clone(), change); assert(change); #if 0 LOG << "replaced " << call << " with " << result << "\n"; #endif } callw = new Binary(opFlagCall, new Const((char *)"plus"), new Terminal(opWild)); if (rhs->search(callw, call)) { assert(call->getSubExp2()->getOper() == opList); Exp *p1 = applyFuncs(call->getSubExp2()->getSubExp1()); Exp *p2 = applyFuncs(call->getSubExp2()->getSubExp2()->getSubExp1()); assert(p1->getOper() == opIntConst); assert(p2->getOper() == opIntConst); int a = ((Const *)p1)->getInt(); int b = ((Const *)p2)->getInt(); Exp *result = new Const(a + b); bool change; rhs = rhs->searchReplace(callw->clone(), result->clone(), change); assert(change); #if 0 LOG << "replaced " << call << " with " << result << "\n"; #endif } callw = new Binary(opFlagCall, new Const((char *)"neg"), new Terminal(opWild)); if (rhs->search(callw, call)) { Exp *p1 = applyFuncs(call->getSubExp2()); assert(p1->getOper() == opIntConst); int a = ((Const *)p1)->getInt(); Exp *result = new Const(-a); bool change; rhs = rhs->searchReplace(callw->clone(), result->clone(), change); assert(change); #if 0 LOG << "replaced " << call << " with " << result << "\n"; #endif } return rhs; }