diff --git a/OpenSim/Region/ScriptEngine/Interfaces/IScriptEngine.cs b/OpenSim/Region/ScriptEngine/Interfaces/IScriptEngine.cs index 17c270810f..20dcac9855 100644 --- a/OpenSim/Region/ScriptEngine/Interfaces/IScriptEngine.cs +++ b/OpenSim/Region/ScriptEngine/Interfaces/IScriptEngine.cs @@ -25,16 +25,17 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -using log4net; using System; -using OpenSim.Region.ScriptEngine.Shared; +using System.Reflection; +using OpenSim.Framework; using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Interfaces; -using OpenMetaverse; -using Nini.Config; using OpenSim.Region.ScriptEngine.Interfaces; +using OpenSim.Region.ScriptEngine.Shared; using Amib.Threading; -using OpenSim.Framework; +using log4net; +using Nini.Config; +using OpenMetaverse; namespace OpenSim.Region.ScriptEngine.Interfaces { @@ -76,6 +77,30 @@ namespace OpenSim.Region.ScriptEngine.Interfaces IConfigSource ConfigSource { get; } string ScriptEngineName { get; } string ScriptEnginePath { get; } + + /// + /// Return the name of the base class that will be used for all running scripts. + /// + string ScriptBaseClassName { get; } + + /// + /// Assemblies that need to be referenced when compiling scripts. + /// + /// + /// These are currently additional to those always referenced by the compiler, BUT THIS MAY CHANGE IN THE + /// FUTURE. + /// This can be null if there are no additional assemblies. + /// + string[] ScriptReferencedAssemblies { get; } + + /// + /// Parameters for the generated script's constructor. + /// + /// + /// Can be null if there are no parameters + /// + ParameterInfo[] ScriptBaseClassParameters { get; } + IScriptApi GetApi(UUID itemID, string name); } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 79137b1b4b..6def207345 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -183,7 +183,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { if (m_coopSleepHandle == null) System.Threading.Thread.Sleep(delay); - else if (m_coopSleepHandle.WaitOne(delay)) + else + CheckForCoopTermination(delay); + } + + /// + /// Check for co-operative termination. + /// + /// If called with 0, then just the check is performed with no wait. + protected virtual void CheckForCoopTermination(int delay) + { + if (m_coopSleepHandle.WaitOne(delay)) throw new ScriptCoopStopException(); } diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs index 97dd0f6122..002f9b8a44 100644 --- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs +++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs @@ -49,6 +49,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools private List m_warnings = new List(); private IScriptModuleComms m_comms = null; + private bool m_insertCoopTerminationChecks; + private static string m_coopTerminationCheck = "opensim_reserved_CheckForCoopTermination();"; + + /// + /// Keep a record of the previous node when we do the parsing. + /// + /// + /// We do this here because the parser generated by CSTools does not retain a reference to its parent node. + /// The previous node is required so we can correctly insert co-op termination checks when required. + /// +// private SYMBOL m_previousNode; + /// /// Creates an 'empty' CSCodeGenerator instance. /// @@ -58,9 +70,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools ResetCounters(); } - public CSCodeGenerator(IScriptModuleComms comms) + public CSCodeGenerator(IScriptModuleComms comms, bool insertCoopTerminationChecks) { m_comms = comms; + m_insertCoopTerminationChecks = insertCoopTerminationChecks; ResetCounters(); } @@ -155,7 +168,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools // here's the payload retstr += GenerateLine(); foreach (SYMBOL s in m_astRoot.kids) - retstr += GenerateNode(s); + retstr += GenerateNode(m_astRoot, s); // close braces! m_braceCount--; @@ -165,7 +178,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools // Removes all carriage return characters which may be generated in Windows platform. Is there // cleaner way of doing this? - retstr=retstr.Replace("\r", ""); + retstr = retstr.Replace("\r", ""); return retstr; } @@ -191,9 +204,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools /// Recursively called to generate each type of node. Will generate this /// node, then all it's children. /// + /// The parent node. /// The current node to generate code for. /// String containing C# code for SYMBOL s. - private string GenerateNode(SYMBOL s) + private string GenerateNode(SYMBOL previousSymbol, SYMBOL s) { string retstr = String.Empty; @@ -207,11 +221,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools else if (s is State) retstr += GenerateState((State) s); else if (s is CompoundStatement) - retstr += GenerateCompoundStatement((CompoundStatement) s); + retstr += GenerateCompoundStatement(previousSymbol, (CompoundStatement) s); else if (s is Declaration) retstr += GenerateDeclaration((Declaration) s); else if (s is Statement) - retstr += GenerateStatement((Statement) s); + retstr += GenerateStatement(previousSymbol, (Statement) s); else if (s is ReturnStatement) retstr += GenerateReturnStatement((ReturnStatement) s); else if (s is JumpLabel) @@ -261,7 +275,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools else { foreach (SYMBOL kid in s.kids) - retstr += GenerateNode(kid); + retstr += GenerateNode(s, kid); } return retstr; @@ -295,7 +309,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools retstr += GenerateLine(")"); foreach (SYMBOL kid in remainingKids) - retstr += GenerateNode(kid); + retstr += GenerateNode(gf, kid); return retstr; } @@ -312,7 +326,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools foreach (SYMBOL s in gv.kids) { retstr += Indent(); - retstr += GenerateNode(s); + retstr += GenerateNode(gv, s); retstr += GenerateLine(";"); } @@ -365,7 +379,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools retstr += GenerateLine(")"); foreach (SYMBOL kid in remainingKids) - retstr += GenerateNode(kid); + retstr += GenerateNode(se, kid); return retstr; } @@ -404,7 +418,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools foreach (SYMBOL s in al.kids) { - retstr += GenerateNode(s); + retstr += GenerateNode(al, s); if (0 < comma--) retstr += Generate(", "); } @@ -417,7 +431,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools /// /// The CompoundStatement node. /// String containing C# code for CompoundStatement cs. - private string GenerateCompoundStatement(CompoundStatement cs) + private string GenerateCompoundStatement(SYMBOL previousSymbol, CompoundStatement cs) { string retstr = String.Empty; @@ -425,8 +439,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools retstr += GenerateIndentedLine("{"); m_braceCount++; + if (m_insertCoopTerminationChecks) + { + // We have to check in event functions as well because the user can manually call these. + if (previousSymbol is GlobalFunctionDefinition + || previousSymbol is WhileStatement + || previousSymbol is DoWhileStatement + || previousSymbol is ForLoopStatement + || previousSymbol is StateEvent) + retstr += GenerateIndentedLine(m_coopTerminationCheck); + } + foreach (SYMBOL kid in cs.kids) - retstr += GenerateNode(kid); + retstr += GenerateNode(cs, kid); // closing brace m_braceCount--; @@ -450,13 +475,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools /// /// The Statement node. /// String containing C# code for Statement s. - private string GenerateStatement(Statement s) + private string GenerateStatement(SYMBOL previousSymbol, Statement s) { string retstr = String.Empty; bool printSemicolon = true; retstr += Indent(); + if (m_insertCoopTerminationChecks) + { + // We have to check in event functions as well because the user can manually call these. + if (previousSymbol is GlobalFunctionDefinition + || previousSymbol is WhileStatement + || previousSymbol is DoWhileStatement + || previousSymbol is ForLoop + || previousSymbol is StateEvent) + retstr += Generate(m_coopTerminationCheck); + } + if (0 < s.kids.Count) { // Jump label prints its own colon, we don't need a semicolon. @@ -466,7 +502,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools // (MONO) error. if (!(s.kids.Top is IdentExpression && 1 == s.kids.Count)) foreach (SYMBOL kid in s.kids) - retstr += GenerateNode(kid); + retstr += GenerateNode(s, kid); } if (printSemicolon) @@ -487,10 +523,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools List identifiers = new List(); checkForMultipleAssignments(identifiers, a); - retstr += GenerateNode((SYMBOL) a.kids.Pop()); + retstr += GenerateNode(a, (SYMBOL) a.kids.Pop()); retstr += Generate(String.Format(" {0} ", a.AssignmentType), a); foreach (SYMBOL kid in a.kids) - retstr += GenerateNode(kid); + retstr += GenerateNode(a, kid); return retstr; } @@ -563,7 +599,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools retstr += Generate("return ", rs); foreach (SYMBOL kid in rs.kids) - retstr += GenerateNode(kid); + retstr += GenerateNode(rs, kid); return retstr; } @@ -575,7 +611,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools /// String containing C# code for JumpLabel jl. private string GenerateJumpLabel(JumpLabel jl) { - return Generate(String.Format("{0}:", CheckName(jl.LabelName)), jl) + " NoOp();\n"; + string labelStatement; + + if (m_insertCoopTerminationChecks) + labelStatement = m_coopTerminationCheck + "\n"; + else + labelStatement = "NoOp();\n"; + + return Generate(String.Format("{0}: ", CheckName(jl.LabelName)), jl) + labelStatement; } /// @@ -598,14 +641,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools string retstr = String.Empty; retstr += GenerateIndented("if (", ifs); - retstr += GenerateNode((SYMBOL) ifs.kids.Pop()); + retstr += GenerateNode(ifs, (SYMBOL) ifs.kids.Pop()); retstr += GenerateLine(")"); // CompoundStatement handles indentation itself but we need to do it // otherwise. bool indentHere = ifs.kids.Top is Statement; if (indentHere) m_braceCount++; - retstr += GenerateNode((SYMBOL) ifs.kids.Pop()); + retstr += GenerateNode(ifs, (SYMBOL) ifs.kids.Pop()); if (indentHere) m_braceCount--; if (0 < ifs.kids.Count) // do it again for an else @@ -614,7 +657,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools indentHere = ifs.kids.Top is Statement; if (indentHere) m_braceCount++; - retstr += GenerateNode((SYMBOL) ifs.kids.Pop()); + retstr += GenerateNode(ifs, (SYMBOL) ifs.kids.Pop()); if (indentHere) m_braceCount--; } @@ -641,14 +684,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools string retstr = String.Empty; retstr += GenerateIndented("while (", ws); - retstr += GenerateNode((SYMBOL) ws.kids.Pop()); + retstr += GenerateNode(ws, (SYMBOL) ws.kids.Pop()); retstr += GenerateLine(")"); // CompoundStatement handles indentation itself but we need to do it // otherwise. bool indentHere = ws.kids.Top is Statement; if (indentHere) m_braceCount++; - retstr += GenerateNode((SYMBOL) ws.kids.Pop()); + retstr += GenerateNode(ws, (SYMBOL) ws.kids.Pop()); if (indentHere) m_braceCount--; return retstr; @@ -669,11 +712,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools // otherwise. bool indentHere = dws.kids.Top is Statement; if (indentHere) m_braceCount++; - retstr += GenerateNode((SYMBOL) dws.kids.Pop()); + retstr += GenerateNode(dws, (SYMBOL) dws.kids.Pop()); if (indentHere) m_braceCount--; retstr += GenerateIndented("while (", dws); - retstr += GenerateNode((SYMBOL) dws.kids.Pop()); + retstr += GenerateNode(dws, (SYMBOL) dws.kids.Pop()); retstr += GenerateLine(");"); return retstr; @@ -702,7 +745,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools retstr += Generate("; "); // for (x = 0; x < 10; x++) // ^^^^^^ - retstr += GenerateNode((SYMBOL) fl.kids.Pop()); + retstr += GenerateNode(fl, (SYMBOL) fl.kids.Pop()); retstr += Generate("; "); // for (x = 0; x < 10; x++) // ^^^ @@ -713,7 +756,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools // otherwise. bool indentHere = fl.kids.Top is Statement; if (indentHere) m_braceCount++; - retstr += GenerateNode((SYMBOL) fl.kids.Pop()); + retstr += GenerateNode(fl, (SYMBOL) fl.kids.Pop()); if (indentHere) m_braceCount--; return retstr; @@ -758,7 +801,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools while (s is ParenthesisExpression) s = (SYMBOL)s.kids.Pop(); - retstr += GenerateNode(s); + retstr += GenerateNode(fls, s); if (0 < comma--) retstr += Generate(", "); } @@ -779,20 +822,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools { // special case handling for logical and/or, see Mantis 3174 retstr += "((bool)("; - retstr += GenerateNode((SYMBOL)be.kids.Pop()); + retstr += GenerateNode(be, (SYMBOL)be.kids.Pop()); retstr += "))"; retstr += Generate(String.Format(" {0} ", be.ExpressionSymbol.Substring(0,1)), be); retstr += "((bool)("; foreach (SYMBOL kid in be.kids) - retstr += GenerateNode(kid); + retstr += GenerateNode(be, kid); retstr += "))"; } else { - retstr += GenerateNode((SYMBOL)be.kids.Pop()); + retstr += GenerateNode(be, (SYMBOL)be.kids.Pop()); retstr += Generate(String.Format(" {0} ", be.ExpressionSymbol), be); foreach (SYMBOL kid in be.kids) - retstr += GenerateNode(kid); + retstr += GenerateNode(be, kid); } return retstr; @@ -808,7 +851,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools string retstr = String.Empty; retstr += Generate(ue.UnarySymbol, ue); - retstr += GenerateNode((SYMBOL) ue.kids.Pop()); + retstr += GenerateNode(ue, (SYMBOL) ue.kids.Pop()); return retstr; } @@ -824,7 +867,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools retstr += Generate("("); foreach (SYMBOL kid in pe.kids) - retstr += GenerateNode(kid); + retstr += GenerateNode(pe, kid); retstr += Generate(")"); return retstr; @@ -861,7 +904,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools // we wrap all typecasted statements in parentheses retstr += Generate(String.Format("({0}) (", te.TypecastType), te); - retstr += GenerateNode((SYMBOL) te.kids.Pop()); + retstr += GenerateNode(te, (SYMBOL) te.kids.Pop()); retstr += Generate(")"); return retstr; @@ -931,7 +974,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools } foreach (SYMBOL kid in fc.kids) - retstr += GenerateNode(kid); + retstr += GenerateNode(fc, kid); retstr += Generate(")"); @@ -980,11 +1023,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools string retstr = String.Empty; retstr += Generate(String.Format("new {0}(", vc.Type), vc); - retstr += GenerateNode((SYMBOL) vc.kids.Pop()); + retstr += GenerateNode(vc, (SYMBOL) vc.kids.Pop()); retstr += Generate(", "); - retstr += GenerateNode((SYMBOL) vc.kids.Pop()); + retstr += GenerateNode(vc, (SYMBOL) vc.kids.Pop()); retstr += Generate(", "); - retstr += GenerateNode((SYMBOL) vc.kids.Pop()); + retstr += GenerateNode(vc, (SYMBOL) vc.kids.Pop()); retstr += Generate(")"); return retstr; @@ -1000,13 +1043,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools string retstr = String.Empty; retstr += Generate(String.Format("new {0}(", rc.Type), rc); - retstr += GenerateNode((SYMBOL) rc.kids.Pop()); + retstr += GenerateNode(rc, (SYMBOL) rc.kids.Pop()); retstr += Generate(", "); - retstr += GenerateNode((SYMBOL) rc.kids.Pop()); + retstr += GenerateNode(rc, (SYMBOL) rc.kids.Pop()); retstr += Generate(", "); - retstr += GenerateNode((SYMBOL) rc.kids.Pop()); + retstr += GenerateNode(rc, (SYMBOL) rc.kids.Pop()); retstr += Generate(", "); - retstr += GenerateNode((SYMBOL) rc.kids.Pop()); + retstr += GenerateNode(rc, (SYMBOL) rc.kids.Pop()); retstr += Generate(")"); return retstr; @@ -1024,7 +1067,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools retstr += Generate(String.Format("new {0}(", lc.Type), lc); foreach (SYMBOL kid in lc.kids) - retstr += GenerateNode(kid); + retstr += GenerateNode(lc, kid); retstr += Generate(")"); diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs index 17a0d69838..8f6055624b 100644 --- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs +++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs @@ -31,6 +31,7 @@ using System.Collections.Generic; using System.Globalization; using System.Reflection; using System.IO; +using System.Linq; using System.Text; using Microsoft.CSharp; //using Microsoft.JScript; @@ -72,6 +73,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools private bool CompileWithDebugInformation; private Dictionary AllowedCompilers = new Dictionary(StringComparer.CurrentCultureIgnoreCase); private Dictionary LanguageMapping = new Dictionary(StringComparer.CurrentCultureIgnoreCase); + private bool m_insertCoopTerminationCalls; private string FilePrefix; private string ScriptEnginesPath = null; @@ -95,20 +97,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools private Dictionary, KeyValuePair>> m_lineMaps = new Dictionary, KeyValuePair>>(); + public bool in_startup = true; + public Compiler(IScriptEngine scriptEngine) { - m_scriptEngine = scriptEngine;; + m_scriptEngine = scriptEngine; ScriptEnginesPath = scriptEngine.ScriptEnginePath; ReadConfig(); } - public bool in_startup = true; public void ReadConfig() { // Get some config WriteScriptSourceToDebugFile = m_scriptEngine.Config.GetBoolean("WriteScriptSourceToDebugFile", false); CompileWithDebugInformation = m_scriptEngine.Config.GetBoolean("CompileWithDebugInformation", true); bool DeleteScriptsOnStartup = m_scriptEngine.Config.GetBoolean("DeleteScriptsOnStartup", true); + m_insertCoopTerminationCalls = m_scriptEngine.Config.GetString("ScriptStopStrategy", "abort") == "co-op"; // Get file prefix from scriptengine name and make it file system safe: FilePrefix = "CommonCompiler"; @@ -386,7 +390,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools if (language == enumCompileType.lsl) { // Its LSL, convert it to C# - LSL_Converter = (ICodeConverter)new CSCodeGenerator(comms); + LSL_Converter = (ICodeConverter)new CSCodeGenerator(comms, m_insertCoopTerminationCalls); compileScript = LSL_Converter.Convert(Script); // copy converter warnings into our warnings. @@ -411,16 +415,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools { case enumCompileType.cs: case enumCompileType.lsl: - compileScript = CreateCSCompilerScript(compileScript); + compileScript = CreateCSCompilerScript( + compileScript, m_scriptEngine.ScriptBaseClassName, m_scriptEngine.ScriptBaseClassParameters); break; case enumCompileType.vb: - compileScript = CreateVBCompilerScript(compileScript); + compileScript = CreateVBCompilerScript(compileScript, m_scriptEngine.ScriptBaseClassName); break; // case enumCompileType.js: -// compileScript = CreateJSCompilerScript(compileScript); +// compileScript = CreateJSCompilerScript(compileScript, m_scriptEngine.ScriptBaseClassName); // break; case enumCompileType.yp: - compileScript = CreateYPCompilerScript(compileScript); + compileScript = CreateYPCompilerScript(compileScript, m_scriptEngine.ScriptBaseClassName); break; } @@ -451,43 +456,59 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools // return compileScript; // } - private static string CreateCSCompilerScript(string compileScript) + private static string CreateCSCompilerScript( + string compileScript, string baseClassName, ParameterInfo[] constructorParameters) { - compileScript = String.Empty + - "using OpenSim.Region.ScriptEngine.Shared; using System.Collections.Generic;\r\n" + - String.Empty + "namespace SecondLife { " + - String.Empty + "public class Script : OpenSim.Region.ScriptEngine.Shared.ScriptBase.ScriptBaseClass { \r\n" + - @"public Script() { } " + - compileScript + - "} }\r\n"; + compileScript = string.Format( +@"using OpenSim.Region.ScriptEngine.Shared; +using System.Collections.Generic; + +namespace SecondLife +{{ + public class Script : {0} + {{ + public Script({1}) : base({2}) {{}} +{3} + }} +}}", + baseClassName, + constructorParameters != null + ? string.Join(", ", Array.ConvertAll(constructorParameters, pi => pi.ToString())) + : "", + constructorParameters != null + ? string.Join(", ", Array.ConvertAll(constructorParameters, pi => pi.Name)) + : "", + compileScript); + return compileScript; } - private static string CreateYPCompilerScript(string compileScript) + private static string CreateYPCompilerScript(string compileScript, string baseClassName) { compileScript = String.Empty + "using OpenSim.Region.ScriptEngine.Shared.YieldProlog; " + "using OpenSim.Region.ScriptEngine.Shared; using System.Collections.Generic;\r\n" + String.Empty + "namespace SecondLife { " + - String.Empty + "public class Script : OpenSim.Region.ScriptEngine.Shared.ScriptBase.ScriptBaseClass { \r\n" + + String.Empty + "public class Script : " + baseClassName + " { \r\n" + //@"public Script() { } " + @"static OpenSim.Region.ScriptEngine.Shared.YieldProlog.YP YP=null; " + @"public Script() { YP= new OpenSim.Region.ScriptEngine.Shared.YieldProlog.YP(); } " + - compileScript + "} }\r\n"; + return compileScript; } - private static string CreateVBCompilerScript(string compileScript) + private static string CreateVBCompilerScript(string compileScript, string baseClassName) { compileScript = String.Empty + "Imports OpenSim.Region.ScriptEngine.Shared: Imports System.Collections.Generic: " + String.Empty + "NameSpace SecondLife:" + - String.Empty + "Public Class Script: Inherits OpenSim.Region.ScriptEngine.Shared.ScriptBase.ScriptBaseClass: " + + String.Empty + "Public Class Script: Inherits " + baseClassName + "\r\nPublic Sub New()\r\nEnd Sub: " + compileScript + ":End Class :End Namespace\r\n"; + return compileScript; } @@ -547,6 +568,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools parameters.ReferencedAssemblies.Add(Path.Combine(rootPath, "OpenSim.Region.ScriptEngine.Shared.Api.Runtime.dll")); + if (m_scriptEngine.ScriptReferencedAssemblies != null) + Array.ForEach( + m_scriptEngine.ScriptReferencedAssemblies, + a => parameters.ReferencedAssemblies.Add(Path.Combine(rootPath, a))); + if (lang == enumCompileType.yp) { parameters.ReferencedAssemblies.Add(Path.Combine(rootPath, diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index 75aea2b0b1..e6ec0e1867 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs @@ -267,13 +267,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance try { if (dom != System.AppDomain.CurrentDomain) - m_Script = (IScript)dom.CreateInstanceAndUnwrap( + m_Script + = (IScript)dom.CreateInstanceAndUnwrap( Path.GetFileNameWithoutExtension(assembly), - "SecondLife.Script"); + "SecondLife.Script", + false, + BindingFlags.Default, + null, + new object[] { m_coopSleepHandle }, + null, + null, + null); else - m_Script = (IScript)Assembly.Load( - Path.GetFileNameWithoutExtension(assembly)).CreateInstance( - "SecondLife.Script"); + m_Script + = (IScript)Assembly.Load(Path.GetFileNameWithoutExtension(assembly)).CreateInstance( + "SecondLife.Script", + false, + BindingFlags.Default, + null, + new object[] { m_coopSleepHandle }, + null, + null); //ILease lease = (ILease)RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass); //RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass); diff --git a/OpenSim/Region/ScriptEngine/XEngine/Api/Runtime/XEngineScriptBase.cs b/OpenSim/Region/ScriptEngine/XEngine/Api/Runtime/XEngineScriptBase.cs new file mode 100644 index 0000000000..f4211c8286 --- /dev/null +++ b/OpenSim/Region/ScriptEngine/XEngine/Api/Runtime/XEngineScriptBase.cs @@ -0,0 +1,61 @@ +/* + * 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 OpenSimulator 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 System; +using System.Runtime.Remoting; +using System.Runtime.Remoting.Lifetime; +using System.Security.Permissions; +using System.Threading; +using System.Reflection; +using System.Collections; +using System.Collections.Generic; +using OpenSim.Region.ScriptEngine.Interfaces; +using OpenSim.Region.ScriptEngine.Shared; +using OpenSim.Region.ScriptEngine.Shared.ScriptBase; + +namespace OpenSim.Region.ScriptEngine.XEngine.ScriptBase +{ + public class XEngineScriptBase : ScriptBaseClass + { + /// + /// Used for script sleeps when we are using co-operative script termination. + /// + /// null if co-operative script termination is not active + WaitHandle m_coopSleepHandle; + + public XEngineScriptBase(WaitHandle coopSleepHandle) : base() + { + m_coopSleepHandle = coopSleepHandle; + } + + public void opensim_reserved_CheckForCoopTermination() + { + if (m_coopSleepHandle != null && m_coopSleepHandle.WaitOne(0)) + throw new ScriptCoopStopException(); + } + } +} \ No newline at end of file diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 82ddbec761..35825d48ed 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -53,6 +53,7 @@ using OpenSim.Region.ScriptEngine.Shared.Instance; using OpenSim.Region.ScriptEngine.Shared.Api; using OpenSim.Region.ScriptEngine.Shared.Api.Plugins; using OpenSim.Region.ScriptEngine.Interfaces; +using OpenSim.Region.ScriptEngine.XEngine.ScriptBase; using Timer = OpenSim.Region.ScriptEngine.Shared.Api.Plugins.Timer; using ScriptCompileQueue = OpenSim.Framework.LocklessQueue; @@ -176,6 +177,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine get { return "XEngine"; } } + public string ScriptBaseClassName { get; private set; } + + public ParameterInfo[] ScriptBaseClassParameters { get; private set; } + + public string[] ScriptReferencedAssemblies { get; private set; } + public Scene World { get { return m_Scene; } @@ -230,6 +237,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine m_ScriptConfig = configSource.Configs["XEngine"]; m_ConfigSource = configSource; + + ScriptBaseClassName = typeof(XEngineScriptBase).FullName; + ScriptBaseClassParameters = typeof(XEngineScriptBase).GetConstructor(new Type[] { typeof(WaitHandle) }).GetParameters(); + ScriptReferencedAssemblies = new string[] { Path.GetFileName(typeof(XEngineScriptBase).Assembly.Location) }; + + Console.WriteLine("ASSEMBLY NAME: {0}", ScriptReferencedAssemblies[0]); } public void AddRegion(Scene scene) @@ -1179,7 +1192,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine } catch (Exception e) { -// m_log.ErrorFormat("[XEngine]: Exception when rezzing script {0}{1}", e.Message, e.StackTrace); +// m_log.ErrorFormat( +// "[XEngine]: Exception when rezzing script with item ID {0}, {1}{2}", +// itemID, e.Message, e.StackTrace); // try // { diff --git a/prebuild.xml b/prebuild.xml index 529b494d96..935c857b82 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -2378,6 +2378,40 @@ + + + + ../../../../../../bin/ + + + + + ../../../../../../bin/ + + + + ../../../../../../bin/ + + + + + + + + + + + + + + + + + + + + + @@ -2408,6 +2442,7 @@ + @@ -2415,6 +2450,7 @@ +