mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 688891: C++ power-armor for Sprinter. (r=cdleary)
This commit is contained in:
parent
b67a4113ce
commit
383585fcc8
@ -57,11 +57,11 @@ void
|
||||
PrintBytecode(JSContext *cx, JSScript *script, jsbytecode *pc)
|
||||
{
|
||||
printf("#%u:", script->id());
|
||||
LifoAlloc lifoAlloc(1024);
|
||||
Sprinter sprinter;
|
||||
INIT_SPRINTER(cx, &sprinter, &lifoAlloc, 0);
|
||||
Sprinter sprinter(cx);
|
||||
if (!sprinter.init())
|
||||
return;
|
||||
js_Disassemble1(cx, script, pc, pc - script->code, true, &sprinter);
|
||||
fprintf(stdout, "%s", sprinter.base);
|
||||
fprintf(stdout, "%s", sprinter.string());
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -5600,7 +5600,7 @@ JS_NewStringCopyZ(JSContext *cx, const char *s)
|
||||
|
||||
AssertNoGC(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
if (!s)
|
||||
if (!s || !*s)
|
||||
return cx->runtime->emptyString;
|
||||
n = strlen(s);
|
||||
js = InflateString(cx, s, &n);
|
||||
|
@ -1620,13 +1620,13 @@ JS_PUBLIC_API(void)
|
||||
JS_DumpBytecode(JSContext *cx, JSScript *script)
|
||||
{
|
||||
#if defined(DEBUG)
|
||||
LifoAlloc lifoAlloc(1024);
|
||||
Sprinter sprinter;
|
||||
INIT_SPRINTER(cx, &sprinter, &lifoAlloc, 0);
|
||||
Sprinter sprinter(cx);
|
||||
if (!sprinter.init())
|
||||
return;
|
||||
|
||||
fprintf(stdout, "--- SCRIPT %s:%d ---\n", script->filename, script->lineno);
|
||||
js_Disassemble(cx, script, true, &sprinter);
|
||||
fputs(sprinter.base, stdout);
|
||||
fputs(sprinter.string(), stdout);
|
||||
fprintf(stdout, "--- END SCRIPT %s:%d ---\n", script->filename, script->lineno);
|
||||
#endif
|
||||
}
|
||||
@ -1637,13 +1637,13 @@ JS_DumpPCCounts(JSContext *cx, JSScript *script)
|
||||
#if defined(DEBUG)
|
||||
JS_ASSERT(script->pcCounters);
|
||||
|
||||
LifoAlloc lifoAlloc(1024);
|
||||
Sprinter sprinter;
|
||||
INIT_SPRINTER(cx, &sprinter, &lifoAlloc, 0);
|
||||
Sprinter sprinter(cx);
|
||||
if (!sprinter.init())
|
||||
return;
|
||||
|
||||
fprintf(stdout, "--- SCRIPT %s:%d ---\n", script->filename, script->lineno);
|
||||
js_DumpPCCounts(cx, script, &sprinter);
|
||||
fputs(sprinter.base, stdout);
|
||||
fputs(sprinter.string(), stdout);
|
||||
fprintf(stdout, "--- END SCRIPT %s:%d ---\n", script->filename, script->lineno);
|
||||
#endif
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -440,27 +440,81 @@ DecompileValueGenerator(JSContext *cx, intN spindex, const Value &v,
|
||||
/*
|
||||
* Sprintf, but with unlimited and automatically allocated buffering.
|
||||
*/
|
||||
struct Sprinter {
|
||||
JSContext *context; /* context executing the decompiler */
|
||||
LifoAlloc *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 */
|
||||
class Sprinter
|
||||
{
|
||||
public:
|
||||
struct InvariantChecker
|
||||
{
|
||||
const Sprinter *parent;
|
||||
|
||||
explicit InvariantChecker(const Sprinter *p) : parent(p) {
|
||||
parent->checkInvariants();
|
||||
}
|
||||
|
||||
~InvariantChecker() {
|
||||
parent->checkInvariants();
|
||||
}
|
||||
};
|
||||
|
||||
JSContext *context; /* context executing the decompiler */
|
||||
|
||||
private:
|
||||
static const size_t DefaultSize;
|
||||
#ifdef DEBUG
|
||||
bool initialized; /* true if this is initialized, use for debug builds */
|
||||
#endif
|
||||
char *base; /* malloc'd buffer address */
|
||||
size_t size; /* size of buffer allocated at base */
|
||||
ptrdiff_t offset; /* offset of next free char in buffer */
|
||||
|
||||
bool realloc_(size_t newSize);
|
||||
|
||||
public:
|
||||
explicit Sprinter(JSContext *cx);
|
||||
~Sprinter();
|
||||
|
||||
/* Initialize this sprinter, returns false on error */
|
||||
bool init();
|
||||
|
||||
void checkInvariants() const;
|
||||
|
||||
const char *string() const;
|
||||
const char *stringEnd() const;
|
||||
/* Returns the string at offset |off| */
|
||||
char *stringAt(ptrdiff_t off) const;
|
||||
/* Returns the char at offset |off| */
|
||||
char &operator[](size_t off);
|
||||
/* Test if this Sprinter is empty */
|
||||
bool empty() const;
|
||||
|
||||
/*
|
||||
* Attempt to reserve len + 1 space (for a trailing NULL byte). If the
|
||||
* attempt succeeds, return a pointer to the start of that space and adjust the
|
||||
* internal content. The caller *must* completely fill this space on success.
|
||||
*/
|
||||
char *reserve(size_t len);
|
||||
/* Like reserve, but memory is initialized to 0 */
|
||||
char *reserveAndClear(size_t len);
|
||||
|
||||
/*
|
||||
* Puts |len| characters from |s| at the current position and return an offset to
|
||||
* the beginning of this new data
|
||||
*/
|
||||
ptrdiff_t put(const char *s, size_t len);
|
||||
ptrdiff_t putString(JSString *str);
|
||||
|
||||
/* Prints a formatted string into the buffer */
|
||||
int printf(const char *fmt, ...);
|
||||
|
||||
/* Change the offset */
|
||||
void setOffset(const char *end);
|
||||
void setOffset(ptrdiff_t off);
|
||||
|
||||
/* Get the offset */
|
||||
ptrdiff_t getOffset() const;
|
||||
ptrdiff_t getOffsetOf(const char *string) const;
|
||||
};
|
||||
|
||||
#define INIT_SPRINTER(cx, sp, ap, off) \
|
||||
((sp)->context = cx, (sp)->pool = ap, (sp)->base = NULL, (sp)->size = 0, \
|
||||
(sp)->offset = off)
|
||||
|
||||
/*
|
||||
* Attempt to reserve len space in sp (including a trailing NULL byte). If the
|
||||
* attempt succeeds, return a pointer to the start of that space and adjust the
|
||||
* length of sp's contents. The caller *must* completely fill this space
|
||||
* (including the space for the trailing NULL byte) on success.
|
||||
*/
|
||||
extern char *
|
||||
SprintReserveAmount(Sprinter *sp, size_t len);
|
||||
|
||||
extern ptrdiff_t
|
||||
SprintPut(Sprinter *sp, const char *s, size_t len);
|
||||
|
||||
|
@ -1840,13 +1840,12 @@ mjit::Compiler::finishThisUp()
|
||||
#define SPEW_OPCODE() \
|
||||
JS_BEGIN_MACRO \
|
||||
if (IsJaegerSpewChannelActive(JSpew_JSOps)) { \
|
||||
LifoAllocScope las(&cx->tempLifoAlloc()); \
|
||||
Sprinter sprinter; \
|
||||
INIT_SPRINTER(cx, &sprinter, &cx->tempLifoAlloc(), 0); \
|
||||
Sprinter sprinter(cx); \
|
||||
sprinter.init(); \
|
||||
js_Disassemble1(cx, script, PC, PC - script->code, \
|
||||
JS_TRUE, &sprinter); \
|
||||
JaegerSpew(JSpew_JSOps, " %2d %s", \
|
||||
frame.stackDepth(), sprinter.base); \
|
||||
frame.stackDepth(), sprinter.string()); \
|
||||
} \
|
||||
JS_END_MACRO;
|
||||
#else
|
||||
|
@ -1916,9 +1916,9 @@ SrcNotes(JSContext *cx, JSScript *script, Sprinter *sp)
|
||||
JSAtom *atom = script->getAtom(index);
|
||||
Sprint(sp, " atom %u (", index);
|
||||
size_t len = PutEscapedString(NULL, 0, atom, '\0');
|
||||
if (char *buf = SprintReserveAmount(sp, len)) {
|
||||
if (char *buf = sp->reserve(len)) {
|
||||
PutEscapedString(buf, len, atom, 0);
|
||||
buf[len] = '\0';
|
||||
buf[len] = 0;
|
||||
}
|
||||
Sprint(sp, ")");
|
||||
break;
|
||||
@ -1964,9 +1964,9 @@ SrcNotes(JSContext *cx, JSScript *script, Sprinter *sp)
|
||||
static JSBool
|
||||
Notes(JSContext *cx, uintN argc, jsval *vp)
|
||||
{
|
||||
LifoAllocScope las(&cx->tempLifoAlloc());
|
||||
Sprinter sprinter;
|
||||
INIT_SPRINTER(cx, &sprinter, &cx->tempLifoAlloc(), 0);
|
||||
Sprinter sprinter(cx);
|
||||
if (!sprinter.init())
|
||||
return JS_FALSE;
|
||||
|
||||
jsval *argv = JS_ARGV(cx, vp);
|
||||
for (uintN i = 0; i < argc; i++) {
|
||||
@ -1977,7 +1977,7 @@ Notes(JSContext *cx, uintN argc, jsval *vp)
|
||||
SrcNotes(cx, script, &sprinter);
|
||||
}
|
||||
|
||||
JSString *str = JS_NewStringCopyZ(cx, sprinter.base);
|
||||
JSString *str = JS_NewStringCopyZ(cx, sprinter.string());
|
||||
if (!str)
|
||||
return JS_FALSE;
|
||||
JS_SET_RVAL(cx, vp, STRING_TO_JSVAL(str));
|
||||
@ -2117,19 +2117,18 @@ DisassembleToString(JSContext *cx, uintN argc, jsval *vp)
|
||||
if (!p.parse(cx))
|
||||
return false;
|
||||
|
||||
LifoAllocScope las(&cx->tempLifoAlloc());
|
||||
Sprinter sprinter;
|
||||
INIT_SPRINTER(cx, &sprinter, &cx->tempLifoAlloc(), 0);
|
||||
Sprinter *sp = &sprinter;
|
||||
Sprinter sprinter(cx);
|
||||
if (!sprinter.init())
|
||||
return false;
|
||||
|
||||
bool ok = true;
|
||||
if (p.argc == 0) {
|
||||
/* Without arguments, disassemble the current script. */
|
||||
if (JSStackFrame *frame = JS_GetScriptedCaller(cx, NULL)) {
|
||||
JSScript *script = JS_GetFrameScript(cx, frame);
|
||||
if (js_Disassemble(cx, script, p.lines, sp)) {
|
||||
SrcNotes(cx, script, sp);
|
||||
TryNotes(cx, script, sp);
|
||||
if (js_Disassemble(cx, script, p.lines, &sprinter)) {
|
||||
SrcNotes(cx, script, &sprinter);
|
||||
TryNotes(cx, script, &sprinter);
|
||||
} else {
|
||||
ok = false;
|
||||
}
|
||||
@ -2138,11 +2137,11 @@ DisassembleToString(JSContext *cx, uintN argc, jsval *vp)
|
||||
for (uintN i = 0; i < p.argc; i++) {
|
||||
JSFunction *fun;
|
||||
JSScript *script = ValueToScript(cx, p.argv[i], &fun);
|
||||
ok = ok && script && DisassembleScript(cx, script, fun, p.lines, p.recursive, sp);
|
||||
ok = ok && script && DisassembleScript(cx, script, fun, p.lines, p.recursive, &sprinter);
|
||||
}
|
||||
}
|
||||
|
||||
JSString *str = ok ? JS_NewStringCopyZ(cx, sprinter.base) : NULL;
|
||||
JSString *str = ok ? JS_NewStringCopyZ(cx, sprinter.string()) : NULL;
|
||||
if (!str)
|
||||
return false;
|
||||
JS_SET_RVAL(cx, vp, STRING_TO_JSVAL(str));
|
||||
@ -2156,19 +2155,18 @@ Disassemble(JSContext *cx, uintN argc, jsval *vp)
|
||||
if (!p.parse(cx))
|
||||
return false;
|
||||
|
||||
LifoAllocScope las(&cx->tempLifoAlloc());
|
||||
Sprinter sprinter;
|
||||
INIT_SPRINTER(cx, &sprinter, &cx->tempLifoAlloc(), 0);
|
||||
Sprinter *sp = &sprinter;
|
||||
Sprinter sprinter(cx);
|
||||
if (!sprinter.init())
|
||||
return false;
|
||||
|
||||
bool ok = true;
|
||||
if (p.argc == 0) {
|
||||
/* Without arguments, disassemble the current script. */
|
||||
if (JSStackFrame *frame = JS_GetScriptedCaller(cx, NULL)) {
|
||||
JSScript *script = JS_GetFrameScript(cx, frame);
|
||||
if (js_Disassemble(cx, script, p.lines, sp)) {
|
||||
SrcNotes(cx, script, sp);
|
||||
TryNotes(cx, script, sp);
|
||||
if (js_Disassemble(cx, script, p.lines, &sprinter)) {
|
||||
SrcNotes(cx, script, &sprinter);
|
||||
TryNotes(cx, script, &sprinter);
|
||||
} else {
|
||||
ok = false;
|
||||
}
|
||||
@ -2177,12 +2175,12 @@ Disassemble(JSContext *cx, uintN argc, jsval *vp)
|
||||
for (uintN i = 0; i < p.argc; i++) {
|
||||
JSFunction *fun;
|
||||
JSScript *script = ValueToScript(cx, p.argv[i], &fun);
|
||||
ok = ok && script && DisassembleScript(cx, script, fun, p.lines, p.recursive, sp);
|
||||
ok = ok && script && DisassembleScript(cx, script, fun, p.lines, p.recursive, &sprinter);
|
||||
}
|
||||
}
|
||||
|
||||
if (ok)
|
||||
fprintf(stdout, "%s\n", sprinter.base);
|
||||
fprintf(stdout, "%s\n", sprinter.string());
|
||||
JS_SET_RVAL(cx, vp, JSVAL_VOID);
|
||||
return ok;
|
||||
}
|
||||
@ -2218,12 +2216,12 @@ DisassFile(JSContext *cx, uintN argc, jsval *vp)
|
||||
if (!script)
|
||||
return false;
|
||||
|
||||
LifoAllocScope las(&cx->tempLifoAlloc());
|
||||
Sprinter sprinter;
|
||||
INIT_SPRINTER(cx, &sprinter, &cx->tempLifoAlloc(), 0);
|
||||
Sprinter sprinter(cx);
|
||||
if (!sprinter.init())
|
||||
return false;
|
||||
bool ok = DisassembleScript(cx, script, NULL, p.lines, p.recursive, &sprinter);
|
||||
if (ok)
|
||||
fprintf(stdout, "%s\n", sprinter.base);
|
||||
fprintf(stdout, "%s\n", sprinter.string());
|
||||
if (!ok)
|
||||
return false;
|
||||
|
||||
@ -2267,10 +2265,11 @@ DisassWithSrc(JSContext *cx, uintN argc, jsval *vp)
|
||||
pc = script->code;
|
||||
end = pc + script->length;
|
||||
|
||||
LifoAllocScope las(&cx->tempLifoAlloc());
|
||||
Sprinter sprinter;
|
||||
Sprinter *sp = &sprinter;
|
||||
INIT_SPRINTER(cx, sp, &cx->tempLifoAlloc(), 0);
|
||||
Sprinter sprinter(cx);
|
||||
if (!sprinter.init()) {
|
||||
ok = JS_FALSE;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
/* burn the leading lines */
|
||||
line2 = JS_PCToLineNumber(cx, script, pc);
|
||||
@ -2290,11 +2289,11 @@ DisassWithSrc(JSContext *cx, uintN argc, jsval *vp)
|
||||
if (line2 < line1) {
|
||||
if (bupline != line2) {
|
||||
bupline = line2;
|
||||
Sprint(sp, "%s %3u: BACKUP\n", sep, line2);
|
||||
Sprint(&sprinter, "%s %3u: BACKUP\n", sep, line2);
|
||||
}
|
||||
} else {
|
||||
if (bupline && line1 == line2)
|
||||
Sprint(sp, "%s %3u: RESTORE\n", sep, line2);
|
||||
Sprint(&sprinter, "%s %3u: RESTORE\n", sep, line2);
|
||||
bupline = 0;
|
||||
while (line1 < line2) {
|
||||
if (!fgets(linebuf, LINE_BUF_LEN, file)) {
|
||||
@ -2305,11 +2304,11 @@ DisassWithSrc(JSContext *cx, uintN argc, jsval *vp)
|
||||
goto bail;
|
||||
}
|
||||
line1++;
|
||||
Sprint(sp, "%s %3u: %s", sep, line1, linebuf);
|
||||
Sprint(&sprinter, "%s %3u: %s", sep, line1, linebuf);
|
||||
}
|
||||
}
|
||||
|
||||
len = js_Disassemble1(cx, script, pc, pc - script->code, JS_TRUE, sp);
|
||||
len = js_Disassemble1(cx, script, pc, pc - script->code, JS_TRUE, &sprinter);
|
||||
if (!len) {
|
||||
ok = JS_FALSE;
|
||||
goto bail;
|
||||
|
Loading…
Reference in New Issue
Block a user