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.
22 * \brief VM Interpreter
24 * VM interpreter header.
31 #define INTERP_LOOP_FOREVER 0
32 #define INTERP_RETURN_ON_NO_THREADS 1
35 /** Frame pointer ; currently for single thread */
36 #define PM_FP (gVmGlobal.pthread->pframe)
37 /** Instruction pointer */
38 #define PM_IP (PM_FP->fo_ip)
39 /** Argument stack pointer */
40 #define PM_SP (PM_FP->fo_sp)
43 #define TOS (*(PM_SP - 1))
45 #define TOS1 (*(PM_SP - 2))
47 #define TOS2 (*(PM_SP - 3))
48 /** three under TOS */
49 #define TOS3 (*(PM_SP - 4))
50 /** index into stack; 0 is top, 1 is next */
51 #define STACK(n) (*(PM_SP - ((n) + 1)))
52 /** pops an obj from the stack */
53 #define PM_POP() (*(--PM_SP))
54 /** pushes an obj on the stack */
55 #define PM_PUSH(pobj) (*(PM_SP++) = (pobj))
56 /** gets the argument (S16) from the instruction stream */
57 #define GET_ARG() mem_getWord(PM_FP->fo_memspace, &PM_IP)
59 /** pushes an obj in the only stack slot of the native frame */
60 #define NATIVE_SET_TOS(pobj) (gVmGlobal.nativeframe.nf_stack = \
62 /** gets the nth local var from the native frame locals */
63 #define NATIVE_GET_LOCAL(n) (gVmGlobal.nativeframe.nf_locals[n])
64 /** gets a pointer to the frame that called this native fxn */
65 #define NATIVE_GET_PFRAME() (*ppframe)
66 /** gets the number of args passed to the native fxn */
67 #define NATIVE_GET_NUM_ARGS() (gVmGlobal.nativeframe.nf_numlocals)
72 * Used by the COMPARE_OP bytecode to determine
73 * which type of compare to perform.
74 * Must match those defined in Python.
76 typedef enum PmCompare_e
78 COMP_LT
= 0, /**< less than */
79 COMP_LE
, /**< less than or equal */
80 COMP_EQ
, /**< equal */
81 COMP_NE
, /**< not equal */
82 COMP_GT
, /**< greater than */
83 COMP_GE
, /**< greater than or equal */
84 COMP_IN
, /**< is in */
85 COMP_NOT_IN
, /**< is not in */
87 COMP_IS_NOT
, /**< is not */
88 COMP_EXN_MATCH
/**< do exceptions match */
89 } PmCompare_t
, *pPmCompare_t
;
92 * Byte code enumeration
94 typedef enum PmBcode_e
97 * Python source to create this list:
100 * for i in range(256):
102 * print "\t%s," % o[i]
104 * print "\tUNUSED_%02X," % i
106 STOP_CODE
= 0, /* 0x00 */
116 UNARY_POSITIVE
, /* d010 */
122 UNUSED_10
, /* 0x10 */
126 BINARY_MULTIPLY
, /* d020 */
134 INPLACE_FLOOR_DIVIDE
,
146 STORE_SLICE_0
, /* d040 */
154 UNUSED_30
, /* 0x30 */
156 DELETE_SLICE_0
, /* d050 */
166 STORE_SUBSCR
, /* d060 */
170 BINARY_AND
, /* 0x40 */
176 PRINT_EXPR
, /* d070 */
186 BREAK_LOOP
, /* 0x50 *//* d080 */
197 /* Opcodes from here have an argument */
198 HAVE_ARGUMENT
= 90, /* d090 */
205 DELETE_ATTR
, /* 0x60 */
209 LOAD_CONST
, /* d100 */
219 JUMP_FORWARD
, /* d110 */
221 JUMP_IF_TRUE
, /* 0x70 */
229 SETUP_LOOP
, /* d120 */
237 UNUSED_80
, /* 0x80 */
239 RAISE_VARARGS
, /* d130 */
249 CALL_FUNCTION_VAR
, /* d140 */
251 CALL_FUNCTION_VAR_KW
,
254 UNUSED_90
, UNUSED_91
, UNUSED_92
, UNUSED_93
,
255 UNUSED_94
, UNUSED_95
, UNUSED_96
, UNUSED_97
,
256 UNUSED_98
, UNUSED_99
, UNUSED_9A
, UNUSED_9B
,
257 UNUSED_9C
, UNUSED_9D
, UNUSED_9E
, UNUSED_9F
,
258 UNUSED_A0
, UNUSED_A1
, UNUSED_A2
, UNUSED_A3
,
259 UNUSED_A4
, UNUSED_A5
, UNUSED_A6
, UNUSED_A7
,
260 UNUSED_A8
, UNUSED_A9
, UNUSED_AA
, UNUSED_AB
,
261 UNUSED_AC
, UNUSED_AD
, UNUSED_AE
, UNUSED_AF
,
262 UNUSED_B0
, UNUSED_B1
, UNUSED_B2
, UNUSED_B3
,
263 UNUSED_B4
, UNUSED_B5
, UNUSED_B6
, UNUSED_B7
,
264 UNUSED_B8
, UNUSED_B9
, UNUSED_BA
, UNUSED_BB
,
265 UNUSED_BC
, UNUSED_BD
, UNUSED_BE
, UNUSED_BF
,
266 UNUSED_C0
, UNUSED_C1
, UNUSED_C2
, UNUSED_C3
,
267 UNUSED_C4
, UNUSED_C5
, UNUSED_C6
, UNUSED_C7
,
268 UNUSED_C8
, UNUSED_C9
, UNUSED_CA
, UNUSED_CB
,
269 UNUSED_CC
, UNUSED_CD
, UNUSED_CE
, UNUSED_CF
,
270 UNUSED_D0
, UNUSED_D1
, UNUSED_D2
, UNUSED_D3
,
271 UNUSED_D4
, UNUSED_D5
, UNUSED_D6
, UNUSED_D7
,
272 UNUSED_D8
, UNUSED_D9
, UNUSED_DA
, UNUSED_DB
,
273 UNUSED_DC
, UNUSED_DD
, UNUSED_DE
, UNUSED_DF
,
274 UNUSED_E0
, UNUSED_E1
, UNUSED_E2
, UNUSED_E3
,
275 UNUSED_E4
, UNUSED_E5
, UNUSED_E6
, UNUSED_E7
,
276 UNUSED_E8
, UNUSED_E9
, UNUSED_EA
, UNUSED_EB
,
277 UNUSED_EC
, UNUSED_ED
, UNUSED_EE
, UNUSED_EF
,
278 UNUSED_F0
, UNUSED_F1
, UNUSED_F2
, UNUSED_F3
,
279 UNUSED_F4
, UNUSED_F5
, UNUSED_F6
, UNUSED_F7
,
280 UNUSED_F8
, UNUSED_F9
, UNUSED_FA
, UNUSED_FB
,
281 UNUSED_FC
, UNUSED_FD
, UNUSED_FE
, UNUSED_FF
282 } PmBcode_t
, *pPmBcode_t
;
286 * Interprets the available threads. Does not return.
288 * @param returnOnNoThreads Loop forever if 0, exit with status if no more
290 * @return Return status if called with returnOnNoThreads != 0,
291 * will not return otherwise.
293 PmReturn_t
interpret(const uint8_t returnOnNoThreads
);
296 * Selects a thread to run and changes the VM internal variables to
297 * let the switch-loop execute the chosen one in the next iteration.
298 * For the moment the algorithm is primitive and will change the
299 * thread each time it is called in a round-robin fashion.
301 PmReturn_t
interp_reschedule(void);
304 * Creates a thread object and adds it to the queue of threads to be
305 * executed while interpret() is running.
307 * The given obj may be a function, module, or class.
308 * Creates a frame for the given function.
310 * @param pfunc Ptr to function to be executed as a thread.
311 * @return Return status
313 PmReturn_t
interp_addThread(pPmFunc_t pfunc
);
316 * Sets the reschedule flag.
318 * @param boolean Reschedule on next occasion if boolean is true; clear
319 * the flag otherwise.
321 void interp_setRescheduleFlag(uint8_t boolean
);
323 #endif /* __INTERP_H__ */