예제 #1
0
int traverse(const parsetree_statement_t *stmt, void *bgtheme)
{
    const char *identifier;
    const parsetree_parameter_t *param_list;
    const parsetree_parameter_t *p1;
    background_t *bg;
    bgtheme_t *theme = (bgtheme_t*)bgtheme;

    identifier = nanoparser_get_identifier(stmt);
    param_list = nanoparser_get_parameter_list(stmt);

    if(str_icmp(identifier, "background") == 0) {
        p1 = nanoparser_get_nth_parameter(param_list, 1);

        nanoparser_expect_program(p1, "Can't read background. Missing background attributes");

        bg = background_new();
        theme->data = reallocx(theme->data, (++(theme->length)) * sizeof(*(theme->data)));
        theme->data[theme->length-1] = bg;
        nanoparser_traverse_program_ex(nanoparser_get_program(p1), (void*)bg, traverse_background_attributes);
        validate_background(bg);
        actor_change_animation(bg->actor, bg->data->animation_data[0]);
    }
    else
        fatal_error("Can't read background. Unknown identifier: '%s'", identifier);

    return 0;
}
예제 #2
0
파일: run.c 프로젝트: sauliusg/starta
static int realloc_eval_stack( cexception_t * ex )
{
    /* The 'eval' stack should not have any references from the
       garbage-collected blocks, so it can be safely reallocated. */

    if( stack_realloc_delta <= 0 ) {
        return 0;
    } else {
        stackcell_t *old_eval_stack = istate.eval_stack;
        ssize_t old_eval_stack_length = istate.eval_stack_length;
        ssize_t delta, offset, full_offset;

        istate.eval_stack =
            reallocx( istate.eval_stack, sizeof(istate.eval_stack[0]) *
                      (istate.eval_stack_length + stack_realloc_delta), ex );

        istate.eval_stack_length += stack_realloc_delta;

        delta = (char*)istate.eval_stack - (char*)old_eval_stack;

        offset = stack_realloc_delta * sizeof(istate.eval_stack[0]);

        full_offset = offset + delta;

        /* We must use memmove() since the source and the destination
           overlap: */
        memmove( ((char*)istate.eval_stack) + offset, istate.eval_stack,
                 old_eval_stack_length * sizeof(istate.eval_stack[0]));

        istate.ep_bottom =
            (stackcell_t*)(((char*)istate.ep_bottom) + full_offset);
        istate.ep = (stackcell_t*)(((char*)istate.ep) + full_offset);
        istate.ep_top = istate.eval_stack + STACK_SAFETY_MARGIN;

        struct interpret_exception_t *current_xp;
        for( current_xp = istate.xp;
                current_xp != NULL;
                current_xp = current_xp->old_xp.ptr ) {
            current_xp->ep = (stackcell_t*)((char*)(current_xp->ep) +
                                            full_offset );
        }

#if 0
        memset( istate.eval_stack, 0xAA,
                stack_realloc_delta * sizeof(istate.eval_stack[0]));
#endif

        return 1;
    }
}
예제 #3
0
파일: dwebsvr.c 프로젝트: Cloudhomebr/rCPU
void badd(blk *b, void *data, int len)
{
    if (b->alloc_bytes - b->used_bytes < len)
    {
        while (b->alloc_bytes - b->used_bytes < len)
        {
			b->alloc_bytes+= (b->chunk_size * b->elem_bytes);
        }
        b->ptr=reallocx(b->ptr, b->alloc_bytes);
    }
    memcpy(b->ptr + b->used_bytes, data, len);
    b->used_bytes += len;
    memset(b->ptr + b->used_bytes, 0, b->alloc_bytes - b->used_bytes);
}
예제 #4
0
파일: memio.c 프로젝트: dschwen/libmesh
/*
 *  Sync any changes to disk, then truncate or extend file so its size
 *  is length.  This is only intended to be called before close, if the
 *  file is open for writing and the actual size does not match the
 *  calculated size, perhaps as the result of having been previously
 *  written in NOFILL mode.
 */
static int
memio_pad_length(ncio* nciop, off_t length)
{
    NCMEMIO* memio;
    size_t len = (size_t)length;
    if(nciop == NULL || nciop->pvt == NULL) return NC_EINVAL;
    memio = (NCMEMIO*)nciop->pvt;

    if(!fIsSet(nciop->ioflags,NC_WRITE))
        return EPERM; /* attempt to write readonly file*/
    if(memio->locked)
	return NC_EINMEMORY;

    if(len > memio->alloc) {
        /* Realloc the allocated memory to a multiple of the pagesize*/
	size_t newsize = (size_t)len;
	void* newmem = NULL;
	/* Round to a multiple of pagesize */
	if((newsize % pagesize) != 0)
	    newsize += (pagesize - (newsize % pagesize));

        newmem = (char*)reallocx(memio->memory,newsize,memio->alloc);
        if(newmem == NULL) return NC_ENOMEM;
	/* If not copy is set, then fail if the newmem address is different
           from old address */
	if(newmem != memio->memory) {
	    memio->modified++;
	    if(memio->locked) {
		free(newmem);
		return NC_EINMEMORY;
	    }
        }
	/* zero out the extra memory */
        memset((void*)((char*)newmem+memio->alloc),0,(size_t)(newsize - memio->alloc));

#ifdef DEBUG
fprintf(stderr,"realloc: %lu/%lu -> %lu/%lu\n",
(unsigned long)memio->memory,(unsigned long)memio->alloc,
(unsigned long)newmem,(unsigned long)newsize);
#endif
	if(memio->memory != NULL && (!memio->locked || memio->modified))
	    free(memio->memory);
	memio->memory = newmem;
	memio->alloc = newsize;
	memio->modified = 1;
    }
    memio->size = len;
    return NC_NOERR;
}
예제 #5
0
파일: thrcode.c 프로젝트: sauliusg/starta
static void thrcode_alloc( THRCODE *bc, size_t delta, cexception_t *ex )
{
    size_t new_capacity;

    assert( delta >= 0 );
    assert( bc->length <= bc->capacity );

    if( bc->length + delta <= bc->capacity )
        return;

    new_capacity = bc->capacity + (ALLOC_CHUNK > delta ? ALLOC_CHUNK : delta);
    bc->opcodes =
        reallocx( bc->opcodes, new_capacity * sizeof(bc->opcodes[0]), ex );
    bc->capacity = new_capacity;
}
예제 #6
0
파일: thrcode.c 프로젝트: sauliusg/starta
static THRCODE *thrcode_insert_string( THRCODE *tc, char * volatile *str,
				       cexception_t *ex )
{
    ssize_t len = thrcode_line_count( tc );;

    assert( tc );
    assert( str );

    tc->lines = reallocx( tc->lines, sizeof(tc->lines[0]) * (len + 2), ex );
    tc->lines[len+1] = NULL;
    tc->lines[len] = *str;
    *str = NULL;

    return tc;
}
예제 #7
0
파일: dwebsvr.c 프로젝트: TrunkerRoad/rCPU
// assumes a content type of "application/x-www-form-urlencoded" (the default type)
void get_form_values(struct hitArgs *args, char *body)
{
    char *saveptr;
    int t=0, i, alloc = FORM_VALUE_BLOCK;
    char *tmp, *token = strtok_r(body, "&", &saveptr);
    
    args->form_values = mallocx(alloc * sizeof(FORM_VALUE));
    memset(args->form_values, 0, alloc * sizeof(FORM_VALUE));
    
    while(token != NULL)
    {
        tmp = mallocx((int)strlen(token)+1);
        strcpy(tmp, token);
        url_decode(tmp);
        
        for (i=0; i<strlen(tmp); i++)
        {
            if (tmp[i]=='=') break;
        }
        
        // don't allow i to be set to strlen(tmp) - to prevent reading other memory
        if (i>0 && i==strlen(tmp)) i--;
        
        if (alloc <= t)
        {
            int newsize = alloc+FORM_VALUE_BLOCK;
            args->form_values = reallocx(args->form_values, newsize * sizeof(FORM_VALUE));
            memset(args->form_values+alloc, 0, FORM_VALUE_BLOCK * sizeof(FORM_VALUE));
            alloc = newsize;
        }
        
        args->form_values[t].data = mallocx((int)strlen(tmp)+1);
        strcpy(args->form_values[t].data, tmp);
        args->form_values[t].name = args->form_values[t].data;
        args->form_values[t].value = args->form_values[t].data+1+i;
        args->form_values[t++].data[i] = 0;
        token = strtok_r(NULL, "&", &saveptr);
        free (tmp);
    }
    args->form_value_counter = t;
}
예제 #8
0
파일: thrcode.c 프로젝트: sauliusg/starta
static void thrcode_merge_line_lists( THRCODE *code1, THRCODE *code2,
				      cexception_t *ex )
{
    ssize_t i;
    ssize_t len1 = thrcode_line_count( code1 );
    ssize_t len2 = thrcode_line_count( code2 );
    ssize_t len = len1 + len2;

    if( code1->flags & THRF_IMMEDIATE_PRINTOUT ) {
	thrcode_flush_lines( code2 );
    } else {
	code1->lines = reallocx( code1->lines,
				 sizeof(code1->lines[0]) * (len + 1), ex );

	memmove( code1->lines + len1, code2->lines,
		 sizeof(code1->lines[0]) * len2 );

	code1->lines[len] = NULL;
    
	for( i = 0; i < len2; i ++ ) {
	    code2->lines = NULL;
	}
    }
}
예제 #9
0
int main( int argc, char *argv[], char *env[] )
{
  cexception_t inner;
  char ** volatile files = NULL;
  CIF * volatile cif = NULL;
  int retval = 0;
  int i;

  progname = argv[0];

  tags.value.s = "";
  separator.value.s = " ";
  vseparator.value.s = ",";
  print_filename.value.b = 0;
  print_dataname.value.b = 1;

  char ** taglist = NULL;
  int tagcount = 0;

  cexception_guard( inner ) {
      files = get_optionsx( argc, argv, options, &inner );
      char * tag_pointer = tags.value.s;
      char * end_pointer = strchr( tags.value.s, ',' );

      if( !tags.present || !tags.value.s || !tags.value.s[0] ) {
          fprintf( stderr, "%s: no data items to extract from the input, please "
                   "specify them using --tag option (--help for examples)\n",
                   argv[0] );
          exit(0);
      }

      while( tag_pointer != NULL ) {
        tagcount++;
        int taglen;
        if( end_pointer != NULL ) {
            taglen = end_pointer - tag_pointer;
        } else {
            taglen = strchr( tag_pointer, '\0' ) - tag_pointer;
        }
        taglist = reallocx( taglist, sizeof( char * ) * tagcount, &inner );
        taglist[tagcount - 1] = mallocx( taglen * sizeof( char ) + 1, &inner );
        strncpy( taglist[tagcount - 1], tag_pointer, taglen );
        int i;
        for( i = 0; i < taglen; i++ ) {
            taglist[tagcount - 1][i] = tolower( taglist[tagcount - 1][i] );
        }
        taglist[tagcount - 1][taglen] = '\0';
        if( end_pointer != NULL ) {
            tag_pointer = end_pointer + 1;
            end_pointer = strchr( tag_pointer, ',' );
        } else {
            tag_pointer = NULL;
        }
      }
  }
  cexception_catch {
      fprintf( stderr, "%s: %s\n", argv[0], cexception_message( &inner ));
      exit(1);
  }

  if( files[0] == NULL && isatty(0) && isatty(1) ) {
      fprintf( stderr, "%s: Usage: %s data.cif\n", argv[0], argv[0] );
      exit(2);
  }

  cif_yy_debug_off();    
  cif_flex_debug_off();    
  cif_debug_off();
  if( debug.present ) {
      if( strstr(debug.value.s, "lex") != NULL ) cif_flex_debug_yyflex();
      if( strstr(debug.value.s, "yacc") != NULL ) cif_yy_debug_on();
      if( strstr(debug.value.s, "yylval") != NULL ) cif_flex_debug_yylval();
      if( strstr(debug.value.s, "text") != NULL ) cif_flex_debug_yytext();
      if( strstr(debug.value.s, "code") != NULL ) {
	  cif_flex_debug_lines();
	  cif_debug_on();
      }
  }

  for( i = 0; i == 0 || files[i] != NULL; i++ ) {
      char * volatile filename = NULL;
      cexception_guard( inner ) {
          filename = files[i] ? files[i] : "-";
          cif = new_cif_from_cif_file( files[i], cif_option_default(),
                                       &inner );

          if( cif && cif_nerrors( cif ) == 0 ) {
              if( debug.present && strstr(debug.value.s, "dump") != NULL ) {
                  cif_print( cif );
              } else {
                  if( ( !cif_datablock_list( cif ) || 
                        !datablock_next( cif_datablock_list( cif ))) &&
                      !datablock_name( cif_datablock_list( cif ))) {
                      fprintf( stderr,
                               "%s: file '%s' seems to be empty (no named datablocks)\n",
                               argv[0], filename );
                  } else {
                      cif_print_tag_values
                          ( cif, taglist, tagcount,
                            ( print_filename.value.b == 1 ? filename : "" ),
                            print_dataname.value.b, separator.value.s, 
                            vseparator.value.s );
                  }
              }         
              delete_cif( cif );
              cif = NULL;
              filename = NULL;
          }
      }
      cexception_catch {
          if( filename ) {
              fprintf( stderr, "%s: %s: %s\n", argv[0], filename, cexception_message( &inner ));
          } else {
              fprintf( stderr, "%s: %s\n", argv[0], cexception_message( &inner ));
          }
          delete_cif( cif );
          retval = 3;
          cif = NULL;
      }
  }

  delete_cif( cif );
  freex( files );

  return retval;
}
예제 #10
0
파일: memio.c 프로젝트: dschwen/libmesh
/* This function opens the data file or inmemory data
   path - path of data file.
   ioflags - flags passed into nc_open.
   igeto - looks like this function can do an initial page get, and
   igeto is going to be the offset for that. But it appears to be
   unused
   igetsz - the size in bytes of initial page get (a.k.a. extent). Not
   ever used in the library.
   sizehintp - the size of a page of data for buffered reads and writes.
   parameters - arbitrary data
   nciopp - pointer to pointer that will get address of newly created
   and inited ncio struct.
   mempp - pointer to pointer to the initial memory read.
*/
int
memio_open(const char* path,
    int ioflags,
    off_t igeto, size_t igetsz, size_t* sizehintp,
    void* parameters,
    ncio* *nciopp, void** const mempp)
{
    ncio* nciop = NULL;
    int fd = -1;
    int status = NC_NOERR;
    size_t sizehint = 0;
    NC_memio meminfo; /* use struct to avoid worrying about free'ing it */
    NCMEMIO* memio = NULL;
    size_t initialsize;
    /* Should be the case that diskless => inmemory but not converse */
    int diskless = (fIsSet(ioflags,NC_DISKLESS));
    int inmemory = fIsSet(ioflags,NC_INMEMORY);
    int locked = 0;

    assert(inmemory ? !diskless : 1);

    if(path == NULL || strlen(path) == 0)
        return NC_EINVAL;

    assert(sizehintp != NULL);

    sizehint = *sizehintp;

    memset(&meminfo,0,sizeof(meminfo));

    if(inmemory) { /* parameters provide the memory chunk */
	NC_memio* memparams = (NC_memio*)parameters;
        meminfo = *memparams;
        locked = fIsSet(meminfo.flags,NC_MEMIO_LOCKED);
	/* As a safeguard, if !locked and NC_WRITE is set,
           then we must take control of the incoming memory */
        if(!locked && fIsSet(ioflags,NC_WRITE)) {
	    memparams->memory = NULL;	    
	}	
    } else { /* read the file into a chunk of memory*/
	assert(diskless);
	status = readfile(path,&meminfo);
	if(status != NC_NOERR)
	    {goto unwind_open;}
    }

    /* Fix up initial size */
    initialsize = meminfo.size;

    /* create the NCMEMIO structure */
    status = memio_new(path, ioflags, initialsize, &nciop, &memio);
    if(status != NC_NOERR)
	{goto unwind_open;}
    memio->locked = locked;

    /* Initialize the memio memory */
    memio->memory = meminfo.memory;

    /* memio_new may have modified the allocated size, in which case,
       reallocate the memory unless the memory is locked. */    
    if(memio->alloc > meminfo.size) {
	if(memio->locked)
	    memio->alloc = meminfo.size; /* force it back to what it was */
	else {
	   void* oldmem = memio->memory;
	   memio->memory = reallocx(oldmem,memio->alloc,meminfo.size);
	   if(memio->memory == NULL)
	       {status = NC_ENOMEM; goto unwind_open;}
	}
    }

#ifdef DEBUG
fprintf(stderr,"memio_open: initial memory: %lu/%lu\n",(unsigned long)memio->memory,(unsigned long)memio->alloc);
#endif

    if(memio->persist) {
	/* Verify the file is writeable and exists */
	if(!fileexists(path))
	    {status = ENOENT; goto unwind_open;}	
	if(!fileiswriteable(path))
	    {status = EACCES; goto unwind_open;}	
    }

    /* Use half the filesize as the blocksize ; why? */
    sizehint = (size_t)(memio->alloc/2);

    /* sizehint must be multiple of 8 */
    sizehint = (sizehint / 8) * 8;
    if(sizehint < 8) sizehint = 8;

    fd = nc__pseudofd();
    *((int* )&nciop->fd) = fd;

    if(igetsz != 0)
    {
        status = nciop->get(nciop,
                igeto, igetsz,
                0,
                mempp);
        if(status != NC_NOERR)
            goto unwind_open;
    }

    if(sizehintp) *sizehintp = sizehint;
    if(nciopp) *nciopp = nciop; else {ncio_close(nciop,0);}
    return NC_NOERR;

unwind_open:
    if(fd >= 0)
      close(fd);
    memio_close(nciop,0);
    return status;
}
예제 #11
0
/*
 * traverse_sprite_attributes()
 * Sprite attributes traversal
 */
int traverse_sprite_attributes(const parsetree_statement_t *stmt, void *spriteinfo)
{
    const char *identifier;
    const parsetree_parameter_t *param_list;
    const parsetree_parameter_t *p1, *p2, *p3, *p4;
    spriteinfo_t *s = (spriteinfo_t*)spriteinfo;
    int anim_id = 0;

    identifier = nanoparser_get_identifier(stmt);
    param_list = nanoparser_get_parameter_list(stmt);

    if(str_icmp(identifier, "source_file") == 0) {
        p1 = nanoparser_get_nth_parameter(param_list, 1);

        nanoparser_expect_string(p1, "Must provide path to the source_file");

        if(s->source_file != NULL)
            free(s->source_file);
        s->source_file = str_dup(nanoparser_get_string(p1));
    }
    else if(str_icmp(identifier, "source_rect") == 0) {
        p1 = nanoparser_get_nth_parameter(param_list, 1);
        p2 = nanoparser_get_nth_parameter(param_list, 2);
        p3 = nanoparser_get_nth_parameter(param_list, 3);
        p4 = nanoparser_get_nth_parameter(param_list, 4);

        nanoparser_expect_string(p1, "Must provide four numbers to source_rect: xpos, ypos, width, height");
        nanoparser_expect_string(p2, "Must provide four numbers to source_rect: xpos, ypos, width, height");
        nanoparser_expect_string(p3, "Must provide four numbers to source_rect: xpos, ypos, width, height");
        nanoparser_expect_string(p4, "Must provide four numbers to source_rect: xpos, ypos, width, height");

        s->rect_x = max(0, atoi(nanoparser_get_string(p1)));
        s->rect_y = max(0, atoi(nanoparser_get_string(p2)));
        s->rect_w = max(1, atoi(nanoparser_get_string(p3)));
        s->rect_h = max(1, atoi(nanoparser_get_string(p4)));
    }
    else if(str_icmp(identifier, "frame_size") == 0) {
        p1 = nanoparser_get_nth_parameter(param_list, 1);
        p2 = nanoparser_get_nth_parameter(param_list, 2);

        nanoparser_expect_string(p1, "Must provide two numbers to frame_size: width, height");
        nanoparser_expect_string(p2, "Must provide two numbers to frame_size: width, height");

        s->frame_w = max(1, atoi(nanoparser_get_string(p1)));
        s->frame_h = max(1, atoi(nanoparser_get_string(p2)));
    }
    else if(str_icmp(identifier, "hot_spot") == 0) {
        p1 = nanoparser_get_nth_parameter(param_list, 1);
        p2 = nanoparser_get_nth_parameter(param_list, 2);

        nanoparser_expect_string(p1, "Must provide two numbers to hot_spot: xpos, ypos");
        nanoparser_expect_string(p2, "Must provide two numbers to hot_spot: xpos, ypos");

        s->hot_spot.x = (float)atoi(nanoparser_get_string(p1));
        s->hot_spot.y = (float)atoi(nanoparser_get_string(p2));
    }
    else if(str_icmp(identifier, "animation") == 0) {
        p1 = nanoparser_get_nth_parameter(param_list, 1);
        p2 = nanoparser_get_nth_parameter(param_list, 2);

        if(p1 && p2) {
            nanoparser_expect_string(p1, "Must provide animation number");
            nanoparser_expect_program(p2, "Must provide animation attributes");
            anim_id = atoi(nanoparser_get_string(p1));
            if(anim_id < 0 || anim_id >= SPRITE_MAX_ANIM)
                fatal_error("Can't load sprites. Animation number must be in range 0..%d\nin\"%s\" near line %d", SPRITE_MAX_ANIM-1, nanoparser_get_file(stmt), nanoparser_get_line_number(stmt));
        }
        else if(p1) {
            nanoparser_expect_program(p1, "Must provide animation attributes");
            anim_id = 0;
            p2 = p1;
        }
        else
            fatal_error("No attributes provided to 'animation' block\nin\"%s\" near line %d", nanoparser_get_file(stmt), nanoparser_get_line_number(stmt));

        if(anim_id < s->animation_count && NULL != s->animation_data[anim_id])
            s->animation_data[anim_id] = animation_delete(s->animation_data[anim_id]);

        s->animation_count = max(s->animation_count, anim_id+1);
        s->animation_data = reallocx(s->animation_data, sizeof(animation_t*) * s->animation_count); /* TODO: watch this! It may generate garbage in the middle. */
        s->animation_data[anim_id] = animation_new(anim_id);
        nanoparser_traverse_program_ex(nanoparser_get_program(p2), s->animation_data[anim_id], traverse_animation_attributes);
        validate_animation(s->animation_data[anim_id]);
    }
    else
        fatal_error("Can't load sprites. Unknown identifier '%s'\nin\"%s\" near line %d", identifier, nanoparser_get_file(stmt), nanoparser_get_line_number(stmt));

    return 0;
}
예제 #12
0
파일: run.c 프로젝트: sauliusg/starta
static int realloc_call_stack( cexception_t * ex )
{
    /* The 'call' can be pointed to from the evaluation stack,
       therefore references on the evaluation stack must be adjusted
       after the reallocation. */

    if( stack_realloc_delta <= 0 ) {
        return 0;
    } else {
        stackcell_t *old_call_stack = istate.call_stack;
        stackcell_t *old_call_limit =
            istate.call_stack + istate.call_stack_length;
        stackcell_t *ep, *ep_limit, *sp, *sp_limit;
        ssize_t old_call_stack_length = istate.call_stack_length;
        ssize_t delta, offset, full_offset;

        istate.call_stack =
            reallocx( istate.call_stack, sizeof(istate.call_stack[0]) *
                      (istate.call_stack_length + stack_realloc_delta), ex );

        istate.call_stack_length += stack_realloc_delta;

        offset = stack_realloc_delta * sizeof(istate.call_stack[0]);

        /* We must use memmove() since the source and the destination
           overlap: */
        memmove( ((char*)istate.call_stack) + offset, istate.call_stack,
                 old_call_stack_length * sizeof(istate.call_stack[0]));

        delta = (char*)istate.call_stack - (char*)old_call_stack;

        full_offset = offset + delta;

        /* Adjust pointers on the evaluation stack so that they point
           to the moved elements on the newly reallocated call
           stack: */
        if( full_offset != 0 ) {
            ep_limit = istate.eval_stack + istate.eval_stack_length;
            for( ep = istate.eval_stack; ep < ep_limit; ep++ ) {
                if( ep->PTR >= (void*)old_call_stack &&
                        ep->PTR < (void*)old_call_limit ) {
                    ep->PTR = (char*)(ep->PTR) + full_offset;
                    //printf( "<<<< Moving on eval: %p -> %p\n", ep->PTR-full_offset, ep->PTR );
                }
            }
            sp_limit = istate.call_stack + istate.call_stack_length;
            for( sp = istate.call_stack; sp < sp_limit; sp++ ) {
                //printf( ">>> checking call stack %p, PTR = %p\n", sp, sp->PTR );
                if( sp->PTR >= (void*)old_call_stack &&
                        sp->PTR < (void*)old_call_limit ) {
                    sp->PTR = (char*)(sp->PTR) + full_offset;
                    //printf( ">>> Moving on call: %p -> %p\n", sp->PTR-full_offset, sp->PTR );
                }
            }
        }

#if 0
        printf( "reallocating call stack, length = %d, delta = %d, full_offset = %d\n",
                istate.call_stack_length, delta, full_offset );
        printf( "old call stack = %p, new call stack = %p\n",
                old_call_stack, istate.call_stack );
#endif

        istate.bottom = (stackcell_t*)((char*)(istate.bottom) + full_offset);
        istate.fp = (stackcell_t*)((char*)(istate.fp) + full_offset);
        istate.sp = (stackcell_t*)((char*)(istate.sp) + full_offset);
        istate.gp = (stackcell_t*)((char*)(istate.gp) + full_offset);
        istate.top = istate.call_stack + STACK_SAFETY_MARGIN;

        /* Adjust exception structure pointers: */

        struct interpret_exception_t *current_xp;
        for( current_xp = istate.xp;
                current_xp != NULL;
                current_xp = current_xp->old_xp.ptr ) {

            current_xp->fp = (stackcell_t*)((char*)(current_xp->fp) +
                                            full_offset );

            current_xp->sp = (stackcell_t*)((char*)(current_xp->sp) +
                                            full_offset );
        }
#if 1
        memset( istate.call_stack, 0x55,
                stack_realloc_delta * sizeof(istate.call_stack[0]));
#endif

        return 1;
    }
}