Project

General

Profile

Feature #4893 ยป String_call_initialize_v6.diff

stable patch with some doc subjecting possible further processing - lazaridis.com (Lazaridis Ilias), 07/21/2011 02:24 PM

View differences:

string.c
406 406
    return str;
407 407
}
408 408

  
409
extern int rb_obj_call_init_if_redefined(VALUE obj, int argc, VALUE *argv);
410

  
409 411
VALUE
410 412
rb_str_new(const char *ptr, long len)
411 413
{
412
    return str_new(rb_cString, ptr, len);
414
    /* str is already initialized by original initialize within str_new() */
415
    VALUE str = str_new(rb_cString, ptr, len);
416

  
417
    /* speed: call initialize only if it was redefined. See #4893 */
418
    /* passing str itself as parameter, avoiding need for a temp str */
419
    rb_obj_call_init_if_redefined((VALUE)str, 1, &str);
420

  
421
    return str;
413 422
}
414 423

  
415 424
VALUE
vm_method.c
258 258
    }
259 259
}
260 260

  
261
#define FL_CALL_INIT FL_USER18 /* TODO: move to header file */
262

  
263
int
264
rb_set_redefined_flag(VALUE klass, ID mid, int set)
265
{
266
/* current implementation uses class-object-variable (bit-flag FL_USERnn).
267
Q: why not use of existent "ruby_vm_redefined_flag[]"?
268
A: It works too, but fails after an undef/remove_method.
269
   Additionally, the vm_redefined_flag is not a per-class but a per-method-flag.
270
Can be possibly normalized to a later point, after refactoring and
271
documenting the the vm, especially vm_method.c. The goal would be to have
272
per-method-flags for any method, and per-class-flags only if absolutely
273
unavoidable (= avoid global-status, reduce existent global-status to a more
274
local scope.)*/
275

  
276
/*  redesign: introduce FL_FAST_CLASS to flag a class for fast
277
initialization, and test via FL_TEST(CLASS_OF(obj), FL_FAST_CLASS) instead
278
of klass == rb_cString */
279

  
280
    if (ruby_running && mid == idInitialize && klass == rb_cString) {
281
	if (set) {
282
	    FL_SET(klass, FL_CALL_INIT);
283
	} else {
284
	    FL_UNSET(klass, FL_CALL_INIT);
285
	}
286
	return TRUE; /* flag was set or unset */
287
    }
288
    return FALSE; /* no action taken */
289
}
290

  
291
int
292
rb_obj_call_init_if_redefined(VALUE obj, int argc, VALUE *argv)
293
{
294
/*  use only in fast_classes like String, which call the low level initialize.
295
    Method lookup and call of initialize will be done only, if initialize
296
    was redefined. */
297

  
298
    if (FL_TEST(CLASS_OF(obj), FL_CALL_INIT)) {
299
	rb_obj_call_init(obj, argc, argv);
300
	return TRUE;
301
    }
302
    return FALSE; /* initialize was not called */
303
}
304

  
261 305
rb_method_entry_t *
262 306
rb_add_method(VALUE klass, ID mid, rb_method_type_t type, void *opts, rb_method_flag_t noex)
263 307
{
......
304 348
      default:
305 349
	rb_bug("rb_add_method: unsupported method type (%d)\n", type);
306 350
    }
351

  
352
    rb_set_redefined_flag(klass, mid, TRUE);
353

  
307 354
    if (type != VM_METHOD_TYPE_UNDEF) {
308 355
	method_added(klass, mid);
309 356
    }
......
441 488
    rb_vm_check_redefinition_opt_method(me);
442 489
    rb_clear_cache_for_undef(klass, mid);
443 490
    rb_unlink_method_entry(me);
444

  
491
    rb_set_redefined_flag(klass, mid, FALSE);
445 492
    CALL_METHOD_HOOK(klass, removed, mid);
446 493
}
447 494

  
......
628 675

  
629 676
    rb_add_method(klass, id, VM_METHOD_TYPE_UNDEF, 0, NOEX_PUBLIC);
630 677

  
678
    rb_set_redefined_flag(klass, id, FALSE);
679

  
631 680
    CALL_METHOD_HOOK(klass, undefined, id);
632 681
}
633 682