Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
frame.c
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
