bool
CrossCompartmentWrapper::call(JSContext *cx, JSObject *wrapperArg, unsigned argc, Value *vp)
{
    RootedObject wrapper(cx, wrapperArg);
    RootedObject wrapped(cx, wrappedObject(wrapper));

    CallArgs args = CallArgsFromVp(argc, vp);
    {
        AutoCompartment call(cx, wrapped);

        args.setCallee(ObjectValue(*wrapped));
        if (!cx->compartment->wrap(cx, args.mutableThisv()))
            return false;

        for (size_t n = 0; n < args.length(); ++n) {
            if (!cx->compartment->wrap(cx, args.handleAt(n)))
                return false;
        }

        if (!Wrapper::call(cx, wrapper, argc, vp))
            return false;
    }

    return cx->compartment->wrap(cx, args.rval());
}
bool CrossCompartmentWrapper::call(JSContext* cx, HandleObject wrapper,
                                   const CallArgs& args) const {
  RootedObject wrapped(cx, wrappedObject(wrapper));

  {
    AutoRealm call(cx, wrapped);

    args.setCallee(ObjectValue(*wrapped));
    if (!cx->compartment()->wrap(cx, args.mutableThisv())) {
      return false;
    }

    for (size_t n = 0; n < args.length(); ++n) {
      if (!cx->compartment()->wrap(cx, args[n])) {
        return false;
      }
    }

    if (!Wrapper::call(cx, wrapper, args)) {
      return false;
    }
  }

  return cx->compartment()->wrap(cx, args.rval());
}