# Extension Libraries

Extensions provide a way to extend the VM with optional system calls.
One or more extensions can be enabled at a time, but they must not use
the same opcodes. Use `grep case */dispatch.c` to check the currently
used ones.

ext/example is an example extension with a custom primop 48, an example
C-function, an Owl library and a sample program using the library and
the extension.


## Enabling Extensions

To enable an extension, add a file called enabled to the directory. Then
after `make clean` and `make`, you can include the libraries or call the
primitives directly.

Example:

```
$ touch ext/example/enabled
$ make clean
$ make
$ bin/ol
You see a prompt.
> (import (ext example main))
ext_example(11,22) = 29
ext_example(111,222) = 177
Example library OK
;; Library (ext example main) added
> loaded
> (test-call 1 2)
3
```

It is sufficient to rebuild just the vm for a faster extension code development
cycle. In this case you would do something like:

```
$ make clean
$ make bin/vm
$ bin/vm fasl/init.fasl --run ext/example/program.scm
```

## Compiling

In case you want to compile the program running extensions, first build Owl
with the desired extensions and then use it to build your program.

```
$ bin/ol -o test.c ext/example/program.scm
ext_example(11,22) = 29
ext_example(111,222) = 177
Example library OK
$ cc -o test test.c
$ ./test
ext_example(11,22) = 29
29
```

## Anatomy of an Extension

Extensions are in separate directories under ext/. Each extension has a file
main.c, which holds functions to be included in the VM after macros and
globals, and dispatch.c, which handles calling the functions with chosen
opcodes. The extensions are called from Owl via `(sys-prim <opcode> A B C)`,
where opcode is the one handled via case in dispatch.c, and A, B and c are
arbitrary Owl values.

If an Owl library is defined for the extension, it is recommended to be in the
same directory as the rest of the extension. This allows the extensions to be
checked out form external repositories. Extension Owl libraries can be imported
with e.g. `(import (ext example main))` as usual. It is recommended to have
some kind of test of the functionality in the library, so that it will fail to
load if the wrong binary is used.
