Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Basic type definitions #32

Merged
merged 4 commits into from
May 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
449 changes: 407 additions & 42 deletions globals.d.ts

Large diffs are not rendered by default.

8 changes: 0 additions & 8 deletions jsconfig.json

This file was deleted.

32 changes: 32 additions & 0 deletions lib/@typify/typify.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@

type ARCH = 'x64';
type CType = 'u64' | 'f64' | 'u32' | 'i64' | 'f32' | 'i32' | 'u8' | 'void' | 'char';
type Pointer = 'pointer'
type Bool = 'bool';
type String = 'string';
type Buffer = 'buffer';
type TypedArray = 'u32array';

// lib_api_typed
type LibApiParameter = Pointer | CType | String | Buffer | TypedArray | Bool;
type LibApiResult = Pointer | CType | Bool;
type LibApiPointer = string; // this is sad
type LibApiOverride = { param: number, fastfield: `${string}->${string}`, slowfield: `${string}.${string}()` } | number;
type LibApiItem = { nofast: boolean; declare_only: boolean; } | {
parameters: LibApiParameter[];
pointers?: (LibApiPointer | void)[];
result: LibApiResult;
rpointer?: LibApiPointer | [LibApiPointer];
name?: string;
arch?: ARCH[];
override?: (LibApiOverride | void)[];
casts?: (string | void)[];
jsdoc?: string;
man?: string[];
nofast?: boolean;
nonblocking?: boolean;
};
type LibApi = Record<string, LibApiItem>;

// TODO: add lib_exports_typed to get types for lib exports
export const lib_api_typed: <const T extends LibApi>(api: T) => T;
3 changes: 3 additions & 0 deletions lib/@typify/typify.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
function passthrough(v){ return v }

export const lib_api_typed = passthrough
6 changes: 4 additions & 2 deletions lib/ada/api.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
const api = {
import { lib_api_typed } from 'lib/@typify/typify.js';

const api = lib_api_typed({
ada_parse: {
parameters: ['pointer', 'u32'],
pointers: ['const char*'],
Expand Down Expand Up @@ -30,7 +32,7 @@ const api = {
parameters: ['pointer'],
result: 'void'
}
}
})

const preamble = `
#ifdef __cplusplus
Expand Down
14 changes: 8 additions & 6 deletions lib/bestlines/api.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
const api = {
import { lib_api_typed } from 'lib/@typify/typify.js';

const api = lib_api_typed({
bestline: {
parameters: ['buffer'],
parameters: ['buffer'],
pointers: ['const char*'],
result: 'pointer'
},
Expand All @@ -13,16 +15,16 @@ const api = {
result: 'i32', name: 'bestlineHistoryAdd'
},
save: {
parameters: ['string'],
parameters: ['string'],
pointers: ['const char*'],
result: 'i32', name: 'bestlineHistorySave'
},
load: {
parameters: ['string'],
parameters: ['string'],
pointers: ['const char*'],
result: 'i32', name: 'bestlineHistoryLoad'
}
}
}
})

const name = 'bestlines'
const includes = ['bestline.h']
Expand Down
8 changes: 5 additions & 3 deletions lib/boringssl/api.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
const api = {
import { lib_api_typed } from 'lib/@typify/typify.js';

const api = lib_api_typed({
OpenSSL_version: {
parameters: ['i32'],
result: 'pointer',
Expand All @@ -15,7 +17,7 @@ const api = {
result: 'i32'
},
EVP_PKEY_keygen: {
parameters: ['pointer', 'pointer'],
parameters: ['pointer', 'pointer'],
pointers: ['EVP_PKEY_CTX*', 'EVP_PKEY**'],
result: 'i32'
},
Expand Down Expand Up @@ -516,7 +518,7 @@ const api = {
pointers: ['SSL*'],
result: 'i32'
},
}
})

const constants = {
SSL_OP_ALL: 'u64',
Expand Down
102 changes: 64 additions & 38 deletions lib/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { is_file, is_dir, mkdir_all_safe } from 'lib/fs.js'
import { inflate } from 'lib/inflate.js'
import { fetch } from 'lib/curl.js'
import { untar } from 'lib/untar.js'
import {
import {
bindings, linkerScript, headerFile, config, linkArgs, libPaths
} from 'lib/gen.js'
import { exec } from 'lib/proc.js'
Expand All @@ -11,7 +11,7 @@ import { fileName, extName, join, baseName } from 'lib/path.js'
const { core, getenv, getcwd, assert, colors } = lo
const { AM, AY, AG, AD } = colors
const {
write_file, chdir, mkdir, read_file, unlink, rename,
write_file, chdir, mkdir, read_file, unlink, rename,
S_IXOTH, S_IRWXU, S_IRWXG, S_IROTH, defaultWriteFlags
} = core

Expand Down Expand Up @@ -71,8 +71,8 @@ async function create_lo_home () {
assert(chdir(LO_HOME) === 0)
const file_name = `libv8_monolith-${os}-${arch}.a.gz`
console.log(`${AY}download v8 static lib for version ${AD}${v8}`)
const size =
fetch(`${v8_url_prefix}/${v8}/libv8_monolith-${os}-${arch}.a.gz`,
const size =
fetch(`${v8_url_prefix}/${v8}/libv8_monolith-${os}-${arch}.a.gz`,
file_name)
assert(size > 0)
console.log(`${AY}downloaded${AD} ${file_name} ${AG}size${AY} ${size}`)
Expand All @@ -85,7 +85,7 @@ async function create_lo_home () {
assert(is_file(v8_lib))
assert(chdir(cwd) === 0)
}
}
}

// todo: change these methods to accept objects, not filenames
async function compile_bindings (lib, verbose = false, opt = OPT, shared = true) {
Expand Down Expand Up @@ -146,14 +146,14 @@ async function compile_bindings (lib, verbose = false, opt = OPT, shared = true)
}
console.log(`${AY}compile${AD} ${def.name}.cc ${AY}with${AG} ${CXX}${AD}`)
unlink(`${def.name}.o`)
exec2([...CXX.split(' '), ...CFLAGS, ...opt.split(' '), `-I${LO_HOME}`, `-I${LO_HOME}/v8`,
exec2([...CXX.split(' '), ...CFLAGS, ...opt.split(' '), `-I${LO_HOME}`, `-I${LO_HOME}/v8`,
...include_paths.map(p => `-I${p}`), '-I.', `-I${LO_HOME}/v8/include`,
`-I${lib_dir}`, ...WARN, '-o', `${def.name}.o`, `${def.name}.cc`], verbose)

console.log(`${AY}static lib ${AD} ${def.name}.a`)
unlink(`${def.name}.a`)
if (obj && obj.length) {
exec2(['ar', 'crsT', `${def.name}.a`, `${def.name}.o`,
exec2(['ar', 'crsT', `${def.name}.a`, `${def.name}.o`,
...obj.filter(f => extName(f) === 'o')], verbose)
} else {
exec2(['ar', 'crsT', `${def.name}.a`, `${def.name}.o`], verbose)
Expand All @@ -162,17 +162,17 @@ async function compile_bindings (lib, verbose = false, opt = OPT, shared = true)
console.log(`${AY}shared lib ${AD} ${def.name}.so ${AY}with${AG} ${CXX}${AD}`)
unlink(`${def.name}.so`)
if (os === 'mac') {
exec2([...LINK.split(' '), '-bundle_loader', LO_PATH, ...LARGS, ...opt.split(' '), '-bundle', ...WARN, '-o',
`${def.name}.so`, `${def.name}.o`,
...(obj || []),
...(libs || []).map(l => `-l${l}`),
exec2([...LINK.split(' '), '-bundle_loader', LO_PATH, ...LARGS, ...opt.split(' '), '-bundle', ...WARN, '-o',
`${def.name}.so`, `${def.name}.o`,
...(obj || []),
...(libs || []).map(l => `-l${l}`),
...(lib_paths || []).map(l => `-L${l}`)],
verbose)
} else if (os === 'linux') {
exec2([...LINK.split(' '), ...LARGS, ...opt.split(' '), '-shared', ...WARN, '-o',
exec2([...LINK.split(' '), ...LARGS, ...opt.split(' '), '-shared', ...WARN, '-o',
`${def.name}.so`, `${def.name}.o`,
...(obj || []),
...(libs || []).map(l => `-l${l}`),
...(libs || []).map(l => `-l${l}`),
...(lib_paths || []).map(l => `-L${l}`)],
verbose)
}
Expand All @@ -198,10 +198,10 @@ function create_builtins (libs = [], main = 'main.js', os) {
return linkerScript(path)
}
config.os = 'linux'
write_file(`${LO_HOME}/builtins_linux.S`,
write_file(`${LO_HOME}/builtins_linux.S`,
encoder.encode(`${Array.from(new Set([main, ...libs])).map(verify_path).join('')}.section .note.GNU-stack,"",@progbits`))
config.os = 'mac'
write_file(`${LO_HOME}/builtins.S`,
write_file(`${LO_HOME}/builtins.S`,
encoder.encode(Array.from(new Set([main, ...libs])).map(verify_path).join('')))
config.os = os
}
Expand Down Expand Up @@ -288,8 +288,8 @@ function check_compilers () {

}

async function build_runtime ({ libs = lo.builtins(), bindings = lo.libraries(),
embeds = [], target, link_type = LINK_TYPE, opt = OPT,
async function build_runtime ({ libs = lo.builtins(), bindings = lo.libraries(),
embeds = [], target, link_type = LINK_TYPE, opt = OPT,
v8_opts = {}, index = '', main = 'main.js' }, verbose = false) {
const cwd = getcwd()
if (index) embeds.push(index)
Expand Down Expand Up @@ -317,14 +317,14 @@ async function build_runtime ({ libs = lo.builtins(), bindings = lo.libraries(),
exec2([...CC.split(' '), '-c', 'builtins.S', '-o', 'builtins.o'], verbose)
}
console.log(`${AY}compile${AD} main.cc`)
exec2([...CXX.split(' '), `-DRUNTIME="${RUNTIME}"`, `-DVERSION="${VERSION}"`,
...CFLAGS, ...opt.split(' '), `-I${LO_HOME}`, `-I${LO_HOME}/v8`,
'-I.', `-I${LO_HOME}/v8/include`, ...WARN, '-o', 'main.o', 'main.cc'],
exec2([...CXX.split(' '), `-DRUNTIME="${RUNTIME}"`, `-DVERSION="${VERSION}"`,
...CFLAGS, ...opt.split(' '), `-I${LO_HOME}`, `-I${LO_HOME}/v8`,
'-I.', `-I${LO_HOME}/v8/include`, ...WARN, '-o', 'main.o', 'main.cc'],
verbose)
console.log(`${AY}compile${AD} lo.cc`)
exec2([...CXX.split(' '), `-DRUNTIME="${RUNTIME}"`, `-DVERSION="${VERSION}"`,
...CFLAGS, ...opt.split(' '), `-I${LO_HOME}`, `-I${LO_HOME}/v8`,
'-I.', `-I${LO_HOME}/v8/include`, ...WARN, '-o', `${target}.o`, `lo.cc`],
exec2([...CXX.split(' '), `-DRUNTIME="${RUNTIME}"`, `-DVERSION="${VERSION}"`,
...CFLAGS, ...opt.split(' '), `-I${LO_HOME}`, `-I${LO_HOME}/v8`,
'-I.', `-I${LO_HOME}/v8/include`, ...WARN, '-o', `${target}.o`, `lo.cc`],
verbose)
console.log(`${AY}link runtime ${AD}`)
assert(chdir(cwd) === 0)
Expand All @@ -337,7 +337,7 @@ async function build_runtime ({ libs = lo.builtins(), bindings = lo.libraries(),
return join(cwd, f)
}
return f
})
})
assert(chdir(LO_HOME) === 0)
let dynamic_libs = await linkArgs(platform_bindings.map(n => `lib/${n}/api.js`))
if (link_type.split(' ').includes('-static')) {
Expand All @@ -347,9 +347,9 @@ async function build_runtime ({ libs = lo.builtins(), bindings = lo.libraries(),
let lib_paths = await libPaths(platform_bindings.map(n => `lib/${n}/api.js`), { prefix: PREFIX })
let bin = target
if (cwd !== LO_HOME) bin = `${join(cwd, target)}`
exec2([...LINK.split(' '), ...LARGS, ...opt.split(' '), ...link_type.split(' '), ...WARN, '-o',
`${bin}`, `${target}.o`, 'main.o', 'builtins.o', 'v8/libv8_monolith.a',
...static_libs, ...dynamic_libs, ...lib_paths].filter(v => v).flat(), verbose)
exec2([...LINK.split(' '), ...LARGS, ...opt.split(' '), ...link_type.split(' '), ...WARN, '-o',
`${bin}`, `${target}.o`, 'main.o', 'builtins.o', 'v8/libv8_monolith.a',
...static_libs, ...dynamic_libs, ...lib_paths].filter(v => v).flat(), verbose)
assert(chdir(cwd) === 0)
}

Expand All @@ -373,7 +373,7 @@ const constants = {}
// put comments in here

export { name, api, constants, preamble }
`
`
}

function generate_config (config) {
Expand Down Expand Up @@ -497,17 +497,43 @@ lib/**/*.a
lib/**/*.so
lib/**/deps
globals.d.ts
jsconfig.json
tsconfig.json
${app_name}
`))
write_file(`jsconfig.json`, encoder.encode(`{
`));

write_file(`tsconfig.json`, encoder.encode(`{
"files": ["${config.default.index}"],
"compilerOptions": {
"paths": {
"lib": ["${LO_HOME}/lib"]
},
"types": [],
"target": "es2022",
"lib": ["es2023"],
"outDir": "dist",
"allowJs": true,
"checkJs": true,
"module": "ES2022",
"target": "ES2022"
"strict": true,
"noImplicitAny": false,
"isolatedModules": true,
"noEmit": false,
"module": "es2022"
},
"exclude": ["scratch", "v8", ".vscode", ".git", ".github"]
}`))
"exclude": ["scratch", "v8", ".vscode", ".git", ".github"],
"include": ["globals.d.ts", "lib"]
}`));

write_file(`README.md`, encoder.encode(`
# Build
\`\`\`sh
lo build runtime ${cwd}/${app_name}
\`\`\`
# Run
\`\`\`sh
./${app_name}
\`\`\`
`));

if (!is_file(`${app_name}.js`)) {
write_file(`${app_name}.js`, encoder.encode(`console.log('hello')`))
}
Expand All @@ -528,7 +554,7 @@ const RUNTIME = getenv('LO_RUNTIME') || 'lo'
const TARGET = getenv('LO_TARGET')
const LINK_TYPE = getenv('LO_LINK_TYPE') || '-rdynamic'
const OPT = getenv('LO_OPT') || '-O3 -march=native -mtune=native'
const WARN = (getenv('LO_WARN') ||
const WARN = (getenv('LO_WARN') ||
'-Werror -Wpedantic -Wall -Wextra -Wno-unused-parameter').split(' ')
const cwd = getcwd()
const LO_HOME = getenv('LO_HOME') || join(cwd, '.lo')
Expand All @@ -539,7 +565,7 @@ const url_prefix = getenv('LO_URL_PREFIX') || `https://github.com/${org}`
const v8_path = getenv('LO_V8_PATH') || 'v8/releases/download'
const v8_url_prefix = `${url_prefix}/${v8_path}`
// todo: way to override these - usse env?
// todo: only set this if memory is > 16 GB on x86_64
// todo: only set this if memory is > 16 GB on x86_64
// --huge-max-old-generation-size
let defaultOpts = {
v8_cleanup: 0, v8_threads: 2, on_exit: 0,
Expand Down Expand Up @@ -602,7 +628,7 @@ if (os === 'mac') {
LO_PATH = lo.latin1Decode(path_name.ptr, len)
}

export {
export {
build, build_runtime, create_binding, compile_bindings, create_lo_home,
install, upgrade, uninstall, init,
config
Expand Down
8 changes: 5 additions & 3 deletions lib/cfzlib/api.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
const api = {
import { lib_api_typed } from 'lib/@typify/typify.js';

const api = lib_api_typed({
deflate: {
parameters: ['buffer', 'u32', 'buffer', 'u32'],
pointers: ['uint8_t*', ,'uint8_t*'],
Expand All @@ -11,7 +13,7 @@ const api = {
result: 'u32',
name: 'zlib_inflate'
}
}
})
const includes = ['zlib.h', 'stdint.h', 'stdlib.h']
const preamble = `
#define Z_DEFAULT_MEMLEVEL 8
Expand Down Expand Up @@ -52,7 +54,7 @@ uint32_t zlib_inflate (uint8_t* src, uint32_t ssize, uint8_t* dest, uint32_t dsi
inflateEnd(stream);
free(stream);
return written;
}
}
`
//const libs = ['z']
const name = 'cfzlib'
Expand Down
Loading
Loading