mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2024-12-05 13:24:11 +01:00
183 lines
4.2 KiB
C
183 lines
4.2 KiB
C
|
/*
|
||
|
# This file is Copyright 2003, 2006, 2007, 2009, 2010 Dean Hall.
|
||
|
#
|
||
|
# This file is part of the PyMite VM.
|
||
|
# The PyMite VM is free software: you can redistribute it and/or modify
|
||
|
# it under the terms of the GNU GENERAL PUBLIC LICENSE Version 2.
|
||
|
#
|
||
|
# The PyMite VM is distributed in the hope that it will be useful,
|
||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||
|
# A copy of the GNU GENERAL PUBLIC LICENSE Version 2
|
||
|
# is seen in the file COPYING in this directory.
|
||
|
*/
|
||
|
|
||
|
|
||
|
#ifndef __FRAME_H__
|
||
|
#define __FRAME_H__
|
||
|
|
||
|
|
||
|
/**
|
||
|
* \file
|
||
|
* \brief VM Frame
|
||
|
*
|
||
|
* VM frame header.
|
||
|
*/
|
||
|
|
||
|
|
||
|
/**
|
||
|
* The maximum number of local variables a native function can have.
|
||
|
* This defines the length of the locals array in the native frame struct.
|
||
|
*/
|
||
|
#define NATIVE_MAX_NUM_LOCALS 8
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Block Type
|
||
|
*
|
||
|
* Numerical values to put in the 'b_type' field of the tPmBlockType struct.
|
||
|
*/
|
||
|
typedef enum PmBlockType_e
|
||
|
{
|
||
|
/** Invalid block type */
|
||
|
B_INVALID = 0,
|
||
|
|
||
|
/** Loop type */
|
||
|
B_LOOP,
|
||
|
|
||
|
/** Try type */
|
||
|
B_TRY
|
||
|
} PmBlockType_t, *pPmBlockType_t;
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Block
|
||
|
*
|
||
|
* Extra info for loops and trys (others?)
|
||
|
* Frames use linked list of blocks to handle
|
||
|
* nested loops and try-catch blocks.
|
||
|
*/
|
||
|
typedef struct PmBlock_s
|
||
|
{
|
||
|
/** Obligatory obj descriptor */
|
||
|
PmObjDesc_t od;
|
||
|
|
||
|
/** Ptr to backup stack ptr */
|
||
|
pPmObj_t *b_sp;
|
||
|
|
||
|
/** Handler fxn obj */
|
||
|
uint8_t const *b_handler;
|
||
|
|
||
|
/** Block type */
|
||
|
PmBlockType_t b_type:8;
|
||
|
|
||
|
/** Next block in stack */
|
||
|
struct PmBlock_s *next;
|
||
|
} PmBlock_t,
|
||
|
*pPmBlock_t;
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Frame
|
||
|
*
|
||
|
* A struct that holds the execution frame of a function, including the stack,
|
||
|
* local vars and pointer to the code object.
|
||
|
*
|
||
|
* This struct doesn't declare the stack.
|
||
|
* frame_new() is responsible for allocating the extra memory
|
||
|
* at the tail of fo_locals[] to hold both the locals and stack.
|
||
|
*/
|
||
|
typedef struct PmFrame_s
|
||
|
{
|
||
|
/** Obligatory obj descriptor */
|
||
|
PmObjDesc_t od;
|
||
|
|
||
|
/** Ptr to previous frame obj */
|
||
|
struct PmFrame_s *fo_back;
|
||
|
|
||
|
/** Ptr to fxn obj */
|
||
|
pPmFunc_t fo_func;
|
||
|
|
||
|
/** Mem space where func's CO comes from */
|
||
|
PmMemSpace_t fo_memspace:8;
|
||
|
|
||
|
/** Instrxn ptr (pts into memspace) */
|
||
|
uint8_t const *fo_ip;
|
||
|
|
||
|
/** Linked list of blocks */
|
||
|
pPmBlock_t fo_blockstack;
|
||
|
|
||
|
/** Local attributes dict (non-fast locals) */
|
||
|
pPmDict_t fo_attrs;
|
||
|
|
||
|
/** Global attributes dict (pts to root frame's globals */
|
||
|
pPmDict_t fo_globals;
|
||
|
|
||
|
/** Points to next empty slot in fo_locals (1 past TOS) */
|
||
|
pPmObj_t *fo_sp;
|
||
|
|
||
|
/** Frame can be an import-frame that handles RETURN differently */
|
||
|
uint8_t fo_isImport:1;
|
||
|
|
||
|
#ifdef HAVE_CLASSES
|
||
|
/** Flag to indicate class initailzer frame; handle RETURN differently */
|
||
|
uint8_t fo_isInit:1;
|
||
|
#endif /* HAVE_CLASSES */
|
||
|
|
||
|
/** Array of local vars and stack (space appended at alloc) */
|
||
|
pPmObj_t fo_locals[1];
|
||
|
/* WARNING: Do not put new fields below fo_locals */
|
||
|
} PmFrame_t,
|
||
|
*pPmFrame_t;
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Native Frame
|
||
|
*
|
||
|
* A struct that holds the execution frame of a native function,
|
||
|
* including the args and single stack slot, and pointer to the code object.
|
||
|
*
|
||
|
* This struct doesn't need an OD because it is only used statically in the
|
||
|
* globals struct. There's only one native frame, the global one.
|
||
|
* This happens because a native function is a leaf node
|
||
|
* in the call tree (a native func can't call python funcs).
|
||
|
*/
|
||
|
typedef struct PmNativeFrame_s
|
||
|
{
|
||
|
/** Object descriptor */
|
||
|
PmObjDesc_t od;
|
||
|
|
||
|
/** Ptr to previous frame obj */
|
||
|
struct PmFrame_s *nf_back;
|
||
|
|
||
|
/** Ptr to fxn obj */
|
||
|
pPmFunc_t nf_func;
|
||
|
|
||
|
/** Single stack slot */
|
||
|
pPmObj_t nf_stack;
|
||
|
|
||
|
/** Boolean to indicate if the native frame is active */
|
||
|
uint8_t nf_active;
|
||
|
|
||
|
/** Number of args passed to the native function */
|
||
|
uint8_t nf_numlocals;
|
||
|
|
||
|
/** Local vars */
|
||
|
pPmObj_t nf_locals[NATIVE_MAX_NUM_LOCALS];
|
||
|
} PmNativeFrame_t,
|
||
|
*pPmNativeFrame_t;
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Allocate space for a new frame, fill its fields
|
||
|
* with respect to the given function object.
|
||
|
* Return pointer to the new frame.
|
||
|
*
|
||
|
* @param pfunc ptr to Function object.
|
||
|
* @param r_pobj Return value; the new frame.
|
||
|
* @return Return status.
|
||
|
*/
|
||
|
PmReturn_t frame_new(pPmObj_t pfunc, pPmObj_t *r_pobj);
|
||
|
|
||
|
#endif /* __FRAME_H__ */
|