Add files via upload

This commit is contained in:
Valk Richard Li 2020-07-28 02:21:10 -07:00 committed by GitHub
parent 7b35d77f44
commit 2af4050bac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 258 additions and 258 deletions

View File

@ -22,7 +22,6 @@
#include "nasal_lexer.h" #include "nasal_lexer.h"
#include "nasal_ast.h" #include "nasal_ast.h"
#include "nasal_parse.h" #include "nasal_parse.h"
#include "nasal_vm.h"
#include "nasal_gc.h" #include "nasal_gc.h"
#endif #endif

View File

@ -1,80 +1,45 @@
#ifndef __NASAL_GC_H__ #ifndef __NASAL_GC_H__
#define __NASAL_GC_H__ #define __NASAL_GC_H__
#define MEM_BLK_SIZE 128 #define MEM_BLK_SIZE 256 // 0x00 ~ 0xff
#define GC_BLK_SIZE 128 #define GC_BLK_SIZE 256 // 0x00 ~ 0xff
class nasal_vector class nasal_vector
{ {
private: private:
// this int points to the space in nasal_vm_memory_manager // this int points to the space in nasal_vm::memory_manager_memory
std::vector<int> elems; std::vector<int> elems;
public: public:
nasal_vector() nasal_vector();
{ void add_elem(int);
elems.clear(); int del_elem(int);
return;
}
void add_elem(int memory_address)
{
elems.push_back(memory_address);
return;
}
int del_elem(int index)
{
if(index>=elems.size())
return -1;
int ret=elems[index];
elems.pop_back();
return ret;
}
}; };
class nasal_hash class nasal_hash
{ {
private: private:
// this int points to the space in nasal_vm_memory_manager // this int points to the space in nasal_vm::memory_manager_memory
std::map<std::string,int> elems; std::map<std::string,int> elems;
public: public:
nasal_hash() nasal_hash();
{ void add_elem(std::string,int);
elems.clear(); void del_elem(std::string);
return;
}
void add_elem(std::string key,int memory_address)
{
elems[key]=memory_address;
return;
}
void del_elem(std::string key)
{
elems.erase(key);
return;
}
}; };
class nasal_function class nasal_function
{ {
private: private:
// this int points to the space in nasal_vm_memory_manager // this int points to the space in nasal_vm::memory_manager_memory
std::list<int> closures; std::list<int> closures;
nasal_ast function_tree; nasal_ast function_tree;
public: public:
nasal_function() nasal_function();
{
closures.clear();
function_tree.clear();
return;
}
}; };
class nasal_closure class nasal_closure
{ {
private: private:
// this int points to the space in nasal_vm::memory_manager_memory
std::map<std::string,int> elems; std::map<std::string,int> elems;
public: public:
nasal_closure() nasal_closure();
{
elems.clear();
return;
}
}; };
class nasal_scalar class nasal_scalar
@ -83,13 +48,111 @@ private:
int type; int type;
void* scalar_ptr; void* scalar_ptr;
public: public:
nasal_scalar() nasal_scalar();
~nasal_scalar();
void clear();
bool set_type(int);
// +-*/~
// =
// unary - !
};
class nasal_virtual_machine
{
struct gc_unit
{
bool collected;
char ref_cnt;
nasal_scalar elem;
gc_unit()
{
collected=true;
ref_cnt=0;
return;
}
};
private:
std::queue<int> garbage_collector_free_space;
std::vector<gc_unit*> garbage_collector_memory;
std::queue<int> memory_manager_free_space;
std::vector<int*> memory_manager_memory;
public:
~nasal_virtual_machine();
int gc_alloc();
int add_reference(int);
int del_reference(int);
int mem_alloc();
int mem_free(int);
int mem_store(int,int);
};
/*
nasal runtime virtual machine
*/
nasal_virtual_machine nasal_vm;
/*functions of nasal_vector*/
nasal_vector::nasal_vector()
{
elems.clear();
return;
}
void nasal_vector::add_elem(int memory_address)
{
elems.push_back(memory_address);
return;
}
int nasal_vector::del_elem(int index)
{
if(index>=elems.size())
return -1;
int ret=elems[index];
nasal_vm.mem_free(ret);
elems.pop_back();
return ret;
}
/*functions of nasal_hash*/
nasal_hash::nasal_hash()
{
elems.clear();
return;
}
void nasal_hash::add_elem(std::string key,int memory_address)
{
elems[key]=memory_address;
return;
}
void nasal_hash::del_elem(std::string key)
{
nasal_vm.mem_free(elems[key]);
elems.erase(key);
return;
}
/*functions of nasal_function*/
nasal_function::nasal_function()
{
closures.clear();
function_tree.clear();
return;
}
/*functions of nasal_closure*/
nasal_closure::nasal_closure()
{
elems.clear();
return;
}
/*functions of nasal_scalar*/
nasal_scalar::nasal_scalar()
{ {
this->type=vm_nil; this->type=vm_nil;
this->scalar_ptr=(void*)NULL; this->scalar_ptr=(void*)NULL;
return; return;
} }
~nasal_scalar() nasal_scalar::~nasal_scalar()
{ {
switch(this->type) switch(this->type)
{ {
@ -103,7 +166,22 @@ public:
} }
return; return;
} }
bool set_type(int nasal_scalar_type) void nasal_scalar::clear()
{
this->type=vm_nil;
switch(this->type)
{
case vm_nil:break;
case vm_number: delete (double*)(this->scalar_ptr); break;
case vm_string: delete (std::string*)(this->scalar_ptr); break;
case vm_vector: delete (nasal_vector*)(this->scalar_ptr); break;
case vm_hash: delete (nasal_hash*)(this->scalar_ptr); break;
case vm_function: delete (nasal_function*)(this->scalar_ptr); break;
case vm_closure: delete (nasal_closure*)(this->scalar_ptr); break;
}
return;
}
bool nasal_scalar::set_type(int nasal_scalar_type)
{ {
bool ret=true; bool ret=true;
this->type=nasal_scalar_type; this->type=nasal_scalar_type;
@ -125,185 +203,108 @@ public:
} }
return ret; return ret;
} }
// +-*/~
// =
// unary - !
};
/* gc_unit is the basic unit of garbage_collector*/ /*functions of nasal_virtual_machine*/
struct gc_unit nasal_virtual_machine::~nasal_virtual_machine()
{ {
bool collected; int gc_mem_size=garbage_collector_memory.size();
char ref_cnt; int mm_mem_size=memory_manager_memory.size();
nasal_scalar elem; for(int i=0;i<gc_mem_size;++i)
gc_unit() delete []garbage_collector_memory[i];
{ for(int i=0;i<mm_mem_size;++i)
collected=true; delete []memory_manager_memory[i];
ref_cnt=0; garbage_collector_memory.clear();
memory_manager_memory.clear();
return; return;
} }
}; int nasal_virtual_machine::gc_alloc()
/* garbage_collector uses FIFO to manage value space*/
class nasal_garbage_collector
{ {
private: if(garbage_collector_free_space.empty())
std::queue<int> free_space;
std::vector<gc_unit*> memory;
public:
nasal_garbage_collector();
~nasal_garbage_collector();
int gc_alloc();
int add_ref(int);
int del_ref(int);
};
nasal_garbage_collector::nasal_garbage_collector()
{ {
memory.clear(); gc_unit* new_block=new gc_unit[256];
return; garbage_collector_memory.push_back(new_block);
int mem_size=garbage_collector_memory.size();
for(int i=((mem_size-1)<<8);i<(mem_size<<8);++i)
garbage_collector_free_space.push(i);
} }
int ret=garbage_collector_free_space.front();
nasal_garbage_collector::~nasal_garbage_collector() garbage_collector_memory[ret>>8][ret&0xff].collected=false;
{ garbage_collector_memory[ret>>8][ret&0xff].ref_cnt=1;
int size=memory.size(); garbage_collector_free_space.pop();
for(int i=0;i<size;++i)
delete []memory[i];
while(!free_space.empty())
free_space.pop();
return;
}
int nasal_garbage_collector::gc_alloc()
{
if(free_space.empty())
{
gc_unit* new_block=new gc_unit[GC_BLK_SIZE];
memory.push_back(new_block);
int mem_size=memory.size();
for(int i=(mem_size-1)*GC_BLK_SIZE;i<mem_size*GC_BLK_SIZE;++i)
free_space.push(i);
}
int ret=free_space.front();
memory[ret/GC_BLK_SIZE][ret%GC_BLK_SIZE].collected=false;
memory[ret/GC_BLK_SIZE][ret%GC_BLK_SIZE].ref_cnt=1;
free_space.pop();
return ret; return ret;
} }
int nasal_virtual_machine::add_reference(int memory_address)
int nasal_garbage_collector::add_ref(int mem_space)
{ {
int blk_num=mem_space/GC_BLK_SIZE; int blk_num=(memory_address>>8);
int blk_plc=mem_space%GC_BLK_SIZE; int blk_plc=(memory_address&0xff);
if(0<=mem_space && mem_space<memory.size()*GC_BLK_SIZE && !memory[blk_num][blk_plc].collected) if(0<=memory_address && memory_address<(garbage_collector_memory.size()<<8) && !garbage_collector_memory[blk_num][blk_plc].collected)
++memory[blk_num][blk_plc].ref_cnt; ++garbage_collector_memory[blk_num][blk_plc].ref_cnt;
else else
{ {
std::cout<<">> [gc] add_ref:unexpected memory \'"<<mem_space<<"\'."<<std::endl; std::cout<<">> [vm] gc_add_ref:unexpected memory \'"<<memory_address<<"\'."<<std::endl;
return 0; return 0;
} }
return 1; return 1;
} }
int nasal_virtual_machine::del_reference(int memory_address)
int nasal_garbage_collector::del_ref(int mem_space)
{ {
int blk_num=mem_space/GC_BLK_SIZE; int blk_num=(memory_address>>8);
int blk_plc=mem_space%GC_BLK_SIZE; int blk_plc=(memory_address&0xff);
if(0<=mem_space && mem_space<memory.size()*GC_BLK_SIZE && !memory[blk_num][blk_plc].collected) if(0<=memory_address && memory_address<(garbage_collector_memory.size()<<8) && !garbage_collector_memory[blk_num][blk_plc].collected)
--memory[blk_num][blk_plc].ref_cnt; --garbage_collector_memory[blk_num][blk_plc].ref_cnt;
else else
{ {
std::cout<<">> [gc] del_ref:unexpected memory \'"<<mem_space<<"\'."<<std::endl; std::cout<<">> [vm] gc_del_ref:unexpected memory \'"<<memory_address<<"\'."<<std::endl;
return 0; return 0;
} }
if(!memory[blk_num][blk_plc].ref_cnt) if(!garbage_collector_memory[blk_num][blk_plc].ref_cnt)
{ {
memory[blk_num][blk_plc].collected=true; garbage_collector_memory[blk_num][blk_plc].collected=true;
free_space.push(mem_space); garbage_collector_memory[blk_num][blk_plc].elem.clear();
garbage_collector_free_space.push(memory_address);
} }
return 1; return 1;
} }
int nasal_virtual_machine::mem_alloc()
/* memory_manage simulates a virtual memory space to store values in */
class nasal_vm_memory_manager
{ {
private: if(memory_manager_free_space.empty())
std::queue<int> free_space;
std::vector<int*> memory;
public:
nasal_vm_memory_manager();
~nasal_vm_memory_manager();
int nas_alloc();
int nas_free(int);
int nas_store(int,int);
};
nasal_vm_memory_manager::nasal_vm_memory_manager()
{ {
memory.clear(); int* new_block=new int[256];
return; memory_manager_memory.push_back(new_block);
int mem_size=memory_manager_memory.size();
for(int i=((mem_size-1)<<8);i<(mem_size<<8);++i)
memory_manager_free_space.push(i);
} }
int ret=memory_manager_free_space.front();
nasal_vm_memory_manager::~nasal_vm_memory_manager() memory_manager_free_space.pop();
{
int size=memory.size();
for(int i=0;i<size;++i)
delete []memory[i];
memory.clear();
while(!free_space.empty())
free_space.pop();
return;
}
int nasal_vm_memory_manager::nas_alloc()
{
if(free_space.empty())
{
int* new_block=new int[MEM_BLK_SIZE];
memory.push_back(new_block);
int mem_size=memory.size();
for(int i=(mem_size-1)*MEM_BLK_SIZE;i<mem_size*MEM_BLK_SIZE;++i)
free_space.push(i);
}
int ret=free_space.front();
free_space.pop();
return ret; return ret;
} }
int nasal_virtual_machine::mem_free(int memory_address)
int nasal_vm_memory_manager::nas_free(int space_num)
{ {
if(0<=space_num && space_num<memory.size()*MEM_BLK_SIZE) // mem_free has helped scalar to delete the reference
free_space.push(space_num); // so don't need to delete reference again
if(0<=memory_address && memory_address<(memory_manager_memory.size()<<8))
{
this->del_reference(memory_manager_memory[memory_address>>8][memory_address&0xff]);
memory_manager_free_space.push(memory_address);
}
else else
{ {
std::cout<<">> [vm] nas_free:unexpected memory \'"<<space_num<<"\'."<<std::endl; std::cout<<">> [vm] mem_free:unexpected memory \'"<<memory_address<<"\'."<<std::endl;
return 0; return 0;
} }
return 1; return 1;
} }
int nasal_virtual_machine::mem_store(int memory_address,int value_space)
int nasal_vm_memory_manager::nas_store(int mem_space,int value_space)
{ {
// be careful! this process doesn't check if this mem_space is in use. // be careful! this process doesn't check if this mem_space is in use.
if(0<=mem_space && mem_space<memory.size()*MEM_BLK_SIZE) if(0<=memory_address && memory_address<(memory_manager_memory.size()<<8))
memory[mem_space/MEM_BLK_SIZE][mem_space%MEM_BLK_SIZE]=value_space; memory_manager_memory[memory_address>>8][memory_address&0xff]=value_space;
else else
{ {
std::cout<<">> [vm] nas_store:unexpected memory \'"<<mem_space<<"\'."<<std::endl; std::cout<<">> [vm] mem_store:unexpected memory \'"<<memory_address<<"\'."<<std::endl;
return 0; return 0;
} }
return 1; return 1;
} }
/*
nasal_gc and nasal_mem are used in nasal_scalar
because nasal_scalars' memory management needs these two modules
when vector/hash/function/closure delete values,they need nasal_gc and nasal_mem to
change the reference counters of these values
*/
nasal_garbage_collector nasal_gc;
nasal_vm_memory_manager nasal_mem;
//
#endif #endif