mirror of
https://github.com/ProgramSnail/Lama.git
synced 2025-12-06 06:48:48 +00:00
fixes
This commit is contained in:
parent
014f249b16
commit
c373b7ef82
2 changed files with 46 additions and 21 deletions
|
|
@ -7,11 +7,10 @@ extern "C" {
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
// TODO
|
|
||||||
void analyze(Bytefile *bf) {
|
void analyze(Bytefile *bf) {
|
||||||
static constexpr const int NOT_VISITED = -1;
|
static constexpr const int NOT_VISITED = -1;
|
||||||
std::vector<int> visited(bf->code_size, NOT_VISITED); // store stack depth
|
std::vector<int> visited(bf->code_size, NOT_VISITED); // store stack depth
|
||||||
std::vector<int> control_flow_in(bf->code_size, false); // store
|
std::vector<bool> control_flow_in(bf->code_size, false); // store
|
||||||
|
|
||||||
std::vector<size_t> to_visit_func;
|
std::vector<size_t> to_visit_func;
|
||||||
std::vector<size_t> to_visit_jmp;
|
std::vector<size_t> to_visit_jmp;
|
||||||
|
|
@ -197,17 +196,17 @@ void analyze(Bytefile *bf) {
|
||||||
break;
|
break;
|
||||||
case Cmd::BEGIN:
|
case Cmd::BEGIN:
|
||||||
case Cmd::CBEGIN:
|
case Cmd::CBEGIN:
|
||||||
// TODO: remember & check needed args count
|
|
||||||
if (current_begin_counter != nullptr) {
|
if (current_begin_counter != nullptr) {
|
||||||
failure("unexpected function beginning");
|
failure("unexpected function beginning");
|
||||||
}
|
}
|
||||||
|
current_args_count = ip_read_int(¤t_ip, *bf);
|
||||||
current_begin_counter = (uint16_t *)(current_ip + sizeof(uint16_t));
|
current_begin_counter = (uint16_t *)(current_ip + sizeof(uint16_t));
|
||||||
*current_begin_counter = 0;
|
|
||||||
current_args_count = ip_read_int(¤t_ip, *bf); // TODO: read int16 ??
|
|
||||||
current_locals_count = ip_read_int(¤t_ip, *bf);
|
current_locals_count = ip_read_int(¤t_ip, *bf);
|
||||||
|
// TODO: check uint16_t max ??
|
||||||
|
(*(uint16_t *)(current_ip - sizeof(uint16_t))) = current_locals_count;
|
||||||
|
*current_begin_counter = 0;
|
||||||
break;
|
break;
|
||||||
case Cmd::CLOSURE: {
|
case Cmd::CLOSURE: {
|
||||||
// // TODO: checks ??
|
|
||||||
ip_read_int(&ip, *bf); // offset
|
ip_read_int(&ip, *bf); // offset
|
||||||
size_t args_count = ip_read_int(¤t_ip, *bf); // args count
|
size_t args_count = ip_read_int(¤t_ip, *bf); // args count
|
||||||
extra_stack_during_opr = args_count;
|
extra_stack_during_opr = args_count;
|
||||||
|
|
@ -219,22 +218,31 @@ void analyze(Bytefile *bf) {
|
||||||
++current_stack_depth;
|
++current_stack_depth;
|
||||||
} break;
|
} break;
|
||||||
case Cmd::CALLC: {
|
case Cmd::CALLC: {
|
||||||
current_stack_depth -=
|
uint args_count = ip_read_int(¤t_ip, *bf);
|
||||||
ip_read_int(¤t_ip, *bf) + 1; // + closure itself
|
current_stack_depth -= args_count + 1; // + closure itself
|
||||||
if (current_stack_depth < 0) {
|
if (current_stack_depth < 0) {
|
||||||
failure("not enough elements in stack");
|
failure("not enough elements in stack");
|
||||||
}
|
}
|
||||||
++current_stack_depth;
|
++current_stack_depth;
|
||||||
// TODO: check args == cbegin args (?)
|
// NOTE: can't check args == cbegin args (?)
|
||||||
} break;
|
} break;
|
||||||
case Cmd::CALL: {
|
case Cmd::CALL: {
|
||||||
ip_read_int(¤t_ip, *bf); // call offset
|
uint call_offset = ip_read_int(¤t_ip, *bf); // call offset
|
||||||
current_stack_depth -= ip_read_int(¤t_ip, *bf);
|
uint args_count = ip_read_int(¤t_ip, *bf);
|
||||||
|
current_stack_depth -= args_count;
|
||||||
if (current_stack_depth < 0) {
|
if (current_stack_depth < 0) {
|
||||||
failure("not enough elements in stack");
|
failure("not enough elements in stack");
|
||||||
}
|
}
|
||||||
++current_stack_depth;
|
++current_stack_depth;
|
||||||
// TODO: check args == begin args
|
|
||||||
|
// TODO: unify with next loop
|
||||||
|
if (call_offset >= bf->code_size) {
|
||||||
|
failure("jump/call out of file");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args_count != *(uint *)(bf->code_ptr + call_offset + 1)) {
|
||||||
|
failure("wrong call argument count");
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
case Cmd::TAG:
|
case Cmd::TAG:
|
||||||
if (current_stack_depth < 1) {
|
if (current_stack_depth < 1) {
|
||||||
|
|
@ -315,8 +323,9 @@ void analyze(Bytefile *bf) {
|
||||||
bool is_call = (cmd == Cmd::CLOSURE || cmd == Cmd::CALL);
|
bool is_call = (cmd == Cmd::CLOSURE || cmd == Cmd::CALL);
|
||||||
|
|
||||||
uint jmp_p = ip_read_int(¤t_ip, *bf);
|
uint jmp_p = ip_read_int(¤t_ip, *bf);
|
||||||
if (jmp_p >= bf->code_size) { // TODO: check that > begin (?)
|
if (jmp_p >= bf->code_size) {
|
||||||
failure("jump out of file");
|
// NOTE: maybe also should check that > begin (?)
|
||||||
|
failure("jump/call out of file");
|
||||||
}
|
}
|
||||||
control_push(jmp_p, is_call ? to_visit_func : to_visit_jmp);
|
control_push(jmp_p, is_call ? to_visit_func : to_visit_jmp);
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,14 @@
|
||||||
|
|
||||||
struct State s;
|
struct State s;
|
||||||
|
|
||||||
|
static inline uint16_t ip_read_half_int(char **ip) {
|
||||||
|
if (*ip + sizeof(uint16_t) > s.bf->code_ptr + s.bf->code_size) {
|
||||||
|
failure("last command is invalid, int parameter can not be read\n");
|
||||||
|
}
|
||||||
|
*ip += sizeof(uint16_t);
|
||||||
|
return *(uint16_t *)((*ip) - sizeof(uint16_t));
|
||||||
|
}
|
||||||
|
|
||||||
static inline int ip_read_int(char **ip) {
|
static inline int ip_read_int(char **ip) {
|
||||||
if (*ip + sizeof(int) > s.bf->code_ptr + s.bf->code_size) {
|
if (*ip + sizeof(int) > s.bf->code_ptr + s.bf->code_size) {
|
||||||
failure("last command is invalid, int parameter can not be read\n");
|
failure("last command is invalid, int parameter can not be read\n");
|
||||||
|
|
@ -267,28 +275,36 @@ void run(Bytefile *bf, int argc, char **argv) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: read req stack from second part or args
|
|
||||||
case CMD_CTRL_BEGIN: { // BEGIN %d %d // function begin
|
case CMD_CTRL_BEGIN: { // BEGIN %d %d // function begin
|
||||||
int args_sz = ip_read_int(&s.ip);
|
uint args_sz = ip_read_int(&s.ip);
|
||||||
int locals_sz = ip_read_int(&s.ip);
|
uint locals_sz = ip_read_half_int(&s.ip);
|
||||||
|
uint max_additional_stack_sz = ip_read_half_int(&s.ip);
|
||||||
if (s.fp != NULL && s.call_ip == NULL) {
|
if (s.fp != NULL && s.call_ip == NULL) {
|
||||||
s_failure(&s, "begin should only be called after call");
|
s_failure(&s, "begin should only be called after call");
|
||||||
}
|
}
|
||||||
s_enter_f(s.call_ip /*ip from call*/, s.is_closure_call, args_sz,
|
s_enter_f(s.call_ip /*ip from call*/, s.is_closure_call, args_sz,
|
||||||
locals_sz);
|
locals_sz);
|
||||||
|
// TODO: add ifdef
|
||||||
|
if ((void **)__gc_stack_top + (aint)max_additional_stack_sz - 1 <= s.stack) {
|
||||||
|
s_failure(&s, "stack owerflow");
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: read req stack from second part of args
|
|
||||||
case CMD_CTRL_CBEGIN: { // CBEGIN %d %d
|
case CMD_CTRL_CBEGIN: { // CBEGIN %d %d
|
||||||
// NOTE: example not found, no checks done
|
// NOTE: example not found, no checks done
|
||||||
int args_sz = ip_read_int(&s.ip);
|
uint args_sz = ip_read_int(&s.ip);
|
||||||
int locals_sz = ip_read_int(&s.ip);
|
uint max_additional_stack_sz = ip_read_half_int(&s.ip);
|
||||||
|
uint locals_sz = ip_read_half_int(&s.ip);
|
||||||
if (s.fp != NULL && s.call_ip == NULL) {
|
if (s.fp != NULL && s.call_ip == NULL) {
|
||||||
s_failure(&s, "begin should only be called after call");
|
s_failure(&s, "begin should only be called after call");
|
||||||
}
|
}
|
||||||
s_enter_f(s.call_ip /*ip from call*/, s.is_closure_call, args_sz,
|
s_enter_f(s.call_ip /*ip from call*/, s.is_closure_call, args_sz,
|
||||||
locals_sz);
|
locals_sz);
|
||||||
|
// TODO: add ifdef
|
||||||
|
if ((void **)__gc_stack_top + (aint)max_additional_stack_sz - 1 <= s.stack) {
|
||||||
|
s_failure(&s, "stack owerflow");
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue