Bug 1008236. Assert that binding generic getters/setters/methods return values that match the return type claimed in the jitinfo. r=smaug

This commit is contained in:
Boris Zbarsky 2014-05-15 10:26:23 -07:00
parent b6d4826f34
commit 36b45d89c9
3 changed files with 86 additions and 6 deletions

View File

@ -2258,7 +2258,13 @@ GenericBindingGetter(JSContext* cx, unsigned argc, JS::Value* vp)
MOZ_ASSERT(info->type() == JSJitInfo::Getter);
JSJitGetterOp getter = info->getter;
return getter(cx, obj, self, JSJitGetterCallArgs(args));
bool ok = getter(cx, obj, self, JSJitGetterCallArgs(args));
#ifdef DEBUG
if (ok) {
AssertReturnTypeMatchesJitinfo(info, args.rval());
}
#endif
return ok;
}
bool
@ -2291,7 +2297,10 @@ GenericBindingSetter(JSContext* cx, unsigned argc, JS::Value* vp)
if (!setter(cx, obj, self, JSJitSetterCallArgs(args))) {
return false;
}
args.rval().set(JSVAL_VOID);
args.rval().setUndefined();
#ifdef DEBUG
AssertReturnTypeMatchesJitinfo(info, args.rval());
#endif
return true;
}
@ -2319,7 +2328,13 @@ GenericBindingMethod(JSContext* cx, unsigned argc, JS::Value* vp)
}
MOZ_ASSERT(info->type() == JSJitInfo::Method);
JSJitMethodOp method = info->method;
return method(cx, obj, self, JSJitMethodCallArgs(args));
bool ok = method(cx, obj, self, JSJitMethodCallArgs(args));
#ifdef DEBUG
if (ok) {
AssertReturnTypeMatchesJitinfo(info, args.rval());
}
#endif
return ok;
}
bool
@ -2357,9 +2372,14 @@ GenericPromiseReturningBindingMethod(JSContext* cx, unsigned argc, JS::Value* vp
JSJitMethodOp method = info->method;
bool ok = method(cx, obj, self, JSJitMethodCallArgs(args));
if (ok) {
#ifdef DEBUG
AssertReturnTypeMatchesJitinfo(info, args.rval());
#endif
return true;
}
// Promise-returning methods always return objects
MOZ_ASSERT(info->returnType() == JSVAL_TYPE_OBJECT);
return ConvertExceptionToPromise(cx, xpc::XrayAwareCalleeGlobal(callee),
args.rval());
}
@ -2429,5 +2449,44 @@ CreateGlobalOptions<nsGlobalWindow>::PostCreateGlobal(JSContext* aCx,
return XPCWrappedNativeScope::GetNewOrUsed(aCx, aGlobal);
}
#ifdef DEBUG
void
AssertReturnTypeMatchesJitinfo(const JSJitInfo* aJitInfo,
JS::Handle<JS::Value> aValue)
{
switch (aJitInfo->returnType()) {
case JSVAL_TYPE_UNKNOWN:
// Any value is good.
break;
case JSVAL_TYPE_DOUBLE:
// The value could actually be an int32 value as well.
MOZ_ASSERT(aValue.isNumber());
break;
case JSVAL_TYPE_INT32:
MOZ_ASSERT(aValue.isInt32());
break;
case JSVAL_TYPE_UNDEFINED:
MOZ_ASSERT(aValue.isUndefined());
break;
case JSVAL_TYPE_BOOLEAN:
MOZ_ASSERT(aValue.isBoolean());
break;
case JSVAL_TYPE_STRING:
MOZ_ASSERT(aValue.isString());
break;
case JSVAL_TYPE_NULL:
MOZ_ASSERT(aValue.isNull());
break;
case JSVAL_TYPE_OBJECT:
MOZ_ASSERT(aValue.isObject());
break;
default:
// Someone messed up their jitinfo type.
MOZ_ASSERT(false, "Unexpected JSValueType stored in jitinfo");
break;
}
}
#endif
} // namespace dom
} // namespace mozilla

View File

@ -2744,6 +2744,12 @@ GlobalPropertiesAreOwn()
return true;
}
#ifdef DEBUG
void
AssertReturnTypeMatchesJitinfo(const JSJitInfo* aJitinfo,
JS::Handle<JS::Value> aValue);
#endif
} // namespace dom
} // namespace mozilla

View File

@ -70,7 +70,7 @@ def indent(s, indentLevel=2):
Indent C++ code.
Weird secret feature: this doesn't indent lines that start with # (such as
#include lines).
#include lines or #ifdef/#endif).
"""
if s == "":
return s
@ -6683,7 +6683,13 @@ class CGGenericMethod(CGAbstractBindingMethod):
const JSJitInfo *info = FUNCTION_VALUE_TO_JITINFO(args.calleev());
MOZ_ASSERT(info->type() == JSJitInfo::Method);
JSJitMethodOp method = info->method;
return method(cx, obj, self, JSJitMethodCallArgs(args));
bool ok = method(cx, obj, self, JSJitMethodCallArgs(args));
#ifdef DEBUG
if (ok) {
AssertReturnTypeMatchesJitinfo(info, args.rval());
}
#endif
return ok;
""")))
@ -6981,7 +6987,13 @@ class CGGenericGetter(CGAbstractBindingMethod):
const JSJitInfo *info = FUNCTION_VALUE_TO_JITINFO(args.calleev());
MOZ_ASSERT(info->type() == JSJitInfo::Getter);
JSJitGetterOp getter = info->getter;
return getter(cx, obj, self, JSJitGetterCallArgs(args));
bool ok = getter(cx, obj, self, JSJitGetterCallArgs(args));
#ifdef DEBUG
if (ok) {
AssertReturnTypeMatchesJitinfo(info, args.rval());
}
#endif
return ok;
""")))
@ -7116,6 +7128,9 @@ class CGGenericSetter(CGAbstractBindingMethod):
return false;
}
args.rval().set(JSVAL_VOID);
#ifdef DEBUG
AssertReturnTypeMatchesJitinfo(info, args.rval());
#endif
return true;
""",
name=self.descriptor.interface.identifier.name)))