python-on-a-chip online compiler

Dependencies:   mbed TSI

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers frame.c Source File

frame.c

Go to the documentation of this file.
00001 /*
00002 # This file is Copyright 2002 Dean Hall.
00003 # This file is part of the PyMite VM.
00004 # This file is licensed under the MIT License.
00005 # See the LICENSE file for details.
00006 */
00007 
00008 
00009 #undef __FILE_ID__
00010 #define __FILE_ID__ 0x03
00011 
00012 
00013 /**
00014  * \file
00015  * \brief VM Frame
00016  *
00017  * VM frame operations.
00018  */
00019 
00020 
00021 #include "pm.h"
00022 
00023 
00024 PmReturn_t
00025 frame_new(pPmObj_t pfunc, pPmObj_t *r_pobj)
00026 {
00027     PmReturn_t retval = PM_RET_OK;
00028     int16_t fsize = 0;
00029     pPmCo_t pco = C_NULL;
00030     pPmFrame_t pframe = C_NULL;
00031     uint8_t *pchunk;
00032 
00033     /* Get fxn's code obj */
00034     pco = ((pPmFunc_t)pfunc)->f_co;
00035 
00036     /* TypeError if passed func's CO is not a true COB */
00037     if (OBJ_GET_TYPE(pco) != OBJ_TYPE_COB)
00038     {
00039         PM_RAISE(retval, PM_RET_EX_TYPE);
00040         return retval;
00041     }
00042 
00043 #ifdef HAVE_GENERATORS
00044     /* #207: Initializing a Generator using CALL_FUNC needs extra stack slot */
00045     fsize = sizeof(PmFrame_t) + (pco->co_stacksize + pco->co_nlocals + 2) * sizeof(pPmObj_t);
00046 #elif defined(HAVE_CLASSES)
00047     /* #230: Calling a class's __init__() takes two extra spaces on the stack */
00048     fsize = sizeof(PmFrame_t) + (pco->co_stacksize + pco->co_nlocals + 1) * sizeof(pPmObj_t);
00049 #else
00050     fsize = sizeof(PmFrame_t) + (pco->co_stacksize + pco->co_nlocals - 1) * sizeof(pPmObj_t);
00051 #endif /* HAVE_CLASSES */
00052 
00053 #ifdef HAVE_CLOSURES
00054     /* #256: Add support for closures */
00055     fsize = fsize + pco->co_nfreevars
00056             + ((pco->co_cellvars == C_NULL) ? 0 : pco->co_cellvars->length);
00057 #endif /* HAVE_CLOSURES */
00058 
00059     /* Allocate a frame */
00060     retval = heap_getChunk(fsize, &pchunk);
00061     PM_RETURN_IF_ERROR(retval);
00062     pframe = (pPmFrame_t)pchunk;
00063 
00064     /* Set frame fields */
00065     OBJ_SET_TYPE(pframe, OBJ_TYPE_FRM);
00066     pframe->fo_back = C_NULL;
00067     pframe->fo_func = (pPmFunc_t)pfunc;
00068     pframe->fo_memspace = pco->co_memspace;
00069 
00070     /* Init instruction pointer and block stack */
00071     pframe->fo_ip = pco->co_codeaddr;
00072     pframe->fo_blockstack = C_NULL;
00073 
00074     /* Get globals and attrs from the function object */
00075     pframe->fo_globals = ((pPmFunc_t)pfunc)->f_globals;
00076     pframe->fo_attrs = ((pPmFunc_t)pfunc)->f_attrs;
00077 
00078 #ifndef HAVE_CLOSURES
00079     /* Empty stack points to one past locals */
00080     pframe->fo_sp = &(pframe->fo_locals[pco->co_nlocals]);
00081 #else
00082     /* #256: Add support for closures */
00083     pframe->fo_sp = &(pframe->fo_locals[pco->co_nlocals + pco->co_nfreevars
00084         + ((pco->co_cellvars == C_NULL) ? 0 : pco->co_cellvars->length)]);
00085 #endif /* HAVE_CLOSURES */
00086 
00087     /* By default, this is a normal frame, not an import or __init__ one */
00088     pframe->fo_isImport = 0;
00089 #ifdef HAVE_CLASSES
00090     pframe->fo_isInit = 0;
00091 #endif
00092 
00093     /* Clear the stack */
00094     sli_memset((unsigned char *)&(pframe->fo_locals), (char const)0,
00095                (unsigned int)fsize - sizeof(PmFrame_t));
00096 
00097     /* Return ptr to frame */
00098     *r_pobj = (pPmObj_t)pframe;
00099     return retval;
00100 }