aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/ScriptEngine/Interfaces/IScriptApi.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Interfaces/IScriptEngine.cs43
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs16
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs133
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs74
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs98
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs250
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/Api/Runtime/XEngineScriptBase.cs61
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/EventManager.cs4
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineBasicTests.cs (renamed from OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineTest.cs)0
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XEngine.cs48
-rw-r--r--bin/OpenSim.ini.example24
-rw-r--r--bin/OpenSimDefaults.ini20
-rw-r--r--prebuild.xml37
17 files changed, 672 insertions, 144 deletions
diff --git a/OpenSim/Region/ScriptEngine/Interfaces/IScriptApi.cs b/OpenSim/Region/ScriptEngine/Interfaces/IScriptApi.cs
index d2323f5..30e99b0 100644
--- a/OpenSim/Region/ScriptEngine/Interfaces/IScriptApi.cs
+++ b/OpenSim/Region/ScriptEngine/Interfaces/IScriptApi.cs
@@ -46,6 +46,6 @@ namespace OpenSim.Region.ScriptEngine.Interfaces
46 /// <param name='item'>/param> 46 /// <param name='item'>/param>
47 /// <param name='coopSleepHandle'>/param> 47 /// <param name='coopSleepHandle'>/param>
48 void Initialize( 48 void Initialize(
49 IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, EventWaitHandle coopSleepHandle); 49 IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, WaitHandle coopSleepHandle);
50 } 50 }
51} \ No newline at end of file 51} \ No newline at end of file
diff --git a/OpenSim/Region/ScriptEngine/Interfaces/IScriptEngine.cs b/OpenSim/Region/ScriptEngine/Interfaces/IScriptEngine.cs
index 17c2708..b8fdd01 100644
--- a/OpenSim/Region/ScriptEngine/Interfaces/IScriptEngine.cs
+++ b/OpenSim/Region/ScriptEngine/Interfaces/IScriptEngine.cs
@@ -25,16 +25,17 @@
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using log4net;
29using System; 28using System;
30using OpenSim.Region.ScriptEngine.Shared; 29using System.Reflection;
30using OpenSim.Framework;
31using OpenSim.Region.Framework.Scenes; 31using OpenSim.Region.Framework.Scenes;
32using OpenSim.Region.Framework.Interfaces; 32using OpenSim.Region.Framework.Interfaces;
33using OpenMetaverse;
34using Nini.Config;
35using OpenSim.Region.ScriptEngine.Interfaces; 33using OpenSim.Region.ScriptEngine.Interfaces;
34using OpenSim.Region.ScriptEngine.Shared;
36using Amib.Threading; 35using Amib.Threading;
37using OpenSim.Framework; 36using log4net;
37using Nini.Config;
38using OpenMetaverse;
38 39
39namespace OpenSim.Region.ScriptEngine.Interfaces 40namespace OpenSim.Region.ScriptEngine.Interfaces
40{ 41{
@@ -76,6 +77,38 @@ namespace OpenSim.Region.ScriptEngine.Interfaces
76 IConfigSource ConfigSource { get; } 77 IConfigSource ConfigSource { get; }
77 string ScriptEngineName { get; } 78 string ScriptEngineName { get; }
78 string ScriptEnginePath { get; } 79 string ScriptEnginePath { get; }
80
81 /// <summary>
82 /// Return the name of the class that will be used for all running scripts.
83 /// </summary>
84 /// <remarks>
85 /// Each class goes in its own assembly so we don't need to otherwise distinguish the class name.
86 /// </remarks>
87 string ScriptClassName { get; }
88
89 /// <summary>
90 /// Return the name of the base class that will be used for all running scripts.
91 /// </summary>
92 string ScriptBaseClassName { get; }
93
94 /// <summary>
95 /// Assemblies that need to be referenced when compiling scripts.
96 /// </summary>
97 /// <remarks>
98 /// These are currently additional to those always referenced by the compiler, BUT THIS MAY CHANGE IN THE
99 /// FUTURE.
100 /// This can be null if there are no additional assemblies.
101 /// </remarks>
102 string[] ScriptReferencedAssemblies { get; }
103
104 /// <summary>
105 /// Parameters for the generated script's constructor.
106 /// </summary>
107 /// <remarks>
108 /// Can be null if there are no parameters
109 /// </remarks>
110 ParameterInfo[] ScriptBaseClassParameters { get; }
111
79 IScriptApi GetApi(UUID itemID, string name); 112 IScriptApi GetApi(UUID itemID, string name);
80 } 113 }
81} 114}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 3a7e1c7..63f4800 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -91,7 +91,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
91 /// Used for script sleeps when we are using co-operative script termination. 91 /// Used for script sleeps when we are using co-operative script termination.
92 /// </summary> 92 /// </summary>
93 /// <remarks>null if co-operative script termination is not active</remarks> 93 /// <remarks>null if co-operative script termination is not active</remarks>
94 EventWaitHandle m_coopSleepHandle; 94 WaitHandle m_coopSleepHandle;
95 95
96 /// <summary> 96 /// <summary>
97 /// The item that hosts this script 97 /// The item that hosts this script
@@ -118,7 +118,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
118 protected ISoundModule m_SoundModule = null; 118 protected ISoundModule m_SoundModule = null;
119 119
120 public void Initialize( 120 public void Initialize(
121 IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, EventWaitHandle coopSleepHandle) 121 IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, WaitHandle coopSleepHandle)
122 { 122 {
123 m_ScriptEngine = scriptEngine; 123 m_ScriptEngine = scriptEngine;
124 m_host = host; 124 m_host = host;
@@ -192,7 +192,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
192 { 192 {
193 if (m_coopSleepHandle == null) 193 if (m_coopSleepHandle == null)
194 System.Threading.Thread.Sleep(delay); 194 System.Threading.Thread.Sleep(delay);
195 else if (m_coopSleepHandle.WaitOne(delay)) 195 else
196 CheckForCoopTermination(delay);
197 }
198
199 /// <summary>
200 /// Check for co-operative termination.
201 /// </summary>
202 /// <param name='delay'>If called with 0, then just the check is performed with no wait.</param>
203 protected virtual void CheckForCoopTermination(int delay)
204 {
205 if (m_coopSleepHandle.WaitOne(delay))
196 throw new ScriptCoopStopException(); 206 throw new ScriptCoopStopException();
197 } 207 }
198 208
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs
index a08ccc8..1d6cb6d 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs
@@ -63,7 +63,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
63 internal IScriptModuleComms m_comms = null; 63 internal IScriptModuleComms m_comms = null;
64 64
65 public void Initialize( 65 public void Initialize(
66 IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, EventWaitHandle coopSleepHandle) 66 IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, WaitHandle coopSleepHandle)
67 { 67 {
68 m_ScriptEngine = scriptEngine; 68 m_ScriptEngine = scriptEngine;
69 m_host = host; 69 m_host = host;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs
index 981499e..9045672 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs
@@ -63,7 +63,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
63 internal IScriptModuleComms m_comms = null; 63 internal IScriptModuleComms m_comms = null;
64 64
65 public void Initialize( 65 public void Initialize(
66 IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, EventWaitHandle coopSleepHandle) 66 IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, WaitHandle coopSleepHandle)
67 { 67 {
68 m_ScriptEngine = scriptEngine; 68 m_ScriptEngine = scriptEngine;
69 m_host = host; 69 m_host = host;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 5c0ff1c..1426070 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -143,7 +143,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
143 protected IUrlModule m_UrlModule = null; 143 protected IUrlModule m_UrlModule = null;
144 144
145 public void Initialize( 145 public void Initialize(
146 IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, EventWaitHandle coopSleepHandle) 146 IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, WaitHandle coopSleepHandle)
147 { 147 {
148 m_ScriptEngine = scriptEngine; 148 m_ScriptEngine = scriptEngine;
149 m_host = host; 149 m_host = host;
diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs
index 97dd0f6..985e598 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
49 private List<string> m_warnings = new List<string>(); 49 private List<string> m_warnings = new List<string>();
50 private IScriptModuleComms m_comms = null; 50 private IScriptModuleComms m_comms = null;
51 51
52 private bool m_insertCoopTerminationChecks;
53 private static string m_coopTerminationCheck = "opensim_reserved_CheckForCoopTermination();";
54
55 /// <summary>
56 /// Keep a record of the previous node when we do the parsing.
57 /// </summary>
58 /// <remarks>
59 /// We do this here because the parser generated by CSTools does not retain a reference to its parent node.
60 /// The previous node is required so we can correctly insert co-op termination checks when required.
61 /// </remarks>
62// private SYMBOL m_previousNode;
63
52 /// <summary> 64 /// <summary>
53 /// Creates an 'empty' CSCodeGenerator instance. 65 /// Creates an 'empty' CSCodeGenerator instance.
54 /// </summary> 66 /// </summary>
@@ -58,9 +70,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
58 ResetCounters(); 70 ResetCounters();
59 } 71 }
60 72
61 public CSCodeGenerator(IScriptModuleComms comms) 73 public CSCodeGenerator(IScriptModuleComms comms, bool insertCoopTerminationChecks)
62 { 74 {
63 m_comms = comms; 75 m_comms = comms;
76 m_insertCoopTerminationChecks = insertCoopTerminationChecks;
64 ResetCounters(); 77 ResetCounters();
65 } 78 }
66 79
@@ -155,7 +168,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
155 // here's the payload 168 // here's the payload
156 retstr += GenerateLine(); 169 retstr += GenerateLine();
157 foreach (SYMBOL s in m_astRoot.kids) 170 foreach (SYMBOL s in m_astRoot.kids)
158 retstr += GenerateNode(s); 171 retstr += GenerateNode(m_astRoot, s);
159 172
160 // close braces! 173 // close braces!
161 m_braceCount--; 174 m_braceCount--;
@@ -165,7 +178,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
165 178
166 // Removes all carriage return characters which may be generated in Windows platform. Is there 179 // Removes all carriage return characters which may be generated in Windows platform. Is there
167 // cleaner way of doing this? 180 // cleaner way of doing this?
168 retstr=retstr.Replace("\r", ""); 181 retstr = retstr.Replace("\r", "");
169 182
170 return retstr; 183 return retstr;
171 } 184 }
@@ -191,9 +204,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
191 /// Recursively called to generate each type of node. Will generate this 204 /// Recursively called to generate each type of node. Will generate this
192 /// node, then all it's children. 205 /// node, then all it's children.
193 /// </summary> 206 /// </summary>
207 /// <param name="previousSymbol">The parent node.</param>
194 /// <param name="s">The current node to generate code for.</param> 208 /// <param name="s">The current node to generate code for.</param>
195 /// <returns>String containing C# code for SYMBOL s.</returns> 209 /// <returns>String containing C# code for SYMBOL s.</returns>
196 private string GenerateNode(SYMBOL s) 210 private string GenerateNode(SYMBOL previousSymbol, SYMBOL s)
197 { 211 {
198 string retstr = String.Empty; 212 string retstr = String.Empty;
199 213
@@ -207,11 +221,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
207 else if (s is State) 221 else if (s is State)
208 retstr += GenerateState((State) s); 222 retstr += GenerateState((State) s);
209 else if (s is CompoundStatement) 223 else if (s is CompoundStatement)
210 retstr += GenerateCompoundStatement((CompoundStatement) s); 224 retstr += GenerateCompoundStatement(previousSymbol, (CompoundStatement) s);
211 else if (s is Declaration) 225 else if (s is Declaration)
212 retstr += GenerateDeclaration((Declaration) s); 226 retstr += GenerateDeclaration((Declaration) s);
213 else if (s is Statement) 227 else if (s is Statement)
214 retstr += GenerateStatement((Statement) s); 228 retstr += GenerateStatement(previousSymbol, (Statement) s);
215 else if (s is ReturnStatement) 229 else if (s is ReturnStatement)
216 retstr += GenerateReturnStatement((ReturnStatement) s); 230 retstr += GenerateReturnStatement((ReturnStatement) s);
217 else if (s is JumpLabel) 231 else if (s is JumpLabel)
@@ -261,7 +275,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
261 else 275 else
262 { 276 {
263 foreach (SYMBOL kid in s.kids) 277 foreach (SYMBOL kid in s.kids)
264 retstr += GenerateNode(kid); 278 retstr += GenerateNode(s, kid);
265 } 279 }
266 280
267 return retstr; 281 return retstr;
@@ -295,7 +309,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
295 retstr += GenerateLine(")"); 309 retstr += GenerateLine(")");
296 310
297 foreach (SYMBOL kid in remainingKids) 311 foreach (SYMBOL kid in remainingKids)
298 retstr += GenerateNode(kid); 312 retstr += GenerateNode(gf, kid);
299 313
300 return retstr; 314 return retstr;
301 } 315 }
@@ -312,7 +326,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
312 foreach (SYMBOL s in gv.kids) 326 foreach (SYMBOL s in gv.kids)
313 { 327 {
314 retstr += Indent(); 328 retstr += Indent();
315 retstr += GenerateNode(s); 329 retstr += GenerateNode(gv, s);
316 retstr += GenerateLine(";"); 330 retstr += GenerateLine(";");
317 } 331 }
318 332
@@ -365,7 +379,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
365 retstr += GenerateLine(")"); 379 retstr += GenerateLine(")");
366 380
367 foreach (SYMBOL kid in remainingKids) 381 foreach (SYMBOL kid in remainingKids)
368 retstr += GenerateNode(kid); 382 retstr += GenerateNode(se, kid);
369 383
370 return retstr; 384 return retstr;
371 } 385 }
@@ -404,7 +418,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
404 418
405 foreach (SYMBOL s in al.kids) 419 foreach (SYMBOL s in al.kids)
406 { 420 {
407 retstr += GenerateNode(s); 421 retstr += GenerateNode(al, s);
408 if (0 < comma--) 422 if (0 < comma--)
409 retstr += Generate(", "); 423 retstr += Generate(", ");
410 } 424 }
@@ -417,7 +431,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
417 /// </summary> 431 /// </summary>
418 /// <param name="cs">The CompoundStatement node.</param> 432 /// <param name="cs">The CompoundStatement node.</param>
419 /// <returns>String containing C# code for CompoundStatement cs.</returns> 433 /// <returns>String containing C# code for CompoundStatement cs.</returns>
420 private string GenerateCompoundStatement(CompoundStatement cs) 434 private string GenerateCompoundStatement(SYMBOL previousSymbol, CompoundStatement cs)
421 { 435 {
422 string retstr = String.Empty; 436 string retstr = String.Empty;
423 437
@@ -425,8 +439,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
425 retstr += GenerateIndentedLine("{"); 439 retstr += GenerateIndentedLine("{");
426 m_braceCount++; 440 m_braceCount++;
427 441
442 if (m_insertCoopTerminationChecks)
443 {
444 // We have to check in event functions as well because the user can manually call these.
445 if (previousSymbol is GlobalFunctionDefinition
446 || previousSymbol is WhileStatement
447 || previousSymbol is DoWhileStatement
448 || previousSymbol is ForLoop
449 || previousSymbol is StateEvent)
450 retstr += GenerateIndentedLine(m_coopTerminationCheck);
451 }
452
428 foreach (SYMBOL kid in cs.kids) 453 foreach (SYMBOL kid in cs.kids)
429 retstr += GenerateNode(kid); 454 retstr += GenerateNode(cs, kid);
430 455
431 // closing brace 456 // closing brace
432 m_braceCount--; 457 m_braceCount--;
@@ -450,13 +475,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
450 /// </summary> 475 /// </summary>
451 /// <param name="s">The Statement node.</param> 476 /// <param name="s">The Statement node.</param>
452 /// <returns>String containing C# code for Statement s.</returns> 477 /// <returns>String containing C# code for Statement s.</returns>
453 private string GenerateStatement(Statement s) 478 private string GenerateStatement(SYMBOL previousSymbol, Statement s)
454 { 479 {
455 string retstr = String.Empty; 480 string retstr = String.Empty;
456 bool printSemicolon = true; 481 bool printSemicolon = true;
457 482
458 retstr += Indent(); 483 retstr += Indent();
459 484
485 if (m_insertCoopTerminationChecks)
486 {
487 // We have to check in event functions as well because the user can manually call these.
488 if (previousSymbol is GlobalFunctionDefinition
489 || previousSymbol is WhileStatement
490 || previousSymbol is DoWhileStatement
491 || previousSymbol is ForLoop
492 || previousSymbol is StateEvent)
493 retstr += Generate(m_coopTerminationCheck);
494 }
495
460 if (0 < s.kids.Count) 496 if (0 < s.kids.Count)
461 { 497 {
462 // Jump label prints its own colon, we don't need a semicolon. 498 // Jump label prints its own colon, we don't need a semicolon.
@@ -466,7 +502,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
466 // (MONO) error. 502 // (MONO) error.
467 if (!(s.kids.Top is IdentExpression && 1 == s.kids.Count)) 503 if (!(s.kids.Top is IdentExpression && 1 == s.kids.Count))
468 foreach (SYMBOL kid in s.kids) 504 foreach (SYMBOL kid in s.kids)
469 retstr += GenerateNode(kid); 505 retstr += GenerateNode(s, kid);
470 } 506 }
471 507
472 if (printSemicolon) 508 if (printSemicolon)
@@ -487,10 +523,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
487 List<string> identifiers = new List<string>(); 523 List<string> identifiers = new List<string>();
488 checkForMultipleAssignments(identifiers, a); 524 checkForMultipleAssignments(identifiers, a);
489 525
490 retstr += GenerateNode((SYMBOL) a.kids.Pop()); 526 retstr += GenerateNode(a, (SYMBOL) a.kids.Pop());
491 retstr += Generate(String.Format(" {0} ", a.AssignmentType), a); 527 retstr += Generate(String.Format(" {0} ", a.AssignmentType), a);
492 foreach (SYMBOL kid in a.kids) 528 foreach (SYMBOL kid in a.kids)
493 retstr += GenerateNode(kid); 529 retstr += GenerateNode(a, kid);
494 530
495 return retstr; 531 return retstr;
496 } 532 }
@@ -563,7 +599,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
563 retstr += Generate("return ", rs); 599 retstr += Generate("return ", rs);
564 600
565 foreach (SYMBOL kid in rs.kids) 601 foreach (SYMBOL kid in rs.kids)
566 retstr += GenerateNode(kid); 602 retstr += GenerateNode(rs, kid);
567 603
568 return retstr; 604 return retstr;
569 } 605 }
@@ -575,7 +611,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
575 /// <returns>String containing C# code for JumpLabel jl.</returns> 611 /// <returns>String containing C# code for JumpLabel jl.</returns>
576 private string GenerateJumpLabel(JumpLabel jl) 612 private string GenerateJumpLabel(JumpLabel jl)
577 { 613 {
578 return Generate(String.Format("{0}:", CheckName(jl.LabelName)), jl) + " NoOp();\n"; 614 string labelStatement;
615
616 if (m_insertCoopTerminationChecks)
617 labelStatement = m_coopTerminationCheck + "\n";
618 else
619 labelStatement = "NoOp();\n";
620
621 return Generate(String.Format("{0}: ", CheckName(jl.LabelName)), jl) + labelStatement;
579 } 622 }
580 623
581 /// <summary> 624 /// <summary>
@@ -598,14 +641,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
598 string retstr = String.Empty; 641 string retstr = String.Empty;
599 642
600 retstr += GenerateIndented("if (", ifs); 643 retstr += GenerateIndented("if (", ifs);
601 retstr += GenerateNode((SYMBOL) ifs.kids.Pop()); 644 retstr += GenerateNode(ifs, (SYMBOL) ifs.kids.Pop());
602 retstr += GenerateLine(")"); 645 retstr += GenerateLine(")");
603 646
604 // CompoundStatement handles indentation itself but we need to do it 647 // CompoundStatement handles indentation itself but we need to do it
605 // otherwise. 648 // otherwise.
606 bool indentHere = ifs.kids.Top is Statement; 649 bool indentHere = ifs.kids.Top is Statement;
607 if (indentHere) m_braceCount++; 650 if (indentHere) m_braceCount++;
608 retstr += GenerateNode((SYMBOL) ifs.kids.Pop()); 651 retstr += GenerateNode(ifs, (SYMBOL) ifs.kids.Pop());
609 if (indentHere) m_braceCount--; 652 if (indentHere) m_braceCount--;
610 653
611 if (0 < ifs.kids.Count) // do it again for an else 654 if (0 < ifs.kids.Count) // do it again for an else
@@ -614,7 +657,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
614 657
615 indentHere = ifs.kids.Top is Statement; 658 indentHere = ifs.kids.Top is Statement;
616 if (indentHere) m_braceCount++; 659 if (indentHere) m_braceCount++;
617 retstr += GenerateNode((SYMBOL) ifs.kids.Pop()); 660 retstr += GenerateNode(ifs, (SYMBOL) ifs.kids.Pop());
618 if (indentHere) m_braceCount--; 661 if (indentHere) m_braceCount--;
619 } 662 }
620 663
@@ -641,14 +684,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
641 string retstr = String.Empty; 684 string retstr = String.Empty;
642 685
643 retstr += GenerateIndented("while (", ws); 686 retstr += GenerateIndented("while (", ws);
644 retstr += GenerateNode((SYMBOL) ws.kids.Pop()); 687 retstr += GenerateNode(ws, (SYMBOL) ws.kids.Pop());
645 retstr += GenerateLine(")"); 688 retstr += GenerateLine(")");
646 689
647 // CompoundStatement handles indentation itself but we need to do it 690 // CompoundStatement handles indentation itself but we need to do it
648 // otherwise. 691 // otherwise.
649 bool indentHere = ws.kids.Top is Statement; 692 bool indentHere = ws.kids.Top is Statement;
650 if (indentHere) m_braceCount++; 693 if (indentHere) m_braceCount++;
651 retstr += GenerateNode((SYMBOL) ws.kids.Pop()); 694 retstr += GenerateNode(ws, (SYMBOL) ws.kids.Pop());
652 if (indentHere) m_braceCount--; 695 if (indentHere) m_braceCount--;
653 696
654 return retstr; 697 return retstr;
@@ -669,11 +712,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
669 // otherwise. 712 // otherwise.
670 bool indentHere = dws.kids.Top is Statement; 713 bool indentHere = dws.kids.Top is Statement;
671 if (indentHere) m_braceCount++; 714 if (indentHere) m_braceCount++;
672 retstr += GenerateNode((SYMBOL) dws.kids.Pop()); 715 retstr += GenerateNode(dws, (SYMBOL) dws.kids.Pop());
673 if (indentHere) m_braceCount--; 716 if (indentHere) m_braceCount--;
674 717
675 retstr += GenerateIndented("while (", dws); 718 retstr += GenerateIndented("while (", dws);
676 retstr += GenerateNode((SYMBOL) dws.kids.Pop()); 719 retstr += GenerateNode(dws, (SYMBOL) dws.kids.Pop());
677 retstr += GenerateLine(");"); 720 retstr += GenerateLine(");");
678 721
679 return retstr; 722 return retstr;
@@ -702,7 +745,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
702 retstr += Generate("; "); 745 retstr += Generate("; ");
703 // for (x = 0; x < 10; x++) 746 // for (x = 0; x < 10; x++)
704 // ^^^^^^ 747 // ^^^^^^
705 retstr += GenerateNode((SYMBOL) fl.kids.Pop()); 748 retstr += GenerateNode(fl, (SYMBOL) fl.kids.Pop());
706 retstr += Generate("; "); 749 retstr += Generate("; ");
707 // for (x = 0; x < 10; x++) 750 // for (x = 0; x < 10; x++)
708 // ^^^ 751 // ^^^
@@ -713,7 +756,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
713 // otherwise. 756 // otherwise.
714 bool indentHere = fl.kids.Top is Statement; 757 bool indentHere = fl.kids.Top is Statement;
715 if (indentHere) m_braceCount++; 758 if (indentHere) m_braceCount++;
716 retstr += GenerateNode((SYMBOL) fl.kids.Pop()); 759 retstr += GenerateNode(fl, (SYMBOL) fl.kids.Pop());
717 if (indentHere) m_braceCount--; 760 if (indentHere) m_braceCount--;
718 761
719 return retstr; 762 return retstr;
@@ -758,7 +801,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
758 while (s is ParenthesisExpression) 801 while (s is ParenthesisExpression)
759 s = (SYMBOL)s.kids.Pop(); 802 s = (SYMBOL)s.kids.Pop();
760 803
761 retstr += GenerateNode(s); 804 retstr += GenerateNode(fls, s);
762 if (0 < comma--) 805 if (0 < comma--)
763 retstr += Generate(", "); 806 retstr += Generate(", ");
764 } 807 }
@@ -779,20 +822,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
779 { 822 {
780 // special case handling for logical and/or, see Mantis 3174 823 // special case handling for logical and/or, see Mantis 3174
781 retstr += "((bool)("; 824 retstr += "((bool)(";
782 retstr += GenerateNode((SYMBOL)be.kids.Pop()); 825 retstr += GenerateNode(be, (SYMBOL)be.kids.Pop());
783 retstr += "))"; 826 retstr += "))";
784 retstr += Generate(String.Format(" {0} ", be.ExpressionSymbol.Substring(0,1)), be); 827 retstr += Generate(String.Format(" {0} ", be.ExpressionSymbol.Substring(0,1)), be);
785 retstr += "((bool)("; 828 retstr += "((bool)(";
786 foreach (SYMBOL kid in be.kids) 829 foreach (SYMBOL kid in be.kids)
787 retstr += GenerateNode(kid); 830 retstr += GenerateNode(be, kid);
788 retstr += "))"; 831 retstr += "))";
789 } 832 }
790 else 833 else
791 { 834 {
792 retstr += GenerateNode((SYMBOL)be.kids.Pop()); 835 retstr += GenerateNode(be, (SYMBOL)be.kids.Pop());
793 retstr += Generate(String.Format(" {0} ", be.ExpressionSymbol), be); 836 retstr += Generate(String.Format(" {0} ", be.ExpressionSymbol), be);
794 foreach (SYMBOL kid in be.kids) 837 foreach (SYMBOL kid in be.kids)
795 retstr += GenerateNode(kid); 838 retstr += GenerateNode(be, kid);
796 } 839 }
797 840
798 return retstr; 841 return retstr;
@@ -808,7 +851,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
808 string retstr = String.Empty; 851 string retstr = String.Empty;
809 852
810 retstr += Generate(ue.UnarySymbol, ue); 853 retstr += Generate(ue.UnarySymbol, ue);
811 retstr += GenerateNode((SYMBOL) ue.kids.Pop()); 854 retstr += GenerateNode(ue, (SYMBOL) ue.kids.Pop());
812 855
813 return retstr; 856 return retstr;
814 } 857 }
@@ -824,7 +867,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
824 867
825 retstr += Generate("("); 868 retstr += Generate("(");
826 foreach (SYMBOL kid in pe.kids) 869 foreach (SYMBOL kid in pe.kids)
827 retstr += GenerateNode(kid); 870 retstr += GenerateNode(pe, kid);
828 retstr += Generate(")"); 871 retstr += Generate(")");
829 872
830 return retstr; 873 return retstr;
@@ -861,7 +904,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
861 904
862 // we wrap all typecasted statements in parentheses 905 // we wrap all typecasted statements in parentheses
863 retstr += Generate(String.Format("({0}) (", te.TypecastType), te); 906 retstr += Generate(String.Format("({0}) (", te.TypecastType), te);
864 retstr += GenerateNode((SYMBOL) te.kids.Pop()); 907 retstr += GenerateNode(te, (SYMBOL) te.kids.Pop());
865 retstr += Generate(")"); 908 retstr += Generate(")");
866 909
867 return retstr; 910 return retstr;
@@ -931,7 +974,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
931 } 974 }
932 975
933 foreach (SYMBOL kid in fc.kids) 976 foreach (SYMBOL kid in fc.kids)
934 retstr += GenerateNode(kid); 977 retstr += GenerateNode(fc, kid);
935 978
936 retstr += Generate(")"); 979 retstr += Generate(")");
937 980
@@ -980,11 +1023,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
980 string retstr = String.Empty; 1023 string retstr = String.Empty;
981 1024
982 retstr += Generate(String.Format("new {0}(", vc.Type), vc); 1025 retstr += Generate(String.Format("new {0}(", vc.Type), vc);
983 retstr += GenerateNode((SYMBOL) vc.kids.Pop()); 1026 retstr += GenerateNode(vc, (SYMBOL) vc.kids.Pop());
984 retstr += Generate(", "); 1027 retstr += Generate(", ");
985 retstr += GenerateNode((SYMBOL) vc.kids.Pop()); 1028 retstr += GenerateNode(vc, (SYMBOL) vc.kids.Pop());
986 retstr += Generate(", "); 1029 retstr += Generate(", ");
987 retstr += GenerateNode((SYMBOL) vc.kids.Pop()); 1030 retstr += GenerateNode(vc, (SYMBOL) vc.kids.Pop());
988 retstr += Generate(")"); 1031 retstr += Generate(")");
989 1032
990 return retstr; 1033 return retstr;
@@ -1000,13 +1043,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
1000 string retstr = String.Empty; 1043 string retstr = String.Empty;
1001 1044
1002 retstr += Generate(String.Format("new {0}(", rc.Type), rc); 1045 retstr += Generate(String.Format("new {0}(", rc.Type), rc);
1003 retstr += GenerateNode((SYMBOL) rc.kids.Pop()); 1046 retstr += GenerateNode(rc, (SYMBOL) rc.kids.Pop());
1004 retstr += Generate(", "); 1047 retstr += Generate(", ");
1005 retstr += GenerateNode((SYMBOL) rc.kids.Pop()); 1048 retstr += GenerateNode(rc, (SYMBOL) rc.kids.Pop());
1006 retstr += Generate(", "); 1049 retstr += Generate(", ");
1007 retstr += GenerateNode((SYMBOL) rc.kids.Pop()); 1050 retstr += GenerateNode(rc, (SYMBOL) rc.kids.Pop());
1008 retstr += Generate(", "); 1051 retstr += Generate(", ");
1009 retstr += GenerateNode((SYMBOL) rc.kids.Pop()); 1052 retstr += GenerateNode(rc, (SYMBOL) rc.kids.Pop());
1010 retstr += Generate(")"); 1053 retstr += Generate(")");
1011 1054
1012 return retstr; 1055 return retstr;
@@ -1024,7 +1067,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
1024 retstr += Generate(String.Format("new {0}(", lc.Type), lc); 1067 retstr += Generate(String.Format("new {0}(", lc.Type), lc);
1025 1068
1026 foreach (SYMBOL kid in lc.kids) 1069 foreach (SYMBOL kid in lc.kids)
1027 retstr += GenerateNode(kid); 1070 retstr += GenerateNode(lc, kid);
1028 1071
1029 retstr += Generate(")"); 1072 retstr += Generate(")");
1030 1073
diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs
index 03be2ab..002e852 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;
31using System.Globalization; 31using System.Globalization;
32using System.Reflection; 32using System.Reflection;
33using System.IO; 33using System.IO;
34using System.Linq;
34using System.Text; 35using System.Text;
35using Microsoft.CSharp; 36using Microsoft.CSharp;
36//using Microsoft.JScript; 37//using Microsoft.JScript;
@@ -72,6 +73,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
72 private bool CompileWithDebugInformation; 73 private bool CompileWithDebugInformation;
73 private Dictionary<string, bool> AllowedCompilers = new Dictionary<string, bool>(StringComparer.CurrentCultureIgnoreCase); 74 private Dictionary<string, bool> AllowedCompilers = new Dictionary<string, bool>(StringComparer.CurrentCultureIgnoreCase);
74 private Dictionary<string, enumCompileType> LanguageMapping = new Dictionary<string, enumCompileType>(StringComparer.CurrentCultureIgnoreCase); 75 private Dictionary<string, enumCompileType> LanguageMapping = new Dictionary<string, enumCompileType>(StringComparer.CurrentCultureIgnoreCase);
76 private bool m_insertCoopTerminationCalls;
75 77
76 private string FilePrefix; 78 private string FilePrefix;
77 private string ScriptEnginesPath = null; 79 private string ScriptEnginesPath = null;
@@ -95,20 +97,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
95 private Dictionary<string, Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>>> m_lineMaps = 97 private Dictionary<string, Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>>> m_lineMaps =
96 new Dictionary<string, Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>>>(); 98 new Dictionary<string, Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>>>();
97 99
100 public bool in_startup = true;
101
98 public Compiler(IScriptEngine scriptEngine) 102 public Compiler(IScriptEngine scriptEngine)
99 { 103 {
100 m_scriptEngine = scriptEngine;; 104 m_scriptEngine = scriptEngine;
101 ScriptEnginesPath = scriptEngine.ScriptEnginePath; 105 ScriptEnginesPath = scriptEngine.ScriptEnginePath;
102 ReadConfig(); 106 ReadConfig();
103 } 107 }
104 108
105 public bool in_startup = true;
106 public void ReadConfig() 109 public void ReadConfig()
107 { 110 {
108 // Get some config 111 // Get some config
109 WriteScriptSourceToDebugFile = m_scriptEngine.Config.GetBoolean("WriteScriptSourceToDebugFile", false); 112 WriteScriptSourceToDebugFile = m_scriptEngine.Config.GetBoolean("WriteScriptSourceToDebugFile", false);
110 CompileWithDebugInformation = m_scriptEngine.Config.GetBoolean("CompileWithDebugInformation", true); 113 CompileWithDebugInformation = m_scriptEngine.Config.GetBoolean("CompileWithDebugInformation", true);
111 bool DeleteScriptsOnStartup = m_scriptEngine.Config.GetBoolean("DeleteScriptsOnStartup", true); 114 bool DeleteScriptsOnStartup = m_scriptEngine.Config.GetBoolean("DeleteScriptsOnStartup", true);
115 m_insertCoopTerminationCalls = m_scriptEngine.Config.GetString("ScriptStopStrategy", "abort") == "co-op";
112 116
113 // Get file prefix from scriptengine name and make it file system safe: 117 // Get file prefix from scriptengine name and make it file system safe:
114 FilePrefix = "CommonCompiler"; 118 FilePrefix = "CommonCompiler";
@@ -386,7 +390,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
386 if (language == enumCompileType.lsl) 390 if (language == enumCompileType.lsl)
387 { 391 {
388 // Its LSL, convert it to C# 392 // Its LSL, convert it to C#
389 LSL_Converter = (ICodeConverter)new CSCodeGenerator(comms); 393 LSL_Converter = (ICodeConverter)new CSCodeGenerator(comms, m_insertCoopTerminationCalls);
390 compileScript = LSL_Converter.Convert(Script); 394 compileScript = LSL_Converter.Convert(Script);
391 395
392 // copy converter warnings into our warnings. 396 // copy converter warnings into our warnings.
@@ -411,16 +415,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
411 { 415 {
412 case enumCompileType.cs: 416 case enumCompileType.cs:
413 case enumCompileType.lsl: 417 case enumCompileType.lsl:
414 compileScript = CreateCSCompilerScript(compileScript); 418 compileScript = CreateCSCompilerScript(
419 compileScript,
420 m_scriptEngine.ScriptClassName,
421 m_scriptEngine.ScriptBaseClassName,
422 m_scriptEngine.ScriptBaseClassParameters);
415 break; 423 break;
416 case enumCompileType.vb: 424 case enumCompileType.vb:
417 compileScript = CreateVBCompilerScript(compileScript); 425 compileScript = CreateVBCompilerScript(
426 compileScript, m_scriptEngine.ScriptClassName, m_scriptEngine.ScriptBaseClassName);
418 break; 427 break;
419// case enumCompileType.js: 428// case enumCompileType.js:
420// compileScript = CreateJSCompilerScript(compileScript); 429// compileScript = CreateJSCompilerScript(compileScript, m_scriptEngine.ScriptBaseClassName);
421// break; 430// break;
422 case enumCompileType.yp: 431 case enumCompileType.yp:
423 compileScript = CreateYPCompilerScript(compileScript); 432 compileScript = CreateYPCompilerScript(
433 compileScript, m_scriptEngine.ScriptClassName,m_scriptEngine.ScriptBaseClassName);
424 break; 434 break;
425 } 435 }
426 436
@@ -451,43 +461,60 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
451// return compileScript; 461// return compileScript;
452// } 462// }
453 463
454 private static string CreateCSCompilerScript(string compileScript) 464 private static string CreateCSCompilerScript(
465 string compileScript, string className, string baseClassName, ParameterInfo[] constructorParameters)
455 { 466 {
456 compileScript = String.Empty + 467 compileScript = string.Format(
457 "using OpenSim.Region.ScriptEngine.Shared; using System.Collections.Generic;\r\n" + 468@"using OpenSim.Region.ScriptEngine.Shared;
458 String.Empty + "namespace SecondLife { " + 469using System.Collections.Generic;
459 String.Empty + "public class Script : OpenSim.Region.ScriptEngine.Shared.ScriptBase.ScriptBaseClass { \r\n" + 470
460 @"public Script() { } " + 471namespace SecondLife
461 compileScript + 472{{
462 "} }\r\n"; 473 public class {0} : {1}
474 {{
475 public {0}({2}) : base({3}) {{}}
476{4}
477 }}
478}}",
479 className,
480 baseClassName,
481 constructorParameters != null
482 ? string.Join(", ", Array.ConvertAll<ParameterInfo, string>(constructorParameters, pi => pi.ToString()))
483 : "",
484 constructorParameters != null
485 ? string.Join(", ", Array.ConvertAll<ParameterInfo, string>(constructorParameters, pi => pi.Name))
486 : "",
487 compileScript);
488
463 return compileScript; 489 return compileScript;
464 } 490 }
465 491
466 private static string CreateYPCompilerScript(string compileScript) 492 private static string CreateYPCompilerScript(string compileScript, string className, string baseClassName)
467 { 493 {
468 compileScript = String.Empty + 494 compileScript = String.Empty +
469 "using OpenSim.Region.ScriptEngine.Shared.YieldProlog; " + 495 "using OpenSim.Region.ScriptEngine.Shared.YieldProlog; " +
470 "using OpenSim.Region.ScriptEngine.Shared; using System.Collections.Generic;\r\n" + 496 "using OpenSim.Region.ScriptEngine.Shared; using System.Collections.Generic;\r\n" +
471 String.Empty + "namespace SecondLife { " + 497 String.Empty + "namespace SecondLife { " +
472 String.Empty + "public class Script : OpenSim.Region.ScriptEngine.Shared.ScriptBase.ScriptBaseClass { \r\n" + 498 String.Empty + "public class " + className + " : " + baseClassName + " { \r\n" +
473 //@"public Script() { } " + 499 //@"public Script() { } " +
474 @"static OpenSim.Region.ScriptEngine.Shared.YieldProlog.YP YP=null; " + 500 @"static OpenSim.Region.ScriptEngine.Shared.YieldProlog.YP YP=null; " +
475 @"public Script() { YP= new OpenSim.Region.ScriptEngine.Shared.YieldProlog.YP(); } " + 501 @"public " + className + "() { YP= new OpenSim.Region.ScriptEngine.Shared.YieldProlog.YP(); } " +
476
477 compileScript + 502 compileScript +
478 "} }\r\n"; 503 "} }\r\n";
504
479 return compileScript; 505 return compileScript;
480 } 506 }
481 507
482 private static string CreateVBCompilerScript(string compileScript) 508 private static string CreateVBCompilerScript(string compileScript, string className, string baseClassName)
483 { 509 {
484 compileScript = String.Empty + 510 compileScript = String.Empty +
485 "Imports OpenSim.Region.ScriptEngine.Shared: Imports System.Collections.Generic: " + 511 "Imports OpenSim.Region.ScriptEngine.Shared: Imports System.Collections.Generic: " +
486 String.Empty + "NameSpace SecondLife:" + 512 String.Empty + "NameSpace SecondLife:" +
487 String.Empty + "Public Class Script: Inherits OpenSim.Region.ScriptEngine.Shared.ScriptBase.ScriptBaseClass: " + 513 String.Empty + "Public Class " + className + ": Inherits " + baseClassName +
488 "\r\nPublic Sub New()\r\nEnd Sub: " + 514 "\r\nPublic Sub New()\r\nEnd Sub: " +
489 compileScript + 515 compileScript +
490 ":End Class :End Namespace\r\n"; 516 ":End Class :End Namespace\r\n";
517
491 return compileScript; 518 return compileScript;
492 } 519 }
493 520
@@ -549,6 +576,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
549 parameters.ReferencedAssemblies.Add(Path.Combine(rootPath, 576 parameters.ReferencedAssemblies.Add(Path.Combine(rootPath,
550 "OpenMetaverseTypes.dll")); 577 "OpenMetaverseTypes.dll"));
551 578
579 if (m_scriptEngine.ScriptReferencedAssemblies != null)
580 Array.ForEach<string>(
581 m_scriptEngine.ScriptReferencedAssemblies,
582 a => parameters.ReferencedAssemblies.Add(Path.Combine(rootPath, a)));
583
552 if (lang == enumCompileType.yp) 584 if (lang == enumCompileType.yp)
553 { 585 {
554 parameters.ReferencedAssemblies.Add(Path.Combine(rootPath, 586 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 75aea2b..5bc585e 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
@@ -251,7 +251,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
251 /// <param name='dom'></param> 251 /// <param name='dom'></param>
252 /// <param name='assembly'></param> 252 /// <param name='assembly'></param>
253 /// <param name='stateSource'></param> 253 /// <param name='stateSource'></param>
254 public void Load(AppDomain dom, string assembly, StateSource stateSource) 254 /// <returns>false if load failed, true if suceeded</returns>
255 public bool Load(AppDomain dom, string assembly, StateSource stateSource)
255 { 256 {
256 m_Assembly = assembly; 257 m_Assembly = assembly;
257 m_stateSource = stateSource; 258 m_stateSource = stateSource;
@@ -266,14 +267,56 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
266 267
267 try 268 try
268 { 269 {
270 object[] constructorParams;
271
272 Assembly scriptAssembly = dom.Load(Path.GetFileNameWithoutExtension(assembly));
273 Type scriptType = scriptAssembly.GetType("SecondLife.XEngineScript");
274
275 if (scriptType != null)
276 {
277 constructorParams = new object[] { m_coopSleepHandle };
278 }
279 else if (!m_coopTermination)
280 {
281 scriptType = scriptAssembly.GetType("SecondLife.Script");
282 constructorParams = null;
283 }
284 else
285 {
286 m_log.ErrorFormat(
287 "[SCRIPT INSTANCE]: Not starting script {0} (id {1}) in part {2} (id {3}) in object {4} in {5}. You must remove all existing {6}* script DLL files before using enabling co-op termination"
288 + ", either by setting DeleteScriptsOnStartup = true in [XEngine] for one run"
289 + " or by deleting these files manually.",
290 ScriptTask.Name, ScriptTask.ItemID, Part.Name, Part.UUID, Part.ParentGroup.Name, Engine.World.Name, assembly);
291
292 return false;
293 }
294
295// m_log.DebugFormat(
296// "[SCRIPT INSTANCE]: Looking to load {0} from assembly {1} in {2}",
297// scriptType.FullName, Path.GetFileNameWithoutExtension(assembly), Engine.World.Name);
298
269 if (dom != System.AppDomain.CurrentDomain) 299 if (dom != System.AppDomain.CurrentDomain)
270 m_Script = (IScript)dom.CreateInstanceAndUnwrap( 300 m_Script
301 = (IScript)dom.CreateInstanceAndUnwrap(
271 Path.GetFileNameWithoutExtension(assembly), 302 Path.GetFileNameWithoutExtension(assembly),
272 "SecondLife.Script"); 303 scriptType.FullName,
304 false,
305 BindingFlags.Default,
306 null,
307 constructorParams,
308 null,
309 null);
273 else 310 else
274 m_Script = (IScript)Assembly.Load( 311 m_Script
275 Path.GetFileNameWithoutExtension(assembly)).CreateInstance( 312 = (IScript)scriptAssembly.CreateInstance(
276 "SecondLife.Script"); 313 scriptType.FullName,
314 false,
315 BindingFlags.Default,
316 null,
317 constructorParams,
318 null,
319 null);
277 320
278 //ILease lease = (ILease)RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass); 321 //ILease lease = (ILease)RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass);
279 //RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass); 322 //RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass);
@@ -282,8 +325,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
282 catch (Exception e) 325 catch (Exception e)
283 { 326 {
284 m_log.ErrorFormat( 327 m_log.ErrorFormat(
285 "[SCRIPT INSTANCE]: Error loading assembly {0}. Exception {1}{2}", 328 "[SCRIPT INSTANCE]: Not starting script {0} (id {1}) in part {2} (id {3}) in object {4} in {5}. Error loading assembly {6}. Exception {7}{8}",
286 assembly, e.Message, e.StackTrace); 329 ScriptTask.Name, ScriptTask.ItemID, Part.Name, Part.UUID, Part.ParentGroup.Name, Engine.World.Name, assembly, e.Message, e.StackTrace);
330
331 return false;
287 } 332 }
288 333
289 try 334 try
@@ -301,10 +346,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
301 catch (Exception e) 346 catch (Exception e)
302 { 347 {
303 m_log.ErrorFormat( 348 m_log.ErrorFormat(
304 "[SCRIPT INSTANCE]: Error loading script instance from assembly {0}. Exception {1}{2}", 349 "[SCRIPT INSTANCE]: Not starting script {0} (id {1}) in part {2} (id {3}) in object {4} in {5}. Error initializing script instance. Exception {6}{7}",
305 assembly, e.Message, e.StackTrace); 350 ScriptTask.Name, ScriptTask.ItemID, Part.Name, Part.UUID, Part.ParentGroup.Name, Engine.World.Name, e.Message, e.StackTrace);
306 351
307 return; 352 return false;
308 } 353 }
309 354
310 m_SaveState = true; 355 m_SaveState = true;
@@ -357,15 +402,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
357 else 402 else
358 { 403 {
359 m_log.WarnFormat( 404 m_log.WarnFormat(
360 "[SCRIPT INSTANCE]: Unable to load script state file {0} for script {1} {2} in {3} {4} (assembly {5}). Memory limit exceeded", 405 "[SCRIPT INSTANCE]: Not starting script {0} (id {1}) in part {2} (id {3}) in object {4} in {5}. Unable to load script state file {6}. Memory limit exceeded.",
361 savedState, ScriptName, ItemID, PrimName, ObjectID, assembly); 406 ScriptTask.Name, ScriptTask.ItemID, Part.Name, Part.UUID, Part.ParentGroup.Name, Engine.World.Name, savedState);
362 } 407 }
363 } 408 }
364 catch (Exception e) 409 catch (Exception e)
365 { 410 {
366 m_log.ErrorFormat( 411 m_log.ErrorFormat(
367 "[SCRIPT INSTANCE]: Unable to load script state file {0} for script {1} {2} in {3} {4} (assembly {5}). XML is {6}. Exception {7}{8}", 412 "[SCRIPT INSTANCE]: Not starting script {0} (id {1}) in part {2} (id {3}) in object {4} in {5}. Unable to load script state file {6}. XML is {7}. Exception {8}{9}",
368 savedState, ScriptName, ItemID, PrimName, ObjectID, assembly, xml, e.Message, e.StackTrace); 413 ScriptTask.Name, ScriptTask.ItemID, Part.Name, Part.UUID, Part.ParentGroup.Name, Engine.World.Name, savedState, xml, e.Message, e.StackTrace);
369 } 414 }
370 } 415 }
371// else 416// else
@@ -376,6 +421,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
376// presence.ControllingClient.SendAgentAlertMessage("Compile successful", false); 421// presence.ControllingClient.SendAgentAlertMessage("Compile successful", false);
377 422
378// } 423// }
424
425 return true;
379 } 426 }
380 427
381 public void Init() 428 public void Init()
@@ -552,9 +599,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
552 } 599 }
553 else 600 else
554 { 601 {
555 m_log.DebugFormat( 602 if (DebugLevel >= 1)
556 "[SCRIPT INSTANCE]: Co-operatively stopping script {0} {1} in {2} {3}", 603 m_log.DebugFormat(
557 ScriptName, ItemID, PrimName, ObjectID); 604 "[SCRIPT INSTANCE]: Co-operatively stopping script {0} {1} in {2} {3}",
605 ScriptName, ItemID, PrimName, ObjectID);
558 606
559 // This will terminate the event on next handle check by the script. 607 // This will terminate the event on next handle check by the script.
560 m_coopSleepHandle.Set(); 608 m_coopSleepHandle.Set();
@@ -563,9 +611,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
563 // checking is implemented. May want to allow a shorter timeout option later. 611 // checking is implemented. May want to allow a shorter timeout option later.
564 if (workItem.Wait(TimeSpan.MaxValue)) 612 if (workItem.Wait(TimeSpan.MaxValue))
565 { 613 {
566 m_log.DebugFormat( 614 if (DebugLevel >= 1)
567 "[SCRIPT INSTANCE]: Co-operatively stopped script {0} {1} in {2} {3}", 615 m_log.DebugFormat(
568 ScriptName, ItemID, PrimName, ObjectID); 616 "[SCRIPT INSTANCE]: Co-operatively stopped script {0} {1} in {2} {3}",
617 ScriptName, ItemID, PrimName, ObjectID);
569 618
570 return true; 619 return true;
571 } 620 }
@@ -876,9 +925,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
876 } 925 }
877 else if ((e is TargetInvocationException) && (e.InnerException is ScriptCoopStopException)) 926 else if ((e is TargetInvocationException) && (e.InnerException is ScriptCoopStopException))
878 { 927 {
879 m_log.DebugFormat( 928 if (DebugLevel >= 1)
880 "[SCRIPT INSTANCE]: Script {0}.{1} in event {2}, state {3} stopped co-operatively.", 929 m_log.DebugFormat(
881 PrimName, ScriptName, data.EventName, State); 930 "[SCRIPT INSTANCE]: Script {0}.{1} in event {2}, state {3} stopped co-operatively.",
931 PrimName, ScriptName, data.EventName, State);
882 } 932 }
883 } 933 }
884 } 934 }
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs
index 8c3e9e0..52d75a0 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs
@@ -50,14 +50,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests
50 private TestScene m_scene; 50 private TestScene m_scene;
51 private OpenSim.Region.ScriptEngine.XEngine.XEngine m_xEngine; 51 private OpenSim.Region.ScriptEngine.XEngine.XEngine m_xEngine;
52 52
53 private AutoResetEvent m_chatEvent = new AutoResetEvent(false); 53 private AutoResetEvent m_chatEvent;
54 private AutoResetEvent m_stoppedEvent = new AutoResetEvent(false); 54 private AutoResetEvent m_stoppedEvent;
55 55
56 private OSChatMessage m_osChatMessageReceived; 56 private OSChatMessage m_osChatMessageReceived;
57 57
58 [TestFixtureSetUp] 58 [SetUp]
59 public void Init() 59 public void Init()
60 { 60 {
61 m_osChatMessageReceived = null;
62 m_chatEvent = new AutoResetEvent(false);
63 m_stoppedEvent = new AutoResetEvent(false);
64
61 //AppDomain.CurrentDomain.SetData("APPBASE", Environment.CurrentDirectory + "/bin"); 65 //AppDomain.CurrentDomain.SetData("APPBASE", Environment.CurrentDirectory + "/bin");
62// Console.WriteLine(AppDomain.CurrentDomain.BaseDirectory); 66// Console.WriteLine(AppDomain.CurrentDomain.BaseDirectory);
63 m_xEngine = new OpenSim.Region.ScriptEngine.XEngine.XEngine(); 67 m_xEngine = new OpenSim.Region.ScriptEngine.XEngine.XEngine();
@@ -77,7 +81,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests
77 81
78 xEngineConfig.Set("ScriptStopStrategy", "co-op"); 82 xEngineConfig.Set("ScriptStopStrategy", "co-op");
79 83
80 m_scene = new SceneHelpers().SetupScene("My Test", UUID.Random(), 1000, 1000, configSource); 84 // Make sure loops aren't actually being terminated by a script delay wait.
85 xEngineConfig.Set("ScriptDelayFactor", 0);
86
87 // This is really just set for debugging the test.
88 xEngineConfig.Set("WriteScriptSourceToDebugFile", true);
89
90 // Set to false if we need to debug test so the old scripts don't get wiped before each separate test
91// xEngineConfig.Set("DeleteScriptsOnStartup", false);
92
93 // This is not currently used at all for co-op termination. Bumping up to demonstrate that co-op termination
94 // has an effect - without it tests will fail due to a 120 second wait for the event to finish.
95 xEngineConfig.Set("WaitForEventCompletionOnScriptStop", 120000);
96
97 m_scene = new SceneHelpers().SetupScene("My Test", TestHelpers.ParseTail(0x9999), 1000, 1000, configSource);
81 SceneHelpers.SetupSceneModules(m_scene, configSource, m_xEngine); 98 SceneHelpers.SetupSceneModules(m_scene, configSource, m_xEngine);
82 m_scene.StartScripts(); 99 m_scene.StartScripts();
83 } 100 }
@@ -95,12 +112,218 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests
95 TestHelpers.InMethod(); 112 TestHelpers.InMethod();
96// TestHelpers.EnableLogging(); 113// TestHelpers.EnableLogging();
97 114
115 string script =
116@"default
117{
118 state_entry()
119 {
120 llSay(0, ""Thin Lizzy"");
121 llSleep(60);
122 }
123}";
124
125 TestStop(script);
126 }
127
128 [Test]
129 public void TestStopOnLongSingleStatementForLoop()
130 {
131 TestHelpers.InMethod();
132// TestHelpers.EnableLogging();
133
134 string script =
135@"default
136{
137 state_entry()
138 {
139 integer i = 0;
140 llSay(0, ""Thin Lizzy"");
141
142 for (i = 0; i < 2147483647; i++)
143 llSay(0, ""Iter "" + (string)i);
144 }
145}";
146
147 TestStop(script);
148 }
149
150 [Test]
151 public void TestStopOnLongCompoundStatementForLoop()
152 {
153 TestHelpers.InMethod();
154// TestHelpers.EnableLogging();
155
156 string script =
157@"default
158{
159 state_entry()
160 {
161 integer i = 0;
162 llSay(0, ""Thin Lizzy"");
163
164 for (i = 0; i < 2147483647; i++)
165 {
166 llSay(0, ""Iter "" + (string)i);
167 }
168 }
169}";
170
171 TestStop(script);
172 }
173
174 [Test]
175 public void TestStopOnLongSingleStatementWhileLoop()
176 {
177 TestHelpers.InMethod();
178// TestHelpers.EnableLogging();
179
180 string script =
181@"default
182{
183 state_entry()
184 {
185 integer i = 0;
186 llSay(0, ""Thin Lizzy"");
187
188 while (1 == 1)
189 llSay(0, ""Iter "" + (string)i++);
190 }
191}";
192
193 TestStop(script);
194 }
195
196 [Test]
197 public void TestStopOnLongCompoundStatementWhileLoop()
198 {
199 TestHelpers.InMethod();
200// TestHelpers.EnableLogging();
201
202 string script =
203@"default
204{
205 state_entry()
206 {
207 integer i = 0;
208 llSay(0, ""Thin Lizzy"");
209
210 while (1 == 1)
211 {
212 llSay(0, ""Iter "" + (string)i++);
213 }
214 }
215}";
216
217 TestStop(script);
218 }
219
220 [Test]
221 public void TestStopOnLongDoWhileLoop()
222 {
223 TestHelpers.InMethod();
224// TestHelpers.EnableLogging();
225
226 string script =
227@"default
228{
229 state_entry()
230 {
231 integer i = 0;
232 llSay(0, ""Thin Lizzy"");
233
234 do
235 {
236 llSay(0, ""Iter "" + (string)i++);
237} while (1 == 1);
238 }
239}";
240
241 TestStop(script);
242 }
243
244 [Test]
245 public void TestStopOnInfiniteJumpLoop()
246 {
247 TestHelpers.InMethod();
248 TestHelpers.EnableLogging();
249
250 string script =
251@"default
252{
253 state_entry()
254 {
255 integer i = 0;
256 llSay(0, ""Thin Lizzy"");
257
258 @p1;
259 llSay(0, ""Iter "" + (string)i++);
260 jump p1;
261 }
262}";
263
264 TestStop(script);
265 }
266
267 [Test]
268 public void TestStopOnInfiniteUserFunctionCallLoop()
269 {
270 TestHelpers.InMethod();
271// TestHelpers.EnableLogging();
272
273 string script =
274@"
275integer i = 0;
276
277ufn1()
278{
279 llSay(0, ""Iter ufn1() "" + (string)i++);
280 ufn1();
281}
282
283default
284{
285 state_entry()
286 {
287 integer i = 0;
288 llSay(0, ""Thin Lizzy"");
289
290 ufn1();
291 }
292}";
293
294 TestStop(script);
295 }
296
297 [Test]
298 public void TestStopOnInfiniteManualEventCallLoop()
299 {
300 TestHelpers.InMethod();
301// TestHelpers.EnableLogging();
302
303 string script =
304@"default
305{
306 state_entry()
307 {
308 integer i = 0;
309 llSay(0, ""Thin Lizzy"");
310
311 llSay(0, ""Iter"" + (string)i++);
312 default_event_state_entry();
313 }
314}";
315
316 TestStop(script);
317 }
318
319 private void TestStop(string script)
320 {
98 UUID userId = TestHelpers.ParseTail(0x1); 321 UUID userId = TestHelpers.ParseTail(0x1);
99// UUID objectId = TestHelpers.ParseTail(0x100); 322// UUID objectId = TestHelpers.ParseTail(0x100);
100// UUID itemId = TestHelpers.ParseTail(0x3); 323// UUID itemId = TestHelpers.ParseTail(0x3);
101 string itemName = "TestStopOnObjectDerezLongSleep() Item"; 324 string itemName = "TestStop() Item";
102 325
103 SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId, "TestStopOnObjectDerezLongSleep", 0x100); 326 SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId, "TestStop", 0x100);
104 m_scene.AddNewSceneObject(so, true); 327 m_scene.AddNewSceneObject(so, true);
105 328
106 InventoryItemBase itemTemplate = new InventoryItemBase(); 329 InventoryItemBase itemTemplate = new InventoryItemBase();
@@ -111,15 +334,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests
111 334
112 m_scene.EventManager.OnChatFromWorld += OnChatFromWorld; 335 m_scene.EventManager.OnChatFromWorld += OnChatFromWorld;
113 336
114 SceneObjectPart partWhereRezzed = m_scene.RezNewScript(userId, itemTemplate, 337 SceneObjectPart partWhereRezzed = m_scene.RezNewScript(userId, itemTemplate, script);
115@"default
116{
117 state_entry()
118 {
119 llSay(0, ""Thin Lizzy"");
120 llSleep(60);
121 }
122}");
123 338
124 TaskInventoryItem rezzedItem = partWhereRezzed.Inventory.GetInventoryItem(itemName); 339 TaskInventoryItem rezzedItem = partWhereRezzed.Inventory.GetInventoryItem(itemName);
125 340
@@ -129,7 +344,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests
129 Console.WriteLine("Script started with message [{0}]", m_osChatMessageReceived.Message); 344 Console.WriteLine("Script started with message [{0}]", m_osChatMessageReceived.Message);
130 345
131 // FIXME: This is a very poor way of trying to avoid a low-probability race condition where the script 346 // FIXME: This is a very poor way of trying to avoid a low-probability race condition where the script
132 // executes llSay() but has not started the sleep before we try to stop it. 347 // executes llSay() but has not started the next statement before we try to stop it.
133 Thread.Sleep(1000); 348 Thread.Sleep(1000);
134 349
135 // We need a way of carrying on if StopScript() fail, since it won't return if the script isn't actually 350 // We need a way of carrying on if StopScript() fail, since it won't return if the script isn't actually
@@ -148,7 +363,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests
148 363
149 private void OnChatFromWorld(object sender, OSChatMessage oscm) 364 private void OnChatFromWorld(object sender, OSChatMessage oscm)
150 { 365 {
151// Console.WriteLine("Got chat [{0}]", oscm.Message); 366 m_scene.EventManager.OnChatFromWorld -= OnChatFromWorld;
367 Console.WriteLine("Got chat [{0}]", oscm.Message);
152 368
153 m_osChatMessageReceived = oscm; 369 m_osChatMessageReceived = oscm;
154 m_chatEvent.Set(); 370 m_chatEvent.Set();
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 0000000..f4211c8
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/XEngine/Api/Runtime/XEngineScriptBase.cs
@@ -0,0 +1,61 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Runtime.Remoting;
30using System.Runtime.Remoting.Lifetime;
31using System.Security.Permissions;
32using System.Threading;
33using System.Reflection;
34using System.Collections;
35using System.Collections.Generic;
36using OpenSim.Region.ScriptEngine.Interfaces;
37using OpenSim.Region.ScriptEngine.Shared;
38using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
39
40namespace OpenSim.Region.ScriptEngine.XEngine.ScriptBase
41{
42 public class XEngineScriptBase : ScriptBaseClass
43 {
44 /// <summary>
45 /// Used for script sleeps when we are using co-operative script termination.
46 /// </summary>
47 /// <remarks>null if co-operative script termination is not active</remarks>
48 WaitHandle m_coopSleepHandle;
49
50 public XEngineScriptBase(WaitHandle coopSleepHandle) : base()
51 {
52 m_coopSleepHandle = coopSleepHandle;
53 }
54
55 public void opensim_reserved_CheckForCoopTermination()
56 {
57 if (m_coopSleepHandle != null && m_coopSleepHandle.WaitOne(0))
58 throw new ScriptCoopStopException();
59 }
60 }
61} \ No newline at end of file
diff --git a/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs b/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs
index 9405075..afde685 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs
@@ -52,7 +52,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
52 { 52 {
53 myScriptEngine = _ScriptEngine; 53 myScriptEngine = _ScriptEngine;
54 54
55 m_log.Info("[XEngine] Hooking up to server events"); 55// m_log.Info("[XEngine] Hooking up to server events");
56 myScriptEngine.World.EventManager.OnAttach += attach; 56 myScriptEngine.World.EventManager.OnAttach += attach;
57 myScriptEngine.World.EventManager.OnObjectGrab += touch_start; 57 myScriptEngine.World.EventManager.OnObjectGrab += touch_start;
58 myScriptEngine.World.EventManager.OnObjectGrabbing += touch; 58 myScriptEngine.World.EventManager.OnObjectGrabbing += touch;
@@ -69,7 +69,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
69 myScriptEngine.World.EventManager.OnScriptLandColliderStart += land_collision_start; 69 myScriptEngine.World.EventManager.OnScriptLandColliderStart += land_collision_start;
70 myScriptEngine.World.EventManager.OnScriptLandColliding += land_collision; 70 myScriptEngine.World.EventManager.OnScriptLandColliding += land_collision;
71 myScriptEngine.World.EventManager.OnScriptLandColliderEnd += land_collision_end; 71 myScriptEngine.World.EventManager.OnScriptLandColliderEnd += land_collision_end;
72 IMoneyModule money=myScriptEngine.World.RequestModuleInterface<IMoneyModule>(); 72 IMoneyModule money = myScriptEngine.World.RequestModuleInterface<IMoneyModule>();
73 if (money != null) 73 if (money != null)
74 { 74 {
75 money.OnObjectPaid+=HandleObjectPaid; 75 money.OnObjectPaid+=HandleObjectPaid;
diff --git a/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineTest.cs b/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineBasicTests.cs
index 5abfe9a..5abfe9a 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineTest.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineBasicTests.cs
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index 72646f6..d483219 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
@@ -46,13 +46,15 @@ using OpenSim.Framework;
46using OpenSim.Framework.Console; 46using OpenSim.Framework.Console;
47using OpenSim.Region.Framework.Scenes; 47using OpenSim.Region.Framework.Scenes;
48using OpenSim.Region.Framework.Interfaces; 48using OpenSim.Region.Framework.Interfaces;
49using OpenSim.Region.ScriptEngine.Interfaces;
49using OpenSim.Region.ScriptEngine.Shared; 50using OpenSim.Region.ScriptEngine.Shared;
50using OpenSim.Region.ScriptEngine.Shared.ScriptBase; 51using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
51using OpenSim.Region.ScriptEngine.Shared.CodeTools; 52using OpenSim.Region.ScriptEngine.Shared.CodeTools;
52using OpenSim.Region.ScriptEngine.Shared.Instance; 53using OpenSim.Region.ScriptEngine.Shared.Instance;
53using OpenSim.Region.ScriptEngine.Shared.Api; 54using OpenSim.Region.ScriptEngine.Shared.Api;
54using OpenSim.Region.ScriptEngine.Shared.Api.Plugins; 55using OpenSim.Region.ScriptEngine.Shared.Api.Plugins;
55using OpenSim.Region.ScriptEngine.Interfaces; 56using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
57using OpenSim.Region.ScriptEngine.XEngine.ScriptBase;
56using Timer = OpenSim.Region.ScriptEngine.Shared.Api.Plugins.Timer; 58using Timer = OpenSim.Region.ScriptEngine.Shared.Api.Plugins.Timer;
57 59
58using ScriptCompileQueue = OpenSim.Framework.LocklessQueue<object[]>; 60using ScriptCompileQueue = OpenSim.Framework.LocklessQueue<object[]>;
@@ -176,6 +178,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine
176 get { return "XEngine"; } 178 get { return "XEngine"; }
177 } 179 }
178 180
181 public string ScriptClassName { get; private set; }
182
183 public string ScriptBaseClassName { get; private set; }
184
185 public ParameterInfo[] ScriptBaseClassParameters { get; private set; }
186
187 public string[] ScriptReferencedAssemblies { get; private set; }
188
179 public Scene World 189 public Scene World
180 { 190 {
181 get { return m_Scene; } 191 get { return m_Scene; }
@@ -230,21 +240,35 @@ namespace OpenSim.Region.ScriptEngine.XEngine
230 240
231 m_ScriptConfig = configSource.Configs["XEngine"]; 241 m_ScriptConfig = configSource.Configs["XEngine"];
232 m_ConfigSource = configSource; 242 m_ConfigSource = configSource;
243
244 string rawScriptStopStrategy = m_ScriptConfig.GetString("ScriptStopStrategy", "abort");
245
246 m_log.InfoFormat("[XEngine]: Script stop strategy is {0}", rawScriptStopStrategy);
247
248 if (rawScriptStopStrategy == "co-op")
249 {
250 ScriptClassName = "XEngineScript";
251 ScriptBaseClassName = typeof(XEngineScriptBase).FullName;
252 ScriptBaseClassParameters = typeof(XEngineScriptBase).GetConstructor(new Type[] { typeof(WaitHandle) }).GetParameters();
253 ScriptReferencedAssemblies = new string[] { Path.GetFileName(typeof(XEngineScriptBase).Assembly.Location) };
254 }
255 else
256 {
257 ScriptClassName = "Script";
258 ScriptBaseClassName = typeof(ScriptBaseClass).FullName;
259 }
260
261// Console.WriteLine("ASSEMBLY NAME: {0}", ScriptReferencedAssemblies[0]);
233 } 262 }
234 263
235 public void AddRegion(Scene scene) 264 public void AddRegion(Scene scene)
236 { 265 {
237 if (m_ScriptConfig == null) 266 if (m_ScriptConfig == null)
238 return; 267 return;
268
239 m_ScriptFailCount = 0; 269 m_ScriptFailCount = 0;
240 m_ScriptErrorMessage = String.Empty; 270 m_ScriptErrorMessage = String.Empty;
241 271
242 if (m_ScriptConfig == null)
243 {
244// m_log.ErrorFormat("[XEngine] No script configuration found. Scripts disabled");
245 return;
246 }
247
248 m_Enabled = m_ScriptConfig.GetBoolean("Enabled", true); 272 m_Enabled = m_ScriptConfig.GetBoolean("Enabled", true);
249 273
250 if (!m_Enabled) 274 if (!m_Enabled)
@@ -1109,7 +1133,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1109 } 1133 }
1110 1134
1111 m_log.DebugFormat( 1135 m_log.DebugFormat(
1112 "[XEngine] Loading script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}", 1136 "[XEngine]: Loading script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}",
1113 part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID, 1137 part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID,
1114 part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); 1138 part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
1115 1139
@@ -1130,6 +1154,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1130 lock (m_AddingAssemblies) 1154 lock (m_AddingAssemblies)
1131 { 1155 {
1132 m_Compiler.PerformScriptCompile(script, assetID.ToString(), item.OwnerID, out assembly, out linemap); 1156 m_Compiler.PerformScriptCompile(script, assetID.ToString(), item.OwnerID, out assembly, out linemap);
1157
1133 if (!m_AddingAssemblies.ContainsKey(assembly)) { 1158 if (!m_AddingAssemblies.ContainsKey(assembly)) {
1134 m_AddingAssemblies[assembly] = 1; 1159 m_AddingAssemblies[assembly] = 1;
1135 } else { 1160 } else {
@@ -1179,7 +1204,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1179 } 1204 }
1180 catch (Exception e) 1205 catch (Exception e)
1181 { 1206 {
1182// m_log.ErrorFormat("[XEngine]: Exception when rezzing script {0}{1}", e.Message, e.StackTrace); 1207// m_log.ErrorFormat(
1208// "[XEngine]: Exception when rezzing script with item ID {0}, {1}{2}",
1209// itemID, e.Message, e.StackTrace);
1183 1210
1184 // try 1211 // try
1185 // { 1212 // {
@@ -1288,7 +1315,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1288 startParam, postOnRez, 1315 startParam, postOnRez,
1289 m_MaxScriptQueue); 1316 m_MaxScriptQueue);
1290 1317
1291 instance.Load(m_AppDomains[appDomain], assembly, stateSource); 1318 if (!instance.Load(m_AppDomains[appDomain], assembly, stateSource))
1319 return false;
1292 1320
1293// if (DebugLevel >= 1) 1321// if (DebugLevel >= 1)
1294// m_log.DebugFormat( 1322// m_log.DebugFormat(
diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example
index 658b993..0fe44e9 100644
--- a/bin/OpenSim.ini.example
+++ b/bin/OpenSim.ini.example
@@ -749,13 +749,6 @@
749 ;; The trade-off may be increased memory usage by the script engine. 749 ;; The trade-off may be increased memory usage by the script engine.
750 ; ThreadStackSize = 262144 750 ; ThreadStackSize = 262144
751 751
752 ;# {DeleteScriptsOnStartup} {} {Delete previously compiled script DLLs on startup?} (true false) true
753 ;; Controls whether previously compiled scripts DLLs are deleted on sim restart. If you set this to false
754 ;; then startup will be considerably faster since scripts won't need to be recompiled. However, then it becomes your responsibility to delete the
755 ;; compiled scripts if you're recompiling OpenSim from source code and internal interfaces used
756 ;; by scripts have changed.
757 ; DeleteScriptsOnStartup = true
758
759 ;; Set this to true (the default) to load each script into a separate 752 ;; Set this to true (the default) to load each script into a separate
760 ;; AppDomain. 753 ;; AppDomain.
761 ;; 754 ;;
@@ -768,6 +761,23 @@
768 ;; Some Windows users have also reported script loading problems when AppDomainLoading = false 761 ;; Some Windows users have also reported script loading problems when AppDomainLoading = false
769 ; AppDomainLoading = true 762 ; AppDomainLoading = true
770 763
764 ;; Controls whether scripts are stopped by aborting their threads externally (abort) or by co-operative checks from the compiled script (co-op)
765 ;; co-op will be more stable but this option is currently experimental.
766 ;; If moving from co-op to abort, existing script DLLs will need to be recompiled.
767 ;; This currently can only be done manually, either by setting DeleteScriptsOnStartup = true for one run
768 ;; or by deleting the script DLL* files in bin/ScriptEngines/<region-id>/
769 ;; One can move from co-op back to abort without recompilation, but reverting back to co-op again will need script recompile
770 ;; Current valid values are "abort" and "co-op"
771 ; ScriptStopStrategy = abort
772
773
774 ;# {DeleteScriptsOnStartup} {} {Delete previously compiled script DLLs on startup?} (true false) true
775 ;; Controls whether previously compiled scripts DLLs are deleted on sim restart. If you set this to false
776 ;; then startup will be considerably faster since scripts won't need to be recompiled. However, then it becomes your responsibility to delete the
777 ;; compiled scripts if you're recompiling OpenSim from source code and internal interfaces used
778 ;; by scripts have changed.
779 ; DeleteScriptsOnStartup = true
780
771 ;# {DefaultCompileLanguage} {Enabled:true} {Default script language?} {lsl vb cs} lsl 781 ;# {DefaultCompileLanguage} {Enabled:true} {Default script language?} {lsl vb cs} lsl
772 ;; Default language for scripts 782 ;; Default language for scripts
773 ; DefaultCompileLanguage = "lsl" 783 ; DefaultCompileLanguage = "lsl"
diff --git a/bin/OpenSimDefaults.ini b/bin/OpenSimDefaults.ini
index 889865b..c60579b 100644
--- a/bin/OpenSimDefaults.ini
+++ b/bin/OpenSimDefaults.ini
@@ -1315,6 +1315,20 @@
1315 ; script assemblies 1315 ; script assemblies
1316 AppDomainLoading = true 1316 AppDomainLoading = true
1317 1317
1318 ; Controls whether previously compiled scripts DLLs are deleted on sim restart. If you set this to false
1319 ; then startup will be considerably faster since scripts won't need to be recompiled. However, then it becomes your responsibility to delete the
1320 ; compiled scripts if you're recompiling OpenSim from source code and internal interfaces used
1321 ; by scripts have changed.
1322 ; DeleteScriptsOnStartup = false
1323
1324 ; Controls whether scripts are stopped by aborting their threads externally (abort) or by co-operative checks from the compiled script (co-op)
1325 ; co-op will be more stable but this option is currently experimental.
1326 ; If moving from co-op to abort, existing script DLLs will need to be recompiled.
1327 ; This currently can only be done manually, either by setting DeleteScriptsOnStartup = true for one run
1328 ; or by deleting the script DLL* files in bin/ScriptEngines/<region-id>/
1329 ; One can move from co-op back to abort without recompilation, but reverting back to co-op again will need script recompile
1330 ScriptStopStrategy = abort
1331
1318 ; Rate to poll for asynchronous command replies (ms) 1332 ; Rate to poll for asynchronous command replies (ms)
1319 ; currently unused 1333 ; currently unused
1320 ;AsyncLLCommandLoopms = 50 1334 ;AsyncLLCommandLoopms = 50
@@ -1416,12 +1430,6 @@
1416 ;; Path to script assemblies 1430 ;; Path to script assemblies
1417 ; ScriptEnginesPath = "ScriptEngines" 1431 ; ScriptEnginesPath = "ScriptEngines"
1418 1432
1419 ; Controls whether previously compiled scripts DLLs are deleted on sim restart. If you set this to false
1420 ; then startup will be considerably faster since scripts won't need to be recompiled. However, then it becomes your responsibility to delete the
1421 ; compiled scripts if you're recompiling OpenSim from source code and internal interfaces used
1422 ; by scripts have changed.
1423 ; DeleteScriptsOnStartup = false
1424
1425 1433
1426[Concierge] 1434[Concierge]
1427 ; Enable concierge module 1435 ; Enable concierge module
diff --git a/prebuild.xml b/prebuild.xml
index 37b406c..cea4530 100644
--- a/prebuild.xml
+++ b/prebuild.xml
@@ -2391,6 +2391,40 @@
2391 </Files> 2391 </Files>
2392 </Project> 2392 </Project>
2393 2393
2394 <Project frameworkVersion="v3_5" name="OpenSim.Region.ScriptEngine.XEngine.Api.Runtime" path="OpenSim/Region/ScriptEngine/XEngine/Api/Runtime" type="Library">
2395 <Configuration name="Debug">
2396 <Options>
2397 <OutputPath>../../../../../../bin/</OutputPath>
2398 </Options>
2399 </Configuration>
2400 <Configuration name="Release">
2401 <Options>
2402 <OutputPath>../../../../../../bin/</OutputPath>
2403 </Options>
2404 </Configuration>
2405
2406 <ReferencePath>../../../../../../bin/</ReferencePath>
2407 <Reference name="System"/>
2408 <Reference name="System.Data"/>
2409 <Reference name="System.Web"/>
2410 <Reference name="System.Xml"/>
2411 <Reference name="OpenMetaverseTypes" path="../../../../../../bin/"/>
2412 <Reference name="OpenSim"/>
2413 <Reference name="OpenSim.Framework"/>
2414 <Reference name="OpenSim.Framework.Communications"/>
2415 <Reference name="OpenSim.Region.Framework"/>
2416 <Reference name="OpenSim.Region.CoreModules"/>
2417 <Reference name="OpenSim.Framework.Console"/>
2418 <Reference name="OpenSim.Region.ScriptEngine.Shared"/>
2419 <Reference name="OpenSim.Region.ScriptEngine.Shared.Api.Runtime"/>
2420 <Reference name="Nini" path="../../../../../../bin/"/>
2421 <Reference name="log4net" path="../../../../../../bin/"/>
2422
2423 <Files>
2424 <Match pattern="*.cs" recurse="true"/>
2425 </Files>
2426 </Project>
2427
2394 <Project frameworkVersion="v3_5" name="OpenSim.Region.ScriptEngine.XEngine" path="OpenSim/Region/ScriptEngine/XEngine" type="Library"> 2428 <Project frameworkVersion="v3_5" name="OpenSim.Region.ScriptEngine.XEngine" path="OpenSim/Region/ScriptEngine/XEngine" type="Library">
2395 <Configuration name="Debug"> 2429 <Configuration name="Debug">
2396 <Options> 2430 <Options>
@@ -2421,6 +2455,8 @@
2421 <Reference name="OpenSim.Region.ScriptEngine.Shared.CodeTools"/> 2455 <Reference name="OpenSim.Region.ScriptEngine.Shared.CodeTools"/>
2422 <Reference name="OpenSim.Region.ScriptEngine.Shared.Instance"/> 2456 <Reference name="OpenSim.Region.ScriptEngine.Shared.Instance"/>
2423 <Reference name="OpenSim.Region.ScriptEngine.Shared.Api"/> 2457 <Reference name="OpenSim.Region.ScriptEngine.Shared.Api"/>
2458 <Reference name="OpenSim.Region.ScriptEngine.Shared.Api.Runtime"/>
2459 <Reference name="OpenSim.Region.ScriptEngine.XEngine.Api.Runtime"/>
2424 <Reference name="SmartThreadPool"/> 2460 <Reference name="SmartThreadPool"/>
2425 <Reference name="Nini" path="../../../../bin/"/> 2461 <Reference name="Nini" path="../../../../bin/"/>
2426 <Reference name="log4net" path="../../../../bin/"/> 2462 <Reference name="log4net" path="../../../../bin/"/>
@@ -2428,6 +2464,7 @@
2428 <Files> 2464 <Files>
2429 <Match buildAction="EmbeddedResource" path="Resources" pattern="*.addin.xml" recurse="true"/> 2465 <Match buildAction="EmbeddedResource" path="Resources" pattern="*.addin.xml" recurse="true"/>
2430 <Match pattern="*.cs" recurse="true"> 2466 <Match pattern="*.cs" recurse="true">
2467 <Exclude name="Api"/>
2431 <Exclude name="Tests" pattern="Tests"/> 2468 <Exclude name="Tests" pattern="Tests"/>
2432 </Match> 2469 </Match>
2433 </Files> 2470 </Files>