HOT_FUNC_VM void VerifyParamTypeSlow(const Class* cls, const Class* constraint, int param, const TypeConstraint* expected) { if (LIKELY(constraint && cls->classof(constraint))) { return; } // Check a typedef for a class. We interp'd if the param wasn't an // object, so if it's a typedef for something non-objecty we're // failing anyway. if (auto namedEntity = expected->namedEntity()) { NameDef def = namedEntity->getCachedNameDef(); if (UNLIKELY(!def)) { VMRegAnchor _; String nameStr(const_cast<StringData*>(expected->typeName())); if (AutoloadHandler::s_instance->autoloadType(nameStr)) { def = namedEntity->getCachedNameDef(); } } if (def && (constraint = def.asClass()) && cls->classof(constraint)) { return; } } VerifyParamTypeFail(param); }
HOT_FUNC_VM void VerifyParamTypeSlow(const Class* cls, const Class* constraint, int param, const TypeConstraint* expected) { if (LIKELY(constraint && cls->classof(constraint))) { return; } // Check a typedef for a class. We interp'd if the param wasn't an // object, so if it's a typedef for something non-objecty we're // failing anyway. if (auto namedEntity = expected->namedEntity()) { auto def = namedEntity->getCachedTypedef(); if (UNLIKELY(!def)) { VMRegAnchor _; String nameStr(const_cast<StringData*>(expected->typeName())); if (AutoloadHandler::s_instance->autoloadType(nameStr)) { def = namedEntity->getCachedTypedef(); } } if (def) { // There's no need to handle nullable typedefs specially here: // we already know we're checking a non-null object with the // class `cls'. We do however need to check for typedefs to // mixed. if (def->kind == KindOfObject) { constraint = def->klass; if (constraint && cls->classof(constraint)) return; } else if (def->kind == KindOfAny) { return; } } } VerifyParamTypeFail(param); }
void VerifyParamTypeCallable(TypedValue value, int param) { if (UNLIKELY(!f_is_callable(tvAsCVarRef(&value)))) { VerifyParamTypeFail(param); } }