Skip to content
GitLab
Projects Groups Snippets
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
  • Sign in / Register
  • GHC GHC
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
    • Locked Files
  • Issues 5,407
    • Issues 5,407
    • List
    • Boards
    • Service Desk
    • Milestones
    • Iterations
  • Merge requests 600
    • Merge requests 600
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
    • Test Cases
  • Deployments
    • Deployments
    • Releases
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Code review
    • Insights
    • Issue
    • Repository
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • Glasgow Haskell CompilerGlasgow Haskell Compiler
  • GHCGHC
  • Issues
  • #20693
Closed
Open
Issue created Nov 16, 2021 by Norman Ramsey@nrnrnrDeveloper

Adding new species of foreign calls could be made easier

Motivation

A Haskell program built with Asterius, which targets WebAssembly, can make foreign calls to both JavaScript code and C code. Ideally Asterius would use existing support for making foreign C calls while adding new support for making foreign JavaScript calls. But GHC's current way of typechecking and desugaring foreign calls (GHC.Tc.Gen.Foreign and GHC.HsToCore.Foreign.Decl) makes that more difficult than one might like.

  • GHC currently provides hooks for typechecking and desugaring foreign calls, but the hooks (tcForeignExportsHook and dsForeignsHook) appear to be designed only to replace existing code with new code, not to mix existing code with new code. While it might be possible to use the hooks together with a primed function like tcForeignImports' or dsForeigns', we are not confident doing so. In particular, we are not confident that multiple calls to dsForeigns' could safely be composed. (The hooks in question are tcForeignImportsHook, tcForeignExportsHook, dsForeignsHook.)

  • A foreign calling convention is defined as an enumeration (type CCallConv in module GHC.Types.ForeignCall). An enumeration can easily be extended, but we have not been able to find documentation explaining what obligations might be incurred by an extension. (There is a comment about allocation, but the comment mentions just two of the five calling conventions defined. There is also a link to http://www.programmersheaven.com/2/Calling-conventions, but this link has bit-rotted, and the site is not captured at archive.org.) And if the semantics of a calling convention is spread throughout the compiler, to any location where a value of type CCallConv is depended on, then as GHC evolves, a new calling convention may be difficult to maintain.

Proposal

There's more than one way to resolve this issue, but we (@nrnrnr and @TerrorJack) like the idea of a minor refactoring. Instead of yes-or-no hooks, each target could identify a finite map of supported calling conventions. In that map, a key like ccall, capi, or javascript would be associated with a dictionary of operations. (Like a type-class dictionary, but not tied to a type.) Based on a cursory review of the source code, such a dictionary might include values like these:

  • A way of type-checking declarations

  • A way of desugaring declarations

  • A Boolean saying whether the convention is C-ish

  • A unique key per convention used to make calling convention an instance of Binary

(Care would have to be taken to ensure that all players agree on the meanings of the Binary keys.)

Or it might make more sense to define finer-grain values like these:

  • A value of type Tcm () used to check whether the calling convention is valid with the current back end (e.g., checkCg checkCOrAsmOrLlvmOrInterp)

  • A check on argument types to see whether they are supported by the calling convention

  • A function that gives a foreign export a stable name

These bullet points are just examples; the actual contents of a dictionary will be hard to settle on without an implementation, experience with which can then inform the design.

Edited Nov 17, 2021 by Norman Ramsey
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information
Assignee
Assign to
Time tracking