mirror of
https://github.com/ruby/ruby.git
synced 2026-10-28 16:36:20 +08:00
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
35 lines
1006 B
C
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
|