
ExecutorAddr was introduced in b8e5f918166 as an eventual replacement for JITTargetAddress. ExecutorSymbolDef is introduced in this patch as a replacement for JITEvaluatedSymbol: ExecutorSymbolDef is an (ExecutorAddr, JITSymbolFlags) pair, where JITEvaluatedSymbol was a (JITTargetAddress, JITSymbolFlags) pair. A number of APIs had already migrated from JITTargetAddress to ExecutorAddr, but many of ORC's internals were still using the older type. This patch aims to address that. Some public APIs are affected as well. If you need to migrate your APIs you can use the following operations: * ExecutorAddr::toPtr replaces jitTargetAddressToPointer and jitTargetAddressToFunction. * ExecutorAddr::fromPtr replace pointerToJITTargetAddress. * ExecutorAddr(JITTargetAddress) creates an ExecutorAddr value from a JITTargetAddress. * ExecutorAddr::getValue() creates a JITTargetAddress value from an ExecutorAddr. JITTargetAddress and JITEvaluatedSymbol will remain in JITSymbol.h for now, but the aim will be to eventually deprecate and remove these types (probably when MCJIT and RuntimeDyld are deprecated).
119 lines
4.2 KiB
C++
119 lines
4.2 KiB
C++
//===- ExecutionSessionWrapperFunctionCallsTest.cpp -- Test wrapper calls -===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "llvm/ExecutionEngine/Orc/Core.h"
|
|
#include "llvm/ExecutionEngine/Orc/ExecutorProcessControl.h"
|
|
#include "llvm/Support/MSVCErrorWorkarounds.h"
|
|
#include "llvm/Testing/Support/Error.h"
|
|
#include "gtest/gtest.h"
|
|
|
|
#include <future>
|
|
|
|
using namespace llvm;
|
|
using namespace llvm::orc;
|
|
using namespace llvm::orc::shared;
|
|
|
|
static llvm::orc::shared::CWrapperFunctionResult addWrapper(const char *ArgData,
|
|
size_t ArgSize) {
|
|
return WrapperFunction<int32_t(int32_t, int32_t)>::handle(
|
|
ArgData, ArgSize, [](int32_t X, int32_t Y) { return X + Y; })
|
|
.release();
|
|
}
|
|
|
|
static void addAsyncWrapper(unique_function<void(int32_t)> SendResult,
|
|
int32_t X, int32_t Y) {
|
|
SendResult(X + Y);
|
|
}
|
|
|
|
static llvm::orc::shared::CWrapperFunctionResult
|
|
voidWrapper(const char *ArgData, size_t ArgSize) {
|
|
return WrapperFunction<void()>::handle(ArgData, ArgSize, []() {}).release();
|
|
}
|
|
|
|
TEST(ExecutionSessionWrapperFunctionCalls, RunWrapperTemplate) {
|
|
ExecutionSession ES(cantFail(SelfExecutorProcessControl::Create()));
|
|
|
|
int32_t Result;
|
|
EXPECT_THAT_ERROR(ES.callSPSWrapper<int32_t(int32_t, int32_t)>(
|
|
ExecutorAddr::fromPtr(addWrapper), Result, 2, 3),
|
|
Succeeded());
|
|
EXPECT_EQ(Result, 5);
|
|
cantFail(ES.endSession());
|
|
}
|
|
|
|
TEST(ExecutionSessionWrapperFunctionCalls, RunVoidWrapperAsyncTemplate) {
|
|
ExecutionSession ES(cantFail(SelfExecutorProcessControl::Create()));
|
|
|
|
std::promise<MSVCPError> RP;
|
|
ES.callSPSWrapperAsync<void()>(ExecutorAddr::fromPtr(voidWrapper),
|
|
[&](Error SerializationErr) {
|
|
RP.set_value(std::move(SerializationErr));
|
|
});
|
|
Error Err = RP.get_future().get();
|
|
EXPECT_THAT_ERROR(std::move(Err), Succeeded());
|
|
cantFail(ES.endSession());
|
|
}
|
|
|
|
TEST(ExecutionSessionWrapperFunctionCalls, RunNonVoidWrapperAsyncTemplate) {
|
|
ExecutionSession ES(cantFail(SelfExecutorProcessControl::Create()));
|
|
|
|
std::promise<MSVCPExpected<int32_t>> RP;
|
|
ES.callSPSWrapperAsync<int32_t(int32_t, int32_t)>(
|
|
ExecutorAddr::fromPtr(addWrapper),
|
|
[&](Error SerializationErr, int32_t R) {
|
|
if (SerializationErr)
|
|
RP.set_value(std::move(SerializationErr));
|
|
RP.set_value(std::move(R));
|
|
},
|
|
2, 3);
|
|
Expected<int32_t> Result = RP.get_future().get();
|
|
EXPECT_THAT_EXPECTED(Result, HasValue(5));
|
|
cantFail(ES.endSession());
|
|
}
|
|
|
|
TEST(ExecutionSessionWrapperFunctionCalls, RegisterAsyncHandlerAndRun) {
|
|
|
|
constexpr ExecutorAddr AddAsyncTagAddr(0x01);
|
|
|
|
ExecutionSession ES(cantFail(SelfExecutorProcessControl::Create()));
|
|
auto &JD = ES.createBareJITDylib("JD");
|
|
|
|
auto AddAsyncTag = ES.intern("addAsync_tag");
|
|
cantFail(JD.define(absoluteSymbols(
|
|
{{AddAsyncTag, {AddAsyncTagAddr, JITSymbolFlags::Exported}}})));
|
|
|
|
ExecutionSession::JITDispatchHandlerAssociationMap Associations;
|
|
|
|
Associations[AddAsyncTag] =
|
|
ES.wrapAsyncWithSPS<int32_t(int32_t, int32_t)>(addAsyncWrapper);
|
|
|
|
cantFail(ES.registerJITDispatchHandlers(JD, std::move(Associations)));
|
|
|
|
std::promise<int32_t> RP;
|
|
auto RF = RP.get_future();
|
|
|
|
using ArgSerialization = SPSArgList<int32_t, int32_t>;
|
|
size_t ArgBufferSize = ArgSerialization::size(1, 2);
|
|
auto ArgBuffer = WrapperFunctionResult::allocate(ArgBufferSize);
|
|
SPSOutputBuffer OB(ArgBuffer.data(), ArgBuffer.size());
|
|
EXPECT_TRUE(ArgSerialization::serialize(OB, 1, 2));
|
|
|
|
ES.runJITDispatchHandler(
|
|
[&](WrapperFunctionResult ResultBuffer) {
|
|
int32_t Result;
|
|
SPSInputBuffer IB(ResultBuffer.data(), ResultBuffer.size());
|
|
EXPECT_TRUE(SPSArgList<int32_t>::deserialize(IB, Result));
|
|
RP.set_value(Result);
|
|
},
|
|
AddAsyncTagAddr, ArrayRef<char>(ArgBuffer.data(), ArgBuffer.size()));
|
|
|
|
EXPECT_EQ(RF.get(), (int32_t)3);
|
|
|
|
cantFail(ES.endSession());
|
|
}
|