Skip to content

Commit

Permalink
106 complex test (#112)
Browse files Browse the repository at this point in the history
* #106: refactored object array

* #106: Implemented mod and ifnull

* #106: Implemented dump chai function

* #106: Updated isa md

* #106: Implemented test

* #106: Implemented test

* #106: Implemented test

* #106: Removed pseudo-code.md

* #106: format
  • Loading branch information
levBagryansky authored Jun 14, 2024
1 parent 9272eb1 commit 6f8223b
Show file tree
Hide file tree
Showing 9 changed files with 492 additions and 81 deletions.
2 changes: 2 additions & 0 deletions ISA.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Notation: `imm` is raw value, `[imm]` is value from constant pool by number imm.
| Muli | I | i64, mul acc by [imm] |
| Div | R | i64, divides acc by R1 |
| Divi | I | i64, divides acc by [imm] |
| Modi | I | i64, acc = acc % [imm] |
| Ldiaf | I | f64, loads constant [i] to acc |
| Addf | R | f64, Adds R1 to acc |
| Addif | I | f64, Adds [imm] to acc |
Expand All @@ -41,6 +42,7 @@ Notation: `imm` is raw value, `[imm]` is value from constant pool by number imm.
| If_icmple | RI | i64, if acc <= r1 then branch to instruction at offset(instructions) imm otherwise just next instr |
| If_acmpeq | RI | ref, if references are equal, branch to instruction at offset(instructions) imm |
| If_acmpne | RI | ref, if references are not equal, branch to instruction at offset(instructions) imm |
| If_null | I | ref, if reference in acc is null, branch to instruction at offset(instructions) imm |
| Сmpgf | R | f64 -> i64, compare acc with r1. Acc became 1 i64 if greater than r1, 0 if equal, otherwise -1 |
| Cmplf | R | f64 -> i64, compare acc with r1. Acc became 1 i64 if less than r1, 0 if equal, otherwise -1 |
| Goto | I | Goes to another instruction at branchoffset(instructions) imm |
Expand Down
12 changes: 6 additions & 6 deletions include/ChaiVM/interpreter/executor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ class Executor {
void muli(Instruction ins);
void div(Instruction ins);
void divi(Instruction ins);
void modi(Instruction ins);
void mod(Instruction ins);
void ldiaf(Instruction ins);
void addf(Instruction ins);
void addif(Instruction ins);
Expand All @@ -73,6 +75,7 @@ class Executor {
void if_icmple(Instruction ins);
void if_acmpeq(Instruction ins);
void if_acmpne(Instruction ins);
void if_null(Instruction ins);
void cmpgf(Instruction ins);
void cmplf(Instruction ins);
void g0t0(Instruction ins);
Expand Down Expand Up @@ -113,6 +116,8 @@ class Executor {
&Executor::muli,
&Executor::div,
&Executor::divi,
&Executor::modi,
&Executor::mod,
&Executor::ldiaf,
&Executor::addf,
&Executor::addif,
Expand All @@ -136,6 +141,7 @@ class Executor {
&Executor::if_icmple,
&Executor::if_acmpeq,
&Executor::if_acmpne,
&Executor::if_null,
&Executor::cmpgf,
&Executor::cmplf,
&Executor::g0t0,
Expand Down Expand Up @@ -183,10 +189,4 @@ class InvalidInstruction : public std::runtime_error {
const char *what() const noexcept override;
};

class IndexOutOfBoundary : public std::runtime_error {
public:
explicit IndexOutOfBoundary(char const *msg);
IndexOutOfBoundary(const std::string &msg);
const char *what() const noexcept override;
};
} // namespace chai::interpreter
40 changes: 38 additions & 2 deletions include/ChaiVM/interpreter/objects.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "ChaiVM/interpreter/code-manager/klass.hpp"
#include "ChaiVM/memory/linear-allocator.hpp"
#include "ChaiVM/memory/linear-buffer.hpp"
#include "executor.hpp"
#include <cassert>

namespace chai::interpreter {
Expand Down Expand Up @@ -55,7 +56,7 @@ class Object {
* header).
* @return Value of member.
*/
chsize_t getMember(Immidiate offset) const;
const chsize_t &getMember(Immidiate offset) const;

/**
* Set member.
Expand All @@ -65,7 +66,7 @@ class Object {
*/
void setMember(Immidiate offset, chsize_t value) const;

private:
protected:
ObjectHeader *header_;

/**
Expand All @@ -75,4 +76,39 @@ class Object {
chsize_t *members_;
};

class IndexOutOfBoundary : public std::runtime_error {
public:
explicit IndexOutOfBoundary(char const *msg);
IndexOutOfBoundary(const std::string &msg);
const char *what() const noexcept override;
};

/**
* Convenient way to use array of objects object.
* We consider size as the first member of object.
*/
class ObjectArray final : private Object {

public:
/**
* Ctor.
* Create object from ref to object.
* @param ref Ref to object (usually contains in register).
*/
explicit ObjectArray(chsize_t ref);

chsize_t length() const;

chai::chsize_t &operator[](int64_t i) &;

const chsize_t &operator[](int64_t i) const &;

/**
* Calculate size (in bytes) of object array.
* @param len Array length/
* @return size in bytes.
*/
static chsize_t sizeOfObjectArray(int64_t len);
};

} // namespace chai::interpreter
52 changes: 33 additions & 19 deletions src/ChaiVM/interpreter/executor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ namespace chai::interpreter {
#define DO_NEXT_INS() \
Instruction newIns = \
decoder::parse(currentFrame_->func_.code[pc() / sizeof(bytecode_t)]); \
/*std::cout << "Next inst: " << OP_TO_STR[newIns.operation] << ", imm = " \
* << newIns.immidiate << std::endl; */ \
(this->*HANDLER_ARR[newIns.operation])(newIns);

Executor::Executor(CodeManager *manager, memory::LinearBuffer &framesBuffer,
Expand Down Expand Up @@ -133,6 +135,20 @@ void Executor::divi(Instruction ins) {
advancePc();
DO_NEXT_INS()
}
void Executor::modi(Instruction ins) {
acc() = static_cast<chsize_t>(
static_cast<int64_t>(acc()) %
static_cast<int64_t>(codeManager_->getCnst(ins.immidiate)));
advancePc();
DO_NEXT_INS()
}
void Executor::mod(Instruction ins) {
acc() =
static_cast<chsize_t>(static_cast<int64_t>(acc()) %
static_cast<int64_t>((*currentFrame_)[ins.r1]));
advancePc();
DO_NEXT_INS()
}
void Executor::ldiaf(Instruction ins) {
double immd = std::bit_cast<double>(codeManager_->getCnst(ins.immidiate));
acc() = std::bit_cast<chsize_t>(immd);
Expand Down Expand Up @@ -197,8 +213,7 @@ void Executor::divif(Instruction ins) {
DO_NEXT_INS()
}
void Executor::icprint(Instruction ins) {
assert(acc() <= 0xFF);
std::cout << acc();
std::cout << static_cast<int64_t>(acc()) << " ";
advancePc();
DO_NEXT_INS()
}
Expand Down Expand Up @@ -294,6 +309,14 @@ void Executor::if_acmpne(Instruction ins) {
*/
DO_NEXT_INS()
}
void Executor::if_null(Instruction ins) {
if (acc() == CHAI_NULL) {
pc() += sizeof(bytecode_t) * static_cast<int16_t>(ins.immidiate);
} else {
advancePc();
}
DO_NEXT_INS()
}
void Executor::cmpgf(Instruction ins) {
double acc_f64 = std::bit_cast<double>(acc());
double r1_f64 = std::bit_cast<double>((*currentFrame_)[ins.r1]);
Expand Down Expand Up @@ -372,15 +395,16 @@ void Executor::set_f64in_arr(Instruction ins) {
}
void Executor::new_ref_arr(Instruction ins) {
chsize_t len = acc();
chsize_t num_bytes = sizeof(ObjectHeader) + len * sizeof(chsize_t);
chsize_t num_bytes = ObjectArray::sizeOfObjectArray(len);
auto *object_arr =
new (objectsAllocator_.allocate(num_bytes)) uint8_t[num_bytes]();
auto *pheader = reinterpret_cast<ObjectHeader *>(object_arr);
auto *members =
reinterpret_cast<chsize_t *>(object_arr + sizeof(ObjectHeader));
pheader->size_ = num_bytes;
pheader->klassId_ = OBJ_ARR_IMM;
for (int i = 0; i < len; ++i) {
members[0] = len;
for (int i = 1; i < len; ++i) {
members[i] = CHAI_NULL;
}
acc() = std::bit_cast<chsize_t>(object_arr);
Expand All @@ -389,20 +413,16 @@ void Executor::new_ref_arr(Instruction ins) {
}
void Executor::get_ref_from_arr(Instruction ins) {
auto i = static_cast<int64_t>((*currentFrame_)[ins.r1]);
Object object{acc()};
if (i >= object.countMembers()) {
throw IndexOutOfBoundary("index " + std::to_string(i) +
" is greater than array length " +
std::to_string(object.countMembers()));
}
acc() = object.getMember(i * sizeof(chsize_t));
ObjectArray array{acc()};
acc() = array[i];
advancePc();
DO_NEXT_INS();
}
void Executor::set_ref_in_arr(Instruction ins) {
auto i = static_cast<int64_t>((*currentFrame_)[ins.r1]);
chsize_t new_ref = (*currentFrame_)[ins.r2];
Object{acc()}.setMember(i * sizeof(chsize_t), new_ref);
ObjectArray array{acc()};
array[i] = new_ref;
advancePc();
DO_NEXT_INS();
}
Expand Down Expand Up @@ -447,6 +467,7 @@ void Executor::alloc_ref(Instruction ins) {
auto *fields = reinterpret_cast<chsize_t *>(object + sizeof(*pheader));
pheader->size_ = klass.instanceSize();
pheader->klassId_ = ins.immidiate;
pheader->klassId_ = ins.immidiate;
for (int i = 0; i < klass.nFields(); ++i) {
assert(fields[i] == 0);
}
Expand Down Expand Up @@ -490,11 +511,4 @@ const char *InvalidInstruction::what() const noexcept {
return runtime_error::what();
}

IndexOutOfBoundary::IndexOutOfBoundary(const char *msg) : runtime_error(msg) {}
IndexOutOfBoundary::IndexOutOfBoundary(const std::string &msg)
: runtime_error(msg) {}
const char *IndexOutOfBoundary::what() const noexcept {
return runtime_error::what();
}

} // namespace chai::interpreter
40 changes: 39 additions & 1 deletion src/ChaiVM/interpreter/objects.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ chsize_t Object::countMembers() const {
return (header_->size_ - sizeof(ObjectHeader)) / sizeof(chsize_t);
}

chsize_t Object::getMember(Immidiate offset) const {
const chsize_t &Object::getMember(Immidiate offset) const {
assert(offset % sizeof(chsize_t) == 0);
return members_[offset / sizeof(chsize_t)];
}
Expand All @@ -26,4 +26,42 @@ void Object::setMember(Immidiate offset, chsize_t value) const {
members_[offset / sizeof(chsize_t)] = value;
}

IndexOutOfBoundary::IndexOutOfBoundary(const char *msg) : runtime_error(msg) {}
IndexOutOfBoundary::IndexOutOfBoundary(const std::string &msg)
: runtime_error(msg) {}
const char *IndexOutOfBoundary::what() const noexcept {
return runtime_error::what();
}

ObjectArray::ObjectArray(chsize_t ref) : Object(ref) {}

chsize_t ObjectArray::length() const { return Object::countMembers() - 1; }

chai::chsize_t &ObjectArray::operator[](int64_t i) & {
if (i < 0) {
std::cout << "i < 0" << std::endl;
i += length();
}
if (i >= length()) {
throw IndexOutOfBoundary("index " + std::to_string(i) +
" is greater than array length " +
std::to_string(length()));
}
return Object::members_[i + 1];
}

const chsize_t &ObjectArray::operator[](int64_t i) const & {
assert(i >= 0);
if (i >= length()) {
throw IndexOutOfBoundary("index " + std::to_string(i) +
" is greater than array length " +
std::to_string(length()));
}
return Object::members_[i + 1];
}

chsize_t ObjectArray::sizeOfObjectArray(int64_t len) {
return sizeof(ObjectHeader) + (1 + len) * sizeof(chsize_t);
}

} // namespace chai::interpreter
2 changes: 2 additions & 0 deletions test/ChaiVM/interpreter/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ chai_test(decoder-test.cpp)
chai_test(code-manager-test.cpp)
chai_test(./executor_test.cpp)
chai_test(./simple-programs-executor-test.cpp)
chai_test(./complex-bar-foo-executor-test.cpp)

target_sources(simple-programs-executor-test PRIVATE executor-test-fixture.cpp)
target_sources(complex-bar-foo-executor-test PRIVATE executor-test-fixture.cpp)
target_sources(executor_test PRIVATE executor-test-fixture.cpp)
Loading

0 comments on commit 6f8223b

Please sign in to comment.