Project

General

Profile

Bug #15856 ยป 0001-Sort-feature-index-arrays-by-the-priority-of-file-ty.patch

nobu (Nobuyoshi Nakada), 07/12/2021 04:07 PM

View differences:

load.c
185 185
    return st_hash(str, len, 0xfea7009e);
186 186
}
187 187

  
188
static bool
189
is_rbext_path(VALUE feature_path)
190
{
191
    long len = RSTRING_LEN(feature_path);
192
    long rbext_len = rb_strlen_lit(".rb");
193
    if (len <= rbext_len) return false;
194
    return IS_RBEXT(RSTRING_PTR(feature_path) + len - rbext_len);
195
}
196

  
188 197
static void
189
features_index_add_single(const char* str, size_t len, VALUE offset)
198
features_index_add_single(const char* str, size_t len, VALUE offset, bool rb)
190 199
{
191 200
    struct st_table *features_index;
192 201
    VALUE this_feature_index = Qnil;
......
202 211
	st_insert(features_index, short_feature_key, (st_data_t)offset);
203 212
    }
204 213
    else if (RB_TYPE_P(this_feature_index, T_FIXNUM)) {
214
	VALUE loaded_features = get_loaded_features();
215
	VALUE this_feature_path = RARRAY_AREF(loaded_features, FIX2LONG(this_feature_index));
205 216
	VALUE feature_indexes[2];
206
	feature_indexes[0] = this_feature_index;
207
	feature_indexes[1] = offset;
217
	int top = (rb && !is_rbext_path(this_feature_path)) ? 1 : 0;
218
	feature_indexes[top^0] = this_feature_index;
219
	feature_indexes[top^1] = offset;
208 220
	this_feature_index = (VALUE)xcalloc(1, sizeof(struct RArray));
209 221
	RBASIC(this_feature_index)->flags = T_ARRAY; /* fake VALUE, do not mark/sweep */
210 222
	rb_ary_cat(this_feature_index, feature_indexes, numberof(feature_indexes));
211 223
	st_insert(features_index, short_feature_key, (st_data_t)this_feature_index);
212 224
    }
213 225
    else {
226
        long pos = -1;
227

  
214 228
	Check_Type(this_feature_index, T_ARRAY);
229
        if (rb) {
230
            VALUE loaded_features = get_loaded_features();
231
            long i;
232
            for (i = 0; i < RARRAY_LEN(this_feature_index); ++i) {
233
                VALUE idx = RARRAY_AREF(this_feature_index, i);
234
                VALUE this_feature_path = RARRAY_AREF(loaded_features, FIX2LONG(idx));
235
                Check_Type(this_feature_path, T_STRING);
236
                if (!is_rbext_path(this_feature_path)) {
237
#if 0 /* can't wb_unprotect */
238
                    rb_ary_splice(this_feature_index, i, 0, &offset, 1);
239
                    return;
240
#endif
241
                    pos = i;
242
                    break;
243
                }
244
            }
245
        }
215 246
	rb_ary_push(this_feature_index, offset);
247
        if (pos >= 0) {
248
            VALUE *ptr = (VALUE *)RARRAY_CONST_PTR_TRANSIENT(this_feature_index);
249
            MEMMOVE(ptr + pos, ptr + pos + 1, VALUE, RARRAY_LEN(this_feature_index) - pos - 1);
250
            ptr[pos] = offset;
251
        }
216 252
    }
217 253
}
218 254

  
......
228 264
features_index_add(VALUE feature, VALUE offset)
229 265
{
230 266
    const char *feature_str, *feature_end, *ext, *p;
267
    bool rb = false;
231 268

  
232 269
    feature_str = StringValuePtr(feature);
233 270
    feature_end = feature_str + RSTRING_LEN(feature);
......
237 274
	    break;
238 275
    if (*ext != '.')
239 276
	ext = NULL;
277
    else
278
        rb = IS_RBEXT(ext);
240 279
    /* Now `ext` points to the only string matching %r{^\.[^./]*$} that is
241 280
       at the end of `feature`, or is NULL if there is no such string. */
242 281

  
......
248 287
	if (p < feature_str)
249 288
	    break;
250 289
	/* Now *p == '/'.  We reach this point for every '/' in `feature`. */
251
	features_index_add_single(p + 1, feature_end - p - 1, offset);
290
	features_index_add_single(p + 1, feature_end - p - 1, offset, false);
252 291
	if (ext) {
253
	    features_index_add_single(p + 1, ext - p - 1, offset);
292
	    features_index_add_single(p + 1, ext - p - 1, offset, rb);
254 293
	}
255 294
    }
256
    features_index_add_single(feature_str, feature_end - feature_str, offset);
295
    features_index_add_single(feature_str, feature_end - feature_str, offset, false);
257 296
    if (ext) {
258
	features_index_add_single(feature_str, ext - feature_str, offset);
297
	features_index_add_single(feature_str, ext - feature_str, offset, rb);
259 298
    }
260 299
}
261 300