9. Release Notes
This following summarizes the most important changes in recent Spicy releases. For an exhaustive list of all changes, see the #CHANGES file coming with the distribution.
9.1. Version 1.8 (in progress)
New Functionality
Changed Functionality
Bug fixes
Documentation
9.2. Version 1.7
New Functionality
Support Zeek-style documentation strings in Spicy source code.
Provide ability for host applications to initiate runtime’s module-pre-init phase manually.
Add DPD-style
spicy::accept_input()andspicy::decline_input().Add driver option to output full set of generated C++ files.
GH-1123: Support arbitrary expression as argument to type constructors, such as
interval(...).
Changed Functionality
Search
HILTI_CXX_INCLUDE_DIRSpaths before default include paths.Search user module paths before system paths.
Streamline runtime exception hierarchy.
Fix bug in cast from
realtointerval.GH-1326: Generate proper runtime types for enums.
GH-1330: Reject uses of imported module IDs as expression.
Bug fixes
GH-1310: Fix ASAN false positive with GCC.
GH-1345: Improve runtime performance of stream iteration.
GH-1367: Use unique filename for all object files generated during JIT.
Remove potential race during JIT when using
HILTI_CXX_COMPILER_LAUNCHER.GH-1349: Fix incremental regexp matching for potentially empty results.
Documentation
9.3. Version 1.6
New Functionality
GH-1249: Allow combining
&eodwith&untilor&until-including.GH-1251: When decoding bytes into a string using a given character set, allow caller to control error handling.
All methods taking a charset parameters now take an additional enum selecting 1 of 3 possible error handling strategies in case a character can’t be decoded/represented:
STRICTthrows an error,IGNOREskips the problematic character and proceeds with the next, andREPLACEreplaces the problematic character with a safe substitute.REPLACEis the default everywhere now, so that by default no errors are triggered.This comes with an additional functional change for the ASCII encoding: we now consistently sanitize characters that ASCII can’t represent when in
REPLACE/IGNOREmodes (and, hence, by default), and trigger errors inSTRICTmode. Previously, we’d sometimes let them through, and never triggered any errors. This also fixes a bug with the ASCII encoding sometimes turning a non-printable character into multiple repeated substitutes.GH-1294: Add library function to parse an address from string or bytes.
HLTO files now perform a version check when loaded.
We previously would potentially allow building a HLTO file against one version of the Spicy runtime, and then load it with a different version. If exposed symbols matched loading might have succeeded, but could still have lead to sublte bugs at runtime.
We now embed a runtime version string in HLTO files and reject loading HLTO files into a different runtime version. We require an exact version match.
New
packandunpackoperators.These provide low-level primitives for transforming a value into, or out of, a binary representations, see the docs for details.
Changed Functionality
GH-1236: Add support for adding link dependencies via
--cxx-link.GH-1285: C++ identifiers referenced in
&cxxnameare now automatically interpreted to be in the global namespace.Synchronization-related debug messages are now logged to the
spicy-verbosestream. We added logging of successful synchronization.Downgrade required Flex version. We previously required at least flex-2.6.0; we can now build against flex-2.5.37.
Improve C++ caching during JIT.
We improved caching behavior via
HILTI_CXX_COMPILER_LAUNCHERif the configuration ofspicycwas changed without changing the C++ file produced during JIT.hilti::rt::isDebugVersionhas been removed.The
-O | --optimizeflag has been removed from command line tools.This was already a no-op without observable side-effects.
GH-1311: Reject use of
context()unit method if unit does not declare a context with%context.GH-1319: Unsupported unit variable attributes are now rejected.
GH-1299: Add validator for bitfield field ranges.
We now reject uses of
selfas an ID.GH-1233: Reject key types for maps that can’t be sorted.
Fix validator for field
&defaultexpression types for constness.When checking types of field
&defaultexpressions we previously would also consider their constness. This breaks e.g., cases where the used expression is not a LHS like the field the&defaultis defined for,type X = unit { var x: bytes = b"" + a; };
We now do not consider constness in the type check anymore. Since fields are never const this allows us to set a
&defaultwith constant expressions as well.
Bug fixes
GH-1231: Add special handling for potential
advancefailure in trial mode.GH-1115, GH-1196: Explicitly type temporary value used by
&max_sizelogic.GH-1143, GH-1220: Add coercion on assignment for optionals that only differ in constness of their inner types.
GH-1230: Add coercion to default argument of
map::get.GH-1234, GH-1238: Fix assertions with anonymous struct constructor.
GH-1248: Fix
stopfor unbounded loop.GH-1250: Fix internal errors when seeing unsupported character classes in regular expression.
GH-1170: Fix contexts not allowing being passed
inout.GH-1266: Fix wrong type for Spicy-side
selfexpression.GH-1261: Fix inability to access unit fields through
selfin&convertexpressions.GH-1267: Install only needed headers from bundled SafeInt library.
GH-1227: Fix code generation when a module’s file could be imported through different means.
GH-1273: Remove bundled code licensed under CPOL license.
GH-1303: Fix potentially late synchronization when jumping over gaps during synchronization.
Do not force gold linker with user-provided linker flags or when built as a CMake subproject.
Improve efficiency of
startsWithfor long inputs.
Documentation
The documentation now reflects Zeek package manager Spicy feature templates.
The documentation for bitfields was clarified.
Documentation for casts from integers to boolean was added.
We added documentation for how to expose custom C++ code in Spicy.
Update doc link to commits mailing list.
Clarify that
%contextcan only be used in top-level units.Clarify that
&untilconsumes the delimiter.GH-1240: Clarify docs on
SPICY_VERSION.Add FAQ item on source locations.
Add example for use of
?..
9.4. Version 1.5
New Functionality
GH-1179: Cap parallelism use for JIT background jobs.
During JIT, we would previously launch all compilation jobs in parallel. For projects using many modules this could have lead to resource contention which often forced users to use sequential compilation with
HILTI_JIT_SEQUENTIAL. We now by default cap the number of parallel background jobs at the number of logical cores. This can be parameterized with the environment variableHILTI_JIT_PARALLELISMwhich forHILTI_JIT_PARALLELISM=1reproducesHILTI_JIT_SEQUENTIAL.GH-1134: Add support for
synchronize-atandsynchronize-afterproperties.These unit properties allow specifying a literal which should be searched for during error recovery. If the respective unit is used as a synchronize point during error recovery, i.e., it is used as a field which is marked
&synchronize, input resynchronization during error recovery will seek to the next position of this pattern in the input stream.GH-1209: Provide error message to
%errorhandler.We now allow to optionally provide a string parameter with
%errorthat will receive the associated error message:on %error(msg: string) { print msg; }
Changed Functionality
GH-1184: Allow more cache hits if only a few modules are changed in multi-module compilation.
GH-1208: Incremental performance tweaks for JIT.
GH-1197: Make handling of sanitizer workarounds more granular.
Bug fixes
GH-1150: Preserve additional permissions from umask when generating HLTO files.
GH-1154: Add stringificaton of
Map::value_type.GH-1080: Reject constant declarations at non-global scope.
GH-1164: Make compiler plugin initialization explicit.
GH-1050: Update location when entering most parser methods.
GH-1187: Fix support for having multiple source modules of the same name.
GH-1197: Prevent too early integer overflow in pow.
GH-1201: Adjust removal of symlinks on install for
DESTDIR.GH-1203: Allow changing
DESTDIRbetween configure and install time.GH-1204: Remove potential use-after-move.
GH-1210: Prevent unnecessarily executable stack with GNU toolchain.
GH-1206: Fix detection of recursive dependencies.
GH-1217: Produce
hilti::rt::Boolwhen casting to boolean.GH-1224: Fix import segfault.
Documentation
GH-44: Update docs for spicy-plugin rename
_Zeek::Spicy->Zeek::Spicy.GH-1183: Update docs for Discourse migration [skip CI].
GH-1205: Update Spicy docs for now being built into Zeek.
9.5. Version 1.4
New Functionality
Add support for recovery from parse errors or incomplete input
This release adds support for recovering from parse errors or incomplete input (e.g., gaps or partial connections). Grammars can denote unit synchronization points with a
&synchronizeattribute. If an error is encountered while extracting a previous fields, parsing will attempt to resynchronize the input at that point. The synchronization result needs to be checked and confirmed or rejected explicitly; a number of hooks are provided for that. See the docs for details.Remove restriction that units used as sinks need to be
publicUses
ccachefor C++ compilation during JIT if Spicy itself was configured to useccache
Spicy spends a considerable amount of JIT time compiling generated C++ code. This work can be cached if neither inputs nor any of the used flags have changed so that subsequent JIT runs can complete much faster.
We now automatically cache many C++ compilation artifacts with
ccacheif Spicy itself was configured with e.g.,--with-hilti-compiler-launcher=ccache. This behavior can be controlled or disabled via theHILTI_CXX_COMPILER_LAUNCHERenvironment variable.
GH-842: Add Spicy support for struct initialization.
GH-1036: Support unit initialization through a struct constructor expression.
Changed Functionality
GH-1074:
%random-accessis now derived automatically from uses and declaring it explicitly has been deprecated.GH-1072: Disallow enum declarations with non-unique values.
It is unclear what code should be generated when requested to convert an integer value to the following enum:
type E = enum { A = 1, B = 2, C = 1, };
For
1we could produce eitherE::AorE::Chere.Instead of allowing this ambiguity we now disallow enums with non-unique values.
Bug fixes
Prevent exception if cache directory is not readable.
Propagate failure from
cmakeup to./configure.GH-1030: Make sure types required for globals are declared before being used.
Fix potentially use-after-free in stringification of
stream::View.GH-1087: Make
offsetreturn correct value even before parsing of field.
Documentation
9.6. Version 1.3
New Functionality
Add optimizer removing unused
%random-accessor%filterfunctionalityIf a unit has e.g., a
%random-accessattribute Spicy emits additional code to track and update offsets. If the%random-accessfunctionality is not used this leads to unneeded code being emitted which causes unneeded overhead, both during JIT and during execution.We now emit such feature-dependent code under a feature flag (effectively a global boolean constant) which is by default on. Additionally, we added an optimizer pass which detects whether a feature is used and can disable unused feature functionality (switching the feature flag to off), and can then remove unreachable code behind such disabled feature flags by performing basic constant folding.
Add optimizer pass removing unused sink functionality
By default any unit declared
publiccan be used as a sink. To support sink behavior additional code is emitted and invoked at runtime, regardless of whether the unit is used as a sink or not.We now detect unused sink functionality and avoid emitting it.
GH-934: Allow
$$in place ofselfin unit convert attributes.
Changed Functionality
GH-941: Allow use of units with all defaulted parameters as entry points.
We added precompilation support for
libspicy.h.Drop support for end-of-life Fedora 32, and add support for Fedora 34.
Bug fixes
Correctly handle lookups for NULL library symbols.
Use safe integers for
sizefunctions in the runtime library.Make it possible to build on ARM64.
Fix building with gcc-11.
Documentation
9.7. Version 1.2
New Functionality
GH-913: Add support for switch-level
&parse-atand&parse-fromattributes inside a unit.Add optimizer pass removing unimplemented functions and methods.
This introduces a global pass triggered after all individual input ASTs have been finalized, but before we generate any C++ code. We then strip out any unimplemented member functions (typically Spicy hooks), both their definitions as well as their uses.
In order to correctly handle previously generated C++ files which might have been generated with different optimization settings, we disallow optimizations if we detect that a C++ input file was generated by us.
Changed Functionality
Add validation of unit switch attributes. We previously silently ignored unsupported attributes; now errors are raised.
Remove configure option
--build-zeek-plugin. Spicy no longer supports building the Zeek plugin/analyzers in-tree. This used to be available primarily for development purposes, but became challenging to maintain.Add environment variable
HILTI_CXX_INCLUDE_DIRSto specify additional C++ include directories when compiling generated code.GH-940: Add runtime check for parsing progress during loops.
Bug fixes
Fix computation of unset locations.
Fix accidental truncating conversion in integer code.
Documentation
9.8. Version 1.1
New Functionality
GH-844: Add support for
&sizeattribute to unitswitchstatement.GH-26: Add
%skip,%skip-preand%skip-postproperties for skipping input matching a regular expression before any further input processing takes place.Extend library functionality provided by the
spicymodule:crc32_init()/crc32_add()compute CRC32 checksums.mktime()creates atimevalue from individual components.zlib_init()initializes aZlibStreamwith a given window bits argument.Zlibnow accepts a window bits parameter.
Add a new
find()method to units for that searches for abytessequence inside their input data, forward or backward from a given starting position.Add support for
&chunkedwhen parsing bytes data with&untilor&until_including.Add
encode()method tostringfor conversion tobytes.Extend parsing of
voidfields:Add support for
&eodto skip all data until the end of the current input is encountered.Add support for
&untilto skip all data until a deliminator is encountered. The deliminator will be extracted from the stream before continuing.
Port Spicy to Apple silicon.
Add Dockerfile for OpenSUSE 15.2.
Changed Functionality
Reject
voidfields with names.Lower minimum required Python version to 3.2.
GH-882: Lower minimum required Bison version to 3.0.
Bug fixes
GH-872: Fix missing normalization of enum label IDs.
GH-878: Fix casting integers to enums.
GH-889: Fix hook handling for anonymous void fields.
GH-901: Fix type resolution bug in
&convert.Fix handling of
&sizeattribute for anonymous void fields.Fix missing update to input position before running
%donehook.Add validation rejecting
$$in hooks not supporting it.Make sure container sizes are runtime integers.
Fix missing operator<< for enums when generating debug code.
GH-917: Default-initialize forwarding fields without type arguments.
Documentation
GH-37: Add documentation on how to skip data with
voidfields.
9.9. Migrating from the old prototype
Below we summarize language changes in Spicy compared to the original research prototype. Note that some of the prototype’s more advanced functionality has not yet been ported to the new code base; see the corresponding list on GitHub for what’s still missing.
Changes:
Renamed
exportlinkage topublic.Renamed
%byteorderproperty to%byte-order.Renamed
&byteorderattribute to&byte-order.Renamed
&bitorderattribute to&bit-order.All unit-level properties now need to conclude with a semicolon (e.g.,
%filter;).Renamed
&lengthattribute to&size.Renamed
&until_includingattribute to&until-including.Replaced
&parsewith separate&parse-from(taking a “bytes” instance) and&parse-at(taking a stream iterator) attributes.Attributes no longer accept their arguments in parentheses, it now must
<attr>=expr. (Before, both versions were accepted.)uint<N>andint<N>are no longer accepted, useuintN/intNinstead (which worked before already as well)list<T>is no longer supported, usevector<T>instead.New syntax for parsing sequences: Use
x: int8[5]instead ofx: vector<int8> &length=5. For lists of unknown size, usex: int8[]. When parsing sequences sub-units, use:x: Item[]; or, if further arguments/attributes are required,x: (Item(1,2,3))[]. (The latter syntax isn’t great, but the old syntax was ambiguous.)New syntax for functions:
function f(<params>) [: <result>]instead of<result> f(<params>)Renamed runtime support module from
Spicytospicy(so useimport spicy)In units, variables are now initialized to default values by default. Previously, that was (inconsistently) happening only for variables of type sink. To revert to the old behaviour, add “&optional” to the variable.
Renamed type
doubletoreal.Generally, types don’t coerce implicitly to bool anymore except in specific language contexts, such as in statements with boolean conditions.
Filters can now be implemented in Spicy itself. The pre-built
filter::Base64Decodeandfilter::Zlibprovide the base64 and zlib functionality of the previously built-in filters.{unit,sink}::add_filterare renamed to{unit,sink}::connect_filter.Enums don’t coerce to bool anymore, need to manually compare to
Undef.Coercion to bool now happens only in certain contexts, like
if-conditions (similar to C++).The sink method
sequencehas been renamed tosequence_number.The effect of the sink method
set_initial_sequence_numberno longer persists when reconnecting a different unit to a sink.&transientis no longer a supported unit field attribute. The same effect can now be achieved through an anonymous field (also see next point).$$can now be generally used in hooks to refer to the just parsed value. That’s particularly useful inside hooks for anonymous fields, including fields that previously were&transient(see above). Previously, “$$” worked only for container elements inforeachhooks (which still operates the same way).Fields of type
realare parsed with&typeattribute (e.g.,&type=Spicy::RealType::IEEE754_Double). They used to&precisionattributes with a different enum type.Assigning to unit fields and variables no longer triggers any hooks. That also means that hooks are generally no longer supported for variables (This is tricky to implement, not clear it’s worth the effort.)
When importing modules, module names are now case-sensitive.
When parsing vectors/lists of integers of a given length, use
&countinstead of&length.Zeek plugin:
Bro::dpd_confirm()has been renamed tozeek::confirm_protocol(). There’s also a correspondingzeek::reject_protocol().To auto-export enums to Zeek, they need to be declared public.