ftp.nice.ch/pub/next/developer/languages/lisp/AKCL.1.599.s.tar.gz#/akcl-1-599/c/fat_string.c

This is fat_string.c in view mode; [Download] [Up]

/*
(c) Copyright W. Schelter 1988, All rights reserved.
*/

/* 16 bit strings  with leader, and raw slots in the leader t_fat_string */


#include "include.h"
#include "page.h"
#define FAT_STRING

object  Sfat_string;
enum type what_to_collect;
#define	inheap(pp)	((char *)(pp) < heap_end)



/* start fasdump stuff */
#include "fasdump.c"

/* this will be used for lines, and for structures that require some
raw storage */

#define check_fs_args(ar,ind) \
    if (type_of(ar) != t_fat_string) FEerror("Not a vector with leader",0); \
   if ((ind >= (ar->fs.fs_dim)) \
       ||(ind < 0)) FEerror("subscript out of bounds",0)
   
check_type_fat_string(p)
object *p;
{
BEGIN:
	if (type_of(*p)==t_fat_string) return;
	*p = wrong_type_argument(Sfat_string, *p);
	goto BEGIN;
      }
      

void
siLfsref()
{ check_arg(2);
  {register int  ind = fix(vs_base[1]);
   register object ar =  vs_base[0];
   check_fs_args(ar,ind);
   vs_base[0]=make_fixnum((int) (ar->fs.fs_self[ind]));
   vs_top=vs_base+1;}}

void
siLfsset()
{register object *base,ar;
 register int ind;
 check_arg(3);
 base=vs_base;
 ar=base[0];
 check_type_integer(&base[1]);
 ind =fix(base[1]); 
 check_fs_args(ar,ind);
 base[0]=base[2];
 ar->fs.fs_self[ind]=fix(base[0]);
 vs_top=base+1;
}

#define check_fs_leader(ar,ind) \
      if (type_of(ar) != t_fat_string) FEerror("Not a vector with leader",0); \
      if ((ind >= ar->fs.fs_leader_length)||(ind < 0)) FEerror("subscript out of bounds",0)


fs_leader_ref(ar,ind)
     register object ar;
     register int ind;
{ check_arg(2);
  check_fs_leader(ar,ind);
  return (int) fs_leader(ar,ind);
}


void
check_raw(raw,i)
     unsigned int raw;
     int i;
{if (!(raw & (1 << i))) FEerror("Slot not raw",0);}


void
siLfs_leader_ref()
{ register object *base;
  base=vs_base;
  base[0]=(object) fs_leader_ref(base[0],fix(base[1]));
  vs_top=base+1;
}

void
siLfixnum_fs_leader_ref()
{ register object *base;
  base=vs_base;
  check_raw((base[0]->fs.fs_raw),fix(base[1]));
  base[0]=make_fixnum(fs_leader_ref(base[0],fix(base[1])));
  vs_top=base+1;
}


void
fs_leader_set(ar,ind,val)
 register object ar;
  register  int ind;
     object val;
{  check_arg(3);
  check_fs_leader(ar,ind);
  fs_leader(ar,ind)=  val;
}


void
siLfs_leader_set()
{ register object *base;
  base=vs_base;
  fs_leader_set(base[0],fix(base[1]), base[2]);
  base[0]=base[2];
  vs_top=base+1;}

void
siLfixnum_fs_leader_set()
{ register object *base;
  base=vs_base;
  check_type_integer(&base[2]);
  check_raw((base[0])->fs.fs_raw,fix(base[1]));
  fs_leader_set(base[0],fix(base[1]),(object) fix(base[2]));
  base[0]=base[2];
  vs_top=base+1;}

void
mark_fat_string(x)
     object x;
{register char *cp;
 { int i=0,raw=x->fs.fs_raw;
   cp = (char *) x->fs.fs_self;
   while (i < x->fs.fs_leader_length)
     {if (raw & 1) ;
      else mark_object(fs_leader(x,i));
      raw=( raw >> 1); i++;
    }}
 {int leader_size = (x->fs.fs_leader_length) * sizeof(object *);
  int body_size = leader_size + (x->fs.fs_dim)*sizeof(fatchar);
  cp=cp-leader_size;
  if ((int)what_to_collect >= (int)t_contiguous) {
    if (inheap(cp)) {
      if (what_to_collect == t_contiguous)
	mark_contblock(cp,body_size);
    }
    else x->fs.fs_self =
      (fatchar *) ((char *)copy_relblock(cp,body_size) + leader_size);
  }}}
   
void
siLfs_array_total_size()
{vs_top=vs_base+1;
  check_type_fat_string(&vs_base[0]);
 vs_base[0]=make_fixnum(vs_base[0]->fs.fs_dim);
}

void
siLfs_fill_pointer()
{vs_top=vs_base+1;
  check_type_fat_string(&vs_base[0]);
 vs_base[0]=make_fixnum(vs_base[0]->fs.fs_fillp);
}


void
siLset_fs_fill_pointer()
{check_arg(2);
 check_type_fat_string(&vs_base[0]);
 vs_top=vs_base+1;
 vs_base[0]->fs.fs_fillp = fix(vs_base[1]);
}


object
make_fat_string(dim,raw,lleng,staticp)
int dim,raw,lleng;
{object x;
 x=alloc_object(t_fat_string);
 vs_push(x);
 x->fs.fs_dim=dim;
 x->fs.fs_raw=raw;
 x->fs.fs_leader_length=lleng;
 x->fs.fs_fillp=0;
 alloc_fs(x,staticp);
 return x;
}

void
siLmake_fat_string()
{ register object *base;
 check_arg(4);
 base=vs_base;
 base[0]=make_fat_string (fix(base[0]),fix(base[1]),fix(base[2]),
			  (base[3]!=Cnil));
 vs_top=base+1;
}


alloc_fs(x,staticp)
object x; int staticp;
{char *cp, *actual_cp ;
 register object *obp;
 char *(*f)();
 int leader_size=sizeof(object *)*(x->fs.fs_leader_length);
 if (staticp)
   f = alloc_contblock;
 else
   f = alloc_relblock;
 obp=(object *)(cp= (*f)(sizeof(fatchar) * (x->fs.fs_dim)
			+leader_size));
 actual_cp=cp+leader_size;
 while(obp <  (object *) actual_cp)
   {*obp=Cnil;
    obp++;}
 x->fs.fs_self=(fatchar *)actual_cp;
}


object siLprofile_array;

void
siLprofile() /*(start-address scale) where scale is 0 <= n <= 256 */
{
object ar=siLprofile_array->s.s_dbind;
if (type_of(ar)!=t_string)
      FEerror("si:*Profile-array* not a string",0);
if((vs_top-vs_base != 2) ||
   type_of(vs_base[0])!=t_fixnum ||   type_of(vs_base[1])!=t_fixnum)
     FEerror("Needs start address and scale as args",0);
  profil((char *) (ar->ust.ust_self), (ar->ust.ust_dim),
       fix(vs_base[0]),fix(vs_base[1]) << 8);
}

void
siLfunction_start()
{check_arg(1);
 if(type_of(vs_base[0])!=t_cfun) FEerror("not compiled function",0);
 vs_base[0]=make_fixnum((int) (vs_base[0]->cf.cf_self));
}

/* begin fasl stuff*/

#include "ext_sym.h"
#ifdef AIX3
#include <sys/ldr.h>
char *data_load_addr =0;
#endif

read_special_symbols(symfile)
char *symfile;
{FILE *symin;
 char *symbols;
 int i,jj;
 struct lsymbol_table tab;
#ifdef AIX3
 {char buf[500];
  struct ld_info * ld;
 loadquery(L_GETINFO,buf,sizeof(buf));
  ld = (struct ld_info *)buf;
  data_load_addr = ld->ldinfo_dataorg ;}
#endif  
 if (!(symin=fopen(symfile,"r")))
   {perror(symfile);exit(1);};
 if(!fread((char *)&tab,sizeof(tab),1,symin))
   FEerror("No header",0);
 symbols=malloc(tab.tot_leng);
 c_table.alloc_length=( (PTABLE_EXTRA+ tab.n_symbols));
 (c_table.ptable) = (TABL *) malloc(sizeof(struct node) * c_table.alloc_length);
 if (!(c_table.ptable)) {perror("could not allocate"); exit(1);};
 i=0; c_table.length=tab.n_symbols;
 while(i < tab.n_symbols)
   { fread((char *)&jj,sizeof(int),1,symin);
#ifdef FIX_ADDRESS
     FIX_ADDRESS(jj);
#endif       
     (SYM_ADDRESS(c_table,i))=jj;
     SYM_STRING(c_table,i)=symbols;
 
     while( *(symbols++) =   getc(symin)) 
       {;}
/*     dprintf( name %s ,  SYM_STRING(c_table,i));
     dprintf( addr %d , jj);
*/
     i++;
   }

 /*
   for(i=0;i< 5;i++)
   {printf("Symbol: %d %s %d \n",i,SYM_STRINGN(c_table,i),
   SYM_ADDRESS(*ptable,i));}
   */
 if (symin) fclose(symin);
}

node_compare(node1,node2)
char *node1, *node2;
{ return(strcmp( ((struct node *)node1)->string,
	         ((struct node *)node2)->string));}


void
siLread_externals()
{check_arg(1);
 {object x=vs_base[0];
  unsigned int n;
  char *str;
  n=x->st.st_fillp;
 check_type_string(&x);
 str=malloc(n+1);
  str[n]=NULL;
 (void) strncpy(str,x->st.st_self,n);
 read_special_symbols(str);
  /* we sort them since these are used by the sfasl loader too */
qsort((char*)(c_table.ptable),(int)(c_table.length),sizeof(struct node),node_compare);
 free(str);}}

#define CFUN_LIM 10000

int maxpage;
object siLcdefn;

#define CF_FLAG (1 << 31) 


cfuns_to_combined_table(n) /* non zero n will ensure new table length */
unsigned int n;
{int ii=0;  
 STATIC int i, j;
 STATIC object x;
 STATIC char *p,*cf_addr;
 STATIC struct typemanager *tm;
 if (! (n || combined_table.ptable)) n=CFUN_LIM;
 if (n && combined_table.alloc_length < n)
   { 
     (combined_table.ptable)=NULL;
     (combined_table.ptable)= (TABL *)malloc(n* sizeof(struct node));
     if(!combined_table.ptable)
       FEerror("unable to allocate",0);
     combined_table.alloc_length=n;}

 for (i = 0;  i < maxpage;  i++) {
   if ((enum type)type_map[i]!=tm_table[(short)t_cfun].tm_type &&
       (enum type)type_map[i]!=tm_table[(short)t_gfun].tm_type &&
       (enum type)type_map[i]!=tm_table[(short)t_sfun].tm_type &&
       (enum type)type_map[i]!=tm_table[(short)t_vfun].tm_type
       )
     continue;
   tm = tm_of((enum type)type_map[i]);
   p = pagetochar(i);
   for (j = tm->tm_nppage; j > 0; --j, p += tm->tm_size) {
     x = (object)p;
     if (type_of(x)!=t_cfun &&
	 type_of(x)!=t_sfun &&
	 type_of(x)!=t_vfun &&
	 type_of(x)!=t_gfun
	 ) continue;
     if ((x->d.m == FREE) || x->cf.cf_self == NULL)
       continue;
	/* the cdefn things are the proclaimed call types. */
     cf_addr=(char * ) ((unsigned int)(x->cf.cf_self));
	
     SYM_ADDRESS(combined_table,ii)=(unsigned int)cf_addr;
     SYM_STRING(combined_table,ii)= (char *)(CF_FLAG | (unsigned int)x) ;
/*       (x->cf.cf_name ? x->cf.cf_name->s.st_self : NULL) ; */
     combined_table.length = ++ii;
     if (ii >= combined_table.alloc_length)
       FEerror("Need a larger combined_table",0);
   }
		
 }
}

address_node_compare(node1,node2)
char *node1, *node2;
{unsigned int a1,a2;
 a1=((struct node *)node1)->address;
 a2=((struct node *)node2)->address;
 if (a1> a2) return 1;
 if (a1< a2) return -1;
 return 0;
}
 

void
siLset_up_combined()
{unsigned int n=0;
 if (((vs_top - vs_base) == 1)&&type_of(vs_base[0])==t_fixnum)
   n = (unsigned int) fix(vs_base[0]);
 cfuns_to_combined_table(n);
 if (c_table.ptable)
   {int j,k;
    if((k=combined_table.length)+c_table.length >=
       combined_table.alloc_length)
      cfuns_to_combined_table(combined_table.length+c_table.length +20);
    for(j = 0; j < c_table.length;)
    { SYM_ADDRESS(combined_table,k) =SYM_ADDRESS(c_table,j);
      SYM_STRING(combined_table,k) =SYM_STRING(c_table,j);
      k++;j++;
    };
    combined_table.length += c_table.length ;}
 qsort((char*)combined_table.ptable,(int)combined_table.length,
       sizeof(struct node),address_node_compare);
}

static int  prof_start;
prof_ind(address,scale)
     unsigned int address;
{address = address - prof_start ;
 if (address > 0) return ((address * scale) >> 8) ;
 return 0;
}

/* sum entries AAR up to DIM entries */
string_sum(aar,dim)
register unsigned char *aar;
unsigned int dim;
{register unsigned char *endar;
 register unsigned int count = 0;
endar=aar+dim;
 for ( ; aar< endar; aar++)
   count += *aar;
 return count;
}

void
siLdisplay_profile()
{if (!combined_table.ptable)
   FEerror("must symbols first",0);
   check_arg(2);
   {unsigned int prev,next,upto,dim,total;
    int j,scale,count;
    unsigned char *ar;
    object obj_ar;
    obj_ar=siLprofile_array->s.s_dbind;
    if (type_of(obj_ar)!=t_string)
      FEerror("si:*Profile-array* not a string",0);
    ar=obj_ar->ust.ust_self;
    scale=fix(vs_base[1]);
    prof_start=fix(vs_base[0]);
    vs_top=vs_base;
    dim= (obj_ar->ust.ust_dim);

    total=string_sum(ar,dim);
  
    j=0;
    {int i, finish = combined_table.length-1;
     for(i =0,prev=SYM_ADDRESS(combined_table,i); i< finish;
	 prev=next)
       { ++i;
	 next=SYM_ADDRESS(combined_table,i);
	 if ( prev < prof_start) continue;
	 upto=prof_ind(next,scale);
	 if (upto >= dim) upto=dim;
	 {char *name; unsigned int uname;
	  count=0;
	  for( ; j<upto;j++)
	    count += ar[j];
	  if (count > 0) {
	    name=SYM_STRING(combined_table,i-1);
	    uname = (unsigned int) name;
	    printf("\n%6.2f%% (%5d): ",(100.0*count)/total, count);
	    fflush(stdout);
	    if (CF_FLAG & uname)
	      {if (~CF_FLAG & uname) prin1( ((object) (~CF_FLAG & uname))->cf.cf_name,Cnil);}
	     else if (name ) printf("%s",name);};
	  if (upto==dim) goto TOTALS ;
	  
	}}}
 TOTALS:
  printf("\nTotal ticks %d",total);fflush(stdout);
}}

#ifdef SFASL
int build_symbol_table();
#endif


/* end fasl stuff*/


/* These are some low level hacks to allow determining the address
   of an array body, and to allow jumping to inside the body
   of the array */

siLarray_adress()
{check_arg(1);
 vs_base[0]=make_fixnum((int) (&(vs_base[0]->st.st_self[0])));
}

/* This is some very low level code for hacking invokation of
   m68k instructions in a lisp array.  The index used should be
   a byte index.  So invoke(ar,3) jmps to byte ar+3.
   */

#ifdef CLI

invoke(ar)
char *ar;
{asm("movel a6@(8),a0");
 asm("jmp a0@");
}
/* save regs (2 3 4 5 6 7  10 11 12 13 14) and invoke restoring them */
save_regs_invoke(ar)
char *ar;
{asm("moveml #0x3f3e,sp@-");
 invoke(ar);
 asm("moveml a6@(-44),#0x7cfc");
}
siLsave_regs_invoke()
{int x;
 check_arg(2);
  check_type_integer(&vs_base[1]);
  x=save_regs_invoke((vs_base[0]->st.st_self)+fix(vs_base[1]));
 vs_top=vs_base+1;
 vs_base[0]=make_fixnum(x);
}


#endif

init_fat_string()
{make_si_function("ARRAY-ADDRESS",siLarray_adress);
#ifdef CLI
 make_si_function("SAVE-REGS-INVOKE",siLsave_regs_invoke);
#endif 
 make_si_function("FSREF",siLfsref);
 make_si_function("FSSET",siLfsset);
 make_si_function("FS-LEADER-REF",siLfs_leader_ref);
 make_si_function("FS-LEADER-SET",siLfs_leader_set);
 make_si_function("FIXNUM-FS-LEADER-SET",siLfixnum_fs_leader_set);
 make_si_function("FIXNUM-FS-LEADER-REF",siLfixnum_fs_leader_ref);
 make_si_function("SET-FS-FILL-POINTER",siLset_fs_fill_pointer);
 make_si_function("FS-ARRAY-TOTAL-SIZE",siLfs_array_total_size);
 make_si_function("FS-FILL-POINTER",siLfs_fill_pointer);
 make_si_function("MAKE-FAT-STRING",siLmake_fat_string);
 make_si_function("FUNCTION-START",siLfunction_start);
 make_si_function("PROFILE",siLprofile);
 make_si_function("READ-EXTERNALS",siLread_externals);
 make_si_function("SET-UP-COMBINED",siLset_up_combined);
 make_si_function("DISPLAY-PROFILE",siLdisplay_profile);
 make_si_constant("*ASH->>*",(-1==(((int)-1) >> 50))? Ct :Cnil);
#ifdef SFASL
 make_si_function("BUILD-SYMBOL-TABLE",build_symbol_table);
#endif
 siLprofile_array=make_si_special("*PROFILE-ARRAY*",Cnil);
 Sfat_string = make_ordinary("FAT-STRING");
 enter_mark_origin(&Sfat_string);
 init_fasdump();
 
}







These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.