mirror of
https://github.com/Ylianst/MeshAgent
synced 2026-01-13 22:14:00 +00:00
Updated GC handling
This commit is contained in:
@@ -5551,6 +5551,14 @@ void MeshAgent_ScriptMode(MeshAgentHostContainer *agentHost, int argc, char **ar
|
||||
gEventEmitterReferenceHold = atoi(tmp + 1);
|
||||
}
|
||||
}
|
||||
else if (strncmp(argv[i], "--finalizer-messages=", 21) == 0)
|
||||
{
|
||||
char *tmp = strstr(argv[i], "=");
|
||||
if (tmp != NULL)
|
||||
{
|
||||
g_displayFinalizerMessages = atoi(tmp + 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Unhandled arguments, passed to JavaScript
|
||||
|
||||
@@ -72,11 +72,13 @@ int ILibDuktape_EventEmitter_HasListeners2(ILibDuktape_EventEmitter *emitter, ch
|
||||
|
||||
int ILibDuktape_EventEmitter_AddOn(ILibDuktape_EventEmitter *emitter, char *eventName, void *heapptr); // Add native event handler
|
||||
int ILibDuktape_EventEmitter_AddOnEx(duk_context *ctx, duk_idx_t idx, char *eventName, duk_c_function func);
|
||||
#define ILibDuktape_EventEmitter_AddOn_Infrastructure(ctx, idx, eventName, func) duk_prepare_method_call(ctx, idx, "on");duk_push_string(ctx, eventName);duk_push_c_function(ctx, func, DUK_VARARGS);duk_push_true(ctx);duk_put_prop_string(ctx, -2, ILibDuktape_EventEmitter_InfrastructureEvent);duk_pcall_method(ctx, 2);duk_pop(ctx);
|
||||
#define ILibDuktape_EventEmitter_AddOn_Infrastructure(ctx, idx, eventName, func) duk_events_setup_on(ctx, idx, eventName, func);duk_push_true(ctx);duk_put_prop_string(ctx, -2, ILibDuktape_EventEmitter_InfrastructureEvent);duk_pcall_method(ctx, 2);duk_pop(ctx);
|
||||
|
||||
|
||||
void ILibDuktape_EventEmitter_AddHook(ILibDuktape_EventEmitter *emitter, char *eventName, ILibDuktape_EventEmitter_HookHandler handler);
|
||||
void ILibDuktape_EventEmitter_ClearHook(ILibDuktape_EventEmitter *emitter, char *eventName);
|
||||
|
||||
int ILibDuktape_EventEmitter_ForwardEventEx(duk_context *ctx, duk_idx_t sourceIdx, duk_idx_t targetIdx, char *eventName);
|
||||
void ILibDuktape_EventEmitter_ForwardEvent(duk_context *ctx, duk_idx_t eventSourceIndex, char *sourceEventName, duk_idx_t eventTargetIndex, char *targetEventName);
|
||||
void ILibDuktape_EventEmitter_DeleteForwardEvent(duk_context *ctx, duk_idx_t eventSourceIndex, char *sourceEventName);
|
||||
|
||||
|
||||
@@ -1279,3 +1279,31 @@ void ILibDuktape_Log_Object(duk_context *ctx, duk_idx_t i, char *meta)
|
||||
duk_pop(ctx);
|
||||
}
|
||||
|
||||
void ILibDuktape_DisplayProperties(duk_context *ctx, duk_idx_t idx)
|
||||
{
|
||||
duk_idx_t i = duk_get_top(ctx);
|
||||
duk_dup(ctx, idx); // [obj]
|
||||
duk_push_global_object(ctx); // [obj][g]
|
||||
duk_get_prop_string(ctx, -1, "console"); // [obj][g][console]
|
||||
duk_prepare_method_call(ctx, -1, "log"); // [obj][g][console][log][this]
|
||||
duk_get_prop_string(ctx, -5, ILibDuktape_OBJID); // [obj][g][console][log][this][ID]
|
||||
duk_pcall_method(ctx, 1); duk_pop_3(ctx); // [obj]
|
||||
|
||||
|
||||
duk_eval_string(ctx, "require('events').allProperties"); // [obj][allProp]
|
||||
duk_swap_top(ctx, -2); // [allProp][obj]
|
||||
duk_pcall(ctx, 1); // [array]
|
||||
duk_push_global_object(ctx); // [array][g]
|
||||
duk_get_prop_string(ctx, -1, "console"); // [array][g][console]
|
||||
duk_prepare_method_call(ctx, -1, "log"); // [array][g][console][log][this]
|
||||
|
||||
duk_get_prop_string(ctx, -4, "JSON"); // [array][g][console][log][this][JSON]
|
||||
duk_prepare_method_call(ctx, -1, "stringify"); // [array][g][console][log][this][JSON][stringify][this]
|
||||
duk_dup(ctx, -8); // [array][g][console][log][this][JSON][stringify][this][array]
|
||||
duk_push_null(ctx); duk_push_int(ctx, 1); // [array][g][console][log][this][JSON][stringify][this][array][null][1]
|
||||
duk_pcall_method(ctx, 3); // [array][g][console][log][this][JSON][string]
|
||||
duk_remove(ctx, -2); // [array][g][console][log][this][string]
|
||||
duk_pcall_method(ctx, 1);
|
||||
duk_set_top(ctx, i);
|
||||
}
|
||||
|
||||
|
||||
@@ -228,5 +228,6 @@ void* ILibDuktape_Timeout(duk_context *ctx, void **args, int argsLen, int delay,
|
||||
int ILibDuktape_GetReferenceCount(duk_context *ctx, duk_idx_t i);
|
||||
|
||||
#define ILibDuktape_WriteID(ctx, id) duk_push_string(ctx, id);duk_put_prop_string(ctx, -2, ILibDuktape_OBJID)
|
||||
void ILibDuktape_DisplayProperties(duk_context *ctx, duk_idx_t idx);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -978,6 +978,14 @@ duk_ret_t ILibDuktape_Polyfills_timer_finalizer(duk_context *ctx)
|
||||
|
||||
ILibLifeTime_Remove(ILibGetBaseTimer(Duktape_GetChain(ctx)), ptrs);
|
||||
}
|
||||
|
||||
duk_eval_string(ctx, "require('events')"); // [events]
|
||||
duk_prepare_method_call(ctx, -1, "deleteProperty"); // [events][deleteProperty][this]
|
||||
duk_push_this(ctx); // [events][deleteProperty][this][timer]
|
||||
duk_prepare_method_call(ctx, -4, "hiddenProperties");//[events][deleteProperty][this][timer][hidden][this]
|
||||
duk_push_this(ctx); // [events][deleteProperty][this][timer][hidden][this][timer]
|
||||
duk_call_method(ctx, 1); // [events][deleteProperty][this][timer][array]
|
||||
duk_call_method(ctx, 2); // [events][ret]
|
||||
return 0;
|
||||
}
|
||||
void ILibDuktape_Polyfills_timer_elapsed(void *obj)
|
||||
@@ -1191,6 +1199,7 @@ duk_ret_t ILibDuktape_Polyfills_addCompressedModule_dataSink(duk_context *ctx)
|
||||
duk_ret_t ILibDuktape_Polyfills_addCompressedModule(duk_context *ctx)
|
||||
{
|
||||
duk_eval_string(ctx, "require('compressed-stream').createDecompressor();");
|
||||
duk_dup(ctx, 0); duk_put_prop_string(ctx, -2, ILibDuktape_EventEmitter_FinalizerDebugMessage);
|
||||
void *decoder = duk_get_heapptr(ctx, -1);
|
||||
ILibDuktape_EventEmitter_AddOnEx(ctx, -1, "data", ILibDuktape_Polyfills_addCompressedModule_dataSink);
|
||||
|
||||
@@ -1213,6 +1222,10 @@ duk_ret_t ILibDuktape_Polyfills_addCompressedModule(duk_context *ctx)
|
||||
duk_pcall_method(ctx, 2);
|
||||
}
|
||||
|
||||
duk_push_heapptr(ctx, decoder); // [stream]
|
||||
duk_prepare_method_call(ctx, -1, "removeAllListeners"); // [stream][remove][this]
|
||||
duk_pcall_method(ctx, 0);
|
||||
|
||||
return(0);
|
||||
}
|
||||
duk_ret_t ILibDuktape_Polyfills_addModuleObject(duk_context *ctx)
|
||||
|
||||
@@ -516,11 +516,12 @@ int ILibDuktape_readableStream_WriteEnd(ILibDuktape_readableStream *stream)
|
||||
void ILibDuktape_readableStream_Closed(ILibDuktape_readableStream *stream)
|
||||
{
|
||||
ILibDuktape_readableStream_WriteEnd(stream);
|
||||
if(ILibDuktape_EventEmitter_HasListeners(stream->emitter, "close")!=0)
|
||||
if (ILibMemory_CanaryOK(stream) && ILibDuktape_EventEmitter_HasListeners(stream->emitter, "close") != 0)
|
||||
{
|
||||
duk_context *ctx = stream->ctx;
|
||||
ILibDuktape_EventEmitter_SetupEmit(stream->ctx, stream->object, "close"); // [emit][this][close]
|
||||
if (duk_pcall_method(stream->ctx, 1) != 0) { ILibDuktape_Process_UncaughtException(stream->ctx); }
|
||||
duk_pop(stream->ctx); // ...
|
||||
duk_pop(ctx); // ...
|
||||
}
|
||||
|
||||
if (ILibMemory_CanaryOK(stream))
|
||||
@@ -735,7 +736,7 @@ void ILibDuktape_readableStream_unpipe_later(duk_context *ctx, void ** args, int
|
||||
data = (ILibDuktape_readableStream*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
duk_pop_2(ctx); // ...
|
||||
|
||||
if (data->emitter->ctx == NULL) { return; }
|
||||
if (data == NULL || data->emitter == NULL || data->emitter->ctx == NULL) { return; }
|
||||
ILibSpinLock_Lock(&(data->pipeLock));
|
||||
#ifdef WIN32
|
||||
if (data->pipeInProgress != 0 && data->pipedThreadID != GetCurrentThreadId())
|
||||
@@ -922,7 +923,7 @@ duk_ret_t ILibDuktape_ReadableStream_PipeLockFinalizer(duk_context *ctx)
|
||||
|
||||
duk_push_this(ctx); // [stream]
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_readableStream_RSPTRS); // [stream][buffer]
|
||||
ptrs = (ILibDuktape_readableStream*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
if ((ptrs = (ILibDuktape_readableStream*)Duktape_GetBuffer(ctx, -1, NULL)) == NULL) { return(0); }
|
||||
if (ptrs->pipeImmediate != NULL)
|
||||
{
|
||||
duk_push_global_object(ctx); // [g]
|
||||
|
||||
@@ -284,6 +284,7 @@ duk_ret_t ILibDuktape_WritableStream_UnPipeSink(duk_context *ctx)
|
||||
|
||||
duk_dup(ctx, 0); // [readable]
|
||||
duk_push_this(ctx); // [readable][writable]
|
||||
duk_del_prop_string(ctx, -1, "\xFF_ReadableStream_PTRS");
|
||||
if (duk_has_prop_string(ctx, -1, ILibDuktape_WritableStream_WSPTRS))
|
||||
{
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_WritableStream_WSPTRS); // [readable][writable][ptr]
|
||||
|
||||
@@ -167,6 +167,7 @@ void ILibDuktape_net_socket_OnConnect(ILibAsyncSocket_SocketModule socketModule,
|
||||
ILibDuktape_net_socket *ptrs = (ILibDuktape_net_socket*)((ILibChain_Link*)socketModule)->ExtraMemoryPtr;
|
||||
struct sockaddr_in6 local;
|
||||
if (ptrs->ctx == NULL) { return; }
|
||||
duk_context *ctx = ptrs->ctx;
|
||||
|
||||
duk_push_heapptr(ptrs->ctx, ptrs->object); // [sockat]
|
||||
duk_push_false(ptrs->ctx); // [socket][connecting]
|
||||
@@ -175,7 +176,7 @@ void ILibDuktape_net_socket_OnConnect(ILibAsyncSocket_SocketModule socketModule,
|
||||
|
||||
if (Connected != 0)
|
||||
{
|
||||
duk_push_heapptr(ptrs->ctx, ptrs->object); // [sock]
|
||||
duk_push_heapptr(ptrs->ctx, ptrs->object); // [sock]
|
||||
if (ILibAsyncSocket_IsDomainSocket(socketModule) == 0)
|
||||
{
|
||||
ILibAsyncSocket_GetLocalInterface(socketModule, (struct sockaddr*)&local);
|
||||
@@ -197,7 +198,7 @@ void ILibDuktape_net_socket_OnConnect(ILibAsyncSocket_SocketModule socketModule,
|
||||
duk_get_prop_string(ptrs->ctx, -1, "remoteHost"); // [sock][remoteHost]
|
||||
duk_put_prop_string(ptrs->ctx, -2, "path"); // [sock]
|
||||
}
|
||||
duk_pop(ptrs->ctx); // ...
|
||||
duk_pop(ptrs->ctx); // ...
|
||||
|
||||
#ifndef MICROSTACK_NOTLS
|
||||
if (ptrs->ssl != NULL)
|
||||
@@ -231,7 +232,7 @@ void ILibDuktape_net_socket_OnConnect(ILibAsyncSocket_SocketModule socketModule,
|
||||
duk_swap_top(ptrs->ctx, -2); // [emit][this]
|
||||
duk_push_string(ptrs->ctx, "connect"); // [emit][this][connect]
|
||||
if (duk_pcall_method(ptrs->ctx, 1) != 0) { ILibDuktape_Process_UncaughtException(ptrs->ctx); }
|
||||
duk_pop(ptrs->ctx); // ...
|
||||
duk_pop(ctx); // ...
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -389,8 +390,7 @@ duk_ret_t ILibDuktape_net_socket_connect(duk_context *ctx)
|
||||
duk_push_this(ctx); // [socket]
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_net_socket_ptr); // [socket][ptrs]
|
||||
ptrs = (ILibDuktape_net_socket*)duk_to_pointer(ctx, -1);
|
||||
duk_pop(ctx); // [socket]
|
||||
|
||||
duk_pop_2(ctx); // ...
|
||||
if (duk_is_object(ctx, 0))
|
||||
{
|
||||
/* This is an OPTIONS object
|
||||
@@ -595,6 +595,7 @@ duk_ret_t ILibDuktape_net_socket_connect(duk_context *ctx)
|
||||
duk_put_prop_string(ptrs->ctx, -2, "connecting"); // [socket]
|
||||
duk_pop(ptrs->ctx); // ...
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -842,6 +843,13 @@ int ILibDuktape_net_server_unshiftSink(ILibDuktape_DuplexStream *sender, int uns
|
||||
session->unshiftBytes = unshiftBytes;
|
||||
return(unshiftBytes);
|
||||
}
|
||||
duk_ret_t ILibDuktape_net_server_SocketDisconnected(duk_context *ctx)
|
||||
{
|
||||
duk_push_this(ctx); // [socket]
|
||||
duk_prepare_method_call(ctx, -1, "removeAllListeners"); // [socket][removeAll][this]
|
||||
duk_call_method(ctx, 0);
|
||||
return(0);
|
||||
}
|
||||
void ILibDuktape_net_server_OnConnect(ILibAsyncServerSocket_ServerModule AsyncServerSocketModule, ILibAsyncServerSocket_ConnectionToken ConnectionToken, void **user)
|
||||
{
|
||||
ILibDuktape_net_server *ptr = (ILibDuktape_net_server*)((void**)ILibMemory_GetExtraMemory(AsyncServerSocketModule, ILibMemory_ASYNCSERVERSOCKET_CONTAINERSIZE))[0];
|
||||
@@ -854,13 +862,14 @@ void ILibDuktape_net_server_OnConnect(ILibAsyncServerSocket_ServerModule AsyncSe
|
||||
if (!ILibMemory_CanaryOK(ptr)) { return; }
|
||||
|
||||
duk_push_heapptr(ptr->ctx, ptr->self); // [server]
|
||||
ILibMemory_Free(((ILibChain_Link*)ConnectionToken)->MetaData);
|
||||
if (strcmp(Duktape_GetStringPropertyValue(ptr->ctx, -1, ILibDuktape_OBJID, ""), "net.ipcServer") == 0)
|
||||
{
|
||||
((ILibChain_Link*)ConnectionToken)->MetaData = "net.ipcServer.ipcSocketConnection";
|
||||
((ILibChain_Link*)ConnectionToken)->MetaData = ILibMemory_SmartAllocate_FromString("net.ipcServer.ipcSocketConnection");
|
||||
}
|
||||
else
|
||||
{
|
||||
((ILibChain_Link*)ConnectionToken)->MetaData = isTLS == 0 ? "net.serverSocketConnection" : "tls.serverSocketConnection";
|
||||
((ILibChain_Link*)ConnectionToken)->MetaData = isTLS == 0 ? ILibMemory_SmartAllocate_FromString("net.serverSocketConnection") : ILibMemory_SmartAllocate_FromString("tls.serverSocketConnection");
|
||||
}
|
||||
|
||||
duk_get_prop_string(ptr->ctx, -1, "emit"); // [server][emit]
|
||||
@@ -915,6 +924,10 @@ void ILibDuktape_net_server_OnConnect(ILibAsyncServerSocket_ServerModule AsyncSe
|
||||
|
||||
ILibDuktape_EventEmitter_CreateEventEx(session->emitter, "timeout");
|
||||
|
||||
duk_events_setup_on(ptr->ctx, -1, "close", ILibDuktape_net_server_SocketDisconnected); // [on][this][close][func]
|
||||
duk_push_true(ptr->ctx); duk_put_prop_string(ptr->ctx, -2, ILibDuktape_EventEmitter_InfrastructureEvent);
|
||||
duk_pcall_method(ptr->ctx, 2); duk_pop(ptr->ctx); // ...
|
||||
|
||||
session->stream = ILibDuktape_DuplexStream_InitEx(ptr->ctx, ILibDuktape_net_server_WriteSink, ILibDuktape_net_server_EndSink,
|
||||
ILibDuktape_net_server_PauseSink, ILibDuktape_net_server_ResumeSink, ILibDuktape_net_server_unshiftSink, session);
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ limitations under the License.
|
||||
#include "ILibDuktape_Polyfills.h"
|
||||
|
||||
#define ILibDuktape_EventEmitter_MaxEventNameLen 255
|
||||
#define ILibDuktape_EventEmitter_EmitterUtils "\xFF_emitterUtils"
|
||||
#define ILibDuktape_EventEmitter_Data "\xFF_EventEmitter_Data"
|
||||
#define ILibDuktape_EventEmitter_RetVal "\xFF_EventEmitter_RetVal"
|
||||
#define ILibDuktape_EventEmitter_LastRetValueTable "\xFF_EventEmitter_LastRetValueTable"
|
||||
@@ -502,8 +503,78 @@ duk_ret_t ILibDuktape_EventEmitter_removeListener(duk_context *ctx)
|
||||
|
||||
return(0);
|
||||
}
|
||||
duk_ret_t ILibDuktape_EventEmitter_removeAllListeners_AllEvents_NonInfrastructure_find(duk_context *ctx)
|
||||
{
|
||||
duk_dup(ctx, 0); // [element]
|
||||
duk_get_prop_string(ctx, -1, "func"); // [element][func]
|
||||
if (Duktape_GetBooleanProperty(ctx, -1, ILibDuktape_EventEmitter_InfrastructureEvent, 0) == 0)
|
||||
{
|
||||
duk_push_true(ctx);
|
||||
}
|
||||
else
|
||||
{
|
||||
duk_push_false(ctx);
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
duk_ret_t ILibDuktape_EventEmitter_removeAllListeners_AllEvents_NonInfrastructure(duk_context *ctx)
|
||||
{
|
||||
int i = -1;
|
||||
duk_push_this(ctx); // [emitter]
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_EventEmitter_EventTable); // [emitter][table]
|
||||
duk_enum(ctx, -1, DUK_ENUM_OWN_PROPERTIES_ONLY); // [emitter][table][enum]
|
||||
while (duk_next(ctx, -1, 1)) // [emitter][table][enum][name][array]
|
||||
{
|
||||
// Skip finalizers, as well as removeListener
|
||||
if (strcmp(duk_get_string(ctx, -2), "~") == 0 || strcmp(duk_get_string(ctx, -2), "removeListener") == 0) { duk_pop_2(ctx); continue; }
|
||||
do
|
||||
{
|
||||
duk_prepare_method_call(ctx, -1, "findIndex"); // [emitter][table][enum][name][array][findIndex][this]
|
||||
duk_push_c_function(ctx, ILibDuktape_EventEmitter_removeAllListeners_AllEvents_NonInfrastructure_find, DUK_VARARGS);//][func]
|
||||
duk_call_method(ctx, 1); // [emitter][table][enum][name][array][index]
|
||||
if ((i = duk_get_int(ctx, -1)) != -1)
|
||||
{
|
||||
duk_get_prop_index(ctx, -2, i); // [emitter][table][enum][name][array][index][element]
|
||||
duk_prepare_method_call(ctx, -3, "splice"); // [emitter][table][enum][name][array][index][element][splice][this]
|
||||
duk_push_int(ctx, i); // [emitter][table][enum][name][array][index][element][splice][this][start]
|
||||
duk_push_int(ctx, 1); // [emitter][table][enum][name][array][index][element][splice][this][start][1]
|
||||
duk_call_method(ctx, 2); duk_pop(ctx); // [emitter][table][enum][name][array][index][element]
|
||||
ILibDuktape_EventEmitter_emit_removeListener(ctx, duk_get_string(ctx, -4), -7, -1);
|
||||
duk_pop(ctx); // [emitter][table][enum][name][array][index]
|
||||
}
|
||||
duk_pop(ctx); // [emitter][table][enum][name][array]
|
||||
} while (i != -1);
|
||||
duk_pop_2(ctx); // [emitter][table][enum]
|
||||
}
|
||||
duk_pop(ctx); // [emitter][table]
|
||||
if (duk_has_prop_string(ctx, -1, "removeListener"))
|
||||
{
|
||||
i = -1;
|
||||
duk_get_prop_string(ctx, -1, "removeListener"); // [emitter][table][array]
|
||||
do
|
||||
{
|
||||
duk_prepare_method_call(ctx, -1, "findIndex"); // [emitter][table][array][findIndex][this]
|
||||
duk_push_c_function(ctx, ILibDuktape_EventEmitter_removeAllListeners_AllEvents_NonInfrastructure_find, DUK_VARARGS);//][func]
|
||||
duk_call_method(ctx, 1); // [emitter][table][array][index]
|
||||
if ((i = duk_get_int(ctx, -1)) != -1)
|
||||
{
|
||||
duk_get_prop_index(ctx, -2, i); // [emitter][table][array][index][element]
|
||||
duk_prepare_method_call(ctx, -3, "splice"); // [emitter][table][array][index][element][splice][this]
|
||||
duk_push_int(ctx, i); // [emitter][table][array][index][element][splice][this][start]
|
||||
duk_push_int(ctx, 1); // [emitter][table][array][index][element][splice][this][start][1]
|
||||
duk_call_method(ctx, 2); duk_pop(ctx); // [emitter][table][array][index][element]
|
||||
ILibDuktape_EventEmitter_emit_removeListener(ctx, "removeListener", -5, -1);
|
||||
duk_pop(ctx); // [emitter][table][array][index]
|
||||
}
|
||||
duk_pop(ctx); // [emitter][table][array]
|
||||
} while (i != -1);
|
||||
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
duk_ret_t ILibDuktape_EventEmitter_removeAllListeners(duk_context *ctx)
|
||||
{
|
||||
if (duk_get_top(ctx) == 0) { return(ILibDuktape_EventEmitter_removeAllListeners_AllEvents_NonInfrastructure(ctx)); }
|
||||
char *eventName = (char*)duk_require_string(ctx, 0);
|
||||
|
||||
duk_push_this(ctx); // [object]
|
||||
@@ -785,7 +856,7 @@ duk_ret_t ILibDuktape_EventEmitter_listeners_tableinit(duk_context *ctx)
|
||||
emitter->listenerCountTableLength = len;
|
||||
duk_push_this(ctx); // [g][JSON][array][index][string][array][string][string][this]
|
||||
duk_swap_top(ctx, -2); // [g][JSON][array][index][string][array][string][this][string]
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_EventEmitter_CountTable);
|
||||
ILibDuktape_CreateReadonlyProperty_SetEnumerable(ctx, ILibDuktape_EventEmitter_CountTable, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -803,18 +874,18 @@ ILibDuktape_EventEmitter* ILibDuktape_EventEmitter_Create(duk_context *ctx)
|
||||
}
|
||||
|
||||
retVal = (ILibDuktape_EventEmitter*)Duktape_PushBuffer(ctx, sizeof(ILibDuktape_EventEmitter)); // [event][data]
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_EventEmitter_Data); // [event]
|
||||
ILibDuktape_CreateReadonlyProperty_SetEnumerable(ctx, ILibDuktape_EventEmitter_Data, 0); // [event]
|
||||
|
||||
retVal->ctx = ctx;
|
||||
retVal->object = duk_get_heapptr(ctx, -1);
|
||||
|
||||
duk_push_object(ctx);
|
||||
retVal->table = duk_get_heapptr(ctx, -1);
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_EventEmitter_EventTable);
|
||||
ILibDuktape_CreateReadonlyProperty_SetEnumerable(ctx, ILibDuktape_EventEmitter_EventTable, 0);
|
||||
|
||||
duk_push_object(ctx);
|
||||
retVal->retValTable = duk_get_heapptr(ctx, -1);
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_EventEmitter_LastRetValueTable);
|
||||
ILibDuktape_CreateReadonlyProperty_SetEnumerable(ctx, ILibDuktape_EventEmitter_LastRetValueTable, 0);
|
||||
ILibSpinLock_Init(&(retVal->listenerCountTableLock));
|
||||
retVal->listenerCountTable = (char*)"[]";
|
||||
retVal->listenerCountTableLength = 2;
|
||||
@@ -1036,8 +1107,8 @@ duk_ret_t ILibDuktape_EventEmitter_Inherits(duk_context *ctx)
|
||||
duk_dup(ctx, 0); // [target]
|
||||
emitter = ILibDuktape_EventEmitter_Create(ctx);
|
||||
duk_push_object(ctx); // [target][emitterUtils]
|
||||
duk_dup(ctx, -1); // [target][emitterUtils][dup]
|
||||
duk_put_prop_string(ctx, -3, "\xFF_emitterUtils"); // [target][emitterUtils]
|
||||
ILibDuktape_CreateReadonlyProperty_SetEnumerable(ctx, ILibDuktape_EventEmitter_EmitterUtils, 0);
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_EventEmitter_EmitterUtils);
|
||||
duk_push_pointer(ctx, emitter); // [target][emitterUtils][ptr]
|
||||
duk_put_prop_string(ctx, -2, "emitter"); // [target][emitterUtils]
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "createEvent", ILibDuktape_EventEmitter_Inherits_createEvent, 1);
|
||||
@@ -1053,8 +1124,8 @@ duk_ret_t ILibDuktape_EventEmitter_EventEmitter(duk_context *ctx)
|
||||
duk_push_this(ctx); // [target]
|
||||
emitter = ILibDuktape_EventEmitter_Create(ctx);
|
||||
duk_push_object(ctx); // [target][emitterUtils]
|
||||
duk_dup(ctx, -1); // [target][emitterUtils][dup]
|
||||
duk_put_prop_string(ctx, -3, "\xFF_emitterUtils"); // [target][emitterUtils]
|
||||
ILibDuktape_CreateReadonlyProperty_SetEnumerable(ctx, ILibDuktape_EventEmitter_EmitterUtils, 0);
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_EventEmitter_EmitterUtils);
|
||||
duk_push_pointer(ctx, emitter); // [target][emitterUtils][ptr]
|
||||
duk_put_prop_string(ctx, -2, "emitter"); // [target][emitterUtils]
|
||||
|
||||
@@ -1136,27 +1207,145 @@ duk_ret_t ILibDuktape_EventEmitter_moderated(duk_context *ctx)
|
||||
|
||||
duk_ret_t ILibDuktape_EventEmitter_allProperties(duk_context *ctx)
|
||||
{
|
||||
duk_push_current_function(ctx);
|
||||
int all = Duktape_GetIntPropertyValue(ctx, -1, "all", 0);
|
||||
|
||||
const char *tmp;
|
||||
duk_push_array(ctx); // [arr]
|
||||
duk_dup(ctx, 0); // [arr][obj]
|
||||
duk_enum(ctx, -1, DUK_ENUM_INCLUDE_NONENUMERABLE | DUK_ENUM_INCLUDE_HIDDEN );
|
||||
duk_enum(ctx, -1, (all == 0 ? 0 : DUK_ENUM_INCLUDE_NONENUMERABLE) | DUK_ENUM_INCLUDE_HIDDEN | DUK_ENUM_INCLUDE_SYMBOLS);;
|
||||
while (duk_next(ctx, -1, 0)) // [arr][obj][enum][key]
|
||||
{
|
||||
tmp = duk_get_string(ctx, -1);
|
||||
duk_push_string(ctx, tmp); // [arr][obj][enum][key][string]
|
||||
duk_array_push(ctx, -5); // [arr][obj][enum][key]
|
||||
tmp = NULL;
|
||||
if (duk_is_symbol(ctx, -1))
|
||||
{
|
||||
duk_size_t len;
|
||||
tmp = Duktape_GetBuffer(ctx, -1, &len);
|
||||
char *buf = duk_push_fixed_buffer(ctx, len + 1); // [arr][obj][enum][key][buf]
|
||||
duk_insert(ctx, -5); // [buf][arr][obj][enum][key]
|
||||
memcpy_s(buf, len + 1, tmp, len);
|
||||
buf[0] = '?';
|
||||
buf[len] = 0;
|
||||
tmp = buf;
|
||||
if (all == 0)
|
||||
{
|
||||
if (strcmp(tmp, "?Finalizer") == 0) { tmp = NULL; }
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (all) { tmp = duk_get_string(ctx, -1); }
|
||||
}
|
||||
if (tmp != NULL)
|
||||
{
|
||||
duk_push_string(ctx, tmp); // [arr][obj][enum][key][string]
|
||||
duk_array_push(ctx, -5); // [arr][obj][enum][key]
|
||||
}
|
||||
duk_pop(ctx); // [arr][obj][enum]
|
||||
}
|
||||
duk_pop_2(ctx); // [arr]
|
||||
return(1);
|
||||
}
|
||||
duk_ret_t ILibDuktape_EventEmitter_showReferences(duk_context *ctx)
|
||||
{
|
||||
const char *ID, *MSG;
|
||||
duk_push_heap_stash(ctx); // [stash]
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_EventEmitter_References); // [stash][refs]
|
||||
if (!duk_is_null_or_undefined(ctx, -1))
|
||||
{
|
||||
duk_enum(ctx, -1, DUK_ENUM_OWN_PROPERTIES_ONLY); // [stash][refs][enum]
|
||||
while (duk_next(ctx, -1, 1)) // [stash][refs][enum][key][value]
|
||||
{
|
||||
ID = Duktape_GetStringPropertyValue(ctx, -1, ILibDuktape_OBJID, "?");
|
||||
MSG = Duktape_GetStringPropertyValue(ctx, -1, ILibDuktape_EventEmitter_FinalizerDebugMessage, "");
|
||||
duk_push_global_object(ctx); // [stash][refs][enum][key][value][g]
|
||||
duk_get_prop_string(ctx, -1, "console"); // [stash][refs][enum][key][value][g][console]
|
||||
duk_remove(ctx, -2); // [stash][refs][enum][key][value][console]
|
||||
duk_prepare_method_call(ctx, -1, "log"); // [stash][refs][enum][key][value][console][log][this]
|
||||
duk_push_sprintf(ctx, "%s%s%s", ID, MSG != NULL ? " => " : "", MSG != NULL ? MSG : ""); //][value][console][log][this][string]
|
||||
duk_call_method(ctx, 1); duk_pop_n(ctx, 2); // [stash][refs][enum][key][value]
|
||||
duk_prepare_method_call(ctx, -1, "eventNames"); // [stash][refs][enum][key][value][eventNames][this]
|
||||
if (duk_pcall_method(ctx, 0) == 0) // [stash][refs][enum][key][value][array]
|
||||
{
|
||||
if (duk_get_length(ctx, -1) > 0)
|
||||
{
|
||||
duk_push_global_object(ctx); // [stash][refs][enum][key][value][array][g]
|
||||
duk_get_prop_string(ctx, -1, "JSON"); // [stash][refs][enum][key][value][array][g][JSON]
|
||||
duk_prepare_method_call(ctx, -1, "stringify"); // [stash][refs][enum][key][value][array][g][JSON][stringify][this]
|
||||
duk_dup(ctx, -5); // [stash][refs][enum][key][value][array][g][JSON][stringify][this][array]
|
||||
duk_call_method(ctx, 1); // [stash][refs][enum][key][value][array][g][JSON][STRING]
|
||||
duk_get_prop_string(ctx, -3, "console"); // [stash][refs][enum][key][value][array][g][JSON][STRING][console]
|
||||
duk_prepare_method_call(ctx, -1, "log"); // [stash][refs][enum][key][value][array][g][JSON][STRING][console][log][this]
|
||||
duk_push_sprintf(ctx, " -> events %s", duk_get_string(ctx, -4));// tash][refs][enum][key][value][array][g][JSON][STRING][console][log][this][VAL]
|
||||
duk_call_method(ctx, 1); // [stash][refs][enum][key][value][array][g][JSON][STRING][console][ret]
|
||||
duk_pop_n(ctx, 5); // [stash][refs][enum][key][value][array]
|
||||
}
|
||||
duk_eval_string(ctx, "require('events')"); // [stash][refs][enum][key][value][array][events]
|
||||
duk_prepare_method_call(ctx, -1, "hiddenProperties"); // [stash][refs][enum][key][value][array][events][hidden][this]
|
||||
duk_dup(ctx, -5); // [stash][refs][enum][key][value][array][events][hidden][this][value]
|
||||
duk_call_method(ctx, 1); // [stash][refs][enum][key][value][array][events][props]
|
||||
duk_push_global_object(ctx); // [stash][refs][enum][key][value][array][events][props][g]
|
||||
duk_get_prop_string(ctx, -1, "JSON"); // [stash][refs][enum][key][value][array][events][props][g][JSON]
|
||||
duk_prepare_method_call(ctx, -1, "stringify"); // [stash][refs][enum][key][value][array][events][props][g][JSON][stringify][this]
|
||||
duk_dup(ctx, -5); // [stash][refs][enum][key][value][array][events][props][g][JSON][stringify][this][props]
|
||||
duk_push_null(ctx); duk_push_int(ctx, 1); // [stash][refs][enum][key][value][array][events][props][g][JSON][stringify][this][props][null][1]
|
||||
duk_call_method(ctx, 3); // [stash][refs][enum][key][value][array][events][props][g][JSON][PROPSTRING]
|
||||
duk_get_prop_string(ctx, -3, "console"); // [stash][refs][enum][key][value][array][events][props][g][JSON][PROPSTRING][console]
|
||||
duk_prepare_method_call(ctx, -1, "log"); // [stash][refs][enum][key][value][array][events][props][g][JSON][PROPSTRING][console][log][this]
|
||||
duk_push_sprintf(ctx, " -> props %s", duk_get_string(ctx, -4)); // [refs][enum][key][value][array][events][props][g][JSON][PROPSTRING][console][log][this][string]
|
||||
duk_call_method(ctx, 1); // [stash][refs][enum][key][value][array][events][props][g][JSON][PROPSTRING][console][ret]
|
||||
duk_pop_n(ctx, 7); // [stash][refs][enum][key][value][array]
|
||||
}
|
||||
duk_pop_n(ctx, 3); // [stash][refs][enum]
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
duk_ret_t ILibDuktape_EventEmitter_addHidden(duk_context *ctx)
|
||||
{
|
||||
duk_dup(ctx, 0); // [a]
|
||||
duk_dup(ctx, 1); // [a][b]
|
||||
duk_put_prop_string(ctx, -2, "\xFF_HIDDEN");
|
||||
return(0);
|
||||
}
|
||||
duk_ret_t ILibDuktape_EventEmitter_deleteProperty(duk_context *ctx)
|
||||
{
|
||||
char *tmp;
|
||||
duk_dup(ctx, 0); // [obj]
|
||||
if (duk_is_string(ctx, 1))
|
||||
{
|
||||
duk_dup(ctx, 1); // [obj][string]
|
||||
duk_del_prop(ctx, -2);
|
||||
}
|
||||
else if (duk_is_array(ctx, 1))
|
||||
{
|
||||
duk_dup(ctx, 1); // [obj][array]
|
||||
while (duk_get_length(ctx, -1) > 0)
|
||||
{
|
||||
duk_array_pop(ctx, -1); // [obj][array][string]
|
||||
tmp = (char*)duk_push_sprintf(ctx, "%s", duk_get_string(ctx, -1)); // [obj][array][string][string]
|
||||
tmp[0] = '\xFF';
|
||||
duk_del_prop_string(ctx, -4, tmp);
|
||||
duk_pop_2(ctx); // [obj][array]
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return(ILibDuktape_Error(ctx, "Invalid Args"));
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
void ILibDuktape_EventEmitter_PUSH(duk_context *ctx, void *chain)
|
||||
{
|
||||
duk_push_object(ctx); // [emitter]
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "inherits", ILibDuktape_EventEmitter_Inherits, 1);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "EventEmitter", ILibDuktape_EventEmitter_EventEmitter, DUK_VARARGS);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "moderated", ILibDuktape_EventEmitter_moderated, DUK_VARARGS);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "allProperties", ILibDuktape_EventEmitter_allProperties, 1);
|
||||
ILibDuktape_CreateInstanceMethodWithIntProperty(ctx, "all", 1, "allProperties", ILibDuktape_EventEmitter_allProperties, 1);
|
||||
ILibDuktape_CreateInstanceMethodWithIntProperty(ctx, "all", 0, "hiddenProperties", ILibDuktape_EventEmitter_allProperties, 1);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "showReferences", ILibDuktape_EventEmitter_showReferences, DUK_VARARGS);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "addHiddenReference", ILibDuktape_EventEmitter_addHidden, 2);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "deleteProperty", ILibDuktape_EventEmitter_deleteProperty, 2);
|
||||
}
|
||||
void ILibDuktape_EventEmitter_Init(duk_context *ctx)
|
||||
{
|
||||
@@ -1388,3 +1577,114 @@ int ILibDuktape_EventEmitter_AddOnEx(duk_context *ctx, duk_idx_t idx, char *even
|
||||
duk_pop(ctx); // ...
|
||||
return(retVal);
|
||||
}
|
||||
|
||||
duk_ret_t ILibDuktape_EventEmitter_ForwardEx_target_newListenerSink(duk_context *ctx)
|
||||
{
|
||||
duk_push_current_function(ctx); // [func]
|
||||
char *eventName = Duktape_GetStringPropertyValue(ctx, -1, "eventName", NULL);
|
||||
void **ptr = (void**)Duktape_GetPointerProperty(ctx, -1, "sourcePtr");
|
||||
char *hookedEvent = (char*)duk_require_string(ctx, 0);
|
||||
if (eventName == NULL || !ILibMemory_CanaryOK(ptr) || strcmp(eventName, hookedEvent) != 0) { return(0); }
|
||||
|
||||
duk_dup(ctx, 1); // [func]
|
||||
duk_prepare_method_call(ctx, -1, "bind"); // [func][bind][this]
|
||||
duk_push_this(ctx); // [func][bind][this][target]
|
||||
duk_call_method(ctx, 1); // [func][proxyFunc]
|
||||
duk_push_true(ctx); duk_put_prop_string(ctx, -2, ILibDuktape_EventEmitter_InfrastructureEvent);
|
||||
duk_push_pointer(ctx, ptr); duk_put_prop_string(ctx, -2, "sourcePtr");
|
||||
duk_dup(ctx, -1); // [func][proxyFunc][proxyFunc]
|
||||
duk_put_prop_string(ctx, -3, "proxyFunc"); // [func][proxyFunc]
|
||||
|
||||
|
||||
duk_push_heapptr(ctx, ptr[0]); // [func][proxyFunc][source]
|
||||
duk_prepare_method_call(ctx, -1, "on"); // [func][proxyFunc][source][on][this]
|
||||
duk_dup(ctx, 0); // [func][proxyFunc][source][on][this][eventName]
|
||||
duk_dup(ctx, -5); // [func][proxyFunc][source][on][this][eventName][func]
|
||||
duk_call_method(ctx, 2); // [func][proxyFunc][source][ret]
|
||||
|
||||
return(0);
|
||||
}
|
||||
duk_ret_t ILibDuktape_EventEmitter_ForwardEx_target_removeListenerSink(duk_context *ctx)
|
||||
{
|
||||
duk_push_current_function(ctx); // [func]
|
||||
char *eventName = Duktape_GetStringPropertyValue(ctx, -1, "eventName", NULL);
|
||||
void **ptr = (void**)Duktape_GetPointerProperty(ctx, -1, "sourcePtr");
|
||||
char *hookedEvent = (char*)duk_require_string(ctx, 0);
|
||||
if (eventName == NULL || !ILibMemory_CanaryOK(ptr) || strcmp(eventName, hookedEvent) != 0 || !duk_has_prop_string(ctx, 1, "proxyFunc")) { return(0); }
|
||||
|
||||
duk_push_heapptr(ctx, ptr[0]); // [source]
|
||||
duk_prepare_method_call(ctx, -1, "removeListener"); // [source][removeListener][this]
|
||||
duk_dup(ctx, 0); // [source][removeListener][this][name]
|
||||
duk_get_prop_string(ctx, 1, "proxyFunc"); // [source][removeListener][this][name][func]
|
||||
duk_call_method(ctx, 2); // [source][ret]
|
||||
return(0);
|
||||
}
|
||||
int ILibDuktape_EventEmitter_ForwardEventEx(duk_context *ctx, duk_idx_t sourceIdx, duk_idx_t targetIdx, char *eventName)
|
||||
{
|
||||
int X = duk_get_top(ctx);
|
||||
void *source = duk_get_heapptr(ctx, sourceIdx);
|
||||
void *target = duk_get_heapptr(ctx, targetIdx);
|
||||
void **ptr;
|
||||
|
||||
duk_push_heapptr(ctx, source); // [source]
|
||||
if (!duk_has_prop_string(ctx, -1, "\xFF_ProxyEvent_WeakReference"))
|
||||
{
|
||||
ptr = (void**)Duktape_PushBuffer(ctx, sizeof(void*)); // [source][buffer]
|
||||
duk_put_prop_string(ctx, -2, "\xFF_ProxyEvent_WeakReference"); // [source]
|
||||
ptr[0] = source;
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr = Duktape_GetPointerProperty(ctx, -1, "\xFF_ProxyEvent_WeakReference");
|
||||
}
|
||||
duk_pop(ctx); // ...
|
||||
|
||||
|
||||
// Check for pre-existing event listeners
|
||||
duk_prepare_method_call(ctx, targetIdx, "listeners"); // [listeners][this]
|
||||
duk_push_string(ctx, eventName); // [listeners][this][name]
|
||||
if (duk_pcall_method(ctx, 1) != 0) { duk_set_top(ctx, X); return(1); } // [array]
|
||||
while(duk_get_length(ctx, -1)>0)
|
||||
{
|
||||
duk_array_pop(ctx, -1); // [array][func]
|
||||
if (!duk_has_prop_string(ctx, -1, "proxyFunc"))
|
||||
{
|
||||
duk_prepare_method_call(ctx, -1, "bind"); // [array][func][bind][this]
|
||||
duk_push_heapptr(ctx, target); // [array][func][bind][this][target]
|
||||
if (duk_pcall_method(ctx, 1) != 0) { duk_set_top(ctx, X); return(1); } // [array][func][proxyFunc]
|
||||
duk_push_true(ctx); duk_put_prop_string(ctx, -2, ILibDuktape_EventEmitter_InfrastructureEvent);
|
||||
duk_push_pointer(ctx, ptr); duk_put_prop_string(ctx, -2, "sourcePtr");
|
||||
duk_put_prop_string(ctx, -2, "proxyFunc"); // [array][func]
|
||||
}
|
||||
duk_push_heapptr(ctx, source); // [array][func][source]
|
||||
duk_prepare_method_call(ctx, -1, "on"); // [array][func][source][on][this]
|
||||
duk_push_string(ctx, eventName); // [array][func][source][on][this][eventName]
|
||||
duk_get_prop_string(ctx, -5, "proxyFunc"); // [array][func][source][on][this][eventName][proxyFunc]
|
||||
if (duk_pcall_method(ctx, 2) != 0) { duk_set_top(ctx, X); return(1); } // [array][func][source][ret]
|
||||
duk_pop_n(ctx, 3); // [array]
|
||||
}
|
||||
|
||||
|
||||
// Hookup a 'newListener' hook, to attach new subscribers
|
||||
int ret = 0;
|
||||
duk_set_top(ctx, X);
|
||||
duk_events_setup_on(ctx, targetIdx, "newListener", ILibDuktape_EventEmitter_ForwardEx_target_newListenerSink); // [on][this][newListener][func]
|
||||
duk_push_string(ctx, eventName); duk_put_prop_string(ctx, -2, "eventName");
|
||||
duk_push_pointer(ctx, ptr); duk_put_prop_string(ctx, -2, "sourcePtr");
|
||||
duk_push_true(ctx); duk_put_prop_string(ctx, -2, ILibDuktape_EventEmitter_InfrastructureEvent);
|
||||
ret = duk_pcall_method(ctx, 2) == 0 ? 0 : 1;
|
||||
duk_set_top(ctx, X);
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
// Hookup a 'removeListener' hook, to remove subscribers
|
||||
duk_events_setup_on(ctx, targetIdx, "removeListener", ILibDuktape_EventEmitter_ForwardEx_target_removeListenerSink); // [on][this][removeListener][func]
|
||||
duk_push_string(ctx, eventName); duk_put_prop_string(ctx, -2, "eventName");
|
||||
duk_push_pointer(ctx, ptr); duk_put_prop_string(ctx, -2, "sourcePtr");
|
||||
duk_push_true(ctx); duk_put_prop_string(ctx, -2, ILibDuktape_EventEmitter_InfrastructureEvent);
|
||||
ret = duk_pcall_method(ctx, 2) == 0 ? 0 : 1;
|
||||
duk_set_top(ctx, X);
|
||||
}
|
||||
|
||||
return(ret);
|
||||
}
|
||||
Reference in New Issue
Block a user