diff --git a/src/c/stacks.d b/src/c/stacks.d index ac39f7639..714ccc9f9 100644 --- a/src/c/stacks.d +++ b/src/c/stacks.d @@ -532,6 +532,12 @@ frs_overflow(void) /* used as condition in list.d */ ecl_frame_ptr _ecl_frs_push(register cl_env_ptr env, register cl_object val) { + /* We store a dummy tag first, to make sure that it is safe to + * interrupt this method with a call to ecl_unwind. Otherwise, a + * stray ECL_PROTECT_TAG will lead to segfaults. AO_store_full is + * needed to ensure that the CPU doesn't reorder the memory + * stores. */ + AO_store_full((AO_t*)&(env->frs_top+1)->frs_val,(AO_t)ECL_DUMMY_TAG); ecl_frame_ptr output = ++env->frs_top; if (output >= env->frs_limit) { frs_overflow(); diff --git a/src/c/symbols_list.h b/src/c/symbols_list.h index ffe8c65e3..5fc077709 100755 --- a/src/c/symbols_list.h +++ b/src/c/symbols_list.h @@ -74,6 +74,7 @@ cl_symbols[] = { {"T", CL_ORDINARY, NULL, -1, OBJNULL}, {SYS_ "UNBOUND", SI_CONSTANT, si_unbound, 0, ECL_UNBOUND}, {SYS_ "PROTECT-TAG", SI_ORDINARY, NULL, -1, OBJNULL}, +{SYS_ "DUMMY-TAG", SI_ORDINARY, NULL, -1, OBJNULL}, {SYS_ "*RESTART-CLUSTERS*", SI_SPECIAL, NULL, -1, Cnil}, {SYS_ "*HANDLER-CLUSTERS*", SI_SPECIAL, NULL, -1, Cnil}, diff --git a/src/c/symbols_list2.h b/src/c/symbols_list2.h index acd1b8442..5c9f730ac 100644 --- a/src/c/symbols_list2.h +++ b/src/c/symbols_list2.h @@ -74,6 +74,7 @@ cl_symbols[] = { {"T",NULL}, {SYS_ "UNBOUND","si_unbound"}, {SYS_ "PROTECT-TAG",NULL}, +{SYS_ "DUMMY-TAG",NULL}, {SYS_ "*RESTART-CLUSTERS*",NULL}, {SYS_ "*HANDLER-CLUSTERS*",NULL}, diff --git a/src/h/object.h b/src/h/object.h index c83ba0d9e..111d68d08 100644 --- a/src/h/object.h +++ b/src/h/object.h @@ -246,8 +246,9 @@ enum ecl_stype { /* symbol type */ #define ECL_T ((cl_object)(cl_symbols+1)) #define ECL_UNBOUND ((cl_object)(cl_symbols+2)) #define ECL_PROTECT_TAG ((cl_object)(cl_symbols+3)) -#define ECL_RESTART_CLUSTERS ((cl_object)(cl_symbols+4)) -#define ECL_HANDLER_CLUSTERS ((cl_object)(cl_symbols+5)) +#define ECL_DUMMY_TAG ((cl_object)(cl_symbols+4)) +#define ECL_RESTART_CLUSTERS ((cl_object)(cl_symbols+5)) +#define ECL_HANDLER_CLUSTERS ((cl_object)(cl_symbols+6)) #define ECL_NO_TL_BINDING ((cl_object)(1 << ECL_TAG_BITS)) struct ecl_symbol {