diff --git a/app/test-uv.js b/app/test-uv.js index 370fd8d..f56f864 100644 --- a/app/test-uv.js +++ b/app/test-uv.js @@ -6,6 +6,11 @@ p(uv.Timer.prototype); print("Handle.prototype (via Timer.prototype)"); p(Object.getPrototypeOf(uv.Timer.prototype)); +print("\nPrepare.prototype"); +p(uv.Prepare.prototype); +print("Handle.prototype (via Prepare.prototype)"); +p(Object.getPrototypeOf(uv.Prepare.prototype)); + print("\nTcp.prototype"); p(uv.Tcp.prototype); print("Stream.prototype (via Tcp.prototype)"); @@ -21,6 +26,12 @@ uv.walk(p); timer.close(); tcp.close(); +var prepare = new uv.Prepare(); +prepare.start(function () { + print("prepare..."); +}); +prepare.unref(); + print("\nTesting simple timeout"); var timer = new uv.Timer(); timer.start(100, 0, function () { diff --git a/implementations/duktape/duv/callbacks.c b/implementations/duktape/duv/callbacks.c index 2463448..dbeb4b3 100644 --- a/implementations/duktape/duv/callbacks.c +++ b/implementations/duktape/duv/callbacks.c @@ -19,6 +19,10 @@ void duv_on_timeout(uv_timer_t *timer) { duv_call_callback((uv_handle_t*)timer, "\xffon-timeout", 0); } +void duv_on_prepare(uv_prepare_t *prepare) { + duv_call_callback((uv_handle_t*)prepare, "\xffon-prepare", 0); +} + void duv_on_read(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) { duk_context *ctx = stream->data; if (nread >= 0) { diff --git a/implementations/duktape/duv/callbacks.h b/implementations/duktape/duv/callbacks.h index 369109a..5134744 100644 --- a/implementations/duktape/duv/callbacks.h +++ b/implementations/duktape/duv/callbacks.h @@ -10,6 +10,9 @@ void duv_on_alloc(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf); // Timer method callbacks void duv_on_timeout(uv_timer_t *timer); +// Prepare method callbacks +void duv_on_prepare(uv_prepare_t *prepare); + // Stream method callbacks void duv_on_read(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf); void duv_on_write(uv_write_t *shutdown, int status); diff --git a/implementations/duktape/duv/duv.c b/implementations/duktape/duv/duv.c index bba4ecb..f4c6de0 100644 --- a/implementations/duktape/duv/duv.c +++ b/implementations/duktape/duv/duv.c @@ -3,6 +3,7 @@ #include "loop.h" #include "handle.h" #include "timer.h" +#include "prepare.h" #include "stream.h" #include "tcp.h" @@ -27,6 +28,12 @@ static const duk_function_list_entry duv_timer_methods[] = { {0,0,0} }; +static const duk_function_list_entry duv_prepare_methods[] = { + {"start", duv_prepare_start, 1}, + {"stop", duv_prepare_stop, 0}, + {0,0,0} +}; + static const duk_function_list_entry duv_stream_methods[] = { {"shutdown", duv_shutdown, 1}, {"listen", duv_listen, 2}, @@ -62,6 +69,7 @@ static const duk_function_list_entry duv_funcs[] = { // libuv handle constructors {"Timer", duv_timer, 0}, + {"Prepare", duv_prepare, 0}, {"Tcp", duv_tcp, 0}, // // pipe.c @@ -166,6 +174,17 @@ duk_ret_t duv_push_module(duk_context *ctx) { // stack: nucleus uv Handle.prototype + // uv.Prepare.prototype + duk_get_prop_string(ctx, -2, "Prepare"); + duk_push_object(ctx); + duk_put_function_list(ctx, -1, duv_prepare_methods); + duk_dup(ctx, -3); + duk_set_prototype(ctx, -2); + duk_put_prop_string(ctx, -2, "prototype"); + duk_pop(ctx); + + // stack: nucleus uv Handle.prototype + // uv.Stream.prototype duk_push_object(ctx); duk_put_function_list(ctx, -1, duv_stream_methods); diff --git a/implementations/duktape/duv/duv.h b/implementations/duktape/duv/duv.h index 3525212..a652e6d 100644 --- a/implementations/duktape/duv/duv.h +++ b/implementations/duktape/duv/duv.h @@ -6,13 +6,19 @@ typedef enum { DUV_TIMER, + DUV_PREPARE, DUV_TCP, DUV_PIPE, } duv_type_t; typedef enum { - DUV_HANDLE_MASK = 1 << DUV_TIMER | 1 << DUV_TCP | 1 << DUV_PIPE, + DUV_HANDLE_MASK = + 1 << DUV_TIMER | + 1 << DUV_PREPARE | + 1 << DUV_TCP | + 1 << DUV_PIPE, DUV_TIMER_MASK = 1 << DUV_TIMER, + DUV_PREPARE_MASK = 1 << DUV_PREPARE, DUV_STREAM_MASK = 1 << DUV_TCP | 1 << DUV_PIPE, DUV_TCP_MASK = 1 << DUV_TCP, DUV_PIPE_MASK = 1 << DUV_PIPE, diff --git a/implementations/duktape/duv/handle.c b/implementations/duktape/duv/handle.c index f290a4c..b1198bf 100644 --- a/implementations/duktape/duv/handle.c +++ b/implementations/duktape/duv/handle.c @@ -28,21 +28,31 @@ duk_ret_t duv_close(duk_context *ctx) { duk_ret_t duv_is_active(duk_context *ctx) { - duk_error(ctx, DUK_ERR_UNIMPLEMENTED_ERROR, "TODO: Implement duv_is_active"); + uv_handle_t *handle = duv_require_this_handle(ctx, DUV_HANDLE_MASK); + duk_push_boolean(ctx, uv_is_active(handle)); + return 1; } duk_ret_t duv_is_closing(duk_context *ctx) { - duk_error(ctx, DUK_ERR_UNIMPLEMENTED_ERROR, "TODO: Implement duv_is_closing"); + uv_handle_t *handle = duv_require_this_handle(ctx, DUV_HANDLE_MASK); + duk_push_boolean(ctx, uv_is_closing(handle)); + return 1; } duk_ret_t duv_ref(duk_context *ctx) { - duk_error(ctx, DUK_ERR_UNIMPLEMENTED_ERROR, "TODO: Implement duv_ref"); + uv_handle_t *handle = duv_require_this_handle(ctx, DUV_HANDLE_MASK); + uv_ref(handle); + return 0; } duk_ret_t duv_unref(duk_context *ctx) { - duk_error(ctx, DUK_ERR_UNIMPLEMENTED_ERROR, "TODO: Implement duv_unref"); + uv_handle_t *handle = duv_require_this_handle(ctx, DUV_HANDLE_MASK); + uv_unref(handle); + return 0; } duk_ret_t duv_has_ref(duk_context *ctx) { - duk_error(ctx, DUK_ERR_UNIMPLEMENTED_ERROR, "TODO: Implement duv_has_ref"); + uv_handle_t *handle = duv_require_this_handle(ctx, DUV_HANDLE_MASK); + duk_push_boolean(ctx, uv_has_ref(handle)); + return 1; } diff --git a/implementations/duktape/duv/prepare.c b/implementations/duktape/duv/prepare.c index 29eaf9c..e016230 100644 --- a/implementations/duktape/duv/prepare.c +++ b/implementations/duktape/duv/prepare.c @@ -1 +1,28 @@ #include "prepare.h" +#include "utils.h" +#include "callbacks.h" + +duk_ret_t duv_prepare(duk_context *ctx) { + uv_prepare_t *prepare = duk_push_fixed_buffer(ctx, sizeof(uv_prepare_t)); + duv_check(ctx, uv_prepare_init(duv_loop(ctx), prepare)); + duv_setup_handle(ctx, (uv_handle_t*)prepare, DUV_PREPARE); + return 1; +} + +duk_ret_t duv_prepare_start(duk_context *ctx) { + dschema_check(ctx, (const duv_schema_entry[]) { + {"callback", duk_is_function}, + {0,0} + }); + uv_prepare_t *prepare = duv_require_this_handle(ctx, DUV_PREPARE_MASK); + duk_put_prop_string(ctx, 0, "\xffon-prepare"); + duv_check(ctx, uv_prepare_start(prepare, duv_on_prepare)); + return 0; +} + +duk_ret_t duv_prepare_stop(duk_context *ctx) { + uv_prepare_t *prepare = duv_require_this_handle(ctx, DUV_PREPARE_MASK); + duk_del_prop_string(ctx, -1, "\xffon-prepare"); + duv_check(ctx, uv_prepare_stop(prepare)); + return 0; +} diff --git a/implementations/duktape/duv/prepare.h b/implementations/duktape/duv/prepare.h index 65fc6b2..bd2146e 100644 --- a/implementations/duktape/duv/prepare.h +++ b/implementations/duktape/duv/prepare.h @@ -3,4 +3,8 @@ #include "duv.h" +duk_ret_t duv_prepare(duk_context *ctx); +duk_ret_t duv_prepare_start(duk_context *ctx); +duk_ret_t duv_prepare_stop(duk_context *ctx); + #endif diff --git a/implementations/duktape/duv/timer.c b/implementations/duktape/duv/timer.c index bd26a81..7feaea8 100644 --- a/implementations/duktape/duv/timer.c +++ b/implementations/duktape/duv/timer.c @@ -19,7 +19,7 @@ duk_ret_t duv_timer_start(duk_context *ctx) { uv_timer_t *timer = duv_require_this_handle(ctx, DUV_TIMER_MASK); int timeout = duk_get_int(ctx, 1); int repeat = duk_get_int(ctx, 2); - duk_put_prop_string(ctx, -4, "\xffon-timeout"); + duk_put_prop_string(ctx, 0, "\xffon-timeout"); duv_check(ctx, uv_timer_start(timer, duv_on_timeout, timeout, repeat)); return 0; } diff --git a/implementations/duktape/duv/utils.c b/implementations/duktape/duv/utils.c index 3d703b2..39f0c86 100644 --- a/implementations/duktape/duv/utils.c +++ b/implementations/duktape/duv/utils.c @@ -4,6 +4,7 @@ const char* duv_type_to_string(duv_type_t type) { switch (type) { case DUV_TIMER: return "uv_timer_t"; + case DUV_PREPARE: return "uv_prepare_t"; case DUV_TCP: return "uv_tcp_t"; case DUV_PIPE: return "uv_pipe_t"; } @@ -14,6 +15,7 @@ const char* duv_mask_to_string(duv_type_mask_t mask) { switch (mask) { case DUV_HANDLE_MASK: return "uv_handle_t"; case DUV_TIMER_MASK: return "uv_timer_t"; + case DUV_PREPARE_MASK: return "uv_prepare_t"; case DUV_STREAM_MASK: return "uv_stream_t"; case DUV_TCP_MASK: return "uv_tcp_t"; case DUV_PIPE_MASK: return "uv_pipe_t"; diff --git a/implementations/duktape/main.c b/implementations/duktape/main.c index b845aa3..6e5e029 100644 --- a/implementations/duktape/main.c +++ b/implementations/duktape/main.c @@ -472,6 +472,7 @@ int main(int argc, char *argv[]) { // Run main.js function duk_push_string(ctx, "nucleus.dofile('main.js')"); if (duk_peval(ctx)) { + duk_dump_context_stderr(ctx); fprintf(stderr, "Uncaught %s\n", duk_safe_to_string(ctx, -1)); exit(1); }