mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-14 15:37:55 +00:00
Move GETELEM/SETELEM operations to jsinterpinlines (bug 718683, r=pierron)
This commit is contained in:
parent
c34267eb99
commit
796259b65c
@ -1108,6 +1108,7 @@ class TypeScript
|
||||
*/
|
||||
static inline void Monitor(JSContext *cx, JSScript *script, jsbytecode *pc,
|
||||
const js::Value &val);
|
||||
static inline void Monitor(JSContext *cx, const js::Value &rval);
|
||||
|
||||
/* Monitor an assignment at a SETELEM on a non-integer identifier. */
|
||||
static inline void MonitorAssign(JSContext *cx, JSScript *script, jsbytecode *pc,
|
||||
|
@ -629,6 +629,15 @@ TypeScript::MonitorUnknown(JSContext *cx)
|
||||
MonitorUnknown(cx, script, pc);
|
||||
}
|
||||
|
||||
/* static */ inline void
|
||||
TypeScript::Monitor(JSContext *cx, const js::Value &rval)
|
||||
{
|
||||
JSScript *script;
|
||||
jsbytecode *pc;
|
||||
GetPcScript(cx, &script, &pc);
|
||||
Monitor(cx, script, pc, rval);
|
||||
}
|
||||
|
||||
/* static */ inline void
|
||||
TypeScript::MonitorAssign(JSContext *cx, JSScript *script, jsbytecode *pc,
|
||||
JSObject *obj, jsid id, const js::Value &rval)
|
||||
|
@ -2721,78 +2721,8 @@ BEGIN_CASE(JSOP_GETELEM)
|
||||
{
|
||||
Value &lref = regs.sp[-2];
|
||||
Value &rref = regs.sp[-1];
|
||||
Value &rval = regs.sp[-2];
|
||||
if (lref.isString() && rref.isInt32()) {
|
||||
JSString *str = lref.toString();
|
||||
int32_t i = rref.toInt32();
|
||||
if (size_t(i) < str->length()) {
|
||||
str = cx->runtime->staticStrings.getUnitStringForElement(cx, str, size_t(i));
|
||||
if (!str)
|
||||
goto error;
|
||||
rval.setString(str);
|
||||
TypeScript::Monitor(cx, script, regs.pc, rval);
|
||||
regs.sp--;
|
||||
len = JSOP_GETELEM_LENGTH;
|
||||
DO_NEXT_OP(len);
|
||||
}
|
||||
}
|
||||
|
||||
if (lref.isMagic(JS_LAZY_ARGUMENTS)) {
|
||||
if (rref.isInt32() && size_t(rref.toInt32()) < regs.fp()->numActualArgs()) {
|
||||
rval = regs.fp()->canonicalActualArg(rref.toInt32());
|
||||
TypeScript::Monitor(cx, script, regs.pc, rval);
|
||||
regs.sp--;
|
||||
len = JSOP_GETELEM_LENGTH;
|
||||
DO_NEXT_OP(len);
|
||||
}
|
||||
MarkArgumentsCreated(cx, script);
|
||||
JS_ASSERT(!lref.isMagic(JS_LAZY_ARGUMENTS));
|
||||
}
|
||||
|
||||
JSObject *obj;
|
||||
VALUE_TO_OBJECT(cx, &lref, obj);
|
||||
|
||||
uint32_t index;
|
||||
if (IsDefinitelyIndex(rref, &index)) {
|
||||
if (obj->isDenseArray()) {
|
||||
if (index < obj->getDenseArrayInitializedLength()) {
|
||||
rval = obj->getDenseArrayElement(index);
|
||||
if (!rval.isMagic())
|
||||
goto end_getelem;
|
||||
}
|
||||
} else if (obj->isArguments()) {
|
||||
if (obj->asArguments().getElement(index, &rval))
|
||||
goto end_getelem;
|
||||
}
|
||||
|
||||
if (!obj->getElement(cx, index, &rval))
|
||||
goto error;
|
||||
} else {
|
||||
if (script->hasAnalysis())
|
||||
script->analysis()->getCode(regs.pc).getStringElement = true;
|
||||
|
||||
SpecialId special;
|
||||
if (ValueIsSpecial(obj, &rref, &special, cx)) {
|
||||
if (!obj->getSpecial(cx, obj, special, &rval))
|
||||
goto error;
|
||||
} else {
|
||||
JSAtom *name;
|
||||
if (!js_ValueToAtom(cx, rref, &name))
|
||||
goto error;
|
||||
|
||||
if (name->isIndex(&index)) {
|
||||
if (!obj->getElement(cx, index, &rval))
|
||||
goto error;
|
||||
} else {
|
||||
if (!obj->getProperty(cx, name->asPropertyName(), &rval))
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
end_getelem:
|
||||
assertSameCompartment(cx, rval);
|
||||
TypeScript::Monitor(cx, script, regs.pc, rval);
|
||||
if (!GetElementOperation(cx, lref, rref, ®s.sp[-2]))
|
||||
goto error;
|
||||
regs.sp--;
|
||||
}
|
||||
END_CASE(JSOP_GETELEM)
|
||||
@ -2832,32 +2762,10 @@ BEGIN_CASE(JSOP_SETELEM)
|
||||
FETCH_OBJECT(cx, -3, obj);
|
||||
jsid id;
|
||||
FETCH_ELEMENT_ID(obj, -2, id);
|
||||
Value rval;
|
||||
TypeScript::MonitorAssign(cx, script, regs.pc, obj, id, regs.sp[-1]);
|
||||
do {
|
||||
if (obj->isDenseArray() && JSID_IS_INT(id)) {
|
||||
jsuint length = obj->getDenseArrayInitializedLength();
|
||||
jsint i = JSID_TO_INT(id);
|
||||
if ((jsuint)i < length) {
|
||||
if (obj->getDenseArrayElement(i).isMagic(JS_ARRAY_HOLE)) {
|
||||
if (js_PrototypeHasIndexedProperties(cx, obj))
|
||||
break;
|
||||
if ((jsuint)i >= obj->getArrayLength())
|
||||
obj->setArrayLength(cx, i + 1);
|
||||
}
|
||||
obj->setDenseArrayElementWithType(cx, i, regs.sp[-1]);
|
||||
goto end_setelem;
|
||||
} else {
|
||||
if (script->hasAnalysis())
|
||||
script->analysis()->getCode(regs.pc).arrayWriteHole = true;
|
||||
}
|
||||
}
|
||||
} while (0);
|
||||
rval = regs.sp[-1];
|
||||
if (!obj->setGeneric(cx, id, &rval, script->strictModeCode))
|
||||
Value &value = regs.sp[-1];
|
||||
if (!SetObjectElementOperation(cx, obj, id, value))
|
||||
goto error;
|
||||
end_setelem:
|
||||
regs.sp[-3] = regs.sp[-1];
|
||||
regs.sp[-3] = value;
|
||||
regs.sp -= 2;
|
||||
}
|
||||
END_CASE(JSOP_SETELEM)
|
||||
|
@ -645,6 +645,133 @@ ModOperation(JSContext *cx, const Value &lhs, const Value &rhs, Value *res)
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
FetchElementId(JSContext *cx, JSObject *obj, const Value &idval, jsid &id, Value *vp)
|
||||
{
|
||||
int32_t i_;
|
||||
if (ValueFitsInInt32(idval, &i_) && INT_FITS_IN_JSID(i_)) {
|
||||
id = INT_TO_JSID(i_);
|
||||
return true;
|
||||
}
|
||||
return !!js_InternNonIntElementId(cx, obj, idval, &id, vp);
|
||||
}
|
||||
|
||||
static JS_ALWAYS_INLINE bool
|
||||
GetObjectElementOperation(JSContext *cx, JSObject *obj, const Value &rref, Value *res)
|
||||
{
|
||||
JSScript *script;
|
||||
jsbytecode *pc;
|
||||
types::TypeScript::GetPcScript(cx, &script, &pc);
|
||||
|
||||
uint32_t index;
|
||||
if (IsDefinitelyIndex(rref, &index)) {
|
||||
do {
|
||||
if (obj->isDenseArray()) {
|
||||
if (index < obj->getDenseArrayInitializedLength()) {
|
||||
*res = obj->getDenseArrayElement(index);
|
||||
if (!res->isMagic())
|
||||
break;
|
||||
}
|
||||
} else if (obj->isArguments()) {
|
||||
if (obj->asArguments().getElement(index, res))
|
||||
break;
|
||||
}
|
||||
if (!obj->getElement(cx, index, res))
|
||||
return false;
|
||||
} while(0);
|
||||
} else {
|
||||
if (script->hasAnalysis())
|
||||
script->analysis()->getCode(pc).getStringElement = true;
|
||||
|
||||
SpecialId special;
|
||||
*res = rref;
|
||||
if (ValueIsSpecial(obj, res, &special, cx)) {
|
||||
if (!obj->getSpecial(cx, obj, special, res))
|
||||
return false;
|
||||
} else {
|
||||
JSAtom *name;
|
||||
if (!js_ValueToAtom(cx, *res, &name))
|
||||
return false;
|
||||
|
||||
if (name->isIndex(&index)) {
|
||||
if (!obj->getElement(cx, index, res))
|
||||
return false;
|
||||
} else {
|
||||
if (!obj->getProperty(cx, name->asPropertyName(), res))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assertSameCompartment(cx, *res);
|
||||
types::TypeScript::Monitor(cx, script, pc, *res);
|
||||
return true;
|
||||
}
|
||||
|
||||
static JS_ALWAYS_INLINE bool
|
||||
GetElementOperation(JSContext *cx, const Value &lref, const Value &rref, Value *res)
|
||||
{
|
||||
if (lref.isString() && rref.isInt32()) {
|
||||
JSString *str = lref.toString();
|
||||
int32_t i = rref.toInt32();
|
||||
if (size_t(i) < str->length()) {
|
||||
str = cx->runtime->staticStrings.getUnitStringForElement(cx, str, size_t(i));
|
||||
if (!str)
|
||||
return false;
|
||||
res->setString(str);
|
||||
types::TypeScript::Monitor(cx, *res);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (lref.isMagic(JS_LAZY_ARGUMENTS)) {
|
||||
if (rref.isInt32() && size_t(rref.toInt32()) < cx->regs().fp()->numActualArgs()) {
|
||||
*res = cx->regs().fp()->canonicalActualArg(rref.toInt32());
|
||||
types::TypeScript::Monitor(cx, *res);
|
||||
return true;
|
||||
}
|
||||
types::MarkArgumentsCreated(cx, cx->fp()->script());
|
||||
JS_ASSERT(!lref.isMagic(JS_LAZY_ARGUMENTS));
|
||||
}
|
||||
|
||||
JSObject *obj = ValueToObject(cx, lref);
|
||||
if (!obj)
|
||||
return false;
|
||||
return GetObjectElementOperation(cx, obj, rref, res);
|
||||
}
|
||||
|
||||
static JS_ALWAYS_INLINE bool
|
||||
SetObjectElementOperation(JSContext *cx, JSObject *obj, jsid id, const Value &value)
|
||||
{
|
||||
JSScript *script;
|
||||
jsbytecode *pc;
|
||||
types::TypeScript::GetPcScript(cx, &script, &pc);
|
||||
types::TypeScript::MonitorAssign(cx, script, pc, obj, id, value);
|
||||
|
||||
do {
|
||||
if (obj->isDenseArray() && JSID_IS_INT(id)) {
|
||||
jsuint length = obj->getDenseArrayInitializedLength();
|
||||
jsint i = JSID_TO_INT(id);
|
||||
if ((jsuint)i < length) {
|
||||
if (obj->getDenseArrayElement(i).isMagic(JS_ARRAY_HOLE)) {
|
||||
if (js_PrototypeHasIndexedProperties(cx, obj))
|
||||
break;
|
||||
if ((jsuint)i >= obj->getArrayLength())
|
||||
obj->setArrayLength(cx, i + 1);
|
||||
}
|
||||
obj->setDenseArrayElementWithType(cx, i, value);
|
||||
return true;
|
||||
} else {
|
||||
if (script->hasAnalysis())
|
||||
script->analysis()->getCode(pc).arrayWriteHole = true;
|
||||
}
|
||||
}
|
||||
} while (0);
|
||||
|
||||
Value tmp = value;
|
||||
return obj->setGeneric(cx, id, &tmp, script->strictModeCode);
|
||||
}
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
#endif /* jsinterpinlines_h__ */
|
||||
|
@ -210,17 +210,6 @@ stubs::GetElem(VMFrame &f)
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline bool
|
||||
FetchElementId(VMFrame &f, JSObject *obj, const Value &idval, jsid &id, Value *vp)
|
||||
{
|
||||
int32_t i_;
|
||||
if (ValueFitsInInt32(idval, &i_) && INT_FITS_IN_JSID(i_)) {
|
||||
id = INT_TO_JSID(i_);
|
||||
return true;
|
||||
}
|
||||
return !!js_InternNonIntElementId(f.cx, obj, idval, &id, vp);
|
||||
}
|
||||
|
||||
template<JSBool strict>
|
||||
void JS_FASTCALL
|
||||
stubs::SetElem(VMFrame &f)
|
||||
@ -239,7 +228,7 @@ stubs::SetElem(VMFrame &f)
|
||||
if (!obj)
|
||||
THROW();
|
||||
|
||||
if (!FetchElementId(f, obj, idval, id, ®s.sp[-2]))
|
||||
if (!FetchElementId(f.cx, obj, idval, id, ®s.sp[-2]))
|
||||
THROW();
|
||||
|
||||
TypeScript::MonitorAssign(cx, f.script(), f.pc(), obj, id, rval);
|
||||
@ -287,7 +276,7 @@ stubs::ToId(VMFrame &f)
|
||||
THROW();
|
||||
|
||||
jsid id;
|
||||
if (!FetchElementId(f, obj, idval, id, &idval))
|
||||
if (!FetchElementId(f.cx, obj, idval, id, &idval))
|
||||
THROW();
|
||||
|
||||
if (!idval.isInt32())
|
||||
@ -1032,7 +1021,7 @@ stubs::InitElem(VMFrame &f, uint32_t last)
|
||||
/* Fetch id now that we have obj. */
|
||||
jsid id;
|
||||
const Value &idval = regs.sp[-2];
|
||||
if (!FetchElementId(f, obj, idval, id, ®s.sp[-2]))
|
||||
if (!FetchElementId(f.cx, obj, idval, id, ®s.sp[-2]))
|
||||
THROW();
|
||||
|
||||
/*
|
||||
@ -1744,7 +1733,7 @@ stubs::In(VMFrame &f)
|
||||
|
||||
JSObject *obj = &rref.toObject();
|
||||
jsid id;
|
||||
if (!FetchElementId(f, obj, f.regs.sp[-2], id, &f.regs.sp[-2]))
|
||||
if (!FetchElementId(f.cx, obj, f.regs.sp[-2], id, &f.regs.sp[-2]))
|
||||
THROWV(JS_FALSE);
|
||||
|
||||
JSObject *obj2;
|
||||
|
Loading…
Reference in New Issue
Block a user