123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648 |
- /*
- * Copyright (c) Contributors, http://opensimulator.org/
- * See CONTRIBUTORS.TXT for a full list of copyright holders.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of the OpenSim Project nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- using System;
- using System.Collections.Generic;
- using System.IO;
- using OpenSim.Region.ExtensionsScriptModule.JVMEngine.Types;
- using OpenSim.Region.ExtensionsScriptModule.JVMEngine.Types.PrimitiveTypes;
- namespace OpenSim.Region.ExtensionsScriptModule.JVMEngine.JVM
- {
- public class ClassRecord
- {
- private ushort m_majorVersion;
- private ushort m_minorVersion;
- private ushort m_constantPoolCount;
- private ushort m_accessFlags;
- private ushort m_thisClass;
- private ushort m_supperClass;
- private ushort m_interfaceCount;
- private ushort m_fieldCount;
- private ushort m_methodCount;
- //private ushort _attributeCount;
- //private string _name;
- public Dictionary<string, BaseType> StaticFields = new Dictionary<string, BaseType>();
- public PoolClass MClass;
- public List<PoolItem> m_constantsPool = new List<PoolItem>();
- private List<MethodInfo> m_methodsList = new List<MethodInfo>();
- private List<FieldInfo> m_fieldList = new List<FieldInfo>();
- public ClassRecord()
- {
- }
- public ClassInstance CreateNewInstance()
- {
- ClassInstance classInst = new ClassInstance();
- classInst.ClassRec = this;
- //TODO: set fields
- return classInst;
- }
- public void LoadClassFromFile(string fileName)
- {
- Console.WriteLine("loading script " + fileName);
- FileStream fs = File.OpenRead(fileName);
- LoadClassFromBytes(ReadFully(fs));
- fs.Close();
- }
- public void LoadClassFromBytes(byte[] data)
- {
- int i = 0;
- i += 4;
- m_minorVersion = (ushort) ((data[i++] << 8) + data[i++]);
- m_majorVersion = (ushort) ((data[i++] << 8) + data[i++]);
- m_constantPoolCount = (ushort) ((data[i++] << 8) + data[i++]);
- Console.WriteLine("there should be " + m_constantPoolCount + " items in the pool");
- for (int count = 0; count < (m_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);
- m_constantsPool.Add(utf8);
- break;
- case 3: //Int
- break;
- case 4: //Float
- break;
- case 7: //Class
- PoolClass pClass = new PoolClass(this);
- pClass.readValue(data, ref i);
- m_constantsPool.Add(pClass);
- break;
- case 9: //FieldRef
- PoolFieldRef pField = new PoolFieldRef(this);
- pField.readValue(data, ref i);
- m_constantsPool.Add(pField);
- break;
- case 10: //Method
- PoolMethodRef pMeth = new PoolMethodRef(this);
- pMeth.readValue(data, ref i);
- m_constantsPool.Add(pMeth);
- break;
- case 12: //NamedType
- PoolNamedType pNamed = new PoolNamedType(this);
- pNamed.readValue(data, ref i);
- m_constantsPool.Add(pNamed);
- break;
- }
- }
- m_accessFlags = (ushort) ((data[i++] << 8) + data[i++]);
- m_thisClass = (ushort) ((data[i++] << 8) + data[i++]);
- m_supperClass = (ushort) ((data[i++] << 8) + data[i++]);
- if (m_constantsPool[m_thisClass - 1] is PoolClass)
- {
- MClass = ((PoolClass) m_constantsPool[m_thisClass - 1]);
- }
- m_interfaceCount = (ushort) ((data[i++] << 8) + data[i++]);
- //should now read in the info for each interface
- m_fieldCount = (ushort) ((data[i++] << 8) + data[i++]);
- //should now read in the info for each field
- for (int count = 0; count < m_fieldCount; count++)
- {
- FieldInfo fieldInf = new FieldInfo(this);
- fieldInf.ReadData(data, ref i);
- m_fieldList.Add(fieldInf);
- }
- m_methodCount = (ushort) ((data[i++] << 8) + data[i++]);
- for (int count = 0; count < m_methodCount; count++)
- {
- MethodInfo methInf = new MethodInfo(this);
- methInf.ReadData(data, ref i);
- m_methodsList.Add(methInf);
- }
- }
- public void AddMethodsToMemory(MethodMemory memory)
- {
- for (int count = 0; count < m_methodCount; count++)
- {
- m_methodsList[count].AddMethodCode(memory);
- }
- }
- public bool StartMethod(Thread thread, string methodName)
- {
- for (int count = 0; count < m_methodCount; count++)
- {
- if (m_constantsPool[m_methodsList[count].NameIndex - 1] is PoolUtf8)
- {
- if (((PoolUtf8) m_constantsPool[m_methodsList[count].NameIndex - 1]).Value == methodName)
- {
- //Console.WriteLine("found method: " + ((PoolUtf8)this._constantsPool[this._methodsList[count].NameIndex - 1]).Value);
- thread.SetPC(m_methodsList[count].CodePointer);
- return true;
- }
- }
- }
- return false;
- }
- public void PrintToConsole()
- {
- Console.WriteLine("Class File:");
- Console.WriteLine("Major version: " + m_majorVersion);
- Console.WriteLine("Minor version: " + m_minorVersion);
- Console.WriteLine("Pool size: " + m_constantPoolCount);
- for (int i = 0; i < m_constantsPool.Count; i++)
- {
- m_constantsPool[i].Print();
- }
- Console.WriteLine("Access flags: " + m_accessFlags);
- Console.WriteLine("This class: " + m_thisClass);
- Console.WriteLine("Super class: " + m_supperClass);
- for (int count = 0; count < m_fieldCount; count++)
- {
- Console.WriteLine();
- m_fieldList[count].Print();
- }
- for (int count = 0; count < m_methodCount; count++)
- {
- Console.WriteLine();
- m_methodsList[count].Print();
- }
- Console.WriteLine("class name is " + 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 = String.Empty;
- 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 = String.Empty;
- 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()
- {
- Name = ((PoolUtf8) parent.m_constantsPool[namePointer - 1]);
- Console.Write("Class type: " + namePointer);
- Console.WriteLine(" // " + ((PoolUtf8) parent.m_constantsPool[namePointer - 1]).Value);
- }
- }
- public class PoolFieldRef : PoolItem
- {
- public ushort classPointer = 0;
- public ushort nameTypePointer = 0;
- public PoolNamedType mNameType;
- public PoolClass mClass;
- private ClassRecord parent;
- public PoolFieldRef(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()
- {
- mNameType = ((PoolNamedType) parent.m_constantsPool[nameTypePointer - 1]);
- mClass = ((PoolClass) parent.m_constantsPool[classPointer - 1]);
- Console.WriteLine("FieldRef type: " + classPointer + " , " + nameTypePointer);
- }
- }
- 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()
- {
- mNameType = ((PoolNamedType) parent.m_constantsPool[nameTypePointer - 1]);
- mClass = ((PoolClass) parent.m_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) parent.m_constantsPool[namePointer - 1]);
- Type = ((PoolUtf8) parent.m_constantsPool[typePointer - 1]);
- Console.Write("Named type: " + namePointer + " , " + typePointer);
- Console.WriteLine(" // " + ((PoolUtf8) parent.m_constantsPool[namePointer - 1]).Value);
- }
- }
- //***********************
- public class MethodInfo
- {
- public ushort AccessFlags = 0;
- public ushort NameIndex = 0;
- public string Name = String.Empty;
- 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(Attributes[0].Code, 0, memory.MethodBuffer, memory.NextMethodPC, Attributes[0].Code.Length);
- memory.Methodcount++;
- CodePointer = memory.NextMethodPC;
- memory.NextMethodPC += 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(parent);
- attri.ReadData(data, ref pointer);
- Attributes.Add(attri);
- }
- }
- public void Print()
- {
- Console.WriteLine("Method Info Struct: ");
- Console.WriteLine("AccessFlags: " + AccessFlags);
- Console.WriteLine("NameIndex: " + NameIndex + " // " +
- ((PoolUtf8) parent.m_constantsPool[NameIndex - 1]).Value);
- Console.WriteLine("DescriptorIndex: " + DescriptorIndex + " // " +
- ((PoolUtf8) parent.m_constantsPool[DescriptorIndex - 1]).Value);
- Console.WriteLine("Attribute Count:" + AttributeCount);
- for (int i = 0; i < AttributeCount; i++)
- {
- Attributes[i].Print();
- }
- }
- public class MethodAttribute
- {
- public ushort NameIndex = 0;
- public string Name = String.Empty;
- 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(parent);
- subAttri.ReadData(data, ref pointer);
- SubAttributes.Add(subAttri);
- }
- }
- public void Print()
- {
- Console.WriteLine("Method Attribute: ");
- Console.WriteLine("Name Index: " + NameIndex + " // " +
- ((PoolUtf8) parent.m_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++)
- {
- SubAttributes[i].Print();
- }
- }
- public class SubAttribute
- {
- public ushort NameIndex = 0;
- public string Name = String.Empty;
- 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) parent.m_constantsPool[NameIndex - 1]).Value);
- }
- }
- }
- }
- private class InterfaceInfo
- {
- public void ReadData(byte[] data, ref int i)
- {
- }
- }
- public class FieldInfo
- {
- public ushort AccessFlags = 0;
- public ushort NameIndex = 0;
- public string Name = String.Empty;
- public ushort DescriptorIndex = 0;
- public ushort AttributeCount = 0;
- public List<FieldAttribute> Attributes = new List<FieldAttribute>();
- private ClassRecord parent;
- public FieldInfo(ClassRecord paren)
- {
- parent = paren;
- }
- 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++)
- {
- FieldAttribute attri = new FieldAttribute(parent);
- attri.ReadData(data, ref pointer);
- Attributes.Add(attri);
- }
- }
- public void Print()
- {
- Console.WriteLine("Field Info Struct: ");
- Console.WriteLine("AccessFlags: " + AccessFlags);
- Console.WriteLine("NameIndex: " + NameIndex + " // " +
- ((PoolUtf8) parent.m_constantsPool[NameIndex - 1]).Value);
- Console.WriteLine("DescriptorIndex: " + DescriptorIndex + " // " +
- ((PoolUtf8) parent.m_constantsPool[DescriptorIndex - 1]).Value);
- Console.WriteLine("Attribute Count:" + AttributeCount);
- //if static, add to static field list
- // if (this.AccessFlags == 9) //public and static
- if ((AccessFlags & 0x08) != 0)
- {
- switch (((PoolUtf8) parent.m_constantsPool[DescriptorIndex - 1]).Value)
- {
- case "I":
- Int newin = new Int();
- parent.StaticFields.Add(((PoolUtf8) parent.m_constantsPool[NameIndex - 1]).Value, newin);
- break;
- case "F":
- Float newfl = new Float();
- parent.StaticFields.Add(((PoolUtf8) parent.m_constantsPool[NameIndex - 1]).Value, newfl);
- break;
- }
- }
- for (int i = 0; i < AttributeCount; i++)
- {
- Attributes[i].Print();
- }
- }
- public class FieldAttribute
- {
- public ushort NameIndex = 0;
- public string Name = String.Empty;
- public Int32 Length = 0;
- public byte[] Data;
- private ClassRecord parent;
- public FieldAttribute(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("FieldAttribute: NameIndex: " + NameIndex + " // " +
- ((PoolUtf8) parent.m_constantsPool[NameIndex - 1]).Value);
- }
- }
- }
- private class AttributeInfo
- {
- public void ReadData(byte[] data, ref int i)
- {
- }
- }
- #endregion
- }
- }
|