Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of pymite by
pmstdlib_nat.cpp
00001 #undef __FILE_ID__ 00002 #define __FILE_ID__ 0x0A 00003 /** 00004 * PyMite std native function file 00005 * 00006 * automatically created by pmImgCreator.py 00007 * on Sat Mar 02 20:27:03 2013 00008 * 00009 * DO NOT EDIT THIS FILE. 00010 * ANY CHANGES WILL BE LOST. 00011 * 00012 * @file pmstdlib_nat.cpp 00013 */ 00014 00015 #define __IN_LIBNATIVE_C__ 00016 #include "pm.h" 00017 00018 /* From: ../../lib/string.py */ 00019 #include <stdlib.h> 00020 #include <string.h> 00021 00022 PmReturn_t 00023 nat_00___bi_chr(pPmFrame_t *ppframe) 00024 { 00025 00026 pPmObj_t ps; 00027 pPmObj_t pn; 00028 int32_t n; 00029 PmReturn_t retval; 00030 00031 /* If wrong number of args, raise TypeError */ 00032 if (NATIVE_GET_NUM_ARGS() != 1) 00033 { 00034 PM_RAISE(retval, PM_RET_EX_TYPE); 00035 return retval; 00036 } 00037 00038 /* Raise TypeError if arg is not an int */ 00039 pn = NATIVE_GET_LOCAL(0); 00040 if (OBJ_GET_TYPE(pn) != OBJ_TYPE_INT) 00041 { 00042 PM_RAISE(retval, PM_RET_EX_TYPE); 00043 return retval; 00044 } 00045 00046 /* Raise ValueError if arg is not int within range(256) */ 00047 n = ((pPmInt_t)pn)->val; 00048 if ((n < 0) || (n > 255)) 00049 { 00050 PM_RAISE(retval, PM_RET_EX_VAL); 00051 return retval; 00052 } 00053 00054 /* Create char string from integer value */ 00055 retval = string_newFromChar((uint8_t)n, &ps); 00056 NATIVE_SET_TOS(ps); 00057 return retval; 00058 00059 } 00060 00061 PmReturn_t 00062 nat_01___bi_dir(pPmFrame_t *ppframe) 00063 { 00064 00065 PmReturn_t retval = PM_RET_OK; 00066 pPmObj_t po; 00067 pPmObj_t pk; 00068 pPmObj_t pl; 00069 pSeglist_t psl; 00070 int16_t i; 00071 uint8_t objid; 00072 00073 /* Use globals if no arg given */ 00074 if (NATIVE_GET_NUM_ARGS() == 0) 00075 { 00076 /* Get the globals dict */ 00077 po = (pPmObj_t)NATIVE_GET_PFRAME()->fo_globals; 00078 } 00079 00080 /* Otherwise use the given arg */ 00081 else if (NATIVE_GET_NUM_ARGS() == 1) 00082 { 00083 po = NATIVE_GET_LOCAL(0); 00084 00085 /* If object is a function or module, use its attrs dict */ 00086 if ((OBJ_GET_TYPE(po) == OBJ_TYPE_FXN) 00087 || (OBJ_GET_TYPE(po) == OBJ_TYPE_MOD)) 00088 { 00089 po = (pPmObj_t)((pPmFunc_t)po)->f_attrs; 00090 } 00091 00092 #ifdef HAVE_CLASSES 00093 else if (OBJ_GET_TYPE(po) == OBJ_TYPE_CLO) 00094 { 00095 po = (pPmObj_t)((pPmClass_t)po)->cl_attrs; 00096 } 00097 else if (OBJ_GET_TYPE(po) == OBJ_TYPE_CLI) 00098 { 00099 po = (pPmObj_t)((pPmInstance_t)po)->cli_attrs; 00100 } 00101 else if (OBJ_GET_TYPE(po) == OBJ_TYPE_MTH) 00102 { 00103 po = (pPmObj_t)((pPmMethod_t)po)->m_attrs; 00104 } 00105 #endif /* HAVE_CLASSES */ 00106 00107 else 00108 { 00109 po = C_NULL; 00110 } 00111 } 00112 00113 /* Raise TypeError if wrong number of args */ 00114 else 00115 { 00116 PM_RAISE(retval, PM_RET_EX_TYPE); 00117 return retval; 00118 } 00119 00120 if (po == C_NULL) 00121 { 00122 pl = PM_NONE; 00123 } 00124 else 00125 { 00126 /* Create new list */ 00127 retval = list_new(&pl); 00128 PM_RETURN_IF_ERROR(retval); 00129 00130 /* Copy dict's keys to the list */ 00131 psl = ((pPmDict_t)po)->d_keys; 00132 for (i = 0; i < ((pPmDict_t)po)->length; i++) 00133 { 00134 retval = seglist_getItem(psl, i, &pk); 00135 PM_RETURN_IF_ERROR(retval); 00136 heap_gcPushTempRoot(pl, &objid); 00137 retval = list_append(pl, pk); 00138 heap_gcPopTempRoot(objid); 00139 PM_RETURN_IF_ERROR(retval); 00140 } 00141 } 00142 00143 NATIVE_SET_TOS(pl); 00144 return retval; 00145 00146 } 00147 00148 PmReturn_t 00149 nat_02___bi_eval(pPmFrame_t *ppframe) 00150 { 00151 00152 PmReturn_t retval; 00153 pPmObj_t pco; 00154 pPmObj_t pfunc; 00155 pPmObj_t pnewframe; 00156 pPmObj_t pg = C_NULL; 00157 pPmObj_t pl = C_NULL; 00158 uint8_t objid; 00159 00160 /* If wrong number of args, raise TypeError */ 00161 if ((NATIVE_GET_NUM_ARGS() == 0) || (NATIVE_GET_NUM_ARGS() > 3)) 00162 { 00163 PM_RAISE(retval, PM_RET_EX_TYPE); 00164 return retval; 00165 } 00166 00167 /* Raise ValueError if first arg is not a Code Object */ 00168 pco = NATIVE_GET_LOCAL(0); 00169 if (OBJ_GET_TYPE(pco) != OBJ_TYPE_COB) 00170 { 00171 PM_RAISE(retval, PM_RET_EX_VAL); 00172 return retval; 00173 } 00174 00175 /* If 2nd arg exists, raise ValueError if it is not a Dict */ 00176 if (NATIVE_GET_NUM_ARGS() >= 2) 00177 { 00178 pg = NATIVE_GET_LOCAL(1); 00179 if (OBJ_GET_TYPE(pg) != OBJ_TYPE_DIC) 00180 { 00181 PM_RAISE(retval, PM_RET_EX_VAL); 00182 return retval; 00183 } 00184 } 00185 00186 /* If no args are given, use the caller's globals for the function's */ 00187 else 00188 { 00189 pg = (pPmObj_t)NATIVE_GET_PFRAME()->fo_globals; 00190 } 00191 00192 /* If 3rd arg exists, raise ValueError if it is not a Dict */ 00193 if (NATIVE_GET_NUM_ARGS() >= 3) 00194 { 00195 pl = NATIVE_GET_LOCAL(2); 00196 if (OBJ_GET_TYPE(pl) != OBJ_TYPE_DIC) 00197 { 00198 PM_RAISE(retval, PM_RET_EX_VAL); 00199 return retval; 00200 } 00201 } 00202 00203 /* Create func from code object */ 00204 retval = func_new(pco, pg, &pfunc); 00205 PM_RETURN_IF_ERROR(retval); 00206 00207 /* Create frame from module object; globals is set to null */ 00208 heap_gcPushTempRoot(pfunc, &objid); 00209 retval = frame_new(pfunc, &pnewframe); 00210 heap_gcPopTempRoot(objid); 00211 PM_RETURN_IF_ERROR(retval); 00212 00213 /* TODO: Reclaim pnewframe's attrs dict created in frame_new */ 00214 /* 00215 * By default use calling frame's attrs as local namespace. 00216 * This works for ipm because the interactive mode 00217 * needs a locals namespace that persists across calls to eval() 00218 */ 00219 ((pPmFrame_t)pnewframe)->fo_attrs = NATIVE_GET_PFRAME()->fo_attrs; 00220 00221 /* If 2nd arg exists, use it as the global namespace for the new func */ 00222 if (NATIVE_GET_NUM_ARGS() >= 2) 00223 { 00224 ((pPmFrame_t)pnewframe)->fo_globals = (pPmDict_t)pg; 00225 00226 /* If only globals is given, locals defaults to it */ 00227 ((pPmFrame_t)pnewframe)->fo_attrs = (pPmDict_t)pg; 00228 } 00229 00230 /* If 3rd arg exists, use it as the local namespace for the new func */ 00231 if (NATIVE_GET_NUM_ARGS() >= 3) 00232 { 00233 ((pPmFrame_t)pnewframe)->fo_attrs = (pPmDict_t)pl; 00234 } 00235 00236 /* 00237 * Set the fo_back frame so flow returns to eval()'s caller when completed. 00238 * Set the frame pointer so the new frame is interpreted immediately 00239 * after this function returns. 00240 */ 00241 ((pPmFrame_t)pnewframe)->fo_back = NATIVE_GET_PFRAME(); 00242 NATIVE_GET_PFRAME() = (pPmFrame_t)pnewframe; 00243 retval = PM_RET_FRAME_SWITCH; 00244 00245 return retval; 00246 00247 } 00248 00249 PmReturn_t 00250 nat_03___bi_globals(pPmFrame_t *ppframe) 00251 { 00252 00253 pPmObj_t pr = C_NULL; 00254 PmReturn_t retval; 00255 00256 /* If wrong number of args, raise TypeError */ 00257 if (NATIVE_GET_NUM_ARGS() != 0) 00258 { 00259 PM_RAISE(retval, PM_RET_EX_TYPE); 00260 return retval; 00261 } 00262 00263 /* Return calling frame's globals dict on stack*/ 00264 pr = (pPmObj_t)NATIVE_GET_PFRAME()->fo_globals; 00265 NATIVE_SET_TOS(pr); 00266 00267 return PM_RET_OK; 00268 00269 } 00270 00271 PmReturn_t 00272 nat_04___bi_id(pPmFrame_t *ppframe) 00273 { 00274 00275 PmReturn_t retval; 00276 pPmObj_t pr = C_NULL; 00277 00278 /* If wrong number of args, raise TypeError */ 00279 if (NATIVE_GET_NUM_ARGS() != 1) 00280 { 00281 PM_RAISE(retval, PM_RET_EX_TYPE); 00282 return retval; 00283 } 00284 00285 /* Return object's address as an int on the stack */ 00286 retval = int_new((intptr_t)NATIVE_GET_LOCAL(0), &pr); 00287 NATIVE_SET_TOS(pr); 00288 00289 return retval; 00290 00291 } 00292 00293 PmReturn_t 00294 nat_05___bi_len(pPmFrame_t *ppframe) 00295 { 00296 00297 PmReturn_t retval; 00298 pPmObj_t ps = C_NULL; 00299 pPmObj_t pr = C_NULL; 00300 00301 /* If wrong number of args, raise TypeError */ 00302 if (NATIVE_GET_NUM_ARGS() != 1) 00303 { 00304 PM_RAISE(retval, PM_RET_EX_TYPE); 00305 return retval; 00306 } 00307 00308 /* Get first arg */ 00309 ps = NATIVE_GET_LOCAL(0); 00310 00311 #ifdef HAVE_BYTEARRAY 00312 /* If object is an instance, get the thing it contains */ 00313 if (OBJ_GET_TYPE(ps) == OBJ_TYPE_CLI) 00314 { 00315 retval = dict_getItem((pPmObj_t)((pPmInstance_t)ps)->cli_attrs, 00316 PM_NONE, 00317 &pr); 00318 00319 /* If None wasn't in attributes, obj is wrong type for len() */ 00320 if (retval == PM_RET_EX_KEY) retval = PM_RET_EX_TYPE; 00321 PM_RETURN_IF_ERROR(retval); 00322 ps = pr; 00323 } 00324 #endif /* HAVE_BYTEARRAY */ 00325 00326 /* Get the length of the arg based on its type */ 00327 switch (OBJ_GET_TYPE(ps)) 00328 { 00329 case OBJ_TYPE_STR: 00330 retval = int_new(((pPmString_t)ps)->length, &pr); 00331 break; 00332 00333 case OBJ_TYPE_TUP: 00334 retval = int_new(((pPmTuple_t)ps)->length, &pr); 00335 break; 00336 00337 case OBJ_TYPE_LST: 00338 retval = int_new(((pPmList_t)ps)->length, &pr); 00339 break; 00340 00341 case OBJ_TYPE_DIC: 00342 retval = int_new(((pPmDict_t)ps)->length, &pr); 00343 break; 00344 00345 #ifdef HAVE_BYTEARRAY 00346 case OBJ_TYPE_BYA: 00347 retval = int_new(((pPmBytearray_t)ps)->length, &pr); 00348 break; 00349 #endif /* HAVE_BYTEARRAY */ 00350 00351 default: 00352 /* If not a string or sequence type, raise TypeError */ 00353 PM_RAISE(retval, PM_RET_EX_TYPE); 00354 } 00355 00356 NATIVE_SET_TOS(pr); 00357 return retval; 00358 00359 } 00360 00361 PmReturn_t 00362 nat_06___bi_locals(pPmFrame_t *ppframe) 00363 { 00364 00365 pPmObj_t pr = C_NULL; 00366 PmReturn_t retval; 00367 00368 /* If wrong number of args, raise TypeError */ 00369 if (NATIVE_GET_NUM_ARGS() != 0) 00370 { 00371 PM_RAISE(retval, PM_RET_EX_TYPE); 00372 return retval; 00373 } 00374 00375 /* Return calling frame's local attrs dict on the stack */ 00376 pr = (pPmObj_t)NATIVE_GET_PFRAME()->fo_attrs; 00377 NATIVE_SET_TOS(pr); 00378 00379 return PM_RET_OK; 00380 00381 } 00382 00383 PmReturn_t 00384 nat_07___bi_ord(pPmFrame_t *ppframe) 00385 { 00386 00387 pPmObj_t ps; 00388 pPmObj_t pn; 00389 int32_t n; 00390 PmReturn_t retval; 00391 00392 /* If wrong number of args, raise TypeError */ 00393 if (NATIVE_GET_NUM_ARGS() != 1) 00394 { 00395 PM_RAISE(retval, PM_RET_EX_TYPE); 00396 return retval; 00397 } 00398 00399 ps = NATIVE_GET_LOCAL(0); 00400 00401 /* Raise TypeError if arg is not string of length 1 */ 00402 if ((OBJ_GET_TYPE(ps) != OBJ_TYPE_STR) 00403 || (((pPmString_t)ps)->length != 1)) 00404 00405 { 00406 PM_RAISE(retval, PM_RET_EX_TYPE); 00407 return retval; 00408 } 00409 00410 /* Get integer value of character */ 00411 n = ((pPmString_t)ps)->val[0]; 00412 retval = int_new(n, &pn); 00413 NATIVE_SET_TOS(pn); 00414 return retval; 00415 00416 } 00417 00418 PmReturn_t 00419 nat_08___bi_range(pPmFrame_t *ppframe) 00420 { 00421 00422 PmReturn_t retval; 00423 pPmObj_t pa = C_NULL; 00424 pPmObj_t pb = C_NULL; 00425 pPmObj_t pc = C_NULL; 00426 pPmObj_t pi = C_NULL; 00427 pPmObj_t pr = C_NULL; 00428 int16_t i = 0; 00429 uint8_t objid1, objid2; 00430 00431 switch (NATIVE_GET_NUM_ARGS()) 00432 { 00433 case 1: 00434 pa = PM_ZERO; 00435 pb = NATIVE_GET_LOCAL(0); 00436 pc = PM_ONE; 00437 break; 00438 00439 case 2: 00440 pa = NATIVE_GET_LOCAL(0); 00441 pb = NATIVE_GET_LOCAL(1); 00442 pc = PM_ONE; 00443 break; 00444 00445 case 3: 00446 pa = NATIVE_GET_LOCAL(0); 00447 pb = NATIVE_GET_LOCAL(1); 00448 pc = NATIVE_GET_LOCAL(2); 00449 00450 /* If 3rd arg is 0, ValueError */ 00451 if (((pPmInt_t)pc)->val == 0) 00452 { 00453 PM_RAISE(retval, PM_RET_EX_VAL); 00454 return retval; 00455 } 00456 break; 00457 00458 default: 00459 /* If wrong number of args, raise TypeError */ 00460 PM_RAISE(retval, PM_RET_EX_TYPE); 00461 return retval; 00462 } 00463 00464 /* Allocate list */ 00465 retval = list_new(&pr); 00466 PM_RETURN_IF_ERROR(retval); 00467 00468 /* Iterate depending on counting direction */ 00469 if (((pPmInt_t)pc)->val > 0) 00470 { 00471 for (i = ((pPmInt_t)pa)->val; 00472 i < ((pPmInt_t)pb)->val; 00473 i += ((pPmInt_t)pc)->val) 00474 { 00475 heap_gcPushTempRoot(pr, &objid1); 00476 retval = int_new(i, &pi); 00477 if (retval != PM_RET_OK) 00478 { 00479 heap_gcPopTempRoot(objid1); 00480 return retval; 00481 } 00482 00483 heap_gcPushTempRoot(pi, &objid2); 00484 retval = list_append(pr, pi); 00485 heap_gcPopTempRoot(objid1); 00486 PM_RETURN_IF_ERROR(retval); 00487 } 00488 } 00489 else 00490 { 00491 for (i = ((pPmInt_t)pa)->val; 00492 i > ((pPmInt_t)pb)->val; 00493 i += ((pPmInt_t)pc)->val) 00494 { 00495 heap_gcPushTempRoot(pr, &objid1); 00496 retval = int_new(i, &pi); 00497 if (retval != PM_RET_OK) 00498 { 00499 heap_gcPopTempRoot(objid1); 00500 return retval; 00501 } 00502 00503 heap_gcPushTempRoot(pi, &objid2); 00504 retval = list_append(pr, pi); 00505 heap_gcPopTempRoot(objid1); 00506 PM_RETURN_IF_ERROR(retval); 00507 } 00508 } 00509 00510 /* Return list */ 00511 NATIVE_SET_TOS(pr); 00512 return retval; 00513 00514 } 00515 00516 PmReturn_t 00517 nat_09___bi_sum(pPmFrame_t *ppframe) 00518 { 00519 00520 pPmObj_t ps; 00521 pPmObj_t pn; 00522 pPmObj_t po; 00523 int32_t n; 00524 uint16_t len; 00525 uint16_t i; 00526 PmReturn_t retval; 00527 #ifdef HAVE_FLOAT 00528 float f; 00529 uint8_t usefloat = C_FALSE; 00530 #endif /* HAVE_FLOAT */ 00531 00532 /* If wrong number of args, raise TypeError */ 00533 if (NATIVE_GET_NUM_ARGS() != 1) 00534 { 00535 PM_RAISE(retval, PM_RET_EX_TYPE); 00536 return retval; 00537 } 00538 00539 ps = NATIVE_GET_LOCAL(0); 00540 00541 #ifdef HAVE_BYTEARRAY 00542 /* Bytearray is a special case to save RAM converting each byte to an Int */ 00543 if (OBJ_GET_TYPE(ps) == OBJ_TYPE_BYA) 00544 { 00545 n = 0; 00546 len = ((pPmBytearray_t)ps)->length; 00547 po = (pPmObj_t)((pPmBytearray_t)ps)->val; 00548 for (i = 0; i < len; i++) 00549 { 00550 n += (uint8_t)((pPmBytes_t)po)->val[i]; 00551 } 00552 retval = int_new(n, &pn); 00553 NATIVE_SET_TOS(pn); 00554 return retval; 00555 } 00556 #endif /* HAVE_BYTEARRAY */ 00557 00558 /* Raise TypeError if arg is not a sequence */ 00559 if ((OBJ_GET_TYPE(ps) != OBJ_TYPE_TUP) 00560 && (OBJ_GET_TYPE(ps) != OBJ_TYPE_LST) 00561 && (OBJ_GET_TYPE(ps) != OBJ_TYPE_DIC)) 00562 { 00563 PM_RAISE(retval, PM_RET_EX_TYPE); 00564 return retval; 00565 } 00566 00567 /* Get the length of the sequence */ 00568 retval = seq_getLength(ps, &len); 00569 PM_RETURN_IF_ERROR(retval); 00570 00571 /* Calculate the sum of the sequence */ 00572 n = 0; 00573 #ifdef HAVE_FLOAT 00574 f = 0.0; 00575 #endif 00576 for (i = 0; i < len; i++) 00577 { 00578 retval = seq_getSubscript(ps, i, &po); 00579 00580 if (OBJ_GET_TYPE(po) == OBJ_TYPE_INT) 00581 { 00582 /* Add value to sum */ 00583 n += ((pPmInt_t)po)->val; 00584 #ifdef HAVE_FLOAT 00585 f += (float)((pPmInt_t)po)->val; 00586 #endif /* HAVE_FLOAT */ 00587 } 00588 00589 #ifdef HAVE_FLOAT 00590 else if (OBJ_GET_TYPE(po) == OBJ_TYPE_FLT) 00591 { 00592 /* Add value to sum */ 00593 f += ((pPmFloat_t)po)->val; 00594 usefloat = C_TRUE; 00595 } 00596 #endif /* HAVE_FLOAT */ 00597 00598 /* Raise TypeError if item is not an integer */ 00599 else 00600 { 00601 PM_RAISE(retval, PM_RET_EX_TYPE); 00602 return retval; 00603 } 00604 } 00605 00606 #ifdef HAVE_FLOAT 00607 if (usefloat) 00608 { 00609 retval = float_new(f, &pn); 00610 } 00611 else 00612 #endif /* HAVE_FLOAT */ 00613 { 00614 retval = int_new(n, &pn); 00615 } 00616 NATIVE_SET_TOS(pn); 00617 return retval; 00618 00619 } 00620 00621 PmReturn_t 00622 nat_10___bi_type(pPmFrame_t *ppframe) 00623 { 00624 00625 PmReturn_t retval; 00626 pPmObj_t po = C_NULL; 00627 pPmObj_t pr = C_NULL; 00628 00629 /* If wrong number of args, raise TypeError */ 00630 if (NATIVE_GET_NUM_ARGS() != 1) 00631 { 00632 PM_RAISE(retval, PM_RET_EX_TYPE); 00633 return retval; 00634 } 00635 00636 /* Get arg */ 00637 po = NATIVE_GET_LOCAL(0); 00638 00639 /* Create int from type enum */ 00640 retval = int_new(OBJ_GET_TYPE(po), &pr); 00641 NATIVE_SET_TOS(pr); 00642 return retval; 00643 00644 } 00645 00646 PmReturn_t 00647 nat_11___bi_Co(pPmFrame_t *ppframe) 00648 { 00649 00650 PmReturn_t retval; 00651 pPmObj_t pimg; 00652 pPmObj_t pco; 00653 00654 /* If wrong number of args, raise TypeError */ 00655 if (NATIVE_GET_NUM_ARGS() != 1) 00656 { 00657 PM_RAISE(retval, PM_RET_EX_TYPE); 00658 return retval; 00659 } 00660 00661 /* Raise ValueError if arg is not an Image Obj */ 00662 pimg = NATIVE_GET_LOCAL(0); 00663 if (OBJ_GET_TYPE(pimg) != OBJ_TYPE_CIO) 00664 { 00665 PM_RAISE(retval, PM_RET_EX_VAL); 00666 return retval; 00667 } 00668 00669 /* Create a code object from the image */ 00670 retval = obj_loadFromImgObj(pimg, &pco); 00671 PM_RETURN_IF_ERROR(retval); 00672 00673 /* Return the code object */ 00674 NATIVE_SET_TOS(pco); 00675 return retval; 00676 00677 } 00678 00679 PmReturn_t 00680 nat_12___bi___init__(pPmFrame_t *ppframe) 00681 { 00682 00683 PmReturn_t retval; 00684 pPmObj_t pself; 00685 pPmObj_t pfa; 00686 pPmObj_t pfunc; 00687 pPmObj_t pframe; 00688 uint8_t i; 00689 uint8_t objid; 00690 00691 /* Raise TypeError if wrong number of args */ 00692 if (NATIVE_GET_NUM_ARGS() != 2) 00693 { 00694 PM_RAISE(retval, PM_RET_EX_TYPE); 00695 return retval; 00696 } 00697 00698 /* Raise ValueError if first args are not: instance, tuple */ 00699 pself = NATIVE_GET_LOCAL(0); 00700 pfa = NATIVE_GET_LOCAL(1); 00701 if (OBJ_GET_TYPE(pself) != OBJ_TYPE_CLI) 00702 { 00703 PM_RAISE(retval, PM_RET_EX_VAL); 00704 return retval; 00705 } 00706 if (OBJ_GET_TYPE(pfa) != OBJ_TYPE_TUP) 00707 { 00708 PM_RAISE(retval, PM_RET_EX_VAL); 00709 return retval; 00710 } 00711 00712 /* Create a new frame for the function */ 00713 pfunc = ((pPmTuple_t)pfa)->val[0]; 00714 retval = frame_new(pfunc, &pframe); 00715 PM_RETURN_IF_ERROR(retval); 00716 00717 /* Copy args into frame's locals */ 00718 for (i = 0; i < ((pPmTuple_t)pfa)->length - 1; i++) 00719 { 00720 /* The pfa tuple is (func, [arg0, ... argN]) */ 00721 ((pPmFrame_t)pframe)->fo_locals[i] = ((pPmTuple_t)pfa)->val[i + 1]; 00722 } 00723 00724 /* Store frame in None attr of instance */ 00725 heap_gcPushTempRoot(pframe, &objid); 00726 retval = dict_setItem((pPmObj_t)((pPmInstance_t)pself)->cli_attrs, 00727 PM_NONE, pframe); 00728 heap_gcPopTempRoot(objid); 00729 00730 NATIVE_SET_TOS(PM_NONE); 00731 return retval; 00732 00733 } 00734 00735 PmReturn_t 00736 nat_13___bi_send(pPmFrame_t *ppframe) 00737 { 00738 00739 PmReturn_t retval; 00740 pPmObj_t pself; 00741 pPmObj_t parg; 00742 pPmObj_t pgenframe; 00743 00744 /* Raise TypeError if wrong number of args */ 00745 if (NATIVE_GET_NUM_ARGS() != 2) 00746 { 00747 PM_RAISE(retval, PM_RET_EX_TYPE); 00748 return retval; 00749 } 00750 00751 /* Raise ValueError if first arg is not an instance */ 00752 pself = NATIVE_GET_LOCAL(0); 00753 parg = NATIVE_GET_LOCAL(1); 00754 if (OBJ_GET_TYPE(pself) != OBJ_TYPE_CLI) 00755 { 00756 PM_RAISE(retval, PM_RET_EX_VAL); 00757 return retval; 00758 } 00759 00760 /* Get the generator's frame */ 00761 retval = dict_getItem((pPmObj_t)((pPmInstance_t)pself)->cli_attrs, 00762 PM_NONE, &pgenframe); 00763 PM_RETURN_IF_ERROR(retval); 00764 00765 /* Push argument onto generator's frame's stack */ 00766 *(((pPmFrame_t)pgenframe)->fo_sp) = parg; 00767 ((pPmFrame_t)pgenframe)->fo_sp++; 00768 00769 /* Set generator's frame's fo_back so yielded value goes to caller */ 00770 ((pPmFrame_t)pgenframe)->fo_back = NATIVE_GET_PFRAME(); 00771 00772 /* Set active frame to run generator */ 00773 NATIVE_GET_PFRAME() = (pPmFrame_t)pgenframe; 00774 00775 return PM_RET_FRAME_SWITCH; 00776 00777 } 00778 00779 PmReturn_t 00780 nat_14___bi_ismain(pPmFrame_t *ppframe) 00781 { 00782 00783 00784 NATIVE_SET_TOS((NATIVE_GET_PFRAME()->fo_isImport) ? PM_FALSE : PM_TRUE); 00785 00786 return PM_RET_OK; 00787 00788 } 00789 00790 PmReturn_t 00791 nat_15_dict_clear(pPmFrame_t *ppframe) 00792 { 00793 00794 pPmObj_t pd; 00795 PmReturn_t retval = PM_RET_OK; 00796 00797 /* Raise TypeError if it's not a dict or wrong number of args, */ 00798 pd = NATIVE_GET_LOCAL(0); 00799 if ((OBJ_GET_TYPE(pd) != OBJ_TYPE_DIC) || (NATIVE_GET_NUM_ARGS() != 1)) 00800 { 00801 PM_RAISE(retval, PM_RET_EX_TYPE); 00802 return retval; 00803 } 00804 00805 /* Clear the contents of the dict */ 00806 retval = dict_clear(pd); 00807 PM_RETURN_IF_ERROR(retval); 00808 00809 NATIVE_SET_TOS(PM_NONE); 00810 00811 return retval; 00812 00813 } 00814 00815 PmReturn_t 00816 nat_16_dict_keys(pPmFrame_t *ppframe) 00817 { 00818 00819 pPmObj_t pd; 00820 pPmObj_t pl; 00821 pPmObj_t pk; 00822 pSeglist_t psl; 00823 uint16_t i; 00824 PmReturn_t retval = PM_RET_OK; 00825 uint8_t objid; 00826 00827 /* Raise TypeError if it's not a dict or wrong number of args, */ 00828 pd = NATIVE_GET_LOCAL(0); 00829 if ((OBJ_GET_TYPE(pd) != OBJ_TYPE_DIC) || (NATIVE_GET_NUM_ARGS() != 1)) 00830 { 00831 PM_RAISE(retval, PM_RET_EX_TYPE); 00832 return retval; 00833 } 00834 00835 /* Create empty list */ 00836 retval = list_new(&pl); 00837 PM_RETURN_IF_ERROR(retval); 00838 00839 /* Iterate through the keys seglist */ 00840 psl = ((pPmDict_t)pd)->d_keys; 00841 for (i = 0; i < ((pPmDict_t)pd)->length; i++) 00842 { 00843 /* Get the key and append it to the list */ 00844 retval = seglist_getItem(psl, i, &pk); 00845 PM_RETURN_IF_ERROR(retval); 00846 heap_gcPushTempRoot(pl, &objid); 00847 retval = list_append(pl, pk); 00848 heap_gcPopTempRoot(objid); 00849 PM_RETURN_IF_ERROR(retval); 00850 } 00851 00852 /* Return the list of keys to the caller */ 00853 NATIVE_SET_TOS(pl); 00854 00855 return retval; 00856 00857 } 00858 00859 PmReturn_t 00860 nat_17_dict_values(pPmFrame_t *ppframe) 00861 { 00862 00863 pPmObj_t pd; 00864 pPmObj_t pl; 00865 pPmObj_t pv; 00866 pSeglist_t psl; 00867 uint16_t i; 00868 PmReturn_t retval = PM_RET_OK; 00869 uint8_t objid; 00870 00871 /* Raise TypeError if it's not a dict or wrong number of args, */ 00872 pd = NATIVE_GET_LOCAL(0); 00873 if ((OBJ_GET_TYPE(pd) != OBJ_TYPE_DIC) || (NATIVE_GET_NUM_ARGS() != 1)) 00874 { 00875 PM_RAISE(retval, PM_RET_EX_TYPE); 00876 return retval; 00877 } 00878 00879 /* Create empty list */ 00880 retval = list_new(&pl); 00881 PM_RETURN_IF_ERROR(retval); 00882 00883 /* Iterate through the values seglist */ 00884 psl = ((pPmDict_t)pd)->d_vals; 00885 for (i = 0; i < ((pPmDict_t)pd)->length; i++) 00886 { 00887 /* Get the value and append it to the list */ 00888 retval = seglist_getItem(psl, i, &pv); 00889 PM_RETURN_IF_ERROR(retval); 00890 heap_gcPushTempRoot(pl, &objid); 00891 retval = list_append(pl, pv); 00892 heap_gcPopTempRoot(objid); 00893 PM_RETURN_IF_ERROR(retval); 00894 } 00895 00896 /* Return the list of values to the caller */ 00897 NATIVE_SET_TOS(pl); 00898 00899 return retval; 00900 00901 } 00902 00903 PmReturn_t 00904 nat_18_dict_update(pPmFrame_t *ppframe) 00905 { 00906 00907 pPmObj_t pd1; 00908 pPmObj_t pd2; 00909 PmReturn_t retval; 00910 00911 /* Raise TypeError if wrong number of args, */ 00912 if (NATIVE_GET_NUM_ARGS() != 2) 00913 { 00914 PM_RAISE(retval, PM_RET_EX_TYPE); 00915 return retval; 00916 } 00917 00918 pd1 = NATIVE_GET_LOCAL(0); 00919 pd2 = NATIVE_GET_LOCAL(1); 00920 retval = dict_update(pd1, pd2, C_FALSE); 00921 00922 NATIVE_SET_TOS(PM_NONE); 00923 return retval; 00924 00925 } 00926 00927 PmReturn_t 00928 nat_19_list_append(pPmFrame_t *ppframe) 00929 { 00930 00931 pPmObj_t pl; 00932 PmReturn_t retval = PM_RET_OK; 00933 00934 /* Raise TypeError if it's not a list or wrong number of args, */ 00935 pl = NATIVE_GET_LOCAL(0); 00936 if ((OBJ_GET_TYPE(pl) != OBJ_TYPE_LST) || (NATIVE_GET_NUM_ARGS() != 2)) 00937 { 00938 PM_RAISE(retval, PM_RET_EX_TYPE); 00939 return retval; 00940 } 00941 00942 /* Append the object to the list */ 00943 retval = list_append(pl, NATIVE_GET_LOCAL(1)); 00944 00945 NATIVE_SET_TOS(PM_NONE); 00946 00947 return retval; 00948 00949 } 00950 00951 PmReturn_t 00952 nat_20_list_index(pPmFrame_t *ppframe) 00953 { 00954 00955 pPmObj_t pl; 00956 pPmObj_t po; 00957 pPmObj_t pi; 00958 PmReturn_t retval = PM_RET_OK; 00959 uint16_t i; 00960 00961 /* Raise TypeError if it's not a list or wrong number of args, */ 00962 pl = NATIVE_GET_LOCAL(0); 00963 if ((OBJ_GET_TYPE(pl) != OBJ_TYPE_LST) || (NATIVE_GET_NUM_ARGS() != 2)) 00964 { 00965 PM_RAISE(retval, PM_RET_EX_TYPE); 00966 return retval; 00967 } 00968 00969 /* Get the index of the object in the list */ 00970 po = NATIVE_GET_LOCAL(1); 00971 retval = list_index(pl, po, &i); 00972 00973 if (retval == PM_RET_EX_VAL) 00974 { 00975 PM_RAISE(retval, PM_RET_EX_VAL); 00976 return retval; 00977 } 00978 00979 int_new((int32_t)i, &pi); 00980 NATIVE_SET_TOS(pi); 00981 00982 return retval; 00983 00984 } 00985 00986 PmReturn_t 00987 nat_21_list_insert(pPmFrame_t *ppframe) 00988 { 00989 00990 pPmObj_t pl; 00991 pPmObj_t pi; 00992 pPmObj_t po; 00993 PmReturn_t retval = PM_RET_OK; 00994 uint16_t i; 00995 00996 /* 00997 * Raise TypeError if wrong number of args, first arg is not a list, or 00998 * second arg is not an int 00999 */ 01000 pl = NATIVE_GET_LOCAL(0); 01001 pi = NATIVE_GET_LOCAL(1); 01002 po = NATIVE_GET_LOCAL(2); 01003 if ((NATIVE_GET_NUM_ARGS() != 3) 01004 || (OBJ_GET_TYPE(pl) != OBJ_TYPE_LST) 01005 || (OBJ_GET_TYPE(pi) != OBJ_TYPE_INT) ) 01006 { 01007 PM_RAISE(retval, PM_RET_EX_TYPE); 01008 return retval; 01009 } 01010 01011 /* Insert the object before the given index */ 01012 i = (uint16_t)((pPmInt_t)pi)->val; 01013 retval = list_insert(pl, i, po); 01014 01015 if (retval != PM_RET_OK) 01016 { 01017 PM_RAISE(retval, PM_RET_EX_SYS); 01018 } 01019 01020 NATIVE_SET_TOS(PM_NONE); 01021 01022 return retval; 01023 01024 } 01025 01026 PmReturn_t 01027 nat_22_list_pop(pPmFrame_t *ppframe) 01028 { 01029 01030 pPmObj_t pl; 01031 pPmObj_t pi; 01032 pPmObj_t po; 01033 PmReturn_t retval = PM_RET_OK; 01034 int16_t i; 01035 01036 /* 01037 * Raise TypeError if first arg is not a list o second arg is not an int 01038 * or there are the wrong number of arguments 01039 */ 01040 pl = NATIVE_GET_LOCAL(0); 01041 if (OBJ_GET_TYPE(pl) != OBJ_TYPE_LST) 01042 { 01043 PM_RAISE(retval, PM_RET_EX_TYPE); 01044 return retval; 01045 } 01046 01047 pi = NATIVE_GET_LOCAL(1); 01048 if (NATIVE_GET_NUM_ARGS() == 2) 01049 { 01050 if (OBJ_GET_TYPE(pi) != OBJ_TYPE_INT) 01051 { 01052 PM_RAISE(retval, PM_RET_EX_TYPE); 01053 return retval; 01054 } 01055 i = (uint16_t)((pPmInt_t)pi)->val; 01056 } 01057 else 01058 { 01059 i = -1; 01060 } 01061 if ((NATIVE_GET_NUM_ARGS() < 1) || (NATIVE_GET_NUM_ARGS() > 2)) 01062 { 01063 PM_RAISE(retval, PM_RET_EX_TYPE); 01064 return retval; 01065 } 01066 01067 /* Get the object at the given index */ 01068 retval = list_getItem(pl, i, &po); 01069 PM_RETURN_IF_ERROR(retval); 01070 01071 /* Return the object to the caller */ 01072 NATIVE_SET_TOS(po); 01073 01074 /* Remove the object from the given index */ 01075 retval = list_delItem(pl, i); 01076 PM_RETURN_IF_ERROR(retval); 01077 01078 return retval; 01079 01080 } 01081 01082 PmReturn_t 01083 nat_23_list_remove(pPmFrame_t *ppframe) 01084 { 01085 01086 pPmObj_t pl; 01087 pPmObj_t pv; 01088 PmReturn_t retval = PM_RET_OK; 01089 01090 /* Raise TypeError if it's not a list or wrong number of args, */ 01091 pl = NATIVE_GET_LOCAL(0); 01092 if ((OBJ_GET_TYPE(pl) != OBJ_TYPE_LST) || (NATIVE_GET_NUM_ARGS() != 2)) 01093 { 01094 PM_RAISE(retval, PM_RET_EX_TYPE); 01095 return retval; 01096 } 01097 01098 /* Remove the value from the list */ 01099 pv = NATIVE_GET_LOCAL(1); 01100 retval = list_remove(pl, pv); 01101 if (retval != PM_RET_OK) 01102 { 01103 PM_RAISE(retval, retval); 01104 } 01105 01106 NATIVE_SET_TOS(PM_NONE); 01107 01108 return retval; 01109 01110 } 01111 01112 PmReturn_t 01113 nat_24_string_atoi(pPmFrame_t *ppframe) 01114 { 01115 01116 pPmObj_t pa; 01117 pPmObj_t pb; 01118 char const *pc; 01119 char *pend; 01120 long i; 01121 int8_t base; 01122 pPmObj_t pi; 01123 PmReturn_t retval = PM_RET_OK; 01124 01125 /* Raise TypeError if it's not a string or wrong number of args, */ 01126 pa = NATIVE_GET_LOCAL(0); 01127 if ((OBJ_GET_TYPE(pa) != OBJ_TYPE_STR) || (NATIVE_GET_NUM_ARGS() < 1) 01128 || (NATIVE_GET_NUM_ARGS() > 2)) 01129 { 01130 PM_RAISE(retval, PM_RET_EX_TYPE); 01131 return retval; 01132 } 01133 01134 /* Get the base, if it exists; otherwise assume 10 */ 01135 base = 10; 01136 if (NATIVE_GET_NUM_ARGS() == 2) 01137 { 01138 pb = NATIVE_GET_LOCAL(1); 01139 01140 /* Raise a TypeError if 2nd arg is not an int */ 01141 if (OBJ_GET_TYPE(pb) != OBJ_TYPE_INT) 01142 { 01143 PM_RAISE(retval, PM_RET_EX_TYPE); 01144 return retval; 01145 } 01146 01147 base = ((pPmInt_t)pb)->val; 01148 01149 /* Raise ValueError if base is out of range */ 01150 if ((base < 0) || (base == 1) || (base > 36)) 01151 { 01152 PM_RAISE(retval, PM_RET_EX_VAL); 01153 return retval; 01154 } 01155 } 01156 01157 /* Perform conversion */ 01158 pend = C_NULL; 01159 pc = (char const *)&(((pPmString_t)pa)->val); 01160 i = strtol(pc, &pend, base); 01161 01162 /* Raise ValueError if there was a conversion error */ 01163 if (*pend != C_NULL) 01164 { 01165 PM_RAISE(retval, PM_RET_EX_VAL); 01166 return retval; 01167 } 01168 01169 /* Create an int object to hold the result of the conversion */ 01170 retval = int_new(i, &pi); 01171 01172 NATIVE_SET_TOS(pi); 01173 01174 return retval; 01175 01176 } 01177 01178 PmReturn_t 01179 nat_25_string_count(pPmFrame_t *ppframe) 01180 { 01181 01182 pPmObj_t ps1; 01183 pPmObj_t ps2; 01184 uint8_t *pc1; 01185 uint8_t *pc2; 01186 uint8_t *pscan; 01187 uint8_t *pmatch; 01188 uint8_t pc2c0; 01189 uint16_t pc1len; 01190 uint16_t pc2len; 01191 uint16_t n; 01192 uint16_t remaining; 01193 uint16_t cmp; 01194 pPmObj_t pn; 01195 PmReturn_t retval = PM_RET_OK; 01196 01197 /* Raise TypeError if it's not a string or wrong number of args, */ 01198 ps1 = NATIVE_GET_LOCAL(0); 01199 ps2 = NATIVE_GET_LOCAL(1); 01200 if ((OBJ_GET_TYPE(ps1) != OBJ_TYPE_STR) || (NATIVE_GET_NUM_ARGS() != 2) 01201 || (OBJ_GET_TYPE(ps2) != OBJ_TYPE_STR)) 01202 { 01203 PM_RAISE(retval, PM_RET_EX_TYPE); 01204 return retval; 01205 } 01206 01207 pc1 = ((pPmString_t)ps1)->val; 01208 pc2 = ((pPmString_t)ps2)->val; 01209 pc1len = ((pPmString_t)ps1)->length; 01210 pc2len = ((pPmString_t)ps2)->length; 01211 n = 0; 01212 01213 /* Handle some quick special cases (order of if-clauses is important) */ 01214 if (pc2len == 0) 01215 { 01216 n = pc1len + 1; 01217 } 01218 else if (pc1len == 0) 01219 { 01220 n = 0; 01221 } 01222 01223 /* Count the number of matches */ 01224 else 01225 { 01226 n = 0; 01227 remaining = pc1len; 01228 pscan = pc1; 01229 pc2c0 = pc2[0]; 01230 while (pscan <= (pc1 + (pc1len - pc2len))) 01231 { 01232 /* Find the next possible start */ 01233 pmatch = (uint8_t *)memchr(pscan, pc2c0, remaining); 01234 if (pmatch == C_NULL) break; 01235 remaining -= (pmatch - pscan); 01236 pscan = pmatch; 01237 01238 /* If it matches, increase the count, else try the next char */ 01239 cmp = memcmp(pscan, pc2, pc2len); 01240 if (cmp == 0) 01241 { 01242 n++; 01243 pscan += pc2len; 01244 remaining -= pc2len; 01245 } 01246 else 01247 { 01248 pscan++; 01249 remaining--; 01250 } 01251 } 01252 } 01253 01254 retval = int_new(n, &pn); 01255 01256 NATIVE_SET_TOS(pn); 01257 01258 return retval; 01259 01260 } 01261 01262 PmReturn_t 01263 nat_26_string_find(pPmFrame_t *ppframe) 01264 { 01265 01266 pPmObj_t ps1; 01267 pPmObj_t ps2; 01268 uint8_t *pc1; 01269 uint8_t *pc2; 01270 uint8_t *pmatch; 01271 uint16_t pc1len; 01272 uint16_t pc2len; 01273 int32_t n; 01274 pPmObj_t pn; 01275 PmReturn_t retval = PM_RET_OK; 01276 01277 /* Raise TypeError if it's not a string or wrong number of args, */ 01278 ps1 = NATIVE_GET_LOCAL(0); 01279 ps2 = NATIVE_GET_LOCAL(1); 01280 if ((OBJ_GET_TYPE(ps1) != OBJ_TYPE_STR) || (NATIVE_GET_NUM_ARGS() != 2) 01281 || (OBJ_GET_TYPE(ps2) != OBJ_TYPE_STR)) 01282 { 01283 PM_RAISE(retval, PM_RET_EX_TYPE); 01284 return retval; 01285 } 01286 01287 pc1 = ((pPmString_t)ps1)->val; 01288 pc2 = ((pPmString_t)ps2)->val; 01289 pc1len = ((pPmString_t)ps1)->length; 01290 pc2len = ((pPmString_t)ps2)->length; 01291 n = -1; 01292 01293 /* Handle a quick special case */ 01294 if (pc2len == 0) 01295 { 01296 n = 0; 01297 } 01298 01299 /* Try to find the index of the substring */ 01300 else 01301 { 01302 /* Find the next possible start */ 01303 pmatch = (uint8_t *)memchr(pc1, pc2[0], pc1len); 01304 if (pmatch != C_NULL) 01305 { 01306 /* If it matches, calculate the index */ 01307 if (memcmp(pmatch, pc2, pc2len) == 0) 01308 { 01309 n = pmatch - pc1; 01310 } 01311 } 01312 } 01313 01314 retval = int_new(n, &pn); 01315 01316 NATIVE_SET_TOS(pn); 01317 01318 return retval; 01319 01320 } 01321 01322 PmReturn_t 01323 nat_27_sys_exit(pPmFrame_t *ppframe) 01324 { 01325 01326 pPmObj_t pval = C_NULL; 01327 PmReturn_t retval; 01328 01329 /* If no arg given, assume return 0 */ 01330 if (NATIVE_GET_NUM_ARGS() == 0) 01331 { 01332 NATIVE_SET_TOS(PM_ZERO); 01333 } 01334 01335 /* If 1 arg given, put it on stack */ 01336 else if (NATIVE_GET_NUM_ARGS() == 1) 01337 { 01338 pval = NATIVE_GET_LOCAL(0); 01339 NATIVE_SET_TOS(pval); 01340 } 01341 01342 /* If wrong number of args, raise TypeError */ 01343 else 01344 { 01345 PM_RAISE(retval, PM_RET_EX_TYPE); 01346 return retval; 01347 } 01348 01349 /* Raise the SystemExit exception */ 01350 PM_RAISE(retval, PM_RET_EX_EXIT); 01351 return retval; 01352 01353 } 01354 01355 PmReturn_t 01356 nat_28_sys_gc(pPmFrame_t *ppframe) 01357 { 01358 01359 PmReturn_t retval = PM_RET_OK; 01360 #ifdef HAVE_GC 01361 /* If wrong number of args, raise TypeError */ 01362 if (NATIVE_GET_NUM_ARGS() != 0) 01363 { 01364 PM_RAISE(retval, PM_RET_EX_TYPE); 01365 return retval; 01366 } 01367 01368 retval = heap_gcRun(); 01369 #endif 01370 NATIVE_SET_TOS(PM_NONE); 01371 01372 return retval; 01373 01374 } 01375 01376 PmReturn_t 01377 nat_29_sys_getb(pPmFrame_t *ppframe) 01378 { 01379 01380 uint8_t b; 01381 pPmObj_t pb; 01382 PmReturn_t retval; 01383 01384 /* If wrong number of args, raise TypeError */ 01385 if (NATIVE_GET_NUM_ARGS() != 0) 01386 { 01387 PM_RAISE(retval, PM_RET_EX_TYPE); 01388 return retval; 01389 } 01390 01391 retval = plat_getByte(&b); 01392 PM_RETURN_IF_ERROR(retval); 01393 01394 retval = int_new((int32_t)b, &pb); 01395 NATIVE_SET_TOS(pb); 01396 return retval; 01397 01398 } 01399 01400 PmReturn_t 01401 nat_30_sys_heap(pPmFrame_t *ppframe) 01402 { 01403 01404 PmReturn_t retval; 01405 pPmObj_t pavail; 01406 pPmObj_t psize; 01407 pPmObj_t ptup; 01408 uint8_t objid; 01409 01410 /* If wrong number of args, raise TypeError */ 01411 if (NATIVE_GET_NUM_ARGS() != 0) 01412 { 01413 PM_RAISE(retval, PM_RET_EX_TYPE); 01414 return retval; 01415 } 01416 01417 /* Allocate a tuple to store the return values */ 01418 retval = tuple_new(2, &ptup); 01419 PM_RETURN_IF_ERROR(retval); 01420 01421 /* Get the maximum heap size */ 01422 heap_gcPushTempRoot(ptup, &objid); 01423 retval = int_new(heap_getSize (), &psize); 01424 if (retval != PM_RET_OK) 01425 { 01426 heap_gcPopTempRoot(objid); 01427 return retval; 01428 } 01429 01430 /* Allocate an int to hold the amount of heap available */ 01431 retval = int_new(heap_getAvail () - sizeof(PmInt_t), &pavail); 01432 heap_gcPopTempRoot(objid); 01433 PM_RETURN_IF_ERROR(retval); 01434 01435 /* Put the two heap values in the tuple */ 01436 ((pPmTuple_t)ptup)->val[0] = pavail; 01437 ((pPmTuple_t)ptup)->val[1] = psize; 01438 01439 /* Return the tuple on the stack */ 01440 NATIVE_SET_TOS(ptup); 01441 01442 return retval; 01443 01444 } 01445 01446 PmReturn_t 01447 nat_31_sys_putb(pPmFrame_t *ppframe) 01448 { 01449 01450 uint8_t b; 01451 pPmObj_t pb; 01452 PmReturn_t retval; 01453 01454 pb = NATIVE_GET_LOCAL(0); 01455 01456 /* If wrong number of args, raise TypeError */ 01457 if (NATIVE_GET_NUM_ARGS() != 1) 01458 { 01459 PM_RAISE(retval, PM_RET_EX_TYPE); 01460 return retval; 01461 } 01462 01463 /* If arg is not an int, raise TypeError */ 01464 if (OBJ_GET_TYPE(pb) != OBJ_TYPE_INT) 01465 { 01466 PM_RAISE(retval, PM_RET_EX_TYPE); 01467 return retval; 01468 } 01469 01470 b = ((pPmInt_t)pb)->val & 0xFF; 01471 retval = plat_putByte(b); 01472 NATIVE_SET_TOS(PM_NONE); 01473 return retval; 01474 01475 } 01476 01477 PmReturn_t 01478 nat_32_sys_runInThread(pPmFrame_t *ppframe) 01479 { 01480 01481 PmReturn_t retval; 01482 pPmObj_t pf; 01483 01484 /* If wrong number of args, raise TypeError */ 01485 if (NATIVE_GET_NUM_ARGS() != 1) 01486 { 01487 PM_RAISE(retval, PM_RET_EX_TYPE); 01488 return retval; 01489 } 01490 01491 /* If arg is not a function, raise TypeError */ 01492 pf = NATIVE_GET_LOCAL(0); 01493 if (OBJ_GET_TYPE(pf) != OBJ_TYPE_FXN) 01494 { 01495 PM_RAISE(retval, PM_RET_EX_TYPE); 01496 return retval; 01497 } 01498 01499 retval = interp_addThread((pPmFunc_t)pf); 01500 NATIVE_SET_TOS(PM_NONE); 01501 return retval; 01502 01503 } 01504 01505 PmReturn_t 01506 nat_33_sys_time(pPmFrame_t *ppframe) 01507 { 01508 01509 uint32_t t; 01510 pPmObj_t pt; 01511 PmReturn_t retval; 01512 01513 /* If wrong number of args, raise TypeError */ 01514 if (NATIVE_GET_NUM_ARGS() != 0) 01515 { 01516 PM_RAISE(retval, PM_RET_EX_TYPE); 01517 return retval; 01518 } 01519 01520 /* Get the system time (milliseconds since init) */ 01521 retval = plat_getMsTicks(&t); 01522 PM_RETURN_IF_ERROR(retval); 01523 01524 /* 01525 * Raise ValueError if there is an overflow 01526 * (plat_getMsTicks is unsigned; int is signed) 01527 */ 01528 if ((int32_t)t < 0) 01529 { 01530 PM_RAISE(retval, PM_RET_EX_VAL); 01531 return retval; 01532 } 01533 01534 /* Return an int object with the time value */ 01535 retval = int_new((int32_t)t, &pt); 01536 NATIVE_SET_TOS(pt); 01537 return retval; 01538 01539 } 01540 01541 PmReturn_t 01542 nat_34_ipm__getImg(pPmFrame_t *ppframe) 01543 { 01544 01545 PmReturn_t retval; 01546 uint8_t imgType; 01547 uint16_t imgSize; 01548 uint8_t *pchunk; 01549 pPmCodeImgObj_t pimg; 01550 uint16_t i; 01551 uint8_t b; 01552 01553 /* Get the image type */ 01554 retval = plat_getByte(&imgType); 01555 PM_RETURN_IF_ERROR(retval); 01556 01557 /* Quit if a code image type was not received */ 01558 if (imgType != OBJ_TYPE_CIM) 01559 { 01560 PM_RAISE(retval, PM_RET_EX_STOP); 01561 return retval; 01562 } 01563 01564 /* Get the image size (little endien) */ 01565 retval = plat_getByte(&b); 01566 PM_RETURN_IF_ERROR(retval); 01567 imgSize = b; 01568 retval = plat_getByte(&b); 01569 PM_RETURN_IF_ERROR(retval); 01570 imgSize |= (b << 8); 01571 01572 /* Get space for CodeImgObj */ 01573 retval = heap_getChunk(sizeof(PmCodeImgObj_t) + imgSize, &pchunk); 01574 PM_RETURN_IF_ERROR(retval); 01575 pimg = (pPmCodeImgObj_t)pchunk; 01576 OBJ_SET_TYPE(pimg, OBJ_TYPE_CIO); 01577 01578 /* Start the image with the bytes that have already been received */ 01579 i = 0; 01580 pimg->val[i++] = imgType; 01581 pimg->val[i++] = imgSize & 0xFF; 01582 pimg->val[i++] = (imgSize >> 8) & 0xFF; 01583 01584 /* Get the remaining bytes in the image */ 01585 for(; i < imgSize; i++) 01586 { 01587 retval = plat_getByte(&b); 01588 PM_RETURN_IF_ERROR(retval); 01589 01590 pimg->val[i] = b; 01591 } 01592 01593 /* Return the image as a code image object on the stack */ 01594 NATIVE_SET_TOS((pPmObj_t)pimg); 01595 return retval; 01596 01597 } 01598 01599 PmReturn_t 01600 nat_35_ipm_x04(pPmFrame_t *ppframe) 01601 { 01602 01603 NATIVE_SET_TOS(PM_NONE); 01604 return plat_putByte(0x04); 01605 01606 } 01607 01608 /* Native function lookup table */ 01609 pPmNativeFxn_t const std_nat_fxn_table[] = 01610 { 01611 nat_00___bi_chr, 01612 nat_01___bi_dir, 01613 nat_02___bi_eval, 01614 nat_03___bi_globals, 01615 nat_04___bi_id, 01616 nat_05___bi_len, 01617 nat_06___bi_locals, 01618 nat_07___bi_ord, 01619 nat_08___bi_range, 01620 nat_09___bi_sum, 01621 nat_10___bi_type, 01622 nat_11___bi_Co, 01623 nat_12___bi___init__, 01624 nat_13___bi_send, 01625 nat_14___bi_ismain, 01626 nat_15_dict_clear, 01627 nat_16_dict_keys, 01628 nat_17_dict_values, 01629 nat_18_dict_update, 01630 nat_19_list_append, 01631 nat_20_list_index, 01632 nat_21_list_insert, 01633 nat_22_list_pop, 01634 nat_23_list_remove, 01635 nat_24_string_atoi, 01636 nat_25_string_count, 01637 nat_26_string_find, 01638 nat_27_sys_exit, 01639 nat_28_sys_gc, 01640 nat_29_sys_getb, 01641 nat_30_sys_heap, 01642 nat_31_sys_putb, 01643 nat_32_sys_runInThread, 01644 nat_33_sys_time, 01645 nat_34_ipm__getImg, 01646 nat_35_ipm_x04, 01647 };
Generated on Tue Jul 12 2022 21:25:46 by
1.7.2
