[project] Generate syscalls from new interface DSL

This change adds a new interface DSL for specifying objects (with
methods) and interfaces (that expose objects, and optionally have their
own methods).

Significant changes:

- Add the new scripts/definitions Python module to parse the DSL
- Add the new definitions directory containing DSL definition files
- Use cog to generate syscall-related code in kernel and libj6
- Unify ordering of pointer + length pairs in interfaces
This commit is contained in:
Justin C. Miller
2021-08-30 01:05:32 -07:00
parent 80f815c020
commit 186724e751
52 changed files with 4025 additions and 206 deletions

View File

@@ -1,15 +0,0 @@
#pragma once
#include <j6/types.h>
#ifdef __cplusplus
extern "C" {
#endif
#define SYSCALL(n, name, ...) j6_status_t j6_ ## name (__VA_ARGS__);
#include "j6/tables/syscalls.inc"
#undef SYSCALL
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,39 @@
#pragma once
// vim: ft=cpp
#include <j6/types.h>
#ifdef __cplusplus
extern "C" {
#endif
/*[[[cog code generation
from definitions.context import Context
ctx = Context(definitions_path)
ctx.parse("syscalls.def")
syscalls = ctx.interfaces["syscalls"]
for id, scope, method in syscalls.methods:
if scope:
name = f"{scope.name}_{method.name}"
else:
name = method.name
args = []
if method.constructor:
args.append("j6_handle_t *handle")
elif not method.static:
args.append("j6_handle_t handle")
for param in method.params:
for type, suffix in param.type.c_names(param.options):
args.append(f"{type} {param.name}{suffix}")
cog.outl(f"""j6_status_t j6_{name} ({", ".join(args)});""")
]]]*/
/// [[[end]]]
#ifdef __cplusplus
}
#endif

View File

@@ -1,9 +1,14 @@
# vim: ft=python
module("j6",
j6 = module("j6",
kind = "lib",
includes = [ "include" ],
sources = [
"init.cpp",
"syscalls.s",
])
from glob import glob
definitions = glob('definitions/**/*.def', recursive=True)
j6.add_input("include/j6/syscalls.h.cog", deps=definitions)
j6.add_input("syscalls.s.cog", deps=definitions)

View File

@@ -1,28 +0,0 @@
%macro SYSCALL 2
global j6_%1
j6_%1:
push rbp
mov rbp, rsp
; args should already be in rdi, etc, but rcx will
; get stomped, so stash it in r10, which isn't a
; callee-saved register, but also isn't used in the
; function call ABI.
mov r10, rcx
mov rax, %2
syscall
; result is now already in rax, so just return
pop rbp
ret
%endmacro
%define SYSCALL(n, name) SYSCALL name, n
%define SYSCALL(n, name, a) SYSCALL name, n
%define SYSCALL(n, name, a, b) SYSCALL name, n
%define SYSCALL(n, name, a, b, c) SYSCALL name, n
%define SYSCALL(n, name, a, b, c, d) SYSCALL name, n
%define SYSCALL(n, name, a, b, c, d, e) SYSCALL name, n
%include "j6/tables/syscalls.inc"

View File

@@ -0,0 +1,37 @@
; vim: ft=asm
%macro define_syscall 2
global j6_%1
j6_%1:
push rbp
mov rbp, rsp
; args should already be in rdi, etc, but rcx will
; get stomped, so stash it in r10, which isn't a
; callee-saved register, but also isn't used in the
; function call ABI.
mov r10, rcx
mov rax, %2
syscall
; result is now already in rax, so just return
pop rbp
ret
%endmacro
; [[[cog code generation
; from definitions.context import Context
;
; ctx = Context(definitions_path)
; ctx.parse("syscalls.def")
; syscalls = ctx.interfaces['syscalls']
;
; for id, scope, method in syscalls.methods:
; if scope:
; name = f"{scope.name}_{method.name}"
; else:
; name = method.name
; cog.outl(f"define_syscall {name:20}, {id}")
; ]]]
; [[[end]]]