Simplify Lisp calling convention #19

Closed
opened 2026-04-01 09:14:41 +00:00 by simon · 1 comment
Owner

In version 0.0.X, all Lisp functions written in C had the signature:

struct cons_pointer function_name( struct stack_frame *frame,
                               struct cons_pointer frame_pointer,
                               struct cons_pointer env );

and I've reproduced this heedlessly in 0.1.X as:

struct pso_pointer function_name( struct pso4 *frame,
                            struct pso_pointer frame_pointer,
                            struct pso_pointer env);

However frame and frame_pointer both point to the exact same thing: the actual object in memory. It's just that frame is the byte offset in memory as visible to the C program, and frame_pointer is a {node, page, offset} structure, where the page is an index into the pages[] array which holds (struct page *) pointers, and the offset is an offset into that page considered as an array of 64 bit words, so provided node is the current node (and if it isn't, we should request a copy of the memory object from that node), the C address of any object should be possible to be calculated as:

(struct pso4*)(&(pages[page]) + (offset * sizeof uint64_t))

Which means our calling convention should be possible to be just:

struct pso_pointer function_name( struct pso_pointer frame_pointer,
                             struct pso_pointer env) {
      struct pso4 * frame = pointer_to_pso4( frame_pointer);

      ...
  }

This seems to me a lot more elegant, and will make the Lisp compiler a lot easier to write, but if we're going to do it, now is the time to do it!

In version 0.0.X, all Lisp functions written in C had the signature: ```C struct cons_pointer function_name( struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env ); ``` and I've reproduced this heedlessly in 0.1.X as: ```C struct pso_pointer function_name( struct pso4 *frame, struct pso_pointer frame_pointer, struct pso_pointer env); ``` However `frame` and `frame_pointer` both point to the exact same thing: the actual object in memory. It's just that `frame` is the byte offset in memory as visible to the C program, and `frame_pointer` is a `{node, page, offset}` structure, where the `page` is an index into the `pages[]` array which holds `(struct page *)` pointers, and the `offset` is an offset into that page considered as an array of 64 bit words, so provided `node` is the current node (and if it isn't, we should request a copy of the memory object from that node), the C address of any object should be possible to be calculated as: ```C (struct pso4*)(&(pages[page]) + (offset * sizeof uint64_t)) ``` Which means our calling convention should be possible to be just: ```C struct pso_pointer function_name( struct pso_pointer frame_pointer, struct pso_pointer env) { struct pso4 * frame = pointer_to_pso4( frame_pointer); ... } ``` This seems to me a lot more elegant, and will make the Lisp compiler a lot easier to write, but if we're going to do it, now is the time to do it!
Author
Owner

Didn't auto-close on the commit message :-(

Didn't auto-close on the commit message :-(
simon closed this issue 2026-04-01 16:14:16 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: simon/post-scarcity#19
No description provided.