mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Fix imacro vs. script code disassembly/decompilation confusion (510644, r=jorendorff).
This commit is contained in:
parent
cf62469ed2
commit
fd61e1b61a
@ -341,6 +341,14 @@ function assemble(filename) {
|
||||
if (!imacro)
|
||||
throw new Error("opcode " + opname + " outside of .imacro");
|
||||
|
||||
// Blacklist ops that may or must use an atomized double immediate.
|
||||
switch (info.opname) {
|
||||
case "double":
|
||||
case "lookupswitch":
|
||||
case "lookupswitchx":
|
||||
throw new Error(op.opname + " opcode not yet supported");
|
||||
}
|
||||
|
||||
if (label) {
|
||||
imacro.labeldefs[label] = imacro.offset;
|
||||
imacro.labeldef_indexes[label] = imacro.code.length;
|
||||
|
@ -365,7 +365,7 @@ js_Disassemble1(JSContext *cx, JSScript *script, jsbytecode *pc,
|
||||
case JOF_REGEXP:
|
||||
index = js_GetIndexFromBytecode(cx, script, pc, 0);
|
||||
if (type == JOF_ATOM) {
|
||||
JS_GET_SCRIPT_ATOM(script, index, atom);
|
||||
JS_GET_SCRIPT_ATOM(script, pc, index, atom);
|
||||
v = ATOM_KEY(atom);
|
||||
} else {
|
||||
if (type == JOF_OBJECT)
|
||||
@ -424,7 +424,7 @@ js_Disassemble1(JSContext *cx, JSScript *script, jsbytecode *pc,
|
||||
pc2 += UINT16_LEN;
|
||||
fprintf(fp, " offset %d npairs %u", (intN) off, (uintN) npairs);
|
||||
while (npairs) {
|
||||
JS_GET_SCRIPT_ATOM(script, GET_INDEX(pc2), atom);
|
||||
JS_GET_SCRIPT_ATOM(script, pc, GET_INDEX(pc2), atom);
|
||||
pc2 += INDEX_LEN;
|
||||
off = GetJumpOffset(pc, pc2);
|
||||
pc2 += jmplen;
|
||||
@ -452,7 +452,7 @@ js_Disassemble1(JSContext *cx, JSScript *script, jsbytecode *pc,
|
||||
fprintf(fp, " %u", GET_SLOTNO(pc));
|
||||
index = js_GetIndexFromBytecode(cx, script, pc, SLOTNO_LEN);
|
||||
if (type == JOF_SLOTATOM) {
|
||||
JS_GET_SCRIPT_ATOM(script, index, atom);
|
||||
JS_GET_SCRIPT_ATOM(script, pc, index, atom);
|
||||
v = ATOM_KEY(atom);
|
||||
} else {
|
||||
JS_GET_SCRIPT_OBJECT(script, index, obj);
|
||||
@ -1345,6 +1345,9 @@ IsVarSlot(JSPrinter *jp, jsbytecode *pc, jsint *indexp)
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
#define LOAD_ATOM(PCOFF) \
|
||||
GET_ATOM_FROM_BYTECODE(jp->script, pc, PCOFF, atom)
|
||||
|
||||
#if JS_HAS_DESTRUCTURING
|
||||
|
||||
#define LOCAL_ASSERT(expr) LOCAL_ASSERT_RV(expr, NULL)
|
||||
@ -1405,7 +1408,7 @@ DecompileDestructuringLHS(SprintStack *ss, jsbytecode *pc, jsbytecode *endpc,
|
||||
atom = GetArgOrVarAtom(jp, GET_SLOTNO(pc));
|
||||
LOCAL_ASSERT(atom);
|
||||
} else if (op == JSOP_SETGVAR) {
|
||||
GET_ATOM_FROM_BYTECODE(jp->script, pc, 0, atom);
|
||||
LOAD_ATOM(0);
|
||||
} else if (IsVarSlot(jp, pc, &i)) {
|
||||
atom = GetArgOrVarAtom(jp, i);
|
||||
LOCAL_ASSERT(atom);
|
||||
@ -1539,7 +1542,7 @@ DecompileDestructuring(SprintStack *ss, jsbytecode *pc, jsbytecode *endpc)
|
||||
case JSOP_INT32: d = i = GET_INT32(pc); goto do_getelem;
|
||||
|
||||
case JSOP_DOUBLE:
|
||||
GET_ATOM_FROM_BYTECODE(jp->script, pc, 0, atom);
|
||||
GET_DOUBLE_FROM_BYTECODE(jp->script, pc, 0, atom);
|
||||
d = *ATOM_TO_DOUBLE(atom);
|
||||
LOCAL_ASSERT(JSDOUBLE_IS_FINITE(d) && !JSDOUBLE_IS_NEGZERO(d));
|
||||
i = (jsint)d;
|
||||
@ -1575,7 +1578,7 @@ DecompileDestructuring(SprintStack *ss, jsbytecode *pc, jsbytecode *endpc)
|
||||
|
||||
case JSOP_CALLPROP:
|
||||
case JSOP_GETPROP:
|
||||
GET_ATOM_FROM_BYTECODE(jp->script, pc, 0, atom);
|
||||
LOAD_ATOM(0);
|
||||
do_destructure_atom:
|
||||
*OFF2STR(&ss->sprinter, head) = '{';
|
||||
str = ATOM_TO_STRING(atom);
|
||||
@ -1858,9 +1861,6 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
||||
return NULL; \
|
||||
JS_END_MACRO
|
||||
|
||||
#define LOAD_ATOM(PCOFF) \
|
||||
GET_ATOM_FROM_BYTECODE(jp->script, pc, PCOFF, atom)
|
||||
|
||||
#define LOAD_OBJECT(PCOFF) \
|
||||
GET_OBJECT_FROM_BYTECODE(jp->script, pc, PCOFF, obj)
|
||||
|
||||
@ -3993,7 +3993,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
||||
break;
|
||||
|
||||
case JSOP_DOUBLE:
|
||||
LOAD_ATOM(0);
|
||||
GET_DOUBLE_FROM_BYTECODE(jp->script, pc, 0, atom);
|
||||
val = ATOM_KEY(atom);
|
||||
LOCAL_ASSERT(JSVAL_IS_DOUBLE(val));
|
||||
todo = SprintDoubleValue(&ss->sprinter, val, &saveop);
|
||||
@ -4272,7 +4272,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
||||
} else {
|
||||
table[k].label = NULL;
|
||||
}
|
||||
JS_GET_SCRIPT_ATOM(jp->script, GET_INDEX(pc2), atom);
|
||||
JS_GET_SCRIPT_ATOM(jp->script, pc, GET_INDEX(pc2), atom);
|
||||
pc2 += INDEX_LEN;
|
||||
off2 = GetJumpOffset(pc, pc2);
|
||||
pc2 += jmplen;
|
||||
|
@ -311,8 +311,27 @@ js_GetIndexFromBytecode(JSContext *cx, JSScript *script, jsbytecode *pc,
|
||||
*/
|
||||
#define GET_ATOM_FROM_BYTECODE(script, pc, pcoff, atom) \
|
||||
JS_BEGIN_MACRO \
|
||||
JS_ASSERT(*(pc) != JSOP_DOUBLE); \
|
||||
uintN index_ = js_GetIndexFromBytecode(cx, (script), (pc), (pcoff)); \
|
||||
JS_GET_SCRIPT_ATOM((script), index_, atom); \
|
||||
JS_GET_SCRIPT_ATOM(script, pc, index_, atom); \
|
||||
JS_END_MACRO
|
||||
|
||||
/*
|
||||
* Variant for getting a double atom when we might be in an imacro. Bytecodes
|
||||
* with literals that are only ever doubles must use this macro, and never use
|
||||
* GET_ATOM_FROM_BYTECODE or JS_GET_SCRIPT_ATOM.
|
||||
*
|
||||
* Unfortunately some bytecodes such as JSOP_LOOKUPSWITCH have immediates that
|
||||
* might be string or double atoms. Those opcodes cannot be used from imacros.
|
||||
* See the assertions in the JSOP_DOUBLE and JSOP_LOOKUPSWTICH* opcode cases in
|
||||
* jsops.cpp.
|
||||
*/
|
||||
#define GET_DOUBLE_FROM_BYTECODE(script, pc, pcoff, atom) \
|
||||
JS_BEGIN_MACRO \
|
||||
uintN index_ = js_GetIndexFromBytecode(cx, (script), (pc), (pcoff)); \
|
||||
JS_ASSERT(index_ < (script)->atomMap.length); \
|
||||
(atom) = (script)->atomMap.vector[index_]; \
|
||||
JS_ASSERT(ATOM_IS_DOUBLE(atom)); \
|
||||
JS_END_MACRO
|
||||
|
||||
#define GET_OBJECT_FROM_BYTECODE(script, pc, pcoff, obj) \
|
||||
|
@ -2395,6 +2395,10 @@
|
||||
END_CASE(JSOP_RESETBASE)
|
||||
|
||||
BEGIN_CASE(JSOP_DOUBLE)
|
||||
JS_ASSERT(!fp->imacpc);
|
||||
JS_ASSERT(atoms == script->atomMap.vector);
|
||||
/* FALL THROUGH */
|
||||
|
||||
BEGIN_CASE(JSOP_STRING)
|
||||
LOAD_ATOM(0);
|
||||
PUSH_OPND(ATOM_KEY(atom));
|
||||
@ -2617,6 +2621,7 @@
|
||||
* JSOP_LOOKUPSWITCH and JSOP_LOOKUPSWITCHX are never used if
|
||||
* any atom index in it would exceed 64K limit.
|
||||
*/
|
||||
JS_ASSERT(!fp->imacpc);
|
||||
JS_ASSERT(atoms == script->atomMap.vector);
|
||||
pc2 = regs.pc;
|
||||
lval = POP_OPND();
|
||||
|
@ -161,10 +161,15 @@ StackDepth(JSScript *script)
|
||||
(JS_ASSERT((script)->trynotesOffset != 0), \
|
||||
(JSTryNoteArray *)((uint8 *)(script) + (script)->trynotesOffset))
|
||||
|
||||
#define JS_GET_SCRIPT_ATOM(script_, index, atom) \
|
||||
/*
|
||||
* If pc_ does not point within script_'s bytecode, then it must point into an
|
||||
* imacro body, so we use cx->runtime common atoms instead of script_'s atoms.
|
||||
* This macro uses cx from its callers' environments in the pc-in-imacro case.
|
||||
*/
|
||||
#define JS_GET_SCRIPT_ATOM(script_, pc_, index, atom) \
|
||||
JS_BEGIN_MACRO \
|
||||
JSStackFrame *fp_ = js_GetTopStackFrame(cx); \
|
||||
if (fp_ && fp_->imacpc && fp_->script == script_) { \
|
||||
if ((pc_) < (script_)->code || \
|
||||
(script_)->code + (script_)->length <= (pc_)) { \
|
||||
JS_ASSERT((size_t)(index) < js_common_atom_count); \
|
||||
(atom) = COMMON_ATOMS_START(&cx->runtime->atomState)[index]; \
|
||||
} else { \
|
||||
|
@ -1619,7 +1619,7 @@ SrcNotes(JSContext *cx, JSScript *script)
|
||||
case SRC_BREAK2LABEL:
|
||||
case SRC_CONT2LABEL:
|
||||
index = js_GetSrcNoteOffset(sn, 0);
|
||||
JS_GET_SCRIPT_ATOM(script, index, atom);
|
||||
JS_GET_SCRIPT_ATOM(script, NULL, index, atom);
|
||||
JS_ASSERT(ATOM_IS_STRING(atom));
|
||||
str = ATOM_TO_STRING(atom);
|
||||
fprintf(gOutFile, " atom %u (", index);
|
||||
|
@ -0,0 +1,7 @@
|
||||
function f() {
|
||||
for (var i=0; i<9; i++)
|
||||
assertEq("" + f, expected);
|
||||
}
|
||||
|
||||
var expected = "" + f;
|
||||
f();
|
Loading…
Reference in New Issue
Block a user