mirror of
https://github.com/opensim/opensim.git
synced 2026-05-16 11:46:04 +08:00
620 lines
32 KiB
C#
620 lines
32 KiB
C#
/*
|
|
* 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 OpenSim.Region.ExtensionsScriptModule.JVMEngine.Types;
|
|
using OpenSim.Region.ExtensionsScriptModule.JVMEngine.Types.PrimitiveTypes;
|
|
|
|
namespace OpenSim.Region.ExtensionsScriptModule.JVMEngine.JVM
|
|
{
|
|
partial class Thread
|
|
{
|
|
private partial class Interpreter
|
|
{
|
|
private bool IsLogicOpCode(byte opcode)
|
|
{
|
|
bool result = false;
|
|
switch (opcode)
|
|
{
|
|
case (byte) (byte) OpCode.iconst_m1:
|
|
Int m_int = new Int();
|
|
m_int.mValue = -1;
|
|
m_thread.m_currentFrame.OpStack.Push(m_int);
|
|
result = true;
|
|
break;
|
|
case (byte) (byte) OpCode.iconst_0:
|
|
m_int = new Int();
|
|
m_int.mValue = 0;
|
|
m_thread.m_currentFrame.OpStack.Push(m_int);
|
|
result = true;
|
|
break;
|
|
case (byte) (byte) OpCode.iconst_1:
|
|
m_int = new Int();
|
|
m_int.mValue = 1;
|
|
m_thread.m_currentFrame.OpStack.Push(m_int);
|
|
result = true;
|
|
break;
|
|
case (byte) (byte) OpCode.iconst_2:
|
|
m_int = new Int();
|
|
m_int.mValue = 2;
|
|
m_thread.m_currentFrame.OpStack.Push(m_int);
|
|
result = true;
|
|
break;
|
|
case (byte) (byte) OpCode.iconst_3:
|
|
m_int = new Int();
|
|
m_int.mValue = 3;
|
|
m_thread.m_currentFrame.OpStack.Push(m_int);
|
|
break;
|
|
case (byte) (byte) OpCode.iconst_4:
|
|
m_int = new Int();
|
|
m_int.mValue = 4;
|
|
m_thread.m_currentFrame.OpStack.Push(m_int);
|
|
result = true;
|
|
break;
|
|
case (byte) OpCode.iconst_5:
|
|
m_int = new Int();
|
|
m_int.mValue = 5;
|
|
m_thread.m_currentFrame.OpStack.Push(m_int);
|
|
result = true;
|
|
break;
|
|
case (byte) OpCode.fconst_0:
|
|
Float m_float = new Float();
|
|
m_float.mValue = 0.0f;
|
|
m_thread.m_currentFrame.OpStack.Push(m_float);
|
|
result = true;
|
|
break;
|
|
case (byte) OpCode.fconst_1:
|
|
m_float = new Float();
|
|
m_float.mValue = 1.0f;
|
|
m_thread.m_currentFrame.OpStack.Push(m_float);
|
|
result = true;
|
|
break;
|
|
case (byte) OpCode.fconst_2:
|
|
m_float = new Float();
|
|
m_float.mValue = 2.0f;
|
|
m_thread.m_currentFrame.OpStack.Push(m_float);
|
|
result = true;
|
|
break;
|
|
case (byte) OpCode.bipush: //is this right? this should be pushing a byte onto stack not int?
|
|
int pushvalue = (int) GlobalMemory.MethodArea.MethodBuffer[m_thread.PC];
|
|
Int pushInt = new Int();
|
|
pushInt.mValue = pushvalue;
|
|
m_thread.m_currentFrame.OpStack.Push(pushInt);
|
|
m_thread.PC++;
|
|
result = true;
|
|
break;
|
|
case (byte) OpCode.sipush:
|
|
short pushvalue2 =
|
|
(short)
|
|
((GlobalMemory.MethodArea.MethodBuffer[m_thread.PC] << 8) +
|
|
GlobalMemory.MethodArea.MethodBuffer[m_thread.PC + 1]);
|
|
Int pushInt2 = new Int();
|
|
pushInt2.mValue = pushvalue2;
|
|
m_thread.m_currentFrame.OpStack.Push(pushInt2);
|
|
m_thread.PC += 2;
|
|
result = true;
|
|
break;
|
|
case (byte) OpCode.fload:
|
|
short findex1 = (short) ((GlobalMemory.MethodArea.MethodBuffer[m_thread.PC]));
|
|
Float fload = new Float();
|
|
if (m_thread.m_currentFrame.LocalVariables[findex1] != null)
|
|
{
|
|
if (m_thread.m_currentFrame.LocalVariables[findex1] is Float)
|
|
{
|
|
fload.mValue = ((Float) m_thread.m_currentFrame.LocalVariables[findex1]).mValue;
|
|
m_thread.m_currentFrame.OpStack.Push(fload);
|
|
}
|
|
}
|
|
m_thread.PC++;
|
|
result = true;
|
|
break;
|
|
case (byte) OpCode.iload_0:
|
|
if (m_thread.m_currentFrame.LocalVariables[0] != null)
|
|
{
|
|
if (m_thread.m_currentFrame.LocalVariables[0] is Int)
|
|
{
|
|
Int newInt = new Int();
|
|
newInt.mValue = ((Int) m_thread.m_currentFrame.LocalVariables[0]).mValue;
|
|
m_thread.m_currentFrame.OpStack.Push(newInt);
|
|
}
|
|
}
|
|
result = true;
|
|
break;
|
|
case (byte) OpCode.iload_1:
|
|
if (m_thread.m_currentFrame.LocalVariables[1] != null)
|
|
{
|
|
if (m_thread.m_currentFrame.LocalVariables[1] is Int)
|
|
{
|
|
Int newInt = new Int();
|
|
newInt.mValue = ((Int) m_thread.m_currentFrame.LocalVariables[1]).mValue;
|
|
m_thread.m_currentFrame.OpStack.Push(newInt);
|
|
}
|
|
}
|
|
result = true;
|
|
break;
|
|
case (byte) OpCode.fload_0:
|
|
if (m_thread.m_currentFrame.LocalVariables[0] != null)
|
|
{
|
|
if (m_thread.m_currentFrame.LocalVariables[0] is Float)
|
|
{
|
|
Float newfloat = new Float();
|
|
newfloat.mValue = ((Float) m_thread.m_currentFrame.LocalVariables[0]).mValue;
|
|
m_thread.m_currentFrame.OpStack.Push(newfloat);
|
|
}
|
|
}
|
|
result = true;
|
|
break;
|
|
case (byte) OpCode.fload_1:
|
|
if (m_thread.m_currentFrame.LocalVariables[1] != null)
|
|
{
|
|
if (m_thread.m_currentFrame.LocalVariables[1] is Float)
|
|
{
|
|
Float newfloat = new Float();
|
|
newfloat.mValue = ((Float) m_thread.m_currentFrame.LocalVariables[1]).mValue;
|
|
m_thread.m_currentFrame.OpStack.Push(newfloat);
|
|
}
|
|
}
|
|
result = true;
|
|
break;
|
|
case (byte) OpCode.fload_2:
|
|
if (m_thread.m_currentFrame.LocalVariables[2] != null)
|
|
{
|
|
if (m_thread.m_currentFrame.LocalVariables[2] is Float)
|
|
{
|
|
Float newfloat = new Float();
|
|
newfloat.mValue = ((Float) m_thread.m_currentFrame.LocalVariables[2]).mValue;
|
|
m_thread.m_currentFrame.OpStack.Push(newfloat);
|
|
}
|
|
}
|
|
result = true;
|
|
break;
|
|
case (byte) OpCode.fload_3:
|
|
if (m_thread.m_currentFrame.LocalVariables[3] != null)
|
|
{
|
|
if (m_thread.m_currentFrame.LocalVariables[3] is Float)
|
|
{
|
|
Float newfloat = new Float();
|
|
newfloat.mValue = ((Float) m_thread.m_currentFrame.LocalVariables[3]).mValue;
|
|
m_thread.m_currentFrame.OpStack.Push(newfloat);
|
|
}
|
|
}
|
|
result = true;
|
|
break;
|
|
case (byte) OpCode.istore:
|
|
short findex3 = (short) ((GlobalMemory.MethodArea.MethodBuffer[m_thread.PC]));
|
|
BaseType istor = m_thread.m_currentFrame.OpStack.Pop();
|
|
if (istor is Int)
|
|
{
|
|
m_thread.m_currentFrame.LocalVariables[findex3] = (Int) istor;
|
|
}
|
|
m_thread.PC++;
|
|
result = true;
|
|
break;
|
|
case (byte) OpCode.fstore:
|
|
short findex = (short) ((GlobalMemory.MethodArea.MethodBuffer[m_thread.PC]));
|
|
BaseType fstor = m_thread.m_currentFrame.OpStack.Pop();
|
|
if (fstor is Float)
|
|
{
|
|
m_thread.m_currentFrame.LocalVariables[findex] = (Float) fstor;
|
|
}
|
|
m_thread.PC++;
|
|
result = true;
|
|
break;
|
|
case (byte) OpCode.istore_0:
|
|
BaseType baset = m_thread.m_currentFrame.OpStack.Pop();
|
|
if (baset is Int)
|
|
{
|
|
m_thread.m_currentFrame.LocalVariables[0] = (Int) baset;
|
|
}
|
|
result = true;
|
|
break;
|
|
case (byte) OpCode.istore_1:
|
|
baset = m_thread.m_currentFrame.OpStack.Pop();
|
|
if (baset is Int)
|
|
{
|
|
m_thread.m_currentFrame.LocalVariables[1] = (Int) baset;
|
|
}
|
|
result = true;
|
|
break;
|
|
case (byte) OpCode.fstore_0:
|
|
baset = m_thread.m_currentFrame.OpStack.Pop();
|
|
if (baset is Float)
|
|
{
|
|
m_thread.m_currentFrame.LocalVariables[0] = (Float) baset;
|
|
}
|
|
result = true;
|
|
break;
|
|
case (byte) OpCode.fstore_1:
|
|
baset = m_thread.m_currentFrame.OpStack.Pop();
|
|
if (baset is Float)
|
|
{
|
|
m_thread.m_currentFrame.LocalVariables[1] = (Float) baset;
|
|
}
|
|
result = true;
|
|
break;
|
|
case (byte) OpCode.fstore_2:
|
|
baset = m_thread.m_currentFrame.OpStack.Pop();
|
|
if (baset is Float)
|
|
{
|
|
m_thread.m_currentFrame.LocalVariables[2] = (Float) baset;
|
|
}
|
|
result = true;
|
|
break;
|
|
case (byte) OpCode.fstore_3:
|
|
baset = m_thread.m_currentFrame.OpStack.Pop();
|
|
if (baset is Float)
|
|
{
|
|
m_thread.m_currentFrame.LocalVariables[3] = (Float) baset;
|
|
}
|
|
result = true;
|
|
break;
|
|
case (byte) OpCode.pop:
|
|
m_thread.m_currentFrame.OpStack.Pop();
|
|
result = true;
|
|
break;
|
|
case (byte) OpCode.fadd:
|
|
BaseType bf2 = m_thread.m_currentFrame.OpStack.Pop();
|
|
BaseType bf1 = m_thread.m_currentFrame.OpStack.Pop();
|
|
if (bf1 is Float && bf2 is Float)
|
|
{
|
|
Float nflt = new Float();
|
|
nflt.mValue = ((Float) bf1).mValue + ((Float) bf2).mValue;
|
|
m_thread.m_currentFrame.OpStack.Push(nflt);
|
|
}
|
|
result = true;
|
|
break;
|
|
case (byte) OpCode.fsub:
|
|
BaseType bsf2 = m_thread.m_currentFrame.OpStack.Pop();
|
|
BaseType bsf1 = m_thread.m_currentFrame.OpStack.Pop();
|
|
if (bsf1 is Float && bsf2 is Float)
|
|
{
|
|
Float resf = new Float();
|
|
resf.mValue = ((Float) bsf1).mValue - ((Float) bsf2).mValue;
|
|
m_thread.m_currentFrame.OpStack.Push(resf);
|
|
}
|
|
result = true;
|
|
break;
|
|
case (byte) OpCode.imul: //check the order of the two values off the stack is correct
|
|
BaseType bs2 = m_thread.m_currentFrame.OpStack.Pop();
|
|
BaseType bs1 = m_thread.m_currentFrame.OpStack.Pop();
|
|
if (bs1 is Int && bs2 is Int)
|
|
{
|
|
Int nInt = new Int();
|
|
nInt.mValue = ((Int) bs1).mValue*((Int) bs2).mValue;
|
|
m_thread.m_currentFrame.OpStack.Push(nInt);
|
|
}
|
|
result = true;
|
|
break;
|
|
case (byte) OpCode.iinc:
|
|
if (m_thread.m_currentFrame.LocalVariables[GlobalMemory.MethodArea.MethodBuffer[m_thread.PC]] !=
|
|
null)
|
|
{
|
|
if (
|
|
m_thread.m_currentFrame.LocalVariables[GlobalMemory.MethodArea.MethodBuffer[m_thread.PC]
|
|
] is Int)
|
|
{
|
|
((Int)
|
|
m_thread.m_currentFrame.LocalVariables[
|
|
GlobalMemory.MethodArea.MethodBuffer[m_thread.PC]]).mValue +=
|
|
(sbyte) GlobalMemory.MethodArea.MethodBuffer[m_thread.PC + 1];
|
|
}
|
|
}
|
|
m_thread.PC += 2;
|
|
result = true;
|
|
break;
|
|
case (byte) OpCode.f2i:
|
|
BaseType conv1 = m_thread.m_currentFrame.OpStack.Pop();
|
|
if (conv1 is Float)
|
|
{
|
|
Int newconv = new Int();
|
|
newconv.mValue = (int) ((Float) conv1).mValue;
|
|
m_thread.m_currentFrame.OpStack.Push(newconv);
|
|
}
|
|
result = true;
|
|
break;
|
|
case (byte) OpCode.fcmpl:
|
|
BaseType flcom2 = m_thread.m_currentFrame.OpStack.Pop();
|
|
BaseType flcom1 = m_thread.m_currentFrame.OpStack.Pop();
|
|
if (flcom1 is Float && flcom2 is Float)
|
|
{
|
|
Int compres = new Int();
|
|
if (((Float) flcom1).mValue < ((Float) flcom2).mValue)
|
|
{
|
|
compres.mValue = -1;
|
|
}
|
|
else if (((Float) flcom1).mValue > ((Float) flcom2).mValue)
|
|
{
|
|
compres.mValue = 1;
|
|
}
|
|
else
|
|
{
|
|
compres.mValue = 0;
|
|
}
|
|
m_thread.m_currentFrame.OpStack.Push(compres);
|
|
}
|
|
result = true;
|
|
break;
|
|
case (byte) OpCode.fcmpg:
|
|
flcom2 = m_thread.m_currentFrame.OpStack.Pop();
|
|
flcom1 = m_thread.m_currentFrame.OpStack.Pop();
|
|
if (flcom1 is Float && flcom2 is Float)
|
|
{
|
|
Int compres = new Int();
|
|
if (((Float) flcom1).mValue < ((Float) flcom2).mValue)
|
|
{
|
|
compres.mValue = -1;
|
|
}
|
|
else if (((Float) flcom1).mValue > ((Float) flcom2).mValue)
|
|
{
|
|
compres.mValue = 1;
|
|
}
|
|
else
|
|
{
|
|
compres.mValue = 0;
|
|
}
|
|
m_thread.m_currentFrame.OpStack.Push(compres);
|
|
}
|
|
result = true;
|
|
break;
|
|
case (byte) OpCode.ifge:
|
|
short compareoffset2 =
|
|
(short)
|
|
((GlobalMemory.MethodArea.MethodBuffer[m_thread.PC] << 8) +
|
|
GlobalMemory.MethodArea.MethodBuffer[m_thread.PC + 1]);
|
|
BaseType compe1 = m_thread.m_currentFrame.OpStack.Pop();
|
|
if (compe1 is Int)
|
|
{
|
|
if (((Int) compe1).mValue >= 0)
|
|
{
|
|
m_thread.PC += -1 + compareoffset2;
|
|
}
|
|
else
|
|
{
|
|
m_thread.PC += 2;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
m_thread.PC += 2;
|
|
}
|
|
result = true;
|
|
break;
|
|
case (byte) OpCode.ifle:
|
|
short compareoffset1 =
|
|
(short)
|
|
((GlobalMemory.MethodArea.MethodBuffer[m_thread.PC] << 8) +
|
|
GlobalMemory.MethodArea.MethodBuffer[m_thread.PC + 1]);
|
|
BaseType comp1 = m_thread.m_currentFrame.OpStack.Pop();
|
|
if (comp1 is Int)
|
|
{
|
|
if (((Int) comp1).mValue <= 0)
|
|
{
|
|
m_thread.PC += -1 + compareoffset1;
|
|
}
|
|
else
|
|
{
|
|
m_thread.PC += 2;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
m_thread.PC += 2;
|
|
}
|
|
result = true;
|
|
break;
|
|
case (byte) OpCode.if_icmpge:
|
|
short compareoffset =
|
|
(short)
|
|
((GlobalMemory.MethodArea.MethodBuffer[m_thread.PC] << 8) +
|
|
GlobalMemory.MethodArea.MethodBuffer[m_thread.PC + 1]);
|
|
BaseType bc2 = m_thread.m_currentFrame.OpStack.Pop();
|
|
BaseType bc1 = m_thread.m_currentFrame.OpStack.Pop();
|
|
if (bc1 is Int && bc2 is Int)
|
|
{
|
|
//Console.WriteLine("comparing " + ((Int)bc1).mValue + " and " + ((Int)bc2).mValue);
|
|
if (((Int) bc1).mValue >= ((Int) bc2).mValue)
|
|
{
|
|
// Console.WriteLine("branch compare true , offset is " +compareoffset);
|
|
// Console.WriteLine("current PC is " + this._mThread.PC);
|
|
m_thread.PC += -1 + compareoffset;
|
|
//Console.WriteLine("new PC is " + this._mThread.PC);
|
|
}
|
|
else
|
|
{
|
|
//Console.WriteLine("branch compare false");
|
|
m_thread.PC += 2;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
m_thread.PC += 2;
|
|
}
|
|
result = true;
|
|
break;
|
|
case (byte) OpCode.if_icmple:
|
|
short compareloffset =
|
|
(short)
|
|
((GlobalMemory.MethodArea.MethodBuffer[m_thread.PC] << 8) +
|
|
GlobalMemory.MethodArea.MethodBuffer[m_thread.PC + 1]);
|
|
BaseType bcl2 = m_thread.m_currentFrame.OpStack.Pop();
|
|
BaseType bcl1 = m_thread.m_currentFrame.OpStack.Pop();
|
|
if (bcl1 is Int && bcl2 is Int)
|
|
{
|
|
//Console.WriteLine("comparing " + ((Int)bcl1).mValue + " and " + ((Int)bcl2).mValue);
|
|
if (((Int) bcl1).mValue <= ((Int) bcl2).mValue)
|
|
{
|
|
// Console.WriteLine("branch compare true , offset is " + compareloffset);
|
|
// Console.WriteLine("current PC is " + this._mThread.PC);
|
|
m_thread.PC += -1 + compareloffset;
|
|
// Console.WriteLine("new PC is " + this._mThread.PC);
|
|
}
|
|
else
|
|
{
|
|
//Console.WriteLine("branch compare false");
|
|
m_thread.PC += 2;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
m_thread.PC += 2;
|
|
}
|
|
result = true;
|
|
break;
|
|
case (byte) OpCode._goto:
|
|
short offset =
|
|
(short)
|
|
((GlobalMemory.MethodArea.MethodBuffer[m_thread.PC] << 8) +
|
|
GlobalMemory.MethodArea.MethodBuffer[m_thread.PC + 1]);
|
|
m_thread.PC += -1 + offset;
|
|
result = true;
|
|
break;
|
|
case (byte) OpCode.getstatic:
|
|
short fieldrefIndex =
|
|
(short)
|
|
((GlobalMemory.MethodArea.MethodBuffer[m_thread.PC] << 8) +
|
|
GlobalMemory.MethodArea.MethodBuffer[m_thread.PC + 1]);
|
|
if (m_thread.currentClass.m_constantsPool[fieldrefIndex - 1] is ClassRecord.PoolFieldRef)
|
|
{
|
|
if (
|
|
((ClassRecord.PoolFieldRef) m_thread.currentClass.m_constantsPool[fieldrefIndex - 1]).
|
|
mClass.Name.Value == m_thread.currentClass.MClass.Name.Value)
|
|
{
|
|
//from this class
|
|
if (
|
|
m_thread.currentClass.StaticFields.ContainsKey(
|
|
((ClassRecord.PoolFieldRef)
|
|
m_thread.currentClass.m_constantsPool[fieldrefIndex - 1]).mNameType.Name.Value))
|
|
{
|
|
if (
|
|
m_thread.currentClass.StaticFields[
|
|
((ClassRecord.PoolFieldRef)
|
|
m_thread.currentClass.m_constantsPool[fieldrefIndex - 1]).mNameType.Name.
|
|
Value] is Float)
|
|
{
|
|
Float retFloat = new Float();
|
|
retFloat.mValue =
|
|
((Float)
|
|
m_thread.currentClass.StaticFields[
|
|
((ClassRecord.PoolFieldRef)
|
|
m_thread.currentClass.m_constantsPool[fieldrefIndex - 1]).mNameType.
|
|
Name.Value]).mValue;
|
|
m_thread.m_currentFrame.OpStack.Push(retFloat);
|
|
}
|
|
else if (
|
|
m_thread.currentClass.StaticFields[
|
|
((ClassRecord.PoolFieldRef)
|
|
m_thread.currentClass.m_constantsPool[fieldrefIndex - 1]).mNameType.
|
|
Name.Value] is Int)
|
|
{
|
|
Int retInt = new Int();
|
|
retInt.mValue =
|
|
((Int)
|
|
m_thread.currentClass.StaticFields[
|
|
((ClassRecord.PoolFieldRef)
|
|
m_thread.currentClass.m_constantsPool[fieldrefIndex - 1]).
|
|
mNameType.Name.Value]).mValue;
|
|
// Console.WriteLine("getting static field, " + retInt.mValue);
|
|
m_thread.m_currentFrame.OpStack.Push(retInt);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//get from a different class
|
|
}
|
|
}
|
|
m_thread.PC += 2;
|
|
result = true;
|
|
break;
|
|
case (byte) OpCode.putstatic:
|
|
fieldrefIndex =
|
|
(short)
|
|
((GlobalMemory.MethodArea.MethodBuffer[m_thread.PC] << 8) +
|
|
GlobalMemory.MethodArea.MethodBuffer[m_thread.PC + 1]);
|
|
BaseType addstatic = m_thread.m_currentFrame.OpStack.Pop();
|
|
if (m_thread.currentClass.m_constantsPool[fieldrefIndex - 1] is ClassRecord.PoolFieldRef)
|
|
{
|
|
if (
|
|
((ClassRecord.PoolFieldRef) m_thread.currentClass.m_constantsPool[fieldrefIndex - 1]).
|
|
mClass.Name.Value == m_thread.currentClass.MClass.Name.Value)
|
|
{
|
|
// this class
|
|
if (
|
|
m_thread.currentClass.StaticFields.ContainsKey(
|
|
((ClassRecord.PoolFieldRef)
|
|
m_thread.currentClass.m_constantsPool[fieldrefIndex - 1]).mNameType.Name.Value))
|
|
{
|
|
if (addstatic is Float)
|
|
{
|
|
if (
|
|
m_thread.currentClass.StaticFields[
|
|
((ClassRecord.PoolFieldRef)
|
|
m_thread.currentClass.m_constantsPool[fieldrefIndex - 1]).mNameType.
|
|
Name.Value] is Float)
|
|
{
|
|
Float newf = new Float();
|
|
newf.mValue = ((Float) addstatic).mValue;
|
|
m_thread.currentClass.StaticFields[
|
|
((ClassRecord.PoolFieldRef)
|
|
m_thread.currentClass.m_constantsPool[fieldrefIndex - 1]).mNameType.
|
|
Name.Value] = newf;
|
|
}
|
|
}
|
|
else if (addstatic is Int)
|
|
{
|
|
if (
|
|
m_thread.currentClass.StaticFields[
|
|
((ClassRecord.PoolFieldRef)
|
|
m_thread.currentClass.m_constantsPool[fieldrefIndex - 1]).mNameType.
|
|
Name.Value] is Int)
|
|
{
|
|
//Console.WriteLine("setting static field to " + ((Int)addstatic).mValue);
|
|
Int newi = new Int();
|
|
newi.mValue = ((Int) addstatic).mValue;
|
|
m_thread.currentClass.StaticFields[
|
|
((ClassRecord.PoolFieldRef)
|
|
m_thread.currentClass.m_constantsPool[fieldrefIndex - 1]).mNameType.
|
|
Name.Value] = newi;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// a different class
|
|
}
|
|
}
|
|
m_thread.PC += 2;
|
|
result = true;
|
|
break;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
}
|
|
}
|
|
}
|