1
0
mirror of https://github.com/Ylianst/MeshAgent synced 2026-01-15 06:53:40 +00:00

Fixed circular references impacting GC

This commit is contained in:
Bryan Roe
2021-03-11 11:17:39 -08:00
parent 6d15f3f5a9
commit 0f8278bf6b
7 changed files with 334 additions and 67 deletions

View File

@@ -387,6 +387,36 @@ duk_ret_t ILibDuktape_SpawnedProcess_SIGCHLD_sink(duk_context *ctx)
return(0);
}
#endif
void ILibDuktape_SpawnedProcess_exitHandler_immediateSink(duk_context *ctx, void ** args, int argsLen)
{
duk_push_this(ctx); // [immediate]
duk_get_prop_string(ctx, -1, "process"); // [immediate][spawnedProcess]
duk_del_prop_string(ctx, -2, "process");
if (duk_has_prop_string(ctx, -1, "stdout"))
{
duk_get_prop_string(ctx, -1, "stdout"); // [immediate][spawnedProcess][stdout]
duk_prepare_method_call(ctx, -1, "removeAllListeners"); // [immediate][spawnedProcess][stdout][removeAll][this]
duk_pcall_method(ctx, 0); duk_pop_2(ctx); // [immediate][spawnedProcess]
}
if (duk_has_prop_string(ctx, -1, "stderr"))
{
duk_get_prop_string(ctx, -1, "stderr"); // [immediate][spawnedProcess][stderr]
duk_prepare_method_call(ctx, -1, "removeAllListeners"); // [immediate][spawnedProcess][stderr][removeAll][this]
duk_pcall_method(ctx, 0); duk_pop_2(ctx); // [immediate][spawnedProcess]
}
duk_prepare_method_call(ctx, -1, "removeAllListeners"); // [immediate][spawnedProcess][removeAll][this]
duk_pcall_method(ctx, 0); duk_pop_3(ctx); // ...
}
duk_ret_t ILibDuktape_SpawnedProcess_exitHandler(duk_context *ctx)
{
void *i = ILibDuktape_Immediate(ctx, (void*[]) { ctx }, 1, ILibDuktape_SpawnedProcess_exitHandler_immediateSink);
duk_push_heapptr(ctx, i); // [immediate]
duk_push_this(ctx); // [immediate][spawnedProcess]
duk_put_prop_string(ctx, -2, "process"); // [immediate]
duk_pop(ctx); // ...
return(0);
}
ILibDuktape_ChildProcess_SubProcess* ILibDuktape_ChildProcess_SpawnedProcess_PUSH(duk_context *ctx, ILibProcessPipe_Process mProcess, void *callback)
{
duk_push_object(ctx); // [ChildProcess]
@@ -449,11 +479,6 @@ ILibDuktape_ChildProcess_SubProcess* ILibDuktape_ChildProcess_SpawnedProcess_PUS
ILibDuktape_ChildProcess_SubProcess_StdErrHandler,
ILibDuktape_ChildProcess_SubProcess_SendOK, retVal);
}
else
{
if (callback != NULL) { ILibDuktape_EventEmitter_AddOnce(emitter, "exit", callback); }
}
#if defined(_POSIX)
ILibDuktape_EventEmitter_SetupOn(ctx, ILibDuktape_GetProcessObject(ctx), "SIGCHLD"); // [child][on][process][SIGCHLD]
@@ -466,6 +491,9 @@ ILibDuktape_ChildProcess_SubProcess* ILibDuktape_ChildProcess_SpawnedProcess_PUS
#endif
ILibDuktape_CreateEventWithSetterEx(ctx, "descriptorMetadata", ILibDuktape_SpawnedProcess_descriptorSetter);
if (callback != NULL) { ILibDuktape_EventEmitter_AddOnce(emitter, "exit", callback); }
ILibDuktape_EventEmitter_AddOnceEx3(ctx, -1, "exit", ILibDuktape_SpawnedProcess_exitHandler);
return(retVal);
}

View File

@@ -436,6 +436,19 @@ duk_ret_t ILibDuktape_GenericMarshal_Variable_bignum_SET(duk_context *ctx)
return(0);
}
#endif
duk_ret_t ILibDuktape_GenericMarshal_Variable_metadata_get(duk_context *ctx)
{
duk_push_this(ctx);
duk_get_prop_string(ctx, -1, ILibDuktape_EventEmitter_FinalizerDebugMessage);
return(1);
}
duk_ret_t ILibDuktape_GenericMarshal_Variable_metadata_set(duk_context *ctx)
{
duk_push_this(ctx); // [var]
duk_dup(ctx, 0); // [var][value]
duk_put_prop_string(ctx, -2, ILibDuktape_EventEmitter_FinalizerDebugMessage);
return(0);
}
void ILibDuktape_GenericMarshal_Variable_PUSH(duk_context *ctx, void *ptr, int size)
{
duk_push_object(ctx); // [var]
@@ -463,6 +476,10 @@ void ILibDuktape_GenericMarshal_Variable_PUSH(duk_context *ctx, void *ptr, int s
ILibDuktape_CreateInstanceMethod(ctx, "autoFree", ILibDuktape_GenericMarshal_Variable_autoFree, DUK_VARARGS);
ILibDuktape_CreateInstanceMethod(ctx, "pointerBuffer", ILibDuktape_GenericMarshal_Variable_pointerBuffer, 0);
ILibDuktape_CreateInstanceMethod(ctx, "getPointerPointer", ILibDuktape_GenericMarshal_Variable_pointerpointer, 0);
ILibDuktape_CreateEventWithGetterAndSetterEx(ctx, "descriptorMetadata", ILibDuktape_GenericMarshal_Variable_metadata_get, ILibDuktape_GenericMarshal_Variable_metadata_set);
duk_push_sprintf(ctx, "Size: %d", size);
duk_put_prop_string(ctx, -2, ILibDuktape_EventEmitter_FinalizerDebugMessage);
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_GenericMarshal_Variable_Finalizer);
}
@@ -889,6 +906,7 @@ void ILibDuktape_GenericMarshal_MethodInvokeAsync_ChainDispatch(void *chain, voi
duk_context *ctx = data->ctx;
duk_push_heapptr(data->ctx, data->promise); // [promise]
duk_del_prop_string(data->ctx, -1, "_varArray");
duk_get_prop_string(data->ctx, -1, "_RES"); // [promise][resolver]
duk_swap_top(data->ctx, -2); // [resolver][this]
ILibDuktape_GenericMarshal_Variable_PUSH(data->ctx, (void*)(PTRSIZE)data->vars, (int)sizeof(void*)); // [resolver][this][var]
@@ -1048,6 +1066,7 @@ void ILibDuktape_GenericMarshal_MethodInvokeAsync_Done_chain(void *chain, void*
}
duk_push_heapptr(data->ctx, data->promise); // [promise]
duk_del_prop_string(data->ctx, -1, "_varArray");
duk_get_prop_string(data->ctx, -1, "_RES"); // [promise][resolver]
duk_swap_top(data->ctx, -2); // [resolver][this]
ILibDuktape_GenericMarshal_Variable_PUSH(data->ctx, (void*)data->workAvailable, (int)sizeof(void*)); // [resolver][this][var]
@@ -1090,6 +1109,12 @@ duk_ret_t ILibDuktape_GenericMarshal_MethodInvokeAsync_promfin(duk_context *ctx)
}
return(0);
}
duk_ret_t ILibDuktape_GenericMarshal_MethodInvokeAsync_PromiseSettled(duk_context *ctx)
{
duk_push_this(ctx); // [promise]
duk_del_prop_string(ctx, -1, "nativeProxy");
return(0);
}
duk_ret_t ILibDuktape_GenericMarshal_MethodInvokeAsync(duk_context *ctx)
{
void *redirectionPtr = NULL, *redirectionPtrName = NULL;
@@ -1136,6 +1161,9 @@ duk_ret_t ILibDuktape_GenericMarshal_MethodInvokeAsync(duk_context *ctx)
data->chain = duk_ctx_chain(ctx);
duk_push_current_function(ctx); // [promise][func]
duk_push_sprintf(ctx, "%s_Async", Duktape_GetStringPropertyValue(ctx, -1, "_funcName", "??"));
duk_put_prop_string(ctx, -3, ILibDuktape_EventEmitter_FinalizerDebugMessage);
data->fptr = Duktape_GetPointerProperty(ctx, -1, "_address");
data->methodName = Duktape_GetStringPropertyValue(ctx, -1, "_funcName", NULL);
data->waitingForResult = WAITING_FOR_RESULT__DISPATCHER;
@@ -1143,6 +1171,7 @@ duk_ret_t ILibDuktape_GenericMarshal_MethodInvokeAsync(duk_context *ctx)
data->workStarted = ggd->dispatch->WorkerThreadHandle;
data->vars = (PTRSIZE*)ILibMemory_SmartAllocate(sizeof(PTRSIZE)*parms);
data->fptr_redirection = NULL;
duk_pop(ctx); // [promise]
}
else
{
@@ -1185,6 +1214,10 @@ duk_ret_t ILibDuktape_GenericMarshal_MethodInvokeAsync(duk_context *ctx)
duk_eval_string(ctx, "require('promise');"); // [func][promise]
duk_push_c_function(ctx, ILibDuktape_GenericMarshal_MethodInvokeAsync_promise, 2);
duk_new(ctx, 1);
duk_get_prop_string(ctx, -1, "_internal");
duk_push_sprintf(ctx, "%s_Async", Duktape_GetStringPropertyValue(ctx, -3, "_funcName", "??"));
duk_put_prop_string(ctx, -2, ILibDuktape_EventEmitter_FinalizerDebugMessage);
duk_pop(ctx);
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_GenericMarshal_MethodInvokeAsync_promfin);
duk_push_pointer(ctx, data); duk_put_prop_string(ctx, -2, "_data");
data->promise = duk_get_heapptr(ctx, -1);
@@ -1209,8 +1242,7 @@ duk_ret_t ILibDuktape_GenericMarshal_MethodInvokeAsync(duk_context *ctx)
{
if (duk_is_object(ctx, i))
{
duk_get_prop_string(ctx, i, "_ptr");
data->vars[i] = (PTRSIZE)duk_to_pointer(ctx, -1);
data->vars[i] = (PTRSIZE)Duktape_GetPointerProperty(ctx, i, "_ptr");
}
else if (duk_is_number(ctx, i))
{
@@ -1240,13 +1272,15 @@ duk_ret_t ILibDuktape_GenericMarshal_MethodInvokeAsync(duk_context *ctx)
}
#endif
duk_push_heapptr(ctx, data->promise); // [promise]
duk_push_current_function(ctx); // [promise][func]
duk_get_prop_string(ctx, -1, "_obj"); // [promise][func][obj]
duk_remove(ctx, -2); // [promise][obj]
void *hptr = Duktape_GetPointerProperty(ctx, -1, "_obj");
duk_pop(ctx); // [promise]
duk_push_heapptr(ctx, hptr); // [promise][obj]
duk_put_prop_string(ctx, -2, "nativeProxy");// [promise]
duk_get_prop_string(ctx, -1, "_internal");
ILibDuktape_EventEmitter_AddOn_Infrastructure(ctx, -1, "settled", ILibDuktape_GenericMarshal_MethodInvokeAsync_PromiseSettled);
duk_pop(ctx);
return(1);
}
duk_ret_t ILibDuktape_GenericMarshal_MethodInvokeAsync_wait(duk_context *ctx)
@@ -1458,7 +1492,8 @@ duk_ret_t ILibDuktape_GenericMarshal_CreateMethod(duk_context *ctx)
duk_push_string(ctx, funcName); duk_put_prop_string(ctx, -2, "_funcName");
duk_push_c_function(ctx, ILibDuktape_GenericMarshal_MethodInvokeAsync_abort, 0); // [obj][func][func][func]
duk_put_prop_string(ctx, -2, "abort"); // [obj][func][func]
duk_push_this(ctx); duk_put_prop_string(ctx, -2, "_obj");
duk_push_pointer(ctx, duk_get_heapptr(ctx, -3)); duk_put_prop_string(ctx, -2, "_obj");
duk_push_c_function(ctx, ILibDuktape_GenericMarshal_MethodInvokeAsync_thread, 0); duk_put_prop_string(ctx, -2, "thread");
duk_push_c_function(ctx, ILibDuktape_GenericMarshal_MethodInvokeAsync_wait, DUK_VARARGS); duk_put_prop_string(ctx, -2, "wait");
duk_push_c_function(ctx, ILibDuktape_GenericMarshal_MethodInvokeAsync_thread_id, 0); duk_put_prop_string(ctx, -2, "threadId");

File diff suppressed because one or more lines are too long

View File

@@ -38,6 +38,7 @@ limitations under the License.
#define ILibDuktape_EventEmitter_EventTable "\xFF_EventEmitter_EventTable"
#define ILibDuktape_EventEmitter_CountTable "\xFF_EventEmitter_CountTable"
#define ILibDuktape_EventEmitter_References "\xFF_EventReferences"
extern void ILibDuktape_GenericMarshal_Variable_PUSH(duk_context *ctx, void *ptr, int size);
#ifdef ILIBEVENTEMITTER_REFHOLD
int gEventEmitterReferenceHold = ILIBEVENTEMITTER_REFHOLD;
@@ -1213,7 +1214,7 @@ duk_ret_t ILibDuktape_EventEmitter_allProperties(duk_context *ctx)
const char *tmp;
duk_push_array(ctx); // [arr]
duk_dup(ctx, 0); // [arr][obj]
duk_enum(ctx, -1, (all == 0 ? 0 : DUK_ENUM_INCLUDE_NONENUMERABLE) | DUK_ENUM_INCLUDE_HIDDEN | DUK_ENUM_INCLUDE_SYMBOLS);;
duk_enum(ctx, -1, (all == 0 ? 0 : DUK_ENUM_INCLUDE_NONENUMERABLE) | (all == 2 ? DUK_ENUM_OWN_PROPERTIES_ONLY : 0) | DUK_ENUM_INCLUDE_HIDDEN | DUK_ENUM_INCLUDE_SYMBOLS);;
while (duk_next(ctx, -1, 0)) // [arr][obj][enum][key]
{
tmp = NULL;
@@ -1342,13 +1343,56 @@ duk_ret_t ILibDuktape_EventEmitter_setFinalizerMetadata(duk_context *ctx)
duk_put_prop_string(ctx, -2, ILibDuktape_EventEmitter_FinalizerDebugMessage);
return(0);
}
duk_ret_t ILibDuktape_RefCountPointer(duk_context *ctx)
duk_ret_t ILibDuktape_RefCountPointer_eval(duk_context *ctx)
{
duk_push_this(ctx);
duk_int_t *t = _get_refcount_ptr(ctx, -1);
duk_push_pointer(ctx, t);
duk_int_t *t = (duk_int_t*)Duktape_GetPointerProperty(ctx, -1, "_ptr");
if (t == NULL) { return(ILibDuktape_Error(ctx, "ERROR")); }
duk_push_int(ctx, *t);
return(1);
}
duk_ret_t ILibDuktape_RefCountPointer_set(duk_context *ctx)
{
duk_push_this(ctx);
duk_int_t *t = (duk_int_t*)Duktape_GetPointerProperty(ctx, -1, "_ptr");
if (t == NULL) { return(ILibDuktape_Error(ctx, "ERROR")); }
*t = duk_require_int(ctx, 0);
return(0);
}
duk_ret_t ILibDuktape_RefCountPointer(duk_context *ctx)
{
int nargs = duk_get_top(ctx);
duk_push_this(ctx);
char *tmp = Duktape_GetStringPropertyValue(ctx, -1, ILibDuktape_OBJID, "");
if (nargs == 1) { duk_dup(ctx, 0); }
duk_int_t *t = _get_refcount_ptr(ctx, -1);
if (nargs == 1) { duk_pop(ctx); }
ILibDuktape_GenericMarshal_Variable_PUSH(ctx, t, sizeof(void*));
duk_push_sprintf(ctx, "_get_refcount_ptr(%s)", tmp); duk_put_prop_string(ctx, -2, ILibDuktape_EventEmitter_FinalizerDebugMessage);
ILibDuktape_CreateInstanceMethod(ctx, "eval", ILibDuktape_RefCountPointer_eval, 0);
ILibDuktape_CreateInstanceMethod(ctx, "set", ILibDuktape_RefCountPointer_set, 1);
return(1);
}
duk_ret_t ILibDuktape_EventEmitter_getProperty(duk_context *ctx)
{
duk_push_this(ctx); // [obj]
char *tmp = (char*)duk_push_sprintf(ctx, "%s", duk_get_string(ctx, 0));// [obj][string]
if (tmp[0] == '?') { tmp[0] = '\xFF'; }
duk_get_prop_string(ctx, -2, tmp);
tmp = (char*)duk_get_string(ctx, -1);
return(1);
}
duk_ret_t ILibDuktape_EventEmitter_setProperty(duk_context *ctx)
{
char *s = (char*)duk_get_string(ctx, 0);
char *s2 = (char*)duk_get_string(ctx, 1);
duk_push_this(ctx); // [obj]
char *tmp = (char*)duk_push_sprintf(ctx, "%s", duk_get_string(ctx, 0));// [obj][string]
duk_dup(ctx, 1); // [obj][string][val]
if (tmp[0] == '?') { tmp[0] = '\xFF'; }
duk_put_prop_string(ctx, -3, tmp);
return(0);
}
void ILibDuktape_EventEmitter_PUSH(duk_context *ctx, void *chain)
{
duk_push_object(ctx); // [emitter]
@@ -1357,11 +1401,14 @@ void ILibDuktape_EventEmitter_PUSH(duk_context *ctx, void *chain)
ILibDuktape_CreateInstanceMethod(ctx, "moderated", ILibDuktape_EventEmitter_moderated, DUK_VARARGS);
ILibDuktape_CreateInstanceMethodWithIntProperty(ctx, "all", 1, "allProperties", ILibDuktape_EventEmitter_allProperties, 1);
ILibDuktape_CreateInstanceMethodWithIntProperty(ctx, "all", 0, "hiddenProperties", ILibDuktape_EventEmitter_allProperties, 1);
ILibDuktape_CreateInstanceMethodWithIntProperty(ctx, "all", 2, "allOwnProperties", 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);
ILibDuktape_CreateInstanceMethod(ctx, "setFinalizerMetadata", ILibDuktape_EventEmitter_setFinalizerMetadata, 1);
ILibDuktape_CreateInstanceMethod(ctx, "_refCountPointer", ILibDuktape_RefCountPointer, 0);
ILibDuktape_CreateInstanceMethod(ctx, "_refCountPointer", ILibDuktape_RefCountPointer, DUK_VARARGS);
ILibDuktape_CreateInstanceMethod(ctx, "getProperty", ILibDuktape_EventEmitter_getProperty, 1);
ILibDuktape_CreateInstanceMethod(ctx, "setProperty", ILibDuktape_EventEmitter_setProperty, 2);
}
void ILibDuktape_EventEmitter_Init(duk_context *ctx)
{

View File

@@ -99915,3 +99915,14 @@ duk_int_t* _get_refcount_ptr(void *thr, duk_idx_t idx)
duk_heaphdr *h = (DUK_TVAL_IS_HEAP_ALLOCATED(tv) ? DUK_TVAL_GET_HEAPHDR(tv) : NULL);
return(&(DUK_HEAPHDR_GET_REFCOUNT(h)));
}
void* _duk_get_first_object(void *ctx)
{
duk_hthread *thr = (duk_hthread*)ctx;
return(thr->heap->heap_allocated);
}
void* _duk_get_next_object(void *ctx, void *heapptr)
{
duk_hthread *thr = (duk_hthread*)ctx;
return(DUK_HEAPHDR_GET_NEXT(thr->heap, ((duk_heaphdr*)heapptr)));
}