kanayago 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +12 -0
  3. data/.ruby-version +1 -0
  4. data/README.md +20 -29
  5. data/Rakefile +43 -96
  6. data/ext/kanayago/extconf.rb +6 -0
  7. data/ext/kanayago/id.h +12 -5
  8. data/ext/kanayago/id_table.h +15 -0
  9. data/ext/kanayago/include/ruby/st.h +199 -0
  10. data/ext/kanayago/internal/array.h +3 -0
  11. data/ext/kanayago/internal/basic_operators.h +1 -0
  12. data/ext/kanayago/internal/bignum.h +1 -0
  13. data/ext/kanayago/internal/bits.h +82 -0
  14. data/ext/kanayago/internal/encoding.h +4 -1
  15. data/ext/kanayago/internal/error.h +33 -0
  16. data/ext/kanayago/internal/fixnum.h +1 -0
  17. data/ext/kanayago/internal/gc.h +47 -11
  18. data/ext/kanayago/internal/hash.h +3 -0
  19. data/ext/kanayago/internal/imemo.h +93 -32
  20. data/ext/kanayago/internal/io.h +30 -7
  21. data/ext/kanayago/internal/namespace.h +81 -0
  22. data/ext/kanayago/internal/numeric.h +1 -0
  23. data/ext/kanayago/internal/parse.h +17 -3
  24. data/ext/kanayago/internal/re.h +7 -2
  25. data/ext/kanayago/internal/sanitizers.h +88 -39
  26. data/ext/kanayago/internal/set_table.h +70 -0
  27. data/ext/kanayago/internal/string.h +33 -16
  28. data/ext/kanayago/internal/symbol.h +4 -3
  29. data/ext/kanayago/internal/thread.h +42 -9
  30. data/ext/kanayago/internal/variable.h +13 -11
  31. data/ext/kanayago/internal/vm.h +4 -5
  32. data/ext/kanayago/internal.h +0 -3
  33. data/ext/kanayago/kanayago.c +554 -235
  34. data/ext/kanayago/kanayago.h +5 -0
  35. data/ext/kanayago/literal_node.c +343 -0
  36. data/ext/kanayago/literal_node.h +30 -0
  37. data/ext/kanayago/method.h +18 -2
  38. data/ext/kanayago/node.c +7 -1
  39. data/ext/kanayago/node.h +14 -3
  40. data/ext/kanayago/parse.c +7602 -7156
  41. data/ext/kanayago/parse.h +39 -39
  42. data/ext/kanayago/parser_st.c +2 -1
  43. data/ext/kanayago/pattern_node.c +78 -0
  44. data/ext/kanayago/pattern_node.h +13 -0
  45. data/ext/kanayago/ruby_atomic.h +43 -0
  46. data/ext/kanayago/ruby_parser.c +7 -35
  47. data/ext/kanayago/rubyparser.h +83 -80
  48. data/ext/kanayago/scope_node.c +34 -0
  49. data/ext/kanayago/scope_node.h +8 -0
  50. data/ext/kanayago/shape.h +321 -111
  51. data/ext/kanayago/st.c +905 -21
  52. data/ext/kanayago/statement_node.c +795 -0
  53. data/ext/kanayago/statement_node.h +66 -0
  54. data/ext/kanayago/string_node.c +192 -0
  55. data/ext/kanayago/string_node.h +19 -0
  56. data/ext/kanayago/symbol.h +2 -9
  57. data/ext/kanayago/thread_pthread.h +10 -3
  58. data/ext/kanayago/universal_parser.c +1 -20
  59. data/ext/kanayago/variable_node.c +72 -0
  60. data/ext/kanayago/variable_node.h +12 -0
  61. data/ext/kanayago/vm_core.h +205 -71
  62. data/lib/kanayago/literal_node.rb +87 -0
  63. data/lib/kanayago/pattern_node.rb +19 -0
  64. data/lib/kanayago/statement_node.rb +222 -0
  65. data/lib/kanayago/string_node.rb +43 -0
  66. data/lib/kanayago/variable_node.rb +23 -0
  67. data/lib/kanayago/version.rb +1 -1
  68. data/lib/kanayago.rb +22 -0
  69. data/patch/3.4/copy_target.rb +78 -0
  70. data/patch/3.4/kanayago.patch +162 -0
  71. data/patch/head/copy_target.rb +84 -0
  72. data/patch/head/kanayago.patch +162 -0
  73. data/sample/minitest_generator.rb +266 -0
  74. data/sample/test_generator.rb +272 -0
  75. data/typeprof.conf.json +9 -0
  76. metadata +32 -4
  77. data/ext/kanayago/parse.tmp.y +0 -16145
@@ -0,0 +1,81 @@
1
+ #ifndef INTERNAL_NAMESPACE_H /*-*-C-*-vi:se ft=c:*/
2
+ #define INTERNAL_NAMESPACE_H
3
+
4
+ #include "ruby/ruby.h" /* for VALUE */
5
+
6
+ /**
7
+ * @author Ruby developers <ruby-core@ruby-lang.org>
8
+ * @copyright This file is a part of the programming language Ruby.
9
+ * Permission is hereby granted, to either redistribute and/or
10
+ * modify this file, provided that the conditions mentioned in the
11
+ * file COPYING are met. Consult the file for details.
12
+ * @brief Internal header for Namespace.
13
+ */
14
+ struct rb_namespace_struct {
15
+ /*
16
+ * To retrieve Namespace object that provides #require and so on.
17
+ * That is used from load.c, etc., that uses rb_namespace_t internally.
18
+ */
19
+ VALUE ns_object;
20
+ long ns_id; // namespace id to generate ext filenames
21
+
22
+ VALUE top_self;
23
+
24
+ VALUE load_path;
25
+ VALUE load_path_snapshot;
26
+ VALUE load_path_check_cache;
27
+ VALUE expanded_load_path;
28
+ VALUE loaded_features;
29
+ VALUE loaded_features_snapshot;
30
+ VALUE loaded_features_realpaths;
31
+ VALUE loaded_features_realpath_map;
32
+ struct st_table *loaded_features_index;
33
+ struct st_table *loading_table;
34
+ VALUE ruby_dln_libmap;
35
+
36
+ VALUE gvar_tbl;
37
+
38
+ bool is_user;
39
+ bool is_optional;
40
+ };
41
+ typedef struct rb_namespace_struct rb_namespace_t;
42
+
43
+ #define NAMESPACE_OBJ_P(obj) (rb_obj_class(obj) == rb_cNamespace)
44
+
45
+ #define NAMESPACE_ROOT_P(ns) (ns && !ns->is_user)
46
+ #define NAMESPACE_USER_P(ns) (ns && ns->is_user)
47
+ #define NAMESPACE_OPTIONAL_P(ns) (ns && ns->is_optional)
48
+ #define NAMESPACE_MAIN_P(ns) (ns && ns->is_user && !ns->is_optional)
49
+
50
+ #define NAMESPACE_METHOD_DEFINITION(mdef) (mdef ? mdef->ns : NULL)
51
+ #define NAMESPACE_METHOD_ENTRY(me) (me ? NAMESPACE_METHOD_DEFINITION(me->def) : NULL)
52
+ #define NAMESPACE_CC(cc) (cc ? NAMESPACE_METHOD_ENTRY(cc->cme_) : NULL)
53
+ #define NAMESPACE_CC_ENTRIES(ccs) (ccs ? NAMESPACE_METHOD_ENTRY(ccs->cme) : NULL)
54
+
55
+ RUBY_EXTERN bool ruby_namespace_enabled;
56
+ RUBY_EXTERN bool ruby_namespace_init_done;
57
+ RUBY_EXTERN bool ruby_namespace_crashed;
58
+
59
+ static inline bool
60
+ rb_namespace_available(void)
61
+ {
62
+ return ruby_namespace_enabled;
63
+ }
64
+
65
+ const rb_namespace_t * rb_root_namespace(void);
66
+ const rb_namespace_t * rb_main_namespace(void);
67
+ const rb_namespace_t * rb_current_namespace(void);
68
+ const rb_namespace_t * rb_loading_namespace(void);
69
+ const rb_namespace_t * rb_current_namespace_in_crash_report(void);
70
+
71
+ void rb_namespace_entry_mark(void *);
72
+ void rb_namespace_gc_update_references(void *ptr);
73
+
74
+ rb_namespace_t * rb_get_namespace_t(VALUE ns);
75
+ VALUE rb_get_namespace_object(rb_namespace_t *ns);
76
+
77
+ VALUE rb_namespace_local_extension(VALUE namespace, VALUE fname, VALUE path);
78
+
79
+ void rb_initialize_main_namespace(void);
80
+ void rb_namespace_init_done(void);
81
+ #endif /* INTERNAL_NAMESPACE_H */
@@ -85,6 +85,7 @@ VALUE rb_int_cmp(VALUE x, VALUE y);
85
85
  VALUE rb_int_equal(VALUE x, VALUE y);
86
86
  VALUE rb_int_divmod(VALUE x, VALUE y);
87
87
  VALUE rb_int_and(VALUE x, VALUE y);
88
+ VALUE rb_int_xor(VALUE x, VALUE y);
88
89
  VALUE rb_int_lshift(VALUE x, VALUE y);
89
90
  VALUE rb_int_rshift(VALUE x, VALUE y);
90
91
  VALUE rb_int_div(VALUE x, VALUE y);
@@ -12,6 +12,17 @@
12
12
  #include "rubyparser.h"
13
13
  #include "internal/static_assert.h"
14
14
 
15
+ // The default parser to use for Ruby code.
16
+ typedef enum {
17
+ RB_DEFAULT_PARSER_PARSE_Y,
18
+ RB_DEFAULT_PARSER_PRISM,
19
+ } ruby_default_parser_enum;
20
+
21
+ ruby_default_parser_enum rb_ruby_default_parser(void);
22
+ void rb_ruby_default_parser_set(ruby_default_parser_enum parser);
23
+
24
+ #define rb_ruby_prism_p() (rb_ruby_default_parser() == RB_DEFAULT_PARSER_PRISM)
25
+
15
26
  #ifdef UNIVERSAL_PARSER
16
27
  #define rb_encoding const void
17
28
  #endif
@@ -63,12 +74,15 @@ rb_encoding *rb_ruby_parser_encoding(rb_parser_t *p);
63
74
  int rb_ruby_parser_end_seen_p(rb_parser_t *p);
64
75
  int rb_ruby_parser_set_yydebug(rb_parser_t *p, int flag);
65
76
  rb_parser_string_t *rb_str_to_parser_string(rb_parser_t *p, VALUE str);
77
+ void rb_parser_string_free(rb_parser_t *p, rb_parser_string_t *str);
66
78
 
67
79
  int rb_parser_dvar_defined_ref(struct parser_params*, ID, ID**);
68
80
  ID rb_parser_internal_id(struct parser_params*);
69
- int rb_parser_reg_fragment_check(struct parser_params*, rb_parser_string_t*, int);
70
- int rb_reg_named_capture_assign_iter_impl(struct parser_params *p, const char *s, long len, rb_encoding *enc, NODE **succ_block, const rb_code_location_t *loc);
81
+ typedef void (*rb_parser_reg_fragment_error_func)(struct parser_params *, VALUE);
82
+ int rb_parser_reg_fragment_check(struct parser_params*, rb_parser_string_t*, int, rb_parser_reg_fragment_error_func);
83
+ int rb_reg_named_capture_assign_iter_impl(struct parser_params *p, const char *s, long len, rb_encoding *enc, NODE **succ_block, const rb_code_location_t *loc, rb_parser_assignable_func assignable);
71
84
  int rb_parser_local_defined(struct parser_params *p, ID id, const struct rb_iseq_struct *iseq);
85
+ NODE *rb_parser_assignable(struct parser_params *p, ID id, NODE *val, const YYLTYPE *loc);
72
86
 
73
87
  RUBY_SYMBOL_EXPORT_END
74
88
 
@@ -97,7 +111,7 @@ VALUE rb_ruby_parser_ruby_sourcefile_string(rb_parser_t *p);
97
111
  int rb_ruby_parser_ruby_sourceline(rb_parser_t *p);
98
112
  int rb_ruby_parser_lex_state(rb_parser_t *p);
99
113
  void rb_ruby_ripper_parse0(rb_parser_t *p);
100
- int rb_ruby_ripper_dedent_string(rb_parser_t *p, VALUE string, int width);
114
+ int rb_ruby_ripper_dedent_string(rb_parser_t *p, rb_parser_string_t *string, int width);
101
115
  int rb_ruby_ripper_initialized_p(rb_parser_t *p);
102
116
  void rb_ruby_ripper_parser_initialize(rb_parser_t *p);
103
117
  long rb_ruby_ripper_column(rb_parser_t *p);
@@ -14,15 +14,20 @@
14
14
  /* re.c */
15
15
  VALUE rb_reg_compile(VALUE str, int options, const char *sourcefile, int sourceline);
16
16
  VALUE rb_reg_check_preprocess(VALUE);
17
- long rb_reg_search0(VALUE, VALUE, long, int, int);
17
+ long rb_reg_search0(VALUE, VALUE, long, int, int, VALUE *);
18
18
  VALUE rb_reg_match_p(VALUE re, VALUE str, long pos);
19
19
  bool rb_reg_start_with_p(VALUE re, VALUE str);
20
20
  VALUE rb_reg_hash(VALUE re);
21
21
  VALUE rb_reg_equal(VALUE re1, VALUE re2);
22
- void rb_backref_set_string(VALUE string, long pos, long len);
22
+ VALUE rb_backref_set_string(VALUE string, long pos, long len);
23
23
  void rb_match_unbusy(VALUE);
24
24
  int rb_match_count(VALUE match);
25
25
  VALUE rb_reg_new_ary(VALUE ary, int options);
26
26
  VALUE rb_reg_last_defined(VALUE match);
27
27
 
28
+ #define ARG_REG_OPTION_MASK \
29
+ (ONIG_OPTION_IGNORECASE|ONIG_OPTION_MULTILINE|ONIG_OPTION_EXTEND)
30
+ #define ARG_ENCODING_FIXED 16
31
+ #define ARG_ENCODING_NONE 32
32
+
28
33
  #endif /* INTERNAL_RE_H */
@@ -16,7 +16,7 @@
16
16
  #endif
17
17
 
18
18
  #ifdef HAVE_SANITIZER_ASAN_INTERFACE_H
19
- # if __has_feature(address_sanitizer)
19
+ # if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
20
20
  # define RUBY_ASAN_ENABLED
21
21
  # include <sanitizer/asan_interface.h>
22
22
  # endif
@@ -29,6 +29,13 @@
29
29
  # endif
30
30
  #endif
31
31
 
32
+ #ifdef HAVE_SANITIZER_TSAN_INTERFACE_H
33
+ # if __has_feature(thread_sanitizer) || defined(__SANITIZE_THREAD__)
34
+ # define RUBY_TSAN_ENABLED
35
+ # include <sanitizer/tsan_interface.h>
36
+ # endif
37
+ #endif
38
+
32
39
  #include "ruby/internal/stdbool.h" /* for bool */
33
40
  #include "ruby/ruby.h" /* for VALUE */
34
41
 
@@ -39,6 +46,12 @@
39
46
  #elif defined(RUBY_ASAN_ENABLED)
40
47
  # define ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS(x) \
41
48
  __attribute__((__no_sanitize__("address"), __noinline__)) x
49
+ #elif defined(RUBY_MSAN_ENABLED)
50
+ # define ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS(x) \
51
+ __attribute__((__no_sanitize__("memory"), __noinline__)) x
52
+ #elif defined(RUBY_TSAN_ENABLED)
53
+ # define ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS(x) \
54
+ __attribute__((__no_sanitize__("thread"), __noinline__)) x
42
55
  #elif defined(NO_SANITIZE_ADDRESS)
43
56
  # define ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS(x) \
44
57
  NO_SANITIZE_ADDRESS(NOINLINE(x))
@@ -54,10 +67,11 @@
54
67
  # include "internal/warnings.h"
55
68
  # undef NO_SANITIZE
56
69
  # define NO_SANITIZE(x, y) \
57
- COMPILER_WARNING_PUSH; \
58
- COMPILER_WARNING_IGNORED(-Wattributes); \
70
+ COMPILER_WARNING_PUSH \
71
+ COMPILER_WARNING_IGNORED(-Wattributes) \
59
72
  __attribute__((__no_sanitize__(x))) y; \
60
- COMPILER_WARNING_POP
73
+ COMPILER_WARNING_POP \
74
+ y
61
75
  #endif
62
76
 
63
77
  #ifndef NO_SANITIZE
@@ -115,26 +129,23 @@ asan_poison_memory_region(const volatile void *ptr, size_t size)
115
129
  __asan_poison_memory_region(ptr, size);
116
130
  }
117
131
 
118
- /**
119
- * This is a variant of asan_poison_memory_region that takes a VALUE.
120
- *
121
- * @param[in] obj target object.
122
- */
123
- static inline void
124
- asan_poison_object(VALUE obj)
125
- {
126
- MAYBE_UNUSED(struct RVALUE *) ptr = (void *)obj;
127
- asan_poison_memory_region(ptr, SIZEOF_VALUE);
128
- }
129
-
130
132
  #ifdef RUBY_ASAN_ENABLED
131
133
  #define asan_poison_object_if(ptr, obj) do { \
132
- if (ptr) asan_poison_object(obj); \
134
+ if (ptr) rb_asan_poison_object(obj); \
133
135
  } while (0)
134
136
  #else
135
137
  #define asan_poison_object_if(ptr, obj) ((void)(ptr), (void)(obj))
136
138
  #endif
137
139
 
140
+ #ifdef RUBY_ASAN_ENABLED
141
+ RUBY_SYMBOL_EXPORT_BEGIN
142
+ /**
143
+ * This is a variant of asan_poison_memory_region that takes a VALUE.
144
+ *
145
+ * @param[in] obj target object.
146
+ */
147
+ void rb_asan_poison_object(VALUE obj);
148
+
138
149
  /**
139
150
  * This function predicates if the given object is fully addressable or not.
140
151
  *
@@ -142,12 +153,22 @@ asan_poison_object(VALUE obj)
142
153
  * @retval 0 the given object is fully addressable.
143
154
  * @retval otherwise pointer to first such byte who is poisoned.
144
155
  */
145
- static inline void *
146
- asan_poisoned_object_p(VALUE obj)
147
- {
148
- MAYBE_UNUSED(struct RVALUE *) ptr = (void *)obj;
149
- return __asan_region_is_poisoned(ptr, SIZEOF_VALUE);
150
- }
156
+ void *rb_asan_poisoned_object_p(VALUE obj);
157
+
158
+ /**
159
+ * This is a variant of asan_unpoison_memory_region that takes a VALUE.
160
+ *
161
+ * @param[in] obj target object.
162
+ * @param[in] malloc_p if the memory region is like a malloc's return value or not.
163
+ */
164
+ void rb_asan_unpoison_object(VALUE obj, bool newobj_p);
165
+
166
+ RUBY_SYMBOL_EXPORT_END
167
+ #else
168
+ # define rb_asan_poison_object(obj) ((void)obj)
169
+ # define rb_asan_poisoned_object_p(obj) ((void)obj, NULL)
170
+ # define rb_asan_unpoison_object(obj, newobj_p) ((void)obj, (void)newobj_p)
171
+ #endif
151
172
 
152
173
  /**
153
174
  * This function asserts that a (formally poisoned) memory region from ptr to
@@ -176,24 +197,11 @@ asan_unpoison_memory_region(const volatile void *ptr, size_t size, bool malloc_p
176
197
  }
177
198
  }
178
199
 
179
- /**
180
- * This is a variant of asan_unpoison_memory_region that takes a VALUE.
181
- *
182
- * @param[in] obj target object.
183
- * @param[in] malloc_p if the memory region is like a malloc's return value or not.
184
- */
185
- static inline void
186
- asan_unpoison_object(VALUE obj, bool newobj_p)
187
- {
188
- MAYBE_UNUSED(struct RVALUE *) ptr = (void *)obj;
189
- asan_unpoison_memory_region(ptr, SIZEOF_VALUE, newobj_p);
190
- }
191
-
192
200
  static inline void *
193
201
  asan_unpoison_object_temporary(VALUE obj)
194
202
  {
195
- void *ptr = asan_poisoned_object_p(obj);
196
- asan_unpoison_object(obj, false);
203
+ void *ptr = rb_asan_poisoned_object_p(obj);
204
+ rb_asan_unpoison_object(obj, false);
197
205
  return ptr;
198
206
  }
199
207
 
@@ -201,11 +209,40 @@ static inline void *
201
209
  asan_poison_object_restore(VALUE obj, void *ptr)
202
210
  {
203
211
  if (ptr) {
204
- asan_poison_object(obj);
212
+ rb_asan_poison_object(obj);
205
213
  }
206
214
  return NULL;
207
215
  }
208
216
 
217
+ #define asan_unpoisoning_object(obj) \
218
+ for (void *poisoned = asan_unpoison_object_temporary(obj), \
219
+ *unpoisoning = &poisoned; /* flag to loop just once */ \
220
+ unpoisoning; \
221
+ unpoisoning = asan_poison_object_restore(obj, poisoned))
222
+
223
+
224
+ static inline void *
225
+ asan_unpoison_memory_region_temporary(void *ptr, size_t len)
226
+ {
227
+ void *poisoned_ptr = __asan_region_is_poisoned(ptr, len);
228
+ asan_unpoison_memory_region(ptr, len, false);
229
+ return poisoned_ptr;
230
+ }
231
+
232
+ static inline void *
233
+ asan_poison_memory_region_restore(void *ptr, size_t len, void *poisoned_ptr)
234
+ {
235
+ if (poisoned_ptr) {
236
+ asan_poison_memory_region(ptr, len);
237
+ }
238
+ return NULL;
239
+ }
240
+
241
+ #define asan_unpoisoning_memory_region(ptr, len) \
242
+ for (void *poisoned = asan_unpoison_memory_region_temporary(ptr, len), \
243
+ *unpoisoning = &poisoned; /* flag to loop just once */ \
244
+ unpoisoning; \
245
+ unpoisoning = asan_poison_memory_region_restore(ptr, len, poisoned))
209
246
 
210
247
  /**
211
248
  * Checks if the given pointer is on an ASAN fake stack. If so, it returns the
@@ -293,5 +330,17 @@ asan_get_fake_stack_extents(void *thread_fake_stack_handle, VALUE slot,
293
330
  return false;
294
331
  }
295
332
 
333
+ extern const char ruby_asan_default_options[];
334
+
335
+ #ifdef RUBY_ASAN_ENABLED
336
+ /* Compile in the ASAN options Ruby needs, rather than relying on environment variables, so
337
+ * that even tests which fork ruby with a clean environment will run ASAN with the right
338
+ * settings */
339
+ # undef RUBY__ASAN_DEFAULT_OPTIONS
340
+ # define RUBY__ASAN_DEFAULT_OPTIONS \
341
+ RBIMPL_SYMBOL_EXPORT_BEGIN() \
342
+ const char * __asan_default_options(void) {return ruby_asan_default_options;} \
343
+ RBIMPL_SYMBOL_EXPORT_END()
344
+ #endif
296
345
 
297
346
  #endif /* INTERNAL_SANITIZERS_H */
@@ -0,0 +1,70 @@
1
+ #ifndef INTERNAL_SET_TABLE_H
2
+ #define INTERNAL_SET_TABLE_H
3
+
4
+ #include "include/ruby/st.h"
5
+
6
+ struct set_table_entry;
7
+
8
+ typedef struct set_table_entry set_table_entry;
9
+
10
+ struct set_table {
11
+ /* Cached features of the table -- see st.c for more details. */
12
+ unsigned char entry_power, bin_power, size_ind;
13
+ /* How many times the table was rebuilt. */
14
+ unsigned int rebuilds_num;
15
+ const struct st_hash_type *type;
16
+ /* Number of entries currently in the table. */
17
+ st_index_t num_entries;
18
+
19
+ /* Start and bound index of entries in array entries.
20
+ entries_starts and entries_bound are in interval
21
+ [0,allocated_entries]. */
22
+ st_index_t entries_start, entries_bound;
23
+
24
+ /**
25
+ * Array of size 2^entry_power.
26
+ * Followed by st_index_t *bins, Array of bins used for access by keys.
27
+ */
28
+ set_table_entry *entries;
29
+ };
30
+
31
+ typedef struct set_table set_table;
32
+
33
+ typedef int set_foreach_callback_func(st_data_t, st_data_t);
34
+ typedef int set_foreach_check_callback_func(st_data_t, st_data_t, int);
35
+ typedef int set_update_callback_func(st_data_t *key, st_data_t arg, int existing);
36
+
37
+ #define set_table_size rb_set_table_size
38
+ size_t rb_set_table_size(const struct set_table *tbl);
39
+ #define set_init_table_with_size rb_set_init_table_with_size
40
+ set_table *rb_set_init_table_with_size(set_table *tab, const struct st_hash_type *, st_index_t);
41
+ #define set_init_numtable rb_set_init_numtable
42
+ set_table *rb_set_init_numtable(void);
43
+ #define set_init_numtable_with_size rb_set_init_numtable_with_size
44
+ set_table *rb_set_init_numtable_with_size(st_index_t size);
45
+ #define set_table_delete rb_set_table_delete
46
+ int rb_set_table_delete(set_table *, st_data_t *); /* returns 0:notfound 1:deleted */
47
+ #define set_insert rb_set_insert
48
+ int rb_set_insert(set_table *, st_data_t);
49
+ #define set_table_lookup rb_set_table_lookup
50
+ int rb_set_table_lookup(set_table *, st_data_t);
51
+ #define set_foreach_with_replace rb_set_foreach_with_replace
52
+ int rb_set_foreach_with_replace(set_table *tab, set_foreach_check_callback_func *func, set_update_callback_func *replace, st_data_t arg);
53
+ #define set_table_foreach rb_set_table_foreach
54
+ int rb_set_table_foreach(set_table *, set_foreach_callback_func *, st_data_t);
55
+ #define set_foreach_check rb_set_foreach_check
56
+ int rb_set_foreach_check(set_table *, set_foreach_check_callback_func *, st_data_t, st_data_t);
57
+ #define set_keys rb_set_keys
58
+ st_index_t rb_set_keys(set_table *table, st_data_t *keys, st_index_t size);
59
+ #define set_free_table rb_set_free_table
60
+ void rb_set_free_table(set_table *);
61
+ #define set_table_clear rb_set_table_clear
62
+ void rb_set_table_clear(set_table *);
63
+ #define set_copy rb_set_copy
64
+ set_table *rb_set_copy(set_table *new_table, set_table *old_table);
65
+ #define set_memsize rb_set_memsize
66
+ PUREFUNC(size_t rb_set_memsize(const set_table *));
67
+ #define set_compact_table rb_set_compact_table
68
+ void set_compact_table(set_table *tab);
69
+
70
+ #endif
@@ -15,9 +15,11 @@
15
15
  #include "ruby/encoding.h" /* for rb_encoding */
16
16
  #include "ruby/ruby.h" /* for VALUE */
17
17
 
18
- #define STR_NOEMBED FL_USER1
19
- #define STR_SHARED FL_USER2 /* = ELTS_SHARED */
20
- #define STR_CHILLED FL_USER3
18
+ #define STR_SHARED FL_USER0 /* = ELTS_SHARED */
19
+ #define STR_NOEMBED FL_USER1
20
+ #define STR_CHILLED (FL_USER2 | FL_USER3)
21
+ #define STR_CHILLED_LITERAL FL_USER2
22
+ #define STR_CHILLED_SYMBOL_TO_S FL_USER3
21
23
 
22
24
  enum ruby_rstring_private_flags {
23
25
  RSTRING_CHILLED = STR_CHILLED,
@@ -28,6 +30,7 @@ enum ruby_rstring_private_flags {
28
30
  #endif
29
31
 
30
32
  /* string.c */
33
+ VALUE rb_str_dup_m(VALUE str);
31
34
  VALUE rb_fstring(VALUE);
32
35
  VALUE rb_fstring_cstr(const char *str);
33
36
  VALUE rb_fstring_enc_new(const char *ptr, long len, rb_encoding *enc);
@@ -51,6 +54,19 @@ int rb_enc_str_coderange_scan(VALUE str, rb_encoding *enc);
51
54
  int rb_ascii8bit_appendable_encoding_index(rb_encoding *enc, unsigned int code);
52
55
  VALUE rb_str_include(VALUE str, VALUE arg);
53
56
  VALUE rb_str_byte_substr(VALUE str, VALUE beg, VALUE len);
57
+ VALUE rb_str_substr_two_fixnums(VALUE str, VALUE beg, VALUE len, int empty);
58
+ VALUE rb_str_tmp_frozen_no_embed_acquire(VALUE str);
59
+ void rb_str_make_embedded(VALUE);
60
+ VALUE rb_str_upto_each(VALUE, VALUE, int, int (*each)(VALUE, VALUE), VALUE);
61
+ size_t rb_str_size_as_embedded(VALUE);
62
+ bool rb_str_reembeddable_p(VALUE);
63
+ VALUE rb_str_upto_endless_each(VALUE, int (*each)(VALUE, VALUE), VALUE);
64
+ VALUE rb_str_with_debug_created_info(VALUE, VALUE, int);
65
+ VALUE rb_str_frozen_bare_string(VALUE);
66
+
67
+ /* error.c */
68
+ void rb_warn_unchilled_literal(VALUE str);
69
+ void rb_warn_unchilled_symbol_to_s(VALUE str);
54
70
 
55
71
  static inline bool STR_EMBED_P(VALUE str);
56
72
  static inline bool STR_SHARED_P(VALUE str);
@@ -63,17 +79,14 @@ static inline VALUE rb_str_eql_internal(const VALUE str1, const VALUE str2);
63
79
  RUBY_SYMBOL_EXPORT_BEGIN
64
80
  /* string.c (export) */
65
81
  VALUE rb_str_tmp_frozen_acquire(VALUE str);
66
- VALUE rb_str_tmp_frozen_no_embed_acquire(VALUE str);
67
82
  void rb_str_tmp_frozen_release(VALUE str, VALUE tmp);
68
83
  VALUE rb_setup_fake_str(struct RString *fake_str, const char *name, long len, rb_encoding *enc);
69
- VALUE rb_str_upto_each(VALUE, VALUE, int, int (*each)(VALUE, VALUE), VALUE);
70
- VALUE rb_str_upto_endless_each(VALUE, int (*each)(VALUE, VALUE), VALUE);
71
- void rb_str_make_embedded(VALUE);
72
- size_t rb_str_size_as_embedded(VALUE);
73
- bool rb_str_reembeddable_p(VALUE);
74
84
  RUBY_SYMBOL_EXPORT_END
75
85
 
76
86
  VALUE rb_fstring_new(const char *ptr, long len);
87
+ void rb_gc_free_fstring(VALUE obj);
88
+ bool rb_obj_is_fstring_table(VALUE obj);
89
+ void Init_fstring_table();
77
90
  VALUE rb_obj_as_string_result(VALUE str, VALUE obj);
78
91
  VALUE rb_str_opt_plus(VALUE x, VALUE y);
79
92
  VALUE rb_str_concat_literals(size_t num, const VALUE *strary);
@@ -123,14 +136,18 @@ CHILLED_STRING_P(VALUE obj)
123
136
  static inline void
124
137
  CHILLED_STRING_MUTATED(VALUE str)
125
138
  {
139
+ VALUE chilled_reason = RB_FL_TEST_RAW(str, STR_CHILLED);
126
140
  FL_UNSET_RAW(str, STR_CHILLED);
127
- rb_category_warn(RB_WARN_CATEGORY_DEPRECATED, "literal string will be frozen in the future");
128
- }
129
-
130
- static inline void
131
- STR_CHILL_RAW(VALUE str)
132
- {
133
- FL_SET_RAW(str, STR_CHILLED);
141
+ switch (chilled_reason) {
142
+ case STR_CHILLED_SYMBOL_TO_S:
143
+ rb_warn_unchilled_symbol_to_s(str);
144
+ break;
145
+ case STR_CHILLED_LITERAL:
146
+ rb_warn_unchilled_literal(str);
147
+ break;
148
+ default:
149
+ rb_bug("RString was chilled for multiple reasons");
150
+ }
134
151
  }
135
152
 
136
153
  static inline bool
@@ -17,6 +17,7 @@
17
17
  #endif
18
18
 
19
19
  /* symbol.c */
20
+ void rb_sym_global_symbols_mark_and_move(void);
20
21
  VALUE rb_to_symbol_type(VALUE obj);
21
22
  VALUE rb_sym_intern(const char *ptr, long len, rb_encoding *enc);
22
23
  VALUE rb_sym_intern_ascii(const char *ptr, long len);
@@ -29,11 +30,11 @@ PUREFUNC(int rb_is_const_sym(VALUE sym));
29
30
  PUREFUNC(int rb_is_attrset_sym(VALUE sym));
30
31
  ID rb_make_internal_id(void);
31
32
  ID rb_make_temporary_id(size_t n);
33
+ bool rb_obj_is_symbol_table(VALUE obj);
34
+ void rb_sym_global_symbol_table_foreach_weak_reference(int (*callback)(VALUE *key, void *data), void *data);
32
35
  void rb_gc_free_dsymbol(VALUE);
33
36
  int rb_static_id_valid_p(ID id);
34
-
35
- /* vm.c */
36
- void rb_free_static_symid_str(void);
37
+ void rb_free_global_symbol_table(void);
37
38
 
38
39
  #if __has_builtin(__builtin_constant_p)
39
40
  #define rb_sym_intern_ascii_cstr(ptr) \
@@ -13,6 +13,7 @@
13
13
  #include "ccan/list/list.h" /* for list in rb_io_close_wait_list */
14
14
 
15
15
  struct rb_thread_struct; /* in vm_core.h */
16
+ struct rb_io;
16
17
 
17
18
  #define RB_VM_SAVE_MACHINE_CONTEXT(th) \
18
19
  do { \
@@ -46,27 +47,35 @@ VALUE rb_thread_shield_wait(VALUE self);
46
47
  VALUE rb_thread_shield_release(VALUE self);
47
48
  VALUE rb_thread_shield_destroy(VALUE self);
48
49
  int rb_thread_to_be_killed(VALUE thread);
50
+ void rb_thread_acquire_fork_lock(void);
51
+ void rb_thread_release_fork_lock(void);
52
+ void rb_thread_reset_fork_lock(void);
49
53
  void rb_mutex_allow_trap(VALUE self, int val);
50
54
  VALUE rb_uninterruptible(VALUE (*b_proc)(VALUE), VALUE data);
51
55
  VALUE rb_mutex_owned_p(VALUE self);
52
56
  VALUE rb_exec_recursive_outer_mid(VALUE (*f)(VALUE g, VALUE h, int r), VALUE g, VALUE h, ID mid);
53
57
  void ruby_mn_threads_params(void);
54
58
 
59
+ int rb_thread_io_wait(struct rb_io *io, int events, struct timeval * timeout);
55
60
  int rb_thread_wait_for_single_fd(int fd, int events, struct timeval * timeout);
56
61
 
57
- struct rb_io_close_wait_list {
58
- struct ccan_list_head pending_fd_users;
59
- VALUE closing_thread;
60
- VALUE wakeup_mutex;
61
- };
62
- int rb_notify_fd_close(int fd, struct rb_io_close_wait_list *busy);
63
- void rb_notify_fd_close_wait(struct rb_io_close_wait_list *busy);
62
+ size_t rb_thread_io_close_interrupt(struct rb_io *);
63
+ void rb_thread_io_close_wait(struct rb_io *);
64
+
65
+ void rb_ec_check_ints(struct rb_execution_context_struct *ec);
66
+
67
+ void rb_thread_free_native_thread(void *th_ptr);
64
68
 
65
69
  RUBY_SYMBOL_EXPORT_BEGIN
66
70
 
71
+ void *rb_thread_prevent_fork(void *(*func)(void *), void *data); /* for ext/socket/raddrinfo.c */
72
+
67
73
  /* Temporary. This API will be removed (renamed). */
68
- VALUE rb_thread_io_blocking_region(rb_blocking_function_t *func, void *data1, int fd);
69
- VALUE rb_thread_io_blocking_call(rb_blocking_function_t *func, void *data1, int fd, int events);
74
+ VALUE rb_thread_io_blocking_region(struct rb_io *io, rb_blocking_function_t *func, void *data1);
75
+ VALUE rb_thread_io_blocking_call(struct rb_io *io, rb_blocking_function_t *func, void *data1, int events);
76
+
77
+ // Invoke the given function, with the specified argument, in a way that `IO#close` from another execution context can interrupt it.
78
+ VALUE rb_thread_io_blocking_operation(VALUE self, VALUE(*function)(VALUE), VALUE argument);
70
79
 
71
80
  /* thread.c (export) */
72
81
  int ruby_thread_has_gvl_p(void); /* for ext/fiddle/closure.c */
@@ -76,4 +85,28 @@ RUBY_SYMBOL_EXPORT_END
76
85
  int rb_threadptr_execute_interrupts(struct rb_thread_struct *th, int blocking_timing);
77
86
  bool rb_thread_mn_schedulable(VALUE thread);
78
87
 
88
+ bool rb_thread_resolve_unblock_function(rb_unblock_function_t **unblock_function, void **data2, struct rb_thread_struct *thread);
89
+
90
+ // interrupt exec
91
+
92
+ typedef VALUE (rb_interrupt_exec_func_t)(void *data);
93
+
94
+ enum rb_interrupt_exec_flag {
95
+ rb_interrupt_exec_flag_none = 0x00,
96
+ rb_interrupt_exec_flag_value_data = 0x01,
97
+ rb_interrupt_exec_flag_new_thread = 0x02,
98
+ };
99
+
100
+ // interrupt the target_th and run func.
101
+ struct rb_ractor_struct;
102
+
103
+ void rb_threadptr_interrupt_exec(struct rb_thread_struct *target_th,
104
+ rb_interrupt_exec_func_t *func, void *data, enum rb_interrupt_exec_flag flags);
105
+
106
+ // create a thread in the target_r and run func on the created thread.
107
+ void rb_ractor_interrupt_exec(struct rb_ractor_struct *target_r,
108
+ rb_interrupt_exec_func_t *func, void *data, enum rb_interrupt_exec_flag flags);
109
+
110
+ void rb_threadptr_interrupt_exec_task_mark(struct rb_thread_struct *th);
111
+
79
112
  #endif /* INTERNAL_THREAD_H */