Fix some hhbc verifier bugs
With these changes, we can run HHVM_ALWAYS_VERIFY=1 HHVM_VERIFY_VERBOSE=1 hhvm without crashing.
Esse commit está contido em:
@@ -477,8 +477,10 @@ void Func::prettyPrint(std::ostream& out) const {
|
||||
const ParamInfoVec& params = shared()->m_params;
|
||||
for (uint i = 0; i < params.size(); ++i) {
|
||||
if (params[i].funcletOff() != InvalidAbsoluteOffset) {
|
||||
out << " DV for parameter " << i << " at " << params[i].funcletOff()
|
||||
<< " = " << params[i].phpCode()->data() << std::endl;
|
||||
out << " DV for parameter " << i << " at " << params[i].funcletOff();
|
||||
if (params[i].phpCode()) {
|
||||
out << " = " << params[i].phpCode()->data() << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
const EHEntVec& ehtab = shared()->m_ehtab;
|
||||
|
||||
@@ -118,7 +118,9 @@ class FuncChecker {
|
||||
bool checkFunc(const Func* func, bool verbose) {
|
||||
if (verbose) {
|
||||
func->prettyPrint(std::cout);
|
||||
printf(" FuncId %d\n", func->getFuncId());
|
||||
if (func->cls() || !func->preClass()) {
|
||||
printf(" FuncId %d\n", func->getFuncId());
|
||||
}
|
||||
printFPI(func);
|
||||
}
|
||||
FuncChecker v(func, verbose);
|
||||
@@ -507,6 +509,9 @@ bool FuncChecker::checkImmediates(const char* name, const Opcode* instr) {
|
||||
ok = false;
|
||||
}
|
||||
break;
|
||||
case OpBareThis:
|
||||
if (op > 1) ok = false;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}}
|
||||
@@ -543,7 +548,11 @@ bool FuncChecker::checkSig(PC pc, int len, const FlavorDesc* args,
|
||||
const FlavorDesc* FuncChecker::vectorSig(PC pc, FlavorDesc rhs_flavor) {
|
||||
ImmVecRange vr(pc);
|
||||
int n = 0;
|
||||
if (vr.loc_local != -1) {
|
||||
if (vr.loc_local != -1 ||
|
||||
vr.loc == LH ||
|
||||
vr.loc == LGL ||
|
||||
vr.loc == LNL ||
|
||||
vr.loc == LSL) {
|
||||
/* nothing on stack for loc */
|
||||
} else if (vr.loc == LR) {
|
||||
m_tmp_sig[n++] = RV;
|
||||
@@ -714,6 +723,9 @@ bool FuncChecker::checkIter(State* cur, PC pc) {
|
||||
"IterInit* or MIterInit* <%d> trying to double-initialize\n", id);
|
||||
ok = false;
|
||||
}
|
||||
if (Op(*pc) == OpDecodeCufIter) {
|
||||
cur->iters[id] = true;
|
||||
}
|
||||
} else {
|
||||
if (!cur->iters[id]) {
|
||||
verify_error("Cannot access un-initialized iter %d\n", id);
|
||||
@@ -916,7 +928,7 @@ bool FuncChecker::checkSuccEdges(Block* b, State* cur) {
|
||||
cur->stklen = save_stklen;
|
||||
cur->fpilen = save_fpilen;
|
||||
}
|
||||
if (isIter(b->last)) {
|
||||
if (isIter(b->last) && numSuccBlocks(b) == 2) {
|
||||
// IterInit* and IterNext*, Both implicitly free their iterator variable
|
||||
// on the loop-exit path. Compute the iterator state on the "taken" path;
|
||||
// the fall-through path has the opposite state.
|
||||
@@ -929,7 +941,7 @@ bool FuncChecker::checkSuccEdges(Block* b, State* cur) {
|
||||
cur->iters[id] = taken_state;
|
||||
if (m_verbose) {
|
||||
std::cout << " " << stateToString(*cur) <<
|
||||
" -> B" << b->succs[1]->id << std::endl;
|
||||
" -> B" << b->succs[1]->id << std::endl;
|
||||
}
|
||||
ok &= checkEdge(b, *cur, b->succs[1]);
|
||||
cur->iters[id] = !taken_state;
|
||||
|
||||
Referência em uma Nova Issue
Bloquear um usuário