convert enums to enum classes, part 2
C++11 cleanup (clean up easy enums) Since sandcastle is failing:
Esse commit está contido em:
@@ -1076,12 +1076,12 @@ void MetaInfoBuilder::add(int pos, Unit::MetaInfo::Kind kind,
|
||||
if (mVector) arg |= Unit::MetaInfo::VectorArg;
|
||||
Vec& info = m_metaMap[pos];
|
||||
int i = info.size();
|
||||
if (kind == Unit::MetaInfo::NopOut) {
|
||||
if (kind == Unit::MetaInfo::Kind::NopOut) {
|
||||
info.clear();
|
||||
} else if (i == 1 && info[0].m_kind == Unit::MetaInfo::NopOut) {
|
||||
} else if (i == 1 && info[0].m_kind == Unit::MetaInfo::Kind::NopOut) {
|
||||
return;
|
||||
} else if (kind == Unit::MetaInfo::DataTypeInferred ||
|
||||
kind == Unit::MetaInfo::DataTypePredicted) {
|
||||
} else if (kind == Unit::MetaInfo::Kind::DataTypeInferred ||
|
||||
kind == Unit::MetaInfo::Kind::DataTypePredicted) {
|
||||
// Put DataType first, because if applyInputMetaData saw Class
|
||||
// first, it would call recordRead which mark the input as
|
||||
// needing a guard before we saw the DataType
|
||||
@@ -1097,8 +1097,8 @@ void MetaInfoBuilder::addKnownDataType(DataType dt,
|
||||
int arg) {
|
||||
if (dt != KindOfUnknown) {
|
||||
Unit::MetaInfo::Kind dtKind = (dtPredicted ?
|
||||
Unit::MetaInfo::DataTypePredicted :
|
||||
Unit::MetaInfo::DataTypeInferred);
|
||||
Unit::MetaInfo::Kind::DataTypePredicted :
|
||||
Unit::MetaInfo::Kind::DataTypeInferred);
|
||||
add(pos, dtKind, mVector, arg, dt);
|
||||
}
|
||||
}
|
||||
@@ -1127,7 +1127,7 @@ void MetaInfoBuilder::setForUnit(UnitEmitter& target) const {
|
||||
assert(v.size());
|
||||
for (unsigned i = 0; i < v.size(); i++) {
|
||||
const Unit::MetaInfo& mi = v[i];
|
||||
data.push_back(mi.m_kind);
|
||||
data.push_back(static_cast<uint8_t>(mi.m_kind));
|
||||
data.push_back(mi.m_arg);
|
||||
if (mi.m_data < 0x80) {
|
||||
data.push_back(mi.m_data << 1);
|
||||
@@ -1882,7 +1882,7 @@ void EmitterVisitor::fixReturnType(Emitter& e, FunctionCallPtr fn,
|
||||
/* we dont support V in M-vectors, so leave it as an R in that
|
||||
case */
|
||||
assert(m_evalStack.get(m_evalStack.size() - 1) == StackSym::R);
|
||||
m_metaInfo.add(m_ue.bcPos(), Unit::MetaInfo::NopOut, false, 0, 0);
|
||||
m_metaInfo.add(m_ue.bcPos(), Unit::MetaInfo::Kind::NopOut, false, 0, 0);
|
||||
if (ref) {
|
||||
e.BoxR();
|
||||
} else {
|
||||
@@ -2245,14 +2245,14 @@ bool EmitterVisitor::visitImpl(ConstructPtr node) {
|
||||
}
|
||||
|
||||
if (r->isGuarded()) {
|
||||
m_metaInfo.add(m_ue.bcPos(), Unit::MetaInfo::GuardedThis,
|
||||
m_metaInfo.add(m_ue.bcPos(), Unit::MetaInfo::Kind::GuardedThis,
|
||||
false, 0, 0);
|
||||
}
|
||||
|
||||
// XXX: disabled until static analysis is more reliable: t2225399
|
||||
/*for (auto& l : r->nonRefcountedLocals()) {
|
||||
auto v = m_curFunc->lookupVarId(StringData::GetStaticString(l));
|
||||
m_metaInfo.add(m_ue.bcPos(), Unit::MetaInfo::NonRefCounted,
|
||||
m_metaInfo.add(m_ue.bcPos(), Unit::MetaInfo::Kind::NonRefCounted,
|
||||
false, 0, v);
|
||||
}*/
|
||||
if (retV) {
|
||||
@@ -2633,7 +2633,8 @@ bool EmitterVisitor::visitImpl(ConstructPtr node) {
|
||||
ExpressionListPtr el(static_pointer_cast<ExpressionList>(ex));
|
||||
int capacity = el->getCount();
|
||||
if (capacity > 0) {
|
||||
m_metaInfo.add(m_ue.bcPos(), Unit::MetaInfo::ArrayCapacity,
|
||||
m_metaInfo.add(m_ue.bcPos(),
|
||||
Unit::MetaInfo::Kind::ArrayCapacity,
|
||||
false, 0, capacity);
|
||||
}
|
||||
}
|
||||
@@ -2684,7 +2685,8 @@ bool EmitterVisitor::visitImpl(ConstructPtr node) {
|
||||
{
|
||||
FPIRegionRecorder fpi(this, m_ue, m_evalStack, fpiStart);
|
||||
e.Int(0);
|
||||
m_metaInfo.add(m_ue.bcPos(), Unit::MetaInfo::NopOut, false, 0, 0);
|
||||
m_metaInfo.add(m_ue.bcPos(), Unit::MetaInfo::Kind::NopOut,
|
||||
false, 0, 0);
|
||||
e.FPassC(0);
|
||||
}
|
||||
e.FCall(1);
|
||||
@@ -3086,7 +3088,8 @@ bool EmitterVisitor::visitImpl(ConstructPtr node) {
|
||||
|
||||
if (el->getType() == '`') {
|
||||
emitConvertToCell(e);
|
||||
m_metaInfo.add(m_ue.bcPos(), Unit::MetaInfo::NopOut, false, 0, 0);
|
||||
m_metaInfo.add(m_ue.bcPos(), Unit::MetaInfo::Kind::NopOut,
|
||||
false, 0, 0);
|
||||
e.FPassC(0);
|
||||
delete fpi;
|
||||
e.FCall(1);
|
||||
@@ -3205,7 +3208,8 @@ bool EmitterVisitor::visitImpl(ConstructPtr node) {
|
||||
emitConvertToCell(e);
|
||||
e.False();
|
||||
e.FCallBuiltin(2, 1, s_count);
|
||||
m_metaInfo.add(m_ue.bcPos(), Unit::MetaInfo::NopOut, false, 0, 0);
|
||||
m_metaInfo.add(m_ue.bcPos(), Unit::MetaInfo::Kind::NopOut,
|
||||
false, 0, 0);
|
||||
e.UnboxR();
|
||||
return true;
|
||||
} else if (call->isCallToFunction("func_get_args") &&
|
||||
@@ -3248,7 +3252,8 @@ bool EmitterVisitor::visitImpl(ConstructPtr node) {
|
||||
Id local = m_curFunc->lookupVarId(s_continuationVarArgsLocal);
|
||||
emitVirtualLocal(local);
|
||||
e.FCallBuiltin(0, 0, s_func_get_args);
|
||||
m_metaInfo.add(m_ue.bcPos(), Unit::MetaInfo::NopOut, false, 0, 0);
|
||||
m_metaInfo.add(m_ue.bcPos(), Unit::MetaInfo::Kind::NopOut,
|
||||
false, 0, 0);
|
||||
e.UnboxR();
|
||||
emitSet(e);
|
||||
e.PopC();
|
||||
@@ -3524,7 +3529,7 @@ bool EmitterVisitor::visitImpl(ConstructPtr node) {
|
||||
}
|
||||
if (clsName) {
|
||||
Id id = m_ue.mergeLitstr(clsName);
|
||||
m_metaInfo.add(fpiStart, Unit::MetaInfo::Class, false,
|
||||
m_metaInfo.add(fpiStart, Unit::MetaInfo::Kind::Class, false,
|
||||
useDirectForm ? 0 : 1, id);
|
||||
}
|
||||
{
|
||||
@@ -3549,7 +3554,7 @@ bool EmitterVisitor::visitImpl(ConstructPtr node) {
|
||||
SimpleVariablePtr sv = dynamic_pointer_cast<SimpleVariable>(obj);
|
||||
if (sv && sv->isThis() && sv->hasContext(Expression::ObjectContext)) {
|
||||
if (sv->isGuarded()) {
|
||||
m_metaInfo.add(m_ue.bcPos(), Unit::MetaInfo::GuardedThis,
|
||||
m_metaInfo.add(m_ue.bcPos(), Unit::MetaInfo::Kind::GuardedThis,
|
||||
false, 0, 0);
|
||||
}
|
||||
e.CheckThis();
|
||||
@@ -3659,7 +3664,7 @@ bool EmitterVisitor::visitImpl(ConstructPtr node) {
|
||||
if (sv->isThis()) {
|
||||
if (sv->hasContext(Expression::ObjectContext)) {
|
||||
if (sv->isGuarded()) {
|
||||
m_metaInfo.add(m_ue.bcPos(), Unit::MetaInfo::GuardedThis,
|
||||
m_metaInfo.add(m_ue.bcPos(), Unit::MetaInfo::Kind::GuardedThis,
|
||||
false, 0, 0);
|
||||
}
|
||||
e.This();
|
||||
@@ -3670,7 +3675,7 @@ bool EmitterVisitor::visitImpl(ConstructPtr node) {
|
||||
emitVirtualLocal(thisId);
|
||||
} else {
|
||||
if (sv->isGuarded()) {
|
||||
m_metaInfo.add(m_ue.bcPos(), Unit::MetaInfo::GuardedThis,
|
||||
m_metaInfo.add(m_ue.bcPos(), Unit::MetaInfo::Kind::GuardedThis,
|
||||
false, 0, 0);
|
||||
e.This();
|
||||
} else {
|
||||
@@ -4010,7 +4015,7 @@ void EmitterVisitor::buildVectorImm(std::vector<uchar>& vectorImm,
|
||||
m_ue.bcPos(), true, 0);
|
||||
if (const StringData* cls = m_evalStack.getClsName(iFirst)) {
|
||||
Id id = m_ue.mergeLitstr(cls);
|
||||
m_metaInfo.add(m_ue.bcPos(), Unit::MetaInfo::Class, true, 0, id);
|
||||
m_metaInfo.add(m_ue.bcPos(), Unit::MetaInfo::Kind::Class, true, 0, id);
|
||||
}
|
||||
switch (marker) {
|
||||
case StackSym::N: {
|
||||
@@ -4076,13 +4081,13 @@ void EmitterVisitor::buildVectorImm(std::vector<uchar>& vectorImm,
|
||||
// m-vector later on in this function. Don't duplicate it in the
|
||||
// metadata table.
|
||||
if (symFlavor != StackSym::T) {
|
||||
m_metaInfo.add(m_ue.bcPos(), Unit::MetaInfo::String,
|
||||
m_metaInfo.add(m_ue.bcPos(), Unit::MetaInfo::Kind::String,
|
||||
true, metaI, strid);
|
||||
}
|
||||
}
|
||||
if (const StringData* cls = m_evalStack.getClsName(i)) {
|
||||
const int mcodeNum = i - (iFirst + 1);
|
||||
m_metaInfo.add(m_ue.bcPos(), Unit::MetaInfo::MVecPropClass,
|
||||
m_metaInfo.add(m_ue.bcPos(), Unit::MetaInfo::Kind::MVecPropClass,
|
||||
false, mcodeNum, m_ue.mergeLitstr(cls));
|
||||
}
|
||||
m_metaInfo.addKnownDataType(m_evalStack.getKnownType(i),
|
||||
@@ -4422,13 +4427,13 @@ void EmitterVisitor::emitFuncCallArg(Emitter& e,
|
||||
if (passByRefKind == PassByRefKind::AllowCell ||
|
||||
m_evalStack.get(m_evalStack.size() - 1) != StackSym::C) {
|
||||
emitVGet(e);
|
||||
m_metaInfo.add(m_ue.bcPos(), Unit::MetaInfo::NopOut, false, 0, 0);
|
||||
m_metaInfo.add(m_ue.bcPos(), Unit::MetaInfo::Kind::NopOut, false, 0, 0);
|
||||
e.FPassV(paramId);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
emitCGet(e);
|
||||
m_metaInfo.add(m_ue.bcPos(), Unit::MetaInfo::NopOut, false, 0, 0);
|
||||
m_metaInfo.add(m_ue.bcPos(), Unit::MetaInfo::Kind::NopOut, false, 0, 0);
|
||||
e.FPassC(paramId);
|
||||
return;
|
||||
}
|
||||
@@ -5541,7 +5546,7 @@ void EmitterVisitor::emitPostponedMeths() {
|
||||
e.ContRetC();
|
||||
} else {
|
||||
if ((p.m_meth->getStmts() && p.m_meth->getStmts()->isGuarded())) {
|
||||
m_metaInfo.add(m_ue.bcPos(), Unit::MetaInfo::GuardedThis,
|
||||
m_metaInfo.add(m_ue.bcPos(), Unit::MetaInfo::Kind::GuardedThis,
|
||||
false, 0, 0);
|
||||
}
|
||||
e.RetC();
|
||||
@@ -5563,7 +5568,8 @@ void EmitterVisitor::emitPostponedMeths() {
|
||||
p.m_fe->setParamFuncletOff(paramId, entryPoint.getAbsoluteOffset());
|
||||
}
|
||||
if (!dvInitializers.empty()) {
|
||||
m_metaInfo.add(m_ue.bcPos(), Unit::MetaInfo::NoSurprise, false, 0, 0);
|
||||
m_metaInfo.add(m_ue.bcPos(), Unit::MetaInfo::Kind::NoSurprise,
|
||||
false, 0, 0);
|
||||
e.Jmp(topOfBody);
|
||||
}
|
||||
delete p.m_closureUseVars;
|
||||
@@ -5884,7 +5890,7 @@ bool EmitterVisitor::emitCallUserFunc(Emitter& e, SimpleFunctionCallPtr func) {
|
||||
for (int i = param; i < nParams; i++) {
|
||||
visit((*params)[i]);
|
||||
emitConvertToCell(e);
|
||||
m_metaInfo.add(m_ue.bcPos(), Unit::MetaInfo::NopOut, false, 0, 0);
|
||||
m_metaInfo.add(m_ue.bcPos(), Unit::MetaInfo::Kind::NopOut, false, 0, 0);
|
||||
e.FPassC(i - param);
|
||||
}
|
||||
}
|
||||
@@ -5965,7 +5971,7 @@ void EmitterVisitor::emitFuncCall(Emitter& e, FunctionCallPtr node) {
|
||||
fpiStart = m_ue.bcPos();
|
||||
e.FPushClsMethodD(numParams, nLiteral, cLiteral);
|
||||
if (node->forcedPresent()) {
|
||||
m_metaInfo.add(fpiStart, Unit::MetaInfo::GuardedCls, false, 0, 0);
|
||||
m_metaInfo.add(fpiStart, Unit::MetaInfo::Kind::GuardedCls, false, 0, 0);
|
||||
}
|
||||
} else {
|
||||
emitVirtualClassBase(e, node.get());
|
||||
@@ -6591,7 +6597,7 @@ void EmitterVisitor::emitRestoreErrorReporting(Emitter& e, Id oldLevelLoc) {
|
||||
FPIRegionRecorder fpi(this, m_ue, m_evalStack, fpiStart);
|
||||
emitVirtualLocal(oldLevelLoc);
|
||||
emitCGet(e);
|
||||
m_metaInfo.add(m_ue.bcPos(), Unit::MetaInfo::NopOut, false, 0, 0);
|
||||
m_metaInfo.add(m_ue.bcPos(), Unit::MetaInfo::Kind::NopOut, false, 0, 0);
|
||||
e.FPassC(0);
|
||||
}
|
||||
e.FCall(1);
|
||||
@@ -6608,7 +6614,7 @@ void EmitterVisitor::emitRestoreErrorReporting(Emitter& e, Id oldLevelLoc) {
|
||||
FPIRegionRecorder fpi(this, m_ue, m_evalStack, fpiStart);
|
||||
emitVirtualLocal(oldLevelLoc);
|
||||
emitCGet(e);
|
||||
m_metaInfo.add(m_ue.bcPos(), Unit::MetaInfo::NopOut, false, 0, 0);
|
||||
m_metaInfo.add(m_ue.bcPos(), Unit::MetaInfo::Kind::NopOut, false, 0, 0);
|
||||
e.FPassC(0);
|
||||
}
|
||||
e.FCall(1);
|
||||
@@ -6655,7 +6661,7 @@ void EmitterVisitor::copyOverExnHandlers(FuncEmitter* fe) {
|
||||
for (std::deque<ExnHandlerRegion*>::const_iterator it = m_exnHandlers.begin();
|
||||
it != m_exnHandlers.end(); ++it) {
|
||||
EHEnt& e = fe->addEHEnt();
|
||||
e.m_ehtype = EHEnt::EHType_Catch;
|
||||
e.m_type = EHEnt::Type::Catch;
|
||||
e.m_base = (*it)->m_start;
|
||||
e.m_past = (*it)->m_end;
|
||||
e.m_iterId = -1;
|
||||
@@ -6672,7 +6678,7 @@ void EmitterVisitor::copyOverExnHandlers(FuncEmitter* fe) {
|
||||
|
||||
for (auto& fr : m_faultRegions) {
|
||||
EHEnt& e = fe->addEHEnt();
|
||||
e.m_ehtype = EHEnt::EHType_Fault;
|
||||
e.m_type = EHEnt::Type::Fault;
|
||||
e.m_base = fr->m_start;
|
||||
e.m_past = fr->m_end;
|
||||
e.m_iterId = fr->m_iterId;
|
||||
@@ -6991,7 +6997,7 @@ static void emitContinuationMethod(UnitEmitter& ue, FuncEmitter* fe,
|
||||
ue.emitOp(OpRetC);
|
||||
|
||||
EHEnt& eh = fe->addEHEnt();
|
||||
eh.m_ehtype = EHEnt::EHType_Catch;
|
||||
eh.m_type = EHEnt::Type::Catch;
|
||||
eh.m_base = ehStart;
|
||||
eh.m_past = ue.bcPos();
|
||||
eh.m_catches.push_back(
|
||||
@@ -7291,7 +7297,7 @@ static void batchCommit(std::vector<UnitEmitter*>& ues) {
|
||||
for (std::vector<UnitEmitter*>::const_iterator it = ues.begin();
|
||||
it != ues.end(); ++it) {
|
||||
UnitEmitter* ue = *it;
|
||||
if (repo.insertUnit(ue, UnitOriginFile, txn)) {
|
||||
if (repo.insertUnit(ue, UnitOrigin::File, txn)) {
|
||||
err = true;
|
||||
break;
|
||||
}
|
||||
@@ -7307,7 +7313,7 @@ static void batchCommit(std::vector<UnitEmitter*>& ues) {
|
||||
UnitEmitter* ue = *it;
|
||||
// Commit units individually if an error occurred during batch commit.
|
||||
if (err) {
|
||||
repo.commitUnit(ue, UnitOriginFile);
|
||||
repo.commitUnit(ue, UnitOrigin::File);
|
||||
}
|
||||
delete ue;
|
||||
}
|
||||
@@ -7404,10 +7410,10 @@ Unit* hphp_compiler_parse(const char* code, int codeLen, const MD5& md5,
|
||||
}
|
||||
|
||||
try {
|
||||
UnitOrigin unitOrigin = UnitOriginFile;
|
||||
UnitOrigin unitOrigin = UnitOrigin::File;
|
||||
if (!filename) {
|
||||
filename = "";
|
||||
unitOrigin = UnitOriginEval;
|
||||
unitOrigin = UnitOrigin::Eval;
|
||||
}
|
||||
SCOPE_EXIT { SymbolTable::Purge(); };
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ void ObjectData::destruct() {
|
||||
// case.
|
||||
auto& faults = g_vmContext->m_faults;
|
||||
if (!faults.empty()) {
|
||||
if (faults.back().m_faultType == Fault::CppException) return;
|
||||
if (faults.back().m_faultType == Fault::Type::CppException) return;
|
||||
}
|
||||
// We raise the refcount around the call to __destruct(). This is to
|
||||
// prevent the refcount from going to zero when the destructor returns.
|
||||
|
||||
+21
-21
@@ -1064,7 +1064,7 @@ OpcodeParserMap opcode_parsers;
|
||||
as.enforceStackDepth(0); \
|
||||
} \
|
||||
\
|
||||
if (instrFlags(thisOpcode) & TF) { \
|
||||
if (instrFlags(thisOpcode) & InstrFlags::TF) { \
|
||||
as.enterUnreachableRegion(); \
|
||||
} \
|
||||
}
|
||||
@@ -1181,7 +1181,7 @@ void parse_fault(AsmState& as, int nestLevel) {
|
||||
parse_function_body(as, nestLevel + 1);
|
||||
|
||||
EHEnt& eh = as.fe->addEHEnt();
|
||||
eh.m_ehtype = EHEnt::EHType_Fault;
|
||||
eh.m_type = EHEnt::Type::Fault;
|
||||
eh.m_base = start;
|
||||
eh.m_past = as.ue->bcPos();
|
||||
eh.m_iterId = iterId;
|
||||
@@ -1224,7 +1224,7 @@ void parse_catch(AsmState& as, int nestLevel) {
|
||||
parse_function_body(as, nestLevel + 1);
|
||||
|
||||
EHEnt& eh = as.fe->addEHEnt();
|
||||
eh.m_ehtype = EHEnt::EHType_Catch;
|
||||
eh.m_type = EHEnt::Type::Catch;
|
||||
eh.m_base = start;
|
||||
eh.m_past = as.ue->bcPos();
|
||||
eh.m_iterId = -1;
|
||||
@@ -1302,16 +1302,16 @@ void parse_function_body(AsmState& as, int nestLevel /* = 0 */) {
|
||||
* The `attribute-name' rule is context-sensitive; just look at the
|
||||
* code below.
|
||||
*/
|
||||
enum AttrContext {
|
||||
ClassAttributes,
|
||||
FuncAttributes,
|
||||
PropAttributes,
|
||||
TraitImportAttributes
|
||||
enum class AttrContext {
|
||||
Class,
|
||||
Func,
|
||||
Prop,
|
||||
TraitImport
|
||||
};
|
||||
Attr parse_attribute_list(AsmState& as, AttrContext ctx) {
|
||||
as.in.skipWhitespace();
|
||||
int ret = AttrNone;
|
||||
if (ctx == ClassAttributes || ctx == FuncAttributes) {
|
||||
if (ctx == AttrContext::Class || ctx == AttrContext::Func) {
|
||||
if (!SystemLib::s_inited) {
|
||||
ret |= AttrUnique | AttrPersistent;
|
||||
}
|
||||
@@ -1325,27 +1325,27 @@ Attr parse_attribute_list(AsmState& as, AttrContext ctx) {
|
||||
if (as.in.peek() == ']') break;
|
||||
if (!as.in.readword(word)) break;
|
||||
|
||||
if (ctx == FuncAttributes || ctx == PropAttributes ||
|
||||
ctx == TraitImportAttributes) {
|
||||
if (ctx == AttrContext::Func || ctx == AttrContext::Prop ||
|
||||
ctx == AttrContext::TraitImport) {
|
||||
if (word == "public") { ret |= AttrPublic; continue; }
|
||||
if (word == "protected") { ret |= AttrProtected; continue; }
|
||||
if (word == "private") { ret |= AttrPrivate; continue; }
|
||||
}
|
||||
if (ctx == FuncAttributes || ctx == PropAttributes) {
|
||||
if (ctx == AttrContext::Func || ctx == AttrContext::Prop) {
|
||||
if (word == "static") { ret |= AttrStatic; continue; }
|
||||
}
|
||||
if (ctx == ClassAttributes) {
|
||||
if (ctx == AttrContext::Class) {
|
||||
if (word == "interface") { ret |= AttrInterface; continue; }
|
||||
if (word == "no_expand_trait")
|
||||
{ ret |= AttrNoExpandTrait; continue; }
|
||||
}
|
||||
if (ctx == ClassAttributes || ctx == FuncAttributes ||
|
||||
ctx == TraitImportAttributes) {
|
||||
if (ctx == AttrContext::Class || ctx == AttrContext::Func ||
|
||||
ctx == AttrContext::TraitImport) {
|
||||
if (word == "abstract") { ret |= AttrAbstract; continue; }
|
||||
if (word == "final") { ret |= AttrFinal; continue; }
|
||||
if (word == "no_override") { ret |= AttrNoOverride; continue; }
|
||||
}
|
||||
if (ctx == ClassAttributes || ctx == FuncAttributes) {
|
||||
if (ctx == AttrContext::Class || ctx == AttrContext::Func) {
|
||||
if (word == "trait") { ret |= AttrTrait; continue; }
|
||||
if (word == "unique") { ret |= AttrUnique; continue; }
|
||||
}
|
||||
@@ -1432,7 +1432,7 @@ void parse_function(AsmState& as) {
|
||||
as.error(".function blocks must all follow the .main block");
|
||||
}
|
||||
|
||||
Attr attrs = parse_attribute_list(as, FuncAttributes);
|
||||
Attr attrs = parse_attribute_list(as, AttrContext::Func);
|
||||
std::string name;
|
||||
if (!as.in.readword(name)) {
|
||||
as.error(".function must have a name");
|
||||
@@ -1456,7 +1456,7 @@ void parse_function(AsmState& as) {
|
||||
void parse_method(AsmState& as) {
|
||||
as.in.skipWhitespace();
|
||||
|
||||
Attr attrs = parse_attribute_list(as, FuncAttributes);
|
||||
Attr attrs = parse_attribute_list(as, AttrContext::Func);
|
||||
std::string name;
|
||||
if (!as.in.readword(name)) {
|
||||
as.error(".method requires a method name");
|
||||
@@ -1528,7 +1528,7 @@ TypedValue parse_member_tv_initializer(AsmState& as) {
|
||||
void parse_property(AsmState& as) {
|
||||
as.in.skipWhitespace();
|
||||
|
||||
Attr attrs = parse_attribute_list(as, PropAttributes);
|
||||
Attr attrs = parse_attribute_list(as, AttrContext::Prop);
|
||||
std::string name;
|
||||
if (!as.in.readword(name)) {
|
||||
as.error("expected name for property");
|
||||
@@ -1640,7 +1640,7 @@ void parse_use(AsmState& as) {
|
||||
}
|
||||
|
||||
if (as.in.tryConsume("as")) {
|
||||
Attr attrs = parse_attribute_list(as, TraitImportAttributes);
|
||||
Attr attrs = parse_attribute_list(as, AttrContext::TraitImport);
|
||||
std::string alias;
|
||||
if (!as.in.readword(alias)) {
|
||||
if (attrs != AttrNone) {
|
||||
@@ -1729,7 +1729,7 @@ void parse_class_body(AsmState& as) {
|
||||
void parse_class(AsmState& as) {
|
||||
as.in.skipWhitespace();
|
||||
|
||||
Attr attrs = parse_attribute_list(as, ClassAttributes);
|
||||
Attr attrs = parse_attribute_list(as, AttrContext::Class);
|
||||
std::string name;
|
||||
if (!as.in.readword(name)) {
|
||||
as.error(".class must have a name");
|
||||
|
||||
@@ -39,7 +39,7 @@ TRACE_SET_MOD(gc);
|
||||
|
||||
namespace {
|
||||
|
||||
enum Color {
|
||||
enum class Color {
|
||||
Colorless,
|
||||
Black, // Known to be reachable
|
||||
Garbage // Used for GarbageDetector
|
||||
@@ -79,7 +79,7 @@ struct GCState : private boost::noncopyable {
|
||||
Color setColor(void* vp, Color newColor) {
|
||||
std::pair<ColorMap::iterator,bool> p =
|
||||
m_colorMap.insert(std::make_pair(vp, newColor));
|
||||
Color ret = !p.second ? p.first->second : Colorless;
|
||||
Color ret = !p.second ? p.first->second : Color::Colorless;
|
||||
p.first->second = newColor;
|
||||
return ret;
|
||||
}
|
||||
@@ -315,7 +315,7 @@ struct MarkLive {
|
||||
template<class T>
|
||||
void operator()(T* t) const {
|
||||
++*count_addr(t);
|
||||
if (m_state.setColor(t, Black) == Colorless) {
|
||||
if (m_state.setColor(t, Color::Black) == Color::Colorless) {
|
||||
trace(*this, t);
|
||||
}
|
||||
}
|
||||
@@ -328,7 +328,7 @@ struct ExternalRefRestorer {
|
||||
|
||||
template<class T> void operator()(SmartAllocatorImpl*, T* t) const {
|
||||
if (*count_addr(t) == 0) return;
|
||||
if (m_state.setColor(t, Black) == Colorless) {
|
||||
if (m_state.setColor(t, Color::Black) == Color::Colorless) {
|
||||
trace(MarkLive(m_state), t);
|
||||
}
|
||||
}
|
||||
@@ -409,7 +409,7 @@ struct GarbageDetector {
|
||||
void operator()(SmartAllocatorImpl*, T* t) const {
|
||||
// Check a color flag instead of the count, because we might
|
||||
// increment it before seeing it.
|
||||
if (m_state.setColor(t, Garbage) == Colorless) {
|
||||
if (m_state.setColor(t, Color::Garbage) == Color::Colorless) {
|
||||
m_state.m_cyclicGarbage.insert(make_typed_obj(t));
|
||||
|
||||
/*
|
||||
|
||||
@@ -1637,13 +1637,13 @@ resume:
|
||||
m_faults.pop_back();
|
||||
|
||||
switch (fault.m_faultType) {
|
||||
case Fault::UserException:
|
||||
case Fault::Type::UserException:
|
||||
{
|
||||
Object obj = fault.m_userException;
|
||||
fault.m_userException->decRefCount();
|
||||
throw obj;
|
||||
}
|
||||
case Fault::CppException:
|
||||
case Fault::Type::CppException:
|
||||
// throwException() will take care of deleting heap-allocated
|
||||
// exception object for us
|
||||
fault.m_cppException->throwException();
|
||||
@@ -4096,18 +4096,18 @@ inline void OPTBLD_INLINE VMExecutionContext::iopJmpNZ(PC& pc) {
|
||||
#undef JMPOP
|
||||
#undef JMP_SURPRISE_CHECK
|
||||
|
||||
enum SwitchMatch {
|
||||
MATCH_NORMAL, // value was converted to an int: match normally
|
||||
MATCH_NONZERO, // can't be converted to an int: match first nonzero case
|
||||
MATCH_DEFAULT, // can't be converted to an int: match default case
|
||||
enum class SwitchMatch {
|
||||
NORMAL, // value was converted to an int: match normally
|
||||
NONZERO, // can't be converted to an int: match first nonzero case
|
||||
DEFAULT, // can't be converted to an int: match default case
|
||||
};
|
||||
|
||||
static SwitchMatch doubleCheck(double d, int64_t& out) {
|
||||
if (int64_t(d) == d) {
|
||||
out = d;
|
||||
return MATCH_NORMAL;
|
||||
return SwitchMatch::NORMAL;
|
||||
} else {
|
||||
return MATCH_DEFAULT;
|
||||
return SwitchMatch::DEFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4132,7 +4132,7 @@ inline void OPTBLD_INLINE VMExecutionContext::iopSwitch(PC& pc) {
|
||||
} else {
|
||||
// Generic integer switch
|
||||
int64_t intval;
|
||||
SwitchMatch match = MATCH_NORMAL;
|
||||
SwitchMatch match = SwitchMatch::NORMAL;
|
||||
|
||||
switch (val->m_type) {
|
||||
case KindOfUninit:
|
||||
@@ -4143,7 +4143,7 @@ inline void OPTBLD_INLINE VMExecutionContext::iopSwitch(PC& pc) {
|
||||
case KindOfBoolean:
|
||||
// bool(true) is equal to any non-zero int, bool(false) == 0
|
||||
if (val->m_data.num) {
|
||||
match = MATCH_NONZERO;
|
||||
match = SwitchMatch::NONZERO;
|
||||
} else {
|
||||
intval = 0;
|
||||
}
|
||||
@@ -4182,7 +4182,7 @@ inline void OPTBLD_INLINE VMExecutionContext::iopSwitch(PC& pc) {
|
||||
}
|
||||
|
||||
case KindOfArray:
|
||||
match = MATCH_DEFAULT;
|
||||
match = SwitchMatch::DEFAULT;
|
||||
tvDecRef(val);
|
||||
break;
|
||||
|
||||
@@ -4196,15 +4196,15 @@ inline void OPTBLD_INLINE VMExecutionContext::iopSwitch(PC& pc) {
|
||||
}
|
||||
m_stack.discard();
|
||||
|
||||
if (match != MATCH_NORMAL ||
|
||||
if (match != SwitchMatch::NORMAL ||
|
||||
intval < base || intval >= (base + veclen - 2)) {
|
||||
switch (match) {
|
||||
case MATCH_NORMAL:
|
||||
case MATCH_DEFAULT:
|
||||
case SwitchMatch::NORMAL:
|
||||
case SwitchMatch::DEFAULT:
|
||||
pc = origPC + jmptab[veclen - 1];
|
||||
break;
|
||||
|
||||
case MATCH_NONZERO:
|
||||
case SwitchMatch::NONZERO:
|
||||
pc = origPC + jmptab[veclen - 2];
|
||||
break;
|
||||
}
|
||||
@@ -6581,7 +6581,7 @@ inline void OPTBLD_INLINE VMExecutionContext::iopCatch(PC& pc) {
|
||||
assert(m_faults.size() > 0);
|
||||
Fault fault = m_faults.back();
|
||||
m_faults.pop_back();
|
||||
assert(fault.m_faultType == Fault::UserException);
|
||||
assert(fault.m_faultType == Fault::Type::UserException);
|
||||
m_stack.pushObjectNoRc(fault.m_userException);
|
||||
}
|
||||
|
||||
|
||||
@@ -471,7 +471,7 @@ constexpr int kStackCheckPadding = kStackCheckLeafPadding +
|
||||
kStackCheckReenterPadding;
|
||||
|
||||
struct Fault {
|
||||
enum Type : int16_t {
|
||||
enum class Type : int16_t {
|
||||
UserException,
|
||||
CppException
|
||||
};
|
||||
@@ -487,7 +487,7 @@ struct Fault {
|
||||
};
|
||||
Type m_faultType;
|
||||
|
||||
// During unwinding, this tracks the number of nested EHType_Fault
|
||||
// During unwinding, this tracks the number of nested EHEnt::Fault
|
||||
// regions we've propagated through in a given frame.
|
||||
int16_t m_handledCount;
|
||||
|
||||
|
||||
+14
-14
@@ -720,17 +720,17 @@ bool Class::getInstanceBitMask(const StringData* name,
|
||||
* Being available means that the parent, the interfaces and the traits are
|
||||
* already defined (or become defined via autoload, if tryAutoload is true).
|
||||
*
|
||||
* returns AvailTrue - if it is available
|
||||
* AvailFail - if it is impossible to define the class at this point
|
||||
* AvailFalse- if this particular Class* cant be defined at this point
|
||||
* returns Avail::True - if it is available
|
||||
* Avail::Fail - if it is impossible to define the class at this point
|
||||
* Avail::False- if this particular Class* cant be defined at this point
|
||||
*
|
||||
* Note that AvailFail means that at least one of the parent, interfaces and
|
||||
* traits was not defined at all, while AvailFalse means that at least one
|
||||
* was defined but did not correspond to this Class*
|
||||
* Note that Fail means that at least one of the parent, interfaces and traits
|
||||
* was not defined at all, while False means that at least one was defined but
|
||||
* did not correspond to this Class*
|
||||
*
|
||||
* The parent parameter is used for two purposes: first it avoids looking up the
|
||||
* active parent class for each potential Class*; and second its used on
|
||||
* AvailFail to return the problem class so the caller can report the error
|
||||
* Fail to return the problem class so the caller can report the error
|
||||
* correctly.
|
||||
*/
|
||||
Class::Avail Class::avail(Class*& parent, bool tryAutoload /*=false*/) const {
|
||||
@@ -740,10 +740,10 @@ Class::Avail Class::avail(Class*& parent, bool tryAutoload /*=false*/) const {
|
||||
parent = Unit::getClass(ppcls->namedEntity(), ppcls->name(), tryAutoload);
|
||||
if (!parent) {
|
||||
parent = ourParent;
|
||||
return AvailFail;
|
||||
return Avail::Fail;
|
||||
}
|
||||
}
|
||||
if (parent != ourParent) return AvailFalse;
|
||||
if (parent != ourParent) return Avail::False;
|
||||
}
|
||||
for (size_t i = 0, nInterfaces = m_declInterfaces.size();
|
||||
i < nInterfaces; ++i) {
|
||||
@@ -754,9 +754,9 @@ Class::Avail Class::avail(Class*& parent, bool tryAutoload /*=false*/) const {
|
||||
if (interface != declInterface) {
|
||||
if (interface == nullptr) {
|
||||
parent = declInterface;
|
||||
return AvailFail;
|
||||
return Avail::Fail;
|
||||
}
|
||||
return AvailFalse;
|
||||
return Avail::False;
|
||||
}
|
||||
}
|
||||
for (size_t i = 0; i < m_usedTraits.size(); i++) {
|
||||
@@ -767,12 +767,12 @@ Class::Avail Class::avail(Class*& parent, bool tryAutoload /*=false*/) const {
|
||||
if (trait != usedTrait) {
|
||||
if (trait == nullptr) {
|
||||
parent = usedTrait;
|
||||
return AvailFail;
|
||||
return Avail::Fail;
|
||||
}
|
||||
return AvailFalse;
|
||||
return Avail::False;
|
||||
}
|
||||
}
|
||||
return AvailTrue;
|
||||
return Avail::True;
|
||||
}
|
||||
|
||||
void Class::initialize(TypedValue*& sProps) const {
|
||||
|
||||
@@ -98,7 +98,7 @@ typedef Instance*(*BuiltinCtorFunction)(Class*);
|
||||
*
|
||||
* The very last condition here (parent already defined when the
|
||||
* unit is required) is not known at parse time. This leads to the
|
||||
* MaybeHoistable/AlwaysHoistable split below.
|
||||
* Maybe/Always split below.
|
||||
*
|
||||
*/
|
||||
class PreClass : public AtomicCountable {
|
||||
@@ -556,10 +556,10 @@ public:
|
||||
friend class Instance;
|
||||
friend class Unit;
|
||||
|
||||
enum Avail {
|
||||
AvailFalse,
|
||||
AvailTrue,
|
||||
AvailFail
|
||||
enum class Avail {
|
||||
False,
|
||||
True,
|
||||
Fail
|
||||
};
|
||||
|
||||
struct Prop {
|
||||
|
||||
@@ -90,7 +90,7 @@ void EventHook::RunUserProfiler(const ActRec* ar, int mode) {
|
||||
params.append(s_exit);
|
||||
if (!g_vmContext->m_faults.empty()) {
|
||||
Fault fault = g_vmContext->m_faults.back();
|
||||
if (fault.m_faultType == Fault::UserException) {
|
||||
if (fault.m_faultType == Fault::Type::UserException) {
|
||||
frameinfo.set(s_exception, fault.m_userException);
|
||||
}
|
||||
} else if (!ar->m_func->info() &&
|
||||
|
||||
@@ -307,7 +307,7 @@ bool Func::checkIterScope(Offset o, Id iterId, bool& itRef) const {
|
||||
assert(o >= base() && o < past());
|
||||
for (unsigned i = 0, n = ehtab.size(); i < n; i++) {
|
||||
const EHEnt* eh = &ehtab[i];
|
||||
if (eh->m_ehtype == EHEnt::EHType_Fault &&
|
||||
if (eh->m_type == EHEnt::Type::Fault &&
|
||||
eh->m_base <= o && o < eh->m_past &&
|
||||
eh->m_iterId == iterId) {
|
||||
itRef = eh->m_itRef;
|
||||
@@ -490,7 +490,7 @@ void Func::prettyPrint(std::ostream& out) const {
|
||||
}
|
||||
const EHEntVec& ehtab = shared()->m_ehtab;
|
||||
for (EHEntVec::const_iterator it = ehtab.begin(); it != ehtab.end(); ++it) {
|
||||
bool catcher = it->m_ehtype == EHEnt::EHType_Catch;
|
||||
bool catcher = it->m_type == EHEnt::Type::Catch;
|
||||
out << " EH " << (catcher ? "Catch" : "Fault") << " for " <<
|
||||
it->m_base << ":" << it->m_past;
|
||||
if (it->m_parentIndex != -1) {
|
||||
@@ -846,7 +846,7 @@ struct EHEntComp {
|
||||
bool operator()(const EHEnt& e1, const EHEnt& e2) const {
|
||||
if (e1.m_base == e2.m_base) {
|
||||
if (e1.m_past == e2.m_past) {
|
||||
return e1.m_ehtype == EHEnt::EHType_Catch;
|
||||
return e1.m_type == EHEnt::Type::Catch;
|
||||
}
|
||||
return e1.m_past > e2.m_past;
|
||||
}
|
||||
|
||||
@@ -434,13 +434,13 @@ int instrNumPushes(const Opcode* opcode) {
|
||||
|
||||
StackTransInfo instrStackTransInfo(const Opcode* opcode) {
|
||||
static const StackTransInfo::Kind transKind[] = {
|
||||
#define NOV StackTransInfo::PushPop
|
||||
#define ONE(...) StackTransInfo::PushPop
|
||||
#define TWO(...) StackTransInfo::PushPop
|
||||
#define THREE(...) StackTransInfo::PushPop
|
||||
#define FOUR(...) StackTransInfo::PushPop
|
||||
#define INS_1(...) StackTransInfo::InsertMid
|
||||
#define INS_2(...) StackTransInfo::InsertMid
|
||||
#define NOV StackTransInfo::Kind::PushPop
|
||||
#define ONE(...) StackTransInfo::Kind::PushPop
|
||||
#define TWO(...) StackTransInfo::Kind::PushPop
|
||||
#define THREE(...) StackTransInfo::Kind::PushPop
|
||||
#define FOUR(...) StackTransInfo::Kind::PushPop
|
||||
#define INS_1(...) StackTransInfo::Kind::InsertMid
|
||||
#define INS_2(...) StackTransInfo::Kind::InsertMid
|
||||
#define O(name, imm, pop, push, flags) push,
|
||||
OPCODES
|
||||
#undef NOV
|
||||
@@ -474,12 +474,12 @@ StackTransInfo instrStackTransInfo(const Opcode* opcode) {
|
||||
StackTransInfo ret;
|
||||
ret.kind = transKind[*opcode];
|
||||
switch (ret.kind) {
|
||||
case StackTransInfo::PushPop:
|
||||
case StackTransInfo::Kind::PushPop:
|
||||
ret.pos = 0;
|
||||
ret.numPushes = instrNumPushes(opcode);
|
||||
ret.numPops = instrNumPops(opcode);
|
||||
return ret;
|
||||
case StackTransInfo::InsertMid:
|
||||
case StackTransInfo::Kind::InsertMid:
|
||||
ret.numPops = 0;
|
||||
ret.numPushes = 0;
|
||||
ret.pos = peekPokeType[*opcode];
|
||||
|
||||
@@ -750,7 +750,7 @@ Offset* instrJumpOffset(Opcode* instr);
|
||||
Offset instrJumpTarget(const Opcode* instrs, Offset pos);
|
||||
|
||||
struct StackTransInfo {
|
||||
enum Kind {
|
||||
enum class Kind {
|
||||
PushPop,
|
||||
InsertMid
|
||||
};
|
||||
|
||||
@@ -90,7 +90,7 @@ Instance* Instance::callCustomInstanceInit() {
|
||||
HOT_FUNC_VM
|
||||
Instance* Instance::newInstanceRaw(Class* cls, int idx) {
|
||||
Instance* obj = (Instance*)ALLOCOBJIDX(idx);
|
||||
new (obj) Instance(cls, noinit);
|
||||
new (obj) Instance(cls, NoInit::noinit);
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ class Instance : public ObjectData {
|
||||
instanceInit(cls);
|
||||
}
|
||||
|
||||
enum NoInit { noinit };
|
||||
enum class NoInit { noinit };
|
||||
explicit Instance(Class* cls, NoInit) : ObjectData(false, cls) {}
|
||||
|
||||
public:
|
||||
|
||||
@@ -3608,7 +3608,7 @@ void CodeGenerator::cgCoerceStk(IRInstruction *inst) {
|
||||
}
|
||||
|
||||
auto tmpReg = PhysReg(m_rScratch);
|
||||
cgCallHelper(m_as, tvCoerceHelper, tmpReg, kSyncPoint, args);
|
||||
cgCallHelper(m_as, tvCoerceHelper, tmpReg, SyncOptions::kSyncPoint, args);
|
||||
m_as.testb(1, rbyte(tmpReg));
|
||||
emitFwdJcc(m_as, CC_E, exit);
|
||||
}
|
||||
|
||||
@@ -1291,10 +1291,10 @@ void HhbcTranslator::emitArrayIdx() {
|
||||
TCA opFunc;
|
||||
if (checkForInt) {
|
||||
opFunc = (TCA)&arrayIdxSi;
|
||||
} else if (IntKey == arrayKeyType) {
|
||||
} else if (KeyType::Int == arrayKeyType) {
|
||||
opFunc = (TCA)&arrayIdxI;
|
||||
} else {
|
||||
assert(StrKey == arrayKeyType);
|
||||
assert(KeyType::Str == arrayKeyType);
|
||||
opFunc = (TCA)&arrayIdxS;
|
||||
}
|
||||
|
||||
@@ -3696,14 +3696,14 @@ void HhbcTranslator::checkStrictlyInteger(
|
||||
SSATmp*& key, KeyType& keyType, bool& checkForInt) {
|
||||
checkForInt = false;
|
||||
if (key->isA(Type::Int)) {
|
||||
keyType = IntKey;
|
||||
keyType = KeyType::Int;
|
||||
} else {
|
||||
assert(key->isA(Type::Str));
|
||||
keyType = StrKey;
|
||||
keyType = KeyType::Str;
|
||||
if (key->isConst()) {
|
||||
int64_t i;
|
||||
if (key->getValStr()->isStrictlyInteger(i)) {
|
||||
keyType = IntKey;
|
||||
keyType = KeyType::Int;
|
||||
key = cns(i);
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -1434,11 +1434,11 @@ void Translator::preInputApplyMetaData(Unit::MetaHandle metaHand,
|
||||
Unit::MetaInfo info;
|
||||
while (metaHand.nextArg(info)) {
|
||||
switch (info.m_kind) {
|
||||
case Unit::MetaInfo::NonRefCounted:
|
||||
case Unit::MetaInfo::Kind::NonRefCounted:
|
||||
ni->nonRefCountedLocals.resize(curFunc()->numLocals());
|
||||
ni->nonRefCountedLocals[info.m_data] = 1;
|
||||
break;
|
||||
case Unit::MetaInfo::GuardedThis:
|
||||
case Unit::MetaInfo::Kind::GuardedThis:
|
||||
ni->guardedThis = true;
|
||||
break;
|
||||
default:
|
||||
@@ -1455,7 +1455,7 @@ bool Translator::applyInputMetaData(Unit::MetaHandle& metaHand,
|
||||
|
||||
Unit::MetaInfo info;
|
||||
if (!metaHand.nextArg(info)) return false;
|
||||
if (info.m_kind == Unit::MetaInfo::NopOut) {
|
||||
if (info.m_kind == Unit::MetaInfo::Kind::NopOut) {
|
||||
ni->noOp = true;
|
||||
return true;
|
||||
}
|
||||
@@ -1492,16 +1492,16 @@ bool Translator::applyInputMetaData(Unit::MetaHandle& metaHand,
|
||||
base + (info.m_arg & ~Unit::MetaInfo::VectorArg) : info.m_arg;
|
||||
|
||||
switch (info.m_kind) {
|
||||
case Unit::MetaInfo::NoSurprise:
|
||||
case Unit::MetaInfo::Kind::NoSurprise:
|
||||
ni->noSurprise = true;
|
||||
break;
|
||||
case Unit::MetaInfo::GuardedCls:
|
||||
case Unit::MetaInfo::Kind::GuardedCls:
|
||||
ni->guardedCls = true;
|
||||
break;
|
||||
case Unit::MetaInfo::ArrayCapacity:
|
||||
case Unit::MetaInfo::Kind::ArrayCapacity:
|
||||
ni->imm[0].u_IVA = info.m_data;
|
||||
break;
|
||||
case Unit::MetaInfo::DataTypePredicted: {
|
||||
case Unit::MetaInfo::Kind::DataTypePredicted: {
|
||||
// If the original type was invalid or predicted, then use the
|
||||
// prediction in the meta-data.
|
||||
assert((unsigned) arg < inputInfos.size());
|
||||
@@ -1528,7 +1528,7 @@ bool Translator::applyInputMetaData(Unit::MetaHandle& metaHand,
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Unit::MetaInfo::DataTypeInferred: {
|
||||
case Unit::MetaInfo::Kind::DataTypeInferred: {
|
||||
assert((unsigned)arg < inputInfos.size());
|
||||
SKTRACE(1, ni->source, "MetaInfo DataTypeInferred for input %d; "
|
||||
"newType = %d\n", arg, DataType(info.m_data));
|
||||
@@ -1585,7 +1585,7 @@ bool Translator::applyInputMetaData(Unit::MetaHandle& metaHand,
|
||||
break;
|
||||
}
|
||||
|
||||
case Unit::MetaInfo::String: {
|
||||
case Unit::MetaInfo::Kind::String: {
|
||||
const StringData* sd = ni->unit()->lookupLitstrId(info.m_data);
|
||||
assert((unsigned)arg < inputInfos.size());
|
||||
InputInfo& ii = inputInfos[arg];
|
||||
@@ -1599,7 +1599,7 @@ bool Translator::applyInputMetaData(Unit::MetaHandle& metaHand,
|
||||
break;
|
||||
}
|
||||
|
||||
case Unit::MetaInfo::Class: {
|
||||
case Unit::MetaInfo::Kind::Class: {
|
||||
assert((unsigned)arg < inputInfos.size());
|
||||
InputInfo& ii = inputInfos[arg];
|
||||
DynLocation* dl = tas.recordRead(ii, true);
|
||||
@@ -1632,7 +1632,7 @@ bool Translator::applyInputMetaData(Unit::MetaHandle& metaHand,
|
||||
break;
|
||||
}
|
||||
|
||||
case Unit::MetaInfo::MVecPropClass: {
|
||||
case Unit::MetaInfo::Kind::MVecPropClass: {
|
||||
const StringData* metaName = ni->unit()->lookupLitstrId(info.m_data);
|
||||
Class* metaCls = Unit::lookupUniqueClass(metaName);
|
||||
if (metaCls) {
|
||||
@@ -1641,15 +1641,15 @@ bool Translator::applyInputMetaData(Unit::MetaHandle& metaHand,
|
||||
break;
|
||||
}
|
||||
|
||||
case Unit::MetaInfo::NopOut:
|
||||
case Unit::MetaInfo::Kind::NopOut:
|
||||
// NopOut should always be the first and only annotation
|
||||
// and was handled above.
|
||||
not_reached();
|
||||
|
||||
case Unit::MetaInfo::GuardedThis:
|
||||
case Unit::MetaInfo::NonRefCounted:
|
||||
case Unit::MetaInfo::Kind::GuardedThis:
|
||||
case Unit::MetaInfo::Kind::NonRefCounted:
|
||||
// fallthrough; these are handled in preInputApplyMetaData.
|
||||
case Unit::MetaInfo::None:
|
||||
case Unit::MetaInfo::Kind::None:
|
||||
break;
|
||||
}
|
||||
} while (metaHand.nextArg(info));
|
||||
@@ -3632,7 +3632,7 @@ void Translator::readMetaData(Unit::MetaHandle& handle,
|
||||
|
||||
Unit::MetaInfo info;
|
||||
if (!handle.nextArg(info)) return;
|
||||
if (info.m_kind == Unit::MetaInfo::NopOut) {
|
||||
if (info.m_kind == Unit::MetaInfo::Kind::NopOut) {
|
||||
inst.noOp = true;
|
||||
return;
|
||||
}
|
||||
@@ -3673,16 +3673,16 @@ void Translator::readMetaData(Unit::MetaHandle& handle,
|
||||
};
|
||||
|
||||
switch (info.m_kind) {
|
||||
case Unit::MetaInfo::NoSurprise:
|
||||
case Unit::MetaInfo::Kind::NoSurprise:
|
||||
inst.noSurprise = true;
|
||||
break;
|
||||
case Unit::MetaInfo::GuardedCls:
|
||||
case Unit::MetaInfo::Kind::GuardedCls:
|
||||
inst.guardedCls = true;
|
||||
break;
|
||||
case Unit::MetaInfo::ArrayCapacity:
|
||||
case Unit::MetaInfo::Kind::ArrayCapacity:
|
||||
inst.imm[0].u_IVA = info.m_data;
|
||||
break;
|
||||
case Unit::MetaInfo::DataTypePredicted: {
|
||||
case Unit::MetaInfo::Kind::DataTypePredicted: {
|
||||
auto const& loc = inst.inputs[arg]->location;
|
||||
auto const t = Type::fromDataType(DataType(info.m_data));
|
||||
auto const offset = inst.source.offset();
|
||||
@@ -3695,20 +3695,20 @@ void Translator::readMetaData(Unit::MetaHandle& handle,
|
||||
updateType();
|
||||
break;
|
||||
}
|
||||
case Unit::MetaInfo::DataTypeInferred: {
|
||||
case Unit::MetaInfo::Kind::DataTypeInferred: {
|
||||
m_hhbcTrans->assertTypeLocation(
|
||||
inst.inputs[arg]->location,
|
||||
Type::fromDataType(DataType(info.m_data)));
|
||||
updateType();
|
||||
break;
|
||||
}
|
||||
case Unit::MetaInfo::String: {
|
||||
case Unit::MetaInfo::Kind::String: {
|
||||
m_hhbcTrans->assertString(inst.inputs[arg]->location,
|
||||
inst.unit()->lookupLitstrId(info.m_data));
|
||||
updateType();
|
||||
break;
|
||||
}
|
||||
case Unit::MetaInfo::Class: {
|
||||
case Unit::MetaInfo::Kind::Class: {
|
||||
RuntimeType& rtt = inst.inputs[arg]->rtt;
|
||||
if (rtt.valueType() != KindOfObject) {
|
||||
continue;
|
||||
@@ -3738,7 +3738,7 @@ void Translator::readMetaData(Unit::MetaHandle& handle,
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Unit::MetaInfo::MVecPropClass: {
|
||||
case Unit::MetaInfo::Kind::MVecPropClass: {
|
||||
const StringData* metaName = inst.unit()->lookupLitstrId(info.m_data);
|
||||
Class* metaCls = Unit::lookupUniqueClass(metaName);
|
||||
if (metaCls) {
|
||||
@@ -3746,15 +3746,15 @@ void Translator::readMetaData(Unit::MetaHandle& handle,
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Unit::MetaInfo::NopOut:
|
||||
case Unit::MetaInfo::Kind::NopOut:
|
||||
// NopOut should always be the first and only annotation
|
||||
// and was handled above.
|
||||
not_reached();
|
||||
|
||||
case Unit::MetaInfo::GuardedThis:
|
||||
case Unit::MetaInfo::NonRefCounted:
|
||||
case Unit::MetaInfo::Kind::GuardedThis:
|
||||
case Unit::MetaInfo::Kind::NonRefCounted:
|
||||
// fallthrough; these are handled in preInputApplyMetaData.
|
||||
case Unit::MetaInfo::None:
|
||||
case Unit::MetaInfo::Kind::None:
|
||||
break;
|
||||
}
|
||||
} while (handle.nextArg(info));
|
||||
|
||||
@@ -111,11 +111,11 @@ static KeyType getKeyType(const SSATmp* key, bool nonLitStr,
|
||||
assert(keyType.isKnownDataType() || keyType.equals(Type::Cell));
|
||||
|
||||
if ((key->isConst() || nonLitStr) && key->isString()) {
|
||||
return StrKey;
|
||||
return KeyType::Str;
|
||||
} else if ((key->isConst() || nonLitInt) && key->isA(Type::Int)) {
|
||||
return IntKey;
|
||||
return KeyType::Int;
|
||||
} else {
|
||||
return AnyKey;
|
||||
return KeyType::Any;
|
||||
}
|
||||
}
|
||||
inline static KeyType getKeyType(const SSATmp* key) {
|
||||
@@ -135,7 +135,7 @@ inline static KeyType getKeyTypeIS(const SSATmp* key) {
|
||||
// cleaned up to use the right types: #2174037
|
||||
template<KeyType kt>
|
||||
static inline TypedValue* keyPtr(TypedValue& key) {
|
||||
if (kt == AnyKey) {
|
||||
if (kt == KeyType::Any) {
|
||||
assert(tvIsPlausible(&key));
|
||||
return &key;
|
||||
} else {
|
||||
|
||||
@@ -984,28 +984,28 @@ static inline TypedValue* elemImpl(TypedValue* base, TypedValue keyVal,
|
||||
}
|
||||
|
||||
#define HELPER_TABLE(m) \
|
||||
/* name hot key attrs */ \
|
||||
m(elemC, , AnyKey, None) \
|
||||
m(elemCD, , AnyKey, Define) \
|
||||
m(elemCDR, , AnyKey, DefineReffy) \
|
||||
m(elemCU, , AnyKey, Unset) \
|
||||
m(elemCW, , AnyKey, Warn) \
|
||||
m(elemCWD, , AnyKey, WarnDefine) \
|
||||
m(elemCWDR, , AnyKey, WarnDefineReffy) \
|
||||
m(elemI, , IntKey, None) \
|
||||
m(elemID, HOT_FUNC_VM, IntKey, Define) \
|
||||
m(elemIDR, , IntKey, DefineReffy) \
|
||||
m(elemIU, , IntKey, Unset) \
|
||||
m(elemIW, , IntKey, Warn) \
|
||||
m(elemIWD, , IntKey, WarnDefine) \
|
||||
m(elemIWDR, , IntKey, WarnDefineReffy) \
|
||||
m(elemS, HOT_FUNC_VM, StrKey, None) \
|
||||
m(elemSD, HOT_FUNC_VM, StrKey, Define) \
|
||||
m(elemSDR, , StrKey, DefineReffy) \
|
||||
m(elemSU, , StrKey, Unset) \
|
||||
m(elemSW, HOT_FUNC_VM, StrKey, Warn) \
|
||||
m(elemSWD, , StrKey, WarnDefine) \
|
||||
m(elemSWDR, , StrKey, WarnDefineReffy)
|
||||
/* name hot keyType attrs */ \
|
||||
m(elemC, , KeyType::Any, None) \
|
||||
m(elemCD, , KeyType::Any, Define) \
|
||||
m(elemCDR, , KeyType::Any, DefineReffy) \
|
||||
m(elemCU, , KeyType::Any, Unset) \
|
||||
m(elemCW, , KeyType::Any, Warn) \
|
||||
m(elemCWD, , KeyType::Any, WarnDefine) \
|
||||
m(elemCWDR, , KeyType::Any, WarnDefineReffy) \
|
||||
m(elemI, , KeyType::Int, None) \
|
||||
m(elemID, HOT_FUNC_VM, KeyType::Int, Define) \
|
||||
m(elemIDR, , KeyType::Int, DefineReffy) \
|
||||
m(elemIU, , KeyType::Int, Unset) \
|
||||
m(elemIW, , KeyType::Int, Warn) \
|
||||
m(elemIWD, , KeyType::Int, WarnDefine) \
|
||||
m(elemIWDR, , KeyType::Int, WarnDefineReffy) \
|
||||
m(elemS, HOT_FUNC_VM, KeyType::Str, None) \
|
||||
m(elemSD, HOT_FUNC_VM, KeyType::Str, Define) \
|
||||
m(elemSDR, , KeyType::Str, DefineReffy) \
|
||||
m(elemSU, , KeyType::Str, Unset) \
|
||||
m(elemSW, HOT_FUNC_VM, KeyType::Str, Warn) \
|
||||
m(elemSWD, , KeyType::Str, WarnDefine) \
|
||||
m(elemSWDR, , KeyType::Str, WarnDefineReffy)
|
||||
|
||||
#define ELEM(nm, hot, keyType, attrs) \
|
||||
hot \
|
||||
@@ -1145,11 +1145,11 @@ static inline TypedValue cGetPropImpl(Class* ctx, TypedValue* base,
|
||||
}
|
||||
|
||||
#define HELPER_TABLE(m) \
|
||||
/* name hot key isObj */ \
|
||||
m(cGetPropC, , AnyKey, false) \
|
||||
m(cGetPropCO, , AnyKey, true) \
|
||||
m(cGetPropS, , StrKey, false) \
|
||||
m(cGetPropSO, HOT_FUNC_VM, StrKey, true)
|
||||
/* name hot keyType isObj */ \
|
||||
m(cGetPropC, , KeyType::Any, false) \
|
||||
m(cGetPropCO, , KeyType::Any, true) \
|
||||
m(cGetPropS, , KeyType::Str, false) \
|
||||
m(cGetPropSO, HOT_FUNC_VM, KeyType::Str, true)
|
||||
|
||||
#define PROP(nm, hot, ...) \
|
||||
hot \
|
||||
@@ -1199,12 +1199,12 @@ static inline RefData* vGetPropImpl(Class* ctx, TypedValue* base,
|
||||
return ref;
|
||||
}
|
||||
|
||||
#define HELPER_TABLE(m) \
|
||||
/* name hot key isObj */ \
|
||||
m(vGetPropC, , AnyKey, false) \
|
||||
m(vGetPropCO, , AnyKey, true) \
|
||||
m(vGetPropS, , StrKey, false) \
|
||||
m(vGetPropSO, HOT_FUNC_VM, StrKey, true)
|
||||
#define HELPER_TABLE(m) \
|
||||
/* name hot keyType isObj */\
|
||||
m(vGetPropC, , KeyType::Any, false) \
|
||||
m(vGetPropCO, , KeyType::Any, true) \
|
||||
m(vGetPropS, , KeyType::Str, false) \
|
||||
m(vGetPropSO, HOT_FUNC_VM, KeyType::Str, true)
|
||||
|
||||
#define PROP(nm, hot, ...) \
|
||||
hot \
|
||||
@@ -1486,10 +1486,10 @@ static inline TypedValue arrayGetImpl(
|
||||
}
|
||||
|
||||
#define HELPER_TABLE(m) \
|
||||
/* name hot keyType checkForInt */ \
|
||||
m(arrayGetS, HOT_FUNC_VM, StrKey, false) \
|
||||
m(arrayGetSi, HOT_FUNC_VM, StrKey, true) \
|
||||
m(arrayGetI, HOT_FUNC_VM, IntKey, false)
|
||||
/* name hot keyType checkForInt */\
|
||||
m(arrayGetS, HOT_FUNC_VM, KeyType::Str, false) \
|
||||
m(arrayGetSi, HOT_FUNC_VM, KeyType::Str, true) \
|
||||
m(arrayGetI, HOT_FUNC_VM, KeyType::Int, false)
|
||||
|
||||
#define ELEM(nm, hot, keyType, checkForInt) \
|
||||
hot \
|
||||
@@ -1548,8 +1548,8 @@ static inline TypedValue mapGetImpl(
|
||||
|
||||
#define HELPER_TABLE(m) \
|
||||
/* name hot keyType */ \
|
||||
m(mapGetS, HOT_FUNC_VM, StrKey) \
|
||||
m(mapGetI, HOT_FUNC_VM, IntKey)
|
||||
m(mapGetS, HOT_FUNC_VM, KeyType::Str) \
|
||||
m(mapGetI, HOT_FUNC_VM, KeyType::Int)
|
||||
|
||||
#define ELEM(nm, hot, keyType) \
|
||||
hot \
|
||||
@@ -1563,7 +1563,7 @@ HELPER_TABLE(ELEM)
|
||||
|
||||
void HhbcTranslator::VectorTranslator::emitMapGet(SSATmp* key) {
|
||||
assert(key->isA(Type::Int) || key->isA(Type::Str));
|
||||
KeyType keyType = key->isA(Type::Int) ? IntKey : StrKey;
|
||||
KeyType keyType = key->isA(Type::Int) ? KeyType::Int : KeyType::Str;
|
||||
|
||||
typedef TypedValue (*OpFunc)(c_Map*, TypedValue*);
|
||||
BUILD_OPTAB_HOT(keyType);
|
||||
@@ -1581,9 +1581,9 @@ static inline TypedValue stableMapGetImpl(
|
||||
}
|
||||
|
||||
#define HELPER_TABLE(m) \
|
||||
/* name hot keyType */ \
|
||||
m(stableMapGetS, HOT_FUNC_VM, StrKey) \
|
||||
m(stableMapGetI, HOT_FUNC_VM, IntKey)
|
||||
/* name hot keyType */ \
|
||||
m(stableMapGetS, HOT_FUNC_VM, KeyType::Str) \
|
||||
m(stableMapGetI, HOT_FUNC_VM, KeyType::Int)
|
||||
|
||||
#define ELEM(nm, hot, keyType) \
|
||||
hot \
|
||||
@@ -1597,7 +1597,7 @@ HELPER_TABLE(ELEM)
|
||||
|
||||
void HhbcTranslator::VectorTranslator::emitStableMapGet(SSATmp* key) {
|
||||
assert(key->isA(Type::Int) || key->isA(Type::Str));
|
||||
KeyType keyType = key->isA(Type::Int) ? IntKey : StrKey;
|
||||
KeyType keyType = key->isA(Type::Int) ? KeyType::Int : KeyType::Str;
|
||||
|
||||
typedef TypedValue (*OpFunc)(c_StableMap*, TypedValue*);
|
||||
BUILD_OPTAB_HOT(keyType);
|
||||
@@ -1623,9 +1623,9 @@ static inline TypedValue cGetElemImpl(TypedValue* base, TypedValue keyVal,
|
||||
|
||||
#define HELPER_TABLE(m) \
|
||||
/* name hot key */ \
|
||||
m(cGetElemC, , AnyKey) \
|
||||
m(cGetElemI, , IntKey) \
|
||||
m(cGetElemS, HOT_FUNC_VM, StrKey)
|
||||
m(cGetElemC, , KeyType::Any) \
|
||||
m(cGetElemI, , KeyType::Int) \
|
||||
m(cGetElemS, HOT_FUNC_VM, KeyType::Str)
|
||||
|
||||
#define ELEM(nm, hot, ...) \
|
||||
hot \
|
||||
@@ -1684,9 +1684,9 @@ static inline RefData* vGetElemImpl(TypedValue* base, TypedValue keyVal,
|
||||
|
||||
#define HELPER_TABLE(m) \
|
||||
/* name keyType */ \
|
||||
m(vGetElemC, AnyKey) \
|
||||
m(vGetElemI, IntKey) \
|
||||
m(vGetElemS, StrKey)
|
||||
m(vGetElemC, KeyType::Any) \
|
||||
m(vGetElemI, KeyType::Int) \
|
||||
m(vGetElemS, KeyType::Str)
|
||||
|
||||
#define ELEM(nm, ...) \
|
||||
RefData* nm(TypedValue* base, TypedValue key, MInstrState* mis) { \
|
||||
@@ -1718,13 +1718,13 @@ static inline bool issetEmptyElemImpl(TypedValue* base, TypedValue keyVal,
|
||||
}
|
||||
|
||||
#define HELPER_TABLE(m) \
|
||||
/* name hot keyType isEmpty */ \
|
||||
m(issetElemC, , AnyKey, false) \
|
||||
m(issetElemCE, , AnyKey, true) \
|
||||
m(issetElemI, HOT_FUNC_VM, IntKey, false) \
|
||||
m(issetElemIE, , IntKey, true) \
|
||||
m(issetElemS, HOT_FUNC_VM, StrKey, false) \
|
||||
m(issetElemSE, , StrKey, true)
|
||||
/* name hot keyType isEmpty */\
|
||||
m(issetElemC, , KeyType::Any, false) \
|
||||
m(issetElemCE, , KeyType::Any, true) \
|
||||
m(issetElemI, HOT_FUNC_VM, KeyType::Int, false) \
|
||||
m(issetElemIE, , KeyType::Int, true) \
|
||||
m(issetElemS, HOT_FUNC_VM, KeyType::Str, false) \
|
||||
m(issetElemSE, , KeyType::Str, true)
|
||||
|
||||
#define ISSET(nm, hot, ...) \
|
||||
hot \
|
||||
@@ -1766,10 +1766,10 @@ static inline uint64_t arrayIssetImpl(
|
||||
}
|
||||
|
||||
#define HELPER_TABLE(m) \
|
||||
/* name keyType checkForInt */ \
|
||||
m(arrayIssetS, StrKey, false) \
|
||||
m(arrayIssetSi, StrKey, true) \
|
||||
m(arrayIssetI, IntKey, false)
|
||||
/* name keyType checkForInt */\
|
||||
m(arrayIssetS, KeyType::Str, false) \
|
||||
m(arrayIssetSi, KeyType::Str, true) \
|
||||
m(arrayIssetI, KeyType::Int, false)
|
||||
|
||||
#define ISSET(nm, keyType, checkForInt) \
|
||||
uint64_t nm(ArrayData* a, TypedValue* key) { \
|
||||
@@ -1832,8 +1832,8 @@ static inline uint64_t mapIssetImpl(
|
||||
|
||||
#define HELPER_TABLE(m) \
|
||||
/* name hot keyType */ \
|
||||
m(mapIssetS, HOT_FUNC_VM, StrKey) \
|
||||
m(mapIssetI, HOT_FUNC_VM, IntKey)
|
||||
m(mapIssetS, HOT_FUNC_VM, KeyType::Str) \
|
||||
m(mapIssetI, HOT_FUNC_VM, KeyType::Int)
|
||||
|
||||
#define ELEM(nm, hot, keyType) \
|
||||
hot \
|
||||
@@ -1848,7 +1848,7 @@ HELPER_TABLE(ELEM)
|
||||
void HhbcTranslator::VectorTranslator::emitMapIsset() {
|
||||
SSATmp* key = getKey();
|
||||
assert(key->isA(Type::Int) || key->isA(Type::Str));
|
||||
KeyType keyType = key->isA(Type::Int) ? IntKey : StrKey;
|
||||
KeyType keyType = key->isA(Type::Int) ? KeyType::Int : KeyType::Str;
|
||||
|
||||
typedef TypedValue (*OpFunc)(c_Map*, TypedValue*);
|
||||
BUILD_OPTAB_HOT(keyType);
|
||||
@@ -1864,8 +1864,8 @@ static inline uint64_t stableMapIssetImpl(
|
||||
|
||||
#define HELPER_TABLE(m) \
|
||||
/* name hot keyType */ \
|
||||
m(stableMapIssetS, HOT_FUNC_VM, StrKey) \
|
||||
m(stableMapIssetI, HOT_FUNC_VM, IntKey)
|
||||
m(stableMapIssetS, HOT_FUNC_VM, KeyType::Str) \
|
||||
m(stableMapIssetI, HOT_FUNC_VM, KeyType::Int)
|
||||
|
||||
#define ELEM(nm, hot, keyType) \
|
||||
hot \
|
||||
@@ -1880,7 +1880,7 @@ HELPER_TABLE(ELEM)
|
||||
void HhbcTranslator::VectorTranslator::emitStableMapIsset() {
|
||||
SSATmp* key = getKey();
|
||||
assert(key->isA(Type::Int) || key->isA(Type::Str));
|
||||
KeyType keyType = key->isA(Type::Int) ? IntKey : StrKey;
|
||||
KeyType keyType = key->isA(Type::Int) ? KeyType::Int : KeyType::Str;
|
||||
|
||||
typedef TypedValue (*OpFunc)(c_StableMap*, TypedValue*);
|
||||
BUILD_OPTAB_HOT(keyType);
|
||||
@@ -1932,7 +1932,8 @@ template<KeyType keyType, bool checkForInt, bool setRef>
|
||||
static inline typename ShuffleReturn<setRef>::return_type arraySetImpl(
|
||||
ArrayData* a, typename KeyTypeTraits<keyType>::rawType key,
|
||||
CVarRef value, RefData* ref) {
|
||||
static_assert(keyType != AnyKey, "AnyKey is not supported in arraySetMImpl");
|
||||
static_assert(keyType != KeyType::Any,
|
||||
"KeyType::Any is not supported in arraySetMImpl");
|
||||
const bool copy = a->getCount() > 1;
|
||||
ArrayData* ret = checkForInt ? checkedSet(a, key, value, copy)
|
||||
: a->set(key, value, copy);
|
||||
@@ -1941,13 +1942,13 @@ static inline typename ShuffleReturn<setRef>::return_type arraySetImpl(
|
||||
}
|
||||
|
||||
#define HELPER_TABLE(m) \
|
||||
/* name hot keyType checkForInt setRef */ \
|
||||
m(arraySetS, HOT_FUNC_VM, StrKey, false, false) \
|
||||
m(arraySetSi, HOT_FUNC_VM, StrKey, true, false) \
|
||||
m(arraySetI, HOT_FUNC_VM, IntKey, false, false) \
|
||||
m(arraySetSR, , StrKey, false, true) \
|
||||
m(arraySetSiR, , StrKey, true, true) \
|
||||
m(arraySetIR, , IntKey, false, true)
|
||||
/* name hot keyType checkForInt setRef */ \
|
||||
m(arraySetS, HOT_FUNC_VM, KeyType::Str, false, false) \
|
||||
m(arraySetSi, HOT_FUNC_VM, KeyType::Str, true, false) \
|
||||
m(arraySetI, HOT_FUNC_VM, KeyType::Int, false, false) \
|
||||
m(arraySetSR, , KeyType::Str, false, true) \
|
||||
m(arraySetSiR, , KeyType::Str, true, true) \
|
||||
m(arraySetIR, , KeyType::Int, false, true)
|
||||
|
||||
#define ELEM(nm, hot, keyType, checkForInt, setRef) \
|
||||
hot \
|
||||
@@ -2092,8 +2093,8 @@ static inline void mapSetImpl(
|
||||
|
||||
#define HELPER_TABLE(m) \
|
||||
/* name hot keyType */ \
|
||||
m(mapSetS, HOT_FUNC_VM, StrKey) \
|
||||
m(mapSetI, HOT_FUNC_VM, IntKey)
|
||||
m(mapSetS, HOT_FUNC_VM, KeyType::Str) \
|
||||
m(mapSetI, HOT_FUNC_VM, KeyType::Int)
|
||||
|
||||
#define ELEM(nm, hot, keyType) \
|
||||
hot \
|
||||
@@ -2108,7 +2109,7 @@ HELPER_TABLE(ELEM)
|
||||
void HhbcTranslator::VectorTranslator::emitMapSet(
|
||||
SSATmp* key, SSATmp* value) {
|
||||
assert(key->isA(Type::Int) || key->isA(Type::Str));
|
||||
KeyType keyType = key->isA(Type::Int) ? IntKey : StrKey;
|
||||
KeyType keyType = key->isA(Type::Int) ? KeyType::Int : KeyType::Str;
|
||||
|
||||
typedef TypedValue (*OpFunc)(c_Map*, TypedValue*, TypedValue*);
|
||||
BUILD_OPTAB_HOT(keyType);
|
||||
@@ -2128,8 +2129,8 @@ static inline void stableMapSetImpl(
|
||||
|
||||
#define HELPER_TABLE(m) \
|
||||
/* name hot keyType */ \
|
||||
m(stableMapSetS, HOT_FUNC_VM, StrKey) \
|
||||
m(stableMapSetI, HOT_FUNC_VM, IntKey)
|
||||
m(stableMapSetS, HOT_FUNC_VM, KeyType::Str) \
|
||||
m(stableMapSetI, HOT_FUNC_VM, KeyType::Int)
|
||||
|
||||
#define ELEM(nm, hot, keyType) \
|
||||
hot \
|
||||
@@ -2144,7 +2145,7 @@ HELPER_TABLE(ELEM)
|
||||
void HhbcTranslator::VectorTranslator::emitStableMapSet(
|
||||
SSATmp* key, SSATmp* value) {
|
||||
assert(key->isA(Type::Int) || key->isA(Type::Str));
|
||||
KeyType keyType = key->isA(Type::Int) ? IntKey : StrKey;
|
||||
KeyType keyType = key->isA(Type::Int) ? KeyType::Int : KeyType::Str;
|
||||
|
||||
typedef TypedValue (*OpFunc)(c_StableMap*, TypedValue*, TypedValue*);
|
||||
BUILD_OPTAB_HOT(keyType);
|
||||
@@ -2162,10 +2163,10 @@ static inline StringData* setElemImpl(TypedValue* base, TypedValue keyVal,
|
||||
}
|
||||
|
||||
#define HELPER_TABLE(m) \
|
||||
/* name hot key */ \
|
||||
m(setElemC, , AnyKey) \
|
||||
m(setElemI, , IntKey) \
|
||||
m(setElemS, HOT_FUNC_VM, StrKey)
|
||||
/* name hot keyType */ \
|
||||
m(setElemC, , KeyType::Any) \
|
||||
m(setElemI, , KeyType::Int) \
|
||||
m(setElemS, HOT_FUNC_VM, KeyType::Str)
|
||||
|
||||
#define ELEM(nm, hot, ...) \
|
||||
hot \
|
||||
@@ -2324,9 +2325,9 @@ static inline void unsetElemImpl(TypedValue* base, TypedValue keyVal) {
|
||||
|
||||
#define HELPER_TABLE(m) \
|
||||
/* name hot keyType */ \
|
||||
m(unsetElemC, , AnyKey) \
|
||||
m(unsetElemI, , IntKey) \
|
||||
m(unsetElemS, HOT_FUNC_VM, StrKey)
|
||||
m(unsetElemC, , KeyType::Any) \
|
||||
m(unsetElemI, , KeyType::Int) \
|
||||
m(unsetElemS, HOT_FUNC_VM, KeyType::Str)
|
||||
|
||||
#define ELEM(nm, hot, ...) \
|
||||
hot \
|
||||
|
||||
@@ -59,32 +59,32 @@ const bool MoreWarnings =
|
||||
#endif
|
||||
;
|
||||
|
||||
enum KeyType {
|
||||
AnyKey = 0,
|
||||
StrKey,
|
||||
IntKey,
|
||||
enum class KeyType {
|
||||
Any = 0,
|
||||
Str,
|
||||
Int,
|
||||
};
|
||||
|
||||
template<KeyType kt>
|
||||
struct KeyTypeTraits {};
|
||||
template<> struct KeyTypeTraits<AnyKey> {
|
||||
template<> struct KeyTypeTraits<KeyType::Any> {
|
||||
typedef CVarRef valType;
|
||||
typedef int64_t rawType; // This is never actually used but it's
|
||||
// needed to keep the compiler happy
|
||||
};
|
||||
template<> struct KeyTypeTraits<StrKey> {
|
||||
template<> struct KeyTypeTraits<KeyType::Str> {
|
||||
typedef StrNR valType;
|
||||
typedef StringData* rawType;
|
||||
};
|
||||
template<> struct KeyTypeTraits<IntKey> {
|
||||
template<> struct KeyTypeTraits<KeyType::Int> {
|
||||
typedef int64_t valType;
|
||||
typedef int64_t rawType;
|
||||
};
|
||||
|
||||
inline DataType keyDataType(KeyType t) {
|
||||
if (t == StrKey) {
|
||||
if (t == KeyType::Str) {
|
||||
return KindOfString;
|
||||
} else if (t == IntKey) {
|
||||
} else if (t == KeyType::Int) {
|
||||
return KindOfInt64;
|
||||
} else {
|
||||
not_reached();
|
||||
@@ -94,21 +94,21 @@ inline DataType keyDataType(KeyType t) {
|
||||
template<KeyType kt>
|
||||
inline typename KeyTypeTraits<kt>::valType keyAsValue(TypedValue* key);
|
||||
template<>
|
||||
inline int64_t keyAsValue<IntKey>(TypedValue* key) {
|
||||
inline int64_t keyAsValue<KeyType::Int>(TypedValue* key) {
|
||||
return reinterpret_cast<int64_t>(key);
|
||||
}
|
||||
template<>
|
||||
inline CVarRef keyAsValue<AnyKey>(TypedValue* key) {
|
||||
inline CVarRef keyAsValue<KeyType::Any>(TypedValue* key) {
|
||||
return tvAsCVarRef(key);
|
||||
}
|
||||
template<>
|
||||
inline StrNR keyAsValue<StrKey>(TypedValue* key) {
|
||||
inline StrNR keyAsValue<KeyType::Str>(TypedValue* key) {
|
||||
return StrNR(reinterpret_cast<StringData*>(key));
|
||||
}
|
||||
|
||||
template<KeyType kt>
|
||||
inline typename KeyTypeTraits<kt>::rawType keyAsRaw(TypedValue* key) {
|
||||
if (kt == AnyKey) {
|
||||
if (kt == KeyType::Any) {
|
||||
not_reached();
|
||||
}
|
||||
return reinterpret_cast<typename KeyTypeTraits<kt>::rawType>(key);
|
||||
@@ -118,7 +118,7 @@ inline typename KeyTypeTraits<kt>::rawType keyAsRaw(TypedValue* key) {
|
||||
// and therefore need the key in a TypedValue
|
||||
template<KeyType kt>
|
||||
inline void initScratchKey(TypedValue& tv, TypedValue*& key) {
|
||||
if (kt != AnyKey) {
|
||||
if (kt != KeyType::Any) {
|
||||
tv.m_type = keyDataType(kt);
|
||||
tv.m_data.num = reinterpret_cast<int64_t>(key);
|
||||
key = &tv;
|
||||
@@ -139,11 +139,11 @@ void objOffsetUnset(Instance* base, CVarRef offset);
|
||||
|
||||
StringData* prepareAnyKey(TypedValue* tv);
|
||||
|
||||
template <KeyType keyType = AnyKey>
|
||||
template <KeyType keyType = KeyType::Any>
|
||||
inline StringData* prepareKey(TypedValue* tv) {
|
||||
if (keyType == StrKey) {
|
||||
if (keyType == KeyType::Str) {
|
||||
return reinterpret_cast<StringData*>(tv);
|
||||
} else if (keyType == AnyKey) {
|
||||
} else if (keyType == KeyType::Any) {
|
||||
return prepareAnyKey(tv);
|
||||
} else {
|
||||
not_reached();
|
||||
@@ -152,10 +152,10 @@ inline StringData* prepareKey(TypedValue* tv) {
|
||||
|
||||
template <KeyType keyType>
|
||||
inline void releaseKey(StringData* keySD) {
|
||||
if (keyType == AnyKey) {
|
||||
if (keyType == KeyType::Any) {
|
||||
decRefStr(keySD);
|
||||
} else {
|
||||
assert(keyType == StrKey);
|
||||
assert(keyType == KeyType::Str);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -186,7 +186,7 @@ template <bool warn, KeyType keyType>
|
||||
inline TypedValue* ElemArray(ArrayData* base,
|
||||
TypedValue* key) {
|
||||
TypedValue* result;
|
||||
if (keyType == AnyKey) {
|
||||
if (keyType == KeyType::Any) {
|
||||
DataType rtt = key->m_type;
|
||||
if (rtt == KindOfInt64) {
|
||||
result = ElemArrayRawKey(base, key->m_data.num);
|
||||
@@ -213,7 +213,7 @@ inline TypedValue* ElemArray(ArrayData* base,
|
||||
}
|
||||
|
||||
// $result = $base[$key];
|
||||
template <bool warn, KeyType keyType = AnyKey>
|
||||
template <bool warn, KeyType keyType = KeyType::Any>
|
||||
inline TypedValue* Elem(TypedValue& tvScratch, TypedValue& tvRef,
|
||||
TypedValue* base, TypedValue* key) {
|
||||
TypedValue* result;
|
||||
@@ -241,9 +241,9 @@ inline TypedValue* Elem(TypedValue& tvScratch, TypedValue& tvRef,
|
||||
case KindOfStaticString:
|
||||
case KindOfString: {
|
||||
int64_t x;
|
||||
if (keyType == IntKey) {
|
||||
if (keyType == KeyType::Int) {
|
||||
x = reinterpret_cast<int64_t>(key);
|
||||
} else if (keyType == StrKey) {
|
||||
} else if (keyType == KeyType::Str) {
|
||||
x = reinterpret_cast<StringData*>(key)->toInt64(10);
|
||||
} else if (LIKELY(IS_INT_TYPE(key->m_type))) {
|
||||
x = key->m_data.num;
|
||||
@@ -296,7 +296,7 @@ inline TypedValue* ElemDArray(TypedValue* base, TypedValue* key) {
|
||||
bool defined = !warn ||
|
||||
tvAsCVarRef(base).asCArrRef().exists(keyAsValue<keyType>(key));
|
||||
|
||||
if (keyType == AnyKey && key->m_type == KindOfInt64) {
|
||||
if (keyType == KeyType::Any && key->m_type == KindOfInt64) {
|
||||
result = (TypedValue*)&tvAsVariant(base).asArrRef()
|
||||
.lvalAt(key->m_data.num);
|
||||
} else {
|
||||
@@ -320,7 +320,7 @@ inline TypedValue* ElemDArray(TypedValue* base, TypedValue* key) {
|
||||
// \____ ____/
|
||||
// v
|
||||
// $result
|
||||
template <bool warn, bool reffy, KeyType keyType = AnyKey>
|
||||
template <bool warn, bool reffy, KeyType keyType = KeyType::Any>
|
||||
inline TypedValue* ElemD(TypedValue& tvScratch, TypedValue& tvRef,
|
||||
TypedValue* base, TypedValue* key) {
|
||||
TypedValue scratch;
|
||||
@@ -411,7 +411,7 @@ inline TypedValue* ElemD(TypedValue& tvScratch, TypedValue& tvRef,
|
||||
// \____ ____/
|
||||
// v
|
||||
// $result
|
||||
template <KeyType keyType = AnyKey>
|
||||
template <KeyType keyType = KeyType::Any>
|
||||
inline TypedValue* ElemU(TypedValue& tvScratch, TypedValue& tvRef,
|
||||
TypedValue* base, TypedValue* key) {
|
||||
TypedValue* result = nullptr;
|
||||
@@ -437,7 +437,7 @@ inline TypedValue* ElemU(TypedValue& tvScratch, TypedValue& tvRef,
|
||||
bool defined =
|
||||
tvAsCVarRef(base).asCArrRef().exists(keyAsValue<keyType>(key));
|
||||
if (defined) {
|
||||
if (keyType == AnyKey && key->m_type == KindOfInt64) {
|
||||
if (keyType == KeyType::Any && key->m_type == KindOfInt64) {
|
||||
result = (TypedValue*)&tvAsVariant(base).asArrRef()
|
||||
.lvalAt(key->m_data.num);
|
||||
} else {
|
||||
@@ -614,7 +614,7 @@ inline void SetElemArray(TypedValue* base, TypedValue* key,
|
||||
bool copy = (a->getCount() > 1)
|
||||
|| (value->m_type == KindOfArray && value->m_data.parr == a);
|
||||
|
||||
if (keyType != AnyKey) {
|
||||
if (keyType != KeyType::Any) {
|
||||
newData = SetElemArrayRawKey(a, keyAsRaw<keyType>(key), value, copy);
|
||||
} else if (key->m_type <= KindOfNull) {
|
||||
newData = a->set(empty_string, tvCellAsCVarRef(value), copy);
|
||||
@@ -650,14 +650,14 @@ inline int64_t castKeyToInt(TypedValue* key) {
|
||||
}
|
||||
|
||||
template<>
|
||||
inline int64_t castKeyToInt<IntKey>(TypedValue* key) {
|
||||
return keyAsRaw<IntKey>(key);
|
||||
inline int64_t castKeyToInt<KeyType::Int>(TypedValue* key) {
|
||||
return keyAsRaw<KeyType::Int>(key);
|
||||
}
|
||||
|
||||
// SetElem() leaves the result in 'value', rather than returning it as in
|
||||
// SetOpElem(), because doing so avoids a dup operation that SetOpElem() can't
|
||||
// get around.
|
||||
template <bool setResult, KeyType keyType = AnyKey>
|
||||
template <bool setResult, KeyType keyType = KeyType::Any>
|
||||
inline StringData* SetElem(TypedValue* base, TypedValue* key, Cell* value) {
|
||||
TypedValue scratch;
|
||||
DataType type;
|
||||
@@ -866,7 +866,7 @@ inline TypedValue* SetOpElemNumberish(TypedValue& tvScratch) {
|
||||
return &tvScratch;
|
||||
}
|
||||
|
||||
template <KeyType keyType = AnyKey>
|
||||
template <KeyType keyType = KeyType::Any>
|
||||
inline TypedValue* SetOpElem(TypedValue& tvScratch, TypedValue& tvRef,
|
||||
unsigned char op, TypedValue* base,
|
||||
TypedValue* key, Cell* rhs) {
|
||||
@@ -1100,7 +1100,7 @@ inline void IncDecElemNumberish(TypedValue& dest) {
|
||||
tvWriteNull(&dest);
|
||||
}
|
||||
}
|
||||
template <bool setResult, KeyType keyType = AnyKey>
|
||||
template <bool setResult, KeyType keyType = KeyType::Any>
|
||||
inline void IncDecElem(TypedValue& tvScratch, TypedValue& tvRef,
|
||||
unsigned char op, TypedValue* base,
|
||||
TypedValue* key, TypedValue& dest) {
|
||||
@@ -1245,7 +1245,7 @@ inline void UnsetElemArray(TypedValue* base, TypedValue* key) {
|
||||
ArrayData* a = base->m_data.parr;
|
||||
ArrayData* a2;
|
||||
bool copy = a->getCount() > 1;
|
||||
if (keyType == AnyKey) {
|
||||
if (keyType == KeyType::Any) {
|
||||
if (IS_STRING_TYPE(key->m_type)) {
|
||||
a2 = UnsetElemArrayRawKey(a, key->m_data.pstr, copy);
|
||||
} else if (key->m_type == KindOfInt64) {
|
||||
@@ -1267,7 +1267,7 @@ inline void UnsetElemArray(TypedValue* base, TypedValue* key) {
|
||||
}
|
||||
}
|
||||
|
||||
template <KeyType keyType = AnyKey>
|
||||
template <KeyType keyType = KeyType::Any>
|
||||
inline void UnsetElem(TypedValue* base, TypedValue* member) {
|
||||
TypedValue scratch;
|
||||
DataType type;
|
||||
@@ -1370,10 +1370,11 @@ inline DataType propPre(TypedValue& tvScratch, TypedValue*& result,
|
||||
// v
|
||||
// $result
|
||||
template <bool warn, bool define, bool unset, bool baseIsObj = false,
|
||||
KeyType keyType = AnyKey>
|
||||
KeyType keyType = KeyType::Any>
|
||||
inline TypedValue* Prop(TypedValue& tvScratch, TypedValue& tvRef,
|
||||
Class* ctx, TypedValue* base, TypedValue* key) {
|
||||
static_assert(keyType != IntKey, "Integer property keys are not supported");
|
||||
static_assert(keyType != KeyType::Int,
|
||||
"Integer property keys are not supported");
|
||||
assert(!warn || !unset);
|
||||
TypedValue* result = nullptr;
|
||||
StringData* keySD = nullptr;
|
||||
@@ -1420,7 +1421,7 @@ inline bool IssetEmptyElemObj(TypedValue& tvRef, Instance* instance,
|
||||
}
|
||||
}
|
||||
|
||||
template <bool useEmpty, bool isObj = false, KeyType keyType = AnyKey>
|
||||
template <bool useEmpty, bool isObj = false, KeyType keyType = KeyType::Any>
|
||||
inline bool IssetEmptyElem(TypedValue& tvScratch, TypedValue& tvRef,
|
||||
TypedValue* base,
|
||||
TypedValue* key) {
|
||||
@@ -1489,7 +1490,7 @@ inline bool IssetEmptyPropObj(Class* ctx, Instance* instance,
|
||||
return issetEmptyResult;
|
||||
}
|
||||
|
||||
template <bool useEmpty, bool isObj = false, KeyType keyType = AnyKey>
|
||||
template <bool useEmpty, bool isObj = false, KeyType keyType = KeyType::Any>
|
||||
inline bool IssetEmptyProp(Class* ctx, TypedValue* base,
|
||||
TypedValue* key) {
|
||||
if (isObj) {
|
||||
@@ -1543,7 +1544,7 @@ inline void SetPropObj(Class* ctx, Instance* instance,
|
||||
}
|
||||
|
||||
// $base->$key = $val
|
||||
template <bool setResult, bool isObj = false, KeyType keyType = AnyKey>
|
||||
template <bool setResult, bool isObj = false, KeyType keyType = KeyType::Any>
|
||||
inline void SetProp(Class* ctx, TypedValue* base, TypedValue* key,
|
||||
Cell* val) {
|
||||
if (isObj) {
|
||||
@@ -1626,7 +1627,7 @@ inline TypedValue* SetOpPropObj(TypedValue& tvRef, Class* ctx,
|
||||
}
|
||||
|
||||
// $base->$key <op>= $rhs
|
||||
template<bool isObj = false, KeyType keyType = AnyKey>
|
||||
template<bool isObj = false, KeyType keyType = KeyType::Any>
|
||||
inline TypedValue* SetOpProp(TypedValue& tvScratch, TypedValue& tvRef,
|
||||
Class* ctx, unsigned char op,
|
||||
TypedValue* base, TypedValue* key,
|
||||
@@ -1723,7 +1724,7 @@ inline void IncDecPropObj(TypedValue& tvRef, Class* ctx,
|
||||
releaseKey<keyType>(keySD);
|
||||
}
|
||||
|
||||
template <bool setResult, bool isObj = false, KeyType keyType = AnyKey>
|
||||
template <bool setResult, bool isObj = false, KeyType keyType = KeyType::Any>
|
||||
inline void IncDecProp(TypedValue& tvScratch, TypedValue& tvRef,
|
||||
Class* ctx, unsigned char op,
|
||||
TypedValue* base, TypedValue* key,
|
||||
@@ -1776,7 +1777,7 @@ inline void IncDecProp(TypedValue& tvScratch, TypedValue& tvRef,
|
||||
}
|
||||
}
|
||||
|
||||
template<bool isObj = false, KeyType keyType = AnyKey>
|
||||
template<bool isObj = false, KeyType keyType = KeyType::Any>
|
||||
inline void UnsetProp(Class* ctx, TypedValue* base,
|
||||
TypedValue* key) {
|
||||
Instance* instance;
|
||||
|
||||
@@ -51,9 +51,9 @@ class Repo : public RepoProxy {
|
||||
sqlite3* dbc() const { return m_dbc; }
|
||||
int repoIdForNewUnit(UnitOrigin unitOrigin) const {
|
||||
switch (unitOrigin) {
|
||||
case UnitOriginFile:
|
||||
case UnitOrigin::File:
|
||||
return m_localWritable ? RepoIdLocal : RepoIdCentral;
|
||||
case UnitOriginEval:
|
||||
case UnitOrigin::Eval:
|
||||
return m_evalRepoId;
|
||||
default:
|
||||
assert(false);
|
||||
|
||||
@@ -40,23 +40,35 @@ void TypeConstraint::init() {
|
||||
const StringData* name;
|
||||
Type type;
|
||||
} pairs[] = {
|
||||
{ StringData::GetStaticString("bool"), { KindOfBoolean, Precise }},
|
||||
{ StringData::GetStaticString("boolean"), { KindOfBoolean, Precise }},
|
||||
{ StringData::GetStaticString("bool"), { KindOfBoolean,
|
||||
MetaType::Precise }},
|
||||
{ StringData::GetStaticString("boolean"), { KindOfBoolean,
|
||||
MetaType::Precise }},
|
||||
|
||||
{ StringData::GetStaticString("int"), { KindOfInt64, Precise }},
|
||||
{ StringData::GetStaticString("integer"), { KindOfInt64, Precise }},
|
||||
{ StringData::GetStaticString("int"), { KindOfInt64,
|
||||
MetaType::Precise }},
|
||||
{ StringData::GetStaticString("integer"), { KindOfInt64,
|
||||
MetaType::Precise }},
|
||||
|
||||
{ StringData::GetStaticString("real"), { KindOfDouble, Precise }},
|
||||
{ StringData::GetStaticString("double"), { KindOfDouble, Precise }},
|
||||
{ StringData::GetStaticString("float"), { KindOfDouble, Precise }},
|
||||
{ StringData::GetStaticString("real"), { KindOfDouble,
|
||||
MetaType::Precise }},
|
||||
{ StringData::GetStaticString("double"), { KindOfDouble,
|
||||
MetaType::Precise }},
|
||||
{ StringData::GetStaticString("float"), { KindOfDouble,
|
||||
MetaType::Precise }},
|
||||
|
||||
{ StringData::GetStaticString("string"), { KindOfString, Precise }},
|
||||
{ StringData::GetStaticString("string"), { KindOfString,
|
||||
MetaType::Precise }},
|
||||
|
||||
{ StringData::GetStaticString("array"), { KindOfArray, Precise }},
|
||||
{ StringData::GetStaticString("array"), { KindOfArray,
|
||||
MetaType::Precise }},
|
||||
|
||||
{ StringData::GetStaticString("self"), { KindOfObject, Self }},
|
||||
{ StringData::GetStaticString("parent"), { KindOfObject, Parent }},
|
||||
{ StringData::GetStaticString("callable"), { KindOfObject, Callable }},
|
||||
{ StringData::GetStaticString("self"), { KindOfObject,
|
||||
MetaType::Self }},
|
||||
{ StringData::GetStaticString("parent"), { KindOfObject,
|
||||
MetaType::Parent }},
|
||||
{ StringData::GetStaticString("callable"), { KindOfObject,
|
||||
MetaType::Callable }},
|
||||
};
|
||||
for (unsigned i = 0; i < sizeof(pairs) / sizeof(Pair); ++i) {
|
||||
s_typeNamesToTypes[pairs[i].name] = pairs[i].type;
|
||||
@@ -65,7 +77,7 @@ void TypeConstraint::init() {
|
||||
|
||||
if (typeName == nullptr) {
|
||||
m_type.m_dt = KindOfInvalid;
|
||||
m_type.m_metatype = Precise;
|
||||
m_type.m_metatype = MetaType::Precise;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -77,7 +89,7 @@ void TypeConstraint::init() {
|
||||
dtype.isSelf())) {
|
||||
TRACE(5, "TypeConstraint: this %p no such type %s, treating as object\n",
|
||||
this, typeName->data());
|
||||
m_type = { KindOfObject, Precise };
|
||||
m_type = { KindOfObject, MetaType::Precise };
|
||||
m_namedEntity = Unit::GetNamedEntity(typeName);
|
||||
TRACE(5, "TypeConstraint: NamedEntity: %p\n", m_namedEntity);
|
||||
return;
|
||||
|
||||
@@ -37,7 +37,7 @@ public:
|
||||
};
|
||||
|
||||
protected:
|
||||
enum MetaType {
|
||||
enum class MetaType {
|
||||
Precise,
|
||||
Self,
|
||||
Parent,
|
||||
@@ -48,16 +48,16 @@ protected:
|
||||
DataType m_dt;
|
||||
MetaType m_metatype;
|
||||
constexpr bool isParent() const {
|
||||
return m_metatype == Parent;
|
||||
return m_metatype == MetaType::Parent;
|
||||
}
|
||||
constexpr bool isSelf() const {
|
||||
return m_metatype == Self;
|
||||
return m_metatype == MetaType::Self;
|
||||
}
|
||||
constexpr bool isCallable() const {
|
||||
return m_metatype == Callable;
|
||||
return m_metatype == MetaType::Callable;
|
||||
}
|
||||
constexpr bool isPrecise() const {
|
||||
return m_metatype == Precise;
|
||||
return m_metatype == MetaType::Precise;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -184,7 +184,7 @@ void profileRequestEnd() {
|
||||
numRequests++; // racy RMW; ok to miss a rare few.
|
||||
}
|
||||
|
||||
enum KeyToVPMode {
|
||||
enum class KeyToVPMode {
|
||||
Read, Write
|
||||
};
|
||||
|
||||
@@ -211,12 +211,12 @@ keyToVP(TypeProfileKey key, KeyToVPMode mode) {
|
||||
l[i].m_tag, key.m_name->data(), uint32_t(h));
|
||||
return &l[i];
|
||||
}
|
||||
if (mode == Write && l[i].m_totalSamples < minCount) {
|
||||
if (mode == KeyToVPMode::Write && l[i].m_totalSamples < minCount) {
|
||||
replaceCandidate = i;
|
||||
minCount = l[i].m_totalSamples;
|
||||
}
|
||||
}
|
||||
if (mode == Write) {
|
||||
if (mode == KeyToVPMode::Write) {
|
||||
assert(replaceCandidate >= 0 && replaceCandidate < kLineSize);
|
||||
ValueProfile& vp = l[replaceCandidate];
|
||||
Stats::inc(Stats::TypePred_Evict, vp.m_totalSamples != 0);
|
||||
@@ -242,7 +242,7 @@ void recordType(TypeProfileKey key, DataType dt) {
|
||||
// Normalize strings to KindOfString.
|
||||
if (dt == KindOfStaticString) dt = KindOfString;
|
||||
TRACE(1, "recordType lookup: %s -> %d\n", key.m_name->data(), dt);
|
||||
ValueProfile *prof = keyToVP(key, Write);
|
||||
ValueProfile *prof = keyToVP(key, KeyToVPMode::Write);
|
||||
if (prof->m_totalSamples != kMaxCounter) {
|
||||
prof->m_totalSamples++;
|
||||
// NB: we can't quite assert that we have fewer than kMaxCounter samples,
|
||||
@@ -260,7 +260,7 @@ typedef std::pair<DataType, double> PredVal;
|
||||
PredVal predictType(TypeProfileKey key) {
|
||||
PredVal kNullPred = std::make_pair(KindOfUninit, 0.0);
|
||||
if (!profiles) return kNullPred;
|
||||
const ValueProfile *prof = keyToVP(key, Read);
|
||||
const ValueProfile *prof = keyToVP(key, KeyToVPMode::Read);
|
||||
if (!prof) {
|
||||
TRACE(2, "predictType lookup: %s -> MISS\n", key.m_name->data());
|
||||
Stats::inc(Stats::TypePred_Miss);
|
||||
|
||||
+18
-18
@@ -557,19 +557,19 @@ Class* Unit::defClass(const PreClass* preClass,
|
||||
if (class_->preClass() != preClass) continue;
|
||||
|
||||
Class::Avail avail = class_->avail(parent, failIsFatal /*tryAutoload*/);
|
||||
if (LIKELY(avail == Class::AvailTrue)) {
|
||||
if (LIKELY(avail == Class::Avail::True)) {
|
||||
class_->setCached();
|
||||
DEBUGGER_ATTACHED_ONLY(phpDebuggerDefClassHook(class_));
|
||||
return class_;
|
||||
}
|
||||
if (avail == Class::AvailFail) {
|
||||
if (avail == Class::Avail::Fail) {
|
||||
if (failIsFatal) {
|
||||
FrameRestore fr(preClass);
|
||||
raise_error("unknown class %s", parent->name()->data());
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
assert(avail == Class::AvailFalse);
|
||||
assert(avail == Class::Avail::False);
|
||||
}
|
||||
|
||||
// Create a new class.
|
||||
@@ -1319,10 +1319,10 @@ void Unit::mergeImpl(void* tcbase, UnitMergeInfo* mi) {
|
||||
Stats::inc(Stats::UnitMerge_mergeable_unique_persistent_cache);
|
||||
}
|
||||
Class::Avail avail = cls->avail(other, true);
|
||||
if (UNLIKELY(avail == Class::AvailFail)) {
|
||||
if (UNLIKELY(avail == Class::Avail::Fail)) {
|
||||
raise_error("unknown class %s", other->name()->data());
|
||||
}
|
||||
assert(avail == Class::AvailTrue);
|
||||
assert(avail == Class::Avail::True);
|
||||
getDataRef<Class*>(tcbase, cls->m_cachedOffset) = cls;
|
||||
if (debugger) phpDebuggerDefClassHook(cls);
|
||||
obj = mi->mergeableObj(++ix);
|
||||
@@ -1585,48 +1585,48 @@ void Unit::prettyPrint(std::ostream& out, PrintOpts opts) const {
|
||||
int arg = info.m_arg & ~MetaInfo::VectorArg;
|
||||
const char *argKind = info.m_arg & MetaInfo::VectorArg ? "M" : "";
|
||||
switch (info.m_kind) {
|
||||
case Unit::MetaInfo::DataTypeInferred:
|
||||
case Unit::MetaInfo::DataTypePredicted:
|
||||
case Unit::MetaInfo::Kind::DataTypeInferred:
|
||||
case Unit::MetaInfo::Kind::DataTypePredicted:
|
||||
out << " i" << argKind << arg << ":t=" << (int)info.m_data;
|
||||
if (info.m_kind == Unit::MetaInfo::DataTypePredicted) {
|
||||
if (info.m_kind == Unit::MetaInfo::Kind::DataTypePredicted) {
|
||||
out << "*";
|
||||
}
|
||||
break;
|
||||
case Unit::MetaInfo::String: {
|
||||
case Unit::MetaInfo::Kind::String: {
|
||||
const StringData* sd = lookupLitstrId(info.m_data);
|
||||
out << " i" << argKind << arg << ":s=" <<
|
||||
std::string(sd->data(), sd->size());
|
||||
break;
|
||||
}
|
||||
case Unit::MetaInfo::Class: {
|
||||
case Unit::MetaInfo::Kind::Class: {
|
||||
const StringData* sd = lookupLitstrId(info.m_data);
|
||||
out << " i" << argKind << arg << ":c=" << sd->data();
|
||||
break;
|
||||
}
|
||||
case Unit::MetaInfo::MVecPropClass: {
|
||||
case Unit::MetaInfo::Kind::MVecPropClass: {
|
||||
const StringData* sd = lookupLitstrId(info.m_data);
|
||||
out << " i" << argKind << arg << ":pc=" << sd->data();
|
||||
break;
|
||||
}
|
||||
case Unit::MetaInfo::NopOut:
|
||||
case Unit::MetaInfo::Kind::NopOut:
|
||||
out << " Nop";
|
||||
break;
|
||||
case Unit::MetaInfo::GuardedThis:
|
||||
case Unit::MetaInfo::Kind::GuardedThis:
|
||||
out << " GuardedThis";
|
||||
break;
|
||||
case Unit::MetaInfo::GuardedCls:
|
||||
case Unit::MetaInfo::Kind::GuardedCls:
|
||||
out << " GuardedCls";
|
||||
break;
|
||||
case Unit::MetaInfo::NoSurprise:
|
||||
case Unit::MetaInfo::Kind::NoSurprise:
|
||||
out << " NoSurprise";
|
||||
break;
|
||||
case Unit::MetaInfo::ArrayCapacity:
|
||||
case Unit::MetaInfo::Kind::ArrayCapacity:
|
||||
out << " capacity=" << info.m_data;
|
||||
break;
|
||||
case Unit::MetaInfo::NonRefCounted:
|
||||
case Unit::MetaInfo::Kind::NonRefCounted:
|
||||
out << " :nrc=" << info.m_data;
|
||||
break;
|
||||
case Unit::MetaInfo::None:
|
||||
case Unit::MetaInfo::Kind::None:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
|
||||
+11
-11
@@ -40,9 +40,9 @@ class Repo;
|
||||
class FuncDict;
|
||||
class Unit;
|
||||
|
||||
enum UnitOrigin {
|
||||
UnitOriginFile = 0,
|
||||
UnitOriginEval = 1
|
||||
enum class UnitOrigin {
|
||||
File = 0,
|
||||
Eval = 1
|
||||
};
|
||||
|
||||
enum UnitMergeKind {
|
||||
@@ -114,11 +114,11 @@ struct UnitMergeInfo {
|
||||
// Exception handler table entry.
|
||||
class EHEnt {
|
||||
public:
|
||||
enum EHType {
|
||||
EHType_Catch,
|
||||
EHType_Fault
|
||||
enum class Type {
|
||||
Catch,
|
||||
Fault
|
||||
};
|
||||
EHType m_ehtype;
|
||||
Type m_type;
|
||||
Offset m_base;
|
||||
Offset m_past;
|
||||
int m_iterId;
|
||||
@@ -129,7 +129,7 @@ class EHEnt {
|
||||
CatchVec m_catches;
|
||||
|
||||
template<class SerDe> void serde(SerDe& sd) {
|
||||
sd(m_ehtype)
|
||||
sd(m_type)
|
||||
(m_base)
|
||||
(m_past)
|
||||
(m_iterId)
|
||||
@@ -137,7 +137,7 @@ class EHEnt {
|
||||
(m_itRef)
|
||||
// eh.m_parentIndex is re-computed in sortEHTab, not serialized.
|
||||
;
|
||||
if (m_ehtype == EHType_Catch) {
|
||||
if (m_type == Type::Catch) {
|
||||
sd(m_catches);
|
||||
}
|
||||
}
|
||||
@@ -289,7 +289,7 @@ struct Unit {
|
||||
|
||||
class MetaInfo {
|
||||
public:
|
||||
enum Kind {
|
||||
enum class Kind {
|
||||
None,
|
||||
String,
|
||||
Class,
|
||||
@@ -344,7 +344,7 @@ struct Unit {
|
||||
MetaInfo(Kind k, int a, Id d) : m_kind(k), m_arg(a), m_data(d) {
|
||||
assert((int)m_arg == a);
|
||||
}
|
||||
MetaInfo() : m_kind(None), m_arg(-1), m_data(0) {}
|
||||
MetaInfo() : m_kind(Kind::None), m_arg(-1), m_data(0) {}
|
||||
|
||||
/*
|
||||
* m_arg indicates which input the MetaInfo applies to.
|
||||
|
||||
@@ -38,10 +38,10 @@ namespace {
|
||||
#if (defined(DEBUG) || defined(USE_TRACE))
|
||||
std::string describeFault(const Fault& f) {
|
||||
switch (f.m_faultType) {
|
||||
case Fault::UserException:
|
||||
case Fault::Type::UserException:
|
||||
return folly::format("[user exception] {}",
|
||||
implicit_cast<void*>(f.m_userException)).str();
|
||||
case Fault::CppException:
|
||||
case Fault::Type::CppException:
|
||||
return folly::format("[cpp exception] {}",
|
||||
implicit_cast<void*>(f.m_cppException)).str();
|
||||
}
|
||||
@@ -99,8 +99,8 @@ UnwindAction checkHandlers(const EHEnt* eh,
|
||||
if (faultNest == fault.m_handledCount) {
|
||||
++fault.m_handledCount;
|
||||
|
||||
switch (eh->m_ehtype) {
|
||||
case EHEnt::EHType_Fault:
|
||||
switch (eh->m_type) {
|
||||
case EHEnt::Type::Fault:
|
||||
FTRACE(1, "checkHandlers: entering fault at {}: save {}\n",
|
||||
eh->m_fault,
|
||||
func->unit()->offsetOf(pc));
|
||||
@@ -108,11 +108,11 @@ UnwindAction checkHandlers(const EHEnt* eh,
|
||||
pc = func->unit()->entry() + eh->m_fault;
|
||||
DEBUGGER_ATTACHED_ONLY(phpDebuggerExceptionHandlerHook());
|
||||
return UnwindAction::ResumeVM;
|
||||
case EHEnt::EHType_Catch:
|
||||
case EHEnt::Type::Catch:
|
||||
// Note: we skip catch clauses if we have a pending C++ exception
|
||||
// as part of our efforts to avoid running more PHP code in the
|
||||
// face of such exceptions.
|
||||
if (fault.m_faultType == Fault::UserException &&
|
||||
if (fault.m_faultType == Fault::Type::UserException &&
|
||||
ThreadInfo::s_threadInfo->m_pendingException == nullptr) {
|
||||
auto const obj = fault.m_userException;
|
||||
for (auto& idOff : eh->m_catches) {
|
||||
@@ -321,7 +321,7 @@ void unwindBuiltinFrame() {
|
||||
|
||||
void pushFault(Exception* e) {
|
||||
Fault f;
|
||||
f.m_faultType = Fault::CppException;
|
||||
f.m_faultType = Fault::Type::CppException;
|
||||
f.m_cppException = e;
|
||||
g_vmContext->m_faults.push_back(f);
|
||||
FTRACE(1, "pushing new fault: {}\n", describeFault(f));
|
||||
@@ -329,7 +329,7 @@ void pushFault(Exception* e) {
|
||||
|
||||
void pushFault(const Object& o) {
|
||||
Fault f;
|
||||
f.m_faultType = Fault::UserException;
|
||||
f.m_faultType = Fault::Type::UserException;
|
||||
f.m_userException = o.get();
|
||||
f.m_userException->incRefCount();
|
||||
g_vmContext->m_faults.push_back(f);
|
||||
|
||||
@@ -120,7 +120,7 @@ void GraphBuilder::createExBlocks() {
|
||||
const EHEnt& handler = i.popFront();
|
||||
createBlock(handler.m_base);
|
||||
createBlock(handler.m_past);
|
||||
if (handler.m_ehtype == EHEnt::EHType_Catch) {
|
||||
if (handler.m_type == EHEnt::Type::Catch) {
|
||||
m_graph->exn_cap += handler.m_catches.size() - 1;
|
||||
for (Range<EHEnt::CatchVec> c(handler.m_catches); !c.empty(); ) {
|
||||
createBlock(c.popFront().second);
|
||||
@@ -140,7 +140,7 @@ const EHEnt* findFunclet(const Func::EHEntVec& ehtab, Offset off) {
|
||||
const EHEnt* nearest = 0;
|
||||
for (Range<Func::EHEntVec> i(ehtab); !i.empty(); ) {
|
||||
const EHEnt* eh = &i.popFront();
|
||||
if (eh->m_ehtype != EHEnt::EHType_Fault) continue;
|
||||
if (eh->m_type != EHEnt::Type::Fault) continue;
|
||||
if (eh->m_fault <= off && (!nearest || eh->m_fault > nearest->m_fault)) {
|
||||
nearest = eh;
|
||||
}
|
||||
@@ -180,7 +180,7 @@ void GraphBuilder::linkExBlocks() {
|
||||
int exn_index = 0;
|
||||
for (const EHEnt* eh = m_func->findEH(off); eh != 0; ) {
|
||||
assert(eh->m_base <= off && off < eh->m_past);
|
||||
if (eh->m_ehtype == EHEnt::EHType_Catch) {
|
||||
if (eh->m_type == EHEnt::Type::Catch) {
|
||||
// each catch block is reachable from b
|
||||
for (Range<EHEnt::CatchVec> j(eh->m_catches); !j.empty(); ) {
|
||||
exns(b)[exn_index++] = at(j.popFront().second);
|
||||
@@ -198,7 +198,7 @@ void GraphBuilder::linkExBlocks() {
|
||||
const EHEnt* eh = findFunclet(ehtab, offset(b->last));
|
||||
eh = nextOuter(ehtab, eh);
|
||||
while (eh) {
|
||||
if (eh->m_ehtype == EHEnt::EHType_Catch) {
|
||||
if (eh->m_type == EHEnt::Type::Catch) {
|
||||
// each catch target for eh is reachable from b
|
||||
for (Range<EHEnt::CatchVec> j(eh->m_catches); !j.empty(); ) {
|
||||
exns(b)[exn_index++] = at(j.popFront().second);
|
||||
@@ -262,7 +262,7 @@ void GraphBuilder::addEdge(Block* from, EdgeKind k, Block* target) {
|
||||
*/
|
||||
class RpoSort {
|
||||
public:
|
||||
RpoSort(Graph* g);
|
||||
explicit RpoSort(Graph* g);
|
||||
private:
|
||||
void visit(Block* b);
|
||||
private:
|
||||
|
||||
@@ -174,7 +174,7 @@ bool FuncChecker::checkOffsets() {
|
||||
SectionMap sections;
|
||||
for (Range<FixedVector<EHEnt> > i(m_func->ehtab()); !i.empty(); ) {
|
||||
const EHEnt& eh = i.popFront();
|
||||
if (eh.m_ehtype == EHEnt::EHType_Fault) {
|
||||
if (eh.m_type == EHEnt::Type::Fault) {
|
||||
ok &= checkOffset("fault funclet", eh.m_fault, "func bytecode", base,
|
||||
past, false);
|
||||
sections[eh.m_fault] = 0;
|
||||
@@ -221,7 +221,7 @@ bool FuncChecker::checkOffsets() {
|
||||
for (Range<FixedVector<EHEnt> > i(m_func->ehtab()); !i.empty(); ) {
|
||||
const EHEnt& eh = i.popFront();
|
||||
checkRegion("EH", eh.m_base, eh.m_past, "func body", base, funclets);
|
||||
if (eh.m_ehtype == EHEnt::EHType_Catch) {
|
||||
if (eh.m_type == EHEnt::Type::Catch) {
|
||||
for (Range<vector<CatchEnt> > c(eh.m_catches); !c.empty(); ) {
|
||||
ok &= checkOffset("catch", c.popFront().second, "func body", base,
|
||||
funclets);
|
||||
@@ -789,7 +789,7 @@ bool FuncChecker::checkOutputs(State* cur, PC pc, Block* b) {
|
||||
};
|
||||
bool ok = true;
|
||||
StackTransInfo info = instrStackTransInfo(pc);
|
||||
if (info.kind == StackTransInfo::InsertMid) {
|
||||
if (info.kind == StackTransInfo::Kind::InsertMid) {
|
||||
int index = cur->stklen - info.pos - 1;
|
||||
if (index < 0) {
|
||||
reportStkUnderflow(b, *cur, pc);
|
||||
@@ -924,7 +924,7 @@ bool FuncChecker::checkFlow() {
|
||||
// Make sure eval stack is empty at start of each try region
|
||||
for (Range<FixedVector<EHEnt> > i(m_func->ehtab()); !i.empty(); ) {
|
||||
const EHEnt& handler = i.popFront();
|
||||
if (handler.m_ehtype == EHEnt::EHType_Catch) {
|
||||
if (handler.m_type == EHEnt::Type::Catch) {
|
||||
ok &= checkEmptyStack(handler, builder.at(handler.m_base));
|
||||
}
|
||||
}
|
||||
|
||||
Referência em uma Nova Issue
Bloquear um usuário