1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-06-14 15:40:19 +02:00

push error handlers out of line in the vm

* libguile/vm.c:
  (vm_error):
  (vm_error_bad_instruction):
  (vm_error_unbound):
  (vm_error_unbound_fluid):
  (vm_error_not_a_variable):
  (vm_error_not_a_thunk):
  (vm_error_apply_to_non_list):
  (vm_error_kwargs_length_not_even):
  (vm_error_kwargs_invalid_keyword):
  (vm_error_kwargs_unrecognized_keyword):
  (vm_error_too_many_args):
  (vm_error_wrong_num_args):
  (vm_error_wrong_type_apply):
  (vm_error_stack_overflow):
  (vm_error_stack_underflow):
  (vm_error_improper_list):
  (vm_error_not_a_pair):
  (vm_error_not_a_bytevector):
  (vm_error_not_a_struct):
  (vm_error_no_values):
  (vm_error_not_enough_values):
  (vm_error_continuation_not_rewindable):
  (vm_error_bad_wide_string_length):
  (vm_error_invalid_address):
  (vm_error_object):
  (vm_error_free_variable): New internal helpers, implementing VM error
  handling.

* libguile/vm-engine.h (VM_ASSERT): New helper macro.
  (ASSERT, CHECK_OBJECT, CHECK_FREE_VARIABLE):
  (PRE_CHECK_UNDERFLOW, PUSH_LIST): Use the new helper.

* libguile/vm-i-loader.c:
* libguile/vm-i-scheme.c:
* libguile/vm-i-system.c: Use VM_ASSERT and the out-of-line error
  handlers.

* libguile/vm-engine.c (vm_engine): Remove inline error handlers, and
  remove a couple of local vars.  Use VM_ASSERT.  Have halt handle the
  return itself.
This commit is contained in:
Andy Wingo 2012-04-30 20:25:53 +02:00
parent 7dbc03498a
commit 53bdfcf034
6 changed files with 332 additions and 320 deletions

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2001, 2009, 2010, 2011 Free Software Foundation, Inc.
/* Copyright (C) 2001, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
@ -103,8 +103,11 @@
* Cache/Sync
*/
#define VM_ASSERT(condition, handler) \
do { if (SCM_UNLIKELY (!(condition))) { SYNC_ALL(); handler; } } while (0)
#ifdef VM_ENABLE_ASSERTIONS
# define ASSERT(condition) if (SCM_UNLIKELY (!(condition))) abort()
# define ASSERT(condition) VM_ASSERT (condition, abort())
#else
# define ASSERT(condition)
#endif
@ -191,18 +194,16 @@
/* Accesses to a program's object table. */
#if VM_CHECK_OBJECT
#define CHECK_OBJECT(_num) \
do { if (SCM_UNLIKELY ((_num) >= object_count)) goto vm_error_object; } while (0)
#define CHECK_OBJECT(_num) \
VM_ASSERT ((_num) < object_count, vm_error_object ())
#else
#define CHECK_OBJECT(_num)
#endif
#if VM_CHECK_FREE_VARIABLES
#define CHECK_FREE_VARIABLE(_num) \
do { \
if (SCM_UNLIKELY ((_num) >= SCM_PROGRAM_NUM_FREE_VARIABLES (program))) \
goto vm_error_free_variable; \
} while (0)
#define CHECK_FREE_VARIABLE(_num) \
VM_ASSERT ((_num) < SCM_PROGRAM_NUM_FREE_VARIABLES (program), \
vm_error_free_variable ())
#else
#define CHECK_FREE_VARIABLE(_num)
#endif
@ -276,21 +277,20 @@
# define NULLSTACK_FOR_NONLOCAL_EXIT()
#endif
#define CHECK_OVERFLOW() \
if (SCM_UNLIKELY (sp >= stack_limit)) \
goto vm_error_stack_overflow
/* For this check, we don't use VM_ASSERT, because that leads to a
per-site SYNC_ALL, which is too much code growth. The real problem
of course is having to check for overflow all the time... */
#define CHECK_OVERFLOW() \
do { if (SCM_UNLIKELY (sp >= stack_limit)) goto handle_overflow; } while (0)
#ifdef VM_CHECK_UNDERFLOW
#define CHECK_UNDERFLOW() \
if (SCM_UNLIKELY (sp <= SCM_FRAME_UPPER_ADDRESS (fp))) \
goto vm_error_stack_underflow
#define PRE_CHECK_UNDERFLOW(N) \
if (SCM_UNLIKELY (sp - N <= SCM_FRAME_UPPER_ADDRESS (fp))) \
goto vm_error_stack_underflow
VM_ASSERT (sp - (N) > SCM_FRAME_UPPER_ADDRESS (fp), vm_error_stack_underflow ())
#define CHECK_UNDERFLOW() PRE_CHECK_UNDERFLOW (0)
#else
#define CHECK_UNDERFLOW() /* nop */
#define PRE_CHECK_UNDERFLOW(N) /* nop */
#define CHECK_UNDERFLOW() /* nop */
#endif
@ -333,10 +333,7 @@ do \
{ \
for (; scm_is_pair (l); l = SCM_CDR (l)) \
PUSH (SCM_CAR (l)); \
if (SCM_UNLIKELY (!NILP (l))) { \
finish_args = scm_list_1 (l); \
goto vm_error_improper_list; \
} \
VM_ASSERT (NILP (l), vm_error_improper_list (l)); \
} while (0)