Rizin
unix-like reverse engineering framework and cli tools
stack.c File Reference
#include "./alloc.h"
#include "./language.h"
#include "./subtree.h"
#include "./array.h"
#include "./stack.h"
#include "./length.h"
#include <assert.h>
#include <stdio.h>

Go to the source code of this file.

Classes

struct  StackLink
 
struct  StackNode
 
struct  StackIterator
 
struct  StackHead
 
struct  Stack
 
struct  SummarizeStackSession
 

Macros

#define MAX_LINK_COUNT   8
 
#define MAX_NODE_POOL_SIZE   50
 
#define MAX_ITERATOR_COUNT   64
 
#define inline   static inline __attribute__((always_inline))
 

Typedefs

typedef struct StackNode StackNode
 
typedef unsigned StackAction
 
typedef StackAction(* StackCallback) (void *, const StackIterator *)
 

Enumerations

enum  { StackActionNone , StackActionStop = 1 , StackActionPop = 2 }
 

Functions

typedef Array (StackNode *)
 
static void stack_node_retain (StackNode *self)
 
static void stack_node_release (StackNode *self, StackNodeArray *pool, SubtreePool *subtree_pool)
 
static StackNodestack_node_new (StackNode *previous_node, Subtree subtree, bool is_pending, TSStateId state, StackNodeArray *pool)
 
static bool stack__subtree_is_equivalent (Subtree left, Subtree right)
 
static void stack_node_add_link (StackNode *self, StackLink link, SubtreePool *subtree_pool)
 
static void stack_head_delete (StackHead *self, StackNodeArray *pool, SubtreePool *subtree_pool)
 
static StackVersion ts_stack__add_version (Stack *self, StackVersion original_version, StackNode *node)
 
static void ts_stack__add_slice (Stack *self, StackVersion original_version, StackNode *node, SubtreeArray *subtrees)
 
StackSliceArray stack__iter (Stack *self, StackVersion version, StackCallback callback, void *payload, int goal_subtree_count)
 
Stackts_stack_new (SubtreePool *subtree_pool)
 
void ts_stack_delete (Stack *self)
 
uint32_t ts_stack_version_count (const Stack *self)
 
TSStateId ts_stack_state (const Stack *self, StackVersion version)
 
Length ts_stack_position (const Stack *self, StackVersion version)
 
Subtree ts_stack_last_external_token (const Stack *self, StackVersion version)
 
void ts_stack_set_last_external_token (Stack *self, StackVersion version, Subtree token)
 
unsigned ts_stack_error_cost (const Stack *self, StackVersion version)
 
unsigned ts_stack_node_count_since_error (const Stack *self, StackVersion version)
 
void ts_stack_push (Stack *self, StackVersion version, Subtree subtree, bool pending, TSStateId state)
 
StackAction pop_count_callback (void *payload, const StackIterator *iterator)
 
StackSliceArray ts_stack_pop_count (Stack *self, StackVersion version, uint32_t count)
 
StackAction pop_pending_callback (void *payload, const StackIterator *iterator)
 
StackSliceArray ts_stack_pop_pending (Stack *self, StackVersion version)
 
StackAction pop_error_callback (void *payload, const StackIterator *iterator)
 
SubtreeArray ts_stack_pop_error (Stack *self, StackVersion version)
 
StackAction pop_all_callback (void *payload, const StackIterator *iterator)
 
StackSliceArray ts_stack_pop_all (Stack *self, StackVersion version)
 
StackAction summarize_stack_callback (void *payload, const StackIterator *iterator)
 
void ts_stack_record_summary (Stack *self, StackVersion version, unsigned max_depth)
 
StackSummary * ts_stack_get_summary (Stack *self, StackVersion version)
 
int ts_stack_dynamic_precedence (Stack *self, StackVersion version)
 
bool ts_stack_has_advanced_since_error (const Stack *self, StackVersion version)
 
void ts_stack_remove_version (Stack *self, StackVersion version)
 
void ts_stack_renumber_version (Stack *self, StackVersion v1, StackVersion v2)
 
void ts_stack_swap_versions (Stack *self, StackVersion v1, StackVersion v2)
 
StackVersion ts_stack_copy_version (Stack *self, StackVersion version)
 
bool ts_stack_merge (Stack *self, StackVersion version1, StackVersion version2)
 
bool ts_stack_can_merge (Stack *self, StackVersion version1, StackVersion version2)
 
void ts_stack_halt (Stack *self, StackVersion version)
 
void ts_stack_pause (Stack *self, StackVersion version, Subtree lookahead)
 
bool ts_stack_is_active (const Stack *self, StackVersion version)
 
bool ts_stack_is_halted (const Stack *self, StackVersion version)
 
bool ts_stack_is_paused (const Stack *self, StackVersion version)
 
Subtree ts_stack_resume (Stack *self, StackVersion version)
 
void ts_stack_clear (Stack *self)
 
bool ts_stack_print_dot_graph (Stack *self, const TSLanguage *language, FILE *f)
 

Variables

 StackStatus
 

Macro Definition Documentation

◆ inline

#define inline   static inline __attribute__((always_inline))

Definition at line 17 of file stack.c.

◆ MAX_ITERATOR_COUNT

#define MAX_ITERATOR_COUNT   64

Definition at line 12 of file stack.c.

◆ MAX_LINK_COUNT

#define MAX_LINK_COUNT   8

Definition at line 10 of file stack.c.

◆ MAX_NODE_POOL_SIZE

#define MAX_NODE_POOL_SIZE   50

Definition at line 11 of file stack.c.

Typedef Documentation

◆ StackAction

Definition at line 72 of file stack.c.

◆ StackCallback

typedef StackAction(* StackCallback) (void *, const StackIterator *)

Definition at line 79 of file stack.c.

◆ StackNode

typedef struct StackNode StackNode

Definition at line 1 of file stack.c.

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
StackActionNone 
StackActionStop 
StackActionPop 

Definition at line 73 of file stack.c.

73  {
75  StackActionStop = 1,
76  StackActionPop = 2,
77 };
@ StackActionNone
Definition: stack.c:74
@ StackActionPop
Definition: stack.c:76
@ StackActionStop
Definition: stack.c:75

Function Documentation

◆ Array()

typedef Array ( StackNode )

Definition at line 46 of file stack.c.

48  {
49  StackStatusActive,
50  StackStatusPaused,
51  StackStatusHalted,
52 } StackStatus;
StackStatus
Definition: stack.c:52

Referenced by ts_stack_print_dot_graph().

◆ pop_all_callback()

StackAction pop_all_callback ( void *  payload,
const StackIterator iterator 
)
inline

Definition at line 564 of file stack.c.

564  {
565  (void)payload;
566  return iterator->node->link_count == 0 ? StackActionPop : StackActionNone;
567 }
const MCPhysReg * iterator

References StackActionNone, and StackActionPop.

Referenced by ts_stack_pop_all().

◆ pop_count_callback()

StackAction pop_count_callback ( void *  payload,
const StackIterator iterator 
)
inline

Definition at line 498 of file stack.c.

498  {
499  unsigned *goal_subtree_count = payload;
500  if (iterator->subtree_count == *goal_subtree_count) {
502  } else {
503  return StackActionNone;
504  }
505 }

References StackActionNone, StackActionPop, and StackActionStop.

Referenced by ts_stack_pop_count().

◆ pop_error_callback()

StackAction pop_error_callback ( void *  payload,
const StackIterator iterator 
)
inline

Definition at line 533 of file stack.c.

533  {
534  if (iterator->subtrees.size > 0) {
535  bool *found_error = payload;
536  if (!*found_error && ts_subtree_is_error(iterator->subtrees.contents[0])) {
537  *found_error = true;
539  } else {
540  return StackActionStop;
541  }
542  } else {
543  return StackActionNone;
544  }
545 }
static bool ts_subtree_is_error(Subtree self)
Definition: subtree.h:342

References StackActionNone, StackActionPop, StackActionStop, and ts_subtree_is_error().

Referenced by ts_stack_pop_error().

◆ pop_pending_callback()

StackAction pop_pending_callback ( void *  payload,
const StackIterator iterator 
)
inline

Definition at line 511 of file stack.c.

511  {
512  (void)payload;
513  if (iterator->subtree_count >= 1) {
514  if (iterator->is_pending) {
516  } else {
517  return StackActionStop;
518  }
519  } else {
520  return StackActionNone;
521  }
522 }

References StackActionNone, StackActionPop, and StackActionStop.

Referenced by ts_stack_pop_pending().

◆ stack__iter()

StackSliceArray stack__iter ( Stack self,
StackVersion  version,
StackCallback  callback,
void *  payload,
int  goal_subtree_count 
)
inline

Definition at line 308 of file stack.c.

314  {
315  array_clear(&self->slices);
316  array_clear(&self->iterators);
317 
318  StackHead *head = array_get(&self->heads, version);
320  .node = head->node,
321  .subtrees = array_new(),
322  .subtree_count = 0,
323  .is_pending = true,
324  };
325 
326  bool include_subtrees = false;
327  if (goal_subtree_count >= 0) {
328  include_subtrees = true;
329  array_reserve(&iterator.subtrees, ts_subtree_alloc_size(goal_subtree_count) / sizeof(Subtree));
330  }
331 
332  array_push(&self->iterators, iterator);
333 
334  while (self->iterators.size > 0) {
335  for (uint32_t i = 0, size = self->iterators.size; i < size; i++) {
336  StackIterator *iterator = &self->iterators.contents[i];
337  StackNode *node = iterator->node;
338 
339  StackAction action = callback(payload, iterator);
340  bool should_pop = action & StackActionPop;
341  bool should_stop = action & StackActionStop || node->link_count == 0;
342 
343  if (should_pop) {
344  SubtreeArray subtrees = iterator->subtrees;
345  if (!should_stop) {
346  ts_subtree_array_copy(subtrees, &subtrees);
347  }
348  ts_subtree_array_reverse(&subtrees);
350  self,
351  version,
352  node,
353  &subtrees
354  );
355  }
356 
357  if (should_stop) {
358  if (!should_pop) {
359  ts_subtree_array_delete(self->subtree_pool, &iterator->subtrees);
360  }
361  array_erase(&self->iterators, i);
362  i--, size--;
363  continue;
364  }
365 
366  for (uint32_t j = 1; j <= node->link_count; j++) {
367  StackIterator *next_iterator;
368  StackLink link;
369  if (j == node->link_count) {
370  link = node->links[0];
371  next_iterator = &self->iterators.contents[i];
372  } else {
373  if (self->iterators.size >= MAX_ITERATOR_COUNT) continue;
374  link = node->links[j];
375  StackIterator current_iterator = self->iterators.contents[i];
376  array_push(&self->iterators, current_iterator);
377  next_iterator = array_back(&self->iterators);
378  ts_subtree_array_copy(next_iterator->subtrees, &next_iterator->subtrees);
379  }
380 
381  next_iterator->node = link.node;
382  if (link.subtree.ptr) {
383  if (include_subtrees) {
384  array_push(&next_iterator->subtrees, link.subtree);
385  ts_subtree_retain(link.subtree);
386  }
387 
388  if (!ts_subtree_extra(link.subtree)) {
389  next_iterator->subtree_count++;
390  if (!link.is_pending) {
391  next_iterator->is_pending = false;
392  }
393  }
394  } else {
395  next_iterator->subtree_count++;
396  next_iterator->is_pending = false;
397  }
398  }
399  }
400  }
401 
402  return self->slices;
403 }
lzma_index ** i
Definition: index.h:629
#define array_new()
Definition: array.h:25
#define array_erase(self, index)
Definition: array.h:79
#define array_get(self, index)
Definition: array.h:28
#define array_back(self)
Definition: array.h:33
#define array_push(self, element)
Definition: array.h:43
#define array_reserve(self, new_capacity)
Definition: array.h:37
#define array_clear(self)
Definition: array.h:35
static static fork const void static count static fd link
Definition: sflib.h:33
voidpf void uLong size
Definition: ioapi.h:138
unsigned int uint32_t
Definition: sftypes.h:29
uint32_t subtree_count
Definition: stack.c:42
StackNode * node
Definition: stack.c:40
SubtreeArray subtrees
Definition: stack.c:41
bool is_pending
Definition: stack.c:43
StackLink links[MAX_LINK_COUNT]
Definition: stack.c:31
short unsigned int link_count
Definition: stack.c:32
#define MAX_ITERATOR_COUNT
Definition: stack.c:12
static void ts_stack__add_slice(Stack *self, StackVersion original_version, StackNode *node, SubtreeArray *subtrees)
Definition: stack.c:288
unsigned StackAction
Definition: stack.c:72
void ts_subtree_array_reverse(SubtreeArray *self)
Definition: subtree.c:112
void ts_subtree_retain(Subtree self)
Definition: subtree.c:577
void ts_subtree_array_delete(SubtreePool *pool, SubtreeArray *self)
Definition: subtree.c:90
void ts_subtree_array_copy(SubtreeArray self, SubtreeArray *dest)
Definition: subtree.c:70
static size_t ts_subtree_alloc_size(uint32_t child_count)
Definition: subtree.h:227
static bool ts_subtree_extra(Subtree self)
Definition: subtree.h:216

References test-lz4-speed::action, array_back, array_clear, array_erase, array_get, array_new, array_push, array_reserve, test-lz4-versions::head, i, StackIterator::is_pending, link, StackNode::link_count, StackNode::links, MAX_ITERATOR_COUNT, StackIterator::node, StackActionPop, StackActionStop, StackIterator::subtree_count, StackIterator::subtrees, ts_stack__add_slice(), ts_subtree_alloc_size(), ts_subtree_array_copy(), ts_subtree_array_delete(), ts_subtree_array_reverse(), ts_subtree_extra(), and ts_subtree_retain().

Referenced by ts_stack_pop_all(), ts_stack_pop_count(), ts_stack_pop_error(), ts_stack_pop_pending(), and ts_stack_record_summary().

◆ stack__subtree_is_equivalent()

static bool stack__subtree_is_equivalent ( Subtree  left,
Subtree  right 
)
static

Definition at line 166 of file stack.c.

166  {
167  if (left.ptr == right.ptr) return true;
168  if (!left.ptr || !right.ptr) return false;
169 
170  // Symbols must match
171  if (ts_subtree_symbol(left) != ts_subtree_symbol(right)) return false;
172 
173  // If both have errors, don't bother keeping both.
174  if (ts_subtree_error_cost(left) > 0 && ts_subtree_error_cost(right) > 0) return true;
175 
176  return (
178  ts_subtree_size(left).bytes == ts_subtree_size(right).bytes &&
180  ts_subtree_extra(left) == ts_subtree_extra(right) &&
182  );
183 }
static ut8 bytes[32]
Definition: asm_arc.c:23
bool ts_subtree_external_scanner_state_eq(Subtree self, Subtree other)
Definition: subtree.c:1027
static uint32_t ts_subtree_error_cost(Subtree self)
Definition: subtree.h:302
static Length ts_subtree_size(Subtree self)
Definition: subtree.h:265
static uint32_t ts_subtree_child_count(Subtree self)
Definition: subtree.h:282
static Length ts_subtree_padding(Subtree self)
Definition: subtree.h:256
static TSSymbol ts_subtree_symbol(Subtree self)
Definition: subtree.h:213
const SubtreeHeapData * ptr
Definition: subtree.h:158

References bytes, Subtree::ptr, ts_subtree_child_count(), ts_subtree_error_cost(), ts_subtree_external_scanner_state_eq(), ts_subtree_extra(), ts_subtree_padding(), ts_subtree_size(), and ts_subtree_symbol().

Referenced by stack_node_add_link().

◆ stack_head_delete()

static void stack_head_delete ( StackHead self,
StackNodeArray *  pool,
SubtreePool subtree_pool 
)
static

Definition at line 250 of file stack.c.

254  {
255  if (self->node) {
256  if (self->last_external_token.ptr) {
257  ts_subtree_release(subtree_pool, self->last_external_token);
258  }
259  if (self->lookahead_when_paused.ptr) {
260  ts_subtree_release(subtree_pool, self->lookahead_when_paused);
261  }
262  if (self->summary) {
263  array_delete(self->summary);
264  ts_free(self->summary);
265  }
266  stack_node_release(self->node, pool, subtree_pool);
267  }
268 }
#define ts_free
Definition: alloc.h:30
#define array_delete(self)
Definition: array.h:41
Subtree last_external_token
Definition: stack.c:58
StackNode * node
Definition: stack.c:55
Subtree lookahead_when_paused
Definition: stack.c:59
StackSummary * summary
Definition: stack.c:56
static void stack_node_release(StackNode *self, StackNodeArray *pool, SubtreePool *subtree_pool)
Definition: stack.c:89
void ts_subtree_release(SubtreePool *pool, Subtree self)
Definition: subtree.c:584

References array_delete, stack_node_release(), ts_free, and ts_subtree_release().

Referenced by ts_stack_clear(), ts_stack_delete(), ts_stack_remove_version(), and ts_stack_renumber_version().

◆ stack_node_add_link()

static void stack_node_add_link ( StackNode self,
StackLink  link,
SubtreePool subtree_pool 
)
static

Definition at line 185 of file stack.c.

189  {
190  if (link.node == self) return;
191 
192  for (int i = 0; i < self->link_count; i++) {
193  StackLink *existing_link = &self->links[i];
194  if (stack__subtree_is_equivalent(existing_link->subtree, link.subtree)) {
195  // In general, we preserve ambiguities until they are removed from the stack
196  // during a pop operation where multiple paths lead to the same node. But in
197  // the special case where two links directly connect the same pair of nodes,
198  // we can safely remove the ambiguity ahead of time without changing behavior.
199  if (existing_link->node == link.node) {
200  if (
202  ts_subtree_dynamic_precedence(existing_link->subtree)
203  ) {
204  ts_subtree_retain(link.subtree);
205  ts_subtree_release(subtree_pool, existing_link->subtree);
206  existing_link->subtree = link.subtree;
207  self->dynamic_precedence =
208  link.node->dynamic_precedence + ts_subtree_dynamic_precedence(link.subtree);
209  }
210  return;
211  }
212 
213  // If the previous nodes are mergeable, merge them recursively.
214  if (
215  existing_link->node->state == link.node->state &&
216  existing_link->node->position.bytes == link.node->position.bytes
217  ) {
218  for (int j = 0; j < link.node->link_count; j++) {
219  stack_node_add_link(existing_link->node, link.node->links[j], subtree_pool);
220  }
221  int32_t dynamic_precedence = link.node->dynamic_precedence;
222  if (link.subtree.ptr) {
223  dynamic_precedence += ts_subtree_dynamic_precedence(link.subtree);
224  }
225  if (dynamic_precedence > self->dynamic_precedence) {
226  self->dynamic_precedence = dynamic_precedence;
227  }
228  return;
229  }
230  }
231  }
232 
233  if (self->link_count == MAX_LINK_COUNT) return;
234 
235  stack_node_retain(link.node);
236  unsigned node_count = link.node->node_count;
237  int dynamic_precedence = link.node->dynamic_precedence;
238  self->links[self->link_count++] = link;
239 
240  if (link.subtree.ptr) {
241  ts_subtree_retain(link.subtree);
242  node_count += ts_subtree_node_count(link.subtree);
243  dynamic_precedence += ts_subtree_dynamic_precedence(link.subtree);
244  }
245 
246  if (node_count > self->node_count) self->node_count = node_count;
247  if (dynamic_precedence > self->dynamic_precedence) self->dynamic_precedence = dynamic_precedence;
248 }
int int32_t
Definition: sftypes.h:33
uint32_t bytes
Definition: length.h:10
unsigned node_count
Definition: stack.c:35
TSStateId state
Definition: stack.c:29
Length position
Definition: stack.c:30
int dynamic_precedence
Definition: stack.c:36
static void stack_node_add_link(StackNode *self, StackLink link, SubtreePool *subtree_pool)
Definition: stack.c:185
static bool stack__subtree_is_equivalent(Subtree left, Subtree right)
Definition: stack.c:166
#define MAX_LINK_COUNT
Definition: stack.c:10
static void stack_node_retain(StackNode *self)
Definition: stack.c:81
static int32_t ts_subtree_dynamic_precedence(Subtree self)
Definition: subtree.h:310
static uint32_t ts_subtree_node_count(Subtree self)
Definition: subtree.h:290

References Length::bytes, i, link, MAX_LINK_COUNT, StackLink::node, StackNode::position, stack__subtree_is_equivalent(), stack_node_retain(), StackNode::state, StackLink::subtree, ts_subtree_dynamic_precedence(), ts_subtree_node_count(), ts_subtree_release(), and ts_subtree_retain().

Referenced by ts_stack_merge().

◆ stack_node_new()

static StackNode* stack_node_new ( StackNode previous_node,
Subtree  subtree,
bool  is_pending,
TSStateId  state,
StackNodeArray *  pool 
)
static

Definition at line 123 of file stack.c.

129  {
130  StackNode *node = pool->size > 0
131  ? array_pop(pool)
132  : ts_malloc(sizeof(StackNode));
133  *node = (StackNode) {
134  .ref_count = 1,
135  .link_count = 0,
136  .state = state
137  };
138 
139  if (previous_node) {
140  node->link_count = 1;
141  node->links[0] = (StackLink) {
142  .node = previous_node,
143  .subtree = subtree,
144  .is_pending = is_pending,
145  };
146 
147  node->position = previous_node->position;
148  node->error_cost = previous_node->error_cost;
149  node->dynamic_precedence = previous_node->dynamic_precedence;
150  node->node_count = previous_node->node_count;
151 
152  if (subtree.ptr) {
153  node->error_cost += ts_subtree_error_cost(subtree);
154  node->position = length_add(node->position, ts_subtree_total_size(subtree));
155  node->node_count += ts_subtree_node_count(subtree);
157  }
158  } else {
159  node->position = length_zero();
160  node->error_cost = 0;
161  }
162 
163  return node;
164 }
#define ts_malloc
Definition: alloc.h:21
#define array_pop(self)
Definition: array.h:82
static Length length_zero(void)
Definition: length.h:39
static Length length_add(Length len1, Length len2)
Definition: length.h:25
uint32_t ref_count
Definition: stack.c:33
unsigned error_cost
Definition: stack.c:34
Definition: dis.h:43
struct StackNode StackNode
Definition: stack.c:20
static Length ts_subtree_total_size(Subtree self)
Definition: subtree.h:274

References array_pop, StackNode::dynamic_precedence, StackNode::error_cost, length_add(), length_zero(), StackNode::link_count, StackNode::links, StackLink::node, StackNode::node_count, StackNode::position, Subtree::ptr, StackNode::ref_count, ts_malloc, ts_subtree_dynamic_precedence(), ts_subtree_error_cost(), ts_subtree_node_count(), and ts_subtree_total_size().

Referenced by ts_stack_new(), and ts_stack_push().

◆ stack_node_release()

static void stack_node_release ( StackNode self,
StackNodeArray *  pool,
SubtreePool subtree_pool 
)
static

Definition at line 89 of file stack.c.

93  {
94 recur:
95  assert(self->ref_count != 0);
96  self->ref_count--;
97  if (self->ref_count > 0) return;
98 
99  StackNode *first_predecessor = NULL;
100  if (self->link_count > 0) {
101  for (unsigned i = self->link_count - 1; i > 0; i--) {
102  StackLink link = self->links[i];
103  if (link.subtree.ptr) ts_subtree_release(subtree_pool, link.subtree);
104  stack_node_release(link.node, pool, subtree_pool);
105  }
106  StackLink link = self->links[0];
107  if (link.subtree.ptr) ts_subtree_release(subtree_pool, link.subtree);
108  first_predecessor = self->links[0].node;
109  }
110 
111  if (pool->size < MAX_NODE_POOL_SIZE) {
112  array_push(pool, self);
113  } else {
114  ts_free(self);
115  }
116 
117  if (first_predecessor) {
118  self = first_predecessor;
119  goto recur;
120  }
121 }
#define NULL
Definition: cris-opc.c:27
assert(limit<=UINT32_MAX/2)
#define MAX_NODE_POOL_SIZE
Definition: stack.c:11

References array_push, assert(), i, link, StackNode::links, MAX_NODE_POOL_SIZE, StackLink::node, NULL, ts_free, and ts_subtree_release().

Referenced by stack_head_delete(), and ts_stack_delete().

◆ stack_node_retain()

static void stack_node_retain ( StackNode self)
static

Definition at line 81 of file stack.c.

81  {
82  if (!self)
83  return;
84  assert(self->ref_count > 0);
85  self->ref_count++;
86  assert(self->ref_count != 0);
87 }

References assert().

Referenced by stack_node_add_link(), ts_stack__add_version(), ts_stack_clear(), and ts_stack_copy_version().

◆ summarize_stack_callback()

StackAction summarize_stack_callback ( void *  payload,
const StackIterator iterator 
)
inline

Definition at line 578 of file stack.c.

578  {
579  SummarizeStackSession *session = payload;
580  TSStateId state = iterator->node->state;
581  unsigned depth = iterator->subtree_count;
582  if (depth > session->max_depth) return StackActionStop;
583  for (unsigned i = session->summary->size - 1; i + 1 > 0; i--) {
584  StackSummaryEntry entry = session->summary->contents[i];
585  if (entry.depth < depth) break;
586  if (entry.depth == depth && entry.state == state) return StackActionNone;
587  }
588  array_push(session->summary, ((StackSummaryEntry) {
589  .position = iterator->node->position,
590  .depth = depth,
591  .state = state,
592  }));
593  return StackActionNone;
594 }
uint16_t TSStateId
Definition: parser.h:16
unsigned max_depth
Definition: stack.c:575
StackSummary * summary
Definition: stack.c:574
Definition: zipcmp.c:77

References array_push, i, SummarizeStackSession::max_depth, StackActionNone, StackActionStop, and SummarizeStackSession::summary.

Referenced by ts_stack_record_summary().

◆ ts_stack__add_slice()

static void ts_stack__add_slice ( Stack self,
StackVersion  original_version,
StackNode node,
SubtreeArray *  subtrees 
)
static

Definition at line 288 of file stack.c.

293  {
294  for (uint32_t i = self->slices.size - 1; i + 1 > 0; i--) {
295  StackVersion version = self->slices.contents[i].version;
296  if (self->heads.contents[version].node == node) {
297  StackSlice slice = {*subtrees, version};
298  array_insert(&self->slices, i + 1, slice);
299  return;
300  }
301  }
302 
303  StackVersion version = ts_stack__add_version(self, original_version, node);
304  StackSlice slice = { *subtrees, version };
305  array_push(&self->slices, slice);
306 }
#define array_insert(self, index, element)
Definition: array.h:75
unsigned StackVersion
Definition: stack.h:15
static StackVersion ts_stack__add_version(Stack *self, StackVersion original_version, StackNode *node)
Definition: stack.c:270

References array_insert, array_push, i, and ts_stack__add_version().

Referenced by stack__iter().

◆ ts_stack__add_version()

static StackVersion ts_stack__add_version ( Stack self,
StackVersion  original_version,
StackNode node 
)
static

Definition at line 270 of file stack.c.

274  {
275  StackHead head = {
276  .node = node,
277  .node_count_at_last_error = self->heads.contents[original_version].node_count_at_last_error,
278  .last_external_token = self->heads.contents[original_version].last_external_token,
279  .status = StackStatusActive,
280  .lookahead_when_paused = NULL_SUBTREE,
281  };
282  array_push(&self->heads, head);
283  stack_node_retain(node);
284  if (head.last_external_token.ptr) ts_subtree_retain(head.last_external_token);
285  return (StackVersion)(self->heads.size - 1);
286 }
#define NULL_SUBTREE
Definition: subtree.h:19

References array_push, test-lz4-versions::head, NULL_SUBTREE, stack_node_retain(), and ts_subtree_retain().

Referenced by ts_stack__add_slice().

◆ ts_stack_can_merge()

bool ts_stack_can_merge ( Stack self,
StackVersion  version1,
StackVersion  version2 
)

Definition at line 693 of file stack.c.

693  {
694  StackHead *head1 = &self->heads.contents[version1];
695  StackHead *head2 = &self->heads.contents[version2];
696  return
697  head1->status == StackStatusActive &&
698  head2->status == StackStatusActive &&
699  head1->node->state == head2->node->state &&
700  head1->node->position.bytes == head2->node->position.bytes &&
701  head1->node->error_cost == head2->node->error_cost &&
703 }
StackStatus status
Definition: stack.c:60

References Length::bytes, StackNode::error_cost, StackHead::last_external_token, StackHead::node, StackNode::position, StackNode::state, StackHead::status, and ts_subtree_external_scanner_state_eq().

Referenced by ts_parser__better_version_exists(), and ts_stack_merge().

◆ ts_stack_clear()

void ts_stack_clear ( Stack self)

Definition at line 737 of file stack.c.

737  {
738  stack_node_retain(self->base_node);
739  for (uint32_t i = 0; i < self->heads.size; i++) {
740  stack_head_delete(&self->heads.contents[i], &self->node_pool, self->subtree_pool);
741  }
742  array_clear(&self->heads);
743  array_push(&self->heads, ((StackHead) {
744  .node = self->base_node,
745  .status = StackStatusActive,
746  .last_external_token = NULL_SUBTREE,
747  .lookahead_when_paused = NULL_SUBTREE,
748  }));
749 }
static void stack_head_delete(StackHead *self, StackNodeArray *pool, SubtreePool *subtree_pool)
Definition: stack.c:250

References array_clear, array_push, i, stack_head_delete(), and stack_node_retain().

Referenced by parser__start(), parser_parse(), ts_parser_reset(), and ts_stack_new().

◆ ts_stack_copy_version()

StackVersion ts_stack_copy_version ( Stack self,
StackVersion  version 
)

Definition at line 669 of file stack.c.

669  {
670  assert(version < self->heads.size);
671  array_push(&self->heads, self->heads.contents[version]);
672  StackHead *head = array_back(&self->heads);
673  stack_node_retain(head->node);
674  if (head->last_external_token.ptr) ts_subtree_retain(head->last_external_token);
675  head->summary = NULL;
676  return self->heads.size - 1;
677 }

References array_back, array_push, assert(), test-lz4-versions::head, NULL, stack_node_retain(), and ts_subtree_retain().

Referenced by parser__recover(), parser__reduce(), and ts_parser__handle_error().

◆ ts_stack_delete()

void ts_stack_delete ( Stack self)

Definition at line 424 of file stack.c.

424  {
425  if (self->slices.contents)
426  array_delete(&self->slices);
427  if (self->iterators.contents)
428  array_delete(&self->iterators);
429  stack_node_release(self->base_node, &self->node_pool, self->subtree_pool);
430  for (uint32_t i = 0; i < self->heads.size; i++) {
431  stack_head_delete(&self->heads.contents[i], &self->node_pool, self->subtree_pool);
432  }
433  array_clear(&self->heads);
434  if (self->node_pool.contents) {
435  for (uint32_t i = 0; i < self->node_pool.size; i++)
436  ts_free(self->node_pool.contents[i]);
437  array_delete(&self->node_pool);
438  }
439  array_delete(&self->heads);
440  ts_free(self);
441 }

References array_clear, array_delete, i, stack_head_delete(), stack_node_release(), and ts_free.

Referenced by parser_destroy(), and ts_parser_delete().

◆ ts_stack_dynamic_precedence()

int ts_stack_dynamic_precedence ( Stack self,
StackVersion  version 
)

Definition at line 615 of file stack.c.

615  {
616  return array_get(&self->heads, version)->node->dynamic_precedence;
617 }

References array_get.

Referenced by ts_parser__better_version_exists(), and ts_parser__version_status().

◆ ts_stack_error_cost()

unsigned ts_stack_error_cost ( const Stack self,
StackVersion  version 
)

Definition at line 466 of file stack.c.

466  {
467  StackHead *head = array_get(&self->heads, version);
468  unsigned result = head->node->error_cost;
469  if (
470  head->status == StackStatusPaused ||
471  (head->node->state == ERROR_STATE && !head->node->links[0].subtree.ptr)) {
472  result += ERROR_COST_PER_RECOVERY;
473  }
474  return result;
475 }
#define ERROR_STATE
Definition: error_costs.h:4
#define ERROR_COST_PER_RECOVERY
Definition: error_costs.h:5

References array_get, ERROR_COST_PER_RECOVERY, ERROR_STATE, and test-lz4-versions::head.

Referenced by ts_parser__condense_stack(), ts_parser__recover(), ts_parser__version_status(), and ts_stack_print_dot_graph().

◆ ts_stack_get_summary()

StackSummary* ts_stack_get_summary ( Stack self,
StackVersion  version 
)

Definition at line 611 of file stack.c.

611  {
612  return array_get(&self->heads, version)->summary;
613 }

References array_get.

Referenced by ts_parser__recover().

◆ ts_stack_halt()

void ts_stack_halt ( Stack self,
StackVersion  version 
)

Definition at line 705 of file stack.c.

705  {
706  array_get(&self->heads, version)->status = StackStatusHalted;
707 }

References array_get.

Referenced by parser__accept(), parser__better_version_exists(), parser__handle_error(), parser__repair_error(), ts_parser__accept(), ts_parser__recover(), and ts_parser__recover_to_state().

◆ ts_stack_has_advanced_since_error()

bool ts_stack_has_advanced_since_error ( const Stack self,
StackVersion  version 
)

Definition at line 619 of file stack.c.

619  {
620  const StackHead *head = array_get(&self->heads, version);
621  const StackNode *node = head->node;
622  if (node->error_cost == 0) return true;
623  while (node) {
624  if (node->link_count > 0) {
625  Subtree subtree = node->links[0].subtree;
626  if (subtree.ptr) {
627  if (ts_subtree_total_bytes(subtree) > 0) {
628  return true;
629  } else if (
630  node->node_count > head->node_count_at_last_error &&
631  ts_subtree_error_cost(subtree) == 0
632  ) {
633  node = node->links[0].node;
634  continue;
635  }
636  }
637  }
638  break;
639  }
640  return false;
641 }
static uint32_t ts_subtree_total_bytes(Subtree self)
Definition: subtree.h:278

References array_get, StackNode::error_cost, test-lz4-versions::head, StackNode::link_count, StackNode::links, StackLink::node, StackNode::node_count, Subtree::ptr, StackLink::subtree, ts_subtree_error_cost(), and ts_subtree_total_bytes().

Referenced by ts_parser__lex().

◆ ts_stack_is_active()

bool ts_stack_is_active ( const Stack self,
StackVersion  version 
)

Definition at line 716 of file stack.c.

716  {
717  return array_get(&self->heads, version)->status == StackStatusActive;
718 }

References array_get.

Referenced by ts_parser__better_version_exists(), ts_parser__recover(), and ts_parser_parse().

◆ ts_stack_is_halted()

bool ts_stack_is_halted ( const Stack self,
StackVersion  version 
)

Definition at line 720 of file stack.c.

720  {
721  return array_get(&self->heads, version)->status == StackStatusHalted;
722 }

References array_get.

Referenced by parser__advance(), parser__better_version_exists(), parser__condense_stack(), parser_parse(), and ts_parser__condense_stack().

◆ ts_stack_is_paused()

bool ts_stack_is_paused ( const Stack self,
StackVersion  version 
)

Definition at line 724 of file stack.c.

724  {
725  return array_get(&self->heads, version)->status == StackStatusPaused;
726 }

References array_get.

Referenced by ts_parser__condense_stack(), and ts_parser__version_status().

◆ ts_stack_last_external_token()

Subtree ts_stack_last_external_token ( const Stack self,
StackVersion  version 
)

Definition at line 455 of file stack.c.

455  {
456  return array_get(&self->heads, version)->last_external_token;
457 }

References array_get.

Referenced by ts_parser__advance(), and ts_parser__lex().

◆ ts_stack_merge()

bool ts_stack_merge ( Stack self,
StackVersion  version1,
StackVersion  version2 
)

Definition at line 679 of file stack.c.

679  {
680  if (!ts_stack_can_merge(self, version1, version2)) return false;
681  StackHead *head1 = &self->heads.contents[version1];
682  StackHead *head2 = &self->heads.contents[version2];
683  for (uint32_t i = 0; i < head2->node->link_count; i++) {
684  stack_node_add_link(head1->node, head2->node->links[i], self->subtree_pool);
685  }
686  if (head1->node->state == ERROR_STATE) {
687  head1->node_count_at_last_error = head1->node->node_count;
688  }
689  ts_stack_remove_version(self, version2);
690  return true;
691 }
unsigned node_count_at_last_error
Definition: stack.c:57
bool ts_stack_can_merge(Stack *self, StackVersion version1, StackVersion version2)
Definition: stack.c:693
void ts_stack_remove_version(Stack *self, StackVersion version)
Definition: stack.c:643

References ERROR_STATE, i, StackNode::link_count, StackNode::links, StackHead::node, StackNode::node_count, StackHead::node_count_at_last_error, stack_node_add_link(), StackNode::state, ts_stack_can_merge(), and ts_stack_remove_version().

Referenced by parser__condense_stack(), parser__handle_error(), parser__reduce(), ts_parser__condense_stack(), ts_parser__do_all_potential_reductions(), ts_parser__handle_error(), and ts_parser__reduce().

◆ ts_stack_new()

Stack* ts_stack_new ( SubtreePool subtree_pool)

Definition at line 405 of file stack.c.

405  {
406  Stack *self = ts_calloc(1, sizeof(Stack));
407 
408  array_init(&self->heads);
409  array_init(&self->slices);
410  array_init(&self->iterators);
411  array_init(&self->node_pool);
412  array_reserve(&self->heads, 4);
413  array_reserve(&self->slices, 4);
414  array_reserve(&self->iterators, 4);
415  array_reserve(&self->node_pool, MAX_NODE_POOL_SIZE);
416 
417  self->subtree_pool = subtree_pool;
418  self->base_node = stack_node_new(NULL, NULL_SUBTREE, false, 1, &self->node_pool);
419  ts_stack_clear(self);
420 
421  return self;
422 }
#define ts_calloc
Definition: alloc.h:24
#define array_init(self)
Definition: array.h:22
Definition: stack.c:63
void ts_stack_clear(Stack *self)
Definition: stack.c:737
static StackNode * stack_node_new(StackNode *previous_node, Subtree subtree, bool is_pending, TSStateId state, StackNodeArray *pool)
Definition: stack.c:123

References array_init, array_reserve, MAX_NODE_POOL_SIZE, NULL, NULL_SUBTREE, stack_node_new(), ts_calloc, and ts_stack_clear().

Referenced by parser_init(), and ts_parser_new().

◆ ts_stack_node_count_since_error()

unsigned ts_stack_node_count_since_error ( const Stack self,
StackVersion  version 
)

Definition at line 477 of file stack.c.

477  {
478  StackHead *head = array_get(&self->heads, version);
479  if (head->node->node_count < head->node_count_at_last_error) {
480  head->node_count_at_last_error = head->node->node_count;
481  }
482  return head->node->node_count - head->node_count_at_last_error;
483 }

References array_get, and test-lz4-versions::head.

Referenced by ts_parser__better_version_exists(), ts_parser__recover(), ts_parser__version_status(), ts_parser_has_outstanding_parse(), and ts_stack_print_dot_graph().

◆ ts_stack_pause()

void ts_stack_pause ( Stack self,
StackVersion  version,
Subtree  lookahead 
)

Definition at line 709 of file stack.c.

709  {
710  StackHead *head = array_get(&self->heads, version);
711  head->status = StackStatusPaused;
712  head->lookahead_when_paused = lookahead;
713  head->node_count_at_last_error = head->node->node_count;
714 }

References array_get, and test-lz4-versions::head.

Referenced by ts_parser__advance().

◆ ts_stack_pop_all()

StackSliceArray ts_stack_pop_all ( Stack self,
StackVersion  version 
)

Definition at line 569 of file stack.c.

569  {
570  return stack__iter(self, version, pop_all_callback, NULL, 0);
571 }
StackSliceArray stack__iter(Stack *self, StackVersion version, StackCallback callback, void *payload, int goal_subtree_count)
Definition: stack.c:308
StackAction pop_all_callback(void *payload, const StackIterator *iterator)
Definition: stack.c:564

References NULL, pop_all_callback(), and stack__iter().

Referenced by parser__accept(), and ts_parser__accept().

◆ ts_stack_pop_count()

StackSliceArray ts_stack_pop_count ( Stack self,
StackVersion  version,
uint32_t  count 
)

Definition at line 507 of file stack.c.

507  {
509 }
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void count
Definition: sflib.h:98
StackAction pop_count_callback(void *payload, const StackIterator *iterator)
Definition: stack.c:498

References count, pop_count_callback(), and stack__iter().

Referenced by parser__reduce(), ts_parser__recover(), ts_parser__recover_to_state(), and ts_parser__reduce().

◆ ts_stack_pop_error()

SubtreeArray ts_stack_pop_error ( Stack self,
StackVersion  version 
)

Definition at line 547 of file stack.c.

547  {
548  StackNode *node = array_get(&self->heads, version)->node;
549  for (unsigned i = 0; i < node->link_count; i++) {
550  if (node->links[i].subtree.ptr && ts_subtree_is_error(node->links[i].subtree)) {
551  bool found_error = false;
552  StackSliceArray pop = stack__iter(self, version, pop_error_callback, &found_error, 1);
553  if (pop.size > 0) {
554  assert(pop.size == 1);
555  ts_stack_renumber_version(self, pop.contents[0].version, version);
556  return pop.contents[0].subtrees;
557  }
558  break;
559  }
560  }
561  return (SubtreeArray) {.size = 0};
562 }
void ts_stack_renumber_version(Stack *self, StackVersion v1, StackVersion v2)
Definition: stack.c:648
StackAction pop_error_callback(void *payload, const StackIterator *iterator)
Definition: stack.c:533

References array_get, assert(), i, StackNode::link_count, StackNode::links, pop_error_callback(), Subtree::ptr, stack__iter(), StackLink::subtree, ts_stack_renumber_version(), and ts_subtree_is_error().

Referenced by ts_parser__recover_to_state().

◆ ts_stack_pop_pending()

StackSliceArray ts_stack_pop_pending ( Stack self,
StackVersion  version 
)

Definition at line 524 of file stack.c.

524  {
525  StackSliceArray pop = stack__iter(self, version, pop_pending_callback, NULL, 0);
526  if (pop.size > 0) {
527  ts_stack_renumber_version(self, pop.contents[0].version, version);
528  pop.contents[0].version = version;
529  }
530  return pop;
531 }
static char * version
Definition: acr.h:4
StackAction pop_pending_callback(void *payload, const StackIterator *iterator)
Definition: stack.c:511

References NULL, pop_pending_callback(), stack__iter(), ts_stack_renumber_version(), and version.

Referenced by parser__breakdown_top_of_stack(), and ts_parser__breakdown_top_of_stack().

◆ ts_stack_position()

Length ts_stack_position ( const Stack self,
StackVersion  version 
)

Definition at line 451 of file stack.c.

451  {
452  return array_get(&self->heads, version)->node->position;
453 }

References array_get.

Referenced by ts_parser__advance(), ts_parser__better_version_exists(), ts_parser__handle_error(), ts_parser__lex(), ts_parser__recover(), and ts_parser_parse().

◆ ts_stack_print_dot_graph()

bool ts_stack_print_dot_graph ( Stack self,
const TSLanguage language,
FILE *  f 
)

Definition at line 751 of file stack.c.

751  {
752  array_reserve(&self->iterators, 32);
753  if (!f) f = stderr;
754 
755  fprintf(f, "digraph stack {\n");
756  fprintf(f, "rankdir=\"RL\";\n");
757  fprintf(f, "edge [arrowhead=none]\n");
758 
759  Array(StackNode *) visited_nodes = array_new();
760 
761  array_clear(&self->iterators);
762  for (uint32_t i = 0; i < self->heads.size; i++) {
763  StackHead *head = &self->heads.contents[i];
764  if (head->status == StackStatusHalted) continue;
765 
766  fprintf(f, "node_head_%u [shape=none, label=\"\"]\n", i);
767  fprintf(f, "node_head_%u -> node_%p [", i, (void *)head->node);
768 
769  if (head->status == StackStatusPaused) {
770  fprintf(f, "color=red ");
771  }
772  fprintf(f,
773  "label=%u, fontcolor=blue, weight=10000, labeltooltip=\"node_count: %u\nerror_cost: %u",
774  i,
776  ts_stack_error_cost(self, i)
777  );
778 
779  if (head->summary) {
780  fprintf(f, "\nsummary_size: %u", head->summary->size);
781  }
782 
783  if (head->last_external_token.ptr) {
784  const ExternalScannerState *state = &head->last_external_token.ptr->external_scanner_state;
785  const char *data = ts_external_scanner_state_data(state);
786  fprintf(f, "\nexternal_scanner_state:");
787  for (uint32_t j = 0; j < state->length; j++) fprintf(f, " %2X", data[j]);
788  }
789 
790  fprintf(f, "\"]\n");
791  array_push(&self->iterators, ((StackIterator) {
792  .node = head->node
793  }));
794  }
795 
796  bool all_iterators_done = false;
797  while (!all_iterators_done) {
798  all_iterators_done = true;
799 
800  for (uint32_t i = 0; i < self->iterators.size; i++) {
801  StackIterator iterator = self->iterators.contents[i];
802  StackNode *node = iterator.node;
803 
804  for (uint32_t j = 0; j < visited_nodes.size; j++) {
805  if (visited_nodes.contents[j] == node) {
806  node = NULL;
807  break;
808  }
809  }
810 
811  if (!node) continue;
812  all_iterators_done = false;
813 
814  fprintf(f, "node_%p [", (void *)node);
815  if (node->state == ERROR_STATE) {
816  fprintf(f, "label=\"?\"");
817  } else if (
818  node->link_count == 1 &&
819  node->links[0].subtree.ptr &&
820  ts_subtree_extra(node->links[0].subtree)
821  ) {
822  fprintf(f, "shape=point margin=0 label=\"\"");
823  } else {
824  fprintf(f, "label=\"%d\"", node->state);
825  }
826 
827  fprintf(
828  f,
829  " tooltip=\"position: %u,%u\nnode_count:%u\nerror_cost: %u\ndynamic_precedence: %d\"];\n",
830  node->position.extent.row + 1,
831  node->position.extent.column,
832  node->node_count,
833  node->error_cost,
834  node->dynamic_precedence
835  );
836 
837  for (int j = 0; j < node->link_count; j++) {
838  StackLink link = node->links[j];
839  fprintf(f, "node_%p -> node_%p [", (void *)node, (void *)link.node);
840  if (link.is_pending) fprintf(f, "style=dashed ");
841  if (link.subtree.ptr && ts_subtree_extra(link.subtree)) fprintf(f, "fontcolor=gray ");
842 
843  if (!link.subtree.ptr) {
844  fprintf(f, "color=red");
845  } else {
846  fprintf(f, "label=\"");
847  bool quoted = ts_subtree_visible(link.subtree) && !ts_subtree_named(link.subtree);
848  if (quoted) fprintf(f, "'");
849  const char *name = ts_language_symbol_name(language, ts_subtree_symbol(link.subtree));
850  for (const char *c = name; *c; c++) {
851  if (*c == '\"' || *c == '\\') fprintf(f, "\\");
852  fprintf(f, "%c", *c);
853  }
854  if (quoted) fprintf(f, "'");
855  fprintf(f, "\"");
856  fprintf(
857  f,
858  "labeltooltip=\"error_cost: %u\ndynamic_precedence: %u\"",
859  ts_subtree_error_cost(link.subtree),
861  );
862  }
863 
864  fprintf(f, "];\n");
865 
866  StackIterator *next_iterator;
867  if (j == 0) {
868  next_iterator = &self->iterators.contents[i];
869  } else {
870  array_push(&self->iterators, iterator);
871  next_iterator = array_back(&self->iterators);
872  }
873  next_iterator->node = link.node;
874  }
875 
876  array_push(&visited_nodes, node);
877  }
878  }
879 
880  fprintf(f, "}\n");
881 
882  array_delete(&visited_nodes);
883  return true;
884 }
const char * ts_language_symbol_name(const TSLanguage *, TSSymbol)
Definition: language.c:59
#define f(i)
Definition: sha256.c:46
#define c(i)
Definition: sha256.c:43
TSPoint extent
Definition: length.h:11
uint32_t row
Definition: api.h:56
uint32_t column
Definition: api.h:57
Definition: z80asm.h:102
unsigned ts_stack_node_count_since_error(const Stack *self, StackVersion version)
Definition: stack.c:477
unsigned ts_stack_error_cost(const Stack *self, StackVersion version)
Definition: stack.c:466
typedef Array(StackNode *)
Definition: stack.c:46
const char * ts_external_scanner_state_data(const ExternalScannerState *self)
Definition: subtree.c:53
static bool ts_subtree_visible(Subtree self)
Definition: subtree.h:214
static bool ts_subtree_named(Subtree self)
Definition: subtree.h:215

References Array(), array_back, array_clear, array_delete, array_new, array_push, array_reserve, c, TSPoint::column, StackNode::dynamic_precedence, StackNode::error_cost, ERROR_STATE, Length::extent, f, test-lz4-versions::head, i, link, StackNode::link_count, StackNode::links, StackIterator::node, StackNode::node_count, NULL, StackNode::position, Subtree::ptr, TSPoint::row, StackNode::state, StackLink::subtree, ts_external_scanner_state_data(), ts_language_symbol_name(), ts_stack_error_cost(), ts_stack_node_count_since_error(), ts_subtree_dynamic_precedence(), ts_subtree_error_cost(), ts_subtree_extra(), ts_subtree_named(), ts_subtree_symbol(), and ts_subtree_visible().

◆ ts_stack_push()

void ts_stack_push ( Stack self,
StackVersion  version,
Subtree  subtree,
bool  pending,
TSStateId  state 
)

◆ ts_stack_record_summary()

void ts_stack_record_summary ( Stack self,
StackVersion  version,
unsigned  max_depth 
)

Definition at line 596 of file stack.c.

596  {
597  SummarizeStackSession session = {
598  .summary = ts_malloc(sizeof(StackSummary)),
599  .max_depth = max_depth
600  };
601  array_init(session.summary);
602  stack__iter(self, version, summarize_stack_callback, &session, -1);
603  StackHead *head = &self->heads.contents[version];
604  if (head->summary) {
605  array_delete(head->summary);
606  ts_free(head->summary);
607  }
608  head->summary = session.summary;
609 }
StackAction summarize_stack_callback(void *payload, const StackIterator *iterator)
Definition: stack.c:578

References array_delete, array_init, test-lz4-versions::head, stack__iter(), summarize_stack_callback(), SummarizeStackSession::summary, ts_free, ts_malloc, and version.

Referenced by ts_parser__handle_error().

◆ ts_stack_remove_version()

◆ ts_stack_renumber_version()

void ts_stack_renumber_version ( Stack self,
StackVersion  v1,
StackVersion  v2 
)

Definition at line 648 of file stack.c.

648  {
649  if (v1 == v2) return;
650  assert(v2 < v1);
651  assert((uint32_t)v1 < self->heads.size);
652  StackHead *source_head = &self->heads.contents[v1];
653  StackHead *target_head = &self->heads.contents[v2];
654  if (target_head->summary && !source_head->summary) {
655  source_head->summary = target_head->summary;
656  target_head->summary = NULL;
657  }
658  stack_head_delete(target_head, &self->node_pool, self->subtree_pool);
659  *target_head = *source_head;
660  array_erase(&self->heads, v1);
661 }
@ v1
Definition: lanai.h:85

References array_erase, assert(), NULL, stack_head_delete(), StackHead::summary, and v1.

Referenced by parser__advance(), parser__do_potential_reductions(), parser__repair_error(), ts_parser__advance(), ts_parser__do_all_potential_reductions(), ts_parser__recover(), ts_stack_pop_error(), and ts_stack_pop_pending().

◆ ts_stack_resume()

Subtree ts_stack_resume ( Stack self,
StackVersion  version 
)

Definition at line 728 of file stack.c.

728  {
729  StackHead *head = array_get(&self->heads, version);
730  assert(head->status == StackStatusPaused);
731  Subtree result = head->lookahead_when_paused;
732  head->status = StackStatusActive;
733  head->lookahead_when_paused = NULL_SUBTREE;
734  return result;
735 }

References array_get, assert(), test-lz4-versions::head, and NULL_SUBTREE.

Referenced by ts_parser__condense_stack().

◆ ts_stack_set_last_external_token()

void ts_stack_set_last_external_token ( Stack self,
StackVersion  version,
Subtree  token 
)

Definition at line 459 of file stack.c.

459  {
460  StackHead *head = array_get(&self->heads, version);
461  if (token.ptr) ts_subtree_retain(token);
462  if (head->last_external_token.ptr) ts_subtree_release(self->subtree_pool, head->last_external_token);
463  head->last_external_token = token;
464 }

References array_get, test-lz4-versions::head, Subtree::ptr, ts_subtree_release(), and ts_subtree_retain().

Referenced by ts_parser__recover(), and ts_parser__shift().

◆ ts_stack_state()

◆ ts_stack_swap_versions()

void ts_stack_swap_versions ( Stack self,
StackVersion  v1,
StackVersion  v2 
)

Definition at line 663 of file stack.c.

663  {
664  StackHead temporary_head = self->heads.contents[v1];
665  self->heads.contents[v1] = self->heads.contents[v2];
666  self->heads.contents[v2] = temporary_head;
667 }

References v1.

Referenced by ts_parser__condense_stack().

◆ ts_stack_version_count()

Variable Documentation

◆ StackStatus

StackStatus

Definition at line 52 of file stack.c.