and the linker. Note, however, that the flags that ECL uses may take
priority.
+ - In the C code we are beginning to use GCC's attributes (__attribute__) and
+ branch annotation (__builtin_expect) to decrease the size of code that
+ checks for errors and improve overall speed.
+
;;; Local Variables: ***
;;; mode:text ***
;;; fill-column:79 ***
cl_object fun = x;
AGAIN:
frame->frame.env->function = fun;
- if (fun == OBJNULL || fun == Cnil)
+ if (__builtin_expect(fun == OBJNULL || fun == Cnil, 0))
FEundefined_function(x);
switch (type_of(fun)) {
case t_cfunfixed:
- if (narg != (cl_index)fun->cfun.narg)
+ if (__builtin_expect(narg != (cl_index)fun->cfun.narg, 0))
FEwrong_num_arguments(fun);
return APPLY_fixed(narg, fun->cfunfixed.entry_fixed, sp);
case t_cfun:
goto AGAIN;
#endif
case t_symbol:
- if (fun->symbol.stype & stp_macro)
+ if (__builtin_expect(fun->symbol.stype & stp_macro, 0))
FEundefined_function(x);
fun = SYM_FUN(fun);
goto AGAIN;
ecl_function_dispatch(cl_env_ptr env, cl_object x)
{
cl_object fun = x;
- AGAIN:
- if (fun == OBJNULL || fun == Cnil)
+ AGAIN:
+ if (__builtin_expect(fun == OBJNULL || fun == Cnil, 0))
FEundefined_function(x);
switch (type_of(fun)) {
case t_cfunfixed:
return fun->instance.entry;
#endif
case t_symbol:
- if (fun->symbol.stype & stp_macro)
+ if (__builtin_expect(fun->symbol.stype & stp_macro, 0))
FEundefined_function(x);
fun = SYM_FUN(fun);
goto AGAIN;
reg0 = ecl_apply_from_stack_frame((cl_object)&frame, fun); \
the_env->stack_top -= __n; }
+static void
+undefined_function(cl_object fname)
+{
+ cl_error(3, @'undefined-function', @':name', fname);
+}
+
+static void
+invalid_function(cl_object obj)
+{
+ FEwrong_type_argument(@'function', obj);
+}
+
+
+
/* -------------------- THE INTERPRETER -------------------- */
cl_object
SETUP_ENV(the_env);
AGAIN:
if (reg0 == OBJNULL || reg0 == Cnil) {
- FEundefined_function(x);
+ undefined_function(x);
}
switch (type_of(reg0)) {
case t_cfunfixed:
reg0 = reg0->instance.slots[reg0->instance.length - 1];
goto AGAIN;
default:
- FEinvalid_function(reg0);
+ invalid_function(reg0);
}
break;
#endif
case t_symbol:
if (reg0->symbol.stype & stp_macro)
- FEundefined_function(x);
+ undefined_function(x);
reg0 = SYM_FUN(reg0);
goto AGAIN;
case t_bytecodes:
reg0 = ecl_interpret(frame, reg0->bclosure.lex, reg0->bclosure.code);
break;
default:
- FEinvalid_function(reg0);
+ invalid_function(reg0);
}
ECL_STACK_POP_N_UNSAFE(the_env, narg);
THREAD_NEXT;
extern ECL_API void FEinvalid_macro_call(cl_object obj) /*__attribute__((noreturn))*/;
extern ECL_API void FEinvalid_variable(const char *s, cl_object obj) /*__attribute__((noreturn))*/;
extern ECL_API void FEassignment_to_constant(cl_object v) /*__attribute__((noreturn))*/;
-extern ECL_API void FEundefined_function(cl_object fname) /*__attribute__((noreturn))*/;
-extern ECL_API void FEinvalid_function(cl_object obj) /*__attribute__((noreturn))*/;
+extern ECL_API void FEundefined_function(cl_object fname) __attribute__((noreturn));
+extern ECL_API void FEinvalid_function(cl_object obj) __attribute__((noreturn));
extern ECL_API void FEinvalid_function_name(cl_object obj) /*__attribute__((noreturn))*/;
extern ECL_API cl_object CEerror(cl_object c, const char *err_str, int narg, ...);
extern ECL_API void FEillegal_index(cl_object x, cl_object i);