frame.c

Go to the documentation of this file.
00001 /*
00002 # This file is Copyright 2003, 2006, 2007, 2009, 2010 Dean Hall.
00003 #
00004 # This file is part of the PyMite VM.
00005 # The PyMite VM is free software: you can redistribute it and/or modify
00006 # it under the terms of the GNU GENERAL PUBLIC LICENSE Version 2.
00007 #
00008 # The PyMite VM is distributed in the hope that it will be useful,
00009 # but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00011 # A copy of the GNU GENERAL PUBLIC LICENSE Version 2
00012 # is seen in the file COPYING in this directory.
00013 */
00014 
00015 
00016 #undef __FILE_ID__
00017 #define __FILE_ID__ 0x03
00018 
00019 
00028 #include "pm.h"
00029 
00030 
00031 PmReturn_t
00032 frame_new(pPmObj_t pfunc, pPmObj_t *r_pobj)
00033 {
00034     PmReturn_t retval = PM_RET_OK;
00035     int16_t fsize = 0;
00036     pPmCo_t pco = C_NULL;
00037     pPmFrame_t pframe = C_NULL;
00038     uint8_t *pchunk;
00039 
00040     /* Get fxn's code obj */
00041     pco = ((pPmFunc_t)pfunc)->f_co;
00042 
00043     /* TypeError if passed func's CO is not a true COB */
00044     if (OBJ_GET_TYPE(pco) != OBJ_TYPE_COB)
00045     {
00046         PM_RAISE(retval, PM_RET_EX_TYPE);
00047         return retval;
00048     }
00049 
00050 #ifdef HAVE_GENERATORS
00051     /* #207: Initializing a Generator using CALL_FUNC needs extra stack slot */
00052     fsize = sizeof(PmFrame_t) + (pco->co_stacksize + pco->co_nlocals + 2) * sizeof(pPmObj_t);
00053 #elif defined(HAVE_CLASSES)
00054     /* #230: Calling a class's __init__() takes two extra spaces on the stack */
00055     fsize = sizeof(PmFrame_t) + (pco->co_stacksize + pco->co_nlocals + 1) * sizeof(pPmObj_t);
00056 #else
00057     fsize = sizeof(PmFrame_t) + (pco->co_stacksize + pco->co_nlocals - 1) * sizeof(pPmObj_t);
00058 #endif /* HAVE_CLASSES */
00059 
00060 #ifdef HAVE_CLOSURES
00061     /* #256: Add support for closures */
00062     fsize = fsize + pco->co_nfreevars
00063             + ((pco->co_cellvars == C_NULL) ? 0 : pco->co_cellvars->length);
00064 #endif /* HAVE_CLOSURES */
00065 
00066     /* Allocate a frame */
00067     retval = heap_getChunk(fsize, &pchunk);
00068     PM_RETURN_IF_ERROR(retval);
00069     pframe = (pPmFrame_t)pchunk;
00070 
00071     /* Set frame fields */
00072     OBJ_SET_TYPE(pframe, OBJ_TYPE_FRM);
00073     pframe->fo_back = C_NULL;
00074     pframe->fo_func = (pPmFunc_t)pfunc;
00075     pframe->fo_memspace = pco->co_memspace;
00076 
00077     /* Init instruction pointer and block stack */
00078     pframe->fo_ip = pco->co_codeaddr;
00079     pframe->fo_blockstack = C_NULL;
00080 
00081     /* Get globals and attrs from the function object */
00082     pframe->fo_globals = ((pPmFunc_t)pfunc)->f_globals;
00083     pframe->fo_attrs = ((pPmFunc_t)pfunc)->f_attrs;
00084 
00085 #ifndef HAVE_CLOSURES
00086     /* Empty stack points to one past locals */
00087     pframe->fo_sp = &(pframe->fo_locals[pco->co_nlocals]);
00088 #else
00089     /* #256: Add support for closures */
00090     pframe->fo_sp = &(pframe->fo_locals[pco->co_nlocals + pco->co_nfreevars
00091         + ((pco->co_cellvars == C_NULL) ? 0 : pco->co_cellvars->length)]);
00092 #endif /* HAVE_CLOSURES */
00093 
00094     /* By default, this is a normal frame, not an import or __init__ one */
00095     pframe->fo_isImport = 0;
00096 #ifdef HAVE_CLASSES
00097     pframe->fo_isInit = 0;
00098 #endif
00099 
00100     /* Clear the stack */
00101     sli_memset((unsigned char *)&(pframe->fo_locals), (char const)0,
00102                (unsigned int)fsize - sizeof(PmFrame_t));
00103 
00104     /* Return ptr to frame */
00105     *r_pobj = (pPmObj_t)pframe;
00106     return retval;
00107 }

Generated on Mon Oct 18 07:40:47 2010 for Python-on-a-chip by  doxygen 1.5.9