bootsnap 1.8.1 → 1.12.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4565db3033321cbf9866e33e0d42021d76f164974154bfb62dc9bcb02082763c
4
- data.tar.gz: 48424a914d66bebe2029e2bbdb86aef1c0d684a9a773f219a54b4c2675aec0b4
3
+ metadata.gz: 761e97c3b4772e9c0af1bd8391d70dddebd94addf88e9295e72a790a85deb5e0
4
+ data.tar.gz: 17f80fcf67adc6a4e7f9fb475d3e7d5c008c89b491e23804da1f2603e859888c
5
5
  SHA512:
6
- metadata.gz: 05732a91a5437872eb83b96fcf1fa2db302acf599a53ca5a25c5ef9b628eef780051173f5081261a2491798ea71a005af180504da19707a09c52692eb01d65c3
7
- data.tar.gz: b19e9db48806a6cee08f9de5268c81fb235d577e8771f6acb238843a507856cb120fce3d63bec7d4664d4c88ea60f01ebb7acd8545ffa10291a3157dd25ebf89
6
+ metadata.gz: dca99dc5e57a644e627e8705958c8c4916a9c444c2a64788fd4214aa174d6c3eed7fc15ef7bdb6e06922fb8d1eef3beeff08e316aadbc3015a36e82b1a232309
7
+ data.tar.gz: 1c9ffc9c5c04694f4838693edda976f58925649f7b14411d61bec64eca10bb04548c5bb4e2be6ff897c8d5a0e929aa2cd885d017ccd1770530971fedba831ec3
data/CHANGELOG.md CHANGED
@@ -1,12 +1,113 @@
1
1
  # Unreleased
2
2
 
3
+ # 1.12.0
4
+
5
+ * `bootsnap precompile` CLI will now also precompile `Rakefile` and `.rake` files.
6
+
7
+ * Stop decorating `Module#autoload` as it was only useful for supporting Ruby 2.2 and older.
8
+
9
+ * Remove `uname` and other patform specific version from the cache keys. `RUBY_PLATFORM + RUBY_REVISION` should be
10
+ enough to ensure bytecode compatibility. This should improve caching for alpine based setups. See #409.
11
+
12
+ # 1.11.1
13
+
14
+ * Fix the `can't modify frozen Hash` error on load path cache mutation. See #411.
15
+
16
+ # 1.11.0
17
+
18
+ * Drop dependency on `fileutils`.
19
+
20
+ * Better respect `Kernel#require` duck typing. While it almost never comes up in practice, `Kernel#require`
21
+ follow a fairly intricate duck-typing protocol on its argument implemented as `rb_get_path(VALUE)` in MRI.
22
+ So when applicable we bind `rb_get_path` and use it for improved compatibility. See #396 and #406.
23
+
24
+ * Get rid of the `Kernel.require_relative` decorator by resolving `$LOAD_PATH` members to their real path.
25
+ This way we handle symlinks in `$LOAD_PATH` much more efficiently. See #402 for the detailed explanation.
26
+
27
+ * Drop support for Ruby 2.3 (to allow getting rid of the `Kernel.require_relative` decorator).
28
+
29
+ # 1.10.3
30
+
31
+ * Fix Regexp and Date type support in YAML compile cache. (#400)
32
+
33
+ * Improve the YAML compile cache to support `UTF-8` symbols. (#398, #399)
34
+ [The default `MessagePack` symbol serializer assumes all symbols are ASCII](https://github.com/msgpack/msgpack-ruby/pull/211),
35
+ because of this, non-ASCII compatible symbol would be restored with `ASCII_8BIT` encoding (AKA `BINARY`).
36
+ Bootsnap now properly cache them in `UTF-8`.
37
+
38
+ Note that the above only apply for actual YAML symbols (e..g `--- :foo`).
39
+ The issue is still present for string keys parsed with `YAML.load_file(..., symbolize_names: true)`, that is a bug
40
+ in `msgpack` that will hopefully be solved soon, see: https://github.com/msgpack/msgpack-ruby/pull/246
41
+
42
+ * Entirely disable the YAML compile cache if `Encoding.default_internal` is set to an encoding not supported by `msgpack`. (#398)
43
+ `Psych` coerce strings to `Encoding.default_internal`, but `MessagePack` doesn't. So in this scenario we can't provide
44
+ YAML caching at all without returning the strings in the wrong encoding.
45
+ This never came up in practice but might as well be safe.
46
+
47
+ # 1.10.2
48
+
49
+ * Reduce the `Kernel.require` extra stack frames some more. Now bootsnap should only add one extra frame per `require` call.
50
+
51
+ * Better check `freeze` option support in JSON compile cache.
52
+ Previously `JSON.load_file(..., freeze: true)` would be cached even when the msgpack version is missing support for it.
53
+
54
+ # 1.10.1
55
+
56
+ * Fix `Kernel#autoload`'s fallback path always being executed.
57
+
58
+ * Consider `unlink` failing with `ENOENT` as a success.
59
+
60
+ # 1.10.0
61
+
62
+ * Delay requiring `FileUtils`. (#285)
63
+ `FileUtils` can be installed as a gem, so it's best to wait for bundler to have setup the load path before requiring it.
64
+
65
+ * Improve support of Psych 4. (#392)
66
+ Since `1.8.0`, `YAML.load_file` was no longer cached when Psych 4 was used. This is because `load_file` loads
67
+ in safe mode by default, so the Bootsnap cache could defeat that safety.
68
+ Now when precompiling YAML files, Bootsnap first try to parse them in safe mode, and if it can't fallback to unsafe mode,
69
+ and the cache contains a flag that records whether it was generated in safe mode or not.
70
+ `YAML.unsafe_load_file` will use safe caches just fine, but `YAML.load_file` will fallback to uncached YAML parsing
71
+ if the cache was generated using unsafe parsing.
72
+
73
+ * Minimize the Kernel.require extra stack frames. (#393)
74
+ This should reduce the noise generated by bootsnap on `LoadError`.
75
+
76
+ # 1.9.4
77
+
78
+ * Ignore absolute paths in the loaded feature index. (#385)
79
+ This fixes a compatibility issue with Zeitwerk when Zeitwerk is loaded before bootsnap. It also should
80
+ reduce the memory usage and improve load performance of Zeitwerk managed files.
81
+
82
+ * Automatically invalidate the load path cache whenever the Ruby version change. (#387)
83
+ This is to avoid issues in case the same installation path is re-used for subsequent ruby patch releases.
84
+
85
+ # 1.9.3
86
+
87
+ * Only disable the compile cache for source files impacted by [Ruby 3.0.3 [Bug 18250]](https://bugs.ruby-lang.org/issues/18250).
88
+ This should keep the performance loss to a minimum.
89
+
90
+ # 1.9.2
91
+
92
+ * Disable compile cache if [Ruby 3.0.3's ISeq cache bug](https://bugs.ruby-lang.org/issues/18250) is detected.
93
+ AKA `iseq.rb:13 to_binary: wrong argument type false (expected Symbol)`
94
+ * Fix `Kernel.load` behavior: before `load 'a'` would load `a.rb` (and other tried extensions) and wouldn't load `a` unless `development_mode: true`, now only `a` would be loaded and files with extensions wouldn't be.
95
+
96
+ # 1.9.1
97
+
98
+ * Removed a forgotten debug statement in JSON precompilation.
99
+
100
+ # 1.9.0
101
+
102
+ * Added a compilation cache for `JSON.load_file`. (#370)
103
+
3
104
  # 1.8.1
4
105
 
5
106
  * Fixed support for older Psych. (#369)
6
107
 
7
108
  # 1.8.0
8
109
 
9
- * Improve support for Pysch 4. (#368)
110
+ * Improve support for Psych 4. (#368)
10
111
 
11
112
  # 1.7.7
12
113
 
@@ -24,8 +125,8 @@
24
125
 
25
126
  # 1.7.4
26
127
 
27
- * Stop raising errors when encoutering various file system errors. The cache is now best effort,
28
- if somehow it can't be saved, bootsnapp will gracefully fallback to the original operation (e.g. `Kernel.require`).
128
+ * Stop raising errors when encountering various file system errors. The cache is now best effort,
129
+ if somehow it can't be saved, bootsnap will gracefully fallback to the original operation (e.g. `Kernel.require`).
29
130
  (#353, #177, #262)
30
131
 
31
132
  # 1.7.3
data/LICENSE.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2017 Shopify, Inc.
3
+ Copyright (c) 2017-present Shopify, Inc.
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -41,7 +41,7 @@ getting progressively slower, this is almost certainly the cause.**
41
41
  It's technically possible to simply specify `gem 'bootsnap', require: 'bootsnap/setup'`, but it's
42
42
  important to load Bootsnap as early as possible to get maximum performance improvement.
43
43
 
44
- You can see how this require works [here](https://github.com/Shopify/bootsnap/blob/master/lib/bootsnap/setup.rb).
44
+ You can see how this require works [here](https://github.com/Shopify/bootsnap/blob/main/lib/bootsnap/setup.rb).
45
45
 
46
46
  If you are not using Rails, or if you are but want more control over things, add this to your
47
47
  application setup immediately after `require 'bundler/setup'` (i.e. as early as possible: the sooner
@@ -161,7 +161,7 @@ The only directories considered "stable" are things under the Ruby install prefi
161
161
  "volatile".
162
162
 
163
163
  In addition to the [`Bootsnap::LoadPathCache::Cache`
164
- source](https://github.com/Shopify/bootsnap/blob/master/lib/bootsnap/load_path_cache/cache.rb),
164
+ source](https://github.com/Shopify/bootsnap/blob/main/lib/bootsnap/load_path_cache/cache.rb),
165
165
  this diagram may help clarify how entry resolution works:
166
166
 
167
167
  ![How path searching works](https://cloud.githubusercontent.com/assets/3074765/25388270/670b5652-299b-11e7-87fb-975647f68981.png)
@@ -232,9 +232,9 @@ Bootsnap writes a cache file containing a 64 byte header followed by the cache c
232
232
  is a cache key including several fields:
233
233
 
234
234
  * `version`, hardcoded in bootsnap. Essentially a schema version;
235
- * `ruby_platform`, A hash of `RUBY_PLATFORM` (e.g. x86_64-linux-gnu) variable and glibc version (on Linux) or OS version (`uname -v` on BSD, macOS)
235
+ * `ruby_platform`, A hash of `RUBY_PLATFORM` (e.g. x86_64-linux-gnu) variable.
236
236
  * `compile_option`, which changes with `RubyVM::InstructionSequence.compile_option` does;
237
- * `ruby_revision`, the version of Ruby this was compiled with;
237
+ * `ruby_revision`, A hash of `RUBY_REVISION`, the exact version of Ruby;
238
238
  * `size`, the size of the source file;
239
239
  * `mtime`, the last-modification timestamp of the source file when it was compiled; and
240
240
  * `data_size`, the number of bytes following the header, which we need to read it into a buffer.
data/exe/bootsnap CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- require 'bootsnap/cli'
4
+ require "bootsnap/cli"
5
5
  exit Bootsnap::CLI.new(ARGV).run
@@ -19,12 +19,6 @@
19
19
  #include <errno.h>
20
20
  #include <fcntl.h>
21
21
  #include <sys/stat.h>
22
- #ifndef _WIN32
23
- #include <sys/utsname.h>
24
- #endif
25
- #ifdef __GLIBC__
26
- #include <gnu/libc-version.h>
27
- #endif
28
22
 
29
23
  /* 1000 is an arbitrary limit; FNV64 plus some slashes brings the cap down to
30
24
  * 981 for the cache dir */
@@ -75,7 +69,7 @@ struct bs_cache_key {
75
69
  STATIC_ASSERT(sizeof(struct bs_cache_key) == KEY_SIZE);
76
70
 
77
71
  /* Effectively a schema version. Bumping invalidates all previous caches */
78
- static const uint32_t current_version = 3;
72
+ static const uint32_t current_version = 4;
79
73
 
80
74
  /* hash of e.g. "x86_64-darwin17", invalidating when ruby is recompiled on a
81
75
  * new OS ABI, etc. */
@@ -91,8 +85,7 @@ static mode_t current_umask;
91
85
  static VALUE rb_mBootsnap;
92
86
  static VALUE rb_mBootsnap_CompileCache;
93
87
  static VALUE rb_mBootsnap_CompileCache_Native;
94
- static VALUE rb_eBootsnap_CompileCache_Uncompilable;
95
- static ID uncompilable;
88
+ static VALUE rb_cBootsnap_CompileCache_UNCOMPILABLE;
96
89
  static ID instrumentation_method;
97
90
  static VALUE sym_miss;
98
91
  static VALUE sym_stale;
@@ -120,10 +113,8 @@ static uint32_t get_ruby_platform(void);
120
113
  * exception.
121
114
  */
122
115
  static int bs_storage_to_output(VALUE handler, VALUE args, VALUE storage_data, VALUE * output_data);
123
- static VALUE prot_storage_to_output(VALUE arg);
124
116
  static VALUE prot_input_to_output(VALUE arg);
125
117
  static void bs_input_to_output(VALUE handler, VALUE args, VALUE input_data, VALUE * output_data, int * exception_tag);
126
- static VALUE prot_input_to_storage(VALUE arg);
127
118
  static int bs_input_to_storage(VALUE handler, VALUE args, VALUE input_data, VALUE pathval, VALUE * storage_data);
128
119
  struct s2o_data;
129
120
  struct i2o_data;
@@ -138,6 +129,12 @@ bs_rb_coverage_running(VALUE self)
138
129
  return RTEST(cov) ? Qtrue : Qfalse;
139
130
  }
140
131
 
132
+ static VALUE
133
+ bs_rb_get_path(VALUE self, VALUE fname)
134
+ {
135
+ return rb_get_path(fname);
136
+ }
137
+
141
138
  /*
142
139
  * Ruby C extensions are initialized by calling Init_<extname>.
143
140
  *
@@ -149,14 +146,17 @@ void
149
146
  Init_bootsnap(void)
150
147
  {
151
148
  rb_mBootsnap = rb_define_module("Bootsnap");
149
+
150
+ rb_define_singleton_method(rb_mBootsnap, "rb_get_path", bs_rb_get_path, 1);
151
+
152
152
  rb_mBootsnap_CompileCache = rb_define_module_under(rb_mBootsnap, "CompileCache");
153
153
  rb_mBootsnap_CompileCache_Native = rb_define_module_under(rb_mBootsnap_CompileCache, "Native");
154
- rb_eBootsnap_CompileCache_Uncompilable = rb_define_class_under(rb_mBootsnap_CompileCache, "Uncompilable", rb_eStandardError);
154
+ rb_cBootsnap_CompileCache_UNCOMPILABLE = rb_const_get(rb_mBootsnap_CompileCache, rb_intern("UNCOMPILABLE"));
155
+ rb_global_variable(&rb_cBootsnap_CompileCache_UNCOMPILABLE);
155
156
 
156
157
  current_ruby_revision = get_ruby_revision();
157
158
  current_ruby_platform = get_ruby_platform();
158
159
 
159
- uncompilable = rb_intern("__bootsnap_uncompilable__");
160
160
  instrumentation_method = rb_intern("_instrument");
161
161
 
162
162
  sym_miss = ID2SYM(rb_intern("miss"));
@@ -199,29 +199,6 @@ bs_compile_option_crc32_set(VALUE self, VALUE crc32_v)
199
199
  return Qnil;
200
200
  }
201
201
 
202
- /*
203
- * We use FNV1a-64 to derive cache paths. The choice is somewhat arbitrary but
204
- * it has several nice properties:
205
- *
206
- * - Tiny implementation
207
- * - No external dependency
208
- * - Solid performance
209
- * - Solid randomness
210
- * - 32 bits doesn't feel collision-resistant enough; 64 is nice.
211
- */
212
- static uint64_t
213
- fnv1a_64_iter_cstr(uint64_t h, const char *str)
214
- {
215
- unsigned char *s = (unsigned char *)str;
216
-
217
- while (*s) {
218
- h ^= (uint64_t)*s++;
219
- h += (h << 1) + (h << 4) + (h << 5) + (h << 7) + (h << 8) + (h << 40);
220
- }
221
-
222
- return h;
223
- }
224
-
225
202
  static uint64_t
226
203
  fnv1a_64_iter(uint64_t h, const VALUE str)
227
204
  {
@@ -266,10 +243,6 @@ get_ruby_revision(void)
266
243
  /*
267
244
  * When ruby's version doesn't change, but it's recompiled on a different OS
268
245
  * (or OS version), we need to invalidate the cache.
269
- *
270
- * We actually factor in some extra information here, to be extra confident
271
- * that we don't try to re-use caches that will not be compatible, by factoring
272
- * in utsname.version.
273
246
  */
274
247
  static uint32_t
275
248
  get_ruby_platform(void)
@@ -279,22 +252,7 @@ get_ruby_platform(void)
279
252
 
280
253
  ruby_platform = rb_const_get(rb_cObject, rb_intern("RUBY_PLATFORM"));
281
254
  hash = fnv1a_64(ruby_platform);
282
-
283
- #ifdef _WIN32
284
- return (uint32_t)(hash >> 32) ^ (uint32_t)GetVersion();
285
- #elif defined(__GLIBC__)
286
- hash = fnv1a_64_iter_cstr(hash, gnu_get_libc_version());
287
- return (uint32_t)(hash >> 32);
288
- #else
289
- struct utsname utsname;
290
-
291
- /* Not worth crashing if this fails; lose extra cache invalidation potential */
292
- if (uname(&utsname) >= 0) {
293
- hash = fnv1a_64_iter_cstr(hash, utsname.version);
294
- }
295
-
296
255
  return (uint32_t)(hash >> 32);
297
- #endif
298
256
  }
299
257
 
300
258
  /*
@@ -426,6 +384,7 @@ open_current_file(char * path, struct bs_cache_key * key, const char ** errno_pr
426
384
  #define ERROR_WITH_ERRNO -1
427
385
  #define CACHE_MISS -2
428
386
  #define CACHE_STALE -3
387
+ #define CACHE_UNCOMPILABLE -4
429
388
 
430
389
  /*
431
390
  * Read the cache key from the given fd, which must have position 0 (e.g.
@@ -507,14 +466,14 @@ fetch_cached_data(int fd, ssize_t data_size, VALUE handler, VALUE args, VALUE *
507
466
  if (data_size > 100000000000) {
508
467
  *errno_provenance = "bs_fetch:fetch_cached_data:datasize";
509
468
  errno = EINVAL; /* because wtf? */
510
- ret = -1;
469
+ ret = ERROR_WITH_ERRNO;
511
470
  goto done;
512
471
  }
513
472
  data = ALLOC_N(char, data_size);
514
473
  nread = read(fd, data, data_size);
515
474
  if (nread < 0) {
516
475
  *errno_provenance = "bs_fetch:fetch_cached_data:read";
517
- ret = -1;
476
+ ret = ERROR_WITH_ERRNO;
518
477
  goto done;
519
478
  }
520
479
  if (nread != data_size) {
@@ -525,6 +484,10 @@ fetch_cached_data(int fd, ssize_t data_size, VALUE handler, VALUE args, VALUE *
525
484
  storage_data = rb_str_new(data, data_size);
526
485
 
527
486
  *exception_tag = bs_storage_to_output(handler, args, storage_data, output_data);
487
+ if (*output_data == rb_cBootsnap_CompileCache_UNCOMPILABLE) {
488
+ ret = CACHE_UNCOMPILABLE;
489
+ goto done;
490
+ }
528
491
  ret = 0;
529
492
  done:
530
493
  if (data != NULL) xfree(data);
@@ -737,7 +700,15 @@ bs_fetch(char * path, VALUE path_v, char * cache_path, VALUE handler, VALUE args
737
700
  &output_data, &exception_tag, &errno_provenance
738
701
  );
739
702
  if (exception_tag != 0) goto raise;
740
- else if (res == CACHE_MISS || res == CACHE_STALE) valid_cache = 0;
703
+ else if (res == CACHE_UNCOMPILABLE) {
704
+ /* If fetch_cached_data returned `Uncompilable` we fallback to `input_to_output`
705
+ This happens if we have say, an unsafe YAML cache, but try to load it in safe mode */
706
+ if (bs_read_contents(current_fd, current_key.size, &contents, &errno_provenance) < 0) goto fail_errno;
707
+ input_data = rb_str_new(contents, current_key.size);
708
+ bs_input_to_output(handler, args, input_data, &output_data, &exception_tag);
709
+ if (exception_tag != 0) goto raise;
710
+ goto succeed;
711
+ } else if (res == CACHE_MISS || res == CACHE_STALE) valid_cache = 0;
741
712
  else if (res == ERROR_WITH_ERRNO) goto fail_errno;
742
713
  else if (!NIL_P(output_data)) goto succeed; /* fast-path, goal */
743
714
  }
@@ -754,7 +725,7 @@ bs_fetch(char * path, VALUE path_v, char * cache_path, VALUE handler, VALUE args
754
725
  if (exception_tag != 0) goto raise;
755
726
  /* If input_to_storage raised Bootsnap::CompileCache::Uncompilable, don't try
756
727
  * to cache anything; just return input_to_output(input_data) */
757
- if (storage_data == uncompilable) {
728
+ if (storage_data == rb_cBootsnap_CompileCache_UNCOMPILABLE) {
758
729
  bs_input_to_output(handler, args, input_data, &output_data, &exception_tag);
759
730
  if (exception_tag != 0) goto raise;
760
731
  goto succeed;
@@ -772,12 +743,20 @@ bs_fetch(char * path, VALUE path_v, char * cache_path, VALUE handler, VALUE args
772
743
  exception_tag = bs_storage_to_output(handler, args, storage_data, &output_data);
773
744
  if (exception_tag != 0) goto raise;
774
745
 
775
- /* If output_data is nil, delete the cache entry and generate the output
776
- * using input_to_output */
777
- if (NIL_P(output_data)) {
746
+ if (output_data == rb_cBootsnap_CompileCache_UNCOMPILABLE) {
747
+ /* If storage_to_output returned `Uncompilable` we fallback to `input_to_output` */
748
+ bs_input_to_output(handler, args, input_data, &output_data, &exception_tag);
749
+ if (exception_tag != 0) goto raise;
750
+ } else if (NIL_P(output_data)) {
751
+ /* If output_data is nil, delete the cache entry and generate the output
752
+ * using input_to_output */
778
753
  if (unlink(cache_path) < 0) {
779
- errno_provenance = "bs_fetch:unlink";
780
- goto fail_errno;
754
+ /* If the cache was already deleted, it might be that another process did it before us.
755
+ * No point raising an error */
756
+ if (errno != ENOENT) {
757
+ errno_provenance = "bs_fetch:unlink";
758
+ goto fail_errno;
759
+ }
781
760
  }
782
761
  bs_input_to_output(handler, args, input_data, &output_data, &exception_tag);
783
762
  if (exception_tag != 0) goto raise;
@@ -856,7 +835,7 @@ bs_precompile(char * path, VALUE path_v, char * cache_path, VALUE handler)
856
835
 
857
836
  /* If input_to_storage raised Bootsnap::CompileCache::Uncompilable, don't try
858
837
  * to cache anything; just return false */
859
- if (storage_data == uncompilable) {
838
+ if (storage_data == rb_cBootsnap_CompileCache_UNCOMPILABLE) {
860
839
  goto fail;
861
840
  }
862
841
  /* If storage_data isn't a string, we can't cache it */
@@ -919,7 +898,7 @@ struct i2s_data {
919
898
  };
920
899
 
921
900
  static VALUE
922
- prot_storage_to_output(VALUE arg)
901
+ try_storage_to_output(VALUE arg)
923
902
  {
924
903
  struct s2o_data * data = (struct s2o_data *)arg;
925
904
  return rb_funcall(data->handler, rb_intern("storage_to_output"), 2, data->storage_data, data->args);
@@ -934,7 +913,7 @@ bs_storage_to_output(VALUE handler, VALUE args, VALUE storage_data, VALUE * outp
934
913
  .args = args,
935
914
  .storage_data = storage_data,
936
915
  };
937
- *output_data = rb_protect(prot_storage_to_output, (VALUE)&s2o_data, &state);
916
+ *output_data = rb_protect(try_storage_to_output, (VALUE)&s2o_data, &state);
938
917
  return state;
939
918
  }
940
919
 
@@ -963,22 +942,6 @@ try_input_to_storage(VALUE arg)
963
942
  return rb_funcall(data->handler, rb_intern("input_to_storage"), 2, data->input_data, data->pathval);
964
943
  }
965
944
 
966
- static VALUE
967
- rescue_input_to_storage(VALUE arg, VALUE e)
968
- {
969
- return uncompilable;
970
- }
971
-
972
- static VALUE
973
- prot_input_to_storage(VALUE arg)
974
- {
975
- struct i2s_data * data = (struct i2s_data *)arg;
976
- return rb_rescue2(
977
- try_input_to_storage, (VALUE)data,
978
- rescue_input_to_storage, Qnil,
979
- rb_eBootsnap_CompileCache_Uncompilable, 0);
980
- }
981
-
982
945
  static int
983
946
  bs_input_to_storage(VALUE handler, VALUE args, VALUE input_data, VALUE pathval, VALUE * storage_data)
984
947
  {
@@ -988,6 +951,6 @@ bs_input_to_storage(VALUE handler, VALUE args, VALUE input_data, VALUE pathval,
988
951
  .input_data = input_data,
989
952
  .pathval = pathval,
990
953
  };
991
- *storage_data = rb_protect(prot_input_to_storage, (VALUE)&i2s_data, &state);
954
+ *storage_data = rb_protect(try_input_to_storage, (VALUE)&i2s_data, &state);
992
955
  return state;
993
956
  }
@@ -1,21 +1,23 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require("mkmf")
3
4
 
4
- if RUBY_ENGINE == 'ruby'
5
- $CFLAGS << ' -O3 '
6
- $CFLAGS << ' -std=c99'
5
+ if RUBY_ENGINE == "ruby"
6
+ $CFLAGS << " -O3 "
7
+ $CFLAGS << " -std=c99"
7
8
 
8
9
  # ruby.h has some -Wpedantic fails in some cases
9
10
  # (e.g. https://github.com/Shopify/bootsnap/issues/15)
10
- unless ['0', '', nil].include?(ENV['BOOTSNAP_PEDANTIC'])
11
- $CFLAGS << ' -Wall'
12
- $CFLAGS << ' -Werror'
13
- $CFLAGS << ' -Wextra'
14
- $CFLAGS << ' -Wpedantic'
11
+ unless ["0", "", nil].include?(ENV["BOOTSNAP_PEDANTIC"])
12
+ $CFLAGS << " -Wall"
13
+ $CFLAGS << " -Werror"
14
+ $CFLAGS << " -Wextra"
15
+ $CFLAGS << " -Wpedantic"
15
16
 
16
- $CFLAGS << ' -Wno-unused-parameter' # VALUE self has to be there but we don't care what it is.
17
- $CFLAGS << ' -Wno-keyword-macro' # hiding return
18
- $CFLAGS << ' -Wno-gcc-compat' # ruby.h 2.6.0 on macos 10.14, dunno
17
+ $CFLAGS << " -Wno-unused-parameter" # VALUE self has to be there but we don't care what it is.
18
+ $CFLAGS << " -Wno-keyword-macro" # hiding return
19
+ $CFLAGS << " -Wno-gcc-compat" # ruby.h 2.6.0 on macos 10.14, dunno
20
+ $CFLAGS << " -Wno-compound-token-split-by-macro"
19
21
  end
20
22
 
21
23
  create_makefile("bootsnap/bootsnap")
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Bootsnap
3
4
  extend(self)
4
5
 
@@ -63,6 +63,7 @@ module Bootsnap
63
63
  loop do
64
64
  job, *args = Marshal.load(@pipe_out)
65
65
  return if job == :exit
66
+
66
67
  @jobs.fetch(job).call(*args)
67
68
  end
68
69
  rescue IOError