Embed:
(wiki syntax)
Show/hide line numbers
frame.c
Go to the documentation of this file.
00001 /* 00002 # This file is Copyright 2003, 2006, 2007, 2009 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__ 0x03 00018 00019 00020 /** 00021 * \file 00022 * \brief VM Frame 00023 * 00024 * VM frame operations. 00025 */ 00026 00027 00028 #include "pm.h" 00029 00030 00031 PmReturn_t 00032 frame_new(pPmObj_t pfunc, pPmObj_t *r_pobj) 00033 { 00034 PmReturn_t retval = PM_RET_OK; 00035 int16_t fsize = 0; 00036 int8_t stacksz = (int8_t)0; 00037 int8_t nlocals = (int8_t)0; 00038 pPmCo_t pco = C_NULL; 00039 pPmFrame_t pframe = C_NULL; 00040 uint8_t const *paddr = C_NULL; 00041 uint8_t *pchunk; 00042 00043 /* Get fxn's code obj */ 00044 pco = ((pPmFunc_t)pfunc)->f_co; 00045 00046 /* TypeError if passed func's CO is not a true COB */ 00047 if (OBJ_GET_TYPE(pco) != OBJ_TYPE_COB) 00048 { 00049 PM_RAISE(retval, PM_RET_EX_TYPE); 00050 return retval; 00051 } 00052 00053 /* Get sizes needed to calc frame size */ 00054 if (pco->co_memspace == MEMSPACE_RAM) 00055 { 00056 paddr = (uint8_t *)((pPmCodeImgObj_t)pco->co_codeimgaddr)->val + CI_STACKSIZE_FIELD; 00057 } 00058 else 00059 { 00060 paddr = pco->co_codeimgaddr + CI_STACKSIZE_FIELD; 00061 } 00062 stacksz = mem_getByte(pco->co_memspace, &paddr); 00063 00064 /* Now paddr points to CI_NLOCALS_FIELD */ 00065 nlocals = mem_getByte(pco->co_memspace, &paddr); 00066 00067 #ifdef HAVE_GENERATORS 00068 /* #207: Initializing a Generator using CALL_FUNC needs extra stack slot */ 00069 fsize = sizeof(PmFrame_t) + (stacksz + nlocals + 2) * sizeof(pPmObj_t); 00070 #elif defined(HAVE_CLASSES) 00071 /* #230: Calling a class's __init__() takes two extra spaces on the stack */ 00072 fsize = sizeof(PmFrame_t) + (stacksz + nlocals + 1) * sizeof(pPmObj_t); 00073 #else 00074 fsize = sizeof(PmFrame_t) + (stacksz + nlocals - 1) * sizeof(pPmObj_t); 00075 #endif /* HAVE_CLASSES */ 00076 00077 #ifdef HAVE_CLOSURES 00078 /* #256: Add support for closures */ 00079 fsize = fsize + pco->co_nfreevars 00080 + ((pco->co_cellvars == C_NULL) ? 0 : pco->co_cellvars->length); 00081 #endif /* HAVE_CLOSURES */ 00082 00083 /* Allocate a frame */ 00084 retval = heap_getChunk(fsize, &pchunk); 00085 PM_RETURN_IF_ERROR(retval); 00086 pframe = (pPmFrame_t)pchunk; 00087 00088 /* Set frame fields */ 00089 OBJ_SET_TYPE(pframe, OBJ_TYPE_FRM); 00090 pframe->fo_back = C_NULL; 00091 pframe->fo_func = (pPmFunc_t)pfunc; 00092 pframe->fo_memspace = pco->co_memspace; 00093 00094 /* Init instruction pointer, line number and block stack */ 00095 pframe->fo_ip = pco->co_codeaddr; 00096 pframe->fo_blockstack = C_NULL; 00097 00098 /* Get globals and attrs from the function object */ 00099 pframe->fo_globals = ((pPmFunc_t)pfunc)->f_globals; 00100 pframe->fo_attrs = ((pPmFunc_t)pfunc)->f_attrs; 00101 00102 #ifndef HAVE_CLOSURES 00103 /* Empty stack points to one past locals */ 00104 pframe->fo_sp = &(pframe->fo_locals[nlocals]); 00105 #else 00106 /* #256: Add support for closures */ 00107 pframe->fo_sp = &(pframe->fo_locals[nlocals + pco->co_nfreevars 00108 + ((pco->co_cellvars == C_NULL) ? 0 : pco->co_cellvars->length)]); 00109 #endif /* HAVE_CLOSURES */ 00110 00111 /* By default, this is a normal frame, not an import or __init__ one */ 00112 pframe->fo_isImport = 0; 00113 #ifdef HAVE_CLASSES 00114 pframe->fo_isInit = 0; 00115 #endif 00116 00117 /* Clear the stack */ 00118 sli_memset((unsigned char *)&(pframe->fo_locals), (char const)0, 00119 (unsigned int)fsize - sizeof(PmFrame_t)); 00120 00121 /* Return ptr to frame */ 00122 *r_pobj = (pPmObj_t)pframe; 00123 return retval; 00124 }
Generated on Tue Jul 12 2022 17:07:01 by
1.7.2