Bug 867844 part 1. Fix rooting hazards in LegacyCall. r=smaug

This commit is contained in:
Boris Zbarsky
2013-05-06 08:30:40 -04:00
parent 9694684126
commit 1821761af9
3 changed files with 21 additions and 17 deletions

View File

@@ -2848,7 +2848,7 @@ nsObjectLoadingContent::GetContentDocument()
JS::Value
nsObjectLoadingContent::LegacyCall(JSContext* aCx,
JS::Value aThisVal,
JS::Handle<JS::Value> aThisVal,
const Sequence<JS::Value>& aArguments,
ErrorResult& aRv)
{
@@ -2885,7 +2885,8 @@ nsObjectLoadingContent::LegacyCall(JSContext* aCx,
}
}
if (!JS_WrapValue(aCx, &aThisVal)) {
JS::Rooted<JS::Value> thisVal(aCx, aThisVal);
if (!JS_WrapValue(aCx, thisVal.address())) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return JS::UndefinedValue();
}
@@ -2903,10 +2904,10 @@ nsObjectLoadingContent::LegacyCall(JSContext* aCx,
return JS::UndefinedValue();
}
JSObject *pi_obj;
JSObject *pi_proto;
JS::Rooted<JSObject*> pi_obj(aCx);
JS::Rooted<JSObject*> pi_proto(aCx);
rv = GetPluginJSObject(aCx, obj, pi, &pi_obj, &pi_proto);
rv = GetPluginJSObject(aCx, obj, pi, pi_obj.address(), pi_proto.address());
if (NS_FAILED(rv)) {
aRv.Throw(rv);
return JS::UndefinedValue();
@@ -2917,9 +2918,9 @@ nsObjectLoadingContent::LegacyCall(JSContext* aCx,
return JS::UndefinedValue();
}
JS::Value retval;
bool ok = ::JS::Call(aCx, aThisVal, pi_obj, args.Length(),
args.Elements(), &retval);
JS::Rooted<JS::Value> retval(aCx);
bool ok = ::JS::Call(aCx, thisVal, pi_obj, args.Length(),
args.Elements(), retval.address());
if (!ok) {
aRv.Throw(NS_ERROR_FAILURE);
return JS::UndefinedValue();
@@ -2970,10 +2971,10 @@ nsObjectLoadingContent::SetupProtoChain(JSContext* aCx,
return;
}
JSObject *pi_obj; // XPConnect-wrapped peer object, when we get it.
JSObject *pi_proto; // 'pi.__proto__'
JS::Rooted<JSObject*> pi_obj(aCx); // XPConnect-wrapped peer object, when we get it.
JS::Rooted<JSObject*> pi_proto(aCx); // 'pi.__proto__'
rv = GetPluginJSObject(aCx, aObject, pi, &pi_obj, &pi_proto);
rv = GetPluginJSObject(aCx, aObject, pi, pi_obj.address(), pi_proto.address());
if (NS_FAILED(rv)) {
return;
}

View File

@@ -195,7 +195,7 @@ class nsObjectLoadingContent : public nsImageLoadingContent
{
aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
}
JS::Value LegacyCall(JSContext* aCx, JS::Value aThisVal,
JS::Value LegacyCall(JSContext* aCx, JS::Handle<JS::Value> aThisVal,
const mozilla::dom::Sequence<JS::Value>& aArguments,
mozilla::ErrorResult& aRv);

View File

@@ -4312,7 +4312,7 @@ if (global.Failed()) {
# generating code for the legacycaller or not.
assert idlNode.isIdentifierLess()
# Pass in our thisVal
argsPre.append("JS_THIS_VALUE(cx, vp)")
argsPre.append("args.thisv()")
cgThings.extend([CGArgumentConverter(arguments[i], i, self.getArgv(),
self.getArgc(), self.descriptor,
@@ -4807,7 +4807,8 @@ class CGAbstractBindingMethod(CGAbstractStaticMethod):
CGThing which is already properly indented.
"""
def __init__(self, descriptor, name, args, unwrapFailureCode=None,
getThisObj="JS_THIS_OBJECT(cx, vp)"):
getThisObj="&args.computeThis(cx).toObject()",
callArgs="JS::CallArgs args = JS::CallArgsFromVp(argc, vp);"):
CGAbstractStaticMethod.__init__(self, descriptor, name, "JSBool", args)
if unwrapFailureCode is None:
@@ -4815,18 +4816,20 @@ class CGAbstractBindingMethod(CGAbstractStaticMethod):
else:
self.unwrapFailureCode = unwrapFailureCode
self.getThisObj = getThisObj
self.callArgs = callArgs
def definition_body(self):
# Our descriptor might claim that we're not castable, simply because
# we're someone's consequential interface. But for this-unwrapping, we
# know that we're the real deal. So fake a descriptor here for
# consumption by CastableObjectUnwrapper.
getThis = CGGeneric("""JS::RootedObject obj(cx, %s);
getThis = CGGeneric("""%s
JS::RootedObject obj(cx, %s);
if (!obj) {
return false;
}
%s* self;""" % (self.getThisObj, self.descriptor.nativeType))
%s* self;""" % (self.callArgs, self.getThisObj, self.descriptor.nativeType))
unwrapThis = CGGeneric(
str(CastableObjectUnwrapper(
self.descriptor,
@@ -4939,7 +4942,7 @@ class CGNewResolveHook(CGAbstractBindingMethod):
# Our "self" is actually the callee in this case, not the thisval.
CGAbstractBindingMethod.__init__(
self, descriptor, NEWRESOLVE_HOOK_NAME,
args, getThisObj="obj_")
args, getThisObj="obj_", callArgs="")
def define(self):
if not self._needNewResolve: