mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 517633: printf that can be called from trace, r=lw
--HG-- extra : rebase_source : 7bf61fae910feab40ef706717420e883ccafc4da
This commit is contained in:
parent
2d21b7a6d5
commit
10e9f4f6b8
@ -224,6 +224,7 @@ class ClosureVarInfo;
|
||||
#define _JS_CTYPE_FRAGMENT _JS_CTYPE(nanojit::Fragment *, _JS_PTR, --, --, INFALLIBLE)
|
||||
#define _JS_CTYPE_CLASS _JS_CTYPE(JSClass *, _JS_PTR, --, --, INFALLIBLE)
|
||||
#define _JS_CTYPE_DOUBLEPTR _JS_CTYPE(double *, _JS_PTR, --, --, INFALLIBLE)
|
||||
#define _JS_CTYPE_CHARPTR _JS_CTYPE(char *, _JS_PTR, --, --, INFALLIBLE)
|
||||
#define _JS_CTYPE_APNPTR _JS_CTYPE(js_ArgsPrivateNative *, _JS_PTR, --, --, INFALLIBLE)
|
||||
#define _JS_CTYPE_CVIPTR _JS_CTYPE(const ClosureVarInfo *, _JS_PTR, --, --, INFALLIBLE)
|
||||
|
||||
|
@ -641,7 +641,7 @@ js_FragProfiling_showResults(JSTraceMonitor* tm)
|
||||
|
||||
/* ----------------------------------------------------------------- */
|
||||
|
||||
#if defined DEBUG
|
||||
#ifdef DEBUG
|
||||
static const char*
|
||||
getExitName(ExitType type)
|
||||
{
|
||||
@ -657,6 +657,174 @@ getExitName(ExitType type)
|
||||
|
||||
return exitNames[type];
|
||||
}
|
||||
|
||||
static JSBool FASTCALL
|
||||
PrintOnTrace(char* format, uint32 argc, double *argv)
|
||||
{
|
||||
union {
|
||||
struct {
|
||||
uint32 lo;
|
||||
uint32 hi;
|
||||
} i;
|
||||
double d;
|
||||
char *cstr;
|
||||
JSObject *o;
|
||||
JSString *s;
|
||||
} u;
|
||||
|
||||
#define GET_ARG() JS_BEGIN_MACRO \
|
||||
if (argi >= argc) { \
|
||||
fprintf(out, "[too few args for format]"); \
|
||||
break; \
|
||||
} \
|
||||
u.d = argv[argi++]; \
|
||||
JS_END_MACRO
|
||||
|
||||
FILE *out = stderr;
|
||||
|
||||
uint32 argi = 0;
|
||||
for (char *p = format; *p; ++p) {
|
||||
if (*p != '%') {
|
||||
putc(*p, out);
|
||||
continue;
|
||||
}
|
||||
char ch = *++p;
|
||||
if (!ch) {
|
||||
fprintf(out, "[trailing %%]");
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (ch) {
|
||||
case 'a':
|
||||
GET_ARG();
|
||||
fprintf(out, "[%u:%u 0x%x:0x%x %lf]", u.i.lo, u.i.hi, u.i.lo, u.i.hi, u.d);
|
||||
break;
|
||||
case 'd':
|
||||
GET_ARG();
|
||||
fprintf(out, "%d", u.i.lo);
|
||||
break;
|
||||
case 'u':
|
||||
GET_ARG();
|
||||
fprintf(out, "%u", u.i.lo);
|
||||
break;
|
||||
case 'x':
|
||||
GET_ARG();
|
||||
fprintf(out, "%x", u.i.lo);
|
||||
break;
|
||||
case 'f':
|
||||
GET_ARG();
|
||||
fprintf(out, "%lf", u.d);
|
||||
break;
|
||||
case 'o':
|
||||
GET_ARG();
|
||||
js_DumpObject(u.o);
|
||||
break;
|
||||
case 's':
|
||||
GET_ARG();
|
||||
{
|
||||
size_t length = u.s->length();
|
||||
// protect against massive spew if u.s is a bad pointer.
|
||||
if (length > 1 << 16)
|
||||
length = 1 << 16;
|
||||
jschar *chars = u.s->chars();
|
||||
for (unsigned i = 0; i < length; ++i) {
|
||||
jschar co = chars[i];
|
||||
if (co < 128)
|
||||
putc(co, out);
|
||||
else if (co < 256)
|
||||
fprintf(out, "\\u%02x", co);
|
||||
else
|
||||
fprintf(out, "\\u%04x", co);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'S':
|
||||
GET_ARG();
|
||||
fprintf(out, "%s", u.cstr);
|
||||
break;
|
||||
default:
|
||||
fprintf(out, "[invalid %%%c]", *p);
|
||||
}
|
||||
}
|
||||
|
||||
#undef GET_ARG
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JS_DEFINE_CALLINFO_3(extern, BOOL, PrintOnTrace, CHARPTR, UINT32, DOUBLEPTR, 0, 0);
|
||||
|
||||
// This version is not intended to be called directly: usually it is easier to
|
||||
// use one of the other overloads.
|
||||
void
|
||||
TraceRecorder::tprint(const char *format, int count, nanojit::LIns *insa[])
|
||||
{
|
||||
size_t size = strlen(format) + 1;
|
||||
char *data = (char*) lir->insSkip(size)->payload();
|
||||
memcpy(data, format, size);
|
||||
|
||||
double *args = (double*) lir->insSkip(count * sizeof(double))->payload();
|
||||
for (int i = 0; i < count; ++i) {
|
||||
JS_ASSERT(insa[i]);
|
||||
lir->insStorei(insa[i], INS_CONSTPTR(args), sizeof(double) * i);
|
||||
}
|
||||
|
||||
LIns* args_ins[] = { INS_CONSTPTR(args), INS_CONST(count), INS_CONSTPTR(data) };
|
||||
LIns* call_ins = lir->insCall(&PrintOnTrace_ci, args_ins);
|
||||
guard(false, lir->ins_eq0(call_ins), MISMATCH_EXIT);
|
||||
}
|
||||
|
||||
// Generate a 'printf'-type call from trace for debugging.
|
||||
void
|
||||
TraceRecorder::tprint(const char *format)
|
||||
{
|
||||
LIns* insa[] = { NULL };
|
||||
tprint(format, 0, insa);
|
||||
}
|
||||
|
||||
void
|
||||
TraceRecorder::tprint(const char *format, LIns *ins)
|
||||
{
|
||||
LIns* insa[] = { ins };
|
||||
tprint(format, 1, insa);
|
||||
}
|
||||
|
||||
void
|
||||
TraceRecorder::tprint(const char *format, LIns *ins1, LIns *ins2)
|
||||
{
|
||||
LIns* insa[] = { ins1, ins2 };
|
||||
tprint(format, 2, insa);
|
||||
}
|
||||
|
||||
void
|
||||
TraceRecorder::tprint(const char *format, LIns *ins1, LIns *ins2, LIns *ins3)
|
||||
{
|
||||
LIns* insa[] = { ins1, ins2, ins3 };
|
||||
tprint(format, 3, insa);
|
||||
}
|
||||
|
||||
void
|
||||
TraceRecorder::tprint(const char *format, LIns *ins1, LIns *ins2, LIns *ins3, LIns *ins4)
|
||||
{
|
||||
LIns* insa[] = { ins1, ins2, ins3, ins4 };
|
||||
tprint(format, 4, insa);
|
||||
}
|
||||
|
||||
void
|
||||
TraceRecorder::tprint(const char *format, LIns *ins1, LIns *ins2, LIns *ins3, LIns *ins4,
|
||||
LIns *ins5)
|
||||
{
|
||||
LIns* insa[] = { ins1, ins2, ins3, ins4, ins5 };
|
||||
tprint(format, 5, insa);
|
||||
}
|
||||
|
||||
void
|
||||
TraceRecorder::tprint(const char *format, LIns *ins1, LIns *ins2, LIns *ins3, LIns *ins4,
|
||||
LIns *ins5, LIns *ins6)
|
||||
{
|
||||
LIns* insa[] = { ins1, ins2, ins3, ins4, ins5, ins6 };
|
||||
tprint(format, 6, insa);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -1053,6 +1053,20 @@ public:
|
||||
bool wasDeepAborted() { return deepAborted; }
|
||||
TreeInfo* getTreeInfo() { return treeInfo; }
|
||||
|
||||
#ifdef DEBUG
|
||||
void tprint(const char *format, int count, nanojit::LIns *insa[]);
|
||||
void tprint(const char *format);
|
||||
void tprint(const char *format, nanojit::LIns *ins);
|
||||
void tprint(const char *format, nanojit::LIns *ins1, nanojit::LIns *ins2);
|
||||
void tprint(const char *format, nanojit::LIns *ins1, nanojit::LIns *ins2, nanojit::LIns *ins3);
|
||||
void tprint(const char *format, nanojit::LIns *ins1, nanojit::LIns *ins2, nanojit::LIns *ins3,
|
||||
nanojit::LIns *ins4);
|
||||
void tprint(const char *format, nanojit::LIns *ins1, nanojit::LIns *ins2, nanojit::LIns *ins3,
|
||||
nanojit::LIns *ins4, nanojit::LIns *ins5);
|
||||
void tprint(const char *format, nanojit::LIns *ins1, nanojit::LIns *ins2, nanojit::LIns *ins3,
|
||||
nanojit::LIns *ins4, nanojit::LIns *ins5, nanojit::LIns *ins6);
|
||||
#endif
|
||||
|
||||
#define OPDEF(op,val,name,token,length,nuses,ndefs,prec,format) \
|
||||
JS_REQUIRES_STACK JSRecordingStatus record_##op();
|
||||
# include "jsopcode.tbl"
|
||||
|
Loading…
Reference in New Issue
Block a user