Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
a0e835b
chore: get windows basics working without breaking existing
billywhizz Dec 31, 2025
50c90dc
fix: use CLOCK_MONOTONIC directly
billywhizz Dec 31, 2025
93a567e
fix: macos build
billywhizz Dec 31, 2025
422ac93
chore: windoze build mostly working
billywhizz Jan 1, 2026
18335f8
chore: windows build - inflate, tweaks
billywhizz Jan 1, 2026
f9f6857
chore: generate main_win.h
billywhizz Jan 1, 2026
eccf0d3
chore: build inflate for windows
billywhizz Jan 1, 2026
3a27e13
chore: more builtins for windows
billywhizz Jan 1, 2026
33751da
chore: memory usage for windows
billywhizz Jan 1, 2026
e3cfa94
chore: update builtins.h
billywhizz Jan 1, 2026
1cfa488
chore: nicer build script for windows
billywhizz Jan 1, 2026
4c0a3f4
chore: basic createProcess for windows
billywhizz Jan 2, 2026
95ac834
chore: check in core2 source
billywhizz Jan 2, 2026
3065e9c
chore: giving up on curl for now
billywhizz Jan 2, 2026
3e1553b
chore: try a windows ci build
billywhizz Jan 2, 2026
06416c1
chore: download deps on windows build
billywhizz Jan 2, 2026
9e05d8b
chore: try to fix ci
billywhizz Jan 2, 2026
1e83294
feat: repl for windows
billywhizz Jan 18, 2026
1a8ce9f
feat: md4c bindings
billywhizz Jan 30, 2026
a72945b
feat: cpio support
billywhizz Jan 31, 2026
7f1642b
feat: ffi callbacks
billywhizz Jan 31, 2026
db7eb1b
feat: fs fixes & stat working on linux
billywhizz Jan 31, 2026
1f8c0fe
fix: codegen fixes
billywhizz Jan 31, 2026
a958f57
fix: hash fixes
billywhizz Jan 31, 2026
08da370
chore: remove repl logo
billywhizz Jan 31, 2026
6c3cec3
fix: sqlite fixes
billywhizz Jan 31, 2026
083b3ec
fix: tuntap fixes
billywhizz Jan 31, 2026
4d41550
chore: assembler improvements
billywhizz Jan 31, 2026
109b95f
fix: don't leak memory in compiler
billywhizz Jan 31, 2026
829058a
chore: update boringssl
billywhizz Jan 31, 2026
86c0f50
chore: add some syscalls to core
billywhizz Jan 31, 2026
cd96fc0
chore: add some syscalls to core
billywhizz Jan 31, 2026
608f967
fix: sqlite - use pointers
billywhizz Jan 31, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 5 additions & 7 deletions .github/workflows/push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -139,23 +139,21 @@ jobs:
name: lo-linux-${{ matrix.platform }}

build-windows:
if: ${{ false }} # disable
# if: ${{ false }} # disable
name: windows
runs-on: windows-2022
runs-on: windows-latest
strategy:
fail-fast: false
matrix:
platform: [x64,arm64]
platform: [x64]
steps:
- uses: actions/checkout@v3
- name: Install MSVC/MCBuild (Windows)
uses: microsoft/setup-msbuild@v1.0.2
- name: compile
shell: cmd
run: |
make BINDINGS= ARCH=${{ matrix.platform }} lo.exe
- name: check
run: |
make check
call ${{ github.workspace}}\build.cmd
- name: upload artifact
uses: actions/upload-artifact@v4
with:
Expand Down
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ notes.md
lib/inflate/em_inflate.c
lib/inflate/em_inflate.h
lib/**/*.cc
!lib/win/win.cc
!lib/core/core.cc
!lib/core2/core.cc
!lib/curl/curl.cc
!lib/inflate/inflate.cc
!lib/mach/mach.cc
Expand All @@ -32,4 +34,5 @@ node_modules
lib/lines/linenoise.h
lib/lines/linenoise.c
zero
dist
dist
*.pdb
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ CCARGS=-fPIC -std=c++20 -c -fno-omit-frame-pointer -fno-rtti -fno-exceptions -fv
CARGS=-fPIC -c -fno-omit-frame-pointer -fvisibility=hidden
WARN=-Werror -Wpedantic -Wall -Wextra -Wno-unused-parameter -Wno-error=unknown-warning-option
OPT=-O3
VERSION=0.0.23-pre
VERSION=0.0.24-pre
V8_VERSION=14.3
RUNTIME=lo
LO_HOME=$(shell pwd)
Expand Down
53 changes: 53 additions & 0 deletions build.cmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
@echo off
set VERSION=0.0.24-pre
set V8=14.3
set RUNTIME=lo
set V8_OPTS=-DV8_TYPED_ARRAY_MAX_SIZE_IN_HEAP=64 -DV8_ALLOCATION_FOLDING -DV8_SHORT_BUILTIN_CALLS
set OPTS=-std=c++20 -fomit-frame-pointer -fno-rtti -fno-exceptions -O3 -march=native -mtune=native
set WARN=-Werror -Wpedantic -Wall -Wextra -Wno-unused-parameter -Wno-error=unknown-warning-option
set OBJS=lo.o main.o win.o core.o inflate.o lib\inflate\em_inflate.o
set LOPTS=-lwinmm -ldbghelp -lbcrypt
set INCLUDE=-I. -I./v8 -I./v8/include
set BUILTINS=lib/inflate.js lib/gen.js lib/path.js lib/proc.js lib/stringify.js lib/binary.js
if "%WindowsSdkDir%"== "" (
call "C:\Program Files (x86)\Microsoft Visual Studio\18\BuildTools\VC\Auxiliary\Build\vcvars64.bat"
)
if not exist v8 (
mkdir v8
cd v8
curl -L -O https://github.com/just-js/v8/releases/download/%V8%/include.tar.gz
tar -xvf include.tar.gz
curl -L -O https://github.com/just-js/v8/releases/download/%V8%/libv8_monolith-win-x64.zip
tar -xvf libv8_monolith-win-x64.zip
del /Q *.zip
del /Q *.gz
cd ..
)
if exist lo.exe (
lo.exe gen --builtins --win main.js %BUILTINS% > builtins.h
lo.exe gen lib\core2\api.js > lib\core2\core.cc
lo.exe gen --header --win core.a win.a inflate.a %BUILTINS% > main_win.h
)
if not exist lib\inflate\em_inflate.o (
cd lib\inflate
if not exist em_inflate.h (
curl -s -O https://raw.githubusercontent.com/emmanuel-marty/em_inflate/master/lib/em_inflate.h
)
if not exist em_inflate.c (
curl -s -O https://raw.githubusercontent.com/emmanuel-marty/em_inflate/master/lib/em_inflate.c
)
clang -I. -c -o em_inflate.o -O3 em_inflate.c
cd ..\..
)
clang++ %OPTS% %WARN% %INCLUDE% -c %V8_OPTS% lib/win/win.cc
clang++ %OPTS% %WARN% %INCLUDE% -c %V8_OPTS% -Ilib/inflate lib/inflate/inflate.cc
clang++ %OPTS% %WARN% %INCLUDE% -c %V8_OPTS% -D_CRT_SECURE_NO_WARNINGS lib/core2/core.cc
clang++ %OPTS% %WARN% %INCLUDE% -c %V8_OPTS% -DVERSION=\"%VERSION%\" -DRUNTIME=\"%RUNTIME%\" lo.cc
clang++ %OPTS% %WARN% %INCLUDE% -c %V8_OPTS% -DVERSION=\"%VERSION%\" -DRUNTIME=\"%RUNTIME%\" main.cc
REM set CURLP=scratch\curl\curl-8.17.0_6-win64-mingw\
REM clang++ %OPTS% %INCLUDE% -I%CURLP%include -c %V8_OPTS% -DNOMINMAX lib/curl/curl.cc
REM clang++ v8\v8_monolith.lib %OBJS% curl.o -L %CURLP%lib -l libcurl -l libcurl.dll -l libbrotlicommon -l libbrotlidec -l libcrypto -l libnghttp2 -l libnghttp3 -l libngtcp2 -l libngtcp2_crypto_libressl -l libpsl -l libssh2 -l libz -l libzstd %LOPTS% -o lo.tmp.exe
clang++ v8\v8_monolith.lib %OBJS% %LOPTS% -o %RUNTIME%.tmp.exe
move /Y %RUNTIME%.tmp.exe %RUNTIME%.exe
del *.lib
del *.exp
42 changes: 36 additions & 6 deletions builtins.h

Large diffs are not rendered by default.

8 changes: 8 additions & 0 deletions lib/asm/arm64.js
Original file line number Diff line number Diff line change
Expand Up @@ -781,6 +781,14 @@ class Assembler {
return new Uint8Array(this.#codes.flat())
}

get size () {
let len = 0
for (const code of this.#codes) {
len += code.length
}
return len
}

get src () {
const { codes, instr } = this
return instr.map((v, i) => [`# ${codes[i].reverse().map(v => '0x' + v.toString(16))}`, v]).flat().join('\n') + '\n'
Expand Down
11 changes: 8 additions & 3 deletions lib/asm/compiler.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const { assert, addr, ptr, core } = lo

const {
mprotect, memcpy, mmap,
mprotect, memcpy, mmap, aligned_alloc,
PROT_READ, MAP_PRIVATE, PROT_WRITE, PROT_EXEC, MAP_ANONYMOUS
} = core

Expand All @@ -27,8 +27,13 @@ class Compiler {
const address = mmap(0, code.length, PROT_WRITE, flags,
-1, u32)
assert(address)
assert(memcpy(address, code.ptr, code.length) === address)
assert(mprotect(address, code.length, PROT_EXEC | PROT_READ) === 0)
try {
assert(memcpy(address, code.ptr, code.length) === address)
assert(mprotect(address, code.length, PROT_EXEC | PROT_READ) === 0)
} catch (err) {
munmap(address)
throw err
}
return address
}
}
Expand Down
76 changes: 67 additions & 9 deletions lib/asm/x64.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,9 @@ const op_cmp = 0x3d
const op_je8 = 0x74
const op_je32 = [0x0f, 0x84]

const op_jne8 = 0x75
const op_jne32 = [0x0f, 0x85]

const op_jmp8 = 0xeb
const op_jmp32 = 0xe9

Expand Down Expand Up @@ -247,6 +250,15 @@ class Assembler {
return this
}

test (rega, regb) {
this.#instr.push(`test %${rega}, %${regb}`)
if (rega === 'rax' && regb === 'rax') {
//this.#codes.push([0x48, 0x85, 0xc0])
this.#codes.push([0x85, 0xc0])
}
return this
}

// url: https://www.felixcloutier.com/x86/push
// OpCode: 50 +rd
// Instruction: PUSH r64
Expand Down Expand Up @@ -305,6 +317,16 @@ class Assembler {
return this
}

callr (address) {
// OpCode: E8 cd
// Instruction: call rel32
// Op/En: D
// 1: 32 bit offset
this.#instr.push(`call ${address}`)
this.#codes.push([0xe8, ...as_four_bytes(address)])
return this
}

// url: https://www.felixcloutier.com/x86/jmp
jmp (address, reg = 'rax') {
// OpCode: FF /4
Expand All @@ -315,13 +337,6 @@ class Assembler {
return this
}

// url: https://www.felixcloutier.com/x86/jmp
jmpl (label, reg = 'rax') {
this.#instr.push(`jmp :${label}`)
this.#codes.push([])
return this
}

// url: https://www.felixcloutier.com/x86/mov
movabs (address, reg) {
// OpCode: REX.W + B8+ rd io
Expand Down Expand Up @@ -380,12 +395,25 @@ class Assembler {
return this
}

// url: https://www.felixcloutier.com/x86/jmp
jmpl (label, reg = 'rax') {
this.#instr.push(`jmp :${label}`)
this.#codes.push([])
return this
}

jel (label) {
this.#instr.push(`jel :${label}`)
this.#codes.push([])
return this
}

jne (label) {
this.#instr.push(`jne :${label}`)
this.#codes.push([])
return this
}

label (name) {
const end = this.#codes.flat().length
let start = 0
Expand All @@ -400,15 +428,23 @@ class Assembler {
} else {
this.#codes[i] = [...op_je32, ...as_four_bytes(distance)]
}
this.#instr[i] = `je :${distance}`
this.#instr[i] = `jel ${distance}`
} else if (instr === `jne :${name}`) {
const distance = end - start
if (distance < pow8) {
this.#codes[i] = [op_jne8, distance]
} else {
this.#codes[i] = [...op_jne32, ...as_four_bytes(distance)]
}
this.#instr[i] = `jne ${distance}`
} else if (instr === `jmp :${name}`) {
const distance = end - start
if (distance < pow8) {
this.#codes[i] = [op_jmp8, distance]
} else {
this.#codes[i] = [op_jmp32, ...as_four_bytes(distance)]
}
this.#instr[i] = `jmp :${distance}`
this.#instr[i] = `jmp ${distance}`
}
}
return this
Expand Down Expand Up @@ -499,6 +535,20 @@ class Assembler {
return this
}

nop () {
this.#instr.push('nop')
this.#codes.push([0x90])
return this
}

pad () {
const extra = this.size % 16
if (extra) {
let padding = 16 - extra
while (padding--) this.nop()
}
}

syscall () {
this.#instr.push('syscall')
this.#codes.push([0x0f, 0x05])
Expand All @@ -515,6 +565,14 @@ class Assembler {
return new Uint8Array(this.#codes.flat())
}

get size () {
let len = 0
for (const code of this.#codes) {
len += code.length
}
return len
}

get src () {
const { codes, instr } = this
return instr.map((v, i) => [`# ${codes[i].map(v => '0x' + v.toString(16))}`, v]).flat().join('\n') + '\n'
Expand Down
4 changes: 2 additions & 2 deletions lib/boringssl/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -582,8 +582,8 @@ const includes = [

const libs = []
const obj = [
'deps/boringssl/build/ssl/libssl.a',
'deps/boringssl/build/crypto/libcrypto.a'
'deps/boringssl/build/libssl.a',
'deps/boringssl/build/libcrypto.a'
]
const include_paths = ['./deps/boringssl/include']
const lib_paths = []
Expand Down
2 changes: 1 addition & 1 deletion lib/boringssl/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ async function build () {
assert(chdir('deps') === 0)
if (!isFile('boringssl.tar.gz')) {
console.log('fetching release')
fetch('https://codeload.github.com/google/boringssl/tar.gz/master',
fetch('https://codeload.github.com/google/boringssl/tar.gz/main',
'boringssl.tar.gz')
}
const bytes = readFile('boringssl.tar.gz')
Expand Down
31 changes: 27 additions & 4 deletions lib/core/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,22 @@ const api = {
parameters: [],
result: 'i32'
},
getsid: {
parameters: ['i32'],
result: 'i32'
},
setsid: {
parameters: [],
result: 'i32'
},
getpgrp: {
parameters: [],
result: 'i32'
},
setpgid: {
parameters: ['i32', 'i32'],
result: 'i32'
},
fork: {
parameters: [],
result: 'i32'
Expand Down Expand Up @@ -734,8 +750,9 @@ const constants = {
S_IFBLK: 'i32', S_IFCHR: 'i32', S_IFIFO: 'i32',
S_IRUSR: 'i32', S_IWUSR: 'i32', S_IRGRP: 'i32', S_IWGRP: 'i32',
S_IROTH: 'i32', S_IWOTH: 'i32', O_RDONLY: 'i32', O_WRONLY: 'i32',
O_CREAT: 'i32', S_IRWXU: 'i32', S_IRWXG: 'i32', S_IXOTH: 'i32',
O_TRUNC: 'i32', STDIN: 0, STDOUT: 1, STDERR: 2, O_CLOEXEC: 'i32',
O_CREAT: 'i32', S_IXOTH: 'i32',
S_IXUSR: 'i32', S_IXGRP: 'i32', S_IRWXU: 'i32', S_IRWXG: 'i32',
O_TRUNC: 'i32', STDIN: 0, STDOUT: 1, STDERR: 2, O_CLOEXEC: 'i32',
RUSAGE_SELF: 'i32', SEEK_SET: 'i32', SEEK_CUR: 'i32',
SEEK_END: 'i32', S_IRWXO: 'i32', F_OK: 'i32', S_IFMT: 'i32', S_IFDIR: 'i32',
S_IFREG: 'i32', NAME_MAX: 'u32', O_RDWR: 'i32', O_SYNC: 'i32',
Expand All @@ -760,7 +777,7 @@ const constants = {
DT_UNKNOWN: 'i32',
}

const structs = ['clock_t', 'fastcall']
const structs = ['clock_t', 'fastcall', 'struct stat', 'struct timespec', 'dev_t', 'ino_t', 'mode_t', 'nlink_t', 'uid_t', 'gid_t', 'off_t', 'blksize_t', 'blkcnt_t']

// list of headers to include
const includes = [
Expand Down Expand Up @@ -801,9 +818,15 @@ const linux = {
'linux/reboot.h',
'sys/ioctl.h',
'dirent.h',
'sched.h'
'sched.h',
'sys/sysmacros.h'
],
api: {
makedev: {
parameters: ['u32', 'u32'],
result: 'u32',
name: 'gnu_dev_makedev'
},
posix_fadvise: {
parameters: ['i32', 'u32', 'u32', 'i32'],
result: 'i32'
Expand Down
Loading
Loading