diff options
author | Charles Krinke | 2009-02-23 02:43:51 +0000 |
---|---|---|
committer | Charles Krinke | 2009-02-23 02:43:51 +0000 |
commit | 08c76989a719803e4cb7c5391bc864046bba31f2 (patch) | |
tree | b62e6288ba9ce024a5020d0f302a059e44ba457e /OpenSim/Region/ScriptEngine/Shared | |
parent | A little bit more tweaking with appearance. Now passing both the wearables an... (diff) | |
download | opensim-SC_OLD-08c76989a719803e4cb7c5391bc864046bba31f2.zip opensim-SC_OLD-08c76989a719803e4cb7c5391bc864046bba31f2.tar.gz opensim-SC_OLD-08c76989a719803e4cb7c5391bc864046bba31f2.tar.bz2 opensim-SC_OLD-08c76989a719803e4cb7c5391bc864046bba31f2.tar.xz |
Mantis#3187. Thank you kindly, DoranZemlja for a patch that:
Adds a warning for an LSL construct that exploits a
popular list memory saving hack.
Diffstat (limited to 'OpenSim/Region/ScriptEngine/Shared')
3 files changed, 99 insertions, 0 deletions
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 | } |