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

📄 jsopcode.c

📁 java script test programing source code
💻 C
📖 第 1 页 / 共 5 页
字号:
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * vim: set sw=4 ts=8 et tw=78: * * ***** 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 "jsregexp.h"#include "jsscan.h"#include "jsscope.h"#include "jsscript.h"#include "jsstr.h"#if JS_HAS_DESTRUCTURING# include "jsnum.h"#endifstatic const char js_incop_strs[][3] = {"++", "--"};/* 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(JSBool)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 JS_FALSE;        pc += len;    }    return JS_TRUE;}const char *ToDisassemblySource(JSContext *cx, jsval v){    JSObject *obj;    JSScopeProperty *sprop;    char *source;    const char *bytes;    JSString *str;    if (!JSVAL_IS_PRIMITIVE(v)) {        obj = JSVAL_TO_OBJECT(v);        if (OBJ_GET_CLASS(cx, obj) == &js_BlockClass) {            source = JS_sprintf_append(NULL, "depth %d {",                                       OBJ_BLOCK_DEPTH(cx, obj));            for (sprop = OBJ_SCOPE(obj)->lastProp; sprop;                 sprop = sprop->parent) {                bytes = js_AtomToPrintableString(cx, JSID_TO_ATOM(sprop->id));                if (!bytes)                    return NULL;                source = JS_sprintf_append(source, "%s: %d%s",                                           bytes, sprop->shortid,                                           sprop->parent ? ", " : "");            }            source = JS_sprintf_append(source, "}");            if (!source)                return NULL;            str = JS_NewString(cx, source, strlen(source));            if (!str)                return NULL;            return JS_GetStringBytes(str);        }    }    return js_ValueToPrintableSource(cx, v);}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;    const char *bytes;    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 = (ptrdiff_t) 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 = (ptrdiff_t) js_CodeSpec[op].length;        }        break;      case JOF_JUMP:      case JOF_JUMPX:        off = GetJumpOffset(pc, pc);        fprintf(fp, " %u (%d)", loc + off, off);        break;      case JOF_CONST:        atom = GET_ATOM(cx, script, pc);        bytes = ToDisassemblySource(cx, ATOM_KEY(atom));        if (!bytes)            return 0;        fprintf(fp, " %s", bytes);        break;      case JOF_UINT16:      case JOF_LOCAL:        fprintf(fp, " %u", GET_UINT16(pc));        break;      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 %d low %d high %d", off, low, high);        for (i = low; i <= high; i++) {            off = GetJumpOffset(pc, pc2);            fprintf(fp, "\n\t%d: %d", i, off);            pc2 += jmplen;        }        len = 1 + pc2 - pc;        break;      }      case JOF_LOOKUPSWITCH:      case JOF_LOOKUPSWITCHX:      {        jsbytecode *pc2;        jsatomid npairs;        jmplen = (type == JOF_LOOKUPSWITCH) ? JUMP_OFFSET_LEN                                            : JUMPX_OFFSET_LEN;        pc2 = pc;        off = GetJumpOffset(pc, pc2);        pc2 += jmplen;        npairs = GET_ATOM_INDEX(pc2);        pc2 += ATOM_INDEX_LEN;        fprintf(fp, " offset %d npairs %u", off, (uintN) npairs);        while (npairs) {            atom = GET_ATOM(cx, script, pc2);            pc2 += ATOM_INDEX_LEN;            off = GetJumpOffset(pc, pc2);            pc2 += jmplen;            bytes = ToDisassemblySource(cx, ATOM_KEY(atom));            if (!bytes)                return 0;            fprintf(fp, "\n\t%s: %d", bytes, off);            npairs--;        }        len = 1 + pc2 - pc;        break;      }      case JOF_QARG:        fprintf(fp, " %u", GET_ARGNO(pc));        break;      case JOF_QVAR:        fprintf(fp, " %u", GET_VARNO(pc));        break;      case JOF_INDEXCONST:        fprintf(fp, " %u", GET_VARNO(pc));        pc += VARNO_LEN;        atom = GET_ATOM(cx, script, pc);        bytes = ToDisassemblySource(cx, ATOM_KEY(atom));        if (!bytes)            return 0;        fprintf(fp, " %s", bytes);        break;      case JOF_UINT24:        if (op == JSOP_FINDNAME) {            /* Special case to avoid a JOF_FINDNAME just for this op. */            atom = js_GetAtom(cx, &script->atomMap, GET_UINT24(pc));            bytes = ToDisassemblySource(cx, ATOM_KEY(atom));            if (!bytes)                return 0;            fprintf(fp, " %s", bytes);            break;        }        JS_ASSERT(op == JSOP_UINT24 || op == JSOP_LITERAL);        fprintf(fp, " %u", GET_UINT24(pc));        break;      case JOF_LITOPX:        atom = js_GetAtom(cx, &script->atomMap, GET_LITERAL_INDEX(pc));        bytes = ToDisassemblySource(cx, ATOM_KEY(atom));        if (!bytes)            return 0;        /*         * Bytecode: JSOP_LITOPX <uint24> op [<varno> if JSOP_DEFLOCALFUN].         * Advance pc to point at op.         */        pc += 1 + LITERAL_INDEX_LEN;        op = *pc;        cs = &js_CodeSpec[op];        fprintf(fp, " %s op %s", bytes, cs->name);        if ((cs->format & JOF_TYPEMASK) == JOF_INDEXCONST)            fprintf(fp, " %u", GET_VARNO(pc));        /*         * Set len to advance pc to skip op and any other immediates (namely,         * <varno> if JSOP_DEFLOCALFUN).         */        JS_ASSERT(cs->length > ATOM_INDEX_LEN);        len = cs->length - ATOM_INDEX_LEN;        break;      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){    char *base;    base = sp->base;    if (!base) {        JS_ARENA_ALLOCATE_CAST(base, char *, sp->pool, nb);    } else {        JS_ARENA_GROW_CAST(base, char *, sp->pool, sp->size, nb);    }    if (!base) {        JS_ReportOutOfMemory(sp->context);        return JS_FALSE;    }    sp->base = base;    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;

⌨️ 快捷键说明

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