Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 23 additions & 2 deletions quickjs.c
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,9 @@ struct JSRuntime {
void *user_opaque;
void *libc_opaque;
JSRuntimeFinalizerState *finalizers;

/* Unified handler for all the engine hooks */
JS_BOOL (*hooks)(JSRuntimeHooks type, void* opaque);
};

struct JSClass {
Expand Down Expand Up @@ -1440,7 +1443,17 @@ static void js_trigger_gc(JSRuntime *rt, size_t size)
(uint64_t)rt->malloc_state.malloc_size);
}
#endif
JS_RunGC(rt);
//To ensure JS_RunGC cannot be executed again within callbacks, disable and restore it after.
size_t tmp_threshold = rt->malloc_gc_threshold;
rt->malloc_gc_threshold=-1;

if((rt->hooks == NULL) || rt->hooks(JS_HOOK_GC_BEFORE,NULL)){
JS_RunGC(rt);
if(rt->hooks != NULL)rt->hooks(JS_HOOK_GC_AFTER,NULL);
}

rt->malloc_gc_threshold=tmp_threshold;

rt->malloc_gc_threshold = rt->malloc_state.malloc_size +
(rt->malloc_state.malloc_size >> 1);
}
Expand Down Expand Up @@ -1810,6 +1823,8 @@ JSRuntime *JS_NewRuntime2(const JSMallocFunctions *mf, void *opaque)
rt->malloc_state = ms;
rt->malloc_gc_threshold = 256 * 1024;

rt->hooks = NULL;

bf_context_init(&rt->bf_ctx, js_bf_realloc, rt);

init_list_head(&rt->context_list);
Expand Down Expand Up @@ -1922,7 +1937,8 @@ void JS_SetDumpFlags(JSRuntime *rt, uint64_t flags)
rt->dump_flags = flags;
}

size_t JS_GetGCThreshold(JSRuntime *rt) {
size_t JS_GetGCThreshold(JSRuntime *rt)
{
return rt->malloc_gc_threshold;
}

Expand All @@ -1932,6 +1948,11 @@ void JS_SetGCThreshold(JSRuntime *rt, size_t gc_threshold)
rt->malloc_gc_threshold = gc_threshold;
}

void JS_SetHooksHandler(JSRuntime *rt, JS_BOOL (*fn)(JSRuntimeHooks type, void* opaque))
{
rt->hooks = fn;
}

#define malloc(s) malloc_is_forbidden(s)
#define free(p) free_is_forbidden(p)
#define realloc(p,s) realloc_is_forbidden(p,s)
Expand Down
9 changes: 9 additions & 0 deletions quickjs.h
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,13 @@ typedef void JSRuntimeFinalizer(JSRuntime *rt, void *arg);

typedef struct JSGCObjectHeader JSGCObjectHeader;

/* Engine hooks */
typedef enum JSRuntimeHooks{
JS_HOOK_NONE, //Don't use, just to catch potential bugs
JS_HOOK_GC_BEFORE, //Run before a GC event takes place. No payload. Return false if the hooks opposes the GC event to take place.
JS_HOOK_GC_AFTER, //Run after a GC event took place. No payload. Return value ignored.
} JSRuntimeHooks;

JS_EXTERN JSRuntime *JS_NewRuntime(void);
/* info lifetime must exceed that of rt */
JS_EXTERN void JS_SetRuntimeInfo(JSRuntime *rt, const char *info);
Expand All @@ -332,6 +339,8 @@ JS_EXTERN void JS_SetMemoryLimit(JSRuntime *rt, size_t limit);
JS_EXTERN void JS_SetDumpFlags(JSRuntime *rt, uint64_t flags);
JS_EXTERN size_t JS_GetGCThreshold(JSRuntime *rt);
JS_EXTERN void JS_SetGCThreshold(JSRuntime *rt, size_t gc_threshold);
/* register a hook dispatcher for this runtime. The handler should always return true for hooks which are not supported. */
JS_EXTERN void JS_SetHooksHandler(JSRuntime *rt, JS_BOOL (*fn)(JSRuntimeHooks type, void* opaque));
/* use 0 to disable maximum stack size check */
JS_EXTERN void JS_SetMaxStackSize(JSRuntime *rt, size_t stack_size);
/* should be called when changing thread to update the stack top value
Expand Down
Loading