⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jsopcode.c

📁 java script test programing source code
💻 C
📖 第 1 页 / 共 5 页
字号:
    if (nb > 0 && !SprintAlloc(sp, nb))        return -1;    /* Advance offset and copy s into sp's buffer. */    offset = sp->offset;    sp->offset += len;    bp = sp->base + offset;    memmove(bp, s, len);    bp[len] = 0;    return offset;}static ptrdiff_tSprintCString(Sprinter *sp, const char *s){    return SprintPut(sp, s, strlen(s));}static ptrdiff_tSprint(Sprinter *sp, const char *format, ...){    va_list ap;    char *bp;    ptrdiff_t offset;    va_start(ap, format);    bp = JS_vsmprintf(format, ap);      /* XXX vsaprintf */    va_end(ap);    if (!bp) {        JS_ReportOutOfMemory(sp->context);        return -1;    }    offset = SprintCString(sp, bp);    free(bp);    return offset;}const jschar js_EscapeMap[] = {    '\b', 'b',    '\f', 'f',    '\n', 'n',    '\r', 'r',    '\t', 't',    '\v', 'v',    '"',  '"',    '\'', '\'',    '\\', '\\',    0};#define DONT_ESCAPE     0x10000static char *QuoteString(Sprinter *sp, JSString *str, uint32 quote){    JSBool dontEscape, ok;    jschar qc, c;    ptrdiff_t off, len, nb;    const jschar *s, *t, *u, *z;    char *bp;    /* Sample off first for later return value pointer computation. */    dontEscape = (quote & DONT_ESCAPE) != 0;    qc = (jschar) quote;    off = sp->offset;    if (qc && Sprint(sp, "%c", (char)qc) < 0)        return NULL;    /* Loop control variables: z points at end of string sentinel. */    s = JSSTRING_CHARS(str);    z = s + JSSTRING_LENGTH(str);    for (t = s; t < z; s = ++t) {        /* Move t forward from s past un-quote-worthy characters. */        c = *t;        while (JS_ISPRINT(c) && c != qc && c != '\\' && !(c >> 8)) {            c = *++t;            if (t == z)                break;        }        len = PTRDIFF(t, s, jschar);        /* Allocate space for s, including the '\0' at the end. */        nb = (sp->offset + len + 1) - sp->size;        if (nb > 0 && !SprintAlloc(sp, nb))            return NULL;        /* Advance sp->offset and copy s into sp's buffer. */        bp = sp->base + sp->offset;        sp->offset += len;        while (--len >= 0)            *bp++ = (char) *s++;        *bp = '\0';        if (t == z)            break;        /* Use js_EscapeMap, \u, or \x only if necessary. */        if ((u = js_strchr(js_EscapeMap, c)) != NULL) {            ok = dontEscape                 ? Sprint(sp, "%c", (char)c) >= 0                 : Sprint(sp, "\\%c", (char)u[1]) >= 0;        } else {#ifdef JS_C_STRINGS_ARE_UTF8            /* If this is a surrogate pair, make sure to print the pair. */            if (c >= 0xD800 && c <= 0xDBFF) {                jschar buffer[3];                buffer[0] = c;                buffer[1] = *++t;                buffer[2] = 0;                if (t == z) {                    char numbuf[10];                    JS_snprintf(numbuf, sizeof numbuf, "0x%x", c);                    JS_ReportErrorFlagsAndNumber(sp->context, JSREPORT_ERROR,                                                 js_GetErrorMessage, NULL,                                                 JSMSG_BAD_SURROGATE_CHAR,                                                 numbuf);                    ok = JS_FALSE;                    break;                }                ok = Sprint(sp, "%hs", buffer) >= 0;            } else {                /* Print as UTF-8 string. */                ok = Sprint(sp, "%hc", c) >= 0;            }#else            /* Use \uXXXX or \xXX  if the string can't be displayed as UTF-8. */            ok = Sprint(sp, (c >> 8) ? "\\u%04X" : "\\x%02X", c) >= 0;#endif        }        if (!ok)            return NULL;    }    /* Sprint the closing quote and return the quoted string. */    if (qc && Sprint(sp, "%c", (char)qc) < 0)        return NULL;    /*     * If we haven't Sprint'd anything yet, Sprint an empty string so that     * the OFF2STR below gives a valid result.     */    if (off == sp->offset && Sprint(sp, "") < 0)        return NULL;    return OFF2STR(sp, off);}JSString *js_QuoteString(JSContext *cx, JSString *str, jschar quote){    void *mark;    Sprinter sprinter;    char *bytes;    JSString *escstr;    mark = JS_ARENA_MARK(&cx->tempPool);    INIT_SPRINTER(cx, &sprinter, &cx->tempPool, 0);    bytes = QuoteString(&sprinter, str, quote);    escstr = bytes ? JS_NewStringCopyZ(cx, bytes) : NULL;    JS_ARENA_RELEASE(&cx->tempPool, mark);    return escstr;}/************************************************************************/#if JS_HAS_BLOCK_SCOPEtypedef enum JSBraceState {    ALWAYS_BRACE,    MAYBE_BRACE,    DONT_BRACE} JSBraceState;#endifstruct JSPrinter {    Sprinter        sprinter;       /* base class state */    JSArenaPool     pool;           /* string allocation pool */    uintN           indent;         /* indentation in spaces */    JSPackedBool    pretty;         /* pretty-print: indent, use newlines */    JSPackedBool    grouped;        /* in parenthesized expression context */    JSScript        *script;        /* script being printed */    jsbytecode      *dvgfence;      /* js_DecompileValueGenerator fencepost */    JSScope         *scope;         /* script function scope */#if JS_HAS_BLOCK_SCOPE    JSBraceState    braceState;     /* remove braces around let declaration */    ptrdiff_t       spaceOffset;    /* -1 or offset of space before maybe-{ */#endif};/* * Hack another flag, a la JS_DONT_PRETTY_PRINT, into uintN indent parameters * to functions such as js_DecompileFunction and js_NewPrinter.  This time, as * opposed to JS_DONT_PRETTY_PRINT back in the dark ages, we can assume that a * uintN is at least 32 bits. */#define JS_IN_GROUP_CONTEXT 0x10000JSPrinter *js_NewPrinter(JSContext *cx, const char *name, uintN indent, JSBool pretty){    JSPrinter *jp;    jp = (JSPrinter *) JS_malloc(cx, sizeof(JSPrinter));    if (!jp)        return NULL;    INIT_SPRINTER(cx, &jp->sprinter, &jp->pool, 0);    JS_InitArenaPool(&jp->pool, name, 256, 1);    jp->indent = indent & ~JS_IN_GROUP_CONTEXT;    jp->pretty = pretty;    jp->grouped = (indent & JS_IN_GROUP_CONTEXT) != 0;    jp->script = NULL;    jp->dvgfence = NULL;    jp->scope = NULL;#if JS_HAS_BLOCK_SCOPE    jp->braceState = ALWAYS_BRACE;    jp->spaceOffset = -1;#endif    return jp;}voidjs_DestroyPrinter(JSPrinter *jp){    JS_FinishArenaPool(&jp->pool);    JS_free(jp->sprinter.context, jp);}JSString *js_GetPrinterOutput(JSPrinter *jp){    JSContext *cx;    JSString *str;    cx = jp->sprinter.context;    if (!jp->sprinter.base)        return cx->runtime->emptyString;    str = JS_NewStringCopyZ(cx, jp->sprinter.base);    if (!str)        return NULL;    JS_FreeArenaPool(&jp->pool);    INIT_SPRINTER(cx, &jp->sprinter, &jp->pool, 0);    return str;}#if !JS_HAS_BLOCK_SCOPE# define SET_MAYBE_BRACE(jp)    jp# define CLEAR_MAYBE_BRACE(jp)  jp#else# define SET_MAYBE_BRACE(jp)    ((jp)->braceState = MAYBE_BRACE, (jp))# define CLEAR_MAYBE_BRACE(jp)  ((jp)->braceState = ALWAYS_BRACE, (jp))static voidSetDontBrace(JSPrinter *jp){    ptrdiff_t offset;    const char *bp;    /* When not pretty-printing, newline after brace is chopped. */    JS_ASSERT(jp->spaceOffset < 0);    offset = jp->sprinter.offset - (jp->pretty ? 3 : 2);    /* The shortest case is "if (x) {". */    JS_ASSERT(offset >= 6);    bp = jp->sprinter.base;    if (bp[offset+0] == ' ' && bp[offset+1] == '{') {        JS_ASSERT(!jp->pretty || bp[offset+2] == '\n');        jp->spaceOffset = offset;        jp->braceState = DONT_BRACE;    }}#endifintjs_printf(JSPrinter *jp, const char *format, ...){    va_list ap;    char *bp, *fp;    int cc;    if (*format == '\0')        return 0;    va_start(ap, format);    /* If pretty-printing, expand magic tab into a run of jp->indent spaces. */    if (*format == '\t') {        format++;#if JS_HAS_BLOCK_SCOPE        if (*format == '}' && jp->braceState != ALWAYS_BRACE) {            JSBraceState braceState;            braceState = jp->braceState;            jp->braceState = ALWAYS_BRACE;            if (braceState == DONT_BRACE) {                ptrdiff_t offset, delta, from;                JS_ASSERT(format[1] == '\n' || format[1] == ' ');                offset = jp->spaceOffset;                JS_ASSERT(offset >= 6);                /* Replace " {\n" at the end of jp->sprinter with "\n". */                bp = jp->sprinter.base;                if (bp[offset+0] == ' ' && bp[offset+1] == '{') {                    delta = 2;                    if (jp->pretty) {                        /* If pretty, we don't have to worry about 'else'. */                        JS_ASSERT(bp[offset+2] == '\n');                    } else if (bp[offset-1] != ')') {                        /* Must keep ' ' to avoid 'dolet' or 'elselet'. */                        ++offset;                        delta = 1;                    }                    from = offset + delta;                    memmove(bp + offset, bp + from, jp->sprinter.offset - from);                    jp->sprinter.offset -= delta;                    jp->spaceOffset = -1;                    format += 2;                    if (*format == '\0')                        return 0;                }            }        }#endif        if (jp->pretty && Sprint(&jp->sprinter, "%*s", jp->indent, "") < 0)            return -1;    }    /* Suppress newlines (must be once per format, at the end) if not pretty. */    fp = NULL;    if (!jp->pretty && format[cc = strlen(format) - 1] == '\n') {        fp = JS_strdup(jp->sprinter.context, format);        if (!fp)            return -1;        fp[cc] = '\0';        format = fp;    }    /* Allocate temp space, convert format, and put. */    bp = JS_vsmprintf(format, ap);      /* XXX vsaprintf */    if (fp) {        JS_free(jp->sprinter.context, fp);        format = NULL;    }    if (!bp) {        JS_ReportOutOfMemory(jp->sprinter.context);        return -1;    }    cc = strlen(bp);    if (SprintPut(&jp->sprinter, bp, (size_t)cc) < 0)        cc = -1;    free(bp);    va_end(ap);    return cc;}JSBooljs_puts(JSPrinter *jp, const char *s){    return SprintCString(&jp->sprinter, s) >= 0;}/************************************************************************/typedef struct SprintStack {    Sprinter    sprinter;       /* sprinter for postfix to infix buffering */    ptrdiff_t   *offsets;       /* stack of postfix string offsets */    jsbytecode  *opcodes;       /* parallel stack of JS opcodes */    uintN       top;            /* top of stack index */    uintN       inArrayInit;    /* array initialiser/comprehension level */    JSPrinter   *printer;       /* permanent output goes here */} SprintStack;/* * Get a stacked offset from ss->sprinter.base, or if the stacked value |off| * is negative, lazily fetch the generating pc at |spindex = 1 + off| and try * to decompile the code that generated the missing value.  This is used when * reporting errors, where the model stack will lack |pcdepth| non-negative * offsets (see js_DecompileValueGenerator and js_DecompileCode). * * If the stacked offset is -1, return 0 to index the NUL padding at the start * of ss->sprinter.base.  If this happens, it means there is a decompiler bug * to fix, but it won't violate memory safety. */static ptrdiff_tGetOff(SprintStack *ss, uintN i){    ptrdiff_t off;    JSString *str;    off = ss->offsets[i];    if (off < 0) {#if defined DEBUG_brendan || defined DEBUG_mrbkap || defined DEBUG_crowder        JS_ASSERT(off < -1);#endif        if (++off == 0) {            if (!ss->sprinter.base && SprintPut(&ss->sprinter, "", 0) >= 0)                memset(ss->sprinter.base, 0, ss->sprinter.offset);            return 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -