From 3ef8effe9ad84e56672f78d32f0ab5245e81ea97 Mon Sep 17 00:00:00 2001 From: ValKmjolnir Date: Sun, 23 Oct 2022 01:29:20 +0800 Subject: [PATCH] :fire: change `nasal_gc` to `gc` --- README.md | 18 ++++++++--------- doc/README_zh.md | 18 ++++++++--------- doc/dev.md | 12 ++++++------ doc/dev_zh.md | 8 ++++---- main.cpp | 8 +++----- nasal_gc.h | 51 +++++++++++++++++++++++++----------------------- nasal_import.h | 2 +- nasal_vm.h | 11 ++++++----- 8 files changed, 65 insertions(+), 63 deletions(-) diff --git a/README.md b/README.md index 66ad847..9e2daa5 100644 --- a/README.md +++ b/README.md @@ -490,7 +490,7 @@ nas_native(builtin_print); Then complete this function using C++: ```C++ -var builtin_print(var* local,nasal_gc& gc) +var builtin_print(var* local,gc& ngc) { // find value with index begin from 1 // because local[0] is reserved for value 'me' @@ -512,7 +512,7 @@ var builtin_print(var* local,nasal_gc& gc) } std::cout<& args,nasal_gc& gc){ +extern "C" var fib(std::vector& args,gc& ngc){ // the arguments are generated into a vm_vec: args // get values from the vector that must be used here var num=args[0]; @@ -627,7 +627,7 @@ extern "C" var fib(std::vector& args,nasal_gc& gc){ if(num.type!=vm_num) return nas_err("extern_fib","\"num\" must be number"); // ok, you must know that vm_num now is not managed by gc - // if want to return a gc object, use gc.alloc(type) + // if want to return a gc object, use ngc.alloc(type) // usage of gc is the same as adding a native function return {vm_num,fibonaci(num.tonum())}; } diff --git a/doc/README_zh.md b/doc/README_zh.md index 06dfd45..c012c0b 100644 --- a/doc/README_zh.md +++ b/doc/README_zh.md @@ -469,7 +469,7 @@ nas_native(builtin_print); 然后用C++完成这个函数的函数体: ```C++ -var builtin_print(var* local,nasal_gc& gc) +var builtin_print(var* local,gc& ngc) { // 局部变量的下标其实是从1开始的 // 因为local[0]是保留给'me'的空间 @@ -492,7 +492,7 @@ var builtin_print(var* local,nasal_gc& gc) } std::cout<& args,nasal_gc& gc){ +extern "C" var fib(std::vector& args,gc& ngc){ // 传参会被送到一个vm_vec类型中送过来,而不是上文中那种指针直接指向局部作用域 var num=args[0]; // 如果你想让这个函数有更强的稳定性,那么一定要进行合法性检查 @@ -600,7 +600,7 @@ extern "C" var fib(std::vector& args,nasal_gc& gc){ if(num.type!=vm_num) return nas_err("extern_fib","\"num\" must be number"); // vm_num作为普通的数字类型,不是内存管理的对象,所以无需申请 - // 如果需要返回内存管理的对象,请使用gc.alloc(type) + // 如果需要返回内存管理的对象,请使用ngc.alloc(type) return {vm_num,fibonaci(num.tonum())}; } ``` diff --git a/doc/dev.md b/doc/dev.md index 8acb0d9..ecb087c 100644 --- a/doc/dev.md +++ b/doc/dev.md @@ -59,7 +59,7 @@ var f=func(x,y,z){return x+y+z}; ### version 1.0 parser (last update 2019/10/14) -First fully functional version of nasal_parser. +First fully functional version of parser. Before version 1.0,i tried many times to create a correct parser. @@ -266,8 +266,8 @@ parser will check this left-value and tells that these kinds of left-value are n But now it can work. And you could see its use by reading the code above. To make sure this assignment works correctly, -codegen will generate byte code by `nasal_codegen::call_gen()` instead of `nasal_codegen::mcall_gen()`, -and the last child of the ast will be generated by `nasal_codegen::mcall_gen()`. +codegen will generate byte code by `codegen::call_gen()` instead of `codegen::mcall_gen()`, +and the last child of the ast will be generated by `codegen::mcall_gen()`. So the bytecode is totally different now: ```x86asm @@ -357,7 +357,7 @@ This version uses g++ extension "labels as values", which is also supported by clang++. (But i don't know if MSVC supports this) -There is also a change in nasal_gc: +There is also a change in `gc`: `std::vector` global is deleted, now the global values are all stored on stack(from `val_stack+0` to `val_stack+intg-1`). @@ -415,7 +415,7 @@ a=b=0; 2021/10/8 update: -In this version vm_nil and vm_num now is not managed by `nasal_gc`, +In this version vm_nil and vm_num now is not managed by `gc`, this will decrease the usage of `gc::alloc` and increase the efficiency of execution. New value type is added: `vm_obj`. @@ -471,7 +471,7 @@ Both of them are meaningless and will be replaced by `op_pnum`. Local values now are __stored on stack__. So function calling will be faster than before. Because in v8.0 when calling a function, -new `vm_vec` will be allocated by `nasal_gc`, this makes gc doing mark-sweep too many times and spends a quite lot of time. +new `vm_vec` will be allocated by `gc`, this makes gc doing mark-sweep too many times and spends a quite lot of time. In test file `test/bf.nas`, it takes too much time to test the file because this file has too many function calls(see test data below in table `version 8.0 (R9-5900HX ubuntu-WSL 2022/1/23)`). Upvalue now is generated when creating first new function in the local scope, using `vm_vec`. diff --git a/doc/dev_zh.md b/doc/dev_zh.md index df00bad..da245af 100644 --- a/doc/dev_zh.md +++ b/doc/dev_zh.md @@ -238,7 +238,7 @@ m(0)._=m(1)._=10; [0,1,2][1:2][0]=0; ``` -在老版本中,语法分析器会检查左值,并且在检测到有特别调用的情况下直接告知用户这种左值是不被接受的(bad lvalue)。但是现在它可以正常运作了。为了保证这种赋值语句能正常执行,codegen模块会优先使用`nasal_codegen::call_gen()`生成前面调用链的字节码而不是全部使用 `nasal_codegen::mcall_gen()`,在最后一个调用处才会使用`nasal_codegen::mcall_gen()`。 +在老版本中,语法分析器会检查左值,并且在检测到有特别调用的情况下直接告知用户这种左值是不被接受的(bad lvalue)。但是现在它可以正常运作了。为了保证这种赋值语句能正常执行,codegen模块会优先使用`codegen::call_gen()`生成前面调用链的字节码而不是全部使用 `codegen::mcall_gen()`,在最后一个调用处才会使用`codegen::mcall_gen()`。 所以现在生成的相关字节码也完全不同了: @@ -311,11 +311,11 @@ m(0)._=m(1)._=10; 2021/6/26 update: -指令分派方式从call-threading改为了computed-goto。在更改了指令分派方式之后,nasal_vm的执行效率有了非常巨大的提升。现在虚拟机可以在0.2秒内执行完test/bigloop和test/pi!并且在linux平台虚拟机可以在0.8秒内执行完test/fib。你可以在下面的测试数据部分看到测试的结果。 +指令分派方式从call-threading改为了computed-goto。在更改了指令分派方式之后,`vm`的执行效率有了非常巨大的提升。现在虚拟机可以在0.2秒内执行完`test/bigloop`和`test/pi`!并且在linux平台虚拟机可以在0.8秒内执行完`test/fib`。你可以在下面的测试数据部分看到测试的结果。 这个分派方式使用了g++扩展"labels as values",clang++目前也支持这种指令分派的实现方式。(不过MSVC支不支持就不得而知了,哈哈) -nasal_gc中也有部分改动: +`gc`中也有部分改动: 全局变量不再用`std::vector`存储,而是全部存在操作数栈上(从`val_stack+0`到`val_stack+intg-1`)。 2021/6/29 update: @@ -369,7 +369,7 @@ a=b=0; 2021/10/8 update: -从这个版本开始`vm_nil`和`vm_num`不再由`nasal_gc`管理,这会大幅度降低`gc::alloc`的调用并且会大幅度提升执行效率。 +从这个版本开始`vm_nil`和`vm_num`不再由`gc`管理,这会大幅度降低`gc::alloc`的调用并且会大幅度提升执行效率。 添加了新的数据类型: `vm_obj`。这个类型是留给用户定义他们想要的数据类型的。相关的API会在未来加入。 diff --git a/main.cpp b/main.cpp index bea7ad7..f4bb8a4 100644 --- a/main.cpp +++ b/main.cpp @@ -82,14 +82,12 @@ void err() void execute(const string& file,const std::vector& argv,const u32 cmd) { - // front end use the same error module error err; lexer lex(err); parse parse(err); linker ld(err); codegen gen(err); - // back end - vm rt; + vm ctx; // lexer scans file to get tokens lex.scan(file); @@ -117,12 +115,12 @@ void execute(const string& file,const std::vector& argv,const u32 cmd) else if(cmd&VM_TIME) { auto start=std::chrono::high_resolution_clock::now(); - rt.run(gen,ld,argv,cmd&VM_DETAIL); + ctx.run(gen,ld,argv,cmd&VM_DETAIL); auto end=std::chrono::high_resolution_clock::now(); std::clog<<"process exited after "<<(end-start).count()*1.0/std::chrono::high_resolution_clock::duration::period::den<<"s.\n"; } else if(cmd&VM_EXEC) - rt.run(gen,ld,argv,cmd&VM_DETAIL); + ctx.run(gen,ld,argv,cmd&VM_DETAIL); } i32 main(i32 argc,const char* argv[]) diff --git a/nasal_gc.h b/nasal_gc.h index 857ad9c..3fa21d6 100644 --- a/nasal_gc.h +++ b/nasal_gc.h @@ -1,6 +1,7 @@ #ifndef __NASAL_GC_H__ #define __NASAL_GC_H__ +#include #include #include @@ -252,6 +253,7 @@ struct nas_val nas_val(u8); ~nas_val(); + void clear(); }; var nas_vec::get_val(const i32 n) @@ -376,6 +378,19 @@ nas_val::~nas_val() } type=vm_nil; } +void nas_val::clear() +{ + switch(type) + { + case vm_str: ptr.str->clear(); break; + case vm_vec: ptr.vec->elems.clear(); break; + case vm_hash: ptr.hash->elems.clear();break; + case vm_func: ptr.func->clear(); break; + case vm_upval:ptr.upval->clear(); break; + case vm_obj: ptr.obj->clear(); break; + case vm_co: ptr.co->clear(); break; + } +} f64 var::tonum() { return type!=vm_str?val.num:str2num(str().c_str()); @@ -457,20 +472,17 @@ struct gc var temp; // temporary place used in builtin/module functions /* constants and memory pool */ - std::vector strs; // reserved address for const vm_str - std::vector env_argv; // command line arguments - std::vector memory; // gc memory - std::queue unused[gc_tsize]; // gc free list + std::vector strs; // reserved address for const vm_str + std::vector env_argv; // command line arguments + std::vector memory; // gc memory + std::queue unused[gc_tsize]; // gc free list /* values for analysis */ u64 size[gc_tsize]; u64 count[gc_tsize]; - u64 allocc[gc_tsize]; - gc( - u32& _pc, var*& _localr, - var*& _memr, var& _funcr, - var& _upvalr, var*& _canary, - var*& _top, var* _stk): + u64 acnt[gc_tsize]; + gc(u32& _pc, var*& _localr, var*& _memr, var& _funcr, + var& _upvalr, var*& _canary, var*& _top, var* _stk): pc(_pc),localr(_localr),memr(_memr),funcr(_funcr),upvalr(_upvalr), canary(_canary),top(_top),stack(_stk),cort(nullptr),temp(nil){} void mark(); @@ -548,16 +560,7 @@ void gc::sweep() { if(i->mark==GC_UNCOLLECTED) { - switch(i->type) - { - case vm_str: i->ptr.str->clear(); break; - case vm_vec: i->ptr.vec->elems.clear(); break; - case vm_hash: i->ptr.hash->elems.clear();break; - case vm_func: i->ptr.func->clear(); break; - case vm_upval:i->ptr.upval->clear(); break; - case vm_obj: i->ptr.obj->clear(); break; - case vm_co: i->ptr.co->clear(); break; - } + i->clear(); unused[i->type-vm_str].push(i); i->mark=GC_COLLECTED; } @@ -571,7 +574,7 @@ void gc::init(const std::vector& s,const std::vector& argv) funcr=nil; for(u8 i=0;i& filelist() const {return files;} }; -linker::linker(error& e):lib_loaded(false),err(e){ +linker::linker(error& e):show_path(false),lib_loaded(false),err(e){ #ifdef _WIN32 char sep=';'; #else diff --git a/nasal_vm.h b/nasal_vm.h index 44f7973..ecbeee0 100644 --- a/nasal_vm.h +++ b/nasal_vm.h @@ -125,11 +125,12 @@ protected: void o_mcallh(); void o_ret(); public: - vm():pc(0),localr(nullptr),memr(nullptr),funcr(nil), - upvalr(nil),canary(nullptr),top(stack), - num_table(nullptr),str_table(nullptr), - ngc(pc,localr,memr,funcr,upvalr,canary,top,stack), - files(nullptr),bytecode(nullptr),detail_info(false){} + vm(): + pc(0),localr(nullptr),memr(nullptr),funcr(nil), + upvalr(nil),canary(nullptr),top(stack), + num_table(nullptr),str_table(nullptr), + ngc(pc,localr,memr,funcr,upvalr,canary,top,stack), + files(nullptr),bytecode(nullptr),detail_info(false){} void run( const codegen&, const linker&,