/* * 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; } } } }