diff options
author | Melanie Thielker | 2008-09-27 05:31:43 +0000 |
---|---|---|
committer | Melanie Thielker | 2008-09-27 05:31:43 +0000 |
commit | 85068dae60db02b168a29ffd75e1408e30d279e1 (patch) | |
tree | 8389c246a6e9891eb1bf310b85cba19a1668d790 | |
parent | Mantis #2277 (diff) | |
download | opensim-SC-85068dae60db02b168a29ffd75e1408e30d279e1.zip opensim-SC-85068dae60db02b168a29ffd75e1408e30d279e1.tar.gz opensim-SC-85068dae60db02b168a29ffd75e1408e30d279e1.tar.bz2 opensim-SC-85068dae60db02b168a29ffd75e1408e30d279e1.tar.xz |
Add friendly error messages to both engines.
9 files changed, 303 insertions, 109 deletions
diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/EventQueueManager.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/EventQueueManager.cs index 634a12b..4a094e2 100644 --- a/OpenSim/Region/ScriptEngine/DotNetEngine/EventQueueManager.cs +++ b/OpenSim/Region/ScriptEngine/DotNetEngine/EventQueueManager.cs | |||
@@ -139,6 +139,8 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine | |||
139 | public string functionName; | 139 | public string functionName; |
140 | public DetectParams[] llDetectParams; | 140 | public DetectParams[] llDetectParams; |
141 | public object[] param; | 141 | public object[] param; |
142 | public Dictionary<KeyValuePair<int,int>,KeyValuePair<int,int>> | ||
143 | LineMap; | ||
142 | } | 144 | } |
143 | 145 | ||
144 | #endregion | 146 | #endregion |
@@ -349,6 +351,9 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine | |||
349 | return false; | 351 | return false; |
350 | } | 352 | } |
351 | 353 | ||
354 | InstanceData id = m_ScriptEngine.m_ScriptManager.GetScript( | ||
355 | localID, itemID); | ||
356 | |||
352 | // Create a structure and add data | 357 | // Create a structure and add data |
353 | QueueItemStruct QIS = new QueueItemStruct(); | 358 | QueueItemStruct QIS = new QueueItemStruct(); |
354 | QIS.localID = localID; | 359 | QIS.localID = localID; |
@@ -356,6 +361,8 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine | |||
356 | QIS.functionName = FunctionName; | 361 | QIS.functionName = FunctionName; |
357 | QIS.llDetectParams = qParams; | 362 | QIS.llDetectParams = qParams; |
358 | QIS.param = param; | 363 | QIS.param = param; |
364 | if (id != null) | ||
365 | QIS.LineMap = id.LineMap; | ||
359 | 366 | ||
360 | // Add it to queue | 367 | // Add it to queue |
361 | eventQueue.Enqueue(QIS); | 368 | eventQueue.Enqueue(QIS); |
diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/EventQueueThreadClass.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/EventQueueThreadClass.cs index 2d60ed5..16dafdc 100644 --- a/OpenSim/Region/ScriptEngine/DotNetEngine/EventQueueThreadClass.cs +++ b/OpenSim/Region/ScriptEngine/DotNetEngine/EventQueueThreadClass.cs | |||
@@ -27,6 +27,7 @@ | |||
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections; | 29 | using System.Collections; |
30 | using System.Collections.Generic; | ||
30 | using System.Reflection; | 31 | using System.Reflection; |
31 | using System.Text.RegularExpressions; | 32 | using System.Text.RegularExpressions; |
32 | using System.Threading; | 33 | using System.Threading; |
@@ -37,6 +38,7 @@ using OpenSim.Framework; | |||
37 | using OpenSim.Region.Environment.Scenes; | 38 | using OpenSim.Region.Environment.Scenes; |
38 | using OpenSim.Region.Environment.Scenes.Scripting; | 39 | using OpenSim.Region.Environment.Scenes.Scripting; |
39 | using OpenSim.Region.ScriptEngine.Shared; | 40 | using OpenSim.Region.ScriptEngine.Shared; |
41 | using OpenSim.Region.ScriptEngine.Shared.CodeTools; | ||
40 | 42 | ||
41 | namespace OpenSim.Region.ScriptEngine.DotNetEngine | 43 | namespace OpenSim.Region.ScriptEngine.DotNetEngine |
42 | { | 44 | { |
@@ -198,10 +200,6 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine | |||
198 | } | 200 | } |
199 | catch (Exception e) | 201 | catch (Exception e) |
200 | { | 202 | { |
201 | if (lastScriptEngine != null) | ||
202 | lastScriptEngine.Log.Error("[" + ScriptEngineName + | ||
203 | "]: Exception in EventQueueThreadLoop: " + | ||
204 | e.ToString()); | ||
205 | } | 203 | } |
206 | } | 204 | } |
207 | } | 205 | } |
@@ -290,32 +288,32 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine | |||
290 | catch (Exception e) | 288 | catch (Exception e) |
291 | { | 289 | { |
292 | InExecution = false; | 290 | InExecution = false; |
291 | string text = FormatException(e, QIS.LineMap); | ||
292 | |||
293 | // DISPLAY ERROR INWORLD | 293 | // DISPLAY ERROR INWORLD |
294 | string text = "Error executing script function \"" + | ||
295 | QIS.functionName + "\":\r\n"; | ||
296 | 294 | ||
297 | if (e.InnerException != null) | 295 | // if (e.InnerException != null) |
298 | { | 296 | // { |
299 | // Send inner exception | 297 | // // Send inner exception |
300 | string line = " (unknown line)"; | 298 | // string line = " (unknown line)"; |
301 | Regex rx = new Regex(@"SecondLife\.Script\..+[\s:](?<line>\d+)\.?\r?$", RegexOptions.Compiled); | 299 | // Regex rx = new Regex(@"SecondLife\.Script\..+[\s:](?<line>\d+)\.?\r?$", RegexOptions.Compiled); |
302 | if (rx.Match(e.InnerException.ToString()).Success) | 300 | // if (rx.Match(e.InnerException.ToString()).Success) |
303 | line = " (line " + rx.Match(e.InnerException.ToString()).Result("${line}") + ")"; | 301 | // line = " (line " + rx.Match(e.InnerException.ToString()).Result("${line}") + ")"; |
304 | text += e.InnerException.Message.ToString() + line; | 302 | // text += e.InnerException.Message.ToString() + line; |
305 | } | 303 | // } |
306 | else | 304 | // else |
307 | { | 305 | // { |
308 | text += "\r\n"; | 306 | // text += "\r\n"; |
309 | // Send normal | 307 | // // Send normal |
310 | text += e.Message.ToString(); | 308 | // text += e.Message.ToString(); |
311 | } | 309 | // } |
312 | if (KillCurrentScript) | 310 | // if (KillCurrentScript) |
313 | text += "\r\nScript will be deactivated!"; | 311 | // text += "\r\nScript will be deactivated!"; |
314 | 312 | ||
315 | try | 313 | try |
316 | { | 314 | { |
317 | if (text.Length > 1500) | 315 | if (text.Length >= 1100) |
318 | text = text.Substring(0, 1500); | 316 | text = text.Substring(0, 1099); |
319 | IScriptHost m_host = | 317 | IScriptHost m_host = |
320 | m_ScriptEngine.World.GetSceneObjectPart(QIS.localID); | 318 | m_ScriptEngine.World.GetSceneObjectPart(QIS.localID); |
321 | m_ScriptEngine.World.SimChat( | 319 | m_ScriptEngine.World.SimChat( |
@@ -343,10 +341,6 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine | |||
343 | QIS.localID, QIS.itemID); | 341 | QIS.localID, QIS.itemID); |
344 | } | 342 | } |
345 | } | 343 | } |
346 | |||
347 | // Pass it on so it's displayed on the console | ||
348 | // and in the logs (mikem 2008.06.02). | ||
349 | throw e.InnerException; | ||
350 | } | 344 | } |
351 | finally | 345 | finally |
352 | { | 346 | { |
@@ -358,5 +352,45 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine | |||
358 | } | 352 | } |
359 | } | 353 | } |
360 | } | 354 | } |
355 | |||
356 | string FormatException(Exception e, Dictionary<KeyValuePair<int,int>, | ||
357 | KeyValuePair<int,int>> LineMap) | ||
358 | { | ||
359 | string message = "Runtime error:\n" + e.InnerException.StackTrace; | ||
360 | string[] lines = message.Split(new char[] {'\n'}); | ||
361 | |||
362 | foreach (string line in lines) | ||
363 | { | ||
364 | if (line.Contains("SecondLife.Script")) | ||
365 | { | ||
366 | int idx = line.IndexOf(':'); | ||
367 | if (idx != -1) | ||
368 | { | ||
369 | string val = line.Substring(idx+1); | ||
370 | int lineNum = 0; | ||
371 | if (int.TryParse(val, out lineNum)) | ||
372 | { | ||
373 | KeyValuePair<int, int> pos = | ||
374 | Compiler.FindErrorPosition( | ||
375 | lineNum, 0, LineMap); | ||
376 | |||
377 | int scriptLine = pos.Key; | ||
378 | int col = pos.Value; | ||
379 | if (scriptLine == 0) | ||
380 | scriptLine++; | ||
381 | if (col == 0) | ||
382 | col++; | ||
383 | message = string.Format("Runtime error:\n" + | ||
384 | "Line ({0}): {1}", scriptLine - 1, | ||
385 | e.InnerException.Message); | ||
386 | |||
387 | return message; | ||
388 | } | ||
389 | } | ||
390 | } | ||
391 | } | ||
392 | |||
393 | return message; | ||
394 | } | ||
361 | } | 395 | } |
362 | } | 396 | } |
diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptManager.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptManager.cs index 8329805..1c1dcf3 100644 --- a/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptManager.cs +++ b/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptManager.cs | |||
@@ -53,6 +53,8 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine | |||
53 | public int StartParam; | 53 | public int StartParam; |
54 | public AppDomain AppDomain; | 54 | public AppDomain AppDomain; |
55 | public Dictionary<string, IScriptApi> Apis; | 55 | public Dictionary<string, IScriptApi> Apis; |
56 | public Dictionary<KeyValuePair<int,int>, KeyValuePair<int,int>> | ||
57 | LineMap; | ||
56 | } | 58 | } |
57 | 59 | ||
58 | public class ScriptManager | 60 | public class ScriptManager |
@@ -159,6 +161,7 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine | |||
159 | m_scriptEngine.m_AppDomainManager.LoadScript( | 161 | m_scriptEngine.m_AppDomainManager.LoadScript( |
160 | CompiledScriptFile, out id.AppDomain); | 162 | CompiledScriptFile, out id.AppDomain); |
161 | 163 | ||
164 | id.LineMap = LSLCompiler.LineMap(); | ||
162 | id.Script = CompiledScript; | 165 | id.Script = CompiledScript; |
163 | id.Source = Script; | 166 | id.Source = Script; |
164 | id.StartParam = startParam; | 167 | id.StartParam = startParam; |
@@ -212,7 +215,7 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine | |||
212 | try | 215 | try |
213 | { | 216 | { |
214 | // DISPLAY ERROR INWORLD | 217 | // DISPLAY ERROR INWORLD |
215 | string text = "Error compiling script:\r\n" + | 218 | string text = "Error compiling script:\n" + |
216 | e.Message.ToString(); | 219 | e.Message.ToString(); |
217 | if (text.Length > 1100) | 220 | if (text.Length > 1100) |
218 | text = text.Substring(0, 1099); | 221 | text = text.Substring(0, 1099); |
diff --git a/OpenSim/Region/ScriptEngine/Interfaces/ICompiler.cs b/OpenSim/Region/ScriptEngine/Interfaces/ICompiler.cs index efb05d3..6273da9 100644 --- a/OpenSim/Region/ScriptEngine/Interfaces/ICompiler.cs +++ b/OpenSim/Region/ScriptEngine/Interfaces/ICompiler.cs | |||
@@ -33,7 +33,8 @@ namespace OpenSim.Region.ScriptEngine.Interfaces | |||
33 | { | 33 | { |
34 | public interface ICompiler | 34 | public interface ICompiler |
35 | { | 35 | { |
36 | void Configure(IConfig configSource); | 36 | string PerformScriptCompile(string source, string asset); |
37 | void Compile(string text, string outFile, List<IScriptApi> apiList); | 37 | Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> |
38 | LineMap(); | ||
38 | } | 39 | } |
39 | } | 40 | } |
diff --git a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs index 0c807a8..dee7970 100644 --- a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs | |||
@@ -96,5 +96,8 @@ namespace OpenSim.Region.ScriptEngine.Interfaces | |||
96 | void DestroyScriptInstance(); | 96 | void DestroyScriptInstance(); |
97 | 97 | ||
98 | IScriptApi GetApi(string name); | 98 | IScriptApi GetApi(string name); |
99 | |||
100 | Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> LineMap | ||
101 | { get; set; } | ||
99 | } | 102 | } |
100 | } | 103 | } |
diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs index 86d6188..e8f2b71 100644 --- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs +++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs | |||
@@ -89,7 +89,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
89 | ResetCounters(); | 89 | ResetCounters(); |
90 | Parser p = new LSLSyntax(new yyLSLSyntax(), new ErrorHandler(true)); | 90 | Parser p = new LSLSyntax(new yyLSLSyntax(), new ErrorHandler(true)); |
91 | // Obviously this needs to be in a try/except block. | 91 | // Obviously this needs to be in a try/except block. |
92 | LSL2CSCodeTransformer codeTransformer = new LSL2CSCodeTransformer(p.Parse(script)); | 92 | LSL2CSCodeTransformer codeTransformer; |
93 | try | ||
94 | { | ||
95 | codeTransformer = new LSL2CSCodeTransformer(p.Parse(script)); | ||
96 | } | ||
97 | catch (CSToolsException e) | ||
98 | { | ||
99 | string message; | ||
100 | |||
101 | // LL start numbering lines at 0 - geeks! | ||
102 | // | ||
103 | message = String.Format("Line ({0},{1}) {2}", | ||
104 | e.slInfo.lineNumber - 1, | ||
105 | e.slInfo.charPosition - 1, e.Message); | ||
106 | |||
107 | throw new Exception(message); | ||
108 | } | ||
109 | |||
93 | m_astRoot = codeTransformer.Transform(); | 110 | m_astRoot = codeTransformer.Transform(); |
94 | 111 | ||
95 | string retstr = String.Empty; | 112 | string retstr = String.Empty; |
diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs index ec864e1..c6026fb 100644 --- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs +++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs | |||
@@ -38,7 +38,7 @@ using OpenSim.Region.ScriptEngine.Interfaces; | |||
38 | 38 | ||
39 | namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | 39 | namespace OpenSim.Region.ScriptEngine.Shared.CodeTools |
40 | { | 40 | { |
41 | public class Compiler | 41 | public class Compiler : ICompiler |
42 | { | 42 | { |
43 | // private static readonly log4net.ILog m_log | 43 | // private static readonly log4net.ILog m_log |
44 | // = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); | 44 | // = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); |
@@ -255,18 +255,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
255 | /// <returns>Filename to .dll assembly</returns> | 255 | /// <returns>Filename to .dll assembly</returns> |
256 | public string PerformScriptCompile(string Script, string asset) | 256 | public string PerformScriptCompile(string Script, string asset) |
257 | { | 257 | { |
258 | m_positionMap = null; | ||
259 | |||
258 | string OutFile = Path.Combine(ScriptEnginesPath, Path.Combine( | 260 | string OutFile = Path.Combine(ScriptEnginesPath, Path.Combine( |
259 | m_scriptEngine.World.RegionInfo.RegionID.ToString(), | 261 | m_scriptEngine.World.RegionInfo.RegionID.ToString(), |
260 | FilePrefix + "_compiled_" + asset + ".dll")); | 262 | FilePrefix + "_compiled_" + asset + ".dll")); |
261 | // string OutFile = Path.Combine(ScriptEnginesPath, | 263 | // string OutFile = Path.Combine(ScriptEnginesPath, |
262 | // FilePrefix + "_compiled_" + asset + ".dll"); | 264 | // FilePrefix + "_compiled_" + asset + ".dll"); |
263 | 265 | ||
264 | if (File.Exists(OutFile)) | ||
265 | { | ||
266 | m_scriptEngine.Log.DebugFormat("[Compiler] Returning existing assembly for {0}", asset); | ||
267 | return OutFile; | ||
268 | } | ||
269 | |||
270 | if (!Directory.Exists(ScriptEnginesPath)) | 266 | if (!Directory.Exists(ScriptEnginesPath)) |
271 | { | 267 | { |
272 | try | 268 | try |
@@ -327,38 +323,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
327 | compileScript = LSL_Converter.Convert(Script); | 323 | compileScript = LSL_Converter.Convert(Script); |
328 | 324 | ||
329 | m_positionMap = ((CSCodeGenerator) LSL_Converter).PositionMap; | 325 | m_positionMap = ((CSCodeGenerator) LSL_Converter).PositionMap; |
326 | } | ||
330 | 327 | ||
331 | l = enumCompileType.cs; | 328 | // Check this late so the map is generated on sim start |
329 | // | ||
330 | if (File.Exists(OutFile)) | ||
331 | { | ||
332 | m_scriptEngine.Log.DebugFormat("[Compiler] Returning existing assembly for {0}", asset); | ||
333 | return OutFile; | ||
332 | } | 334 | } |
333 | 335 | ||
334 | if (l == enumCompileType.yp) | 336 | if (l == enumCompileType.yp) |
335 | { | 337 | { |
336 | // Its YP, convert it to C# | 338 | // Its YP, convert it to C# |
337 | compileScript = YP_Converter.Convert(Script); | 339 | compileScript = YP_Converter.Convert(Script); |
338 | // We have our own processor now | ||
339 | //l = enumCompileType.cs; | ||
340 | } | ||
341 | |||
342 | // Insert additional assemblies here | ||
343 | |||
344 | //ADAM: Disabled for the moment until it's working right. | ||
345 | bool enableCommanderLSL = false; | ||
346 | |||
347 | if (enableCommanderLSL == true && ((l == enumCompileType.cs) || (l == enumCompileType.yp))) | ||
348 | { | ||
349 | foreach (KeyValuePair<string, | ||
350 | ICommander> com | ||
351 | in m_scriptEngine.World.GetCommanders()) | ||
352 | { | ||
353 | compileScript = com.Value.GenerateRuntimeAPI() + compileScript; | ||
354 | } | ||
355 | } | 340 | } |
356 | 341 | ||
357 | // End of insert | ||
358 | |||
359 | switch (l) | 342 | switch (l) |
360 | { | 343 | { |
361 | case enumCompileType.cs: | 344 | case enumCompileType.cs: |
345 | case enumCompileType.lsl: | ||
362 | compileScript = CreateCSCompilerScript(compileScript); | 346 | compileScript = CreateCSCompilerScript(compileScript); |
363 | break; | 347 | break; |
364 | case enumCompileType.vb: | 348 | case enumCompileType.vb: |
@@ -372,10 +356,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
372 | break; | 356 | break; |
373 | } | 357 | } |
374 | 358 | ||
375 | // m_log.Debug("[ScriptEngine.DotNetEngine]: Preparing to compile the following LSL to C# translated code"); | ||
376 | // m_log.Debug(""); | ||
377 | // m_log.Debug(compileScript); | ||
378 | |||
379 | return CompileFromDotNetText(compileScript, l, asset); | 359 | return CompileFromDotNetText(compileScript, l, asset); |
380 | } | 360 | } |
381 | 361 | ||
@@ -442,26 +422,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
442 | // Output assembly name | 422 | // Output assembly name |
443 | scriptCompileCounter++; | 423 | scriptCompileCounter++; |
444 | string OutFile = Path.Combine(ScriptEnginesPath, Path.Combine( | 424 | string OutFile = Path.Combine(ScriptEnginesPath, Path.Combine( |
445 | m_scriptEngine.World.RegionInfo.RegionID.ToString(), | 425 | m_scriptEngine.World.RegionInfo.RegionID.ToString(), |
446 | FilePrefix + "_compiled_" + asset + ".dll")); | 426 | FilePrefix + "_compiled_" + asset + ".dll")); |
447 | #if DEBUG | ||
448 | // m_scriptEngine.Log.Debug("[Compiler]: Starting compile of \"" + OutFile + "\"."); | ||
449 | #endif | ||
450 | try | 427 | try |
451 | { | 428 | { |
452 | File.Delete(OutFile); | 429 | File.Delete(OutFile); |
453 | } | 430 | } |
454 | catch (Exception e) // NOTLEGIT - Should be just catching FileIOException | 431 | catch (Exception e) // NOTLEGIT - Should be just FileIOException |
455 | { | 432 | { |
456 | //m_scriptEngine.Log.Error("[Compiler]: Unable to delete old existring script-file before writing new. Compile aborted: " + e.ToString()); | 433 | throw new Exception("Unable to delete old existing "+ |
457 | throw new Exception("Unable to delete old existring script-file before writing new. Compile aborted: " + e.ToString()); | 434 | "script-file before writing new. Compile aborted: " + |
435 | e.ToString()); | ||
458 | } | 436 | } |
459 | //string OutFile = Path.Combine("ScriptEngines", "SecondLife.Script.dll"); | ||
460 | 437 | ||
461 | // DEBUG - write source to disk | 438 | // DEBUG - write source to disk |
462 | if (WriteScriptSourceToDebugFile) | 439 | if (WriteScriptSourceToDebugFile) |
463 | { | 440 | { |
464 | string srcFileName = FilePrefix + "_source_" + Path.GetFileNameWithoutExtension(OutFile) + ext; | 441 | string srcFileName = FilePrefix + "_source_" + |
442 | Path.GetFileNameWithoutExtension(OutFile) + ext; | ||
465 | try | 443 | try |
466 | { | 444 | { |
467 | File.WriteAllText(Path.Combine(Path.Combine( | 445 | File.WriteAllText(Path.Combine(Path.Combine( |
@@ -469,9 +447,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
469 | m_scriptEngine.World.RegionInfo.RegionID.ToString()), | 447 | m_scriptEngine.World.RegionInfo.RegionID.ToString()), |
470 | srcFileName), Script); | 448 | srcFileName), Script); |
471 | } | 449 | } |
472 | catch (Exception ex) // NOTLEGIT - Should be just catching FileIOException | 450 | catch (Exception ex) //NOTLEGIT - Should be just FileIOException |
473 | { | 451 | { |
474 | m_scriptEngine.Log.Error("[Compiler]: Exception while trying to write script source to file \"" + srcFileName + "\": " + ex.ToString()); | 452 | m_scriptEngine.Log.Error("[Compiler]: Exception while "+ |
453 | "trying to write script source to file \"" + | ||
454 | srcFileName + "\": " + ex.ToString()); | ||
475 | } | 455 | } |
476 | } | 456 | } |
477 | 457 | ||
@@ -480,22 +460,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
480 | 460 | ||
481 | parameters.IncludeDebugInformation = true; | 461 | parameters.IncludeDebugInformation = true; |
482 | 462 | ||
483 | // Add all available assemblies | 463 | string rootPath = |
484 | // foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies()) | 464 | Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory); |
485 | // { | ||
486 | // Console.WriteLine("Adding assembly: " + asm.Location); | ||
487 | // parameters.ReferencedAssemblies.Add(asm.Location); | ||
488 | // } | ||
489 | 465 | ||
490 | string rootPath = Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory); | 466 | parameters.ReferencedAssemblies.Add(Path.Combine(rootPath, |
491 | // string rootPathSE = Path.GetDirectoryName(GetType().Assembly.Location); | 467 | "OpenSim.Region.ScriptEngine.Shared.dll")); |
492 | //Console.WriteLine("Assembly location: " + rootPath); | 468 | parameters.ReferencedAssemblies.Add(Path.Combine(rootPath, |
493 | parameters.ReferencedAssemblies.Add(Path.Combine(rootPath, "OpenSim.Region.ScriptEngine.Shared.dll")); | 469 | "OpenSim.Region.ScriptEngine.Shared.Api.Runtime.dll")); |
494 | parameters.ReferencedAssemblies.Add(Path.Combine(rootPath, "OpenSim.Region.ScriptEngine.Shared.Api.Runtime.dll")); | ||
495 | 470 | ||
496 | if (lang == enumCompileType.yp) | 471 | if (lang == enumCompileType.yp) |
497 | { | 472 | { |
498 | parameters.ReferencedAssemblies.Add(Path.Combine(rootPath, "OpenSim.Region.ScriptEngine.Shared.YieldProlog.dll")); | 473 | parameters.ReferencedAssemblies.Add(Path.Combine(rootPath, |
474 | "OpenSim.Region.ScriptEngine.Shared.YieldProlog.dll")); | ||
499 | } | 475 | } |
500 | 476 | ||
501 | parameters.GenerateExecutable = false; | 477 | parameters.GenerateExecutable = false; |
@@ -504,24 +480,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
504 | //parameters.WarningLevel = 1; // Should be 4? | 480 | //parameters.WarningLevel = 1; // Should be 4? |
505 | parameters.TreatWarningsAsErrors = false; | 481 | parameters.TreatWarningsAsErrors = false; |
506 | 482 | ||
507 | //Console.WriteLine(Script); | ||
508 | CompilerResults results; | 483 | CompilerResults results; |
509 | switch (lang) | 484 | switch (lang) |
510 | { | 485 | { |
511 | case enumCompileType.vb: | 486 | case enumCompileType.vb: |
512 | results = VBcodeProvider.CompileAssemblyFromSource(parameters, Script); | 487 | results = VBcodeProvider.CompileAssemblyFromSource( |
488 | parameters, Script); | ||
513 | break; | 489 | break; |
514 | case enumCompileType.cs: | 490 | case enumCompileType.cs: |
515 | results = CScodeProvider.CompileAssemblyFromSource(parameters, Script); | 491 | case enumCompileType.lsl: |
492 | results = CScodeProvider.CompileAssemblyFromSource( | ||
493 | parameters, Script); | ||
516 | break; | 494 | break; |
517 | case enumCompileType.js: | 495 | case enumCompileType.js: |
518 | results = JScodeProvider.CompileAssemblyFromSource(parameters, Script); | 496 | results = JScodeProvider.CompileAssemblyFromSource( |
497 | parameters, Script); | ||
519 | break; | 498 | break; |
520 | case enumCompileType.yp: | 499 | case enumCompileType.yp: |
521 | results = YPcodeProvider.CompileAssemblyFromSource(parameters, Script); | 500 | results = YPcodeProvider.CompileAssemblyFromSource( |
501 | parameters, Script); | ||
522 | break; | 502 | break; |
523 | default: | 503 | default: |
524 | throw new Exception("Compiler is not able to recongnize language type \"" + lang.ToString() + "\""); | 504 | throw new Exception("Compiler is not able to recongnize "+ |
505 | "language type \"" + lang.ToString() + "\""); | ||
525 | } | 506 | } |
526 | 507 | ||
527 | // Check result | 508 | // Check result |
@@ -530,11 +511,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
530 | // | 511 | // |
531 | // WARNINGS AND ERRORS | 512 | // WARNINGS AND ERRORS |
532 | // | 513 | // |
514 | int display = 5; | ||
533 | if (results.Errors.Count > 0) | 515 | if (results.Errors.Count > 0) |
534 | { | 516 | { |
535 | string errtext = String.Empty; | 517 | string errtext = String.Empty; |
536 | foreach (CompilerError CompErr in results.Errors) | 518 | foreach (CompilerError CompErr in results.Errors) |
537 | { | 519 | { |
520 | // Show 5 errors max | ||
521 | // | ||
522 | if (display <= 0) | ||
523 | break; | ||
524 | display--; | ||
525 | |||
538 | string severity = "Error"; | 526 | string severity = "Error"; |
539 | if ( CompErr.IsWarning ) | 527 | if ( CompErr.IsWarning ) |
540 | { | 528 | { |
@@ -543,22 +531,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
543 | 531 | ||
544 | KeyValuePair<int, int> lslPos; | 532 | KeyValuePair<int, int> lslPos; |
545 | 533 | ||
546 | try | 534 | lslPos = FindErrorPosition(CompErr.Line, CompErr.Column); |
547 | { | 535 | |
548 | lslPos = m_positionMap[new KeyValuePair<int, int>(CompErr.Line, CompErr.Column)]; | 536 | string text = CompErr.ErrorText; |
549 | } | 537 | |
550 | catch (KeyNotFoundException) // we don't have this line/column mapped | 538 | // Use LSL type names |
551 | { | 539 | if (lang == enumCompileType.lsl) |
552 | m_scriptEngine.Log.Debug(String.Format("[Compiler]: Lookup of C# line {0}, column {1} failed.", CompErr.Line, CompErr.Column)); | 540 | text = ReplaceTypes(CompErr.ErrorText); |
553 | lslPos = new KeyValuePair<int, int>(-CompErr.Line, -CompErr.Column); | ||
554 | } | ||
555 | 541 | ||
556 | // The Second Life viewer's script editor begins | 542 | // The Second Life viewer's script editor begins |
557 | // countingn lines and columns at 0, so we subtract 1. | 543 | // countingn lines and columns at 0, so we subtract 1. |
558 | errtext += String.Format("Line {0}, column {1}, {4} Number: {2}, '{3}'\r\n", lslPos.Key - 1, lslPos.Value - 1, CompErr.ErrorNumber, CompErr.ErrorText, severity); | 544 | errtext += String.Format("Line ({0},{1}): {4} {2}: {3}\n", |
545 | lslPos.Key - 1, lslPos.Value - 1, | ||
546 | CompErr.ErrorNumber, text, severity); | ||
559 | } | 547 | } |
560 | 548 | ||
561 | Console.WriteLine("[COMPILER MESSAGES]: " + errtext); | ||
562 | if (!File.Exists(OutFile)) | 549 | if (!File.Exists(OutFile)) |
563 | { | 550 | { |
564 | throw new Exception(errtext); | 551 | throw new Exception(errtext); |
@@ -574,8 +561,100 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
574 | errtext += "No compile error. But not able to locate compiled file."; | 561 | errtext += "No compile error. But not able to locate compiled file."; |
575 | throw new Exception(errtext); | 562 | throw new Exception(errtext); |
576 | } | 563 | } |
577 | m_scriptEngine.Log.DebugFormat("[Compiler] Compiled new assembly for {0}", asset); | 564 | m_scriptEngine.Log.DebugFormat("[Compiler] Compiled new assembly "+ |
565 | "for {0}", asset); | ||
578 | return OutFile; | 566 | return OutFile; |
579 | } | 567 | } |
568 | |||
569 | public KeyValuePair<int, int> FindErrorPosition(int line, int col) | ||
570 | { | ||
571 | return FindErrorPosition(line, col, m_positionMap); | ||
572 | } | ||
573 | |||
574 | private class kvpSorter : IComparer<KeyValuePair<int,int>> | ||
575 | { | ||
576 | public int Compare(KeyValuePair<int,int> a, | ||
577 | KeyValuePair<int,int> b) | ||
578 | { | ||
579 | return a.Key.CompareTo(b.Key); | ||
580 | } | ||
581 | } | ||
582 | |||
583 | public static KeyValuePair<int, int> FindErrorPosition(int line, | ||
584 | int col, Dictionary<KeyValuePair<int, int>, | ||
585 | KeyValuePair<int, int>> positionMap) | ||
586 | { | ||
587 | if (positionMap == null || positionMap.Count == 0) | ||
588 | return new KeyValuePair<int, int>(line, col); | ||
589 | |||
590 | KeyValuePair<int, int> ret = new KeyValuePair<int, int>(); | ||
591 | |||
592 | if (positionMap.TryGetValue(new KeyValuePair<int, int>(line, col), | ||
593 | out ret)) | ||
594 | return ret; | ||
595 | |||
596 | List<KeyValuePair<int,int>> sorted = | ||
597 | new List<KeyValuePair<int,int>>(positionMap.Keys); | ||
598 | |||
599 | sorted.Sort(new kvpSorter()); | ||
600 | |||
601 | int l = 1; | ||
602 | int c = 1; | ||
603 | |||
604 | foreach (KeyValuePair<int, int> cspos in sorted) | ||
605 | { | ||
606 | if (cspos.Key >= line) | ||
607 | { | ||
608 | if (cspos.Key > line) | ||
609 | return new KeyValuePair<int, int>(l, c); | ||
610 | if (cspos.Value > col) | ||
611 | return new KeyValuePair<int, int>(l, c); | ||
612 | c = cspos.Value; | ||
613 | if (c == 0) | ||
614 | c++; | ||
615 | } | ||
616 | else | ||
617 | { | ||
618 | l = cspos.Key; | ||
619 | } | ||
620 | } | ||
621 | return new KeyValuePair<int, int>(l, c); | ||
622 | } | ||
623 | |||
624 | string ReplaceTypes(string message) | ||
625 | { | ||
626 | message = message.Replace( | ||
627 | "OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString", | ||
628 | "string"); | ||
629 | |||
630 | message = message.Replace( | ||
631 | "OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger", | ||
632 | "integer"); | ||
633 | |||
634 | message = message.Replace( | ||
635 | "OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat", | ||
636 | "float"); | ||
637 | |||
638 | message = message.Replace( | ||
639 | "OpenSim.Region.ScriptEngine.Shared.LSL_Types.list", | ||
640 | "list"); | ||
641 | |||
642 | return message; | ||
643 | } | ||
644 | |||
645 | public Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> | ||
646 | LineMap() | ||
647 | { | ||
648 | if (m_positionMap == null) | ||
649 | return null; | ||
650 | |||
651 | Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> ret = | ||
652 | new Dictionary<KeyValuePair<int,int>, KeyValuePair<int, int>>(); | ||
653 | |||
654 | foreach (KeyValuePair<int, int> kvp in m_positionMap.Keys) | ||
655 | ret.Add(kvp, m_positionMap[kvp]); | ||
656 | |||
657 | return ret; | ||
658 | } | ||
580 | } | 659 | } |
581 | } | 660 | } |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index c8d60af..aa9ace4 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs | |||
@@ -80,6 +80,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
80 | private int m_ControlEventsInQueue = 0; | 80 | private int m_ControlEventsInQueue = 0; |
81 | private int m_LastControlLevel = 0; | 81 | private int m_LastControlLevel = 0; |
82 | private bool m_CollisionInQueue = false; | 82 | private bool m_CollisionInQueue = false; |
83 | private Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> | ||
84 | m_LineMap; | ||
85 | |||
86 | public Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> | ||
87 | LineMap | ||
88 | { | ||
89 | get { return m_LineMap; } | ||
90 | set { m_LineMap = value; } | ||
91 | } | ||
83 | 92 | ||
84 | private Dictionary<string,IScriptApi> m_Apis = new Dictionary<string,IScriptApi>(); | 93 | private Dictionary<string,IScriptApi> m_Apis = new Dictionary<string,IScriptApi>(); |
85 | 94 | ||
@@ -628,7 +637,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
628 | try | 637 | try |
629 | { | 638 | { |
630 | // DISPLAY ERROR INWORLD | 639 | // DISPLAY ERROR INWORLD |
631 | string text = "Runtime error:\n" + e.InnerException.ToString(); | 640 | string text = FormatException(e); |
641 | |||
632 | if (text.Length > 1000) | 642 | if (text.Length > 1000) |
633 | text = text.Substring(0, 1000); | 643 | text = text.Substring(0, 1000); |
634 | m_Engine.World.SimChat(Utils.StringToBytes(text), | 644 | m_Engine.World.SimChat(Utils.StringToBytes(text), |
@@ -812,5 +822,44 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
812 | { | 822 | { |
813 | return String.Format("{0} {1} on {2}", m_ScriptName, m_ItemID, m_PrimName); | 823 | return String.Format("{0} {1} on {2}", m_ScriptName, m_ItemID, m_PrimName); |
814 | } | 824 | } |
825 | |||
826 | string FormatException(Exception e) | ||
827 | { | ||
828 | string message = "Runtime error:\n" + e.InnerException.StackTrace; | ||
829 | string[] lines = message.Split(new char[] {'\n'}); | ||
830 | |||
831 | foreach (string line in lines) | ||
832 | { | ||
833 | if (line.Contains("SecondLife.Script")) | ||
834 | { | ||
835 | int idx = line.IndexOf(':'); | ||
836 | if (idx != -1) | ||
837 | { | ||
838 | string val = line.Substring(idx+1); | ||
839 | int lineNum = 0; | ||
840 | if (int.TryParse(val, out lineNum)) | ||
841 | { | ||
842 | KeyValuePair<int, int> pos = | ||
843 | Compiler.FindErrorPosition( | ||
844 | lineNum, 0, LineMap); | ||
845 | |||
846 | int scriptLine = pos.Key; | ||
847 | int col = pos.Value; | ||
848 | if (scriptLine == 0) | ||
849 | scriptLine++; | ||
850 | if (col == 0) | ||
851 | col++; | ||
852 | message = string.Format("Runtime error:\n" + | ||
853 | "Line ({0}): {1}", scriptLine - 1, | ||
854 | e.InnerException.Message); | ||
855 | |||
856 | return message; | ||
857 | } | ||
858 | } | ||
859 | } | ||
860 | } | ||
861 | |||
862 | return message; | ||
863 | } | ||
815 | } | 864 | } |
816 | } | 865 | } |
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index a37cbb4..6bafd69 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | |||
@@ -59,7 +59,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
59 | private int m_MaxScriptQueue; | 59 | private int m_MaxScriptQueue; |
60 | private Scene m_Scene; | 60 | private Scene m_Scene; |
61 | private IConfig m_ScriptConfig; | 61 | private IConfig m_ScriptConfig; |
62 | private Compiler m_Compiler; | 62 | private ICompiler m_Compiler; |
63 | private int m_MinThreads; | 63 | private int m_MinThreads; |
64 | private int m_MaxThreads ; | 64 | private int m_MaxThreads ; |
65 | private int m_IdleTimeout; | 65 | private int m_IdleTimeout; |
@@ -510,7 +510,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
510 | try | 510 | try |
511 | { | 511 | { |
512 | // DISPLAY ERROR INWORLD | 512 | // DISPLAY ERROR INWORLD |
513 | string text = "Error compiling script:\r\n" + e.Message.ToString(); | 513 | string text = "Error compiling script:\n" + e.ToString(); |
514 | if (text.Length > 1000) | 514 | if (text.Length > 1000) |
515 | text = text.Substring(0, 1000); | 515 | text = text.Substring(0, 1000); |
516 | World.SimChat(Utils.StringToBytes(text), | 516 | World.SimChat(Utils.StringToBytes(text), |
@@ -585,6 +585,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
585 | part.ParentGroup.RootPart.Name, item.Name); | 585 | part.ParentGroup.RootPart.Name, item.Name); |
586 | 586 | ||
587 | instance.AppDomain = appDomain; | 587 | instance.AppDomain = appDomain; |
588 | instance.LineMap = m_Compiler.LineMap(); | ||
588 | 589 | ||
589 | m_Scripts[itemID] = instance; | 590 | m_Scripts[itemID] = instance; |
590 | } | 591 | } |