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