Merged in f5soh/librepilot/update_credits (pull request #529)
[librepilot.git] / flight / libraries / PyMite / vm / codeobj.c
blob4f7fae73ebbd62a8d3893de4774d81f13161f1dd
1 /*
2 # This file is Copyright 2003, 2006, 2007, 2009, 2010 Dean Hall.
4 # This file is part of the PyMite VM.
5 # The PyMite VM is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU GENERAL PUBLIC LICENSE Version 2.
8 # The PyMite VM is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 # A copy of the GNU GENERAL PUBLIC LICENSE Version 2
12 # is seen in the file COPYING in this directory.
16 #undef __FILE_ID__
17 #define __FILE_ID__ 0x01
20 /**
21 * \file
22 * \brief CodeObj Type
24 * CodeObj type operations.
28 #include "pm.h"
31 /* The image format is defined by co_to_str() in src/tools/pmImgCreator.py */
32 PmReturn_t
33 co_loadFromImg(PmMemSpace_t memspace, uint8_t const **paddr, pPmObj_t *r_pco)
35 PmReturn_t retval = PM_RET_OK;
36 pPmObj_t pobj;
37 pPmCo_t pco = C_NULL;
38 uint8_t *pchunk;
39 uint8_t objid;
40 #ifdef HAVE_DEBUG_INFO
41 uint8_t objtype;
42 uint16_t len_str;
43 #endif /* HAVE_DEBUG_INFO */
45 /* Store ptr to top of code img (less type byte) */
46 uint8_t const *pci = *paddr - 1;
48 /* Get size of code img */
49 uint16_t size = mem_getWord(memspace, paddr);
51 /* Allocate a code obj */
52 retval = heap_getChunk(sizeof(PmCo_t), &pchunk);
53 PM_RETURN_IF_ERROR(retval);
54 pco = (pPmCo_t)pchunk;
56 /* Fill in the CO struct */
57 OBJ_SET_TYPE(pco, OBJ_TYPE_COB);
58 pco->co_memspace = memspace;
59 pco->co_argcount = mem_getByte(memspace, paddr);
60 pco->co_flags = mem_getByte(memspace, paddr);
61 pco->co_stacksize = mem_getByte(memspace, paddr);
62 pco->co_nlocals = mem_getByte(memspace, paddr);
64 /* Do not set code image address if image is in RAM.
65 * CIs in RAM have their image address set in obj_loadFromImgObj() */
66 pco->co_codeimgaddr = (memspace == MEMSPACE_RAM) ? C_NULL : pci;
68 /* Set these to null in case a GC occurs before their objects are alloc'd */
69 pco->co_names = C_NULL;
70 pco->co_consts = C_NULL;
72 #ifdef HAVE_CLOSURES
73 pco->co_nfreevars = mem_getByte(memspace, paddr);
74 pco->co_cellvars = C_NULL;
75 #endif /* HAVE_CLOSURES */
77 #ifdef HAVE_DEBUG_INFO
78 pco->co_firstlineno = mem_getWord(memspace, paddr);
79 pco->co_lnotab = C_NULL;
80 pco->co_filename = C_NULL;
81 #endif /* HAVE_DEBUG_INFO */
83 /* Load names (tuple obj) */
84 heap_gcPushTempRoot((pPmObj_t)pco, &objid);
85 retval = obj_loadFromImg(memspace, paddr, &pobj);
86 heap_gcPopTempRoot(objid);
87 PM_RETURN_IF_ERROR(retval);
88 pco->co_names = (pPmTuple_t)pobj;
90 #ifdef HAVE_DEBUG_INFO
91 /* Get address in memspace of line number table (including length) */
92 objtype = mem_getByte(memspace, paddr);
93 C_ASSERT(objtype == OBJ_TYPE_STR);
94 pco->co_lnotab = *paddr;
95 len_str = mem_getWord(memspace, paddr);
96 *paddr = *paddr + len_str;
98 /* Get address in memspace of CO's filename (excluding length) */
99 objtype = mem_getByte(memspace, paddr);
100 C_ASSERT(objtype == OBJ_TYPE_STR);
101 len_str = mem_getWord(memspace, paddr);
102 pco->co_filename = *paddr;
103 *paddr = *paddr + len_str;
104 #endif /* HAVE_DEBUG_INFO */
106 /* Load consts (tuple obj) assume it follows names */
107 heap_gcPushTempRoot((pPmObj_t)pco, &objid);
108 retval = obj_loadFromImg(memspace, paddr, &pobj);
109 heap_gcPopTempRoot(objid);
110 PM_RETURN_IF_ERROR(retval);
111 pco->co_consts = (pPmTuple_t)pobj;
113 #ifdef HAVE_CLOSURES
114 heap_gcPushTempRoot((pPmObj_t)pco, &objid);
115 retval = obj_loadFromImg(memspace, paddr, &pobj);
116 heap_gcPopTempRoot(objid);
117 PM_RETURN_IF_ERROR(retval);
119 /* Save RAM, don't keep empty tuple */
120 if (((pPmTuple_t)pobj)->length == 0)
122 heap_freeChunk(pobj);
124 else
126 pco->co_cellvars = (pPmTuple_t)pobj;
128 #endif /* HAVE_CLOSURES */
130 /* Start of bcode always follows consts */
131 pco->co_codeaddr = *paddr;
133 /* Set addr to point one past end of img */
134 *paddr = pci + size;
136 *r_pco = (pPmObj_t)pco;
137 return PM_RET_OK;
141 void
142 co_rSetCodeImgAddr(pPmCo_t pco, uint8_t const *pimg)
144 uint8_t i;
146 pco->co_codeimgaddr = pimg;
148 /* Set the image address for any COs in the constant pool */
149 for (i = 0; i < pco->co_consts->length; i++)
151 if (OBJ_GET_TYPE(pco->co_consts->val[i]) == OBJ_TYPE_COB)
153 co_rSetCodeImgAddr((pPmCo_t)pco->co_consts->val[i], pimg);
157 return;
161 PmReturn_t
162 no_loadFromImg(PmMemSpace_t memspace, uint8_t const **paddr, pPmObj_t *r_pno)
164 PmReturn_t retval = PM_RET_OK;
165 pPmNo_t pno = C_NULL;
166 uint8_t *pchunk;
168 /* Allocate a code obj */
169 retval = heap_getChunk(sizeof(PmNo_t), &pchunk);
170 PM_RETURN_IF_ERROR(retval);
171 pno = (pPmNo_t)pchunk;
173 /* Fill in the NO struct */
174 OBJ_SET_TYPE(pno, OBJ_TYPE_NOB);
175 pno->no_argcount = mem_getByte(memspace, paddr);
177 /* Get index into native fxn table */
178 pno->no_funcindx = (int16_t)mem_getWord(memspace, paddr);
180 *r_pno = (pPmObj_t)pno;
181 return PM_RET_OK;