void plat_reportError(PmReturn_t result) { /* Print error */ printf_P(PSTR("Error: 0x%02X\n"), result); printf_P(PSTR(" Release: 0x%02X\n"), gVmGlobal.errVmRelease); printf_P(PSTR(" FileId: 0x%02X\n"), gVmGlobal.errFileId); printf_P(PSTR(" LineNum: %d\n"), gVmGlobal.errLineNum); /* Print traceback */ { pPmObj_t pframe; pPmObj_t pstr; PmReturn_t retval; puts_P(PSTR("Traceback (top first):")); /* Get the top frame */ pframe = (pPmObj_t)gVmGlobal.pthread->pframe; /* If it's the native frame, print the native function name */ if (pframe == (pPmObj_t)&(gVmGlobal.nativeframe)) { /* The last name in the names tuple of the code obj is the name */ retval = tuple_getItem((pPmObj_t)gVmGlobal.nativeframe.nf_func-> f_co->co_names, -1, &pstr); if ((retval) != PM_RET_OK) { puts_P(PSTR(" Unable to get native func name.")); return; } else { printf_P(PSTR(" %s() __NATIVE__\n"), ((pPmString_t)pstr)->val); } /* Get the frame that called the native frame */ pframe = (pPmObj_t)gVmGlobal.nativeframe.nf_back; } /* Print the remaining frame stack */ for (; pframe != C_NULL; pframe = (pPmObj_t)((pPmFrame_t)pframe)->fo_back) { /* The last name in the names tuple of the code obj is the name */ retval = tuple_getItem((pPmObj_t)((pPmFrame_t)pframe)-> fo_func->f_co->co_names, -1, &pstr); if ((retval) != PM_RET_OK) break; printf_P(PSTR(" %s()\n"), ((pPmString_t)pstr)->val); } puts_P(PSTR(" <module>.")); } }
/* Returns the object sequence[index] */ PmReturn_t seq_getSubscript(pPmObj_t pobj, int16_t index, pPmObj_t *r_pobj) { PmReturn_t retval; uint8_t c; switch (OBJ_GET_TYPE(pobj)) { case OBJ_TYPE_STR: /* Adjust for negative index */ if (index < 0) { index += ((pPmString_t)pobj)->length; } /* Raise IndexError if index is out of bounds */ if ((index < 0) || (index > ((pPmString_t)pobj)->length)) { PM_RAISE(retval, PM_RET_EX_INDX); break; } /* Get the character from the string */ c = ((pPmString_t)pobj)->val[index]; /* Create a new string from the character */ retval = string_newFromChar(c, r_pobj); break; case OBJ_TYPE_TUP: /* Get the tuple item */ retval = tuple_getItem(pobj, index, r_pobj); break; case OBJ_TYPE_LST: /* Get the list item */ retval = list_getItem(pobj, index, r_pobj); break; default: /* Raise TypeError, unsubscriptable object */ PM_RAISE(retval, PM_RET_EX_TYPE); break; } return retval; }
void plat_reportError(PmReturn_t result) { #ifdef HAVE_DEBUG_INFO #define LEN_FNLOOKUP 26 #define LEN_EXNLOOKUP 18 uint8_t res; pPmFrame_t pframe; pPmObj_t pstr; PmReturn_t retval; uint8_t bcindex; uint16_t bcsum; uint16_t linesum; uint16_t len_lnotab; uint8_t const *plnotab; uint16_t i; /* This table should match src/vm/fileid.txt */ char const * const fnlookup[LEN_FNLOOKUP] = { "<no file>", "codeobj.c", "dict.c", "frame.c", "func.c", "global.c", "heap.c", "img.c", "int.c", "interp.c", "pmstdlib_nat.c", "list.c", "main.c", "mem.c", "module.c", "obj.c", "seglist.c", "sli.c", "strobj.c", "tuple.c", "seq.c", "pm.c", "thread.c", "float.c", "class.c", "bytearray.c", }; /* This table should match src/vm/pm.h PmReturn_t */ char const * const exnlookup[LEN_EXNLOOKUP] = { "Exception", "SystemExit", "IoError", "ZeroDivisionError", "AssertionError", "AttributeError", "ImportError", "IndexError", "KeyError", "MemoryError", "NameError", "SyntaxError", "SystemError", "TypeError", "ValueError", "StopIteration", "Warning", "OverflowError", }; /* Print traceback */ printf("Traceback (most recent call first):\n"); /* Get the top frame */ pframe = gVmGlobal.pthread->pframe; /* If it's the native frame, print the native function name */ if (pframe == (pPmFrame_t)&(gVmGlobal.nativeframe)) { /* The last name in the names tuple of the code obj is the name */ retval = tuple_getItem((pPmObj_t)gVmGlobal.nativeframe.nf_func-> f_co->co_names, -1, &pstr); if ((retval) != PM_RET_OK) { printf(" Unable to get native func name.\n"); return; } else { printf(" %s() __NATIVE__\n", ((pPmString_t)pstr)->val); } /* Get the frame that called the native frame */ pframe = (pPmFrame_t)gVmGlobal.nativeframe.nf_back; } /* Print the remaining frame stack */ for (; pframe != C_NULL; pframe = pframe->fo_back) { /* The last name in the names tuple of the code obj is the name */ retval = tuple_getItem((pPmObj_t)pframe->fo_func->f_co->co_names, -1, &pstr); if ((retval) != PM_RET_OK) break; /* * Get the line number of the current bytecode. Algorithm comes from: * http://svn.python.org/view/python/trunk/Objects/lnotab_notes.txt?view=markup */ bcindex = pframe->fo_ip - pframe->fo_func->f_co->co_codeaddr; plnotab = pframe->fo_func->f_co->co_lnotab; len_lnotab = mem_getWord(MEMSPACE_PROG, &plnotab); bcsum = 0; linesum = pframe->fo_func->f_co->co_firstlineno; for (i = 0; i < len_lnotab; i += 2) { bcsum += mem_getByte(MEMSPACE_PROG, &plnotab); if (bcsum > bcindex) break; linesum += mem_getByte(MEMSPACE_PROG, &plnotab); } printf(" File \"%s\", line %d, in %s\n", ((pPmFrame_t)pframe)->fo_func->f_co->co_filename, linesum, ((pPmString_t)pstr)->val); } /* Print error */ res = (uint8_t)result; if ((res > 0) && ((res - PM_RET_EX) < LEN_EXNLOOKUP)) { printf("%s", exnlookup[res - PM_RET_EX]); } else { printf("Error code 0x%02X", result); } printf(" detected by "); if ((gVmGlobal.errFileId > 0) && (gVmGlobal.errFileId < LEN_FNLOOKUP)) { printf("%s:", fnlookup[gVmGlobal.errFileId]); } else { printf("FileId 0x%02X line ", gVmGlobal.errFileId); } printf("%d\n", gVmGlobal.errLineNum); #else /* HAVE_DEBUG_INFO */ /* Print error */ printf("Error: 0x%02X\n", result); printf(" Release: 0x%02X\n", gVmGlobal.errVmRelease); printf(" FileId: 0x%02X\n", gVmGlobal.errFileId); printf(" LineNum: %d\n", gVmGlobal.errLineNum); /* Print traceback */ { pPmObj_t pframe; pPmObj_t pstr; PmReturn_t retval; printf("Traceback (top first):\n"); /* Get the top frame */ pframe = (pPmObj_t)gVmGlobal.pthread->pframe; /* If it's the native frame, print the native function name */ if (pframe == (pPmObj_t)&(gVmGlobal.nativeframe)) { /* The last name in the names tuple of the code obj is the name */ retval = tuple_getItem((pPmObj_t)gVmGlobal.nativeframe.nf_func-> f_co->co_names, -1, &pstr); if ((retval) != PM_RET_OK) { printf(" Unable to get native func name.\n"); return; } else { printf(" %s() __NATIVE__\n", ((pPmString_t)pstr)->val); } /* Get the frame that called the native frame */ pframe = (pPmObj_t)gVmGlobal.nativeframe.nf_back; } /* Print the remaining frame stack */ for (; pframe != C_NULL; pframe = (pPmObj_t)((pPmFrame_t)pframe)->fo_back) { /* The last name in the names tuple of the code obj is the name */ retval = tuple_getItem((pPmObj_t)((pPmFrame_t)pframe)-> fo_func->f_co->co_names, -1, &pstr); if ((retval) != PM_RET_OK) break; printf(" %s()\n", ((pPmString_t)pstr)->val); } printf(" <module>.\n"); } #endif /* HAVE_DEBUG_INFO */ }
/* Returns true if the item is in the container object */ PmReturn_t obj_isIn(pPmObj_t pobj, pPmObj_t pitem) { PmReturn_t retval = PM_RET_NO; pPmObj_t ptestItem; int16_t i; uint8_t c; switch (OBJ_GET_TYPE(pobj)) { case OBJ_TYPE_TUP: /* Iterate over tuple to find item */ for (i = 0; i < ((pPmTuple_t)pobj)->length; i++) { PM_RETURN_IF_ERROR(tuple_getItem(pobj, i, &ptestItem)); if (obj_compare(pitem, ptestItem) == C_SAME) { retval = PM_RET_OK; break; } } break; case OBJ_TYPE_STR: /* Raise a TypeError if item is not a string */ if ((OBJ_GET_TYPE(pitem) != OBJ_TYPE_STR)) { retval = PM_RET_EX_TYPE; break; } /* Empty string is alway present */ if (((pPmString_t)pitem)->length == 0) { retval = PM_RET_OK; break; } /* Raise a ValueError if the string is more than 1 char */ else if (((pPmString_t)pitem)->length != 1) { retval = PM_RET_EX_VAL; break; } /* Iterate over string to find char */ c = ((pPmString_t)pitem)->val[0]; for (i = 0; i < ((pPmString_t)pobj)->length; i++) { if (c == ((pPmString_t)pobj)->val[i]) { retval = PM_RET_OK; break; } } break; case OBJ_TYPE_LST: /* Iterate over list to find item */ for (i = 0; i < ((pPmList_t)pobj)->length; i++) { PM_RETURN_IF_ERROR(list_getItem(pobj, i, &ptestItem)); if (obj_compare(pitem, ptestItem) == C_SAME) { retval = PM_RET_OK; break; } } break; case OBJ_TYPE_DIC: /* Check if the item is one of the keys of the dict */ retval = dict_getItem(pobj, pitem, &ptestItem); if (retval == PM_RET_EX_KEY) { retval = PM_RET_NO; } break; default: retval = PM_RET_EX_TYPE; break; } return retval; }
void plat_reportError(PmReturn_t result) { #ifdef HAVE_DEBUG_INFO uint8_t res; pPmFrame_t pframe; pPmObj_t pstr; PmReturn_t retval; uint8_t bcindex; uint16_t bcsum; uint16_t linesum; uint16_t len_lnotab; uint8_t const *plnotab; uint16_t i; char pstrbuf[MAX(FN_MAX_LEN, EXN_MAX_LEN)]; /* Print traceback */ puts_P(PSTR("Traceback (most recent call first):")); /* Get the top frame */ pframe = gVmGlobal.pthread->pframe; /* If it's the native frame, print the native function name */ if (pframe == (pPmFrame_t)&(gVmGlobal.nativeframe)) { /* The last name in the names tuple of the code obj is the name */ retval = tuple_getItem((pPmObj_t)gVmGlobal.nativeframe.nf_func-> f_co->co_names, -1, &pstr); if ((retval) != PM_RET_OK) { puts_P(PSTR(" Unable to get native func name.")); return; } else { printf_P(PSTR(" %s() __NATIVE__\n"), ((pPmString_t)pstr)->val); } /* Get the frame that called the native frame */ pframe = (pPmFrame_t)gVmGlobal.nativeframe.nf_back; } /* Print the remaining frame stack */ for (; pframe != C_NULL; pframe = pframe->fo_back) { /* The last name in the names tuple of the code obj is the name */ retval = tuple_getItem((pPmObj_t)pframe->fo_func->f_co->co_names, -1, &pstr); if ((retval) != PM_RET_OK) break; /* * Get the line number of the current bytecode. Algorithm comes from: * http://svn.python.org/view/python/trunk/Objects/lnotab_notes.txt?view=markup */ bcindex = pframe->fo_ip - pframe->fo_func->f_co->co_codeaddr; plnotab = pframe->fo_func->f_co->co_lnotab; len_lnotab = mem_getWord(MEMSPACE_PROG, &plnotab); bcsum = 0; linesum = pframe->fo_func->f_co->co_firstlineno; for (i = 0; i < len_lnotab; i += 2) { bcsum += mem_getByte(MEMSPACE_PROG, &plnotab); if (bcsum > bcindex) break; linesum += mem_getByte(MEMSPACE_PROG, &plnotab); } /* Get the file name of this frame's function */ if (pframe->fo_func->f_co->co_memspace == MEMSPACE_PROG) { strncpy_P(pstrbuf, (char *)pframe->fo_func->f_co->co_filename, MAX(FN_MAX_LEN, EXN_MAX_LEN)); } printf_P(PSTR(" File \"%s\", line %d, in %s\n"), ((pframe->fo_func->f_co->co_memspace == MEMSPACE_PROG) ? pstrbuf : (char *)pframe->fo_func->f_co->co_filename), linesum, ((pPmString_t)pstr)->val); } /* Print error */ res = (uint8_t)result; if ((res > 0) && ((res - PM_RET_EX) < LEN_EXNLOOKUP)) { strncpy_P(pstrbuf, (PGM_P)pgm_read_word(&exnlookup[res - PM_RET_EX]), EXN_MAX_LEN); printf_P(PSTR("%s"), pstrbuf); } else { printf_P(PSTR("Error code 0x%02X"), result); } printf_P(PSTR(" detected by ")); if ((gVmGlobal.errFileId > 0) && (gVmGlobal.errFileId < LEN_FNLOOKUP)) { strncpy_P(pstrbuf, (PGM_P)pgm_read_word(&fnlookup[gVmGlobal.errFileId]), FN_MAX_LEN); printf_P(PSTR("%s:"), pstrbuf); } else { printf_P(PSTR("FileId 0x%02X line "), gVmGlobal.errFileId); } printf_P(PSTR("%d\n"), gVmGlobal.errLineNum); #else /* HAVE_DEBUG_INFO */ /* Print error */ printf_P(PSTR("Error: 0x%02X\n"), result); printf_P(PSTR(" Release: 0x%02X\n"), gVmGlobal.errVmRelease); printf_P(PSTR(" FileId: 0x%02X\n"), gVmGlobal.errFileId); printf_P(PSTR(" LineNum: %d\n"), gVmGlobal.errLineNum); /* Print traceback */ { pPmObj_t pframe; pPmObj_t pstr; PmReturn_t retval; puts_P(PSTR("Traceback (top first):")); /* Get the top frame */ pframe = (pPmObj_t)gVmGlobal.pthread->pframe; /* If it's the native frame, print the native function name */ if (pframe == (pPmObj_t)&(gVmGlobal.nativeframe)) { /* The last name in the names tuple of the code obj is the name */ retval = tuple_getItem((pPmObj_t)gVmGlobal.nativeframe.nf_func-> f_co->co_names, -1, &pstr); if ((retval) != PM_RET_OK) { puts_P(PSTR(" Unable to get native func name.")); return; } else { printf_P(PSTR(" %s() __NATIVE__\n"), ((pPmString_t)pstr)->val); } /* Get the frame that called the native frame */ pframe = (pPmObj_t)gVmGlobal.nativeframe.nf_back; } /* Print the remaining frame stack */ for (; pframe != C_NULL; pframe = (pPmObj_t)((pPmFrame_t)pframe)->fo_back) { /* The last name in the names tuple of the code obj is the name */ retval = tuple_getItem((pPmObj_t)((pPmFrame_t)pframe)-> fo_func->f_co->co_names, -1, &pstr); if ((retval) != PM_RET_OK) break; printf_P(PSTR(" %s()\n"), ((pPmString_t)pstr)->val); } puts_P(PSTR(" <module>.")); } #endif /* HAVE_DEBUG_INFO */ }