diff --git a/lib/nop/clib.ns b/lib/nop/clib.ns index 343a688..5dbfc2a 100644 --- a/lib/nop/clib.ns +++ b/lib/nop/clib.ns @@ -1,34 +1,32 @@ \ SPDX-License-Identifier: MIT -\ Copyright (c) 2018-2022 Iruatã Martins dos Santos Souza - -: arch-lib - here " nop/clib/" dup push mem, NOPARCH dup push mem, - pop pop + ; - -arch-lib floaded +\ Copyright (c) 2018-2024 Iruatã Martins dos Santos Souza forth 1 value RTLD_LAZY +variable handle + : errorstr ( -> a u ) dlerror dup if z>mem exit then 0 ; : ?clib-abort ( flag -> ) errorstr ?abort ; -: clib-load ( a u -> handle ) - dup if s>z else 2drop 0 then - RTLD_LAZY dlopen dup 0 = ?clib-abort ; +: (clib-open) ( name #name -> handle ) + dup if s>z else nip 0 then RTLD_LAZY dlopen ; + +: clib-open ( name #name -> handle ) + (clib-open) dup 0 = ?clib-abort ; -: clib-symbol ( handle a u -> 'func ) - s>z dlsym dup 0 = ?clib-abort ; +: clib-symbol ( a u -> 'func ) + s>z handle @ swap dlsym dup 0 = ?clib-abort ; -: cfunc>entry ( handle Cname #Cname nopname #nopname -> 'func ) +: cfunc>entry ( Cname #Cname nopname #nopname -> definition ) 2push clib-symbol 2pop entry, codep @ swap >cfa ! ; : callC0 \ no input arguments, only create space for return value ` dup ; -: callC, ( #ret #args 'func -> ) - push prolog, +: callC, ( #args #ret definition -> ) + push swap prolog, dup 5 > " too many arguments to C function" ?abort dup 4 > if callC5 then dup 3 > if callC4 then @@ -38,14 +36,21 @@ forth callC0 then pop call, 0 = if ` drop then epilog, ` exit ; -forth +: no-dot? ( a u -> bool ) [char] . scan nip 0 = ; + +: shortcut->real-name ( a u -> a' u' ) + 2dup no-dot? if extension string+ then ; ( User API ) -0 value handle +: Clibrary: + create latest @ @ definition-name@ shortcut->real-name clib-open dup , handle ! + does> @ handle ! ; + +\ Return the local name by which Cname will be called +: local-name ( Cname #Cname -> Cname #Cname localname #localname ) + word dup 0 = if 2drop 2dup then ; -: library: - handle if handle dlclose drop then - word clib-load to handle ; +: Cfunction: ( #args #ret -> ) ( input: "Cname" "localname" ) + word local-name cfunc>entry callC, ; -: Cfunction: ( #args #ret "Cname" "nopname" -> ) - swap handle word word cfunc>entry callC, ; +Clibrary: libc diff --git a/lib/nop/clib/elf-extension.ns b/lib/nop/clib/elf-extension.ns new file mode 100644 index 0000000..307f60e --- /dev/null +++ b/lib/nop/clib/elf-extension.ns @@ -0,0 +1,4 @@ +\ SPDX-License-Identifier: MIT +\ Copyright (c) 2024 Iruatã Martins dos Santos Souza + +: extension " .so" ; diff --git a/lib/nop/clib/macho-extension.ns b/lib/nop/clib/macho-extension.ns new file mode 100644 index 0000000..aee35fe --- /dev/null +++ b/lib/nop/clib/macho-extension.ns @@ -0,0 +1,4 @@ +\ SPDX-License-Identifier: MIT +\ Copyright (c) 2024 Iruatã Martins dos Santos Souza + +: extension " .dylib" ; diff --git a/src/arm64/Darwin.s b/src/arm64/Darwin.s index 60efb86..e9a1fb8 100644 --- a/src/arm64/Darwin.s +++ b/src/arm64/Darwin.s @@ -1,5 +1,5 @@ # SPDX-License-Identifier: MIT -# Copyright (c) 2021-2022 Iruatã Martins dos Santos Souza +# Copyright (c) 2021-2024 Iruatã Martins dos Santos Souza .text #include "arm64/boot.s" @@ -196,6 +196,9 @@ _kernbuf: .incbin "pictured.ns" .incbin "arm64/signals.ns" .incbin "interpreter.ns" +.incbin "../lib/nop/clib/arm64.ns" +.incbin "../lib/nop/clib/macho-extension.ns" +.incbin "../lib/nop/clib.ns" .incbin "file.ns" .incbin "shell.ns" .incbin "loadpaths.ns" diff --git a/src/string.ns b/src/string.ns index f9cd275..1493083 100644 --- a/src/string.ns +++ b/src/string.ns @@ -17,7 +17,7 @@ macro : [char] ( -> b ) char ` lit ; forth -: s>z ( a u -> a' ) here push dup allot r@ swap move 0 1, pop ; +: s>z ( a u -> a' ) tuck here swap move here + 0 swap 1! here ; : zlen ( a -> u ) a! 0 begin 1@+ while 1 + repeat ; : z" ( -> a ) [char] " parse s>z ; : z>mem ( a -> a' u ) dup zlen ; @@ -30,8 +30,10 @@ macro : " [char] " parse ` memlit ; forth : " ( -> a u ) [char] " parse tuck here dup push over allot swap move pop swap ; -: string+ ( a1 u1 a2 u2 -> a3 u1+u2 ) - here push 2push tuck mem, 2pop tuck mem, + pop swap ; +: string+ ( a1 u1 a2 u2 -> a3 u1+u2 ) \ XXX shouldn't allot + 2push tuck pad swap move ( u1 ) ( r: a2 u2 ) + pad + pop over r@ ( pad+u1 a2 pad+u1 u2 ) move + pop + ( pad+u1+u2 ) pad swap over - ; : string= ( a1 u1 a2 u2 -> bool ) swap push over ~= if 2drop rdrop false exit then diff --git a/src/x86_64/Darwin.s b/src/x86_64/Darwin.s index 5c382a3..083b077 100644 --- a/src/x86_64/Darwin.s +++ b/src/x86_64/Darwin.s @@ -280,6 +280,9 @@ _kernbuf: .incbin "string.ns" .incbin "pictured.ns" .incbin "interpreter.ns" +.incbin "../lib/nop/clib/x86_64.ns" +.incbin "../lib/nop/clib/macho-extension.ns" +.incbin "../lib/nop/clib.ns" .incbin "file.ns" .incbin "shell.ns" .incbin "loadpaths.ns" diff --git a/src/x86_64/Linux.s b/src/x86_64/Linux.s index b0e0102..6a18369 100644 --- a/src/x86_64/Linux.s +++ b/src/x86_64/Linux.s @@ -1,5 +1,5 @@ # SPDX-License-Identifier: MIT -# Copyright (c) 2018-2022 Iruatã Martins dos Santos Souza +# Copyright (c) 2018-2024 Iruatã Martins dos Santos Souza .equ MAP_ANONYMOUS, 0x20 errnoaddr = __errno_location @@ -21,6 +21,9 @@ _kernbuf: .incbin "string.ns" .incbin "pictured.ns" .incbin "interpreter.ns" +.incbin "../lib/nop/clib/x86_64.ns" +.incbin "../lib/nop/clib/elf-extension.ns" +.incbin "../lib/nop/clib.ns" .incbin "file.ns" .incbin "shell.ns" .incbin "loadpaths.ns" diff --git a/test/clib.ns b/test/clib.ns index 607ffe1..362d1c0 100644 --- a/test/clib.ns +++ b/test/clib.ns @@ -1,11 +1,9 @@ \ SPDX-License-Identifier: MIT -\ Copyright (c) 2018-2022 Iruatã Martins dos Santos Souza +\ Copyright (c) 2018-2024 Iruatã Martins dos Santos Souza -include lib/nop/clib.ns - -library: -1 1 Cfunction: puts puts -0 1 Cfunction: fork fork +Clibrary: libc +libc 1 1 Cfunction: puts +libc 0 1 Cfunction: fork z" clib test" puts drop