public static Memory checkReturnType(Environment env, TraceInfo trace, Memory result, Function<String> callName,
                                         TypeChecker typeChecker, boolean nullable) {
        if (typeChecker == null) {
            return result;
        }

        if (!typeChecker.check(env, result, nullable, null)) {
            ModuleEntity module = env.getModuleManager().findModule(trace);

            Memory newReturn = typeChecker.apply(
                    env, result, nullable, module != null && module.isStrictTypes()
            );

            if (newReturn == null) {
                String given = result.isObject()
                        ? result.toValue(ObjectMemory.class).getReflection().getName()
                        : result.getRealType().toString();

                env.exception(
                        trace,
                        BaseTypeError.class,
                        Messages.ERR_RETURN_TYPE_INVALID.fetch(callName.call(), typeChecker.getHumanString(), given)
                );

                return null;
            } else {
                return newReturn;
            }
        }


        return result;
    }
Method is invoked via bytecode

@throws Throwable
jphp-runtime/src/php/runtime/invoke/InvokeHelper.java