ruby-changes:52507
From: hsbt <ko1@a...>
Date: Thu, 13 Sep 2018 16:04:58 +0900 (JST)
Subject: [ruby-changes:52507] hsbt:r64721: Move mvm branch to tags.
hsbt 2018-09-13 16:01:55 +0900 (Thu, 13 Sep 2018) New Revision: 64721 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=64721 Log: Move mvm branch to tags. Added directories: tags/mvm/ Removed directories: branches/mvm/ Index: mvm/class.c =================================================================== --- mvm/class.c (revision 64720) +++ mvm/class.c (nonexistent) @@ -1,1394 +0,0 @@ https://github.com/ruby/ruby/blob/trunk/mvm/class.c#L0 -/********************************************************************** - - class.c - - - $Author$ - created at: Tue Aug 10 15:05:44 JST 1993 - - Copyright (C) 1993-2007 Yukihiro Matsumoto - -**********************************************************************/ - -/*! - * \defgroup class Classes and their hierarchy. - * \par Terminology - * - class: same as in Ruby. - * - singleton class: class for a particular object - * - eigenclass: = singleton class - * - metaclass: class of a class. metaclass is a kind of singleton class. - * - metametaclass: class of a metaclass. - * - meta^(n)-class: class of a meta^(n-1)-class. - * - attached object: A singleton class knows its unique instance. - * The instance is called the attached object for the singleton class. - * \{ - */ - -#include "ruby/ruby.h" -#include "ruby/st.h" -#include "method.h" -#include "vm_core.h" -#include <ctype.h> - -static ID id_attached; - -/** - * Allocates a struct RClass for a new class. - * - * \param flags initial value for basic.flags of the returned class. - * \param klass the class of the returned class. - * \return an uninitialized Class object. - * \pre \p klass must refer \c Class class or an ancestor of Class. - * \pre \code (flags | T_CLASS) != 0 \endcode - * \post the returned class can safely be \c #initialize 'd. - * - * \note this function is not Class#allocate. - */ -static VALUE -class_alloc(VALUE flags, VALUE klass) -{ - rb_classext_t *ext = ALLOC(rb_classext_t); - NEWOBJ(obj, struct RClass); - OBJSETUP(obj, klass, flags); - obj->ptr = ext; - RCLASS_IV_TBL(obj) = 0; - RCLASS_M_TBL(obj) = 0; - RCLASS_SUPER(obj) = 0; - RCLASS_IV_INDEX_TBL(obj) = 0; - return (VALUE)obj; -} - - -/*! - * A utility function that wraps class_alloc. - * - * allocates a class and initializes safely. - * \param super a class from which the new class derives. - * \return a class object. - * \pre \a super must be a class. - * \post the metaclass of the new class is Class. - */ -VALUE -rb_class_boot(VALUE super) -{ - VALUE klass = class_alloc(T_CLASS, rb_cClass); - - RCLASS_SUPER(klass) = super; - RCLASS_M_TBL(klass) = st_init_numtable(); - - OBJ_INFECT(klass, super); - return (VALUE)klass; -} - - -/*! - * Ensures a class can be derived from super. - * - * \param super a reference to an object. - * \exception TypeError if \a super is not a Class or \a super is a singleton class. - */ -void -rb_check_inheritable(VALUE super) -{ - if (TYPE(super) != T_CLASS) { - rb_raise(rb_eTypeError, "superclass must be a Class (%s given)", - rb_obj_classname(super)); - } - if (RBASIC(super)->flags & FL_SINGLETON) { - rb_raise(rb_eTypeError, "can't make subclass of singleton class"); - } - if (super == rb_cClass) { - rb_raise(rb_eTypeError, "can't make subclass of Class"); - } -} - - -/*! - * Creates a new class. - * \param super a class from which the new class derives. - * \exception TypeError \a super is not inheritable. - * \exception TypeError \a super is the Class class. - */ -VALUE -rb_class_new(VALUE super) -{ - Check_Type(super, T_CLASS); - rb_check_inheritable(super); - return rb_class_boot(super); -} - -struct clone_method_data { - st_table *tbl; - VALUE klass; -}; - -VALUE rb_iseq_clone(VALUE iseqval, VALUE newcbase); - -static int -clone_method(ID mid, const rb_method_entry_t *me, struct clone_method_data *data) -{ - if (me->def && me->def->type == VM_METHOD_TYPE_ISEQ) { - VALUE newiseqval = rb_iseq_clone(me->def->body.iseq->self, data->klass); - rb_iseq_t *iseq; - GetISeqPtr(newiseqval, iseq); - rb_add_method(data->klass, mid, VM_METHOD_TYPE_ISEQ, iseq, me->flag); - } - else { - rb_add_method_me(data->klass, mid, me, me->flag); - } - return ST_CONTINUE; -} - -/* :nodoc: */ -VALUE -rb_mod_init_copy(VALUE clone, VALUE orig) -{ - rb_obj_init_copy(clone, orig); - if (!FL_TEST(CLASS_OF(clone), FL_SINGLETON)) { - RBASIC(clone)->klass = rb_singleton_class_clone(orig); - } - RCLASS_SUPER(clone) = RCLASS_SUPER(orig); - if (RCLASS_IV_TBL(orig)) { - ID id; - - if (RCLASS_IV_TBL(clone)) { - st_free_table(RCLASS_IV_TBL(clone)); - } - RCLASS_IV_TBL(clone) = st_copy(RCLASS_IV_TBL(orig)); - CONST_ID(id, "__classpath__"); - st_delete(RCLASS_IV_TBL(clone), (st_data_t*)&id, 0); - CONST_ID(id, "__classid__"); - st_delete(RCLASS_IV_TBL(clone), (st_data_t*)&id, 0); - } - if (RCLASS_M_TBL(orig)) { - struct clone_method_data data; - - if (RCLASS_M_TBL(clone)) { - extern void rb_free_m_table(st_table *tbl); - rb_free_m_table(RCLASS_M_TBL(clone)); - } - data.tbl = RCLASS_M_TBL(clone) = st_init_numtable(); - data.klass = clone; - st_foreach(RCLASS_M_TBL(orig), clone_method, - (st_data_t)&data); - } - - return clone; -} - -/* :nodoc: */ -VALUE -rb_class_init_copy(VALUE clone, VALUE orig) -{ - if (orig == rb_cBasicObject) { - rb_raise(rb_eTypeError, "can't copy the root class"); - } - if (RCLASS_SUPER(clone) != 0 || clone == rb_cBasicObject) { - rb_raise(rb_eTypeError, "already initialized class"); - } - if (FL_TEST(orig, FL_SINGLETON)) { - rb_raise(rb_eTypeError, "can't copy singleton class"); - } - return rb_mod_init_copy(clone, orig); -} - -VALUE -rb_singleton_class_clone(VALUE obj) -{ - VALUE klass = RBASIC(obj)->klass; - - if (!FL_TEST(klass, FL_SINGLETON)) - return klass; - else { - struct clone_method_data data; - /* copy singleton(unnamed) class */ - VALUE clone = class_alloc(RBASIC(klass)->flags, 0); - - if (BUILTIN_TYPE(obj) == T_CLASS) { - RBASIC(clone)->klass = (VALUE)clone; - } - else { - RBASIC(clone)->klass = rb_singleton_class_clone(klass); - } - - RCLASS_SUPER(clone) = RCLASS_SUPER(klass); - if (RCLASS_IV_TBL(klass)) { - RCLASS_IV_TBL(clone) = st_copy(RCLASS_IV_TBL(klass)); - } - RCLASS_M_TBL(clone) = st_init_numtable(); - data.tbl = RCLASS_M_TBL(clone); - data.klass = (VALUE)clone; - st_foreach(RCLASS_M_TBL(klass), clone_method, - (st_data_t)&data); - rb_singleton_class_attached(RBASIC(clone)->klass, (VALUE)clone); - FL_SET(clone, FL_SINGLETON); - return (VALUE)clone; - } -} - -/*! - * Attach a object to a singleton class. - * @pre \a klass is the singleton class of \a obj. - */ -void -rb_singleton_class_attached(VALUE klass, VALUE obj) -{ - if (FL_TEST(klass, FL_SINGLETON)) { - if (!RCLASS_IV_TBL(klass)) { - RCLASS_IV_TBL(klass) = st_init_numtable(); - } - st_insert(RCLASS_IV_TBL(klass), id_attached, obj); - } -} - - - -#define METACLASS_OF(k) RBASIC(k)->klass - -/*! - * whether k is a meta^(n)-class of Class class - * @retval 1 if \a k is a meta^(n)-class of Class class (n >= 0) - * @retval 0 otherwise - */ -#define META_CLASS_OF_CLASS_CLASS_P(k) (METACLASS_OF(k) == k) - - -/*! - * ensures \a klass belongs to its own eigenclass. - * @return the eigenclass of \a klass - * @post \a klass belongs to the returned eigenclass. - * i.e. the attached object of the eigenclass is \a klass. - * @note this macro creates a new eigenclass if necessary. - */ -#define ENSURE_EIGENCLASS(klass) \ - (rb_ivar_get(METACLASS_OF(klass), id_attached) == klass ? METACLASS_OF(klass) : make_metaclass(klass)) - - -/*! - * Creates a metaclass of \a klass - * \param klass a class - * \return created metaclass for the class - * \pre \a klass is a Class object - * \pre \a klass has no singleton class. - * \post the class of \a klass is the returned class. - * \post the returned class is meta^(n+1)-class when \a klass is a meta^(n)-klass for n >= 0 - */ -static inline VALUE -make_metaclass(VALUE klass) -{ - VALUE super; - VALUE metaclass = rb_class_boot(Qundef); - - FL_SET(metaclass, FL_SINGLETON); - rb_singleton_class_attached(metaclass, klass); - - if (META_CLASS_OF_CLASS_CLASS_P(klass)) { - METACLASS_OF(klass) = METACLASS_OF(metaclass) = metaclass; - } - else { - VALUE tmp = METACLASS_OF(klass); /* for a meta^(n)-class klass, tmp is meta^(n)-class of Class class */ - METACLASS_OF(klass) = metaclass; - METACLASS_OF(metaclass) = ENSURE_EIGENCLASS(tmp); - } - - super = RCLASS_SUPER(klass); - while (FL_TEST(super, T_ICLASS)) super = RCLASS_SUPER(super); - RCLASS_SUPER(metaclass) = super ? ENSURE_EIGENCLASS(super) : rb_cClass; - - OBJ_INFECT(metaclass, RCLASS_SUPER(metaclass)); - - return metaclass; -} - -/*! - * Creates a singleton class for \a obj. - * \pre \a obj must not a immediate nor a special const. - * \pre \a obj must not a Class object. - * \pre \a obj has no singleton class. - */ -static inline VALUE -make_singleton_class(VALUE obj) -{ - VALUE orig_class = RBASIC(obj)->klass; - VALUE klass = rb_class_boot(orig_class); - - FL_SET(klass, FL_SINGLETON); - RBASIC(obj)->klass = klass; - rb_singleton_class_attached(klass, obj); - - METACLASS_OF(klass) = METACLASS_OF(rb_class_real(orig_class)); - return klass; -} - - -static VALUE -boot_defclass(const char *name, VALUE super) -{ - VALUE obj = rb_class_boot(super); - ID id = rb_intern(name); - - rb_name_class(obj, id); - rb_const_set((rb_cObject ? rb_cObject : obj), id, obj); - return obj; -} - -void -Init_class_hierarchy(void) -{ - id_attached = rb_intern("__attached__"); -} - -void -InitVM_class_hierarchy(void) -{ - rb_cBasicObject = boot_defclass("BasicObject", 0); - rb_cObject = boot_defclass("Object", rb_cBasicObject); - rb_cModule = boot_defclass("Module", rb_cObject); - rb_cClass = boot_defclass("Class", rb_cModule); - - RBASIC(rb_cClass)->klass - = RBASIC(rb_cModule)->klass - = RBASIC(rb_cObject)->klass - = RBASIC(rb_cBasicObject)->klass - = rb_cClass; -} - - -/*! - * \internal - * Creates a new *singleton class* for an object. - * - * \pre \a obj has no singleton class. - * \note DO NOT USE the function in an extension libraries. Use \ref rb_singleton_class. - * \param obj An object. - * \param unused ignored. - * \return The singleton class of the object. - */ -VALUE -rb_make_metaclass(VALUE obj, VALUE unused) -{ - if (BUILTIN_TYPE(obj) == T_CLASS) { - return make_metaclass(obj); - } - else { - return make_singleton_class(obj); - } -} - - -/*! - * Defines a new class. - * \param id ignored - * \param super A class from which the new class will derive. NULL means \c Object class. - * \return the created class - * \throw TypeError if super is not a \c Class object. - * - * \note the returned class will not be associated with \a id. - * You must explicitly set a class name if necessary. - */ -VALUE -rb_define_class_id(ID id, VALUE super) -{ - VALUE klass; - - if (!super) super = rb_cObject; - klass = rb_class_new(super); - rb_make_metaclass(klass, RBASIC(super)->klass); - - return klass; -} - - -/*! - * Calls Class#inherited. - * \param super A class which will be called #inherited. - * NULL means Object class. - * \param klass A Class object which derived from \a super - * \return the value \c Class#inherited's returns - * \pre Each of \a super and \a klass must be a \c Class object. - */ -VALUE -rb_class_inherited(VALUE super, VALUE klass) -{ - ID inherited; - if (!super) super = rb_cObject; - CONST_ID(inherited, "inherited"); - return rb_funcall(super, inherited, 1, klass); -} - - - -/*! - * Defines a top-level class. - * \param name name of the class - * \param super a class from which the new class will derive. - * NULL means \c Object class. - * \return the created class - * \throw TypeError if the constant name \a name is already taken but - * the constant is not a \c Class. - * \throw NameError if the class is already defined but the class can not - * be reopened because its superclass is not \a super. - * \post top-level constant named \a name refers the returned class. - * - * \note if a class named \a name is already defined and its superclass is - * \a super, the function just returns the defined class. - */ -VALUE -rb_define_class(const char *name, VALUE super) -{ - VALUE klass; - ID id; - - id = rb_intern(name); - if (rb_const_defined(rb_cObject, id)) { - klass = rb_const_get(rb_cObject, id); - if (TYPE(klass) != T_CLASS) { - rb_raise(rb_eTypeError, "%s is not a class", name); - } - if (rb_class_real(RCLASS_SUPER(klass)) != super) { - rb_raise(rb_eTypeError, "superclass mismatch for class %s", name); - } - return klass; - } - if (!super) { - rb_warn("no super class for `%s', Object assumed", name); - } - klass = rb_define_class_id(id, super); - rb_gc_register_mark_object(klass); - rb_name_class(klass, id); - rb_const_set(rb_cObject, id, klass); - rb_class_inherited(super, klass); - - return klass; -} - - -/*! - * Defines a class under the namespace of \a outer. - * \param outer a class which contains the new class. - * \param name name of the new class - * \param super a class from which the new class will derive. - * NULL means \c Object class. - * \return the created class - * \throw TypeError if the constant name \a name is already taken but - * the constant is not a \c Class. - * \throw NameError if the class is already defined but the class can not - * be reopened because its superclass is not \a super. - * \post top-level constant named \a name refers the returned class. - * - * \note if a class named \a name is already defined and its superclass is - * \a super, the function just returns the defined class. - */ -VALUE -rb_define_class_under(VALUE outer, const char *name, VALUE super) -{ - return rb_define_class_id_under(outer, rb_intern(name), super); -} - - -/*! - * Defines a class under the namespace of \a outer. - * \param outer a class which contains the new class. - * \param id name of the new class - * \param super a class from which the new class will derive. - * NULL means \c Object class. - * \return the created class - * \throw TypeError if the constant name \a name is already taken but - * the constant is not a \c Class. - * \throw NameError if the class is already defined but the class can not - * be reopened because its superclass is not \a super. - * \post top-level constant named \a name refers the returned class. - * - * \note if a class named \a name is already defined and its superclass is - * \a super, the function just returns the defined class. - */ -VALUE -rb_define_class_id_under(VALUE outer, ID id, VALUE super) -{ - VALUE klass; - - if (rb_const_defined_at(outer, id)) { - klass = rb_const_get_at(outer, id); - if (TYPE(klass) != T_CLASS) { - rb_raise(rb_eTypeError, "%s is not a class", rb_id2name(id)); - } - if (rb_class_real(RCLASS_SUPER(klass)) != super) { - rb_name_error(id, "%s is already defined", rb_id2name(id)); - } - return klass; - } - if (!super) { - rb_warn("no super class for `%s::%s', Object assumed", - rb_class2name(outer), rb_id2name(id)); - } - klass = rb_define_class_id(id, super); - rb_set_class_path_string(klass, outer, rb_id2str(id)); - rb_const_set(outer, id, klass); - rb_class_inherited(super, klass); - - return klass; -} - -VALUE -rb_module_new(void) -{ - VALUE mdl = class_alloc(T_MODULE, rb_cModule); - - RCLASS_M_TBL(mdl) = st_init_numtable(); - - return (VALUE)mdl; -} - -VALUE -rb_define_module_id(ID id) -{ - VALUE mdl; - - mdl = rb_module_new(); - rb_name_class(mdl, id); - - return mdl; -} - -VALUE -rb_define_module(const char *name) -{ - VALUE module; - ID id; - - id = rb_intern(name); - if (rb_const_defined(rb_cObject, id)) { - module = rb_const_get(rb_cObject, id); - if (TYPE(module) == T_MODULE) - return module; - rb_raise(rb_eTypeError, "%s is not a module", rb_obj_classname(module)); - } - module = rb_define_module_id(id); - rb_gc_register_mark_object(module); - rb_const_set(rb_cObject, id, module); - - return module; -} - -VALUE -rb_define_module_under(VALUE outer, const char *name) -{ - return rb_define_module_id_under(outer, rb_intern(name)); -} - -VALUE -rb_define_module_id_under(VALUE outer, ID id) -{ - VALUE module; - - if (rb_const_defined_at(outer, id)) { - module = rb_const_get_at(outer, id); - if (TYPE(module) == T_MODULE) - return module; - rb_raise(rb_eTypeError, "%s::%s is not a module", - rb_class2name(outer), rb_obj_classname(module)); - } - module = rb_define_module_id(id); - rb_const_set(outer, id, module); - rb_set_class_path_string(module, outer, rb_id2str(id)); - - return module; -} - -static VALUE -include_class_new(VALUE module, VALUE super) -{ - VALUE klass = class_alloc(T_ICLASS, rb_cClass); - - if (BUILTIN_TYPE(module) == T_ICLASS) { - module = RBASIC(module)->klass; - } - if (!RCLASS_IV_TBL(module)) { - RCLASS_IV_TBL(module) = st_init_numtable(); - } - RCLASS_IV_TBL(klass) = RCLASS_IV_TBL(module); - RCLASS_M_TBL(klass) = RCLASS_M_TBL(module); - RCLASS_SUPER(klass) = super; - if (TYPE(module) == T_ICLASS) { - RBASIC(klass)->klass = RBASIC(module)->klass; - } - else { - RBASIC(klass)->klass = module; - } - OBJ_INFECT(klass, module); - OBJ_INFECT(klass, super); - - return (VALUE)klass; -} - -void -rb_include_module(VALUE klass, VALUE module) -{ - VALUE p, c; - int changed = 0; - - rb_frozen_class_p(klass); - if (!OBJ_UNTRUSTED(klass)) { - rb_secure(4); - } - - if (TYPE(module) != T_MODULE) { - Check_Type(module, T_MODULE); - } - - OBJ_INFECT(klass, module); - c = klass; - while (module) { - int superclass_seen = FALSE; - - if (RCLASS_M_TBL(klass) == RCLASS_M_TBL(module)) - rb_raise(rb_eArgError, "cyclic include detected"); - /* ignore if the module included already in superclasses */ - for (p = RCLASS_SUPER(klass); p; p = RCLASS_SUPER(p)) { - switch (BUILTIN_TYPE(p)) { - case T_ICLASS: - if (RCLASS_M_TBL(p) == RCLASS_M_TBL(module)) { - if (!superclass_seen) { - c = p; /* move insertion point */ - } - goto skip; - } - break; - case T_CLASS: - superclass_seen = TRUE; - break; - } - } - c = RCLASS_SUPER(c) = include_class_new(module, RCLASS_SUPER(c)); - changed = 1; - skip: - module = RCLASS_SUPER(module); - } - if (changed) rb_clear_cache(); -} - -/* - * call-seq: - * mod.included_modules -> array - * - * Returns the list of modules included in <i>mod</i>. - * - * module Mixin - * end - * - * module Outer - * include Mixin - * end - * - * Mixin.included_modules #=> [] - * Outer.included_modules #=> [Mixin] - */ - -VALUE -rb_mod_included_modules(VALUE mod) -{ - VALUE ary = rb_ary_new(); - VALUE p; - - for (p = RCLASS_SUPER(mod); p; p = RCLASS_SUPER(p)) { - if (BUILTIN_TYPE(p) == T_ICLASS) { - rb_ary_push(ary, RBASIC(p)->klass); - } - } - return ary; -} - -/* - * call-seq: - * mod.include?(module) => true or false - * - * Returns <code>true</code> if <i>module</i> is included in - * <i>mod</i> or one of <i>mod</i>'s ancestors. - * - * module A - * end - * class B - * include A - * end - * class C < B - * end - * B.include?(A) #=> true - * C.include?(A) #=> true - * A.include?(A) #=> false - */ - -VALUE -rb_mod_include_p(VALUE mod, VALUE mod2) -{ - VALUE p; - - Check_Type(mod2, T_MODULE); - for (p = RCLASS_SUPER(mod); p; p = RCLASS_SUPER(p)) { - if (BUILTIN_TYPE(p) == T_ICLASS) { - if (RBASIC(p)->klass == mod2) return Qtrue; - } - } - return Qfalse; -} - -/* - * call-seq: - * mod.ancestors -> array - * - * Returns a list of modules included in <i>mod</i> (including - * <i>mod</i> (... truncated) -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/