<commit_before>#include <x0/flow/vm/Runner.h>
#include <x0/flow/vm/Params.h>
#include <x0/flow/vm/NativeCallback.h>
#include <x0/flow/vm/Handler.h>
#include <x0/flow/vm/Program.h>
#include <x0/flow/vm/Match.h>
#include <x0/flow/vm/Instruction.h>
#include <vector>
#include <utility>
#include <memory>
#include <new>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>

namespace x0 {
namespace FlowVM {

std::unique_ptr<Runner> Runner::create(Handler* handler)
{
    Runner* p = (Runner*) malloc(sizeof(Runner) + handler->registerCount() * sizeof(uint64_t));
    new (p) Runner(handler);
    return std::unique_ptr<Runner>(p);
}

Runner::Runner(Handler* handler) :
    handler_(handler),
    program_(handler->program()),
    userdata_(nullptr),
    stringGarbage_()
{
    // initialize emptyString()
    newString("");

    // initialize registers
    memset(data_, 0, sizeof(Register) * handler_->registerCount());
}

void Runner::operator delete (void* p)
{
    free(p);
}

FlowString* Runner::newString(const std::string& value)
{
    stringGarbage_.push_back(FlowString(strdup(value.c_str()), value.size()));
    return &stringGarbage_.back();
}

FlowString* Runner::newString(const char* p, size_t n)
{
    char* s = (char*) malloc(n);

    memcpy(s, p, n);
    stringGarbage_.push_back(FlowString(s, n));

    return &stringGarbage_.back();
}

FlowString* Runner::catString(const FlowString& a, const FlowString& b)
{
    size_t n = a.size() + b.size();
    char* s = (char*) malloc(n);

    memcpy(s, a.data(), a.size());
    memcpy(s + a.size(), b.data(), b.size());
    stringGarbage_.push_back(FlowString(s, n));

    return &stringGarbage_.back();
}

bool Runner::run()
{
    const Program* program = handler_->program();
    const auto& code = handler_->code();
    register const Instruction* pc = code.data();
    uint64_t ticks = 0;

    #define OP opcode(*pc)
    #define A  operandA(*pc)
    #define B  operandB(*pc)
    #define C  operandC(*pc)

    #define toString(R)     (*(FlowString*) data_[R])
    #define toIPAddress(R)  (*(IPAddress*) data_[R])
    #define toCidr(R)       (*(Cidr*) data_[R])
    #define toNumber(R)     ((FlowNumber) data_[R])

    #define toStringPtr(R)  ((FlowString*) data_[R])
    #define toCidrPtr(R)    ((Cidr*) data_[R])

    #define instr(name) \
        l_##name: \
        /*disassemble(*pc, pc - code.data());*/ \
        ++ticks;

    #define next goto *ops[opcode(*++pc)]

    // {{{ jump table
    static const void* ops[] = {<commit_msg>flow: mutes compile time warning<commit_after>#include <x0/flow/vm/Runner.h>
#include <x0/flow/vm/Params.h>
#include <x0/flow/vm/NativeCallback.h>
#include <x0/flow/vm/Handler.h>
#include <x0/flow/vm/Program.h>
#include <x0/flow/vm/Match.h>
#include <x0/flow/vm/Instruction.h>
#include <vector>
#include <utility>
#include <memory>
#include <new>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>

namespace x0 {
namespace FlowVM {

std::unique_ptr<Runner> Runner::create(Handler* handler)
{
    Runner* p = (Runner*) malloc(sizeof(Runner) + handler->registerCount() * sizeof(uint64_t));
    new (p) Runner(handler);
    return std::unique_ptr<Runner>(p);
}

Runner::Runner(Handler* handler) :
    handler_(handler),
    program_(handler->program()),
    userdata_(nullptr),
    stringGarbage_()
{
    // initialize emptyString()
    newString("");

    // initialize registers
    memset(data_, 0, sizeof(Register) * handler_->registerCount());
}

void Runner::operator delete (void* p)
{
    free(p);
}

FlowString* Runner::newString(const std::string& value)
{
    stringGarbage_.push_back(FlowString(strdup(value.c_str()), value.size()));
    return &stringGarbage_.back();
}

FlowString* Runner::newString(const char* p, size_t n)
{
    char* s = (char*) malloc(n);

    memcpy(s, p, n);
    stringGarbage_.push_back(FlowString(s, n));

    return &stringGarbage_.back();
}

FlowString* Runner::catString(const FlowString& a, const FlowString& b)
{
    size_t n = a.size() + b.size();
    char* s = (char*) malloc(n);

    memcpy(s, a.data(), a.size());
    memcpy(s + a.size(), b.data(), b.size());
    stringGarbage_.push_back(FlowString(s, n));

    return &stringGarbage_.back();
}

bool Runner::run()
{
    const Program* program = handler_->program();
    const auto& code = handler_->code();
    const Instruction* pc = code.data();
    uint64_t ticks = 0;

    #define OP opcode(*pc)
    #define A  operandA(*pc)
    #define B  operandB(*pc)
    #define C  operandC(*pc)

    #define toString(R)     (*(FlowString*) data_[R])
    #define toIPAddress(R)  (*(IPAddress*) data_[R])
    #define toCidr(R)       (*(Cidr*) data_[R])
    #define toNumber(R)     ((FlowNumber) data_[R])

    #define toStringPtr(R)  ((FlowString*) data_[R])
    #define toCidrPtr(R)    ((Cidr*) data_[R])

    #define instr(name) \
        l_##name: \
        /*disassemble(*pc, pc - code.data());*/ \
        ++ticks;

    #define next goto *ops[opcode(*++pc)]

    // {{{ jump table
    static const void* ops[] = {
{'fraction_non_alphanumeric': 0.17974633372968687, 'fraction_numerical': 0.005548949663099485, 'mean_word_length': 3.797528517110266, 'pattern_counts': {'":': 0, '<': 37, '<?xml version=': 0, '>': 47, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '79126', 'n_tokens_mistral': 1844, 'n_tokens_neox': 1801, 'n_words': 385}