author | Jon Coppeard <jcoppeard@mozilla.com> |
Wed, 24 Apr 2013 11:34:38 +0100 | |
changeset 129737 | 781a47680e34f39facde9a397d7d2c2e4765c6ac |
parent 129736 | c307cb8bffec6ff6389cc64cfef648edb33617ec |
child 129738 | 4bba65656e46e524aa4eb9ff27a95b86af65a999 |
push id | 26974 |
push user | jcoppeard@mozilla.com |
push date | Wed, 24 Apr 2013 10:37:18 +0000 |
treeherder | mozilla-inbound@781a47680e34 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | djvj |
bugs | 864002 |
milestone | 23.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/js/src/vm/ArgumentsObject.cpp +++ b/js/src/vm/ArgumentsObject.cpp @@ -19,22 +19,25 @@ #include "vm/ArgumentsObject-inl.h" #include "ion/IonFrames.h" using namespace js; using namespace js::gc; static void -CopyStackFrameArguments(const AbstractFramePtr frame, HeapValue *dst) +CopyStackFrameArguments(const AbstractFramePtr frame, HeapValue *dst, unsigned totalArgs) { JS_ASSERT_IF(frame.isStackFrame(), !frame.asStackFrame()->runningInIon()); unsigned numActuals = frame.numActualArgs(); unsigned numFormals = frame.callee()->nargs; + JS_ASSERT(numActuals <= totalArgs); + JS_ASSERT(numFormals <= totalArgs); + JS_ASSERT(Max(numActuals, numFormals) == totalArgs); /* Copy formal arguments. */ Value *src = frame.formals(); Value *end = src + numFormals; while (src != end) (dst++)->init(*src++); /* Copy actual argument which are not contignous. */ @@ -77,18 +80,18 @@ ArgumentsObject::MaybeForwardToCallObjec struct CopyFrameArgs { AbstractFramePtr frame_; CopyFrameArgs(AbstractFramePtr frame) : frame_(frame) { } - void copyArgs(JSContext *, HeapValue *dst) const { - CopyStackFrameArguments(frame_, dst); + void copyArgs(JSContext *, HeapValue *dst, unsigned totalArgs) const { + CopyStackFrameArguments(frame_, dst, totalArgs); } /* * If a call object exists and the arguments object aliases formals, the * call object is the canonical location for formals. */ void maybeForwardToCallObject(JSObject *obj, ArgumentsData *data) { ArgumentsObject::MaybeForwardToCallObject(frame_, obj, data); @@ -100,24 +103,35 @@ struct CopyIonJSFrameArgs { ion::IonJSFrameLayout *frame_; HandleObject callObj_; CopyIonJSFrameArgs(ion::IonJSFrameLayout *frame, HandleObject callObj) : frame_(frame), callObj_(callObj) { } - void copyArgs(JSContext *, HeapValue *dst) const { + void copyArgs(JSContext *, HeapValue *dstBase, unsigned totalArgs) const { unsigned numActuals = frame_->numActualArgs(); + unsigned numFormals = ion::CalleeTokenToFunction(frame_->calleeToken())->nargs; + JS_ASSERT(numActuals <= totalArgs); + JS_ASSERT(numFormals <= totalArgs); + JS_ASSERT(Max(numActuals, numFormals) == totalArgs); /* Copy all arguments. */ Value *src = frame_->argv() + 1; /* +1 to skip this. */ Value *end = src + numActuals; + HeapValue *dst = dstBase; while (src != end) (dst++)->init(*src++); + + if (numActuals < numFormals) { + HeapValue *dstEnd = dstBase + totalArgs; + while (dst != dstEnd) + (dst++)->init(UndefinedValue()); + } } /* * If a call object exists and the arguments object aliases formals, the * call object is the canonical location for formals. */ void maybeForwardToCallObject(JSObject *obj, ArgumentsData *data) { ArgumentsObject::MaybeForwardToCallObject(frame_, callObj_, obj, data); @@ -128,30 +142,34 @@ struct CopyIonJSFrameArgs struct CopyStackIterArgs { StackIter &iter_; CopyStackIterArgs(StackIter &iter) : iter_(iter) { } - void copyArgs(JSContext *cx, HeapValue *dstBase) const { + void copyArgs(JSContext *cx, HeapValue *dstBase, unsigned totalArgs) const { if (!iter_.isIon()) { - CopyStackFrameArguments(iter_.abstractFramePtr(), dstBase); + CopyStackFrameArguments(iter_.abstractFramePtr(), dstBase, totalArgs); return; } /* Copy actual arguments. */ iter_.ionForEachCanonicalActualArg(cx, CopyToHeap(dstBase)); /* Define formals which are not part of the actuals. */ unsigned numActuals = iter_.numActualArgs(); unsigned numFormals = iter_.callee()->nargs; + JS_ASSERT(numActuals <= totalArgs); + JS_ASSERT(numFormals <= totalArgs); + JS_ASSERT(Max(numActuals, numFormals) == totalArgs); + if (numActuals < numFormals) { - HeapValue *dst = dstBase + numActuals, *dstEnd = dstBase + numFormals; + HeapValue *dst = dstBase + numActuals, *dstEnd = dstBase + totalArgs; while (dst != dstEnd) (dst++)->init(UndefinedValue()); } } /* * Ion frames are copying every argument onto the stack, other locations are * invalid. @@ -196,17 +214,17 @@ ArgumentsObject::create(JSContext *cx, H return NULL; data->numArgs = numArgs; data->callee.init(ObjectValue(*callee.get())); data->script = script; /* Copy [0, numArgs) into data->slots. */ HeapValue *dst = data->args, *dstEnd = data->args + numArgs; - copy.copyArgs(cx, dst); + copy.copyArgs(cx, dst, numArgs); data->deletedBits = reinterpret_cast<size_t *>(dstEnd); ClearAllBitArrayElements(data->deletedBits, numDeletedWords); RawObject obj = JSObject::create(cx, FINALIZE_KIND, GetInitialHeap(GenericObject, clasp), shape, type); if (!obj) { js_free(data);