summaryrefslogtreecommitdiff
path: root/notes/function_pointers.txt
blob: 8c670857b1093793f925200e3fabcec5609b1741 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

Function pointers
=================

Should we have them?
- Makes it possible to have a "custom" option for class structs (e.g. custom List, custom Allocator, etc.)

Downsides:
- Code cannot be replaced, because addresses are now "locked".

Possible workarounds:
- Relative function pointers make the code moveable as a unit,
  but individual code areas cannot move (or change layout)
- Could use fat pointers, with e.g:
-- Code "area" ID and function ID
-- This may be able to fit in a pointer!

type FunctionPointer = struct (
    ushort code_area
    ushort func_id
)

- Or we just use a function ID? With a per-"area" lookup table.
- (We cannot just have a area-local function ID, because the function
  pointer could be passed to other modules)
- We could also register function pointers, so we can update them when the
  code is moved or updated.
- We could also register the *function itself* and get a handle.
  The registration could happen automatically at load time.
-- Handles need to be process-global (or system global in a unikernel).
-- Getting the handle (from the function pointer) requires indirection. How to do this with position independent code? Perhaps pass in a relative offset and then, inside the "get handle" function, look at the return address.
-- Calling the function requires indirection. How to do this without having a race condition?
-- BUT we could generate code for the "call" function at load time,
   so it becomes basically a switch-case of IDs with calls to the
   functions.
--- Because the size of the function can change, the function needs to
    use a jump "trampoline" to jump to the current function body.
--- This way we will never do a jump to an address (except from function returns).
--- Also, this way we can compare function pointers.

=> have function pointers, but allow the implementation to transform them to something else.