🔥 add check for imported files' quantity

This commit is contained in:
ValKmjolnir 2024-05-12 23:29:48 +08:00
parent 96731d180f
commit a11e0726bb
8 changed files with 52 additions and 37 deletions

View File

@ -6,7 +6,7 @@ endif
ifeq ($(OS), Darwin)
CXXFLAGS = -std=$(STD) -c -O3 -fPIC -mmacosx-version-min=10.15 -I src
else
CXXFLAGS = -std=$(STD) -c -O3 -fPIC -I src -Wconversion -Wno-float-conversion
CXXFLAGS = -std=$(STD) -c -O3 -fPIC -I src
endif
NASAL_HEADER = \

View File

@ -95,7 +95,7 @@ std::ostream& logo(std::ostream& out) {
}
std::ostream& version(std::ostream& out) {
std::srand(static_cast<u16>(std::time(nullptr)));
std::srand(static_cast<u32>(std::time(nullptr)));
f64 num = 0;
for(u32 i = 0; i<5; ++i) {
@ -152,7 +152,7 @@ void execute(const std::string& file,
}
// optimizer does simple optimization on ast
auto opt = std::unique_ptr<nasal::optimizer>(new nasal::optimizer);
auto opt = std::make_unique<nasal::optimizer>();
opt->do_optimization(parse.tree());
if (cmd&VM_AST) {
nasal::ast_dumper().dump(parse.tree());
@ -170,10 +170,10 @@ void execute(const std::string& file,
// run
const auto start = clk::now();
if (cmd&VM_DEBUG) {
auto debugger = std::unique_ptr<nasal::dbg>(new nasal::dbg);
auto debugger = std::make_unique<nasal::dbg>();
debugger->run(gen, ld, argv, cmd&VM_PROFILE, cmd&VM_PROF_ALL);
} else if (cmd&VM_TIME || cmd&VM_EXEC) {
auto runtime = std::unique_ptr<nasal::vm>(new nasal::vm);
auto runtime = std::make_unique<nasal::vm>();
runtime->set_detail_report_info(cmd&VM_DETAIL);
runtime->set_limit_mode_flag(cmd&VM_LIMIT);
runtime->run(gen, ld, argv);
@ -202,7 +202,7 @@ i32 main(i32 argc, const char* argv[]) {
} else if (s=="-v" || s=="--version") {
std::clog << version;
} else if (s=="-r" || s=="--repl") {
auto repl = std::unique_ptr<nasal::repl::repl>(new nasal::repl::repl);
auto repl = std::make_unique<nasal::repl::repl>();
repl->execute();
} else if (s[0]!='-') {
execute(s, {}, VM_EXEC);

View File

@ -87,7 +87,7 @@ void codegen::regist_string(const std::string& str) {
}
void codegen::find_symbol(code_block* node) {
auto finder = std::unique_ptr<symbol_finder>(new symbol_finder);
auto finder = std::make_unique<symbol_finder>();
for(const auto& i : finder->do_find(node)) {
// check if symbol conflicts with native function name
if (native_function_mapper.count(i.name)) {
@ -95,11 +95,11 @@ void codegen::find_symbol(code_block* node) {
continue;
}
// create new namespace with checking existence of location file
if (!experimental_namespace.count(i.location.file)) {
experimental_namespace[i.location.file] = {};
if (!nasal_namespace.count(i.location.file)) {
nasal_namespace[i.location.file] = {};
}
// if in global scope, load global symbol into this namespace
auto& scope = experimental_namespace.at(i.location.file);
auto& scope = nasal_namespace.at(i.location.file);
if (local.empty() && !scope.count(i.name)) {
scope.insert(i.name);
}
@ -126,26 +126,30 @@ void codegen::regist_symbol(const std::string& name) {
local.back()[name] = index;
}
i32 codegen::local_symbol_find(const std::string& name) {
i64 codegen::local_symbol_find(const std::string& name) {
if (local.empty()) {
return -1;
}
return local.back().count(name)? local.back().at(name):-1;
}
i32 codegen::global_symbol_find(const std::string& name) {
i64 codegen::global_symbol_find(const std::string& name) {
return global.count(name)? global.at(name):-1;
}
i32 codegen::upvalue_symbol_find(const std::string& name) {
i64 codegen::upvalue_symbol_find(const std::string& name) {
// 32768 level 65536 upvalues
i32 index = -1;
// may cause some errors if local scope depth is too deep or
// local scope's symbol list size is greater than 65536,
// but we check the local size in codegen::func_gen
i64 index = -1;
usize size = local.size();
if (size<=1) {
return -1;
}
auto iter = local.begin();
for(u32 i = 0; i<size-1; ++i, ++iter) {
for(u64 i = 0; i<size-1; ++i, ++iter) {
if (iter->count(name)) {
index = ((i<<16)|(*iter).at(name));
}
@ -301,10 +305,14 @@ void codegen::func_gen(function* node) {
block_gen(block);
in_foreach_loop_level.pop_back();
// we must check the local scope symbol list size
// the local scope should not cause stack overflow
// and should not greater than upvalue's max size(65536)
code[lsize].num = local.back().size();
if (local.back().size()>=STACK_DEPTH) {
if (local.back().size()>=STACK_DEPTH || local.back().size()>=UINT16_MAX) {
die("too many local variants: " +
std::to_string(local.back().size()), block->get_location()
std::to_string(local.back().size()),
block->get_location()
);
}
local.pop_back();
@ -350,7 +358,7 @@ void codegen::call_identifier(identifier* node) {
return;
}
i32 index;
i64 index;
if ((index = local_symbol_find(name))>=0) {
emit(op_calll, index, node->get_location());
return;
@ -470,7 +478,7 @@ void codegen::mcall_identifier(identifier* node) {
return;
}
i32 index;
i64 index;
if ((index = local_symbol_find(name))>=0) {
emit(op_mcalll, index, node->get_location());
return;
@ -1428,7 +1436,7 @@ void codegen::print(std::ostream& out) {
}
void codegen::symbol_dump(std::ostream& out) const {
for(const auto& domain : experimental_namespace) {
for(const auto& domain : nasal_namespace) {
out << "<" << domain.first << ">\n";
for(const auto& i : domain.second) {
out << " 0x" << std::setw(4) << std::setfill('0');

View File

@ -89,7 +89,10 @@ private:
// symbol table
// global : max STACK_DEPTH-1 values
std::unordered_map<std::string, u64> global;
std::unordered_map<std::string, std::unordered_set<std::string>> experimental_namespace;
// nasal namespace
// stores all global symbols of each file
std::unordered_map<std::string, std::unordered_set<std::string>> nasal_namespace;
// local : max 32768 upvalues 65536 values
// but in fact local scope also has less than STACK_DEPTH value
@ -105,9 +108,9 @@ private:
void regist_string(const std::string&);
void find_symbol(code_block*);
void regist_symbol(const std::string&);
i32 local_symbol_find(const std::string&);
i32 global_symbol_find(const std::string&);
i32 upvalue_symbol_find(const std::string&);
i64 local_symbol_find(const std::string&);
i64 global_symbol_find(const std::string&);
i64 upvalue_symbol_find(const std::string&);
void emit(u8, u64, const span&);
@ -157,9 +160,6 @@ public:
const auto& natives() const {return native_function;}
const auto& codes() const {return code;}
const auto& globals() const {return global;}
const auto& get_experimental_namespace() const {
return experimental_namespace;
}
public:
codegen() = default;

View File

@ -113,7 +113,7 @@ u16 dbg::file_index(const std::string& filename) const {
return i;
}
}
return 65535;
return UINT16_MAX;
}
void dbg::err() {
@ -221,7 +221,7 @@ void dbg::interact() {
} else if (res.size()==3 &&
get_cmd_type(res[0])==cmd_kind::cmd_break_point) {
break_file_index = file_index(res[1]);
if (break_file_index==65535) {
if (break_file_index==UINT16_MAX) {
std::clog << "cannot find file named `" << res[1] << "`\n";
continue;
}

View File

@ -142,7 +142,7 @@ private:
bool next;
usize fsize;
u16 break_file_index;
u32 break_line;
u64 break_line;
error src;
private:

View File

@ -316,7 +316,7 @@ std::string linker::generate_module_name(const std::string& file_path) {
}
return_expr* linker::generate_module_return(code_block* block) {
auto finder = std::unique_ptr<symbol_finder>(new symbol_finder);
auto finder = std::make_unique<symbol_finder>();
auto result = new return_expr(block->get_location());
auto value = new hash_expr(block->get_location());
result->set_value(value);
@ -406,6 +406,13 @@ const error& linker::link(parse& parse, bool spath = false) {
merge_tree(library, parse.tree());
// swap tree root, and delete old root
delete parse.swap(library);
if (imported_files.size()>=UINT16_MAX) {
err.err("link",
"too many imported files: " +
std::to_string(imported_files.size())
);
}
return err;
}

View File

@ -37,7 +37,7 @@ void repl::update_temp_file() {
bool repl::check_need_more_input() {
while(true) {
update_temp_file();
auto nasal_lexer = std::unique_ptr<lexer>(new lexer);
auto nasal_lexer = std::make_unique<lexer>();
if (nasal_lexer->scan("<nasal-repl>").geterr()) {
return false;
}
@ -77,11 +77,11 @@ void repl::help() {
}
bool repl::run() {
auto nasal_lexer = std::unique_ptr<lexer>(new lexer);
auto nasal_parser = std::unique_ptr<parse>(new parse);
auto nasal_linker = std::unique_ptr<linker>(new linker);
auto nasal_opt = std::unique_ptr<optimizer>(new optimizer);
auto nasal_codegen = std::unique_ptr<codegen>(new codegen);
auto nasal_lexer = std::make_unique<lexer>();
auto nasal_parser = std::make_unique<parse>();
auto nasal_linker = std::make_unique<linker>();
auto nasal_opt = std::make_unique<optimizer>();
auto nasal_codegen = std::make_unique<codegen>();
update_temp_file();
if (nasal_lexer->scan("<nasal-repl>").geterr()) {