mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Removed attempt to imply ints into doubles on the fly. This can't work. Use proper float loads where needed and add some initial code for builtin functions.
This commit is contained in:
parent
228a13576a
commit
e70272bfab
@ -2345,7 +2345,9 @@ store_int(JSContext* cx, JSFrameRegs& regs, int n, jsint& i)
|
||||
if (INT_FITS_IN_JSVAL(i)) {
|
||||
prim_int_to_jsval(cx, i, regs.sp[n]);
|
||||
} else {
|
||||
if (!call_NewIntInRootedValue(cx, i, regs.sp[n]))
|
||||
jsdouble d;
|
||||
prim_int_to_double(cx, i, d);
|
||||
if (!call_NewDoubleInRootedValue(cx, d, regs.sp[n]))
|
||||
return JS_FALSE;
|
||||
}
|
||||
return JS_TRUE;
|
||||
|
@ -177,12 +177,6 @@ PRIMITIVE(call_ValueToECMAInt32)(JSContext* cx, jsval& v, jsint& i)
|
||||
return !JSVAL_IS_NULL(v);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
PRIMITIVE(call_NewIntInRootedValue)(JSContext* cx, jsint& i, jsval& v)
|
||||
{
|
||||
return js_NewDoubleInRootedValue(cx, (jsdouble)i, &v);
|
||||
}
|
||||
|
||||
static inline void
|
||||
PRIMITIVE(prim_int_to_uint)(JSContext* cx, jsint& i, uint32& u)
|
||||
{
|
||||
|
@ -132,12 +132,25 @@ static avmplus::AvmCore* core = new (&gc) avmplus::AvmCore();
|
||||
#define NAME(op)
|
||||
#endif
|
||||
|
||||
void builtin_unimplemented(void) {
|
||||
JS_ASSERT(0);
|
||||
}
|
||||
|
||||
#define builtin_DOUBLE_IS_INT builtin_unimplemented
|
||||
#define builtin_StringToDouble builtin_unimplemented
|
||||
#define builtin_ObjectToDouble builtin_unimplemented
|
||||
#define builtin_ValueToBoolean builtin_unimplemented
|
||||
|
||||
jsint builtin_DoubleToECMAInt32(jsdouble d) {
|
||||
return js_DoubleToECMAInt32(d);
|
||||
}
|
||||
|
||||
#define BUILTIN1(op, at0, atr, tr, t0, cse, fold) \
|
||||
{ 0, (at0 | (atr << 2)), cse, fold NAME(op) },
|
||||
{ (intptr_t)&builtin_##op, (at0 << 2) | atr, cse, fold NAME(op) },
|
||||
#define BUILTIN2(op, at0, at1, atr, tr, t0, t1, cse, fold) \
|
||||
{ 0, (at0 | (at1 << 2) | (atr << 4)), cse, fold NAME(op) },
|
||||
{ 0, (at0 << 4) | (at1 << 2) | atr, cse, fold NAME(op) },
|
||||
#define BUILTIN3(op, at0, at1, at2, atr, tr, t0, t1, t2, cse, fold) \
|
||||
{ 0, (at0 | (at1 << 2) | (at2 << 4) | (atr << 6)), cse, fold NAME(op) },
|
||||
{ 0, (at0 << 6) | (at1 << 4) | (at2 << 2) | atr, cse, fold NAME(op) },
|
||||
|
||||
static struct CallInfo builtins[] = {
|
||||
#include "builtins.tbl"
|
||||
@ -170,14 +183,18 @@ TraceRecorder::TraceRecorder(JSContext* cx, Fragmento* fragmento)
|
||||
lir = expr_filter = new (&gc) ExprFilter(lir);
|
||||
lir->ins0(LIR_trace);
|
||||
/* generate the entry map and stash it in the trace */
|
||||
LIns* data = lir_buf_writer->skip(nativeFrameSlots(entryFrame, entryRegs));
|
||||
buildTypeMap(entryFrame, entryRegs, (char*)(fragment->vmprivate = data->payload()));
|
||||
entryNativeFrameSlots = nativeFrameSlots(entryFrame, entryRegs);
|
||||
LIns* data = lir_buf_writer->skip(entryNativeFrameSlots);
|
||||
buildTypeMap(entryFrame, entryRegs,
|
||||
entryTypeMap = (char*)(fragment->vmprivate = data->payload()));
|
||||
fragment->param0 = lir->insImm8(LIR_param, Assembler::argRegs[0], 0);
|
||||
fragment->param1 = lir->insImm8(LIR_param, Assembler::argRegs[1], 0);
|
||||
fragment->sp = lir->insLoadi(fragment->param0, offsetof(InterpState, sp));
|
||||
cx_ins = lir->insLoadi(fragment->param0, offsetof(InterpState, f));
|
||||
#ifdef DEBUG
|
||||
lirbuf->names->addName(fragment->param0, "state");
|
||||
lirbuf->names->addName(fragment->sp, "sp");
|
||||
lirbuf->names->addName(cx_ins, "cx");
|
||||
#endif
|
||||
|
||||
JSStackFrame* fp = cx->fp;
|
||||
@ -278,12 +295,6 @@ static inline int gettag(jsval v)
|
||||
{
|
||||
if (JSVAL_IS_INT(v))
|
||||
return JSVAL_INT;
|
||||
if (JSVAL_IS_DOUBLE(v)) {
|
||||
jsdouble d = *JSVAL_TO_DOUBLE(v);
|
||||
jsint i;
|
||||
if (JSDOUBLE_IS_INT(d, i))
|
||||
return JSVAL_INT;
|
||||
}
|
||||
return JSVAL_TAG(v);
|
||||
}
|
||||
|
||||
@ -314,14 +325,7 @@ TraceRecorder::unbox_jsval(jsval v, int t, double* slot) const
|
||||
*(bool*)slot = JSVAL_TO_BOOLEAN(v);
|
||||
break;
|
||||
case JSVAL_INT:
|
||||
*(jsint*)slot = JSVAL_IS_INT(v);
|
||||
if (JSVAL_IS_INT(v))
|
||||
*(jsint*)slot = JSVAL_TO_INT(v);
|
||||
else {
|
||||
jsdouble d = *JSVAL_TO_DOUBLE(v);
|
||||
JS_ASSERT(JSDOUBLE_IS_INT(d, t));
|
||||
*(jsint*)slot = (jsint)d;
|
||||
}
|
||||
break;
|
||||
case JSVAL_DOUBLE:
|
||||
*(jsdouble*)slot = *JSVAL_TO_DOUBLE(v);
|
||||
@ -345,24 +349,23 @@ TraceRecorder::box_jsval(jsval* vp, int t, double* slot) const
|
||||
switch (t) {
|
||||
case JSVAL_BOOLEAN:
|
||||
*vp = BOOLEAN_TO_JSVAL(*(bool*)slot);
|
||||
return true;
|
||||
break;
|
||||
case JSVAL_INT:
|
||||
jsint i = *(jsint*)slot;
|
||||
if (INT_FITS_IN_JSVAL(i))
|
||||
JS_ASSERT(INT_FITS_IN_JSVAL(i));
|
||||
*vp = INT_TO_JSVAL(i);
|
||||
else
|
||||
return js_NewDoubleInRootedValue(cx, (double)i, vp);
|
||||
return true;
|
||||
break;
|
||||
case JSVAL_DOUBLE:
|
||||
return js_NewDoubleInRootedValue(cx, *slot, vp);
|
||||
case JSVAL_STRING:
|
||||
*vp = STRING_TO_JSVAL(*(JSString**)slot);
|
||||
return true;
|
||||
break;
|
||||
default:
|
||||
JS_ASSERT(t == JSVAL_OBJECT);
|
||||
*vp = OBJECT_TO_JSVAL(*(JSObject**)slot);
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Attempt to unbox the given JS frame into a native frame, checking
|
||||
@ -403,10 +406,11 @@ TraceRecorder::box(JSStackFrame* fp, JSFrameRegs& regs, char* m, double* native)
|
||||
|
||||
/* Emit load instructions onto the trace that read the initial stack state. */
|
||||
void
|
||||
TraceRecorder::readstack(void* p, char *prefix, int index)
|
||||
TraceRecorder::readstack(jsval* p, char *prefix, int index)
|
||||
{
|
||||
JS_ASSERT(onFrame(p));
|
||||
LIns *ins = lir->insLoadi(fragment->sp, nativeFrameOffset(p));
|
||||
LIns *ins = lir->insLoad(JSVAL_IS_DOUBLE(*p) ? LIR_ldq : LIR_ld,
|
||||
fragment->sp, nativeFrameOffset(p));
|
||||
tracker.set(p, ins);
|
||||
|
||||
#ifdef DEBUG
|
||||
@ -427,13 +431,14 @@ TraceRecorder::set(void* p, LIns* i)
|
||||
{
|
||||
tracker.set(p, i);
|
||||
if (onFrame(p))
|
||||
lir->insStorei(i, fragment->sp,
|
||||
nativeFrameOffset(p));
|
||||
lir->insStorei(i, fragment->sp, nativeFrameOffset(p));
|
||||
}
|
||||
|
||||
LIns*
|
||||
TraceRecorder::get(void* p)
|
||||
{
|
||||
if (p == cx)
|
||||
return cx_ins;
|
||||
return tracker.get(p);
|
||||
}
|
||||
|
||||
@ -541,7 +546,7 @@ TraceRecorder::snapshot()
|
||||
exit.calldepth = calldepth();
|
||||
exit.sp_adj = (markRegs.sp - entryRegs.sp + 1) * sizeof(double);
|
||||
exit.ip_adj = markRegs.pc - entryRegs.pc;
|
||||
exit.f_adj = (int)data->payload();
|
||||
exit.vmprivate = data->payload();
|
||||
return &exit;
|
||||
}
|
||||
|
||||
@ -606,19 +611,19 @@ TraceRecorder::closeLoop(Fragmento* fragmento)
|
||||
state.ip = (FOpcodep)entryRegs.pc;
|
||||
state.sp = native;
|
||||
state.rp = NULL;
|
||||
state.f = NULL;
|
||||
union { NIns *code; void* (FASTCALL *func)(InterpState*, Fragment*); } u;
|
||||
state.f = (void*)cx;
|
||||
union { NIns *code; GuardRecord* (FASTCALL *func)(InterpState*, Fragment*); } u;
|
||||
//printf("pc in: %p\n", cx->fp->regs->pc);
|
||||
//printf("sp in: %p\n", cx->fp->regs->sp);
|
||||
u.code = fragment->code();
|
||||
u.func(&state, NULL);
|
||||
GuardRecord* lr = u.func(&state, NULL);
|
||||
//printf("out: %d %d %d %d\n", *(int*)&native[0], *(int*)&native[1], *(int*)&native[2], *(int*)&native[3]);
|
||||
markRegs.sp = entryRegs.sp + (((double*)state.sp - native) - 1);
|
||||
markRegs.pc = (jsbytecode*)state.ip;
|
||||
//printf("base: %p sp out: %p\n", cx->fp->spbase, markRegs.sp);
|
||||
//printf("pc out: %p\n", state.ip);
|
||||
//printf("exit map: %p\n", (char*)state.f);
|
||||
box(cx->fp, markRegs, (char*)state.f, native);
|
||||
box(cx->fp, markRegs, (char*)lr->vmprivate, native);
|
||||
//printf("vm: var0=%ld var1=%ld stack0=%ld stack1=%ld\n", cx->fp->vars[0], cx->fp->vars[1], cx->fp->spbase[0], cx->fp->spbase[1]);
|
||||
//cx->fp->regs->pc = (jsbytecode*)state.ip;
|
||||
//cx->fp->regs->sp += (((double*)state.sp) - native);
|
||||
|
@ -42,6 +42,7 @@
|
||||
|
||||
#include "jsstddef.h"
|
||||
#include "jslock.h"
|
||||
#include "jsnum.h"
|
||||
|
||||
#include "nanojit/nanojit.h"
|
||||
|
||||
@ -73,6 +74,8 @@ public:
|
||||
class TraceRecorder {
|
||||
JSContext* cx;
|
||||
Tracker tracker;
|
||||
char* entryTypeMap;
|
||||
unsigned entryNativeFrameSlots;
|
||||
struct JSStackFrame* entryFrame;
|
||||
struct JSFrameRegs entryRegs;
|
||||
nanojit::Fragment* fragment;
|
||||
@ -82,6 +85,7 @@ class TraceRecorder {
|
||||
nanojit::LirWriter* verbose_filter;
|
||||
nanojit::LirWriter* cse_filter;
|
||||
nanojit::LirWriter* expr_filter;
|
||||
nanojit::LIns* cx_ins;
|
||||
struct JSFrameRegs markRegs;
|
||||
nanojit::SideExit exit;
|
||||
|
||||
@ -115,7 +119,7 @@ public:
|
||||
void set(void* p, nanojit::LIns* l);
|
||||
nanojit::LIns* get(void* p);
|
||||
|
||||
void readstack(void*, char *prefix = NULL, int index = 0);
|
||||
void readstack(jsval*, char *prefix = NULL, int index = 0);
|
||||
|
||||
void copy(void* a, void* v);
|
||||
void imm(jsint i, void* v);
|
||||
|
@ -226,11 +226,7 @@ call_ValueToECMAInt32(JSContext* cx, jsval& v, jsint& i)
|
||||
{
|
||||
jsint tmp;
|
||||
if (JSVAL_IS_DOUBLE(v)) {
|
||||
if (JSDOUBLE_IS_INT(v, tmp)) {
|
||||
/* its really an integer, just copy it */
|
||||
recorder(cx)->copy(&v, &i);
|
||||
} else
|
||||
recorder(cx)->call(F_DoubleToECMAInt32, cx, &v, &i);
|
||||
recorder(cx)->call(F_DoubleToECMAInt32, &v, &i);
|
||||
} else if (JSVAL_IS_VOID(v)) {
|
||||
recorder(cx)->imm(js_DoubleToECMAInt32(*cx->runtime->jsNaN), &i);
|
||||
} else if (JSVAL_IS_BOOLEAN(v)) {
|
||||
@ -248,15 +244,6 @@ call_ValueToECMAInt32(JSContext* cx, jsval& v, jsint& i)
|
||||
return interp_call_ValueToECMAInt32(cx, v, i);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
call_NewIntInRootedValue(JSContext* cx, jsint& i, jsval& v)
|
||||
{
|
||||
/* the trace is 32-bit clean and doesn't require a conversion, just
|
||||
track the copy here */
|
||||
recorder(cx)->copy(&i, &v);
|
||||
return interp_call_NewIntInRootedValue(cx, i, v);
|
||||
}
|
||||
|
||||
static inline void
|
||||
prim_int_to_uint(JSContext* cx, jsint& i, uint32& u)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user