This commit is contained in:
2025-12-29 17:53:21 -06:00
parent d0674e7921
commit a0038a7ab2
3 changed files with 86 additions and 56 deletions

View File

@@ -73,7 +73,8 @@ Build.detect_host_target = function() {
// ============================================================================
function content_hash(str) {
return text(crypto.blake2(new blob(str)), 'h')
var bb = stone(new blob(str))
return text(crypto.blake2(bb, 32), 'h')
}
function get_build_dir() {
@@ -379,7 +380,7 @@ Build.build_all_dynamic = function(target, buildtype = 'release') {
var lib = Build.build_dynamic('core', target, buildtype)
results.push({ package: 'core', library: lib })
} catch (e) {
log.error('Failed to build core: ' + e)
log.error('Failed to build core: ' + text(e))
results.push({ package: 'core', error: e })
}
}

View File

@@ -138,72 +138,81 @@ void bitcpy(unsigned char *dst, size_t dst_bit_offset,
}
}
// Fast bit-copy for arbitrary bit ranges (inclusive) from src → dest
void copy_bits_fast(const void *src, void *dest,
size_t n, /* start bit in src (inclusive) */
size_t m, /* end bit in src (inclusive) */
size_t x) /* start bit in dest */
static inline uint16_t load16_window(const uint8_t *s, size_t i, size_t last_byte)
{
const uint8_t *s = (const uint8_t*)src;
uint8_t *d = (uint8_t*)dest;
uint16_t lo = s[i];
uint16_t hi = 0;
if (i + 1 <= last_byte) hi = (uint16_t)s[i + 1] << 8;
return lo | hi;
}
size_t total_bits = m - n + 1;
void copy_bits_fast(const void *src, void *dest, size_t n, size_t m, size_t x)
{
if (m < n) return;
size_t src_bit = n;
size_t dst_bit = x;
const uint8_t *s = (const uint8_t *)src;
uint8_t *d = (uint8_t *)dest;
size_t total_bits = m - n + 1;
size_t src_bit = n;
size_t dst_bit = x;
size_t src_byte = src_bit >> 3;
size_t dst_byte = dst_bit >> 3;
int src_off = src_bit & 7;
int dst_off = dst_bit & 7;
int src_off = src_bit & 7;
int dst_off = dst_bit & 7;
// 1) Leading partial byte to align dest
size_t last_src_byte = m >> 3;
/* Fast path: whole bytes, aligned */
if (src_off == 0 && dst_off == 0 && (total_bits & 7) == 0) {
memcpy(d + dst_byte, s + src_byte, total_bits >> 3);
return;
}
/* 1) Leading partial byte to align dest */
if (dst_off != 0) {
size_t chunk = 8 - dst_off;
if (chunk > total_bits) chunk = total_bits;
uint8_t dst_mask = (((1u << chunk) - 1u) << dst_off);
uint16_t wb = (uint16_t)s[src_byte] | ((uint16_t)s[src_byte + 1] << 8);
uint8_t dst_mask = (uint8_t)(((1u << chunk) - 1u) << dst_off);
uint16_t wb = load16_window(s, src_byte, last_src_byte);
uint8_t bits = (uint8_t)((wb >> src_off) & ((1u << chunk) - 1u));
bits <<= dst_off;
d[dst_byte] = (d[dst_byte] & ~dst_mask) | (bits & dst_mask);
d[dst_byte] = (d[dst_byte] & (uint8_t)~dst_mask) | (bits & dst_mask);
total_bits -= chunk;
src_bit += chunk;
dst_bit += chunk;
src_byte = src_bit >> 3;
dst_byte = dst_bit >> 3;
src_off = src_bit & 7;
dst_off = dst_bit & 7; // now zero
src_bit += chunk;
dst_bit += chunk;
src_byte = src_bit >> 3;
dst_byte = dst_bit >> 3;
src_off = src_bit & 7;
dst_off = dst_bit & 7;
}
// 2) Copy full bytes
/* 2) Copy full bytes */
if (total_bits >= 8) {
size_t num_bytes = total_bits >> 3;
if (src_off == 0) {
size_t num_bytes = total_bits >> 3;
memcpy(&d[dst_byte], &s[src_byte], num_bytes);
total_bits -= num_bytes << 3;
src_byte += num_bytes;
dst_byte += num_bytes;
memcpy(d + dst_byte, s + src_byte, num_bytes);
} else {
size_t num_bytes = total_bits >> 3;
for (size_t i = 0; i < num_bytes; i++) {
uint16_t wb = (uint16_t)s[src_byte + i] |
((uint16_t)s[src_byte + i + 1] << 8);
uint16_t wb = load16_window(s, src_byte + i, last_src_byte);
d[dst_byte + i] = (uint8_t)((wb >> src_off) & 0xFFu);
}
total_bits -= num_bytes << 3;
src_byte += num_bytes;
dst_byte += num_bytes;
}
total_bits -= num_bytes << 3;
src_byte += num_bytes;
dst_byte += num_bytes;
}
// 3) Trailing bits (< 8)
/* 3) Trailing bits (< 8), dest is byte-aligned here */
if (total_bits > 0) {
uint8_t dst_mask = (1u << total_bits) - 1u;
uint16_t wb = (uint16_t)s[src_byte] | ((uint16_t)s[src_byte + 1] << 8);
uint8_t dst_mask = (uint8_t)((1u << total_bits) - 1u);
uint16_t wb = load16_window(s, src_byte, last_src_byte);
uint8_t bits = (uint8_t)((wb >> src_off) & dst_mask);
d[dst_byte] = (d[dst_byte] & ~dst_mask) | (bits & dst_mask);
d[dst_byte] = (d[dst_byte] & (uint8_t)~dst_mask) | (bits & dst_mask);
}
}
@@ -378,16 +387,30 @@ int blob_write_text(blob *b, const char *text) {
return 0;
}
int blob_write_bytes(blob *b, const void *data, size_t len_bytes) {
int blob_write_bytes(blob *b, const void *data, size_t len_bytes)
{
if (!b || b->is_stone) return -1;
if (len_bytes == 0) return 0;
size_t bits = len_bytes * 8;
if (blob_ensure_capacity(b, bits) < 0) return -1;
copy_bits_fast(data, b->data, 0, bits - 1, b->length);
b->length += bits;
if (!len_bytes) return 0;
size_t bit_len = len_bytes << 3;
size_t bit_off = b->length;
size_t new_len = bit_off + bit_len;
if (new_len < bit_off) return -1;
if (blob_ensure_capacity(b, new_len) < 0) return -1;
if ((bit_off & 7) == 0) {
uint8_t *dst = (uint8_t *)b->data + (bit_off >> 3);
memcpy(dst, data, len_bytes);
} else {
copy_bits_fast(data, b->data, 0, bit_len - 1, bit_off);
}
b->length = new_len;
return 0;
}
int blob_read_bit(const blob *b, size_t pos, int *out_bit) {
if (!b || !b->is_stone || !out_bit) return -1;
if (pos >= b->length) return -1;

View File

@@ -39674,26 +39674,32 @@ static JSValue js_blob_w16(JSContext *ctx, JSValueConst this_val,
}
/* blob.wf(value) - write float */
static JSValue js_blob_wf(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv)
static JSValue js_blob_wf(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
{
if (argc < 1)
return JS_ThrowTypeError(ctx, "wf(value) requires 1 argument");
if (argc < 1) return JS_ThrowTypeError(ctx, "wf(value) requires 1 argument");
blob *bd = js_get_blob(ctx, this_val);
if (!bd)
return JS_ThrowTypeError(ctx, "wf: not called on a blob");
if (!bd) return JS_ThrowTypeError(ctx, "wf: not called on a blob");
double d;
if (JS_ToFloat64(ctx, &d, argv[0]) < 0) return JS_EXCEPTION;
float f;
int tag = JS_VALUE_GET_TAG(argv[0]);
if (tag == JS_TAG_INT) {
f = (float)JS_VALUE_GET_INT(argv[0]);
} else if (tag == JS_TAG_FLOAT64) {
f = (float)JS_VALUE_GET_FLOAT64(argv[0]);
} else {
double d;
if (JS_ToFloat64(ctx, &d, argv[0]) < 0) return JS_EXCEPTION;
f = (float)d;
}
float f = (float)d;
if (blob_write_bytes(bd, &f, sizeof(float)) < 0)
if (blob_write_bytes(bd, &f, sizeof(f)) < 0)
return JS_ThrowTypeError(ctx, "wf: cannot write");
return JS_NULL;
}
/* blob.read_logical(from) */
static JSValue js_blob_read_logical(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv)