mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 470964 - Simulate CFG in imacro assembler and decompiler, r=brendan.
This commit is contained in:
parent
76accb1b4f
commit
3471a48ea3
@ -89,7 +89,7 @@ for (let i = 0; i < opinfo.length; i++) {
|
||||
jsop2opcode[info.jsop] = info.opcode;
|
||||
}
|
||||
|
||||
function formatoffset(n, w) {
|
||||
function format_offset(n, w) {
|
||||
let s = n.toString();
|
||||
while (s.length < w)
|
||||
s = ' ' + s;
|
||||
@ -124,6 +124,41 @@ function immediate(op) {
|
||||
throw new Error(info.jsop + " format not yet implemented");
|
||||
}
|
||||
|
||||
function simulate_cfg(imacro, depth, i) {
|
||||
while (i < imacro.code.length) {
|
||||
let op = imacro.code[i];
|
||||
depth -= (op.info.pops < 0) ? 2 + Number(op.imm1) : op.info.pops;
|
||||
depth += op.info.pushes;
|
||||
|
||||
if (imacro.depths.hasOwnProperty(i) && imacro.depths[i] != depth)
|
||||
throw Error("Mismatched depth at " + imacro.filename + ":" + op.line);
|
||||
|
||||
/*
|
||||
* Underflowing depth isn't necessarily fatal; most of the imacros
|
||||
* assume they are called with N>0 args so some assume it's ok to go
|
||||
* to some depth <N. We simulate starting from 0, as we've no idea
|
||||
* what else to do.
|
||||
*
|
||||
* if (depth < 0)
|
||||
* throw Error("Negative static-stack depth at " + imacro.filename + ":" + op.line);
|
||||
*/
|
||||
if (depth > imacro.maxdepth)
|
||||
imacro.maxdepth = depth;
|
||||
imacro.depths[i] = depth;
|
||||
|
||||
if (op.hasOwnProperty("target_index")) {
|
||||
if (op.target_index <= i)
|
||||
throw Error("Backward jump at " + imacro.filename + ":" + op.line);
|
||||
|
||||
simulate_cfg(imacro, depth, op.target_index);
|
||||
|
||||
if (op.info.opname == "goto" || op.info.opname == "gotox")
|
||||
return;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Syntax (spaces are significant only to delimit tokens):
|
||||
*
|
||||
@ -156,6 +191,7 @@ const line_regexp = new RegExp(line_regexp_parts.join(""));
|
||||
function assemble(filename) {
|
||||
let igroup = null, imacro = null;
|
||||
let opcode2extra = [];
|
||||
let igroups = [];
|
||||
|
||||
print("/* GENERATED BY imacro_asm.js -- DO NOT EDIT!!! */");
|
||||
|
||||
@ -204,7 +240,10 @@ function assemble(filename) {
|
||||
offset: 0,
|
||||
code: [],
|
||||
labeldefs: {},
|
||||
labelrefs: {}
|
||||
labeldef_indexes: {},
|
||||
labelrefs: {},
|
||||
filename: filename,
|
||||
depths: {}
|
||||
};
|
||||
break;
|
||||
|
||||
@ -232,14 +271,16 @@ function assemble(filename) {
|
||||
for (let k = 0; k < imacro.code.length; k++) {
|
||||
let op = imacro.code[k];
|
||||
|
||||
print("/*" + formatoffset(op.offset,2) + "*/ " + op.info.jsop +
|
||||
print("/*" + format_offset(op.offset,2) + "*/ " + op.info.jsop +
|
||||
(op.imm1 ? ", " + immediate(op) : "") + ",");
|
||||
|
||||
depth -= (op.info.pops < 0) ? 2 + op.imm1 : op.info.pops;
|
||||
depth += op.info.pushes;
|
||||
if (depth > maxdepth)
|
||||
maxdepth = depth;
|
||||
}
|
||||
|
||||
imacro.maxdepth = 0;
|
||||
simulate_cfg(imacro, 0, 0);
|
||||
if (imacro.maxdepth > maxdepth)
|
||||
maxdepth = imacro.maxdepth;
|
||||
|
||||
print(" },");
|
||||
}
|
||||
|
||||
@ -250,6 +291,7 @@ function assemble(filename) {
|
||||
do {
|
||||
opcode2extra[opcode] = maxdepth;
|
||||
} while (opcode++ != oplast);
|
||||
igroups.push(igroup);
|
||||
igroup = null;
|
||||
} else {
|
||||
ASSERT(igroup);
|
||||
@ -271,6 +313,7 @@ function assemble(filename) {
|
||||
ASSERT(op.hasOwnProperty('target'));
|
||||
let next = op.target;
|
||||
op.target = imacro.labeldefs[label] - op.offset;
|
||||
op.target_index = imacro.labeldef_indexes[label];
|
||||
if (next < 0)
|
||||
break;
|
||||
link = next;
|
||||
@ -298,14 +341,17 @@ function assemble(filename) {
|
||||
if (!imacro)
|
||||
throw new Error("opcode " + opname + " outside of .imacro");
|
||||
|
||||
if (label)
|
||||
if (label) {
|
||||
imacro.labeldefs[label] = imacro.offset;
|
||||
imacro.labeldef_indexes[label] = imacro.code.length;
|
||||
}
|
||||
|
||||
let op = {offset: imacro.offset, info: info, imm1: imm1, imm2: imm2};
|
||||
let op = {offset: imacro.offset, info: info, imm1: imm1, imm2: imm2, line:(i+1) };
|
||||
if (info.flags.indexOf("JOF_JUMP") >= 0) {
|
||||
if (imacro.labeldefs.hasOwnProperty(imm1)) {
|
||||
// Backward reference can be resolved right away, no backpatching needed.
|
||||
op.target = imacro.labeldefs[imm1] - op.offset;
|
||||
op.target_index = imacro.labeldef_indexes[imm1];
|
||||
} else {
|
||||
// Link op into the .target-linked backpatch chain at labelrefs[imm1].
|
||||
// The linked list terminates with a -1 sentinel.
|
||||
@ -329,6 +375,16 @@ function assemble(filename) {
|
||||
for (let i in opcode2extra)
|
||||
print(" || x == " + opinfo[i].jsop + " \\");
|
||||
print(")");
|
||||
|
||||
print("jsbytecode*\njs_GetImacroStart(jsbytecode* pc) {");
|
||||
for each (let g in igroups) {
|
||||
for each (let m in g.imacros) {
|
||||
let start = g.name + "_imacros." + m.name;
|
||||
print(" if (size_t(pc - " + start + ") < " + m.offset + ") return " + start + ";");
|
||||
}
|
||||
}
|
||||
print(" return NULL;");
|
||||
print("}");
|
||||
}
|
||||
|
||||
for (let i = 0; i < arguments.length; i++) {
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* GENERATED BY imacro_asm.js -- DO NOT EDIT!!! */
|
||||
static struct {
|
||||
jsbytecode any_obj[37];
|
||||
jsbytecode obj_any[39];
|
||||
jsbytecode any_obj[34];
|
||||
jsbytecode obj_any[36];
|
||||
} equality_imacros = {
|
||||
{
|
||||
/* 0*/ JSOP_DUP,
|
||||
@ -11,18 +11,16 @@ static struct {
|
||||
/* 8*/ JSOP_SWAP,
|
||||
/* 9*/ JSOP_STRING, 0, COMMON_TYPE_ATOM_INDEX(JSTYPE_VOID),
|
||||
/*12*/ JSOP_CALL, 0, 1,
|
||||
/*15*/ JSOP_IFPRIMTOP, 0, 18,
|
||||
/*15*/ JSOP_IFPRIMTOP, 0, 15,
|
||||
/*18*/ JSOP_GOTO, 0, 4,
|
||||
/*21*/ JSOP_POP,
|
||||
/*22*/ JSOP_POP,
|
||||
/*23*/ JSOP_CALLPROP, 0, COMMON_ATOM_INDEX(toString),
|
||||
/*26*/ JSOP_CALL, 0, 0,
|
||||
/*29*/ JSOP_PRIMTOP,
|
||||
/*30*/ JSOP_GOTO, 0, 5,
|
||||
/*33*/ JSOP_SWAP,
|
||||
/*34*/ JSOP_POP,
|
||||
/*35*/ JSOP_IMACOP,
|
||||
/*36*/ JSOP_STOP,
|
||||
/*22*/ JSOP_CALLPROP, 0, COMMON_ATOM_INDEX(toString),
|
||||
/*25*/ JSOP_CALL, 0, 0,
|
||||
/*28*/ JSOP_PRIMTOP, (JSTYPE_NUMBER),
|
||||
/*30*/ JSOP_SWAP,
|
||||
/*31*/ JSOP_POP,
|
||||
/*32*/ JSOP_IMACOP,
|
||||
/*33*/ JSOP_STOP,
|
||||
},
|
||||
{
|
||||
/* 0*/ JSOP_SWAP,
|
||||
@ -33,25 +31,23 @@ static struct {
|
||||
/* 9*/ JSOP_SWAP,
|
||||
/*10*/ JSOP_STRING, 0, COMMON_TYPE_ATOM_INDEX(JSTYPE_VOID),
|
||||
/*13*/ JSOP_CALL, 0, 1,
|
||||
/*16*/ JSOP_IFPRIMTOP, 0, 18,
|
||||
/*16*/ JSOP_IFPRIMTOP, 0, 15,
|
||||
/*19*/ JSOP_GOTO, 0, 4,
|
||||
/*22*/ JSOP_POP,
|
||||
/*23*/ JSOP_POP,
|
||||
/*24*/ JSOP_CALLPROP, 0, COMMON_ATOM_INDEX(toString),
|
||||
/*27*/ JSOP_CALL, 0, 0,
|
||||
/*30*/ JSOP_PRIMTOP,
|
||||
/*31*/ JSOP_GOTO, 0, 5,
|
||||
/*34*/ JSOP_SWAP,
|
||||
/*35*/ JSOP_POP,
|
||||
/*36*/ JSOP_SWAP,
|
||||
/*37*/ JSOP_IMACOP,
|
||||
/*38*/ JSOP_STOP,
|
||||
/*23*/ JSOP_CALLPROP, 0, COMMON_ATOM_INDEX(toString),
|
||||
/*26*/ JSOP_CALL, 0, 0,
|
||||
/*29*/ JSOP_PRIMTOP, (JSTYPE_NUMBER),
|
||||
/*31*/ JSOP_SWAP,
|
||||
/*32*/ JSOP_POP,
|
||||
/*33*/ JSOP_SWAP,
|
||||
/*34*/ JSOP_IMACOP,
|
||||
/*35*/ JSOP_STOP,
|
||||
},
|
||||
};
|
||||
static struct {
|
||||
jsbytecode any_obj[37];
|
||||
jsbytecode obj_any[39];
|
||||
jsbytecode obj_obj[74];
|
||||
jsbytecode any_obj[34];
|
||||
jsbytecode obj_any[38];
|
||||
jsbytecode obj_obj[68];
|
||||
} binary_imacros = {
|
||||
{
|
||||
/* 0*/ JSOP_DUP,
|
||||
@ -61,87 +57,81 @@ static struct {
|
||||
/* 8*/ JSOP_SWAP,
|
||||
/* 9*/ JSOP_STRING, 0, COMMON_TYPE_ATOM_INDEX(JSTYPE_NUMBER),
|
||||
/*12*/ JSOP_CALL, 0, 1,
|
||||
/*15*/ JSOP_IFPRIMTOP, 0, 18,
|
||||
/*15*/ JSOP_IFPRIMTOP, 0, 15,
|
||||
/*18*/ JSOP_GOTO, 0, 4,
|
||||
/*21*/ JSOP_POP,
|
||||
/*22*/ JSOP_CALLPROP, 0, COMMON_ATOM_INDEX(toString),
|
||||
/*25*/ JSOP_CALL, 0, 0,
|
||||
/*28*/ JSOP_PRIMTOP, (JSTYPE_NUMBER),
|
||||
/*30*/ JSOP_SWAP,
|
||||
/*31*/ JSOP_POP,
|
||||
/*32*/ JSOP_IMACOP,
|
||||
/*33*/ JSOP_STOP,
|
||||
},
|
||||
{
|
||||
/* 0*/ JSOP_SWAP,
|
||||
/* 1*/ JSOP_DUP,
|
||||
/* 2*/ JSOP_DUP,
|
||||
/* 3*/ JSOP_GETPROP, 0, COMMON_ATOM_INDEX(valueOf),
|
||||
/* 6*/ JSOP_IFPRIMTOP, 0, 18,
|
||||
/* 9*/ JSOP_SWAP,
|
||||
/*10*/ JSOP_STRING, 0, COMMON_TYPE_ATOM_INDEX(JSTYPE_NUMBER),
|
||||
/*13*/ JSOP_CALL, 0, 1,
|
||||
/*16*/ JSOP_IFPRIMTOP, 0, 17,
|
||||
/*19*/ JSOP_POP,
|
||||
/*20*/ JSOP_DUP,
|
||||
/*21*/ JSOP_GOTO, 0, 4,
|
||||
/*24*/ JSOP_POP,
|
||||
/*25*/ JSOP_CALLPROP, 0, COMMON_ATOM_INDEX(toString),
|
||||
/*28*/ JSOP_CALL, 0, 0,
|
||||
/*31*/ JSOP_PRIMTOP, (JSTYPE_NUMBER),
|
||||
/*33*/ JSOP_SWAP,
|
||||
/*34*/ JSOP_POP,
|
||||
/*35*/ JSOP_SWAP,
|
||||
/*36*/ JSOP_IMACOP,
|
||||
/*37*/ JSOP_STOP,
|
||||
},
|
||||
{
|
||||
/* 0*/ JSOP_SWAP,
|
||||
/* 1*/ JSOP_DUP,
|
||||
/* 2*/ JSOP_DUP,
|
||||
/* 3*/ JSOP_GETPROP, 0, COMMON_ATOM_INDEX(valueOf),
|
||||
/* 6*/ JSOP_IFPRIMTOP, 0, 16,
|
||||
/* 9*/ JSOP_SWAP,
|
||||
/*10*/ JSOP_STRING, 0, COMMON_TYPE_ATOM_INDEX(JSTYPE_NUMBER),
|
||||
/*13*/ JSOP_CALL, 0, 1,
|
||||
/*16*/ JSOP_IFPRIMTOP, 0, 15,
|
||||
/*19*/ JSOP_GOTO, 0, 4,
|
||||
/*22*/ JSOP_POP,
|
||||
/*23*/ JSOP_CALLPROP, 0, COMMON_ATOM_INDEX(toString),
|
||||
/*26*/ JSOP_CALL, 0, 0,
|
||||
/*29*/ JSOP_PRIMTOP,
|
||||
/*30*/ JSOP_GOTO, 0, 5,
|
||||
/*29*/ JSOP_PRIMTOP, (JSTYPE_NUMBER),
|
||||
/*31*/ JSOP_SWAP,
|
||||
/*32*/ JSOP_POP,
|
||||
/*33*/ JSOP_SWAP,
|
||||
/*34*/ JSOP_POP,
|
||||
/*35*/ JSOP_IMACOP,
|
||||
/*36*/ JSOP_STOP,
|
||||
},
|
||||
{
|
||||
/* 0*/ JSOP_SWAP,
|
||||
/* 1*/ JSOP_DUP,
|
||||
/* 2*/ JSOP_DUP,
|
||||
/* 3*/ JSOP_GETPROP, 0, COMMON_ATOM_INDEX(valueOf),
|
||||
/* 6*/ JSOP_IFPRIMTOP, 0, 16,
|
||||
/* 9*/ JSOP_SWAP,
|
||||
/*10*/ JSOP_STRING, 0, COMMON_TYPE_ATOM_INDEX(JSTYPE_NUMBER),
|
||||
/*13*/ JSOP_CALL, 0, 1,
|
||||
/*16*/ JSOP_IFPRIMTOP, 0, 18,
|
||||
/*19*/ JSOP_GOTO, 0, 4,
|
||||
/*22*/ JSOP_POP,
|
||||
/*23*/ JSOP_POP,
|
||||
/*24*/ JSOP_CALLPROP, 0, COMMON_ATOM_INDEX(toString),
|
||||
/*27*/ JSOP_CALL, 0, 0,
|
||||
/*30*/ JSOP_PRIMTOP,
|
||||
/*31*/ JSOP_GOTO, 0, 5,
|
||||
/*34*/ JSOP_SWAP,
|
||||
/*35*/ JSOP_POP,
|
||||
/*36*/ JSOP_SWAP,
|
||||
/*37*/ JSOP_IMACOP,
|
||||
/*38*/ JSOP_STOP,
|
||||
},
|
||||
{
|
||||
/* 0*/ JSOP_SWAP,
|
||||
/* 1*/ JSOP_DUP,
|
||||
/* 2*/ JSOP_DUP,
|
||||
/* 3*/ JSOP_GETPROP, 0, COMMON_ATOM_INDEX(valueOf),
|
||||
/* 6*/ JSOP_IFPRIMTOP, 0, 16,
|
||||
/* 9*/ JSOP_SWAP,
|
||||
/*10*/ JSOP_STRING, 0, COMMON_TYPE_ATOM_INDEX(JSTYPE_NUMBER),
|
||||
/*13*/ JSOP_CALL, 0, 1,
|
||||
/*16*/ JSOP_IFPRIMTOP, 0, 18,
|
||||
/*19*/ JSOP_GOTO, 0, 4,
|
||||
/*22*/ JSOP_POP,
|
||||
/*23*/ JSOP_POP,
|
||||
/*24*/ JSOP_CALLPROP, 0, COMMON_ATOM_INDEX(toString),
|
||||
/*27*/ JSOP_CALL, 0, 0,
|
||||
/*30*/ JSOP_PRIMTOP,
|
||||
/*31*/ JSOP_GOTO, 0, 5,
|
||||
/*34*/ JSOP_SWAP,
|
||||
/*35*/ JSOP_POP,
|
||||
/*36*/ JSOP_SWAP,
|
||||
/*37*/ JSOP_DUP,
|
||||
/*38*/ JSOP_DUP,
|
||||
/*39*/ JSOP_GETPROP, 0, COMMON_ATOM_INDEX(valueOf),
|
||||
/*42*/ JSOP_IFPRIMTOP, 0, 16,
|
||||
/*45*/ JSOP_SWAP,
|
||||
/*46*/ JSOP_STRING, 0, COMMON_TYPE_ATOM_INDEX(JSTYPE_NUMBER),
|
||||
/*49*/ JSOP_CALL, 0, 1,
|
||||
/*52*/ JSOP_IFPRIMTOP, 0, 18,
|
||||
/*55*/ JSOP_GOTO, 0, 4,
|
||||
/*58*/ JSOP_POP,
|
||||
/*59*/ JSOP_POP,
|
||||
/*60*/ JSOP_CALLPROP, 0, COMMON_ATOM_INDEX(toString),
|
||||
/*63*/ JSOP_CALL, 0, 0,
|
||||
/*66*/ JSOP_PRIMTOP,
|
||||
/*67*/ JSOP_GOTO, 0, 5,
|
||||
/*70*/ JSOP_SWAP,
|
||||
/*71*/ JSOP_POP,
|
||||
/*72*/ JSOP_IMACOP,
|
||||
/*73*/ JSOP_STOP,
|
||||
/*34*/ JSOP_DUP,
|
||||
/*35*/ JSOP_DUP,
|
||||
/*36*/ JSOP_GETPROP, 0, COMMON_ATOM_INDEX(valueOf),
|
||||
/*39*/ JSOP_IFPRIMTOP, 0, 16,
|
||||
/*42*/ JSOP_SWAP,
|
||||
/*43*/ JSOP_STRING, 0, COMMON_TYPE_ATOM_INDEX(JSTYPE_NUMBER),
|
||||
/*46*/ JSOP_CALL, 0, 1,
|
||||
/*49*/ JSOP_IFPRIMTOP, 0, 15,
|
||||
/*52*/ JSOP_GOTO, 0, 4,
|
||||
/*55*/ JSOP_POP,
|
||||
/*56*/ JSOP_CALLPROP, 0, COMMON_ATOM_INDEX(toString),
|
||||
/*59*/ JSOP_CALL, 0, 0,
|
||||
/*62*/ JSOP_PRIMTOP, (JSTYPE_NUMBER),
|
||||
/*64*/ JSOP_SWAP,
|
||||
/*65*/ JSOP_POP,
|
||||
/*66*/ JSOP_IMACOP,
|
||||
/*67*/ JSOP_STOP,
|
||||
},
|
||||
};
|
||||
static struct {
|
||||
jsbytecode any_obj[37];
|
||||
jsbytecode obj_any[39];
|
||||
jsbytecode obj_obj[74];
|
||||
jsbytecode any_obj[34];
|
||||
jsbytecode obj_any[36];
|
||||
jsbytecode obj_obj[68];
|
||||
} add_imacros = {
|
||||
{
|
||||
/* 0*/ JSOP_DUP,
|
||||
@ -151,18 +141,37 @@ static struct {
|
||||
/* 8*/ JSOP_SWAP,
|
||||
/* 9*/ JSOP_STRING, 0, COMMON_TYPE_ATOM_INDEX(JSTYPE_VOID),
|
||||
/*12*/ JSOP_CALL, 0, 1,
|
||||
/*15*/ JSOP_IFPRIMTOP, 0, 18,
|
||||
/*15*/ JSOP_IFPRIMTOP, 0, 15,
|
||||
/*18*/ JSOP_GOTO, 0, 4,
|
||||
/*21*/ JSOP_POP,
|
||||
/*22*/ JSOP_CALLPROP, 0, COMMON_ATOM_INDEX(toString),
|
||||
/*25*/ JSOP_CALL, 0, 0,
|
||||
/*28*/ JSOP_PRIMTOP, (JSTYPE_VOID),
|
||||
/*30*/ JSOP_SWAP,
|
||||
/*31*/ JSOP_POP,
|
||||
/*32*/ JSOP_ADD,
|
||||
/*33*/ JSOP_STOP,
|
||||
},
|
||||
{
|
||||
/* 0*/ JSOP_SWAP,
|
||||
/* 1*/ JSOP_DUP,
|
||||
/* 2*/ JSOP_DUP,
|
||||
/* 3*/ JSOP_GETPROP, 0, COMMON_ATOM_INDEX(valueOf),
|
||||
/* 6*/ JSOP_IFPRIMTOP, 0, 16,
|
||||
/* 9*/ JSOP_SWAP,
|
||||
/*10*/ JSOP_STRING, 0, COMMON_TYPE_ATOM_INDEX(JSTYPE_VOID),
|
||||
/*13*/ JSOP_CALL, 0, 1,
|
||||
/*16*/ JSOP_IFPRIMTOP, 0, 15,
|
||||
/*19*/ JSOP_GOTO, 0, 4,
|
||||
/*22*/ JSOP_POP,
|
||||
/*23*/ JSOP_CALLPROP, 0, COMMON_ATOM_INDEX(toString),
|
||||
/*26*/ JSOP_CALL, 0, 0,
|
||||
/*29*/ JSOP_PRIMTOP,
|
||||
/*30*/ JSOP_GOTO, 0, 5,
|
||||
/*29*/ JSOP_PRIMTOP, (JSTYPE_VOID),
|
||||
/*31*/ JSOP_SWAP,
|
||||
/*32*/ JSOP_POP,
|
||||
/*33*/ JSOP_SWAP,
|
||||
/*34*/ JSOP_POP,
|
||||
/*35*/ JSOP_ADD,
|
||||
/*36*/ JSOP_STOP,
|
||||
/*34*/ JSOP_ADD,
|
||||
/*35*/ JSOP_STOP,
|
||||
},
|
||||
{
|
||||
/* 0*/ JSOP_SWAP,
|
||||
@ -173,63 +182,36 @@ static struct {
|
||||
/* 9*/ JSOP_SWAP,
|
||||
/*10*/ JSOP_STRING, 0, COMMON_TYPE_ATOM_INDEX(JSTYPE_VOID),
|
||||
/*13*/ JSOP_CALL, 0, 1,
|
||||
/*16*/ JSOP_IFPRIMTOP, 0, 18,
|
||||
/*16*/ JSOP_IFPRIMTOP, 0, 15,
|
||||
/*19*/ JSOP_GOTO, 0, 4,
|
||||
/*22*/ JSOP_POP,
|
||||
/*23*/ JSOP_POP,
|
||||
/*24*/ JSOP_CALLPROP, 0, COMMON_ATOM_INDEX(toString),
|
||||
/*27*/ JSOP_CALL, 0, 0,
|
||||
/*30*/ JSOP_PRIMTOP,
|
||||
/*31*/ JSOP_GOTO, 0, 5,
|
||||
/*34*/ JSOP_SWAP,
|
||||
/*35*/ JSOP_POP,
|
||||
/*36*/ JSOP_SWAP,
|
||||
/*37*/ JSOP_ADD,
|
||||
/*38*/ JSOP_STOP,
|
||||
},
|
||||
{
|
||||
/* 0*/ JSOP_SWAP,
|
||||
/* 1*/ JSOP_DUP,
|
||||
/* 2*/ JSOP_DUP,
|
||||
/* 3*/ JSOP_GETPROP, 0, COMMON_ATOM_INDEX(valueOf),
|
||||
/* 6*/ JSOP_IFPRIMTOP, 0, 16,
|
||||
/* 9*/ JSOP_SWAP,
|
||||
/*10*/ JSOP_STRING, 0, COMMON_TYPE_ATOM_INDEX(JSTYPE_VOID),
|
||||
/*13*/ JSOP_CALL, 0, 1,
|
||||
/*16*/ JSOP_IFPRIMTOP, 0, 18,
|
||||
/*19*/ JSOP_GOTO, 0, 4,
|
||||
/*22*/ JSOP_POP,
|
||||
/*23*/ JSOP_POP,
|
||||
/*24*/ JSOP_CALLPROP, 0, COMMON_ATOM_INDEX(toString),
|
||||
/*27*/ JSOP_CALL, 0, 0,
|
||||
/*30*/ JSOP_PRIMTOP,
|
||||
/*31*/ JSOP_GOTO, 0, 5,
|
||||
/*34*/ JSOP_SWAP,
|
||||
/*35*/ JSOP_POP,
|
||||
/*36*/ JSOP_SWAP,
|
||||
/*37*/ JSOP_DUP,
|
||||
/*38*/ JSOP_DUP,
|
||||
/*39*/ JSOP_GETPROP, 0, COMMON_ATOM_INDEX(valueOf),
|
||||
/*42*/ JSOP_IFPRIMTOP, 0, 16,
|
||||
/*45*/ JSOP_SWAP,
|
||||
/*46*/ JSOP_STRING, 0, COMMON_TYPE_ATOM_INDEX(JSTYPE_VOID),
|
||||
/*49*/ JSOP_CALL, 0, 1,
|
||||
/*52*/ JSOP_IFPRIMTOP, 0, 18,
|
||||
/*55*/ JSOP_GOTO, 0, 4,
|
||||
/*58*/ JSOP_POP,
|
||||
/*59*/ JSOP_POP,
|
||||
/*60*/ JSOP_CALLPROP, 0, COMMON_ATOM_INDEX(toString),
|
||||
/*63*/ JSOP_CALL, 0, 0,
|
||||
/*66*/ JSOP_PRIMTOP,
|
||||
/*67*/ JSOP_GOTO, 0, 5,
|
||||
/*70*/ JSOP_SWAP,
|
||||
/*71*/ JSOP_POP,
|
||||
/*72*/ JSOP_ADD,
|
||||
/*73*/ JSOP_STOP,
|
||||
/*23*/ JSOP_CALLPROP, 0, COMMON_ATOM_INDEX(toString),
|
||||
/*26*/ JSOP_CALL, 0, 0,
|
||||
/*29*/ JSOP_PRIMTOP, (JSTYPE_VOID),
|
||||
/*31*/ JSOP_SWAP,
|
||||
/*32*/ JSOP_POP,
|
||||
/*33*/ JSOP_SWAP,
|
||||
/*34*/ JSOP_DUP,
|
||||
/*35*/ JSOP_DUP,
|
||||
/*36*/ JSOP_GETPROP, 0, COMMON_ATOM_INDEX(valueOf),
|
||||
/*39*/ JSOP_IFPRIMTOP, 0, 16,
|
||||
/*42*/ JSOP_SWAP,
|
||||
/*43*/ JSOP_STRING, 0, COMMON_TYPE_ATOM_INDEX(JSTYPE_VOID),
|
||||
/*46*/ JSOP_CALL, 0, 1,
|
||||
/*49*/ JSOP_IFPRIMTOP, 0, 15,
|
||||
/*52*/ JSOP_GOTO, 0, 4,
|
||||
/*55*/ JSOP_POP,
|
||||
/*56*/ JSOP_CALLPROP, 0, COMMON_ATOM_INDEX(toString),
|
||||
/*59*/ JSOP_CALL, 0, 0,
|
||||
/*62*/ JSOP_PRIMTOP, (JSTYPE_VOID),
|
||||
/*64*/ JSOP_SWAP,
|
||||
/*65*/ JSOP_POP,
|
||||
/*66*/ JSOP_ADD,
|
||||
/*67*/ JSOP_STOP,
|
||||
},
|
||||
};
|
||||
static struct {
|
||||
jsbytecode sign[37];
|
||||
jsbytecode sign[39];
|
||||
} unary_imacros = {
|
||||
{
|
||||
/* 0*/ JSOP_DUP,
|
||||
@ -243,18 +225,19 @@ static struct {
|
||||
/*18*/ JSOP_GOTO, 0, 9,
|
||||
/*21*/ JSOP_SWAP,
|
||||
/*22*/ JSOP_POP,
|
||||
/*23*/ JSOP_GOTO, 0, 12,
|
||||
/*23*/ JSOP_GOTO, 0, 14,
|
||||
/*26*/ JSOP_POP,
|
||||
/*27*/ JSOP_POP,
|
||||
/*28*/ JSOP_CALLPROP, 0, COMMON_ATOM_INDEX(toString),
|
||||
/*31*/ JSOP_CALL, 0, 0,
|
||||
/*34*/ JSOP_PRIMTOP,
|
||||
/*35*/ JSOP_IMACOP,
|
||||
/*36*/ JSOP_STOP,
|
||||
/*27*/ JSOP_CALLPROP, 0, COMMON_ATOM_INDEX(toString),
|
||||
/*30*/ JSOP_CALL, 0, 0,
|
||||
/*33*/ JSOP_PRIMTOP, (JSTYPE_NUMBER),
|
||||
/*35*/ JSOP_SWAP,
|
||||
/*36*/ JSOP_POP,
|
||||
/*37*/ JSOP_IMACOP,
|
||||
/*38*/ JSOP_STOP,
|
||||
},
|
||||
};
|
||||
static struct {
|
||||
jsbytecode String[39];
|
||||
jsbytecode String[36];
|
||||
} call_imacros = {
|
||||
{
|
||||
/* 0*/ JSOP_DUP,
|
||||
@ -263,23 +246,21 @@ static struct {
|
||||
/* 5*/ JSOP_IFPRIMTOP, 0, 13,
|
||||
/* 8*/ JSOP_SWAP,
|
||||
/* 9*/ JSOP_CALL, 0, 0,
|
||||
/*12*/ JSOP_IFPRIMTOP, 0, 21,
|
||||
/*12*/ JSOP_IFPRIMTOP, 0, 18,
|
||||
/*15*/ JSOP_GOTO, 0, 4,
|
||||
/*18*/ JSOP_POP,
|
||||
/*19*/ JSOP_POP,
|
||||
/*20*/ JSOP_CALLPROP, 0, COMMON_ATOM_INDEX(valueOf),
|
||||
/*23*/ JSOP_STRING, 0, COMMON_TYPE_ATOM_INDEX(JSTYPE_STRING),
|
||||
/*26*/ JSOP_CALL, 0, 1,
|
||||
/*29*/ JSOP_PRIMTOP,
|
||||
/*30*/ JSOP_GOTO, 0, 5,
|
||||
/*33*/ JSOP_SWAP,
|
||||
/*34*/ JSOP_POP,
|
||||
/*35*/ JSOP_CALL, 0, 1,
|
||||
/*38*/ JSOP_STOP,
|
||||
/*19*/ JSOP_CALLPROP, 0, COMMON_ATOM_INDEX(valueOf),
|
||||
/*22*/ JSOP_STRING, 0, COMMON_TYPE_ATOM_INDEX(JSTYPE_STRING),
|
||||
/*25*/ JSOP_CALL, 0, 1,
|
||||
/*28*/ JSOP_PRIMTOP, (JSTYPE_STRING),
|
||||
/*30*/ JSOP_SWAP,
|
||||
/*31*/ JSOP_POP,
|
||||
/*32*/ JSOP_CALL, 0, 1,
|
||||
/*35*/ JSOP_STOP,
|
||||
},
|
||||
};
|
||||
static struct {
|
||||
jsbytecode String[39];
|
||||
jsbytecode String[36];
|
||||
} new_imacros = {
|
||||
{
|
||||
/* 0*/ JSOP_DUP,
|
||||
@ -288,19 +269,17 @@ static struct {
|
||||
/* 5*/ JSOP_IFPRIMTOP, 0, 13,
|
||||
/* 8*/ JSOP_SWAP,
|
||||
/* 9*/ JSOP_CALL, 0, 0,
|
||||
/*12*/ JSOP_IFPRIMTOP, 0, 21,
|
||||
/*12*/ JSOP_IFPRIMTOP, 0, 18,
|
||||
/*15*/ JSOP_GOTO, 0, 4,
|
||||
/*18*/ JSOP_POP,
|
||||
/*19*/ JSOP_POP,
|
||||
/*20*/ JSOP_CALLPROP, 0, COMMON_ATOM_INDEX(valueOf),
|
||||
/*23*/ JSOP_STRING, 0, COMMON_TYPE_ATOM_INDEX(JSTYPE_STRING),
|
||||
/*26*/ JSOP_CALL, 0, 1,
|
||||
/*29*/ JSOP_PRIMTOP,
|
||||
/*30*/ JSOP_GOTO, 0, 5,
|
||||
/*33*/ JSOP_SWAP,
|
||||
/*34*/ JSOP_POP,
|
||||
/*35*/ JSOP_NEW, 0, 1,
|
||||
/*38*/ JSOP_STOP,
|
||||
/*19*/ JSOP_CALLPROP, 0, COMMON_ATOM_INDEX(valueOf),
|
||||
/*22*/ JSOP_STRING, 0, COMMON_TYPE_ATOM_INDEX(JSTYPE_STRING),
|
||||
/*25*/ JSOP_CALL, 0, 1,
|
||||
/*28*/ JSOP_PRIMTOP, (JSTYPE_STRING),
|
||||
/*30*/ JSOP_SWAP,
|
||||
/*31*/ JSOP_POP,
|
||||
/*32*/ JSOP_NEW, 0, 1,
|
||||
/*35*/ JSOP_STOP,
|
||||
},
|
||||
};
|
||||
static struct {
|
||||
@ -796,10 +775,10 @@ uint8 js_opcode2extra[JSOP_LIMIT] = {
|
||||
0, /* JSOP_ELEMDEC */
|
||||
0, /* JSOP_GETPROP */
|
||||
0, /* JSOP_SETPROP */
|
||||
2, /* JSOP_GETELEM */
|
||||
3, /* JSOP_SETELEM */
|
||||
1, /* JSOP_GETELEM */
|
||||
2, /* JSOP_SETELEM */
|
||||
0, /* JSOP_CALLNAME */
|
||||
2, /* JSOP_CALL */
|
||||
3, /* JSOP_CALL */
|
||||
0, /* JSOP_NAME */
|
||||
0, /* JSOP_DOUBLE */
|
||||
0, /* JSOP_STRING */
|
||||
@ -816,14 +795,14 @@ uint8 js_opcode2extra[JSOP_LIMIT] = {
|
||||
0, /* JSOP_STRICTEQ */
|
||||
0, /* JSOP_STRICTNE */
|
||||
0, /* JSOP_SETCALL */
|
||||
3, /* JSOP_ITER */
|
||||
2, /* JSOP_ITER */
|
||||
2, /* JSOP_NEXTITER */
|
||||
0, /* JSOP_ENDITER */
|
||||
8, /* JSOP_APPLY */
|
||||
0, /* JSOP_SWAP */
|
||||
0, /* JSOP_OBJECT */
|
||||
0, /* JSOP_POP */
|
||||
2, /* JSOP_NEW */
|
||||
3, /* JSOP_NEW */
|
||||
0, /* JSOP_TRAP */
|
||||
0, /* JSOP_GETARG */
|
||||
0, /* JSOP_SETARG */
|
||||
@ -833,7 +812,7 @@ uint8 js_opcode2extra[JSOP_LIMIT] = {
|
||||
0, /* JSOP_NEWINIT */
|
||||
0, /* JSOP_ENDINIT */
|
||||
0, /* JSOP_INITPROP */
|
||||
3, /* JSOP_INITELEM */
|
||||
2, /* JSOP_INITELEM */
|
||||
0, /* JSOP_DEFSHARP */
|
||||
0, /* JSOP_USESHARP */
|
||||
0, /* JSOP_INCARG */
|
||||
@ -935,7 +914,7 @@ uint8 js_opcode2extra[JSOP_LIMIT] = {
|
||||
0, /* JSOP_RESETBASE0 */
|
||||
0, /* JSOP_STARTXML */
|
||||
0, /* JSOP_STARTXMLEXPR */
|
||||
3, /* JSOP_CALLELEM */
|
||||
2, /* JSOP_CALLELEM */
|
||||
0, /* JSOP_STOP */
|
||||
0, /* JSOP_GETXPROP */
|
||||
0, /* JSOP_CALLXMLNAME */
|
||||
@ -1001,3 +980,50 @@ uint8 js_opcode2extra[JSOP_LIMIT] = {
|
||||
|| x == JSOP_INITELEM \
|
||||
|| x == JSOP_CALLELEM \
|
||||
)
|
||||
jsbytecode*
|
||||
js_GetImacroStart(jsbytecode* pc) {
|
||||
if (size_t(pc - equality_imacros.any_obj) < 34) return equality_imacros.any_obj;
|
||||
if (size_t(pc - equality_imacros.obj_any) < 36) return equality_imacros.obj_any;
|
||||
if (size_t(pc - binary_imacros.any_obj) < 34) return binary_imacros.any_obj;
|
||||
if (size_t(pc - binary_imacros.obj_any) < 38) return binary_imacros.obj_any;
|
||||
if (size_t(pc - binary_imacros.obj_obj) < 68) return binary_imacros.obj_obj;
|
||||
if (size_t(pc - add_imacros.any_obj) < 34) return add_imacros.any_obj;
|
||||
if (size_t(pc - add_imacros.obj_any) < 36) return add_imacros.obj_any;
|
||||
if (size_t(pc - add_imacros.obj_obj) < 68) return add_imacros.obj_obj;
|
||||
if (size_t(pc - unary_imacros.sign) < 39) return unary_imacros.sign;
|
||||
if (size_t(pc - call_imacros.String) < 36) return call_imacros.String;
|
||||
if (size_t(pc - new_imacros.String) < 36) return new_imacros.String;
|
||||
if (size_t(pc - apply_imacros.apply0) < 8) return apply_imacros.apply0;
|
||||
if (size_t(pc - apply_imacros.apply1) < 12) return apply_imacros.apply1;
|
||||
if (size_t(pc - apply_imacros.apply2) < 16) return apply_imacros.apply2;
|
||||
if (size_t(pc - apply_imacros.apply3) < 21) return apply_imacros.apply3;
|
||||
if (size_t(pc - apply_imacros.apply4) < 26) return apply_imacros.apply4;
|
||||
if (size_t(pc - apply_imacros.apply5) < 31) return apply_imacros.apply5;
|
||||
if (size_t(pc - apply_imacros.apply6) < 36) return apply_imacros.apply6;
|
||||
if (size_t(pc - apply_imacros.apply7) < 41) return apply_imacros.apply7;
|
||||
if (size_t(pc - apply_imacros.apply8) < 46) return apply_imacros.apply8;
|
||||
if (size_t(pc - apply_imacros.call0) < 7) return apply_imacros.call0;
|
||||
if (size_t(pc - apply_imacros.call1) < 7) return apply_imacros.call1;
|
||||
if (size_t(pc - apply_imacros.call2) < 7) return apply_imacros.call2;
|
||||
if (size_t(pc - apply_imacros.call3) < 7) return apply_imacros.call3;
|
||||
if (size_t(pc - apply_imacros.call4) < 7) return apply_imacros.call4;
|
||||
if (size_t(pc - apply_imacros.call5) < 7) return apply_imacros.call5;
|
||||
if (size_t(pc - apply_imacros.call6) < 7) return apply_imacros.call6;
|
||||
if (size_t(pc - apply_imacros.call7) < 7) return apply_imacros.call7;
|
||||
if (size_t(pc - apply_imacros.call8) < 7) return apply_imacros.call8;
|
||||
if (size_t(pc - iter_imacros.for_in) < 13) return iter_imacros.for_in;
|
||||
if (size_t(pc - iter_imacros.for_each) < 13) return iter_imacros.for_each;
|
||||
if (size_t(pc - iter_imacros.for_in_native) < 10) return iter_imacros.for_in_native;
|
||||
if (size_t(pc - iter_imacros.for_each_native) < 10) return iter_imacros.for_each_native;
|
||||
if (size_t(pc - nextiter_imacros.custom_iter_next) < 12) return nextiter_imacros.custom_iter_next;
|
||||
if (size_t(pc - nextiter_imacros.native_iter_next) < 12) return nextiter_imacros.native_iter_next;
|
||||
if (size_t(pc - getelem_imacros.getprop) < 10) return getelem_imacros.getprop;
|
||||
if (size_t(pc - getelem_imacros.getelem) < 10) return getelem_imacros.getelem;
|
||||
if (size_t(pc - callelem_imacros.callprop) < 12) return callelem_imacros.callprop;
|
||||
if (size_t(pc - callelem_imacros.callelem) < 12) return callelem_imacros.callelem;
|
||||
if (size_t(pc - setelem_imacros.setprop) < 15) return setelem_imacros.setprop;
|
||||
if (size_t(pc - setelem_imacros.setelem) < 15) return setelem_imacros.setelem;
|
||||
if (size_t(pc - initelem_imacros.initprop) < 15) return initelem_imacros.initprop;
|
||||
if (size_t(pc - initelem_imacros.initelem) < 15) return initelem_imacros.initelem;
|
||||
return NULL;
|
||||
}
|
||||
|
@ -49,14 +49,12 @@
|
||||
ifprimtop 3 # any obj rval
|
||||
goto 2
|
||||
1: pop # any obj obj
|
||||
2: pop # any obj
|
||||
callprop toString # any toString obj
|
||||
call 0 # any rval
|
||||
primtop # any rval
|
||||
goto 4 # any rval
|
||||
2: callprop toString # any obj toString obj
|
||||
call 0 # any obj rval
|
||||
primtop (JSTYPE_NUMBER) # any obj rval
|
||||
3: swap # any rval obj
|
||||
pop # any rval
|
||||
4: imacop # eqval
|
||||
imacop # eqval
|
||||
stop
|
||||
.end
|
||||
|
||||
@ -72,14 +70,12 @@
|
||||
ifprimtop 3 # any obj lval
|
||||
goto 2
|
||||
1: pop # any obj obj
|
||||
2: pop # any obj
|
||||
callprop toString # any toString obj
|
||||
call 0 # any lval
|
||||
primtop # any rval
|
||||
goto 4 # any lval
|
||||
2: callprop toString # any obj toString obj
|
||||
call 0 # any obj lval
|
||||
primtop (JSTYPE_NUMBER) # any obj rval
|
||||
3: swap # any lval obj
|
||||
pop # any lval
|
||||
4: swap # lval any
|
||||
swap # lval any
|
||||
imacop # eqval
|
||||
stop
|
||||
.end
|
||||
@ -99,14 +95,12 @@
|
||||
ifprimtop 3 # any obj rval
|
||||
goto 2
|
||||
1: pop # any obj obj
|
||||
2: pop # any obj
|
||||
callprop toString # any toString obj
|
||||
call 0 # any rval
|
||||
primtop # any rval
|
||||
goto 4 # any rval
|
||||
2: callprop toString # any obj toString obj
|
||||
call 0 # any obj rval
|
||||
primtop (JSTYPE_NUMBER) # any obj rval
|
||||
3: swap # any rval obj
|
||||
pop # any rval
|
||||
4: imacop # bval
|
||||
imacop # bval
|
||||
stop
|
||||
.end
|
||||
|
||||
@ -120,16 +114,16 @@
|
||||
string number # any obj valueOf obj "number"
|
||||
call 1 # any obj lval
|
||||
ifprimtop 3 # any obj lval
|
||||
pop # any obj
|
||||
dup # any obj obj
|
||||
goto 2
|
||||
1: pop # any obj obj
|
||||
2: pop # any obj
|
||||
callprop toString # any toString obj
|
||||
call 0 # any lval
|
||||
primtop # any rval
|
||||
goto 4 # any lval
|
||||
2: callprop toString # any obj toString obj
|
||||
call 0 # any obj lval
|
||||
primtop (JSTYPE_NUMBER) # any obj lval
|
||||
3: swap # any lval obj
|
||||
pop # any lval
|
||||
4: swap # lval any
|
||||
swap # lval any
|
||||
imacop # bval
|
||||
stop
|
||||
.end
|
||||
@ -146,32 +140,28 @@
|
||||
ifprimtop 3 # obj2 obj1 lval
|
||||
goto 2
|
||||
1: pop # obj2 obj1 obj1
|
||||
2: pop # obj2 obj1
|
||||
callprop toString # obj2 toString obj1
|
||||
call 0 # obj2 lval
|
||||
primtop # obj2 lval
|
||||
goto 4 # obj2 lval
|
||||
2: callprop toString # obj2 obj1 toString obj1
|
||||
call 0 # obj2 obj1 lval
|
||||
primtop (JSTYPE_NUMBER) # obj2 obj1 lval
|
||||
3: swap # obj2 lval obj1
|
||||
pop # obj2 lval
|
||||
4: swap # lval obj2
|
||||
swap # lval obj2
|
||||
dup # lval obj1 obj1
|
||||
dup # lval obj obj obj
|
||||
getprop valueOf # lval obj obj valueOf
|
||||
ifprimtop 5 # lval obj obj valueOf
|
||||
ifprimtop 4 # lval obj obj valueOf
|
||||
swap # lval obj valueOf obj
|
||||
string number # lval obj valueOf obj "number"
|
||||
call 1 # lval obj rval
|
||||
ifprimtop 7 # lval obj rval
|
||||
goto 6
|
||||
5: pop # lval obj obj
|
||||
6: pop # lval obj
|
||||
callprop toString # lval toString obj
|
||||
call 0 # lval rval
|
||||
primtop # lval rval
|
||||
goto 8 # lval rval
|
||||
7: swap # lval rval obj
|
||||
ifprimtop 6 # lval obj rval
|
||||
goto 5
|
||||
4: pop # lval obj obj
|
||||
5: callprop toString # lval obj toString obj
|
||||
call 0 # lval obj rval
|
||||
primtop (JSTYPE_NUMBER) # lval obj rval
|
||||
6: swap # lval rval obj
|
||||
pop # lval rval
|
||||
8: imacop # bval
|
||||
imacop # bval
|
||||
stop
|
||||
.end
|
||||
|
||||
@ -190,14 +180,12 @@
|
||||
ifprimtop 3 # any obj rval
|
||||
goto 2
|
||||
1: pop # any obj obj
|
||||
2: pop # any obj
|
||||
callprop toString # any toString obj
|
||||
call 0 # any rval
|
||||
primtop # any rval
|
||||
goto 4 # any rval
|
||||
2: callprop toString # any obj toString obj
|
||||
call 0 # any obj rval
|
||||
primtop (JSTYPE_VOID) # any obj rval
|
||||
3: swap # any rval obj
|
||||
pop # any rval
|
||||
4: add # aval
|
||||
add # aval
|
||||
stop
|
||||
.end
|
||||
|
||||
@ -213,14 +201,12 @@
|
||||
ifprimtop 3 # any obj lval
|
||||
goto 2
|
||||
1: pop # any obj obj
|
||||
2: pop # any obj
|
||||
callprop toString # any toString obj
|
||||
call 0 # any lval
|
||||
primtop # any lval
|
||||
goto 4 # any lval
|
||||
2: callprop toString # any obj toString obj
|
||||
call 0 # any obj lval
|
||||
primtop (JSTYPE_VOID) # any obj lval
|
||||
3: swap # any lval obj
|
||||
pop # any lval
|
||||
4: swap # lval any
|
||||
swap # lval any
|
||||
add # aval
|
||||
stop
|
||||
.end
|
||||
@ -237,32 +223,28 @@
|
||||
ifprimtop 3 # obj2 obj1 lval
|
||||
goto 2
|
||||
1: pop # obj2 obj1 obj1
|
||||
2: pop # obj2 obj1
|
||||
callprop toString # obj2 toString obj1
|
||||
call 0 # obj2 lval
|
||||
primtop # obj2 lval
|
||||
goto 4 # obj2 lval
|
||||
2: callprop toString # obj2 obj toString obj1
|
||||
call 0 # obj2 obj lval
|
||||
primtop (JSTYPE_VOID) # obj2 obj lval
|
||||
3: swap # obj2 lval obj1
|
||||
pop # obj2 lval
|
||||
4: swap # lval obj2
|
||||
swap # lval obj2
|
||||
dup # lval obj1 obj1
|
||||
dup # lval obj obj obj
|
||||
getprop valueOf # lval obj obj valueOf
|
||||
ifprimtop 5 # lval obj obj valueOf
|
||||
ifprimtop 4 # lval obj obj valueOf
|
||||
swap # lval obj valueOf obj
|
||||
string void # lval obj valueOf obj "void"
|
||||
call 1 # lval obj rval
|
||||
ifprimtop 7 # lval obj rval
|
||||
goto 6
|
||||
5: pop # lval obj obj
|
||||
6: pop # lval obj
|
||||
callprop toString # lval toString obj
|
||||
call 0 # lval rval
|
||||
primtop # lval rval
|
||||
goto 8 # lval rval
|
||||
7: swap # lval rval obj
|
||||
ifprimtop 6 # lval obj rval
|
||||
goto 5
|
||||
4: pop # lval obj obj
|
||||
5: callprop toString # lval obj toString obj
|
||||
call 0 # lval obj rval
|
||||
primtop (JSTYPE_VOID) # lval obj rval
|
||||
6: swap # lval rval obj
|
||||
pop # lval rval
|
||||
8: add # aval
|
||||
add # aval
|
||||
stop
|
||||
.end
|
||||
|
||||
@ -279,15 +261,16 @@
|
||||
string number # obj valueOf obj "number"
|
||||
call 1 # obj lval
|
||||
ifprimtop 1 # obj lval
|
||||
goto 3 # obj lval
|
||||
goto 3
|
||||
1: swap # lval obj
|
||||
pop # lval
|
||||
goto 4 # lval
|
||||
goto 4
|
||||
2: pop # obj obj
|
||||
3: pop # obj
|
||||
callprop toString # toString obj
|
||||
call 0 # lval
|
||||
primtop # lval
|
||||
3: callprop toString # obj toString obj
|
||||
call 0 # obj lval
|
||||
primtop (JSTYPE_NUMBER) # obj lval
|
||||
swap # lval obj
|
||||
pop # lval
|
||||
4: imacop # aval
|
||||
stop
|
||||
.end
|
||||
@ -306,15 +289,13 @@
|
||||
ifprimtop 3 # String this obj rval
|
||||
goto 2
|
||||
1: pop # String this obj obj
|
||||
2: pop # String this obj
|
||||
callprop valueOf # String this valueOf obj
|
||||
string string # String this valueOf obj "string"
|
||||
call 1 # String this rval
|
||||
primtop # String this rval
|
||||
goto 4 # String this rval
|
||||
2: callprop valueOf # String this obj valueOf obj
|
||||
string string # String this obj valueOf obj "string"
|
||||
call 1 # String this obj rval
|
||||
primtop (JSTYPE_STRING) # String this obj rval
|
||||
3: swap # String this rval obj
|
||||
pop # String this rval
|
||||
4: call 1 # str
|
||||
call 1 # str
|
||||
stop # str
|
||||
.end
|
||||
|
||||
@ -332,15 +313,13 @@
|
||||
ifprimtop 3 # String this obj rval
|
||||
goto 2
|
||||
1: pop # String this obj obj
|
||||
2: pop # String this obj
|
||||
callprop valueOf # String this valueOf obj
|
||||
string string # String this valueOf obj "string"
|
||||
call 1 # String this rval
|
||||
primtop # String this rval
|
||||
goto 4 # String this rval
|
||||
2: callprop valueOf # String this obj valueOf obj
|
||||
string string # String this obj valueOf obj "string"
|
||||
call 1 # String this obj rval
|
||||
primtop (JSTYPE_STRING) # String this obj rval
|
||||
3: swap # String this rval obj
|
||||
pop # String this rval
|
||||
4: new 1 # strobj
|
||||
new 1 # strobj
|
||||
stop # strobj
|
||||
.end
|
||||
|
||||
|
@ -6568,10 +6568,14 @@ js_Interpret(JSContext *cx)
|
||||
BEGIN_CASE(JSOP_PRIMTOP)
|
||||
JS_ASSERT(regs.sp > StackBase(fp));
|
||||
lval = FETCH_OPND(-1);
|
||||
i = GET_INT8(regs.pc);
|
||||
if (!JSVAL_IS_PRIMITIVE(lval)) {
|
||||
lval = FETCH_OPND(-2);
|
||||
js_ReportValueError2(cx, JSMSG_CANT_CONVERT_TO,
|
||||
JSDVG_SEARCH_STACK, lval, NULL,
|
||||
"primitive type");
|
||||
-2, lval, NULL,
|
||||
(i == JSTYPE_VOID)
|
||||
? "primitive type"
|
||||
: JS_TYPE_STR(i));
|
||||
goto error;
|
||||
}
|
||||
END_CASE(JSOP_PRIMTOP)
|
||||
|
@ -5077,17 +5077,16 @@ js_DecompileValueGenerator(JSContext *cx, intN spindex, jsval v,
|
||||
}
|
||||
} while (*--sp != v);
|
||||
|
||||
if (sp >= stackBase + pcdepth) {
|
||||
/*
|
||||
* The value comes from a temporary slot that the interpreter
|
||||
* uses for GC roots or when JSOP_APPLY extended the stack to
|
||||
* fit the argument array elements. Assume that it is the
|
||||
* current PC that caused the exception.
|
||||
*/
|
||||
pc = fp->imacpc ? fp->imacpc : regs->pc;
|
||||
} else {
|
||||
/*
|
||||
* The value may have come from beyond stackBase + pcdepth,
|
||||
* meaning that it came from a temporary slot that the
|
||||
* interpreter uses for GC roots or when JSOP_APPLY extended
|
||||
* the stack to fit the argument array elements. Only update pc
|
||||
* if beneath stackBase + pcdepth; otherwise blame existing
|
||||
* (current) PC.
|
||||
*/
|
||||
if (sp < stackBase + pcdepth)
|
||||
pc = pcstack[sp - stackBase];
|
||||
}
|
||||
}
|
||||
|
||||
release_pcstack:
|
||||
@ -5103,7 +5102,16 @@ js_DecompileValueGenerator(JSContext *cx, intN spindex, jsval v,
|
||||
regs->pc = imacpc;
|
||||
fp->imacpc = NULL;
|
||||
}
|
||||
name = DecompileExpression(cx, script, fp->fun, pc);
|
||||
|
||||
/*
|
||||
* FIXME: bug 489843. Stack reconstruction may have returned a pc
|
||||
* value *inside* an imacro; this would confuse the decompiler.
|
||||
*/
|
||||
if (imacpc && size_t(pc - script->code) >= script->length)
|
||||
name = FAILED_EXPRESSION_DECOMPILER;
|
||||
else
|
||||
name = DecompileExpression(cx, script, fp->fun, pc);
|
||||
|
||||
if (imacpc) {
|
||||
regs->pc = savepc;
|
||||
fp->imacpc = imacpc;
|
||||
@ -5261,12 +5269,148 @@ js_ReconstructStackDepth(JSContext *cx, JSScript *script, jsbytecode *pc)
|
||||
return ReconstructPCStack(cx, script, pc, NULL);
|
||||
}
|
||||
|
||||
#define LOCAL_ASSERT(expr) LOCAL_ASSERT_RV(expr, -1);
|
||||
|
||||
static intN
|
||||
SimulateOp(JSContext *cx, JSScript *script, JSOp op, const JSCodeSpec *cs,
|
||||
jsbytecode *pc, jsbytecode **pcstack, uintN &pcdepth)
|
||||
{
|
||||
uintN nuses = js_GetStackUses(cs, op, pc);
|
||||
uintN ndefs = js_GetStackDefs(cx, cs, op, script, pc);
|
||||
LOCAL_ASSERT(pcdepth >= nuses);
|
||||
pcdepth -= nuses;
|
||||
LOCAL_ASSERT(pcdepth + ndefs <= StackDepth(script));
|
||||
|
||||
/*
|
||||
* Fill the slots that the opcode defines withs its pc unless it just
|
||||
* reshuffles the stack. In the latter case we want to preserve the
|
||||
* opcode that generated the original value.
|
||||
*/
|
||||
switch (op) {
|
||||
default:
|
||||
if (pcstack) {
|
||||
for (uintN i = 0; i != ndefs; ++i)
|
||||
pcstack[pcdepth + i] = pc;
|
||||
}
|
||||
break;
|
||||
|
||||
case JSOP_CASE:
|
||||
case JSOP_CASEX:
|
||||
/* Keep the switch value. */
|
||||
JS_ASSERT(ndefs == 1);
|
||||
break;
|
||||
|
||||
case JSOP_DUP:
|
||||
JS_ASSERT(ndefs == 2);
|
||||
if (pcstack)
|
||||
pcstack[pcdepth + 1] = pcstack[pcdepth];
|
||||
break;
|
||||
|
||||
case JSOP_DUP2:
|
||||
JS_ASSERT(ndefs == 4);
|
||||
if (pcstack) {
|
||||
pcstack[pcdepth + 2] = pcstack[pcdepth];
|
||||
pcstack[pcdepth + 3] = pcstack[pcdepth + 1];
|
||||
}
|
||||
break;
|
||||
|
||||
case JSOP_SWAP:
|
||||
JS_ASSERT(ndefs == 2);
|
||||
if (pcstack) {
|
||||
jsbytecode *tmp = pcstack[pcdepth + 1];
|
||||
pcstack[pcdepth + 1] = pcstack[pcdepth];
|
||||
pcstack[pcdepth] = tmp;
|
||||
}
|
||||
break;
|
||||
}
|
||||
pcdepth += ndefs;
|
||||
return pcdepth;
|
||||
}
|
||||
|
||||
#ifdef JS_TRACER
|
||||
static intN
|
||||
SimulateImacroCFG(JSContext *cx, JSScript *script,
|
||||
uintN pcdepth, jsbytecode *pc, jsbytecode *target,
|
||||
jsbytecode **pcstack)
|
||||
{
|
||||
size_t nbytes = StackDepth(script) * sizeof *pcstack;
|
||||
jsbytecode** tmp_pcstack = (jsbytecode **) JS_malloc(cx, nbytes);
|
||||
if (!tmp_pcstack)
|
||||
return -1;
|
||||
memcpy(tmp_pcstack, pcstack, nbytes);
|
||||
|
||||
ptrdiff_t oplen;
|
||||
for (; pc < target; pc += oplen) {
|
||||
JSOp op = js_GetOpcode(cx, script, pc);
|
||||
const JSCodeSpec *cs = &js_CodeSpec[op];
|
||||
oplen = cs->length;
|
||||
if (oplen < 0)
|
||||
oplen = js_GetVariableBytecodeLength(pc);
|
||||
|
||||
if (SimulateOp(cx, script, op, cs, pc, tmp_pcstack, pcdepth) < 0)
|
||||
goto failure;
|
||||
|
||||
uint32 type = cs->format & JOF_TYPEMASK;
|
||||
if (type == JOF_JUMP || type == JOF_JUMPX) {
|
||||
ptrdiff_t jmpoff = (type == JOF_JUMP) ? GET_JUMP_OFFSET(pc)
|
||||
: GET_JUMPX_OFFSET(pc);
|
||||
LOCAL_ASSERT(jmpoff >= 0);
|
||||
uintN tmp_pcdepth = SimulateImacroCFG(cx, script, pcdepth, pc + jmpoff,
|
||||
target, tmp_pcstack);
|
||||
if (tmp_pcdepth >= 0) {
|
||||
pcdepth = tmp_pcdepth;
|
||||
goto success;
|
||||
}
|
||||
|
||||
if (op == JSOP_GOTO || op == JSOP_GOTOX)
|
||||
goto failure;
|
||||
}
|
||||
}
|
||||
|
||||
if (pc > target)
|
||||
goto failure;
|
||||
|
||||
LOCAL_ASSERT(pc == target);
|
||||
|
||||
success:
|
||||
LOCAL_ASSERT(pcdepth >= 0);
|
||||
memcpy(pcstack, tmp_pcstack, nbytes);
|
||||
JS_free(cx, tmp_pcstack);
|
||||
return pcdepth;
|
||||
|
||||
failure:
|
||||
JS_free(cx, tmp_pcstack);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static intN
|
||||
ReconstructPCStack(JSContext *cx, JSScript *script, jsbytecode *target,
|
||||
jsbytecode **pcstack);
|
||||
|
||||
static intN
|
||||
ReconstructImacroPCStack(JSContext *cx, JSScript *script,
|
||||
jsbytecode *imacstart, jsbytecode *target,
|
||||
jsbytecode **pcstack)
|
||||
{
|
||||
/*
|
||||
* Begin with a recursive call back to ReconstructPCStack to pick up
|
||||
* the state-of-the-world at the *start* of the imacro.
|
||||
*/
|
||||
JSStackFrame *fp = js_GetScriptedCaller(cx, NULL);
|
||||
JS_ASSERT(fp->imacpc);
|
||||
uintN pcdepth = ReconstructPCStack(cx, script, fp->imacpc, pcstack);
|
||||
if (pcdepth < 0)
|
||||
return pcdepth;
|
||||
return SimulateImacroCFG(cx, script, pcdepth, imacstart, target, pcstack);
|
||||
}
|
||||
|
||||
extern jsbytecode* js_GetImacroStart(jsbytecode* pc);
|
||||
#endif
|
||||
|
||||
static intN
|
||||
ReconstructPCStack(JSContext *cx, JSScript *script, jsbytecode *target,
|
||||
jsbytecode **pcstack)
|
||||
{
|
||||
#define LOCAL_ASSERT(expr) LOCAL_ASSERT_RV(expr, -1);
|
||||
|
||||
/*
|
||||
* Walk forward from script->main and compute the stack depth and stack of
|
||||
* operand-generating opcode PCs in pcstack.
|
||||
@ -5274,9 +5418,16 @@ ReconstructPCStack(JSContext *cx, JSScript *script, jsbytecode *target,
|
||||
* FIXME: Code to compute oplen copied from js_Disassemble1 and reduced.
|
||||
* FIXME: Optimize to use last empty-stack sequence point.
|
||||
*/
|
||||
#ifdef JS_TRACER
|
||||
jsbytecode *imacstart = js_GetImacroStart(target);
|
||||
|
||||
if (imacstart)
|
||||
return ReconstructImacroPCStack(cx, script, imacstart, target, pcstack);
|
||||
#endif
|
||||
|
||||
LOCAL_ASSERT(script->main <= target && target < script->code + script->length);
|
||||
uintN pcdepth = 0;
|
||||
jsbytecode *pc = script->main;
|
||||
uintN pcdepth = 0;
|
||||
ptrdiff_t oplen;
|
||||
for (; pc < target; pc += oplen) {
|
||||
JSOp op = js_GetOpcode(cx, script, pc);
|
||||
@ -5320,46 +5471,9 @@ ReconstructPCStack(JSContext *cx, JSScript *script, jsbytecode *target,
|
||||
if (sn && SN_TYPE(sn) == SRC_HIDDEN)
|
||||
continue;
|
||||
|
||||
uintN nuses = js_GetStackUses(cs, op, pc);
|
||||
uintN ndefs = js_GetStackDefs(cx, cs, op, script, pc);
|
||||
LOCAL_ASSERT(pcdepth >= nuses);
|
||||
pcdepth -= nuses;
|
||||
LOCAL_ASSERT(pcdepth + ndefs <= StackDepth(script));
|
||||
if (SimulateOp(cx, script, op, cs, pc, pcstack, pcdepth) < 0)
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* Fill the slots that the opcode defines withs its pc unless it just
|
||||
* reshuffle the stack. In the latter case we want to preserve the
|
||||
* opcode that generated the original value.
|
||||
*/
|
||||
switch (op) {
|
||||
default:
|
||||
if (pcstack) {
|
||||
for (uintN i = 0; i != ndefs; ++i)
|
||||
pcstack[pcdepth + i] = pc;
|
||||
}
|
||||
break;
|
||||
|
||||
case JSOP_CASE:
|
||||
case JSOP_CASEX:
|
||||
/* Keep the switch value. */
|
||||
JS_ASSERT(ndefs == 1);
|
||||
break;
|
||||
|
||||
case JSOP_DUP:
|
||||
JS_ASSERT(ndefs == 2);
|
||||
if (pcstack)
|
||||
pcstack[pcdepth + 1] = pcstack[pcdepth];
|
||||
break;
|
||||
|
||||
case JSOP_DUP2:
|
||||
JS_ASSERT(ndefs == 4);
|
||||
if (pcstack) {
|
||||
pcstack[pcdepth + 2] = pcstack[pcdepth];
|
||||
pcstack[pcdepth + 3] = pcstack[pcdepth + 1];
|
||||
}
|
||||
break;
|
||||
}
|
||||
pcdepth += ndefs;
|
||||
}
|
||||
LOCAL_ASSERT(pc == target);
|
||||
return pcdepth;
|
||||
|
@ -493,7 +493,7 @@ OPDEF(JSOP_LEAVEBLOCK, 200,"leaveblock", NULL, 3, -1, 0, 0, JOF_UINT16
|
||||
OPDEF(JSOP_IFPRIMTOP, 201,"ifprimtop", NULL, 3, 1, 1, 0, JOF_JUMP|JOF_DETECTING)
|
||||
|
||||
/* Throws a TypeError if the value at the top of the stack is not primitive. */
|
||||
OPDEF(JSOP_PRIMTOP, 202,"primtop", NULL, 1, 1, 1, 0, JOF_BYTE)
|
||||
OPDEF(JSOP_PRIMTOP, 202,"primtop", NULL, 2, 1, 1, 0, JOF_INT8)
|
||||
|
||||
/*
|
||||
* Generator and array comprehension support.
|
||||
@ -536,7 +536,7 @@ OPDEF(JSOP_INDEXBASE3, 214,"atombase3", NULL, 1, 0, 0, 0, JOF_BYTE |
|
||||
OPDEF(JSOP_CALLGVAR, 215, "callgvar", NULL, 3, 0, 2, 19, JOF_ATOM|JOF_NAME|JOF_CALLOP)
|
||||
OPDEF(JSOP_CALLLOCAL, 216, "calllocal", NULL, 3, 0, 2, 19, JOF_LOCAL|JOF_NAME|JOF_CALLOP)
|
||||
OPDEF(JSOP_CALLARG, 217, "callarg", NULL, 3, 0, 2, 19, JOF_QARG |JOF_NAME|JOF_CALLOP)
|
||||
OPDEF(JSOP_CALLBUILTIN, 218, "callbuiltin", NULL, 3, 0, 2, 0, JOF_UINT16)
|
||||
OPDEF(JSOP_CALLBUILTIN, 218, "callbuiltin", NULL, 3, 1, 2, 0, JOF_UINT16)
|
||||
|
||||
/*
|
||||
* Opcodes to hold 8-bit and 32-bit immediate integer operands.
|
||||
|
Loading…
Reference in New Issue
Block a user