Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
BEGIN LICENSE BLOCK ***** Version: CPL 1.0/GPL 2.0/LGPL 2.1 The contents of this file are subject to the Common Public License Version 1.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.eclipse.org/legal/cpl-v10.html Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. Copyright (C) 2001-2004 Jan Arne Petersen <jpetersen@uni-bonn.de> Copyright (C) 2002-2004 Anders Bengtsson <ndrsbngtssn@yahoo.se> Copyright (C) 2004-2005 Thomas E Enebo <enebo@acm.org> Copyright (C) 2004 Stefan Matthias Aust <sma@3plus4.de> Alternatively, the contents of this file may be used under the terms of either of the GNU General Public License Version 2 or later (the "GPL"), or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), in which case the provisions of the GPL or the LGPL are applicable instead of those above. If you wish to allow use of your version of this file only under the terms of either the GPL or the LGPL, and not to allow others to use your version of this file under the terms of the CPL, indicate your decision by deleting the provisions above and replace them with the notice and other provisions required by the GPL or the LGPL. If you do not delete the provisions above, a recipient may use your version of this file under the terms of any one of the CPL, the GPL or the LGPL. END LICENSE BLOCK ***
  
  package org.jruby;
  
  import static org.jruby.util.CodegenUtils.ci;
  import static org.jruby.util.CodegenUtils.p;
  import static org.jruby.util.CodegenUtils.sig;
  import static org.objectweb.asm.Opcodes.ACC_PRIVATE;
  import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
  import static org.objectweb.asm.Opcodes.ACC_STATIC;
  import static org.objectweb.asm.Opcodes.ACC_SUPER;
  import static org.objectweb.asm.Opcodes.ACC_VARARGS;
  
  import java.util.HashMap;
  import java.util.HashSet;
  import java.util.List;
  import java.util.Map;
  import java.util.Set;
  
  import static org.jruby.runtime.Visibility.*;
  import static org.jruby.CompatVersion.*;
  import  org.objectweb.asm.AnnotationVisitor;
  import  org.objectweb.asm.ClassWriter;

Author(s):
jpetersen
  
  @JRubyClass(name="Class", parent="Module")
  public class RubyClass extends RubyModule {
  
      private static final Logger LOG = LoggerFactory.getLogger("RubyClass");
 
     public static void createClassClass(Ruby runtimeRubyClass classClass) {
         classClass.index = .;
         classClass.setReifiedClass(RubyClass.class);
         classClass.kindOf = new RubyModule.KindOf() {
             @Override
             public boolean isKindOf(IRubyObject objRubyModule type) {
                 return obj instanceof RubyClass;
             }
         };
         
         classClass.undefineMethod("module_function");
         classClass.undefineMethod("append_features");
         classClass.undefineMethod("extend_object");
         
         classClass.defineAnnotatedMethods(RubyClass.class);
     }
     
     public static final ObjectAllocator CLASS_ALLOCATOR = new ObjectAllocator() {
         public IRubyObject allocate(Ruby runtimeRubyClass klass) {
             RubyClass clazz = new RubyClass(runtime);
             clazz.allocator = .// Class.allocate object is not allocatable before it is initialized
             return clazz;
         }
     };
 
     public ObjectAllocator getAllocator() {
         return ;
     }
 
     public void setAllocator(ObjectAllocator allocator) {
         this. = allocator;
     }

    
Set a reflective allocator that calls a no-arg constructor on the given class.

Parameters:
cls The class on which to call the default constructor to allocate
 
     public void setClassAllocator(final Class cls) {
         this. = new ObjectAllocator() {
             public IRubyObject allocate(Ruby runtimeRubyClass klazz) {
                 try {
                     RubyBasicObject object = (RubyBasicObject)cls.newInstance();
                     object.setMetaClass(klazz);
                     return object;
                 } catch (InstantiationException ie) {
                     throw runtime.newTypeError("could not allocate " + cls + " with default constructor:\n" + ie);
                 } catch (IllegalAccessException iae) {
                     throw runtime.newSecurityError("could not allocate " + cls + " due to inaccessible default constructor:\n" + iae);
                 }
             }
         };
         
         this. = cls;
     }

    
Set a reflective allocator that calls the "standard" Ruby object constructor (Ruby, RubyClass) on the given class.

Parameters:
cls The class from which to grab a standard Ruby constructor
 
     public void setRubyClassAllocator(final Class cls) {
         try {
             final Constructor constructor = cls.getConstructor(Ruby.classRubyClass.class);
             
             this. = new ObjectAllocator() {
                 public IRubyObject allocate(Ruby runtimeRubyClass klazz) {
                     try {
                         return (IRubyObject)constructor.newInstance(runtimeklazz);
                     } catch (InvocationTargetException ite) {
                         throw runtime.newTypeError("could not allocate " + cls + " with (Ruby, RubyClass) constructor:\n" + ite);
                     } catch (InstantiationException ie) {
                         throw runtime.newTypeError("could not allocate " + cls + " with (Ruby, RubyClass) constructor:\n" + ie);
                     } catch (IllegalAccessException iae) {
                         throw runtime.newSecurityError("could not allocate " + cls + " due to inaccessible (Ruby, RubyClass) constructor:\n" + iae);
                     }
                 }
             };
 
             this. = cls;
         } catch (NoSuchMethodException nsme) {
             throw new RuntimeException(nsme);
         }
     }

    
Set a reflective allocator that calls the "standard" Ruby object constructor (Ruby, RubyClass) on the given class via a static __allocate__ method intermediate.

Parameters:
cls The class from which to grab a standard Ruby __allocate__ method.
 
     public void setRubyStaticAllocator(final Class cls) {
         try {
             final Method method = cls.getDeclaredMethod("__allocate__"Ruby.classRubyClass.class);
 
             this. = new ObjectAllocator() {
                 public IRubyObject allocate(Ruby runtimeRubyClass klazz) {
                     try {
                         return (IRubyObject)method.invoke(nullruntimeklazz);
                     } catch (InvocationTargetException ite) {
                         throw runtime.newTypeError("could not allocate " + cls + " with (Ruby, RubyClass) constructor:\n" + ite);
                     } catch (IllegalAccessException iae) {
                         throw runtime.newSecurityError("could not allocate " + cls + " due to inaccessible (Ruby, RubyClass) constructor:\n" + iae);
                     }
                 }
             };
 
             this. = cls;
         } catch (NoSuchMethodException nsme) {
             throw new RuntimeException(nsme);
         }
     }
 
     @JRubyMethod(name = "allocate")
     public IRubyObject allocate() {
         if ( == null) {
             if(!(.is1_9() && this == .getBasicObject())) {
                 throw .newTypeError("can't instantiate uninitialized class");
             }
         }
         IRubyObject obj = .allocate(this);
         if (obj.getMetaClass().getRealClass() != getRealClass()) {
             throw .newTypeError("wrong instance allocation");
         }
         return obj;
     }
 
     public CallSite getBaseCallSite(int idx) {
         return [idx];
     }
 
     public CallSite[] getBaseCallSites() {
         return ;
     }
     
     public CallSite[] getExtraCallSites() {
         return ;
     }
 
     public static class VariableAccessor {
         private final String name;
         private final int index;
         private final int classId;
         public VariableAccessor(String nameint indexint classId) {
             this. = index;
             this. = classId;
             this. = name;
         }
         public int getClassId() {
             return ;
         }
         public int getIndex() {
             return ;
         }
         public String getName() {
             return ;
         }
         public Object get(Object object) {
             return ((IRubyObject)object).getVariable();
         }
         public void set(Object objectObject value) {
             ((IRubyObject)object).setVariable(value);
         }
         public static final VariableAccessor DUMMY_ACCESSOR = new VariableAccessor(null, -1, -1);
     }
 
         return ;
     }
     
     
 
 
     private synchronized final VariableAccessor allocateVariableAccessor(String name) {
         String[] myVariableNames = ;
 
         int newIndex = myVariableNames.length;
         String[] newVariableNames = new String[newIndex + 1];
 
         VariableAccessor newVariableAccessor = new VariableAccessor(namenewIndexthis.);
 
         System.arraycopy(myVariableNames, 0, newVariableNames, 0, newIndex);
 
         newVariableNames[newIndex] = name;
          = newVariableNames;
 
         return newVariableAccessor;
     }
 
         VariableAccessor ivarAccessor = .get(name);
         if (ivarAccessor == null) {
 
             synchronized (this) {
                 Map<StringVariableAccessormyVariableAccessors = ;
                 ivarAccessor = myVariableAccessors.get(name);
 
                 if (ivarAccessor == null) {
                     // allocate a new accessor and populate a new table
                     ivarAccessor = allocateVariableAccessor(name);
                     Map<StringVariableAccessornewVariableAccessors = new HashMap<StringVariableAccessor>(myVariableAccessors.size() + 1);
 
                     newVariableAccessors.putAll(myVariableAccessors);
                     newVariableAccessors.put(nameivarAccessor);
 
                      = newVariableAccessors;
                 }
             }
         }
         return ivarAccessor;
     }
 
     private synchronized VariableAccessor allocateIdAccessor() {
         if ( == .) {
              = allocateVariableAccessor("object_id");
         }
 
         return ;
     }
 
     private synchronized VariableAccessor allocateCExtHandleAccessor() {
         if ( == .) {
              = allocateVariableAccessor("cext");
         }
 
         return ;
     }
 
     private synchronized VariableAccessor allocateFFIHandleAccessor() {
         if ( == .) {
              = allocateVariableAccessor("ffi");
         }
 
         return ;
     }
 
 
         VariableAccessor accessor = getVariableAccessorsForRead().get(name);
         if (accessor == nullaccessor = .;
         return accessor;
     }
 
         VariableAccessor accessor = ;
         return accessor != . ? accessor : allocateIdAccessor();
     }
 
         return ;
     }
 
         VariableAccessor accessor = ;
         return accessor != . ? accessor : allocateCExtHandleAccessor();
     }
 
         return ;
     }
 
         VariableAccessor accessor = ;
         return accessor != . ? accessor : allocateFFIHandleAccessor();
     }
 
         return ;
     }
 
     public int getVariableTableSize() {
         return .size();
     }
 
     public int getVariableTableSizeWithExtras() {
         return .;
     }
 
         return new HashMap<StringVariableAccessor>(getVariableAccessorsForRead());
     }

    
Get an array of all the known instance variable names. The offset into the array indicates the offset of the variable's value in the per-object variable array.

Returns:
a copy of the array of known instance variable names
 
     public String[] getVariableNames() {
         String[] original = ;
         String[] copy = new String[original.length];
         System.arraycopy(original, 0, copy, 0, original.length);
         return copy;
     }
 
     @Override
     public int getNativeTypeIndex() {
         return .;
     }
     
     @Override
     public boolean isModule() {
         return false;
     }
 
     @Override
     public boolean isClass() {
         return true;
     }
 
     @Override
     public boolean isSingleton() {
         return false;
     }

    
boot_defclass Create an initial Object meta class before Module and Kernel dependencies have squirreled themselves together.

Parameters:
runtime we need it
Returns:
a half-baked meta class for object
 
     public static RubyClass createBootstrapClass(Ruby runtimeString nameRubyClass superClassObjectAllocator allocator) {
         RubyClass obj;
 
         if (superClass == null ) {  // boot the Object class 
             obj = new RubyClass(runtime);
             obj.marshal = ;
         } else {                    // boot the Module and Class classes
             obj = new RubyClass(runtimesuperClass);
         }
         obj.setAllocator(allocator);
         obj.setBaseName(name);
         return obj;
     }

    
separate path for MetaClass and IncludedModuleWrapper construction (rb_class_boot version for MetaClasses) no marshal, allocator initialization and addSubclass(this) here!
 
     protected RubyClass(Ruby runtimeRubyClass superClassboolean objectSpace) {
         super(runtimeruntime.getClassClass(), objectSpace);
         this. = runtime;
         this. = superClass == null ? null : superClass.getRealClass();
         setSuperClass(superClass); // this is the only case it might be null here (in MetaClass construction)
     }
    
    
used by CLASS_ALLOCATOR (any Class' class will be a Class!) also used to bootstrap Object class
 
     protected RubyClass(Ruby runtime) {
         super(runtimeruntime.getClassClass());
         this. = runtime;
         this. = this;
          = .;
     }
    
    
rb_class_boot (for plain Classes) also used to bootstrap Module and Class classes
 
     protected RubyClass(Ruby runtimeRubyClass superClazz) {
         this(runtime);
         setSuperClass(superClazz);
          = superClazz.marshal// use parent's marshal
         superClazz.addSubclass(this);
          = superClazz.allocator;
         
         infectBy();        
     }
    
    
A constructor which allows passing in an array of supplementary call sites.
 
     protected RubyClass(Ruby runtimeRubyClass superClazzCallSite[] extraCallSites) {
         this(runtime);
         setSuperClass(superClazz);
         this. = superClazz.marshal// use parent's marshal
         superClazz.addSubclass(this);
         
         this. = extraCallSites;
         
         infectBy();        
     }

    
Construct a new class with the given name scoped under Object (global) and with Object as its immediate superclass. Corresponds to rb_class_new in MRI.
 
     public static RubyClass newClass(Ruby runtimeRubyClass superClass) {
         if (superClass == runtime.getClassClass()) throw runtime.newTypeError("can't make subclass of Class");
         if (superClass.isSingleton()) throw runtime.newTypeError("can't make subclass of virtual class");
         return new RubyClass(runtimesuperClass);        
     }

    
A variation on newClass that allow passing in an array of supplementary call sites to improve dynamic invocation.
 
     public static RubyClass newClass(Ruby runtimeRubyClass superClassCallSite[] extraCallSites) {
         if (superClass == runtime.getClassClass()) throw runtime.newTypeError("can't make subclass of Class");
         if (superClass.isSingleton()) throw runtime.newTypeError("can't make subclass of virtual class");
         return new RubyClass(runtimesuperClassextraCallSites);        
     }

    
Construct a new class with the given name, allocator, parent class, and containing class. If setParent is true, the class's parent will be explicitly set to the provided parent (rather than the new class just being assigned to a constant in that parent). Corresponds to rb_class_new/rb_define_class_id/rb_name_class/rb_set_class_path in MRI.
 
     public static RubyClass newClass(Ruby runtimeRubyClass superClassString nameObjectAllocator allocatorRubyModule parentboolean setParent) {
         RubyClass clazz = newClass(runtimesuperClass);
         clazz.setBaseName(name);
         clazz.setAllocator(allocator);
         clazz.makeMetaClass(superClass.getMetaClass());
         if (setParentclazz.setParent(parent);
         parent.setConstant(nameclazz);
         clazz.inherit(superClass);
         return clazz;
     }

    
A variation on newClass that allows passing in an array of supplementary call sites to improve dynamic invocation performance.
 
     public static RubyClass newClass(Ruby runtimeRubyClass superClassString nameObjectAllocator allocatorRubyModule parentboolean setParentCallSite[] extraCallSites) {
         RubyClass clazz = newClass(runtimesuperClassextraCallSites);
         clazz.setBaseName(name);
         clazz.setAllocator(allocator);
         clazz.makeMetaClass(superClass.getMetaClass());
         if (setParentclazz.setParent(parent);
         parent.setConstant(nameclazz);
         clazz.inherit(superClass);
         return clazz;
     }

    
rb_make_metaclass
 
     @Override
     public RubyClass makeMetaClass(RubyClass superClass) {
         if (isSingleton()) { // could be pulled down to RubyClass in future
             MetaClass klass = new MetaClass(superClassthis); // rb_class_boot
             setMetaClass(klass);
 
             klass.setMetaClass(klass);
             klass.setSuperClass(getSuperClass().getRealClass().getMetaClass());
             
             return klass;
         } else {
             return super.makeMetaClass(superClass);
         }
     }
     
     @Deprecated
     public IRubyObject invoke(ThreadContext contextIRubyObject selfint methodIndexString nameIRubyObject[] argsCallType callTypeBlock block) {
         return invoke(contextselfnameargscallTypeblock);
     }
     
     public boolean notVisibleAndNotMethodMissing(DynamicMethod methodString nameIRubyObject callerCallType callType) {
         return !method.isCallableFrom(callercallType) && !name.equals("method_missing");
     }
     
     public IRubyObject invoke(ThreadContext contextIRubyObject selfString name,
             CallType callTypeBlock block) {
         DynamicMethod method = searchMethod(name);
         IRubyObject caller = context.getFrameSelf();
         if (shouldCallMethodMissing(methodnamecallercallType)) {
             return RuntimeHelpers.callMethodMissing(contextselfmethod.getVisibility(), namecallTypeblock);
         }
         return method.call(contextselfthisnameblock);
     }
     
     public IRubyObject finvoke(ThreadContext contextIRubyObject selfString nameBlock block) {
         DynamicMethod method = searchMethod(name);
         if (shouldCallMethodMissing(method)) {
             return RuntimeHelpers.callMethodMissing(contextselfmethod.getVisibility(), name.block);
         }
         return method.call(contextselfthisnameblock);
     }
     
     public IRubyObject invoke(ThreadContext contextIRubyObject selfString name,
             IRubyObject[] argsCallType callTypeBlock block) {
         assert args != null;
         DynamicMethod method = searchMethod(name);
         IRubyObject caller = context.getFrameSelf();
         if (shouldCallMethodMissing(methodnamecallercallType)) {
             return RuntimeHelpers.callMethodMissing(contextselfmethod.getVisibility(), namecallTypeargsblock);
         }
         return method.call(contextselfthisnameargsblock);
     }
     
     public IRubyObject finvoke(ThreadContext contextIRubyObject selfString name,
             IRubyObject[] argsBlock block) {
         assert args != null;
         DynamicMethod method = searchMethod(name);
         if (shouldCallMethodMissing(method)) {
             return RuntimeHelpers.callMethodMissing(contextselfmethod.getVisibility(), name.argsblock);
         }
         return method.call(contextselfthisnameargsblock);
     }
     
     public IRubyObject invoke(ThreadContext contextIRubyObject selfString name,
             IRubyObject argCallType callTypeBlock block) {
         DynamicMethod method = searchMethod(name);
         IRubyObject caller = context.getFrameSelf();
         if (shouldCallMethodMissing(methodnamecallercallType)) {
             return RuntimeHelpers.callMethodMissing(contextselfmethod.getVisibility(), namecallTypeargblock);
         }
         return method.call(contextselfthisnameargblock);
     }
     
     public IRubyObject finvoke(ThreadContext contextIRubyObject selfString name,
             IRubyObject argBlock block) {
         DynamicMethod method = searchMethod(name);
         if (shouldCallMethodMissing(method)) {
             return RuntimeHelpers.callMethodMissing(contextselfmethod.getVisibility(), name.argblock);
         }
         return method.call(contextselfthisnameargblock);
     }
     
     public IRubyObject invoke(ThreadContext contextIRubyObject selfString name,
             IRubyObject arg0IRubyObject arg1CallType callTypeBlock block) {
         DynamicMethod method = searchMethod(name);
         IRubyObject caller = context.getFrameSelf();
         if (shouldCallMethodMissing(methodnamecallercallType)) {
             return RuntimeHelpers.callMethodMissing(contextselfmethod.getVisibility(), namecallTypearg0arg1block);
         }
         return method.call(contextselfthisnamearg0arg1block);
     }
     
     public IRubyObject finvoke(ThreadContext contextIRubyObject selfString name,
             IRubyObject arg0IRubyObject arg1Block block) {
         DynamicMethod method = searchMethod(name);
         if (shouldCallMethodMissing(method)) {
             return RuntimeHelpers.callMethodMissing(contextselfmethod.getVisibility(), name.arg0arg1block);
         }
         return method.call(contextselfthisnamearg0arg1block);
     }
     
     public IRubyObject invoke(ThreadContext contextIRubyObject selfString name,
             IRubyObject arg0IRubyObject arg1IRubyObject arg2CallType callTypeBlock block) {
         DynamicMethod method = searchMethod(name);
         IRubyObject caller = context.getFrameSelf();
         if (shouldCallMethodMissing(methodnamecallercallType)) {
             return RuntimeHelpers.callMethodMissing(contextselfmethod.getVisibility(), namecallTypearg0arg1arg2block);
         }
         return method.call(contextselfthisnamearg0arg1arg2block);
     }
     
     public IRubyObject finvoke(ThreadContext contextIRubyObject selfString name,
             IRubyObject arg0IRubyObject arg1IRubyObject arg2Block block) {
         DynamicMethod method = searchMethod(name);
         if (shouldCallMethodMissing(method)) {
             return RuntimeHelpers.callMethodMissing(contextselfmethod.getVisibility(), name.arg0arg1arg2block);
         }
         return method.call(contextselfthisnamearg0arg1arg2block);
     }
     
     public IRubyObject invoke(ThreadContext contextIRubyObject selfString name,
             CallType callType) {
         DynamicMethod method = searchMethod(name);
         IRubyObject caller = context.getFrameSelf();
         if (shouldCallMethodMissing(methodnamecallercallType)) {
             return RuntimeHelpers.callMethodMissing(contextselfmethod.getVisibility(), namecallType.);
         }
         return method.call(contextselfthisname);
     }
     
     public IRubyObject finvoke(ThreadContext contextIRubyObject selfString name) {
         DynamicMethod method = searchMethod(name);
         if (shouldCallMethodMissing(method)) {
             return RuntimeHelpers.callMethodMissing(contextselfmethod.getVisibility(), name..);
         }
         return method.call(contextselfthisname);
     }
 
     public IRubyObject finvokeChecked(ThreadContext contextIRubyObject selfString name) {
         DynamicMethod method = searchMethod(name);
         if(method.isUndefined()) {
             DynamicMethod methodMissing = searchMethod("method_missing");
             if(methodMissing.isUndefined() || methodMissing.equals(context.runtime.getDefaultMethodMissing())) {
                 return null;
             }
 
             try {
                 return RuntimeHelpers.callMethodMissing(contextselfmethod.getVisibility(), name..);
             } catch(RaiseException e) {
                 if(context.runtime.getNoMethodError().isInstance(e.getException())) {
                     if(self.respondsTo(name)) {
                         throw e;
                     } else {
                         // we swallow, so we also must clear $!
                         context.setErrorInfo(context.nil);
                         return null;
                     }
                 } else {
                     throw e;
                 }
             }
         }
         return method.call(contextselfthisname);
     }
     
     public IRubyObject invoke(ThreadContext contextIRubyObject selfString name,
             IRubyObject[] argsCallType callType) {
         assert args != null;
         DynamicMethod method = searchMethod(name);
         IRubyObject caller = context.getFrameSelf();
         if (shouldCallMethodMissing(methodnamecallercallType)) {
             return RuntimeHelpers.callMethodMissing(contextselfmethod.getVisibility(), namecallTypeargs.);
         }
         return method.call(contextselfthisnameargs);
     }
     
     public IRubyObject finvoke(ThreadContext contextIRubyObject selfString name,
             IRubyObject[] args) {
         assert args != null;
         DynamicMethod method = searchMethod(name);
         if (shouldCallMethodMissing(method)) {
             return RuntimeHelpers.callMethodMissing(contextselfmethod.getVisibility(), name.args.);
         }
         return method.call(contextselfthisnameargs);
     }
     
     public IRubyObject invoke(ThreadContext contextIRubyObject selfString name,
             IRubyObject argCallType callType) {
         DynamicMethod method = searchMethod(name);
         IRubyObject caller = context.getFrameSelf();
         if (shouldCallMethodMissing(methodnamecallercallType)) {
             return RuntimeHelpers.callMethodMissing(contextselfmethod.getVisibility(), namecallTypearg.);
         }
         return method.call(contextselfthisnamearg);
     }
     
     public IRubyObject finvoke(ThreadContext contextIRubyObject selfString name,
             IRubyObject arg) {
         DynamicMethod method = searchMethod(name);
         if (shouldCallMethodMissing(method)) {
             return RuntimeHelpers.callMethodMissing(contextselfmethod.getVisibility(), name.arg.);
         }
         return method.call(contextselfthisnamearg);
     }
     
     public IRubyObject invoke(ThreadContext contextIRubyObject selfString name,
             IRubyObject arg0IRubyObject arg1CallType callType) {
         DynamicMethod method = searchMethod(name);
         IRubyObject caller = context.getFrameSelf();
         if (shouldCallMethodMissing(methodnamecallercallType)) {
             return RuntimeHelpers.callMethodMissing(contextselfmethod.getVisibility(), namecallTypearg0arg1.);
         }
         return method.call(contextselfthisnamearg0arg1);
     }
     
     public IRubyObject finvoke(ThreadContext contextIRubyObject selfString name,
             IRubyObject arg0IRubyObject arg1) {
         DynamicMethod method = searchMethod(name);
         if (shouldCallMethodMissing(method)) {
             return RuntimeHelpers.callMethodMissing(contextselfmethod.getVisibility(), name.arg0arg1.);
         }
         return method.call(contextselfthisnamearg0arg1);
     }
     
     public IRubyObject invoke(ThreadContext contextIRubyObject selfString name,
             IRubyObject arg0IRubyObject arg1IRubyObject arg2CallType callType) {
         DynamicMethod method = searchMethod(name);
         IRubyObject caller = context.getFrameSelf();
         if (shouldCallMethodMissing(methodnamecallercallType)) {
             return RuntimeHelpers.callMethodMissing(contextselfmethod.getVisibility(), namecallTypearg0arg1arg2.);
         }
         return method.call(contextselfthisnamearg0arg1arg2);
     }
     
     public IRubyObject finvoke(ThreadContext contextIRubyObject selfString name,
             IRubyObject arg0IRubyObject arg1IRubyObject arg2) {
         DynamicMethod method = searchMethod(name);
         if (shouldCallMethodMissing(method)) {
             return RuntimeHelpers.callMethodMissing(contextselfmethod.getVisibility(), name.arg0arg1arg2.);
         }
         return method.call(contextselfthisnamearg0arg1arg2);
     }
 
     private void dumpReifiedClass(String dumpDirString javaPathbyte[] classBytes) {
         if (dumpDir != null) {
             if (dumpDir.equals("")) {
                 dumpDir = ".";
             }
             java.io.FileOutputStream classStream = null;
             try {
                 java.io.File classFile = new java.io.File(dumpDirjavaPath + ".class");
                 classFile.getParentFile().mkdirs();
                 classStream = new java.io.FileOutputStream(classFile);
                 classStream.write(classBytes);
             } catch (IOException io) {
                 getRuntime().getWarnings().warn("unable to dump class file: " + io.getMessage());
             } finally {
                 if (classStream != null) {
                     try {
                         classStream.close();
                     } catch (IOException ignored) {
                     }
                 }
             }
         }
     }
 
     private void generateMethodAnnotations(Map<ClassMap<StringObject>> methodAnnosSkinnyMethodAdapter mList<Map<ClassMap<StringObject>>> parameterAnnos) {
         if (methodAnnos != null && methodAnnos.size() != 0) {
             for (Map.Entry<ClassMap<StringObject>> entry : methodAnnos.entrySet()) {
                 m.visitAnnotationWithFields(ci(entry.getKey()), trueentry.getValue());
             }
         }
         if (parameterAnnos != null && parameterAnnos.size() != 0) {
             for (int i = 0; i < parameterAnnos.size(); i++) {
                 Map<ClassMap<StringObject>> annos = parameterAnnos.get(i);
                 if (annos != null && annos.size() != 0) {
                     for (Iterator<Map.Entry<ClassMap<StringObject>>> it = annos.entrySet().iterator(); it.hasNext();) {
                         Map.Entry<ClassMap<StringObject>> entry = it.next();
                         m.visitParameterAnnotationWithFields(ici(entry.getKey()), trueentry.getValue());
                     }
                 }
             }
         }
     }
     
     private boolean shouldCallMethodMissing(DynamicMethod method) {
         return method.isUndefined();
     }
     private boolean shouldCallMethodMissing(DynamicMethod methodString nameIRubyObject callerCallType callType) {
         return method.isUndefined() || notVisibleAndNotMethodMissing(methodnamecallercallType);
     }
     
     public IRubyObject invokeInherited(ThreadContext contextIRubyObject selfIRubyObject subclass) {
         DynamicMethod method = getMetaClass().searchMethod("inherited");
 
         if (method.isUndefined()) {
             return RuntimeHelpers.callMethodMissing(contextselfmethod.getVisibility(), "inherited"..);
         }
 
         return method.call(contextselfgetMetaClass(), "inherited"subclass.);
     }

    
rb_class_new_instance
 
     @JRubyMethod(name = "new", omit = true)
     public IRubyObject newInstance(ThreadContext contextBlock block) {
         IRubyObject obj = allocate();
         [].call(contextobjobjblock);
         return obj;
     }
 
     @JRubyMethod(name = "new", omit = true)
     public IRubyObject newInstance(ThreadContext contextIRubyObject arg0Block block) {
         IRubyObject obj = allocate();
         [].call(contextobjobjarg0block);
         return obj;
     }
 
     @JRubyMethod(name = "new", omit = true)
     public IRubyObject newInstance(ThreadContext contextIRubyObject arg0IRubyObject arg1Block block) {
         IRubyObject obj = allocate();
         [].call(contextobjobjarg0arg1block);
         return obj;
     }
 
     @JRubyMethod(name = "new", omit = true)
     public IRubyObject newInstance(ThreadContext contextIRubyObject arg0IRubyObject arg1IRubyObject arg2Block block) {
         IRubyObject obj = allocate();
         [].call(contextobjobjarg0arg1arg2block);
         return obj;
     }
 
     @JRubyMethod(name = "new", rest = true, omit = true)
     public IRubyObject newInstance(ThreadContext contextIRubyObject[] argsBlock block) {
         IRubyObject obj = allocate();
         [].call(contextobjobjargsblock);
         return obj;
     }

    
rb_class_initialize
 
     @JRubyMethod(compat = , visibility = )
     @Override
     public IRubyObject initialize(ThreadContext contextBlock block) {
         checkNotInitialized();
         return initializeCommon(context.getObject(), blockfalse);
     }
         
     @JRubyMethod(compat = , visibility = )
     public IRubyObject initialize(ThreadContext contextIRubyObject superObjectBlock block) {
         checkNotInitialized();
         checkInheritable(superObject);
         return initializeCommon(context, (RubyClass)superObjectblockfalse);
     }
         
     @JRubyMethod(name = "initialize", compat = , visibility = )
     public IRubyObject initialize19(ThreadContext contextBlock block) {
         checkNotInitialized();
         return initializeCommon(context.getObject(), blocktrue);
     }
         
     @JRubyMethod(name = "initialize", compat = , visibility = )
     public IRubyObject initialize19(ThreadContext contextIRubyObject superObjectBlock block) {
         checkNotInitialized();
         checkInheritable(superObject);
         return initializeCommon(context, (RubyClass)superObjectblocktrue);
     }
 
     private IRubyObject initializeCommon(ThreadContext contextRubyClass superClazzBlock blockboolean ruby1_9 /*callInheritBeforeSuper*/) {
         setSuperClass(superClazz);
          = superClazz.allocator;
         makeMetaClass(superClazz.getMetaClass());
 
          = superClazz.marshal;
 
         superClazz.addSubclass(this);
 
         if (ruby1_9) {
             inherit(superClazz);
             super.initialize(contextblock);
         } else {
             super.initialize(contextblock);
             inherit(superClazz);
         }
 
         return this;
     }

    
rb_class_init_copy
 
     @JRubyMethod(name = "initialize_copy", required = 1, visibility = )
     @Override
     public IRubyObject initialize_copy(IRubyObject original){
         checkNotInitialized();
         if (original instanceof MetaClassthrow .newTypeError("can't copy singleton class");        
         
         super.initialize_copy(original);
          = ((RubyClass)original).
         return this;        
     }
 
     protected void setModuleSuperClass(RubyClass superClass) {
         // remove us from old superclass's child classes
         if (this. != nullthis..removeSubclass(this);
         // add us to new superclass's child classes
         superClass.addSubclass(this);
         // update superclass reference
         setSuperClass(superClass);
     }
     
     public Collection<RubyClasssubclasses(boolean includeDescendants) {
         Set<RubyClassmySubclasses = ;
         if (mySubclasses != null) {
             Collection<RubyClassmine = new ArrayList<RubyClass>(mySubclasses);
             if (includeDescendants) {
                 for (RubyClass imySubclasses) {
                     mine.addAll(i.subclasses(includeDescendants));
                 }
             }
 
             return mine;
         } else {
             return .;
         }
     }

    
Add a new subclass to the weak set of subclasses. This version always constructs a new set to avoid having to synchronize against the set when iterating it for invalidation in invalidateCacheDescendants.

Parameters:
subclass The subclass to add
 
     public synchronized void addSubclass(RubyClass subclass) {
         synchronized (.getHierarchyLock()) {
             Set<RubyClassoldSubclasses = ;
             if (oldSubclasses == null = oldSubclasses = new WeakHashSet<RubyClass>(4);