mirror of
https://github.com/ProgramSnail/Lama.git
synced 2025-12-24 23:58:47 +00:00
modules: 'rebase' from byterun_with_modules, initial impl, without verification
This commit is contained in:
parent
73d3fbc388
commit
eb1ddfa447
14 changed files with 420 additions and 115 deletions
|
|
@ -2,4 +2,14 @@
|
|||
|
||||
#include "utils.h"
|
||||
|
||||
void run(Bytefile *bf, int argc, char **argv);
|
||||
// void run(Bytefile *bf, int argc, char **argv);
|
||||
|
||||
void run_init(size_t *stack);
|
||||
|
||||
void run_mod_rec(uint mod_id, int argc, char **argv);
|
||||
|
||||
void run_prepare_exec(int argc, char **argv);
|
||||
|
||||
void run_mod(uint mod_id, int argc, char **argv);
|
||||
|
||||
void run_cleanup();
|
||||
|
|
|
|||
23
byterun/include/module_manager.h
Normal file
23
byterun/include/module_manager.h
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
struct ModSearchResult {
|
||||
size_t symbol_offset;
|
||||
uint32_t mod_id;
|
||||
Bytefile *mod_file; // = NULL => not found
|
||||
};
|
||||
|
||||
void mod_add_search_path(const char *path);
|
||||
|
||||
Bytefile *mod_get(uint32_t id);
|
||||
|
||||
int32_t find_mod_loaded(const char *name); // < 0 => not found
|
||||
|
||||
int32_t mod_load(const char *name); // < 0 => not found
|
||||
|
||||
uint32_t mod_add(Bytefile *module);
|
||||
|
||||
struct ModSearchResult mod_search_pub_symbol(const char *name);
|
||||
|
|
@ -35,6 +35,7 @@ enum class Cmd : int8_t {
|
|||
ARRAY,
|
||||
FAIL,
|
||||
LINE,
|
||||
CALLF,
|
||||
PATT,
|
||||
Lread,
|
||||
Lwrite,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "../../runtime/gc.h"
|
||||
#include "module_manager.h"
|
||||
#include "runtime_externs.h"
|
||||
#include "types.h"
|
||||
#include "utils.h"
|
||||
|
|
@ -148,14 +149,14 @@ static inline void s_rotate_n(size_t n) {
|
|||
|
||||
// ------ functions ------
|
||||
|
||||
// |> param_0 ... param_n | frame[ ret rp prev_fp ¶ms &locals &end
|
||||
// |> param_0 ... param_n | frame[ ret rp prev_fp ... ¶ms &locals &end
|
||||
// ]
|
||||
// |> local_0 ... local_m |> | ...
|
||||
//
|
||||
// where |> defines corresponding frame pointer, | is stack pointer
|
||||
// location before / after new frame added
|
||||
static inline void s_enter_f(char *rp, bool is_closure_call, auint args_sz,
|
||||
auint locals_sz) {
|
||||
static inline void s_enter_f(char *rp, aint ret_module_id, 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,6 +187,7 @@ static inline void s_enter_f(char *rp, bool is_closure_call, auint args_sz,
|
|||
.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),
|
||||
};
|
||||
|
|
@ -226,6 +228,10 @@ 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);
|
||||
// TODO: return to ret_module
|
||||
}
|
||||
|
||||
static inline void print_stack() {
|
||||
|
|
|
|||
|
|
@ -22,13 +22,14 @@ 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 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 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]
|
||||
};
|
||||
|
||||
// NOTE: stack is [top -> bottom]
|
||||
|
|
@ -60,14 +61,20 @@ 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 construct_state(Bytefile *bf, struct State *s, void **stack);
|
||||
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 cleanup_state(struct State *state);
|
||||
|
||||
// TODO: print current mod id
|
||||
static inline void s_failure(struct State *s, const char *msg) {
|
||||
exec_failure(read_cmd(s->instr_ip, s->bf), s->current_line,
|
||||
s->instr_ip - s->bf->code_ptr, msg);
|
||||
|
|
@ -154,6 +161,7 @@ enum CMD_CTRLS {
|
|||
CMD_CTRL_ARRAY,
|
||||
CMD_CTRL_FAIL,
|
||||
CMD_CTRL_LINE,
|
||||
CMD_CTRL_CALLF,
|
||||
};
|
||||
|
||||
enum CMD_PATTS {
|
||||
|
|
|
|||
|
|
@ -10,13 +10,15 @@
|
|||
/* The unpacked representation of bytecode file */
|
||||
typedef struct {
|
||||
char *string_ptr; /* A pointer to the beginning of the string table */
|
||||
int *imports_ptr; /* A pointer to the beginning of imports table */
|
||||
int *public_ptr; /* A pointer to the beginning of publics table */
|
||||
char *code_ptr; /* A pointer to the bytecode itself */
|
||||
int *global_ptr; /* A pointer to the global area */
|
||||
int code_size; /* The size (in bytes) of code */
|
||||
uint stringtab_size; /* The size (in bytes) of the string table */
|
||||
uint global_area_size; /* The size (in words) of global area */
|
||||
uint public_symbols_number; /* The number of public symbols */
|
||||
uint imports_number; /* The number of imports */
|
||||
uint public_symbols_number; /* The number of public symbols */
|
||||
char buffer[0];
|
||||
} Bytefile;
|
||||
|
||||
|
|
@ -35,6 +37,14 @@ static inline const char *get_string_unsafe(const Bytefile *bf, size_t pos) {
|
|||
return &bf->string_ptr[pos];
|
||||
}
|
||||
|
||||
/* Gets import */
|
||||
static inline const char *get_import_unsafe(const Bytefile *f, size_t i) {
|
||||
if (i >= f->imports_number) {
|
||||
failure("import pos is out of range: %zu >= %i\n", i, f->imports_number);
|
||||
}
|
||||
return get_string_unsafe(f, f->imports_ptr[i]);
|
||||
}
|
||||
|
||||
/* Gets a name offset for a public symbol */
|
||||
static inline size_t get_public_name_offset_unsafe(const Bytefile *bf,
|
||||
size_t i) {
|
||||
|
|
@ -80,6 +90,14 @@ static inline const char *get_string_safe(const Bytefile *f, size_t pos) {
|
|||
return get_string_unsafe(f, pos);
|
||||
}
|
||||
|
||||
/* Gets import */
|
||||
static inline const char *get_import_safe(const Bytefile *f, size_t i) {
|
||||
if (i >= f->imports_number) {
|
||||
failure("import pos is out of range: %zu >= %i\n", i, f->imports_number);
|
||||
}
|
||||
return get_string_safe(f, f->imports_ptr[i]);
|
||||
}
|
||||
|
||||
/* Gets a name offset for a public symbol */
|
||||
static inline size_t get_public_name_offset_safe(const Bytefile *f, size_t i) {
|
||||
if (i >= f->public_symbols_number) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue