|
Lhogho
0.0.027
|
Defines | |
| #define | void void __attribute__ ((used,noinline,regparm(0),stdcall)) |
Functions | |
| void | init_atoms () |
| initializes the Atoms module | |
| void | finit_atoms () |
| finalizes the Atoms module | |
| atom_t | use (atom_t a) |
| adds link to atom | |
| void | deuse (atom_t a) |
| removes link to atom | |
| void | dump_atom (atom_t a, int level) |
| dumps atom contents | |
| void | dump (atom_t a) |
| dumps atom contents | |
| void | dumpln (atom_t a) |
| dumps atom contents | |
| void | init_output (outter_t new_outter) |
| initializes text output | |
| void | init_input (inner_t new_inner, inner_eof_t new_inner_eof) |
| initializes text input | |
| void | outter (chars_t string, int len) |
| prints text | |
| int | inner_eof () |
| returns eof status | |
| char_t | inner () |
Variables | |
| inner_t | std_inner |
| hook variable for inputting text | |
| inner_eof_t | std_inner_eof |
| hook variable for inputting text | |
| outter_t | std_outter |
| hook variable for outputting text | |
| int | outter_size = 0 |
| counts outted characters | |
| FILE * | input_stream = NULL |
| current input stream | |
| FILE * | output_stream = NULL |
| current input stream | |
| struct lconv * | locale_info |
| locale information | |
| #define void void __attribute__ ((used,noinline,regparm(0),stdcall)) |
| void init_atoms | ( | ) |
Creates a data pool for all atoms and creates one special atom representing the empty list.
{
#ifdef DEBUG_ATOM
printf("<ATOM> Atoms initialized\n");
#endif //DEBUG_ATOM
#ifdef ADVANCED
int i;
stats_free = 0;
stats_allocs = 0;
for( i=MIN_ID; i<MAX_ID; i++ )
{
stats[i].max = 0;
stats[i].allocs = 0;
stats[i].deallocs = 0;
}
#endif //ADVANCED
#ifdef SAFEMODE
assert( sizeof(atomrec_t)==16 );
#endif
//setlocale( LC_ALL, "" );
locale_info = localeconv();
init_pool( &data_pool, ATOM_SIZE );
init_pool( &data_pool_ex, ATOM_SIZE_EX );
empty_list = (atom_t)take_from_pool( &data_pool );
REF(empty_list) = 1;
ID(empty_list) = LIST_ID;
CAR(empty_list) = empty_list;
CDR(empty_list) = empty_list;
FLAGS(empty_list) = 0;
}
| void finit_atoms | ( | ) |
Returns the empty list back to the data pool.
{
return_to_pool( &data_pool, empty_list );
#ifdef DEBUG_MEMORY_LEAKS
dump_pool();
#endif
#ifdef DEBUG_ATOM
printf("<ATOM> Atoms finalized\n");
#endif //DEBUG_ATOM
}
| a | atom to use |
Adds a link to an atom by increasing atom's reference count.
{
if( IS_UNBOUND(a) || IS_EMPTY(a) || IS_STOPPED(a) )
return a;
//if( a==0x49f3b8)
//{
//printf("USE.BUG[%08x] ref %d->%d\n", (int)a, REF(a), REF(a)+1 );
//}
#ifdef DEBUG_RUNTIME_ATOMS
if( running_compiled_code )
{
outter( TEXT("<RUNTIME> use "), -1 );
dump_atom_address( a );
dump_atom( a, 1 );
outter( TEXT("\n"), -1 );
}
#endif
#ifdef DEBUG_COMPILETIME_ATOMS
if( compiling_code )
{
outter( TEXT("<COMPILETIME> use "), -1 );
dump_atom_address( a );
dump_atom( a, 1 );
outter( TEXT("\n"), -1 );
}
#endif
//if( IS_ERROR(a) )
// {
// printf("TO BE USEIT hex(a)=%x id=%d REF=%d a=",(int)a,ID(a),REF(a)); dumpln(a);
// }
#ifdef SAFEMODE
assert( a );
assert( ID(a)<MAX_ID );
assert( REF(a)>=0 ); // 2009 was >0
#endif //SAFEMODE
//if( IS_INTEGER(a) || IS_FLOAT(a))
//{
//printf("deuse[addr=%x ref=%d]\n",a,REF(a));
//printf("use atom="); dumpln(a);
//}
REF(a)++;
#ifdef DEBUG_ATOM
printf("<ATOM> [%08x] ref+1\n",(int)a);
#endif //DEBUG_ATOM
return a;
}
| a | atom to unlink |
Decrements the reference count for the atom and if it reaches 0 then frees the atom using one of the functions delete_numeric, delete_list, delete_word, delete_subword, delete_error, delete_var.
{
__asm__ volatile ( ASM_STORE_RESULT:::ASM_CLOBBER_REGISTERS );
typedef void(*deleter_t)(atom_t);
static deleter_t deleters[MAX_ID] = {
delete_numeric, // INTEGER_ID
delete_numeric, // FLOAT_ID
delete_list, // LIST_ID
delete_word, // WORD_ID
delete_subword, // SUBWORD_ID
delete_error, // ERROR_ID
delete_var, // VAR_ID
delete_mem, // MEM_ID
}; // array of deleter functions for each atom type
//if( a==0x49f3b8)
//{
//printf("DEUSE.BUG[%08x] ref %d->%d\n", (int)a, REF(a), REF(a)-1 );
//}
//if( IS_INTEGER(a) || IS_FLOAT(a))
// {
// //printf("deuse[addr=%x ref=%d]\n",(int)a,REF(a));
// printf("deuse atom="); dumpln(a);
// }
if( !IS_EMPTY(a) && !IS_UNBOUND(a) && !IS_STOPPED(a))
{
//printf("deuse "); dumpln(a);
#ifdef DEBUG_RUNTIME_ATOMS
if( running_compiled_code )
{
outter( TEXT("<RUNTIME> deuse"), -1 );
dump_atom_address( a );
dump_atom( a, 1 );
outter( TEXT("\n"), -1 );
}
#endif
#ifdef DEBUG_COMPILETIME_ATOMS
if( compiling_code )
{
outter( TEXT("<COMPILETIME> deuse"), -1 );
dump_atom_address( a );
dump_atom( a, 1 );
outter( TEXT("\n"), -1 );
}
#endif
//if( IS_ERROR(a) )
//{
//printf("TO BE DEUSE hex(a)=%x id=%d REF=%d a=",(int)a,ID(a),REF(a)); dumpln(a);
//}
#ifdef SAFEMODE
assert( a );
//if(ID(a)>=MAX_ID) {printf("ASSERT[%x]\n",a);}
assert( (ID(a)<MAX_ID) );
assert( REF(a)>0 );
#endif // SAFEMODE
//printf("GOODY hex(a)=%x id=%d REF=%d\n\n",(int)a,ID(a),REF(a));
if( !--REF(a) )
{
#ifdef DEBUG_ATOM
printf("<ATOM> [%08x] ref-1\n",(int)a);
#endif //DEBUG_ATOM
#ifdef ADVANCED
stats[ID(a)].deallocs++;
stats_free++;
#endif //ADVANCED
deleter_t deleter = deleters[ID(a)];
deleter(a);
}
}
__asm__ volatile ( ASM_RESTORE_RESULT:::ASM_CLOBBER_REGISTERS );
}
| a | atom to dump |
| level | level of nesting |
Dumps atom's contents using a call-back outter function. Texts are automatically indented according to the level. Typically this function is used to print an atom when the call-back function forwards contents to standard output. The call-back function is set by init_output().
< array of deleter functions for each atom type
{
typedef void(*dumper_t)(atom_t,int);
static dumper_t dumpers[MAX_ID] = {
dump_integer, // INTEGER_ID
dump_float, // FLOAT_ID
dump_list, // LIST_ID
dump_word, // WORD_ID
dump_word, // SUBWORD_ID
dump_error, // ERROR_ID
dump_var, // VAR_ID
dump_mem, // MEM_ID
};
#ifdef SAFEMODE
assert( a );
//assert( outter );
if( IS_NOT_EMPTY(a) ) assert( ID(a)<MAX_ID );
#endif //SAFEMODE
#ifdef DEBUG_REF_COUNT
if( IS_EMPTY(a) )
{
outter( TEXT("##"), 2 );
}
else
{
int n;
char_t buf[64];
n = SPRINTF( buf, DUMP_BUF_SIZE, TEXT(" %d#"), REF(a) );
outter( buf, n );
}
#endif
dumper_t dumper = dumpers[ID(a)];
dumper(a,level);
}
| a | atom to dump |
Dumps atom's contents throught the current text output function (e.g. use_stdout).
{
dump_atom( a, 0 );
}
| a | atom to dump |
Dumps atom's contents throught the current text output function (e.g. use_stdout) and moves cursor to the next line.
| void init_output | ( | outter_t | new_outter | ) |
Initializes the text output system by setting the std_outter function to output text throught it.
{
std_outter = new_outter;
}
| void init_input | ( | inner_t | new_inner, |
| inner_eof_t | new_inner_eof | ||
| ) |
| new_inner | new inner function |
| new_inner_eof | new inner_eof function |
Initializes the text input system by setting the std_inner and :std_inner_eof functions to input text throught it.
{
std_inner = new_inner;
std_inner_eof = new_inner_eof;
}
| string | text to print |
| len | length of text |
This function prints text to either the hooked output or to a file.
{
if( output_stream==NULL )
{
std_outter( string, len );
}
else
{
if( len==-1 ) len = STRLEN( string );
for( ; len>0; len--, string++ )
{
int crlf = (DEBAR(*string)==0x0D) && (DEBAR(*(string+1))==0x0A);
if( !crlf )
{
char_t wc[2];
wc[0] = DEBAR(*string);
wc[1] = 0;
char* buf =(char*) UTF16_to_UTF8(wc);
DEALLOC( buf );
fprintf( output_stream, "%S", wc );
}
}
}
}
Return EOF status of a hooked or file stream.
{
if( input_stream==NULL )
{
return std_inner_eof();
}
else
{
return feof(input_stream)?1:0;
}
}
{
if( input_stream==NULL )
{
return std_inner();
}
else
{
char_t ch;
//ch = GETCHAR( input_stream );
//while( ch=='\r' ) ch = GETCHAR( input_stream ); // remove ^M from input, keep ^J
ch = (char_t)getc( input_stream );
while( ch=='\r' ) ch = (char_t)getc( input_stream ); // remove ^M from input, keep ^J
return ch;
}
}
| int outter_size = 0 |
| FILE* input_stream = NULL |
| FILE* output_stream = NULL |
| struct lconv* locale_info |