Skip to content

Commit 7d201ae

Browse files
committed
Added support for TerminatorKind::Assert
1 parent b278e2e commit 7d201ae

File tree

13 files changed

+144
-46
lines changed

13 files changed

+144
-46
lines changed

bin/c_success_coretests.txt

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,6 @@ cell::refcell_unsized
131131
cell::smoketest_cell
132132
cell::smoketest_unsafe_cell
133133
cell::unsafe_cell_raw_get
134-
cell::unsafe_cell_unsized
135134
char::ed_iterator_specializations
136135
char::eu_iterator_specializations
137136
char::test_convert
@@ -666,7 +665,6 @@ num::bignum::test_mul_digits
666665
num::bignum::test_mul_pow2
667666
num::bignum::test_mul_pow2_overflow_1
668667
num::bignum::test_mul_pow5
669-
num::bignum::test_mul_pow5_overflow_1
670668
num::bignum::test_mul_small
671669
num::bignum::test_ord
672670
num::bignum::test_sub
@@ -741,7 +739,6 @@ num::i128::test_le
741739
num::i128::test_leading_trailing_ones
742740
num::i128::test_midpoint
743741
num::i128::test_next_multiple_of
744-
num::i128::test_num
745742
num::i128::test_overflows
746743
num::i128::test_rem_euclid
747744
num::i128::test_rotate
@@ -902,7 +899,6 @@ num::int_log::checked_ilog10
902899
num::int_log::checked_ilog2
903900
num::int_log::ilog0_of_1_panic
904901
num::int_log::ilog10_of_0_panic
905-
num::int_log::ilog10_u128
906902
num::int_log::ilog10_u16
907903
num::int_log::ilog10_u32
908904
num::int_log::ilog10_u64
@@ -946,7 +942,6 @@ num::ops::test_bitxor_assign_defined
946942
num::ops::test_bitxor_defined
947943
num::ops::test_div_assign_defined
948944
num::ops::test_div_defined
949-
num::ops::test_mul_assign_defined
950945
num::ops::test_mul_defined
951946
num::ops::test_neg_defined
952947
num::ops::test_not_defined_bool
@@ -1166,10 +1161,8 @@ num::u128::test_isolate_most_significant_one
11661161
num::u128::test_isqrt
11671162
num::u128::test_le
11681163
num::u128::test_leading_trailing_ones
1169-
num::u128::test_lots_of_isqrt
11701164
num::u128::test_midpoint
11711165
num::u128::test_next_multiple_of
1172-
num::u128::test_num
11731166
num::u128::test_overflows
11741167
num::u128::test_reverse_bits
11751168
num::u128::test_rotate
@@ -1463,7 +1456,6 @@ slice::memchr::no_match
14631456
slice::memchr::no_match_empty
14641457
slice::memchr::no_match_empty_reversed
14651458
slice::memchr::no_match_reversed
1466-
slice::select_nth_unstable
14671459
slice::select_nth_unstable_past_length
14681460
slice::select_nth_unstable_zero_length
14691461
slice::slice_index::assert_range_eq_can_fail_by_inequality

cilly/src/bin/linker/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,7 @@ fn main() {
436436
cilly::builtins::insert_bounds_check(&mut final_assembly, &mut overrides);
437437
cilly::builtins::casts::insert_casts(&mut final_assembly, &mut overrides);
438438
cilly::builtins::insert_heap(&mut final_assembly, &mut overrides, *C_MODE);
439+
cilly::builtins::rust_assert(&mut final_assembly, &mut overrides);
439440
cilly::builtins::int128::generate_int128_ops(&mut final_assembly, &mut overrides, *C_MODE);
440441
cilly::builtins::int128::i128_mul_ovf_check(&mut final_assembly, &mut overrides);
441442
cilly::builtins::int128::u128_mul_ovf_check(&mut final_assembly, &mut overrides);

cilly/src/v2/builtins/mod.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,29 @@ fn insert_pause(asm: &mut Assembly, patcher: &mut MissingMethodPatcher) {
476476
};
477477
patcher.insert(name, Box::new(generator));
478478
}
479+
pub fn rust_assert(asm: &mut Assembly, patcher: &mut MissingMethodPatcher) {
480+
let name = asm.alloc_string("rust_assert");
481+
let generator = move |_, asm: &mut Assembly| {
482+
let ret = asm.alloc_root(CILRoot::VoidRet);
483+
let assert = asm.alloc_node(CILNode::LdArg(0));
484+
let assert = asm.alloc_root(CILRoot::Branch(Box::new((
485+
1,
486+
0,
487+
Some(BranchCond::False(assert)),
488+
))));
489+
let mref = MethodRefIdx::abort(asm);
490+
let assert_failed = asm.alloc_root(CILRoot::call(mref, vec![]));
491+
MethodImpl::MethodBody {
492+
blocks: vec![
493+
BasicBlock::new(vec![assert, ret], 0, None),
494+
BasicBlock::new(vec![assert_failed, ret], 1, None),
495+
],
496+
locals: vec![],
497+
}
498+
};
499+
patcher.insert(name, Box::new(generator));
500+
}
501+
479502
fn insert_catch_unwind_stub(asm: &mut Assembly, patcher: &mut MissingMethodPatcher) {
480503
let name = asm.alloc_string("catch_unwind");
481504
let generator = move |_, asm: &mut Assembly| {

cilly/src/v2/c_exporter/c_header.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -376,11 +376,11 @@ static inline int32_t System_Numerics_BitOperations_LeadingZeroCountu64i32(uint6
376376
static inline int32_t System_Numerics_BitOperations_LeadingZeroCountusizei32(uintptr_t val) { if (val == 0) return sizeof(uintptr_t) * 8; return __builtin_clzl((uint64_t)val); }
377377
#endif
378378

379-
#define System_Numerics_BitOperations_PopCountusizei32(val) __builtin_popcountl((uint64_t)val)
380-
#define System_Numerics_BitOperations_PopCountu32i32(val) __builtin_popcountl((uint32_t)val)
381-
#define System_Numerics_BitOperations_PopCountu64i32(val) __builtin_popcountl((uint64_t)val)
379+
#define System_Numerics_BitOperations_PopCountusizei32(val) __builtin_popcountll((uint64_t)val)
380+
#define System_Numerics_BitOperations_PopCountu32i32(val) __builtin_popcountll((uint32_t)val)
381+
#define System_Numerics_BitOperations_PopCountu64i32(val) __builtin_popcountll((uint64_t)val)
382382
static inline __uint128_t System_UInt128_PopCountu128u128(__uint128_t val) {
383-
return __builtin_popcountl((uint64_t)val) + __builtin_popcountl((uint64_t)(val>>64));
383+
return __builtin_popcountll((uint64_t)val) + __builtin_popcountll((uint64_t)(val>>64));
384384
}
385385

386386
#define System_Console_WriteLinev() printf("\n")

cilly/src/v2/cilnode.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,32 @@ impl IsPure {
2626
}
2727
#[derive(Hash, PartialEq, Eq, Clone, Debug, Serialize, Deserialize)]
2828
pub enum CILNode {
29+
/// A constant IR value.
2930
Const(Box<Const>),
31+
/// Binary operation performed on values `lhs` and `rhs`, of kind `op`.
3032
BinOp(NodeIdx, NodeIdx, BinOp),
33+
/// A unary operation performed on value `val`, of kind `op`.
3134
UnOp(NodeIdx, UnOp),
35+
/// Retrives the value of a local with a given index.
3236
LdLoc(u32),
37+
/// Retrives a reference(not a pointer!) to a local with a given index.
38+
/// See [crate::tpe::Type::Ref].
3339
LdLocA(u32),
40+
/// Retrives the value of an argument with a given index.
3441
LdArg(u32),
42+
/// Retrives a reference(not a pointer!) to an argument with a given index.
43+
/// See [crate::tpe::Type::Ref].
3544
LdArgA(u32),
36-
/// Method, args, pure
45+
/// Calls `method` with, `args`, and a given `pure`-ness.
46+
/// [`IsPure::PURE`] value marks a call as a pure, side-effect free call.
3747
Call(Box<(MethodRefIdx, Box<[NodeIdx]>, IsPure)>),
48+
/// A cast to an intiger type.
3849
IntCast {
50+
/// The input value.
3951
input: NodeIdx,
52+
/// The resulting type
4053
target: Int,
54+
/// Is this a signed or zero extension?
4155
extend: ExtendKind,
4256
},
4357
FloatCast {

cilly/src/v2/cst.rs

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,27 +6,47 @@ use super::{
66
};
77

88
#[derive(PartialEq, Eq, Copy, Clone, Debug, Hash, Serialize, Deserialize)]
9+
/// A constant cillyIR value.
910
pub enum Const {
11+
/// Constant i8 value.
1012
I8(i8),
13+
/// Constant i16 value.
1114
I16(i16),
15+
/// Constant i32 value.
1216
I32(i32),
17+
/// Constant i64 value.
1318
I64(i64),
19+
/// Constant i128 value.
1420
I128(i128),
21+
/// Constant isize value.
1522
ISize(i64),
23+
/// Constant u8 value.
1624
U8(u8),
25+
/// Constant u16 value.
1726
U16(u16),
27+
/// Constant u32 value.
1828
U32(u32),
29+
/// Constant u64 value.
1930
U64(u64),
31+
/// Constant u128 value.
2032
U128(u128),
33+
/// Constant usize value.
2134
USize(u64),
35+
/// A reference to an immutable, platform-specific representation of a string.
36+
/// There is no guarrantees about the encoding of this type.
2237
PlatformString(StringIdx),
38+
/// A boolean value
2339
Bool(bool),
40+
/// A representation of a single-precision floating-point value. No guarateess are given about the exact bitpattern of NaNs.
2441
F32(HashableF32),
42+
/// A representation of a double-precision floating-point value. No guarateess are given about the exact bitpattern of NaNs.
2543
F64(HashableF64),
44+
/// A "null" reference to a platform-specifc managed object of type `class`.
2645
Null(ClassRefIdx),
2746
}
2847
impl Const {
29-
pub(crate) fn get_type(&self) -> Type {
48+
/// Retrives the type of this value.
49+
pub fn get_type(&self) -> Type {
3050
match self {
3151
Const::I8(_) => Type::Int(Int::I8),
3252
Const::I16(_) => Type::Int(Int::I16),
@@ -47,8 +67,8 @@ impl Const {
4767
Const::Null(tpe) => Type::ClassRef(*tpe),
4868
}
4969
}
50-
51-
pub(crate) fn is_zero(&self) -> bool {
70+
/// Checks if the value is zero.
71+
pub fn is_zero(&self) -> bool {
5272
match self {
5373
Const::I8(val) => *val == 0,
5474
Const::I16(val) => *val == 0,
@@ -69,7 +89,8 @@ impl Const {
6989
Const::Null(_) => true,
7090
}
7191
}
72-
pub(crate) fn is_one(&self) -> bool {
92+
/// Checks if the value is exactly one.
93+
pub fn is_one(&self) -> bool {
7394
match self {
7495
Const::I8(val) => *val == 1,
7596
Const::I16(val) => *val == 1,
@@ -85,8 +106,8 @@ impl Const {
85106
Const::USize(val) => *val == 1,
86107
Const::PlatformString(_) => false,
87108
Const::Bool(_) => false,
88-
Const::F32(val) => **val == 1.1,
89-
Const::F64(val) => **val == 1.1,
109+
Const::F32(val) => **val == 1.0,
110+
Const::F64(val) => **val == 1.0,
90111
Const::Null(_) => true,
91112
}
92113
}

cilly/src/v2/method.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -742,7 +742,6 @@ impl MethodImpl {
742742
let args = sig
743743
.inputs()
744744
.iter()
745-
746745
.enumerate()
747746
.map(|(idx, _)| asm.alloc_node(CILNode::LdArg(idx.try_into().unwrap())))
748747
.collect();
@@ -787,6 +786,12 @@ impl MethodRefIdx {
787786
pub unsafe fn from_raw(raw: BiMapIndex) -> Self {
788787
Self(raw)
789788
}
789+
790+
pub fn abort(asm: &mut Assembly) -> MethodRefIdx {
791+
let main = asm.main_module();
792+
let sig = asm.sig([], Type::Void);
793+
asm.new_methodref(*main, "abort", sig, MethodKind::Static, vec![])
794+
}
790795
}
791796
#[test]
792797
fn locals() {

rustc_codegen_clr_place/src/adress.rs

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ use cilly::{
88
};
99
use rustc_codegen_clr_ctx::MethodCompileCtx;
1010
use rustc_codegen_clr_type::{
11-
adt::{enum_field_descriptor, field_descrptor, FieldOffsetIterator}, r#type::{fat_ptr_to, get_type}, GetTypeExt
11+
GetTypeExt,
12+
adt::{FieldOffsetIterator, enum_field_descriptor, field_descrptor},
13+
r#type::{fat_ptr_to, get_type},
1214
};
1315
use rustc_middle::{
1416
mir::PlaceElem,
@@ -226,10 +228,13 @@ pub fn place_elem_adress<'tcx>(
226228
}
227229
}
228230
PlaceElem::Subslice { from, to, from_end } => {
229-
let elem_type = curr_type.as_ty().expect("Can't index into an enum!").sequence_element_type(ctx.tcx());
230-
let elem_type = get_type(elem_type,ctx);
231+
let elem_type = curr_type
232+
.as_ty()
233+
.expect("Can't index into an enum!")
234+
.sequence_element_type(ctx.tcx());
235+
let elem_type = get_type(elem_type, ctx);
231236
let curr_type = fat_ptr_to(curr_type.as_ty().expect("Can't index into an enum!"), ctx);
232-
237+
233238
if *from_end {
234239
//assert!(from >= to, "from_end:{from_end} from:{from} to:{to}");
235240
let metadata_name = ctx.alloc_string(cilly::METADATA);
@@ -248,8 +253,13 @@ pub fn place_elem_adress<'tcx>(
248253
Box::new(CILNode::V2(ctx.alloc_node(Const::USize(*to + from)))),
249254
);
250255

251-
let data_ptr = ld_field!(addr_calc, ptr_field)
252-
+ CILNode::V2(ctx.alloc_node(Const::USize(*from))) * conv_usize!(CILNode::V2(ctx.size_of(elem_type).into_idx(ctx)));
256+
let data_ptr = if elem_type != Type::Void {
257+
ld_field!(addr_calc, ptr_field)
258+
+ CILNode::V2(ctx.alloc_node(Const::USize(*from)))
259+
* conv_usize!(CILNode::V2(ctx.size_of(elem_type).into_idx(ctx)))
260+
} else {
261+
ld_field!(addr_calc, ptr_field)
262+
};
253263
CILNode::create_slice(curr_type, ctx, metadata, data_ptr)
254264
} else {
255265
let void_ptr = ctx.nptr(Type::Void);
@@ -258,7 +268,8 @@ pub fn place_elem_adress<'tcx>(
258268
let ptr_field = ctx.alloc_field(FieldDesc::new(curr_type, data_ptr, void_ptr));
259269
let metadata = CILNode::V2(ctx.alloc_node(Const::USize(to - from)));
260270
let data_ptr = ld_field!(addr_calc, ptr_field)
261-
+ CILNode::V2(ctx.alloc_node(Const::USize(*from))) * conv_usize!(CILNode::V2(ctx.size_of(elem_type).into_idx(ctx)));
271+
+ CILNode::V2(ctx.alloc_node(Const::USize(*from)))
272+
* conv_usize!(CILNode::V2(ctx.size_of(elem_type).into_idx(ctx)));
262273

263274
CILNode::create_slice(curr_type, ctx, metadata, data_ptr)
264275
}

rustc_codegen_clr_type/src/adt.rs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ use cilly::{
44
};
55
use rustc_abi::{FieldIdx, FieldsShape, Layout, LayoutData, VariantIdx, Variants};
66
use rustc_codegen_clr_ctx::MethodCompileCtx;
7+
use rustc_middle::span_bug;
78
use rustc_middle::ty::List;
89
use rustc_middle::ty::{AdtDef, GenericArg, Ty, TyKind};
9-
1010
pub fn enum_variant_offsets(_: AdtDef, layout: Layout, vidix: VariantIdx) -> FieldOffsetIterator {
1111
FieldOffsetIterator::fields(get_variant_at_index(vidix, (*layout.0).clone()))
1212
}
@@ -215,14 +215,20 @@ pub fn field_descrptor<'tcx>(
215215
field_type,
216216
));
217217
} else if let TyKind::Coroutine(_, args) = owner_ty.kind() {
218-
let coroutine = args.as_coroutine();
219-
let field_type = coroutine
220-
.upvar_tys()
218+
let coroutine = args.as_coroutine().witness();
219+
let TyKind::CoroutineWitness(_, fields) = coroutine.kind() else {
220+
panic!("corutine witness is not CoroutineWitness.");
221+
};
222+
let field_type = fields
221223
.iter()
222224
.nth(field_idx as usize)
223225
.expect("Could not find coroutine fields!");
224226
let field_type = ctx.monomorphize(field_type);
225-
let field_type = ctx.type_from_cache(field_type);
227+
let field_type = ctx.type_from_cache(
228+
field_type
229+
.as_type()
230+
.expect("Non type args in coroutine witness."),
231+
);
226232
let owner_ty = ctx.monomorphize(owner_ty);
227233
let owner_type = ctx.type_from_cache(owner_ty);
228234
let field_name = ctx.alloc_string(format!("f_{field_idx}"));

rustc_codgen_clr_operand/src/constant.rs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use cilly::{
1313
use rustc_codegen_clr_call::CallInfo;
1414
use rustc_codegen_clr_ctx::MethodCompileCtx;
1515
use rustc_codegen_clr_place::deref_op;
16-
use rustc_codegen_clr_type::GetTypeExt;
16+
use rustc_codegen_clr_type::{GetTypeExt, utilis::is_fat_ptr};
1717
use rustc_middle::ty::ExistentialTraitRef;
1818
use rustc_middle::{
1919
mir::{
@@ -245,10 +245,20 @@ fn load_const_scalar<'tcx>(
245245
TyKind::Uint(uint_type) => CILNode::V2(load_const_uint(scalar_u128, *uint_type, ctx)),
246246
TyKind::Float(ftype) => load_const_float(scalar_u128, *ftype, ctx),
247247
TyKind::Bool => CILNode::V2(ctx.alloc_node(scalar_u128 != 0)),
248-
TyKind::RawPtr(_, _) => CILNode::V2(ctx.alloc_node(Const::USize(
249-
u64::try_from(scalar_u128).expect("pointers must be smaller than 2^64"),
250-
)))
251-
.cast_ptr(scalar_type),
248+
TyKind::RawPtr(..) | TyKind::Ref(..) => {
249+
if is_fat_ptr(scalar_ty, ctx.tcx(), ctx.instance()) {
250+
CILNode::V2(ctx.alloc_node(scalar_u128)).transmute_on_stack(
251+
Type::Int(Int::U128),
252+
scalar_type,
253+
ctx,
254+
)
255+
} else {
256+
CILNode::V2(ctx.alloc_node(Const::USize(
257+
u64::try_from(scalar_u128).expect("pointers must be smaller than 2^64"),
258+
)))
259+
.cast_ptr(scalar_type)
260+
}
261+
}
252262
TyKind::Tuple(elements) => {
253263
if elements.is_empty() {
254264
let scalar_ptr = ctx.nptr(scalar_type);

src/compile_test.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -806,6 +806,7 @@ run_test! {intrinsics,wrapping_ops,stable}
806806
run_test! {iter,fold,stable}
807807
run_test! {statics,thread_local,stable}
808808
run_test! {std,arg_test,stable}
809+
run_test! {std,getopt,stable}
809810
run_test! {std,const_error,stable}
810811
run_test! {std,cell_test,unstable}
811812
run_test! {std,cstr,unstable}

src/terminator/intrinsics/mod.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1100,7 +1100,6 @@ fn intrinsic_slow<'tcx>(
11001100
"intrinsic {} must be overridden by rustc_codgen_clr, but isn't",
11011101
intrinsic.name,
11021102
);
1103-
todo!("ERROR: span bug did not diverge.");
11041103
}
11051104
super::call::call_inner(
11061105
Instance::new(call_instance.def_id(), call_instance.args)

0 commit comments

Comments
 (0)