aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Environment/Scenes/scripting/Engines/JVMEngine/ClassRecord.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Environment/Scenes/scripting/Engines/JVMEngine/ClassRecord.cs')
-rw-r--r--OpenSim/Region/Environment/Scenes/scripting/Engines/JVMEngine/ClassRecord.cs503
1 files changed, 503 insertions, 0 deletions
diff --git a/OpenSim/Region/Environment/Scenes/scripting/Engines/JVMEngine/ClassRecord.cs b/OpenSim/Region/Environment/Scenes/scripting/Engines/JVMEngine/ClassRecord.cs
new file mode 100644
index 0000000..f4ab1a2
--- /dev/null
+++ b/OpenSim/Region/Environment/Scenes/scripting/Engines/JVMEngine/ClassRecord.cs
@@ -0,0 +1,503 @@
1/*
2* Copyright (c) Contributors, http://www.openmetaverse.org/
3* See CONTRIBUTORS.TXT for a full list of copyright holders.
4*
5* Redistribution and use in source and binary forms, with or without
6* modification, are permitted provided that the following conditions are met:
7* * Redistributions of source code must retain the above copyright
8* notice, this list of conditions and the following disclaimer.
9* * Redistributions in binary form must reproduce the above copyright
10* notice, this list of conditions and the following disclaimer in the
11* documentation and/or other materials provided with the distribution.
12* * Neither the name of the OpenSim Project nor the
13* names of its contributors may be used to endorse or promote products
14* derived from this software without specific prior written permission.
15*
16* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY
17* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*
27*/
28using System;
29using System.IO;
30using System.Collections.Generic;
31using System.Text;
32using OpenSim.Scripting.EmbeddedJVM.Types;
33
34namespace OpenSim.Scripting.EmbeddedJVM
35{
36 public class ClassRecord
37 {
38 private ushort _majorVersion;
39 private ushort _minorVersion;
40 private ushort _constantPoolCount;
41 private ushort _accessFlags;
42 private ushort _thisClass;
43 private ushort _supperClass;
44 private ushort _interfaceCount;
45 private ushort _fieldCount;
46 private ushort _methodCount;
47 //private ushort _attributeCount;
48 //private string _name;
49 public Dictionary<string, BaseType> StaticFields = new Dictionary<string, BaseType>();
50 public PoolClass mClass;
51
52 public List<PoolItem> _constantsPool = new List<PoolItem>();
53 private List<MethodInfo> _methodsList = new List<MethodInfo>();
54 private List<FieldInfo> _fieldList = new List<FieldInfo>();
55
56 public ClassRecord()
57 {
58
59 }
60
61 public ClassInstance CreateNewInstance()
62 {
63 return new ClassInstance();
64 }
65
66 public void LoadClassFromFile(string fileName)
67 {
68 Console.WriteLine("loading script " + fileName);
69 FileStream fs = File.OpenRead(fileName);
70 this.LoadClassFromBytes(ReadFully(fs));
71 fs.Close();
72 }
73
74 public void LoadClassFromBytes(byte[] data)
75 {
76 int i = 0;
77 i += 4;
78 _minorVersion = (ushort)((data[i++] << 8) + data[i++] );
79 _majorVersion = (ushort)((data[i++] << 8) + data[i++] );
80 _constantPoolCount = (ushort)((data[i++] << 8) + data[i++] );
81 // Console.WriteLine("there should be " + _constantPoolCount + " items in the pool");
82 for (int count = 0; count < _constantPoolCount -1 ; count++)
83 {
84 //read in the constant pool
85 byte pooltype = data[i++];
86 //Console.WriteLine("#" +count +": new constant type = " +pooltype);
87 //Console.WriteLine("start position is: " + i);
88 switch (pooltype)
89 {
90 case 1: //Utf8
91 ushort uLength = (ushort)((data[i++] << 8) + data[i++] );
92
93 // Console.WriteLine("new utf8 type, length is " + uLength);
94 PoolUtf8 utf8 = new PoolUtf8();
95 utf8.readValue(data, ref i, uLength);
96 this._constantsPool.Add(utf8);
97 break;
98 case 3: //Int
99 break;
100 case 7: //Class
101 PoolClass pClass = new PoolClass(this);
102 pClass.readValue(data, ref i);
103 this._constantsPool.Add(pClass);
104 break;
105 case 10: //Method
106 PoolMethodRef pMeth = new PoolMethodRef(this);
107 pMeth.readValue(data, ref i);
108 this._constantsPool.Add(pMeth);
109 break;
110 case 12: //NamedType
111 PoolNamedType pNamed = new PoolNamedType(this);
112 pNamed.readValue(data, ref i);
113 this._constantsPool.Add(pNamed);
114 break;
115 }
116 }
117
118 _accessFlags = (ushort)((data[i++] << 8) + data[i++] );
119 _thisClass = (ushort)((data[i++] << 8) + data[i++] );
120 _supperClass = (ushort)((data[i++] << 8) + data[i++] );
121
122 if (this._constantsPool[this._thisClass - 1] is PoolClass)
123 {
124 this.mClass = ((PoolClass)this._constantsPool[this._thisClass - 1]);
125 }
126
127 _interfaceCount = (ushort)((data[i++] << 8) + data[i++]);
128 //should now read in the info for each interface
129 _fieldCount = (ushort)((data[i++] << 8) + data[i++]);
130 //should now read in the info for each field
131 _methodCount = (ushort)((data[i++] << 8) + data[i++]);
132 for (int count = 0; count < _methodCount; count++)
133 {
134 MethodInfo methInf = new MethodInfo(this);
135 methInf.ReadData(data, ref i);
136 this._methodsList.Add(methInf);
137 }
138 }
139
140 public void AddMethodsToMemory(MethodMemory memory)
141 {
142 for (int count = 0; count < _methodCount; count++)
143 {
144 this._methodsList[count].AddMethodCode(memory);
145 }
146 }
147
148 public bool StartMethod(Thread thread, string methodName)
149 {
150 for (int count = 0; count < _methodCount; count++)
151 {
152 if (this._constantsPool[this._methodsList[count].NameIndex-1] is PoolUtf8)
153 {
154 if (((PoolUtf8)this._constantsPool[this._methodsList[count].NameIndex-1]).Value == methodName)
155 {
156 //Console.WriteLine("found method: " + ((PoolUtf8)this._constantsPool[this._methodsList[count].NameIndex - 1]).Value);
157 thread.SetPC(this._methodsList[count].CodePointer);
158 return true;
159 }
160 }
161 }
162 return false;
163 }
164
165 public void PrintToConsole()
166 {
167 Console.WriteLine("Class File:");
168 Console.WriteLine("Major version: " + _majorVersion);
169 Console.WriteLine("Minor version: " + _minorVersion);
170 Console.WriteLine("Pool size: " + _constantPoolCount);
171
172 for (int i = 0; i < _constantsPool.Count; i++)
173 {
174 this._constantsPool[i].Print();
175 }
176
177 Console.WriteLine("Access flags: " + _accessFlags);
178 Console.WriteLine("This class: " + _thisClass );
179 Console.WriteLine("Super class: " + _supperClass);
180
181 for (int count = 0; count < _methodCount; count++)
182 {
183 Console.WriteLine();
184 this._methodsList[count].Print();
185 }
186
187 Console.WriteLine("class name is " + this.mClass.Name.Value);
188 }
189
190 public static byte[] ReadFully(Stream stream)
191 {
192 byte[] buffer = new byte[1024];
193 using (MemoryStream ms = new MemoryStream())
194 {
195 while (true)
196 {
197 int read = stream.Read(buffer, 0, buffer.Length);
198 if (read <= 0)
199 return ms.ToArray();
200 ms.Write(buffer, 0, read);
201 }
202 }
203 }
204
205 #region nested classes
206 public class PoolItem
207 {
208 public virtual void Print()
209 {
210
211 }
212 }
213
214 public class PoolUtf8 : PoolItem
215 {
216 public string Value = "";
217
218 public void readValue(byte[] data,ref int pointer , int length)
219 {
220 for (int i = 0; i < length; i++)
221 {
222 int a =(int) data[pointer++];
223 if ((a & 0x80) == 0)
224 {
225 Value = Value + (char)a;
226 }
227 else if ((a & 0x20) == 0)
228 {
229 int b = (int) data[pointer++];
230 Value = Value + (char)(((a & 0x1f) << 6) + (b & 0x3f));
231 }
232 else
233 {
234 int b = (int)data[pointer++];
235 int c = (int)data[pointer++];
236 Value = Value + (char)(((a & 0xf) << 12) + ((b & 0x3f) << 6) + (c & 0x3f));
237 }
238 }
239 }
240
241 public override void Print()
242 {
243 Console.WriteLine("Utf8 type: " + Value);
244 }
245 }
246
247 private class PoolInt : PoolItem
248 {
249
250 }
251
252 public class PoolClass : PoolItem
253 {
254 //public string name = "";
255 public ushort namePointer = 0;
256 private ClassRecord parent;
257 public PoolUtf8 Name;
258
259 public PoolClass(ClassRecord paren)
260 {
261 parent = paren;
262 }
263
264 public void readValue(byte[] data, ref int pointer)
265 {
266 namePointer = (ushort)((data[pointer++] << 8) + data[pointer++] );
267 }
268
269 public override void Print()
270 {
271 this.Name = ((PoolUtf8)this.parent._constantsPool[namePointer - 1]);
272 Console.Write("Class type: " + namePointer);
273 Console.WriteLine(" // " + ((PoolUtf8)this.parent._constantsPool[namePointer - 1]).Value);
274
275 }
276 }
277
278 public class PoolMethodRef : PoolItem
279 {
280 public ushort classPointer = 0;
281 public ushort nameTypePointer = 0;
282 public PoolNamedType mNameType;
283 public PoolClass mClass;
284 private ClassRecord parent;
285
286 public PoolMethodRef(ClassRecord paren)
287 {
288 parent = paren;
289 }
290
291 public void readValue(byte[] data, ref int pointer)
292 {
293 classPointer = (ushort)((data[pointer++] << 8) + data[pointer++]);
294 nameTypePointer = (ushort)((data[pointer++] << 8) + data[pointer++]);
295 }
296
297 public override void Print()
298 {
299 this.mNameType = ((PoolNamedType)this.parent._constantsPool[nameTypePointer - 1]);
300 this.mClass = ((PoolClass)this.parent._constantsPool[classPointer - 1]);
301 Console.WriteLine("MethodRef type: " + classPointer + " , " + nameTypePointer);
302 }
303 }
304
305 public class PoolNamedType : PoolItem
306 {
307 public ushort namePointer = 0;
308 public ushort typePointer = 0;
309 private ClassRecord parent;
310 public PoolUtf8 Name;
311 public PoolUtf8 Type;
312
313 public PoolNamedType(ClassRecord paren)
314 {
315 parent = paren;
316 }
317
318 public void readValue(byte[] data, ref int pointer)
319 {
320 namePointer = (ushort)((data[pointer++] << 8) + data[pointer++] );
321 typePointer = (ushort)((data[pointer++] << 8) + data[pointer++] );
322 }
323
324 public override void Print()
325 {
326 Name = ((PoolUtf8)this.parent._constantsPool[namePointer-1]);
327 Type = ((PoolUtf8)this.parent._constantsPool[typePointer-1]);
328 Console.Write("Named type: " + namePointer + " , " + typePointer );
329 Console.WriteLine(" // "+ ((PoolUtf8)this.parent._constantsPool[namePointer-1]).Value);
330 }
331 }
332
333 //***********************
334 public class MethodInfo
335 {
336 public ushort AccessFlags = 0;
337 public ushort NameIndex = 0;
338 public string Name = "";
339 public ushort DescriptorIndex = 0;
340 public ushort AttributeCount = 0;
341 public List<MethodAttribute> Attributes = new List<MethodAttribute>();
342 private ClassRecord parent;
343 public int CodePointer = 0;
344
345 public MethodInfo(ClassRecord paren)
346 {
347 parent = paren;
348 }
349
350 public void AddMethodCode(MethodMemory memory)
351 {
352 Array.Copy(this.Attributes[0].Code, 0, memory.MethodBuffer, memory.NextMethodPC, this.Attributes[0].Code.Length);
353 memory.Methodcount++;
354 this.CodePointer = memory.NextMethodPC;
355 memory.NextMethodPC += this.Attributes[0].Code.Length;
356 }
357
358 public void ReadData(byte[] data, ref int pointer)
359 {
360 AccessFlags = (ushort)((data[pointer++] << 8) + data[pointer++]);
361 NameIndex = (ushort)((data[pointer++] << 8) + data[pointer++]);
362 DescriptorIndex = (ushort)((data[pointer++] << 8) + data[pointer++]);
363 AttributeCount = (ushort)((data[pointer++] << 8) + data[pointer++]);
364 for(int i =0; i< AttributeCount; i++)
365 {
366 MethodAttribute attri = new MethodAttribute(this.parent);
367 attri.ReadData(data, ref pointer);
368 this.Attributes.Add(attri);
369 }
370 }
371
372 public void Print()
373 {
374 Console.WriteLine("Method Info Struct: ");
375 Console.WriteLine("AccessFlags: " + AccessFlags);
376 Console.WriteLine("NameIndex: " + NameIndex +" // "+ ((PoolUtf8)this.parent._constantsPool[NameIndex-1]).Value);
377 Console.WriteLine("DescriptorIndex: " + DescriptorIndex + " // "+ ((PoolUtf8)this.parent._constantsPool[DescriptorIndex-1]).Value);
378 Console.WriteLine("Attribute Count:" + AttributeCount);
379 for (int i = 0; i < AttributeCount; i++)
380 {
381 this.Attributes[i].Print();
382 }
383 }
384
385 public class MethodAttribute
386 {
387 public ushort NameIndex = 0;
388 public string Name = "";
389 public Int32 Length = 0;
390 //for now only support code attribute
391 public ushort MaxStack = 0;
392 public ushort MaxLocals = 0;
393 public Int32 CodeLength = 0;
394 public byte[] Code;
395 public ushort ExceptionTableLength = 0;
396 public ushort SubAttributeCount = 0;
397 public List<SubAttribute> SubAttributes = new List<SubAttribute>();
398 private ClassRecord parent;
399
400 public MethodAttribute(ClassRecord paren)
401 {
402 parent = paren;
403 }
404
405 public void ReadData(byte[] data, ref int pointer)
406 {
407 NameIndex = (ushort)((data[pointer++] << 8) + data[pointer++]);
408 Length = (Int32)((data[pointer++] << 24) + (data[pointer++] << 16) + (data[pointer++] << 8) + data[pointer++]);
409 MaxStack = (ushort)((data[pointer++] << 8) + data[pointer++]);
410 MaxLocals = (ushort)((data[pointer++] << 8) + data[pointer++]);
411 CodeLength = (Int32)((data[pointer++] << 24) + (data[pointer++] << 16) + (data[pointer++] << 8) + data[pointer++]);
412 Code = new byte[CodeLength];
413 for (int i = 0; i < CodeLength; i++)
414 {
415 Code[i] = data[pointer++];
416 }
417 ExceptionTableLength = (ushort)((data[pointer++] << 8) + data[pointer++]);
418 SubAttributeCount = (ushort)((data[pointer++] << 8) + data[pointer++]);
419 for (int i = 0; i < SubAttributeCount; i++)
420 {
421 SubAttribute subAttri = new SubAttribute(this.parent);
422 subAttri.ReadData(data, ref pointer);
423 this.SubAttributes.Add(subAttri);
424 }
425 }
426
427 public void Print()
428 {
429 Console.WriteLine("Method Attribute: ");
430 Console.WriteLine("Name Index: " + NameIndex + " // "+ ((PoolUtf8)this.parent._constantsPool[NameIndex-1]).Value);
431 Console.WriteLine("Length: " + Length);
432 Console.WriteLine("MaxStack: " + MaxStack);
433 Console.WriteLine("MaxLocals: " + MaxLocals);
434 Console.WriteLine("CodeLength: " + CodeLength);
435 for (int i = 0; i < Code.Length; i++)
436 {
437 Console.WriteLine("OpCode #" + i + " is: " + Code[i]);
438 }
439 Console.WriteLine("SubAttributes: " + SubAttributeCount);
440 for (int i = 0; i < SubAttributeCount; i++)
441 {
442 this.SubAttributes[i].Print();
443 }
444 }
445
446 public class SubAttribute
447 {
448 public ushort NameIndex = 0;
449 public string Name = "";
450 public Int32 Length = 0;
451 public byte[] Data;
452 private ClassRecord parent;
453
454 public SubAttribute(ClassRecord paren)
455 {
456 parent = paren;
457 }
458
459 public void ReadData(byte[] data, ref int pointer)
460 {
461 NameIndex = (ushort)((data[pointer++] << 8) + data[pointer++]);
462 Length = (Int32)((data[pointer++] << 24) + (data[pointer++] << 16) + (data[pointer++] << 8) + data[pointer++]);
463 Data = new byte[Length];
464 for (int i = 0; i < Length; i++)
465 {
466 Data[i] = data[pointer++];
467 }
468 }
469
470 public void Print()
471 {
472 Console.WriteLine("SubAttribute: NameIndex: " + NameIndex + " // " + ((PoolUtf8)this.parent._constantsPool[NameIndex - 1]).Value);
473 }
474
475 }
476 }
477
478 }
479 private class InterfaceInfo
480 {
481 public void ReadData(byte[] data, ref int i)
482 {
483
484 }
485 }
486 private class FieldInfo
487 {
488 public void ReadData(byte[] data, ref int i)
489 {
490
491 }
492 }
493 private class AttributeInfo
494 {
495 public void ReadData(byte[] data, ref int i)
496 {
497
498 }
499 }
500 #endregion
501
502 }
503}