我正在研究Rust中的LLVM教程。我已經實施了萬花筒REPL的一些部分。它對我很好,但突然停止工作,現在每個嘗試計算一個值都在LLVM ERROR: Target does not support MC emission!
。它似乎發生在Rust編譯器更新到最新的每晚(但我不確定在這裏)之後。「LLVM ERROR:目標不支持MC發射!」是什麼原因?
相關代碼如下。
初始化功能:
#[allow(non_snake_case)]
pub unsafe fn LLVMInitializeNativeTarget() {
llvm::LLVMInitializeX86TargetInfo();
llvm::LLVMInitializeX86Target();
llvm::LLVMInitializeX86TargetMC();
}
模塊創建:
let module = llvm::LLVMModuleCreateWithNameInContext(module_name.to_c_str().as_ptr(), context);
執行引擎創建:
let mut exec_engine = 0 as llvm::ExecutionEngineRef;
let mut error = 0 as *const c_char;
LLVMCreateExecutionEngineForModule(&mut exec_engine, module, &mut error);
assert!(exec_engine != 0 as llvm::ExecutionEngineRef);
彙編和運行的功能:
pub fn run(value: llvm::ValueRef, context: &Context) -> f64 {
unsafe {
let result = LLVMRunFunction(context.exec_engine,
value,
0,
0 as *const GenericValueRef);
let ty = llvm::LLVMDoubleTypeInContext(context.context);
LLVMGenericValueToFloat(ty, result)
}
}
由llvm ::指定的LLVM函數是由rustc導入的,那些不是由llvm ::指定的導入我的代碼,請參閱https://github.com/jauhien/iron-kaleidoscope/blob/master/src/missing_llvm_bindings/mod.rs。
要查看完整的代碼清單,看看https://github.com/jauhien/iron-kaleidoscope/blob/master/src/builder.rs
我使用的是最新的夜間鏽和LLVM 3.5.0。
UPD:在對LLVMInitializeNativeTarget的調用註釋掉後,JIT開始再次工作。但我仍然想知道問題的原因是什麼以及JIT應該如何正確使用。
UPD2:在註釋掉初始化之後,並不是所有東西都重新開始工作:現在調用Rust代碼中定義的函數失敗,出現LLVM ERROR: Tried to execute an unknown external function
。
功能我想調用(這工作之前):
#[no_mangle]
pub extern fn print(x: f64) -> f64 {
println!("> {} <", x);
x
}
舉例會議:
[email protected] iron-repl % ./target/iron_kaleidoscope
>extern print(x)
declare double @print(double)
>print(1)
LLVM ERROR: Tried to execute an unknown external function: print
不確定是否是你的問題的原因,但'module_name.to_c_str()。as_ptr()'是內存不安全。你不能確保C字符串超過指針。請參閱[文檔](http://doc.rust-lang.org/std/str/trait.StrSlice.html#tymethod.as_ptr)。我建議使用['with_c_str'](http://doc.rust-lang.org/std/c_str/trait.ToCStr.html#tymethod.with_c_str)。 – Dylan 2014-10-09 22:30:18
另外,我建議避免Rust中現有的LLVM API。它基於LLVM C API,它不像C++ API那樣受到支持,而且完全不安全。您還會發現API的某些部分缺失。對於我正在開發的項目,我正在爲C++類/函數構建自己的安全綁定。這並不難,最終結果更容易使用。 – Dylan 2014-10-09 22:38:44
我知道,但那是一個教程。所以我使用已有的東西。如果存在一些安全的API,我會使用它。關於'with_c_str',我看到沒有理由在這裏使用它。或者可以在調用參數的函數之前將字符串解除分配?無論如何,這與我的問題無關。 – 2014-10-10 11:12:43