Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Additional intrinsics for the NativePtr module #200

Closed
baronfel opened this issue Oct 20, 2016 · 8 comments
Closed

Additional intrinsics for the NativePtr module #200

baronfel opened this issue Oct 20, 2016 · 8 comments

Comments

@baronfel
Copy link
Contributor

baronfel commented Oct 20, 2016

RFC: https://github.com/fsharp/fslang-design/blob/main/preview/FS-1109-Additional-intrinsics-for-the-NativePtr-module.md

Additional intrinsics for the NativePtr module [5670328]

Submitted by Jack Pappas on 3/23/2014 12:00:00 AM
10 votes on UserVoice prior to migration

When interoperating with native code, it would be handy if the NativePtr module included some additional "intrinsic" functions for taking advantage of low-level IL instructions; specifically, I'd like to be able to use 'cpblk', 'initblk', 'initobj', and 'copyobj'.
It would also be nice to have an easy way of checking for null pointer values.
Example implementation of these functions:

[<RequireQualifiedAccess>]
[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
module NativePtr =
  [<GeneralizableValue>]
  [<NoDynamicInvocation>]
  [<CompiledName("Zero")>]
  let inline zero<'T when 'T : unmanaged> : nativeptr<'T> =
      (# "ldnull" : nativeptr<'T> #)
  
  [<NoDynamicInvocation>]
  [<CompiledName("IsNull")>]
  let inline isNull<'T when 'T : unmanaged> (ptr : nativeptr<'T>) =
      (# "ceq" zero<'T> ptr : bool #)
  
  [<Unverifiable>]
  [<NoDynamicInvocation>]
  [<CompiledName("InitBlockInlined")>]
  let inline initBlock (p : nativeptr<'T>) (value : byte) (size : uint32) =
  (# "initblk" p value size #)
  
  [<Unverifiable>]
  [<NoDynamicInvocation>]
  [<CompiledName("CopyBlockInlined")>]
  let inline memcpy (destPtr : nativeptr<'T>) (srcPtr : nativeptr<'T>) (count : int) =
      (# "cpblk" destPtr srcPtr (count \* sizeof<'T>) #)
  
  [<Unverifiable>]
  [<NoDynamicInvocation>]
  [<CompiledName("InitPointerInlined")>]
  let inline clear (p : nativeptr<'T>) =
      (# "initobj !0" type ('T) p #)
  
  [<Unverifiable>]
  [<NoDynamicInvocation>]
  [<CompiledName("CopyPointerInlined")>]
  let inline copy (destPtr : nativeptr<'T>) (srcPtr : nativeptr<'T>) =
      (# "copyobj !0" type ('T) destPtr srcPtr #)
  

Response

** by fslang-admin on 11/8/2014 12:00:00 AM **

I’m marking this as “approved” for F# 4.0+.
A pull request for this feature has been submitted here:
https://visualfsharp.codeplex.com/SourceControl/network/forks/jackpappas/fsharpcontrib/contribution/7134
Thanks
Don, F# Language Design

Original UserVoice Submission
Archived Uservoice Comments

@Happypig375
Copy link
Contributor

I'll add two functions to this list:

        [<Unverifiable>]
        [<CompiledName("OfIlSigPtrInlined")>]
        /// <summary>Returns a typed native pointer for an IL (Intermediate Language) signature pointer.</summary>
        ///
        /// <param name="address">The IL signature pointer.</param>
        ///
        /// <returns>A typed pointer.</returns>
        val inline ofIlSigPtr : address: ilsigptr<'T> -> nativeptr<'T>

        [<Unverifiable>]
        [<CompiledName("ToIlSigPtrInlined")>]
        /// <summary>Returns an IL (Intermediate Language) signature pointer for a given typed pointer.</summary>
        ///
        /// <param name="address">The pointer address.</param>
        ///
        /// <returns>An IL signature pointer.</returns>
        val inline toIlSigPtr : address: nativeptr<'T> -> ilsigptr<'T>

These two functions are also important because of interoperability with C#. C# pointers are CIL signature pointers, but the only way to specify them in F# currently is through ilsigptr<'T>. Although the use of CIL pointers will interfere with piping and other F# features, this is the only way to show correct signatures to C#.

@Happypig375
Copy link
Contributor

Surprisingly CIL pointers do not interfere with piping. This would make exposing correct pointer signatures to C# more convenient.

@dsyme
Copy link
Collaborator

dsyme commented Jun 16, 2021

We basically marked this as approved for F# 4.0 and an implementation was started but not integrated

I'll mark it as approved now. ilsigptr is a bit of an oddity and we'd need to make sure it makes sense to use in this way, I think it will be ok

@Happypig375
Copy link
Contributor

The .NET Runtime has no problem supporting conversion from byref to voidptr: https://github.com/dotnet/runtime/blob/main/src/libraries/System.Runtime.CompilerServices.Unsafe/ref/System.Runtime.CompilerServices.Unsafe.cs

For consistency, F# should add NativePtr.ofByRef as well.

@dsyme
Copy link
Collaborator

dsyme commented Jul 6, 2021

The .NET Runtime has no problem supporting conversion from byref to voidptr: https://github.com/dotnet/runtime/blob/main/src/libraries/System.Runtime.CompilerServices.Unsafe/ref/System.Runtime.CompilerServices.Unsafe.cs

The problem is that this is very, very unsafe, and the right way is to pin. I don't think we should allow managed pointer --> native pointer in FSharp.Core, especially if underlying .NET Core methods are available anyway

@dsyme
Copy link
Collaborator

dsyme commented Jul 13, 2021

@dsyme
Copy link
Collaborator

dsyme commented Sep 25, 2021

This has been completed (will be in F# 6.0)

@dsyme dsyme closed this as completed Sep 25, 2021
@abelbraaksma abelbraaksma mentioned this issue Aug 30, 2022
5 tasks
@abelbraaksma
Copy link
Member

abelbraaksma commented Aug 30, 2022

It may be a year later now, but I totally missed this in the "What's new" series a while ago, or maybe it was glanced over. Either way, I used to have a lot of pain getting my pointers together. This reminds me of the delegate* discussion, I now see why you suggested over there to use nativeptr (see #934 (comment)).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants