plat.c

00001 /*
00002 # This file is Copyright 2006, 2007, 2009 Dean Hall, 2010 Oscar Lindberg.
00003 #
00004 # This file is part of the Python-on-a-Chip program.
00005 # Python-on-a-Chip is free software: you can redistribute it and/or modify
00006 # it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE Version 2.1.
00007 #
00008 # Python-on-a-Chip is distributed in the hope that it will be useful,
00009 # but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00011 # A copy of the GNU LESSER GENERAL PUBLIC LICENSE Version 2.1
00012 # is seen in the file COPYING up one directory from this.
00013 */
00014 
00015 
00016 #undef __FILE_ID__
00017 #define __FILE_ID__ 0x70
00018 
00019 
00022 #include <ma.h>
00023 
00024 #include "pm.h"
00025 
00026 
00027 /* MoSync target requires no initiation. */
00028 PmReturn_t
00029 plat_init(void)
00030 {
00031     return PM_RET_OK;
00032 }
00033 
00034 
00035 /* No cleaning up */
00036 PmReturn_t
00037 plat_deinit(void)
00038 {
00039     return PM_RET_OK;
00040 }
00041 
00042 /*
00043  * Gets a byte from the address in the designated memory space
00044  * Post-increments *paddr.
00045  */
00046 uint8_t
00047 plat_memGetByte(PmMemSpace_t memspace, uint8_t const **paddr)
00048 {
00049     uint8_t b = 0;
00050 
00051     switch (memspace)
00052     {
00053         case MEMSPACE_RAM:
00054         case MEMSPACE_PROG:
00055             b = **paddr;
00056             *paddr += 1;
00057             return b;
00058 
00059         case MEMSPACE_EEPROM:
00060         case MEMSPACE_SEEPROM:
00061         case MEMSPACE_OTHER0:
00062         case MEMSPACE_OTHER1:
00063         case MEMSPACE_OTHER2:
00064         case MEMSPACE_OTHER3:
00065         default:
00066             return 0;
00067     }
00068 }
00069 
00070 
00071 /* MoSync does not have an obvious stdin, so getByte is empty. 
00072  * Suggestions are welcome.
00073  */
00074 PmReturn_t
00075 plat_getByte(uint8_t *b)
00076 {
00077     PmReturn_t retval = PM_RET_OK;
00078     return retval;
00079 }
00080 
00081 #define PRINTBUFSIZE 80
00082 
00083 /* Prints to the log.
00084  * A newline is added by the platform to every write to log.
00085  * So the bytes are buffered and logged at newline or if buffer is full. */
00086 
00087 PmReturn_t
00088 plat_putByte(uint8_t b)
00089 {
00090     static char buf[PRINTBUFSIZE];
00091     static int bufpos = 0;
00092     PmReturn_t retval = PM_RET_OK;
00093     int flush = 0;
00094 
00095     if (b == (uint8_t)('\n')) {
00096         flush = 1;
00097     } else {
00098         buf[bufpos++] = b;
00099         flush = bufpos == PRINTBUFSIZE;
00100     }
00101 
00102     if (flush) {
00103         maWriteLog(buf, bufpos);
00104         bufpos = 0;
00105     }
00106 
00107     return retval;
00108 }
00109 
00110 
00111 PmReturn_t
00112 plat_getMsTicks(uint32_t *r_ticks)
00113 {
00114     *r_ticks = maGetMilliSecondCount();
00115 
00116     return PM_RET_OK;
00117 }
00118 
00119 
00120 /* Copied from Desktop platform */
00121 void
00122 plat_reportError(PmReturn_t result)
00123 {
00124 
00125 #ifdef HAVE_DEBUG_INFO
00126 #define LEN_FNLOOKUP 26
00127 #define LEN_EXNLOOKUP 17
00128 
00129     uint8_t res;
00130     pPmFrame_t pframe;
00131     pPmObj_t pstr;
00132     PmReturn_t retval;
00133     uint8_t bcindex;
00134     uint16_t bcsum;
00135     uint16_t linesum;
00136     uint16_t len_lnotab;
00137     uint8_t const *plnotab;
00138     uint16_t i;
00139 
00140     /* This table should match src/vm/fileid.txt */
00141     char const * const fnlookup[LEN_FNLOOKUP] = {
00142         "<no file>",
00143         "codeobj.c",
00144         "dict.c",
00145         "frame.c",
00146         "func.c",
00147         "global.c",
00148         "heap.c",
00149         "img.c",
00150         "int.c",
00151         "interp.c",
00152         "pmstdlib_nat.c",
00153         "list.c",
00154         "main.c",
00155         "mem.c",
00156         "module.c",
00157         "obj.c",
00158         "seglist.c",
00159         "sli.c",
00160         "strobj.c",
00161         "tuple.c",
00162         "seq.c",
00163         "pm.c",
00164         "thread.c",
00165         "float.c",
00166         "class.c",
00167         "bytearray.c",
00168     };
00169 
00170     /* This table should match src/vm/pm.h PmReturn_t */
00171     char const * const exnlookup[LEN_EXNLOOKUP] = {
00172         "Exception",
00173         "SystemExit",
00174         "IoError",
00175         "ZeroDivisionError",
00176         "AssertionError",
00177         "AttributeError",
00178         "ImportError",
00179         "IndexError",
00180         "KeyError",
00181         "MemoryError",
00182         "NameError",
00183         "SyntaxError",
00184         "SystemError",
00185         "TypeError",
00186         "ValueError",
00187         "StopIteration",
00188         "Warning",
00189     };
00190 
00191     /* Print traceback */
00192     printf("Traceback (most recent call first):\n");
00193 
00194     /* Get the top frame */
00195     pframe = gVmGlobal.pthread->pframe;
00196 
00197     /* If it's the native frame, print the native function name */
00198     if (pframe == (pPmFrame_t)&(gVmGlobal.nativeframe))
00199     {
00200 
00201         /* The last name in the names tuple of the code obj is the name */
00202         retval = tuple_getItem((pPmObj_t)gVmGlobal.nativeframe.nf_func->
00203                                f_co->co_names, -1, &pstr);
00204         if ((retval) != PM_RET_OK)
00205         {
00206             printf("  Unable to get native func name.\n");
00207             return;
00208         }
00209         else
00210         {
00211             printf("  %s() __NATIVE__\n", ((pPmString_t)pstr)->val);
00212         }
00213 
00214         /* Get the frame that called the native frame */
00215         pframe = (pPmFrame_t)gVmGlobal.nativeframe.nf_back;
00216     }
00217 
00218     /* Print the remaining frame stack */
00219     for (; pframe != C_NULL; pframe = pframe->fo_back)
00220     {
00221         /* The last name in the names tuple of the code obj is the name */
00222         retval = tuple_getItem((pPmObj_t)pframe->fo_func->f_co->co_names,
00223                                -1,
00224                                &pstr);
00225         if ((retval) != PM_RET_OK) break;
00226 
00227         /*
00228          * Get the line number of the current bytecode. Algorithm comes from:
00229          * http://svn.python.org/view/python/trunk/Objects/lnotab_notes.txt?view=markup
00230          */
00231         bcindex = pframe->fo_ip - pframe->fo_func->f_co->co_codeaddr;
00232         plnotab = pframe->fo_func->f_co->co_lnotab;
00233         len_lnotab = mem_getWord(MEMSPACE_PROG, &plnotab);
00234         bcsum = 0;
00235         linesum = pframe->fo_func->f_co->co_firstlineno;
00236         for (i = 0; i < len_lnotab; i += 2)
00237         {
00238             bcsum += mem_getByte(MEMSPACE_PROG, &plnotab);
00239             if (bcsum > bcindex) break;
00240             linesum += mem_getByte(MEMSPACE_PROG, &plnotab);
00241         }
00242         printf("  File \"%s\", line %d, in %s\n",
00243                ((pPmFrame_t)pframe)->fo_func->f_co->co_filename,
00244                linesum,
00245                ((pPmString_t)pstr)->val);
00246     }
00247 
00248     /* Print error */
00249     res = (uint8_t)result;
00250     if ((res > 0) && ((res - PM_RET_EX) < LEN_EXNLOOKUP))
00251     {
00252         printf("%s", exnlookup[res - PM_RET_EX]);
00253     }
00254     else
00255     {
00256         printf("Error code 0x%02X", result);
00257     }
00258     printf(" detected by ");
00259 
00260     if ((gVmGlobal.errFileId > 0) && (gVmGlobal.errFileId < LEN_FNLOOKUP))
00261     {
00262         printf("%s:", fnlookup[gVmGlobal.errFileId]);
00263     }
00264     else
00265     {
00266         printf("FileId 0x%02X line ", gVmGlobal.errFileId);
00267     }
00268     printf("%d\n", gVmGlobal.errLineNum);
00269 
00270 #else /* HAVE_DEBUG_INFO *
00271 
00272     /* Print error */
00273     printf("Error:     0x%02X\n", result);
00274     printf("  Release: 0x%02X\n", gVmGlobal.errVmRelease);
00275     printf("  FileId:  0x%02X\n", gVmGlobal.errFileId);
00276     printf("  LineNum: %d\n", gVmGlobal.errLineNum);
00277 
00278     /* Print traceback */
00279     {
00280         pPmObj_t pframe;
00281         pPmObj_t pstr;
00282         PmReturn_t retval;
00283 
00284         printf("Traceback (top first):\n");
00285 
00286         /* Get the top frame */
00287         pframe = (pPmObj_t)gVmGlobal.pthread->pframe;
00288 
00289         /* If it's the native frame, print the native function name */
00290         if (pframe == (pPmObj_t)&(gVmGlobal.nativeframe))
00291         {
00292 
00293             /* The last name in the names tuple of the code obj is the name */
00294             retval = tuple_getItem((pPmObj_t)gVmGlobal.nativeframe.nf_func->
00295                                    f_co->co_names, -1, &pstr);
00296             if ((retval) != PM_RET_OK)
00297             {
00298                 printf("  Unable to get native func name.\n");
00299                 return;
00300             }
00301             else
00302             {
00303                 printf("  %s() __NATIVE__\n", ((pPmString_t)pstr)->val);
00304             }
00305 
00306             /* Get the frame that called the native frame */
00307             pframe = (pPmObj_t)gVmGlobal.nativeframe.nf_back;
00308         }
00309 
00310         /* Print the remaining frame stack */
00311         for (;
00312              pframe != C_NULL;
00313              pframe = (pPmObj_t)((pPmFrame_t)pframe)->fo_back)
00314         {
00315             /* The last name in the names tuple of the code obj is the name */
00316             retval = tuple_getItem((pPmObj_t)((pPmFrame_t)pframe)->
00317                                    fo_func->f_co->co_names, -1, &pstr);
00318             if ((retval) != PM_RET_OK) break;
00319 
00320             printf("  %s()\n", ((pPmString_t)pstr)->val);
00321         }
00322         printf("  <module>.\n");
00323     }
00324 
00325 #endif /* HAVE_DEBUG_INFO */
00326 }
00327 

Generated on Mon Oct 18 07:40:46 2010 for Python-on-a-chip by  doxygen 1.5.9