Norimasa Okamoto
/
pymite
python-on-a-chip online compiler
Embed:
(wiki syntax)
Show/hide line numbers
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 }
Generated on Tue Jul 12 2022 23:13:47 by 1.7.2