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"}; "-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> 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> 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_release = {"-g", "-O2"};
std::vector<std::string> opt_flags_debug = {"-g", "-ggdb", "-O0"}; std::vector<std::string> opt_flags_debug = {"-g", "-ggdb", "-O0"};
@ -79,6 +79,7 @@ struct Libregexis024BuildSystem {
"libregexis024sol/expr_parse_functions/command_recognition.cpp", "libregexis024sol/expr_parse_functions/command_recognition.cpp",
"libregexis024tools/stringmatching.cpp", "libregexis024tools/stringmatching.cpp",
"libregexis024tools/delayed_matching.cpp",
}; };
/* These are added to compilation_units_of_release */ /* These are added to compilation_units_of_release */
@ -102,6 +103,7 @@ struct Libregexis024BuildSystem {
"libregexis024sol/expr_compiler.h", "libregexis024sol/expr_compiler.h",
"libregexis024tools/stringmatching.h", "libregexis024tools/stringmatching.h",
"libregexis024tools/delayed_matching.h",
}; };
CTarget T{"libregexis024", "shared_library"}; CTarget T{"libregexis024", "shared_library"};
@ -131,14 +133,14 @@ struct Libregexis024BuildSystem {
int main(int argc, char** argv) { int main(int argc, char** argv) {
try { try {
assert(argc > 0); ASSERT_pl(argc > 0);
std::vector<std::string> args(argc - 1); std::vector<std::string> args(argc - 1);
for (int i = 0; i + 1 < argc; i++) { for (int i = 0; i + 1 < argc; i++) {
args[i] = argv[i + 1]; args[i] = argv[i + 1];
} }
NormalCBuildSystemCommandMeaning cmd; NormalCBuildSystemCommandMeaning cmd;
regular_bs_cli_cmd_interpret(args, cmd); regular_bs_cli_cmd_interpret(args, cmd);
Libregexis024BuildSystem bs("debug", cmd); Libregexis024BuildSystem bs("release", cmd);
if (cmd.need_to_build) if (cmd.need_to_build)
complete_tasks_of_build_units(bs.runlevel_1); complete_tasks_of_build_units(bs.runlevel_1);
if (cmd.need_to_install) if (cmd.need_to_install)

View File

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

View File

@ -4,6 +4,8 @@
#include <stdint.h> #include <stdint.h>
#include <libregexis024vm/vm_opcodes_types.h> #include <libregexis024vm/vm_opcodes_types.h>
#include <vector> #include <vector>
#include <stddef.h>
namespace regexis024 { namespace regexis024 {
void write_byte(std::vector<uint8_t>& result, uint8_t x); void write_byte(std::vector<uint8_t>& result, uint8_t x);
void write_word(std::vector<uint8_t>& result, uint16_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 #ifndef LIBREGEXIS024_SRC_LIBREGEXIS024FA_TRACKING_VARIABLES_H
#define LIBREGEXIS024_SRC_LIBREGEXIS024FA_TRACKING_VARIABLES_H #define LIBREGEXIS024_SRC_LIBREGEXIS024FA_TRACKING_VARIABLES_H
#include <map>
#include <string>
namespace regexis024 { namespace regexis024 {
namespace tracking_var_types { namespace tracking_var_types {
enum tracking_var_type_I { enum tracking_var_type_I {
@ -11,6 +14,21 @@ namespace regexis024 {
} }
typedef tracking_var_types::tracking_var_type_I tracking_var_type_t; 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 #endif

View File

@ -138,7 +138,7 @@ namespace regexis024 {
chekushka BracketLvl_ParseCall::firstTime(REGEX_IS024_MeaningContext& ctx, ParsingContext& pctx, FA_Container& fa) { chekushka BracketLvl_ParseCall::firstTime(REGEX_IS024_MeaningContext& ctx, ParsingContext& pctx, FA_Container& fa) {
result.assertDefault(); result.assertDefault();
assert(readChar(ctx) == U'('); 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){ if (namedSubexpressionId >= 0){
assert(ctx.ktr.retrieval_info[namedSubexpressionId].type == tracking_var_types::range); assert(ctx.ktr.retrieval_info[namedSubexpressionId].type == tracking_var_types::range);
if (ctx.ktr.retrieval_info[namedSubexpressionId].stored_in_sa){ if (ctx.ktr.retrieval_info[namedSubexpressionId].stored_in_sa){
@ -157,7 +157,7 @@ namespace regexis024 {
readChar(ctx); readChar(ctx);
result = tmp_ret_buff; result = tmp_ret_buff;
if (namedSubexpressionId >= 0) { 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){ if (tai_slots.stored_in_ca){
assert(tai_slots.colarr_first >= 0 && tai_slots.colarr_first < UINT16_MAX); assert(tai_slots.colarr_first >= 0 && tai_slots.colarr_first < UINT16_MAX);
assert(tai_slots.colarr_second >= 0 && tai_slots.colarr_second < 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) */ /* Generating priority table (sifting program) */
for (const SubtrackingNameInfo& sni: ctx.ktr.retrieval_info) { for (const SubtrackingNameUsageInfo& sni: ctx.ktr.retrieval_info) {
if (!sni.discovered) if (!sni.discovered)
aux_THROW("tracking tool named in !select is not used anywhere"); aux_THROW("tracking tool named in !select is not used anywhere");
if (sni.used_in_sifting) { 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) { 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_t id = ctx.ktr.track_names[name];
/* Size of this verctor won't be changed. THis is a safe reference */ /* 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){ if (!info.discovered){
info.type = type; info.type = type;
if (info.stored_in_ca) { if (info.stored_in_ca) {

View File

@ -7,7 +7,7 @@
#include <libregexis024fa/tracking_variables.h> #include <libregexis024fa/tracking_variables.h>
namespace regexis024 { namespace regexis024 {
struct SubtrackingNameInfo{ struct SubtrackingNameUsageInfo: public TrackingVariableInfo{
bool stored_in_ca = true; bool stored_in_ca = true;
bool stored_in_sa = false; bool stored_in_sa = false;
@ -25,7 +25,7 @@ namespace regexis024 {
struct KnownTrackingTools { struct KnownTrackingTools {
std::map<std::string, int64_t> track_names; 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); assert(patient.start);
for (FA_Node** end: patient.ends){ for (FA_Node** end: patient.ends){
assert(!(*end)); assert(!(*end));
printf("DEBUG %lu->->->->->%lu\n", patient.start->nodeId, node->nodeId);
reattach_fa_node_edge(end, node); reattach_fa_node_edge(end, node);
} }
} }

View File

@ -2,6 +2,7 @@
#include <assert.h> #include <assert.h>
#include <stdexcept> #include <stdexcept>
#include <libregexis024sol/expr_compiler.h> #include <libregexis024sol/expr_compiler.h>
#include <libregexis024tools/delayed_matching.h>
using namespace regexis024; using namespace regexis024;
using namespace std; using namespace std;
@ -20,13 +21,45 @@ void test(const string& input, const string& pattern, const MatchInfo& right_ans
printf("Test passed\n"); 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() { 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", "[ab]*", MatchInfo({}, {}));
test("bababbaa", "!dfa;[ab]*", MatchInfo({}, {})); test("bababbaa", "!dfa;[ab]*", MatchInfo({}, {}));
test("d3", "[abc]3", MatchInfo()); test("d3", "[abc]3", MatchInfo());
test("a3", "[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("abba", "!select{M{max}}a#M(b*)a", MatchInfo({}, {1, 3}));
test("LINE\r\nFirst:Second\r\nThird:12\r\n\r\n", 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 <libregexis024sol/utils.h>
#include <assert.h> #include <assert.h>
// using namespace regexis024;
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, int matchStrToRegexp(const std::string& input, const std::string& pattern,
MatchInfo& retMatchInfo, track_var_list& retTrackVarList, std::string& retStatus) MatchInfo& retMatchInfo, track_var_list& retTrackVarList, std::string& retStatus)
{ {
retTrackVarList = {}; retTrackVarList = {};
retMatchInfo = MatchInfo(); retMatchInfo = MatchInfo();
retStatus = ""; retStatus.clear();
REGEX_IS024_MeaningContext regexp(pattern.size(), pattern.data()); REGEX_IS024_MeaningContext regexp(pattern.size(), pattern.data());
if (regexp.error) { if (regexp.error) {
retStatus = "Pattern compilation. " + regexp.error_msg; retStatus = "Pattern compilation. " + regexp.error_msg;
return -1; return -1;
} }
retTrackVarList = {}; retTrackVarList = {};
for (auto& iip: regexp.ktr.track_names) { for (auto& iip: regexp.ktr.track_names)
convert(retTrackVarList[iip.first], regexp.ktr.retrieval_info[iip.second]); retTrackVarList[iip.first] = (TrackingVariableInfo)regexp.ktr.retrieval_info[iip.second];
}
VirtualMachine vm(regexp.compiled_program.size(), regexp.compiled_program.data(), VirtualMachine vm(regexp.compiled_program.size(), regexp.compiled_program.data(),
UINT64_MAX, UINT16_MAX, UINT64_MAX, UINT16_MAX,
UINT32_MAX, UINT32_MAX, UINT64_MAX); UINT32_MAX, UINT32_MAX, UINT64_MAX);

View File

@ -2,26 +2,9 @@
#define LIBREGEXIS024_SRC_LIBREGEXIS024TOOLS_STRINGMATCHING_H #define LIBREGEXIS024_SRC_LIBREGEXIS024TOOLS_STRINGMATCHING_H
#include <libregexis024fa/tracking_variables.h> #include <libregexis024fa/tracking_variables.h>
#include <map>
#include <string>
#include <libregexis024vm/libregexis024vm_interface.h> #include <libregexis024vm/libregexis024vm_interface.h>
namespace regexis024 { 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 { struct MatchInfo {
bool have_match = false; bool have_match = false;
std::vector<CAEvent> ca_history; std::vector<CAEvent> ca_history;

View File

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

View File

@ -15,22 +15,34 @@
#define SLOT_NEW 2 #define SLOT_NEW 2
#define SLOT_NEW_val (SLOT_OCCUPIED | SLOT_NEW) #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; } ctx.error = error_codes::improper_finish; return; }
#if defined(LIBREGEXIS024_DEBUG) && defined(LIBREGEXIS024_ALLOW_LOUD) #if defined(LIBREGEXIS024_DEBUG) && defined(LIBREGEXIS024_ALLOW_LOUD)
#include <debugging_regexis024/vm/libregexis024vm_debug.h> #include <debugging_regexis024/vm/libregexis024vm_debug.h>
#define my_assert(expr) assert(expr)
#define ctx_print_debug(ctx) debug_print_context(ctx, __func__) #define ctx_print_debug(ctx) debug_print_context(ctx, __func__)
#define thread_print_debug(thread) debug_print_thread(thread, __func__) #define thread_print_debug(thread) debug_print_thread(thread, __func__)
#else #else
#define my_assert(expr) assert(expr)
#define ctx_print_debug(ctx) #define ctx_print_debug(ctx)
#define thread_print_debug(thread) #define thread_print_debug(thread)
#endif #endif
namespace regexis024 { 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); void instruction_table(VMContext& ctx);
} }

View File

@ -53,7 +53,6 @@ namespace regexis024 {
uint64_t* SAptr = NULL; uint64_t* SAptr = NULL;
void delete_thread() noexcept; void delete_thread() noexcept;
void debug_print(const char* place);
}; };
struct VMContext{ struct VMContext{
@ -132,22 +131,8 @@ namespace regexis024 {
uint64_t INP = 0; uint64_t INP = 0;
uint64_t passed_chars = 0; uint64_t passed_chars = 0;
uint64_t passed_bytes = 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 #endif //LIBREGEXIS024_LIBREGEXIS024VM_H

View File

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

View File

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

View File

@ -85,4 +85,8 @@ namespace regexis024 {
throw std::runtime_error("unusable\n"); throw std::runtime_error("unusable\n");
return reveal->feedCharacter(input, bytesResembled); 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 addNewMatchingThread();
error_code_t feedCharacter(uint64_t input, uint64_t bytesResembled); error_code_t feedCharacter(uint64_t input, uint64_t bytesResembled);
void wipeToInit();
private: private:
bool gave_SOF = false; bool gave_SOF = false;
void* opaque; void* opaque;