bootsnap 1.4.5-java → 1.5.0-java
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 +4 -4
- data/CHANGELOG.md +32 -0
- data/README.md +15 -2
- data/exe/bootsnap +5 -0
- data/ext/bootsnap/bootsnap.c +91 -64
- data/ext/bootsnap/extconf.rb +1 -0
- data/lib/bootsnap.rb +2 -0
- data/lib/bootsnap/bundler.rb +1 -0
- data/lib/bootsnap/cli.rb +136 -0
- data/lib/bootsnap/compile_cache.rb +3 -2
- data/lib/bootsnap/compile_cache/iseq.rb +15 -8
- data/lib/bootsnap/compile_cache/yaml.rb +67 -38
- data/lib/bootsnap/explicit_require.rb +1 -0
- data/lib/bootsnap/load_path_cache.rb +1 -1
- data/lib/bootsnap/load_path_cache/cache.rb +8 -8
- data/lib/bootsnap/load_path_cache/change_observer.rb +2 -1
- data/lib/bootsnap/load_path_cache/core_ext/active_support.rb +1 -0
- data/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb +18 -5
- data/lib/bootsnap/load_path_cache/core_ext/loaded_features.rb +1 -0
- data/lib/bootsnap/load_path_cache/loaded_features_index.rb +33 -10
- data/lib/bootsnap/load_path_cache/path.rb +3 -2
- data/lib/bootsnap/load_path_cache/path_scanner.rb +39 -26
- data/lib/bootsnap/load_path_cache/realpath_cache.rb +5 -5
- data/lib/bootsnap/load_path_cache/store.rb +6 -5
- data/lib/bootsnap/setup.rb +1 -0
- data/lib/bootsnap/version.rb +2 -1
- metadata +14 -28
- data/.github/CODEOWNERS +0 -2
- data/.github/probots.yml +0 -2
- data/.gitignore +0 -17
- data/.rubocop.yml +0 -20
- data/.travis.yml +0 -21
- data/CODE_OF_CONDUCT.md +0 -74
- data/CONTRIBUTING.md +0 -21
- data/Gemfile +0 -8
- data/README.jp.md +0 -231
- data/Rakefile +0 -12
- data/bin/ci +0 -10
- data/bin/console +0 -14
- data/bin/setup +0 -8
- data/bin/test-minimal-support +0 -7
- data/bin/testunit +0 -8
- data/bootsnap.gemspec +0 -45
- data/dev.yml +0 -10
- data/shipit.rubygems.yml +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a6981435a732015b8043d7ffc3a63c0603b6f1de300db2610becafc93c25b91e
|
4
|
+
data.tar.gz: d977b2ee4969224edd10530a4cb4332bcaea0298f8f147e4e3aaf846cbc584ab
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d544e765dcc1ccd998ffd0c65ee8aeda19e0a8a37cc37a0fbcb9917384283d27902acb81c079ec7c6b3cb1fe2ffb4fa752b1b668ae34bfdfc0b695cf943159bb
|
7
|
+
data.tar.gz: 7036e0b6c86ada90a48fe5d384b029c2c2f383e3231d3bcab43cc6bb765ef49cce4dc785120bac88c293aae2f24f4e23ba6d15ba9eb5ffa953eb0f8843e5e588
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,35 @@
|
|
1
|
+
# 1.5.0
|
2
|
+
|
3
|
+
* Add a command line to statically precompile the ISeq cache. (#326)
|
4
|
+
|
5
|
+
# 1.4.9
|
6
|
+
|
7
|
+
* [Windows support](https://github.com/Shopify/bootsnap/pull/319)
|
8
|
+
* [Fix potential crash](https://github.com/Shopify/bootsnap/pull/322)
|
9
|
+
|
10
|
+
# 1.4.8
|
11
|
+
|
12
|
+
* [Prevent FallbackScan from polluting exception cause](https://github.com/Shopify/bootsnap/pull/314)
|
13
|
+
|
14
|
+
# 1.4.7
|
15
|
+
|
16
|
+
* Various performance enhancements
|
17
|
+
* Fix race condition in heavy concurrent load scenarios that would cause bootsnap to raise
|
18
|
+
|
19
|
+
# 1.4.6
|
20
|
+
|
21
|
+
* Fix bug that was erroneously considering that files containing `.` in the names were being
|
22
|
+
required if a different file with the same name was already being required
|
23
|
+
|
24
|
+
Example:
|
25
|
+
|
26
|
+
require 'foo'
|
27
|
+
require 'foo.en'
|
28
|
+
|
29
|
+
Before bootsnap was considering `foo.en` to be the same file as `foo`
|
30
|
+
|
31
|
+
* Use glibc as part of the ruby_platform cache key
|
32
|
+
|
1
33
|
# 1.4.5
|
2
34
|
|
3
35
|
* MRI 2.7 support
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Bootsnap [](https://github.com/Shopify/bootsnap/actions)
|
2
2
|
|
3
3
|
Bootsnap is a library that plugs into Ruby, with optional support for `ActiveSupport` and `YAML`,
|
4
4
|
to optimize and cache expensive computations. See [How Does This Work](#how-does-this-work).
|
@@ -214,7 +214,7 @@ Bootsnap writes a cache file containing a 64 byte header followed by the cache c
|
|
214
214
|
is a cache key including several fields:
|
215
215
|
|
216
216
|
* `version`, hardcoded in bootsnap. Essentially a schema version;
|
217
|
-
* `
|
217
|
+
* `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)
|
218
218
|
* `compile_option`, which changes with `RubyVM::InstructionSequence.compile_option` does;
|
219
219
|
* `ruby_revision`, the version of Ruby this was compiled with;
|
220
220
|
* `size`, the size of the source file;
|
@@ -294,6 +294,19 @@ open /c/nope.bundle -> -1
|
|
294
294
|
# (nothing!)
|
295
295
|
```
|
296
296
|
|
297
|
+
## Precompilation
|
298
|
+
|
299
|
+
In development environments the bootsnap compilation cache is generated on the fly when source files are loaded.
|
300
|
+
But in production environments, such as docker images, you might need to precompile the cache.
|
301
|
+
|
302
|
+
To do so you can use the `bootsnap precompile` command.
|
303
|
+
|
304
|
+
Example:
|
305
|
+
|
306
|
+
```bash
|
307
|
+
$ bundle exec bootsnap precompile --gemfile app/ lib/
|
308
|
+
```
|
309
|
+
|
297
310
|
## When not to use Bootsnap
|
298
311
|
|
299
312
|
*Alternative engines*: Bootsnap is pretty reliant on MRI features, and parts are disabled entirely on alternative ruby
|
data/exe/bootsnap
ADDED
data/ext/bootsnap/bootsnap.c
CHANGED
@@ -21,6 +21,9 @@
|
|
21
21
|
#ifndef _WIN32
|
22
22
|
#include <sys/utsname.h>
|
23
23
|
#endif
|
24
|
+
#ifdef __GLIBC__
|
25
|
+
#include <gnu/libc-version.h>
|
26
|
+
#endif
|
24
27
|
|
25
28
|
/* 1000 is an arbitrary limit; FNV64 plus some slashes brings the cap down to
|
26
29
|
* 981 for the cache dir */
|
@@ -29,6 +32,8 @@
|
|
29
32
|
|
30
33
|
#define KEY_SIZE 64
|
31
34
|
|
35
|
+
#define MAX_CREATE_TEMPFILE_ATTEMPT 3
|
36
|
+
|
32
37
|
/*
|
33
38
|
* An instance of this key is written as the first 64 bytes of each cache file.
|
34
39
|
* The mtime and size members track whether the file contents have changed, and
|
@@ -86,16 +91,16 @@ static ID uncompilable;
|
|
86
91
|
|
87
92
|
/* Functions exposed as module functions on Bootsnap::CompileCache::Native */
|
88
93
|
static VALUE bs_compile_option_crc32_set(VALUE self, VALUE crc32_v);
|
89
|
-
static VALUE bs_rb_fetch(VALUE self, VALUE cachedir_v, VALUE path_v, VALUE handler);
|
94
|
+
static VALUE bs_rb_fetch(VALUE self, VALUE cachedir_v, VALUE path_v, VALUE handler, VALUE args);
|
90
95
|
|
91
96
|
/* Helpers */
|
92
97
|
static uint64_t fnv1a_64(const char *str);
|
93
|
-
static void bs_cache_path(const char * cachedir, const char * path, char
|
98
|
+
static void bs_cache_path(const char * cachedir, const char * path, const char * extra, char (* cache_path)[MAX_CACHEPATH_SIZE]);
|
94
99
|
static int bs_read_key(int fd, struct bs_cache_key * key);
|
95
100
|
static int cache_key_equal(struct bs_cache_key * k1, struct bs_cache_key * k2);
|
96
|
-
static VALUE bs_fetch(char * path, VALUE path_v, char * cache_path, VALUE handler);
|
97
|
-
static int open_current_file(char * path, struct bs_cache_key * key, char ** errno_provenance);
|
98
|
-
static int fetch_cached_data(int fd, ssize_t data_size, VALUE handler, VALUE * output_data, int * exception_tag, char ** errno_provenance);
|
101
|
+
static VALUE bs_fetch(char * path, VALUE path_v, char * cache_path, VALUE handler, VALUE args);
|
102
|
+
static int open_current_file(char * path, struct bs_cache_key * key, const char ** errno_provenance);
|
103
|
+
static int fetch_cached_data(int fd, ssize_t data_size, VALUE handler, VALUE args, VALUE * output_data, int * exception_tag, const char ** errno_provenance);
|
99
104
|
static uint32_t get_ruby_revision(void);
|
100
105
|
static uint32_t get_ruby_platform(void);
|
101
106
|
|
@@ -103,12 +108,12 @@ static uint32_t get_ruby_platform(void);
|
|
103
108
|
* Helper functions to call ruby methods on handler object without crashing on
|
104
109
|
* exception.
|
105
110
|
*/
|
106
|
-
static int bs_storage_to_output(VALUE handler, VALUE storage_data, VALUE * output_data);
|
111
|
+
static int bs_storage_to_output(VALUE handler, VALUE args, VALUE storage_data, VALUE * output_data);
|
107
112
|
static VALUE prot_storage_to_output(VALUE arg);
|
108
113
|
static VALUE prot_input_to_output(VALUE arg);
|
109
|
-
static void bs_input_to_output(VALUE handler, VALUE input_data, VALUE * output_data, int * exception_tag);
|
114
|
+
static void bs_input_to_output(VALUE handler, VALUE args, VALUE input_data, VALUE * output_data, int * exception_tag);
|
110
115
|
static VALUE prot_input_to_storage(VALUE arg);
|
111
|
-
static int bs_input_to_storage(VALUE handler, VALUE input_data, VALUE pathval, VALUE * storage_data);
|
116
|
+
static int bs_input_to_storage(VALUE handler, VALUE args, VALUE input_data, VALUE pathval, VALUE * storage_data);
|
112
117
|
struct s2o_data;
|
113
118
|
struct i2o_data;
|
114
119
|
struct i2s_data;
|
@@ -143,7 +148,7 @@ Init_bootsnap(void)
|
|
143
148
|
uncompilable = rb_intern("__bootsnap_uncompilable__");
|
144
149
|
|
145
150
|
rb_define_module_function(rb_mBootsnap_CompileCache_Native, "coverage_running?", bs_rb_coverage_running, 0);
|
146
|
-
rb_define_module_function(rb_mBootsnap_CompileCache_Native, "fetch", bs_rb_fetch,
|
151
|
+
rb_define_module_function(rb_mBootsnap_CompileCache_Native, "fetch", bs_rb_fetch, 4);
|
147
152
|
rb_define_module_function(rb_mBootsnap_CompileCache_Native, "compile_option_crc32=", bs_compile_option_crc32_set, 1);
|
148
153
|
|
149
154
|
current_umask = umask(0777);
|
@@ -236,6 +241,9 @@ get_ruby_platform(void)
|
|
236
241
|
|
237
242
|
#ifdef _WIN32
|
238
243
|
return (uint32_t)(hash >> 32) ^ (uint32_t)GetVersion();
|
244
|
+
#elif defined(__GLIBC__)
|
245
|
+
hash = fnv1a_64_iter(hash, gnu_get_libc_version());
|
246
|
+
return (uint32_t)(hash >> 32);
|
239
247
|
#else
|
240
248
|
struct utsname utsname;
|
241
249
|
|
@@ -256,9 +264,12 @@ get_ruby_platform(void)
|
|
256
264
|
* The path will look something like: <cachedir>/12/34567890abcdef
|
257
265
|
*/
|
258
266
|
static void
|
259
|
-
bs_cache_path(const char * cachedir, const char * path, char
|
267
|
+
bs_cache_path(const char * cachedir, const char * path, const char * extra, char (* cache_path)[MAX_CACHEPATH_SIZE])
|
260
268
|
{
|
261
269
|
uint64_t hash = fnv1a_64(path);
|
270
|
+
if (extra) {
|
271
|
+
hash ^= fnv1a_64(extra);
|
272
|
+
}
|
262
273
|
|
263
274
|
uint8_t first_byte = (hash >> (64 - 8));
|
264
275
|
uint64_t remainder = hash & 0x00ffffffffffffff;
|
@@ -293,7 +304,7 @@ cache_key_equal(struct bs_cache_key * k1, struct bs_cache_key * k2)
|
|
293
304
|
* conversions on the ruby VALUE arguments before passing them along.
|
294
305
|
*/
|
295
306
|
static VALUE
|
296
|
-
bs_rb_fetch(VALUE self, VALUE cachedir_v, VALUE path_v, VALUE handler)
|
307
|
+
bs_rb_fetch(VALUE self, VALUE cachedir_v, VALUE path_v, VALUE handler, VALUE args)
|
297
308
|
{
|
298
309
|
FilePathValue(path_v);
|
299
310
|
|
@@ -307,13 +318,16 @@ bs_rb_fetch(VALUE self, VALUE cachedir_v, VALUE path_v, VALUE handler)
|
|
307
318
|
char * cachedir = RSTRING_PTR(cachedir_v);
|
308
319
|
char * path = RSTRING_PTR(path_v);
|
309
320
|
char cache_path[MAX_CACHEPATH_SIZE];
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
321
|
+
char * extra = NULL;
|
322
|
+
if (!NIL_P(args)) {
|
323
|
+
VALUE args_serial = rb_marshal_dump(args, Qnil);
|
324
|
+
extra = RSTRING_PTR(args_serial);
|
314
325
|
}
|
315
326
|
|
316
|
-
|
327
|
+
/* generate cache path to cache_path */
|
328
|
+
bs_cache_path(cachedir, path, extra, &cache_path);
|
329
|
+
|
330
|
+
return bs_fetch(path, path_v, cache_path, handler, args);
|
317
331
|
}
|
318
332
|
|
319
333
|
/*
|
@@ -321,14 +335,14 @@ bs_rb_fetch(VALUE self, VALUE cachedir_v, VALUE path_v, VALUE handler)
|
|
321
335
|
* was loaded.
|
322
336
|
*/
|
323
337
|
static int
|
324
|
-
open_current_file(char * path, struct bs_cache_key * key, char ** errno_provenance)
|
338
|
+
open_current_file(char * path, struct bs_cache_key * key, const char ** errno_provenance)
|
325
339
|
{
|
326
340
|
struct stat statbuf;
|
327
341
|
int fd;
|
328
342
|
|
329
343
|
fd = open(path, O_RDONLY);
|
330
344
|
if (fd < 0) {
|
331
|
-
*errno_provenance =
|
345
|
+
*errno_provenance = "bs_fetch:open_current_file:open";
|
332
346
|
return fd;
|
333
347
|
}
|
334
348
|
#ifdef _WIN32
|
@@ -336,7 +350,7 @@ open_current_file(char * path, struct bs_cache_key * key, char ** errno_provenan
|
|
336
350
|
#endif
|
337
351
|
|
338
352
|
if (fstat(fd, &statbuf) < 0) {
|
339
|
-
*errno_provenance =
|
353
|
+
*errno_provenance = "bs_fetch:open_current_file:fstat";
|
340
354
|
close(fd);
|
341
355
|
return -1;
|
342
356
|
}
|
@@ -382,13 +396,13 @@ bs_read_key(int fd, struct bs_cache_key * key)
|
|
382
396
|
* - ERROR_WITH_ERRNO (-1, errno is set)
|
383
397
|
*/
|
384
398
|
static int
|
385
|
-
open_cache_file(const char * path, struct bs_cache_key * key, char ** errno_provenance)
|
399
|
+
open_cache_file(const char * path, struct bs_cache_key * key, const char ** errno_provenance)
|
386
400
|
{
|
387
401
|
int fd, res;
|
388
402
|
|
389
403
|
fd = open(path, O_RDONLY);
|
390
404
|
if (fd < 0) {
|
391
|
-
*errno_provenance =
|
405
|
+
*errno_provenance = "bs_fetch:open_cache_file:open";
|
392
406
|
if (errno == ENOENT) return CACHE_MISSING_OR_INVALID;
|
393
407
|
return ERROR_WITH_ERRNO;
|
394
408
|
}
|
@@ -398,7 +412,7 @@ open_cache_file(const char * path, struct bs_cache_key * key, char ** errno_prov
|
|
398
412
|
|
399
413
|
res = bs_read_key(fd, key);
|
400
414
|
if (res < 0) {
|
401
|
-
*errno_provenance =
|
415
|
+
*errno_provenance = "bs_fetch:open_cache_file:read";
|
402
416
|
close(fd);
|
403
417
|
return res;
|
404
418
|
}
|
@@ -422,7 +436,7 @@ open_cache_file(const char * path, struct bs_cache_key * key, char ** errno_prov
|
|
422
436
|
* or exception, will be the final data returnable to the user.
|
423
437
|
*/
|
424
438
|
static int
|
425
|
-
fetch_cached_data(int fd, ssize_t data_size, VALUE handler, VALUE * output_data, int * exception_tag, char ** errno_provenance)
|
439
|
+
fetch_cached_data(int fd, ssize_t data_size, VALUE handler, VALUE args, VALUE * output_data, int * exception_tag, const char ** errno_provenance)
|
426
440
|
{
|
427
441
|
char * data = NULL;
|
428
442
|
ssize_t nread;
|
@@ -431,7 +445,7 @@ fetch_cached_data(int fd, ssize_t data_size, VALUE handler, VALUE * output_data,
|
|
431
445
|
VALUE storage_data;
|
432
446
|
|
433
447
|
if (data_size > 100000000000) {
|
434
|
-
*errno_provenance =
|
448
|
+
*errno_provenance = "bs_fetch:fetch_cached_data:datasize";
|
435
449
|
errno = EINVAL; /* because wtf? */
|
436
450
|
ret = -1;
|
437
451
|
goto done;
|
@@ -439,7 +453,7 @@ fetch_cached_data(int fd, ssize_t data_size, VALUE handler, VALUE * output_data,
|
|
439
453
|
data = ALLOC_N(char, data_size);
|
440
454
|
nread = read(fd, data, data_size);
|
441
455
|
if (nread < 0) {
|
442
|
-
*errno_provenance =
|
456
|
+
*errno_provenance = "bs_fetch:fetch_cached_data:read";
|
443
457
|
ret = -1;
|
444
458
|
goto done;
|
445
459
|
}
|
@@ -448,9 +462,9 @@ fetch_cached_data(int fd, ssize_t data_size, VALUE handler, VALUE * output_data,
|
|
448
462
|
goto done;
|
449
463
|
}
|
450
464
|
|
451
|
-
storage_data =
|
465
|
+
storage_data = rb_str_new(data, data_size);
|
452
466
|
|
453
|
-
*exception_tag = bs_storage_to_output(handler, storage_data, output_data);
|
467
|
+
*exception_tag = bs_storage_to_output(handler, args, storage_data, output_data);
|
454
468
|
ret = 0;
|
455
469
|
done:
|
456
470
|
if (data != NULL) xfree(data);
|
@@ -491,29 +505,36 @@ mkpath(char * file_path, mode_t mode)
|
|
491
505
|
* path.
|
492
506
|
*/
|
493
507
|
static int
|
494
|
-
atomic_write_cache_file(char * path, struct bs_cache_key * key, VALUE data, char ** errno_provenance)
|
508
|
+
atomic_write_cache_file(char * path, struct bs_cache_key * key, VALUE data, const char ** errno_provenance)
|
495
509
|
{
|
496
510
|
char template[MAX_CACHEPATH_SIZE + 20];
|
497
511
|
char * tmp_path;
|
498
|
-
int fd, ret;
|
512
|
+
int fd, ret, attempt;
|
499
513
|
ssize_t nwrite;
|
500
514
|
|
501
|
-
|
502
|
-
|
515
|
+
for (attempt = 0; attempt < MAX_CREATE_TEMPFILE_ATTEMPT; ++attempt) {
|
516
|
+
tmp_path = strncpy(template, path, MAX_CACHEPATH_SIZE);
|
517
|
+
strcat(tmp_path, ".tmp.XXXXXX");
|
503
518
|
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
}
|
511
|
-
fd = open(tmp_path, O_WRONLY | O_CREAT, 0664);
|
512
|
-
if (fd < 0) {
|
513
|
-
*errno_provenance = (char *)"bs_fetch:atomic_write_cache_file:open";
|
519
|
+
// mkstemp modifies the template to be the actual created path
|
520
|
+
fd = mkstemp(tmp_path);
|
521
|
+
if (fd > 0) break;
|
522
|
+
|
523
|
+
if (attempt == 0 && mkpath(tmp_path, 0775) < 0) {
|
524
|
+
*errno_provenance = "bs_fetch:atomic_write_cache_file:mkpath";
|
514
525
|
return -1;
|
515
526
|
}
|
516
527
|
}
|
528
|
+
if (fd < 0) {
|
529
|
+
*errno_provenance = "bs_fetch:atomic_write_cache_file:mkstemp";
|
530
|
+
return -1;
|
531
|
+
}
|
532
|
+
|
533
|
+
if (chmod(tmp_path, 0644) < 0) {
|
534
|
+
*errno_provenance = "bs_fetch:atomic_write_cache_file:chmod";
|
535
|
+
return -1;
|
536
|
+
}
|
537
|
+
|
517
538
|
#ifdef _WIN32
|
518
539
|
setmode(fd, O_BINARY);
|
519
540
|
#endif
|
@@ -521,11 +542,11 @@ atomic_write_cache_file(char * path, struct bs_cache_key * key, VALUE data, char
|
|
521
542
|
key->data_size = RSTRING_LEN(data);
|
522
543
|
nwrite = write(fd, key, KEY_SIZE);
|
523
544
|
if (nwrite < 0) {
|
524
|
-
*errno_provenance =
|
545
|
+
*errno_provenance = "bs_fetch:atomic_write_cache_file:write";
|
525
546
|
return -1;
|
526
547
|
}
|
527
548
|
if (nwrite != KEY_SIZE) {
|
528
|
-
*errno_provenance =
|
549
|
+
*errno_provenance = "bs_fetch:atomic_write_cache_file:keysize";
|
529
550
|
errno = EIO; /* Lies but whatever */
|
530
551
|
return -1;
|
531
552
|
}
|
@@ -533,7 +554,7 @@ atomic_write_cache_file(char * path, struct bs_cache_key * key, VALUE data, char
|
|
533
554
|
nwrite = write(fd, RSTRING_PTR(data), RSTRING_LEN(data));
|
534
555
|
if (nwrite < 0) return -1;
|
535
556
|
if (nwrite != RSTRING_LEN(data)) {
|
536
|
-
*errno_provenance =
|
557
|
+
*errno_provenance = "bs_fetch:atomic_write_cache_file:writelength";
|
537
558
|
errno = EIO; /* Lies but whatever */
|
538
559
|
return -1;
|
539
560
|
}
|
@@ -541,12 +562,12 @@ atomic_write_cache_file(char * path, struct bs_cache_key * key, VALUE data, char
|
|
541
562
|
close(fd);
|
542
563
|
ret = rename(tmp_path, path);
|
543
564
|
if (ret < 0) {
|
544
|
-
*errno_provenance =
|
565
|
+
*errno_provenance = "bs_fetch:atomic_write_cache_file:rename";
|
545
566
|
return -1;
|
546
567
|
}
|
547
568
|
ret = chmod(path, 0664 & ~current_umask);
|
548
569
|
if (ret < 0) {
|
549
|
-
*errno_provenance =
|
570
|
+
*errno_provenance = "bs_fetch:atomic_write_cache_file:chmod";
|
550
571
|
}
|
551
572
|
return ret;
|
552
573
|
}
|
@@ -555,13 +576,13 @@ atomic_write_cache_file(char * path, struct bs_cache_key * key, VALUE data, char
|
|
555
576
|
/* Read contents from an fd, whose contents are asserted to be +size+ bytes
|
556
577
|
* long, into a buffer */
|
557
578
|
static ssize_t
|
558
|
-
bs_read_contents(int fd, size_t size, char ** contents, char ** errno_provenance)
|
579
|
+
bs_read_contents(int fd, size_t size, char ** contents, const char ** errno_provenance)
|
559
580
|
{
|
560
581
|
ssize_t nread;
|
561
582
|
*contents = ALLOC_N(char, size);
|
562
583
|
nread = read(fd, *contents, size);
|
563
584
|
if (nread < 0) {
|
564
|
-
*errno_provenance =
|
585
|
+
*errno_provenance = "bs_fetch:bs_read_contents:read";
|
565
586
|
}
|
566
587
|
return nread;
|
567
588
|
}
|
@@ -611,13 +632,13 @@ bs_read_contents(int fd, size_t size, char ** contents, char ** errno_provenance
|
|
611
632
|
* - Return storage_to_output(storage_data)
|
612
633
|
*/
|
613
634
|
static VALUE
|
614
|
-
bs_fetch(char * path, VALUE path_v, char * cache_path, VALUE handler)
|
635
|
+
bs_fetch(char * path, VALUE path_v, char * cache_path, VALUE handler, VALUE args)
|
615
636
|
{
|
616
637
|
struct bs_cache_key cached_key, current_key;
|
617
638
|
char * contents = NULL;
|
618
639
|
int cache_fd = -1, current_fd = -1;
|
619
640
|
int res, valid_cache = 0, exception_tag = 0;
|
620
|
-
char * errno_provenance = NULL;
|
641
|
+
const char * errno_provenance = NULL;
|
621
642
|
|
622
643
|
VALUE input_data; /* data read from source file, e.g. YAML or ruby source */
|
623
644
|
VALUE storage_data; /* compiled data, e.g. msgpack / binary iseq */
|
@@ -644,7 +665,7 @@ bs_fetch(char * path, VALUE path_v, char * cache_path, VALUE handler)
|
|
644
665
|
if (valid_cache) {
|
645
666
|
/* Fetch the cache data and return it if we're able to load it successfully */
|
646
667
|
res = fetch_cached_data(
|
647
|
-
cache_fd, (ssize_t)cached_key.data_size, handler,
|
668
|
+
cache_fd, (ssize_t)cached_key.data_size, handler, args,
|
648
669
|
&output_data, &exception_tag, &errno_provenance
|
649
670
|
);
|
650
671
|
if (exception_tag != 0) goto raise;
|
@@ -658,15 +679,15 @@ bs_fetch(char * path, VALUE path_v, char * cache_path, VALUE handler)
|
|
658
679
|
|
659
680
|
/* Read the contents of the source file into a buffer */
|
660
681
|
if (bs_read_contents(current_fd, current_key.size, &contents, &errno_provenance) < 0) goto fail_errno;
|
661
|
-
input_data =
|
682
|
+
input_data = rb_str_new(contents, current_key.size);
|
662
683
|
|
663
684
|
/* Try to compile the input_data using input_to_storage(input_data) */
|
664
|
-
exception_tag = bs_input_to_storage(handler, input_data, path_v, &storage_data);
|
685
|
+
exception_tag = bs_input_to_storage(handler, args, input_data, path_v, &storage_data);
|
665
686
|
if (exception_tag != 0) goto raise;
|
666
687
|
/* If input_to_storage raised Bootsnap::CompileCache::Uncompilable, don't try
|
667
688
|
* to cache anything; just return input_to_output(input_data) */
|
668
689
|
if (storage_data == uncompilable) {
|
669
|
-
bs_input_to_output(handler, input_data, &output_data, &exception_tag);
|
690
|
+
bs_input_to_output(handler, args, input_data, &output_data, &exception_tag);
|
670
691
|
if (exception_tag != 0) goto raise;
|
671
692
|
goto succeed;
|
672
693
|
}
|
@@ -678,17 +699,17 @@ bs_fetch(char * path, VALUE path_v, char * cache_path, VALUE handler)
|
|
678
699
|
if (res < 0) goto fail_errno;
|
679
700
|
|
680
701
|
/* Having written the cache, now convert storage_data to output_data */
|
681
|
-
exception_tag = bs_storage_to_output(handler, storage_data, &output_data);
|
702
|
+
exception_tag = bs_storage_to_output(handler, args, storage_data, &output_data);
|
682
703
|
if (exception_tag != 0) goto raise;
|
683
704
|
|
684
705
|
/* If output_data is nil, delete the cache entry and generate the output
|
685
706
|
* using input_to_output */
|
686
707
|
if (NIL_P(output_data)) {
|
687
708
|
if (unlink(cache_path) < 0) {
|
688
|
-
errno_provenance =
|
709
|
+
errno_provenance = "bs_fetch:unlink";
|
689
710
|
goto fail_errno;
|
690
711
|
}
|
691
|
-
bs_input_to_output(handler, input_data, &output_data, &exception_tag);
|
712
|
+
bs_input_to_output(handler, args, input_data, &output_data, &exception_tag);
|
692
713
|
if (exception_tag != 0) goto raise;
|
693
714
|
}
|
694
715
|
|
@@ -738,16 +759,19 @@ invalid_type_storage_data:
|
|
738
759
|
|
739
760
|
struct s2o_data {
|
740
761
|
VALUE handler;
|
762
|
+
VALUE args;
|
741
763
|
VALUE storage_data;
|
742
764
|
};
|
743
765
|
|
744
766
|
struct i2o_data {
|
745
767
|
VALUE handler;
|
768
|
+
VALUE args;
|
746
769
|
VALUE input_data;
|
747
770
|
};
|
748
771
|
|
749
772
|
struct i2s_data {
|
750
773
|
VALUE handler;
|
774
|
+
VALUE args;
|
751
775
|
VALUE input_data;
|
752
776
|
VALUE pathval;
|
753
777
|
};
|
@@ -756,15 +780,16 @@ static VALUE
|
|
756
780
|
prot_storage_to_output(VALUE arg)
|
757
781
|
{
|
758
782
|
struct s2o_data * data = (struct s2o_data *)arg;
|
759
|
-
return rb_funcall(data->handler, rb_intern("storage_to_output"),
|
783
|
+
return rb_funcall(data->handler, rb_intern("storage_to_output"), 2, data->storage_data, data->args);
|
760
784
|
}
|
761
785
|
|
762
786
|
static int
|
763
|
-
bs_storage_to_output(VALUE handler, VALUE storage_data, VALUE * output_data)
|
787
|
+
bs_storage_to_output(VALUE handler, VALUE args, VALUE storage_data, VALUE * output_data)
|
764
788
|
{
|
765
789
|
int state;
|
766
790
|
struct s2o_data s2o_data = {
|
767
791
|
.handler = handler,
|
792
|
+
.args = args,
|
768
793
|
.storage_data = storage_data,
|
769
794
|
};
|
770
795
|
*output_data = rb_protect(prot_storage_to_output, (VALUE)&s2o_data, &state);
|
@@ -772,10 +797,11 @@ bs_storage_to_output(VALUE handler, VALUE storage_data, VALUE * output_data)
|
|
772
797
|
}
|
773
798
|
|
774
799
|
static void
|
775
|
-
bs_input_to_output(VALUE handler, VALUE input_data, VALUE * output_data, int * exception_tag)
|
800
|
+
bs_input_to_output(VALUE handler, VALUE args, VALUE input_data, VALUE * output_data, int * exception_tag)
|
776
801
|
{
|
777
802
|
struct i2o_data i2o_data = {
|
778
803
|
.handler = handler,
|
804
|
+
.args = args,
|
779
805
|
.input_data = input_data,
|
780
806
|
};
|
781
807
|
*output_data = rb_protect(prot_input_to_output, (VALUE)&i2o_data, exception_tag);
|
@@ -785,18 +811,18 @@ static VALUE
|
|
785
811
|
prot_input_to_output(VALUE arg)
|
786
812
|
{
|
787
813
|
struct i2o_data * data = (struct i2o_data *)arg;
|
788
|
-
return rb_funcall(data->handler, rb_intern("input_to_output"),
|
814
|
+
return rb_funcall(data->handler, rb_intern("input_to_output"), 2, data->input_data, data->args);
|
789
815
|
}
|
790
816
|
|
791
817
|
static VALUE
|
792
818
|
try_input_to_storage(VALUE arg)
|
793
819
|
{
|
794
820
|
struct i2s_data * data = (struct i2s_data *)arg;
|
795
|
-
return rb_funcall(data->handler, rb_intern("input_to_storage"),
|
821
|
+
return rb_funcall(data->handler, rb_intern("input_to_storage"), 3, data->input_data, data->pathval, data->args);
|
796
822
|
}
|
797
823
|
|
798
824
|
static VALUE
|
799
|
-
rescue_input_to_storage(VALUE arg)
|
825
|
+
rescue_input_to_storage(VALUE arg, VALUE e)
|
800
826
|
{
|
801
827
|
return uncompilable;
|
802
828
|
}
|
@@ -812,11 +838,12 @@ prot_input_to_storage(VALUE arg)
|
|
812
838
|
}
|
813
839
|
|
814
840
|
static int
|
815
|
-
bs_input_to_storage(VALUE handler, VALUE input_data, VALUE pathval, VALUE * storage_data)
|
841
|
+
bs_input_to_storage(VALUE handler, VALUE args, VALUE input_data, VALUE pathval, VALUE * storage_data)
|
816
842
|
{
|
817
843
|
int state;
|
818
844
|
struct i2s_data i2s_data = {
|
819
845
|
.handler = handler,
|
846
|
+
.args = args,
|
820
847
|
.input_data = input_data,
|
821
848
|
.pathval = pathval,
|
822
849
|
};
|