From f09a18a7a897994aaed7f7fc4ce751ff7871bb27 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Fri, 18 Oct 2019 14:16:37 +0100 Subject: [PATCH] Yengine: Also error on division by Zero --- .../ScriptEngine/YEngine/MMRScriptBinOpStr.cs | 63 ++++- .../ScriptEngine/YEngine/MMRScriptCodeGen.cs | 220 +++--------------- .../ScriptEngine/YEngine/MMRScriptInlines.cs | 2 +- .../ScriptEngine/YEngine/MMRScriptReduce.cs | 4 +- .../ScriptEngine/YEngine/MMRScriptTokenize.cs | 87 +++++-- 5 files changed, 154 insertions(+), 222 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptBinOpStr.cs b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptBinOpStr.cs index f5e91f778a..89f4ee3b33 100644 --- a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptBinOpStr.cs +++ b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptBinOpStr.cs @@ -34,6 +34,7 @@ using System.Reflection; using System.Reflection.Emit; using System.Text; using System.Text.RegularExpressions; +using OpenSim.Region.ScriptEngine.Shared; using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; @@ -120,6 +121,10 @@ namespace OpenSim.Region.ScriptEngine.Yengine private static MethodInfo infoMethVecDivInt = GetBinOpsMethod("MethVecDivInt", new Type[] { typeof(LSL_Vector), typeof(int) }); private static MethodInfo infoMethVecMulRot = GetBinOpsMethod("MethVecMulRot", new Type[] { typeof(LSL_Vector), typeof(LSL_Rotation) }); private static MethodInfo infoMethVecDivRot = GetBinOpsMethod("MethVecDivRot", new Type[] { typeof(LSL_Vector), typeof(LSL_Rotation) }); + private static MethodInfo infoMethDoubleDivDouble = GetBinOpsMethod("MethDoubleDivDouble", new Type[] { typeof(Double), typeof(Double) }); + private static MethodInfo infoMethLongDivLong = GetBinOpsMethod("MethLongDivLong", new Type[] { typeof(long), typeof(long) }); + private static MethodInfo infoMethDoubleModDouble = GetBinOpsMethod("MethDoubleModDouble", new Type[] { typeof(Double), typeof(Double) }); + private static MethodInfo infoMethLongModLong = GetBinOpsMethod("MethLongModLong", new Type[] { typeof(long), typeof(long) }); private static MethodInfo GetBinOpsMethod(string name, Type[] types) { @@ -589,7 +594,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine result.PopPre(scg, errorAt); left.PushVal(scg, errorAt, tokenTypeFloat); right.PushVal(scg, errorAt, tokenTypeFloat); - scg.ilGen.Emit(errorAt, OpCodes.Div); + //scg.ilGen.Emit(errorAt, OpCodes.Div); + scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethDoubleDivDouble); result.PopPost(scg, errorAt, tokenTypeFloat); } @@ -598,7 +604,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine result.PopPre(scg, errorAt); left.PushVal(scg, errorAt, tokenTypeFloat); right.PushVal(scg, errorAt, tokenTypeFloat); - scg.ilGen.Emit(errorAt, OpCodes.Rem); + //scg.ilGen.Emit(errorAt, OpCodes.Rem); + scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethDoubleModDouble); result.PopPost(scg, errorAt, tokenTypeFloat); } @@ -694,7 +701,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine result.PopPre(scg, errorAt); left.PushVal(scg, errorAt, tokenTypeFloat); right.PushVal(scg, errorAt, tokenTypeFloat); - scg.ilGen.Emit(errorAt, OpCodes.Div); + //scg.ilGen.Emit(errorAt, OpCodes.Div); + scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethDoubleDivDouble); result.PopPost(scg, errorAt, tokenTypeFloat); } @@ -703,7 +711,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine result.PopPre(scg, errorAt); left.PushVal(scg, errorAt, tokenTypeFloat); right.PushVal(scg, errorAt, tokenTypeFloat); - scg.ilGen.Emit(errorAt, OpCodes.Rem); + //scg.ilGen.Emit(errorAt, OpCodes.Rem); + scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethDoubleModDouble); result.PopPost(scg, errorAt, tokenTypeFloat); } @@ -917,7 +926,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine scg.ilGen.Emit(errorAt, OpCodes.Conv_I8); right.PushVal(scg, errorAt, tokenTypeInt); scg.ilGen.Emit(errorAt, OpCodes.Conv_I8); - scg.ilGen.Emit(errorAt, OpCodes.Div); + //scg.ilGen.Emit(errorAt, OpCodes.Div); + scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethLongDivLong); scg.ilGen.Emit(errorAt, OpCodes.Conv_I4); result.PopPost(scg, errorAt, tokenTypeInt); } @@ -931,7 +941,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine scg.ilGen.Emit(errorAt, OpCodes.Conv_I8); right.PushVal(scg, errorAt, tokenTypeInt); scg.ilGen.Emit(errorAt, OpCodes.Conv_I8); - scg.ilGen.Emit(errorAt, OpCodes.Rem); + //scg.ilGen.Emit(errorAt, OpCodes.Rem); + scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethLongModLong); scg.ilGen.Emit(errorAt, OpCodes.Conv_I4); result.PopPost(scg, errorAt, tokenTypeInt); } @@ -1573,5 +1584,45 @@ namespace OpenSim.Region.ScriptEngine.Yengine { return left / right; } + + public static double MethDoubleDivDouble(double a, double b) + { + double r = a / b; + if (double.IsNaN(r) || double.IsInfinity(r)) + throw new ScriptException("Division by Zero"); + return r; + } + + public static long MethLongDivLong(long a, long b) + { + try + { + return a / b; + } + catch (DivideByZeroException) + { + throw new ScriptException("Division by Zero"); + } + } + + public static double MethDoubleModDouble(double a, double b) + { + double r = a % b; + if (double.IsNaN(r) || double.IsInfinity(r)) + throw new ScriptException("Division by Zero"); + return r; + } + + public static long MethLongModLong(long a, long b) + { + try + { + return a % b; + } + catch (DivideByZeroException) + { + throw new ScriptException("Division by Zero"); + } + } } } diff --git a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCodeGen.cs b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCodeGen.cs index 27fde5b22c..da17a13008 100644 --- a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCodeGen.cs +++ b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCodeGen.cs @@ -64,9 +64,6 @@ namespace OpenSim.Region.ScriptEngine.Yengine public class ScriptCodeGen: IScriptCodeGen { - private static readonly bool DEBUG_STACKCAPRES = false; - private static readonly bool DEBUG_TRYSTMT = false; - public static readonly string OBJECT_CODE_MAGIC = "YObjectCode"; // reserve positive version values for original xmr public static int COMPILED_VERSION_VALUE = -2; // decremented when compiler or object file changes @@ -972,11 +969,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine string eventname = declFunc.GetSimpleName(); TokenArgDecl argDecl = declFunc.argDecl; - // Make sure event handler name is valid and that number and type of arguments is correct. - // Apparently some scripts exist with fewer than correct number of args in their declaration - // so allow for that. It is ok because the handlers are called with the arguments in an - // object[] array, and we just won't access the missing argments in the vector. But the - // specified types must match one of the prototypes in legalEventHandlers. + HeapLocals.Clear(); + + // Make sure event handler name is valid and that number and type of arguments is correct. + // Apparently some scripts exist with fewer than correct number of args in their declaration + // so allow for that. It is ok because the handlers are called with the arguments in an + // object[] array, and we just won't access the missing argments in the vector. But the + // specified types must match one of the prototypes in legalEventHandlers. TokenDeclVar protoDeclFunc = legalEventHandlers.FindExact(eventname, argDecl.types); if(protoDeclFunc == null) { @@ -1113,7 +1112,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine */ private void GenerateMethodBody(TokenDeclVar declFunc) { - // Set up code generator for the function's contents. + HeapLocals.Clear(); + + // Set up code generator for the function's contents. _ilGen = declFunc.ilGen; StartFunctionBody(declFunc); @@ -1258,7 +1259,6 @@ namespace OpenSim.Region.ScriptEngine.Yengine // resume at the correct spot. actCallLabels.Clear(); allCallLabels.Clear(); - HeapLocals.Clear(); openCallLabel = null; // Alloc stack space for local vars. @@ -1405,18 +1405,18 @@ namespace OpenSim.Region.ScriptEngine.Yengine // Build list of locals and temps active at all the call labels. activeTemps = new List(); foreach (CallLabel cl in allCallLabels) + { + foreach (ScriptMyLocal lcl in cl.callLabel.whereAmI.localsReadBeforeWritten) { - foreach(ScriptMyLocal lcl in cl.callLabel.whereAmI.localsReadBeforeWritten) + if (!activeTemps.Contains(lcl)) { - if(!activeTemps.Contains(lcl)) - { activeTemps.Add(lcl); } } } - // Output code to restore the args, locals and temps then jump to - // the call label that we were interrupted at. + // Output code to restore the args, locals and temps then jump to + // the call label that we were interrupted at. ilGen.MarkLabel(cmRestore); GenerateFrameRestoreCode(activeTemps); } @@ -1546,15 +1546,6 @@ namespace OpenSim.Region.ScriptEngine.Yengine ilGen.Emit(curDeclFunc, OpCodes.Ldc_I4, nSaves); ilGen.Emit(curDeclFunc, OpCodes.Call, captureStackFrameMethodInfo); - if(DEBUG_STACKCAPRES) - { - ilGen.Emit(curDeclFunc, OpCodes.Ldstr, ilGen.methName + "*: capture mainCallNo="); - ilGen.Emit(curDeclFunc, OpCodes.Call, consoleWriteMethodInfo); - ilGen.Emit(curDeclFunc, OpCodes.Ldloc, actCallNo); - ilGen.Emit(curDeclFunc, OpCodes.Box, typeof(int)); - ilGen.Emit(curDeclFunc, OpCodes.Call, consoleWriteMethodInfo); - } - // Copy arg values to object array, boxing as needed. int i = 0; foreach(TokenDeclVar argVar in curDeclFunc.argDecl.varDict) @@ -1562,13 +1553,6 @@ namespace OpenSim.Region.ScriptEngine.Yengine ilGen.Emit(curDeclFunc, OpCodes.Dup); ilGen.Emit(curDeclFunc, OpCodes.Ldc_I4, i); argVar.location.PushVal(this, argVar.name, tokenTypeObj); - if(DEBUG_STACKCAPRES) - { - ilGen.Emit(curDeclFunc, OpCodes.Ldstr, "\n arg:" + argVar.name.val + "="); - ilGen.Emit(curDeclFunc, OpCodes.Call, consoleWriteMethodInfo); - ilGen.Emit(curDeclFunc, OpCodes.Dup); - ilGen.Emit(curDeclFunc, OpCodes.Call, consoleWriteMethodInfo); - } ilGen.Emit(curDeclFunc, OpCodes.Stelem_Ref); i++; } @@ -1596,20 +1580,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine { ilGen.Emit(curDeclFunc, OpCodes.Box, t); } - if(DEBUG_STACKCAPRES) - { - ilGen.Emit(curDeclFunc, OpCodes.Ldstr, "\n lcl:" + lcl.name + "="); - ilGen.Emit(curDeclFunc, OpCodes.Call, consoleWriteMethodInfo); - ilGen.Emit(curDeclFunc, OpCodes.Dup); - ilGen.Emit(curDeclFunc, OpCodes.Call, consoleWriteMethodInfo); - } ilGen.Emit(curDeclFunc, OpCodes.Stelem_Ref); } - if(DEBUG_STACKCAPRES) - { - ilGen.Emit(curDeclFunc, OpCodes.Ldstr, "\n"); - ilGen.Emit(curDeclFunc, OpCodes.Call, consoleWriteMethodInfo); - } ilGen.Emit(curDeclFunc, OpCodes.Pop); } @@ -1629,14 +1601,6 @@ namespace OpenSim.Region.ScriptEngine.Yengine ilGen.Emit(curDeclFunc, OpCodes.Ldloca, actCallNo); // __mainCallNo ilGen.Emit(curDeclFunc, OpCodes.Call, restoreStackFrameMethodInfo); ilGen.Emit(curDeclFunc, OpCodes.Stloc, objArray); - if(DEBUG_STACKCAPRES) - { - ilGen.Emit(curDeclFunc, OpCodes.Ldstr, ilGen.methName + "*: restore mainCallNo="); - ilGen.Emit(curDeclFunc, OpCodes.Call, consoleWriteMethodInfo); - ilGen.Emit(curDeclFunc, OpCodes.Ldloc, actCallNo); - ilGen.Emit(curDeclFunc, OpCodes.Box, typeof(int)); - ilGen.Emit(curDeclFunc, OpCodes.Call, consoleWriteMethodInfo); - } // Restore argument values from object array, unboxing as needed. // Although the caller has restored them to what it called us with, it's possible that this @@ -1649,13 +1613,6 @@ namespace OpenSim.Region.ScriptEngine.Yengine ilGen.Emit(curDeclFunc, OpCodes.Ldloc, objArray); ilGen.Emit(curDeclFunc, OpCodes.Ldc_I4, i); ilGen.Emit(curDeclFunc, OpCodes.Ldelem_Ref); - if(DEBUG_STACKCAPRES) - { - ilGen.Emit(curDeclFunc, OpCodes.Ldstr, "\n arg:" + argVar.name.val + "="); - ilGen.Emit(curDeclFunc, OpCodes.Call, consoleWriteMethodInfo); - ilGen.Emit(curDeclFunc, OpCodes.Dup); - ilGen.Emit(curDeclFunc, OpCodes.Call, consoleWriteMethodInfo); - } TypeCast.CastTopOfStack(this, argVar.name, tokenTypeObj, argLoc.type, true); argLoc.PopPost(this, argVar.name); i++; @@ -1679,13 +1636,6 @@ namespace OpenSim.Region.ScriptEngine.Yengine ilGen.Emit(curDeclFunc, OpCodes.Ldloc, objArray); ilGen.Emit(curDeclFunc, OpCodes.Ldc_I4, i++); ilGen.Emit(curDeclFunc, OpCodes.Ldelem_Ref); - if(DEBUG_STACKCAPRES) - { - ilGen.Emit(curDeclFunc, OpCodes.Ldstr, "\n lcl:" + lcl.name + "="); - ilGen.Emit(curDeclFunc, OpCodes.Call, consoleWriteMethodInfo); - ilGen.Emit(curDeclFunc, OpCodes.Dup); - ilGen.Emit(curDeclFunc, OpCodes.Call, consoleWriteMethodInfo); - } if(u.IsValueType) { ilGen.Emit(curDeclFunc, OpCodes.Unbox_Any, u); @@ -1708,11 +1658,6 @@ namespace OpenSim.Region.ScriptEngine.Yengine ilGen.Emit(curDeclFunc, OpCodes.Stloc, lcl); } } - if(DEBUG_STACKCAPRES) - { - ilGen.Emit(curDeclFunc, OpCodes.Ldstr, "\n"); - ilGen.Emit(curDeclFunc, OpCodes.Call, consoleWriteMethodInfo); - } OutputCallNoSwitchStmt(); } @@ -3235,34 +3180,6 @@ namespace OpenSim.Region.ScriptEngine.Yengine new CallLabel(this, tryStmt); // : ilGen.BeginExceptionBlock(); // try { openCallLabel = null; - if(DEBUG_TRYSTMT) - { - ilGen.Emit(tryStmt, OpCodes.Ldstr, "enter try*: " + tryStmt.line + " callMode="); - ilGen.Emit(tryStmt, OpCodes.Call, consoleWriteMethodInfo); - PushXMRInst(); - ilGen.Emit(tryStmt, OpCodes.Ldfld, callModeFieldInfo); - ilGen.Emit(tryStmt, OpCodes.Box, typeof(int)); - ilGen.Emit(tryStmt, OpCodes.Call, consoleWriteMethodInfo); - ilGen.Emit(tryStmt, OpCodes.Ldstr, " tryCallNo="); - ilGen.Emit(tryStmt, OpCodes.Call, consoleWriteMethodInfo); - tryCallNo.PushVal(this, tryStmt); - ilGen.Emit(tryStmt, OpCodes.Box, typeof(int)); - ilGen.Emit(tryStmt, OpCodes.Call, consoleWriteMethodInfo); - ilGen.Emit(tryStmt, OpCodes.Ldstr, " catThrown.IsNull="); - ilGen.Emit(tryStmt, OpCodes.Call, consoleWriteMethodInfo); - catThrown.PushVal(this, tryStmt); - ilGen.Emit(tryStmt, OpCodes.Ldnull); - ilGen.Emit(tryStmt, OpCodes.Ceq); - ilGen.Emit(tryStmt, OpCodes.Box, typeof(int)); - ilGen.Emit(tryStmt, OpCodes.Call, consoleWriteMethodInfo); - ilGen.Emit(tryStmt, OpCodes.Ldstr, " catCallNo="); - ilGen.Emit(tryStmt, OpCodes.Call, consoleWriteMethodInfo); - catCallNo.PushVal(this, tryStmt); - ilGen.Emit(tryStmt, OpCodes.Box, typeof(int)); - ilGen.Emit(tryStmt, OpCodes.Call, consoleWriteMethodInfo); - ilGen.Emit(tryStmt, OpCodes.Ldstr, "\n"); - ilGen.Emit(tryStmt, OpCodes.Call, consoleWriteMethodInfo); - } GetCallNo(tryStmt, tryCallNo); // if (__tryCallNo >= 0) goto tryCallSw; ilGen.Emit(tryStmt, OpCodes.Ldc_I4_0); @@ -3282,31 +3199,12 @@ namespace OpenSim.Region.ScriptEngine.Yengine } CallLabel tryThrow = new CallLabel(this, tryStmt); // tryThrow:: - if(DEBUG_TRYSTMT) - { - ilGen.Emit(tryStmt, OpCodes.Ldstr, "tryThrow*: " + tryStmt.line + " catThrown="); - ilGen.Emit(tryStmt, OpCodes.Call, consoleWriteMethodInfo); - catThrown.PushVal(this, tryStmt); - ilGen.Emit(tryStmt, OpCodes.Call, consoleWriteMethodInfo); - ilGen.Emit(tryStmt, OpCodes.Ldstr, "\n"); - ilGen.Emit(tryStmt, OpCodes.Call, consoleWriteMethodInfo); - } catThrown.PushVal(this, tryStmt); // throw new ScriptRestoreCatchException (__catThrown); ilGen.Emit(tryStmt, OpCodes.Newobj, scriptRestoreCatchExceptionConstructorInfo); ilGen.Emit(tryStmt, OpCodes.Throw); openCallLabel = null; ilGen.MarkLabel(tryCallSw); // tryCallSw: - if(DEBUG_TRYSTMT) - { - ilGen.Emit(tryStmt, OpCodes.Ldstr, "tryCallSw*: " + tryStmt.line + " tryCallNo="); - ilGen.Emit(tryStmt, OpCodes.Call, consoleWriteMethodInfo); - tryCallNo.PushVal(this, tryStmt); - ilGen.Emit(tryStmt, OpCodes.Box, typeof(int)); - ilGen.Emit(tryStmt, OpCodes.Call, consoleWriteMethodInfo); - ilGen.Emit(tryStmt, OpCodes.Ldstr, "\n"); - ilGen.Emit(tryStmt, OpCodes.Call, consoleWriteMethodInfo); - } OutputCallNoSwitchStmt(); // switch (tryCallNo) ... CompValuLocalVar catchVarLocExc = null; @@ -3324,26 +3222,6 @@ namespace OpenSim.Region.ScriptEngine.Yengine ScriptMyLocal excLocal = ilGen.DeclareLocal(typeof(String), "catchstr_" + tryStmt.Unique); ilGen.BeginCatchBlock(typeof(Exception)); // start of the catch block that can catch any exception - if(DEBUG_TRYSTMT) - { - ilGen.Emit(tryStmt.catchStmt, OpCodes.Ldstr, "enter catch*: " + tryStmt.line + " callMode="); - ilGen.Emit(tryStmt.catchStmt, OpCodes.Call, consoleWriteMethodInfo); - PushXMRInst(); - ilGen.Emit(tryStmt.catchStmt, OpCodes.Ldfld, callModeFieldInfo); - ilGen.Emit(tryStmt.catchStmt, OpCodes.Box, typeof(int)); - ilGen.Emit(tryStmt.catchStmt, OpCodes.Call, consoleWriteMethodInfo); - ilGen.Emit(tryStmt.catchStmt, OpCodes.Ldstr, " catCallNo="); - ilGen.Emit(tryStmt.catchStmt, OpCodes.Call, consoleWriteMethodInfo); - catCallNo.PushVal(this, tryStmt); - ilGen.Emit(tryStmt.catchStmt, OpCodes.Box, typeof(int)); - ilGen.Emit(tryStmt.catchStmt, OpCodes.Call, consoleWriteMethodInfo); - ilGen.Emit(tryStmt.catchStmt, OpCodes.Ldstr, " exc="); - ilGen.Emit(tryStmt.catchStmt, OpCodes.Call, consoleWriteMethodInfo); - ilGen.Emit(tryStmt.catchStmt, OpCodes.Dup); - ilGen.Emit(tryStmt.catchStmt, OpCodes.Call, consoleWriteMethodInfo); - ilGen.Emit(tryStmt.catchStmt, OpCodes.Ldstr, "\n"); - ilGen.Emit(tryStmt.catchStmt, OpCodes.Call, consoleWriteMethodInfo); - } ilGen.Emit(tryStmt.catchStmt, OpCodes.Call, scriptRestoreCatchExceptionUnwrap); // exc = ScriptRestoreCatchException.Unwrap (exc); ilGen.Emit(tryStmt.catchStmt, OpCodes.Dup); // rethrow if IXMRUncatchable (eg, StackCaptureException) @@ -3475,34 +3353,6 @@ namespace OpenSim.Region.ScriptEngine.Yengine ilGen.BeginExceptionBlock(); // try { ilGen.BeginExceptionBlock(); // try { openCallLabel = null; - if(DEBUG_TRYSTMT) - { - ilGen.Emit(tryStmt, OpCodes.Ldstr, "enter try*: " + tryStmt.line + " callMode="); - ilGen.Emit(tryStmt, OpCodes.Call, consoleWriteMethodInfo); - PushXMRInst(); - ilGen.Emit(tryStmt, OpCodes.Ldfld, callModeFieldInfo); - ilGen.Emit(tryStmt, OpCodes.Box, typeof(int)); - ilGen.Emit(tryStmt, OpCodes.Call, consoleWriteMethodInfo); - ilGen.Emit(tryStmt, OpCodes.Ldstr, " tryCallNo="); - ilGen.Emit(tryStmt, OpCodes.Call, consoleWriteMethodInfo); - tryCallNo.PushVal(this, tryStmt); - ilGen.Emit(tryStmt, OpCodes.Box, typeof(int)); - ilGen.Emit(tryStmt, OpCodes.Call, consoleWriteMethodInfo); - ilGen.Emit(tryStmt, OpCodes.Ldstr, " finCallNo="); - ilGen.Emit(tryStmt, OpCodes.Call, consoleWriteMethodInfo); - finCallNo.PushVal(this, tryStmt); - ilGen.Emit(tryStmt, OpCodes.Box, typeof(int)); - ilGen.Emit(tryStmt, OpCodes.Call, consoleWriteMethodInfo); - ilGen.Emit(tryStmt, OpCodes.Ldstr, " catThrown.IsNull="); - ilGen.Emit(tryStmt, OpCodes.Call, consoleWriteMethodInfo); - catThrown.PushVal(this, tryStmt); - ilGen.Emit(tryStmt, OpCodes.Ldnull); - ilGen.Emit(tryStmt, OpCodes.Ceq); - ilGen.Emit(tryStmt, OpCodes.Box, typeof(int)); - ilGen.Emit(tryStmt, OpCodes.Call, consoleWriteMethodInfo); - ilGen.Emit(tryStmt, OpCodes.Ldstr, "\n"); - ilGen.Emit(tryStmt, OpCodes.Call, consoleWriteMethodInfo); - } GetCallNo(tryStmt, tryCallNo); // if (__tryCallNo >= 0) goto tryCallSw; ilGen.Emit(tryStmt, OpCodes.Ldc_I4_0); @@ -3529,15 +3379,6 @@ namespace OpenSim.Region.ScriptEngine.Yengine } CallLabel tryThrow = new CallLabel(this, tryStmt); // tryThrow:: - if(DEBUG_TRYSTMT) - { - ilGen.Emit(tryStmt, OpCodes.Ldstr, "tryThrow*: " + tryStmt.line + " catThrown="); - ilGen.Emit(tryStmt, OpCodes.Call, consoleWriteMethodInfo); - catThrown.PushVal(this, tryStmt); - ilGen.Emit(tryStmt, OpCodes.Call, consoleWriteMethodInfo); - ilGen.Emit(tryStmt, OpCodes.Ldstr, "\n"); - ilGen.Emit(tryStmt, OpCodes.Call, consoleWriteMethodInfo); - } catThrown.PushVal(this, tryStmt); // throw new ScriptRestoreCatchException (__catThrown); ilGen.Emit(tryStmt, OpCodes.Newobj, scriptRestoreCatchExceptionConstructorInfo); ilGen.Emit(tryStmt, OpCodes.Throw); @@ -3548,21 +3389,6 @@ namespace OpenSim.Region.ScriptEngine.Yengine // } ilGen.BeginCatchBlock(typeof(Exception)); // start of the catch block that can catch any exception - if(DEBUG_TRYSTMT) - { - ilGen.Emit(tryStmt, OpCodes.Ldstr, "enter catch*: " + tryStmt.line + " callMode="); - ilGen.Emit(tryStmt, OpCodes.Call, consoleWriteMethodInfo); - PushXMRInst(); - ilGen.Emit(tryStmt, OpCodes.Ldfld, callModeFieldInfo); - ilGen.Emit(tryStmt, OpCodes.Box, typeof(int)); - ilGen.Emit(tryStmt, OpCodes.Call, consoleWriteMethodInfo); - ilGen.Emit(tryStmt, OpCodes.Ldstr, " exc="); - ilGen.Emit(tryStmt, OpCodes.Call, consoleWriteMethodInfo); - ilGen.Emit(tryStmt, OpCodes.Dup); - ilGen.Emit(tryStmt, OpCodes.Call, consoleWriteMethodInfo); - ilGen.Emit(tryStmt, OpCodes.Ldstr, "\n"); - ilGen.Emit(tryStmt, OpCodes.Call, consoleWriteMethodInfo); - } ilGen.Emit(tryStmt, OpCodes.Call, scriptRestoreCatchExceptionUnwrap); // exc = ScriptRestoreCatchException.Unwrap (exc); PushXMRInst(); // if (callMode == CallMode_SAVE) goto catchRetro; ilGen.Emit(tryStmt, OpCodes.Ldfld, callModeFieldInfo); @@ -4154,11 +3980,19 @@ namespace OpenSim.Region.ScriptEngine.Yengine // Maybe the expression can be converted to a constant. bool didOne; - do + try { - didOne = false; - rVal = rVal.TryComputeConstant(LookupBodyConstants, ref didOne); - } while(didOne); + do + { + didOne = false; + rVal = rVal.TryComputeConstant(LookupBodyConstants, ref didOne); + } while(didOne); + } + catch(Exception ex) + { + ErrorMsg(errorMessageToken, ex.Message); + throw; + } // Generate code for the computation and return resulting type and location. CompValu cVal = null; diff --git a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptInlines.cs b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptInlines.cs index e17d41ac2d..31dc5bc50f 100644 --- a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptInlines.cs +++ b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptInlines.cs @@ -138,13 +138,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine }; VarDict ifd = new VarDict(false); - Type[] oneDoub = new Type[] { typeof(double) }; Type[] twoDoubs = new Type[] { typeof(double), typeof(double) }; /* * Mono generates an FPU instruction for many math calls. */ + new TokenDeclInline_LLAbs(ifd); new TokenDeclInline_Math(ifd, "llAcos(float)", "Acos", oneDoub); new TokenDeclInline_Math(ifd, "llAsin(float)", "Asin", oneDoub); diff --git a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptReduce.cs b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptReduce.cs index 85bc9aa260..f3bc764fe1 100644 --- a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptReduce.cs +++ b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptReduce.cs @@ -7296,7 +7296,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine rValRight = rValRight.TryComputeConstant(lookup, ref didOne); if((rValLeft is TokenRValConst) && (rValRight is TokenRValConst)) { - try +// try { object val = opcode.binOpConst(((TokenRValConst)rValLeft).val, ((TokenRValConst)rValRight).val); @@ -7304,7 +7304,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine didOne = true; return rValConst; } - catch +// catch { } } diff --git a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptTokenize.cs b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptTokenize.cs index 199216eea4..e0b7f5db4c 100644 --- a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptTokenize.cs +++ b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptTokenize.cs @@ -611,8 +611,20 @@ namespace OpenSim.Region.ScriptEngine.Yengine continue; } - // Check for option enables. - if((c == ';') && (lastToken is TokenName) && + // Check for option enables. + + if ((c == ';') && (lastToken is TokenName) && + (strcasecmp(((TokenName)lastToken).val, "yoptions") == 0)) + { + options.advFlowCtl = true; + options.tryCatch = true; + + lastToken = lastToken.prevToken; + lastToken.nextToken = null; + continue; + } + + else if ((c == ';') && (lastToken is TokenName) && (lastToken.prevToken is TokenName) && (strcasecmp(((TokenName)lastToken.prevToken).val, "yoption") == 0)) { @@ -2186,44 +2198,79 @@ namespace OpenSim.Region.ScriptEngine.Yengine } public static object Div(object left, object right) { - if((left is int) && (right is int)) + double r; + try { - return (int)left / (int)right; + if ((left is int) && (right is int)) + { + return (int)left / (int)right; + } + if ((left is double) && (right is int)) + { + r = (double)left / (int)right; + if (double.IsNaN(r) || double.IsInfinity(r)) + throw new Exception("Division by Zero"); + return r; + } } - if((left is int) && (right is double)) + catch (DivideByZeroException) { - return (int)left / (double)right; + throw new Exception("Division by Zero"); } - if((left is double) && (right is int)) + + if ((left is int) && (right is double)) { - return (double)left / (int)right; + r = (int)left / (double)right; } - if((left is double) && (right is double)) + else if((left is double) && (right is double)) { - return (double)left / (double)right; + r= (double)left / (double)right; } - return null; + else + return null; + + if (double.IsNaN(r) || double.IsInfinity(r)) + throw new Exception("Division by Zero"); + return r; } public static object Mod(object left, object right) { - if((left is int) && (right is int)) + double r; + try { - return (int)left % (int)right; + if ((left is int) && (right is int)) + { + return (int)left % (int)right; + } + if ((left is double) && (right is int)) + { + r = (double)left % (int)right; + if (double.IsNaN(r) || double.IsInfinity(r)) + throw new Exception("Division by Zero"); + return r; + } } - if((left is int) && (right is double)) + catch (DivideByZeroException) { - return (int)left % (double)right; + throw new Exception("Division by Zero"); } - if((left is double) && (right is int)) + + if ((left is int) && (right is double)) { - return (double)left % (int)right; + r = (int)left % (double)right; } - if((left is double) && (right is double)) + else if ((left is double) && (right is double)) { - return (double)left % (double)right; + r = (double)left % (double)right; } - return null; + else + return null; + + if (double.IsNaN(r) || double.IsInfinity(r)) + throw new Exception("Division by Zero"); + return r; } + public static object Mul(object left, object right) { if((left is int) && (right is int))