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

📄 jsopcode.c

📁 Swfdec still is development software, but has also followed a rigid no-crashes-allowed policy. I b
💻 C
📖 第 1 页 / 共 5 页
字号:
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is Mozilla Communicator client code, released * March 31, 1998. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1998 * the Initial Developer. All Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** *//* * JS bytecode descriptors, disassemblers, and decompilers. */#include "jsstddef.h"#ifdef HAVE_MEMORY_H#include <memory.h>#endif#include <stdarg.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include "jstypes.h"#include "jsarena.h" /* Added by JSIFY */#include "jsutil.h" /* Added by JSIFY */#include "jsdtoa.h"#include "jsprf.h"#include "jsapi.h"#include "jsarray.h"#include "jsatom.h"#include "jscntxt.h"#include "jsconfig.h"#include "jsdbgapi.h"#include "jsemit.h"#include "jsfun.h"#include "jslock.h"#include "jsobj.h"#include "jsopcode.h"#include "jsscope.h"#include "jsscript.h"#include "jsstr.h"const char js_const_str[]       = "const";const char js_var_str[]         = "var";const char js_function_str[]    = "function";const char js_in_str[]          = "in";const char js_instanceof_str[]  = "instanceof";const char js_new_str[]         = "new";const char js_delete_str[]      = "delete";const char js_typeof_str[]      = "typeof";const char js_void_str[]        = "void";const char js_null_str[]        = "null";const char js_this_str[]        = "this";const char js_false_str[]       = "false";const char js_true_str[]        = "true";const char *js_incop_str[]      = {"++", "--"};/* Pollute the namespace locally for MSVC Win16, but not for WatCom.  */#ifdef __WINDOWS_386__    #ifdef FAR        #undef FAR    #endif#else  /* !__WINDOWS_386__ */#ifndef FAR#define FAR#endif#endif /* !__WINDOWS_386__ */const JSCodeSpec FAR js_CodeSpec[] = {#define OPDEF(op,val,name,token,length,nuses,ndefs,prec,format) \    {name,token,length,nuses,ndefs,prec,format},#include "jsopcode.tbl"#undef OPDEF};uintN js_NumCodeSpecs = sizeof (js_CodeSpec) / sizeof js_CodeSpec[0];/************************************************************************/static ptrdiff_tGetJumpOffset(jsbytecode *pc, jsbytecode *pc2){    uint32 type;        type = (js_CodeSpec[*pc].format & JOF_TYPEMASK);    if (JOF_TYPE_IS_EXTENDED_JUMP(type))        return GET_JUMPX_OFFSET(pc2);    return GET_JUMP_OFFSET(pc2);}#ifdef DEBUGJS_FRIEND_API(void)js_Disassemble(JSContext *cx, JSScript *script, JSBool lines, FILE *fp){    jsbytecode *pc, *end;    uintN len;    pc = script->code;    end = pc + script->length;    while (pc < end) {        if (pc == script->main)            fputs("main:\n", fp);        len = js_Disassemble1(cx, script, pc,                              PTRDIFF(pc, script->code, jsbytecode),                              lines, fp);        if (!len)            return;        pc += len;    }}JS_FRIEND_API(uintN)js_Disassemble1(JSContext *cx, JSScript *script, jsbytecode *pc, uintN loc,                JSBool lines, FILE *fp){    JSOp op;    const JSCodeSpec *cs;    ptrdiff_t len, off, jmplen;    uint32 type;    JSAtom *atom;    JSString *str;    char *cstr;    op = (JSOp)*pc;    if (op >= JSOP_LIMIT) {        char numBuf1[12], numBuf2[12];        JS_snprintf(numBuf1, sizeof numBuf1, "%d", op);        JS_snprintf(numBuf2, sizeof numBuf2, "%d", JSOP_LIMIT);        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,                             JSMSG_BYTECODE_TOO_BIG, numBuf1, numBuf2);        return 0;    }    cs = &js_CodeSpec[op];    len = (intN)cs->length;    fprintf(fp, "%05u:", loc);    if (lines)        fprintf(fp, "%4u", JS_PCToLineNumber(cx, script, pc));    fprintf(fp, "  %s", cs->name);    type = cs->format & JOF_TYPEMASK;    switch (type) {      case JOF_BYTE:        if (op == JSOP_TRAP) {            op = JS_GetTrapOpcode(cx, script, pc);            if (op == JSOP_LIMIT)                return 0;            len = (intN)js_CodeSpec[op].length;        }        break;      case JOF_JUMP:      case JOF_JUMPX:        off = GetJumpOffset(pc, pc);        fprintf(fp, " %td (%td)", loc + off, off);        break;      case JOF_CONST:        atom = GET_ATOM(cx, script, pc);        str = js_ValueToSource(cx, ATOM_KEY(atom));        if (!str)            return 0;        cstr = js_DeflateString(cx, JSSTRING_CHARS(str), JSSTRING_LENGTH(str));        if (!cstr)            return 0;        fprintf(fp, " %s", cstr);        JS_free(cx, cstr);        break;      case JOF_UINT16:        fprintf(fp, " %u", GET_ARGC(pc));        break;#if JS_HAS_SWITCH_STATEMENT      case JOF_TABLESWITCH:      case JOF_TABLESWITCHX:      {        jsbytecode *pc2;        jsint i, low, high;        jmplen = (type == JOF_TABLESWITCH) ? JUMP_OFFSET_LEN                                           : JUMPX_OFFSET_LEN;        pc2 = pc;        off = GetJumpOffset(pc, pc2);        pc2 += jmplen;        low = GET_JUMP_OFFSET(pc2);        pc2 += JUMP_OFFSET_LEN;        high = GET_JUMP_OFFSET(pc2);        pc2 += JUMP_OFFSET_LEN;        fprintf(fp, " defaultOffset %td low %d high %d", off, low, high);        for (i = low; i <= high; i++) {            off = GetJumpOffset(pc, pc2);            fprintf(fp, "\n\t%d: %td", i, off);            pc2 += jmplen;        }        len = 1 + pc2 - pc;        break;      }      case JOF_LOOKUPSWITCH:      case JOF_LOOKUPSWITCHX:      {        jsbytecode *pc2;        jsint npairs;        jmplen = (type == JOF_LOOKUPSWITCH) ? JUMP_OFFSET_LEN                                            : JUMPX_OFFSET_LEN;        pc2 = pc;        off = GetJumpOffset(pc, pc2);        pc2 += jmplen;        npairs = (jsint) GET_ATOM_INDEX(pc2);        pc2 += ATOM_INDEX_LEN;        fprintf(fp, " offset %td npairs %u", off, (uintN) npairs);        while (npairs) {            atom = GET_ATOM(cx, script, pc2);            pc2 += ATOM_INDEX_LEN;            off = GetJumpOffset(pc, pc2);            pc2 += jmplen;            str = js_ValueToSource(cx, ATOM_KEY(atom));            if (!str)                return 0;            cstr = js_DeflateString(cx, JSSTRING_CHARS(str),                                    JSSTRING_LENGTH(str));            if (!cstr)                return 0;            fprintf(fp, "\n\t%s: %td", cstr, off);            JS_free(cx, cstr);            npairs--;        }        len = 1 + pc2 - pc;        break;      }#endif /* JS_HAS_SWITCH_STATEMENT */      case JOF_QARG:        fprintf(fp, " %u", GET_ARGNO(pc));        break;      case JOF_QVAR:        fprintf(fp, " %u", GET_VARNO(pc));        break;#if JS_HAS_LEXICAL_CLOSURE      case JOF_DEFLOCALVAR:        fprintf(fp, " %u", GET_VARNO(pc));        pc += VARNO_LEN;        atom = GET_ATOM(cx, script, pc);        str = js_ValueToSource(cx, ATOM_KEY(atom));        if (!str)            return 0;        cstr = js_DeflateString(cx, JSSTRING_CHARS(str), JSSTRING_LENGTH(str));        if (!cstr)            return 0;        fprintf(fp, " %s", cstr);        JS_free(cx, cstr);        break;#endif      default: {        char numBuf[12];        JS_snprintf(numBuf, sizeof numBuf, "%lx", (unsigned long) cs->format);        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,                             JSMSG_UNKNOWN_FORMAT, numBuf);        return 0;      }    }    fputs("\n", fp);    return len;}#endif /* DEBUG *//************************************************************************//* * Sprintf, but with unlimited and automatically allocated buffering. */typedef struct Sprinter {    JSContext       *context;       /* context executing the decompiler */    JSArenaPool     *pool;          /* string allocation pool */    char            *base;          /* base address of buffer in pool */    size_t          size;           /* size of buffer allocated at base */    ptrdiff_t       offset;         /* offset of next free char in buffer */} Sprinter;#define INIT_SPRINTER(cx, sp, ap, off) \    ((sp)->context = cx, (sp)->pool = ap, (sp)->base = NULL, (sp)->size = 0,  \     (sp)->offset = off)#define OFF2STR(sp,off) ((sp)->base + (off))#define STR2OFF(sp,str) ((str) - (sp)->base)#define RETRACT(sp,str) ((sp)->offset = STR2OFF(sp, str))static JSBoolSprintAlloc(Sprinter *sp, size_t nb){    if (!sp->base) {        JS_ARENA_ALLOCATE_CAST(sp->base, char *, sp->pool, nb);    } else {        JS_ARENA_GROW_CAST(sp->base, char *, sp->pool, sp->size, nb);    }    if (!sp->base) {        JS_ReportOutOfMemory(sp->context);        return JS_FALSE;    }    sp->size += nb;    return JS_TRUE;}static ptrdiff_tSprintPut(Sprinter *sp, const char *s, size_t len){    ptrdiff_t nb, offset;    char *bp;    /* Allocate space for s, including the '\0' at the end. */    nb = (sp->offset + len + 1) - sp->size;    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_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 = SprintPut(sp, bp, strlen(bp));    free(bp);    return offset;}const jschar js_EscapeMap[] = {    '\b', 'b',    '\f', 'f',    '\n', 'n',

⌨️ 快捷键说明

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