Changeset 174


Ignore:
Timestamp:
Jan 3, 2004, 11:37:17 AM (21 years ago)
Author:
Gary Byers
Message:

Integrate a little better with the new debugger.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/ccl/lisp-kernel/lisp-exceptions.c

    r137 r174  
    17861786      return(noErr);
    17871787    }
    1788 
    1789     if ((the_trap & OP_MASK) == OP(major_opcode_TWI)) {
    1790       /* TWI.  If the RA field is "nargs", that means that the
    1791          instruction is either a number-of-args check or an
    1792          event-poll.  Otherwise, the trap is some sort of
    1793          typecheck. */
    1794 
    1795       if (RA_field(the_trap) == nargs) {
    1796         fn_reg = nfn;
    1797         switch (TO_field(the_trap)) {
    1798         case TO_NE:
    1799           error_msg = ( (xpGPR(xp, nargs) < D_field(the_trap))
    1800                        ? "Too few arguments (no opt/rest)"
    1801                        : "Too many arguments (no opt/rest)" );
    1802           break;
    1803        
    1804         case TO_GT:
    1805           error_msg = "Event poll !";
    1806           break;
    1807 
    1808         case TO_HI:
    1809           error_msg = "Too many arguments (with opt)";
    1810           break;
    1811        
    1812         case TO_LT:
    1813           error_msg = "Too few arguments (with opt/rest/key)";
    1814           break;
    1815        
    1816         default:                /* some weird trap, not ours. */
    1817           fn_reg = 0;
    1818           break;
    1819         }
    1820       } else {
    1821         /* A type or boundp trap of some sort. */
    1822         switch (TO_field(the_trap)) {
    1823         case TO_EQ:
    1824           /* Boundp traps are of the form:
    1825              tweqi rX,unbound
    1826              where some preceding instruction is of the form:
    1827              lwz rX,symbol.value(rY).
    1828              The error message should try to say that rY is unbound. */
    1829 
    1830           if (D_field(the_trap) == unbound) {
    1831             instr = scan_for_instr(LWZ_instruction(RA_field(the_trap),
    1832                                                    unmasked_register,
    1833                                                    offsetof(lispsymbol,vcell)-fulltag_misc),
    1834                                    D_RT_IMM_MASK,
    1835                                    where);
    1836             if (instr) {
    1837               ra = RA_field(instr);
    1838               if (lisp_reg_p(ra)) {
    1839                 error_msg = "Unbound variable: %s";
    1840                 (void)symbol_name( xpGPR(xp, ra), name, kNameBufLen );
    1841                 err_arg1 = (unsigned)name;
    1842                 fn_reg = fn;
    1843               }
    1844             }
    1845           }
    1846           break;
    1847 
    1848         case TO_NE:
    1849           /* A type check.  If the type (the immediate field of the trap instruction)
    1850              is a header type, an "lbz rX,misc_header_offset(rY)" should precede it,
    1851              in which case we say that "rY is not of header type <type>."  If the
    1852              type is not a header type, then rX should have been set by a preceding
    1853              "clrlwi rX,rY,29/30".  In that case, scan backwards for an RLWINM instruction
    1854              that set rX and report that rY isn't of the indicated type. */
    1855           err_arg2 = D_field(the_trap);
    1856           if (((err_arg2 & fulltagmask) == fulltag_nodeheader) ||
    1857               ((err_arg2 & fulltagmask) == fulltag_immheader)) {
    1858             instr = scan_for_instr(LBZ_instruction(RA_field(the_trap),
    1859                                                    unmasked_register,
    1860                                                    misc_subtag_offset),
    1861                                    D_RT_IMM_MASK,
    1862                                    where);
    1863             if (instr) {
    1864               ra = RA_field(instr);
    1865               if (lisp_reg_p(ra)) {
    1866                 error_msg = "value %08X is not of the expected header type %02X";
    1867                 err_arg1 = xpGPR(xp, ra);
    1868                 fn_reg = fn;
    1869               }
    1870             }
    1871           } else {             
    1872             /* Not a header type, look for rlwinm whose RA field matches the_trap's */
    1873             instr = scan_for_instr((OP(major_opcode_RLWINM) | (the_trap & RA_MASK)),
    1874                                    (OP_MASK | RA_MASK),
    1875                                    where);
    1876             if (instr) {
    1877               rs = RS_field(instr);
    1878               if (lisp_reg_p(rs)) {
    1879                 error_msg = "value %08X is not of the expected type %02X";
    1880                 err_arg1 = xpGPR(xp, rs);
    1881                 fn_reg = fn;
    1882               }
    1883             }
    1884           }
    1885           break;
    1886         }
    1887       }
    1888     } else {
    1889       /* a "TW <to>,ra,rb" instruction."
    1890          twltu sp,rN is stack-overflow on SP.
    1891          twgeu rX,rY is subscript out-of-bounds, which was preceded
    1892          by an "lwz rM,misc_header_offset(rN)" instruction.
    1893          rM may or may not be the same as rY, but no other header
    1894          would have been loaded before the trap. */
    1895       switch (TO_field(the_trap)) {
    1896       case TO_LO:
    1897         if (RA_field(the_trap) == sp) {
    1898           fn_reg = fn;
    1899           error_msg = "Stack overflow! Run away! Run away!";
    1900         }
    1901         break;
    1902 
    1903       case (TO_HI|TO_EQ):
    1904         instr = scan_for_instr(OP(major_opcode_LWZ) | (D_MASK & misc_header_offset),
    1905                                (OP_MASK | D_MASK),
    1906                                where);
    1907         if (instr) {
    1908           ra = RA_field(instr);
    1909           if (lisp_reg_p(ra)) {
    1910             error_msg = "Bad index %d for vector %08X length %d";
    1911             err_arg1 = unbox_fixnum(xpGPR(xp, RA_field(the_trap)));
    1912             err_arg2 = xpGPR(xp, ra);
    1913             err_arg3 = unbox_fixnum(xpGPR(xp, RB_field(the_trap)));
    1914             fn_reg = fn;
    1915           }
    1916         }
    1917         break;
    1918       }
    1919     }
    1920  
    1921 
    1922     if (!error_msg) {
    1923       return -1;
    1924     }
    1925 
    1926     fprintf( stderr, "\nError: ");
    1927     fprintf( stderr, error_msg, err_arg1, err_arg2, err_arg3 );
    1928     fprintf( stderr, "\n");
    1929     if (fn_reg && exception_fn_name( xp, fn_reg, name, kNameBufLen )) {
    1930       fprintf( stderr, "While executing: %s.\n", name );
    1931     }
    1932     fflush( stderr );
    1933     switch( error_action() ) {
    1934     case kDebugger:
    1935       return(-1);
    1936       break;
    1937     case kContinue:
    1938       adjust_exception_pc(xp, 4);
    1939       return(noErr);
    1940       break;
    1941     case kExit:
    1942     default:
    1943       terminate_lisp();
    1944       break;
    1945     }
    19461788    return -1;
    19471789  }
     
    19671809}
    19681810
    1969 /* Copy function name to name & terminate, return # chars */
    1970 size_t
    1971 exception_fn_name( ExceptionInformation *xp, int fn_reg, char *name, size_t name_len )
    1972 {
    1973   unsigned the_fn = xpGPR(xp, fn_reg);
    1974 
    1975   if ((fulltag_of(the_fn) != fulltag_misc) ||
    1976       (header_subtag(header_of(the_fn)) != subtag_function)) {
    1977     non_fatal_error( "exception_fn_name: bogus fn" );
    1978     name[0] = 0;
    1979     return 0;
    1980   }
    1981 
    1982   if (named_function_p(the_fn)) {
    1983     unsigned the_sym = named_function_name(the_fn);
    1984     /* trust it - if ((fulltag_of(the_sym) == fulltag_misc) &&
    1985        (header_subtag(header_of(the_sym)) == subtag_symbol)) */
    1986 
    1987     return symbol_name( the_sym, name, name_len );
    1988 
    1989   } else {                      /* unnamed function */
    1990     strcpy( name, "<Anonymous Function>" );
    1991     return strlen(name);
    1992   }
    1993 }
    1994 
    1995 /* Make name a c-string of symbol's pname, return length */
    1996 size_t
    1997 symbol_name( unsigned the_sym, char *name, size_t name_len )
    1998 {
    1999   unsigned the_pname = ((lispsymbol *)(untag(the_sym)))->pname;
    2000   /* trust it - if (the_pname) */
    2001 
    2002   size_t length = header_element_count(header_of(the_pname));
    2003   if (length >= name_len) length = name_len - 1;
    2004   memcpy( (void *)name,
    2005          (const void *)(the_pname + misc_data_offset),
    2006          length );
    2007   name[length] = 0;
    2008   return length;
    2009 }
    20101811
    20111812void non_fatal_error( char *msg )
     
    20611862    }
    20621863
    2063   switch (errnum) {
    2064   case error_udf_call:
    2065     rb = xpGPR(xp, fname);
    2066     if ((fulltag_of(rb) == fulltag_misc) &&
    2067         (header_subtag(header_of(rb)) == subtag_symbol)) {
    2068       pname = ((lispsymbol *)(untag(rb)))->pname;
    2069     } else {
    2070       pname = (LispObj)NULL;
    2071     }
    2072      
    2073     fprintf(stderr, "\nERROR: undefined function call: ");
    2074     if (pname) {
    2075       fwrite((const void *)(pname+misc_data_offset),
    2076              1,
    2077              header_element_count(header_of(pname)),
    2078              stderr);
    2079     } else {
    2080       fprintf(stderr, "[can't determine symbol name.]");
    2081     }
    2082     putc('\n',stderr);
    2083     fflush(stderr);
    2084     switch( error_action() ) {
    2085     case kExit:
    2086       terminate_lisp();
    2087       break;
    2088     case kDebugger:
    2089     default:
    2090       return(-1);
    2091       break;
    2092     }
    2093     break;
    2094   default:
    2095     break;
    2096   }
    20971864  return(-1);
    20981865}
    20991866               
    2100 ErrAction
    2101 error_action( void )
    2102 {
    2103   /* getchar reads from line start, so end message with \n */
    2104   fprintf( stderr, "\nContinue/Debugger/eXit <enter>?\n" );
    2105   fflush( stderr );
    2106 
    2107   do {
    2108     int c = toupper( getchar() );
    2109     switch( c ) {
    2110     case 'X':
    2111       return( kExit );
    2112       break;
    2113     case 'D':
    2114       return( kDebugger );
    2115       break;
    2116     case 'C':
    2117       return( kContinue );
    2118       break;
    2119     }
    2120   } while( true );
    2121 }
    21221867
    21231868/*
     
    24302175}
    24312176
    2432 Boolean
    2433 exception_filter_installed_p()
    2434 {
    2435   return true;
    2436 #if 0
    2437   return installed_exception_filter == PMCL_exception_filter;
    2438 #endif
    2439 }
     2177
    24402178
    24412179
Note: See TracChangeset for help on using the changeset viewer.