Skip to content

Commit

Permalink
Clean up startup files (#498)
Browse files Browse the repository at this point in the history
  • Loading branch information
Akuli authored Feb 22, 2024
1 parent 1d420e2 commit c3c2efa
Show file tree
Hide file tree
Showing 11 changed files with 92 additions and 123 deletions.
10 changes: 2 additions & 8 deletions self_hosted/create_llvm_ir.jou
Original file line number Diff line number Diff line change
Expand Up @@ -796,17 +796,11 @@ class AstToIR:
self->do_statement(&body->statements[i])

def call_the_special_startup_function(self) -> None:
if WINDOWS:
name = "_jou_windows_startup"
elif MACOS:
name = "_jou_macos_startup"
elif NETBSD:
name = "_jou_netbsd_startup"
else:
if not (WINDOWS or MACOS or NETBSD):
return

functype = LLVMFunctionType(LLVMVoidType(), NULL, 0, False as int)
func = LLVMAddFunction(self->module, name, functype)
func = LLVMAddFunction(self->module, "_jou_startup", functype)
LLVMBuildCall2(self->builder, functype, func, NULL, 0, "")

def define_function_or_method(self, funcdef: AstFunctionOrMethod*, self_type: Type*) -> None:
Expand Down
2 changes: 2 additions & 0 deletions self_hosted/evaluate.jou
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ def get_special_constant(name: byte*) -> int:
return WINDOWS as int
if strcmp(name, "MACOS") == 0:
return MACOS as int
if strcmp(name, "NETBSD") == 0:
return NETBSD as int
return -1


Expand Down
10 changes: 2 additions & 8 deletions self_hosted/main.jou
Original file line number Diff line number Diff line change
Expand Up @@ -172,15 +172,9 @@ class Compiler:
def determine_automagic_files(self) -> None:
self->automagic_files[0] = malloc(strlen(self->stdlib_path) + 40)
sprintf(self->automagic_files[0], "%s/_assert_fail.jou", self->stdlib_path)
if WINDOWS:
self->automagic_files[1] = malloc(strlen(self->stdlib_path) + 40)
sprintf(self->automagic_files[1], "%s/_windows_startup.jou", self->stdlib_path)
if MACOS:
self->automagic_files[1] = malloc(strlen(self->stdlib_path) + 40)
sprintf(self->automagic_files[1], "%s/_macos_startup.jou", self->stdlib_path)
if NETBSD:
if WINDOWS or MACOS or NETBSD:
self->automagic_files[1] = malloc(strlen(self->stdlib_path) + 40)
sprintf(self->automagic_files[1], "%s/_netbsd_startup.jou", self->stdlib_path)
sprintf(self->automagic_files[1], "%s/_jou_startup.jou", self->stdlib_path)

def parse_all_files(self) -> None:
queue: ParseQueueItem* = malloc(50 * sizeof queue[0])
Expand Down
11 changes: 1 addition & 10 deletions src/codegen.c
Original file line number Diff line number Diff line change
Expand Up @@ -417,17 +417,8 @@ static int find_block(const CfGraph *cfg, const CfBlock *b)
#if defined(_WIN32) || defined(__APPLE__) || defined(__NetBSD__)
static void codegen_call_to_the_special_startup_function(const struct State *st)
{
const char *name;
#if defined _WIN32
name = "_jou_windows_startup";
#elif defined __APPLE__
name = "_jou_macos_startup";
#else
name = "_jou_netbsd_startup";
#endif

LLVMTypeRef functype = LLVMFunctionType(LLVMVoidType(), NULL, 0, false);
LLVMValueRef func = LLVMAddFunction(st->module, name, functype);
LLVMValueRef func = LLVMAddFunction(st->module, "_jou_startup", functype);
LLVMBuildCall2(st->builder, functype, func, NULL, 0, "");
}
#endif
Expand Down
14 changes: 6 additions & 8 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -455,15 +455,13 @@ int main(int argc, char **argv)
}

include_special_stdlib_file(&compst, "_assert_fail.jou");
#ifdef _WIN32
include_special_stdlib_file(&compst, "_windows_startup.jou");
#endif
#ifdef __APPLE__
include_special_stdlib_file(&compst, "_macos_startup.jou");
#endif
#ifdef __NetBSD__

#if defined(__NetBSD__)
assert(sizeof(FILE) == 152); // magic number in the startup file
include_special_stdlib_file(&compst, "_netbsd_startup.jou");
#endif

#if defined(_WIN32) || defined(__APPLE__) || defined(__NetBSD__)
include_special_stdlib_file(&compst, "_jou_startup.jou");
#endif

parse_file(&compst, command_line_args.infile, NULL);
Expand Down
48 changes: 48 additions & 0 deletions stdlib/_jou_startup.jou
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# On many platforms, a call to the _jou_startup() function is inserted to
# the start of main() in every Jou program.
#
# On Windows, the C "global variables" stdin, stdout and stderr are
# actually macros:
#
# $ printf "#include <stdio.h>\nstdin\nstdout\nstderr\n" | x86_64-w64-mingw32-cpp | tail -3
# (__acrt_iob_func(0))
# (__acrt_iob_func(1))
# (__acrt_iob_func(2))
#
# For simplicity, Jou redefines them as variables with the same
# names and assigns the correct values to them.
#
# There seems to be a similar situation on most other platforms.
#
# We can't import FILE from io.jou here, because then we would be
# trying to define a variable that already exists.
if WINDOWS or MACOS or NETBSD:
global stdin: void*
global stdout: void*
global stderr: void*

if WINDOWS:
declare __acrt_iob_func(index: int) -> void*

def _jou_startup() -> None:
stdin = __acrt_iob_func(0)
stdout = __acrt_iob_func(1)
stderr = __acrt_iob_func(2)

if MACOS:
declare global __stdinp: void*
declare global __stdoutp: void*
declare global __stderrp: void*

def _jou_startup() -> None:
stdin = __stdinp
stdout = __stdoutp
stderr = __stderrp

if NETBSD:
declare global __sF: byte[152][3] # sizeof(FILE) == 152

def _jou_startup() -> None:
stdin = &__sF[0]
stdout = &__sF[1]
stderr = &__sF[2]
26 changes: 0 additions & 26 deletions stdlib/_macos_startup.jou

This file was deleted.

23 changes: 0 additions & 23 deletions stdlib/_netbsd_startup.jou

This file was deleted.

32 changes: 0 additions & 32 deletions stdlib/_windows_startup.jou

This file was deleted.

37 changes: 30 additions & 7 deletions stdlib/errno.jou
Original file line number Diff line number Diff line change
@@ -1,12 +1,35 @@
# C's errno is actually a macro that expands to a function call.
# See also _windows_startup.jou
declare __errno_location() -> int*
# The function name varies by platform.
if WINDOWS:
declare _errno() -> int*
elif MACOS:
declare __error() -> int*
elif NETBSD:
declare __errno() -> int*
else:
declare __errno_location() -> int*

def set_errno(value: int) -> None:
*__errno_location() = value

def get_errno() -> int:
return *__errno_location()
# TODO: Ideally we would be able to place the if statements inside the functions.
if WINDOWS:
def set_errno(value: int) -> None:
*_errno() = value
def get_errno() -> int:
return *_errno()
elif MACOS:
def set_errno(value: int) -> None:
*__error() = value
def get_errno() -> int:
return *__error()
elif NETBSD:
def set_errno(value: int) -> None:
*__errno() = value
def get_errno() -> int:
return *__errno()
else:
def set_errno(value: int) -> None:
*__errno_location() = value
def get_errno() -> int:
return *__errno_location()

# Convert an error code into a string. Do not modify or free() the returned string.
declare strerror(errno_value: int) -> byte*
2 changes: 1 addition & 1 deletion tests/should_succeed/compiler_cli.jou
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ def main() -> int:

# Test that double-verbose kinda works, without asserting the output in too much detail.
# See README for an explanation of why CFG is twice.
# TODO: shouldn't need to hide stdlib/io.jou or _windows_startup or _assert_fail stuff, ideally it would be precompiled
# TODO: shouldn't need to hide special stdlib/_... files, ideally they would be precompiled
run_jou("-vv examples/hello.jou | grep === | grep -v stdlib/io.jou | grep -v stdlib/_")
# Output: ===== Tokens for file "examples/hello.jou" =====
# Output: ===== AST for file "examples/hello.jou" =====
Expand Down

0 comments on commit c3c2efa

Please sign in to comment.