xref: /onnv-gate/usr/src/lib/libast/common/misc/stk.c (revision 12068:08a39a083754)
14887Schin /***********************************************************************
24887Schin *                                                                      *
34887Schin *               This software is part of the ast package               *
4*12068SRoger.Faulkner@Oracle.COM *          Copyright (c) 1985-2010 AT&T Intellectual Property          *
54887Schin *                      and is licensed under the                       *
64887Schin *                  Common Public License, Version 1.0                  *
78462SApril.Chin@Sun.COM *                    by AT&T Intellectual Property                     *
84887Schin *                                                                      *
94887Schin *                A copy of the License is available at                 *
104887Schin *            http://www.opensource.org/licenses/cpl1.0.txt             *
114887Schin *         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
124887Schin *                                                                      *
134887Schin *              Information and Software Systems Research               *
144887Schin *                            AT&T Research                             *
154887Schin *                           Florham Park NJ                            *
164887Schin *                                                                      *
174887Schin *                 Glenn Fowler <gsf@research.att.com>                  *
184887Schin *                  David Korn <dgk@research.att.com>                   *
194887Schin *                   Phong Vo <kpv@research.att.com>                    *
204887Schin *                                                                      *
214887Schin ***********************************************************************/
224887Schin #pragma prototyped
234887Schin /*
244887Schin  *   Routines to implement a stack-like storage library
254887Schin  *
264887Schin  *   A stack consists of a link list of variable size frames
274887Schin  *   The beginning of each frame is initialized with a frame structure
284887Schin  *   that contains a pointer to the previous frame and a pointer to the
294887Schin  *   end of the current frame.
304887Schin  *
314887Schin  *   This is a rewrite of the stk library that uses sfio
324887Schin  *
334887Schin  *   David Korn
344887Schin  *   AT&T Research
354887Schin  *   dgk@research.att.com
364887Schin  *
374887Schin  */
384887Schin 
394887Schin #include	<sfio_t.h>
404887Schin #include	<ast.h>
414887Schin #include	<align.h>
424887Schin #include	<stk.h>
434887Schin 
444887Schin /*
454887Schin  *  A stack is a header and a linked list of frames
464887Schin  *  The first frame has structure
474887Schin  *	Sfio_t
484887Schin  *	Sfdisc_t
494887Schin  *	struct stk
504887Schin  * Frames have structure
514887Schin  *	struct frame
524887Schin  *	data
534887Schin  */
544887Schin 
554887Schin #define STK_ALIGN	ALIGN_BOUND
564887Schin #define STK_FSIZE	(1024*sizeof(int))
574887Schin #define STK_HDRSIZE	(sizeof(Sfio_t)+sizeof(Sfdisc_t))
584887Schin 
594887Schin typedef char* (*_stk_overflow_)(int);
604887Schin 
614887Schin static int stkexcept(Sfio_t*,int,void*,Sfdisc_t*);
624887Schin static Sfdisc_t stkdisc = { 0, 0, 0, stkexcept };
634887Schin 
644887Schin Sfio_t _Stak_data = SFNEW((char*)0,0,-1,SF_STATIC|SF_WRITE|SF_STRING,&stkdisc,0);
654887Schin 
664887Schin __EXTERN__(Sfio_t, _Stak_data);
674887Schin 
684887Schin struct frame
694887Schin {
704887Schin 	char	*prev;		/* address of previous frame */
714887Schin 	char	*end;		/* address of end this frame */
724887Schin 	char	**aliases;	/* address aliases */
734887Schin 	int	nalias;		/* number of aliases */
744887Schin };
754887Schin 
764887Schin struct stk
774887Schin {
784887Schin 	_stk_overflow_	stkoverflow;	/* called when malloc fails */
794887Schin 	short		stkref;	/* reference count; */
804887Schin 	short		stkflags;	/* stack attributes */
814887Schin 	char		*stkbase;	/* beginning of current stack frame */
824887Schin 	char		*stkend;	/* end of current stack frame */
834887Schin };
844887Schin 
854887Schin static int		init;		/* 1 when initialized */
864887Schin static struct stk	*stkcur;	/* pointer to current stk */
874887Schin static char		*stkgrow(Sfio_t*, unsigned);
884887Schin 
894887Schin #define stream2stk(stream)	((stream)==stkstd? stkcur:\
904887Schin 				 ((struct stk*)(((char*)(stream))+STK_HDRSIZE)))
914887Schin #define stk2stream(sp)		((Sfio_t*)(((char*)(sp))-STK_HDRSIZE))
924887Schin #define stkleft(stream)		((stream)->_endb-(stream)->_data)
934887Schin 
944887Schin 
954887Schin #ifdef STKSTATS
964887Schin     static struct
974887Schin     {
984887Schin 	int	create;
994887Schin 	int	delete;
1004887Schin 	int	install;
1014887Schin 	int	alloc;
1024887Schin 	int	copy;
1034887Schin 	int	puts;
1044887Schin 	int	seek;
1054887Schin 	int	set;
1064887Schin 	int	grow;
1074887Schin 	int	addsize;
1084887Schin 	int	delsize;
1094887Schin 	int	movsize;
1104887Schin     } _stkstats;
1114887Schin #   define increment(x)	(_stkstats.x++)
1124887Schin #   define count(x,n)	(_stkstats.x += (n))
1134887Schin #else
1144887Schin #   define increment(x)
1154887Schin #   define count(x,n)
1164887Schin #endif /* STKSTATS */
1174887Schin 
1184887Schin static const char Omsg[] = "malloc failed while growing stack\n";
1194887Schin 
1204887Schin /*
1214887Schin  * default overflow exception
1224887Schin  */
overflow(int n)1234887Schin static char *overflow(int n)
1244887Schin {
1254887Schin 	NoP(n);
1264887Schin 	write(2,Omsg, sizeof(Omsg)-1);
1274887Schin 	exit(2);
1284887Schin 	/* NOTREACHED */
1294887Schin 	return(0);
1304887Schin }
1314887Schin 
1324887Schin /*
1334887Schin  * initialize stkstd, sfio operations may have already occcured
1344887Schin  */
stkinit(int size)1354887Schin static void stkinit(int size)
1364887Schin {
1374887Schin 	register Sfio_t *sp;
1384887Schin 	init = size;
1394887Schin 	sp = stkopen(0);
1404887Schin 	init = 1;
1414887Schin 	stkinstall(sp,overflow);
1424887Schin }
1434887Schin 
stkexcept(register Sfio_t * stream,int type,void * val,Sfdisc_t * dp)1444887Schin static int stkexcept(register Sfio_t *stream, int type, void* val, Sfdisc_t* dp)
1454887Schin {
1464887Schin 	NoP(dp);
1474887Schin 	NoP(val);
1484887Schin 	switch(type)
1494887Schin 	{
1504887Schin 	    case SF_CLOSING:
1514887Schin 		{
1524887Schin 			register struct stk *sp = stream2stk(stream);
1534887Schin 			register char *cp = sp->stkbase;
1544887Schin 			register struct frame *fp;
1554887Schin 			if(--sp->stkref<=0)
1564887Schin 			{
1574887Schin 				increment(delete);
1584887Schin 				if(stream==stkstd)
1594887Schin 					stkset(stream,(char*)0,0);
1604887Schin 				else
1614887Schin 				{
1624887Schin 					while(1)
1634887Schin 					{
1644887Schin 						fp = (struct frame*)cp;
1654887Schin 						if(fp->prev)
1664887Schin 						{
1674887Schin 							cp = fp->prev;
1684887Schin 							free(fp);
1694887Schin 						}
1704887Schin 						else
1714887Schin 						{
1724887Schin 							free(fp);
1734887Schin 							break;
1744887Schin 						}
1754887Schin 					}
1764887Schin 				}
1774887Schin 			}
1784887Schin 			stream->_data = stream->_next = 0;
1794887Schin 		}
1804887Schin 		return(0);
1814887Schin 	    case SF_FINAL:
1824887Schin 		free(stream);
1834887Schin 		return(1);
1844887Schin 	    case SF_DPOP:
1854887Schin 		return(-1);
1864887Schin 	    case SF_WRITE:
1874887Schin 	    case SF_SEEK:
1884887Schin 		{
1894887Schin 			long size = sfvalue(stream);
1904887Schin 			if(init)
1914887Schin 			{
1924887Schin 				Sfio_t *old = 0;
1934887Schin 				if(stream!=stkstd)
1944887Schin 					old = stkinstall(stream,NiL);
1954887Schin 				if(!stkgrow(stkstd,size-(stkstd->_endb-stkstd->_data)))
1964887Schin 					return(-1);
1974887Schin 				if(old)
1984887Schin 					stkinstall(old,NiL);
1994887Schin 			}
2004887Schin 			else
2014887Schin 				stkinit(size);
2024887Schin 		}
2034887Schin 		return(1);
2044887Schin 	    case SF_NEW:
2054887Schin 		return(-1);
2064887Schin 	}
2074887Schin 	return(0);
2084887Schin }
2094887Schin 
2104887Schin /*
2114887Schin  * create a stack
2124887Schin  */
stkopen(int flags)2134887Schin Sfio_t *stkopen(int flags)
2144887Schin {
2154887Schin 	register int bsize;
2164887Schin 	register Sfio_t *stream;
2174887Schin 	register struct stk *sp;
2184887Schin 	register struct frame *fp;
2194887Schin 	register Sfdisc_t *dp;
2204887Schin 	register char *cp;
2214887Schin 	if(!(stream=newof((char*)0,Sfio_t, 1, sizeof(*dp)+sizeof(*sp))))
2224887Schin 		return(0);
2234887Schin 	increment(create);
2244887Schin 	count(addsize,sizeof(*stream)+sizeof(*dp)+sizeof(*sp));
2254887Schin 	dp = (Sfdisc_t*)(stream+1);
2264887Schin 	dp->exceptf = stkexcept;
2274887Schin 	sp = (struct stk*)(dp+1);
2284887Schin 	sp->stkref = 1;
2294887Schin 	sp->stkflags = (flags&STK_SMALL);
2304887Schin 	if(flags&STK_NULL) sp->stkoverflow = 0;
2314887Schin 	else sp->stkoverflow = stkcur?stkcur->stkoverflow:overflow;
2324887Schin 	bsize = init+sizeof(struct frame);
2334887Schin #ifndef USE_REALLOC
2344887Schin 	if(flags&STK_SMALL)
2354887Schin 		bsize = roundof(bsize,STK_FSIZE/16);
2364887Schin 	else
2374887Schin #endif /* USE_REALLOC */
2384887Schin 		bsize = roundof(bsize,STK_FSIZE);
2394887Schin 	bsize -= sizeof(struct frame);
2404887Schin 	if(!(fp=newof((char*)0,struct frame, 1,bsize)))
2414887Schin 	{
2424887Schin 		free(stream);
2434887Schin 		return(0);
2444887Schin 	}
2454887Schin 	count(addsize,sizeof(*fp)+bsize);
2464887Schin 	cp = (char*)(fp+1);
2474887Schin 	sp->stkbase = (char*)fp;
2484887Schin 	fp->prev = 0;
2494887Schin 	fp->nalias = 0;
2504887Schin 	fp->aliases = 0;
2514887Schin 	fp->end = sp->stkend = cp+bsize;
2524887Schin 	if(!sfnew(stream,cp,bsize,-1,SF_STRING|SF_WRITE|SF_STATIC|SF_EOF))
2534887Schin 		return((Sfio_t*)0);
2544887Schin 	sfdisc(stream,dp);
2554887Schin 	return(stream);
2564887Schin }
2574887Schin 
2584887Schin /*
2594887Schin  * return a pointer to the current stack
2604887Schin  * if <stream> is not null, it becomes the new current stack
2614887Schin  * <oflow> becomes the new overflow function
2624887Schin  */
stkinstall(Sfio_t * stream,_stk_overflow_ oflow)2634887Schin Sfio_t *stkinstall(Sfio_t *stream, _stk_overflow_ oflow)
2644887Schin {
2654887Schin 	Sfio_t *old;
2664887Schin 	register struct stk *sp;
2674887Schin 	if(!init)
2684887Schin 	{
2694887Schin 		stkinit(1);
2704887Schin 		if(oflow)
2714887Schin 			stkcur->stkoverflow = oflow;
2724887Schin 		return((Sfio_t*)0);
2734887Schin 	}
2744887Schin 	increment(install);
2754887Schin 	old = stkcur?stk2stream(stkcur):0;
2764887Schin 	if(stream)
2774887Schin 	{
2784887Schin 		sp = stream2stk(stream);
2794887Schin 		while(sfstack(stkstd, SF_POPSTACK));
2804887Schin 		if(stream!=stkstd)
2814887Schin 			sfstack(stkstd,stream);
2824887Schin 		stkcur = sp;
2834887Schin #ifdef USE_REALLOC
2844887Schin 		/*** someday ***/
2854887Schin #endif /* USE_REALLOC */
2864887Schin 	}
2874887Schin 	else
2884887Schin 		sp = stkcur;
2894887Schin 	if(oflow)
2904887Schin 		sp->stkoverflow = oflow;
2914887Schin 	return(old);
2924887Schin }
2934887Schin 
2944887Schin /*
2954887Schin  * increase the reference count on the given <stack>
2964887Schin  */
stklink(register Sfio_t * stream)2974887Schin int stklink(register Sfio_t* stream)
2984887Schin {
2994887Schin 	register struct stk *sp = stream2stk(stream);
3004887Schin 	return(sp->stkref++);
3014887Schin }
3024887Schin 
3034887Schin /*
3044887Schin  * terminate a stack and free up the space
3054887Schin  * >0 returned if reference decremented but still > 0
3064887Schin  *  0 returned on last close
3074887Schin  * <0 returned on error
3084887Schin  */
stkclose(Sfio_t * stream)3094887Schin int stkclose(Sfio_t* stream)
3104887Schin {
3114887Schin 	register struct stk *sp = stream2stk(stream);
3124887Schin 	if(sp->stkref>1)
3134887Schin 	{
3144887Schin 		sp->stkref--;
3154887Schin 		return(1);
3164887Schin 	}
3174887Schin 	return(sfclose(stream));
3184887Schin }
3194887Schin 
3204887Schin /*
3218462SApril.Chin@Sun.COM  * returns 1 if <loc> is on this stack
3228462SApril.Chin@Sun.COM  */
stkon(register Sfio_t * stream,register char * loc)3238462SApril.Chin@Sun.COM int stkon(register Sfio_t * stream, register char* loc)
3248462SApril.Chin@Sun.COM {
3258462SApril.Chin@Sun.COM 	register struct stk *sp = stream2stk(stream);
3268462SApril.Chin@Sun.COM 	register struct frame *fp;
3278462SApril.Chin@Sun.COM 	for(fp=(struct frame*)sp->stkbase; fp; fp=(struct frame*)fp->prev)
3288462SApril.Chin@Sun.COM 		if(loc>=((char*)(fp+1)) && loc< fp->end)
3298462SApril.Chin@Sun.COM 			return(1);
3308462SApril.Chin@Sun.COM 	return(0);
3318462SApril.Chin@Sun.COM }
3328462SApril.Chin@Sun.COM /*
3334887Schin  * reset the bottom of the current stack back to <loc>
3344887Schin  * if <loc> is not in this stack, then the stack is reset to the beginning
3354887Schin  * otherwise, the top of the stack is set to stkbot+<offset>
3364887Schin  *
3374887Schin  */
stkset(register Sfio_t * stream,register char * loc,unsigned offset)3384887Schin char *stkset(register Sfio_t * stream, register char* loc, unsigned offset)
3394887Schin {
3404887Schin 	register struct stk *sp = stream2stk(stream);
3414887Schin 	register char *cp;
3424887Schin 	register struct frame *fp;
3434887Schin 	register int frames = 0;
3444887Schin 	int n;
3454887Schin 	if(!init)
3464887Schin 		stkinit(offset+1);
3474887Schin 	increment(set);
3484887Schin 	while(1)
3494887Schin 	{
3504887Schin 		fp = (struct frame*)sp->stkbase;
3514887Schin 		cp  = sp->stkbase + roundof(sizeof(struct frame), STK_ALIGN);
3524887Schin 		n = fp->nalias;
3534887Schin 		while(n-->0)
3544887Schin 		{
3554887Schin 			if(loc==fp->aliases[n])
3564887Schin 			{
3574887Schin 				loc = cp;
3584887Schin 				break;
3594887Schin 			}
3604887Schin 		}
3614887Schin 		/* see whether <loc> is in current stack frame */
3624887Schin 		if(loc>=cp && loc<=sp->stkend)
3634887Schin 		{
3644887Schin 			if(frames)
3654887Schin 				sfsetbuf(stream,cp,sp->stkend-cp);
3664887Schin 			stream->_data = (unsigned char*)(cp + roundof(loc-cp,STK_ALIGN));
3674887Schin 			stream->_next = (unsigned char*)loc+offset;
3684887Schin 			goto found;
3694887Schin 		}
3704887Schin 		if(fp->prev)
3714887Schin 		{
3724887Schin 			sp->stkbase = fp->prev;
3734887Schin 			sp->stkend = ((struct frame*)(fp->prev))->end;
3744887Schin 			free((void*)fp);
3754887Schin 		}
3764887Schin 		else
3774887Schin 			break;
3784887Schin 		frames++;
3794887Schin 	}
3804887Schin 	/* set stack back to the beginning */
3814887Schin 	cp = (char*)(fp+1);
3824887Schin 	if(frames)
3834887Schin 		sfsetbuf(stream,cp,sp->stkend-cp);
3844887Schin 	else
3854887Schin 		stream->_data = stream->_next = (unsigned char*)cp;
3864887Schin found:
3874887Schin 	return((char*)stream->_data);
3884887Schin }
3894887Schin 
3904887Schin /*
3914887Schin  * allocate <n> bytes on the current stack
3924887Schin  */
stkalloc(register Sfio_t * stream,register unsigned int n)3934887Schin char *stkalloc(register Sfio_t *stream, register unsigned int n)
3944887Schin {
3954887Schin 	register unsigned char *old;
3964887Schin 	if(!init)
3974887Schin 		stkinit(n);
3984887Schin 	increment(alloc);
3994887Schin 	n = roundof(n,STK_ALIGN);
4004887Schin 	if(stkleft(stream) <= (int)n && !stkgrow(stream,n))
4014887Schin 		return(0);
4024887Schin 	old = stream->_data;
4034887Schin 	stream->_data = stream->_next = old+n;
4044887Schin 	return((char*)old);
4054887Schin }
4064887Schin 
4074887Schin /*
4084887Schin  * begin a new stack word of at least <n> bytes
4094887Schin  */
_stkseek(register Sfio_t * stream,register unsigned n)4104887Schin char *_stkseek(register Sfio_t *stream, register unsigned n)
4114887Schin {
4124887Schin 	if(!init)
4134887Schin 		stkinit(n);
4144887Schin 	increment(seek);
4154887Schin 	if(stkleft(stream) <= (int)n && !stkgrow(stream,n))
4164887Schin 		return(0);
4174887Schin 	stream->_next = stream->_data+n;
4184887Schin 	return((char*)stream->_data);
4194887Schin }
4204887Schin 
4214887Schin /*
4224887Schin  * advance the stack to the current top
4234887Schin  * if extra is non-zero, first add a extra bytes and zero the first
4244887Schin  */
stkfreeze(register Sfio_t * stream,register unsigned extra)4254887Schin char	*stkfreeze(register Sfio_t *stream, register unsigned extra)
4264887Schin {
4274887Schin 	register unsigned char *old, *top;
4284887Schin 	if(!init)
4294887Schin 		stkinit(extra);
4304887Schin 	old = stream->_data;
4314887Schin 	top = stream->_next;
4324887Schin 	if(extra)
4334887Schin 	{
4344887Schin 		if(extra > (stream->_endb-stream->_next))
4354887Schin 		{
4364887Schin 			if (!(top = (unsigned char*)stkgrow(stream,extra)))
4374887Schin 				return(0);
4384887Schin 			old = stream->_data;
4394887Schin 		}
4404887Schin 		*top = 0;
4414887Schin 		top += extra;
4424887Schin 	}
4434887Schin 	stream->_next = stream->_data += roundof(top-old,STK_ALIGN);
4444887Schin 	return((char*)old);
4454887Schin }
4464887Schin 
4474887Schin /*
4484887Schin  * copy string <str> onto the stack as a new stack word
4494887Schin  */
stkcopy(Sfio_t * stream,const char * str)4504887Schin char	*stkcopy(Sfio_t *stream, const char* str)
4514887Schin {
4524887Schin 	register unsigned char *cp = (unsigned char*)str;
4534887Schin 	register int n;
4548462SApril.Chin@Sun.COM 	register int off=stktell(stream);
4558462SApril.Chin@Sun.COM 	char buff[40], *tp=buff;
4568462SApril.Chin@Sun.COM 	if(off)
4578462SApril.Chin@Sun.COM 	{
4588462SApril.Chin@Sun.COM 		if(off > sizeof(buff))
4598462SApril.Chin@Sun.COM 		{
4608462SApril.Chin@Sun.COM 			if(!(tp = malloc(off)))
4618462SApril.Chin@Sun.COM 			{
4628462SApril.Chin@Sun.COM 				struct stk *sp = stream2stk(stream);
4638462SApril.Chin@Sun.COM 				if(!sp->stkoverflow || !(tp = (*sp->stkoverflow)(off)))
4648462SApril.Chin@Sun.COM 					return(0);
4658462SApril.Chin@Sun.COM 			}
4668462SApril.Chin@Sun.COM 		}
4678462SApril.Chin@Sun.COM 		memcpy(tp, stream->_data, off);
4688462SApril.Chin@Sun.COM 	}
4694887Schin 	while(*cp++);
4704887Schin 	n = roundof(cp-(unsigned char*)str,STK_ALIGN);
4714887Schin 	if(!init)
4724887Schin 		stkinit(n);
4734887Schin 	increment(copy);
4744887Schin 	if(stkleft(stream) <= n && !stkgrow(stream,n))
4754887Schin 		return(0);
4764887Schin 	strcpy((char*)(cp=stream->_data),str);
4774887Schin 	stream->_data = stream->_next = cp+n;
4788462SApril.Chin@Sun.COM 	if(off)
4798462SApril.Chin@Sun.COM 	{
4808462SApril.Chin@Sun.COM 		_stkseek(stream,off);
4818462SApril.Chin@Sun.COM 		memcpy(stream->_data, tp, off);
4828462SApril.Chin@Sun.COM 		if(tp!=buff)
4838462SApril.Chin@Sun.COM 			free((void*)tp);
4848462SApril.Chin@Sun.COM 	}
4854887Schin 	return((char*)cp);
4864887Schin }
4874887Schin 
4884887Schin /*
4894887Schin  * add a new stack frame of size >= <n> to the current stack.
4904887Schin  * if <n> > 0, copy the bytes from stkbot to stktop to the new stack
4914887Schin  * if <n> is zero, then copy the remainder of the stack frame from stkbot
4924887Schin  * to the end is copied into the new stack frame
4934887Schin  */
4944887Schin 
stkgrow(register Sfio_t * stream,unsigned size)4954887Schin static char *stkgrow(register Sfio_t *stream, unsigned size)
4964887Schin {
4974887Schin 	register int n = size;
4984887Schin 	register struct stk *sp = stream2stk(stream);
4994887Schin 	register struct frame *fp= (struct frame*)sp->stkbase;
5004887Schin 	register char *cp, *dp=0;
5014887Schin 	register unsigned m = stktell(stream);
5024887Schin 	int nn=0;
5034887Schin 	n += (m + sizeof(struct frame)+1);
5044887Schin 	if(sp->stkflags&STK_SMALL)
5054887Schin #ifndef USE_REALLOC
5064887Schin 		n = roundof(n,STK_FSIZE/16);
5074887Schin 	else
5084887Schin #endif /* !USE_REALLOC */
5094887Schin 		n = roundof(n,STK_FSIZE);
5104887Schin 	/* see whether current frame can be extended */
5114887Schin 	if(stkptr(stream,0)==sp->stkbase+sizeof(struct frame))
5124887Schin 	{
5134887Schin 		nn = fp->nalias+1;
5144887Schin 		dp=sp->stkbase;
5154887Schin 		sp->stkbase = ((struct frame*)dp)->prev;
5164887Schin 	}
5174887Schin 	cp = newof(dp, char, n, nn*sizeof(char*));
5184887Schin 	if(!cp && (!sp->stkoverflow || !(cp = (*sp->stkoverflow)(n))))
5194887Schin 		return(0);
5204887Schin 	increment(grow);
5214887Schin 	count(addsize,n - (dp?m:0));
5224887Schin 	if(dp && cp==dp)
5234887Schin 		nn--;
5244887Schin 	fp = (struct frame*)cp;
5254887Schin 	fp->prev = sp->stkbase;
5264887Schin 	sp->stkbase = cp;
5274887Schin 	sp->stkend = fp->end = cp+n;
5284887Schin 	cp = (char*)(fp+1);
5294887Schin 	cp = sp->stkbase + roundof((cp-sp->stkbase),STK_ALIGN);
5304887Schin 	if(fp->nalias=nn)
5314887Schin 	{
5324887Schin 		fp->aliases = (char**)fp->end;
5334887Schin 		fp->aliases[nn-1] =  dp + roundof(sizeof(struct frame),STK_ALIGN);
5344887Schin 	}
5354887Schin 	if(m && !dp)
5364887Schin 	{
5374887Schin 		memcpy(cp,(char*)stream->_data,m);
5384887Schin 		count(movsize,m);
5394887Schin 	}
5404887Schin 	sfsetbuf(stream,cp,sp->stkend-cp);
5414887Schin 	return((char*)(stream->_next = stream->_data+m));
5424887Schin }
543