Auto merge of #113162 - matthiaskrgr:rollup-fct3wj7, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - #111322 (Support for native WASM exceptions) - #112086 (resolve: Remove artificial import ambiguity errors) - #112234 (refactor `tool_doc!`) - #112300 (Convert `run-make/coverage-reports` tests to use a custom compiletest mode) - #112795 (Migrate some rustc_builtin_macros to SessionDiagnostic) - #113144 (Make the `Elaboratable` trait take clauses) - #113161 (Fix type privacy lints error message) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
97279e91d8
171 changed files with 1053 additions and 790 deletions
|
@ -8,7 +8,7 @@ use crate::llvm_util;
|
|||
use crate::type_::Type;
|
||||
use crate::value::Value;
|
||||
|
||||
use rustc_codegen_ssa::base::wants_msvc_seh;
|
||||
use rustc_codegen_ssa::base::{wants_msvc_seh, wants_wasm_eh};
|
||||
use rustc_codegen_ssa::traits::*;
|
||||
use rustc_data_structures::base_n;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
|
@ -532,19 +532,28 @@ impl<'ll, 'tcx> MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
|||
if let Some(llpersonality) = self.eh_personality.get() {
|
||||
return llpersonality;
|
||||
}
|
||||
|
||||
let name = if wants_msvc_seh(self.sess()) {
|
||||
Some("__CxxFrameHandler3")
|
||||
} else if wants_wasm_eh(self.sess()) {
|
||||
// LLVM specifically tests for the name of the personality function
|
||||
// There is no need for this function to exist anywhere, it will
|
||||
// not be called. However, its name has to be "__gxx_wasm_personality_v0"
|
||||
// for native wasm exceptions.
|
||||
Some("__gxx_wasm_personality_v0")
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let tcx = self.tcx;
|
||||
let llfn = match tcx.lang_items().eh_personality() {
|
||||
Some(def_id) if !wants_msvc_seh(self.sess()) => self.get_fn_addr(
|
||||
Some(def_id) if name.is_none() => self.get_fn_addr(
|
||||
ty::Instance::resolve(tcx, ty::ParamEnv::reveal_all(), def_id, ty::List::empty())
|
||||
.unwrap()
|
||||
.unwrap(),
|
||||
),
|
||||
_ => {
|
||||
let name = if wants_msvc_seh(self.sess()) {
|
||||
"__CxxFrameHandler3"
|
||||
} else {
|
||||
"rust_eh_personality"
|
||||
};
|
||||
let name = name.unwrap_or("rust_eh_personality");
|
||||
if let Some(llfn) = self.get_declared_value(name) {
|
||||
llfn
|
||||
} else {
|
||||
|
@ -662,6 +671,10 @@ impl<'ll> CodegenCx<'ll, '_> {
|
|||
let t_f32 = self.type_f32();
|
||||
let t_f64 = self.type_f64();
|
||||
let t_metadata = self.type_metadata();
|
||||
let t_token = self.type_token();
|
||||
|
||||
ifn!("llvm.wasm.get.exception", fn(t_token) -> i8p);
|
||||
ifn!("llvm.wasm.get.ehselector", fn(t_token) -> t_i32);
|
||||
|
||||
ifn!("llvm.wasm.trunc.unsigned.i32.f32", fn(t_f32) -> t_i32);
|
||||
ifn!("llvm.wasm.trunc.unsigned.i32.f64", fn(t_f64) -> t_i32);
|
||||
|
|
|
@ -7,7 +7,7 @@ use crate::type_of::LayoutLlvmExt;
|
|||
use crate::va_arg::emit_va_arg;
|
||||
use crate::value::Value;
|
||||
|
||||
use rustc_codegen_ssa::base::{compare_simd_types, wants_msvc_seh};
|
||||
use rustc_codegen_ssa::base::{compare_simd_types, wants_msvc_seh, wants_wasm_eh};
|
||||
use rustc_codegen_ssa::common::{IntPredicate, TypeKind};
|
||||
use rustc_codegen_ssa::errors::{ExpectedPointerMutability, InvalidMonomorphization};
|
||||
use rustc_codegen_ssa::mir::operand::OperandRef;
|
||||
|
@ -452,6 +452,8 @@ fn try_intrinsic<'ll>(
|
|||
bx.store(bx.const_i32(0), dest, ret_align);
|
||||
} else if wants_msvc_seh(bx.sess()) {
|
||||
codegen_msvc_try(bx, try_func, data, catch_func, dest);
|
||||
} else if wants_wasm_eh(bx.sess()) {
|
||||
codegen_wasm_try(bx, try_func, data, catch_func, dest);
|
||||
} else if bx.sess().target.os == "emscripten" {
|
||||
codegen_emcc_try(bx, try_func, data, catch_func, dest);
|
||||
} else {
|
||||
|
@ -610,6 +612,80 @@ fn codegen_msvc_try<'ll>(
|
|||
bx.store(ret, dest, i32_align);
|
||||
}
|
||||
|
||||
// WASM's definition of the `rust_try` function.
|
||||
fn codegen_wasm_try<'ll>(
|
||||
bx: &mut Builder<'_, 'll, '_>,
|
||||
try_func: &'ll Value,
|
||||
data: &'ll Value,
|
||||
catch_func: &'ll Value,
|
||||
dest: &'ll Value,
|
||||
) {
|
||||
let (llty, llfn) = get_rust_try_fn(bx, &mut |mut bx| {
|
||||
bx.set_personality_fn(bx.eh_personality());
|
||||
|
||||
let normal = bx.append_sibling_block("normal");
|
||||
let catchswitch = bx.append_sibling_block("catchswitch");
|
||||
let catchpad = bx.append_sibling_block("catchpad");
|
||||
let caught = bx.append_sibling_block("caught");
|
||||
|
||||
let try_func = llvm::get_param(bx.llfn(), 0);
|
||||
let data = llvm::get_param(bx.llfn(), 1);
|
||||
let catch_func = llvm::get_param(bx.llfn(), 2);
|
||||
|
||||
// We're generating an IR snippet that looks like:
|
||||
//
|
||||
// declare i32 @rust_try(%try_func, %data, %catch_func) {
|
||||
// %slot = alloca i8*
|
||||
// invoke %try_func(%data) to label %normal unwind label %catchswitch
|
||||
//
|
||||
// normal:
|
||||
// ret i32 0
|
||||
//
|
||||
// catchswitch:
|
||||
// %cs = catchswitch within none [%catchpad] unwind to caller
|
||||
//
|
||||
// catchpad:
|
||||
// %tok = catchpad within %cs [null]
|
||||
// %ptr = call @llvm.wasm.get.exception(token %tok)
|
||||
// %sel = call @llvm.wasm.get.ehselector(token %tok)
|
||||
// call %catch_func(%data, %ptr)
|
||||
// catchret from %tok to label %caught
|
||||
//
|
||||
// caught:
|
||||
// ret i32 1
|
||||
// }
|
||||
//
|
||||
let try_func_ty = bx.type_func(&[bx.type_i8p()], bx.type_void());
|
||||
bx.invoke(try_func_ty, None, None, try_func, &[data], normal, catchswitch, None);
|
||||
|
||||
bx.switch_to_block(normal);
|
||||
bx.ret(bx.const_i32(0));
|
||||
|
||||
bx.switch_to_block(catchswitch);
|
||||
let cs = bx.catch_switch(None, None, &[catchpad]);
|
||||
|
||||
bx.switch_to_block(catchpad);
|
||||
let null = bx.const_null(bx.type_i8p());
|
||||
let funclet = bx.catch_pad(cs, &[null]);
|
||||
|
||||
let ptr = bx.call_intrinsic("llvm.wasm.get.exception", &[funclet.cleanuppad()]);
|
||||
let _sel = bx.call_intrinsic("llvm.wasm.get.ehselector", &[funclet.cleanuppad()]);
|
||||
|
||||
let catch_ty = bx.type_func(&[bx.type_i8p(), bx.type_i8p()], bx.type_void());
|
||||
bx.call(catch_ty, None, None, catch_func, &[data, ptr], Some(&funclet));
|
||||
bx.catch_ret(&funclet, caught);
|
||||
|
||||
bx.switch_to_block(caught);
|
||||
bx.ret(bx.const_i32(1));
|
||||
});
|
||||
|
||||
// Note that no invoke is used here because by definition this function
|
||||
// can't panic (that's what it's catching).
|
||||
let ret = bx.call(llty, None, None, llfn, &[try_func, data, catch_func], None);
|
||||
let i32_align = bx.tcx().data_layout.i32_align.abi;
|
||||
bx.store(ret, dest, i32_align);
|
||||
}
|
||||
|
||||
// Definition of the standard `try` function for Rust using the GNU-like model
|
||||
// of exceptions (e.g., the normal semantics of LLVM's `landingpad` and `invoke`
|
||||
// instructions).
|
||||
|
|
|
@ -1071,6 +1071,7 @@ extern "C" {
|
|||
|
||||
// Operations on other types
|
||||
pub fn LLVMVoidTypeInContext(C: &Context) -> &Type;
|
||||
pub fn LLVMTokenTypeInContext(C: &Context) -> &Type;
|
||||
pub fn LLVMMetadataTypeInContext(C: &Context) -> &Type;
|
||||
|
||||
// Operations on all values
|
||||
|
|
|
@ -52,6 +52,10 @@ impl<'ll> CodegenCx<'ll, '_> {
|
|||
unsafe { llvm::LLVMVoidTypeInContext(self.llcx) }
|
||||
}
|
||||
|
||||
pub(crate) fn type_token(&self) -> &'ll Type {
|
||||
unsafe { llvm::LLVMTokenTypeInContext(self.llcx) }
|
||||
}
|
||||
|
||||
pub(crate) fn type_metadata(&self) -> &'ll Type {
|
||||
unsafe { llvm::LLVMMetadataTypeInContext(self.llcx) }
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue