/**
 *    Copyright (C) 2019-present MongoDB, Inc.
 *
 *    This program is free software: you can redistribute it and/or modify
 *    it under the terms of the Server Side Public License, version 1,
 *    as published by MongoDB, Inc.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    Server Side Public License for more details.
 *
 *    You should have received a copy of the Server Side Public License
 *    along with this program. If not, see
 *    <http://www.mongodb.com/licensing/server-side-public-license>.
 *
 *    As a special exception, the copyright holders give permission to link the
 *    code of portions of this program with the OpenSSL library under certain
 *    conditions as described in each individual source file and distribute
 *    linked combinations including the program with the OpenSSL library. You
 *    must comply with the Server Side Public License in all respects for
 *    all of the code used other than as permitted herein. If you modify file(s)
 *    with this exception, you may extend this exception to your version of the
 *    file(s), but you are not obligated to do so. If you do not wish to do so,
 *    delete this exception statement from your version. If you delete this
 *    exception statement from all source files in the program, then also delete
 *    it in the license file.
 */

#include "mongo/db/exec/sbe/vm/vm_builtin.h"

#include "mongo/db/exec/sbe/vm/vm.h"
#include "mongo/util/assert_util.h"  // MONGO_UNREACHABLE

#define MONGO_LOGV2_DEFAULT_COMPONENT ::mongo::logv2::LogComponent::kQuery

namespace mongo {
namespace sbe {
namespace vm {
std::string builtinToString(Builtin b) {
    switch (b) {
        case Builtin::split:
            return "split";
        case Builtin::regexMatch:
            return "regexMatch";
        case Builtin::replaceOne:
            return "replaceOne";
        case Builtin::dateDiff:
            return "dateDiff";
        case Builtin::dateParts:
            return "dateParts";
        case Builtin::dateToParts:
            return "dateToParts";
        case Builtin::isoDateToParts:
            return "isoDateToParts";
        case Builtin::dayOfYear:
            return "dayOfYear";
        case Builtin::dayOfMonth:
            return "dayOfMonth";
        case Builtin::dayOfWeek:
            return "dayOfWeek";
        case Builtin::datePartsWeekYear:
            return "datePartsWeekYear";
        case Builtin::dateToString:
            return "dateToString";
        case Builtin::dateFromString:
            return "dateFromString";
        case Builtin::dateFromStringNoThrow:
            return "dateFromStringNoThrow";
        case Builtin::dropFields:
            return "dropFields";
        case Builtin::newArray:
            return "newArray";
        case Builtin::keepFields:
            return "keepFields";
        case Builtin::newArrayFromRange:
            return "newArrayFromRange";
        case Builtin::newObj:
            return "newObj";
        case Builtin::newBsonObj:
            return "newBsonObj";
        case Builtin::ksToString:
            return "ksToString";
        case Builtin::newKs:
            return "newKs";
        case Builtin::collNewKs:
            return "collNewKs";
        case Builtin::abs:
            return "abs";
        case Builtin::ceil:
            return "ceil";
        case Builtin::floor:
            return "floor";
        case Builtin::trunc:
            return "trunc";
        case Builtin::exp:
            return "exp";
        case Builtin::ln:
            return "ln";
        case Builtin::log10:
            return "log10";
        case Builtin::sqrt:
            return "sqrt";
        case Builtin::pow:
            return "pow";
        case Builtin::addToArray:
            return "addToArray";
        case Builtin::addToArrayCapped:
            return "addToArrayCapped";
        case Builtin::mergeObjects:
            return "mergeObjects";
        case Builtin::addToSet:
            return "addToSet";
        case Builtin::addToSetCapped:
            return "addToSetCapped";
        case Builtin::collAddToSet:
            return "collAddToSet";
        case Builtin::collAddToSetCapped:
            return "collAddToSetCapped";
        case Builtin::setUnionCapped:
            return "setUnionCapped";
        case Builtin::collSetUnionCapped:
            return "collSetUnionCapped";
        case Builtin::doubleDoubleSum:
            return "doubleDoubleSum";
        case Builtin::convertSimpleSumToDoubleDoubleSum:
            return "convertSimpleSumToDoubleDoubleSum";
        case Builtin::aggDoubleDoubleSum:
            return "aggDoubleDoubleSum";
        case Builtin::doubleDoubleSumFinalize:
            return "doubleDoubleSumFinalize";
        case Builtin::doubleDoublePartialSumFinalize:
            return "doubleDoublePartialSumFinalize";
        case Builtin::aggMergeDoubleDoubleSums:
            return "aggMergeDoubleDoubleSums";
        case Builtin::aggStdDev:
            return "aggStdDev";
        case Builtin::aggMergeStdDevs:
            return "aggMergeStdDevs";
        case Builtin::stdDevPopFinalize:
            return "stdDevPopFinalize";
        case Builtin::stdDevSampFinalize:
            return "stdDevSampFinalize";
        case Builtin::bitTestZero:
            return "bitTestZero";
        case Builtin::bitTestMask:
            return "bitTestMask";
        case Builtin::bitTestPosition:
            return "bitTestPosition";
        case Builtin::bsonSize:
            return "bsonSize";
        case Builtin::strLenBytes:
            return "strLenBytes";
        case Builtin::strLenCP:
            return "strLenCP";
        case Builtin::substrBytes:
            return "substrBytes";
        case Builtin::substrCP:
            return "substrCP";
        case Builtin::toUpper:
            return "toUpper";
        case Builtin::toLower:
            return "toLower";
        case Builtin::trim:
            return "trim";
        case Builtin::ltrim:
            return "ltrim";
        case Builtin::rtrim:
            return "rtrim";
        case Builtin::coerceToBool:
            return "coerceToBool";
        case Builtin::coerceToString:
            return "coerceToString";
        case Builtin::concat:
            return "concat";
        case Builtin::concatArrays:
            return "concatArrays";
        case Builtin::aggConcatArraysCapped:
            return "aggConcatArraysCapped";
        case Builtin::concatArraysCapped:
            return "concatArraysCapped";
        case Builtin::aggSetUnion:
            return "aggSetUnion";
        case Builtin::aggCollSetUnion:
            return "aggCollSetUnion";
        case Builtin::aggSetUnionCapped:
            return "aggSetUnionCapped";
        case Builtin::aggCollSetUnionCapped:
            return "aggCollSetUnionCapped";
        case Builtin::acos:
            return "acos";
        case Builtin::acosh:
            return "acosh";
        case Builtin::asin:
            return "asin";
        case Builtin::asinh:
            return "asinh";
        case Builtin::atan:
            return "atan";
        case Builtin::atanh:
            return "atanh";
        case Builtin::atan2:
            return "atan2";
        case Builtin::cos:
            return "cos";
        case Builtin::cosh:
            return "cosh";
        case Builtin::degreesToRadians:
            return "degreesToRadians";
        case Builtin::radiansToDegrees:
            return "radiansToDegrees";
        case Builtin::sin:
            return "sin";
        case Builtin::sinh:
            return "sinh";
        case Builtin::tan:
            return "tan";
        case Builtin::tanh:
            return "tanh";
        case Builtin::rand:
            return "rand";
        case Builtin::round:
            return "round";
        case Builtin::isMember:
            return "isMember";
        case Builtin::collIsMember:
            return "collIsMember";
        case Builtin::indexOfBytes:
            return "indexOfBytes";
        case Builtin::indexOfCP:
            return "indexOfCP";
        case Builtin::isDayOfWeek:
            return "isDayOfWeek";
        case Builtin::isTimeUnit:
            return "isTimeUnit";
        case Builtin::isTimezone:
            return "isTimezone";
        case Builtin::isValidToStringFormat:
            return "isValidToStringFormat";
        case Builtin::validateFromStringFormat:
            return "validateFromStringFormat";
        case Builtin::setUnion:
            return "setUnion";
        case Builtin::setIntersection:
            return "setIntersection";
        case Builtin::setDifference:
            return "setDifference";
        case Builtin::setEquals:
            return "setEquals";
        case Builtin::collSetUnion:
            return "collSetUnion";
        case Builtin::collSetIntersection:
            return "collSetIntersection";
        case Builtin::collSetDifference:
            return "collSetDifference";
        case Builtin::collSetEquals:
            return "collSetEquals";
        case Builtin::runJsPredicate:
            return "runJsPredicate";
        case Builtin::regexCompile:
            return "regexCompile";
        case Builtin::regexFind:
            return "regexFind";
        case Builtin::regexFindAll:
            return "regexFindAll";
        case Builtin::shardFilter:
            return "shardFilter";
        case Builtin::shardHash:
            return "shardHash";
        case Builtin::extractSubArray:
            return "extractSubArray";
        case Builtin::isArrayEmpty:
            return "isArrayEmpty";
        case Builtin::reverseArray:
            return "reverseArray";
        case Builtin::sortArray:
            return "sortArray";
        case Builtin::dateAdd:
            return "dateAdd";
        case Builtin::hasNullBytes:
            return "hasNullBytes";
        case Builtin::getRegexPattern:
            return "getRegexPattern";
        case Builtin::getRegexFlags:
            return "getRegexFlags";
        case Builtin::hash:
            return "hash";
        case Builtin::ftsMatch:
            return "ftsMatch";
        case Builtin::generateSortKey:
            return "generateSortKey";
        case Builtin::generateCheapSortKey:
            return "generateCheapSortKey";
        case Builtin::sortKeyComponentVectorGetElement:
            return "sortKeyComponentVectorGetElement";
        case Builtin::sortKeyComponentVectorToArray:
            return "sortKeyComponentVectorToArray";
        case Builtin::makeObj:
            return "makeObj";
        case Builtin::makeBsonObj:
            return "makeBsonObj";
        case Builtin::tsSecond:
            return "tsSecond";
        case Builtin::tsIncrement:
            return "tsIncrement";
        case Builtin::typeMatch:
            return "typeMatch";
        case Builtin::dateTrunc:
            return "dateTrunc";
        case Builtin::getSortKeyAsc:
            return "getSortKeyAsc";
        case Builtin::getSortKeyDesc:
            return "getSortKeyDesc";
        case Builtin::getNonLeafSortKeyAsc:
            return "getNonLeafSortKeyAsc";
        case Builtin::getNonLeafSortKeyDesc:
            return "getNonLeafSortKeyDesc";
        case Builtin::year:
            return "year";
        case Builtin::month:
            return "month";
        case Builtin::hour:
            return "hour";
        case Builtin::minute:
            return "minute";
        case Builtin::second:
            return "second";
        case Builtin::millisecond:
            return "millisecond";
        case Builtin::week:
            return "week";
        case Builtin::isoWeekYear:
            return "isoWeekYear";
        case Builtin::isoDayOfWeek:
            return "isoDayOfWeek";
        case Builtin::isoWeek:
            return "isoWeek";
        case Builtin::objectToArray:
            return "objectToArray";
        case Builtin::arrayToObject:
            return "arrayToObject";
        case Builtin::avgOfArray:
            return "avgOfArray";
        case Builtin::maxOfArray:
            return "maxOfArray";
        case Builtin::minOfArray:
            return "minOfArray";
        case Builtin::stdDevPop:
            return "stdDevPop";
        case Builtin::stdDevSamp:
            return "stdDevSamp";
        case Builtin::sumOfArray:
            return "sumOfArray";
        case Builtin::unwindArray:
            return "unwindArray";
        case Builtin::arrayToSet:
            return "arrayToSet";
        case Builtin::collArrayToSet:
            return "collArrayToSet";
        case Builtin::setToArray:
            return "setToArray";
        case Builtin::fillType:
            return "fillType";
        case Builtin::aggFirstNNeedsMoreInput:
            return "aggFirstNNeedsMoreInput";
        case Builtin::aggFirstN:
            return "aggFirstN";
        case Builtin::aggFirstNMerge:
            return "aggFirstNMerge";
        case Builtin::aggFirstNFinalize:
            return "aggFirstNFinalize";
        case Builtin::aggLastN:
            return "aggLastN";
        case Builtin::aggLastNMerge:
            return "aggLastNMerge";
        case Builtin::aggLastNFinalize:
            return "aggLastNFinalize";
        case Builtin::aggTopN:
            return "aggTopN";
        case Builtin::aggTopNArray:
            return "aggTopNArray";
        case Builtin::aggTopNMerge:
            return "aggTopNMerge";
        case Builtin::aggTopNFinalize:
            return "aggTopNFinalize";
        case Builtin::aggBottomN:
            return "aggBottomN";
        case Builtin::aggBottomNArray:
            return "aggBottomNArray";
        case Builtin::aggBottomNMerge:
            return "aggBottomNMerge";
        case Builtin::aggBottomNFinalize:
            return "aggBottomNFinalize";
        case Builtin::aggMaxN:
            return "aggMaxN";
        case Builtin::aggMaxNMerge:
            return "aggMaxNMerge";
        case Builtin::aggMaxNFinalize:
            return "aggMaxNFinalize";
        case Builtin::aggMinN:
            return "aggMinN";
        case Builtin::aggMinNMerge:
            return "aggMinNMerge";
        case Builtin::aggMinNFinalize:
            return "aggMinNFinalize";
        case Builtin::aggRank:
            return "aggRank";
        case Builtin::aggRankColl:
            return "aggRankColl";
        case Builtin::aggDenseRank:
            return "aggDenseRank";
        case Builtin::aggDenseRankColl:
            return "aggDenseRankColl";
        case Builtin::aggRankFinalize:
            return "aggRankFinalize";
        case Builtin::aggExpMovingAvg:
            return "aggExpMovingAvg";
        case Builtin::aggExpMovingAvgFinalize:
            return "aggExpMovingAvgFinalize";
        case Builtin::aggRemovableSumAdd:
            return "aggRemovableSumAdd";
        case Builtin::aggRemovableSumRemove:
            return "aggRemovableSumRemove";
        case Builtin::aggRemovableSumFinalize:
            return "aggRemovableSumFinalize";
        case Builtin::aggIntegralInit:
            return "aggIntegralInit";
        case Builtin::aggIntegralAdd:
            return "aggIntegralAdd";
        case Builtin::aggIntegralRemove:
            return "aggIntegralRemove";
        case Builtin::aggIntegralFinalize:
            return "aggIntegralFinalize";
        case Builtin::aggDerivativeFinalize:
            return "aggDerivativeFinalize";
        case Builtin::aggCovarianceAdd:
            return "aggCovarianceAdd";
        case Builtin::aggCovarianceRemove:
            return "aggCovarianceRemove";
        case Builtin::aggCovarianceSampFinalize:
            return "aggCovarianceSampFinalize";
        case Builtin::aggCovariancePopFinalize:
            return "aggCovariancePopFinalize";
        case Builtin::aggRemovablePushAdd:
            return "aggRemovablePushAdd";
        case Builtin::aggRemovablePushRemove:
            return "aggRemovablePushRemove";
        case Builtin::aggRemovablePushFinalize:
            return "aggRemovablePushFinalize";
        case Builtin::aggRemovableStdDevAdd:
            return "aggRemovableStdDevAdd";
        case Builtin::aggRemovableStdDevRemove:
            return "aggRemovableStdDevRemove";
        case Builtin::aggRemovableStdDevSampFinalize:
            return "aggRemovableStdDevSampFinalize";
        case Builtin::aggRemovableStdDevPopFinalize:
            return "aggRemovableStdDevPopFinalize";
        case Builtin::aggRemovableFirstNInit:
            return "aggRemovableFirstNInit";
        case Builtin::aggRemovableFirstNAdd:
            return "aggRemovableFirstNAdd";
        case Builtin::aggRemovableFirstNRemove:
            return "aggRemovableFirstNRemove";
        case Builtin::aggRemovableFirstNFinalize:
            return "aggRemovableFirstNFinalize";
        case Builtin::aggRemovableLastNInit:
            return "aggRemovableLastNInit";
        case Builtin::aggRemovableLastNAdd:
            return "aggRemovableLastNAdd";
        case Builtin::aggRemovableLastNRemove:
            return "aggRemovableLastNRemove";
        case Builtin::aggRemovableLastNFinalize:
            return "aggRemovableLastNFinalize";
        case Builtin::aggLinearFillCanAdd:
            return "aggLinearFillCanAdd";
        case Builtin::aggLinearFillAdd:
            return "aggLinearFillAdd";
        case Builtin::aggLinearFillFinalize:
            return "aggLinearFillFinalize";
        case Builtin::aggRemovableSetCommonInit:
            return "aggRemovableSetCommonInit";
        case Builtin::aggRemovableSetCommonCollInit:
            return "aggRemovableSetCommonCollInit";
        case Builtin::aggRemovableAddToSetAdd:
            return "aggRemovableAddToSetAdd";
        case Builtin::aggRemovableAddToSetRemove:
            return "aggRemovableAddToSetRemove";
        case Builtin::aggRemovableSetUnionAdd:
            return "aggRemovableSetUnionAdd";
        case Builtin::aggRemovableSetUnionRemove:
            return "aggRemovableSetUnionRemove";
        case Builtin::aggRemovableSetCommonFinalize:
            return "aggRemovableSetCommonFinalize";
        case Builtin::aggRemovableMinMaxNCollInit:
            return "aggRemovableMinMaxNCollInit";
        case Builtin::aggRemovableMinMaxNInit:
            return "aggRemovableMinMaxNInit";
        case Builtin::aggRemovableMinMaxNAdd:
            return "aggRemovableMinMaxNAdd";
        case Builtin::aggRemovableMinMaxNRemove:
            return "aggRemovableMinMaxNRemove";
        case Builtin::aggRemovableMinNFinalize:
            return "aggRemovableMinNFinalize";
        case Builtin::aggRemovableMaxNFinalize:
            return "aggRemovableMaxNFinalize";
        case Builtin::aggRemovableTopNInit:
            return "aggRemovableTopNInit";
        case Builtin::aggRemovableTopNAdd:
            return "aggRemovableTopNAdd";
        case Builtin::aggRemovableTopNRemove:
            return "aggRemovableTopNRemove";
        case Builtin::aggRemovableTopNFinalize:
            return "aggRemovableTopNFinalize";
        case Builtin::aggRemovableBottomNInit:
            return "aggRemovableBottomNInit";
        case Builtin::aggRemovableBottomNAdd:
            return "aggRemovableBottomNAdd";
        case Builtin::aggRemovableBottomNRemove:
            return "aggRemovableBottomNRemove";
        case Builtin::aggRemovableBottomNFinalize:
            return "aggRemovableBottomNFinalize";
        case Builtin::valueBlockTypeMatch:
            return "valueBlockTypeMatch";
        case Builtin::valueBlockIsTimezone:
            return "valueBlockIsTimezone";
        case Builtin::valueBlockExists:
            return "valueBlockExists";
        case Builtin::valueBlockFillEmpty:
            return "valueBlockFillEmpty";
        case Builtin::valueBlockFillEmptyBlock:
            return "valueBlockFillEmptyBlock";
        case Builtin::valueBlockFillType:
            return "valueBlockFillType";
        case Builtin::valueBlockAggMin:
            return "valueBlockAggMin";
        case Builtin::valueBlockAggMax:
            return "valueBlockAggMax";
        case Builtin::valueBlockAggCount:
            return "valueBlockAggCount";
        case Builtin::valueBlockAggSum:
            return "valueBlockAggSum";
        case Builtin::valueBlockAggDoubleDoubleSum:
            return "valueBlockAggDoubleDoubleSum";
        case Builtin::valueBlockAggTopN:
            return "valueBlockAggTopN";
        case Builtin::valueBlockAggTopNArray:
            return "valueBlockAggTopNArray";
        case Builtin::valueBlockAggBottomN:
            return "valueBlockAggBottomN";
        case Builtin::valueBlockAggBottomNArray:
            return "valueBlockAggBottomNArray";
        case Builtin::valueBlockDateDiff:
            return "valueBlockDateDiff";
        case Builtin::valueBlockDateTrunc:
            return "valueBlockDateTrunc";
        case Builtin::valueBlockDateAdd:
            return "valueBlockDateAdd";
        case Builtin::valueBlockTrunc:
            return "valueBlockTrunc";
        case Builtin::valueBlockRound:
            return "valueBlockRound";
        case Builtin::valueBlockAdd:
            return "valueBlockAdd";
        case Builtin::valueBlockSub:
            return "valueBlockSub";
        case Builtin::valueBlockMult:
            return "valueBlockMult";
        case Builtin::valueBlockDiv:
            return "valueBlockDiv";
        case Builtin::valueBlockGtScalar:
            return "valueBlockGtScalar";
        case Builtin::valueBlockGteScalar:
            return "valueBlockGteScalar";
        case Builtin::valueBlockEqScalar:
            return "valueBlockEqScalar";
        case Builtin::valueBlockNeqScalar:
            return "valueBlockNeqScalar";
        case Builtin::valueBlockLtScalar:
            return "valueBlockLtScalar";
        case Builtin::valueBlockLteScalar:
            return "valueBlockLteScalar";
        case Builtin::valueBlockCmp3wScalar:
            return "valueBlockCmp3wScalar";
        case Builtin::valueBlockCombine:
            return "valueBlockCombine";
        case Builtin::valueBlockLogicalAnd:
            return "valueBlockLogicalAnd";
        case Builtin::valueBlockLogicalOr:
            return "valueBlockLogicalOr";
        case Builtin::valueBlockLogicalNot:
            return "valueBlockLogicalNot";
        case Builtin::valueBlockNewFill:
            return "valueBlockNewFill";
        case Builtin::valueBlockSize:
            return "valueBlockSize";
        case Builtin::valueBlockNone:
            return "valueBlockNone";
        case Builtin::valueBlockIsMember:
            return "valueBlockIsMember";
        case Builtin::valueBlockCoerceToBool:
            return "valueBlockCoerceToBool";
        case Builtin::valueBlockMod:
            return "valueBlockMod";
        case Builtin::valueBlockConvert:
            return "valueBlockConvert";
        case Builtin::valueBlockGetSortKeyAsc:
            return "valueBlockGetSortKeyAsc";
        case Builtin::valueBlockGetSortKeyDesc:
            return "valueBlockGetSortKeyDesc";
        case Builtin::cellFoldValues_F:
            return "cellFoldValues_F";
        case Builtin::cellFoldValues_P:
            return "cellFoldValues_P";
        case Builtin::cellBlockGetFlatValuesBlock:
            return "cellBlockGetFlatValuesBlock";
        default:
            MONGO_UNREACHABLE;
    }
}  // builtinToString

FastTuple<bool, value::TypeTags, value::Value> ByteCode::dispatchBuiltin(Builtin f,
                                                                         ArityType arity,
                                                                         const CodeFragment* code) {
    switch (f) {
        case Builtin::dateDiff:
            return builtinDateDiff(arity);
        case Builtin::dateParts:
            return builtinDate(arity);
        case Builtin::datePartsWeekYear:
            return builtinDateWeekYear(arity);
        case Builtin::dateToParts:
            return builtinDateToParts(arity);
        case Builtin::isoDateToParts:
            return builtinIsoDateToParts(arity);
        case Builtin::dayOfYear:
            return builtinDayOfYear(arity);
        case Builtin::dayOfMonth:
            return builtinDayOfMonth(arity);
        case Builtin::dayOfWeek:
            return builtinDayOfWeek(arity);
        case Builtin::dateToString:
            return builtinDateToString(arity);
        case Builtin::dateFromString:
            return builtinDateFromString(arity);
        case Builtin::dateFromStringNoThrow:
            return builtinDateFromStringNoThrow(arity);
        case Builtin::split:
            return builtinSplit(arity);
        case Builtin::regexMatch:
            return builtinRegexMatch(arity);
        case Builtin::replaceOne:
            return builtinReplaceOne(arity);
        case Builtin::dropFields:
            return builtinDropFields(arity);
        case Builtin::newArray:
            return builtinNewArray(arity);
        case Builtin::keepFields:
            return builtinKeepFields(arity);
        case Builtin::newArrayFromRange:
            return builtinNewArrayFromRange(arity);
        case Builtin::newObj:
            return builtinNewObj(arity);
        case Builtin::newBsonObj:
            return builtinNewBsonObj(arity);
        case Builtin::ksToString:
            return builtinKeyStringToString(arity);
        case Builtin::newKs:
            return builtinNewKeyString(arity);
        case Builtin::collNewKs:
            return builtinCollNewKeyString(arity);
        case Builtin::abs:
            return builtinAbs(arity);
        case Builtin::ceil:
            return builtinCeil(arity);
        case Builtin::floor:
            return builtinFloor(arity);
        case Builtin::trunc:
            return builtinTrunc(arity);
        case Builtin::exp:
            return builtinExp(arity);
        case Builtin::ln:
            return builtinLn(arity);
        case Builtin::log10:
            return builtinLog10(arity);
        case Builtin::sqrt:
            return builtinSqrt(arity);
        case Builtin::pow:
            return builtinPow(arity);
        case Builtin::addToArray:
            return builtinAddToArray(arity);
        case Builtin::addToArrayCapped:
            return builtinAddToArrayCapped(arity);
        case Builtin::mergeObjects:
            return builtinMergeObjects(arity);
        case Builtin::addToSet:
            return builtinAddToSet(arity);
        case Builtin::addToSetCapped:
            return builtinAddToSetCapped(arity);
        case Builtin::collAddToSet:
            return builtinCollAddToSet(arity);
        case Builtin::collAddToSetCapped:
            return builtinCollAddToSetCapped(arity);
        case Builtin::doubleDoubleSum:
            return builtinDoubleDoubleSum(arity);
        case Builtin::convertSimpleSumToDoubleDoubleSum:
            return builtinConvertSimpleSumToDoubleDoubleSum(arity);
        case Builtin::aggDoubleDoubleSum:
            return builtinAggDoubleDoubleSum<false /*merging*/>(arity);
        case Builtin::doubleDoubleSumFinalize:
            return builtinDoubleDoubleSumFinalize(arity);
        case Builtin::doubleDoublePartialSumFinalize:
            return builtinDoubleDoublePartialSumFinalize(arity);
        case Builtin::aggMergeDoubleDoubleSums:
            return builtinAggDoubleDoubleSum<true /*merging*/>(arity);
        case Builtin::aggStdDev:
            return builtinAggStdDev<false /*merging*/>(arity);
        case Builtin::aggMergeStdDevs:
            return builtinAggStdDev<true /*merging*/>(arity);
        case Builtin::stdDevPopFinalize:
            return builtinStdDevPopFinalize(arity);
        case Builtin::stdDevSampFinalize:
            return builtinStdDevSampFinalize(arity);
        case Builtin::bitTestZero:
            return builtinBitTestZero(arity);
        case Builtin::bitTestMask:
            return builtinBitTestMask(arity);
        case Builtin::bitTestPosition:
            return builtinBitTestPosition(arity);
        case Builtin::bsonSize:
            return builtinBsonSize(arity);
        case Builtin::strLenBytes:
            return builtinStrLenBytes(arity);
        case Builtin::strLenCP:
            return builtinStrLenCP(arity);
        case Builtin::substrBytes:
            return builtinSubstrBytes(arity);
        case Builtin::substrCP:
            return builtinSubstrCP(arity);
        case Builtin::toUpper:
            return builtinToUpper(arity);
        case Builtin::toLower:
            return builtinToLower(arity);
        case Builtin::trim:
            return builtinTrim(arity, true, true);
        case Builtin::ltrim:
            return builtinTrim(arity, true, false);
        case Builtin::rtrim:
            return builtinTrim(arity, false, true);
        case Builtin::coerceToBool:
            return builtinCoerceToBool(arity);
        case Builtin::coerceToString:
            return builtinCoerceToString(arity);
        case Builtin::acos:
            return builtinAcos(arity);
        case Builtin::acosh:
            return builtinAcosh(arity);
        case Builtin::asin:
            return builtinAsin(arity);
        case Builtin::asinh:
            return builtinAsinh(arity);
        case Builtin::atan:
            return builtinAtan(arity);
        case Builtin::atanh:
            return builtinAtanh(arity);
        case Builtin::atan2:
            return builtinAtan2(arity);
        case Builtin::cos:
            return builtinCos(arity);
        case Builtin::cosh:
            return builtinCosh(arity);
        case Builtin::degreesToRadians:
            return builtinDegreesToRadians(arity);
        case Builtin::radiansToDegrees:
            return builtinRadiansToDegrees(arity);
        case Builtin::sin:
            return builtinSin(arity);
        case Builtin::sinh:
            return builtinSinh(arity);
        case Builtin::tan:
            return builtinTan(arity);
        case Builtin::tanh:
            return builtinTanh(arity);
        case Builtin::rand:
            return builtinRand(arity);
        case Builtin::round:
            return builtinRound(arity);
        case Builtin::concat:
            return builtinConcat(arity);
        case Builtin::concatArrays:
            return builtinConcatArrays(arity);
        case Builtin::aggConcatArraysCapped:
            return builtinAggConcatArraysCapped(arity);
        case Builtin::concatArraysCapped:
            return builtinConcatArraysCapped(arity);
        case Builtin::aggSetUnion:
            return builtinAggSetUnion(arity);
        case Builtin::aggCollSetUnion:
            return builtinAggCollSetUnion(arity);
        case Builtin::aggSetUnionCapped:
            return builtinAggSetUnionCapped(arity);
        case Builtin::aggCollSetUnionCapped:
            return builtinAggCollSetUnionCapped(arity);
        case Builtin::setUnionCapped:
            return builtinSetUnionCapped(arity);
        case Builtin::collSetUnionCapped:
            return builtinCollSetUnionCapped(arity);
        case Builtin::isMember:
            return builtinIsMember(arity);
        case Builtin::collIsMember:
            return builtinCollIsMember(arity);
        case Builtin::indexOfBytes:
            return builtinIndexOfBytes(arity);
        case Builtin::indexOfCP:
            return builtinIndexOfCP(arity);
        case Builtin::isDayOfWeek:
            return builtinIsDayOfWeek(arity);
        case Builtin::isTimeUnit:
            return builtinIsTimeUnit(arity);
        case Builtin::isTimezone:
            return builtinIsTimezone(arity);
        case Builtin::isValidToStringFormat:
            return builtinIsValidToStringFormat(arity);
        case Builtin::validateFromStringFormat:
            return builtinValidateFromStringFormat(arity);
        case Builtin::setUnion:
            return builtinSetUnion(arity);
        case Builtin::setIntersection:
            return builtinSetIntersection(arity);
        case Builtin::setDifference:
            return builtinSetDifference(arity);
        case Builtin::setEquals:
            return builtinSetEquals(arity);
        case Builtin::setIsSubset:
            return builtinSetIsSubset(arity);
        case Builtin::collSetUnion:
            return builtinCollSetUnion(arity);
        case Builtin::collSetIntersection:
            return builtinCollSetIntersection(arity);
        case Builtin::collSetDifference:
            return builtinCollSetDifference(arity);
        case Builtin::collSetEquals:
            return builtinCollSetEquals(arity);
        case Builtin::collSetIsSubset:
            return builtinCollSetIsSubset(arity);
        case Builtin::runJsPredicate:
            return builtinRunJsPredicate(arity);
        case Builtin::regexCompile:
            return builtinRegexCompile(arity);
        case Builtin::regexFind:
            return builtinRegexFind(arity);
        case Builtin::regexFindAll:
            return builtinRegexFindAll(arity);
        case Builtin::shardFilter:
            return builtinShardFilter(arity);
        case Builtin::shardHash:
            return builtinShardHash(arity);
        case Builtin::extractSubArray:
            return builtinExtractSubArray(arity);
        case Builtin::isArrayEmpty:
            return builtinIsArrayEmpty(arity);
        case Builtin::reverseArray:
            return builtinReverseArray(arity);
        case Builtin::sortArray:
            return builtinSortArray(arity);
        case Builtin::dateAdd:
            return builtinDateAdd(arity);
        case Builtin::hasNullBytes:
            return builtinHasNullBytes(arity);
        case Builtin::getRegexPattern:
            return builtinGetRegexPattern(arity);
        case Builtin::getRegexFlags:
            return builtinGetRegexFlags(arity);
        case Builtin::hash:
            return builtinHash(arity);
        case Builtin::ftsMatch:
            return builtinFtsMatch(arity);
        case Builtin::generateSortKey:
            return builtinGenerateSortKey(arity);
        case Builtin::generateCheapSortKey:
            return builtinGenerateCheapSortKey(arity);
        case Builtin::sortKeyComponentVectorGetElement:
            return builtinSortKeyComponentVectorGetElement(arity);
        case Builtin::sortKeyComponentVectorToArray:
            return builtinSortKeyComponentVectorToArray(arity);
        case Builtin::makeObj:
            return builtinMakeObj(arity, code);
        case Builtin::makeBsonObj:
            return builtinMakeBsonObj(arity, code);
        case Builtin::tsSecond:
            return builtinTsSecond(arity);
        case Builtin::tsIncrement:
            return builtinTsIncrement(arity);
        case Builtin::typeMatch:
            return builtinTypeMatch(arity);
        case Builtin::dateTrunc:
            return builtinDateTrunc(arity);
        case Builtin::getSortKeyAsc:
            return builtinGetSortKey<true /*IsAscending*/, true /*IsLeaf*/>(arity);
        case Builtin::getSortKeyDesc:
            return builtinGetSortKey<false /*IsAscending*/, true /*IsLeaf*/>(arity);
        case Builtin::getNonLeafSortKeyAsc:
            return builtinGetSortKey<true /*IsAscending*/, false /*IsLeaf*/>(arity);
        case Builtin::getNonLeafSortKeyDesc:
            return builtinGetSortKey<false /*IsAscending*/, false /*IsLeaf*/>(arity);
        case Builtin::year:
            return builtinYear(arity);
        case Builtin::month:
            return builtinMonth(arity);
        case Builtin::hour:
            return builtinHour(arity);
        case Builtin::minute:
            return builtinMinute(arity);
        case Builtin::second:
            return builtinSecond(arity);
        case Builtin::millisecond:
            return builtinMillisecond(arity);
        case Builtin::week:
            return builtinWeek(arity);
        case Builtin::isoWeekYear:
            return builtinISOWeekYear(arity);
        case Builtin::isoDayOfWeek:
            return builtinISODayOfWeek(arity);
        case Builtin::isoWeek:
            return builtinISOWeek(arity);
        case Builtin::objectToArray:
            return builtinObjectToArray(arity);
        case Builtin::arrayToObject:
            return builtinArrayToObject(arity);
        case Builtin::avgOfArray:
            return builtinAvgOfArray(arity);
        case Builtin::maxOfArray:
            return builtinMaxOfArray(arity);
        case Builtin::minOfArray:
            return builtinMinOfArray(arity);
        case Builtin::stdDevPop:
            return builtinStdDevPop(arity);
        case Builtin::stdDevSamp:
            return builtinStdDevSamp(arity);
        case Builtin::sumOfArray:
            return builtinSumOfArray(arity);
        case Builtin::unwindArray:
            return builtinUnwindArray(arity);
        case Builtin::arrayToSet:
            return builtinArrayToSet(arity);
        case Builtin::collArrayToSet:
            return builtinCollArrayToSet(arity);
        case Builtin::setToArray:
            return builtinSetToArray(arity);
        case Builtin::fillType:
            return builtinFillType(arity);
        case Builtin::aggFirstNNeedsMoreInput:
            return builtinAggFirstNNeedsMoreInput(arity);
        case Builtin::aggFirstN:
            return builtinAggFirstN(arity);
        case Builtin::aggFirstNMerge:
            return builtinAggFirstNMerge(arity);
        case Builtin::aggFirstNFinalize:
            return builtinAggFirstNFinalize(arity);
        case Builtin::aggLastN:
            return builtinAggLastN(arity);
        case Builtin::aggLastNMerge:
            return builtinAggLastNMerge(arity);
        case Builtin::aggLastNFinalize:
            return builtinAggLastNFinalize(arity);
        case Builtin::aggTopN:
            return builtinAggTopBottomN<TopBottomSense::kTop>(arity);
        case Builtin::aggTopNArray:
            return builtinAggTopBottomNArray<TopBottomSense::kTop>(arity);
        case Builtin::aggTopNMerge:
            return builtinAggTopBottomNMerge<TopBottomSense::kTop>(arity);
        case Builtin::aggTopNFinalize:
            return builtinAggTopBottomNFinalize(arity);
        case Builtin::aggBottomN:
            return builtinAggTopBottomN<TopBottomSense::kBottom>(arity);
        case Builtin::aggBottomNArray:
            return builtinAggTopBottomNArray<TopBottomSense::kBottom>(arity);
        case Builtin::aggBottomNMerge:
            return builtinAggTopBottomNMerge<TopBottomSense::kBottom>(arity);
        case Builtin::aggBottomNFinalize:
            return builtinAggTopBottomNFinalize(arity);
        case Builtin::aggMaxN:
            return builtinAggMinMaxN<AccumulatorMinMaxN::MinMaxSense::kMax>(arity);
        case Builtin::aggMaxNMerge:
            return builtinAggMinMaxNMerge<AccumulatorMinMaxN::MinMaxSense::kMax>(arity);
        case Builtin::aggMaxNFinalize:
            return builtinAggMinMaxNFinalize<AccumulatorMinMaxN::MinMaxSense::kMax>(arity);
        case Builtin::aggMinN:
            return builtinAggMinMaxN<AccumulatorMinMaxN::MinMaxSense::kMin>(arity);
        case Builtin::aggMinNMerge:
            return builtinAggMinMaxNMerge<AccumulatorMinMaxN::MinMaxSense::kMin>(arity);
        case Builtin::aggMinNFinalize:
            return builtinAggMinMaxNFinalize<AccumulatorMinMaxN::MinMaxSense::kMin>(arity);
        case Builtin::aggRank:
            return builtinAggRank(arity);
        case Builtin::aggRankColl:
            return builtinAggRankColl(arity);
        case Builtin::aggDenseRank:
            return builtinAggDenseRank(arity);
        case Builtin::aggDenseRankColl:
            return builtinAggDenseRankColl(arity);
        case Builtin::aggRankFinalize:
            return builtinAggRankFinalize(arity);
        case Builtin::aggExpMovingAvg:
            return builtinAggExpMovingAvg(arity);
        case Builtin::aggExpMovingAvgFinalize:
            return builtinAggExpMovingAvgFinalize(arity);
        case Builtin::aggRemovableSumAdd:
            return builtinAggRemovableSum<1 /*sign*/>(arity);
        case Builtin::aggRemovableSumRemove:
            return builtinAggRemovableSum<-1 /*sign*/>(arity);
        case Builtin::aggRemovableSumFinalize:
            return builtinAggRemovableSumFinalize(arity);
        case Builtin::aggIntegralInit:
            return builtinAggIntegralInit(arity);
        case Builtin::aggIntegralAdd:
            return builtinAggIntegralAdd(arity);
        case Builtin::aggIntegralRemove:
            return builtinAggIntegralRemove(arity);
        case Builtin::aggIntegralFinalize:
            return builtinAggIntegralFinalize(arity);
        case Builtin::aggDerivativeFinalize:
            return builtinAggDerivativeFinalize(arity);
        case Builtin::aggCovarianceAdd:
            return builtinAggCovarianceAdd(arity);
        case Builtin::aggCovarianceRemove:
            return builtinAggCovarianceRemove(arity);
        case Builtin::aggCovarianceSampFinalize:
            return builtinAggCovarianceSampFinalize(arity);
        case Builtin::aggCovariancePopFinalize:
            return builtinAggCovariancePopFinalize(arity);
        case Builtin::aggRemovablePushAdd:
            return builtinAggRemovablePushAdd(arity);
        case Builtin::aggRemovablePushRemove:
            return builtinAggRemovablePushRemove(arity);
        case Builtin::aggRemovablePushFinalize:
            return builtinAggRemovablePushFinalize(arity);
        case Builtin::aggRemovableStdDevAdd:
            return builtinAggRemovableStdDevAdd(arity);
        case Builtin::aggRemovableStdDevRemove:
            return builtinAggRemovableStdDevRemove(arity);
        case Builtin::aggRemovableStdDevSampFinalize:
            return builtinAggRemovableStdDevSampFinalize(arity);
        case Builtin::aggRemovableStdDevPopFinalize:
            return builtinAggRemovableStdDevPopFinalize(arity);
        case Builtin::aggRemovableAvgFinalize:
            return builtinAggRemovableAvgFinalize(arity);
        case Builtin::aggRemovableFirstNInit:
            return builtinAggFirstLastNInit(arity);
        case Builtin::aggRemovableFirstNAdd:
            return builtinAggFirstLastNAdd(arity);
        case Builtin::aggRemovableFirstNRemove:
            return builtinAggFirstLastNRemove(arity);
        case Builtin::aggRemovableFirstNFinalize:
            return builtinAggFirstLastNFinalize<AccumulatorFirstLastN::Sense::kFirst>(arity);
        case Builtin::aggRemovableLastNInit:
            return builtinAggFirstLastNInit(arity);
        case Builtin::aggRemovableLastNAdd:
            return builtinAggFirstLastNAdd(arity);
        case Builtin::aggRemovableLastNRemove:
            return builtinAggFirstLastNRemove(arity);
        case Builtin::aggRemovableLastNFinalize:
            return builtinAggFirstLastNFinalize<AccumulatorFirstLastN::Sense::kLast>(arity);
        case Builtin::aggRemovableSetCommonInit:
            return builtinAggRemovableSetCommonInit(arity);
        case Builtin::aggRemovableSetCommonCollInit:
            return builtinAggRemovableSetCommonCollInit(arity);
        case Builtin::aggRemovableAddToSetAdd:
            return builtinAggRemovableAddToSetAdd(arity);
        case Builtin::aggRemovableAddToSetRemove:
            return builtinAggRemovableAddToSetRemove(arity);
        case Builtin::aggRemovableSetUnionAdd:
            return builtinAggRemovableSetUnionAdd(arity);
        case Builtin::aggRemovableSetUnionRemove:
            return builtinAggRemovableSetUnionRemove(arity);
        case Builtin::aggRemovableSetCommonFinalize:
            return builtinAggRemovableSetCommonFinalize(arity);
        case Builtin::aggRemovableMinMaxNCollInit:
            return builtinAggRemovableMinMaxNCollInit(arity);
        case Builtin::aggRemovableMinMaxNInit:
            return builtinAggRemovableMinMaxNInit(arity);
        case Builtin::aggRemovableMinMaxNAdd:
            return builtinAggRemovableMinMaxNAdd(arity);
        case Builtin::aggRemovableMinMaxNRemove:
            return builtinAggRemovableMinMaxNRemove(arity);
        case Builtin::aggRemovableMinNFinalize:
            return builtinAggRemovableMinMaxNFinalize<AccumulatorMinMaxN::MinMaxSense::kMin>(arity);
        case Builtin::aggRemovableMaxNFinalize:
            return builtinAggRemovableMinMaxNFinalize<AccumulatorMinMaxN::MinMaxSense::kMax>(arity);
        case Builtin::aggRemovableTopNInit:
        case Builtin::aggRemovableBottomNInit:
            return builtinAggRemovableTopBottomNInit(arity);
        case Builtin::aggRemovableTopNAdd:
        case Builtin::aggRemovableBottomNAdd:
            return builtinAggRemovableTopBottomNAdd(arity);
        case Builtin::aggRemovableTopNRemove:
        case Builtin::aggRemovableBottomNRemove:
            return builtinAggRemovableTopBottomNRemove(arity);
        case Builtin::aggRemovableTopNFinalize:
            return builtinAggRemovableTopBottomNFinalize<TopBottomSense::kTop>(arity);
        case Builtin::aggRemovableBottomNFinalize:
            return builtinAggRemovableTopBottomNFinalize<TopBottomSense::kBottom>(arity);
        case Builtin::aggLinearFillCanAdd:
            return builtinAggLinearFillCanAdd(arity);
        case Builtin::aggLinearFillAdd:
            return builtinAggLinearFillAdd(arity);
        case Builtin::aggLinearFillFinalize:
            return builtinAggLinearFillFinalize(arity);
        case Builtin::valueBlockExists:
            return builtinValueBlockExists(arity);
        case Builtin::valueBlockTypeMatch:
            return builtinValueBlockTypeMatch(arity);
        case Builtin::valueBlockIsTimezone:
            return builtinValueBlockIsTimezone(arity);
        case Builtin::valueBlockFillEmpty:
            return builtinValueBlockFillEmpty(arity);
        case Builtin::valueBlockFillEmptyBlock:
            return builtinValueBlockFillEmptyBlock(arity);
        case Builtin::valueBlockFillType:
            return builtinValueBlockFillType(arity);
        case Builtin::valueBlockAggMin:
            return builtinValueBlockAggMin(arity);
        case Builtin::valueBlockAggMax:
            return builtinValueBlockAggMax(arity);
        case Builtin::valueBlockAggCount:
            return builtinValueBlockAggCount(arity);
        case Builtin::valueBlockAggSum:
            return builtinValueBlockAggSum(arity);
        case Builtin::valueBlockAggDoubleDoubleSum:
            return builtinValueBlockAggDoubleDoubleSum(arity);
        case Builtin::valueBlockAggTopN:
            return ByteCode::builtinValueBlockAggTopN(arity);
        case Builtin::valueBlockAggTopNArray:
            return ByteCode::builtinValueBlockAggTopNArray(arity);
        case Builtin::valueBlockAggBottomN:
            return ByteCode::builtinValueBlockAggBottomN(arity);
        case Builtin::valueBlockAggBottomNArray:
            return ByteCode::builtinValueBlockAggBottomNArray(arity);
        case Builtin::valueBlockDateDiff:
            return builtinValueBlockDateDiff(arity);
        case Builtin::valueBlockDateTrunc:
            return builtinValueBlockDateTrunc(arity);
        case Builtin::valueBlockDateAdd:
            return builtinValueBlockDateAdd(arity);
        case Builtin::valueBlockTrunc:
            return builtinValueBlockTrunc(arity);
        case Builtin::valueBlockRound:
            return builtinValueBlockRound(arity);
        case Builtin::valueBlockAdd:
            return builtinValueBlockAdd(arity);
        case Builtin::valueBlockSub:
            return builtinValueBlockSub(arity);
        case Builtin::valueBlockMult:
            return builtinValueBlockMult(arity);
        case Builtin::valueBlockDiv:
            return builtinValueBlockDiv(arity);
        case Builtin::valueBlockGtScalar:
            return builtinValueBlockGtScalar(arity);
        case Builtin::valueBlockGteScalar:
            return builtinValueBlockGteScalar(arity);
        case Builtin::valueBlockEqScalar:
            return builtinValueBlockEqScalar(arity);
        case Builtin::valueBlockNeqScalar:
            return builtinValueBlockNeqScalar(arity);
        case Builtin::valueBlockLtScalar:
            return builtinValueBlockLtScalar(arity);
        case Builtin::valueBlockLteScalar:
            return builtinValueBlockLteScalar(arity);
        case Builtin::valueBlockCmp3wScalar:
            return builtinValueBlockCmp3wScalar(arity);
        case Builtin::valueBlockCombine:
            return builtinValueBlockCombine(arity);
        case Builtin::valueBlockLogicalAnd:
            return builtinValueBlockLogicalAnd(arity);
        case Builtin::valueBlockLogicalOr:
            return builtinValueBlockLogicalOr(arity);
        case Builtin::valueBlockLogicalNot:
            return builtinValueBlockLogicalNot(arity);
        case Builtin::valueBlockNewFill:
            return builtinValueBlockNewFill(arity);
        case Builtin::valueBlockSize:
            return builtinValueBlockSize(arity);
        case Builtin::valueBlockNone:
            return builtinValueBlockNone(arity);
        case Builtin::valueBlockIsMember:
            return builtinValueBlockIsMember(arity);
        case Builtin::valueBlockCoerceToBool:
            return builtinValueBlockCoerceToBool(arity);
        case Builtin::valueBlockMod:
            return builtinValueBlockMod(arity);
        case Builtin::valueBlockConvert:
            return builtinValueBlockConvert(arity);
        case Builtin::valueBlockGetSortKeyAsc:
            return builtinValueBlockGetSortKeyAsc(arity);
        case Builtin::valueBlockGetSortKeyDesc:
            return builtinValueBlockGetSortKeyDesc(arity);
        case Builtin::cellFoldValues_F:
            return builtinCellFoldValues_F(arity);
        case Builtin::cellFoldValues_P:
            return builtinCellFoldValues_P(arity);
        case Builtin::cellBlockGetFlatValuesBlock:
            return builtinCellBlockGetFlatValuesBlock(arity);
    }

    MONGO_UNREACHABLE;
}  // ByteCode::dispatchBuiltin

}  // namespace vm
}  // namespace sbe
}  // namespace mongo
