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

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