python-on-a-chip online compiler

Dependencies:   mbed TSI

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

more info: python-on-a-chip

Committer:
va009039
Date:
Thu Apr 14 22:32:57 2016 +0000
Revision:
15:94ca5c8003e5
Parent:
1:28afb064a41c
update Nucleo-F401RE.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
va009039 0:65f1469d6bfb 1 /*
va009039 0:65f1469d6bfb 2 # This file is Copyright 2002 Dean Hall.
va009039 0:65f1469d6bfb 3 # This file is part of the PyMite VM.
va009039 0:65f1469d6bfb 4 # This file is licensed under the MIT License.
va009039 0:65f1469d6bfb 5 # See the LICENSE file for details.
va009039 0:65f1469d6bfb 6 */
va009039 0:65f1469d6bfb 7
va009039 0:65f1469d6bfb 8
va009039 0:65f1469d6bfb 9 #undef __FILE_ID__
va009039 0:65f1469d6bfb 10 #define __FILE_ID__ 0x09
va009039 0:65f1469d6bfb 11
va009039 0:65f1469d6bfb 12
va009039 0:65f1469d6bfb 13 /**
va009039 0:65f1469d6bfb 14 * \file
va009039 0:65f1469d6bfb 15 * \brief VM Interpreter
va009039 0:65f1469d6bfb 16 *
va009039 0:65f1469d6bfb 17 * VM interpreter operations.
va009039 0:65f1469d6bfb 18 */
va009039 0:65f1469d6bfb 19
va009039 0:65f1469d6bfb 20
va009039 0:65f1469d6bfb 21 #include "pm.h"
va009039 0:65f1469d6bfb 22
va009039 0:65f1469d6bfb 23
va009039 0:65f1469d6bfb 24 PmReturn_t
va009039 0:65f1469d6bfb 25 interpret(const uint8_t returnOnNoThreads)
va009039 0:65f1469d6bfb 26 {
va009039 0:65f1469d6bfb 27 PmReturn_t retval = PM_RET_OK;
va009039 0:65f1469d6bfb 28 pPmObj_t pobj1 = C_NULL;
va009039 0:65f1469d6bfb 29 pPmObj_t pobj2 = C_NULL;
va009039 0:65f1469d6bfb 30 pPmObj_t pobj3 = C_NULL;
va009039 0:65f1469d6bfb 31 int16_t t16 = 0;
va009039 0:65f1469d6bfb 32 int8_t t8 = 0;
va009039 0:65f1469d6bfb 33 uint8_t bc;
va009039 0:65f1469d6bfb 34 uint8_t objid, objid2;
va009039 0:65f1469d6bfb 35
va009039 0:65f1469d6bfb 36 /* Activate a thread the first time */
va009039 0:65f1469d6bfb 37 retval = interp_reschedule();
va009039 0:65f1469d6bfb 38 PM_RETURN_IF_ERROR(retval);
va009039 0:65f1469d6bfb 39
va009039 0:65f1469d6bfb 40 /* Interpret loop */
va009039 0:65f1469d6bfb 41 for (;;)
va009039 0:65f1469d6bfb 42 {
va009039 0:65f1469d6bfb 43 if (gVmGlobal.pthread == C_NULL)
va009039 0:65f1469d6bfb 44 {
va009039 0:65f1469d6bfb 45 if (returnOnNoThreads)
va009039 0:65f1469d6bfb 46 {
va009039 0:65f1469d6bfb 47 /* User chose to return on no threads left */
va009039 0:65f1469d6bfb 48 return retval;
va009039 0:65f1469d6bfb 49 }
va009039 0:65f1469d6bfb 50
va009039 0:65f1469d6bfb 51 /*
va009039 0:65f1469d6bfb 52 * Without a frame there is nothing to execute, so reschedule
va009039 0:65f1469d6bfb 53 * (possibly activating a recently added thread).
va009039 0:65f1469d6bfb 54 */
va009039 0:65f1469d6bfb 55 retval = interp_reschedule();
va009039 0:65f1469d6bfb 56 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 57 continue;
va009039 0:65f1469d6bfb 58 }
va009039 0:65f1469d6bfb 59
va009039 0:65f1469d6bfb 60 /* Reschedule threads if flag is true? */
va009039 0:65f1469d6bfb 61 if (gVmGlobal.reschedule)
va009039 0:65f1469d6bfb 62 {
va009039 0:65f1469d6bfb 63 retval = interp_reschedule();
va009039 0:65f1469d6bfb 64 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 65 }
va009039 0:65f1469d6bfb 66
va009039 0:65f1469d6bfb 67 /* Get byte; the func post-incrs PM_IP */
va009039 0:65f1469d6bfb 68 bc = mem_getByte(PM_FP->fo_memspace, &PM_IP);
va009039 0:65f1469d6bfb 69 switch (bc)
va009039 0:65f1469d6bfb 70 {
va009039 0:65f1469d6bfb 71 case POP_TOP:
va009039 0:65f1469d6bfb 72 pobj1 = PM_POP();
va009039 0:65f1469d6bfb 73 continue;
va009039 0:65f1469d6bfb 74
va009039 0:65f1469d6bfb 75 case ROT_TWO:
va009039 0:65f1469d6bfb 76 pobj1 = TOS;
va009039 0:65f1469d6bfb 77 TOS = TOS1;
va009039 0:65f1469d6bfb 78 TOS1 = pobj1;
va009039 0:65f1469d6bfb 79 continue;
va009039 0:65f1469d6bfb 80
va009039 0:65f1469d6bfb 81 case ROT_THREE:
va009039 0:65f1469d6bfb 82 pobj1 = TOS;
va009039 0:65f1469d6bfb 83 TOS = TOS1;
va009039 0:65f1469d6bfb 84 TOS1 = TOS2;
va009039 0:65f1469d6bfb 85 TOS2 = pobj1;
va009039 0:65f1469d6bfb 86 continue;
va009039 0:65f1469d6bfb 87
va009039 0:65f1469d6bfb 88 case DUP_TOP:
va009039 0:65f1469d6bfb 89 pobj1 = TOS;
va009039 0:65f1469d6bfb 90 PM_PUSH(pobj1);
va009039 0:65f1469d6bfb 91 continue;
va009039 0:65f1469d6bfb 92
va009039 0:65f1469d6bfb 93 case ROT_FOUR:
va009039 0:65f1469d6bfb 94 pobj1 = TOS;
va009039 0:65f1469d6bfb 95 TOS = TOS1;
va009039 0:65f1469d6bfb 96 TOS1 = TOS2;
va009039 0:65f1469d6bfb 97 TOS2 = TOS3;
va009039 0:65f1469d6bfb 98 TOS3 = pobj1;
va009039 0:65f1469d6bfb 99 continue;
va009039 0:65f1469d6bfb 100
va009039 0:65f1469d6bfb 101 case NOP:
va009039 0:65f1469d6bfb 102 continue;
va009039 0:65f1469d6bfb 103
va009039 0:65f1469d6bfb 104 case UNARY_POSITIVE:
va009039 0:65f1469d6bfb 105 /* Raise TypeError if TOS is not an int */
va009039 0:65f1469d6bfb 106 if ((OBJ_GET_TYPE(TOS) != OBJ_TYPE_INT)
va009039 0:65f1469d6bfb 107 #ifdef HAVE_FLOAT
va009039 0:65f1469d6bfb 108 && (OBJ_GET_TYPE(TOS) != OBJ_TYPE_FLT)
va009039 0:65f1469d6bfb 109 #endif /* HAVE_FLOAT */
va009039 0:65f1469d6bfb 110 )
va009039 0:65f1469d6bfb 111 {
va009039 0:65f1469d6bfb 112 PM_RAISE(retval, PM_RET_EX_TYPE);
va009039 0:65f1469d6bfb 113 break;
va009039 0:65f1469d6bfb 114 }
va009039 0:65f1469d6bfb 115
va009039 0:65f1469d6bfb 116 /* When TOS is an int, this is a no-op */
va009039 0:65f1469d6bfb 117 continue;
va009039 0:65f1469d6bfb 118
va009039 0:65f1469d6bfb 119 case UNARY_NEGATIVE:
va009039 0:65f1469d6bfb 120 #ifdef HAVE_FLOAT
va009039 0:65f1469d6bfb 121 if (OBJ_GET_TYPE(TOS) == OBJ_TYPE_FLT)
va009039 0:65f1469d6bfb 122 {
va009039 0:65f1469d6bfb 123 retval = float_negative(TOS, &pobj2);
va009039 0:65f1469d6bfb 124 }
va009039 0:65f1469d6bfb 125 else
va009039 0:65f1469d6bfb 126 #endif /* HAVE_FLOAT */
va009039 0:65f1469d6bfb 127 {
va009039 0:65f1469d6bfb 128 retval = int_negative(TOS, &pobj2);
va009039 0:65f1469d6bfb 129 }
va009039 0:65f1469d6bfb 130 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 131 TOS = pobj2;
va009039 0:65f1469d6bfb 132 continue;
va009039 0:65f1469d6bfb 133
va009039 0:65f1469d6bfb 134 case UNARY_NOT:
va009039 0:65f1469d6bfb 135 pobj1 = PM_POP();
va009039 0:65f1469d6bfb 136 if (obj_isFalse(pobj1))
va009039 0:65f1469d6bfb 137 {
va009039 0:65f1469d6bfb 138 PM_PUSH(PM_TRUE);
va009039 0:65f1469d6bfb 139 }
va009039 0:65f1469d6bfb 140 else
va009039 0:65f1469d6bfb 141 {
va009039 0:65f1469d6bfb 142 PM_PUSH(PM_FALSE);
va009039 0:65f1469d6bfb 143 }
va009039 0:65f1469d6bfb 144 continue;
va009039 0:65f1469d6bfb 145
va009039 0:65f1469d6bfb 146 #ifdef HAVE_BACKTICK
va009039 0:65f1469d6bfb 147 /* #244 Add support for the backtick operation (UNARY_CONVERT) */
va009039 0:65f1469d6bfb 148 case UNARY_CONVERT:
va009039 0:65f1469d6bfb 149 retval = obj_repr(TOS, &pobj3);
va009039 0:65f1469d6bfb 150 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 151 TOS = pobj3;
va009039 0:65f1469d6bfb 152 continue;
va009039 0:65f1469d6bfb 153 #endif /* HAVE_BACKTICK */
va009039 0:65f1469d6bfb 154
va009039 0:65f1469d6bfb 155 case UNARY_INVERT:
va009039 0:65f1469d6bfb 156 /* Raise TypeError if it's not an int */
va009039 0:65f1469d6bfb 157 if (OBJ_GET_TYPE(TOS) != OBJ_TYPE_INT)
va009039 0:65f1469d6bfb 158 {
va009039 0:65f1469d6bfb 159 PM_RAISE(retval, PM_RET_EX_TYPE);
va009039 0:65f1469d6bfb 160 break;
va009039 0:65f1469d6bfb 161 }
va009039 0:65f1469d6bfb 162
va009039 0:65f1469d6bfb 163 /* Otherwise perform bit-wise complement */
va009039 0:65f1469d6bfb 164 retval = int_bitInvert(TOS, &pobj2);
va009039 0:65f1469d6bfb 165 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 166 TOS = pobj2;
va009039 0:65f1469d6bfb 167 continue;
va009039 0:65f1469d6bfb 168
va009039 1:28afb064a41c 169 #ifdef HAVE_PYTHON27
va009039 1:28afb064a41c 170 case LIST_APPEND:
va009039 1:28afb064a41c 171 t16 = GET_ARG();
va009039 1:28afb064a41c 172 C_ASSERT(t16 >= 2);
va009039 1:28afb064a41c 173 retval = list_append((*(PM_SP - t16)), TOS);
va009039 1:28afb064a41c 174 PM_SP--;
va009039 1:28afb064a41c 175 continue;
va009039 1:28afb064a41c 176
va009039 1:28afb064a41c 177 #else /* HAVE_PYTHON27 */
va009039 0:65f1469d6bfb 178 case LIST_APPEND:
va009039 0:65f1469d6bfb 179 /* list_append will raise a TypeError if TOS1 is not a list */
va009039 0:65f1469d6bfb 180 retval = list_append(TOS1, TOS);
va009039 0:65f1469d6bfb 181 PM_SP -= 2;
va009039 0:65f1469d6bfb 182 continue;
va009039 1:28afb064a41c 183 #endif /* HAVE_PYTHON27 */
va009039 0:65f1469d6bfb 184
va009039 0:65f1469d6bfb 185 case BINARY_POWER:
va009039 0:65f1469d6bfb 186 case INPLACE_POWER:
va009039 0:65f1469d6bfb 187
va009039 0:65f1469d6bfb 188 #ifdef HAVE_FLOAT
va009039 0:65f1469d6bfb 189 if ((OBJ_GET_TYPE(TOS) == OBJ_TYPE_FLT)
va009039 0:65f1469d6bfb 190 || (OBJ_GET_TYPE(TOS1) == OBJ_TYPE_FLT))
va009039 0:65f1469d6bfb 191 {
va009039 0:65f1469d6bfb 192 /* Calculate float power */
va009039 0:65f1469d6bfb 193 retval = float_op(TOS1, TOS, &pobj3, 'P');
va009039 0:65f1469d6bfb 194 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 195 PM_SP--;
va009039 0:65f1469d6bfb 196 TOS = pobj3;
va009039 0:65f1469d6bfb 197 continue;
va009039 0:65f1469d6bfb 198 }
va009039 0:65f1469d6bfb 199 #endif /* HAVE_FLOAT */
va009039 0:65f1469d6bfb 200
va009039 0:65f1469d6bfb 201 /* Calculate integer power */
va009039 0:65f1469d6bfb 202 retval = int_pow(TOS1, TOS, &pobj3);
va009039 0:65f1469d6bfb 203 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 204
va009039 0:65f1469d6bfb 205 /* Set return value */
va009039 0:65f1469d6bfb 206 PM_SP--;
va009039 0:65f1469d6bfb 207 TOS = pobj3;
va009039 0:65f1469d6bfb 208 continue;
va009039 0:65f1469d6bfb 209
va009039 0:65f1469d6bfb 210 case GET_ITER:
va009039 0:65f1469d6bfb 211 #ifdef HAVE_GENERATORS
va009039 0:65f1469d6bfb 212 /* Raise TypeError if TOS is an instance, but not iterable */
va009039 0:65f1469d6bfb 213 if (OBJ_GET_TYPE(TOS) == OBJ_TYPE_CLI)
va009039 0:65f1469d6bfb 214 {
va009039 0:65f1469d6bfb 215 retval = class_getAttr(TOS, PM_NEXT_STR, &pobj1);
va009039 0:65f1469d6bfb 216 if (retval != PM_RET_OK)
va009039 0:65f1469d6bfb 217 {
va009039 0:65f1469d6bfb 218 PM_RAISE(retval, PM_RET_EX_TYPE);
va009039 0:65f1469d6bfb 219 break;
va009039 0:65f1469d6bfb 220 }
va009039 0:65f1469d6bfb 221 }
va009039 0:65f1469d6bfb 222 else
va009039 0:65f1469d6bfb 223 #endif /* HAVE_GENERATORS */
va009039 0:65f1469d6bfb 224 {
va009039 0:65f1469d6bfb 225 /* Convert sequence to sequence-iterator */
va009039 0:65f1469d6bfb 226 retval = seqiter_new(TOS, &pobj1);
va009039 0:65f1469d6bfb 227 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 228
va009039 0:65f1469d6bfb 229 /* Put sequence-iterator on top of stack */
va009039 0:65f1469d6bfb 230 TOS = pobj1;
va009039 0:65f1469d6bfb 231 }
va009039 0:65f1469d6bfb 232 continue;
va009039 0:65f1469d6bfb 233
va009039 0:65f1469d6bfb 234 case BINARY_MULTIPLY:
va009039 0:65f1469d6bfb 235 case INPLACE_MULTIPLY:
va009039 0:65f1469d6bfb 236 /* If both objs are ints, perform the op */
va009039 0:65f1469d6bfb 237 if ((OBJ_GET_TYPE(TOS) == OBJ_TYPE_INT)
va009039 0:65f1469d6bfb 238 && (OBJ_GET_TYPE(TOS1) == OBJ_TYPE_INT))
va009039 0:65f1469d6bfb 239 {
va009039 0:65f1469d6bfb 240 retval = int_new(((pPmInt_t)TOS1)->val *
va009039 0:65f1469d6bfb 241 ((pPmInt_t)TOS)->val, &pobj3);
va009039 0:65f1469d6bfb 242 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 243 PM_SP--;
va009039 0:65f1469d6bfb 244 TOS = pobj3;
va009039 0:65f1469d6bfb 245 continue;
va009039 0:65f1469d6bfb 246 }
va009039 0:65f1469d6bfb 247
va009039 0:65f1469d6bfb 248 #ifdef HAVE_FLOAT
va009039 0:65f1469d6bfb 249 else if ((OBJ_GET_TYPE(TOS) == OBJ_TYPE_FLT)
va009039 0:65f1469d6bfb 250 || (OBJ_GET_TYPE(TOS1) == OBJ_TYPE_FLT))
va009039 0:65f1469d6bfb 251 {
va009039 0:65f1469d6bfb 252 retval = float_op(TOS1, TOS, &pobj3, '*');
va009039 0:65f1469d6bfb 253 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 254 PM_SP--;
va009039 0:65f1469d6bfb 255 TOS = pobj3;
va009039 0:65f1469d6bfb 256 continue;
va009039 0:65f1469d6bfb 257 }
va009039 0:65f1469d6bfb 258 #endif /* HAVE_FLOAT */
va009039 0:65f1469d6bfb 259
va009039 0:65f1469d6bfb 260 #ifdef HAVE_REPLICATION
va009039 0:65f1469d6bfb 261 /* If it's a list replication operation */
va009039 0:65f1469d6bfb 262 else if ((OBJ_GET_TYPE(TOS) == OBJ_TYPE_INT)
va009039 0:65f1469d6bfb 263 && (OBJ_GET_TYPE(TOS1) == OBJ_TYPE_LST))
va009039 0:65f1469d6bfb 264 {
va009039 0:65f1469d6bfb 265 t16 = (int16_t)((pPmInt_t)TOS)->val;
va009039 0:65f1469d6bfb 266 if (t16 < 0)
va009039 0:65f1469d6bfb 267 {
va009039 0:65f1469d6bfb 268 t16 = 0;
va009039 0:65f1469d6bfb 269 }
va009039 0:65f1469d6bfb 270
va009039 0:65f1469d6bfb 271 retval = list_replicate(TOS1, t16, &pobj3);
va009039 0:65f1469d6bfb 272 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 273 PM_SP--;
va009039 0:65f1469d6bfb 274 TOS = pobj3;
va009039 0:65f1469d6bfb 275 continue;
va009039 0:65f1469d6bfb 276 }
va009039 0:65f1469d6bfb 277
va009039 0:65f1469d6bfb 278 /* If it's a tuple replication operation */
va009039 0:65f1469d6bfb 279 else if ((OBJ_GET_TYPE(TOS) == OBJ_TYPE_INT)
va009039 0:65f1469d6bfb 280 && (OBJ_GET_TYPE(TOS1) == OBJ_TYPE_TUP))
va009039 0:65f1469d6bfb 281 {
va009039 0:65f1469d6bfb 282 t16 = (int16_t)((pPmInt_t)TOS)->val;
va009039 0:65f1469d6bfb 283 if (t16 < 0)
va009039 0:65f1469d6bfb 284 {
va009039 0:65f1469d6bfb 285 t16 = 0;
va009039 0:65f1469d6bfb 286 }
va009039 0:65f1469d6bfb 287
va009039 0:65f1469d6bfb 288 retval = tuple_replicate(TOS1, t16, &pobj3);
va009039 0:65f1469d6bfb 289 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 290 PM_SP--;
va009039 0:65f1469d6bfb 291 TOS = pobj3;
va009039 0:65f1469d6bfb 292 continue;
va009039 0:65f1469d6bfb 293 }
va009039 0:65f1469d6bfb 294
va009039 0:65f1469d6bfb 295 /* If it's a string replication operation */
va009039 0:65f1469d6bfb 296 else if ((OBJ_GET_TYPE(TOS) == OBJ_TYPE_INT)
va009039 0:65f1469d6bfb 297 && (OBJ_GET_TYPE(TOS1) == OBJ_TYPE_STR))
va009039 0:65f1469d6bfb 298 {
va009039 0:65f1469d6bfb 299 t16 = (int16_t)((pPmInt_t)TOS)->val;
va009039 0:65f1469d6bfb 300 if (t16 < 0)
va009039 0:65f1469d6bfb 301 {
va009039 0:65f1469d6bfb 302 t16 = 0;
va009039 0:65f1469d6bfb 303 }
va009039 0:65f1469d6bfb 304
va009039 0:65f1469d6bfb 305 pobj2 = TOS1;
va009039 0:65f1469d6bfb 306 pobj2 = (pPmObj_t)&((pPmString_t)pobj2)->val;
va009039 0:65f1469d6bfb 307 retval = string_replicate(
va009039 0:65f1469d6bfb 308 (uint8_t const **)(uint8_t *)&pobj2, t16, &pobj3);
va009039 0:65f1469d6bfb 309 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 310 PM_SP--;
va009039 0:65f1469d6bfb 311 TOS = pobj3;
va009039 0:65f1469d6bfb 312 continue;
va009039 0:65f1469d6bfb 313 }
va009039 0:65f1469d6bfb 314 #endif /* HAVE_REPLICATION */
va009039 0:65f1469d6bfb 315
va009039 0:65f1469d6bfb 316 /* Otherwise raise a TypeError */
va009039 0:65f1469d6bfb 317 PM_RAISE(retval, PM_RET_EX_TYPE);
va009039 0:65f1469d6bfb 318 break;
va009039 0:65f1469d6bfb 319
va009039 0:65f1469d6bfb 320 case BINARY_DIVIDE:
va009039 0:65f1469d6bfb 321 case INPLACE_DIVIDE:
va009039 0:65f1469d6bfb 322 case BINARY_FLOOR_DIVIDE:
va009039 0:65f1469d6bfb 323 case INPLACE_FLOOR_DIVIDE:
va009039 0:65f1469d6bfb 324
va009039 0:65f1469d6bfb 325 #ifdef HAVE_FLOAT
va009039 0:65f1469d6bfb 326 if ((OBJ_GET_TYPE(TOS) == OBJ_TYPE_FLT)
va009039 0:65f1469d6bfb 327 || (OBJ_GET_TYPE(TOS1) == OBJ_TYPE_FLT))
va009039 0:65f1469d6bfb 328 {
va009039 0:65f1469d6bfb 329 retval = float_op(TOS1, TOS, &pobj3, '/');
va009039 0:65f1469d6bfb 330 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 331 PM_SP--;
va009039 0:65f1469d6bfb 332 TOS = pobj3;
va009039 0:65f1469d6bfb 333 continue;
va009039 0:65f1469d6bfb 334 }
va009039 0:65f1469d6bfb 335 #endif /* HAVE_FLOAT */
va009039 0:65f1469d6bfb 336
va009039 0:65f1469d6bfb 337 /* Otherwise perform operation */
va009039 0:65f1469d6bfb 338 retval = int_divmod(TOS1, TOS, '/', &pobj3);
va009039 0:65f1469d6bfb 339 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 340 PM_SP--;
va009039 0:65f1469d6bfb 341 TOS = pobj3;
va009039 0:65f1469d6bfb 342 continue;
va009039 0:65f1469d6bfb 343
va009039 0:65f1469d6bfb 344 case BINARY_MODULO:
va009039 0:65f1469d6bfb 345 case INPLACE_MODULO:
va009039 0:65f1469d6bfb 346
va009039 0:65f1469d6bfb 347 #ifdef HAVE_STRING_FORMAT
va009039 0:65f1469d6bfb 348 /* If it's a string, perform string format */
va009039 0:65f1469d6bfb 349 if (OBJ_GET_TYPE(TOS1) == OBJ_TYPE_STR)
va009039 0:65f1469d6bfb 350 {
va009039 0:65f1469d6bfb 351 retval = string_format((pPmString_t)TOS1, TOS, &pobj3);
va009039 0:65f1469d6bfb 352 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 353 PM_SP--;
va009039 0:65f1469d6bfb 354 TOS = pobj3;
va009039 0:65f1469d6bfb 355 continue;
va009039 0:65f1469d6bfb 356 }
va009039 0:65f1469d6bfb 357 #endif /* HAVE_STRING_FORMAT */
va009039 0:65f1469d6bfb 358
va009039 0:65f1469d6bfb 359 #ifdef HAVE_FLOAT
va009039 0:65f1469d6bfb 360 if ((OBJ_GET_TYPE(TOS) == OBJ_TYPE_FLT)
va009039 0:65f1469d6bfb 361 || (OBJ_GET_TYPE(TOS1) == OBJ_TYPE_FLT))
va009039 0:65f1469d6bfb 362 {
va009039 0:65f1469d6bfb 363 retval = float_op(TOS1, TOS, &pobj3, '%');
va009039 0:65f1469d6bfb 364 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 365 PM_SP--;
va009039 0:65f1469d6bfb 366 TOS = pobj3;
va009039 0:65f1469d6bfb 367 continue;
va009039 0:65f1469d6bfb 368 }
va009039 0:65f1469d6bfb 369 #endif /* HAVE_FLOAT */
va009039 0:65f1469d6bfb 370
va009039 0:65f1469d6bfb 371 /* Otherwise perform operation */
va009039 0:65f1469d6bfb 372 retval = int_divmod(TOS1, TOS, '%', &pobj3);
va009039 0:65f1469d6bfb 373 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 374 PM_SP--;
va009039 0:65f1469d6bfb 375 TOS = pobj3;
va009039 0:65f1469d6bfb 376 continue;
va009039 0:65f1469d6bfb 377
va009039 0:65f1469d6bfb 378 case STORE_MAP:
va009039 0:65f1469d6bfb 379 /* #213: Add support for Python 2.6 bytecodes */
va009039 0:65f1469d6bfb 380 C_ASSERT(OBJ_GET_TYPE(TOS2) == OBJ_TYPE_DIC);
va009039 0:65f1469d6bfb 381 retval = dict_setItem(TOS2, TOS, TOS1);
va009039 0:65f1469d6bfb 382 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 383 PM_SP -= 2;
va009039 0:65f1469d6bfb 384 continue;
va009039 0:65f1469d6bfb 385
va009039 0:65f1469d6bfb 386 case BINARY_ADD:
va009039 0:65f1469d6bfb 387 case INPLACE_ADD:
va009039 0:65f1469d6bfb 388
va009039 0:65f1469d6bfb 389 #ifdef HAVE_FLOAT
va009039 0:65f1469d6bfb 390 if ((OBJ_GET_TYPE(TOS) == OBJ_TYPE_FLT)
va009039 0:65f1469d6bfb 391 || (OBJ_GET_TYPE(TOS1) == OBJ_TYPE_FLT))
va009039 0:65f1469d6bfb 392 {
va009039 0:65f1469d6bfb 393 retval = float_op(TOS1, TOS, &pobj3, '+');
va009039 0:65f1469d6bfb 394 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 395 PM_SP--;
va009039 0:65f1469d6bfb 396 TOS = pobj3;
va009039 0:65f1469d6bfb 397 continue;
va009039 0:65f1469d6bfb 398 }
va009039 0:65f1469d6bfb 399 #endif /* HAVE_FLOAT */
va009039 0:65f1469d6bfb 400
va009039 0:65f1469d6bfb 401 /* If both objs are ints, perform the op */
va009039 0:65f1469d6bfb 402 if ((OBJ_GET_TYPE(TOS) == OBJ_TYPE_INT)
va009039 0:65f1469d6bfb 403 && (OBJ_GET_TYPE(TOS1) == OBJ_TYPE_INT))
va009039 0:65f1469d6bfb 404 {
va009039 0:65f1469d6bfb 405 retval = int_new(((pPmInt_t)TOS1)->val +
va009039 0:65f1469d6bfb 406 ((pPmInt_t)TOS)->val, &pobj3);
va009039 0:65f1469d6bfb 407 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 408 PM_SP--;
va009039 0:65f1469d6bfb 409 TOS = pobj3;
va009039 0:65f1469d6bfb 410 continue;
va009039 0:65f1469d6bfb 411 }
va009039 0:65f1469d6bfb 412
va009039 0:65f1469d6bfb 413 /* #242: If both objs are strings, perform concatenation */
va009039 0:65f1469d6bfb 414 if ((OBJ_GET_TYPE(TOS) == OBJ_TYPE_STR)
va009039 0:65f1469d6bfb 415 && (OBJ_GET_TYPE(TOS1) == OBJ_TYPE_STR))
va009039 0:65f1469d6bfb 416 {
va009039 0:65f1469d6bfb 417 retval = string_concat((pPmString_t)TOS1,
va009039 0:65f1469d6bfb 418 (pPmString_t)TOS,
va009039 0:65f1469d6bfb 419 &pobj3);
va009039 0:65f1469d6bfb 420 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 421 PM_SP--;
va009039 0:65f1469d6bfb 422 TOS = pobj3;
va009039 0:65f1469d6bfb 423 continue;
va009039 0:65f1469d6bfb 424 }
va009039 0:65f1469d6bfb 425
va009039 0:65f1469d6bfb 426 /* Otherwise raise a TypeError */
va009039 0:65f1469d6bfb 427 PM_RAISE(retval, PM_RET_EX_TYPE);
va009039 0:65f1469d6bfb 428 break;
va009039 0:65f1469d6bfb 429
va009039 0:65f1469d6bfb 430 case BINARY_SUBTRACT:
va009039 0:65f1469d6bfb 431 case INPLACE_SUBTRACT:
va009039 0:65f1469d6bfb 432
va009039 0:65f1469d6bfb 433 #ifdef HAVE_FLOAT
va009039 0:65f1469d6bfb 434 if ((OBJ_GET_TYPE(TOS) == OBJ_TYPE_FLT)
va009039 0:65f1469d6bfb 435 || (OBJ_GET_TYPE(TOS1) == OBJ_TYPE_FLT))
va009039 0:65f1469d6bfb 436 {
va009039 0:65f1469d6bfb 437 retval = float_op(TOS1, TOS, &pobj3, '-');
va009039 0:65f1469d6bfb 438 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 439 PM_SP--;
va009039 0:65f1469d6bfb 440 TOS = pobj3;
va009039 0:65f1469d6bfb 441 continue;
va009039 0:65f1469d6bfb 442 }
va009039 0:65f1469d6bfb 443 #endif /* HAVE_FLOAT */
va009039 0:65f1469d6bfb 444
va009039 0:65f1469d6bfb 445 /* If both objs are ints, perform the op */
va009039 0:65f1469d6bfb 446 if ((OBJ_GET_TYPE(TOS) == OBJ_TYPE_INT)
va009039 0:65f1469d6bfb 447 && (OBJ_GET_TYPE(TOS1) == OBJ_TYPE_INT))
va009039 0:65f1469d6bfb 448 {
va009039 0:65f1469d6bfb 449 retval = int_new(((pPmInt_t)TOS1)->val -
va009039 0:65f1469d6bfb 450 ((pPmInt_t)TOS)->val, &pobj3);
va009039 0:65f1469d6bfb 451 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 452 PM_SP--;
va009039 0:65f1469d6bfb 453 TOS = pobj3;
va009039 0:65f1469d6bfb 454 continue;
va009039 0:65f1469d6bfb 455 }
va009039 0:65f1469d6bfb 456
va009039 0:65f1469d6bfb 457 /* Otherwise raise a TypeError */
va009039 0:65f1469d6bfb 458 PM_RAISE(retval, PM_RET_EX_TYPE);
va009039 0:65f1469d6bfb 459 break;
va009039 0:65f1469d6bfb 460
va009039 0:65f1469d6bfb 461 case BINARY_SUBSCR:
va009039 0:65f1469d6bfb 462 /* Implements TOS = TOS1[TOS]. */
va009039 0:65f1469d6bfb 463
va009039 0:65f1469d6bfb 464 if (OBJ_GET_TYPE(TOS1) == OBJ_TYPE_DIC)
va009039 0:65f1469d6bfb 465 {
va009039 0:65f1469d6bfb 466 retval = dict_getItem(TOS1, TOS, &pobj3);
va009039 0:65f1469d6bfb 467 }
va009039 0:65f1469d6bfb 468 else
va009039 0:65f1469d6bfb 469 {
va009039 0:65f1469d6bfb 470 /* Raise a TypeError if index is not an Integer or Bool */
va009039 0:65f1469d6bfb 471 if ((OBJ_GET_TYPE(TOS) != OBJ_TYPE_INT)
va009039 0:65f1469d6bfb 472 && (OBJ_GET_TYPE(TOS) != OBJ_TYPE_BOOL))
va009039 0:65f1469d6bfb 473 {
va009039 0:65f1469d6bfb 474 PM_RAISE(retval, PM_RET_EX_TYPE);
va009039 0:65f1469d6bfb 475 break;
va009039 0:65f1469d6bfb 476 }
va009039 0:65f1469d6bfb 477
va009039 0:65f1469d6bfb 478 pobj1 = TOS1;
va009039 0:65f1469d6bfb 479 #ifdef HAVE_BYTEARRAY
va009039 0:65f1469d6bfb 480 /* If object is an instance, get the thing it contains */
va009039 0:65f1469d6bfb 481 if (OBJ_GET_TYPE(pobj1) == OBJ_TYPE_CLI)
va009039 0:65f1469d6bfb 482 {
va009039 0:65f1469d6bfb 483 retval = dict_getItem((pPmObj_t)((pPmInstance_t)pobj1)->cli_attrs,
va009039 0:65f1469d6bfb 484 PM_NONE,
va009039 0:65f1469d6bfb 485 &pobj2);
va009039 0:65f1469d6bfb 486 PM_RETURN_IF_ERROR(retval);
va009039 0:65f1469d6bfb 487 pobj1 = pobj2;
va009039 0:65f1469d6bfb 488 }
va009039 0:65f1469d6bfb 489 #endif /* HAVE_BYTEARRAY */
va009039 0:65f1469d6bfb 490
va009039 0:65f1469d6bfb 491 /* Ensure the index doesn't overflow */
va009039 0:65f1469d6bfb 492 C_ASSERT(((pPmInt_t)TOS)->val <= 0x0000FFFF);
va009039 0:65f1469d6bfb 493 t16 = (int16_t)((pPmInt_t)TOS)->val;
va009039 0:65f1469d6bfb 494
va009039 0:65f1469d6bfb 495 retval = seq_getSubscript(pobj1, t16, &pobj3);
va009039 0:65f1469d6bfb 496 }
va009039 0:65f1469d6bfb 497 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 498 PM_SP--;
va009039 0:65f1469d6bfb 499 TOS = pobj3;
va009039 0:65f1469d6bfb 500 continue;
va009039 0:65f1469d6bfb 501
va009039 0:65f1469d6bfb 502 #ifdef HAVE_FLOAT
va009039 0:65f1469d6bfb 503 /* #213: Add support for Python 2.6 bytecodes */
va009039 0:65f1469d6bfb 504 case BINARY_TRUE_DIVIDE:
va009039 0:65f1469d6bfb 505 case INPLACE_TRUE_DIVIDE:
va009039 0:65f1469d6bfb 506
va009039 0:65f1469d6bfb 507 /* Perform division; float_op() checks for types and zero-div */
va009039 0:65f1469d6bfb 508 retval = float_op(TOS1, TOS, &pobj3, '/');
va009039 0:65f1469d6bfb 509 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 510 PM_SP--;
va009039 0:65f1469d6bfb 511 TOS = pobj3;
va009039 0:65f1469d6bfb 512 continue;
va009039 0:65f1469d6bfb 513 #endif /* HAVE_FLOAT */
va009039 0:65f1469d6bfb 514
va009039 0:65f1469d6bfb 515 case SLICE_0:
va009039 0:65f1469d6bfb 516 /* Implements TOS = TOS[:], push a copy of the sequence */
va009039 0:65f1469d6bfb 517
va009039 0:65f1469d6bfb 518 /* Create a copy if it is a list */
va009039 0:65f1469d6bfb 519 if (OBJ_GET_TYPE(TOS) == OBJ_TYPE_LST)
va009039 0:65f1469d6bfb 520 {
va009039 0:65f1469d6bfb 521 retval = list_copy(TOS, &pobj2);
va009039 0:65f1469d6bfb 522 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 523
va009039 0:65f1469d6bfb 524 TOS = pobj2;
va009039 0:65f1469d6bfb 525 }
va009039 0:65f1469d6bfb 526
va009039 0:65f1469d6bfb 527 /* If TOS is an immutable sequence leave it (no op) */
va009039 0:65f1469d6bfb 528
va009039 0:65f1469d6bfb 529 /* Raise a TypeError for types that can not be sliced */
va009039 0:65f1469d6bfb 530 else if ((OBJ_GET_TYPE(TOS) != OBJ_TYPE_STR)
va009039 0:65f1469d6bfb 531 && (OBJ_GET_TYPE(TOS) != OBJ_TYPE_TUP))
va009039 0:65f1469d6bfb 532 {
va009039 0:65f1469d6bfb 533 PM_RAISE(retval, PM_RET_EX_TYPE);
va009039 0:65f1469d6bfb 534 break;
va009039 0:65f1469d6bfb 535 }
va009039 0:65f1469d6bfb 536 continue;
va009039 0:65f1469d6bfb 537
va009039 0:65f1469d6bfb 538 case STORE_SUBSCR:
va009039 0:65f1469d6bfb 539 /* Implements TOS1[TOS] = TOS2 */
va009039 0:65f1469d6bfb 540
va009039 0:65f1469d6bfb 541 /* If it's a list */
va009039 0:65f1469d6bfb 542 if (OBJ_GET_TYPE(TOS1) == OBJ_TYPE_LST)
va009039 0:65f1469d6bfb 543 {
va009039 0:65f1469d6bfb 544 /* Ensure subscr is an int or bool */
va009039 0:65f1469d6bfb 545 if ((OBJ_GET_TYPE(TOS) != OBJ_TYPE_INT)
va009039 0:65f1469d6bfb 546 && (OBJ_GET_TYPE(TOS) != OBJ_TYPE_BOOL))
va009039 0:65f1469d6bfb 547 {
va009039 0:65f1469d6bfb 548 PM_RAISE(retval, PM_RET_EX_TYPE);
va009039 0:65f1469d6bfb 549 break;
va009039 0:65f1469d6bfb 550 }
va009039 0:65f1469d6bfb 551
va009039 0:65f1469d6bfb 552 /* Set the list item */
va009039 0:65f1469d6bfb 553 retval = list_setItem(TOS1,
va009039 0:65f1469d6bfb 554 (int16_t)(((pPmInt_t)TOS)->val),
va009039 0:65f1469d6bfb 555 TOS2);
va009039 0:65f1469d6bfb 556 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 557 PM_SP -= 3;
va009039 0:65f1469d6bfb 558 continue;
va009039 0:65f1469d6bfb 559 }
va009039 0:65f1469d6bfb 560
va009039 0:65f1469d6bfb 561 /* If it's a dict */
va009039 0:65f1469d6bfb 562 if (OBJ_GET_TYPE(TOS1) == OBJ_TYPE_DIC)
va009039 0:65f1469d6bfb 563 {
va009039 0:65f1469d6bfb 564 /* Set the dict item */
va009039 0:65f1469d6bfb 565 retval = dict_setItem(TOS1, TOS, TOS2);
va009039 0:65f1469d6bfb 566 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 567 PM_SP -= 3;
va009039 0:65f1469d6bfb 568 continue;
va009039 0:65f1469d6bfb 569 }
va009039 0:65f1469d6bfb 570
va009039 0:65f1469d6bfb 571 #ifdef HAVE_BYTEARRAY
va009039 0:65f1469d6bfb 572 /* If object is an instance, get the thing it contains */
va009039 0:65f1469d6bfb 573 if (OBJ_GET_TYPE(TOS1) == OBJ_TYPE_CLI)
va009039 0:65f1469d6bfb 574 {
va009039 0:65f1469d6bfb 575 retval = dict_getItem((pPmObj_t)((pPmInstance_t)TOS1)->cli_attrs,
va009039 0:65f1469d6bfb 576 PM_NONE,
va009039 0:65f1469d6bfb 577 &pobj2);
va009039 0:65f1469d6bfb 578
va009039 0:65f1469d6bfb 579 /* Raise TypeError if instance isn't a ByteArray */
va009039 0:65f1469d6bfb 580 if ((retval == PM_RET_EX_KEY)
va009039 0:65f1469d6bfb 581 || (OBJ_GET_TYPE(pobj2) != OBJ_TYPE_BYA))
va009039 0:65f1469d6bfb 582 {
va009039 0:65f1469d6bfb 583 PM_RAISE(retval, PM_RET_EX_TYPE);
va009039 0:65f1469d6bfb 584 break;
va009039 0:65f1469d6bfb 585 }
va009039 0:65f1469d6bfb 586 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 587
va009039 0:65f1469d6bfb 588 /* Ensure subscr is an int or bool */
va009039 0:65f1469d6bfb 589 if ((OBJ_GET_TYPE(TOS) != OBJ_TYPE_INT)
va009039 0:65f1469d6bfb 590 && (OBJ_GET_TYPE(TOS) != OBJ_TYPE_BOOL))
va009039 0:65f1469d6bfb 591 {
va009039 0:65f1469d6bfb 592 PM_RAISE(retval, PM_RET_EX_TYPE);
va009039 0:65f1469d6bfb 593 break;
va009039 0:65f1469d6bfb 594 }
va009039 0:65f1469d6bfb 595
va009039 0:65f1469d6bfb 596 retval = bytearray_setItem(pobj2,
va009039 0:65f1469d6bfb 597 (int16_t)(((pPmInt_t)TOS)->val),
va009039 0:65f1469d6bfb 598 TOS2);
va009039 0:65f1469d6bfb 599 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 600 PM_SP -= 3;
va009039 0:65f1469d6bfb 601 continue;
va009039 0:65f1469d6bfb 602 }
va009039 0:65f1469d6bfb 603 #endif /* HAVE_BYTEARRAY */
va009039 0:65f1469d6bfb 604
va009039 0:65f1469d6bfb 605 /* TypeError for all else */
va009039 0:65f1469d6bfb 606 PM_RAISE(retval, PM_RET_EX_TYPE);
va009039 0:65f1469d6bfb 607 break;
va009039 0:65f1469d6bfb 608
va009039 0:65f1469d6bfb 609 #ifdef HAVE_DEL
va009039 0:65f1469d6bfb 610 case DELETE_SUBSCR:
va009039 0:65f1469d6bfb 611
va009039 0:65f1469d6bfb 612 if ((OBJ_GET_TYPE(TOS1) == OBJ_TYPE_LST)
va009039 0:65f1469d6bfb 613 && (OBJ_GET_TYPE(TOS) == OBJ_TYPE_INT))
va009039 0:65f1469d6bfb 614 {
va009039 0:65f1469d6bfb 615 retval = list_delItem(TOS1,
va009039 0:65f1469d6bfb 616 (int16_t)((pPmInt_t)TOS)->val);
va009039 0:65f1469d6bfb 617 }
va009039 0:65f1469d6bfb 618
va009039 0:65f1469d6bfb 619 else if ((OBJ_GET_TYPE(TOS1) == OBJ_TYPE_DIC)
va009039 0:65f1469d6bfb 620 && (OBJ_GET_TYPE(TOS) <= OBJ_TYPE_HASHABLE_MAX))
va009039 0:65f1469d6bfb 621 {
va009039 0:65f1469d6bfb 622 retval = dict_delItem(TOS1, TOS);
va009039 0:65f1469d6bfb 623 }
va009039 0:65f1469d6bfb 624
va009039 0:65f1469d6bfb 625 /* Raise TypeError if obj is not a list or dict */
va009039 0:65f1469d6bfb 626 else
va009039 0:65f1469d6bfb 627 {
va009039 0:65f1469d6bfb 628 PM_RAISE(retval, PM_RET_EX_TYPE);
va009039 0:65f1469d6bfb 629 }
va009039 0:65f1469d6bfb 630
va009039 0:65f1469d6bfb 631 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 632 PM_SP -= 2;
va009039 0:65f1469d6bfb 633 continue;
va009039 0:65f1469d6bfb 634 #endif /* HAVE_DEL */
va009039 0:65f1469d6bfb 635
va009039 0:65f1469d6bfb 636 case BINARY_LSHIFT:
va009039 0:65f1469d6bfb 637 case INPLACE_LSHIFT:
va009039 0:65f1469d6bfb 638 /* If both objs are ints, perform the op */
va009039 0:65f1469d6bfb 639 if ((OBJ_GET_TYPE(TOS) == OBJ_TYPE_INT)
va009039 0:65f1469d6bfb 640 && (OBJ_GET_TYPE(TOS1) == OBJ_TYPE_INT))
va009039 0:65f1469d6bfb 641 {
va009039 0:65f1469d6bfb 642 retval = int_new(((pPmInt_t)TOS1)->val <<
va009039 0:65f1469d6bfb 643 ((pPmInt_t)TOS)->val, &pobj3);
va009039 0:65f1469d6bfb 644 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 645 PM_SP--;
va009039 0:65f1469d6bfb 646 TOS = pobj3;
va009039 0:65f1469d6bfb 647 continue;
va009039 0:65f1469d6bfb 648 }
va009039 0:65f1469d6bfb 649
va009039 0:65f1469d6bfb 650 /* Otherwise raise a TypeError */
va009039 0:65f1469d6bfb 651 PM_RAISE(retval, PM_RET_EX_TYPE);
va009039 0:65f1469d6bfb 652 break;
va009039 0:65f1469d6bfb 653
va009039 0:65f1469d6bfb 654 case BINARY_RSHIFT:
va009039 0:65f1469d6bfb 655 case INPLACE_RSHIFT:
va009039 0:65f1469d6bfb 656 /* If both objs are ints, perform the op */
va009039 0:65f1469d6bfb 657 if ((OBJ_GET_TYPE(TOS) == OBJ_TYPE_INT)
va009039 0:65f1469d6bfb 658 && (OBJ_GET_TYPE(TOS1) == OBJ_TYPE_INT))
va009039 0:65f1469d6bfb 659 {
va009039 0:65f1469d6bfb 660 retval = int_new(((pPmInt_t)TOS1)->val >>
va009039 0:65f1469d6bfb 661 ((pPmInt_t)TOS)->val, &pobj3);
va009039 0:65f1469d6bfb 662 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 663 PM_SP--;
va009039 0:65f1469d6bfb 664 TOS = pobj3;
va009039 0:65f1469d6bfb 665 continue;
va009039 0:65f1469d6bfb 666 }
va009039 0:65f1469d6bfb 667
va009039 0:65f1469d6bfb 668 /* Otherwise raise a TypeError */
va009039 0:65f1469d6bfb 669 PM_RAISE(retval, PM_RET_EX_TYPE);
va009039 0:65f1469d6bfb 670 break;
va009039 0:65f1469d6bfb 671
va009039 0:65f1469d6bfb 672 case BINARY_AND:
va009039 0:65f1469d6bfb 673 case INPLACE_AND:
va009039 0:65f1469d6bfb 674 /* If both objs are ints, perform the op */
va009039 0:65f1469d6bfb 675 if ((OBJ_GET_TYPE(TOS) == OBJ_TYPE_INT)
va009039 0:65f1469d6bfb 676 && (OBJ_GET_TYPE(TOS1) == OBJ_TYPE_INT))
va009039 0:65f1469d6bfb 677 {
va009039 0:65f1469d6bfb 678 retval = int_new(((pPmInt_t)TOS1)->val &
va009039 0:65f1469d6bfb 679 ((pPmInt_t)TOS)->val, &pobj3);
va009039 0:65f1469d6bfb 680 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 681 PM_SP--;
va009039 0:65f1469d6bfb 682 TOS = pobj3;
va009039 0:65f1469d6bfb 683 continue;
va009039 0:65f1469d6bfb 684 }
va009039 0:65f1469d6bfb 685
va009039 0:65f1469d6bfb 686 /* Otherwise raise a TypeError */
va009039 0:65f1469d6bfb 687 PM_RAISE(retval, PM_RET_EX_TYPE);
va009039 0:65f1469d6bfb 688 break;
va009039 0:65f1469d6bfb 689
va009039 0:65f1469d6bfb 690 case BINARY_XOR:
va009039 0:65f1469d6bfb 691 case INPLACE_XOR:
va009039 0:65f1469d6bfb 692 /* If both objs are ints, perform the op */
va009039 0:65f1469d6bfb 693 if ((OBJ_GET_TYPE(TOS) == OBJ_TYPE_INT)
va009039 0:65f1469d6bfb 694 && (OBJ_GET_TYPE(TOS1) == OBJ_TYPE_INT))
va009039 0:65f1469d6bfb 695 {
va009039 0:65f1469d6bfb 696 retval = int_new(((pPmInt_t)TOS1)->val ^
va009039 0:65f1469d6bfb 697 ((pPmInt_t)TOS)->val, &pobj3);
va009039 0:65f1469d6bfb 698 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 699 PM_SP--;
va009039 0:65f1469d6bfb 700 TOS = pobj3;
va009039 0:65f1469d6bfb 701 continue;
va009039 0:65f1469d6bfb 702 }
va009039 0:65f1469d6bfb 703
va009039 0:65f1469d6bfb 704 /* Otherwise raise a TypeError */
va009039 0:65f1469d6bfb 705 PM_RAISE(retval, PM_RET_EX_TYPE);
va009039 0:65f1469d6bfb 706 break;
va009039 0:65f1469d6bfb 707
va009039 0:65f1469d6bfb 708 case BINARY_OR:
va009039 0:65f1469d6bfb 709 case INPLACE_OR:
va009039 0:65f1469d6bfb 710 /* If both objs are ints, perform the op */
va009039 0:65f1469d6bfb 711 if ((OBJ_GET_TYPE(TOS) == OBJ_TYPE_INT)
va009039 0:65f1469d6bfb 712 && (OBJ_GET_TYPE(TOS1) == OBJ_TYPE_INT))
va009039 0:65f1469d6bfb 713 {
va009039 0:65f1469d6bfb 714 retval = int_new(((pPmInt_t)TOS1)->val |
va009039 0:65f1469d6bfb 715 ((pPmInt_t)TOS)->val, &pobj3);
va009039 0:65f1469d6bfb 716 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 717 PM_SP--;
va009039 0:65f1469d6bfb 718 TOS = pobj3;
va009039 0:65f1469d6bfb 719 continue;
va009039 0:65f1469d6bfb 720 }
va009039 0:65f1469d6bfb 721
va009039 0:65f1469d6bfb 722 /* Otherwise raise a TypeError */
va009039 0:65f1469d6bfb 723 PM_RAISE(retval, PM_RET_EX_TYPE);
va009039 0:65f1469d6bfb 724 break;
va009039 0:65f1469d6bfb 725
va009039 0:65f1469d6bfb 726 #ifdef HAVE_PRINT
va009039 0:65f1469d6bfb 727 case PRINT_EXPR:
va009039 0:65f1469d6bfb 728 /* Print interactive expression */
va009039 0:65f1469d6bfb 729 /* Fallthrough */
va009039 0:65f1469d6bfb 730
va009039 0:65f1469d6bfb 731 case PRINT_ITEM:
va009039 0:65f1469d6bfb 732 if (gVmGlobal.needSoftSpace && (bc == PRINT_ITEM))
va009039 0:65f1469d6bfb 733 {
va009039 0:65f1469d6bfb 734 retval = plat_putByte(' ');
va009039 0:65f1469d6bfb 735 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 736 }
va009039 0:65f1469d6bfb 737 gVmGlobal.needSoftSpace = C_TRUE;
va009039 0:65f1469d6bfb 738
va009039 0:65f1469d6bfb 739 /* Print out topmost stack element */
va009039 0:65f1469d6bfb 740 retval = obj_print(TOS, (uint8_t)(bc == PRINT_EXPR), C_FALSE);
va009039 0:65f1469d6bfb 741 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 742 PM_SP--;
va009039 0:65f1469d6bfb 743 if (bc != PRINT_EXPR)
va009039 0:65f1469d6bfb 744 {
va009039 0:65f1469d6bfb 745 continue;
va009039 0:65f1469d6bfb 746 }
va009039 0:65f1469d6bfb 747 /* If PRINT_EXPR, Fallthrough to print a newline */
va009039 0:65f1469d6bfb 748
va009039 0:65f1469d6bfb 749 case PRINT_NEWLINE:
va009039 0:65f1469d6bfb 750 gVmGlobal.needSoftSpace = C_FALSE;
va009039 0:65f1469d6bfb 751 if (gVmGlobal.somethingPrinted)
va009039 0:65f1469d6bfb 752 {
va009039 0:65f1469d6bfb 753 retval = plat_putByte('\n');
va009039 0:65f1469d6bfb 754 gVmGlobal.somethingPrinted = C_FALSE;
va009039 0:65f1469d6bfb 755 }
va009039 0:65f1469d6bfb 756 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 757 continue;
va009039 0:65f1469d6bfb 758 #endif /* HAVE_PRINT */
va009039 0:65f1469d6bfb 759
va009039 0:65f1469d6bfb 760 case BREAK_LOOP:
va009039 0:65f1469d6bfb 761 {
va009039 0:65f1469d6bfb 762 pPmBlock_t pb1 = PM_FP->fo_blockstack;
va009039 0:65f1469d6bfb 763
va009039 0:65f1469d6bfb 764 /* Ensure there's a block */
va009039 0:65f1469d6bfb 765 C_ASSERT(pb1 != C_NULL);
va009039 0:65f1469d6bfb 766
va009039 0:65f1469d6bfb 767 /* Delete blocks until first loop block */
va009039 0:65f1469d6bfb 768 while ((pb1->b_type != B_LOOP) && (pb1->next != C_NULL))
va009039 0:65f1469d6bfb 769 {
va009039 0:65f1469d6bfb 770 pobj2 = (pPmObj_t)pb1;
va009039 0:65f1469d6bfb 771 pb1 = pb1->next;
va009039 0:65f1469d6bfb 772 retval = heap_freeChunk(pobj2);
va009039 0:65f1469d6bfb 773 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 774 }
va009039 0:65f1469d6bfb 775
va009039 0:65f1469d6bfb 776 /* Test again outside while loop */
va009039 0:65f1469d6bfb 777 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 778
va009039 0:65f1469d6bfb 779 /* Restore PM_SP */
va009039 0:65f1469d6bfb 780 PM_SP = pb1->b_sp;
va009039 0:65f1469d6bfb 781
va009039 0:65f1469d6bfb 782 /* Goto handler */
va009039 0:65f1469d6bfb 783 PM_IP = pb1->b_handler;
va009039 0:65f1469d6bfb 784
va009039 0:65f1469d6bfb 785 /* Pop and delete this block */
va009039 0:65f1469d6bfb 786 PM_FP->fo_blockstack = pb1->next;
va009039 0:65f1469d6bfb 787 retval = heap_freeChunk((pPmObj_t)pb1);
va009039 0:65f1469d6bfb 788 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 789 }
va009039 0:65f1469d6bfb 790 continue;
va009039 0:65f1469d6bfb 791
va009039 0:65f1469d6bfb 792 case LOAD_LOCALS:
va009039 0:65f1469d6bfb 793 /* Pushes local attrs dict of current frame */
va009039 0:65f1469d6bfb 794 /* WARNING: does not copy fo_locals to attrs */
va009039 0:65f1469d6bfb 795 PM_PUSH((pPmObj_t)PM_FP->fo_attrs);
va009039 0:65f1469d6bfb 796 continue;
va009039 0:65f1469d6bfb 797
va009039 0:65f1469d6bfb 798 case RETURN_VALUE:
va009039 0:65f1469d6bfb 799 /* Get expiring frame's TOS */
va009039 0:65f1469d6bfb 800 pobj2 = PM_POP();
va009039 0:65f1469d6bfb 801
va009039 0:65f1469d6bfb 802 #if 0 /*__DEBUG__*/
va009039 0:65f1469d6bfb 803 /* #251: This safety check is disabled because it breaks ipm */
va009039 0:65f1469d6bfb 804 /* #109: Check that stack should now be empty */
va009039 0:65f1469d6bfb 805 /* If this is regular frame (not native and not a generator) */
va009039 0:65f1469d6bfb 806 if ((PM_FP != (pPmFrame_t)(&gVmGlobal.nativeframe)) &&
va009039 0:65f1469d6bfb 807 !(PM_FP->fo_func->f_co->co_flags & CO_GENERATOR))
va009039 0:65f1469d6bfb 808 {
va009039 0:65f1469d6bfb 809 /* An empty stack points one past end of locals */
va009039 0:65f1469d6bfb 810 t8 = PM_FP->fo_func->f_co->co_nlocals;
va009039 0:65f1469d6bfb 811 C_ASSERT(PM_SP == &(PM_FP->fo_locals[t8]));
va009039 0:65f1469d6bfb 812 }
va009039 0:65f1469d6bfb 813 #endif /* __DEBUG__ */
va009039 0:65f1469d6bfb 814
va009039 0:65f1469d6bfb 815 /* Keep ref of expiring frame */
va009039 0:65f1469d6bfb 816 pobj1 = (pPmObj_t)PM_FP;
va009039 0:65f1469d6bfb 817 C_ASSERT(OBJ_GET_TYPE(pobj1) == OBJ_TYPE_FRM);
va009039 0:65f1469d6bfb 818
va009039 0:65f1469d6bfb 819 /* If no previous frame, quit thread */
va009039 0:65f1469d6bfb 820 if (PM_FP->fo_back == C_NULL)
va009039 0:65f1469d6bfb 821 {
va009039 0:65f1469d6bfb 822 gVmGlobal.pthread->interpctrl = INTERP_CTRL_EXIT;
va009039 0:65f1469d6bfb 823 retval = PM_RET_OK;
va009039 0:65f1469d6bfb 824 break;
va009039 0:65f1469d6bfb 825 }
va009039 0:65f1469d6bfb 826
va009039 0:65f1469d6bfb 827 /* Otherwise return to previous frame */
va009039 0:65f1469d6bfb 828 PM_FP = PM_FP->fo_back;
va009039 0:65f1469d6bfb 829
va009039 0:65f1469d6bfb 830 #ifdef HAVE_GENERATORS
va009039 0:65f1469d6bfb 831 /* If returning function was a generator */
va009039 0:65f1469d6bfb 832 if (((pPmFrame_t)pobj1)->fo_func->f_co->co_flags & CO_GENERATOR)
va009039 0:65f1469d6bfb 833 {
va009039 0:65f1469d6bfb 834 /* Raise a StopIteration exception */
va009039 0:65f1469d6bfb 835 PM_RAISE(retval, PM_RET_EX_STOP);
va009039 0:65f1469d6bfb 836 break;
va009039 0:65f1469d6bfb 837 }
va009039 0:65f1469d6bfb 838 #endif /* HAVE_GENERATORS */
va009039 0:65f1469d6bfb 839
va009039 0:65f1469d6bfb 840 #ifdef HAVE_CLASSES
va009039 0:65f1469d6bfb 841 /*
va009039 0:65f1469d6bfb 842 * If returning function was class initializer
va009039 0:65f1469d6bfb 843 * do not push a return object
va009039 0:65f1469d6bfb 844 */
va009039 0:65f1469d6bfb 845 if (((pPmFrame_t)pobj1)->fo_isInit)
va009039 0:65f1469d6bfb 846 {
va009039 0:65f1469d6bfb 847 /* Raise TypeError if __init__ did not return None */
va009039 0:65f1469d6bfb 848 if (pobj2 != PM_NONE)
va009039 0:65f1469d6bfb 849 {
va009039 0:65f1469d6bfb 850 PM_RAISE(retval, PM_RET_EX_TYPE);
va009039 0:65f1469d6bfb 851 break;
va009039 0:65f1469d6bfb 852 }
va009039 0:65f1469d6bfb 853 }
va009039 0:65f1469d6bfb 854 else
va009039 0:65f1469d6bfb 855 #endif /* HAVE_CLASSES */
va009039 0:65f1469d6bfb 856
va009039 0:65f1469d6bfb 857 /*
va009039 0:65f1469d6bfb 858 * Push frame's return val, except if the expiring frame
va009039 0:65f1469d6bfb 859 * was due to an import statement
va009039 0:65f1469d6bfb 860 */
va009039 0:65f1469d6bfb 861 if (!(((pPmFrame_t)pobj1)->fo_isImport))
va009039 0:65f1469d6bfb 862 {
va009039 0:65f1469d6bfb 863 PM_PUSH(pobj2);
va009039 0:65f1469d6bfb 864 }
va009039 0:65f1469d6bfb 865
va009039 0:65f1469d6bfb 866 /* Deallocate expired frame */
va009039 0:65f1469d6bfb 867 PM_BREAK_IF_ERROR(heap_freeChunk(pobj1));
va009039 0:65f1469d6bfb 868 continue;
va009039 0:65f1469d6bfb 869
va009039 0:65f1469d6bfb 870 #ifdef HAVE_IMPORTS
va009039 0:65f1469d6bfb 871 case IMPORT_STAR:
va009039 0:65f1469d6bfb 872 /* #102: Implement the remaining IMPORT_ bytecodes */
va009039 0:65f1469d6bfb 873 /* Expect a module on the top of the stack */
va009039 0:65f1469d6bfb 874 C_ASSERT(OBJ_GET_TYPE(TOS) == OBJ_TYPE_MOD);
va009039 0:65f1469d6bfb 875
va009039 0:65f1469d6bfb 876 /* Update PM_FP's attrs with those of the module on the stack */
va009039 0:65f1469d6bfb 877 retval = dict_update((pPmObj_t)PM_FP->fo_attrs,
va009039 0:65f1469d6bfb 878 (pPmObj_t)((pPmFunc_t)TOS)->f_attrs,
va009039 0:65f1469d6bfb 879 C_TRUE);
va009039 0:65f1469d6bfb 880 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 881 PM_SP--;
va009039 0:65f1469d6bfb 882 continue;
va009039 0:65f1469d6bfb 883 #endif /* HAVE_IMPORTS */
va009039 0:65f1469d6bfb 884
va009039 0:65f1469d6bfb 885 #ifdef HAVE_GENERATORS
va009039 0:65f1469d6bfb 886 case YIELD_VALUE:
va009039 0:65f1469d6bfb 887 /* #207: Add support for the yield keyword */
va009039 0:65f1469d6bfb 888 /* Get expiring frame's TOS */
va009039 0:65f1469d6bfb 889 pobj1 = PM_POP();
va009039 0:65f1469d6bfb 890
va009039 0:65f1469d6bfb 891 /* Raise TypeError if __init__ did not return None */
va009039 0:65f1469d6bfb 892 /* (Yield means this is a generator) */
va009039 0:65f1469d6bfb 893 if ((PM_FP)->fo_isInit)
va009039 0:65f1469d6bfb 894 {
va009039 0:65f1469d6bfb 895 PM_RAISE(retval, PM_RET_EX_TYPE);
va009039 0:65f1469d6bfb 896 break;
va009039 0:65f1469d6bfb 897 }
va009039 0:65f1469d6bfb 898
va009039 0:65f1469d6bfb 899 /* Return to previous frame */
va009039 0:65f1469d6bfb 900 PM_FP = PM_FP->fo_back;
va009039 0:65f1469d6bfb 901
va009039 0:65f1469d6bfb 902 /* Push yield value onto caller's TOS */
va009039 0:65f1469d6bfb 903 PM_PUSH(pobj1);
va009039 0:65f1469d6bfb 904 continue;
va009039 0:65f1469d6bfb 905 #endif /* HAVE_GENERATORS */
va009039 0:65f1469d6bfb 906
va009039 0:65f1469d6bfb 907 case POP_BLOCK:
va009039 0:65f1469d6bfb 908 /* Get ptr to top block */
va009039 0:65f1469d6bfb 909 pobj1 = (pPmObj_t)PM_FP->fo_blockstack;
va009039 0:65f1469d6bfb 910
va009039 0:65f1469d6bfb 911 /* If there's no block, raise SystemError */
va009039 0:65f1469d6bfb 912 C_ASSERT(pobj1 != C_NULL);
va009039 0:65f1469d6bfb 913
va009039 0:65f1469d6bfb 914 /* Pop block */
va009039 0:65f1469d6bfb 915 PM_FP->fo_blockstack = PM_FP->fo_blockstack->next;
va009039 0:65f1469d6bfb 916
va009039 0:65f1469d6bfb 917 /* Set stack to previous level, jump to code outside block */
va009039 0:65f1469d6bfb 918 PM_SP = ((pPmBlock_t)pobj1)->b_sp;
va009039 0:65f1469d6bfb 919 PM_IP = ((pPmBlock_t)pobj1)->b_handler;
va009039 0:65f1469d6bfb 920
va009039 0:65f1469d6bfb 921 PM_BREAK_IF_ERROR(heap_freeChunk(pobj1));
va009039 0:65f1469d6bfb 922 continue;
va009039 0:65f1469d6bfb 923
va009039 0:65f1469d6bfb 924 #ifdef HAVE_CLASSES
va009039 0:65f1469d6bfb 925 case BUILD_CLASS:
va009039 0:65f1469d6bfb 926 /* Create and push new class */
va009039 0:65f1469d6bfb 927 retval = class_new(TOS, TOS1, TOS2, &pobj2);
va009039 0:65f1469d6bfb 928 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 929 PM_SP -= 2;
va009039 0:65f1469d6bfb 930 TOS = pobj2;
va009039 0:65f1469d6bfb 931 continue;
va009039 0:65f1469d6bfb 932 #endif /* HAVE_CLASSES */
va009039 0:65f1469d6bfb 933
va009039 0:65f1469d6bfb 934
va009039 0:65f1469d6bfb 935 /***************************************************
va009039 0:65f1469d6bfb 936 * All bytecodes after 90 (0x5A) have a 2-byte arg
va009039 0:65f1469d6bfb 937 * that needs to be swallowed using GET_ARG().
va009039 0:65f1469d6bfb 938 **************************************************/
va009039 0:65f1469d6bfb 939
va009039 0:65f1469d6bfb 940 case STORE_NAME:
va009039 0:65f1469d6bfb 941 /* Get name index */
va009039 0:65f1469d6bfb 942 t16 = GET_ARG();
va009039 0:65f1469d6bfb 943
va009039 0:65f1469d6bfb 944 /* Get key */
va009039 0:65f1469d6bfb 945 pobj2 = PM_FP->fo_func->f_co->co_names->val[t16];
va009039 0:65f1469d6bfb 946
va009039 0:65f1469d6bfb 947 /* Set key=val in current frame's attrs dict */
va009039 0:65f1469d6bfb 948 retval = dict_setItem((pPmObj_t)PM_FP->fo_attrs, pobj2, TOS);
va009039 0:65f1469d6bfb 949 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 950 PM_SP--;
va009039 0:65f1469d6bfb 951 continue;
va009039 0:65f1469d6bfb 952
va009039 0:65f1469d6bfb 953 #ifdef HAVE_DEL
va009039 0:65f1469d6bfb 954 case DELETE_NAME:
va009039 0:65f1469d6bfb 955 /* Get name index */
va009039 0:65f1469d6bfb 956 t16 = GET_ARG();
va009039 0:65f1469d6bfb 957
va009039 0:65f1469d6bfb 958 /* Get key */
va009039 0:65f1469d6bfb 959 pobj2 = PM_FP->fo_func->f_co->co_names->val[t16];
va009039 0:65f1469d6bfb 960
va009039 0:65f1469d6bfb 961 /* Remove key,val pair from current frame's attrs dict */
va009039 0:65f1469d6bfb 962 retval = dict_delItem((pPmObj_t)PM_FP->fo_attrs, pobj2);
va009039 0:65f1469d6bfb 963 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 964 continue;
va009039 0:65f1469d6bfb 965 #endif /* HAVE_DEL */
va009039 0:65f1469d6bfb 966
va009039 0:65f1469d6bfb 967 case UNPACK_SEQUENCE:
va009039 0:65f1469d6bfb 968 /* Get ptr to sequence */
va009039 0:65f1469d6bfb 969 pobj1 = PM_POP();
va009039 0:65f1469d6bfb 970
va009039 0:65f1469d6bfb 971 #ifdef HAVE_BYTEARRAY
va009039 0:65f1469d6bfb 972 /* If object is an instance, get the thing it contains */
va009039 0:65f1469d6bfb 973 if (OBJ_GET_TYPE(pobj1) == OBJ_TYPE_CLI)
va009039 0:65f1469d6bfb 974 {
va009039 0:65f1469d6bfb 975 retval = dict_getItem((pPmObj_t)((pPmInstance_t)pobj1)->cli_attrs,
va009039 0:65f1469d6bfb 976 PM_NONE,
va009039 0:65f1469d6bfb 977 &pobj2);
va009039 0:65f1469d6bfb 978 PM_RETURN_IF_ERROR(retval);
va009039 0:65f1469d6bfb 979 pobj1 = pobj2;
va009039 0:65f1469d6bfb 980 }
va009039 0:65f1469d6bfb 981 #endif /* HAVE_BYTEARRAY */
va009039 0:65f1469d6bfb 982
va009039 0:65f1469d6bfb 983 /*
va009039 0:65f1469d6bfb 984 * Get the length of the sequence; this will
va009039 0:65f1469d6bfb 985 * raise TypeError if obj is not a sequence.
va009039 0:65f1469d6bfb 986 *
va009039 0:65f1469d6bfb 987 * #59: Unpacking to a Dict shall not be supported
va009039 0:65f1469d6bfb 988 */
va009039 0:65f1469d6bfb 989 retval = seq_getLength(pobj1, (uint16_t *)&t16);
va009039 0:65f1469d6bfb 990 if (retval != PM_RET_OK)
va009039 0:65f1469d6bfb 991 {
va009039 0:65f1469d6bfb 992 GET_ARG();
va009039 0:65f1469d6bfb 993 break;
va009039 0:65f1469d6bfb 994 }
va009039 0:65f1469d6bfb 995
va009039 0:65f1469d6bfb 996 /* Raise ValueError if seq length does not match num args */
va009039 0:65f1469d6bfb 997 if (t16 != GET_ARG())
va009039 0:65f1469d6bfb 998 {
va009039 0:65f1469d6bfb 999 PM_RAISE(retval, PM_RET_EX_VAL);
va009039 0:65f1469d6bfb 1000 break;
va009039 0:65f1469d6bfb 1001 }
va009039 0:65f1469d6bfb 1002
va009039 0:65f1469d6bfb 1003 /* Push sequence's objs onto stack */
va009039 0:65f1469d6bfb 1004 for (; --t16 >= 0;)
va009039 0:65f1469d6bfb 1005 {
va009039 0:65f1469d6bfb 1006 retval = seq_getSubscript(pobj1, t16, &pobj2);
va009039 0:65f1469d6bfb 1007 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 1008 PM_PUSH(pobj2);
va009039 0:65f1469d6bfb 1009 }
va009039 0:65f1469d6bfb 1010
va009039 0:65f1469d6bfb 1011 /* Test again outside the for loop */
va009039 0:65f1469d6bfb 1012 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 1013 continue;
va009039 0:65f1469d6bfb 1014
va009039 0:65f1469d6bfb 1015 case FOR_ITER:
va009039 0:65f1469d6bfb 1016 t16 = GET_ARG();
va009039 0:65f1469d6bfb 1017
va009039 0:65f1469d6bfb 1018 #ifdef HAVE_GENERATORS
va009039 0:65f1469d6bfb 1019 /* If TOS is an instance, call next method */
va009039 0:65f1469d6bfb 1020 if (OBJ_GET_TYPE(TOS) == OBJ_TYPE_CLI)
va009039 0:65f1469d6bfb 1021 {
va009039 0:65f1469d6bfb 1022 /* Get the next() func */
va009039 0:65f1469d6bfb 1023 retval = class_getAttr(TOS, PM_NEXT_STR, &pobj1);
va009039 0:65f1469d6bfb 1024 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 1025
va009039 0:65f1469d6bfb 1026 /* Push the func and instance as an arg */
va009039 0:65f1469d6bfb 1027 pobj2 = TOS;
va009039 0:65f1469d6bfb 1028 PM_PUSH(pobj1);
va009039 0:65f1469d6bfb 1029 PM_PUSH(pobj2);
va009039 0:65f1469d6bfb 1030 t16 = 1;
va009039 0:65f1469d6bfb 1031
va009039 0:65f1469d6bfb 1032 /* Ensure pobj1 is the func */
va009039 0:65f1469d6bfb 1033 goto CALL_FUNC_FOR_ITER;
va009039 0:65f1469d6bfb 1034 }
va009039 0:65f1469d6bfb 1035 else
va009039 0:65f1469d6bfb 1036 #endif /* HAVE_GENERATORS */
va009039 0:65f1469d6bfb 1037 {
va009039 0:65f1469d6bfb 1038 /* Get the next item in the sequence iterator */
va009039 0:65f1469d6bfb 1039 retval = seqiter_getNext(TOS, &pobj2);
va009039 0:65f1469d6bfb 1040 }
va009039 0:65f1469d6bfb 1041
va009039 0:65f1469d6bfb 1042 /* Catch StopIteration early: pop iterator and break loop */
va009039 0:65f1469d6bfb 1043 if (retval == PM_RET_EX_STOP)
va009039 0:65f1469d6bfb 1044 {
va009039 0:65f1469d6bfb 1045 PM_SP--;
va009039 0:65f1469d6bfb 1046 retval = PM_RET_OK;
va009039 0:65f1469d6bfb 1047 PM_IP += t16;
va009039 0:65f1469d6bfb 1048 continue;
va009039 0:65f1469d6bfb 1049 }
va009039 0:65f1469d6bfb 1050 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 1051
va009039 0:65f1469d6bfb 1052 /* Push the next item onto the stack */
va009039 0:65f1469d6bfb 1053 PM_PUSH(pobj2);
va009039 0:65f1469d6bfb 1054 continue;
va009039 0:65f1469d6bfb 1055
va009039 0:65f1469d6bfb 1056 case STORE_ATTR:
va009039 0:65f1469d6bfb 1057 /* TOS.name = TOS1 */
va009039 0:65f1469d6bfb 1058 /* Get names index */
va009039 0:65f1469d6bfb 1059 t16 = GET_ARG();
va009039 0:65f1469d6bfb 1060
va009039 0:65f1469d6bfb 1061 /* Get attrs dict from obj */
va009039 0:65f1469d6bfb 1062 if ((OBJ_GET_TYPE(TOS) == OBJ_TYPE_FXN)
va009039 0:65f1469d6bfb 1063 || (OBJ_GET_TYPE(TOS) == OBJ_TYPE_MOD))
va009039 0:65f1469d6bfb 1064 {
va009039 0:65f1469d6bfb 1065 pobj2 = (pPmObj_t)((pPmFunc_t)TOS)->f_attrs;
va009039 0:65f1469d6bfb 1066 }
va009039 0:65f1469d6bfb 1067
va009039 0:65f1469d6bfb 1068 #ifdef HAVE_CLASSES
va009039 0:65f1469d6bfb 1069 else if (OBJ_GET_TYPE(TOS) == OBJ_TYPE_CLO)
va009039 0:65f1469d6bfb 1070 {
va009039 0:65f1469d6bfb 1071 pobj2 = (pPmObj_t)((pPmClass_t)TOS)->cl_attrs;
va009039 0:65f1469d6bfb 1072 }
va009039 0:65f1469d6bfb 1073 else if (OBJ_GET_TYPE(TOS) == OBJ_TYPE_CLI)
va009039 0:65f1469d6bfb 1074 {
va009039 0:65f1469d6bfb 1075 pobj2 = (pPmObj_t)((pPmInstance_t)TOS)->cli_attrs;
va009039 0:65f1469d6bfb 1076 }
va009039 0:65f1469d6bfb 1077 else if (OBJ_GET_TYPE(TOS) == OBJ_TYPE_MTH)
va009039 0:65f1469d6bfb 1078 {
va009039 0:65f1469d6bfb 1079 pobj2 = (pPmObj_t)((pPmMethod_t)TOS)->m_attrs;
va009039 0:65f1469d6bfb 1080 }
va009039 0:65f1469d6bfb 1081 #endif /* HAVE_CLASSES */
va009039 0:65f1469d6bfb 1082
va009039 0:65f1469d6bfb 1083 /* Other types result in an AttributeError */
va009039 0:65f1469d6bfb 1084 else
va009039 0:65f1469d6bfb 1085 {
va009039 0:65f1469d6bfb 1086 PM_RAISE(retval, PM_RET_EX_ATTR);
va009039 0:65f1469d6bfb 1087 break;
va009039 0:65f1469d6bfb 1088 }
va009039 0:65f1469d6bfb 1089
va009039 0:65f1469d6bfb 1090 /* If attrs is not a dict, raise SystemError */
va009039 0:65f1469d6bfb 1091 if (OBJ_GET_TYPE(pobj2) != OBJ_TYPE_DIC)
va009039 0:65f1469d6bfb 1092 {
va009039 0:65f1469d6bfb 1093 PM_RAISE(retval, PM_RET_EX_SYS);
va009039 0:65f1469d6bfb 1094 break;
va009039 0:65f1469d6bfb 1095 }
va009039 0:65f1469d6bfb 1096
va009039 0:65f1469d6bfb 1097 /* Get name/key obj */
va009039 0:65f1469d6bfb 1098 pobj3 = PM_FP->fo_func->f_co->co_names->val[t16];
va009039 0:65f1469d6bfb 1099
va009039 0:65f1469d6bfb 1100 /* Set key=val in obj's dict */
va009039 0:65f1469d6bfb 1101 retval = dict_setItem(pobj2, pobj3, TOS1);
va009039 0:65f1469d6bfb 1102 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 1103 PM_SP -= 2;
va009039 0:65f1469d6bfb 1104 continue;
va009039 0:65f1469d6bfb 1105
va009039 0:65f1469d6bfb 1106 #ifdef HAVE_DEL
va009039 0:65f1469d6bfb 1107 case DELETE_ATTR:
va009039 0:65f1469d6bfb 1108 /* del TOS.name */
va009039 0:65f1469d6bfb 1109 /* Get names index */
va009039 0:65f1469d6bfb 1110 t16 = GET_ARG();
va009039 0:65f1469d6bfb 1111
va009039 0:65f1469d6bfb 1112 /* Get attrs dict from obj */
va009039 0:65f1469d6bfb 1113 if ((OBJ_GET_TYPE(TOS) == OBJ_TYPE_FXN)
va009039 0:65f1469d6bfb 1114 || (OBJ_GET_TYPE(TOS) == OBJ_TYPE_MOD))
va009039 0:65f1469d6bfb 1115 {
va009039 0:65f1469d6bfb 1116 pobj2 = (pPmObj_t)((pPmFunc_t)TOS)->f_attrs;
va009039 0:65f1469d6bfb 1117 }
va009039 0:65f1469d6bfb 1118
va009039 0:65f1469d6bfb 1119 #ifdef HAVE_CLASSES
va009039 0:65f1469d6bfb 1120 else if (OBJ_GET_TYPE(TOS) == OBJ_TYPE_CLO)
va009039 0:65f1469d6bfb 1121 {
va009039 0:65f1469d6bfb 1122 pobj2 = (pPmObj_t)((pPmClass_t)TOS)->cl_attrs;
va009039 0:65f1469d6bfb 1123 }
va009039 0:65f1469d6bfb 1124 else if (OBJ_GET_TYPE(TOS) == OBJ_TYPE_CLI)
va009039 0:65f1469d6bfb 1125 {
va009039 0:65f1469d6bfb 1126 pobj2 = (pPmObj_t)((pPmInstance_t)TOS)->cli_attrs;
va009039 0:65f1469d6bfb 1127 }
va009039 0:65f1469d6bfb 1128 else if (OBJ_GET_TYPE(TOS) == OBJ_TYPE_MTH)
va009039 0:65f1469d6bfb 1129 {
va009039 0:65f1469d6bfb 1130 pobj2 = (pPmObj_t)((pPmMethod_t)TOS)->m_attrs;
va009039 0:65f1469d6bfb 1131 }
va009039 0:65f1469d6bfb 1132 #endif /* HAVE_CLASSES */
va009039 0:65f1469d6bfb 1133
va009039 0:65f1469d6bfb 1134 /* Other types result in an AttributeError */
va009039 0:65f1469d6bfb 1135 else
va009039 0:65f1469d6bfb 1136 {
va009039 0:65f1469d6bfb 1137 PM_RAISE(retval, PM_RET_EX_ATTR);
va009039 0:65f1469d6bfb 1138 break;
va009039 0:65f1469d6bfb 1139 }
va009039 0:65f1469d6bfb 1140
va009039 0:65f1469d6bfb 1141 /* If attrs is not a dict, raise SystemError */
va009039 0:65f1469d6bfb 1142 if (OBJ_GET_TYPE(pobj2) != OBJ_TYPE_DIC)
va009039 0:65f1469d6bfb 1143 {
va009039 0:65f1469d6bfb 1144 PM_RAISE(retval, PM_RET_EX_SYS);
va009039 0:65f1469d6bfb 1145 break;
va009039 0:65f1469d6bfb 1146 }
va009039 0:65f1469d6bfb 1147
va009039 0:65f1469d6bfb 1148 /* Get name/key obj */
va009039 0:65f1469d6bfb 1149 pobj3 = PM_FP->fo_func->f_co->co_names->val[t16];
va009039 0:65f1469d6bfb 1150
va009039 0:65f1469d6bfb 1151 /* Remove key,val from obj's dict */
va009039 0:65f1469d6bfb 1152 retval = dict_delItem(pobj2, pobj3);
va009039 0:65f1469d6bfb 1153
va009039 0:65f1469d6bfb 1154 /* Raise an AttributeError if key is not found */
va009039 0:65f1469d6bfb 1155 if (retval == PM_RET_EX_KEY)
va009039 0:65f1469d6bfb 1156 {
va009039 0:65f1469d6bfb 1157 PM_RAISE(retval, PM_RET_EX_ATTR);
va009039 0:65f1469d6bfb 1158 }
va009039 0:65f1469d6bfb 1159
va009039 0:65f1469d6bfb 1160 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 1161 PM_SP--;
va009039 0:65f1469d6bfb 1162 continue;
va009039 0:65f1469d6bfb 1163 #endif /* HAVE_DEL */
va009039 0:65f1469d6bfb 1164
va009039 0:65f1469d6bfb 1165 case STORE_GLOBAL:
va009039 0:65f1469d6bfb 1166 /* Get name index */
va009039 0:65f1469d6bfb 1167 t16 = GET_ARG();
va009039 0:65f1469d6bfb 1168
va009039 0:65f1469d6bfb 1169 /* Get key */
va009039 0:65f1469d6bfb 1170 pobj2 = PM_FP->fo_func->f_co->co_names->val[t16];
va009039 0:65f1469d6bfb 1171
va009039 0:65f1469d6bfb 1172 /* Set key=val in global dict */
va009039 0:65f1469d6bfb 1173 retval = dict_setItem((pPmObj_t)PM_FP->fo_globals, pobj2, TOS);
va009039 0:65f1469d6bfb 1174 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 1175 PM_SP--;
va009039 0:65f1469d6bfb 1176 continue;
va009039 0:65f1469d6bfb 1177
va009039 0:65f1469d6bfb 1178 #ifdef HAVE_DEL
va009039 0:65f1469d6bfb 1179 case DELETE_GLOBAL:
va009039 0:65f1469d6bfb 1180 /* Get name index */
va009039 0:65f1469d6bfb 1181 t16 = GET_ARG();
va009039 0:65f1469d6bfb 1182
va009039 0:65f1469d6bfb 1183 /* Get key */
va009039 0:65f1469d6bfb 1184 pobj2 = PM_FP->fo_func->f_co->co_names->val[t16];
va009039 0:65f1469d6bfb 1185
va009039 0:65f1469d6bfb 1186 /* Remove key,val from globals */
va009039 0:65f1469d6bfb 1187 retval = dict_delItem((pPmObj_t)PM_FP->fo_globals, pobj2);
va009039 0:65f1469d6bfb 1188 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 1189 continue;
va009039 0:65f1469d6bfb 1190 #endif /* HAVE_DEL */
va009039 0:65f1469d6bfb 1191
va009039 0:65f1469d6bfb 1192 case DUP_TOPX:
va009039 0:65f1469d6bfb 1193 t16 = GET_ARG();
va009039 0:65f1469d6bfb 1194 C_ASSERT(t16 <= 3);
va009039 0:65f1469d6bfb 1195
va009039 0:65f1469d6bfb 1196 pobj1 = TOS;
va009039 0:65f1469d6bfb 1197 pobj2 = TOS1;
va009039 0:65f1469d6bfb 1198 pobj3 = TOS2;
va009039 0:65f1469d6bfb 1199 if (t16 >= 3)
va009039 0:65f1469d6bfb 1200 PM_PUSH(pobj3);
va009039 0:65f1469d6bfb 1201 if (t16 >= 2)
va009039 0:65f1469d6bfb 1202 PM_PUSH(pobj2);
va009039 0:65f1469d6bfb 1203 if (t16 >= 1)
va009039 0:65f1469d6bfb 1204 PM_PUSH(pobj1);
va009039 0:65f1469d6bfb 1205 continue;
va009039 0:65f1469d6bfb 1206
va009039 0:65f1469d6bfb 1207 case LOAD_CONST:
va009039 0:65f1469d6bfb 1208 /* Get const's index in CO */
va009039 0:65f1469d6bfb 1209 t16 = GET_ARG();
va009039 0:65f1469d6bfb 1210
va009039 0:65f1469d6bfb 1211 /* Push const on stack */
va009039 0:65f1469d6bfb 1212 PM_PUSH(PM_FP->fo_func->f_co->co_consts->val[t16]);
va009039 0:65f1469d6bfb 1213 continue;
va009039 0:65f1469d6bfb 1214
va009039 0:65f1469d6bfb 1215 case LOAD_NAME:
va009039 0:65f1469d6bfb 1216 /* Get name index */
va009039 0:65f1469d6bfb 1217 t16 = GET_ARG();
va009039 0:65f1469d6bfb 1218
va009039 0:65f1469d6bfb 1219 /* Get name from names tuple */
va009039 0:65f1469d6bfb 1220 pobj1 = PM_FP->fo_func->f_co->co_names->val[t16];
va009039 0:65f1469d6bfb 1221
va009039 0:65f1469d6bfb 1222 /* Get value from frame's attrs dict */
va009039 0:65f1469d6bfb 1223 retval = dict_getItem((pPmObj_t)PM_FP->fo_attrs, pobj1, &pobj2);
va009039 0:65f1469d6bfb 1224 if (retval == PM_RET_EX_KEY)
va009039 0:65f1469d6bfb 1225 {
va009039 0:65f1469d6bfb 1226 /* Get val from globals */
va009039 0:65f1469d6bfb 1227 retval = dict_getItem((pPmObj_t)PM_FP->fo_globals,
va009039 0:65f1469d6bfb 1228 pobj1, &pobj2);
va009039 0:65f1469d6bfb 1229
va009039 0:65f1469d6bfb 1230 /* Check for name in the builtins module if it is loaded */
va009039 0:65f1469d6bfb 1231 if ((retval == PM_RET_EX_KEY) && (PM_PBUILTINS != C_NULL))
va009039 0:65f1469d6bfb 1232 {
va009039 0:65f1469d6bfb 1233 /* Get val from builtins */
va009039 0:65f1469d6bfb 1234 retval = dict_getItem(PM_PBUILTINS, pobj1, &pobj2);
va009039 0:65f1469d6bfb 1235 if (retval == PM_RET_EX_KEY)
va009039 0:65f1469d6bfb 1236 {
va009039 0:65f1469d6bfb 1237 /* Name not defined, raise NameError */
va009039 0:65f1469d6bfb 1238 PM_RAISE(retval, PM_RET_EX_NAME);
va009039 0:65f1469d6bfb 1239 break;
va009039 0:65f1469d6bfb 1240 }
va009039 0:65f1469d6bfb 1241 }
va009039 0:65f1469d6bfb 1242 }
va009039 0:65f1469d6bfb 1243 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 1244 PM_PUSH(pobj2);
va009039 0:65f1469d6bfb 1245 continue;
va009039 0:65f1469d6bfb 1246
va009039 0:65f1469d6bfb 1247 case BUILD_TUPLE:
va009039 0:65f1469d6bfb 1248 /* Get num items */
va009039 0:65f1469d6bfb 1249 t16 = GET_ARG();
va009039 0:65f1469d6bfb 1250 retval = tuple_new(t16, &pobj1);
va009039 0:65f1469d6bfb 1251 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 1252
va009039 0:65f1469d6bfb 1253 /* Fill tuple with ptrs to objs */
va009039 0:65f1469d6bfb 1254 for (; --t16 >= 0;)
va009039 0:65f1469d6bfb 1255 {
va009039 0:65f1469d6bfb 1256 ((pPmTuple_t)pobj1)->val[t16] = PM_POP();
va009039 0:65f1469d6bfb 1257 }
va009039 0:65f1469d6bfb 1258 PM_PUSH(pobj1);
va009039 0:65f1469d6bfb 1259 continue;
va009039 0:65f1469d6bfb 1260
va009039 0:65f1469d6bfb 1261 case BUILD_LIST:
va009039 0:65f1469d6bfb 1262 t16 = GET_ARG();
va009039 0:65f1469d6bfb 1263 retval = list_new(&pobj1);
va009039 0:65f1469d6bfb 1264 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 1265 for (; --t16 >= 0;)
va009039 0:65f1469d6bfb 1266 {
va009039 0:65f1469d6bfb 1267 /* Insert obj into list */
va009039 0:65f1469d6bfb 1268 heap_gcPushTempRoot(pobj1, &objid);
va009039 0:65f1469d6bfb 1269 retval = list_insert(pobj1, 0, TOS);
va009039 0:65f1469d6bfb 1270 heap_gcPopTempRoot(objid);
va009039 0:65f1469d6bfb 1271 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 1272 PM_SP--;
va009039 0:65f1469d6bfb 1273 }
va009039 0:65f1469d6bfb 1274 /* Test again outside for loop */
va009039 0:65f1469d6bfb 1275 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 1276
va009039 0:65f1469d6bfb 1277 /* push list onto stack */
va009039 0:65f1469d6bfb 1278 PM_PUSH(pobj1);
va009039 0:65f1469d6bfb 1279 continue;
va009039 0:65f1469d6bfb 1280
va009039 0:65f1469d6bfb 1281 case BUILD_MAP:
va009039 0:65f1469d6bfb 1282 /* Argument is ignored */
va009039 0:65f1469d6bfb 1283 t16 = GET_ARG();
va009039 0:65f1469d6bfb 1284 retval = dict_new(&pobj1);
va009039 0:65f1469d6bfb 1285 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 1286 PM_PUSH(pobj1);
va009039 0:65f1469d6bfb 1287 continue;
va009039 0:65f1469d6bfb 1288
va009039 0:65f1469d6bfb 1289 case LOAD_ATTR:
va009039 0:65f1469d6bfb 1290 /* Implements TOS.attr */
va009039 0:65f1469d6bfb 1291 t16 = GET_ARG();
va009039 0:65f1469d6bfb 1292
va009039 0:65f1469d6bfb 1293 #ifdef HAVE_AUTOBOX
va009039 0:65f1469d6bfb 1294 /* Autobox the object, if necessary */
va009039 0:65f1469d6bfb 1295 retval = class_autobox(&TOS);
va009039 0:65f1469d6bfb 1296 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 1297 #endif
va009039 0:65f1469d6bfb 1298
va009039 0:65f1469d6bfb 1299 /* Get attrs dict from obj */
va009039 0:65f1469d6bfb 1300 if ((OBJ_GET_TYPE(TOS) == OBJ_TYPE_FXN) ||
va009039 0:65f1469d6bfb 1301 (OBJ_GET_TYPE(TOS) == OBJ_TYPE_MOD))
va009039 0:65f1469d6bfb 1302 {
va009039 0:65f1469d6bfb 1303 pobj1 = (pPmObj_t)((pPmFunc_t)TOS)->f_attrs;
va009039 0:65f1469d6bfb 1304 }
va009039 0:65f1469d6bfb 1305
va009039 0:65f1469d6bfb 1306 #ifdef HAVE_CLASSES
va009039 0:65f1469d6bfb 1307 else if (OBJ_GET_TYPE(TOS) == OBJ_TYPE_CLO)
va009039 0:65f1469d6bfb 1308 {
va009039 0:65f1469d6bfb 1309 pobj1 = (pPmObj_t)((pPmClass_t)TOS)->cl_attrs;
va009039 0:65f1469d6bfb 1310 }
va009039 0:65f1469d6bfb 1311 else if (OBJ_GET_TYPE(TOS) == OBJ_TYPE_CLI)
va009039 0:65f1469d6bfb 1312 {
va009039 0:65f1469d6bfb 1313 pobj1 = (pPmObj_t)((pPmInstance_t)TOS)->cli_attrs;
va009039 0:65f1469d6bfb 1314 }
va009039 0:65f1469d6bfb 1315 else if (OBJ_GET_TYPE(TOS) == OBJ_TYPE_MTH)
va009039 0:65f1469d6bfb 1316 {
va009039 0:65f1469d6bfb 1317 pobj1 = (pPmObj_t)((pPmMethod_t)TOS)->m_attrs;
va009039 0:65f1469d6bfb 1318 }
va009039 0:65f1469d6bfb 1319 #endif /* HAVE_CLASSES */
va009039 0:65f1469d6bfb 1320
va009039 0:65f1469d6bfb 1321 /* Other types result in an AttributeError */
va009039 0:65f1469d6bfb 1322 else
va009039 0:65f1469d6bfb 1323 {
va009039 0:65f1469d6bfb 1324 PM_RAISE(retval, PM_RET_EX_ATTR);
va009039 0:65f1469d6bfb 1325 break;
va009039 0:65f1469d6bfb 1326 }
va009039 0:65f1469d6bfb 1327
va009039 0:65f1469d6bfb 1328 /* If attrs is not a dict, raise SystemError */
va009039 0:65f1469d6bfb 1329 if (OBJ_GET_TYPE(pobj1) != OBJ_TYPE_DIC)
va009039 0:65f1469d6bfb 1330 {
va009039 0:65f1469d6bfb 1331 PM_RAISE(retval, PM_RET_EX_SYS);
va009039 0:65f1469d6bfb 1332 break;
va009039 0:65f1469d6bfb 1333 }
va009039 0:65f1469d6bfb 1334
va009039 0:65f1469d6bfb 1335 /* Get name */
va009039 0:65f1469d6bfb 1336 pobj2 = PM_FP->fo_func->f_co->co_names->val[t16];
va009039 0:65f1469d6bfb 1337
va009039 0:65f1469d6bfb 1338 /* Get attr with given name */
va009039 0:65f1469d6bfb 1339 retval = dict_getItem(pobj1, pobj2, &pobj3);
va009039 0:65f1469d6bfb 1340
va009039 0:65f1469d6bfb 1341 #ifdef HAVE_CLASSES
va009039 0:65f1469d6bfb 1342 /*
va009039 0:65f1469d6bfb 1343 * If attr is not found and object is a class or instance,
va009039 0:65f1469d6bfb 1344 * try to get the attribute from the class attrs or parent(s)
va009039 0:65f1469d6bfb 1345 */
va009039 0:65f1469d6bfb 1346 if ((retval == PM_RET_EX_KEY) &&
va009039 0:65f1469d6bfb 1347 ((OBJ_GET_TYPE(TOS) == OBJ_TYPE_CLO)
va009039 0:65f1469d6bfb 1348 || (OBJ_GET_TYPE(TOS) == OBJ_TYPE_CLI)))
va009039 0:65f1469d6bfb 1349 {
va009039 0:65f1469d6bfb 1350 retval = class_getAttr(TOS, pobj2, &pobj3);
va009039 0:65f1469d6bfb 1351 }
va009039 0:65f1469d6bfb 1352 #endif /* HAVE_CLASSES */
va009039 0:65f1469d6bfb 1353
va009039 0:65f1469d6bfb 1354 /* Raise an AttributeError if key is not found */
va009039 0:65f1469d6bfb 1355 if (retval == PM_RET_EX_KEY)
va009039 0:65f1469d6bfb 1356 {
va009039 0:65f1469d6bfb 1357 PM_RAISE(retval, PM_RET_EX_ATTR);
va009039 0:65f1469d6bfb 1358 }
va009039 0:65f1469d6bfb 1359 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 1360
va009039 0:65f1469d6bfb 1361 #ifdef HAVE_CLASSES
va009039 0:65f1469d6bfb 1362 /* If obj is an instance and attr is a func, create method */
va009039 0:65f1469d6bfb 1363 if ((OBJ_GET_TYPE(TOS) == OBJ_TYPE_CLI) &&
va009039 0:65f1469d6bfb 1364 (OBJ_GET_TYPE(pobj3) == OBJ_TYPE_FXN))
va009039 0:65f1469d6bfb 1365 {
va009039 0:65f1469d6bfb 1366 pobj2 = pobj3;
va009039 0:65f1469d6bfb 1367 retval = class_method(TOS, pobj2, &pobj3);
va009039 0:65f1469d6bfb 1368 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 1369 }
va009039 0:65f1469d6bfb 1370 #endif /* HAVE_CLASSES */
va009039 0:65f1469d6bfb 1371
va009039 0:65f1469d6bfb 1372 /* Put attr on the stack */
va009039 0:65f1469d6bfb 1373 TOS = pobj3;
va009039 0:65f1469d6bfb 1374 continue;
va009039 0:65f1469d6bfb 1375
va009039 0:65f1469d6bfb 1376 case COMPARE_OP:
va009039 0:65f1469d6bfb 1377 retval = PM_RET_OK;
va009039 0:65f1469d6bfb 1378 t16 = GET_ARG();
va009039 0:65f1469d6bfb 1379
va009039 0:65f1469d6bfb 1380 #ifdef HAVE_FLOAT
va009039 0:65f1469d6bfb 1381 if ((OBJ_GET_TYPE(TOS) == OBJ_TYPE_FLT)
va009039 0:65f1469d6bfb 1382 || (OBJ_GET_TYPE(TOS1) == OBJ_TYPE_FLT))
va009039 0:65f1469d6bfb 1383 {
va009039 0:65f1469d6bfb 1384 retval = float_compare(TOS1, TOS, &pobj3, (PmCompare_t)t16);
va009039 0:65f1469d6bfb 1385 PM_SP--;
va009039 0:65f1469d6bfb 1386 TOS = pobj3;
va009039 0:65f1469d6bfb 1387 continue;
va009039 0:65f1469d6bfb 1388 }
va009039 0:65f1469d6bfb 1389 #endif /* HAVE_FLOAT */
va009039 0:65f1469d6bfb 1390
va009039 0:65f1469d6bfb 1391 /* Handle all integer-to-integer (or bool) comparisons */
va009039 0:65f1469d6bfb 1392 if (((OBJ_GET_TYPE(TOS) == OBJ_TYPE_INT)
va009039 0:65f1469d6bfb 1393 || (OBJ_GET_TYPE(TOS) == OBJ_TYPE_BOOL))
va009039 0:65f1469d6bfb 1394 && ((OBJ_GET_TYPE(TOS1) == OBJ_TYPE_INT)
va009039 0:65f1469d6bfb 1395 || (OBJ_GET_TYPE(TOS1) == OBJ_TYPE_BOOL)))
va009039 0:65f1469d6bfb 1396 {
va009039 0:65f1469d6bfb 1397 int32_t a = ((pPmInt_t)TOS1)->val;
va009039 0:65f1469d6bfb 1398 int32_t b = ((pPmInt_t)TOS)->val;
va009039 0:65f1469d6bfb 1399
va009039 0:65f1469d6bfb 1400 switch (t16)
va009039 0:65f1469d6bfb 1401 {
va009039 0:65f1469d6bfb 1402 /* *INDENT-OFF* */
va009039 0:65f1469d6bfb 1403 case COMP_LT: t8 = (int8_t)(a < b); break;
va009039 0:65f1469d6bfb 1404 case COMP_LE: t8 = (int8_t)(a <= b); break;
va009039 0:65f1469d6bfb 1405 case COMP_EQ: t8 = (int8_t)(a == b); break;
va009039 0:65f1469d6bfb 1406 case COMP_NE: t8 = (int8_t)(a != b); break;
va009039 0:65f1469d6bfb 1407 case COMP_GT: t8 = (int8_t)(a > b); break;
va009039 0:65f1469d6bfb 1408 case COMP_GE: t8 = (int8_t)(a >= b); break;
va009039 0:65f1469d6bfb 1409 case COMP_IS: t8 = (int8_t)(TOS == TOS1); break;
va009039 0:65f1469d6bfb 1410 case COMP_IS_NOT: t8 = (int8_t)(TOS != TOS1);break;
va009039 0:65f1469d6bfb 1411 case COMP_IN:
va009039 0:65f1469d6bfb 1412 case COMP_NOT_IN:
va009039 0:65f1469d6bfb 1413 PM_RAISE(retval, PM_RET_EX_TYPE);
va009039 0:65f1469d6bfb 1414 break;
va009039 0:65f1469d6bfb 1415
va009039 0:65f1469d6bfb 1416 default:
va009039 0:65f1469d6bfb 1417 /* Other compares are not yet supported */
va009039 0:65f1469d6bfb 1418 PM_RAISE(retval, PM_RET_EX_SYS);
va009039 0:65f1469d6bfb 1419 break;
va009039 0:65f1469d6bfb 1420 /* *INDENT-ON* */
va009039 0:65f1469d6bfb 1421 }
va009039 0:65f1469d6bfb 1422 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 1423 pobj3 = (t8) ? PM_TRUE : PM_FALSE;
va009039 0:65f1469d6bfb 1424 }
va009039 0:65f1469d6bfb 1425
va009039 0:65f1469d6bfb 1426 /* Handle non-integer comparisons */
va009039 0:65f1469d6bfb 1427 else
va009039 0:65f1469d6bfb 1428 {
va009039 0:65f1469d6bfb 1429 retval = PM_RET_OK;
va009039 0:65f1469d6bfb 1430 switch (t16)
va009039 0:65f1469d6bfb 1431 {
va009039 0:65f1469d6bfb 1432 case COMP_EQ:
va009039 0:65f1469d6bfb 1433 case COMP_NE:
va009039 0:65f1469d6bfb 1434 /* Handle equality for non-int types */
va009039 0:65f1469d6bfb 1435 pobj3 = PM_FALSE;
va009039 0:65f1469d6bfb 1436 t8 = obj_compare(TOS, TOS1);
va009039 0:65f1469d6bfb 1437 if (((t8 == C_SAME) && (t16 == COMP_EQ))
va009039 0:65f1469d6bfb 1438 || ((t8 == C_DIFFER) && (t16 == COMP_NE)))
va009039 0:65f1469d6bfb 1439 {
va009039 0:65f1469d6bfb 1440 pobj3 = PM_TRUE;
va009039 0:65f1469d6bfb 1441 }
va009039 0:65f1469d6bfb 1442 break;
va009039 0:65f1469d6bfb 1443
va009039 0:65f1469d6bfb 1444 case COMP_IN:
va009039 0:65f1469d6bfb 1445 case COMP_NOT_IN:
va009039 0:65f1469d6bfb 1446 /* Handle membership comparisons */
va009039 0:65f1469d6bfb 1447 pobj3 = PM_FALSE;
va009039 0:65f1469d6bfb 1448 retval = obj_isIn(TOS, TOS1);
va009039 0:65f1469d6bfb 1449 if (retval == PM_RET_OK)
va009039 0:65f1469d6bfb 1450 {
va009039 0:65f1469d6bfb 1451 if (t16 == COMP_IN)
va009039 0:65f1469d6bfb 1452 {
va009039 0:65f1469d6bfb 1453 pobj3 = PM_TRUE;
va009039 0:65f1469d6bfb 1454 }
va009039 0:65f1469d6bfb 1455 }
va009039 0:65f1469d6bfb 1456 else if (retval == PM_RET_NO)
va009039 0:65f1469d6bfb 1457 {
va009039 0:65f1469d6bfb 1458 retval = PM_RET_OK;
va009039 0:65f1469d6bfb 1459 if (t16 == COMP_NOT_IN)
va009039 0:65f1469d6bfb 1460 {
va009039 0:65f1469d6bfb 1461 pobj3 = PM_TRUE;
va009039 0:65f1469d6bfb 1462 }
va009039 0:65f1469d6bfb 1463 }
va009039 0:65f1469d6bfb 1464 break;
va009039 0:65f1469d6bfb 1465
va009039 0:65f1469d6bfb 1466 case COMP_IS:
va009039 0:65f1469d6bfb 1467 pobj3 = (TOS == TOS1) ? PM_TRUE : PM_FALSE;
va009039 0:65f1469d6bfb 1468 break;
va009039 0:65f1469d6bfb 1469
va009039 0:65f1469d6bfb 1470 case COMP_IS_NOT:
va009039 0:65f1469d6bfb 1471 pobj3 = (TOS != TOS1) ? PM_TRUE : PM_FALSE;
va009039 0:65f1469d6bfb 1472 break;
va009039 0:65f1469d6bfb 1473
va009039 0:65f1469d6bfb 1474 default:
va009039 0:65f1469d6bfb 1475 /* Other comparisons are not implemented */
va009039 0:65f1469d6bfb 1476 PM_RAISE(retval, PM_RET_EX_SYS);
va009039 0:65f1469d6bfb 1477 break;
va009039 0:65f1469d6bfb 1478 }
va009039 0:65f1469d6bfb 1479 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 1480 }
va009039 0:65f1469d6bfb 1481 PM_SP--;
va009039 0:65f1469d6bfb 1482 TOS = pobj3;
va009039 0:65f1469d6bfb 1483 continue;
va009039 0:65f1469d6bfb 1484
va009039 0:65f1469d6bfb 1485 case IMPORT_NAME:
va009039 0:65f1469d6bfb 1486 /* Get name index */
va009039 0:65f1469d6bfb 1487 t16 = GET_ARG();
va009039 0:65f1469d6bfb 1488
va009039 0:65f1469d6bfb 1489 /* Get name String obj */
va009039 0:65f1469d6bfb 1490 pobj1 = PM_FP->fo_func->f_co->co_names->val[t16];
va009039 0:65f1469d6bfb 1491
va009039 0:65f1469d6bfb 1492 /* Pop unused None object */
va009039 0:65f1469d6bfb 1493 PM_SP--;
va009039 0:65f1469d6bfb 1494
va009039 0:65f1469d6bfb 1495 /* Ensure "level" is -1; no support for relative import yet */
va009039 0:65f1469d6bfb 1496 C_ASSERT(obj_compare(TOS, PM_NEGONE) == C_SAME);
va009039 0:65f1469d6bfb 1497
va009039 0:65f1469d6bfb 1498 /* #178: Fix import so modules are reused */
va009039 0:65f1469d6bfb 1499 /* Return the module if found in the modules dict (cache) */
va009039 0:65f1469d6bfb 1500 retval = dict_getItem(PM_PBUILTINS, PM_MD_STR, &pobj3);
va009039 0:65f1469d6bfb 1501 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 1502 retval = dict_getItem(pobj3, pobj1, &pobj2);
va009039 0:65f1469d6bfb 1503 if (retval == PM_RET_OK)
va009039 0:65f1469d6bfb 1504 {
va009039 0:65f1469d6bfb 1505 TOS = pobj2;
va009039 0:65f1469d6bfb 1506 continue;
va009039 0:65f1469d6bfb 1507 }
va009039 0:65f1469d6bfb 1508 if (retval != PM_RET_EX_KEY)
va009039 0:65f1469d6bfb 1509 {
va009039 0:65f1469d6bfb 1510 break;
va009039 0:65f1469d6bfb 1511 }
va009039 0:65f1469d6bfb 1512
va009039 0:65f1469d6bfb 1513 /* Load module from image */
va009039 0:65f1469d6bfb 1514 retval = mod_import(pobj1, &pobj2);
va009039 0:65f1469d6bfb 1515 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 1516
va009039 0:65f1469d6bfb 1517 /* #178: Fix import so modules are reused */
va009039 0:65f1469d6bfb 1518 /*
va009039 0:65f1469d6bfb 1519 * Store the module's attrs/globals under the module's name
va009039 0:65f1469d6bfb 1520 * in the global module dict (cache)
va009039 0:65f1469d6bfb 1521 */
va009039 0:65f1469d6bfb 1522 heap_gcPushTempRoot(pobj2, &objid);
va009039 0:65f1469d6bfb 1523 retval = dict_setItem(pobj3, pobj1, pobj2);
va009039 0:65f1469d6bfb 1524 heap_gcPopTempRoot(objid);
va009039 0:65f1469d6bfb 1525 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 1526
va009039 0:65f1469d6bfb 1527 /* Put Module on top of stack */
va009039 0:65f1469d6bfb 1528 TOS = pobj2;
va009039 0:65f1469d6bfb 1529
va009039 0:65f1469d6bfb 1530 /* Code after here is a duplicate of CALL_FUNCTION */
va009039 0:65f1469d6bfb 1531 /* Make frame object to interpret the module's root code */
va009039 0:65f1469d6bfb 1532 heap_gcPushTempRoot(pobj2, &objid);
va009039 0:65f1469d6bfb 1533 retval = frame_new(pobj2, &pobj3);
va009039 0:65f1469d6bfb 1534 heap_gcPopTempRoot(objid);
va009039 0:65f1469d6bfb 1535 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 1536
va009039 0:65f1469d6bfb 1537 /* No arguments to pass */
va009039 0:65f1469d6bfb 1538
va009039 0:65f1469d6bfb 1539 /* Keep ref to current frame */
va009039 0:65f1469d6bfb 1540 ((pPmFrame_t)pobj3)->fo_back = PM_FP;
va009039 0:65f1469d6bfb 1541
va009039 0:65f1469d6bfb 1542 /* Handle to have None popped on return */
va009039 0:65f1469d6bfb 1543 ((pPmFrame_t)pobj3)->fo_isImport = (uint8_t)1;
va009039 0:65f1469d6bfb 1544
va009039 0:65f1469d6bfb 1545 /* Set new frame */
va009039 0:65f1469d6bfb 1546 PM_FP = (pPmFrame_t)pobj3;
va009039 0:65f1469d6bfb 1547 continue;
va009039 0:65f1469d6bfb 1548
va009039 0:65f1469d6bfb 1549 #ifdef HAVE_IMPORTS
va009039 0:65f1469d6bfb 1550 case IMPORT_FROM:
va009039 0:65f1469d6bfb 1551 /* #102: Implement the remaining IMPORT_ bytecodes */
va009039 0:65f1469d6bfb 1552 /* Expect the module on the top of the stack */
va009039 0:65f1469d6bfb 1553 C_ASSERT(OBJ_GET_TYPE(TOS) == OBJ_TYPE_MOD);
va009039 0:65f1469d6bfb 1554 pobj1 = TOS;
va009039 0:65f1469d6bfb 1555
va009039 0:65f1469d6bfb 1556 /* Get the name of the object to import */
va009039 0:65f1469d6bfb 1557 t16 = GET_ARG();
va009039 0:65f1469d6bfb 1558 pobj2 = PM_FP->fo_func->f_co->co_names->val[t16];
va009039 0:65f1469d6bfb 1559
va009039 0:65f1469d6bfb 1560 /* Get the object from the module's attributes */
va009039 0:65f1469d6bfb 1561 retval = dict_getItem((pPmObj_t)((pPmFunc_t)pobj1)->f_attrs,
va009039 0:65f1469d6bfb 1562 pobj2, &pobj3);
va009039 0:65f1469d6bfb 1563 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 1564
va009039 0:65f1469d6bfb 1565 /* Push the object onto the top of the stack */
va009039 0:65f1469d6bfb 1566 PM_PUSH(pobj3);
va009039 0:65f1469d6bfb 1567 continue;
va009039 0:65f1469d6bfb 1568 #endif /* HAVE_IMPORTS */
va009039 0:65f1469d6bfb 1569
va009039 0:65f1469d6bfb 1570 case JUMP_FORWARD:
va009039 0:65f1469d6bfb 1571 t16 = GET_ARG();
va009039 0:65f1469d6bfb 1572 PM_IP += t16;
va009039 0:65f1469d6bfb 1573 continue;
va009039 1:28afb064a41c 1574
va009039 1:28afb064a41c 1575 #ifdef HAVE_PYTHON27
va009039 1:28afb064a41c 1576 case JUMP_IF_FALSE_OR_POP:
va009039 1:28afb064a41c 1577 t16 = GET_ARG();
va009039 1:28afb064a41c 1578 if (obj_isFalse(TOS))
va009039 1:28afb064a41c 1579 {
va009039 1:28afb064a41c 1580 PM_IP = PM_FP->fo_func->f_co->co_codeaddr + t16;
va009039 1:28afb064a41c 1581 }
va009039 1:28afb064a41c 1582 else
va009039 1:28afb064a41c 1583 {
va009039 1:28afb064a41c 1584 --PM_SP;
va009039 1:28afb064a41c 1585 }
va009039 1:28afb064a41c 1586 continue;
va009039 0:65f1469d6bfb 1587
va009039 1:28afb064a41c 1588 case JUMP_IF_TRUE_OR_POP:
va009039 1:28afb064a41c 1589 t16 = GET_ARG();
va009039 1:28afb064a41c 1590 if (!obj_isFalse(TOS))
va009039 1:28afb064a41c 1591 {
va009039 1:28afb064a41c 1592 PM_IP = PM_FP->fo_func->f_co->co_codeaddr + t16;
va009039 1:28afb064a41c 1593 }
va009039 1:28afb064a41c 1594 else
va009039 1:28afb064a41c 1595 {
va009039 1:28afb064a41c 1596 --PM_SP;
va009039 1:28afb064a41c 1597 }
va009039 1:28afb064a41c 1598 continue;
va009039 1:28afb064a41c 1599
va009039 1:28afb064a41c 1600 case POP_JUMP_IF_FALSE:
va009039 1:28afb064a41c 1601 t16 = GET_ARG();
va009039 1:28afb064a41c 1602 if (obj_isFalse(TOS))
va009039 1:28afb064a41c 1603 {
va009039 1:28afb064a41c 1604 PM_IP = PM_FP->fo_func->f_co->co_codeaddr + t16;
va009039 1:28afb064a41c 1605 }
va009039 1:28afb064a41c 1606 --PM_SP;
va009039 1:28afb064a41c 1607 continue;
va009039 1:28afb064a41c 1608
va009039 1:28afb064a41c 1609 case POP_JUMP_IF_TRUE:
va009039 1:28afb064a41c 1610 t16 = GET_ARG();
va009039 1:28afb064a41c 1611 if (!obj_isFalse(TOS))
va009039 1:28afb064a41c 1612 {
va009039 1:28afb064a41c 1613 PM_IP = PM_FP->fo_func->f_co->co_codeaddr + t16;
va009039 1:28afb064a41c 1614 }
va009039 1:28afb064a41c 1615 --PM_SP;
va009039 1:28afb064a41c 1616 continue;
va009039 1:28afb064a41c 1617 #else /* HAVE_PYTHON27 */
va009039 0:65f1469d6bfb 1618 case JUMP_IF_FALSE:
va009039 0:65f1469d6bfb 1619 t16 = GET_ARG();
va009039 0:65f1469d6bfb 1620 if (obj_isFalse(TOS))
va009039 0:65f1469d6bfb 1621 {
va009039 0:65f1469d6bfb 1622 PM_IP += t16;
va009039 0:65f1469d6bfb 1623 }
va009039 0:65f1469d6bfb 1624 continue;
va009039 0:65f1469d6bfb 1625
va009039 0:65f1469d6bfb 1626 case JUMP_IF_TRUE:
va009039 0:65f1469d6bfb 1627 t16 = GET_ARG();
va009039 0:65f1469d6bfb 1628 if (!obj_isFalse(TOS))
va009039 0:65f1469d6bfb 1629 {
va009039 0:65f1469d6bfb 1630 PM_IP += t16;
va009039 0:65f1469d6bfb 1631 }
va009039 0:65f1469d6bfb 1632 continue;
va009039 1:28afb064a41c 1633 #endif /* HAVE_PYTHON27 */
va009039 0:65f1469d6bfb 1634
va009039 0:65f1469d6bfb 1635 case JUMP_ABSOLUTE:
va009039 0:65f1469d6bfb 1636 case CONTINUE_LOOP:
va009039 0:65f1469d6bfb 1637 /* Get target offset (bytes) */
va009039 0:65f1469d6bfb 1638 t16 = GET_ARG();
va009039 0:65f1469d6bfb 1639
va009039 0:65f1469d6bfb 1640 /* Jump to base_ip + arg */
va009039 0:65f1469d6bfb 1641 PM_IP = PM_FP->fo_func->f_co->co_codeaddr + t16;
va009039 0:65f1469d6bfb 1642 continue;
va009039 0:65f1469d6bfb 1643
va009039 0:65f1469d6bfb 1644 case LOAD_GLOBAL:
va009039 0:65f1469d6bfb 1645 /* Get name */
va009039 0:65f1469d6bfb 1646 t16 = GET_ARG();
va009039 0:65f1469d6bfb 1647 pobj1 = PM_FP->fo_func->f_co->co_names->val[t16];
va009039 0:65f1469d6bfb 1648
va009039 0:65f1469d6bfb 1649 /* Try globals first */
va009039 0:65f1469d6bfb 1650 retval = dict_getItem((pPmObj_t)PM_FP->fo_globals,
va009039 0:65f1469d6bfb 1651 pobj1, &pobj2);
va009039 0:65f1469d6bfb 1652
va009039 0:65f1469d6bfb 1653 /* If that didn't work, try builtins */
va009039 0:65f1469d6bfb 1654 if (retval == PM_RET_EX_KEY)
va009039 0:65f1469d6bfb 1655 {
va009039 0:65f1469d6bfb 1656 retval = dict_getItem(PM_PBUILTINS, pobj1, &pobj2);
va009039 0:65f1469d6bfb 1657
va009039 0:65f1469d6bfb 1658 /* No such global, raise NameError */
va009039 0:65f1469d6bfb 1659 if (retval == PM_RET_EX_KEY)
va009039 0:65f1469d6bfb 1660 {
va009039 0:65f1469d6bfb 1661 PM_RAISE(retval, PM_RET_EX_NAME);
va009039 0:65f1469d6bfb 1662 break;
va009039 0:65f1469d6bfb 1663 }
va009039 0:65f1469d6bfb 1664 }
va009039 0:65f1469d6bfb 1665 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 1666 PM_PUSH(pobj2);
va009039 0:65f1469d6bfb 1667 continue;
va009039 0:65f1469d6bfb 1668
va009039 0:65f1469d6bfb 1669 case SETUP_LOOP:
va009039 0:65f1469d6bfb 1670 {
va009039 0:65f1469d6bfb 1671 uint8_t *pchunk;
va009039 0:65f1469d6bfb 1672
va009039 0:65f1469d6bfb 1673 /* Get block span (bytes) */
va009039 0:65f1469d6bfb 1674 t16 = GET_ARG();
va009039 0:65f1469d6bfb 1675
va009039 0:65f1469d6bfb 1676 /* Create block */
va009039 0:65f1469d6bfb 1677 retval = heap_getChunk(sizeof(PmBlock_t), &pchunk);
va009039 0:65f1469d6bfb 1678 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 1679 pobj1 = (pPmObj_t)pchunk;
va009039 0:65f1469d6bfb 1680 OBJ_SET_TYPE(pobj1, OBJ_TYPE_BLK);
va009039 0:65f1469d6bfb 1681
va009039 0:65f1469d6bfb 1682 /* Store current stack pointer */
va009039 0:65f1469d6bfb 1683 ((pPmBlock_t)pobj1)->b_sp = PM_SP;
va009039 0:65f1469d6bfb 1684
va009039 0:65f1469d6bfb 1685 /* Default handler is to exit block/loop */
va009039 0:65f1469d6bfb 1686 ((pPmBlock_t)pobj1)->b_handler = PM_IP + t16;
va009039 0:65f1469d6bfb 1687 ((pPmBlock_t)pobj1)->b_type = B_LOOP;
va009039 0:65f1469d6bfb 1688
va009039 0:65f1469d6bfb 1689 /* Insert block into blockstack */
va009039 0:65f1469d6bfb 1690 ((pPmBlock_t)pobj1)->next = PM_FP->fo_blockstack;
va009039 0:65f1469d6bfb 1691 PM_FP->fo_blockstack = (pPmBlock_t)pobj1;
va009039 0:65f1469d6bfb 1692 continue;
va009039 0:65f1469d6bfb 1693 }
va009039 0:65f1469d6bfb 1694
va009039 0:65f1469d6bfb 1695 case LOAD_FAST:
va009039 0:65f1469d6bfb 1696 t16 = GET_ARG();
va009039 0:65f1469d6bfb 1697 PM_PUSH(PM_FP->fo_locals[t16]);
va009039 0:65f1469d6bfb 1698 continue;
va009039 0:65f1469d6bfb 1699
va009039 0:65f1469d6bfb 1700 case STORE_FAST:
va009039 0:65f1469d6bfb 1701 t16 = GET_ARG();
va009039 0:65f1469d6bfb 1702 PM_FP->fo_locals[t16] = PM_POP();
va009039 0:65f1469d6bfb 1703 continue;
va009039 0:65f1469d6bfb 1704
va009039 0:65f1469d6bfb 1705 #ifdef HAVE_DEL
va009039 0:65f1469d6bfb 1706 case DELETE_FAST:
va009039 0:65f1469d6bfb 1707 t16 = GET_ARG();
va009039 0:65f1469d6bfb 1708 PM_FP->fo_locals[t16] = PM_NONE;
va009039 0:65f1469d6bfb 1709 continue;
va009039 0:65f1469d6bfb 1710 #endif /* HAVE_DEL */
va009039 0:65f1469d6bfb 1711
va009039 0:65f1469d6bfb 1712 #ifdef HAVE_ASSERT
va009039 0:65f1469d6bfb 1713 case RAISE_VARARGS:
va009039 0:65f1469d6bfb 1714 t16 = GET_ARG();
va009039 0:65f1469d6bfb 1715
va009039 0:65f1469d6bfb 1716 /* Only supports taking 1 arg for now */
va009039 0:65f1469d6bfb 1717 if (t16 != 1)
va009039 0:65f1469d6bfb 1718 {
va009039 0:65f1469d6bfb 1719 PM_RAISE(retval, PM_RET_EX_SYS);
va009039 0:65f1469d6bfb 1720 break;
va009039 0:65f1469d6bfb 1721 }
va009039 0:65f1469d6bfb 1722
va009039 0:65f1469d6bfb 1723 /* Load Exception class from builtins */
va009039 0:65f1469d6bfb 1724 retval = dict_getItem(PM_PBUILTINS, PM_EXCEPTION_STR, &pobj2);
va009039 0:65f1469d6bfb 1725 if (retval != PM_RET_OK)
va009039 0:65f1469d6bfb 1726 {
va009039 0:65f1469d6bfb 1727 PM_RAISE(retval, PM_RET_EX_SYS);
va009039 0:65f1469d6bfb 1728 break;
va009039 0:65f1469d6bfb 1729 }
va009039 0:65f1469d6bfb 1730
va009039 0:65f1469d6bfb 1731 /* Raise TypeError if TOS is not an instance of Exception */
va009039 0:65f1469d6bfb 1732 pobj1 = TOS;
va009039 0:65f1469d6bfb 1733 if ((OBJ_GET_TYPE(pobj1) != OBJ_TYPE_CLO)
va009039 0:65f1469d6bfb 1734 || !class_isSubclass(pobj1, pobj2))
va009039 0:65f1469d6bfb 1735 {
va009039 0:65f1469d6bfb 1736 PM_RAISE(retval, PM_RET_EX_TYPE);
va009039 0:65f1469d6bfb 1737 break;
va009039 0:65f1469d6bfb 1738 }
va009039 0:65f1469d6bfb 1739
va009039 0:65f1469d6bfb 1740 /* Push the traceback, parameter and exception object */
va009039 0:65f1469d6bfb 1741 TOS = PM_NONE;
va009039 0:65f1469d6bfb 1742 PM_PUSH(PM_NONE);
va009039 0:65f1469d6bfb 1743 PM_PUSH(pobj1);
va009039 0:65f1469d6bfb 1744
va009039 0:65f1469d6bfb 1745 /* Get the exception's code attr */
va009039 0:65f1469d6bfb 1746 retval = dict_getItem((pPmObj_t)((pPmClass_t)pobj1)->cl_attrs,
va009039 0:65f1469d6bfb 1747 PM_CODE_STR, &pobj2);
va009039 0:65f1469d6bfb 1748 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 1749
va009039 0:65f1469d6bfb 1750 /* Raise exception by breaking with retval set to code */
va009039 0:65f1469d6bfb 1751 PM_RAISE(retval, (PmReturn_t)(((pPmInt_t)pobj2)->val & 0xFF));
va009039 0:65f1469d6bfb 1752 break;
va009039 0:65f1469d6bfb 1753 #endif /* HAVE_ASSERT */
va009039 0:65f1469d6bfb 1754
va009039 0:65f1469d6bfb 1755 case CALL_FUNCTION:
va009039 0:65f1469d6bfb 1756 /* Get num args */
va009039 0:65f1469d6bfb 1757 t16 = GET_ARG();
va009039 0:65f1469d6bfb 1758
va009039 0:65f1469d6bfb 1759 /* Ensure no keyword args */
va009039 0:65f1469d6bfb 1760 if ((t16 & (uint16_t)0xFF00) != 0)
va009039 0:65f1469d6bfb 1761 {
va009039 0:65f1469d6bfb 1762 PM_RAISE(retval, PM_RET_EX_SYS);
va009039 0:65f1469d6bfb 1763 break;
va009039 0:65f1469d6bfb 1764 }
va009039 0:65f1469d6bfb 1765
va009039 0:65f1469d6bfb 1766 /* Get the callable */
va009039 0:65f1469d6bfb 1767 pobj1 = STACK(t16);
va009039 0:65f1469d6bfb 1768
va009039 0:65f1469d6bfb 1769 /* Useless push to get temp-roots stack level used in cleanup */
va009039 0:65f1469d6bfb 1770 heap_gcPushTempRoot(pobj1, &objid);
va009039 0:65f1469d6bfb 1771
va009039 0:65f1469d6bfb 1772 C_DEBUG_PRINT(VERBOSITY_LOW,
va009039 0:65f1469d6bfb 1773 "interpret(), CALL_FUNCTION on <obj type=%d @ %p>\n",
va009039 0:65f1469d6bfb 1774 OBJ_GET_TYPE(pobj1), pobj1);
va009039 0:65f1469d6bfb 1775
va009039 0:65f1469d6bfb 1776 #ifdef HAVE_GENERATORS
va009039 0:65f1469d6bfb 1777 /* If the callable is a generator function (can't be native) */
va009039 0:65f1469d6bfb 1778 if ((OBJ_GET_TYPE(pobj1) == OBJ_TYPE_FXN)
va009039 0:65f1469d6bfb 1779 && (OBJ_GET_TYPE(((pPmFunc_t)pobj1)->f_co) == OBJ_TYPE_COB)
va009039 0:65f1469d6bfb 1780 && (((pPmFunc_t)pobj1)->f_co->co_flags & CO_GENERATOR))
va009039 0:65f1469d6bfb 1781 {
va009039 0:65f1469d6bfb 1782 #ifdef HAVE_DEFAULTARGS
va009039 0:65f1469d6bfb 1783 /* Num required args := argcount - num default args */
va009039 0:65f1469d6bfb 1784 t8 = ((pPmFunc_t)pobj1)->f_co->co_argcount;
va009039 0:65f1469d6bfb 1785 if (((pPmFunc_t)pobj1)->f_defaultargs != C_NULL)
va009039 0:65f1469d6bfb 1786 {
va009039 0:65f1469d6bfb 1787 t8 -= ((pPmTuple_t)((pPmFunc_t)pobj1)->f_defaultargs)->
va009039 0:65f1469d6bfb 1788 length;
va009039 0:65f1469d6bfb 1789 }
va009039 0:65f1469d6bfb 1790
va009039 0:65f1469d6bfb 1791 /*
va009039 0:65f1469d6bfb 1792 * Raise a TypeError if num args passed
va009039 0:65f1469d6bfb 1793 * is more than allowed or less than required
va009039 0:65f1469d6bfb 1794 */
va009039 0:65f1469d6bfb 1795 if (((t16 & ((uint8_t)0xFF))
va009039 0:65f1469d6bfb 1796 > ((pPmFunc_t)pobj1)->f_co->co_argcount)
va009039 0:65f1469d6bfb 1797 || ((t16 & ((uint8_t)0xFF)) < t8))
va009039 0:65f1469d6bfb 1798 #else
va009039 0:65f1469d6bfb 1799 if ((t16 & ((uint8_t)0xFF)) !=
va009039 0:65f1469d6bfb 1800 ((pPmFunc_t)pobj1)->f_co->co_argcount)
va009039 0:65f1469d6bfb 1801 #endif /* HAVE_DEFAULTARGS */
va009039 0:65f1469d6bfb 1802 {
va009039 0:65f1469d6bfb 1803 PM_RAISE(retval, PM_RET_EX_TYPE);
va009039 0:65f1469d6bfb 1804 break;
va009039 0:65f1469d6bfb 1805 }
va009039 0:65f1469d6bfb 1806
va009039 0:65f1469d6bfb 1807 /* Collect the function and arguments into a tuple */
va009039 0:65f1469d6bfb 1808 retval = tuple_new(t16 + 1, &pobj2);
va009039 0:65f1469d6bfb 1809 heap_gcPushTempRoot(pobj2, &objid2);
va009039 0:65f1469d6bfb 1810 PM_GOTO_IF_ERROR(retval, CALL_FUNC_CLEANUP);
va009039 0:65f1469d6bfb 1811 sli_memcpy((uint8_t *)&((pPmTuple_t)pobj2)->val,
va009039 0:65f1469d6bfb 1812 (uint8_t *)&STACK(t16),
va009039 0:65f1469d6bfb 1813 (t16 + 1) * sizeof(pPmObj_t));
va009039 0:65f1469d6bfb 1814
va009039 0:65f1469d6bfb 1815 /* Remove old args, push func/args tuple as one arg */
va009039 0:65f1469d6bfb 1816 PM_SP -= t16;
va009039 0:65f1469d6bfb 1817 PM_PUSH(pobj2);
va009039 0:65f1469d6bfb 1818 t16 = 1;
va009039 0:65f1469d6bfb 1819
va009039 0:65f1469d6bfb 1820 /* Set pobj1 and stack to create an instance of Generator */
va009039 0:65f1469d6bfb 1821 retval = dict_getItem(PM_PBUILTINS, PM_GENERATOR_STR,
va009039 0:65f1469d6bfb 1822 &pobj1);
va009039 0:65f1469d6bfb 1823 C_ASSERT(retval == PM_RET_OK);
va009039 0:65f1469d6bfb 1824 STACK(t16) = pobj1;
va009039 0:65f1469d6bfb 1825 }
va009039 0:65f1469d6bfb 1826 #endif /* HAVE_GENERATORS */
va009039 0:65f1469d6bfb 1827
va009039 0:65f1469d6bfb 1828 #ifdef HAVE_CLASSES
va009039 0:65f1469d6bfb 1829 /* If the callable is a class, create an instance of it */
va009039 0:65f1469d6bfb 1830 if (OBJ_GET_TYPE(pobj1) == OBJ_TYPE_CLO)
va009039 0:65f1469d6bfb 1831 {
va009039 0:65f1469d6bfb 1832 /* This marks that the original callable was a class */
va009039 0:65f1469d6bfb 1833 bc = 0;
va009039 0:65f1469d6bfb 1834
va009039 0:65f1469d6bfb 1835 /* Replace class with new instance */
va009039 0:65f1469d6bfb 1836 retval = class_instantiate(pobj1, &pobj2);
va009039 0:65f1469d6bfb 1837 heap_gcPushTempRoot(pobj2, &objid2);
va009039 0:65f1469d6bfb 1838 STACK(t16) = pobj2;
va009039 0:65f1469d6bfb 1839
va009039 0:65f1469d6bfb 1840 /* If __init__ does not exist */
va009039 0:65f1469d6bfb 1841 pobj3 = C_NULL;
va009039 0:65f1469d6bfb 1842 retval = class_getAttr(pobj1, PM_INIT_STR, &pobj3);
va009039 0:65f1469d6bfb 1843 if (retval == PM_RET_EX_KEY)
va009039 0:65f1469d6bfb 1844 {
va009039 0:65f1469d6bfb 1845 /* Raise TypeError if there are args */
va009039 0:65f1469d6bfb 1846 if (t16 > 0)
va009039 0:65f1469d6bfb 1847 {
va009039 0:65f1469d6bfb 1848 PM_RAISE(retval, PM_RET_EX_TYPE);
va009039 0:65f1469d6bfb 1849 goto CALL_FUNC_CLEANUP;
va009039 0:65f1469d6bfb 1850 }
va009039 0:65f1469d6bfb 1851
va009039 0:65f1469d6bfb 1852 /* Otherwise, continue with instance */
va009039 0:65f1469d6bfb 1853 heap_gcPopTempRoot(objid);
va009039 0:65f1469d6bfb 1854 continue;
va009039 0:65f1469d6bfb 1855 }
va009039 0:65f1469d6bfb 1856 else if (retval != PM_RET_OK)
va009039 0:65f1469d6bfb 1857 {
va009039 0:65f1469d6bfb 1858 PM_GOTO_IF_ERROR(retval, CALL_FUNC_CLEANUP);
va009039 0:65f1469d6bfb 1859 }
va009039 0:65f1469d6bfb 1860
va009039 0:65f1469d6bfb 1861 /* Slide the arguments up 1 slot in the stack */
va009039 0:65f1469d6bfb 1862 PM_SP++;
va009039 0:65f1469d6bfb 1863 for (t8 = 0; t8 < t16; t8++)
va009039 0:65f1469d6bfb 1864 {
va009039 0:65f1469d6bfb 1865 STACK(t8) = STACK(t8 + 1);
va009039 0:65f1469d6bfb 1866 }
va009039 0:65f1469d6bfb 1867
va009039 0:65f1469d6bfb 1868 /* Convert __init__ to method, insert it as the callable */
va009039 0:65f1469d6bfb 1869 retval = class_method(pobj2, pobj3, &pobj1);
va009039 0:65f1469d6bfb 1870 PM_GOTO_IF_ERROR(retval, CALL_FUNC_CLEANUP);
va009039 0:65f1469d6bfb 1871 heap_gcPushTempRoot(pobj2, &objid2);
va009039 0:65f1469d6bfb 1872 STACK(t16) = pobj1;
va009039 0:65f1469d6bfb 1873 /* Fall through to call the method */
va009039 0:65f1469d6bfb 1874 }
va009039 0:65f1469d6bfb 1875
va009039 0:65f1469d6bfb 1876 if (OBJ_GET_TYPE(pobj1) == OBJ_TYPE_MTH)
va009039 0:65f1469d6bfb 1877 {
va009039 0:65f1469d6bfb 1878 /* Set the method's func to be the callable */
va009039 0:65f1469d6bfb 1879 STACK(t16) = (pPmObj_t)((pPmMethod_t)pobj1)->m_func;
va009039 0:65f1469d6bfb 1880
va009039 0:65f1469d6bfb 1881 /* Slide the arguments up 1 slot in the stack */
va009039 0:65f1469d6bfb 1882 PM_SP++;
va009039 0:65f1469d6bfb 1883 for (t8 = 0; t8 < t16; t8++)
va009039 0:65f1469d6bfb 1884 {
va009039 0:65f1469d6bfb 1885 STACK(t8) = STACK(t8 + 1);
va009039 0:65f1469d6bfb 1886 }
va009039 0:65f1469d6bfb 1887
va009039 0:65f1469d6bfb 1888 /* Insert instance as "self" arg to the method */
va009039 0:65f1469d6bfb 1889 STACK(t16++) = (pPmObj_t)((pPmMethod_t)pobj1)->m_instance;
va009039 0:65f1469d6bfb 1890
va009039 0:65f1469d6bfb 1891 /* Refresh the callable */
va009039 0:65f1469d6bfb 1892 pobj1 = (pPmObj_t)((pPmMethod_t)pobj1)->m_func;
va009039 0:65f1469d6bfb 1893 }
va009039 0:65f1469d6bfb 1894 #endif /* HAVE_CLASSES */
va009039 0:65f1469d6bfb 1895
va009039 0:65f1469d6bfb 1896 #ifdef HAVE_GENERATORS
va009039 0:65f1469d6bfb 1897 CALL_FUNC_FOR_ITER:
va009039 0:65f1469d6bfb 1898 #endif /* HAVE_GENERATORS */
va009039 0:65f1469d6bfb 1899 /* Raise a TypeError if object is not callable */
va009039 0:65f1469d6bfb 1900 if (OBJ_GET_TYPE(pobj1) != OBJ_TYPE_FXN)
va009039 0:65f1469d6bfb 1901 {
va009039 0:65f1469d6bfb 1902 PM_RAISE(retval, PM_RET_EX_TYPE);
va009039 0:65f1469d6bfb 1903 goto CALL_FUNC_CLEANUP;
va009039 0:65f1469d6bfb 1904 }
va009039 0:65f1469d6bfb 1905
va009039 0:65f1469d6bfb 1906 /* If it is a regular func (not native) */
va009039 0:65f1469d6bfb 1907 if (OBJ_GET_TYPE(((pPmFunc_t)pobj1)->f_co) == OBJ_TYPE_COB)
va009039 0:65f1469d6bfb 1908 {
va009039 0:65f1469d6bfb 1909 /*
va009039 0:65f1469d6bfb 1910 * #132 Raise TypeError if num args does not match the
va009039 0:65f1469d6bfb 1911 * code object's expected argcount
va009039 0:65f1469d6bfb 1912 */
va009039 0:65f1469d6bfb 1913
va009039 0:65f1469d6bfb 1914 #ifdef HAVE_DEFAULTARGS
va009039 0:65f1469d6bfb 1915 /* Num required args := argcount - num default args */
va009039 0:65f1469d6bfb 1916 t8 = ((pPmFunc_t)pobj1)->f_co->co_argcount;
va009039 0:65f1469d6bfb 1917 if (((pPmFunc_t)pobj1)->f_defaultargs != C_NULL)
va009039 0:65f1469d6bfb 1918 {
va009039 0:65f1469d6bfb 1919 t8 -= ((pPmTuple_t)((pPmFunc_t)pobj1)->f_defaultargs)->
va009039 0:65f1469d6bfb 1920 length;
va009039 0:65f1469d6bfb 1921 }
va009039 0:65f1469d6bfb 1922
va009039 0:65f1469d6bfb 1923 /*
va009039 0:65f1469d6bfb 1924 * Raise a TypeError if num args passed
va009039 0:65f1469d6bfb 1925 * is more than allowed or less than required
va009039 0:65f1469d6bfb 1926 */
va009039 0:65f1469d6bfb 1927 if (((t16 & ((uint8_t)0xFF))
va009039 0:65f1469d6bfb 1928 > ((pPmFunc_t)pobj1)->f_co->co_argcount)
va009039 0:65f1469d6bfb 1929 || ((t16 & ((uint8_t)0xFF)) < t8))
va009039 0:65f1469d6bfb 1930 #else
va009039 0:65f1469d6bfb 1931 if ((t16 & ((uint8_t)0xFF)) !=
va009039 0:65f1469d6bfb 1932 ((pPmFunc_t)pobj1)->f_co->co_argcount)
va009039 0:65f1469d6bfb 1933 #endif /* HAVE_DEFAULTARGS */
va009039 0:65f1469d6bfb 1934 {
va009039 0:65f1469d6bfb 1935 PM_RAISE(retval, PM_RET_EX_TYPE);
va009039 0:65f1469d6bfb 1936 break;
va009039 0:65f1469d6bfb 1937 }
va009039 0:65f1469d6bfb 1938
va009039 0:65f1469d6bfb 1939 /* Make frame object to run the func object */
va009039 0:65f1469d6bfb 1940 retval = frame_new(pobj1, &pobj2);
va009039 0:65f1469d6bfb 1941 heap_gcPushTempRoot(pobj2, &objid2);
va009039 0:65f1469d6bfb 1942 PM_GOTO_IF_ERROR(retval, CALL_FUNC_CLEANUP);
va009039 0:65f1469d6bfb 1943
va009039 0:65f1469d6bfb 1944 #ifdef HAVE_CLASSES
va009039 0:65f1469d6bfb 1945 /*
va009039 0:65f1469d6bfb 1946 * If the original callable was a class, indicate that
va009039 0:65f1469d6bfb 1947 * the frame is running the initializer so that
va009039 0:65f1469d6bfb 1948 * its return object is checked for None and ignored.
va009039 0:65f1469d6bfb 1949 */
va009039 0:65f1469d6bfb 1950 if (bc == 0)
va009039 0:65f1469d6bfb 1951 {
va009039 0:65f1469d6bfb 1952 ((pPmFrame_t)pobj2)->fo_isInit = C_TRUE;
va009039 0:65f1469d6bfb 1953 }
va009039 0:65f1469d6bfb 1954 #endif /* HAVE_CLASSES */
va009039 0:65f1469d6bfb 1955
va009039 0:65f1469d6bfb 1956 #ifdef HAVE_DEFAULTARGS
va009039 0:65f1469d6bfb 1957 /* If this func has default arguments, put them in place */
va009039 0:65f1469d6bfb 1958 if (((pPmFunc_t)pobj1)->f_defaultargs != C_NULL)
va009039 0:65f1469d6bfb 1959 {
va009039 0:65f1469d6bfb 1960 int8_t i = 0;
va009039 0:65f1469d6bfb 1961
va009039 0:65f1469d6bfb 1962 /* Copy default args into the new frame's locals */
va009039 0:65f1469d6bfb 1963 for ( /* t8 set above */ ;
va009039 0:65f1469d6bfb 1964 t8 < ((pPmFunc_t)pobj1)->f_co->co_argcount; t8++)
va009039 0:65f1469d6bfb 1965 {
va009039 0:65f1469d6bfb 1966 ((pPmFrame_t)pobj2)->fo_locals[t8] =
va009039 0:65f1469d6bfb 1967 ((pPmTuple_t)((pPmFunc_t)pobj1)->
va009039 0:65f1469d6bfb 1968 f_defaultargs)->val[i++];
va009039 0:65f1469d6bfb 1969 }
va009039 0:65f1469d6bfb 1970 }
va009039 0:65f1469d6bfb 1971 #endif /* HAVE_DEFAULTARGS */
va009039 0:65f1469d6bfb 1972
va009039 0:65f1469d6bfb 1973 /* Pass args to new frame */
va009039 0:65f1469d6bfb 1974 while (--t16 >= 0)
va009039 0:65f1469d6bfb 1975 {
va009039 0:65f1469d6bfb 1976 /*
va009039 0:65f1469d6bfb 1977 * Pop args from stack right to left,
va009039 0:65f1469d6bfb 1978 * since args are pushed left to right,
va009039 0:65f1469d6bfb 1979 */
va009039 0:65f1469d6bfb 1980 ((pPmFrame_t)pobj2)->fo_locals[t16] = PM_POP();
va009039 0:65f1469d6bfb 1981 }
va009039 0:65f1469d6bfb 1982
va009039 0:65f1469d6bfb 1983 #ifdef HAVE_CLOSURES
va009039 0:65f1469d6bfb 1984 /* #256: Add support for closures */
va009039 0:65f1469d6bfb 1985 /* Copy arguments that become cellvars */
va009039 0:65f1469d6bfb 1986 if (((pPmFunc_t)pobj1)->f_co->co_cellvars != C_NULL)
va009039 0:65f1469d6bfb 1987 {
va009039 0:65f1469d6bfb 1988 for (t8 = 0;
va009039 0:65f1469d6bfb 1989 t8 < ((pPmFunc_t)pobj1)->f_co->co_cellvars->length;
va009039 0:65f1469d6bfb 1990 t8++)
va009039 0:65f1469d6bfb 1991 {
va009039 0:65f1469d6bfb 1992 if (((pPmInt_t)((pPmFunc_t)pobj1)->
va009039 0:65f1469d6bfb 1993 f_co->co_cellvars->val[t8])->val >= 0)
va009039 0:65f1469d6bfb 1994 {
va009039 0:65f1469d6bfb 1995 ((pPmFrame_t)pobj2)->fo_locals[
va009039 0:65f1469d6bfb 1996 ((pPmFunc_t)pobj1)->f_co->co_nlocals + t8] =
va009039 0:65f1469d6bfb 1997 ((pPmFrame_t)pobj2)->fo_locals[
va009039 0:65f1469d6bfb 1998 ((pPmInt_t)(((pPmFunc_t)pobj1)->
va009039 0:65f1469d6bfb 1999 f_co->co_cellvars->val[t8]))->val
va009039 0:65f1469d6bfb 2000 ];
va009039 0:65f1469d6bfb 2001 }
va009039 0:65f1469d6bfb 2002 }
va009039 0:65f1469d6bfb 2003 }
va009039 0:65f1469d6bfb 2004
va009039 0:65f1469d6bfb 2005 /* Fill frame's freevars with references from closure */
va009039 0:65f1469d6bfb 2006 for (t8 = 0;
va009039 0:65f1469d6bfb 2007 t8 < ((pPmFunc_t)pobj1)->f_co->co_nfreevars;
va009039 0:65f1469d6bfb 2008 t8++)
va009039 0:65f1469d6bfb 2009 {
va009039 0:65f1469d6bfb 2010 C_ASSERT(((pPmFunc_t)pobj1)->f_closure != C_NULL);
va009039 0:65f1469d6bfb 2011 ((pPmFrame_t)pobj2)->fo_locals[
va009039 0:65f1469d6bfb 2012 ((pPmFunc_t)pobj1)->f_co->co_nlocals
va009039 0:65f1469d6bfb 2013 + ((((pPmFunc_t)pobj1)->f_co->co_cellvars == C_NULL) ? 0 : ((pPmFunc_t)pobj1)->f_co->co_cellvars->length)
va009039 0:65f1469d6bfb 2014 + t8] = ((pPmFunc_t)pobj1)->f_closure->val[t8];
va009039 0:65f1469d6bfb 2015 }
va009039 0:65f1469d6bfb 2016 #endif /* HAVE_CLOSURES */
va009039 0:65f1469d6bfb 2017
va009039 0:65f1469d6bfb 2018 /* Pop func obj */
va009039 0:65f1469d6bfb 2019 pobj3 = PM_POP();
va009039 0:65f1469d6bfb 2020
va009039 0:65f1469d6bfb 2021 /* Keep ref to current frame */
va009039 0:65f1469d6bfb 2022 ((pPmFrame_t)pobj2)->fo_back = PM_FP;
va009039 0:65f1469d6bfb 2023
va009039 0:65f1469d6bfb 2024 /* Set new frame */
va009039 0:65f1469d6bfb 2025 PM_FP = (pPmFrame_t)pobj2;
va009039 0:65f1469d6bfb 2026 }
va009039 0:65f1469d6bfb 2027
va009039 0:65f1469d6bfb 2028 /* If it's native func */
va009039 0:65f1469d6bfb 2029 else if (OBJ_GET_TYPE(((pPmFunc_t)pobj1)->f_co) ==
va009039 0:65f1469d6bfb 2030 OBJ_TYPE_NOB)
va009039 0:65f1469d6bfb 2031 {
va009039 0:65f1469d6bfb 2032 /* Set number of locals (arguments) */
va009039 0:65f1469d6bfb 2033 gVmGlobal.nativeframe.nf_numlocals = (uint8_t)t16;
va009039 0:65f1469d6bfb 2034
va009039 0:65f1469d6bfb 2035 /* Pop args from stack */
va009039 0:65f1469d6bfb 2036 while (--t16 >= 0)
va009039 0:65f1469d6bfb 2037 {
va009039 0:65f1469d6bfb 2038 gVmGlobal.nativeframe.nf_locals[t16] = PM_POP();
va009039 0:65f1469d6bfb 2039 }
va009039 0:65f1469d6bfb 2040
va009039 0:65f1469d6bfb 2041 /* Set flag, so the GC knows a native session is active */
va009039 0:65f1469d6bfb 2042 gVmGlobal.nativeframe.nf_active = C_TRUE;
va009039 0:65f1469d6bfb 2043
va009039 0:65f1469d6bfb 2044 #ifdef HAVE_GC
va009039 0:65f1469d6bfb 2045 /* If the heap is low on memory, run the GC */
va009039 0:65f1469d6bfb 2046 if (heap_getAvail() < HEAP_GC_NF_THRESHOLD)
va009039 0:65f1469d6bfb 2047 {
va009039 0:65f1469d6bfb 2048 retval = heap_gcRun();
va009039 0:65f1469d6bfb 2049 PM_GOTO_IF_ERROR(retval, CALL_FUNC_CLEANUP);
va009039 0:65f1469d6bfb 2050 }
va009039 0:65f1469d6bfb 2051 #endif /* HAVE_GC */
va009039 0:65f1469d6bfb 2052
va009039 0:65f1469d6bfb 2053 /* Pop the function object */
va009039 0:65f1469d6bfb 2054 PM_SP--;
va009039 0:65f1469d6bfb 2055
va009039 0:65f1469d6bfb 2056 /* Get native function index */
va009039 0:65f1469d6bfb 2057 pobj2 = (pPmObj_t)((pPmFunc_t)pobj1)->f_co;
va009039 0:65f1469d6bfb 2058 t16 = ((pPmNo_t)pobj2)->no_funcindx;
va009039 0:65f1469d6bfb 2059
va009039 0:65f1469d6bfb 2060 /*
va009039 0:65f1469d6bfb 2061 * CALL NATIVE FXN: pass caller's frame and numargs
va009039 0:65f1469d6bfb 2062 */
va009039 0:65f1469d6bfb 2063 /* Positive index is a stdlib func */
va009039 0:65f1469d6bfb 2064 if (t16 >= 0)
va009039 0:65f1469d6bfb 2065 {
va009039 0:65f1469d6bfb 2066 retval = std_nat_fxn_table[t16] (&PM_FP);
va009039 0:65f1469d6bfb 2067 }
va009039 0:65f1469d6bfb 2068
va009039 0:65f1469d6bfb 2069 /* Negative index is a usrlib func */
va009039 0:65f1469d6bfb 2070 else
va009039 0:65f1469d6bfb 2071 {
va009039 0:65f1469d6bfb 2072 retval = usr_nat_fxn_table[-t16] (&PM_FP);
va009039 0:65f1469d6bfb 2073 }
va009039 0:65f1469d6bfb 2074
va009039 0:65f1469d6bfb 2075 /*
va009039 0:65f1469d6bfb 2076 * RETURN FROM NATIVE FXN
va009039 0:65f1469d6bfb 2077 */
va009039 0:65f1469d6bfb 2078
va009039 0:65f1469d6bfb 2079 /* Clear flag, so frame will not be marked by the GC */
va009039 0:65f1469d6bfb 2080 gVmGlobal.nativeframe.nf_active = C_FALSE;
va009039 0:65f1469d6bfb 2081
va009039 0:65f1469d6bfb 2082 #ifdef HAVE_CLASSES
va009039 0:65f1469d6bfb 2083 /* If class's __init__ called, do not push a return obj */
va009039 0:65f1469d6bfb 2084 if (bc == 0)
va009039 0:65f1469d6bfb 2085 {
va009039 0:65f1469d6bfb 2086 /* Raise TypeError if returned obj was not None */
va009039 0:65f1469d6bfb 2087 if ((retval == PM_RET_OK)
va009039 0:65f1469d6bfb 2088 && (gVmGlobal.nativeframe.nf_stack != PM_NONE))
va009039 0:65f1469d6bfb 2089 {
va009039 0:65f1469d6bfb 2090 PM_RAISE(retval, PM_RET_EX_TYPE);
va009039 0:65f1469d6bfb 2091 goto CALL_FUNC_CLEANUP;
va009039 0:65f1469d6bfb 2092 }
va009039 0:65f1469d6bfb 2093 }
va009039 0:65f1469d6bfb 2094 else
va009039 0:65f1469d6bfb 2095 #endif /* HAVE_CLASSES */
va009039 0:65f1469d6bfb 2096
va009039 0:65f1469d6bfb 2097 /* If the frame pointer was switched, do nothing to TOS */
va009039 0:65f1469d6bfb 2098 if (retval == PM_RET_FRAME_SWITCH)
va009039 0:65f1469d6bfb 2099 {
va009039 0:65f1469d6bfb 2100 retval = PM_RET_OK;
va009039 0:65f1469d6bfb 2101 }
va009039 0:65f1469d6bfb 2102
va009039 0:65f1469d6bfb 2103 /* Otherwise, return the result from the native function */
va009039 0:65f1469d6bfb 2104 else
va009039 0:65f1469d6bfb 2105 {
va009039 0:65f1469d6bfb 2106 PM_PUSH(gVmGlobal.nativeframe.nf_stack);
va009039 0:65f1469d6bfb 2107 }
va009039 0:65f1469d6bfb 2108 }
va009039 0:65f1469d6bfb 2109 CALL_FUNC_CLEANUP:
va009039 0:65f1469d6bfb 2110 heap_gcPopTempRoot(objid);
va009039 0:65f1469d6bfb 2111 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 2112 continue;
va009039 0:65f1469d6bfb 2113
va009039 0:65f1469d6bfb 2114 case MAKE_FUNCTION:
va009039 0:65f1469d6bfb 2115 /* Get num default args to fxn */
va009039 0:65f1469d6bfb 2116 t16 = GET_ARG();
va009039 0:65f1469d6bfb 2117
va009039 0:65f1469d6bfb 2118 /*
va009039 0:65f1469d6bfb 2119 * The current frame's globals become the function object's
va009039 0:65f1469d6bfb 2120 * globals. The current frame is the container object
va009039 0:65f1469d6bfb 2121 * of this new function object
va009039 0:65f1469d6bfb 2122 */
va009039 0:65f1469d6bfb 2123 retval = func_new(TOS, (pPmObj_t)PM_FP->fo_globals, &pobj2);
va009039 0:65f1469d6bfb 2124 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 2125
va009039 0:65f1469d6bfb 2126 /* Put any default args in a tuple */
va009039 0:65f1469d6bfb 2127 if (t16 > 0)
va009039 0:65f1469d6bfb 2128 {
va009039 0:65f1469d6bfb 2129
va009039 0:65f1469d6bfb 2130 #ifdef HAVE_DEFAULTARGS
va009039 0:65f1469d6bfb 2131 heap_gcPushTempRoot(pobj2, &objid);
va009039 0:65f1469d6bfb 2132 retval = tuple_new(t16, &pobj3);
va009039 0:65f1469d6bfb 2133 heap_gcPopTempRoot(objid);
va009039 0:65f1469d6bfb 2134 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 2135 PM_SP--;
va009039 0:65f1469d6bfb 2136 while (--t16 >= 0)
va009039 0:65f1469d6bfb 2137 {
va009039 0:65f1469d6bfb 2138 ((pPmTuple_t)pobj3)->val[t16] = PM_POP();
va009039 0:65f1469d6bfb 2139 }
va009039 0:65f1469d6bfb 2140
va009039 0:65f1469d6bfb 2141 /* Set func's default args */
va009039 0:65f1469d6bfb 2142 ((pPmFunc_t)pobj2)->f_defaultargs = (pPmTuple_t)pobj3;
va009039 0:65f1469d6bfb 2143 #else
va009039 0:65f1469d6bfb 2144 /* Default arguments not configured in pmfeatures.h */
va009039 0:65f1469d6bfb 2145 PM_RAISE(retval, PM_RET_EX_SYS);
va009039 0:65f1469d6bfb 2146 break;
va009039 0:65f1469d6bfb 2147 #endif /* HAVE_DEFAULTARGS */
va009039 0:65f1469d6bfb 2148
va009039 0:65f1469d6bfb 2149 }
va009039 0:65f1469d6bfb 2150 else
va009039 0:65f1469d6bfb 2151 {
va009039 0:65f1469d6bfb 2152 PM_SP--;
va009039 0:65f1469d6bfb 2153 }
va009039 0:65f1469d6bfb 2154
va009039 0:65f1469d6bfb 2155 /* Push func obj */
va009039 0:65f1469d6bfb 2156 PM_PUSH(pobj2);
va009039 0:65f1469d6bfb 2157 continue;
va009039 0:65f1469d6bfb 2158
va009039 0:65f1469d6bfb 2159 #ifdef HAVE_CLOSURES
va009039 0:65f1469d6bfb 2160 case MAKE_CLOSURE:
va009039 0:65f1469d6bfb 2161 /* Get number of default args */
va009039 0:65f1469d6bfb 2162 t16 = GET_ARG();
va009039 0:65f1469d6bfb 2163 retval = func_new(TOS, (pPmObj_t)PM_FP->fo_globals, &pobj2);
va009039 0:65f1469d6bfb 2164 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 2165
va009039 0:65f1469d6bfb 2166 /* Set closure of the new function */
va009039 0:65f1469d6bfb 2167 ((pPmFunc_t)pobj2)->f_closure = (pPmTuple_t)TOS1;
va009039 0:65f1469d6bfb 2168 PM_SP -= 2;
va009039 0:65f1469d6bfb 2169
va009039 0:65f1469d6bfb 2170 /* Collect any default arguments into tuple */
va009039 0:65f1469d6bfb 2171 if (t16 > 0)
va009039 0:65f1469d6bfb 2172 {
va009039 0:65f1469d6bfb 2173 heap_gcPushTempRoot(pobj2, &objid);
va009039 0:65f1469d6bfb 2174 retval = tuple_new(t16, &pobj3);
va009039 0:65f1469d6bfb 2175 heap_gcPopTempRoot(objid);
va009039 0:65f1469d6bfb 2176 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 2177
va009039 0:65f1469d6bfb 2178 while (--t16 >= 0)
va009039 0:65f1469d6bfb 2179 {
va009039 0:65f1469d6bfb 2180 ((pPmTuple_t)pobj3)->val[t16] = PM_POP();
va009039 0:65f1469d6bfb 2181 }
va009039 0:65f1469d6bfb 2182 ((pPmFunc_t)pobj2)->f_defaultargs = (pPmTuple_t)pobj3;
va009039 0:65f1469d6bfb 2183 }
va009039 0:65f1469d6bfb 2184
va009039 0:65f1469d6bfb 2185 /* Push new func with closure */
va009039 0:65f1469d6bfb 2186 PM_PUSH(pobj2);
va009039 0:65f1469d6bfb 2187 continue;
va009039 0:65f1469d6bfb 2188
va009039 0:65f1469d6bfb 2189 case LOAD_CLOSURE:
va009039 0:65f1469d6bfb 2190 case LOAD_DEREF:
va009039 0:65f1469d6bfb 2191 /* Loads the i'th cell of free variable storage onto TOS */
va009039 0:65f1469d6bfb 2192 t16 = GET_ARG();
va009039 0:65f1469d6bfb 2193 pobj1 = PM_FP->fo_locals[PM_FP->fo_func->f_co->co_nlocals + t16];
va009039 0:65f1469d6bfb 2194 if (pobj1 == C_NULL)
va009039 0:65f1469d6bfb 2195 {
va009039 0:65f1469d6bfb 2196 PM_RAISE(retval, PM_RET_EX_SYS);
va009039 0:65f1469d6bfb 2197 break;
va009039 0:65f1469d6bfb 2198 }
va009039 0:65f1469d6bfb 2199 PM_PUSH(pobj1);
va009039 0:65f1469d6bfb 2200 continue;
va009039 0:65f1469d6bfb 2201
va009039 0:65f1469d6bfb 2202 case STORE_DEREF:
va009039 0:65f1469d6bfb 2203 /* Stores TOS into the i'th cell of free variable storage */
va009039 0:65f1469d6bfb 2204 t16 = GET_ARG();
va009039 0:65f1469d6bfb 2205 PM_FP->fo_locals[PM_FP->fo_func->f_co->co_nlocals + t16] = PM_POP();
va009039 0:65f1469d6bfb 2206 continue;
va009039 0:65f1469d6bfb 2207 #endif /* HAVE_CLOSURES */
va009039 0:65f1469d6bfb 2208
va009039 0:65f1469d6bfb 2209
va009039 0:65f1469d6bfb 2210 default:
va009039 1:28afb064a41c 2211 #ifdef HAVE_PYTHON27
va009039 1:28afb064a41c 2212 printf("SystemError unimplemented opcode %02x\n", bc);
va009039 1:28afb064a41c 2213 C_ASSERT(0);
va009039 1:28afb064a41c 2214 #endif
va009039 0:65f1469d6bfb 2215 /* SystemError, unknown or unimplemented opcode */
va009039 0:65f1469d6bfb 2216 PM_RAISE(retval, PM_RET_EX_SYS);
va009039 0:65f1469d6bfb 2217 break;
va009039 0:65f1469d6bfb 2218 }
va009039 0:65f1469d6bfb 2219
va009039 0:65f1469d6bfb 2220 #ifdef HAVE_GENERATORS
va009039 0:65f1469d6bfb 2221 /* If got a StopIteration exception, check for a B_LOOP block */
va009039 0:65f1469d6bfb 2222 if (retval == PM_RET_EX_STOP)
va009039 0:65f1469d6bfb 2223 {
va009039 0:65f1469d6bfb 2224 pobj1 = (pPmObj_t)PM_FP;
va009039 0:65f1469d6bfb 2225 while ((retval == PM_RET_EX_STOP) && (pobj1 != C_NULL))
va009039 0:65f1469d6bfb 2226 {
va009039 0:65f1469d6bfb 2227 pobj2 = (pPmObj_t)((pPmFrame_t)pobj1)->fo_blockstack;
va009039 0:65f1469d6bfb 2228 while ((retval == PM_RET_EX_STOP) && (pobj2 != C_NULL))
va009039 0:65f1469d6bfb 2229 {
va009039 0:65f1469d6bfb 2230 if (((pPmBlock_t)pobj2)->b_type == B_LOOP)
va009039 0:65f1469d6bfb 2231 {
va009039 0:65f1469d6bfb 2232 /* Resume execution where the block handler says */
va009039 0:65f1469d6bfb 2233 /* Set PM_FP first, so PM_SP and PM_IP are set in the frame */
va009039 0:65f1469d6bfb 2234 PM_FP = (pPmFrame_t)pobj1;
va009039 0:65f1469d6bfb 2235 PM_SP = ((pPmBlock_t)pobj2)->b_sp;
va009039 0:65f1469d6bfb 2236 PM_IP = ((pPmBlock_t)pobj2)->b_handler;
va009039 0:65f1469d6bfb 2237 ((pPmFrame_t)pobj1)->fo_blockstack =
va009039 0:65f1469d6bfb 2238 ((pPmFrame_t)pobj1)->fo_blockstack->next;
va009039 0:65f1469d6bfb 2239 retval = PM_RET_OK;
va009039 0:65f1469d6bfb 2240 break;
va009039 0:65f1469d6bfb 2241 }
va009039 0:65f1469d6bfb 2242
va009039 0:65f1469d6bfb 2243 pobj2 = (pPmObj_t)((pPmBlock_t)pobj2)->next;
va009039 0:65f1469d6bfb 2244 }
va009039 0:65f1469d6bfb 2245 pobj1 = (pPmObj_t)((pPmFrame_t)pobj1)->fo_back;
va009039 0:65f1469d6bfb 2246 }
va009039 0:65f1469d6bfb 2247 if (retval == PM_RET_OK)
va009039 0:65f1469d6bfb 2248 {
va009039 0:65f1469d6bfb 2249 continue;
va009039 0:65f1469d6bfb 2250 }
va009039 0:65f1469d6bfb 2251 }
va009039 0:65f1469d6bfb 2252 #endif /* HAVE_GENERATORS */
va009039 0:65f1469d6bfb 2253
va009039 0:65f1469d6bfb 2254 /*
va009039 0:65f1469d6bfb 2255 * If execution reaches this point, it is because
va009039 0:65f1469d6bfb 2256 * a return value (from above) is not OK or we should exit the thread
va009039 0:65f1469d6bfb 2257 * (return of the function). In any case, remove the
va009039 0:65f1469d6bfb 2258 * current thread and reschedule.
va009039 0:65f1469d6bfb 2259 */
va009039 0:65f1469d6bfb 2260 PM_REPORT_IF_ERROR(retval);
va009039 0:65f1469d6bfb 2261
va009039 0:65f1469d6bfb 2262 /* If this is the last thread, return the error code */
va009039 0:65f1469d6bfb 2263 if ((gVmGlobal.threadList->length <= 1) && (retval != PM_RET_OK))
va009039 0:65f1469d6bfb 2264 {
va009039 0:65f1469d6bfb 2265 break;
va009039 0:65f1469d6bfb 2266 }
va009039 0:65f1469d6bfb 2267
va009039 0:65f1469d6bfb 2268 retval = list_remove((pPmObj_t)gVmGlobal.threadList,
va009039 0:65f1469d6bfb 2269 (pPmObj_t)gVmGlobal.pthread);
va009039 0:65f1469d6bfb 2270 gVmGlobal.pthread = C_NULL;
va009039 0:65f1469d6bfb 2271 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 2272
va009039 0:65f1469d6bfb 2273 retval = interp_reschedule();
va009039 0:65f1469d6bfb 2274 PM_BREAK_IF_ERROR(retval);
va009039 0:65f1469d6bfb 2275 }
va009039 0:65f1469d6bfb 2276
va009039 0:65f1469d6bfb 2277 return retval;
va009039 0:65f1469d6bfb 2278 }
va009039 0:65f1469d6bfb 2279
va009039 0:65f1469d6bfb 2280
va009039 0:65f1469d6bfb 2281 PmReturn_t
va009039 0:65f1469d6bfb 2282 interp_reschedule(void)
va009039 0:65f1469d6bfb 2283 {
va009039 0:65f1469d6bfb 2284 PmReturn_t retval = PM_RET_OK;
va009039 0:65f1469d6bfb 2285 static uint8_t threadIndex = (uint8_t)0;
va009039 0:65f1469d6bfb 2286 pPmObj_t pobj;
va009039 0:65f1469d6bfb 2287
va009039 0:65f1469d6bfb 2288 /* If there are no threads in the runnable list, null the active thread */
va009039 0:65f1469d6bfb 2289 if (gVmGlobal.threadList->length == 0)
va009039 0:65f1469d6bfb 2290 {
va009039 0:65f1469d6bfb 2291 gVmGlobal.pthread = C_NULL;
va009039 0:65f1469d6bfb 2292 }
va009039 0:65f1469d6bfb 2293
va009039 0:65f1469d6bfb 2294 /* Otherwise, get the next thread in the list (round robin) */
va009039 0:65f1469d6bfb 2295 else
va009039 0:65f1469d6bfb 2296 {
va009039 0:65f1469d6bfb 2297 if (++threadIndex >= gVmGlobal.threadList->length)
va009039 0:65f1469d6bfb 2298 {
va009039 0:65f1469d6bfb 2299 threadIndex = (uint8_t)0;
va009039 0:65f1469d6bfb 2300 }
va009039 0:65f1469d6bfb 2301 retval = list_getItem((pPmObj_t)gVmGlobal.threadList, threadIndex,
va009039 0:65f1469d6bfb 2302 &pobj);
va009039 0:65f1469d6bfb 2303 gVmGlobal.pthread = (pPmThread_t)pobj;
va009039 0:65f1469d6bfb 2304 PM_RETURN_IF_ERROR(retval);
va009039 0:65f1469d6bfb 2305 }
va009039 0:65f1469d6bfb 2306
va009039 0:65f1469d6bfb 2307 /* Clear flag to indicate a reschedule has occurred */
va009039 0:65f1469d6bfb 2308 interp_setRescheduleFlag(0);
va009039 0:65f1469d6bfb 2309 return retval;
va009039 0:65f1469d6bfb 2310 }
va009039 0:65f1469d6bfb 2311
va009039 0:65f1469d6bfb 2312
va009039 0:65f1469d6bfb 2313 PmReturn_t
va009039 0:65f1469d6bfb 2314 interp_addThread(pPmFunc_t pfunc)
va009039 0:65f1469d6bfb 2315 {
va009039 0:65f1469d6bfb 2316 PmReturn_t retval;
va009039 0:65f1469d6bfb 2317 pPmObj_t pframe;
va009039 0:65f1469d6bfb 2318 pPmObj_t pthread;
va009039 0:65f1469d6bfb 2319 uint8_t objid1, objid2;
va009039 0:65f1469d6bfb 2320
va009039 0:65f1469d6bfb 2321 /* Create a frame for the func */
va009039 0:65f1469d6bfb 2322 retval = frame_new((pPmObj_t)pfunc, &pframe);
va009039 0:65f1469d6bfb 2323 PM_RETURN_IF_ERROR(retval);
va009039 0:65f1469d6bfb 2324
va009039 0:65f1469d6bfb 2325 /* Create a thread with this new frame */
va009039 0:65f1469d6bfb 2326 heap_gcPushTempRoot(pframe, &objid1);
va009039 0:65f1469d6bfb 2327 retval = thread_new(pframe, &pthread);
va009039 0:65f1469d6bfb 2328 if (retval != PM_RET_OK)
va009039 0:65f1469d6bfb 2329 {
va009039 0:65f1469d6bfb 2330 heap_gcPopTempRoot(objid1);
va009039 0:65f1469d6bfb 2331 return retval;
va009039 0:65f1469d6bfb 2332 }
va009039 0:65f1469d6bfb 2333
va009039 0:65f1469d6bfb 2334 /* Add thread to end of list */
va009039 0:65f1469d6bfb 2335 heap_gcPushTempRoot(pthread, &objid2);
va009039 0:65f1469d6bfb 2336 retval = list_append((pPmObj_t)gVmGlobal.threadList, pthread);
va009039 0:65f1469d6bfb 2337 heap_gcPopTempRoot(objid1);
va009039 0:65f1469d6bfb 2338 return retval;
va009039 0:65f1469d6bfb 2339 }
va009039 0:65f1469d6bfb 2340
va009039 0:65f1469d6bfb 2341
va009039 0:65f1469d6bfb 2342 void
va009039 0:65f1469d6bfb 2343 interp_setRescheduleFlag(uint8_t boolean)
va009039 0:65f1469d6bfb 2344 {
va009039 0:65f1469d6bfb 2345 gVmGlobal.reschedule = boolean;
va009039 0:65f1469d6bfb 2346 }