2014-10-08 15 views
6

我正在研究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 
+0

不確定是否是你的問題的原因,但'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

+0

另外,我建議避免Rust中現有的LLVM API。它基於LLVM C API,它不像C++ API那樣受到支持,而且完全不安全。您還會發現API的某些部分缺失。對於我正在開發的項目,我正在爲C++類/函數構建自己的安全綁定。這並不難,最終結果更容易使用。 – Dylan 2014-10-09 22:38:44

+0

我知道,但那是一個教程。所以我使用已有的東西。如果存在一些安全的API,我會使用它。關於'with_c_str',我看到沒有理由在這裏使用它。或者可以在調用參數的函數之前將字符串解除分配?無論如何,這與我的問題無關。 – 2014-10-10 11:12:43

回答

4

我有same problem並且可以通過同時運行

LLVMInitializeNativeAsmPrinter(); 
LLVMInitializeNativeAsmParser(); 
解決問題初始化X86Target之後的

。我在lli的源代碼中找到了這個。

相關問題