From 2e24dda14574c0aee8f4e2567ec1aeb049331595 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Fri, 7 Feb 2014 17:56:38 +0100 Subject: [PATCH] Bug 944975: fix bug by getting original fcn for callsite clone in New (r=shu). --- js/src/jsfun.cpp | 4 ++-- js/src/jsfun.h | 10 ++++++++++ js/src/vm/Interpreter.cpp | 7 ++++--- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/js/src/jsfun.cpp b/js/src/jsfun.cpp index 97d874db834d..afef861c5fb7 100644 --- a/js/src/jsfun.cpp +++ b/js/src/jsfun.cpp @@ -118,8 +118,8 @@ fun_getProperty(JSContext *cx, HandleObject obj_, HandleId id, MutableHandleValu /* Callsite clones should never escape to script. */ JSObject &maybeClone = iter.calleev().toObject(); - if (maybeClone.is() && maybeClone.as().nonLazyScript()->isCallsiteClone()) - vp.setObject(*maybeClone.as().nonLazyScript()->originalFunction()); + if (maybeClone.is()) + vp.setObject(*maybeClone.as().originalFunction()); else vp.set(iter.calleev()); diff --git a/js/src/jsfun.h b/js/src/jsfun.h index 502843c2a9e7..1e05ef681253 100644 --- a/js/src/jsfun.h +++ b/js/src/jsfun.h @@ -339,6 +339,16 @@ class JSFunction : public JSObject return u.i.s.script_; } + // Returns the non-callsited-clone version of this function. Use + // when return-value can flow to arbitrary JS (see Bug 944975). + JSFunction* originalFunction() { + if (this->hasScript() && this->nonLazyScript()->isCallsiteClone()) { + return this->nonLazyScript()->originalFunction(); + } else { + return this; + } + } + js::HeapPtrScript &mutableScript() { JS_ASSERT(isInterpreted()); return *(js::HeapPtrScript *)&u.i.s.script_; diff --git a/js/src/vm/Interpreter.cpp b/js/src/vm/Interpreter.cpp index cfc5b03411fc..ab9038255df8 100644 --- a/js/src/vm/Interpreter.cpp +++ b/js/src/vm/Interpreter.cpp @@ -555,9 +555,10 @@ js::InvokeConstructor(JSContext *cx, CallArgs args) return ok; } - if (!fun->isInterpretedConstructor()) - return ReportIsNotFunction(cx, args.calleev(), args.length() + 1, CONSTRUCT); - + if (!fun->isInterpretedConstructor()) { + RootedValue orig(cx, ObjectValue(*fun->originalFunction())); + return ReportIsNotFunction(cx, orig, args.length() + 1, CONSTRUCT); + } if (!Invoke(cx, args, CONSTRUCT)) return false;