mirror of
https://github.com/ProgramSnail/Lama.git
synced 2025-12-05 22:38:44 +00:00
fix interpreter and analyzer with new algorithm (with bugs)
This commit is contained in:
parent
343a21ee2d
commit
58c9fd77c2
21 changed files with 3489 additions and 559 deletions
|
|
@ -4,4 +4,6 @@ extern "C" {
|
|||
#include "utils.h"
|
||||
}
|
||||
|
||||
void analyze(uint32_t mod_id);
|
||||
#include <vector>
|
||||
|
||||
void analyze(Bytefile *bf, std::vector<size_t> &&add_publics = {});
|
||||
|
|
|
|||
|
|
@ -7,10 +7,8 @@
|
|||
|
||||
void run_init(size_t *stack);
|
||||
|
||||
void run_mod_rec(uint mod_id, int argc, char **argv, bool do_verification);
|
||||
void set_argc_argv(int argc, char **argv);
|
||||
|
||||
void run_prepare_exec(int argc, char **argv);
|
||||
|
||||
void run_mod(uint mod_id, int argc, char **argv);
|
||||
void run_main(Bytefile *bf, int argc, char **argv);
|
||||
|
||||
void run_cleanup();
|
||||
|
|
|
|||
|
|
@ -5,26 +5,55 @@
|
|||
|
||||
#include "utils.h"
|
||||
|
||||
struct ModSearchResult {
|
||||
size_t symbol_offset;
|
||||
uint32_t mod_id;
|
||||
Bytefile *mod_file; // = NULL => not found
|
||||
Bytefile *run_with_imports(Bytefile *root, int argc, char **argv,
|
||||
bool do_verification);
|
||||
|
||||
// ---
|
||||
|
||||
enum BUILTIN : uint {
|
||||
BUILTIN_Luppercase,
|
||||
BUILTIN_Llowercase,
|
||||
BUILTIN_Lassert,
|
||||
BUILTIN_Lstring,
|
||||
BUILTIN_Llength,
|
||||
BUILTIN_LstringInt,
|
||||
BUILTIN_Lread,
|
||||
BUILTIN_Lwrite,
|
||||
BUILTIN_LmakeArray,
|
||||
BUILTIN_LmakeString,
|
||||
BUILTIN_Lstringcat,
|
||||
BUILTIN_LmatchSubString,
|
||||
BUILTIN_Lsprintf,
|
||||
BUILTIN_Lsubstring,
|
||||
BUILTIN_Li__Infix_4343, // ++
|
||||
BUILTIN_Lclone,
|
||||
BUILTIN_Lhash,
|
||||
BUILTIN_LtagHash,
|
||||
BUILTIN_Lcompare,
|
||||
BUILTIN_LflatCompare,
|
||||
BUILTIN_Lfst,
|
||||
BUILTIN_Lsnd,
|
||||
BUILTIN_Lhd,
|
||||
BUILTIN_Ltl,
|
||||
BUILTIN_Lprintf,
|
||||
BUILTIN_LreadLine,
|
||||
BUILTIN_Lfopen,
|
||||
BUILTIN_Lfclose,
|
||||
BUILTIN_Lfread,
|
||||
BUILTIN_Lfwrite,
|
||||
BUILTIN_Lfexists,
|
||||
BUILTIN_Lfprintf,
|
||||
BUILTIN_Lregexp,
|
||||
BUILTIN_LregexpMatch,
|
||||
BUILTIN_Lfailure,
|
||||
BUILTIN_Lsystem,
|
||||
BUILTIN_LgetEnv,
|
||||
BUILTIN_Lrandom,
|
||||
BUILTIN_Ltime,
|
||||
BUILTIN_Barray, // can't be run with run_stdlib_func
|
||||
BUILTIN_NONE,
|
||||
};
|
||||
|
||||
void mod_cleanup();
|
||||
enum BUILTIN id_by_builtin(const char *name);
|
||||
|
||||
void mod_add_search_path(const char *path);
|
||||
|
||||
const char *mod_get_name(uint32_t id);
|
||||
|
||||
Bytefile *mod_get(uint32_t id);
|
||||
|
||||
int32_t find_mod_loaded(const char *name); // < 0 => not found
|
||||
|
||||
int32_t mod_load(const char *name, bool do_verification); // < 0 => not found
|
||||
|
||||
uint32_t mod_add(Bytefile *module, bool do_verification);
|
||||
|
||||
struct ModSearchResult mod_search_pub_symbol(const char *name);
|
||||
|
||||
bool run_stdlib_func(const char *name, size_t args_count);
|
||||
void run_stdlib_func(enum BUILTIN id, size_t args_count);
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ enum class Cmd : int8_t {
|
|||
ARRAY,
|
||||
FAIL,
|
||||
LINE,
|
||||
// CALLF,
|
||||
BUILTIN,
|
||||
PATT,
|
||||
// NOTE: no longer used
|
||||
// Lread,
|
||||
|
|
@ -50,8 +50,6 @@ enum class Cmd : int8_t {
|
|||
|
||||
Bytefile *read_file(const char *fname);
|
||||
|
||||
Bytefile *merge_files(const std::vector<Bytefile> &bytefiles);
|
||||
|
||||
std::pair<Cmd, uint8_t> parse_command(char **ip, const Bytefile *bf);
|
||||
std::pair<Cmd, uint8_t> parse_command(char **ip, const Bytefile *bf,
|
||||
std::ostream &out);
|
||||
|
|
|
|||
|
|
@ -155,8 +155,8 @@ static inline void s_rotate_n(size_t n) {
|
|||
//
|
||||
// where |> defines corresponding frame pointer, | is stack pointer
|
||||
// location before / after new frame added
|
||||
static inline void s_enter_f(char *rp, aint ret_module_id, bool is_closure_call,
|
||||
auint args_sz, auint locals_sz) {
|
||||
static inline void s_enter_f(char *rp, bool is_closure_call, auint args_sz,
|
||||
auint locals_sz) {
|
||||
#ifdef DEBUG_VERSION
|
||||
printf("-> %i args sz\n", args_sz);
|
||||
printf("-> %i locals sz\n", locals_sz);
|
||||
|
|
@ -186,7 +186,6 @@ static inline void s_enter_f(char *rp, aint ret_module_id, bool is_closure_call,
|
|||
.ret = NULL, // field in frame itself
|
||||
.rp = rp,
|
||||
.prev_fp = (void **)s.fp,
|
||||
.ret_module_box = BOX(ret_module_id),
|
||||
.args_sz_box = BOX(args_sz),
|
||||
.locals_sz_box = BOX(locals_sz),
|
||||
};
|
||||
|
|
@ -227,9 +226,6 @@ static inline void s_exit_f() {
|
|||
}
|
||||
|
||||
s.ip = frame.rp;
|
||||
|
||||
s.current_module_id = UNBOX(frame.ret_module_box);
|
||||
s.bf = mod_get(s.current_module_id);
|
||||
}
|
||||
|
||||
static inline void print_stack(struct State *state) {
|
||||
|
|
|
|||
|
|
@ -23,14 +23,13 @@ static const size_t MAX_ARRAY_SIZE = 0x11111110;
|
|||
// ------ Frame ------
|
||||
|
||||
struct Frame {
|
||||
void *closure; // where closure value stored if needed
|
||||
void *ret; // store returned value [gc pointer]
|
||||
char *rp; // ret instruction pointer [not gc pointer]
|
||||
void **prev_fp; // ret function frame pointer [boxed value, not gc
|
||||
// pointer]
|
||||
aint ret_module_box; // module to return [boxed value, not gc pointer]
|
||||
aint args_sz_box; // store arguments [boxed value, not gc pointer]
|
||||
aint locals_sz_box; // store locals [boxed value, not gc pointer]
|
||||
void *closure; // where closure value stored if needed
|
||||
void *ret; // store returned value [gc pointer]
|
||||
char *rp; // ret instruction pointer [not gc pointer]
|
||||
void **prev_fp; // ret function frame pointer [boxed value, not gc
|
||||
// pointer]
|
||||
aint args_sz_box; // store arguments [boxed value, not gc pointer]
|
||||
aint locals_sz_box; // store locals [boxed value, not gc pointer]
|
||||
};
|
||||
|
||||
// NOTE: stack is [top -> bottom]
|
||||
|
|
@ -62,33 +61,27 @@ struct State {
|
|||
|
||||
bool is_closure_call;
|
||||
|
||||
uint current_module_id;
|
||||
uint call_module_id;
|
||||
|
||||
char *ip; // instruction pointer
|
||||
char *instr_ip; // poiter to current instruction
|
||||
char *call_ip; // prev instruction pointer (to remember jmp locations)
|
||||
};
|
||||
|
||||
void init_state(struct State *s, void **stack);
|
||||
void init_mod_state(uint mod_id, struct State *s);
|
||||
void init_mod_state_globals(struct State *s);
|
||||
void prepare_state(Bytefile *bf, struct State *s);
|
||||
void push_globals(struct State *s);
|
||||
void cleanup_state(struct State *state);
|
||||
|
||||
static inline void s_failure(struct State *s, const char *msg) {
|
||||
exec_failure(read_cmd(s->instr_ip, s->bf), mod_get_name(s->current_module_id),
|
||||
s->current_line, s->instr_ip - s->bf->code_ptr, msg);
|
||||
exec_failure(read_cmd(s->instr_ip, s->bf), s->current_line,
|
||||
s->instr_ip - s->bf->code_ptr, msg);
|
||||
}
|
||||
|
||||
static inline void ip_failure(char *ip, uint32_t mod_id, const char *msg) {
|
||||
Bytefile *bf = mod_get(mod_id);
|
||||
exec_failure(read_cmd(ip, bf), mod_get_name(mod_id), 0, ip - bf->code_ptr,
|
||||
msg);
|
||||
static inline void ip_failure(char *ip, Bytefile *bf, const char *msg) {
|
||||
exec_failure(read_cmd(ip, bf), 0, ip - bf->code_ptr, msg);
|
||||
}
|
||||
|
||||
static inline void ip_safe_failure(char *ip, uint32_t mod_id, const char *msg) {
|
||||
Bytefile *bf = mod_get(mod_id);
|
||||
exec_failure("_UNDEF_", mod_get_name(mod_id), 0, ip - bf->code_ptr, msg);
|
||||
static inline void ip_safe_failure(char *ip, Bytefile *bf, const char *msg) {
|
||||
exec_failure("_UNDEF_", 0, ip - bf->code_ptr, msg);
|
||||
}
|
||||
|
||||
// ------ VarCategory ------
|
||||
|
|
@ -164,7 +157,7 @@ enum CMD_CTRLS {
|
|||
CMD_CTRL_ARRAY,
|
||||
CMD_CTRL_FAIL,
|
||||
CMD_CTRL_LINE,
|
||||
// CMD_CTRL_CALLF,
|
||||
CMD_CTRL_BUILTIN,
|
||||
};
|
||||
|
||||
enum CMD_PATTS {
|
||||
|
|
|
|||
|
|
@ -7,11 +7,6 @@
|
|||
#include "../../runtime/runtime.h"
|
||||
#include "../../runtime/runtime_common.h"
|
||||
|
||||
typedef struct {
|
||||
uint offset;
|
||||
char label[0];
|
||||
} Subst;
|
||||
|
||||
/* The unpacked representation of bytecode file */
|
||||
typedef struct {
|
||||
uint main_offset; /* offset of the function 'main' */
|
||||
|
|
@ -30,10 +25,10 @@ typedef struct {
|
|||
char buffer[0];
|
||||
} Bytefile;
|
||||
|
||||
static inline void exec_failure(const char *cmd, const char *module_name,
|
||||
int line, aint offset, const char *msg) {
|
||||
failure("*** RUNTIME ERROR: %s:%i(0x%.8x):%s error: %s\n", module_name, line,
|
||||
offset, cmd, msg);
|
||||
static inline void exec_failure(const char *cmd, int line, aint offset,
|
||||
const char *msg) {
|
||||
failure("*** RUNTIME ERROR: %i(0x%.8x):%s error: %s\n", line, offset, cmd,
|
||||
msg);
|
||||
}
|
||||
|
||||
// --- unsafe versions
|
||||
|
|
@ -166,3 +161,9 @@ static inline uint8_t ip_read_byte_safe(char **ip, const Bytefile *bf) {
|
|||
static inline const char *ip_read_string_safe(char **ip, const Bytefile *bf) {
|
||||
return get_string_safe(bf, ip_read_int_safe(ip, bf));
|
||||
}
|
||||
|
||||
// ---
|
||||
|
||||
static inline size_t calc_publics_size(size_t publics_number) {
|
||||
return publics_number * 2 * sizeof(int);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue