aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/Shared
diff options
context:
space:
mode:
authorJustin Clark-Casey (justincc)2013-01-17 23:39:09 +0000
committerJustin Clark-Casey (justincc)2013-01-17 23:39:09 +0000
commitc8afc8523b9caf931afb3d5b3f9874b26b866a77 (patch)
treeb1a84d82591f462ae61b3aeed4f4b6dd3c5c06e8 /OpenSim/Region/ScriptEngine/Shared
parentMerge branch 'master' of melanie@opensimulator.org:/var/git/opensim (diff)
downloadopensim-SC_OLD-c8afc8523b9caf931afb3d5b3f9874b26b866a77.zip
opensim-SC_OLD-c8afc8523b9caf931afb3d5b3f9874b26b866a77.tar.gz
opensim-SC_OLD-c8afc8523b9caf931afb3d5b3f9874b26b866a77.tar.bz2
opensim-SC_OLD-c8afc8523b9caf931afb3d5b3f9874b26b866a77.tar.xz
Implement non-wait co-operative termination of scripts for XEngine in addition to termination on wait.
This involves inserting opensim_reserved_CheckForCoopTermination() calls in lsl -> c# translation at any place where the script could be in a loop with no wait calls. These places are for, while, do-while, label, user function call and manual event function call. Call goes through to an XEngineScriptBase which extends ScriptBase. IEngine is extended to supply necessary engine-specific parent class references and constructor parameters to Compiler. Unfortunately, since XEngineScriptBase has to be passed WaitHandle in its constructor, older compiled scripts will fail to load with an error on the OpenSim console. Such scripts will need to be recompiled, either by removing all *.dll files from the bin/ScriptEngines/<region-id> or by setting DeleteScriptsOnStartup = true in [XEngine] for one run. Automatic recompilation may be implemented in a later commit. This feature should not yet be used, default remains termination with Thread.Abort() which will work as normal once scripts are recompiled.
Diffstat (limited to 'OpenSim/Region/ScriptEngine/Shared')
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs12
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs133
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs66
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs24
4 files changed, 164 insertions, 71 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index d47fd6b..cee10a8 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -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/CodeTools/CSCodeGenerator.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs
index 97dd0f6..002f9b8 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 ForLoopStatement
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..7432202 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,17 @@ 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, m_scriptEngine.ScriptBaseClassName, m_scriptEngine.ScriptBaseClassParameters);
415 break; 420 break;
416 case enumCompileType.vb: 421 case enumCompileType.vb:
417 compileScript = CreateVBCompilerScript(compileScript); 422 compileScript = CreateVBCompilerScript(compileScript, m_scriptEngine.ScriptBaseClassName);
418 break; 423 break;
419// case enumCompileType.js: 424// case enumCompileType.js:
420// compileScript = CreateJSCompilerScript(compileScript); 425// compileScript = CreateJSCompilerScript(compileScript, m_scriptEngine.ScriptBaseClassName);
421// break; 426// break;
422 case enumCompileType.yp: 427 case enumCompileType.yp:
423 compileScript = CreateYPCompilerScript(compileScript); 428 compileScript = CreateYPCompilerScript(compileScript, m_scriptEngine.ScriptBaseClassName);
424 break; 429 break;
425 } 430 }
426 431
@@ -451,43 +456,59 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
451// return compileScript; 456// return compileScript;
452// } 457// }
453 458
454 private static string CreateCSCompilerScript(string compileScript) 459 private static string CreateCSCompilerScript(
460 string compileScript, string baseClassName, ParameterInfo[] constructorParameters)
455 { 461 {
456 compileScript = String.Empty + 462 compileScript = string.Format(
457 "using OpenSim.Region.ScriptEngine.Shared; using System.Collections.Generic;\r\n" + 463@"using OpenSim.Region.ScriptEngine.Shared;
458 String.Empty + "namespace SecondLife { " + 464using System.Collections.Generic;
459 String.Empty + "public class Script : OpenSim.Region.ScriptEngine.Shared.ScriptBase.ScriptBaseClass { \r\n" + 465
460 @"public Script() { } " + 466namespace SecondLife
461 compileScript + 467{{
462 "} }\r\n"; 468 public class Script : {0}
469 {{
470 public Script({1}) : base({2}) {{}}
471{3}
472 }}
473}}",
474 baseClassName,
475 constructorParameters != null
476 ? string.Join(", ", Array.ConvertAll<ParameterInfo, string>(constructorParameters, pi => pi.ToString()))
477 : "",
478 constructorParameters != null
479 ? string.Join(", ", Array.ConvertAll<ParameterInfo, string>(constructorParameters, pi => pi.Name))
480 : "",
481 compileScript);
482
463 return compileScript; 483 return compileScript;
464 } 484 }
465 485
466 private static string CreateYPCompilerScript(string compileScript) 486 private static string CreateYPCompilerScript(string compileScript, string baseClassName)
467 { 487 {
468 compileScript = String.Empty + 488 compileScript = String.Empty +
469 "using OpenSim.Region.ScriptEngine.Shared.YieldProlog; " + 489 "using OpenSim.Region.ScriptEngine.Shared.YieldProlog; " +
470 "using OpenSim.Region.ScriptEngine.Shared; using System.Collections.Generic;\r\n" + 490 "using OpenSim.Region.ScriptEngine.Shared; using System.Collections.Generic;\r\n" +
471 String.Empty + "namespace SecondLife { " + 491 String.Empty + "namespace SecondLife { " +
472 String.Empty + "public class Script : OpenSim.Region.ScriptEngine.Shared.ScriptBase.ScriptBaseClass { \r\n" + 492 String.Empty + "public class Script : " + baseClassName + " { \r\n" +
473 //@"public Script() { } " + 493 //@"public Script() { } " +
474 @"static OpenSim.Region.ScriptEngine.Shared.YieldProlog.YP YP=null; " + 494 @"static OpenSim.Region.ScriptEngine.Shared.YieldProlog.YP YP=null; " +
475 @"public Script() { YP= new OpenSim.Region.ScriptEngine.Shared.YieldProlog.YP(); } " + 495 @"public Script() { YP= new OpenSim.Region.ScriptEngine.Shared.YieldProlog.YP(); } " +
476
477 compileScript + 496 compileScript +
478 "} }\r\n"; 497 "} }\r\n";
498
479 return compileScript; 499 return compileScript;
480 } 500 }
481 501
482 private static string CreateVBCompilerScript(string compileScript) 502 private static string CreateVBCompilerScript(string compileScript, string baseClassName)
483 { 503 {
484 compileScript = String.Empty + 504 compileScript = String.Empty +
485 "Imports OpenSim.Region.ScriptEngine.Shared: Imports System.Collections.Generic: " + 505 "Imports OpenSim.Region.ScriptEngine.Shared: Imports System.Collections.Generic: " +
486 String.Empty + "NameSpace SecondLife:" + 506 String.Empty + "NameSpace SecondLife:" +
487 String.Empty + "Public Class Script: Inherits OpenSim.Region.ScriptEngine.Shared.ScriptBase.ScriptBaseClass: " + 507 String.Empty + "Public Class Script: Inherits " + baseClassName +
488 "\r\nPublic Sub New()\r\nEnd Sub: " + 508 "\r\nPublic Sub New()\r\nEnd Sub: " +
489 compileScript + 509 compileScript +
490 ":End Class :End Namespace\r\n"; 510 ":End Class :End Namespace\r\n";
511
491 return compileScript; 512 return compileScript;
492 } 513 }
493 514
@@ -549,6 +570,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
549 parameters.ReferencedAssemblies.Add(Path.Combine(rootPath, 570 parameters.ReferencedAssemblies.Add(Path.Combine(rootPath,
550 "OpenMetaverseTypes.dll")); 571 "OpenMetaverseTypes.dll"));
551 572
573 if (m_scriptEngine.ScriptReferencedAssemblies != null)
574 Array.ForEach<string>(
575 m_scriptEngine.ScriptReferencedAssemblies,
576 a => parameters.ReferencedAssemblies.Add(Path.Combine(rootPath, a)));
577
552 if (lang == enumCompileType.yp) 578 if (lang == enumCompileType.yp)
553 { 579 {
554 parameters.ReferencedAssemblies.Add(Path.Combine(rootPath, 580 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..e6ec0e1 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
267 try 267 try
268 { 268 {
269 if (dom != System.AppDomain.CurrentDomain) 269 if (dom != System.AppDomain.CurrentDomain)
270 m_Script = (IScript)dom.CreateInstanceAndUnwrap( 270 m_Script
271 = (IScript)dom.CreateInstanceAndUnwrap(
271 Path.GetFileNameWithoutExtension(assembly), 272 Path.GetFileNameWithoutExtension(assembly),
272 "SecondLife.Script"); 273 "SecondLife.Script",
274 false,
275 BindingFlags.Default,
276 null,
277 new object[] { m_coopSleepHandle },
278 null,
279 null,
280 null);
273 else 281 else
274 m_Script = (IScript)Assembly.Load( 282 m_Script
275 Path.GetFileNameWithoutExtension(assembly)).CreateInstance( 283 = (IScript)Assembly.Load(Path.GetFileNameWithoutExtension(assembly)).CreateInstance(
276 "SecondLife.Script"); 284 "SecondLife.Script",
285 false,
286 BindingFlags.Default,
287 null,
288 new object[] { m_coopSleepHandle },
289 null,
290 null);
277 291
278 //ILease lease = (ILease)RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass); 292 //ILease lease = (ILease)RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass);
279 //RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass); 293 //RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass);