SERVER-119194 Default initialize SBE VM dispatch table to lastInstruc… (#48867)
GitOrigin-RevId: dcf4dad12c450670a512d1c0807ab316c768ff4d
This commit is contained in:
committed by
MongoDB Bot
parent
54ff814ae2
commit
af5ca36132
@@ -31,6 +31,8 @@
|
|||||||
#include "mongo/db/exec/sbe/expressions/runtime_environment.h"
|
#include "mongo/db/exec/sbe/expressions/runtime_environment.h"
|
||||||
#include "mongo/db/exec/sbe/values/slot.h"
|
#include "mongo/db/exec/sbe/values/slot.h"
|
||||||
#include "mongo/db/exec/sbe/vm/vm.h"
|
#include "mongo/db/exec/sbe/vm/vm.h"
|
||||||
|
#include "mongo/db/exec/sbe/vm/vm_instruction.h"
|
||||||
|
#include "mongo/unittest/death_test.h"
|
||||||
#include "mongo/unittest/unittest.h"
|
#include "mongo/unittest/unittest.h"
|
||||||
|
|
||||||
namespace mongo {
|
namespace mongo {
|
||||||
@@ -66,4 +68,15 @@ TEST(CodeFragmentTest, TestPushOwnedAccessorVal) {
|
|||||||
ASSERT(res.tag() == testTag);
|
ASSERT(res.tag() == testTag);
|
||||||
ASSERT(res.value() == testValue);
|
ASSERT(res.value() == testValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEATH_TEST(SBEVMBytecodeValidationDeathTest,
|
||||||
|
InvalidOpcodeTriggersUnreachable,
|
||||||
|
"SBE lastInstruction VM opcode") {
|
||||||
|
constexpr uint8_t kInvalidOpcode = static_cast<uint8_t>(sbe::vm::Instruction::lastInstruction);
|
||||||
|
sbe::vm::CodeFragment code;
|
||||||
|
code.instrs().resize(1, kInvalidOpcode);
|
||||||
|
sbe::vm::ByteCode interpreter;
|
||||||
|
interpreter.run(&code);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace mongo
|
} // namespace mongo
|
||||||
|
|||||||
@@ -36,6 +36,8 @@
|
|||||||
#include "mongo/db/exec/sbe/vm/vm.h"
|
#include "mongo/db/exec/sbe/vm/vm.h"
|
||||||
#include "mongo/db/query/collation/collation_index_key.h"
|
#include "mongo/db/query/collation/collation_index_key.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
#define MONGO_LOGV2_DEFAULT_COMPONENT ::mongo::logv2::LogComponent::kQuery
|
#define MONGO_LOGV2_DEFAULT_COMPONENT ::mongo::logv2::LogComponent::kQuery
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
@@ -255,110 +257,127 @@ void ByteCode::runLambdaInternal(const CodeFragment* code, int64_t position) {
|
|||||||
popAndReleaseStack();
|
popAndReleaseStack();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
using DispatchTable = std::array<void*, std::numeric_limits<decltype(Instruction::tag)>::max() + 1>;
|
||||||
|
|
||||||
|
constexpr DispatchTable defaultInitializeDispatchTable(void* lastInstructionAddr,
|
||||||
|
DispatchTable initial) {
|
||||||
|
DispatchTable ret{};
|
||||||
|
std::fill(ret.begin() + Instruction::lastInstruction, ret.end(), lastInstructionAddr);
|
||||||
|
for (auto i = 0; i < Instruction::lastInstruction; i++) {
|
||||||
|
ret[i] = initial[i];
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
} // namespace
|
||||||
|
|
||||||
void ByteCode::runInternal(const CodeFragment* code, int64_t position) {
|
void ByteCode::runInternal(const CodeFragment* code, int64_t position) {
|
||||||
#if USE_THREADED_INTERPRETER
|
#if USE_THREADED_INTERPRETER
|
||||||
// Very important this in sync with Instruction::Tags.
|
// Very important this in sync with Instruction::Tags.
|
||||||
static constexpr void* dispatchTable[std::numeric_limits<decltype(Instruction::tag)>::max() +
|
constexpr DispatchTable dispatchTable =
|
||||||
1] = {&&do_pushConstVal,
|
defaultInitializeDispatchTable(&&do_lastInstruction,
|
||||||
&&do_pushAccessVal,
|
{&&do_pushConstVal,
|
||||||
&&do_pushOwnedAccessorVal,
|
&&do_pushAccessVal,
|
||||||
&&do_pushEnvAccessorVal,
|
&&do_pushOwnedAccessorVal,
|
||||||
&&do_pushMoveVal,
|
&&do_pushEnvAccessorVal,
|
||||||
&&do_pushLocalVal,
|
&&do_pushMoveVal,
|
||||||
&&do_pushMoveLocalVal,
|
&&do_pushLocalVal,
|
||||||
&&do_pushOneArgLambda,
|
&&do_pushMoveLocalVal,
|
||||||
&&do_pushTwoArgLambda,
|
&&do_pushOneArgLambda,
|
||||||
&&do_pop,
|
&&do_pushTwoArgLambda,
|
||||||
&&do_swap,
|
&&do_pop,
|
||||||
&&do_makeOwn,
|
&&do_swap,
|
||||||
|
&&do_makeOwn,
|
||||||
|
|
||||||
&&do_add,
|
&&do_add,
|
||||||
&&do_sub,
|
&&do_sub,
|
||||||
&&do_mul,
|
&&do_mul,
|
||||||
&&do_div,
|
&&do_div,
|
||||||
&&do_idiv,
|
&&do_idiv,
|
||||||
&&do_mod,
|
&&do_mod,
|
||||||
&&do_negate,
|
&&do_negate,
|
||||||
&&do_numConvert,
|
&&do_numConvert,
|
||||||
|
|
||||||
&&do_logicNot,
|
&&do_logicNot,
|
||||||
|
|
||||||
&&do_less,
|
&&do_less,
|
||||||
&&do_lessEq,
|
&&do_lessEq,
|
||||||
&&do_greater,
|
&&do_greater,
|
||||||
&&do_greaterEq,
|
&&do_greaterEq,
|
||||||
&&do_eq,
|
&&do_eq,
|
||||||
&&do_neq,
|
&&do_neq,
|
||||||
|
|
||||||
&&do_cmp3w,
|
&&do_cmp3w,
|
||||||
|
|
||||||
&&do_collLess,
|
&&do_collLess,
|
||||||
&&do_collLessEq,
|
&&do_collLessEq,
|
||||||
&&do_collGreater,
|
&&do_collGreater,
|
||||||
&&do_collGreaterEq,
|
&&do_collGreaterEq,
|
||||||
&&do_collEq,
|
&&do_collEq,
|
||||||
&&do_collNeq,
|
&&do_collNeq,
|
||||||
&&do_collCmp3w,
|
&&do_collCmp3w,
|
||||||
|
|
||||||
&&do_fillEmpty,
|
&&do_fillEmpty,
|
||||||
&&do_fillEmptyImm,
|
&&do_fillEmptyImm,
|
||||||
&&do_getField,
|
&&do_getField,
|
||||||
&&do_getFieldImm,
|
&&do_getFieldImm,
|
||||||
&&do_getElement,
|
&&do_getElement,
|
||||||
&&do_collComparisonKey,
|
&&do_collComparisonKey,
|
||||||
&&do_getFieldOrElement,
|
&&do_getFieldOrElement,
|
||||||
&&do_traverseP,
|
&&do_traverseP,
|
||||||
&&do_traversePImm,
|
&&do_traversePImm,
|
||||||
&&do_traverseF,
|
&&do_traverseF,
|
||||||
&&do_traverseFImm,
|
&&do_traverseFImm,
|
||||||
&&do_magicTraverseF,
|
&&do_magicTraverseF,
|
||||||
&&do_setField,
|
&&do_setField,
|
||||||
&&do_getArraySize,
|
&&do_getArraySize,
|
||||||
|
|
||||||
&&do_aggSum,
|
&&do_aggSum,
|
||||||
&&do_aggCount,
|
&&do_aggCount,
|
||||||
&&do_aggMin,
|
&&do_aggMin,
|
||||||
&&do_aggMax,
|
&&do_aggMax,
|
||||||
&&do_aggFirst,
|
&&do_aggFirst,
|
||||||
&&do_aggLast,
|
&&do_aggLast,
|
||||||
|
|
||||||
&&do_aggCollMin,
|
&&do_aggCollMin,
|
||||||
&&do_aggCollMax,
|
&&do_aggCollMax,
|
||||||
|
|
||||||
&&do_exists,
|
&&do_exists,
|
||||||
&&do_isNull,
|
&&do_isNull,
|
||||||
&&do_isObject,
|
&&do_isObject,
|
||||||
&&do_isArray,
|
&&do_isArray,
|
||||||
&&do_isInList,
|
&&do_isInList,
|
||||||
&&do_isString,
|
&&do_isString,
|
||||||
&&do_isNumber,
|
&&do_isNumber,
|
||||||
&&do_isBinData,
|
&&do_isBinData,
|
||||||
&&do_isDate,
|
&&do_isDate,
|
||||||
&&do_isNaN,
|
&&do_isNaN,
|
||||||
&&do_isInfinity,
|
&&do_isInfinity,
|
||||||
&&do_isRecordId,
|
&&do_isRecordId,
|
||||||
&&do_isMinKey,
|
&&do_isMinKey,
|
||||||
&&do_isMaxKey,
|
&&do_isMaxKey,
|
||||||
&&do_isTimestamp,
|
&&do_isTimestamp,
|
||||||
&&do_isKeyString,
|
&&do_isKeyString,
|
||||||
&&do_typeMatchImm,
|
&&do_typeMatchImm,
|
||||||
|
|
||||||
&&do_function,
|
&&do_function,
|
||||||
&&do_functionSmall,
|
&&do_functionSmall,
|
||||||
|
|
||||||
&&do_jmp,
|
&&do_jmp,
|
||||||
&&do_jmpTrue,
|
&&do_jmpTrue,
|
||||||
&&do_jmpFalse,
|
&&do_jmpFalse,
|
||||||
&&do_jmpNothing,
|
&&do_jmpNothing,
|
||||||
&&do_jmpNotNothing,
|
&&do_jmpNotNothing,
|
||||||
&&do_ret,
|
&&do_ret,
|
||||||
&&do_allocStack,
|
&&do_allocStack,
|
||||||
|
|
||||||
&&do_fail,
|
&&do_fail,
|
||||||
|
|
||||||
&&do_dateTruncImm,
|
&&do_dateTruncImm,
|
||||||
|
|
||||||
&&do_valueBlockApplyLambda};
|
&&do_valueBlockApplyLambda});
|
||||||
|
static_assert(std::none_of(
|
||||||
|
dispatchTable.begin(), dispatchTable.end(), [](void* p) { return p == nullptr; }));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
auto pcPointer = code->instrs().data() + position;
|
auto pcPointer = code->instrs().data() + position;
|
||||||
@@ -1472,6 +1491,15 @@ void ByteCode::runInternal(const CodeFragment* code, int64_t position) {
|
|||||||
valueBlockApplyLambda(code);
|
valueBlockApplyLambda(code);
|
||||||
}
|
}
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
|
INSTRUCTION(lastInstruction) {
|
||||||
|
// Invalid opcode; log and kill the process. Field names are PII, so only log opcode tags.
|
||||||
|
LOGV2_ERROR(11919400,
|
||||||
|
"Invalid SBE VM bytecode",
|
||||||
|
"bytecode in hexadecimal"_attr = hexblob::encode(
|
||||||
|
code->instrs().data(), code->instrs().size() * sizeof(uint8_t)));
|
||||||
|
tasserted(11919401, "SBE lastInstruction VM opcode");
|
||||||
|
}
|
||||||
|
DISPATCH();
|
||||||
#if USE_THREADED_INTERPRETER
|
#if USE_THREADED_INTERPRETER
|
||||||
#else
|
#else
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user