diff --git a/js/src/methodjit/Compiler.cpp b/js/src/methodjit/Compiler.cpp index 9259e9d18be..ed20076c0db 100644 --- a/js/src/methodjit/Compiler.cpp +++ b/js/src/methodjit/Compiler.cpp @@ -596,6 +596,13 @@ mjit::Compiler::generateMethod() jsop_getprop_slow(); END_CASE(JSOP_GETPROP) + BEGIN_CASE(JSOP_LENGTH) + prepareStubCall(); + stubCall(stubs::Length, Uses(1), Defs(1)); + frame.pop(); + frame.pushSynced(); + END_CASE(JSOP_LENGTH) + BEGIN_CASE(JSOP_GETELEM) prepareStubCall(); stubCall(stubs::GetElem, Uses(2), Defs(1)); diff --git a/js/src/methodjit/StubCalls.cpp b/js/src/methodjit/StubCalls.cpp index c3448dfa2c6..a6613748e05 100644 --- a/js/src/methodjit/StubCalls.cpp +++ b/js/src/methodjit/StubCalls.cpp @@ -2163,6 +2163,33 @@ stubs::CallProp(VMFrame &f, JSAtom *atom) #endif /* JS_HAS_NO_SUCH_METHOD */ } +void JS_FASTCALL +stubs::Length(VMFrame &f) +{ + JSFrameRegs ®s = f.regs; + Value *vp = ®s.sp[-1]; + + if (vp->isString()) { + vp->setInt32(vp->asString()->length()); + return; + } else if (vp->isObject()) { + JSObject *obj = &vp->asObject(); + if (obj->isArray()) { + jsuint length = obj->getArrayLength(); + regs.sp[-1].setDouble(length); + return; + } else if (obj->isArguments() && !obj->isArgsLengthOverridden()) { + uint32 length = obj->getArgsLength(); + JS_ASSERT(length < INT32_MAX); + regs.sp[-1].setInt32(int32_t(length)); + return; + } + } + + if (!InlineGetProp(f)) + THROW(); +} + void JS_FASTCALL stubs::Iter(VMFrame &f, uint32 flags) { diff --git a/js/src/methodjit/StubCalls.h b/js/src/methodjit/StubCalls.h index 6367803cf35..6d78e0a4cdb 100644 --- a/js/src/methodjit/StubCalls.h +++ b/js/src/methodjit/StubCalls.h @@ -67,6 +67,7 @@ void JS_FASTCALL Name(VMFrame &f, uint32 index); void JS_FASTCALL GetProp(VMFrame &f); void JS_FASTCALL GetElem(VMFrame &f); void JS_FASTCALL SetElem(VMFrame &f); +void JS_FASTCALL Length(VMFrame &f); void JS_FASTCALL CallName(VMFrame &f, uint32 index); void JS_FASTCALL GetUpvar(VMFrame &f, uint32 index);