Rework the engine's internal recursion limit (#2969)
This patch unifies the recursion limit checking for RegExp, function call and JSON as well. Until now the limit was only a counter which was increased/decreased at certain points. This counter has been substituted with a numeric limit which allows to restrict the stack usage. This patch fixes #2963 and resolves the closed #2258 issue. Co-authored-by: Gabor Loki loki@inf.u-szeged.hu JerryScript-DCO-1.0-Signed-off-by: Robert Fancsik frobert@inf.u-szeged.hu
This commit is contained in:
@@ -1542,6 +1542,25 @@ typedef struct
|
||||
*/
|
||||
#define ECMA_SYMBOL_HASH_SHIFT 2
|
||||
|
||||
#if (JERRY_STACK_LIMIT != 0)
|
||||
/**
|
||||
* Check the current stack usage. If the limit is reached a RangeError is raised.
|
||||
*/
|
||||
#define ECMA_CHECK_STACK_USAGE() \
|
||||
do \
|
||||
{ \
|
||||
if (ecma_get_current_stack_usage () > CONFIG_MEM_STACK_LIMIT) \
|
||||
{ \
|
||||
return ecma_raise_range_error (ECMA_ERR_MSG ("Maximum call stack size exceeded.")); \
|
||||
} \
|
||||
} while (0)
|
||||
#else /* JERRY_STACK_LIMIT == 0) */
|
||||
/**
|
||||
* If the stack limit is unlimited, this check is an empty macro.
|
||||
*/
|
||||
#define ECMA_CHECK_STACK_USAGE()
|
||||
#endif /* (JERRY_STACK_LIMIT != 0) */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
|
||||
@@ -1599,6 +1599,21 @@ ecma_bytecode_deref (ecma_compiled_code_t *bytecode_p) /**< byte code pointer */
|
||||
((size_t) bytecode_p->size) << JMEM_ALIGNMENT_LOG);
|
||||
} /* ecma_bytecode_deref */
|
||||
|
||||
#if (JERRY_STACK_LIMIT != 0)
|
||||
/**
|
||||
* Check the current stack usage by calculating the difference from the initial stack base.
|
||||
*
|
||||
* @return current stack usage in bytes
|
||||
*/
|
||||
uintptr_t JERRY_ATTR_NOINLINE
|
||||
ecma_get_current_stack_usage (void)
|
||||
{
|
||||
volatile int __sp;
|
||||
return (uintptr_t) (JERRY_CONTEXT (stack_base) - (uintptr_t)&__sp);
|
||||
} /* ecma_get_current_stack_usage */
|
||||
|
||||
#endif /* (JERRY_STACK_LIMIT != 0) */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
|
||||
@@ -393,6 +393,9 @@ ecma_value_t ecma_clear_error_reference (ecma_value_t value, bool set_abort_flag
|
||||
|
||||
void ecma_bytecode_ref (ecma_compiled_code_t *bytecode_p);
|
||||
void ecma_bytecode_deref (ecma_compiled_code_t *bytecode_p);
|
||||
#if (JERRY_STACK_LIMIT != 0)
|
||||
uintptr_t ecma_get_current_stack_usage (void);
|
||||
#endif /* (JERRY_STACK_LIMIT != 0) */
|
||||
|
||||
/* ecma-helpers-external-pointers.c */
|
||||
bool ecma_create_native_pointer_property (ecma_object_t *obj_p, void *native_p, void *info_p);
|
||||
|
||||
@@ -42,9 +42,10 @@ ecma_init (void)
|
||||
JERRY_CONTEXT (status_flags) &= (uint32_t) ~ECMA_STATUS_HIGH_PRESSURE_GC;
|
||||
#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */
|
||||
|
||||
#if defined (JERRY_CALL_STACK_LIMIT) && (JERRY_CALL_STACK_LIMIT != 0)
|
||||
JERRY_CONTEXT (function_call_counter) = JERRY_CALL_STACK_LIMIT;
|
||||
#endif /* defined (JERRY_CALL_STACK_LIMIT) && (JERRY_CALL_STACK_LIMIT != 0) */
|
||||
#if (JERRY_STACK_LIMIT != 0)
|
||||
volatile int sp;
|
||||
JERRY_CONTEXT (stack_base) = (uintptr_t)&sp;
|
||||
#endif /* (JERRY_STACK_LIMIT != 0) */
|
||||
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROMISE)
|
||||
ecma_job_queue_init ();
|
||||
|
||||
Reference in New Issue
Block a user