/** * checkByRef() returns true if the parameter specified by argNum is pass * by reference, otherwise it returns false. This function may also throw an * UnknownInputException if the reffiness cannot be determined. * * Note that the 'entryArDelta' parameter specifies the delta between sp at * the beginning of the tracelet and ar. */ bool ActRecState::checkByRef(int argNum, int entryArDelta, RefDeps* refDeps) { FTRACE(2, "ActRecState: getting reffiness for arg {}, arDelta {}\n", argNum, entryArDelta); if (m_arStack.empty()) { // The ActRec in question was pushed before the beginning of the // tracelet, so we can make a guess about parameter reffiness and // record our assumptions about parameter reffiness as tracelet // guards. const ActRec* ar = arFromSpOffset((ActRec*)vmsp(), entryArDelta); Record r; r.m_state = State::GUESSABLE; r.m_entryArDelta = entryArDelta; ar->m_func->validate(); r.m_topFunc = ar->m_func; m_arStack.push_back(r); } Record& r = m_arStack.back(); if (r.m_state == State::UNKNOWABLE) { TRACE(2, "ActRecState: unknowable, throwing in the towel\n"); throwUnknownInput(); not_reached(); } assertx(r.m_topFunc); bool retval = r.m_topFunc->byRef(argNum); if (r.m_state == State::GUESSABLE) { assertx(r.m_entryArDelta != InvalidEntryArDelta); TRACE(2, "ActRecState: guessing arg%d -> %d\n", argNum, retval); refDeps->addDep(r.m_entryArDelta, argNum, retval); } return retval; }
/** * checkByRef() returns true if the parameter specified by argNum is pass * by reference, otherwise it returns false. This function may also throw an * UnknownInputException if the reffiness cannot be determined. * * Note that the 'entryArDelta' parameter specifies the delta between sp at * the beginning of the tracelet and ar. */ bool ActRecState::checkByRef(int argNum, int entryArDelta, RefDeps* refDeps, const RegionContext& ctx) { FTRACE(2, "ActRecState: getting reffiness for arg {}, arDelta {}\n", argNum, entryArDelta); if (m_arStack.empty()) { // The ActRec in question was pushed before the beginning of the // tracelet, so we can make a guess about parameter reffiness and // record our assumptions about parameter reffiness as tracelet // guards. auto const func = [&] { for (auto& ar : ctx.preLiveARs) { if (ar.stackOff == entryArDelta) return ar.func; } not_reached(); }(); Record r; r.m_state = State::GUESSABLE; r.m_entryArDelta = entryArDelta; func->validate(); r.m_topFunc = func; m_arStack.push_back(r); } Record& r = m_arStack.back(); if (r.m_state == State::UNKNOWABLE) { TRACE(2, "ActRecState: unknowable, throwing in the towel\n"); throwUnknownInput(); not_reached(); } assertx(r.m_topFunc); bool retval = r.m_topFunc->byRef(argNum); if (r.m_state == State::GUESSABLE) { assertx(r.m_entryArDelta != InvalidEntryArDelta); TRACE(2, "ActRecState: guessing arg%d -> %d\n", argNum, retval); refDeps->addDep(r.m_entryArDelta, argNum, retval); } return retval; }