✨ update
This commit is contained in:
parent
4b597000ba
commit
d9cf9ff49e
|
@ -1133,7 +1133,7 @@ var builtin_cocreate(var* local, gc& ngc) {
|
||||||
cort.ctx.top[0] = var::ret(0); // old pc, set to zero to make op_ret recognizing this as coroutine function
|
cort.ctx.top[0] = var::ret(0); // old pc, set to zero to make op_ret recognizing this as coroutine function
|
||||||
|
|
||||||
cort.ctx.funcr = func; // make sure the coroutine function can use correct upvalues
|
cort.ctx.funcr = func; // make sure the coroutine function can use correct upvalues
|
||||||
cort.status = coroutine_status::suspended;
|
cort.status = nas_co::status::suspended;
|
||||||
|
|
||||||
return co;
|
return co;
|
||||||
}
|
}
|
||||||
|
@ -1148,7 +1148,7 @@ var builtin_coresume(var* local, gc& ngc) {
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
// cannot resume a dead coroutine
|
// cannot resume a dead coroutine
|
||||||
if (co.co().status==coroutine_status::dead) {
|
if (co.co().status==nas_co::status::dead) {
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1193,9 +1193,9 @@ var builtin_costatus(var* local, gc& ngc) {
|
||||||
return ngc.newstr("error");
|
return ngc.newstr("error");
|
||||||
}
|
}
|
||||||
switch(co.co().status) {
|
switch(co.co().status) {
|
||||||
case coroutine_status::suspended: return ngc.newstr("suspended");
|
case nas_co::status::suspended: return ngc.newstr("suspended");
|
||||||
case coroutine_status::running: return ngc.newstr("running");
|
case nas_co::status::running: return ngc.newstr("running");
|
||||||
case coroutine_status::dead: return ngc.newstr("dead");
|
case nas_co::status::dead: return ngc.newstr("dead");
|
||||||
}
|
}
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
|
@ -156,7 +156,7 @@ void nas_co::clear() {
|
||||||
ctx.upvalr = var::nil();
|
ctx.upvalr = var::nil();
|
||||||
ctx.stack = stack;
|
ctx.stack = stack;
|
||||||
|
|
||||||
status = coroutine_status::suspended;
|
status = status::suspended;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& out, const nas_co& co) {
|
std::ostream& operator<<(std::ostream& out, const nas_co& co) {
|
||||||
|
@ -385,7 +385,7 @@ void gc::mark() {
|
||||||
var value = bfs.back();
|
var value = bfs.back();
|
||||||
bfs.pop_back();
|
bfs.pop_back();
|
||||||
if (value.type<=vm_num ||
|
if (value.type<=vm_num ||
|
||||||
value.val.gcobj->mark!=gc_status::uncollected) {
|
value.val.gcobj->mark!=nas_val::gc_status::uncollected) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
mark_var(bfs, value);
|
mark_var(bfs, value);
|
||||||
|
@ -397,7 +397,7 @@ void gc::concurrent_mark(std::vector<var>& vec, usize begin, usize end) {
|
||||||
for(auto i = begin; i<end; ++i) {
|
for(auto i = begin; i<end; ++i) {
|
||||||
var value = vec[i];
|
var value = vec[i];
|
||||||
if (value.type<=vm_num ||
|
if (value.type<=vm_num ||
|
||||||
value.val.gcobj->mark!=gc_status::uncollected) {
|
value.val.gcobj->mark!=nas_val::gc_status::uncollected) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
mark_var(bfs, value);
|
mark_var(bfs, value);
|
||||||
|
@ -406,7 +406,7 @@ void gc::concurrent_mark(std::vector<var>& vec, usize begin, usize end) {
|
||||||
var value = bfs.back();
|
var value = bfs.back();
|
||||||
bfs.pop_back();
|
bfs.pop_back();
|
||||||
if (value.type<=vm_num ||
|
if (value.type<=vm_num ||
|
||||||
value.val.gcobj->mark!=gc_status::uncollected) {
|
value.val.gcobj->mark!=nas_val::gc_status::uncollected) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
mark_var(bfs, value);
|
mark_var(bfs, value);
|
||||||
|
@ -440,7 +440,7 @@ void gc::mark_context_root(std::vector<var>& bfs_queue) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void gc::mark_var(std::vector<var>& bfs_queue, var& value) {
|
void gc::mark_var(std::vector<var>& bfs_queue, var& value) {
|
||||||
value.val.gcobj->mark = gc_status::found;
|
value.val.gcobj->mark = nas_val::gc_status::found;
|
||||||
switch(value.type) {
|
switch(value.type) {
|
||||||
case vm_vec: mark_vec(bfs_queue, value.vec()); break;
|
case vm_vec: mark_vec(bfs_queue, value.vec()); break;
|
||||||
case vm_hash: mark_hash(bfs_queue, value.hash()); break;
|
case vm_hash: mark_hash(bfs_queue, value.hash()); break;
|
||||||
|
@ -507,12 +507,12 @@ void gc::mark_map(std::vector<var>& bfs_queue, nas_map& mp) {
|
||||||
|
|
||||||
void gc::sweep() {
|
void gc::sweep() {
|
||||||
for(auto i : memory) {
|
for(auto i : memory) {
|
||||||
if (i->mark==gc_status::uncollected) {
|
if (i->mark==nas_val::gc_status::uncollected) {
|
||||||
i->clear();
|
i->clear();
|
||||||
unused[i->type-vm_str].push_back(i);
|
unused[i->type-vm_str].push_back(i);
|
||||||
i->mark = gc_status::collected;
|
i->mark = nas_val::gc_status::collected;
|
||||||
} else if (i->mark==gc_status::found) {
|
} else if (i->mark==nas_val::gc_status::found) {
|
||||||
i->mark = gc_status::uncollected;
|
i->mark = nas_val::gc_status::uncollected;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -680,7 +680,7 @@ var gc::alloc(u8 type) {
|
||||||
extend(type);
|
extend(type);
|
||||||
}
|
}
|
||||||
var ret = var::gcobj(unused[index].back());
|
var ret = var::gcobj(unused[index].back());
|
||||||
ret.val.gcobj->mark = gc_status::uncollected;
|
ret.val.gcobj->mark = nas_val::gc_status::uncollected;
|
||||||
unused[index].pop_back();
|
unused[index].pop_back();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -696,14 +696,14 @@ void gc::ctxchg(nas_co& co) {
|
||||||
cort = &co;
|
cort = &co;
|
||||||
|
|
||||||
// set coroutine state to running
|
// set coroutine state to running
|
||||||
cort->status = coroutine_status::running;
|
cort->status = nas_co::status::running;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gc::ctxreserve() {
|
void gc::ctxreserve() {
|
||||||
// pc=0 means this coroutine is finished
|
// pc=0 means this coroutine is finished
|
||||||
cort->status = rctx->pc?
|
cort->status = rctx->pc?
|
||||||
coroutine_status::suspended:
|
nas_co::status::suspended:
|
||||||
coroutine_status::dead;
|
nas_co::status::dead;
|
||||||
|
|
||||||
// store running state to coroutine
|
// store running state to coroutine
|
||||||
cort->ctx = *rctx;
|
cort->ctx = *rctx;
|
||||||
|
|
|
@ -53,18 +53,6 @@ enum vm_type:u8 {
|
||||||
|
|
||||||
const u32 gc_type_size = vm_map-vm_str+1;
|
const u32 gc_type_size = vm_map-vm_str+1;
|
||||||
|
|
||||||
enum class coroutine_status:u32 {
|
|
||||||
suspended,
|
|
||||||
running,
|
|
||||||
dead
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class gc_status:u8 {
|
|
||||||
uncollected=0,
|
|
||||||
collected,
|
|
||||||
found
|
|
||||||
};
|
|
||||||
|
|
||||||
struct nas_vec; // vector
|
struct nas_vec; // vector
|
||||||
struct nas_hash; // hashmap(dict)
|
struct nas_hash; // hashmap(dict)
|
||||||
struct nas_func; // function(lambda)
|
struct nas_func; // function(lambda)
|
||||||
|
@ -283,9 +271,15 @@ struct context {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct nas_co {
|
struct nas_co {
|
||||||
|
enum class status:u32 {
|
||||||
|
suspended,
|
||||||
|
running,
|
||||||
|
dead
|
||||||
|
};
|
||||||
|
|
||||||
var stack[STACK_DEPTH];
|
var stack[STACK_DEPTH];
|
||||||
context ctx;
|
context ctx;
|
||||||
coroutine_status status;
|
status status;
|
||||||
|
|
||||||
nas_co() {clear();}
|
nas_co() {clear();}
|
||||||
void clear();
|
void clear();
|
||||||
|
@ -305,6 +299,12 @@ struct nas_map {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct nas_val {
|
struct nas_val {
|
||||||
|
enum class gc_status:u8 {
|
||||||
|
uncollected = 0,
|
||||||
|
collected,
|
||||||
|
found
|
||||||
|
};
|
||||||
|
|
||||||
gc_status mark;
|
gc_status mark;
|
||||||
u8 type; // value type
|
u8 type; // value type
|
||||||
u8 unmut; // used to mark if a string is unmutable
|
u8 unmut; // used to mark if a string is unmutable
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#include "nasal_import.h"
|
#include "nasal_import.h"
|
||||||
|
|
||||||
linker::linker(): show_path(false), lib_loaded(false) {
|
linker::linker():
|
||||||
|
show_path(false), lib_loaded(false),
|
||||||
|
this_file(""), lib_path("") {
|
||||||
char sep = is_windows()? ';':':';
|
char sep = is_windows()? ';':':';
|
||||||
std::string PATH = getenv("PATH");
|
std::string PATH = getenv("PATH");
|
||||||
usize last = 0, pos = PATH.find(sep, 0);
|
usize last = 0, pos = PATH.find(sep, 0);
|
||||||
|
@ -181,6 +183,7 @@ code_block* linker::import_nasal_lib() {
|
||||||
if (!filename.length()) {
|
if (!filename.length()) {
|
||||||
return new code_block({0, 0, 0, 0, filename});
|
return new code_block({0, 0, 0, 0, filename});
|
||||||
}
|
}
|
||||||
|
lib_path = filename;
|
||||||
|
|
||||||
// avoid infinite loading loop
|
// avoid infinite loading loop
|
||||||
if (exist(filename)) {
|
if (exist(filename)) {
|
||||||
|
@ -228,6 +231,7 @@ const error& linker::link(
|
||||||
parse& parse, const std::string& self, bool spath = false) {
|
parse& parse, const std::string& self, bool spath = false) {
|
||||||
show_path = spath;
|
show_path = spath;
|
||||||
// initializing
|
// initializing
|
||||||
|
this_file = self;
|
||||||
files = {self};
|
files = {self};
|
||||||
// scan root and import files
|
// scan root and import files
|
||||||
// then generate a new ast and return to import_ast
|
// then generate a new ast and return to import_ast
|
||||||
|
@ -235,5 +239,10 @@ const error& linker::link(
|
||||||
auto new_tree_root = load(parse.tree(), 0);
|
auto new_tree_root = load(parse.tree(), 0);
|
||||||
auto old_tree_root = parse.swap(new_tree_root);
|
auto old_tree_root = parse.swap(new_tree_root);
|
||||||
delete old_tree_root;
|
delete old_tree_root;
|
||||||
|
if (show_path) {
|
||||||
|
std::clog << orange << "Linker Info" << reset << ":\n";
|
||||||
|
std::clog << " compiled file: <" << this_file << ">\n";
|
||||||
|
std::clog << " library path : <" << lib_path << ">\n\n";
|
||||||
|
}
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,8 @@ class linker{
|
||||||
private:
|
private:
|
||||||
bool show_path;
|
bool show_path;
|
||||||
bool lib_loaded;
|
bool lib_loaded;
|
||||||
|
std::string this_file;
|
||||||
|
std::string lib_path;
|
||||||
error err;
|
error err;
|
||||||
std::vector<std::string> files;
|
std::vector<std::string> files;
|
||||||
std::vector<std::string> envpath;
|
std::vector<std::string> envpath;
|
||||||
|
|
Loading…
Reference in New Issue