Added wipeToInit method to virtual machine, fixed some bugs, removed debug output

This commit is contained in:
Андреев Григорий 2024-08-03 22:48:40 +03:00
parent 96cf8e96c1
commit 807d311c15
20 changed files with 214 additions and 151 deletions

View File

@ -14,7 +14,7 @@ struct Libregexis024BuildSystem {
"-Wno-unused-but-set-variable", "-Wno-reorder"};
std::vector<std::string> version_flags = {"--std", "c++14", "-D", "_POSIX_C_SOURCE=200809L"};
std::vector<std::string> debug_defines_release = {"_GLIBCXX_DEBUG"};
std::vector<std::string> debug_defines_release = {};
std::vector<std::string> debug_defines_debug = {"_GLIBCXX_DEBUG", "LIBREGEXIS024_DEBUG", "LIBREGEXIS024_ALLOW_LOUD"};
std::vector<std::string> opt_flags_release = {"-g", "-O2"};
std::vector<std::string> opt_flags_debug = {"-g", "-ggdb", "-O0"};
@ -79,6 +79,7 @@ struct Libregexis024BuildSystem {
"libregexis024sol/expr_parse_functions/command_recognition.cpp",
"libregexis024tools/stringmatching.cpp",
"libregexis024tools/delayed_matching.cpp",
};
/* These are added to compilation_units_of_release */
@ -102,6 +103,7 @@ struct Libregexis024BuildSystem {
"libregexis024sol/expr_compiler.h",
"libregexis024tools/stringmatching.h",
"libregexis024tools/delayed_matching.h",
};
CTarget T{"libregexis024", "shared_library"};
@ -131,14 +133,14 @@ struct Libregexis024BuildSystem {
int main(int argc, char** argv) {
try {
assert(argc > 0);
ASSERT_pl(argc > 0);
std::vector<std::string> args(argc - 1);
for (int i = 0; i + 1 < argc; i++) {
args[i] = argv[i + 1];
}
NormalCBuildSystemCommandMeaning cmd;
regular_bs_cli_cmd_interpret(args, cmd);
Libregexis024BuildSystem bs("debug", cmd);
Libregexis024BuildSystem bs("release", cmd);
if (cmd.need_to_build)
complete_tasks_of_build_units(bs.runlevel_1);
if (cmd.need_to_install)

View File

@ -198,7 +198,7 @@ namespace regexis024 {
std::string infoText;
for (auto& p: ktr.track_names){
const SubtrackingNameInfo& tu = ktr.retrieval_info[p.second];
const SubtrackingNameUsageInfo& tu = ktr.retrieval_info[p.second];
auto getRole = [](bool presence, tracking_var_type_t type, int first, int second,
const std::string& ARR_NAME) -> std::string {

View File

@ -4,6 +4,8 @@
#include <stdint.h>
#include <libregexis024vm/vm_opcodes_types.h>
#include <vector>
#include <stddef.h>
namespace regexis024 {
void write_byte(std::vector<uint8_t>& result, uint8_t x);
void write_word(std::vector<uint8_t>& result, uint16_t x);

View File

@ -1,6 +1,9 @@
#ifndef LIBREGEXIS024_SRC_LIBREGEXIS024FA_TRACKING_VARIABLES_H
#define LIBREGEXIS024_SRC_LIBREGEXIS024FA_TRACKING_VARIABLES_H
#include <map>
#include <string>
namespace regexis024 {
namespace tracking_var_types {
enum tracking_var_type_I {
@ -11,6 +14,21 @@ namespace regexis024 {
}
typedef tracking_var_types::tracking_var_type_I tracking_var_type_t;
struct TrackingVariableInfo {
bool stored_in_ca = true;
bool stored_in_sa = false;
tracking_var_type_t type;
/* These fields will be -1 if unused */
int colarr_first = -1;
int colarr_second = -1;
int selarr_first = -1;
int selarr_second = -1;
};
typedef std::map<std::string, TrackingVariableInfo> track_var_list;
}
#endif

View File

@ -138,7 +138,7 @@ namespace regexis024 {
chekushka BracketLvl_ParseCall::firstTime(REGEX_IS024_MeaningContext& ctx, ParsingContext& pctx, FA_Container& fa) {
result.assertDefault();
assert(readChar(ctx) == U'(');
/* sequence lvl already took care about resolving name and configuring SubtrackingNameInfo */
/* sequence lvl already took care about resolving name and configuring SubtrackingNameUsageInfo */
if (namedSubexpressionId >= 0){
assert(ctx.ktr.retrieval_info[namedSubexpressionId].type == tracking_var_types::range);
if (ctx.ktr.retrieval_info[namedSubexpressionId].stored_in_sa){
@ -157,7 +157,7 @@ namespace regexis024 {
readChar(ctx);
result = tmp_ret_buff;
if (namedSubexpressionId >= 0) {
SubtrackingNameInfo& tai_slots = ctx.ktr.retrieval_info[namedSubexpressionId];
SubtrackingNameUsageInfo& tai_slots = ctx.ktr.retrieval_info[namedSubexpressionId];
if (tai_slots.stored_in_ca){
assert(tai_slots.colarr_first >= 0 && tai_slots.colarr_first < UINT16_MAX);
assert(tai_slots.colarr_second >= 0 && tai_slots.colarr_second < UINT16_MAX);
@ -214,7 +214,7 @@ namespace regexis024 {
}
}
/* Generating priority table (sifting program) */
for (const SubtrackingNameInfo& sni: ctx.ktr.retrieval_info) {
for (const SubtrackingNameUsageInfo& sni: ctx.ktr.retrieval_info) {
if (!sni.discovered)
aux_THROW("tracking tool named in !select is not used anywhere");
if (sni.used_in_sifting) {

View File

@ -20,7 +20,7 @@ report(ctx, ("regex: " + ARR_NAME + ": key namespace overflow").c_str()); return
void ensure_space_for_track_unit(REGEX_IS024_MeaningContext &ctx, const std::string& name, tracking_var_type_t type) {
size_t id = ctx.ktr.track_names[name];
/* Size of this verctor won't be changed. THis is a safe reference */
SubtrackingNameInfo& info = ctx.ktr.retrieval_info[id];
SubtrackingNameUsageInfo& info = ctx.ktr.retrieval_info[id];
if (!info.discovered){
info.type = type;
if (info.stored_in_ca) {

View File

@ -7,7 +7,7 @@
#include <libregexis024fa/tracking_variables.h>
namespace regexis024 {
struct SubtrackingNameInfo{
struct SubtrackingNameUsageInfo: public TrackingVariableInfo{
bool stored_in_ca = true;
bool stored_in_sa = false;
@ -25,7 +25,7 @@ namespace regexis024 {
struct KnownTrackingTools {
std::map<std::string, int64_t> track_names;
std::vector<SubtrackingNameInfo> retrieval_info;
std::vector<SubtrackingNameUsageInfo> retrieval_info;
};
}

View File

@ -76,7 +76,6 @@ namespace regexis024 {
assert(patient.start);
for (FA_Node** end: patient.ends){
assert(!(*end));
printf("DEBUG %lu->->->->->%lu\n", patient.start->nodeId, node->nodeId);
reattach_fa_node_edge(end, node);
}
}

View File

@ -2,6 +2,7 @@
#include <assert.h>
#include <stdexcept>
#include <libregexis024sol/expr_compiler.h>
#include <libregexis024tools/delayed_matching.h>
using namespace regexis024;
using namespace std;
@ -20,13 +21,45 @@ void test(const string& input, const string& pattern, const MatchInfo& right_ans
printf("Test passed\n");
}
void boba(const vector<pair<string, bool>>& input, const string& pattern) {
std::vector<uint8_t> regexp_program;
std::map<std::string, TrackingVariableInfo> variables;
std::string error;
int ret = compile(pattern, variables, regexp_program, error);
if (ret < 0) {
throw runtime_error("Compilation failure " + error);
}
VirtualMachine vm(regexp_program.size(), regexp_program.data(),
UINT64_MAX, UINT16_MAX,
UINT32_MAX, UINT32_MAX, UINT64_MAX);
if (vm.initialize() < 0) {
throw runtime_error("Can't initialize");
}
for (int i = 0; i < 3; i++) {
for (auto& inp: input) {
vm.wipeToInit();
if (vm.addNewMatchingThread() < 0)
throw runtime_error("addNewMatchingThread");
for (char ch: inp.first) {
if (vm.feedCharacter(ch, 1) < 0)
throw runtime_error("feedCharacter");
}
if (vm.isMatched() != inp.second)
throw runtime_error("AAAAAAAAAAAAAAAA");
}
}
}
int main() {
boba({{"", true}, {"a", false}}, "");
boba({{"", true}, {"a", true}, {"aab", true}, {"aac", false}, {"c", false}, {"abbababa", true}}, "[ab]*");
test("", "", MatchInfo({}, {}));
test("a", "a", MatchInfo({}, {}));
test("1b", "1\\<b", MatchInfo({}, {}));
test("bababbaa", "[ab]*", MatchInfo({}, {}));
test("bababbaa", "!dfa;[ab]*", MatchInfo({}, {}));
test("d3", "[abc]3", MatchInfo());
test("a3", "[abc]3", MatchInfo({}, {}));
test("", "", MatchInfo({}, {}));
test("a", "a", MatchInfo({}, {}));
test("abba", "!select{M{max}}a#M(b*)a", MatchInfo({}, {1, 3}));
test("LINE\r\nFirst:Second\r\nThird:12\r\n\r\n",

View File

@ -0,0 +1,19 @@
#include "delayed_matching.h"
#include <libregexis024sol/expr_compiler.h>
namespace regexis024 {
int compile(const std::string& regexp, track_var_list &ret_track_var_list, std::vector<uint8_t> &ret_program,
std::string &ret_message) {
ret_message.clear();
REGEX_IS024_MeaningContext cmp_ctx(regexp.size(), regexp.data());
if (cmp_ctx.error) {
ret_message = std::move(cmp_ctx.error_msg);
return -1;
}
ret_program = std::move(cmp_ctx.compiled_program);
ret_track_var_list.clear();
for (auto& iip: cmp_ctx.ktr.track_names)
ret_track_var_list[iip.first] = (TrackingVariableInfo)cmp_ctx.ktr.retrieval_info[iip.second];
return 0;
}
}

View File

@ -0,0 +1,13 @@
#ifndef LIBREGEXIS024_SRC_LIBREGEXIS024TOOLS_DELAYED_MATCHING_H
#define LIBREGEXIS024_SRC_LIBREGEXIS024TOOLS_DELAYED_MATCHING_H
#include <libregexis024fa/tracking_variables.h>
#include <stdint.h>
#include <vector>
namespace regexis024 {
int compile(const std::string& regexp, track_var_list& ret_track_var_list, std::vector<uint8_t>& ret_program,
std::string& ret_message);
}
#endif

View File

@ -5,36 +5,21 @@
#include <libregexis024sol/utils.h>
#include <assert.h>
// using namespace regexis024;
namespace regexis024 {
void convert(TrackingVariableInfo& to, const SubtrackingNameInfo& from) {
#define plagiat(field) to.field = from.field;
plagiat(type);
plagiat(colarr_first);
plagiat(colarr_second);
plagiat(stored_in_ca);
plagiat(selarr_first);
plagiat(selarr_second);
plagiat(stored_in_sa);
#undef plagiat
}
int matchStrToRegexp(const std::string& input, const std::string& pattern,
MatchInfo& retMatchInfo, track_var_list& retTrackVarList, std::string& retStatus)
{
retTrackVarList = {};
retMatchInfo = MatchInfo();
retStatus = "";
retStatus.clear();
REGEX_IS024_MeaningContext regexp(pattern.size(), pattern.data());
if (regexp.error) {
retStatus = "Pattern compilation. " + regexp.error_msg;
return -1;
}
retTrackVarList = {};
for (auto& iip: regexp.ktr.track_names) {
convert(retTrackVarList[iip.first], regexp.ktr.retrieval_info[iip.second]);
}
for (auto& iip: regexp.ktr.track_names)
retTrackVarList[iip.first] = (TrackingVariableInfo)regexp.ktr.retrieval_info[iip.second];
VirtualMachine vm(regexp.compiled_program.size(), regexp.compiled_program.data(),
UINT64_MAX, UINT16_MAX,
UINT32_MAX, UINT32_MAX, UINT64_MAX);

View File

@ -2,26 +2,9 @@
#define LIBREGEXIS024_SRC_LIBREGEXIS024TOOLS_STRINGMATCHING_H
#include <libregexis024fa/tracking_variables.h>
#include <map>
#include <string>
#include <libregexis024vm/libregexis024vm_interface.h>
namespace regexis024 {
struct TrackingVariableInfo {
bool stored_in_ca = true;
bool stored_in_sa = false;
tracking_var_type_t type;
/* These fields will be -1 if unused */
int colarr_first = -1;
int colarr_second = -1;
int selarr_first = -1;
int selarr_second = -1;
};
typedef std::map<std::string, TrackingVariableInfo> track_var_list;
struct MatchInfo {
bool have_match = false;
std::vector<CAEvent> ca_history;

View File

@ -22,7 +22,7 @@ namespace regexis024 {
ctx.RAX = ctx.RBX = 0;
} else {
ctx.active_thread.delete_thread();
ctx.try_to_continue_scheduled();
try_to_continue_scheduled(ctx);
}
}
@ -69,14 +69,14 @@ ctx.error = error_codes::instruction_not_for_collision_thread; return; }
other.slot_occupation_status = SLOT_NEW_val;
ctx.active_thread.slot_occupation_status = SLOT_EMPTY_val;
ctx.READ_halted_stack_new.append(ssid);
ctx.try_to_continue_scheduled();
try_to_continue_scheduled(ctx);
}
}
void i_READ(VMContext &ctx) {
ctx_print_debug(ctx);
check_available_prg(BYTECODE_SSLOT_ID_SZ)
sslot_id_t ssid = ctx.extract_sslot_id();
sslot_id_t ssid = extract_sslot_id(ctx);
do_i_read(ctx, ssid);
}
@ -88,7 +88,7 @@ ctx.error = error_codes::instruction_not_for_collision_thread; return; }
void i_JUMP(VMContext& ctx){
ctx_print_debug(ctx);
check_available_prg(BYTECODE_NEAR_POINTER_SZ)
ctx.active_thread.IP = ctx.extract_near_pointer();
ctx.active_thread.IP = extract_near_pointer(ctx);
}
template<typename conditionT, typename immArgSzT>
@ -97,7 +97,7 @@ ctx.error = error_codes::instruction_not_for_collision_thread; return; }
ctx_print_debug(ctx);
check_available_prg(immArgSzT::byte_sz + BYTECODE_NEAR_POINTER_SZ);
uint64_t imm_val_B = immArgSzT::extract(ctx);
near_ptr_t dest = ctx.extract_near_pointer();
near_ptr_t dest = extract_near_pointer(ctx);
uint64_t imm_val_A = ctx.INP;
if (conditionT::call(imm_val_A, imm_val_B))
ctx.active_thread.IP = dest;
@ -109,25 +109,25 @@ ctx.error = error_codes::instruction_not_for_collision_thread; return; }
struct immArgByte{
static constexpr int byte_sz = 1;
static uint64_t extract(VMContext& ctx){return ctx.extract_b();}
static uint64_t extract(VMContext& ctx){return extract_b(ctx);}
};
struct immArgWord{
static constexpr int byte_sz = 2;
static uint64_t extract(VMContext& ctx){return ctx.extract_w();}
static uint64_t extract(VMContext& ctx){return extract_w(ctx);}
};
struct immArgDoubleWord{
static constexpr int byte_sz = 4;
static uint64_t extract(VMContext& ctx){return ctx.extract_dw();}
static uint64_t extract(VMContext& ctx){return extract_dw(ctx);}
};
struct immArgQuadWord{
static constexpr int byte_sz = 8;
static uint64_t extract(VMContext& ctx){return ctx.extract_qw();}
static uint64_t extract(VMContext& ctx){return extract_qw(ctx);}
};
void clone_thread_into_slot(Thread& source, Thread& vessel){
thread_print_debug(source);
my_assert(!(vessel.slot_occupation_status & SLOT_OCCUPIED));
my_assert((source.slot_occupation_status & SLOT_OCCUPIED));
assert(!(vessel.slot_occupation_status & SLOT_OCCUPIED));
assert((source.slot_occupation_status & SLOT_OCCUPIED));
vessel = source;
if (vessel.CAHptr){
vessel.CAHptr->refs++;
@ -142,8 +142,8 @@ ctx.error = error_codes::instruction_not_for_collision_thread; return; }
ctx_print_debug(ctx);
general_matching_mode_check()
check_available_prg(BYTECODE_SSLOT_ID_SZ + BYTECODE_NEAR_POINTER_SZ);
sslot_id_t ssid = ctx.extract_sslot_id();
near_ptr_t dest = ctx.extract_near_pointer();
sslot_id_t ssid = extract_sslot_id(ctx);
near_ptr_t dest = extract_near_pointer(ctx);
if (ssid >= ctx.fork_slots_number)
smitsya(fork_sslot_out_of_range);
Thread& other = ctx.FORK_halted_slots[ssid];
@ -170,14 +170,14 @@ ctx.error = error_codes::instruction_not_for_collision_thread; return; }
ctx_print_debug(ctx);
general_matching_mode_check()
ctx.active_thread.delete_thread();
ctx.try_to_continue_scheduled();
try_to_continue_scheduled(ctx);
}
void i_PARAM_READ_SS_NUMBER(VMContext& ctx){
ctx_print_debug(ctx);
initialization_phase_check()
check_available_prg(BYTECODE_SSLOT_ID_SZ)
sslot_id_t read_slots_number = ctx.extract_sslot_id();
sslot_id_t read_slots_number = extract_sslot_id(ctx);
ctx.read_slots_number = read_slots_number;
}
@ -185,7 +185,7 @@ ctx.error = error_codes::instruction_not_for_collision_thread; return; }
ctx_print_debug(ctx);
initialization_phase_check()
check_available_prg(BYTECODE_SSLOT_ID_SZ)
sslot_id_t fork_slots_number = ctx.extract_sslot_id();
sslot_id_t fork_slots_number = extract_sslot_id(ctx);
ctx.fork_slots_number = fork_slots_number;
}
@ -193,7 +193,7 @@ ctx.error = error_codes::instruction_not_for_collision_thread; return; }
ctx_print_debug(ctx);
initialization_phase_check()
check_available_prg(BYTECODE_TRACK_ARRAY_INDEX_ID_SZ)
tai_t selection_array_len = ctx.extract_track_array_index();
tai_t selection_array_len = extract_track_array_index(ctx);
ctx.selection_array_len = selection_array_len;
}
@ -201,7 +201,7 @@ ctx.error = error_codes::instruction_not_for_collision_thread; return; }
ctx_print_debug(ctx);
initialization_phase_check()
check_available_prg(BYTECODE_NEAR_POINTER_SZ)
near_ptr_t sift_function = ctx.extract_near_pointer();
near_ptr_t sift_function = extract_near_pointer(ctx);
ctx.have_sift_function = true;
ctx.sift_function = sift_function;
}
@ -220,7 +220,7 @@ ctx.error = error_codes::instruction_not_for_collision_thread; return; }
ctx_print_debug(ctx);
sift_mode_check()
check_available_prg(BYTECODE_TRACK_ARRAY_INDEX_ID_SZ)
tai_t i1 = ctx.extract_track_array_index();
tai_t i1 = extract_track_array_index(ctx);
if (i1 >= ctx.selection_array_len)
smitsya(selection_arr_out_of_range);
ctx.RAX = get_el_from_selarr(ctx.active_thread.SAptr, i1);
@ -237,10 +237,10 @@ ctx.error = error_codes::instruction_not_for_collision_thread; return; }
ctx_print_debug(ctx);
sift_mode_check()
check_available_prg(BYTECODE_TRACK_ARRAY_INDEX_ID_SZ * 2)
tai_t i_start = ctx.extract_track_array_index();
tai_t i_start = extract_track_array_index(ctx);
if (i_start >= ctx.selection_array_len)
smitsya(selection_arr_out_of_range);
tai_t i_end = ctx.extract_track_array_index();
tai_t i_end = extract_track_array_index(ctx);
if (i_end >= ctx.selection_array_len)
smitsya(selection_arr_out_of_range);
ctx.RAX = get_selarr_el_dist(ctx.active_thread.SAptr, i_start, i_end);
@ -251,7 +251,7 @@ ctx.error = error_codes::instruction_not_for_collision_thread; return; }
ctx_print_debug(ctx);
if (ctx.who_started_sift == opcodes::READ){
ctx.active_thread.delete_thread();
ctx.try_to_continue_scheduled();
try_to_continue_scheduled(ctx);
} else {
/* FORK or MATCH (which will also be shown as FORK) */
/* Cloning conflict ends, active_thread jumps to offsprings IP */
@ -268,7 +268,7 @@ ctx.error = error_codes::instruction_not_for_collision_thread; return; }
/* noncloning conflict won by intruder+ */
*ctx.sifting_with = ctx.active_thread;
ctx.active_thread.slot_occupation_status = SLOT_EMPTY_val;
ctx.try_to_continue_scheduled();
try_to_continue_scheduled(ctx);
} else {
/* End of cloning conflict (it involved cloning) */
clone_thread_into_slot(ctx.active_thread, *ctx.sifting_with);
@ -319,8 +319,8 @@ ctx.error = error_codes::instruction_not_for_collision_thread; return; }
ctx_print_debug(ctx);
general_matching_mode_check()
check_available_prg(BYTECODE_TRACK_ARRAY_INDEX_ID_SZ + 8)
tai_t ca_ind = ctx.extract_track_array_index();
uint64_t imm = ctx.extract_qw();
tai_t ca_ind = extract_track_array_index(ctx);
uint64_t imm = extract_qw(ctx);
ca_branch_new_node(ctx, ca_ind, imm);
}
@ -328,7 +328,7 @@ ctx.error = error_codes::instruction_not_for_collision_thread; return; }
ctx_print_debug(ctx);
general_matching_mode_check()
check_available_prg(BYTECODE_TRACK_ARRAY_INDEX_ID_SZ)
tai_t ca_ind = ctx.extract_track_array_index();
tai_t ca_ind = extract_track_array_index(ctx);
ca_branch_new_node(ctx, ca_ind, ctx.passed_bytes);
}
@ -364,8 +364,8 @@ ctx.error = error_codes::instruction_not_for_collision_thread; return; }
ctx_print_debug(ctx);
general_matching_mode_check()
check_available_prg(BYTECODE_TRACK_ARRAY_INDEX_ID_SZ + 8)
tai_t sa_ind = ctx.extract_track_array_index();
uint64_t imm = ctx.extract_qw();
tai_t sa_ind = extract_track_array_index(ctx);
uint64_t imm = extract_qw(ctx);
edit_selection_array(ctx, sa_ind, imm);
}
@ -373,7 +373,7 @@ ctx.error = error_codes::instruction_not_for_collision_thread; return; }
ctx_print_debug(ctx);
general_matching_mode_check()
check_available_prg(BYTECODE_TRACK_ARRAY_INDEX_ID_SZ)
tai_t sa_ind = ctx.extract_track_array_index();
tai_t sa_ind = extract_track_array_index(ctx);
edit_selection_array(ctx, sa_ind, ctx.passed_chars);
}
@ -421,7 +421,7 @@ ctx.error = error_codes::instruction_not_for_collision_thread; return; }
void instruction_table(VMContext &ctx) {
ctx_print_debug(ctx);
uint8_t opcode = ctx.extract_instruction();
uint8_t opcode = extract_instruction(ctx);
#define rcase(inst) case opcodes::inst: return i_ ## inst (ctx);
#define jumpC(UN, st) case opcodes::JC ## UN ## _B: return i_JC<st, immArgByte>(ctx); \
@ -460,4 +460,4 @@ ctx.error = error_codes::instruction_not_for_collision_thread; return; }
ctx.error = error_codes::invalid_opcode;
}
}
}
}

View File

@ -15,23 +15,35 @@
#define SLOT_NEW 2
#define SLOT_NEW_val (SLOT_OCCUPIED | SLOT_NEW)
#define check_available_prg(regionSz) if (!ctx.check_inboundness(regionSz)){ \
#define check_available_prg(regionSz) if (!check_inboundness(ctx, regionSz)){ \
ctx.error = error_codes::improper_finish; return; }
#if defined(LIBREGEXIS024_DEBUG) && defined(LIBREGEXIS024_ALLOW_LOUD)
#include <debugging_regexis024/vm/libregexis024vm_debug.h>
#define my_assert(expr) assert(expr)
#define ctx_print_debug(ctx) debug_print_context(ctx, __func__)
#define thread_print_debug(thread) debug_print_thread(thread, __func__)
#else
#define my_assert(expr) assert(expr)
#define ctx_print_debug(ctx)
#define thread_print_debug(thread)
#endif
namespace regexis024 {
bool check_inboundness(VMContext& ctx, int region);
uint8_t extract_b(VMContext& ctx);
uint16_t extract_w(VMContext& ctx);
uint32_t extract_dw(VMContext& ctx);
uint64_t extract_qw(VMContext& ctx);
uint8_t extract_instruction(VMContext& ctx);
sslot_id_t extract_sslot_id(VMContext& ctx);
near_ptr_t extract_near_pointer(VMContext& ctx);
tai_t extract_track_array_index(VMContext& ctx);
void try_to_continue_scheduled(VMContext& ctx);
void instruction_table(VMContext& ctx);
}
#endif //LIBREGEXIS024_INSTRUCTION_IMPLEMENTATION_H
#endif //LIBREGEXIS024_INSTRUCTION_IMPLEMENTATION_H

View File

@ -53,7 +53,6 @@ namespace regexis024 {
uint64_t* SAptr = NULL;
void delete_thread() noexcept;
void debug_print(const char* place);
};
struct VMContext{
@ -132,22 +131,8 @@ namespace regexis024 {
uint64_t INP = 0;
uint64_t passed_chars = 0;
uint64_t passed_bytes = 0;
void try_to_continue_scheduled();
bool check_inboundness(int region);
uint8_t extract_b();
uint16_t extract_w();
uint32_t extract_dw();
uint64_t extract_qw();
uint8_t extract_instruction();
sslot_id_t extract_sslot_id();
near_ptr_t extract_near_pointer();
tai_t extract_track_array_index();
void debug_print(const char* place);
};
void wipe(VMContext& ctx) noexcept;
}
#endif //LIBREGEXIS024_LIBREGEXIS024VM_H

View File

@ -42,7 +42,7 @@ namespace regexis024 {
* gonna deoccupy slot_occupation_status*/
void Thread::delete_thread() noexcept {
thread_print_debug(*this);
my_assert(slot_occupation_status & SLOT_OCCUPIED);
assert(slot_occupation_status & SLOT_OCCUPIED);
slot_occupation_status = SLOT_EMPTY_val;
CollectionArrayNode* cur_CAptr = CAHptr;
while (cur_CAptr){
@ -60,37 +60,29 @@ namespace regexis024 {
}
}
void emptify_one_of_new_read_halted_stacks(VMContext& ctx, SSID_Stack& type_new_stack){
while (!type_new_stack.empty()){
Thread& thread = ctx.READ_halted_slots[type_new_stack.pop()];
assert(thread.slot_occupation_status & SLOT_OCCUPIED);
thread.delete_thread();
}
}
/* First it will try to pop pending thread from FORK_halted_stack
* Then it will try popping thread from READ_halted_stack_old (checking if top
* thread here is not actually SLOT_NEW). If something succeded, corresponding slot will be deoccupied, and
* active slot will be occupied with it.
*
* try_to_continue_scheduled() assumes that active thread is unoccupied.*/
void VMContext::try_to_continue_scheduled(){
ctx_print_debug(*this);
my_assert(!(active_thread.slot_occupation_status & SLOT_OCCUPIED));
if (FORK_halted_stack.sz){
sslot_id_t ssid = FORK_halted_stack.pop();
active_thread = FORK_halted_slots[ssid];
FORK_halted_slots[ssid].slot_occupation_status = SLOT_EMPTY_val;
void try_to_continue_scheduled(VMContext& ctx){
ctx_print_debug(ctx);
assert(!(ctx.active_thread.slot_occupation_status & SLOT_OCCUPIED));
if (ctx.FORK_halted_stack.sz){
sslot_id_t ssid = ctx.FORK_halted_stack.pop();
ctx.active_thread = ctx.FORK_halted_slots[ssid];
ctx.FORK_halted_slots[ssid].slot_occupation_status = SLOT_EMPTY_val;
return;
}
while (READ_halted_stack_old.sz){
sslot_id_t ssid = READ_halted_stack_old.pop();
if (READ_halted_slots[ssid].slot_occupation_status & SLOT_NEW){
while (ctx.READ_halted_stack_old.sz){
sslot_id_t ssid = ctx.READ_halted_stack_old.pop();
if (ctx.READ_halted_slots[ssid].slot_occupation_status & SLOT_NEW){
/* This is the case when old thread was silently replaced by settled new thread */
continue;
}
active_thread = READ_halted_slots[ssid];
READ_halted_slots[ssid].slot_occupation_status = SLOT_EMPTY_val;
ctx.active_thread = ctx.READ_halted_slots[ssid];
ctx.READ_halted_slots[ssid].slot_occupation_status = SLOT_EMPTY_val;
return;
}
/* Failure here will be detected. We started with unoccupied active thread. iterator inside kick will see it */
@ -148,28 +140,44 @@ namespace regexis024 {
INP = input;
passed_bytes += corresponding_byte_amount;
passed_chars++;
try_to_continue_scheduled();
try_to_continue_scheduled(*this);
kick(*this);
return error;
}
VMContext::~VMContext() {
ctx_print_debug(*this);
if (initialized){
emptify_one_of_new_read_halted_stacks(*this, READ_halted_stack_new);
while (!READ_halted_stack_old.empty()){
Thread& thread = READ_halted_slots[READ_halted_stack_old.pop()];
if (active_thread.slot_occupation_status & SLOT_OCCUPIED)
active_thread.delete_thread();
wipe(*this);
if (initialized) {
free(READ_halted_slots);
free(FORK_halted_slots);
}
}
void wipe(VMContext& ctx) noexcept {
ctx_print_debug(ctx);
assert(!(ctx.active_thread.slot_occupation_status & SLOT_OCCUPIED));
if (ctx.initialized){
ctx.timer = 0;
ctx.CAN_total = 0;
while (!ctx.READ_halted_stack_new.empty()){
Thread& thread = ctx.READ_halted_slots[ctx.READ_halted_stack_new.pop()];
assert(thread.slot_occupation_status & SLOT_OCCUPIED);
thread.delete_thread();
}
while (!ctx.READ_halted_stack_old.empty()){
Thread& thread = ctx.READ_halted_slots[ctx.READ_halted_stack_old.pop()];
assert(thread.slot_occupation_status & SLOT_OCCUPIED);
if (!(thread.slot_occupation_status & SLOT_NEW))
thread.delete_thread();
}
free(READ_halted_slots);
while (!FORK_halted_stack.empty())
FORK_halted_slots[FORK_halted_stack.pop()].delete_thread();
free(FORK_halted_slots);
while (!ctx.FORK_halted_stack.empty())
ctx.FORK_halted_slots[ctx.FORK_halted_stack.pop()].delete_thread();
if (matched_thread.slot_occupation_status & SLOT_OCCUPIED){
matched_thread.delete_thread();
if (ctx.matched_thread.slot_occupation_status & SLOT_OCCUPIED){
ctx.matched_thread.delete_thread();
}
}
}

View File

@ -2,39 +2,39 @@
#include <libregexis024vm/vm_opcodes.h>
namespace regexis024 {
bool VMContext::check_inboundness(int region){
return vmprog_check_inboundness(program_size, active_thread.IP, region);
bool check_inboundness(VMContext& ctx, int region){
return vmprog_check_inboundness(ctx.program_size, ctx.active_thread.IP, region);
}
uint8_t VMContext::extract_b() {
return vmprog_extract_b(&active_thread.IP, prg);
uint8_t extract_b(VMContext& ctx) {
return vmprog_extract_b(&ctx.active_thread.IP, ctx.prg);
}
uint16_t VMContext::extract_w() {
return vmprog_extract_w(&active_thread.IP, prg);
uint16_t extract_w(VMContext& ctx) {
return vmprog_extract_w(&ctx.active_thread.IP, ctx.prg);
}
uint32_t VMContext::extract_dw() {
return vmprog_extract_dw(&active_thread.IP, prg);
uint32_t extract_dw(VMContext& ctx) {
return vmprog_extract_dw(&ctx.active_thread.IP, ctx.prg);
}
uint64_t VMContext::extract_qw() {
return vmprog_extract_qw(&active_thread.IP, prg);
uint64_t extract_qw(VMContext& ctx) {
return vmprog_extract_qw(&ctx.active_thread.IP, ctx.prg);
}
uint8_t VMContext::extract_instruction() {
return extract_b();
uint8_t extract_instruction(VMContext& ctx) {
return extract_b(ctx);
}
sslot_id_t VMContext::extract_sslot_id() {
return extract_dw();
sslot_id_t extract_sslot_id(VMContext& ctx) {
return extract_dw(ctx);
}
near_ptr_t VMContext::extract_near_pointer() {
return extract_qw();
near_ptr_t extract_near_pointer(VMContext& ctx) {
return extract_qw(ctx);
}
tai_t VMContext::extract_track_array_index() {
return extract_w();
tai_t extract_track_array_index(VMContext& ctx) {
return extract_w(ctx);
}
}

View File

@ -85,4 +85,8 @@ namespace regexis024 {
throw std::runtime_error("unusable\n");
return reveal->feedCharacter(input, bytesResembled);
}
void VirtualMachine::wipeToInit() {
wipe(*reveal);
}
}

View File

@ -33,7 +33,7 @@ namespace regexis024 {
error_code_t addNewMatchingThread();
error_code_t feedCharacter(uint64_t input, uint64_t bytesResembled);
void wipeToInit();
private:
bool gave_SOF = false;
void* opaque;