python-on-a-chip online compiler

Dependencies:   mbed TSI

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers codeobj.c Source File

codeobj.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__ 0x01
00011 
00012 
00013 /**
00014  * \file
00015  * \brief CodeObj Type
00016  *
00017  * CodeObj type operations.
00018  */
00019 
00020 
00021 #include "pm.h"
00022 
00023 
00024 /* The image format is defined by co_to_str() in src/tools/pmImgCreator.py */
00025 PmReturn_t
00026 co_loadFromImg(PmMemSpace_t memspace, uint8_t const **paddr, pPmObj_t *r_pco)
00027 {
00028     PmReturn_t retval = PM_RET_OK;
00029     pPmObj_t pobj;
00030     pPmCo_t pco = C_NULL;
00031     uint8_t *pchunk;
00032     uint8_t objid;
00033 #ifdef HAVE_DEBUG_INFO
00034     uint8_t objtype;
00035     uint16_t len_str;
00036 #endif /* HAVE_DEBUG_INFO */
00037 
00038     /* Store ptr to top of code img (less type byte) */
00039     uint8_t const *pci = *paddr - 1;
00040 
00041     /* Get size of code img */
00042     uint16_t size = mem_getWord(memspace, paddr);
00043 
00044     /* Allocate a code obj */
00045     retval = heap_getChunk(sizeof(PmCo_t), &pchunk);
00046     PM_RETURN_IF_ERROR(retval);
00047     pco = (pPmCo_t)pchunk;
00048 
00049     /* Fill in the CO struct */
00050     OBJ_SET_TYPE(pco, OBJ_TYPE_COB);
00051     pco->co_memspace = memspace;
00052     pco->co_argcount = mem_getByte(memspace, paddr);
00053     pco->co_flags = mem_getByte(memspace, paddr);
00054     pco->co_stacksize = mem_getByte(memspace, paddr);
00055     pco->co_nlocals = mem_getByte(memspace, paddr);
00056 
00057     /* Do not set code image address if image is in RAM.
00058      * CIs in RAM have their image address set in obj_loadFromImgObj() */
00059     pco->co_codeimgaddr = (memspace == MEMSPACE_RAM) ? C_NULL : pci;
00060 
00061     /* Set these to null in case a GC occurs before their objects are alloc'd */
00062     pco->co_names = C_NULL;
00063     pco->co_consts = C_NULL;
00064     pco->co_codeaddr = C_NULL;
00065 
00066 #ifdef HAVE_CLOSURES
00067     pco->co_nfreevars = mem_getByte(memspace, paddr);
00068     pco->co_cellvars = C_NULL;
00069 #endif /* HAVE_CLOSURES */
00070 
00071 #ifdef HAVE_DEBUG_INFO
00072     pco->co_firstlineno = mem_getWord(memspace, paddr);
00073     pco->co_lnotab = C_NULL;
00074     pco->co_filename = C_NULL;
00075 #endif /* HAVE_DEBUG_INFO */
00076 
00077     /* Load names (tuple obj) */
00078     heap_gcPushTempRoot((pPmObj_t)pco, &objid);
00079     retval = obj_loadFromImg(memspace, paddr, &pobj);
00080     heap_gcPopTempRoot(objid);
00081     PM_RETURN_IF_ERROR(retval);
00082     pco->co_names = (pPmTuple_t)pobj;
00083 
00084 #ifdef HAVE_DEBUG_INFO
00085     /* Get address in memspace of line number table (including length) */
00086     objtype = mem_getByte(memspace, paddr);
00087     C_ASSERT(objtype == OBJ_TYPE_STR);
00088     pco->co_lnotab = *paddr;
00089     len_str = mem_getWord(memspace, paddr);
00090     *paddr = *paddr + len_str;
00091 
00092     /* Get address in memspace of CO's filename (excluding length) */
00093     objtype = mem_getByte(memspace, paddr);
00094     C_ASSERT(objtype == OBJ_TYPE_STR);
00095     len_str = mem_getWord(memspace, paddr);
00096     pco->co_filename = *paddr;
00097     *paddr = *paddr + len_str;
00098 #endif /* HAVE_DEBUG_INFO */
00099 
00100     /* Load consts (tuple obj) assume it follows names */
00101     heap_gcPushTempRoot((pPmObj_t)pco, &objid);
00102     retval = obj_loadFromImg(memspace, paddr, &pobj);
00103     heap_gcPopTempRoot(objid);
00104     PM_RETURN_IF_ERROR(retval);
00105     pco->co_consts = (pPmTuple_t)pobj;
00106 
00107 #ifdef HAVE_CLOSURES
00108     heap_gcPushTempRoot((pPmObj_t)pco, &objid);
00109     retval = obj_loadFromImg(memspace, paddr, &pobj);
00110     heap_gcPopTempRoot(objid);
00111     PM_RETURN_IF_ERROR(retval);
00112 
00113     /* Save RAM, don't keep empty tuple */
00114     if (((pPmTuple_t)pobj)->length == 0)
00115     {
00116         heap_freeChunk(pobj);
00117     }
00118     else
00119     {
00120         pco->co_cellvars = (pPmTuple_t)pobj;
00121     }
00122 #endif /* HAVE_CLOSURES */
00123 
00124     /* Start of bcode always follows consts */
00125     pco->co_codeaddr = *paddr;
00126 
00127     /* Set addr to point one past end of img */
00128     *paddr = pci + size;
00129 
00130     *r_pco = (pPmObj_t)pco;
00131     return PM_RET_OK;
00132 }
00133 
00134 
00135 void
00136 co_rSetCodeImgAddr(pPmCo_t pco, uint8_t const *pimg)
00137 {
00138     uint8_t i;
00139 
00140     pco->co_codeimgaddr = pimg;
00141 
00142     /* Set the image address for any COs in the constant pool */
00143     for (i = 0; i < pco->co_consts->length; i++)
00144     {
00145         if (OBJ_GET_TYPE(pco->co_consts->val[i]) == OBJ_TYPE_COB)
00146         {
00147             co_rSetCodeImgAddr((pPmCo_t)pco->co_consts->val[i], pimg);
00148         }
00149     }
00150 
00151     return;
00152 }
00153 
00154 
00155 PmReturn_t
00156 no_loadFromImg(PmMemSpace_t memspace, uint8_t const **paddr, pPmObj_t *r_pno)
00157 {
00158     PmReturn_t retval = PM_RET_OK;
00159     pPmNo_t pno = C_NULL;
00160     uint8_t *pchunk;
00161 
00162     /* Allocate a code obj */
00163     retval = heap_getChunk(sizeof(PmNo_t), &pchunk);
00164     PM_RETURN_IF_ERROR(retval);
00165     pno = (pPmNo_t)pchunk;
00166 
00167     /* Fill in the NO struct */
00168     OBJ_SET_TYPE(pno, OBJ_TYPE_NOB);
00169     pno->no_argcount = mem_getByte(memspace, paddr);
00170 
00171     /* Get index into native fxn table */
00172     pno->no_funcindx = (int16_t)mem_getWord(memspace, paddr);
00173 
00174     *r_pno = (pPmObj_t)pno;
00175     return PM_RET_OK;
00176 }