Files
Kevin Newton ae6ef1bfb5 [ruby/prism] Add checksum
CRuby is now hashing the contents of a file and attaching that to
iseqs in order to properly determine if a file has changed since
it was compiled. This is used in a couple places, but namely it is
used for error_highlight to make sure it isn't highlighting stale
locations.

The hashing algorithm doesn't actually matter since it's just used
to compare across parses, so as long as it is consistent it's okay.
I wanted something fast and standard, so this commit implements the
XXH3_64 algorithm from the spec. Noteably it uses the default
secret and a seed of 0 to make things even simpler. With NEON and
SSE2 implementations, this thing flies quite a bit faster than the
upstream FNV-1a implementation.

I figured this could be useful for other consumers as well, in
particular for tools that generate some kind of metadata around
files (type checkers, linters, etc). Eventually a nice extension
may be to hash a minimal version of the contents (i.e., with
context-insensitive whitespace removed) so that changes to docs or
indentation do not change the hash value.

If you're using the C API, you are only charged for this function
if you actually call it since it is computed lazily. For everyone
else it is automatically called, but truthfully it is so fast that
the difference is completely negligible.

https://github.com/ruby/prism/commit/6b7c5773eb
2026-10-19 17:30:05 -04:00

35 lines
1006 B
C

/**
* @file compiler/endianness.h
*/
#ifndef PRISM_COMPILER_ENDIANNESS_H
#define PRISM_COMPILER_ENDIANNESS_H
/**
* Detect endianness at compile-time through the use of predefined macros.
*/
#if defined(_WIN32) || defined(__LITTLE_ENDIAN__) || (defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
#define PRISM_LITTLE_ENDIAN_COMPTIME
#endif
/**
* Determine endianness at runtime, either through predefined macros or through
* a runtime check that is usually folded.
*/
#if defined(PRISM_LITTLE_ENDIAN_COMPTIME)
#define PRISM_LITTLE_ENDIAN_RUNTIME 1
#elif defined(__BIG_ENDIAN__) || (defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
#define PRISM_LITTLE_ENDIAN_RUNTIME 0
#else
#include <stdint.h>
static inline int
pm_little_endian(void) {
const union { uint32_t u; uint8_t c[4]; } one = { 1 };
return one.c[0];
}
#define PRISM_LITTLE_ENDIAN_RUNTIME pm_little_endian()
#endif
#endif