Mercurial > cpython-lru_cache-weakref
annotate Python/ceval.c @ 119:9fee1ca6c8fe legacy-trunk
File name shortening.
| author | Guido van Rossum <guido@python.org> |
|---|---|
| date | Mon, 21 Jan 1991 15:12:35 +0000 |
| parents | 16e8c5d16493 |
| children | 853b736a6a9e |
| rev | line source |
|---|---|
| 86 | 1 /* Execute compiled code */ |
| 69 | 2 |
| 86 | 3 #include "allobjects.h" |
| 4 | |
| 69 | 5 #include "import.h" |
| 6 #include "sysmodule.h" | |
| 7 #include "compile.h" | |
| 86 | 8 #include "frameobject.h" |
| 9 #include "ceval.h" | |
| 69 | 10 #include "opcode.h" |
| 119 | 11 #include "bltinmodule.h" |
| 86 | 12 #include "traceback.h" |
| 69 | 13 |
| 86 | 14 #ifndef NDEBUG |
| 15 #define TRACE | |
| 69 | 16 #endif |
| 17 | |
| 86 | 18 #ifdef TRACE |
| 19 static int | |
| 20 prtrace(v, str) | |
| 21 object *v; | |
| 22 char *str; | |
| 69 | 23 { |
| 86 | 24 printf("%s ", str); |
| 25 printobject(v, stdout, 0); | |
| 26 printf("\n"); | |
| 69 | 27 } |
| 86 | 28 #endif |
| 69 | 29 |
| 86 | 30 static frameobject *current_frame; |
| 69 | 31 |
| 86 | 32 object * |
| 33 getlocals() | |
| 69 | 34 { |
| 86 | 35 if (current_frame == NULL) |
| 69 | 36 return NULL; |
| 86 | 37 else |
| 38 return current_frame->f_locals; | |
| 69 | 39 } |
| 40 | |
| 86 | 41 object * |
| 42 getglobals() | |
| 69 | 43 { |
| 86 | 44 if (current_frame == NULL) |
| 45 return NULL; | |
| 46 else | |
| 47 return current_frame->f_globals; | |
| 69 | 48 } |
| 49 | |
| 86 | 50 void |
| 51 printtraceback(fp) | |
| 52 FILE *fp; | |
| 69 | 53 { |
| 86 | 54 object *v = tb_fetch(); |
| 55 if (v != NULL) { | |
| 56 fprintf(fp, "Stack backtrace (innermost last):\n"); | |
| 57 tb_print(v, fp); | |
| 58 DECREF(v); | |
| 69 | 59 } |
| 60 } | |
| 61 | |
| 62 | |
| 63 /* XXX Mixing "print ...," and direct file I/O on stdin/stdout | |
| 64 XXX has some bad consequences. The needspace flag should | |
| 65 XXX really be part of the file object. */ | |
| 66 | |
| 67 static int needspace; | |
| 68 | |
| 69 void | |
| 70 flushline() | |
| 71 { | |
| 72 FILE *fp = sysgetfile("stdout", stdout); | |
| 73 if (needspace) { | |
| 74 fprintf(fp, "\n"); | |
| 75 needspace = 0; | |
| 76 } | |
| 77 } | |
| 78 | |
| 86 | 79 |
| 80 /* Test a value used as condition, e.g., in a for or if statement */ | |
| 81 | |
| 82 static int | |
| 83 testbool(v) | |
| 69 | 84 object *v; |
| 85 { | |
| 86 | 86 if (is_intobject(v)) |
| 87 return getintvalue(v) != 0; | |
| 88 if (is_floatobject(v)) | |
| 89 return getfloatvalue(v) != 0.0; | |
| 90 if (v->ob_type->tp_as_sequence != NULL) | |
| 91 return (*v->ob_type->tp_as_sequence->sq_length)(v) != 0; | |
| 92 if (v->ob_type->tp_as_mapping != NULL) | |
| 93 return (*v->ob_type->tp_as_mapping->mp_length)(v) != 0; | |
| 94 if (v == None) | |
| 95 return 0; | |
| 96 /* All other objects are 'true' */ | |
| 97 return 1; | |
| 69 | 98 } |
| 99 | |
| 100 static object * | |
| 86 | 101 add(v, w) |
| 69 | 102 object *v, *w; |
| 103 { | |
| 104 if (v->ob_type->tp_as_number != NULL) | |
| 105 v = (*v->ob_type->tp_as_number->nb_add)(v, w); | |
| 106 else if (v->ob_type->tp_as_sequence != NULL) | |
| 107 v = (*v->ob_type->tp_as_sequence->sq_concat)(v, w); | |
| 108 else { | |
| 86 | 109 err_setstr(TypeError, "+ not supported by operands"); |
| 69 | 110 return NULL; |
| 111 } | |
| 86 | 112 return v; |
| 69 | 113 } |
| 114 | |
| 115 static object * | |
| 86 | 116 sub(v, w) |
| 69 | 117 object *v, *w; |
| 118 { | |
| 119 if (v->ob_type->tp_as_number != NULL) | |
| 86 | 120 return (*v->ob_type->tp_as_number->nb_subtract)(v, w); |
| 121 err_setstr(TypeError, "bad operand type(s) for -"); | |
| 69 | 122 return NULL; |
| 123 } | |
| 124 | |
| 125 static object * | |
| 86 | 126 mul(v, w) |
| 69 | 127 object *v, *w; |
| 128 { | |
| 129 typeobject *tp; | |
| 130 if (is_intobject(v) && w->ob_type->tp_as_sequence != NULL) { | |
| 131 /* int*sequence -- swap v and w */ | |
| 132 object *tmp = v; | |
| 133 v = w; | |
| 134 w = tmp; | |
| 135 } | |
| 136 tp = v->ob_type; | |
| 137 if (tp->tp_as_number != NULL) | |
| 86 | 138 return (*tp->tp_as_number->nb_multiply)(v, w); |
| 69 | 139 if (tp->tp_as_sequence != NULL) { |
| 140 if (!is_intobject(w)) { | |
| 86 | 141 err_setstr(TypeError, |
| 142 "can't multiply sequence with non-int"); | |
| 69 | 143 return NULL; |
| 144 } | |
| 145 if (tp->tp_as_sequence->sq_repeat == NULL) { | |
| 86 | 146 err_setstr(TypeError, "sequence does not support *"); |
| 69 | 147 return NULL; |
| 148 } | |
| 86 | 149 return (*tp->tp_as_sequence->sq_repeat) |
| 150 (v, (int)getintvalue(w)); | |
| 69 | 151 } |
| 86 | 152 err_setstr(TypeError, "bad operand type(s) for *"); |
| 69 | 153 return NULL; |
| 154 } | |
| 155 | |
| 156 static object * | |
|
88
16e8c5d16493
Change div() into divide(); div() is a Standard C function.
Guido van Rossum <guido@python.org>
parents:
86
diff
changeset
|
157 divide(v, w) |
| 69 | 158 object *v, *w; |
| 159 { | |
| 160 if (v->ob_type->tp_as_number != NULL) | |
| 86 | 161 return (*v->ob_type->tp_as_number->nb_divide)(v, w); |
| 162 err_setstr(TypeError, "bad operand type(s) for /"); | |
| 69 | 163 return NULL; |
| 164 } | |
| 165 | |
| 166 static object * | |
| 86 | 167 rem(v, w) |
| 168 object *v, *w; | |
| 69 | 169 { |
| 170 if (v->ob_type->tp_as_number != NULL) | |
| 86 | 171 return (*v->ob_type->tp_as_number->nb_remainder)(v, w); |
| 172 err_setstr(TypeError, "bad operand type(s) for %"); | |
| 69 | 173 return NULL; |
| 174 } | |
| 175 | |
| 176 static object * | |
| 86 | 177 neg(v) |
| 69 | 178 object *v; |
| 179 { | |
| 180 if (v->ob_type->tp_as_number != NULL) | |
| 86 | 181 return (*v->ob_type->tp_as_number->nb_negative)(v); |
| 182 err_setstr(TypeError, "bad operand type(s) for unary -"); | |
| 183 return NULL; | |
| 184 } | |
| 185 | |
| 186 static object * | |
| 187 pos(v) | |
| 188 object *v; | |
| 189 { | |
| 190 if (v->ob_type->tp_as_number != NULL) | |
| 191 return (*v->ob_type->tp_as_number->nb_positive)(v); | |
| 192 err_setstr(TypeError, "bad operand type(s) for unary +"); | |
| 69 | 193 return NULL; |
| 194 } | |
| 195 | |
| 196 static object * | |
| 86 | 197 not(v) |
| 69 | 198 object *v; |
| 199 { | |
| 86 | 200 int outcome = testbool(v); |
| 201 object *w = outcome == 0 ? True : False; | |
| 202 INCREF(w); | |
| 203 return w; | |
| 69 | 204 } |
| 205 | |
| 206 static object * | |
| 86 | 207 call_builtin(func, arg) |
| 69 | 208 object *func; |
| 86 | 209 object *arg; |
| 69 | 210 { |
| 211 if (is_methodobject(func)) { | |
| 212 method meth = getmethod(func); | |
| 213 object *self = getself(func); | |
| 86 | 214 return (*meth)(self, arg); |
| 69 | 215 } |
| 216 if (is_classobject(func)) { | |
| 86 | 217 if (arg != NULL) { |
| 218 err_setstr(TypeError, | |
| 219 "classobject() allows no arguments"); | |
| 69 | 220 return NULL; |
| 221 } | |
| 86 | 222 return newclassmemberobject(func); |
| 69 | 223 } |
| 86 | 224 err_setstr(TypeError, "call of non-function"); |
| 69 | 225 return NULL; |
| 226 } | |
| 227 | |
| 228 static object * | |
| 86 | 229 call_function(func, arg) |
| 69 | 230 object *func; |
| 86 | 231 object *arg; |
| 69 | 232 { |
| 86 | 233 object *newarg = NULL; |
| 234 object *newlocals, *newglobals; | |
| 235 object *co, *v; | |
| 69 | 236 |
| 237 if (is_classmethodobject(func)) { | |
| 238 object *self = classmethodgetself(func); | |
| 239 func = classmethodgetfunc(func); | |
| 86 | 240 if (arg == NULL) { |
| 241 arg = self; | |
| 69 | 242 } |
| 243 else { | |
| 86 | 244 newarg = newtupleobject(2); |
| 245 if (newarg == NULL) | |
| 69 | 246 return NULL; |
| 247 INCREF(self); | |
| 86 | 248 INCREF(arg); |
| 249 settupleitem(newarg, 0, self); | |
| 250 settupleitem(newarg, 1, arg); | |
| 251 arg = newarg; | |
| 69 | 252 } |
| 253 } | |
| 254 else { | |
| 255 if (!is_funcobject(func)) { | |
| 86 | 256 err_setstr(TypeError, "call of non-function"); |
| 69 | 257 return NULL; |
| 258 } | |
| 259 } | |
| 260 | |
| 86 | 261 co = getfunccode(func); |
| 262 if (co == NULL) { | |
| 263 XDECREF(newarg); | |
| 69 | 264 return NULL; |
| 265 } | |
| 86 | 266 if (!is_codeobject(co)) { |
| 267 fprintf(stderr, "XXX Bad code\n"); | |
| 69 | 268 abort(); |
| 269 } | |
| 86 | 270 newlocals = newdictobject(); |
| 69 | 271 if (newlocals == NULL) { |
| 86 | 272 XDECREF(newarg); |
| 69 | 273 return NULL; |
| 274 } | |
| 275 | |
| 86 | 276 newglobals = getfuncglobals(func); |
| 277 INCREF(newglobals); | |
| 278 | |
| 279 v = eval_code((codeobject *)co, newglobals, newlocals, arg); | |
| 69 | 280 |
| 86 | 281 DECREF(newlocals); |
| 282 DECREF(newglobals); | |
| 69 | 283 |
| 86 | 284 XDECREF(newarg); |
| 69 | 285 |
| 286 return v; | |
| 287 } | |
| 288 | |
| 289 static object * | |
| 86 | 290 apply_subscript(v, w) |
| 69 | 291 object *v, *w; |
| 292 { | |
| 293 typeobject *tp = v->ob_type; | |
| 294 if (tp->tp_as_sequence == NULL && tp->tp_as_mapping == NULL) { | |
| 86 | 295 err_setstr(TypeError, "unsubscriptable object"); |
| 69 | 296 return NULL; |
| 297 } | |
| 298 if (tp->tp_as_sequence != NULL) { | |
| 299 int i; | |
| 300 if (!is_intobject(w)) { | |
| 86 | 301 err_setstr(TypeError, "sequence subscript not int"); |
| 69 | 302 return NULL; |
| 303 } | |
| 304 i = getintvalue(w); | |
| 86 | 305 return (*tp->tp_as_sequence->sq_item)(v, i); |
| 69 | 306 } |
| 86 | 307 return (*tp->tp_as_mapping->mp_subscript)(v, w); |
| 69 | 308 } |
| 309 | |
| 310 static object * | |
| 86 | 311 loop_subscript(v, w) |
| 69 | 312 object *v, *w; |
| 313 { | |
| 314 sequence_methods *sq = v->ob_type->tp_as_sequence; | |
| 315 int i, n; | |
| 316 if (sq == NULL) { | |
| 86 | 317 err_setstr(TypeError, "loop over non-sequence"); |
| 69 | 318 return NULL; |
| 319 } | |
| 320 i = getintvalue(w); | |
| 321 n = (*sq->sq_length)(v); | |
| 322 if (i >= n) | |
| 323 return NULL; /* End of loop */ | |
| 86 | 324 return (*sq->sq_item)(v, i); |
| 69 | 325 } |
| 326 | |
| 327 static int | |
| 86 | 328 slice_index(v, isize, pi) |
| 69 | 329 object *v; |
| 330 int isize; | |
| 331 int *pi; | |
| 332 { | |
| 333 if (v != NULL) { | |
| 334 if (!is_intobject(v)) { | |
| 86 | 335 err_setstr(TypeError, "slice index must be int"); |
| 336 return -1; | |
| 69 | 337 } |
| 338 *pi = getintvalue(v); | |
| 339 if (*pi < 0) | |
| 340 *pi += isize; | |
| 341 } | |
| 86 | 342 return 0; |
| 69 | 343 } |
| 344 | |
| 345 static object * | |
| 86 | 346 apply_slice(u, v, w) /* return u[v:w] */ |
| 69 | 347 object *u, *v, *w; |
| 348 { | |
| 349 typeobject *tp = u->ob_type; | |
| 350 int ilow, ihigh, isize; | |
| 351 if (tp->tp_as_sequence == NULL) { | |
| 86 | 352 err_setstr(TypeError, "only sequences can be sliced"); |
| 69 | 353 return NULL; |
| 354 } | |
| 355 ilow = 0; | |
| 356 isize = ihigh = (*tp->tp_as_sequence->sq_length)(u); | |
| 86 | 357 if (slice_index(v, isize, &ilow) != 0) |
| 69 | 358 return NULL; |
| 86 | 359 if (slice_index(w, isize, &ihigh) != 0) |
| 69 | 360 return NULL; |
| 86 | 361 return (*tp->tp_as_sequence->sq_slice)(u, ilow, ihigh); |
| 69 | 362 } |
| 86 | 363 |
| 364 static int | |
| 365 assign_subscript(w, key, v) /* w[key] = v */ | |
| 69 | 366 object *w; |
| 367 object *key; | |
| 368 object *v; | |
| 369 { | |
| 370 typeobject *tp = w->ob_type; | |
| 371 sequence_methods *sq; | |
| 372 mapping_methods *mp; | |
| 373 int (*func)(); | |
| 374 if ((sq = tp->tp_as_sequence) != NULL && | |
| 375 (func = sq->sq_ass_item) != NULL) { | |
| 376 if (!is_intobject(key)) { | |
| 86 | 377 err_setstr(TypeError, |
| 378 "sequence subscript must be integer"); | |
| 379 return -1; | |
| 69 | 380 } |
| 86 | 381 else |
| 382 return (*func)(w, (int)getintvalue(key), v); | |
| 69 | 383 } |
| 384 else if ((mp = tp->tp_as_mapping) != NULL && | |
| 385 (func = mp->mp_ass_subscript) != NULL) { | |
| 86 | 386 return (*func)(w, key, v); |
| 69 | 387 } |
| 388 else { | |
| 86 | 389 err_setstr(TypeError, |
| 390 "can't assign to this subscripted object"); | |
| 391 return -1; | |
| 69 | 392 } |
| 393 } | |
| 394 | |
| 86 | 395 static int |
| 396 assign_slice(u, v, w, x) /* u[v:w] = x */ | |
| 69 | 397 object *u, *v, *w, *x; |
| 398 { | |
| 86 | 399 sequence_methods *sq = u->ob_type->tp_as_sequence; |
| 69 | 400 int ilow, ihigh, isize; |
| 86 | 401 if (sq == NULL) { |
| 402 err_setstr(TypeError, "assign to slice of non-sequence"); | |
| 403 return -1; | |
| 404 } | |
| 405 if (sq == NULL || sq->sq_ass_slice == NULL) { | |
| 406 err_setstr(TypeError, "unassignable slice"); | |
| 407 return -1; | |
| 69 | 408 } |
| 409 ilow = 0; | |
| 86 | 410 isize = ihigh = (*sq->sq_length)(u); |
| 411 if (slice_index(v, isize, &ilow) != 0) | |
| 412 return -1; | |
| 413 if (slice_index(w, isize, &ihigh) != 0) | |
| 414 return -1; | |
| 415 return (*sq->sq_ass_slice)(u, ilow, ihigh, x); | |
| 69 | 416 } |
| 417 | |
| 418 static int | |
| 419 cmp_exception(err, v) | |
| 420 object *err, *v; | |
| 421 { | |
| 422 if (is_tupleobject(v)) { | |
| 423 int i, n; | |
| 424 n = gettuplesize(v); | |
| 425 for (i = 0; i < n; i++) { | |
| 426 if (err == gettupleitem(v, i)) | |
| 427 return 1; | |
| 428 } | |
| 429 return 0; | |
| 430 } | |
| 431 return err == v; | |
| 432 } | |
| 433 | |
| 86 | 434 static int |
| 435 cmp_member(v, w) | |
| 436 object *v, *w; | |
| 437 { | |
| 438 int i, n, cmp; | |
| 439 object *x; | |
| 440 sequence_methods *sq; | |
| 441 /* Special case for char in string */ | |
| 442 if (is_stringobject(w)) { | |
| 443 register char *s, *end; | |
| 444 register char c; | |
| 445 if (!is_stringobject(v) || getstringsize(v) != 1) { | |
| 446 err_setstr(TypeError, | |
| 447 "string member test needs char left operand"); | |
| 448 return -1; | |
| 449 } | |
| 450 c = getstringvalue(v)[0]; | |
| 451 s = getstringvalue(w); | |
| 452 end = s + getstringsize(w); | |
| 453 while (s < end) { | |
| 454 if (c == *s++) | |
| 455 return 1; | |
| 456 } | |
| 457 return 0; | |
| 458 } | |
| 459 sq = w->ob_type->tp_as_sequence; | |
| 460 if (sq == NULL) { | |
| 461 err_setstr(TypeError, | |
| 462 "'in' or 'not in' needs sequence right argument"); | |
| 463 return -1; | |
| 464 } | |
| 465 n = (*sq->sq_length)(w); | |
| 466 for (i = 0; i < n; i++) { | |
| 467 x = (*sq->sq_item)(w, i); | |
| 468 cmp = cmpobject(v, x); | |
| 469 XDECREF(x); | |
| 470 if (cmp == 0) | |
| 471 return 1; | |
| 472 } | |
| 473 return 0; | |
| 474 } | |
| 475 | |
| 69 | 476 static object * |
| 86 | 477 cmp_outcome(op, v, w) |
| 69 | 478 enum cmp_op op; |
| 479 register object *v; | |
| 480 register object *w; | |
| 481 { | |
| 482 register int cmp; | |
| 483 register int res = 0; | |
| 484 switch (op) { | |
| 86 | 485 case IS: |
| 486 case IS_NOT: | |
| 487 res = (v == w); | |
| 488 if (op == IS_NOT) | |
| 489 res = !res; | |
| 490 break; | |
| 69 | 491 case IN: |
| 492 case NOT_IN: | |
| 86 | 493 res = cmp_member(v, w); |
| 494 if (res < 0) | |
| 495 return NULL; | |
| 496 if (op == NOT_IN) | |
| 497 res = !res; | |
| 69 | 498 break; |
| 499 case EXC_MATCH: | |
| 86 | 500 res = cmp_exception(v, w); |
| 69 | 501 break; |
| 502 default: | |
| 86 | 503 cmp = cmpobject(v, w); |
| 504 switch (op) { | |
| 505 case LT: res = cmp < 0; break; | |
| 506 case LE: res = cmp <= 0; break; | |
| 507 case EQ: res = cmp == 0; break; | |
| 508 case NE: res = cmp != 0; break; | |
| 509 case GT: res = cmp > 0; break; | |
| 510 case GE: res = cmp >= 0; break; | |
| 511 /* XXX no default? (res is initialized to 0 though) */ | |
| 512 } | |
| 69 | 513 } |
| 514 v = res ? True : False; | |
| 515 INCREF(v); | |
| 516 return v; | |
| 517 } | |
| 518 | |
| 86 | 519 static int |
| 520 import_from(locals, v, name) | |
| 521 object *locals; | |
|
72
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
522 object *v; |
|
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
523 char *name; |
|
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
524 { |
|
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
525 object *w, *x; |
|
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
526 w = getmoduledict(v); |
|
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
527 if (name[0] == '*') { |
|
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
528 int i; |
|
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
529 int n = getdictsize(w); |
|
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
530 for (i = 0; i < n; i++) { |
|
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
531 name = getdictkey(w, i); |
|
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
532 if (name == NULL || name[0] == '_') |
|
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
533 continue; |
|
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
534 x = dictlookup(w, name); |
|
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
535 if (x == NULL) { |
|
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
536 /* XXX can't happen? */ |
| 86 | 537 err_setstr(NameError, name); |
| 538 return -1; | |
|
72
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
539 } |
| 86 | 540 if (dictinsert(locals, name, x) != 0) |
| 541 return -1; | |
|
72
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
542 } |
| 86 | 543 return 0; |
|
72
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
544 } |
|
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
545 else { |
|
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
546 x = dictlookup(w, name); |
| 86 | 547 if (x == NULL) { |
| 548 err_setstr(NameError, name); | |
| 549 return -1; | |
| 550 } | |
| 551 else | |
| 552 return dictinsert(locals, name, x); | |
|
72
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
553 } |
|
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
554 } |
|
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
555 |
|
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
556 static object * |
| 86 | 557 build_class(v, w) |
|
72
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
558 object *v; /* None or tuple containing base classes */ |
|
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
559 object *w; /* dictionary */ |
|
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
560 { |
|
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
561 if (is_tupleobject(v)) { |
|
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
562 int i; |
|
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
563 for (i = gettuplesize(v); --i >= 0; ) { |
|
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
564 object *x = gettupleitem(v, i); |
|
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
565 if (!is_classobject(x)) { |
| 86 | 566 err_setstr(TypeError, |
| 567 "base is not a class object"); | |
|
72
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
568 return NULL; |
|
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
569 } |
|
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
570 } |
|
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
571 } |
|
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
572 else { |
|
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
573 v = NULL; |
|
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
574 } |
|
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
575 if (!is_dictobject(w)) { |
| 86 | 576 err_setstr(SystemError, "build_class with non-dictionary"); |
|
72
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
577 return NULL; |
|
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
578 } |
| 86 | 579 return newclassobject(v, w); |
|
72
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
580 } |
|
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
581 |
| 86 | 582 |
| 583 /* Status code for main loop (reason for stack unwind) */ | |
| 584 | |
| 585 enum why_code { | |
| 586 WHY_NOT, /* No error */ | |
| 587 WHY_EXCEPTION, /* Exception occurred */ | |
| 588 WHY_RERAISE, /* Exception re-raised by 'finally' */ | |
| 589 WHY_RETURN, /* 'return' statement */ | |
| 590 WHY_BREAK /* 'break' statement */ | |
| 591 }; | |
| 592 | |
| 593 /* Interpreter main loop */ | |
| 594 | |
| 595 object * | |
| 596 eval_code(co, globals, locals, arg) | |
| 69 | 597 codeobject *co; |
| 86 | 598 object *globals; |
| 599 object *locals; | |
| 69 | 600 object *arg; |
| 601 { | |
| 86 | 602 register unsigned char *next_instr; |
| 603 register int opcode; /* Current opcode */ | |
| 604 register int oparg; /* Current opcode argument, if any */ | |
| 605 register object **stack_pointer; | |
| 606 register enum why_code why; /* Reason for block stack unwind */ | |
| 607 register int err; /* Error status -- nonzero if error */ | |
| 608 register object *x; /* Result object -- NULL if error */ | |
| 609 register object *v; /* Temporary objects popped off stack */ | |
| 69 | 610 register object *w; |
| 611 register object *u; | |
| 86 | 612 register object *t; |
| 613 register frameobject *f; /* Current frame */ | |
| 614 int lineno; /* Current line number */ | |
| 615 object *retval; /* Return value iff why == WHY_RETURN */ | |
| 616 char *name; /* Name used by some instructions */ | |
| 617 FILE *fp; /* Used by print operations */ | |
| 618 #ifdef TRACE | |
| 619 int trace = dictlookup(globals, "__trace__") != NULL; | |
| 620 #endif | |
| 621 | |
| 622 /* Code access macros */ | |
| 623 | |
| 624 #define GETCONST(i) Getconst(f, i) | |
| 625 #define GETNAME(i) Getname(f, i) | |
| 626 #define FIRST_INSTR() (GETUSTRINGVALUE(f->f_code->co_code)) | |
| 627 #define INSTR_OFFSET() (next_instr - FIRST_INSTR()) | |
| 628 #define NEXTOP() (*next_instr++) | |
| 629 #define NEXTARG() (next_instr += 2, (next_instr[-1]<<8) + next_instr[-2]) | |
| 630 #define JUMPTO(x) (next_instr = FIRST_INSTR() + (x)) | |
| 631 #define JUMPBY(x) (next_instr += (x)) | |
| 632 | |
| 633 /* Stack manipulation macros */ | |
| 634 | |
| 635 #define STACK_LEVEL() (stack_pointer - f->f_valuestack) | |
| 636 #define EMPTY() (STACK_LEVEL() == 0) | |
| 637 #define TOP() (stack_pointer[-1]) | |
| 638 #define BASIC_PUSH(v) (*stack_pointer++ = (v)) | |
| 639 #define BASIC_POP() (*--stack_pointer) | |
| 640 | |
| 641 #ifdef TRACE | |
| 642 #define PUSH(v) (BASIC_PUSH(v), trace && prtrace(TOP(), "push")) | |
| 643 #define POP() (trace && prtrace(TOP(), "pop"), BASIC_POP()) | |
| 644 #else | |
| 645 #define PUSH(v) BASIC_PUSH(v) | |
| 646 #define POP() BASIC_POP() | |
| 69 | 647 #endif |
| 648 | |
| 649 f = newframeobject( | |
| 86 | 650 current_frame, /*back*/ |
| 69 | 651 co, /*code*/ |
| 86 | 652 globals, /*globals*/ |
| 653 locals, /*locals*/ | |
| 69 | 654 50, /*nvalues*/ |
| 655 20); /*nblocks*/ | |
| 86 | 656 if (f == NULL) |
| 69 | 657 return NULL; |
| 86 | 658 |
| 659 current_frame = f; | |
| 660 | |
| 661 next_instr = GETUSTRINGVALUE(f->f_code->co_code); | |
| 662 | |
| 663 stack_pointer = f->f_valuestack; | |
| 664 | |
| 69 | 665 if (arg != NULL) { |
| 666 INCREF(arg); | |
| 667 PUSH(arg); | |
| 668 } | |
| 669 | |
| 86 | 670 why = WHY_NOT; |
| 671 err = 0; | |
| 672 x = None; /* Not a reference, just anything non-NULL */ | |
| 673 lineno = -1; | |
| 674 | |
| 675 for (;;) { | |
| 676 static ticker; | |
| 677 | |
| 678 /* Do periodic things */ | |
| 679 | |
| 680 if (--ticker < 0) { | |
| 681 ticker = 100; | |
| 682 if (intrcheck()) { | |
| 683 err_set(KeyboardInterrupt); | |
| 684 why = WHY_EXCEPTION; | |
| 685 tb_here(f, INSTR_OFFSET(), lineno); | |
| 686 break; | |
| 687 } | |
| 688 } | |
| 689 | |
| 690 /* Extract opcode and argument */ | |
| 691 | |
| 692 opcode = NEXTOP(); | |
| 693 if (HAS_ARG(opcode)) | |
| 694 oparg = NEXTARG(); | |
| 695 | |
| 696 #ifdef TRACE | |
| 697 /* Instruction tracing */ | |
| 698 | |
| 699 if (trace) { | |
| 700 if (HAS_ARG(opcode)) { | |
| 701 printf("%d: %d, %d\n", | |
| 702 (int) (INSTR_OFFSET() - 3), | |
| 703 opcode, oparg); | |
| 704 } | |
| 705 else { | |
| 706 printf("%d: %d\n", | |
| 707 (int) (INSTR_OFFSET() - 1), opcode); | |
| 708 } | |
| 709 } | |
|
72
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
710 #endif |
| 86 | 711 |
| 712 /* Main switch on opcode */ | |
| 713 | |
| 714 switch (opcode) { | |
| 69 | 715 |
| 86 | 716 /* BEWARE! |
| 717 It is essential that any operation that fails sets either | |
| 718 x to NULL, err to nonzero, or why to anything but WHY_NOT, | |
| 719 and that no operation that succeeds does this! */ | |
| 720 | |
| 721 /* case STOP_CODE: this is an error! */ | |
| 69 | 722 |
| 723 case POP_TOP: | |
| 724 v = POP(); | |
| 725 DECREF(v); | |
| 726 break; | |
| 727 | |
| 728 case ROT_TWO: | |
| 729 v = POP(); | |
| 730 w = POP(); | |
| 731 PUSH(v); | |
| 732 PUSH(w); | |
| 733 break; | |
| 734 | |
| 735 case ROT_THREE: | |
| 736 v = POP(); | |
| 737 w = POP(); | |
| 738 x = POP(); | |
| 739 PUSH(v); | |
| 740 PUSH(x); | |
| 741 PUSH(w); | |
| 742 break; | |
| 743 | |
| 86 | 744 case DUP_TOP: |
| 745 v = TOP(); | |
| 746 INCREF(v); | |
| 747 PUSH(v); | |
| 748 break; | |
| 749 | |
| 69 | 750 case UNARY_POSITIVE: |
| 751 v = POP(); | |
| 86 | 752 x = pos(v); |
| 69 | 753 DECREF(v); |
| 86 | 754 PUSH(x); |
| 69 | 755 break; |
| 756 | |
| 757 case UNARY_NEGATIVE: | |
| 758 v = POP(); | |
| 86 | 759 x = neg(v); |
| 69 | 760 DECREF(v); |
| 86 | 761 PUSH(x); |
| 69 | 762 break; |
| 763 | |
| 764 case UNARY_NOT: | |
| 765 v = POP(); | |
| 86 | 766 x = not(v); |
| 69 | 767 DECREF(v); |
| 86 | 768 PUSH(x); |
| 69 | 769 break; |
| 770 | |
| 771 case UNARY_CONVERT: | |
| 772 v = POP(); | |
| 86 | 773 x = reprobject(v); |
| 69 | 774 DECREF(v); |
| 86 | 775 PUSH(x); |
| 69 | 776 break; |
| 777 | |
| 778 case UNARY_CALL: | |
| 779 v = POP(); | |
|
72
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
780 if (is_classmethodobject(v) || is_funcobject(v)) |
| 86 | 781 x = call_function(v, (object *)NULL); |
| 69 | 782 else |
| 86 | 783 x = call_builtin(v, (object *)NULL); |
| 69 | 784 DECREF(v); |
| 86 | 785 PUSH(x); |
| 69 | 786 break; |
| 787 | |
| 788 case BINARY_MULTIPLY: | |
| 789 w = POP(); | |
| 790 v = POP(); | |
| 86 | 791 x = mul(v, w); |
| 69 | 792 DECREF(v); |
| 793 DECREF(w); | |
| 86 | 794 PUSH(x); |
| 69 | 795 break; |
| 796 | |
| 797 case BINARY_DIVIDE: | |
| 798 w = POP(); | |
| 799 v = POP(); | |
|
88
16e8c5d16493
Change div() into divide(); div() is a Standard C function.
Guido van Rossum <guido@python.org>
parents:
86
diff
changeset
|
800 x = divide(v, w); |
| 69 | 801 DECREF(v); |
| 802 DECREF(w); | |
| 86 | 803 PUSH(x); |
| 69 | 804 break; |
| 805 | |
| 806 case BINARY_MODULO: | |
| 807 w = POP(); | |
| 808 v = POP(); | |
| 86 | 809 x = rem(v, w); |
| 69 | 810 DECREF(v); |
| 811 DECREF(w); | |
| 86 | 812 PUSH(x); |
| 69 | 813 break; |
| 814 | |
| 815 case BINARY_ADD: | |
| 816 w = POP(); | |
| 817 v = POP(); | |
| 86 | 818 x = add(v, w); |
| 69 | 819 DECREF(v); |
| 820 DECREF(w); | |
| 86 | 821 PUSH(x); |
| 69 | 822 break; |
| 823 | |
| 824 case BINARY_SUBTRACT: | |
| 825 w = POP(); | |
| 826 v = POP(); | |
| 86 | 827 x = sub(v, w); |
| 69 | 828 DECREF(v); |
| 829 DECREF(w); | |
| 86 | 830 PUSH(x); |
| 69 | 831 break; |
| 832 | |
| 833 case BINARY_SUBSCR: | |
| 834 w = POP(); | |
| 835 v = POP(); | |
| 86 | 836 x = apply_subscript(v, w); |
| 69 | 837 DECREF(v); |
| 838 DECREF(w); | |
| 86 | 839 PUSH(x); |
| 69 | 840 break; |
| 841 | |
| 842 case BINARY_CALL: | |
| 843 w = POP(); | |
| 844 v = POP(); | |
|
72
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
845 if (is_classmethodobject(v) || is_funcobject(v)) |
| 86 | 846 x = call_function(v, w); |
| 69 | 847 else |
| 86 | 848 x = call_builtin(v, w); |
| 69 | 849 DECREF(v); |
| 850 DECREF(w); | |
| 86 | 851 PUSH(x); |
| 69 | 852 break; |
| 853 | |
|
72
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
854 case SLICE+0: |
| 69 | 855 case SLICE+1: |
| 856 case SLICE+2: | |
| 857 case SLICE+3: | |
| 86 | 858 if ((opcode-SLICE) & 2) |
|
72
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
859 w = POP(); |
|
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
860 else |
|
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
861 w = NULL; |
| 86 | 862 if ((opcode-SLICE) & 1) |
|
72
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
863 v = POP(); |
|
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
864 else |
|
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
865 v = NULL; |
| 69 | 866 u = POP(); |
| 86 | 867 x = apply_slice(u, v, w); |
| 69 | 868 DECREF(u); |
|
72
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
869 XDECREF(v); |
|
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
870 XDECREF(w); |
| 69 | 871 PUSH(x); |
| 872 break; | |
| 873 | |
|
72
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
874 case STORE_SLICE+0: |
| 69 | 875 case STORE_SLICE+1: |
| 876 case STORE_SLICE+2: | |
| 877 case STORE_SLICE+3: | |
| 86 | 878 if ((opcode-STORE_SLICE) & 2) |
|
72
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
879 w = POP(); |
|
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
880 else |
|
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
881 w = NULL; |
| 86 | 882 if ((opcode-STORE_SLICE) & 1) |
|
72
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
883 v = POP(); |
|
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
884 else |
|
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
885 v = NULL; |
| 69 | 886 u = POP(); |
| 86 | 887 t = POP(); |
| 888 err = assign_slice(u, v, w, t); /* u[v:w] = t */ | |
| 889 DECREF(t); | |
| 69 | 890 DECREF(u); |
|
72
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
891 XDECREF(v); |
|
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
892 XDECREF(w); |
| 69 | 893 break; |
| 894 | |
|
72
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
895 case DELETE_SLICE+0: |
| 69 | 896 case DELETE_SLICE+1: |
| 897 case DELETE_SLICE+2: | |
| 898 case DELETE_SLICE+3: | |
| 86 | 899 if ((opcode-DELETE_SLICE) & 2) |
|
72
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
900 w = POP(); |
|
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
901 else |
|
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
902 w = NULL; |
| 86 | 903 if ((opcode-DELETE_SLICE) & 1) |
|
72
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
904 v = POP(); |
|
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
905 else |
|
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
906 v = NULL; |
| 69 | 907 u = POP(); |
| 86 | 908 err = assign_slice(u, v, w, (object *)NULL); |
| 909 /* del u[v:w] */ | |
| 69 | 910 DECREF(u); |
|
72
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
911 XDECREF(v); |
|
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
912 XDECREF(w); |
| 69 | 913 break; |
| 914 | |
| 915 case STORE_SUBSCR: | |
| 916 w = POP(); | |
| 917 v = POP(); | |
| 918 u = POP(); | |
| 919 /* v[w] = u */ | |
| 86 | 920 err = assign_subscript(v, w, u); |
| 69 | 921 DECREF(u); |
| 922 DECREF(v); | |
| 923 DECREF(w); | |
| 924 break; | |
| 925 | |
| 926 case DELETE_SUBSCR: | |
| 927 w = POP(); | |
| 928 v = POP(); | |
| 929 /* del v[w] */ | |
| 86 | 930 err = assign_subscript(v, w, (object *)NULL); |
| 69 | 931 DECREF(v); |
| 932 DECREF(w); | |
| 933 break; | |
| 934 | |
| 935 case PRINT_EXPR: | |
| 936 v = POP(); | |
| 937 fp = sysgetfile("stdout", stdout); | |
| 938 /* Print value except if procedure result */ | |
| 939 if (v != None) { | |
| 940 flushline(); | |
| 941 printobject(v, fp, 0); | |
| 942 fprintf(fp, "\n"); | |
| 943 } | |
| 944 DECREF(v); | |
| 945 break; | |
| 946 | |
| 947 case PRINT_ITEM: | |
| 948 v = POP(); | |
| 949 fp = sysgetfile("stdout", stdout); | |
| 950 if (needspace) | |
| 951 fprintf(fp, " "); | |
| 952 if (is_stringobject(v)) { | |
| 953 char *s = getstringvalue(v); | |
| 954 int len = getstringsize(v); | |
| 955 fwrite(s, 1, len, fp); | |
| 956 if (len > 0 && s[len-1] == '\n') | |
| 957 needspace = 0; | |
| 958 else | |
| 959 needspace = 1; | |
| 960 } | |
| 961 else { | |
| 962 printobject(v, fp, 0); | |
| 963 needspace = 1; | |
| 964 } | |
| 965 DECREF(v); | |
| 966 break; | |
| 967 | |
| 968 case PRINT_NEWLINE: | |
| 969 fp = sysgetfile("stdout", stdout); | |
| 970 fprintf(fp, "\n"); | |
| 971 needspace = 0; | |
| 972 break; | |
| 973 | |
| 974 case BREAK_LOOP: | |
| 86 | 975 why = WHY_BREAK; |
| 69 | 976 break; |
| 977 | |
| 978 case RAISE_EXCEPTION: | |
| 979 v = POP(); | |
| 980 w = POP(); | |
| 86 | 981 if (!is_stringobject(w)) |
| 982 err_setstr(TypeError, | |
| 983 "exceptions must be strings"); | |
| 984 else | |
| 985 err_setval(w, v); | |
| 986 DECREF(v); | |
| 987 DECREF(w); | |
| 988 why = WHY_EXCEPTION; | |
| 69 | 989 break; |
| 990 | |
|
72
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
991 case LOAD_LOCALS: |
| 86 | 992 v = f->f_locals; |
|
72
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
993 INCREF(v); |
|
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
994 PUSH(v); |
|
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
995 break; |
|
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
996 |
| 69 | 997 case RETURN_VALUE: |
| 86 | 998 retval = POP(); |
| 999 why = WHY_RETURN; | |
| 69 | 1000 break; |
| 1001 | |
| 1002 case REQUIRE_ARGS: | |
| 86 | 1003 if (EMPTY()) { |
| 1004 err_setstr(TypeError, | |
| 69 | 1005 "function expects argument(s)"); |
| 86 | 1006 why = WHY_EXCEPTION; |
| 1007 } | |
| 69 | 1008 break; |
| 1009 | |
| 1010 case REFUSE_ARGS: | |
| 86 | 1011 if (!EMPTY()) { |
| 1012 err_setstr(TypeError, | |
| 69 | 1013 "function expects no argument(s)"); |
| 86 | 1014 why = WHY_EXCEPTION; |
| 1015 } | |
| 69 | 1016 break; |
| 1017 | |
| 1018 case BUILD_FUNCTION: | |
| 1019 v = POP(); | |
| 86 | 1020 x = newfuncobject(v, f->f_globals); |
| 69 | 1021 DECREF(v); |
| 1022 PUSH(x); | |
| 1023 break; | |
| 1024 | |
| 1025 case POP_BLOCK: | |
| 86 | 1026 { |
| 1027 block *b = pop_block(f); | |
| 1028 while (STACK_LEVEL() > b->b_level) { | |
| 1029 v = POP(); | |
| 1030 DECREF(v); | |
| 1031 } | |
| 1032 } | |
| 69 | 1033 break; |
| 1034 | |
| 1035 case END_FINALLY: | |
| 1036 v = POP(); | |
| 1037 if (is_intobject(v)) { | |
| 86 | 1038 why = (enum why_code) getintvalue(v); |
| 1039 if (why == WHY_RETURN) | |
| 1040 retval = POP(); | |
| 69 | 1041 } |
| 86 | 1042 else if (is_stringobject(v)) { |
| 1043 w = POP(); | |
| 1044 err_setval(v, w); | |
| 1045 DECREF(w); | |
| 1046 w = POP(); | |
| 1047 tb_store(w); | |
| 69 | 1048 DECREF(w); |
| 86 | 1049 why = WHY_RERAISE; |
| 69 | 1050 } |
| 86 | 1051 else if (v != None) { |
| 1052 err_setstr(SystemError, | |
| 1053 "'finally' pops bad exception"); | |
| 1054 why = WHY_EXCEPTION; | |
| 69 | 1055 } |
| 86 | 1056 DECREF(v); |
| 69 | 1057 break; |
| 1058 | |
|
72
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
1059 case BUILD_CLASS: |
|
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
1060 w = POP(); |
|
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
1061 v = POP(); |
| 86 | 1062 x = build_class(v, w); |
|
72
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
1063 PUSH(x); |
|
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
1064 DECREF(v); |
|
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
1065 DECREF(w); |
|
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
1066 break; |
|
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
1067 |
| 69 | 1068 case STORE_NAME: |
| 86 | 1069 name = GETNAME(oparg); |
| 69 | 1070 v = POP(); |
| 86 | 1071 err = dictinsert(f->f_locals, name, v); |
| 69 | 1072 DECREF(v); |
| 1073 break; | |
| 1074 | |
| 1075 case DELETE_NAME: | |
| 86 | 1076 name = GETNAME(oparg); |
| 1077 if ((err = dictremove(f->f_locals, name)) != 0) | |
| 1078 err_setstr(NameError, name); | |
| 69 | 1079 break; |
| 1080 | |
| 1081 case UNPACK_TUPLE: | |
| 1082 v = POP(); | |
| 1083 if (!is_tupleobject(v)) { | |
| 86 | 1084 err_setstr(TypeError, "unpack non-tuple"); |
| 1085 why = WHY_EXCEPTION; | |
| 69 | 1086 } |
| 86 | 1087 else if (gettuplesize(v) != oparg) { |
| 1088 err_setstr(RuntimeError, | |
| 1089 "unpack tuple of wrong size"); | |
| 1090 why = WHY_EXCEPTION; | |
| 69 | 1091 } |
| 1092 else { | |
| 86 | 1093 for (; --oparg >= 0; ) { |
| 1094 w = gettupleitem(v, oparg); | |
| 69 | 1095 INCREF(w); |
| 1096 PUSH(w); | |
| 1097 } | |
| 1098 } | |
| 1099 DECREF(v); | |
| 1100 break; | |
| 1101 | |
| 1102 case UNPACK_LIST: | |
| 1103 v = POP(); | |
| 1104 if (!is_listobject(v)) { | |
| 86 | 1105 err_setstr(TypeError, "unpack non-list"); |
| 1106 why = WHY_EXCEPTION; | |
| 69 | 1107 } |
| 86 | 1108 else if (getlistsize(v) != oparg) { |
| 1109 err_setstr(RuntimeError, | |
| 1110 "unpack list of wrong size"); | |
| 1111 why = WHY_EXCEPTION; | |
| 69 | 1112 } |
| 1113 else { | |
| 86 | 1114 for (; --oparg >= 0; ) { |
| 1115 w = getlistitem(v, oparg); | |
| 69 | 1116 INCREF(w); |
| 1117 PUSH(w); | |
| 1118 } | |
| 1119 } | |
| 1120 DECREF(v); | |
| 1121 break; | |
| 1122 | |
| 1123 case STORE_ATTR: | |
| 86 | 1124 name = GETNAME(oparg); |
| 69 | 1125 v = POP(); |
| 1126 u = POP(); | |
| 86 | 1127 err = setattr(v, name, u); /* v.name = u */ |
| 69 | 1128 DECREF(v); |
| 1129 DECREF(u); | |
| 1130 break; | |
| 1131 | |
| 1132 case DELETE_ATTR: | |
| 86 | 1133 name = GETNAME(oparg); |
| 69 | 1134 v = POP(); |
| 86 | 1135 err = setattr(v, name, (object *)NULL); |
| 1136 /* del v.name */ | |
| 69 | 1137 DECREF(v); |
| 1138 break; | |
| 1139 | |
| 1140 case LOAD_CONST: | |
| 86 | 1141 x = GETCONST(oparg); |
| 1142 INCREF(x); | |
| 1143 PUSH(x); | |
| 69 | 1144 break; |
| 1145 | |
| 1146 case LOAD_NAME: | |
| 86 | 1147 name = GETNAME(oparg); |
| 1148 x = dictlookup(f->f_locals, name); | |
| 1149 if (x == NULL) { | |
| 1150 x = dictlookup(f->f_globals, name); | |
| 1151 if (x == NULL) | |
| 1152 x = getbuiltin(name); | |
| 69 | 1153 } |
| 86 | 1154 if (x == NULL) |
| 1155 err_setstr(NameError, name); | |
| 69 | 1156 else |
| 86 | 1157 INCREF(x); |
| 1158 PUSH(x); | |
| 69 | 1159 break; |
| 1160 | |
| 1161 case BUILD_TUPLE: | |
| 86 | 1162 x = newtupleobject(oparg); |
| 1163 if (x != NULL) { | |
| 1164 for (; --oparg >= 0;) { | |
| 69 | 1165 w = POP(); |
| 86 | 1166 err = settupleitem(x, oparg, w); |
| 1167 if (err != 0) | |
| 1168 break; | |
| 69 | 1169 } |
| 86 | 1170 PUSH(x); |
| 69 | 1171 } |
| 1172 break; | |
| 1173 | |
| 1174 case BUILD_LIST: | |
| 86 | 1175 x = newlistobject(oparg); |
| 1176 if (x != NULL) { | |
| 1177 for (; --oparg >= 0;) { | |
| 69 | 1178 w = POP(); |
| 86 | 1179 err = setlistitem(x, oparg, w); |
| 1180 if (err != 0) | |
| 1181 break; | |
| 69 | 1182 } |
| 86 | 1183 PUSH(x); |
| 69 | 1184 } |
| 1185 break; | |
| 1186 | |
| 1187 case BUILD_MAP: | |
| 86 | 1188 x = newdictobject(); |
| 1189 PUSH(x); | |
| 69 | 1190 break; |
| 1191 | |
| 1192 case LOAD_ATTR: | |
| 86 | 1193 name = GETNAME(oparg); |
| 69 | 1194 v = POP(); |
| 86 | 1195 x = getattr(v, name); |
| 69 | 1196 DECREF(v); |
| 86 | 1197 PUSH(x); |
| 69 | 1198 break; |
| 1199 | |
| 1200 case COMPARE_OP: | |
| 1201 w = POP(); | |
| 1202 v = POP(); | |
| 86 | 1203 x = cmp_outcome((enum cmp_op)oparg, v, w); |
| 69 | 1204 DECREF(v); |
| 1205 DECREF(w); | |
| 86 | 1206 PUSH(x); |
| 69 | 1207 break; |
| 1208 | |
| 1209 case IMPORT_NAME: | |
| 86 | 1210 name = GETNAME(oparg); |
| 1211 x = import_module(name); | |
| 1212 XINCREF(x); | |
| 1213 PUSH(x); | |
| 69 | 1214 break; |
| 1215 | |
| 1216 case IMPORT_FROM: | |
| 86 | 1217 name = GETNAME(oparg); |
| 69 | 1218 v = TOP(); |
| 86 | 1219 err = import_from(f->f_locals, v, name); |
| 69 | 1220 break; |
| 1221 | |
| 1222 case JUMP_FORWARD: | |
| 86 | 1223 JUMPBY(oparg); |
| 69 | 1224 break; |
| 1225 | |
| 1226 case JUMP_IF_FALSE: | |
| 86 | 1227 if (!testbool(TOP())) |
| 1228 JUMPBY(oparg); | |
| 69 | 1229 break; |
| 1230 | |
| 1231 case JUMP_IF_TRUE: | |
| 86 | 1232 if (testbool(TOP())) |
| 1233 JUMPBY(oparg); | |
| 69 | 1234 break; |
| 1235 | |
| 1236 case JUMP_ABSOLUTE: | |
| 86 | 1237 JUMPTO(oparg); |
| 69 | 1238 break; |
| 1239 | |
| 1240 case FOR_LOOP: | |
| 1241 /* for v in s: ... | |
| 1242 On entry: stack contains s, i. | |
| 1243 On exit: stack contains s, i+1, s[i]; | |
| 1244 but if loop exhausted: | |
|
72
5e8a0b40a4bd
Free parse tree after compiling.
Guido van Rossum <guido@python.org>
parents:
69
diff
changeset
|
1245 s, i are popped, and we jump */ |
| 69 | 1246 w = POP(); /* Loop index */ |
| 1247 v = POP(); /* Sequence object */ | |
| 86 | 1248 u = loop_subscript(v, w); |
| 1249 if (u != NULL) { | |
| 69 | 1250 PUSH(v); |
| 86 | 1251 x = newintobject(getintvalue(w)+1); |
| 1252 PUSH(x); | |
| 1253 DECREF(w); | |
| 69 | 1254 PUSH(u); |
| 1255 } | |
| 1256 else { | |
| 1257 DECREF(v); | |
| 1258 DECREF(w); | |
| 86 | 1259 /* A NULL can mean "s exhausted" |
| 1260 but also an error: */ | |
| 1261 if (err_occurred()) | |
| 1262 why = WHY_EXCEPTION; | |
| 1263 else | |
| 1264 JUMPBY(oparg); | |
| 69 | 1265 } |
| 1266 break; | |
| 1267 | |
| 1268 case SETUP_LOOP: | |
| 86 | 1269 case SETUP_EXCEPT: |
| 1270 case SETUP_FINALLY: | |
| 1271 setup_block(f, opcode, INSTR_OFFSET() + oparg, | |
| 1272 STACK_LEVEL()); | |
| 69 | 1273 break; |
| 1274 | |
| 86 | 1275 case SET_LINENO: |
| 1276 #ifdef TRACE | |
| 1277 if (trace) | |
| 1278 printf("--- Line %d ---\n", oparg); | |
| 1279 #endif | |
| 1280 lineno = oparg; | |
| 69 | 1281 break; |
| 1282 | |
| 1283 default: | |
| 86 | 1284 fprintf(stderr, |
| 1285 "XXX lineno: %d, opcode: %d\n", | |
| 1286 lineno, opcode); | |
| 1287 err_setstr(SystemError, "eval_code: unknown opcode"); | |
| 1288 why = WHY_EXCEPTION; | |
| 69 | 1289 break; |
| 1290 | |
| 86 | 1291 } /* switch */ |
| 1292 | |
| 1293 | |
| 1294 /* Quickly continue if no error occurred */ | |
| 1295 | |
| 1296 if (why == WHY_NOT) { | |
| 1297 if (err == 0 && x != NULL) | |
| 1298 continue; /* Normal, fast path */ | |
| 1299 why = WHY_EXCEPTION; | |
| 1300 x = None; | |
| 1301 err = 0; | |
| 1302 } | |
| 1303 | |
| 1304 #ifndef NDEBUG | |
| 1305 /* Double-check exception status */ | |
| 1306 | |
| 1307 if (why == WHY_EXCEPTION || why == WHY_RERAISE) { | |
| 1308 if (!err_occurred()) { | |
| 1309 fprintf(stderr, "XXX ghost error\n"); | |
| 1310 err_setstr(SystemError, "ghost error"); | |
| 1311 why = WHY_EXCEPTION; | |
| 1312 } | |
| 1313 } | |
| 1314 else { | |
| 1315 if (err_occurred()) { | |
| 1316 fprintf(stderr, "XXX undetected error\n"); | |
| 1317 why = WHY_EXCEPTION; | |
| 1318 } | |
| 1319 } | |
| 1320 #endif | |
| 1321 | |
| 1322 /* Log traceback info if this is a real exception */ | |
| 1323 | |
| 1324 if (why == WHY_EXCEPTION) { | |
| 1325 int lasti = INSTR_OFFSET() - 1; | |
| 1326 if (HAS_ARG(opcode)) | |
| 1327 lasti -= 2; | |
| 1328 tb_here(f, lasti, lineno); | |
| 69 | 1329 } |
| 1330 | |
| 86 | 1331 /* For the rest, treat WHY_RERAISE as WHY_EXCEPTION */ |
| 69 | 1332 |
| 86 | 1333 if (why == WHY_RERAISE) |
| 1334 why = WHY_EXCEPTION; | |
| 1335 | |
| 1336 /* Unwind stacks if a (pseudo) exception occurred */ | |
| 1337 | |
| 1338 while (why != WHY_NOT && f->f_iblock > 0) { | |
| 69 | 1339 block *b = pop_block(f); |
| 86 | 1340 while (STACK_LEVEL() > b->b_level) { |
| 1341 v = POP(); | |
| 1342 XDECREF(v); | |
| 69 | 1343 } |
| 86 | 1344 if (b->b_type == SETUP_LOOP && why == WHY_BREAK) { |
| 1345 why = WHY_NOT; | |
| 69 | 1346 JUMPTO(b->b_handler); |
| 1347 break; | |
| 1348 } | |
| 86 | 1349 if (b->b_type == SETUP_FINALLY || |
| 1350 b->b_type == SETUP_EXCEPT && | |
| 1351 why == WHY_EXCEPTION) { | |
| 1352 if (why == WHY_EXCEPTION) { | |
| 1353 object *exc, *val; | |
| 1354 err_get(&exc, &val); | |
| 1355 if (val == NULL) { | |
| 1356 val = None; | |
| 1357 INCREF(val); | |
| 1358 } | |
| 1359 v = tb_fetch(); | |
| 1360 /* Make the raw exception data | |
| 1361 available to the handler, | |
| 1362 so a program can emulate the | |
| 1363 Python main loop. Don't do | |
| 1364 this for 'finally'. */ | |
| 1365 if (b->b_type == SETUP_EXCEPT) { | |
| 1366 #if 0 /* Oops, this breaks too many things */ | |
| 1367 sysset("exc_traceback", v); | |
| 1368 #endif | |
| 1369 sysset("exc_value", val); | |
| 1370 sysset("exc_type", exc); | |
| 1371 err_clear(); | |
| 1372 } | |
| 1373 PUSH(v); | |
| 1374 PUSH(val); | |
| 1375 PUSH(exc); | |
| 1376 } | |
| 1377 else { | |
| 1378 if (why == WHY_RETURN) | |
| 1379 PUSH(retval); | |
| 1380 v = newintobject((long)why); | |
| 1381 PUSH(v); | |
| 1382 } | |
| 1383 why = WHY_NOT; | |
| 1384 JUMPTO(b->b_handler); | |
| 1385 break; | |
| 1386 } | |
| 1387 } /* unwind stack */ | |
| 1388 | |
| 1389 /* End the loop if we still have an error (or return) */ | |
| 1390 | |
| 1391 if (why != WHY_NOT) | |
| 1392 break; | |
| 1393 | |
| 1394 } /* main loop */ | |
| 1395 | |
| 1396 /* Pop remaining stack entries */ | |
| 1397 | |
| 1398 while (!EMPTY()) { | |
| 1399 v = POP(); | |
| 1400 XDECREF(v); | |
| 69 | 1401 } |
| 1402 | |
| 86 | 1403 /* Restore previous frame and release the current one */ |
| 1404 | |
| 1405 current_frame = f->f_back; | |
| 1406 DECREF(f); | |
| 69 | 1407 |
| 86 | 1408 if (why == WHY_RETURN) |
| 1409 return retval; | |
| 1410 else | |
| 69 | 1411 return NULL; |
| 1412 } |
