<commit_before>#ifndef HORNET_VM_HH
#define HORNET_VM_HH

#include <cstddef>
#include <cstdint>
#include <memory>
#include <string>
#include <vector>
#include <mutex>
#include <map>

#include <classfile_constants.h>

namespace hornet {

class constant_pool;
struct method;
struct field;
struct klass;
class loader;

class jvm {
public:
    std::shared_ptr<klass> lookup_class(std::string name);
    void register_class(std::shared_ptr<klass> klass);
    void invoke(method* method);

private:
    std::map<std::string, std::shared_ptr<klass>> _classes;
};

extern jvm *_jvm;

typedef uint64_t value_t;

struct object {
    struct object* fwd;
    struct klass*  klass;
    std::vector<value_t> _fields;
    std::mutex _mutex;

    object(struct klass* _klass);
    ~object();

    object& operator=(const object&) = delete;
    object(const object&) = delete;

    value_t get_field(size_t offset) const {
        return _fields[offset];
    }

    void set_field(size_t offset, value_t value) {
        _fields[offset] = value;
    }

    void lock() {
        _mutex.lock();
    }

    void unlock() {
        _mutex.unlock();
    }
};

using method_list_type = std::vector<std::shared_ptr<method>>;
using field_list_type = std::vector<std::shared_ptr<field>>;

enum class klass_state {
    loaded,
    initialized,
};

struct klass {
    struct object object;
    std::string   name;
    klass*        super;
    uint16_t      access_flags;
    klass_state   state = klass_state::loaded;
    uint32_t      nr_fields;
    std::vector<value_t> static_values;
    std::vector<std::shared_ptr<klass>> interfaces;

    klass();
    klass(loader* loader, std::shared_ptr<constant_pool> const_pool);
    ~klass();

    klass& operator=(const klass&) = delete;
    klass(const klass&) = delete;

    void init();
    bool verify();

    void add(std::shared_ptr<klass> iface);
    void add(std::shared_ptr<method> method);
    void add(std::shared_ptr<field> field);

    virtual bool is_primitive() const {
        return false;
    }

    virtual size_t size() const {
        return sizeof(void*);
    }

    std::shared_ptr<constant_pool> const_pool() const {
        return _const_pool;
    }

    bool is_subclass_of(klass* klass) {
        auto* super = this;
        while (super != nullptr) {
            if (super == klass) {
                return true;
            }
            super = super->super;
        }
        return false;
    }

    std::shared_ptr<klass> load_class(std::string name);

    std::shared_ptr<method> lookup_method(std::string name, std::string desciptor);
    std::shared_ptr<field> lookup_field(std::string name, std::string desciptor);

    std::shared_ptr<klass>  resolve_class (uint16_t idx);
    std::shared_ptr<field>  resolve_field (uint16_t idx);
    std::shared_ptr<method> resolve_method(uint16_t idx);
    std::shared_ptr<method> resolve_interface_method(uint16_t idx);

private:
    std::shared_ptr<constant_pool> _const_pool;
    method_list_type _methods;
    field_list_type _fields;
    loader* _loader;
};

struct field {
    struct klass* klass;
    std::string   name;
    std::string   descriptor;
    uint32_t      offset;
    uint16_t      access_flags;

    field(struct klass* klass_);
    ~field();

    field& operator=(const field&) = delete;
    field(const field&) = delete;

    bool is_static() const {
        return access_flags & JVM_ACC_STATIC;
    }

    bool matches(std::string name, std::string descriptor);
};

struct method {
    // Method lifecycle is tied to the class it belongs to. Use a pointer to
    // klass instead of a smart pointer to break the cyclic dependency during
    // destruction.
    struct klass* klass;
    uint16_t    access_flags;
    std::string name;
    std::string descriptor;
    struct klass* return_type;
    std::vector<struct klass*> arg_types;
    uint16_t    args_count;
    uint16_t    max_locals;
    char*       code;
    uint32_t    code_length;
    std::vector<uint8_t> trampoline;

    method() {
    }

    ~method() {
        delete[] code;
    }

    method& operator=(const method&) = delete;
    method(const method&) = delete;

    std::string full_name() const {
        return klass->name + "::" + name + descriptor;
    }

    bool is_init() const {
        return name[0] == '<';
    }

    bool is_native() const {
        return access_flags & JVM_ACC_NATIVE;
    }

    bool matches(std::string n, std::string d)
    {
       return name == n && descriptor == d;
    }
};

struct array {<commit_msg>vm: Make method::matches() const<commit_after>#ifndef HORNET_VM_HH
#define HORNET_VM_HH

#include <cstddef>
#include <cstdint>
#include <memory>
#include <string>
#include <vector>
#include <mutex>
#include <map>

#include <classfile_constants.h>

namespace hornet {

class constant_pool;
struct method;
struct field;
struct klass;
class loader;

class jvm {
public:
    std::shared_ptr<klass> lookup_class(std::string name);
    void register_class(std::shared_ptr<klass> klass);
    void invoke(method* method);

private:
    std::map<std::string, std::shared_ptr<klass>> _classes;
};

extern jvm *_jvm;

typedef uint64_t value_t;

struct object {
    struct object* fwd;
    struct klass*  klass;
    std::vector<value_t> _fields;
    std::mutex _mutex;

    object(struct klass* _klass);
    ~object();

    object& operator=(const object&) = delete;
    object(const object&) = delete;

    value_t get_field(size_t offset) const {
        return _fields[offset];
    }

    void set_field(size_t offset, value_t value) {
        _fields[offset] = value;
    }

    void lock() {
        _mutex.lock();
    }

    void unlock() {
        _mutex.unlock();
    }
};

using method_list_type = std::vector<std::shared_ptr<method>>;
using field_list_type = std::vector<std::shared_ptr<field>>;

enum class klass_state {
    loaded,
    initialized,
};

struct klass {
    struct object object;
    std::string   name;
    klass*        super;
    uint16_t      access_flags;
    klass_state   state = klass_state::loaded;
    uint32_t      nr_fields;
    std::vector<value_t> static_values;
    std::vector<std::shared_ptr<klass>> interfaces;

    klass();
    klass(loader* loader, std::shared_ptr<constant_pool> const_pool);
    ~klass();

    klass& operator=(const klass&) = delete;
    klass(const klass&) = delete;

    void init();
    bool verify();

    void add(std::shared_ptr<klass> iface);
    void add(std::shared_ptr<method> method);
    void add(std::shared_ptr<field> field);

    virtual bool is_primitive() const {
        return false;
    }

    virtual size_t size() const {
        return sizeof(void*);
    }

    std::shared_ptr<constant_pool> const_pool() const {
        return _const_pool;
    }

    bool is_subclass_of(klass* klass) {
        auto* super = this;
        while (super != nullptr) {
            if (super == klass) {
                return true;
            }
            super = super->super;
        }
        return false;
    }

    std::shared_ptr<klass> load_class(std::string name);

    std::shared_ptr<method> lookup_method(std::string name, std::string desciptor);
    std::shared_ptr<field> lookup_field(std::string name, std::string desciptor);

    std::shared_ptr<klass>  resolve_class (uint16_t idx);
    std::shared_ptr<field>  resolve_field (uint16_t idx);
    std::shared_ptr<method> resolve_method(uint16_t idx);
    std::shared_ptr<method> resolve_interface_method(uint16_t idx);

private:
    std::shared_ptr<constant_pool> _const_pool;
    method_list_type _methods;
    field_list_type _fields;
    loader* _loader;
};

struct field {
    struct klass* klass;
    std::string   name;
    std::string   descriptor;
    uint32_t      offset;
    uint16_t      access_flags;

    field(struct klass* klass_);
    ~field();

    field& operator=(const field&) = delete;
    field(const field&) = delete;

    bool is_static() const {
        return access_flags & JVM_ACC_STATIC;
    }

    bool matches(std::string name, std::string descriptor);
};

struct method {
    // Method lifecycle is tied to the class it belongs to. Use a pointer to
    // klass instead of a smart pointer to break the cyclic dependency during
    // destruction.
    struct klass* klass;
    uint16_t    access_flags;
    std::string name;
    std::string descriptor;
    struct klass* return_type;
    std::vector<struct klass*> arg_types;
    uint16_t    args_count;
    uint16_t    max_locals;
    char*       code;
    uint32_t    code_length;
    std::vector<uint8_t> trampoline;

    method() {
    }

    ~method() {
        delete[] code;
    }

    method& operator=(const method&) = delete;
    method(const method&) = delete;

    std::string full_name() const {
        return klass->name + "::" + name + descriptor;
    }

    bool is_init() const {
        return name[0] == '<';
    }

    bool is_native() const {
        return access_flags & JVM_ACC_NATIVE;
    }

    bool matches(const std::string& n, const std::string d) const
    {
       return name == n && descriptor == d;
    }
};

struct array {
{'fraction_non_alphanumeric': 0.11744007037607214, 'fraction_numerical': 0.00615790631185397, 'mean_word_length': 3.008373732921992, 'pattern_counts': {'":': 2, '<': 75, '<?xml version=': 0, '>': 77, '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': '311618', 'n_tokens_mistral': 3000, 'n_tokens_neox': 2973, 'n_words': 714}