ipc_helpers: Make PushStaticBuffer take std::vector by value

Allows interfaces to move the vector into the calls, avoiding any
reallocations.

Many existing call sites already std::move into the parameter, expecting
a move to occur. Only a few remain where this wasn't already
being done, which we can convert over.
This commit is contained in:
Lioncash 2020-04-18 19:01:16 -04:00
parent 397bd1bb73
commit a6e37b48e9
8 changed files with 52 additions and 51 deletions

View file

@ -93,7 +93,7 @@ public:
template <typename... O>
void PushMoveObjects(std::shared_ptr<O>... pointers);
void PushStaticBuffer(const std::vector<u8>& buffer, u8 buffer_id);
void PushStaticBuffer(std::vector<u8> buffer, u8 buffer_id);
/// Pushes an HLE MappedBuffer interface back to unmapped the buffer.
void PushMappedBuffer(const Kernel::MappedBuffer& mapped_buffer);
@ -193,14 +193,14 @@ inline void RequestBuilder::PushMoveObjects(std::shared_ptr<O>... pointers) {
PushMoveHLEHandles(context->AddOutgoingHandle(std::move(pointers))...);
}
inline void RequestBuilder::PushStaticBuffer(const std::vector<u8>& buffer, u8 buffer_id) {
inline void RequestBuilder::PushStaticBuffer(std::vector<u8> buffer, u8 buffer_id) {
ASSERT_MSG(buffer_id < MAX_STATIC_BUFFERS, "Invalid static buffer id");
Push(StaticBufferDesc(buffer.size(), buffer_id));
// This address will be replaced by the correct static buffer address during IPC translation.
Push<VAddr>(0xDEADC0DE);
context->AddStaticBuffer(buffer_id, buffer);
context->AddStaticBuffer(buffer_id, std::move(buffer));
}
inline void RequestBuilder::PushMappedBuffer(const Kernel::MappedBuffer& mapped_buffer) {

View file

@ -1307,7 +1307,7 @@ void Module::Interface::GetDependencyListFromCia(Kernel::HLERequestContext& ctx)
IPC::RequestBuilder rb = rp.MakeBuilder(1, 2);
rb.Push(RESULT_SUCCESS);
rb.PushStaticBuffer(buffer, 0);
rb.PushStaticBuffer(std::move(buffer), 0);
}
void Module::Interface::GetTransferSizeFromCia(Kernel::HLERequestContext& ctx) {

View file

@ -357,8 +357,8 @@ void Module::APTInterface::SendParameter(Kernel::HLERequestContext& ctx) {
void Module::APTInterface::ReceiveParameter(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0xD, 2, 0); // 0xD0080
AppletId app_id = rp.PopEnum<AppletId>();
u32 buffer_size = rp.Pop<u32>();
const auto app_id = rp.PopEnum<AppletId>();
const u32 buffer_size = rp.Pop<u32>();
LOG_DEBUG(Service_APT, "called app_id={:#010X}, buffer_size={:#010X}", static_cast<u32>(app_id),
buffer_size);
@ -379,14 +379,14 @@ void Module::APTInterface::ReceiveParameter(Kernel::HLERequestContext& ctx) {
ASSERT_MSG(next_parameter->buffer.size() <= buffer_size, "Input static buffer is too small!");
rb.Push(static_cast<u32>(next_parameter->buffer.size())); // Parameter buffer size
rb.PushMoveObjects(next_parameter->object);
next_parameter->buffer.resize(buffer_size, 0); // APT always push a buffer with the maximum size
rb.PushStaticBuffer(next_parameter->buffer, 0);
next_parameter->buffer.resize(buffer_size); // APT always push a buffer with the maximum size
rb.PushStaticBuffer(std::move(next_parameter->buffer), 0);
}
void Module::APTInterface::GlanceParameter(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0xE, 2, 0); // 0xE0080
AppletId app_id = rp.PopEnum<AppletId>();
u32 buffer_size = rp.Pop<u32>();
const auto app_id = rp.PopEnum<AppletId>();
const u32 buffer_size = rp.Pop<u32>();
LOG_DEBUG(Service_APT, "called app_id={:#010X}, buffer_size={:#010X}", static_cast<u32>(app_id),
buffer_size);
@ -406,8 +406,8 @@ void Module::APTInterface::GlanceParameter(Kernel::HLERequestContext& ctx) {
ASSERT_MSG(next_parameter->buffer.size() <= buffer_size, "Input static buffer is too small!");
rb.Push(static_cast<u32>(next_parameter->buffer.size())); // Parameter buffer size
rb.PushMoveObjects(next_parameter->object);
next_parameter->buffer.resize(buffer_size, 0); // APT always push a buffer with the maximum size
rb.PushStaticBuffer(next_parameter->buffer, 0);
next_parameter->buffer.resize(buffer_size); // APT always push a buffer with the maximum size
rb.PushStaticBuffer(std::move(next_parameter->buffer), 0);
}
void Module::APTInterface::CancelParameter(Kernel::HLERequestContext& ctx) {
@ -779,9 +779,8 @@ void Module::APTInterface::GetAppletInfo(Kernel::HLERequestContext& ctx) {
void Module::APTInterface::GetStartupArgument(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x51, 2, 0); // 0x00510080
u32 parameter_size = rp.Pop<u32>();
StartupArgumentType startup_argument_type = static_cast<StartupArgumentType>(rp.Pop<u8>());
const u32 max_parameter_size{0x1000};
constexpr u32 max_parameter_size{0x1000};
const auto startup_argument_type = static_cast<StartupArgumentType>(rp.Pop<u8>());
if (parameter_size > max_parameter_size) {
LOG_ERROR(Service_APT,
@ -791,7 +790,7 @@ void Module::APTInterface::GetStartupArgument(Kernel::HLERequestContext& ctx) {
parameter_size = max_parameter_size;
}
std::vector<u8> parameter(parameter_size, 0);
std::vector<u8> parameter(parameter_size);
LOG_WARNING(Service_APT, "(STUBBED) called, startup_argument_type={}, parameter_size={:#010X}",
static_cast<u32>(startup_argument_type), parameter_size);
@ -799,7 +798,7 @@ void Module::APTInterface::GetStartupArgument(Kernel::HLERequestContext& ctx) {
IPC::RequestBuilder rb = rp.MakeBuilder(2, 2);
rb.Push(RESULT_SUCCESS);
rb.Push<u32>(0);
rb.PushStaticBuffer(parameter, 0);
rb.PushStaticBuffer(std::move(parameter), 0);
}
void Module::APTInterface::Wrap(Kernel::HLERequestContext& ctx) {

View file

@ -936,7 +936,7 @@ void Module::Interface::GetLatestVsyncTiming(Kernel::HLERequestContext& ctx) {
break;
}
}
rb.PushStaticBuffer(out, 0);
rb.PushStaticBuffer(std::move(out), 0);
}
void Module::Interface::GetStereoCameraCalibrationData(Kernel::HLERequestContext& ctx) {

View file

@ -155,13 +155,14 @@ void DSP_DSP::ReadPipeIfPossible(Kernel::HLERequestContext& ctx) {
const u16 pipe_readable_size = static_cast<u16>(system.DSP().GetPipeReadableSize(pipe));
std::vector<u8> pipe_buffer;
if (pipe_readable_size >= size)
if (pipe_readable_size >= size) {
pipe_buffer = system.DSP().PipeRead(pipe, size);
}
IPC::RequestBuilder rb = rp.MakeBuilder(2, 2);
rb.Push(RESULT_SUCCESS);
rb.Push<u16>(pipe_readable_size);
rb.PushStaticBuffer(pipe_buffer, 0);
rb.PushStaticBuffer(std::move(pipe_buffer), 0);
LOG_DEBUG(Service_DSP, "channel={}, peer={}, size=0x{:04X}, pipe_readable_size=0x{:04X}",
channel, peer, size, pipe_readable_size);

View file

@ -29,52 +29,52 @@ void Module::Interface::GetMyPresence(Kernel::HLERequestContext& ctx) {
IPC::RequestBuilder rb = rp.MakeBuilder(1, 2);
rb.Push(RESULT_SUCCESS);
rb.PushStaticBuffer(buffer, 0);
rb.PushStaticBuffer(std::move(buffer), 0);
LOG_WARNING(Service_FRD, "(STUBBED) called");
}
void Module::Interface::GetFriendKeyList(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x11, 2, 0);
u32 unknown = rp.Pop<u32>();
u32 frd_count = rp.Pop<u32>();
const u32 unknown = rp.Pop<u32>();
const u32 frd_count = rp.Pop<u32>();
std::vector<u8> buffer(sizeof(FriendKey) * frd_count, 0);
IPC::RequestBuilder rb = rp.MakeBuilder(2, 2);
rb.Push(RESULT_SUCCESS);
rb.Push<u32>(0); // 0 friends
rb.PushStaticBuffer(buffer, 0);
rb.PushStaticBuffer(std::move(buffer), 0);
LOG_WARNING(Service_FRD, "(STUBBED) called, unknown={}, frd_count={}", unknown, frd_count);
}
void Module::Interface::GetFriendProfile(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x15, 1, 2);
u32 count = rp.Pop<u32>();
std::vector<u8> frd_keys = rp.PopStaticBuffer();
const u32 count = rp.Pop<u32>();
const std::vector<u8> frd_keys = rp.PopStaticBuffer();
ASSERT(frd_keys.size() == count * sizeof(FriendKey));
std::vector<u8> buffer(sizeof(Profile) * count, 0);
IPC::RequestBuilder rb = rp.MakeBuilder(1, 2);
rb.Push(RESULT_SUCCESS);
rb.PushStaticBuffer(buffer, 0);
rb.PushStaticBuffer(std::move(buffer), 0);
LOG_WARNING(Service_FRD, "(STUBBED) called, count={}", count);
}
void Module::Interface::GetFriendAttributeFlags(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x17, 1, 2);
u32 count = rp.Pop<u32>();
std::vector<u8> frd_keys = rp.PopStaticBuffer();
const u32 count = rp.Pop<u32>();
const std::vector<u8> frd_keys = rp.PopStaticBuffer();
ASSERT(frd_keys.size() == count * sizeof(FriendKey));
// TODO:(mailwl) figure out AttributeFlag size and zero all buffer. Assume 1 byte
std::vector<u8> buffer(1 * count, 0);
IPC::RequestBuilder rb = rp.MakeBuilder(1, 2);
rb.Push(RESULT_SUCCESS);
rb.PushStaticBuffer(buffer, 0);
rb.PushStaticBuffer(std::move(buffer), 0);
LOG_WARNING(Service_FRD, "(STUBBED) called, count={}", count);
}
@ -111,7 +111,7 @@ void Module::Interface::UnscrambleLocalFriendCode(Kernel::HLERequestContext& ctx
IPC::RequestParser rp(ctx, 0x1C, 1, 2);
const u32 friend_code_count = rp.Pop<u32>();
std::vector<u8> scrambled_friend_codes = rp.PopStaticBuffer();
const std::vector<u8> scrambled_friend_codes = rp.PopStaticBuffer();
ASSERT_MSG(scrambled_friend_codes.size() == (friend_code_count * scrambled_friend_code_size),
"Wrong input buffer size");
@ -133,7 +133,7 @@ void Module::Interface::UnscrambleLocalFriendCode(Kernel::HLERequestContext& ctx
LOG_WARNING(Service_FRD, "(STUBBED) called");
IPC::RequestBuilder rb = rp.MakeBuilder(1, 2);
rb.Push(RESULT_SUCCESS);
rb.PushStaticBuffer(unscrambled_friend_codes, 0);
rb.PushStaticBuffer(std::move(unscrambled_friend_codes), 0);
}
void Module::Interface::SetClientSdkVersion(Kernel::HLERequestContext& ctx) {

View file

@ -1124,12 +1124,12 @@ void NWM_UDS::PullPacket(Kernel::HLERequestContext& ctx) {
}
if (channel->second.received_packets.empty()) {
std::vector<u8> output_buffer(buff_size, 0);
std::vector<u8> output_buffer(buff_size);
IPC::RequestBuilder rb = rp.MakeBuilder(3, 2);
rb.Push(RESULT_SUCCESS);
rb.Push<u32>(0);
rb.Push<u16>(0);
rb.PushStaticBuffer(output_buffer, 0);
rb.PushStaticBuffer(std::move(output_buffer), 0);
return;
}
@ -1147,7 +1147,7 @@ void NWM_UDS::PullPacket(Kernel::HLERequestContext& ctx) {
IPC::RequestBuilder rb = rp.MakeBuilder(3, 2);
std::vector<u8> output_buffer(buff_size, 0);
std::vector<u8> output_buffer(buff_size);
// Write the actual data.
std::memcpy(output_buffer.data(),
next_packet.data() + sizeof(LLCHeader) + sizeof(SecureDataHeader), data_size);
@ -1155,7 +1155,7 @@ void NWM_UDS::PullPacket(Kernel::HLERequestContext& ctx) {
rb.Push(RESULT_SUCCESS);
rb.Push<u32>(data_size);
rb.Push<u16>(secure_data.src_node_id);
rb.PushStaticBuffer(output_buffer, 0);
rb.PushStaticBuffer(std::move(output_buffer), 0);
channel->second.received_packets.pop_front();
}
@ -1336,9 +1336,9 @@ void NWM_UDS::DecryptBeaconData(Kernel::HLERequestContext& ctx, u16 command_id)
IPC::RequestBuilder rb = rp.MakeBuilder(1, 2);
rb.Push(RESULT_SUCCESS);
std::vector<u8> output_buffer(sizeof(NodeInfo) * UDSMaxNodes, 0);
std::vector<u8> output_buffer(sizeof(NodeInfo) * UDSMaxNodes);
std::memcpy(output_buffer.data(), nodes.data(), sizeof(NodeInfo) * nodes.size());
rb.PushStaticBuffer(output_buffer, 0);
rb.PushStaticBuffer(std::move(output_buffer), 0);
}
template <u16 command_id>

View file

@ -513,12 +513,13 @@ void SOC_U::Accept(Kernel::HLERequestContext& ctx) {
socklen_t addr_len = sizeof(addr);
u32 ret = static_cast<u32>(::accept(socket_handle, &addr, &addr_len));
if ((s32)ret != SOCKET_ERROR_VALUE)
if (static_cast<s32>(ret) != SOCKET_ERROR_VALUE) {
open_sockets[ret] = {ret, true};
}
CTRSockAddr ctr_addr;
std::vector<u8> ctr_addr_buf(sizeof(ctr_addr));
if ((s32)ret == SOCKET_ERROR_VALUE) {
if (static_cast<s32>(ret) == SOCKET_ERROR_VALUE) {
ret = TranslateError(GET_ERRNO);
} else {
ctr_addr = CTRSockAddr::FromPlatform(addr);
@ -528,7 +529,7 @@ void SOC_U::Accept(Kernel::HLERequestContext& ctx) {
IPC::RequestBuilder rb = rp.MakeBuilder(2, 2);
rb.Push(RESULT_SUCCESS);
rb.Push(ret);
rb.PushStaticBuffer(ctr_addr_buf, 0);
rb.PushStaticBuffer(std::move(ctr_addr_buf), 0);
}
void SOC_U::GetHostId(Kernel::HLERequestContext& ctx) {
@ -636,7 +637,7 @@ void SOC_U::RecvFromOther(Kernel::HLERequestContext& ctx) {
IPC::RequestBuilder rb = rp.MakeBuilder(2, 4);
rb.Push(RESULT_SUCCESS);
rb.Push(ret);
rb.PushStaticBuffer(addr_buff, 0);
rb.PushStaticBuffer(std::move(addr_buff), 0);
rb.PushMappedBuffer(buffer);
}
@ -685,8 +686,8 @@ void SOC_U::RecvFrom(Kernel::HLERequestContext& ctx) {
rb.Push(RESULT_SUCCESS);
rb.Push(ret);
rb.Push(total_received);
rb.PushStaticBuffer(output_buff, 0);
rb.PushStaticBuffer(addr_buff, 1);
rb.PushStaticBuffer(std::move(output_buff), 0);
rb.PushStaticBuffer(std::move(addr_buff), 1);
}
void SOC_U::Poll(Kernel::HLERequestContext& ctx) {
@ -720,7 +721,7 @@ void SOC_U::Poll(Kernel::HLERequestContext& ctx) {
IPC::RequestBuilder rb = rp.MakeBuilder(2, 2);
rb.Push(RESULT_SUCCESS);
rb.Push(ret);
rb.PushStaticBuffer(output_fds, 0);
rb.PushStaticBuffer(std::move(output_fds), 0);
}
void SOC_U::GetSockName(Kernel::HLERequestContext& ctx) {
@ -743,7 +744,7 @@ void SOC_U::GetSockName(Kernel::HLERequestContext& ctx) {
IPC::RequestBuilder rb = rp.MakeBuilder(2, 2);
rb.Push(RESULT_SUCCESS);
rb.Push(ret);
rb.PushStaticBuffer(dest_addr_buff, 0);
rb.PushStaticBuffer(std::move(dest_addr_buff), 0);
}
void SOC_U::Shutdown(Kernel::HLERequestContext& ctx) {
@ -781,7 +782,7 @@ void SOC_U::GetPeerName(Kernel::HLERequestContext& ctx) {
IPC::RequestBuilder rb = rp.MakeBuilder(2, 2);
rb.Push(RESULT_SUCCESS);
rb.Push(ret);
rb.PushStaticBuffer(dest_addr_buff, 0);
rb.PushStaticBuffer(std::move(dest_addr_buff), 0);
}
void SOC_U::Connect(Kernel::HLERequestContext& ctx) {
@ -857,7 +858,7 @@ void SOC_U::GetSockOpt(Kernel::HLERequestContext& ctx) {
rb.Push(RESULT_SUCCESS);
rb.Push(err);
rb.Push(static_cast<u32>(optlen));
rb.PushStaticBuffer(optval, 0);
rb.PushStaticBuffer(std::move(optval), 0);
}
void SOC_U::SetSockOpt(Kernel::HLERequestContext& ctx) {
@ -948,7 +949,7 @@ void SOC_U::GetAddrInfoImpl(Kernel::HLERequestContext& ctx) {
rb.Push(RESULT_SUCCESS);
rb.Push(ret);
rb.Push(count);
rb.PushStaticBuffer(out_buff, 0);
rb.PushStaticBuffer(std::move(out_buff), 0);
}
void SOC_U::GetNameInfoImpl(Kernel::HLERequestContext& ctx) {
@ -976,8 +977,8 @@ void SOC_U::GetNameInfoImpl(Kernel::HLERequestContext& ctx) {
IPC::RequestBuilder rb = rp.MakeBuilder(2, 4);
rb.Push(RESULT_SUCCESS);
rb.Push(ret);
rb.PushStaticBuffer(host, 0);
rb.PushStaticBuffer(serv, 1);
rb.PushStaticBuffer(std::move(host), 0);
rb.PushStaticBuffer(std::move(serv), 1);
}
SOC_U::SOC_U() : ServiceFramework("soc:U") {