mirror of
https://github.com/janet-lang/janet
synced 2024-11-28 19:19:53 +00:00
Add configurable stack overflow to prevent infinite recursion
without waiting for out of memory.
This commit is contained in:
parent
7f693796ea
commit
af6e6ded35
@ -1,3 +1,4 @@
|
|||||||
|
(def a (fn [] 2))
|
||||||
#
|
#
|
||||||
# Copyright (c) 2017 Calvin Rose
|
# Copyright (c) 2017 Calvin Rose
|
||||||
#
|
#
|
||||||
|
@ -75,9 +75,11 @@
|
|||||||
(def end (get head 2))
|
(def end (get head 2))
|
||||||
(def _inc (get head 3))
|
(def _inc (get head 3))
|
||||||
(def inc (if _inc _inc 1))
|
(def inc (if _inc _inc 1))
|
||||||
|
(def endsym (gensym))
|
||||||
(tuple 'do
|
(tuple 'do
|
||||||
(tuple 'var sym start)
|
(tuple 'var sym start)
|
||||||
(tuple 'while (tuple '< sym end)
|
(tuple 'def endsym end)
|
||||||
|
(tuple 'while (tuple '< sym endsym)
|
||||||
(tuple-prepend body 'do)
|
(tuple-prepend body 'do)
|
||||||
(tuple 'varset! sym (tuple '+ sym 1))
|
(tuple 'varset! sym (tuple '+ sym 1))
|
||||||
)))
|
)))
|
||||||
@ -136,7 +138,7 @@
|
|||||||
(fiber (fn [parent]
|
(fiber (fn [parent]
|
||||||
(var up parent)
|
(var up parent)
|
||||||
(def me (fiber-current))
|
(def me (fiber-current))
|
||||||
(def p (parser))
|
(def p (parser 1))
|
||||||
(while true
|
(while true
|
||||||
(def s (parser-status p))
|
(def s (parser-status p))
|
||||||
(if (= s :full)
|
(if (= s :full)
|
||||||
|
@ -541,6 +541,11 @@ static void *op_lookup[255] = {
|
|||||||
VM_OP(DOP_CALL)
|
VM_OP(DOP_CALL)
|
||||||
{
|
{
|
||||||
Dst callee = stack[oparg(2, 0xFFFF)];
|
Dst callee = stack[oparg(2, 0xFFFF)];
|
||||||
|
#ifdef DST_STACK_MAX
|
||||||
|
if (dst_vm_fiber->stacktop > DST_STACK_MAX) {
|
||||||
|
vm_throw("stack overflow");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if (dst_checktype(callee, DST_FUNCTION)) {
|
if (dst_checktype(callee, DST_FUNCTION)) {
|
||||||
func = dst_unwrap_function(callee);
|
func = dst_unwrap_function(callee);
|
||||||
dst_stack_frame(stack)->pc = pc;
|
dst_stack_frame(stack)->pc = pc;
|
||||||
|
@ -120,6 +120,11 @@ extern "C" {
|
|||||||
* ands crashing (the parser). Instead, error out. */
|
* ands crashing (the parser). Instead, error out. */
|
||||||
#define DST_RECURSION_GUARD 1024
|
#define DST_RECURSION_GUARD 1024
|
||||||
|
|
||||||
|
/* Define max stack size for stacks before raising a stack overflow error.
|
||||||
|
* If this is not defined, fiber stacks can grow without limit (until memory
|
||||||
|
* runs out) */
|
||||||
|
#define DST_STACK_MAX 4096
|
||||||
|
|
||||||
/* Use nanboxed values - uses 8 bytes per value instead of 12 or 16. */
|
/* Use nanboxed values - uses 8 bytes per value instead of 12 or 16. */
|
||||||
#define DST_NANBOX
|
#define DST_NANBOX
|
||||||
#define DST_NANBOX_47
|
#define DST_NANBOX_47
|
||||||
|
@ -458,12 +458,12 @@ static int root(DstParser *p, DstParseState *state, uint8_t c) {
|
|||||||
int dst_parser_consume(DstParser *parser, uint8_t c) {
|
int dst_parser_consume(DstParser *parser, uint8_t c) {
|
||||||
int consumed = 0;
|
int consumed = 0;
|
||||||
if (parser->error) return 0;
|
if (parser->error) return 0;
|
||||||
|
parser->index++;
|
||||||
while (!consumed && !parser->error) {
|
while (!consumed && !parser->error) {
|
||||||
DstParseState *state = &dst_v_last(parser->states);
|
DstParseState *state = &dst_v_last(parser->states);
|
||||||
consumed = state->consumer(parser, state, c);
|
consumed = state->consumer(parser, state, c);
|
||||||
}
|
}
|
||||||
parser->lookback = c;
|
parser->lookback = c;
|
||||||
parser->index++;
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user