Merge branch 'simplify_disruption'
This commit is contained in:
@@ -47,14 +47,14 @@ static JSValue js_miniz_read(JSContext *js, JSValue self, int argc, JSValue *arg
|
||||
|
||||
mz_zip_archive *zip = calloc(sizeof(*zip), 1);
|
||||
if (!zip)
|
||||
return JS_ThrowOutOfMemory(js);
|
||||
return JS_RaiseOOM(js);
|
||||
|
||||
mz_bool success = mz_zip_reader_init_mem(zip, data, len, 0);
|
||||
|
||||
if (!success) {
|
||||
int err = mz_zip_get_last_error(zip);
|
||||
free(zip);
|
||||
return JS_ThrowInternalError(js, "Failed to initialize zip reader: %s", mz_zip_get_error_string(err));
|
||||
return JS_RaiseDisrupt(js, "Failed to initialize zip reader: %s", mz_zip_get_error_string(err));
|
||||
}
|
||||
|
||||
JSValue jszip = JS_NewObjectClass(js, js_reader_class_id);
|
||||
@@ -71,7 +71,7 @@ static JSValue js_miniz_write(JSContext *js, JSValue self, int argc, JSValue *ar
|
||||
mz_zip_archive *zip = calloc(sizeof(*zip), 1);
|
||||
if (!zip) {
|
||||
JS_FreeCString(js, file);
|
||||
return JS_ThrowOutOfMemory(js);
|
||||
return JS_RaiseOOM(js);
|
||||
}
|
||||
|
||||
mz_bool success = mz_zip_writer_init_file(zip, file, 0);
|
||||
@@ -81,7 +81,7 @@ static JSValue js_miniz_write(JSContext *js, JSValue self, int argc, JSValue *ar
|
||||
int err = mz_zip_get_last_error(zip);
|
||||
mz_zip_writer_end(zip);
|
||||
free(zip);
|
||||
return JS_ThrowInternalError(js, "Failed to initialize zip writer: %s", mz_zip_get_error_string(err));
|
||||
return JS_RaiseDisrupt(js, "Failed to initialize zip writer: %s", mz_zip_get_error_string(err));
|
||||
}
|
||||
|
||||
JSValue jszip = JS_NewObjectClass(js, js_writer_class_id);
|
||||
@@ -93,7 +93,7 @@ static JSValue js_miniz_compress(JSContext *js, JSValue this_val,
|
||||
int argc, JSValueConst *argv)
|
||||
{
|
||||
if (argc < 1)
|
||||
return JS_ThrowTypeError(js,
|
||||
return JS_RaiseDisrupt(js,
|
||||
"compress needs a string or ArrayBuffer");
|
||||
|
||||
/* ─── 1. Grab the input data ──────────────────────────────── */
|
||||
@@ -131,7 +131,7 @@ static JSValue js_miniz_compress(JSContext *js, JSValue this_val,
|
||||
|
||||
if (st != MZ_OK) {
|
||||
js_free(js, out_buf);
|
||||
return JS_ThrowInternalError(js,
|
||||
return JS_RaiseDisrupt(js,
|
||||
"miniz: compression failed (%d)", st);
|
||||
}
|
||||
|
||||
@@ -147,7 +147,7 @@ static JSValue js_miniz_decompress(JSContext *js,
|
||||
JSValueConst *argv)
|
||||
{
|
||||
if (argc < 1)
|
||||
return JS_ThrowTypeError(js,
|
||||
return JS_RaiseDisrupt(js,
|
||||
"decompress: need compressed ArrayBuffer");
|
||||
|
||||
/* grab compressed data */
|
||||
@@ -163,7 +163,7 @@ static JSValue js_miniz_decompress(JSContext *js,
|
||||
TINFL_FLAG_PARSE_ZLIB_HEADER);
|
||||
|
||||
if (!out_ptr)
|
||||
return JS_ThrowInternalError(js,
|
||||
return JS_RaiseDisrupt(js,
|
||||
"miniz: decompression failed");
|
||||
|
||||
JSValue ret;
|
||||
@@ -187,12 +187,12 @@ static const JSCFunctionListEntry js_miniz_funcs[] = {
|
||||
JSValue js_writer_add_file(JSContext *js, JSValue self, int argc, JSValue *argv)
|
||||
{
|
||||
if (argc < 2)
|
||||
return JS_ThrowTypeError(js, "add_file requires (path, arrayBuffer)");
|
||||
return JS_RaiseDisrupt(js, "add_file requires (path, arrayBuffer)");
|
||||
|
||||
mz_zip_archive *zip = js2writer(js, self);
|
||||
const char *pathInZip = JS_ToCString(js, argv[0]);
|
||||
if (!pathInZip)
|
||||
return JS_ThrowTypeError(js, "Could not parse path argument");
|
||||
return JS_RaiseDisrupt(js, "Could not parse path argument");
|
||||
|
||||
size_t dataLen;
|
||||
void *data = js_get_blob_data(js, &dataLen, argv[1]);
|
||||
@@ -205,7 +205,7 @@ JSValue js_writer_add_file(JSContext *js, JSValue self, int argc, JSValue *argv)
|
||||
JS_FreeCString(js, pathInZip);
|
||||
|
||||
if (!success)
|
||||
return JS_ThrowInternalError(js, "Failed to add memory to zip");
|
||||
return JS_RaiseDisrupt(js, "Failed to add memory to zip");
|
||||
|
||||
return JS_NULL;
|
||||
}
|
||||
@@ -225,7 +225,7 @@ JSValue js_reader_mod(JSContext *js, JSValue self, int argc, JSValue *argv)
|
||||
mz_zip_archive *zip = js2reader(js, self);
|
||||
if (!zip) {
|
||||
JS_FreeCString(js, file);
|
||||
return JS_ThrowInternalError(js, "Invalid zip reader");
|
||||
return JS_RaiseDisrupt(js, "Invalid zip reader");
|
||||
}
|
||||
|
||||
mz_zip_archive_file_stat pstat;
|
||||
@@ -233,19 +233,19 @@ JSValue js_reader_mod(JSContext *js, JSValue self, int argc, JSValue *argv)
|
||||
|
||||
if (index == (mz_uint)-1) {
|
||||
JS_FreeCString(js, file);
|
||||
return JS_ThrowReferenceError(js, "File '%s' not found in archive", file);
|
||||
return JS_RaiseDisrupt(js, "File '%s' not found in archive", file);
|
||||
}
|
||||
|
||||
JS_FreeCString(js, file);
|
||||
|
||||
if (!mz_zip_reader_file_stat(zip, index, &pstat)) {
|
||||
int err = mz_zip_get_last_error(zip);
|
||||
return JS_ThrowInternalError(js, "Failed to get file stats: %s", mz_zip_get_error_string(err));
|
||||
return JS_RaiseDisrupt(js, "Failed to get file stats: %s", mz_zip_get_error_string(err));
|
||||
}
|
||||
|
||||
return JS_NewFloat64(js, pstat.m_time);
|
||||
#else
|
||||
return JS_ThrowInternalError(js, "MINIZ_NO_TIME is defined");
|
||||
return JS_RaiseDisrupt(js, "MINIZ_NO_TIME is defined");
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -258,7 +258,7 @@ JSValue js_reader_exists(JSContext *js, JSValue self, int argc, JSValue *argv)
|
||||
mz_zip_archive *zip = js2reader(js, self);
|
||||
if (!zip) {
|
||||
JS_FreeCString(js, file);
|
||||
return JS_ThrowInternalError(js, "Invalid zip reader");
|
||||
return JS_RaiseDisrupt(js, "Invalid zip reader");
|
||||
}
|
||||
|
||||
mz_uint index = mz_zip_reader_locate_file(zip, file, NULL, 0);
|
||||
@@ -276,7 +276,7 @@ JSValue js_reader_slurp(JSContext *js, JSValue self, int argc, JSValue *argv)
|
||||
mz_zip_archive *zip = js2reader(js, self);
|
||||
if (!zip) {
|
||||
JS_FreeCString(js, file);
|
||||
return JS_ThrowInternalError(js, "Invalid zip reader");
|
||||
return JS_RaiseDisrupt(js, "Invalid zip reader");
|
||||
}
|
||||
|
||||
size_t len;
|
||||
@@ -286,7 +286,7 @@ JSValue js_reader_slurp(JSContext *js, JSValue self, int argc, JSValue *argv)
|
||||
int err = mz_zip_get_last_error(zip);
|
||||
const char *filename = file;
|
||||
JS_FreeCString(js, file);
|
||||
return JS_ThrowInternalError(js, "Failed to extract file '%s': %s", filename, mz_zip_get_error_string(err));
|
||||
return JS_RaiseDisrupt(js, "Failed to extract file '%s': %s", filename, mz_zip_get_error_string(err));
|
||||
}
|
||||
|
||||
JS_FreeCString(js, file);
|
||||
@@ -300,7 +300,7 @@ JSValue js_reader_list(JSContext *js, JSValue self, int argc, JSValue *argv)
|
||||
{
|
||||
mz_zip_archive *zip = js2reader(js, self);
|
||||
if (!zip)
|
||||
return JS_ThrowInternalError(js, "Invalid zip reader");
|
||||
return JS_RaiseDisrupt(js, "Invalid zip reader");
|
||||
|
||||
mz_uint num_files = mz_zip_reader_get_num_files(zip);
|
||||
|
||||
@@ -328,7 +328,7 @@ JSValue js_reader_list(JSContext *js, JSValue self, int argc, JSValue *argv)
|
||||
JSValue js_reader_is_directory(JSContext *js, JSValue self, int argc, JSValue *argv)
|
||||
{
|
||||
if (argc < 1)
|
||||
return JS_ThrowTypeError(js, "is_directory requires a file index");
|
||||
return JS_RaiseDisrupt(js, "is_directory requires a file index");
|
||||
|
||||
int32_t index;
|
||||
if (JS_ToInt32(js, &index, argv[0]))
|
||||
@@ -336,7 +336,7 @@ JSValue js_reader_is_directory(JSContext *js, JSValue self, int argc, JSValue *a
|
||||
|
||||
mz_zip_archive *zip = js2reader(js, self);
|
||||
if (!zip)
|
||||
return JS_ThrowInternalError(js, "Invalid zip reader");
|
||||
return JS_RaiseDisrupt(js, "Invalid zip reader");
|
||||
|
||||
return JS_NewBool(js, mz_zip_reader_is_file_a_directory(zip, index));
|
||||
}
|
||||
@@ -344,7 +344,7 @@ JSValue js_reader_is_directory(JSContext *js, JSValue self, int argc, JSValue *a
|
||||
JSValue js_reader_get_filename(JSContext *js, JSValue self, int argc, JSValue *argv)
|
||||
{
|
||||
if (argc < 1)
|
||||
return JS_ThrowTypeError(js, "get_filename requires a file index");
|
||||
return JS_RaiseDisrupt(js, "get_filename requires a file index");
|
||||
|
||||
int32_t index;
|
||||
if (JS_ToInt32(js, &index, argv[0]))
|
||||
@@ -352,11 +352,11 @@ JSValue js_reader_get_filename(JSContext *js, JSValue self, int argc, JSValue *a
|
||||
|
||||
mz_zip_archive *zip = js2reader(js, self);
|
||||
if (!zip)
|
||||
return JS_ThrowInternalError(js, "Invalid zip reader");
|
||||
return JS_RaiseDisrupt(js, "Invalid zip reader");
|
||||
|
||||
mz_zip_archive_file_stat file_stat;
|
||||
if (!mz_zip_reader_file_stat(zip, index, &file_stat))
|
||||
return JS_ThrowInternalError(js, "Failed to get file stats");
|
||||
return JS_RaiseDisrupt(js, "Failed to get file stats");
|
||||
|
||||
return JS_NewString(js, file_stat.m_filename);
|
||||
}
|
||||
@@ -365,7 +365,7 @@ JSValue js_reader_count(JSContext *js, JSValue self, int argc, JSValue *argv)
|
||||
{
|
||||
mz_zip_archive *zip = js2reader(js, self);
|
||||
if (!zip)
|
||||
return JS_ThrowInternalError(js, "Invalid zip reader");
|
||||
return JS_RaiseDisrupt(js, "Invalid zip reader");
|
||||
return JS_NewUint32(js, mz_zip_reader_get_num_files(zip));
|
||||
}
|
||||
|
||||
|
||||
22
crypto.c
22
crypto.c
@@ -61,7 +61,7 @@ static void *get_blob_check_bits(JSContext *js, JSValue val, size_t expected_bit
|
||||
}
|
||||
|
||||
if (bits != expected_bits) {
|
||||
JS_ThrowTypeError(js, "%s: expected %zu bits, got %zu", name, expected_bits, bits);
|
||||
JS_RaiseDisrupt(js, "%s: expected %zu bits, got %zu", name, expected_bits, bits);
|
||||
return NULL;
|
||||
}
|
||||
return result;
|
||||
@@ -79,7 +79,7 @@ static void *get_blob_any(JSContext *js, JSValue val, size_t *out_bits, const ch
|
||||
JSValue js_crypto_shared(JSContext *js, JSValue self, int argc, JSValue *argv)
|
||||
{
|
||||
if (argc < 2) {
|
||||
return JS_ThrowTypeError(js, "crypto.shared: expected public_key, private_key");
|
||||
return JS_RaiseDisrupt(js, "crypto.shared: expected public_key, private_key");
|
||||
}
|
||||
|
||||
uint8_t *pub = get_blob_check_bits(js, argv[0], 256, "crypto.shared public_key");
|
||||
@@ -97,7 +97,7 @@ JSValue js_crypto_shared(JSContext *js, JSValue self, int argc, JSValue *argv)
|
||||
JSValue js_crypto_blake2(JSContext *js, JSValue self, int argc, JSValue *argv)
|
||||
{
|
||||
if (argc < 1)
|
||||
return JS_ThrowTypeError(js, "crypto.blake2: expected data blob");
|
||||
return JS_RaiseDisrupt(js, "crypto.blake2: expected data blob");
|
||||
|
||||
size_t data_bits;
|
||||
uint8_t *data = get_blob_any(js, argv[0], &data_bits, "crypto.blake2 data");
|
||||
@@ -108,7 +108,7 @@ JSValue js_crypto_blake2(JSContext *js, JSValue self, int argc, JSValue *argv)
|
||||
if (JS_ToInt32(js, &hash_len, argv[1]))
|
||||
return JS_EXCEPTION;
|
||||
if (hash_len < 1 || hash_len > 64)
|
||||
return JS_ThrowRangeError(js, "crypto.blake2: hash length must be between 1 and 64 bytes");
|
||||
return JS_RaiseDisrupt(js, "crypto.blake2: hash length must be between 1 and 64 bytes");
|
||||
}
|
||||
|
||||
uint8_t hash[64];
|
||||
@@ -119,7 +119,7 @@ JSValue js_crypto_blake2(JSContext *js, JSValue self, int argc, JSValue *argv)
|
||||
}
|
||||
|
||||
JSValue js_crypto_sign(JSContext *js, JSValue self, int argc, JSValue *argv) {
|
||||
if (argc < 2) return JS_ThrowTypeError(js, "crypto.sign: expected secret_key, message");
|
||||
if (argc < 2) return JS_RaiseDisrupt(js, "crypto.sign: expected secret_key, message");
|
||||
|
||||
uint8_t *sk = get_blob_check_bits(js, argv[0], 512, "crypto.sign secret_key");
|
||||
if (!sk) return JS_EXCEPTION;
|
||||
@@ -135,7 +135,7 @@ JSValue js_crypto_sign(JSContext *js, JSValue self, int argc, JSValue *argv) {
|
||||
}
|
||||
|
||||
JSValue js_crypto_verify(JSContext *js, JSValue self, int argc, JSValue *argv) {
|
||||
if (argc < 3) return JS_ThrowTypeError(js, "crypto.verify: expected signature, public_key, message");
|
||||
if (argc < 3) return JS_RaiseDisrupt(js, "crypto.verify: expected signature, public_key, message");
|
||||
|
||||
uint8_t *sig = get_blob_check_bits(js, argv[0], 512, "crypto.verify signature");
|
||||
if (!sig) return JS_EXCEPTION;
|
||||
@@ -152,7 +152,7 @@ JSValue js_crypto_verify(JSContext *js, JSValue self, int argc, JSValue *argv) {
|
||||
}
|
||||
|
||||
JSValue js_crypto_lock(JSContext *js, JSValue self, int argc, JSValue *argv) {
|
||||
if (argc < 3) return JS_ThrowTypeError(js, "crypto.lock: expected key, nonce, message, [ad]");
|
||||
if (argc < 3) return JS_RaiseDisrupt(js, "crypto.lock: expected key, nonce, message, [ad]");
|
||||
|
||||
uint8_t *key = get_blob_check_bits(js, argv[0], 256, "crypto.lock key");
|
||||
if (!key) return JS_EXCEPTION;
|
||||
@@ -176,7 +176,7 @@ JSValue js_crypto_lock(JSContext *js, JSValue self, int argc, JSValue *argv) {
|
||||
|
||||
size_t out_len = msg_len + 16;
|
||||
uint8_t *out = malloc(out_len);
|
||||
if (!out) return JS_ThrowOutOfMemory(js);
|
||||
if (!out) return JS_RaiseOOM(js);
|
||||
|
||||
// Output: [Ciphertext (msg_len)] [MAC (16)]
|
||||
crypto_aead_lock(out, out + msg_len, key, nonce, ad, ad_len, msg, msg_len);
|
||||
@@ -187,7 +187,7 @@ JSValue js_crypto_lock(JSContext *js, JSValue self, int argc, JSValue *argv) {
|
||||
}
|
||||
|
||||
JSValue js_crypto_unlock(JSContext *js, JSValue self, int argc, JSValue *argv) {
|
||||
if (argc < 3) return JS_ThrowTypeError(js, "crypto.unlock: expected key, nonce, ciphertext, [ad]");
|
||||
if (argc < 3) return JS_RaiseDisrupt(js, "crypto.unlock: expected key, nonce, ciphertext, [ad]");
|
||||
|
||||
uint8_t *key = get_blob_check_bits(js, argv[0], 256, "crypto.unlock key");
|
||||
if (!key) return JS_EXCEPTION;
|
||||
@@ -200,7 +200,7 @@ JSValue js_crypto_unlock(JSContext *js, JSValue self, int argc, JSValue *argv) {
|
||||
if (!cipher) return JS_EXCEPTION;
|
||||
|
||||
size_t cipher_len = (cipher_bits + 7) / 8;
|
||||
if (cipher_len < 16) return JS_ThrowTypeError(js, "crypto.unlock: ciphertext too short (min 16 bytes)");
|
||||
if (cipher_len < 16) return JS_RaiseDisrupt(js, "crypto.unlock: ciphertext too short (min 16 bytes)");
|
||||
|
||||
size_t msg_len = cipher_len - 16;
|
||||
|
||||
@@ -214,7 +214,7 @@ JSValue js_crypto_unlock(JSContext *js, JSValue self, int argc, JSValue *argv) {
|
||||
}
|
||||
|
||||
uint8_t *out = malloc(msg_len > 0 ? msg_len : 1);
|
||||
if (!out) return JS_ThrowOutOfMemory(js);
|
||||
if (!out) return JS_RaiseOOM(js);
|
||||
|
||||
// MAC is at cipher + msg_len
|
||||
const uint8_t *mac = cipher + msg_len;
|
||||
|
||||
@@ -16,7 +16,7 @@ static SDFile* js2fd(JSContext *ctx, JSValueConst val)
|
||||
{
|
||||
int32_t fd_int;
|
||||
if (JS_ToInt32(ctx, &fd_int, val) < 0) {
|
||||
JS_ThrowTypeError(ctx, "Expected file descriptor number");
|
||||
JS_RaiseDisrupt(ctx, "Expected file descriptor number");
|
||||
return NULL;
|
||||
}
|
||||
return (SDFile*)(intptr_t)fd_int;
|
||||
@@ -58,7 +58,7 @@ JSC_SCALL(fd_open,
|
||||
SDFile* file = pd_file->open(str, flags);
|
||||
if (!file) {
|
||||
const char* err = pd_file->geterr();
|
||||
ret = JS_ThrowInternalError(js, "open failed: %s", err ? err : "unknown error");
|
||||
ret = JS_RaiseDisrupt(js, "open failed: %s", err ? err : "unknown error");
|
||||
} else {
|
||||
ret = JS_NewInt32(js, (int32_t)(intptr_t)file);
|
||||
}
|
||||
@@ -84,7 +84,7 @@ JSC_CCALL(fd_write,
|
||||
|
||||
if (wrote < 0) {
|
||||
const char* err = pd_file->geterr();
|
||||
return JS_ThrowInternalError(js, "write failed: %s", err ? err : "unknown error");
|
||||
return JS_RaiseDisrupt(js, "write failed: %s", err ? err : "unknown error");
|
||||
}
|
||||
|
||||
return JS_NewInt64(js, wrote);
|
||||
@@ -100,13 +100,13 @@ JSC_CCALL(fd_read,
|
||||
|
||||
void *buf = malloc(size);
|
||||
if (!buf)
|
||||
return JS_ThrowInternalError(js, "malloc failed");
|
||||
return JS_RaiseDisrupt(js, "malloc failed");
|
||||
|
||||
int bytes_read = pd_file->read(fd, buf, (unsigned int)size);
|
||||
if (bytes_read < 0) {
|
||||
free(buf);
|
||||
const char* err = pd_file->geterr();
|
||||
return JS_ThrowInternalError(js, "read failed: %s", err ? err : "unknown error");
|
||||
return JS_RaiseDisrupt(js, "read failed: %s", err ? err : "unknown error");
|
||||
}
|
||||
|
||||
ret = js_new_blob_stoned_copy(js, buf, bytes_read);
|
||||
@@ -118,11 +118,11 @@ JSC_SCALL(fd_slurp,
|
||||
FileStat st;
|
||||
if (pd_file->stat(str, &st) != 0) {
|
||||
// const char* err = pd_file->geterr(); // stat usually returns -1 on error
|
||||
return JS_ThrowInternalError(js, "stat failed for %s", str);
|
||||
return JS_RaiseDisrupt(js, "stat failed for %s", str);
|
||||
}
|
||||
|
||||
if (st.isdir)
|
||||
return JS_ThrowTypeError(js, "path is a directory");
|
||||
return JS_RaiseDisrupt(js, "path is a directory");
|
||||
|
||||
size_t size = st.size;
|
||||
if (size == 0)
|
||||
@@ -131,13 +131,13 @@ JSC_SCALL(fd_slurp,
|
||||
SDFile* fd = pd_file->open(str, kFileRead);
|
||||
if (!fd) {
|
||||
const char* err = pd_file->geterr();
|
||||
return JS_ThrowInternalError(js, "open failed: %s", err ? err : "unknown error");
|
||||
return JS_RaiseDisrupt(js, "open failed: %s", err ? err : "unknown error");
|
||||
}
|
||||
|
||||
void *data = malloc(size);
|
||||
if (!data) {
|
||||
pd_file->close(fd);
|
||||
return JS_ThrowInternalError(js, "malloc failed");
|
||||
return JS_RaiseDisrupt(js, "malloc failed");
|
||||
}
|
||||
|
||||
int bytes_read = pd_file->read(fd, data, (unsigned int)size);
|
||||
@@ -145,7 +145,7 @@ JSC_SCALL(fd_slurp,
|
||||
|
||||
if (bytes_read < 0) {
|
||||
free(data);
|
||||
return JS_ThrowInternalError(js, "read failed");
|
||||
return JS_RaiseDisrupt(js, "read failed");
|
||||
}
|
||||
|
||||
ret = js_new_blob_stoned_copy(js, data, bytes_read);
|
||||
@@ -168,7 +168,7 @@ JSC_CCALL(fd_lseek,
|
||||
|
||||
if (pd_file->seek(fd, offset, whence) != 0) {
|
||||
const char* err = pd_file->geterr();
|
||||
return JS_ThrowInternalError(js, "seek failed: %s", err ? err : "unknown error");
|
||||
return JS_RaiseDisrupt(js, "seek failed: %s", err ? err : "unknown error");
|
||||
}
|
||||
|
||||
// tell to get new pos
|
||||
@@ -188,27 +188,27 @@ JSC_SCALL(fd_rmdir,
|
||||
|
||||
if (pd_file->unlink(str, recursive) != 0) {
|
||||
const char* err = pd_file->geterr();
|
||||
ret = JS_ThrowInternalError(js, "could not remove %s: %s", str, err ? err : "unknown error");
|
||||
ret = JS_RaiseDisrupt(js, "could not remove %s: %s", str, err ? err : "unknown error");
|
||||
}
|
||||
)
|
||||
|
||||
JSC_SCALL(fd_mkdir,
|
||||
if (pd_file->mkdir(str) != 0) {
|
||||
const char* err = pd_file->geterr();
|
||||
ret = JS_ThrowInternalError(js, "could not make directory %s: %s", str, err ? err : "unknown error");
|
||||
ret = JS_RaiseDisrupt(js, "could not make directory %s: %s", str, err ? err : "unknown error");
|
||||
}
|
||||
)
|
||||
|
||||
JSC_SCALL(fd_mv,
|
||||
if (argc < 2)
|
||||
ret = JS_ThrowTypeError(js, "fd.mv requires 2 arguments: old path and new path");
|
||||
ret = JS_RaiseDisrupt(js, "fd.mv requires 2 arguments: old path and new path");
|
||||
else if (!JS_IsText(argv[1]))
|
||||
ret = JS_ThrowTypeError(js, "second argument must be a string (new path)");
|
||||
ret = JS_RaiseDisrupt(js, "second argument must be a string (new path)");
|
||||
else {
|
||||
const char *new_path = JS_ToCString(js, argv[1]);
|
||||
if (pd_file->rename(str, new_path) != 0) {
|
||||
const char* err = pd_file->geterr();
|
||||
ret = JS_ThrowInternalError(js, "could not rename %s to %s: %s", str, new_path, err ? err : "unknown error");
|
||||
ret = JS_RaiseDisrupt(js, "could not rename %s to %s: %s", str, new_path, err ? err : "unknown error");
|
||||
}
|
||||
JS_FreeCString(js, new_path);
|
||||
}
|
||||
@@ -220,13 +220,13 @@ JSC_SCALL(fd_symlink,
|
||||
// consume arg
|
||||
JS_FreeCString(js, JS_ToCString(js, argv[1]));
|
||||
}
|
||||
ret = JS_ThrowInternalError(js, "symlink not supported on Playdate");
|
||||
ret = JS_RaiseDisrupt(js, "symlink not supported on Playdate");
|
||||
)
|
||||
|
||||
JSC_SCALL(fd_unlink,
|
||||
if (pd_file->unlink(str, 0) != 0) {
|
||||
const char* err = pd_file->geterr();
|
||||
ret = JS_ThrowInternalError(js, "could not remove file %s: %s", str, err ? err : "unknown error");
|
||||
ret = JS_RaiseDisrupt(js, "could not remove file %s: %s", str, err ? err : "unknown error");
|
||||
}
|
||||
)
|
||||
|
||||
@@ -234,7 +234,7 @@ JSC_SCALL(fd_rm,
|
||||
// Recursive remove
|
||||
if (pd_file->unlink(str, 1) != 0) {
|
||||
const char* err = pd_file->geterr();
|
||||
ret = JS_ThrowInternalError(js, "could not remove %s: %s", str, err ? err : "unknown error");
|
||||
ret = JS_RaiseDisrupt(js, "could not remove %s: %s", str, err ? err : "unknown error");
|
||||
}
|
||||
)
|
||||
|
||||
@@ -244,7 +244,7 @@ JSC_CCALL(fd_fsync,
|
||||
|
||||
if (pd_file->flush(fd) != 0) {
|
||||
const char* err = pd_file->geterr();
|
||||
return JS_ThrowInternalError(js, "fsync failed: %s", err ? err : "unknown error");
|
||||
return JS_RaiseDisrupt(js, "fsync failed: %s", err ? err : "unknown error");
|
||||
}
|
||||
|
||||
return JS_NULL;
|
||||
@@ -256,7 +256,7 @@ JSC_CCALL(fd_close,
|
||||
|
||||
if (pd_file->close(fd) != 0) {
|
||||
const char* err = pd_file->geterr();
|
||||
return JS_ThrowInternalError(js, "close failed: %s", err ? err : "unknown error");
|
||||
return JS_RaiseDisrupt(js, "close failed: %s", err ? err : "unknown error");
|
||||
}
|
||||
|
||||
return JS_NULL;
|
||||
@@ -334,7 +334,7 @@ JSC_SCALL(fd_readdir,
|
||||
if (pd_file->listfiles(str, listfiles_cb, &ctx, 0) != 0) {
|
||||
const char* err = pd_file->geterr();
|
||||
JS_FreeValue(js, ret_arr);
|
||||
return JS_ThrowInternalError(js, "listfiles failed: %s", err ? err : "unknown error");
|
||||
return JS_RaiseDisrupt(js, "listfiles failed: %s", err ? err : "unknown error");
|
||||
}
|
||||
|
||||
ret = ret_arr;
|
||||
@@ -379,7 +379,7 @@ JSC_CCALL(fd_slurpwrite,
|
||||
|
||||
if (!fd) {
|
||||
const char* err = pd_file->geterr();
|
||||
return JS_ThrowInternalError(js, "open failed: %s", err ? err : "unknown error");
|
||||
return JS_RaiseDisrupt(js, "open failed: %s", err ? err : "unknown error");
|
||||
}
|
||||
|
||||
int written = pd_file->write(fd, data, (unsigned int)len);
|
||||
@@ -387,7 +387,7 @@ JSC_CCALL(fd_slurpwrite,
|
||||
|
||||
if (written != (int)len) {
|
||||
const char* err = pd_file->geterr();
|
||||
return JS_ThrowInternalError(js, "write failed: %s", err ? err : "unknown error");
|
||||
return JS_RaiseDisrupt(js, "write failed: %s", err ? err : "unknown error");
|
||||
}
|
||||
|
||||
return JS_NULL;
|
||||
@@ -485,7 +485,7 @@ JSC_CCALL(fd_is_link,
|
||||
JSC_CCALL(fd_readlink,
|
||||
const char *path = JS_ToCString(js, argv[0]);
|
||||
JS_FreeCString(js, path);
|
||||
return JS_ThrowInternalError(js, "readlink not supported");
|
||||
return JS_RaiseDisrupt(js, "readlink not supported");
|
||||
)
|
||||
|
||||
static const JSCFunctionListEntry js_fd_funcs[] = {
|
||||
|
||||
@@ -554,6 +554,7 @@ load_log_config()
|
||||
log = function(name, args) {
|
||||
var sinks = channel_sinks[name]
|
||||
var event = args[0]
|
||||
var c_stack = args[1]
|
||||
var caller = null
|
||||
var stack = null
|
||||
var rec = null
|
||||
@@ -566,8 +567,15 @@ log = function(name, args) {
|
||||
return
|
||||
}
|
||||
|
||||
caller = caller_info(2)
|
||||
if (stack_channels[name]) stack = os.stack(1)
|
||||
// C-provided stack (from JS_Log callback) overrides caller_info/os.stack
|
||||
if (c_stack && length(c_stack) > 0) {
|
||||
caller = {file: c_stack[0].file, line: c_stack[0].line}
|
||||
if (stack_channels[name]) stack = c_stack
|
||||
} else {
|
||||
caller = caller_info(2)
|
||||
if (stack_channels[name]) stack = os.stack(1)
|
||||
}
|
||||
|
||||
rec = {
|
||||
actor_id: _cell.id,
|
||||
timestamp: time.number(),
|
||||
@@ -581,6 +589,9 @@ log = function(name, args) {
|
||||
arrfor(wildcard_sinks, function(sink) { dispatch_to_sink(sink, rec) })
|
||||
}
|
||||
|
||||
// Wire C-level JS_Log through the ƿit log system
|
||||
actor_mod.set_log(log)
|
||||
|
||||
var pronto = use_core('pronto')
|
||||
var fallback = pronto.fallback
|
||||
var parallel = pronto.parallel
|
||||
|
||||
@@ -31,7 +31,7 @@ static int js2fd(JSContext *ctx, JSValueConst val)
|
||||
{
|
||||
int fd;
|
||||
if (JS_ToInt32(ctx, &fd, val) < 0) {
|
||||
JS_ThrowTypeError(ctx, "Expected file descriptor number");
|
||||
JS_RaiseDisrupt(ctx, "Expected file descriptor number");
|
||||
return -1;
|
||||
}
|
||||
return fd;
|
||||
@@ -67,7 +67,7 @@ JSC_SCALL(fd_open,
|
||||
|
||||
int fd = open(str, flags, mode);
|
||||
if (fd < 0)
|
||||
ret = JS_ThrowInternalError(js, "open failed: %s", strerror(errno));
|
||||
ret = JS_RaiseDisrupt(js, "open failed: %s", strerror(errno));
|
||||
else
|
||||
ret = JS_NewInt32(js, fd);
|
||||
)
|
||||
@@ -103,12 +103,12 @@ JSC_CCALL(fd_read,
|
||||
|
||||
void *buf = malloc(size);
|
||||
if (!buf)
|
||||
return JS_ThrowInternalError(js, "malloc failed");
|
||||
return JS_RaiseDisrupt(js, "malloc failed");
|
||||
|
||||
ssize_t bytes_read = read(fd, buf, size);
|
||||
if (bytes_read < 0) {
|
||||
free(buf);
|
||||
return JS_ThrowInternalError(js, "read failed: %s", strerror(errno));
|
||||
return JS_RaiseDisrupt(js, "read failed: %s", strerror(errno));
|
||||
}
|
||||
|
||||
ret = js_new_blob_stoned_copy(js, buf, bytes_read);
|
||||
@@ -119,10 +119,10 @@ JSC_CCALL(fd_read,
|
||||
JSC_SCALL(fd_slurp,
|
||||
struct stat st;
|
||||
if (stat(str, &st) != 0)
|
||||
return JS_ThrowInternalError(js, "stat failed: %s", strerror(errno));
|
||||
return JS_RaiseDisrupt(js, "stat failed: %s", strerror(errno));
|
||||
|
||||
if (!S_ISREG(st.st_mode))
|
||||
return JS_ThrowTypeError(js, "path is not a regular file");
|
||||
return JS_RaiseDisrupt(js, "path is not a regular file");
|
||||
|
||||
size_t size = st.st_size;
|
||||
if (size == 0)
|
||||
@@ -131,12 +131,12 @@ JSC_SCALL(fd_slurp,
|
||||
#ifndef _WIN32
|
||||
int fd = open(str, O_RDONLY);
|
||||
if (fd < 0)
|
||||
return JS_ThrowInternalError(js, "open failed: %s", strerror(errno));
|
||||
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_ThrowInternalError(js, "mmap failed: %s", strerror(errno));
|
||||
return JS_RaiseDisrupt(js, "mmap failed: %s", strerror(errno));
|
||||
}
|
||||
ret = js_new_blob_stoned_copy(js, data, size);
|
||||
munmap(data, size);
|
||||
@@ -145,19 +145,19 @@ JSC_SCALL(fd_slurp,
|
||||
// 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_ThrowInternalError(js, "CreateFile failed: %lu", GetLastError());
|
||||
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_ThrowInternalError(js, "CreateFileMapping failed: %lu", GetLastError());
|
||||
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_ThrowInternalError(js, "MapViewOfFile failed: %lu", GetLastError());
|
||||
return JS_RaiseDisrupt(js, "MapViewOfFile failed: %lu", GetLastError());
|
||||
}
|
||||
|
||||
ret = js_new_blob_stoned_copy(js, data, size);
|
||||
@@ -183,7 +183,7 @@ JSC_CCALL(fd_lseek,
|
||||
|
||||
off_t new_pos = lseek(fd, offset, whence);
|
||||
if (new_pos < 0)
|
||||
return JS_ThrowInternalError(js, "lseek failed: %s", strerror(errno));
|
||||
return JS_RaiseDisrupt(js, "lseek failed: %s", strerror(errno));
|
||||
|
||||
return JS_NewInt64(js, new_pos);
|
||||
)
|
||||
@@ -191,7 +191,7 @@ JSC_CCALL(fd_lseek,
|
||||
JSC_CCALL(fd_getcwd,
|
||||
char buf[PATH_MAX];
|
||||
if (getcwd(buf, sizeof(buf)) == NULL)
|
||||
return JS_ThrowInternalError(js, "getcwd failed: %s", strerror(errno));
|
||||
return JS_RaiseDisrupt(js, "getcwd failed: %s", strerror(errno));
|
||||
return JS_NewString(js, buf);
|
||||
)
|
||||
|
||||
@@ -225,7 +225,7 @@ JSC_SCALL(fd_rmdir,
|
||||
} else {
|
||||
if (unlink(full_path) != 0) {
|
||||
FindClose(hFind);
|
||||
ret = JS_ThrowInternalError(js, "could not remove file %s: %s", full_path, strerror(errno));
|
||||
ret = JS_RaiseDisrupt(js, "could not remove file %s: %s", full_path, strerror(errno));
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
@@ -254,7 +254,7 @@ JSC_SCALL(fd_rmdir,
|
||||
} else {
|
||||
if (unlink(full_path) != 0) {
|
||||
closedir(dir);
|
||||
ret = JS_ThrowInternalError(js, "could not remove file %s: %s", full_path, strerror(errno));
|
||||
ret = JS_RaiseDisrupt(js, "could not remove file %s: %s", full_path, strerror(errno));
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
@@ -265,44 +265,44 @@ JSC_SCALL(fd_rmdir,
|
||||
}
|
||||
|
||||
if (rmdir(str) != 0)
|
||||
ret = JS_ThrowInternalError(js, "could not remove directory %s: %s", str, strerror(errno));
|
||||
ret = JS_RaiseDisrupt(js, "could not remove directory %s: %s", str, strerror(errno));
|
||||
)
|
||||
|
||||
JSC_SCALL(fd_mkdir,
|
||||
if (mkdir(str, 0755) != 0)
|
||||
ret = JS_ThrowInternalError(js, "could not make directory %s: %s", str, strerror(errno));
|
||||
ret = JS_RaiseDisrupt(js, "could not make directory %s: %s", str, strerror(errno));
|
||||
)
|
||||
|
||||
JSC_SCALL(fd_mv,
|
||||
if (argc < 2)
|
||||
ret = JS_ThrowTypeError(js, "fd.mv requires 2 arguments: old path and new path");
|
||||
ret = JS_RaiseDisrupt(js, "fd.mv requires 2 arguments: old path and new path");
|
||||
else if (!JS_IsText(argv[1]))
|
||||
ret = JS_ThrowTypeError(js, "second argument must be a string (new path)");
|
||||
ret = JS_RaiseDisrupt(js, "second argument must be a string (new path)");
|
||||
else {
|
||||
const char *new_path = JS_ToCString(js, argv[1]);
|
||||
if (rename(str, new_path) != 0)
|
||||
ret = JS_ThrowInternalError(js, "could not rename %s to %s: %s", str, new_path, strerror(errno));
|
||||
ret = JS_RaiseDisrupt(js, "could not rename %s to %s: %s", str, new_path, strerror(errno));
|
||||
JS_FreeCString(js, new_path);
|
||||
}
|
||||
)
|
||||
|
||||
JSC_SCALL(fd_symlink,
|
||||
if (argc < 2)
|
||||
ret = JS_ThrowTypeError(js, "fd.symlink requires 2 arguments: target and link path");
|
||||
ret = JS_RaiseDisrupt(js, "fd.symlink requires 2 arguments: target and link path");
|
||||
else if (!JS_IsText(argv[1]))
|
||||
ret = JS_ThrowTypeError(js, "second argument must be a string (link path)");
|
||||
ret = JS_RaiseDisrupt(js, "second argument must be a string (link path)");
|
||||
else {
|
||||
const char *link_path = JS_ToCString(js, argv[1]);
|
||||
#ifdef _WIN32
|
||||
if (!CreateSymbolicLinkA(link_path, str, SYMBOLIC_LINK_FLAG_DIRECTORY)) {
|
||||
// Try file
|
||||
if (!CreateSymbolicLinkA(link_path, str, 0)) {
|
||||
ret = JS_ThrowInternalError(js, "could not create symlink %s -> %s: %lu", link_path, str, GetLastError());
|
||||
ret = JS_RaiseDisrupt(js, "could not create symlink %s -> %s: %lu", link_path, str, GetLastError());
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (symlink(str, link_path) != 0)
|
||||
ret = JS_ThrowInternalError(js, "could not create symlink %s -> %s: %s", link_path, str, strerror(errno));
|
||||
ret = JS_RaiseDisrupt(js, "could not create symlink %s -> %s: %s", link_path, str, strerror(errno));
|
||||
#endif
|
||||
JS_FreeCString(js, link_path);
|
||||
}
|
||||
@@ -320,14 +320,14 @@ JSC_SCALL(fd_unlink,
|
||||
if (err == ERROR_ACCESS_DENIED) {
|
||||
// Might be a directory, try RemoveDirectory
|
||||
if (!RemoveDirectoryA(str))
|
||||
ret = JS_ThrowInternalError(js, "could not remove %s: error %lu", str, GetLastError());
|
||||
ret = JS_RaiseDisrupt(js, "could not remove %s: error %lu", str, GetLastError());
|
||||
} else {
|
||||
ret = JS_ThrowInternalError(js, "could not remove file %s: error %lu", str, err);
|
||||
ret = JS_RaiseDisrupt(js, "could not remove file %s: error %lu", str, err);
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (unlink(str) != 0)
|
||||
ret = JS_ThrowInternalError(js, "could not remove file %s: %s", str, strerror(errno));
|
||||
ret = JS_RaiseDisrupt(js, "could not remove file %s: %s", str, strerror(errno));
|
||||
#endif
|
||||
)
|
||||
|
||||
@@ -386,7 +386,7 @@ static int remove_recursive(const char *path) {
|
||||
|
||||
JSC_SCALL(fd_rm,
|
||||
if (remove_recursive(str) != 0)
|
||||
ret = JS_ThrowInternalError(js, "could not remove %s: %s", str, strerror(errno));
|
||||
ret = JS_RaiseDisrupt(js, "could not remove %s: %s", str, strerror(errno));
|
||||
)
|
||||
|
||||
JSC_CCALL(fd_fsync,
|
||||
@@ -394,7 +394,7 @@ JSC_CCALL(fd_fsync,
|
||||
if (fd < 0) return JS_EXCEPTION;
|
||||
|
||||
if (fsync(fd) != 0)
|
||||
return JS_ThrowInternalError(js, "fsync failed: %s", strerror(errno));
|
||||
return JS_RaiseDisrupt(js, "fsync failed: %s", strerror(errno));
|
||||
|
||||
return JS_NULL;
|
||||
)
|
||||
@@ -404,7 +404,7 @@ JSC_CCALL(fd_close,
|
||||
if (fd < 0) return JS_EXCEPTION;
|
||||
|
||||
if (close(fd) != 0)
|
||||
return JS_ThrowInternalError(js, "close failed: %s", strerror(errno));
|
||||
return JS_RaiseDisrupt(js, "close failed: %s", strerror(errno));
|
||||
|
||||
return JS_NULL;
|
||||
)
|
||||
@@ -415,7 +415,7 @@ JSC_CCALL(fd_fstat,
|
||||
|
||||
struct stat st;
|
||||
if (fstat(fd, &st) != 0)
|
||||
return JS_ThrowInternalError(js, "fstat failed: %s", strerror(errno));
|
||||
return JS_RaiseDisrupt(js, "fstat failed: %s", strerror(errno));
|
||||
|
||||
JS_FRAME(js);
|
||||
JS_ROOT(obj, JS_NewObject(js));
|
||||
@@ -496,7 +496,7 @@ JSC_SCALL(fd_readdir,
|
||||
snprintf(path, sizeof(path), "%s\\*", str);
|
||||
HANDLE hFind = FindFirstFile(path, &ffd);
|
||||
if (hFind == INVALID_HANDLE_VALUE) {
|
||||
ret = JS_ThrowInternalError(js, "FindFirstFile failed for %s", path);
|
||||
ret = JS_RaiseDisrupt(js, "FindFirstFile failed for %s", path);
|
||||
} else {
|
||||
JS_ROOT(arr, JS_NewArray(js));
|
||||
do {
|
||||
@@ -519,7 +519,7 @@ JSC_SCALL(fd_readdir,
|
||||
closedir(d);
|
||||
ret = arr.val;
|
||||
} else {
|
||||
ret = JS_ThrowInternalError(js, "opendir failed for %s: %s", str, strerror(errno));
|
||||
ret = JS_RaiseDisrupt(js, "opendir failed for %s: %s", str, strerror(errno));
|
||||
}
|
||||
#endif
|
||||
JS_RestoreFrame(_js_ctx, _js_gc_frame, _js_local_frame);
|
||||
@@ -565,7 +565,7 @@ JSC_CCALL(fd_slurpwrite,
|
||||
if (!str) return JS_EXCEPTION;
|
||||
int fd = open(str, O_WRONLY | O_CREAT | O_TRUNC, 0644);
|
||||
if (fd < 0) {
|
||||
ret = JS_ThrowInternalError(js, "open failed for %s: %s", str, strerror(errno));
|
||||
ret = JS_RaiseDisrupt(js, "open failed for %s: %s", str, strerror(errno));
|
||||
JS_FreeCString(js, str);
|
||||
return ret;
|
||||
}
|
||||
@@ -574,7 +574,7 @@ JSC_CCALL(fd_slurpwrite,
|
||||
close(fd);
|
||||
|
||||
if (written != (ssize_t)len) {
|
||||
ret = JS_ThrowInternalError(js, "write failed for %s: %s", str, strerror(errno));
|
||||
ret = JS_RaiseDisrupt(js, "write failed for %s: %s", str, strerror(errno));
|
||||
JS_FreeCString(js, str);
|
||||
return ret;
|
||||
}
|
||||
@@ -596,7 +596,7 @@ JSC_CCALL(fd_slurpappend,
|
||||
if (!str) return JS_EXCEPTION;
|
||||
int fd = open(str, O_WRONLY | O_CREAT | O_APPEND, 0644);
|
||||
if (fd < 0) {
|
||||
ret = JS_ThrowInternalError(js, "open failed for %s: %s", str, strerror(errno));
|
||||
ret = JS_RaiseDisrupt(js, "open failed for %s: %s", str, strerror(errno));
|
||||
JS_FreeCString(js, str);
|
||||
return ret;
|
||||
}
|
||||
@@ -605,7 +605,7 @@ JSC_CCALL(fd_slurpappend,
|
||||
close(fd);
|
||||
|
||||
if (written != (ssize_t)len) {
|
||||
ret = JS_ThrowInternalError(js, "write failed for %s: %s", str, strerror(errno));
|
||||
ret = JS_RaiseDisrupt(js, "write failed for %s: %s", str, strerror(errno));
|
||||
JS_FreeCString(js, str);
|
||||
return ret;
|
||||
}
|
||||
@@ -702,7 +702,7 @@ JSC_CCALL(fd_realpath,
|
||||
char resolved[PATH_MAX];
|
||||
DWORD len = GetFullPathNameA(path, PATH_MAX, resolved, NULL);
|
||||
if (len == 0 || len >= PATH_MAX) {
|
||||
JSValue err = JS_ThrowInternalError(js, "realpath failed for %s: %s", path, strerror(errno));
|
||||
JSValue err = JS_RaiseDisrupt(js, "realpath failed for %s: %s", path, strerror(errno));
|
||||
JS_FreeCString(js, path);
|
||||
return err;
|
||||
}
|
||||
@@ -711,7 +711,7 @@ JSC_CCALL(fd_realpath,
|
||||
#else
|
||||
char *resolved = realpath(path, NULL);
|
||||
if (!resolved) {
|
||||
JSValue err = JS_ThrowInternalError(js, "realpath failed for %s: %s", path, strerror(errno));
|
||||
JSValue err = JS_RaiseDisrupt(js, "realpath failed for %s: %s", path, strerror(errno));
|
||||
JS_FreeCString(js, path);
|
||||
return err;
|
||||
}
|
||||
@@ -745,13 +745,13 @@ JSC_CCALL(fd_readlink,
|
||||
|
||||
#ifdef _WIN32
|
||||
JS_FreeCString(js, path);
|
||||
return JS_ThrowInternalError(js, "readlink not supported on Windows");
|
||||
return JS_RaiseDisrupt(js, "readlink not supported on Windows");
|
||||
#else
|
||||
char buf[PATH_MAX];
|
||||
ssize_t len = readlink(path, buf, sizeof(buf) - 1);
|
||||
JS_FreeCString(js, path);
|
||||
if (len < 0) {
|
||||
return JS_ThrowInternalError(js, "readlink failed: %s", strerror(errno));
|
||||
return JS_RaiseDisrupt(js, "readlink failed: %s", strerror(errno));
|
||||
}
|
||||
buf[len] = '\0';
|
||||
return JS_NewString(js, buf);
|
||||
|
||||
@@ -98,7 +98,7 @@ static JSValue js_os_totalmem(JSContext *js, JSValue self, int argc, JSValue *ar
|
||||
#ifdef _WIN32
|
||||
MEMORYSTATUSEX statex;
|
||||
statex.dwLength = sizeof(statex);
|
||||
if (!GlobalMemoryStatusEx(&statex)) return JS_ThrowInternalError(js,"GlobalMemoryStatusEx failed");
|
||||
if (!GlobalMemoryStatusEx(&statex)) return JS_RaiseDisrupt(js,"GlobalMemoryStatusEx failed");
|
||||
return JS_NewInt64(js,(int64_t)(statex.ullTotalPhys / (1024 * 1024)));
|
||||
#elif defined(__linux__)
|
||||
struct sysinfo info;
|
||||
@@ -150,7 +150,7 @@ static JSValue js_os_hostname(JSContext *js, JSValue self, int argc, JSValue *ar
|
||||
return JS_NewString(js, buffer);
|
||||
#else
|
||||
struct utsname buffer;
|
||||
if (uname(&buffer) != 0) return JS_ThrowReferenceError(js,"Could not get hostname.");
|
||||
if (uname(&buffer) != 0) return JS_RaiseDisrupt(js,"Could not get hostname.");
|
||||
return JS_NewString(js, buffer.nodename);
|
||||
#endif
|
||||
return ret;
|
||||
@@ -189,7 +189,7 @@ static JSValue js_os_freemem(JSContext *js, JSValue self, int argc, JSValue *arg
|
||||
#ifdef _WIN32
|
||||
MEMORYSTATUSEX statex;
|
||||
statex.dwLength = sizeof(statex);
|
||||
if (!GlobalMemoryStatusEx(&statex)) return JS_ThrowInternalError(js,"GlobalMemoryStatusEx failed");
|
||||
if (!GlobalMemoryStatusEx(&statex)) return JS_RaiseDisrupt(js,"GlobalMemoryStatusEx failed");
|
||||
return JS_NewInt64(js,(int64_t)statex.ullAvailPhys);
|
||||
#elif defined(__linux__)
|
||||
struct sysinfo info;
|
||||
@@ -316,12 +316,12 @@ JSC_CCALL(os_exit,
|
||||
static JSValue js_os_dylib_open(JSContext *js, JSValue self, int argc, JSValue *argv)
|
||||
{
|
||||
if (argc < 1) {
|
||||
return JS_ThrowTypeError(js, "dylib_open requires a path argument");
|
||||
return JS_RaiseDisrupt(js, "dylib_open requires a path argument");
|
||||
}
|
||||
|
||||
const char *path = JS_ToCString(js, argv[0]);
|
||||
if (!path) {
|
||||
return JS_ThrowTypeError(js, "path must be a string");
|
||||
return JS_RaiseDisrupt(js, "path must be a string");
|
||||
}
|
||||
|
||||
void *handle;
|
||||
@@ -341,7 +341,7 @@ static JSValue js_os_dylib_open(JSContext *js, JSValue self, int argc, JSValue *
|
||||
error_msg = dl_error;
|
||||
}
|
||||
#endif
|
||||
return JS_ThrowReferenceError(js, "Failed to load library: %s", error_msg);
|
||||
return JS_RaiseDisrupt(js, "Failed to load library: %s", error_msg);
|
||||
}
|
||||
|
||||
JSValue dylib_obj = JS_NewObjectClass(js, js_dylib_class_id);
|
||||
@@ -396,17 +396,17 @@ static JSValue js_os_dylib_preload(JSContext *js, JSValue self, int argc, JSValu
|
||||
static JSValue js_os_dylib_symbol(JSContext *js, JSValue self, int argc, JSValue *argv)
|
||||
{
|
||||
if (argc < 2) {
|
||||
return JS_ThrowTypeError(js, "dylib_symbol requires dylib object and symbol name");
|
||||
return JS_RaiseDisrupt(js, "dylib_symbol requires dylib object and symbol name");
|
||||
}
|
||||
|
||||
void *handle = JS_GetOpaque(argv[0], js_dylib_class_id);
|
||||
if (!handle) {
|
||||
return JS_ThrowTypeError(js, "First argument must be a dylib object");
|
||||
return JS_RaiseDisrupt(js, "First argument must be a dylib object");
|
||||
}
|
||||
|
||||
const char *symbol_name = JS_ToCString(js, argv[1]);
|
||||
if (!symbol_name) {
|
||||
return JS_ThrowTypeError(js, "symbol name must be a string");
|
||||
return JS_RaiseDisrupt(js, "symbol name must be a string");
|
||||
}
|
||||
|
||||
JSValue (*symbol)(JSContext *js);
|
||||
@@ -426,7 +426,7 @@ static JSValue js_os_dylib_symbol(JSContext *js, JSValue self, int argc, JSValue
|
||||
error_msg = dl_error;
|
||||
}
|
||||
#endif
|
||||
return JS_ThrowReferenceError(js, "Failed to load symbol: %s", error_msg);
|
||||
return JS_RaiseDisrupt(js, "Failed to load symbol: %s", error_msg);
|
||||
return JS_NULL;
|
||||
}
|
||||
|
||||
@@ -437,17 +437,17 @@ static JSValue js_os_dylib_symbol(JSContext *js, JSValue self, int argc, JSValue
|
||||
static JSValue js_os_dylib_has_symbol(JSContext *js, JSValue self, int argc, JSValue *argv)
|
||||
{
|
||||
if (argc < 2) {
|
||||
return JS_ThrowTypeError(js, "dylib_has_symbol requires dylib object and symbol name");
|
||||
return JS_RaiseDisrupt(js, "dylib_has_symbol requires dylib object and symbol name");
|
||||
}
|
||||
|
||||
void *handle = JS_GetOpaque(argv[0], js_dylib_class_id);
|
||||
if (!handle) {
|
||||
return JS_ThrowTypeError(js, "First argument must be a dylib object");
|
||||
return JS_RaiseDisrupt(js, "First argument must be a dylib object");
|
||||
}
|
||||
|
||||
const char *symbol_name = JS_ToCString(js, argv[1]);
|
||||
if (!symbol_name) {
|
||||
return JS_ThrowTypeError(js, "symbol name must be a string");
|
||||
return JS_RaiseDisrupt(js, "symbol name must be a string");
|
||||
}
|
||||
|
||||
void *symbol;
|
||||
@@ -465,7 +465,7 @@ static JSValue js_os_dylib_has_symbol(JSContext *js, JSValue self, int argc, JSV
|
||||
static JSValue js_os_dylib_close(JSContext *js, JSValue self, int argc, JSValue *argv)
|
||||
{
|
||||
if (argc < 1)
|
||||
return JS_ThrowTypeError(js, "dylib_close requires a dylib object");
|
||||
return JS_RaiseDisrupt(js, "dylib_close requires a dylib object");
|
||||
void *handle = JS_GetOpaque(argv[0], js_dylib_class_id);
|
||||
if (handle) {
|
||||
#ifdef _WIN32
|
||||
@@ -487,11 +487,11 @@ extern JSValue js_os_qbe(JSContext *, JSValue, int, JSValue *);
|
||||
static JSValue js_os_native_module_load(JSContext *js, JSValue self, int argc, JSValue *argv)
|
||||
{
|
||||
if (argc < 1)
|
||||
return JS_ThrowTypeError(js, "native_module_load requires a dylib object");
|
||||
return JS_RaiseDisrupt(js, "native_module_load requires a dylib object");
|
||||
|
||||
void *handle = JS_GetOpaque(argv[0], js_dylib_class_id);
|
||||
if (!handle)
|
||||
return JS_ThrowTypeError(js, "First argument must be a dylib object");
|
||||
return JS_RaiseDisrupt(js, "First argument must be a dylib object");
|
||||
|
||||
JSValue env = (argc >= 2) ? argv[1] : JS_NULL;
|
||||
return cell_rt_native_module_load(js, handle, env);
|
||||
@@ -500,11 +500,11 @@ static JSValue js_os_native_module_load(JSContext *js, JSValue self, int argc, J
|
||||
static JSValue js_os_native_module_load_named(JSContext *js, JSValue self, int argc, JSValue *argv)
|
||||
{
|
||||
if (argc < 2)
|
||||
return JS_ThrowTypeError(js, "native_module_load_named requires (dylib, sym_name)");
|
||||
return JS_RaiseDisrupt(js, "native_module_load_named requires (dylib, sym_name)");
|
||||
|
||||
void *handle = JS_GetOpaque(argv[0], js_dylib_class_id);
|
||||
if (!handle)
|
||||
return JS_ThrowTypeError(js, "First argument must be a dylib object");
|
||||
return JS_RaiseDisrupt(js, "First argument must be a dylib object");
|
||||
|
||||
const char *sym_name = JS_ToCString(js, argv[1]);
|
||||
if (!sym_name)
|
||||
@@ -532,11 +532,11 @@ static JSValue js_os_load_internal(JSContext *js, JSValue self, int argc, JSValu
|
||||
handle = dlopen(NULL, RTLD_LAZY);
|
||||
#endif
|
||||
if (argc < 1)
|
||||
return JS_ThrowTypeError(js, "load_internal requires a symbol name");
|
||||
return JS_RaiseDisrupt(js, "load_internal requires a symbol name");
|
||||
|
||||
const char *symbol_name = JS_ToCString(js, argv[0]);
|
||||
if (!symbol_name)
|
||||
return JS_ThrowTypeError(js, "symbol name must be a string");
|
||||
return JS_RaiseDisrupt(js, "symbol name must be a string");
|
||||
|
||||
JSValue (*symbol)(JSContext *js);
|
||||
#if defined(_WIN32)
|
||||
@@ -562,11 +562,11 @@ static JSValue js_os_internal_exists(JSContext *js, JSValue self, int argc, JSVa
|
||||
handle = dlopen(NULL, RTLD_LAZY);
|
||||
#endif
|
||||
if (argc < 1)
|
||||
return JS_ThrowTypeError(js, "internal_exists requires a symbol name");
|
||||
return JS_RaiseDisrupt(js, "internal_exists requires a symbol name");
|
||||
|
||||
const char *symbol_name = JS_ToCString(js, argv[0]);
|
||||
if (!symbol_name)
|
||||
return JS_ThrowTypeError(js, "symbol name must be a string");
|
||||
return JS_RaiseDisrupt(js, "symbol name must be a string");
|
||||
|
||||
void *symbol;
|
||||
#if defined(_WIN32)
|
||||
|
||||
@@ -96,11 +96,11 @@ JSC_CCALL(os_exit,
|
||||
|
||||
// dylib functions - assuming static build for now unless side modules are used
|
||||
static JSValue js_os_dylib_open(JSContext *js, JSValue self, int argc, JSValue *argv) {
|
||||
return JS_ThrowInternalError(js, "dylib_open: not supported on Emscripten");
|
||||
return JS_RaiseDisrupt(js, "dylib_open: not supported on Emscripten");
|
||||
}
|
||||
|
||||
static JSValue js_os_dylib_symbol(JSContext *js, JSValue self, int argc, JSValue *argv) {
|
||||
return JS_ThrowInternalError(js, "dylib_symbol: not supported on Emscripten");
|
||||
return JS_RaiseDisrupt(js, "dylib_symbol: not supported on Emscripten");
|
||||
}
|
||||
|
||||
static JSValue js_os_dylib_has_symbol(JSContext *js, JSValue self, int argc, JSValue *argv) {
|
||||
|
||||
@@ -94,11 +94,11 @@ JSC_CCALL(os_exit,
|
||||
|
||||
// dylib functions - not supported on Playdate
|
||||
static JSValue js_os_dylib_open(JSContext *js, JSValue self, int argc, JSValue *argv) {
|
||||
return JS_ThrowInternalError(js, "dylib_open: not supported on Playdate");
|
||||
return JS_RaiseDisrupt(js, "dylib_open: not supported on Playdate");
|
||||
}
|
||||
|
||||
static JSValue js_os_dylib_symbol(JSContext *js, JSValue self, int argc, JSValue *argv) {
|
||||
return JS_ThrowInternalError(js, "dylib_symbol: not supported on Playdate");
|
||||
return JS_RaiseDisrupt(js, "dylib_symbol: not supported on Playdate");
|
||||
}
|
||||
|
||||
static JSValue js_os_dylib_has_symbol(JSContext *js, JSValue self, int argc, JSValue *argv) {
|
||||
|
||||
32
net/enet.c
32
net/enet.c
@@ -30,7 +30,7 @@ static void js_enet_peer_finalizer(JSRuntime *rt, JSValue val)
|
||||
// Initialize the ENet library. Must be called before using any ENet functionality.
|
||||
static JSValue js_enet_initialize(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
|
||||
{
|
||||
if (enet_initialize() != 0) return JS_ThrowInternalError(ctx, "Error initializing ENet");
|
||||
if (enet_initialize() != 0) return JS_RaiseDisrupt(ctx, "Error initializing ENet");
|
||||
return JS_NULL;
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ static JSValue js_enet_host_create(JSContext *ctx, JSValueConst this_val, int ar
|
||||
|
||||
if (argc < 1 || !JS_IsRecord(argv[0])) {
|
||||
host = enet_host_create(NULL, peer_count, channel_limit, incoming_bandwidth, outgoing_bandwidth);
|
||||
if (!host) return JS_ThrowInternalError(ctx, "Failed to create ENet client host");
|
||||
if (!host) return JS_RaiseDisrupt(ctx, "Failed to create ENet client host");
|
||||
goto wrap;
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ static JSValue js_enet_host_create(JSContext *ctx, JSValueConst this_val, int ar
|
||||
int err = enet_address_set_host_ip(&address, addr_str);
|
||||
if (err != 0) {
|
||||
JS_FreeCString(ctx, addr_str);
|
||||
return JS_ThrowInternalError(ctx, "Failed to set host IP from '%s'. Error: %d", addr_str, err);
|
||||
return JS_RaiseDisrupt(ctx, "Failed to set host IP from '%s'. Error: %d", addr_str, err);
|
||||
}
|
||||
}
|
||||
address.port = (enet_uint16)port32;
|
||||
@@ -109,7 +109,7 @@ static JSValue js_enet_host_create(JSContext *ctx, JSValueConst this_val, int ar
|
||||
JS_FreeValue(ctx, out_bw_val);
|
||||
|
||||
host = enet_host_create(send, peer_count, channel_limit, incoming_bandwidth, outgoing_bandwidth);
|
||||
if (!host) return JS_ThrowInternalError(ctx, "Failed to create ENet host");
|
||||
if (!host) return JS_RaiseDisrupt(ctx, "Failed to create ENet host");
|
||||
|
||||
wrap:
|
||||
obj = JS_NewObjectClass(ctx, enet_host_id);
|
||||
@@ -145,7 +145,7 @@ static JSValue js_enet_host_service(JSContext *ctx, JSValueConst this_val, int a
|
||||
ENetHost *host = JS_GetOpaque(this_val, enet_host_id);
|
||||
if (!host) return JS_EXCEPTION;
|
||||
|
||||
if (argc < 1 || !JS_IsFunction(argv[0])) return JS_ThrowTypeError(ctx, "Expected a callback function as first argument");
|
||||
if (argc < 1 || !JS_IsFunction(argv[0])) return JS_RaiseDisrupt(ctx, "Expected a callback function as first argument");
|
||||
JSValue callback = JS_DupValue(ctx, argv[0]);
|
||||
|
||||
double secs;
|
||||
@@ -201,7 +201,7 @@ static JSValue js_enet_host_connect(JSContext *ctx, JSValueConst this_val, int a
|
||||
ENetHost *host = JS_GetOpaque(this_val, enet_host_id);
|
||||
if (!host) return JS_EXCEPTION;
|
||||
|
||||
if (argc < 2) return JS_ThrowTypeError(ctx, "Expected 2 arguments: hostname, port");
|
||||
if (argc < 2) return JS_RaiseDisrupt(ctx, "Expected 2 arguments: hostname, port");
|
||||
|
||||
const char *hostname = JS_ToCString(ctx, argv[0]);
|
||||
if (!hostname) return JS_EXCEPTION;
|
||||
@@ -214,7 +214,7 @@ static JSValue js_enet_host_connect(JSContext *ctx, JSValueConst this_val, int a
|
||||
address.port = port;
|
||||
|
||||
ENetPeer *peer = enet_host_connect(host, &address, 2, 0);
|
||||
if (!peer) return JS_ThrowInternalError(ctx, "No available peers for initiating an ENet connection");
|
||||
if (!peer) return JS_RaiseDisrupt(ctx, "No available peers for initiating an ENet connection");
|
||||
|
||||
return peer_get_value(ctx, peer);
|
||||
}
|
||||
@@ -239,7 +239,7 @@ static JSValue js_enet_host_broadcast(JSContext *ctx, JSValueConst this_val, int
|
||||
ENetHost *host = JS_GetOpaque(this_val, enet_host_id);
|
||||
if (!host) return JS_EXCEPTION;
|
||||
|
||||
if (argc < 1) return JS_ThrowTypeError(ctx, "Expected a string or ArrayBuffer to broadcast");
|
||||
if (argc < 1) return JS_RaiseDisrupt(ctx, "Expected a string or ArrayBuffer to broadcast");
|
||||
|
||||
const char *data_str = NULL;
|
||||
size_t data_len = 0;
|
||||
@@ -252,12 +252,12 @@ static JSValue js_enet_host_broadcast(JSContext *ctx, JSValueConst this_val, int
|
||||
buf = js_get_blob_data(ctx, &data_len, argv[0]);
|
||||
if (!buf) return JS_EXCEPTION;
|
||||
} else {
|
||||
return JS_ThrowTypeError(ctx, "broadcast() only accepts a string or ArrayBuffer");
|
||||
return JS_RaiseDisrupt(ctx, "broadcast() only accepts a string or ArrayBuffer");
|
||||
}
|
||||
|
||||
ENetPacket *packet = enet_packet_create(data_str ? (const void*)data_str : (const void*)buf, data_len, ENET_PACKET_FLAG_RELIABLE);
|
||||
if (data_str) JS_FreeCString(ctx, data_str);
|
||||
if (!packet) return JS_ThrowInternalError(ctx, "Failed to create ENet packet");
|
||||
if (!packet) return JS_RaiseDisrupt(ctx, "Failed to create ENet packet");
|
||||
|
||||
enet_host_broadcast(host, 0, packet);
|
||||
return JS_NULL;
|
||||
@@ -304,7 +304,7 @@ static JSValue js_enet_peer_send(JSContext *ctx, JSValueConst this_val, int argc
|
||||
ENetPeer *peer = JS_GetOpaque(this_val, enet_peer_class_id);
|
||||
if (!peer) return JS_EXCEPTION;
|
||||
|
||||
if (argc < 1) return JS_ThrowTypeError(ctx, "Expected a string or ArrayBuffer to send");
|
||||
if (argc < 1) return JS_RaiseDisrupt(ctx, "Expected a string or ArrayBuffer to send");
|
||||
|
||||
const char *data_str = NULL;
|
||||
size_t data_len = 0;
|
||||
@@ -317,14 +317,14 @@ static JSValue js_enet_peer_send(JSContext *ctx, JSValueConst this_val, int argc
|
||||
buf = js_get_blob_data(ctx, &data_len, argv[0]);
|
||||
if (!buf) return JS_EXCEPTION;
|
||||
} else {
|
||||
return JS_ThrowTypeError(ctx, "send() only accepts a string or ArrayBuffer");
|
||||
return JS_RaiseDisrupt(ctx, "send() only accepts a string or ArrayBuffer");
|
||||
}
|
||||
|
||||
ENetPacket *packet = enet_packet_create(data_str ? (const void*)data_str : (const void*)buf, data_len, ENET_PACKET_FLAG_RELIABLE);
|
||||
if (data_str) JS_FreeCString(ctx, data_str);
|
||||
if (!packet) return JS_ThrowInternalError(ctx, "Failed to create ENet packet");
|
||||
if (!packet) return JS_RaiseDisrupt(ctx, "Failed to create ENet packet");
|
||||
|
||||
if (enet_peer_send(peer, 0, packet) < 0) return JS_ThrowInternalError(ctx, "Unable to send packet");
|
||||
if (enet_peer_send(peer, 0, packet) < 0) return JS_RaiseDisrupt(ctx, "Unable to send packet");
|
||||
return JS_NULL;
|
||||
}
|
||||
|
||||
@@ -386,7 +386,7 @@ static JSValue js_enet_peer_throttle_configure(JSContext *ctx, JSValueConst this
|
||||
|
||||
int interval, acceleration, deceleration;
|
||||
if (argc < 3 || JS_ToInt32(ctx, &interval, argv[0]) || JS_ToInt32(ctx, &acceleration, argv[1]) || JS_ToInt32(ctx, &deceleration, argv[2]))
|
||||
return JS_ThrowTypeError(ctx, "Expected 3 int arguments: interval, acceleration, deceleration");
|
||||
return JS_RaiseDisrupt(ctx, "Expected 3 int arguments: interval, acceleration, deceleration");
|
||||
|
||||
enet_peer_throttle_configure(peer, interval, acceleration, deceleration);
|
||||
return JS_NULL;
|
||||
@@ -399,7 +399,7 @@ static JSValue js_enet_peer_timeout(JSContext *ctx, JSValueConst this_val, int a
|
||||
|
||||
int timeout_limit, timeout_min, timeout_max;
|
||||
if (argc < 3 || JS_ToInt32(ctx, &timeout_limit, argv[0]) || JS_ToInt32(ctx, &timeout_min, argv[1]) || JS_ToInt32(ctx, &timeout_max, argv[2]))
|
||||
return JS_ThrowTypeError(ctx, "Expected 3 integer arguments: timeout_limit, timeout_min, timeout_max");
|
||||
return JS_RaiseDisrupt(ctx, "Expected 3 integer arguments: timeout_limit, timeout_min, timeout_max");
|
||||
|
||||
enet_peer_timeout(peer, timeout_limit, timeout_min, timeout_max);
|
||||
return JS_NULL;
|
||||
|
||||
@@ -294,16 +294,16 @@ static int par_easycurl_to_memory(char const *url, par_byte **data, int *nbytes)
|
||||
static JSValue js_fetch_picoparser(JSContext *ctx, JSValueConst this_val,
|
||||
int argc, JSValueConst *argv) {
|
||||
if (argc < 1 || !JS_IsText(argv[0]))
|
||||
return JS_ThrowTypeError(ctx, "fetch: URL string required");
|
||||
return JS_RaiseDisrupt(ctx, "fetch: URL string required");
|
||||
|
||||
const char *url = JS_ToCString(ctx, argv[0]);
|
||||
if (!url) return JS_ThrowTypeError(ctx, "fetch: invalid URL");
|
||||
if (!url) return JS_RaiseDisrupt(ctx, "fetch: invalid URL");
|
||||
|
||||
par_byte *data = NULL;
|
||||
int nbytes = 0;
|
||||
if (!par_easycurl_to_memory(url, &data, &nbytes)) {
|
||||
JS_FreeCString(ctx, url);
|
||||
return JS_ThrowTypeError(ctx, "fetch: failed to fetch URL");
|
||||
return JS_RaiseDisrupt(ctx, "fetch: failed to fetch URL");
|
||||
}
|
||||
|
||||
JS_FreeCString(ctx, url);
|
||||
|
||||
@@ -136,14 +136,14 @@ static int parse_url(const char *url, char **host, int *port, char **path, int *
|
||||
static JSValue js_fetch_playdate(JSContext *ctx, JSValueConst this_val,
|
||||
int argc, JSValueConst *argv) {
|
||||
if (argc < 1 || !JS_IsText(argv[0]))
|
||||
return JS_ThrowTypeError(ctx, "fetch: URL string required");
|
||||
return JS_RaiseDisrupt(ctx, "fetch: URL string required");
|
||||
|
||||
if (!pd_network || !pd_network->http) {
|
||||
return JS_ThrowInternalError(ctx, "fetch: Playdate network API not available");
|
||||
return JS_RaiseDisrupt(ctx, "fetch: Playdate network API not available");
|
||||
}
|
||||
|
||||
const char *url = JS_ToCString(ctx, argv[0]);
|
||||
if (!url) return JS_ThrowTypeError(ctx, "fetch: invalid URL");
|
||||
if (!url) return JS_RaiseDisrupt(ctx, "fetch: invalid URL");
|
||||
|
||||
char *host = NULL;
|
||||
char *path = NULL;
|
||||
@@ -152,7 +152,7 @@ static JSValue js_fetch_playdate(JSContext *ctx, JSValueConst this_val,
|
||||
|
||||
if (parse_url(url, &host, &port, &path, &is_https) < 0) {
|
||||
JS_FreeCString(ctx, url);
|
||||
return JS_ThrowTypeError(ctx, "fetch: failed to parse URL");
|
||||
return JS_RaiseDisrupt(ctx, "fetch: failed to parse URL");
|
||||
}
|
||||
|
||||
JS_FreeCString(ctx, url);
|
||||
@@ -161,7 +161,7 @@ static JSValue js_fetch_playdate(JSContext *ctx, JSValueConst this_val,
|
||||
if (is_https) {
|
||||
free(host);
|
||||
free(path);
|
||||
return JS_ThrowTypeError(ctx, "fetch: HTTPS not supported on Playdate");
|
||||
return JS_RaiseDisrupt(ctx, "fetch: HTTPS not supported on Playdate");
|
||||
}
|
||||
|
||||
// Create HTTP connection
|
||||
@@ -170,7 +170,7 @@ static JSValue js_fetch_playdate(JSContext *ctx, JSValueConst this_val,
|
||||
|
||||
if (!conn) {
|
||||
free(path);
|
||||
return JS_ThrowInternalError(ctx, "fetch: failed to create connection");
|
||||
return JS_RaiseDisrupt(ctx, "fetch: failed to create connection");
|
||||
}
|
||||
|
||||
// Set up context
|
||||
@@ -186,7 +186,7 @@ static JSValue js_fetch_playdate(JSContext *ctx, JSValueConst this_val,
|
||||
if (!fetch_ctx.data) {
|
||||
pd_network->http->release(conn);
|
||||
free(path);
|
||||
return JS_ThrowInternalError(ctx, "fetch: malloc failed");
|
||||
return JS_RaiseDisrupt(ctx, "fetch: malloc failed");
|
||||
}
|
||||
|
||||
pd_network->http->setUserdata(conn, &fetch_ctx);
|
||||
@@ -203,7 +203,7 @@ static JSValue js_fetch_playdate(JSContext *ctx, JSValueConst this_val,
|
||||
if (err != NET_OK) {
|
||||
free(fetch_ctx.data);
|
||||
pd_network->http->release(conn);
|
||||
return JS_ThrowInternalError(ctx, "fetch: request failed with error %d", err);
|
||||
return JS_RaiseDisrupt(ctx, "fetch: request failed with error %d", err);
|
||||
}
|
||||
|
||||
// Poll until complete (blocking)
|
||||
@@ -219,7 +219,7 @@ static JSValue js_fetch_playdate(JSContext *ctx, JSValueConst this_val,
|
||||
|
||||
if (!fetch_ctx.success) {
|
||||
free(fetch_ctx.data);
|
||||
return JS_ThrowTypeError(ctx, "fetch: request failed (status %d)", fetch_ctx.status_code);
|
||||
return JS_RaiseDisrupt(ctx, "fetch: request failed (status %d)", fetch_ctx.status_code);
|
||||
}
|
||||
|
||||
// Return a Blob wrapping the data
|
||||
@@ -232,7 +232,7 @@ static JSValue js_fetch_playdate(JSContext *ctx, JSValueConst this_val,
|
||||
// Simulator/non-extension build - provide stub
|
||||
static JSValue js_fetch_playdate(JSContext *ctx, JSValueConst this_val,
|
||||
int argc, JSValueConst *argv) {
|
||||
return JS_ThrowInternalError(ctx, "fetch: not available in simulator");
|
||||
return JS_RaiseDisrupt(ctx, "fetch: not available in simulator");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
50
net/socket.c
50
net/socket.c
@@ -30,7 +30,7 @@ static int js2fd(JSContext *ctx, JSValueConst val)
|
||||
{
|
||||
int fd;
|
||||
if (JS_ToInt32(ctx, &fd, val) < 0) {
|
||||
JS_ThrowTypeError(ctx, "Expected file descriptor number");
|
||||
JS_RaiseDisrupt(ctx, "Expected file descriptor number");
|
||||
return -1;
|
||||
}
|
||||
return fd;
|
||||
@@ -94,7 +94,7 @@ JSC_CCALL(socket_getaddrinfo,
|
||||
if (service) JS_FreeCString(js, service);
|
||||
|
||||
if (status != 0) {
|
||||
return JS_ThrowReferenceError(js, "getaddrinfo error: %s", gai_strerror(status));
|
||||
return JS_RaiseDisrupt(js, "getaddrinfo error: %s", gai_strerror(status));
|
||||
}
|
||||
|
||||
// Convert linked list to JS array
|
||||
@@ -173,7 +173,7 @@ JSC_CCALL(socket_socket,
|
||||
|
||||
int sockfd = socket(domain, type, protocol);
|
||||
if (sockfd < 0) {
|
||||
return JS_ThrowReferenceError(js, "socket failed: %s", strerror(errno));
|
||||
return JS_RaiseDisrupt(js, "socket failed: %s", strerror(errno));
|
||||
}
|
||||
|
||||
return JS_NewInt32(js, sockfd);
|
||||
@@ -195,12 +195,12 @@ JSC_CCALL(socket_bind,
|
||||
addr.sin_port = htons(port);
|
||||
if (inet_pton(AF_INET, addr_str, &addr.sin_addr) <= 0) {
|
||||
JS_FreeCString(js, addr_str);
|
||||
return JS_ThrowReferenceError(js, "Invalid address");
|
||||
return JS_RaiseDisrupt(js, "Invalid address");
|
||||
}
|
||||
JS_FreeCString(js, addr_str);
|
||||
|
||||
if (bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
|
||||
return JS_ThrowReferenceError(js, "bind failed: %s", strerror(errno));
|
||||
return JS_RaiseDisrupt(js, "bind failed: %s", strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -223,12 +223,12 @@ JSC_CCALL(socket_connect,
|
||||
addr.sin_port = htons(port);
|
||||
if (inet_pton(AF_INET, addr_str, &addr.sin_addr) <= 0) {
|
||||
JS_FreeCString(js, addr_str);
|
||||
return JS_ThrowReferenceError(js, "Invalid address");
|
||||
return JS_RaiseDisrupt(js, "Invalid address");
|
||||
}
|
||||
JS_FreeCString(js, addr_str);
|
||||
|
||||
if (connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
|
||||
return JS_ThrowReferenceError(js, "connect failed: %s", strerror(errno));
|
||||
return JS_RaiseDisrupt(js, "connect failed: %s", strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -245,7 +245,7 @@ JSC_CCALL(socket_listen,
|
||||
}
|
||||
|
||||
if (listen(sockfd, backlog) < 0) {
|
||||
return JS_ThrowReferenceError(js, "listen failed: %s", strerror(errno));
|
||||
return JS_RaiseDisrupt(js, "listen failed: %s", strerror(errno));
|
||||
}
|
||||
|
||||
return JS_NULL;
|
||||
@@ -260,7 +260,7 @@ JSC_CCALL(socket_accept,
|
||||
|
||||
int new_sockfd = accept(sockfd, (struct sockaddr *)&their_addr, &addr_size);
|
||||
if (new_sockfd < 0) {
|
||||
return JS_ThrowReferenceError(js, "accept failed: %s", strerror(errno));
|
||||
return JS_RaiseDisrupt(js, "accept failed: %s", strerror(errno));
|
||||
}
|
||||
|
||||
ret = JS_NewObject(js);
|
||||
@@ -307,13 +307,13 @@ JSC_CCALL(socket_send,
|
||||
return JS_EXCEPTION;
|
||||
|
||||
if (len == 0)
|
||||
return JS_ThrowReferenceError(js, "No data to send");
|
||||
return JS_RaiseDisrupt(js, "No data to send");
|
||||
|
||||
sent = send(sockfd, (const char *)data, len, flags);
|
||||
}
|
||||
|
||||
if (sent < 0) {
|
||||
return JS_ThrowReferenceError(js, "send failed: %s", strerror(errno));
|
||||
return JS_RaiseDisrupt(js, "send failed: %s", strerror(errno));
|
||||
}
|
||||
|
||||
return JS_NewInt64(js, sent);
|
||||
@@ -335,13 +335,13 @@ JSC_CCALL(socket_recv,
|
||||
|
||||
void *buf = malloc(len);
|
||||
if (!buf) {
|
||||
return JS_ThrowReferenceError(js, "malloc failed");
|
||||
return JS_RaiseDisrupt(js, "malloc failed");
|
||||
}
|
||||
|
||||
ssize_t received = recv(sockfd, buf, len, flags);
|
||||
if (received < 0) {
|
||||
free(buf);
|
||||
return JS_ThrowReferenceError(js, "recv failed: %s", strerror(errno));
|
||||
return JS_RaiseDisrupt(js, "recv failed: %s", strerror(errno));
|
||||
}
|
||||
|
||||
ret = js_new_blob_stoned_copy(js, buf, received);
|
||||
@@ -377,7 +377,7 @@ JSC_CCALL(socket_sendto,
|
||||
addr.sin_port = htons(port);
|
||||
if (inet_pton(AF_INET, addr_str, &addr.sin_addr) <= 0) {
|
||||
JS_FreeCString(js, addr_str);
|
||||
return JS_ThrowReferenceError(js, "Invalid address");
|
||||
return JS_RaiseDisrupt(js, "Invalid address");
|
||||
}
|
||||
JS_FreeCString(js, addr_str);
|
||||
|
||||
@@ -395,13 +395,13 @@ JSC_CCALL(socket_sendto,
|
||||
return JS_EXCEPTION;
|
||||
}
|
||||
if (len == 0) {
|
||||
return JS_ThrowReferenceError(js, "No data to send");
|
||||
return JS_RaiseDisrupt(js, "No data to send");
|
||||
}
|
||||
sent = sendto(sockfd, (const char *)data, len, flags, to_addr, to_len);
|
||||
}
|
||||
|
||||
if (sent < 0) {
|
||||
return JS_ThrowReferenceError(js, "sendto failed: %s", strerror(errno));
|
||||
return JS_RaiseDisrupt(js, "sendto failed: %s", strerror(errno));
|
||||
}
|
||||
|
||||
return JS_NewInt64(js, sent);
|
||||
@@ -423,7 +423,7 @@ JSC_CCALL(socket_recvfrom,
|
||||
|
||||
void *buf = malloc(len);
|
||||
if (!buf) {
|
||||
return JS_ThrowReferenceError(js, "malloc failed");
|
||||
return JS_RaiseDisrupt(js, "malloc failed");
|
||||
}
|
||||
|
||||
struct sockaddr_storage from_addr;
|
||||
@@ -433,7 +433,7 @@ JSC_CCALL(socket_recvfrom,
|
||||
(struct sockaddr *)&from_addr, &from_len);
|
||||
if (received < 0) {
|
||||
free(buf);
|
||||
return JS_ThrowReferenceError(js, "recvfrom failed: %s", strerror(errno));
|
||||
return JS_RaiseDisrupt(js, "recvfrom failed: %s", strerror(errno));
|
||||
}
|
||||
|
||||
ret = JS_NewObject(js);
|
||||
@@ -469,7 +469,7 @@ JSC_CCALL(socket_shutdown,
|
||||
}
|
||||
|
||||
if (shutdown(sockfd, how) < 0) {
|
||||
return JS_ThrowReferenceError(js, "shutdown failed: %s", strerror(errno));
|
||||
return JS_RaiseDisrupt(js, "shutdown failed: %s", strerror(errno));
|
||||
}
|
||||
|
||||
return JS_NULL;
|
||||
@@ -483,7 +483,7 @@ JSC_CCALL(socket_getpeername,
|
||||
socklen_t len = sizeof addr;
|
||||
|
||||
if (getpeername(sockfd, (struct sockaddr *)&addr, &len) < 0) {
|
||||
return JS_ThrowReferenceError(js, "getpeername failed: %s", strerror(errno));
|
||||
return JS_RaiseDisrupt(js, "getpeername failed: %s", strerror(errno));
|
||||
}
|
||||
|
||||
char ipstr[INET6_ADDRSTRLEN];
|
||||
@@ -506,7 +506,7 @@ JSC_CCALL(socket_getpeername,
|
||||
JSC_CCALL(socket_gethostname,
|
||||
char hostname[256];
|
||||
if (gethostname(hostname, sizeof(hostname)) < 0) {
|
||||
return JS_ThrowReferenceError(js, "gethostname failed: %s", strerror(errno));
|
||||
return JS_RaiseDisrupt(js, "gethostname failed: %s", strerror(errno));
|
||||
}
|
||||
return JS_NewString(js, hostname);
|
||||
)
|
||||
@@ -551,15 +551,15 @@ JSC_CCALL(socket_setsockopt,
|
||||
if (JS_IsBool(argv[3])) {
|
||||
int optval = JS_ToBool(js, argv[3]);
|
||||
if (setsockopt(sockfd, level, optname, &optval, sizeof(optval)) < 0) {
|
||||
return JS_ThrowReferenceError(js, "setsockopt failed: %s", strerror(errno));
|
||||
return JS_RaiseDisrupt(js, "setsockopt failed: %s", strerror(errno));
|
||||
}
|
||||
} else if (JS_IsNumber(argv[3])) {
|
||||
int optval = js2number(js, argv[3]);
|
||||
if (setsockopt(sockfd, level, optname, &optval, sizeof(optval)) < 0) {
|
||||
return JS_ThrowReferenceError(js, "setsockopt failed: %s", strerror(errno));
|
||||
return JS_RaiseDisrupt(js, "setsockopt failed: %s", strerror(errno));
|
||||
}
|
||||
} else {
|
||||
return JS_ThrowTypeError(js, "Invalid option value");
|
||||
return JS_RaiseDisrupt(js, "Invalid option value");
|
||||
}
|
||||
|
||||
return JS_NULL;
|
||||
@@ -570,7 +570,7 @@ JSC_CCALL(socket_close,
|
||||
if (sockfd < 0) return JS_EXCEPTION;
|
||||
|
||||
if (close(sockfd) != 0)
|
||||
return JS_ThrowReferenceError(js, "close failed: %s", strerror(errno));
|
||||
return JS_RaiseDisrupt(js, "close failed: %s", strerror(errno));
|
||||
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
@@ -7,51 +7,51 @@
|
||||
// All socket functions throw "not supported" errors
|
||||
|
||||
JSC_CCALL(socket_getaddrinfo,
|
||||
return JS_ThrowInternalError(js, "socket.getaddrinfo: not supported on Playdate");
|
||||
return JS_RaiseDisrupt(js, "socket.getaddrinfo: not supported on Playdate");
|
||||
)
|
||||
|
||||
JSC_CCALL(socket_socket,
|
||||
return JS_ThrowInternalError(js, "socket.socket: not supported on Playdate");
|
||||
return JS_RaiseDisrupt(js, "socket.socket: not supported on Playdate");
|
||||
)
|
||||
|
||||
JSC_CCALL(socket_bind,
|
||||
return JS_ThrowInternalError(js, "socket.bind: not supported on Playdate");
|
||||
return JS_RaiseDisrupt(js, "socket.bind: not supported on Playdate");
|
||||
)
|
||||
|
||||
JSC_CCALL(socket_connect,
|
||||
return JS_ThrowInternalError(js, "socket.connect: not supported on Playdate");
|
||||
return JS_RaiseDisrupt(js, "socket.connect: not supported on Playdate");
|
||||
)
|
||||
|
||||
JSC_CCALL(socket_listen,
|
||||
return JS_ThrowInternalError(js, "socket.listen: not supported on Playdate");
|
||||
return JS_RaiseDisrupt(js, "socket.listen: not supported on Playdate");
|
||||
)
|
||||
|
||||
JSC_CCALL(socket_accept,
|
||||
return JS_ThrowInternalError(js, "socket.accept: not supported on Playdate");
|
||||
return JS_RaiseDisrupt(js, "socket.accept: not supported on Playdate");
|
||||
)
|
||||
|
||||
JSC_CCALL(socket_send,
|
||||
return JS_ThrowInternalError(js, "socket.send: not supported on Playdate");
|
||||
return JS_RaiseDisrupt(js, "socket.send: not supported on Playdate");
|
||||
)
|
||||
|
||||
JSC_CCALL(socket_recv,
|
||||
return JS_ThrowInternalError(js, "socket.recv: not supported on Playdate");
|
||||
return JS_RaiseDisrupt(js, "socket.recv: not supported on Playdate");
|
||||
)
|
||||
|
||||
JSC_CCALL(socket_sendto,
|
||||
return JS_ThrowInternalError(js, "socket.sendto: not supported on Playdate");
|
||||
return JS_RaiseDisrupt(js, "socket.sendto: not supported on Playdate");
|
||||
)
|
||||
|
||||
JSC_CCALL(socket_recvfrom,
|
||||
return JS_ThrowInternalError(js, "socket.recvfrom: not supported on Playdate");
|
||||
return JS_RaiseDisrupt(js, "socket.recvfrom: not supported on Playdate");
|
||||
)
|
||||
|
||||
JSC_CCALL(socket_shutdown,
|
||||
return JS_ThrowInternalError(js, "socket.shutdown: not supported on Playdate");
|
||||
return JS_RaiseDisrupt(js, "socket.shutdown: not supported on Playdate");
|
||||
)
|
||||
|
||||
JSC_CCALL(socket_getpeername,
|
||||
return JS_ThrowInternalError(js, "socket.getpeername: not supported on Playdate");
|
||||
return JS_RaiseDisrupt(js, "socket.getpeername: not supported on Playdate");
|
||||
)
|
||||
|
||||
JSC_CCALL(socket_gethostname,
|
||||
@@ -63,11 +63,11 @@ JSC_CCALL(socket_gai_strerror,
|
||||
)
|
||||
|
||||
JSC_CCALL(socket_setsockopt,
|
||||
return JS_ThrowInternalError(js, "socket.setsockopt: not supported on Playdate");
|
||||
return JS_RaiseDisrupt(js, "socket.setsockopt: not supported on Playdate");
|
||||
)
|
||||
|
||||
JSC_CCALL(socket_close,
|
||||
return JS_ThrowInternalError(js, "socket.close: not supported on Playdate");
|
||||
return JS_RaiseDisrupt(js, "socket.close: not supported on Playdate");
|
||||
)
|
||||
|
||||
static const JSCFunctionListEntry js_socket_funcs[] = {
|
||||
|
||||
@@ -7,48 +7,48 @@
|
||||
// --- Display API Wrappers ---
|
||||
|
||||
JSC_CCALL(display_getWidth,
|
||||
if (!pd_display) return JS_ThrowInternalError(js, "display not initialized");
|
||||
if (!pd_display) return JS_RaiseDisrupt(js, "display not initialized");
|
||||
return JS_NewInt32(js, pd_display->getWidth());
|
||||
)
|
||||
|
||||
JSC_CCALL(display_getHeight,
|
||||
if (!pd_display) return JS_ThrowInternalError(js, "display not initialized");
|
||||
if (!pd_display) return JS_RaiseDisrupt(js, "display not initialized");
|
||||
return JS_NewInt32(js, pd_display->getHeight());
|
||||
)
|
||||
|
||||
JSC_CCALL(display_setRefreshRate,
|
||||
if (!pd_display) return JS_ThrowInternalError(js, "display not initialized");
|
||||
if (!pd_display) return JS_RaiseDisrupt(js, "display not initialized");
|
||||
float rate = (float)js2number(js, argv[0]);
|
||||
pd_display->setRefreshRate(rate);
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(display_getRefreshRate,
|
||||
if (!pd_display) return JS_ThrowInternalError(js, "display not initialized");
|
||||
if (!pd_display) return JS_RaiseDisrupt(js, "display not initialized");
|
||||
return JS_NewFloat64(js, pd_display->getRefreshRate());
|
||||
)
|
||||
|
||||
JSC_CCALL(display_getFPS,
|
||||
if (!pd_display) return JS_ThrowInternalError(js, "display not initialized");
|
||||
if (!pd_display) return JS_RaiseDisrupt(js, "display not initialized");
|
||||
return JS_NewFloat64(js, pd_display->getFPS());
|
||||
)
|
||||
|
||||
JSC_CCALL(display_setInverted,
|
||||
if (!pd_display) return JS_ThrowInternalError(js, "display not initialized");
|
||||
if (!pd_display) return JS_RaiseDisrupt(js, "display not initialized");
|
||||
int flag = JS_ToBool(js, argv[0]);
|
||||
pd_display->setInverted(flag);
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(display_setScale,
|
||||
if (!pd_display) return JS_ThrowInternalError(js, "display not initialized");
|
||||
if (!pd_display) return JS_RaiseDisrupt(js, "display not initialized");
|
||||
unsigned int scale = (unsigned int)js2number(js, argv[0]);
|
||||
pd_display->setScale(scale);
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(display_setMosaic,
|
||||
if (!pd_display) return JS_ThrowInternalError(js, "display not initialized");
|
||||
if (!pd_display) return JS_RaiseDisrupt(js, "display not initialized");
|
||||
unsigned int x = (unsigned int)js2number(js, argv[0]);
|
||||
unsigned int y = (unsigned int)js2number(js, argv[1]);
|
||||
pd_display->setMosaic(x, y);
|
||||
@@ -56,7 +56,7 @@ JSC_CCALL(display_setMosaic,
|
||||
)
|
||||
|
||||
JSC_CCALL(display_setFlipped,
|
||||
if (!pd_display) return JS_ThrowInternalError(js, "display not initialized");
|
||||
if (!pd_display) return JS_RaiseDisrupt(js, "display not initialized");
|
||||
int x = JS_ToBool(js, argv[0]);
|
||||
int y = JS_ToBool(js, argv[1]);
|
||||
pd_display->setFlipped(x, y);
|
||||
@@ -64,7 +64,7 @@ JSC_CCALL(display_setFlipped,
|
||||
)
|
||||
|
||||
JSC_CCALL(display_setOffset,
|
||||
if (!pd_display) return JS_ThrowInternalError(js, "display not initialized");
|
||||
if (!pd_display) return JS_RaiseDisrupt(js, "display not initialized");
|
||||
int x = (int)js2number(js, argv[0]);
|
||||
int y = (int)js2number(js, argv[1]);
|
||||
pd_display->setOffset(x, y);
|
||||
|
||||
@@ -17,13 +17,13 @@ static SDFile* js2sdfile(JSContext *js, JSValueConst val) {
|
||||
// --- File Functions ---
|
||||
|
||||
JSC_CCALL(file_geterr,
|
||||
if (!pd_file) return JS_ThrowInternalError(js, "file not initialized");
|
||||
if (!pd_file) return JS_RaiseDisrupt(js, "file not initialized");
|
||||
const char *err = pd_file->geterr();
|
||||
return err ? JS_NewString(js, err) : JS_NULL;
|
||||
)
|
||||
|
||||
JSC_SCALL(file_stat,
|
||||
if (!pd_file) return JS_ThrowInternalError(js, "file not initialized");
|
||||
if (!pd_file) return JS_RaiseDisrupt(js, "file not initialized");
|
||||
FileStat st;
|
||||
if (pd_file->stat(str, &st) != 0) {
|
||||
ret = JS_NULL;
|
||||
@@ -42,18 +42,18 @@ JSC_SCALL(file_stat,
|
||||
)
|
||||
|
||||
JSC_SCALL(file_mkdir,
|
||||
if (!pd_file) return JS_ThrowInternalError(js, "file not initialized");
|
||||
if (!pd_file) return JS_RaiseDisrupt(js, "file not initialized");
|
||||
ret = JS_NewBool(js, pd_file->mkdir(str) == 0);
|
||||
)
|
||||
|
||||
JSC_SCALL(file_unlink,
|
||||
if (!pd_file) return JS_ThrowInternalError(js, "file not initialized");
|
||||
if (!pd_file) return JS_RaiseDisrupt(js, "file not initialized");
|
||||
int recursive = argc > 1 ? JS_ToBool(js, argv[1]) : 0;
|
||||
ret = JS_NewBool(js, pd_file->unlink(str, recursive) == 0);
|
||||
)
|
||||
|
||||
JSC_SCALL(file_rename,
|
||||
if (!pd_file) return JS_ThrowInternalError(js, "file not initialized");
|
||||
if (!pd_file) return JS_RaiseDisrupt(js, "file not initialized");
|
||||
const char *to = JS_ToCString(js, argv[1]);
|
||||
int result = pd_file->rename(str, to);
|
||||
JS_FreeCString(js, to);
|
||||
@@ -61,7 +61,7 @@ JSC_SCALL(file_rename,
|
||||
)
|
||||
|
||||
JSC_SCALL(file_open,
|
||||
if (!pd_file) return JS_ThrowInternalError(js, "file not initialized");
|
||||
if (!pd_file) return JS_RaiseDisrupt(js, "file not initialized");
|
||||
FileOptions mode = kFileRead;
|
||||
if (argc > 1) mode = (FileOptions)(int)js2number(js, argv[1]);
|
||||
SDFile *f = pd_file->open(str, mode);
|
||||
@@ -69,17 +69,17 @@ JSC_SCALL(file_open,
|
||||
)
|
||||
|
||||
JSC_CCALL(file_close,
|
||||
if (!pd_file) return JS_ThrowInternalError(js, "file not initialized");
|
||||
if (!pd_file) return JS_RaiseDisrupt(js, "file not initialized");
|
||||
SDFile *f = js2sdfile(js, argv[0]);
|
||||
return JS_NewBool(js, pd_file->close(f) == 0);
|
||||
)
|
||||
|
||||
JSC_CCALL(file_read,
|
||||
if (!pd_file) return JS_ThrowInternalError(js, "file not initialized");
|
||||
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_ThrowInternalError(js, "malloc failed");
|
||||
if (!buf) return JS_RaiseDisrupt(js, "malloc failed");
|
||||
int read = pd_file->read(f, buf, len);
|
||||
if (read < 0) {
|
||||
free(buf);
|
||||
@@ -91,7 +91,7 @@ JSC_CCALL(file_read,
|
||||
)
|
||||
|
||||
JSC_CCALL(file_write,
|
||||
if (!pd_file) return JS_ThrowInternalError(js, "file not initialized");
|
||||
if (!pd_file) return JS_RaiseDisrupt(js, "file not initialized");
|
||||
SDFile *f = js2sdfile(js, argv[0]);
|
||||
size_t len;
|
||||
const void *data = js_get_blob_data(js, &len, argv[1]);
|
||||
@@ -101,19 +101,19 @@ JSC_CCALL(file_write,
|
||||
)
|
||||
|
||||
JSC_CCALL(file_flush,
|
||||
if (!pd_file) return JS_ThrowInternalError(js, "file not initialized");
|
||||
if (!pd_file) return JS_RaiseDisrupt(js, "file not initialized");
|
||||
SDFile *f = js2sdfile(js, argv[0]);
|
||||
return JS_NewBool(js, pd_file->flush(f) == 0);
|
||||
)
|
||||
|
||||
JSC_CCALL(file_tell,
|
||||
if (!pd_file) return JS_ThrowInternalError(js, "file not initialized");
|
||||
if (!pd_file) return JS_RaiseDisrupt(js, "file not initialized");
|
||||
SDFile *f = js2sdfile(js, argv[0]);
|
||||
return JS_NewInt32(js, pd_file->tell(f));
|
||||
)
|
||||
|
||||
JSC_CCALL(file_seek,
|
||||
if (!pd_file) return JS_ThrowInternalError(js, "file not initialized");
|
||||
if (!pd_file) return JS_RaiseDisrupt(js, "file not initialized");
|
||||
SDFile *f = js2sdfile(js, argv[0]);
|
||||
int pos = (int)js2number(js, argv[1]);
|
||||
int whence = argc > 2 ? (int)js2number(js, argv[2]) : SEEK_SET;
|
||||
@@ -132,7 +132,7 @@ static void listfiles_cb(const char *path, void *userdata) {
|
||||
}
|
||||
|
||||
JSC_SCALL(file_listfiles,
|
||||
if (!pd_file) return JS_ThrowInternalError(js, "file not initialized");
|
||||
if (!pd_file) return JS_RaiseDisrupt(js, "file not initialized");
|
||||
int showhidden = argc > 1 ? JS_ToBool(js, argv[1]) : 0;
|
||||
JSValue arr = JS_NewArray(js);
|
||||
struct listfiles_ctx ctx = { js, arr, 0 };
|
||||
|
||||
@@ -27,76 +27,76 @@ static LCDFont* js2font(JSContext *js, JSValueConst val) {
|
||||
// --- Drawing Functions ---
|
||||
|
||||
JSC_CCALL(gfx_clear,
|
||||
if (!pd_gfx) return JS_ThrowInternalError(js, "graphics not initialized");
|
||||
if (!pd_gfx) return JS_RaiseDisrupt(js, "graphics not initialized");
|
||||
LCDColor color = (LCDColor)js2number(js, argv[0]);
|
||||
pd_gfx->clear(color);
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(gfx_setBackgroundColor,
|
||||
if (!pd_gfx) return JS_ThrowInternalError(js, "graphics not initialized");
|
||||
if (!pd_gfx) return JS_RaiseDisrupt(js, "graphics not initialized");
|
||||
LCDSolidColor color = (LCDSolidColor)(int)js2number(js, argv[0]);
|
||||
pd_gfx->setBackgroundColor(color);
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(gfx_setDrawMode,
|
||||
if (!pd_gfx) return JS_ThrowInternalError(js, "graphics not initialized");
|
||||
if (!pd_gfx) return JS_RaiseDisrupt(js, "graphics not initialized");
|
||||
LCDBitmapDrawMode mode = (LCDBitmapDrawMode)(int)js2number(js, argv[0]);
|
||||
LCDBitmapDrawMode prev = pd_gfx->setDrawMode(mode);
|
||||
return JS_NewInt32(js, prev);
|
||||
)
|
||||
|
||||
JSC_CCALL(gfx_setDrawOffset,
|
||||
if (!pd_gfx) return JS_ThrowInternalError(js, "graphics not initialized");
|
||||
if (!pd_gfx) return JS_RaiseDisrupt(js, "graphics not initialized");
|
||||
pd_gfx->setDrawOffset((int)js2number(js, argv[0]), (int)js2number(js, argv[1]));
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(gfx_setClipRect,
|
||||
if (!pd_gfx) return JS_ThrowInternalError(js, "graphics not initialized");
|
||||
if (!pd_gfx) return JS_RaiseDisrupt(js, "graphics not initialized");
|
||||
pd_gfx->setClipRect((int)js2number(js, argv[0]), (int)js2number(js, argv[1]),
|
||||
(int)js2number(js, argv[2]), (int)js2number(js, argv[3]));
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(gfx_clearClipRect,
|
||||
if (!pd_gfx) return JS_ThrowInternalError(js, "graphics not initialized");
|
||||
if (!pd_gfx) return JS_RaiseDisrupt(js, "graphics not initialized");
|
||||
pd_gfx->clearClipRect();
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(gfx_setLineCapStyle,
|
||||
if (!pd_gfx) return JS_ThrowInternalError(js, "graphics not initialized");
|
||||
if (!pd_gfx) return JS_RaiseDisrupt(js, "graphics not initialized");
|
||||
pd_gfx->setLineCapStyle((LCDLineCapStyle)(int)js2number(js, argv[0]));
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(gfx_setFont,
|
||||
if (!pd_gfx) return JS_ThrowInternalError(js, "graphics not initialized");
|
||||
if (!pd_gfx) return JS_RaiseDisrupt(js, "graphics not initialized");
|
||||
pd_gfx->setFont(js2font(js, argv[0]));
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(gfx_setTextTracking,
|
||||
if (!pd_gfx) return JS_ThrowInternalError(js, "graphics not initialized");
|
||||
if (!pd_gfx) return JS_RaiseDisrupt(js, "graphics not initialized");
|
||||
pd_gfx->setTextTracking((int)js2number(js, argv[0]));
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(gfx_getTextTracking,
|
||||
if (!pd_gfx) return JS_ThrowInternalError(js, "graphics not initialized");
|
||||
if (!pd_gfx) return JS_RaiseDisrupt(js, "graphics not initialized");
|
||||
return JS_NewInt32(js, pd_gfx->getTextTracking());
|
||||
)
|
||||
|
||||
JSC_CCALL(gfx_pushContext,
|
||||
if (!pd_gfx) return JS_ThrowInternalError(js, "graphics not initialized");
|
||||
if (!pd_gfx) return JS_RaiseDisrupt(js, "graphics not initialized");
|
||||
pd_gfx->pushContext(argc > 0 ? js2bitmap(js, argv[0]) : NULL);
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(gfx_popContext,
|
||||
if (!pd_gfx) return JS_ThrowInternalError(js, "graphics not initialized");
|
||||
if (!pd_gfx) return JS_RaiseDisrupt(js, "graphics not initialized");
|
||||
pd_gfx->popContext();
|
||||
return JS_NULL;
|
||||
)
|
||||
@@ -104,16 +104,16 @@ JSC_CCALL(gfx_popContext,
|
||||
// --- Drawing Primitives ---
|
||||
|
||||
JSC_CCALL(gfx_drawBitmap,
|
||||
if (!pd_gfx) return JS_ThrowInternalError(js, "graphics not initialized");
|
||||
if (!pd_gfx) return JS_RaiseDisrupt(js, "graphics not initialized");
|
||||
LCDBitmap *bmp = js2bitmap(js, argv[0]);
|
||||
if (!bmp) return JS_ThrowTypeError(js, "invalid bitmap");
|
||||
if (!bmp) return JS_RaiseDisrupt(js, "invalid bitmap");
|
||||
pd_gfx->drawBitmap(bmp, (int)js2number(js, argv[1]), (int)js2number(js, argv[2]),
|
||||
argc > 3 ? (LCDBitmapFlip)(int)js2number(js, argv[3]) : kBitmapUnflipped);
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(gfx_drawLine,
|
||||
if (!pd_gfx) return JS_ThrowInternalError(js, "graphics not initialized");
|
||||
if (!pd_gfx) return JS_RaiseDisrupt(js, "graphics not initialized");
|
||||
pd_gfx->drawLine((int)js2number(js, argv[0]), (int)js2number(js, argv[1]),
|
||||
(int)js2number(js, argv[2]), (int)js2number(js, argv[3]),
|
||||
(int)js2number(js, argv[4]), (LCDColor)js2number(js, argv[5]));
|
||||
@@ -121,7 +121,7 @@ JSC_CCALL(gfx_drawLine,
|
||||
)
|
||||
|
||||
JSC_CCALL(gfx_drawRect,
|
||||
if (!pd_gfx) return JS_ThrowInternalError(js, "graphics not initialized");
|
||||
if (!pd_gfx) return JS_RaiseDisrupt(js, "graphics not initialized");
|
||||
pd_gfx->drawRect((int)js2number(js, argv[0]), (int)js2number(js, argv[1]),
|
||||
(int)js2number(js, argv[2]), (int)js2number(js, argv[3]),
|
||||
(LCDColor)js2number(js, argv[4]));
|
||||
@@ -129,7 +129,7 @@ JSC_CCALL(gfx_drawRect,
|
||||
)
|
||||
|
||||
JSC_CCALL(gfx_fillRect,
|
||||
if (!pd_gfx) return JS_ThrowInternalError(js, "graphics not initialized");
|
||||
if (!pd_gfx) return JS_RaiseDisrupt(js, "graphics not initialized");
|
||||
pd_gfx->fillRect((int)js2number(js, argv[0]), (int)js2number(js, argv[1]),
|
||||
(int)js2number(js, argv[2]), (int)js2number(js, argv[3]),
|
||||
(LCDColor)js2number(js, argv[4]));
|
||||
@@ -137,7 +137,7 @@ JSC_CCALL(gfx_fillRect,
|
||||
)
|
||||
|
||||
JSC_CCALL(gfx_fillTriangle,
|
||||
if (!pd_gfx) return JS_ThrowInternalError(js, "graphics not initialized");
|
||||
if (!pd_gfx) return JS_RaiseDisrupt(js, "graphics not initialized");
|
||||
pd_gfx->fillTriangle((int)js2number(js, argv[0]), (int)js2number(js, argv[1]),
|
||||
(int)js2number(js, argv[2]), (int)js2number(js, argv[3]),
|
||||
(int)js2number(js, argv[4]), (int)js2number(js, argv[5]),
|
||||
@@ -146,7 +146,7 @@ JSC_CCALL(gfx_fillTriangle,
|
||||
)
|
||||
|
||||
JSC_CCALL(gfx_drawEllipse,
|
||||
if (!pd_gfx) return JS_ThrowInternalError(js, "graphics not initialized");
|
||||
if (!pd_gfx) return JS_RaiseDisrupt(js, "graphics not initialized");
|
||||
pd_gfx->drawEllipse((int)js2number(js, argv[0]), (int)js2number(js, argv[1]),
|
||||
(int)js2number(js, argv[2]), (int)js2number(js, argv[3]),
|
||||
(int)js2number(js, argv[4]), (float)js2number(js, argv[5]),
|
||||
@@ -155,7 +155,7 @@ JSC_CCALL(gfx_drawEllipse,
|
||||
)
|
||||
|
||||
JSC_CCALL(gfx_fillEllipse,
|
||||
if (!pd_gfx) return JS_ThrowInternalError(js, "graphics not initialized");
|
||||
if (!pd_gfx) return JS_RaiseDisrupt(js, "graphics not initialized");
|
||||
pd_gfx->fillEllipse((int)js2number(js, argv[0]), (int)js2number(js, argv[1]),
|
||||
(int)js2number(js, argv[2]), (int)js2number(js, argv[3]),
|
||||
(float)js2number(js, argv[4]), (float)js2number(js, argv[5]),
|
||||
@@ -164,25 +164,25 @@ JSC_CCALL(gfx_fillEllipse,
|
||||
)
|
||||
|
||||
JSC_SCALL(gfx_drawText,
|
||||
if (!pd_gfx) return JS_ThrowInternalError(js, "graphics not initialized");
|
||||
if (!pd_gfx) return JS_RaiseDisrupt(js, "graphics not initialized");
|
||||
int w = pd_gfx->drawText(str, strlen(str), kUTF8Encoding,
|
||||
(int)js2number(js, argv[1]), (int)js2number(js, argv[2]));
|
||||
ret = JS_NewInt32(js, w);
|
||||
)
|
||||
|
||||
JSC_CCALL(gfx_drawScaledBitmap,
|
||||
if (!pd_gfx) return JS_ThrowInternalError(js, "graphics not initialized");
|
||||
if (!pd_gfx) return JS_RaiseDisrupt(js, "graphics not initialized");
|
||||
LCDBitmap *bmp = js2bitmap(js, argv[0]);
|
||||
if (!bmp) return JS_ThrowTypeError(js, "invalid bitmap");
|
||||
if (!bmp) return JS_RaiseDisrupt(js, "invalid bitmap");
|
||||
pd_gfx->drawScaledBitmap(bmp, (int)js2number(js, argv[1]), (int)js2number(js, argv[2]),
|
||||
(float)js2number(js, argv[3]), (float)js2number(js, argv[4]));
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(gfx_drawRotatedBitmap,
|
||||
if (!pd_gfx) return JS_ThrowInternalError(js, "graphics not initialized");
|
||||
if (!pd_gfx) return JS_RaiseDisrupt(js, "graphics not initialized");
|
||||
LCDBitmap *bmp = js2bitmap(js, argv[0]);
|
||||
if (!bmp) return JS_ThrowTypeError(js, "invalid bitmap");
|
||||
if (!bmp) return JS_RaiseDisrupt(js, "invalid bitmap");
|
||||
pd_gfx->drawRotatedBitmap(bmp, (int)js2number(js, argv[1]), (int)js2number(js, argv[2]),
|
||||
(float)js2number(js, argv[3]), (float)js2number(js, argv[4]),
|
||||
(float)js2number(js, argv[5]), (float)js2number(js, argv[6]),
|
||||
@@ -191,7 +191,7 @@ JSC_CCALL(gfx_drawRotatedBitmap,
|
||||
)
|
||||
|
||||
JSC_CCALL(gfx_setPixel,
|
||||
if (!pd_gfx) return JS_ThrowInternalError(js, "graphics not initialized");
|
||||
if (!pd_gfx) return JS_RaiseDisrupt(js, "graphics not initialized");
|
||||
pd_gfx->setPixel((int)js2number(js, argv[0]), (int)js2number(js, argv[1]),
|
||||
(LCDColor)js2number(js, argv[2]));
|
||||
return JS_NULL;
|
||||
@@ -200,48 +200,48 @@ JSC_CCALL(gfx_setPixel,
|
||||
// --- Bitmap Functions ---
|
||||
|
||||
JSC_CCALL(gfx_newBitmap,
|
||||
if (!pd_gfx) return JS_ThrowInternalError(js, "graphics not initialized");
|
||||
if (!pd_gfx) return JS_RaiseDisrupt(js, "graphics not initialized");
|
||||
LCDBitmap *bmp = pd_gfx->newBitmap((int)js2number(js, argv[0]), (int)js2number(js, argv[1]),
|
||||
argc > 2 ? (LCDColor)js2number(js, argv[2]) : kColorWhite);
|
||||
if (!bmp) return JS_ThrowInternalError(js, "failed to create bitmap");
|
||||
if (!bmp) return JS_RaiseDisrupt(js, "failed to create bitmap");
|
||||
return JS_NewInt64(js, (int64_t)(intptr_t)bmp);
|
||||
)
|
||||
|
||||
JSC_CCALL(gfx_freeBitmap,
|
||||
if (!pd_gfx) return JS_ThrowInternalError(js, "graphics not initialized");
|
||||
if (!pd_gfx) return JS_RaiseDisrupt(js, "graphics not initialized");
|
||||
LCDBitmap *bmp = js2bitmap(js, argv[0]);
|
||||
if (bmp) pd_gfx->freeBitmap(bmp);
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
JSC_SCALL(gfx_loadBitmap,
|
||||
if (!pd_gfx) return JS_ThrowInternalError(js, "graphics not initialized");
|
||||
if (!pd_gfx) return JS_RaiseDisrupt(js, "graphics not initialized");
|
||||
const char *err = NULL;
|
||||
LCDBitmap *bmp = pd_gfx->loadBitmap(str, &err);
|
||||
if (!bmp) ret = JS_ThrowInternalError(js, "loadBitmap: %s", err ? err : "unknown");
|
||||
if (!bmp) ret = JS_RaiseDisrupt(js, "loadBitmap: %s", err ? err : "unknown");
|
||||
else ret = JS_NewInt64(js, (int64_t)(intptr_t)bmp);
|
||||
)
|
||||
|
||||
JSC_CCALL(gfx_copyBitmap,
|
||||
if (!pd_gfx) return JS_ThrowInternalError(js, "graphics not initialized");
|
||||
if (!pd_gfx) return JS_RaiseDisrupt(js, "graphics not initialized");
|
||||
LCDBitmap *bmp = js2bitmap(js, argv[0]);
|
||||
if (!bmp) return JS_ThrowTypeError(js, "invalid bitmap");
|
||||
if (!bmp) return JS_RaiseDisrupt(js, "invalid bitmap");
|
||||
LCDBitmap *copy = pd_gfx->copyBitmap(bmp);
|
||||
return copy ? JS_NewInt64(js, (int64_t)(intptr_t)copy) : JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(gfx_clearBitmap,
|
||||
if (!pd_gfx) return JS_ThrowInternalError(js, "graphics not initialized");
|
||||
if (!pd_gfx) return JS_RaiseDisrupt(js, "graphics not initialized");
|
||||
LCDBitmap *bmp = js2bitmap(js, argv[0]);
|
||||
if (!bmp) return JS_ThrowTypeError(js, "invalid bitmap");
|
||||
if (!bmp) return JS_RaiseDisrupt(js, "invalid bitmap");
|
||||
pd_gfx->clearBitmap(bmp, argc > 1 ? (LCDColor)js2number(js, argv[1]) : kColorWhite);
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(gfx_getBitmapData,
|
||||
if (!pd_gfx) return JS_ThrowInternalError(js, "graphics not initialized");
|
||||
if (!pd_gfx) return JS_RaiseDisrupt(js, "graphics not initialized");
|
||||
LCDBitmap *bmp = js2bitmap(js, argv[0]);
|
||||
if (!bmp) return JS_ThrowTypeError(js, "invalid bitmap");
|
||||
if (!bmp) return JS_RaiseDisrupt(js, "invalid bitmap");
|
||||
int w, h, rb; uint8_t *mask, *data;
|
||||
pd_gfx->getBitmapData(bmp, &w, &h, &rb, &mask, &data);
|
||||
JSValue obj = JS_NewObject(js);
|
||||
@@ -254,21 +254,21 @@ JSC_CCALL(gfx_getBitmapData,
|
||||
// --- Font Functions ---
|
||||
|
||||
JSC_SCALL(gfx_loadFont,
|
||||
if (!pd_gfx) return JS_ThrowInternalError(js, "graphics not initialized");
|
||||
if (!pd_gfx) return JS_RaiseDisrupt(js, "graphics not initialized");
|
||||
const char *err = NULL;
|
||||
LCDFont *font = pd_gfx->loadFont(str, &err);
|
||||
if (!font) ret = JS_ThrowInternalError(js, "loadFont: %s", err ? err : "unknown");
|
||||
if (!font) ret = JS_RaiseDisrupt(js, "loadFont: %s", err ? err : "unknown");
|
||||
else ret = JS_NewInt64(js, (int64_t)(intptr_t)font);
|
||||
)
|
||||
|
||||
JSC_CCALL(gfx_getFontHeight,
|
||||
if (!pd_gfx) return JS_ThrowInternalError(js, "graphics not initialized");
|
||||
if (!pd_gfx) return JS_RaiseDisrupt(js, "graphics not initialized");
|
||||
LCDFont *font = js2font(js, argv[0]);
|
||||
return JS_NewInt32(js, pd_gfx->getFontHeight(font));
|
||||
)
|
||||
|
||||
JSC_SCALL(gfx_getTextWidth,
|
||||
if (!pd_gfx) return JS_ThrowInternalError(js, "graphics not initialized");
|
||||
if (!pd_gfx) return JS_RaiseDisrupt(js, "graphics not initialized");
|
||||
LCDFont *font = argc > 1 ? js2font(js, argv[1]) : NULL;
|
||||
int tracking = argc > 2 ? (int)js2number(js, argv[2]) : 0;
|
||||
ret = JS_NewInt32(js, pd_gfx->getTextWidth(font, str, strlen(str), kUTF8Encoding, tracking));
|
||||
@@ -277,19 +277,19 @@ JSC_SCALL(gfx_getTextWidth,
|
||||
// --- Framebuffer ---
|
||||
|
||||
JSC_CCALL(gfx_display,
|
||||
if (!pd_gfx) return JS_ThrowInternalError(js, "graphics not initialized");
|
||||
if (!pd_gfx) return JS_RaiseDisrupt(js, "graphics not initialized");
|
||||
pd_gfx->display();
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(gfx_markUpdatedRows,
|
||||
if (!pd_gfx) return JS_ThrowInternalError(js, "graphics not initialized");
|
||||
if (!pd_gfx) return JS_RaiseDisrupt(js, "graphics not initialized");
|
||||
pd_gfx->markUpdatedRows((int)js2number(js, argv[0]), (int)js2number(js, argv[1]));
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(gfx_copyFrameBufferBitmap,
|
||||
if (!pd_gfx) return JS_ThrowInternalError(js, "graphics not initialized");
|
||||
if (!pd_gfx) return JS_RaiseDisrupt(js, "graphics not initialized");
|
||||
LCDBitmap *bmp = pd_gfx->copyFrameBufferBitmap();
|
||||
return bmp ? JS_NewInt64(js, (int64_t)(intptr_t)bmp) : JS_NULL;
|
||||
)
|
||||
|
||||
@@ -16,7 +16,7 @@ typedef struct {
|
||||
|
||||
static void json_decode_error(json_decoder *decoder, const char *error, int linenum) {
|
||||
JsonDecodeCtx *ctx = (JsonDecodeCtx*)decoder->userdata;
|
||||
ctx->result = JS_ThrowSyntaxError(ctx->js, "JSON parse error at line %d: %s", linenum, error);
|
||||
ctx->result = JS_RaiseDisrupt(ctx->js, "JSON parse error at line %d: %s", linenum, error);
|
||||
}
|
||||
|
||||
static void json_decode_will_sublist(json_decoder *decoder, const char *name, json_value_type type) {
|
||||
@@ -162,7 +162,7 @@ static void encode_js_value(json_encoder *enc, JSContext *js, JSValue val) {
|
||||
// --- API Functions ---
|
||||
|
||||
JSC_SCALL(json_decodeString,
|
||||
if (!pd_json) return JS_ThrowInternalError(js, "json not initialized");
|
||||
if (!pd_json) return JS_RaiseDisrupt(js, "json not initialized");
|
||||
JsonDecodeCtx ctx = { js, JS_NULL, {}, 0 };
|
||||
json_decoder decoder = {0};
|
||||
decoder.decodeError = json_decode_error;
|
||||
@@ -177,9 +177,9 @@ JSC_SCALL(json_decodeString,
|
||||
)
|
||||
|
||||
JSC_CCALL(json_encode,
|
||||
if (!pd_json) return JS_ThrowInternalError(js, "json not initialized");
|
||||
if (!pd_json) return JS_RaiseDisrupt(js, "json not initialized");
|
||||
JsonEncodeCtx ctx = { malloc(256), 0, 256 };
|
||||
if (!ctx.buffer) return JS_ThrowInternalError(js, "malloc failed");
|
||||
if (!ctx.buffer) return JS_RaiseDisrupt(js, "malloc failed");
|
||||
ctx.buffer[0] = '\0';
|
||||
json_encoder enc;
|
||||
int pretty = argc > 1 ? JS_ToBool(js, argv[1]) : 0;
|
||||
|
||||
@@ -9,24 +9,24 @@
|
||||
// --- Lua API Functions ---
|
||||
|
||||
JSC_CCALL(lua_stop,
|
||||
if (!pd_lua) return JS_ThrowInternalError(js, "lua not initialized");
|
||||
if (!pd_lua) return JS_RaiseDisrupt(js, "lua not initialized");
|
||||
pd_lua->stop();
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(lua_start,
|
||||
if (!pd_lua) return JS_ThrowInternalError(js, "lua not initialized");
|
||||
if (!pd_lua) return JS_RaiseDisrupt(js, "lua not initialized");
|
||||
pd_lua->start();
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(lua_getArgCount,
|
||||
if (!pd_lua) return JS_ThrowInternalError(js, "lua not initialized");
|
||||
if (!pd_lua) return JS_RaiseDisrupt(js, "lua not initialized");
|
||||
return JS_NewInt32(js, pd_lua->getArgCount());
|
||||
)
|
||||
|
||||
JSC_CCALL(lua_getArgType,
|
||||
if (!pd_lua) return JS_ThrowInternalError(js, "lua not initialized");
|
||||
if (!pd_lua) return JS_RaiseDisrupt(js, "lua not initialized");
|
||||
int pos = (int)js2number(js, argv[0]);
|
||||
const char *outClass = NULL;
|
||||
enum LuaType type = pd_lua->getArgType(pos, &outClass);
|
||||
@@ -37,33 +37,33 @@ JSC_CCALL(lua_getArgType,
|
||||
)
|
||||
|
||||
JSC_CCALL(lua_argIsNil,
|
||||
if (!pd_lua) return JS_ThrowInternalError(js, "lua not initialized");
|
||||
if (!pd_lua) return JS_RaiseDisrupt(js, "lua not initialized");
|
||||
return JS_NewBool(js, pd_lua->argIsNil((int)js2number(js, argv[0])));
|
||||
)
|
||||
|
||||
JSC_CCALL(lua_getArgBool,
|
||||
if (!pd_lua) return JS_ThrowInternalError(js, "lua not initialized");
|
||||
if (!pd_lua) return JS_RaiseDisrupt(js, "lua not initialized");
|
||||
return JS_NewBool(js, pd_lua->getArgBool((int)js2number(js, argv[0])));
|
||||
)
|
||||
|
||||
JSC_CCALL(lua_getArgInt,
|
||||
if (!pd_lua) return JS_ThrowInternalError(js, "lua not initialized");
|
||||
if (!pd_lua) return JS_RaiseDisrupt(js, "lua not initialized");
|
||||
return JS_NewInt32(js, pd_lua->getArgInt((int)js2number(js, argv[0])));
|
||||
)
|
||||
|
||||
JSC_CCALL(lua_getArgFloat,
|
||||
if (!pd_lua) return JS_ThrowInternalError(js, "lua not initialized");
|
||||
if (!pd_lua) return JS_RaiseDisrupt(js, "lua not initialized");
|
||||
return JS_NewFloat64(js, pd_lua->getArgFloat((int)js2number(js, argv[0])));
|
||||
)
|
||||
|
||||
JSC_CCALL(lua_getArgString,
|
||||
if (!pd_lua) return JS_ThrowInternalError(js, "lua not initialized");
|
||||
if (!pd_lua) return JS_RaiseDisrupt(js, "lua not initialized");
|
||||
const char *str = pd_lua->getArgString((int)js2number(js, argv[0]));
|
||||
return str ? JS_NewString(js, str) : JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(lua_getArgBytes,
|
||||
if (!pd_lua) return JS_ThrowInternalError(js, "lua not initialized");
|
||||
if (!pd_lua) return JS_RaiseDisrupt(js, "lua not initialized");
|
||||
size_t len;
|
||||
const char *bytes = pd_lua->getArgBytes((int)js2number(js, argv[0]), &len);
|
||||
if (!bytes) return JS_NULL;
|
||||
@@ -71,36 +71,36 @@ JSC_CCALL(lua_getArgBytes,
|
||||
)
|
||||
|
||||
JSC_CCALL(lua_pushNil,
|
||||
if (!pd_lua) return JS_ThrowInternalError(js, "lua not initialized");
|
||||
if (!pd_lua) return JS_RaiseDisrupt(js, "lua not initialized");
|
||||
pd_lua->pushNil();
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(lua_pushBool,
|
||||
if (!pd_lua) return JS_ThrowInternalError(js, "lua not initialized");
|
||||
if (!pd_lua) return JS_RaiseDisrupt(js, "lua not initialized");
|
||||
pd_lua->pushBool(JS_ToBool(js, argv[0]));
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(lua_pushInt,
|
||||
if (!pd_lua) return JS_ThrowInternalError(js, "lua not initialized");
|
||||
if (!pd_lua) return JS_RaiseDisrupt(js, "lua not initialized");
|
||||
pd_lua->pushInt((int)js2number(js, argv[0]));
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(lua_pushFloat,
|
||||
if (!pd_lua) return JS_ThrowInternalError(js, "lua not initialized");
|
||||
if (!pd_lua) return JS_RaiseDisrupt(js, "lua not initialized");
|
||||
pd_lua->pushFloat((float)js2number(js, argv[0]));
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
JSC_SCALL(lua_pushString,
|
||||
if (!pd_lua) return JS_ThrowInternalError(js, "lua not initialized");
|
||||
if (!pd_lua) return JS_RaiseDisrupt(js, "lua not initialized");
|
||||
pd_lua->pushString(str);
|
||||
)
|
||||
|
||||
JSC_CCALL(lua_pushBytes,
|
||||
if (!pd_lua) return JS_ThrowInternalError(js, "lua not initialized");
|
||||
if (!pd_lua) return JS_RaiseDisrupt(js, "lua not initialized");
|
||||
size_t len;
|
||||
const char *data = js_get_blob_data(js, &len, argv[0]);
|
||||
if (data == (void*)-1) return JS_EXCEPTION;
|
||||
@@ -109,12 +109,12 @@ JSC_CCALL(lua_pushBytes,
|
||||
)
|
||||
|
||||
JSC_SCALL(lua_callFunction,
|
||||
if (!pd_lua) return JS_ThrowInternalError(js, "lua not initialized");
|
||||
if (!pd_lua) return JS_RaiseDisrupt(js, "lua not initialized");
|
||||
int nargs = argc > 1 ? (int)js2number(js, argv[1]) : 0;
|
||||
const char *outerr = NULL;
|
||||
int result = pd_lua->callFunction(str, nargs, &outerr);
|
||||
if (result == 0 && outerr) {
|
||||
ret = JS_ThrowInternalError(js, "Lua error: %s", outerr);
|
||||
ret = JS_RaiseDisrupt(js, "Lua error: %s", outerr);
|
||||
} else {
|
||||
ret = JS_NewBool(js, result);
|
||||
}
|
||||
|
||||
@@ -22,12 +22,12 @@ static TCPConnection* js2tcp(JSContext *js, JSValueConst val) {
|
||||
// --- Network Status ---
|
||||
|
||||
JSC_CCALL(network_getStatus,
|
||||
if (!pd_network) return JS_ThrowInternalError(js, "network not initialized");
|
||||
if (!pd_network) return JS_RaiseDisrupt(js, "network not initialized");
|
||||
return JS_NewInt32(js, pd_network->getStatus());
|
||||
)
|
||||
|
||||
JSC_CCALL(network_setEnabled,
|
||||
if (!pd_network) return JS_ThrowInternalError(js, "network not initialized");
|
||||
if (!pd_network) return JS_RaiseDisrupt(js, "network not initialized");
|
||||
// Note: callback not implemented for simplicity
|
||||
pd_network->setEnabled(JS_ToBool(js, argv[0]), NULL);
|
||||
return JS_NULL;
|
||||
@@ -36,7 +36,7 @@ JSC_CCALL(network_setEnabled,
|
||||
// --- HTTP Functions ---
|
||||
|
||||
JSC_SCALL(http_newConnection,
|
||||
if (!pd_network || !pd_network->http) return JS_ThrowInternalError(js, "network not initialized");
|
||||
if (!pd_network || !pd_network->http) return JS_RaiseDisrupt(js, "network not initialized");
|
||||
int port = (int)js2number(js, argv[1]);
|
||||
int usessl = argc > 2 ? JS_ToBool(js, argv[2]) : 0;
|
||||
HTTPConnection *conn = pd_network->http->newConnection(str, port, usessl);
|
||||
@@ -44,39 +44,39 @@ JSC_SCALL(http_newConnection,
|
||||
)
|
||||
|
||||
JSC_CCALL(http_retain,
|
||||
if (!pd_network || !pd_network->http) return JS_ThrowInternalError(js, "network not initialized");
|
||||
if (!pd_network || !pd_network->http) return JS_RaiseDisrupt(js, "network not initialized");
|
||||
HTTPConnection *conn = js2http(js, argv[0]);
|
||||
HTTPConnection *ret_conn = pd_network->http->retain(conn);
|
||||
return ret_conn ? JS_NewInt64(js, (int64_t)(intptr_t)ret_conn) : JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(http_release,
|
||||
if (!pd_network || !pd_network->http) return JS_ThrowInternalError(js, "network not initialized");
|
||||
if (!pd_network || !pd_network->http) return JS_RaiseDisrupt(js, "network not initialized");
|
||||
HTTPConnection *conn = js2http(js, argv[0]);
|
||||
if (conn) pd_network->http->release(conn);
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(http_setConnectTimeout,
|
||||
if (!pd_network || !pd_network->http) return JS_ThrowInternalError(js, "network not initialized");
|
||||
if (!pd_network || !pd_network->http) return JS_RaiseDisrupt(js, "network not initialized");
|
||||
pd_network->http->setConnectTimeout(js2http(js, argv[0]), (int)js2number(js, argv[1]));
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(http_setKeepAlive,
|
||||
if (!pd_network || !pd_network->http) return JS_ThrowInternalError(js, "network not initialized");
|
||||
if (!pd_network || !pd_network->http) return JS_RaiseDisrupt(js, "network not initialized");
|
||||
pd_network->http->setKeepAlive(js2http(js, argv[0]), JS_ToBool(js, argv[1]));
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(http_setByteRange,
|
||||
if (!pd_network || !pd_network->http) return JS_ThrowInternalError(js, "network not initialized");
|
||||
if (!pd_network || !pd_network->http) return JS_RaiseDisrupt(js, "network not initialized");
|
||||
pd_network->http->setByteRange(js2http(js, argv[0]), (int)js2number(js, argv[1]), (int)js2number(js, argv[2]));
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
JSC_SCALL(http_get,
|
||||
if (!pd_network || !pd_network->http) return JS_ThrowInternalError(js, "network not initialized");
|
||||
if (!pd_network || !pd_network->http) return JS_RaiseDisrupt(js, "network not initialized");
|
||||
HTTPConnection *conn = js2http(js, argv[0]);
|
||||
const char *headers = argc > 2 ? JS_ToCString(js, argv[2]) : NULL;
|
||||
size_t hlen = headers ? strlen(headers) : 0;
|
||||
@@ -86,7 +86,7 @@ JSC_SCALL(http_get,
|
||||
)
|
||||
|
||||
JSC_SCALL(http_post,
|
||||
if (!pd_network || !pd_network->http) return JS_ThrowInternalError(js, "network not initialized");
|
||||
if (!pd_network || !pd_network->http) return JS_RaiseDisrupt(js, "network not initialized");
|
||||
HTTPConnection *conn = js2http(js, argv[0]);
|
||||
const char *headers = argc > 2 ? JS_ToCString(js, argv[2]) : NULL;
|
||||
size_t hlen = headers ? strlen(headers) : 0;
|
||||
@@ -99,12 +99,12 @@ JSC_SCALL(http_post,
|
||||
)
|
||||
|
||||
JSC_CCALL(http_getError,
|
||||
if (!pd_network || !pd_network->http) return JS_ThrowInternalError(js, "network not initialized");
|
||||
if (!pd_network || !pd_network->http) return JS_RaiseDisrupt(js, "network not initialized");
|
||||
return JS_NewInt32(js, pd_network->http->getError(js2http(js, argv[0])));
|
||||
)
|
||||
|
||||
JSC_CCALL(http_getProgress,
|
||||
if (!pd_network || !pd_network->http) return JS_ThrowInternalError(js, "network not initialized");
|
||||
if (!pd_network || !pd_network->http) return JS_RaiseDisrupt(js, "network not initialized");
|
||||
int read, total;
|
||||
pd_network->http->getProgress(js2http(js, argv[0]), &read, &total);
|
||||
JSValue obj = JS_NewObject(js);
|
||||
@@ -114,33 +114,33 @@ JSC_CCALL(http_getProgress,
|
||||
)
|
||||
|
||||
JSC_CCALL(http_getResponseStatus,
|
||||
if (!pd_network || !pd_network->http) return JS_ThrowInternalError(js, "network not initialized");
|
||||
if (!pd_network || !pd_network->http) return JS_RaiseDisrupt(js, "network not initialized");
|
||||
return JS_NewInt32(js, pd_network->http->getResponseStatus(js2http(js, argv[0])));
|
||||
)
|
||||
|
||||
JSC_CCALL(http_getBytesAvailable,
|
||||
if (!pd_network || !pd_network->http) return JS_ThrowInternalError(js, "network not initialized");
|
||||
if (!pd_network || !pd_network->http) return JS_RaiseDisrupt(js, "network not initialized");
|
||||
return JS_NewInt64(js, pd_network->http->getBytesAvailable(js2http(js, argv[0])));
|
||||
)
|
||||
|
||||
JSC_CCALL(http_setReadTimeout,
|
||||
if (!pd_network || !pd_network->http) return JS_ThrowInternalError(js, "network not initialized");
|
||||
if (!pd_network || !pd_network->http) return JS_RaiseDisrupt(js, "network not initialized");
|
||||
pd_network->http->setReadTimeout(js2http(js, argv[0]), (int)js2number(js, argv[1]));
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(http_setReadBufferSize,
|
||||
if (!pd_network || !pd_network->http) return JS_ThrowInternalError(js, "network not initialized");
|
||||
if (!pd_network || !pd_network->http) return JS_RaiseDisrupt(js, "network not initialized");
|
||||
pd_network->http->setReadBufferSize(js2http(js, argv[0]), (int)js2number(js, argv[1]));
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(http_read,
|
||||
if (!pd_network || !pd_network->http) return JS_ThrowInternalError(js, "network not initialized");
|
||||
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_ThrowInternalError(js, "malloc failed");
|
||||
if (!buf) return JS_RaiseDisrupt(js, "malloc failed");
|
||||
int read = pd_network->http->read(conn, buf, buflen);
|
||||
if (read < 0) {
|
||||
free(buf);
|
||||
@@ -152,7 +152,7 @@ JSC_CCALL(http_read,
|
||||
)
|
||||
|
||||
JSC_CCALL(http_close,
|
||||
if (!pd_network || !pd_network->http) return JS_ThrowInternalError(js, "network not initialized");
|
||||
if (!pd_network || !pd_network->http) return JS_RaiseDisrupt(js, "network not initialized");
|
||||
pd_network->http->close(js2http(js, argv[0]));
|
||||
return JS_NULL;
|
||||
)
|
||||
@@ -160,7 +160,7 @@ JSC_CCALL(http_close,
|
||||
// --- TCP Functions ---
|
||||
|
||||
JSC_SCALL(tcp_newConnection,
|
||||
if (!pd_network || !pd_network->tcp) return JS_ThrowInternalError(js, "network not initialized");
|
||||
if (!pd_network || !pd_network->tcp) return JS_RaiseDisrupt(js, "network not initialized");
|
||||
int port = (int)js2number(js, argv[1]);
|
||||
int usessl = argc > 2 ? JS_ToBool(js, argv[2]) : 0;
|
||||
TCPConnection *conn = pd_network->tcp->newConnection(str, port, usessl);
|
||||
@@ -168,58 +168,58 @@ JSC_SCALL(tcp_newConnection,
|
||||
)
|
||||
|
||||
JSC_CCALL(tcp_retain,
|
||||
if (!pd_network || !pd_network->tcp) return JS_ThrowInternalError(js, "network not initialized");
|
||||
if (!pd_network || !pd_network->tcp) return JS_RaiseDisrupt(js, "network not initialized");
|
||||
TCPConnection *conn = js2tcp(js, argv[0]);
|
||||
TCPConnection *ret_conn = pd_network->tcp->retain(conn);
|
||||
return ret_conn ? JS_NewInt64(js, (int64_t)(intptr_t)ret_conn) : JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(tcp_release,
|
||||
if (!pd_network || !pd_network->tcp) return JS_ThrowInternalError(js, "network not initialized");
|
||||
if (!pd_network || !pd_network->tcp) return JS_RaiseDisrupt(js, "network not initialized");
|
||||
TCPConnection *conn = js2tcp(js, argv[0]);
|
||||
if (conn) pd_network->tcp->release(conn);
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(tcp_getError,
|
||||
if (!pd_network || !pd_network->tcp) return JS_ThrowInternalError(js, "network not initialized");
|
||||
if (!pd_network || !pd_network->tcp) return JS_RaiseDisrupt(js, "network not initialized");
|
||||
return JS_NewInt32(js, pd_network->tcp->getError(js2tcp(js, argv[0])));
|
||||
)
|
||||
|
||||
JSC_CCALL(tcp_setConnectTimeout,
|
||||
if (!pd_network || !pd_network->tcp) return JS_ThrowInternalError(js, "network not initialized");
|
||||
if (!pd_network || !pd_network->tcp) return JS_RaiseDisrupt(js, "network not initialized");
|
||||
pd_network->tcp->setConnectTimeout(js2tcp(js, argv[0]), (int)js2number(js, argv[1]));
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(tcp_close,
|
||||
if (!pd_network || !pd_network->tcp) return JS_ThrowInternalError(js, "network not initialized");
|
||||
if (!pd_network || !pd_network->tcp) return JS_RaiseDisrupt(js, "network not initialized");
|
||||
return JS_NewInt32(js, pd_network->tcp->close(js2tcp(js, argv[0])));
|
||||
)
|
||||
|
||||
JSC_CCALL(tcp_setReadTimeout,
|
||||
if (!pd_network || !pd_network->tcp) return JS_ThrowInternalError(js, "network not initialized");
|
||||
if (!pd_network || !pd_network->tcp) return JS_RaiseDisrupt(js, "network not initialized");
|
||||
pd_network->tcp->setReadTimeout(js2tcp(js, argv[0]), (int)js2number(js, argv[1]));
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(tcp_setReadBufferSize,
|
||||
if (!pd_network || !pd_network->tcp) return JS_ThrowInternalError(js, "network not initialized");
|
||||
if (!pd_network || !pd_network->tcp) return JS_RaiseDisrupt(js, "network not initialized");
|
||||
pd_network->tcp->setReadBufferSize(js2tcp(js, argv[0]), (int)js2number(js, argv[1]));
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(tcp_getBytesAvailable,
|
||||
if (!pd_network || !pd_network->tcp) return JS_ThrowInternalError(js, "network not initialized");
|
||||
if (!pd_network || !pd_network->tcp) return JS_RaiseDisrupt(js, "network not initialized");
|
||||
return JS_NewInt64(js, pd_network->tcp->getBytesAvailable(js2tcp(js, argv[0])));
|
||||
)
|
||||
|
||||
JSC_CCALL(tcp_read,
|
||||
if (!pd_network || !pd_network->tcp) return JS_ThrowInternalError(js, "network not initialized");
|
||||
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_ThrowInternalError(js, "malloc failed");
|
||||
if (!buf) return JS_RaiseDisrupt(js, "malloc failed");
|
||||
int read = pd_network->tcp->read(conn, buf, len);
|
||||
if (read < 0) {
|
||||
free(buf);
|
||||
@@ -231,7 +231,7 @@ JSC_CCALL(tcp_read,
|
||||
)
|
||||
|
||||
JSC_CCALL(tcp_write,
|
||||
if (!pd_network || !pd_network->tcp) return JS_ThrowInternalError(js, "network not initialized");
|
||||
if (!pd_network || !pd_network->tcp) return JS_RaiseDisrupt(js, "network not initialized");
|
||||
TCPConnection *conn = js2tcp(js, argv[0]);
|
||||
size_t len;
|
||||
const void *data = js_get_blob_data(js, &len, argv[1]);
|
||||
|
||||
@@ -100,7 +100,7 @@ static void scores_cb(PDScoresList *scores, const char *errorMessage) {
|
||||
// --- API Functions ---
|
||||
|
||||
JSC_SCALL(scoreboards_addScore,
|
||||
if (!pd_scoreboards) return JS_ThrowInternalError(js, "scoreboards not initialized");
|
||||
if (!pd_scoreboards) return JS_RaiseDisrupt(js, "scoreboards not initialized");
|
||||
uint32_t value = (uint32_t)js2number(js, argv[1]);
|
||||
if (argc > 2 && JS_IsFunction(argv[2])) {
|
||||
g_scoreboard_js = js;
|
||||
@@ -111,7 +111,7 @@ JSC_SCALL(scoreboards_addScore,
|
||||
)
|
||||
|
||||
JSC_SCALL(scoreboards_getPersonalBest,
|
||||
if (!pd_scoreboards) return JS_ThrowInternalError(js, "scoreboards not initialized");
|
||||
if (!pd_scoreboards) return JS_RaiseDisrupt(js, "scoreboards not initialized");
|
||||
if (argc > 1 && JS_IsFunction(argv[1])) {
|
||||
g_scoreboard_js = js;
|
||||
JS_FreeValue(js, g_personal_best_callback);
|
||||
@@ -121,14 +121,14 @@ JSC_SCALL(scoreboards_getPersonalBest,
|
||||
)
|
||||
|
||||
JSC_CCALL(scoreboards_freeScore,
|
||||
if (!pd_scoreboards) return JS_ThrowInternalError(js, "scoreboards not initialized");
|
||||
if (!pd_scoreboards) return JS_RaiseDisrupt(js, "scoreboards not initialized");
|
||||
// Note: PDScore from callbacks is managed by Playdate, this is for user-allocated scores
|
||||
// In practice, JS doesn't allocate PDScore directly, so this is a no-op wrapper
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(scoreboards_getScoreboards,
|
||||
if (!pd_scoreboards) return JS_ThrowInternalError(js, "scoreboards not initialized");
|
||||
if (!pd_scoreboards) return JS_RaiseDisrupt(js, "scoreboards not initialized");
|
||||
if (argc > 0 && JS_IsFunction(argv[0])) {
|
||||
g_scoreboard_js = js;
|
||||
JS_FreeValue(js, g_boards_list_callback);
|
||||
@@ -138,13 +138,13 @@ JSC_CCALL(scoreboards_getScoreboards,
|
||||
)
|
||||
|
||||
JSC_CCALL(scoreboards_freeBoardsList,
|
||||
if (!pd_scoreboards) return JS_ThrowInternalError(js, "scoreboards not initialized");
|
||||
if (!pd_scoreboards) return JS_RaiseDisrupt(js, "scoreboards not initialized");
|
||||
// Managed by Playdate after callback
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
JSC_SCALL(scoreboards_getScores,
|
||||
if (!pd_scoreboards) return JS_ThrowInternalError(js, "scoreboards not initialized");
|
||||
if (!pd_scoreboards) return JS_RaiseDisrupt(js, "scoreboards not initialized");
|
||||
if (argc > 1 && JS_IsFunction(argv[1])) {
|
||||
g_scoreboard_js = js;
|
||||
JS_FreeValue(js, g_scores_callback);
|
||||
@@ -154,7 +154,7 @@ JSC_SCALL(scoreboards_getScores,
|
||||
)
|
||||
|
||||
JSC_CCALL(scoreboards_freeScoresList,
|
||||
if (!pd_scoreboards) return JS_ThrowInternalError(js, "scoreboards not initialized");
|
||||
if (!pd_scoreboards) return JS_RaiseDisrupt(js, "scoreboards not initialized");
|
||||
// Managed by Playdate after callback
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
@@ -28,77 +28,77 @@ static SoundChannel* js2channel(JSContext *js, JSValueConst val) {
|
||||
|
||||
// --- Global ---
|
||||
JSC_CCALL(sound_getCurrentTime,
|
||||
if (!pd_sound) return JS_ThrowInternalError(js, "sound not initialized");
|
||||
if (!pd_sound) return JS_RaiseDisrupt(js, "sound not initialized");
|
||||
return JS_NewInt64(js, pd_sound->getCurrentTime());
|
||||
)
|
||||
JSC_CCALL(sound_getDefaultChannel,
|
||||
if (!pd_sound) return JS_ThrowInternalError(js, "sound not initialized");
|
||||
if (!pd_sound) return JS_RaiseDisrupt(js, "sound not initialized");
|
||||
SoundChannel *ch = pd_sound->getDefaultChannel();
|
||||
return ch ? JS_NewInt64(js, (int64_t)(intptr_t)ch) : JS_NULL;
|
||||
)
|
||||
JSC_CCALL(sound_addChannel,
|
||||
if (!pd_sound) return JS_ThrowInternalError(js, "sound not initialized");
|
||||
if (!pd_sound) return JS_RaiseDisrupt(js, "sound not initialized");
|
||||
return JS_NewBool(js, pd_sound->addChannel(js2channel(js, argv[0])));
|
||||
)
|
||||
JSC_CCALL(sound_removeChannel,
|
||||
if (!pd_sound) return JS_ThrowInternalError(js, "sound not initialized");
|
||||
if (!pd_sound) return JS_RaiseDisrupt(js, "sound not initialized");
|
||||
return JS_NewBool(js, pd_sound->removeChannel(js2channel(js, argv[0])));
|
||||
)
|
||||
JSC_CCALL(sound_setOutputsActive,
|
||||
if (!pd_sound) return JS_ThrowInternalError(js, "sound not initialized");
|
||||
if (!pd_sound) return JS_RaiseDisrupt(js, "sound not initialized");
|
||||
pd_sound->setOutputsActive(JS_ToBool(js, argv[0]), JS_ToBool(js, argv[1]));
|
||||
return JS_NULL;
|
||||
)
|
||||
JSC_CCALL(sound_getError,
|
||||
if (!pd_sound) return JS_ThrowInternalError(js, "sound not initialized");
|
||||
if (!pd_sound) return JS_RaiseDisrupt(js, "sound not initialized");
|
||||
const char *err = pd_sound->getError();
|
||||
return err ? JS_NewString(js, err) : JS_NULL;
|
||||
)
|
||||
|
||||
// --- FilePlayer ---
|
||||
JSC_CCALL(sound_newFilePlayer,
|
||||
if (!pd_sound) return JS_ThrowInternalError(js, "sound not initialized");
|
||||
if (!pd_sound) return JS_RaiseDisrupt(js, "sound not initialized");
|
||||
FilePlayer *p = pd_sound->fileplayer->newPlayer();
|
||||
return p ? JS_NewInt64(js, (int64_t)(intptr_t)p) : JS_NULL;
|
||||
)
|
||||
JSC_CCALL(sound_freeFilePlayer,
|
||||
if (!pd_sound) return JS_ThrowInternalError(js, "sound not initialized");
|
||||
if (!pd_sound) return JS_RaiseDisrupt(js, "sound not initialized");
|
||||
FilePlayer *p = js2fileplayer(js, argv[0]);
|
||||
if (p) pd_sound->fileplayer->freePlayer(p);
|
||||
return JS_NULL;
|
||||
)
|
||||
JSC_SCALL(sound_loadIntoFilePlayer,
|
||||
if (!pd_sound) return JS_ThrowInternalError(js, "sound not initialized");
|
||||
if (!pd_sound) return JS_RaiseDisrupt(js, "sound not initialized");
|
||||
FilePlayer *p = js2fileplayer(js, argv[0]);
|
||||
ret = JS_NewBool(js, pd_sound->fileplayer->loadIntoPlayer(p, str));
|
||||
)
|
||||
JSC_CCALL(sound_filePlayerPlay,
|
||||
if (!pd_sound) return JS_ThrowInternalError(js, "sound not initialized");
|
||||
if (!pd_sound) return JS_RaiseDisrupt(js, "sound not initialized");
|
||||
FilePlayer *p = js2fileplayer(js, argv[0]);
|
||||
int repeat = argc > 1 ? (int)js2number(js, argv[1]) : 1;
|
||||
return JS_NewBool(js, pd_sound->fileplayer->play(p, repeat));
|
||||
)
|
||||
JSC_CCALL(sound_filePlayerIsPlaying,
|
||||
if (!pd_sound) return JS_ThrowInternalError(js, "sound not initialized");
|
||||
if (!pd_sound) return JS_RaiseDisrupt(js, "sound not initialized");
|
||||
return JS_NewBool(js, pd_sound->fileplayer->isPlaying(js2fileplayer(js, argv[0])));
|
||||
)
|
||||
JSC_CCALL(sound_filePlayerPause,
|
||||
if (!pd_sound) return JS_ThrowInternalError(js, "sound not initialized");
|
||||
if (!pd_sound) return JS_RaiseDisrupt(js, "sound not initialized");
|
||||
pd_sound->fileplayer->pause(js2fileplayer(js, argv[0]));
|
||||
return JS_NULL;
|
||||
)
|
||||
JSC_CCALL(sound_filePlayerStop,
|
||||
if (!pd_sound) return JS_ThrowInternalError(js, "sound not initialized");
|
||||
if (!pd_sound) return JS_RaiseDisrupt(js, "sound not initialized");
|
||||
pd_sound->fileplayer->stop(js2fileplayer(js, argv[0]));
|
||||
return JS_NULL;
|
||||
)
|
||||
JSC_CCALL(sound_filePlayerSetVolume,
|
||||
if (!pd_sound) return JS_ThrowInternalError(js, "sound not initialized");
|
||||
if (!pd_sound) return JS_RaiseDisrupt(js, "sound not initialized");
|
||||
pd_sound->fileplayer->setVolume(js2fileplayer(js, argv[0]), (float)js2number(js, argv[1]), (float)js2number(js, argv[2]));
|
||||
return JS_NULL;
|
||||
)
|
||||
JSC_CCALL(sound_filePlayerGetVolume,
|
||||
if (!pd_sound) return JS_ThrowInternalError(js, "sound not initialized");
|
||||
if (!pd_sound) return JS_RaiseDisrupt(js, "sound not initialized");
|
||||
float l, r; pd_sound->fileplayer->getVolume(js2fileplayer(js, argv[0]), &l, &r);
|
||||
JSValue obj = JS_NewObject(js);
|
||||
JS_SetPropertyStr(js, obj, "left", JS_NewFloat64(js, l));
|
||||
@@ -106,109 +106,109 @@ JSC_CCALL(sound_filePlayerGetVolume,
|
||||
return obj;
|
||||
)
|
||||
JSC_CCALL(sound_filePlayerGetLength,
|
||||
if (!pd_sound) return JS_ThrowInternalError(js, "sound not initialized");
|
||||
if (!pd_sound) return JS_RaiseDisrupt(js, "sound not initialized");
|
||||
return JS_NewFloat64(js, pd_sound->fileplayer->getLength(js2fileplayer(js, argv[0])));
|
||||
)
|
||||
JSC_CCALL(sound_filePlayerSetOffset,
|
||||
if (!pd_sound) return JS_ThrowInternalError(js, "sound not initialized");
|
||||
if (!pd_sound) return JS_RaiseDisrupt(js, "sound not initialized");
|
||||
pd_sound->fileplayer->setOffset(js2fileplayer(js, argv[0]), (float)js2number(js, argv[1]));
|
||||
return JS_NULL;
|
||||
)
|
||||
JSC_CCALL(sound_filePlayerGetOffset,
|
||||
if (!pd_sound) return JS_ThrowInternalError(js, "sound not initialized");
|
||||
if (!pd_sound) return JS_RaiseDisrupt(js, "sound not initialized");
|
||||
return JS_NewFloat64(js, pd_sound->fileplayer->getOffset(js2fileplayer(js, argv[0])));
|
||||
)
|
||||
JSC_CCALL(sound_filePlayerSetRate,
|
||||
if (!pd_sound) return JS_ThrowInternalError(js, "sound not initialized");
|
||||
if (!pd_sound) return JS_RaiseDisrupt(js, "sound not initialized");
|
||||
pd_sound->fileplayer->setRate(js2fileplayer(js, argv[0]), (float)js2number(js, argv[1]));
|
||||
return JS_NULL;
|
||||
)
|
||||
JSC_CCALL(sound_filePlayerGetRate,
|
||||
if (!pd_sound) return JS_ThrowInternalError(js, "sound not initialized");
|
||||
if (!pd_sound) return JS_RaiseDisrupt(js, "sound not initialized");
|
||||
return JS_NewFloat64(js, pd_sound->fileplayer->getRate(js2fileplayer(js, argv[0])));
|
||||
)
|
||||
JSC_CCALL(sound_filePlayerSetLoopRange,
|
||||
if (!pd_sound) return JS_ThrowInternalError(js, "sound not initialized");
|
||||
if (!pd_sound) return JS_RaiseDisrupt(js, "sound not initialized");
|
||||
pd_sound->fileplayer->setLoopRange(js2fileplayer(js, argv[0]), (float)js2number(js, argv[1]), (float)js2number(js, argv[2]));
|
||||
return JS_NULL;
|
||||
)
|
||||
JSC_CCALL(sound_filePlayerDidUnderrun,
|
||||
if (!pd_sound) return JS_ThrowInternalError(js, "sound not initialized");
|
||||
if (!pd_sound) return JS_RaiseDisrupt(js, "sound not initialized");
|
||||
return JS_NewBool(js, pd_sound->fileplayer->didUnderrun(js2fileplayer(js, argv[0])));
|
||||
)
|
||||
JSC_CCALL(sound_filePlayerSetStopOnUnderrun,
|
||||
if (!pd_sound) return JS_ThrowInternalError(js, "sound not initialized");
|
||||
if (!pd_sound) return JS_RaiseDisrupt(js, "sound not initialized");
|
||||
pd_sound->fileplayer->setStopOnUnderrun(js2fileplayer(js, argv[0]), JS_ToBool(js, argv[1]));
|
||||
return JS_NULL;
|
||||
)
|
||||
JSC_CCALL(sound_filePlayerSetBufferLength,
|
||||
if (!pd_sound) return JS_ThrowInternalError(js, "sound not initialized");
|
||||
if (!pd_sound) return JS_RaiseDisrupt(js, "sound not initialized");
|
||||
pd_sound->fileplayer->setBufferLength(js2fileplayer(js, argv[0]), (float)js2number(js, argv[1]));
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
// --- Sample ---
|
||||
JSC_SCALL(sound_loadSample,
|
||||
if (!pd_sound) return JS_ThrowInternalError(js, "sound not initialized");
|
||||
if (!pd_sound) return JS_RaiseDisrupt(js, "sound not initialized");
|
||||
AudioSample *s = pd_sound->sample->load(str);
|
||||
ret = s ? JS_NewInt64(js, (int64_t)(intptr_t)s) : JS_NULL;
|
||||
)
|
||||
JSC_CCALL(sound_freeSample,
|
||||
if (!pd_sound) return JS_ThrowInternalError(js, "sound not initialized");
|
||||
if (!pd_sound) return JS_RaiseDisrupt(js, "sound not initialized");
|
||||
AudioSample *s = js2sample(js, argv[0]);
|
||||
if (s) pd_sound->sample->freeSample(s);
|
||||
return JS_NULL;
|
||||
)
|
||||
JSC_CCALL(sound_getSampleLength,
|
||||
if (!pd_sound) return JS_ThrowInternalError(js, "sound not initialized");
|
||||
if (!pd_sound) return JS_RaiseDisrupt(js, "sound not initialized");
|
||||
return JS_NewFloat64(js, pd_sound->sample->getLength(js2sample(js, argv[0])));
|
||||
)
|
||||
JSC_CCALL(sound_newSampleBuffer,
|
||||
if (!pd_sound) return JS_ThrowInternalError(js, "sound not initialized");
|
||||
if (!pd_sound) return JS_RaiseDisrupt(js, "sound not initialized");
|
||||
AudioSample *s = pd_sound->sample->newSampleBuffer((int)js2number(js, argv[0]));
|
||||
return s ? JS_NewInt64(js, (int64_t)(intptr_t)s) : JS_NULL;
|
||||
)
|
||||
|
||||
// --- SamplePlayer ---
|
||||
JSC_CCALL(sound_newSamplePlayer,
|
||||
if (!pd_sound) return JS_ThrowInternalError(js, "sound not initialized");
|
||||
if (!pd_sound) return JS_RaiseDisrupt(js, "sound not initialized");
|
||||
SamplePlayer *p = pd_sound->sampleplayer->newPlayer();
|
||||
return p ? JS_NewInt64(js, (int64_t)(intptr_t)p) : JS_NULL;
|
||||
)
|
||||
JSC_CCALL(sound_freeSamplePlayer,
|
||||
if (!pd_sound) return JS_ThrowInternalError(js, "sound not initialized");
|
||||
if (!pd_sound) return JS_RaiseDisrupt(js, "sound not initialized");
|
||||
SamplePlayer *p = js2sampleplayer(js, argv[0]);
|
||||
if (p) pd_sound->sampleplayer->freePlayer(p);
|
||||
return JS_NULL;
|
||||
)
|
||||
JSC_CCALL(sound_samplePlayerSetSample,
|
||||
if (!pd_sound) return JS_ThrowInternalError(js, "sound not initialized");
|
||||
if (!pd_sound) return JS_RaiseDisrupt(js, "sound not initialized");
|
||||
pd_sound->sampleplayer->setSample(js2sampleplayer(js, argv[0]), js2sample(js, argv[1]));
|
||||
return JS_NULL;
|
||||
)
|
||||
JSC_CCALL(sound_samplePlayerPlay,
|
||||
if (!pd_sound) return JS_ThrowInternalError(js, "sound not initialized");
|
||||
if (!pd_sound) return JS_RaiseDisrupt(js, "sound not initialized");
|
||||
SamplePlayer *p = js2sampleplayer(js, argv[0]);
|
||||
int repeat = argc > 1 ? (int)js2number(js, argv[1]) : 1;
|
||||
float rate = argc > 2 ? (float)js2number(js, argv[2]) : 1.0f;
|
||||
return JS_NewBool(js, pd_sound->sampleplayer->play(p, repeat, rate));
|
||||
)
|
||||
JSC_CCALL(sound_samplePlayerIsPlaying,
|
||||
if (!pd_sound) return JS_ThrowInternalError(js, "sound not initialized");
|
||||
if (!pd_sound) return JS_RaiseDisrupt(js, "sound not initialized");
|
||||
return JS_NewBool(js, pd_sound->sampleplayer->isPlaying(js2sampleplayer(js, argv[0])));
|
||||
)
|
||||
JSC_CCALL(sound_samplePlayerStop,
|
||||
if (!pd_sound) return JS_ThrowInternalError(js, "sound not initialized");
|
||||
if (!pd_sound) return JS_RaiseDisrupt(js, "sound not initialized");
|
||||
pd_sound->sampleplayer->stop(js2sampleplayer(js, argv[0]));
|
||||
return JS_NULL;
|
||||
)
|
||||
JSC_CCALL(sound_samplePlayerSetVolume,
|
||||
if (!pd_sound) return JS_ThrowInternalError(js, "sound not initialized");
|
||||
if (!pd_sound) return JS_RaiseDisrupt(js, "sound not initialized");
|
||||
pd_sound->sampleplayer->setVolume(js2sampleplayer(js, argv[0]), (float)js2number(js, argv[1]), (float)js2number(js, argv[2]));
|
||||
return JS_NULL;
|
||||
)
|
||||
JSC_CCALL(sound_samplePlayerGetVolume,
|
||||
if (!pd_sound) return JS_ThrowInternalError(js, "sound not initialized");
|
||||
if (!pd_sound) return JS_RaiseDisrupt(js, "sound not initialized");
|
||||
float l, r; pd_sound->sampleplayer->getVolume(js2sampleplayer(js, argv[0]), &l, &r);
|
||||
JSValue obj = JS_NewObject(js);
|
||||
JS_SetPropertyStr(js, obj, "left", JS_NewFloat64(js, l));
|
||||
@@ -216,82 +216,82 @@ JSC_CCALL(sound_samplePlayerGetVolume,
|
||||
return obj;
|
||||
)
|
||||
JSC_CCALL(sound_samplePlayerGetLength,
|
||||
if (!pd_sound) return JS_ThrowInternalError(js, "sound not initialized");
|
||||
if (!pd_sound) return JS_RaiseDisrupt(js, "sound not initialized");
|
||||
return JS_NewFloat64(js, pd_sound->sampleplayer->getLength(js2sampleplayer(js, argv[0])));
|
||||
)
|
||||
JSC_CCALL(sound_samplePlayerSetOffset,
|
||||
if (!pd_sound) return JS_ThrowInternalError(js, "sound not initialized");
|
||||
if (!pd_sound) return JS_RaiseDisrupt(js, "sound not initialized");
|
||||
pd_sound->sampleplayer->setOffset(js2sampleplayer(js, argv[0]), (float)js2number(js, argv[1]));
|
||||
return JS_NULL;
|
||||
)
|
||||
JSC_CCALL(sound_samplePlayerGetOffset,
|
||||
if (!pd_sound) return JS_ThrowInternalError(js, "sound not initialized");
|
||||
if (!pd_sound) return JS_RaiseDisrupt(js, "sound not initialized");
|
||||
return JS_NewFloat64(js, pd_sound->sampleplayer->getOffset(js2sampleplayer(js, argv[0])));
|
||||
)
|
||||
JSC_CCALL(sound_samplePlayerSetRate,
|
||||
if (!pd_sound) return JS_ThrowInternalError(js, "sound not initialized");
|
||||
if (!pd_sound) return JS_RaiseDisrupt(js, "sound not initialized");
|
||||
pd_sound->sampleplayer->setRate(js2sampleplayer(js, argv[0]), (float)js2number(js, argv[1]));
|
||||
return JS_NULL;
|
||||
)
|
||||
JSC_CCALL(sound_samplePlayerGetRate,
|
||||
if (!pd_sound) return JS_ThrowInternalError(js, "sound not initialized");
|
||||
if (!pd_sound) return JS_RaiseDisrupt(js, "sound not initialized");
|
||||
return JS_NewFloat64(js, pd_sound->sampleplayer->getRate(js2sampleplayer(js, argv[0])));
|
||||
)
|
||||
JSC_CCALL(sound_samplePlayerSetPlayRange,
|
||||
if (!pd_sound) return JS_ThrowInternalError(js, "sound not initialized");
|
||||
if (!pd_sound) return JS_RaiseDisrupt(js, "sound not initialized");
|
||||
pd_sound->sampleplayer->setPlayRange(js2sampleplayer(js, argv[0]), (int)js2number(js, argv[1]), (int)js2number(js, argv[2]));
|
||||
return JS_NULL;
|
||||
)
|
||||
JSC_CCALL(sound_samplePlayerSetPaused,
|
||||
if (!pd_sound) return JS_ThrowInternalError(js, "sound not initialized");
|
||||
if (!pd_sound) return JS_RaiseDisrupt(js, "sound not initialized");
|
||||
pd_sound->sampleplayer->setPaused(js2sampleplayer(js, argv[0]), JS_ToBool(js, argv[1]));
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
// --- Synth ---
|
||||
JSC_CCALL(sound_newSynth,
|
||||
if (!pd_sound) return JS_ThrowInternalError(js, "sound not initialized");
|
||||
if (!pd_sound) return JS_RaiseDisrupt(js, "sound not initialized");
|
||||
PDSynth *s = pd_sound->synth->newSynth();
|
||||
return s ? JS_NewInt64(js, (int64_t)(intptr_t)s) : JS_NULL;
|
||||
)
|
||||
JSC_CCALL(sound_freeSynth,
|
||||
if (!pd_sound) return JS_ThrowInternalError(js, "sound not initialized");
|
||||
if (!pd_sound) return JS_RaiseDisrupt(js, "sound not initialized");
|
||||
PDSynth *s = js2synth(js, argv[0]);
|
||||
if (s) pd_sound->synth->freeSynth(s);
|
||||
return JS_NULL;
|
||||
)
|
||||
JSC_CCALL(sound_synthSetWaveform,
|
||||
if (!pd_sound) return JS_ThrowInternalError(js, "sound not initialized");
|
||||
if (!pd_sound) return JS_RaiseDisrupt(js, "sound not initialized");
|
||||
pd_sound->synth->setWaveform(js2synth(js, argv[0]), (SoundWaveform)(int)js2number(js, argv[1]));
|
||||
return JS_NULL;
|
||||
)
|
||||
JSC_CCALL(sound_synthSetAttackTime,
|
||||
if (!pd_sound) return JS_ThrowInternalError(js, "sound not initialized");
|
||||
if (!pd_sound) return JS_RaiseDisrupt(js, "sound not initialized");
|
||||
pd_sound->synth->setAttackTime(js2synth(js, argv[0]), (float)js2number(js, argv[1]));
|
||||
return JS_NULL;
|
||||
)
|
||||
JSC_CCALL(sound_synthSetDecayTime,
|
||||
if (!pd_sound) return JS_ThrowInternalError(js, "sound not initialized");
|
||||
if (!pd_sound) return JS_RaiseDisrupt(js, "sound not initialized");
|
||||
pd_sound->synth->setDecayTime(js2synth(js, argv[0]), (float)js2number(js, argv[1]));
|
||||
return JS_NULL;
|
||||
)
|
||||
JSC_CCALL(sound_synthSetSustainLevel,
|
||||
if (!pd_sound) return JS_ThrowInternalError(js, "sound not initialized");
|
||||
if (!pd_sound) return JS_RaiseDisrupt(js, "sound not initialized");
|
||||
pd_sound->synth->setSustainLevel(js2synth(js, argv[0]), (float)js2number(js, argv[1]));
|
||||
return JS_NULL;
|
||||
)
|
||||
JSC_CCALL(sound_synthSetReleaseTime,
|
||||
if (!pd_sound) return JS_ThrowInternalError(js, "sound not initialized");
|
||||
if (!pd_sound) return JS_RaiseDisrupt(js, "sound not initialized");
|
||||
pd_sound->synth->setReleaseTime(js2synth(js, argv[0]), (float)js2number(js, argv[1]));
|
||||
return JS_NULL;
|
||||
)
|
||||
JSC_CCALL(sound_synthSetTranspose,
|
||||
if (!pd_sound) return JS_ThrowInternalError(js, "sound not initialized");
|
||||
if (!pd_sound) return JS_RaiseDisrupt(js, "sound not initialized");
|
||||
pd_sound->synth->setTranspose(js2synth(js, argv[0]), (float)js2number(js, argv[1]));
|
||||
return JS_NULL;
|
||||
)
|
||||
JSC_CCALL(sound_synthPlayNote,
|
||||
if (!pd_sound) return JS_ThrowInternalError(js, "sound not initialized");
|
||||
if (!pd_sound) return JS_RaiseDisrupt(js, "sound not initialized");
|
||||
PDSynth *s = js2synth(js, argv[0]);
|
||||
float freq = (float)js2number(js, argv[1]);
|
||||
float vel = argc > 2 ? (float)js2number(js, argv[2]) : 1.0f;
|
||||
@@ -301,7 +301,7 @@ JSC_CCALL(sound_synthPlayNote,
|
||||
return JS_NULL;
|
||||
)
|
||||
JSC_CCALL(sound_synthPlayMIDINote,
|
||||
if (!pd_sound) return JS_ThrowInternalError(js, "sound not initialized");
|
||||
if (!pd_sound) return JS_RaiseDisrupt(js, "sound not initialized");
|
||||
PDSynth *s = js2synth(js, argv[0]);
|
||||
MIDINote note = (MIDINote)js2number(js, argv[1]);
|
||||
float vel = argc > 2 ? (float)js2number(js, argv[2]) : 1.0f;
|
||||
@@ -311,22 +311,22 @@ JSC_CCALL(sound_synthPlayMIDINote,
|
||||
return JS_NULL;
|
||||
)
|
||||
JSC_CCALL(sound_synthNoteOff,
|
||||
if (!pd_sound) return JS_ThrowInternalError(js, "sound not initialized");
|
||||
if (!pd_sound) return JS_RaiseDisrupt(js, "sound not initialized");
|
||||
pd_sound->synth->noteOff(js2synth(js, argv[0]), argc > 1 ? (uint32_t)js2number(js, argv[1]) : 0);
|
||||
return JS_NULL;
|
||||
)
|
||||
JSC_CCALL(sound_synthStop,
|
||||
if (!pd_sound) return JS_ThrowInternalError(js, "sound not initialized");
|
||||
if (!pd_sound) return JS_RaiseDisrupt(js, "sound not initialized");
|
||||
pd_sound->synth->stop(js2synth(js, argv[0]));
|
||||
return JS_NULL;
|
||||
)
|
||||
JSC_CCALL(sound_synthSetVolume,
|
||||
if (!pd_sound) return JS_ThrowInternalError(js, "sound not initialized");
|
||||
if (!pd_sound) return JS_RaiseDisrupt(js, "sound not initialized");
|
||||
pd_sound->synth->setVolume(js2synth(js, argv[0]), (float)js2number(js, argv[1]), (float)js2number(js, argv[2]));
|
||||
return JS_NULL;
|
||||
)
|
||||
JSC_CCALL(sound_synthGetVolume,
|
||||
if (!pd_sound) return JS_ThrowInternalError(js, "sound not initialized");
|
||||
if (!pd_sound) return JS_RaiseDisrupt(js, "sound not initialized");
|
||||
float l, r; pd_sound->synth->getVolume(js2synth(js, argv[0]), &l, &r);
|
||||
JSValue obj = JS_NewObject(js);
|
||||
JS_SetPropertyStr(js, obj, "left", JS_NewFloat64(js, l));
|
||||
@@ -334,41 +334,41 @@ JSC_CCALL(sound_synthGetVolume,
|
||||
return obj;
|
||||
)
|
||||
JSC_CCALL(sound_synthIsPlaying,
|
||||
if (!pd_sound) return JS_ThrowInternalError(js, "sound not initialized");
|
||||
if (!pd_sound) return JS_RaiseDisrupt(js, "sound not initialized");
|
||||
return JS_NewBool(js, pd_sound->synth->isPlaying(js2synth(js, argv[0])));
|
||||
)
|
||||
JSC_CCALL(sound_synthGetParameterCount,
|
||||
if (!pd_sound) return JS_ThrowInternalError(js, "sound not initialized");
|
||||
if (!pd_sound) return JS_RaiseDisrupt(js, "sound not initialized");
|
||||
return JS_NewInt32(js, pd_sound->synth->getParameterCount(js2synth(js, argv[0])));
|
||||
)
|
||||
JSC_CCALL(sound_synthSetParameter,
|
||||
if (!pd_sound) return JS_ThrowInternalError(js, "sound not initialized");
|
||||
if (!pd_sound) return JS_RaiseDisrupt(js, "sound not initialized");
|
||||
return JS_NewBool(js, pd_sound->synth->setParameter(js2synth(js, argv[0]), (int)js2number(js, argv[1]), (float)js2number(js, argv[2])));
|
||||
)
|
||||
|
||||
// --- Channel ---
|
||||
JSC_CCALL(sound_newChannel,
|
||||
if (!pd_sound) return JS_ThrowInternalError(js, "sound not initialized");
|
||||
if (!pd_sound) return JS_RaiseDisrupt(js, "sound not initialized");
|
||||
SoundChannel *ch = pd_sound->channel->newChannel();
|
||||
return ch ? JS_NewInt64(js, (int64_t)(intptr_t)ch) : JS_NULL;
|
||||
)
|
||||
JSC_CCALL(sound_freeChannel,
|
||||
if (!pd_sound) return JS_ThrowInternalError(js, "sound not initialized");
|
||||
if (!pd_sound) return JS_RaiseDisrupt(js, "sound not initialized");
|
||||
SoundChannel *ch = js2channel(js, argv[0]);
|
||||
if (ch) pd_sound->channel->freeChannel(ch);
|
||||
return JS_NULL;
|
||||
)
|
||||
JSC_CCALL(sound_channelSetVolume,
|
||||
if (!pd_sound) return JS_ThrowInternalError(js, "sound not initialized");
|
||||
if (!pd_sound) return JS_RaiseDisrupt(js, "sound not initialized");
|
||||
pd_sound->channel->setVolume(js2channel(js, argv[0]), (float)js2number(js, argv[1]));
|
||||
return JS_NULL;
|
||||
)
|
||||
JSC_CCALL(sound_channelGetVolume,
|
||||
if (!pd_sound) return JS_ThrowInternalError(js, "sound not initialized");
|
||||
if (!pd_sound) return JS_RaiseDisrupt(js, "sound not initialized");
|
||||
return JS_NewFloat64(js, pd_sound->channel->getVolume(js2channel(js, argv[0])));
|
||||
)
|
||||
JSC_CCALL(sound_channelSetPan,
|
||||
if (!pd_sound) return JS_ThrowInternalError(js, "sound not initialized");
|
||||
if (!pd_sound) return JS_RaiseDisrupt(js, "sound not initialized");
|
||||
pd_sound->channel->setPan(js2channel(js, argv[0]), (float)js2number(js, argv[1]));
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
@@ -21,76 +21,76 @@ static LCDBitmap* js2bitmap(JSContext *js, JSValueConst val) {
|
||||
// --- Sprite Functions ---
|
||||
|
||||
JSC_CCALL(sprite_setAlwaysRedraw,
|
||||
if (!pd_sprite) return JS_ThrowInternalError(js, "sprite not initialized");
|
||||
if (!pd_sprite) return JS_RaiseDisrupt(js, "sprite not initialized");
|
||||
pd_sprite->setAlwaysRedraw(JS_ToBool(js, argv[0]));
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(sprite_drawSprites,
|
||||
if (!pd_sprite) return JS_ThrowInternalError(js, "sprite not initialized");
|
||||
if (!pd_sprite) return JS_RaiseDisrupt(js, "sprite not initialized");
|
||||
pd_sprite->drawSprites();
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(sprite_updateAndDrawSprites,
|
||||
if (!pd_sprite) return JS_ThrowInternalError(js, "sprite not initialized");
|
||||
if (!pd_sprite) return JS_RaiseDisrupt(js, "sprite not initialized");
|
||||
pd_sprite->updateAndDrawSprites();
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(sprite_newSprite,
|
||||
if (!pd_sprite) return JS_ThrowInternalError(js, "sprite not initialized");
|
||||
if (!pd_sprite) return JS_RaiseDisrupt(js, "sprite not initialized");
|
||||
LCDSprite *s = pd_sprite->newSprite();
|
||||
if (!s) return JS_ThrowInternalError(js, "failed to create sprite");
|
||||
if (!s) return JS_RaiseDisrupt(js, "failed to create sprite");
|
||||
return JS_NewInt64(js, (int64_t)(intptr_t)s);
|
||||
)
|
||||
|
||||
JSC_CCALL(sprite_freeSprite,
|
||||
if (!pd_sprite) return JS_ThrowInternalError(js, "sprite not initialized");
|
||||
if (!pd_sprite) return JS_RaiseDisrupt(js, "sprite not initialized");
|
||||
LCDSprite *s = js2sprite(js, argv[0]);
|
||||
if (s) pd_sprite->freeSprite(s);
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(sprite_copy,
|
||||
if (!pd_sprite) return JS_ThrowInternalError(js, "sprite not initialized");
|
||||
if (!pd_sprite) return JS_RaiseDisrupt(js, "sprite not initialized");
|
||||
LCDSprite *s = js2sprite(js, argv[0]);
|
||||
if (!s) return JS_ThrowTypeError(js, "invalid sprite");
|
||||
if (!s) return JS_RaiseDisrupt(js, "invalid sprite");
|
||||
LCDSprite *copy = pd_sprite->copy(s);
|
||||
return copy ? JS_NewInt64(js, (int64_t)(intptr_t)copy) : JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(sprite_addSprite,
|
||||
if (!pd_sprite) return JS_ThrowInternalError(js, "sprite not initialized");
|
||||
if (!pd_sprite) return JS_RaiseDisrupt(js, "sprite not initialized");
|
||||
LCDSprite *s = js2sprite(js, argv[0]);
|
||||
if (!s) return JS_ThrowTypeError(js, "invalid sprite");
|
||||
if (!s) return JS_RaiseDisrupt(js, "invalid sprite");
|
||||
pd_sprite->addSprite(s);
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(sprite_removeSprite,
|
||||
if (!pd_sprite) return JS_ThrowInternalError(js, "sprite not initialized");
|
||||
if (!pd_sprite) return JS_RaiseDisrupt(js, "sprite not initialized");
|
||||
LCDSprite *s = js2sprite(js, argv[0]);
|
||||
if (!s) return JS_ThrowTypeError(js, "invalid sprite");
|
||||
if (!s) return JS_RaiseDisrupt(js, "invalid sprite");
|
||||
pd_sprite->removeSprite(s);
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(sprite_removeAllSprites,
|
||||
if (!pd_sprite) return JS_ThrowInternalError(js, "sprite not initialized");
|
||||
if (!pd_sprite) return JS_RaiseDisrupt(js, "sprite not initialized");
|
||||
pd_sprite->removeAllSprites();
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(sprite_getSpriteCount,
|
||||
if (!pd_sprite) return JS_ThrowInternalError(js, "sprite not initialized");
|
||||
if (!pd_sprite) return JS_RaiseDisrupt(js, "sprite not initialized");
|
||||
return JS_NewInt32(js, pd_sprite->getSpriteCount());
|
||||
)
|
||||
|
||||
JSC_CCALL(sprite_setBounds,
|
||||
if (!pd_sprite) return JS_ThrowInternalError(js, "sprite not initialized");
|
||||
if (!pd_sprite) return JS_RaiseDisrupt(js, "sprite not initialized");
|
||||
LCDSprite *s = js2sprite(js, argv[0]);
|
||||
if (!s) return JS_ThrowTypeError(js, "invalid sprite");
|
||||
if (!s) return JS_RaiseDisrupt(js, "invalid sprite");
|
||||
PDRect bounds = { (float)js2number(js, argv[1]), (float)js2number(js, argv[2]),
|
||||
(float)js2number(js, argv[3]), (float)js2number(js, argv[4]) };
|
||||
pd_sprite->setBounds(s, bounds);
|
||||
@@ -98,9 +98,9 @@ JSC_CCALL(sprite_setBounds,
|
||||
)
|
||||
|
||||
JSC_CCALL(sprite_getBounds,
|
||||
if (!pd_sprite) return JS_ThrowInternalError(js, "sprite not initialized");
|
||||
if (!pd_sprite) return JS_RaiseDisrupt(js, "sprite not initialized");
|
||||
LCDSprite *s = js2sprite(js, argv[0]);
|
||||
if (!s) return JS_ThrowTypeError(js, "invalid sprite");
|
||||
if (!s) return JS_RaiseDisrupt(js, "invalid sprite");
|
||||
PDRect b = pd_sprite->getBounds(s);
|
||||
JSValue obj = JS_NewObject(js);
|
||||
JS_SetPropertyStr(js, obj, "x", JS_NewFloat64(js, b.x));
|
||||
@@ -111,143 +111,143 @@ JSC_CCALL(sprite_getBounds,
|
||||
)
|
||||
|
||||
JSC_CCALL(sprite_moveTo,
|
||||
if (!pd_sprite) return JS_ThrowInternalError(js, "sprite not initialized");
|
||||
if (!pd_sprite) return JS_RaiseDisrupt(js, "sprite not initialized");
|
||||
LCDSprite *s = js2sprite(js, argv[0]);
|
||||
if (!s) return JS_ThrowTypeError(js, "invalid sprite");
|
||||
if (!s) return JS_RaiseDisrupt(js, "invalid sprite");
|
||||
pd_sprite->moveTo(s, (float)js2number(js, argv[1]), (float)js2number(js, argv[2]));
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(sprite_moveBy,
|
||||
if (!pd_sprite) return JS_ThrowInternalError(js, "sprite not initialized");
|
||||
if (!pd_sprite) return JS_RaiseDisrupt(js, "sprite not initialized");
|
||||
LCDSprite *s = js2sprite(js, argv[0]);
|
||||
if (!s) return JS_ThrowTypeError(js, "invalid sprite");
|
||||
if (!s) return JS_RaiseDisrupt(js, "invalid sprite");
|
||||
pd_sprite->moveBy(s, (float)js2number(js, argv[1]), (float)js2number(js, argv[2]));
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(sprite_setImage,
|
||||
if (!pd_sprite) return JS_ThrowInternalError(js, "sprite not initialized");
|
||||
if (!pd_sprite) return JS_RaiseDisrupt(js, "sprite not initialized");
|
||||
LCDSprite *s = js2sprite(js, argv[0]);
|
||||
LCDBitmap *img = js2bitmap(js, argv[1]);
|
||||
if (!s) return JS_ThrowTypeError(js, "invalid sprite");
|
||||
if (!s) return JS_RaiseDisrupt(js, "invalid sprite");
|
||||
LCDBitmapFlip flip = argc > 2 ? (LCDBitmapFlip)(int)js2number(js, argv[2]) : kBitmapUnflipped;
|
||||
pd_sprite->setImage(s, img, flip);
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(sprite_getImage,
|
||||
if (!pd_sprite) return JS_ThrowInternalError(js, "sprite not initialized");
|
||||
if (!pd_sprite) return JS_RaiseDisrupt(js, "sprite not initialized");
|
||||
LCDSprite *s = js2sprite(js, argv[0]);
|
||||
if (!s) return JS_ThrowTypeError(js, "invalid sprite");
|
||||
if (!s) return JS_RaiseDisrupt(js, "invalid sprite");
|
||||
LCDBitmap *img = pd_sprite->getImage(s);
|
||||
return img ? JS_NewInt64(js, (int64_t)(intptr_t)img) : JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(sprite_setSize,
|
||||
if (!pd_sprite) return JS_ThrowInternalError(js, "sprite not initialized");
|
||||
if (!pd_sprite) return JS_RaiseDisrupt(js, "sprite not initialized");
|
||||
LCDSprite *s = js2sprite(js, argv[0]);
|
||||
if (!s) return JS_ThrowTypeError(js, "invalid sprite");
|
||||
if (!s) return JS_RaiseDisrupt(js, "invalid sprite");
|
||||
pd_sprite->setSize(s, (float)js2number(js, argv[1]), (float)js2number(js, argv[2]));
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(sprite_setZIndex,
|
||||
if (!pd_sprite) return JS_ThrowInternalError(js, "sprite not initialized");
|
||||
if (!pd_sprite) return JS_RaiseDisrupt(js, "sprite not initialized");
|
||||
LCDSprite *s = js2sprite(js, argv[0]);
|
||||
if (!s) return JS_ThrowTypeError(js, "invalid sprite");
|
||||
if (!s) return JS_RaiseDisrupt(js, "invalid sprite");
|
||||
pd_sprite->setZIndex(s, (int16_t)js2number(js, argv[1]));
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(sprite_getZIndex,
|
||||
if (!pd_sprite) return JS_ThrowInternalError(js, "sprite not initialized");
|
||||
if (!pd_sprite) return JS_RaiseDisrupt(js, "sprite not initialized");
|
||||
LCDSprite *s = js2sprite(js, argv[0]);
|
||||
if (!s) return JS_ThrowTypeError(js, "invalid sprite");
|
||||
if (!s) return JS_RaiseDisrupt(js, "invalid sprite");
|
||||
return JS_NewInt32(js, pd_sprite->getZIndex(s));
|
||||
)
|
||||
|
||||
JSC_CCALL(sprite_setDrawMode,
|
||||
if (!pd_sprite) return JS_ThrowInternalError(js, "sprite not initialized");
|
||||
if (!pd_sprite) return JS_RaiseDisrupt(js, "sprite not initialized");
|
||||
LCDSprite *s = js2sprite(js, argv[0]);
|
||||
if (!s) return JS_ThrowTypeError(js, "invalid sprite");
|
||||
if (!s) return JS_RaiseDisrupt(js, "invalid sprite");
|
||||
pd_sprite->setDrawMode(s, (LCDBitmapDrawMode)(int)js2number(js, argv[1]));
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(sprite_setImageFlip,
|
||||
if (!pd_sprite) return JS_ThrowInternalError(js, "sprite not initialized");
|
||||
if (!pd_sprite) return JS_RaiseDisrupt(js, "sprite not initialized");
|
||||
LCDSprite *s = js2sprite(js, argv[0]);
|
||||
if (!s) return JS_ThrowTypeError(js, "invalid sprite");
|
||||
if (!s) return JS_RaiseDisrupt(js, "invalid sprite");
|
||||
pd_sprite->setImageFlip(s, (LCDBitmapFlip)(int)js2number(js, argv[1]));
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(sprite_getImageFlip,
|
||||
if (!pd_sprite) return JS_ThrowInternalError(js, "sprite not initialized");
|
||||
if (!pd_sprite) return JS_RaiseDisrupt(js, "sprite not initialized");
|
||||
LCDSprite *s = js2sprite(js, argv[0]);
|
||||
if (!s) return JS_ThrowTypeError(js, "invalid sprite");
|
||||
if (!s) return JS_RaiseDisrupt(js, "invalid sprite");
|
||||
return JS_NewInt32(js, pd_sprite->getImageFlip(s));
|
||||
)
|
||||
|
||||
JSC_CCALL(sprite_setVisible,
|
||||
if (!pd_sprite) return JS_ThrowInternalError(js, "sprite not initialized");
|
||||
if (!pd_sprite) return JS_RaiseDisrupt(js, "sprite not initialized");
|
||||
LCDSprite *s = js2sprite(js, argv[0]);
|
||||
if (!s) return JS_ThrowTypeError(js, "invalid sprite");
|
||||
if (!s) return JS_RaiseDisrupt(js, "invalid sprite");
|
||||
pd_sprite->setVisible(s, JS_ToBool(js, argv[1]));
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(sprite_isVisible,
|
||||
if (!pd_sprite) return JS_ThrowInternalError(js, "sprite not initialized");
|
||||
if (!pd_sprite) return JS_RaiseDisrupt(js, "sprite not initialized");
|
||||
LCDSprite *s = js2sprite(js, argv[0]);
|
||||
if (!s) return JS_ThrowTypeError(js, "invalid sprite");
|
||||
if (!s) return JS_RaiseDisrupt(js, "invalid sprite");
|
||||
return JS_NewBool(js, pd_sprite->isVisible(s));
|
||||
)
|
||||
|
||||
JSC_CCALL(sprite_setOpaque,
|
||||
if (!pd_sprite) return JS_ThrowInternalError(js, "sprite not initialized");
|
||||
if (!pd_sprite) return JS_RaiseDisrupt(js, "sprite not initialized");
|
||||
LCDSprite *s = js2sprite(js, argv[0]);
|
||||
if (!s) return JS_ThrowTypeError(js, "invalid sprite");
|
||||
if (!s) return JS_RaiseDisrupt(js, "invalid sprite");
|
||||
pd_sprite->setOpaque(s, JS_ToBool(js, argv[1]));
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(sprite_markDirty,
|
||||
if (!pd_sprite) return JS_ThrowInternalError(js, "sprite not initialized");
|
||||
if (!pd_sprite) return JS_RaiseDisrupt(js, "sprite not initialized");
|
||||
LCDSprite *s = js2sprite(js, argv[0]);
|
||||
if (!s) return JS_ThrowTypeError(js, "invalid sprite");
|
||||
if (!s) return JS_RaiseDisrupt(js, "invalid sprite");
|
||||
pd_sprite->markDirty(s);
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(sprite_setTag,
|
||||
if (!pd_sprite) return JS_ThrowInternalError(js, "sprite not initialized");
|
||||
if (!pd_sprite) return JS_RaiseDisrupt(js, "sprite not initialized");
|
||||
LCDSprite *s = js2sprite(js, argv[0]);
|
||||
if (!s) return JS_ThrowTypeError(js, "invalid sprite");
|
||||
if (!s) return JS_RaiseDisrupt(js, "invalid sprite");
|
||||
pd_sprite->setTag(s, (uint8_t)js2number(js, argv[1]));
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(sprite_getTag,
|
||||
if (!pd_sprite) return JS_ThrowInternalError(js, "sprite not initialized");
|
||||
if (!pd_sprite) return JS_RaiseDisrupt(js, "sprite not initialized");
|
||||
LCDSprite *s = js2sprite(js, argv[0]);
|
||||
if (!s) return JS_ThrowTypeError(js, "invalid sprite");
|
||||
if (!s) return JS_RaiseDisrupt(js, "invalid sprite");
|
||||
return JS_NewInt32(js, pd_sprite->getTag(s));
|
||||
)
|
||||
|
||||
JSC_CCALL(sprite_setIgnoresDrawOffset,
|
||||
if (!pd_sprite) return JS_ThrowInternalError(js, "sprite not initialized");
|
||||
if (!pd_sprite) return JS_RaiseDisrupt(js, "sprite not initialized");
|
||||
LCDSprite *s = js2sprite(js, argv[0]);
|
||||
if (!s) return JS_ThrowTypeError(js, "invalid sprite");
|
||||
if (!s) return JS_RaiseDisrupt(js, "invalid sprite");
|
||||
pd_sprite->setIgnoresDrawOffset(s, JS_ToBool(js, argv[1]));
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(sprite_getPosition,
|
||||
if (!pd_sprite) return JS_ThrowInternalError(js, "sprite not initialized");
|
||||
if (!pd_sprite) return JS_RaiseDisrupt(js, "sprite not initialized");
|
||||
LCDSprite *s = js2sprite(js, argv[0]);
|
||||
if (!s) return JS_ThrowTypeError(js, "invalid sprite");
|
||||
if (!s) return JS_RaiseDisrupt(js, "invalid sprite");
|
||||
float x, y;
|
||||
pd_sprite->getPosition(s, &x, &y);
|
||||
JSValue obj = JS_NewObject(js);
|
||||
@@ -257,17 +257,17 @@ JSC_CCALL(sprite_getPosition,
|
||||
)
|
||||
|
||||
JSC_CCALL(sprite_setCenter,
|
||||
if (!pd_sprite) return JS_ThrowInternalError(js, "sprite not initialized");
|
||||
if (!pd_sprite) return JS_RaiseDisrupt(js, "sprite not initialized");
|
||||
LCDSprite *s = js2sprite(js, argv[0]);
|
||||
if (!s) return JS_ThrowTypeError(js, "invalid sprite");
|
||||
if (!s) return JS_RaiseDisrupt(js, "invalid sprite");
|
||||
pd_sprite->setCenter(s, (float)js2number(js, argv[1]), (float)js2number(js, argv[2]));
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(sprite_getCenter,
|
||||
if (!pd_sprite) return JS_ThrowInternalError(js, "sprite not initialized");
|
||||
if (!pd_sprite) return JS_RaiseDisrupt(js, "sprite not initialized");
|
||||
LCDSprite *s = js2sprite(js, argv[0]);
|
||||
if (!s) return JS_ThrowTypeError(js, "invalid sprite");
|
||||
if (!s) return JS_RaiseDisrupt(js, "invalid sprite");
|
||||
float x, y;
|
||||
pd_sprite->getCenter(s, &x, &y);
|
||||
JSValue obj = JS_NewObject(js);
|
||||
@@ -279,15 +279,15 @@ JSC_CCALL(sprite_getCenter,
|
||||
// --- Collision Functions ---
|
||||
|
||||
JSC_CCALL(sprite_resetCollisionWorld,
|
||||
if (!pd_sprite) return JS_ThrowInternalError(js, "sprite not initialized");
|
||||
if (!pd_sprite) return JS_RaiseDisrupt(js, "sprite not initialized");
|
||||
pd_sprite->resetCollisionWorld();
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(sprite_setCollideRect,
|
||||
if (!pd_sprite) return JS_ThrowInternalError(js, "sprite not initialized");
|
||||
if (!pd_sprite) return JS_RaiseDisrupt(js, "sprite not initialized");
|
||||
LCDSprite *s = js2sprite(js, argv[0]);
|
||||
if (!s) return JS_ThrowTypeError(js, "invalid sprite");
|
||||
if (!s) return JS_RaiseDisrupt(js, "invalid sprite");
|
||||
PDRect rect = { (float)js2number(js, argv[1]), (float)js2number(js, argv[2]),
|
||||
(float)js2number(js, argv[3]), (float)js2number(js, argv[4]) };
|
||||
pd_sprite->setCollideRect(s, rect);
|
||||
@@ -295,9 +295,9 @@ JSC_CCALL(sprite_setCollideRect,
|
||||
)
|
||||
|
||||
JSC_CCALL(sprite_getCollideRect,
|
||||
if (!pd_sprite) return JS_ThrowInternalError(js, "sprite not initialized");
|
||||
if (!pd_sprite) return JS_RaiseDisrupt(js, "sprite not initialized");
|
||||
LCDSprite *s = js2sprite(js, argv[0]);
|
||||
if (!s) return JS_ThrowTypeError(js, "invalid sprite");
|
||||
if (!s) return JS_RaiseDisrupt(js, "invalid sprite");
|
||||
PDRect r = pd_sprite->getCollideRect(s);
|
||||
JSValue obj = JS_NewObject(js);
|
||||
JS_SetPropertyStr(js, obj, "x", JS_NewFloat64(js, r.x));
|
||||
@@ -308,40 +308,40 @@ JSC_CCALL(sprite_getCollideRect,
|
||||
)
|
||||
|
||||
JSC_CCALL(sprite_clearCollideRect,
|
||||
if (!pd_sprite) return JS_ThrowInternalError(js, "sprite not initialized");
|
||||
if (!pd_sprite) return JS_RaiseDisrupt(js, "sprite not initialized");
|
||||
LCDSprite *s = js2sprite(js, argv[0]);
|
||||
if (!s) return JS_ThrowTypeError(js, "invalid sprite");
|
||||
if (!s) return JS_RaiseDisrupt(js, "invalid sprite");
|
||||
pd_sprite->clearCollideRect(s);
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(sprite_setCollisionsEnabled,
|
||||
if (!pd_sprite) return JS_ThrowInternalError(js, "sprite not initialized");
|
||||
if (!pd_sprite) return JS_RaiseDisrupt(js, "sprite not initialized");
|
||||
LCDSprite *s = js2sprite(js, argv[0]);
|
||||
if (!s) return JS_ThrowTypeError(js, "invalid sprite");
|
||||
if (!s) return JS_RaiseDisrupt(js, "invalid sprite");
|
||||
pd_sprite->setCollisionsEnabled(s, JS_ToBool(js, argv[1]));
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(sprite_collisionsEnabled,
|
||||
if (!pd_sprite) return JS_ThrowInternalError(js, "sprite not initialized");
|
||||
if (!pd_sprite) return JS_RaiseDisrupt(js, "sprite not initialized");
|
||||
LCDSprite *s = js2sprite(js, argv[0]);
|
||||
if (!s) return JS_ThrowTypeError(js, "invalid sprite");
|
||||
if (!s) return JS_RaiseDisrupt(js, "invalid sprite");
|
||||
return JS_NewBool(js, pd_sprite->collisionsEnabled(s));
|
||||
)
|
||||
|
||||
JSC_CCALL(sprite_setUpdatesEnabled,
|
||||
if (!pd_sprite) return JS_ThrowInternalError(js, "sprite not initialized");
|
||||
if (!pd_sprite) return JS_RaiseDisrupt(js, "sprite not initialized");
|
||||
LCDSprite *s = js2sprite(js, argv[0]);
|
||||
if (!s) return JS_ThrowTypeError(js, "invalid sprite");
|
||||
if (!s) return JS_RaiseDisrupt(js, "invalid sprite");
|
||||
pd_sprite->setUpdatesEnabled(s, JS_ToBool(js, argv[1]));
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(sprite_updatesEnabled,
|
||||
if (!pd_sprite) return JS_ThrowInternalError(js, "sprite not initialized");
|
||||
if (!pd_sprite) return JS_RaiseDisrupt(js, "sprite not initialized");
|
||||
LCDSprite *s = js2sprite(js, argv[0]);
|
||||
if (!s) return JS_ThrowTypeError(js, "invalid sprite");
|
||||
if (!s) return JS_RaiseDisrupt(js, "invalid sprite");
|
||||
return JS_NewBool(js, pd_sprite->updatesEnabled(s));
|
||||
)
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
// --- System Functions ---
|
||||
|
||||
JSC_CCALL(sys_logToConsole,
|
||||
if (!pd_sys) return JS_ThrowInternalError(js, "system not initialized");
|
||||
if (!pd_sys) return JS_RaiseDisrupt(js, "system not initialized");
|
||||
const char *str = JS_ToCString(js, argv[0]);
|
||||
if (str) {
|
||||
pd_sys->logToConsole("%s", str);
|
||||
@@ -18,7 +18,7 @@ JSC_CCALL(sys_logToConsole,
|
||||
)
|
||||
|
||||
JSC_CCALL(sys_error,
|
||||
if (!pd_sys) return JS_ThrowInternalError(js, "system not initialized");
|
||||
if (!pd_sys) return JS_RaiseDisrupt(js, "system not initialized");
|
||||
const char *str = JS_ToCString(js, argv[0]);
|
||||
if (str) {
|
||||
pd_sys->error("%s", str);
|
||||
@@ -28,18 +28,18 @@ JSC_CCALL(sys_error,
|
||||
)
|
||||
|
||||
JSC_CCALL(sys_getLanguage,
|
||||
if (!pd_sys) return JS_ThrowInternalError(js, "system not initialized");
|
||||
if (!pd_sys) return JS_RaiseDisrupt(js, "system not initialized");
|
||||
PDLanguage lang = pd_sys->getLanguage();
|
||||
return JS_NewInt32(js, lang);
|
||||
)
|
||||
|
||||
JSC_CCALL(sys_getCurrentTimeMilliseconds,
|
||||
if (!pd_sys) return JS_ThrowInternalError(js, "system not initialized");
|
||||
if (!pd_sys) return JS_RaiseDisrupt(js, "system not initialized");
|
||||
return JS_NewInt64(js, pd_sys->getCurrentTimeMilliseconds());
|
||||
)
|
||||
|
||||
JSC_CCALL(sys_getSecondsSinceEpoch,
|
||||
if (!pd_sys) return JS_ThrowInternalError(js, "system not initialized");
|
||||
if (!pd_sys) return JS_RaiseDisrupt(js, "system not initialized");
|
||||
unsigned int ms = 0;
|
||||
unsigned int secs = pd_sys->getSecondsSinceEpoch(&ms);
|
||||
JSValue obj = JS_NewObject(js);
|
||||
@@ -49,7 +49,7 @@ JSC_CCALL(sys_getSecondsSinceEpoch,
|
||||
)
|
||||
|
||||
JSC_CCALL(sys_drawFPS,
|
||||
if (!pd_sys) return JS_ThrowInternalError(js, "system not initialized");
|
||||
if (!pd_sys) return JS_RaiseDisrupt(js, "system not initialized");
|
||||
int x = (int)js2number(js, argv[0]);
|
||||
int y = (int)js2number(js, argv[1]);
|
||||
pd_sys->drawFPS(x, y);
|
||||
@@ -57,7 +57,7 @@ JSC_CCALL(sys_drawFPS,
|
||||
)
|
||||
|
||||
JSC_CCALL(sys_getButtonState,
|
||||
if (!pd_sys) return JS_ThrowInternalError(js, "system not initialized");
|
||||
if (!pd_sys) return JS_RaiseDisrupt(js, "system not initialized");
|
||||
PDButtons current, pushed, released;
|
||||
pd_sys->getButtonState(¤t, &pushed, &released);
|
||||
JSValue obj = JS_NewObject(js);
|
||||
@@ -68,14 +68,14 @@ JSC_CCALL(sys_getButtonState,
|
||||
)
|
||||
|
||||
JSC_CCALL(sys_setPeripheralsEnabled,
|
||||
if (!pd_sys) return JS_ThrowInternalError(js, "system not initialized");
|
||||
if (!pd_sys) return JS_RaiseDisrupt(js, "system not initialized");
|
||||
PDPeripherals mask = (PDPeripherals)(int)js2number(js, argv[0]);
|
||||
pd_sys->setPeripheralsEnabled(mask);
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(sys_getAccelerometer,
|
||||
if (!pd_sys) return JS_ThrowInternalError(js, "system not initialized");
|
||||
if (!pd_sys) return JS_RaiseDisrupt(js, "system not initialized");
|
||||
float x, y, z;
|
||||
pd_sys->getAccelerometer(&x, &y, &z);
|
||||
JSValue obj = JS_NewObject(js);
|
||||
@@ -86,76 +86,76 @@ JSC_CCALL(sys_getAccelerometer,
|
||||
)
|
||||
|
||||
JSC_CCALL(sys_getCrankChange,
|
||||
if (!pd_sys) return JS_ThrowInternalError(js, "system not initialized");
|
||||
if (!pd_sys) return JS_RaiseDisrupt(js, "system not initialized");
|
||||
return JS_NewFloat64(js, pd_sys->getCrankChange());
|
||||
)
|
||||
|
||||
JSC_CCALL(sys_getCrankAngle,
|
||||
if (!pd_sys) return JS_ThrowInternalError(js, "system not initialized");
|
||||
if (!pd_sys) return JS_RaiseDisrupt(js, "system not initialized");
|
||||
return JS_NewFloat64(js, pd_sys->getCrankAngle());
|
||||
)
|
||||
|
||||
JSC_CCALL(sys_isCrankDocked,
|
||||
if (!pd_sys) return JS_ThrowInternalError(js, "system not initialized");
|
||||
if (!pd_sys) return JS_RaiseDisrupt(js, "system not initialized");
|
||||
return JS_NewBool(js, pd_sys->isCrankDocked());
|
||||
)
|
||||
|
||||
JSC_CCALL(sys_setCrankSoundsDisabled,
|
||||
if (!pd_sys) return JS_ThrowInternalError(js, "system not initialized");
|
||||
if (!pd_sys) return JS_RaiseDisrupt(js, "system not initialized");
|
||||
int flag = JS_ToBool(js, argv[0]);
|
||||
int prev = pd_sys->setCrankSoundsDisabled(flag);
|
||||
return JS_NewBool(js, prev);
|
||||
)
|
||||
|
||||
JSC_CCALL(sys_getFlipped,
|
||||
if (!pd_sys) return JS_ThrowInternalError(js, "system not initialized");
|
||||
if (!pd_sys) return JS_RaiseDisrupt(js, "system not initialized");
|
||||
return JS_NewBool(js, pd_sys->getFlipped());
|
||||
)
|
||||
|
||||
JSC_CCALL(sys_setAutoLockDisabled,
|
||||
if (!pd_sys) return JS_ThrowInternalError(js, "system not initialized");
|
||||
if (!pd_sys) return JS_RaiseDisrupt(js, "system not initialized");
|
||||
pd_sys->setAutoLockDisabled(JS_ToBool(js, argv[0]));
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(sys_getReduceFlashing,
|
||||
if (!pd_sys) return JS_ThrowInternalError(js, "system not initialized");
|
||||
if (!pd_sys) return JS_RaiseDisrupt(js, "system not initialized");
|
||||
return JS_NewBool(js, pd_sys->getReduceFlashing());
|
||||
)
|
||||
|
||||
JSC_CCALL(sys_getElapsedTime,
|
||||
if (!pd_sys) return JS_ThrowInternalError(js, "system not initialized");
|
||||
if (!pd_sys) return JS_RaiseDisrupt(js, "system not initialized");
|
||||
return JS_NewFloat64(js, pd_sys->getElapsedTime());
|
||||
)
|
||||
|
||||
JSC_CCALL(sys_resetElapsedTime,
|
||||
if (!pd_sys) return JS_ThrowInternalError(js, "system not initialized");
|
||||
if (!pd_sys) return JS_RaiseDisrupt(js, "system not initialized");
|
||||
pd_sys->resetElapsedTime();
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(sys_getBatteryPercentage,
|
||||
if (!pd_sys) return JS_ThrowInternalError(js, "system not initialized");
|
||||
if (!pd_sys) return JS_RaiseDisrupt(js, "system not initialized");
|
||||
return JS_NewFloat64(js, pd_sys->getBatteryPercentage());
|
||||
)
|
||||
|
||||
JSC_CCALL(sys_getBatteryVoltage,
|
||||
if (!pd_sys) return JS_ThrowInternalError(js, "system not initialized");
|
||||
if (!pd_sys) return JS_RaiseDisrupt(js, "system not initialized");
|
||||
return JS_NewFloat64(js, pd_sys->getBatteryVoltage());
|
||||
)
|
||||
|
||||
JSC_CCALL(sys_getTimezoneOffset,
|
||||
if (!pd_sys) return JS_ThrowInternalError(js, "system not initialized");
|
||||
if (!pd_sys) return JS_RaiseDisrupt(js, "system not initialized");
|
||||
return JS_NewInt32(js, pd_sys->getTimezoneOffset());
|
||||
)
|
||||
|
||||
JSC_CCALL(sys_shouldDisplay24HourTime,
|
||||
if (!pd_sys) return JS_ThrowInternalError(js, "system not initialized");
|
||||
if (!pd_sys) return JS_RaiseDisrupt(js, "system not initialized");
|
||||
return JS_NewBool(js, pd_sys->shouldDisplay24HourTime());
|
||||
)
|
||||
|
||||
JSC_CCALL(sys_convertEpochToDateTime,
|
||||
if (!pd_sys) return JS_ThrowInternalError(js, "system not initialized");
|
||||
if (!pd_sys) return JS_RaiseDisrupt(js, "system not initialized");
|
||||
uint32_t epoch = (uint32_t)js2number(js, argv[0]);
|
||||
struct PDDateTime dt;
|
||||
pd_sys->convertEpochToDateTime(epoch, &dt);
|
||||
@@ -171,7 +171,7 @@ JSC_CCALL(sys_convertEpochToDateTime,
|
||||
)
|
||||
|
||||
JSC_CCALL(sys_convertDateTimeToEpoch,
|
||||
if (!pd_sys) return JS_ThrowInternalError(js, "system not initialized");
|
||||
if (!pd_sys) return JS_RaiseDisrupt(js, "system not initialized");
|
||||
struct PDDateTime dt = {0};
|
||||
dt.year = (uint16_t)js2number(js, JS_GetPropertyStr(js, argv[0], "year"));
|
||||
dt.month = (uint8_t)js2number(js, JS_GetPropertyStr(js, argv[0], "month"));
|
||||
@@ -183,24 +183,24 @@ JSC_CCALL(sys_convertDateTimeToEpoch,
|
||||
)
|
||||
|
||||
JSC_CCALL(sys_clearICache,
|
||||
if (!pd_sys) return JS_ThrowInternalError(js, "system not initialized");
|
||||
if (!pd_sys) return JS_RaiseDisrupt(js, "system not initialized");
|
||||
pd_sys->clearICache();
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(sys_delay,
|
||||
if (!pd_sys) return JS_ThrowInternalError(js, "system not initialized");
|
||||
if (!pd_sys) return JS_RaiseDisrupt(js, "system not initialized");
|
||||
pd_sys->delay((uint32_t)js2number(js, argv[0]));
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
JSC_SCALL(sys_restartGame,
|
||||
if (!pd_sys) return JS_ThrowInternalError(js, "system not initialized");
|
||||
if (!pd_sys) return JS_RaiseDisrupt(js, "system not initialized");
|
||||
pd_sys->restartGame(str);
|
||||
)
|
||||
|
||||
JSC_CCALL(sys_getLaunchArgs,
|
||||
if (!pd_sys) return JS_ThrowInternalError(js, "system not initialized");
|
||||
if (!pd_sys) return JS_RaiseDisrupt(js, "system not initialized");
|
||||
const char *path = NULL;
|
||||
const char *args = pd_sys->getLaunchArgs(&path);
|
||||
JSValue obj = JS_NewObject(js);
|
||||
@@ -210,7 +210,7 @@ JSC_CCALL(sys_getLaunchArgs,
|
||||
)
|
||||
|
||||
JSC_CCALL(sys_getSystemInfo,
|
||||
if (!pd_sys) return JS_ThrowInternalError(js, "system not initialized");
|
||||
if (!pd_sys) return JS_RaiseDisrupt(js, "system not initialized");
|
||||
const struct PDInfo *info = pd_sys->getSystemInfo();
|
||||
if (!info) return JS_NULL;
|
||||
JSValue obj = JS_NewObject(js);
|
||||
@@ -222,7 +222,7 @@ JSC_CCALL(sys_getSystemInfo,
|
||||
// --- Menu Functions ---
|
||||
|
||||
JSC_CCALL(sys_removeAllMenuItems,
|
||||
if (!pd_sys) return JS_ThrowInternalError(js, "system not initialized");
|
||||
if (!pd_sys) return JS_RaiseDisrupt(js, "system not initialized");
|
||||
pd_sys->removeAllMenuItems();
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
54
qop.c
54
qop.c
@@ -100,16 +100,16 @@ JSC_CCALL(qop_open,
|
||||
if (data == -1)
|
||||
ret = JS_EXCEPTION;
|
||||
else if (!data)
|
||||
ret = JS_ThrowReferenceError(js, "Empty blob");
|
||||
ret = JS_RaiseDisrupt(js, "Empty blob");
|
||||
else {
|
||||
qop_desc *qop = js_malloc(js, sizeof(qop_desc));
|
||||
if (!qop)
|
||||
ret = JS_ThrowOutOfMemory(js);
|
||||
ret = JS_RaiseOOM(js);
|
||||
else {
|
||||
int size = qop_open_data((const unsigned char *)data, len, qop);
|
||||
if (size == 0) {
|
||||
js_free(js, qop);
|
||||
ret = JS_ThrowReferenceError(js, "Failed to open QOP archive from blob");
|
||||
ret = JS_RaiseDisrupt(js, "Failed to open QOP archive from blob");
|
||||
} else {
|
||||
JSValue obj = JS_NewObjectClass(js, js_qop_archive_class_id);
|
||||
JS_SetOpaque(obj, qop);
|
||||
@@ -125,12 +125,12 @@ JSC_CCALL(qop_write,
|
||||
|
||||
FILE *fh = fopen(path, "wb");
|
||||
JS_FreeCString(js, path);
|
||||
if (!fh) return JS_ThrowInternalError(js, "Could not open file for writing");
|
||||
if (!fh) return JS_RaiseDisrupt(js, "Could not open file for writing");
|
||||
|
||||
qop_writer *w = js_malloc(js, sizeof(qop_writer));
|
||||
if (!w) {
|
||||
fclose(fh);
|
||||
return JS_ThrowOutOfMemory(js);
|
||||
return JS_RaiseOOM(js);
|
||||
}
|
||||
|
||||
w->fh = fh;
|
||||
@@ -141,7 +141,7 @@ JSC_CCALL(qop_write,
|
||||
if (!w->files) {
|
||||
fclose(fh);
|
||||
js_free(js, w);
|
||||
return JS_ThrowOutOfMemory(js);
|
||||
return JS_RaiseOOM(js);
|
||||
}
|
||||
|
||||
JSValue obj = JS_NewObjectClass(js, js_qop_writer_class_id);
|
||||
@@ -153,7 +153,7 @@ JSC_CCALL(qop_write,
|
||||
static JSValue js_qop_close(JSContext *js, JSValue self, int argc, JSValue *argv) {
|
||||
qop_desc *qop = js2qop(js, self);
|
||||
if (!qop)
|
||||
return JS_ThrowInternalError(js, "Invalid QOP archive");
|
||||
return JS_RaiseDisrupt(js, "Invalid QOP archive");
|
||||
|
||||
qop_close(qop);
|
||||
JS_SetOpaque(self, NULL); // Prevent double free
|
||||
@@ -165,7 +165,7 @@ static JSValue js_qop_close(JSContext *js, JSValue self, int argc, JSValue *argv
|
||||
static JSValue js_qop_read(JSContext *js, JSValue self, int argc, JSValue *argv) {
|
||||
qop_desc *qop = js2qop(js, self);
|
||||
if (!qop)
|
||||
return JS_ThrowInternalError(js, "Invalid QOP archive");
|
||||
return JS_RaiseDisrupt(js, "Invalid QOP archive");
|
||||
|
||||
const char *path = JS_ToCString(js, argv[0]);
|
||||
if (!path)
|
||||
@@ -173,7 +173,7 @@ static JSValue js_qop_read(JSContext *js, JSValue self, int argc, JSValue *argv)
|
||||
|
||||
if (!js_qop_ensure_index(js, qop)) {
|
||||
JS_FreeCString(js, path);
|
||||
return JS_ThrowReferenceError(js, "Failed to read QOP index");
|
||||
return JS_RaiseDisrupt(js, "Failed to read QOP index");
|
||||
}
|
||||
|
||||
qop_file *file = qop_find(qop, path);
|
||||
@@ -185,12 +185,12 @@ static JSValue js_qop_read(JSContext *js, JSValue self, int argc, JSValue *argv)
|
||||
|
||||
unsigned char *dest = js_malloc(js, file->size);
|
||||
if (!dest)
|
||||
return JS_ThrowOutOfMemory(js);
|
||||
return JS_RaiseOOM(js);
|
||||
|
||||
int bytes = qop_read(qop, file, dest);
|
||||
if (bytes == 0) {
|
||||
js_free(js, dest);
|
||||
return JS_ThrowReferenceError(js, "Failed to read file");
|
||||
return JS_RaiseDisrupt(js, "Failed to read file");
|
||||
}
|
||||
|
||||
JSValue blob = js_new_blob_stoned_copy(js, dest, bytes);
|
||||
@@ -201,7 +201,7 @@ static JSValue js_qop_read(JSContext *js, JSValue self, int argc, JSValue *argv)
|
||||
static JSValue js_qop_read_ex(JSContext *js, JSValue self, int argc, JSValue *argv) {
|
||||
qop_desc *qop = js2qop(js, self);
|
||||
if (!qop)
|
||||
return JS_ThrowInternalError(js, "Invalid QOP archive");
|
||||
return JS_RaiseDisrupt(js, "Invalid QOP archive");
|
||||
|
||||
const char *path = JS_ToCString(js, argv[0]);
|
||||
if (!path)
|
||||
@@ -209,7 +209,7 @@ static JSValue js_qop_read_ex(JSContext *js, JSValue self, int argc, JSValue *ar
|
||||
|
||||
if (!js_qop_ensure_index(js, qop)) {
|
||||
JS_FreeCString(js, path);
|
||||
return JS_ThrowReferenceError(js, "Failed to read QOP index");
|
||||
return JS_RaiseDisrupt(js, "Failed to read QOP index");
|
||||
}
|
||||
|
||||
qop_file *file = qop_find(qop, path);
|
||||
@@ -221,16 +221,16 @@ static JSValue js_qop_read_ex(JSContext *js, JSValue self, int argc, JSValue *ar
|
||||
unsigned int start;
|
||||
unsigned int len;
|
||||
if (JS_ToUint32(js, &start, argv[1]) < 0 || JS_ToUint32(js, &len, argv[2]) < 0)
|
||||
return JS_ThrowTypeError(js, "Invalid start or len");
|
||||
return JS_RaiseDisrupt(js, "Invalid start or len");
|
||||
|
||||
unsigned char *dest = js_malloc(js, len);
|
||||
if (!dest)
|
||||
return JS_ThrowOutOfMemory(js);
|
||||
return JS_RaiseOOM(js);
|
||||
|
||||
int bytes = qop_read_ex(qop, file, dest, start, len);
|
||||
if (bytes == 0) {
|
||||
js_free(js, dest);
|
||||
return JS_ThrowReferenceError(js, "Failed to read file part");
|
||||
return JS_RaiseDisrupt(js, "Failed to read file part");
|
||||
}
|
||||
|
||||
JSValue blob = js_new_blob_stoned_copy(js, dest, bytes);
|
||||
@@ -241,10 +241,10 @@ static JSValue js_qop_read_ex(JSContext *js, JSValue self, int argc, JSValue *ar
|
||||
static JSValue js_qop_list(JSContext *js, JSValue self, int argc, JSValue *argv) {
|
||||
qop_desc *qop = js2qop(js, self);
|
||||
if (!qop)
|
||||
return JS_ThrowInternalError(js, "Invalid QOP archive");
|
||||
return JS_RaiseDisrupt(js, "Invalid QOP archive");
|
||||
|
||||
if (!js_qop_ensure_index(js, qop)) {
|
||||
return JS_ThrowReferenceError(js, "Failed to read QOP index");
|
||||
return JS_RaiseDisrupt(js, "Failed to read QOP index");
|
||||
}
|
||||
|
||||
JSValue arr = JS_NewArray(js);
|
||||
@@ -256,7 +256,7 @@ static JSValue js_qop_list(JSContext *js, JSValue self, int argc, JSValue *argv)
|
||||
|
||||
char *path = js_malloc(js, file->path_len);
|
||||
if (!path) {
|
||||
return JS_ThrowOutOfMemory(js);
|
||||
return JS_RaiseOOM(js);
|
||||
}
|
||||
|
||||
int len = qop_read_path(qop, file, path);
|
||||
@@ -275,14 +275,14 @@ static JSValue js_qop_list(JSContext *js, JSValue self, int argc, JSValue *argv)
|
||||
|
||||
static JSValue js_qop_stat(JSContext *js, JSValue self, int argc, JSValue *argv) {
|
||||
qop_desc *qop = js2qop(js, self);
|
||||
if (!qop) return JS_ThrowInternalError(js, "Invalid QOP archive");
|
||||
if (!qop) return JS_RaiseDisrupt(js, "Invalid QOP archive");
|
||||
|
||||
const char *path = JS_ToCString(js, argv[0]);
|
||||
if (!path) return JS_EXCEPTION;
|
||||
|
||||
if (!js_qop_ensure_index(js, qop)) {
|
||||
JS_FreeCString(js, path);
|
||||
return JS_ThrowReferenceError(js, "Failed to read QOP index");
|
||||
return JS_RaiseDisrupt(js, "Failed to read QOP index");
|
||||
}
|
||||
|
||||
qop_file *file = qop_find(qop, path);
|
||||
@@ -299,14 +299,14 @@ static JSValue js_qop_stat(JSContext *js, JSValue self, int argc, JSValue *argv)
|
||||
|
||||
static JSValue js_qop_is_directory(JSContext *js, JSValue self, int argc, JSValue *argv) {
|
||||
qop_desc *qop = js2qop(js, self);
|
||||
if (!qop) return JS_ThrowInternalError(js, "Invalid QOP archive");
|
||||
if (!qop) return JS_RaiseDisrupt(js, "Invalid QOP archive");
|
||||
|
||||
const char *path = JS_ToCString(js, argv[0]);
|
||||
if (!path) return JS_EXCEPTION;
|
||||
|
||||
if (!js_qop_ensure_index(js, qop)) {
|
||||
JS_FreeCString(js, path);
|
||||
return JS_ThrowReferenceError(js, "Failed to read QOP index");
|
||||
return JS_RaiseDisrupt(js, "Failed to read QOP index");
|
||||
}
|
||||
|
||||
// Check if any file starts with path + "/"
|
||||
@@ -348,7 +348,7 @@ static JSValue js_qop_is_directory(JSContext *js, JSValue self, int argc, JSValu
|
||||
|
||||
static JSValue js_writer_add_file(JSContext *js, JSValue self, int argc, JSValue *argv) {
|
||||
qop_writer *w = js2writer(js, self);
|
||||
if (!w) return JS_ThrowInternalError(js, "Invalid QOP writer");
|
||||
if (!w) return JS_RaiseDisrupt(js, "Invalid QOP writer");
|
||||
|
||||
const char *path = JS_ToCString(js, argv[0]);
|
||||
if (!path) return JS_EXCEPTION;
|
||||
@@ -361,7 +361,7 @@ static JSValue js_writer_add_file(JSContext *js, JSValue self, int argc, JSValue
|
||||
}
|
||||
if (!data) {
|
||||
JS_FreeCString(js, path);
|
||||
return JS_ThrowTypeError(js, "No blob data present");
|
||||
return JS_RaiseDisrupt(js, "No blob data present");
|
||||
}
|
||||
|
||||
if (w->len >= w->capacity) {
|
||||
@@ -369,7 +369,7 @@ static JSValue js_writer_add_file(JSContext *js, JSValue self, int argc, JSValue
|
||||
qop_file *new_files = js_realloc(js, w->files, sizeof(qop_file) * w->capacity);
|
||||
if (!new_files) {
|
||||
JS_FreeCString(js, path);
|
||||
return JS_ThrowOutOfMemory(js);
|
||||
return JS_RaiseOOM(js);
|
||||
}
|
||||
w->files = new_files;
|
||||
}
|
||||
@@ -406,7 +406,7 @@ static JSValue js_writer_add_file(JSContext *js, JSValue self, int argc, JSValue
|
||||
|
||||
static JSValue js_writer_finalize(JSContext *js, JSValue self, int argc, JSValue *argv) {
|
||||
qop_writer *w = js2writer(js, self);
|
||||
if (!w || !w->fh) return JS_ThrowInternalError(js, "Invalid QOP writer or already closed");
|
||||
if (!w || !w->fh) return JS_RaiseDisrupt(js, "Invalid QOP writer or already closed");
|
||||
|
||||
unsigned int total_size = w->size + 12; // Header size
|
||||
|
||||
|
||||
@@ -189,6 +189,12 @@ JS_SetClassProto(js, js_##TYPE##_id, TYPE##_proto); \
|
||||
return JS_EXCEPTION; \
|
||||
} while (0)
|
||||
|
||||
// Safe integer property extraction (null → 0)
|
||||
#define JS_GETINT(JS, TARGET, VALUE, PROP) { \
|
||||
JSValue __##PROP##__v = JS_GetPropertyStr(JS, VALUE, #PROP); \
|
||||
TARGET = JS_IsNull(__##PROP##__v) ? 0 : (int)js2number(JS, __##PROP##__v); \
|
||||
JS_FreeValue(JS, __##PROP##__v); }
|
||||
|
||||
// Common macros for property access
|
||||
#define JS_GETPROP(JS, TARGET, VALUE, PROP, TYPE) {\
|
||||
JSValue __##PROP##__v = JS_GetPropertyStr(JS,VALUE,#PROP); \
|
||||
|
||||
@@ -675,7 +675,7 @@ static JSValue reg_vm_binop(JSContext *ctx, int op, JSValue a, JSValue b) {
|
||||
}
|
||||
|
||||
/* Type mismatch — disrupt */
|
||||
return JS_ThrowTypeError(ctx, "type mismatch in binary operation");
|
||||
return JS_RaiseDisrupt(ctx, "type mismatch in binary operation");
|
||||
}
|
||||
|
||||
|
||||
@@ -809,7 +809,7 @@ vm_dispatch:
|
||||
if (pc >= code->instr_count) {
|
||||
fprintf(stderr, "mach VM: pc %u overran code->instr_count %u (missing RETURN/RETNIL?)\n",
|
||||
pc, code->instr_count);
|
||||
result = JS_ThrowInternalError(ctx, "pc overrun");
|
||||
result = JS_RaiseDisrupt(ctx, "pc overrun");
|
||||
goto done;
|
||||
}
|
||||
#endif
|
||||
@@ -886,6 +886,8 @@ vm_dispatch:
|
||||
};
|
||||
#undef DT
|
||||
#define VM_DECODE() do { \
|
||||
ctx->reg_current_frame = frame_ref.val; \
|
||||
ctx->current_register_pc = pc; \
|
||||
instr = code->instructions[pc++]; \
|
||||
op = MACH_GET_OP(instr); \
|
||||
a = MACH_GET_A(instr); \
|
||||
@@ -899,6 +901,8 @@ vm_dispatch:
|
||||
#define VM_BREAK() VM_DISPATCH()
|
||||
#else
|
||||
#define VM_DECODE() do { \
|
||||
ctx->reg_current_frame = frame_ref.val; \
|
||||
ctx->current_register_pc = pc; \
|
||||
instr = code->instructions[pc++]; \
|
||||
op = MACH_GET_OP(instr); \
|
||||
a = MACH_GET_A(instr); \
|
||||
@@ -1258,7 +1262,7 @@ vm_dispatch:
|
||||
if (mist_is_function(obj)) {
|
||||
JSFunction *fn_chk = JS_VALUE_GET_FUNCTION(obj);
|
||||
if (fn_chk->length != 2) {
|
||||
JS_ThrowTypeError(ctx, "cannot read property of non-proxy function");
|
||||
JS_RaiseDisrupt(ctx, "cannot read property of non-proxy function");
|
||||
frame = (JSFrameRegister *)JS_VALUE_GET_PTR(frame_ref.val);
|
||||
goto disrupt;
|
||||
}
|
||||
@@ -1314,7 +1318,7 @@ vm_dispatch:
|
||||
if (has <= 0) {
|
||||
char buf[128];
|
||||
JS_KeyGetStr(ctx, buf, sizeof(buf), key);
|
||||
JS_ThrowReferenceError(ctx, "'%s' is not defined", buf);
|
||||
JS_RaiseDisrupt(ctx, "'%s' is not defined", buf);
|
||||
goto disrupt;
|
||||
}
|
||||
}
|
||||
@@ -1359,7 +1363,7 @@ vm_dispatch:
|
||||
if (!target) {
|
||||
fprintf(stderr, "GETUP: NULL outer_frame at depth 0! pc=%d a=%d depth=%d slot=%d nr_slots=%d instr=0x%08x\n",
|
||||
pc-1, a, depth, c, code->nr_slots, instr);
|
||||
result = JS_ThrowInternalError(ctx, "GETUP: NULL outer_frame");
|
||||
result = JS_RaiseDisrupt(ctx, "GETUP: NULL outer_frame");
|
||||
goto disrupt;
|
||||
}
|
||||
for (int d = 1; d < depth; d++) {
|
||||
@@ -1368,7 +1372,7 @@ vm_dispatch:
|
||||
if (!next) {
|
||||
fprintf(stderr, "GETUP: NULL outer_frame at depth %d! pc=%d a=%d depth=%d slot=%d nr_slots=%d instr=0x%08x\n",
|
||||
d, pc-1, a, depth, c, code->nr_slots, instr);
|
||||
result = JS_ThrowInternalError(ctx, "GETUP: NULL outer_frame at depth %d", d);
|
||||
result = JS_RaiseDisrupt(ctx, "GETUP: NULL outer_frame at depth %d", d);
|
||||
goto disrupt;
|
||||
}
|
||||
target = next;
|
||||
@@ -1396,7 +1400,7 @@ vm_dispatch:
|
||||
if (offset < 0) {
|
||||
int pf = atomic_load_explicit(&ctx->pause_flag, memory_order_relaxed);
|
||||
if (pf == 2) {
|
||||
result = JS_ThrowInternalError(ctx, "interrupted");
|
||||
result = JS_RaiseDisrupt(ctx, "interrupted");
|
||||
goto done;
|
||||
}
|
||||
if (pf == 1) {
|
||||
@@ -1421,7 +1425,7 @@ vm_dispatch:
|
||||
if (offset < 0) {
|
||||
int pf = atomic_load_explicit(&ctx->pause_flag, memory_order_relaxed);
|
||||
if (pf == 2) {
|
||||
result = JS_ThrowInternalError(ctx, "interrupted");
|
||||
result = JS_RaiseDisrupt(ctx, "interrupted");
|
||||
goto done;
|
||||
}
|
||||
if (pf == 1) {
|
||||
@@ -1447,7 +1451,7 @@ vm_dispatch:
|
||||
if (offset < 0) {
|
||||
int pf = atomic_load_explicit(&ctx->pause_flag, memory_order_relaxed);
|
||||
if (pf == 2) {
|
||||
result = JS_ThrowInternalError(ctx, "interrupted");
|
||||
result = JS_RaiseDisrupt(ctx, "interrupted");
|
||||
goto done;
|
||||
}
|
||||
if (pf == 1) {
|
||||
@@ -1817,7 +1821,7 @@ vm_dispatch:
|
||||
JSValue obj = frame->slots[b];
|
||||
JSValue key = code->cpool[c];
|
||||
if (mist_is_function(obj)) {
|
||||
JS_ThrowTypeError(ctx, "cannot read property of function");
|
||||
JS_RaiseDisrupt(ctx, "cannot read property of function");
|
||||
frame = (JSFrameRegister *)JS_VALUE_GET_PTR(frame_ref.val);
|
||||
goto disrupt;
|
||||
}
|
||||
@@ -1878,10 +1882,10 @@ vm_dispatch:
|
||||
JSValue r = JS_SetPropertyNumber(ctx, obj, JS_VALUE_GET_INT(key), val);
|
||||
ret = JS_IsException(r) ? -1 : 0;
|
||||
} else if (mist_is_array(obj)) {
|
||||
JS_ThrowTypeError(ctx, "array index must be a number");
|
||||
JS_RaiseDisrupt(ctx, "array index must be a number");
|
||||
ret = -1;
|
||||
} else if (JS_IsBool(key) || JS_IsNull(key) || mist_is_array(key) || mist_is_function(key)) {
|
||||
JS_ThrowTypeError(ctx, "object key must be text");
|
||||
JS_RaiseDisrupt(ctx, "object key must be text");
|
||||
ret = -1;
|
||||
} else {
|
||||
ret = JS_SetProperty(ctx, obj, key, val);
|
||||
@@ -1907,7 +1911,7 @@ vm_dispatch:
|
||||
/* A=frame_slot, B=func_reg, C=argc */
|
||||
JSValue func_val = frame->slots[b];
|
||||
if (!mist_is_function(func_val)) {
|
||||
JS_ThrowTypeError(ctx, "not a function");
|
||||
JS_RaiseDisrupt(ctx, "not a function");
|
||||
frame = (JSFrameRegister *)JS_VALUE_GET_PTR(frame_ref.val);
|
||||
goto disrupt;
|
||||
}
|
||||
@@ -2105,7 +2109,7 @@ vm_dispatch:
|
||||
}
|
||||
|
||||
VM_DEFAULT:
|
||||
result = JS_ThrowInternalError(ctx, "unknown register VM opcode %d: %s", op, mach_opcode_names[op]);
|
||||
result = JS_RaiseDisrupt(ctx, "unknown register VM opcode %d: %s", op, mach_opcode_names[op]);
|
||||
goto done;
|
||||
}
|
||||
continue;
|
||||
@@ -2136,49 +2140,11 @@ vm_dispatch:
|
||||
break;
|
||||
}
|
||||
if (JS_IsNull(frame->caller)) {
|
||||
if (!ctx->disruption_reported) {
|
||||
/* Use faulting frame (frame_ref.val) for the header */
|
||||
JSFrameRegister *fault = (JSFrameRegister *)JS_VALUE_GET_PTR(frame_ref.val);
|
||||
JSFunction *fault_fn = JS_VALUE_GET_FUNCTION(fault->function);
|
||||
JSCodeRegister *fault_code = fault_fn->u.reg.code;
|
||||
const char *fn_name = fault_code->name_cstr ? fault_code->name_cstr : "<anonymous>";
|
||||
const char *file = fault_code->filename_cstr ? fault_code->filename_cstr : "<unknown>";
|
||||
uint16_t line = 0, col = 0;
|
||||
uint32_t fpc = pc > 0 ? pc - 1 : 0;
|
||||
if (fault_code->line_table && fpc < fault_code->instr_count) {
|
||||
line = fault_code->line_table[fpc].line;
|
||||
col = fault_code->line_table[fpc].col;
|
||||
}
|
||||
fprintf(stderr, "unhandled disruption in %s (%s:%u:%u)\n", fn_name, file, line, col);
|
||||
/* Walk intact caller chain for stack trace */
|
||||
{
|
||||
JSFrameRegister *trace_frame = fault;
|
||||
int first = 1;
|
||||
while (trace_frame) {
|
||||
if (!mist_is_function(trace_frame->function)) break;
|
||||
JSFunction *trace_fn = JS_VALUE_GET_FUNCTION(trace_frame->function);
|
||||
if (trace_fn->kind == JS_FUNC_KIND_REGISTER && trace_fn->u.reg.code) {
|
||||
JSCodeRegister *tc = trace_fn->u.reg.code;
|
||||
uint32_t tpc = first ? fpc
|
||||
: (uint32_t)(JS_VALUE_GET_INT(trace_frame->address) >> 16);
|
||||
uint16_t tl = 0, tcol = 0;
|
||||
if (tc->line_table && tpc < tc->instr_count) {
|
||||
tl = tc->line_table[tpc].line;
|
||||
tcol = tc->line_table[tpc].col;
|
||||
}
|
||||
fprintf(stderr, " at %s (%s:%u:%u)\n",
|
||||
tc->name_cstr ? tc->name_cstr : "<anonymous>",
|
||||
tc->filename_cstr ? tc->filename_cstr : "<unknown>", tl, tcol);
|
||||
}
|
||||
if (JS_IsNull(trace_frame->caller)) break;
|
||||
trace_frame = (JSFrameRegister *)JS_VALUE_GET_PTR(trace_frame->caller);
|
||||
first = 0;
|
||||
}
|
||||
}
|
||||
ctx->disruption_reported = TRUE;
|
||||
}
|
||||
/* Stack trace was already included in the JS_RaiseDisrupt log via the callback. */
|
||||
ctx->disruption_reported = TRUE;
|
||||
frame_ref.val = JS_MKPTR(frame); /* update root for GC / done */
|
||||
result = JS_Throw(ctx, JS_NULL);
|
||||
ctx->current_exception = JS_NULL;
|
||||
result = JS_EXCEPTION;
|
||||
frame = (JSFrameRegister *)JS_VALUE_GET_PTR(frame_ref.val);
|
||||
goto done;
|
||||
}
|
||||
@@ -2215,7 +2181,7 @@ done:
|
||||
|
||||
JSValue JS_ResumeRegisterVM(JSContext *ctx) {
|
||||
if (!ctx->suspended)
|
||||
return JS_ThrowInternalError(ctx, "no suspended VM to resume");
|
||||
return JS_RaiseDisrupt(ctx, "no suspended VM to resume");
|
||||
/* ctx->suspended is set; JS_CallRegisterVM will take the resume path */
|
||||
return JS_CallRegisterVM(ctx, NULL, JS_NULL, 0, NULL, JS_NULL, JS_NULL);
|
||||
}
|
||||
@@ -3057,7 +3023,7 @@ static void dump_register_code(JSContext *ctx, JSCodeRegister *code, int indent)
|
||||
JSValue JS_RunMachBin(JSContext *ctx, const uint8_t *data, size_t size, JSValue env) {
|
||||
MachCode *mc = JS_DeserializeMachCode(data, size);
|
||||
if (!mc)
|
||||
return JS_ThrowSyntaxError(ctx, "failed to deserialize MACH bytecode");
|
||||
return JS_RaiseDisrupt(ctx, "failed to deserialize MACH bytecode");
|
||||
|
||||
JSGCRef env_ref;
|
||||
JS_PushGCRef(ctx, &env_ref);
|
||||
@@ -3075,12 +3041,12 @@ JSValue JS_RunMachMcode(JSContext *ctx, const char *json_str, size_t len, JSValu
|
||||
(void)len;
|
||||
cJSON *mcode = cJSON_Parse(json_str);
|
||||
if (!mcode)
|
||||
return JS_ThrowSyntaxError(ctx, "failed to parse mcode JSON");
|
||||
return JS_RaiseDisrupt(ctx, "failed to parse mcode JSON");
|
||||
|
||||
MachCode *mc = mach_compile_mcode(mcode);
|
||||
cJSON_Delete(mcode);
|
||||
if (!mc)
|
||||
return JS_ThrowInternalError(ctx, "mcode compilation failed");
|
||||
return JS_RaiseDisrupt(ctx, "mcode compilation failed");
|
||||
|
||||
JSGCRef env_ref;
|
||||
JS_PushGCRef(ctx, &env_ref);
|
||||
|
||||
@@ -109,7 +109,7 @@ static void qbe_dbgfile(char *fn) {
|
||||
*/
|
||||
JSValue js_os_qbe(JSContext *js, JSValue self, int argc, JSValue *argv) {
|
||||
if (argc < 1)
|
||||
return JS_ThrowTypeError(js, "os.qbe requires an IR string argument");
|
||||
return JS_RaiseDisrupt(js, "os.qbe requires an IR string argument");
|
||||
|
||||
const char *ir = JS_ToCString(js, argv[0]);
|
||||
if (!ir)
|
||||
@@ -140,7 +140,7 @@ JSValue js_os_qbe(JSContext *js, JSValue self, int argc, JSValue *argv) {
|
||||
FILE *inf = fmemopen((void *)ir, ir_len, "r");
|
||||
if (!inf) {
|
||||
JS_FreeCString(js, ir);
|
||||
return JS_ThrowInternalError(js, "os.qbe: fmemopen failed");
|
||||
return JS_RaiseDisrupt(js, "os.qbe: fmemopen failed");
|
||||
}
|
||||
|
||||
/* Open output memory stream */
|
||||
@@ -150,7 +150,7 @@ JSValue js_os_qbe(JSContext *js, JSValue self, int argc, JSValue *argv) {
|
||||
if (!qbe_outf) {
|
||||
fclose(inf);
|
||||
JS_FreeCString(js, ir);
|
||||
return JS_ThrowInternalError(js, "os.qbe: open_memstream failed");
|
||||
return JS_RaiseDisrupt(js, "os.qbe: open_memstream failed");
|
||||
}
|
||||
|
||||
/* Run the QBE pipeline */
|
||||
|
||||
@@ -58,7 +58,7 @@ JSValue cell_rt_add(JSContext *ctx, JSValue a, JSValue b) {
|
||||
return JS_ConcatString(ctx, a, b);
|
||||
if (JS_IsNumber(a) && JS_IsNumber(b))
|
||||
return qbe_float_binop(ctx, a, b, op_add);
|
||||
JS_ThrowTypeError(ctx, "cannot add incompatible types");
|
||||
JS_RaiseDisrupt(ctx, "cannot add incompatible types");
|
||||
return JS_NULL;
|
||||
}
|
||||
|
||||
@@ -224,7 +224,7 @@ JSValue qbe_shift_shr(JSContext *ctx, JSValue a, JSValue b) {
|
||||
|
||||
JSValue cell_rt_load_field(JSContext *ctx, JSValue obj, const char *name) {
|
||||
if (JS_IsFunction(obj)) {
|
||||
JS_ThrowTypeError(ctx, "cannot read property of function");
|
||||
JS_RaiseDisrupt(ctx, "cannot read property of function");
|
||||
return JS_EXCEPTION;
|
||||
}
|
||||
return JS_GetPropertyStr(ctx, obj, name);
|
||||
@@ -252,9 +252,9 @@ void cell_rt_store_dynamic(JSContext *ctx, JSValue val, JSValue obj,
|
||||
if (JS_IsInt(key)) {
|
||||
JS_SetPropertyNumber(ctx, obj, (uint32_t)JS_VALUE_GET_INT(key), val);
|
||||
} else if (JS_IsArray(obj) && !JS_IsInt(key)) {
|
||||
JS_ThrowTypeError(ctx, "array index must be a number");
|
||||
JS_RaiseDisrupt(ctx, "array index must be a number");
|
||||
} else if (JS_IsBool(key) || JS_IsNull(key) || JS_IsArray(key) || JS_IsFunction(key)) {
|
||||
JS_ThrowTypeError(ctx, "object key must be text");
|
||||
JS_RaiseDisrupt(ctx, "object key must be text");
|
||||
} else {
|
||||
JS_SetProperty(ctx, obj, key, val);
|
||||
}
|
||||
@@ -315,7 +315,7 @@ JSValue cell_rt_get_intrinsic(JSContext *ctx, const char *name) {
|
||||
return rec->slots[i].val;
|
||||
}
|
||||
}
|
||||
JS_ThrowReferenceError(ctx, "'%s' is not defined", name);
|
||||
JS_RaiseDisrupt(ctx, "'%s' is not defined", name);
|
||||
return JS_EXCEPTION;
|
||||
}
|
||||
|
||||
@@ -383,7 +383,7 @@ static int stack_space_ok(void) {
|
||||
|
||||
JSValue *cell_rt_enter_frame(JSContext *ctx, int64_t nr_slots) {
|
||||
if (g_aot_depth >= MAX_AOT_DEPTH || !stack_space_ok()) {
|
||||
JS_ThrowTypeError(ctx, "native call stack overflow (depth %d)", g_aot_depth);
|
||||
JS_RaiseDisrupt(ctx, "native call stack overflow (depth %d)", g_aot_depth);
|
||||
return NULL;
|
||||
}
|
||||
JSFrameRegister *frame = alloc_frame_register(ctx, (int)nr_slots);
|
||||
@@ -481,7 +481,7 @@ static void reclaim_native_fns(JSContext *ctx, int saved_count) {
|
||||
static JSValue cell_fn_trampoline(JSContext *ctx, JSValue this_val,
|
||||
int argc, JSValue *argv, int magic) {
|
||||
if (magic < 0 || magic >= g_native_fn_count)
|
||||
return JS_ThrowTypeError(ctx, "invalid native function id %d", magic);
|
||||
return JS_RaiseDisrupt(ctx, "invalid native function id %d", magic);
|
||||
|
||||
void *handle = g_native_fn_registry[magic].dl_handle;
|
||||
int fn_idx = g_native_fn_registry[magic].fn_idx;
|
||||
@@ -491,7 +491,7 @@ static JSValue cell_fn_trampoline(JSContext *ctx, JSValue this_val,
|
||||
|
||||
cell_compiled_fn fn = (cell_compiled_fn)dlsym(handle, name);
|
||||
if (!fn)
|
||||
return JS_ThrowTypeError(ctx, "native function %s not found in dylib", name);
|
||||
return JS_RaiseDisrupt(ctx, "native function %s not found in dylib", name);
|
||||
|
||||
/* Allocate GC-managed frame: slot 0 = this, slots 1..argc = args */
|
||||
JSValue *fp = cell_rt_enter_frame(ctx, 512);
|
||||
@@ -527,7 +527,7 @@ static JSValue cell_fn_trampoline(JSContext *ctx, JSValue this_val,
|
||||
/* Ensure there is a pending exception. QBE @_exc_ret returns 15
|
||||
but may not have set one (e.g. if cell_rt_enter_frame failed). */
|
||||
if (!JS_HasException(ctx))
|
||||
JS_Throw(ctx, JS_NULL);
|
||||
ctx->current_exception = JS_NULL;
|
||||
return JS_EXCEPTION;
|
||||
}
|
||||
return result;
|
||||
@@ -537,7 +537,7 @@ JSValue cell_rt_make_function(JSContext *ctx, int64_t fn_idx, void *outer_fp,
|
||||
int64_t nr_args) {
|
||||
(void)outer_fp;
|
||||
if (g_native_fn_count >= MAX_NATIVE_FN)
|
||||
return JS_ThrowTypeError(ctx, "too many native functions (max %d)", MAX_NATIVE_FN);
|
||||
return JS_RaiseDisrupt(ctx, "too many native functions (max %d)", MAX_NATIVE_FN);
|
||||
|
||||
int global_id = g_native_fn_count++;
|
||||
g_native_fn_registry[global_id].dl_handle = g_current_dl_handle;
|
||||
@@ -562,7 +562,7 @@ JSValue cell_rt_make_function(JSContext *ctx, int64_t fn_idx, void *outer_fp,
|
||||
|
||||
JSValue cell_rt_frame(JSContext *ctx, JSValue fn, int64_t nargs) {
|
||||
if (!JS_IsFunction(fn)) {
|
||||
JS_ThrowTypeError(ctx, "not a function");
|
||||
JS_RaiseDisrupt(ctx, "not a function");
|
||||
return JS_EXCEPTION;
|
||||
}
|
||||
int nr_slots = (int)nargs + 2;
|
||||
@@ -586,7 +586,7 @@ JSValue cell_rt_invoke(JSContext *ctx, JSValue frame_val) {
|
||||
JSValue fn_val = fr->function;
|
||||
|
||||
if (!JS_IsFunction(fn_val)) {
|
||||
JS_ThrowTypeError(ctx, "not a function");
|
||||
JS_RaiseDisrupt(ctx, "not a function");
|
||||
return JS_EXCEPTION;
|
||||
}
|
||||
|
||||
@@ -766,7 +766,7 @@ void cell_rt_clear_exception(JSContext *ctx) {
|
||||
/* --- Disruption --- */
|
||||
|
||||
void cell_rt_disrupt(JSContext *ctx) {
|
||||
JS_ThrowTypeError(ctx, "type error in native code");
|
||||
JS_RaiseDisrupt(ctx, "type error in native code");
|
||||
}
|
||||
|
||||
/* --- in: key in obj --- */
|
||||
@@ -796,7 +796,7 @@ JSValue cell_rt_regexp(JSContext *ctx, const char *pattern, const char *flags) {
|
||||
JSValue cell_rt_native_module_load(JSContext *ctx, void *dl_handle, JSValue env) {
|
||||
cell_compiled_fn fn = (cell_compiled_fn)dlsym(dl_handle, "cell_main");
|
||||
if (!fn)
|
||||
return JS_ThrowTypeError(ctx, "cell_main not found in native module dylib");
|
||||
return JS_RaiseDisrupt(ctx, "cell_main not found in native module dylib");
|
||||
|
||||
/* Set current handle so cell_rt_make_function registers closures
|
||||
against this module's dylib */
|
||||
@@ -810,7 +810,7 @@ JSValue cell_rt_native_module_load(JSContext *ctx, void *dl_handle, JSValue env)
|
||||
JSValue *fp = cell_rt_enter_frame(ctx, 512);
|
||||
if (!fp) {
|
||||
g_current_dl_handle = prev_handle;
|
||||
return JS_ThrowTypeError(ctx, "frame allocation failed");
|
||||
return JS_RaiseDisrupt(ctx, "frame allocation failed");
|
||||
}
|
||||
|
||||
/* Clear any stale exception left by a previous interpreted run */
|
||||
@@ -834,7 +834,7 @@ JSValue cell_rt_native_module_load_named(JSContext *ctx, void *dl_handle, const
|
||||
if (!fn)
|
||||
fn = (cell_compiled_fn)dlsym(dl_handle, "cell_main");
|
||||
if (!fn)
|
||||
return JS_ThrowTypeError(ctx, "symbol not found in native module dylib");
|
||||
return JS_RaiseDisrupt(ctx, "symbol not found in native module dylib");
|
||||
|
||||
void *prev_handle = g_current_dl_handle;
|
||||
g_current_dl_handle = dl_handle;
|
||||
@@ -845,7 +845,7 @@ JSValue cell_rt_native_module_load_named(JSContext *ctx, void *dl_handle, const
|
||||
JSValue *fp = cell_rt_enter_frame(ctx, 512);
|
||||
if (!fp) {
|
||||
g_current_dl_handle = prev_handle;
|
||||
return JS_ThrowTypeError(ctx, "frame allocation failed");
|
||||
return JS_RaiseDisrupt(ctx, "frame allocation failed");
|
||||
}
|
||||
|
||||
JSValue result = fn(ctx, fp);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "cell.h"
|
||||
#include "cell_internal.h"
|
||||
#include "quickjs-internal.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -7,24 +8,24 @@
|
||||
JSC_CCALL(os_createactor,
|
||||
cell_rt *rt = JS_GetContextOpaque(js);
|
||||
if (rt->disrupt)
|
||||
return JS_ThrowInternalError(js, "Can't start a new actor while disrupting.");
|
||||
return JS_RaiseDisrupt(js, "Can't start a new actor while disrupting.");
|
||||
|
||||
void *startup = value2wota(js, argv[0], JS_NULL, NULL);
|
||||
if (!startup)
|
||||
return JS_ThrowInternalError(js, "Failed to encode startup data");
|
||||
return JS_RaiseDisrupt(js, "Failed to encode startup data");
|
||||
create_actor(startup);
|
||||
)
|
||||
|
||||
JSC_CCALL(os_mailbox_push,
|
||||
if (argc < 2) return JS_ThrowInternalError(js, "Need an actor and a message");
|
||||
if (!js_is_blob(js, argv[1])) return JS_ThrowInternalError(js, "Can only send blobs.");
|
||||
if (argc < 2) return JS_RaiseDisrupt(js, "Need an actor and a message");
|
||||
if (!js_is_blob(js, argv[1])) return JS_RaiseDisrupt(js, "Can only send blobs.");
|
||||
|
||||
const char *id = JS_ToCString(js, argv[0]);
|
||||
int exist = actor_exists(id);
|
||||
|
||||
if (!exist) {
|
||||
JS_FreeCString(js, id);
|
||||
return JS_ThrowInternalError(js, "No mailbox found for given ID");
|
||||
return JS_RaiseDisrupt(js, "No mailbox found for given ID");
|
||||
}
|
||||
|
||||
size_t size;
|
||||
@@ -35,13 +36,13 @@ JSC_CCALL(os_mailbox_push,
|
||||
}
|
||||
if (size == 0) {
|
||||
JS_FreeCString(js, id);
|
||||
return JS_ThrowInternalError(js, "No data present in blob");
|
||||
return JS_RaiseDisrupt(js, "No data present in blob");
|
||||
}
|
||||
|
||||
blob *msg_blob = blob_new(size * 8);
|
||||
if (!msg_blob) {
|
||||
JS_FreeCString(js, id);
|
||||
return JS_ThrowInternalError(js, "Could not allocate blob");
|
||||
return JS_RaiseDisrupt(js, "Could not allocate blob");
|
||||
}
|
||||
|
||||
blob_write_bytes(msg_blob, data, size);
|
||||
@@ -51,7 +52,7 @@ JSC_CCALL(os_mailbox_push,
|
||||
JS_FreeCString(js, id);
|
||||
if (err) {
|
||||
blob_destroy(msg_blob);
|
||||
return JS_ThrowInternalError(js, "Could not send message: %s", err);
|
||||
return JS_RaiseDisrupt(js, "Could not send message: %s", err);
|
||||
}
|
||||
)
|
||||
|
||||
@@ -61,7 +62,7 @@ JSC_CCALL(os_register_actor,
|
||||
double ar;
|
||||
JS_ToFloat64(js, &ar, argv[3]);
|
||||
const char *err = register_actor(id, rt, JS_ToBool(js, argv[2]), ar);
|
||||
if (err) return JS_ThrowInternalError(js, "Could not register actor: %s", err);
|
||||
if (err) return JS_RaiseDisrupt(js, "Could not register actor: %s", err);
|
||||
rt->message_handle_ref.val = argv[1];
|
||||
rt->context = js;
|
||||
JS_FreeCString(js, id);
|
||||
@@ -99,7 +100,7 @@ JSC_CCALL(actor_on_exception,
|
||||
|
||||
JSC_CCALL(actor_clock,
|
||||
if (!JS_IsFunction(argv[0]))
|
||||
return JS_ThrowReferenceError(js, "Argument must be a function.");
|
||||
return JS_RaiseDisrupt(js, "Argument must be a function.");
|
||||
|
||||
cell_rt *actor = JS_GetContextOpaque(js);
|
||||
actor_clock(actor, argv[0]);
|
||||
@@ -107,7 +108,7 @@ JSC_CCALL(actor_clock,
|
||||
|
||||
JSC_CCALL(actor_delay,
|
||||
if (!JS_IsFunction(argv[0]))
|
||||
return JS_ThrowReferenceError(js, "Argument must be a function.");
|
||||
return JS_RaiseDisrupt(js, "Argument must be a function.");
|
||||
|
||||
cell_rt *actor = JS_GetContextOpaque(js);
|
||||
double seconds;
|
||||
@@ -129,6 +130,32 @@ JSC_CCALL(actor_removetimer,
|
||||
JS_FreeValue(js, removed);
|
||||
)
|
||||
|
||||
/* Log callback bridge: called from JS_Log, calls ƿit log(channel, [msg, stack])
|
||||
Captures the register VM stack trace so the log system can show the real error site. */
|
||||
static void js_log_callback(JSContext *ctx, const char *channel, const char *msg) {
|
||||
if (JS_IsNull(ctx->log_callback_js)) {
|
||||
fprintf(stderr, "%s\n", msg);
|
||||
return;
|
||||
}
|
||||
JS_FRAME(ctx);
|
||||
JS_ROOT(stack, JS_GetStack(ctx));
|
||||
JS_ROOT(args_array, JS_NewArray(ctx));
|
||||
JS_SetPropertyNumber(ctx, args_array.val, 0, JS_NewString(ctx, msg));
|
||||
JS_SetPropertyNumber(ctx, args_array.val, 1, stack.val);
|
||||
JSValue argv[2];
|
||||
argv[0] = JS_NewString(ctx, channel);
|
||||
argv[1] = args_array.val;
|
||||
JS_Call(ctx, ctx->log_callback_js, JS_NULL, 2, argv);
|
||||
JS_RestoreFrame(ctx, _js_gc_frame, _js_local_frame);
|
||||
}
|
||||
|
||||
JSC_CCALL(actor_set_log,
|
||||
if (argc < 1 || !JS_IsFunction(argv[0]))
|
||||
return JS_RaiseDisrupt(js, "set_log requires a function");
|
||||
js->log_callback_js = argv[0];
|
||||
js->log_callback = js_log_callback;
|
||||
)
|
||||
|
||||
static const JSCFunctionListEntry js_actor_funcs[] = {
|
||||
MIST_FUNC_DEF(os, createactor, 1),
|
||||
MIST_FUNC_DEF(os, mailbox_push, 2),
|
||||
@@ -141,6 +168,7 @@ static const JSCFunctionListEntry js_actor_funcs[] = {
|
||||
MIST_FUNC_DEF(actor, setname, 1),
|
||||
MIST_FUNC_DEF(actor, on_exception, 1),
|
||||
MIST_FUNC_DEF(actor, clock, 1),
|
||||
MIST_FUNC_DEF(actor, set_log, 1),
|
||||
};
|
||||
|
||||
JSValue js_core_actor_use(JSContext *js) {
|
||||
|
||||
@@ -264,18 +264,9 @@ enum {
|
||||
JS_CLASS_INIT_COUNT, /* last entry for predefined classes */
|
||||
};
|
||||
|
||||
typedef enum JSErrorEnum {
|
||||
JS_EVAL_ERROR,
|
||||
JS_RANGE_ERROR,
|
||||
JS_REFERENCE_ERROR,
|
||||
JS_SYNTAX_ERROR,
|
||||
JS_TYPE_ERROR,
|
||||
JS_URI_ERROR,
|
||||
JS_INTERNAL_ERROR,
|
||||
JS_AGGREGATE_ERROR,
|
||||
|
||||
JS_NATIVE_ERROR_COUNT, /* number of different error name strings */
|
||||
} JSErrorEnum;
|
||||
/* Log callback — set by engine.cm via $_set_log to route JS_Log through ƿit.
|
||||
For "memory" channel (OOM), the callback is skipped (can't allocate). */
|
||||
typedef void (*JSLogCallback)(JSContext *ctx, const char *channel, const char *msg);
|
||||
|
||||
/* the variable and scope indexes must fit on 16 bits. The (-1) and
|
||||
ARG_SCOPE_END values are reserved. */
|
||||
@@ -313,8 +304,8 @@ void heap_check_fail(void *ptr, struct JSContext *ctx);
|
||||
/* Compatibility: JS_TAG_STRING is an alias for text type checks */
|
||||
#define JS_TAG_STRING JS_TAG_STRING_IMM
|
||||
|
||||
/* JS_ThrowMemoryError is an alias for JS_ThrowOutOfMemory */
|
||||
#define JS_ThrowMemoryError(ctx) JS_ThrowOutOfMemory(ctx)
|
||||
/* JS_ThrowMemoryError is an alias for JS_RaiseOOM */
|
||||
#define JS_ThrowMemoryError(ctx) JS_RaiseOOM(ctx)
|
||||
|
||||
/* Helper to set cap in objhdr */
|
||||
static inline objhdr_t objhdr_set_cap56 (objhdr_t h, uint64_t cap) {
|
||||
@@ -1146,6 +1137,10 @@ struct JSContext {
|
||||
|
||||
JS_BOOL disruption_reported;
|
||||
|
||||
/* Log routing — set by $_set_log intrinsic */
|
||||
JSLogCallback log_callback;
|
||||
JSValue log_callback_js; /* the ƿit log function (rooted) */
|
||||
|
||||
/* Actor identity key — used by wota/nota PRIVATE serialization */
|
||||
JSValue actor_sym;
|
||||
|
||||
@@ -1365,7 +1360,7 @@ JSValue JS_CallInternal (JSContext *ctx, JSValue func_obj, JSValue this_obj, int
|
||||
JSValue JS_CallRegisterVM(JSContext *ctx, JSCodeRegister *code, JSValue this_obj, int argc, JSValue *argv, JSValue env, JSValue outer_frame);
|
||||
int JS_DeleteProperty (JSContext *ctx, JSValue obj, JSValue prop);
|
||||
JSValue __attribute__ ((format (printf, 2, 3)))
|
||||
JS_ThrowInternalError (JSContext *ctx, const char *fmt, ...);
|
||||
JS_RaiseDisrupt (JSContext *ctx, const char *fmt, ...);
|
||||
__maybe_unused void JS_DumpString (JSRuntime *rt, const JSText *text);
|
||||
__maybe_unused void JS_DumpObjectHeader (JSRuntime *rt);
|
||||
__maybe_unused void JS_DumpObject (JSRuntime *rt, JSRecord *rec);
|
||||
@@ -1428,7 +1423,7 @@ static JSValue js_cell_object (JSContext *ctx, JSValue this_val, int argc, JSVal
|
||||
static JSValue js_cell_text_format (JSContext *ctx, JSValue this_val, int argc, JSValue *argv);
|
||||
static JSValue js_print (JSContext *ctx, JSValue this_val, int argc, JSValue *argv);
|
||||
JSValue JS_GetStack(JSContext *ctx);
|
||||
JSValue JS_ThrowOutOfMemory (JSContext *ctx);
|
||||
JSValue JS_RaiseOOM (JSContext *ctx);
|
||||
|
||||
|
||||
JSValue JS_ToNumber (JSContext *ctx, JSValue val);
|
||||
@@ -1536,11 +1531,9 @@ static inline void set_value (JSContext *ctx, JSValue *pval, JSValue new_val) {
|
||||
*pval = new_val;
|
||||
}
|
||||
|
||||
void JS_ThrowInterrupted (JSContext *ctx);
|
||||
|
||||
static inline __exception int js_poll_interrupts (JSContext *ctx) {
|
||||
if (unlikely (atomic_load_explicit (&ctx->pause_flag, memory_order_relaxed) >= 2)) {
|
||||
JS_ThrowInterrupted (ctx);
|
||||
JS_RaiseDisrupt (ctx, "interrupted");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
@@ -1595,8 +1588,6 @@ uint64_t get_text_hash (JSText *text);
|
||||
void pack_utf32_to_words (const uint32_t *utf32, uint32_t len, uint64_t *packed);
|
||||
int text_equal (JSText *a, const uint64_t *packed_b, uint32_t len_b);
|
||||
|
||||
void print_backtrace (JSContext *ctx, JSValue stack, const char *filename, int line_num, int col_num);
|
||||
JSValue JS_ThrowError2 (JSContext *ctx, JSErrorEnum error_num, const char *fmt, va_list ap, BOOL add_backtrace);
|
||||
JSValue gc_copy_value (JSContext *ctx, JSValue v, uint8_t *from_base, uint8_t *from_end, uint8_t *to_base, uint8_t **to_free, uint8_t *to_end);
|
||||
PPretext *ppretext_init (int capacity);
|
||||
PPretext *ppretext_putc (PPretext *p, uint32_t c);
|
||||
|
||||
@@ -570,20 +570,23 @@ JS_BOOL JS_StrictEq (JSContext *ctx, JSValue op1, JSValue op2);
|
||||
7. Error Handling
|
||||
============================================================ */
|
||||
|
||||
JSValue JS_Throw (JSContext *ctx, JSValue obj);
|
||||
JSValue JS_GetException (JSContext *ctx);
|
||||
JS_BOOL JS_HasException (JSContext *ctx);
|
||||
|
||||
/* Set the disruption flag. No logging. */
|
||||
JSValue JS_Disrupt (JSContext *ctx);
|
||||
|
||||
/* Log a message to a named channel. Routes through the ƿit log callback
|
||||
if one has been set, otherwise falls back to fprintf(stderr). */
|
||||
void __js_printf_like (3, 4)
|
||||
JS_Log (JSContext *ctx, const char *channel, const char *fmt, ...);
|
||||
|
||||
/* Log to "error" channel + raise disruption. The common case. */
|
||||
JSValue __js_printf_like (2, 3)
|
||||
JS_ThrowSyntaxError (JSContext *ctx, const char *fmt, ...);
|
||||
JSValue __js_printf_like (2, 3)
|
||||
JS_ThrowTypeError (JSContext *ctx, const char *fmt, ...);
|
||||
JSValue __js_printf_like (2, 3)
|
||||
JS_ThrowReferenceError (JSContext *ctx, const char *fmt, ...);
|
||||
JSValue __js_printf_like (2, 3)
|
||||
JS_ThrowRangeError (JSContext *ctx, const char *fmt, ...);
|
||||
JSValue __js_printf_like (2, 3)
|
||||
JS_ThrowInternalError (JSContext *ctx, const char *fmt, ...);
|
||||
JSValue JS_ThrowOutOfMemory (JSContext *ctx);
|
||||
JS_RaiseDisrupt (JSContext *ctx, const char *fmt, ...);
|
||||
|
||||
/* Log to "memory" channel + disrupt. Skips JS callback (can't allocate). */
|
||||
JSValue JS_RaiseOOM (JSContext *ctx);
|
||||
|
||||
/* ============================================================
|
||||
8. Function Creation and Invocation
|
||||
|
||||
522
source/runtime.c
522
source/runtime.c
File diff suppressed because it is too large
Load Diff
@@ -1741,7 +1741,7 @@ TEST(has_exception_initially_false) {
|
||||
|
||||
TEST(throw_and_check_exception) {
|
||||
ASSERT(!JS_HasException(ctx));
|
||||
JS_ThrowTypeError(ctx, "test error");
|
||||
JS_RaiseDisrupt(ctx, "test error");
|
||||
ASSERT(JS_HasException(ctx));
|
||||
JS_GetException(ctx); /* clear it */
|
||||
ASSERT(!JS_HasException(ctx));
|
||||
|
||||
Reference in New Issue
Block a user