123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475 |
- using System;
- using System.IO;
- using System.Collections.Generic;
- using System.Text;
- using OpenSim.Scripting.EmbeddedJVM.Types;
- namespace OpenSim.Scripting.EmbeddedJVM
- {
- public class ClassRecord
- {
- private ushort _majorVersion;
- private ushort _minorVersion;
- private ushort _constantPoolCount;
- private ushort _accessFlags;
- private ushort _thisClass;
- private ushort _supperClass;
- private ushort _interfaceCount;
- private ushort _fieldCount;
- private ushort _methodCount;
- private ushort _attributeCount;
- private string _name;
- public Dictionary<string, BaseType> StaticFields = new Dictionary<string, BaseType>();
- public PoolClass mClass;
- public List<PoolItem> _constantsPool = new List<PoolItem>();
- private List<MethodInfo> _methodsList = new List<MethodInfo>();
- private List<FieldInfo> _fieldList = new List<FieldInfo>();
- public ClassRecord()
- {
- }
- public ClassInstance CreateNewInstance()
- {
- return new ClassInstance();
- }
- public void LoadClassFromFile(string fileName)
- {
- FileStream fs = File.OpenRead(fileName);
- this.LoadClassFromBytes(ReadFully(fs));
- fs.Close();
- }
- public void LoadClassFromBytes(byte[] data)
- {
- int i = 0;
- i += 4;
- _minorVersion = (ushort)((data[i++] << 8) + data[i++] );
- _majorVersion = (ushort)((data[i++] << 8) + data[i++] );
- _constantPoolCount = (ushort)((data[i++] << 8) + data[i++] );
- //Console.WriteLine("there should be " + _constantPoolCount + " items in the pool");
- for (int count = 0; count < _constantPoolCount -1 ; count++)
- {
- //read in the constant pool
- byte pooltype = data[i++];
- //Console.WriteLine("#" +count +": new constant type = " +pooltype);
- //Console.WriteLine("start position is: " + i);
- switch (pooltype)
- {
- case 1: //Utf8
- ushort uLength = (ushort)((data[i++] << 8) + data[i++] );
- // Console.WriteLine("new utf8 type, length is " + uLength);
- PoolUtf8 utf8 = new PoolUtf8();
- utf8.readValue(data, ref i, uLength);
- this._constantsPool.Add(utf8);
- break;
- case 3: //Int
- break;
- case 7: //Class
- PoolClass pClass = new PoolClass(this);
- pClass.readValue(data, ref i);
- this._constantsPool.Add(pClass);
- break;
- case 10: //Method
- PoolMethodRef pMeth = new PoolMethodRef(this);
- pMeth.readValue(data, ref i);
- this._constantsPool.Add(pMeth);
- break;
- case 12: //NamedType
- PoolNamedType pNamed = new PoolNamedType(this);
- pNamed.readValue(data, ref i);
- this._constantsPool.Add(pNamed);
- break;
- }
- }
- _accessFlags = (ushort)((data[i++] << 8) + data[i++] );
- _thisClass = (ushort)((data[i++] << 8) + data[i++] );
- _supperClass = (ushort)((data[i++] << 8) + data[i++] );
- if (this._constantsPool[this._thisClass - 1] is PoolClass)
- {
- this.mClass = ((PoolClass)this._constantsPool[this._thisClass - 1]);
- }
- _interfaceCount = (ushort)((data[i++] << 8) + data[i++]);
- //should now read in the info for each interface
- _fieldCount = (ushort)((data[i++] << 8) + data[i++]);
- //should now read in the info for each field
- _methodCount = (ushort)((data[i++] << 8) + data[i++]);
- for (int count = 0; count < _methodCount; count++)
- {
- MethodInfo methInf = new MethodInfo(this);
- methInf.ReadData(data, ref i);
- this._methodsList.Add(methInf);
- }
- }
- public void AddMethodsToMemory(MethodMemory memory)
- {
- for (int count = 0; count < _methodCount; count++)
- {
- this._methodsList[count].AddMethodCode(memory);
- }
- }
- public bool StartMethod(Thread thread, string methodName)
- {
- for (int count = 0; count < _methodCount; count++)
- {
- if (this._constantsPool[this._methodsList[count].NameIndex-1] is PoolUtf8)
- {
- if (((PoolUtf8)this._constantsPool[this._methodsList[count].NameIndex-1]).Value == methodName)
- {
- //Console.WriteLine("found method: " + ((PoolUtf8)this._constantsPool[this._methodsList[count].NameIndex - 1]).Value);
- thread.SetPC(this._methodsList[count].CodePointer);
- return true;
- }
- }
- }
- return false;
- }
- public void PrintToConsole()
- {
- // Console.WriteLine("Class File:");
- // Console.WriteLine("Major version: " + _majorVersion);
- // Console.WriteLine("Minor version: " + _minorVersion);
- //Console.WriteLine("Pool size: " + _constantPoolCount);
- for (int i = 0; i < _constantsPool.Count; i++)
- {
- this._constantsPool[i].Print();
- }
- // Console.WriteLine("Access flags: " + _accessFlags);
- // Console.WriteLine("This class: " + _thisClass );
- // Console.WriteLine("Super class: " + _supperClass);
- for (int count = 0; count < _methodCount; count++)
- {
- Console.WriteLine();
- this._methodsList[count].Print();
- }
- // Console.WriteLine("class name is " + this.mClass.Name.Value);
- }
- public static byte[] ReadFully(Stream stream)
- {
- byte[] buffer = new byte[1024];
- using (MemoryStream ms = new MemoryStream())
- {
- while (true)
- {
- int read = stream.Read(buffer, 0, buffer.Length);
- if (read <= 0)
- return ms.ToArray();
- ms.Write(buffer, 0, read);
- }
- }
- }
- #region nested classes
- public class PoolItem
- {
- public virtual void Print()
- {
- }
- }
- public class PoolUtf8 : PoolItem
- {
- public string Value = "";
- public void readValue(byte[] data,ref int pointer , int length)
- {
- for (int i = 0; i < length; i++)
- {
- int a =(int) data[pointer++];
- if ((a & 0x80) == 0)
- {
- Value = Value + (char)a;
- }
- else if ((a & 0x20) == 0)
- {
- int b = (int) data[pointer++];
- Value = Value + (char)(((a & 0x1f) << 6) + (b & 0x3f));
- }
- else
- {
- int b = (int)data[pointer++];
- int c = (int)data[pointer++];
- Value = Value + (char)(((a & 0xf) << 12) + ((b & 0x3f) << 6) + (c & 0x3f));
- }
- }
- }
- public override void Print()
- {
- // Console.WriteLine("Utf8 type: " + Value);
- }
- }
- private class PoolInt : PoolItem
- {
- }
- public class PoolClass : PoolItem
- {
- //public string name = "";
- public ushort namePointer = 0;
- private ClassRecord parent;
- public PoolUtf8 Name;
- public PoolClass(ClassRecord paren)
- {
- parent = paren;
- }
- public void readValue(byte[] data, ref int pointer)
- {
- namePointer = (ushort)((data[pointer++] << 8) + data[pointer++] );
- }
- public override void Print()
- {
- this.Name = ((PoolUtf8)this.parent._constantsPool[namePointer - 1]);
- //Console.Write("Class type: " + namePointer);
- //Console.WriteLine(" // " + ((PoolUtf8)this.parent._constantsPool[namePointer - 1]).Value);
-
- }
- }
- public class PoolMethodRef : PoolItem
- {
- public ushort classPointer = 0;
- public ushort nameTypePointer = 0;
- public PoolNamedType mNameType;
- public PoolClass mClass;
- private ClassRecord parent;
- public PoolMethodRef(ClassRecord paren)
- {
- parent = paren;
- }
- public void readValue(byte[] data, ref int pointer)
- {
- classPointer = (ushort)((data[pointer++] << 8) + data[pointer++]);
- nameTypePointer = (ushort)((data[pointer++] << 8) + data[pointer++]);
- }
- public override void Print()
- {
- this.mNameType = ((PoolNamedType)this.parent._constantsPool[nameTypePointer - 1]);
- this.mClass = ((PoolClass)this.parent._constantsPool[classPointer - 1]);
- // Console.WriteLine("MethodRef type: " + classPointer + " , " + nameTypePointer);
- }
- }
- public class PoolNamedType : PoolItem
- {
- public ushort namePointer = 0;
- public ushort typePointer = 0;
- private ClassRecord parent;
- public PoolUtf8 Name;
- public PoolUtf8 Type;
- public PoolNamedType(ClassRecord paren)
- {
- parent = paren;
- }
- public void readValue(byte[] data, ref int pointer)
- {
- namePointer = (ushort)((data[pointer++] << 8) + data[pointer++] );
- typePointer = (ushort)((data[pointer++] << 8) + data[pointer++] );
- }
- public override void Print()
- {
- Name = ((PoolUtf8)this.parent._constantsPool[namePointer-1]);
- Type = ((PoolUtf8)this.parent._constantsPool[typePointer-1]);
- //Console.Write("Named type: " + namePointer + " , " + typePointer );
- //Console.WriteLine(" // "+ ((PoolUtf8)this.parent._constantsPool[namePointer-1]).Value);
- }
- }
- //***********************
- public class MethodInfo
- {
- public ushort AccessFlags = 0;
- public ushort NameIndex = 0;
- public string Name = "";
- public ushort DescriptorIndex = 0;
- public ushort AttributeCount = 0;
- public List<MethodAttribute> Attributes = new List<MethodAttribute>();
- private ClassRecord parent;
- public int CodePointer = 0;
-
- public MethodInfo(ClassRecord paren)
- {
- parent = paren;
- }
- public void AddMethodCode(MethodMemory memory)
- {
- Array.Copy(this.Attributes[0].Code, 0, memory.MethodBuffer, memory.NextMethodPC, this.Attributes[0].Code.Length);
- memory.Methodcount++;
- this.CodePointer = memory.NextMethodPC;
- memory.NextMethodPC += this.Attributes[0].Code.Length;
- }
- public void ReadData(byte[] data, ref int pointer)
- {
- AccessFlags = (ushort)((data[pointer++] << 8) + data[pointer++]);
- NameIndex = (ushort)((data[pointer++] << 8) + data[pointer++]);
- DescriptorIndex = (ushort)((data[pointer++] << 8) + data[pointer++]);
- AttributeCount = (ushort)((data[pointer++] << 8) + data[pointer++]);
- for(int i =0; i< AttributeCount; i++)
- {
- MethodAttribute attri = new MethodAttribute(this.parent);
- attri.ReadData(data, ref pointer);
- this.Attributes.Add(attri);
- }
- }
- public void Print()
- {
- // Console.WriteLine("Method Info Struct: ");
- // Console.WriteLine("AccessFlags: " + AccessFlags);
- // Console.WriteLine("NameIndex: " + NameIndex +" // "+ ((PoolUtf8)this.parent._constantsPool[NameIndex-1]).Value);
- // Console.WriteLine("DescriptorIndex: " + DescriptorIndex + " // "+ ((PoolUtf8)this.parent._constantsPool[DescriptorIndex-1]).Value);
- // Console.WriteLine("Attribute Count:" + AttributeCount);
- for (int i = 0; i < AttributeCount; i++)
- {
- this.Attributes[i].Print();
- }
- }
- public class MethodAttribute
- {
- public ushort NameIndex = 0;
- public string Name = "";
- public Int32 Length = 0;
- //for now only support code attribute
- public ushort MaxStack = 0;
- public ushort MaxLocals = 0;
- public Int32 CodeLength = 0;
- public byte[] Code;
- public ushort ExceptionTableLength = 0;
- public ushort SubAttributeCount = 0;
- public List<SubAttribute> SubAttributes = new List<SubAttribute>();
- private ClassRecord parent;
- public MethodAttribute(ClassRecord paren)
- {
- parent = paren;
- }
- public void ReadData(byte[] data, ref int pointer)
- {
- NameIndex = (ushort)((data[pointer++] << 8) + data[pointer++]);
- Length = (Int32)((data[pointer++] << 24) + (data[pointer++] << 16) + (data[pointer++] << 8) + data[pointer++]);
- MaxStack = (ushort)((data[pointer++] << 8) + data[pointer++]);
- MaxLocals = (ushort)((data[pointer++] << 8) + data[pointer++]);
- CodeLength = (Int32)((data[pointer++] << 24) + (data[pointer++] << 16) + (data[pointer++] << 8) + data[pointer++]);
- Code = new byte[CodeLength];
- for (int i = 0; i < CodeLength; i++)
- {
- Code[i] = data[pointer++];
- }
- ExceptionTableLength = (ushort)((data[pointer++] << 8) + data[pointer++]);
- SubAttributeCount = (ushort)((data[pointer++] << 8) + data[pointer++]);
- for (int i = 0; i < SubAttributeCount; i++)
- {
- SubAttribute subAttri = new SubAttribute(this.parent);
- subAttri.ReadData(data, ref pointer);
- this.SubAttributes.Add(subAttri);
- }
- }
- public void Print()
- {
- // Console.WriteLine("Method Attribute: ");
- // Console.WriteLine("Name Index: " + NameIndex + " // "+ ((PoolUtf8)this.parent._constantsPool[NameIndex-1]).Value);
- // Console.WriteLine("Length: " + Length);
- // Console.WriteLine("MaxStack: " + MaxStack);
- // Console.WriteLine("MaxLocals: " + MaxLocals);
- // Console.WriteLine("CodeLength: " + CodeLength);
- for (int i = 0; i < Code.Length; i++)
- {
- // Console.WriteLine("OpCode #" + i + " is: " + Code[i]);
- }
- // Console.WriteLine("SubAttributes: " + SubAttributeCount);
- for (int i = 0; i < SubAttributeCount; i++)
- {
- this.SubAttributes[i].Print();
- }
- }
- public class SubAttribute
- {
- public ushort NameIndex = 0;
- public string Name = "";
- public Int32 Length = 0;
- public byte[] Data;
- private ClassRecord parent;
- public SubAttribute(ClassRecord paren)
- {
- parent = paren;
- }
- public void ReadData(byte[] data, ref int pointer)
- {
- NameIndex = (ushort)((data[pointer++] << 8) + data[pointer++]);
- Length = (Int32)((data[pointer++] << 24) + (data[pointer++] << 16) + (data[pointer++] << 8) + data[pointer++]);
- Data = new byte[Length];
- for (int i = 0; i < Length; i++)
- {
- Data[i] = data[pointer++];
- }
- }
- public void Print()
- {
- //Console.WriteLine("SubAttribute: NameIndex: " + NameIndex + " // " + ((PoolUtf8)this.parent._constantsPool[NameIndex - 1]).Value);
- }
- }
- }
- }
- private class InterfaceInfo
- {
- public void ReadData(byte[] data, ref int i)
- {
- }
- }
- private class FieldInfo
- {
- public void ReadData(byte[] data, ref int i)
- {
- }
- }
- private class AttributeInfo
- {
- public void ReadData(byte[] data, ref int i)
- {
- }
- }
- #endregion
- }
- }
|