aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/ScriptEngine/DotNetEngine/ScriptManager.cs37
-rw-r--r--OpenSim/Region/ScriptEngine/Interfaces/ICompiler.cs1
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs77
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs21
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/CodeTools/ICodeConverter.cs1
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XEngine.cs32
6 files changed, 169 insertions, 0 deletions
diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptManager.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptManager.cs
index 4ede7f1..32eb200 100644
--- a/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptManager.cs
+++ b/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptManager.cs
@@ -218,6 +218,43 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
218 localID, itemID, "on_rez", new DetectParams[0], 218 localID, itemID, "on_rez", new DetectParams[0],
219 new object[] { new LSL_Types.LSLInteger(startParam) }); 219 new object[] { new LSL_Types.LSLInteger(startParam) });
220 } 220 }
221
222 string[] warnings = LSLCompiler.GetWarnings();
223
224 if (warnings != null && warnings.Length != 0)
225 {
226 if (presence != null && (!postOnRez))
227 presence.ControllingClient.SendAgentAlertMessage(
228 "Script saved with warnings, check debug window!",
229 false);
230
231 foreach (string warning in warnings)
232 {
233 try
234 {
235 // DISPLAY WARNING INWORLD
236 string text = "Warning:\n" + warning;
237 if (text.Length > 1100)
238 text = text.Substring(0, 1099);
239
240 World.SimChat(Utils.StringToBytes(text),
241 ChatTypeEnum.DebugChannel, 2147483647,
242 m_host.AbsolutePosition, m_host.Name, m_host.UUID,
243 false);
244 }
245 catch (Exception e2) // LEGIT: User Scripting
246 {
247 m_log.Error("[" +
248 m_scriptEngine.ScriptEngineName +
249 "]: Error displaying warning in-world: " +
250 e2.ToString());
251 m_log.Error("[" +
252 m_scriptEngine.ScriptEngineName + "]: " +
253 "Warning:\r\n" +
254 warning);
255 }
256 }
257 }
221 } 258 }
222 catch (Exception e) // LEGIT: User Scripting 259 catch (Exception e) // LEGIT: User Scripting
223 { 260 {
diff --git a/OpenSim/Region/ScriptEngine/Interfaces/ICompiler.cs b/OpenSim/Region/ScriptEngine/Interfaces/ICompiler.cs
index 6273da9..d11abbc 100644
--- a/OpenSim/Region/ScriptEngine/Interfaces/ICompiler.cs
+++ b/OpenSim/Region/ScriptEngine/Interfaces/ICompiler.cs
@@ -34,6 +34,7 @@ namespace OpenSim.Region.ScriptEngine.Interfaces
34 public interface ICompiler 34 public interface ICompiler
35 { 35 {
36 string PerformScriptCompile(string source, string asset); 36 string PerformScriptCompile(string source, string asset);
37 string[] GetWarnings();
37 Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> 38 Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>>
38 LineMap(); 39 LineMap();
39 } 40 }
diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs
index 71e88e3..880ba4a 100644
--- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs
@@ -40,6 +40,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
40 private int m_braceCount; // for indentation 40 private int m_braceCount; // for indentation
41 private int m_CSharpLine; // the current line of generated C# code 41 private int m_CSharpLine; // the current line of generated C# code
42 private int m_CSharpCol; // the current column of generated C# code 42 private int m_CSharpCol; // the current column of generated C# code
43 private List<string> m_warnings = new List<string>();
43 44
44 /// <summary> 45 /// <summary>
45 /// Creates an 'empty' CSCodeGenerator instance. 46 /// Creates an 'empty' CSCodeGenerator instance.
@@ -153,6 +154,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
153 } 154 }
154 155
155 /// <summary> 156 /// <summary>
157 /// Get the set of warnings generated during compilation.
158 /// </summary>
159 /// <returns></returns>
160 public string[] GetWarnings()
161 {
162 return m_warnings.ToArray();
163 }
164
165 private void AddWarning(string warning)
166 {
167 if (!m_warnings.Contains(warning))
168 {
169 m_warnings.Add(warning);
170 }
171 }
172
173 /// <summary>
156 /// Recursively called to generate each type of node. Will generate this 174 /// Recursively called to generate each type of node. Will generate this
157 /// node, then all it's children. 175 /// node, then all it's children.
158 /// </summary> 176 /// </summary>
@@ -446,6 +464,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
446 { 464 {
447 string retstr = String.Empty; 465 string retstr = String.Empty;
448 466
467 List<string> identifiers = new List<string>();
468 checkForMultipleAssignments(identifiers, a);
469
449 retstr += GenerateNode((SYMBOL) a.kids.Pop()); 470 retstr += GenerateNode((SYMBOL) a.kids.Pop());
450 retstr += Generate(String.Format(" {0} ", a.AssignmentType), a); 471 retstr += Generate(String.Format(" {0} ", a.AssignmentType), a);
451 foreach (SYMBOL kid in a.kids) 472 foreach (SYMBOL kid in a.kids)
@@ -454,6 +475,62 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
454 return retstr; 475 return retstr;
455 } 476 }
456 477
478 // This code checks for LSL of the following forms, and generates a
479 // warning if it finds them.
480 //
481 // list l = [ "foo" ];
482 // l = (l=[]) + l + ["bar"];
483 // (produces l=["foo","bar"] in SL but l=["bar"] in OS)
484 //
485 // integer i;
486 // integer j;
487 // i = (j = 3) + (j = 4) + (j = 5);
488 // (produces j=3 in SL but j=5 in OS)
489 //
490 // Without this check, that code passes compilation, but does not do what
491 // the end user expects, because LSL in SL evaluates right to left instead
492 // of left to right.
493 //
494 // The theory here is that producing an error and alerting the end user that
495 // something needs to change is better than silently generating incorrect code.
496 private void checkForMultipleAssignments(List<string> identifiers, SYMBOL s)
497 {
498 if (s is Assignment)
499 {
500 Assignment a = (Assignment)s;
501 string newident = null;
502
503 if (a.kids[0] is Declaration)
504 {
505 newident = ((Declaration)a.kids[0]).Id;
506 }
507 else if (a.kids[0] is IDENT)
508 {
509 newident = ((IDENT)a.kids[0]).yytext;
510 }
511 else if (a.kids[0] is IdentDotExpression)
512 {
513 newident = ((IdentDotExpression)a.kids[0]).Name; // +"." + ((IdentDotExpression)a.kids[0]).Member;
514 }
515 else
516 {
517 AddWarning(String.Format("Multiple assignments checker internal error '{0}' at line {1} column {2}.", a.kids[0].GetType(), ((SYMBOL)a.kids[0]).Line - 1, ((SYMBOL)a.kids[0]).Position));
518 }
519
520 if (identifiers.Contains(newident))
521 {
522 AddWarning(String.Format("Multiple assignments to '{0}' at line {1} column {2}; results may differ between LSL and OSSL.", newident, ((SYMBOL)a.kids[0]).Line - 1, ((SYMBOL)a.kids[0]).Position));
523 }
524 identifiers.Add(newident);
525 }
526
527 int index;
528 for (index = 0; index < s.kids.Count; index++)
529 {
530 checkForMultipleAssignments(identifiers, (SYMBOL) s.kids[index]);
531 }
532 }
533
457 /// <summary> 534 /// <summary>
458 /// Generates the code for a ReturnStatement node. 535 /// Generates the code for a ReturnStatement node.
459 /// </summary> 536 /// </summary>
diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs
index 03b2ab3..59d862d 100644
--- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs
@@ -76,6 +76,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
76 private Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> m_positionMap; 76 private Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> m_positionMap;
77 private ICodeConverter LSL_Converter; 77 private ICodeConverter LSL_Converter;
78 78
79 private List<string> m_warnings = new List<string>();
80
79 // private object m_syncy = new object(); 81 // private object m_syncy = new object();
80 82
81 private static CSharpCodeProvider CScodeProvider = new CSharpCodeProvider(); 83 private static CSharpCodeProvider CScodeProvider = new CSharpCodeProvider();
@@ -336,6 +338,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
336 LSL_Converter = (ICodeConverter)new CSCodeGenerator(); 338 LSL_Converter = (ICodeConverter)new CSCodeGenerator();
337 compileScript = LSL_Converter.Convert(Script); 339 compileScript = LSL_Converter.Convert(Script);
338 340
341 // copy converter warnings into our warnings.
342 foreach(string warning in LSL_Converter.GetWarnings())
343 {
344 AddWarning(warning);
345 }
346
339 m_positionMap = ((CSCodeGenerator) LSL_Converter).PositionMap; 347 m_positionMap = ((CSCodeGenerator) LSL_Converter).PositionMap;
340 } 348 }
341 349
@@ -373,6 +381,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
373 return CompileFromDotNetText(compileScript, l, asset); 381 return CompileFromDotNetText(compileScript, l, asset);
374 } 382 }
375 383
384 public string[] GetWarnings()
385 {
386 return m_warnings.ToArray();
387 }
388
389 private void AddWarning(string warning)
390 {
391 if (!m_warnings.Contains(warning))
392 {
393 m_warnings.Add(warning);
394 }
395 }
396
376 private static string CreateJSCompilerScript(string compileScript) 397 private static string CreateJSCompilerScript(string compileScript)
377 { 398 {
378 compileScript = String.Empty + 399 compileScript = String.Empty +
diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/ICodeConverter.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/ICodeConverter.cs
index 28e42da..917000e 100644
--- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/ICodeConverter.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/ICodeConverter.cs
@@ -33,5 +33,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
33 public interface ICodeConverter 33 public interface ICodeConverter
34 { 34 {
35 string Convert(string script); 35 string Convert(string script);
36 string[] GetWarnings();
36 } 37 }
37} 38}
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index 75d0bec..40a6dd1 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
@@ -516,6 +516,38 @@ namespace OpenSim.Region.ScriptEngine.XEngine
516 m_AddingAssemblies[assembly]++; 516 m_AddingAssemblies[assembly]++;
517 } 517 }
518 } 518 }
519
520 string[] warnings = m_Compiler.GetWarnings();
521
522 if (warnings != null && warnings.Length != 0)
523 {
524 if (presence != null && (!postOnRez))
525 presence.ControllingClient.SendAgentAlertMessage("Script saved with warnings, check debug window!", false);
526
527 foreach (string warning in warnings)
528 {
529 try
530 {
531 // DISPLAY WARNING INWORLD
532 string text = "Warning:\n" + warning;
533 if (text.Length > 1000)
534 text = text.Substring(0, 1000);
535 World.SimChat(Utils.StringToBytes(text),
536 ChatTypeEnum.DebugChannel, 2147483647,
537 part.AbsolutePosition,
538 part.Name, part.UUID, false);
539 }
540 catch (Exception e2) // LEGIT: User Scripting
541 {
542 m_log.Error("[XEngine]: " +
543 "Error displaying warning in-world: " +
544 e2.ToString());
545 m_log.Error("[XEngine]: " +
546 "Warning:\r\n" +
547 warning);
548 }
549 }
550 }
519 } 551 }
520 catch (Exception e) 552 catch (Exception e)
521 { 553 {