diff options
| author | Satoshi Tagomori <s-tagomori@sakura.ad.jp> | 2026-05-08 18:43:15 +0900 |
|---|---|---|
| committer | Satoshi Tagomori <tagomoris@gmail.com> | 2026-05-10 09:38:45 +0900 |
| commit | 5ed1f93b0e87d961282a4487c81b48cf6f0b127f (patch) | |
| tree | 12273ddd9aa59883f60af2ca7fc2edb531642964 | |
| parent | 56cd26f8353713c485f49fa68d804e0f04777e08 (diff) | |
Fix bug: the Slowpath doesn't work correctly because of double increment
builtin_lookup() find the pre-loaded and compiled (to ISeq) builtin libraries.
The libraries (.rb files) are loaded by miniruby, and those ISeq are written
in build/builtin_library.rbbin in the order that miniruby loads.
The fastpath of builtin_lookup() searches the contents of builtin_library.rbbin
in the order of miniruby loading, on ruby. The only fastpath works as far as
the order of loading libraries in ruby is equal to miniruby.
This is the reason why the slowpath's bug has not caused problems.
The slowpath incremented `bb` twice in a loop, so it's clearly bug
to skip the item after checking bb. Items at 1, 3, 5... will never be found
in the swlopath.
| -rw-r--r-- | builtin.c | 33 |
1 files changed, 28 insertions, 5 deletions
@@ -22,13 +22,36 @@ bin4feature(const struct builtin_binary *bb, const char *feature, size_t *psize) static const unsigned char* builtin_lookup(const char *feature, size_t *psize) { - static int index = 0; - const unsigned char *bin = bin4feature(&builtin_binary[index++], feature, psize); + static size_t index = 0; + const unsigned char *bin = NULL; + + /* + * Fast path: + * builtin_binary is usually arranged in the same order + * as features are looked up in miniruby, so try the next entry first. + */ + if (builtin_binary[index].feature) { + bin = bin4feature(&builtin_binary[index], feature, psize); + index++; + } + if (bin) { + return bin; + } - // usually, `builtin_binary` order is loading order at miniruby. - for (const struct builtin_binary *bb = &builtin_binary[0]; bb->feature &&! bin; bb++) { - bin = bin4feature(bb++, feature, psize); + /* + * Fallback: + * In case the lookup order does not match the array order, + * scan the entire table to find the feature. + */ + for (const struct builtin_binary *bb = &builtin_binary[0]; + bb->feature; + bb++) { + bin = bin4feature(bb, feature, psize); + if (bin) { + break; + } } + return bin; } |
