00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #undef __FILE_ID__
00017 #define __FILE_ID__ 0x09
00018
00019
00028 #include "pm.h"
00029
00030
00031 PmReturn_t
00032 interpret(const uint8_t returnOnNoThreads)
00033 {
00034 PmReturn_t retval = PM_RET_OK;
00035 pPmObj_t pobj1 = C_NULL;
00036 pPmObj_t pobj2 = C_NULL;
00037 pPmObj_t pobj3 = C_NULL;
00038 int16_t t16 = 0;
00039 int8_t t8 = 0;
00040 uint8_t bc;
00041 uint8_t objid, objid2;
00042
00043
00044 retval = interp_reschedule();
00045 PM_RETURN_IF_ERROR(retval);
00046
00047
00048 for (;;)
00049 {
00050 if (gVmGlobal.pthread == C_NULL)
00051 {
00052 if (returnOnNoThreads)
00053 {
00054
00055 return retval;
00056 }
00057
00058
00059
00060
00061
00062 retval = interp_reschedule();
00063 PM_BREAK_IF_ERROR(retval);
00064 continue;
00065 }
00066
00067
00068 if (gVmGlobal.reschedule)
00069 {
00070 retval = interp_reschedule();
00071 PM_BREAK_IF_ERROR(retval);
00072 }
00073
00074
00075 bc = mem_getByte(PM_FP->fo_memspace, &PM_IP);
00076 switch (bc)
00077 {
00078 case POP_TOP:
00079 pobj1 = PM_POP();
00080 continue;
00081
00082 case ROT_TWO:
00083 pobj1 = TOS;
00084 TOS = TOS1;
00085 TOS1 = pobj1;
00086 continue;
00087
00088 case ROT_THREE:
00089 pobj1 = TOS;
00090 TOS = TOS1;
00091 TOS1 = TOS2;
00092 TOS2 = pobj1;
00093 continue;
00094
00095 case DUP_TOP:
00096 pobj1 = TOS;
00097 PM_PUSH(pobj1);
00098 continue;
00099
00100 case ROT_FOUR:
00101 pobj1 = TOS;
00102 TOS = TOS1;
00103 TOS1 = TOS2;
00104 TOS2 = TOS3;
00105 TOS3 = pobj1;
00106 continue;
00107
00108 case NOP:
00109 continue;
00110
00111 case UNARY_POSITIVE:
00112
00113 if ((OBJ_GET_TYPE(TOS) != OBJ_TYPE_INT)
00114 #ifdef HAVE_FLOAT
00115 && (OBJ_GET_TYPE(TOS) != OBJ_TYPE_FLT)
00116 #endif
00117 )
00118 {
00119 PM_RAISE(retval, PM_RET_EX_TYPE);
00120 break;
00121 }
00122
00123
00124 continue;
00125
00126 case UNARY_NEGATIVE:
00127 #ifdef HAVE_FLOAT
00128 if (OBJ_GET_TYPE(TOS) == OBJ_TYPE_FLT)
00129 {
00130 retval = float_negative(TOS, &pobj2);
00131 }
00132 else
00133 #endif
00134 {
00135 retval = int_negative(TOS, &pobj2);
00136 }
00137 PM_BREAK_IF_ERROR(retval);
00138 TOS = pobj2;
00139 continue;
00140
00141 case UNARY_NOT:
00142 pobj1 = PM_POP();
00143 if (obj_isFalse(pobj1))
00144 {
00145 PM_PUSH(PM_TRUE);
00146 }
00147 else
00148 {
00149 PM_PUSH(PM_FALSE);
00150 }
00151 continue;
00152
00153 #ifdef HAVE_BACKTICK
00154
00155 case UNARY_CONVERT:
00156 retval = obj_repr(TOS, &pobj3);
00157 PM_BREAK_IF_ERROR(retval);
00158 TOS = pobj3;
00159 continue;
00160 #endif
00161
00162 case UNARY_INVERT:
00163
00164 if (OBJ_GET_TYPE(TOS) != OBJ_TYPE_INT)
00165 {
00166 PM_RAISE(retval, PM_RET_EX_TYPE);
00167 break;
00168 }
00169
00170
00171 retval = int_bitInvert(TOS, &pobj2);
00172 PM_BREAK_IF_ERROR(retval);
00173 TOS = pobj2;
00174 continue;
00175
00176 case LIST_APPEND:
00177
00178 retval = list_append(TOS1, TOS);
00179 PM_SP -= 2;
00180 continue;
00181
00182 case BINARY_POWER:
00183 case INPLACE_POWER:
00184
00185 #ifdef HAVE_FLOAT
00186 if ((OBJ_GET_TYPE(TOS) == OBJ_TYPE_FLT)
00187 || (OBJ_GET_TYPE(TOS1) == OBJ_TYPE_FLT))
00188 {
00189
00190 retval = float_op(TOS1, TOS, &pobj3, 'P');
00191 PM_BREAK_IF_ERROR(retval);
00192 PM_SP--;
00193 TOS = pobj3;
00194 continue;
00195 }
00196 #endif
00197
00198
00199 retval = int_pow(TOS1, TOS, &pobj3);
00200 PM_BREAK_IF_ERROR(retval);
00201
00202
00203 PM_SP--;
00204 TOS = pobj3;
00205 continue;
00206
00207 case GET_ITER:
00208 #ifdef HAVE_GENERATORS
00209
00210 if (OBJ_GET_TYPE(TOS) == OBJ_TYPE_CLI)
00211 {
00212 retval = class_getAttr(TOS, PM_NEXT_STR, &pobj1);
00213 if (retval != PM_RET_OK)
00214 {
00215 PM_RAISE(retval, PM_RET_EX_TYPE);
00216 break;
00217 }
00218 }
00219 else
00220 #endif
00221 {
00222
00223 retval = seqiter_new(TOS, &pobj1);
00224 PM_BREAK_IF_ERROR(retval);
00225
00226
00227 TOS = pobj1;
00228 }
00229 continue;
00230
00231 case BINARY_MULTIPLY:
00232 case INPLACE_MULTIPLY:
00233
00234 if ((OBJ_GET_TYPE(TOS) == OBJ_TYPE_INT)
00235 && (OBJ_GET_TYPE(TOS1) == OBJ_TYPE_INT))
00236 {
00237 retval = int_new(((pPmInt_t)TOS1)->val *
00238 ((pPmInt_t)TOS)->val, &pobj3);
00239 PM_BREAK_IF_ERROR(retval);
00240 PM_SP--;
00241 TOS = pobj3;
00242 continue;
00243 }
00244
00245 #ifdef HAVE_FLOAT
00246 else if ((OBJ_GET_TYPE(TOS) == OBJ_TYPE_FLT)
00247 || (OBJ_GET_TYPE(TOS1) == OBJ_TYPE_FLT))
00248 {
00249 retval = float_op(TOS1, TOS, &pobj3, '*');
00250 PM_BREAK_IF_ERROR(retval);
00251 PM_SP--;
00252 TOS = pobj3;
00253 continue;
00254 }
00255 #endif
00256
00257 #ifdef HAVE_REPLICATION
00258
00259 else if ((OBJ_GET_TYPE(TOS) == OBJ_TYPE_INT)
00260 && (OBJ_GET_TYPE(TOS1) == OBJ_TYPE_LST))
00261 {
00262 t16 = (int16_t)((pPmInt_t)TOS)->val;
00263 if (t16 < 0)
00264 {
00265 t16 = 0;
00266 }
00267
00268 retval = list_replicate(TOS1, t16, &pobj3);
00269 PM_BREAK_IF_ERROR(retval);
00270 PM_SP--;
00271 TOS = pobj3;
00272 continue;
00273 }
00274
00275
00276 else if ((OBJ_GET_TYPE(TOS) == OBJ_TYPE_INT)
00277 && (OBJ_GET_TYPE(TOS1) == OBJ_TYPE_TUP))
00278 {
00279 t16 = (int16_t)((pPmInt_t)TOS)->val;
00280 if (t16 < 0)
00281 {
00282 t16 = 0;
00283 }
00284
00285 retval = tuple_replicate(TOS1, t16, &pobj3);
00286 PM_BREAK_IF_ERROR(retval);
00287 PM_SP--;
00288 TOS = pobj3;
00289 continue;
00290 }
00291
00292
00293 else if ((OBJ_GET_TYPE(TOS) == OBJ_TYPE_INT)
00294 && (OBJ_GET_TYPE(TOS1) == OBJ_TYPE_STR))
00295 {
00296 t16 = (int16_t)((pPmInt_t)TOS)->val;
00297 if (t16 < 0)
00298 {
00299 t16 = 0;
00300 }
00301
00302 pobj2 = TOS1;
00303 pobj2 = (pPmObj_t)&((pPmString_t)pobj2)->val;
00304 retval = string_replicate(
00305 (uint8_t const **)(uint8_t *)&pobj2, t16, &pobj3);
00306 PM_BREAK_IF_ERROR(retval);
00307 PM_SP--;
00308 TOS = pobj3;
00309 continue;
00310 }
00311 #endif
00312
00313
00314 PM_RAISE(retval, PM_RET_EX_TYPE);
00315 break;
00316
00317 case BINARY_DIVIDE:
00318 case INPLACE_DIVIDE:
00319 case BINARY_FLOOR_DIVIDE:
00320 case INPLACE_FLOOR_DIVIDE:
00321
00322 #ifdef HAVE_FLOAT
00323 if ((OBJ_GET_TYPE(TOS) == OBJ_TYPE_FLT)
00324 || (OBJ_GET_TYPE(TOS1) == OBJ_TYPE_FLT))
00325 {
00326 retval = float_op(TOS1, TOS, &pobj3, '/');
00327 PM_BREAK_IF_ERROR(retval);
00328 PM_SP--;
00329 TOS = pobj3;
00330 continue;
00331 }
00332 #endif
00333
00334
00335 if ((OBJ_GET_TYPE(TOS) != OBJ_TYPE_INT)
00336 || (OBJ_GET_TYPE(TOS1) != OBJ_TYPE_INT))
00337 {
00338 PM_RAISE(retval, PM_RET_EX_TYPE);
00339 break;
00340 }
00341
00342
00343 if (((pPmInt_t)TOS)->val == 0)
00344 {
00345 PM_RAISE(retval, PM_RET_EX_ZDIV);
00346 break;
00347 }
00348
00349
00350 retval = int_new(((pPmInt_t)TOS1)->val /
00351 ((pPmInt_t)TOS)->val, &pobj3);
00352 PM_BREAK_IF_ERROR(retval);
00353 PM_SP--;
00354 TOS = pobj3;
00355 continue;
00356
00357 case BINARY_MODULO:
00358 case INPLACE_MODULO:
00359
00360 #ifdef HAVE_STRING_FORMAT
00361
00362 if (OBJ_GET_TYPE(TOS1) == OBJ_TYPE_STR)
00363 {
00364 retval = string_format((pPmString_t)TOS1, TOS, &pobj3);
00365 PM_BREAK_IF_ERROR(retval);
00366 PM_SP--;
00367 TOS = pobj3;
00368 continue;
00369 }
00370 #endif
00371
00372 #ifdef HAVE_FLOAT
00373 if ((OBJ_GET_TYPE(TOS) == OBJ_TYPE_FLT)
00374 || (OBJ_GET_TYPE(TOS1) == OBJ_TYPE_FLT))
00375 {
00376 retval = float_op(TOS1, TOS, &pobj3, '%');
00377 PM_BREAK_IF_ERROR(retval);
00378 PM_SP--;
00379 TOS = pobj3;
00380 continue;
00381 }
00382 #endif
00383
00384
00385 if ((OBJ_GET_TYPE(TOS) != OBJ_TYPE_INT)
00386 || (OBJ_GET_TYPE(TOS1) != OBJ_TYPE_INT))
00387 {
00388 PM_RAISE(retval, PM_RET_EX_TYPE);
00389 break;
00390 }
00391
00392
00393 if (((pPmInt_t)TOS)->val == 0)
00394 {
00395 PM_RAISE(retval, PM_RET_EX_ZDIV);
00396 break;
00397 }
00398
00399
00400 retval = int_new(((pPmInt_t)TOS1)->val %
00401 ((pPmInt_t)TOS)->val, &pobj3);
00402 PM_BREAK_IF_ERROR(retval);
00403 PM_SP--;
00404 TOS = pobj3;
00405 continue;
00406
00407 case STORE_MAP:
00408
00409 C_ASSERT(OBJ_GET_TYPE(TOS2) == OBJ_TYPE_DIC);
00410 retval = dict_setItem(TOS2, TOS, TOS1);
00411 PM_BREAK_IF_ERROR(retval);
00412 PM_SP -= 2;
00413 continue;
00414
00415 case BINARY_ADD:
00416 case INPLACE_ADD:
00417
00418 #ifdef HAVE_FLOAT
00419 if ((OBJ_GET_TYPE(TOS) == OBJ_TYPE_FLT)
00420 || (OBJ_GET_TYPE(TOS1) == OBJ_TYPE_FLT))
00421 {
00422 retval = float_op(TOS1, TOS, &pobj3, '+');
00423 PM_BREAK_IF_ERROR(retval);
00424 PM_SP--;
00425 TOS = pobj3;
00426 continue;
00427 }
00428 #endif
00429
00430
00431 if ((OBJ_GET_TYPE(TOS) == OBJ_TYPE_INT)
00432 && (OBJ_GET_TYPE(TOS1) == OBJ_TYPE_INT))
00433 {
00434 retval = int_new(((pPmInt_t)TOS1)->val +
00435 ((pPmInt_t)TOS)->val, &pobj3);
00436 PM_BREAK_IF_ERROR(retval);
00437 PM_SP--;
00438 TOS = pobj3;
00439 continue;
00440 }
00441
00442
00443 if ((OBJ_GET_TYPE(TOS) == OBJ_TYPE_STR)
00444 && (OBJ_GET_TYPE(TOS1) == OBJ_TYPE_STR))
00445 {
00446 retval = string_concat((pPmString_t)TOS1,
00447 (pPmString_t)TOS,
00448 &pobj3);
00449 PM_BREAK_IF_ERROR(retval);
00450 PM_SP--;
00451 TOS = pobj3;
00452 continue;
00453 }
00454
00455
00456 PM_RAISE(retval, PM_RET_EX_TYPE);
00457 break;
00458
00459 case BINARY_SUBTRACT:
00460 case INPLACE_SUBTRACT:
00461
00462 #ifdef HAVE_FLOAT
00463 if ((OBJ_GET_TYPE(TOS) == OBJ_TYPE_FLT)
00464 || (OBJ_GET_TYPE(TOS1) == OBJ_TYPE_FLT))
00465 {
00466 retval = float_op(TOS1, TOS, &pobj3, '-');
00467 PM_BREAK_IF_ERROR(retval);
00468 PM_SP--;
00469 TOS = pobj3;
00470 continue;
00471 }
00472 #endif
00473
00474
00475 if ((OBJ_GET_TYPE(TOS) == OBJ_TYPE_INT)
00476 && (OBJ_GET_TYPE(TOS1) == OBJ_TYPE_INT))
00477 {
00478 retval = int_new(((pPmInt_t)TOS1)->val -
00479 ((pPmInt_t)TOS)->val, &pobj3);
00480 PM_BREAK_IF_ERROR(retval);
00481 PM_SP--;
00482 TOS = pobj3;
00483 continue;
00484 }
00485
00486
00487 PM_RAISE(retval, PM_RET_EX_TYPE);
00488 break;
00489
00490 case BINARY_SUBSCR:
00491
00492
00493 if (OBJ_GET_TYPE(TOS1) == OBJ_TYPE_DIC)
00494 {
00495 retval = dict_getItem(TOS1, TOS, &pobj3);
00496 }
00497 else
00498 {
00499
00500 if ((OBJ_GET_TYPE(TOS) != OBJ_TYPE_INT)
00501 && (OBJ_GET_TYPE(TOS) != OBJ_TYPE_BOOL))
00502 {
00503 PM_RAISE(retval, PM_RET_EX_TYPE);
00504 break;
00505 }
00506
00507 pobj1 = TOS1;
00508 #ifdef HAVE_BYTEARRAY
00509
00510 if (OBJ_GET_TYPE(pobj1) == OBJ_TYPE_CLI)
00511 {
00512 retval = dict_getItem((pPmObj_t)((pPmInstance_t)pobj1)->cli_attrs,
00513 PM_NONE,
00514 &pobj2);
00515 PM_RETURN_IF_ERROR(retval);
00516 pobj1 = pobj2;
00517 }
00518 #endif
00519
00520
00521 C_ASSERT(((pPmInt_t)TOS)->val <= 0x0000FFFF);
00522 t16 = (int16_t)((pPmInt_t)TOS)->val;
00523
00524 retval = seq_getSubscript(pobj1, t16, &pobj3);
00525 }
00526 PM_BREAK_IF_ERROR(retval);
00527 PM_SP--;
00528 TOS = pobj3;
00529 continue;
00530
00531 #ifdef HAVE_FLOAT
00532
00533 case BINARY_TRUE_DIVIDE:
00534 case INPLACE_TRUE_DIVIDE:
00535
00536
00537 retval = float_op(TOS1, TOS, &pobj3, '/');
00538 PM_BREAK_IF_ERROR(retval);
00539 PM_SP--;
00540 TOS = pobj3;
00541 continue;
00542 #endif
00543
00544 case SLICE_0:
00545
00546
00547
00548 if (OBJ_GET_TYPE(TOS) == OBJ_TYPE_LST)
00549 {
00550 retval = list_copy(TOS, &pobj2);
00551 PM_BREAK_IF_ERROR(retval);
00552
00553 TOS = pobj2;
00554 }
00555
00556
00557
00558
00559 else if ((OBJ_GET_TYPE(TOS) != OBJ_TYPE_STR)
00560 && (OBJ_GET_TYPE(TOS) != OBJ_TYPE_TUP))
00561 {
00562 PM_RAISE(retval, PM_RET_EX_TYPE);
00563 break;
00564 }
00565 continue;
00566
00567 case STORE_SUBSCR:
00568
00569
00570
00571 if (OBJ_GET_TYPE(TOS1) == OBJ_TYPE_LST)
00572 {
00573
00574 if ((OBJ_GET_TYPE(TOS) != OBJ_TYPE_INT)
00575 && (OBJ_GET_TYPE(TOS) != OBJ_TYPE_BOOL))
00576 {
00577 PM_RAISE(retval, PM_RET_EX_TYPE);
00578 break;
00579 }
00580
00581
00582 retval = list_setItem(TOS1,
00583 (int16_t)(((pPmInt_t)TOS)->val),
00584 TOS2);
00585 PM_BREAK_IF_ERROR(retval);
00586 PM_SP -= 3;
00587 continue;
00588 }
00589
00590
00591 if (OBJ_GET_TYPE(TOS1) == OBJ_TYPE_DIC)
00592 {
00593
00594 retval = dict_setItem(TOS1, TOS, TOS2);
00595 PM_BREAK_IF_ERROR(retval);
00596 PM_SP -= 3;
00597 continue;
00598 }
00599
00600 #ifdef HAVE_BYTEARRAY
00601
00602 if (OBJ_GET_TYPE(TOS1) == OBJ_TYPE_CLI)
00603 {
00604 retval = dict_getItem((pPmObj_t)((pPmInstance_t)TOS1)->cli_attrs,
00605 PM_NONE,
00606 &pobj2);
00607
00608
00609 if ((retval == PM_RET_EX_KEY)
00610 || (OBJ_GET_TYPE(pobj2) != OBJ_TYPE_BYA))
00611 {
00612 PM_RAISE(retval, PM_RET_EX_TYPE);
00613 break;
00614 }
00615 PM_BREAK_IF_ERROR(retval);
00616
00617
00618 if ((OBJ_GET_TYPE(TOS) != OBJ_TYPE_INT)
00619 && (OBJ_GET_TYPE(TOS) != OBJ_TYPE_BOOL))
00620 {
00621 PM_RAISE(retval, PM_RET_EX_TYPE);
00622 break;
00623 }
00624
00625 retval = bytearray_setItem(pobj2,
00626 (int16_t)(((pPmInt_t)TOS)->val),
00627 TOS2);
00628 PM_BREAK_IF_ERROR(retval);
00629 PM_SP -= 3;
00630 continue;
00631 }
00632 #endif
00633
00634
00635 PM_RAISE(retval, PM_RET_EX_TYPE);
00636 break;
00637
00638 #ifdef HAVE_DEL
00639 case DELETE_SUBSCR:
00640
00641 if ((OBJ_GET_TYPE(TOS1) == OBJ_TYPE_LST)
00642 && (OBJ_GET_TYPE(TOS) == OBJ_TYPE_INT))
00643 {
00644 retval = list_delItem(TOS1,
00645 (int16_t)((pPmInt_t)TOS)->val);
00646 }
00647
00648 else if ((OBJ_GET_TYPE(TOS1) == OBJ_TYPE_DIC)
00649 && (OBJ_GET_TYPE(TOS) <= OBJ_TYPE_HASHABLE_MAX))
00650 {
00651 retval = dict_delItem(TOS1, TOS);
00652 }
00653
00654
00655 else
00656 {
00657 PM_RAISE(retval, PM_RET_EX_TYPE);
00658 }
00659
00660 PM_BREAK_IF_ERROR(retval);
00661 PM_SP -= 2;
00662 continue;
00663 #endif
00664
00665 case BINARY_LSHIFT:
00666 case INPLACE_LSHIFT:
00667
00668 if ((OBJ_GET_TYPE(TOS) == OBJ_TYPE_INT)
00669 && (OBJ_GET_TYPE(TOS1) == OBJ_TYPE_INT))
00670 {
00671 retval = int_new(((pPmInt_t)TOS1)->val <<
00672 ((pPmInt_t)TOS)->val, &pobj3);
00673 PM_BREAK_IF_ERROR(retval);
00674 PM_SP--;
00675 TOS = pobj3;
00676 continue;
00677 }
00678
00679
00680 PM_RAISE(retval, PM_RET_EX_TYPE);
00681 break;
00682
00683 case BINARY_RSHIFT:
00684 case INPLACE_RSHIFT:
00685
00686 if ((OBJ_GET_TYPE(TOS) == OBJ_TYPE_INT)
00687 && (OBJ_GET_TYPE(TOS1) == OBJ_TYPE_INT))
00688 {
00689 retval = int_new(((pPmInt_t)TOS1)->val >>
00690 ((pPmInt_t)TOS)->val, &pobj3);
00691 PM_BREAK_IF_ERROR(retval);
00692 PM_SP--;
00693 TOS = pobj3;
00694 continue;
00695 }
00696
00697
00698 PM_RAISE(retval, PM_RET_EX_TYPE);
00699 break;
00700
00701 case BINARY_AND:
00702 case INPLACE_AND:
00703
00704 if ((OBJ_GET_TYPE(TOS) == OBJ_TYPE_INT)
00705 && (OBJ_GET_TYPE(TOS1) == OBJ_TYPE_INT))
00706 {
00707 retval = int_new(((pPmInt_t)TOS1)->val &
00708 ((pPmInt_t)TOS)->val, &pobj3);
00709 PM_BREAK_IF_ERROR(retval);
00710 PM_SP--;
00711 TOS = pobj3;
00712 continue;
00713 }
00714
00715
00716 PM_RAISE(retval, PM_RET_EX_TYPE);
00717 break;
00718
00719 case BINARY_XOR:
00720 case INPLACE_XOR:
00721
00722 if ((OBJ_GET_TYPE(TOS) == OBJ_TYPE_INT)
00723 && (OBJ_GET_TYPE(TOS1) == OBJ_TYPE_INT))
00724 {
00725 retval = int_new(((pPmInt_t)TOS1)->val ^
00726 ((pPmInt_t)TOS)->val, &pobj3);
00727 PM_BREAK_IF_ERROR(retval);
00728 PM_SP--;
00729 TOS = pobj3;
00730 continue;
00731 }
00732
00733
00734 PM_RAISE(retval, PM_RET_EX_TYPE);
00735 break;
00736
00737 case BINARY_OR:
00738 case INPLACE_OR:
00739
00740 if ((OBJ_GET_TYPE(TOS) == OBJ_TYPE_INT)
00741 && (OBJ_GET_TYPE(TOS1) == OBJ_TYPE_INT))
00742 {
00743 retval = int_new(((pPmInt_t)TOS1)->val |
00744 ((pPmInt_t)TOS)->val, &pobj3);
00745 PM_BREAK_IF_ERROR(retval);
00746 PM_SP--;
00747 TOS = pobj3;
00748 continue;
00749 }
00750
00751
00752 PM_RAISE(retval, PM_RET_EX_TYPE);
00753 break;
00754
00755 #ifdef HAVE_PRINT
00756 case PRINT_EXPR:
00757
00758
00759
00760 case PRINT_ITEM:
00761 if (gVmGlobal.needSoftSpace && (bc == PRINT_ITEM))
00762 {
00763 retval = plat_putByte(' ');
00764 PM_BREAK_IF_ERROR(retval);
00765 }
00766 gVmGlobal.needSoftSpace = C_TRUE;
00767
00768
00769 retval = obj_print(TOS, (uint8_t)(bc == PRINT_EXPR), C_FALSE);
00770 PM_BREAK_IF_ERROR(retval);
00771 PM_SP--;
00772 if (bc != PRINT_EXPR)
00773 {
00774 continue;
00775 }
00776
00777
00778 case PRINT_NEWLINE:
00779 gVmGlobal.needSoftSpace = C_FALSE;
00780 if (gVmGlobal.somethingPrinted)
00781 {
00782 retval = plat_putByte('\n');
00783 gVmGlobal.somethingPrinted = C_FALSE;
00784 }
00785 PM_BREAK_IF_ERROR(retval);
00786 continue;
00787 #endif
00788
00789 case BREAK_LOOP:
00790 {
00791 pPmBlock_t pb1 = PM_FP->fo_blockstack;
00792
00793
00794 C_ASSERT(pb1 != C_NULL);
00795
00796
00797 while ((pb1->b_type != B_LOOP) && (pb1->next != C_NULL))
00798 {
00799 pobj2 = (pPmObj_t)pb1;
00800 pb1 = pb1->next;
00801 retval = heap_freeChunk(pobj2);
00802 PM_BREAK_IF_ERROR(retval);
00803 }
00804
00805
00806 PM_BREAK_IF_ERROR(retval);
00807
00808
00809 PM_SP = pb1->b_sp;
00810
00811
00812 PM_IP = pb1->b_handler;
00813
00814
00815 PM_FP->fo_blockstack = pb1->next;
00816 retval = heap_freeChunk((pPmObj_t)pb1);
00817 PM_BREAK_IF_ERROR(retval);
00818 }
00819 continue;
00820
00821 case LOAD_LOCALS:
00822
00823
00824 PM_PUSH((pPmObj_t)PM_FP->fo_attrs);
00825 continue;
00826
00827 case RETURN_VALUE:
00828
00829 pobj2 = PM_POP();
00830
00831 #if 0
00832
00833
00834
00835 if ((PM_FP != (pPmFrame_t)(&gVmGlobal.nativeframe)) &&
00836 !(PM_FP->fo_func->f_co->co_flags & CO_GENERATOR))
00837 {
00838
00839 t8 = PM_FP->fo_func->f_co->co_nlocals;
00840 C_ASSERT(PM_SP == &(PM_FP->fo_locals[t8]));
00841 }
00842 #endif
00843
00844
00845 pobj1 = (pPmObj_t)PM_FP;
00846 C_ASSERT(OBJ_GET_TYPE(pobj1) == OBJ_TYPE_FRM);
00847
00848
00849 if (PM_FP->fo_back == C_NULL)
00850 {
00851 gVmGlobal.pthread->interpctrl = INTERP_CTRL_EXIT;
00852 retval = PM_RET_OK;
00853 break;
00854 }
00855
00856
00857 PM_FP = PM_FP->fo_back;
00858
00859 #ifdef HAVE_GENERATORS
00860
00861 if (((pPmFrame_t)pobj1)->fo_func->f_co->co_flags & CO_GENERATOR)
00862 {
00863
00864 PM_RAISE(retval, PM_RET_EX_STOP);
00865 break;
00866 }
00867 #endif
00868
00869 #ifdef HAVE_CLASSES
00870
00871
00872
00873
00874 if (((pPmFrame_t)pobj1)->fo_isInit)
00875 {
00876
00877 if (pobj2 != PM_NONE)
00878 {
00879 PM_RAISE(retval, PM_RET_EX_TYPE);
00880 break;
00881 }
00882 }
00883 else
00884 #endif
00885
00886
00887
00888
00889
00890 if (!(((pPmFrame_t)pobj1)->fo_isImport))
00891 {
00892 PM_PUSH(pobj2);
00893 }
00894
00895
00896 PM_BREAK_IF_ERROR(heap_freeChunk(pobj1));
00897 continue;
00898
00899 #ifdef HAVE_IMPORTS
00900 case IMPORT_STAR:
00901
00902
00903 C_ASSERT(OBJ_GET_TYPE(TOS) == OBJ_TYPE_MOD);
00904
00905
00906 retval = dict_update((pPmObj_t)PM_FP->fo_attrs,
00907 (pPmObj_t)((pPmFunc_t)TOS)->f_attrs);
00908 PM_BREAK_IF_ERROR(retval);
00909 PM_SP--;
00910 continue;
00911 #endif
00912
00913 #ifdef HAVE_GENERATORS
00914 case YIELD_VALUE:
00915
00916
00917 pobj1 = PM_POP();
00918
00919
00920
00921 if ((PM_FP)->fo_isInit)
00922 {
00923 PM_RAISE(retval, PM_RET_EX_TYPE);
00924 break;
00925 }
00926
00927
00928 PM_FP = PM_FP->fo_back;
00929
00930
00931 PM_PUSH(pobj1);
00932 continue;
00933 #endif
00934
00935 case POP_BLOCK:
00936
00937 pobj1 = (pPmObj_t)PM_FP->fo_blockstack;
00938
00939
00940 C_ASSERT(pobj1 != C_NULL);
00941
00942
00943 PM_FP->fo_blockstack = PM_FP->fo_blockstack->next;
00944
00945
00946 PM_SP = ((pPmBlock_t)pobj1)->b_sp;
00947 PM_IP = ((pPmBlock_t)pobj1)->b_handler;
00948
00949 PM_BREAK_IF_ERROR(heap_freeChunk(pobj1));
00950 continue;
00951
00952 #ifdef HAVE_CLASSES
00953 case BUILD_CLASS:
00954
00955 retval = class_new(TOS, TOS1, TOS2, &pobj2);
00956 PM_BREAK_IF_ERROR(retval);
00957 PM_SP -= 2;
00958 TOS = pobj2;
00959 continue;
00960 #endif
00961
00962
00963
00964
00965
00966
00967
00968 case STORE_NAME:
00969
00970 t16 = GET_ARG();
00971
00972
00973 pobj2 = PM_FP->fo_func->f_co->co_names->val[t16];
00974
00975
00976 retval = dict_setItem((pPmObj_t)PM_FP->fo_attrs, pobj2, TOS);
00977 PM_BREAK_IF_ERROR(retval);
00978 PM_SP--;
00979 continue;
00980
00981 #ifdef HAVE_DEL
00982 case DELETE_NAME:
00983
00984 t16 = GET_ARG();
00985
00986
00987 pobj2 = PM_FP->fo_func->f_co->co_names->val[t16];
00988
00989
00990 retval = dict_delItem((pPmObj_t)PM_FP->fo_attrs, pobj2);
00991 PM_BREAK_IF_ERROR(retval);
00992 continue;
00993 #endif
00994
00995 case UNPACK_SEQUENCE:
00996
00997 pobj1 = PM_POP();
00998
00999 #ifdef HAVE_BYTEARRAY
01000
01001 if (OBJ_GET_TYPE(pobj1) == OBJ_TYPE_CLI)
01002 {
01003 retval = dict_getItem((pPmObj_t)((pPmInstance_t)pobj1)->cli_attrs,
01004 PM_NONE,
01005 &pobj2);
01006 PM_RETURN_IF_ERROR(retval);
01007 pobj1 = pobj2;
01008 }
01009 #endif
01010
01011
01012
01013
01014
01015
01016
01017 retval = seq_getLength(pobj1, &t16);
01018 if (retval != PM_RET_OK)
01019 {
01020 GET_ARG();
01021 break;
01022 }
01023
01024
01025 if (t16 != GET_ARG())
01026 {
01027 PM_RAISE(retval, PM_RET_EX_VAL);
01028 break;
01029 }
01030
01031
01032 for (; --t16 >= 0;)
01033 {
01034 retval = seq_getSubscript(pobj1, t16, &pobj2);
01035 PM_BREAK_IF_ERROR(retval);
01036 PM_PUSH(pobj2);
01037 }
01038
01039
01040 PM_BREAK_IF_ERROR(retval);
01041 continue;
01042
01043 case FOR_ITER:
01044 t16 = GET_ARG();
01045
01046 #ifdef HAVE_GENERATORS
01047
01048 if (OBJ_GET_TYPE(TOS) == OBJ_TYPE_CLI)
01049 {
01050
01051 retval = class_getAttr(TOS, PM_NEXT_STR, &pobj1);
01052 PM_BREAK_IF_ERROR(retval);
01053
01054
01055 pobj2 = TOS;
01056 PM_PUSH(pobj1);
01057 PM_PUSH(pobj2);
01058 t16 = 1;
01059
01060
01061 goto CALL_FUNC_FOR_ITER;
01062 }
01063 else
01064 #endif
01065 {
01066
01067 retval = seqiter_getNext(TOS, &pobj2);
01068 }
01069
01070
01071 if (retval == PM_RET_EX_STOP)
01072 {
01073 PM_SP--;
01074 retval = PM_RET_OK;
01075 PM_IP += t16;
01076 continue;
01077 }
01078 PM_BREAK_IF_ERROR(retval);
01079
01080
01081 PM_PUSH(pobj2);
01082 continue;
01083
01084 case STORE_ATTR:
01085
01086
01087 t16 = GET_ARG();
01088
01089
01090 if ((OBJ_GET_TYPE(TOS) == OBJ_TYPE_FXN)
01091 || (OBJ_GET_TYPE(TOS) == OBJ_TYPE_MOD))
01092 {
01093 pobj2 = (pPmObj_t)((pPmFunc_t)TOS)->f_attrs;
01094 }
01095
01096 #ifdef HAVE_CLASSES
01097 else if (OBJ_GET_TYPE(TOS) == OBJ_TYPE_CLO)
01098 {
01099 pobj2 = (pPmObj_t)((pPmClass_t)TOS)->cl_attrs;
01100 }
01101 else if (OBJ_GET_TYPE(TOS) == OBJ_TYPE_CLI)
01102 {
01103 pobj2 = (pPmObj_t)((pPmInstance_t)TOS)->cli_attrs;
01104 }
01105 else if (OBJ_GET_TYPE(TOS) == OBJ_TYPE_MTH)
01106 {
01107 pobj2 = (pPmObj_t)((pPmMethod_t)TOS)->m_attrs;
01108 }
01109 #endif
01110
01111
01112 else
01113 {
01114 PM_RAISE(retval, PM_RET_EX_ATTR);
01115 break;
01116 }
01117
01118
01119 if (OBJ_GET_TYPE(pobj2) != OBJ_TYPE_DIC)
01120 {
01121 PM_RAISE(retval, PM_RET_EX_SYS);
01122 break;
01123 }
01124
01125
01126 pobj3 = PM_FP->fo_func->f_co->co_names->val[t16];
01127
01128
01129 retval = dict_setItem(pobj2, pobj3, TOS1);
01130 PM_BREAK_IF_ERROR(retval);
01131 PM_SP -= 2;
01132 continue;
01133
01134 #ifdef HAVE_DEL
01135 case DELETE_ATTR:
01136
01137
01138 t16 = GET_ARG();
01139
01140
01141 if ((OBJ_GET_TYPE(TOS) == OBJ_TYPE_FXN)
01142 || (OBJ_GET_TYPE(TOS) == OBJ_TYPE_MOD))
01143 {
01144 pobj2 = (pPmObj_t)((pPmFunc_t)TOS)->f_attrs;
01145 }
01146
01147 #ifdef HAVE_CLASSES
01148 else if (OBJ_GET_TYPE(TOS) == OBJ_TYPE_CLO)
01149 {
01150 pobj2 = (pPmObj_t)((pPmClass_t)TOS)->cl_attrs;
01151 }
01152 else if (OBJ_GET_TYPE(TOS) == OBJ_TYPE_CLI)
01153 {
01154 pobj2 = (pPmObj_t)((pPmInstance_t)TOS)->cli_attrs;
01155 }
01156 else if (OBJ_GET_TYPE(TOS) == OBJ_TYPE_MTH)
01157 {
01158 pobj2 = (pPmObj_t)((pPmMethod_t)TOS)->m_attrs;
01159 }
01160 #endif
01161
01162
01163 else
01164 {
01165 PM_RAISE(retval, PM_RET_EX_ATTR);
01166 break;
01167 }
01168
01169
01170 if (OBJ_GET_TYPE(pobj2) != OBJ_TYPE_DIC)
01171 {
01172 PM_RAISE(retval, PM_RET_EX_SYS);
01173 break;
01174 }
01175
01176
01177 pobj3 = PM_FP->fo_func->f_co->co_names->val[t16];
01178
01179
01180 retval = dict_delItem(pobj2, pobj3);
01181
01182
01183 if (retval == PM_RET_EX_KEY)
01184 {
01185 PM_RAISE(retval, PM_RET_EX_ATTR);
01186 }
01187
01188 PM_BREAK_IF_ERROR(retval);
01189 PM_SP--;
01190 continue;
01191 #endif
01192
01193 case STORE_GLOBAL:
01194
01195 t16 = GET_ARG();
01196
01197
01198 pobj2 = PM_FP->fo_func->f_co->co_names->val[t16];
01199
01200
01201 retval = dict_setItem((pPmObj_t)PM_FP->fo_globals, pobj2, TOS);
01202 PM_BREAK_IF_ERROR(retval);
01203 PM_SP--;
01204 continue;
01205
01206 #ifdef HAVE_DEL
01207 case DELETE_GLOBAL:
01208
01209 t16 = GET_ARG();
01210
01211
01212 pobj2 = PM_FP->fo_func->f_co->co_names->val[t16];
01213
01214
01215 retval = dict_delItem((pPmObj_t)PM_FP->fo_globals, pobj2);
01216 PM_BREAK_IF_ERROR(retval);
01217 continue;
01218 #endif
01219
01220 case DUP_TOPX:
01221 t16 = GET_ARG();
01222 C_ASSERT(t16 <= 3);
01223
01224 pobj1 = TOS;
01225 pobj2 = TOS1;
01226 pobj3 = TOS2;
01227 if (t16 >= 3)
01228 PM_PUSH(pobj3);
01229 if (t16 >= 2)
01230 PM_PUSH(pobj2);
01231 if (t16 >= 1)
01232 PM_PUSH(pobj1);
01233 continue;
01234
01235 case LOAD_CONST:
01236
01237 t16 = GET_ARG();
01238
01239
01240 PM_PUSH(PM_FP->fo_func->f_co->co_consts->val[t16]);
01241 continue;
01242
01243 case LOAD_NAME:
01244
01245 t16 = GET_ARG();
01246
01247
01248 pobj1 = PM_FP->fo_func->f_co->co_names->val[t16];
01249
01250
01251 retval = dict_getItem((pPmObj_t)PM_FP->fo_attrs, pobj1, &pobj2);
01252 if (retval == PM_RET_EX_KEY)
01253 {
01254
01255 retval = dict_getItem((pPmObj_t)PM_FP->fo_globals,
01256 pobj1, &pobj2);
01257
01258
01259 if ((retval == PM_RET_EX_KEY) && (PM_PBUILTINS != C_NULL))
01260 {
01261
01262 retval = dict_getItem(PM_PBUILTINS, pobj1, &pobj2);
01263 if (retval == PM_RET_EX_KEY)
01264 {
01265
01266 PM_RAISE(retval, PM_RET_EX_NAME);
01267 break;
01268 }
01269 }
01270 }
01271 PM_BREAK_IF_ERROR(retval);
01272 PM_PUSH(pobj2);
01273 continue;
01274
01275 case BUILD_TUPLE:
01276
01277 t16 = GET_ARG();
01278 retval = tuple_new(t16, &pobj1);
01279 PM_BREAK_IF_ERROR(retval);
01280
01281
01282 for (; --t16 >= 0;)
01283 {
01284 ((pPmTuple_t)pobj1)->val[t16] = PM_POP();
01285 }
01286 PM_PUSH(pobj1);
01287 continue;
01288
01289 case BUILD_LIST:
01290 t16 = GET_ARG();
01291 retval = list_new(&pobj1);
01292 PM_BREAK_IF_ERROR(retval);
01293 for (; --t16 >= 0;)
01294 {
01295
01296 heap_gcPushTempRoot(pobj1, &objid);
01297 retval = list_insert(pobj1, 0, TOS);
01298 heap_gcPopTempRoot(objid);
01299 PM_BREAK_IF_ERROR(retval);
01300 PM_SP--;
01301 }
01302
01303 PM_BREAK_IF_ERROR(retval);
01304
01305
01306 PM_PUSH(pobj1);
01307 continue;
01308
01309 case BUILD_MAP:
01310
01311 t16 = GET_ARG();
01312 retval = dict_new(&pobj1);
01313 PM_BREAK_IF_ERROR(retval);
01314 PM_PUSH(pobj1);
01315 continue;
01316
01317 case LOAD_ATTR:
01318
01319 t16 = GET_ARG();
01320
01321
01322 if ((OBJ_GET_TYPE(TOS) == OBJ_TYPE_FXN) ||
01323 (OBJ_GET_TYPE(TOS) == OBJ_TYPE_MOD))
01324 {
01325 pobj1 = (pPmObj_t)((pPmFunc_t)TOS)->f_attrs;
01326 }
01327
01328 #ifdef HAVE_CLASSES
01329 else if (OBJ_GET_TYPE(TOS) == OBJ_TYPE_CLO)
01330 {
01331 pobj1 = (pPmObj_t)((pPmClass_t)TOS)->cl_attrs;
01332 }
01333 else if (OBJ_GET_TYPE(TOS) == OBJ_TYPE_CLI)
01334 {
01335 pobj1 = (pPmObj_t)((pPmInstance_t)TOS)->cli_attrs;
01336 }
01337 else if (OBJ_GET_TYPE(TOS) == OBJ_TYPE_MTH)
01338 {
01339 pobj1 = (pPmObj_t)((pPmMethod_t)TOS)->m_attrs;
01340 }
01341 #endif
01342
01343
01344 else
01345 {
01346 PM_RAISE(retval, PM_RET_EX_ATTR);
01347 break;
01348 }
01349
01350
01351 if (OBJ_GET_TYPE(pobj1) != OBJ_TYPE_DIC)
01352 {
01353 PM_RAISE(retval, PM_RET_EX_SYS);
01354 break;
01355 }
01356
01357
01358 pobj2 = PM_FP->fo_func->f_co->co_names->val[t16];
01359
01360
01361 retval = dict_getItem(pobj1, pobj2, &pobj3);
01362
01363 #ifdef HAVE_CLASSES
01364
01365
01366
01367
01368 if ((retval == PM_RET_EX_KEY) &&
01369 ((OBJ_GET_TYPE(TOS) == OBJ_TYPE_CLO)
01370 || (OBJ_GET_TYPE(TOS) == OBJ_TYPE_CLI)))
01371 {
01372 retval = class_getAttr(TOS, pobj2, &pobj3);
01373 }
01374 #endif
01375
01376
01377 if (retval == PM_RET_EX_KEY)
01378 {
01379 PM_RAISE(retval, PM_RET_EX_ATTR);
01380 }
01381 PM_BREAK_IF_ERROR(retval);
01382
01383 #ifdef HAVE_CLASSES
01384
01385 if ((OBJ_GET_TYPE(TOS) == OBJ_TYPE_CLI) &&
01386 (OBJ_GET_TYPE(pobj3) == OBJ_TYPE_FXN))
01387 {
01388 pobj2 = pobj3;
01389 retval = class_method(TOS, pobj2, &pobj3);
01390 PM_BREAK_IF_ERROR(retval);
01391 }
01392 #endif
01393
01394
01395 TOS = pobj3;
01396 continue;
01397
01398 case COMPARE_OP:
01399 retval = PM_RET_OK;
01400 t16 = GET_ARG();
01401
01402 #ifdef HAVE_FLOAT
01403 if ((OBJ_GET_TYPE(TOS) == OBJ_TYPE_FLT)
01404 || (OBJ_GET_TYPE(TOS1) == OBJ_TYPE_FLT))
01405 {
01406 retval = float_compare(TOS1, TOS, &pobj3, (PmCompare_t)t16);
01407 PM_SP--;
01408 TOS = pobj3;
01409 continue;
01410 }
01411 #endif
01412
01413
01414 if (((OBJ_GET_TYPE(TOS) == OBJ_TYPE_INT)
01415 || (OBJ_GET_TYPE(TOS) == OBJ_TYPE_BOOL))
01416 && ((OBJ_GET_TYPE(TOS1) == OBJ_TYPE_INT)
01417 || (OBJ_GET_TYPE(TOS1) == OBJ_TYPE_BOOL)))
01418 {
01419 int32_t a = ((pPmInt_t)TOS1)->val;
01420 int32_t b = ((pPmInt_t)TOS)->val;
01421
01422 switch (t16)
01423 {
01424
01425 case COMP_LT: t8 = (int8_t)(a < b); break;
01426 case COMP_LE: t8 = (int8_t)(a <= b); break;
01427 case COMP_EQ: t8 = (int8_t)(a == b); break;
01428 case COMP_NE: t8 = (int8_t)(a != b); break;
01429 case COMP_GT: t8 = (int8_t)(a > b); break;
01430 case COMP_GE: t8 = (int8_t)(a >= b); break;
01431 case COMP_IS: t8 = (int8_t)(TOS == TOS1); break;
01432 case COMP_IS_NOT: t8 = (int8_t)(TOS != TOS1);break;
01433 case COMP_IN:
01434 case COMP_NOT_IN:
01435 PM_RAISE(retval, PM_RET_EX_TYPE);
01436 break;
01437
01438 default:
01439
01440 PM_RAISE(retval, PM_RET_EX_SYS);
01441 break;
01442
01443 }
01444 PM_BREAK_IF_ERROR(retval);
01445 pobj3 = (t8) ? PM_TRUE : PM_FALSE;
01446 }
01447
01448
01449 else
01450 {
01451 retval = PM_RET_OK;
01452 switch (t16)
01453 {
01454 case COMP_EQ:
01455 case COMP_NE:
01456
01457 pobj3 = PM_FALSE;
01458 t8 = obj_compare(TOS, TOS1);
01459 if (((t8 == C_SAME) && (t16 == COMP_EQ))
01460 || ((t8 == C_DIFFER) && (t16 == COMP_NE)))
01461 {
01462 pobj3 = PM_TRUE;
01463 }
01464 break;
01465
01466 case COMP_IN:
01467 case COMP_NOT_IN:
01468
01469 pobj3 = PM_FALSE;
01470 retval = obj_isIn(TOS, TOS1);
01471 if (retval == PM_RET_OK)
01472 {
01473 if (t16 == COMP_IN)
01474 {
01475 pobj3 = PM_TRUE;
01476 }
01477 }
01478 else if (retval == PM_RET_NO)
01479 {
01480 retval = PM_RET_OK;
01481 if (t16 == COMP_NOT_IN)
01482 {
01483 pobj3 = PM_TRUE;
01484 }
01485 }
01486 break;
01487
01488 default:
01489
01490 PM_RAISE(retval, PM_RET_EX_SYS);
01491 break;
01492 }
01493 PM_BREAK_IF_ERROR(retval);
01494 }
01495 PM_SP--;
01496 TOS = pobj3;
01497 continue;
01498
01499 case IMPORT_NAME:
01500
01501 t16 = GET_ARG();
01502
01503
01504 pobj1 = PM_FP->fo_func->f_co->co_names->val[t16];
01505
01506
01507 PM_SP--;
01508
01509
01510 C_ASSERT(obj_compare(TOS, PM_NEGONE) == C_SAME);
01511
01512
01513
01514 retval =
01515 dict_getItem((pPmObj_t)PM_FP->fo_globals, pobj1, &pobj2);
01516 if ((retval == PM_RET_OK)
01517 && (OBJ_GET_TYPE(pobj2) == OBJ_TYPE_MOD))
01518 {
01519 TOS = pobj2;
01520 continue;
01521 }
01522
01523
01524 retval = mod_import(pobj1, &pobj2);
01525 PM_BREAK_IF_ERROR(retval);
01526
01527
01528 TOS = pobj2;
01529
01530
01531
01532 heap_gcPushTempRoot(pobj2, &objid);
01533 retval = frame_new(pobj2, &pobj3);
01534 heap_gcPopTempRoot(objid);
01535 PM_BREAK_IF_ERROR(retval);
01536
01537
01538
01539
01540 ((pPmFrame_t)pobj3)->fo_back = PM_FP;
01541
01542
01543 ((pPmFrame_t)pobj3)->fo_isImport = (uint8_t)1;
01544
01545
01546 PM_FP = (pPmFrame_t)pobj3;
01547 continue;
01548
01549 #ifdef HAVE_IMPORTS
01550 case IMPORT_FROM:
01551
01552
01553 C_ASSERT(OBJ_GET_TYPE(TOS) == OBJ_TYPE_MOD);
01554 pobj1 = TOS;
01555
01556
01557 t16 = GET_ARG();
01558 pobj2 = PM_FP->fo_func->f_co->co_names->val[t16];
01559
01560
01561 retval = dict_getItem((pPmObj_t)((pPmFunc_t)pobj1)->f_attrs,
01562 pobj2, &pobj3);
01563 PM_BREAK_IF_ERROR(retval);
01564
01565
01566 PM_PUSH(pobj3);
01567 continue;
01568 #endif
01569
01570 case JUMP_FORWARD:
01571 t16 = GET_ARG();
01572 PM_IP += t16;
01573 continue;
01574
01575 case JUMP_IF_FALSE:
01576 t16 = GET_ARG();
01577 if (obj_isFalse(TOS))
01578 {
01579 PM_IP += t16;
01580 }
01581 continue;
01582
01583 case JUMP_IF_TRUE:
01584 t16 = GET_ARG();
01585 if (!obj_isFalse(TOS))
01586 {
01587 PM_IP += t16;
01588 }
01589 continue;
01590
01591 case JUMP_ABSOLUTE:
01592 case CONTINUE_LOOP:
01593
01594 t16 = GET_ARG();
01595
01596
01597 PM_IP = PM_FP->fo_func->f_co->co_codeaddr + t16;
01598 continue;
01599
01600 case LOAD_GLOBAL:
01601
01602 t16 = GET_ARG();
01603 pobj1 = PM_FP->fo_func->f_co->co_names->val[t16];
01604
01605
01606 retval = dict_getItem((pPmObj_t)PM_FP->fo_globals,
01607 pobj1, &pobj2);
01608
01609
01610 if (retval == PM_RET_EX_KEY)
01611 {
01612 retval = dict_getItem(PM_PBUILTINS, pobj1, &pobj2);
01613
01614
01615 if (retval == PM_RET_EX_KEY)
01616 {
01617 PM_RAISE(retval, PM_RET_EX_NAME);
01618 break;
01619 }
01620 }
01621 PM_BREAK_IF_ERROR(retval);
01622 PM_PUSH(pobj2);
01623 continue;
01624
01625 case SETUP_LOOP:
01626 {
01627 uint8_t *pchunk;
01628
01629
01630 t16 = GET_ARG();
01631
01632
01633 retval = heap_getChunk(sizeof(PmBlock_t), &pchunk);
01634 PM_BREAK_IF_ERROR(retval);
01635 pobj1 = (pPmObj_t)pchunk;
01636 OBJ_SET_TYPE(pobj1, OBJ_TYPE_BLK);
01637
01638
01639 ((pPmBlock_t)pobj1)->b_sp = PM_SP;
01640
01641
01642 ((pPmBlock_t)pobj1)->b_handler = PM_IP + t16;
01643 ((pPmBlock_t)pobj1)->b_type = B_LOOP;
01644
01645
01646 ((pPmBlock_t)pobj1)->next = PM_FP->fo_blockstack;
01647 PM_FP->fo_blockstack = (pPmBlock_t)pobj1;
01648 continue;
01649 }
01650
01651 case LOAD_FAST:
01652 t16 = GET_ARG();
01653 PM_PUSH(PM_FP->fo_locals[t16]);
01654 continue;
01655
01656 case STORE_FAST:
01657 t16 = GET_ARG();
01658 PM_FP->fo_locals[t16] = PM_POP();
01659 continue;
01660
01661 #ifdef HAVE_DEL
01662 case DELETE_FAST:
01663 t16 = GET_ARG();
01664 PM_FP->fo_locals[t16] = PM_NONE;
01665 continue;
01666 #endif
01667
01668 #ifdef HAVE_ASSERT
01669 case RAISE_VARARGS:
01670 t16 = GET_ARG();
01671
01672
01673 if (t16 != 1)
01674 {
01675 PM_RAISE(retval, PM_RET_EX_SYS);
01676 break;
01677 }
01678
01679
01680 retval = dict_getItem(PM_PBUILTINS, PM_EXCEPTION_STR, &pobj2);
01681 if (retval != PM_RET_OK)
01682 {
01683 PM_RAISE(retval, PM_RET_EX_SYS);
01684 break;
01685 }
01686
01687
01688 pobj1 = TOS;
01689 if ((OBJ_GET_TYPE(pobj1) != OBJ_TYPE_CLO)
01690 || !class_isSubclass(pobj1, pobj2))
01691 {
01692 PM_RAISE(retval, PM_RET_EX_TYPE);
01693 break;
01694 }
01695
01696
01697 TOS = PM_NONE;
01698 PM_PUSH(PM_NONE);
01699 PM_PUSH(pobj1);
01700
01701
01702 retval = dict_getItem((pPmObj_t)((pPmClass_t)pobj1)->cl_attrs,
01703 PM_CODE_STR, &pobj2);
01704 PM_BREAK_IF_ERROR(retval);
01705
01706
01707 PM_RAISE(retval, (PmReturn_t)(((pPmInt_t)pobj2)->val & 0xFF));
01708 break;
01709 #endif
01710
01711 case CALL_FUNCTION:
01712
01713 t16 = GET_ARG();
01714
01715
01716 if ((t16 & (uint16_t)0xFF00) != 0)
01717 {
01718 PM_RAISE(retval, PM_RET_EX_SYS);
01719 break;
01720 }
01721
01722
01723 pobj1 = STACK(t16);
01724
01725
01726 heap_gcPushTempRoot(pobj1, &objid);
01727
01728 C_DEBUG_PRINT(VERBOSITY_LOW,
01729 "interpret(), CALL_FUNCTION on <obj type=%d @ %p>\n",
01730 OBJ_GET_TYPE(pobj1), pobj1);
01731
01732 #ifdef HAVE_GENERATORS
01733
01734 if ((OBJ_GET_TYPE(pobj1) == OBJ_TYPE_FXN)
01735 && (OBJ_GET_TYPE(((pPmFunc_t)pobj1)->f_co) == OBJ_TYPE_COB)
01736 && (((pPmFunc_t)pobj1)->f_co->co_flags & CO_GENERATOR))
01737 {
01738 #ifdef HAVE_DEFAULTARGS
01739
01740 t8 = ((pPmFunc_t)pobj1)->f_co->co_argcount;
01741 if (((pPmFunc_t)pobj1)->f_defaultargs != C_NULL)
01742 {
01743 t8 -= ((pPmTuple_t)((pPmFunc_t)pobj1)->f_defaultargs)->
01744 length;
01745 }
01746
01747
01748
01749
01750
01751 if (((t16 & ((uint8_t)0xFF))
01752 > ((pPmFunc_t)pobj1)->f_co->co_argcount)
01753 || ((t16 & ((uint8_t)0xFF)) < t8))
01754 #else
01755 if ((t16 & ((uint8_t)0xFF)) !=
01756 ((pPmFunc_t)pobj1)->f_co->co_argcount)
01757 #endif
01758 {
01759 PM_RAISE(retval, PM_RET_EX_TYPE);
01760 break;
01761 }
01762
01763
01764 retval = tuple_new(t16 + 1, &pobj2);
01765 heap_gcPushTempRoot(pobj2, &objid2);
01766 PM_GOTO_IF_ERROR(retval, CALL_FUNC_CLEANUP);
01767 sli_memcpy((uint8_t *)&((pPmTuple_t)pobj2)->val,
01768 (uint8_t *)&STACK(t16),
01769 (t16 + 1) * sizeof(pPmObj_t));
01770
01771
01772 PM_SP -= t16;
01773 PM_PUSH(pobj2);
01774 t16 = 1;
01775
01776
01777 retval = dict_getItem(PM_PBUILTINS, PM_GENERATOR_STR,
01778 &pobj1);
01779 C_ASSERT(retval == PM_RET_OK);
01780 STACK(t16) = pobj1;
01781 }
01782 #endif
01783
01784 #ifdef HAVE_CLASSES
01785
01786 if (OBJ_GET_TYPE(pobj1) == OBJ_TYPE_CLO)
01787 {
01788
01789 bc = 0;
01790
01791
01792 retval = class_instantiate(pobj1, &pobj2);
01793 heap_gcPushTempRoot(pobj2, &objid2);
01794 STACK(t16) = pobj2;
01795
01796
01797 pobj3 = C_NULL;
01798 retval = class_getAttr(pobj1, PM_INIT_STR, &pobj3);
01799 if (retval == PM_RET_EX_KEY)
01800 {
01801
01802 if (t16 > 0)
01803 {
01804 PM_RAISE(retval, PM_RET_EX_TYPE);
01805 goto CALL_FUNC_CLEANUP;
01806 }
01807
01808
01809 heap_gcPopTempRoot(objid);
01810 continue;
01811 }
01812 else if (retval != PM_RET_OK)
01813 {
01814 PM_GOTO_IF_ERROR(retval, CALL_FUNC_CLEANUP);
01815 }
01816
01817
01818 PM_SP++;
01819 for (t8 = 0; t8 < t16; t8++)
01820 {
01821 STACK(t8) = STACK(t8 + 1);
01822 }
01823
01824
01825 retval = class_method(pobj2, pobj3, &pobj1);
01826 PM_GOTO_IF_ERROR(retval, CALL_FUNC_CLEANUP);
01827 heap_gcPushTempRoot(pobj2, &objid2);
01828 STACK(t16) = pobj1;
01829
01830 }
01831
01832 if (OBJ_GET_TYPE(pobj1) == OBJ_TYPE_MTH)
01833 {
01834
01835 STACK(t16) = (pPmObj_t)((pPmMethod_t)pobj1)->m_func;
01836
01837
01838 PM_SP++;
01839 for (t8 = 0; t8 < t16; t8++)
01840 {
01841 STACK(t8) = STACK(t8 + 1);
01842 }
01843
01844
01845 STACK(t16++) = (pPmObj_t)((pPmMethod_t)pobj1)->m_instance;
01846
01847
01848 pobj1 = (pPmObj_t)((pPmMethod_t)pobj1)->m_func;
01849 }
01850 #endif
01851
01852 #ifdef HAVE_GENERATORS
01853 CALL_FUNC_FOR_ITER:
01854 #endif
01855
01856 if (OBJ_GET_TYPE(pobj1) != OBJ_TYPE_FXN)
01857 {
01858 PM_RAISE(retval, PM_RET_EX_TYPE);
01859 goto CALL_FUNC_CLEANUP;
01860 }
01861
01862
01863 if (OBJ_GET_TYPE(((pPmFunc_t)pobj1)->f_co) == OBJ_TYPE_COB)
01864 {
01865
01866
01867
01868
01869
01870 #ifdef HAVE_DEFAULTARGS
01871
01872 t8 = ((pPmFunc_t)pobj1)->f_co->co_argcount;
01873 if (((pPmFunc_t)pobj1)->f_defaultargs != C_NULL)
01874 {
01875 t8 -= ((pPmTuple_t)((pPmFunc_t)pobj1)->f_defaultargs)->
01876 length;
01877 }
01878
01879
01880
01881
01882
01883 if (((t16 & ((uint8_t)0xFF))
01884 > ((pPmFunc_t)pobj1)->f_co->co_argcount)
01885 || ((t16 & ((uint8_t)0xFF)) < t8))
01886 #else
01887 if ((t16 & ((uint8_t)0xFF)) !=
01888 ((pPmFunc_t)pobj1)->f_co->co_argcount)
01889 #endif
01890 {
01891 PM_RAISE(retval, PM_RET_EX_TYPE);
01892 break;
01893 }
01894
01895
01896 retval = frame_new(pobj1, &pobj2);
01897 heap_gcPushTempRoot(pobj2, &objid2);
01898 PM_GOTO_IF_ERROR(retval, CALL_FUNC_CLEANUP);
01899
01900 #ifdef HAVE_CLASSES
01901
01902
01903
01904
01905
01906 if (bc == 0)
01907 {
01908 ((pPmFrame_t)pobj2)->fo_isInit = C_TRUE;
01909 }
01910 #endif
01911
01912 #ifdef HAVE_DEFAULTARGS
01913
01914 if (((pPmFunc_t)pobj1)->f_defaultargs != C_NULL)
01915 {
01916 int8_t i = 0;
01917
01918
01919 for ( ;
01920 t8 < ((pPmFunc_t)pobj1)->f_co->co_argcount; t8++)
01921 {
01922 ((pPmFrame_t)pobj2)->fo_locals[t8] =
01923 ((pPmTuple_t)((pPmFunc_t)pobj1)->
01924 f_defaultargs)->val[i++];
01925 }
01926 }
01927 #endif
01928
01929
01930 while (--t16 >= 0)
01931 {
01932
01933
01934
01935
01936 ((pPmFrame_t)pobj2)->fo_locals[t16] = PM_POP();
01937 }
01938
01939 #ifdef HAVE_CLOSURES
01940
01941
01942 if (((pPmFunc_t)pobj1)->f_co->co_cellvars != C_NULL)
01943 {
01944 for (t8 = 0;
01945 t8 < ((pPmFunc_t)pobj1)->f_co->co_cellvars->length;
01946 t8++)
01947 {
01948 if (((pPmInt_t)((pPmFunc_t)pobj1)->
01949 f_co->co_cellvars->val[t8])->val >= 0)
01950 {
01951 ((pPmFrame_t)pobj2)->fo_locals[
01952 ((pPmFunc_t)pobj1)->f_co->co_nlocals + t8] =
01953 ((pPmFrame_t)pobj2)->fo_locals[
01954 ((pPmInt_t)(((pPmFunc_t)pobj1)->
01955 f_co->co_cellvars->val[t8]))->val
01956 ];
01957 }
01958 }
01959 }
01960
01961
01962 for (t8 = 0;
01963 t8 < ((pPmFunc_t)pobj1)->f_co->co_nfreevars;
01964 t8++)
01965 {
01966 C_ASSERT(((pPmFunc_t)pobj1)->f_closure != C_NULL);
01967 ((pPmFrame_t)pobj2)->fo_locals[
01968 ((pPmFunc_t)pobj1)->f_co->co_nlocals
01969 + ((((pPmFunc_t)pobj1)->f_co->co_cellvars == C_NULL) ? 0 : ((pPmFunc_t)pobj1)->f_co->co_cellvars->length)
01970 + t8] = ((pPmFunc_t)pobj1)->f_closure->val[t8];
01971 }
01972 #endif
01973
01974
01975 pobj3 = PM_POP();
01976
01977
01978 ((pPmFrame_t)pobj2)->fo_back = PM_FP;
01979
01980
01981 PM_FP = (pPmFrame_t)pobj2;
01982 }
01983
01984
01985 else if (OBJ_GET_TYPE(((pPmFunc_t)pobj1)->f_co) ==
01986 OBJ_TYPE_NOB)
01987 {
01988
01989 gVmGlobal.nativeframe.nf_numlocals = (uint8_t)t16;
01990
01991
01992 while (--t16 >= 0)
01993 {
01994 gVmGlobal.nativeframe.nf_locals[t16] = PM_POP();
01995 }
01996
01997 #ifdef HAVE_GC
01998
01999 if (heap_getAvail() < HEAP_GC_NF_THRESHOLD)
02000 {
02001 retval = heap_gcRun();
02002 PM_GOTO_IF_ERROR(retval, CALL_FUNC_CLEANUP);
02003 }
02004 #endif
02005
02006
02007 PM_SP--;
02008
02009
02010 pobj2 = (pPmObj_t)((pPmFunc_t)pobj1)->f_co;
02011 t16 = ((pPmNo_t)pobj2)->no_funcindx;
02012
02013
02014 gVmGlobal.nativeframe.nf_active = C_TRUE;
02015
02016
02017
02018
02019
02020 if (t16 >= 0)
02021 {
02022 retval = std_nat_fxn_table[t16] (&PM_FP);
02023 }
02024
02025
02026 else
02027 {
02028 retval = usr_nat_fxn_table[-t16] (&PM_FP);
02029 }
02030
02031
02032
02033
02034
02035
02036 gVmGlobal.nativeframe.nf_active = C_FALSE;
02037
02038 #ifdef HAVE_CLASSES
02039
02040 if (bc == 0)
02041 {
02042
02043 if ((retval == PM_RET_OK)
02044 && (gVmGlobal.nativeframe.nf_stack != PM_NONE))
02045 {
02046 PM_RAISE(retval, PM_RET_EX_TYPE);
02047 goto CALL_FUNC_CLEANUP;
02048 }
02049 }
02050 else
02051 #endif
02052
02053
02054 if (retval == PM_RET_FRAME_SWITCH)
02055 {
02056 retval = PM_RET_OK;
02057 }
02058
02059
02060 else
02061 {
02062 PM_PUSH(gVmGlobal.nativeframe.nf_stack);
02063 }
02064 }
02065 CALL_FUNC_CLEANUP:
02066 heap_gcPopTempRoot(objid);
02067 PM_BREAK_IF_ERROR(retval);
02068 continue;
02069
02070 case MAKE_FUNCTION:
02071
02072 t16 = GET_ARG();
02073
02074
02075
02076
02077
02078
02079 retval = func_new(TOS, (pPmObj_t)PM_FP->fo_globals, &pobj2);
02080 PM_BREAK_IF_ERROR(retval);
02081
02082
02083 if (t16 > 0)
02084 {
02085
02086 #ifdef HAVE_DEFAULTARGS
02087 heap_gcPushTempRoot(pobj2, &objid);
02088 retval = tuple_new(t16, &pobj3);
02089 heap_gcPopTempRoot(objid);
02090 PM_BREAK_IF_ERROR(retval);
02091 PM_SP--;
02092 while (--t16 >= 0)
02093 {
02094 ((pPmTuple_t)pobj3)->val[t16] = PM_POP();
02095 }
02096
02097
02098 ((pPmFunc_t)pobj2)->f_defaultargs = (pPmTuple_t)pobj3;
02099 #else
02100
02101 PM_RAISE(retval, PM_RET_EX_SYS);
02102 break;
02103 #endif
02104
02105 }
02106 else
02107 {
02108 PM_SP--;
02109 }
02110
02111
02112 PM_PUSH(pobj2);
02113 continue;
02114
02115 #ifdef HAVE_CLOSURES
02116 case MAKE_CLOSURE:
02117
02118 t16 = GET_ARG();
02119 retval = func_new(TOS, (pPmObj_t)PM_FP->fo_globals, &pobj2);
02120 PM_BREAK_IF_ERROR(retval);
02121
02122
02123 ((pPmFunc_t)pobj2)->f_closure = (pPmTuple_t)TOS1;
02124 PM_SP -= 2;
02125
02126
02127 if (t16 > 0)
02128 {
02129 heap_gcPushTempRoot(pobj2, &objid);
02130 retval = tuple_new(t16, &pobj3);
02131 heap_gcPopTempRoot(objid);
02132 PM_BREAK_IF_ERROR(retval);
02133
02134 while (--t16 >= 0)
02135 {
02136 ((pPmTuple_t)pobj3)->val[t16] = PM_POP();
02137 }
02138 ((pPmFunc_t)pobj2)->f_defaultargs = (pPmTuple_t)pobj3;
02139 }
02140
02141
02142 PM_PUSH(pobj2);
02143 continue;
02144
02145 case LOAD_CLOSURE:
02146 case LOAD_DEREF:
02147
02148 t16 = GET_ARG();
02149 pobj1 = PM_FP->fo_locals[PM_FP->fo_func->f_co->co_nlocals + t16];
02150 if (pobj1 == C_NULL)
02151 {
02152 PM_RAISE(retval, PM_RET_EX_SYS);
02153 break;
02154 }
02155 PM_PUSH(pobj1);
02156 continue;
02157
02158 case STORE_DEREF:
02159
02160 t16 = GET_ARG();
02161 PM_FP->fo_locals[PM_FP->fo_func->f_co->co_nlocals + t16] = PM_POP();
02162 continue;
02163 #endif
02164
02165
02166 default:
02167
02168 PM_RAISE(retval, PM_RET_EX_SYS);
02169 break;
02170 }
02171
02172 #ifdef HAVE_GENERATORS
02173
02174 if (retval == PM_RET_EX_STOP)
02175 {
02176 pobj1 = (pPmObj_t)PM_FP;
02177 while ((retval == PM_RET_EX_STOP) && (pobj1 != C_NULL))
02178 {
02179 pobj2 = (pPmObj_t)((pPmFrame_t)pobj1)->fo_blockstack;
02180 while ((retval == PM_RET_EX_STOP) && (pobj2 != C_NULL))
02181 {
02182 if (((pPmBlock_t)pobj2)->b_type == B_LOOP)
02183 {
02184
02185
02186 PM_FP = (pPmFrame_t)pobj1;
02187 PM_SP = ((pPmBlock_t)pobj2)->b_sp;
02188 PM_IP = ((pPmBlock_t)pobj2)->b_handler;
02189 ((pPmFrame_t)pobj1)->fo_blockstack =
02190 ((pPmFrame_t)pobj1)->fo_blockstack->next;
02191 retval = PM_RET_OK;
02192 break;
02193 }
02194
02195 pobj2 = (pPmObj_t)((pPmBlock_t)pobj2)->next;
02196 }
02197 pobj1 = (pPmObj_t)((pPmFrame_t)pobj1)->fo_back;
02198 }
02199 if (retval == PM_RET_OK)
02200 {
02201 continue;
02202 }
02203 }
02204 #endif
02205
02206
02207
02208
02209
02210
02211
02212 PM_REPORT_IF_ERROR(retval);
02213
02214
02215 if ((gVmGlobal.threadList->length <= 1) && (retval != PM_RET_OK))
02216 {
02217 break;
02218 }
02219
02220 retval = list_remove((pPmObj_t)gVmGlobal.threadList,
02221 (pPmObj_t)gVmGlobal.pthread);
02222 gVmGlobal.pthread = C_NULL;
02223 PM_BREAK_IF_ERROR(retval);
02224
02225 retval = interp_reschedule();
02226 PM_BREAK_IF_ERROR(retval);
02227 }
02228
02229 return retval;
02230 }
02231
02232
02233 PmReturn_t
02234 interp_reschedule(void)
02235 {
02236 PmReturn_t retval = PM_RET_OK;
02237 static uint8_t threadIndex = (uint8_t)0;
02238 pPmObj_t pobj;
02239
02240
02241 if (gVmGlobal.threadList->length == 0)
02242 {
02243 gVmGlobal.pthread = C_NULL;
02244 }
02245
02246
02247 else
02248 {
02249 if (++threadIndex >= gVmGlobal.threadList->length)
02250 {
02251 threadIndex = (uint8_t)0;
02252 }
02253 retval = list_getItem((pPmObj_t)gVmGlobal.threadList, threadIndex,
02254 &pobj);
02255 gVmGlobal.pthread = (pPmThread_t)pobj;
02256 PM_RETURN_IF_ERROR(retval);
02257 }
02258
02259
02260 interp_setRescheduleFlag(0);
02261 return retval;
02262 }
02263
02264
02265 PmReturn_t
02266 interp_addThread(pPmFunc_t pfunc)
02267 {
02268 PmReturn_t retval;
02269 pPmObj_t pframe;
02270 pPmObj_t pthread;
02271 uint8_t objid1, objid2;
02272
02273
02274 retval = frame_new((pPmObj_t)pfunc, &pframe);
02275 PM_RETURN_IF_ERROR(retval);
02276
02277
02278 heap_gcPushTempRoot(pframe, &objid1);
02279 retval = thread_new(pframe, &pthread);
02280 if (retval != PM_RET_OK)
02281 {
02282 heap_gcPopTempRoot(objid1);
02283 return retval;
02284 }
02285
02286
02287 heap_gcPushTempRoot(pthread, &objid2);
02288 retval = list_append((pPmObj_t)gVmGlobal.threadList, pthread);
02289 heap_gcPopTempRoot(objid1);
02290 return retval;
02291 }
02292
02293
02294 void
02295 interp_setRescheduleFlag(uint8_t boolean)
02296 {
02297 gVmGlobal.reschedule = boolean;
02298 }