From c50b1c2346d264622a736eb3aef5e86d73d70dea Mon Sep 17 00:00:00 2001 From: Andrew Johnston Date: Fri, 1 Dec 2023 20:16:32 +0000 Subject: [PATCH 1/4] tweaks --- lib/bench.js | 16 ++++++---------- main.js | 2 +- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/lib/bench.js b/lib/bench.js index 3885ec2..43376ef 100644 --- a/lib/bench.js +++ b/lib/bench.js @@ -1,3 +1,5 @@ +import { mem } from 'lib/proc.js' + const { AY, AD, AG, AM } = lo.colors function pad (v, size, precision = 0) { @@ -16,11 +18,9 @@ class Bench { #end = 0 #name = 'bench' #display = true - #mem = undefined - constructor (display = true, mem) { + constructor (display = true) { this.#display = display - this.#mem = mem } start (name = 'bench', pad = 32) { @@ -33,13 +33,9 @@ class Bench { const elapsed = this.#end - this.#start const rate = Math.floor(count / (elapsed / 1e9)) const nanos = 1000000000 / rate - if (this.#mem) { - const rss = this.#mem() - if (this.#display) console.log(`${this.#name} ${AG}rate${AD} ${pad(rate, 10)} ${formatNanos(nanos)} ${AM}rss${AD} ${rss}`) - return { name: this.#name.trim(), count, elapsed, rate, nanos, rss } - } - if (this.#display) console.log(`${this.#name} ${AG}rate${AD} ${pad(rate, 10)} ${formatNanos(nanos)}`) - return { name: this.#name.trim(), count, elapsed, rate, nanos } + const rss = mem() + if (this.#display) console.log(`${this.#name} ${AG}rate${AD} ${pad(rate, 10)} ${formatNanos(nanos)} ${AM}rss${AD} ${rss}`) + return { name: this.#name.trim(), count, elapsed, rate, nanos, rss } } } diff --git a/main.js b/main.js index 889c0a2..641b9ca 100644 --- a/main.js +++ b/main.js @@ -351,7 +351,7 @@ lo.core = core // todo: should we just overwrite the existing ones and not put these on "lo"? lo.getenv = wrap_getenv() lo.getcwd = wrap_getcwd() -const LO_HOME = lo.getenv('LO_HOME') +const LO_HOME = lo.getenv('LO_HOME') || './' const LO_CACHE = parseInt(lo.getenv('LO_CACHE') || '0', 10) core.dlopen = wrap(handle, core.dlopen, 2) core.dlsym = wrap(handle, core.dlsym, 2) From a007d4684bc51e9cd3494ea2fe1767ed6993db49 Mon Sep 17 00:00:00 2001 From: Andrew Johnston Date: Fri, 1 Dec 2023 20:39:43 +0000 Subject: [PATCH 2/4] additional duckdb apis --- lib/duckdb/api.js | 37 ++++++++++++- lib/duckdb/duckdb.cc | 125 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 160 insertions(+), 2 deletions(-) diff --git a/lib/duckdb/api.js b/lib/duckdb/api.js index 96c842d..118e049 100644 --- a/lib/duckdb/api.js +++ b/lib/duckdb/api.js @@ -85,6 +85,39 @@ const api = { pointers: ['duckdb_prepared_statement', 'duckdb_result*'], result: 'i32', name: 'duckdb_execute_prepared' + }, + duckdb_column_name: { + // todo: these should be u64 + parameters: ['pointer', 'u32'], + pointers: ['duckdb_result*'], + result: 'pointer', + rpointer: 'const char*', + name: 'duckdb_column_name' + }, + result_error: { + parameters: ['pointer'], + pointers: ['duckdb_result*'], + result: 'pointer', + rpointer: 'const char*', + name: 'duckdb_result_error' + }, + value_is_null: { + parameters: ['pointer', 'u32', 'u32'], + pointers: ['duckdb_result*'], + result: 'u32', + name: 'duckdb_value_is_null' + }, + disconnect: { + parameters: ['pointer'], + pointers: ['duckdb_connection*'], + result: 'void', + name: 'duckdb_disconnect' + }, + library_version: { + parameters: [], + result: 'pointer', + rpointer: 'const char*', + name: 'duckdb_library_version' } } @@ -99,7 +132,9 @@ const obj = [ 'deps/duckdb/duckdb.o', 'duckdb.a' ] -const constants = {} +const constants = { + DuckDBSuccess: 'i32', DuckDBError: 'i32' +} const include_paths = ['./deps/duckdb/src/include'] const includes = [ 'duckdb.h' diff --git a/lib/duckdb/duckdb.cc b/lib/duckdb/duckdb.cc index 8b556eb..61a40b4 100644 --- a/lib/duckdb/duckdb.cc +++ b/lib/duckdb/duckdb.cc @@ -209,6 +209,57 @@ v8::CTypeInfo rcexecute_prepared = v8::CTypeInfo(v8::CTypeInfo::Type::kInt32); v8::CFunctionInfo infoexecute_prepared = v8::CFunctionInfo(rcexecute_prepared, 3, cargsexecute_prepared); v8::CFunction pFexecute_prepared = v8::CFunction((const void*)&execute_preparedFast, &infoexecute_prepared); +void duckdb_column_nameFast(void* p, void* p0, uint32_t p1, struct FastApiTypedArray* const p_ret); +v8::CTypeInfo cargsduckdb_column_name[4] = { + v8::CTypeInfo(v8::CTypeInfo::Type::kV8Value), + v8::CTypeInfo(v8::CTypeInfo::Type::kUint64), + v8::CTypeInfo(v8::CTypeInfo::Type::kUint32), + v8::CTypeInfo(v8::CTypeInfo::Type::kUint32, v8::CTypeInfo::SequenceType::kIsTypedArray, v8::CTypeInfo::Flags::kNone) +}; +v8::CTypeInfo rcduckdb_column_name = v8::CTypeInfo(v8::CTypeInfo::Type::kVoid); +v8::CFunctionInfo infoduckdb_column_name = v8::CFunctionInfo(rcduckdb_column_name, 4, cargsduckdb_column_name); +v8::CFunction pFduckdb_column_name = v8::CFunction((const void*)&duckdb_column_nameFast, &infoduckdb_column_name); + +void result_errorFast(void* p, void* p0, struct FastApiTypedArray* const p_ret); +v8::CTypeInfo cargsresult_error[3] = { + v8::CTypeInfo(v8::CTypeInfo::Type::kV8Value), + v8::CTypeInfo(v8::CTypeInfo::Type::kUint64), + v8::CTypeInfo(v8::CTypeInfo::Type::kUint32, v8::CTypeInfo::SequenceType::kIsTypedArray, v8::CTypeInfo::Flags::kNone) +}; +v8::CTypeInfo rcresult_error = v8::CTypeInfo(v8::CTypeInfo::Type::kVoid); +v8::CFunctionInfo inforesult_error = v8::CFunctionInfo(rcresult_error, 3, cargsresult_error); +v8::CFunction pFresult_error = v8::CFunction((const void*)&result_errorFast, &inforesult_error); + +uint32_t value_is_nullFast(void* p, void* p0, uint32_t p1, uint32_t p2); +v8::CTypeInfo cargsvalue_is_null[4] = { + v8::CTypeInfo(v8::CTypeInfo::Type::kV8Value), + v8::CTypeInfo(v8::CTypeInfo::Type::kUint64), + v8::CTypeInfo(v8::CTypeInfo::Type::kUint32), + v8::CTypeInfo(v8::CTypeInfo::Type::kUint32), +}; +v8::CTypeInfo rcvalue_is_null = v8::CTypeInfo(v8::CTypeInfo::Type::kUint32); +v8::CFunctionInfo infovalue_is_null = v8::CFunctionInfo(rcvalue_is_null, 4, cargsvalue_is_null); +v8::CFunction pFvalue_is_null = v8::CFunction((const void*)&value_is_nullFast, &infovalue_is_null); + +void disconnectFast(void* p, void* p0); +v8::CTypeInfo cargsdisconnect[2] = { + v8::CTypeInfo(v8::CTypeInfo::Type::kV8Value), + v8::CTypeInfo(v8::CTypeInfo::Type::kUint64), +}; +v8::CTypeInfo rcdisconnect = v8::CTypeInfo(v8::CTypeInfo::Type::kVoid); +v8::CFunctionInfo infodisconnect = v8::CFunctionInfo(rcdisconnect, 2, cargsdisconnect); +v8::CFunction pFdisconnect = v8::CFunction((const void*)&disconnectFast, &infodisconnect); + +void library_versionFast(void* p, struct FastApiTypedArray* const p_ret); +v8::CTypeInfo cargslibrary_version[2] = { + v8::CTypeInfo(v8::CTypeInfo::Type::kV8Value), + + v8::CTypeInfo(v8::CTypeInfo::Type::kUint32, v8::CTypeInfo::SequenceType::kIsTypedArray, v8::CTypeInfo::Flags::kNone) +}; +v8::CTypeInfo rclibrary_version = v8::CTypeInfo(v8::CTypeInfo::Type::kVoid); +v8::CFunctionInfo infolibrary_version = v8::CFunctionInfo(rclibrary_version, 2, cargslibrary_version); +v8::CFunction pFlibrary_version = v8::CFunction((const void*)&library_versionFast, &infolibrary_version); + void create_configSlow(const FunctionCallbackInfo &args) { @@ -397,6 +448,71 @@ int32_t execute_preparedFast(void* p, void* p0, void* p1) { duckdb_result* v1 = reinterpret_cast(p1); return duckdb_execute_prepared(v0, v1); } +void duckdb_column_nameSlow(const FunctionCallbackInfo &args) { + duckdb_result* v0 = reinterpret_cast((uint64_t)Local::Cast(args[0])->Value()); + uint32_t v1 = Local::Cast(args[1])->Value(); + const char* rc = duckdb_column_name(v0, v1); + Local ab = args[2].As()->Buffer(); + ((const char**)ab->Data())[0] = rc; +} + +void duckdb_column_nameFast(void* p, void* p0, uint32_t p1, struct FastApiTypedArray* const p_ret) { + duckdb_result* v0 = reinterpret_cast(p0); + uint32_t v1 = p1; + const char* r = duckdb_column_name(v0, v1); + ((const char**)p_ret->data)[0] = r; + +} +void result_errorSlow(const FunctionCallbackInfo &args) { + duckdb_result* v0 = reinterpret_cast((uint64_t)Local::Cast(args[0])->Value()); + const char* rc = duckdb_result_error(v0); + Local ab = args[1].As()->Buffer(); + ((const char**)ab->Data())[0] = rc; +} + +void result_errorFast(void* p, void* p0, struct FastApiTypedArray* const p_ret) { + duckdb_result* v0 = reinterpret_cast(p0); + const char* r = duckdb_result_error(v0); + ((const char**)p_ret->data)[0] = r; + +} +void value_is_nullSlow(const FunctionCallbackInfo &args) { + Isolate *isolate = args.GetIsolate(); + duckdb_result* v0 = reinterpret_cast((uint64_t)Local::Cast(args[0])->Value()); + uint32_t v1 = Local::Cast(args[1])->Value(); + uint32_t v2 = Local::Cast(args[2])->Value(); + uint32_t rc = duckdb_value_is_null(v0, v1, v2); + args.GetReturnValue().Set(Number::New(isolate, rc)); +} + +uint32_t value_is_nullFast(void* p, void* p0, uint32_t p1, uint32_t p2) { + duckdb_result* v0 = reinterpret_cast(p0); + uint32_t v1 = p1; + uint32_t v2 = p2; + return duckdb_value_is_null(v0, v1, v2); +} +void disconnectSlow(const FunctionCallbackInfo &args) { + duckdb_connection* v0 = reinterpret_cast((uint64_t)Local::Cast(args[0])->Value()); + duckdb_disconnect(v0); +} + +void disconnectFast(void* p, void* p0) { + duckdb_connection* v0 = reinterpret_cast(p0); + duckdb_disconnect(v0); +} +void library_versionSlow(const FunctionCallbackInfo &args) { + + const char* rc = duckdb_library_version(); + Local ab = args[0].As()->Buffer(); + ((const char**)ab->Data())[0] = rc; +} + +void library_versionFast(void* p, struct FastApiTypedArray* const p_ret) { + + const char* r = duckdb_library_version(); + ((const char**)p_ret->data)[0] = r; + +} void Init(Isolate* isolate, Local target) { Local module = ObjectTemplate::New(isolate); @@ -414,7 +530,14 @@ void Init(Isolate* isolate, Local target) { SET_FAST_METHOD(isolate, module, "destroy_result", &pFdestroy_result, destroy_resultSlow); SET_FAST_METHOD(isolate, module, "destroy_prepare", &pFdestroy_prepare, destroy_prepareSlow); SET_FAST_METHOD(isolate, module, "execute_prepared", &pFexecute_prepared, execute_preparedSlow); - + SET_FAST_METHOD(isolate, module, "duckdb_column_name", &pFduckdb_column_name, duckdb_column_nameSlow); + SET_FAST_METHOD(isolate, module, "result_error", &pFresult_error, result_errorSlow); + SET_FAST_METHOD(isolate, module, "value_is_null", &pFvalue_is_null, value_is_nullSlow); + SET_FAST_METHOD(isolate, module, "disconnect", &pFdisconnect, disconnectSlow); + SET_FAST_METHOD(isolate, module, "library_version", &pFlibrary_version, library_versionSlow); + + SET_VALUE(isolate, module, "DuckDBSuccess", Integer::New(isolate, DuckDBSuccess)); + SET_VALUE(isolate, module, "DuckDBError", Integer::New(isolate, DuckDBError)); SET_VALUE(isolate, module, "struct_duckdb_config_size", Integer::New(isolate, sizeof(duckdb_config))); SET_VALUE(isolate, module, "struct_duckdb_result_size", Integer::New(isolate, sizeof(duckdb_result))); From d8ab2bb29b0da2c6bdda53fc31e6a48f4f10473b Mon Sep 17 00:00:00 2001 From: Andrew Johnston Date: Fri, 1 Dec 2023 20:40:25 +0000 Subject: [PATCH 3/4] bump version --- Makefile | 2 +- lib/build.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index b07dbee..ff540c1 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ CCARGS=-std=c++17 -c -fno-omit-frame-pointer -fno-rtti -fno-exceptions CARGS=-c -fno-omit-frame-pointer WARN=-Werror -Wpedantic -Wall -Wextra -Wno-unused-parameter OPT=-O3 -VERSION=0.0.5-pre +VERSION=0.0.6-pre V8_VERSION=1.0.0 RUNTIME=lo LO_HOME=$(shell pwd) diff --git a/lib/build.js b/lib/build.js index ba52ac2..6d6303a 100644 --- a/lib/build.js +++ b/lib/build.js @@ -228,7 +228,7 @@ const encoder = new TextEncoder() const status = new Int32Array(2) // todo: clean up api so we can pass a config in and run builds through api -const VERSION = getenv('VERSION') || '"0.0.5pre"' +const VERSION = getenv('VERSION') || '"0.0.6pre"' const RUNTIME = getenv('RUNTIME') || '"lo"' const TARGET = getenv('TARGET') || 'lo' const C = getenv('C') || 'gcc' From 959237f480c3d99f439c26c7e48ad73173cadd93 Mon Sep 17 00:00:00 2001 From: Andrew Johnston Date: Fri, 1 Dec 2023 21:53:36 +0000 Subject: [PATCH 4/4] add duckdb bindings to runtime config --- builtins.S | 5 +++++ builtins_linux.S | 5 +++++ lib/build.js | 1 + main.h | 3 +++ main_win.h | 1 + 5 files changed, 15 insertions(+) diff --git a/builtins.S b/builtins.S index cc169dc..2f7c56c 100644 --- a/builtins.S +++ b/builtins.S @@ -73,6 +73,11 @@ __binary_lib_curl_api_js_start: .incbin "lib/curl/api.js" .global __binary_lib_curl_api_js_end __binary_lib_curl_api_js_end: +.global __binary_lib_duckdb_api_js_start +__binary_lib_duckdb_api_js_start: + .incbin "lib/duckdb/api.js" + .global __binary_lib_duckdb_api_js_end +__binary_lib_duckdb_api_js_end: .global __binary_lib_encode_api_js_start __binary_lib_encode_api_js_start: .incbin "lib/encode/api.js" diff --git a/builtins_linux.S b/builtins_linux.S index ef858c4..98fc073 100644 --- a/builtins_linux.S +++ b/builtins_linux.S @@ -73,6 +73,11 @@ _binary_lib_curl_api_js_start: .incbin "lib/curl/api.js" .global _binary_lib_curl_api_js_end _binary_lib_curl_api_js_end: +.global _binary_lib_duckdb_api_js_start +_binary_lib_duckdb_api_js_start: + .incbin "lib/duckdb/api.js" + .global _binary_lib_duckdb_api_js_end +_binary_lib_duckdb_api_js_end: .global _binary_lib_encode_api_js_start _binary_lib_encode_api_js_start: .incbin "lib/encode/api.js" diff --git a/lib/build.js b/lib/build.js index 6d6303a..6d2a734 100644 --- a/lib/build.js +++ b/lib/build.js @@ -278,6 +278,7 @@ const runtimes = { 'lo.h', 'lib/core/api.js', 'lib/curl/api.js', + 'lib/duckdb/api.js', 'lib/encode/api.js', 'lib/epoll/api.js', 'lib/inflate/api.js', diff --git a/main.h b/main.h index 359f3a7..09eff51 100644 --- a/main.h +++ b/main.h @@ -35,6 +35,8 @@ extern char _binary_lib_core_api_js_start[]; extern char _binary_lib_core_api_js_end[]; extern char _binary_lib_curl_api_js_start[]; extern char _binary_lib_curl_api_js_end[]; +extern char _binary_lib_duckdb_api_js_start[]; +extern char _binary_lib_duckdb_api_js_end[]; extern char _binary_lib_encode_api_js_start[]; extern char _binary_lib_encode_api_js_end[]; extern char _binary_lib_epoll_api_js_start[]; @@ -94,6 +96,7 @@ void register_builtins() { lo::builtins_add("lo.h", _binary_lo_h_start, _binary_lo_h_end - _binary_lo_h_start); lo::builtins_add("lib/core/api.js", _binary_lib_core_api_js_start, _binary_lib_core_api_js_end - _binary_lib_core_api_js_start); lo::builtins_add("lib/curl/api.js", _binary_lib_curl_api_js_start, _binary_lib_curl_api_js_end - _binary_lib_curl_api_js_start); + lo::builtins_add("lib/duckdb/api.js", _binary_lib_duckdb_api_js_start, _binary_lib_duckdb_api_js_end - _binary_lib_duckdb_api_js_start); lo::builtins_add("lib/encode/api.js", _binary_lib_encode_api_js_start, _binary_lib_encode_api_js_end - _binary_lib_encode_api_js_start); lo::builtins_add("lib/epoll/api.js", _binary_lib_epoll_api_js_start, _binary_lib_epoll_api_js_end - _binary_lib_epoll_api_js_start); lo::builtins_add("lib/inflate/api.js", _binary_lib_inflate_api_js_start, _binary_lib_inflate_api_js_end - _binary_lib_inflate_api_js_start); diff --git a/main_win.h b/main_win.h index 8b0fbe7..d0f070b 100644 --- a/main_win.h +++ b/main_win.h @@ -29,6 +29,7 @@ void register_builtins() { lo::builtins_add("lo.h", _binary_lo_h_start, _binary_lo_h_len); lo::builtins_add("lib/core/api.js", _binary_lib_core_api_js_start, _binary_lib_core_api_js_len); lo::builtins_add("lib/curl/api.js", _binary_lib_curl_api_js_start, _binary_lib_curl_api_js_len); + lo::builtins_add("lib/duckdb/api.js", _binary_lib_duckdb_api_js_start, _binary_lib_duckdb_api_js_len); lo::builtins_add("lib/encode/api.js", _binary_lib_encode_api_js_start, _binary_lib_encode_api_js_len); lo::builtins_add("lib/epoll/api.js", _binary_lib_epoll_api_js_start, _binary_lib_epoll_api_js_len); lo::builtins_add("lib/inflate/api.js", _binary_lib_inflate_api_js_start, _binary_lib_inflate_api_js_len);