The cxx-jit Reference Manual

Table of Contents

Next: , Previous: , Up: (dir)   [Contents][Index]

The cxx-jit Reference Manual

This is the cxx-jit Reference Manual, version 1.0, generated automatically by Declt version 3.0 "Montgomery Scott" on Wed Oct 13 09:29:52 2021 GMT+0.


Next: , Previous: , Up: Top   [Contents][Index]

1 Introduction

#+OPTIONS: toc:3          (only include two levels in TOC)
* CL-CXX-JIT - Common Lisp C++ JIT for exposing C++ functions

This library provides an interface to C++ from lisp. It compiles C++ code, then loads it into lisp. It was inspired by [[https://github.com/onqtam/rcrl][RCRL]] and the older project [[https://github.com/Islam0mar/cl-cxx][CL-CXX]].

** API
=(from '("list of string headers") 'import "normal string is inserted as it is" '("function/function-pointer/mem-fun-pointer/lambda" . "name-used-in-lisp"))=

** Examples
*** SDL2 Example
[[sdl2.gif]]
#+begin_src lisp
(ql:quickload :cxx-jit)
(setf cxx-jit:*cxx-compiler-link-libs* "-lGL -lSDL2 -lSDL2main")

(cxx-jit:from '(
                "")
              'import
              '("[](){return SDL_Init(SDL_Init(SDL_INIT_VIDEO));}" . "init")
              '("SDL_CreateWindow" . "create-window")
              '("SDL_CreateRenderer" . "create-renderer")
              '("SDL_SetRenderDrawColor" . "set-color")
              '("SDL_DestroyWindow" . "destroy-window")
              '("SDL_RenderClear" . "clear-renderer")
              '("SDL_RenderPresent" . "renderer-render")
              '("SDL_Quit" . "sdl-quit"))

(init)
(setf wind (create-window "create-window" 0 0 600 700 0))
(setf rend (create-renderer wind -1 0))
(loop for x to (* 255 3)
      for r = (if (> x 255) 255 x)
      for g = (if (> x 255) (if (> x (* 2 255)) 255 (rem x 256)) 0)
      for b = (if (> x (* 2 255)) (rem x 256) 0)
      do
         (print x)
         (set-color rend r g b 255)
         (clear-renderer rend)
         (renderer-render rend)
         (sleep 0.01))

(destroy-window wind)
(sdl-quit)
#+end_src

*** Basic Example
Start with =(ql:quickload :cxx-jit) (in-package cxx-jit)=
#+begin_src lisp
  (from '("") 'import '("[](std::string x){return \"Hi, \"+x;}" . "hi"))
  (hi "there!")

  (from '("") 'import '("static_cast(std::sin)" . "cpp-sin"))
  (cpp-sin 0d0)
  (cpp-sin pi)
  (cpp-sin (/ pi 2))

  (from nil 'import "struct C{ auto hi(){return \"Hello, World\\n\";} auto bye(){return \"Bye\";} };" '("&C::bye" . "bye") '("&C::hi" . "hi") '("[](){static C x; return x;}" . "cc"))
  (cc)
  (hi *)
  (bye **)
    ;;; structure  definition could be written in a header file then be used as the following:
  (from '("c.hpp") 'import '("&C::bye" . "bye") '("&C::hi" . "hi") '("[](){static C x; return x;}" . "cc"))
#+end_src

*** Eigen Library Example
Start with =(ql:quickload :cxx-jit) (in-package cxx-jit)=
#+begin_src lisp
     (from '("" "") 'import '("[](Eigen::CwiseNullaryOp,Eigen::Matrix> x){std::stringstream s;
         s << x;
         return s.str();}" . "print-matrix"))

    (from '("" "") 'import '("static_cast,Eigen::Matrix> (*)()> (&Eigen::Matrix3d::Identity)" . "identity-matrix"))

(print-matrix (identity-matrix))
#+end_src

** Prerequisites
 - common lisp supporting [[https://www.common-lisp.net/project/cffi/][CFFI]]
 - working C++17 compiler
 - the following variables should be set according to OS and compiler used
|------------------------------------+------------------------------------------------------------------------------------|
| variable                           | default value                                                                      |
|------------------------------------+------------------------------------------------------------------------------------|
| =*cxx-compiler-executable-path*=   | "~/usr/bin/g++~"                                                                   |
| =*cxx-compiler-flags*=             | "~-std=c++17 -Wall -Wextra -I/usr/include/eigen3~"                                 |
| =*cxx-compiler-working-directory*= | "~/tmp/~" #\/ '/' should be the last character                                     |
| =+cxx-compiler-lib-name+=          | (intern "~plugin~")                                                                |
| =+cxx-compiler-wrap-cxx-path+=     | shouldn't be changed "~path to wrap-cxx.cpp~"                                      |
| =*cxx-compiler-internal-flags*=    | "~-shared -fPIC -Wl,--no-undefined -Wl,--no-allow-shlib-undefined~"                |
|                                    | for g++ and for clang++ "~-shared -fPIC -Wl,-undefined,error -Wl,-flat_namespace~" |
| =*cxx-compiler-link-libs*=         | "~-lm~" these flags are added after "~-o output~" to link correctly                |
|------------------------------------+------------------------------------------------------------------------------------|

** Installation
Clone into home/common-lisp directory. Then =(ql:quickload :cxx-jit-test)=

** Supported Types
|------------------+------------------|
| C++ type         | Lisp cffi type   |
|------------------+------------------|
| fundamental      | same             |
| string           | :string          |
| class            | :pointer         |
| std::is_function | :pointer         |
| other            | not implemented! |
|------------------+------------------|

** Under The Hood
 + function/lambda/member_function/function_pointer is wrapped into a dummy lambda class to have a unique template specialization.
     #+begin_src C++ 
       Import([&]() { return __VA_ARGS__; });
      #+end_src
 + =Import= function calls =DecayThenResolve= with function pointer as the template specialization so thunk pointer is omitted and we only return the direct function pointer which will be used from lisp side.
 + =InvocableTypeName= returns a vector contains: [return type, class type for class function member, args]. It resolves C++ types as follows:
   * Fundamental types and pointers are passed directly
   * String is converted to char* with new[] operator, should be cleared with =ClCxxDeleteObject(ptr, true)=
   * Class/std::is_function is converted to void* with new[] operator, should be cleared with =ClCxxDeleteObject(ptr, false)=
   * rest report an issue for other cases
 + Meta data for each function defined is passed through a lisp callback with this data:
    #+begin_src C++
typedef struct {
  // could be void*
  void (*thunk_ptr)();
  bool method_p;
  const char **type;  // memory handled in C++
  std::uint8_t type_size;
} MetaData;
#+end_src

** NOTE
Tested on:
 - SBCL 2.0.1 on debian

** Todo List
*** TODO Add redirect stdout : =freopen("/tmp/tmp.txt", "w", stdout);= @apemangr
*** TODO Use trivial-garbage with =ClCxxDeleteObject=
*** TODO Add non-polling =from=
*** TODO Test functions
*** TODO Benchmark
*** TODO Better class interface

** Copyright

Copyright (c) 2021 Islam Omar (io1131@fayoum.edu.eg)

** License

Licensed under the MIT License.


Next: , Previous: , Up: Top   [Contents][Index]

2 Systems

The main system appears first, followed by any subsystem dependency.


Previous: , Up: Systems   [Contents][Index]

2.1 cxx-jit

Author

Islam Omar

License

MIT

Description

Common Lisp Cxx Interoperation

Long Description

#+OPTIONS: toc:3 (only include two levels in TOC)
* CL-CXX-JIT - Common Lisp C++ JIT for exposing C++ functions

This library provides an interface to C++ from lisp. It compiles C++ code, then loads it into lisp. It was inspired by [[https://github.com/onqtam/rcrl][RCRL]] and the older project [[https://github.com/Islam0mar/cl-cxx][CL-CXX]].

** API
=(from ’("list of string headers") ’import "normal string is inserted as it is" ’("function/function-pointer/mem-fun-pointer/lambda" . "name-used-in-lisp"))=

** Examples
*** SDL2 Example
[[sdl2.gif]]
#+begin_src lisp
(ql:quickload :cxx-jit)
(setf cxx-jit:*cxx-compiler-link-libs* "-lGL -lSDL2 -lSDL2main")

(cxx-jit:from ’(
"<SDL2/SDL.h>")
’import
’("[](){return SDL_Init(SDL_Init(SDL_INIT_VIDEO));}" . "init")
’("SDL_CreateWindow" . "create-window")
’("SDL_CreateRenderer" . "create-renderer")
’("SDL_SetRenderDrawColor" . "set-color")
’("SDL_DestroyWindow" . "destroy-window")
’("SDL_RenderClear" . "clear-renderer")
’("SDL_RenderPresent" . "renderer-render")
’("SDL_Quit" . "sdl-quit"))

(init)
(setf wind (create-window "create-window" 0 0 600 700 0))
(setf rend (create-renderer wind -1 0))
(loop for x to (* 255 3)
for r = (if (> x 255) 255 x)
for g = (if (> x 255) (if (> x (* 2 255)) 255 (rem x 256)) 0)
for b = (if (> x (* 2 255)) (rem x 256) 0)
do
(print x)
(set-color rend r g b 255)
(clear-renderer rend)
(renderer-render rend)
(sleep 0.01))

(destroy-window wind)
(sdl-quit)
#+end_src

*** Basic Example
Start with =(ql:quickload :cxx-jit) (in-package cxx-jit)=
#+begin_src lisp
(from ’("<string>") ’import ’("[](std::string x){return \"Hi, \"+x;}" . "hi"))
(hi "there!")

(from ’("<cmath>") ’import ’("static_cast<double(*)(double)>(std::sin)" . "cpp-sin"))
(cpp-sin 0d0)
(cpp-sin pi)
(cpp-sin (/ pi 2))

(from nil ’import "struct C{ auto hi(){return \"Hello, World\\n\";} auto bye(){return \"Bye\";} };" ’("&C::bye" . "bye") ’("&C::hi" . "hi") ’("[](){static C x; return x;}" . "cc"))
(cc)
(hi *)
(bye **)
;;; structure definition could be written in a header file then be used as the following:
(from ’("c.hpp") ’import ’("&C::bye" . "bye") ’("&C::hi" . "hi") ’("[](){static C x; return x;}" . "cc"))
#+end_src

*** Eigen Library Example
Start with =(ql:quickload :cxx-jit) (in-package cxx-jit)=
#+begin_src lisp
(from ’("<Eigen/Core>" "<Eigen/Core>") ’import ’("[](Eigen::CwiseNullaryOp<Eigen::internal::scalar_identity_op<double>,Eigen::Matrix<double, 3, 3>> x){std::stringstream s;
s << x;
return s.str();}" . "print-matrix"))

(from ’("<Eigen/Core>" "<Eigen/Core>") ’import ’("static_cast<const Eigen::CwiseNullaryOp<Eigen::internal::scalar_identity_op<double>,Eigen::Matrix<double, 3, 3>> (*)()> (&Eigen::Matrix3d::Identity)" . "identity-matrix"))

(print-matrix (identity-matrix))
#+end_src

** Prerequisites
- common lisp supporting [[https://www.common-lisp.net/project/cffi/][CFFI]]
- working C++17 compiler
- the following variables should be set according to OS and compiler used
|————————————+————————————————————————————|
| variable | default value | |————————————+————————————————————————————|
| =*cxx-compiler-executable-path*= | "~/usr/bin/g++~" |
| =*cxx-compiler-flags*= | "~-std=c++17 -Wall -Wextra -I/usr/include/eigen3~" |
| =*cxx-compiler-working-directory*= | "~/tmp/~" #\/ ’/’ should be the last character |
| =+cxx-compiler-lib-name+= | (intern "~plugin~") |
| =+cxx-compiler-wrap-cxx-path+= | shouldn’t be changed "~path to wrap-cxx.cpp~" |
| =*cxx-compiler-internal-flags*= | "~-shared -fPIC -Wl,–no-undefined -Wl,–no-allow-shlib-undefined~" |
| | for g++ and for clang++ "~-shared -fPIC -Wl,-undefined,error -Wl,-flat_namespace~" |
| =*cxx-compiler-link-libs*= | "~-lm~" these flags are added after "~-o output~" to link correctly | |————————————+————————————————————————————|

** Installation
Clone into home/common-lisp directory. Then =(ql:quickload :cxx-jit-test)=

** Supported Types
|——————+——————|
| C++ type | Lisp cffi type |
|——————+——————|
| fundamental | same |
| string | :string |
| class | :pointer |
| std::is_function | :pointer |
| other | not implemented! |
|——————+——————|

** Under The Hood
+ function/lambda/member_function/function_pointer is wrapped into a dummy lambda class to have a unique template specialization.
#+begin_src C++
Import([&]() { return __VA_ARGS__; });
#+end_src
+ =Import= function calls =DecayThenResolve= with function pointer as the template specialization so thunk pointer is omitted and we only return the direct function pointer which will be used from lisp side.
+ =InvocableTypeName= returns a vector contains: [return type, class type for class function member, args]. It resolves C++ types as follows:
* Fundamental types and pointers are passed directly
* String is converted to char* with new[] operator, should be cleared with =ClCxxDeleteObject(ptr, true)=
* Class/std::is_function is converted to void* with new[] operator, should be cleared with =ClCxxDeleteObject(ptr, false)=
* rest report an issue for other cases
+ Meta data for each function defined is passed through a lisp callback with this data:
#+begin_src C++
typedef struct {
// could be void*
void (*thunk_ptr)();
bool method_p;
const char **type; // memory handled in C++
std::uint8_t type_size;
} MetaData;
#+end_src

** NOTE
Tested on:
- SBCL 2.0.1 on debian

** Todo List
*** TODO Add redirect stdout : =freopen("/tmp/tmp.txt", "w", stdout);= @apemangr
*** TODO Use trivial-garbage with =ClCxxDeleteObject=
*** TODO Add non-polling =from=
*** TODO Test functions
*** TODO Benchmark
*** TODO Better class interface

** Copyright

Copyright (c) 2021 Islam Omar (io1131@fayoum.edu.eg)

** License

Licensed under the MIT License.

Version

1.0

Dependencies
Source

cxx-jit.asd (file)

Components

Next: , Previous: , Up: Top   [Contents][Index]

3 Modules

Modules are listed depth-first from the system components tree.


Previous: , Up: Modules   [Contents][Index]

3.1 cxx-jit/src

Parent

cxx-jit (system)

Location

src/

Component

cxx-jit.lisp (file)


Next: , Previous: , Up: Top   [Contents][Index]

4 Files

Files are sorted by type and then listed depth-first from the systems components trees.


Previous: , Up: Files   [Contents][Index]

4.1 Lisp


Next: , Previous: , Up: Lisp files   [Contents][Index]

4.1.1 cxx-jit.asd

Location

cxx-jit.asd

Systems

cxx-jit (system)

Packages

cxx-jit/system


Next: , Previous: , Up: Lisp files   [Contents][Index]

4.1.2 cxx-jit/package.lisp

Parent

cxx-jit (system)

Location

package.lisp

Packages

cxx-jit


Previous: , Up: Lisp files   [Contents][Index]

4.1.3 cxx-jit/src/cxx-jit.lisp

Parent

src (module)

Location

src/cxx-jit.lisp

Exported Definitions
Internal Definitions

Next: , Previous: , Up: Top   [Contents][Index]

5 Packages

Packages are listed by definition order.


Next: , Previous: , Up: Packages   [Contents][Index]

5.1 cxx-jit/system

Source

cxx-jit.asd

Use List

Previous: , Up: Packages   [Contents][Index]

5.2 cxx-jit

Source

package.lisp (file)

Use List
Exported Definitions
Internal Definitions

Next: , Previous: , Up: Top   [Contents][Index]

6 Definitions

Definitions are sorted by export status, category, package, and then by lexicographic order.


Next: , Previous: , Up: Definitions   [Contents][Index]

6.1 Exported definitions


Next: , Previous: , Up: Exported definitions   [Contents][Index]

6.1.1 Constants

Constant: +cxx-compiler-lib-name+
Package

cxx-jit

Source

cxx-jit.lisp (file)

Constant: +cxx-compiler-wrap-cxx-path+
Package

cxx-jit

Source

cxx-jit.lisp (file)


Next: , Previous: , Up: Exported definitions   [Contents][Index]

6.1.2 Special variables

Special Variable: *cxx-compiler-flags*
Package

cxx-jit

Source

cxx-jit.lisp (file)

Special Variable: *cxx-compiler-internal-flags*
Package

cxx-jit

Source

cxx-jit.lisp (file)

Package

cxx-jit

Source

cxx-jit.lisp (file)

Special Variable: *cxx-compiler-packages*
Package

cxx-jit

Source

cxx-jit.lisp (file)

Special Variable: *cxx-compiler-packages-number*
Package

cxx-jit

Source

cxx-jit.lisp (file)

Special Variable: *cxx-compiler-process*
Package

cxx-jit

Source

cxx-jit.lisp (file)

Special Variable: *cxx-compiler-working-directory*
Package

cxx-jit

Source

cxx-jit.lisp (file)


Previous: , Up: Exported definitions   [Contents][Index]

6.1.3 Functions

Function: from HEADER-NAMES IMPORT &rest BODY

import cxx functions/methods from the header

Package

cxx-jit

Source

cxx-jit.lisp (file)

Function: try-get-cxx-compiler-output ()

returns nil if compiler process is compiling else returns the exit value from the process

Package

cxx-jit

Source

cxx-jit.lisp (file)


Previous: , Up: Definitions   [Contents][Index]

6.2 Internal definitions


Next: , Previous: , Up: Internal definitions   [Contents][Index]

6.2.1 Special variables

Special Variable: *cxx--fun-names*
Package

cxx-jit

Source

cxx-jit.lisp (file)

Special Variable: *cxx-compiler-executable-path*
Package

cxx-jit

Source

cxx-jit.lisp (file)


Next: , Previous: , Up: Internal definitions   [Contents][Index]

6.2.2 Functions

Function: cffi-type TYPE

Returns cffi-type as a keyword

Package

cxx-jit

Source

cxx-jit.lisp (file)

Function: compile-code CODE

compile aync. code string with cxx compiler

Package

cxx-jit

Source

cxx-jit.lisp (file)

Function: copy-and-load-new-library ()

if compilation suceceded copy plugin.so to plugin_x.so ,where x = 0,1,...
then load the library

Package

cxx-jit

Source

cxx-jit.lisp (file)

Function: parse-input-args ARG-TYPES

return argument types (with variables if they are inputs) in a proper list

Package

cxx-jit

Source

cxx-jit.lisp (file)

Function: symbols-list ARG-TYPES &optional METHOD-P

Return a list of symbols ’(V0 V1 V2 V3 ...) representing the number of args

Package

cxx-jit

Source

cxx-jit.lisp (file)


Previous: , Up: Internal definitions   [Contents][Index]

6.2.3 Classes

Class: meta-data-tclass ()
Package

cxx-jit

Source

cxx-jit.lisp (file)

Direct superclasses
  • translatable-foreign-type (class)
  • foreign-struct-type (class)

Previous: , Up: Top   [Contents][Index]

Appendix A Indexes


Next: , Previous: , Up: Indexes   [Contents][Index]

A.1 Concepts

Jump to:   C   F   L   M  
Index Entry  Section

C
cxx-jit.asd: The cxx-jit․asd file
cxx-jit/package.lisp: The cxx-jit/package․lisp file
cxx-jit/src: The cxx-jit/src module
cxx-jit/src/cxx-jit.lisp: The cxx-jit/src/cxx-jit․lisp file

F
File, Lisp, cxx-jit.asd: The cxx-jit․asd file
File, Lisp, cxx-jit/package.lisp: The cxx-jit/package․lisp file
File, Lisp, cxx-jit/src/cxx-jit.lisp: The cxx-jit/src/cxx-jit․lisp file

L
Lisp File, cxx-jit.asd: The cxx-jit․asd file
Lisp File, cxx-jit/package.lisp: The cxx-jit/package․lisp file
Lisp File, cxx-jit/src/cxx-jit.lisp: The cxx-jit/src/cxx-jit․lisp file

M
Module, cxx-jit/src: The cxx-jit/src module

Jump to:   C   F   L   M  

Next: , Previous: , Up: Indexes   [Contents][Index]

A.2 Functions

Jump to:   C   F   P   S   T  
Index Entry  Section

C
cffi-type: Internal functions
compile-code: Internal functions
copy-and-load-new-library: Internal functions

F
from: Exported functions
Function, cffi-type: Internal functions
Function, compile-code: Internal functions
Function, copy-and-load-new-library: Internal functions
Function, from: Exported functions
Function, parse-input-args: Internal functions
Function, symbols-list: Internal functions
Function, try-get-cxx-compiler-output: Exported functions

P
parse-input-args: Internal functions

S
symbols-list: Internal functions

T
try-get-cxx-compiler-output: Exported functions

Jump to:   C   F   P   S   T  

Next: , Previous: , Up: Indexes   [Contents][Index]

A.3 Variables

Jump to:   *   +  
C   S  
Index Entry  Section

*
*cxx--fun-names*: Internal special variables
*cxx-compiler-executable-path*: Internal special variables
*cxx-compiler-flags*: Exported special variables
*cxx-compiler-internal-flags*: Exported special variables
*cxx-compiler-link-libs*: Exported special variables
*cxx-compiler-packages*: Exported special variables
*cxx-compiler-packages-number*: Exported special variables
*cxx-compiler-process*: Exported special variables
*cxx-compiler-working-directory*: Exported special variables

+
+cxx-compiler-lib-name+: Exported constants
+cxx-compiler-wrap-cxx-path+: Exported constants

C
Constant, +cxx-compiler-lib-name+: Exported constants
Constant, +cxx-compiler-wrap-cxx-path+: Exported constants

S
Special Variable, *cxx--fun-names*: Internal special variables
Special Variable, *cxx-compiler-executable-path*: Internal special variables
Special Variable, *cxx-compiler-flags*: Exported special variables
Special Variable, *cxx-compiler-internal-flags*: Exported special variables
Special Variable, *cxx-compiler-link-libs*: Exported special variables
Special Variable, *cxx-compiler-packages*: Exported special variables
Special Variable, *cxx-compiler-packages-number*: Exported special variables
Special Variable, *cxx-compiler-process*: Exported special variables
Special Variable, *cxx-compiler-working-directory*: Exported special variables

Jump to:   *   +  
C   S  

Previous: , Up: Indexes   [Contents][Index]

A.4 Data types

Jump to:   C   M   P   S  
Index Entry  Section

C
Class, meta-data-tclass: Internal classes
cxx-jit: The cxx-jit system
cxx-jit: The cxx-jit package
cxx-jit/system: The cxx-jit/system package

M
meta-data-tclass: Internal classes

P
Package, cxx-jit: The cxx-jit package
Package, cxx-jit/system: The cxx-jit/system package

S
System, cxx-jit: The cxx-jit system

Jump to:   C   M   P   S