[JAEGER] Added JSOP_INITELEM.

This commit is contained in:
David Anderson 2010-06-05 16:45:48 -07:00
parent 8bb2f61b44
commit 50f045e244
3 changed files with 68 additions and 6 deletions

View File

@ -660,6 +660,16 @@ mjit::Compiler::generateMethod()
stubCall(stubs::EndInit, Uses(0), Defs(0));
END_CASE(JSOP_ENDINIT)
BEGIN_CASE(JSOP_INITELEM)
{
JSOp next = JSOp(PC[JSOP_INITELEM_LENGTH]);
prepareStubCall();
masm.move(Imm32(next == JSOP_ENDINIT ? 1 : 0), Registers::ArgReg1);
stubCall(stubs::InitElem, Uses(2), Defs(0));
frame.popn(2);
}
END_CASE(JSOP_INITELEM)
BEGIN_CASE(JSOP_BINDNAME)
jsop_bindname(fullAtomIndex(PC));
END_CASE(JSOP_BINDNAME)

View File

@ -703,6 +703,17 @@ stubs::GetElem(VMFrame &f)
f.regs.sp[-2] = *copyFrom;
}
static inline bool
FetchElementId(VMFrame &f, JSObject *obj, const Value &idval, jsid &id, Value *vp)
{
int32_t i_;
if (ValueFitsInInt32(idval, &i_)) {
id = INT_TO_JSID(i_);
return true;
}
return !!js_InternNonIntElementId(f.cx, obj, idval, &id, vp);
}
void JS_FASTCALL
stubs::SetElem(VMFrame &f)
{
@ -720,13 +731,8 @@ stubs::SetElem(VMFrame &f)
if (!obj)
THROW();
/* jsops.cpp:FETCH_ELEMENT_ID */
int32_t i_;
if (ValueFitsInInt32(idval, &i_)) {
id = INT_TO_JSID(i_);
} else if (!js_InternNonIntElementId(cx, obj, idval, &id, &regs.sp[-2])) {
if (!FetchElementId(f, obj, idval, id, &regs.sp[-2]))
THROW();
}
if (obj->isDenseArray() && JSID_IS_INT(id)) {
jsuint length = obj->getDenseArrayCapacity();
@ -1716,3 +1722,48 @@ stubs::EndInit(VMFrame &f)
f.cx->weakRoots.finalizableNewborns[FINALIZE_OBJECT] = &lref.asObject();
}
void JS_FASTCALL
stubs::InitElem(VMFrame &f, uint32 last)
{
JSContext *cx = f.cx;
JSFrameRegs &regs = f.regs;
/* Pop the element's value into rval. */
JS_ASSERT(regs.sp - f.fp->base() >= 3);
const Value &rref = regs.sp[-1];
/* Find the object being initialized at top of stack. */
const Value &lref = regs.sp[-3];
JS_ASSERT(lref.isObject());
JSObject *obj = &lref.asObject();
/* Fetch id now that we have obj. */
jsid id;
const Value &idval = regs.sp[-2];
if (!FetchElementId(f, obj, idval, id, &regs.sp[-2]))
THROW();
/*
* Check for property redeclaration strict warning (we may be in an object
* initialiser, not an array initialiser).
*/
if (!CheckRedeclaration(cx, obj, id, JSPROP_INITIALIZER, NULL, NULL))
THROW();
/*
* If rref is a hole, do not call JSObject::defineProperty. In this case,
* obj must be an array, so if the current op is the last element
* initialiser, set the array length to one greater than id.
*/
if (rref.isMagic(JS_ARRAY_HOLE)) {
JS_ASSERT(obj->isArray());
JS_ASSERT(JSID_IS_INT(id));
JS_ASSERT(jsuint(JSID_TO_INT(id)) < JS_ARGS_LENGTH_MAX);
if (last && !js_SetLengthProperty(cx, obj, (jsuint) (JSID_TO_INT(id) + 1)))
THROW();
} else {
if (!obj->defineProperty(cx, id, rref, NULL, NULL, JSPROP_ENUMERATE))
THROW();
}
}

View File

@ -51,6 +51,7 @@ void JS_FASTCALL This(VMFrame &f);
JSObject * JS_FASTCALL NewInitArray(VMFrame &f);
JSObject * JS_FASTCALL NewInitObject(VMFrame &f, uint32 empty);
JSObject * JS_FASTCALL NewArray(VMFrame &f, uint32 len);
void JS_FASTCALL InitElem(VMFrame &f, uint32 last);
void JS_FASTCALL EndInit(VMFrame &f);
void * JS_FASTCALL Call(VMFrame &f, uint32 argc);