diff --git a/byterun/dune b/byterun/dune index 258b18920..cf8dcb382 100644 --- a/byterun/dune +++ b/byterun/dune @@ -5,7 +5,7 @@ (:main src/cli.cpp) (:parser src/parser.cpp) (:analyzer src/analyzer.cpp) - (:module_manager module_manager.o) + (:module_manager src/module_manager.cpp) (:obj types.o interpreter.o) (:runtime ../runtime/runtime.a)) (mode @@ -34,14 +34,3 @@ (promote (until-clean))) (action (run gcc -Wall -Wextra -Iinclude/ -DWITH_CHECK -c %{src} -o %{target}))) - -(rule -(target module_manager.o) -(deps - (:include (source_tree include)) - (:src src/module_manager.cpp) - (:runtime ../runtime/runtime.a)) - (mode - (promote (until-clean))) - (action - (run g++ -Wall -Wextra -std=c++20 -Iinclude/ -c %{src} -o %{target}))) diff --git a/byterun/include/analyzer.hpp b/byterun/include/analyzer.hpp index 9a2b533a5..a006c5ce7 100644 --- a/byterun/include/analyzer.hpp +++ b/byterun/include/analyzer.hpp @@ -4,4 +4,6 @@ extern "C" { #include "utils.h" } -void analyze(uint32_t mod_id); +#include + +void analyze(Bytefile *bf, std::vector &&add_publics = {}); diff --git a/byterun/include/interpreter.h b/byterun/include/interpreter.h index d270b9f72..cebbb3142 100644 --- a/byterun/include/interpreter.h +++ b/byterun/include/interpreter.h @@ -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(); diff --git a/byterun/include/module_manager.h b/byterun/include/module_manager.h index 22a7c732a..d6e31d036 100644 --- a/byterun/include/module_manager.h +++ b/byterun/include/module_manager.h @@ -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); diff --git a/byterun/include/parser.hpp b/byterun/include/parser.hpp index 8bee8adbd..3f63a2ca9 100644 --- a/byterun/include/parser.hpp +++ b/byterun/include/parser.hpp @@ -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 &bytefiles); - std::pair parse_command(char **ip, const Bytefile *bf); std::pair parse_command(char **ip, const Bytefile *bf, std::ostream &out); diff --git a/byterun/include/stack.h b/byterun/include/stack.h index 04f1ff05f..005d821c9 100644 --- a/byterun/include/stack.h +++ b/byterun/include/stack.h @@ -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) { diff --git a/byterun/include/types.h b/byterun/include/types.h index bb4cb3d0c..53315f8c5 100644 --- a/byterun/include/types.h +++ b/byterun/include/types.h @@ -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 { diff --git a/byterun/include/utils.h b/byterun/include/utils.h index b201df3a9..4d26b8527 100644 --- a/byterun/include/utils.h +++ b/byterun/include/utils.h @@ -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); +} diff --git a/byterun/regression_check.sh b/byterun/regression_check.sh index 2fc1c31bc..162a7d908 100755 --- a/byterun/regression_check.sh +++ b/byterun/regression_check.sh @@ -10,12 +10,13 @@ compiler=../_build/default/src/Driver.exe echo "Used compiler path:" echo $compiler -for test in ../regression/*.lama; do +for test in ../regression/*009.lama; do echo $test $compiler -b $test > /dev/null test_file="${test%.*}" echo $test_file - cat $test_file.input | ./byterun.exe -vi test*.bc > /dev/null + cat $test_file.input | ./byterun.exe -p test*.bc #> /dev/null + cat $test_file.input | ./byterun.exe -vi test*.bc #> /dev/null rm test*.bc echo "done" done diff --git a/byterun/src/analyzer.cpp b/byterun/src/analyzer.cpp index 24ec0feea..1a278658a 100644 --- a/byterun/src/analyzer.cpp +++ b/byterun/src/analyzer.cpp @@ -9,13 +9,11 @@ extern "C" { #include -void analyze(uint32_t mod_id) { - Bytefile *bf = mod_get(mod_id); - +void analyze(Bytefile *bf, std::vector &&add_publics) { static constexpr const int NOT_VISITED = -1; std::vector visited(bf->code_size, NOT_VISITED); // store stack depth - std::vector to_visit_func; + std::vector to_visit_func = std::move(add_publics); std::vector to_visit_jmp; int current_stack_depth = 0; @@ -30,57 +28,55 @@ void analyze(uint32_t mod_id) { char *current_ip = ip; char *saved_current_ip = current_ip; - auto const jmp_to_visit_push = [&saved_current_ip, mod_id, &visited, + auto const jmp_to_visit_push = [&saved_current_ip, bf, &visited, ¤t_stack_depth, &to_visit_jmp](size_t offset) { if (visited[offset] == NOT_VISITED) { visited[offset] = current_stack_depth; to_visit_jmp.push_back(offset); } else if (visited[offset] != current_stack_depth) { - ip_failure(saved_current_ip, mod_id, + ip_failure(saved_current_ip, bf, "different stack depth on same point is not allowed"); } }; - auto const func_to_visit_push = [&saved_current_ip, mod_id, &visited, + auto const func_to_visit_push = [&saved_current_ip, bf, &visited, &to_visit_func](size_t offset) { if (visited[offset] == NOT_VISITED) { visited[offset] = 0; to_visit_func.push_back(offset); } else if (visited[offset] != 0) { - ip_failure(saved_current_ip, mod_id, + ip_failure(saved_current_ip, bf, "different stack depth on same point is not allowed"); } }; - auto const check_correct_var = [&saved_current_ip, mod_id, &globals_count, + auto const check_correct_var = [&saved_current_ip, bf, &globals_count, ¤t_locals_count, ¤t_args_count, &is_in_closure](uint8_t l, uint id) { if (l > 3) { - ip_failure(saved_current_ip, mod_id, "unexpected variable category"); + ip_failure(saved_current_ip, bf, "unexpected variable category"); } VarCategory category = to_var_category(l); switch (category) { case VAR_GLOBAL: if (id >= globals_count) { - ip_failure(saved_current_ip, mod_id, - "global var index is out of range"); + ip_failure(saved_current_ip, bf, "global var index is out of range"); } break; case VAR_LOCAL: if (id >= current_locals_count) { - ip_failure(saved_current_ip, mod_id, "local var index is out of range"); + ip_failure(saved_current_ip, bf, "local var index is out of range"); } break; case VAR_ARGUMENT: if (id >= current_args_count) { - ip_failure(saved_current_ip, mod_id, - "argument var index is out of range"); + ip_failure(saved_current_ip, bf, "argument var index is out of range"); } break; case VAR_CLOSURE: if (!is_in_closure) { - ip_failure(saved_current_ip, mod_id, + ip_failure(saved_current_ip, bf, "can't access closure vars outside of closure"); } // NOTE: impossible to properly check bounds there @@ -89,13 +85,13 @@ void analyze(uint32_t mod_id) { }; // add publics - to_visit_func.reserve(bf->public_symbols_number); + to_visit_func.reserve(bf->public_symbols_number + to_visit_func.size()); for (size_t i = 0; i < bf->public_symbols_number; ++i) { func_to_visit_push(get_public_offset_safe(bf, i)); } if (to_visit_func.size() == 0) { - failure("no public symbols detected"); + failure("no public symbols detected\n"); } while (true) { @@ -112,7 +108,8 @@ void analyze(uint32_t mod_id) { if (to_visit_jmp.empty()) { current_begin_counter = nullptr; if (func_end_found != 1) { - failure("each function should have exactly one end"); + failure("each function should have exactly one end (%zu found)\n", + func_end_found); } continue; } @@ -121,12 +118,11 @@ void analyze(uint32_t mod_id) { } if (ip >= bf->code_ptr + bf->code_size) { - ip_safe_failure(ip, mod_id, - "instruction pointer is out of range (>= size)"); + ip_safe_failure(ip, bf, "instruction pointer is out of range (>= size)"); } if (ip < bf->code_ptr) { - ip_safe_failure(ip, mod_id, "instruction pointer is out of range (< 0)"); + ip_safe_failure(ip, bf, "instruction pointer is out of range (< 0)"); } current_ip = ip; @@ -134,18 +130,18 @@ void analyze(uint32_t mod_id) { #ifdef DEBUG_VERSION const auto [cmd, l] = parse_command(&ip, bf, std::cout); + std::cout << '\n'; #else const auto [cmd, l] = parse_command(&ip, bf); #endif if (current_begin_counter == nullptr && cmd != Cmd::BEGIN && cmd != Cmd::CBEGIN) { - ip_failure(saved_current_ip, mod_id, - "function does not start with begin"); + ip_failure(saved_current_ip, bf, "function does not start with begin"); } if (visited[current_ip - bf->code_ptr] == NOT_VISITED) { - ip_failure(saved_current_ip, mod_id, "not visited command"); + ip_failure(saved_current_ip, bf, "not visited command"); } current_stack_depth = visited[current_ip - bf->code_ptr]; @@ -161,7 +157,7 @@ void analyze(uint32_t mod_id) { case Cmd::BINOP: current_stack_depth -= 2; if (current_stack_depth < 0) { - ip_failure(saved_current_ip, mod_id, "not enough elements in stack"); + ip_failure(saved_current_ip, bf, "not enough elements in stack"); } ++current_stack_depth; break; @@ -175,21 +171,21 @@ void analyze(uint32_t mod_id) { ip_read_string_unsafe(¤t_ip, bf); current_stack_depth -= ip_read_int_unsafe(¤t_ip); if (current_stack_depth < 0) { - ip_failure(saved_current_ip, mod_id, "not enough elements in stack"); + ip_failure(saved_current_ip, bf, "not enough elements in stack"); } ++current_stack_depth; break; case Cmd::STI: current_stack_depth -= 2; if (current_stack_depth < 0) { - ip_failure(saved_current_ip, mod_id, "not enough elements in stack"); + ip_failure(saved_current_ip, bf, "not enough elements in stack"); } ++current_stack_depth; break; case Cmd::STA: current_stack_depth -= 3; if (current_stack_depth < 0) { - ip_failure(saved_current_ip, mod_id, "not enough elements in stack"); + ip_failure(saved_current_ip, bf, "not enough elements in stack"); } ++current_stack_depth; break; @@ -207,19 +203,19 @@ void analyze(uint32_t mod_id) { break; case Cmd::DUP: if (current_stack_depth < 1) { - ip_failure(saved_current_ip, mod_id, "not enough elements in stack"); + ip_failure(saved_current_ip, bf, "not enough elements in stack"); } ++current_stack_depth; break; case Cmd::SWAP: if (current_stack_depth < 2) { - ip_failure(saved_current_ip, mod_id, "not enough elements in stack"); + ip_failure(saved_current_ip, bf, "not enough elements in stack"); } break; case Cmd::ELEM: current_stack_depth -= 2; if (current_stack_depth < 0) { - ip_failure(saved_current_ip, mod_id, "not enough elements in stack"); + ip_failure(saved_current_ip, bf, "not enough elements in stack"); } ++current_stack_depth; break; @@ -234,7 +230,7 @@ void analyze(uint32_t mod_id) { case Cmd::ST: check_correct_var(l, ip_read_int_unsafe(¤t_ip)); if (current_stack_depth < 1) { - ip_failure(saved_current_ip, mod_id, "not enough elements in stack"); + ip_failure(saved_current_ip, bf, "not enough elements in stack"); } break; case Cmd::CJMPz: @@ -244,13 +240,14 @@ void analyze(uint32_t mod_id) { case Cmd::BEGIN: case Cmd::CBEGIN: if (current_begin_counter != nullptr) { - ip_failure(saved_current_ip, mod_id, "unexpected function beginning"); + ip_failure(saved_current_ip, bf, "unexpected function beginning"); } current_args_count = ip_read_int_unsafe(¤t_ip); current_begin_counter = (uint16_t *)(current_ip + sizeof(uint16_t)); current_locals_count = ip_read_int_unsafe(¤t_ip); if (current_locals_count >= std::numeric_limits::max()) { - ip_failure(saved_current_ip, mod_id, "too many locals in functions"); + std::cerr << current_locals_count << " locals" << '\n'; + ip_failure(saved_current_ip, bf, "too many locals in functions"); } (*(uint16_t *)(current_ip - sizeof(uint16_t))) = current_locals_count; *current_begin_counter = 0; @@ -269,12 +266,12 @@ void analyze(uint32_t mod_id) { ++current_stack_depth; // if (closure_offset >= bf->code_size) { - // ip_failure(saved_current_ip, mod_id, "jump/call out of file"); + // ip_failure(saved_current_ip, bf, "jump/call out of file"); // } // NOTE: is not always true // if (!is_command_name(bf->code_ptr + closure_offset, bf, Cmd::CBEGIN)) { - // ip_failure(saved_current_ip, mod_id, "closure should point to + // ip_failure(saved_current_ip, bf, "closure should point to // cbegin"); // } } break; @@ -282,7 +279,7 @@ void analyze(uint32_t mod_id) { uint args_count = ip_read_int_unsafe(¤t_ip); current_stack_depth -= args_count + 1; // + closure itself if (current_stack_depth < 0) { - ip_failure(saved_current_ip, mod_id, "not enough elements in stack"); + ip_failure(saved_current_ip, bf, "not enough elements in stack"); } ++current_stack_depth; // NOTE: can't check args == cbegin args @@ -292,29 +289,29 @@ void analyze(uint32_t mod_id) { uint args_count = ip_read_int_unsafe(¤t_ip); current_stack_depth -= args_count; if (current_stack_depth < 0) { - ip_failure(saved_current_ip, mod_id, "not enough elements in stack"); + ip_failure(saved_current_ip, bf, "not enough elements in stack"); } ++current_stack_depth; if ((int)call_offset >= bf->code_size) { - ip_failure(saved_current_ip, mod_id, "jump/call out of file"); + ip_failure(saved_current_ip, bf, "jump/call out of file"); } if (!is_command_name(bf->code_ptr + call_offset, bf, Cmd::BEGIN)) { - ip_failure(saved_current_ip, mod_id, "call should point to begin"); + ip_failure(saved_current_ip, bf, "call should point to begin"); } if (args_count != *(uint *)(bf->code_ptr + call_offset + 1)) { - ip_failure(saved_current_ip, mod_id, "wrong call argument count"); + ip_failure(saved_current_ip, bf, "wrong call argument count"); } } break; case Cmd::TAG: if (current_stack_depth < 1) { - ip_failure(saved_current_ip, mod_id, "not enough elements in stack"); + ip_failure(saved_current_ip, bf, "not enough elements in stack"); } break; case Cmd::ARRAY: if (current_stack_depth < 1) { - ip_failure(saved_current_ip, mod_id, "not enough elements in stack"); + ip_failure(saved_current_ip, bf, "not enough elements in stack"); } break; case Cmd::FAIL: @@ -322,25 +319,31 @@ void analyze(uint32_t mod_id) { break; case Cmd::LINE: break; - // case Cmd::CALLF: { - // // TODO: find link to real function and replace call (need to save all - // // modules in one space) <- optimization + case Cmd::BUILTIN: { + std::cout << "builtin\n"; + // TODO: find link to real function and replace call (need to save all + // modules in one space) <- optimization - // ip_read_int_unsafe(¤t_ip); // function name (str) - // uint args_count = ip_read_int_unsafe(¤t_ip); - // current_stack_depth -= args_count; - // if (current_stack_depth < 0) { - // ip_failure(saved_current_ip, mod_id, "not enough elements in stack"); - // } - // ++current_stack_depth; - // } break; + size_t id = ip_read_int_unsafe(¤t_ip); // builtin id + + if (id >= BUILTIN_NONE) { + ip_failure(saved_current_ip, bf, "undefined builtin id"); + } + + uint args_count = ip_read_int_unsafe(¤t_ip); + current_stack_depth -= args_count; + if (current_stack_depth < 0) { + ip_failure(saved_current_ip, bf, "not enough elements in stack"); + } + ++current_stack_depth; + } break; case Cmd::PATT: --current_stack_depth; if (l == CMD_PATT_STR) { --current_stack_depth; } if (current_stack_depth < 0) { - ip_failure(saved_current_ip, mod_id, "not enough elements in stack"); + ip_failure(saved_current_ip, bf, "not enough elements in stack"); } ++current_stack_depth; break; @@ -352,32 +355,31 @@ void analyze(uint32_t mod_id) { // case Cmd::Llength: // case Cmd::Lstring: // if (current_stack_depth < 1) { - // ip_failure(saved_current_ip, mod_id, "not enough elements in stack"); + // ip_failure(saved_current_ip, bf, "not enough elements in stack"); // } // break; // case Cmd::Barray: // current_stack_depth -= ip_read_int_unsafe(¤t_ip); // elem count // if (current_stack_depth < 0) { - // ip_failure(saved_current_ip, mod_id, "not enough elements in stack"); + // ip_failure(saved_current_ip, bf, "not enough elements in stack"); // } // ++current_stack_depth; // break; case Cmd::EXIT: - ip_failure(saved_current_ip, mod_id, + ip_failure(saved_current_ip, bf, "exit should be unreachable"); // NOTE: not sure break; case Cmd::_UNDEF_: - ip_failure(saved_current_ip, mod_id, "undefined command"); + ip_failure(saved_current_ip, bf, "undefined command"); break; } if (current_begin_counter == nullptr) { - ip_failure(saved_current_ip, mod_id, - "function does not start with begin"); + ip_failure(saved_current_ip, bf, "function does not start with begin"); } if (current_stack_depth < 0) { - ip_failure(saved_current_ip, mod_id, "not enough elements in stack"); + ip_failure(saved_current_ip, bf, "not enough elements in stack"); } *current_begin_counter = @@ -404,7 +406,7 @@ void analyze(uint32_t mod_id) { uint jmp_p = ip_read_int_unsafe(¤t_ip); if ((int)jmp_p >= bf->code_size) { // NOTE: maybe also should check that > begin (?) - ip_failure(saved_current_ip, mod_id, "jump/call out of file"); + ip_failure(saved_current_ip, bf, "jump/call out of file"); } if (is_call) { func_to_visit_push(jmp_p); @@ -415,7 +417,7 @@ void analyze(uint32_t mod_id) { } case Cmd::_UNDEF_: - ip_failure(saved_current_ip, mod_id, "undefined command"); + ip_failure(saved_current_ip, bf, "undefined command"); break; default: diff --git a/byterun/src/cli.cpp b/byterun/src/cli.cpp index fefeb7a30..0ae8fa980 100644 --- a/byterun/src/cli.cpp +++ b/byterun/src/cli.cpp @@ -42,42 +42,32 @@ int main(int argc, char **argv) { } #ifdef DEBUG_VERSION - std::cerr << "- read code file" << std::endl; + std::cout << "- read code file" << std::endl; #endif Bytefile *f = read_file(argv[2]); if (do_print) { #ifdef DEBUG_VERSION - std::cerr << "- print code file" << std::endl; + std::cout << "- print code file" << std::endl; #endif print_file(*f, std::cout); - free(f); } if (do_verification || do_interpretation) { #ifdef DEBUG_VERSION - std::cerr << "- init stack" << std::endl; + std::cout << "- init stack" << std::endl; #endif size_t stack[STACK_SIZE]; run_init(stack); #ifdef DEBUG_VERSION - std::cerr << "- add main module" << std::endl; + std::cout << "- run with imports" << std::endl; #endif - uint main_mod_id = mod_add(f, do_verification); - - if (do_interpretation) { -#ifdef DEBUG_VERSION - std::cerr << "- start interpretation" << std::endl; -#endif - - run_mod_rec(main_mod_id, argc - 2, argv + 2, do_verification); - } + f = run_with_imports(f, argc - 2, argv + 2, do_verification); } - mod_cleanup(); - + free(f); return 0; } diff --git a/byterun/src/compiler.cpp b/byterun/src/compiler.cpp index 35ae073e9..0387da2f7 100644 --- a/byterun/src/compiler.cpp +++ b/byterun/src/compiler.cpp @@ -328,7 +328,7 @@ struct ArgumentLocation { }; /* We need to know the word size to calculate offsets correctly */ -constexpr auto word_size = 8; +constexpr size_t word_size = 8; const Register::T &as_register(const Opnd &opnd) { return std::visit( @@ -1278,7 +1278,7 @@ std::vector compile_binop(Env &env, Opr op) { switch (op) { case Opr::DIV: return with_rdx([&x, &y](const auto &rdx) -> std::vector { - return {Mov{y, rax}, Sar1{rax}, Binop{"^", rdx, rdx}, + return {Mov{y, rax}, Sar1{rax}, Binop{Opr::XOR, rdx, rdx}, Cltd{}, Sar1{x}, IDiv{x}, Sal1{rax}, Or1{rax}, Mov{rax, y}}; }); @@ -1301,7 +1301,7 @@ std::vector compile_binop(Env &env, Opr op) { return { Binop{Opr::XOR, rax, rax}, Mov{x, extra}, - Binop{"cmp", extra, y}, + Binop{Opr::CMP, extra, y}, Set{suffix(op), Registers::rax}, Sal1{rax}, Or1{rax}, diff --git a/byterun/src/interpreter.c b/byterun/src/interpreter.c index 406db87b0..bc897a0e1 100644 --- a/byterun/src/interpreter.c +++ b/byterun/src/interpreter.c @@ -58,7 +58,7 @@ void run_init(size_t *stack) { init_state(&s, (void**)stack); } -void run_prepare_exec(int argc, char **argv) { +void set_argc_argv(int argc, char **argv) { s_push_i(BOX(argc)); #ifdef DEBUG_VERSION printf("- argc: %i\n", argc); @@ -80,38 +80,7 @@ void run_prepare_exec(int argc, char **argv) { #endif } -void run_mod_rec(uint mod_id, int argc, char **argv, bool do_verification) { - Bytefile* mod = mod_get(mod_id); -#ifdef DEBUG_VERSION - printf("- run mod rec, %i imports\n", mod->imports_number); -#endif - for (size_t i = 0; i < mod->imports_number; ++i) { - const char* import_str = get_import_safe(mod, i); - if (find_mod_loaded(import_str) < 0 && strcmp(import_str, "Std") != 0) { // not loaded -#ifdef DEBUG_VERSION - printf("- mod load <%s>\n", import_str); -#endif - int32_t import_mod = mod_load(import_str, do_verification); - if (import_mod < 0) { - failure("module <%s> not found\n", import_str); - } -#ifdef DEBUG_VERSION - printf("- mod run <%s>\n", import_str); -#endif - run_mod_rec(import_mod, argc, argv, do_verification); - } - } - - init_mod_state(mod_id, &s); - init_mod_state_globals(&s); - - run_prepare_exec(argc, argv); // args for module main - run_mod(mod_id, argc, argv); - - cleanup_state(&s); -} - -static inline void call_Barray(size_t elem_count, char** ip, void** buffer) { +void call_Barray(size_t elem_count, char** ip, void** buffer) { // size_t elem_count = ip_read_int(ip); bool use_new_buffer = (elem_count > BUFFER_SIZE); @@ -149,17 +118,17 @@ static inline void call_Barray(size_t elem_count, char** ip, void** buffer) { } } -void run_mod(uint mod_id, int argc, char **argv) { +void run_main(Bytefile* bf, int argc, char **argv) { #ifdef DEBUG_VERSION - printf("--- module init state ---\n"); + printf("--- init state ---\n"); #endif - init_mod_state(mod_id, &s); + prepare_state(bf, &s); void *buffer[BUFFER_SIZE]; #ifdef DEBUG_VERSION - printf("--- module run begin ---\n"); + printf("--- run begin ---\n"); #endif do { @@ -178,9 +147,9 @@ void run_mod(uint mod_id, int argc, char **argv) { s.instr_ip = s.ip; uint8_t x = ip_read_byte(&s.ip), h = (x & 0xF0) >> 4, l = x & 0x0F; -#ifdef DEBUG_VERSION +// #ifdef DEBUG_VERSION printf("0x%.8x: %s\n", s.ip - s.bf->code_ptr - 1, read_cmd(s.ip - 1, s.bf)); -#endif +// #endif switch (h) { case CMD_EXIT: @@ -207,7 +176,7 @@ void run_mod(uint mod_id, int argc, char **argv) { #undef BINOP_OPR default: - s_failure(&s, "invalid opcode"); // %d-%d\n", h, l); + s_failure(&s, "interpreter: invalid opcode"); // %d-%d\n", h, l); break; } } @@ -343,7 +312,7 @@ void run_mod(uint mod_id, int argc, char **argv) { } break; default: - s_failure(&s, "invalid opcode"); // %d-%d\n", h, l); + s_failure(&s, "interpreter: basic, invalid opcode"); // %d-%d\n", h, l); } break; @@ -407,7 +376,7 @@ void run_mod(uint mod_id, int argc, char **argv) { s_failure(&s, "begin should only be called after call"); } #endif - s_enter_f(s.call_ip /*ip from call*/, s.call_module_id, + s_enter_f(s.call_ip /*ip from call*/, s.is_closure_call, args_sz, locals_sz); #ifndef WITH_CHECK if ((void **)__gc_stack_top + (aint)max_additional_stack_sz - 1 <= s.stack) { @@ -431,7 +400,7 @@ void run_mod(uint mod_id, int argc, char **argv) { s_failure(&s, "begin should only be called after call"); } #endif - s_enter_f(s.call_ip /*ip from call*/, s.call_module_id, + s_enter_f(s.call_ip /*ip from call*/, s.is_closure_call, args_sz, locals_sz); #ifdef WITH_CHECK if ((void **)__gc_stack_top + (aint)max_additional_stack_sz - 1 <= s.stack) { @@ -474,7 +443,6 @@ void run_mod(uint mod_id, int argc, char **argv) { call_happened = true; s.is_closure_call = true; s.call_ip = s.ip; - s.call_module_id = s.current_module_id; s.ip = (char*)Belem(*s_nth(args_count), BOX(0)); // use offset instead ?? break; @@ -487,7 +455,6 @@ void run_mod(uint mod_id, int argc, char **argv) { call_happened = true; s.is_closure_call = false; s.call_ip = s.ip; - s.call_module_id = s.current_module_id; #ifndef WITH_CHECK if (call_p >= s.bf->code_size) { @@ -527,42 +494,29 @@ void run_mod(uint mod_id, int argc, char **argv) { // maybe some metainfo should be collected break; - // case CMD_CTRL_CALLF: { // CALLF %s %d // call external function - // const char *call_func_name = ip_read_string(&s.ip); - // size_t args_count = ip_read_int(&s.ip); // args count + case CMD_CTRL_BUILTIN: { // BUILTIN %d %d // call builtin + size_t builtin_id = ip_read_int(&s.ip); + size_t args_count = ip_read_int(&s.ip); // args count - // if (run_stdlib_func(call_func_name, args_count)) { - // // case of stdlib function - // break; - // } + printf("builtin id: %zu\n", builtin_id); +// #ifndef WITH_CHECK + if (builtin_id >= BUILTIN_NONE) { + s_failure(&s, "invalid builtin"); + } +// #endif - // if (strcmp(call_func_name, ".array") == 0) { - // call_Barray(args_count, &s.ip, buffer); - // break; - // } - - // struct ModSearchResult func = mod_search_pub_symbol(call_func_name); - // if (func.mod_file == NULL) { - // failure("RUNTIME ERROR: external function <%s> with <%zu> args not found\n", call_func_name, args_count); - // } - - // call_happened = true; - // s.is_closure_call = false; - // s.call_ip = s.ip; - // s.call_module_id = s.current_module_id; - - // s.current_module_id = func.mod_id; - // s.bf = func.mod_file; - - // if (func.symbol_offset >= s.bf->code_size) { - // s_failure(&s, "jump out of file"); - // } - // s.ip = s.bf->code_ptr + func.symbol_offset; - // break; - // } + if (builtin_id == BUILTIN_Barray) { + call_Barray(args_count, &s.ip, buffer); + } else { + run_stdlib_func(builtin_id, args_count); + } + printf("builtin end\n"); + fflush(stdout); + break; + } default: - s_failure(&s, "invalid opcode"); // %d-%d\n", h, l); + s_failure(&s, "interpreter: ctrl, invalid opcode"); // %d-%d\n", h, l); } break; @@ -650,7 +604,6 @@ void run_mod(uint mod_id, int argc, char **argv) { if (!call_happened) { s.is_closure_call = false; s.call_ip = NULL; - s.call_module_id = 0; } if (s.fp == NULL) { diff --git a/byterun/src/module_manager.cpp b/byterun/src/module_manager.cpp index 188392728..419800f07 100644 --- a/byterun/src/module_manager.cpp +++ b/byterun/src/module_manager.cpp @@ -1,4 +1,6 @@ +#include extern "C" { +#include "interpreter.h" #include "module_manager.h" #include "runtime_externs.h" #include "stack.h" @@ -9,6 +11,7 @@ extern "C" { #include "parser.hpp" #include +#include #include #include #include @@ -42,146 +45,336 @@ void call_anyarg_func(void (*f)(), size_t n) { } } -struct ModSymbolPos { - uint32_t mod_id; - size_t offset; +// --- + +struct Offsets { + size_t strings; + size_t globals; + size_t code; + size_t publics_num; }; -struct Module { - std::string name; - Bytefile *bf; -}; +void rewrite_code_with_offsets(Bytefile *bytefile, const Offsets &offsets) { + // TODO: globals offsets -struct ModuleManager { - std::unordered_map loaded_modules; - std::unordered_map public_symbols_mods; - std::vector modules; - std::vector search_paths; -}; + char *ip = bytefile->code_ptr; + while (ip - bytefile->code_ptr < bytefile->code_size) { + char *instr_ip = ip; + const auto [cmd, l] = parse_command(&ip, bytefile); -static ModuleManager manager; - -uint32_t mod_add_impl(Bytefile *bf, bool do_verification, - std::optional name = std::nullopt) { -#ifdef DEBUG_VERSION - std::cerr << "- add module (impl) '" << std::string{name ? *name : ""} - << "'\n"; -#endif - uint32_t id = manager.modules.size(); - manager.modules.push_back({.name = name ? *name : "", .bf = bf}); - for (size_t i = 0; i < bf->public_symbols_number; ++i) { - const char *public_name = get_public_name_safe(bf, i); -#ifdef DEBUG_VERSION - std::cerr << "- load public " << public_name << "\n"; -#endif - size_t public_offset = get_public_offset_safe(bf, i); - if (strcmp(public_name, "main") == 0) { - bf->main_offset = public_offset; - } else if (!manager.public_symbols_mods - .insert( - {public_name, {.mod_id = id, .offset = public_offset}}) - .second) { - failure("public symbol '%s' loaded more then once\n", - get_public_name_safe(bf, i)); + char *read_ip = instr_ip + 1; + char *write_ip = instr_ip + 1; + switch (cmd) { + case Cmd::STRING: + ip_write_int_unsafe(write_ip, + ip_read_int_unsafe(&read_ip) + offsets.strings); + break; + case Cmd::JMP: + case Cmd::CJMPnz: + case Cmd::CJMPz: + case Cmd::CALL: + ip_write_int_unsafe(write_ip, + ip_read_int_unsafe(&read_ip) + offsets.code); + break; + case Cmd::CLOSURE: { + ip_write_int_unsafe(write_ip, + ip_read_int_unsafe(&read_ip) + offsets.code); + size_t args_count = ip_read_int_unsafe(&read_ip); + for (size_t i = 0; i < args_count; ++i) { + uint8_t arg_type = ip_read_byte_unsafe(&read_ip); + if (to_var_category(arg_type) == VAR_GLOBAL) { + write_ip = read_ip; + ip_write_int_unsafe(write_ip, + ip_read_int_unsafe(&read_ip) + offsets.globals); + } + } + break; + } + case Cmd::LD: + case Cmd::ST: + case Cmd::STA: + if (to_var_category(l) == VAR_GLOBAL) { + ip_write_int_unsafe(write_ip, + ip_read_int_unsafe(&read_ip) + offsets.globals); + } + break; + default: + break; } } - if (name) { - manager.loaded_modules.insert({*name, id}); - } - if (do_verification) { - analyze(id); - } - return id; } -uint32_t path_mod_load(const char *name, std::filesystem::path &&path, - bool do_verification) { +void subst_in_code(Bytefile *bytefile, + const std::unordered_map &publics) { + for (size_t i = 0; i < bytefile->substs_area_size; ++i) { + if (i + sizeof(uint32_t) >= bytefile->substs_area_size) { + failure("substitution %zu offset is out of area\n", i); + } + + uint32_t offset = *(uint32_t *)(bytefile->substs_ptr + i); + i += sizeof(uint32_t); + const char *name = bytefile->substs_ptr + i; + i += strlen(name); + #ifdef DEBUG_VERSION - std::cerr << "- module path load '" << name << "'\n"; + printf("subst: offset %u, name %s\n", offset, name); #endif - Bytefile *module = read_file(path.c_str()); - return mod_add_impl(module, do_verification, name); + + if (i > bytefile->substs_area_size) { + failure("substitution %zu name is out of area\n", i); + } + + BUILTIN builtin = id_by_builtin(name); + + // NOTE: address is first argument of the call + if (builtin != BUILTIN_NONE) { + uint8_t cmd = ((CMD_CTRL << 4) | CMD_CTRL_BUILTIN); +#ifdef DEBUG_VERSION + printf("set builtin %i, offset %i, cmd %u = (%u << 4) | %u, h = %u, l = " + "%u\n", + builtin, offset, cmd, CMD_CTRL, CMD_CTRL_BUILTIN, + (cmd & 0xF0) >> 4, cmd & 0x0F); +#endif + *(uint8_t *)(bytefile->code_ptr + offset - 1) = + cmd; // set BUILTIN command + *(uint32_t *)(bytefile->code_ptr + offset) = builtin; + continue; + } + + const auto it = publics.find(name); + if (it == publics.end()) { + failure("public name for substitution is not found: <%s>\n", name); + } + + *(uint32_t *)(bytefile->code_ptr + offset) = it->second; + // TODO: check: +4 to match ? + } } +Offsets calc_merge_sizes(const std::vector &bytefiles) { + Offsets sizes{.strings = 0, .globals = 0, .code = 0, .publics_num = 0}; + for (size_t i = 0; i < bytefiles.size(); ++i) { + sizes.strings += bytefiles[i]->stringtab_size; + sizes.globals += bytefiles[i]->global_area_size; + sizes.code += bytefiles[i]->code_size; + sizes.publics_num += bytefiles[i]->public_symbols_number; + } + return sizes; +} + +struct MergeResult { + Bytefile *bf; + std::vector main_offsets; +}; + +MergeResult merge_files(std::vector &&bytefiles) { + Offsets sizes = calc_merge_sizes(bytefiles); + size_t public_symbols_size = calc_publics_size(sizes.publics_num); + Bytefile *result = + (Bytefile *)malloc(sizeof(Bytefile) + sizes.strings + sizes.code + + public_symbols_size); // globals are on the stack + + // collect publics + // TODO: add publics + updat name offsets too ?()) + std::unordered_map publics; + std::vector main_offsets; + { + size_t code_offset = 0; + for (size_t i = 0; i < bytefiles.size(); ++i) { +#ifdef DEBUG_VERSION + printf("bytefile <%zu>\n", i); +#endif + for (size_t j = 0; j < bytefiles[i]->public_symbols_number; ++j) { +#ifdef DEBUG_VERSION + printf("symbol <%zu>:<%zu>\n", i, j); +#endif + const char *name = get_public_name_unsafe(bytefiles[i], j); + size_t offset = get_public_offset_unsafe(bytefiles[i], j) + code_offset; + +#ifdef DEBUG_VERSION + printf("symbol %s : %zu (code offset %zu)\n", name, offset, + code_offset); +#endif + if (strcmp(name, "main") == 0) { + main_offsets.push_back(offset); + } else if (!publics.insert({name, offset}).second) { + failure("public name found more then once: %s", name); + } + } + code_offset += bytefiles[i]->code_size; + } + } + + // init result + result->code_size = sizes.code; + result->stringtab_size = sizes.strings; + result->global_area_size = sizes.globals; + result->substs_area_size = 0; + result->imports_number = 0; + result->public_symbols_number = sizes.publics_num; + + result->main_offset = 0; // TODO: save al main offsets in some way (?) + result->public_ptr = (int *)result->buffer; + result->string_ptr = (char *)result->public_ptr + public_symbols_size; + result->code_ptr = result->string_ptr + result->stringtab_size; + result->imports_ptr = NULL; + result->global_ptr = NULL; + result->substs_ptr = NULL; + + // update & merge code segments + Offsets offsets{.strings = 0, .globals = 0, .code = 0, .publics_num = 0}; + // REMOVE printf("merge bytefiles\n"); + for (size_t i = 0; i < bytefiles.size(); ++i) { + // REMOVE printf("rewrite offsets %zu\n", i); + rewrite_code_with_offsets(bytefiles[i], offsets); + // REMOVE printf("subst in code %zu\n", i); + subst_in_code(bytefiles[i], publics); + + size_t publics_offset = calc_publics_size(offsets.publics_num); + + // copy data to merged file + memcpy(result->string_ptr + offsets.strings, bytefiles[i]->string_ptr, + bytefiles[i]->stringtab_size); + memcpy(result->code_ptr + offsets.code, bytefiles[i]->code_ptr, + bytefiles[i]->code_size); + memcpy((char *)result->public_ptr + publics_offset, + (char *)bytefiles[i]->public_ptr, + calc_publics_size( + bytefiles[i]->public_symbols_number)); // TODO: recalc publics: + // offsets, strings + + // update offsets + offsets.strings += bytefiles[i]->stringtab_size; + offsets.globals += bytefiles[i]->global_area_size; + offsets.code += bytefiles[i]->code_size; + offsets.publics_num += bytefiles[i]->public_symbols_number; + free(bytefiles[i]); + } + +#ifdef DEBUG_VERSION + std::cout << "- merged file:\n"; + print_file(*result, std::cout); +#endif + return {result, main_offsets}; +} + +// --- + +Bytefile *path_mod_load(const char *name, std::filesystem::path &&path) { +#ifdef DEBUG_VERSION + std::cout << "- module path load '" << name << "'\n"; +#endif + return read_file(path.c_str()); +} + +static std::vector search_paths; + extern "C" { -void mod_cleanup() { - for (auto &mod : manager.modules) { - free(mod.bf); - } -} +void mod_add_search_path(const char *path) { search_paths.emplace_back(path); } -void mod_add_search_path(const char *path) { - manager.search_paths.emplace_back(path); -} - -const char *mod_get_name(uint32_t id) { - if (id > manager.modules.size()) { - failure("module id is out of range\n"); - } - return manager.modules[id].name.c_str(); -} - -Bytefile *mod_get(uint32_t id) { - if (id > manager.modules.size()) { - failure("module id is out of range\n"); - } - return manager.modules[id].bf; -} - -int32_t find_mod_loaded(const char *name) { - auto it = manager.loaded_modules.find(name); - - // module already loaded - if (it != manager.loaded_modules.end()) { - return it->second; - } - - return -1; -} - -int32_t mod_load(const char *name, bool do_verification) { +Bytefile *mod_load(const char *name) { std::string full_name = std::string{name} + ".bc"; - auto it = manager.loaded_modules.find(name); - - // module already loaded - if (it != manager.loaded_modules.end()) { - return it->second; - } - if (std::filesystem::exists(full_name)) { - return path_mod_load(name, full_name, do_verification); + return path_mod_load(name, full_name); } - for (const auto &dir_path : manager.search_paths) { + for (const auto &dir_path : search_paths) { auto path = dir_path / full_name; if (std::filesystem::exists(path)) { - return path_mod_load(name, std::move(path), do_verification); + return path_mod_load(name, std::move(path)); } } - return -1; + return NULL; } -uint32_t mod_add(Bytefile *module, bool do_verification) { +} // extern "C" + +// uint32_t mod_add(Bytefile *module, bool do_verification) { +// #ifdef DEBUG_VERSION +// std::cout << "- add module, no name\n"; +// #endif +// return mod_add_impl(module, do_verification); +// } + +// ModSearchResult mod_search_pub_symbol(const char *name) { +// auto it = manager.public_symbols_mods.find(name); +// if (it == manager.public_symbols_mods.end()) { +// return {.symbol_offset = 0, .mod_id = 0, .mod_file = NULL}; +// } + +// return { +// .symbol_offset = it->second.offset, +// .mod_id = it->second.mod_id, +// .mod_file = mod_get(it->second.mod_id), +// }; +// } + +void mod_load_rec(Bytefile *mod, + std::unordered_map &loaded, + std::vector &loaded_ord) { #ifdef DEBUG_VERSION - std::cerr << "- add module, no name\n"; + printf("- run mod rec, %i imports\n", mod->imports_number); #endif - return mod_add_impl(module, do_verification); + for (size_t i = 0; i < mod->imports_number; ++i) { + const char *import_str = get_import_safe(mod, i); + if (loaded.count(import_str) == 0 && + strcmp(import_str, "Std") != 0) { // not loaded +#ifdef DEBUG_VERSION + printf("- mod load <%s>\n", import_str); +#endif + Bytefile *import_mod = mod_load(import_str); // TODO + if (import_mod == NULL) { + failure("module <%s> not found\n", import_str); + } + loaded.insert({import_str, import_mod}); + mod_load_rec(import_mod, loaded, loaded_ord); + // loaded_ord.push_back(import_mod); + } + } + loaded_ord.push_back(mod); } -ModSearchResult mod_search_pub_symbol(const char *name) { - auto it = manager.public_symbols_mods.find(name); - if (it == manager.public_symbols_mods.end()) { - return {.symbol_offset = 0, .mod_id = 0, .mod_file = NULL}; +MergeResult load_with_imports(Bytefile *root, bool do_verification) { + std::unordered_map loaded; + std::vector loaded_ord; + mod_load_rec(root, loaded, loaded_ord); + + MergeResult result = merge_files(std::move(loaded_ord)); + + if (do_verification) { + // #ifdef DEBUG_VERSION + printf("main offsets count: %zu\n", result.main_offsets.size()); + // #endif + analyze(result.bf /*, std::move(result.main_offsets)*/); + } + return result; +} + +extern "C" { +Bytefile *run_with_imports(Bytefile *root, int argc, char **argv, + bool do_verification) { + + MergeResult result = load_with_imports(root, do_verification); + + Bytefile *bf = result.bf; + + bf->main_offset = 0; + prepare_state(bf, &s); // NOTE: for push_globals + push_globals(&s); + + for (size_t i = 0; i < result.main_offsets.size(); ++i) { + bf->main_offset = result.main_offsets[i]; + set_argc_argv(argc, argv); // args for module main + run_main(bf, argc, argv); } - return { - .symbol_offset = it->second.offset, - .mod_id = it->second.mod_id, - .mod_file = mod_get(it->second.mod_id), - }; + cleanup_state(&s); + + return bf; } +} // extern "C" struct StdFunc { void (*ptr)(); @@ -189,75 +382,128 @@ struct StdFunc { bool is_args = false; // one var for all args bool is_vararg = false; }; -bool run_stdlib_func(const char *name, size_t args_count) { - static const std::unordered_map std_func = { - {"Luppercase", {.ptr = (void (*)()) & Luppercase, .args_count = 1}}, - {"Llowercase", {.ptr = (void (*)()) & Llowercase, .args_count = 1}}, - {"Lassert", + +BUILTIN id_by_builtin(const char *name) { + static const std::unordered_map std_func = { + {"Luppercase", BUILTIN_Luppercase}, + {"Llowercase", BUILTIN_Llowercase}, + {"Lassert", BUILTIN_Lassert}, + {"Lstring", BUILTIN_Lstring}, + {"Llength", BUILTIN_Llength}, + {"LstringInt", BUILTIN_LstringInt}, + {"Lread", BUILTIN_Lread}, + {"Lwrite", BUILTIN_Lwrite}, + {"LmakeArray", BUILTIN_LmakeArray}, + {"LmakeString", BUILTIN_LmakeString}, + {"Lstringcat", BUILTIN_Lstringcat}, + {"LmatchSubString", BUILTIN_LmatchSubString}, + {"Lsprintf", BUILTIN_Lsprintf}, + {"Lsubstring", BUILTIN_Lsubstring}, + {"Li__Infix_4343", BUILTIN_Li__Infix_4343}, // ++ + {"Lclone", BUILTIN_Lclone}, + {"Lhash", BUILTIN_Lhash}, + {"LtagHash", BUILTIN_LtagHash}, + {"Lcompare", BUILTIN_Lcompare}, + {"LflatCompare", BUILTIN_LflatCompare}, + {"Lfst", BUILTIN_Lfst}, + {"Lsnd", BUILTIN_Lsnd}, + {"Lhd", BUILTIN_Lhd}, + {"Ltl", BUILTIN_Ltl}, + {"LreadLine", BUILTIN_LreadLine}, + {"Lprintf", BUILTIN_Lprintf}, + {"Lfopen", BUILTIN_Lfopen}, + {"Lfclose", BUILTIN_Lfclose}, + {"Lfread", BUILTIN_Lfread}, + {"Lfwrite", BUILTIN_Lfwrite}, + {"Lfexists", BUILTIN_Lfexists}, + {"Lfprintf", BUILTIN_Lfprintf}, + {"Lregexp", BUILTIN_Lregexp}, + {"LregexpMatch", BUILTIN_LregexpMatch}, + {"Lfailure", BUILTIN_Lfailure}, + {"Lsystem", BUILTIN_Lsystem}, + {"LgetEnv", BUILTIN_LgetEnv}, + {"Lrandom", BUILTIN_Lrandom}, + {"Ltime", BUILTIN_Ltime}, + {".array", BUILTIN_Barray}, + }; + + auto const it = std_func.find(name); + + return it == std_func.end() ? BUILTIN_NONE : it->second; +} + +void run_stdlib_func(BUILTIN id, size_t args_count) { + static const std::map std_func = { + {BUILTIN_Luppercase, {.ptr = (void (*)()) & Luppercase, .args_count = 1}}, + {BUILTIN_Llowercase, {.ptr = (void (*)()) & Llowercase, .args_count = 1}}, + {BUILTIN_Lassert, {.ptr = (void (*)()) & Lassert, .args_count = 2, .is_vararg = true}}, - {"Lstring", + {BUILTIN_Lstring, {.ptr = (void (*)()) & Lstring, .args_count = 1, .is_args = true}}, - {"Llength", {.ptr = (void (*)()) & Llength, .args_count = 1}}, - {"LstringInt", {.ptr = (void (*)()) & LstringInt, .args_count = 1}}, - {"Lread", {.ptr = (void (*)()) & Lread, .args_count = 0}}, - {"Lwrite", {.ptr = (void (*)()) & Lwrite, .args_count = 1}}, - {"LmakeArray", {.ptr = (void (*)()) & LmakeArray, .args_count = 1}}, - {"LmakeString", {.ptr = (void (*)()) & LmakeString, .args_count = 1}}, - {"Lstringcat", + {BUILTIN_Llength, {.ptr = (void (*)()) & Llength, .args_count = 1}}, + {BUILTIN_LstringInt, {.ptr = (void (*)()) & LstringInt, .args_count = 1}}, + {BUILTIN_Lread, {.ptr = (void (*)()) & Lread, .args_count = 0}}, + {BUILTIN_Lwrite, {.ptr = (void (*)()) & Lwrite, .args_count = 1}}, + {BUILTIN_LmakeArray, {.ptr = (void (*)()) & LmakeArray, .args_count = 1}}, + {BUILTIN_LmakeString, + {.ptr = (void (*)()) & LmakeString, .args_count = 1}}, + {BUILTIN_Lstringcat, {.ptr = (void (*)()) & Lstringcat, .args_count = 1, .is_args = true}}, - {"LmatchSubString", + {BUILTIN_LmatchSubString, {.ptr = (void (*)()) & LmatchSubString, .args_count = 3}}, - {"Lsprintf", + {BUILTIN_Lsprintf, {.ptr = (void (*)()) & Lsprintf, .args_count = 1, .is_vararg = true}}, - {"Lsubstring", + {BUILTIN_Lsubstring, {.ptr = (void (*)()) & Lsubstring, .args_count = 3, .is_args = true}}, - {"Li__Infix_4343", + {BUILTIN_Li__Infix_4343, {.ptr = (void (*)()) & Li__Infix_4343, .args_count = 2, .is_args = true}}, // ++ - {"Lclone", + {BUILTIN_Lclone, {.ptr = (void (*)()) & Lclone, .args_count = 1, .is_args = true}}, - {"Lhash", {.ptr = (void (*)()) & Lhash, .args_count = 1}}, - {"LtagHash", {.ptr = (void (*)()) & LtagHash, .args_count = 1}}, - {"Lcompare", {.ptr = (void (*)()) & Lcompare, .args_count = 2}}, - {"LflatCompare", {.ptr = (void (*)()) & LflatCompare, .args_count = 2}}, - {"Lfst", {.ptr = (void (*)()) & Lfst, .args_count = 1}}, - {"Lsnd", {.ptr = (void (*)()) & Lsnd, .args_count = 1}}, - {"Lhd", {.ptr = (void (*)()) & Lhd, .args_count = 1}}, - {"Ltl", {.ptr = (void (*)()) & Ltl, .args_count = 1}}, - {"LreadLine", {.ptr = (void (*)()) & LreadLine, .args_count = 0}}, - {"Lprintf", + {BUILTIN_Lhash, {.ptr = (void (*)()) & Lhash, .args_count = 1}}, + {BUILTIN_LtagHash, {.ptr = (void (*)()) & LtagHash, .args_count = 1}}, + {BUILTIN_Lcompare, {.ptr = (void (*)()) & Lcompare, .args_count = 2}}, + {BUILTIN_LflatCompare, + {.ptr = (void (*)()) & LflatCompare, .args_count = 2}}, + {BUILTIN_Lfst, {.ptr = (void (*)()) & Lfst, .args_count = 1}}, + {BUILTIN_Lsnd, {.ptr = (void (*)()) & Lsnd, .args_count = 1}}, + {BUILTIN_Lhd, {.ptr = (void (*)()) & Lhd, .args_count = 1}}, + {BUILTIN_Ltl, {.ptr = (void (*)()) & Ltl, .args_count = 1}}, + {BUILTIN_LreadLine, {.ptr = (void (*)()) & LreadLine, .args_count = 0}}, + {BUILTIN_Lprintf, {.ptr = (void (*)()) & Lprintf, .args_count = 1, .is_vararg = true}}, - {"Lfopen", {.ptr = (void (*)()) & Lfopen, .args_count = 2}}, - {"Lfclose", {.ptr = (void (*)()) & Lfclose, .args_count = 1}}, - {"Lfread", {.ptr = (void (*)()) & Lfread, .args_count = 1}}, - {"Lfwrite", {.ptr = (void (*)()) & Lfwrite, .args_count = 2}}, - {"Lfexists", {.ptr = (void (*)()) & Lfexists, .args_count = 1}}, - {"Lfprintf", + {BUILTIN_Lfopen, {.ptr = (void (*)()) & Lfopen, .args_count = 2}}, + {BUILTIN_Lfclose, {.ptr = (void (*)()) & Lfclose, .args_count = 1}}, + {BUILTIN_Lfread, {.ptr = (void (*)()) & Lfread, .args_count = 1}}, + {BUILTIN_Lfwrite, {.ptr = (void (*)()) & Lfwrite, .args_count = 2}}, + {BUILTIN_Lfexists, {.ptr = (void (*)()) & Lfexists, .args_count = 1}}, + {BUILTIN_Lfprintf, {.ptr = (void (*)()) & Lfprintf, .args_count = 2, .is_vararg = true}}, - {"Lregexp", {.ptr = (void (*)()) & Lregexp, .args_count = 1}}, - {"LregexpMatch", {.ptr = (void (*)()) & LregexpMatch, .args_count = 3}}, - {"Lfailure", + {BUILTIN_Lregexp, {.ptr = (void (*)()) & Lregexp, .args_count = 1}}, + {BUILTIN_LregexpMatch, + {.ptr = (void (*)()) & LregexpMatch, .args_count = 3}}, + {BUILTIN_Lfailure, {.ptr = (void (*)()) & Lfailure, .args_count = 1, .is_vararg = true}}, - {"Lsystem", {.ptr = (void (*)()) & Lsystem, .args_count = 1}}, - {"LgetEnv", {.ptr = (void (*)()) & LgetEnv, .args_count = 1}}, - {"Lrandom", {.ptr = (void (*)()) & Lrandom, .args_count = 1}}, - {"Ltime", {.ptr = (void (*)()) & Ltime, .args_count = 0}}, + {BUILTIN_Lsystem, {.ptr = (void (*)()) & Lsystem, .args_count = 1}}, + {BUILTIN_LgetEnv, {.ptr = (void (*)()) & LgetEnv, .args_count = 1}}, + {BUILTIN_Lrandom, {.ptr = (void (*)()) & Lrandom, .args_count = 1}}, + {BUILTIN_Ltime, {.ptr = (void (*)()) & Ltime, .args_count = 0}}, }; // some functions do use on args pointer - const auto it = std_func.find(name); + const auto it = std_func.find(id); if (it == std_func.end()) { - return false; + failure("RUNTIME ERROR: stdlib function <%u> not found\n", id); } // TODO: move to bytecode verifier if ((!it->second.is_vararg && it->second.args_count != args_count) || it->second.args_count > args_count) { - failure("RUNTIME ERROR: stdlib function <%s> argument count <%zu> is not " + failure("RUNTIME ERROR: stdlib function <%u> argument count <%zu> is not " "expected (expected is <%s%zu>)\n", - name, it->second.args_count, it->second.is_vararg ? ">=" : "=", + id, it->second.args_count, it->second.is_vararg ? ">=" : "=", args_count); } @@ -268,7 +514,4 @@ bool run_stdlib_func(const char *name, size_t args_count) { } else { call_anyarg_func<20>(it->second.ptr, args_count); } - return true; } - -} // extern "C" diff --git a/byterun/src/parser.cpp b/byterun/src/parser.cpp index fcbc05128..50ec7f3c2 100644 --- a/byterun/src/parser.cpp +++ b/byterun/src/parser.cpp @@ -72,6 +72,8 @@ Bytefile *read_file(const char *fname) { char *file_begin = (char *)file + additional_size; char *file_end = file_begin + size; + size_t buffer_size = size + additional_size - sizeof(Bytefile); + if (file == 0) { failure("unable to allocate memory to store file data\n"); } @@ -85,7 +87,7 @@ Bytefile *read_file(const char *fname) { fclose(f); size_t imports_size = file->imports_number * sizeof(int); - size_t public_symbols_size = file->public_symbols_number * 2 * sizeof(int); + size_t public_symbols_size = calc_publics_size(file->public_symbols_number); size_t strings_buffer_offset = public_symbols_size + imports_size; if (file->buffer + strings_buffer_offset >= file_end) { @@ -98,7 +100,7 @@ Bytefile *read_file(const char *fname) { size_t substs_buffer_offset = strings_buffer_offset + file->stringtab_size; file->substs_ptr = file->buffer + substs_buffer_offset; - if ((char *)file->substs_ptr + file->substs_area_size > file_end) { + if (file->substs_ptr + file->substs_area_size > file_end) { failure("substitutions table is out of the file size\n"); } @@ -106,7 +108,9 @@ Bytefile *read_file(const char *fname) { // file->string_ptr[file->stringtab_size - 1] != 0) { // failure("strings table is not zero-ended\n"); // } - file->code_size = size - substs_buffer_offset - file->substs_area_size; + file->code_ptr = file->substs_ptr + file->substs_area_size; + // file->code_size = size - substs_buffer_offset - file->substs_area_size; + file->code_size = buffer_size - (file->code_ptr - file->buffer); if (file->code_size < 0 || public_symbols_size < 0 || file->stringtab_size < 0) { @@ -116,144 +120,11 @@ Bytefile *read_file(const char *fname) { file->imports_ptr = (int *)file->buffer; file->public_ptr = (int *)(file->buffer + imports_size); file->global_ptr = NULL; // is allocated on module run on stack - file->code_ptr = file->string_ptr + file->stringtab_size; // file->global_ptr = (int*) calloc (file->global_area_size, sizeof (int)); return file; } -struct Offsets { - size_t strings; - size_t globals; - size_t code; -}; - -void rewrite_code_with_offsets(Bytefile *bytefile, const Offsets &offsets) { - char *ip = bytefile->code_ptr; - while (ip - bytefile->code_ptr < bytefile->code_size) { - const auto [cmd, l] = parse_command(&ip, bytefile); - - char *cmd_ip = ip; - - switch (cmd) { - case Cmd::STRING: - ip_write_int_unsafe(cmd_ip, ip_read_int_unsafe(&ip) + - offsets.strings); // TODO: check - break; - case Cmd::JMP: - case Cmd::CJMPnz: - case Cmd::CJMPz: - case Cmd::CLOSURE: - case Cmd::CALL: - ip_write_int_unsafe(cmd_ip, ip_read_int_unsafe(&ip) + - offsets.code); // TODO: check - break; - default: - break; - } - } -} - -void subst_in_code(Bytefile *bytefile, - const std::unordered_map &publics) { - for (size_t i = 0; i < bytefile->substs_area_size;) { - if (i + sizeof(uint32_t) >= bytefile->substs_area_size) { - failure("substitution %zu offset is out of area", i); - } - - uint32_t offset = *(uint32_t *)(bytefile->substs_ptr + i); - i += sizeof(uint32_t); - const char *name = bytefile->substs_ptr + i; - - i += strlen(name); - - if (i > bytefile->substs_area_size) { - failure("substitution %zu name is out of area", i); - } - - const auto it = publics.find(name); - if (it == publics.end()) { - failure("public name for substitution is not found: %s", name); - } - - *(uint32_t *)(bytefile->code_ptr + offset) = it->second; - // TODO: check: +4 to match ? - } -} - -Offsets calc_merge_sizes(const std::vector &bytefiles) { - Offsets sizes{.strings = 0, .globals = 0, .code = 0}; - for (size_t i = 0; i < bytefiles.size(); ++i) { - sizes.strings += bytefiles[i]->stringtab_size; - sizes.strings += bytefiles[i]->global_area_size; - sizes.strings += bytefiles[i]->code_size; - } - return sizes; -} - -Bytefile *merge_files(std::vector &&bytefiles) { - Offsets sizes = calc_merge_sizes(bytefiles); - Bytefile *result = (Bytefile *)malloc(sizeof(Bytefile) + sizes.strings + - sizes.code); // globals - on stack - - // collect publics - std::unordered_map publics; - std::vector main_offsets; - { - size_t code_offset = 0; - for (size_t i = 0; i < bytefiles.size(); ++i) { - for (size_t j = 0; j < bytefiles[i]->public_symbols_number; ++j) { - const char *name = get_public_name_unsafe(bytefiles[i], j); - size_t offset = - get_public_name_offset_unsafe(bytefiles[i], j) + code_offset; - - if (strcmp(name, "main") == 0) { - main_offsets.push_back(offset); - } else if (!publics.insert({name, offset}).second) { - failure("public name found more then once: %s", name); - } - } - code_offset += bytefiles[i]->code_size; - } - } - - // init result - result->code_size = sizes.code; - result->stringtab_size = sizes.strings; - result->global_area_size = sizes.globals; - result->substs_area_size = 0; - result->imports_number = 0; - result->public_symbols_number = 0; - - result->main_offset = 0; // TODO: save al main offsets in some way (?) - result->string_ptr = result->buffer; - result->imports_ptr = NULL; - result->public_ptr = NULL; - result->code_ptr = result->string_ptr + result->stringtab_size; - result->global_ptr = NULL; - result->substs_ptr = NULL; - - // update & merge code segments - Offsets offsets{.strings = 0, .globals = 0, .code = 0}; - for (size_t i = 0; i < bytefiles.size(); ++i) { - rewrite_code_with_offsets(bytefiles[i], offsets); - subst_in_code(bytefiles[i], publics); - - // copy data to merged file - memcpy(result->string_ptr + offsets.strings, bytefiles[i]->string_ptr, - bytefiles[i]->stringtab_size); - memcpy(result->code_ptr + offsets.code, bytefiles[i]->code_ptr, - bytefiles[i]->code_size); - - // update offsets - offsets.strings += bytefiles[i]->stringtab_size; - offsets.globals += bytefiles[i]->global_area_size; - offsets.code += bytefiles[i]->code_size; - free(bytefiles[i]); - } - return result; -} - const char *command_name(Cmd cmd, int8_t l) { static const char *const ops[] = { #define OP_TO_STR(id, op) "BINOP:" #op, @@ -349,6 +220,8 @@ const char *command_name(Cmd cmd, int8_t l) { return "CALLC"; case Cmd::CALL: return "CALL"; + case Cmd::BUILTIN: + return "BUILTIN"; case Cmd::TAG: return "TAG"; case Cmd::ARRAY: @@ -379,7 +252,7 @@ const char *command_name(Cmd cmd, int8_t l) { return "_UNDEF_"; } - exit(1); + failure("command_name: unexpected command %u", static_cast(cmd)); } // } // extern "C" @@ -569,14 +442,14 @@ std::pair parse_command_impl(char **ip, const Bytefile &bf, break; default: - failure("invalid opcode"); + failure("parser: basic, invalid opcode\n"); } break; case CMD_LD: // LD %d cmd = Cmd::LD; if (l > sizeof(ldts) / sizeof(char *)) { - failure("wrong ld argument type"); + failure("wrong ld argument type\n"); } read_print_cmd_seq_opt(cmd, l, ip, bf, out); @@ -584,7 +457,7 @@ std::pair parse_command_impl(char **ip, const Bytefile &bf, case CMD_LDA: // LDA %d cmd = Cmd::LDA; if (l > sizeof(ldts) / sizeof(char *)) { - failure("wrong lda argument type"); + failure("wrong lda argument type\n"); } read_print_cmd_seq_opt(cmd, l, ip, bf, out); @@ -592,7 +465,7 @@ std::pair parse_command_impl(char **ip, const Bytefile &bf, case CMD_ST: // ST %d cmd = Cmd::ST; if (l > sizeof(ldts) / sizeof(char *)) { - failure("wrong st argument type"); + failure("wrong st argument type\n"); } read_print_cmd_seq_opt(cmd, l, ip, bf, out); @@ -633,7 +506,7 @@ std::pair parse_command_impl(char **ip, const Bytefile &bf, for (size_t i = 0; i < args_count; i++) { uint8_t arg_type = ip_read_byte_safe(ip, &bf); if (arg_type > sizeof(ldts) / sizeof(char *)) { - failure("wrong closure argument type"); + failure("wrong closure argument type\n"); } print_space(out); print_val(out, ldts[arg_type]); @@ -677,22 +550,21 @@ std::pair parse_command_impl(char **ip, const Bytefile &bf, read_print_cmd_seq_opt(cmd, l, ip, bf, out); break; - // NOTE: is replaced - // case CMD_CTRL_CALLF: // CALLF %s %d - // cmd = Cmd::CALLF; - // read_print_cmd_seq_opt( - // cmd, l, ip, bf, out); - // break; + case CMD_CTRL_BUILTIN: // BUILTIN %d %d // call builtin + cmd = Cmd::BUILTIN; + read_print_cmd_seq_opt( + cmd, l, ip, bf, out); + break; default: - failure("invalid opcode"); + failure("parser: ctrl, invalid opcode\n"); } break; case CMD_PATT: // PATT pats[l] // {"=str", "#string", "#array", "#sexp", "#ref", "#val", "#fun"} if (l >= sizeof(pats) / sizeof(char *)) { - failure("invalid opcode"); + failure("parser: patt, invalid opcode\n"); } cmd = Cmd::PATT; read_print_cmd_seq_opt(cmd, l, ip, bf, out); @@ -726,12 +598,12 @@ std::pair parse_command_impl(char **ip, const Bytefile &bf, // break; // default: - // failure("invalid opcode"); + // failure("parser: bultin, invalid opcode\n"); // } // } break; default: - failure("invalid opcode"); + failure("parser: invalid opcode\n"); } #ifdef DEBUG_VERSION std::cout << command_name(cmd, l) << '\n'; @@ -757,6 +629,7 @@ bool is_command_name(char *ip, const Bytefile *bf, Cmd cmd) { } void print_file_info(const Bytefile &bf, std::ostream &out) { + out << "Code size : " << bf.code_size << '\n'; out << "String table size : " << bf.stringtab_size << '\n'; out << "Global area size : " << bf.global_area_size << '\n'; out << "Substitutions area size : " << bf.substs_area_size << '\n'; @@ -774,6 +647,16 @@ void print_file_info(const Bytefile &bf, std::ostream &out) { << get_public_offset_safe(&bf, i) << ": " << std::dec << get_public_name_safe(&bf, i) << '\n'; } + + out << "Substs :\n"; + for (size_t i = 0; i < bf.substs_area_size; i++) { + uint32_t offset = *(uint32_t *)(bf.substs_ptr + i); + i += sizeof(uint32_t); + const char *name = bf.substs_ptr + i; + out << " " << std::setfill('0') << std::setw(8) << std::hex << offset + << ": " << std::dec << name << '\n'; + i += strlen(name); + } } void print_file_code(const Bytefile &bf, std::ostream &out) { @@ -786,6 +669,7 @@ void print_file_code(const Bytefile &bf, std::ostream &out) { out << std::endl; if (cmd == Cmd::EXIT) { + std::cout << "> EXIT" << std::endl; break; } } @@ -796,7 +680,7 @@ void print_file(const Bytefile &bf, std::ostream &out) { out << "Code:\n"; print_file_code(bf, out); - out << "code end\n"; + out << "Code end\n"; } extern "C" { diff --git a/byterun/src/types.c b/byterun/src/types.c index e2df5881a..1a38e7f49 100644 --- a/byterun/src/types.c +++ b/byterun/src/types.c @@ -19,8 +19,6 @@ void init_state(struct State* s, void** stack) { s->bf = NULL; s->current_line = 0; s->is_closure_call = false; - s->current_module_id = 0; - s->call_module_id = 0; s->ip = NULL; //s->bf->code_ptr; s->instr_ip = NULL; //s->bf->code_ptr; s->call_ip = NULL; @@ -38,16 +36,13 @@ void init_state(struct State* s, void** stack) { #endif } -void init_mod_state(uint mod_id, struct State* s) { - // init module data - s->bf = mod_get(mod_id); - s->current_module_id = mod_id; +void prepare_state(Bytefile* bf, struct State* s) { + // init data + s->bf = bf; // clearup from previous executions s->is_closure_call = false; - s->current_module_id = 0; - s->call_module_id = 0; s->call_ip = NULL; s->current_line = 0; @@ -62,7 +57,7 @@ void init_mod_state(uint mod_id, struct State* s) { #endif } -void init_mod_state_globals(struct State *s) { +void push_globals(struct State *s) { s_pushn_nil(s->bf->global_area_size); s->bf->global_ptr = (void*)__gc_stack_top; diff --git a/byterun/test046 b/byterun/test046 new file mode 100755 index 000000000..2081b68b7 Binary files /dev/null and b/byterun/test046 differ diff --git a/byterun/test046.i b/byterun/test046.i new file mode 100644 index 000000000..517e120ae --- /dev/null +++ b/byterun/test046.i @@ -0,0 +1 @@ +I,Std; diff --git a/byterun/test046.s b/byterun/test046.s new file mode 100644 index 000000000..64204d021 --- /dev/null +++ b/byterun/test046.s @@ -0,0 +1,2351 @@ + .file "/home/dragon/Containers/LaMa/projects/Lama/byterun/../regression/test046.lama" + + .stabs "/home/dragon/Containers/LaMa/projects/Lama/byterun/../regression/test046.lama",100,0,0,.Ltext + + .globl main + + .data + +string_0: .string "../regression/test046.lama" + +init: .quad 0 + + .section custom_data,"aw",@progbits + +filler: .fill 5, 8, 1 + + .stabs "n:S1",40,0,0,global_n + +global_n: .quad 1 + + .text + +.Ltext: + + .stabs "data:t1=r1;0;4294967295;",128,0,0,0 + +# IMPORT ("Std") + +# PUBLIC ("main") + +# EXTERN ("Llowercase") + +# EXTERN ("Luppercase") + +# EXTERN ("LtagHash") + +# EXTERN ("LflatCompare") + +# EXTERN ("LcompareTags") + +# EXTERN ("LkindOf") + +# EXTERN ("Ltime") + +# EXTERN ("Lrandom") + +# EXTERN ("LdisableGC") + +# EXTERN ("LenableGC") + +# EXTERN ("Ls__Infix_37") + +# EXTERN ("Ls__Infix_47") + +# EXTERN ("Ls__Infix_42") + +# EXTERN ("Ls__Infix_45") + +# EXTERN ("Ls__Infix_43") + +# EXTERN ("Ls__Infix_62") + +# EXTERN ("Ls__Infix_6261") + +# EXTERN ("Ls__Infix_60") + +# EXTERN ("Ls__Infix_6061") + +# EXTERN ("Ls__Infix_3361") + +# EXTERN ("Ls__Infix_6161") + +# EXTERN ("Ls__Infix_3838") + +# EXTERN ("Ls__Infix_3333") + +# EXTERN ("Ls__Infix_58") + +# EXTERN ("Li__Infix_4343") + +# EXTERN ("Lcompare") + +# EXTERN ("Lwrite") + +# EXTERN ("Lread") + +# EXTERN ("Lfailure") + +# EXTERN ("Lfexists") + +# EXTERN ("Lfwrite") + +# EXTERN ("Lfread") + +# EXTERN ("Lfclose") + +# EXTERN ("Lfopen") + +# EXTERN ("Lfprintf") + +# EXTERN ("Lprintf") + +# EXTERN ("LmakeString") + +# EXTERN ("Lsprintf") + +# EXTERN ("LregexpMatch") + +# EXTERN ("Lregexp") + +# EXTERN ("Lsubstring") + +# EXTERN ("LmatchSubString") + +# EXTERN ("Lstringcat") + +# EXTERN ("LreadLine") + +# EXTERN ("Ltl") + +# EXTERN ("Lhd") + +# EXTERN ("Lsnd") + +# EXTERN ("Lfst") + +# EXTERN ("Lhash") + +# EXTERN ("Lclone") + +# EXTERN ("Llength") + +# EXTERN ("Lstring") + +# EXTERN ("LmakeArray") + +# EXTERN ("LstringInt") + +# EXTERN ("global_sysargs") + +# EXTERN ("Lsystem") + +# EXTERN ("LgetEnv") + +# EXTERN ("Lassert") + +# LABEL ("main") + +main: + +# BEGIN ("main", 2, 4, [], [], []) + + .type main, @function + + .cfi_startproc + + movq init(%rip), %rax + test %rax, %rax + jz continue + ret +_ERROR: + + call Lbinoperror + ret +_ERROR2: + + call Lbinoperror2 + ret +continue: + + movq $1, init(%rip) + pushq %rbp + .cfi_def_cfa_offset 8 + + .cfi_offset 5, -8 + + movq %rsp, %rbp + .cfi_def_cfa_register 5 + + subq $Lmain_SIZE, %rsp + movq %rdi, %r12 + movq %rsi, %r13 + movq %rcx, %r14 + movq %rsp, %rdi + leaq filler(%rip), %rsi + movq $LSmain_SIZE, %rcx + rep movsq + movq %r12, %rdi + movq %r13, %rsi + movq %r14, %rcx + movq $15, %rax + test %rsp, %rax + jz ALIGNED + pushq filler(%rip) +ALIGNED: + + pushq %rdi + pushq %rsi + call __gc_init + popq %rsi + popq %rdi + call set_args +# SLABEL ("L1") + +L1: + +# LINE (3) + + .stabn 68,0,3,.L0 + +.L0: + +# CALL ("Lread", 0, false) + + pushq %rdi + pushq %rsi + movq $0, %r11 + call Lread + popq %rsi + popq %rdi + movq %rax, %r10 +# LINE (1) + + .stabn 68,0,1,.L1 + +.L1: + +# ST (Global ("n")) + + movq %r10, global_n(%rip) +# DROP + +# CONST (3) + + movq $7, %r10 +# DUP + + movq %r10, %r11 +# SLABEL ("L11") + +L11: + +# DROP + +# DUP + + movq %r10, %r11 +# ST (Local (0)) + + movq %r11, -8(%rbp) +# DROP + +# DROP + +# SLABEL ("L13") + +L13: + +# LINE (6) + + .stabn 68,0,6,.L2 + +.L2: + +# LD (Local (0)) + + movq -8(%rbp), %r10 +# CALL ("Lwrite", 1, false) + + pushq %rdi + pushq %rsi + movq %r10, %rdi + movq $1, %r11 + call Lwrite + popq %rsi + popq %rdi + movq %rax, %r10 +# DROP + +# SLABEL ("L14") + +L14: + +# JMP ("L7") + + jmp L7 +# SLABEL ("L12") + +L12: + +# JMP ("L7") + +# LABEL ("L7") + +L7: + +# CONST (3) + + movq $7, %r10 +# DUP + + movq %r10, %r11 +# SLABEL ("L20") + +L20: + +# DROP + +# DUP + + movq %r10, %r11 +# ST (Local (0)) + + movq %r11, -8(%rbp) +# DROP + +# DROP + +# SLABEL ("L22") + +L22: + +# LINE (11) + + .stabn 68,0,11,.L3 + +.L3: + +# LD (Local (0)) + + movq -8(%rbp), %r10 +# CALL ("Lwrite", 1, false) + + pushq %rdi + pushq %rsi + movq %r10, %rdi + movq $1, %r11 + call Lwrite + popq %rsi + popq %rdi + movq %rax, %r10 +# DROP + +# SLABEL ("L23") + +L23: + +# SLABEL ("L21") + +L21: + +# JMP ("L17") + + jmp L17 +# LABEL ("L17") + +L17: + +# CONST (3) + + movq $7, %r10 +# DUP + + movq %r10, %r11 +# SLABEL ("L29") + +L29: + +# DROP + +# DUP + + movq %r10, %r11 +# ST (Local (0)) + + movq %r11, -8(%rbp) +# DROP + +# DROP + +# SLABEL ("L31") + +L31: + +# LINE (15) + + .stabn 68,0,15,.L4 + +.L4: + +# LD (Local (0)) + + movq -8(%rbp), %r10 +# CALL ("Lwrite", 1, false) + + pushq %rdi + pushq %rsi + movq %r10, %rdi + movq $1, %r11 + call Lwrite + popq %rsi + popq %rdi + movq %rax, %r10 +# DROP + +# SLABEL ("L32") + +L32: + +# SLABEL ("L30") + +L30: + +# JMP ("L26") + + jmp L26 +# LABEL ("L26") + +L26: + +# CONST (1) + + movq $3, %r10 +# CONST (2) + + movq $5, %r11 +# CONST (3) + + movq $7, %r12 +# SEXP ("A", 3) + + movq $55, %r13 + pushq %rdi + pushq %rsi + pushq %r13 + pushq %r12 + pushq %r11 + pushq %r10 + movq %rsp, %rdi + movq $9, %rsi + call Bsexp + addq $32, %rsp + popq %rsi + popq %rdi + movq %rax, %r10 +# DUP + + movq %r10, %r11 +# SLABEL ("L44") + +L44: + +# DUP + + movq %r11, %r12 +# TAG ("A", 0) + + movq $55, %r13 + movq $1, %r14 + pushq %rdi + pushq %rsi + pushq %r10 + pushq %r11 + movq %r14, %rdx + movq %r13, %rsi + movq %r12, %rdi + movq $3, %r11 + call Btag + popq %r11 + popq %r10 + popq %rsi + popq %rdi + movq %rax, %r12 +# CJMP ("nz", "L42") + + sarq %r12 + cmpq $0, %r12 + jnz L42 +# LABEL ("L43") + +L43: + +# DROP + +# JMP ("L41") + + jmp L41 +# LABEL ("L42") + +L42: + +# DROP + +# DROP + +# SLABEL ("L46") + +L46: + +# LINE (19) + + .stabn 68,0,19,.L5 + +.L5: + +# CONST (1) + + movq $3, %r10 +# CALL ("Lwrite", 1, false) + + pushq %rdi + pushq %rsi + movq %r10, %rdi + movq $1, %r11 + call Lwrite + popq %rsi + popq %rdi + movq %rax, %r10 +# DROP + +# SLABEL ("L47") + +L47: + +# JMP ("L35") + + jmp L35 +# SLABEL ("L45") + +L45: + +# SLABEL ("L52") + +L52: + +# LABEL ("L41") + +L41: + +# DUP + + movq %r10, %r11 +# DUP + + movq %r11, %r12 +# TAG ("A", 3) + + movq $55, %r13 + movq $7, %r14 + pushq %rdi + pushq %rsi + pushq %r10 + pushq %r11 + movq %r14, %rdx + movq %r13, %rsi + movq %r12, %rdi + movq $3, %r11 + call Btag + popq %r11 + popq %r10 + popq %rsi + popq %rdi + movq %rax, %r12 +# CJMP ("nz", "L50") + + sarq %r12 + cmpq $0, %r12 + jnz L50 +# LABEL ("L51") + +L51: + +# DROP + +# JMP ("L36") + + jmp L36 +# LABEL ("L50") + +L50: + +# DUP + + movq %r11, %r12 +# CONST (0) + + movq $1, %r13 +# ELEM + + pushq %rdi + pushq %rsi + pushq %r10 + pushq %r11 + movq %r13, %rsi + movq %r12, %rdi + movq $2, %r11 + call Belem + popq %r11 + popq %r10 + popq %rsi + popq %rdi + movq %rax, %r12 +# DROP + +# DUP + + movq %r11, %r12 +# CONST (1) + + movq $3, %r13 +# ELEM + + pushq %rdi + pushq %rsi + pushq %r10 + pushq %r11 + movq %r13, %rsi + movq %r12, %rdi + movq $2, %r11 + call Belem + popq %r11 + popq %r10 + popq %rsi + popq %rdi + movq %rax, %r12 +# DROP + +# DUP + + movq %r11, %r12 +# CONST (2) + + movq $5, %r13 +# ELEM + + pushq %rdi + pushq %rsi + pushq %r10 + pushq %r11 + movq %r13, %rsi + movq %r12, %rdi + movq $2, %r11 + call Belem + popq %r11 + popq %r10 + popq %rsi + popq %rdi + movq %rax, %r12 +# DROP + +# DROP + +# DUP + + movq %r10, %r11 +# ST (Local (0)) + + movq %r11, -8(%rbp) +# DROP + +# DROP + +# SLABEL ("L54") + +L54: + +# LINE (20) + + .stabn 68,0,20,.L6 + +.L6: + +# LD (Local (0)) + + movq -8(%rbp), %r10 +# DUP + + movq %r10, %r11 +# SLABEL ("L60") + +L60: + +# DUP + + movq %r11, %r12 +# TAG ("A", 3) + + movq $55, %r13 + movq $7, %r14 + pushq %rdi + pushq %rsi + pushq %r10 + pushq %r11 + movq %r14, %rdx + movq %r13, %rsi + movq %r12, %rdi + movq $3, %r11 + call Btag + popq %r11 + popq %r10 + popq %rsi + popq %rdi + movq %rax, %r12 +# CJMP ("nz", "L58") + + sarq %r12 + cmpq $0, %r12 + jnz L58 +# LABEL ("L59") + +L59: + +# DROP + +# JMP ("L56") + + jmp L56 +# LABEL ("L58") + +L58: + +# DUP + + movq %r11, %r12 +# CONST (0) + + movq $1, %r13 +# ELEM + + pushq %rdi + pushq %rsi + pushq %r10 + pushq %r11 + movq %r13, %rsi + movq %r12, %rdi + movq $2, %r11 + call Belem + popq %r11 + popq %r10 + popq %rsi + popq %rdi + movq %rax, %r12 +# DROP + +# DUP + + movq %r11, %r12 +# CONST (1) + + movq $3, %r13 +# ELEM + + pushq %rdi + pushq %rsi + pushq %r10 + pushq %r11 + movq %r13, %rsi + movq %r12, %rdi + movq $2, %r11 + call Belem + popq %r11 + popq %r10 + popq %rsi + popq %rdi + movq %rax, %r12 +# DROP + +# DUP + + movq %r11, %r12 +# CONST (2) + + movq $5, %r13 +# ELEM + + pushq %rdi + pushq %rsi + pushq %r10 + pushq %r11 + movq %r13, %rsi + movq %r12, %rdi + movq $2, %r11 + call Belem + popq %r11 + popq %r10 + popq %rsi + popq %rdi + movq %rax, %r12 +# DROP + +# DROP + +# DUP + + movq %r10, %r11 +# CONST (0) + + movq $1, %r12 +# ELEM + + pushq %rdi + pushq %rsi + pushq %r10 + pushq filler(%rip) + movq %r12, %rsi + movq %r11, %rdi + movq $2, %r11 + call Belem + addq $8, %rsp + popq %r10 + popq %rsi + popq %rdi + movq %rax, %r11 +# ST (Local (3)) + + movq %r11, -32(%rbp) +# DROP + +# DUP + + movq %r10, %r11 +# CONST (1) + + movq $3, %r12 +# ELEM + + pushq %rdi + pushq %rsi + pushq %r10 + pushq filler(%rip) + movq %r12, %rsi + movq %r11, %rdi + movq $2, %r11 + call Belem + addq $8, %rsp + popq %r10 + popq %rsi + popq %rdi + movq %rax, %r11 +# ST (Local (2)) + + movq %r11, -24(%rbp) +# DROP + +# DUP + + movq %r10, %r11 +# CONST (2) + + movq $5, %r12 +# ELEM + + pushq %rdi + pushq %rsi + pushq %r10 + pushq filler(%rip) + movq %r12, %rsi + movq %r11, %rdi + movq $2, %r11 + call Belem + addq $8, %rsp + popq %r10 + popq %rsi + popq %rdi + movq %rax, %r11 +# ST (Local (1)) + + movq %r11, -16(%rbp) +# DROP + +# DROP + +# SLABEL ("L62") + +L62: + +# LINE (21) + + .stabn 68,0,21,.L7 + +.L7: + +# LD (Local (3)) + + movq -32(%rbp), %r10 +# CALL ("Lwrite", 1, false) + + pushq %rdi + pushq %rsi + movq %r10, %rdi + movq $1, %r11 + call Lwrite + popq %rsi + popq %rdi + movq %rax, %r10 +# DROP + +# LD (Local (2)) + + movq -24(%rbp), %r10 +# CALL ("Lwrite", 1, false) + + pushq %rdi + pushq %rsi + movq %r10, %rdi + movq $1, %r11 + call Lwrite + popq %rsi + popq %rdi + movq %rax, %r10 +# DROP + +# LD (Local (1)) + + movq -16(%rbp), %r10 +# CALL ("Lwrite", 1, false) + + pushq %rdi + pushq %rsi + movq %r10, %rdi + movq $1, %r11 + call Lwrite + popq %rsi + popq %rdi + movq %rax, %r10 +# DROP + +# SLABEL ("L63") + +L63: + +# SLABEL ("L61") + +L61: + +# JMP ("L35") + + jmp L35 +# LABEL ("L56") + +L56: + +# FAIL ((20, 24), false) + + movq $24, %r13 + movq $20, %r12 + leaq string_0(%rip), %r11 + movq %r10, %r10 + pushq %rdi + pushq %rsi + movq %r13, %rcx + movq %r12, %rdx + movq %r11, %rsi + movq %r10, %rdi + movq $4, %r11 + call Bmatch_failure + popq %rsi + popq %rdi + movq %rax, %r10 +# JMP ("L35") + + jmp L35 +# SLABEL ("L55") + +L55: + +# SLABEL ("L53") + +L53: + +# JMP ("L35") + +# LABEL ("L36") + +L36: + +# FAIL ((18, 5), false) + + movq $5, %r13 + movq $18, %r12 + leaq string_0(%rip), %r11 + movq %r10, %r10 + pushq %rdi + pushq %rsi + movq %r13, %rcx + movq %r12, %rdx + movq %r11, %rsi + movq %r10, %rdi + movq $4, %r11 + call Bmatch_failure + popq %rsi + popq %rdi + movq %rax, %r10 +# JMP ("L35") + + jmp L35 +# LABEL ("L35") + +L35: + +# CONST (1) + + movq $3, %r10 +# CONST (2) + + movq $5, %r11 +# CONST (3) + + movq $7, %r12 +# CONST (4) + + movq $9, %r13 +# CONST (5) + + movq $11, %r14 +# SEXP ("A", 5) + + movq $55, -40(%rbp) + pushq %rdi + pushq %rsi + pushq -40(%rbp) + pushq %r14 + pushq %r13 + pushq %r12 + pushq %r11 + pushq %r10 + movq %rsp, %rdi + movq $13, %rsi + call Bsexp + addq $48, %rsp + popq %rsi + popq %rdi + movq %rax, %r10 +# DUP + + movq %r10, %r11 +# SLABEL ("L83") + +L83: + +# DUP + + movq %r11, %r12 +# TAG ("A", 0) + + movq $55, %r13 + movq $1, %r14 + pushq %rdi + pushq %rsi + pushq %r10 + pushq %r11 + movq %r14, %rdx + movq %r13, %rsi + movq %r12, %rdi + movq $3, %r11 + call Btag + popq %r11 + popq %r10 + popq %rsi + popq %rdi + movq %rax, %r12 +# CJMP ("nz", "L81") + + sarq %r12 + cmpq $0, %r12 + jnz L81 +# LABEL ("L82") + +L82: + +# DROP + +# JMP ("L80") + + jmp L80 +# LABEL ("L81") + +L81: + +# DROP + +# DROP + +# SLABEL ("L85") + +L85: + +# LINE (26) + + .stabn 68,0,26,.L8 + +.L8: + +# CONST (0) + + movq $1, %r10 +# CALL ("Lwrite", 1, false) + + pushq %rdi + pushq %rsi + movq %r10, %rdi + movq $1, %r11 + call Lwrite + popq %rsi + popq %rdi + movq %rax, %r10 +# DROP + +# SLABEL ("L86") + +L86: + +# JMP ("L72") + + jmp L72 +# SLABEL ("L84") + +L84: + +# SLABEL ("L92") + +L92: + +# LABEL ("L80") + +L80: + +# DUP + + movq %r10, %r11 +# DUP + + movq %r11, %r12 +# TAG ("A", 1) + + movq $55, %r13 + movq $3, %r14 + pushq %rdi + pushq %rsi + pushq %r10 + pushq %r11 + movq %r14, %rdx + movq %r13, %rsi + movq %r12, %rdi + movq $3, %r11 + call Btag + popq %r11 + popq %r10 + popq %rsi + popq %rdi + movq %rax, %r12 +# CJMP ("nz", "L90") + + sarq %r12 + cmpq $0, %r12 + jnz L90 +# LABEL ("L91") + +L91: + +# DROP + +# JMP ("L89") + + jmp L89 +# LABEL ("L90") + +L90: + +# DUP + + movq %r11, %r12 +# CONST (0) + + movq $1, %r13 +# ELEM + + pushq %rdi + pushq %rsi + pushq %r10 + pushq %r11 + movq %r13, %rsi + movq %r12, %rdi + movq $2, %r11 + call Belem + popq %r11 + popq %r10 + popq %rsi + popq %rdi + movq %rax, %r12 +# DROP + +# DROP + +# DROP + +# SLABEL ("L94") + +L94: + +# LINE (27) + + .stabn 68,0,27,.L9 + +.L9: + +# CONST (1) + + movq $3, %r10 +# CALL ("Lwrite", 1, false) + + pushq %rdi + pushq %rsi + movq %r10, %rdi + movq $1, %r11 + call Lwrite + popq %rsi + popq %rdi + movq %rax, %r10 +# DROP + +# SLABEL ("L95") + +L95: + +# JMP ("L72") + + jmp L72 +# SLABEL ("L93") + +L93: + +# SLABEL ("L101") + +L101: + +# LABEL ("L89") + +L89: + +# DUP + + movq %r10, %r11 +# DUP + + movq %r11, %r12 +# TAG ("A", 2) + + movq $55, %r13 + movq $5, %r14 + pushq %rdi + pushq %rsi + pushq %r10 + pushq %r11 + movq %r14, %rdx + movq %r13, %rsi + movq %r12, %rdi + movq $3, %r11 + call Btag + popq %r11 + popq %r10 + popq %rsi + popq %rdi + movq %rax, %r12 +# CJMP ("nz", "L99") + + sarq %r12 + cmpq $0, %r12 + jnz L99 +# LABEL ("L100") + +L100: + +# DROP + +# JMP ("L98") + + jmp L98 +# LABEL ("L99") + +L99: + +# DUP + + movq %r11, %r12 +# CONST (0) + + movq $1, %r13 +# ELEM + + pushq %rdi + pushq %rsi + pushq %r10 + pushq %r11 + movq %r13, %rsi + movq %r12, %rdi + movq $2, %r11 + call Belem + popq %r11 + popq %r10 + popq %rsi + popq %rdi + movq %rax, %r12 +# DROP + +# DUP + + movq %r11, %r12 +# CONST (1) + + movq $3, %r13 +# ELEM + + pushq %rdi + pushq %rsi + pushq %r10 + pushq %r11 + movq %r13, %rsi + movq %r12, %rdi + movq $2, %r11 + call Belem + popq %r11 + popq %r10 + popq %rsi + popq %rdi + movq %rax, %r12 +# DROP + +# DROP + +# DROP + +# SLABEL ("L103") + +L103: + +# LINE (28) + + .stabn 68,0,28,.L10 + +.L10: + +# CONST (2) + + movq $5, %r10 +# CALL ("Lwrite", 1, false) + + pushq %rdi + pushq %rsi + movq %r10, %rdi + movq $1, %r11 + call Lwrite + popq %rsi + popq %rdi + movq %rax, %r10 +# DROP + +# SLABEL ("L104") + +L104: + +# JMP ("L72") + + jmp L72 +# SLABEL ("L102") + +L102: + +# SLABEL ("L110") + +L110: + +# LABEL ("L98") + +L98: + +# DUP + + movq %r10, %r11 +# DUP + + movq %r11, %r12 +# TAG ("A", 3) + + movq $55, %r13 + movq $7, %r14 + pushq %rdi + pushq %rsi + pushq %r10 + pushq %r11 + movq %r14, %rdx + movq %r13, %rsi + movq %r12, %rdi + movq $3, %r11 + call Btag + popq %r11 + popq %r10 + popq %rsi + popq %rdi + movq %rax, %r12 +# CJMP ("nz", "L108") + + sarq %r12 + cmpq $0, %r12 + jnz L108 +# LABEL ("L109") + +L109: + +# DROP + +# JMP ("L107") + + jmp L107 +# LABEL ("L108") + +L108: + +# DUP + + movq %r11, %r12 +# CONST (0) + + movq $1, %r13 +# ELEM + + pushq %rdi + pushq %rsi + pushq %r10 + pushq %r11 + movq %r13, %rsi + movq %r12, %rdi + movq $2, %r11 + call Belem + popq %r11 + popq %r10 + popq %rsi + popq %rdi + movq %rax, %r12 +# DROP + +# DUP + + movq %r11, %r12 +# CONST (1) + + movq $3, %r13 +# ELEM + + pushq %rdi + pushq %rsi + pushq %r10 + pushq %r11 + movq %r13, %rsi + movq %r12, %rdi + movq $2, %r11 + call Belem + popq %r11 + popq %r10 + popq %rsi + popq %rdi + movq %rax, %r12 +# DROP + +# DUP + + movq %r11, %r12 +# CONST (2) + + movq $5, %r13 +# ELEM + + pushq %rdi + pushq %rsi + pushq %r10 + pushq %r11 + movq %r13, %rsi + movq %r12, %rdi + movq $2, %r11 + call Belem + popq %r11 + popq %r10 + popq %rsi + popq %rdi + movq %rax, %r12 +# DROP + +# DROP + +# DROP + +# SLABEL ("L112") + +L112: + +# LINE (29) + + .stabn 68,0,29,.L11 + +.L11: + +# CONST (3) + + movq $7, %r10 +# CALL ("Lwrite", 1, false) + + pushq %rdi + pushq %rsi + movq %r10, %rdi + movq $1, %r11 + call Lwrite + popq %rsi + popq %rdi + movq %rax, %r10 +# DROP + +# SLABEL ("L113") + +L113: + +# JMP ("L72") + + jmp L72 +# SLABEL ("L111") + +L111: + +# SLABEL ("L119") + +L119: + +# LABEL ("L107") + +L107: + +# DUP + + movq %r10, %r11 +# DUP + + movq %r11, %r12 +# TAG ("A", 4) + + movq $55, %r13 + movq $9, %r14 + pushq %rdi + pushq %rsi + pushq %r10 + pushq %r11 + movq %r14, %rdx + movq %r13, %rsi + movq %r12, %rdi + movq $3, %r11 + call Btag + popq %r11 + popq %r10 + popq %rsi + popq %rdi + movq %rax, %r12 +# CJMP ("nz", "L117") + + sarq %r12 + cmpq $0, %r12 + jnz L117 +# LABEL ("L118") + +L118: + +# DROP + +# JMP ("L116") + + jmp L116 +# LABEL ("L117") + +L117: + +# DUP + + movq %r11, %r12 +# CONST (0) + + movq $1, %r13 +# ELEM + + pushq %rdi + pushq %rsi + pushq %r10 + pushq %r11 + movq %r13, %rsi + movq %r12, %rdi + movq $2, %r11 + call Belem + popq %r11 + popq %r10 + popq %rsi + popq %rdi + movq %rax, %r12 +# DROP + +# DUP + + movq %r11, %r12 +# CONST (1) + + movq $3, %r13 +# ELEM + + pushq %rdi + pushq %rsi + pushq %r10 + pushq %r11 + movq %r13, %rsi + movq %r12, %rdi + movq $2, %r11 + call Belem + popq %r11 + popq %r10 + popq %rsi + popq %rdi + movq %rax, %r12 +# DROP + +# DUP + + movq %r11, %r12 +# CONST (2) + + movq $5, %r13 +# ELEM + + pushq %rdi + pushq %rsi + pushq %r10 + pushq %r11 + movq %r13, %rsi + movq %r12, %rdi + movq $2, %r11 + call Belem + popq %r11 + popq %r10 + popq %rsi + popq %rdi + movq %rax, %r12 +# DROP + +# DUP + + movq %r11, %r12 +# CONST (3) + + movq $7, %r13 +# ELEM + + pushq %rdi + pushq %rsi + pushq %r10 + pushq %r11 + movq %r13, %rsi + movq %r12, %rdi + movq $2, %r11 + call Belem + popq %r11 + popq %r10 + popq %rsi + popq %rdi + movq %rax, %r12 +# DROP + +# DROP + +# DROP + +# SLABEL ("L121") + +L121: + +# LINE (30) + + .stabn 68,0,30,.L12 + +.L12: + +# CONST (4) + + movq $9, %r10 +# CALL ("Lwrite", 1, false) + + pushq %rdi + pushq %rsi + movq %r10, %rdi + movq $1, %r11 + call Lwrite + popq %rsi + popq %rdi + movq %rax, %r10 +# DROP + +# SLABEL ("L122") + +L122: + +# JMP ("L72") + + jmp L72 +# SLABEL ("L120") + +L120: + +# SLABEL ("L127") + +L127: + +# LABEL ("L116") + +L116: + +# DUP + + movq %r10, %r11 +# DUP + + movq %r11, %r12 +# TAG ("A", 5) + + movq $55, %r13 + movq $11, %r14 + pushq %rdi + pushq %rsi + pushq %r10 + pushq %r11 + movq %r14, %rdx + movq %r13, %rsi + movq %r12, %rdi + movq $3, %r11 + call Btag + popq %r11 + popq %r10 + popq %rsi + popq %rdi + movq %rax, %r12 +# CJMP ("nz", "L125") + + sarq %r12 + cmpq $0, %r12 + jnz L125 +# LABEL ("L126") + +L126: + +# DROP + +# JMP ("L73") + + jmp L73 +# LABEL ("L125") + +L125: + +# DUP + + movq %r11, %r12 +# CONST (0) + + movq $1, %r13 +# ELEM + + pushq %rdi + pushq %rsi + pushq %r10 + pushq %r11 + movq %r13, %rsi + movq %r12, %rdi + movq $2, %r11 + call Belem + popq %r11 + popq %r10 + popq %rsi + popq %rdi + movq %rax, %r12 +# DROP + +# DUP + + movq %r11, %r12 +# CONST (1) + + movq $3, %r13 +# ELEM + + pushq %rdi + pushq %rsi + pushq %r10 + pushq %r11 + movq %r13, %rsi + movq %r12, %rdi + movq $2, %r11 + call Belem + popq %r11 + popq %r10 + popq %rsi + popq %rdi + movq %rax, %r12 +# DROP + +# DUP + + movq %r11, %r12 +# CONST (2) + + movq $5, %r13 +# ELEM + + pushq %rdi + pushq %rsi + pushq %r10 + pushq %r11 + movq %r13, %rsi + movq %r12, %rdi + movq $2, %r11 + call Belem + popq %r11 + popq %r10 + popq %rsi + popq %rdi + movq %rax, %r12 +# DROP + +# DUP + + movq %r11, %r12 +# CONST (3) + + movq $7, %r13 +# ELEM + + pushq %rdi + pushq %rsi + pushq %r10 + pushq %r11 + movq %r13, %rsi + movq %r12, %rdi + movq $2, %r11 + call Belem + popq %r11 + popq %r10 + popq %rsi + popq %rdi + movq %rax, %r12 +# DROP + +# DUP + + movq %r11, %r12 +# CONST (4) + + movq $9, %r13 +# ELEM + + pushq %rdi + pushq %rsi + pushq %r10 + pushq %r11 + movq %r13, %rsi + movq %r12, %rdi + movq $2, %r11 + call Belem + popq %r11 + popq %r10 + popq %rsi + popq %rdi + movq %rax, %r12 +# DROP + +# DROP + +# DROP + +# SLABEL ("L129") + +L129: + +# LINE (31) + + .stabn 68,0,31,.L13 + +.L13: + +# CONST (5) + + movq $11, %r10 +# CALL ("Lwrite", 1, false) + + pushq %rdi + pushq %rsi + movq %r10, %rdi + movq $1, %r11 + call Lwrite + popq %rsi + popq %rdi + movq %rax, %r10 +# DROP + +# SLABEL ("L130") + +L130: + +# SLABEL ("L128") + +L128: + +# JMP ("L72") + + jmp L72 +# LABEL ("L73") + +L73: + +# FAIL ((25, 5), false) + + movq $5, %r13 + movq $25, %r12 + leaq string_0(%rip), %r11 + movq %r10, %r10 + pushq %rdi + pushq %rsi + movq %r13, %rcx + movq %r12, %rdx + movq %r11, %rsi + movq %r10, %rdi + movq $4, %r11 + call Bmatch_failure + popq %rsi + popq %rdi + movq %rax, %r10 +# JMP ("L72") + + jmp L72 +# LABEL ("L72") + +L72: + +# LINE (32) + + .stabn 68,0,32,.L14 + +.L14: + +# CONST (1) + + movq $3, %r10 +# CONST (2) + + movq $5, %r11 +# CONST (3) + + movq $7, %r12 +# CONST (4) + + movq $9, %r13 +# CONST (5) + + movq $11, %r14 +# SEXP ("A", 5) + + movq $55, -40(%rbp) + pushq %rdi + pushq %rsi + pushq -40(%rbp) + pushq %r14 + pushq %r13 + pushq %r12 + pushq %r11 + pushq %r10 + movq %rsp, %rdi + movq $13, %rsi + call Bsexp + addq $48, %rsp + popq %rsi + popq %rdi + movq %rax, %r10 +# CALL ("Llength", 1, false) + + pushq %rdi + pushq %rsi + movq %r10, %rdi + movq $1, %r11 + call Llength + popq %rsi + popq %rdi + movq %rax, %r10 +# CALL ("Lwrite", 1, false) + + pushq %rdi + pushq %rsi + movq %r10, %rdi + movq $1, %r11 + call Lwrite + popq %rsi + popq %rdi + movq %rax, %r10 +# DROP + +# LINE (34) + + .stabn 68,0,34,.L15 + +.L15: + +# CONST (1) + + movq $3, %r10 +# CONST (2) + + movq $5, %r11 +# CONST (3) + + movq $7, %r12 +# CONST (4) + + movq $9, %r13 +# CONST (5) + + movq $11, %r14 +# SEXP ("A", 5) + + movq $55, -40(%rbp) + pushq %rdi + pushq %rsi + pushq -40(%rbp) + pushq %r14 + pushq %r13 + pushq %r12 + pushq %r11 + pushq %r10 + movq %rsp, %rdi + movq $13, %rsi + call Bsexp + addq $48, %rsp + popq %rsi + popq %rdi + movq %rax, %r10 +# CONST (0) + + movq $1, %r11 +# ELEM + + pushq %rdi + pushq %rsi + movq %r11, %rsi + movq %r10, %rdi + movq $2, %r11 + call Belem + popq %rsi + popq %rdi + movq %rax, %r10 +# CALL ("Lwrite", 1, false) + + pushq %rdi + pushq %rsi + movq %r10, %rdi + movq $1, %r11 + call Lwrite + popq %rsi + popq %rdi + movq %rax, %r10 +# DROP + +# LINE (36) + + .stabn 68,0,36,.L16 + +.L16: + +# CONST (1) + + movq $3, %r10 +# CONST (2) + + movq $5, %r11 +# CONST (3) + + movq $7, %r12 +# CONST (4) + + movq $9, %r13 +# CONST (5) + + movq $11, %r14 +# SEXP ("A", 5) + + movq $55, -40(%rbp) + pushq %rdi + pushq %rsi + pushq -40(%rbp) + pushq %r14 + pushq %r13 + pushq %r12 + pushq %r11 + pushq %r10 + movq %rsp, %rdi + movq $13, %rsi + call Bsexp + addq $48, %rsp + popq %rsi + popq %rdi + movq %rax, %r10 +# CONST (1) + + movq $3, %r11 +# ELEM + + pushq %rdi + pushq %rsi + movq %r11, %rsi + movq %r10, %rdi + movq $2, %r11 + call Belem + popq %rsi + popq %rdi + movq %rax, %r10 +# CALL ("Lwrite", 1, false) + + pushq %rdi + pushq %rsi + movq %r10, %rdi + movq $1, %r11 + call Lwrite + popq %rsi + popq %rdi + movq %rax, %r10 +# DROP + +# LINE (37) + + .stabn 68,0,37,.L17 + +.L17: + +# CONST (1) + + movq $3, %r10 +# CONST (2) + + movq $5, %r11 +# CONST (3) + + movq $7, %r12 +# CONST (4) + + movq $9, %r13 +# CONST (5) + + movq $11, %r14 +# SEXP ("A", 5) + + movq $55, -40(%rbp) + pushq %rdi + pushq %rsi + pushq -40(%rbp) + pushq %r14 + pushq %r13 + pushq %r12 + pushq %r11 + pushq %r10 + movq %rsp, %rdi + movq $13, %rsi + call Bsexp + addq $48, %rsp + popq %rsi + popq %rdi + movq %rax, %r10 +# CONST (2) + + movq $5, %r11 +# ELEM + + pushq %rdi + pushq %rsi + movq %r11, %rsi + movq %r10, %rdi + movq $2, %r11 + call Belem + popq %rsi + popq %rdi + movq %rax, %r10 +# CALL ("Lwrite", 1, false) + + pushq %rdi + pushq %rsi + movq %r10, %rdi + movq $1, %r11 + call Lwrite + popq %rsi + popq %rdi + movq %rax, %r10 +# DROP + +# LINE (38) + + .stabn 68,0,38,.L18 + +.L18: + +# CONST (1) + + movq $3, %r10 +# CONST (2) + + movq $5, %r11 +# CONST (3) + + movq $7, %r12 +# CONST (4) + + movq $9, %r13 +# CONST (5) + + movq $11, %r14 +# SEXP ("A", 5) + + movq $55, -40(%rbp) + pushq %rdi + pushq %rsi + pushq -40(%rbp) + pushq %r14 + pushq %r13 + pushq %r12 + pushq %r11 + pushq %r10 + movq %rsp, %rdi + movq $13, %rsi + call Bsexp + addq $48, %rsp + popq %rsi + popq %rdi + movq %rax, %r10 +# CONST (3) + + movq $7, %r11 +# ELEM + + pushq %rdi + pushq %rsi + movq %r11, %rsi + movq %r10, %rdi + movq $2, %r11 + call Belem + popq %rsi + popq %rdi + movq %rax, %r10 +# CALL ("Lwrite", 1, false) + + pushq %rdi + pushq %rsi + movq %r10, %rdi + movq $1, %r11 + call Lwrite + popq %rsi + popq %rdi + movq %rax, %r10 +# DROP + +# LINE (39) + + .stabn 68,0,39,.L19 + +.L19: + +# CONST (1) + + movq $3, %r10 +# CONST (2) + + movq $5, %r11 +# CONST (3) + + movq $7, %r12 +# CONST (4) + + movq $9, %r13 +# CONST (5) + + movq $11, %r14 +# SEXP ("A", 5) + + movq $55, -40(%rbp) + pushq %rdi + pushq %rsi + pushq -40(%rbp) + pushq %r14 + pushq %r13 + pushq %r12 + pushq %r11 + pushq %r10 + movq %rsp, %rdi + movq $13, %rsi + call Bsexp + addq $48, %rsp + popq %rsi + popq %rdi + movq %rax, %r10 +# CONST (4) + + movq $9, %r11 +# ELEM + + pushq %rdi + pushq %rsi + movq %r11, %rsi + movq %r10, %rdi + movq $2, %r11 + call Belem + popq %rsi + popq %rdi + movq %rax, %r10 +# CALL ("Lwrite", 1, false) + + pushq %rdi + pushq %rsi + movq %r10, %rdi + movq $1, %r11 + call Lwrite + popq %rsi + popq %rdi + movq %rax, %r10 +# SLABEL ("L2") + +L2: + +# END + + movq %r10, %rax +Lmain_epilogue: + + movq %rbp, %rsp + popq %rbp + xorq %rax, %rax + .cfi_restore 5 + + .cfi_def_cfa 4, 4 + + ret + .cfi_endproc + + .set Lmain_SIZE, 48 + + .set LSmain_SIZE, 5 + + .size main, .-main + diff --git a/byterun/test046.sm b/byterun/test046.sm new file mode 100644 index 000000000..72a74bc25 --- /dev/null +++ b/byterun/test046.sm @@ -0,0 +1,490 @@ +IMPORT ("Std") +PUBLIC ("main") +EXTERN ("Llowercase") +EXTERN ("Luppercase") +EXTERN ("LtagHash") +EXTERN ("LflatCompare") +EXTERN ("LcompareTags") +EXTERN ("LkindOf") +EXTERN ("Ltime") +EXTERN ("Lrandom") +EXTERN ("LdisableGC") +EXTERN ("LenableGC") +EXTERN ("Ls__Infix_37") +EXTERN ("Ls__Infix_47") +EXTERN ("Ls__Infix_42") +EXTERN ("Ls__Infix_45") +EXTERN ("Ls__Infix_43") +EXTERN ("Ls__Infix_62") +EXTERN ("Ls__Infix_6261") +EXTERN ("Ls__Infix_60") +EXTERN ("Ls__Infix_6061") +EXTERN ("Ls__Infix_3361") +EXTERN ("Ls__Infix_6161") +EXTERN ("Ls__Infix_3838") +EXTERN ("Ls__Infix_3333") +EXTERN ("Ls__Infix_58") +EXTERN ("Li__Infix_4343") +EXTERN ("Lcompare") +EXTERN ("Lwrite") +EXTERN ("Lread") +EXTERN ("Lfailure") +EXTERN ("Lfexists") +EXTERN ("Lfwrite") +EXTERN ("Lfread") +EXTERN ("Lfclose") +EXTERN ("Lfopen") +EXTERN ("Lfprintf") +EXTERN ("Lprintf") +EXTERN ("LmakeString") +EXTERN ("Lsprintf") +EXTERN ("LregexpMatch") +EXTERN ("Lregexp") +EXTERN ("Lsubstring") +EXTERN ("LmatchSubString") +EXTERN ("Lstringcat") +EXTERN ("LreadLine") +EXTERN ("Ltl") +EXTERN ("Lhd") +EXTERN ("Lsnd") +EXTERN ("Lfst") +EXTERN ("Lhash") +EXTERN ("Lclone") +EXTERN ("Llength") +EXTERN ("Lstring") +EXTERN ("LmakeArray") +EXTERN ("LstringInt") +EXTERN ("global_sysargs") +EXTERN ("Lsystem") +EXTERN ("LgetEnv") +EXTERN ("Lassert") +LABEL ("main") +BEGIN ("main", 2, 4, [], [], []) +SLABEL ("L1") +LINE (3) +CALL ("Lread", 0, false) +LINE (1) +ST (Global ("n")) +DROP +CONST (3) +DUP +SLABEL ("L11") +DROP +DUP +ST (Local (0)) +DROP +DROP +SLABEL ("L13") +LINE (6) +LD (Local (0)) +CALL ("Lwrite", 1, false) +DROP +SLABEL ("L14") +JMP ("L7") +SLABEL ("L12") +JMP ("L7") +LABEL ("L7") +CONST (3) +DUP +SLABEL ("L20") +DROP +DUP +ST (Local (0)) +DROP +DROP +SLABEL ("L22") +LINE (11) +LD (Local (0)) +CALL ("Lwrite", 1, false) +DROP +SLABEL ("L23") +SLABEL ("L21") +JMP ("L17") +LABEL ("L17") +CONST (3) +DUP +SLABEL ("L29") +DROP +DUP +ST (Local (0)) +DROP +DROP +SLABEL ("L31") +LINE (15) +LD (Local (0)) +CALL ("Lwrite", 1, false) +DROP +SLABEL ("L32") +SLABEL ("L30") +JMP ("L26") +LABEL ("L26") +CONST (1) +CONST (2) +CONST (3) +SEXP ("A", 3) +DUP +SLABEL ("L44") +DUP +TAG ("A", 0) +CJMP ("nz", "L42") +LABEL ("L43") +DROP +JMP ("L41") +LABEL ("L42") +DROP +DROP +SLABEL ("L46") +LINE (19) +CONST (1) +CALL ("Lwrite", 1, false) +DROP +SLABEL ("L47") +JMP ("L35") +SLABEL ("L45") +SLABEL ("L52") +LABEL ("L41") +DUP +DUP +TAG ("A", 3) +CJMP ("nz", "L50") +LABEL ("L51") +DROP +JMP ("L36") +LABEL ("L50") +DUP +CONST (0) +ELEM +DROP +DUP +CONST (1) +ELEM +DROP +DUP +CONST (2) +ELEM +DROP +DROP +DUP +ST (Local (0)) +DROP +DROP +SLABEL ("L54") +LINE (20) +LD (Local (0)) +DUP +SLABEL ("L60") +DUP +TAG ("A", 3) +CJMP ("nz", "L58") +LABEL ("L59") +DROP +JMP ("L56") +LABEL ("L58") +DUP +CONST (0) +ELEM +DROP +DUP +CONST (1) +ELEM +DROP +DUP +CONST (2) +ELEM +DROP +DROP +DUP +CONST (0) +ELEM +ST (Local (3)) +DROP +DUP +CONST (1) +ELEM +ST (Local (2)) +DROP +DUP +CONST (2) +ELEM +ST (Local (1)) +DROP +DROP +SLABEL ("L62") +LINE (21) +LD (Local (3)) +CALL ("Lwrite", 1, false) +DROP +LD (Local (2)) +CALL ("Lwrite", 1, false) +DROP +LD (Local (1)) +CALL ("Lwrite", 1, false) +DROP +SLABEL ("L63") +SLABEL ("L61") +JMP ("L35") +LABEL ("L56") +FAIL ((20, 24), false) +JMP ("L35") +SLABEL ("L55") +SLABEL ("L53") +JMP ("L35") +LABEL ("L36") +FAIL ((18, 5), false) +JMP ("L35") +LABEL ("L35") +CONST (1) +CONST (2) +CONST (3) +CONST (4) +CONST (5) +SEXP ("A", 5) +DUP +SLABEL ("L83") +DUP +TAG ("A", 0) +CJMP ("nz", "L81") +LABEL ("L82") +DROP +JMP ("L80") +LABEL ("L81") +DROP +DROP +SLABEL ("L85") +LINE (26) +CONST (0) +CALL ("Lwrite", 1, false) +DROP +SLABEL ("L86") +JMP ("L72") +SLABEL ("L84") +SLABEL ("L92") +LABEL ("L80") +DUP +DUP +TAG ("A", 1) +CJMP ("nz", "L90") +LABEL ("L91") +DROP +JMP ("L89") +LABEL ("L90") +DUP +CONST (0) +ELEM +DROP +DROP +DROP +SLABEL ("L94") +LINE (27) +CONST (1) +CALL ("Lwrite", 1, false) +DROP +SLABEL ("L95") +JMP ("L72") +SLABEL ("L93") +SLABEL ("L101") +LABEL ("L89") +DUP +DUP +TAG ("A", 2) +CJMP ("nz", "L99") +LABEL ("L100") +DROP +JMP ("L98") +LABEL ("L99") +DUP +CONST (0) +ELEM +DROP +DUP +CONST (1) +ELEM +DROP +DROP +DROP +SLABEL ("L103") +LINE (28) +CONST (2) +CALL ("Lwrite", 1, false) +DROP +SLABEL ("L104") +JMP ("L72") +SLABEL ("L102") +SLABEL ("L110") +LABEL ("L98") +DUP +DUP +TAG ("A", 3) +CJMP ("nz", "L108") +LABEL ("L109") +DROP +JMP ("L107") +LABEL ("L108") +DUP +CONST (0) +ELEM +DROP +DUP +CONST (1) +ELEM +DROP +DUP +CONST (2) +ELEM +DROP +DROP +DROP +SLABEL ("L112") +LINE (29) +CONST (3) +CALL ("Lwrite", 1, false) +DROP +SLABEL ("L113") +JMP ("L72") +SLABEL ("L111") +SLABEL ("L119") +LABEL ("L107") +DUP +DUP +TAG ("A", 4) +CJMP ("nz", "L117") +LABEL ("L118") +DROP +JMP ("L116") +LABEL ("L117") +DUP +CONST (0) +ELEM +DROP +DUP +CONST (1) +ELEM +DROP +DUP +CONST (2) +ELEM +DROP +DUP +CONST (3) +ELEM +DROP +DROP +DROP +SLABEL ("L121") +LINE (30) +CONST (4) +CALL ("Lwrite", 1, false) +DROP +SLABEL ("L122") +JMP ("L72") +SLABEL ("L120") +SLABEL ("L127") +LABEL ("L116") +DUP +DUP +TAG ("A", 5) +CJMP ("nz", "L125") +LABEL ("L126") +DROP +JMP ("L73") +LABEL ("L125") +DUP +CONST (0) +ELEM +DROP +DUP +CONST (1) +ELEM +DROP +DUP +CONST (2) +ELEM +DROP +DUP +CONST (3) +ELEM +DROP +DUP +CONST (4) +ELEM +DROP +DROP +DROP +SLABEL ("L129") +LINE (31) +CONST (5) +CALL ("Lwrite", 1, false) +DROP +SLABEL ("L130") +SLABEL ("L128") +JMP ("L72") +LABEL ("L73") +FAIL ((25, 5), false) +JMP ("L72") +LABEL ("L72") +LINE (32) +CONST (1) +CONST (2) +CONST (3) +CONST (4) +CONST (5) +SEXP ("A", 5) +CALL ("Llength", 1, false) +CALL ("Lwrite", 1, false) +DROP +LINE (34) +CONST (1) +CONST (2) +CONST (3) +CONST (4) +CONST (5) +SEXP ("A", 5) +CONST (0) +ELEM +CALL ("Lwrite", 1, false) +DROP +LINE (36) +CONST (1) +CONST (2) +CONST (3) +CONST (4) +CONST (5) +SEXP ("A", 5) +CONST (1) +ELEM +CALL ("Lwrite", 1, false) +DROP +LINE (37) +CONST (1) +CONST (2) +CONST (3) +CONST (4) +CONST (5) +SEXP ("A", 5) +CONST (2) +ELEM +CALL ("Lwrite", 1, false) +DROP +LINE (38) +CONST (1) +CONST (2) +CONST (3) +CONST (4) +CONST (5) +SEXP ("A", 5) +CONST (3) +ELEM +CALL ("Lwrite", 1, false) +DROP +LINE (39) +CONST (1) +CONST (2) +CONST (3) +CONST (4) +CONST (5) +SEXP ("A", 5) +CONST (4) +ELEM +CALL ("Lwrite", 1, false) +SLABEL ("L2") +END diff --git a/byterun/xmake.lua b/byterun/xmake.lua new file mode 100644 index 000000000..437b8814c --- /dev/null +++ b/byterun/xmake.lua @@ -0,0 +1,14 @@ +-- add_rules("mode.debug", "mode.release") +-- add_rules("c++.unity_build") + +set_languages("c++20", "c20") + +target("byterun") + set_kind("binary") + add_includedirs("include") + add_files("../runtime/runtime.a") + add_files("src/**.cpp", "src/**.c") + remove_files("src/compiler.cpp") + set_warnings("allextra") + set_rundir("$(projectdir)") +