python-on-a-chip online compiler

Dependencies:   mbed TSI

/media/uploads/va009039/p14p-f446re.png

more info: python-on-a-chip

vm/interp.h

Committer:
va009039
Date:
2016-04-14
Revision:
15:94ca5c8003e5
Parent:
1:28afb064a41c

File content as of revision 15:94ca5c8003e5:

/*
# This file is Copyright 2002 Dean Hall.
# This file is part of the PyMite VM.
# This file is licensed under the MIT License.
# See the LICENSE file for details.
*/


#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
{
#ifdef HAVE_PYTHON27
    STOP_CODE=0, /* 0x00 */
    POP_TOP=1, /* 0x01 */
    ROT_TWO=2, /* 0x02 */
    ROT_THREE=3, /* 0x03 */
    DUP_TOP=4, /* 0x04 */
    ROT_FOUR=5, /* 0x05 */
    UNUSED_06=6,
    UNUSED_07=7,
    UNUSED_08=8,
    NOP=9, /* 0x09 */
    UNARY_POSITIVE=10, /* 0x0a */
    UNARY_NEGATIVE=11, /* 0x0b */
    UNARY_NOT=12, /* 0x0c */
    UNARY_CONVERT=13, /* 0x0d */
    UNUSED_0E=14,
    UNARY_INVERT=15, /* 0x0f */
    UNUSED_10=16,
    UNUSED_11=17,
    UNUSED_12=18,
    BINARY_POWER=19, /* 0x13 */
    BINARY_MULTIPLY=20, /* 0x14 */
    BINARY_DIVIDE=21, /* 0x15 */
    BINARY_MODULO=22, /* 0x16 */
    BINARY_ADD=23, /* 0x17 */
    BINARY_SUBTRACT=24, /* 0x18 */
    BINARY_SUBSCR=25, /* 0x19 */
    BINARY_FLOOR_DIVIDE=26, /* 0x1a */
    BINARY_TRUE_DIVIDE=27, /* 0x1b */
    INPLACE_FLOOR_DIVIDE=28, /* 0x1c */
    INPLACE_TRUE_DIVIDE=29, /* 0x1d */
    SLICE_0=30, /* 0x1e */
    SLICE_1=31, /* 0x1f */
    SLICE_2=32, /* 0x20 */
    SLICE_3=33, /* 0x21 */
    UNUSED_22=34,
    UNUSED_23=35,
    UNUSED_24=36,
    UNUSED_25=37,
    UNUSED_26=38,
    UNUSED_27=39,
    STORE_SLICE_0=40, /* 0x28 */
    STORE_SLICE_1=41, /* 0x29 */
    STORE_SLICE_2=42, /* 0x2a */
    STORE_SLICE_3=43, /* 0x2b */
    UNUSED_2C=44,
    UNUSED_2D=45,
    UNUSED_2E=46,
    UNUSED_2F=47,
    UNUSED_30=48,
    UNUSED_31=49,
    DELETE_SLICE_0=50, /* 0x32 */
    DELETE_SLICE_1=51, /* 0x33 */
    DELETE_SLICE_2=52, /* 0x34 */
    DELETE_SLICE_3=53, /* 0x35 */
    STORE_MAP=54, /* 0x36 */
    INPLACE_ADD=55, /* 0x37 */
    INPLACE_SUBTRACT=56, /* 0x38 */
    INPLACE_MULTIPLY=57, /* 0x39 */
    INPLACE_DIVIDE=58, /* 0x3a */
    INPLACE_MODULO=59, /* 0x3b */
    STORE_SUBSCR=60, /* 0x3c */
    DELETE_SUBSCR=61, /* 0x3d */
    BINARY_LSHIFT=62, /* 0x3e */
    BINARY_RSHIFT=63, /* 0x3f */
    BINARY_AND=64, /* 0x40 */
    BINARY_XOR=65, /* 0x41 */
    BINARY_OR=66, /* 0x42 */
    INPLACE_POWER=67, /* 0x43 */
    GET_ITER=68, /* 0x44 */
    UNUSED_45=69,
    PRINT_EXPR=70, /* 0x46 */
    PRINT_ITEM=71, /* 0x47 */
    PRINT_NEWLINE=72, /* 0x48 */
    PRINT_ITEM_TO=73, /* 0x49 */
    PRINT_NEWLINE_TO=74, /* 0x4a */
    INPLACE_LSHIFT=75, /* 0x4b */
    INPLACE_RSHIFT=76, /* 0x4c */
    INPLACE_AND=77, /* 0x4d */
    INPLACE_XOR=78, /* 0x4e */
    INPLACE_OR=79, /* 0x4f */
    BREAK_LOOP=80, /* 0x50 */
    WITH_CLEANUP=81, /* 0x51 */
    LOAD_LOCALS=82, /* 0x52 */
    RETURN_VALUE=83, /* 0x53 */
    IMPORT_STAR=84, /* 0x54 */
    EXEC_STMT=85, /* 0x55 */
    YIELD_VALUE=86, /* 0x56 */
    POP_BLOCK=87, /* 0x57 */
    END_FINALLY=88, /* 0x58 */
    BUILD_CLASS=89, /* 0x59 */
    
    /* Opcodes from here have an argument */
    HAVE_ARGUMENT=90, /* 0x5a */
    STORE_NAME=90, /* 0x5a */
    DELETE_NAME=91, /* 0x5b */
    UNPACK_SEQUENCE=92, /* 0x5c */
    FOR_ITER=93, /* 0x5d */
    LIST_APPEND=94, /* 0x5e */
    STORE_ATTR=95, /* 0x5f */
    DELETE_ATTR=96, /* 0x60 */
    STORE_GLOBAL=97, /* 0x61 */
    DELETE_GLOBAL=98, /* 0x62 */
    DUP_TOPX=99, /* 0x63 */
    LOAD_CONST=100, /* 0x64 */
    LOAD_NAME=101, /* 0x65 */
    BUILD_TUPLE=102, /* 0x66 */
    BUILD_LIST=103, /* 0x67 */
    BUILD_SET=104, /* 0x68 */
    BUILD_MAP=105, /* 0x69 */
    LOAD_ATTR=106, /* 0x6a */
    COMPARE_OP=107, /* 0x6b */
    IMPORT_NAME=108, /* 0x6c */
    IMPORT_FROM=109, /* 0x6d */
    JUMP_FORWARD=110, /* 0x6e */
    JUMP_IF_FALSE_OR_POP=111, /* 0x6f */
    JUMP_IF_TRUE_OR_POP=112, /* 0x70 */
    JUMP_ABSOLUTE=113, /* 0x71 */
    POP_JUMP_IF_FALSE=114, /* 0x72 */
    POP_JUMP_IF_TRUE=115, /* 0x73 */
    LOAD_GLOBAL=116, /* 0x74 */
    UNUSED_75=117,
    UNUSED_76=118,
    CONTINUE_LOOP=119, /* 0x77 */
    SETUP_LOOP=120, /* 0x78 */
    SETUP_EXCEPT=121, /* 0x79 */
    SETUP_FINALLY=122, /* 0x7a */
    UNUSED_7B=123,
    LOAD_FAST=124, /* 0x7c */
    STORE_FAST=125, /* 0x7d */
    DELETE_FAST=126, /* 0x7e */
    UNUSED_7F=127,
    UNUSED_80=128,
    UNUSED_81=129,
    RAISE_VARARGS=130, /* 0x82 */
    CALL_FUNCTION=131, /* 0x83 */
    MAKE_FUNCTION=132, /* 0x84 */
    BUILD_SLICE=133, /* 0x85 */
    MAKE_CLOSURE=134, /* 0x86 */
    LOAD_CLOSURE=135, /* 0x87 */
    LOAD_DEREF=136, /* 0x88 */
    STORE_DEREF=137, /* 0x89 */
    UNUSED_8A=138,
    UNUSED_8B=139,
    CALL_FUNCTION_VAR=140, /* 0x8c */
    CALL_FUNCTION_KW=141, /* 0x8d */
    CALL_FUNCTION_VAR_KW=142, /* 0x8e */
    SETUP_WITH=143, /* 0x8f */
    UNUSED_90=144,
    EXTENDED_ARG=145, /* 0x91 */
    SET_ADD=146, /* 0x92 */
    MAP_ADD=147, /* 0x93 */
    UNUSED_94=148,
    UNUSED_95=149,
    UNUSED_96=150,
    UNUSED_97=151,
    UNUSED_98=152,
    UNUSED_99=153,
    UNUSED_9A=154,
    UNUSED_9B=155,
    UNUSED_9C=156,
    UNUSED_9D=157,
    UNUSED_9E=158,
    UNUSED_9F=159,
    UNUSED_A0=160,
    UNUSED_A1=161,
    UNUSED_A2=162,
    UNUSED_A3=163,
    UNUSED_A4=164,
    UNUSED_A5=165,
    UNUSED_A6=166,
    UNUSED_A7=167,
    UNUSED_A8=168,
    UNUSED_A9=169,
    UNUSED_AA=170,
    UNUSED_AB=171,
    UNUSED_AC=172,
    UNUSED_AD=173,
    UNUSED_AE=174,
    UNUSED_AF=175,
    UNUSED_B0=176,
    UNUSED_B1=177,
    UNUSED_B2=178,
    UNUSED_B3=179,
    UNUSED_B4=180,
    UNUSED_B5=181,
    UNUSED_B6=182,
    UNUSED_B7=183,
    UNUSED_B8=184,
    UNUSED_B9=185,
    UNUSED_BA=186,
    UNUSED_BB=187,
    UNUSED_BC=188,
    UNUSED_BD=189,
    UNUSED_BE=190,
    UNUSED_BF=191,
    UNUSED_C0=192,
    UNUSED_C1=193,
    UNUSED_C2=194,
    UNUSED_C3=195,
    UNUSED_C4=196,
    UNUSED_C5=197,
    UNUSED_C6=198,
    UNUSED_C7=199,
    UNUSED_C8=200,
    UNUSED_C9=201,
    UNUSED_CA=202,
    UNUSED_CB=203,
    UNUSED_CC=204,
    UNUSED_CD=205,
    UNUSED_CE=206,
    UNUSED_CF=207,
    UNUSED_D0=208,
    UNUSED_D1=209,
    UNUSED_D2=210,
    UNUSED_D3=211,
    UNUSED_D4=212,
    UNUSED_D5=213,
    UNUSED_D6=214,
    UNUSED_D7=215,
    UNUSED_D8=216,
    UNUSED_D9=217,
    UNUSED_DA=218,
    UNUSED_DB=219,
    UNUSED_DC=220,
    UNUSED_DD=221,
    UNUSED_DE=222,
    UNUSED_DF=223,
    UNUSED_E0=224,
    UNUSED_E1=225,
    UNUSED_E2=226,
    UNUSED_E3=227,
    UNUSED_E4=228,
    UNUSED_E5=229,
    UNUSED_E6=230,
    UNUSED_E7=231,
    UNUSED_E8=232,
    UNUSED_E9=233,
    UNUSED_EA=234,
    UNUSED_EB=235,
    UNUSED_EC=236,
    UNUSED_ED=237,
    UNUSED_EE=238,
    UNUSED_EF=239,
    UNUSED_F0=240,
    UNUSED_F1=241,
    UNUSED_F2=242,
    UNUSED_F3=243,
    UNUSED_F4=244,
    UNUSED_F5=245,
    UNUSED_F6=246,
    UNUSED_F7=247,
    UNUSED_F8=248,
    UNUSED_F9=249,
    UNUSED_FA=250,
    UNUSED_FB=251,
    UNUSED_FC=252,
    UNUSED_FD=253,
    UNUSED_FE=254,
    UNUSED_FF=255,
#else /* HAVE_PYTHON27 */
    /*
     * 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
#endif /* HAVE_PYTHON27 */
} 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__ */