⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 skeleton.c

📁 OXCC is a multipass, interpreting C compiler with several language extensions. It generates an Archi
💻 C
📖 第 1 页 / 共 4 页
字号:
SKIPVARS;
unsigned cursize;
unsigned *address;
struct _bins *bp;
NodePM onode;

	if(addr == 0) 
		return mallocC(category, newsize);
	else
	{
		if(!(bp = getcat(category))) {
		   VCRASH("reallocC:%d: non-existant category at:%x\n",category,addr);
		}
HEAPCHECK 
		if(newsize == 0)
			newsize = ALIGNMENTM;
		else
			newsize += ROUNDINGM(newsize);
		newsize += bp->guarded;

		address = (void*)(((char*)addr)-(bp->guarded/2));
		FINDKEY(USEDH, (unsigned)address)
		if(node->key != (unsigned)address) {
		  VCRASH("reallocC:%d: bogus address=0x%x\n", category, addr);
		}
		cursize = node->value;
		node->value = newsize;
		onode = node;

		CHECKGUARDS(reallocC)

		if(newsize == cursize)
			return addr;
		if(newsize > cursize)
		{/* check if block can be extended */
		void *taddr = ((char*)address) + cursize;
		unsigned extendsize = newsize-cursize;

			/* check freelist for an available block at the right address */
			FINDKEY(FREEH, (unsigned)taddr)
			if(node->key == (unsigned)taddr)
			{
			AddrP sp = (AddrP)node->value;
				if(sp->size >= extendsize)
				{/* BLOCK CAN BE EXTENDED INTERNALLY */
					node->key += extendsize;
					sp->size -= extendsize;
					DETACH(sp)
					if(sp->size == 0)
					{/* the extension block is used up, delete this node */
						free_addr(bp, sp);
						DELETENODE(FREEH)
					}
					else
					{/* shift the remainder in the sizelist */
						addto_sizelist(bp, sp);
					}
					/* SUCCESS */
					if(bp->guarded)
					{
						*((unsigned*)(((char*)address)+newsize-ALIGNMENTM))
							= BACKGUARD;
					}
					return addr;
				}
			}
			/* HERE WE COULD CHECK OTHER SOURCES OF SPACE */

			/* can't extend block, malloc some new space */
			if((taddr = mallocC(category,newsize-bp->guarded)))
			{
				memmove(taddr,addr,cursize-bp->guarded);
				onode->value = cursize;
				freeC(category, addr);
			}
			/* SUCCESS */
			return taddr;
		}
		else
		{/* shrink block */
			if(bp->guarded)
			{
				*((unsigned*)(((char*)address)+newsize-ALIGNMENTM))
					= BACKGUARD;
			}
			addto_freelist(bp, ((char*)address)+newsize, cursize-newsize); 
			return addr;
		}
  	}
}
void
freecat(int category)
{
struct _bins *bp;

	if(category == 0)
		return;

	if((bp = getcat(category)))
	{
	struct _catlocs *cl = bp->catlocs;
	struct _bins *hbp;
	struct _bins *prev;

		while(cl)
		{/* Space allocated to the category is moved to category 0 */
		void *ql = cl->fptr;

			freeC(0, cl->addr);
			free_catloc(cl);
			cl = ql;
		}
		/* space for the _bins struct is placed on a free list */
		hbp = hmap[category % 1009];
		prev = 0;
		while(hbp)
		{
			if(hbp->bincat == category)
			{
				if(prev == 0)
					hmap[category % 1009] = hbp->fptr;
				else
					prev->fptr = hbp->fptr;
				free_bins(hbp);
				return;
			}
			prev = hbp;
			hbp = hbp->fptr;
		}
	}
}
int
memrangeC(int category, unsigned *min, unsigned *max)
{
struct _bins *bp;

	if((bp = getcat(category)))
	{
		*min = bp->minloc;
		*max = bp->maxloc;
		return 1;
	}
	return 0;
}
int
usedrangeC(int category, unsigned *min, unsigned *max)
{
struct _bins *bp;
NodePM node;
int level;

	if((bp = getcat(category)))
	{
		node = bp->USEDHheader;
		*min = node->fptr[0]->key;
		for(level = bp->USEDHlevel; level >= 0; level--)
		  while(node->fptr[level]->key < 0xffffffff)
			node = node->fptr[level];
		*max = node->key;
		return 1;
	}
	return 0;
}
void
totrangeC(unsigned *min, unsigned *max)
{
	*min = minloc;
	*max = maxloc;
}
void
guardC(int category)
{
struct _bins *bp;

	if(!(bp = getcat(category)))
	  if(!(bp = initcat(category)))
		  return;

	if(!bp->guarded)
	{
		bp->guarded = 2*ALIGNMENTM;
		bp->addrbump = 1;
	}
}
void*
heapcheckC(int category, void *start)
{
struct _bins *bp;
NodePM node,prev;
unsigned *p1,*p2;

	if((bp = getcat(category)))
	{
		if(bp->guarded)
		{
			prev = 0;
			node = bp->USEDHheader;
			while(		(node = node->fptr[0]) != (NodePM)0xffffffff
					&&	node->key != 0xffffffffUL)
			{
				if((void*)node->key > start)
				{
					p1 = (unsigned*)node->key;
					if(*p1 != FRNTGUARD)
					{
						if(prev)
							return (char*)prev->key+ALIGNMENTM;
						else
							return (void*)1;
					}
					p2 = (unsigned*)(((char*)p1)+node->value-ALIGNMENTM);
					if(*p2 != BACKGUARD)
						return (char*)node->key+ALIGNMENTM;
				}
				prev = node;
			}
		}
	}
	return 0;
}
void* 
mallocC(int category, unsigned size)
{
	return memalignC(category, 0, size);
}

void* 
vallocC(int category, unsigned bytes)
{
  return memalignC (category, PAGESIZE, bytes);
}
unsigned
mallocsizeC(int category, void* addr)
{
struct _bins *bp;
SKIPVARS;

	if(addr && (bp = getcat(category)))
	{
	unsigned address = (unsigned)((unsigned*)addr - bp->addrbump);
		FINDKEY(USEDH, address)
		if(node->key == address)
			return node->value - bp->guarded;
	}
	return 0;
}

int
NewMallocCategory(void)
{
static unsigned int cat = BASE_CATEGORY;
	return ++cat;
}
/* ====================== END MULTI-HEAP MALLOC ============================ */


/* These are here to prevent the system malloc from being linked */
void *
malloc(unsigned a)
{
void *result = mallocC(BASE_CATEGORY, a);
MPRINTF("malloc %d bytes at %p caller=%x\n", a, result, ((unsigned *)&a)[-1]);
	return result;
}
void
free(void *a)
{
MPRINTF("free at %p caller=%x\n", a, ((unsigned*)&a)[-1]);
	freeC(BASE_CATEGORY,a);
}
void *
realloc(void *a, unsigned b)
{
void *result = reallocC(BASE_CATEGORY,a,b);
MPRINTF("realloc %d bytes at %p old=%p caller=%x\n",
	b, result, a, ((unsigned*)&a)[-1]);
	return result;
}
void *
calloc(unsigned a, unsigned b)
{
void *result = callocC(BASE_CATEGORY,a,b);
MPRINTF("calloc %d bytes at %p caller=%x\n", a*b, result, ((unsigned*)&a)[-1]);
	return result;
}
void *
valloc(unsigned a)
{
void *result = vallocC(BASE_CATEGORY,a);
MPRINTF("valloc %d bytes at %p caller=%x\n", a, result, ((unsigned *)&a)[-1]);
	return result;
}
void *
memalign(unsigned a, unsigned b)
{
void *result = memalignC(BASE_CATEGORY,a,b);
MPRINTF("memalign(%u) %u bytes at %p caller=%x\n",
	a,b,result,((unsigned *)&a)[-1]);
	return result;
}
unsigned
mallocsize(void *a)
{
	return mallocsizeC(BASE_CATEGORY, a);
}

static int 
lnulfunc()
{
	return 0;
}
static void 
lhash(void *keyptr, int cnt, CAT *cat)
{/* THIS FUNCTION IS IDENTICAL TO 'key_hash' in CFF */
STOR  value;
int  i;

	cat->c0.item = 0;

	if(cnt <= 8)
		for (i = 0; i < cnt; ++i)
			cat->c0.a5.b[i] = *((unsigned char *)keyptr)++;
	else
		for (i = 0; i < cnt; ++i)
			cat->c0.a5.b[i&7] ^= *((unsigned char *)keyptr)++;

	/* THE CONSTANTS WERE CAREFULLY CHOSEN BY THEORY */
	/* value.item is a long long (use gcc only) */

	value.item = ((1103515245LL)*(cat->c0.a4.s0 ^ cat->c0.a4.s1))+453816693LL;
	if(value.a0 == 0) value.a0 = 1;
	value.a0 &= 0x0fffffff;
	if(cnt <= 8) value.a0 |= 0x80000000;	/* exact key chunk */
	cat->c1.a0 = value.a0;
}
static int linkup_complete;
static int
laccess(char *a, int b)
{/* suppress use of 'access', it links in too many other functions */

	if(linkup_complete)
		return ((VOBTYPE(a) & (OB_XFILE|OB_TREEDIR|OB_HASHDIR)) ? 0 : 1);
	else {
	int fd = VOPEN(a,O_RDONLY|O_BINARY);
		if(fd > 0)
		{
			VCLOSE(fd);
			return 0;
		}
		return 1;
	}
}
static int
lpagesize()
{
	return 4096;
}
static int
lprintchar(int c)
{
	return VWRITE(1,&c,1);
}
static void
lprintstr(char *str)
{
	while(*str)
		lprintchar(*str++);
}

#if EARLY_PRINT == 1

struct parameters
{
  int number_of_output_chars;
  int (*output_function)(void *, int);
  void *output_pointer;
  short minimum_field_width;
  short edited_string_length;
  short leading_zeros;
  char options;
    #define MINUS_SIGN    1
    #define RIGHT_JUSTIFY 2
    #define ZERO_PAD      4
    #define CAPITAL_HEX   8
};

static void output_and_count(struct parameters *p, int c)
{
  if (p->number_of_output_chars >= 0)
  {
    int n = (*p->output_function)(p->output_pointer, c);
    if (n>=0) p->number_of_output_chars++;
    else p->number_of_output_chars = n;
  }
}

static void output_field(struct parameters *p, char *s)
{
  short justification_length =
    p->minimum_field_width - p->leading_zeros - p->edited_string_length;
  if (p->options & MINUS_SIGN)
  {
    if (p->options & ZERO_PAD)
      output_and_count(p, '-');
    justification_length--;
  }
  if (p->options & RIGHT_JUSTIFY)
    while (--justification_length >= 0)
      output_and_count(p, p->options & ZERO_PAD ? '0' : ' ');
  if (p->options & MINUS_SIGN && !(p->options & ZERO_PAD))
    output_and_count(p, '-');
  while (--p->leading_zeros >= 0)
    output_and_count(p, '0');
  while (--p->edited_string_length >= 0)
    output_and_count(p, *s++);
  while (--justification_length >= 0)
    output_and_count(p, ' ');
}
    

static int 
gprintf(int (*output_function)(void *, int), void *output_pointer,
  char *control_string, int *argument_pointer)
{
  struct parameters p;
  char control_char;
  p.number_of_output_chars = 0;
  p.output_function = output_function;
  p.output_pointer = output_pointer;
  control_char = *control_string++;
  while (control_char != '\0')
  {
    if (control_char == '%')
    {
      short precision = -1;
      short long_argument = 0;
      short base = 0;
      control_char = *control_string++;
      p.minimum_field_width = 0;
      p.leading_zeros = 0;
      p.options = RIGHT_JUSTIFY;
      if (control_char == '-')
      {
        p.options = 0;
        control_char = *control_string++;
      }
      if (control_char == '0')
      {
        p.options |= ZERO_PAD;
        control_char = *control_string++;
      }
      if (control_char == '*')
      {
        p.minimum_field_width = *argument_pointer++;
        control_char = *control_string++;
      }
      else
      {
        while ('0' <= control_char && control_char <= '9')
        {
          p.minimum_field_width =
            p.minimum_field_width * 10 + control_char - '0';
          control_char = *control_string++;
        }
      }
      if (control_char == '.')
      {
        control_char = *control_string++;
        if (control_char == '*')
        {
          precision = *argument_pointer++;
          control_char = *control_string++;
        }
        else
        {
          precision = 0;
          while ('0' <= control_char && control_char <= '9')
          {
            precision = precision * 10 + control_char - '0';
            control_char = *control_string++;
          }
        }
      }
      if (control_char == 'l')
      {
        long_argument = 1;
        control_char = *control_string++;
      }
      if (control_char == 'd')
        base = 10;
      else if (control_char == 'x' || control_char == 'p')
        base = 16;
      else if (control_char == 'X')
      {
        base = 16;
        p.options |= CAPITAL_HEX;
      }
      else if (control_char == 'u')
        base = 10;
      else if (control_char == 'o')
        base = 8;
      else if (control_char == 'b')
        base = 2;
      else if (control_char == 'c')
      {
        base = -1;
        p.options &= ~ZERO_PAD;
      }
      else if (control_char == 's')
      {
        base = -2;
        p.options &= ~ZERO_PAD;
      }
      if (base == 0)  /* invalid conversion type */
      {
        if (control_char != '\0')
        {
          output_and_count(&p, control_char);
          control_char = *control_string++;
        }
      }
      else
      {
        if (base == -1)  /* conversion type c */
        {
          char c = *argument_pointer++;
          p.edited_string_length = 1;
          output_field(&p, &c);
        }
        else if (base == -2)  /* conversion type s */
        {
          char *string;
          p.edited_string_length = 0;
          string = * (char **) argument_pointer;
          argument_pointer += sizeof(char *) / sizeof(int);
          while (string[p.edited_string_length] != 0)
            p.edited_string_length++;
          if (precision >= 0 && p.edited_string_length > precision)
            p.edited_string_length = precision;
          output_field(&p, string);
        }
        else  /* conversion type d, b, o or x */
        {
          unsigned long x;
          char buffer[64];
          p.edited_string_length = 0;
          if (long_argument) 
          {
            x = * (unsigned long *) argument_pointer;
            argument_pointer += sizeof(unsigned long) / sizeof(int);
          }
          else if (control_char == 'd')
            x = (long) *argument_pointer++;
          else
            x = (unsigned) *argument_pointer++;
          if (control_char == 'd' && (long) x < 0)
          {
            p.options |= MINUS_SIGN;
            x = - (long) x;
          }
          do 
          {
            int c;
            c = x % base + '0';
            if (c > '9')
            {
              if (p.options & CAPITAL_HEX)
                c += 'A'-'9'-1;
              else
                c += 'a'-'9'-1;
            }
            buffer[sizeof(buffer) - 1 - p.edited_string_length++] = c;
          }
          while ((x/=base) != 0);
          if (precision >= 0 && precision > p.edited_string_length)
            p.leading_zeros = precision - p.edited_string_length;
          output_field(&p, buffer + sizeof(buffer) - p.edited_string_length);
        }
        control_char = *control_string++;
      }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -