1 #include <emscripten.h>
2 #include <tree_sitter/api.h>
3 #include <stdio.h>
4 #include "array.h"
5 #include "point.h"
6 
7 /*****************************/
8 /* Section - Data marshaling */
9 /*****************************/
10 
11 static const uint32_t INPUT_BUFFER_SIZE = 10 * 1024;
12 
13 const void *TRANSFER_BUFFER[12] = {
14   NULL, NULL, NULL, NULL,
15   NULL, NULL, NULL, NULL,
16   NULL, NULL, NULL, NULL,
17 };
18 
ts_init()19 void *ts_init() {
20   TRANSFER_BUFFER[0] = (const void *)TREE_SITTER_LANGUAGE_VERSION;
21   TRANSFER_BUFFER[1] = (const void *)TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION;
22   return TRANSFER_BUFFER;
23 }
24 
code_unit_to_byte(uint32_t unit)25 static uint32_t code_unit_to_byte(uint32_t unit) {
26   return unit << 1;
27 }
28 
byte_to_code_unit(uint32_t byte)29 static uint32_t byte_to_code_unit(uint32_t byte) {
30   return byte >> 1;
31 }
32 
marshal_node(const void ** buffer,TSNode node)33 static inline void marshal_node(const void **buffer, TSNode node) {
34   buffer[0] = (const void *)node.id;
35   buffer[1] = (const void *)byte_to_code_unit(node.context[0]);
36   buffer[2] = (const void *)node.context[1];
37   buffer[3] = (const void *)byte_to_code_unit(node.context[2]);
38   buffer[4] = (const void *)node.context[3];
39 }
40 
unmarshal_node(const TSTree * tree)41 static inline TSNode unmarshal_node(const TSTree *tree) {
42   TSNode node;
43   node.id = TRANSFER_BUFFER[0];
44   node.context[0] = code_unit_to_byte((uint32_t)TRANSFER_BUFFER[1]);
45   node.context[1] = (uint32_t)TRANSFER_BUFFER[2];
46   node.context[2] = code_unit_to_byte((uint32_t)TRANSFER_BUFFER[3]);
47   node.context[3] = (uint32_t)TRANSFER_BUFFER[4];
48   node.tree = tree;
49   return node;
50 }
51 
marshal_cursor(const TSTreeCursor * cursor)52 static inline void marshal_cursor(const TSTreeCursor *cursor) {
53   TRANSFER_BUFFER[0] = (const void *)cursor->id;
54   TRANSFER_BUFFER[1] = (const void *)cursor->context[0];
55   TRANSFER_BUFFER[2] = (const void *)cursor->context[1];
56 }
57 
unmarshal_cursor(const void ** buffer,const TSTree * tree)58 static inline TSTreeCursor unmarshal_cursor(const void **buffer, const TSTree *tree) {
59   TSTreeCursor cursor;
60   cursor.id = buffer[0];
61   cursor.context[0] = (uint32_t)buffer[1];
62   cursor.context[1] = (uint32_t)buffer[2];
63   cursor.tree = tree;
64   return cursor;
65 }
66 
marshal_point(TSPoint point)67 static void marshal_point(TSPoint point) {
68   TRANSFER_BUFFER[0] = (const void *)point.row;
69   TRANSFER_BUFFER[1] = (const void *)byte_to_code_unit(point.column);
70 }
71 
unmarshal_point(const void ** address)72 static TSPoint unmarshal_point(const void **address) {
73   TSPoint point;
74   point.row = (uint32_t)address[0];
75   point.column = code_unit_to_byte((uint32_t)address[1]);
76   return point;
77 }
78 
marshal_range(TSRange * range)79 static void marshal_range(TSRange *range) {
80   range->start_byte = byte_to_code_unit(range->start_byte);
81   range->end_byte = byte_to_code_unit(range->end_byte);
82   range->start_point.column = byte_to_code_unit(range->start_point.column);
83   range->end_point.column = byte_to_code_unit(range->end_point.column);
84 }
85 
unmarshal_range(TSRange * range)86 static void unmarshal_range(TSRange *range) {
87   range->start_byte = code_unit_to_byte(range->start_byte);
88   range->end_byte = code_unit_to_byte(range->end_byte);
89   range->start_point.column = code_unit_to_byte(range->start_point.column);
90   range->end_point.column = code_unit_to_byte(range->end_point.column);
91 }
92 
unmarshal_edit()93 static TSInputEdit unmarshal_edit() {
94   TSInputEdit edit;
95   const void **address = TRANSFER_BUFFER;
96   edit.start_point = unmarshal_point(address); address += 2;
97   edit.old_end_point = unmarshal_point(address); address += 2;
98   edit.new_end_point = unmarshal_point(address); address += 2;
99   edit.start_byte = code_unit_to_byte((uint32_t)*address); address += 1;
100   edit.old_end_byte = code_unit_to_byte((uint32_t)*address); address += 1;
101   edit.new_end_byte = code_unit_to_byte((uint32_t)*address); address += 1;
102   return edit;
103 }
104 
105 /********************/
106 /* Section - Parser */
107 /********************/
108 
109 extern void tree_sitter_parse_callback(
110   char *input_buffer,
111   uint32_t index,
112   uint32_t row,
113   uint32_t column,
114   uint32_t *length_read
115 );
116 
117 extern void tree_sitter_log_callback(
118   bool is_lex_message,
119   const char *message
120 );
121 
call_parse_callback(void * payload,uint32_t byte,TSPoint position,uint32_t * bytes_read)122 static const char *call_parse_callback(
123   void *payload,
124   uint32_t byte,
125   TSPoint position,
126   uint32_t *bytes_read
127 ) {
128   char *buffer = (char *)payload;
129   tree_sitter_parse_callback(
130     buffer,
131     byte_to_code_unit(byte),
132     position.row,
133     byte_to_code_unit(position.column),
134     bytes_read
135   );
136   *bytes_read = code_unit_to_byte(*bytes_read);
137   if (*bytes_read >= INPUT_BUFFER_SIZE) {
138     *bytes_read = INPUT_BUFFER_SIZE - 2;
139   }
140   return buffer;
141 }
142 
call_log_callback(void * payload,TSLogType log_type,const char * message)143 static void call_log_callback(
144   void *payload,
145   TSLogType log_type,
146   const char *message
147 ) {
148   tree_sitter_log_callback(log_type == TSLogTypeLex, message);
149 }
150 
ts_parser_new_wasm()151 void ts_parser_new_wasm() {
152   TSParser *parser = ts_parser_new();
153   char *input_buffer = calloc(INPUT_BUFFER_SIZE, sizeof(char));
154   TRANSFER_BUFFER[0] = parser;
155   TRANSFER_BUFFER[1] = input_buffer;
156 }
157 
ts_parser_enable_logger_wasm(TSParser * self,bool should_log)158 void ts_parser_enable_logger_wasm(TSParser *self, bool should_log) {
159   TSLogger logger = {self, should_log ? call_log_callback : NULL};
160   ts_parser_set_logger(self, logger);
161 }
162 
ts_parser_parse_wasm(TSParser * self,char * input_buffer,const TSTree * old_tree,TSRange * ranges,uint32_t range_count)163 TSTree *ts_parser_parse_wasm(
164   TSParser *self,
165   char *input_buffer,
166   const TSTree *old_tree,
167   TSRange *ranges,
168   uint32_t range_count
169 ) {
170   TSInput input = {
171     input_buffer,
172     call_parse_callback,
173     TSInputEncodingUTF16
174   };
175   if (range_count) {
176     for (unsigned i = 0; i < range_count; i++) {
177       unmarshal_range(&ranges[i]);
178     }
179     ts_parser_set_included_ranges(self, ranges, range_count);
180     free(ranges);
181   } else {
182     ts_parser_set_included_ranges(self, NULL, 0);
183   }
184   return ts_parser_parse(self, old_tree, input);
185 }
186 
187 /**********************/
188 /* Section - Language */
189 /**********************/
190 
ts_language_type_is_named_wasm(const TSLanguage * self,TSSymbol typeId)191 int ts_language_type_is_named_wasm(const TSLanguage *self, TSSymbol typeId) {
192   const TSSymbolType symbolType = ts_language_symbol_type(self, typeId);
193   return symbolType == TSSymbolTypeRegular;
194 }
195 
ts_language_type_is_visible_wasm(const TSLanguage * self,TSSymbol typeId)196 int ts_language_type_is_visible_wasm(const TSLanguage *self, TSSymbol typeId) {
197   const TSSymbolType symbolType = ts_language_symbol_type(self, typeId);
198   return symbolType <= TSSymbolTypeAnonymous;
199 }
200 
201 /******************/
202 /* Section - Tree */
203 /******************/
204 
ts_tree_root_node_wasm(const TSTree * tree)205 void ts_tree_root_node_wasm(const TSTree *tree) {
206   marshal_node(TRANSFER_BUFFER, ts_tree_root_node(tree));
207 }
208 
ts_tree_edit_wasm(TSTree * tree)209 void ts_tree_edit_wasm(TSTree *tree) {
210   TSInputEdit edit = unmarshal_edit();
211   ts_tree_edit(tree, &edit);
212 }
213 
ts_tree_get_changed_ranges_wasm(TSTree * tree,TSTree * other)214 void ts_tree_get_changed_ranges_wasm(TSTree *tree, TSTree *other) {
215   unsigned range_count;
216   TSRange *ranges = ts_tree_get_changed_ranges(tree, other, &range_count);
217   for (unsigned i = 0; i < range_count; i++) {
218     marshal_range(&ranges[i]);
219   }
220   TRANSFER_BUFFER[0] = (const void *)range_count;
221   TRANSFER_BUFFER[1] = (const void *)ranges;
222 }
223 
224 /************************/
225 /* Section - TreeCursor */
226 /************************/
227 
ts_tree_cursor_new_wasm(const TSTree * tree)228 void ts_tree_cursor_new_wasm(const TSTree *tree) {
229   TSNode node = unmarshal_node(tree);
230   TSTreeCursor cursor = ts_tree_cursor_new(node);
231   marshal_cursor(&cursor);
232 }
233 
ts_tree_cursor_delete_wasm(const TSTree * tree)234 void ts_tree_cursor_delete_wasm(const TSTree *tree) {
235   TSTreeCursor cursor = unmarshal_cursor(TRANSFER_BUFFER, tree);
236   ts_tree_cursor_delete(&cursor);
237 }
238 
ts_tree_cursor_reset_wasm(const TSTree * tree)239 void ts_tree_cursor_reset_wasm(const TSTree *tree) {
240   TSNode node = unmarshal_node(tree);
241   TSTreeCursor cursor = unmarshal_cursor(&TRANSFER_BUFFER[5], tree);
242   ts_tree_cursor_reset(&cursor, node);
243   marshal_cursor(&cursor);
244 }
245 
ts_tree_cursor_goto_first_child_wasm(const TSTree * tree)246 bool ts_tree_cursor_goto_first_child_wasm(const TSTree *tree) {
247   TSTreeCursor cursor = unmarshal_cursor(TRANSFER_BUFFER, tree);
248   bool result = ts_tree_cursor_goto_first_child(&cursor);
249   marshal_cursor(&cursor);
250   return result;
251 }
252 
ts_tree_cursor_goto_next_sibling_wasm(const TSTree * tree)253 bool ts_tree_cursor_goto_next_sibling_wasm(const TSTree *tree) {
254   TSTreeCursor cursor = unmarshal_cursor(TRANSFER_BUFFER, tree);
255   bool result = ts_tree_cursor_goto_next_sibling(&cursor);
256   marshal_cursor(&cursor);
257   return result;
258 }
259 
ts_tree_cursor_goto_parent_wasm(const TSTree * tree)260 bool ts_tree_cursor_goto_parent_wasm(const TSTree *tree) {
261   TSTreeCursor cursor = unmarshal_cursor(TRANSFER_BUFFER, tree);
262   bool result = ts_tree_cursor_goto_parent(&cursor);
263   marshal_cursor(&cursor);
264   return result;
265 }
266 
ts_tree_cursor_current_node_type_id_wasm(const TSTree * tree)267 uint16_t ts_tree_cursor_current_node_type_id_wasm(const TSTree *tree) {
268   TSTreeCursor cursor = unmarshal_cursor(TRANSFER_BUFFER, tree);
269   TSNode node = ts_tree_cursor_current_node(&cursor);
270   return ts_node_symbol(node);
271 }
272 
ts_tree_cursor_current_node_is_named_wasm(const TSTree * tree)273 bool ts_tree_cursor_current_node_is_named_wasm(const TSTree *tree) {
274   TSTreeCursor cursor = unmarshal_cursor(TRANSFER_BUFFER, tree);
275   TSNode node = ts_tree_cursor_current_node(&cursor);
276   return ts_node_is_named(node);
277 }
278 
ts_tree_cursor_current_node_is_missing_wasm(const TSTree * tree)279 bool ts_tree_cursor_current_node_is_missing_wasm(const TSTree *tree) {
280   TSTreeCursor cursor = unmarshal_cursor(TRANSFER_BUFFER, tree);
281   TSNode node = ts_tree_cursor_current_node(&cursor);
282   return ts_node_is_missing(node);
283 }
284 
ts_tree_cursor_current_node_id_wasm(const TSTree * tree)285 const uint32_t ts_tree_cursor_current_node_id_wasm(const TSTree *tree) {
286   TSTreeCursor cursor = unmarshal_cursor(TRANSFER_BUFFER, tree);
287   TSNode node = ts_tree_cursor_current_node(&cursor);
288   return (uint32_t)node.id;
289 }
290 
ts_tree_cursor_start_position_wasm(const TSTree * tree)291 void ts_tree_cursor_start_position_wasm(const TSTree *tree) {
292   TSTreeCursor cursor = unmarshal_cursor(TRANSFER_BUFFER, tree);
293   TSNode node = ts_tree_cursor_current_node(&cursor);
294   marshal_point(ts_node_start_point(node));
295 }
296 
ts_tree_cursor_end_position_wasm(const TSTree * tree)297 void ts_tree_cursor_end_position_wasm(const TSTree *tree) {
298   TSTreeCursor cursor = unmarshal_cursor(TRANSFER_BUFFER, tree);
299   TSNode node = ts_tree_cursor_current_node(&cursor);
300   marshal_point(ts_node_end_point(node));
301 }
302 
ts_tree_cursor_start_index_wasm(const TSTree * tree)303 uint32_t ts_tree_cursor_start_index_wasm(const TSTree *tree) {
304   TSTreeCursor cursor = unmarshal_cursor(TRANSFER_BUFFER, tree);
305   TSNode node = ts_tree_cursor_current_node(&cursor);
306   return byte_to_code_unit(ts_node_start_byte(node));
307 }
308 
ts_tree_cursor_end_index_wasm(const TSTree * tree)309 uint32_t ts_tree_cursor_end_index_wasm(const TSTree *tree) {
310   TSTreeCursor cursor = unmarshal_cursor(TRANSFER_BUFFER, tree);
311   TSNode node = ts_tree_cursor_current_node(&cursor);
312   return byte_to_code_unit(ts_node_end_byte(node));
313 }
314 
ts_tree_cursor_current_field_id_wasm(const TSTree * tree)315 uint32_t ts_tree_cursor_current_field_id_wasm(const TSTree *tree) {
316   TSTreeCursor cursor = unmarshal_cursor(TRANSFER_BUFFER, tree);
317   return ts_tree_cursor_current_field_id(&cursor);
318 }
319 
ts_tree_cursor_current_node_wasm(const TSTree * tree)320 void ts_tree_cursor_current_node_wasm(const TSTree *tree) {
321   TSTreeCursor cursor = unmarshal_cursor(TRANSFER_BUFFER, tree);
322   marshal_node(TRANSFER_BUFFER, ts_tree_cursor_current_node(&cursor));
323 }
324 
325 /******************/
326 /* Section - Node */
327 /******************/
328 
329 static TSTreeCursor scratch_cursor = {0};
330 static TSQueryCursor *scratch_query_cursor = NULL;
331 
ts_node_symbol_wasm(const TSTree * tree)332 uint16_t ts_node_symbol_wasm(const TSTree *tree) {
333   TSNode node = unmarshal_node(tree);
334   return ts_node_symbol(node);
335 }
336 
ts_node_child_count_wasm(const TSTree * tree)337 uint32_t ts_node_child_count_wasm(const TSTree *tree) {
338   TSNode node = unmarshal_node(tree);
339   return ts_node_child_count(node);
340 }
341 
ts_node_named_child_count_wasm(const TSTree * tree)342 uint32_t ts_node_named_child_count_wasm(const TSTree *tree) {
343   TSNode node = unmarshal_node(tree);
344   return ts_node_named_child_count(node);
345 }
346 
ts_node_child_wasm(const TSTree * tree,uint32_t index)347 void ts_node_child_wasm(const TSTree *tree, uint32_t index) {
348   TSNode node = unmarshal_node(tree);
349   marshal_node(TRANSFER_BUFFER, ts_node_child(node, index));
350 }
351 
ts_node_named_child_wasm(const TSTree * tree,uint32_t index)352 void ts_node_named_child_wasm(const TSTree *tree, uint32_t index) {
353   TSNode node = unmarshal_node(tree);
354   marshal_node(TRANSFER_BUFFER, ts_node_named_child(node, index));
355 }
356 
ts_node_child_by_field_id_wasm(const TSTree * tree,uint32_t field_id)357 void ts_node_child_by_field_id_wasm(const TSTree *tree, uint32_t field_id) {
358   TSNode node = unmarshal_node(tree);
359   marshal_node(TRANSFER_BUFFER, ts_node_child_by_field_id(node, field_id));
360 }
361 
ts_node_next_sibling_wasm(const TSTree * tree)362 void ts_node_next_sibling_wasm(const TSTree *tree) {
363   TSNode node = unmarshal_node(tree);
364   marshal_node(TRANSFER_BUFFER, ts_node_next_sibling(node));
365 }
366 
ts_node_prev_sibling_wasm(const TSTree * tree)367 void ts_node_prev_sibling_wasm(const TSTree *tree) {
368   TSNode node = unmarshal_node(tree);
369   marshal_node(TRANSFER_BUFFER, ts_node_prev_sibling(node));
370 }
371 
ts_node_next_named_sibling_wasm(const TSTree * tree)372 void ts_node_next_named_sibling_wasm(const TSTree *tree) {
373   TSNode node = unmarshal_node(tree);
374   marshal_node(TRANSFER_BUFFER, ts_node_next_named_sibling(node));
375 }
376 
ts_node_prev_named_sibling_wasm(const TSTree * tree)377 void ts_node_prev_named_sibling_wasm(const TSTree *tree) {
378   TSNode node = unmarshal_node(tree);
379   marshal_node(TRANSFER_BUFFER, ts_node_prev_named_sibling(node));
380 }
381 
ts_node_parent_wasm(const TSTree * tree)382 void ts_node_parent_wasm(const TSTree *tree) {
383   TSNode node = unmarshal_node(tree);
384   marshal_node(TRANSFER_BUFFER, ts_node_parent(node));
385 }
386 
ts_node_descendant_for_index_wasm(const TSTree * tree)387 void ts_node_descendant_for_index_wasm(const TSTree *tree) {
388   TSNode node = unmarshal_node(tree);
389   const void **address = TRANSFER_BUFFER + 5;
390   uint32_t start = code_unit_to_byte((uint32_t)address[0]);
391   uint32_t end = code_unit_to_byte((uint32_t)address[1]);
392   marshal_node(TRANSFER_BUFFER, ts_node_descendant_for_byte_range(node, start, end));
393 }
394 
ts_node_named_descendant_for_index_wasm(const TSTree * tree)395 void ts_node_named_descendant_for_index_wasm(const TSTree *tree) {
396   TSNode node = unmarshal_node(tree);
397   const void **address = TRANSFER_BUFFER + 5;
398   uint32_t start = code_unit_to_byte((uint32_t)address[0]);
399   uint32_t end = code_unit_to_byte((uint32_t)address[1]);
400   marshal_node(TRANSFER_BUFFER, ts_node_named_descendant_for_byte_range(node, start, end));
401 }
402 
ts_node_descendant_for_position_wasm(const TSTree * tree)403 void ts_node_descendant_for_position_wasm(const TSTree *tree) {
404   TSNode node = unmarshal_node(tree);
405   const void **address = TRANSFER_BUFFER + 5;
406   TSPoint start = unmarshal_point(address); address += 2;
407   TSPoint end = unmarshal_point(address);
408   marshal_node(TRANSFER_BUFFER, ts_node_descendant_for_point_range(node, start, end));
409 }
410 
ts_node_named_descendant_for_position_wasm(const TSTree * tree)411 void ts_node_named_descendant_for_position_wasm(const TSTree *tree) {
412   TSNode node = unmarshal_node(tree);
413   const void **address = TRANSFER_BUFFER + 5;
414   TSPoint start = unmarshal_point(address); address += 2;
415   TSPoint end = unmarshal_point(address);
416   marshal_node(TRANSFER_BUFFER, ts_node_named_descendant_for_point_range(node, start, end));
417 }
418 
ts_node_start_point_wasm(const TSTree * tree)419 void ts_node_start_point_wasm(const TSTree *tree) {
420   TSNode node = unmarshal_node(tree);
421   marshal_point(ts_node_start_point(node));
422 }
423 
ts_node_end_point_wasm(const TSTree * tree)424 void ts_node_end_point_wasm(const TSTree *tree) {
425   TSNode node = unmarshal_node(tree);
426   marshal_point(ts_node_end_point(node));
427 }
428 
ts_node_start_index_wasm(const TSTree * tree)429 uint32_t ts_node_start_index_wasm(const TSTree *tree) {
430   TSNode node = unmarshal_node(tree);
431   return byte_to_code_unit(ts_node_start_byte(node));
432 }
433 
ts_node_end_index_wasm(const TSTree * tree)434 uint32_t ts_node_end_index_wasm(const TSTree *tree) {
435   TSNode node = unmarshal_node(tree);
436   return byte_to_code_unit(ts_node_end_byte(node));
437 }
438 
ts_node_to_string_wasm(const TSTree * tree)439 char *ts_node_to_string_wasm(const TSTree *tree) {
440   TSNode node = unmarshal_node(tree);
441   return ts_node_string(node);
442 }
443 
ts_node_children_wasm(const TSTree * tree)444 void ts_node_children_wasm(const TSTree *tree) {
445   TSNode node = unmarshal_node(tree);
446   uint32_t count = ts_node_child_count(node);
447   const void **result = NULL;
448   if (count > 0) {
449     result = calloc(sizeof(void *), 5 * count);
450     const void **address = result;
451     ts_tree_cursor_reset(&scratch_cursor, node);
452     ts_tree_cursor_goto_first_child(&scratch_cursor);
453     marshal_node(address, ts_tree_cursor_current_node(&scratch_cursor));
454     for (uint32_t i = 1; i < count; i++) {
455       address += 5;
456       ts_tree_cursor_goto_next_sibling(&scratch_cursor);
457       TSNode child = ts_tree_cursor_current_node(&scratch_cursor);
458       marshal_node(address, child);
459     }
460   }
461   TRANSFER_BUFFER[0] = (const void *)count;
462   TRANSFER_BUFFER[1] = result;
463 }
464 
ts_node_named_children_wasm(const TSTree * tree)465 void ts_node_named_children_wasm(const TSTree *tree) {
466   TSNode node = unmarshal_node(tree);
467   uint32_t count = ts_node_named_child_count(node);
468   const void **result = NULL;
469   if (count > 0) {
470     result = calloc(sizeof(void *), 5 * count);
471     const void **address = result;
472     ts_tree_cursor_reset(&scratch_cursor, node);
473     ts_tree_cursor_goto_first_child(&scratch_cursor);
474     uint32_t i = 0;
475     for (;;) {
476       TSNode child = ts_tree_cursor_current_node(&scratch_cursor);
477       if (ts_node_is_named(child)) {
478         marshal_node(address, child);
479         address += 5;
480         i++;
481         if (i == count) break;
482       }
483       if (!ts_tree_cursor_goto_next_sibling(&scratch_cursor)) break;
484     }
485   }
486   TRANSFER_BUFFER[0] = (const void *)count;
487   TRANSFER_BUFFER[1] = result;
488 }
489 
symbols_contain(const uint32_t * set,uint32_t length,uint32_t value)490 bool symbols_contain(const uint32_t *set, uint32_t length, uint32_t value) {
491   for (unsigned i = 0; i < length; i++) {
492     if (set[i] == value) return true;
493     if (set[i] > value) break;
494   }
495   return false;
496 }
497 
ts_node_descendants_of_type_wasm(const TSTree * tree,const uint32_t * symbols,uint32_t symbol_count,uint32_t start_row,uint32_t start_column,uint32_t end_row,uint32_t end_column)498 void ts_node_descendants_of_type_wasm(
499   const TSTree *tree,
500   const uint32_t *symbols,
501   uint32_t symbol_count,
502   uint32_t start_row,
503   uint32_t start_column,
504   uint32_t end_row,
505   uint32_t end_column
506 ) {
507   TSNode node = unmarshal_node(tree);
508   TSPoint start_point = {start_row, code_unit_to_byte(start_column)};
509   TSPoint end_point = {end_row, code_unit_to_byte(end_column)};
510   if (end_point.row == 0 && end_point.column == 0) {
511     end_point = (TSPoint) {UINT32_MAX, UINT32_MAX};
512   }
513 
514   Array(const void *) result = array_new();
515 
516   // Walk the tree depth first looking for matching nodes.
517   ts_tree_cursor_reset(&scratch_cursor, node);
518   bool already_visited_children = false;
519   while (true) {
520     TSNode descendant = ts_tree_cursor_current_node(&scratch_cursor);
521 
522     if (!already_visited_children) {
523       // If this node is before the selected range, then avoid
524       // descending into it.
525       if (point_lte(ts_node_end_point(descendant), start_point)) {
526         if (ts_tree_cursor_goto_next_sibling(&scratch_cursor)) {
527           already_visited_children = false;
528         } else {
529           if (!ts_tree_cursor_goto_parent(&scratch_cursor)) break;
530           already_visited_children = true;
531         }
532         continue;
533       }
534 
535       // If this node is after the selected range, then stop walking.
536       if (point_lte(end_point, ts_node_start_point(descendant))) break;
537 
538       // Add the node to the result if its type matches one of the given
539       // node types.
540       if (symbols_contain(symbols, symbol_count, ts_node_symbol(descendant))) {
541         array_grow_by(&result, 5);
542         marshal_node(result.contents + result.size - 5, descendant);
543       }
544 
545       // Continue walking.
546       if (ts_tree_cursor_goto_first_child(&scratch_cursor)) {
547         already_visited_children = false;
548       } else if (ts_tree_cursor_goto_next_sibling(&scratch_cursor)) {
549         already_visited_children = false;
550       } else {
551         if (!ts_tree_cursor_goto_parent(&scratch_cursor)) break;
552         already_visited_children = true;
553       }
554     } else {
555       if (ts_tree_cursor_goto_next_sibling(&scratch_cursor)) {
556         already_visited_children = false;
557       } else {
558         if (!ts_tree_cursor_goto_parent(&scratch_cursor)) break;
559       }
560     }
561   }
562 
563   TRANSFER_BUFFER[0] = (const void *)(result.size / 5);
564   TRANSFER_BUFFER[1] = result.contents;
565 }
566 
ts_node_is_named_wasm(const TSTree * tree)567 int ts_node_is_named_wasm(const TSTree *tree) {
568   TSNode node = unmarshal_node(tree);
569   return ts_node_is_named(node);
570 }
571 
ts_node_has_changes_wasm(const TSTree * tree)572 int ts_node_has_changes_wasm(const TSTree *tree) {
573   TSNode node = unmarshal_node(tree);
574   return ts_node_has_changes(node);
575 }
576 
ts_node_has_error_wasm(const TSTree * tree)577 int ts_node_has_error_wasm(const TSTree *tree) {
578   TSNode node = unmarshal_node(tree);
579   return ts_node_has_error(node);
580 }
581 
ts_node_is_missing_wasm(const TSTree * tree)582 int ts_node_is_missing_wasm(const TSTree *tree) {
583   TSNode node = unmarshal_node(tree);
584   return ts_node_is_missing(node);
585 }
586 
587 /******************/
588 /* Section - Query */
589 /******************/
590 
ts_query_matches_wasm(const TSQuery * self,const TSTree * tree,uint32_t start_row,uint32_t start_column,uint32_t end_row,uint32_t end_column,uint32_t match_limit)591 void ts_query_matches_wasm(
592   const TSQuery *self,
593   const TSTree *tree,
594   uint32_t start_row,
595   uint32_t start_column,
596   uint32_t end_row,
597   uint32_t end_column,
598   uint32_t match_limit
599 ) {
600   if (!scratch_query_cursor) scratch_query_cursor = ts_query_cursor_new();
601   if (match_limit == 0) {
602     ts_query_cursor_set_match_limit(scratch_query_cursor, UINT32_MAX);
603   } else {
604     ts_query_cursor_set_match_limit(scratch_query_cursor, match_limit);
605   }
606 
607   TSNode node = unmarshal_node(tree);
608   TSPoint start_point = {start_row, code_unit_to_byte(start_column)};
609   TSPoint end_point = {end_row, code_unit_to_byte(end_column)};
610   ts_query_cursor_set_point_range(scratch_query_cursor, start_point, end_point);
611   ts_query_cursor_exec(scratch_query_cursor, self, node);
612 
613   uint32_t index = 0;
614   uint32_t match_count = 0;
615   Array(const void *) result = array_new();
616 
617   TSQueryMatch match;
618   while (ts_query_cursor_next_match(scratch_query_cursor, &match)) {
619     match_count++;
620     array_grow_by(&result, 2 + 6 * match.capture_count);
621     result.contents[index++] = (const void *)(uint32_t)match.pattern_index;
622     result.contents[index++] = (const void *)(uint32_t)match.capture_count;
623     for (unsigned i = 0; i < match.capture_count; i++) {
624       const TSQueryCapture *capture = &match.captures[i];
625       result.contents[index++] = (const void *)capture->index;
626       marshal_node(result.contents + index, capture->node);
627       index += 5;
628     }
629   }
630 
631   bool did_exceed_match_limit =
632     ts_query_cursor_did_exceed_match_limit(scratch_query_cursor);
633   TRANSFER_BUFFER[0] = (const void *)(match_count);
634   TRANSFER_BUFFER[1] = result.contents;
635   TRANSFER_BUFFER[2] = (const void *)(did_exceed_match_limit);
636 }
637 
ts_query_captures_wasm(const TSQuery * self,const TSTree * tree,uint32_t start_row,uint32_t start_column,uint32_t end_row,uint32_t end_column,uint32_t match_limit)638 void ts_query_captures_wasm(
639   const TSQuery *self,
640   const TSTree *tree,
641   uint32_t start_row,
642   uint32_t start_column,
643   uint32_t end_row,
644   uint32_t end_column,
645   uint32_t match_limit
646 ) {
647   if (!scratch_query_cursor) scratch_query_cursor = ts_query_cursor_new();
648   if (match_limit == 0) {
649     ts_query_cursor_set_match_limit(scratch_query_cursor, UINT32_MAX);
650   } else {
651     ts_query_cursor_set_match_limit(scratch_query_cursor, match_limit);
652   }
653 
654   TSNode node = unmarshal_node(tree);
655   TSPoint start_point = {start_row, code_unit_to_byte(start_column)};
656   TSPoint end_point = {end_row, code_unit_to_byte(end_column)};
657   ts_query_cursor_set_point_range(scratch_query_cursor, start_point, end_point);
658   ts_query_cursor_exec(scratch_query_cursor, self, node);
659 
660   unsigned index = 0;
661   unsigned capture_count = 0;
662   Array(const void *) result = array_new();
663 
664   TSQueryMatch match;
665   uint32_t capture_index;
666   while (ts_query_cursor_next_capture(
667     scratch_query_cursor,
668     &match,
669     &capture_index
670   )) {
671     capture_count++;
672 
673     array_grow_by(&result, 3 + 6 * match.capture_count);
674     result.contents[index++] = (const void *)(uint32_t)match.pattern_index;
675     result.contents[index++] = (const void *)(uint32_t)match.capture_count;
676     result.contents[index++] = (const void *)(uint32_t)capture_index;
677     for (unsigned i = 0; i < match.capture_count; i++) {
678       const TSQueryCapture *capture = &match.captures[i];
679       result.contents[index++] = (const void *)capture->index;
680       marshal_node(result.contents + index, capture->node);
681       index += 5;
682     }
683   }
684 
685   bool did_exceed_match_limit =
686     ts_query_cursor_did_exceed_match_limit(scratch_query_cursor);
687   TRANSFER_BUFFER[0] = (const void *)(capture_count);
688   TRANSFER_BUFFER[1] = result.contents;
689   TRANSFER_BUFFER[2] = (const void *)(did_exceed_match_limit);
690 }
691