Allow configurable recursion depth and raise exception when exceeded
This commit is contained in:
parent
194b45c25d
commit
f979321141
11
src/kuroko.c
11
src/kuroko.c
|
@ -762,7 +762,8 @@ int main(int argc, char * argv[]) {
|
|||
int moduleAsMain = 0;
|
||||
int inspectAfter = 0;
|
||||
int opt;
|
||||
while ((opt = getopt(argc, argv, "+:c:C:dgGim:rstTMSV-:")) != -1) {
|
||||
int maxDepth = -1;
|
||||
while ((opt = getopt(argc, argv, "+:c:C:dgGim:rR:stTMSV-:")) != -1) {
|
||||
switch (opt) {
|
||||
case 'c':
|
||||
runCmd = optarg;
|
||||
|
@ -804,6 +805,9 @@ int main(int argc, char * argv[]) {
|
|||
case 'r':
|
||||
enableRline = 0;
|
||||
break;
|
||||
case 'R':
|
||||
maxDepth = atoi(optarg);
|
||||
break;
|
||||
case 'M':
|
||||
return runString(argv,0,"import kuroko; print(kuroko.module_paths)\n");
|
||||
case 'V':
|
||||
|
@ -834,6 +838,7 @@ int main(int argc, char * argv[]) {
|
|||
" -i Enter repl after a running -c, -m, or FILE.\n"
|
||||
" -m mod Run a module as a script.\n"
|
||||
" -r Disable complex line editing in the REPL.\n"
|
||||
" -R depth Set maximum recursion depth.\n"
|
||||
" -s Debug output from the scanner/tokenizer.\n"
|
||||
" -t Disassemble instructions as they are exceuted.\n"
|
||||
" -T Write call trace file.\n"
|
||||
|
@ -861,6 +866,10 @@ _finishArgs:
|
|||
findInterpreter(argv);
|
||||
krk_initVM(flags);
|
||||
|
||||
if (maxDepth != -1) {
|
||||
krk_setMaximumRecursionDepth(maxDepth);
|
||||
}
|
||||
|
||||
#ifndef KRK_DISABLE_DEBUG
|
||||
krk_debug_registerCallback(debuggerHook);
|
||||
#endif
|
||||
|
|
|
@ -225,6 +225,7 @@ typedef struct KrkVM {
|
|||
|
||||
KrkThreadState * threads; /**< Invasive linked list of all VM threads. */
|
||||
FILE * callgrindFile; /**< File to write unprocessed callgrind data to. */
|
||||
size_t maximumCallDepth; /**< Maximum recursive call depth. */
|
||||
} KrkVM;
|
||||
|
||||
/* Thread-specific flags */
|
||||
|
@ -824,3 +825,7 @@ extern KrkValue krk_operator_lt(KrkValue,KrkValue);
|
|||
*/
|
||||
extern KrkValue krk_operator_gt(KrkValue,KrkValue);
|
||||
|
||||
/**
|
||||
* @brief Set the maximum recursion call depth.
|
||||
*/
|
||||
extern void krk_setMaximumRecursionDepth(size_t maxDepth);
|
||||
|
|
|
@ -67,7 +67,7 @@ KRK_FUNC(current_thread,{
|
|||
static volatile int _threadLock = 0;
|
||||
static void * _startthread(void * _threadObj) {
|
||||
memset(&krk_currentThread, 0, sizeof(KrkThreadState));
|
||||
krk_currentThread.frames = calloc(KRK_CALL_FRAMES_MAX,sizeof(KrkCallFrame));
|
||||
krk_currentThread.frames = calloc(vm.maximumCallDepth,sizeof(KrkCallFrame));
|
||||
vm.globalFlags |= KRK_GLOBAL_THREADS;
|
||||
_obtain_lock(_threadLock);
|
||||
if (vm.threads->next) {
|
||||
|
|
18
src/vm.c
18
src/vm.c
|
@ -734,7 +734,10 @@ _finishKwarg:
|
|||
return 2;
|
||||
}
|
||||
|
||||
if (unlikely(krk_currentThread.frameCount == KRK_CALL_FRAMES_MAX)) goto _errorAfterKeywords;
|
||||
if (unlikely(krk_currentThread.frameCount == vm.maximumCallDepth)) {
|
||||
krk_runtimeError(vm.exceptions->baseException, "maximum recursion depth exceeded");
|
||||
goto _errorAfterKeywords;
|
||||
}
|
||||
|
||||
KrkCallFrame * frame = &krk_currentThread.frames[krk_currentThread.frameCount++];
|
||||
frame->closure = closure;
|
||||
|
@ -1143,12 +1146,23 @@ KRK_FUNC(unload,{
|
|||
}
|
||||
})
|
||||
|
||||
void krk_setMaximumRecursionDepth(size_t maxDepth) {
|
||||
vm.maximumCallDepth = maxDepth;
|
||||
|
||||
KrkThreadState * thread = vm.threads;
|
||||
while (thread) {
|
||||
thread->frames = realloc(thread->frames, maxDepth * sizeof(KrkCallFrame));
|
||||
thread = thread->next;
|
||||
}
|
||||
}
|
||||
|
||||
void krk_initVM(int flags) {
|
||||
vm.globalFlags = flags & 0xFF00;
|
||||
vm.maximumCallDepth = KRK_CALL_FRAMES_MAX;
|
||||
|
||||
/* Reset current thread */
|
||||
krk_resetStack();
|
||||
krk_currentThread.frames = calloc(KRK_CALL_FRAMES_MAX,sizeof(KrkCallFrame));
|
||||
krk_currentThread.frames = calloc(vm.maximumCallDepth,sizeof(KrkCallFrame));
|
||||
krk_currentThread.flags = flags & 0x00FF;
|
||||
krk_currentThread.module = NULL;
|
||||
vm.threads = &krk_currentThread;
|
||||
|
|
Loading…
Reference in New Issue