finish basic function of repl

This commit is contained in:
ValKmjolnir 2023-09-17 17:56:59 +08:00
parent b77d7fafb1
commit 3e01239722
8 changed files with 63 additions and 32 deletions

View File

@ -154,7 +154,8 @@ void execute(
debugger->run(gen, ld, argv, cmd&VM_PROFILE, cmd&VM_PROF_ALL); debugger->run(gen, ld, argv, cmd&VM_PROFILE, cmd&VM_PROF_ALL);
} else if (cmd&VM_TIME || cmd&VM_EXEC) { } else if (cmd&VM_TIME || cmd&VM_EXEC) {
auto runtime = std::unique_ptr<nasal::vm>(new nasal::vm); auto runtime = std::unique_ptr<nasal::vm>(new nasal::vm);
runtime->run(gen, ld, argv, cmd&VM_DETAIL); runtime->set_detail_report_info(cmd&VM_DETAIL);
runtime->run(gen, ld, argv);
} }
// get running time // get running time

View File

@ -237,7 +237,8 @@ void dbg::run(
const std::vector<std::string>& argv, const std::vector<std::string>& argv,
bool profile, bool profile,
bool show_all_prof_result) { bool show_all_prof_result) {
verbose = true;
set_detail_report_info(true);
do_profiling = profile || show_all_prof_result; do_profiling = profile || show_all_prof_result;
const auto& file_list = linker.get_file_list(); const auto& file_list = linker.get_file_list();

View File

@ -537,11 +537,8 @@ void gc::extend(u8 type) {
void gc::init( void gc::init(
const std::vector<std::string>& s, const std::vector<std::string>& argv) { const std::vector<std::string>& s, const std::vector<std::string>& argv) {
// initialize function register
rctx->funcr = nil;
worktime = 0;
// initialize counters // initialize counters
worktime = 0;
for(u8 i = 0; i<gc_type_size; ++i) { for(u8 i = 0; i<gc_type_size; ++i) {
size[i] = gcnt[i] = acnt[i] = 0; size[i] = gcnt[i] = acnt[i] = 0;
} }

View File

@ -300,9 +300,9 @@ struct gc {
var temp = nil; var temp = nil;
/* constants and memory pool */ /* constants and memory pool */
std::vector<var> strs; // reserved address for const vm_str std::vector<var> strs = {}; // reserved address for const vm_str
std::vector<var> env_argv; // command line arguments std::vector<var> env_argv = {}; // command line arguments
std::vector<nas_val*> memory; // gc memory std::vector<nas_val*> memory; // gc memory
std::vector<nas_val*> unused[gc_type_size]; // gc free list std::vector<nas_val*> unused[gc_type_size]; // gc free list
/* heap increase size */ /* heap increase size */

View File

@ -20,19 +20,10 @@ void vm::init(
/* set native functions */ /* set native functions */
native = natives; native = natives;
/* set canary and program counter */ /* set context and global */
ctx.pc = 0; if (!is_repl_mode || first_exec_flag) {
ctx.localr = nullptr; context_and_global_init();
ctx.memr = nullptr; first_exec_flag = false;
ctx.funcr = nil;
ctx.upvalr = nil;
ctx.canary = ctx.stack+STACK_DEPTH-1; // stack[STACK_DEPTH-1]
ctx.top = ctx.stack; // nothing is on stack
/* clear main stack and global */
for(u32 i = 0; i<STACK_DEPTH; ++i) {
ctx.stack[i] = nil;
global[i] = nil;
} }
/* init gc */ /* init gc */
@ -52,6 +43,27 @@ void vm::init(
arg_instance.vec().elems = ngc.env_argv; arg_instance.vec().elems = ngc.env_argv;
} }
void vm::context_and_global_init() {
/* set canary and program counter */
ctx.pc = 0;
ctx.localr = nullptr;
ctx.memr = nullptr;
ctx.funcr = nil;
ctx.upvalr = nil;
/* set canary = stack[STACK_DEPTH-1] */
ctx.canary = ctx.stack+STACK_DEPTH-1;
/* nothing is on stack */
ctx.top = ctx.stack;
/* clear main stack and global */
for(u32 i = 0; i<STACK_DEPTH; ++i) {
ctx.stack[i] = nil;
global[i] = nil;
}
}
void vm::valinfo(var& val) { void vm::valinfo(var& val) {
const auto p = reinterpret_cast<u64>(val.val.gcobj); const auto p = reinterpret_cast<u64>(val.val.gcobj);
switch(val.type) { switch(val.type) {
@ -240,9 +252,8 @@ void vm::die(const std::string& str) {
void vm::run( void vm::run(
const codegen& gen, const codegen& gen,
const linker& linker, const linker& linker,
const std::vector<std::string>& argv, const std::vector<std::string>& argv
const bool detail) { ) {
verbose = detail;
init(gen.strs(), gen.nums(), gen.natives(), init(gen.strs(), gen.nums(), gen.natives(),
gen.codes(), gen.globals(), linker.get_file_list(), argv); gen.codes(), gen.globals(), linker.get_file_list(), argv);
#ifndef _MSC_VER #ifndef _MSC_VER
@ -341,11 +352,13 @@ void vm::run(
#endif #endif
vmexit: vmexit:
if (detail) { if (verbose) {
ngc.info(); ngc.info();
} }
ngc.clear();
imm.clear(); imm.clear();
if (!is_repl_mode) {
ngc.clear();
}
return; return;
#ifndef _MSC_VER #ifndef _MSC_VER

View File

@ -38,6 +38,10 @@ protected:
const std::string* files = nullptr; // file name list const std::string* files = nullptr; // file name list
const opcode* bytecode = nullptr; // bytecode buffer address const opcode* bytecode = nullptr; // bytecode buffer address
/* variables for repl mode */
bool is_repl_mode = false;
bool first_exec_flag = true;
/* vm initializing function */ /* vm initializing function */
void init( void init(
const std::vector<std::string>&, const std::vector<std::string>&,
@ -46,7 +50,9 @@ protected:
const std::vector<opcode>&, const std::vector<opcode>&,
const std::unordered_map<std::string, i32>&, const std::unordered_map<std::string, i32>&,
const std::vector<std::string>&, const std::vector<std::string>&,
const std::vector<std::string>&); const std::vector<std::string>&
);
void context_and_global_init();
/* debug functions */ /* debug functions */
bool verbose = false; bool verbose = false;
@ -167,8 +173,13 @@ public:
void run( void run(
const codegen&, const codegen&,
const linker&, const linker&,
const std::vector<std::string>&, const std::vector<std::string>&
const bool); );
/* set detail report info flag */
void set_detail_report_info(bool flag) {verbose = flag;}
/* set repl mode flag */
void set_repl_mode_flag(bool flag) {is_repl_mode = flag;}
}; };
inline bool vm::cond(var& val) { inline bool vm::cond(var& val) {

View File

@ -75,7 +75,6 @@ bool repl::run() {
auto nasal_linker = std::unique_ptr<linker>(new linker); auto nasal_linker = std::unique_ptr<linker>(new linker);
auto nasal_opt = std::unique_ptr<optimizer>(new optimizer); auto nasal_opt = std::unique_ptr<optimizer>(new optimizer);
auto nasal_codegen = std::unique_ptr<codegen>(new codegen); auto nasal_codegen = std::unique_ptr<codegen>(new codegen);
auto nasal_runtime = std::unique_ptr<vm>(new vm);
if (nasal_lexer->scan("<nasal-repl>").geterr()) { if (nasal_lexer->scan("<nasal-repl>").geterr()) {
return false; return false;
@ -96,7 +95,11 @@ bool repl::run() {
auto end = clk::now(); auto end = clk::now();
std::clog << "[compile time: " << (end-start).count()*1000.0/den << " ms]\n"; std::clog << "[compile time: " << (end-start).count()*1000.0/den << " ms]\n";
nasal_runtime->run(*nasal_codegen, *nasal_linker, {}, false); runtime->set_detail_report_info(false);
// TODO: gc init stage in this run may cause memory leak,
// because constant strings will be generated again.
// but we could not delete old strings, they maybe still on stack.
runtime->run(*nasal_codegen, *nasal_linker, {});
return true; return true;
} }

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include "nasal.h" #include "nasal.h"
#include "nasal_vm.h"
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
@ -26,6 +27,7 @@ struct info {
class repl { class repl {
private: private:
std::vector<std::string> source; std::vector<std::string> source;
std::unique_ptr<vm> runtime;
private: private:
std::string readline(std::string); std::string readline(std::string);
@ -35,6 +37,9 @@ private:
bool run(); bool run();
public: public:
repl(): runtime(std::unique_ptr<vm>(new vm)) {
runtime->set_repl_mode_flag(true);
}
void execute(); void execute();
}; };