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
@@ -90,6 +90,7 @@
90
90
 
91
91
  #define UNSIGNED_INTEGER_MAX(T) ((T)~(T)0)
92
92
 
93
+ #ifndef MUL_OVERFLOW_SIGNED_INTEGER_P
93
94
  #if __has_builtin(__builtin_mul_overflow_p)
94
95
  # define MUL_OVERFLOW_P(a, b) \
95
96
  __builtin_mul_overflow_p((a), (b), (__typeof__(a * b))0)
@@ -131,6 +132,87 @@
131
132
  # define MUL_OVERFLOW_LONG_P(a, b) MUL_OVERFLOW_SIGNED_INTEGER_P(a, b, LONG_MIN, LONG_MAX)
132
133
  # define MUL_OVERFLOW_INT_P(a, b) MUL_OVERFLOW_SIGNED_INTEGER_P(a, b, INT_MIN, INT_MAX)
133
134
  #endif
135
+ #endif
136
+
137
+ #ifndef ADD_OVERFLOW_SIGNED_INTEGER_P
138
+ #if __has_builtin(__builtin_add_overflow_p)
139
+ # define ADD_OVERFLOW_P(a, b) \
140
+ __builtin_add_overflow_p((a), (b), (__typeof__(a * b))0)
141
+ #elif __has_builtin(__builtin_add_overflow)
142
+ # define ADD_OVERFLOW_P(a, b) \
143
+ __extension__ ({ __typeof__(a) c; __builtin_add_overflow((a), (b), &c); })
144
+ #endif
145
+
146
+ #define ADD_OVERFLOW_SIGNED_INTEGER_P(a, b, min, max) ( \
147
+ (a) > 0 ? (b) > (max) - (a) : (b) < (min) - (a))
148
+
149
+ #if __has_builtin(__builtin_add_overflow_p)
150
+ /* __builtin_add_overflow_p can take bitfield */
151
+ /* and GCC permits bitfields for integers other than int */
152
+ # define ADD_OVERFLOW_FIXNUM_P(a, b) \
153
+ __extension__ ({ \
154
+ struct { long fixnum : sizeof(long) * CHAR_BIT - 1; } c = { 0 }; \
155
+ __builtin_add_overflow_p((a), (b), c.fixnum); \
156
+ })
157
+ #else
158
+ # define ADD_OVERFLOW_FIXNUM_P(a, b) \
159
+ ADD_OVERFLOW_SIGNED_INTEGER_P(a, b, FIXNUM_MIN, FIXNUM_MAX)
160
+ #endif
161
+
162
+ #if defined(ADD_OVERFLOW_P) && defined(USE___BUILTIN_ADD_OVERFLOW_LONG_LONG)
163
+ # define ADD_OVERFLOW_LONG_LONG_P(a, b) ADD_OVERFLOW_P(a, b)
164
+ #else
165
+ # define ADD_OVERFLOW_LONG_LONG_P(a, b) ADD_OVERFLOW_SIGNED_INTEGER_P(a, b, LLONG_MIN, LLONG_MAX)
166
+ #endif
167
+
168
+ #ifdef ADD_OVERFLOW_P
169
+ # define ADD_OVERFLOW_LONG_P(a, b) ADD_OVERFLOW_P(a, b)
170
+ # define ADD_OVERFLOW_INT_P(a, b) ADD_OVERFLOW_P(a, b)
171
+ #else
172
+ # define ADD_OVERFLOW_LONG_P(a, b) ADD_OVERFLOW_SIGNED_INTEGER_P(a, b, LONG_MIN, LONG_MAX)
173
+ # define ADD_OVERFLOW_INT_P(a, b) ADD_OVERFLOW_SIGNED_INTEGER_P(a, b, INT_MIN, INT_MAX)
174
+ #endif
175
+ #endif
176
+
177
+ #ifndef SUB_OVERFLOW_SIGNED_INTEGER_P
178
+ #if __has_builtin(__builtin_sub_overflow_p)
179
+ # define SUB_OVERFLOW_P(a, b) \
180
+ __builtin_sub_overflow_p((a), (b), (__typeof__(a * b))0)
181
+ #elif __has_builtin(__builtin_sub_overflow)
182
+ # define SUB_OVERFLOW_P(a, b) \
183
+ __extension__ ({ __typeof__(a) c; __builtin_sub_overflow((a), (b), &c); })
184
+ #endif
185
+
186
+ #define SUB_OVERFLOW_SIGNED_INTEGER_P(a, b, min, max) ( \
187
+ (b) > 0 ? (a) < (min) + (b) : (a) > (max) + (b))
188
+
189
+ #if __has_builtin(__builtin_sub_overflow_p)
190
+ /* __builtin_sub_overflow_p can take bitfield */
191
+ /* and GCC permits bitfields for integers other than int */
192
+ # define SUB_OVERFLOW_FIXNUM_P(a, b) \
193
+ __extension__ ({ \
194
+ struct { long fixnum : sizeof(long) * CHAR_BIT - 1; } c = { 0 }; \
195
+ __builtin_sub_overflow_p((a), (b), c.fixnum); \
196
+ })
197
+ #else
198
+ # define SUB_OVERFLOW_FIXNUM_P(a, b) \
199
+ SUB_OVERFLOW_SIGNED_INTEGER_P(a, b, FIXNUM_MIN, FIXNUM_MAX)
200
+ #endif
201
+
202
+ #if defined(SUB_OVERFLOW_P) && defined(USE___BUILTIN_SUB_OVERFLOW_LONG_LONG)
203
+ # define SUB_OVERFLOW_LONG_LONG_P(a, b) SUB_OVERFLOW_P(a, b)
204
+ #else
205
+ # define SUB_OVERFLOW_LONG_LONG_P(a, b) SUB_OVERFLOW_SIGNED_INTEGER_P(a, b, LLONG_MIN, LLONG_MAX)
206
+ #endif
207
+
208
+ #ifdef SUB_OVERFLOW_P
209
+ # define SUB_OVERFLOW_LONG_P(a, b) SUB_OVERFLOW_P(a, b)
210
+ # define SUB_OVERFLOW_INT_P(a, b) SUB_OVERFLOW_P(a, b)
211
+ #else
212
+ # define SUB_OVERFLOW_LONG_P(a, b) SUB_OVERFLOW_SIGNED_INTEGER_P(a, b, LONG_MIN, LONG_MAX)
213
+ # define SUB_OVERFLOW_INT_P(a, b) SUB_OVERFLOW_SIGNED_INTEGER_P(a, b, INT_MIN, INT_MAX)
214
+ #endif
215
+ #endif
134
216
 
135
217
  #ifdef HAVE_UINT128_T
136
218
  # define bit_length(x) \
@@ -11,7 +11,6 @@
11
11
  #include "ruby/ruby.h" /* for ID */
12
12
  #include "ruby/encoding.h" /* for rb_encoding */
13
13
 
14
- #define rb_enc_autoload_p(enc) (!rb_enc_mbmaxlen(enc))
15
14
  #define rb_is_usascii_enc(enc) ((enc) == rb_usascii_encoding())
16
15
  #define rb_is_ascii8bit_enc(enc) ((enc) == rb_ascii8bit_encoding())
17
16
  #define rb_is_locale_enc(enc) ((enc) == rb_locale_encoding())
@@ -24,10 +23,14 @@ rb_encoding *rb_enc_check_str(VALUE str1, VALUE str2);
24
23
  int rb_encdb_replicate(const char *alias, const char *orig);
25
24
  int rb_encdb_alias(const char *alias, const char *orig);
26
25
  int rb_enc_autoload(rb_encoding *enc);
26
+ bool rb_enc_autoload_p(rb_encoding *enc);
27
27
  int rb_encdb_dummy(const char *name);
28
28
  void rb_encdb_declare(const char *name);
29
29
  void rb_enc_set_base(const char *name, const char *orig);
30
30
  int rb_enc_set_dummy(int index);
31
+ void rb_enc_raw_set(VALUE obj, rb_encoding *enc);
32
+ int rb_enc_registered(const char *name);
33
+
31
34
  PUREFUNC(int rb_data_is_encoding(VALUE obj));
32
35
 
33
36
  /* vm.c */
@@ -72,6 +72,7 @@ const char *rb_builtin_type_name(int t);
72
72
  const char *rb_builtin_class_name(VALUE x);
73
73
  PRINTF_ARGS(void rb_warn_deprecated(const char *fmt, const char *suggest, ...), 1, 3);
74
74
  PRINTF_ARGS(void rb_warn_deprecated_to_remove(const char *removal, const char *fmt, const char *suggest, ...), 2, 4);
75
+ PRINTF_ARGS(void rb_warn_reserved_name(const char *removal, const char *fmt, ...), 2, 3);
75
76
  #if RUBY_DEBUG
76
77
  # include "ruby/version.h"
77
78
  # define RUBY_VERSION_SINCE(major, minor) (RUBY_API_VERSION_CODE >= (major * 10000) + (minor) * 100)
@@ -110,6 +111,14 @@ rb_deprecated_method_to_be_removed(const char *removal)
110
111
  RBIMPL_ATTR_DIAGNOSE_IF(RUBY_VERSION_STRING_SINCE(removal), "deprecated method to be removed", "error")
111
112
  {
112
113
  }
114
+
115
+ RBIMPL_ATTR_FORCEINLINE()
116
+ static void
117
+ rb_diagnose_reserved_name_at(const char *coming)
118
+ RBIMPL_ATTR_DIAGNOSE_IF(!RUBY_VERSION_isdigit(coming[0]), "malformed version number", "error")
119
+ RBIMPL_ATTR_DIAGNOSE_IF(RUBY_VERSION_STRING_SINCE(coming), "reserved name already in use", "error")
120
+ {
121
+ }
113
122
  # else
114
123
  RBIMPL_ATTR_ERROR(("deprecated"))
115
124
  void rb_deprecated_method_to_be_removed(const char *);
@@ -117,16 +126,32 @@ void rb_deprecated_method_to_be_removed(const char *);
117
126
  (sizeof(char[1-2*(!RUBY_VERSION_isdigit(removal[0]) || RUBY_VERSION_STRING_SINCE(removal))])!=1 ? \
118
127
  rb_deprecated_method_to_be_removed(removal) : \
119
128
  RBIMPL_ASSERT_NOTHING)
129
+
130
+ RBIMPL_ATTR_ERROR(("deprecated"))
131
+ void rb_diagnose_reserved_name_at(const char *);
132
+ # define rb_diagnose_reserved_name_at(coming) \
133
+ (sizeof(char[1-2*(!RUBY_VERSION_isdigit(coming[0]) || RUBY_VERSION_STRING_SINCE(coming))])!=1 ? \
134
+ rb_diagnose_reserved_name_at(coming) : \
135
+ RBIMPL_ASSERT_NOTHING)
136
+
120
137
  # endif
121
138
  # define rb_warn_deprecated_to_remove_at(removal, ...) \
122
139
  (rb_deprecated_method_to_be_removed(#removal), \
123
140
  rb_warn_deprecated_to_remove(#removal, __VA_ARGS__))
141
+
142
+ # define rb_warn_reserved_name_at(coming, ...) \
143
+ (rb_diagnose_reserved_name_at(#coming), \
144
+ rb_warn_reserved_name(#coming, __VA_ARGS__))
124
145
  # endif
125
146
  #endif
126
147
  #ifndef rb_warn_deprecated_to_remove_at
127
148
  # define rb_warn_deprecated_to_remove_at(removal, ...) \
128
149
  rb_warn_deprecated_to_remove(#removal, __VA_ARGS__)
129
150
  #endif
151
+ #ifndef rb_warn_reserved_name_at
152
+ # define rb_warn_reserved_name_at(removal, ...) \
153
+ rb_warn_reserved_name(#removal, __VA_ARGS__)
154
+ #endif
130
155
  #ifndef RUBY_VERSION_SINCE
131
156
  # define RUBY_VERSION_SINCE(major, minor) 0
132
157
  #endif
@@ -160,6 +185,7 @@ NORETURN(static inline void rb_key_err_raise(VALUE mesg, VALUE recv, VALUE name)
160
185
  static inline void Check_Type(VALUE v, enum ruby_value_type t);
161
186
  static inline bool rb_typeddata_is_instance_of_inline(VALUE obj, const rb_data_type_t *data_type);
162
187
  #define rb_typeddata_is_instance_of rb_typeddata_is_instance_of_inline
188
+ void rb_bug_without_die(const char *fmt, ...);
163
189
 
164
190
  RUBY_SYMBOL_EXPORT_BEGIN
165
191
  /* error.c (export) */
@@ -215,4 +241,11 @@ rb_typeddata_is_instance_of_inline(VALUE obj, const rb_data_type_t *data_type)
215
241
  return RB_TYPE_P(obj, T_DATA) && RTYPEDDATA_P(obj) && (RTYPEDDATA_TYPE(obj) == data_type);
216
242
  }
217
243
 
244
+ typedef enum {
245
+ rb_stack_overflow_prevention = 0, // VM stack overflow or about to machine stack overflow
246
+ rb_stack_overflow_signal = 1, // machine stack overflow but may be recoverable
247
+ rb_stack_overflow_fatal = 2, // fatal machine stack overflow
248
+ } ruby_stack_overflow_critical_level;
249
+ NORETURN(void rb_ec_stack_overflow(struct rb_execution_context_struct *ec, ruby_stack_overflow_critical_level crit));
250
+
218
251
  #endif /* INTERNAL_ERROR_H */
@@ -10,6 +10,7 @@
10
10
  */
11
11
  #include "ruby/internal/config.h" /* for HAVE_LONG_LONG */
12
12
  #include <limits.h> /* for CHAR_BIT */
13
+ #include "internal/bits.h" /* for MUL_OVERFLOW_FIXNUM_P */
13
14
  #include "internal/compilers.h" /* for __has_builtin */
14
15
  #include "ruby/internal/stdbool.h" /* for bool */
15
16
  #include "ruby/intern.h" /* for rb_big_mul */
@@ -16,8 +16,8 @@
16
16
  #include "ruby/ruby.h" /* for rb_event_flag_t */
17
17
  #include "vm_core.h" /* for GET_EC() */
18
18
 
19
- #ifndef USE_SHARED_GC
20
- # define USE_SHARED_GC 0
19
+ #ifndef USE_MODULAR_GC
20
+ # define USE_MODULAR_GC 0
21
21
  #endif
22
22
 
23
23
  #if defined(__x86_64__) && !defined(_ILP32) && defined(__GNUC__)
@@ -127,7 +127,13 @@ struct rb_objspace; /* in vm_core.h */
127
127
  rb_wb_protected_newobj_of((ec ? ec : GET_EC()), (c), (f) & ~FL_WB_PROTECTED, s) : \
128
128
  rb_wb_unprotected_newobj_of((c), (f), s))
129
129
 
130
- #define RB_OBJ_GC_FLAGS_MAX 6 /* used in ext/objspace */
130
+ #ifndef RB_GC_OBJECT_METADATA_ENTRY_DEFINED
131
+ # define RB_GC_OBJECT_METADATA_ENTRY_DEFINED
132
+ struct rb_gc_object_metadata_entry {
133
+ ID name;
134
+ VALUE val;
135
+ };
136
+ #endif
131
137
 
132
138
  #ifndef USE_UNALIGNED_MEMBER_ACCESS
133
139
  # define UNALIGNED_MEMBER_ACCESS(expr) (expr)
@@ -175,7 +181,6 @@ struct rb_objspace; /* in vm_core.h */
175
181
  if (_already_disabled == Qfalse) rb_gc_enable()
176
182
 
177
183
  /* gc.c */
178
- extern int ruby_disable_gc;
179
184
  RUBY_ATTR_MALLOC void *ruby_mimmalloc(size_t size);
180
185
  RUBY_ATTR_MALLOC void *ruby_mimcalloc(size_t num, size_t size);
181
186
  void ruby_mimfree(void *ptr);
@@ -196,13 +201,14 @@ RUBY_ATTR_MALLOC void *rb_xcalloc_mul_add_mul(size_t, size_t, size_t, size_t);
196
201
  static inline void *ruby_sized_xrealloc_inlined(void *ptr, size_t new_size, size_t old_size) RUBY_ATTR_RETURNS_NONNULL RUBY_ATTR_ALLOC_SIZE((2));
197
202
  static inline void *ruby_sized_xrealloc2_inlined(void *ptr, size_t new_count, size_t elemsiz, size_t old_count) RUBY_ATTR_RETURNS_NONNULL RUBY_ATTR_ALLOC_SIZE((2, 3));
198
203
  static inline void ruby_sized_xfree_inlined(void *ptr, size_t size);
204
+ void rb_gc_obj_id_moved(VALUE obj);
199
205
 
200
- void *rb_gc_ractor_cache_alloc(void);
206
+ void *rb_gc_ractor_cache_alloc(rb_ractor_t *ractor);
201
207
  void rb_gc_ractor_cache_free(void *cache);
202
208
 
203
209
  bool rb_gc_size_allocatable_p(size_t size);
204
- size_t *rb_gc_size_pool_sizes(void);
205
- size_t rb_gc_size_pool_id_for_size(size_t size);
210
+ size_t *rb_gc_heap_sizes(void);
211
+ size_t rb_gc_heap_id_for_size(size_t size);
206
212
 
207
213
  void rb_gc_mark_and_move(VALUE *ptr);
208
214
 
@@ -213,6 +219,9 @@ void rb_gc_ref_update_table_values_only(st_table *tbl);
213
219
 
214
220
  void rb_gc_initial_stress_set(VALUE flag);
215
221
 
222
+ void rb_gc_before_fork(void);
223
+ void rb_gc_after_fork(rb_pid_t pid);
224
+
216
225
  #define rb_gc_mark_and_move_ptr(ptr) do { \
217
226
  VALUE _obj = (VALUE)*(ptr); \
218
227
  rb_gc_mark_and_move(&_obj); \
@@ -225,6 +234,7 @@ void rb_objspace_reachable_objects_from(VALUE obj, void (func)(VALUE, void *), v
225
234
  void rb_objspace_reachable_objects_from_root(void (func)(const char *category, VALUE, void *), void *data);
226
235
  int rb_objspace_internal_object_p(VALUE obj);
227
236
  int rb_objspace_garbage_object_p(VALUE obj);
237
+ bool rb_gc_pointer_to_heap_p(VALUE obj);
228
238
 
229
239
  void rb_objspace_each_objects(
230
240
  int (*callback)(void *start, void *end, size_t stride, void *data),
@@ -234,13 +244,14 @@ size_t rb_gc_obj_slot_size(VALUE obj);
234
244
 
235
245
  VALUE rb_gc_disable_no_rest(void);
236
246
 
247
+ #define RB_GC_MAX_NAME_LEN 20
237
248
 
238
249
  /* gc.c (export) */
239
250
  const char *rb_objspace_data_type_name(VALUE obj);
240
251
  VALUE rb_wb_protected_newobj_of(struct rb_execution_context_struct *, VALUE, VALUE, size_t);
241
252
  VALUE rb_wb_unprotected_newobj_of(VALUE, VALUE, size_t);
242
253
  size_t rb_obj_memsize_of(VALUE);
243
- size_t rb_obj_gc_flags(VALUE, ID[], size_t);
254
+ struct rb_gc_object_metadata_entry *rb_gc_object_metadata(VALUE obj);
244
255
  void rb_gc_mark_values(long n, const VALUE *values);
245
256
  void rb_gc_mark_vm_stack_values(long n, const VALUE *values);
246
257
  void rb_gc_update_values(long n, VALUE *values);
@@ -248,14 +259,35 @@ void *ruby_sized_xrealloc(void *ptr, size_t new_size, size_t old_size) RUBY_ATTR
248
259
  void *ruby_sized_xrealloc2(void *ptr, size_t new_count, size_t element_size, size_t old_count) RUBY_ATTR_RETURNS_NONNULL RUBY_ATTR_ALLOC_SIZE((2, 3));
249
260
  void ruby_sized_xfree(void *x, size_t size);
250
261
 
251
- #if USE_SHARED_GC
252
- void ruby_load_external_gc_from_argv(int argc, char **argv);
253
- #endif
262
+ const char *rb_gc_active_gc_name(void);
263
+ int rb_gc_modular_gc_loaded_p(void);
264
+
254
265
  RUBY_SYMBOL_EXPORT_END
255
266
 
267
+ static inline VALUE
268
+ rb_obj_atomic_write(
269
+ VALUE a, VALUE *slot, VALUE b,
270
+ RBIMPL_ATTR_MAYBE_UNUSED()
271
+ const char *filename,
272
+ RBIMPL_ATTR_MAYBE_UNUSED()
273
+ int line)
274
+ {
275
+ #ifdef RGENGC_LOGGING_WRITE
276
+ RGENGC_LOGGING_WRITE(a, slot, b, filename, line);
277
+ #endif
278
+
279
+ RUBY_ATOMIC_VALUE_SET(*slot, b);
280
+
281
+ rb_obj_written(a, RUBY_Qundef /* ignore `oldv' now */, b, filename, line);
282
+ return a;
283
+ }
284
+ #define RB_OBJ_ATOMIC_WRITE(old, slot, young) \
285
+ RBIMPL_CAST(rb_obj_atomic_write((VALUE)(old), (VALUE *)(slot), (VALUE)(young), __FILE__, __LINE__))
286
+
256
287
  int rb_ec_stack_check(struct rb_execution_context_struct *ec);
257
288
  void rb_gc_writebarrier_remember(VALUE obj);
258
289
  const char *rb_obj_info(VALUE obj);
290
+ void ruby_annotate_mmap(const void *addr, unsigned long size, const char *name);
259
291
 
260
292
  #if defined(HAVE_MALLOC_USABLE_SIZE) || defined(HAVE_MALLOC_SIZE) || defined(_WIN32)
261
293
 
@@ -319,4 +351,8 @@ ruby_sized_realloc_n(void *ptr, size_t new_count, size_t element_size, size_t ol
319
351
  #define ruby_sized_xrealloc ruby_sized_xrealloc_inlined
320
352
  #define ruby_sized_xrealloc2 ruby_sized_xrealloc2_inlined
321
353
  #define ruby_sized_xfree ruby_sized_xfree_inlined
354
+
355
+ void rb_gc_verify_shareable(VALUE);
356
+ bool rb_gc_checking_shareable(void);
357
+
322
358
  #endif /* INTERNAL_GC_H */
@@ -72,6 +72,7 @@ struct RHash {
72
72
  /* hash.c */
73
73
  void rb_hash_st_table_set(VALUE hash, st_table *st);
74
74
  VALUE rb_hash_default_value(VALUE hash, VALUE key);
75
+ VALUE rb_hash_set_default(VALUE hash, VALUE ifnone);
75
76
  VALUE rb_hash_set_default_proc(VALUE hash, VALUE proc);
76
77
  long rb_dbl_long_hash(double d);
77
78
  st_table *rb_init_identtable(void);
@@ -86,8 +87,10 @@ VALUE rb_hash_set_pair(VALUE hash, VALUE pair);
86
87
  int rb_hash_stlike_delete(VALUE hash, st_data_t *pkey, st_data_t *pval);
87
88
  int rb_hash_stlike_foreach_with_replace(VALUE hash, st_foreach_check_callback_func *func, st_update_callback_func *replace, st_data_t arg);
88
89
  int rb_hash_stlike_update(VALUE hash, st_data_t key, st_update_callback_func *func, st_data_t arg);
90
+ bool rb_hash_default_unredefined(VALUE hash);
89
91
  VALUE rb_ident_hash_new_with_size(st_index_t size);
90
92
  void rb_hash_free(VALUE hash);
93
+ RUBY_EXTERN VALUE rb_cHash_empty_frozen;
91
94
 
92
95
  static inline unsigned RHASH_AR_TABLE_SIZE_RAW(VALUE h);
93
96
  static inline VALUE RHASH_IFNONE(VALUE h);
@@ -10,14 +10,11 @@
10
10
  */
11
11
  #include "ruby/internal/config.h"
12
12
  #include <stddef.h> /* for size_t */
13
+ #include "id_table.h"
13
14
  #include "internal/array.h" /* for rb_ary_hidden_new_fill */
14
15
  #include "ruby/internal/stdbool.h" /* for bool */
15
16
  #include "ruby/ruby.h" /* for rb_block_call_func_t */
16
17
 
17
- #ifndef IMEMO_DEBUG
18
- # define IMEMO_DEBUG 0
19
- #endif
20
-
21
18
  #define IMEMO_MASK 0x0f
22
19
 
23
20
  /* FL_USER0 to FL_USER3 is for type */
@@ -28,6 +25,7 @@
28
25
  #define IMEMO_FL_USER3 FL_USER7
29
26
  #define IMEMO_FL_USER4 FL_USER8
30
27
  #define IMEMO_FL_USER5 FL_USER9
28
+ #define IMEMO_FL_USER6 FL_USER10
31
29
 
32
30
  enum imemo_type {
33
31
  imemo_env = 0,
@@ -39,11 +37,10 @@ enum imemo_type {
39
37
  imemo_ment = 6,
40
38
  imemo_iseq = 7,
41
39
  imemo_tmpbuf = 8,
42
- imemo_ast = 9, // Obsolete due to the universal parser
43
- imemo_parser_strterm = 10,
44
- imemo_callinfo = 11,
45
- imemo_callcache = 12,
46
- imemo_constcache = 13,
40
+ imemo_callinfo = 10,
41
+ imemo_callcache = 11,
42
+ imemo_constcache = 12,
43
+ imemo_fields = 13,
47
44
  };
48
45
 
49
46
  /* CREF (Class REFerence) is defined in method.h */
@@ -79,7 +76,12 @@ struct vm_ifunc_argc {
79
76
  #endif
80
77
  };
81
78
 
82
- /*! IFUNC (Internal FUNCtion) */
79
+ /*! IFUNC (Internal FUNCtion)
80
+ *
81
+ * Bookkeeping for converting a C function and some closed-over data into a
82
+ * block passable to methods. Like Ruby Proc, but not directly accessible at
83
+ * Ruby level since this is an imemo. See rb_block_call() and friends.
84
+ */
83
85
  struct vm_ifunc {
84
86
  VALUE flags;
85
87
  VALUE *svar_lep;
@@ -91,9 +93,7 @@ struct vm_ifunc {
91
93
 
92
94
  struct rb_imemo_tmpbuf_struct {
93
95
  VALUE flags;
94
- VALUE reserved;
95
96
  VALUE *ptr; /* malloc'ed buffer */
96
- struct rb_imemo_tmpbuf_struct *next; /* next imemo */
97
97
  size_t cnt; /* buffer size in VALUE */
98
98
  };
99
99
 
@@ -114,7 +114,8 @@ struct MEMO {
114
114
  } u3;
115
115
  };
116
116
 
117
- #define IMEMO_NEW(T, type, v0) ((T *)rb_imemo_new((type), (v0)))
117
+ #define IMEMO_NEW(T, type, v0) ((T *)rb_imemo_new((type), (v0), sizeof(T), false))
118
+ #define SHAREABLE_IMEMO_NEW(T, type, v0) ((T *)rb_imemo_new((type), (v0), sizeof(T), true))
118
119
 
119
120
  /* ment is in method.h */
120
121
 
@@ -131,32 +132,23 @@ struct MEMO {
131
132
  #ifndef RUBY_RUBYPARSER_H
132
133
  typedef struct rb_imemo_tmpbuf_struct rb_imemo_tmpbuf_t;
133
134
  #endif
134
- rb_imemo_tmpbuf_t *rb_imemo_tmpbuf_parser_heap(void *buf, rb_imemo_tmpbuf_t *old_heap, size_t cnt);
135
+ VALUE rb_imemo_new(enum imemo_type type, VALUE v0, size_t size, bool is_shareable);
136
+ VALUE rb_imemo_tmpbuf_new(void);
135
137
  struct vm_ifunc *rb_vm_ifunc_new(rb_block_call_func_t func, const void *data, int min_argc, int max_argc);
136
138
  static inline enum imemo_type imemo_type(VALUE imemo);
137
139
  static inline int imemo_type_p(VALUE imemo, enum imemo_type imemo_type);
138
140
  static inline bool imemo_throw_data_p(VALUE imemo);
139
141
  static inline struct vm_ifunc *rb_vm_ifunc_proc_new(rb_block_call_func_t func, const void *data);
140
- static inline VALUE rb_imemo_tmpbuf_auto_free_pointer(void);
141
142
  static inline void *RB_IMEMO_TMPBUF_PTR(VALUE v);
142
143
  static inline void *rb_imemo_tmpbuf_set_ptr(VALUE v, void *ptr);
143
- static inline VALUE rb_imemo_tmpbuf_auto_free_pointer_new_from_an_RString(VALUE str);
144
144
  static inline void MEMO_V1_SET(struct MEMO *m, VALUE v);
145
145
  static inline void MEMO_V2_SET(struct MEMO *m, VALUE v);
146
146
 
147
147
  size_t rb_imemo_memsize(VALUE obj);
148
- void rb_cc_table_mark(VALUE klass);
149
148
  void rb_imemo_mark_and_move(VALUE obj, bool reference_updating);
150
- void rb_cc_table_free(VALUE klass);
151
149
  void rb_imemo_free(VALUE obj);
152
150
 
153
151
  RUBY_SYMBOL_EXPORT_BEGIN
154
- #if IMEMO_DEBUG
155
- VALUE rb_imemo_new_debug(enum imemo_type type, VALUE v0, const char *file, int line);
156
- #define rb_imemo_new(type, v1, v2, v3, v0) rb_imemo_new_debug(type, v1, v2, v3, v0, __FILE__, __LINE__)
157
- #else
158
- VALUE rb_imemo_new(enum imemo_type type, VALUE v0);
159
- #endif
160
152
  const char *rb_imemo_name(enum imemo_type type);
161
153
  RUBY_SYMBOL_EXPORT_END
162
154
 
@@ -206,12 +198,6 @@ rb_vm_ifunc_proc_new(rb_block_call_func_t func, const void *data)
206
198
  return rb_vm_ifunc_new(func, data, 0, UNLIMITED_ARGUMENTS);
207
199
  }
208
200
 
209
- static inline VALUE
210
- rb_imemo_tmpbuf_auto_free_pointer(void)
211
- {
212
- return rb_imemo_new(imemo_tmpbuf, 0);
213
- }
214
-
215
201
  static inline void *
216
202
  RB_IMEMO_TMPBUF_PTR(VALUE v)
217
203
  {
@@ -226,7 +212,7 @@ rb_imemo_tmpbuf_set_ptr(VALUE v, void *ptr)
226
212
  }
227
213
 
228
214
  static inline VALUE
229
- rb_imemo_tmpbuf_auto_free_pointer_new_from_an_RString(VALUE str)
215
+ rb_imemo_tmpbuf_new_from_an_RString(VALUE str)
230
216
  {
231
217
  const void *src;
232
218
  VALUE imemo;
@@ -236,7 +222,7 @@ rb_imemo_tmpbuf_auto_free_pointer_new_from_an_RString(VALUE str)
236
222
 
237
223
  StringValue(str);
238
224
  /* create tmpbuf to keep the pointer before xmalloc */
239
- imemo = rb_imemo_tmpbuf_auto_free_pointer();
225
+ imemo = rb_imemo_tmpbuf_new();
240
226
  tmpbuf = (rb_imemo_tmpbuf_t *)imemo;
241
227
  len = RSTRING_LEN(str);
242
228
  src = RSTRING_PTR(str);
@@ -258,4 +244,79 @@ MEMO_V2_SET(struct MEMO *m, VALUE v)
258
244
  RB_OBJ_WRITE(m, &m->v2, v);
259
245
  }
260
246
 
247
+ struct rb_fields {
248
+ struct RBasic basic;
249
+ union {
250
+ struct {
251
+ VALUE fields[1];
252
+ } embed;
253
+ struct {
254
+ VALUE *ptr;
255
+ } external;
256
+ struct {
257
+ // Note: the st_table could be embedded, but complex T_CLASS should be rare to
258
+ // non-existent, so not really worth the trouble.
259
+ st_table *table;
260
+ } complex;
261
+ } as;
262
+ };
263
+
264
+ // IMEMO/fields and T_OBJECT have exactly the same layout.
265
+ // This is useful for JIT and common codepaths.
266
+ #define OBJ_FIELD_HEAP ROBJECT_HEAP
267
+ STATIC_ASSERT(imemo_fields_flags, OBJ_FIELD_HEAP == IMEMO_FL_USER0);
268
+ STATIC_ASSERT(imemo_fields_embed_offset, offsetof(struct RObject, as.ary) == offsetof(struct rb_fields, as.embed.fields));
269
+ STATIC_ASSERT(imemo_fields_embed_offset, offsetof(struct RObject, as.heap.fields) == offsetof(struct rb_fields, as.external.ptr));
270
+ STATIC_ASSERT(imemo_fields_embed_offset, offsetof(struct RObject, as.heap.fields) == offsetof(struct rb_fields, as.complex.table));
271
+
272
+ #define IMEMO_OBJ_FIELDS(fields) ((struct rb_fields *)fields)
273
+
274
+ VALUE rb_imemo_fields_new(VALUE owner, size_t capa, bool shareable);
275
+ VALUE rb_imemo_fields_new_complex(VALUE owner, size_t capa, bool shareable);
276
+ VALUE rb_imemo_fields_new_complex_tbl(VALUE owner, st_table *tbl, bool shareable);
277
+ VALUE rb_imemo_fields_clone(VALUE fields_obj);
278
+ void rb_imemo_fields_clear(VALUE fields_obj);
279
+
280
+ static inline VALUE
281
+ rb_imemo_fields_owner(VALUE fields_obj)
282
+ {
283
+ RUBY_ASSERT(IMEMO_TYPE_P(fields_obj, imemo_fields));
284
+
285
+ return CLASS_OF(fields_obj);
286
+ }
287
+
288
+ static inline VALUE *
289
+ rb_imemo_fields_ptr(VALUE fields_obj)
290
+ {
291
+ if (!fields_obj) {
292
+ return NULL;
293
+ }
294
+
295
+ RUBY_ASSERT(IMEMO_TYPE_P(fields_obj, imemo_fields) || RB_TYPE_P(fields_obj, T_OBJECT));
296
+
297
+ if (UNLIKELY(FL_TEST_RAW(fields_obj, OBJ_FIELD_HEAP))) {
298
+ return IMEMO_OBJ_FIELDS(fields_obj)->as.external.ptr;
299
+ }
300
+ else {
301
+ return IMEMO_OBJ_FIELDS(fields_obj)->as.embed.fields;
302
+ }
303
+ }
304
+
305
+ static inline st_table *
306
+ rb_imemo_fields_complex_tbl(VALUE fields_obj)
307
+ {
308
+ if (!fields_obj) {
309
+ return NULL;
310
+ }
311
+
312
+ RUBY_ASSERT(IMEMO_TYPE_P(fields_obj, imemo_fields) || RB_TYPE_P(fields_obj, T_OBJECT));
313
+ RUBY_ASSERT(FL_TEST_RAW(fields_obj, OBJ_FIELD_HEAP));
314
+
315
+ // Some codepaths unconditionally access the fields_ptr, and assume it can be used as st_table if the
316
+ // shape is too_complex.
317
+ RUBY_ASSERT((st_table *)rb_imemo_fields_ptr(fields_obj) == IMEMO_OBJ_FIELDS(fields_obj)->as.complex.table);
318
+
319
+ return IMEMO_OBJ_FIELDS(fields_obj)->as.complex.table;
320
+ }
321
+
261
322
  #endif /* INTERNAL_IMEMO_H */
@@ -14,10 +14,21 @@
14
14
  struct rb_io;
15
15
 
16
16
  #include "ruby/io.h" /* for rb_io_t */
17
+ #include "ccan/list/list.h"
18
+ #include "serial.h"
17
19
 
18
- #define IO_WITHOUT_GVL(func, arg) rb_thread_call_without_gvl(func, arg, RUBY_UBF_IO, 0)
20
+ #define IO_WITHOUT_GVL(func, arg) rb_nogvl(func, arg, RUBY_UBF_IO, 0, RB_NOGVL_OFFLOAD_SAFE)
19
21
  #define IO_WITHOUT_GVL_INT(func, arg) (int)(VALUE)IO_WITHOUT_GVL(func, arg)
20
22
 
23
+ // Represents an in-flight blocking operation:
24
+ struct rb_io_blocking_operation {
25
+ // The linked list data structure.
26
+ struct ccan_list_node list;
27
+
28
+ // The execution context of the blocking operation.
29
+ struct rb_execution_context_struct *ec;
30
+ };
31
+
21
32
  /** Ruby's IO, metadata and buffers. */
22
33
  struct rb_io {
23
34
 
@@ -31,7 +42,7 @@ struct rb_io {
31
42
  int fd;
32
43
 
33
44
  /** mode flags: FMODE_XXXs */
34
- int mode;
45
+ enum rb_io_mode mode;
35
46
 
36
47
  /** child's pid (for pipes) */
37
48
  rb_pid_t pid;
@@ -111,6 +122,18 @@ struct rb_io {
111
122
  * The timeout associated with this IO when performing blocking operations.
112
123
  */
113
124
  VALUE timeout;
125
+
126
+ /**
127
+ * Threads that are performing a blocking operation without the GVL using
128
+ * this IO. On calling IO#close, these threads will be interrupted so that
129
+ * the operation can be cancelled.
130
+ */
131
+ struct ccan_list_head blocking_operations;
132
+ struct rb_execution_context_struct *closing_ec;
133
+ VALUE wakeup_mutex;
134
+
135
+ // The fork generation of the blocking operations list.
136
+ rb_serial_t fork_generation;
114
137
  };
115
138
 
116
139
  /* io.c */
@@ -119,22 +142,22 @@ void rb_stdio_set_default_encoding(void);
119
142
  VALUE rb_io_flush_raw(VALUE, int);
120
143
  size_t rb_io_memsize(const rb_io_t *);
121
144
  int rb_stderr_tty_p(void);
122
- void rb_io_fptr_finalize_internal(void *ptr);
123
- #ifdef rb_io_fptr_finalize
124
- # undef rb_io_fptr_finalize
125
- #endif
126
- #define rb_io_fptr_finalize rb_io_fptr_finalize_internal
127
145
  VALUE rb_io_popen(VALUE pname, VALUE pmode, VALUE env, VALUE opt);
128
146
 
129
147
  VALUE rb_io_prep_stdin(void);
130
148
  VALUE rb_io_prep_stdout(void);
131
149
  VALUE rb_io_prep_stderr(void);
132
150
 
151
+ int rb_io_notify_close(struct rb_io *fptr);
152
+
133
153
  RUBY_SYMBOL_EXPORT_BEGIN
134
154
  /* io.c (export) */
135
155
  void rb_maygvl_fd_fix_cloexec(int fd);
136
156
  int rb_gc_for_fd(int err);
137
157
  void rb_write_error_str(VALUE mesg);
158
+
159
+ VALUE rb_io_blocking_region_wait(struct rb_io *io, rb_blocking_function_t *function, void *argument, enum rb_io_event events);
160
+ VALUE rb_io_blocking_region(struct rb_io *io, rb_blocking_function_t *function, void *argument);
138
161
  RUBY_SYMBOL_EXPORT_END
139
162
 
140
163
  #endif /* INTERNAL_IO_H */