Bug 890076 - Move isConstructing to CallArgs, r=Waldo

--HG--
extra : rebase_source : f66e59fbd201153a4329a82264c32ad72465d654
This commit is contained in:
Steve Fink 2013-07-03 22:59:43 -07:00
parent e91abd4fa8
commit 0657e8eff7
9 changed files with 67 additions and 46 deletions

View File

@ -98,6 +98,11 @@ extern JS_PUBLIC_DATA(const HandleValue) UndefinedHandleValue;
namespace detail {
#ifdef DEBUG
extern JS_PUBLIC_API(void)
CheckIsValidConstructible(Value v);
#endif
enum UsedRval { IncludeUsedRval, NoUsedRval };
template<UsedRval WantUsedRval>
@ -171,6 +176,14 @@ class MOZ_STACK_CLASS CallReceiverBase : public UsedRvalBase<
return JS_ComputeThis(cx, base());
}
bool isConstructing() const {
#ifdef DEBUG
if (this->usedRval_)
CheckIsValidConstructible(calleev());
#endif
return argv_[-1].isMagic();
}
/*
* Returns the currently-set return value. The initial contents of this
* value are unspecified. Once this method has been called, callee() and

View File

@ -586,10 +586,11 @@ static const JSFunctionSpec collator_methods[] = {
* Spec: ECMAScript Internationalization API Specification, 10.1
*/
static bool
Collator(JSContext *cx, CallArgs args, bool construct)
Collator(JSContext *cx, CallArgs args)
{
RootedObject obj(cx);
bool construct = args.isConstructing();
if (!construct) {
// 10.1.2.1 step 3
JSObject *intl = cx->global()->getOrCreateIntlObject(cx);
@ -642,7 +643,7 @@ static JSBool
Collator(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
return Collator(cx, args, IsConstructing(args));
return Collator(cx, args);
}
JSBool
@ -650,7 +651,7 @@ js::intl_Collator(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
JS_ASSERT(args.length() == 2);
return Collator(cx, args, true);
return Collator(cx, args);
}
static void
@ -1067,9 +1068,10 @@ static const JSFunctionSpec numberFormat_methods[] = {
* Spec: ECMAScript Internationalization API Specification, 11.1
*/
static bool
NumberFormat(JSContext *cx, CallArgs args, bool construct)
NumberFormat(JSContext *cx, CallArgs args)
{
RootedObject obj(cx);
bool construct = args.isConstructing();
if (!construct) {
// 11.1.2.1 step 3
@ -1123,7 +1125,7 @@ static JSBool
NumberFormat(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
return NumberFormat(cx, args, IsConstructing(args));
return NumberFormat(cx, args);
}
JSBool
@ -1131,7 +1133,7 @@ js::intl_NumberFormat(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
JS_ASSERT(args.length() == 2);
return NumberFormat(cx, args, true);
return NumberFormat(cx, args);
}
static void
@ -1520,9 +1522,10 @@ static const JSFunctionSpec dateTimeFormat_methods[] = {
* Spec: ECMAScript Internationalization API Specification, 12.1
*/
static bool
DateTimeFormat(JSContext *cx, CallArgs args, bool construct)
DateTimeFormat(JSContext *cx, CallArgs args)
{
RootedObject obj(cx);
bool construct = args.isConstructing();
if (!construct) {
// 12.1.2.1 step 3
@ -1576,7 +1579,7 @@ static JSBool
DateTimeFormat(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
return DateTimeFormat(cx, args, IsConstructing(args));
return DateTimeFormat(cx, args);
}
JSBool
@ -1584,7 +1587,7 @@ js::intl_DateTimeFormat(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
JS_ASSERT(args.length() == 2);
return DateTimeFormat(cx, args, true);
return DateTimeFormat(cx, args);
}
static void

View File

@ -329,7 +329,7 @@ regexp_construct(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
if (!IsConstructing(args)) {
if (!args.isConstructing()) {
/*
* If first arg is regexp and no flags are given, just return the arg.
* Otherwise, delegate to the standard constructor.

View File

@ -124,7 +124,7 @@ Boolean(JSContext *cx, unsigned argc, Value *vp)
bool b = args.length() != 0 ? JS::ToBoolean(args[0]) : false;
if (IsConstructing(vp)) {
if (args.isConstructing()) {
JSObject *obj = BooleanObject::create(cx, b);
if (!obj)
return false;

View File

@ -2972,7 +2972,7 @@ js_Date(JSContext *cx, unsigned argc, Value *vp)
CallArgs args = CallArgsFromVp(argc, vp);
/* Date called as function. */
if (!IsConstructing(args))
if (!args.isConstructing())
return date_format(cx, NowAsMillis(), FORMATSPEC_FULL, args.rval());
/* Date called as constructor. */

View File

@ -1156,10 +1156,11 @@ JSFunction::createScriptForLazilyInterpretedFunction(JSContext *cx, HandleFuncti
JSBool
js::CallOrConstructBoundFunction(JSContext *cx, unsigned argc, Value *vp)
{
RootedFunction fun(cx, &vp[0].toObject().as<JSFunction>());
CallArgs args = CallArgsFromVp(argc, vp);
RootedFunction fun(cx, &args.callee().as<JSFunction>());
JS_ASSERT(fun->isBoundFunction());
bool constructing = IsConstructing(vp);
bool constructing = args.isConstructing();
if (constructing && fun->isArrow()) {
/*
* Per spec, arrow functions do not even have a [[Construct]] method.
@ -1183,25 +1184,25 @@ js::CallOrConstructBoundFunction(JSContext *cx, unsigned argc, Value *vp)
/* 15.3.4.5.1 step 2. */
const Value &boundThis = fun->getBoundFunctionThis();
InvokeArgs args(cx);
if (!args.init(argc + argslen))
InvokeArgs invokeArgs(cx);
if (!invokeArgs.init(argc + argslen))
return false;
/* 15.3.4.5.1, 15.3.4.5.2 step 4. */
for (unsigned i = 0; i < argslen; i++)
args[i] = fun->getBoundFunctionArgument(i);
PodCopy(args.array() + argslen, vp + 2, argc);
invokeArgs[i] = fun->getBoundFunctionArgument(i);
PodCopy(invokeArgs.array() + argslen, vp + 2, argc);
/* 15.3.4.5.1, 15.3.4.5.2 step 5. */
args.setCallee(ObjectValue(*target));
invokeArgs.setCallee(ObjectValue(*target));
if (!constructing)
args.setThis(boundThis);
invokeArgs.setThis(boundThis);
if (constructing ? !InvokeConstructor(cx, args) : !Invoke(cx, args))
if (constructing ? !InvokeConstructor(cx, invokeArgs) : !Invoke(cx, invokeArgs))
return false;
*vp = args.rval();
*vp = invokeArgs.rval();
return true;
}
@ -1753,3 +1754,18 @@ JSObject::hasIdempotentProtoChain() const
MOZ_ASSUME_UNREACHABLE("Should not get here");
}
namespace JS {
namespace detail {
JS_PUBLIC_API(void)
CheckIsValidConstructible(Value calleev)
{
JSObject *callee = &calleev.toObject();
if (callee->is<JSFunction>())
JS_ASSERT(callee->as<JSFunction>().isNativeConstructor());
else
JS_ASSERT(callee->getClass()->construct != NULL);
}
} // namespace detail
} // namespace JS

View File

@ -382,28 +382,6 @@ JSAPIToJSFunctionFlags(unsigned flags)
namespace js {
/* Valueified JS_IsConstructing. */
static JS_ALWAYS_INLINE bool
IsConstructing(const Value *vp)
{
#ifdef DEBUG
JSObject *callee = &JS_CALLEE(cx, vp).toObject();
if (callee->is<JSFunction>()) {
JSFunction *fun = &callee->as<JSFunction>();
JS_ASSERT(fun->isNativeConstructor());
} else {
JS_ASSERT(callee->getClass()->construct != NULL);
}
#endif
return vp[1].isMagic();
}
inline bool
IsConstructing(CallReceiver call)
{
return IsConstructing(call.base());
}
extern JSBool
Function(JSContext *cx, unsigned argc, Value *vp);
@ -508,4 +486,15 @@ extern JSObject*
js_fun_bind(JSContext *cx, js::HandleObject target, js::HandleValue thisArg,
js::Value *boundArgs, unsigned argslen);
#ifdef DEBUG
namespace JS {
namespace detail {
JS_PUBLIC_API(void)
CheckIsValidConstructible(Value calleev);
} // namespace detail
} // namespace JS
#endif
#endif /* jsfun_h */

View File

@ -434,7 +434,7 @@ Number(JSContext *cx, unsigned argc, Value *vp)
CallArgs args = CallArgsFromVp(argc, vp);
/* Sample JS_CALLEE before clobbering. */
bool isConstructing = IsConstructing(args);
bool isConstructing = args.isConstructing();
if (args.length() > 0) {
if (!ToNumber(cx, args.handleAt(0)))

View File

@ -3518,7 +3518,7 @@ js_String(JSContext *cx, unsigned argc, Value *vp)
str = cx->runtime()->emptyString;
}
if (IsConstructing(args)) {
if (args.isConstructing()) {
StringObject *strobj = StringObject::create(cx, str);
if (!strobj)
return false;