1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2024-12-10 18:24:11 +01:00
LibrePilot/flight/Libraries/PyMite/vm/interp.h

324 lines
8.6 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 __INTERP_H__
#define __INTERP_H__
/**
* \file
* \brief VM Interpreter
*
* VM interpreter header.
*/
#include "thread.h"
#define INTERP_LOOP_FOREVER 0
#define INTERP_RETURN_ON_NO_THREADS 1
/** Frame pointer ; currently for single thread */
#define PM_FP (gVmGlobal.pthread->pframe)
/** Instruction pointer */
#define PM_IP (PM_FP->fo_ip)
/** Argument stack pointer */
#define PM_SP (PM_FP->fo_sp)
/** top of stack */
#define TOS (*(PM_SP - 1))
/** one under TOS */
#define TOS1 (*(PM_SP - 2))
/** two under TOS */
#define TOS2 (*(PM_SP - 3))
/** three under TOS */
#define TOS3 (*(PM_SP - 4))
/** index into stack; 0 is top, 1 is next */
#define STACK(n) (*(PM_SP - ((n) + 1)))
/** pops an obj from the stack */
#define PM_POP() (*(--PM_SP))
/** pushes an obj on the stack */
#define PM_PUSH(pobj) (*(PM_SP++) = (pobj))
/** gets the argument (S16) from the instruction stream */
#define GET_ARG() mem_getWord(PM_FP->fo_memspace, &PM_IP)
/** pushes an obj in the only stack slot of the native frame */
#define NATIVE_SET_TOS(pobj) (gVmGlobal.nativeframe.nf_stack = \
(pobj))
/** gets the nth local var from the native frame locals */
#define NATIVE_GET_LOCAL(n) (gVmGlobal.nativeframe.nf_locals[n])
/** gets a pointer to the frame that called this native fxn */
#define NATIVE_GET_PFRAME() (*ppframe)
/** gets the number of args passed to the native fxn */
#define NATIVE_GET_NUM_ARGS() (gVmGlobal.nativeframe.nf_numlocals)
/**
* COMPARE_OP enum.
* Used by the COMPARE_OP bytecode to determine
* which type of compare to perform.
* Must match those defined in Python.
*/
typedef enum PmCompare_e
{
COMP_LT = 0, /**< less than */
COMP_LE, /**< less than or equal */
COMP_EQ, /**< equal */
COMP_NE, /**< not equal */
COMP_GT, /**< greater than */
COMP_GE, /**< greater than or equal */
COMP_IN, /**< is in */
COMP_NOT_IN, /**< is not in */
COMP_IS, /**< is */
COMP_IS_NOT, /**< is not */
COMP_EXN_MATCH /**< do exceptions match */
} PmCompare_t, *pPmCompare_t;
/**
* Byte code enumeration
*/
typedef enum PmBcode_e
{
/*
* Python source to create this list:
* import dis
* o = dis.opname
* for i in range(256):
* if o[i][0] != '<':
* print "\t%s," % o[i]
* else:
* print "\tUNUSED_%02X," % i
*/
STOP_CODE = 0, /* 0x00 */
POP_TOP,
ROT_TWO,
ROT_THREE,
DUP_TOP,
ROT_FOUR,
UNUSED_06,
UNUSED_07,
UNUSED_08,
NOP,
UNARY_POSITIVE, /* d010 */
UNARY_NEGATIVE,
UNARY_NOT,
UNARY_CONVERT,
UNUSED_0E,
UNARY_INVERT,
UNUSED_10, /* 0x10 */
UNUSED_11,
LIST_APPEND,
BINARY_POWER,
BINARY_MULTIPLY, /* d020 */
BINARY_DIVIDE,
BINARY_MODULO,
BINARY_ADD,
BINARY_SUBTRACT,
BINARY_SUBSCR,
BINARY_FLOOR_DIVIDE,
BINARY_TRUE_DIVIDE,
INPLACE_FLOOR_DIVIDE,
INPLACE_TRUE_DIVIDE,
SLICE_0, /* d030 */
SLICE_1,
SLICE_2, /* 0x20 */
SLICE_3,
UNUSED_22,
UNUSED_23,
UNUSED_24,
UNUSED_25,
UNUSED_26,
UNUSED_27,
STORE_SLICE_0, /* d040 */
STORE_SLICE_1,
STORE_SLICE_2,
STORE_SLICE_3,
UNUSED_2C,
UNUSED_2D,
UNUSED_2E,
UNUSED_2F,
UNUSED_30, /* 0x30 */
UNUSED_31,
DELETE_SLICE_0, /* d050 */
DELETE_SLICE_1,
DELETE_SLICE_2,
DELETE_SLICE_3,
STORE_MAP,
INPLACE_ADD,
INPLACE_SUBTRACT,
INPLACE_MULTIPLY,
INPLACE_DIVIDE,
INPLACE_MODULO,
STORE_SUBSCR, /* d060 */
DELETE_SUBSCR,
BINARY_LSHIFT,
BINARY_RSHIFT,
BINARY_AND, /* 0x40 */
BINARY_XOR,
BINARY_OR,
INPLACE_POWER,
GET_ITER,
UNUSED_45,
PRINT_EXPR, /* d070 */
PRINT_ITEM,
PRINT_NEWLINE,
PRINT_ITEM_TO,
PRINT_NEWLINE_TO,
INPLACE_LSHIFT,
INPLACE_RSHIFT,
INPLACE_AND,
INPLACE_XOR,
INPLACE_OR,
BREAK_LOOP, /* 0x50 *//* d080 */
WITH_CLEANUP,
LOAD_LOCALS,
RETURN_VALUE,
IMPORT_STAR,
EXEC_STMT,
YIELD_VALUE,
POP_BLOCK,
END_FINALLY,
BUILD_CLASS,
/* Opcodes from here have an argument */
HAVE_ARGUMENT = 90, /* d090 */
STORE_NAME = 90,
DELETE_NAME,
UNPACK_SEQUENCE,
FOR_ITER,
UNUSED_5E,
STORE_ATTR,
DELETE_ATTR, /* 0x60 */
STORE_GLOBAL,
DELETE_GLOBAL,
DUP_TOPX,
LOAD_CONST, /* d100 */
LOAD_NAME,
BUILD_TUPLE,
BUILD_LIST,
BUILD_MAP,
LOAD_ATTR,
COMPARE_OP,
IMPORT_NAME,
IMPORT_FROM,
UNUSED_6D,
JUMP_FORWARD, /* d110 */
JUMP_IF_FALSE,
JUMP_IF_TRUE, /* 0x70 */
JUMP_ABSOLUTE,
UNUSED_72,
UNUSED_73,
LOAD_GLOBAL,
UNUSED_75,
UNUSED_76,
CONTINUE_LOOP,
SETUP_LOOP, /* d120 */
SETUP_EXCEPT,
SETUP_FINALLY,
UNUSED_7B,
LOAD_FAST,
STORE_FAST,
DELETE_FAST,
UNUSED_79,
UNUSED_80, /* 0x80 */
UNUSED_81,
RAISE_VARARGS, /* d130 */
CALL_FUNCTION,
MAKE_FUNCTION,
BUILD_SLICE,
MAKE_CLOSURE,
LOAD_CLOSURE,
LOAD_DEREF,
STORE_DEREF,
UNUSED_8A,
UNUSED_8B,
CALL_FUNCTION_VAR, /* d140 */
CALL_FUNCTION_KW,
CALL_FUNCTION_VAR_KW,
EXTENDED_ARG,
UNUSED_90, UNUSED_91, UNUSED_92, UNUSED_93,
UNUSED_94, UNUSED_95, UNUSED_96, UNUSED_97,
UNUSED_98, UNUSED_99, UNUSED_9A, UNUSED_9B,
UNUSED_9C, UNUSED_9D, UNUSED_9E, UNUSED_9F,
UNUSED_A0, UNUSED_A1, UNUSED_A2, UNUSED_A3,
UNUSED_A4, UNUSED_A5, UNUSED_A6, UNUSED_A7,
UNUSED_A8, UNUSED_A9, UNUSED_AA, UNUSED_AB,
UNUSED_AC, UNUSED_AD, UNUSED_AE, UNUSED_AF,
UNUSED_B0, UNUSED_B1, UNUSED_B2, UNUSED_B3,
UNUSED_B4, UNUSED_B5, UNUSED_B6, UNUSED_B7,
UNUSED_B8, UNUSED_B9, UNUSED_BA, UNUSED_BB,
UNUSED_BC, UNUSED_BD, UNUSED_BE, UNUSED_BF,
UNUSED_C0, UNUSED_C1, UNUSED_C2, UNUSED_C3,
UNUSED_C4, UNUSED_C5, UNUSED_C6, UNUSED_C7,
UNUSED_C8, UNUSED_C9, UNUSED_CA, UNUSED_CB,
UNUSED_CC, UNUSED_CD, UNUSED_CE, UNUSED_CF,
UNUSED_D0, UNUSED_D1, UNUSED_D2, UNUSED_D3,
UNUSED_D4, UNUSED_D5, UNUSED_D6, UNUSED_D7,
UNUSED_D8, UNUSED_D9, UNUSED_DA, UNUSED_DB,
UNUSED_DC, UNUSED_DD, UNUSED_DE, UNUSED_DF,
UNUSED_E0, UNUSED_E1, UNUSED_E2, UNUSED_E3,
UNUSED_E4, UNUSED_E5, UNUSED_E6, UNUSED_E7,
UNUSED_E8, UNUSED_E9, UNUSED_EA, UNUSED_EB,
UNUSED_EC, UNUSED_ED, UNUSED_EE, UNUSED_EF,
UNUSED_F0, UNUSED_F1, UNUSED_F2, UNUSED_F3,
UNUSED_F4, UNUSED_F5, UNUSED_F6, UNUSED_F7,
UNUSED_F8, UNUSED_F9, UNUSED_FA, UNUSED_FB,
UNUSED_FC, UNUSED_FD, UNUSED_FE, UNUSED_FF
} PmBcode_t, *pPmBcode_t;
/**
* Interprets the available threads. Does not return.
*
* @param returnOnNoThreads Loop forever if 0, exit with status if no more
* threads left.
* @return Return status if called with returnOnNoThreads != 0,
* will not return otherwise.
*/
PmReturn_t interpret(const uint8_t returnOnNoThreads);
/**
* Selects a thread to run and changes the VM internal variables to
* let the switch-loop execute the chosen one in the next iteration.
* For the moment the algorithm is primitive and will change the
* thread each time it is called in a round-robin fashion.
*/
PmReturn_t interp_reschedule(void);
/**
* Creates a thread object and adds it to the queue of threads to be
* executed while interpret() is running.
*
* The given obj may be a function, module, or class.
* Creates a frame for the given function.
*
* @param pfunc Ptr to function to be executed as a thread.
* @return Return status
*/
PmReturn_t interp_addThread(pPmFunc_t pfunc);
/**
* Sets the reschedule flag.
*
* @param boolean Reschedule on next occasion if boolean is true; clear
* the flag otherwise.
*/
void interp_setRescheduleFlag(uint8_t boolean);
#endif /* __INTERP_H__ */