Merge branch 'fix_compile_warnings'

This commit is contained in:
2026-02-20 14:21:10 -06:00
11 changed files with 160 additions and 153 deletions

View File

@@ -113,31 +113,34 @@ static JSValue js_miniz_compress(JSContext *js, JSValue this_val,
return JS_EXCEPTION;
}
/* ─── 2. Allocate an output buffer big enough ────────────── */
/* ─── 2. Allocate output blob (before getting blob input ptr) ── */
mz_ulong out_len_est = mz_compressBound(in_len);
void *out_buf = js_malloc_rt(out_len_est);
if (!out_buf) {
void *out_ptr;
JSValue abuf = js_new_blob_alloc(js, (size_t)out_len_est, &out_ptr);
if (JS_IsException(abuf)) {
if (cstring) JS_FreeCString(js, cstring);
return JS_EXCEPTION;
return abuf;
}
/* Re-derive blob input pointer after alloc (GC may have moved it) */
if (!cstring) {
in_ptr = js_get_blob_data(js, &in_len, argv[0]);
}
/* ─── 3. Do the compression (MZ_DEFAULT_COMPRESSION = level 6) */
mz_ulong out_len = out_len_est;
int st = mz_compress2(out_buf, &out_len,
int st = mz_compress2(out_ptr, &out_len,
in_ptr, in_len, MZ_DEFAULT_COMPRESSION);
/* clean-up for string input */
if (cstring) JS_FreeCString(js, cstring);
if (st != MZ_OK) {
js_free_rt(out_buf);
if (st != MZ_OK)
return JS_RaiseDisrupt(js,
"miniz: compression failed (%d)", st);
}
/* ─── 4. Hand JavaScript a copy of the compressed data ────── */
JSValue abuf = js_new_blob_stoned_copy(js, out_buf, out_len);
js_free_rt(out_buf);
/* ─── 4. Stone with actual compressed size ────────────────── */
js_blob_stone(abuf, (size_t)out_len);
return abuf;
}

View File

@@ -98,19 +98,17 @@ JSC_CCALL(fd_read,
if (argc > 1)
size = js2number(js, argv[1]);
void *buf = malloc(size);
if (!buf)
return JS_RaiseDisrupt(js, "malloc failed");
int bytes_read = pd_file->read(fd, buf, (unsigned int)size);
void *out;
ret = js_new_blob_alloc(js, size, &out);
if (JS_IsException(ret)) return ret;
int bytes_read = pd_file->read(fd, out, (unsigned int)size);
if (bytes_read < 0) {
free(buf);
const char* err = pd_file->geterr();
return JS_RaiseDisrupt(js, "read failed: %s", err ? err : "unknown error");
}
ret = js_new_blob_stoned_copy(js, buf, bytes_read);
free(buf);
js_blob_stone(ret, bytes_read);
return ret;
)
@@ -134,22 +132,17 @@ JSC_SCALL(fd_slurp,
return JS_RaiseDisrupt(js, "open failed: %s", err ? err : "unknown error");
}
void *data = malloc(size);
if (!data) {
pd_file->close(fd);
return JS_RaiseDisrupt(js, "malloc failed");
}
void *out;
ret = js_new_blob_alloc(js, size, &out);
if (JS_IsException(ret)) { pd_file->close(fd); return ret; }
int bytes_read = pd_file->read(fd, data, (unsigned int)size);
int bytes_read = pd_file->read(fd, out, (unsigned int)size);
pd_file->close(fd);
if (bytes_read < 0) {
free(data);
if (bytes_read < 0)
return JS_RaiseDisrupt(js, "read failed");
}
ret = js_new_blob_stoned_copy(js, data, bytes_read);
free(data);
js_blob_stone(ret, bytes_read);
)
JSC_CCALL(fd_lseek,

View File

@@ -102,18 +102,15 @@ JSC_CCALL(fd_read,
if (argc > 1)
size = js2number(js, argv[1]);
void *buf = malloc(size);
if (!buf)
return JS_RaiseDisrupt(js, "malloc failed");
ssize_t bytes_read = read(fd, buf, size);
if (bytes_read < 0) {
free(buf);
void *out;
ret = js_new_blob_alloc(js, size, &out);
if (JS_IsException(ret)) return ret;
ssize_t bytes_read = read(fd, out, size);
if (bytes_read < 0)
return JS_RaiseDisrupt(js, "read failed: %s", strerror(errno));
}
ret = js_new_blob_stoned_copy(js, buf, bytes_read);
free(buf);
js_blob_stone(ret, bytes_read);
return ret;
)
@@ -128,39 +125,48 @@ JSC_SCALL(fd_slurp,
size_t size = st.st_size;
if (size == 0)
return js_new_blob_stoned_copy(js, NULL, 0);
#ifndef _WIN32
int fd = open(str, O_RDONLY);
if (fd < 0)
return JS_RaiseDisrupt(js, "open failed: %s", strerror(errno));
void *data = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
if (data == MAP_FAILED) {
close(fd);
return JS_RaiseDisrupt(js, "mmap failed: %s", strerror(errno));
void *out;
ret = js_new_blob_alloc(js, size, &out);
if (JS_IsException(ret)) { close(fd); return ret; }
size_t total = 0;
while (total < size) {
ssize_t n = read(fd, (uint8_t *)out + total, size - total);
if (n < 0) {
if (errno == EINTR) continue;
close(fd);
return JS_RaiseDisrupt(js, "read failed: %s", strerror(errno));
}
if (n == 0) break;
total += n;
}
ret = js_new_blob_stoned_copy(js, data, size);
munmap(data, size);
close(fd);
js_blob_stone(ret, total);
#else
// Windows: use memory mapping for optimal performance
HANDLE hFile = CreateFileA(str, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
return JS_RaiseDisrupt(js, "CreateFile failed: %lu", GetLastError());
HANDLE hMapping = CreateFileMappingA(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
if (hMapping == NULL) {
CloseHandle(hFile);
return JS_RaiseDisrupt(js, "CreateFileMapping failed: %lu", GetLastError());
}
void *data = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);
if (data == NULL) {
CloseHandle(hMapping);
CloseHandle(hFile);
return JS_RaiseDisrupt(js, "MapViewOfFile failed: %lu", GetLastError());
}
ret = js_new_blob_stoned_copy(js, data, size);
UnmapViewOfFile(data);
CloseHandle(hMapping);

View File

@@ -8,26 +8,25 @@
JSC_CCALL(kim_encode,
const char *utf8_str = JS_ToCString(js, argv[0]);
if (!utf8_str) return JS_EXCEPTION;
// Count runes to estimate kim buffer size
int rune_count = utf8_count(utf8_str);
// Allocate kim buffer (worst case: 5 bytes per rune)
// Allocate blob (worst case: 5 bytes per rune)
size_t kim_size = rune_count * 5;
char *kim_buffer = malloc(kim_size);
char *kim_ptr = kim_buffer;
// Encode utf8 to kim
void *out;
ret = js_new_blob_alloc(js, kim_size, &out);
if (JS_IsException(ret)) { JS_FreeCString(js, utf8_str); return ret; }
// Encode utf8 to kim directly into blob
char *kim_ptr = (char *)out;
long long runes_encoded;
utf8_to_kim(&utf8_str, &kim_ptr, &runes_encoded);
// Calculate actual size used
size_t actual_size = kim_ptr - kim_buffer;
// Create blob with the encoded data
ret = js_new_blob_stoned_copy(js, kim_buffer, actual_size);
free(kim_buffer);
// Stone with actual size used
size_t actual_size = kim_ptr - (char *)out;
js_blob_stone(ret, actual_size);
JS_FreeCString(js, utf8_str);
)

View File

@@ -333,19 +333,15 @@ JSC_CCALL(socket_recv,
flags = js2number(js, argv[2]);
}
void *buf = malloc(len);
if (!buf) {
return JS_RaiseDisrupt(js, "malloc failed");
}
ssize_t received = recv(sockfd, buf, len, flags);
if (received < 0) {
free(buf);
void *out;
ret = js_new_blob_alloc(js, len, &out);
if (JS_IsException(ret)) return ret;
ssize_t received = recv(sockfd, out, len, flags);
if (received < 0)
return JS_RaiseDisrupt(js, "recv failed: %s", strerror(errno));
}
ret = js_new_blob_stoned_copy(js, buf, received);
free(buf);
js_blob_stone(ret, received);
return ret;
)
@@ -421,25 +417,20 @@ JSC_CCALL(socket_recvfrom,
flags = js2number(js, argv[2]);
}
void *buf = malloc(len);
if (!buf) {
return JS_RaiseDisrupt(js, "malloc failed");
}
void *out;
JSValue blob = js_new_blob_alloc(js, len, &out);
if (JS_IsException(blob)) return blob;
struct sockaddr_storage from_addr;
socklen_t from_len = sizeof from_addr;
ssize_t received = recvfrom(sockfd, buf, len, flags,
ssize_t received = recvfrom(sockfd, out, len, flags,
(struct sockaddr *)&from_addr, &from_len);
if (received < 0) {
free(buf);
if (received < 0)
return JS_RaiseDisrupt(js, "recvfrom failed: %s", strerror(errno));
}
ret = JS_NewObject(js);
JS_SetPropertyStr(js, ret, "data", js_new_blob_stoned_copy(js, buf, received));
free(buf);
js_blob_stone(blob, received);
// Get source address info
char ipstr[INET6_ADDRSTRLEN];
int port;
@@ -452,11 +443,15 @@ JSC_CCALL(socket_recvfrom,
inet_ntop(AF_INET6, &s->sin6_addr, ipstr, sizeof ipstr);
port = ntohs(s->sin6_port);
}
JSValue addr_info = JS_NewObject(js);
JS_SetPropertyStr(js, addr_info, "address", JS_NewString(js, ipstr));
JS_SetPropertyStr(js, addr_info, "port", JS_NewInt32(js, port));
JS_SetPropertyStr(js, ret, "address", addr_info);
JS_FRAME(js);
JS_ROOT(ret_r, JS_NewObject(js));
JS_SetPropertyStr(js, ret_r.val, "data", blob);
JS_ROOT(addr_info, JS_NewObject(js));
JS_SetPropertyStr(js, addr_info.val, "address", JS_NewString(js, ipstr));
JS_SetPropertyStr(js, addr_info.val, "port", JS_NewInt32(js, port));
JS_SetPropertyStr(js, ret_r.val, "address", addr_info.val);
JS_RETURN(ret_r.val);
)
JSC_CCALL(socket_shutdown,

View File

@@ -78,15 +78,13 @@ JSC_CCALL(file_read,
if (!pd_file) return JS_RaiseDisrupt(js, "file not initialized");
SDFile *f = js2sdfile(js, argv[0]);
unsigned int len = (unsigned int)js2number(js, argv[1]);
void *buf = malloc(len);
if (!buf) return JS_RaiseDisrupt(js, "malloc failed");
int read = pd_file->read(f, buf, len);
if (read < 0) {
free(buf);
void *out;
JSValue blob = js_new_blob_alloc(js, len, &out);
if (JS_IsException(blob)) return blob;
int bytes_read = pd_file->read(f, out, len);
if (bytes_read < 0)
return JS_NULL;
}
JSValue blob = js_new_blob_stoned_copy(js, buf, read);
free(buf);
js_blob_stone(blob, bytes_read);
return blob;
)

View File

@@ -139,15 +139,13 @@ JSC_CCALL(http_read,
if (!pd_network || !pd_network->http) return JS_RaiseDisrupt(js, "network not initialized");
HTTPConnection *conn = js2http(js, argv[0]);
unsigned int buflen = (unsigned int)js2number(js, argv[1]);
void *buf = malloc(buflen);
if (!buf) return JS_RaiseDisrupt(js, "malloc failed");
int read = pd_network->http->read(conn, buf, buflen);
if (read < 0) {
free(buf);
void *out;
JSValue blob = js_new_blob_alloc(js, buflen, &out);
if (JS_IsException(blob)) return blob;
int bytes_read = pd_network->http->read(conn, out, buflen);
if (bytes_read < 0)
return JS_NULL;
}
JSValue blob = js_new_blob_stoned_copy(js, buf, read);
free(buf);
js_blob_stone(blob, bytes_read);
return blob;
)
@@ -218,15 +216,13 @@ JSC_CCALL(tcp_read,
if (!pd_network || !pd_network->tcp) return JS_RaiseDisrupt(js, "network not initialized");
TCPConnection *conn = js2tcp(js, argv[0]);
size_t len = (size_t)js2number(js, argv[1]);
void *buf = malloc(len);
if (!buf) return JS_RaiseDisrupt(js, "malloc failed");
int read = pd_network->tcp->read(conn, buf, len);
if (read < 0) {
free(buf);
return JS_NewInt32(js, read); // Return error code
}
JSValue blob = js_new_blob_stoned_copy(js, buf, read);
free(buf);
void *out;
JSValue blob = js_new_blob_alloc(js, len, &out);
if (JS_IsException(blob)) return blob;
int bytes_read = pd_network->tcp->read(conn, out, len);
if (bytes_read < 0)
return JS_NewInt32(js, bytes_read); // Return error code
js_blob_stone(blob, bytes_read);
return blob;
)

30
qop.c
View File

@@ -183,18 +183,15 @@ static JSValue js_qop_read(JSContext *js, JSValue self, int argc, JSValue *argv)
return JS_NULL;
}
unsigned char *dest = js_malloc_rt(file->size);
if (!dest)
return JS_RaiseOOM(js);
void *out;
JSValue blob = js_new_blob_alloc(js, file->size, &out);
if (JS_IsException(blob)) return blob;
int bytes = qop_read(qop, file, dest);
if (bytes == 0) {
js_free_rt(dest);
int bytes = qop_read(qop, file, out);
if (bytes == 0)
return JS_RaiseDisrupt(js, "Failed to read file");
}
JSValue blob = js_new_blob_stoned_copy(js, dest, bytes);
js_free_rt(dest);
js_blob_stone(blob, bytes);
return blob;
}
@@ -223,18 +220,15 @@ static JSValue js_qop_read_ex(JSContext *js, JSValue self, int argc, JSValue *ar
if (JS_ToUint32(js, &start, argv[1]) < 0 || JS_ToUint32(js, &len, argv[2]) < 0)
return JS_RaiseDisrupt(js, "Invalid start or len");
unsigned char *dest = js_malloc_rt(len);
if (!dest)
return JS_RaiseOOM(js);
void *out;
JSValue blob = js_new_blob_alloc(js, len, &out);
if (JS_IsException(blob)) return blob;
int bytes = qop_read_ex(qop, file, dest, start, len);
if (bytes == 0) {
js_free_rt(dest);
int bytes = qop_read_ex(qop, file, out, start, len);
if (bytes == 0)
return JS_RaiseDisrupt(js, "Failed to read file part");
}
JSValue blob = js_new_blob_stoned_copy(js, dest, bytes);
js_free_rt(dest);
js_blob_stone(blob, bytes);
return blob;
}

View File

@@ -10,6 +10,8 @@ extern "C" {
// blob fns
JSValue js_core_blob_use(JSContext *js);
JSValue js_new_blob_alloc(JSContext *js, size_t bytes, void **out);
void js_blob_stone(JSValue blob, size_t actual_bytes);
JSValue js_new_blob_stoned_copy(JSContext *js, void *data, size_t bytes);
void *js_get_blob_data(JSContext *js, size_t *size, JSValue v); // bytes
void *js_get_blob_data_bits(JSContext *js, size_t *bits, JSValue v); // bits

View File

@@ -10048,16 +10048,38 @@ JSValue js_core_blob_use (JSContext *js) {
return JS_GetPropertyStr (js, js->global_obj, "blob");
}
/* Create a new blob from raw data, stone it, and return as JSValue */
JSValue js_new_blob_stoned_copy (JSContext *js, void *data, size_t bytes) {
/* Allocate a mutable blob. *out receives writable pointer to data area.
WARNING: *out is invalidated by ANY GC-triggering operation.
Caller fills data, then calls js_blob_stone(). */
JSValue js_new_blob_alloc (JSContext *js, size_t bytes, void **out) {
size_t bits = bytes * 8;
JSValue bv = js_new_heap_blob (js, bits);
if (JS_IsException (bv)) return bv;
if (JS_IsException (bv)) {
*out = NULL;
return bv;
}
JSBlob *bd = (JSBlob *)chase (bv);
if (bytes > 0)
memcpy (bd->bits, data, bytes);
bd->length = bits;
*out = bd->bits;
return bv;
}
/* Set actual length and stone the blob. actual_bytes <= allocated bytes.
Does NOT allocate — cannot trigger GC. */
void js_blob_stone (JSValue blob, size_t actual_bytes) {
JSBlob *bd = (JSBlob *)chase (blob);
bd->length = actual_bytes * 8;
bd->mist_hdr = objhdr_set_s (bd->mist_hdr, true);
}
/* Create a new blob from raw data, stone it, and return as JSValue */
JSValue js_new_blob_stoned_copy (JSContext *js, void *data, size_t bytes) {
void *out;
JSValue bv = js_new_blob_alloc (js, bytes, &out);
if (JS_IsException (bv)) return bv;
if (bytes > 0)
memcpy (out, data, bytes);
js_blob_stone (bv, bytes);
return bv;
}

View File

@@ -1,6 +1,5 @@
var fd = use("fd")
var miniz = use("miniz")
var utf8 = use("utf8")
return {
create_and_read_zip: function() {
@@ -35,7 +34,7 @@ return {
disrupt
extracted_blob = reader.slurp(ENTRY_PATH)
extracted_text = utf8.decode(extracted_blob)
extracted_text = text(extracted_blob)
if (extracted_text != PAYLOAD)
disrupt
@@ -59,8 +58,8 @@ return {
var _run = function() {
writer = miniz.write(ZIP_PATH)
writer.add_file(ENTRY1, utf8.encode("content1"))
writer.add_file(ENTRY2, utf8.encode("content2"))
writer.add_file(ENTRY1, blob("content1"))
writer.add_file(ENTRY2, blob("content2"))
writer = null
zip_blob = fd.slurp(ZIP_PATH)
@@ -87,7 +86,7 @@ return {
var _run = function() {
writer = miniz.write(ZIP_PATH)
writer.add_file(ENTRY_PATH, utf8.encode("data"))
writer.add_file(ENTRY_PATH, blob("data"))
writer = null
zip_blob = fd.slurp(ZIP_PATH)