mirror of
https://github.com/ncruces/go-sqlite3.git
synced 2026-01-12 05:59:14 +00:00
Use SIMD libc.
This commit is contained in:
@@ -19,15 +19,17 @@ trap 'rm -f libc.tmp' EXIT
|
||||
-mnontrapping-fptoint -msign-ext \
|
||||
-fno-stack-protector -fno-stack-clash-protection \
|
||||
-Wl,--initial-memory=16777216 \
|
||||
-Wl,--export=memset \
|
||||
-Wl,--export=memcpy \
|
||||
-Wl,--export=memchr \
|
||||
-Wl,--export=memcmp \
|
||||
-Wl,--export=strlen \
|
||||
-Wl,--export=memcpy \
|
||||
-Wl,--export=memset \
|
||||
-Wl,--export=strchr \
|
||||
-Wl,--export=strchrnul \
|
||||
-Wl,--export=strcmp \
|
||||
-Wl,--export=strcspn \
|
||||
-Wl,--export=strlen \
|
||||
-Wl,--export=strncmp \
|
||||
-Wl,--export=strchrnul
|
||||
-Wl,--export=strspn
|
||||
|
||||
"$BINARYEN/wasm-ctor-eval" -g -c _initialize libc.wasm -o libc.tmp
|
||||
"$BINARYEN/wasm-opt" -g --strip --strip-producers -c -O3 \
|
||||
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -1,3 +1,4 @@
|
||||
#include "strings.c"
|
||||
// Amalgamation
|
||||
#include "sqlite3.c"
|
||||
// Extensions
|
||||
@@ -10,12 +11,11 @@
|
||||
#include "ext/spellfix.c"
|
||||
#include "ext/uint.c"
|
||||
// Bindings
|
||||
#include "bind.c"
|
||||
#include "column.c"
|
||||
#include "func.c"
|
||||
#include "hooks.c"
|
||||
#include "pointer.c"
|
||||
#include "result.c"
|
||||
#include "stmt.c"
|
||||
#include "text.c"
|
||||
#include "time.c"
|
||||
#include "vfs.c"
|
||||
#include "vtab.c"
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "sqlite3.h"
|
||||
|
||||
void sqlite3_result_text_go(sqlite3_context *ctx, const char *zData,
|
||||
sqlite3_uint64 nData) {
|
||||
sqlite3_result_text64(ctx, zData, nData, &sqlite3_free, SQLITE_UTF8);
|
||||
}
|
||||
|
||||
void sqlite3_result_blob_go(sqlite3_context *ctx, const void *zData,
|
||||
sqlite3_uint64 nData) {
|
||||
sqlite3_result_blob64(ctx, zData, nData, &sqlite3_free);
|
||||
}
|
||||
@@ -16,14 +16,12 @@
|
||||
// #define SQLITE_OMIT_DECLTYPE
|
||||
// #define SQLITE_OMIT_PROGRESS_CALLBACK
|
||||
|
||||
// TODO add this:
|
||||
// #define SQLITE_ENABLE_API_ARMOR
|
||||
|
||||
// Other Options
|
||||
|
||||
#define SQLITE_ALLOW_URI_AUTHORITY
|
||||
#define SQLITE_TRUSTED_SCHEMA 0
|
||||
#define SQLITE_DEFAULT_FOREIGN_KEYS 1
|
||||
#define SQLITE_ENABLE_API_ARMOR
|
||||
#define SQLITE_ENABLE_ATOMIC_WRITE
|
||||
#define SQLITE_ENABLE_BATCH_ATOMIC_WRITE
|
||||
#define SQLITE_ENABLE_COLUMN_METADATA
|
||||
|
||||
@@ -2,6 +2,11 @@
|
||||
|
||||
#include "sqlite3.h"
|
||||
|
||||
int sqlite3_exec_go(sqlite3_stmt *stmt) {
|
||||
while (sqlite3_step(stmt) == SQLITE_ROW);
|
||||
return sqlite3_reset(stmt);
|
||||
}
|
||||
|
||||
union sqlite3_data {
|
||||
sqlite3_int64 i;
|
||||
double d;
|
||||
@@ -16,7 +21,7 @@ int sqlite3_columns_go(sqlite3_stmt *stmt, int nCol, char *aType,
|
||||
if (nCol != sqlite3_column_count(stmt)) {
|
||||
return SQLITE_MISUSE;
|
||||
}
|
||||
int rc = SQLITE_OK;
|
||||
bool check = false;
|
||||
for (int i = 0; i < nCol; ++i) {
|
||||
const void *ptr = NULL;
|
||||
switch (aType[i] = sqlite3_column_type(stmt, i)) {
|
||||
@@ -36,16 +41,14 @@ int sqlite3_columns_go(sqlite3_stmt *stmt, int nCol, char *aType,
|
||||
ptr = sqlite3_column_blob(stmt, i);
|
||||
break;
|
||||
}
|
||||
if (ptr == NULL && rc == SQLITE_OK) {
|
||||
rc = sqlite3_errcode(sqlite3_db_handle(stmt));
|
||||
if (rc == SQLITE_ROW || rc == SQLITE_DONE) {
|
||||
rc = SQLITE_OK;
|
||||
}
|
||||
}
|
||||
aData[i].ptr = ptr;
|
||||
aData[i].len = sqlite3_column_bytes(stmt, i);
|
||||
if (ptr == NULL) check = true;
|
||||
}
|
||||
return rc;
|
||||
if (check && SQLITE_NOMEM == sqlite3_errcode(sqlite3_db_handle(stmt))) {
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
static_assert(offsetof(union sqlite3_data, i) == 0, "Unexpected offset");
|
||||
@@ -1,5 +1,3 @@
|
||||
#include <__macro_PAGESIZE.h>
|
||||
#include <limits.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <wasm_simd128.h>
|
||||
@@ -27,7 +25,7 @@ int memcmp(const void *v1, const void *v2, size_t n) {
|
||||
const v128_t *w2 = v2;
|
||||
for (; n >= sizeof(v128_t); n -= sizeof(v128_t)) {
|
||||
if (wasm_v128_any_true(wasm_v128_load(w1) ^ wasm_v128_load(w2))) {
|
||||
break; // *w1 != *w2
|
||||
break;
|
||||
}
|
||||
w1++;
|
||||
w2++;
|
||||
@@ -50,7 +48,7 @@ void *memchr(const void *v, int c, size_t n) {
|
||||
const v128_t *w = (void *)v;
|
||||
for (; n >= sizeof(v128_t); n -= sizeof(v128_t)) {
|
||||
if (wasm_v128_any_true(wasm_i8x16_eq(wasm_v128_load(w), wc))) {
|
||||
break; // *w has a c
|
||||
break;
|
||||
}
|
||||
w++;
|
||||
}
|
||||
@@ -64,51 +62,41 @@ void *memchr(const void *v, int c, size_t n) {
|
||||
}
|
||||
|
||||
size_t strlen(const char *s) {
|
||||
const v128_t *const limit =
|
||||
(v128_t *)(__builtin_wasm_memory_size(0) * PAGESIZE) - 1;
|
||||
uintptr_t align = (uintptr_t)s % sizeof(v128_t);
|
||||
const v128_t *w = (void *)(s - align);
|
||||
|
||||
const v128_t *w = (void *)s;
|
||||
while (w <= limit) {
|
||||
if (!wasm_i8x16_all_true(wasm_v128_load(w))) {
|
||||
break; // *w has a NUL
|
||||
while (true) {
|
||||
int mask =
|
||||
wasm_i8x16_bitmask(wasm_i8x16_eq(*w, (v128_t){})) >> align << align;
|
||||
if (mask) {
|
||||
return (char *)w - s + __builtin_ctz(mask);
|
||||
}
|
||||
align = 0;
|
||||
w++;
|
||||
}
|
||||
|
||||
const char *ss = (void *)w;
|
||||
while (true) {
|
||||
if (*ss == 0) break;
|
||||
ss++;
|
||||
}
|
||||
return ss - s;
|
||||
}
|
||||
|
||||
int strcmp(const char *s1, const char *s2) {
|
||||
const v128_t *const limit =
|
||||
(v128_t *)(__builtin_wasm_memory_size(0) * PAGESIZE) - 1;
|
||||
|
||||
const v128_t *w1 = (void *)s1;
|
||||
const v128_t *w2 = (void *)s2;
|
||||
while (w1 <= limit && w2 <= limit) {
|
||||
if (wasm_v128_any_true(wasm_v128_load(w1) ^ wasm_v128_load(w2))) {
|
||||
break; // *w1 != *w2
|
||||
if (((uintptr_t)s1 | (uintptr_t)s2) % sizeof(v128_t) == 0) {
|
||||
while (!wasm_v128_any_true(*w1 ^ *w2)) {
|
||||
if (!wasm_i8x16_all_true(*w1)) {
|
||||
return 0;
|
||||
}
|
||||
w1++;
|
||||
w2++;
|
||||
}
|
||||
if (!wasm_i8x16_all_true(wasm_v128_load(w1))) {
|
||||
return 0; // *w1 == *w2 and have a NUL
|
||||
}
|
||||
w1++;
|
||||
w2++;
|
||||
}
|
||||
|
||||
const uint8_t *u1 = (void *)w1;
|
||||
const uint8_t *u2 = (void *)w2;
|
||||
while (true) {
|
||||
if (*u1 != *u2) return *u1 - *u2;
|
||||
if (*u1 == 0) break;
|
||||
if (*u1 == 0) return 0;
|
||||
u1++;
|
||||
u2++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int strncmp(const char *s1, const char *s2, size_t n) {
|
||||
@@ -116,10 +104,10 @@ int strncmp(const char *s1, const char *s2, size_t n) {
|
||||
const v128_t *w2 = (void *)s2;
|
||||
for (; n >= sizeof(v128_t); n -= sizeof(v128_t)) {
|
||||
if (wasm_v128_any_true(wasm_v128_load(w1) ^ wasm_v128_load(w2))) {
|
||||
break; // *w1 != *w2
|
||||
break;
|
||||
}
|
||||
if (!wasm_i8x16_all_true(wasm_v128_load(w1))) {
|
||||
return 0; // *w1 == *w2 and have a NUL
|
||||
return 0;
|
||||
}
|
||||
w1++;
|
||||
w2++;
|
||||
@@ -139,27 +127,24 @@ int strncmp(const char *s1, const char *s2, size_t n) {
|
||||
char *strchrnul(const char *s, int c) {
|
||||
c = (char)c;
|
||||
|
||||
const v128_t *const limit =
|
||||
(v128_t *)(__builtin_wasm_memory_size(0) * PAGESIZE) - 1;
|
||||
if (__builtin_constant_p(c) && c == 0) {
|
||||
return (char *)s + strlen(s);
|
||||
}
|
||||
|
||||
uintptr_t align = (uintptr_t)s % sizeof(v128_t);
|
||||
const v128_t *w = (void *)(s - align);
|
||||
const v128_t wc = wasm_i8x16_splat(c);
|
||||
const v128_t *w = (void *)s;
|
||||
while (w <= limit) {
|
||||
if (!wasm_i8x16_all_true(wasm_v128_load(w))) {
|
||||
break; // *w has a NUL
|
||||
}
|
||||
if (wasm_v128_any_true(wasm_i8x16_eq(wasm_v128_load(w), wc))) {
|
||||
break; // *w has a c
|
||||
|
||||
while (true) {
|
||||
int mask = wasm_i8x16_bitmask(wasm_i8x16_eq(*w, (v128_t){}) |
|
||||
wasm_i8x16_eq(*w, wc)) >>
|
||||
align << align;
|
||||
if (mask) {
|
||||
return (char *)w + __builtin_ctz(mask);
|
||||
}
|
||||
align = 0;
|
||||
w++;
|
||||
}
|
||||
|
||||
s = (void *)w;
|
||||
while (true) {
|
||||
if (*s == 0 || *s == c) break;
|
||||
s++;
|
||||
}
|
||||
return (void *)s;
|
||||
}
|
||||
|
||||
char *strchr(const char *s, int c) {
|
||||
@@ -168,3 +153,29 @@ char *strchr(const char *s, int c) {
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#define BITOP(a, b, op) \
|
||||
((a)[(b) / (8 * sizeof(size_t))] op((size_t)1) \
|
||||
<< ((b) % (8 * sizeof(size_t))))
|
||||
|
||||
size_t strspn(const char *s, const char *c) {
|
||||
const char *const a = s;
|
||||
size_t byteset[32 / sizeof(size_t)] = {0};
|
||||
|
||||
for (; *c && BITOP(byteset, *(uint8_t *)c, |=); c++);
|
||||
for (; *s && BITOP(byteset, *(uint8_t *)s, &); s++);
|
||||
return s - a;
|
||||
}
|
||||
|
||||
size_t strcspn(const char *s, const char *c) {
|
||||
if (!c[0] || !c[1]) return strchrnul(s, *c) - s;
|
||||
|
||||
const char *const a = s;
|
||||
size_t byteset[32 / sizeof(size_t)] = {0};
|
||||
|
||||
for (; *c && BITOP(byteset, *(uint8_t *)c, |=); c++);
|
||||
for (; *s && !BITOP(byteset, *(uint8_t *)s, &); s++);
|
||||
return s - a;
|
||||
}
|
||||
|
||||
#undef BITOP
|
||||
|
||||
@@ -10,4 +10,14 @@ int sqlite3_bind_text_go(sqlite3_stmt *stmt, int i, const char *zData,
|
||||
int sqlite3_bind_blob_go(sqlite3_stmt *stmt, int i, const char *zData,
|
||||
sqlite3_uint64 nData) {
|
||||
return sqlite3_bind_blob64(stmt, i, zData, nData, &sqlite3_free);
|
||||
}
|
||||
|
||||
void sqlite3_result_text_go(sqlite3_context *ctx, const char *zData,
|
||||
sqlite3_uint64 nData) {
|
||||
sqlite3_result_text64(ctx, zData, nData, &sqlite3_free, SQLITE_UTF8);
|
||||
}
|
||||
|
||||
void sqlite3_result_blob_go(sqlite3_context *ctx, const void *zData,
|
||||
sqlite3_uint64 nData) {
|
||||
sqlite3_result_blob64(ctx, zData, nData, &sqlite3_free);
|
||||
}
|
||||
Reference in New Issue
Block a user