Feature #4893 » String_call_initialize_v6.diff
string.c | ||
---|---|---|
return str;
|
||
}
|
||
extern int rb_obj_call_init_if_redefined(VALUE obj, int argc, VALUE *argv);
|
||
VALUE
|
||
rb_str_new(const char *ptr, long len)
|
||
{
|
||
return str_new(rb_cString, ptr, len);
|
||
/* str is already initialized by original initialize within str_new() */
|
||
VALUE str = str_new(rb_cString, ptr, len);
|
||
/* speed: call initialize only if it was redefined. See #4893 */
|
||
/* passing str itself as parameter, avoiding need for a temp str */
|
||
rb_obj_call_init_if_redefined((VALUE)str, 1, &str);
|
||
return str;
|
||
}
|
||
VALUE
|
vm_method.c | ||
---|---|---|
}
|
||
}
|
||
#define FL_CALL_INIT FL_USER18 /* TODO: move to header file */
|
||
int
|
||
rb_set_redefined_flag(VALUE klass, ID mid, int set)
|
||
{
|
||
/* current implementation uses class-object-variable (bit-flag FL_USERnn).
|
||
Q: why not use of existent "ruby_vm_redefined_flag[]"?
|
||
A: It works too, but fails after an undef/remove_method.
|
||
Additionally, the vm_redefined_flag is not a per-class but a per-method-flag.
|
||
Can be possibly normalized to a later point, after refactoring and
|
||
documenting the the vm, especially vm_method.c. The goal would be to have
|
||
per-method-flags for any method, and per-class-flags only if absolutely
|
||
unavoidable (= avoid global-status, reduce existent global-status to a more
|
||
local scope.)*/
|
||
/* redesign: introduce FL_FAST_CLASS to flag a class for fast
|
||
initialization, and test via FL_TEST(CLASS_OF(obj), FL_FAST_CLASS) instead
|
||
of klass == rb_cString */
|
||
if (ruby_running && mid == idInitialize && klass == rb_cString) {
|
||
if (set) {
|
||
FL_SET(klass, FL_CALL_INIT);
|
||
} else {
|
||
FL_UNSET(klass, FL_CALL_INIT);
|
||
}
|
||
return TRUE; /* flag was set or unset */
|
||
}
|
||
return FALSE; /* no action taken */
|
||
}
|
||
int
|
||
rb_obj_call_init_if_redefined(VALUE obj, int argc, VALUE *argv)
|
||
{
|
||
/* use only in fast_classes like String, which call the low level initialize.
|
||
Method lookup and call of initialize will be done only, if initialize
|
||
was redefined. */
|
||
if (FL_TEST(CLASS_OF(obj), FL_CALL_INIT)) {
|
||
rb_obj_call_init(obj, argc, argv);
|
||
return TRUE;
|
||
}
|
||
return FALSE; /* initialize was not called */
|
||
}
|
||
rb_method_entry_t *
|
||
rb_add_method(VALUE klass, ID mid, rb_method_type_t type, void *opts, rb_method_flag_t noex)
|
||
{
|
||
... | ... | |
default:
|
||
rb_bug("rb_add_method: unsupported method type (%d)\n", type);
|
||
}
|
||
rb_set_redefined_flag(klass, mid, TRUE);
|
||
if (type != VM_METHOD_TYPE_UNDEF) {
|
||
method_added(klass, mid);
|
||
}
|
||
... | ... | |
rb_vm_check_redefinition_opt_method(me);
|
||
rb_clear_cache_for_undef(klass, mid);
|
||
rb_unlink_method_entry(me);
|
||
rb_set_redefined_flag(klass, mid, FALSE);
|
||
CALL_METHOD_HOOK(klass, removed, mid);
|
||
}
|
||
... | ... | |
rb_add_method(klass, id, VM_METHOD_TYPE_UNDEF, 0, NOEX_PUBLIC);
|
||
rb_set_redefined_flag(klass, id, FALSE);
|
||
CALL_METHOD_HOOK(klass, undefined, id);
|
||
}
|
||
- « Previous
- 1
- …
- 11
- 12
- 13
- Next »