1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 14:57:35 +00:00

LibRegex: Make get_opcode() return a reference

Previously this would return a pointer which could be null if the
requested opcode was invalid. This should never be the case though
so let's VERIFY() that instead.
This commit is contained in:
Gunnar Beutner 2021-06-13 22:18:54 +02:00 committed by Ali Mohammad Pur
parent cd49fb0229
commit 281f39073d
4 changed files with 24 additions and 37 deletions

View file

@ -90,7 +90,7 @@ static const char* character_class_name(CharClass ch_class)
OwnPtr<OpCode> ByteCode::s_opcodes[(size_t)OpCodeId::Last + 1]; OwnPtr<OpCode> ByteCode::s_opcodes[(size_t)OpCodeId::Last + 1];
bool ByteCode::s_opcodes_initialized { false }; bool ByteCode::s_opcodes_initialized { false };
ALWAYS_INLINE OpCode* ByteCode::get_opcode_by_id(OpCodeId id) const ALWAYS_INLINE OpCode& ByteCode::get_opcode_by_id(OpCodeId id) const
{ {
if (!s_opcodes_initialized) { if (!s_opcodes_initialized) {
for (u32 i = (u32)OpCodeId::First; i <= (u32)OpCodeId::Last; ++i) { for (u32 i = (u32)OpCodeId::First; i <= (u32)OpCodeId::Last; ++i) {
@ -148,27 +148,24 @@ ALWAYS_INLINE OpCode* ByteCode::get_opcode_by_id(OpCodeId id) const
s_opcodes_initialized = true; s_opcodes_initialized = true;
} }
if (id > OpCodeId::Last) VERIFY(id >= OpCodeId::First && id <= OpCodeId::Last);
return nullptr;
auto* opcode = &*s_opcodes[(u32)id]; auto& opcode = s_opcodes[(u32)id];
opcode->set_bytecode(*const_cast<ByteCode*>(this)); opcode->set_bytecode(*const_cast<ByteCode*>(this));
return opcode; return *opcode;
} }
OpCode* ByteCode::get_opcode(MatchState& state) const OpCode& ByteCode::get_opcode(MatchState& state) const
{ {
OpCode* op_code; OpCodeId opcode_id;
if (state.instruction_position >= size())
opcode_id = OpCodeId::Exit;
else
opcode_id = (OpCodeId)at(state.instruction_position);
if (state.instruction_position >= size()) { auto& opcode = get_opcode_by_id(opcode_id);
op_code = get_opcode_by_id(OpCodeId::Exit); opcode.set_state(state);
} else return opcode;
op_code = get_opcode_by_id((OpCodeId)at(state.instruction_position));
if (op_code)
op_code->set_state(state);
return op_code;
} }
ALWAYS_INLINE ExecutionResult OpCode_Exit::execute(const MatchInput& input, MatchState& state, MatchOutput&) const ALWAYS_INLINE ExecutionResult OpCode_Exit::execute(const MatchInput& input, MatchState& state, MatchOutput&) const

View file

@ -439,7 +439,7 @@ public:
bytecode_to_repeat = move(bytecode); bytecode_to_repeat = move(bytecode);
} }
OpCode* get_opcode(MatchState& state) const; OpCode& get_opcode(MatchState& state) const;
private: private:
void insert_string(const StringView& view) void insert_string(const StringView& view)
@ -449,7 +449,7 @@ private:
empend((ByteCodeValueType)view[i]); empend((ByteCodeValueType)view[i]);
} }
ALWAYS_INLINE OpCode* get_opcode_by_id(OpCodeId id) const; ALWAYS_INLINE OpCode& get_opcode_by_id(OpCodeId id) const;
static OwnPtr<OpCode> s_opcodes[(size_t)OpCodeId::Last + 1]; static OwnPtr<OpCode> s_opcodes[(size_t)OpCodeId::Last + 1];
static bool s_opcodes_initialized; static bool s_opcodes_initialized;
}; };

View file

@ -39,19 +39,14 @@ public:
auto& bytecode = regex.parser_result.bytecode; auto& bytecode = regex.parser_result.bytecode;
for (;;) { for (;;) {
auto* opcode = bytecode.get_opcode(state); auto& opcode = bytecode.get_opcode(state);
if (!opcode) { print_opcode("PrintBytecode", opcode, state);
dbgln("Wrong opcode... failed!");
return;
}
print_opcode("PrintBytecode", *opcode, state);
out(m_file, "{}", m_debug_stripline); out(m_file, "{}", m_debug_stripline);
if (is<OpCode_Exit>(*opcode)) if (is<OpCode_Exit>(opcode))
break; break;
state.instruction_position += opcode->size(); state.instruction_position += opcode.size();
} }
fflush(m_file); fflush(m_file);

View file

@ -301,15 +301,10 @@ Optional<bool> Matcher<Parser>::execute(const MatchInput& input, MatchState& sta
for (;;) { for (;;) {
++output.operations; ++output.operations;
auto* opcode = bytecode.get_opcode(state); auto& opcode = bytecode.get_opcode(state);
if (!opcode) {
dbgln("Wrong opcode... failed!");
return {};
}
#if REGEX_DEBUG #if REGEX_DEBUG
s_regex_dbg.print_opcode("VM", *opcode, state, recursion_level, false); s_regex_dbg.print_opcode("VM", opcode, state, recursion_level, false);
#endif #endif
ExecutionResult result; ExecutionResult result;
@ -317,14 +312,14 @@ Optional<bool> Matcher<Parser>::execute(const MatchInput& input, MatchState& sta
--input.fail_counter; --input.fail_counter;
result = ExecutionResult::Failed_ExecuteLowPrioForks; result = ExecutionResult::Failed_ExecuteLowPrioForks;
} else { } else {
result = opcode->execute(input, state, output); result = opcode.execute(input, state, output);
} }
#if REGEX_DEBUG #if REGEX_DEBUG
s_regex_dbg.print_result(*opcode, bytecode, input, state, result); s_regex_dbg.print_result(opcode, bytecode, input, state, result);
#endif #endif
state.instruction_position += opcode->size(); state.instruction_position += opcode.size();
switch (result) { switch (result) {
case ExecutionResult::Fork_PrioLow: case ExecutionResult::Fork_PrioLow: