lowlevel isUnique

This commit is contained in:
J.Teeuwissen 2023-04-26 17:23:10 +02:00
parent 2435bdb41a
commit ed46a1f2cb
No known key found for this signature in database
GPG key ID: DB5F7A1ED8D478AD
8 changed files with 28 additions and 1 deletions

View file

@ -174,6 +174,7 @@ comptime {
exportUtilsFn(utils.test_panic, "test_panic"); exportUtilsFn(utils.test_panic, "test_panic");
exportUtilsFn(utils.increfC, "incref"); exportUtilsFn(utils.increfC, "incref");
exportUtilsFn(utils.decrefC, "decref"); exportUtilsFn(utils.decrefC, "decref");
exportUtilsFn(utils.isUnique, "is_unique");
exportUtilsFn(utils.decrefCheckNullC, "decref_check_null"); exportUtilsFn(utils.decrefCheckNullC, "decref_check_null");
exportUtilsFn(utils.allocateWithRefcountC, "allocate_with_refcount"); exportUtilsFn(utils.allocateWithRefcountC, "allocate_with_refcount");

View file

@ -231,6 +231,22 @@ inline fn decref_ptr_to_refcount(
} }
} }
pub export fn isUnique(
bytes_or_null: ?[*]u8,
) bool {
var bytes = bytes_or_null orelse return true;
const ptr = @ptrToInt(bytes);
const tag_mask: usize = if (@sizeOf(usize) == 8) 0b111 else 0b11;
const masked_ptr = ptr & ~tag_mask;
const isizes: [*]isize = @intToPtr([*]isize, masked_ptr);
const refcount = (isizes - 1)[0];
return refcount == REFCOUNT_ONE_ISIZE;
}
// We follow roughly the [fbvector](https://github.com/facebook/folly/blob/main/folly/docs/FBVector.md) when it comes to growing a RocList. // We follow roughly the [fbvector](https://github.com/facebook/folly/blob/main/folly/docs/FBVector.md) when it comes to growing a RocList.
// Here is [their growth strategy](https://github.com/facebook/folly/blob/3e0525988fd444201b19b76b390a5927c15cb697/folly/FBVector.h#L1128) for push_back: // Here is [their growth strategy](https://github.com/facebook/folly/blob/3e0525988fd444201b19b76b390a5927c15cb697/folly/FBVector.h#L1128) for push_back:
// //

View file

@ -377,6 +377,7 @@ pub const UTILS_TEST_PANIC: &str = "roc_builtins.utils.test_panic";
pub const UTILS_ALLOCATE_WITH_REFCOUNT: &str = "roc_builtins.utils.allocate_with_refcount"; pub const UTILS_ALLOCATE_WITH_REFCOUNT: &str = "roc_builtins.utils.allocate_with_refcount";
pub const UTILS_INCREF: &str = "roc_builtins.utils.incref"; pub const UTILS_INCREF: &str = "roc_builtins.utils.incref";
pub const UTILS_DECREF: &str = "roc_builtins.utils.decref"; pub const UTILS_DECREF: &str = "roc_builtins.utils.decref";
pub const UTILS_IS_UNIQUE: &str = "roc_builtins.utils.is_unique";
pub const UTILS_DECREF_CHECK_NULL: &str = "roc_builtins.utils.decref_check_null"; pub const UTILS_DECREF_CHECK_NULL: &str = "roc_builtins.utils.decref_check_null";
pub const UTILS_EXPECT_FAILED_START_SHARED_BUFFER: &str = pub const UTILS_EXPECT_FAILED_START_SHARED_BUFFER: &str =

View file

@ -87,6 +87,7 @@ macro_rules! map_symbol_to_lowlevel_and_arity {
LowLevel::PtrCast => unimplemented!(), LowLevel::PtrCast => unimplemented!(),
LowLevel::RefCountInc => unimplemented!(), LowLevel::RefCountInc => unimplemented!(),
LowLevel::RefCountDec => unimplemented!(), LowLevel::RefCountDec => unimplemented!(),
LowLevel::RefCountIsUnique => unimplemented!(),
// these are not implemented, not sure why // these are not implemented, not sure why
LowLevel::StrFromInt => unimplemented!(), LowLevel::StrFromInt => unimplemented!(),

View file

@ -1251,6 +1251,11 @@ pub(crate) fn run_low_level<'a, 'ctx, 'env>(
unreachable!("Not used in LLVM backend: {:?}", op); unreachable!("Not used in LLVM backend: {:?}", op);
} }
RefCountIsUnique => {
arguments!(input);
call_bitcode_fn(env, &[input], &bitcode::UTILS_IS_UNIQUE)
}
Unreachable => match RocReturn::from_layout(env, layout_interner, layout) { Unreachable => match RocReturn::from_layout(env, layout_interner, layout) {
RocReturn::Return => { RocReturn::Return => {
let basic_type = basic_type_from_layout(env, layout_interner, layout); let basic_type = basic_type_from_layout(env, layout_interner, layout);

View file

@ -1949,6 +1949,7 @@ impl<'a> LowLevelCall<'a> {
} }
RefCountInc => self.load_args_and_call_zig(backend, bitcode::UTILS_INCREF), RefCountInc => self.load_args_and_call_zig(backend, bitcode::UTILS_INCREF),
RefCountDec => self.load_args_and_call_zig(backend, bitcode::UTILS_DECREF), RefCountDec => self.load_args_and_call_zig(backend, bitcode::UTILS_DECREF),
RefCountIsUnique => self.load_args_and_call_zig(backend, bitcode::UTILS_IS_UNIQUE),
PtrCast => { PtrCast => {
let code_builder = &mut backend.code_builder; let code_builder = &mut backend.code_builder;

View file

@ -117,6 +117,7 @@ pub enum LowLevel {
PtrCast, PtrCast,
RefCountInc, RefCountInc,
RefCountDec, RefCountDec,
RefCountIsUnique,
BoxExpr, BoxExpr,
UnboxExpr, UnboxExpr,
Unreachable, Unreachable,
@ -221,6 +222,7 @@ macro_rules! map_symbol_to_lowlevel {
LowLevel::PtrCast => unimplemented!(), LowLevel::PtrCast => unimplemented!(),
LowLevel::RefCountInc => unimplemented!(), LowLevel::RefCountInc => unimplemented!(),
LowLevel::RefCountDec => unimplemented!(), LowLevel::RefCountDec => unimplemented!(),
LowLevel::RefCountIsUnique => unimplemented!(),
// these are not implemented, not sure why // these are not implemented, not sure why
LowLevel::StrFromInt => unimplemented!(), LowLevel::StrFromInt => unimplemented!(),

View file

@ -1031,7 +1031,7 @@ pub fn lowlevel_borrow_signature(arena: &Bump, op: LowLevel) -> &[Ownership] {
unreachable!("These lowlevel operations are turned into mono Expr's") unreachable!("These lowlevel operations are turned into mono Expr's")
} }
PtrCast | RefCountInc | RefCountDec => { PtrCast | RefCountInc | RefCountDec | RefCountIsUnique => {
unreachable!("Only inserted *after* borrow checking: {:?}", op); unreachable!("Only inserted *after* borrow checking: {:?}", op);
} }
} }