diff --git a/.changeset/late-bags-scream.md b/.changeset/late-bags-scream.md new file mode 100644 index 00000000..716e47bf --- /dev/null +++ b/.changeset/late-bags-scream.md @@ -0,0 +1,5 @@ +--- +"@nx.js/runtime": patch +--- + +Revert "Refactor TCP and TLS code to remove `toPromise()` wrapper (f305fd4)" diff --git a/packages/runtime/src/$.ts b/packages/runtime/src/$.ts index 62e1a8bd..fa2bf1bd 100644 --- a/packages/runtime/src/$.ts +++ b/packages/runtime/src/$.ts @@ -14,6 +14,7 @@ import type { Versions, } from './switch'; import type { + Callback, Keys, Opaque, RGBA, @@ -245,9 +246,9 @@ export interface Init { swkbdUpdate(this: VirtualKeyboard): void; // tcp.c - connect(ip: string, port: number): Promise; - write(fd: number, data: ArrayBuffer): Promise; - read(fd: number, buffer: ArrayBuffer): Promise; + connect(cb: Callback, ip: string, port: number): void; + write(cb: Callback, fd: number, data: ArrayBuffer): void; + read(cb: Callback, fd: number, buffer: ArrayBuffer): void; close(fd: number): void; tcpServerInit(c: any): void; tcpServerNew( @@ -257,9 +258,21 @@ export interface Init { ): Server; // tls.c - tlsHandshake(fd: number, hostname: string): Promise; - tlsWrite(ctx: TlsContextOpaque, data: ArrayBuffer): Promise; - tlsRead(ctx: TlsContextOpaque, buffer: ArrayBuffer): Promise; + tlsHandshake( + cb: Callback, + fd: number, + hostname: string, + ): void; + tlsWrite( + cb: Callback, + ctx: TlsContextOpaque, + data: ArrayBuffer, + ): void; + tlsRead( + cb: Callback, + ctx: TlsContextOpaque, + buffer: ArrayBuffer, + ): void; // url.c urlInit(c: ClassOf): void; diff --git a/packages/runtime/src/internal.ts b/packages/runtime/src/internal.ts index 07e9fd10..b5bc3278 100644 --- a/packages/runtime/src/internal.ts +++ b/packages/runtime/src/internal.ts @@ -8,6 +8,22 @@ export type WasmModuleOpaque = Opaque<'WasmModuleOpaque'>; export type WasmInstanceOpaque = Opaque<'WasmInstanceOpaque'>; export type WasmGlobalOpaque = Opaque<'WasmGlobalOpaque'>; +export type Callback = (err: Error | null, result: T) => void; + +export type CallbackReturnType = T extends ( + fn: Callback, + ...args: any[] +) => any + ? U + : never; + +export type CallbackArguments = T extends ( + fn: Callback, + ...args: infer U +) => any + ? U + : never; + export interface SocketOptionsInternal extends SocketOptions { connect: typeof connect; } diff --git a/packages/runtime/src/tcp.ts b/packages/runtime/src/tcp.ts index b33a0ae3..d2051d7d 100644 --- a/packages/runtime/src/tcp.ts +++ b/packages/runtime/src/tcp.ts @@ -7,6 +7,7 @@ import { bufferSourceToArrayBuffer, createInternal, proto, + toPromise, } from './utils'; import type { BufferSource } from './types'; import { @@ -31,31 +32,31 @@ export async function connect(opts: SocketAddress) { if (!ip) { throw new Error(`Could not resolve "${hostname}" to an IP address`); } - return $.connect(ip, port); + return toPromise($.connect, ip, port); } function read(fd: number, buffer: BufferSource) { const ab = bufferSourceToArrayBuffer(buffer); - return $.read(fd, ab); + return toPromise($.read, fd, ab); } function write(fd: number, data: BufferSource) { const ab = bufferSourceToArrayBuffer(data); - return $.write(fd, ab); + return toPromise($.write, fd, ab); } function tlsHandshake(fd: number, hostname: string) { - return $.tlsHandshake(fd, hostname); + return toPromise($.tlsHandshake, fd, hostname); } function tlsRead(ctx: TlsContextOpaque, buffer: BufferSource) { const ab = bufferSourceToArrayBuffer(buffer); - return $.tlsRead(ctx, ab); + return toPromise($.tlsRead, ctx, ab); } function tlsWrite(ctx: TlsContextOpaque, data: BufferSource) { const ab = bufferSourceToArrayBuffer(data); - return $.tlsWrite(ctx, ab); + return toPromise($.tlsWrite, ctx, ab); } interface SocketInternal { diff --git a/packages/runtime/src/utils.ts b/packages/runtime/src/utils.ts index 1e634da0..909a0c37 100644 --- a/packages/runtime/src/utils.ts +++ b/packages/runtime/src/utils.ts @@ -1,6 +1,12 @@ import type { PathLike } from './switch'; import type { BufferSource } from './types'; -import { INTERNAL_SYMBOL, type RGBA } from './internal'; +import { + INTERNAL_SYMBOL, + type Callback, + type CallbackArguments, + type CallbackReturnType, + type RGBA, +} from './internal'; export const proto = any>( o: any, @@ -52,6 +58,24 @@ export function asyncIteratorToStream(it: AsyncIterableIterator) { }); } +export function toPromise< + Func extends (cb: Callback, ...args: any[]) => any, +>(fn: Func, ...args: CallbackArguments) { + return new Promise>((resolve, reject) => { + try { + fn( + (err, result) => { + if (err) return reject(err); + resolve(result); + }, + ...args, + ); + } catch (err) { + reject(err); + } + }); +} + export function assertInternalConstructor(a: ArrayLike) { if (a[0] !== INTERNAL_SYMBOL) throw new TypeError('Illegal constructor'); } diff --git a/source/tcp.c b/source/tcp.c index 8fecc203..d42008c3 100644 --- a/source/tcp.c +++ b/source/tcp.c @@ -9,23 +9,21 @@ void nx_on_connect(nx_poll_t *p, nx_connect_t *req) { nx_js_callback_t *req_cb = (nx_js_callback_t *)req->opaque; JSContext *ctx = req_cb->context; - JSValue ret_val; - JSValue args[1]; + JSValue args[] = {JS_UNDEFINED, JS_UNDEFINED}; if (req->err) { /* Error during connect. */ args[0] = JS_NewError(ctx); JS_SetPropertyStr(ctx, args[0], "message", JS_NewString(ctx, strerror(req->err))); - ret_val = JS_Call(ctx, req_cb->reject, JS_NULL, 1, args); } else { - args[0] = JS_NewInt32(ctx, req->fd); - ret_val = JS_Call(ctx, req_cb->resolve, JS_NULL, 1, args); + args[1] = JS_NewInt32(ctx, req->fd); } + JSValue ret_val = JS_Call(ctx, req_cb->callback, JS_NULL, 2, args); JS_FreeValue(ctx, args[0]); - JS_FreeValue(ctx, req_cb->resolve); - JS_FreeValue(ctx, req_cb->reject); + JS_FreeValue(ctx, args[1]); + JS_FreeValue(ctx, req_cb->callback); if (JS_IsException(ret_val)) { nx_emit_error_event(ctx); } @@ -37,8 +35,9 @@ void nx_on_connect(nx_poll_t *p, nx_connect_t *req) { JSValue nx_js_tcp_connect(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { int port; - const char *ip = JS_ToCString(ctx, argv[0]); - if (!ip || JS_ToInt32(ctx, &port, argv[1])) { + const char *ip = JS_ToCString(ctx, argv[1]); + if (!ip || JS_ToInt32(ctx, &port, argv[2])) { + JS_ThrowTypeError(ctx, "invalid input"); return JS_EXCEPTION; } @@ -46,10 +45,7 @@ JSValue nx_js_tcp_connect(JSContext *ctx, JSValueConst this_val, int argc, nx_connect_t *req = malloc(sizeof(nx_connect_t)); nx_js_callback_t *req_cb = malloc(sizeof(nx_js_callback_t)); req_cb->context = ctx; - JSValue promise, resolving_funcs[2]; - promise = JS_NewPromiseCapability(ctx, resolving_funcs); - req_cb->resolve = resolving_funcs[0]; - req_cb->reject = resolving_funcs[1]; + req_cb->callback = JS_DupValue(ctx, argv[0]); req_cb->buffer = JS_UNDEFINED; req->opaque = req_cb; @@ -60,30 +56,29 @@ JSValue nx_js_tcp_connect(JSContext *ctx, JSValueConst this_val, int argc, nx_on_connect(&nx_ctx->poll, req); } - return promise; + return JS_UNDEFINED; } void nx_on_read(nx_poll_t *p, nx_read_t *req) { nx_js_callback_t *req_cb = (nx_js_callback_t *)req->opaque; JSContext *ctx = req_cb->context; JS_FreeValue(ctx, req_cb->buffer); - JSValue ret_val; - JSValue args[1]; + + JSValue args[] = {JS_UNDEFINED, JS_UNDEFINED}; if (req->err) { /* Error during read. */ args[0] = JS_NewError(ctx); JS_SetPropertyStr(ctx, args[0], "message", JS_NewString(ctx, strerror(req->err))); - ret_val = JS_Call(ctx, req_cb->reject, JS_NULL, 1, args); } else { - args[0] = JS_NewInt32(ctx, req->bytes_read); - ret_val = JS_Call(ctx, req_cb->resolve, JS_NULL, 1, args); + args[1] = JS_NewInt32(ctx, req->bytes_read); } + JSValue ret_val = JS_Call(ctx, req_cb->callback, JS_NULL, 2, args); JS_FreeValue(ctx, args[0]); - JS_FreeValue(ctx, req_cb->resolve); - JS_FreeValue(ctx, req_cb->reject); + JS_FreeValue(ctx, args[1]); + JS_FreeValue(ctx, req_cb->callback); if (JS_IsException(ret_val)) { nx_emit_error_event(ctx); } @@ -95,10 +90,10 @@ void nx_on_read(nx_poll_t *p, nx_read_t *req) { JSValue nx_js_tcp_read(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { size_t buffer_size; - JSValue buffer_value = JS_DupValue(ctx, argv[1]); + JSValue buffer_value = JS_DupValue(ctx, argv[2]); uint8_t *buffer = JS_GetArrayBuffer(ctx, &buffer_size, buffer_value); int fd; - if (!buffer || JS_ToInt32(ctx, &fd, argv[0])) { + if (!buffer || JS_ToInt32(ctx, &fd, argv[1])) { return JS_EXCEPTION; } @@ -106,39 +101,35 @@ JSValue nx_js_tcp_read(JSContext *ctx, JSValueConst this_val, int argc, nx_read_t *req = malloc(sizeof(nx_read_t)); nx_js_callback_t *req_cb = malloc(sizeof(nx_js_callback_t)); req_cb->context = ctx; - JSValue promise, resolving_funcs[2]; - promise = JS_NewPromiseCapability(ctx, resolving_funcs); - req_cb->resolve = resolving_funcs[0]; - req_cb->reject = resolving_funcs[1]; + req_cb->callback = JS_DupValue(ctx, argv[0]); req_cb->buffer = buffer_value; req->opaque = req_cb; nx_read(&nx_ctx->poll, req, fd, buffer, buffer_size, nx_on_read); - return promise; + return JS_UNDEFINED; } void nx_on_write(nx_poll_t *p, nx_write_t *req) { nx_js_callback_t *req_cb = (nx_js_callback_t *)req->opaque; JSContext *ctx = req_cb->context; JS_FreeValue(ctx, req_cb->buffer); - JSValue ret_val; - JSValue args[1]; + + JSValue args[] = {JS_UNDEFINED, JS_UNDEFINED}; if (req->err) { /* Error during write. */ args[0] = JS_NewError(ctx); JS_SetPropertyStr(ctx, args[0], "message", JS_NewString(ctx, strerror(req->err))); - ret_val = JS_Call(ctx, req_cb->reject, JS_NULL, 1, args); } else { - args[0] = JS_NewInt32(ctx, req->bytes_written); - ret_val = JS_Call(ctx, req_cb->resolve, JS_NULL, 1, args); + args[1] = JS_NewInt32(ctx, req->bytes_written); } + JSValue ret_val = JS_Call(ctx, req_cb->callback, JS_NULL, 2, args); JS_FreeValue(ctx, args[0]); - JS_FreeValue(ctx, req_cb->resolve); - JS_FreeValue(ctx, req_cb->reject); + JS_FreeValue(ctx, args[1]); + JS_FreeValue(ctx, req_cb->callback); if (JS_IsException(ret_val)) { nx_emit_error_event(ctx); } @@ -150,10 +141,11 @@ void nx_on_write(nx_poll_t *p, nx_write_t *req) { JSValue nx_js_tcp_write(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { size_t buffer_size; - JSValue buffer_val = JS_DupValue(ctx, argv[1]); + JSValue buffer_val = JS_DupValue(ctx, argv[2]); uint8_t *buffer = JS_GetArrayBuffer(ctx, &buffer_size, buffer_val); int fd; - if (!buffer || JS_ToInt32(ctx, &fd, argv[0])) { + if (!buffer || JS_ToInt32(ctx, &fd, argv[1])) { + JS_ThrowTypeError(ctx, "invalid input"); return JS_EXCEPTION; } @@ -161,16 +153,13 @@ JSValue nx_js_tcp_write(JSContext *ctx, JSValueConst this_val, int argc, nx_write_t *req = malloc(sizeof(nx_write_t)); nx_js_callback_t *req_cb = malloc(sizeof(nx_js_callback_t)); req_cb->context = ctx; - JSValue promise, resolving_funcs[2]; - promise = JS_NewPromiseCapability(ctx, resolving_funcs); - req_cb->resolve = resolving_funcs[0]; - req_cb->reject = resolving_funcs[1]; + req_cb->callback = JS_DupValue(ctx, argv[0]); req_cb->buffer = buffer_val; req->opaque = req_cb; nx_write(&nx_ctx->poll, req, fd, buffer, buffer_size, nx_on_write); - return promise; + return JS_UNDEFINED; } JSValue nx_js_tcp_close(JSContext *ctx, JSValueConst this_val, int argc, @@ -203,8 +192,7 @@ static JSClassID nx_tcp_server_class_id; typedef struct { nx_server_t server; - JSContext *context; - JSValue callback; + nx_js_callback_t cb; } nx_js_tcp_server_t; static nx_js_tcp_server_t *nx_js_tcp_server_get(JSContext *ctx, @@ -213,12 +201,13 @@ static nx_js_tcp_server_t *nx_js_tcp_server_get(JSContext *ctx, } static void finalizer_tcp_server(JSRuntime *rt, JSValue val) { + fprintf(stderr, "finalizer_tcp_server\n"); nx_js_tcp_server_t *data = JS_GetOpaque(val, nx_tcp_server_class_id); if (data) { - nx_context_t *nx_ctx = JS_GetContextOpaque(data->context); + nx_context_t *nx_ctx = JS_GetContextOpaque(data->cb.context); nx_remove_watcher(&nx_ctx->poll, (nx_watcher_t *)&data->server); - if (!JS_IsUndefined(data->callback)) { - JS_FreeValue(data->context, data->callback); + if (!JS_IsUndefined(data->cb.callback)) { + JS_FreeValue(data->cb.context, data->cb.callback); } js_free_rt(rt, data); } @@ -227,7 +216,7 @@ static void finalizer_tcp_server(JSRuntime *rt, JSValue val) { void nx_on_accept(nx_poll_t *p, nx_server_t *req, int client_fd) { // Handle new client connection here // client_fd is the file descriptor for the new client - nx_js_tcp_server_t *req_cb = (nx_js_tcp_server_t *)req->opaque; + nx_js_callback_t *req_cb = (nx_js_callback_t *)req->opaque; JSValue args[] = {JS_NewInt32(req_cb->context, client_fd)}; JSValue ret_val = JS_Call(req_cb->context, req_cb->callback, JS_NULL, 1, args); @@ -242,20 +231,23 @@ JSValue nx_js_tcp_server_new(JSContext *ctx, JSValueConst this_val, int argc, const char *ip = JS_ToCString(ctx, argv[0]); int port; if (!ip || JS_ToInt32(ctx, &port, argv[1])) { + JS_ThrowTypeError(ctx, "invalid input"); return JS_EXCEPTION; } JSValue obj = JS_NewObjectClass(ctx, nx_tcp_server_class_id); nx_js_tcp_server_t *data = js_mallocz(ctx, sizeof(nx_js_tcp_server_t)); if (!data) { + JS_ThrowOutOfMemory(ctx); return JS_EXCEPTION; } JS_SetOpaque(obj, data); nx_context_t *nx_ctx = JS_GetContextOpaque(ctx); - data->context = ctx; - data->callback = JS_DupValue(ctx, argv[2]); - data->server.opaque = data; + data->cb.context = ctx; + data->cb.callback = JS_DupValue(ctx, argv[2]); + data->cb.buffer = JS_UNDEFINED; + data->server.opaque = &data->cb; int fd = nx_tcp_server(&nx_ctx->poll, &data->server, ip, port, nx_on_accept); @@ -274,8 +266,8 @@ JSValue nx_js_tcp_server_close(JSContext *ctx, JSValueConst this_val, int argc, nx_context_t *nx_ctx = JS_GetContextOpaque(ctx); nx_js_tcp_server_t *data = nx_js_tcp_server_get(ctx, this_val); nx_remove_watcher(&nx_ctx->poll, (nx_watcher_t *)&data->server); - JS_FreeValue(ctx, data->callback); - data->callback = JS_UNDEFINED; + JS_FreeValue(ctx, data->cb.callback); + data->cb.callback = JS_UNDEFINED; shutdown(data->server.fd, SHUT_RDWR); close(data->server.fd); return JS_UNDEFINED; diff --git a/source/tls.c b/source/tls.c index 7e8715dd..19634ce3 100644 --- a/source/tls.c +++ b/source/tls.c @@ -13,6 +13,7 @@ static nx_tls_context_t *nx_tls_context_get(JSContext *ctx, JSValueConst obj) { } static void finalizer_tls_context(JSRuntime *rt, JSValue val) { + fprintf(stderr, "finalizer_tls_context\n"); nx_tls_context_t *data = JS_GetOpaque(val, nx_tls_context_class_id); if (data) { mbedtls_net_free(&data->server_fd); @@ -24,32 +25,28 @@ static void finalizer_tls_context(JSRuntime *rt, JSValue val) { void nx_tls_on_connect(nx_poll_t *p, nx_tls_connect_t *req) { nx_js_callback_t *req_cb = (nx_js_callback_t *)req->opaque; - JSContext *ctx = req_cb->context; - JSValue ret_val; - JSValue args[1]; + JSValue args[] = {JS_UNDEFINED, JS_UNDEFINED}; if (req->err) { /* Error during TLS handshake */ char error_buf[100]; mbedtls_strerror(req->err, error_buf, 100); - args[0] = JS_NewError(ctx); - JS_SetPropertyStr(ctx, args[0], "message", - JS_NewString(ctx, error_buf)); - ret_val = JS_Call(ctx, req_cb->reject, JS_NULL, 1, args); + args[0] = JS_NewError(req_cb->context); + JS_SetPropertyStr(req_cb->context, args[0], "message", + JS_NewString(req_cb->context, error_buf)); } else { /* Handshake complete */ - args[0] = req_cb->buffer; - ret_val = JS_Call(ctx, req_cb->resolve, JS_NULL, 1, args); + args[1] = req_cb->buffer; } - JS_FreeValue(ctx, args[0]); - JS_FreeValue(ctx, req_cb->resolve); - JS_FreeValue(ctx, req_cb->reject); - JS_FreeValue(ctx, req_cb->buffer); + JSValue ret_val = + JS_Call(req_cb->context, req_cb->callback, JS_NULL, 2, args); + JS_FreeValue(req_cb->context, req_cb->buffer); + JS_FreeValue(req_cb->context, req_cb->callback); if (JS_IsException(ret_val)) { - nx_emit_error_event(ctx); + nx_emit_error_event(req_cb->context); } - JS_FreeValue(ctx, ret_val); + JS_FreeValue(req_cb->context, ret_val); free(req_cb); free(req); } @@ -91,14 +88,16 @@ JSValue nx_tls_handshake(JSContext *ctx, JSValueConst this_val, int argc, } int fd; - const char *hostname = JS_ToCString(ctx, argv[1]); - if (!hostname || JS_ToInt32(ctx, &fd, argv[0])) { + const char *hostname = JS_ToCString(ctx, argv[2]); + if (!hostname || JS_ToInt32(ctx, &fd, argv[1])) { + JS_ThrowTypeError(ctx, "invalid input"); return JS_EXCEPTION; } JSValue obj = JS_NewObjectClass(ctx, nx_tls_context_class_id); nx_tls_context_t *data = js_mallocz(ctx, sizeof(nx_tls_context_t)); if (!data) { + JS_ThrowOutOfMemory(ctx); return JS_EXCEPTION; } JS_SetOpaque(obj, data); @@ -107,8 +106,8 @@ JSValue nx_tls_handshake(JSContext *ctx, JSValueConst this_val, int argc, mbedtls_ssl_init(&data->ssl); mbedtls_ssl_config_init(&data->conf); - // Setup the SSL/TLS structure and set the - // hostname for Server Name Indication (SNI) + // Setup the SSL/TLS structure and set the hostname for Server Name + // Indication (SNI) if ((ret = mbedtls_ssl_config_defaults(&data->conf, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT)) != 0) { @@ -141,10 +140,7 @@ JSValue nx_tls_handshake(JSContext *ctx, JSValueConst this_val, int argc, nx_tls_connect_t *req = malloc(sizeof(nx_tls_connect_t)); nx_js_callback_t *req_cb = malloc(sizeof(nx_js_callback_t)); req_cb->context = ctx; - JSValue promise, resolving_funcs[2]; - promise = JS_NewPromiseCapability(ctx, resolving_funcs); - req_cb->resolve = resolving_funcs[0]; - req_cb->reject = resolving_funcs[1]; + req_cb->callback = JS_DupValue(ctx, argv[0]); req_cb->buffer = JS_DupValue(ctx, obj); req->opaque = req_cb; req->data = data; @@ -156,7 +152,7 @@ JSValue nx_tls_handshake(JSContext *ctx, JSValueConst this_val, int argc, nx_add_watcher(&nx_ctx->poll, (nx_watcher_t *)req); nx_tls_do_handshake(&nx_ctx->poll, (nx_watcher_t *)req, 0); - return promise; + return JS_UNDEFINED; } void nx_tls_do_read(nx_poll_t *p, nx_watcher_t *watcher, int revents) { @@ -195,8 +191,8 @@ void nx_tls_do_read(nx_poll_t *p, nx_watcher_t *watcher, int revents) { JSContext *ctx = req_cb->context; JS_FreeValue(ctx, req_cb->buffer); - JSValue ret_val; - JSValue args[1]; + + JSValue args[] = {JS_UNDEFINED, JS_UNDEFINED}; if (req->err) { /* Error during read. */ @@ -205,15 +201,14 @@ void nx_tls_do_read(nx_poll_t *p, nx_watcher_t *watcher, int revents) { args[0] = JS_NewError(ctx); JS_SetPropertyStr(ctx, args[0], "message", JS_NewString(ctx, error_buf)); - ret_val = JS_Call(ctx, req_cb->reject, JS_NULL, 1, args); } else { - args[0] = JS_NewInt32(ctx, total_read); - ret_val = JS_Call(ctx, req_cb->resolve, JS_NULL, 1, args); + args[1] = JS_NewInt32(ctx, total_read); } + JSValue ret_val = JS_Call(ctx, req_cb->callback, JS_NULL, 2, args); JS_FreeValue(ctx, args[0]); - JS_FreeValue(ctx, req_cb->resolve); - JS_FreeValue(ctx, req_cb->reject); + JS_FreeValue(ctx, args[1]); + JS_FreeValue(ctx, req_cb->callback); if (JS_IsException(ret_val)) { nx_emit_error_event(ctx); } @@ -227,23 +222,20 @@ JSValue nx_tls_read(JSContext *ctx, JSValueConst this_val, int argc, nx_context_t *nx_ctx = JS_GetContextOpaque(ctx); size_t buffer_size; - nx_tls_context_t *data = nx_tls_context_get(ctx, argv[0]); + nx_tls_context_t *data = nx_tls_context_get(ctx, argv[1]); if (!data) return JS_EXCEPTION; - uint8_t *buffer = JS_GetArrayBuffer(ctx, &buffer_size, argv[1]); + uint8_t *buffer = JS_GetArrayBuffer(ctx, &buffer_size, argv[2]); if (!buffer) return JS_EXCEPTION; - JSValue buffer_value = JS_DupValue(ctx, argv[1]); + JSValue buffer_value = JS_DupValue(ctx, argv[2]); nx_tls_read_t *req = malloc(sizeof(nx_tls_read_t)); nx_js_callback_t *req_cb = malloc(sizeof(nx_js_callback_t)); req_cb->context = ctx; - JSValue promise, resolving_funcs[2]; - promise = JS_NewPromiseCapability(ctx, resolving_funcs); - req_cb->resolve = resolving_funcs[0]; - req_cb->reject = resolving_funcs[1]; + req_cb->callback = JS_DupValue(ctx, argv[0]); req_cb->buffer = buffer_value; req->fd = data->server_fd.fd; req->events = POLLIN | POLLERR; @@ -257,7 +249,7 @@ JSValue nx_tls_read(JSContext *ctx, JSValueConst this_val, int argc, nx_add_watcher(&nx_ctx->poll, (nx_watcher_t *)req); nx_tls_do_read(&nx_ctx->poll, (nx_watcher_t *)req, 0); - return promise; + return JS_UNDEFINED; } void nx_tls_do_write(nx_poll_t *p, nx_watcher_t *watcher, int revents) { @@ -271,8 +263,7 @@ void nx_tls_do_write(nx_poll_t *p, nx_watcher_t *watcher, int revents) { } JSContext *ctx = req_cb->context; - JSValue ret_val; - JSValue args[1]; + JSValue args[] = {JS_UNDEFINED, JS_UNDEFINED}; if (ret < 0) { /* Error during write */ @@ -281,7 +272,6 @@ void nx_tls_do_write(nx_poll_t *p, nx_watcher_t *watcher, int revents) { args[0] = JS_NewError(ctx); JS_SetPropertyStr(ctx, args[0], "message", JS_NewString(ctx, error_buf)); - ret_val = JS_Call(ctx, req_cb->reject, JS_NULL, 1, args); } else { req->bytes_written += ret; if (req->bytes_written < req->buffer_size) { @@ -289,17 +279,18 @@ void nx_tls_do_write(nx_poll_t *p, nx_watcher_t *watcher, int revents) { return; } - args[0] = JS_NewInt32(ctx, req->bytes_written); - ret_val = JS_Call(ctx, req_cb->resolve, JS_NULL, 1, args); + args[1] = JS_NewInt32(ctx, ret); } // If we got to here then all the data was written nx_remove_watcher(p, watcher); - JS_FreeValue(ctx, args[0]); - JS_FreeValue(ctx, req_cb->resolve); - JS_FreeValue(ctx, req_cb->reject); JS_FreeValue(ctx, req_cb->buffer); + + JSValue ret_val = JS_Call(ctx, req_cb->callback, JS_NULL, 2, args); + JS_FreeValue(ctx, args[0]); + JS_FreeValue(ctx, args[1]); + JS_FreeValue(ctx, req_cb->callback); if (JS_IsException(ret_val)) { nx_emit_error_event(ctx); } @@ -313,23 +304,20 @@ JSValue nx_tls_write(JSContext *ctx, JSValueConst this_val, int argc, nx_context_t *nx_ctx = JS_GetContextOpaque(ctx); size_t buffer_size; - nx_tls_context_t *data = nx_tls_context_get(ctx, argv[0]); + nx_tls_context_t *data = nx_tls_context_get(ctx, argv[1]); if (!data) return JS_EXCEPTION; - uint8_t *buffer = JS_GetArrayBuffer(ctx, &buffer_size, argv[1]); + uint8_t *buffer = JS_GetArrayBuffer(ctx, &buffer_size, argv[2]); if (!buffer) return JS_EXCEPTION; - JSValue buffer_value = JS_DupValue(ctx, argv[1]); + JSValue buffer_value = JS_DupValue(ctx, argv[2]); nx_tls_write_t *req = malloc(sizeof(nx_tls_write_t)); nx_js_callback_t *req_cb = malloc(sizeof(nx_js_callback_t)); req_cb->context = ctx; - JSValue promise, resolving_funcs[2]; - promise = JS_NewPromiseCapability(ctx, resolving_funcs); - req_cb->resolve = resolving_funcs[0]; - req_cb->reject = resolving_funcs[1]; + req_cb->callback = JS_DupValue(ctx, argv[0]); req_cb->buffer = buffer_value; req->fd = data->server_fd.fd; req->events = POLLOUT | POLLERR; @@ -344,7 +332,7 @@ JSValue nx_tls_write(JSContext *ctx, JSValueConst this_val, int argc, nx_add_watcher(&nx_ctx->poll, (nx_watcher_t *)req); nx_tls_do_write(&nx_ctx->poll, (nx_watcher_t *)req, 0); - return promise; + return JS_UNDEFINED; } static const JSCFunctionListEntry function_list[] = { diff --git a/source/types.h b/source/types.h index 9c52162b..49ce1ca9 100644 --- a/source/types.h +++ b/source/types.h @@ -51,8 +51,7 @@ typedef struct { JSContext *context; - JSValue resolve; - JSValue reject; + JSValue callback; JSValue buffer; } nx_js_callback_t;