#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <yafl_usr.h>
#include <yafl_rnt.h>

#define TOP (&(dual_stack[DUAL_STACK_SIZE -1]))

static obj_ptr * dual_stack[DUAL_STACK_SIZE];
obj_ptr **       d_stack = dual_stack;
obj_ptr *        v_stack = (obj_ptr*) TOP;

#ifdef Y_TRACE_GC
extern FILE * gc_trace;
#endif


/*********************************************************/
int used_v_stack YPARAMS0
{
  return ((int*) TOP) - (int*) v_stack;
}
/*********************************************************/
int used_d_stack YPARAMS0
{
  return ((int*) d_stack) - (int*)dual_stack;
}
/*********************************************************/
void dump_regs YPARAMS2(FILE * , output)
{
  obj_ptr **p; 
  FILE * out;
  
  out = output;  
  if (! out)
    out = fopen("reg_stack", "w");

  assert(out != NULL);
  fprintf (out, "Registered stack:\n---------------------------------\n");
  p = dual_stack;
  while (p != d_stack)
    {
      fflush(out);
      if (*p && **p)
        dump_obj_ptr(out, HEADER(**p));
       else
        fprintf(out, "<VOID>\n"); 
      p ++;
    }
  if (! output)
    fclose (out);
}
/*********************************************************/
void y_mark_stack YPARAMS0
{
  obj_ptr **p, *q;
/*
  dump_regs(NULL);     
*/  
  p = dual_stack;
  q = (obj_ptr*) TOP;
  assert(p <= d_stack);
#ifdef Y_TRACE_GC
  fprintf (gc_trace, "\n\n\nMarking reference stack\n\n");
#endif  
  while (p != d_stack)
    {
#ifdef Y_TRACE_GC
      set_initial();
#endif  
      enter_pool(**p);
      flush_pool();
      p++;
    }
  assert(q >= v_stack);
#ifdef Y_TRACE_GC
  fprintf (gc_trace, "\n\n\nMarking value stack\n\n");
#endif  
  while (q != v_stack)
    {
#ifdef Y_TRACE_GC
      set_initial();
#endif  
      enter_pool(*q);
      flush_pool();
      q--;
    }
}

