Commit graph

9041 commits

Author SHA1 Message Date
Daniel Kochmański
e09f0d9742 cmpdefs: fix builds for CC [dlopen host -> no-dlopen target]
(DEFCONFIG *LD-SHARED-FLAGS*) was called without a value when dlopen was not
defined, that lead to error when destructuring. We put there "" instead now.
2025-11-24 10:58:15 +01:00
Marius Gerbershagen
2279b78514 cmp: fix typos 2025-11-23 17:45:10 +01:00
Daniel Kochmański
7933468deb Merge branch 'cross-compilation' into 'develop'
Cross-compilation of user code

See merge request embeddable-common-lisp/ecl!358
2025-11-22 20:39:50 +00:00
Marius Gerbershagen
4734509f15 cmp: allow cross compiling to/from targets without shared library support 2025-11-22 16:25:42 +01:00
Marius Gerbershagen
0baa1290e6 cmp: fix constant folding for target dependent constants
Register these constants as symbol macros in the lexical environment.
Maybe not the cleanest solution, but it works.
2025-11-22 16:25:42 +01:00
Marius Gerbershagen
7a1bd96eb7 cmp: make sure COMPILE works during cross compilation
Previously, calling COMPILE during cross compilation always failed due
to trying to load a shared object compiled for the wrong architecture.
We now temporarily switch back to the host configuration, compile and
load our shared object, and then go on with the target config.
2025-11-22 16:25:42 +01:00
Marius Gerbershagen
7932ffb1be fix cross compilation to a Windows target
Cross compilation of ECL itself:

- The windres program comes with the usual cross compilation target
  prefixes, use AC_CHECK_TOOL to select the right one.
- For c::update-compiler-features, we need to check the features of the
  host system instead of the target because that determines the
  executable prefix of the ecl_min stub.

Cross compilation of user code: We just have to replace some read time
conditionals by runtime checks.

Further notes on Windows cross compilation using mingw:

- Our old copy of libgmp doesn't work, one needs to update that before
  compiling.
- ASDF fails to compile unless XDG_CACHE_HOME is set (it tries and
  fails to find a Windows cache directory if XDG_CACHE_HOME is empty).
- The `windres` program may be located in a separate package from the
  mingw compiler. On debian, I had to install binutils-mingw-w64 and
  gcc-mingw-w64.
2025-11-22 16:25:42 +01:00
Marius Gerbershagen
9365e7abe7 loop macro: fix expansion for cross compilation targets
Check for types in the target environment.
2025-11-22 16:25:42 +01:00
Marius Gerbershagen
4271c7594d cmp: handle subtypep for cross compilation with mismatching complex float features
This is a bit tricky to solve since UPGRADED-COMPLEX-PART-TYPE and
SUBTYPEP behave differently depending on whether we have complex float
support or not and the behaviour is a special case compared to other
types due to the upgrading of part types that is happening.

What we do now is to add a custom declaration in the environment and
select the behaviour based on a runtime check.
2025-11-22 16:25:42 +01:00
Marius Gerbershagen
f099a9082a cmp: move proclamations from system-properties into a compiler specific storage
This allows us to switch out the proclamations when cross-compiling so
that target specific functions are declared correctly.

This was a problem for cross compilation with mismatching thread
support, so we can now allow that.
2025-11-22 16:25:42 +01:00
Marius Gerbershagen
c5f6cd0246 cmp: change handling of *cmp-env-root*
Due to the recent introduction of cross compilation features,
*cmp-env* has to contain type information throughout the entire
compilation (not only while we are compiling a form) so that (typep x
type *cmp-env*) works correctly. Therefore, we can't set *cmp-env* to
nil initially as we did previously. Instead, we set *cmp-env*
to *cmp-env-root* initially.
2025-11-22 16:25:42 +01:00
Marius Gerbershagen
79d33bdd83 cmp: fix typo 2025-11-22 16:25:42 +01:00
Marius Gerbershagen
872622bd0c doc: document the cross compilation feature 2025-11-22 16:25:42 +01:00
Marius Gerbershagen
e30c37691b tests: implement tests for cross compilation of user code
We start a remote ECL host and replace COMPILE-FILE and COMPILE by a
stub which shells out compile commands to this remote ECL. Moreover, a
few commands defining types, special variables and proclamations are
mirrored in the remote ECL as well. This of course is not a complete
synchronization mechanism and thus the state of the remote ECL will
not be 100% the same as that of the host which means that the COMPILE
stub is not an entirely correct implementation of the ANSI standard.
But it works well enough to run the test suite which is all we need.
2025-11-21 19:08:14 +01:00
Marius Gerbershagen
ee60bffaf0 cmp: allow cross compiling to/from targets with complex float support
A host compiler without complex float support still needs to be able
to emit C instructions for complex float. In this case, the host
doesn't define si::complex-{single/double/long}-float types, so we
need to replace those by types which all variants of ECL understand.
Moreover, functions for emitting C code dealing with complex floats
must be present even if the host doesn't support complex floats
natively.

Deciding whether to emit these instructions is implemented either by
explicit checks for *complex-float* or automatically as the compiler
will not create :c{s/d/l}float locations for a target without complex
float support (this is decided at runtime based on the contents
of *machine*).
2025-11-21 19:08:14 +01:00
Marius Gerbershagen
deec67aa57 cmp: allow for cross compiling to/from targets with C compatible variadic dispatch 2025-11-21 19:08:14 +01:00
Marius Gerbershagen
02415a4008 cmp: warn for unsupported cross compilation configurations 2025-11-21 19:08:14 +01:00
Marius Gerbershagen
fb321885db cmp: easier cross-compilation of user code
The procedure works as follows. First, cross compile ECL itself. In
this step, we dump the configuration of the compiler. This
configuration can then be later restored to put the host compiler into
cross compilation mode using a new option to WITH-COMPILATION-UNIT.

The following changes to the public interface are introduced:

- WITH-COMPILATION-UNIT now takes a new :target keyword
- New functions C:WRITE-TARGET-INFO, C:READ-TARGET-INFO to dump and
  restore the config
- The environment parameters to TYPEP and SUBTYPEP are no longer
  unused. User macros can query type relationships in the target
  environment using these parameters.

Internal changes in the compiler include:

- Target dependent variables in the compiler are defined using a new
  DEFCONFIG macro. C:WRITE-TARGET-INFO simply writes the value of
  these variables to a file.
- The distinction between target types and host types already exists
  in the compiler. In this commit, we just register the target types in
  the compiler environment when we change the compiler configuration.
2025-11-21 19:08:14 +01:00
Daniel Kochmański
bd64c52d7e Merge branch 'fix-802' into develop 2025-11-17 10:42:22 +01:00
Daniel Kochmański
7c5471947d c2tagbody-body: fix a regression when processing intermediate tag
In 521e815158 I've introduced a regression where
we did not bind the destination and exit label for intermediate forms.

Fixes #802.
2025-11-17 10:39:45 +01:00
Daniel Kochmański
1e10761593 tests: add a test for the recent regression 2025-11-16 11:03:48 +01:00
Marius Gerbershagen
b8bd5f4026 cmp: fix constant folding
Fixes a regression introduced in commit
816c08340b. After the changes in that
commit, c1forms of name variable can denote constants as well.

Since we are now more aggressive with inlining constant access, we
have to fix a bad defconstant definition in clos/boot.lsp as well (the
new definition makes sure that the compile-time and load-time
evaluations of the constant are eql).
2025-11-15 16:52:31 +01:00
Marius Gerbershagen
294da20f38 Merge branch 'cons-kingdom' into 'develop'
Cleanups and fixes for SUBTYPEP

See merge request embeddable-common-lisp/ecl!357
2025-09-14 12:15:28 +00:00
Daniel Kochmański
dceff25679 predlib: fix a braino in one of the clauses of CANONICAL-TYPE
Instead of returning the registered tag (when found), we've returned NIL.
2025-09-08 09:16:27 +02:00
Daniel Kochmański
47c17cbfa2 predlib: add accessors for *elementary-types* and *member-types*
Previously elementary types were considered to be (CONS SPECC TAG), but I want to
introduce additional slot information to them, so we define a structure for that
type. The representation a is list because MAYBE-SAVE-TYPES calls COPY-TREE. Also
DEFSTRUCT is not available yet.

Rename PUSH-TYPE to PUSH-NEW-TYPE and move it to a correct section in the file.
2025-09-08 09:16:25 +02:00
Daniel Kochmański
783289c629 predlib: assert n important property when adding a new type
The property in question is a strict total order within the kingdom.
2025-08-27 10:46:58 +02:00
Daniel Kochmański
6de56d977f predlib: cosmetic cleanup
Fix comment depth (;; -> ;;;) and simplify a few expressions.
2025-08-27 10:46:58 +02:00
Daniel Kochmański
ef5d534af2 subtypep: refactor canonical number types for consistency
Previously CANONICAL-COMPLEX-TYPE accepted the specializer and that was not
consistent with other functions handling canonical types.

Rename REGISTER-INTERVAL-TYPE to CANONICAL-INTERVAL-TYPE because this function
may register numerous elementary types and return their bit-wise composition,
and rename REGISTER-ELEMENTARY-INTERVAL to REGISTER-INTERVAL-TYPE.
2025-08-27 10:46:58 +02:00
Daniel Kochmański
19eb060d14 subtypep: refactor register-interval-type
We use destructuring to bind elements of the type, and both high and low tag
computation follows the same code shape to highlight similarities.
2025-08-27 10:46:58 +02:00
Daniel Kochmański
b7a22e904b subtypep: ensure that all registered types have total order
This allows us to remove the kludge from FIND-TYPE-BOUNDS - the parameter
MINIMIZE-SUPER was to allow registering ranges that are in a canonical
form (that is left-bound).

We don't register types that may be obtained by a composition of other
registered types to avoid fake aliasing.
2025-08-27 10:46:58 +02:00
Daniel Kochmański
25f825efff subtypep: don't add a new tag for equivalent types
The function MAKE-REGISTERED-TAG calls FIND-TYPE-BOUNDS to determine supertypes
that need to be updated with the new bit, and subtypes that need to be included
in the new tag.

Thiis procedure was bogus because it did not recognize equivalent types. That
lead to a situation, where synonymous types could have been added twice with
incorrect relation. Consider:

type A: 011
type B: 001

We add a type C that is equivalent to A and B is subtype (to both). With the old
method the result would be:

type A: 111
type B: 001
type C: 101

So if we had later queried wheter A is subtypep to C, then the answer would be
incorrectly NIL.

The bug was hidden by the fact, that CANONICAL-TYPE expands type aliases when
they are symbols, so we had never encountered a situation where equivalent types
had different names in *ELEMENTARY-TYPES*. This changes when we introduce the
new kingdom for CONS type, because the key is (CONS X Y), and symbols in type
names X Y are not expanded, so

  (CONS (OR FIXNUM BIGNUM)) is not EQUAL to (CONS INTEGER)
2025-08-27 10:46:58 +02:00
Daniel Kochmański
fd101452b6 subtypep: introduce the function MAKE-REGISTERED-TAG
This function is used by REGISTER-ELEMENTARY-INTERVAL and REGISTER-TYPE.
Additionally we drop the call to LOGANDC2 in the invocation of UPDATE-TYPE,
because FIND-TYPE-BOUNDS always does that for us (so it was redundant).

Also remove redundant (and unused) function BOUNDS-<.
2025-08-27 10:46:58 +02:00
Daniel Kochmański
cfe1dec177 subtypep: rebind type variables with a macro WITH-TYPE-DATABASE
It seems that some variables were rebound also in cmptype-arith.lsp -- to avoid
potential inconsistency we abstract away bindings as WITH-TYPE-DTABASE.
2025-08-27 10:46:58 +02:00
Daniel Kochmański
e8f931c484 subtypep: fix the expansion of the type STRING
The type STRING was defined as an alias to (ARRAY CHARACTER (*)) and that was
inconsistent with the type definition for unicode builds, it should be:

    (OR (ARRAY CHARACTER (*))
        (ARRAY BASE-CHAR (*)))
2025-08-27 10:46:58 +02:00
Daniel Kochmański
135632bedf subtypep: small refactor of find-built-in-tag
Instead of relying on default value in gethash, we handle NIL separately and use
FOUNDP in the last case. That reduces code nesting and makes it more redable.
2025-08-27 10:46:58 +02:00
Daniel Kochmański
fb5969cdcc subtypep: cleanup; remove unnecessary call
FIND-BUILT-IN-TAG works only on type specifiers being symbols , but we've
already estabilished that this type specifier is a cons (COMPLEX ,@args).
2025-08-27 10:46:58 +02:00
Daniel Kochmański
019579dd46 subtypep: use constants for hardcoded tags for T and NIL
+BUILT-IN-TYPE-NIL+ and +BUILT-IN-TYPE-t+ are bottom and top types of the common
lisp type system. They were sometimes refered in the code as naked integers - we
change that by defining constants to better convey the meaning.
2025-08-27 10:46:58 +02:00
Daniel Kochmański
f04f0ac160 bytevm: fix a possible segmentation fault in OP_PUSHKEYS
The issue was revealed by registering long (EQL LIST) elements as cons types --
essentially we've reached the frame size limit in the middle of the loop, the
frame was resized, but the pointer `first' was relative to the old frame base.

The solution is to reinitialize the pointer before each iteration.
2025-08-27 10:46:58 +02:00
Daniel Kochmański
b9e0a7f949 Clarify INSTALL instructions for Windows (replace ...) 2025-08-23 14:14:12 +02:00
Daniel Kochmański
e5aa9c1110 Fix a braino in CL:FINISH-OUTPUT which called ecl_force_output
The function CL:FINISH-OUTPUT called by accident ECL_FORCE_OUTPUT when used on
ANSI streams. That becames an issue when we call it on a two-way stream where
the output buffer was a gray stream with STREAM-FINISH-OUTPUT differing from
STREAM-FORCE-OUTPUT.
2025-08-13 14:19:56 +02:00
Marius Gerbershagen
a2019ce31a Merge branch 'object-streams' into 'develop'
Bivalent streams improvements

See merge request embeddable-common-lisp/ecl!355
2025-08-11 16:41:03 +00:00
Daniel Kochmański
86876f1dc3 Update changelog 2025-08-11 10:01:41 +02:00
Daniel Kochmański
c33c8f2ef7 tests: add a test for failed conversion byte->char
Sometimes bytes are outside of the character range. In that case we should
signal an error when we try to read them.
2025-08-11 10:01:41 +02:00
Daniel Kochmański
41f52d8d0f streams: bivalent stream signals a condition for bytes out of range
Sometimes a byte may be not within the character code range. In that case, when
we read the char, the system will signal a condition.

Alternatively (and that's the behavior before this commit) we could return the
character #\Nul. That was done by virtue of ECL_CHAR_CODE skipping tag bytes, so
the returned NIL was treated as 0.
2025-08-11 10:01:40 +02:00
Daniel Kochmański
43fef5fad8 streams: address a possible segfault in sequence streams
Byte streams transcoding to :ucs-2 and :ucs-4 don't call ecl_set_stream_elt_type
effectively not initializing .byte_buffer.  Moreover functions seq_in_read_byte8
and seq_out_write_byte8 assume the vector type to be an octet based, and they
increment the stream position and test for its limit according to that.

That means that ecl_binary_read_byte and ecl_binary_write_byte calls would
segfault when seq_in_read_byte8 and seq_out_write_byte8 are called.

Both conditions could be easily mitigated by initializing .byte_buffer manually
and fixing seq_*_*_byte8 functions to account for the byte size, but there is no
need for that, because for these streams we are not using

ecl_binary_*_byte
ecl_eformat_*_byte

so byte8 functions are not called and .byte_buffer is not used.
2025-08-11 10:01:40 +02:00
Daniel Kochmański
c7d78a412e tests: add tests for bivalent streams based on sequences 2025-08-11 10:01:40 +02:00
Daniel Kochmański
26a22057e5 streams: introduce direct bivalent sequence streams
Previously sequence streams always needed to go through the eformat and binary
encoders and decoders -- if bytes were too big, then we couldn't create sequence
streams from them.

After this commit it is possible to pass a character stream or a byte stream and
use it as a bivalent stream without a roundtrip for encoding and decoding.
2025-08-11 10:01:40 +02:00
Daniel Kochmański
688eceb9ed streams: bring bivalent streams UNREAD-CHAR and UNREAD-BYTE together
This finishes the commit that adds unread-byte and peek-byte functions to the
mix in that for bivalent stream UNREAD-BYTE will work for the subsequent
READ-CHAR and vice versa. This also caters to transcoding etc.
2025-08-11 10:01:40 +02:00
Daniel Kochmański
b7eaf35502 streams: move byte_stack to strm_os and improve UNREAD-BYTE
The .byte_stack is used only by files to:
a) unread a single octet when we use fallback LISTEN implementation
b) unread bytes that make a character when UNREAD-CHAR is used

The latter is important to transcode characters from one external format to
another (i.e see the test external-format.0003-transcode-read-char).

This commit improves the function unread-byte to do the same brinding bivalent
streams almost to parity with regard to that implementation (see next commit).

That makes the implementation of eformat cleaner, .byte_stack more
self-contained, and saves us consing new byte stack for sequence streams (where
it was simply ignored, not to mention not entirely correct - because we've used
a .byte_stack length to decrement the pointer position while the byte could have
more bits than one octet).

Other optimizations that could be done here:
- make the byte stack an adjustable vector to avoid consing on each unread
2025-08-11 10:01:40 +02:00
Daniel Kochmański
10a1e8dddf streams: invert .last_char processing and UNREAD-CHAR
Previously we've stored in this field the last read char, while now we store
there the last unread char. This way we can't tell whether the last read char
was the same as the unread one, but on the other hand this way requires less
bookeeping and the code shape is similar to UNREAD-BYTE.
2025-08-11 10:01:40 +02:00