summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSatoshi Tagomori <s-tagomori@sakura.ad.jp>2026-05-08 18:43:15 +0900
committerSatoshi Tagomori <tagomoris@gmail.com>2026-05-10 09:38:45 +0900
commit5ed1f93b0e87d961282a4487c81b48cf6f0b127f (patch)
tree12273ddd9aa59883f60af2ca7fc2edb531642964
parent56cd26f8353713c485f49fa68d804e0f04777e08 (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.c33
1 files changed, 28 insertions, 5 deletions
diff --git a/builtin.c b/builtin.c
index 6cc9790466..7861aee8ba 100644
--- a/builtin.c
+++ b/builtin.c
@@ -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;
}