From c0cd6a61a679f3980a7471c862e5570568f0f174 Mon Sep 17 00:00:00 2001 From: John Alanbrook Date: Wed, 18 Feb 2026 16:47:33 -0600 Subject: [PATCH] disruption --- archive/miniz.c | 50 +-- crypto.c | 22 +- fd_playdate.c | 50 +-- internal/engine.cm | 15 +- internal/fd.c | 82 ++--- internal/os.c | 44 +-- internal/os_emscripten.c | 4 +- internal/os_playdate.c | 4 +- net/enet.c | 32 +- net/http.c | 6 +- net/http_playdate.c | 20 +- net/socket.c | 50 +-- net/socket_playdate.c | 28 +- playdate/display_playdate.c | 20 +- playdate/file_playdate.c | 28 +- playdate/gfx_playdate.c | 88 +++--- playdate/json_playdate.c | 8 +- playdate/lua_playdate.c | 36 +-- playdate/network_playdate.c | 62 ++-- playdate/scoreboards_playdate.c | 14 +- playdate/sound_playdate.c | 130 ++++---- playdate/sprite_playdate.c | 146 ++++----- playdate/sys_playdate.c | 60 ++-- qop.c | 54 ++-- source/cell.h | 6 + source/mach.c | 86 ++--- source/qbe_backend.c | 6 +- source/qbe_helpers.c | 34 +- source/qjs_actor.c | 50 ++- source/quickjs-internal.h | 33 +- source/quickjs.h | 25 +- source/runtime.c | 542 ++++++++++++++------------------ source/suite.c | 2 +- 33 files changed, 889 insertions(+), 948 deletions(-) diff --git a/archive/miniz.c b/archive/miniz.c index d9404247..6130e448 100644 --- a/archive/miniz.c +++ b/archive/miniz.c @@ -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)); } diff --git a/crypto.c b/crypto.c index a7ad459d..f10f7afc 100644 --- a/crypto.c +++ b/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; diff --git a/fd_playdate.c b/fd_playdate.c index fa6916da..fa1759c8 100644 --- a/fd_playdate.c +++ b/fd_playdate.c @@ -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[] = { diff --git a/internal/engine.cm b/internal/engine.cm index 9586f59c..53ffcae6 100644 --- a/internal/engine.cm +++ b/internal/engine.cm @@ -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 diff --git a/internal/fd.c b/internal/fd.c index 2a10e507..f35a5feb 100644 --- a/internal/fd.c +++ b/internal/fd.c @@ -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); diff --git a/internal/os.c b/internal/os.c index 4fa6d549..ffe13694 100644 --- a/internal/os.c +++ b/internal/os.c @@ -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) diff --git a/internal/os_emscripten.c b/internal/os_emscripten.c index e3e6f83a..dda7cf70 100644 --- a/internal/os_emscripten.c +++ b/internal/os_emscripten.c @@ -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) { diff --git a/internal/os_playdate.c b/internal/os_playdate.c index c7493c20..5992ccb9 100644 --- a/internal/os_playdate.c +++ b/internal/os_playdate.c @@ -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) { diff --git a/net/enet.c b/net/enet.c index ff8e5228..b1eb7b22 100644 --- a/net/enet.c +++ b/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; diff --git a/net/http.c b/net/http.c index eeaa34b6..dc57603e 100644 --- a/net/http.c +++ b/net/http.c @@ -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); diff --git a/net/http_playdate.c b/net/http_playdate.c index f8881a57..925fcc44 100644 --- a/net/http_playdate.c +++ b/net/http_playdate.c @@ -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 diff --git a/net/socket.c b/net/socket.c index 3fab8e1c..2a1e8d6c 100644 --- a/net/socket.c +++ b/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; ) diff --git a/net/socket_playdate.c b/net/socket_playdate.c index bb6f17ae..14e1d856 100644 --- a/net/socket_playdate.c +++ b/net/socket_playdate.c @@ -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[] = { diff --git a/playdate/display_playdate.c b/playdate/display_playdate.c index ef7e8ec3..737a2592 100644 --- a/playdate/display_playdate.c +++ b/playdate/display_playdate.c @@ -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); diff --git a/playdate/file_playdate.c b/playdate/file_playdate.c index 3038a2de..b3500e62 100644 --- a/playdate/file_playdate.c +++ b/playdate/file_playdate.c @@ -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 }; diff --git a/playdate/gfx_playdate.c b/playdate/gfx_playdate.c index daae9410..a4cf97e0 100644 --- a/playdate/gfx_playdate.c +++ b/playdate/gfx_playdate.c @@ -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; ) diff --git a/playdate/json_playdate.c b/playdate/json_playdate.c index 6aa2b432..e52612f2 100644 --- a/playdate/json_playdate.c +++ b/playdate/json_playdate.c @@ -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; diff --git a/playdate/lua_playdate.c b/playdate/lua_playdate.c index 8186722c..4335cbd7 100644 --- a/playdate/lua_playdate.c +++ b/playdate/lua_playdate.c @@ -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); } diff --git a/playdate/network_playdate.c b/playdate/network_playdate.c index 394d8dfb..ae03fd7a 100644 --- a/playdate/network_playdate.c +++ b/playdate/network_playdate.c @@ -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]); diff --git a/playdate/scoreboards_playdate.c b/playdate/scoreboards_playdate.c index 4905782d..268ec439 100644 --- a/playdate/scoreboards_playdate.c +++ b/playdate/scoreboards_playdate.c @@ -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; ) diff --git a/playdate/sound_playdate.c b/playdate/sound_playdate.c index 445269ad..a21afd41 100644 --- a/playdate/sound_playdate.c +++ b/playdate/sound_playdate.c @@ -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; ) diff --git a/playdate/sprite_playdate.c b/playdate/sprite_playdate.c index 1d6606e0..20a395aa 100644 --- a/playdate/sprite_playdate.c +++ b/playdate/sprite_playdate.c @@ -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)); ) diff --git a/playdate/sys_playdate.c b/playdate/sys_playdate.c index 66d6468b..09b2b761 100644 --- a/playdate/sys_playdate.c +++ b/playdate/sys_playdate.c @@ -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; ) diff --git a/qop.c b/qop.c index af8db7cd..488d8bf6 100644 --- a/qop.c +++ b/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 diff --git a/source/cell.h b/source/cell.h index 80bb7b56..af4d965c 100644 --- a/source/cell.h +++ b/source/cell.h @@ -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); \ diff --git a/source/mach.c b/source/mach.c index 117fe113..60bcac94 100644 --- a/source/mach.c +++ b/source/mach.c @@ -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 : ""; - const char *file = fault_code->filename_cstr ? fault_code->filename_cstr : ""; - 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 : "", - tc->filename_cstr ? tc->filename_cstr : "", 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); diff --git a/source/qbe_backend.c b/source/qbe_backend.c index cd5a4301..29b80d1c 100644 --- a/source/qbe_backend.c +++ b/source/qbe_backend.c @@ -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 */ diff --git a/source/qbe_helpers.c b/source/qbe_helpers.c index 4f189280..44c54943 100644 --- a/source/qbe_helpers.c +++ b/source/qbe_helpers.c @@ -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); diff --git a/source/qjs_actor.c b/source/qjs_actor.c index b1f6daf6..8dcf43da 100644 --- a/source/qjs_actor.c +++ b/source/qjs_actor.c @@ -1,5 +1,6 @@ #include "cell.h" #include "cell_internal.h" +#include "quickjs-internal.h" #include #include @@ -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) { diff --git a/source/quickjs-internal.h b/source/quickjs-internal.h index 0f2a051e..6310755b 100644 --- a/source/quickjs-internal.h +++ b/source/quickjs-internal.h @@ -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); diff --git a/source/quickjs.h b/source/quickjs.h index 1c02f2eb..d100dcd8 100644 --- a/source/quickjs.h +++ b/source/quickjs.h @@ -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 diff --git a/source/runtime.c b/source/runtime.c index f99557e8..82fb5b4c 100644 --- a/source/runtime.c +++ b/source/runtime.c @@ -792,7 +792,7 @@ void *js_malloc (JSContext *ctx, size_t size) { { int need_space = (uint8_t *)ctx->heap_free + size > (uint8_t *)ctx->heap_end; if (ctx_gc(ctx, need_space, size) < 0) { - JS_ThrowOutOfMemory(ctx); + JS_RaiseOOM(ctx); return NULL; } /* If still no room after GC, grow and retry (same logic as normal path) */ @@ -804,12 +804,12 @@ void *js_malloc (JSContext *ctx, size_t size) { ns *= 2; ctx->next_block_size = ns; if (ctx_gc (ctx, 1, size) < 0) { - JS_ThrowOutOfMemory (ctx); + JS_RaiseOOM(ctx); return NULL; } ctx->next_block_size = ctx->current_block_size; if ((uint8_t *)ctx->heap_free + size > (uint8_t *)ctx->heap_end) { - JS_ThrowOutOfMemory (ctx); + JS_RaiseOOM(ctx); return NULL; } } @@ -819,7 +819,7 @@ void *js_malloc (JSContext *ctx, size_t size) { if ((uint8_t *)ctx->heap_free + size > (uint8_t *)ctx->heap_end) { /* Trigger GC to reclaim memory */ if (ctx_gc (ctx, 1, size) < 0) { - JS_ThrowOutOfMemory (ctx); + JS_RaiseOOM(ctx); return NULL; } /* Re-check after GC — if still no room, grow and retry. @@ -838,7 +838,7 @@ void *js_malloc (JSContext *ctx, size_t size) { #endif ctx->next_block_size = ns; if (ctx_gc (ctx, 1, size) < 0) { - JS_ThrowOutOfMemory (ctx); + JS_RaiseOOM(ctx); return NULL; } /* The retry pass relocates compacted data — 0% recovery is expected. @@ -846,7 +846,7 @@ void *js_malloc (JSContext *ctx, size_t size) { doesn't cascade into further unnecessary doubling. */ ctx->next_block_size = ctx->current_block_size; if ((uint8_t *)ctx->heap_free + size > (uint8_t *)ctx->heap_end) { - JS_ThrowOutOfMemory (ctx); + JS_RaiseOOM(ctx); return NULL; } } @@ -1638,6 +1638,9 @@ int ctx_gc (JSContext *ctx, int allow_grow, size_t alloc_size) { /* Copy actor identity key */ ctx->actor_sym = gc_copy_value (ctx, ctx->actor_sym, from_base, from_end, to_base, &to_free, to_end); + /* Copy log callback function */ + ctx->log_callback_js = gc_copy_value (ctx, ctx->log_callback_js, from_base, from_end, to_base, &to_free, to_end); + /* Copy class prototypes */ #ifdef DUMP_GC_DETAIL printf(" roots: class_proto (count=%d)\n", ctx->class_count); fflush(stdout); @@ -1901,7 +1904,7 @@ JSText *js_alloc_string (JSContext *ctx, int max_len) { str = js_malloc (ctx, size); if (unlikely (!str)) { - JS_ThrowOutOfMemory (ctx); + JS_RaiseOOM(ctx); return NULL; } /* Initialize objhdr_t with OBJ_TEXT type and capacity in cap56 */ @@ -1972,6 +1975,8 @@ JSContext *JS_NewContextRawWithHeapSize (JSRuntime *rt, size_t heap_size) { /* Initialize per-context execution state (moved from JSRuntime) */ ctx->current_exception = JS_NULL; ctx->actor_sym = JS_NULL; + ctx->log_callback_js = JS_NULL; + ctx->log_callback = NULL; /* Initialize constant text pool (avoids overflow pages for common case) */ { @@ -2079,8 +2084,6 @@ void JS_FreeContext (JSContext *ctx) { JS_DeleteGCRef(ctx, &ctx->suspended_frame_ref); - for (i = 0; i < JS_NATIVE_ERROR_COUNT; i++) { - } for (i = 0; i < ctx->class_count; i++) { } js_free_rt (ctx->class_array); @@ -2313,7 +2316,7 @@ JSText *pretext_init (JSContext *ctx, int capacity) { /* Reallocate a pretext to hold new_len characters */ static no_inline JSText *pretext_realloc (JSContext *ctx, JSText *s, int new_len) { if (new_len > JS_STRING_LEN_MAX) { - JS_ThrowInternalError (ctx, "string too long"); + JS_RaiseDisrupt (ctx, "string too long"); return NULL; } int old_cap = (int)objhdr_cap56 (s->hdr); @@ -2482,7 +2485,7 @@ JSValue pretext_end (JSContext *ctx, JSText *s) { /* create a string from a UTF-8 buffer */ JSValue JS_NewStringLen (JSContext *ctx, const char *buf, size_t buf_len) { if (buf_len > JS_STRING_LEN_MAX) - return JS_ThrowInternalError (ctx, "string too long"); + return JS_RaiseDisrupt (ctx, "string too long"); /* Try immediate ASCII first (<=7 ASCII chars) */ if (buf_len <= MIST_ASCII_MAX_LEN) { @@ -2927,7 +2930,7 @@ static int js_array_grow (JSContext *ctx, JSValue *arr_ptr, word_t min_cap) { if (min_cap <= old_cap) return 0; if (objhdr_s (arr->mist_hdr)) { - JS_ThrowInternalError (ctx, "cannot grow a stoned array"); + JS_RaiseDisrupt (ctx, "cannot grow a stoned array"); return -1; } @@ -2936,7 +2939,7 @@ static int js_array_grow (JSContext *ctx, JSValue *arr_ptr, word_t min_cap) { new_cap *= 2; if (new_cap > JS_ARRAY_MAX_CAP) new_cap = JS_ARRAY_MAX_CAP; if (new_cap < min_cap) { - JS_ThrowRangeError (ctx, "array capacity overflow"); + JS_RaiseDisrupt (ctx, "array capacity overflow"); return -1; } @@ -2976,7 +2979,7 @@ static int js_intrinsic_array_push (JSContext *ctx, JSValue *arr_ptr, JSValue va JSArray *arr = JS_VALUE_GET_ARRAY (*arr_ptr); if (objhdr_s (arr->mist_hdr)) { - JS_ThrowInternalError (ctx, "cannot push to a stoned array"); + JS_RaiseDisrupt (ctx, "cannot push to a stoned array"); return -1; } @@ -3003,7 +3006,7 @@ static int js_intrinsic_array_set (JSContext *ctx, JSValue *arr_ptr, word_t idx, JSArray *arr = JS_VALUE_GET_ARRAY (*arr_ptr); if (objhdr_s (arr->mist_hdr)) { - JS_ThrowInternalError (ctx, "cannot set on a stoned array"); + JS_RaiseDisrupt (ctx, "cannot set on a stoned array"); return -1; } @@ -3042,9 +3045,46 @@ JSValue js_new_function (JSContext *ctx, JSFunctionKind kind) { return JS_MKPTR (func); } -/* WARNING: obj is freed */ -JSValue JS_Throw (JSContext *ctx, JSValue obj) { - ctx->current_exception = obj; +/* Set the disruption flag. No logging. */ +JSValue JS_Disrupt (JSContext *ctx) { + ctx->current_exception = JS_TRUE; + return JS_EXCEPTION; +} + +/* Log a message to a named channel. + Routes through the ƿit log callback if one is set; + falls back to fprintf(stderr) during bootstrap or for OOM. */ +void JS_Log (JSContext *ctx, const char *channel, const char *fmt, ...) { + char buf[512]; + va_list ap; + va_start (ap, fmt); + vsnprintf (buf, sizeof (buf), fmt, ap); + va_end (ap); + + if (ctx->log_callback && strcmp (channel, "memory") != 0) { + ctx->log_callback (ctx, channel, buf); + } else { + fprintf (stderr, "%s\n", buf); + } +} + +/* Log to "error" channel + raise disruption. The common case. */ +JSValue __attribute__ ((format (printf, 2, 3))) +JS_RaiseDisrupt (JSContext *ctx, const char *fmt, ...) { + char buf[512]; + va_list ap; + va_start (ap, fmt); + vsnprintf (buf, sizeof (buf), fmt, ap); + va_end (ap); + JS_Log (ctx, "error", "%s", buf); + ctx->current_exception = JS_TRUE; + return JS_EXCEPTION; +} + +/* Log to "memory" channel + disrupt. Skips JS callback (can't allocate). */ +JSValue JS_RaiseOOM (JSContext *ctx) { + fprintf (stderr, "out of memory\n"); + ctx->current_exception = JS_TRUE; return JS_EXCEPTION; } @@ -3077,135 +3117,13 @@ static const char *get_func_name (JSContext *ctx, JSValue func) { return JS_ToCString (ctx, val); } -static const char *const native_error_name[JS_NATIVE_ERROR_COUNT] = { - "EvalError", - "RangeError", - "ReferenceError", - "SyntaxError", - "TypeError", - "URIError", - "InternalError", - "AggregateError", -}; - -/* Print backtrace to stderr from a JS array of {fn, file, line, col} objects. */ -void print_backtrace (JSContext *ctx, JSValue stack, const char *filename, int line_num, int col_num) { - if (filename) { - fprintf (stderr, " at %s", filename); - if (line_num != -1) fprintf (stderr, ":%d:%d", line_num, col_num); - fputc ('\n', stderr); - } - - int64_t n = 0; - JS_GetLength(ctx, stack, &n); - for (int i = 0; i < (int)n; i++) { - JSValue fr = JS_GetPropertyNumber(ctx, stack, i); - JSValue fn_val = JS_GetPropertyStr(ctx, fr, "fn"); - JSValue file_val = JS_GetPropertyStr(ctx, fr, "file"); - const char *fn = JS_ToCString(ctx, fn_val); - const char *file = JS_ToCString(ctx, file_val); - int32_t ln = 0, cn = 0; - JSValue line_v = JS_GetPropertyStr(ctx, fr, "line"); - JSValue col_v = JS_GetPropertyStr(ctx, fr, "col"); - JS_ToInt32(ctx, &ln, line_v); - JS_ToInt32(ctx, &cn, col_v); - fprintf (stderr, " at %s (%s:%d:%d)\n", - fn ? fn : "", file ? file : "", ln, cn); - if (fn) JS_FreeCString(ctx, fn); - if (file) JS_FreeCString(ctx, file); - } +static JSValue JS_RaiseDisruptNotAnObject (JSContext *ctx) { + return JS_RaiseDisrupt (ctx, "not an object"); } -/* Print error message + backtrace to stderr, then set exception flag. - No Error object is created — just print and flag. */ -JSValue JS_ThrowError2 (JSContext *ctx, JSErrorEnum error_num, const char *fmt, va_list ap, BOOL add_backtrace) { - char buf[256]; - vsnprintf (buf, sizeof (buf), fmt, ap); - fprintf (stderr, "%s: %s\n", native_error_name[error_num], buf); - if (add_backtrace) { - JSValue stack = JS_GetStack(ctx); - ctx->reg_current_frame = JS_NULL; - print_backtrace (ctx, stack, NULL, 0, 0); - } - return JS_Throw (ctx, JS_TRUE); -} - -static JSValue JS_ThrowError (JSContext *ctx, JSErrorEnum error_num, const char *fmt, va_list ap) { - return JS_ThrowError2 (ctx, error_num, fmt, ap, TRUE); -} - -JSValue __attribute__ ((format (printf, 2, 3))) -JS_ThrowSyntaxError (JSContext *ctx, const char *fmt, ...) { - JSValue val; - va_list ap; - - va_start (ap, fmt); - val = JS_ThrowError (ctx, JS_SYNTAX_ERROR, fmt, ap); - va_end (ap); - return val; -} - -JSValue __attribute__ ((format (printf, 2, 3))) -JS_ThrowTypeError (JSContext *ctx, const char *fmt, ...) { - JSValue val; - va_list ap; - - va_start (ap, fmt); - val = JS_ThrowError (ctx, JS_TYPE_ERROR, fmt, ap); - va_end (ap); - return val; -} - -JSValue __attribute__ ((format (printf, 2, 3))) -JS_ThrowReferenceError (JSContext *ctx, const char *fmt, ...) { - JSValue val; - va_list ap; - - va_start (ap, fmt); - val = JS_ThrowError (ctx, JS_REFERENCE_ERROR, fmt, ap); - va_end (ap); - return val; -} - -JSValue __attribute__ ((format (printf, 2, 3))) -JS_ThrowRangeError (JSContext *ctx, const char *fmt, ...) { - JSValue val; - va_list ap; - - va_start (ap, fmt); - val = JS_ThrowError (ctx, JS_RANGE_ERROR, fmt, ap); - va_end (ap); - return val; -} - -JSValue __attribute__ ((format (printf, 2, 3))) -JS_ThrowInternalError (JSContext *ctx, const char *fmt, ...) { - JSValue val; - va_list ap; - - va_start (ap, fmt); - val = JS_ThrowError (ctx, JS_INTERNAL_ERROR, fmt, ap); - va_end (ap); - return val; -} - -JSValue JS_ThrowOutOfMemory (JSContext *ctx) { - /* Simplified: no re-entry guard needed with copying GC */ - JS_ThrowInternalError (ctx, "out of memory"); - return JS_EXCEPTION; -} - -static JSValue JS_ThrowTypeErrorNotAnObject (JSContext *ctx) { - return JS_ThrowTypeError (ctx, "not an object"); -} - -static JSValue JS_ThrowTypeErrorInvalidClass (JSContext *ctx, int class_id) { +static JSValue JS_RaiseDisruptInvalidClass (JSContext *ctx, int class_id) { const char *name = ctx->class_array[class_id].class_name; - return JS_ThrowTypeError (ctx, "%s object expected", name ? name : "unknown"); -} - -void JS_ThrowInterrupted (JSContext *ctx) { - JS_ThrowInternalError (ctx, "interrupted"); + return JS_RaiseDisrupt (ctx, "%s object expected", name ? name : "unknown"); } /* Return an Object, JS_NULL or JS_EXCEPTION in case of exotic object. */ @@ -3252,7 +3170,7 @@ JSValue JS_GetOwnPropertyNames (JSContext *ctx, JSValue obj) { uint32_t mask, count, i; if (!JS_IsRecord (obj)) { - JS_ThrowTypeErrorNotAnObject (ctx); + JS_RaiseDisruptNotAnObject (ctx); return JS_EXCEPTION; } @@ -3316,7 +3234,7 @@ int JS_GetOwnPropertyInternal (JSContext *ctx, int JS_GetOwnProperty (JSContext *ctx, JSValue *desc, JSValue obj, JSValue prop) { if (!JS_IsRecord (obj)) { - JS_ThrowTypeErrorNotAnObject (ctx); + JS_RaiseDisruptNotAnObject (ctx); return -1; } return JS_GetOwnPropertyInternal (ctx, desc, JS_VALUE_GET_OBJ (obj), prop); @@ -3405,15 +3323,15 @@ JSValue JS_GetPropertyValue (JSContext *ctx, JSValue this_obj, JSValue prop) { JSValue JS_SetPropertyNumber (JSContext *js, JSValue obj, int idx, JSValue val) { if (JS_IsText (obj)) { - return JS_ThrowTypeError (js, "strings are immutable"); + return JS_RaiseDisrupt (js, "strings are immutable"); } if (!JS_IsArray (obj)) { - return JS_ThrowInternalError (js, + return JS_RaiseDisrupt (js, "cannot set with a number on a non array"); } if (idx < 0) { - return JS_ThrowRangeError (js, "array index out of bounds"); + return JS_RaiseDisrupt (js, "array index out of bounds"); } /* Root obj since js_intrinsic_array_set may trigger GC during array grow */ @@ -3486,9 +3404,9 @@ JSValue JS_Invoke (JSContext *ctx, JSValue this_val, JSValue method, int argc, J int JS_SetProperty (JSContext *ctx, JSValue this_obj, JSValue prop, JSValue val) { if (!JS_IsRecord (this_obj)) { if (JS_IsNull (this_obj)) { - JS_ThrowTypeError (ctx, "cannot set property of null"); + JS_RaiseDisrupt (ctx, "cannot set property of null"); } else { - JS_ThrowTypeError (ctx, "cannot set property on a primitive"); + JS_RaiseDisrupt (ctx, "cannot set property on a primitive"); } return -1; } @@ -3497,7 +3415,7 @@ int JS_SetProperty (JSContext *ctx, JSValue this_obj, JSValue prop, JSValue val) JSRecord *rec = (JSRecord *)JS_VALUE_GET_OBJ (this_obj); if (unlikely (obj_is_stone (rec))) { - JS_ThrowTypeError (ctx, "object is stone"); + JS_RaiseDisrupt (ctx, "object is stone"); return -1; } @@ -3576,12 +3494,12 @@ JSValue JS_GetPropertyKey (JSContext *ctx, JSValue this_obj, JSValue key) { int JS_SetPropertyKey (JSContext *ctx, JSValue this_obj, JSValue key, JSValue val) { if (JS_IsRecord (key)) { if (!JS_IsRecord (this_obj)) { - JS_ThrowTypeError (ctx, "cannot set property on this value"); + JS_RaiseDisrupt (ctx, "cannot set property on this value"); return -1; } JSRecord *rec = JS_VALUE_GET_RECORD (this_obj); if (obj_is_stone (rec)) { - JS_ThrowTypeError (ctx, "cannot modify frozen object"); + JS_RaiseDisrupt (ctx, "cannot modify frozen object"); return -1; } return rec_set_own (ctx, &this_obj, key, val); @@ -3628,7 +3546,7 @@ int JS_DeletePropertyKey (JSContext *ctx, JSValue obj, JSValue key) { if (!JS_IsRecord (obj)) return FALSE; JSRecord *rec = JS_VALUE_GET_RECORD (obj); if (obj_is_stone (rec)) { - JS_ThrowTypeError (ctx, "cannot modify frozen object"); + JS_RaiseDisrupt (ctx, "cannot modify frozen object"); return -1; } int slot = rec_find_slot (rec, key); @@ -3661,18 +3579,18 @@ int JS_DeleteProperty (JSContext *ctx, JSValue obj, JSValue prop) { /* Arrays do not support property deletion */ if (JS_IsArray (obj)) { - JS_ThrowTypeError (ctx, "cannot delete array element"); + JS_RaiseDisrupt (ctx, "cannot delete array element"); return -1; } if (JS_VALUE_GET_TAG (obj) != JS_TAG_PTR) { - JS_ThrowTypeErrorNotAnObject (ctx); + JS_RaiseDisruptNotAnObject (ctx); return -1; } rec = (JSRecord *)JS_VALUE_GET_OBJ (obj); if (obj_is_stone (rec)) { - JS_ThrowTypeError (ctx, "cannot delete property of stone object"); + JS_RaiseDisrupt (ctx, "cannot delete property of stone object"); return -1; } @@ -3718,7 +3636,7 @@ void *JS_GetOpaque (JSValue obj, JSClassID class_id) { void *JS_GetOpaque2 (JSContext *ctx, JSValue obj, JSClassID class_id) { void *p = JS_GetOpaque (obj, class_id); - if (unlikely (!p)) { JS_ThrowTypeErrorInvalidClass (ctx, class_id); } + if (unlikely (!p)) { JS_RaiseDisruptInvalidClass (ctx, class_id); } return p; } @@ -3927,7 +3845,7 @@ fail: val = JS_NAN; goto done; mem_error: - val = JS_ThrowOutOfMemory (ctx); + val = JS_RaiseOOM(ctx); goto done; } @@ -3941,10 +3859,10 @@ JSValue JS_ToNumber (JSContext *ctx, JSValue val) { objhdr_t hdr = *(objhdr_t *)ptr; if (objhdr_type (hdr) == OBJ_TEXT) { /* String */ - return JS_ThrowTypeError (ctx, "cannot convert text to a number"); + return JS_RaiseDisrupt (ctx, "cannot convert text to a number"); } /* Objects */ - return JS_ThrowTypeError (ctx, "cannot convert object to number"); + return JS_RaiseDisrupt (ctx, "cannot convert object to number"); } tag = JS_VALUE_GET_NORM_TAG (val); @@ -3954,12 +3872,14 @@ JSValue JS_ToNumber (JSContext *ctx, JSValue val) { case JS_TAG_EXCEPTION: ret = val; break; - case JS_TAG_BOOL: case JS_TAG_NULL: - ret = JS_NewInt32 (ctx, JS_VALUE_GET_INT (val)); + ret = JS_NewInt32 (ctx, 0); + break; + case JS_TAG_BOOL: + ret = JS_NewInt32 (ctx, JS_VALUE_GET_BOOL (val)); break; case JS_TAG_STRING_IMM: - return JS_ThrowTypeError (ctx, "cannot convert text to a number"); + return JS_RaiseDisrupt (ctx, "cannot convert text to a number"); default: ret = JS_NAN; break; @@ -4015,10 +3935,14 @@ redo: tag = JS_VALUE_GET_NORM_TAG (val); switch (tag) { case JS_TAG_INT: - case JS_TAG_BOOL: - case JS_TAG_NULL: ret = JS_VALUE_GET_INT (val); break; + case JS_TAG_NULL: + ret = 0; + break; + case JS_TAG_BOOL: + ret = JS_VALUE_GET_BOOL (val); + break; case JS_TAG_EXCEPTION: *pres = 0; return -1; @@ -4064,10 +3988,14 @@ redo: tag = JS_VALUE_GET_NORM_TAG (val); switch (tag) { case JS_TAG_INT: - case JS_TAG_BOOL: - case JS_TAG_NULL: *pres = JS_VALUE_GET_INT (val); return 0; + case JS_TAG_NULL: + *pres = 0; + return 0; + case JS_TAG_BOOL: + *pres = JS_VALUE_GET_BOOL (val); + return 0; case JS_TAG_EXCEPTION: *pres = 0; return -1; @@ -4115,10 +4043,14 @@ redo: tag = JS_VALUE_GET_NORM_TAG (val); switch (tag) { case JS_TAG_INT: - case JS_TAG_BOOL: - case JS_TAG_NULL: ret = JS_VALUE_GET_INT (val); break; + case JS_TAG_NULL: + ret = 0; + break; + case JS_TAG_BOOL: + ret = JS_VALUE_GET_BOOL (val); + break; case JS_TAG_FLOAT64: { JSFloat64Union u; double d; @@ -4162,10 +4094,14 @@ redo: tag = JS_VALUE_GET_NORM_TAG (val); switch (tag) { case JS_TAG_INT: - case JS_TAG_BOOL: - case JS_TAG_NULL: ret = JS_VALUE_GET_INT (val); break; + case JS_TAG_NULL: + ret = 0; + break; + case JS_TAG_BOOL: + ret = JS_VALUE_GET_BOOL (val); + break; case JS_TAG_FLOAT64: { JSFloat64Union u; double d; @@ -4275,7 +4211,7 @@ JSValue JS_ToString (JSContext *ctx, JSValue val) { static JSValue JS_ToStringCheckObject (JSContext *ctx, JSValue val) { uint32_t tag = JS_VALUE_GET_TAG (val); - if (tag == JS_TAG_NULL) return JS_ThrowTypeError (ctx, "null is forbidden"); + if (tag == JS_TAG_NULL) return JS_RaiseDisrupt (ctx, "null is forbidden"); return JS_ToString (ctx, val); } @@ -4638,7 +4574,7 @@ BOOL JS_StrictEq (JSContext *ctx, JSValue op1, JSValue op2) { } static JSValue js_throw_type_error (JSContext *ctx, JSValue this_val, int argc, JSValue *argv) { - return JS_ThrowTypeError (ctx, "invalid property access"); + return JS_RaiseDisrupt (ctx, "invalid property access"); } JSValue js_call_c_function (JSContext *ctx, JSValue func_obj, JSValue this_obj, int argc, JSValue *argv) { @@ -4763,7 +4699,7 @@ JSValue JS_CallInternal (JSContext *ctx, JSValue func_obj, JSValue this_obj, (void)flags; if (js_poll_interrupts (ctx)) return JS_EXCEPTION; if (!JS_IsFunction (func_obj)) - return JS_ThrowTypeError (ctx, "not a function"); + return JS_RaiseDisrupt (ctx, "not a function"); JSFunction *f = JS_VALUE_GET_FUNCTION (func_obj); switch (f->kind) { case JS_FUNC_KIND_C: @@ -4773,18 +4709,18 @@ JSValue JS_CallInternal (JSContext *ctx, JSValue func_obj, JSValue this_obj, return JS_CallRegisterVM (ctx, f->u.reg.code, this_obj, argc, argv, f->u.reg.env_record, f->u.reg.outer_frame); default: - return JS_ThrowTypeError (ctx, "not a function"); + return JS_RaiseDisrupt (ctx, "not a function"); } } JSValue JS_Call (JSContext *ctx, JSValue func_obj, JSValue this_obj, int argc, JSValue *argv) { if (js_poll_interrupts (ctx)) return JS_EXCEPTION; if (unlikely (!JS_IsFunction (func_obj))) - return JS_ThrowTypeError (ctx, "not a function"); + return JS_RaiseDisrupt (ctx, "not a function"); JSFunction *f = JS_VALUE_GET_FUNCTION (func_obj); if (unlikely (f->length >= 0 && argc > f->length)) { char buf[KEY_GET_STR_BUF_SIZE]; - return JS_ThrowTypeError (ctx, "too many arguments for %s: expected %d, got %d", + return JS_RaiseDisrupt (ctx, "too many arguments for %s: expected %d, got %d", JS_KeyGetStr (ctx, buf, KEY_GET_STR_BUF_SIZE, f->name), f->length, argc); } switch (f->kind) { @@ -4794,7 +4730,7 @@ JSValue JS_Call (JSContext *ctx, JSValue func_obj, JSValue this_obj, int argc, J return JS_CallRegisterVM (ctx, f->u.reg.code, this_obj, argc, argv, f->u.reg.env_record, f->u.reg.outer_frame); default: - return JS_ThrowTypeError (ctx, "not a function"); + return JS_RaiseDisrupt (ctx, "not a function"); } } @@ -4960,7 +4896,7 @@ JSValue *build_arg_list (JSContext *ctx, uint32_t *plen, JSValue *parray_arg) { JSArray *arr = JS_VALUE_GET_ARRAY (*parray_arg); len = arr->len; if (len > JS_MAX_LOCAL_VARS) { - JS_ThrowRangeError ( + JS_RaiseDisrupt ( ctx, "too many arguments in function call (only %d allowed)", JS_MAX_LOCAL_VARS); return NULL; } @@ -4974,7 +4910,7 @@ JSValue *build_arg_list (JSContext *ctx, uint32_t *plen, JSValue *parray_arg) { return tab; } - JS_ThrowTypeError (ctx, "not an array"); + JS_RaiseDisrupt (ctx, "not an array"); return NULL; } @@ -5059,7 +4995,7 @@ JSValue js_compile_regexp (JSContext *ctx, JSValue pattern, JSValue flags) { /* 'u' and 'v' cannot be both set */ if ((re_flags & LRE_FLAG_UNICODE_SETS) && (re_flags & LRE_FLAG_UNICODE)) { bad_flags1: - return JS_ThrowSyntaxError (ctx, "invalid regular expression flags"); + return JS_RaiseDisrupt (ctx, "invalid regular expression flags"); } str = JS_ToCStringLen2 ( @@ -5068,7 +5004,7 @@ JSValue js_compile_regexp (JSContext *ctx, JSValue pattern, JSValue flags) { re_bytecode_buf = lre_compile (&re_bytecode_len, error_msg, sizeof (error_msg), str, len, re_flags, ctx); JS_FreeCString (ctx, str); if (!re_bytecode_buf) { - JS_ThrowSyntaxError (ctx, "%s", error_msg); + JS_RaiseDisrupt (ctx, "%s", error_msg); return JS_EXCEPTION; } @@ -5090,7 +5026,7 @@ JSValue js_regexp_constructor_internal (JSContext *ctx, JSValue pattern, JSValue /* sanity check - need strings for pattern and bytecode */ if (!JS_IsText (bc) || !JS_IsText (pattern)) { - JS_ThrowTypeError (ctx, "string expected"); + JS_RaiseDisrupt (ctx, "string expected"); fail: return JS_EXCEPTION; } @@ -5118,7 +5054,7 @@ JSValue js_regexp_constructor_internal (JSContext *ctx, JSValue pattern, JSValue /* Allocate JSRegExp off-heap (not on GC heap) so opaque pointer stays valid after GC */ re = js_malloc_rt (sizeof(JSRegExp)); - if (!re) { REGEXP_CLEANUP (); JS_ThrowOutOfMemory (ctx); goto fail; } + if (!re) { REGEXP_CLEANUP (); JS_RaiseOOM(ctx); goto fail; } p = JS_VALUE_GET_OBJ (obj_ref.val); REC_SET_OPAQUE(p, re); re->pattern = NULL; @@ -5172,7 +5108,7 @@ static JSRegExp *js_get_regexp (JSContext *ctx, JSValue obj, BOOL throw_error) { JSRecord *p = JS_VALUE_GET_OBJ (obj); if (REC_GET_CLASS_ID(p) == JS_CLASS_REGEXP) return (JSRegExp *)REC_GET_OPAQUE(p); } - if (throw_error) { JS_ThrowTypeErrorInvalidClass (ctx, JS_CLASS_REGEXP); } + if (throw_error) { JS_RaiseDisruptInvalidClass (ctx, JS_CLASS_REGEXP); } return NULL; } @@ -5260,7 +5196,7 @@ static JSValue js_regexp_compile (JSContext *ctx, JSValue this_val, int argc, JS re1 = js_get_regexp (ctx, pattern1, FALSE); if (re1) { if (!JS_IsNull (flags1)) - return JS_ThrowTypeError (ctx, "flags must be undefined"); + return JS_RaiseDisrupt (ctx, "flags must be undefined"); pattern = JS_NewString (ctx, re1->pattern); if (JS_IsException (pattern)) goto fail; bc = js_new_string8_len (ctx, (const char *)re1->bytecode, re1->bytecode_len); @@ -5323,7 +5259,7 @@ fail: JSValue js_regexp_toString (JSContext *ctx, JSValue this_val, int argc, JSValue *argv) { JSValue pattern, flags; - if (!mist_is_gc_object (this_val)) return JS_ThrowTypeErrorNotAnObject (ctx); + if (!mist_is_gc_object (this_val)) return JS_RaiseDisruptNotAnObject (ctx); JSText *b = pretext_init (ctx, 0); if (!b) return JS_EXCEPTION; @@ -5374,7 +5310,7 @@ static uint16_t *js_string_to_utf16 (JSContext *ctx, JSText *str, int *out_len) int len = (int)JSText_len (str); /* Worst case: each UTF-32 char becomes 2 UTF-16 surrogates */ uint16_t *buf = js_malloc_rt (len * 2 * sizeof (uint16_t)); - if (!buf) { JS_ThrowOutOfMemory (ctx); return NULL; } + if (!buf) { JS_RaiseOOM(ctx); return NULL; } int j = 0; for (int i = 0; i < len; i++) { @@ -5456,7 +5392,7 @@ static JSValue js_regexp_exec (JSContext *ctx, JSValue this_val, int argc, JSVal if (capture_count > 0) { capture = js_malloc_rt (sizeof (capture[0]) * capture_count * 2); - if (!capture) { JS_ThrowOutOfMemory (ctx); goto fail; } + if (!capture) { JS_RaiseOOM(ctx); goto fail; } } /* Refresh str after potential GC from js_malloc */ @@ -5487,9 +5423,9 @@ static JSValue js_regexp_exec (JSContext *ctx, JSValue this_val, int argc, JSVal goto done; } if (rc == LRE_RET_TIMEOUT) - JS_ThrowInterrupted (ctx); + JS_RaiseDisrupt (ctx, "interrupted"); else - JS_ThrowInternalError (ctx, "out of memory in regexp execution"); + JS_RaiseDisrupt (ctx, "out of memory in regexp execution"); goto fail; } @@ -5704,7 +5640,7 @@ JSValue JS_ParseJSON (JSContext *ctx, const char *buf, size_t buf_len, (void)buf_len; cJSON *root = cJSON_Parse (buf); if (!root) - return JS_ThrowSyntaxError (ctx, "JSON parse error"); + return JS_RaiseDisrupt (ctx, "JSON parse error"); JSValue result = cjson_to_jsvalue (ctx, root); cJSON_Delete (root); return result; @@ -5836,7 +5772,7 @@ static int js_json_to_str (JSContext *ctx, JSONStringifyContext *jsc, JSValue ho if (mist_is_gc_object ( val_ref.val)) { /* includes arrays (OBJ_ARRAY) since they have JS_TAG_PTR */ if (json_stack_has (ctx, jsc->stack, val_ref.val)) { - JS_ThrowTypeError (ctx, "circular reference"); + JS_RaiseDisrupt (ctx, "circular reference"); goto exception; } indent1_ref.val = JS_ConcatString (ctx, indent_ref.val, jsc->gap); @@ -6887,7 +6823,7 @@ static JSValue js_cell_text (JSContext *ctx, JSValue this_val, int argc, JSValue if (mist_is_blob (arg)) { JSBlob *bd = checked_get_blob (ctx, arg); if (!objhdr_s (bd->mist_hdr)) - return JS_ThrowTypeError (ctx, "text: blob must be stone"); + return JS_RaiseDisrupt (ctx, "text: blob must be stone"); char format = '\0'; if (argc > 1) { @@ -6967,7 +6903,7 @@ static JSValue js_cell_text (JSContext *ctx, JSValue this_val, int argc, JSValue return ret; } else { if (bd->length % 8 != 0) - return JS_ThrowTypeError (ctx, + return JS_RaiseDisrupt (ctx, "text: blob not byte-aligned for UTF-8"); return JS_NewStringLen (ctx, (const char *)data, byte_len); } @@ -7043,7 +6979,7 @@ static JSValue js_cell_text (JSContext *ctx, JSValue this_val, int argc, JSValue if (sep_alloc) JS_FreeCString (ctx, separator); JS_DeleteGCRef (ctx, &b_ref); JS_DeleteGCRef (ctx, &arg_ref); - return JS_ThrowTypeError (ctx, "text: array element is not a string"); + return JS_RaiseDisrupt (ctx, "text: array element is not a string"); } JSValue item_str = JS_ToString (ctx, item); @@ -7103,7 +7039,7 @@ static JSValue js_cell_text (JSContext *ctx, JSValue this_val, int argc, JSValue } return JS_ToString (ctx, arg); - return JS_ThrowInternalError (ctx, "Could not convert to text. Tag is %d", tag); + return JS_RaiseDisrupt (ctx, "Could not convert to text. Tag is %d", tag); } /* text.lower(str) - convert to lowercase */ @@ -7354,7 +7290,7 @@ static JSValue js_cell_text_replace (JSContext *ctx, JSValue this_val, int argc, } if (!JS_VALUE_IS_TEXT (argv[0])) - return JS_ThrowInternalError (ctx, "Replace must have text in arg0."); + return JS_RaiseDisrupt (ctx, "Replace must have text in arg0."); int len = js_string_value_len (argv[0]); @@ -7382,7 +7318,7 @@ static JSValue js_cell_text_replace (JSContext *ctx, JSValue this_val, int argc, if (!target_is_regex) { if (!JS_VALUE_IS_TEXT (argv[1])) { B_CLEANUP (); - return JS_ThrowInternalError ( + return JS_RaiseDisrupt ( ctx, "Second arg of replace must be pattern or text."); } @@ -8184,7 +8120,7 @@ static JSValue js_cell_array (JSContext *ctx, JSValue this_val, int argc, JSValu /* array(number, initial_value) - create array with initial values */ if (JS_IsNumber (arg)) { if (!JS_IsInteger (arg)) - return JS_ThrowTypeError (ctx, "Array expected an integer."); + return JS_RaiseDisrupt (ctx, "Array expected an integer."); int len = JS_VALUE_GET_INT (arg); if (len < 0) return JS_NULL; @@ -9535,13 +9471,13 @@ static JSValue js_blob_constructor (JSContext *ctx, JSValue this_val, int argc, JS_PopGCRef (ctx, &bv_ref); return ret; } - return JS_ThrowTypeError (ctx, "Second argument must be boolean or random function"); + return JS_RaiseDisrupt (ctx, "Second argument must be boolean or random function"); } /* blob(blob, from, to) - copy from another blob */ if (argc >= 1 && mist_is_blob (argv[0])) { JSBlob *src = checked_get_blob (ctx, argv[0]); if (!src) - return JS_ThrowTypeError (ctx, "blob constructor: argument 1 not a blob"); + return JS_RaiseDisrupt (ctx, "blob constructor: argument 1 not a blob"); int64_t from = 0, to = (int64_t)src->length; if (argc >= 2 && JS_IsNumber (argv[1])) { JS_ToInt64 (ctx, &from, argv[1]); @@ -9586,31 +9522,31 @@ static JSValue js_blob_constructor (JSContext *ctx, JSValue this_val, int argc, JS_FreeCString (ctx, str); return bv; } - return JS_ThrowTypeError (ctx, "blob constructor: invalid arguments"); + return JS_RaiseDisrupt (ctx, "blob constructor: invalid arguments"); } /* blob.write_bit(logical) */ static JSValue js_blob_write_bit (JSContext *ctx, JSValue this_val, int argc, JSValue *argv) { if (argc < 1) - return JS_ThrowTypeError (ctx, "write_bit(logical) requires 1 argument"); + return JS_RaiseDisrupt (ctx, "write_bit(logical) requires 1 argument"); JSBlob *bd = checked_get_blob (ctx, this_val); - if (!bd) return JS_ThrowTypeError (ctx, "write_bit: not called on a blob"); + if (!bd) return JS_RaiseDisrupt (ctx, "write_bit: not called on a blob"); if (objhdr_s (bd->mist_hdr)) - return JS_ThrowTypeError (ctx, "write_bit: cannot write (maybe stone or OOM)"); + return JS_RaiseDisrupt (ctx, "write_bit: cannot write (maybe stone or OOM)"); int bit_val; if (JS_IsNumber (argv[0])) { int32_t num; JS_ToInt32 (ctx, &num, argv[0]); if (num != 0 && num != 1) - return JS_ThrowTypeError (ctx, "write_bit: value must be true, false, 0, or 1"); + return JS_RaiseDisrupt (ctx, "write_bit: value must be true, false, 0, or 1"); bit_val = num; } else { bit_val = JS_ToBool (ctx, argv[0]); } if (blob_ensure_cap (ctx, &this_val, bd->length + 1) < 0) - return JS_ThrowTypeError (ctx, "write_bit: cannot write (maybe stone or OOM)"); + return JS_RaiseDisrupt (ctx, "write_bit: cannot write (maybe stone or OOM)"); bd = (JSBlob *)chase (this_val); uint8_t *data = (uint8_t *)bd->bits; size_t idx = bd->length; @@ -9625,14 +9561,14 @@ static JSValue js_blob_write_bit (JSContext *ctx, JSValue this_val, int argc, JS /* blob.write_blob(second_blob) */ static JSValue js_blob_write_blob (JSContext *ctx, JSValue this_val, int argc, JSValue *argv) { if (argc < 1) - return JS_ThrowTypeError (ctx, "write_blob(second_blob) requires 1 argument"); + return JS_RaiseDisrupt (ctx, "write_blob(second_blob) requires 1 argument"); JSBlob *bd = checked_get_blob (ctx, this_val); - if (!bd) return JS_ThrowTypeError (ctx, "write_blob: not called on a blob"); + if (!bd) return JS_RaiseDisrupt (ctx, "write_blob: not called on a blob"); if (objhdr_s (bd->mist_hdr)) - return JS_ThrowTypeError (ctx, "write_blob: cannot write to stone blob or OOM"); + return JS_RaiseDisrupt (ctx, "write_blob: cannot write to stone blob or OOM"); JSBlob *second = checked_get_blob (ctx, argv[0]); if (!second) - return JS_ThrowTypeError (ctx, "write_blob: argument must be a blob"); + return JS_RaiseDisrupt (ctx, "write_blob: argument must be a blob"); size_t src_len = second->length; if (src_len == 0) return JS_NULL; @@ -9648,7 +9584,7 @@ static JSValue js_blob_write_blob (JSContext *ctx, JSValue this_val, int argc, J if (blob_ensure_cap (ctx, &this_ref.val, bd->length + src_len) < 0) { JS_PopGCRef (ctx, &arg_ref); JS_PopGCRef (ctx, &this_ref); - return JS_ThrowTypeError (ctx, "write_blob: cannot write to stone blob or OOM"); + return JS_RaiseDisrupt (ctx, "write_blob: cannot write to stone blob or OOM"); } bd = (JSBlob *)chase (this_ref.val); second = (JSBlob *)chase (arg_ref.val); @@ -9664,18 +9600,18 @@ static JSValue js_blob_write_blob (JSContext *ctx, JSValue this_val, int argc, J /* blob.write_number(number) - write dec64 */ static JSValue js_blob_write_number (JSContext *ctx, JSValue this_val, int argc, JSValue *argv) { if (argc < 1) - return JS_ThrowTypeError (ctx, "write_number(number) requires 1 argument"); + return JS_RaiseDisrupt (ctx, "write_number(number) requires 1 argument"); JSBlob *bd = checked_get_blob (ctx, this_val); if (!bd) - return JS_ThrowTypeError (ctx, "write_number: not called on a blob"); + return JS_RaiseDisrupt (ctx, "write_number: not called on a blob"); if (objhdr_s (bd->mist_hdr)) - return JS_ThrowTypeError (ctx, "write_number: cannot write to stone blob or OOM"); + return JS_RaiseDisrupt (ctx, "write_number: cannot write to stone blob or OOM"); double d; if (JS_ToFloat64 (ctx, &d, argv[0]) < 0) return JS_EXCEPTION; if (blob_ensure_cap (ctx, &this_val, bd->length + 64) < 0) - return JS_ThrowTypeError (ctx, "write_number: cannot write to stone blob or OOM"); + return JS_RaiseDisrupt (ctx, "write_number: cannot write to stone blob or OOM"); bd = (JSBlob *)chase (this_val); copy_bits_fast (&d, bd->bits, 0, 63, bd->length); bd->length += 64; @@ -9685,30 +9621,30 @@ static JSValue js_blob_write_number (JSContext *ctx, JSValue this_val, int argc, /* blob.write_fit(value, len) */ static JSValue js_blob_write_fit (JSContext *ctx, JSValue this_val, int argc, JSValue *argv) { if (argc < 2) - return JS_ThrowTypeError (ctx, "write_fit(value, len) requires 2 arguments"); + return JS_RaiseDisrupt (ctx, "write_fit(value, len) requires 2 arguments"); JSBlob *bd = checked_get_blob (ctx, this_val); - if (!bd) return JS_ThrowTypeError (ctx, "write_fit: not called on a blob"); + if (!bd) return JS_RaiseDisrupt (ctx, "write_fit: not called on a blob"); if (objhdr_s (bd->mist_hdr)) - return JS_ThrowTypeError (ctx, "write_fit: value doesn't fit or stone blob"); + return JS_RaiseDisrupt (ctx, "write_fit: value doesn't fit or stone blob"); int64_t value; int32_t len; if (JS_ToInt64 (ctx, &value, argv[0]) < 0) return JS_EXCEPTION; if (JS_ToInt32 (ctx, &len, argv[1]) < 0) return JS_EXCEPTION; if (len < 1 || len > 64) - return JS_ThrowTypeError (ctx, "write_fit: value doesn't fit or stone blob"); + return JS_RaiseDisrupt (ctx, "write_fit: value doesn't fit or stone blob"); /* Check if value fits in len bits with sign */ if (len < 64) { int64_t max = (1LL << (len - 1)) - 1; int64_t min = -(1LL << (len - 1)); if (value < min || value > max) - return JS_ThrowTypeError (ctx, "write_fit: value doesn't fit or stone blob"); + return JS_RaiseDisrupt (ctx, "write_fit: value doesn't fit or stone blob"); } if (blob_ensure_cap (ctx, &this_val, bd->length + len) < 0) - return JS_ThrowTypeError (ctx, "write_fit: value doesn't fit or stone blob"); + return JS_RaiseDisrupt (ctx, "write_fit: value doesn't fit or stone blob"); bd = (JSBlob *)chase (this_val); copy_bits_fast (&value, bd->bits, 0, len - 1, bd->length); bd->length += len; @@ -9718,12 +9654,12 @@ static JSValue js_blob_write_fit (JSContext *ctx, JSValue this_val, int argc, JS /* blob.write_text(text) */ static JSValue js_blob_write_text (JSContext *ctx, JSValue this_val, int argc, JSValue *argv) { if (argc < 1) - return JS_ThrowTypeError (ctx, "write_text(text) requires 1 argument"); + return JS_RaiseDisrupt (ctx, "write_text(text) requires 1 argument"); JSBlob *bd = checked_get_blob (ctx, this_val); - if (!bd) return JS_ThrowTypeError (ctx, "write_text: not called on a blob"); + if (!bd) return JS_RaiseDisrupt (ctx, "write_text: not called on a blob"); if (objhdr_s (bd->mist_hdr)) - return JS_ThrowTypeError (ctx, "write_text: cannot write to stone blob or OOM"); + return JS_RaiseDisrupt (ctx, "write_text: cannot write to stone blob or OOM"); const char *str = JS_ToCString (ctx, argv[0]); if (!str) return JS_EXCEPTION; @@ -9732,7 +9668,7 @@ static JSValue js_blob_write_text (JSContext *ctx, JSValue this_val, int argc, J if (blob_ensure_cap (ctx, &this_val, bd->length + need) < 0) { JS_FreeCString (ctx, str); - return JS_ThrowTypeError (ctx, "write_text: cannot write to stone blob or OOM"); + return JS_RaiseDisrupt (ctx, "write_text: cannot write to stone blob or OOM"); } bd = (JSBlob *)chase (this_val); @@ -9754,17 +9690,17 @@ static JSValue js_blob_write_text (JSContext *ctx, JSValue this_val, int argc, J /* blob.write_pad(block_size) */ static JSValue js_blob_write_pad (JSContext *ctx, JSValue this_val, int argc, JSValue *argv) { if (argc < 1) - return JS_ThrowTypeError (ctx, "write_pad(block_size) requires 1 argument"); + return JS_RaiseDisrupt (ctx, "write_pad(block_size) requires 1 argument"); JSBlob *bd = checked_get_blob (ctx, this_val); - if (!bd) return JS_ThrowTypeError (ctx, "write_pad: not called on a blob"); + if (!bd) return JS_RaiseDisrupt (ctx, "write_pad: not called on a blob"); if (objhdr_s (bd->mist_hdr)) - return JS_ThrowTypeError (ctx, "write_pad: cannot write"); + return JS_RaiseDisrupt (ctx, "write_pad: cannot write"); int32_t block_size; if (JS_ToInt32 (ctx, &block_size, argv[0]) < 0) return JS_EXCEPTION; if (block_size <= 0) - return JS_ThrowTypeError (ctx, "write_pad: cannot write"); + return JS_RaiseDisrupt (ctx, "write_pad: cannot write"); /* Write a 1 bit, then zeros to align to block_size */ size_t after_one = bd->length + 1; @@ -9773,7 +9709,7 @@ static JSValue js_blob_write_pad (JSContext *ctx, JSValue this_val, int argc, JS size_t total_pad = 1 + pad_zeros; if (blob_ensure_cap (ctx, &this_val, bd->length + total_pad) < 0) - return JS_ThrowTypeError (ctx, "write_pad: cannot write"); + return JS_RaiseDisrupt (ctx, "write_pad: cannot write"); bd = (JSBlob *)chase (this_val); uint8_t *data = (uint8_t *)bd->bits; @@ -9794,19 +9730,19 @@ static JSValue js_blob_write_pad (JSContext *ctx, JSValue this_val, int argc, JS /* blob.w16(value) - write 16-bit value */ static JSValue js_blob_w16 (JSContext *ctx, JSValue this_val, int argc, JSValue *argv) { if (argc < 1) - return JS_ThrowTypeError (ctx, "w16(value) requires 1 argument"); + return JS_RaiseDisrupt (ctx, "w16(value) requires 1 argument"); JSBlob *bd = checked_get_blob (ctx, this_val); - if (!bd) return JS_ThrowTypeError (ctx, "w16: not called on a blob"); + if (!bd) return JS_RaiseDisrupt (ctx, "w16: not called on a blob"); if (objhdr_s (bd->mist_hdr)) - return JS_ThrowTypeError (ctx, "w16: cannot write"); + return JS_RaiseDisrupt (ctx, "w16: cannot write"); int32_t value; if (JS_ToInt32 (ctx, &value, argv[0]) < 0) return JS_EXCEPTION; int16_t short_val = (int16_t)value; if (blob_ensure_cap (ctx, &this_val, bd->length + 16) < 0) - return JS_ThrowTypeError (ctx, "w16: cannot write"); + return JS_RaiseDisrupt (ctx, "w16: cannot write"); bd = (JSBlob *)chase (this_val); uint8_t *data = (uint8_t *)bd->bits; @@ -9823,18 +9759,18 @@ static JSValue js_blob_w16 (JSContext *ctx, JSValue this_val, int argc, JSValue /* blob.w32(value) - write 32-bit value */ static JSValue js_blob_w32 (JSContext *ctx, JSValue this_val, int argc, JSValue *argv) { if (argc < 1) - return JS_ThrowTypeError (ctx, "w32(value) requires 1 argument"); + return JS_RaiseDisrupt (ctx, "w32(value) requires 1 argument"); JSBlob *bd = checked_get_blob (ctx, this_val); - if (!bd) return JS_ThrowTypeError (ctx, "w32: not called on a blob"); + if (!bd) return JS_RaiseDisrupt (ctx, "w32: not called on a blob"); if (objhdr_s (bd->mist_hdr)) - return JS_ThrowTypeError (ctx, "w32: cannot write"); + return JS_RaiseDisrupt (ctx, "w32: cannot write"); int32_t value; if (JS_ToInt32 (ctx, &value, argv[0]) < 0) return JS_EXCEPTION; if (blob_ensure_cap (ctx, &this_val, bd->length + 32) < 0) - return JS_ThrowTypeError (ctx, "w32: cannot write"); + return JS_RaiseDisrupt (ctx, "w32: cannot write"); bd = (JSBlob *)chase (this_val); uint8_t *data = (uint8_t *)bd->bits; @@ -9851,12 +9787,12 @@ static JSValue js_blob_w32 (JSContext *ctx, JSValue this_val, int argc, JSValue /* blob.wf(value) - write float */ static JSValue js_blob_wf (JSContext *ctx, JSValue this_val, JSValue arg0) { if (JS_IsNull (arg0)) - return JS_ThrowTypeError (ctx, "wf(value) requires 1 argument"); + return JS_RaiseDisrupt (ctx, "wf(value) requires 1 argument"); JSBlob *bd = checked_get_blob (ctx, this_val); - if (!bd) return JS_ThrowTypeError (ctx, "wf: not called on a blob"); + if (!bd) return JS_RaiseDisrupt (ctx, "wf: not called on a blob"); if (objhdr_s (bd->mist_hdr)) - return JS_ThrowTypeError (ctx, "wf: cannot write"); + return JS_RaiseDisrupt (ctx, "wf: cannot write"); float f; double d; @@ -9864,7 +9800,7 @@ static JSValue js_blob_wf (JSContext *ctx, JSValue this_val, JSValue arg0) { f = (float)d; if (blob_ensure_cap (ctx, &this_val, bd->length + 32) < 0) - return JS_ThrowTypeError (ctx, "wf: cannot write"); + return JS_RaiseDisrupt (ctx, "wf: cannot write"); bd = (JSBlob *)chase (this_val); uint8_t *data = (uint8_t *)bd->bits; @@ -9881,17 +9817,17 @@ static JSValue js_blob_wf (JSContext *ctx, JSValue this_val, JSValue arg0) { /* blob.read_logical(from) */ static JSValue js_blob_read_logical (JSContext *ctx, JSValue this_val, int argc, JSValue *argv) { if (argc < 1) - return JS_ThrowTypeError (ctx, "read_logical(from) requires 1 argument"); + return JS_RaiseDisrupt (ctx, "read_logical(from) requires 1 argument"); JSBlob *bd = checked_get_blob (ctx, this_val); if (!bd) - return JS_ThrowTypeError (ctx, "read_logical: not called on a blob"); + return JS_RaiseDisrupt (ctx, "read_logical: not called on a blob"); if (!objhdr_s (bd->mist_hdr)) - return JS_ThrowTypeError (ctx, "read_logical: blob must be stone"); + return JS_RaiseDisrupt (ctx, "read_logical: blob must be stone"); int64_t pos; if (JS_ToInt64 (ctx, &pos, argv[0]) < 0) - return JS_ThrowInternalError (ctx, "must provide a positive bit"); + return JS_RaiseDisrupt (ctx, "must provide a positive bit"); if (pos < 0 || (size_t)pos >= bd->length) - return JS_ThrowRangeError (ctx, "read_logical: position must be non-negative"); + return JS_RaiseDisrupt (ctx, "read_logical: position must be non-negative"); uint8_t *data = (uint8_t *)bd->bits; int bit_val = (data[pos >> 3] >> (pos & 7)) & 1; return JS_NewBool (ctx, bit_val); @@ -9900,9 +9836,9 @@ static JSValue js_blob_read_logical (JSContext *ctx, JSValue this_val, int argc, /* blob.read_blob(from, to) */ JSValue js_blob_read_blob (JSContext *ctx, JSValue this_val, int argc, JSValue *argv) { JSBlob *bd = checked_get_blob (ctx, this_val); - if (!bd) return JS_ThrowTypeError (ctx, "read_blob: not called on a blob"); + if (!bd) return JS_RaiseDisrupt (ctx, "read_blob: not called on a blob"); if (!objhdr_s (bd->mist_hdr)) - return JS_ThrowTypeError (ctx, "read_blob: blob must be stone"); + return JS_RaiseDisrupt (ctx, "read_blob: blob must be stone"); int64_t from = 0; int64_t to = (int64_t)bd->length; @@ -9940,17 +9876,17 @@ JSValue js_blob_read_blob (JSContext *ctx, JSValue this_val, int argc, JSValue * /* blob.read_number(from) */ static JSValue js_blob_read_number (JSContext *ctx, JSValue this_val, int argc, JSValue *argv) { if (argc < 1) - return JS_ThrowTypeError (ctx, "read_number(from) requires 1 argument"); + return JS_RaiseDisrupt (ctx, "read_number(from) requires 1 argument"); JSBlob *bd = checked_get_blob (ctx, this_val); - if (!bd) return JS_ThrowTypeError (ctx, "read_number: not called on a blob"); + if (!bd) return JS_RaiseDisrupt (ctx, "read_number: not called on a blob"); if (!objhdr_s (bd->mist_hdr)) - return JS_ThrowTypeError (ctx, "read_number: blob must be stone"); + return JS_RaiseDisrupt (ctx, "read_number: blob must be stone"); double from_d; if (JS_ToFloat64 (ctx, &from_d, argv[0]) < 0) return JS_EXCEPTION; size_t from = (size_t)from_d; if (from_d < 0 || from + 64 > bd->length) - return JS_ThrowRangeError (ctx, "read_number: out of range"); + return JS_RaiseDisrupt (ctx, "read_number: out of range"); double d; copy_bits_fast (bd->bits, &d, from, from + 63, 0); @@ -9960,12 +9896,12 @@ static JSValue js_blob_read_number (JSContext *ctx, JSValue this_val, int argc, /* blob.read_fit(from, len) */ static JSValue js_blob_read_fit (JSContext *ctx, JSValue this_val, int argc, JSValue *argv) { if (argc < 2) - return JS_ThrowTypeError (ctx, "read_fit(from, len) requires 2 arguments"); + return JS_RaiseDisrupt (ctx, "read_fit(from, len) requires 2 arguments"); JSBlob *bd = checked_get_blob (ctx, this_val); - if (!bd) return JS_ThrowTypeError (ctx, "read_fit: not called on a blob"); + if (!bd) return JS_RaiseDisrupt (ctx, "read_fit: not called on a blob"); if (!objhdr_s (bd->mist_hdr)) - return JS_ThrowTypeError (ctx, "read_fit: blob must be stone"); + return JS_RaiseDisrupt (ctx, "read_fit: blob must be stone"); int64_t from; int32_t len; @@ -9973,9 +9909,9 @@ static JSValue js_blob_read_fit (JSContext *ctx, JSValue this_val, int argc, JSV if (JS_ToInt32 (ctx, &len, argv[1]) < 0) return JS_EXCEPTION; if (from < 0) - return JS_ThrowRangeError (ctx, "read_fit: position must be non-negative"); + return JS_RaiseDisrupt (ctx, "read_fit: position must be non-negative"); if (len < 1 || len > 64 || from + len > (int64_t)bd->length) - return JS_ThrowRangeError (ctx, "read_fit: out of range or invalid length"); + return JS_RaiseDisrupt (ctx, "read_fit: out of range or invalid length"); int64_t value = 0; copy_bits_fast (bd->bits, &value, (size_t)from, (size_t)(from + len - 1), 0); @@ -9992,9 +9928,9 @@ static JSValue js_blob_read_fit (JSContext *ctx, JSValue this_val, int argc, JSV /* blob.read_text(from) */ JSValue js_blob_read_text (JSContext *ctx, JSValue this_val, int argc, JSValue *argv) { JSBlob *bd = checked_get_blob (ctx, this_val); - if (!bd) return JS_ThrowTypeError (ctx, "read_text: not called on a blob"); + if (!bd) return JS_RaiseDisrupt (ctx, "read_text: not called on a blob"); if (!objhdr_s (bd->mist_hdr)) - return JS_ThrowTypeError (ctx, "read_text: blob must be stone"); + return JS_RaiseDisrupt (ctx, "read_text: blob must be stone"); int64_t from = 0; if (argc >= 1) { @@ -10003,20 +9939,20 @@ JSValue js_blob_read_text (JSContext *ctx, JSValue this_val, int argc, JSValue * /* Need at least 64 bits for length prefix */ if (from < 0 || (size_t)from + 64 > bd->length) - return JS_ThrowRangeError (ctx, "read_text: out of range or invalid encoding"); + return JS_RaiseDisrupt (ctx, "read_text: out of range or invalid encoding"); int64_t raw_len = 0; copy_bits_fast (bd->bits, &raw_len, (size_t)from, (size_t)from + 63, 0); if (raw_len < 0) - return JS_ThrowRangeError (ctx, "read_text: out of range or invalid encoding"); + return JS_RaiseDisrupt (ctx, "read_text: out of range or invalid encoding"); size_t slen = (size_t)raw_len; size_t after_len = (size_t)from + 64; if (after_len + slen * 8 > bd->length) - return JS_ThrowRangeError (ctx, "read_text: out of range or invalid encoding"); + return JS_RaiseDisrupt (ctx, "read_text: out of range or invalid encoding"); char *str = sys_malloc (slen + 1); - if (!str) return JS_ThrowOutOfMemory (ctx); + if (!str) return JS_RaiseOOM(ctx); if (slen > 0) copy_bits_fast (bd->bits, str, after_len, after_len + slen * 8 - 1, 0); str[slen] = '\0'; @@ -10029,11 +9965,11 @@ JSValue js_blob_read_text (JSContext *ctx, JSValue this_val, int argc, JSValue * /* blob.pad?(from, block_size) */ static JSValue js_blob_pad_q (JSContext *ctx, JSValue this_val, int argc, JSValue *argv) { if (argc < 2) - return JS_ThrowTypeError (ctx, "pad?(from, block_size) requires 2 arguments"); + return JS_RaiseDisrupt (ctx, "pad?(from, block_size) requires 2 arguments"); JSBlob *bd = checked_get_blob (ctx, this_val); - if (!bd) return JS_ThrowTypeError (ctx, "pad?: not called on a blob"); + if (!bd) return JS_RaiseDisrupt (ctx, "pad?: not called on a blob"); if (!objhdr_s (bd->mist_hdr)) - return JS_ThrowTypeError (ctx, "pad?: blob must be stone"); + return JS_RaiseDisrupt (ctx, "pad?: blob must be stone"); int64_t from; int32_t block_size; @@ -10107,18 +10043,18 @@ JSValue js_new_blob_stoned_copy (JSContext *js, void *data, size_t bytes) { void *js_get_blob_data (JSContext *js, size_t *size, JSValue v) { JSBlob *bd = checked_get_blob (js, v); if (!bd) { - JS_ThrowReferenceError (js, "get_blob_data: not called on a blob"); + JS_RaiseDisrupt (js, "get_blob_data: not called on a blob"); return NULL; } *size = (bd->length + 7) / 8; if (!objhdr_s (bd->mist_hdr)) { - JS_ThrowReferenceError (js, "attempted to read data from a non-stone blob"); + JS_RaiseDisrupt (js, "attempted to read data from a non-stone blob"); return NULL; } if (bd->length % 8 != 0) { - JS_ThrowReferenceError ( + JS_RaiseDisrupt ( js, "attempted to read data from a non-byte aligned blob [length is %llu]", (unsigned long long)bd->length); @@ -10133,21 +10069,21 @@ void *js_get_blob_data (JSContext *js, size_t *size, JSValue v) { void *js_get_blob_data_bits (JSContext *js, size_t *bits, JSValue v) { JSBlob *bd = checked_get_blob (js, v); if (!bd) { - JS_ThrowReferenceError (js, "get_blob_data_bits: not called on a blob"); + JS_RaiseDisrupt (js, "get_blob_data_bits: not called on a blob"); return NULL; } if (!objhdr_s (bd->mist_hdr)) { - JS_ThrowReferenceError (js, "attempted to read data from a non-stone blob"); + JS_RaiseDisrupt (js, "attempted to read data from a non-stone blob"); return NULL; } if (bd->length % 8 != 0) { - JS_ThrowReferenceError (js, "attempted to read data from a non-byte aligned blob"); + JS_RaiseDisrupt (js, "attempted to read data from a non-byte aligned blob"); return NULL; } if (bd->length == 0) { - JS_ThrowReferenceError (js, "attempted to read data from an empty blob"); + JS_RaiseDisrupt (js, "attempted to read data from an empty blob"); return NULL; } @@ -10168,7 +10104,7 @@ int js_is_blob (JSContext *js, JSValue v) { /* mach_load(blob, env?) - deserialize and execute binary blob */ static JSValue js_mach_load (JSContext *ctx, JSValue this_val, int argc, JSValue *argv) { if (argc < 1) - return JS_ThrowTypeError (ctx, "mach_load requires a blob argument"); + return JS_RaiseDisrupt (ctx, "mach_load requires a blob argument"); size_t data_size; void *data = js_get_blob_data (ctx, &data_size, argv[0]); @@ -10176,7 +10112,7 @@ static JSValue js_mach_load (JSContext *ctx, JSValue this_val, int argc, JSValue MachCode *mc = JS_DeserializeMachCode ((const uint8_t *)data, data_size); if (!mc) - return JS_ThrowSyntaxError (ctx, "mach_load: failed to deserialize bytecode"); + return JS_RaiseDisrupt (ctx, "mach_load: failed to deserialize bytecode"); JSValue env = (argc >= 2 && mist_is_gc_object (argv[1])) ? argv[1] : JS_NULL; @@ -10188,7 +10124,7 @@ static JSValue js_mach_load (JSContext *ctx, JSValue this_val, int argc, JSValue /* mach_eval_mcode(name, mcode_json, env?) - compile mcode IR and run via register VM */ static JSValue js_mach_eval_mcode (JSContext *ctx, JSValue this_val, int argc, JSValue *argv) { if (argc < 2 || !JS_IsText (argv[0]) || !JS_IsText (argv[1])) - return JS_ThrowTypeError (ctx, "mach_eval_mcode requires (name, mcode_json) text arguments"); + return JS_RaiseDisrupt (ctx, "mach_eval_mcode requires (name, mcode_json) text arguments"); const char *name = JS_ToCString (ctx, argv[0]); if (!name) return JS_EXCEPTION; @@ -10204,7 +10140,7 @@ static JSValue js_mach_eval_mcode (JSContext *ctx, JSValue this_val, int argc, J if (!mcode) { JS_FreeCString (ctx, name); - return JS_ThrowSyntaxError (ctx, "mach_eval_mcode: failed to parse mcode JSON"); + return JS_RaiseDisrupt (ctx, "mach_eval_mcode: failed to parse mcode JSON"); } /* Set filename on the mcode root if not present */ @@ -10217,7 +10153,7 @@ static JSValue js_mach_eval_mcode (JSContext *ctx, JSValue this_val, int argc, J if (!mc) { JS_FreeCString (ctx, name); - return JS_ThrowInternalError (ctx, "mach_eval_mcode: compilation failed"); + return JS_RaiseDisrupt (ctx, "mach_eval_mcode: compilation failed"); } JSValue env = (argc >= 3 && mist_is_gc_object (argv[2])) ? argv[2] : JS_NULL; @@ -10232,7 +10168,7 @@ static JSValue js_mach_eval_mcode (JSContext *ctx, JSValue this_val, int argc, J /* mach_dump_mcode(name, mcode_json, env?) - compile mcode IR and dump bytecode disassembly */ static JSValue js_mach_dump_mcode (JSContext *ctx, JSValue this_val, int argc, JSValue *argv) { if (argc < 2 || !JS_IsText (argv[0]) || !JS_IsText (argv[1])) - return JS_ThrowTypeError (ctx, "mach_dump_mcode requires (name, mcode_json) text arguments"); + return JS_RaiseDisrupt (ctx, "mach_dump_mcode requires (name, mcode_json) text arguments"); const char *name = JS_ToCString (ctx, argv[0]); if (!name) return JS_EXCEPTION; @@ -10248,7 +10184,7 @@ static JSValue js_mach_dump_mcode (JSContext *ctx, JSValue this_val, int argc, J if (!mcode) { JS_FreeCString (ctx, name); - return JS_ThrowSyntaxError (ctx, "mach_dump_mcode: failed to parse mcode JSON"); + return JS_RaiseDisrupt (ctx, "mach_dump_mcode: failed to parse mcode JSON"); } if (!cJSON_GetObjectItemCaseSensitive (mcode, "filename")) @@ -10259,7 +10195,7 @@ static JSValue js_mach_dump_mcode (JSContext *ctx, JSValue this_val, int argc, J if (!mc) { JS_FreeCString (ctx, name); - return JS_ThrowInternalError (ctx, "mach_dump_mcode: compilation failed"); + return JS_RaiseDisrupt (ctx, "mach_dump_mcode: compilation failed"); } JSValue env = (argc >= 3 && mist_is_gc_object (argv[2])) ? argv[2] : JS_NULL; @@ -10294,7 +10230,7 @@ static JSValue js_gc_stats (JSContext *ctx, JSValue this_val, int argc, JSValue /* mach_compile_mcode_bin(name, mcode_json) - compile mcode IR to serialized binary blob */ static JSValue js_mach_compile_mcode_bin (JSContext *ctx, JSValue this_val, int argc, JSValue *argv) { if (argc < 2 || !JS_IsText (argv[0]) || !JS_IsText (argv[1])) - return JS_ThrowTypeError (ctx, "mach_compile_mcode_bin requires (name, mcode_json) text arguments"); + return JS_RaiseDisrupt (ctx, "mach_compile_mcode_bin requires (name, mcode_json) text arguments"); const char *name = JS_ToCString (ctx, argv[0]); if (!name) return JS_EXCEPTION; @@ -10310,7 +10246,7 @@ static JSValue js_mach_compile_mcode_bin (JSContext *ctx, JSValue this_val, int if (!mcode) { JS_FreeCString (ctx, name); - return JS_ThrowSyntaxError (ctx, "mach_compile_mcode_bin: failed to parse mcode JSON"); + return JS_RaiseDisrupt (ctx, "mach_compile_mcode_bin: failed to parse mcode JSON"); } if (!cJSON_GetObjectItemCaseSensitive (mcode, "filename")) @@ -10321,7 +10257,7 @@ static JSValue js_mach_compile_mcode_bin (JSContext *ctx, JSValue this_val, int JS_FreeCString (ctx, name); if (!mc) - return JS_ThrowInternalError (ctx, "mach_compile_mcode_bin: compilation failed"); + return JS_RaiseDisrupt (ctx, "mach_compile_mcode_bin: compilation failed"); size_t size = 0; uint8_t *data = JS_SerializeMachCode (mc, &size); @@ -10329,7 +10265,7 @@ static JSValue js_mach_compile_mcode_bin (JSContext *ctx, JSValue this_val, int JS_FreeMachCode (mc); if (!data) - return JS_ThrowInternalError (ctx, "mach_compile_mcode_bin: serialization failed"); + return JS_RaiseDisrupt (ctx, "mach_compile_mcode_bin: serialization failed"); JSValue blob = js_new_blob_stoned_copy (ctx, data, size); sys_free (data); @@ -10452,14 +10388,14 @@ JSValue JS_Stone (JSContext *ctx, JSValue this_val) { Returns 0 on success, -1 on error. */ int JS_ArrayPush (JSContext *ctx, JSValue *arr_ptr, JSValue val) { if (!JS_IsArray (*arr_ptr)) { - JS_ThrowTypeError (ctx, "not an array"); + JS_RaiseDisrupt (ctx, "not an array"); return -1; } return js_intrinsic_array_push (ctx, arr_ptr, val); } JSValue JS_ArrayPop (JSContext *ctx, JSValue obj) { - if (!JS_IsArray (obj)) return JS_ThrowTypeError (ctx, "not an array"); + if (!JS_IsArray (obj)) return JS_RaiseDisrupt (ctx, "not an array"); return js_cell_pop (ctx, JS_NULL, 1, &obj); } @@ -10846,7 +10782,7 @@ static JSValue js_cell_proto (JSContext *ctx, JSValue this_val, int argc, JSValu JSValue obj = argv[0]; if (JS_IsArray (obj)) { - return JS_ThrowTypeError (ctx, "arrays do not have prototypes"); + return JS_RaiseDisrupt (ctx, "arrays do not have prototypes"); } if (!mist_is_gc_object (obj)) return JS_NULL; @@ -11106,10 +11042,10 @@ static JSValue js_cell_length (JSContext *ctx, JSValue this_val, int argc, JSVal /* call(func, this_val, args_array) */ static JSValue js_cell_call (JSContext *ctx, JSValue this_val, int argc, JSValue *argv) { if (argc < 1) - return JS_ThrowTypeError (ctx, "call requires a function argument"); + return JS_RaiseDisrupt (ctx, "call requires a function argument"); if (!JS_IsFunction (argv[0])) - return JS_ThrowTypeError (ctx, "first argument must be a function"); + return JS_RaiseDisrupt (ctx, "first argument must be a function"); JSGCRef this_ref; JS_PushGCRef (ctx, &this_ref); @@ -11123,7 +11059,7 @@ static JSValue js_cell_call (JSContext *ctx, JSValue this_val, int argc, JSValue if (!JS_IsArray (argv[2])) { JS_PopGCRef (ctx, &this_ref); - return JS_ThrowTypeError (ctx, "third argument must be an array"); + return JS_RaiseDisrupt (ctx, "third argument must be an array"); } uint32_t len; @@ -11537,7 +11473,7 @@ void js_debug_sethook (JSContext *ctx, js_hook hook, int type, void *user) { static JSValue js_cell_json_encode (JSContext *ctx, JSValue this_val, int argc, JSValue *argv) { if (argc < 1) - return JS_ThrowTypeError (ctx, "json.encode requires at least 1 argument"); + return JS_RaiseDisrupt (ctx, "json.encode requires at least 1 argument"); BOOL pretty = argc <= 1 || JS_ToBool (ctx, argv[1]); JSValue space = pretty ? JS_NewInt32 (ctx, 2) : JS_NULL; @@ -11552,10 +11488,10 @@ static JSValue js_cell_json_encode (JSContext *ctx, JSValue this_val, int argc, static JSValue js_cell_json_decode (JSContext *ctx, JSValue this_val, int argc, JSValue *argv) { if (argc < 1) - return JS_ThrowTypeError (ctx, "json.decode requires at least 1 argument"); + return JS_RaiseDisrupt (ctx, "json.decode requires at least 1 argument"); if (!JS_IsText (argv[0])) - return JS_ThrowTypeError (ctx, "couldn't parse text: not a string"); + return JS_RaiseDisrupt (ctx, "couldn't parse text: not a string"); const char *str = JS_ToCString (ctx, argv[0]); if (!str) return JS_EXCEPTION; @@ -11949,7 +11885,7 @@ JSValue nota2value (JSContext *js, void *nota) { } static JSValue js_nota_encode (JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { - if (argc < 1) return JS_ThrowTypeError (ctx, "nota.encode requires at least 1 argument"); + if (argc < 1) return JS_RaiseDisrupt (ctx, "nota.encode requires at least 1 argument"); JSGCRef val_ref, replacer_ref, key_ref; JS_PushGCRef (ctx, &val_ref); @@ -11971,7 +11907,7 @@ static JSValue js_nota_encode (JSContext *ctx, JSValueConst this_val, int argc, JSValue ret; if (enc->cycle) { nota_buffer_free (&enc->nb); - ret = JS_ThrowReferenceError (ctx, "Tried to encode something to nota with a cycle."); + ret = JS_RaiseDisrupt (ctx, "Tried to encode something to nota with a cycle."); } else { size_t total_len = enc->nb.size; void *data_ptr = enc->nb.data; @@ -12447,7 +12383,7 @@ JSValue wota2value (JSContext *ctx, void *wota) { } static JSValue js_wota_encode (JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { - if (argc < 1) return JS_ThrowTypeError (ctx, "wota.encode requires at least 1 argument"); + if (argc < 1) return JS_RaiseDisrupt (ctx, "wota.encode requires at least 1 argument"); size_t total_bytes; void *wota = value2wota (ctx, argv[0], JS_IsFunction (argv[1]) ? argv[1] : JS_NULL, &total_bytes); JSValue ret = js_new_blob_stoned_copy (ctx, wota, total_bytes); @@ -12460,7 +12396,7 @@ static JSValue js_wota_decode (JSContext *ctx, JSValueConst this_val, int argc, size_t len; uint8_t *buf = js_get_blob_data (ctx, &len, argv[0]); if (buf == (uint8_t *)-1) return JS_EXCEPTION; - if (!buf || len == 0) return JS_ThrowTypeError (ctx, "No blob data present"); + if (!buf || len == 0) return JS_RaiseDisrupt (ctx, "No blob data present"); JSValue reviver = (argc > 1 && JS_IsFunction (argv[1])) ? argv[1] : JS_NULL; char *data_ptr = (char *)buf; JSGCRef result_ref, holder_ref, empty_key_ref; diff --git a/source/suite.c b/source/suite.c index bfb791c6..c395dcad 100644 --- a/source/suite.c +++ b/source/suite.c @@ -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));