1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2024-12-05 13:24:11 +01:00
LibrePilot/flight/libraries/PyMite/vm/codeobj.c

183 lines
4.9 KiB
C
Raw Normal View History

/*
# This file is Copyright 2003, 2006, 2007, 2009, 2010 Dean Hall.
#
# This file is part of the PyMite VM.
# The PyMite VM is free software: you can redistribute it and/or modify
# it under the terms of the GNU GENERAL PUBLIC LICENSE Version 2.
#
# The PyMite VM is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# A copy of the GNU GENERAL PUBLIC LICENSE Version 2
# is seen in the file COPYING in this directory.
*/
#undef __FILE_ID__
#define __FILE_ID__ 0x01
/**
* \file
* \brief CodeObj Type
*
* CodeObj type operations.
*/
#include "pm.h"
/* The image format is defined by co_to_str() in src/tools/pmImgCreator.py */
PmReturn_t
co_loadFromImg(PmMemSpace_t memspace, uint8_t const **paddr, pPmObj_t *r_pco)
{
PmReturn_t retval = PM_RET_OK;
pPmObj_t pobj;
pPmCo_t pco = C_NULL;
uint8_t *pchunk;
uint8_t objid;
#ifdef HAVE_DEBUG_INFO
uint8_t objtype;
uint16_t len_str;
#endif /* HAVE_DEBUG_INFO */
/* Store ptr to top of code img (less type byte) */
uint8_t const *pci = *paddr - 1;
/* Get size of code img */
uint16_t size = mem_getWord(memspace, paddr);
/* Allocate a code obj */
retval = heap_getChunk(sizeof(PmCo_t), &pchunk);
PM_RETURN_IF_ERROR(retval);
pco = (pPmCo_t)pchunk;
/* Fill in the CO struct */
OBJ_SET_TYPE(pco, OBJ_TYPE_COB);
pco->co_memspace = memspace;
pco->co_argcount = mem_getByte(memspace, paddr);
pco->co_flags = mem_getByte(memspace, paddr);
pco->co_stacksize = mem_getByte(memspace, paddr);
pco->co_nlocals = mem_getByte(memspace, paddr);
/* Do not set code image address if image is in RAM.
* CIs in RAM have their image address set in obj_loadFromImgObj() */
pco->co_codeimgaddr = (memspace == MEMSPACE_RAM) ? C_NULL : pci;
/* Set these to null in case a GC occurs before their objects are alloc'd */
pco->co_names = C_NULL;
pco->co_consts = C_NULL;
#ifdef HAVE_CLOSURES
pco->co_nfreevars = mem_getByte(memspace, paddr);
pco->co_cellvars = C_NULL;
#endif /* HAVE_CLOSURES */
#ifdef HAVE_DEBUG_INFO
pco->co_firstlineno = mem_getWord(memspace, paddr);
pco->co_lnotab = C_NULL;
pco->co_filename = C_NULL;
#endif /* HAVE_DEBUG_INFO */
/* Load names (tuple obj) */
heap_gcPushTempRoot((pPmObj_t)pco, &objid);
retval = obj_loadFromImg(memspace, paddr, &pobj);
heap_gcPopTempRoot(objid);
PM_RETURN_IF_ERROR(retval);
pco->co_names = (pPmTuple_t)pobj;
#ifdef HAVE_DEBUG_INFO
/* Get address in memspace of line number table (including length) */
objtype = mem_getByte(memspace, paddr);
C_ASSERT(objtype == OBJ_TYPE_STR);
pco->co_lnotab = *paddr;
len_str = mem_getWord(memspace, paddr);
*paddr = *paddr + len_str;
/* Get address in memspace of CO's filename (excluding length) */
objtype = mem_getByte(memspace, paddr);
C_ASSERT(objtype == OBJ_TYPE_STR);
len_str = mem_getWord(memspace, paddr);
pco->co_filename = *paddr;
*paddr = *paddr + len_str;
#endif /* HAVE_DEBUG_INFO */
/* Load consts (tuple obj) assume it follows names */
heap_gcPushTempRoot((pPmObj_t)pco, &objid);
retval = obj_loadFromImg(memspace, paddr, &pobj);
heap_gcPopTempRoot(objid);
PM_RETURN_IF_ERROR(retval);
pco->co_consts = (pPmTuple_t)pobj;
#ifdef HAVE_CLOSURES
heap_gcPushTempRoot((pPmObj_t)pco, &objid);
retval = obj_loadFromImg(memspace, paddr, &pobj);
heap_gcPopTempRoot(objid);
PM_RETURN_IF_ERROR(retval);
/* Save RAM, don't keep empty tuple */
if (((pPmTuple_t)pobj)->length == 0)
{
heap_freeChunk(pobj);
}
else
{
pco->co_cellvars = (pPmTuple_t)pobj;
}
#endif /* HAVE_CLOSURES */
/* Start of bcode always follows consts */
pco->co_codeaddr = *paddr;
/* Set addr to point one past end of img */
*paddr = pci + size;
*r_pco = (pPmObj_t)pco;
return PM_RET_OK;
}
void
co_rSetCodeImgAddr(pPmCo_t pco, uint8_t const *pimg)
{
uint8_t i;
pco->co_codeimgaddr = pimg;
/* Set the image address for any COs in the constant pool */
for (i = 0; i < pco->co_consts->length; i++)
{
if (OBJ_GET_TYPE(pco->co_consts->val[i]) == OBJ_TYPE_COB)
{
co_rSetCodeImgAddr((pPmCo_t)pco->co_consts->val[i], pimg);
}
}
return;
}
PmReturn_t
no_loadFromImg(PmMemSpace_t memspace, uint8_t const **paddr, pPmObj_t *r_pno)
{
PmReturn_t retval = PM_RET_OK;
pPmNo_t pno = C_NULL;
uint8_t *pchunk;
/* Allocate a code obj */
retval = heap_getChunk(sizeof(PmNo_t), &pchunk);
PM_RETURN_IF_ERROR(retval);
pno = (pPmNo_t)pchunk;
/* Fill in the NO struct */
OBJ_SET_TYPE(pno, OBJ_TYPE_NOB);
pno->no_argcount = mem_getByte(memspace, paddr);
/* Get index into native fxn table */
pno->no_funcindx = (int16_t)mem_getWord(memspace, paddr);
*r_pno = (pPmObj_t)pno;
return PM_RET_OK;
}