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.
17 #define __FILE_ID__ 0x03
24 * VM frame operations.
32 frame_new(pPmObj_t pfunc
, pPmObj_t
*r_pobj
)
34 PmReturn_t retval
= PM_RET_OK
;
37 pPmFrame_t pframe
= C_NULL
;
40 /* Get fxn's code obj */
41 pco
= ((pPmFunc_t
)pfunc
)->f_co
;
43 /* TypeError if passed func's CO is not a true COB */
44 if (OBJ_GET_TYPE(pco
) != OBJ_TYPE_COB
)
46 PM_RAISE(retval
, PM_RET_EX_TYPE
);
50 #ifdef HAVE_GENERATORS
51 /* #207: Initializing a Generator using CALL_FUNC needs extra stack slot */
52 fsize
= sizeof(PmFrame_t
) + (pco
->co_stacksize
+ pco
->co_nlocals
+ 2) * sizeof(pPmObj_t
);
53 #elif defined(HAVE_CLASSES)
54 /* #230: Calling a class's __init__() takes two extra spaces on the stack */
55 fsize
= sizeof(PmFrame_t
) + (pco
->co_stacksize
+ pco
->co_nlocals
+ 1) * sizeof(pPmObj_t
);
57 fsize
= sizeof(PmFrame_t
) + (pco
->co_stacksize
+ pco
->co_nlocals
- 1) * sizeof(pPmObj_t
);
58 #endif /* HAVE_CLASSES */
61 /* #256: Add support for closures */
62 fsize
= fsize
+ pco
->co_nfreevars
63 + ((pco
->co_cellvars
== C_NULL
) ? 0 : pco
->co_cellvars
->length
);
64 #endif /* HAVE_CLOSURES */
66 /* Allocate a frame */
67 retval
= heap_getChunk(fsize
, &pchunk
);
68 PM_RETURN_IF_ERROR(retval
);
69 pframe
= (pPmFrame_t
)pchunk
;
71 /* Set frame fields */
72 OBJ_SET_TYPE(pframe
, OBJ_TYPE_FRM
);
73 pframe
->fo_back
= C_NULL
;
74 pframe
->fo_func
= (pPmFunc_t
)pfunc
;
75 pframe
->fo_memspace
= pco
->co_memspace
;
77 /* Init instruction pointer and block stack */
78 pframe
->fo_ip
= pco
->co_codeaddr
;
79 pframe
->fo_blockstack
= C_NULL
;
81 /* Get globals and attrs from the function object */
82 pframe
->fo_globals
= ((pPmFunc_t
)pfunc
)->f_globals
;
83 pframe
->fo_attrs
= ((pPmFunc_t
)pfunc
)->f_attrs
;
86 /* Empty stack points to one past locals */
87 pframe
->fo_sp
= &(pframe
->fo_locals
[pco
->co_nlocals
]);
89 /* #256: Add support for closures */
90 pframe
->fo_sp
= &(pframe
->fo_locals
[pco
->co_nlocals
+ pco
->co_nfreevars
91 + ((pco
->co_cellvars
== C_NULL
) ? 0 : pco
->co_cellvars
->length
)]);
92 #endif /* HAVE_CLOSURES */
94 /* By default, this is a normal frame, not an import or __init__ one */
95 pframe
->fo_isImport
= 0;
97 pframe
->fo_isInit
= 0;
100 /* Clear the stack */
101 sli_memset((unsigned char *)&(pframe
->fo_locals
), (char const)0,
102 (unsigned int)fsize
- sizeof(PmFrame_t
));
104 /* Return ptr to frame */
105 *r_pobj
= (pPmObj_t
)pframe
;