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