⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 natclass.cc

📁 this gcc-g++-3.3.1.tar.gz is a source file of gcc, you can learn more about gcc through this codes f
💻 CC
📖 第 1 页 / 共 4 页
字号:
// Interface Dispatch Table" whose size is (number of methods + 1) words.// The first word is a pointer to the interface (i.e. the java.lang.Class// instance for that interface).  The remaining words are pointers to the// actual methods that implement the methods declared in the interface,// in order of declaration.//// Append partial interface dispatch table for "iface" to "itable", at// position itable_pos.// Returns the offset at which the next partial ITable should be appended.jshort_Jv_AppendPartialITable (jclass klass, jclass iface, void **itable,                          jshort pos){  using namespace java::lang::reflect;  itable[pos++] = (void *) iface;  _Jv_Method *meth;    for (int j=0; j < iface->method_count; j++)    {      meth = NULL;      for (jclass cl = klass; cl; cl = cl->getSuperclass())        {	  meth = _Jv_GetMethodLocal (cl, iface->methods[j].name,				     iface->methods[j].signature);		 	  if (meth)	    break;	}      if (meth && (meth->name->data[0] == '<'))	{	  // leave a placeholder in the itable for hidden init methods.          itable[pos] = NULL;		}      else if (meth)        {	  if (Modifier::isStatic(meth->accflags))	    throw new java::lang::IncompatibleClassChangeError	      (_Jv_GetMethodString (klass, meth->name));	  if (Modifier::isAbstract(meth->accflags))	    throw new java::lang::AbstractMethodError	      (_Jv_GetMethodString (klass, meth->name));	  if (! Modifier::isPublic(meth->accflags))	    throw new java::lang::IllegalAccessError	      (_Jv_GetMethodString (klass, meth->name));	  itable[pos] = meth->ncode;	}      else        {	  // The method doesn't exist in klass. Binary compatibility rules	  // permit this, so we delay the error until runtime using a pointer	  // to a method which throws an exception.	  itable[pos] = (void *) _Jv_ThrowNoSuchMethodError;	}      pos++;    }      return pos;}static _Jv_Mutex_t iindex_mutex;static bool iindex_mutex_initialized = false;// We need to find the correct offset in the Class Interface Dispatch // Table for a given interface. Once we have that, invoking an interface // method just requires combining the Method's index in the interface // (known at compile time) to get the correct method.  Doing a type test // (cast or instanceof) is the same problem: Once we have a possible Partial // Interface Dispatch Table, we just compare the first element to see if it // matches the desired interface. So how can we find the correct offset?  // Our solution is to keep a vector of candiate offsets in each interface // (idt->iface.ioffsets), and in each class we have an index // (idt->cls.iindex) used to select the correct offset from ioffsets.//// Calculate and return iindex for a new class. // ifaces is a vector of num interfaces that the class implements.// offsets[j] is the offset in the interface dispatch table for the// interface corresponding to ifaces[j].// May extend the interface ioffsets if required.jshort_Jv_FindIIndex (jclass *ifaces, jshort *offsets, jshort num){  int i;  int j;    // Acquire a global lock to prevent itable corruption in case of multiple   // classes that implement an intersecting set of interfaces being linked  // simultaneously. We can assume that the mutex will be initialized  // single-threaded.  if (! iindex_mutex_initialized)    {      _Jv_MutexInit (&iindex_mutex);      iindex_mutex_initialized = true;    }    _Jv_MutexLock (&iindex_mutex);    for (i=1;; i++)  /* each potential position in ioffsets */    {      for (j=0;; j++)  /* each iface */        {	  if (j >= num)	    goto found;	  if (i >= ifaces[j]->idt->iface.ioffsets[0])	    continue;	  int ioffset = ifaces[j]->idt->iface.ioffsets[i];	  /* We can potentially share this position with another class. */	  if (ioffset >= 0 && ioffset != offsets[j])	    break; /* Nope. Try next i. */	  	}    }  found:  for (j = 0; j < num; j++)    {      int len = ifaces[j]->idt->iface.ioffsets[0];      if (i >= len) 	{	  /* Resize ioffsets. */	  int newlen = 2 * len;	  if (i >= newlen)	    newlen = i + 3;	  jshort *old_ioffsets = ifaces[j]->idt->iface.ioffsets;	  jshort *new_ioffsets = (jshort *) _Jv_Realloc (old_ioffsets, 	                                  newlen * sizeof(jshort));	  	  new_ioffsets[0] = newlen;	  while (len < newlen)	    new_ioffsets[len++] = -1;	  	  ifaces[j]->idt->iface.ioffsets = new_ioffsets;	}      ifaces[j]->idt->iface.ioffsets[i] = offsets[j];    }  _Jv_MutexUnlock (&iindex_mutex);  return i;}// Only used by serializationjava::lang::reflect::Field *java::lang::Class::getPrivateField (jstring name){  int hash = name->hashCode ();  java::lang::reflect::Field* rfield;  for (int i = 0;  i < field_count;  i++)    {      _Jv_Field *field = &fields[i];      if (! _Jv_equal (field->name, name, hash))	continue;      rfield = new java::lang::reflect::Field ();      rfield->offset = (char*) field - (char*) fields;      rfield->declaringClass = this;      rfield->name = name;      return rfield;    }  jclass superclass = getSuperclass();  if (superclass == NULL)    return NULL;  rfield = superclass->getPrivateField(name);  for (int i = 0; i < interface_count && rfield == NULL; ++i)    rfield = interfaces[i]->getPrivateField (name);  return rfield;}// Only used by serializationjava::lang::reflect::Method *java::lang::Class::getPrivateMethod (jstring name, JArray<jclass> *param_types){  jstring partial_sig = getSignature (param_types, false);  jint p_len = partial_sig->length();  _Jv_Utf8Const *utf_name = _Jv_makeUtf8Const (name);  for (Class *klass = this; klass; klass = klass->getSuperclass())    {      int i = klass->isPrimitive () ? 0 : klass->method_count;      while (--i >= 0)	{	  if (_Jv_equalUtf8Consts (klass->methods[i].name, utf_name)	      && _Jv_equaln (klass->methods[i].signature, partial_sig, p_len))	    {	      // Found it.	      using namespace java::lang::reflect;	      Method *rmethod = new Method ();	      rmethod->offset = ((char *) (&klass->methods[i])				 - (char *) klass->methods);	      rmethod->declaringClass = klass;	      return rmethod;	    }	}    }  throw new java::lang::NoSuchMethodException;}// Private accessor method for Java code to retrieve the protection domain.java::security::ProtectionDomain *java::lang::Class::getProtectionDomain0 (){  return protectionDomain;}// Functions for indirect dispatch (symbolic virtual method binding) support.// Resolve entries in the virtual method offset symbol table // (klass->otable_syms). The vtable offset (in bytes) for each resolved method // is placed at the corresponding position in the virtual method offset table // (klass->otable). A single otable and otable_syms pair may be shared by many // classes.void_Jv_LinkOffsetTable(jclass klass){  //// FIXME: Need to lock the otable ////    if (klass->otable == NULL      || klass->otable->state != 0)    return;    klass->otable->state = 1;  int index = 0;  _Jv_MethodSymbol sym = klass->otable_syms[0];  while (sym.name != NULL)    {      jclass target_class = _Jv_FindClass (sym.class_name, NULL);      _Jv_Method *meth = NULL;                        if (target_class != NULL)	if (target_class->isInterface())	  {	    // FIXME: This does not yet fully conform to binary compatibility	    // rules. It will break if a declaration is moved into a 	    // superinterface.	    for (int i=0; i < target_class->method_count; i++)	      {		meth = &target_class->methods[i];		if (_Jv_equalUtf8Consts (sym.name, meth->name)		    && _Jv_equalUtf8Consts (sym.signature, meth->signature))		  {		    klass->otable->offsets[index] = i + 1;		    break;		  }	      }	  }	else	  {	    // If the target class does not have a vtable_method_count yet, 	    // then we can't tell the offsets for its methods, so we must lay 	    // it out now.	    if (target_class->vtable_method_count == -1)	      {		JvSynchronize sync (target_class);		_Jv_LayoutVTableMethods (target_class);	      }            meth = _Jv_LookupDeclaredMethod(target_class, sym.name, 					    sym.signature);	    if (meth != NULL)	      {		klass->otable->offsets[index] = 		  _Jv_VTable::idx_to_offset (meth->index);	      }	  }      if (meth == NULL)	// FIXME: This should be special index for ThrowNoSuchMethod().	klass->otable->offsets[index] = -1;      sym = klass->otable_syms[++index];    }}// Returns true if METH should get an entry in a VTable.static jbooleanisVirtualMethod (_Jv_Method *meth){  using namespace java::lang::reflect;  return (((meth->accflags & (Modifier::STATIC | Modifier::PRIVATE)) == 0)          && meth->name->data[0] != '<');}// This is put in empty vtable slots.static void_Jv_abstractMethodError (void){  throw new java::lang::AbstractMethodError();}// Prepare virtual method declarations in KLASS, and any superclasses as // required, by determining their vtable index, setting method->index, and// finally setting the class's vtable_method_count. Must be called with the// lock for KLASS held.void_Jv_LayoutVTableMethods (jclass klass){  if (klass->vtable != NULL || klass->isInterface()       || klass->vtable_method_count != -1)    return;  jclass superclass = klass->superclass;  if (superclass != NULL && superclass->vtable_method_count == -1)    {      JvSynchronize sync (superclass);      _Jv_LayoutVTableMethods (superclass);    }  int index = (superclass == NULL ? 0 : superclass->vtable_method_count);  for (int i = 0; i < klass->method_count; ++i)    {      _Jv_Method *meth = &klass->methods[i];      _Jv_Method *super_meth = NULL;      if (! isVirtualMethod (meth))	continue;      if (superclass != NULL)	{	  super_meth = _Jv_LookupDeclaredMethod (superclass, meth->name, 						 meth->signature);	}      if (super_meth)        meth->index = super_meth->index;      else if (! (meth->accflags & java::lang::reflect::Modifier::FINAL)	       && ! (klass->accflags & java::lang::reflect::Modifier::FINAL))	meth->index = index++;    }  klass->vtable_method_count = index;}// Set entries in VTABLE for virtual methods declared in KLASS. If// KLASS has an immediate abstract parent, recursively do its methods// first.  FLAGS is used to determine which slots we've actually set.void_Jv_SetVTableEntries (jclass klass, _Jv_VTable *vtable, jboolean *flags){  using namespace java::lang::reflect;  jclass superclass = klass->getSuperclass();  if (superclass != NULL && (superclass->getModifiers() & Modifier::ABSTRACT))    _Jv_SetVTableEntries (superclass, vtable, flags);  for (int i = klass->method_count - 1; i >= 0; i--)    {      _Jv_Method *meth = &klass->methods[i];      if (meth->index == (_Jv_ushort) -1)	continue;      if ((meth->accflags & Modifier::ABSTRACT))	{	  vtable->set_method(meth->index, (void *) &_Jv_abstractMethodError);	  flags[meth->index] = false;	}      else	{	  vtable->set_method(meth->index, meth->ncode);	  flags[meth->index] = true;	}    }}// Allocate and lay out the virtual method table for KLASS. This will also// cause vtables to be generated for any non-abstract superclasses, and// virtual method layout to occur for any abstract superclasses. Must be// called with monitor lock for KLASS held.void_Jv_MakeVTable (jclass klass){  using namespace java::lang::reflect;    if (klass->vtable != NULL || klass->isInterface()       || (klass->accflags & Modifier::ABSTRACT))    return;  //  out before we can create a vtable.   if (klass->vtable_method_count == -1)    _Jv_LayoutVTableMethods (klass);  // Allocate the new vtable.  _Jv_VTable *vtable = _Jv_VTable::new_vtable (klass->vtable_method_count);  klass->vtable = vtable;  jboolean flags[klass->vtable_method_count];  for (int i = 0; i < klass->vtable_method_count; ++i)    flags[i] = false;  // Copy the vtable of the closest non-abstract superclass.  jclass superclass = klass->superclass;  if (superclass != NULL)    {      while ((superclass->accflags & Modifier::ABSTRACT) != 0)	superclass = superclass->superclass;      if (superclass->vtable == NULL)	{	  JvSynchronize sync (superclass);	  _Jv_MakeVTable (superclass);	}      for (int i = 0; i < superclass->vtable_method_count; ++i)	{	  vtable->set_method (i, superclass->vtable->get_method (i));	  flags[i] = true;	}    }  // Set the class pointer and GC descriptor.  vtable->clas = klass;  vtable->gc_descr = _Jv_BuildGCDescr (klass);  // For each virtual declared in klass and any immediate abstract   // superclasses, set new vtable entry or override an old one.  _Jv_SetVTableEntries (klass, vtable, flags);  // It is an error to have an abstract method in a concrete class.  if (! (klass->accflags & Modifier::ABSTRACT))    {      for (int i = 0; i < klass->vtable_method_count; ++i)	if (! flags[i])	  // FIXME: messsage.	  throw new java::lang::AbstractMethodError ();    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -