🔥 add check for imported files' quantity
This commit is contained in:
parent
96731d180f
commit
a11e0726bb
2
makefile
2
makefile
|
@ -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 = \
|
||||
|
|
10
src/main.cpp
10
src/main.cpp
|
@ -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);
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -142,7 +142,7 @@ private:
|
|||
bool next;
|
||||
usize fsize;
|
||||
u16 break_file_index;
|
||||
u32 break_line;
|
||||
u64 break_line;
|
||||
error src;
|
||||
|
||||
private:
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
12
src/repl.cpp
12
src/repl.cpp
|
@ -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()) {
|
||||
|
|
Loading…
Reference in New Issue