我想将LLVM lli
工具用作静态库(将main()
重命名为lli()
并将其导出到libLLi.a中) - 为其创建丰富的UI。我如何修改它(或使用而无需修改)以拦截stdin?
假设我知道如何生成LLVM程序集文件(使用clang -S -emit-llvm .. -o output.ll
)以及如何使用lli
工具(lli output.ll
)执行它。
常见用例:
由lli解释的简单app的源代码:
#include <iostream>
using namespace std;
int main() {
char name[128];
cout << "type your name: ";
cin.getline(name, sizeof(name));
cout << "hi, " << name << endl;
return 0;
}
我需要为它解释LLVM程序集并在调用cin.getline
时显示InputBox,并在调用cout <<
时显示TextBox(InputBox和TextBox是丰富的UI控件)。
PS。我不能分叉进程并转发整个子进程的stdin / stdout。
答案 0 :(得分:4)
lli
已经是llvm库函数的一个瘦包装器,只需使用它们。 tools/lli/lli.cpp
中的main()函数很长,只是因为它支持大量的标志来控制每个可能的设置。将其剥离后,使用EngineBuilder
创建ExecutionEngine
并使用它来运行llvm::Function
时,应该少于10行。
您可能还会发现chapter 4 of the Kaleidoscope tutorial很有帮助,他们会在该语言中添加JIT支持。这也演示了如何使用EngineBuilder,尽管他们选择构建的ExecutionEngine是JIT
而不是Interpreter
,您可以根据用例自定义它。
现在针对问题的其他部分,您如何陷阱stdin
和stdout
? LLVM不是VM,代码在您的进程中运行并使用您的stdin和stdout。我的第一个建议是,既然你已经拥有LLVM IR格式的功能,只需运行一个转换过程,用你自己的I / O函数替换标准的I / O函数。如果可以让ABI排队,更简单的方法是使用ExecutionEngine进行重映射。调用EE->updateGlobalMapping(functionDeclInIR, &replacementFunctionInNativeCode)
告诉ExecutionEngine,functionDeclInIR的Function*
由nativeFunctionInNativeCode在本机代码中表示。您需要提供自己的_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc(aka。ostream :: operator&lt;&lt;)的实现,它使用您的GUI。