diff options
Diffstat (limited to 'src/dom/js/jsutil.c')
| -rw-r--r-- | src/dom/js/jsutil.c | 213 |
1 files changed, 124 insertions, 89 deletions
diff --git a/src/dom/js/jsutil.c b/src/dom/js/jsutil.c index 6e4c21cad..d7fab0f88 100644 --- a/src/dom/js/jsutil.c +++ b/src/dom/js/jsutil.c @@ -51,107 +51,142 @@ # include <windows.h> #endif -#ifdef XP_MAC -# include <Types.h> -# include <stdarg.h> -# include "jsprf.h" +JS_PUBLIC_API(void) JS_Assert(const char *s, const char *file, JSIntn ln) +{ + fprintf(stderr, "Assertion failure: %s, at %s:%d\n", s, file, ln); +#if defined(WIN32) + DebugBreak(); + exit(3); #endif +#if defined(XP_OS2) + asm("int $3"); +#endif + abort(); +} -#ifdef XP_MAC -/* - * PStrFromCStr converts the source C string to a destination - * pascal string as it copies. The dest string will - * be truncated to fit into an Str255 if necessary. - * If the C String pointer is NULL, the pascal string's length is - * set to zero. - */ -static void PStrFromCStr(const char *src, Str255 dst) +#if defined DEBUG_notme && defined XP_UNIX + +#define __USE_GNU 1 +#include <dlfcn.h> +#include <setjmp.h> +#include <string.h> +#include "jshash.h" +#include "jsprf.h" + +JSCallsite js_calltree_root = {0, NULL, NULL, 0, NULL, NULL, NULL, NULL}; + +static JSCallsite * +CallTree(uint32 *bp) { - short length = 0; - - /* handle case of overlapping strings */ - if ( (void*)src == (void*)dst ) - { - unsigned char *curdst = &dst[1]; - unsigned char thisChar; - - thisChar = *(const unsigned char*)src++; - while ( thisChar != '\0' ) - { - unsigned char nextChar; - - /* - * Use nextChar so we don't overwrite what we - * are about to read - */ - nextChar = *(const unsigned char*)src++; - *curdst++ = thisChar; - thisChar = nextChar; - - if ( ++length >= 255 ) - break; - } + uint32 *bpup, *bpdown, pc; + JSCallsite *parent, *site, **csp; + Dl_info info; + int ok, offset; + const char *symbol; + char *method; + + /* Reverse the stack frame list to avoid recursion. */ + bpup = NULL; + for (;;) { + bpdown = (uint32*) bp[0]; + bp[0] = (uint32) bpup; + if ((uint32*) bpdown[0] < bpdown) + break; + bpup = bp; + bp = bpdown; } - else if ( src != NULL ) - { - unsigned char *curdst = &dst[1]; - /* count down so test it loop is faster */ - short overflow = 255; - register char temp; - /* - * Can't do the K&R C thing of while (*s++ = *t++) - * because it will copy trailing zero which might - * overrun pascal buffer. Instead we use a temp variable. - */ - while ( (temp = *src++) != 0 ) - { - *(char*)curdst++ = temp; + /* Reverse the stack again, finding and building a path in the tree. */ + parent = &js_calltree_root; + do { + bpup = (uint32*) bp[0]; + bp[0] = (uint32) bpdown; + pc = bp[1]; + + csp = &parent->kids; + while ((site = *csp) != NULL) { + if (site->pc == pc) { + /* Put the most recently used site at the front of siblings. */ + *csp = site->siblings; + site->siblings = parent->kids; + parent->kids = site; + + /* Site already built -- go up the stack. */ + goto upward; + } + csp = &site->siblings; + } - if ( --overflow <= 0 ) - break; + /* Check for recursion: see if pc is on our ancestor line. */ + for (site = parent; site; site = site->parent) { + if (site->pc == pc) + goto upward; } - length = 255 - overflow; - } - dst[0] = length; -} -static void jsdebugstr(const char *debuggerMsg) -{ - Str255 pStr; + /* + * Not in tree at all: let's find our symbolic callsite info. + * XXX static syms are masked by nearest lower global + */ + info.dli_fname = info.dli_sname = NULL; + ok = dladdr((void*) pc, &info); + if (ok < 0) { + fprintf(stderr, "dladdr failed!\n"); + return NULL; + } - PStrFromCStr(debuggerMsg, pStr); - DebugStr(pStr); +/* XXXbe sub 0x08040000? or something, see dbaron bug with tenthumbs comment */ + symbol = info.dli_sname; + offset = (char*)pc - (char*)info.dli_fbase; + method = symbol + ? strdup(symbol) + : JS_smprintf("%s+%X", + info.dli_fname ? info.dli_fname : "main", + offset); + if (!method) + return NULL; + + /* Create a new callsite record. */ + site = (JSCallsite *) malloc(sizeof(JSCallsite)); + if (!site) + return NULL; + + /* Insert the new site into the tree. */ + site->pc = pc; + site->name = method; + site->library = info.dli_fname; + site->offset = offset; + site->parent = parent; + site->siblings = parent->kids; + parent->kids = site; + site->kids = NULL; + + upward: + parent = site; + bpdown = bp; + bp = bpup; + } while (bp); + + return site; } -static void dprintf(const char *format, ...) +JSCallsite * +JS_Backtrace(int skip) { - va_list ap; - char *buffer; - - va_start(ap, format); - buffer = (char *)JS_vsmprintf(format, ap); - va_end(ap); + jmp_buf jb; + uint32 *bp, *bpdown; + + setjmp(jb); + + /* Stack walking code adapted from Kipp's "leaky". */ + bp = (uint32*) jb[0].__jmpbuf[JB_BP]; + while (--skip >= 0) { + bpdown = (uint32*) *bp++; + if (bpdown < bp) + break; + bp = bpdown; + } - jsdebugstr(buffer); - JS_smprintf_free(buffer); + return CallTree(bp); } -#endif /* XP_MAC */ -JS_PUBLIC_API(void) JS_Assert(const char *s, const char *file, JSIntn ln) -{ -#ifdef XP_MAC - dprintf("Assertion failure: %s, at %s:%d\n", s, file, ln); -#else - fprintf(stderr, "Assertion failure: %s, at %s:%d\n", s, file, ln); -#endif -#if defined(WIN32) - DebugBreak(); -#endif -#if defined(XP_OS2) - asm("int $3"); -#endif -#ifndef XP_MAC - abort(); -#endif -} +#endif /* DEBUG_notme && XP_UNIX */ |
