fix bug in codegen: foreach/forindex(id;vec/hash) may cause segmentation fault because of incorrect generated operand
This commit is contained in:
parent
ca073499ae
commit
fc25dd69e1
5
main.cpp
5
main.cpp
|
@ -14,7 +14,7 @@ void help()
|
||||||
{
|
{
|
||||||
std::cout
|
std::cout
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
<<"use command \'chcp 65001\' if want to use unicode.\n"
|
<<"use command <chcp 65001> if want to use unicode.\n"
|
||||||
#endif
|
#endif
|
||||||
<<"nasal <option>\n"
|
<<"nasal <option>\n"
|
||||||
<<"option:\n"
|
<<"option:\n"
|
||||||
|
@ -48,7 +48,8 @@ void logo()
|
||||||
<<" / \\/ / _` / __|/ _` | | \n"
|
<<" / \\/ / _` / __|/ _` | | \n"
|
||||||
<<" / /\\ / (_| \\__ \\ (_| | | \n"
|
<<" / /\\ / (_| \\__ \\ (_| | | \n"
|
||||||
<<" \\_\\ \\/ \\__,_|___/\\__,_|_|\n"
|
<<" \\_\\ \\/ \\__,_|___/\\__,_|_|\n"
|
||||||
<<"nasal interpreter ver 9.0\n"
|
<<"nasal ver : "<<__nasver<<"\n"
|
||||||
|
<<"c++ std : "<<__cplusplus<<"\n"
|
||||||
<<"thanks to : https://github.com/andyross/nasal\n"
|
<<"thanks to : https://github.com/andyross/nasal\n"
|
||||||
<<"code repo : https://github.com/ValKmjolnir/Nasal-Interpreter\n"
|
<<"code repo : https://github.com/ValKmjolnir/Nasal-Interpreter\n"
|
||||||
<<"code repo : https://gitee.com/valkmjolnir/Nasal-Interpreter\n"
|
<<"code repo : https://gitee.com/valkmjolnir/Nasal-Interpreter\n"
|
||||||
|
|
2
nasal.h
2
nasal.h
|
@ -1,6 +1,8 @@
|
||||||
#ifndef __NASAL_H__
|
#ifndef __NASAL_H__
|
||||||
#define __NASAL_H__
|
#define __NASAL_H__
|
||||||
|
|
||||||
|
#define __nasver "9.0"
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
|
@ -548,6 +548,11 @@ void nasal_codegen::mcall(const nasal_ast& ast)
|
||||||
mcall_id(ast);
|
mcall_id(ast);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if(ast.size()==1) // foreach and forindex use call-id ast to get mcall
|
||||||
|
{
|
||||||
|
mcall_id(ast[0]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
calc_gen(ast[0]);
|
calc_gen(ast[0]);
|
||||||
for(size_t i=1;i<ast.size()-1;++i)
|
for(size_t i=1;i<ast.size()-1;++i)
|
||||||
{
|
{
|
||||||
|
@ -774,10 +779,10 @@ void nasal_codegen::for_gen(const nasal_ast& ast)
|
||||||
case ast_null:break;
|
case ast_null:break;
|
||||||
case ast_def:def_gen(ast[0]);break;
|
case ast_def:def_gen(ast[0]);break;
|
||||||
case ast_multi_assign:multi_assign_gen(ast[0]);break;
|
case ast_multi_assign:multi_assign_gen(ast[0]);break;
|
||||||
case ast_nil:case ast_num:case ast_str:case ast_func:break;
|
case ast_nil:case ast_num:case ast_str:break;
|
||||||
case ast_vec:case ast_hash:
|
case ast_vec:case ast_hash:case ast_func:
|
||||||
case ast_call:
|
case ast_call:
|
||||||
case ast_equal:case ast_addeq:case ast_subeq:
|
case ast_addeq:case ast_subeq:
|
||||||
case ast_multeq:case ast_diveq:case ast_lnkeq:
|
case ast_multeq:case ast_diveq:case ast_lnkeq:
|
||||||
case ast_neg:case ast_not:
|
case ast_neg:case ast_not:
|
||||||
case ast_add:case ast_sub:
|
case ast_add:case ast_sub:
|
||||||
|
@ -790,6 +795,25 @@ void nasal_codegen::for_gen(const nasal_ast& ast)
|
||||||
calc_gen(ast[0]);
|
calc_gen(ast[0]);
|
||||||
gen(op_pop,0,ast[0].line());
|
gen(op_pop,0,ast[0].line());
|
||||||
break;
|
break;
|
||||||
|
case ast_equal:
|
||||||
|
if(ast[0][0].type()==ast_id)
|
||||||
|
{
|
||||||
|
calc_gen(ast[0][1]);
|
||||||
|
mcall_id(ast[0][0]);
|
||||||
|
// only the first mcall_id can use load
|
||||||
|
if(code.back().op==op_mcalll)
|
||||||
|
code.back().op=op_loadl;
|
||||||
|
else if(code.back().op==op_mupval)
|
||||||
|
code.back().op=op_loadu;
|
||||||
|
else
|
||||||
|
code.back().op=op_loadg;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
calc_gen(ast[0]);
|
||||||
|
gen(op_pop,0,ast[0].line());
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
int jmp_place=code.size();
|
int jmp_place=code.size();
|
||||||
if(ast[1].type()==ast_null)
|
if(ast[1].type()==ast_null)
|
||||||
|
@ -806,10 +830,10 @@ void nasal_codegen::for_gen(const nasal_ast& ast)
|
||||||
case ast_null:break;
|
case ast_null:break;
|
||||||
case ast_def:def_gen(ast[2]);break;
|
case ast_def:def_gen(ast[2]);break;
|
||||||
case ast_multi_assign:multi_assign_gen(ast[2]);break;
|
case ast_multi_assign:multi_assign_gen(ast[2]);break;
|
||||||
case ast_nil:case ast_num:case ast_str:case ast_func:break;
|
case ast_nil:case ast_num:case ast_str:break;
|
||||||
case ast_vec:case ast_hash:
|
case ast_vec:case ast_hash:case ast_func:
|
||||||
case ast_call:
|
case ast_call:
|
||||||
case ast_equal:case ast_addeq:
|
case ast_addeq:
|
||||||
case ast_subeq:case ast_multeq:
|
case ast_subeq:case ast_multeq:
|
||||||
case ast_diveq:case ast_lnkeq:
|
case ast_diveq:case ast_lnkeq:
|
||||||
case ast_neg:case ast_not:
|
case ast_neg:case ast_not:
|
||||||
|
@ -821,6 +845,25 @@ void nasal_codegen::for_gen(const nasal_ast& ast)
|
||||||
calc_gen(ast[2]);
|
calc_gen(ast[2]);
|
||||||
gen(op_pop,0,ast[2].line());
|
gen(op_pop,0,ast[2].line());
|
||||||
break;
|
break;
|
||||||
|
case ast_equal:
|
||||||
|
if(ast[2][0].type()==ast_id)
|
||||||
|
{
|
||||||
|
calc_gen(ast[2][1]);
|
||||||
|
mcall_id(ast[2][0]);
|
||||||
|
// only the first mcall_id can use load
|
||||||
|
if(code.back().op==op_mcalll)
|
||||||
|
code.back().op=op_loadl;
|
||||||
|
else if(code.back().op==op_mupval)
|
||||||
|
code.back().op=op_loadu;
|
||||||
|
else
|
||||||
|
code.back().op=op_loadg;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
calc_gen(ast[2]);
|
||||||
|
gen(op_pop,0,ast[2].line());
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
gen(op_jmp,jmp_place,ast[2].line());
|
gen(op_jmp,jmp_place,ast[2].line());
|
||||||
code[label_exit].num=code.size();
|
code[label_exit].num=code.size();
|
||||||
|
@ -843,8 +886,17 @@ void nasal_codegen::forindex_gen(const nasal_ast& ast)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mcall(ast[0]);
|
mcall(ast[0]);
|
||||||
gen(op_meq,0,ast[0].line());
|
if(code.back().op==op_mcallg)
|
||||||
gen(op_pop,0,ast[0].line());
|
code.back().op=op_loadg;
|
||||||
|
else if(code.back().op==op_mcalll)
|
||||||
|
code.back().op=op_loadl;
|
||||||
|
else if(code.back().op==op_mupval)
|
||||||
|
code.back().op=op_loadu;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gen(op_meq,0,ast[0].line());
|
||||||
|
gen(op_pop,0,ast[0].line());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
++in_iterloop.top();
|
++in_iterloop.top();
|
||||||
block_gen(ast[2]);
|
block_gen(ast[2]);
|
||||||
|
@ -871,8 +923,17 @@ void nasal_codegen::foreach_gen(const nasal_ast& ast)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mcall(ast[0]);
|
mcall(ast[0]);
|
||||||
gen(op_meq,0,ast[0].line());
|
if(code.back().op==op_mcallg)
|
||||||
gen(op_pop,0,ast[0].line());
|
code.back().op=op_loadg;
|
||||||
|
else if(code.back().op==op_mcalll)
|
||||||
|
code.back().op=op_loadl;
|
||||||
|
else if(code.back().op==op_mupval)
|
||||||
|
code.back().op=op_loadu;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gen(op_meq,0,ast[0].line());
|
||||||
|
gen(op_pop,0,ast[0].line());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
++in_iterloop.top();
|
++in_iterloop.top();
|
||||||
block_gen(ast[2]);
|
block_gen(ast[2]);
|
||||||
|
@ -1042,7 +1103,7 @@ void nasal_codegen::block_gen(const nasal_ast& ast)
|
||||||
for(auto& tmp:ast.child())
|
for(auto& tmp:ast.child())
|
||||||
switch(tmp.type())
|
switch(tmp.type())
|
||||||
{
|
{
|
||||||
case ast_null:case ast_nil:case ast_num:case ast_str:case ast_func:break;
|
case ast_null:case ast_nil:case ast_num:case ast_str:break;
|
||||||
case ast_file:fileindex=tmp.num();break; // special node type in main block
|
case ast_file:fileindex=tmp.num();break; // special node type in main block
|
||||||
case ast_def:def_gen(tmp);break;
|
case ast_def:def_gen(tmp);break;
|
||||||
case ast_multi_assign:multi_assign_gen(tmp);break;
|
case ast_multi_assign:multi_assign_gen(tmp);break;
|
||||||
|
@ -1081,6 +1142,7 @@ void nasal_codegen::block_gen(const nasal_ast& ast)
|
||||||
case ast_id:
|
case ast_id:
|
||||||
case ast_vec:
|
case ast_vec:
|
||||||
case ast_hash:
|
case ast_hash:
|
||||||
|
case ast_func:
|
||||||
case ast_call:
|
case ast_call:
|
||||||
case ast_addeq:
|
case ast_addeq:
|
||||||
case ast_subeq:
|
case ast_subeq:
|
||||||
|
|
|
@ -126,9 +126,16 @@ public:
|
||||||
|
|
||||||
void nasal_lexer::open(const std::string& file)
|
void nasal_lexer::open(const std::string& file)
|
||||||
{
|
{
|
||||||
|
struct stat buffer;
|
||||||
|
if(stat(file.c_str(),&buffer)==0 && !S_ISREG(buffer.st_mode))
|
||||||
|
{
|
||||||
|
nerr.err("lexer","<"+file+"> is not a regular file.");
|
||||||
|
res="";
|
||||||
|
return;
|
||||||
|
}
|
||||||
std::ifstream fin(file,std::ios::binary);
|
std::ifstream fin(file,std::ios::binary);
|
||||||
if(fin.fail())
|
if(fin.fail())
|
||||||
nerr.err("lexer","cannot open file <"+file+">.");
|
nerr.err("lexer","failed to open <"+file+">.");
|
||||||
else
|
else
|
||||||
nerr.load(file);
|
nerr.load(file);
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
|
|
|
@ -512,6 +512,8 @@ inline void nasal_vm::opr_meq()
|
||||||
{
|
{
|
||||||
mem_addr[0]=(--gc.top)[0]; // pop old mem_addr[0] and replace it
|
mem_addr[0]=(--gc.top)[0]; // pop old mem_addr[0] and replace it
|
||||||
mem_addr=nullptr;
|
mem_addr=nullptr;
|
||||||
|
if(imm[pc])
|
||||||
|
--gc.top;
|
||||||
}
|
}
|
||||||
inline void nasal_vm::opr_eq()
|
inline void nasal_vm::opr_eq()
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue