From 2024f2753484f7ec417ef6f9ce56940f3709ca9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=A4rkl?= Date: Thu, 4 Nov 2021 18:44:02 +0100 Subject: [PATCH 1/2] Make SubtreeInlineData work on Big-Endian --- lib/src/host.h | 21 +++++++++++++++++ lib/src/subtree.h | 60 +++++++++++++++++++++++++++++++++++++---------- 2 files changed, 69 insertions(+), 12 deletions(-) create mode 100644 lib/src/host.h diff --git a/lib/src/host.h b/lib/src/host.h new file mode 100644 index 00000000..a07e9f89 --- /dev/null +++ b/lib/src/host.h @@ -0,0 +1,21 @@ + +// Determine endian and pointer size based on known defines. +// TS_BIG_ENDIAN and TS_PTR_SIZE can be set as -D compiler arguments +// to override this. + +#if !defined(TS_BIG_ENDIAN) +#if (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) \ + || (defined( __APPLE_CC__) && (defined(__ppc__) || defined(__ppc64__))) +#define TS_BIG_ENDIAN 1 +#else +#define TS_BIG_ENDIAN 0 +#endif +#endif + +#if !defined(TS_PTR_SIZE) +#if UINTPTR_MAX == 0xFFFFFFFF +#define TS_PTR_SIZE 32 +#else +#define TS_PTR_SIZE 64 +#endif +#endif diff --git a/lib/src/subtree.h b/lib/src/subtree.h index 97dee5ea..bfbdbc41 100644 --- a/lib/src/subtree.h +++ b/lib/src/subtree.h @@ -11,6 +11,7 @@ extern "C" { #include "./length.h" #include "./array.h" #include "./error_costs.h" +#include "./host.h" #include "tree_sitter/api.h" #include "tree_sitter/parser.h" @@ -39,21 +40,56 @@ typedef struct { // // This representation is used for small leaf nodes that are not // errors, and were not created by an external scanner. +// The idea behind the layout of this struct is that the `is_inline` +// bit will fall exactly into the same location as the least significant +// bit of the pointer in `Subtree` or `MutableSubtree`, respectively. +// Because of alignment, for any valid pointer this will be 0, giving +// us the opportunity to make use of this bit to signify whether to use +// the pointer or the inline struct. typedef struct { - bool is_inline : 1; - bool visible : 1; - bool named : 1; - bool extra : 1; - bool has_changes : 1; - bool is_missing : 1; +#define SUBTREE_3_BYTES \ + uint8_t symbol; \ + uint8_t padding_bytes; \ + uint8_t size_bytes; \ + +#define SUBTREE_6_BITS \ + bool visible : 1; \ + bool named : 1; \ + bool extra : 1; \ + bool has_changes : 1; \ + bool is_missing : 1; \ bool is_keyword : 1; - uint8_t symbol; - uint8_t padding_bytes; - uint8_t size_bytes; - uint8_t padding_columns; - uint8_t padding_rows : 4; - uint8_t lookahead_bytes : 4; + +#define SUBTREE_4_BYTES \ + uint8_t padding_columns; \ + uint8_t padding_rows : 4; \ + uint8_t lookahead_bytes : 4; \ uint16_t parse_state; + +#if TS_BIG_ENDIAN +#if TS_PTR_SIZE == 32 + SUBTREE_3_BYTES + SUBTREE_6_BITS + bool unused : 1; + bool is_inline : 1; + SUBTREE_4_BYTES +#else + SUBTREE_4_BYTES + SUBTREE_3_BYTES + SUBTREE_6_BITS + bool unused : 1; + bool is_inline : 1; +#endif +#else + bool is_inline : 1; + SUBTREE_6_BITS + SUBTREE_3_BYTES + SUBTREE_4_BYTES +#endif + +#undef SUBTREE_3_BYTES +#undef SUBTREE_6_BITS +#undef SUBTREE_4_BYTES } SubtreeInlineData; // A heap-allocated representation of a subtree. From d5d99e0bfb552dd2e8b32ef7918c13d208aa8075 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=A4rkl?= Date: Fri, 24 Dec 2021 17:07:32 +0100 Subject: [PATCH 2/2] Address feedback --- lib/src/subtree.h | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/lib/src/subtree.h b/lib/src/subtree.h index bfbdbc41..992d31c5 100644 --- a/lib/src/subtree.h +++ b/lib/src/subtree.h @@ -49,10 +49,9 @@ typedef struct { typedef struct { #define SUBTREE_3_BYTES \ uint8_t symbol; \ - uint8_t padding_bytes; \ - uint8_t size_bytes; \ + uint16_t parse_state; -#define SUBTREE_6_BITS \ +#define SUBTREE_BITS \ bool visible : 1; \ bool named : 1; \ bool extra : 1; \ @@ -60,36 +59,39 @@ typedef struct { bool is_missing : 1; \ bool is_keyword : 1; -#define SUBTREE_4_BYTES \ +#define SUBTREE_SIZE \ uint8_t padding_columns; \ uint8_t padding_rows : 4; \ uint8_t lookahead_bytes : 4; \ - uint16_t parse_state; + uint8_t padding_bytes; \ + uint8_t size_bytes; #if TS_BIG_ENDIAN #if TS_PTR_SIZE == 32 - SUBTREE_3_BYTES - SUBTREE_6_BITS + uint16_t parse_state; + uint8_t symbol; + SUBTREE_BITS bool unused : 1; bool is_inline : 1; - SUBTREE_4_BYTES + SUBTREE_SIZE #else - SUBTREE_4_BYTES - SUBTREE_3_BYTES - SUBTREE_6_BITS + SUBTREE_SIZE + uint16_t parse_state; + uint8_t symbol; + SUBTREE_BITS bool unused : 1; bool is_inline : 1; #endif #else bool is_inline : 1; - SUBTREE_6_BITS - SUBTREE_3_BYTES - SUBTREE_4_BYTES + SUBTREE_BITS + uint8_t symbol; + uint16_t parse_state; + SUBTREE_SIZE #endif -#undef SUBTREE_3_BYTES -#undef SUBTREE_6_BITS -#undef SUBTREE_4_BYTES +#undef SUBTREE_BITS +#undef SUBTREE_SIZE } SubtreeInlineData; // A heap-allocated representation of a subtree.