mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Record JSOP_IN (452563, r=gal).
This commit is contained in:
parent
d3cb344df7
commit
5d132dba83
@ -77,6 +77,7 @@ BUILTIN2(CloseIterator, LO, LO, LO, bool, JSContext*, jsval, 0,
|
||||
BUILTIN2(CallTree, LO, LO, P, nanojit::GuardRecord*, avmplus::InterpState*, nanojit::Fragment*, 0, 0)
|
||||
BUILTIN2(FastNewObject, LO, LO, P, JSObject*, JSContext*, JSObject*, 0, 0)
|
||||
BUILTIN3(AddProperty, LO, LO, LO, LO, bool, JSContext*, JSObject*, JSScopeProperty*, 0, 0)
|
||||
BUILTIN3(HasNamedProperty, LO, LO, LO, LO, bool, JSContext*, JSObject*, JSString*, 0, 0)
|
||||
BUILTIN3(CallGetter, LO, LO, LO, P, jsval, JSContext*, JSObject*, JSScopeProperty*, 0, 0)
|
||||
BUILTIN2(TypeOfObject, LO, LO, P, JSString*, JSContext*, JSObject*, 1, 1)
|
||||
BUILTIN2(TypeOfBoolean, LO, LO, P, JSString*, JSContext*, jsint, 1, 1)
|
||||
|
@ -537,6 +537,22 @@ js_AddProperty(JSContext* cx, JSObject* obj, JSScopeProperty* sprop)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FASTCALL
|
||||
js_HasNamedProperty(JSContext* cx, JSObject* obj, JSString* idstr)
|
||||
{
|
||||
jsid id;
|
||||
if (!js_ValueToStringId(cx, STRING_TO_JSVAL(idstr), &id))
|
||||
return JSVAL_ERROR_COOKIE;
|
||||
|
||||
JSObject* obj2;
|
||||
JSProperty* prop;
|
||||
if (!OBJ_LOOKUP_PROPERTY(cx, obj, id, &obj2, &prop))
|
||||
return JSVAL_TO_BOOLEAN(JSVAL_VOID);
|
||||
if (prop)
|
||||
OBJ_DROP_PROPERTY(cx, obj2, prop);
|
||||
return prop != NULL;
|
||||
}
|
||||
|
||||
jsval FASTCALL
|
||||
js_CallGetter(JSContext* cx, JSObject* obj, JSScopeProperty* sprop)
|
||||
{
|
||||
|
@ -3130,6 +3130,23 @@ js_Interpret(JSContext *cx)
|
||||
} \
|
||||
JS_END_MACRO
|
||||
|
||||
#define TRY_BRANCH_AFTER_COND(cond,spdec) \
|
||||
JS_BEGIN_MACRO \
|
||||
uintN diff_; \
|
||||
JS_ASSERT(js_CodeSpec[op].length == 1); \
|
||||
diff_ = (uintN) regs.pc[1] - (uintN) JSOP_IFEQ; \
|
||||
if (diff_ <= 1) { \
|
||||
regs.sp -= spdec; \
|
||||
if (cond == (diff_ != 0)) { \
|
||||
++regs.pc; \
|
||||
len = GET_JUMP_OFFSET(regs.pc); \
|
||||
BRANCH(len); \
|
||||
} \
|
||||
len = 1 + JSOP_IFEQ_LENGTH; \
|
||||
DO_NEXT_OP(len); \
|
||||
} \
|
||||
JS_END_MACRO
|
||||
|
||||
BEGIN_CASE(JSOP_IN)
|
||||
rval = FETCH_OPND(-1);
|
||||
if (JSVAL_IS_PRIMITIVE(rval)) {
|
||||
@ -3140,10 +3157,12 @@ js_Interpret(JSContext *cx)
|
||||
FETCH_ELEMENT_ID(obj, -2, id);
|
||||
if (!OBJ_LOOKUP_PROPERTY(cx, obj, id, &obj2, &prop))
|
||||
goto error;
|
||||
regs.sp--;
|
||||
STORE_OPND(-1, BOOLEAN_TO_JSVAL(prop != NULL));
|
||||
cond = prop != NULL;
|
||||
if (prop)
|
||||
OBJ_DROP_PROPERTY(cx, obj2, prop);
|
||||
TRY_BRANCH_AFTER_COND(cond, 2);
|
||||
regs.sp--;
|
||||
STORE_OPND(-1, BOOLEAN_TO_JSVAL(cond));
|
||||
END_CASE(JSOP_IN)
|
||||
|
||||
BEGIN_CASE(JSOP_ITER)
|
||||
@ -3487,23 +3506,6 @@ js_Interpret(JSContext *cx)
|
||||
BITWISE_OP(&);
|
||||
END_CASE(JSOP_BITAND)
|
||||
|
||||
#define TRY_BRANCH_AFTER_COND(cond,spdec) \
|
||||
JS_BEGIN_MACRO \
|
||||
uintN diff_; \
|
||||
JS_ASSERT(js_CodeSpec[op].length == 1); \
|
||||
diff_ = (uintN) regs.pc[1] - (uintN) JSOP_IFEQ; \
|
||||
if (diff_ <= 1) { \
|
||||
regs.sp -= spdec; \
|
||||
if (cond == (diff_ != 0)) { \
|
||||
++regs.pc; \
|
||||
len = GET_JUMP_OFFSET(regs.pc); \
|
||||
BRANCH(len); \
|
||||
} \
|
||||
len = 1 + JSOP_IFEQ_LENGTH; \
|
||||
DO_NEXT_OP(len); \
|
||||
} \
|
||||
JS_END_MACRO
|
||||
|
||||
#define RELATIONAL_OP(OP) \
|
||||
JS_BEGIN_MACRO \
|
||||
rval = FETCH_OPND(-1); \
|
||||
|
@ -2538,7 +2538,9 @@ TraceRecorder::ifop()
|
||||
jsdouble d = asNumber(v);
|
||||
jsdpun u;
|
||||
u.d = 0;
|
||||
guard((d == 0 || JSDOUBLE_IS_NaN(d)), lir->ins2(LIR_feq, get(&v), lir->insImmq(u.u64)), BRANCH_EXIT);
|
||||
guard(d == 0 || JSDOUBLE_IS_NaN(d),
|
||||
lir->ins2(LIR_feq, get(&v), lir->insImmq(u.u64)),
|
||||
BRANCH_EXIT);
|
||||
} else if (JSVAL_IS_STRING(v)) {
|
||||
guard(JSSTRING_LENGTH(JSVAL_TO_STRING(v)) == 0,
|
||||
lir->ins_eq0(lir->ins2(LIR_piand,
|
||||
@ -3932,7 +3934,7 @@ TraceRecorder::record_JSOP_SETPROP()
|
||||
JSObject* obj = JSVAL_TO_OBJECT(l);
|
||||
|
||||
if (obj->map->ops->setProperty != js_SetProperty)
|
||||
ABORT_TRACE("non-native setProperty");
|
||||
ABORT_TRACE("non-native JSObjectOps::setProperty");
|
||||
|
||||
LIns* obj_ins = get(&l);
|
||||
|
||||
@ -5032,7 +5034,82 @@ TraceRecorder::record_JSOP_THROW()
|
||||
bool
|
||||
TraceRecorder::record_JSOP_IN()
|
||||
{
|
||||
return false;
|
||||
jsval& rval = stackval(-1);
|
||||
if (JSVAL_IS_PRIMITIVE(rval))
|
||||
ABORT_TRACE("JSOP_IN on non-object right operand");
|
||||
|
||||
jsval& lval = stackval(-2);
|
||||
if (!JSVAL_IS_PRIMITIVE(lval))
|
||||
ABORT_TRACE("JSOP_IN on E4X QName left operand");
|
||||
|
||||
jsid id;
|
||||
if (JSVAL_IS_INT(lval)) {
|
||||
id = INT_JSVAL_TO_JSID(lval);
|
||||
} else {
|
||||
if (!js_ValueToStringId(cx, lval, &id))
|
||||
ABORT_TRACE("OOM under js_ValueToStringId in JSOP_IN");
|
||||
lval = ID_TO_VALUE(id);
|
||||
}
|
||||
|
||||
// Expect what we see at trace recording time (hit or miss) to be the same
|
||||
// when executing the trace. Use a builtin helper for named properties, as
|
||||
// forInLoop does. First, handle indexes in dense arrays as a special case.
|
||||
JSObject* obj = JSVAL_TO_OBJECT(rval);
|
||||
LIns* obj_ins = get(&rval);
|
||||
|
||||
bool cond;
|
||||
LIns* x;
|
||||
do {
|
||||
if (guardDenseArray(obj, obj_ins)) {
|
||||
if (JSVAL_IS_INT(lval)) {
|
||||
jsint idx = JSVAL_TO_INT(lval);
|
||||
LIns* idx_ins = f2i(get(&lval));
|
||||
LIns* dslots_ins = lir->insLoad(LIR_ldp, obj_ins, offsetof(JSObject, dslots));
|
||||
if (!guardDenseArrayIndex(obj, idx, obj_ins, dslots_ins, idx_ins))
|
||||
ABORT_TRACE("dense array index out of bounds");
|
||||
|
||||
cond = obj->dslots[idx] != JSVAL_HOLE;
|
||||
x = lir->ins_eq0(lir->ins2(LIR_eq,
|
||||
lir->insLoad(LIR_ldp, dslots_ins, idx * sizeof(jsval)),
|
||||
INS_CONST(JSVAL_HOLE)));
|
||||
break;
|
||||
}
|
||||
|
||||
// Not an index id, but a dense array -- go up to the proto. */
|
||||
obj = STOBJ_GET_PROTO(obj);
|
||||
obj_ins = stobj_get_fslot(obj_ins, JSSLOT_PROTO);
|
||||
} else {
|
||||
if (JSVAL_IS_INT(id))
|
||||
ABORT_TRACE("INT in OBJ where OBJ is not a dense array");
|
||||
}
|
||||
|
||||
JSObject* obj2;
|
||||
JSProperty* prop;
|
||||
if (!OBJ_LOOKUP_PROPERTY(cx, obj, id, &obj2, &prop))
|
||||
ABORT_TRACE("OBJ_LOOKUP_PROPERTY failed in JSOP_IN");
|
||||
|
||||
cond = prop != NULL;
|
||||
if (prop)
|
||||
OBJ_DROP_PROPERTY(cx, obj2, prop);
|
||||
|
||||
LIns* args[] = { get(&lval), obj_ins, cx_ins };
|
||||
x = lir->insCall(F_HasNamedProperty, args);
|
||||
guard(false, lir->ins2i(LIR_eq, x, 2), OOM_EXIT);
|
||||
x = lir->ins2i(LIR_eq, x, 1);
|
||||
} while (0);
|
||||
|
||||
/* The interpreter fuses comparisons and the following branch,
|
||||
so we have to do that here as well. */
|
||||
if (cx->fp->regs->pc[1] == JSOP_IFEQ || cx->fp->regs->pc[1] == JSOP_IFNE)
|
||||
guard(cond, x, BRANCH_EXIT);
|
||||
|
||||
/* We update the stack after the guard. This is safe since
|
||||
the guard bails out at the comparison and the interpreter
|
||||
will this re-execute the comparison. This way the
|
||||
value of the condition doesn't have to be calculated and
|
||||
saved on the stack in most cases. */
|
||||
set(&lval, x);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -849,6 +849,32 @@ function forVarInWith() {
|
||||
forVarInWith.expected = "pqrst";
|
||||
test(forVarInWith);
|
||||
|
||||
function inObjectTest() {
|
||||
var o = {p: 1, q: 2, r: 3, s: 4, t: 5};
|
||||
var r = 0;
|
||||
for (var i in o) {
|
||||
if (!(i in o))
|
||||
break;
|
||||
if ((i + i) in o)
|
||||
break;
|
||||
++r;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
inObjectTest.expected = 5;
|
||||
test(inObjectTest);
|
||||
|
||||
function inArrayTest() {
|
||||
var a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
|
||||
for (var i = 0; i < a.length; i++) {
|
||||
if (!(i in a))
|
||||
break;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
inArrayTest.expected = 10;
|
||||
test(inArrayTest);
|
||||
|
||||
function innerLoopIntOuterDouble() {
|
||||
var n = 10000, i=0, j=0, count=0, limit=0;
|
||||
for (i = 1; i <= n; ++i) {
|
||||
|
Loading…
Reference in New Issue
Block a user