出于某种目的,我想使用一种专用语言。基本上它将是一堆我将从 C 代码调用的函数。我需要将这些函数指针传递给某个结构。我不想通过实验来检查我是否知道如何获得该函数,我编写了一个小程序,该程序应该采用结构的整数并将其加 2。当我试图获取指向结构元素的指针时出现错误。 注意:我完成了万花筒教程,所以我从那里获取了一些对象。 代码: // 结构定义:
struct test_struct {
char *b;
int *c_dummy;
int c;
double f ;
};
struct test_struct tt{0,0,1,0};
// 初始化。
InitializeNativeTarget();
InitializeNativeTargetAsmPrinter();
InitializeNativeTargetAsmParser();
TheJIT = ExitOnErr(KaleidoscopeJIT::Create());
TheContext = std::make_unique<LLVMContext>();
TheModule = std::make_unique<Module>("my cool jit", *TheContext);
TheModule->setDataLayout(TheJIT->getDataLayout());
Builder = std::make_unique<IRBuilder<>>(*TheContext);
TheFPM = std::make_unique<legacy::FunctionPassManager>(TheModule.get());
TheFPM->add(createCFGSimplificationPass());
TheFPM->doInitialization();
// 创建值 2 稍后添加。
Value *v_const = ConstantInt::get(*TheContext,APInt(32,2,true));
// 函数的返回类型:
Type *r_type = Type::getVoidTy(*TheContext);
// 在 llvm 中定义结构参数
ArrayRef<Type *> params = {Type::getInt8PtrTy(*TheContext),Type::getInt32PtrTy(*TheContext),
Type::getInt32Ty(*TheContext),Type::getDoubleTy(*TheContext)};
StructType *st = StructType::create(*TheContext,"s");
st->setBody(params);
// 获取函数并注册到模块。获取条目 BB 并进行加法。
Value *c;
BasicBlock *bb = BasicBlock::Create(*TheContext,"entry",F);
Builder->SetInsertPoint(bb);
Value *mem= Builder->CreateAlloca(st,nullptr); // This should allocate the param to stack.
// create a stac allocation for st.
for (auto &arg : F->args())
{
// bring st from the argument.
auto &tmp_ar = arg;
c = Builder->CreateStructGEP(st,&arg,2);
}
/* Store the argument in the stack*/
Builder->CreateLoad(c,mem);
// perform add
Builder->CreateAdd(mem,v_const,"add tmp");
// close of.
Builder->CreateStore(mem,c);
Builder->CreateRetVoid();
现在我用这个函数测试它:
void do_test()
{
auto fsym = ExitOnErr(TheJIT->lookup("test"));
void (*add_func)(struct test_struct *) = (void (*)(struct test_struct *))(intptr_t)fsym.getAddress();
printf("Before func: %d\n", tt.c);
add_func(&tt); // this should change t.c
printf("After func: %d\n", tt.c);
}
我得到了我不明白的错误:
test_ptr: /usr/lib/llvm-14/include/llvm/Support/Casting.h:269: typename llvm::cast_retty
因为这条线而发生:
c = Builder->CreateStructGEP(st,&arg,2);
我期待它运行并打印正确的值。我编译了:g++ -g test_ptr.cpp
llvm-config --cxxflags --ldflags --system-libs --libs core orcjit native
-O0 -o test_ptr