为什么没有“国外进口原药不安全”?

2024-01-23

这是我之前问题的后续here https://stackoverflow.com/questions/41213378/using-foreign-import-prim-with-a-c-function-using-stg-calling-convention。我已经能够得到一些工作里德·巴顿的回答 https://stackoverflow.com/a/41214165/176841,但我注意到我看到的核心__pkg_ccall_GC:

              case {__pkg_ccall_GC hashabler-2.0.0 sipRound_s_x2 Word#
                                          -> Word#
                                          -> Word#
                                          -> Word#
                                          -> (# Word#, Word#, Word#, Word# #)}
                     ww1 ww2 ww3 (xor# ww4 b1)

我认为这就是您对“安全”的 ffi 通话的期望。然而,不允许在外部导入字符串中添加“不安全”(尽管错误消息没有说明原因):

src/Data/Hashabler/SipHash.hs:60:1: error:
    • The safe/unsafe annotation should not be used with `foreign import prim'.
    • When checking declaration:
        foreign import prim unsafe "static sipRound_s_x4" sipRound_s_x4#
          :: Word#
             -> Word# -> Word# -> Word# -> (# Word#, Word#, Word#, Word# #)

我的外国程序只是一点点,但有点麻烦,所以我不认为我想要什么_GC正在给我。我看过的 GHC 源代码的一些相关部分、FWIW 和背景:

compiler/prelude/ForeignCall.hs:只有“Risky”省略了“_GC”

data Safety
  = PlaySafe            -- Might invoke Haskell GC, or do a call back, or
                        -- switch threads, etc.  So make sure things are
                        -- tidy before the call. Additionally, in the threaded
                        -- RTS we arrange for the external call to be executed
                        -- by a separate OS thread, i.e., _concurrently_ to the
                        -- execution of other Haskell threads.

  | PlayInterruptible   -- Like PlaySafe, but additionally
                        -- the worker thread running this foreign call may
                        -- be unceremoniously killed, so it must be scheduled
                        -- on an unbound thread.

  | PlayRisky           -- None of the above can happen; the call will return
                        -- without interacting with the runtime system at all
  deriving ( Eq, Show, Data )
        -- Show used just for Show Lex.Token, I think

我也看到一些foreign import prim unsafe and ... safe在 GHC 树中,尽管我认为它是死代码。例如testsuite/tests/printer/Ppr046.hs.

所以我的问题是:

  1. 从 a 生成的代码有什么区别__pkg_ccall_GC vs a __pkg_ccall在这种情况下(我正在做的地方foreign import prim not ccall)?和描述的一样吗here https://wiki.haskell.org/Foreign_Function_Interface#Unsafe_calls?
  2. 为什么没有foreign import prim unsafe好像支持?
  3. 假设我理解(1):我是否可以解决这个问题,既获得多个值的有效返回,又避免(1)中发生的任何簿记?

EDIT: 从装配体来看-ddump-asm清楚地表明没有发生任何事情(不应该害怕看大会),支持里德·巴顿(Reid Barton)的评论如下:

movq %rdi,%rax
movq %r8,%rdi 
xorq %r9,%rdi
movq %rsi,%rcx
movq %rax,%rsi
movq %r14,%rax
movq %rcx,%r14
movq %rbx,%rcx
movq %rax,%rbx
movq %r9,-8(%rbp)
movq %rcx,(%rbp)
addq $-16,%rbp
jmp sipRound_s_x2

The xorq朝向顶部对应于 haskellxor。所有那些movq虽然看起来确实很无赖……


正如里德·巴顿指出的__pkg_ccall_GC没有表明任何事情。生成的代码不会执行您在safeFFI 电话。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么没有“国外进口原药不安全”? 的相关文章

  • 类型级别集结合律的证明

    我试图证明类型级函数Union https hackage haskell org package type level sets 0 8 5 0 docs Data Type Set html t Union是关联的 但我不确定应该如何完
  • 迭代打印列表中的每个整数

    假设我有一个整数列表l 1 2 我想打印到stdout Doing print l产生 1 2 假设我想打印不带大括号的列表 map print l产生 No instance for Show IO arising from a use
  • 使用带有两个列表而不是一个列表的地图。可以筑巢吗?

    我需要多次运行一个带有两个参数的函数 我有两个包含这些参数的列表 我希望能够使用map或类似的东西用相应的参数调用函数 我要调用的函数具有以下类型 runParseTest String gt String gt IO 列表的创建方式如下
  • Parsec.Expr 具有不同优先级的重复前缀

    Parsec Expr buildExpressionParser 的文档说 相同优先级的前缀和后缀运算符只能出现一次 即 如果 为前缀否定 则不允许使用 2 但是 我想解析这样的字符串 具体来说 考虑以下语法 sentence ident
  • 在 Haskell 中将字符串转换为整数/浮点数?

    data GroceryItem CartItem ItemName Price Quantity StockItem ItemName Price Quantity makeGroceryItem String gt Float gt I
  • 为什么 mod 在表达式中给出的结果与在函数调用中给出的结果不同?

    假设有人想要计算函数 f x y x mod 3 y mod 3 mod 2 那么 如果再展开f 1 0 手动 可以得到 1 mod 3 0 mod 3 mod 2 1 然而 如果使用内联函数 结果是 let f x y x mod 3 y
  • Haskell Fibonacci 达到最大指定数?

    我有一个已启动并正在运行的 Haskell 函数 但它做错了事情 它应该输出最多指定最大数量的斐波那契数列 像这样 fibonacciSequence 86 1 1 2 3 5 8 13 21 33 54 我的代码当前输出斐波那契数列中的前
  • 如何只修改记录的一个字段而不完全重写它? [复制]

    这个问题在这里已经有答案了 It s the second time I m tackling this problem And for the second time this is while working with the Stat
  • 在列表中查找元素及其索引

    我需要让列表的两个元素都满足谓词and这些元素的索引 我可以通过以下方式实现这一点 import Data List findIndices list Int list 3 2 4 1 9 indices findIndices gt 2
  • 为什么我不能声明推断类型?

    我有以下内容 runcount Eq a Num b gt a gt b runcount runcountacc 0 runcountacc Eq a Num b gt b gt a gt b runcountacc n runcount
  • 并行 Haskell - GHC GC 火花

    我有一个正在尝试并行化的程序 带有可运行代码的完整粘贴here http lpaste net 101528 我进行了分析 发现大部分时间都花在findNearest这本质上是一个简单的foldr超过一个大Data Map findNear
  • 从 Golang 调用 C 函数

    我想在 Golang 中编写控制器逻辑并处理 json 和数据库 同时在 C 中使用我的数学处理模型 在我看来 调用 C 函数的开销必须尽可能低 就像设置寄存器 rcx rdx rsi rdi 一样 执行一些操作fastcall 并获取 r
  • 在 Archlinux 上使用 Vim 作为 Haskell 的 IDE 目前情况如何?

    如果可行的话 我的目标是通过 YouCompleteMe 在 Vim 中完成 Haskell 的命令 在这方面 正如您在下面看到的 我还没有找到关于如何让它发挥作用的共识 相关评论的最新评论YouCompleteMe 上的问题 https
  • Haskell Cabal:“包间接依赖于同一包的多个版本”

    清除我的所有后cabal installed 包 我运行了以下会话 cabal update Downloading the latest package list from hackage haskell org james bast c
  • Haskell 为替代的 Either 数据类型定义 Functor 实例

    通过 Typeclassopedia 获得一些使用类型类的路由 想要替代Either的一个实例Functor 但即使检查定义Either作为一个例子Functor总是给我带来麻烦 有这个 但不会编译 data Alt a b Success
  • 使用 Racket FFI 进行快速阵列访问

    我正在尝试在 Racket 中编写 OpenCV FFI 并达到了需要有效操作数组的地步 然而 我所有使用 Racket FFI 访问数组的尝试都会导致代码效率非常低 有没有办法使用 FFI 快速访问 C 数组 在 Racket 中 这种类
  • 在 Haskell 中调试时打印时间戳

    我仍在学习 Haskell 并调试一些函数 并且通常有一个时间戳函数来了解某些操作何时开始和停止 doSomeAction String gt IO doSomeAction arg1 do putStrLn lt lt makeTime
  • 承诺的反面是什么?

    承诺代表将来可能可用 或无法实现 的值 我正在寻找的是一种数据类型 它表示将来可能变得不可用的可用值 可能是由于错误 Promise a b TransitionFromTo
  • Haskell if-then-else 条件中的“解析输入错误”

    当我尝试编译以下 do 块时 它会抛出错误 输入 conn 上的解析错误 我尝试了许多不同的 if then else 语句配置 但均无济于事 在我添加条件之前 数据库逻辑就起作用了 所以这没有问题 else 中是否有太多行 有没有办法在不
  • 浏览前奏的源代码会带来奇怪的情况

    我一直在寻找的定义seq并遇到了这个奇怪的事情 为什么所有这些函数都有相同 相似的定义 seq a gt b gt b seq let x x in x inline a gt a inline let x x in x lazy a gt

随机推荐