When we process required arguments their amount may exceed maximum
number of arguments which are allowed to be passed on C stack. In this
case the remainder is shifted to optionals *but* we have called
next-lcl for all arguments what lead to a situation where all
arguments were passed on the list. Fixes#514.
The pipe from which we read the output of the C compiler could fill up
when a large number of warnings were printed leading to a deadlock
because we waited for the C compiler to finish before reading the
output.
Many parts of the source code were bent backward to support builds
without long floats which are always present given we depend expect
c99 compiler.
The corresponding C macros (ECL_LONG_FLOAT) and the *feature*
entry (:long-float) are marked as deprecated in the documentation.
For functions without returned value we did return cl_object value0
which was not initialized. That could lead to segmentation faults if
we have used result of calling a function defined as such location.
SFFI definition like this:
(ffi:def-function ("my_test_function3" sffi-test-3)
((x :float) (y :double))
:returning :void)
was previously compiled to
/* function definition for SFFI-TEST-3 */
/* optimize speed 3, debug 0, space 0, safety 2 */
static cl_object L6sffi_test_3(cl_object v1x, cl_object v2y)
{
cl_object env0 = ECL_NIL;
const cl_env_ptr cl_env_copy = ecl_process_env();
cl_object value0;
ecl_cs_check(cl_env_copy,value0);
{
TTL:
my_test_function3(ecl_to_float(v1x),ecl_to_double(v2y));
cl_env_copy->nvalues = 0;
return value0;
}
}
and now it is compiled to
/* function definition for SFFI-TEST-3 */
/* optimize speed 3, debug 0, space 0, safety 2 */
static cl_object L6sffi_test_3(cl_object v1x, cl_object v2y)
{
cl_object env0 = ECL_NIL;
const cl_env_ptr cl_env_copy = ecl_process_env();
cl_object value0;
ecl_cs_check(cl_env_copy,value0);
{
TTL:
my_test_function3(ecl_to_float(v1x),ecl_to_double(v2y));
value0 = ECL_NIL;
cl_env_copy->nvalues = 0;
return value0;
}
}
void functions are treated the same as when *destionation* is 'RETURN
in cmpmulti.lsp.
- add ffi implementation for long-float
- add ffi implementation for (complex float) types
- add compiler optimizations and definitions for complex float
We do not add c?float common constants (long-float i.e has optimizer
for 0.0 and -0.0), because we don't know if they are common at all and
if we think about it each would have four entries counting signed
zeros).
Also add informative comment about global-entries.
What has changed:
- new types si:complex-float, si:complex-single-float,
si:complex-double-float and si:complex-long-float
- new builtin classes long-float (for completness) and
si:complex-float
- new internal function si:complex-float and si:complex-float-p for
constructing complex floats (both arguments must be of the same
float type) and a type predicate
- printer for new types (right now it conses, see below)
- a new feature :complex-float
- a new type is recognized as a type disjoint of complex and real
- cleanup: +built-in-type-list+: remove some redundancy
For instance instread of saying
(real (or integer single-float double-float ratio))
We say
(real (or integer float ratio))
etc.
Flaws which will be fixed in upcoming commits:
- complex-float hierarchy is independent of the complex hierarchy
- ecl_make_complex_float could be replaced by _ecl_make_complex_*float
- write_complex_float allocates new objects for printing
- write_complex_float does print unreadable object
- math dispatchers doesn't recognize the object
Testing things out:
> (si:complex-float 0.0d0 0.0d0)
; #<CF(0.0d0 0.0d0)>
> (si:complex-float 0.0d0 0.0s0) ; signals type error
> (+ (si:complex-float 0.0d0 0.0d0) 1) ; signals type error
lisp runtime: make si_complex-float a subtype of a number.
TYPE= is only used from cmpopt's typep compiler macro which optimizes
atomic complex types by other means. Compound complex types are
handled differently for subtypep and typep (the first relies on
upgraded type and the second relies on the actual types), so we can't
rely in this case on SAFE-CANONICAL-TYPE.
This behaviour makes more sense, since the ANSI standard mandates
that disassemble should compile an interpreted function before
displaying the output (our own documentation even says so).
Also fixes disassemble for closures.
The compiler refactor of commit
7ec2f4a939 introduced an error where
all lexical variables where marked to cross function boundaries,
leading them to be stored in volatile variables on the stack.
ECL needs the definition of a function to inline it. Previously,
this definition would only be saved in the file local environment
(*cmp-env-root*) but not in the global environment used by
proclaim. Hence, ECL could only inline functions in the same file.
Now, we also put the definition of inline functions in the global
environment during load time. This leads to a behaviour of declaim
for inline functions, which is consistent with other declarations
(meaning that the declarations stay only in force during
compilation, but are proclaimed again at load time of the compiled
file).
Fixes#451.
We support both compare-and-swap and fetch-and-add (via
atomic-incf/decf) on the most common places and define an
extension interface for compare-and-swap similiar to the one in
SBCL.
These changes introduce new dependencies on the libatomic_ops
macros AO_fetch_compare_and_swap and AO_fetch_and_add.
After a call to ext:install-c-compiler while the bytecodes compiler
is installed, compile-file and compile-file-pathname still point
to bc-compile-file and bc-compile-file-pathname. Reported and
fixed by gitlab user pouar. Fixes#444.
Signal an error for compilation of cclosures. Allow for
compilation of bclosures over macros, functions and variables.
Macros are simply added to the compiler environment. For functions
and variables we enclose the definition of the closure in
appropiate let/flet forms, e.g. for `(lambda () (fun var))'
closing over the function `fun' and variable `var':
(let ((var ...))
(flet ((fun (x) ...))
(lambda () (fun var))))
Closures over tags and blocks are not implemented and will signal
an error during compilation.
The following statement:
(eval-when (:compile-toplevel :load-toplevel :execute)
(print "test"))
resulted in an error, since the compiler would expand the print
statement in a FFI:C-INLINE form, which can't be evaluated at
compile time.
Avoids redefinition of __ecl_frs_push_result if e.g. two tagbodies
follow each other in the same C block. This redefinition is an
error in C and compilers will not accept the generated code.
In both bytecmp and c compiler we use si:function-boundary and
si:unwind-protect-boundary where appropriate. Previously bytecmp used an ad-hoc
special variable for function-boundary and didn't mark unwind-protect at all.
Remove recently-introduced ECI package (maybe we will reintroduce it later when
we'll have a common frontend for compilers).
Interrupting a thread during setjmp with a call to ecl_unwind
leads to segmentation faults, since we try to call longjmp
before the corresponding setjmp has finished. Thus, we also need
to wait until setjmp has finished before we can set frs_val of
the frame.