コード例 #1
0
/*----------------------------------------------------------------------------*/
PmReturn_t
tres_pm_get_state(pPmFrame_t *ppframe)
{
  PmReturn_t retv = PM_RET_OK;
  pPmObj_t pobj;
  pPmObj_t pobj_new;
  pPmInstance_t pcli;
  pPmDict_t pdict;
  int16_t index;
  float fval;
  int32_t ival;

  if(NATIVE_GET_NUM_ARGS() != 1) {
    PM_RAISE(retv, PM_RET_EX_TYPE);
    return retv;
  }
  pobj = NATIVE_GET_LOCAL(0);
  if(OBJ_GET_TYPE(pobj) != OBJ_TYPE_CLI) {
    PM_RAISE(retv, PM_RET_EX_TYPE);
    return retv;
  }
  pcli = (pPmInstance_t)pobj;
  pdict = pcli->cli_attrs;

  if(*tres_pm_io.state_len > 0) {
    // restore each attribute of the object
    for(index = pdict->length - 1; index >= 0; index--) {
      seglist_getItem(pdict->d_keys, index, &pobj);
      retv = seglist_getItem(pdict->d_vals, index, &pobj);
      PM_RETURN_IF_ERROR(retv);
      switch (OBJ_GET_TYPE(pobj)) {
      case OBJ_TYPE_INT:
        //pop int
        pop_int(&ival);
        retv = int_new(ival, &pobj_new);
        break;
      case OBJ_TYPE_FLT:
        //pop float
        pop_float(&fval);
        retv = float_new(fval, &pobj_new);
        break;
      default:
        /* Raise TypeError */
        PM_RAISE(retv, PM_RET_EX_TYPE);
      }
      if (retv == PM_RET_OK) {
        seglist_setItem(pdict->d_vals, pobj_new, index);
      }
    }
  }
  NATIVE_SET_TOS((pPmObj_t)pcli);
  return retv;
}
コード例 #2
0
/*----------------------------------------------------------------------------*/
PmReturn_t
tres_pm_state_pop(pPmFrame_t *ppframe)
{
  PmReturn_t retv = PM_RET_OK;
  pPmObj_t r_pflt;
  pPmObj_t pa;
  float fval;
  int32_t ival;
  int pop_retv;

  /* Raise TypeError if wrong number of args */
  pa = NATIVE_GET_LOCAL(0);
  if(NATIVE_GET_NUM_ARGS() != 1) {
    PM_RAISE(retv, PM_RET_EX_TYPE);
    return retv;
  }
  switch (OBJ_GET_TYPE(pa)) {
    //case OBJ_TYPE_STR:
    //  ptr = (char const *)&(((pPmString_t)pa)->val);
    //  // TODO: unimplemented
    //  break;
  case OBJ_TYPE_INT:
    pop_retv = pop_int(&ival);
    if(pop_retv != TRES_ERR_NONE) {
      ival = ((pPmInt_t) pa)->val;
    }
    retv = int_new(ival, &r_pflt);
    break;
  case OBJ_TYPE_FLT:
    pop_retv = pop_float(&fval);
    if(pop_retv != TRES_ERR_NONE) {
      fval = ((pPmFloat_t) pa)->val;
    }
    retv = float_new(fval, &r_pflt);
    break;
  default:
    /* Raise TypeError */
    PM_RAISE(retv, PM_RET_EX_TYPE);
  }
  NATIVE_SET_TOS(r_pflt);

  return retv;
}
コード例 #3
0
/*----------------------------------------------------------------------------*/
PmReturn_t
tres_pm_set_output(pPmFrame_t *ppframe)
{
  const char *ptr;
  int32_t ival;
  float fval;
  PmReturn_t retv = PM_RET_OK;
  pPmObj_t pa;

  /* Raise TypeError if wrong number of args */
  if(NATIVE_GET_NUM_ARGS() != 1) {
    PM_RAISE(retv, PM_RET_EX_TYPE);
    return retv;
  }
  pa = NATIVE_GET_LOCAL(0);
  switch (OBJ_GET_TYPE(pa)) {
  case OBJ_TYPE_STR:
    ptr = (char const *)&(((pPmString_t) pa)->val);
    snprintf(tres_pm_io.out, REST_MAX_CHUNK_SIZE, "%s", ptr);
    break;
  case OBJ_TYPE_INT:
    ival = ((pPmInt_t) pa)->val;
    snprintf(tres_pm_io.out, REST_MAX_CHUNK_SIZE, "%" PRId32, ival);
    break;
  case OBJ_TYPE_FLT:
    fval = ((pPmFloat_t) pa)->val;
    // we cannot use snprintf: float are not supported
    //snprintf(tres_pm_io.out, REST_MAX_CHUNK_SIZE, "%f", fval);
    //therefore we use pymite sli_ftoa, which, however requires a buffer => 15
    if(REST_MAX_CHUNK_SIZE >= 15) {
      sli_ftoa(fval, (uint8_t *)tres_pm_io.out, REST_MAX_CHUNK_SIZE);
    }
    break;
  default:
    /* Raise TypeError */
    PM_RAISE(retv, PM_RET_EX_TYPE);
  }
  tres_pm_io.output_set = 1;
  NATIVE_SET_TOS(PM_NONE);

  return retv;
}
コード例 #4
0
/*----------------------------------------------------------------------------*/
PmReturn_t
tres_pm_save_state(pPmFrame_t *ppframe)
{
  PmReturn_t retv = PM_RET_OK;
  pPmObj_t pobj;
  pPmInstance_t pcli;
  pPmDict_t pdict;
  uint16_t index;

  if(NATIVE_GET_NUM_ARGS() != 1) {
    PM_RAISE(retv, PM_RET_EX_TYPE);
    return retv;
  }
  pobj = NATIVE_GET_LOCAL(0);
  if(OBJ_GET_TYPE(pobj) != OBJ_TYPE_CLI) {
    PM_RAISE(retv, PM_RET_EX_TYPE);
    return retv;
  }
  pcli = (pPmInstance_t)pobj;
  pdict = pcli->cli_attrs;

  // store each attribute of the object
  for(index = 0; index < pdict->length; index++) {
    seglist_getItem(pdict->d_keys, index, &pobj);
    retv = seglist_getItem(pdict->d_vals, index, &pobj);
    PM_RETURN_IF_ERROR(retv);
    switch (OBJ_GET_TYPE(pobj)) {
    case OBJ_TYPE_INT:
      push_int(((pPmInt_t) pobj)->val);
      break;
    case OBJ_TYPE_FLT:
      push_float(((pPmFloat_t) pobj)->val);
      break;
    }
  }
  NATIVE_SET_TOS(PM_NONE);
  return retv;
}
コード例 #5
0
/*----------------------------------------------------------------------------*/
PmReturn_t
tres_pm_state_push(pPmFrame_t *ppframe)
{
  //const char *ptr;
  int32_t ival;
  float fval;
  PmReturn_t retv = PM_RET_OK;
  pPmObj_t pa;

  /* Raise TypeError if wrong number of args */
  pa = NATIVE_GET_LOCAL(0);
  if(NATIVE_GET_NUM_ARGS() != 1) {
    PM_RAISE(retv, PM_RET_EX_TYPE);
    return retv;
  }
  switch (OBJ_GET_TYPE(pa)) {
    //case OBJ_TYPE_STR:
    //  ptr = (char const *)&(((pPmString_t)pa)->val);
    //  // TODO: unimplemented
    //  break;
  case OBJ_TYPE_INT:
    ival = ((pPmInt_t) pa)->val;
    push_int(ival);
    break;
  case OBJ_TYPE_FLT:
    fval = ((pPmFloat_t) pa)->val;
    push_float(fval);
    break;
  default:
    /* Raise TypeError */
    PM_RAISE(retv, PM_RET_EX_TYPE);
  }
  NATIVE_SET_TOS(PM_NONE);

  return retv;
}
コード例 #6
0
ファイル: heap.c プロジェクト: 01iv3r/OpenPilot
/*
 * Marks the given object and the objects it references.
 *
 * @param   pobj Any non-free heap object
 * @return  Return code
 */
static PmReturn_t
heap_gcMarkObj(pPmObj_t pobj)
{
    PmReturn_t retval = PM_RET_OK;
    int16_t i = 0;
    int16_t n;
    PmType_t type;

    /* Return if ptr is null or object is already marked */
    if (pobj == C_NULL)
    {
        return retval;
    }
    if (OBJ_GET_GCVAL(pobj) == pmHeap.gcval)
    {
        return retval;
    }

    /* The pointer must be within the heap (native frame is special case) */
    C_ASSERT((((uint8_t *)pobj >= &pmHeap.base[0])
              && ((uint8_t *)pobj <= &pmHeap.base[PM_HEAP_SIZE]))
             || ((uint8_t *)pobj == (uint8_t *)&gVmGlobal.nativeframe));

    /* The object must not already be free */
    C_ASSERT(OBJ_GET_FREE(pobj) == 0);

    type = (PmType_t)OBJ_GET_TYPE(pobj);
    switch (type)
    {
            /* Objects with no references to other objects */
        case OBJ_TYPE_NON:
        case OBJ_TYPE_INT:
        case OBJ_TYPE_FLT:
        case OBJ_TYPE_STR:
        case OBJ_TYPE_NOB:
        case OBJ_TYPE_BOOL:
        case OBJ_TYPE_CIO:
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);
            break;

        case OBJ_TYPE_TUP:
            i = ((pPmTuple_t)pobj)->length;

            /* Mark tuple head */
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);

            /* Mark each obj in tuple */
            while (--i >= 0)
            {
                retval = heap_gcMarkObj(((pPmTuple_t)pobj)->val[i]);
                PM_RETURN_IF_ERROR(retval);
            }
            break;

        case OBJ_TYPE_LST:

            /* Mark the list */
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);

            /* Mark the seglist */
            retval = heap_gcMarkObj((pPmObj_t)((pPmList_t)pobj)->val);
            break;

        case OBJ_TYPE_DIC:
            /* Mark the dict head */
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);

            /* Mark the keys seglist */
            retval = heap_gcMarkObj((pPmObj_t)((pPmDict_t)pobj)->d_keys);
            PM_RETURN_IF_ERROR(retval);

            /* Mark the vals seglist */
            retval = heap_gcMarkObj((pPmObj_t)((pPmDict_t)pobj)->d_vals);
            break;

        case OBJ_TYPE_COB:
            /* Mark the code obj head */
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);

            /* Mark the names tuple */
            retval = heap_gcMarkObj((pPmObj_t)((pPmCo_t)pobj)->co_names);
            PM_RETURN_IF_ERROR(retval);

            /* Mark the consts tuple */
            retval = heap_gcMarkObj((pPmObj_t)((pPmCo_t)pobj)->co_consts);
            PM_RETURN_IF_ERROR(retval);

            /* #122: Mark the code image if it is in RAM */
            if (((pPmCo_t)pobj)->co_memspace == MEMSPACE_RAM)
            {
                retval = heap_gcMarkObj((pPmObj_t)
                                        (((pPmCo_t)pobj)->co_codeimgaddr));
                PM_RETURN_IF_ERROR(retval);
            }

#ifdef HAVE_CLOSURES
            /* #256: Add support for closures */
            /* Mark the cellvars tuple */
            retval = heap_gcMarkObj((pPmObj_t)((pPmCo_t)pobj)->co_cellvars);
#endif /* HAVE_CLOSURES */
            break;

        case OBJ_TYPE_MOD:
        case OBJ_TYPE_FXN:
            /* Module and Func objs are implemented via the PmFunc_t */
            /* Mark the func obj head */
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);

            /* Mark the code obj */
            retval = heap_gcMarkObj((pPmObj_t)((pPmFunc_t)pobj)->f_co);
            PM_RETURN_IF_ERROR(retval);

            /* Mark the attr dict */
            retval = heap_gcMarkObj((pPmObj_t)((pPmFunc_t)pobj)->f_attrs);
            PM_RETURN_IF_ERROR(retval);

            /* Mark the globals dict */
            retval = heap_gcMarkObj((pPmObj_t)((pPmFunc_t)pobj)->f_globals);
            PM_RETURN_IF_ERROR(retval);

#ifdef HAVE_DEFAULTARGS
            /* Mark the default args tuple */
            retval = heap_gcMarkObj((pPmObj_t)((pPmFunc_t)pobj)->f_defaultargs);
            PM_RETURN_IF_ERROR(retval);
#endif /* HAVE_DEFAULTARGS */

#ifdef HAVE_CLOSURES
            /* #256: Mark the closure tuple */
            retval = heap_gcMarkObj((pPmObj_t)((pPmFunc_t)pobj)->f_closure);
#endif /* HAVE_CLOSURES */
            break;

#ifdef HAVE_CLASSES
        case OBJ_TYPE_CLI:
            /* Mark the obj head */
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);

            /* Mark the class */
            retval = heap_gcMarkObj((pPmObj_t)((pPmInstance_t)pobj)->cli_class);
            PM_RETURN_IF_ERROR(retval);

            /* Mark the attrs dict */
            retval = heap_gcMarkObj((pPmObj_t)((pPmInstance_t)pobj)->cli_attrs);
            break;

        case OBJ_TYPE_MTH:
            /* Mark the obj head */
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);

            /* Mark the instance */
            retval = heap_gcMarkObj((pPmObj_t)((pPmMethod_t)pobj)->m_instance);
            PM_RETURN_IF_ERROR(retval);

            /* Mark the func */
            retval = heap_gcMarkObj((pPmObj_t)((pPmMethod_t)pobj)->m_func);
            PM_RETURN_IF_ERROR(retval);

            /* Mark the attrs dict */
            retval = heap_gcMarkObj((pPmObj_t)((pPmMethod_t)pobj)->m_attrs);
            break;

        case OBJ_TYPE_CLO:
            /* Mark the obj head */
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);

            /* Mark the attrs dict */
            retval = heap_gcMarkObj((pPmObj_t)((pPmClass_t)pobj)->cl_attrs);
            PM_RETURN_IF_ERROR(retval);

            /* Mark the base tuple */
            retval = heap_gcMarkObj((pPmObj_t)((pPmClass_t)pobj)->cl_bases);
            break;
#endif /* HAVE_CLASSES */

            /*
             * An obj in ram should not be of these types.
             * Images arrive in RAM as string objects (image is array of bytes)
             */
        case OBJ_TYPE_CIM:
        case OBJ_TYPE_NIM:
            PM_RAISE(retval, PM_RET_EX_SYS);
            return retval;

        case OBJ_TYPE_FRM:
        {
            pPmObj_t *ppobj2 = C_NULL;

            /* Mark the frame obj head */
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);

            /* Mark the previous frame, if this isn't a generator's frame */
            /* Issue #129: Fix iterator losing its object */
            if ((((pPmFrame_t)pobj)->fo_func->f_co->co_flags & CO_GENERATOR) == 0)
            {
                retval = heap_gcMarkObj((pPmObj_t)((pPmFrame_t)pobj)->fo_back);
                PM_RETURN_IF_ERROR(retval);
            }

            /* Mark the fxn obj */
            retval = heap_gcMarkObj((pPmObj_t)((pPmFrame_t)pobj)->fo_func);
            PM_RETURN_IF_ERROR(retval);

            /* Mark the blockstack */
            retval = heap_gcMarkObj((pPmObj_t)
                                    ((pPmFrame_t)pobj)->fo_blockstack);
            PM_RETURN_IF_ERROR(retval);

            /* Mark the attrs dict */
            retval = heap_gcMarkObj((pPmObj_t)((pPmFrame_t)pobj)->fo_attrs);
            PM_RETURN_IF_ERROR(retval);

            /* Mark the globals dict */
            retval = heap_gcMarkObj((pPmObj_t)((pPmFrame_t)pobj)->fo_globals);
            PM_RETURN_IF_ERROR(retval);

            /* Mark each obj in the locals list and the stack */
            ppobj2 = ((pPmFrame_t)pobj)->fo_locals;
            while (ppobj2 < ((pPmFrame_t)pobj)->fo_sp)
            {
                retval = heap_gcMarkObj(*ppobj2);
                PM_RETURN_IF_ERROR(retval);
                ppobj2++;
            }
            break;
        }

        case OBJ_TYPE_BLK:
            /* Mark the block obj head */
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);

            /* Mark the next block in the stack */
            retval = heap_gcMarkObj((pPmObj_t)((pPmBlock_t)pobj)->next);
            break;

        case OBJ_TYPE_SGL:
            /* Mark the seglist obj head */
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);

            /* Mark the seglist's segments */
            n = ((pSeglist_t)pobj)->sl_length;
            pobj = (pPmObj_t)((pSeglist_t)pobj)->sl_rootseg;
            for (i = 0; i < n; i++)
            {
                /* Mark the segment item */
                retval = heap_gcMarkObj(((pSegment_t)pobj)->s_val[i % SEGLIST_OBJS_PER_SEG]);
                PM_RETURN_IF_ERROR(retval);

                /* Mark the segment obj head */
                if ((i % SEGLIST_OBJS_PER_SEG) == 0)
                {
                    OBJ_SET_GCVAL(pobj, pmHeap.gcval);
                }

                /* Point to the next segment */
                else
                if ((i % SEGLIST_OBJS_PER_SEG) == (SEGLIST_OBJS_PER_SEG - 1))
                {
                    pobj = (pPmObj_t)((pSegment_t)pobj)->next;
                    if (pobj == C_NULL)
                    {
                        break;
                    }
                }
            }
            break;

        case OBJ_TYPE_SQI:
            /* Mark the sequence iterator obj head */
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);

            /* Mark the sequence */
            retval = heap_gcMarkObj(((pPmSeqIter_t)pobj)->si_sequence);
            break;

        case OBJ_TYPE_THR:
            /* Mark the thread obj head */
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);

            /* Mark the current frame */
            retval = heap_gcMarkObj((pPmObj_t)((pPmThread_t)pobj)->pframe);
            break;

        case OBJ_TYPE_NFM:
            /*
             * Mark the obj desc.  This doesn't really do much since the
             * native frame is declared static (not from the heap), but this
             * is here in case that ever changes
             */
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);

            /* Mark the native frame's remaining fields if active */
            if (gVmGlobal.nativeframe.nf_active)
            {
                /* Mark the frame stack */
                retval = heap_gcMarkObj((pPmObj_t)
                                        gVmGlobal.nativeframe.nf_back);
                PM_RETURN_IF_ERROR(retval);

                /* Mark the function object */
                retval = heap_gcMarkObj((pPmObj_t)
                                        gVmGlobal.nativeframe.nf_func);
                PM_RETURN_IF_ERROR(retval);

                /* Mark the stack object */
                retval = heap_gcMarkObj(gVmGlobal.nativeframe.nf_stack);
                PM_RETURN_IF_ERROR(retval);

                /* Mark the args to the native func */
                for (i = 0; i < NATIVE_GET_NUM_ARGS(); i++)
                {
                    retval =
                        heap_gcMarkObj(gVmGlobal.nativeframe.nf_locals[i]);
                    PM_RETURN_IF_ERROR(retval);
                }
            }
            break;

#ifdef HAVE_BYTEARRAY
        case OBJ_TYPE_BYA:
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);

            retval = heap_gcMarkObj((pPmObj_t)((pPmBytearray_t)pobj)->val);
            break;

        case OBJ_TYPE_BYS:
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);
            break;
#endif /* HAVE_BYTEARRAY */

        default:
            /* There should be no invalid types */
            PM_RAISE(retval, PM_RET_EX_SYS);
            break;
    }
    return retval;
}
コード例 #7
0
ファイル: heap.c プロジェクト: BackupGGCode/megapython
/*
 * Marks the given object and the objects it references.
 *
 * @param   pobj Any non-free heap object
 * @return  Return code
 */
static PmReturn_t
heap_gcMarkObj(pPmObj_t pobj)
{
    PmReturn_t retval = PM_RET_OK;
    int16_t i = 0;
    PmType_t type;

    /* Return if ptr is null or object is already marked */
    if ((pobj == C_NULL) || (OBJ_GET_GCVAL(pobj) == pmHeap.gcval))
    {
        return retval;
    }

    /* The pointer must be within the heap (native frame is special case) */
    C_ASSERT((((uint8_t *)pobj >= &pmHeap.base[0])
             && ((uint8_t *)pobj <= &pmHeap.base[HEAP_SIZE]))
             || ((uint8_t *)pobj == (uint8_t *)&gVmGlobal.nativeframe));

    /* The object must not already be free */
    C_ASSERT(OBJ_GET_FREE(pobj) == 0);

    type = OBJ_GET_TYPE(pobj);
    /*if (type == 0x03){
	printf("came across string; value is ");
	string_print(pobj,0);
	printf("\n");
    }*/
    switch (type)
    {
        /* Objects with no references to other objects */
        case OBJ_TYPE_NON:
        case OBJ_TYPE_INT:
        case OBJ_TYPE_FLT:
        case OBJ_TYPE_NOB:
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);
            break;

        case OBJ_TYPE_STR:
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);
#if USE_STRING_CACHE
            retval = heap_gcMarkObj((pPmObj_t)((pPmString_t)pobj)->next);
#endif
            break;

        case OBJ_TYPE_TUP:
            i = ((pPmTuple_t)pobj)->length;

            /* Mark tuple head */
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);

            /* Mark each obj in tuple */
            while (--i >= 0)
            {
                retval = heap_gcMarkObj(((pPmTuple_t)pobj)->val[i]);
                PM_RETURN_IF_ERROR(retval);
            }
            break;

        case OBJ_TYPE_LST:

            /* Mark the list */
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);

            /* Mark the seglist */
            retval = heap_gcMarkObj((pPmObj_t)((pPmList_t)pobj)->val);
            break;

        case OBJ_TYPE_DIC:
            /* Mark the dict head */
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);

            /* Mark the keys seglist */
            retval = heap_gcMarkObj((pPmObj_t)((pPmDict_t)pobj)->d_keys);
            PM_RETURN_IF_ERROR(retval);

            /* Mark the vals seglist */
            retval = heap_gcMarkObj((pPmObj_t)((pPmDict_t)pobj)->d_vals);
            break;

        case OBJ_TYPE_COB:
            /* Mark the code obj head */
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);

            /* Mark the names tuple */
            retval = heap_gcMarkObj((pPmObj_t)((pPmCo_t)pobj)->co_names);
            PM_RETURN_IF_ERROR(retval);

            /* Mark the consts tuple */
            retval = heap_gcMarkObj((pPmObj_t)((pPmCo_t)pobj)->co_consts);
            PM_RETURN_IF_ERROR(retval);

            /* #122: Mark the code image if it is in RAM */
            if (((pPmCo_t)pobj)->co_memspace == MEMSPACE_RAM)
            {
                /* Special case: The image is contained in a string object */
                retval = heap_gcMarkObj((pPmObj_t)
                                        (((pPmCo_t)pobj)->co_codeimgaddr
                                         - sizeof(PmObjDesc_t)));
            }
            break;

        case OBJ_TYPE_MOD:
        case OBJ_TYPE_FXN:
            /* Module and Func objs are implemented via the PmFunc_t */
            /* Mark the func obj head */
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);

            /* Mark the code obj */
            retval = heap_gcMarkObj((pPmObj_t)((pPmFunc_t)pobj)->f_co);
            PM_RETURN_IF_ERROR(retval);

            /* Mark the attr dict */
            retval = heap_gcMarkObj((pPmObj_t)((pPmFunc_t)pobj)->f_attrs);
            PM_RETURN_IF_ERROR(retval);

            /* Mark the default args tuple */
            retval = heap_gcMarkObj((pPmObj_t)
                                    ((pPmFunc_t)pobj)->f_defaultargs);
            break;

        case OBJ_TYPE_CLO:
        case OBJ_TYPE_CLI:
        case OBJ_TYPE_EXN:
            /* Mark the obj head */
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);

            /* Mark the attrs dict */
            retval = heap_gcMarkObj((pPmObj_t)((pPmClass_t)pobj)->attrs);
            PM_RETURN_IF_ERROR(retval);

            /* Mark the name */
            retval = heap_gcMarkObj((pPmObj_t)((pPmClass_t)pobj)->name);
            PM_RETURN_IF_ERROR(retval);

            /* Mark the bases */
            retval = heap_gcMarkObj((pPmObj_t)((pPmClass_t)pobj)->bases);
            break;

        /*
         * An obj in ram should not be of these types.
         * Images arrive in RAM as string objects (image is array of bytes)
         */
        case OBJ_TYPE_CIM:
        case OBJ_TYPE_NIM:
            PM_RAISE(retval, PM_RET_EX_SYS);
            return retval;

        case OBJ_TYPE_FRM:
        {
            pPmObj_t *ppobj2 = C_NULL;

            /* Mark the frame obj head */
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);

            /* Mark the previous frame */
            retval = heap_gcMarkObj((pPmObj_t)((pPmFrame_t)pobj)->fo_back);
            PM_RETURN_IF_ERROR(retval);

            /* Mark the fxn obj */
            retval = heap_gcMarkObj((pPmObj_t)((pPmFrame_t)pobj)->fo_func);
            PM_RETURN_IF_ERROR(retval);

            /* Mark the blockstack */
            retval = heap_gcMarkObj((pPmObj_t)
                                    ((pPmFrame_t)pobj)->fo_blockstack);
            PM_RETURN_IF_ERROR(retval);

            /* Mark the attrs dict */
            retval = heap_gcMarkObj((pPmObj_t)((pPmFrame_t)pobj)->fo_attrs);
            PM_RETURN_IF_ERROR(retval);

            /* Mark the globals dict */
            retval = heap_gcMarkObj((pPmObj_t)((pPmFrame_t)pobj)->fo_globals);
            PM_RETURN_IF_ERROR(retval);

            /* Mark each obj in the locals list and the stack */
            ppobj2 = ((pPmFrame_t)pobj)->fo_locals;
            while (ppobj2 < ((pPmFrame_t)pobj)->fo_sp)
            {
                retval = heap_gcMarkObj(*ppobj2);
                PM_RETURN_IF_ERROR(retval);
                ppobj2++;
            }
            break;
        }

        case OBJ_TYPE_BLK:
            /* Mark the block obj head */
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);

            /* Mark the next block in the stack */
            retval = heap_gcMarkObj((pPmObj_t)((pPmBlock_t)pobj)->next);
            break;

        case OBJ_TYPE_SEG:
            /* Mark the segment obj head */
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);

            /* Mark each obj in the segment */
            for (i = 0; i < SEGLIST_OBJS_PER_SEG; i++)
            {
                retval = heap_gcMarkObj(((pSegment_t)pobj)->s_val[i]);
                PM_RETURN_IF_ERROR(retval);
            }

            /* Mark the next segment */
            retval = heap_gcMarkObj((pPmObj_t)((pSegment_t)pobj)->next);
            break;

        case OBJ_TYPE_SGL:
            /* Mark the seglist obj head */
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);

            /* Mark the root segment */
            retval = heap_gcMarkObj((pPmObj_t)((pSeglist_t)pobj)->sl_rootseg);
            break;

        case OBJ_TYPE_SQI:
            /* Mark the sequence iterator obj head */
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);

            /* Mark the sequence */
            retval = heap_gcMarkObj(((pPmSeqIter_t)pobj)->si_sequence);
            break;

        case OBJ_TYPE_THR:
            /* Mark the thread obj head */
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);

            /* Mark the current frame */
            retval = heap_gcMarkObj((pPmObj_t)((pPmThread_t)pobj)->pframe);
            break;

        case OBJ_TYPE_NFM:
            /*
             * Mark the obj desc.  This doesn't really do much since the
             * native frame is declared static (not from the heap), but this
             * is here in case that ever changes
             */
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);

            /* Mark the native frame's fields if it is active */
            if (gVmGlobal.nativeframe.nf_active)
            {
                /* Mark the frame stack */
                retval = heap_gcMarkObj((pPmObj_t)
                                        gVmGlobal.nativeframe.nf_back);
                PM_RETURN_IF_ERROR(retval);

                /* Mark the function object */
                retval = heap_gcMarkObj((pPmObj_t)
                                        gVmGlobal.nativeframe.nf_func);
                PM_RETURN_IF_ERROR(retval);

                /* Mark the stack object */
                retval = heap_gcMarkObj(gVmGlobal.nativeframe.nf_stack);
                PM_RETURN_IF_ERROR(retval);

                /* Mark the args to the native func */
                for (i = 0; i < NATIVE_GET_NUM_ARGS(); i++)
                {
                    retval = heap_gcMarkObj(gVmGlobal.nativeframe
                                            .nf_locals[i]);
                    PM_RETURN_IF_ERROR(retval);
                }
            }
            break;

        case OBJ_TYPE_IIS:
            /* Mark the obj desc */
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);

            /* Mark the name string */
            retval = heap_gcMarkObj((pPmObj_t)((pPmImgInfo_t)pobj)->ii_name);
            PM_RETURN_IF_ERROR(retval);

            /* Mark the next node in the list */
            retval = heap_gcMarkObj((pPmObj_t)((pPmImgInfo_t)pobj)->next);
            break;

        case OBJ_TYPE_SLC:
            /* Mark the obj desc */
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);

            /* Mark the indices */
            retval = heap_gcMarkObj((pPmObj_t)((pPmSlice_t)pobj)->start);
            PM_RETURN_IF_ERROR(retval);
            retval = heap_gcMarkObj((pPmObj_t)((pPmSlice_t)pobj)->end);
            PM_RETURN_IF_ERROR(retval);
            retval = heap_gcMarkObj((pPmObj_t)((pPmSlice_t)pobj)->step);
            PM_RETURN_IF_ERROR(retval);

            break;
        case OBJ_TYPE_MTH:
            /* Mark the obj desc */
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);

            /* Mark the function and self */
            retval = heap_gcMarkObj((pPmObj_t)((pPmMethod_t)pobj)->self);
            PM_RETURN_IF_ERROR(retval);
            retval = heap_gcMarkObj((pPmObj_t)((pPmMethod_t)pobj)->func);
            PM_RETURN_IF_ERROR(retval);

            break;
    }
    return retval;
}