diff options
Diffstat (limited to 'OpenSim/Region/ScriptEngine')
19 files changed, 2058 insertions, 3776 deletions
diff --git a/OpenSim/Region/ScriptEngine/YEngine/MMRInternalFuncDict.cs b/OpenSim/Region/ScriptEngine/YEngine/MMRInternalFuncDict.cs index 5d1cbc0..ca7c372 100644 --- a/OpenSim/Region/ScriptEngine/YEngine/MMRInternalFuncDict.cs +++ b/OpenSim/Region/ScriptEngine/YEngine/MMRInternalFuncDict.cs | |||
@@ -35,7 +35,6 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
35 | 35 | ||
36 | public class InternalFuncDict: VarDict | 36 | public class InternalFuncDict: VarDict |
37 | { | 37 | { |
38 | |||
39 | /** | 38 | /** |
40 | * @brief build dictionary of internal functions from an interface. | 39 | * @brief build dictionary of internal functions from an interface. |
41 | * @param iface = interface with function definitions | 40 | * @param iface = interface with function definitions |
@@ -46,27 +45,20 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
46 | public InternalFuncDict(Type iface, bool inclSig) | 45 | public InternalFuncDict(Type iface, bool inclSig) |
47 | : base(false) | 46 | : base(false) |
48 | { | 47 | { |
49 | /* | 48 | // Loop through list of all methods declared in the interface. |
50 | * Loop through list of all methods declared in the interface. | ||
51 | */ | ||
52 | System.Reflection.MethodInfo[] ifaceMethods = iface.GetMethods(); | 49 | System.Reflection.MethodInfo[] ifaceMethods = iface.GetMethods(); |
53 | foreach(System.Reflection.MethodInfo ifaceMethod in ifaceMethods) | 50 | foreach(System.Reflection.MethodInfo ifaceMethod in ifaceMethods) |
54 | { | 51 | { |
55 | string key = ifaceMethod.Name; | 52 | string key = ifaceMethod.Name; |
56 | 53 | ||
57 | /* | 54 | // Only do ones that begin with lower-case letters... |
58 | * Only do ones that begin with lower-case letters... | 55 | // as any others can't be referenced by scripts |
59 | * as any others can't be referenced by scripts | ||
60 | */ | ||
61 | if((key[0] < 'a') || (key[0] > 'z')) | 56 | if((key[0] < 'a') || (key[0] > 'z')) |
62 | continue; | 57 | continue; |
63 | 58 | ||
64 | try | 59 | try |
65 | { | 60 | { |
66 | 61 | // Create a corresponding TokenDeclVar struct. | |
67 | /* | ||
68 | * Create a corresponding TokenDeclVar struct. | ||
69 | */ | ||
70 | System.Reflection.ParameterInfo[] parameters = ifaceMethod.GetParameters(); | 62 | System.Reflection.ParameterInfo[] parameters = ifaceMethod.GetParameters(); |
71 | TokenArgDecl argDecl = new TokenArgDecl(null); | 63 | TokenArgDecl argDecl = new TokenArgDecl(null); |
72 | for(int i = 0; i < parameters.Length; i++) | 64 | for(int i = 0; i < parameters.Length; i++) |
@@ -81,9 +73,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
81 | declFunc.retType = TokenType.FromSysType(null, ifaceMethod.ReturnType); | 73 | declFunc.retType = TokenType.FromSysType(null, ifaceMethod.ReturnType); |
82 | declFunc.argDecl = argDecl; | 74 | declFunc.argDecl = argDecl; |
83 | 75 | ||
84 | /* | 76 | // Add the TokenDeclVar struct to the dictionary. |
85 | * Add the TokenDeclVar struct to the dictionary. | ||
86 | */ | ||
87 | this.AddEntry(declFunc); | 77 | this.AddEntry(declFunc); |
88 | } | 78 | } |
89 | catch(Exception except) | 79 | catch(Exception except) |
diff --git a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCodeGen.cs b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCodeGen.cs index a480263..ea86b0b 100644 --- a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCodeGen.cs +++ b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCodeGen.cs | |||
@@ -77,9 +77,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
77 | public static Type xmrInstSuperType = null; // typeof whatever is actually malloc'd for script instances | 77 | public static Type xmrInstSuperType = null; // typeof whatever is actually malloc'd for script instances |
78 | // - must inherit from XMRInstAbstract | 78 | // - must inherit from XMRInstAbstract |
79 | 79 | ||
80 | /* | 80 | // Static tables that there only needs to be one copy of for all. |
81 | * Static tables that there only needs to be one copy of for all. | ||
82 | */ | ||
83 | private static VarDict legalEventHandlers = CreateLegalEventHandlers(); | 81 | private static VarDict legalEventHandlers = CreateLegalEventHandlers(); |
84 | private static CompValu[] zeroCompValus = new CompValu[0]; | 82 | private static CompValu[] zeroCompValus = new CompValu[0]; |
85 | private static TokenType[] zeroArgs = new TokenType[0]; | 83 | private static TokenType[] zeroArgs = new TokenType[0]; |
@@ -161,20 +159,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
161 | 159 | ||
162 | public static bool CodeGen(TokenScript tokenScript, BinaryWriter objFileWriter, string sourceHash) | 160 | public static bool CodeGen(TokenScript tokenScript, BinaryWriter objFileWriter, string sourceHash) |
163 | { | 161 | { |
164 | /* | 162 | // Run compiler such that it has a 'this' context for convenience. |
165 | * Run compiler such that it has a 'this' context for convenience. | ||
166 | */ | ||
167 | ScriptCodeGen scg = new ScriptCodeGen(tokenScript, objFileWriter, sourceHash); | 163 | ScriptCodeGen scg = new ScriptCodeGen(tokenScript, objFileWriter, sourceHash); |
168 | 164 | ||
169 | /* | 165 | // Return pointer to resultant script object code. |
170 | * Return pointer to resultant script object code. | ||
171 | */ | ||
172 | return !scg.youveAnError; | 166 | return !scg.youveAnError; |
173 | } | 167 | } |
174 | 168 | ||
175 | /* | 169 | // There is one set of these variables for each script being compiled. |
176 | * There is one set of these variables for each script being compiled. | ||
177 | */ | ||
178 | private bool mightGetHere = false; | 170 | private bool mightGetHere = false; |
179 | private bool youveAnError = false; | 171 | private bool youveAnError = false; |
180 | private BreakContTarg curBreakTarg = null; | 172 | private BreakContTarg curBreakTarg = null; |
@@ -246,24 +238,18 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
246 | */ | 238 | */ |
247 | private void PerformCompilation() | 239 | private void PerformCompilation() |
248 | { | 240 | { |
249 | /* | 241 | // errorMessageToken is used only when the given token doesn't have a |
250 | * errorMessageToken is used only when the given token doesn't have a | 242 | // output delegate associated with it such as for backend API functions |
251 | * output delegate associated with it such as for backend API functions | 243 | // that only have one copy for the whole system. It is kept up-to-date |
252 | * that only have one copy for the whole system. It is kept up-to-date | 244 | // approximately but is rarely needed so going to assume it doesn't have |
253 | * approximately but is rarely needed so going to assume it doesn't have | 245 | // to be exact. |
254 | * to be exact. | ||
255 | */ | ||
256 | errorMessageToken = tokenScript; | 246 | errorMessageToken = tokenScript; |
257 | 247 | ||
258 | /* | 248 | // Set up dictionary to translate state names to their index number. |
259 | * Set up dictionary to translate state names to their index number. | ||
260 | */ | ||
261 | stateIndices = new Dictionary<string, int>(); | 249 | stateIndices = new Dictionary<string, int>(); |
262 | 250 | ||
263 | /* | 251 | // Assign each state its own unique index. |
264 | * Assign each state its own unique index. | 252 | // The default state gets 0. |
265 | * The default state gets 0. | ||
266 | */ | ||
267 | nStates = 0; | 253 | nStates = 0; |
268 | tokenScript.defaultState.body.index = nStates++; | 254 | tokenScript.defaultState.body.index = nStates++; |
269 | stateIndices.Add("default", 0); | 255 | stateIndices.Add("default", 0); |
@@ -274,9 +260,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
274 | stateIndices.Add(declState.name.val, declState.body.index); | 260 | stateIndices.Add(declState.name.val, declState.body.index); |
275 | } | 261 | } |
276 | 262 | ||
277 | /* | 263 | // Make up an array that translates state indices to state name strings. |
278 | * Make up an array that translates state indices to state name strings. | ||
279 | */ | ||
280 | stateNames = new string[nStates]; | 264 | stateNames = new string[nStates]; |
281 | stateNames[0] = "default"; | 265 | stateNames[0] = "default"; |
282 | foreach(KeyValuePair<string, TokenDeclState> kvp in tokenScript.states) | 266 | foreach(KeyValuePair<string, TokenDeclState> kvp in tokenScript.states) |
@@ -285,11 +269,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
285 | stateNames[declState.body.index] = declState.name.val; | 269 | stateNames[declState.body.index] = declState.name.val; |
286 | } | 270 | } |
287 | 271 | ||
288 | /* | 272 | // Make sure we have delegates for all script-defined functions and methods, |
289 | * Make sure we have delegates for all script-defined functions and methods, | 273 | // creating anonymous ones if needed. Note that this includes all property |
290 | * creating anonymous ones if needed. Note that this includes all property | 274 | // getter and setter methods. |
291 | * getter and setter methods. | ||
292 | */ | ||
293 | foreach(TokenDeclVar declFunc in tokenScript.variablesStack) | 275 | foreach(TokenDeclVar declFunc in tokenScript.variablesStack) |
294 | { | 276 | { |
295 | if(declFunc.retType != null) | 277 | if(declFunc.retType != null) |
@@ -347,42 +329,29 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
347 | } | 329 | } |
348 | } | 330 | } |
349 | 331 | ||
350 | /* | 332 | // No more types can be defined or we won't be able to write them to the object file. |
351 | * No more types can be defined or we won't be able to write them to the object file. | ||
352 | */ | ||
353 | tokenScript.sdSrcTypesSeal(); | 333 | tokenScript.sdSrcTypesSeal(); |
354 | 334 | ||
355 | /* | 335 | // Assign all global variables a slot in its corresponding XMRInstance.gbl<Type>s[] array. |
356 | * Assign all global variables a slot in its corresponding XMRInstance.gbl<Type>s[] array. | 336 | // Global variables are simply elements of those arrays at runtime, thus we don't need to create |
357 | * Global variables are simply elements of those arrays at runtime, thus we don't need to create | 337 | // an unique class for each script, we can just use XMRInstance as is for all. |
358 | * an unique class for each script, we can just use XMRInstance as is for all. | ||
359 | */ | ||
360 | foreach(TokenDeclVar declVar in tokenScript.variablesStack) | 338 | foreach(TokenDeclVar declVar in tokenScript.variablesStack) |
361 | { | 339 | { |
362 | 340 | // Omit 'constant' variables as they are coded inline so don't need a slot. | |
363 | /* | ||
364 | * Omit 'constant' variables as they are coded inline so don't need a slot. | ||
365 | */ | ||
366 | if(declVar.constant) | 341 | if(declVar.constant) |
367 | continue; | 342 | continue; |
368 | 343 | ||
369 | /* | 344 | // Do functions later. |
370 | * Do functions later. | ||
371 | */ | ||
372 | if(declVar.retType != null) | 345 | if(declVar.retType != null) |
373 | continue; | 346 | continue; |
374 | 347 | ||
375 | /* | 348 | // Create entry in the value array for the variable or property. |
376 | * Create entry in the value array for the variable or property. | ||
377 | */ | ||
378 | declVar.location = new CompValuGlobalVar(declVar, glblSizes); | 349 | declVar.location = new CompValuGlobalVar(declVar, glblSizes); |
379 | } | 350 | } |
380 | 351 | ||
381 | /* | 352 | // Likewise for any static fields in script-defined classes. |
382 | * Likewise for any static fields in script-defined classes. | 353 | // They can be referenced anywhere by <typename>.<fieldname>, see |
383 | * They can be referenced anywhere by <typename>.<fieldname>, see | 354 | // GenerateFromLValSField(). |
384 | * GenerateFromLValSField(). | ||
385 | */ | ||
386 | foreach(TokenDeclSDType sdType in tokenScript.sdSrcTypesValues) | 355 | foreach(TokenDeclSDType sdType in tokenScript.sdSrcTypesValues) |
387 | { | 356 | { |
388 | if(!(sdType is TokenDeclSDTypeClass)) | 357 | if(!(sdType is TokenDeclSDTypeClass)) |
@@ -391,40 +360,29 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
391 | 360 | ||
392 | foreach(TokenDeclVar declVar in sdtClass.members) | 361 | foreach(TokenDeclVar declVar in sdtClass.members) |
393 | { | 362 | { |
394 | 363 | // Omit 'constant' variables as they are coded inline so don't need a slot. | |
395 | /* | ||
396 | * Omit 'constant' variables as they are coded inline so don't need a slot. | ||
397 | */ | ||
398 | if(declVar.constant) | 364 | if(declVar.constant) |
399 | continue; | 365 | continue; |
400 | 366 | ||
401 | /* | 367 | // Do methods later. |
402 | * Do methods later. | ||
403 | */ | ||
404 | if(declVar.retType != null) | 368 | if(declVar.retType != null) |
405 | continue; | 369 | continue; |
406 | 370 | ||
407 | /* | 371 | // Ignore non-static fields for now. |
408 | * Ignore non-static fields for now. | 372 | // They get assigned below. |
409 | * They get assigned below. | ||
410 | */ | ||
411 | if((declVar.sdtFlags & ScriptReduce.SDT_STATIC) == 0) | 373 | if((declVar.sdtFlags & ScriptReduce.SDT_STATIC) == 0) |
412 | continue; | 374 | continue; |
413 | 375 | ||
414 | /* | 376 | // Create entry in the value array for the static field or static property. |
415 | * Create entry in the value array for the static field or static property. | ||
416 | */ | ||
417 | declVar.location = new CompValuGlobalVar(declVar, glblSizes); | 377 | declVar.location = new CompValuGlobalVar(declVar, glblSizes); |
418 | } | 378 | } |
419 | } | 379 | } |
420 | 380 | ||
421 | /* | 381 | // Assign slots for all interface method prototypes. |
422 | * Assign slots for all interface method prototypes. | 382 | // These indices are used to index the array of delegates that holds a class' implementation of an |
423 | * These indices are used to index the array of delegates that holds a class' implementation of an | 383 | // interface. |
424 | * interface. | 384 | // Properties do not get a slot because they aren't called as such. But their corresponding |
425 | * Properties do not get a slot because they aren't called as such. But their corresponding | 385 | // <name>$get() and <name>$set(<type>) methods are in the table and they each get a slot. |
426 | * <name>$get() and <name>$set(<type>) methods are in the table and they each get a slot. | ||
427 | */ | ||
428 | foreach(TokenDeclSDType sdType in tokenScript.sdSrcTypesValues) | 386 | foreach(TokenDeclSDType sdType in tokenScript.sdSrcTypesValues) |
429 | { | 387 | { |
430 | if(!(sdType is TokenDeclSDTypeInterface)) | 388 | if(!(sdType is TokenDeclSDTypeInterface)) |
@@ -440,9 +398,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
440 | } | 398 | } |
441 | } | 399 | } |
442 | 400 | ||
443 | /* | 401 | // Assign slots for all instance fields and virtual methods of script-defined classes. |
444 | * Assign slots for all instance fields and virtual methods of script-defined classes. | ||
445 | */ | ||
446 | int maxExtends = tokenScript.sdSrcTypesCount; | 402 | int maxExtends = tokenScript.sdSrcTypesCount; |
447 | bool didOne; | 403 | bool didOne; |
448 | do | 404 | do |
@@ -456,10 +412,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
456 | if(sdtClass.slotsAssigned) | 412 | if(sdtClass.slotsAssigned) |
457 | continue; | 413 | continue; |
458 | 414 | ||
459 | /* | 415 | // If this class extends another, the extended class has to already |
460 | * If this class extends another, the extended class has to already | 416 | // be set up, because our slots add on to the end of the extended class. |
461 | * be set up, because our slots add on to the end of the extended class. | ||
462 | */ | ||
463 | TokenDeclSDTypeClass extends = sdtClass.extends; | 417 | TokenDeclSDTypeClass extends = sdtClass.extends; |
464 | if(extends != null) | 418 | if(extends != null) |
465 | { | 419 | { |
@@ -483,10 +437,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
483 | } | 437 | } |
484 | } | 438 | } |
485 | 439 | ||
486 | /* | 440 | // Extended class's slots all assigned, assign our instance fields |
487 | * Extended class's slots all assigned, assign our instance fields | 441 | // slots in the XMRSDTypeClObj arrays. |
488 | * slots in the XMRSDTypeClObj arrays. | ||
489 | */ | ||
490 | foreach(TokenDeclVar declVar in sdtClass.members) | 442 | foreach(TokenDeclVar declVar in sdtClass.members) |
491 | { | 443 | { |
492 | if(declVar.retType != null) | 444 | if(declVar.retType != null) |
@@ -501,31 +453,27 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
501 | } | 453 | } |
502 | } | 454 | } |
503 | 455 | ||
504 | /* | 456 | // ... and assign virtual method vtable slots. |
505 | * ... and assign virtual method vtable slots. | 457 | // |
506 | * | 458 | // - : error if any overridden method, doesn't need a slot |
507 | * - : error if any overridden method, doesn't need a slot | 459 | // abstract : error if any overridden method, alloc new slot but leave it empty |
508 | * abstract : error if any overridden method, alloc new slot but leave it empty | 460 | // new : ignore any overridden method, doesn't need a slot |
509 | * new : ignore any overridden method, doesn't need a slot | 461 | // new abstract : ignore any overridden method, alloc new slot but leave it empty |
510 | * new abstract : ignore any overridden method, alloc new slot but leave it empty | 462 | // override : must have overridden abstract/virtual, use old slot |
511 | * override : must have overridden abstract/virtual, use old slot | 463 | // override abstract : must have overridden abstract, use old slot but it is still empty |
512 | * override abstract : must have overridden abstract, use old slot but it is still empty | 464 | // static : error if any overridden method, doesn't need a slot |
513 | * static : error if any overridden method, doesn't need a slot | 465 | // static new : ignore any overridden method, doesn't need a slot |
514 | * static new : ignore any overridden method, doesn't need a slot | 466 | // virtual : error if any overridden method, alloc new slot and fill it in |
515 | * virtual : error if any overridden method, alloc new slot and fill it in | 467 | // virtual new : ignore any overridden method, alloc new slot and fill it in |
516 | * virtual new : ignore any overridden method, alloc new slot and fill it in | ||
517 | */ | ||
518 | foreach(TokenDeclVar declFunc in sdtClass.members) | 468 | foreach(TokenDeclVar declFunc in sdtClass.members) |
519 | { | 469 | { |
520 | if(declFunc.retType == null) | 470 | if(declFunc.retType == null) |
521 | continue; | 471 | continue; |
522 | curDeclFunc = declFunc; | 472 | curDeclFunc = declFunc; |
523 | 473 | ||
524 | /* | 474 | // See if there is a method in an extended class that this method overshadows. |
525 | * See if there is a method in an extended class that this method overshadows. | 475 | // If so, check for various conflicts. |
526 | * If so, check for various conflicts. | 476 | // In any case, SDT_NEW on our method means to ignore any overshadowed method. |
527 | * In any case, SDT_NEW on our method means to ignore any overshadowed method. | ||
528 | */ | ||
529 | string declLongName = sdtClass.longName.val + "." + declFunc.funcNameSig.val; | 477 | string declLongName = sdtClass.longName.val + "." + declFunc.funcNameSig.val; |
530 | uint declFlags = declFunc.sdtFlags; | 478 | uint declFlags = declFunc.sdtFlags; |
531 | TokenDeclVar overridden = null; | 479 | TokenDeclVar overridden = null; |
@@ -544,9 +492,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
544 | string overLongName = overridden.sdtClass.longName.val; | 492 | string overLongName = overridden.sdtClass.longName.val; |
545 | uint overFlags = overridden.sdtFlags; | 493 | uint overFlags = overridden.sdtFlags; |
546 | 494 | ||
547 | /* | 495 | // See if overridden method allows itself to be overridden. |
548 | * See if overridden method allows itself to be overridden. | ||
549 | */ | ||
550 | if((overFlags & ScriptReduce.SDT_ABSTRACT) != 0) | 496 | if((overFlags & ScriptReduce.SDT_ABSTRACT) != 0) |
551 | { | 497 | { |
552 | if((declFlags & (ScriptReduce.SDT_ABSTRACT | ScriptReduce.SDT_OVERRIDE)) == 0) | 498 | if((declFlags & (ScriptReduce.SDT_ABSTRACT | ScriptReduce.SDT_OVERRIDE)) == 0) |
@@ -573,9 +519,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
573 | break; | 519 | break; |
574 | } | 520 | } |
575 | 521 | ||
576 | /* | 522 | // See if our method is capable of overriding the other method. |
577 | * See if our method is capable of overriding the other method. | ||
578 | */ | ||
579 | if((declFlags & ScriptReduce.SDT_ABSTRACT) != 0) | 523 | if((declFlags & ScriptReduce.SDT_ABSTRACT) != 0) |
580 | { | 524 | { |
581 | if((overFlags & ScriptReduce.SDT_ABSTRACT) == 0) | 525 | if((overFlags & ScriptReduce.SDT_ABSTRACT) == 0) |
@@ -599,9 +543,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
599 | } | 543 | } |
600 | } while(false); | 544 | } while(false); |
601 | 545 | ||
602 | /* | 546 | // Now we can assign it a vtable slot if it needs one (ie, it is virtual). |
603 | * Now we can assign it a vtable slot if it needs one (ie, it is virtual). | ||
604 | */ | ||
605 | declFunc.vTableIndex = -1; | 547 | declFunc.vTableIndex = -1; |
606 | if(overridden != null) | 548 | if(overridden != null) |
607 | { | 549 | { |
@@ -618,11 +560,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
618 | } | 560 | } |
619 | curDeclFunc = null; | 561 | curDeclFunc = null; |
620 | 562 | ||
621 | /* | 563 | // ... and assign implemented interface slots. |
622 | * ... and assign implemented interface slots. | 564 | // Note that our implementations of a given interface is completely independent of any |
623 | * Note that our implementations of a given interface is completely independent of any | 565 | // rootward class's implementation of that same interface. |
624 | * rootward class's implementation of that same interface. | ||
625 | */ | ||
626 | int nIFaces = sdtClass.numInterfaces + sdtClass.implements.Count; | 566 | int nIFaces = sdtClass.numInterfaces + sdtClass.implements.Count; |
627 | sdtClass.iFaces = new TokenDeclSDTypeInterface[nIFaces]; | 567 | sdtClass.iFaces = new TokenDeclSDTypeInterface[nIFaces]; |
628 | sdtClass.iImplFunc = new TokenDeclVar[nIFaces][]; | 568 | sdtClass.iImplFunc = new TokenDeclVar[nIFaces][]; |
@@ -653,11 +593,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
653 | curDeclFunc = classMeth; | 593 | curDeclFunc = classMeth; |
654 | for(TokenIntfImpl intfImpl = classMeth.implements; intfImpl != null; intfImpl = (TokenIntfImpl)intfImpl.nextToken) | 594 | for(TokenIntfImpl intfImpl = classMeth.implements; intfImpl != null; intfImpl = (TokenIntfImpl)intfImpl.nextToken) |
655 | { | 595 | { |
656 | 596 | // One of the class methods implements an interface method. | |
657 | /* | 597 | // Try to find the interface method that is implemented and verify its signature. |
658 | * One of the class methods implements an interface method. | ||
659 | * Try to find the interface method that is implemented and verify its signature. | ||
660 | */ | ||
661 | TokenDeclSDTypeInterface intfType = intfImpl.intfType.decl; | 598 | TokenDeclSDTypeInterface intfType = intfImpl.intfType.decl; |
662 | TokenDeclVar intfMeth = FindExactWithRet(intfType.methsNProps, intfImpl.methName, classMeth.retType, classMeth.argDecl.types); | 599 | TokenDeclVar intfMeth = FindExactWithRet(intfType.methsNProps, intfImpl.methName, classMeth.retType, classMeth.argDecl.types); |
663 | if(intfMeth == null) | 600 | if(intfMeth == null) |
@@ -666,9 +603,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
666 | continue; | 603 | continue; |
667 | } | 604 | } |
668 | 605 | ||
669 | /* | 606 | // See if this class was declared to implement that interface. |
670 | * See if this class was declared to implement that interface. | ||
671 | */ | ||
672 | bool found = false; | 607 | bool found = false; |
673 | foreach(TokenDeclSDTypeInterface intf in sdtClass.implements) | 608 | foreach(TokenDeclSDTypeInterface intf in sdtClass.implements) |
674 | { | 609 | { |
@@ -684,11 +619,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
684 | continue; | 619 | continue; |
685 | } | 620 | } |
686 | 621 | ||
687 | /* | 622 | // Get index in iFaces[] and iImplFunc[] arrays. |
688 | * Get index in iFaces[] and iImplFunc[] arrays. | 623 | // Start scanning from the end in case one of our rootward classes also implements the interface. |
689 | * Start scanning from the end in case one of our rootward classes also implements the interface. | 624 | // We should always be successful because we know by now that this class implements the interface. |
690 | * We should always be successful because we know by now that this class implements the interface. | ||
691 | */ | ||
692 | int i; | 625 | int i; |
693 | for(i = sdtClass.numInterfaces; --i >= 0;) | 626 | for(i = sdtClass.numInterfaces; --i >= 0;) |
694 | { | 627 | { |
@@ -696,9 +629,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
696 | break; | 629 | break; |
697 | } | 630 | } |
698 | 631 | ||
699 | /* | 632 | // Now remember which of the class methods implements that interface method. |
700 | * Now remember which of the class methods implements that interface method. | ||
701 | */ | ||
702 | int j = intfMeth.vTableIndex; | 633 | int j = intfMeth.vTableIndex; |
703 | if(sdtClass.iImplFunc[i][j] != null) | 634 | if(sdtClass.iImplFunc[i][j] != null) |
704 | { | 635 | { |
@@ -710,9 +641,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
710 | } | 641 | } |
711 | curDeclFunc = null; | 642 | curDeclFunc = null; |
712 | 643 | ||
713 | /* | 644 | // Now make sure this class implements all methods for all declared interfaces. |
714 | * Now make sure this class implements all methods for all declared interfaces. | ||
715 | */ | ||
716 | for(int i = sdtClass.numInterfaces - sdtClass.implements.Count; i < sdtClass.numInterfaces; i++) | 645 | for(int i = sdtClass.numInterfaces - sdtClass.implements.Count; i < sdtClass.numInterfaces; i++) |
717 | { | 646 | { |
718 | TokenDeclVar[] implementations = sdtClass.iImplFunc[i]; | 647 | TokenDeclVar[] implementations = sdtClass.iImplFunc[i]; |
@@ -735,18 +664,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
735 | } | 664 | } |
736 | } | 665 | } |
737 | 666 | ||
738 | /* | 667 | // All slots for this class have been assigned. |
739 | * All slots for this class have been assigned. | ||
740 | */ | ||
741 | sdtClass.slotsAssigned = true; | 668 | sdtClass.slotsAssigned = true; |
742 | didOne = true; | 669 | didOne = true; |
743 | } | 670 | } |
744 | } while(didOne); | 671 | } while(didOne); |
745 | 672 | ||
746 | /* | 673 | // Compute final values for all variables/fields declared as 'constant'. |
747 | * Compute final values for all variables/fields declared as 'constant'. | 674 | // Note that there may be forward references. |
748 | * Note that there may be forward references. | ||
749 | */ | ||
750 | do | 675 | do |
751 | { | 676 | { |
752 | didOne = false; | 677 | didOne = false; |
@@ -773,9 +698,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
773 | currentSDTClass = null; | 698 | currentSDTClass = null; |
774 | } while(didOne); | 699 | } while(didOne); |
775 | 700 | ||
776 | /* | 701 | // Now we should be able to assign all those constants their type and location. |
777 | * Now we should be able to assign all those constants their type and location. | ||
778 | */ | ||
779 | foreach(TokenDeclVar tdv in tokenScript.variablesStack) | 702 | foreach(TokenDeclVar tdv in tokenScript.variablesStack) |
780 | { | 703 | { |
781 | if(tdv.constant) | 704 | if(tdv.constant) |
@@ -816,20 +739,16 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
816 | } | 739 | } |
817 | currentSDTClass = null; | 740 | currentSDTClass = null; |
818 | 741 | ||
819 | /* | 742 | // For all classes that define all the methods needed for the class, ie, they aren't abstract, |
820 | * For all classes that define all the methods needed for the class, ie, they aren't abstract, | 743 | // define a static class.$new() method with same args as the $ctor(s). This will allow the |
821 | * define a static class.$new() method with same args as the $ctor(s). This will allow the | 744 | // class to be instantiated via the new operator. |
822 | * class to be instantiated via the new operator. | ||
823 | */ | ||
824 | foreach(TokenDeclSDType sdType in tokenScript.sdSrcTypesValues) | 745 | foreach(TokenDeclSDType sdType in tokenScript.sdSrcTypesValues) |
825 | { | 746 | { |
826 | if(!(sdType is TokenDeclSDTypeClass)) | 747 | if(!(sdType is TokenDeclSDTypeClass)) |
827 | continue; | 748 | continue; |
828 | TokenDeclSDTypeClass sdtClass = (TokenDeclSDTypeClass)sdType; | 749 | TokenDeclSDTypeClass sdtClass = (TokenDeclSDTypeClass)sdType; |
829 | 750 | ||
830 | /* | 751 | // See if the class as it stands would be able to fill every slot of its vtable. |
831 | * See if the class as it stands would be able to fill every slot of its vtable. | ||
832 | */ | ||
833 | bool[] filled = new bool[sdtClass.numVirtFuncs]; | 752 | bool[] filled = new bool[sdtClass.numVirtFuncs]; |
834 | int numFilled = 0; | 753 | int numFilled = 0; |
835 | for(TokenDeclSDTypeClass sdtc = sdtClass; sdtc != null; sdtc = sdtc.extends) | 754 | for(TokenDeclSDTypeClass sdtc = sdtClass; sdtc != null; sdtc = sdtc.extends) |
@@ -847,11 +766,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
847 | } | 766 | } |
848 | } | 767 | } |
849 | 768 | ||
850 | /* | 769 | // If so, define a static class.$new() method for every constructor defined for the class. |
851 | * If so, define a static class.$new() method for every constructor defined for the class. | 770 | // Give it the same access (private/protected/public) as the script declared for the constructor. |
852 | * Give it the same access (private/protected/public) as the script declared for the constructor. | 771 | // Note that the reducer made sure there is at least a default constructor for every class. |
853 | * Note that the reducer made sure there is at least a default constructor for every class. | ||
854 | */ | ||
855 | if(numFilled >= sdtClass.numVirtFuncs) | 772 | if(numFilled >= sdtClass.numVirtFuncs) |
856 | { | 773 | { |
857 | List<TokenDeclVar> newobjDeclFuncs = new List<TokenDeclVar>(); | 774 | List<TokenDeclVar> newobjDeclFuncs = new List<TokenDeclVar>(); |
@@ -870,9 +787,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
870 | } | 787 | } |
871 | } | 788 | } |
872 | 789 | ||
873 | /* | 790 | // Write fixed portion of object file. |
874 | * Write fixed portion of object file. | ||
875 | */ | ||
876 | objFileWriter.Write(OBJECT_CODE_MAGIC.ToCharArray()); | 791 | objFileWriter.Write(OBJECT_CODE_MAGIC.ToCharArray()); |
877 | objFileWriter.Write(COMPILED_VERSION_VALUE); | 792 | objFileWriter.Write(COMPILED_VERSION_VALUE); |
878 | objFileWriter.Write(sourceHash); | 793 | objFileWriter.Write(sourceHash); |
@@ -884,9 +799,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
884 | objFileWriter.Write(stateNames[i]); | 799 | objFileWriter.Write(stateNames[i]); |
885 | } | 800 | } |
886 | 801 | ||
887 | /* | 802 | // For debugging, we also write out global variable array slot assignments. |
888 | * For debugging, we also write out global variable array slot assignments. | ||
889 | */ | ||
890 | foreach(TokenDeclVar declVar in tokenScript.variablesStack) | 803 | foreach(TokenDeclVar declVar in tokenScript.variablesStack) |
891 | { | 804 | { |
892 | if(declVar.retType == null) | 805 | if(declVar.retType == null) |
@@ -909,9 +822,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
909 | } | 822 | } |
910 | objFileWriter.Write(""); | 823 | objFileWriter.Write(""); |
911 | 824 | ||
912 | /* | 825 | // Write out script-defined types. |
913 | * Write out script-defined types. | ||
914 | */ | ||
915 | foreach(TokenDeclSDType sdType in tokenScript.sdSrcTypesValues) | 826 | foreach(TokenDeclSDType sdType in tokenScript.sdSrcTypesValues) |
916 | { | 827 | { |
917 | objFileWriter.Write(sdType.longName.val); | 828 | objFileWriter.Write(sdType.longName.val); |
@@ -919,13 +830,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
919 | } | 830 | } |
920 | objFileWriter.Write(""); | 831 | objFileWriter.Write(""); |
921 | 832 | ||
922 | /* | 833 | // Output function headers then bodies. |
923 | * Output function headers then bodies. | 834 | // Do all headers first in case bodies do forward references. |
924 | * Do all headers first in case bodies do forward references. | 835 | // Do both global functions, script-defined class static methods and |
925 | * Do both global functions, script-defined class static methods and | 836 | // script-defined instance methods, as we handle the differences |
926 | * script-defined instance methods, as we handle the differences | 837 | // during compilation of the functions/methods themselves. |
927 | * during compilation of the functions/methods themselves. | ||
928 | */ | ||
929 | for(int pass = 0; pass < 2; pass++) | 838 | for(int pass = 0; pass < 2; pass++) |
930 | { | 839 | { |
931 | foreach(TokenDeclVar declFunc in tokenScript.variablesStack) | 840 | foreach(TokenDeclVar declFunc in tokenScript.variablesStack) |
@@ -957,11 +866,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
957 | } | 866 | } |
958 | } | 867 | } |
959 | 868 | ||
960 | /* | 869 | // Output default state event handler functions. |
961 | * Output default state event handler functions. | 870 | // Each event handler is a private static method named 'default <eventname>'. |
962 | * Each event handler is a private static method named 'default <eventname>'. | 871 | // Splice in a default state_entry() handler if none defined so we can init global vars. |
963 | * Splice in a default state_entry() handler if none defined so we can init global vars. | ||
964 | */ | ||
965 | TokenDeclVar defaultStateEntry = null; | 872 | TokenDeclVar defaultStateEntry = null; |
966 | for(defaultStateEntry = tokenScript.defaultState.body.eventFuncs; | 873 | for(defaultStateEntry = tokenScript.defaultState.body.eventFuncs; |
967 | defaultStateEntry != null; | 874 | defaultStateEntry != null; |
@@ -984,10 +891,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
984 | } | 891 | } |
985 | GenerateStateEventHandlers("default", tokenScript.defaultState.body); | 892 | GenerateStateEventHandlers("default", tokenScript.defaultState.body); |
986 | 893 | ||
987 | /* | 894 | // Output script-defined state event handler methods. |
988 | * Output script-defined state event handler methods. | 895 | // Each event handler is a private static method named <statename> <eventname> |
989 | * Each event handler is a private static method named <statename> <eventname> | ||
990 | */ | ||
991 | foreach(KeyValuePair<string, TokenDeclState> kvp in tokenScript.states) | 896 | foreach(KeyValuePair<string, TokenDeclState> kvp in tokenScript.states) |
992 | { | 897 | { |
993 | TokenDeclState declState = kvp.Value; | 898 | TokenDeclState declState = kvp.Value; |
@@ -1059,13 +964,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1059 | string eventname = declFunc.GetSimpleName(); | 964 | string eventname = declFunc.GetSimpleName(); |
1060 | TokenArgDecl argDecl = declFunc.argDecl; | 965 | TokenArgDecl argDecl = declFunc.argDecl; |
1061 | 966 | ||
1062 | /* | 967 | // Make sure event handler name is valid and that number and type of arguments is correct. |
1063 | * Make sure event handler name is valid and that number and type of arguments is correct. | 968 | // Apparently some scripts exist with fewer than correct number of args in their declaration |
1064 | * Apparently some scripts exist with fewer than correct number of args in their declaration | 969 | // so allow for that. It is ok because the handlers are called with the arguments in an |
1065 | * so allow for that. It is ok because the handlers are called with the arguments in an | 970 | // object[] array, and we just won't access the missing argments in the vector. But the |
1066 | * object[] array, and we just won't access the missing argments in the vector. But the | 971 | // specified types must match one of the prototypes in legalEventHandlers. |
1067 | * specified types must match one of the prototypes in legalEventHandlers. | ||
1068 | */ | ||
1069 | TokenDeclVar protoDeclFunc = legalEventHandlers.FindExact(eventname, argDecl.types); | 972 | TokenDeclVar protoDeclFunc = legalEventHandlers.FindExact(eventname, argDecl.types); |
1070 | if(protoDeclFunc == null) | 973 | if(protoDeclFunc == null) |
1071 | { | 974 | { |
@@ -1073,10 +976,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1073 | return; | 976 | return; |
1074 | } | 977 | } |
1075 | 978 | ||
1076 | /* | 979 | // Output function header. |
1077 | * Output function header. | 980 | // They just have the XMRInstAbstract pointer as the one argument. |
1078 | * They just have the XMRInstAbstract pointer as the one argument. | ||
1079 | */ | ||
1080 | string functionName = statename + " " + eventname; | 981 | string functionName = statename + " " + eventname; |
1081 | _ilGen = new ScriptObjWriter(tokenScript, | 982 | _ilGen = new ScriptObjWriter(tokenScript, |
1082 | functionName, | 983 | functionName, |
@@ -1086,34 +987,25 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1086 | objFileWriter); | 987 | objFileWriter); |
1087 | StartFunctionBody(declFunc); | 988 | StartFunctionBody(declFunc); |
1088 | 989 | ||
1089 | /* | 990 | // Create a temp to hold XMRInstanceSuperType version of arg 0. |
1090 | * Create a temp to hold XMRInstanceSuperType version of arg 0. | ||
1091 | */ | ||
1092 | instancePointer = ilGen.DeclareLocal(xmrInstSuperType, "__xmrinst"); | 991 | instancePointer = ilGen.DeclareLocal(xmrInstSuperType, "__xmrinst"); |
1093 | ilGen.Emit(declFunc, OpCodes.Ldarg_0); | 992 | ilGen.Emit(declFunc, OpCodes.Ldarg_0); |
1094 | ilGen.Emit(declFunc, OpCodes.Castclass, xmrInstSuperType); | 993 | ilGen.Emit(declFunc, OpCodes.Castclass, xmrInstSuperType); |
1095 | ilGen.Emit(declFunc, OpCodes.Stloc, instancePointer); | 994 | ilGen.Emit(declFunc, OpCodes.Stloc, instancePointer); |
1096 | 995 | ||
1097 | /* | 996 | // Output args as variable definitions and initialize each from __sw.ehArgs[]. |
1098 | * Output args as variable definitions and initialize each from __sw.ehArgs[]. | 997 | // If the script writer goofed, the typecast will complain. |
1099 | * If the script writer goofed, the typecast will complain. | ||
1100 | */ | ||
1101 | int nArgs = argDecl.vars.Length; | 998 | int nArgs = argDecl.vars.Length; |
1102 | for(int i = 0; i < nArgs; i++) | 999 | for(int i = 0; i < nArgs; i++) |
1103 | { | 1000 | { |
1104 | 1001 | // Say that the argument variable is going to be located in a local var. | |
1105 | /* | ||
1106 | * Say that the argument variable is going to be located in a local var. | ||
1107 | */ | ||
1108 | TokenDeclVar argVar = argDecl.vars[i]; | 1002 | TokenDeclVar argVar = argDecl.vars[i]; |
1109 | TokenType argTokType = argVar.type; | 1003 | TokenType argTokType = argVar.type; |
1110 | CompValuLocalVar local = new CompValuLocalVar(argTokType, argVar.name.val, this); | 1004 | CompValuLocalVar local = new CompValuLocalVar(argTokType, argVar.name.val, this); |
1111 | argVar.location = local; | 1005 | argVar.location = local; |
1112 | 1006 | ||
1113 | /* | 1007 | // Copy from the ehArgs[i] element to the temp var. |
1114 | * Copy from the ehArgs[i] element to the temp var. | 1008 | // Cast as needed, there is a lot of craziness like OpenMetaverse.Quaternion. |
1115 | * Cast as needed, there is a lot of craziness like OpenMetaverse.Quaternion. | ||
1116 | */ | ||
1117 | local.PopPre(this, argVar.name); | 1009 | local.PopPre(this, argVar.name); |
1118 | PushXMRInst(); // instance | 1010 | PushXMRInst(); // instance |
1119 | ilGen.Emit(declFunc, OpCodes.Ldfld, ehArgsFieldInfo); // instance.ehArgs (array of objects) | 1011 | ilGen.Emit(declFunc, OpCodes.Ldfld, ehArgsFieldInfo); // instance.ehArgs (array of objects) |
@@ -1154,9 +1046,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1154 | local.PopPost(this, argVar.name, stkTokType); // pop stack type into argtype | 1046 | local.PopPost(this, argVar.name, stkTokType); // pop stack type into argtype |
1155 | } | 1047 | } |
1156 | 1048 | ||
1157 | /* | 1049 | // Output code for the statements and clean up. |
1158 | * Output code for the statements and clean up. | ||
1159 | */ | ||
1160 | GenerateFuncBody(); | 1050 | GenerateFuncBody(); |
1161 | } | 1051 | } |
1162 | 1052 | ||
@@ -1168,12 +1058,10 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1168 | { | 1058 | { |
1169 | curDeclFunc = declFunc; | 1059 | curDeclFunc = declFunc; |
1170 | 1060 | ||
1171 | /* | 1061 | // Make up array of all argument types as seen by the code generator. |
1172 | * Make up array of all argument types as seen by the code generator. | 1062 | // We splice in XMRInstanceSuperType or XMRSDTypeClObj for the first |
1173 | * We splice in XMRInstanceSuperType or XMRSDTypeClObj for the first | 1063 | // arg as the function itself is static, followed by script-visible |
1174 | * arg as the function itself is static, followed by script-visible | 1064 | // arg types. |
1175 | * arg types. | ||
1176 | */ | ||
1177 | TokenArgDecl argDecl = declFunc.argDecl; | 1065 | TokenArgDecl argDecl = declFunc.argDecl; |
1178 | int nArgs = argDecl.vars.Length; | 1066 | int nArgs = argDecl.vars.Length; |
1179 | Type[] argTypes = new Type[nArgs + 1]; | 1067 | Type[] argTypes = new Type[nArgs + 1]; |
@@ -1194,9 +1082,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1194 | argNames[i + 1] = argDecl.vars[i].name.val; | 1082 | argNames[i + 1] = argDecl.vars[i].name.val; |
1195 | } | 1083 | } |
1196 | 1084 | ||
1197 | /* | 1085 | // Set up entrypoint. |
1198 | * Set up entrypoint. | ||
1199 | */ | ||
1200 | string objCodeName = declFunc.GetObjCodeName(); | 1086 | string objCodeName = declFunc.GetObjCodeName(); |
1201 | declFunc.ilGen = new ScriptObjWriter(tokenScript, | 1087 | declFunc.ilGen = new ScriptObjWriter(tokenScript, |
1202 | objCodeName, | 1088 | objCodeName, |
@@ -1205,9 +1091,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1205 | argNames, | 1091 | argNames, |
1206 | objFileWriter); | 1092 | objFileWriter); |
1207 | 1093 | ||
1208 | /* | 1094 | // This says how to generate a call to the function and to get a delegate. |
1209 | * This says how to generate a call to the function and to get a delegate. | ||
1210 | */ | ||
1211 | declFunc.location = new CompValuGlobalMeth(declFunc); | 1095 | declFunc.location = new CompValuGlobalMeth(declFunc); |
1212 | 1096 | ||
1213 | curDeclFunc = null; | 1097 | curDeclFunc = null; |
@@ -1221,20 +1105,16 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1221 | */ | 1105 | */ |
1222 | private void GenerateMethodBody(TokenDeclVar declFunc) | 1106 | private void GenerateMethodBody(TokenDeclVar declFunc) |
1223 | { | 1107 | { |
1224 | /* | 1108 | // Set up code generator for the function's contents. |
1225 | * Set up code generator for the function's contents. | ||
1226 | */ | ||
1227 | _ilGen = declFunc.ilGen; | 1109 | _ilGen = declFunc.ilGen; |
1228 | StartFunctionBody(declFunc); | 1110 | StartFunctionBody(declFunc); |
1229 | 1111 | ||
1230 | /* | 1112 | // Create a temp to hold XMRInstanceSuperType version of arg 0. |
1231 | * Create a temp to hold XMRInstanceSuperType version of arg 0. | 1113 | // For most functions, arg 0 is already XMRInstanceSuperType. |
1232 | * For most functions, arg 0 is already XMRInstanceSuperType. | 1114 | // But for script-defined class instance methods, arg 0 holds |
1233 | * But for script-defined class instance methods, arg 0 holds | 1115 | // the XMRSDTypeClObj pointer and so we read the XMRInstAbstract |
1234 | * the XMRSDTypeClObj pointer and so we read the XMRInstAbstract | 1116 | // pointer from its XMRSDTypeClObj.xmrInst field then cast it to |
1235 | * pointer from its XMRSDTypeClObj.xmrInst field then cast it to | 1117 | // XMRInstanceSuperType. |
1236 | * XMRInstanceSuperType. | ||
1237 | */ | ||
1238 | if(IsSDTInstMethod()) | 1118 | if(IsSDTInstMethod()) |
1239 | { | 1119 | { |
1240 | instancePointer = ilGen.DeclareLocal(xmrInstSuperType, "__xmrinst"); | 1120 | instancePointer = ilGen.DeclareLocal(xmrInstSuperType, "__xmrinst"); |
@@ -1244,11 +1124,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1244 | ilGen.Emit(declFunc, OpCodes.Stloc, instancePointer); | 1124 | ilGen.Emit(declFunc, OpCodes.Stloc, instancePointer); |
1245 | } | 1125 | } |
1246 | 1126 | ||
1247 | /* | 1127 | // Define location of all script-level arguments so script body can access them. |
1248 | * Define location of all script-level arguments so script body can access them. | 1128 | // The argument indices need to have +1 added to them because XMRInstance or |
1249 | * The argument indices need to have +1 added to them because XMRInstance or | 1129 | // XMRSDTypeClObj is spliced in at arg 0. |
1250 | * XMRSDTypeClObj is spliced in at arg 0. | ||
1251 | */ | ||
1252 | TokenArgDecl argDecl = declFunc.argDecl; | 1130 | TokenArgDecl argDecl = declFunc.argDecl; |
1253 | int nArgs = argDecl.vars.Length; | 1131 | int nArgs = argDecl.vars.Length; |
1254 | for(int i = 0; i < nArgs; i++) | 1132 | for(int i = 0; i < nArgs; i++) |
@@ -1257,27 +1135,21 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1257 | argVar.location = new CompValuArg(argVar.type, i + 1); | 1135 | argVar.location = new CompValuArg(argVar.type, i + 1); |
1258 | } | 1136 | } |
1259 | 1137 | ||
1260 | /* | 1138 | // Output code for the statements and clean up. |
1261 | * Output code for the statements and clean up. | ||
1262 | */ | ||
1263 | GenerateFuncBody(); | 1139 | GenerateFuncBody(); |
1264 | } | 1140 | } |
1265 | 1141 | ||
1266 | private void StartFunctionBody(TokenDeclVar declFunc) | 1142 | private void StartFunctionBody(TokenDeclVar declFunc) |
1267 | { | 1143 | { |
1268 | /* | 1144 | // Start current function being processed. |
1269 | * Start current function being processed. | 1145 | // Set 'mightGetHere' as the code at the top is always executed. |
1270 | * Set 'mightGetHere' as the code at the top is always executed. | ||
1271 | */ | ||
1272 | instancePointer = null; | 1146 | instancePointer = null; |
1273 | mightGetHere = true; | 1147 | mightGetHere = true; |
1274 | curBreakTarg = null; | 1148 | curBreakTarg = null; |
1275 | curContTarg = null; | 1149 | curContTarg = null; |
1276 | curDeclFunc = declFunc; | 1150 | curDeclFunc = declFunc; |
1277 | 1151 | ||
1278 | /* | 1152 | // Start generating code. |
1279 | * Start generating code. | ||
1280 | */ | ||
1281 | ((ScriptObjWriter)ilGen).BegMethod(); | 1153 | ((ScriptObjWriter)ilGen).BegMethod(); |
1282 | } | 1154 | } |
1283 | 1155 | ||
@@ -1287,9 +1159,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1287 | */ | 1159 | */ |
1288 | private TokenDeclVar DefineNewobjFunc(TokenDeclVar ctorDeclFunc) | 1160 | private TokenDeclVar DefineNewobjFunc(TokenDeclVar ctorDeclFunc) |
1289 | { | 1161 | { |
1290 | /* | 1162 | // Set up 'static classname $new(params-same-as-ctor) { }'. |
1291 | * Set up 'static classname $new(params-same-as-ctor) { }'. | ||
1292 | */ | ||
1293 | TokenDeclVar newobjDeclFunc = new TokenDeclVar(ctorDeclFunc, null, tokenScript); | 1163 | TokenDeclVar newobjDeclFunc = new TokenDeclVar(ctorDeclFunc, null, tokenScript); |
1294 | newobjDeclFunc.name = new TokenName(newobjDeclFunc, "$new"); | 1164 | newobjDeclFunc.name = new TokenName(newobjDeclFunc, "$new"); |
1295 | newobjDeclFunc.retType = ctorDeclFunc.sdtClass.MakeRefToken(newobjDeclFunc); | 1165 | newobjDeclFunc.retType = ctorDeclFunc.sdtClass.MakeRefToken(newobjDeclFunc); |
@@ -1297,10 +1167,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1297 | newobjDeclFunc.sdtClass = ctorDeclFunc.sdtClass; | 1167 | newobjDeclFunc.sdtClass = ctorDeclFunc.sdtClass; |
1298 | newobjDeclFunc.sdtFlags = ScriptReduce.SDT_STATIC | ctorDeclFunc.sdtFlags; | 1168 | newobjDeclFunc.sdtFlags = ScriptReduce.SDT_STATIC | ctorDeclFunc.sdtFlags; |
1299 | 1169 | ||
1300 | /* | 1170 | // Declare local variable named '$objptr' in a frame just under |
1301 | * Declare local variable named '$objptr' in a frame just under | 1171 | // what the '$new(...)' function's arguments are declared in. |
1302 | * what the '$new(...)' function's arguments are declared in. | ||
1303 | */ | ||
1304 | TokenDeclVar objptrVar = new TokenDeclVar(newobjDeclFunc, newobjDeclFunc, tokenScript); | 1172 | TokenDeclVar objptrVar = new TokenDeclVar(newobjDeclFunc, newobjDeclFunc, tokenScript); |
1305 | objptrVar.type = newobjDeclFunc.retType; | 1173 | objptrVar.type = newobjDeclFunc.retType; |
1306 | objptrVar.name = new TokenName(newobjDeclFunc, "$objptr"); | 1174 | objptrVar.name = new TokenName(newobjDeclFunc, "$objptr"); |
@@ -1308,20 +1176,17 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1308 | newFrame.outerVarDict = ctorDeclFunc.argDecl.varDict; | 1176 | newFrame.outerVarDict = ctorDeclFunc.argDecl.varDict; |
1309 | newFrame.AddEntry(objptrVar); | 1177 | newFrame.AddEntry(objptrVar); |
1310 | 1178 | ||
1311 | /* | 1179 | // Set up '$objptr.$ctor' |
1312 | * Set up '$objptr.$ctor' | ||
1313 | */ | ||
1314 | TokenLValName objptrLValName = new TokenLValName(objptrVar.name, newFrame); | 1180 | TokenLValName objptrLValName = new TokenLValName(objptrVar.name, newFrame); |
1181 | |||
1315 | // ref a var by giving its name | 1182 | // ref a var by giving its name |
1316 | TokenLValIField objptrDotCtor = new TokenLValIField(newobjDeclFunc); // an instance member reference | 1183 | TokenLValIField objptrDotCtor = new TokenLValIField(newobjDeclFunc); // an instance member reference |
1317 | objptrDotCtor.baseRVal = objptrLValName; // '$objptr' | 1184 | objptrDotCtor.baseRVal = objptrLValName; // '$objptr' |
1318 | objptrDotCtor.fieldName = ctorDeclFunc.name; // '.' '$ctor' | 1185 | objptrDotCtor.fieldName = ctorDeclFunc.name; // '.' '$ctor' |
1319 | 1186 | ||
1320 | /* | 1187 | // Set up '$objptr.$ctor(arglist)' call for use in the '$new(...)' body. |
1321 | * Set up '$objptr.$ctor(arglist)' call for use in the '$new(...)' body. | 1188 | // Copy the arglist from the constructor declaration so triviality |
1322 | * Copy the arglist from the constructor declaration so triviality | 1189 | // processing will pick the correct overloaded constructor. |
1323 | * processing will pick the correct overloaded constructor. | ||
1324 | */ | ||
1325 | TokenRValCall callCtorRVal = new TokenRValCall(newobjDeclFunc); // doing a call of some sort | 1190 | TokenRValCall callCtorRVal = new TokenRValCall(newobjDeclFunc); // doing a call of some sort |
1326 | callCtorRVal.meth = objptrDotCtor; // calling $objptr.$ctor() | 1191 | callCtorRVal.meth = objptrDotCtor; // calling $objptr.$ctor() |
1327 | TokenDeclVar[] argList = newobjDeclFunc.argDecl.vars; // get args $new() was declared with | 1192 | TokenDeclVar[] argList = newobjDeclFunc.argDecl.vars; // get args $new() was declared with |
@@ -1335,32 +1200,26 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1335 | callCtorRVal.args = argLValName; | 1200 | callCtorRVal.args = argLValName; |
1336 | } | 1201 | } |
1337 | 1202 | ||
1338 | /* | 1203 | // Set up a funky call to the constructor for the code body. |
1339 | * Set up a funky call to the constructor for the code body. | 1204 | // This will let code generator know there is some craziness. |
1340 | * This will let code generator know there is some craziness. | 1205 | // See GenerateStmtNewobj(). |
1341 | * See GenerateStmtNewobj(). | 1206 | // |
1342 | * | 1207 | // This is in essence: |
1343 | * This is in essence: | 1208 | // { |
1344 | * { | 1209 | // classname $objptr = newobj (classname); |
1345 | * classname $objptr = newobj (classname); | 1210 | // $objptr.$ctor (...); |
1346 | * $objptr.$ctor (...); | 1211 | // return $objptr; |
1347 | * return $objptr; | 1212 | // } |
1348 | * } | ||
1349 | */ | ||
1350 | TokenStmtNewobj newobjStmtBody = new TokenStmtNewobj(ctorDeclFunc); | 1213 | TokenStmtNewobj newobjStmtBody = new TokenStmtNewobj(ctorDeclFunc); |
1351 | newobjStmtBody.objptrVar = objptrVar; | 1214 | newobjStmtBody.objptrVar = objptrVar; |
1352 | newobjStmtBody.rValCall = callCtorRVal; | 1215 | newobjStmtBody.rValCall = callCtorRVal; |
1353 | TokenStmtBlock newobjBody = new TokenStmtBlock(ctorDeclFunc); | 1216 | TokenStmtBlock newobjBody = new TokenStmtBlock(ctorDeclFunc); |
1354 | newobjBody.statements = newobjStmtBody; | 1217 | newobjBody.statements = newobjStmtBody; |
1355 | 1218 | ||
1356 | /* | 1219 | // Link that code as the body of the function. |
1357 | * Link that code as the body of the function. | ||
1358 | */ | ||
1359 | newobjDeclFunc.body = newobjBody; | 1220 | newobjDeclFunc.body = newobjBody; |
1360 | 1221 | ||
1361 | /* | 1222 | // Say the function calls '$objptr.$ctor(arglist)' so we will inherit ctor's triviality. |
1362 | * Say the function calls '$objptr.$ctor(arglist)' so we will inherit ctor's triviality. | ||
1363 | */ | ||
1364 | newobjDeclFunc.unknownTrivialityCalls.AddLast(callCtorRVal); | 1223 | newobjDeclFunc.unknownTrivialityCalls.AddLast(callCtorRVal); |
1365 | return newobjDeclFunc; | 1224 | return newobjDeclFunc; |
1366 | } | 1225 | } |
@@ -1377,43 +1236,33 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1377 | */ | 1236 | */ |
1378 | private void GenerateFuncBody() | 1237 | private void GenerateFuncBody() |
1379 | { | 1238 | { |
1380 | /* | 1239 | // We want to know if the function's code is trivial, ie, |
1381 | * We want to know if the function's code is trivial, ie, | 1240 | // if it doesn't have anything that might be an infinite |
1382 | * if it doesn't have anything that might be an infinite | 1241 | // loop and that is doesn't call anything that might have |
1383 | * loop and that is doesn't call anything that might have | 1242 | // an infinite loop. If it is, we don't need any CheckRun() |
1384 | * an infinite loop. If it is, we don't need any CheckRun() | 1243 | // stuff or any of the frame save/restore stuff. |
1385 | * stuff or any of the frame save/restore stuff. | ||
1386 | */ | ||
1387 | bool isTrivial = curDeclFunc.IsFuncTrivial(this); | 1244 | bool isTrivial = curDeclFunc.IsFuncTrivial(this); |
1388 | 1245 | ||
1389 | /* | 1246 | // Clear list of all call labels. |
1390 | * Clear list of all call labels. | 1247 | // A call label is inserted just before every call that can possibly |
1391 | * A call label is inserted just before every call that can possibly | 1248 | // call CheckRun(), including any direct calls to CheckRun(). |
1392 | * call CheckRun(), including any direct calls to CheckRun(). | 1249 | // Then, when restoring stack, we can just switch to this label to |
1393 | * Then, when restoring stack, we can just switch to this label to | 1250 | // resume at the correct spot. |
1394 | * resume at the correct spot. | ||
1395 | */ | ||
1396 | actCallLabels.Clear(); | 1251 | actCallLabels.Clear(); |
1397 | allCallLabels.Clear(); | 1252 | allCallLabels.Clear(); |
1398 | openCallLabel = null; | 1253 | openCallLabel = null; |
1399 | 1254 | ||
1400 | /* | 1255 | // Alloc stack space for local vars. |
1401 | * Alloc stack space for local vars. | ||
1402 | */ | ||
1403 | int stackframesize = AllocLocalVarStackSpace(); | 1256 | int stackframesize = AllocLocalVarStackSpace(); |
1404 | 1257 | ||
1405 | /* | 1258 | // Include argument variables in stack space for this frame. |
1406 | * Include argument variables in stack space for this frame. | ||
1407 | */ | ||
1408 | foreach(TokenType tokType in curDeclFunc.argDecl.types) | 1259 | foreach(TokenType tokType in curDeclFunc.argDecl.types) |
1409 | { | 1260 | { |
1410 | stackframesize += LocalVarStackSize(tokType); | 1261 | stackframesize += LocalVarStackSize(tokType); |
1411 | } | 1262 | } |
1412 | 1263 | ||
1413 | /* | 1264 | // Any return statements inside function body jump to this label |
1414 | * Any return statements inside function body jump to this label | 1265 | // after putting return value in __retval. |
1415 | * after putting return value in __retval. | ||
1416 | */ | ||
1417 | retLabel = ilGen.DefineLabel("__retlbl"); | 1266 | retLabel = ilGen.DefineLabel("__retlbl"); |
1418 | retValue = null; | 1267 | retValue = null; |
1419 | if(!(curDeclFunc.retType is TokenTypeVoid)) | 1268 | if(!(curDeclFunc.retType is TokenTypeVoid)) |
@@ -1421,13 +1270,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1421 | retValue = ilGen.DeclareLocal(curDeclFunc.retType.ToSysType(), "__retval"); | 1270 | retValue = ilGen.DeclareLocal(curDeclFunc.retType.ToSysType(), "__retval"); |
1422 | } | 1271 | } |
1423 | 1272 | ||
1424 | /* | 1273 | // Output: |
1425 | * Output: | 1274 | // int __mainCallNo = -1; |
1426 | * int __mainCallNo = -1; | 1275 | // instance.m_StackLeft -= stackframesize; |
1427 | * instance.m_StackLeft -= stackframesize; | 1276 | // try { |
1428 | * try { | 1277 | // if (instance.callMode != CallMode_NORMAL) goto __cmRestore; |
1429 | * if (instance.callMode != CallMode_NORMAL) goto __cmRestore; | ||
1430 | */ | ||
1431 | actCallNo = null; | 1278 | actCallNo = null; |
1432 | ScriptMyLabel cmRestore = null; | 1279 | ScriptMyLabel cmRestore = null; |
1433 | if(!isTrivial) | 1280 | if(!isTrivial) |
@@ -1448,18 +1295,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1448 | ilGen.Emit(curDeclFunc, OpCodes.Bne_Un, cmRestore); | 1295 | ilGen.Emit(curDeclFunc, OpCodes.Bne_Un, cmRestore); |
1449 | } | 1296 | } |
1450 | 1297 | ||
1451 | /* | 1298 | // Splice in the code optimizer for the body of the function. |
1452 | * Splice in the code optimizer for the body of the function. | ||
1453 | */ | ||
1454 | ScriptCollector collector = new ScriptCollector((ScriptObjWriter)ilGen); | 1299 | ScriptCollector collector = new ScriptCollector((ScriptObjWriter)ilGen); |
1455 | _ilGen = collector; | 1300 | _ilGen = collector; |
1456 | 1301 | ||
1457 | /* | 1302 | // If this is the default state_entry() handler, output code to set all global |
1458 | * If this is the default state_entry() handler, output code to set all global | 1303 | // variables to their initial values. Note that every script must have a |
1459 | * variables to their initial values. Note that every script must have a | 1304 | // default state_entry() handler, we provide one if the script doesn't explicitly |
1460 | * default state_entry() handler, we provide one if the script doesn't explicitly | 1305 | // define one. |
1461 | * define one. | ||
1462 | */ | ||
1463 | string methname = ilGen.methName; | 1306 | string methname = ilGen.methName; |
1464 | if(methname == "default state_entry") | 1307 | if(methname == "default state_entry") |
1465 | { | 1308 | { |
@@ -1501,10 +1344,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1501 | ilGen.MarkLabel(skipGblInitLabel); | 1344 | ilGen.MarkLabel(skipGblInitLabel); |
1502 | } | 1345 | } |
1503 | 1346 | ||
1504 | /* | 1347 | // If this is a script-defined type constructor, call the base constructor and call |
1505 | * If this is a script-defined type constructor, call the base constructor and call | 1348 | // this class's $instfieldinit() method to initialize instance fields. |
1506 | * this class's $instfieldinit() method to initialize instance fields. | ||
1507 | */ | ||
1508 | if((curDeclFunc.sdtClass != null) && curDeclFunc.funcNameSig.val.StartsWith("$ctor(")) | 1349 | if((curDeclFunc.sdtClass != null) && curDeclFunc.funcNameSig.val.StartsWith("$ctor(")) |
1509 | { | 1350 | { |
1510 | if(curDeclFunc.baseCtorCall != null) | 1351 | if(curDeclFunc.baseCtorCall != null) |
@@ -1521,22 +1362,16 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1521 | } | 1362 | } |
1522 | } | 1363 | } |
1523 | 1364 | ||
1524 | /* | 1365 | // See if time to suspend in case they are doing a loop with recursion. |
1525 | * See if time to suspend in case they are doing a loop with recursion. | ||
1526 | */ | ||
1527 | if(!isTrivial) | 1366 | if(!isTrivial) |
1528 | EmitCallCheckRun(curDeclFunc, true); | 1367 | EmitCallCheckRun(curDeclFunc, true); |
1529 | 1368 | ||
1530 | /* | 1369 | // Output code body. |
1531 | * Output code body. | ||
1532 | */ | ||
1533 | GenerateStmtBlock(curDeclFunc.body); | 1370 | GenerateStmtBlock(curDeclFunc.body); |
1534 | 1371 | ||
1535 | /* | 1372 | // If code falls through to this point, means they are missing |
1536 | * If code falls through to this point, means they are missing | 1373 | // a return statement. And that is legal only if the function |
1537 | * a return statement. And that is legal only if the function | 1374 | // returns 'void'. |
1538 | * returns 'void'. | ||
1539 | */ | ||
1540 | if(mightGetHere) | 1375 | if(mightGetHere) |
1541 | { | 1376 | { |
1542 | if(!(curDeclFunc.retType is TokenTypeVoid)) | 1377 | if(!(curDeclFunc.retType is TokenTypeVoid)) |
@@ -1546,28 +1381,21 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1546 | ilGen.Emit(curDeclFunc, OpCodes.Leave, retLabel); | 1381 | ilGen.Emit(curDeclFunc, OpCodes.Leave, retLabel); |
1547 | } | 1382 | } |
1548 | 1383 | ||
1549 | /* | 1384 | // End of the code to be optimized. |
1550 | * End of the code to be optimized. | 1385 | // Do optimizations then write it all out to object file. |
1551 | * Do optimizations then write it all out to object file. | 1386 | // After this, all code gets written directly to object file. |
1552 | * After this, all code gets written directly to object file. | 1387 | // Optimization must be completed before we scan the allCallLabels |
1553 | * Optimization must be completed before we scan the allCallLabels | 1388 | // list below to look for active locals and temps. |
1554 | * list below to look for active locals and temps. | ||
1555 | */ | ||
1556 | collector.Optimize(); | 1389 | collector.Optimize(); |
1557 | _ilGen = collector.WriteOutAll(); | 1390 | _ilGen = collector.WriteOutAll(); |
1558 | collector = null; | 1391 | collector = null; |
1559 | 1392 | ||
1560 | /* | 1393 | // Output code to restore stack frame from stream. |
1561 | * Output code to restore stack frame from stream. | 1394 | // It jumps back to the call labels within the function body. |
1562 | * It jumps back to the call labels within the function body. | ||
1563 | */ | ||
1564 | List<ScriptMyLocal> activeTemps = null; | 1395 | List<ScriptMyLocal> activeTemps = null; |
1565 | if(!isTrivial) | 1396 | if(!isTrivial) |
1566 | { | 1397 | { |
1567 | 1398 | // Build list of locals and temps active at all the call labels. | |
1568 | /* | ||
1569 | * Build list of locals and temps active at all the call labels. | ||
1570 | */ | ||
1571 | activeTemps = new List<ScriptMyLocal>(); | 1399 | activeTemps = new List<ScriptMyLocal>(); |
1572 | foreach(CallLabel cl in allCallLabels) | 1400 | foreach(CallLabel cl in allCallLabels) |
1573 | { | 1401 | { |
@@ -1580,24 +1408,20 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1580 | } | 1408 | } |
1581 | } | 1409 | } |
1582 | 1410 | ||
1583 | /* | 1411 | // Output code to restore the args, locals and temps then jump to |
1584 | * Output code to restore the args, locals and temps then jump to | 1412 | // the call label that we were interrupted at. |
1585 | * the call label that we were interrupted at. | ||
1586 | */ | ||
1587 | ilGen.MarkLabel(cmRestore); | 1413 | ilGen.MarkLabel(cmRestore); |
1588 | GenerateFrameRestoreCode(activeTemps); | 1414 | GenerateFrameRestoreCode(activeTemps); |
1589 | } | 1415 | } |
1590 | 1416 | ||
1591 | /* | 1417 | // Output epilog that saves stack frame state if CallMode_SAVE. |
1592 | * Output epilog that saves stack frame state if CallMode_SAVE. | 1418 | // |
1593 | * | 1419 | // finally { |
1594 | * finally { | 1420 | // instance.m_StackLeft += stackframesize; |
1595 | * instance.m_StackLeft += stackframesize; | 1421 | // if (instance.callMode != CallMode_SAVE) goto __endFin; |
1596 | * if (instance.callMode != CallMode_SAVE) goto __endFin; | 1422 | // GenerateFrameCaptureCode(); |
1597 | * GenerateFrameCaptureCode(); | 1423 | // __endFin: |
1598 | * __endFin: | 1424 | // } |
1599 | * } | ||
1600 | */ | ||
1601 | ScriptMyLabel endFin = null; | 1425 | ScriptMyLabel endFin = null; |
1602 | if(!isTrivial) | 1426 | if(!isTrivial) |
1603 | { | 1427 | { |
@@ -1619,9 +1443,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1619 | ilGen.EndExceptionBlock(); | 1443 | ilGen.EndExceptionBlock(); |
1620 | } | 1444 | } |
1621 | 1445 | ||
1622 | /* | 1446 | // Output the 'real' return opcode. |
1623 | * Output the 'real' return opcode. | ||
1624 | */ | ||
1625 | ilGen.MarkLabel(retLabel); | 1447 | ilGen.MarkLabel(retLabel); |
1626 | if(!(curDeclFunc.retType is TokenTypeVoid)) | 1448 | if(!(curDeclFunc.retType is TokenTypeVoid)) |
1627 | { | 1449 | { |
@@ -1631,15 +1453,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1631 | retLabel = null; | 1453 | retLabel = null; |
1632 | retValue = null; | 1454 | retValue = null; |
1633 | 1455 | ||
1634 | /* | 1456 | // No more instructions for this method. |
1635 | * No more instructions for this method. | ||
1636 | */ | ||
1637 | ((ScriptObjWriter)ilGen).EndMethod(); | 1457 | ((ScriptObjWriter)ilGen).EndMethod(); |
1638 | _ilGen = null; | 1458 | _ilGen = null; |
1639 | 1459 | ||
1640 | /* | 1460 | // Not generating function code any more. |
1641 | * Not generating function code any more. | ||
1642 | */ | ||
1643 | curBreakTarg = null; | 1461 | curBreakTarg = null; |
1644 | curContTarg = null; | 1462 | curContTarg = null; |
1645 | curDeclFunc = null; | 1463 | curDeclFunc = null; |
@@ -1655,21 +1473,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1655 | int stackframesize = 64; // RIP, RBX, RBP, R12..R15, one extra | 1473 | int stackframesize = 64; // RIP, RBX, RBP, R12..R15, one extra |
1656 | foreach(TokenDeclVar localVar in curDeclFunc.localVars) | 1474 | foreach(TokenDeclVar localVar in curDeclFunc.localVars) |
1657 | { | 1475 | { |
1658 | 1476 | // Skip all 'constant' vars as they were handled by the reducer. | |
1659 | /* | ||
1660 | * Skip all 'constant' vars as they were handled by the reducer. | ||
1661 | */ | ||
1662 | if(localVar.constant) | 1477 | if(localVar.constant) |
1663 | continue; | 1478 | continue; |
1664 | 1479 | ||
1665 | /* | 1480 | // Get a stack location for the local variable. |
1666 | * Get a stack location for the local variable. | ||
1667 | */ | ||
1668 | localVar.location = new CompValuLocalVar(localVar.type, localVar.name.val, this); | 1481 | localVar.location = new CompValuLocalVar(localVar.type, localVar.name.val, this); |
1669 | 1482 | ||
1670 | /* | 1483 | // Stack size for the local variable. |
1671 | * Stack size for the local variable. | ||
1672 | */ | ||
1673 | stackframesize += LocalVarStackSize(localVar.type); | 1484 | stackframesize += LocalVarStackSize(localVar.type); |
1674 | } | 1485 | } |
1675 | return stackframesize; | 1486 | return stackframesize; |
@@ -1692,17 +1503,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1692 | */ | 1503 | */ |
1693 | private void GenerateFrameCaptureCode(List<ScriptMyLocal> activeTemps) | 1504 | private void GenerateFrameCaptureCode(List<ScriptMyLocal> activeTemps) |
1694 | { | 1505 | { |
1695 | /* | 1506 | // Compute total number of slots we need to save stuff. |
1696 | * Compute total number of slots we need to save stuff. | 1507 | // Assume we need to save all call arguments. |
1697 | * Assume we need to save all call arguments. | ||
1698 | */ | ||
1699 | int nSaves = curDeclFunc.argDecl.vars.Length + activeTemps.Count; | 1508 | int nSaves = curDeclFunc.argDecl.vars.Length + activeTemps.Count; |
1700 | 1509 | ||
1701 | /* | 1510 | // Output code to allocate a stack frame object with an object array. |
1702 | * Output code to allocate a stack frame object with an object array. | 1511 | // This also pushes the stack frame object on the instance.stackFrames list. |
1703 | * This also pushes the stack frame object on the instance.stackFrames list. | 1512 | // It returns a pointer to the object array it allocated. |
1704 | * It returns a pointer to the object array it allocated. | ||
1705 | */ | ||
1706 | PushXMRInst(); | 1513 | PushXMRInst(); |
1707 | ilGen.Emit(curDeclFunc, OpCodes.Ldstr, ilGen.methName); | 1514 | ilGen.Emit(curDeclFunc, OpCodes.Ldstr, ilGen.methName); |
1708 | GetCallNo(curDeclFunc, actCallNo); | 1515 | GetCallNo(curDeclFunc, actCallNo); |
@@ -1718,9 +1525,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1718 | ilGen.Emit(curDeclFunc, OpCodes.Call, consoleWriteMethodInfo); | 1525 | ilGen.Emit(curDeclFunc, OpCodes.Call, consoleWriteMethodInfo); |
1719 | } | 1526 | } |
1720 | 1527 | ||
1721 | /* | 1528 | // Copy arg values to object array, boxing as needed. |
1722 | * Copy arg values to object array, boxing as needed. | ||
1723 | */ | ||
1724 | int i = 0; | 1529 | int i = 0; |
1725 | foreach(TokenDeclVar argVar in curDeclFunc.argDecl.varDict) | 1530 | foreach(TokenDeclVar argVar in curDeclFunc.argDecl.varDict) |
1726 | { | 1531 | { |
@@ -1738,9 +1543,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1738 | i++; | 1543 | i++; |
1739 | } | 1544 | } |
1740 | 1545 | ||
1741 | /* | 1546 | // Copy local and temp values to object array, boxing as needed. |
1742 | * Copy local and temp values to object array, boxing as needed. | ||
1743 | */ | ||
1744 | foreach(ScriptMyLocal lcl in activeTemps) | 1547 | foreach(ScriptMyLocal lcl in activeTemps) |
1745 | { | 1548 | { |
1746 | ilGen.Emit(curDeclFunc, OpCodes.Dup); | 1549 | ilGen.Emit(curDeclFunc, OpCodes.Dup); |
@@ -1789,10 +1592,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1789 | { | 1592 | { |
1790 | ScriptMyLocal objArray = ilGen.DeclareLocal(typeof(object[]), "__restObjArray"); | 1593 | ScriptMyLocal objArray = ilGen.DeclareLocal(typeof(object[]), "__restObjArray"); |
1791 | 1594 | ||
1792 | /* | 1595 | // Output code to pop stack frame from instance.stackFrames. |
1793 | * Output code to pop stack frame from instance.stackFrames. | 1596 | // It returns a pointer to the object array that contains values to be restored. |
1794 | * It returns a pointer to the object array that contains values to be restored. | ||
1795 | */ | ||
1796 | PushXMRInst(); | 1597 | PushXMRInst(); |
1797 | ilGen.Emit(curDeclFunc, OpCodes.Ldstr, ilGen.methName); | 1598 | ilGen.Emit(curDeclFunc, OpCodes.Ldstr, ilGen.methName); |
1798 | ilGen.Emit(curDeclFunc, OpCodes.Ldloca, actCallNo); // __mainCallNo | 1599 | ilGen.Emit(curDeclFunc, OpCodes.Ldloca, actCallNo); // __mainCallNo |
@@ -1807,11 +1608,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1807 | ilGen.Emit(curDeclFunc, OpCodes.Call, consoleWriteMethodInfo); | 1608 | ilGen.Emit(curDeclFunc, OpCodes.Call, consoleWriteMethodInfo); |
1808 | } | 1609 | } |
1809 | 1610 | ||
1810 | /* | 1611 | // Restore argument values from object array, unboxing as needed. |
1811 | * Restore argument values from object array, unboxing as needed. | 1612 | // Although the caller has restored them to what it called us with, it's possible that this |
1812 | * Although the caller has restored them to what it called us with, it's possible that this | 1613 | // function has modified them since, so we need to do our own restore. |
1813 | * function has modified them since, so we need to do our own restore. | ||
1814 | */ | ||
1815 | int i = 0; | 1614 | int i = 0; |
1816 | foreach(TokenDeclVar argVar in curDeclFunc.argDecl.varDict) | 1615 | foreach(TokenDeclVar argVar in curDeclFunc.argDecl.varDict) |
1817 | { | 1616 | { |
@@ -1832,9 +1631,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1832 | i++; | 1631 | i++; |
1833 | } | 1632 | } |
1834 | 1633 | ||
1835 | /* | 1634 | // Restore local and temp values from object array, unboxing as needed. |
1836 | * Restore local and temp values from object array, unboxing as needed. | ||
1837 | */ | ||
1838 | foreach(ScriptMyLocal lcl in activeTemps) | 1635 | foreach(ScriptMyLocal lcl in activeTemps) |
1839 | { | 1636 | { |
1840 | Type t = lcl.type; | 1637 | Type t = lcl.type; |
@@ -1952,10 +1749,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1952 | this.index = scg.actCallLabels.Count; | 1749 | this.index = scg.actCallLabels.Count; |
1953 | string name = "__call_" + index + "_" + scg.allCallLabels.Count; | 1750 | string name = "__call_" + index + "_" + scg.allCallLabels.Count; |
1954 | 1751 | ||
1955 | /* | 1752 | // Make sure eval stack is empty because the frame capture/restore |
1956 | * Make sure eval stack is empty because the frame capture/restore | 1753 | // code expects such (restore switch stmt has an empty stack). |
1957 | * code expects such (restore switch stmt has an empty stack). | ||
1958 | */ | ||
1959 | int depth = ((ScriptCollector)scg.ilGen).stackDepth.Count; | 1754 | int depth = ((ScriptCollector)scg.ilGen).stackDepth.Count; |
1960 | if(depth > 0) | 1755 | if(depth > 0) |
1961 | { | 1756 | { |
@@ -1963,9 +1758,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1963 | throw new Exception("call label stack depth " + depth + " at " + errorAt.SrcLoc); | 1758 | throw new Exception("call label stack depth " + depth + " at " + errorAt.SrcLoc); |
1964 | } | 1759 | } |
1965 | 1760 | ||
1966 | /* | 1761 | // Eval stack is empty so the restore code can handle it. |
1967 | * Eval stack is empty so the restore code can handle it. | ||
1968 | */ | ||
1969 | this.index = scg.actCallLabels.Count; | 1762 | this.index = scg.actCallLabels.Count; |
1970 | scg.actCallLabels.AddLast(this); | 1763 | scg.actCallLabels.AddLast(this); |
1971 | scg.allCallLabels.AddLast(this); | 1764 | scg.allCallLabels.AddLast(this); |
@@ -2094,23 +1887,17 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2094 | if(!mightGetHere) | 1887 | if(!mightGetHere) |
2095 | return; | 1888 | return; |
2096 | 1889 | ||
2097 | /* | 1890 | // Push new current statement block pointer for anyone who cares. |
2098 | * Push new current statement block pointer for anyone who cares. | ||
2099 | */ | ||
2100 | TokenStmtBlock oldStmtBlock = curStmtBlock; | 1891 | TokenStmtBlock oldStmtBlock = curStmtBlock; |
2101 | curStmtBlock = stmtBlock; | 1892 | curStmtBlock = stmtBlock; |
2102 | 1893 | ||
2103 | /* | 1894 | // Output the statements that make up the block. |
2104 | * Output the statements that make up the block. | ||
2105 | */ | ||
2106 | for(Token t = stmtBlock.statements; t != null; t = t.nextToken) | 1895 | for(Token t = stmtBlock.statements; t != null; t = t.nextToken) |
2107 | { | 1896 | { |
2108 | GenerateStmt((TokenStmt)t); | 1897 | GenerateStmt((TokenStmt)t); |
2109 | } | 1898 | } |
2110 | 1899 | ||
2111 | /* | 1900 | // Pop the current statement block. |
2112 | * Pop the current statement block. | ||
2113 | */ | ||
2114 | curStmtBlock = oldStmtBlock; | 1901 | curStmtBlock = oldStmtBlock; |
2115 | } | 1902 | } |
2116 | 1903 | ||
@@ -2122,23 +1909,17 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2122 | if(!mightGetHere) | 1909 | if(!mightGetHere) |
2123 | return; | 1910 | return; |
2124 | 1911 | ||
2125 | /* | 1912 | // Make sure we are in a breakable situation. |
2126 | * Make sure we are in a breakable situation. | ||
2127 | */ | ||
2128 | if(curBreakTarg == null) | 1913 | if(curBreakTarg == null) |
2129 | { | 1914 | { |
2130 | ErrorMsg(breakStmt, "not in a breakable situation"); | 1915 | ErrorMsg(breakStmt, "not in a breakable situation"); |
2131 | return; | 1916 | return; |
2132 | } | 1917 | } |
2133 | 1918 | ||
2134 | /* | 1919 | // Tell anyone who cares that the break target was actually used. |
2135 | * Tell anyone who cares that the break target was actually used. | ||
2136 | */ | ||
2137 | curBreakTarg.used = true; | 1920 | curBreakTarg.used = true; |
2138 | 1921 | ||
2139 | /* | 1922 | // Output the instructions. |
2140 | * Output the instructions. | ||
2141 | */ | ||
2142 | EmitJumpCode(curBreakTarg.label, curBreakTarg.block, breakStmt); | 1923 | EmitJumpCode(curBreakTarg.label, curBreakTarg.block, breakStmt); |
2143 | } | 1924 | } |
2144 | 1925 | ||
@@ -2150,23 +1931,17 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2150 | if(!mightGetHere) | 1931 | if(!mightGetHere) |
2151 | return; | 1932 | return; |
2152 | 1933 | ||
2153 | /* | 1934 | // Make sure we are in a contable situation. |
2154 | * Make sure we are in a contable situation. | ||
2155 | */ | ||
2156 | if(curContTarg == null) | 1935 | if(curContTarg == null) |
2157 | { | 1936 | { |
2158 | ErrorMsg(contStmt, "not in a continueable situation"); | 1937 | ErrorMsg(contStmt, "not in a continueable situation"); |
2159 | return; | 1938 | return; |
2160 | } | 1939 | } |
2161 | 1940 | ||
2162 | /* | 1941 | // Tell anyone who cares that the continue target was actually used. |
2163 | * Tell anyone who cares that the continue target was actually used. | ||
2164 | */ | ||
2165 | curContTarg.used = true; | 1942 | curContTarg.used = true; |
2166 | 1943 | ||
2167 | /* | 1944 | // Output the instructions. |
2168 | * Output the instructions. | ||
2169 | */ | ||
2170 | EmitJumpCode(curContTarg.label, curContTarg.block, contStmt); | 1945 | EmitJumpCode(curContTarg.label, curContTarg.block, contStmt); |
2171 | } | 1946 | } |
2172 | 1947 | ||
@@ -2199,29 +1974,21 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2199 | CompValu testRVal = GenerateFromRVal(doStmt.testRVal); | 1974 | CompValu testRVal = GenerateFromRVal(doStmt.testRVal); |
2200 | if(IsConstBoolExprTrue(testRVal)) | 1975 | if(IsConstBoolExprTrue(testRVal)) |
2201 | { | 1976 | { |
2202 | 1977 | // Unconditional looping, unconditional branch and | |
2203 | /* | 1978 | // say we never fall through to next statement. |
2204 | * Unconditional looping, unconditional branch and | ||
2205 | * say we never fall through to next statement. | ||
2206 | */ | ||
2207 | ilGen.Emit(doStmt, OpCodes.Br, loopLabel); | 1979 | ilGen.Emit(doStmt, OpCodes.Br, loopLabel); |
2208 | mightGetHere = false; | 1980 | mightGetHere = false; |
2209 | } | 1981 | } |
2210 | else | 1982 | else |
2211 | { | 1983 | { |
2212 | 1984 | // Conditional looping, test and brach back to top of loop. | |
2213 | /* | ||
2214 | * Conditional looping, test and brach back to top of loop. | ||
2215 | */ | ||
2216 | testRVal.PushVal(this, doStmt.testRVal, tokenTypeBool); | 1985 | testRVal.PushVal(this, doStmt.testRVal, tokenTypeBool); |
2217 | ilGen.Emit(doStmt, OpCodes.Brtrue, loopLabel); | 1986 | ilGen.Emit(doStmt, OpCodes.Brtrue, loopLabel); |
2218 | } | 1987 | } |
2219 | } | 1988 | } |
2220 | 1989 | ||
2221 | /* | 1990 | // If 'break' statement was used, output target label. |
2222 | * If 'break' statement was used, output target label. | 1991 | // And assume that since a 'break' statement was used, it's possible for the code to get here. |
2223 | * And assume that since a 'break' statement was used, it's possible for the code to get here. | ||
2224 | */ | ||
2225 | if(curBreakTarg.used) | 1992 | if(curBreakTarg.used) |
2226 | { | 1993 | { |
2227 | ilGen.MarkLabel(curBreakTarg.label); | 1994 | ilGen.MarkLabel(curBreakTarg.label); |
@@ -2253,10 +2020,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2253 | } | 2020 | } |
2254 | ilGen.MarkLabel(loopLabel); | 2021 | ilGen.MarkLabel(loopLabel); |
2255 | 2022 | ||
2256 | /* | 2023 | // See if we have a test expression that is other than a constant TRUE. |
2257 | * See if we have a test expression that is other than a constant TRUE. | 2024 | // If so, test it and conditionally branch to end if false. |
2258 | * If so, test it and conditionally branch to end if false. | ||
2259 | */ | ||
2260 | if(forStmt.testRVal != null) | 2025 | if(forStmt.testRVal != null) |
2261 | { | 2026 | { |
2262 | CompValu testRVal = GenerateFromRVal(forStmt.testRVal); | 2027 | CompValu testRVal = GenerateFromRVal(forStmt.testRVal); |
@@ -2268,14 +2033,10 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2268 | } | 2033 | } |
2269 | } | 2034 | } |
2270 | 2035 | ||
2271 | /* | 2036 | // Output loop body. |
2272 | * Output loop body. | ||
2273 | */ | ||
2274 | GenerateStmt(forStmt.bodyStmt); | 2037 | GenerateStmt(forStmt.bodyStmt); |
2275 | 2038 | ||
2276 | /* | 2039 | // Here's where a 'continue' statement jumps to. |
2277 | * Here's where a 'continue' statement jumps to. | ||
2278 | */ | ||
2279 | if(curContTarg.used) | 2040 | if(curContTarg.used) |
2280 | { | 2041 | { |
2281 | ilGen.MarkLabel(curContTarg.label); | 2042 | ilGen.MarkLabel(curContTarg.label); |
@@ -2284,27 +2045,20 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2284 | 2045 | ||
2285 | if(mightGetHere) | 2046 | if(mightGetHere) |
2286 | { | 2047 | { |
2287 | 2048 | // After checking for excessive CPU time, output increment statement, if any. | |
2288 | /* | ||
2289 | * After checking for excessive CPU time, output increment statement, if any. | ||
2290 | */ | ||
2291 | EmitCallCheckRun(forStmt, false); | 2049 | EmitCallCheckRun(forStmt, false); |
2292 | if(forStmt.incrRVal != null) | 2050 | if(forStmt.incrRVal != null) |
2293 | { | 2051 | { |
2294 | GenerateFromRVal(forStmt.incrRVal); | 2052 | GenerateFromRVal(forStmt.incrRVal); |
2295 | } | 2053 | } |
2296 | 2054 | ||
2297 | /* | 2055 | // Unconditional branch back to beginning of loop. |
2298 | * Unconditional branch back to beginning of loop. | ||
2299 | */ | ||
2300 | ilGen.Emit(forStmt, OpCodes.Br, loopLabel); | 2056 | ilGen.Emit(forStmt, OpCodes.Br, loopLabel); |
2301 | } | 2057 | } |
2302 | 2058 | ||
2303 | /* | 2059 | // If test needs label, output label for it to jump to. |
2304 | * If test needs label, output label for it to jump to. | 2060 | // Otherwise, clear mightGetHere as we know loop never |
2305 | * Otherwise, clear mightGetHere as we know loop never | 2061 | // falls out the bottom. |
2306 | * falls out the bottom. | ||
2307 | */ | ||
2308 | mightGetHere = curBreakTarg.used; | 2062 | mightGetHere = curBreakTarg.used; |
2309 | if(mightGetHere) | 2063 | if(mightGetHere) |
2310 | { | 2064 | { |
@@ -2433,16 +2187,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2433 | 2187 | ||
2434 | bool constVal; | 2188 | bool constVal; |
2435 | 2189 | ||
2436 | /* | 2190 | // Test condition and see if constant test expression. |
2437 | * Test condition and see if constant test expression. | ||
2438 | */ | ||
2439 | CompValu testRVal = GenerateFromRVal(ifStmt.testRVal); | 2191 | CompValu testRVal = GenerateFromRVal(ifStmt.testRVal); |
2440 | if(IsConstBoolExpr(testRVal, out constVal)) | 2192 | if(IsConstBoolExpr(testRVal, out constVal)) |
2441 | { | 2193 | { |
2442 | 2194 | // Constant, output just either the true or else part. | |
2443 | /* | ||
2444 | * Constant, output just either the true or else part. | ||
2445 | */ | ||
2446 | if(constVal) | 2195 | if(constVal) |
2447 | { | 2196 | { |
2448 | GenerateStmt(ifStmt.trueStmt); | 2197 | GenerateStmt(ifStmt.trueStmt); |
@@ -2454,10 +2203,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2454 | } | 2203 | } |
2455 | else if(ifStmt.elseStmt == null) | 2204 | else if(ifStmt.elseStmt == null) |
2456 | { | 2205 | { |
2457 | 2206 | // This is an 'if' statement without an 'else' clause. | |
2458 | /* | ||
2459 | * This is an 'if' statement without an 'else' clause. | ||
2460 | */ | ||
2461 | testRVal.PushVal(this, ifStmt.testRVal, tokenTypeBool); | 2207 | testRVal.PushVal(this, ifStmt.testRVal, tokenTypeBool); |
2462 | ScriptMyLabel doneLabel = ilGen.DefineLabel("ifdone_" + ifStmt.Unique); | 2208 | ScriptMyLabel doneLabel = ilGen.DefineLabel("ifdone_" + ifStmt.Unique); |
2463 | ilGen.Emit(ifStmt, OpCodes.Brfalse, doneLabel); // brfalse doneLabel | 2209 | ilGen.Emit(ifStmt, OpCodes.Brfalse, doneLabel); // brfalse doneLabel |
@@ -2467,10 +2213,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2467 | } | 2213 | } |
2468 | else | 2214 | else |
2469 | { | 2215 | { |
2470 | 2216 | // This is an 'if' statement with an 'else' clause. | |
2471 | /* | ||
2472 | * This is an 'if' statement with an 'else' clause. | ||
2473 | */ | ||
2474 | testRVal.PushVal(this, ifStmt.testRVal, tokenTypeBool); | 2217 | testRVal.PushVal(this, ifStmt.testRVal, tokenTypeBool); |
2475 | ScriptMyLabel elseLabel = ilGen.DefineLabel("ifelse_" + ifStmt.Unique); | 2218 | ScriptMyLabel elseLabel = ilGen.DefineLabel("ifelse_" + ifStmt.Unique); |
2476 | ilGen.Emit(ifStmt, OpCodes.Brfalse, elseLabel); // brfalse elseLabel | 2219 | ilGen.Emit(ifStmt, OpCodes.Brfalse, elseLabel); // brfalse elseLabel |
@@ -2494,9 +2237,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2494 | if(!mightGetHere) | 2237 | if(!mightGetHere) |
2495 | return; | 2238 | return; |
2496 | 2239 | ||
2497 | /* | 2240 | // Make sure the target label is defined somewhere in the function. |
2498 | * Make sure the target label is defined somewhere in the function. | ||
2499 | */ | ||
2500 | TokenStmtLabel stmtLabel; | 2241 | TokenStmtLabel stmtLabel; |
2501 | if(!curDeclFunc.labels.TryGetValue(jumpStmt.label.val, out stmtLabel)) | 2242 | if(!curDeclFunc.labels.TryGetValue(jumpStmt.label.val, out stmtLabel)) |
2502 | { | 2243 | { |
@@ -2509,9 +2250,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2509 | stmtLabel.labelTagged = true; | 2250 | stmtLabel.labelTagged = true; |
2510 | } | 2251 | } |
2511 | 2252 | ||
2512 | /* | 2253 | // Emit instructions to do the jump. |
2513 | * Emit instructions to do the jump. | ||
2514 | */ | ||
2515 | EmitJumpCode(stmtLabel.labelStruct, stmtLabel.block, jumpStmt); | 2254 | EmitJumpCode(stmtLabel.labelStruct, stmtLabel.block, jumpStmt); |
2516 | } | 2255 | } |
2517 | 2256 | ||
@@ -2522,20 +2261,17 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2522 | */ | 2261 | */ |
2523 | private void EmitJumpCode(ScriptMyLabel target, TokenStmtBlock targetsBlock, Token errorAt) | 2262 | private void EmitJumpCode(ScriptMyLabel target, TokenStmtBlock targetsBlock, Token errorAt) |
2524 | { | 2263 | { |
2525 | /* | 2264 | // Jumps never fall through. |
2526 | * Jumps never fall through. | 2265 | |
2527 | */ | ||
2528 | mightGetHere = false; | 2266 | mightGetHere = false; |
2529 | 2267 | ||
2530 | /* | 2268 | // Find which block the target label is in. Must be in this or an outer block, |
2531 | * Find which block the target label is in. Must be in this or an outer block, | 2269 | // no laterals allowed. And if we exit a try/catch block, use Leave instead of Br. |
2532 | * no laterals allowed. And if we exit a try/catch block, use Leave instead of Br. | 2270 | // |
2533 | * | 2271 | // jump lateral; |
2534 | * jump lateral; | 2272 | // { |
2535 | * { | 2273 | // @lateral; |
2536 | * @lateral; | 2274 | // } |
2537 | * } | ||
2538 | */ | ||
2539 | bool useLeave = false; | 2275 | bool useLeave = false; |
2540 | TokenStmtBlock stmtBlock; | 2276 | TokenStmtBlock stmtBlock; |
2541 | Stack<TokenStmtTry> finallyBlocksCalled = new Stack<TokenStmtTry>(); | 2277 | Stack<TokenStmtTry> finallyBlocksCalled = new Stack<TokenStmtTry>(); |
@@ -2559,46 +2295,44 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2559 | } | 2295 | } |
2560 | } | 2296 | } |
2561 | 2297 | ||
2562 | /* | 2298 | // If popping through more than one finally block, we have to break it down for the stack |
2563 | * If popping through more than one finally block, we have to break it down for the stack | 2299 | // capture and restore code, one finally block at a time. |
2564 | * capture and restore code, one finally block at a time. | 2300 | // |
2565 | * | 2301 | // try { |
2566 | * try { | 2302 | // try { |
2567 | * try { | 2303 | // try { |
2568 | * try { | 2304 | // jump exit; |
2569 | * jump exit; | 2305 | // } finally { |
2570 | * } finally { | 2306 | // llOwnerSay ("exiting inner"); |
2571 | * llOwnerSay ("exiting inner"); | 2307 | // } |
2572 | * } | 2308 | // } finally { |
2573 | * } finally { | 2309 | // llOwnerSay ("exiting middle"); |
2574 | * llOwnerSay ("exiting middle"); | 2310 | // } |
2575 | * } | 2311 | // } finally { |
2576 | * } finally { | 2312 | // llOwnerSay ("exiting outer"); |
2577 | * llOwnerSay ("exiting outer"); | 2313 | // } |
2578 | * } | 2314 | // @exit; |
2579 | * @exit; | 2315 | // |
2580 | * | 2316 | // try { |
2581 | * try { | 2317 | // try { |
2582 | * try { | 2318 | // try { |
2583 | * try { | 2319 | // jump intr2_exit; <<< gets its own tryNo call label so inner try knows where to restore to |
2584 | * jump intr2_exit; <<< gets its own tryNo call label so inner try knows where to restore to | 2320 | // } finally { |
2585 | * } finally { | 2321 | // llOwnerSay ("exiting inner"); |
2586 | * llOwnerSay ("exiting inner"); | 2322 | // } |
2587 | * } | 2323 | // jump outtry2; |
2588 | * jump outtry2; | 2324 | // @intr2_exit; jump intr1_exit; <<< gets its own tryNo call label so middle try knows where to restore to |
2589 | * @intr2_exit; jump intr1_exit; <<< gets its own tryNo call label so middle try knows where to restore to | 2325 | // @outtry2; |
2590 | * @outtry2; | 2326 | // } finally { |
2591 | * } finally { | 2327 | // llOwnerSay ("exiting middle"); |
2592 | * llOwnerSay ("exiting middle"); | 2328 | // } |
2593 | * } | 2329 | // jump outtry1; |
2594 | * jump outtry1; | 2330 | // @intr1_exit: jump exit; <<< gets its own tryNo call label so outer try knows where to restore to |
2595 | * @intr1_exit: jump exit; <<< gets its own tryNo call label so outer try knows where to restore to | 2331 | // @outtry1; |
2596 | * @outtry1; | 2332 | // } finally { |
2597 | * } finally { | 2333 | // llOwnerSay ("exiting outer"); |
2598 | * llOwnerSay ("exiting outer"); | 2334 | // } |
2599 | * } | 2335 | // @exit; |
2600 | * @exit; | ||
2601 | */ | ||
2602 | int level = 0; | 2336 | int level = 0; |
2603 | while(finallyBlocksCalled.Count > 1) | 2337 | while(finallyBlocksCalled.Count > 1) |
2604 | { | 2338 | { |
@@ -2615,12 +2349,10 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2615 | target = iLeave.jumpIntoLabel; | 2349 | target = iLeave.jumpIntoLabel; |
2616 | } | 2350 | } |
2617 | 2351 | ||
2618 | /* | 2352 | // Finally output the branch/leave opcode. |
2619 | * Finally output the branch/leave opcode. | 2353 | // If using Leave, prefix with a call label in case the corresponding finally block |
2620 | * If using Leave, prefix with a call label in case the corresponding finally block | 2354 | // calls CheckRun() and that CheckRun() captures the stack, it will have a point to |
2621 | * calls CheckRun() and that CheckRun() captures the stack, it will have a point to | 2355 | // restore to that will properly jump back into the finally block. |
2622 | * restore to that will properly jump back into the finally block. | ||
2623 | */ | ||
2624 | if(useLeave) | 2356 | if(useLeave) |
2625 | { | 2357 | { |
2626 | new CallLabel(this, errorAt); | 2358 | new CallLabel(this, errorAt); |
@@ -2650,13 +2382,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2650 | EmitCallCheckRun(labelStmt, false); | 2382 | EmitCallCheckRun(labelStmt, false); |
2651 | } | 2383 | } |
2652 | 2384 | ||
2653 | /* | 2385 | // We are going to say that the label falls through. |
2654 | * We are going to say that the label falls through. | 2386 | // It would be nice if we could analyze all referencing |
2655 | * It would be nice if we could analyze all referencing | 2387 | // goto's to see if all of them are not used but we are |
2656 | * goto's to see if all of them are not used but we are | 2388 | // going to assume that if the script writer put a label |
2657 | * going to assume that if the script writer put a label | 2389 | // somewhere, it is probably going to be used. |
2658 | * somewhere, it is probably going to be used. | ||
2659 | */ | ||
2660 | mightGetHere = true; | 2390 | mightGetHere = true; |
2661 | } | 2391 | } |
2662 | 2392 | ||
@@ -2670,34 +2400,26 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2670 | */ | 2400 | */ |
2671 | private void GenerateStmtNewobj(TokenStmtNewobj newobjStmt) | 2401 | private void GenerateStmtNewobj(TokenStmtNewobj newobjStmt) |
2672 | { | 2402 | { |
2673 | /* | 2403 | // First off, malloc a new empty XMRSDTypeClObj object |
2674 | * First off, malloc a new empty XMRSDTypeClObj object | 2404 | // then call the XMRSDTypeClObj()-level constructor. |
2675 | * then call the XMRSDTypeClObj()-level constructor. | 2405 | // Store the result in local var $objptr. |
2676 | * Store the result in local var $objptr. | ||
2677 | */ | ||
2678 | newobjStmt.objptrVar.location.PopPre(this, newobjStmt); | 2406 | newobjStmt.objptrVar.location.PopPre(this, newobjStmt); |
2679 | ilGen.Emit(newobjStmt, OpCodes.Ldarg_0); | 2407 | ilGen.Emit(newobjStmt, OpCodes.Ldarg_0); |
2680 | ilGen.Emit(newobjStmt, OpCodes.Ldc_I4, curDeclFunc.sdtClass.sdTypeIndex); | 2408 | ilGen.Emit(newobjStmt, OpCodes.Ldc_I4, curDeclFunc.sdtClass.sdTypeIndex); |
2681 | ilGen.Emit(newobjStmt, OpCodes.Newobj, sdtClassConstructorInfo); | 2409 | ilGen.Emit(newobjStmt, OpCodes.Newobj, sdtClassConstructorInfo); |
2682 | newobjStmt.objptrVar.location.PopPost(this, newobjStmt); | 2410 | newobjStmt.objptrVar.location.PopPost(this, newobjStmt); |
2683 | 2411 | ||
2684 | /* | 2412 | // Now call the script-level constructor. |
2685 | * Now call the script-level constructor. | 2413 | // Pass the object pointer in $objptr as it's 'this' argument. |
2686 | * Pass the object pointer in $objptr as it's 'this' argument. | 2414 | // The rest of the args are the script-visible args and are just copied from $new() call. |
2687 | * The rest of the args are the script-visible args and are just copied from $new() call. | ||
2688 | */ | ||
2689 | GenerateFromRValCall(newobjStmt.rValCall); | 2415 | GenerateFromRValCall(newobjStmt.rValCall); |
2690 | 2416 | ||
2691 | /* | 2417 | // Put object pointer in retval so it gets returned to caller. |
2692 | * Put object pointer in retval so it gets returned to caller. | ||
2693 | */ | ||
2694 | newobjStmt.objptrVar.location.PushVal(this, newobjStmt); | 2418 | newobjStmt.objptrVar.location.PushVal(this, newobjStmt); |
2695 | ilGen.Emit(newobjStmt, OpCodes.Stloc, retValue); | 2419 | ilGen.Emit(newobjStmt, OpCodes.Stloc, retValue); |
2696 | 2420 | ||
2697 | /* | 2421 | // Exit the function like a return statement. |
2698 | * Exit the function like a return statement. | 2422 | // And thus we don't fall through. |
2699 | * And thus we don't fall through. | ||
2700 | */ | ||
2701 | ilGen.Emit(newobjStmt, OpCodes.Leave, retLabel); | 2423 | ilGen.Emit(newobjStmt, OpCodes.Leave, retLabel); |
2702 | mightGetHere = false; | 2424 | mightGetHere = false; |
2703 | } | 2425 | } |
@@ -2740,10 +2462,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2740 | ilGen.Emit(retStmt, OpCodes.Stloc, retValue); | 2462 | ilGen.Emit(retStmt, OpCodes.Stloc, retValue); |
2741 | } | 2463 | } |
2742 | 2464 | ||
2743 | /* | 2465 | // Use a OpCodes.Leave instruction to break out of any try { } blocks. |
2744 | * Use a OpCodes.Leave instruction to break out of any try { } blocks. | 2466 | // All Leave's inside script-defined try { } need call labels (see GenerateStmtTry()). |
2745 | * All Leave's inside script-defined try { } need call labels (see GenerateStmtTry()). | ||
2746 | */ | ||
2747 | bool brokeOutOfTry = false; | 2467 | bool brokeOutOfTry = false; |
2748 | for(TokenStmtBlock stmtBlock = curStmtBlock; stmtBlock != null; stmtBlock = stmtBlock.outerStmtBlock) | 2468 | for(TokenStmtBlock stmtBlock = curStmtBlock; stmtBlock != null; stmtBlock = stmtBlock.outerStmtBlock) |
2749 | { | 2469 | { |
@@ -2759,9 +2479,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2759 | if(brokeOutOfTry) | 2479 | if(brokeOutOfTry) |
2760 | openCallLabel = null; | 2480 | openCallLabel = null; |
2761 | 2481 | ||
2762 | /* | 2482 | // 'return' statements never fall through. |
2763 | * 'return' statements never fall through. | ||
2764 | */ | ||
2765 | mightGetHere = false; | 2483 | mightGetHere = false; |
2766 | } | 2484 | } |
2767 | 2485 | ||
@@ -2787,10 +2505,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2787 | 2505 | ||
2788 | int index = 0; // 'default' state | 2506 | int index = 0; // 'default' state |
2789 | 2507 | ||
2790 | /* | 2508 | // Set new state value by throwing an exception. |
2791 | * Set new state value by throwing an exception. | 2509 | // These exceptions aren't catchable by script-level try { } catch { }. |
2792 | * These exceptions aren't catchable by script-level try { } catch { }. | ||
2793 | */ | ||
2794 | if((stateStmt.state != null) && !stateIndices.TryGetValue(stateStmt.state.val, out index)) | 2510 | if((stateStmt.state != null) && !stateIndices.TryGetValue(stateStmt.state.val, out index)) |
2795 | { | 2511 | { |
2796 | // The moron XEngine compiles scripts that reference undefined states. | 2512 | // The moron XEngine compiles scripts that reference undefined states. |
@@ -2808,9 +2524,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2808 | } | 2524 | } |
2809 | ilGen.Emit(stateStmt, OpCodes.Throw); | 2525 | ilGen.Emit(stateStmt, OpCodes.Throw); |
2810 | 2526 | ||
2811 | /* | 2527 | // 'state' statements never fall through. |
2812 | * 'state' statements never fall through. | ||
2813 | */ | ||
2814 | mightGetHere = false; | 2528 | mightGetHere = false; |
2815 | } | 2529 | } |
2816 | 2530 | ||
@@ -2822,22 +2536,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2822 | if(!mightGetHere) | 2536 | if(!mightGetHere) |
2823 | return; | 2537 | return; |
2824 | 2538 | ||
2825 | /* | 2539 | // Output code to calculate index. |
2826 | * Output code to calculate index. | ||
2827 | */ | ||
2828 | CompValu testRVal = GenerateFromRVal(switchStmt.testRVal); | 2540 | CompValu testRVal = GenerateFromRVal(switchStmt.testRVal); |
2829 | 2541 | ||
2830 | /* | 2542 | // Generate code based on string or integer index. |
2831 | * Generate code based on string or integer index. | ||
2832 | */ | ||
2833 | if((testRVal.type is TokenTypeKey) || (testRVal.type is TokenTypeStr)) | 2543 | if((testRVal.type is TokenTypeKey) || (testRVal.type is TokenTypeStr)) |
2834 | { | ||
2835 | GenerateStmtSwitchStr(testRVal, switchStmt); | 2544 | GenerateStmtSwitchStr(testRVal, switchStmt); |
2836 | } | ||
2837 | else | 2545 | else |
2838 | { | ||
2839 | GenerateStmtSwitchInt(testRVal, switchStmt); | 2546 | GenerateStmtSwitchInt(testRVal, switchStmt); |
2840 | } | ||
2841 | } | 2547 | } |
2842 | 2548 | ||
2843 | private void GenerateStmtSwitchInt(CompValu testRVal, TokenStmtSwitch switchStmt) | 2549 | private void GenerateStmtSwitchInt(CompValu testRVal, TokenStmtSwitch switchStmt) |
@@ -2851,17 +2557,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2851 | 2557 | ||
2852 | curBreakTarg = new BreakContTarg(this, "switchbreak_" + switchStmt.Unique); | 2558 | curBreakTarg = new BreakContTarg(this, "switchbreak_" + switchStmt.Unique); |
2853 | 2559 | ||
2854 | /* | 2560 | // Build list of cases sorted by ascending values. |
2855 | * Build list of cases sorted by ascending values. | 2561 | // There should not be any overlapping of values. |
2856 | * There should not be any overlapping of values. | ||
2857 | */ | ||
2858 | for(TokenSwitchCase thisCase = switchStmt.cases; thisCase != null; thisCase = thisCase.nextCase) | 2562 | for(TokenSwitchCase thisCase = switchStmt.cases; thisCase != null; thisCase = thisCase.nextCase) |
2859 | { | 2563 | { |
2860 | thisCase.label = ilGen.DefineLabel("case_" + thisCase.Unique); | 2564 | thisCase.label = ilGen.DefineLabel("case_" + thisCase.Unique); |
2861 | 2565 | ||
2862 | /* | 2566 | // The default case if any, goes in its own separate slot. |
2863 | * The default case if any, goes in its own separate slot. | ||
2864 | */ | ||
2865 | if(thisCase.rVal1 == null) | 2567 | if(thisCase.rVal1 == null) |
2866 | { | 2568 | { |
2867 | if(defaultCase != null) | 2569 | if(defaultCase != null) |
@@ -2875,9 +2577,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2875 | continue; | 2577 | continue; |
2876 | } | 2578 | } |
2877 | 2579 | ||
2878 | /* | 2580 | // Evaluate case operands, they must be compile-time integer constants. |
2879 | * Evaluate case operands, they must be compile-time integer constants. | ||
2880 | */ | ||
2881 | CompValu rVal = GenerateFromRVal(thisCase.rVal1); | 2581 | CompValu rVal = GenerateFromRVal(thisCase.rVal1); |
2882 | if(!IsConstIntExpr(rVal, out thisCase.val1)) | 2582 | if(!IsConstIntExpr(rVal, out thisCase.val1)) |
2883 | { | 2583 | { |
@@ -2900,10 +2600,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2900 | return; | 2600 | return; |
2901 | } | 2601 | } |
2902 | 2602 | ||
2903 | /* | 2603 | // Insert into list, sorted by value. |
2904 | * Insert into list, sorted by value. | 2604 | // Note that both limits are inclusive. |
2905 | * Note that both limits are inclusive. | ||
2906 | */ | ||
2907 | TokenSwitchCase lastCase = null; | 2605 | TokenSwitchCase lastCase = null; |
2908 | TokenSwitchCase nextCase; | 2606 | TokenSwitchCase nextCase; |
2909 | for(nextCase = sortedCases; nextCase != null; nextCase = nextCase.nextSortedCase) | 2607 | for(nextCase = sortedCases; nextCase != null; nextCase = nextCase.nextSortedCase) |
@@ -2934,19 +2632,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2934 | defaultLabel = ilGen.DefineLabel("default_" + switchStmt.Unique); | 2632 | defaultLabel = ilGen.DefineLabel("default_" + switchStmt.Unique); |
2935 | } | 2633 | } |
2936 | 2634 | ||
2937 | /* | 2635 | // Output code to jump to the case statement's labels based on integer index on stack. |
2938 | * Output code to jump to the case statement's labels based on integer index on stack. | 2636 | // Note that each case still has the integer index on stack when jumped to. |
2939 | * Note that each case still has the integer index on stack when jumped to. | ||
2940 | */ | ||
2941 | int offset = 0; | 2637 | int offset = 0; |
2942 | for(TokenSwitchCase thisCase = sortedCases; thisCase != null;) | 2638 | for(TokenSwitchCase thisCase = sortedCases; thisCase != null;) |
2943 | { | 2639 | { |
2944 | 2640 | // Scan through list of cases to find the maximum number of cases who's numvalues-to-case ratio | |
2945 | /* | 2641 | // is from 0.5 to 2.0. If such a group is found, use a CIL switch for them. If not, just use a |
2946 | * Scan through list of cases to find the maximum number of cases who's numvalues-to-case ratio | 2642 | // compare-and-branch for the current case. |
2947 | * is from 0.5 to 2.0. If such a group is found, use a CIL switch for them. If not, just use a | ||
2948 | * compare-and-branch for the current case. | ||
2949 | */ | ||
2950 | int numCases = 0; | 2643 | int numCases = 0; |
2951 | int numFound = 0; | 2644 | int numFound = 0; |
2952 | int lowValue = thisCase.val1; | 2645 | int lowValue = thisCase.val1; |
@@ -2963,23 +2656,18 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2963 | } | 2656 | } |
2964 | if(numFound > 1) | 2657 | if(numFound > 1) |
2965 | { | 2658 | { |
2966 | 2659 | // There is a group of case's, starting with thisCase, that fall within our criteria, ie, | |
2967 | /* | 2660 | // that have a nice density of meaningful jumps. |
2968 | * There is a group of case's, starting with thisCase, that fall within our criteria, ie, | 2661 | // |
2969 | * that have a nice density of meaningful jumps. | 2662 | // So first generate an array of jumps to the default label (explicit or implicit). |
2970 | * | ||
2971 | * So first generate an array of jumps to the default label (explicit or implicit). | ||
2972 | */ | ||
2973 | ScriptMyLabel[] labels = new ScriptMyLabel[numValues]; | 2663 | ScriptMyLabel[] labels = new ScriptMyLabel[numValues]; |
2974 | for(int i = 0; i < numValues; i++) | 2664 | for(int i = 0; i < numValues; i++) |
2975 | { | 2665 | { |
2976 | labels[i] = defaultLabel; | 2666 | labels[i] = defaultLabel; |
2977 | } | 2667 | } |
2978 | 2668 | ||
2979 | /* | 2669 | // Next, for each case in that group, fill in the corresponding array entries to jump to |
2980 | * Next, for each case in that group, fill in the corresponding array entries to jump to | 2670 | // that case's label. |
2981 | * that case's label. | ||
2982 | */ | ||
2983 | do | 2671 | do |
2984 | { | 2672 | { |
2985 | for(int i = thisCase.val1; i <= thisCase.val2; i++) | 2673 | for(int i = thisCase.val1; i <= thisCase.val2; i++) |
@@ -2989,10 +2677,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2989 | thisCase = thisCase.nextSortedCase; | 2677 | thisCase = thisCase.nextSortedCase; |
2990 | } while(--numFound > 0); | 2678 | } while(--numFound > 0); |
2991 | 2679 | ||
2992 | /* | 2680 | // Subtract the low value and do the computed jump. |
2993 | * Subtract the low value and do the computed jump. | 2681 | // The OpCodes.Switch falls through if out of range (unsigned compare). |
2994 | * The OpCodes.Switch falls through if out of range (unsigned compare). | ||
2995 | */ | ||
2996 | if(offset != lowValue) | 2682 | if(offset != lowValue) |
2997 | { | 2683 | { |
2998 | ilGen.Emit(switchStmt, OpCodes.Ldc_I4, lowValue - offset); | 2684 | ilGen.Emit(switchStmt, OpCodes.Ldc_I4, lowValue - offset); |
@@ -3004,11 +2690,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
3004 | } | 2690 | } |
3005 | else | 2691 | else |
3006 | { | 2692 | { |
3007 | 2693 | // It's not economical to do with a computed jump, so output a subtract/compare/branch | |
3008 | /* | 2694 | // for thisCase. |
3009 | * It's not economical to do with a computed jump, so output a subtract/compare/branch | ||
3010 | * for thisCase. | ||
3011 | */ | ||
3012 | if(lowValue == thisCase.val2) | 2695 | if(lowValue == thisCase.val2) |
3013 | { | 2696 | { |
3014 | ilGen.Emit(switchStmt, OpCodes.Dup); | 2697 | ilGen.Emit(switchStmt, OpCodes.Dup); |
@@ -3032,15 +2715,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
3032 | } | 2715 | } |
3033 | ilGen.Emit(switchStmt, OpCodes.Br, defaultLabel); | 2716 | ilGen.Emit(switchStmt, OpCodes.Br, defaultLabel); |
3034 | 2717 | ||
3035 | /* | 2718 | // Output code for the cases themselves, in the order given by the programmer, |
3036 | * Output code for the cases themselves, in the order given by the programmer, | 2719 | // so they fall through as programmer wants. This includes the default case, if any. |
3037 | * so they fall through as programmer wants. This includes the default case, if any. | 2720 | // |
3038 | * | 2721 | // Each label is jumped to with the index still on the stack. So pop it off in case |
3039 | * Each label is jumped to with the index still on the stack. So pop it off in case | 2722 | // the case body does a goto outside the switch or a return. If the case body might |
3040 | * the case body does a goto outside the switch or a return. If the case body might | 2723 | // fall through to the next case or the bottom of the switch, push a zero so the stack |
3041 | * fall through to the next case or the bottom of the switch, push a zero so the stack | 2724 | // matches in all cases. |
3042 | * matches in all cases. | ||
3043 | */ | ||
3044 | for(TokenSwitchCase thisCase = switchStmt.cases; thisCase != null; thisCase = thisCase.nextCase) | 2725 | for(TokenSwitchCase thisCase = switchStmt.cases; thisCase != null; thisCase = thisCase.nextCase) |
3045 | { | 2726 | { |
3046 | ilGen.MarkLabel(thisCase.label); // the branch comes here | 2727 | ilGen.MarkLabel(thisCase.label); // the branch comes here |
@@ -3057,28 +2738,22 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
3057 | } | 2738 | } |
3058 | } | 2739 | } |
3059 | 2740 | ||
3060 | /* | 2741 | // If no explicit default case, output the default label here. |
3061 | * If no explicit default case, output the default label here. | ||
3062 | */ | ||
3063 | if(defaultCase == null) | 2742 | if(defaultCase == null) |
3064 | { | 2743 | { |
3065 | ilGen.MarkLabel(defaultLabel); | 2744 | ilGen.MarkLabel(defaultLabel); |
3066 | mightGetHere = true; | 2745 | mightGetHere = true; |
3067 | } | 2746 | } |
3068 | 2747 | ||
3069 | /* | 2748 | // If the last case of the switch falls through out the bottom, |
3070 | * If the last case of the switch falls through out the bottom, | 2749 | // we have to pop the index still on the stack. |
3071 | * we have to pop the index still on the stack. | ||
3072 | */ | ||
3073 | if(mightGetHere) | 2750 | if(mightGetHere) |
3074 | { | 2751 | { |
3075 | ilGen.Emit(switchStmt, OpCodes.Pop); | 2752 | ilGen.Emit(switchStmt, OpCodes.Pop); |
3076 | } | 2753 | } |
3077 | 2754 | ||
3078 | /* | 2755 | // Output the 'break' statement target label. |
3079 | * Output the 'break' statement target label. | 2756 | // Note that the integer index is not on the stack at this point. |
3080 | * Note that the integer index is not on the stack at this point. | ||
3081 | */ | ||
3082 | if(curBreakTarg.used) | 2757 | if(curBreakTarg.used) |
3083 | { | 2758 | { |
3084 | ilGen.MarkLabel(curBreakTarg.label); | 2759 | ilGen.MarkLabel(curBreakTarg.label); |
@@ -3097,9 +2772,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
3097 | 2772 | ||
3098 | curBreakTarg = new BreakContTarg(this, "switchbreak_" + switchStmt.Unique); | 2773 | curBreakTarg = new BreakContTarg(this, "switchbreak_" + switchStmt.Unique); |
3099 | 2774 | ||
3100 | /* | 2775 | // Make sure value is in a temp so we don't compute it more than once. |
3101 | * Make sure value is in a temp so we don't compute it more than once. | ||
3102 | */ | ||
3103 | if(!(testRVal is CompValuTemp)) | 2776 | if(!(testRVal is CompValuTemp)) |
3104 | { | 2777 | { |
3105 | CompValuTemp temp = new CompValuTemp(testRVal.type, this); | 2778 | CompValuTemp temp = new CompValuTemp(testRVal.type, this); |
@@ -3108,17 +2781,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
3108 | testRVal = temp; | 2781 | testRVal = temp; |
3109 | } | 2782 | } |
3110 | 2783 | ||
3111 | /* | 2784 | // Build tree of cases. |
3112 | * Build tree of cases. | 2785 | // There should not be any overlapping of values. |
3113 | * There should not be any overlapping of values. | ||
3114 | */ | ||
3115 | for(TokenSwitchCase thisCase = switchStmt.cases; thisCase != null; thisCase = thisCase.nextCase) | 2786 | for(TokenSwitchCase thisCase = switchStmt.cases; thisCase != null; thisCase = thisCase.nextCase) |
3116 | { | 2787 | { |
3117 | thisCase.label = ilGen.DefineLabel("case"); | 2788 | thisCase.label = ilGen.DefineLabel("case"); |
3118 | 2789 | ||
3119 | /* | 2790 | // The default case if any, goes in its own separate slot. |
3120 | * The default case if any, goes in its own separate slot. | ||
3121 | */ | ||
3122 | if(thisCase.rVal1 == null) | 2791 | if(thisCase.rVal1 == null) |
3123 | { | 2792 | { |
3124 | if(defaultCase != null) | 2793 | if(defaultCase != null) |
@@ -3132,9 +2801,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
3132 | continue; | 2801 | continue; |
3133 | } | 2802 | } |
3134 | 2803 | ||
3135 | /* | 2804 | // Evaluate case operands, they must be compile-time string constants. |
3136 | * Evaluate case operands, they must be compile-time string constants. | ||
3137 | */ | ||
3138 | CompValu rVal = GenerateFromRVal(thisCase.rVal1); | 2805 | CompValu rVal = GenerateFromRVal(thisCase.rVal1); |
3139 | if(!IsConstStrExpr(rVal, out thisCase.str1)) | 2806 | if(!IsConstStrExpr(rVal, out thisCase.str1)) |
3140 | { | 2807 | { |
@@ -3157,31 +2824,23 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
3157 | continue; | 2824 | continue; |
3158 | } | 2825 | } |
3159 | 2826 | ||
3160 | /* | 2827 | // Insert into list, sorted by value. |
3161 | * Insert into list, sorted by value. | 2828 | // Note that both limits are inclusive. |
3162 | * Note that both limits are inclusive. | ||
3163 | */ | ||
3164 | caseTreeTop = InsertCaseInTree(caseTreeTop, thisCase); | 2829 | caseTreeTop = InsertCaseInTree(caseTreeTop, thisCase); |
3165 | } | 2830 | } |
3166 | 2831 | ||
3167 | /* | 2832 | // Balance tree so we end up generating code that does O(log2 n) comparisons. |
3168 | * Balance tree so we end up generating code that does O(log2 n) comparisons. | ||
3169 | */ | ||
3170 | caseTreeTop = BalanceTree(caseTreeTop); | 2833 | caseTreeTop = BalanceTree(caseTreeTop); |
3171 | 2834 | ||
3172 | /* | 2835 | // Output compare and branch instructions in a tree-like fashion so we do O(log2 n) comparisons. |
3173 | * Output compare and branch instructions in a tree-like fashion so we do O(log2 n) comparisons. | ||
3174 | */ | ||
3175 | if(defaultLabel == null) | 2836 | if(defaultLabel == null) |
3176 | { | 2837 | { |
3177 | defaultLabel = ilGen.DefineLabel("default"); | 2838 | defaultLabel = ilGen.DefineLabel("default"); |
3178 | } | 2839 | } |
3179 | OutputStrCase(testRVal, caseTreeTop, defaultLabel); | 2840 | OutputStrCase(testRVal, caseTreeTop, defaultLabel); |
3180 | 2841 | ||
3181 | /* | 2842 | // Output code for the cases themselves, in the order given by the programmer, |
3182 | * Output code for the cases themselves, in the order given by the programmer, | 2843 | // so they fall through as programmer wants. This includes the default case, if any. |
3183 | * so they fall through as programmer wants. This includes the default case, if any. | ||
3184 | */ | ||
3185 | for(TokenSwitchCase thisCase = switchStmt.cases; thisCase != null; thisCase = thisCase.nextCase) | 2844 | for(TokenSwitchCase thisCase = switchStmt.cases; thisCase != null; thisCase = thisCase.nextCase) |
3186 | { | 2845 | { |
3187 | ilGen.MarkLabel(thisCase.label); // the branch comes here | 2846 | ilGen.MarkLabel(thisCase.label); // the branch comes here |
@@ -3192,18 +2851,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
3192 | } | 2851 | } |
3193 | } | 2852 | } |
3194 | 2853 | ||
3195 | /* | 2854 | // If no explicit default case, output the default label here. |
3196 | * If no explicit default case, output the default label here. | ||
3197 | */ | ||
3198 | if(defaultCase == null) | 2855 | if(defaultCase == null) |
3199 | { | 2856 | { |
3200 | ilGen.MarkLabel(defaultLabel); | 2857 | ilGen.MarkLabel(defaultLabel); |
3201 | mightGetHere = true; | 2858 | mightGetHere = true; |
3202 | } | 2859 | } |
3203 | 2860 | ||
3204 | /* | 2861 | // Output the 'break' statement target label. |
3205 | * Output the 'break' statement target label. | ||
3206 | */ | ||
3207 | if(curBreakTarg.used) | 2862 | if(curBreakTarg.used) |
3208 | { | 2863 | { |
3209 | ilGen.MarkLabel(curBreakTarg.label); | 2864 | ilGen.MarkLabel(curBreakTarg.label); |
@@ -3268,10 +2923,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
3268 | int hc = CountTree(r.higherCase); | 2923 | int hc = CountTree(r.higherCase); |
3269 | TokenSwitchCase n, x; | 2924 | TokenSwitchCase n, x; |
3270 | 2925 | ||
3271 | /* | 2926 | // If lower side is heavy, move highest nodes from lower side to |
3272 | * If lower side is heavy, move highest nodes from lower side to | 2927 | // higher side until balanced. |
3273 | * higher side until balanced. | ||
3274 | */ | ||
3275 | while(lc > hc + 1) | 2928 | while(lc > hc + 1) |
3276 | { | 2929 | { |
3277 | x = ExtractHighest(r.lowerCase, out n); | 2930 | x = ExtractHighest(r.lowerCase, out n); |
@@ -3283,10 +2936,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
3283 | hc++; | 2936 | hc++; |
3284 | } | 2937 | } |
3285 | 2938 | ||
3286 | /* | 2939 | // If higher side is heavy, move lowest nodes from higher side to |
3287 | * If higher side is heavy, move lowest nodes from higher side to | 2940 | // lower side until balanced. |
3288 | * lower side until balanced. | ||
3289 | */ | ||
3290 | while(hc > lc + 1) | 2941 | while(hc > lc + 1) |
3291 | { | 2942 | { |
3292 | x = ExtractLowest(r.higherCase, out n); | 2943 | x = ExtractLowest(r.higherCase, out n); |
@@ -3298,9 +2949,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
3298 | hc--; | 2949 | hc--; |
3299 | } | 2950 | } |
3300 | 2951 | ||
3301 | /* | 2952 | // Now balance each side because they can be lopsided individually. |
3302 | * Now balance each side because they can be lopsided individually. | ||
3303 | */ | ||
3304 | r.lowerCase = BalanceTree(r.lowerCase); | 2953 | r.lowerCase = BalanceTree(r.lowerCase); |
3305 | r.higherCase = BalanceTree(r.higherCase); | 2954 | r.higherCase = BalanceTree(r.higherCase); |
3306 | return r; | 2955 | return r; |
@@ -3359,10 +3008,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
3359 | */ | 3008 | */ |
3360 | private void OutputStrCase(CompValu testRVal, TokenSwitchCase thisCase, ScriptMyLabel defaultLabel) | 3009 | private void OutputStrCase(CompValu testRVal, TokenSwitchCase thisCase, ScriptMyLabel defaultLabel) |
3361 | { | 3010 | { |
3362 | /* | 3011 | // If nothing lower on tree and there is a single case value, |
3363 | * If nothing lower on tree and there is a single case value, | 3012 | // just do one compare for equality. |
3364 | * just do one compare for equality. | ||
3365 | */ | ||
3366 | if((thisCase.lowerCase == null) && (thisCase.higherCase == null) && (thisCase.str1 == thisCase.str2)) | 3013 | if((thisCase.lowerCase == null) && (thisCase.higherCase == null) && (thisCase.str1 == thisCase.str2)) |
3367 | { | 3014 | { |
3368 | testRVal.PushVal(this, thisCase, tokenTypeStr); | 3015 | testRVal.PushVal(this, thisCase, tokenTypeStr); |
@@ -3374,28 +3021,22 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
3374 | return; | 3021 | return; |
3375 | } | 3022 | } |
3376 | 3023 | ||
3377 | /* | 3024 | // Determine where to jump if switch value is lower than lower case value. |
3378 | * Determine where to jump if switch value is lower than lower case value. | ||
3379 | */ | ||
3380 | ScriptMyLabel lowerLabel = defaultLabel; | 3025 | ScriptMyLabel lowerLabel = defaultLabel; |
3381 | if(thisCase.lowerCase != null) | 3026 | if(thisCase.lowerCase != null) |
3382 | { | 3027 | { |
3383 | lowerLabel = ilGen.DefineLabel("lower"); | 3028 | lowerLabel = ilGen.DefineLabel("lower"); |
3384 | } | 3029 | } |
3385 | 3030 | ||
3386 | /* | 3031 | // If single case value, put comparison result in this temp. |
3387 | * If single case value, put comparison result in this temp. | ||
3388 | */ | ||
3389 | CompValuTemp cmpv1 = null; | 3032 | CompValuTemp cmpv1 = null; |
3390 | if(thisCase.str1 == thisCase.str2) | 3033 | if(thisCase.str1 == thisCase.str2) |
3391 | { | 3034 | { |
3392 | cmpv1 = new CompValuTemp(tokenTypeInt, this); | 3035 | cmpv1 = new CompValuTemp(tokenTypeInt, this); |
3393 | } | 3036 | } |
3394 | 3037 | ||
3395 | /* | 3038 | // If switch value .lt. lower case value, jump to lower label. |
3396 | * If switch value .lt. lower case value, jump to lower label. | 3039 | // Maybe save comparison result in a temp. |
3397 | * Maybe save comparison result in a temp. | ||
3398 | */ | ||
3399 | testRVal.PushVal(this, thisCase, tokenTypeStr); | 3040 | testRVal.PushVal(this, thisCase, tokenTypeStr); |
3400 | ilGen.Emit(thisCase, OpCodes.Ldstr, thisCase.str1); | 3041 | ilGen.Emit(thisCase, OpCodes.Ldstr, thisCase.str1); |
3401 | ilGen.Emit(thisCase, OpCodes.Ldc_I4, (int)StringComparison.Ordinal); | 3042 | ilGen.Emit(thisCase, OpCodes.Ldc_I4, (int)StringComparison.Ordinal); |
@@ -3408,10 +3049,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
3408 | ilGen.Emit(thisCase, OpCodes.Ldc_I4_0); | 3049 | ilGen.Emit(thisCase, OpCodes.Ldc_I4_0); |
3409 | ilGen.Emit(thisCase, OpCodes.Blt, lowerLabel); | 3050 | ilGen.Emit(thisCase, OpCodes.Blt, lowerLabel); |
3410 | 3051 | ||
3411 | /* | 3052 | // If switch value .le. higher case value, jump to case code. |
3412 | * If switch value .le. higher case value, jump to case code. | 3053 | // Maybe get comparison from the temp. |
3413 | * Maybe get comparison from the temp. | ||
3414 | */ | ||
3415 | if(cmpv1 == null) | 3054 | if(cmpv1 == null) |
3416 | { | 3055 | { |
3417 | testRVal.PushVal(this, thisCase, tokenTypeStr); | 3056 | testRVal.PushVal(this, thisCase, tokenTypeStr); |
@@ -3426,9 +3065,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
3426 | ilGen.Emit(thisCase, OpCodes.Ldc_I4_0); | 3065 | ilGen.Emit(thisCase, OpCodes.Ldc_I4_0); |
3427 | ilGen.Emit(thisCase, OpCodes.Ble, thisCase.label); | 3066 | ilGen.Emit(thisCase, OpCodes.Ble, thisCase.label); |
3428 | 3067 | ||
3429 | /* | 3068 | // Output code for higher comparison if any. |
3430 | * Output code for higher comparison if any. | ||
3431 | */ | ||
3432 | if(thisCase.higherCase == null) | 3069 | if(thisCase.higherCase == null) |
3433 | { | 3070 | { |
3434 | ilGen.Emit(thisCase, OpCodes.Br, defaultLabel); | 3071 | ilGen.Emit(thisCase, OpCodes.Br, defaultLabel); |
@@ -3438,9 +3075,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
3438 | OutputStrCase(testRVal, thisCase.higherCase, defaultLabel); | 3075 | OutputStrCase(testRVal, thisCase.higherCase, defaultLabel); |
3439 | } | 3076 | } |
3440 | 3077 | ||
3441 | /* | 3078 | // Output code for lower comparison if any. |
3442 | * Output code for lower comparison if any. | ||
3443 | */ | ||
3444 | if(thisCase.lowerCase != null) | 3079 | if(thisCase.lowerCase != null) |
3445 | { | 3080 | { |
3446 | ilGen.MarkLabel(lowerLabel); | 3081 | ilGen.MarkLabel(lowerLabel); |
@@ -3457,14 +3092,10 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
3457 | if(!mightGetHere) | 3092 | if(!mightGetHere) |
3458 | return; | 3093 | return; |
3459 | 3094 | ||
3460 | /* | 3095 | // 'throw' statements never fall through. |
3461 | * 'throw' statements never fall through. | ||
3462 | */ | ||
3463 | mightGetHere = false; | 3096 | mightGetHere = false; |
3464 | 3097 | ||
3465 | /* | 3098 | // Output code for either a throw or a rethrow. |
3466 | * Output code for either a throw or a rethrow. | ||
3467 | */ | ||
3468 | if(throwStmt.rVal == null) | 3099 | if(throwStmt.rVal == null) |
3469 | { | 3100 | { |
3470 | for(TokenStmtBlock blk = curStmtBlock; blk != null; blk = blk.outerStmtBlock) | 3101 | for(TokenStmtBlock blk = curStmtBlock; blk != null; blk = blk.outerStmtBlock) |
@@ -3506,24 +3137,18 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
3506 | throw new Exception("can't have both catch and finally on same try"); | 3137 | throw new Exception("can't have both catch and finally on same try"); |
3507 | } | 3138 | } |
3508 | 3139 | ||
3509 | /* | 3140 | // Stack the call labels. |
3510 | * Stack the call labels. | 3141 | // Try blocks have their own series of call labels. |
3511 | * Try blocks have their own series of call labels. | ||
3512 | */ | ||
3513 | ScriptMyLocal saveCallNo = actCallNo; | 3142 | ScriptMyLocal saveCallNo = actCallNo; |
3514 | LinkedList<CallLabel> saveCallLabels = actCallLabels; | 3143 | LinkedList<CallLabel> saveCallLabels = actCallLabels; |
3515 | 3144 | ||
3516 | /* | 3145 | // Generate code for either try { } catch { } or try { } finally { }. |
3517 | * Generate code for either try { } catch { } or try { } finally { }. | ||
3518 | */ | ||
3519 | if(tryStmt.catchStmt != null) | 3146 | if(tryStmt.catchStmt != null) |
3520 | GenerateStmtTryCatch(tryStmt); | 3147 | GenerateStmtTryCatch(tryStmt); |
3521 | if(tryStmt.finallyStmt != null) | 3148 | if(tryStmt.finallyStmt != null) |
3522 | GenerateStmtTryFinally(tryStmt); | 3149 | GenerateStmtTryFinally(tryStmt); |
3523 | 3150 | ||
3524 | /* | 3151 | // Restore call labels. |
3525 | * Restore call labels. | ||
3526 | */ | ||
3527 | actCallNo = saveCallNo; | 3152 | actCallNo = saveCallNo; |
3528 | actCallLabels = saveCallLabels; | 3153 | actCallLabels = saveCallLabels; |
3529 | } | 3154 | } |
@@ -4017,10 +3642,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
4017 | */ | 3642 | */ |
4018 | private void GenerateDeclVar(TokenDeclVar declVar) | 3643 | private void GenerateDeclVar(TokenDeclVar declVar) |
4019 | { | 3644 | { |
4020 | /* | 3645 | // Script gave us an initialization value, so just store init value in var like an assignment statement. |
4021 | * Script gave us an initialization value, so just store init value in var like an assignment statement. | 3646 | // If no init given, set it to its default value. |
4022 | * If no init given, set it to its default value. | ||
4023 | */ | ||
4024 | CompValu local = declVar.location; | 3647 | CompValu local = declVar.location; |
4025 | if(declVar.init != null) | 3648 | if(declVar.init != null) |
4026 | { | 3649 | { |
@@ -4070,14 +3693,10 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
4070 | { | 3693 | { |
4071 | CompValu subCompValu; | 3694 | CompValu subCompValu; |
4072 | 3695 | ||
4073 | /* | 3696 | // Compute location of array itself. |
4074 | * Compute location of array itself. | ||
4075 | */ | ||
4076 | CompValu baseCompValu = GenerateFromRVal(lVal.baseRVal); | 3697 | CompValu baseCompValu = GenerateFromRVal(lVal.baseRVal); |
4077 | 3698 | ||
4078 | /* | 3699 | // Maybe it is a fixed array access. |
4079 | * Maybe it is a fixed array access. | ||
4080 | */ | ||
4081 | string basetypestring = baseCompValu.type.ToString(); | 3700 | string basetypestring = baseCompValu.type.ToString(); |
4082 | if(basetypestring.EndsWith("]")) | 3701 | if(basetypestring.EndsWith("]")) |
4083 | { | 3702 | { |
@@ -4106,9 +3725,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
4106 | return new CompValuFixArEl(this, baseCompValu, subCompValus); | 3725 | return new CompValuFixArEl(this, baseCompValu, subCompValus); |
4107 | } | 3726 | } |
4108 | 3727 | ||
4109 | /* | 3728 | // Maybe it is accessing the $idxprop property of a script-defined class. |
4110 | * Maybe it is accessing the $idxprop property of a script-defined class. | ||
4111 | */ | ||
4112 | if(baseCompValu.type is TokenTypeSDTypeClass) | 3729 | if(baseCompValu.type is TokenTypeSDTypeClass) |
4113 | { | 3730 | { |
4114 | TokenName name = new TokenName(lVal, "$idxprop"); | 3731 | TokenName name = new TokenName(lVal, "$idxprop"); |
@@ -4133,9 +3750,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
4133 | 3750 | ||
4134 | } | 3751 | } |
4135 | 3752 | ||
4136 | /* | 3753 | // Maybe they are accessing $idxprop property of a script-defined interface. |
4137 | * Maybe they are accessing $idxprop property of a script-defined interface. | ||
4138 | */ | ||
4139 | if(baseCompValu.type is TokenTypeSDTypeInterface) | 3754 | if(baseCompValu.type is TokenTypeSDTypeInterface) |
4140 | { | 3755 | { |
4141 | TokenName name = new TokenName(lVal, "$idxprop"); | 3756 | TokenName name = new TokenName(lVal, "$idxprop"); |
@@ -4152,27 +3767,21 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
4152 | return new CompValuIdxProp(idxProp, baseCompValu, argTypes, compValus); | 3767 | return new CompValuIdxProp(idxProp, baseCompValu, argTypes, compValus); |
4153 | } | 3768 | } |
4154 | 3769 | ||
4155 | /* | 3770 | // Maybe it is extracting a character from a string. |
4156 | * Maybe it is extracting a character from a string. | ||
4157 | */ | ||
4158 | if((baseCompValu.type is TokenTypeKey) || (baseCompValu.type is TokenTypeStr)) | 3771 | if((baseCompValu.type is TokenTypeKey) || (baseCompValu.type is TokenTypeStr)) |
4159 | { | 3772 | { |
4160 | subCompValu = GenerateFromRVal(lVal.subRVal); | 3773 | subCompValu = GenerateFromRVal(lVal.subRVal); |
4161 | return new CompValuStrChr(new TokenTypeChar(lVal), baseCompValu, subCompValu); | 3774 | return new CompValuStrChr(new TokenTypeChar(lVal), baseCompValu, subCompValu); |
4162 | } | 3775 | } |
4163 | 3776 | ||
4164 | /* | 3777 | // Maybe it is extracting an element from a list. |
4165 | * Maybe it is extracting an element from a list. | ||
4166 | */ | ||
4167 | if(baseCompValu.type is TokenTypeList) | 3778 | if(baseCompValu.type is TokenTypeList) |
4168 | { | 3779 | { |
4169 | subCompValu = GenerateFromRVal(lVal.subRVal); | 3780 | subCompValu = GenerateFromRVal(lVal.subRVal); |
4170 | return new CompValuListEl(new TokenTypeObject(lVal), baseCompValu, subCompValu); | 3781 | return new CompValuListEl(new TokenTypeObject(lVal), baseCompValu, subCompValu); |
4171 | } | 3782 | } |
4172 | 3783 | ||
4173 | /* | 3784 | // Access should be to XMR_Array otherwise. |
4174 | * Access should be to XMR_Array otherwise. | ||
4175 | */ | ||
4176 | if(!(baseCompValu.type is TokenTypeArray)) | 3785 | if(!(baseCompValu.type is TokenTypeArray)) |
4177 | { | 3786 | { |
4178 | ErrorMsg(lVal, "taking subscript of non-array"); | 3787 | ErrorMsg(lVal, "taking subscript of non-array"); |
@@ -4286,9 +3895,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
4286 | CompValu baseRVal = GenerateFromRVal(lVal.baseRVal); | 3895 | CompValu baseRVal = GenerateFromRVal(lVal.baseRVal); |
4287 | string fieldName = lVal.fieldName.val + ArgSigString(argsig); | 3896 | string fieldName = lVal.fieldName.val + ArgSigString(argsig); |
4288 | 3897 | ||
4289 | /* | 3898 | // Maybe they are accessing an instance field, method or property of a script-defined class. |
4290 | * Maybe they are accessing an instance field, method or property of a script-defined class. | ||
4291 | */ | ||
4292 | if(baseRVal.type is TokenTypeSDTypeClass) | 3899 | if(baseRVal.type is TokenTypeSDTypeClass) |
4293 | { | 3900 | { |
4294 | TokenTypeSDTypeClass sdtType = (TokenTypeSDTypeClass)baseRVal.type; | 3901 | TokenTypeSDTypeClass sdtType = (TokenTypeSDTypeClass)baseRVal.type; |
@@ -4303,9 +3910,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
4303 | return new CompValuVoid(lVal.fieldName); | 3910 | return new CompValuVoid(lVal.fieldName); |
4304 | } | 3911 | } |
4305 | 3912 | ||
4306 | /* | 3913 | // Maybe they are accessing a method or property of a script-defined interface. |
4307 | * Maybe they are accessing a method or property of a script-defined interface. | ||
4308 | */ | ||
4309 | if(baseRVal.type is TokenTypeSDTypeInterface) | 3914 | if(baseRVal.type is TokenTypeSDTypeInterface) |
4310 | { | 3915 | { |
4311 | TokenTypeSDTypeInterface sdtType = (TokenTypeSDTypeInterface)baseRVal.type; | 3916 | TokenTypeSDTypeInterface sdtType = (TokenTypeSDTypeInterface)baseRVal.type; |
@@ -4318,9 +3923,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
4318 | return new CompValuVoid(lVal.fieldName); | 3923 | return new CompValuVoid(lVal.fieldName); |
4319 | } | 3924 | } |
4320 | 3925 | ||
4321 | /* | 3926 | // Since we only have a few built-in types with fields, just pound them out. |
4322 | * Since we only have a few built-in types with fields, just pound them out. | ||
4323 | */ | ||
4324 | if(baseRVal.type is TokenTypeArray) | 3927 | if(baseRVal.type is TokenTypeArray) |
4325 | { | 3928 | { |
4326 | 3929 | ||
@@ -4392,9 +3995,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
4392 | */ | 3995 | */ |
4393 | private CompValu GenerateFromLValName(TokenLValName lVal, TokenType[] argsig) | 3996 | private CompValu GenerateFromLValName(TokenLValName lVal, TokenType[] argsig) |
4394 | { | 3997 | { |
4395 | /* | 3998 | // Look in variable stack then look for built-in constants and functions. |
4396 | * Look in variable stack then look for built-in constants and functions. | ||
4397 | */ | ||
4398 | TokenDeclVar var = FindNamedVar(lVal, argsig); | 3999 | TokenDeclVar var = FindNamedVar(lVal, argsig); |
4399 | if(var == null) | 4000 | if(var == null) |
4400 | { | 4001 | { |
@@ -4402,9 +4003,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
4402 | return new CompValuVoid(lVal); | 4003 | return new CompValuVoid(lVal); |
4403 | } | 4004 | } |
4404 | 4005 | ||
4405 | /* | 4006 | // Maybe it has an implied 'this.' on the front. |
4406 | * Maybe it has an implied 'this.' on the front. | ||
4407 | */ | ||
4408 | if((var.sdtClass != null) && ((var.sdtFlags & ScriptReduce.SDT_STATIC) == 0)) | 4007 | if((var.sdtClass != null) && ((var.sdtFlags & ScriptReduce.SDT_STATIC) == 0)) |
4409 | { | 4008 | { |
4410 | 4009 | ||
@@ -4414,33 +4013,31 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
4414 | return new CompValuVoid(lVal); | 4013 | return new CompValuVoid(lVal); |
4415 | } | 4014 | } |
4416 | 4015 | ||
4417 | /* | 4016 | // Don't allow something such as: |
4418 | * Don't allow something such as: | 4017 | // |
4419 | * | 4018 | // class A { |
4420 | * class A { | 4019 | // integer I; |
4421 | * integer I; | 4020 | // class B { |
4422 | * class B { | 4021 | // Print () |
4423 | * Print () | 4022 | // { |
4424 | * { | 4023 | // llOwnerSay ("I=" + (string)I); <- access to I not allowed inside class B. |
4425 | * llOwnerSay ("I=" + (string)I); <- access to I not allowed inside class B. | 4024 | // explicit reference required as we don't |
4426 | * explicit reference required as we don't | 4025 | // have a valid reference to class A. |
4427 | * have a valid reference to class A. | 4026 | // } |
4428 | * } | 4027 | // } |
4429 | * } | 4028 | // } |
4430 | * } | 4029 | // |
4431 | * | 4030 | // But do allow something such as: |
4432 | * But do allow something such as: | 4031 | // |
4433 | * | 4032 | // class A { |
4434 | * class A { | 4033 | // integer I; |
4435 | * integer I; | 4034 | // } |
4436 | * } | 4035 | // class B : A { |
4437 | * class B : A { | 4036 | // Print () |
4438 | * Print () | 4037 | // { |
4439 | * { | 4038 | // llOwnerSay ("I=" + (string)I); |
4440 | * llOwnerSay ("I=" + (string)I); | 4039 | // } |
4441 | * } | 4040 | // } |
4442 | * } | ||
4443 | */ | ||
4444 | for(TokenDeclSDType c = curDeclFunc.sdtClass; c != var.sdtClass; c = c.extends) | 4041 | for(TokenDeclSDType c = curDeclFunc.sdtClass; c != var.sdtClass; c = c.extends) |
4445 | { | 4042 | { |
4446 | if(c == null) | 4043 | if(c == null) |
@@ -4455,9 +4052,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
4455 | return AccessInstanceMember(var, thisCompValu, lVal, false); | 4052 | return AccessInstanceMember(var, thisCompValu, lVal, false); |
4456 | } | 4053 | } |
4457 | 4054 | ||
4458 | /* | 4055 | // It's a local variable, static field, global, constant, etc. |
4459 | * It's a local variable, static field, global, constant, etc. | ||
4460 | */ | ||
4461 | return var.location; | 4056 | return var.location; |
4462 | } | 4057 | } |
4463 | 4058 | ||
@@ -4487,9 +4082,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
4487 | TokenType stType = lVal.baseType; | 4082 | TokenType stType = lVal.baseType; |
4488 | string fieldName = lVal.fieldName.val + ArgSigString(argsig); | 4083 | string fieldName = lVal.fieldName.val + ArgSigString(argsig); |
4489 | 4084 | ||
4490 | /* | 4085 | // Maybe they are accessing a static member of a script-defined class. |
4491 | * Maybe they are accessing a static member of a script-defined class. | ||
4492 | */ | ||
4493 | if(stType is TokenTypeSDTypeClass) | 4086 | if(stType is TokenTypeSDTypeClass) |
4494 | { | 4087 | { |
4495 | TokenTypeSDTypeClass sdtType = (TokenTypeSDTypeClass)stType; | 4088 | TokenTypeSDTypeClass sdtType = (TokenTypeSDTypeClass)stType; |
@@ -4529,9 +4122,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
4529 | { | 4122 | { |
4530 | errorMessageToken = rVal; | 4123 | errorMessageToken = rVal; |
4531 | 4124 | ||
4532 | /* | 4125 | // Maybe the expression can be converted to a constant. |
4533 | * Maybe the expression can be converted to a constant. | ||
4534 | */ | ||
4535 | bool didOne; | 4126 | bool didOne; |
4536 | do | 4127 | do |
4537 | { | 4128 | { |
@@ -4539,9 +4130,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
4539 | rVal = rVal.TryComputeConstant(LookupBodyConstants, ref didOne); | 4130 | rVal = rVal.TryComputeConstant(LookupBodyConstants, ref didOne); |
4540 | } while(didOne); | 4131 | } while(didOne); |
4541 | 4132 | ||
4542 | /* | 4133 | // Generate code for the computation and return resulting type and location. |
4543 | * Generate code for the computation and return resulting type and location. | ||
4544 | */ | ||
4545 | CompValu cVal = null; | 4134 | CompValu cVal = null; |
4546 | if(rVal is TokenRValAsnPost) | 4135 | if(rVal is TokenRValAsnPost) |
4547 | cVal = GenerateFromRValAsnPost((TokenRValAsnPost)rVal); | 4136 | cVal = GenerateFromRValAsnPost((TokenRValAsnPost)rVal); |
@@ -4583,9 +4172,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
4583 | if(cVal == null) | 4172 | if(cVal == null) |
4584 | throw new Exception("bad rval class " + rVal.GetType().ToString()); | 4173 | throw new Exception("bad rval class " + rVal.GetType().ToString()); |
4585 | 4174 | ||
4586 | /* | 4175 | // Sanity check. |
4587 | * Sanity check. | ||
4588 | */ | ||
4589 | if(!youveAnError) | 4176 | if(!youveAnError) |
4590 | { | 4177 | { |
4591 | if(cVal.type == null) | 4178 | if(cVal.type == null) |
@@ -4616,30 +4203,21 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
4616 | CompValu left, right; | 4203 | CompValu left, right; |
4617 | string opcodeIndex = token.opcode.ToString(); | 4204 | string opcodeIndex = token.opcode.ToString(); |
4618 | 4205 | ||
4619 | /* | 4206 | // Comma operators are special, as they say to compute the left-hand value and |
4620 | * Comma operators are special, as they say to compute the left-hand value and | 4207 | // discard it, then compute the right-hand argument and that is the result. |
4621 | * discard it, then compute the right-hand argument and that is the result. | ||
4622 | */ | ||
4623 | if(opcodeIndex == ",") | 4208 | if(opcodeIndex == ",") |
4624 | { | 4209 | { |
4625 | 4210 | // Compute left-hand operand but throw away result. | |
4626 | /* | ||
4627 | * Compute left-hand operand but throw away result. | ||
4628 | */ | ||
4629 | GenerateFromRVal(token.rValLeft); | 4211 | GenerateFromRVal(token.rValLeft); |
4630 | 4212 | ||
4631 | /* | 4213 | // Compute right-hand operand and that is the value of the expression. |
4632 | * Compute right-hand operand and that is the value of the expression. | ||
4633 | */ | ||
4634 | return GenerateFromRVal(token.rValRight); | 4214 | return GenerateFromRVal(token.rValRight); |
4635 | } | 4215 | } |
4636 | 4216 | ||
4637 | /* | 4217 | // Simple overwriting assignments are their own special case, |
4638 | * Simple overwriting assignments are their own special case, | 4218 | // as we want to cast the R-value to the type of the L-value. |
4639 | * as we want to cast the R-value to the type of the L-value. | 4219 | // And in the case of delegates, we want to use the arg signature |
4640 | * And in the case of delegates, we want to use the arg signature | 4220 | // of the delegate to select which overloaded method to use. |
4641 | * of the delegate to select which overloaded method to use. | ||
4642 | */ | ||
4643 | if(opcodeIndex == "=") | 4221 | if(opcodeIndex == "=") |
4644 | { | 4222 | { |
4645 | if(!(token.rValLeft is TokenLVal)) | 4223 | if(!(token.rValLeft is TokenLVal)) |
@@ -4655,26 +4233,19 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
4655 | return left; | 4233 | return left; |
4656 | } | 4234 | } |
4657 | 4235 | ||
4658 | /* | 4236 | // There are String.Concat() methods available for 2, 3 and 4 operands. |
4659 | * There are String.Concat() methods available for 2, 3 and 4 operands. | 4237 | // So see if we have a string concat op and optimize if so. |
4660 | * So see if we have a string concat op and optimize if so. | ||
4661 | */ | ||
4662 | if((opcodeIndex == "+") || | 4238 | if((opcodeIndex == "+") || |
4663 | ((opcodeIndex == "+=") && | 4239 | ((opcodeIndex == "+=") && |
4664 | (token.rValLeft is TokenLVal) && | 4240 | (token.rValLeft is TokenLVal) && |
4665 | (token.rValLeft.GetRValType(this, null) is TokenTypeStr))) | 4241 | (token.rValLeft.GetRValType(this, null) is TokenTypeStr))) |
4666 | { | 4242 | { |
4667 | 4243 | ||
4668 | /* | 4244 | // We are adding something. Maybe it's a bunch of strings together. |
4669 | * We are adding something. Maybe it's a bunch of strings together. | ||
4670 | */ | ||
4671 | List<TokenRVal> scorvs = new List<TokenRVal>(); | 4245 | List<TokenRVal> scorvs = new List<TokenRVal>(); |
4672 | if(StringConcatOperands(token.rValLeft, token.rValRight, scorvs, token.opcode)) | 4246 | if(StringConcatOperands(token.rValLeft, token.rValRight, scorvs, token.opcode)) |
4673 | { | 4247 | { |
4674 | 4248 | // Evaluate all the operands, right-to-left on purpose per LSL scripting. | |
4675 | /* | ||
4676 | * Evaluate all the operands, right-to-left on purpose per LSL scripting. | ||
4677 | */ | ||
4678 | int i; | 4249 | int i; |
4679 | int n = scorvs.Count; | 4250 | int n = scorvs.Count; |
4680 | CompValu[] scocvs = new CompValu[n]; | 4251 | CompValu[] scocvs = new CompValu[n]; |
@@ -4700,10 +4271,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
4700 | } | 4271 | } |
4701 | retcv.PopPre(this, token); | 4272 | retcv.PopPre(this, token); |
4702 | 4273 | ||
4703 | /* | 4274 | // Call the String.Concat() methods, passing operands in left-to-right order. |
4704 | * Call the String.Concat() methods, passing operands in left-to-right order. | 4275 | // Force a cast to string (retcv.type) for each operand. |
4705 | * Force a cast to string (retcv.type) for each operand. | ||
4706 | */ | ||
4707 | ++i; | 4276 | ++i; |
4708 | scocvs[i].PushVal(this, scorvs[i], retcv.type); | 4277 | scocvs[i].PushVal(this, scorvs[i], retcv.type); |
4709 | while(i + 3 < n) | 4278 | while(i + 3 < n) |
@@ -4731,18 +4300,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
4731 | ilGen.Emit(scorvs[i], OpCodes.Call, stringConcat2MethodInfo); | 4300 | ilGen.Emit(scorvs[i], OpCodes.Call, stringConcat2MethodInfo); |
4732 | } | 4301 | } |
4733 | 4302 | ||
4734 | /* | 4303 | // Put the result where we want it and return where we put it. |
4735 | * Put the result where we want it and return where we put it. | ||
4736 | */ | ||
4737 | retcv.PopPost(this, token); | 4304 | retcv.PopPost(this, token); |
4738 | return retcv; | 4305 | return retcv; |
4739 | } | 4306 | } |
4740 | } | 4307 | } |
4741 | 4308 | ||
4742 | /* | 4309 | // If "&&&", it is a short-circuiting AND. |
4743 | * If "&&&", it is a short-circuiting AND. | 4310 | // Compute left-hand operand and if true, compute right-hand operand. |
4744 | * Compute left-hand operand and if true, compute right-hand operand. | ||
4745 | */ | ||
4746 | if(opcodeIndex == "&&&") | 4311 | if(opcodeIndex == "&&&") |
4747 | { | 4312 | { |
4748 | bool leftVal, rightVal; | 4313 | bool leftVal, rightVal; |
@@ -4791,10 +4356,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
4791 | return new CompValuInteger(new TokenTypeInt(token), rightVal ? 1 : 0); | 4356 | return new CompValuInteger(new TokenTypeInt(token), rightVal ? 1 : 0); |
4792 | } | 4357 | } |
4793 | 4358 | ||
4794 | /* | 4359 | // If "|||", it is a short-circuiting OR. |
4795 | * If "|||", it is a short-circuiting OR. | 4360 | // Compute left-hand operand and if false, compute right-hand operand. |
4796 | * Compute left-hand operand and if false, compute right-hand operand. | ||
4797 | */ | ||
4798 | if(opcodeIndex == "|||") | 4361 | if(opcodeIndex == "|||") |
4799 | { | 4362 | { |
4800 | bool leftVal, rightVal; | 4363 | bool leftVal, rightVal; |
@@ -4843,17 +4406,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
4843 | return new CompValuInteger(new TokenTypeInt(token), rightVal ? 1 : 0); | 4406 | return new CompValuInteger(new TokenTypeInt(token), rightVal ? 1 : 0); |
4844 | } | 4407 | } |
4845 | 4408 | ||
4846 | /* | 4409 | // Computation of some sort, compute right-hand operand value then left-hand value |
4847 | * Computation of some sort, compute right-hand operand value then left-hand value | 4410 | // because LSL is supposed to be right-to-left evaluation. |
4848 | * because LSL is supposed to be right-to-left evaluation. | ||
4849 | */ | ||
4850 | right = Trivialize(GenerateFromRVal(token.rValRight), token.rValRight); | 4411 | right = Trivialize(GenerateFromRVal(token.rValRight), token.rValRight); |
4851 | 4412 | ||
4852 | /* | 4413 | // If left is a script-defined class and there is a method with the operator's name, |
4853 | * If left is a script-defined class and there is a method with the operator's name, | 4414 | // convert this to a call to that method with the right value as its single parameter. |
4854 | * convert this to a call to that method with the right value as its single parameter. | 4415 | // Except don't if the right value is 'undef' so they can always compare to undef. |
4855 | * Except don't if the right value is 'undef' so they can always compare to undef. | ||
4856 | */ | ||
4857 | TokenType leftType = token.rValLeft.GetRValType(this, null); | 4416 | TokenType leftType = token.rValLeft.GetRValType(this, null); |
4858 | if((leftType is TokenTypeSDTypeClass) && !(right.type is TokenTypeUndef)) | 4417 | if((leftType is TokenTypeSDTypeClass) && !(right.type is TokenTypeUndef)) |
4859 | { | 4418 | { |
@@ -4872,28 +4431,21 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
4872 | } | 4431 | } |
4873 | } | 4432 | } |
4874 | 4433 | ||
4875 | /* | 4434 | // Formulate key string for binOpStrings = (lefttype)(operator)(righttype) |
4876 | * Formulate key string for binOpStrings = (lefttype)(operator)(righttype) | ||
4877 | */ | ||
4878 | string leftIndex = leftType.ToString(); | 4435 | string leftIndex = leftType.ToString(); |
4879 | string rightIndex = right.type.ToString(); | 4436 | string rightIndex = right.type.ToString(); |
4880 | string key = leftIndex + opcodeIndex + rightIndex; | 4437 | string key = leftIndex + opcodeIndex + rightIndex; |
4881 | 4438 | ||
4882 | /* | 4439 | // If that key exists in table, then the operation is defined between those types |
4883 | * If that key exists in table, then the operation is defined between those types | 4440 | // ... and it produces an R-value of type as given in the table. |
4884 | * ... and it produces an R-value of type as given in the table. | ||
4885 | */ | ||
4886 | BinOpStr binOpStr; | 4441 | BinOpStr binOpStr; |
4887 | if(BinOpStr.defined.TryGetValue(key, out binOpStr)) | 4442 | if(BinOpStr.defined.TryGetValue(key, out binOpStr)) |
4888 | { | 4443 | { |
4889 | 4444 | // If table contained an explicit assignment type like +=, output the statement without | |
4890 | /* | 4445 | // casting the L-value, then return the L-value as the resultant value. |
4891 | * If table contained an explicit assignment type like +=, output the statement without | 4446 | // |
4892 | * casting the L-value, then return the L-value as the resultant value. | 4447 | // Make sure we don't include comparisons (such as ==, >=, etc). |
4893 | * | 4448 | // Nothing like +=, -=, %=, etc, generate a boolean, only the comparisons. |
4894 | * Make sure we don't include comparisons (such as ==, >=, etc). | ||
4895 | * Nothing like +=, -=, %=, etc, generate a boolean, only the comparisons. | ||
4896 | */ | ||
4897 | if((binOpStr.outtype != typeof(bool)) && opcodeIndex.EndsWith("=") && (opcodeIndex != "!=")) | 4449 | if((binOpStr.outtype != typeof(bool)) && opcodeIndex.EndsWith("=") && (opcodeIndex != "!=")) |
4898 | { | 4450 | { |
4899 | if(!(token.rValLeft is TokenLVal)) | 4451 | if(!(token.rValLeft is TokenLVal)) |
@@ -4906,21 +4458,17 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
4906 | return left; | 4458 | return left; |
4907 | } | 4459 | } |
4908 | 4460 | ||
4909 | /* | 4461 | // It's of the form left binop right. |
4910 | * It's of the form left binop right. | 4462 | // Compute left, perform operation then put result in a temp. |
4911 | * Compute left, perform operation then put result in a temp. | ||
4912 | */ | ||
4913 | left = GenerateFromRVal(token.rValLeft); | 4463 | left = GenerateFromRVal(token.rValLeft); |
4914 | CompValu retRVal = new CompValuTemp(TokenType.FromSysType(token.opcode, binOpStr.outtype), this); | 4464 | CompValu retRVal = new CompValuTemp(TokenType.FromSysType(token.opcode, binOpStr.outtype), this); |
4915 | binOpStr.emitBO(this, token, left, right, retRVal); | 4465 | binOpStr.emitBO(this, token, left, right, retRVal); |
4916 | return retRVal; | 4466 | return retRVal; |
4917 | } | 4467 | } |
4918 | 4468 | ||
4919 | /* | 4469 | // Nothing in the table, check for comparing object pointers because of the myriad of types possible. |
4920 | * Nothing in the table, check for comparing object pointers because of the myriad of types possible. | 4470 | // This will compare list pointers, null pointers, script-defined type pointers, array pointers, etc. |
4921 | * This will compare list pointers, null pointers, script-defined type pointers, array pointers, etc. | 4471 | // It will show equal iff the memory addresses are equal and that is good enough. |
4922 | * It will show equal iff the memory addresses are equal and that is good enough. | ||
4923 | */ | ||
4924 | if(!leftType.ToSysType().IsValueType && !right.type.ToSysType().IsValueType && ((opcodeIndex == "==") || (opcodeIndex == "!="))) | 4472 | if(!leftType.ToSysType().IsValueType && !right.type.ToSysType().IsValueType && ((opcodeIndex == "==") || (opcodeIndex == "!="))) |
4925 | { | 4473 | { |
4926 | CompValuTemp retRVal = new CompValuTemp(new TokenTypeInt(token), this); | 4474 | CompValuTemp retRVal = new CompValuTemp(new TokenTypeInt(token), this); |
@@ -4937,12 +4485,10 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
4937 | return retRVal; | 4485 | return retRVal; |
4938 | } | 4486 | } |
4939 | 4487 | ||
4940 | /* | 4488 | // If the opcode ends with "=", it may be something like "+=". |
4941 | * If the opcode ends with "=", it may be something like "+=". | 4489 | // So look up the key as if we didn't have the "=" to tell us if the operation is legal. |
4942 | * So look up the key as if we didn't have the "=" to tell us if the operation is legal. | 4490 | // Also, the binary operation's output type must be the same as the L-value type. |
4943 | * Also, the binary operation's output type must be the same as the L-value type. | 4491 | // Likewise, integer += float not allowed because result is float, but float += integer is ok. |
4944 | * Likewise, integer += float not allowed because result is float, but float += integer is ok. | ||
4945 | */ | ||
4946 | if(opcodeIndex.EndsWith("=")) | 4492 | if(opcodeIndex.EndsWith("=")) |
4947 | { | 4493 | { |
4948 | key = leftIndex + opcodeIndex.Substring(0, opcodeIndex.Length - 1) + rightIndex; | 4494 | key = leftIndex + opcodeIndex.Substring(0, opcodeIndex.Length - 1) + rightIndex; |
@@ -4959,9 +4505,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
4959 | return new CompValuVoid(token); | 4505 | return new CompValuVoid(token); |
4960 | } | 4506 | } |
4961 | 4507 | ||
4962 | /* | 4508 | // Now we know for something like %= that left%right is legal for the types given. |
4963 | * Now we know for something like %= that left%right is legal for the types given. | ||
4964 | */ | ||
4965 | left = GenerateFromLVal((TokenLVal)token.rValLeft); | 4509 | left = GenerateFromLVal((TokenLVal)token.rValLeft); |
4966 | if(binOpStr.outtype == leftType.ToSysType()) | 4510 | if(binOpStr.outtype == leftType.ToSysType()) |
4967 | { | 4511 | { |
@@ -4979,9 +4523,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
4979 | } | 4523 | } |
4980 | } | 4524 | } |
4981 | 4525 | ||
4982 | /* | 4526 | // Can't find it, oh well. |
4983 | * Can't find it, oh well. | ||
4984 | */ | ||
4985 | ErrorMsg(token, "op not defined: " + leftIndex + " " + opcodeIndex + " " + rightIndex); | 4527 | ErrorMsg(token, "op not defined: " + leftIndex + " " + opcodeIndex + " " + rightIndex); |
4986 | return new CompValuVoid(token); | 4528 | return new CompValuVoid(token); |
4987 | } | 4529 | } |
@@ -5007,26 +4549,20 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
5007 | if(!(leftType is TokenTypeStr) && !(rightType is TokenTypeStr)) | 4549 | if(!(leftType is TokenTypeStr) && !(rightType is TokenTypeStr)) |
5008 | return false; | 4550 | return false; |
5009 | 4551 | ||
5010 | /* | 4552 | // Also, list+string => list so reject that too. |
5011 | * Also, list+string => list so reject that too. | 4553 | // Also, string+list => list so reject that too. |
5012 | * Also, string+list => list so reject that too. | ||
5013 | */ | ||
5014 | if(leftType is TokenTypeList) | 4554 | if(leftType is TokenTypeList) |
5015 | return false; | 4555 | return false; |
5016 | if(rightType is TokenTypeList) | 4556 | if(rightType is TokenTypeList) |
5017 | return false; | 4557 | return false; |
5018 | 4558 | ||
5019 | /* | 4559 | // Append values to the end of the list in left-to-right order. |
5020 | * Append values to the end of the list in left-to-right order. | 4560 | // If value is formed from a something+something => string, |
5021 | * If value is formed from a something+something => string, | 4561 | // push them as separate values, otherwise push as one value. |
5022 | * push them as separate values, otherwise push as one value. | ||
5023 | */ | ||
5024 | StringConcatOperand(leftType, leftRVal, scos); | 4562 | StringConcatOperand(leftType, leftRVal, scos); |
5025 | StringConcatOperand(rightType, rightRVal, scos); | 4563 | StringConcatOperand(rightType, rightRVal, scos); |
5026 | 4564 | ||
5027 | /* | 4565 | // Maybe constant strings can be concatted. |
5028 | * Maybe constant strings can be concatted. | ||
5029 | */ | ||
5030 | try | 4566 | try |
5031 | { | 4567 | { |
5032 | int len; | 4568 | int len; |
@@ -5044,9 +4580,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
5044 | { | 4580 | { |
5045 | } | 4581 | } |
5046 | 4582 | ||
5047 | /* | 4583 | // We pushed some string stuff. |
5048 | * We pushed some string stuff. | ||
5049 | */ | ||
5050 | return true; | 4584 | return true; |
5051 | } | 4585 | } |
5052 | 4586 | ||
@@ -5090,9 +4624,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
5090 | { | 4624 | { |
5091 | CompValu inRVal = GenerateFromRVal(token.rVal); | 4625 | CompValu inRVal = GenerateFromRVal(token.rVal); |
5092 | 4626 | ||
5093 | /* | 4627 | // Script-defined types can define their own methods to handle unary operators. |
5094 | * Script-defined types can define their own methods to handle unary operators. | ||
5095 | */ | ||
5096 | if(inRVal.type is TokenTypeSDTypeClass) | 4628 | if(inRVal.type is TokenTypeSDTypeClass) |
5097 | { | 4629 | { |
5098 | TokenTypeSDTypeClass sdtType = (TokenTypeSDTypeClass)inRVal.type; | 4630 | TokenTypeSDTypeClass sdtType = (TokenTypeSDTypeClass)inRVal.type; |
@@ -5107,9 +4639,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
5107 | } | 4639 | } |
5108 | } | 4640 | } |
5109 | 4641 | ||
5110 | /* | 4642 | // Otherwise use the default. |
5111 | * Otherwise use the default. | ||
5112 | */ | ||
5113 | return UnOpGenerate(inRVal, token.opcode); | 4643 | return UnOpGenerate(inRVal, token.opcode); |
5114 | } | 4644 | } |
5115 | 4645 | ||
@@ -5120,26 +4650,18 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
5120 | { | 4650 | { |
5121 | CompValu lVal = GenerateFromLVal(asnPost.lVal); | 4651 | CompValu lVal = GenerateFromLVal(asnPost.lVal); |
5122 | 4652 | ||
5123 | /* | 4653 | // Make up a temp to save original value in. |
5124 | * Make up a temp to save original value in. | ||
5125 | */ | ||
5126 | CompValuTemp result = new CompValuTemp(lVal.type, this); | 4654 | CompValuTemp result = new CompValuTemp(lVal.type, this); |
5127 | 4655 | ||
5128 | /* | 4656 | // Prepare to pop incremented value back into variable being incremented. |
5129 | * Prepare to pop incremented value back into variable being incremented. | ||
5130 | */ | ||
5131 | lVal.PopPre(this, asnPost.lVal); | 4657 | lVal.PopPre(this, asnPost.lVal); |
5132 | 4658 | ||
5133 | /* | 4659 | // Copy original value to temp and leave value on stack. |
5134 | * Copy original value to temp and leave value on stack. | ||
5135 | */ | ||
5136 | lVal.PushVal(this, asnPost.lVal); | 4660 | lVal.PushVal(this, asnPost.lVal); |
5137 | ilGen.Emit(asnPost.lVal, OpCodes.Dup); | 4661 | ilGen.Emit(asnPost.lVal, OpCodes.Dup); |
5138 | result.Pop(this, asnPost.lVal); | 4662 | result.Pop(this, asnPost.lVal); |
5139 | 4663 | ||
5140 | /* | 4664 | // Perform the ++/--. |
5141 | * Perform the ++/--. | ||
5142 | */ | ||
5143 | if((lVal.type is TokenTypeChar) || (lVal.type is TokenTypeInt)) | 4665 | if((lVal.type is TokenTypeChar) || (lVal.type is TokenTypeInt)) |
5144 | { | 4666 | { |
5145 | ilGen.Emit(asnPost, OpCodes.Ldc_I4_1); | 4667 | ilGen.Emit(asnPost, OpCodes.Ldc_I4_1); |
@@ -5170,9 +4692,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
5170 | throw new Exception("unknown asnPost op"); | 4692 | throw new Exception("unknown asnPost op"); |
5171 | } | 4693 | } |
5172 | 4694 | ||
5173 | /* | 4695 | // Store new value in original variable. |
5174 | * Store new value in original variable. | ||
5175 | */ | ||
5176 | lVal.PopPost(this, asnPost.lVal); | 4696 | lVal.PopPost(this, asnPost.lVal); |
5177 | 4697 | ||
5178 | return result; | 4698 | return result; |
@@ -5185,24 +4705,16 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
5185 | { | 4705 | { |
5186 | CompValu lVal = GenerateFromLVal(asnPre.lVal); | 4706 | CompValu lVal = GenerateFromLVal(asnPre.lVal); |
5187 | 4707 | ||
5188 | /* | 4708 | // Make up a temp to put result in. |
5189 | * Make up a temp to put result in. | ||
5190 | */ | ||
5191 | CompValuTemp result = new CompValuTemp(lVal.type, this); | 4709 | CompValuTemp result = new CompValuTemp(lVal.type, this); |
5192 | 4710 | ||
5193 | /* | 4711 | // Prepare to pop incremented value back into variable being incremented. |
5194 | * Prepare to pop incremented value back into variable being incremented. | ||
5195 | */ | ||
5196 | lVal.PopPre(this, asnPre.lVal); | 4712 | lVal.PopPre(this, asnPre.lVal); |
5197 | 4713 | ||
5198 | /* | 4714 | // Push original value. |
5199 | * Push original value. | ||
5200 | */ | ||
5201 | lVal.PushVal(this, asnPre.lVal); | 4715 | lVal.PushVal(this, asnPre.lVal); |
5202 | 4716 | ||
5203 | /* | 4717 | // Perform the ++/--. |
5204 | * Perform the ++/--. | ||
5205 | */ | ||
5206 | if((lVal.type is TokenTypeChar) || (lVal.type is TokenTypeInt)) | 4718 | if((lVal.type is TokenTypeChar) || (lVal.type is TokenTypeInt)) |
5207 | { | 4719 | { |
5208 | ilGen.Emit(asnPre, OpCodes.Ldc_I4_1); | 4720 | ilGen.Emit(asnPre, OpCodes.Ldc_I4_1); |
@@ -5233,15 +4745,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
5233 | throw new Exception("unknown asnPre op"); | 4745 | throw new Exception("unknown asnPre op"); |
5234 | } | 4746 | } |
5235 | 4747 | ||
5236 | /* | 4748 | // Store new value in temp variable, keeping new value on stack. |
5237 | * Store new value in temp variable, keeping new value on stack. | ||
5238 | */ | ||
5239 | ilGen.Emit(asnPre.lVal, OpCodes.Dup); | 4749 | ilGen.Emit(asnPre.lVal, OpCodes.Dup); |
5240 | result.Pop(this, asnPre.lVal); | 4750 | result.Pop(this, asnPre.lVal); |
5241 | 4751 | ||
5242 | /* | 4752 | // Store new value in original variable. |
5243 | * Store new value in original variable. | ||
5244 | */ | ||
5245 | lVal.PopPost(this, asnPre.lVal); | 4753 | lVal.PopPost(this, asnPre.lVal); |
5246 | 4754 | ||
5247 | return result; | 4755 | return result; |
@@ -5259,11 +4767,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
5259 | TokenRVal arg; | 4767 | TokenRVal arg; |
5260 | TokenType[] argTypes; | 4768 | TokenType[] argTypes; |
5261 | 4769 | ||
5262 | /* | 4770 | // Compute the values of all the function's call arguments. |
5263 | * Compute the values of all the function's call arguments. | 4771 | // Save where the computation results are in the argRVals[] array. |
5264 | * Save where the computation results are in the argRVals[] array. | 4772 | // Might as well build the argument signature from the argument types, too. |
5265 | * Might as well build the argument signature from the argument types, too. | ||
5266 | */ | ||
5267 | nargs = call.nArgs; | 4773 | nargs = call.nArgs; |
5268 | argRVals = new CompValu[nargs]; | 4774 | argRVals = new CompValu[nargs]; |
5269 | argTypes = new TokenType[nargs]; | 4775 | argTypes = new TokenType[nargs]; |
@@ -5278,9 +4784,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
5278 | } | 4784 | } |
5279 | } | 4785 | } |
5280 | 4786 | ||
5281 | /* | 4787 | // Get function/method's entrypoint that matches the call argument types. |
5282 | * Get function/method's entrypoint that matches the call argument types. | ||
5283 | */ | ||
5284 | method = GenerateFromRVal(call.meth, argTypes); | 4788 | method = GenerateFromRVal(call.meth, argTypes); |
5285 | if(method == null) | 4789 | if(method == null) |
5286 | return null; | 4790 | return null; |
@@ -5302,9 +4806,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
5302 | TokenType retType; | 4806 | TokenType retType; |
5303 | TokenType[] argTypes; | 4807 | TokenType[] argTypes; |
5304 | 4808 | ||
5305 | /* | 4809 | // Must be some kind of callable. |
5306 | * Must be some kind of callable. | ||
5307 | */ | ||
5308 | retType = method.GetRetType(); // TokenTypeVoid if void; null means a variable | 4810 | retType = method.GetRetType(); // TokenTypeVoid if void; null means a variable |
5309 | if(retType == null) | 4811 | if(retType == null) |
5310 | { | 4812 | { |
@@ -5312,9 +4814,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
5312 | return new CompValuVoid(call); | 4814 | return new CompValuVoid(call); |
5313 | } | 4815 | } |
5314 | 4816 | ||
5315 | /* | 4817 | // Get a location for return value. |
5316 | * Get a location for return value. | ||
5317 | */ | ||
5318 | if(retType is TokenTypeVoid) | 4818 | if(retType is TokenTypeVoid) |
5319 | { | 4819 | { |
5320 | result = new CompValuVoid(call); | 4820 | result = new CompValuVoid(call); |
@@ -5324,10 +4824,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
5324 | result = new CompValuTemp(retType, this); | 4824 | result = new CompValuTemp(retType, this); |
5325 | } | 4825 | } |
5326 | 4826 | ||
5327 | /* | 4827 | // Make sure all arguments are trivial, ie, don't involve their own call labels. |
5328 | * Make sure all arguments are trivial, ie, don't involve their own call labels. | 4828 | // For any that aren't, output code to calculate the arg and put in a temporary. |
5329 | * For any that aren't, output code to calculate the arg and put in a temporary. | ||
5330 | */ | ||
5331 | nArgs = argRVals.Length; | 4829 | nArgs = argRVals.Length; |
5332 | for(i = 0; i < nArgs; i++) | 4830 | for(i = 0; i < nArgs; i++) |
5333 | { | 4831 | { |
@@ -5337,9 +4835,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
5337 | } | 4835 | } |
5338 | } | 4836 | } |
5339 | 4837 | ||
5340 | /* | 4838 | // Inline functions know how to generate their own call. |
5341 | * Inline functions know how to generate their own call. | ||
5342 | */ | ||
5343 | if(method is CompValuInline) | 4839 | if(method is CompValuInline) |
5344 | { | 4840 | { |
5345 | CompValuInline inline = (CompValuInline)method; | 4841 | CompValuInline inline = (CompValuInline)method; |
@@ -5347,14 +4843,10 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
5347 | return result; | 4843 | return result; |
5348 | } | 4844 | } |
5349 | 4845 | ||
5350 | /* | 4846 | // Push whatever the function/method needs as a this argument, if anything. |
5351 | * Push whatever the function/method needs as a this argument, if anything. | ||
5352 | */ | ||
5353 | method.CallPre(this, call); | 4847 | method.CallPre(this, call); |
5354 | 4848 | ||
5355 | /* | 4849 | // Push the script-visible args, left-to-right. |
5356 | * Push the script-visible args, left-to-right. | ||
5357 | */ | ||
5358 | argTypes = method.GetArgTypes(); | 4850 | argTypes = method.GetArgTypes(); |
5359 | for(i = 0; i < nArgs; i++) | 4851 | for(i = 0; i < nArgs; i++) |
5360 | { | 4852 | { |
@@ -5368,14 +4860,10 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
5368 | } | 4860 | } |
5369 | } | 4861 | } |
5370 | 4862 | ||
5371 | /* | 4863 | // Now output call instruction. |
5372 | * Now output call instruction. | ||
5373 | */ | ||
5374 | method.CallPost(this, call); | 4864 | method.CallPost(this, call); |
5375 | 4865 | ||
5376 | /* | 4866 | // Deal with the return value (if any), by putting it in 'result'. |
5377 | * Deal with the return value (if any), by putting it in 'result'. | ||
5378 | */ | ||
5379 | result.Pop(this, call, retType); | 4867 | result.Pop(this, call, retType); |
5380 | return result; | 4868 | return result; |
5381 | } | 4869 | } |
@@ -5402,13 +4890,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
5402 | */ | 4890 | */ |
5403 | private CompValu GenerateFromRValCast(TokenRValCast cast) | 4891 | private CompValu GenerateFromRValCast(TokenRValCast cast) |
5404 | { | 4892 | { |
5405 | /* | 4893 | // If casting to a delegate type, use the argment signature |
5406 | * If casting to a delegate type, use the argment signature | 4894 | // of the delegate to help select the function/method, eg, |
5407 | * of the delegate to help select the function/method, eg, | 4895 | // '(delegate string(integer))ToString' |
5408 | * '(delegate string(integer))ToString' | 4896 | // will select 'string ToString(integer x)' |
5409 | * will select 'string ToString(integer x)' | 4897 | // instaead of 'string ToString(float x)' or anything else |
5410 | * instaead of 'string ToString(float x)' or anything else | ||
5411 | */ | ||
5412 | TokenType[] argsig = null; | 4898 | TokenType[] argsig = null; |
5413 | TokenType outType = cast.castTo; | 4899 | TokenType outType = cast.castTo; |
5414 | if(outType is TokenTypeSDTypeDelegate) | 4900 | if(outType is TokenTypeSDTypeDelegate) |
@@ -5416,17 +4902,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
5416 | argsig = ((TokenTypeSDTypeDelegate)outType).decl.GetArgTypes(); | 4902 | argsig = ((TokenTypeSDTypeDelegate)outType).decl.GetArgTypes(); |
5417 | } | 4903 | } |
5418 | 4904 | ||
5419 | /* | 4905 | // Generate the value that is being cast. |
5420 | * Generate the value that is being cast. | 4906 | // If the value is already the requested type, just use it as is. |
5421 | * If the value is already the requested type, just use it as is. | ||
5422 | */ | ||
5423 | CompValu inRVal = GenerateFromRVal(cast.rVal, argsig); | 4907 | CompValu inRVal = GenerateFromRVal(cast.rVal, argsig); |
5424 | if(inRVal.type == outType) | 4908 | if(inRVal.type == outType) |
5425 | return inRVal; | 4909 | return inRVal; |
5426 | 4910 | ||
5427 | /* | 4911 | // Different type, generate casting code, putting the result in a temp of the output type. |
5428 | * Different type, generate casting code, putting the result in a temp of the output type. | ||
5429 | */ | ||
5430 | CompValu outRVal = new CompValuTemp(outType, this); | 4912 | CompValu outRVal = new CompValuTemp(outType, this); |
5431 | outRVal.PopPre(this, cast); | 4913 | outRVal.PopPre(this, cast); |
5432 | inRVal.PushVal(this, cast, outType, true); | 4914 | inRVal.PushVal(this, cast, outType, true); |
@@ -5511,10 +4993,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
5511 | */ | 4993 | */ |
5512 | private CompValu GenerateFromRValList(TokenRValList rValList) | 4994 | private CompValu GenerateFromRValList(TokenRValList rValList) |
5513 | { | 4995 | { |
5514 | /* | 4996 | // Compute all element values and remember where we put them. |
5515 | * Compute all element values and remember where we put them. | 4997 | // Do it right-to-left as customary for LSL scripts. |
5516 | * Do it right-to-left as customary for LSL scripts. | ||
5517 | */ | ||
5518 | int i = 0; | 4998 | int i = 0; |
5519 | TokenRVal lastRVal = null; | 4999 | TokenRVal lastRVal = null; |
5520 | for(TokenRVal val = rValList.rVal; val != null; val = (TokenRVal)val.nextToken) | 5000 | for(TokenRVal val = rValList.rVal; val != null; val = (TokenRVal)val.nextToken) |
@@ -5529,43 +5009,31 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
5529 | vals[--i] = GenerateFromRVal(val); | 5009 | vals[--i] = GenerateFromRVal(val); |
5530 | } | 5010 | } |
5531 | 5011 | ||
5532 | /* | 5012 | // This is the temp that will hold the created list. |
5533 | * This is the temp that will hold the created list. | ||
5534 | */ | ||
5535 | CompValuTemp newList = new CompValuTemp(new TokenTypeList(rValList.rVal), this); | 5013 | CompValuTemp newList = new CompValuTemp(new TokenTypeList(rValList.rVal), this); |
5536 | 5014 | ||
5537 | /* | 5015 | // Create a temp object[] array to hold all the initial values. |
5538 | * Create a temp object[] array to hold all the initial values. | ||
5539 | */ | ||
5540 | ilGen.Emit(rValList, OpCodes.Ldc_I4, rValList.nItems); | 5016 | ilGen.Emit(rValList, OpCodes.Ldc_I4, rValList.nItems); |
5541 | ilGen.Emit(rValList, OpCodes.Newarr, typeof(object)); | 5017 | ilGen.Emit(rValList, OpCodes.Newarr, typeof(object)); |
5542 | 5018 | ||
5543 | /* | 5019 | // Populate the array. |
5544 | * Populate the array. | ||
5545 | */ | ||
5546 | i = 0; | 5020 | i = 0; |
5547 | for(TokenRVal val = rValList.rVal; val != null; val = (TokenRVal)val.nextToken) | 5021 | for(TokenRVal val = rValList.rVal; val != null; val = (TokenRVal)val.nextToken) |
5548 | { | 5022 | { |
5549 | 5023 | ||
5550 | /* | 5024 | // Get pointer to temp array object. |
5551 | * Get pointer to temp array object. | ||
5552 | */ | ||
5553 | ilGen.Emit(rValList, OpCodes.Dup); | 5025 | ilGen.Emit(rValList, OpCodes.Dup); |
5554 | 5026 | ||
5555 | /* | 5027 | // Get index in that array. |
5556 | * Get index in that array. | ||
5557 | */ | ||
5558 | ilGen.Emit(rValList, OpCodes.Ldc_I4, i); | 5028 | ilGen.Emit(rValList, OpCodes.Ldc_I4, i); |
5559 | 5029 | ||
5560 | /* | 5030 | // Store initialization value in array location. |
5561 | * Store initialization value in array location. | 5031 | // However, floats and ints need to be converted to LSL_Float and LSL_Integer, |
5562 | * However, floats and ints need to be converted to LSL_Float and LSL_Integer, | 5032 | // or things like llSetPayPrice() will puque when they try to cast the elements |
5563 | * or things like llSetPayPrice() will puque when they try to cast the elements | 5033 | // to LSL_Float or LSL_Integer. Likewise with string/LSL_String. |
5564 | * to LSL_Float or LSL_Integer. Likewise with string/LSL_String. | 5034 | // |
5565 | * | 5035 | // Maybe it's already LSL-boxed so we don't do anything with it except make sure |
5566 | * Maybe it's already LSL-boxed so we don't do anything with it except make sure | 5036 | // it is an object, not a struct. |
5567 | * it is an object, not a struct. | ||
5568 | */ | ||
5569 | CompValu eRVal = vals[i++]; | 5037 | CompValu eRVal = vals[i++]; |
5570 | eRVal.PushVal(this, val); | 5038 | eRVal.PushVal(this, val); |
5571 | if(eRVal.type.ToLSLWrapType() == null) | 5039 | if(eRVal.type.ToLSLWrapType() == null) |
@@ -5599,9 +5067,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
5599 | ilGen.Emit(val, OpCodes.Stelem, typeof(object)); | 5067 | ilGen.Emit(val, OpCodes.Stelem, typeof(object)); |
5600 | } | 5068 | } |
5601 | 5069 | ||
5602 | /* | 5070 | // Create new list object from temp initial value array (whose ref is still on the stack). |
5603 | * Create new list object from temp initial value array (whose ref is still on the stack). | ||
5604 | */ | ||
5605 | ilGen.Emit(rValList, OpCodes.Newobj, lslListConstructorInfo); | 5071 | ilGen.Emit(rValList, OpCodes.Newobj, lslListConstructorInfo); |
5606 | newList.Pop(this, rValList); | 5072 | newList.Pop(this, rValList); |
5607 | return newList; | 5073 | return newList; |
@@ -5717,44 +5183,31 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
5717 | { | 5183 | { |
5718 | CompValu initValue = null; | 5184 | CompValu initValue = null; |
5719 | 5185 | ||
5720 | /* | 5186 | // If it is a sublist, process it. |
5721 | * If it is a sublist, process it. | 5187 | // If we don't have enough subscripts yet, hopefully that sublist will have enough. |
5722 | * If we don't have enough subscripts yet, hopefully that sublist will have enough. | 5188 | // If we already have enough subscripts, then that sublist can be for an element of this supposedly jagged array. |
5723 | * If we already have enough subscripts, then that sublist can be for an element of this supposedly jagged array. | ||
5724 | */ | ||
5725 | if(val is TokenList) | 5189 | if(val is TokenList) |
5726 | { | 5190 | { |
5727 | TokenList sublist = (TokenList)val; | 5191 | TokenList sublist = (TokenList)val; |
5728 | if(dimNo + 1 < rank) | 5192 | if(dimNo + 1 < rank) |
5729 | { | 5193 | { |
5730 | 5194 | // We don't have enough subscripts yet, hopefully the sublist has the rest. | |
5731 | /* | ||
5732 | * We don't have enough subscripts yet, hopefully the sublist has the rest. | ||
5733 | */ | ||
5734 | FillInInitVals(array, setMeth, subscripts, dimNo + 1, rank, sublist, eleType); | 5195 | FillInInitVals(array, setMeth, subscripts, dimNo + 1, rank, sublist, eleType); |
5735 | } | 5196 | } |
5736 | else if((eleType is TokenTypeSDTypeClass) && (((TokenTypeSDTypeClass)eleType).decl.arrayOfType == null)) | 5197 | else if((eleType is TokenTypeSDTypeClass) && (((TokenTypeSDTypeClass)eleType).decl.arrayOfType == null)) |
5737 | { | 5198 | { |
5738 | 5199 | // If we aren't a jagged array either, we can't do anything with the sublist. | |
5739 | /* | ||
5740 | * If we aren't a jagged array either, we can't do anything with the sublist. | ||
5741 | */ | ||
5742 | ErrorMsg(val, "too many brace levels"); | 5200 | ErrorMsg(val, "too many brace levels"); |
5743 | } | 5201 | } |
5744 | else | 5202 | else |
5745 | { | 5203 | { |
5746 | 5204 | // We are a jagged array, so malloc a subarray and initialize it with the sublist. | |
5747 | /* | 5205 | // Then we can use that subarray to fill this array's element. |
5748 | * We are a jagged array, so malloc a subarray and initialize it with the sublist. | ||
5749 | * Then we can use that subarray to fill this array's element. | ||
5750 | */ | ||
5751 | initValue = MallocAndInitArray(eleType, sublist); | 5206 | initValue = MallocAndInitArray(eleType, sublist); |
5752 | } | 5207 | } |
5753 | } | 5208 | } |
5754 | 5209 | ||
5755 | /* | 5210 | // If it is a value expression, then output code to compute the value. |
5756 | * If it is a value expression, then output code to compute the value. | ||
5757 | */ | ||
5758 | if(val is TokenRVal) | 5211 | if(val is TokenRVal) |
5759 | { | 5212 | { |
5760 | if(dimNo + 1 < rank) | 5213 | if(dimNo + 1 < rank) |
@@ -5767,9 +5220,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
5767 | } | 5220 | } |
5768 | } | 5221 | } |
5769 | 5222 | ||
5770 | /* | 5223 | // If there is an initValue, output "array.Set (subscript[0], subscript[1], ..., initValue)" |
5771 | * If there is an initValue, output "array.Set (subscript[0], subscript[1], ..., initValue)" | ||
5772 | */ | ||
5773 | if(initValue != null) | 5224 | if(initValue != null) |
5774 | { | 5225 | { |
5775 | array.PushVal(this, val); | 5226 | array.PushVal(this, val); |
@@ -5781,9 +5232,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
5781 | ilGen.Emit(val, OpCodes.Call, setMeth.ilGen); | 5232 | ilGen.Emit(val, OpCodes.Call, setMeth.ilGen); |
5782 | } | 5233 | } |
5783 | 5234 | ||
5784 | /* | 5235 | // That subscript is processed one way or another, on to the next. |
5785 | * That subscript is processed one way or another, on to the next. | ||
5786 | */ | ||
5787 | subscripts[dimNo]++; | 5236 | subscripts[dimNo]++; |
5788 | } | 5237 | } |
5789 | } | 5238 | } |
@@ -5894,19 +5343,15 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
5894 | return new CompValuVoid(type); | 5343 | return new CompValuVoid(type); |
5895 | } | 5344 | } |
5896 | 5345 | ||
5897 | /* | 5346 | // Default for 'object' type is 'undef'. |
5898 | * Default for 'object' type is 'undef'. | 5347 | // Likewise for script-defined classes and interfaces. |
5899 | * Likewise for script-defined classes and interfaces. | ||
5900 | */ | ||
5901 | if((type is TokenTypeObject) || (type is TokenTypeSDTypeClass) || (type is TokenTypeSDTypeDelegate) || | 5348 | if((type is TokenTypeObject) || (type is TokenTypeSDTypeClass) || (type is TokenTypeSDTypeDelegate) || |
5902 | (type is TokenTypeSDTypeInterface) || (type is TokenTypeExc)) | 5349 | (type is TokenTypeSDTypeInterface) || (type is TokenTypeExc)) |
5903 | { | 5350 | { |
5904 | return new CompValuNull(type); | 5351 | return new CompValuNull(type); |
5905 | } | 5352 | } |
5906 | 5353 | ||
5907 | /* | 5354 | // array and list |
5908 | * array and list | ||
5909 | */ | ||
5910 | CompValuTemp temp = new CompValuTemp(type, this); | 5355 | CompValuTemp temp = new CompValuTemp(type, this); |
5911 | PushDefaultValue(type); | 5356 | PushDefaultValue(type); |
5912 | temp.Pop(this, rValInitDef, type); | 5357 | temp.Pop(this, rValInitDef, type); |
@@ -5918,14 +5363,10 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
5918 | */ | 5363 | */ |
5919 | private CompValu GenerateFromRValIsType(TokenRValIsType rValIsType) | 5364 | private CompValu GenerateFromRValIsType(TokenRValIsType rValIsType) |
5920 | { | 5365 | { |
5921 | /* | 5366 | // Expression we want to know the type of. |
5922 | * Expression we want to know the type of. | ||
5923 | */ | ||
5924 | CompValu val = GenerateFromRVal(rValIsType.rValExp); | 5367 | CompValu val = GenerateFromRVal(rValIsType.rValExp); |
5925 | 5368 | ||
5926 | /* | 5369 | // Pass it in to top-level type expression decoder. |
5927 | * Pass it in to top-level type expression decoder. | ||
5928 | */ | ||
5929 | return GenerateFromTypeExp(val, rValIsType.typeExp); | 5370 | return GenerateFromTypeExp(val, rValIsType.typeExp); |
5930 | } | 5371 | } |
5931 | 5372 | ||
@@ -6062,28 +5503,22 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
6062 | return; | 5503 | return; |
6063 | } | 5504 | } |
6064 | 5505 | ||
6065 | /* | 5506 | // Default for 'object' type is 'undef'. |
6066 | * Default for 'object' type is 'undef'. | 5507 | // Likewise for script-defined classes and interfaces. |
6067 | * Likewise for script-defined classes and interfaces. | ||
6068 | */ | ||
6069 | if((type is TokenTypeObject) || (type is TokenTypeSDTypeClass) || (type is TokenTypeSDTypeInterface) || (type is TokenTypeExc)) | 5508 | if((type is TokenTypeObject) || (type is TokenTypeSDTypeClass) || (type is TokenTypeSDTypeInterface) || (type is TokenTypeExc)) |
6070 | { | 5509 | { |
6071 | ilGen.Emit(type, OpCodes.Ldnull); | 5510 | ilGen.Emit(type, OpCodes.Ldnull); |
6072 | return; | 5511 | return; |
6073 | } | 5512 | } |
6074 | 5513 | ||
6075 | /* | 5514 | // Void is pushed as the default return value of a void function. |
6076 | * Void is pushed as the default return value of a void function. | 5515 | // So just push nothing as expected of void functions. |
6077 | * So just push nothing as expected of void functions. | ||
6078 | */ | ||
6079 | if(type is TokenTypeVoid) | 5516 | if(type is TokenTypeVoid) |
6080 | { | 5517 | { |
6081 | return; | 5518 | return; |
6082 | } | 5519 | } |
6083 | 5520 | ||
6084 | /* | 5521 | // Default for 'delegate' type is 'undef'. |
6085 | * Default for 'delegate' type is 'undef'. | ||
6086 | */ | ||
6087 | if(type is TokenTypeSDTypeDelegate) | 5522 | if(type is TokenTypeSDTypeDelegate) |
6088 | { | 5523 | { |
6089 | ilGen.Emit(type, OpCodes.Ldnull); | 5524 | ilGen.Emit(type, OpCodes.Ldnull); |
@@ -6186,16 +5621,12 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
6186 | */ | 5621 | */ |
6187 | private static VarDict CreateLegalEventHandlers() | 5622 | private static VarDict CreateLegalEventHandlers() |
6188 | { | 5623 | { |
6189 | /* | 5624 | // Get handler prototypes with full argument lists. |
6190 | * Get handler prototypes with full argument lists. | ||
6191 | */ | ||
6192 | VarDict leh = new InternalFuncDict(typeof(IEventHandlers), false); | 5625 | VarDict leh = new InternalFuncDict(typeof(IEventHandlers), false); |
6193 | 5626 | ||
6194 | /* | 5627 | // We want the scripts to be able to declare their handlers with |
6195 | * We want the scripts to be able to declare their handlers with | 5628 | // fewer arguments than the full argument lists. So define additional |
6196 | * fewer arguments than the full argument lists. So define additional | 5629 | // prototypes with fewer arguments. |
6197 | * prototypes with fewer arguments. | ||
6198 | */ | ||
6199 | TokenDeclVar[] fullArgProtos = new TokenDeclVar[leh.Count]; | 5630 | TokenDeclVar[] fullArgProtos = new TokenDeclVar[leh.Count]; |
6200 | int i = 0; | 5631 | int i = 0; |
6201 | foreach(TokenDeclVar fap in leh) | 5632 | foreach(TokenDeclVar fap in leh) |
@@ -6283,9 +5714,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
6283 | */ | 5714 | */ |
6284 | private CompValu UnOpGenerate(CompValu inRVal, Token opcode) | 5715 | private CompValu UnOpGenerate(CompValu inRVal, Token opcode) |
6285 | { | 5716 | { |
6286 | /* | 5717 | // - Negate |
6287 | * - Negate | ||
6288 | */ | ||
6289 | if(opcode is TokenKwSub) | 5718 | if(opcode is TokenKwSub) |
6290 | { | 5719 | { |
6291 | if(inRVal.type is TokenTypeFloat) | 5720 | if(inRVal.type is TokenTypeFloat) |
@@ -6324,9 +5753,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
6324 | return inRVal; | 5753 | return inRVal; |
6325 | } | 5754 | } |
6326 | 5755 | ||
6327 | /* | 5756 | // ~ Complement (bitwise integer) |
6328 | * ~ Complement (bitwise integer) | ||
6329 | */ | ||
6330 | if(opcode is TokenKwTilde) | 5757 | if(opcode is TokenKwTilde) |
6331 | { | 5758 | { |
6332 | if(inRVal.type is TokenTypeInt) | 5759 | if(inRVal.type is TokenTypeInt) |
@@ -6341,13 +5768,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
6341 | return inRVal; | 5768 | return inRVal; |
6342 | } | 5769 | } |
6343 | 5770 | ||
6344 | /* | 5771 | // ! Not (boolean) |
6345 | * ! Not (boolean) | 5772 | // |
6346 | * | 5773 | // We stuff the 0/1 result in an int because I've seen x+!y in scripts |
6347 | * We stuff the 0/1 result in an int because I've seen x+!y in scripts | 5774 | // and we don't want to have to create tables to handle int+bool and |
6348 | * and we don't want to have to create tables to handle int+bool and | 5775 | // everything like that. |
6349 | * everything like that. | ||
6350 | */ | ||
6351 | if(opcode is TokenKwExclam) | 5776 | if(opcode is TokenKwExclam) |
6352 | { | 5777 | { |
6353 | CompValuTemp outRVal = new CompValuTemp(new TokenTypeInt(opcode), this); | 5778 | CompValuTemp outRVal = new CompValuTemp(new TokenTypeInt(opcode), this); |
@@ -6367,9 +5792,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
6367 | */ | 5792 | */ |
6368 | private TokenRVal LookupInitConstants(TokenRVal rVal, ref bool didOne) | 5793 | private TokenRVal LookupInitConstants(TokenRVal rVal, ref bool didOne) |
6369 | { | 5794 | { |
6370 | /* | 5795 | // If it is a static field of a script-defined type, look it up and hopefully we find a constant there. |
6371 | * If it is a static field of a script-defined type, look it up and hopefully we find a constant there. | ||
6372 | */ | ||
6373 | TokenDeclVar gblVar; | 5796 | TokenDeclVar gblVar; |
6374 | if(rVal is TokenLValSField) | 5797 | if(rVal is TokenLValSField) |
6375 | { | 5798 | { |
@@ -6390,17 +5813,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
6390 | return rVal; | 5813 | return rVal; |
6391 | } | 5814 | } |
6392 | 5815 | ||
6393 | /* | 5816 | // Only other thing we handle is stand-alone names. |
6394 | * Only other thing we handle is stand-alone names. | ||
6395 | */ | ||
6396 | if(!(rVal is TokenLValName)) | 5817 | if(!(rVal is TokenLValName)) |
6397 | return rVal; | 5818 | return rVal; |
6398 | string name = ((TokenLValName)rVal).name.val; | 5819 | string name = ((TokenLValName)rVal).name.val; |
6399 | 5820 | ||
6400 | /* | 5821 | // If we are doing the initializations for a script-defined type, |
6401 | * If we are doing the initializations for a script-defined type, | 5822 | // look for the constant among the fields for that type. |
6402 | * look for the constant among the fields for that type. | ||
6403 | */ | ||
6404 | if(currentSDTClass != null) | 5823 | if(currentSDTClass != null) |
6405 | { | 5824 | { |
6406 | gblVar = currentSDTClass.members.FindExact(name, null); | 5825 | gblVar = currentSDTClass.members.FindExact(name, null); |
@@ -6415,11 +5834,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
6415 | } | 5834 | } |
6416 | } | 5835 | } |
6417 | 5836 | ||
6418 | /* | 5837 | // Look it up as a script-defined global variable. |
6419 | * Look it up as a script-defined global variable. | 5838 | // Then if the variable is defined as a constant and has a constant value, |
6420 | * Then if the variable is defined as a constant and has a constant value, | 5839 | // we are successful. If it is defined as something else, return failure. |
6421 | * we are successful. If it is defined as something else, return failure. | ||
6422 | */ | ||
6423 | gblVar = tokenScript.variablesStack.FindExact(name, null); | 5840 | gblVar = tokenScript.variablesStack.FindExact(name, null); |
6424 | if(gblVar != null) | 5841 | if(gblVar != null) |
6425 | { | 5842 | { |
@@ -6431,9 +5848,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
6431 | return rVal; | 5848 | return rVal; |
6432 | } | 5849 | } |
6433 | 5850 | ||
6434 | /* | 5851 | // Maybe it is a built-in symbolic constant. |
6435 | * Maybe it is a built-in symbolic constant. | ||
6436 | */ | ||
6437 | ScriptConst scriptConst = ScriptConst.Lookup(name); | 5852 | ScriptConst scriptConst = ScriptConst.Lookup(name); |
6438 | if(scriptConst != null) | 5853 | if(scriptConst != null) |
6439 | { | 5854 | { |
@@ -6445,9 +5860,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
6445 | } | 5860 | } |
6446 | } | 5861 | } |
6447 | 5862 | ||
6448 | /* | 5863 | // Don't know what it is, return failure. |
6449 | * Don't know what it is, return failure. | ||
6450 | */ | ||
6451 | return rVal; | 5864 | return rVal; |
6452 | } | 5865 | } |
6453 | 5866 | ||
@@ -6457,9 +5870,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
6457 | */ | 5870 | */ |
6458 | private TokenRVal LookupBodyConstants(TokenRVal rVal, ref bool didOne) | 5871 | private TokenRVal LookupBodyConstants(TokenRVal rVal, ref bool didOne) |
6459 | { | 5872 | { |
6460 | /* | 5873 | // If it is a static field of a script-defined type, look it up and hopefully we find a constant there. |
6461 | * If it is a static field of a script-defined type, look it up and hopefully we find a constant there. | ||
6462 | */ | ||
6463 | TokenDeclVar gblVar; | 5874 | TokenDeclVar gblVar; |
6464 | if(rVal is TokenLValSField) | 5875 | if(rVal is TokenLValSField) |
6465 | { | 5876 | { |
@@ -6477,17 +5888,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
6477 | return rVal; | 5888 | return rVal; |
6478 | } | 5889 | } |
6479 | 5890 | ||
6480 | /* | 5891 | // Only other thing we handle is stand-alone names. |
6481 | * Only other thing we handle is stand-alone names. | ||
6482 | */ | ||
6483 | if(!(rVal is TokenLValName)) | 5892 | if(!(rVal is TokenLValName)) |
6484 | return rVal; | 5893 | return rVal; |
6485 | string name = ((TokenLValName)rVal).name.val; | 5894 | string name = ((TokenLValName)rVal).name.val; |
6486 | 5895 | ||
6487 | /* | 5896 | // Scan through the variable stack and hopefully we find a constant there. |
6488 | * Scan through the variable stack and hopefully we find a constant there. | 5897 | // But we stop as soon as we get a match because that's what the script is referring to. |
6489 | * But we stop as soon as we get a match because that's what the script is referring to. | ||
6490 | */ | ||
6491 | CompValu val; | 5898 | CompValu val; |
6492 | for(VarDict vars = ((TokenLValName)rVal).stack; vars != null; vars = vars.outerVarDict) | 5899 | for(VarDict vars = ((TokenLValName)rVal).stack; vars != null; vars = vars.outerVarDict) |
6493 | { | 5900 | { |
@@ -6513,9 +5920,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
6513 | } | 5920 | } |
6514 | } | 5921 | } |
6515 | 5922 | ||
6516 | /* | 5923 | // Maybe it is a built-in symbolic constant. |
6517 | * Maybe it is a built-in symbolic constant. | ||
6518 | */ | ||
6519 | ScriptConst scriptConst = ScriptConst.Lookup(name); | 5924 | ScriptConst scriptConst = ScriptConst.Lookup(name); |
6520 | if(scriptConst != null) | 5925 | if(scriptConst != null) |
6521 | { | 5926 | { |
@@ -6523,15 +5928,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
6523 | goto foundit; | 5928 | goto foundit; |
6524 | } | 5929 | } |
6525 | 5930 | ||
6526 | /* | 5931 | // Don't know what it is, return failure. |
6527 | * Don't know what it is, return failure. | ||
6528 | */ | ||
6529 | return rVal; | 5932 | return rVal; |
6530 | 5933 | ||
6531 | /* | 5934 | // Found a CompValu. If it's a simple constant, then use it. |
6532 | * Found a CompValu. If it's a simple constant, then use it. | 5935 | // Otherwise tell caller we failed to simplify. |
6533 | * Otherwise tell caller we failed to simplify. | ||
6534 | */ | ||
6535 | foundit: | 5936 | foundit: |
6536 | rVal = CompValuConst2RValConst(val, rVal); | 5937 | rVal = CompValuConst2RValConst(val, rVal); |
6537 | if(rVal is TokenRValConst) | 5938 | if(rVal is TokenRValConst) |
@@ -6586,9 +5987,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
6586 | */ | 5987 | */ |
6587 | public TokenDeclVar FindNamedVar(TokenLValName lValName, TokenType[] argsig) | 5988 | public TokenDeclVar FindNamedVar(TokenLValName lValName, TokenType[] argsig) |
6588 | { | 5989 | { |
6589 | /* | 5990 | // Look in variable stack for the given name. |
6590 | * Look in variable stack for the given name. | ||
6591 | */ | ||
6592 | for(VarDict vars = lValName.stack; vars != null; vars = vars.outerVarDict) | 5991 | for(VarDict vars = lValName.stack; vars != null; vars = vars.outerVarDict) |
6593 | { | 5992 | { |
6594 | 5993 | ||
@@ -6627,9 +6026,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
6627 | } | 6026 | } |
6628 | } | 6027 | } |
6629 | 6028 | ||
6630 | /* | 6029 | // If not found, try one of the built-in constants or functions. |
6631 | * If not found, try one of the built-in constants or functions. | ||
6632 | */ | ||
6633 | if(argsig == null) | 6030 | if(argsig == null) |
6634 | { | 6031 | { |
6635 | ScriptConst scriptConst = ScriptConst.Lookup(lValName.name.val); | 6032 | ScriptConst scriptConst = ScriptConst.Lookup(lValName.name.val); |
@@ -6670,31 +6067,28 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
6670 | TokenDeclVar declVar = sdtDecl.FindIFaceMember(this, name, argsig, out impl); | 6067 | TokenDeclVar declVar = sdtDecl.FindIFaceMember(this, name, argsig, out impl); |
6671 | if((declVar != null) && (impl != sdtDecl)) | 6068 | if((declVar != null) && (impl != sdtDecl)) |
6672 | { | 6069 | { |
6673 | 6070 | // Accessing a method or propterty of another interface that the primary interface says it implements. | |
6674 | /* | 6071 | // In this case, we have to cast from the primary interface to that secondary interface. |
6675 | * Accessing a method or propterty of another interface that the primary interface says it implements. | 6072 | // |
6676 | * In this case, we have to cast from the primary interface to that secondary interface. | 6073 | // interface IEnumerable { |
6677 | * | 6074 | // IEnumerator GetEnumerator (); |
6678 | * interface IEnumerable { | 6075 | // } |
6679 | * IEnumerator GetEnumerator (); | 6076 | // interface ICountable : IEnumerable { |
6680 | * } | 6077 | // integer GetCount (); |
6681 | * interface ICountable : IEnumerable { | 6078 | // } |
6682 | * integer GetCount (); | 6079 | // class List : ICountable { |
6683 | * } | 6080 | // public GetCount () : ICountable { ... } |
6684 | * class List : ICountable { | 6081 | // public GetEnumerator () : IEnumerable { ... } |
6685 | * public GetCount () : ICountable { ... } | 6082 | // } |
6686 | * public GetEnumerator () : IEnumerable { ... } | 6083 | // |
6687 | * } | 6084 | // ICountable aList = new List (); |
6688 | * | 6085 | // IEnumerator anEnumer = aList.GetEnumerator (); << we are here |
6689 | * ICountable aList = new List (); | 6086 | // << baseRVal = aList |
6690 | * IEnumerator anEnumer = aList.GetEnumerator (); << we are here | 6087 | // << sdtDecl = ICountable |
6691 | * << baseRVal = aList | 6088 | // << impl = IEnumerable |
6692 | * << sdtDecl = ICountable | 6089 | // << name = GetEnumerator |
6693 | * << impl = IEnumerable | 6090 | // << argsig = () |
6694 | * << name = GetEnumerator | 6091 | // So we have to cast aList from ICountable to IEnumerable. |
6695 | * << argsig = () | ||
6696 | * So we have to cast aList from ICountable to IEnumerable. | ||
6697 | */ | ||
6698 | 6092 | ||
6699 | // make type token for the secondary interface type | 6093 | // make type token for the secondary interface type |
6700 | TokenType subIntfType = impl.MakeRefToken(name); | 6094 | TokenType subIntfType = impl.MakeRefToken(name); |
@@ -6799,19 +6193,15 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
6799 | TokenDeclSDType definedBy = var.sdtClass; | 6193 | TokenDeclSDType definedBy = var.sdtClass; |
6800 | TokenDeclSDType accessedBy = curDeclFunc.sdtClass; | 6194 | TokenDeclSDType accessedBy = curDeclFunc.sdtClass; |
6801 | 6195 | ||
6802 | /*******************************\ | 6196 | //******************************* |
6803 | * Check member-level access * | 6197 | // Check member-level access |
6804 | \*******************************/ | 6198 | //******************************* |
6805 | 6199 | ||
6806 | /* | 6200 | // Note that if accessedBy is null, ie, accessing from global function (or event handlers), |
6807 | * Note that if accessedBy is null, ie, accessing from global function (or event handlers), | 6201 | // anything tagged as SDT_PRIVATE or SDT_PROTECTED will fail. |
6808 | * anything tagged as SDT_PRIVATE or SDT_PROTECTED will fail. | ||
6809 | */ | ||
6810 | 6202 | ||
6811 | /* | 6203 | // Private means accessed by the class that defined the member or accessed by a nested class |
6812 | * Private means accessed by the class that defined the member or accessed by a nested class | 6204 | // of the class that defined the member. |
6813 | * of the class that defined the member. | ||
6814 | */ | ||
6815 | if((var.sdtFlags & ScriptReduce.SDT_PRIVATE) != 0) | 6205 | if((var.sdtFlags & ScriptReduce.SDT_PRIVATE) != 0) |
6816 | { | 6206 | { |
6817 | for(nested = accessedBy; nested != null; nested = nested.outerSDType) | 6207 | for(nested = accessedBy; nested != null; nested = nested.outerSDType) |
@@ -6823,12 +6213,10 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
6823 | return; | 6213 | return; |
6824 | } | 6214 | } |
6825 | 6215 | ||
6826 | /* | 6216 | // Protected means: |
6827 | * Protected means: | 6217 | // If being accessed by an inner class, the inner class has access to it if the inner class derives |
6828 | * If being accessed by an inner class, the inner class has access to it if the inner class derives | 6218 | // from the declaring class. It also has access to it if an outer class derives from the declaring |
6829 | * from the declaring class. It also has access to it if an outer class derives from the declaring | 6219 | // class. |
6830 | * class. | ||
6831 | */ | ||
6832 | if((var.sdtFlags & ScriptReduce.SDT_PROTECTED) != 0) | 6220 | if((var.sdtFlags & ScriptReduce.SDT_PROTECTED) != 0) |
6833 | { | 6221 | { |
6834 | for(nested = accessedBy; nested != null; nested = nested.outerSDType) | 6222 | for(nested = accessedBy; nested != null; nested = nested.outerSDType) |
@@ -6844,26 +6232,24 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
6844 | } | 6232 | } |
6845 | acc1ok: | 6233 | acc1ok: |
6846 | 6234 | ||
6847 | /******************************\ | 6235 | //****************************** |
6848 | * Check class-level access * | 6236 | // Check class-level access |
6849 | \******************************/ | 6237 | //****************************** |
6850 | 6238 | ||
6851 | /* | 6239 | // If being accessed by same or inner class than where defined, it is ok. |
6852 | * If being accessed by same or inner class than where defined, it is ok. | 6240 | // |
6853 | * | 6241 | // class DefiningClass { |
6854 | * class DefiningClass { | 6242 | // varBeingAccessed; |
6855 | * varBeingAccessed; | 6243 | // . |
6856 | * . | 6244 | // . |
6857 | * . | 6245 | // . |
6858 | * . | 6246 | // class AccessingClass { |
6859 | * class AccessingClass { | 6247 | // functionDoingAccess() { } |
6860 | * functionDoingAccess() { } | 6248 | // } |
6861 | * } | 6249 | // . |
6862 | * . | 6250 | // . |
6863 | * . | 6251 | // . |
6864 | * . | 6252 | // } |
6865 | * } | ||
6866 | */ | ||
6867 | nested = accessedBy; | 6253 | nested = accessedBy; |
6868 | while(true) | 6254 | while(true) |
6869 | { | 6255 | { |
@@ -6874,46 +6260,39 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
6874 | nested = (TokenDeclSDTypeClass)nested.outerSDType; | 6260 | nested = (TokenDeclSDTypeClass)nested.outerSDType; |
6875 | } | 6261 | } |
6876 | 6262 | ||
6877 | /* | 6263 | // It is being accessed by an outer class than where defined, |
6878 | * It is being accessed by an outer class than where defined, | 6264 | // check for a 'private' or 'protected' class tag that blocks. |
6879 | * check for a 'private' or 'protected' class tag that blocks. | ||
6880 | */ | ||
6881 | do | 6265 | do |
6882 | { | 6266 | { |
6883 | 6267 | // If the field's class is defined directly inside the accessing class, | |
6884 | /* | 6268 | // access is allowed regardless of class-level private or protected tags. |
6885 | * If the field's class is defined directly inside the accessing class, | 6269 | // |
6886 | * access is allowed regardless of class-level private or protected tags. | 6270 | // class AccessingClass { |
6887 | * | 6271 | // functionDoingAccess() { } |
6888 | * class AccessingClass { | 6272 | // class DefiningClass { |
6889 | * functionDoingAccess() { } | 6273 | // varBeingAccessed; |
6890 | * class DefiningClass { | 6274 | // } |
6891 | * varBeingAccessed; | 6275 | // } |
6892 | * } | ||
6893 | * } | ||
6894 | */ | ||
6895 | if(definedBy.outerSDType == accessedBy) | 6276 | if(definedBy.outerSDType == accessedBy) |
6896 | return; | 6277 | return; |
6897 | 6278 | ||
6898 | /* | 6279 | // If the field's class is defined two or more levels inside the accessing class, |
6899 | * If the field's class is defined two or more levels inside the accessing class, | 6280 | // access is denied if the defining class is tagged private. |
6900 | * access is denied if the defining class is tagged private. | 6281 | // |
6901 | * | 6282 | // class AccessingClass { |
6902 | * class AccessingClass { | 6283 | // functionDoingAccess() { } |
6903 | * functionDoingAccess() { } | 6284 | // . |
6904 | * . | 6285 | // . |
6905 | * . | 6286 | // . |
6906 | * . | 6287 | // class IntermediateClass { |
6907 | * class IntermediateClass { | 6288 | // private class DefiningClass { |
6908 | * private class DefiningClass { | 6289 | // varBeingAccessed; |
6909 | * varBeingAccessed; | 6290 | // } |
6910 | * } | 6291 | // } |
6911 | * } | 6292 | // . |
6912 | * . | 6293 | // . |
6913 | * . | 6294 | // . |
6914 | * . | 6295 | // } |
6915 | * } | ||
6916 | */ | ||
6917 | if((definedBy.accessLevel & ScriptReduce.SDT_PRIVATE) != 0) | 6296 | if((definedBy.accessLevel & ScriptReduce.SDT_PRIVATE) != 0) |
6918 | { | 6297 | { |
6919 | ErrorMsg(errorAt, "member " + var.fullName + " cannot be accessed by " + curDeclFunc.fullName + | 6298 | ErrorMsg(errorAt, "member " + var.fullName + " cannot be accessed by " + curDeclFunc.fullName + |
@@ -6921,10 +6300,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
6921 | return; | 6300 | return; |
6922 | } | 6301 | } |
6923 | 6302 | ||
6924 | /* | 6303 | // Likewise, if DefiningClass is tagged protected, the AccessingClass must derive from the |
6925 | * Likewise, if DefiningClass is tagged protected, the AccessingClass must derive from the | 6304 | // IntermediateClass or access is denied. |
6926 | * IntermediateClass or access is denied. | ||
6927 | */ | ||
6928 | if((definedBy.accessLevel & ScriptReduce.SDT_PROTECTED) != 0) | 6305 | if((definedBy.accessLevel & ScriptReduce.SDT_PROTECTED) != 0) |
6929 | { | 6306 | { |
6930 | for(TokenDeclSDType extends = accessedBy; extends != definedBy.outerSDType; extends = extends.extends) | 6307 | for(TokenDeclSDType extends = accessedBy; extends != definedBy.outerSDType; extends = extends.extends) |
@@ -6938,9 +6315,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
6938 | } | 6315 | } |
6939 | } | 6316 | } |
6940 | 6317 | ||
6941 | /* | 6318 | // Check next outer level. |
6942 | * Check next outer level. | ||
6943 | */ | ||
6944 | definedBy = definedBy.outerSDType; | 6319 | definedBy = definedBy.outerSDType; |
6945 | } while(definedBy != null); | 6320 | } while(definedBy != null); |
6946 | } | 6321 | } |
diff --git a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCollector.cs b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCollector.cs index 4a57823..88cd6c1 100644 --- a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCollector.cs +++ b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCollector.cs | |||
@@ -511,20 +511,16 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
511 | } | 511 | } |
512 | public override bool MoveNext() | 512 | public override bool MoveNext() |
513 | { | 513 | { |
514 | /* | 514 | // First off, return any targets the instruction can come up with. |
515 | * First off, return any targets the instruction can come up with. | ||
516 | */ | ||
517 | if(realEnumerator.MoveNext()) | 515 | if(realEnumerator.MoveNext()) |
518 | { | 516 | { |
519 | nn = realEnumerator.Current; | 517 | nn = realEnumerator.Current; |
520 | return true; | 518 | return true; |
521 | } | 519 | } |
522 | 520 | ||
523 | /* | 521 | // Then if this instruction is in a try section, say this instruction |
524 | * Then if this instruction is in a try section, say this instruction | 522 | // can potentially branch to the beginning of the corresponding |
525 | * can potentially branch to the beginning of the corresponding | 523 | // catch/finally. |
526 | * catch/finally. | ||
527 | */ | ||
528 | if((index == 0) && (gn.tryBlock != null)) | 524 | if((index == 0) && (gn.tryBlock != null)) |
529 | { | 525 | { |
530 | index++; | 526 | index++; |
@@ -532,9 +528,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
532 | return true; | 528 | return true; |
533 | } | 529 | } |
534 | 530 | ||
535 | /* | 531 | // That's all we can do. |
536 | * That's all we can do. | ||
537 | */ | ||
538 | nn = null; | 532 | nn = null; |
539 | return false; | 533 | return false; |
540 | } | 534 | } |
@@ -1875,9 +1869,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1875 | } | 1869 | } |
1876 | public override bool MoveNext() | 1870 | public override bool MoveNext() |
1877 | { | 1871 | { |
1878 | /* | 1872 | // Return next from list of switch case labels. |
1879 | * Return next from list of switch case labels. | ||
1880 | */ | ||
1881 | while(index < gn.myLabels.Length) | 1873 | while(index < gn.myLabels.Length) |
1882 | { | 1874 | { |
1883 | nn = gn.myLabels[index++].whereAmI; | 1875 | nn = gn.myLabels[index++].whereAmI; |
@@ -1885,9 +1877,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1885 | return true; | 1877 | return true; |
1886 | } | 1878 | } |
1887 | 1879 | ||
1888 | /* | 1880 | // If all ran out, the switch instruction falls through. |
1889 | * If all ran out, the switch instruction falls through. | ||
1890 | */ | ||
1891 | if(index == gn.myLabels.Length) | 1881 | if(index == gn.myLabels.Length) |
1892 | { | 1882 | { |
1893 | index++; | 1883 | index++; |
@@ -1895,9 +1885,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1895 | return true; | 1885 | return true; |
1896 | } | 1886 | } |
1897 | 1887 | ||
1898 | /* | 1888 | // Even ran out of that, say there's nothing more. |
1899 | * Even ran out of that, say there's nothing more. | ||
1900 | */ | ||
1901 | nn = null; | 1889 | nn = null; |
1902 | return false; | 1890 | return false; |
1903 | } | 1891 | } |
@@ -2527,10 +2515,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2527 | if(curExcBlock != null) | 2515 | if(curExcBlock != null) |
2528 | throw new Exception("exception block still open"); | 2516 | throw new Exception("exception block still open"); |
2529 | 2517 | ||
2530 | /* | 2518 | // If an instruction says it doesn't fall through, remove all instructions to |
2531 | * If an instruction says it doesn't fall through, remove all instructions to | 2519 | // the end of the block. |
2532 | * the end of the block. | ||
2533 | */ | ||
2534 | for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) | 2520 | for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) |
2535 | { | 2521 | { |
2536 | if(!gn.CanFallThrough()) | 2522 | if(!gn.CanFallThrough()) |
@@ -2547,12 +2533,10 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2547 | } | 2533 | } |
2548 | } | 2534 | } |
2549 | 2535 | ||
2550 | /* | 2536 | // Scan for OpCodes.Leave instructions. |
2551 | * Scan for OpCodes.Leave instructions. | 2537 | // For each found, its target for flow analysis purposes is the beginning of the corresponding |
2552 | * For each found, its target for flow analysis purposes is the beginning of the corresponding | 2538 | // finally block. And the end of the finally block gets a conditional branch target of the |
2553 | * finally block. And the end of the finally block gets a conditional branch target of the | 2539 | // leave instruction's target. A leave instruction can unwind zero or more finally blocks. |
2554 | * leave instruction's target. A leave instruction can unwind zero or more finally blocks. | ||
2555 | */ | ||
2556 | for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) | 2540 | for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) |
2557 | { | 2541 | { |
2558 | if(gn is GraphNodeEmitLabelLeave) | 2542 | if(gn is GraphNodeEmitLabelLeave) |
@@ -2562,12 +2546,10 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2562 | GraphNodeBeginExceptionBlock leaveTargetsTryBlock = // try block directly enclosing leave target | 2546 | GraphNodeBeginExceptionBlock leaveTargetsTryBlock = // try block directly enclosing leave target |
2563 | (leaveTarget == null) ? null : leaveTarget.tryBlock; // ...it must not be unwound | 2547 | (leaveTarget == null) ? null : leaveTarget.tryBlock; // ...it must not be unwound |
2564 | 2548 | ||
2565 | /* | 2549 | // Step through try { }s from the leave instruction towards its target looking for try { }s with finally { }s. |
2566 | * Step through try { }s from the leave instruction towards its target looking for try { }s with finally { }s. | 2550 | // The leave instruction unconditionally branches to the beginning of the innermost one found. |
2567 | * The leave instruction unconditionally branches to the beginning of the innermost one found. | 2551 | // The end of the last one found conditionally branches to the leave instruction's target. |
2568 | * The end of the last one found conditionally branches to the leave instruction's target. | 2552 | // If none found, the leave is a simple unconditional branch to its target. |
2569 | * If none found, the leave is a simple unconditional branch to its target. | ||
2570 | */ | ||
2571 | GraphNodeBeginFinallyBlock innerFinallyBlock = null; | 2553 | GraphNodeBeginFinallyBlock innerFinallyBlock = null; |
2572 | for(GraphNodeBeginExceptionBlock tryBlock = leaveInstr.tryBlock; | 2554 | for(GraphNodeBeginExceptionBlock tryBlock = leaveInstr.tryBlock; |
2573 | tryBlock != leaveTargetsTryBlock; | 2555 | tryBlock != leaveTargetsTryBlock; |
@@ -2586,10 +2568,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2586 | } | 2568 | } |
2587 | } | 2569 | } |
2588 | 2570 | ||
2589 | /* | 2571 | // The end of the outermost finally being unwound can conditionally jump to the target of the leave instruction. |
2590 | * The end of the outermost finally being unwound can conditionally jump to the target of the leave instruction. | 2572 | // In the case of no finallies being unwound, the leave is just a simple unconditional branch. |
2591 | * In the case of no finallies being unwound, the leave is just a simple unconditional branch. | ||
2592 | */ | ||
2593 | if(innerFinallyBlock == null) | 2573 | if(innerFinallyBlock == null) |
2594 | { | 2574 | { |
2595 | leaveInstr.unwindTo = leaveTarget; | 2575 | leaveInstr.unwindTo = leaveTarget; |
@@ -2601,10 +2581,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2601 | } | 2581 | } |
2602 | } | 2582 | } |
2603 | 2583 | ||
2604 | /* | 2584 | // See which variables a particular block reads before writing. |
2605 | * See which variables a particular block reads before writing. | 2585 | // This just considers the block itself and nothing that it branches to or fallsthru to. |
2606 | * This just considers the block itself and nothing that it branches to or fallsthru to. | ||
2607 | */ | ||
2608 | GraphNodeBlock currentBlock = null; | 2586 | GraphNodeBlock currentBlock = null; |
2609 | for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) | 2587 | for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) |
2610 | { | 2588 | { |
@@ -2626,13 +2604,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2626 | } | 2604 | } |
2627 | } | 2605 | } |
2628 | 2606 | ||
2629 | /* | 2607 | // For every block we branch to, add that blocks readables to our list of readables, |
2630 | * For every block we branch to, add that blocks readables to our list of readables, | 2608 | // because we need to have those values valid on entry to our block. But if we write the |
2631 | * because we need to have those values valid on entry to our block. But if we write the | 2609 | // variable before we can possibly branch to that block, then we don't need to have it valid |
2632 | * variable before we can possibly branch to that block, then we don't need to have it valid | 2610 | // on entry to our block. So basically it looks like the branch instruction is reading |
2633 | * on entry to our block. So basically it looks like the branch instruction is reading | 2611 | // everything required by any blocks it can branch to. |
2634 | * everything required by any blocks it can branch to. | ||
2635 | */ | ||
2636 | do | 2612 | do |
2637 | { | 2613 | { |
2638 | this.resolvedSomething = false; | 2614 | this.resolvedSomething = false; |
@@ -2640,17 +2616,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2640 | this.ResolveBlock((GraphNodeBlock)firstLin); | 2616 | this.ResolveBlock((GraphNodeBlock)firstLin); |
2641 | } while(this.resolvedSomething); | 2617 | } while(this.resolvedSomething); |
2642 | 2618 | ||
2643 | /* | 2619 | // Repeat the cutting loops as long as we keep finding stuff. |
2644 | * Repeat the cutting loops as long as we keep finding stuff. | ||
2645 | */ | ||
2646 | bool didSomething; | 2620 | bool didSomething; |
2647 | do | 2621 | do |
2648 | { | 2622 | { |
2649 | didSomething = false; | 2623 | didSomething = false; |
2650 | 2624 | ||
2651 | /* | 2625 | // Strip out ldc.i4.1/xor/ldc.i4.1/xor |
2652 | * Strip out ldc.i4.1/xor/ldc.i4.1/xor | ||
2653 | */ | ||
2654 | for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) | 2626 | for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) |
2655 | { | 2627 | { |
2656 | if(!(gn is GraphNodeEmit)) | 2628 | if(!(gn is GraphNodeEmit)) |
@@ -2678,9 +2650,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2678 | didSomething = true; | 2650 | didSomething = true; |
2679 | } | 2651 | } |
2680 | 2652 | ||
2681 | /* | 2653 | // Replace c{cond}/ldc.i4.1/xor/br{false,true} -> c{cond}/br{true,false} |
2682 | * Replace c{cond}/ldc.i4.1/xor/br{false,true} -> c{cond}/br{true,false} | ||
2683 | */ | ||
2684 | for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) | 2654 | for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) |
2685 | { | 2655 | { |
2686 | if(!(gn is GraphNodeEmit)) | 2656 | if(!(gn is GraphNodeEmit)) |
@@ -2711,9 +2681,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2711 | didSomething = true; | 2681 | didSomething = true; |
2712 | } | 2682 | } |
2713 | 2683 | ||
2714 | /* | 2684 | // Replace c{cond}/br{false,true} -> b{!,}{cond} |
2715 | * Replace c{cond}/br{false,true} -> b{!,}{cond} | ||
2716 | */ | ||
2717 | for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) | 2685 | for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) |
2718 | { | 2686 | { |
2719 | if(!(gn is GraphNodeEmit)) | 2687 | if(!(gn is GraphNodeEmit)) |
@@ -2746,9 +2714,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2746 | didSomething = true; | 2714 | didSomething = true; |
2747 | } | 2715 | } |
2748 | 2716 | ||
2749 | /* | 2717 | // Replace ld{c.i4.0,null}/br{ne.un,eq} -> br{true,false} |
2750 | * Replace ld{c.i4.0,null}/br{ne.un,eq} -> br{true,false} | ||
2751 | */ | ||
2752 | for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) | 2718 | for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) |
2753 | { | 2719 | { |
2754 | if(!(gn is GraphNodeEmit)) | 2720 | if(!(gn is GraphNodeEmit)) |
@@ -2767,17 +2733,15 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2767 | didSomething = true; | 2733 | didSomething = true; |
2768 | } | 2734 | } |
2769 | 2735 | ||
2770 | /* | 2736 | // Replace: |
2771 | * Replace: | 2737 | // ldloc v1 |
2772 | * ldloc v1 | 2738 | // stloc v2 |
2773 | * stloc v2 | 2739 | // ld<anything> except ld<anything> v2 |
2774 | * ld<anything> except ld<anything> v2 | 2740 | // ldloc v2 |
2775 | * ldloc v2 | 2741 | // ...v2 unreferenced hereafter |
2776 | * ...v2 unreferenced hereafter | 2742 | // With: |
2777 | * With: | 2743 | // ld<anything> except ld<anything> v2 |
2778 | * ld<anything> except ld<anything> v2 | 2744 | // ldloc v1 |
2779 | * ldloc v1 | ||
2780 | */ | ||
2781 | for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) | 2745 | for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) |
2782 | { | 2746 | { |
2783 | 2747 | ||
@@ -2833,11 +2797,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2833 | didSomething = true; | 2797 | didSomething = true; |
2834 | } | 2798 | } |
2835 | 2799 | ||
2836 | /* | 2800 | // Remove all the stloc/ldloc that are back-to-back without the local |
2837 | * Remove all the stloc/ldloc that are back-to-back without the local | 2801 | // being needed afterwards. If it is needed afterwards, replace the |
2838 | * being needed afterwards. If it is needed afterwards, replace the | 2802 | // stloc/ldloc with dup/stloc. |
2839 | * stloc/ldloc with dup/stloc. | ||
2840 | */ | ||
2841 | for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) | 2803 | for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) |
2842 | { | 2804 | { |
2843 | if((gn is GraphNodeEmitLocal) && | 2805 | if((gn is GraphNodeEmitLocal) && |
@@ -2871,10 +2833,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2871 | } | 2833 | } |
2872 | } | 2834 | } |
2873 | 2835 | ||
2874 | /* | 2836 | // Remove all write-only local variables, ie, those with no ldloc[a] references. |
2875 | * Remove all write-only local variables, ie, those with no ldloc[a] references. | 2837 | // Replace any stloc instructions with pops. |
2876 | * Replace any stloc instructions with pops. | ||
2877 | */ | ||
2878 | for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) | 2838 | for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) |
2879 | { | 2839 | { |
2880 | ScriptMyLocal rdlcl = gn.ReadsLocal(); | 2840 | ScriptMyLocal rdlcl = gn.ReadsLocal(); |
@@ -2900,9 +2860,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2900 | } | 2860 | } |
2901 | } | 2861 | } |
2902 | 2862 | ||
2903 | /* | 2863 | // Remove any Ld<const>/Dup,Pop. |
2904 | * Remove any Ld<const>/Dup,Pop. | ||
2905 | */ | ||
2906 | for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) | 2864 | for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) |
2907 | { | 2865 | { |
2908 | if((gn is GraphNodeEmit) && | 2866 | if((gn is GraphNodeEmit) && |
@@ -2921,9 +2879,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2921 | } | 2879 | } |
2922 | } while(didSomething); | 2880 | } while(didSomething); |
2923 | 2881 | ||
2924 | /* | 2882 | // Dump out the results. |
2925 | * Dump out the results. | ||
2926 | */ | ||
2927 | if(DEBUG) | 2883 | if(DEBUG) |
2928 | { | 2884 | { |
2929 | Console.WriteLine(""); | 2885 | Console.WriteLine(""); |
@@ -2982,55 +2938,39 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2982 | if(currentBlock.hasBeenResolved == this.resolveSequence) | 2938 | if(currentBlock.hasBeenResolved == this.resolveSequence) |
2983 | return; | 2939 | return; |
2984 | 2940 | ||
2985 | /* | 2941 | // So we don't recurse forever on a backward branch. |
2986 | * So we don't recurse forever on a backward branch. | ||
2987 | */ | ||
2988 | currentBlock.hasBeenResolved = this.resolveSequence; | 2942 | currentBlock.hasBeenResolved = this.resolveSequence; |
2989 | 2943 | ||
2990 | /* | 2944 | // Assume we haven't written any locals yet. |
2991 | * Assume we haven't written any locals yet. | ||
2992 | */ | ||
2993 | List<ScriptMyLocal> localsWrittenSoFar = new List<ScriptMyLocal>(); | 2945 | List<ScriptMyLocal> localsWrittenSoFar = new List<ScriptMyLocal>(); |
2994 | 2946 | ||
2995 | /* | 2947 | // Scan through the instructions in this block. |
2996 | * Scan through the instructions in this block. | ||
2997 | */ | ||
2998 | for(GraphNode gn = currentBlock; gn != null;) | 2948 | for(GraphNode gn = currentBlock; gn != null;) |
2999 | { | 2949 | { |
3000 | 2950 | ||
3001 | /* | 2951 | // See if the instruction writes a local we don't know about yet. |
3002 | * See if the instruction writes a local we don't know about yet. | ||
3003 | */ | ||
3004 | ScriptMyLocal wrlcl = gn.WritesLocal(); | 2952 | ScriptMyLocal wrlcl = gn.WritesLocal(); |
3005 | if((wrlcl != null) && !localsWrittenSoFar.Contains(wrlcl)) | 2953 | if((wrlcl != null) && !localsWrittenSoFar.Contains(wrlcl)) |
3006 | { | 2954 | { |
3007 | localsWrittenSoFar.Add(wrlcl); | 2955 | localsWrittenSoFar.Add(wrlcl); |
3008 | } | 2956 | } |
3009 | 2957 | ||
3010 | /* | 2958 | // Scan through all the possible next instructions after this. |
3011 | * Scan through all the possible next instructions after this. | 2959 | // Note that if we are in the first part of a try/catch/finally block, |
3012 | * Note that if we are in the first part of a try/catch/finally block, | 2960 | // every instruction conditionally branches to the beginning of the |
3013 | * every instruction conditionally branches to the beginning of the | 2961 | // second part (the catch/finally block). |
3014 | * second part (the catch/finally block). | ||
3015 | */ | ||
3016 | GraphNode nextFallthruNode = null; | 2962 | GraphNode nextFallthruNode = null; |
3017 | foreach(GraphNode nn in gn.NextNodes) | 2963 | foreach(GraphNode nn in gn.NextNodes) |
3018 | { | 2964 | { |
3019 | if(nn is GraphNodeBlock) | 2965 | if(nn is GraphNodeBlock) |
3020 | { | 2966 | { |
3021 | 2967 | // Start of a block, go through all locals needed by that block on entry. | |
3022 | /* | ||
3023 | * Start of a block, go through all locals needed by that block on entry. | ||
3024 | */ | ||
3025 | GraphNodeBlock nextBlock = (GraphNodeBlock)nn; | 2968 | GraphNodeBlock nextBlock = (GraphNodeBlock)nn; |
3026 | ResolveBlock(nextBlock); | 2969 | ResolveBlock(nextBlock); |
3027 | foreach(ScriptMyLocal readByNextBlock in nextBlock.localsReadBeforeWritten) | 2970 | foreach(ScriptMyLocal readByNextBlock in nextBlock.localsReadBeforeWritten) |
3028 | { | 2971 | { |
3029 | 2972 | // If this block hasn't written it by now and this block doesn't already | |
3030 | /* | 2973 | // require it on entry, say this block requires it on entry. |
3031 | * If this block hasn't written it by now and this block doesn't already | ||
3032 | * require it on entry, say this block requires it on entry. | ||
3033 | */ | ||
3034 | if(!localsWrittenSoFar.Contains(readByNextBlock) && | 2974 | if(!localsWrittenSoFar.Contains(readByNextBlock) && |
3035 | !currentBlock.localsReadBeforeWritten.Contains(readByNextBlock)) | 2975 | !currentBlock.localsReadBeforeWritten.Contains(readByNextBlock)) |
3036 | { | 2976 | { |
@@ -3041,19 +2981,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
3041 | } | 2981 | } |
3042 | else | 2982 | else |
3043 | { | 2983 | { |
3044 | 2984 | // Not start of a block, should be normal fallthru instruction. | |
3045 | /* | ||
3046 | * Not start of a block, should be normal fallthru instruction. | ||
3047 | */ | ||
3048 | if(nextFallthruNode != null) | 2985 | if(nextFallthruNode != null) |
3049 | throw new Exception("more than one fallthru from " + gn.ToString()); | 2986 | throw new Exception("more than one fallthru from " + gn.ToString()); |
3050 | nextFallthruNode = nn; | 2987 | nextFallthruNode = nn; |
3051 | } | 2988 | } |
3052 | } | 2989 | } |
3053 | 2990 | ||
3054 | /* | 2991 | // Process next instruction if it isn't the start of a block. |
3055 | * Process next instruction if it isn't the start of a block. | ||
3056 | */ | ||
3057 | if(nextFallthruNode == gn) | 2992 | if(nextFallthruNode == gn) |
3058 | throw new Exception("can't fallthru to self"); | 2993 | throw new Exception("can't fallthru to self"); |
3059 | gn = nextFallthruNode; | 2994 | gn = nextFallthruNode; |
diff --git a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCompValu.cs b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCompValu.cs index 17bc3ec..675ab9a 100644 --- a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCompValu.cs +++ b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCompValu.cs | |||
@@ -107,8 +107,10 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
107 | return (type.ToLSLWrapType() != null) ? type.ToLSLWrapType() : type.ToSysType(); | 107 | return (type.ToLSLWrapType() != null) ? type.ToLSLWrapType() : type.ToSysType(); |
108 | } | 108 | } |
109 | 109 | ||
110 | // if a field of an XMRInstArrays array cannot be directly written, | 110 | /* |
111 | // get the method that can write it | 111 | * if a field of an XMRInstArrays array cannot be directly written, |
112 | * get the method that can write it | ||
113 | */ | ||
112 | private static MethodInfo ArrVarPopMeth(FieldInfo fi) | 114 | private static MethodInfo ArrVarPopMeth(FieldInfo fi) |
113 | { | 115 | { |
114 | if(fi.Name == "iarLists") | 116 | if(fi.Name == "iarLists") |
@@ -120,7 +122,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
120 | return null; | 122 | return null; |
121 | } | 123 | } |
122 | 124 | ||
123 | // emit code to push value onto stack | 125 | /* |
126 | * emit code to push value onto stack | ||
127 | */ | ||
124 | public void PushVal(ScriptCodeGen scg, Token errorAt, TokenType stackType) | 128 | public void PushVal(ScriptCodeGen scg, Token errorAt, TokenType stackType) |
125 | { | 129 | { |
126 | this.PushVal(scg, errorAt, stackType, false); | 130 | this.PushVal(scg, errorAt, stackType, false); |
@@ -133,7 +137,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
133 | public abstract void PushVal(ScriptCodeGen scg, Token errorAt); | 137 | public abstract void PushVal(ScriptCodeGen scg, Token errorAt); |
134 | public abstract void PushRef(ScriptCodeGen scg, Token errorAt); | 138 | public abstract void PushRef(ScriptCodeGen scg, Token errorAt); |
135 | 139 | ||
136 | // emit code to pop value from stack | 140 | /* |
141 | * emit code to pop value from stack | ||
142 | */ | ||
137 | public void PopPost(ScriptCodeGen scg, Token errorAt, TokenType stackType) | 143 | public void PopPost(ScriptCodeGen scg, Token errorAt, TokenType stackType) |
138 | { | 144 | { |
139 | TypeCast.CastTopOfStack(scg, errorAt, stackType, this.type, false); | 145 | TypeCast.CastTopOfStack(scg, errorAt, stackType, this.type, false); |
@@ -141,11 +147,18 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
141 | } | 147 | } |
142 | public virtual void PopPre(ScriptCodeGen scg, Token errorAt) | 148 | public virtual void PopPre(ScriptCodeGen scg, Token errorAt) |
143 | { | 149 | { |
144 | } // call this before pushing value to be popped | 150 | } |
151 | |||
152 | /* | ||
153 | * call this before pushing value to be popped | ||
154 | */ | ||
145 | public abstract void PopPost(ScriptCodeGen scg, Token errorAt); // call this after pushing value to be popped | 155 | public abstract void PopPost(ScriptCodeGen scg, Token errorAt); // call this after pushing value to be popped |
146 | 156 | ||
147 | // return true: doing a PushVal() does not involve CheckRun() | 157 | |
148 | // false: otherwise | 158 | /* |
159 | * return true: doing a PushVal() does not involve CheckRun() | ||
160 | * false: otherwise | ||
161 | */ | ||
149 | public virtual bool IsReadTrivial(ScriptCodeGen scg, Token readAt) | 162 | public virtual bool IsReadTrivial(ScriptCodeGen scg, Token readAt) |
150 | { | 163 | { |
151 | return true; | 164 | return true; |
@@ -173,12 +186,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
173 | return ((TokenTypeSDTypeDelegate)type).decl.GetArgSig(); | 186 | return ((TokenTypeSDTypeDelegate)type).decl.GetArgSig(); |
174 | } | 187 | } |
175 | 188 | ||
176 | // These are used only if type is a delegate too | 189 | /* |
177 | // - but it is a real delegate pointer in a global or local variable or a field, etc | 190 | * These are used only if type is a delegate too |
178 | // ie, PushVal() pushes a delegate pointer | 191 | * - but it is a real delegate pointer in a global or local variable or a field, etc |
179 | // - so we must have CallPre() push the delegate pointer as a 'this' for this.Invoke(...) | 192 | * - ie, PushVal() pushes a delegate pointer |
180 | // - and CallPost() call the delegate's Invoke() method | 193 | * - so we must have CallPre() push the delegate pointer as a 'this' for this.Invoke(...) |
181 | // - we assume the target function is non-trivial so we always use a call label | 194 | * - and CallPost() call the delegate's Invoke() method |
195 | * - we assume the target function is non-trivial so we always use a call label | ||
196 | */ | ||
182 | public virtual void CallPre(ScriptCodeGen scg, Token errorAt) // call this before pushing arguments | 197 | public virtual void CallPre(ScriptCodeGen scg, Token errorAt) // call this before pushing arguments |
183 | { | 198 | { |
184 | new ScriptCodeGen.CallLabel(scg, errorAt); | 199 | new ScriptCodeGen.CallLabel(scg, errorAt); |
diff --git a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptConsts.cs b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptConsts.cs index 63a6ee9..b44c4e2 100644 --- a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptConsts.cs +++ b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptConsts.cs | |||
@@ -64,9 +64,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
64 | { | 64 | { |
65 | Dictionary<string, ScriptConst> sc = new Dictionary<string, ScriptConst>(); | 65 | Dictionary<string, ScriptConst> sc = new Dictionary<string, ScriptConst>(); |
66 | 66 | ||
67 | /* | 67 | // For every event code, define XMREVENTCODE_<eventname> and XMREVENTMASKn_<eventname> symbols. |
68 | * For every event code, define XMREVENTCODE_<eventname> and XMREVENTMASKn_<eventname> symbols. | ||
69 | */ | ||
70 | for(int i = 0; i < 64; i++) | 68 | for(int i = 0; i < 64; i++) |
71 | { | 69 | { |
72 | try | 70 | try |
@@ -87,9 +85,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
87 | catch { } | 85 | catch { } |
88 | } | 86 | } |
89 | 87 | ||
90 | /* | 88 | // Also get all the constants from XMRInstAbstract and ScriptBaseClass etc as well. |
91 | * Also get all the constants from XMRInstAbstract and ScriptBaseClass etc as well. | ||
92 | */ | ||
93 | for(Type t = typeof(XMRInstAbstract); t != typeof(object); t = t.BaseType) | 89 | for(Type t = typeof(XMRInstAbstract); t != typeof(object); t = t.BaseType) |
94 | { | 90 | { |
95 | AddInterfaceConstants(sc, t.GetFields()); | 91 | AddInterfaceConstants(sc, t.GetFields()); |
@@ -132,10 +128,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
132 | Type fieldType = constField.FieldType; | 128 | Type fieldType = constField.FieldType; |
133 | CompValu cv; | 129 | CompValu cv; |
134 | 130 | ||
135 | /* | 131 | // The location of a simple number is the number itself. |
136 | * The location of a simple number is the number itself. | 132 | // Access to the value gets compiled as an ldc instruction. |
137 | * Access to the value gets compiled as an ldc instruction. | ||
138 | */ | ||
139 | if(fieldType == typeof(double)) | 133 | if(fieldType == typeof(double)) |
140 | { | 134 | { |
141 | cv = new CompValuFloat(new TokenTypeFloat(null), | 135 | cv = new CompValuFloat(new TokenTypeFloat(null), |
@@ -152,10 +146,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
152 | ((LSL_Integer)constField.GetValue(null)).value); | 146 | ((LSL_Integer)constField.GetValue(null)).value); |
153 | } | 147 | } |
154 | 148 | ||
155 | /* | 149 | // The location of a string is the string itself. |
156 | * The location of a string is the string itself. | 150 | // Access to the value gets compiled as an ldstr instruction. |
157 | * Access to the value gets compiled as an ldstr instruction. | ||
158 | */ | ||
159 | else if(fieldType == typeof(string)) | 151 | else if(fieldType == typeof(string)) |
160 | { | 152 | { |
161 | cv = new CompValuString(new TokenTypeStr(null), | 153 | cv = new CompValuString(new TokenTypeStr(null), |
@@ -167,18 +159,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
167 | (string)(LSL_String)constField.GetValue(null)); | 159 | (string)(LSL_String)constField.GetValue(null)); |
168 | } | 160 | } |
169 | 161 | ||
170 | /* | 162 | // The location of everything else (objects) is the static field in the interface definition. |
171 | * The location of everything else (objects) is the static field in the interface definition. | 163 | // Access to the value gets compiled as an ldsfld instruction. |
172 | * Access to the value gets compiled as an ldsfld instruction. | ||
173 | */ | ||
174 | else | 164 | else |
175 | { | 165 | { |
176 | cv = new CompValuSField(TokenType.FromSysType(null, fieldType), constField); | 166 | cv = new CompValuSField(TokenType.FromSysType(null, fieldType), constField); |
177 | } | 167 | } |
178 | 168 | ||
179 | /* | 169 | // Add to dictionary. |
180 | * Add to dictionary. | ||
181 | */ | ||
182 | new ScriptConst(sc, constField.Name, cv); | 170 | new ScriptConst(sc, constField.Name, cv); |
183 | } | 171 | } |
184 | } | 172 | } |
diff --git a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptObjCode.cs b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptObjCode.cs index d5b08f0..24d7c3d 100644 --- a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptObjCode.cs +++ b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptObjCode.cs | |||
@@ -87,9 +87,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
87 | */ | 87 | */ |
88 | public ScriptObjCode(BinaryReader objFileReader, TextWriter asmFileWriter, TextWriter srcFileWriter) | 88 | public ScriptObjCode(BinaryReader objFileReader, TextWriter asmFileWriter, TextWriter srcFileWriter) |
89 | { | 89 | { |
90 | /* | 90 | // Check version number to make sure we know how to process file contents. |
91 | * Check version number to make sure we know how to process file contents. | ||
92 | */ | ||
93 | char[] ocm = objFileReader.ReadChars(ScriptCodeGen.OBJECT_CODE_MAGIC.Length); | 91 | char[] ocm = objFileReader.ReadChars(ScriptCodeGen.OBJECT_CODE_MAGIC.Length); |
94 | if(new String(ocm) != ScriptCodeGen.OBJECT_CODE_MAGIC) | 92 | if(new String(ocm) != ScriptCodeGen.OBJECT_CODE_MAGIC) |
95 | throw new Exception("not an XMR object file (bad magic)"); | 93 | throw new Exception("not an XMR object file (bad magic)"); |
@@ -206,14 +204,10 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
206 | */ | 204 | */ |
207 | public void EndMethod(DynamicMethod method, Dictionary<int, ScriptSrcLoc> srcLocs) | 205 | public void EndMethod(DynamicMethod method, Dictionary<int, ScriptSrcLoc> srcLocs) |
208 | { | 206 | { |
209 | /* | 207 | // Save method object code pointer. |
210 | * Save method object code pointer. | ||
211 | */ | ||
212 | dynamicMethods.Add(method.Name, method); | 208 | dynamicMethods.Add(method.Name, method); |
213 | 209 | ||
214 | /* | 210 | // Build and sort iloffset -> source code location array. |
215 | * Build and sort iloffset -> source code location array. | ||
216 | */ | ||
217 | int n = srcLocs.Count; | 211 | int n = srcLocs.Count; |
218 | KeyValuePair<int, ScriptSrcLoc>[] srcLocArray = new KeyValuePair<int, ScriptSrcLoc>[n]; | 212 | KeyValuePair<int, ScriptSrcLoc>[] srcLocArray = new KeyValuePair<int, ScriptSrcLoc>[n]; |
219 | n = 0; | 213 | n = 0; |
@@ -221,9 +215,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
221 | srcLocArray[n++] = kvp; | 215 | srcLocArray[n++] = kvp; |
222 | Array.Sort(srcLocArray, endMethodWrapper); | 216 | Array.Sort(srcLocArray, endMethodWrapper); |
223 | 217 | ||
224 | /* | 218 | // Save sorted array. |
225 | * Save sorted array. | ||
226 | */ | ||
227 | scriptSrcLocss.Add(method.Name, srcLocArray); | 219 | scriptSrcLocss.Add(method.Name, srcLocArray); |
228 | } | 220 | } |
229 | 221 | ||
diff --git a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptObjWriter.cs b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptObjWriter.cs index b87bc72..6ab0bb5 100644 --- a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptObjWriter.cs +++ b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptObjWriter.cs | |||
@@ -121,9 +121,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
121 | this.argTypes = argTypes; | 121 | this.argTypes = argTypes; |
122 | this.objFileWriter = objFileWriter; | 122 | this.objFileWriter = objFileWriter; |
123 | 123 | ||
124 | /* | 124 | // Build list that translates system-defined types to script defined types. |
125 | * Build list that translates system-defined types to script defined types. | ||
126 | */ | ||
127 | foreach(TokenDeclSDType sdt in tokenScript.sdSrcTypesValues) | 125 | foreach(TokenDeclSDType sdt in tokenScript.sdSrcTypesValues) |
128 | { | 126 | { |
129 | Type sys = sdt.GetSysType(); | 127 | Type sys = sdt.GetSysType(); |
@@ -131,11 +129,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
131 | sdTypesRev[sys] = sdt.longName.val; | 129 | sdTypesRev[sys] = sdt.longName.val; |
132 | } | 130 | } |
133 | 131 | ||
134 | /* | 132 | // This tells the reader to call 'new DynamicMethod()' to create |
135 | * This tells the reader to call 'new DynamicMethod()' to create | 133 | // the function header. Then any forward reference calls to this |
136 | * the function header. Then any forward reference calls to this | 134 | // method will have a MethodInfo struct to call. |
137 | * method will have a MethodInfo struct to call. | ||
138 | */ | ||
139 | objFileWriter.Write((byte)ScriptObjWriterCode.DclMethod); | 135 | objFileWriter.Write((byte)ScriptObjWriterCode.DclMethod); |
140 | objFileWriter.Write(methName); | 136 | objFileWriter.Write(methName); |
141 | objFileWriter.Write(GetStrFromType(retType)); | 137 | objFileWriter.Write(GetStrFromType(retType)); |
@@ -154,10 +150,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
154 | */ | 150 | */ |
155 | public void BegMethod() | 151 | public void BegMethod() |
156 | { | 152 | { |
157 | /* | 153 | // This tells the reader to call methodInfo.GetILGenerator() |
158 | * This tells the reader to call methodInfo.GetILGenerator() | 154 | // so it can start writing CIL code for the method. |
159 | * so it can start writing CIL code for the method. | ||
160 | */ | ||
161 | objFileWriter.Write((byte)ScriptObjWriterCode.BegMethod); | 155 | objFileWriter.Write((byte)ScriptObjWriterCode.BegMethod); |
162 | objFileWriter.Write(methName); | 156 | objFileWriter.Write(methName); |
163 | } | 157 | } |
@@ -167,11 +161,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
167 | */ | 161 | */ |
168 | public void EndMethod() | 162 | public void EndMethod() |
169 | { | 163 | { |
170 | /* | 164 | // This tells the reader that all code for the method has |
171 | * This tells the reader that all code for the method has | 165 | // been written and so it will typically call CreateDelegate() |
172 | * been written and so it will typically call CreateDelegate() | 166 | // to finalize the method and create an entrypoint. |
173 | * to finalize the method and create an entrypoint. | ||
174 | */ | ||
175 | objFileWriter.Write((byte)ScriptObjWriterCode.EndMethod); | 167 | objFileWriter.Write((byte)ScriptObjWriterCode.EndMethod); |
176 | 168 | ||
177 | objFileWriter = null; | 169 | objFileWriter = null; |
@@ -404,431 +396,385 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
404 | 396 | ||
405 | while(true) | 397 | while(true) |
406 | { | 398 | { |
407 | 399 | // Get IL instruction offset at beginning of instruction. | |
408 | /* | ||
409 | * Get IL instruction offset at beginning of instruction. | ||
410 | */ | ||
411 | offset = 0; | 400 | offset = 0; |
412 | if((ilGen != null) && (monoGetCurrentOffset != null)) | 401 | if((ilGen != null) && (monoGetCurrentOffset != null)) |
413 | { | 402 | { |
414 | offset = (int)monoGetCurrentOffset.Invoke(null, ilGenArg); | 403 | offset = (int)monoGetCurrentOffset.Invoke(null, ilGenArg); |
415 | } | 404 | } |
416 | 405 | ||
417 | /* | 406 | // Read and decode next internal format code from input file (.xmrobj file). |
418 | * Read and decode next internal format code from input file (.xmrobj file). | ||
419 | */ | ||
420 | ScriptObjWriterCode code = (ScriptObjWriterCode)objReader.ReadByte(); | 407 | ScriptObjWriterCode code = (ScriptObjWriterCode)objReader.ReadByte(); |
421 | switch(code) | 408 | switch(code) |
422 | { | 409 | { |
423 | 410 | // Reached end-of-file so we are all done. | |
424 | /* | ||
425 | * Reached end-of-file so we are all done. | ||
426 | */ | ||
427 | case ScriptObjWriterCode.TheEnd: | 411 | case ScriptObjWriterCode.TheEnd: |
428 | { | 412 | return; |
429 | return; | ||
430 | } | ||
431 | 413 | ||
432 | /* | 414 | // Beginning of method's contents. |
433 | * Beginning of method's contents. | 415 | // Method must have already been declared via DclMethod |
434 | * Method must have already been declared via DclMethod | 416 | // so all we need is its name to retrieve from methods[]. |
435 | * so all we need is its name to retrieve from methods[]. | ||
436 | */ | ||
437 | case ScriptObjWriterCode.BegMethod: | 417 | case ScriptObjWriterCode.BegMethod: |
438 | { | 418 | { |
439 | string methName = objReader.ReadString(); | 419 | string methName = objReader.ReadString(); |
440 | 420 | ||
441 | method = methods[methName]; | 421 | method = methods[methName]; |
442 | ilGen = method.GetILGenerator(); | 422 | ilGen = method.GetILGenerator(); |
443 | ilGenArg[0] = ilGen; | 423 | ilGenArg[0] = ilGen; |
444 | 424 | ||
445 | labels.Clear(); | 425 | labels.Clear(); |
446 | locals.Clear(); | 426 | locals.Clear(); |
447 | labelNames.Clear(); | 427 | labelNames.Clear(); |
448 | localNames.Clear(); | 428 | localNames.Clear(); |
449 | 429 | ||
450 | srcLocs = new Dictionary<int, ScriptSrcLoc>(); | 430 | srcLocs = new Dictionary<int, ScriptSrcLoc>(); |
451 | if(objectTokens != null) | 431 | if(objectTokens != null) |
452 | objectTokens.BegMethod(method); | 432 | objectTokens.BegMethod(method); |
453 | break; | 433 | break; |
454 | } | 434 | } |
455 | 435 | ||
456 | /* | 436 | // End of method's contents (ie, an OpCodes.Ret was probably just output). |
457 | * End of method's contents (ie, an OpCodes.Ret was probably just output). | 437 | // Call the callback to tell it the method is complete, and it can do whatever |
458 | * Call the callback to tell it the method is complete, and it can do whatever | 438 | // it wants with the method. |
459 | * it wants with the method. | ||
460 | */ | ||
461 | case ScriptObjWriterCode.EndMethod: | 439 | case ScriptObjWriterCode.EndMethod: |
462 | { | 440 | { |
463 | ilGen = null; | 441 | ilGen = null; |
464 | ilGenArg[0] = null; | 442 | ilGenArg[0] = null; |
465 | scriptObjCode.EndMethod(method, srcLocs); | 443 | scriptObjCode.EndMethod(method, srcLocs); |
466 | srcLocs = null; | 444 | srcLocs = null; |
467 | if(objectTokens != null) | 445 | if(objectTokens != null) |
468 | objectTokens.EndMethod(); | 446 | objectTokens.EndMethod(); |
469 | break; | 447 | break; |
470 | } | 448 | } |
471 | 449 | ||
472 | /* | 450 | // Declare a label for branching to. |
473 | * Declare a label for branching to. | ||
474 | */ | ||
475 | case ScriptObjWriterCode.DclLabel: | 451 | case ScriptObjWriterCode.DclLabel: |
476 | { | 452 | { |
477 | int number = objReader.ReadInt32(); | 453 | int number = objReader.ReadInt32(); |
478 | string name = objReader.ReadString(); | 454 | string name = objReader.ReadString(); |
479 | 455 | ||
480 | labels.Add(number, ilGen.DefineLabel()); | 456 | labels.Add(number, ilGen.DefineLabel()); |
481 | labelNames.Add(number, name + "_" + number.ToString()); | 457 | labelNames.Add(number, name + "_" + number.ToString()); |
482 | if(objectTokens != null) | 458 | if(objectTokens != null) |
483 | objectTokens.DefineLabel(number, name); | 459 | objectTokens.DefineLabel(number, name); |
484 | break; | 460 | break; |
485 | } | 461 | } |
486 | 462 | ||
487 | /* | 463 | // Declare a local variable to store into. |
488 | * Declare a local variable to store into. | ||
489 | */ | ||
490 | case ScriptObjWriterCode.DclLocal: | 464 | case ScriptObjWriterCode.DclLocal: |
491 | { | 465 | { |
492 | int number = objReader.ReadInt32(); | 466 | int number = objReader.ReadInt32(); |
493 | string name = objReader.ReadString(); | 467 | string name = objReader.ReadString(); |
494 | string type = objReader.ReadString(); | 468 | string type = objReader.ReadString(); |
495 | Type syType = GetTypeFromStr(sdTypes, type); | 469 | Type syType = GetTypeFromStr(sdTypes, type); |
496 | 470 | ||
497 | locals.Add(number, ilGen.DeclareLocal(syType)); | 471 | locals.Add(number, ilGen.DeclareLocal(syType)); |
498 | localNames.Add(number, name + "_" + number.ToString()); | 472 | localNames.Add(number, name + "_" + number.ToString()); |
499 | if(objectTokens != null) | 473 | if(objectTokens != null) |
500 | objectTokens.DefineLocal(number, name, type, syType); | 474 | objectTokens.DefineLocal(number, name, type, syType); |
501 | break; | 475 | break; |
502 | } | 476 | } |
503 | 477 | ||
504 | /* | 478 | // Declare a method that will subsequently be defined. |
505 | * Declare a method that will subsequently be defined. | 479 | // We create the DynamicMethod object at this point in case there |
506 | * We create the DynamicMethod object at this point in case there | 480 | // are forward references from other method bodies. |
507 | * are forward references from other method bodies. | ||
508 | */ | ||
509 | case ScriptObjWriterCode.DclMethod: | 481 | case ScriptObjWriterCode.DclMethod: |
482 | { | ||
483 | string methName = objReader.ReadString(); | ||
484 | Type retType = GetTypeFromStr(sdTypes, objReader.ReadString()); | ||
485 | int nArgs = objReader.ReadInt32(); | ||
486 | |||
487 | Type[] argTypes = new Type[nArgs]; | ||
488 | string[] argNames = new string[nArgs]; | ||
489 | for(int i = 0; i < nArgs; i++) | ||
510 | { | 490 | { |
511 | string methName = objReader.ReadString(); | 491 | argTypes[i] = GetTypeFromStr(sdTypes, objReader.ReadString()); |
512 | Type retType = GetTypeFromStr(sdTypes, objReader.ReadString()); | 492 | argNames[i] = objReader.ReadString(); |
513 | int nArgs = objReader.ReadInt32(); | ||
514 | |||
515 | Type[] argTypes = new Type[nArgs]; | ||
516 | string[] argNames = new string[nArgs]; | ||
517 | for(int i = 0; i < nArgs; i++) | ||
518 | { | ||
519 | argTypes[i] = GetTypeFromStr(sdTypes, objReader.ReadString()); | ||
520 | argNames[i] = objReader.ReadString(); | ||
521 | } | ||
522 | methods.Add(methName, new DynamicMethod(methName, retType, argTypes)); | ||
523 | if(objectTokens != null) | ||
524 | objectTokens.DefineMethod(methName, retType, argTypes, argNames); | ||
525 | break; | ||
526 | } | 493 | } |
494 | methods.Add(methName, new DynamicMethod(methName, retType, argTypes)); | ||
495 | if(objectTokens != null) | ||
496 | objectTokens.DefineMethod(methName, retType, argTypes, argNames); | ||
497 | break; | ||
498 | } | ||
527 | 499 | ||
528 | /* | 500 | // Mark a previously declared label at this spot. |
529 | * Mark a previously declared label at this spot. | ||
530 | */ | ||
531 | case ScriptObjWriterCode.MarkLabel: | 501 | case ScriptObjWriterCode.MarkLabel: |
532 | { | 502 | { |
533 | int number = objReader.ReadInt32(); | 503 | int number = objReader.ReadInt32(); |
534 | 504 | ||
535 | ilGen.MarkLabel(labels[number]); | 505 | ilGen.MarkLabel(labels[number]); |
536 | 506 | ||
537 | if(objectTokens != null) | 507 | if(objectTokens != null) |
538 | objectTokens.MarkLabel(offset, number); | 508 | objectTokens.MarkLabel(offset, number); |
539 | break; | 509 | break; |
540 | } | 510 | } |
541 | 511 | ||
542 | /* | 512 | // Try/Catch blocks. |
543 | * Try/Catch blocks. | ||
544 | */ | ||
545 | case ScriptObjWriterCode.BegExcBlk: | 513 | case ScriptObjWriterCode.BegExcBlk: |
546 | { | 514 | { |
547 | ilGen.BeginExceptionBlock(); | 515 | ilGen.BeginExceptionBlock(); |
548 | if(objectTokens != null) | 516 | if(objectTokens != null) |
549 | objectTokens.BegExcBlk(offset); | 517 | objectTokens.BegExcBlk(offset); |
550 | break; | 518 | break; |
551 | } | 519 | } |
552 | 520 | ||
553 | case ScriptObjWriterCode.BegCatBlk: | 521 | case ScriptObjWriterCode.BegCatBlk: |
554 | { | 522 | { |
555 | Type excType = GetTypeFromStr(sdTypes, objReader.ReadString()); | 523 | Type excType = GetTypeFromStr(sdTypes, objReader.ReadString()); |
556 | ilGen.BeginCatchBlock(excType); | 524 | ilGen.BeginCatchBlock(excType); |
557 | if(objectTokens != null) | 525 | if(objectTokens != null) |
558 | objectTokens.BegCatBlk(offset, excType); | 526 | objectTokens.BegCatBlk(offset, excType); |
559 | break; | 527 | break; |
560 | } | 528 | } |
561 | 529 | ||
562 | case ScriptObjWriterCode.BegFinBlk: | 530 | case ScriptObjWriterCode.BegFinBlk: |
563 | { | 531 | { |
564 | ilGen.BeginFinallyBlock(); | 532 | ilGen.BeginFinallyBlock(); |
565 | if(objectTokens != null) | 533 | if(objectTokens != null) |
566 | objectTokens.BegFinBlk(offset); | 534 | objectTokens.BegFinBlk(offset); |
567 | break; | 535 | break; |
568 | } | 536 | } |
569 | 537 | ||
570 | case ScriptObjWriterCode.EndExcBlk: | 538 | case ScriptObjWriterCode.EndExcBlk: |
571 | { | 539 | { |
572 | ilGen.EndExceptionBlock(); | 540 | ilGen.EndExceptionBlock(); |
573 | if(objectTokens != null) | 541 | if(objectTokens != null) |
574 | objectTokens.EndExcBlk(offset); | 542 | objectTokens.EndExcBlk(offset); |
575 | break; | 543 | break; |
576 | } | 544 | } |
577 | 545 | ||
578 | /* | 546 | // Emit an opcode with no operand. |
579 | * Emit an opcode with no operand. | ||
580 | */ | ||
581 | case ScriptObjWriterCode.EmitNull: | 547 | case ScriptObjWriterCode.EmitNull: |
582 | { | 548 | { |
583 | OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn); | 549 | OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn); |
584 | 550 | ||
585 | SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn); | 551 | SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn); |
586 | ilGen.Emit(opCode); | 552 | ilGen.Emit(opCode); |
587 | 553 | ||
588 | if(objectTokens != null) | 554 | if(objectTokens != null) |
589 | objectTokens.EmitNull(offset, opCode); | 555 | objectTokens.EmitNull(offset, opCode); |
590 | break; | 556 | break; |
591 | } | 557 | } |
592 | 558 | ||
593 | /* | 559 | // Emit an opcode with a FieldInfo operand. |
594 | * Emit an opcode with a FieldInfo operand. | ||
595 | */ | ||
596 | case ScriptObjWriterCode.EmitField: | 560 | case ScriptObjWriterCode.EmitField: |
597 | { | 561 | { |
598 | OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn); | 562 | OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn); |
599 | Type reflectedType = GetTypeFromStr(sdTypes, objReader.ReadString()); | 563 | Type reflectedType = GetTypeFromStr(sdTypes, objReader.ReadString()); |
600 | string fieldName = objReader.ReadString(); | 564 | string fieldName = objReader.ReadString(); |
601 | 565 | ||
602 | FieldInfo field = reflectedType.GetField(fieldName); | 566 | FieldInfo field = reflectedType.GetField(fieldName); |
603 | SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn); | 567 | SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn); |
604 | ilGen.Emit(opCode, field); | 568 | ilGen.Emit(opCode, field); |
605 | 569 | ||
606 | if(objectTokens != null) | 570 | if(objectTokens != null) |
607 | objectTokens.EmitField(offset, opCode, field); | 571 | objectTokens.EmitField(offset, opCode, field); |
608 | break; | 572 | break; |
609 | } | 573 | } |
610 | 574 | ||
611 | /* | 575 | // Emit an opcode with a LocalBuilder operand. |
612 | * Emit an opcode with a LocalBuilder operand. | ||
613 | */ | ||
614 | case ScriptObjWriterCode.EmitLocal: | 576 | case ScriptObjWriterCode.EmitLocal: |
615 | { | 577 | { |
616 | OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn); | 578 | OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn); |
617 | int number = objReader.ReadInt32(); | 579 | int number = objReader.ReadInt32(); |
618 | SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn); | 580 | SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn); |
619 | ilGen.Emit(opCode, locals[number]); | 581 | ilGen.Emit(opCode, locals[number]); |
620 | 582 | ||
621 | if(objectTokens != null) | 583 | if(objectTokens != null) |
622 | objectTokens.EmitLocal(offset, opCode, number); | 584 | objectTokens.EmitLocal(offset, opCode, number); |
623 | break; | 585 | break; |
624 | } | 586 | } |
625 | 587 | ||
626 | /* | 588 | // Emit an opcode with a Type operand. |
627 | * Emit an opcode with a Type operand. | ||
628 | */ | ||
629 | case ScriptObjWriterCode.EmitType: | 589 | case ScriptObjWriterCode.EmitType: |
630 | { | 590 | { |
631 | OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn); | 591 | OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn); |
632 | string name = objReader.ReadString(); | 592 | string name = objReader.ReadString(); |
633 | Type type = GetTypeFromStr(sdTypes, name); | 593 | Type type = GetTypeFromStr(sdTypes, name); |
634 | 594 | ||
635 | SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn); | 595 | SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn); |
636 | ilGen.Emit(opCode, type); | 596 | ilGen.Emit(opCode, type); |
637 | 597 | ||
638 | if(objectTokens != null) | 598 | if(objectTokens != null) |
639 | objectTokens.EmitType(offset, opCode, type); | 599 | objectTokens.EmitType(offset, opCode, type); |
640 | break; | 600 | break; |
641 | } | 601 | } |
642 | 602 | ||
643 | /* | 603 | // Emit an opcode with a Label operand. |
644 | * Emit an opcode with a Label operand. | ||
645 | */ | ||
646 | case ScriptObjWriterCode.EmitLabel: | 604 | case ScriptObjWriterCode.EmitLabel: |
647 | { | 605 | { |
648 | OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn); | 606 | OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn); |
649 | int number = objReader.ReadInt32(); | 607 | int number = objReader.ReadInt32(); |
650 | 608 | ||
651 | SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn); | 609 | SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn); |
652 | ilGen.Emit(opCode, labels[number]); | 610 | ilGen.Emit(opCode, labels[number]); |
653 | 611 | ||
654 | if(objectTokens != null) | 612 | if(objectTokens != null) |
655 | objectTokens.EmitLabel(offset, opCode, number); | 613 | objectTokens.EmitLabel(offset, opCode, number); |
656 | break; | 614 | break; |
657 | } | 615 | } |
658 | 616 | ||
659 | /* | 617 | // Emit an opcode with a Label array operand. |
660 | * Emit an opcode with a Label array operand. | ||
661 | */ | ||
662 | case ScriptObjWriterCode.EmitLabels: | 618 | case ScriptObjWriterCode.EmitLabels: |
619 | { | ||
620 | OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn); | ||
621 | int nLabels = objReader.ReadInt32(); | ||
622 | Label[] lbls = new Label[nLabels]; | ||
623 | int[] nums = new int[nLabels]; | ||
624 | for(int i = 0; i < nLabels; i++) | ||
663 | { | 625 | { |
664 | OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn); | 626 | nums[i] = objReader.ReadInt32(); |
665 | int nLabels = objReader.ReadInt32(); | 627 | lbls[i] = labels[nums[i]]; |
666 | Label[] lbls = new Label[nLabels]; | 628 | } |
667 | int[] nums = new int[nLabels]; | ||
668 | for(int i = 0; i < nLabels; i++) | ||
669 | { | ||
670 | nums[i] = objReader.ReadInt32(); | ||
671 | lbls[i] = labels[nums[i]]; | ||
672 | } | ||
673 | 629 | ||
674 | SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn); | 630 | SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn); |
675 | ilGen.Emit(opCode, lbls); | 631 | ilGen.Emit(opCode, lbls); |
676 | 632 | ||
677 | if(objectTokens != null) | 633 | if(objectTokens != null) |
678 | objectTokens.EmitLabels(offset, opCode, nums); | 634 | objectTokens.EmitLabels(offset, opCode, nums); |
679 | break; | 635 | break; |
680 | } | 636 | } |
681 | 637 | ||
682 | /* | 638 | // Emit an opcode with a MethodInfo operand (such as a call) of an external function. |
683 | * Emit an opcode with a MethodInfo operand (such as a call) of an external function. | ||
684 | */ | ||
685 | case ScriptObjWriterCode.EmitMethodExt: | 639 | case ScriptObjWriterCode.EmitMethodExt: |
640 | { | ||
641 | OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn); | ||
642 | string methName = objReader.ReadString(); | ||
643 | Type methType = GetTypeFromStr(sdTypes, objReader.ReadString()); | ||
644 | int nArgs = objReader.ReadInt32(); | ||
645 | |||
646 | Type[] argTypes = new Type[nArgs]; | ||
647 | for(int i = 0; i < nArgs; i++) | ||
686 | { | 648 | { |
687 | OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn); | 649 | argTypes[i] = GetTypeFromStr(sdTypes, objReader.ReadString()); |
688 | string methName = objReader.ReadString(); | ||
689 | Type methType = GetTypeFromStr(sdTypes, objReader.ReadString()); | ||
690 | int nArgs = objReader.ReadInt32(); | ||
691 | |||
692 | Type[] argTypes = new Type[nArgs]; | ||
693 | for(int i = 0; i < nArgs; i++) | ||
694 | { | ||
695 | argTypes[i] = GetTypeFromStr(sdTypes, objReader.ReadString()); | ||
696 | } | ||
697 | MethodInfo methInfo = methType.GetMethod(methName, argTypes); | ||
698 | SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn); | ||
699 | ilGen.Emit(opCode, methInfo); | ||
700 | |||
701 | if(objectTokens != null) | ||
702 | objectTokens.EmitMethod(offset, opCode, methInfo); | ||
703 | break; | ||
704 | } | 650 | } |
651 | MethodInfo methInfo = methType.GetMethod(methName, argTypes); | ||
652 | SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn); | ||
653 | ilGen.Emit(opCode, methInfo); | ||
654 | |||
655 | if(objectTokens != null) | ||
656 | objectTokens.EmitMethod(offset, opCode, methInfo); | ||
657 | break; | ||
658 | } | ||
705 | 659 | ||
706 | /* | 660 | // Emit an opcode with a MethodInfo operand of an internal function |
707 | * Emit an opcode with a MethodInfo operand of an internal function | 661 | // (previously declared via DclMethod). |
708 | * (previously declared via DclMethod). | ||
709 | */ | ||
710 | case ScriptObjWriterCode.EmitMethodInt: | 662 | case ScriptObjWriterCode.EmitMethodInt: |
711 | { | 663 | { |
712 | OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn); | 664 | OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn); |
713 | string methName = objReader.ReadString(); | 665 | string methName = objReader.ReadString(); |
714 | 666 | ||
715 | MethodInfo methInfo = methods[methName]; | 667 | MethodInfo methInfo = methods[methName]; |
716 | SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn); | 668 | SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn); |
717 | ilGen.Emit(opCode, methInfo); | 669 | ilGen.Emit(opCode, methInfo); |
718 | 670 | ||
719 | if(objectTokens != null) | 671 | if(objectTokens != null) |
720 | objectTokens.EmitMethod(offset, opCode, methInfo); | 672 | objectTokens.EmitMethod(offset, opCode, methInfo); |
721 | break; | 673 | break; |
722 | } | 674 | } |
723 | 675 | ||
724 | /* | 676 | // Emit an opcode with a ConstructorInfo operand. |
725 | * Emit an opcode with a ConstructorInfo operand. | ||
726 | */ | ||
727 | case ScriptObjWriterCode.EmitCtor: | 677 | case ScriptObjWriterCode.EmitCtor: |
678 | { | ||
679 | OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn); | ||
680 | Type ctorType = GetTypeFromStr(sdTypes, objReader.ReadString()); | ||
681 | int nArgs = objReader.ReadInt32(); | ||
682 | Type[] argTypes = new Type[nArgs]; | ||
683 | for(int i = 0; i < nArgs; i++) | ||
728 | { | 684 | { |
729 | OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn); | 685 | argTypes[i] = GetTypeFromStr(sdTypes, objReader.ReadString()); |
730 | Type ctorType = GetTypeFromStr(sdTypes, objReader.ReadString()); | 686 | } |
731 | int nArgs = objReader.ReadInt32(); | ||
732 | Type[] argTypes = new Type[nArgs]; | ||
733 | for(int i = 0; i < nArgs; i++) | ||
734 | { | ||
735 | argTypes[i] = GetTypeFromStr(sdTypes, objReader.ReadString()); | ||
736 | } | ||
737 | 687 | ||
738 | ConstructorInfo ctorInfo = ctorType.GetConstructor(argTypes); | 688 | ConstructorInfo ctorInfo = ctorType.GetConstructor(argTypes); |
739 | SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn); | 689 | SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn); |
740 | ilGen.Emit(opCode, ctorInfo); | 690 | ilGen.Emit(opCode, ctorInfo); |
741 | 691 | ||
742 | if(objectTokens != null) | 692 | if(objectTokens != null) |
743 | objectTokens.EmitCtor(offset, opCode, ctorInfo); | 693 | objectTokens.EmitCtor(offset, opCode, ctorInfo); |
744 | break; | 694 | break; |
745 | } | 695 | } |
746 | 696 | ||
747 | /* | 697 | // Emit an opcode with a constant operand of various types. |
748 | * Emit an opcode with a constant operand of various types. | ||
749 | */ | ||
750 | case ScriptObjWriterCode.EmitDouble: | 698 | case ScriptObjWriterCode.EmitDouble: |
751 | { | 699 | { |
752 | OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn); | 700 | OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn); |
753 | double value = objReader.ReadDouble(); | 701 | double value = objReader.ReadDouble(); |
754 | 702 | ||
755 | if(opCode != OpCodes.Ldc_R8) | 703 | if(opCode != OpCodes.Ldc_R8) |
756 | { | 704 | { |
757 | throw new Exception("bad opcode " + opCode.ToString()); | 705 | throw new Exception("bad opcode " + opCode.ToString()); |
758 | } | ||
759 | SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn); | ||
760 | ilGen.Emit(opCode, value); | ||
761 | |||
762 | if(objectTokens != null) | ||
763 | objectTokens.EmitDouble(offset, opCode, value); | ||
764 | break; | ||
765 | } | 706 | } |
707 | SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn); | ||
708 | ilGen.Emit(opCode, value); | ||
766 | 709 | ||
767 | case ScriptObjWriterCode.EmitFloat: | 710 | if(objectTokens != null) |
768 | { | 711 | objectTokens.EmitDouble(offset, opCode, value); |
769 | OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn); | 712 | break; |
770 | float value = objReader.ReadSingle(); | 713 | } |
771 | 714 | ||
772 | if(opCode != OpCodes.Ldc_R4) | 715 | case ScriptObjWriterCode.EmitFloat: |
773 | { | 716 | { |
774 | throw new Exception("bad opcode " + opCode.ToString()); | 717 | OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn); |
775 | } | 718 | float value = objReader.ReadSingle(); |
776 | SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn); | ||
777 | ilGen.Emit(opCode, value); | ||
778 | 719 | ||
779 | if(objectTokens != null) | 720 | if(opCode != OpCodes.Ldc_R4) |
780 | objectTokens.EmitFloat(offset, opCode, value); | 721 | { |
781 | break; | 722 | throw new Exception("bad opcode " + opCode.ToString()); |
782 | } | 723 | } |
724 | SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn); | ||
725 | ilGen.Emit(opCode, value); | ||
726 | |||
727 | if(objectTokens != null) | ||
728 | objectTokens.EmitFloat(offset, opCode, value); | ||
729 | break; | ||
730 | } | ||
783 | 731 | ||
784 | case ScriptObjWriterCode.EmitInteger: | 732 | case ScriptObjWriterCode.EmitInteger: |
785 | { | 733 | { |
786 | OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn); | 734 | OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn); |
787 | int value = objReader.ReadInt32(); | 735 | int value = objReader.ReadInt32(); |
788 | 736 | ||
789 | SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn); | 737 | SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn); |
790 | 738 | ||
791 | if(opCode == OpCodes.Ldc_I4) | 739 | if(opCode == OpCodes.Ldc_I4) |
740 | { | ||
741 | if((value >= -1) && (value <= 8)) | ||
792 | { | 742 | { |
793 | if((value >= -1) && (value <= 8)) | 743 | opCode = opCodesLdcI4M1P8[value + 1]; |
794 | { | 744 | ilGen.Emit(opCode); |
795 | opCode = opCodesLdcI4M1P8[value + 1]; | 745 | if(objectTokens != null) |
796 | ilGen.Emit(opCode); | 746 | objectTokens.EmitNull(offset, opCode); |
797 | if(objectTokens != null) | 747 | break; |
798 | objectTokens.EmitNull(offset, opCode); | 748 | } |
799 | break; | 749 | if((value >= 0) && (value <= 127)) |
800 | } | 750 | { |
801 | if((value >= 0) && (value <= 127)) | 751 | opCode = OpCodes.Ldc_I4_S; |
802 | { | 752 | ilGen.Emit(OpCodes.Ldc_I4_S, (sbyte)value); |
803 | opCode = OpCodes.Ldc_I4_S; | 753 | goto pemitint; |
804 | ilGen.Emit(OpCodes.Ldc_I4_S, (sbyte)value); | ||
805 | goto pemitint; | ||
806 | } | ||
807 | } | 754 | } |
808 | |||
809 | ilGen.Emit(opCode, value); | ||
810 | pemitint: | ||
811 | if(objectTokens != null) | ||
812 | objectTokens.EmitInteger(offset, opCode, value); | ||
813 | break; | ||
814 | } | 755 | } |
815 | 756 | ||
757 | ilGen.Emit(opCode, value); | ||
758 | pemitint: | ||
759 | if(objectTokens != null) | ||
760 | objectTokens.EmitInteger(offset, opCode, value); | ||
761 | break; | ||
762 | } | ||
763 | |||
816 | case ScriptObjWriterCode.EmitString: | 764 | case ScriptObjWriterCode.EmitString: |
817 | { | 765 | { |
818 | OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn); | 766 | OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn); |
819 | string value = objReader.ReadString(); | 767 | string value = objReader.ReadString(); |
820 | 768 | ||
821 | SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn); | 769 | SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn); |
822 | ilGen.Emit(opCode, value); | 770 | ilGen.Emit(opCode, value); |
823 | 771 | ||
824 | if(objectTokens != null) | 772 | if(objectTokens != null) |
825 | objectTokens.EmitString(offset, opCode, value); | 773 | objectTokens.EmitString(offset, opCode, value); |
826 | break; | 774 | break; |
827 | } | 775 | } |
828 | 776 | ||
829 | /* | 777 | // Who knows what? |
830 | * Who knows what? | ||
831 | */ | ||
832 | default: | 778 | default: |
833 | throw new Exception("bad ScriptObjWriterCode " + ((byte)code).ToString()); | 779 | throw new Exception("bad ScriptObjWriterCode " + ((byte)code).ToString()); |
834 | } | 780 | } |
diff --git a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptReduce.cs b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptReduce.cs index b0653f7..85bc9aa 100644 --- a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptReduce.cs +++ b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptReduce.cs | |||
@@ -58,7 +58,6 @@ using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; | |||
58 | 58 | ||
59 | namespace OpenSim.Region.ScriptEngine.Yengine | 59 | namespace OpenSim.Region.ScriptEngine.Yengine |
60 | { | 60 | { |
61 | |||
62 | public class ScriptReduce | 61 | public class ScriptReduce |
63 | { | 62 | { |
64 | public const uint SDT_PRIVATE = 1; | 63 | public const uint SDT_PRIVATE = 1; |
@@ -177,25 +176,21 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
177 | */ | 176 | */ |
178 | private ScriptReduce(TokenBegin tokenBegin) | 177 | private ScriptReduce(TokenBegin tokenBegin) |
179 | { | 178 | { |
180 | /* | 179 | // Create a place to put the top-level script components, |
181 | * Create a place to put the top-level script components, | 180 | // eg, state bodies, functions, global variables. |
182 | * eg, state bodies, functions, global variables. | ||
183 | */ | ||
184 | tokenScript = new TokenScript(tokenBegin.nextToken); | 181 | tokenScript = new TokenScript(tokenBegin.nextToken); |
185 | 182 | ||
186 | /* | 183 | // 'class', 'delegate', 'instance' all define types. |
187 | * 'class', 'delegate', 'instance' all define types. | 184 | // So we pre-scan the source tokens for those keywords |
188 | * So we pre-scan the source tokens for those keywords | 185 | // to build a script-defined type table and substitute |
189 | * to build a script-defined type table and substitute | 186 | // type tokens for those names in the source. This is |
190 | * type tokens for those names in the source. This is | 187 | // done as a separate scan so they can cross-reference |
191 | * done as a separate scan so they can cross-reference | 188 | // each other. Also does likewise for fixed array types. |
192 | * each other. Also does likewise for fixed array types. | 189 | // |
193 | * | 190 | // Also, all 'typedef's are processed here. Their definitions |
194 | * Also, all 'typedef's are processed here. Their definitions | 191 | // remain in the source token stream after this, but they can |
195 | * remain in the source token stream after this, but they can | 192 | // be skipped over, because their bodies have been substituted |
196 | * be skipped over, because their bodies have been substituted | 193 | // in the source for any references. |
197 | * in the source for any references. | ||
198 | */ | ||
199 | ParseSDTypePreScanPassOne(tokenBegin); // catalog definitions | 194 | ParseSDTypePreScanPassOne(tokenBegin); // catalog definitions |
200 | ParseSDTypePreScanPassTwo(tokenBegin); // substitute references | 195 | ParseSDTypePreScanPassTwo(tokenBegin); // substitute references |
201 | 196 | ||
@@ -226,10 +221,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
226 | } | 221 | } |
227 | */ | 222 | */ |
228 | 223 | ||
229 | /* | 224 | // Create a function $globalvarinit to hold all explicit |
230 | * Create a function $globalvarinit to hold all explicit | 225 | // global variable initializations. |
231 | * global variable initializations. | ||
232 | */ | ||
233 | TokenDeclVar gviFunc = new TokenDeclVar(tokenBegin, null, tokenScript); | 226 | TokenDeclVar gviFunc = new TokenDeclVar(tokenBegin, null, tokenScript); |
234 | gviFunc.name = new TokenName(gviFunc, "$globalvarinit"); | 227 | gviFunc.name = new TokenName(gviFunc, "$globalvarinit"); |
235 | gviFunc.retType = new TokenTypeVoid(gviFunc); | 228 | gviFunc.retType = new TokenTypeVoid(gviFunc); |
@@ -240,9 +233,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
240 | tokenScript.globalVarInit = gviFunc; | 233 | tokenScript.globalVarInit = gviFunc; |
241 | tokenScript.AddVarEntry(gviFunc); | 234 | tokenScript.AddVarEntry(gviFunc); |
242 | 235 | ||
243 | /* | 236 | // Scan through the tokens until we reach the end. |
244 | * Scan through the tokens until we reach the end. | ||
245 | */ | ||
246 | for(Token token = tokenBegin.nextToken; !(token is TokenEnd);) | 237 | for(Token token = tokenBegin.nextToken; !(token is TokenEnd);) |
247 | { | 238 | { |
248 | if(token is TokenKwSemi) | 239 | if(token is TokenKwSemi) |
@@ -251,25 +242,19 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
251 | continue; | 242 | continue; |
252 | } | 243 | } |
253 | 244 | ||
254 | /* | 245 | // Script-defined type declarations. |
255 | * Script-defined type declarations. | ||
256 | */ | ||
257 | if(ParseDeclSDTypes(ref token, null, SDT_PUBLIC)) | 246 | if(ParseDeclSDTypes(ref token, null, SDT_PUBLIC)) |
258 | continue; | 247 | continue; |
259 | 248 | ||
260 | /* | 249 | // constant <name> = <rval> ; |
261 | * constant <name> = <rval> ; | ||
262 | */ | ||
263 | if(token is TokenKwConst) | 250 | if(token is TokenKwConst) |
264 | { | 251 | { |
265 | ParseDeclVar(ref token, null); | 252 | ParseDeclVar(ref token, null); |
266 | continue; | 253 | continue; |
267 | } | 254 | } |
268 | 255 | ||
269 | /* | 256 | // <type> <name> ; |
270 | * <type> <name> ; | 257 | // <type> <name> = <rval> ; |
271 | * <type> <name> = <rval> ; | ||
272 | */ | ||
273 | if((token is TokenType) && | 258 | if((token is TokenType) && |
274 | (token.nextToken is TokenName) && | 259 | (token.nextToken is TokenName) && |
275 | ((token.nextToken.nextToken is TokenKwSemi) || | 260 | ((token.nextToken.nextToken is TokenKwSemi) || |
@@ -285,9 +270,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
285 | continue; | 270 | continue; |
286 | } | 271 | } |
287 | 272 | ||
288 | /* | 273 | // <type> <name> { [ get { <body> } ] [ set { <body> } ] } |
289 | * <type> <name> { [ get { <body> } ] [ set { <body> } ] } | ||
290 | */ | ||
291 | if((token is TokenType) && | 274 | if((token is TokenType) && |
292 | (token.nextToken is TokenName) && | 275 | (token.nextToken is TokenName) && |
293 | (token.nextToken.nextToken is TokenKwBrcOpen)) | 276 | (token.nextToken.nextToken is TokenKwBrcOpen)) |
@@ -296,10 +279,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
296 | continue; | 279 | continue; |
297 | } | 280 | } |
298 | 281 | ||
299 | /* | 282 | // <type> <name> <funcargs> <funcbody> |
300 | * <type> <name> <funcargs> <funcbody> | 283 | // global function returning specified type |
301 | * global function returning specified type | ||
302 | */ | ||
303 | if(token is TokenType) | 284 | if(token is TokenType) |
304 | { | 285 | { |
305 | TokenType tokenType = (TokenType)token; | 286 | TokenType tokenType = (TokenType)token; |
@@ -330,10 +311,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
330 | continue; | 311 | continue; |
331 | } | 312 | } |
332 | 313 | ||
333 | /* | 314 | // <name> <funcargs> <funcbody> |
334 | * <name> <funcargs> <funcbody> | 315 | // global function returning void |
335 | * global function returning void | ||
336 | */ | ||
337 | if(token is TokenName) | 316 | if(token is TokenName) |
338 | { | 317 | { |
339 | TokenName tokenName = (TokenName)token; | 318 | TokenName tokenName = (TokenName)token; |
@@ -355,9 +334,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
355 | continue; | 334 | continue; |
356 | } | 335 | } |
357 | 336 | ||
358 | /* | 337 | // default <statebody> |
359 | * default <statebody> | ||
360 | */ | ||
361 | if(token is TokenKwDefault) | 338 | if(token is TokenKwDefault) |
362 | { | 339 | { |
363 | TokenDeclState tokenDeclState = new TokenDeclState(token); | 340 | TokenDeclState tokenDeclState = new TokenDeclState(token); |
@@ -374,9 +351,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
374 | continue; | 351 | continue; |
375 | } | 352 | } |
376 | 353 | ||
377 | /* | 354 | // state <name> <statebody> |
378 | * state <name> <statebody> | ||
379 | */ | ||
380 | if(token is TokenKwState) | 355 | if(token is TokenKwState) |
381 | { | 356 | { |
382 | TokenDeclState tokenDeclState = new TokenDeclState(token); | 357 | TokenDeclState tokenDeclState = new TokenDeclState(token); |
@@ -401,25 +376,19 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
401 | continue; | 376 | continue; |
402 | } | 377 | } |
403 | 378 | ||
404 | /* | 379 | // Doesn't fit any of those forms, output message and skip to next statement. |
405 | * Doesn't fit any of those forms, output message and skip to next statement. | ||
406 | */ | ||
407 | ErrorMsg(token, "looking for var name, type, state or default, script-defined type declaration"); | 380 | ErrorMsg(token, "looking for var name, type, state or default, script-defined type declaration"); |
408 | token = SkipPastSemi(token); | 381 | token = SkipPastSemi(token); |
409 | continue; | 382 | continue; |
410 | } | 383 | } |
411 | 384 | ||
412 | /* | 385 | // Must have a default state to start in. |
413 | * Must have a default state to start in. | ||
414 | */ | ||
415 | if(!errors && (tokenScript.defaultState == null)) | 386 | if(!errors && (tokenScript.defaultState == null)) |
416 | { | 387 | { |
417 | ErrorMsg(tokenScript, "no default state defined"); | 388 | ErrorMsg(tokenScript, "no default state defined"); |
418 | } | 389 | } |
419 | 390 | ||
420 | /* | 391 | // If any error messages were written out, set return value to null. |
421 | * If any error messages were written out, set return value to null. | ||
422 | */ | ||
423 | if(errors) | 392 | if(errors) |
424 | tokenScript = null; | 393 | tokenScript = null; |
425 | } | 394 | } |
@@ -444,10 +413,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
444 | 413 | ||
445 | for(Token t = tokenBegin; !((t = t.nextToken) is TokenEnd);) | 414 | for(Token t = tokenBegin; !((t = t.nextToken) is TokenEnd);) |
446 | { | 415 | { |
447 | /* | 416 | // Keep track of nested definitions so we can link them up. |
448 | * Keep track of nested definitions so we can link them up. | 417 | // We also need to detect the end of class and interface definitions. |
449 | * We also need to detect the end of class and interface definitions. | ||
450 | */ | ||
451 | if(t is TokenKwBrcOpen) | 418 | if(t is TokenKwBrcOpen) |
452 | { | 419 | { |
453 | openBraceLevel++; | 420 | openBraceLevel++; |
@@ -468,11 +435,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
468 | continue; | 435 | continue; |
469 | } | 436 | } |
470 | 437 | ||
471 | /* | 438 | // Check for 'class' or 'interface'. |
472 | * Check for 'class' or 'interface'. | 439 | // They always define a new class or interface. |
473 | * They always define a new class or interface. | 440 | // They can contain nested script-defined type definitions. |
474 | * They can contain nested script-defined type definitions. | ||
475 | */ | ||
476 | if((t is TokenKwClass) || (t is TokenKwInterface)) | 441 | if((t is TokenKwClass) || (t is TokenKwInterface)) |
477 | { | 442 | { |
478 | Token kw = t; | 443 | Token kw = t; |
@@ -486,9 +451,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
486 | TokenName name = (TokenName)t; | 451 | TokenName name = (TokenName)t; |
487 | t = t.nextToken; | 452 | t = t.nextToken; |
488 | 453 | ||
489 | /* | 454 | // Malloc the script-defined type object. |
490 | * Malloc the script-defined type object. | ||
491 | */ | ||
492 | TokenDeclSDType decl; | 455 | TokenDeclSDType decl; |
493 | if(kw is TokenKwClass) | 456 | if(kw is TokenKwClass) |
494 | decl = new TokenDeclSDTypeClass(name, kw.prevToken is TokenKwPartial); | 457 | decl = new TokenDeclSDTypeClass(name, kw.prevToken is TokenKwPartial); |
@@ -496,56 +459,43 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
496 | decl = new TokenDeclSDTypeInterface(name); | 459 | decl = new TokenDeclSDTypeInterface(name); |
497 | decl.outerSDType = outerLevels.Peek(); | 460 | decl.outerSDType = outerLevels.Peek(); |
498 | 461 | ||
499 | /* | 462 | // Check for generic parameter list. |
500 | * Check for generic parameter list. | ||
501 | */ | ||
502 | if(!ParseGenProtoParamList(ref t, decl)) | 463 | if(!ParseGenProtoParamList(ref t, decl)) |
503 | continue; | 464 | continue; |
504 | 465 | ||
505 | /* | 466 | // Splice in a TokenDeclSDType token that replaces the keyword and the name tokens |
506 | * Splice in a TokenDeclSDType token that replaces the keyword and the name tokens | 467 | // and any generic parameters including the '<', ','s and '>'. |
507 | * and any generic parameters including the '<', ','s and '>'. | 468 | // kw = points to 'class' or 'interface' keyword. |
508 | * kw = points to 'class' or 'interface' keyword. | 469 | // t = points to just past last part of class name parsed, hopefully a ':' or '{'. |
509 | * t = points to just past last part of class name parsed, hopefully a ':' or '{'. | ||
510 | */ | ||
511 | decl.prevToken = decl.isPartial ? kw.prevToken.prevToken : kw.prevToken; | 470 | decl.prevToken = decl.isPartial ? kw.prevToken.prevToken : kw.prevToken; |
512 | decl.nextToken = t; | 471 | decl.nextToken = t; |
513 | decl.prevToken.nextToken = decl; | 472 | decl.prevToken.nextToken = decl; |
514 | decl.nextToken.prevToken = decl; | 473 | decl.nextToken.prevToken = decl; |
515 | 474 | ||
516 | /* | 475 | // Enter it in name lists so it can be seen by others. |
517 | * Enter it in name lists so it can be seen by others. | ||
518 | */ | ||
519 | Token partialNewBody = CatalogSDTypeDecl(decl); | 476 | Token partialNewBody = CatalogSDTypeDecl(decl); |
520 | 477 | ||
521 | /* | 478 | // Start inner type definitions. |
522 | * Start inner type definitions. | ||
523 | */ | ||
524 | braceLevels.Push(openBraceLevel); | 479 | braceLevels.Push(openBraceLevel); |
525 | outerLevels.Push(decl); | 480 | outerLevels.Push(decl); |
526 | 481 | ||
527 | /* | 482 | // Scan the body starting on for before the '{'. |
528 | * Scan the body starting on for before the '{'. | 483 | // |
529 | * | 484 | // If this body had an old partial merged into it, |
530 | * If this body had an old partial merged into it, | 485 | // resume scanning at the beginning of the new body, |
531 | * resume scanning at the beginning of the new body, | 486 | // ie, what used to be the first token after the '{' |
532 | * ie, what used to be the first token after the '{' | 487 | // before the old body was spliced in. |
533 | * before the old body was spliced in. | ||
534 | */ | ||
535 | if(partialNewBody != null) | 488 | if(partialNewBody != null) |
536 | { | 489 | { |
537 | 490 | // We have a partial that has had old partial body merged | |
538 | /* | 491 | // into new partial body. So resume scanning at the beginning |
539 | * We have a partial that has had old partial body merged | 492 | // of the new partial body so we don't get any duplicate scanning |
540 | * into new partial body. So resume scanning at the beginning | 493 | // of the old partial body. |
541 | * of the new partial body so we don't get any duplicate scanning | 494 | // |
542 | * of the old partial body. | 495 | // <decl> ... { <oldbody> <newbody> } |
543 | * | 496 | // ^- resume scanning here |
544 | * <decl> ... { <oldbody> <newbody> } | 497 | // but inc openBraceLevel because |
545 | * ^- resume scanning here | 498 | // we skipped scanning the '{' |
546 | * but inc openBraceLevel because | ||
547 | * we skipped scanning the '{' | ||
548 | */ | ||
549 | openBraceLevel++; | 499 | openBraceLevel++; |
550 | t = partialNewBody; | 500 | t = partialNewBody; |
551 | } | 501 | } |
@@ -553,23 +503,19 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
553 | continue; | 503 | continue; |
554 | } | 504 | } |
555 | 505 | ||
556 | /* | 506 | // Check for 'delegate'. |
557 | * Check for 'delegate'. | 507 | // It always defines a new delegate. |
558 | * It always defines a new delegate. | 508 | // Delegates never define nested types. |
559 | * Delegates never define nested types. | ||
560 | */ | ||
561 | if(t is TokenKwDelegate) | 509 | if(t is TokenKwDelegate) |
562 | { | 510 | { |
563 | Token kw = t; | 511 | Token kw = t; |
564 | t = t.nextToken; | 512 | t = t.nextToken; |
565 | 513 | ||
566 | /* | 514 | // Next thing might be an explicit return type or the delegate's name. |
567 | * Next thing might be an explicit return type or the delegate's name. | 515 | // If it's a type token, then it's the return type, simple enough. |
568 | * If it's a type token, then it's the return type, simple enough. | 516 | // But if it's a name token, it might be the name of some other script-defined type. |
569 | * But if it's a name token, it might be the name of some other script-defined type. | 517 | // The way to tell is that the delegate name is followed by a '(', whereas an |
570 | * The way to tell is that the delegate name is followed by a '(', whereas an | 518 | // explicit return type is followed by the delegate name. |
571 | * explicit return type is followed by the delegate name. | ||
572 | */ | ||
573 | Token retType = t; | 519 | Token retType = t; |
574 | TokenName delName = null; | 520 | TokenName delName = null; |
575 | Token u; | 521 | Token u; |
@@ -602,29 +548,21 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
602 | if(retType == delName) | 548 | if(retType == delName) |
603 | retType = null; | 549 | retType = null; |
604 | 550 | ||
605 | /* | 551 | // Malloc the script-defined type object. |
606 | * Malloc the script-defined type object. | ||
607 | */ | ||
608 | TokenDeclSDTypeDelegate decl = new TokenDeclSDTypeDelegate(delName); | 552 | TokenDeclSDTypeDelegate decl = new TokenDeclSDTypeDelegate(delName); |
609 | decl.outerSDType = outerLevels.Peek(); | 553 | decl.outerSDType = outerLevels.Peek(); |
610 | 554 | ||
611 | /* | 555 | // Check for generic parameter list. |
612 | * Check for generic parameter list. | ||
613 | */ | ||
614 | t = delName.nextToken; | 556 | t = delName.nextToken; |
615 | if(!ParseGenProtoParamList(ref t, decl)) | 557 | if(!ParseGenProtoParamList(ref t, decl)) |
616 | continue; | 558 | continue; |
617 | 559 | ||
618 | /* | 560 | // Enter it in name lists so it can be seen by others. |
619 | * Enter it in name lists so it can be seen by others. | ||
620 | */ | ||
621 | CatalogSDTypeDecl(decl); | 561 | CatalogSDTypeDecl(decl); |
622 | 562 | ||
623 | /* | 563 | // Splice in the token that replaces the 'delegate' keyword and the whole name |
624 | * Splice in the token that replaces the 'delegate' keyword and the whole name | 564 | // (including the '<' name ... '>' parts). The return type token(s), if any, |
625 | * (including the '<' name ... '>' parts). The return type token(s), if any, | 565 | // follow the splice token and come before the '('. |
626 | * follow the splice token and come before the '('. | ||
627 | */ | ||
628 | decl.prevToken = kw.prevToken; | 566 | decl.prevToken = kw.prevToken; |
629 | kw.prevToken.nextToken = decl; | 567 | kw.prevToken.nextToken = decl; |
630 | 568 | ||
@@ -641,10 +579,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
641 | t.prevToken = retType; | 579 | t.prevToken = retType; |
642 | } | 580 | } |
643 | 581 | ||
644 | /* | 582 | // Scan for terminating ';'. |
645 | * Scan for terminating ';'. | 583 | // There cannot be an intervening class, delegate, interfate, typedef, { or }. |
646 | * There cannot be an intervening class, delegate, interfate, typedef, { or }. | ||
647 | */ | ||
648 | for(t = decl; !(t is TokenKwSemi); t = u) | 584 | for(t = decl; !(t is TokenKwSemi); t = u) |
649 | { | 585 | { |
650 | u = t.nextToken; | 586 | u = t.nextToken; |
@@ -664,11 +600,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
664 | continue; | 600 | continue; |
665 | } | 601 | } |
666 | 602 | ||
667 | /* | 603 | // Check for 'typedef'. |
668 | * Check for 'typedef'. | 604 | // It always defines a new macro. |
669 | * It always defines a new macro. | 605 | // Typedefs never define nested types. |
670 | * Typedefs never define nested types. | ||
671 | */ | ||
672 | if(t is TokenKwTypedef) | 606 | if(t is TokenKwTypedef) |
673 | { | 607 | { |
674 | Token kw = t; | 608 | Token kw = t; |
@@ -683,37 +617,27 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
683 | TokenName tdName = (TokenName)t; | 617 | TokenName tdName = (TokenName)t; |
684 | t = t.nextToken; | 618 | t = t.nextToken; |
685 | 619 | ||
686 | /* | 620 | // Malloc the script-defined type object. |
687 | * Malloc the script-defined type object. | ||
688 | */ | ||
689 | TokenDeclSDTypeTypedef decl = new TokenDeclSDTypeTypedef(tdName); | 621 | TokenDeclSDTypeTypedef decl = new TokenDeclSDTypeTypedef(tdName); |
690 | decl.outerSDType = outerLevels.Peek(); | 622 | decl.outerSDType = outerLevels.Peek(); |
691 | 623 | ||
692 | /* | 624 | // Check for generic parameter list. |
693 | * Check for generic parameter list. | ||
694 | */ | ||
695 | if(!ParseGenProtoParamList(ref t, decl)) | 625 | if(!ParseGenProtoParamList(ref t, decl)) |
696 | continue; | 626 | continue; |
697 | 627 | ||
698 | /* | 628 | // Enter it in name lists so it can be seen by others. |
699 | * Enter it in name lists so it can be seen by others. | ||
700 | */ | ||
701 | CatalogSDTypeDecl(decl); | 629 | CatalogSDTypeDecl(decl); |
702 | numTypedefs++; | 630 | numTypedefs++; |
703 | 631 | ||
704 | /* | 632 | // Splice in the token that replaces the 'typedef' keyword and the whole name |
705 | * Splice in the token that replaces the 'typedef' keyword and the whole name | 633 | // (including the '<' name ... '>' parts). |
706 | * (including the '<' name ... '>' parts). | ||
707 | */ | ||
708 | decl.prevToken = kw.prevToken; | 634 | decl.prevToken = kw.prevToken; |
709 | kw.prevToken.nextToken = decl; | 635 | kw.prevToken.nextToken = decl; |
710 | decl.nextToken = t; | 636 | decl.nextToken = t; |
711 | t.prevToken = decl; | 637 | t.prevToken = decl; |
712 | 638 | ||
713 | /* | 639 | // Scan for terminating ';'. |
714 | * Scan for terminating ';'. | 640 | // There cannot be an intervening class, delegate, interfate, typedef, { or }. |
715 | * There cannot be an intervening class, delegate, interfate, typedef, { or }. | ||
716 | */ | ||
717 | Token u; | 641 | Token u; |
718 | for(t = decl; !(t is TokenKwSemi); t = u) | 642 | for(t = decl; !(t is TokenKwSemi); t = u) |
719 | { | 643 | { |
@@ -747,16 +671,12 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
747 | */ | 671 | */ |
748 | private bool ParseGenProtoParamList(ref Token t, TokenDeclSDType decl) | 672 | private bool ParseGenProtoParamList(ref Token t, TokenDeclSDType decl) |
749 | { | 673 | { |
750 | /* | 674 | // Maybe there aren't any generic parameters. |
751 | * Maybe there aren't any generic parameters. | 675 | // If so, leave decl.genParams = null. |
752 | * If so, leave decl.genParams = null. | ||
753 | */ | ||
754 | if(!(t is TokenKwCmpLT)) | 676 | if(!(t is TokenKwCmpLT)) |
755 | return true; | 677 | return true; |
756 | 678 | ||
757 | /* | 679 | // Build list of generic parameter names. |
758 | * Build list of generic parameter names. | ||
759 | */ | ||
760 | Dictionary<string, int> parms = new Dictionary<string, int>(); | 680 | Dictionary<string, int> parms = new Dictionary<string, int>(); |
761 | do | 681 | do |
762 | { | 682 | { |
@@ -813,17 +733,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
813 | if(!GenericParametersMatch(decl, dupDecl)) | 733 | if(!GenericParametersMatch(decl, dupDecl)) |
814 | ErrorMsg(decl, "all partial class generic parameters must match"); | 734 | ErrorMsg(decl, "all partial class generic parameters must match"); |
815 | 735 | ||
816 | /* | 736 | // Have new declaration be the cataloged one because body is going to get |
817 | * Have new declaration be the cataloged one because body is going to get | 737 | // snipped out of old declaration and pasted into new declaration. |
818 | * snipped out of old declaration and pasted into new declaration. | ||
819 | */ | ||
820 | tokenScript.sdSrcTypesRep(longName, decl); | 738 | tokenScript.sdSrcTypesRep(longName, decl); |
821 | if(decl.outerSDType != null) | 739 | if(decl.outerSDType != null) |
822 | decl.outerSDType.innerSDTypes[decl.shortName.val] = decl; | 740 | decl.outerSDType.innerSDTypes[decl.shortName.val] = decl; |
823 | 741 | ||
824 | /* | 742 | // Find old partial definition's opening brace. |
825 | * Find old partial definition's opening brace. | ||
826 | */ | ||
827 | Token dupBrcOpen; | 743 | Token dupBrcOpen; |
828 | for(dupBrcOpen = dupDecl; !(dupBrcOpen is TokenKwBrcOpen); dupBrcOpen = dupBrcOpen.nextToken) | 744 | for(dupBrcOpen = dupDecl; !(dupBrcOpen is TokenKwBrcOpen); dupBrcOpen = dupBrcOpen.nextToken) |
829 | { | 745 | { |
@@ -834,9 +750,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
834 | } | 750 | } |
835 | } | 751 | } |
836 | 752 | ||
837 | /* | 753 | // Find new partial definition's opening brace. |
838 | * Find new partial definition's opening brace. | ||
839 | */ | ||
840 | Token brcOpen; | 754 | Token brcOpen; |
841 | for(brcOpen = decl; !(brcOpen is TokenKwBrcOpen); brcOpen = brcOpen.nextToken) | 755 | for(brcOpen = decl; !(brcOpen is TokenKwBrcOpen); brcOpen = brcOpen.nextToken) |
842 | { | 756 | { |
@@ -848,25 +762,23 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
848 | } | 762 | } |
849 | Token body = brcOpen.nextToken; | 763 | Token body = brcOpen.nextToken; |
850 | 764 | ||
851 | /* | 765 | // Stick old partial definition's extends/implementeds list just |
852 | * Stick old partial definition's extends/implementeds list just | 766 | // in front of new partial definition's extends/implementeds list. |
853 | * in front of new partial definition's extends/implementeds list. | 767 | // |
854 | * | 768 | // class oldextimp { oldbody } ... |
855 | * class oldextimp { oldbody } ... | 769 | // dupDecl dupBrcOpen dupDecl.endToken |
856 | * dupDecl dupBrcOpen dupDecl.endToken | 770 | // |
857 | * | 771 | // class newextimp { newbody } ... |
858 | * class newextimp { newbody } ... | 772 | // decl brcOpen body decl.endToken |
859 | * decl brcOpen body decl.endToken | 773 | // |
860 | * | 774 | // becomes |
861 | * becomes | 775 | // |
862 | * | 776 | // class ... |
863 | * class ... | 777 | // dupDecl |
864 | * dupDecl | 778 | // dupDecl.endToken |
865 | * dupDecl.endToken | 779 | // |
866 | * | 780 | // class oldextimp newextimp { oldbody newbody } ... |
867 | * class oldextimp newextimp { oldbody newbody } ... | 781 | // decl brcOpen body decl.endToken |
868 | * decl brcOpen body decl.endToken | ||
869 | */ | ||
870 | if(dupBrcOpen != dupDecl.nextToken) | 782 | if(dupBrcOpen != dupDecl.nextToken) |
871 | { | 783 | { |
872 | dupBrcOpen.prevToken.nextToken = decl.nextToken; | 784 | dupBrcOpen.prevToken.nextToken = decl.nextToken; |
@@ -875,10 +787,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
875 | decl.nextToken = dupDecl.nextToken; | 787 | decl.nextToken = dupDecl.nextToken; |
876 | } | 788 | } |
877 | 789 | ||
878 | /* | 790 | // Stick old partial definition's body just |
879 | * Stick old partial definition's body just | 791 | // in front of new partial definition's body. |
880 | * in front of new partial definition's body. | ||
881 | */ | ||
882 | if(dupBrcOpen.nextToken != dupDecl.endToken) | 792 | if(dupBrcOpen.nextToken != dupDecl.endToken) |
883 | { | 793 | { |
884 | dupBrcOpen.nextToken.prevToken = brcOpen; | 794 | dupBrcOpen.nextToken.prevToken = brcOpen; |
@@ -887,10 +797,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
887 | brcOpen.nextToken = dupBrcOpen.nextToken; | 797 | brcOpen.nextToken = dupBrcOpen.nextToken; |
888 | } | 798 | } |
889 | 799 | ||
890 | /* | 800 | // Null out old definition's extends/implementeds list and body |
891 | * Null out old definition's extends/implementeds list and body | 801 | // by having the declaration token be the only thing left. |
892 | * by having the declaration token be the only thing left. | ||
893 | */ | ||
894 | dupDecl.nextToken = dupDecl.endToken.nextToken; | 802 | dupDecl.nextToken = dupDecl.endToken.nextToken; |
895 | dupDecl.nextToken.prevToken = dupDecl; | 803 | dupDecl.nextToken.prevToken = dupDecl; |
896 | dupDecl.endToken = dupDecl; | 804 | dupDecl.endToken = dupDecl; |
@@ -946,41 +854,34 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
946 | 854 | ||
947 | for(Token t = tokenBegin; !((t = t.nextToken) is TokenEnd);) | 855 | for(Token t = tokenBegin; !((t = t.nextToken) is TokenEnd);) |
948 | { | 856 | { |
949 | 857 | // Maybe it's time to pop out of an outer class definition. | |
950 | /* | ||
951 | * Maybe it's time to pop out of an outer class definition. | ||
952 | */ | ||
953 | if((outerSDType != null) && (outerSDType.endToken == t)) | 858 | if((outerSDType != null) && (outerSDType.endToken == t)) |
954 | { | 859 | { |
955 | outerSDType = outerSDType.outerSDType; | 860 | outerSDType = outerSDType.outerSDType; |
956 | continue; | 861 | continue; |
957 | } | 862 | } |
958 | 863 | ||
959 | /* | 864 | // Skip completely over any script-defined generic prototypes. |
960 | * Skip completely over any script-defined generic prototypes. | 865 | // We only need to process their instantiations which are non- |
961 | * We only need to process their instantiations which are non- | 866 | // generic versions of the generics. |
962 | * generic versions of the generics. | ||
963 | */ | ||
964 | if((t is TokenDeclSDType) && (((TokenDeclSDType)t).genParams != null)) | 867 | if((t is TokenDeclSDType) && (((TokenDeclSDType)t).genParams != null)) |
965 | { | 868 | { |
966 | t = ((TokenDeclSDType)t).endToken; | 869 | t = ((TokenDeclSDType)t).endToken; |
967 | continue; | 870 | continue; |
968 | } | 871 | } |
969 | 872 | ||
970 | /* | 873 | // Check for beginning of non-generic script-defined type definitions. |
971 | * Check for beginning of non-generic script-defined type definitions. | 874 | // They can have nested definitions in their innerSDTypes[] that match |
972 | * They can have nested definitions in their innerSDTypes[] that match | 875 | // name tokens, so add them to the stack. |
973 | * name tokens, so add them to the stack. | 876 | // |
974 | * | 877 | // But just ignore any preliminary partial definitions as they have had |
975 | * But just ignore any preliminary partial definitions as they have had | 878 | // their entire contents spliced out and spliced into a subsequent partial |
976 | * their entire contents spliced out and spliced into a subsequent partial | 879 | // definition. So if we originally had: |
977 | * definition. So if we originally had: | 880 | // partial class Abc { public intenger one; } |
978 | * partial class Abc { public intenger one; } | 881 | // partial class Abc { public intenger two; } |
979 | * partial class Abc { public intenger two; } | 882 | // We now have: |
980 | * We now have: | 883 | // partial_class_Abc <== if we are here, just ignore the partial_class_Abc token |
981 | * partial_class_Abc <== if we are here, just ignore the partial_class_Abc token | 884 | // partial_class_Abc { public intenger one; public intenger two; } |
982 | * partial_class_Abc { public intenger one; public intenger two; } | ||
983 | */ | ||
984 | if(t is TokenDeclSDType) | 885 | if(t is TokenDeclSDType) |
985 | { | 886 | { |
986 | if(((TokenDeclSDType)t).endToken != t) | 887 | if(((TokenDeclSDType)t).endToken != t) |
@@ -989,22 +890,18 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
989 | continue; | 890 | continue; |
990 | } | 891 | } |
991 | 892 | ||
992 | /* | 893 | // For names not preceded by a '.', scan the script-defined type definition |
993 | * For names not preceded by a '.', scan the script-defined type definition | 894 | // stack for that name. Splice the name out and replace with equivalent token. |
994 | * stack for that name. Splice the name out and replace with equivalent token. | ||
995 | */ | ||
996 | if((t is TokenName) && !(t.prevToken is TokenKwDot)) | 895 | if((t is TokenName) && !(t.prevToken is TokenKwDot)) |
997 | t = TrySpliceTypeRef(t, outerSDType, ref repeat, noTypes); | 896 | t = TrySpliceTypeRef(t, outerSDType, ref repeat, noTypes); |
998 | 897 | ||
999 | /* | 898 | // This handles types such as integer[,][], List<string>[], etc. |
1000 | * This handles types such as integer[,][], List<string>[], etc. | 899 | // They are an instantiation of an internally generated type of the same name, brackets and all. |
1001 | * They are an instantiation of an internally generated type of the same name, brackets and all. | 900 | // Note that to malloc an array, use something like 'new float[,][](3,5)', not 'new float[3,5][]'. |
1002 | * Note that to malloc an array, use something like 'new float[,][](3,5)', not 'new float[3,5][]'. | 901 | // |
1003 | * | 902 | // Note that we must not get confused by $idxprop property declarations such as: |
1004 | * Note that we must not get confused by $idxprop property declarations such as: | 903 | // float [string kee] { get { ... } } |
1005 | * float [string kee] { get { ... } } | 904 | // ... and try to convert 'float' '[' to an array type. |
1006 | * ... and try to convert 'float' '[' to an array type. | ||
1007 | */ | ||
1008 | if((t is TokenType) && (t.nextToken is TokenKwBrkOpen)) | 905 | if((t is TokenType) && (t.nextToken is TokenKwBrkOpen)) |
1009 | { | 906 | { |
1010 | if((t.nextToken.nextToken is TokenKwBrkClose) || | 907 | if((t.nextToken.nextToken is TokenKwBrkClose) || |
@@ -1015,19 +912,15 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1015 | } | 912 | } |
1016 | } | 913 | } |
1017 | 914 | ||
1018 | /* | 915 | // If we instantiated a generic, loop back to process its contents |
1019 | * If we instantiated a generic, loop back to process its contents | 916 | // just as if the source code had the instantiated code to begin with. |
1020 | * just as if the source code had the instantiated code to begin with. | 917 | // Also repeat if we found a non-type inside the <> of a generic reference |
1021 | * Also repeat if we found a non-type inside the <> of a generic reference | 918 | // provided we have made at least one name->type substitution. |
1022 | * provided we have made at least one name->type substitution. | ||
1023 | */ | ||
1024 | } while(((repeat & REPEAT_INSTGEN) != 0) || | 919 | } while(((repeat & REPEAT_INSTGEN) != 0) || |
1025 | ((repeat & (REPEAT_NOTYPE | REPEAT_SUBST)) == (REPEAT_NOTYPE | REPEAT_SUBST))); | 920 | ((repeat & (REPEAT_NOTYPE | REPEAT_SUBST)) == (REPEAT_NOTYPE | REPEAT_SUBST))); |
1026 | 921 | ||
1027 | /* | 922 | // These are places where we required a type be present, |
1028 | * These are places where we required a type be present, | 923 | // eg, a generic type argument or the body of a typedef. |
1029 | * eg, a generic type argument or the body of a typedef. | ||
1030 | */ | ||
1031 | foreach(Token t in noTypes) | 924 | foreach(Token t in noTypes) |
1032 | ErrorMsg(t, "looking for type"); | 925 | ErrorMsg(t, "looking for type"); |
1033 | } | 926 | } |
@@ -1048,11 +941,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1048 | Token start = t; | 941 | Token start = t; |
1049 | string tnamestr = ((TokenName)t).val; | 942 | string tnamestr = ((TokenName)t).val; |
1050 | 943 | ||
1051 | /* | 944 | // Look for the name as a type declared by outerSDType or anything |
1052 | * Look for the name as a type declared by outerSDType or anything | 945 | // even farther out than that. If not found, simply return |
1053 | * even farther out than that. If not found, simply return | 946 | // without updating t, meaning that t isn't the name of a type. |
1054 | * without updating t, meaning that t isn't the name of a type. | ||
1055 | */ | ||
1056 | TokenDeclSDType decl = null; | 947 | TokenDeclSDType decl = null; |
1057 | while(outerSDType != null) | 948 | while(outerSDType != null) |
1058 | { | 949 | { |
@@ -1066,10 +957,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1066 | TokenDeclSDType instdecl; | 957 | TokenDeclSDType instdecl; |
1067 | while(true) | 958 | while(true) |
1068 | { | 959 | { |
1069 | 960 | // If it is a generic type, it must be followed by instantiation arguments. | |
1070 | /* | ||
1071 | * If it is a generic type, it must be followed by instantiation arguments. | ||
1072 | */ | ||
1073 | instdecl = decl; | 961 | instdecl = decl; |
1074 | if(decl.genParams != null) | 962 | if(decl.genParams != null) |
1075 | { | 963 | { |
@@ -1134,12 +1022,10 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1134 | tokenScript.sdSrcTypesTryGetValue(tnamestr, out instdecl); | 1022 | tokenScript.sdSrcTypesTryGetValue(tnamestr, out instdecl); |
1135 | } | 1023 | } |
1136 | 1024 | ||
1137 | /* | 1025 | // Couldn't find 'List<string>' but found 'List' and we have genArgs = 'string'. |
1138 | * Couldn't find 'List<string>' but found 'List' and we have genArgs = 'string'. | 1026 | // Instantiate the generic to create 'List<string>'. This splices the definition |
1139 | * Instantiate the generic to create 'List<string>'. This splices the definition | 1027 | // of 'List<string>' into the source token stream just as if it had been there all |
1140 | * of 'List<string>' into the source token stream just as if it had been there all | 1028 | // along. We have to then repeat the scan to process the instance's contents. |
1141 | * along. We have to then repeat the scan to process the instance's contents. | ||
1142 | */ | ||
1143 | if(instdecl == null) | 1029 | if(instdecl == null) |
1144 | { | 1030 | { |
1145 | instdecl = decl.InstantiateGeneric(tnamestr, genArgs, this); | 1031 | instdecl = decl.InstantiateGeneric(tnamestr, genArgs, this); |
@@ -1148,9 +1034,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1148 | } | 1034 | } |
1149 | } | 1035 | } |
1150 | 1036 | ||
1151 | /* | 1037 | // Maybe caller wants a subtype by putting a '.' following all that. |
1152 | * Maybe caller wants a subtype by putting a '.' following all that. | ||
1153 | */ | ||
1154 | if(!(t.nextToken is TokenKwDot)) | 1038 | if(!(t.nextToken is TokenKwDot)) |
1155 | break; | 1039 | break; |
1156 | if(!(t.nextToken.nextToken is TokenName)) | 1040 | if(!(t.nextToken.nextToken is TokenName)) |
@@ -1162,14 +1046,12 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1162 | outerSDType = instdecl; | 1046 | outerSDType = instdecl; |
1163 | } | 1047 | } |
1164 | 1048 | ||
1165 | /* | 1049 | // Create a reference in the source to the definition |
1166 | * Create a reference in the source to the definition | 1050 | // that encapsulates the long dotted type name given in |
1167 | * that encapsulates the long dotted type name given in | 1051 | // the source, and replace the long dotted type name in |
1168 | * the source, and replace the long dotted type name in | 1052 | // the source with the reference token, eg, replace |
1169 | * the source with the reference token, eg, replace | 1053 | // 'Dictionary' '<' 'string' ',' 'integer' '>' '.' 'ValueList' |
1170 | * 'Dictionary' '<' 'string' ',' 'integer' '>' '.' 'ValueList' | 1054 | // with 'Dictionary<string,integer>.ValueList'. |
1171 | * with 'Dictionary<string,integer>.ValueList'. | ||
1172 | */ | ||
1173 | TokenType refer = instdecl.MakeRefToken(start); | 1055 | TokenType refer = instdecl.MakeRefToken(start); |
1174 | if(refer == null) | 1056 | if(refer == null) |
1175 | { | 1057 | { |
@@ -1203,11 +1085,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1203 | 1085 | ||
1204 | Stack<int> ranks = new Stack<int>(); | 1086 | Stack<int> ranks = new Stack<int>(); |
1205 | 1087 | ||
1206 | /* | 1088 | // When script specifies 'float[,][]' it means a two-dimensional matrix |
1207 | * When script specifies 'float[,][]' it means a two-dimensional matrix | 1089 | // that points to one-dimensional vectors of floats. So we would push |
1208 | * that points to one-dimensional vectors of floats. So we would push | 1090 | // a 2 then a 1 in this parsing code... |
1209 | * a 2 then a 1 in this parsing code... | ||
1210 | */ | ||
1211 | do | 1091 | do |
1212 | { | 1092 | { |
1213 | t = t.nextToken; // point at '[' | 1093 | t = t.nextToken; // point at '[' |
@@ -1225,14 +1105,12 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1225 | ranks.Push(rank); | 1105 | ranks.Push(rank); |
1226 | } while(t.nextToken is TokenKwBrkOpen); | 1106 | } while(t.nextToken is TokenKwBrkOpen); |
1227 | 1107 | ||
1228 | /* | 1108 | // Now we build the types in reverse order. For the example above we will: |
1229 | * Now we build the types in reverse order. For the example above we will: | 1109 | // first, create a type that is a one-dimensional vector of floats, float[] |
1230 | * first, create a type that is a one-dimensional vector of floats, float[] | 1110 | // second, create a type that is a two-dimensional matrix of that. |
1231 | * second, create a type that is a two-dimensional matrix of that. | 1111 | // This keeps declaration and referencing similar, eg, |
1232 | * This keeps declaration and referencing similar, eg, | 1112 | // float[,][] jag = new float[,][] (3,4); |
1233 | * float[,][] jag = new float[,][] (3,4); | 1113 | // jag[i,j][k] ... is used to access the elements |
1234 | * jag[i,j][k] ... is used to access the elements | ||
1235 | */ | ||
1236 | do | 1114 | do |
1237 | { | 1115 | { |
1238 | int rank = ranks.Pop(); | 1116 | int rank = ranks.Pop(); |
@@ -1240,17 +1118,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1240 | ofType = decl.MakeRefToken(ofType); | 1118 | ofType = decl.MakeRefToken(ofType); |
1241 | } while(ranks.Count > 0); | 1119 | } while(ranks.Count > 0); |
1242 | 1120 | ||
1243 | /* | 1121 | // Finally splice in the resultant array type to replace the original tokens. |
1244 | * Finally splice in the resultant array type to replace the original tokens. | ||
1245 | */ | ||
1246 | ofType.prevToken = start.prevToken; | 1122 | ofType.prevToken = start.prevToken; |
1247 | ofType.nextToken = t.nextToken; | 1123 | ofType.nextToken = t.nextToken; |
1248 | ofType.prevToken.nextToken = ofType; | 1124 | ofType.prevToken.nextToken = ofType; |
1249 | ofType.nextToken.prevToken = ofType; | 1125 | ofType.nextToken.prevToken = ofType; |
1250 | 1126 | ||
1251 | /* | 1127 | // Resume parsing just after the spliced-in array type token. |
1252 | * Resume parsing just after the spliced-in array type token. | ||
1253 | */ | ||
1254 | return ofType; | 1128 | return ofType; |
1255 | } | 1129 | } |
1256 | 1130 | ||
@@ -1262,13 +1136,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1262 | */ | 1136 | */ |
1263 | private TokenDeclSDType InstantiateFixedArray(int rank, TokenType ofType, Token tokenBegin, ref uint repeat) | 1137 | private TokenDeclSDType InstantiateFixedArray(int rank, TokenType ofType, Token tokenBegin, ref uint repeat) |
1264 | { | 1138 | { |
1265 | /* | 1139 | // Create the array type's name. |
1266 | * Create the array type's name. | 1140 | // If starting with a non-array type, just append the rank to it, eg, float + rank=1 -> float[] |
1267 | * If starting with a non-array type, just append the rank to it, eg, float + rank=1 -> float[] | 1141 | // If starting with an array type, slip this rank in front of existing array, eg, float[] + rank=2 -> float[,][]. |
1268 | * If starting with an array type, slip this rank in front of existing array, eg, float[] + rank=2 -> float[,][]. | 1142 | // This makes it consistent with what the script-writer sees for both a type specification and when |
1269 | * This makes it consistent with what the script-writer sees for both a type specification and when | 1143 | // referencing elements in a jagged array. |
1270 | * referencing elements in a jagged array. | ||
1271 | */ | ||
1272 | string name = ofType.ToString(); | 1144 | string name = ofType.ToString(); |
1273 | StringBuilder sb = new StringBuilder(name); | 1145 | StringBuilder sb = new StringBuilder(name); |
1274 | int ix = name.IndexOf('['); | 1146 | int ix = name.IndexOf('['); |
@@ -1293,12 +1165,10 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1293 | if(ofType is TokenTypeInt) | 1165 | if(ofType is TokenTypeInt) |
1294 | suffix = 'I'; | 1166 | suffix = 'I'; |
1295 | 1167 | ||
1296 | /* | 1168 | // Don't already have one, create a new skeleton struct. |
1297 | * Don't already have one, create a new skeleton struct. | 1169 | // Splice in a definition for the class at beginning of source file. |
1298 | * Splice in a definition for the class at beginning of source file. | 1170 | // |
1299 | * | 1171 | // class <arraytypename> { |
1300 | * class <arraytypename> { | ||
1301 | */ | ||
1302 | fa = new TokenDeclSDTypeClass(new TokenName(tokenScript, name), false); | 1172 | fa = new TokenDeclSDTypeClass(new TokenName(tokenScript, name), false); |
1303 | CatalogSDTypeDecl(fa); | 1173 | CatalogSDTypeDecl(fa); |
1304 | repeat |= REPEAT_INSTGEN; | 1174 | repeat |= REPEAT_INSTGEN; |
@@ -1308,12 +1178,10 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1308 | Token t = SpliceAfter(tokenBegin, fa); | 1178 | Token t = SpliceAfter(tokenBegin, fa); |
1309 | t = SpliceAfter(t, new TokenKwBrcOpen(t)); | 1179 | t = SpliceAfter(t, new TokenKwBrcOpen(t)); |
1310 | 1180 | ||
1311 | /* | 1181 | // public integer len0; |
1312 | * public integer len0; | 1182 | // public integer len1; |
1313 | * public integer len1; | 1183 | // ... |
1314 | * ... | 1184 | // public object obj; |
1315 | * public object obj; | ||
1316 | */ | ||
1317 | for(int i = 0; i < rank; i++) | 1185 | for(int i = 0; i < rank; i++) |
1318 | { | 1186 | { |
1319 | t = SpliceAfter(t, new TokenKwPublic(t)); | 1187 | t = SpliceAfter(t, new TokenKwPublic(t)); |
@@ -1327,14 +1195,12 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1327 | t = SpliceAfter(t, new TokenName(t, "obj")); | 1195 | t = SpliceAfter(t, new TokenName(t, "obj")); |
1328 | t = SpliceAfter(t, new TokenKwSemi(t)); | 1196 | t = SpliceAfter(t, new TokenKwSemi(t)); |
1329 | 1197 | ||
1330 | /* | 1198 | // public constructor (integer len0, integer len1, ...) { |
1331 | * public constructor (integer len0, integer len1, ...) { | 1199 | // this.len0 = len0; |
1332 | * this.len0 = len0; | 1200 | // this.len1 = len1; |
1333 | * this.len1 = len1; | 1201 | // ... |
1334 | * ... | 1202 | // this.obj = xmrFixedArrayAlloc<suffix> (len0 * len1 * ...); |
1335 | * this.obj = xmrFixedArrayAlloc<suffix> (len0 * len1 * ...); | 1203 | // } |
1336 | * } | ||
1337 | */ | ||
1338 | t = SpliceAfter(t, new TokenKwPublic(t)); | 1204 | t = SpliceAfter(t, new TokenKwPublic(t)); |
1339 | t = SpliceAfter(t, new TokenKwConstructor(t)); | 1205 | t = SpliceAfter(t, new TokenKwConstructor(t)); |
1340 | t = SpliceAfter(t, new TokenKwParOpen(t)); | 1206 | t = SpliceAfter(t, new TokenKwParOpen(t)); |
@@ -1374,11 +1240,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1374 | t = SpliceAfter(t, new TokenKwSemi(t)); | 1240 | t = SpliceAfter(t, new TokenKwSemi(t)); |
1375 | t = SpliceAfter(t, new TokenKwBrcClose(t)); | 1241 | t = SpliceAfter(t, new TokenKwBrcClose(t)); |
1376 | 1242 | ||
1377 | /* | 1243 | // public integer Length { get { |
1378 | * public integer Length { get { | 1244 | // return this.len0 * this.len1 * ... ; |
1379 | * return this.len0 * this.len1 * ... ; | 1245 | // } } |
1380 | * } } | ||
1381 | */ | ||
1382 | t = SpliceAfter(t, new TokenKwPublic(t)); | 1246 | t = SpliceAfter(t, new TokenKwPublic(t)); |
1383 | t = SpliceAfter(t, new TokenTypeInt(t)); | 1247 | t = SpliceAfter(t, new TokenTypeInt(t)); |
1384 | t = SpliceAfter(t, new TokenName(t, "Length")); | 1248 | t = SpliceAfter(t, new TokenName(t, "Length")); |
@@ -1400,16 +1264,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1400 | t = SpliceAfter(t, new TokenKwBrcClose(t)); | 1264 | t = SpliceAfter(t, new TokenKwBrcClose(t)); |
1401 | t = SpliceAfter(t, new TokenKwBrcClose(t)); | 1265 | t = SpliceAfter(t, new TokenKwBrcClose(t)); |
1402 | 1266 | ||
1403 | /* | 1267 | // public integer Length (integer dim) { |
1404 | * public integer Length (integer dim) { | 1268 | // switch (dim) { |
1405 | * switch (dim) { | 1269 | // case 0: return this.len0; |
1406 | * case 0: return this.len0; | 1270 | // case 1: return this.len1; |
1407 | * case 1: return this.len1; | 1271 | // ... |
1408 | * ... | 1272 | // } |
1409 | * } | 1273 | // return 0; |
1410 | * return 0; | 1274 | // } |
1411 | * } | ||
1412 | */ | ||
1413 | t = SpliceAfter(t, new TokenKwPublic(t)); | 1275 | t = SpliceAfter(t, new TokenKwPublic(t)); |
1414 | t = SpliceAfter(t, new TokenTypeInt(t)); | 1276 | t = SpliceAfter(t, new TokenTypeInt(t)); |
1415 | t = SpliceAfter(t, new TokenName(t, "Length")); | 1277 | t = SpliceAfter(t, new TokenName(t, "Length")); |
@@ -1443,15 +1305,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1443 | t = SpliceAfter(t, new TokenKwSemi(t)); | 1305 | t = SpliceAfter(t, new TokenKwSemi(t)); |
1444 | t = SpliceAfter(t, new TokenKwBrcClose(t)); | 1306 | t = SpliceAfter(t, new TokenKwBrcClose(t)); |
1445 | 1307 | ||
1446 | /* | 1308 | // public integer Index (integer idx0, integet idx1, ...) { |
1447 | * public integer Index (integer idx0, integet idx1, ...) { | 1309 | // integer idx = idx0; |
1448 | * integer idx = idx0; | 1310 | // idx *= this.len1; idx += idx1; |
1449 | * idx *= this.len1; idx += idx1; | 1311 | // idx *= this.len2; idx += idx2; |
1450 | * idx *= this.len2; idx += idx2; | 1312 | // ... |
1451 | * ... | 1313 | // return idx; |
1452 | * return idx; | 1314 | // } |
1453 | * } | ||
1454 | */ | ||
1455 | t = SpliceAfter(t, new TokenKwPublic(t)); | 1315 | t = SpliceAfter(t, new TokenKwPublic(t)); |
1456 | t = SpliceAfter(t, new TokenTypeInt(t)); | 1316 | t = SpliceAfter(t, new TokenTypeInt(t)); |
1457 | t = SpliceAfter(t, new TokenName(t, "Index")); | 1317 | t = SpliceAfter(t, new TokenName(t, "Index")); |
@@ -1491,15 +1351,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1491 | t = SpliceAfter(t, new TokenKwSemi(t)); | 1351 | t = SpliceAfter(t, new TokenKwSemi(t)); |
1492 | t = SpliceAfter(t, new TokenKwBrcClose(t)); | 1352 | t = SpliceAfter(t, new TokenKwBrcClose(t)); |
1493 | 1353 | ||
1494 | /* | 1354 | // public <oftype> Get (integer idx0, integet idx1, ...) { |
1495 | * public <oftype> Get (integer idx0, integet idx1, ...) { | 1355 | // integer idx = idx0; |
1496 | * integer idx = idx0; | 1356 | // idx *= this.len1; idx += idx1; |
1497 | * idx *= this.len1; idx += idx1; | 1357 | // idx *= this.len2; idx += idx2; |
1498 | * idx *= this.len2; idx += idx2; | 1358 | // ... |
1499 | * ... | 1359 | // return (<oftype>) xmrFixedArrayGet<suffix> (this.obj, idx); |
1500 | * return (<oftype>) xmrFixedArrayGet<suffix> (this.obj, idx); | 1360 | // } |
1501 | * } | ||
1502 | */ | ||
1503 | t = SpliceAfter(t, new TokenKwPublic(t)); | 1361 | t = SpliceAfter(t, new TokenKwPublic(t)); |
1504 | t = SpliceAfter(t, ofType.CopyToken(t)); | 1362 | t = SpliceAfter(t, ofType.CopyToken(t)); |
1505 | t = SpliceAfter(t, new TokenName(t, "Get")); | 1363 | t = SpliceAfter(t, new TokenName(t, "Get")); |
@@ -1552,15 +1410,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1552 | t = SpliceAfter(t, new TokenKwSemi(t)); | 1410 | t = SpliceAfter(t, new TokenKwSemi(t)); |
1553 | t = SpliceAfter(t, new TokenKwBrcClose(t)); | 1411 | t = SpliceAfter(t, new TokenKwBrcClose(t)); |
1554 | 1412 | ||
1555 | /* | 1413 | // public void Set (integer idx0, integer idx1, ..., <oftype> val) { |
1556 | * public void Set (integer idx0, integer idx1, ..., <oftype> val) { | 1414 | // integer idx = idx0; |
1557 | * integer idx = idx0; | 1415 | // idx *= this.len1; idx += idx1; |
1558 | * idx *= this.len1; idx += idx1; | 1416 | // idx *= this.len2; idx += idx2; |
1559 | * idx *= this.len2; idx += idx2; | 1417 | // ... |
1560 | * ... | 1418 | // xmrFixedArraySet<suffix> (this.obj, idx, val); |
1561 | * xmrFixedArraySet<suffix> (this.obj, idx, val); | 1419 | // } |
1562 | * } | ||
1563 | */ | ||
1564 | t = SpliceAfter(t, new TokenKwPublic(t)); | 1420 | t = SpliceAfter(t, new TokenKwPublic(t)); |
1565 | t = SpliceAfter(t, new TokenTypeVoid(t)); | 1421 | t = SpliceAfter(t, new TokenTypeVoid(t)); |
1566 | t = SpliceAfter(t, new TokenName(t, "Set")); | 1422 | t = SpliceAfter(t, new TokenName(t, "Set")); |
@@ -1764,10 +1620,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1764 | tokdeclcl.members.thisClass = tokdeclcl; | 1620 | tokdeclcl.members.thisClass = tokdeclcl; |
1765 | tokenScript.PushVarFrame(tokdeclcl.members); | 1621 | tokenScript.PushVarFrame(tokdeclcl.members); |
1766 | 1622 | ||
1767 | /* | 1623 | // Create a function $instfieldnit to hold all explicit |
1768 | * Create a function $instfieldnit to hold all explicit | 1624 | // instance field initializations. |
1769 | * instance field initializations. | ||
1770 | */ | ||
1771 | TokenDeclVar ifiFunc = new TokenDeclVar(tokdeclcl, null, tokenScript); | 1625 | TokenDeclVar ifiFunc = new TokenDeclVar(tokdeclcl, null, tokenScript); |
1772 | ifiFunc.name = new TokenName(ifiFunc, "$instfieldinit"); | 1626 | ifiFunc.name = new TokenName(ifiFunc, "$instfieldinit"); |
1773 | ifiFunc.retType = new TokenTypeVoid(ifiFunc); | 1627 | ifiFunc.retType = new TokenTypeVoid(ifiFunc); |
@@ -1780,10 +1634,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1780 | tokdeclcl.instFieldInit = ifiFunc; | 1634 | tokdeclcl.instFieldInit = ifiFunc; |
1781 | tokenScript.AddVarEntry(ifiFunc); | 1635 | tokenScript.AddVarEntry(ifiFunc); |
1782 | 1636 | ||
1783 | /* | 1637 | // Create a function $staticfieldnit to hold all explicit |
1784 | * Create a function $staticfieldnit to hold all explicit | 1638 | // static field initializations. |
1785 | * static field initializations. | ||
1786 | */ | ||
1787 | TokenDeclVar sfiFunc = new TokenDeclVar(tokdeclcl, null, tokenScript); | 1639 | TokenDeclVar sfiFunc = new TokenDeclVar(tokdeclcl, null, tokenScript); |
1788 | sfiFunc.name = new TokenName(sfiFunc, "$staticfieldinit"); | 1640 | sfiFunc.name = new TokenName(sfiFunc, "$staticfieldinit"); |
1789 | sfiFunc.retType = new TokenTypeVoid(sfiFunc); | 1641 | sfiFunc.retType = new TokenTypeVoid(sfiFunc); |
@@ -1805,25 +1657,19 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1805 | continue; | 1657 | continue; |
1806 | } | 1658 | } |
1807 | 1659 | ||
1808 | /* | 1660 | // Check for all qualifiers. |
1809 | * Check for all qualifiers. | 1661 | // typedef has an implied 'public' qualifier. |
1810 | * typedef has an implied 'public' qualifier. | ||
1811 | */ | ||
1812 | flags = SDT_PUBLIC; | 1662 | flags = SDT_PUBLIC; |
1813 | if(!(token is TokenDeclSDTypeTypedef)) | 1663 | if(!(token is TokenDeclSDTypeTypedef)) |
1814 | { | 1664 | { |
1815 | flags = ParseQualifierFlags(ref token); | 1665 | flags = ParseQualifierFlags(ref token); |
1816 | } | 1666 | } |
1817 | 1667 | ||
1818 | /* | 1668 | // Parse nested script-defined type definitions. |
1819 | * Parse nested script-defined type definitions. | ||
1820 | */ | ||
1821 | if(ParseDeclSDTypes(ref token, tokdeclcl, flags)) | 1669 | if(ParseDeclSDTypes(ref token, tokdeclcl, flags)) |
1822 | continue; | 1670 | continue; |
1823 | 1671 | ||
1824 | /* | 1672 | // constant <name> = <rval> ; |
1825 | * constant <name> = <rval> ; | ||
1826 | */ | ||
1827 | if(token is TokenKwConst) | 1673 | if(token is TokenKwConst) |
1828 | { | 1674 | { |
1829 | if((flags & (SDT_ABSTRACT | SDT_NEW | SDT_OVERRIDE | SDT_VIRTUAL)) != 0) | 1675 | if((flags & (SDT_ABSTRACT | SDT_NEW | SDT_OVERRIDE | SDT_VIRTUAL)) != 0) |
@@ -1839,10 +1685,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1839 | continue; | 1685 | continue; |
1840 | } | 1686 | } |
1841 | 1687 | ||
1842 | /* | 1688 | // <type> <name> ; |
1843 | * <type> <name> ; | 1689 | // <type> <name> = <rval> ; |
1844 | * <type> <name> = <rval> ; | ||
1845 | */ | ||
1846 | if((token is TokenType) && | 1690 | if((token is TokenType) && |
1847 | (token.nextToken is TokenName) && | 1691 | (token.nextToken is TokenName) && |
1848 | ((token.nextToken.nextToken is TokenKwSemi) || | 1692 | ((token.nextToken.nextToken is TokenKwSemi) || |
@@ -1877,10 +1721,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1877 | continue; | 1721 | continue; |
1878 | } | 1722 | } |
1879 | 1723 | ||
1880 | /* | 1724 | // <type> <name> [ : <implintfs> ] { [ get { <body> } ] [ set { <body> } ] } |
1881 | * <type> <name> [ : <implintfs> ] { [ get { <body> } ] [ set { <body> } ] } | 1725 | // <type> '[' ... ']' [ : <implintfs> ] { [ get { <body> } ] [ set { <body> } ] } |
1882 | * <type> '[' ... ']' [ : <implintfs> ] { [ get { <body> } ] [ set { <body> } ] } | ||
1883 | */ | ||
1884 | bool prop = (token is TokenType) && | 1726 | bool prop = (token is TokenType) && |
1885 | (token.nextToken is TokenName) && | 1727 | (token.nextToken is TokenName) && |
1886 | (token.nextToken.nextToken is TokenKwBrcOpen || | 1728 | (token.nextToken.nextToken is TokenKwBrcOpen || |
@@ -1907,9 +1749,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1907 | continue; | 1749 | continue; |
1908 | } | 1750 | } |
1909 | 1751 | ||
1910 | /* | 1752 | // 'constructor' '(' arglist ')' [ ':' [ 'base' ] '(' baseconstructorcall ')' ] '{' body '}' |
1911 | * 'constructor' '(' arglist ')' [ ':' [ 'base' ] '(' baseconstructorcall ')' ] '{' body '}' | ||
1912 | */ | ||
1913 | if(token is TokenKwConstructor) | 1753 | if(token is TokenKwConstructor) |
1914 | { | 1754 | { |
1915 | ParseSDTClassCtorDecl(ref token, flags, tokdeclcl); | 1755 | ParseSDTClassCtorDecl(ref token, flags, tokdeclcl); |
@@ -1917,36 +1757,28 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1917 | continue; | 1757 | continue; |
1918 | } | 1758 | } |
1919 | 1759 | ||
1920 | /* | 1760 | // <type> <name> <funcargs> <funcbody> |
1921 | * <type> <name> <funcargs> <funcbody> | 1761 | // method with explicit return type |
1922 | * method with explicit return type | ||
1923 | */ | ||
1924 | if(token is TokenType) | 1762 | if(token is TokenType) |
1925 | { | 1763 | { |
1926 | ParseSDTClassMethodDecl(ref token, flags, tokdeclcl); | 1764 | ParseSDTClassMethodDecl(ref token, flags, tokdeclcl); |
1927 | continue; | 1765 | continue; |
1928 | } | 1766 | } |
1929 | 1767 | ||
1930 | /* | 1768 | // <name> <funcargs> <funcbody> |
1931 | * <name> <funcargs> <funcbody> | 1769 | // method returning void |
1932 | * method returning void | ||
1933 | */ | ||
1934 | if((token is TokenName) || ((token is TokenKw) && ((TokenKw)token).sdtClassOp)) | 1770 | if((token is TokenName) || ((token is TokenKw) && ((TokenKw)token).sdtClassOp)) |
1935 | { | 1771 | { |
1936 | ParseSDTClassMethodDecl(ref token, flags, tokdeclcl); | 1772 | ParseSDTClassMethodDecl(ref token, flags, tokdeclcl); |
1937 | continue; | 1773 | continue; |
1938 | } | 1774 | } |
1939 | 1775 | ||
1940 | /* | 1776 | // That's all we support in a class declaration. |
1941 | * That's all we support in a class declaration. | ||
1942 | */ | ||
1943 | ErrorMsg(token, "expecting field or method declaration"); | 1777 | ErrorMsg(token, "expecting field or method declaration"); |
1944 | token = SkipPastSemi(token); | 1778 | token = SkipPastSemi(token); |
1945 | } | 1779 | } |
1946 | 1780 | ||
1947 | /* | 1781 | // If script didn't specify any constructor, create a default no-argument one. |
1948 | * If script didn't specify any constructor, create a default no-argument one. | ||
1949 | */ | ||
1950 | if(!haveExplicitConstructor) | 1782 | if(!haveExplicitConstructor) |
1951 | { | 1783 | { |
1952 | TokenDeclVar tokenDeclFunc = new TokenDeclVar(token, null, tokenScript); | 1784 | TokenDeclVar tokenDeclFunc = new TokenDeclVar(token, null, tokenScript); |
@@ -1971,9 +1803,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1971 | tokenScript.AddVarEntry(tokenDeclFunc); | 1803 | tokenScript.AddVarEntry(tokenDeclFunc); |
1972 | } | 1804 | } |
1973 | 1805 | ||
1974 | /* | 1806 | // Skip over the closing brace and pop corresponding var frame. |
1975 | * Skip over the closing brace and pop corresponding var frame. | ||
1976 | */ | ||
1977 | token = token.nextToken; | 1807 | token = token.nextToken; |
1978 | tokenScript.PopVarFrame(); | 1808 | tokenScript.PopVarFrame(); |
1979 | ret: | 1809 | ret: |
@@ -2079,10 +1909,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2079 | */ | 1909 | */ |
2080 | private TokenDeclVar ParseProperty(ref Token token, bool abs, bool imp) | 1910 | private TokenDeclVar ParseProperty(ref Token token, bool abs, bool imp) |
2081 | { | 1911 | { |
2082 | /* | 1912 | // Parse out the property's type and name. |
2083 | * Parse out the property's type and name. | 1913 | // <type> <name> |
2084 | * <type> <name> | ||
2085 | */ | ||
2086 | TokenType type = (TokenType)token; | 1914 | TokenType type = (TokenType)token; |
2087 | TokenName name; | 1915 | TokenName name; |
2088 | TokenArgDecl args; | 1916 | TokenArgDecl args; |
@@ -2101,10 +1929,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2101 | args = new TokenArgDecl(token); | 1929 | args = new TokenArgDecl(token); |
2102 | } | 1930 | } |
2103 | 1931 | ||
2104 | /* | 1932 | // Maybe it claims to implement some interface properties. |
2105 | * Maybe it claims to implement some interface properties. | 1933 | // [ ':' <ifacetype>[.<propname>] ',' ... ] |
2106 | * [ ':' <ifacetype>[.<propname>] ',' ... ] | ||
2107 | */ | ||
2108 | TokenIntfImpl implements = null; | 1934 | TokenIntfImpl implements = null; |
2109 | if(token is TokenKwColon) | 1935 | if(token is TokenKwColon) |
2110 | { | 1936 | { |
@@ -2117,9 +1943,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2117 | } | 1943 | } |
2118 | } | 1944 | } |
2119 | 1945 | ||
2120 | /* | 1946 | // Should have an opening brace. |
2121 | * Should have an opening brace. | ||
2122 | */ | ||
2123 | if(!(token is TokenKwBrcOpen)) | 1947 | if(!(token is TokenKwBrcOpen)) |
2124 | { | 1948 | { |
2125 | ErrorMsg(token, "expect { to open property definition"); | 1949 | ErrorMsg(token, "expect { to open property definition"); |
@@ -2128,19 +1952,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2128 | } | 1952 | } |
2129 | token = token.nextToken; | 1953 | token = token.nextToken; |
2130 | 1954 | ||
2131 | /* | 1955 | // Parse out the getter and/or setter. |
2132 | * Parse out the getter and/or setter. | 1956 | // 'get' { <body> | ';' } |
2133 | * 'get' { <body> | ';' } | 1957 | // 'set' { <body> | ';' } |
2134 | * 'set' { <body> | ';' } | ||
2135 | */ | ||
2136 | TokenDeclVar getFunc = null; | 1958 | TokenDeclVar getFunc = null; |
2137 | TokenDeclVar setFunc = null; | 1959 | TokenDeclVar setFunc = null; |
2138 | while(!(token is TokenKwBrcClose)) | 1960 | while(!(token is TokenKwBrcClose)) |
2139 | { | 1961 | { |
2140 | 1962 | // Maybe create a getter function. | |
2141 | /* | ||
2142 | * Maybe create a getter function. | ||
2143 | */ | ||
2144 | if(token is TokenKwGet) | 1963 | if(token is TokenKwGet) |
2145 | { | 1964 | { |
2146 | getFunc = new TokenDeclVar(token, null, tokenScript); | 1965 | getFunc = new TokenDeclVar(token, null, tokenScript); |
@@ -2161,9 +1980,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2161 | continue; | 1980 | continue; |
2162 | } | 1981 | } |
2163 | 1982 | ||
2164 | /* | 1983 | // Maybe create a setter function. |
2165 | * Maybe create a setter function. | ||
2166 | */ | ||
2167 | if(token is TokenKwSet) | 1984 | if(token is TokenKwSet) |
2168 | { | 1985 | { |
2169 | TokenArgDecl argDecl = args; | 1986 | TokenArgDecl argDecl = args; |
@@ -2204,18 +2021,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2204 | return null; | 2021 | return null; |
2205 | } | 2022 | } |
2206 | 2023 | ||
2207 | /* | 2024 | // Set up a variable for the property. |
2208 | * Set up a variable for the property. | ||
2209 | */ | ||
2210 | TokenDeclVar tokenDeclVar = new TokenDeclVar(name, null, tokenScript); | 2025 | TokenDeclVar tokenDeclVar = new TokenDeclVar(name, null, tokenScript); |
2211 | tokenDeclVar.type = type; | 2026 | tokenDeclVar.type = type; |
2212 | tokenDeclVar.name = name; | 2027 | tokenDeclVar.name = name; |
2213 | tokenDeclVar.getProp = getFunc; | 2028 | tokenDeclVar.getProp = getFunc; |
2214 | tokenDeclVar.setProp = setFunc; | 2029 | tokenDeclVar.setProp = setFunc; |
2215 | 2030 | ||
2216 | /* | 2031 | // Can't be same name already in block. |
2217 | * Can't be same name already in block. | ||
2218 | */ | ||
2219 | if(!tokenScript.AddVarEntry(tokenDeclVar)) | 2032 | if(!tokenScript.AddVarEntry(tokenDeclVar)) |
2220 | { | 2033 | { |
2221 | ErrorMsg(tokenDeclVar, "duplicate member " + name.val); | 2034 | ErrorMsg(tokenDeclVar, "duplicate member " + name.val); |
@@ -2279,17 +2092,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2279 | tokenScript.PushVarFrame(tokenDeclFunc.argDecl.varDict); | 2092 | tokenScript.PushVarFrame(tokenDeclFunc.argDecl.varDict); |
2280 | try | 2093 | try |
2281 | { | 2094 | { |
2282 | /* | 2095 | // Set up reference to base constructor. |
2283 | * Set up reference to base constructor. | ||
2284 | */ | ||
2285 | TokenLValBaseField baseCtor = new TokenLValBaseField(token, | 2096 | TokenLValBaseField baseCtor = new TokenLValBaseField(token, |
2286 | new TokenName(token, "$ctor"), | 2097 | new TokenName(token, "$ctor"), |
2287 | tokdeclcl); | 2098 | tokdeclcl); |
2288 | 2099 | ||
2289 | /* | 2100 | // Parse any base constructor call as if it were the first statement of the |
2290 | * Parse any base constructor call as if it were the first statement of the | 2101 | // constructor itself. |
2291 | * constructor itself. | ||
2292 | */ | ||
2293 | if(token is TokenKwColon) | 2102 | if(token is TokenKwColon) |
2294 | { | 2103 | { |
2295 | token = token.nextToken; | 2104 | token = token.nextToken; |
@@ -2318,17 +2127,12 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2318 | } | 2127 | } |
2319 | else if(tokdeclcl.extends != null) | 2128 | else if(tokdeclcl.extends != null) |
2320 | { | 2129 | { |
2321 | 2130 | // Caller didn't specify a constructor but we are extending, so we will | |
2322 | /* | 2131 | // call the extended class's default constructor. |
2323 | * Caller didn't specify a constructor but we are extending, so we will | ||
2324 | * call the extended class's default constructor. | ||
2325 | */ | ||
2326 | SetUpDefaultBaseCtorCall(tokenDeclFunc); | 2132 | SetUpDefaultBaseCtorCall(tokenDeclFunc); |
2327 | } | 2133 | } |
2328 | 2134 | ||
2329 | /* | 2135 | // Parse the constructor body. |
2330 | * Parse the constructor body. | ||
2331 | */ | ||
2332 | tokenDeclFunc.body = ParseStmtBlock(ref token); | 2136 | tokenDeclFunc.body = ParseStmtBlock(ref token); |
2333 | if(tokenDeclFunc.body == null) | 2137 | if(tokenDeclFunc.body == null) |
2334 | return; | 2138 | return; |
@@ -2341,10 +2145,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2341 | currentDeclFunc = saveDeclFunc; | 2145 | currentDeclFunc = saveDeclFunc; |
2342 | } | 2146 | } |
2343 | 2147 | ||
2344 | /* | 2148 | // Add to list of methods defined by this class. |
2345 | * Add to list of methods defined by this class. | 2149 | // It has the name "$ctor(argsig)". |
2346 | * It has the name "$ctor(argsig)". | ||
2347 | */ | ||
2348 | if(!tokenScript.AddVarEntry(tokenDeclFunc)) | 2150 | if(!tokenScript.AddVarEntry(tokenDeclFunc)) |
2349 | { | 2151 | { |
2350 | ErrorMsg(tokenDeclFunc, "duplicate constructor definition"); | 2152 | ErrorMsg(tokenDeclFunc, "duplicate constructor definition"); |
@@ -2443,7 +2245,6 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2443 | } | 2245 | } |
2444 | else | 2246 | else |
2445 | { | 2247 | { |
2446 | |||
2447 | // other times should have ',' <type> | 2248 | // other times should have ',' <type> |
2448 | if(!(u is TokenKwComma)) | 2249 | if(!(u is TokenKwComma)) |
2449 | { | 2250 | { |
@@ -2550,16 +2351,12 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2550 | continue; | 2351 | continue; |
2551 | } | 2352 | } |
2552 | 2353 | ||
2553 | /* | 2354 | // Parse nested script-defined type definitions. |
2554 | * Parse nested script-defined type definitions. | ||
2555 | */ | ||
2556 | if(ParseDeclSDTypes(ref token, tokdeclin, SDT_PUBLIC)) | 2355 | if(ParseDeclSDTypes(ref token, tokdeclin, SDT_PUBLIC)) |
2557 | continue; | 2356 | continue; |
2558 | 2357 | ||
2559 | /* | 2358 | // <type> <name> <funcargs> ; |
2560 | * <type> <name> <funcargs> ; | 2359 | // abstract method with explicit return type |
2561 | * abstract method with explicit return type | ||
2562 | */ | ||
2563 | if((token is TokenType) && | 2360 | if((token is TokenType) && |
2564 | (token.nextToken is TokenName) && | 2361 | (token.nextToken is TokenName) && |
2565 | (token.nextToken.nextToken is TokenKwParOpen)) | 2362 | (token.nextToken.nextToken is TokenKwParOpen)) |
@@ -2576,10 +2373,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2576 | continue; | 2373 | continue; |
2577 | } | 2374 | } |
2578 | 2375 | ||
2579 | /* | 2376 | // <name> <funcargs> ; |
2580 | * <name> <funcargs> ; | 2377 | // abstract method returning void |
2581 | * abstract method returning void | ||
2582 | */ | ||
2583 | if((token is TokenName) && | 2378 | if((token is TokenName) && |
2584 | (token.nextToken is TokenKwParOpen)) | 2379 | (token.nextToken is TokenKwParOpen)) |
2585 | { | 2380 | { |
@@ -2594,11 +2389,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2594 | continue; | 2389 | continue; |
2595 | } | 2390 | } |
2596 | 2391 | ||
2597 | /* | 2392 | // <type> <name> { [ get ; ] [ set ; ] } |
2598 | * <type> <name> { [ get ; ] [ set ; ] } | 2393 | // <type> '[' ... ']' { [ get ; ] [ set ; ] } |
2599 | * <type> '[' ... ']' { [ get ; ] [ set ; ] } | 2394 | // abstract property |
2600 | * abstract property | ||
2601 | */ | ||
2602 | bool prop = (token is TokenType) && | 2395 | bool prop = (token is TokenType) && |
2603 | (token.nextToken is TokenName) && | 2396 | (token.nextToken is TokenName) && |
2604 | (token.nextToken.nextToken is TokenKwBrcOpen || | 2397 | (token.nextToken.nextToken is TokenKwBrcOpen || |
@@ -2610,16 +2403,12 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2610 | continue; | 2403 | continue; |
2611 | } | 2404 | } |
2612 | 2405 | ||
2613 | /* | 2406 | // That's all we support in an interface declaration. |
2614 | * That's all we support in an interface declaration. | ||
2615 | */ | ||
2616 | ErrorMsg(token, "expecting method or property prototype"); | 2407 | ErrorMsg(token, "expecting method or property prototype"); |
2617 | token = SkipPastSemi(token); | 2408 | token = SkipPastSemi(token); |
2618 | } | 2409 | } |
2619 | 2410 | ||
2620 | /* | 2411 | // Skip over the closing brace and pop the corresponding var frame. |
2621 | * Skip over the closing brace and pop the corresponding var frame. | ||
2622 | */ | ||
2623 | token = token.nextToken; | 2412 | token = token.nextToken; |
2624 | tokenScript.PopVarFrame(); | 2413 | tokenScript.PopVarFrame(); |
2625 | } | 2414 | } |
@@ -2807,29 +2596,21 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2807 | return true; | 2596 | return true; |
2808 | } | 2597 | } |
2809 | 2598 | ||
2810 | /* | 2599 | // Declare this function as being the one currently being processed |
2811 | * Declare this function as being the one currently being processed | 2600 | // for anything that cares. We also start a variable frame that |
2812 | * for anything that cares. We also start a variable frame that | 2601 | // includes all the declared parameters. |
2813 | * includes all the declared parameters. | ||
2814 | */ | ||
2815 | TokenDeclVar saveDeclFunc = currentDeclFunc; | 2602 | TokenDeclVar saveDeclFunc = currentDeclFunc; |
2816 | currentDeclFunc = tokenDeclFunc; | 2603 | currentDeclFunc = tokenDeclFunc; |
2817 | tokenScript.PushVarFrame(tokenDeclFunc.argDecl.varDict); | 2604 | tokenScript.PushVarFrame(tokenDeclFunc.argDecl.varDict); |
2818 | 2605 | ||
2819 | /* | 2606 | // Now parse the function statement block. |
2820 | * Now parse the function statement block. | ||
2821 | */ | ||
2822 | tokenDeclFunc.body = ParseStmtBlock(ref token); | 2607 | tokenDeclFunc.body = ParseStmtBlock(ref token); |
2823 | 2608 | ||
2824 | /* | 2609 | // Pop the var frame that contains the arguments. |
2825 | * Pop the var frame that contains the arguments. | ||
2826 | */ | ||
2827 | tokenScript.PopVarFrame(); | 2610 | tokenScript.PopVarFrame(); |
2828 | currentDeclFunc = saveDeclFunc; | 2611 | currentDeclFunc = saveDeclFunc; |
2829 | 2612 | ||
2830 | /* | 2613 | // Check final errors. |
2831 | * Check final errors. | ||
2832 | */ | ||
2833 | if(tokenDeclFunc.body == null) | 2614 | if(tokenDeclFunc.body == null) |
2834 | return false; | 2615 | return false; |
2835 | if(abs) | 2616 | if(abs) |
@@ -2851,9 +2632,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2851 | */ | 2632 | */ |
2852 | private TokenStmt ParseStmt(ref Token token) | 2633 | private TokenStmt ParseStmt(ref Token token) |
2853 | { | 2634 | { |
2854 | /* | 2635 | // Statements that begin with a specific keyword. |
2855 | * Statements that begin with a specific keyword. | ||
2856 | */ | ||
2857 | if(token is TokenKwAt) | 2636 | if(token is TokenKwAt) |
2858 | return ParseStmtLabel(ref token); | 2637 | return ParseStmtLabel(ref token); |
2859 | if(token is TokenKwBrcOpen) | 2638 | if(token is TokenKwBrcOpen) |
@@ -2887,10 +2666,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2887 | if(token is TokenKwWhile) | 2666 | if(token is TokenKwWhile) |
2888 | return ParseStmtWhile(ref token); | 2667 | return ParseStmtWhile(ref token); |
2889 | 2668 | ||
2890 | /* | 2669 | // Try to parse anything else as an expression, possibly calling |
2891 | * Try to parse anything else as an expression, possibly calling | 2670 | // something and/or writing to a variable. |
2892 | * something and/or writing to a variable. | ||
2893 | */ | ||
2894 | TokenRVal tokenRVal = ParseRVal(ref token, semiOnly); | 2671 | TokenRVal tokenRVal = ParseRVal(ref token, semiOnly); |
2895 | if(tokenRVal != null) | 2672 | if(tokenRVal != null) |
2896 | { | 2673 | { |
@@ -2899,9 +2676,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2899 | return tokenStmtRVal; | 2676 | return tokenStmtRVal; |
2900 | } | 2677 | } |
2901 | 2678 | ||
2902 | /* | 2679 | // Who knows what it is... |
2903 | * Who knows what it is... | ||
2904 | */ | ||
2905 | ErrorMsg(token, "unknown statement"); | 2680 | ErrorMsg(token, "unknown statement"); |
2906 | token = SkipPastSemi(token); | 2681 | token = SkipPastSemi(token); |
2907 | return null; | 2682 | return null; |
@@ -3053,9 +2828,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
3053 | { | 2828 | { |
3054 | currentDeclFunc.triviality = Triviality.complex; | 2829 | currentDeclFunc.triviality = Triviality.complex; |
3055 | 2830 | ||
3056 | /* | 2831 | // Create encapsulating token and skip past 'for (' |
3057 | * Create encapsulating token and skip past 'for (' | ||
3058 | */ | ||
3059 | TokenStmtFor tokenStmtFor = new TokenStmtFor(token); | 2832 | TokenStmtFor tokenStmtFor = new TokenStmtFor(token); |
3060 | token = token.nextToken; | 2833 | token = token.nextToken; |
3061 | if(!(token is TokenKwParOpen)) | 2834 | if(!(token is TokenKwParOpen)) |
@@ -3065,9 +2838,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
3065 | } | 2838 | } |
3066 | token = token.nextToken; | 2839 | token = token.nextToken; |
3067 | 2840 | ||
3068 | /* | 2841 | // If a plain for, ie, not declaring a variable, it's straightforward. |
3069 | * If a plain for, ie, not declaring a variable, it's straightforward. | ||
3070 | */ | ||
3071 | if(!(token is TokenType)) | 2842 | if(!(token is TokenType)) |
3072 | { | 2843 | { |
3073 | tokenStmtFor.initStmt = ParseStmt(ref token); | 2844 | tokenStmtFor.initStmt = ParseStmt(ref token); |
@@ -3076,10 +2847,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
3076 | return ParseStmtFor2(tokenStmtFor, ref token) ? tokenStmtFor : null; | 2847 | return ParseStmtFor2(tokenStmtFor, ref token) ? tokenStmtFor : null; |
3077 | } | 2848 | } |
3078 | 2849 | ||
3079 | /* | 2850 | // Initialization declares a variable, so encapsulate it in a block so |
3080 | * Initialization declares a variable, so encapsulate it in a block so | 2851 | // variable has scope only in the for statement, including its body. |
3081 | * variable has scope only in the for statement, including its body. | ||
3082 | */ | ||
3083 | TokenStmtBlock forStmtBlock = new TokenStmtBlock(tokenStmtFor); | 2852 | TokenStmtBlock forStmtBlock = new TokenStmtBlock(tokenStmtFor); |
3084 | forStmtBlock.outerStmtBlock = currentStmtBlock; | 2853 | forStmtBlock.outerStmtBlock = currentStmtBlock; |
3085 | forStmtBlock.function = currentDeclFunc; | 2854 | forStmtBlock.function = currentDeclFunc; |
@@ -3148,9 +2917,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
3148 | { | 2917 | { |
3149 | currentDeclFunc.triviality = Triviality.complex; | 2918 | currentDeclFunc.triviality = Triviality.complex; |
3150 | 2919 | ||
3151 | /* | 2920 | // Create encapsulating token and skip past 'foreach (' |
3152 | * Create encapsulating token and skip past 'foreach (' | ||
3153 | */ | ||
3154 | TokenStmtForEach tokenStmtForEach = new TokenStmtForEach(token); | 2921 | TokenStmtForEach tokenStmtForEach = new TokenStmtForEach(token); |
3155 | token = token.nextToken; | 2922 | token = token.nextToken; |
3156 | if(!(token is TokenKwParOpen)) | 2923 | if(!(token is TokenKwParOpen)) |
@@ -3222,9 +2989,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
3222 | 2989 | ||
3223 | private TokenStmtJump ParseStmtJump(ref Token token) | 2990 | private TokenStmtJump ParseStmtJump(ref Token token) |
3224 | { | 2991 | { |
3225 | /* | 2992 | // Create jump statement token to encapsulate the whole statement. |
3226 | * Create jump statement token to encapsulate the whole statement. | ||
3227 | */ | ||
3228 | TokenStmtJump tokenStmtJump = new TokenStmtJump(token); | 2993 | TokenStmtJump tokenStmtJump = new TokenStmtJump(token); |
3229 | token = token.nextToken; | 2994 | token = token.nextToken; |
3230 | if(!(token is TokenName) || !(token.nextToken is TokenKwSemi)) | 2995 | if(!(token is TokenName) || !(token.nextToken is TokenKwSemi)) |
@@ -3236,11 +3001,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
3236 | tokenStmtJump.label = (TokenName)token; | 3001 | tokenStmtJump.label = (TokenName)token; |
3237 | token = token.nextToken.nextToken; | 3002 | token = token.nextToken.nextToken; |
3238 | 3003 | ||
3239 | /* | 3004 | // If label is already defined, it means this is a backward (looping) |
3240 | * If label is already defined, it means this is a backward (looping) | 3005 | // jump, so remember the label has backward jump references. |
3241 | * jump, so remember the label has backward jump references. | 3006 | // We also then assume the function is complex, ie, it has a loop. |
3242 | * We also then assume the function is complex, ie, it has a loop. | ||
3243 | */ | ||
3244 | if(currentDeclFunc.labels.ContainsKey(tokenStmtJump.label.val)) | 3007 | if(currentDeclFunc.labels.ContainsKey(tokenStmtJump.label.val)) |
3245 | { | 3008 | { |
3246 | currentDeclFunc.labels[tokenStmtJump.label.val].hasBkwdRefs = true; | 3009 | currentDeclFunc.labels[tokenStmtJump.label.val].hasBkwdRefs = true; |
@@ -3450,9 +3213,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
3450 | */ | 3213 | */ |
3451 | private TokenStmtTry ParseStmtTry(ref Token token) | 3214 | private TokenStmtTry ParseStmtTry(ref Token token) |
3452 | { | 3215 | { |
3453 | /* | 3216 | // Parse out the 'try { ... }' part |
3454 | * Parse out the 'try { ... }' part | ||
3455 | */ | ||
3456 | Token tryKw = token; | 3217 | Token tryKw = token; |
3457 | token = token.nextToken; | 3218 | token = token.nextToken; |
3458 | TokenStmt body = ParseStmtBlock(ref token); | 3219 | TokenStmt body = ParseStmtBlock(ref token); |
@@ -3585,14 +3346,12 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
3585 | { | 3346 | { |
3586 | TokenDeclVar tokenDeclVar = new TokenDeclVar(token.nextToken, currentDeclFunc, tokenScript); | 3347 | TokenDeclVar tokenDeclVar = new TokenDeclVar(token.nextToken, currentDeclFunc, tokenScript); |
3587 | 3348 | ||
3588 | /* | 3349 | // Handle constant declaration. |
3589 | * Handle constant declaration. | 3350 | // It ends up in the declared variables list for the statement block just like |
3590 | * It ends up in the declared variables list for the statement block just like | 3351 | // any other variable, except it has .constant = true. |
3591 | * any other variable, except it has .constant = true. | 3352 | // The code generator will test that the initialization expression is constant. |
3592 | * The code generator will test that the initialization expression is constant. | 3353 | // |
3593 | * | 3354 | // constant <name> = <value> ; |
3594 | * constant <name> = <value> ; | ||
3595 | */ | ||
3596 | if(token is TokenKwConst) | 3355 | if(token is TokenKwConst) |
3597 | { | 3356 | { |
3598 | token = token.nextToken; | 3357 | token = token.nextToken; |
@@ -3618,14 +3377,10 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
3618 | tokenDeclVar.constant = true; | 3377 | tokenDeclVar.constant = true; |
3619 | } | 3378 | } |
3620 | 3379 | ||
3621 | /* | 3380 | // Otherwise, normal variable declaration with optional initialization value. |
3622 | * Otherwise, normal variable declaration with optional initialization value. | ||
3623 | */ | ||
3624 | else | 3381 | else |
3625 | { | 3382 | { |
3626 | /* | 3383 | // Build basic encapsulating token with type and name. |
3627 | * Build basic encapsulating token with type and name. | ||
3628 | */ | ||
3629 | tokenDeclVar.type = (TokenType)token; | 3384 | tokenDeclVar.type = (TokenType)token; |
3630 | token = token.nextToken; | 3385 | token = token.nextToken; |
3631 | if(!(token is TokenName)) | 3386 | if(!(token is TokenName)) |
@@ -3637,10 +3392,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
3637 | tokenDeclVar.name = (TokenName)token; | 3392 | tokenDeclVar.name = (TokenName)token; |
3638 | token = token.nextToken; | 3393 | token = token.nextToken; |
3639 | 3394 | ||
3640 | /* | 3395 | // If just a ;, there is no explicit initialization value. |
3641 | * If just a ;, there is no explicit initialization value. | 3396 | // Otherwise, look for an =RVal; expression that has init value. |
3642 | * Otherwise, look for an =RVal; expression that has init value. | ||
3643 | */ | ||
3644 | if(token is TokenKwSemi) | 3397 | if(token is TokenKwSemi) |
3645 | { | 3398 | { |
3646 | token = token.nextToken; | 3399 | token = token.nextToken; |
@@ -3673,18 +3426,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
3673 | } | 3426 | } |
3674 | } | 3427 | } |
3675 | 3428 | ||
3676 | /* | 3429 | // If doing local vars, each var goes in its own var frame, |
3677 | * If doing local vars, each var goes in its own var frame, | 3430 | // to make sure no code before this point can reference it. |
3678 | * to make sure no code before this point can reference it. | ||
3679 | */ | ||
3680 | if(currentStmtBlock != null) | 3431 | if(currentStmtBlock != null) |
3681 | { | 3432 | { |
3682 | tokenScript.PushVarFrame(true); | 3433 | tokenScript.PushVarFrame(true); |
3683 | } | 3434 | } |
3684 | 3435 | ||
3685 | /* | 3436 | // Can't be same name already in block. |
3686 | * Can't be same name already in block. | ||
3687 | */ | ||
3688 | if(!tokenScript.AddVarEntry(tokenDeclVar)) | 3437 | if(!tokenScript.AddVarEntry(tokenDeclVar)) |
3689 | { | 3438 | { |
3690 | ErrorMsg(tokenDeclVar, "duplicate variable " + tokenDeclVar.name.val); | 3439 | ErrorMsg(tokenDeclVar, "duplicate variable " + tokenDeclVar.name.val); |
@@ -3702,9 +3451,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
3702 | */ | 3451 | */ |
3703 | private void DoVarInit(TokenDeclVar initFunc, TokenLVal left, TokenRVal init) | 3452 | private void DoVarInit(TokenDeclVar initFunc, TokenLVal left, TokenRVal init) |
3704 | { | 3453 | { |
3705 | /* | 3454 | // Make a statement that assigns the initialization value to the variable. |
3706 | * Make a statement that assigns the initialization value to the variable. | ||
3707 | */ | ||
3708 | TokenStmt stmt; | 3455 | TokenStmt stmt; |
3709 | if(init == null) | 3456 | if(init == null) |
3710 | { | 3457 | { |
@@ -3720,11 +3467,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
3720 | stmt = tsrv; | 3467 | stmt = tsrv; |
3721 | } | 3468 | } |
3722 | 3469 | ||
3723 | /* | 3470 | // Add statement to end of initialization function. |
3724 | * Add statement to end of initialization function. | 3471 | // Be sure to execute them in same order as in source |
3725 | * Be sure to execute them in same order as in source | 3472 | // as some doofus scripts depend on it. |
3726 | * as some doofus scripts depend on it. | ||
3727 | */ | ||
3728 | Token lastStmt = initFunc.body.statements; | 3473 | Token lastStmt = initFunc.body.statements; |
3729 | if(lastStmt == null) | 3474 | if(lastStmt == null) |
3730 | { | 3475 | { |
@@ -3805,17 +3550,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
3805 | */ | 3550 | */ |
3806 | public TokenRVal ParseRVal(ref Token token, Type[] termTokenTypes) | 3551 | public TokenRVal ParseRVal(ref Token token, Type[] termTokenTypes) |
3807 | { | 3552 | { |
3808 | /* | 3553 | // Start with pushing the first operand on operand stack. |
3809 | * Start with pushing the first operand on operand stack. | ||
3810 | */ | ||
3811 | BinOp binOps = null; | 3554 | BinOp binOps = null; |
3812 | TokenRVal operands = GetOperand(ref token); | 3555 | TokenRVal operands = GetOperand(ref token); |
3813 | if(operands == null) | 3556 | if(operands == null) |
3814 | return null; | 3557 | return null; |
3815 | 3558 | ||
3816 | /* | 3559 | // Keep scanning until we hit the termination token. |
3817 | * Keep scanning until we hit the termination token. | ||
3818 | */ | ||
3819 | while(true) | 3560 | while(true) |
3820 | { | 3561 | { |
3821 | Type tokType = token.GetType(); | 3562 | Type tokType = token.GetType(); |
@@ -3825,59 +3566,47 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
3825 | goto done; | 3566 | goto done; |
3826 | } | 3567 | } |
3827 | 3568 | ||
3828 | /* | 3569 | // Special form: |
3829 | * Special form: | 3570 | // <operand> is <typeexp> |
3830 | * <operand> is <typeexp> | ||
3831 | */ | ||
3832 | if(token is TokenKwIs) | 3571 | if(token is TokenKwIs) |
3833 | { | 3572 | { |
3834 | TokenRValIsType tokenRValIsType = new TokenRValIsType(token); | 3573 | TokenRValIsType tokenRValIsType = new TokenRValIsType(token); |
3835 | token = token.nextToken; | 3574 | token = token.nextToken; |
3836 | 3575 | ||
3837 | /* | 3576 | // Parse the <typeexp>. |
3838 | * Parse the <typeexp>. | ||
3839 | */ | ||
3840 | tokenRValIsType.typeExp = ParseTypeExp(ref token); | 3577 | tokenRValIsType.typeExp = ParseTypeExp(ref token); |
3841 | if(tokenRValIsType.typeExp == null) | 3578 | if(tokenRValIsType.typeExp == null) |
3842 | return null; | 3579 | return null; |
3843 | 3580 | ||
3844 | /* | 3581 | // Replace top operand with result of <operand> is <typeexp> |
3845 | * Replace top operand with result of <operand> is <typeexp> | ||
3846 | */ | ||
3847 | tokenRValIsType.rValExp = operands; | 3582 | tokenRValIsType.rValExp = operands; |
3848 | tokenRValIsType.nextToken = operands.nextToken; | 3583 | tokenRValIsType.nextToken = operands.nextToken; |
3849 | operands = tokenRValIsType; | 3584 | operands = tokenRValIsType; |
3850 | 3585 | ||
3851 | /* | 3586 | // token points just past <typeexp> so see if it is another operator. |
3852 | * token points just past <typeexp> so see if it is another operator. | ||
3853 | */ | ||
3854 | continue; | 3587 | continue; |
3855 | } | 3588 | } |
3856 | 3589 | ||
3857 | /* | 3590 | // Peek at next operator. |
3858 | * Peek at next operator. | ||
3859 | */ | ||
3860 | BinOp binOp = GetOperator(ref token); | 3591 | BinOp binOp = GetOperator(ref token); |
3861 | if(binOp == null) | 3592 | if(binOp == null) |
3862 | return null; | 3593 | return null; |
3863 | 3594 | ||
3864 | /* | 3595 | // If there are stacked operators of higher or same precedence than new one, |
3865 | * If there are stacked operators of higher or same precedence than new one, | 3596 | // perform their computation then push result back on operand stack. |
3866 | * perform their computation then push result back on operand stack. | 3597 | // |
3867 | * | 3598 | // higher or same = left-to-right application of operators |
3868 | * higher or same = left-to-right application of operators | 3599 | // eg, a - b - c becomes (a - b) - c |
3869 | * eg, a - b - c becomes (a - b) - c | 3600 | // |
3870 | * | 3601 | // higher precedence = right-to-left application of operators |
3871 | * higher precedence = right-to-left application of operators | 3602 | // eg, a - b - c becomes a - (b - c) |
3872 | * eg, a - b - c becomes a - (b - c) | 3603 | // |
3873 | * | 3604 | // Now of course, there is some ugliness necessary: |
3874 | * Now of course, there is some ugliness necessary: | 3605 | // we want: a - b - c => (a - b) - c so we do 'higher or same' |
3875 | * we want: a - b - c => (a - b) - c so we do 'higher or same' | 3606 | // but we want: a += b = c => a += (b = c) so we do 'higher only' |
3876 | * but we want: a += b = c => a += (b = c) so we do 'higher only' | 3607 | // |
3877 | * | 3608 | // binOps is the first operator (or null if only one) |
3878 | * binOps is the first operator (or null if only one) | 3609 | // binOp is the second operator (or first if only one) |
3879 | * binOp is the second operator (or first if only one) | ||
3880 | */ | ||
3881 | while(binOps != null) | 3610 | while(binOps != null) |
3882 | { | 3611 | { |
3883 | if(binOps.preced < binOp.preced) | 3612 | if(binOps.preced < binOp.preced) |
@@ -3894,10 +3623,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
3894 | binOps = binOps.pop; | 3623 | binOps = binOps.pop; |
3895 | } | 3624 | } |
3896 | 3625 | ||
3897 | /* | 3626 | // Handle conditional expression as a special form: |
3898 | * Handle conditional expression as a special form: | 3627 | // <condexp> ? <trueexp> : <falseexp> |
3899 | * <condexp> ? <trueexp> : <falseexp> | ||
3900 | */ | ||
3901 | if(binOp.token is TokenKwQMark) | 3628 | if(binOp.token is TokenKwQMark) |
3902 | { | 3629 | { |
3903 | TokenRValCondExpr condExpr = new TokenRValCondExpr(binOp.token); | 3630 | TokenRValCondExpr condExpr = new TokenRValCondExpr(binOp.token); |
@@ -3910,15 +3637,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
3910 | goto done; | 3637 | goto done; |
3911 | } | 3638 | } |
3912 | 3639 | ||
3913 | /* | 3640 | // Push new operator on its stack. |
3914 | * Push new operator on its stack. | ||
3915 | */ | ||
3916 | binOp.pop = binOps; | 3641 | binOp.pop = binOps; |
3917 | binOps = binOp; | 3642 | binOps = binOp; |
3918 | 3643 | ||
3919 | /* | 3644 | // Push next operand on its stack. |
3920 | * Push next operand on its stack. | ||
3921 | */ | ||
3922 | TokenRVal operand = GetOperand(ref token); | 3645 | TokenRVal operand = GetOperand(ref token); |
3923 | if(operand == null) | 3646 | if(operand == null) |
3924 | return null; | 3647 | return null; |
@@ -3927,9 +3650,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
3927 | } | 3650 | } |
3928 | done: | 3651 | done: |
3929 | 3652 | ||
3930 | /* | 3653 | // At end of expression, perform any stacked computations. |
3931 | * At end of expression, perform any stacked computations. | ||
3932 | */ | ||
3933 | while(binOps != null) | 3654 | while(binOps != null) |
3934 | { | 3655 | { |
3935 | TokenRVal result = PerformBinOp((TokenRVal)operands.prevToken, binOps, (TokenRVal)operands); | 3656 | TokenRVal result = PerformBinOp((TokenRVal)operands.prevToken, binOps, (TokenRVal)operands); |
@@ -3938,15 +3659,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
3938 | binOps = binOps.pop; | 3659 | binOps = binOps.pop; |
3939 | } | 3660 | } |
3940 | 3661 | ||
3941 | /* | 3662 | // There should be exactly one remaining operand on the stack which is our final result. |
3942 | * There should be exactly one remaining operand on the stack which is our final result. | ||
3943 | */ | ||
3944 | if(operands.prevToken != null) | 3663 | if(operands.prevToken != null) |
3945 | throw new Exception("too many operands"); | 3664 | throw new Exception("too many operands"); |
3946 | 3665 | ||
3947 | /* | 3666 | // If only one terminator type possible, advance past the terminator. |
3948 | * If only one terminator type possible, advance past the terminator. | ||
3949 | */ | ||
3950 | if(termTokenTypes.Length == 1) | 3667 | if(termTokenTypes.Length == 1) |
3951 | token = token.nextToken; | 3668 | token = token.nextToken; |
3952 | 3669 | ||
@@ -4028,9 +3745,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
4028 | */ | 3745 | */ |
4029 | private TokenRVal GetOperand(ref Token token) | 3746 | private TokenRVal GetOperand(ref Token token) |
4030 | { | 3747 | { |
4031 | /* | 3748 | // Prefix unary operators (eg ++, --) requiring an L-value. |
4032 | * Prefix unary operators (eg ++, --) requiring an L-value. | ||
4033 | */ | ||
4034 | if((token is TokenKwIncr) || (token is TokenKwDecr)) | 3749 | if((token is TokenKwIncr) || (token is TokenKwDecr)) |
4035 | { | 3750 | { |
4036 | TokenRValAsnPre asnPre = new TokenRValAsnPre(token); | 3751 | TokenRValAsnPre asnPre = new TokenRValAsnPre(token); |
@@ -4048,17 +3763,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
4048 | return asnPre; | 3763 | return asnPre; |
4049 | } | 3764 | } |
4050 | 3765 | ||
4051 | /* | 3766 | // Get the bulk of the operand, ie, without any of the below suffixes. |
4052 | * Get the bulk of the operand, ie, without any of the below suffixes. | ||
4053 | */ | ||
4054 | TokenRVal operand = GetOperandNoMods(ref token); | 3767 | TokenRVal operand = GetOperandNoMods(ref token); |
4055 | if(operand == null) | 3768 | if(operand == null) |
4056 | return null; | 3769 | return null; |
4057 | modifiers: | 3770 | modifiers: |
4058 | 3771 | ||
4059 | /* | 3772 | // If followed by '++' or '--', it is post-{in,de}cremented. |
4060 | * If followed by '++' or '--', it is post-{in,de}cremented. | ||
4061 | */ | ||
4062 | if((token is TokenKwIncr) || (token is TokenKwDecr)) | 3773 | if((token is TokenKwIncr) || (token is TokenKwDecr)) |
4063 | { | 3774 | { |
4064 | TokenRValAsnPost asnPost = new TokenRValAsnPost(token); | 3775 | TokenRValAsnPost asnPost = new TokenRValAsnPost(token); |
@@ -4073,9 +3784,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
4073 | return asnPost; | 3784 | return asnPost; |
4074 | } | 3785 | } |
4075 | 3786 | ||
4076 | /* | 3787 | // If followed by a '.', it is an instance field or instance method reference. |
4077 | * If followed by a '.', it is an instance field or instance method reference. | ||
4078 | */ | ||
4079 | if(token is TokenKwDot) | 3788 | if(token is TokenKwDot) |
4080 | { | 3789 | { |
4081 | token = token.nextToken; | 3790 | token = token.nextToken; |
@@ -4092,17 +3801,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
4092 | goto modifiers; | 3801 | goto modifiers; |
4093 | } | 3802 | } |
4094 | 3803 | ||
4095 | /* | 3804 | // If followed by a '[', it is an array subscript. |
4096 | * If followed by a '[', it is an array subscript. | ||
4097 | */ | ||
4098 | if(token is TokenKwBrkOpen) | 3805 | if(token is TokenKwBrkOpen) |
4099 | { | 3806 | { |
4100 | TokenLValArEle tokenLValArEle = new TokenLValArEle(token); | 3807 | TokenLValArEle tokenLValArEle = new TokenLValArEle(token); |
4101 | token = token.nextToken; | 3808 | token = token.nextToken; |
4102 | 3809 | ||
4103 | /* | 3810 | // Parse subscript(s) expression. |
4104 | * Parse subscript(s) expression. | ||
4105 | */ | ||
4106 | tokenLValArEle.subRVal = ParseRVal(ref token, brkCloseOnly); | 3811 | tokenLValArEle.subRVal = ParseRVal(ref token, brkCloseOnly); |
4107 | if(tokenLValArEle.subRVal == null) | 3812 | if(tokenLValArEle.subRVal == null) |
4108 | { | 3813 | { |
@@ -4110,44 +3815,33 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
4110 | return null; | 3815 | return null; |
4111 | } | 3816 | } |
4112 | 3817 | ||
4113 | /* | 3818 | // See if comma-separated list of values. |
4114 | * See if comma-separated list of values. | ||
4115 | */ | ||
4116 | TokenRVal subscriptRVals; | 3819 | TokenRVal subscriptRVals; |
4117 | int numSubscripts = SplitCommaRVals(tokenLValArEle.subRVal, out subscriptRVals); | 3820 | int numSubscripts = SplitCommaRVals(tokenLValArEle.subRVal, out subscriptRVals); |
4118 | if(numSubscripts > 1) | 3821 | if(numSubscripts > 1) |
4119 | { | 3822 | { |
4120 | 3823 | // If so, put the values in an LSL_List object. | |
4121 | /* | ||
4122 | * If so, put the values in an LSL_List object. | ||
4123 | */ | ||
4124 | TokenRValList rValList = new TokenRValList(tokenLValArEle); | 3824 | TokenRValList rValList = new TokenRValList(tokenLValArEle); |
4125 | rValList.rVal = subscriptRVals; | 3825 | rValList.rVal = subscriptRVals; |
4126 | rValList.nItems = numSubscripts; | 3826 | rValList.nItems = numSubscripts; |
4127 | tokenLValArEle.subRVal = rValList; | 3827 | tokenLValArEle.subRVal = rValList; |
4128 | } | 3828 | } |
4129 | 3829 | ||
4130 | /* | 3830 | // Either way, save array variable name |
4131 | * Either way, save array variable name | 3831 | // and substitute whole reference for L-value |
4132 | * and substitute whole reference for L-value | ||
4133 | */ | ||
4134 | tokenLValArEle.baseRVal = operand; | 3832 | tokenLValArEle.baseRVal = operand; |
4135 | operand = tokenLValArEle; | 3833 | operand = tokenLValArEle; |
4136 | goto modifiers; | 3834 | goto modifiers; |
4137 | } | 3835 | } |
4138 | 3836 | ||
4139 | /* | 3837 | // If followed by a '(', it is a function/method call. |
4140 | * If followed by a '(', it is a function/method call. | ||
4141 | */ | ||
4142 | if(token is TokenKwParOpen) | 3838 | if(token is TokenKwParOpen) |
4143 | { | 3839 | { |
4144 | operand = ParseRValCall(ref token, operand); | 3840 | operand = ParseRValCall(ref token, operand); |
4145 | goto modifiers; | 3841 | goto modifiers; |
4146 | } | 3842 | } |
4147 | 3843 | ||
4148 | /* | 3844 | // If 'new' arraytipe '{', it is an array initializer. |
4149 | * If 'new' arraytipe '{', it is an array initializer. | ||
4150 | */ | ||
4151 | if((token is TokenKwBrcOpen) && (operand is TokenLValSField) && | 3845 | if((token is TokenKwBrcOpen) && (operand is TokenLValSField) && |
4152 | (((TokenLValSField)operand).fieldName.val == "$new") && | 3846 | (((TokenLValSField)operand).fieldName.val == "$new") && |
4153 | ((TokenLValSField)operand).baseType.ToString().EndsWith("]")) | 3847 | ((TokenLValSField)operand).baseType.ToString().EndsWith("]")) |
@@ -4165,9 +3859,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
4165 | */ | 3859 | */ |
4166 | private TokenRVal GetOperandNoMods(ref Token token) | 3860 | private TokenRVal GetOperandNoMods(ref Token token) |
4167 | { | 3861 | { |
4168 | /* | 3862 | // Simple unary operators. |
4169 | * Simple unary operators. | ||
4170 | */ | ||
4171 | if((token is TokenKwSub) || | 3863 | if((token is TokenKwSub) || |
4172 | (token is TokenKwTilde) || | 3864 | (token is TokenKwTilde) || |
4173 | (token is TokenKwExclam)) | 3865 | (token is TokenKwExclam)) |
@@ -4180,9 +3872,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
4180 | return PerformUnOp(uop, rVal); | 3872 | return PerformUnOp(uop, rVal); |
4181 | } | 3873 | } |
4182 | 3874 | ||
4183 | /* | 3875 | // Type casting. |
4184 | * Type casting. | ||
4185 | */ | ||
4186 | if((token is TokenKwParOpen) && | 3876 | if((token is TokenKwParOpen) && |
4187 | (token.nextToken is TokenType) && | 3877 | (token.nextToken is TokenType) && |
4188 | (token.nextToken.nextToken is TokenKwParClose)) | 3878 | (token.nextToken.nextToken is TokenKwParClose)) |
@@ -4195,17 +3885,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
4195 | return new TokenRValCast(type, rVal); | 3885 | return new TokenRValCast(type, rVal); |
4196 | } | 3886 | } |
4197 | 3887 | ||
4198 | /* | 3888 | // Parenthesized expression. |
4199 | * Parenthesized expression. | ||
4200 | */ | ||
4201 | if(token is TokenKwParOpen) | 3889 | if(token is TokenKwParOpen) |
4202 | { | 3890 | { |
4203 | return ParseRValParen(ref token); | 3891 | return ParseRValParen(ref token); |
4204 | } | 3892 | } |
4205 | 3893 | ||
4206 | /* | 3894 | // Constants. |
4207 | * Constants. | ||
4208 | */ | ||
4209 | if(token is TokenChar) | 3895 | if(token is TokenChar) |
4210 | { | 3896 | { |
4211 | TokenRValConst rValConst = new TokenRValConst(token, ((TokenChar)token).val); | 3897 | TokenRValConst rValConst = new TokenRValConst(token, ((TokenChar)token).val); |
@@ -4237,9 +3923,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
4237 | return rValUndef; | 3923 | return rValUndef; |
4238 | } | 3924 | } |
4239 | 3925 | ||
4240 | /* | 3926 | // '<'value,...'>', ie, rotation or vector |
4241 | * '<'value,...'>', ie, rotation or vector | ||
4242 | */ | ||
4243 | if(token is TokenKwCmpLT) | 3927 | if(token is TokenKwCmpLT) |
4244 | { | 3928 | { |
4245 | Token openBkt = token; | 3929 | Token openBkt = token; |
@@ -4277,9 +3961,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
4277 | } | 3961 | } |
4278 | } | 3962 | } |
4279 | 3963 | ||
4280 | /* | 3964 | // '['value,...']', ie, list |
4281 | * '['value,...']', ie, list | ||
4282 | */ | ||
4283 | if(token is TokenKwBrkOpen) | 3965 | if(token is TokenKwBrkOpen) |
4284 | { | 3966 | { |
4285 | TokenRValList rValList = new TokenRValList(token); | 3967 | TokenRValList rValList = new TokenRValList(token); |
@@ -4298,9 +3980,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
4298 | return rValList; | 3980 | return rValList; |
4299 | } | 3981 | } |
4300 | 3982 | ||
4301 | /* | 3983 | // Maybe we have <type>.<name> referencing a static field or method of some type. |
4302 | * Maybe we have <type>.<name> referencing a static field or method of some type. | ||
4303 | */ | ||
4304 | if((token is TokenType) && (token.nextToken is TokenKwDot) && (token.nextToken.nextToken is TokenName)) | 3984 | if((token is TokenType) && (token.nextToken is TokenKwDot) && (token.nextToken.nextToken is TokenName)) |
4305 | { | 3985 | { |
4306 | TokenLValSField field = new TokenLValSField(token.nextToken.nextToken); | 3986 | TokenLValSField field = new TokenLValSField(token.nextToken.nextToken); |
@@ -4310,9 +3990,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
4310 | return field; | 3990 | return field; |
4311 | } | 3991 | } |
4312 | 3992 | ||
4313 | /* | 3993 | // Maybe we have 'this' referring to the object of the instance method. |
4314 | * Maybe we have 'this' referring to the object of the instance method. | ||
4315 | */ | ||
4316 | if(token is TokenKwThis) | 3994 | if(token is TokenKwThis) |
4317 | { | 3995 | { |
4318 | if((currentDeclSDType == null) || !(currentDeclSDType is TokenDeclSDTypeClass)) | 3996 | if((currentDeclSDType == null) || !(currentDeclSDType is TokenDeclSDTypeClass)) |
@@ -4326,9 +4004,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
4326 | return zhis; | 4004 | return zhis; |
4327 | } | 4005 | } |
4328 | 4006 | ||
4329 | /* | 4007 | // Maybe we have 'base' referring to a field/method of the extended class. |
4330 | * Maybe we have 'base' referring to a field/method of the extended class. | ||
4331 | */ | ||
4332 | if(token is TokenKwBase) | 4008 | if(token is TokenKwBase) |
4333 | { | 4009 | { |
4334 | if((currentDeclFunc == null) || (currentDeclFunc.sdtClass == null) || !(currentDeclFunc.sdtClass is TokenDeclSDTypeClass)) | 4010 | if((currentDeclFunc == null) || (currentDeclFunc.sdtClass == null) || !(currentDeclFunc.sdtClass is TokenDeclSDTypeClass)) |
@@ -4351,11 +4027,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
4351 | return baseField; | 4027 | return baseField; |
4352 | } | 4028 | } |
4353 | 4029 | ||
4354 | /* | 4030 | // Maybe we have 'new <script-defined-type>' saying to create an object instance. |
4355 | * Maybe we have 'new <script-defined-type>' saying to create an object instance. | 4031 | // This ends up generating a call to static function <script-defined-type>.$new(...) |
4356 | * This ends up generating a call to static function <script-defined-type>.$new(...) | 4032 | // whose CIL code is generated by GenerateNewobjBody(). |
4357 | * whose CIL code is generated by GenerateNewobjBody(). | ||
4358 | */ | ||
4359 | if(token is TokenKwNew) | 4033 | if(token is TokenKwNew) |
4360 | { | 4034 | { |
4361 | if(!(token.nextToken is TokenType)) | 4035 | if(!(token.nextToken is TokenType)) |
@@ -4371,9 +4045,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
4371 | return field; | 4045 | return field; |
4372 | } | 4046 | } |
4373 | 4047 | ||
4374 | /* | 4048 | // All we got left is <name>, eg, arg, function, global or local variable reference |
4375 | * All we got left is <name>, eg, arg, function, global or local variable reference | ||
4376 | */ | ||
4377 | if(token is TokenName) | 4049 | if(token is TokenName) |
4378 | { | 4050 | { |
4379 | TokenLValName name = new TokenLValName((TokenName)token, tokenScript.variablesStack); | 4051 | TokenLValName name = new TokenLValName((TokenName)token, tokenScript.variablesStack); |
@@ -4381,9 +4053,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
4381 | return name; | 4053 | return name; |
4382 | } | 4054 | } |
4383 | 4055 | ||
4384 | /* | 4056 | // Who knows what it is supposed to be? |
4385 | * Who knows what it is supposed to be? | ||
4386 | */ | ||
4387 | ErrorMsg(token, "invalid operand token"); | 4057 | ErrorMsg(token, "invalid operand token"); |
4388 | token = SkipPastSemi(token); | 4058 | token = SkipPastSemi(token); |
4389 | return null; | 4059 | return null; |
@@ -4398,15 +4068,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
4398 | */ | 4068 | */ |
4399 | private TokenRValCall ParseRValCall(ref Token token, TokenRVal meth) | 4069 | private TokenRValCall ParseRValCall(ref Token token, TokenRVal meth) |
4400 | { | 4070 | { |
4401 | /* | 4071 | // Set up basic function call struct with function name. |
4402 | * Set up basic function call struct with function name. | ||
4403 | */ | ||
4404 | TokenRValCall rValCall = new TokenRValCall(token); | 4072 | TokenRValCall rValCall = new TokenRValCall(token); |
4405 | rValCall.meth = meth; | 4073 | rValCall.meth = meth; |
4406 | 4074 | ||
4407 | /* | 4075 | // Parse the call parameters, if any. |
4408 | * Parse the call parameters, if any. | ||
4409 | */ | ||
4410 | token = token.nextToken; | 4076 | token = token.nextToken; |
4411 | if(token is TokenKwParClose) | 4077 | if(token is TokenKwParClose) |
4412 | { | 4078 | { |
@@ -4747,24 +4413,18 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
4747 | */ | 4413 | */ |
4748 | public TokenDeclSDType InstantiateGeneric(string name, TokenType[] genArgs, ScriptReduce reduce) | 4414 | public TokenDeclSDType InstantiateGeneric(string name, TokenType[] genArgs, ScriptReduce reduce) |
4749 | { | 4415 | { |
4750 | /* | 4416 | // Malloc the struct and give it a name. |
4751 | * Malloc the struct and give it a name. | ||
4752 | */ | ||
4753 | TokenDeclSDType instdecl = this.MakeBlank(new TokenName(this, name)); | 4417 | TokenDeclSDType instdecl = this.MakeBlank(new TokenName(this, name)); |
4754 | 4418 | ||
4755 | /* | 4419 | // If the original had an outer type, then so does the new one. |
4756 | * If the original had an outer type, then so does the new one. | 4420 | // The outer type will never be a generic prototype, eg, if this |
4757 | * The outer type will never be a generic prototype, eg, if this | 4421 | // is 'ValueList' it will always be inside 'Dictionary<string,integer>' |
4758 | * is 'ValueList' it will always be inside 'Dictionary<string,integer>' | 4422 | // not 'Dictionary' at this point. |
4759 | * not 'Dictionary' at this point. | ||
4760 | */ | ||
4761 | if((this.outerSDType != null) && (this.outerSDType.genParams != null)) | 4423 | if((this.outerSDType != null) && (this.outerSDType.genParams != null)) |
4762 | throw new Exception(); | 4424 | throw new Exception(); |
4763 | instdecl.outerSDType = this.outerSDType; | 4425 | instdecl.outerSDType = this.outerSDType; |
4764 | 4426 | ||
4765 | /* | 4427 | // The generic prototype may have stuff like 'public' just before it and we need to copy that too. |
4766 | * The generic prototype may have stuff like 'public' just before it and we need to copy that too. | ||
4767 | */ | ||
4768 | Token prefix; | 4428 | Token prefix; |
4769 | for(prefix = this; (prefix = prefix.prevToken) != null;) | 4429 | for(prefix = this; (prefix = prefix.prevToken) != null;) |
4770 | { | 4430 | { |
@@ -4773,108 +4433,78 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
4773 | } | 4433 | } |
4774 | this.begToken = prefix.nextToken; | 4434 | this.begToken = prefix.nextToken; |
4775 | 4435 | ||
4776 | /* | 4436 | // Splice in a copy of the prefix tokens, just before the beginning token of prototype (this.begToken). |
4777 | * Splice in a copy of the prefix tokens, just before the beginning token of prototype (this.begToken). | ||
4778 | */ | ||
4779 | while((prefix = prefix.nextToken) != this) | 4437 | while((prefix = prefix.nextToken) != this) |
4780 | { | 4438 | { |
4781 | SpliceSourceToken(prefix.CopyToken(prefix)); | 4439 | SpliceSourceToken(prefix.CopyToken(prefix)); |
4782 | } | 4440 | } |
4783 | 4441 | ||
4784 | /* | 4442 | // Splice instantiation (instdecl) in just before the beginning token of prototype (this.begToken). |
4785 | * Splice instantiation (instdecl) in just before the beginning token of prototype (this.begToken). | ||
4786 | */ | ||
4787 | SpliceSourceToken(instdecl); | 4443 | SpliceSourceToken(instdecl); |
4788 | 4444 | ||
4789 | /* | 4445 | // Now for the fun part... Copy the rest of the prototype body to the |
4790 | * Now for the fun part... Copy the rest of the prototype body to the | 4446 | // instantiated body, replacing all generic parameter type tokens with |
4791 | * instantiated body, replacing all generic parameter type tokens with | 4447 | // the corresponding generic argument types. Note that the parameters |
4792 | * the corresponding generic argument types. Note that the parameters | 4448 | // are numbered starting with the outermost so we need the full genArgs |
4793 | * are numbered starting with the outermost so we need the full genArgs | 4449 | // array. Eg if we are doing 'Converter<V=float>' from |
4794 | * array. Eg if we are doing 'Converter<V=float>' from | 4450 | // 'Dictionary<T=string,U=integer>.Converter<V=float>', any V's are |
4795 | * 'Dictionary<T=string,U=integer>.Converter<V=float>', any V's are | 4451 | // numbered [2]. Any [0]s or [1]s should be gone by now but it doesn't |
4796 | * numbered [2]. Any [0]s or [1]s should be gone by now but it doesn't | 4452 | // matter. |
4797 | * matter. | ||
4798 | */ | ||
4799 | int index; | 4453 | int index; |
4800 | Token it, pt; | 4454 | Token it, pt; |
4801 | TokenDeclSDType innerProto = this; | 4455 | TokenDeclSDType innerProto = this; |
4802 | TokenDeclSDType innerInst = instdecl; | 4456 | TokenDeclSDType innerInst = instdecl; |
4803 | for(pt = this; (pt = pt.nextToken) != this.endToken;) | 4457 | for(pt = this; (pt = pt.nextToken) != this.endToken;) |
4804 | { | 4458 | { |
4805 | 4459 | // Coming across a sub-type's declaration involves a deep copy of the | |
4806 | /* | 4460 | // declaration token. Fortunately we are early on in parsing, so there |
4807 | * Coming across a sub-type's declaration involves a deep copy of the | 4461 | // really isn't much to copy: |
4808 | * declaration token. Fortunately we are early on in parsing, so there | 4462 | // 1) short name is the same, eg, doing List of Dictionary<string,integer>.List is same short name as Dictionary<T,U>.List |
4809 | * really isn't much to copy: | 4463 | // if generic, eg doing Converter<W> of Dictionary<T,U>.Converter<W>, we have to manually copy the W as well. |
4810 | * 1) short name is the same, eg, doing List of Dictionary<string,integer>.List is same short name as Dictionary<T,U>.List | 4464 | // 2) outerSDType is transformed from Dictionary<T,U> to Dictionary<string,integer>. |
4811 | * if generic, eg doing Converter<W> of Dictionary<T,U>.Converter<W>, we have to manually copy the W as well. | 4465 | // 3) innerSDTypes is rebuilt when/if we find classes that are inner to this one. |
4812 | * 2) outerSDType is transformed from Dictionary<T,U> to Dictionary<string,integer>. | ||
4813 | * 3) innerSDTypes is rebuilt when/if we find classes that are inner to this one. | ||
4814 | */ | ||
4815 | if(pt is TokenDeclSDType) | 4466 | if(pt is TokenDeclSDType) |
4816 | { | 4467 | { |
4817 | 4468 | // Make a new TokenDeclSDType{Class,Delegate,Interface}. | |
4818 | /* | ||
4819 | * Make a new TokenDeclSDType{Class,Delegate,Interface}. | ||
4820 | */ | ||
4821 | TokenDeclSDType ptSDType = (TokenDeclSDType)pt; | 4469 | TokenDeclSDType ptSDType = (TokenDeclSDType)pt; |
4822 | TokenDeclSDType itSDType = ptSDType.MakeBlank(new TokenName(ptSDType.shortName, ptSDType.shortName.val)); | 4470 | TokenDeclSDType itSDType = ptSDType.MakeBlank(new TokenName(ptSDType.shortName, ptSDType.shortName.val)); |
4823 | 4471 | ||
4824 | /* | 4472 | // Set up the transformed outerSDType. |
4825 | * Set up the transformed outerSDType. | 4473 | // Eg, if we are creating Enumerator of Dictionary<string,integer>.Enumerator, |
4826 | * Eg, if we are creating Enumerator of Dictionary<string,integer>.Enumerator, | 4474 | // innerProto = Dictionary<T,U> and innerInst = Dictionary<string,integer>. |
4827 | * innerProto = Dictionary<T,U> and innerInst = Dictionary<string,integer>. | ||
4828 | */ | ||
4829 | itSDType.outerSDType = innerInst; | 4475 | itSDType.outerSDType = innerInst; |
4830 | 4476 | ||
4831 | /* | 4477 | // This clone is an inner type of its next outer level. |
4832 | * This clone is an inner type of its next outer level. | ||
4833 | */ | ||
4834 | reduce.CatalogSDTypeDecl(itSDType); | 4478 | reduce.CatalogSDTypeDecl(itSDType); |
4835 | 4479 | ||
4836 | /* | 4480 | // We need to manually copy any generic parameters of the class declaration being cloned. |
4837 | * We need to manually copy any generic parameters of the class declaration being cloned. | 4481 | // eg, if we are cloning Converter<W>, this is where the W gets copied. |
4838 | * eg, if we are cloning Converter<W>, this is where the W gets copied. | 4482 | // Since it is an immutable array of strings, just copy the array pointer, if any. |
4839 | * Since it is an immutable array of strings, just copy the array pointer, if any. | ||
4840 | */ | ||
4841 | itSDType.genParams = ptSDType.genParams; | 4483 | itSDType.genParams = ptSDType.genParams; |
4842 | 4484 | ||
4843 | /* | 4485 | // We are now processing tokens for this cloned type declaration. |
4844 | * We are now processing tokens for this cloned type declaration. | ||
4845 | */ | ||
4846 | innerProto = ptSDType; | 4486 | innerProto = ptSDType; |
4847 | innerInst = itSDType; | 4487 | innerInst = itSDType; |
4848 | 4488 | ||
4849 | /* | 4489 | // Splice this clone token in. |
4850 | * Splice this clone token in. | ||
4851 | */ | ||
4852 | it = itSDType; | 4490 | it = itSDType; |
4853 | } | 4491 | } |
4854 | 4492 | ||
4855 | /* | 4493 | // Check for an generic parameter to substitute out. |
4856 | * Check for an generic parameter to substitute out. | ||
4857 | */ | ||
4858 | else if((pt is TokenName) && this.genParams.TryGetValue(((TokenName)pt).val, out index)) | 4494 | else if((pt is TokenName) && this.genParams.TryGetValue(((TokenName)pt).val, out index)) |
4859 | { | 4495 | { |
4860 | it = genArgs[index].CopyToken(pt); | 4496 | it = genArgs[index].CopyToken(pt); |
4861 | } | 4497 | } |
4862 | 4498 | ||
4863 | /* | 4499 | // Everything else is a simple copy. |
4864 | * Everything else is a simple copy. | ||
4865 | */ | ||
4866 | else | 4500 | else |
4867 | it = pt.CopyToken(pt); | 4501 | it = pt.CopyToken(pt); |
4868 | 4502 | ||
4869 | /* | 4503 | // Whatever we came up with, splice it into the source token stream. |
4870 | * Whatever we came up with, splice it into the source token stream. | ||
4871 | */ | ||
4872 | SpliceSourceToken(it); | 4504 | SpliceSourceToken(it); |
4873 | 4505 | ||
4874 | /* | 4506 | // Maybe we just finished copying an inner type definition. |
4875 | * Maybe we just finished copying an inner type definition. | 4507 | // If so, remember where it ends and pop it from the stack. |
4876 | * If so, remember where it ends and pop it from the stack. | ||
4877 | */ | ||
4878 | if(innerProto.endToken == pt) | 4508 | if(innerProto.endToken == pt) |
4879 | { | 4509 | { |
4880 | innerInst.endToken = it; | 4510 | innerInst.endToken = it; |
@@ -4883,9 +4513,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
4883 | } | 4513 | } |
4884 | } | 4514 | } |
4885 | 4515 | ||
4886 | /* | 4516 | // Clone and insert the terminator, either '}' or ';' |
4887 | * Clone and insert the terminator, either '}' or ';' | ||
4888 | */ | ||
4889 | it = pt.CopyToken(pt); | 4517 | it = pt.CopyToken(pt); |
4890 | SpliceSourceToken(it); | 4518 | SpliceSourceToken(it); |
4891 | instdecl.endToken = it; | 4519 | instdecl.endToken = it; |
@@ -5225,16 +4853,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
5225 | 4853 | ||
5226 | if((numVirtFuncs > 0) && (stackedMethods != null)) | 4854 | if((numVirtFuncs > 0) && (stackedMethods != null)) |
5227 | { | 4855 | { |
5228 | 4856 | // Allocate arrays big enough for mine plus type we are extending. | |
5229 | /* | ||
5230 | * Allocate arrays big enough for mine plus type we are extending. | ||
5231 | */ | ||
5232 | vDynMeths = new DynamicMethod[numVirtFuncs]; | 4857 | vDynMeths = new DynamicMethod[numVirtFuncs]; |
5233 | vMethTypes = new Type[numVirtFuncs]; | 4858 | vMethTypes = new Type[numVirtFuncs]; |
5234 | 4859 | ||
5235 | /* | 4860 | // Fill in low parts from type we are extending. |
5236 | * Fill in low parts from type we are extending. | ||
5237 | */ | ||
5238 | if(extends != null) | 4861 | if(extends != null) |
5239 | { | 4862 | { |
5240 | int n = extends.numVirtFuncs; | 4863 | int n = extends.numVirtFuncs; |
@@ -5245,10 +4868,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
5245 | } | 4868 | } |
5246 | } | 4869 | } |
5247 | 4870 | ||
5248 | /* | 4871 | // Fill in high parts with my own methods. |
5249 | * Fill in high parts with my own methods. | 4872 | // Might also overwrite lower ones with 'override' methods. |
5250 | * Might also overwrite lower ones with 'override' methods. | ||
5251 | */ | ||
5252 | foreach(StackedMethod sm in stackedMethods) | 4873 | foreach(StackedMethod sm in stackedMethods) |
5253 | { | 4874 | { |
5254 | int i = sm.methVTI; | 4875 | int i = sm.methVTI; |
@@ -5294,16 +4915,12 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
5294 | 4915 | ||
5295 | public override void DebString(StringBuilder sb) | 4916 | public override void DebString(StringBuilder sb) |
5296 | { | 4917 | { |
5297 | /* | 4918 | // Don't output if array of some type. |
5298 | * Don't output if array of some type. | 4919 | // They will be re-instantiated as referenced by rest of script. |
5299 | * They will be re-instantiated as referenced by rest of script. | ||
5300 | */ | ||
5301 | if(arrayOfType != null) | 4920 | if(arrayOfType != null) |
5302 | return; | 4921 | return; |
5303 | 4922 | ||
5304 | /* | 4923 | // This class name and extended/implemented type declaration. |
5305 | * This class name and extended/implemented type declaration. | ||
5306 | */ | ||
5307 | sb.Append("class "); | 4924 | sb.Append("class "); |
5308 | sb.Append(shortName.val); | 4925 | sb.Append(shortName.val); |
5309 | bool first = true; | 4926 | bool first = true; |
@@ -5321,17 +4938,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
5321 | } | 4938 | } |
5322 | sb.Append(" {"); | 4939 | sb.Append(" {"); |
5323 | 4940 | ||
5324 | /* | 4941 | // Inner type definitions. |
5325 | * Inner type definitions. | ||
5326 | */ | ||
5327 | foreach(TokenDeclSDType subs in innerSDTypes.Values) | 4942 | foreach(TokenDeclSDType subs in innerSDTypes.Values) |
5328 | { | 4943 | { |
5329 | subs.DebString(sb); | 4944 | subs.DebString(sb); |
5330 | } | 4945 | } |
5331 | 4946 | ||
5332 | /* | 4947 | // Members (fields, methods, properties). |
5333 | * Members (fields, methods, properties). | ||
5334 | */ | ||
5335 | foreach(TokenDeclVar memb in members) | 4948 | foreach(TokenDeclVar memb in members) |
5336 | { | 4949 | { |
5337 | if((memb == instFieldInit) || (memb == staticFieldInit)) | 4950 | if((memb == instFieldInit) || (memb == staticFieldInit)) |
@@ -5511,12 +5124,10 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
5511 | { | 5124 | { |
5512 | int nArgs; | 5125 | int nArgs; |
5513 | 5126 | ||
5514 | /* | 5127 | // This happens when the node was restored via ReadFromFile(). |
5515 | * This happens when the node was restored via ReadFromFile(). | 5128 | // It leaves the types in retStr/argStrs for resolution after |
5516 | * It leaves the types in retStr/argStrs for resolution after | 5129 | // all definitions have been read from the object file in case |
5517 | * all definitions have been read from the object file in case | 5130 | // there are forward references. |
5518 | * there are forward references. | ||
5519 | */ | ||
5520 | if(retType == null) | 5131 | if(retType == null) |
5521 | { | 5132 | { |
5522 | retType = MakeTypeToken(retStr); | 5133 | retType = MakeTypeToken(retStr); |
@@ -5531,10 +5142,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
5531 | } | 5142 | } |
5532 | } | 5143 | } |
5533 | 5144 | ||
5534 | /* | 5145 | // Fill in system types from token types. |
5535 | * Fill in system types from token types. | 5146 | // Might as well build the signature strings too from token types. |
5536 | * Might as well build the signature strings too from token types. | ||
5537 | */ | ||
5538 | retSysType = retType.ToSysType(); | 5147 | retSysType = retType.ToSysType(); |
5539 | 5148 | ||
5540 | nArgs = argTypes.Length; | 5149 | nArgs = argTypes.Length; |
@@ -5552,11 +5161,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
5552 | argSig = sb.ToString(); | 5161 | argSig = sb.ToString(); |
5553 | wholeSig = retType.ToString() + argSig; | 5162 | wholeSig = retType.ToString() + argSig; |
5554 | 5163 | ||
5555 | /* | 5164 | // Now we can create a system delegate type from the given |
5556 | * Now we can create a system delegate type from the given | 5165 | // return and argument types. Give it an unique name using |
5557 | * return and argument types. Give it an unique name using | 5166 | // the whole signature string. |
5558 | * the whole signature string. | ||
5559 | */ | ||
5560 | sysType = DelegateCommon.GetType(retSysType, argSysTypes, wholeSig); | 5167 | sysType = DelegateCommon.GetType(retSysType, argSysTypes, wholeSig); |
5561 | } | 5168 | } |
5562 | 5169 | ||
@@ -5570,9 +5177,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
5570 | { | 5177 | { |
5571 | TokenDeclSDTypeDelegate decldel; | 5178 | TokenDeclSDTypeDelegate decldel; |
5572 | 5179 | ||
5573 | /* | 5180 | // Name it after the whole signature string. |
5574 | * Name it after the whole signature string. | ||
5575 | */ | ||
5576 | StringBuilder sb = new StringBuilder("$inline"); | 5181 | StringBuilder sb = new StringBuilder("$inline"); |
5577 | sb.Append(retType.ToString()); | 5182 | sb.Append(retType.ToString()); |
5578 | sb.Append("("); | 5183 | sb.Append("("); |
@@ -5588,10 +5193,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
5588 | string inlname = sb.ToString(); | 5193 | string inlname = sb.ToString(); |
5589 | if(!inlines.TryGetValue(inlname, out decldel)) | 5194 | if(!inlines.TryGetValue(inlname, out decldel)) |
5590 | { | 5195 | { |
5591 | 5196 | // Create the corresponding declaration and link to it | |
5592 | /* | ||
5593 | * Create the corresponding declaration and link to it | ||
5594 | */ | ||
5595 | TokenName name = new TokenName(null, inlname); | 5197 | TokenName name = new TokenName(null, inlname); |
5596 | decldel = new TokenDeclSDTypeDelegate(name); | 5198 | decldel = new TokenDeclSDTypeDelegate(name); |
5597 | decldel.retType = retType; | 5199 | decldel.retType = retType; |
@@ -5860,9 +5462,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
5860 | { | 5462 | { |
5861 | TokenDeclSDTypeDelegate decldel; | 5463 | TokenDeclSDTypeDelegate decldel; |
5862 | 5464 | ||
5863 | /* | 5465 | // See if we already have a matching declared one cataloged. |
5864 | * See if we already have a matching declared one cataloged. | ||
5865 | */ | ||
5866 | int nArgs = argTypes.Length; | 5466 | int nArgs = argTypes.Length; |
5867 | foreach(TokenDeclSDType decl in tokenScript.sdSrcTypesValues) | 5467 | foreach(TokenDeclSDType decl in tokenScript.sdSrcTypesValues) |
5868 | { | 5468 | { |
@@ -5886,9 +5486,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
5886 | ; | 5486 | ; |
5887 | } | 5487 | } |
5888 | 5488 | ||
5889 | /* | 5489 | // No such luck, create a new anonymous declaration. |
5890 | * No such luck, create a new anonymous declaration. | ||
5891 | */ | ||
5892 | StringBuilder sb = new StringBuilder("$anondel$"); | 5490 | StringBuilder sb = new StringBuilder("$anondel$"); |
5893 | sb.Append(retType.ToString()); | 5491 | sb.Append(retType.ToString()); |
5894 | sb.Append("("); | 5492 | sb.Append("("); |
@@ -6309,50 +5907,36 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
6309 | */ | 5907 | */ |
6310 | public bool IsFuncTrivial(ScriptCodeGen scg) | 5908 | public bool IsFuncTrivial(ScriptCodeGen scg) |
6311 | { | 5909 | { |
6312 | /* | 5910 | // If not really a function, assume it's a delegate. |
6313 | * If not really a function, assume it's a delegate. | 5911 | // And since we don't really know what functions it can point to, |
6314 | * And since we don't really know what functions it can point to, | 5912 | // assume it can point to a non-trivial one. |
6315 | * assume it can point to a non-trivial one. | ||
6316 | */ | ||
6317 | if(retType == null) | 5913 | if(retType == null) |
6318 | return false; | 5914 | return false; |
6319 | 5915 | ||
6320 | /* | 5916 | // All virtual functions are non-trivial because although a particular |
6321 | * All virtual functions are non-trivial because although a particular | 5917 | // one might be trivial, it might be overidden with a non-trivial one. |
6322 | * one might be trivial, it might be overidden with a non-trivial one. | ||
6323 | */ | ||
6324 | if((sdtFlags & (ScriptReduce.SDT_ABSTRACT | ScriptReduce.SDT_OVERRIDE | | 5918 | if((sdtFlags & (ScriptReduce.SDT_ABSTRACT | ScriptReduce.SDT_OVERRIDE | |
6325 | ScriptReduce.SDT_VIRTUAL)) != 0) | 5919 | ScriptReduce.SDT_VIRTUAL)) != 0) |
6326 | { | 5920 | { |
6327 | return false; | 5921 | return false; |
6328 | } | 5922 | } |
6329 | 5923 | ||
6330 | /* | 5924 | // Check the triviality status of the function. |
6331 | * Check the triviality status of the function. | ||
6332 | */ | ||
6333 | switch(triviality) | 5925 | switch(triviality) |
6334 | { | 5926 | { |
6335 | 5927 | // Don't yet know if it is trivial. | |
6336 | /* | 5928 | // We know at this point it doesn't have any direct looping. |
6337 | * Don't yet know if it is trivial. | 5929 | // But if it calls something that has loops, it isn't trivial. |
6338 | * We know at this point it doesn't have any direct looping. | 5930 | // Otherwise it is trivial. |
6339 | * But if it calls something that has loops, it isn't trivial. | ||
6340 | * Otherwise it is trivial. | ||
6341 | */ | ||
6342 | case Triviality.unknown: | 5931 | case Triviality.unknown: |
6343 | { | 5932 | { |
6344 | 5933 | // Mark that we are analyzing this function now. So if there are | |
6345 | /* | 5934 | // any recursive call loops, that will show that the function is |
6346 | * Mark that we are analyzing this function now. So if there are | 5935 | // non-trivial and the analysis will terminate at that point. |
6347 | * any recursive call loops, that will show that the function is | ||
6348 | * non-trivial and the analysis will terminate at that point. | ||
6349 | */ | ||
6350 | triviality = Triviality.analyzing; | 5936 | triviality = Triviality.analyzing; |
6351 | 5937 | ||
6352 | /* | 5938 | // Check out everything else this function calls. If any say they |
6353 | * Check out everything else this function calls. If any say they | 5939 | // aren't trivial, then we say this function isn't trivial. |
6354 | * aren't trivial, then we say this function isn't trivial. | ||
6355 | */ | ||
6356 | foreach(TokenRValCall call in unknownTrivialityCalls) | 5940 | foreach(TokenRValCall call in unknownTrivialityCalls) |
6357 | { | 5941 | { |
6358 | if(!call.IsRValTrivial(scg, null)) | 5942 | if(!call.IsRValTrivial(scg, null)) |
@@ -6362,28 +5946,22 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
6362 | } | 5946 | } |
6363 | } | 5947 | } |
6364 | 5948 | ||
6365 | /* | 5949 | // All functions called by this function are trivial, and this |
6366 | * All functions called by this function are trivial, and this | 5950 | // function's code doesn't have any loops, so we can mark this |
6367 | * function's code doesn't have any loops, so we can mark this | 5951 | // function as being trivial. |
6368 | * function as being trivial. | ||
6369 | */ | ||
6370 | triviality = Triviality.trivial; | 5952 | triviality = Triviality.trivial; |
6371 | return true; | 5953 | return true; |
6372 | } | 5954 | } |
6373 | 5955 | ||
6374 | /* | 5956 | // We already know that it is trivial. |
6375 | * We already know that it is trivial. | ||
6376 | */ | ||
6377 | case Triviality.trivial: | 5957 | case Triviality.trivial: |
6378 | { | 5958 | { |
6379 | return true; | 5959 | return true; |
6380 | } | 5960 | } |
6381 | 5961 | ||
6382 | /* | 5962 | // We either know it is complex or are trying to analyze it already. |
6383 | * We either know it is complex or are trying to analyze it already. | 5963 | // If we are already analyzing it, it means it has a recursive loop |
6384 | * If we are already analyzing it, it means it has a recursive loop | 5964 | // and we assume those are non-trivial. |
6385 | * and we assume those are non-trivial. | ||
6386 | */ | ||
6387 | default: | 5965 | default: |
6388 | return false; | 5966 | return false; |
6389 | } | 5967 | } |
@@ -6450,22 +6028,15 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
6450 | 6028 | ||
6451 | for(Token stmt = body.statements; stmt != null; stmt = stmt.nextToken) | 6029 | for(Token stmt = body.statements; stmt != null; stmt = stmt.nextToken) |
6452 | { | 6030 | { |
6453 | 6031 | // Body of the function should all be arithmetic statements (not eg for loops, if statements etc). | |
6454 | /* | ||
6455 | * Body of the function should all be arithmetic statements (not eg for loops, if statements etc). | ||
6456 | */ | ||
6457 | TokenRVal rval = ((TokenStmtRVal)stmt).rVal; | 6032 | TokenRVal rval = ((TokenStmtRVal)stmt).rVal; |
6458 | 6033 | ||
6459 | /* | 6034 | // And the opcode should be a simple assignment operator. |
6460 | * And the opcode should be a simple assignment operator. | ||
6461 | */ | ||
6462 | TokenRValOpBin rvob = (TokenRValOpBin)rval; | 6035 | TokenRValOpBin rvob = (TokenRValOpBin)rval; |
6463 | if(!(rvob.opcode is TokenKwAssign)) | 6036 | if(!(rvob.opcode is TokenKwAssign)) |
6464 | throw new Exception("bad op type " + rvob.opcode.GetType().Name); | 6037 | throw new Exception("bad op type " + rvob.opcode.GetType().Name); |
6465 | 6038 | ||
6466 | /* | 6039 | // Get field or variable being assigned to. |
6467 | * Get field or variable being assigned to. | ||
6468 | */ | ||
6469 | TokenDeclVar var = null; | 6040 | TokenDeclVar var = null; |
6470 | TokenRVal left = rvob.rValLeft; | 6041 | TokenRVal left = rvob.rValLeft; |
6471 | if(left is TokenLValIField) | 6042 | if(left is TokenLValIField) |
@@ -6490,28 +6061,22 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
6490 | if(var == null) | 6061 | if(var == null) |
6491 | throw new Exception("unknown var type " + left.GetType().Name); | 6062 | throw new Exception("unknown var type " + left.GetType().Name); |
6492 | 6063 | ||
6493 | /* | 6064 | // Output flags, type name and bare variable name. |
6494 | * Output flags, type name and bare variable name. | 6065 | // This should look like a declaration in the 'sb' |
6495 | * This should look like a declaration in the 'sb' | 6066 | // as it is not enclosed in a function. |
6496 | * as it is not enclosed in a function. | ||
6497 | */ | ||
6498 | var.DebStringSDTFlags(sb); | 6067 | var.DebStringSDTFlags(sb); |
6499 | var.type.DebString(sb); | 6068 | var.type.DebString(sb); |
6500 | sb.Append(' '); | 6069 | sb.Append(' '); |
6501 | sb.Append(var.name.val); | 6070 | sb.Append(var.name.val); |
6502 | 6071 | ||
6503 | /* | 6072 | // Maybe it has a non-default initialization value. |
6504 | * Maybe it has a non-default initialization value. | ||
6505 | */ | ||
6506 | if((var.init != null) && !(var.init is TokenRValInitDef)) | 6073 | if((var.init != null) && !(var.init is TokenRValInitDef)) |
6507 | { | 6074 | { |
6508 | sb.Append(" = "); | 6075 | sb.Append(" = "); |
6509 | var.init.DebString(sb); | 6076 | var.init.DebString(sb); |
6510 | } | 6077 | } |
6511 | 6078 | ||
6512 | /* | 6079 | // End of declaration statement. |
6513 | * End of declaration statement. | ||
6514 | */ | ||
6515 | sb.Append(';'); | 6080 | sb.Append(';'); |
6516 | } | 6081 | } |
6517 | } | 6082 | } |
@@ -6578,17 +6143,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
6578 | { | 6143 | { |
6579 | TokenType baseType = baseRVal.GetRValType(scg, null); | 6144 | TokenType baseType = baseRVal.GetRValType(scg, null); |
6580 | 6145 | ||
6581 | /* | 6146 | // Maybe referencing element of a fixed-dimension array. |
6582 | * Maybe referencing element of a fixed-dimension array. | ||
6583 | */ | ||
6584 | if((baseType is TokenTypeSDTypeClass) && (((TokenTypeSDTypeClass)baseType).decl.arrayOfType != null)) | 6147 | if((baseType is TokenTypeSDTypeClass) && (((TokenTypeSDTypeClass)baseType).decl.arrayOfType != null)) |
6585 | { | 6148 | { |
6586 | return ((TokenTypeSDTypeClass)baseType).decl.arrayOfType; | 6149 | return ((TokenTypeSDTypeClass)baseType).decl.arrayOfType; |
6587 | } | 6150 | } |
6588 | 6151 | ||
6589 | /* | 6152 | // Maybe referencing $idxprop property of script-defined class or interface. |
6590 | * Maybe referencing $idxprop property of script-defined class or interface. | ||
6591 | */ | ||
6592 | if(baseType is TokenTypeSDTypeClass) | 6153 | if(baseType is TokenTypeSDTypeClass) |
6593 | { | 6154 | { |
6594 | TokenDeclSDTypeClass sdtDecl = ((TokenTypeSDTypeClass)baseType).decl; | 6155 | TokenDeclSDTypeClass sdtDecl = ((TokenTypeSDTypeClass)baseType).decl; |
@@ -6604,17 +6165,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
6604 | return idxProp.type; | 6165 | return idxProp.type; |
6605 | } | 6166 | } |
6606 | 6167 | ||
6607 | /* | 6168 | // Maybe referencing single character of a string. |
6608 | * Maybe referencing single character of a string. | ||
6609 | */ | ||
6610 | if((baseType is TokenTypeKey) || (baseType is TokenTypeStr)) | 6169 | if((baseType is TokenTypeKey) || (baseType is TokenTypeStr)) |
6611 | { | 6170 | { |
6612 | return new TokenTypeChar(this); | 6171 | return new TokenTypeChar(this); |
6613 | } | 6172 | } |
6614 | 6173 | ||
6615 | /* | 6174 | // Assume XMR_Array element or extracting element from list. |
6616 | * Assume XMR_Array element or extracting element from list. | ||
6617 | */ | ||
6618 | if((baseType is TokenTypeArray) || (baseType is TokenTypeList)) | 6175 | if((baseType is TokenTypeArray) || (baseType is TokenTypeList)) |
6619 | { | 6176 | { |
6620 | return new TokenTypeObject(this); | 6177 | return new TokenTypeObject(this); |
@@ -6714,19 +6271,15 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
6714 | 6271 | ||
6715 | public override bool IsRValTrivial(ScriptCodeGen scg, TokenType[] argsig) | 6272 | public override bool IsRValTrivial(ScriptCodeGen scg, TokenType[] argsig) |
6716 | { | 6273 | { |
6717 | /* | 6274 | // If getting pointer to instance isn't trivial, then accessing the member isn't trivial either. |
6718 | * If getting pointer to instance isn't trivial, then accessing the member isn't trivial either. | ||
6719 | */ | ||
6720 | if(!baseRVal.IsRValTrivial(scg, null)) | 6275 | if(!baseRVal.IsRValTrivial(scg, null)) |
6721 | return false; | 6276 | return false; |
6722 | 6277 | ||
6723 | /* | 6278 | // Accessing a member of a class depends on the member. |
6724 | * Accessing a member of a class depends on the member. | 6279 | // In the case of a method, this is accessing it as a delegate, not calling it, and |
6725 | * In the case of a method, this is accessing it as a delegate, not calling it, and | 6280 | // argsig simply serves as selecting which of possibly overloaded methods to select. |
6726 | * argsig simply serves as selecting which of possibly overloaded methods to select. | 6281 | // The case of accessing a property, however, depends on the property implementation, |
6727 | * The case of accessing a property, however, depends on the property implementation, | 6282 | // as there could be looping inside the property code. |
6728 | * as there could be looping inside the property code. | ||
6729 | */ | ||
6730 | TokenType baseType = baseRVal.GetRValType(scg, null); | 6283 | TokenType baseType = baseRVal.GetRValType(scg, null); |
6731 | if(baseType is TokenTypeSDTypeClass) | 6284 | if(baseType is TokenTypeSDTypeClass) |
6732 | { | 6285 | { |
@@ -6734,9 +6287,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
6734 | return (var != null) && var.IsVarTrivial(scg); | 6287 | return (var != null) && var.IsVarTrivial(scg); |
6735 | } | 6288 | } |
6736 | 6289 | ||
6737 | /* | 6290 | // Accessing the members of anything else (arrays, rotations, vectors) is always trivial. |
6738 | * Accessing the members of anything else (arrays, rotations, vectors) is always trivial. | ||
6739 | */ | ||
6740 | return true; | 6291 | return true; |
6741 | } | 6292 | } |
6742 | 6293 | ||
@@ -6748,15 +6299,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
6748 | */ | 6299 | */ |
6749 | public override bool IsCallTrivial(ScriptCodeGen scg, TokenType[] argsig) | 6300 | public override bool IsCallTrivial(ScriptCodeGen scg, TokenType[] argsig) |
6750 | { | 6301 | { |
6751 | /* | 6302 | // If getting pointer to instance isn't trivial, then calling the method isn't trivial either. |
6752 | * If getting pointer to instance isn't trivial, then calling the method isn't trivial either. | ||
6753 | */ | ||
6754 | if(!baseRVal.IsRValTrivial(scg, null)) | 6303 | if(!baseRVal.IsRValTrivial(scg, null)) |
6755 | return false; | 6304 | return false; |
6756 | 6305 | ||
6757 | /* | 6306 | // Calling a method of a class depends on the method. |
6758 | * Calling a method of a class depends on the method. | ||
6759 | */ | ||
6760 | TokenType baseType = baseRVal.GetRValType(scg, null); | 6307 | TokenType baseType = baseRVal.GetRValType(scg, null); |
6761 | if(baseType is TokenTypeSDTypeClass) | 6308 | if(baseType is TokenTypeSDTypeClass) |
6762 | { | 6309 | { |
@@ -6764,21 +6311,17 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
6764 | return (var != null) && var.IsFuncTrivial(scg); | 6311 | return (var != null) && var.IsFuncTrivial(scg); |
6765 | } | 6312 | } |
6766 | 6313 | ||
6767 | /* | 6314 | // Calling via a pointer to an interface instance is never trivial. |
6768 | * Calling via a pointer to an interface instance is never trivial. | 6315 | // (It is really a pointer to an array of delegates). |
6769 | * (It is really a pointer to an array of delegates). | 6316 | // We can't tell for this call site whether the actual method being called is trivial or not, |
6770 | * We can't tell for this call site whether the actual method being called is trivial or not, | 6317 | // so we have to assume it isn't. |
6771 | * so we have to assume it isn't. | 6318 | // ??? We could theoretically check to see if *all* implementations of this method of |
6772 | * ??? We could theoretically check to see if *all* implementations of this method of | 6319 | // this interface are trivial, then we could conclude that this call is trivial. |
6773 | * this interface are trivial, then we could conclude that this call is trivial. | ||
6774 | */ | ||
6775 | if(baseType is TokenTypeSDTypeInterface) | 6320 | if(baseType is TokenTypeSDTypeInterface) |
6776 | return false; | 6321 | return false; |
6777 | 6322 | ||
6778 | /* | 6323 | // Calling a method of anything else (arrays, rotations, vectors) is always trivial. |
6779 | * Calling a method of anything else (arrays, rotations, vectors) is always trivial. | 6324 | // Even methods of delegates, such as ".GetArgTypes()" that we may someday do is trivial. |
6780 | * Even methods of delegates, such as ".GetArgTypes()" that we may someday do is trivial. | ||
6781 | */ | ||
6782 | return true; | 6325 | return true; |
6783 | } | 6326 | } |
6784 | 6327 | ||
@@ -6801,23 +6344,19 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
6801 | 6344 | ||
6802 | public TokenLValName(TokenName name, VarDict stack) : base(name) | 6345 | public TokenLValName(TokenName name, VarDict stack) : base(name) |
6803 | { | 6346 | { |
6804 | /* | 6347 | // Save name of variable/method/function/field. |
6805 | * Save name of variable/method/function/field. | ||
6806 | */ | ||
6807 | this.name = name; | 6348 | this.name = name; |
6808 | 6349 | ||
6809 | /* | 6350 | // Save where in the stack it can be looked up. |
6810 | * Save where in the stack it can be looked up. | 6351 | // If the current stack is for locals, do not allow forward references. |
6811 | * If the current stack is for locals, do not allow forward references. | 6352 | // this allows idiocy like: |
6812 | * this allows idiocy like: | 6353 | // list buttons = [ 1, 2, 3 ]; |
6813 | * list buttons = [ 1, 2, 3 ]; | 6354 | // x () { |
6814 | * x () { | 6355 | // list buttons = llList2List (buttons, 0, 1); |
6815 | * list buttons = llList2List (buttons, 0, 1); | 6356 | // llOwnerSay (llList2CSV (buttons)); |
6816 | * llOwnerSay (llList2CSV (buttons)); | 6357 | // } |
6817 | * } | 6358 | // If it is not locals, allow forward references. |
6818 | * If it is not locals, allow forward references. | 6359 | // this allows function X() to call Y() and Y() to call X(). |
6819 | * this allows function X() to call Y() and Y() to call X(). | ||
6820 | */ | ||
6821 | this.stack = stack.FreezeLocals(); | 6360 | this.stack = stack.FreezeLocals(); |
6822 | } | 6361 | } |
6823 | 6362 | ||
@@ -6879,22 +6418,18 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
6879 | 6418 | ||
6880 | public override bool IsRValTrivial(ScriptCodeGen scg, TokenType[] argsig) | 6419 | public override bool IsRValTrivial(ScriptCodeGen scg, TokenType[] argsig) |
6881 | { | 6420 | { |
6882 | /* | 6421 | // Accessing a member of a class depends on the member. |
6883 | * Accessing a member of a class depends on the member. | 6422 | // In the case of a method, this is accessing it as a delegate, not calling it, and |
6884 | * In the case of a method, this is accessing it as a delegate, not calling it, and | 6423 | // argsig simply serves as selecting which of possibly overloaded methods to select. |
6885 | * argsig simply serves as selecting which of possibly overloaded methods to select. | 6424 | // The case of accessing a property, however, depends on the property implementation, |
6886 | * The case of accessing a property, however, depends on the property implementation, | 6425 | // as there could be looping inside the property code. |
6887 | * as there could be looping inside the property code. | ||
6888 | */ | ||
6889 | if(baseType is TokenTypeSDTypeClass) | 6426 | if(baseType is TokenTypeSDTypeClass) |
6890 | { | 6427 | { |
6891 | TokenDeclVar var = scg.FindThisMember((TokenTypeSDTypeClass)baseType, fieldName, argsig); | 6428 | TokenDeclVar var = scg.FindThisMember((TokenTypeSDTypeClass)baseType, fieldName, argsig); |
6892 | return (var != null) && var.IsVarTrivial(scg); | 6429 | return (var != null) && var.IsVarTrivial(scg); |
6893 | } | 6430 | } |
6894 | 6431 | ||
6895 | /* | 6432 | // Accessing the fields/methods/properties of anything else (arrays, rotations, vectors) is always trivial. |
6896 | * Accessing the fields/methods/properties of anything else (arrays, rotations, vectors) is always trivial. | ||
6897 | */ | ||
6898 | return true; | 6433 | return true; |
6899 | } | 6434 | } |
6900 | 6435 | ||
@@ -6906,18 +6441,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
6906 | */ | 6441 | */ |
6907 | public override bool IsCallTrivial(ScriptCodeGen scg, TokenType[] argsig) | 6442 | public override bool IsCallTrivial(ScriptCodeGen scg, TokenType[] argsig) |
6908 | { | 6443 | { |
6909 | /* | 6444 | // Calling a static method of a class depends on the method. |
6910 | * Calling a static method of a class depends on the method. | ||
6911 | */ | ||
6912 | if(baseType is TokenTypeSDTypeClass) | 6445 | if(baseType is TokenTypeSDTypeClass) |
6913 | { | 6446 | { |
6914 | TokenDeclVar var = scg.FindThisMember((TokenTypeSDTypeClass)baseType, fieldName, argsig); | 6447 | TokenDeclVar var = scg.FindThisMember((TokenTypeSDTypeClass)baseType, fieldName, argsig); |
6915 | return (var != null) && var.IsFuncTrivial(scg); | 6448 | return (var != null) && var.IsFuncTrivial(scg); |
6916 | } | 6449 | } |
6917 | 6450 | ||
6918 | /* | 6451 | // Calling a static method of anything else (arrays, rotations, vectors) is always trivial. |
6919 | * Calling a static method of anything else (arrays, rotations, vectors) is always trivial. | ||
6920 | */ | ||
6921 | return true; | 6452 | return true; |
6922 | } | 6453 | } |
6923 | 6454 | ||
@@ -7075,9 +6606,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
7075 | */ | 6606 | */ |
7076 | public override TokenType GetRValType(ScriptCodeGen scg, TokenType[] argsig) | 6607 | public override TokenType GetRValType(ScriptCodeGen scg, TokenType[] argsig) |
7077 | { | 6608 | { |
7078 | /* | 6609 | // Build type signature so we select correct overloaded function. |
7079 | * Build type signature so we select correct overloaded function. | ||
7080 | */ | ||
7081 | if(myArgSig == null) | 6610 | if(myArgSig == null) |
7082 | { | 6611 | { |
7083 | myArgSig = new TokenType[nArgs]; | 6612 | myArgSig = new TokenType[nArgs]; |
@@ -7088,9 +6617,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
7088 | } | 6617 | } |
7089 | } | 6618 | } |
7090 | 6619 | ||
7091 | /* | 6620 | // Get the type of the method itself. This should get us a delegate type. |
7092 | * Get the type of the method itself. This should get us a delegate type. | ||
7093 | */ | ||
7094 | TokenType delType = meth.GetRValType(scg, myArgSig); | 6621 | TokenType delType = meth.GetRValType(scg, myArgSig); |
7095 | if(!(delType is TokenTypeSDTypeDelegate)) | 6622 | if(!(delType is TokenTypeSDTypeDelegate)) |
7096 | { | 6623 | { |
@@ -7098,9 +6625,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
7098 | return new TokenTypeVoid(meth); | 6625 | return new TokenTypeVoid(meth); |
7099 | } | 6626 | } |
7100 | 6627 | ||
7101 | /* | 6628 | // Get the return type from the delegate type. |
7102 | * Get the return type from the delegate type. | ||
7103 | */ | ||
7104 | return ((TokenTypeSDTypeDelegate)delType).decl.GetRetType(); | 6629 | return ((TokenTypeSDTypeDelegate)delType).decl.GetRetType(); |
7105 | } | 6630 | } |
7106 | 6631 | ||
@@ -7112,9 +6637,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
7112 | */ | 6637 | */ |
7113 | public override bool IsRValTrivial(ScriptCodeGen scg, TokenType[] argsig) | 6638 | public override bool IsRValTrivial(ScriptCodeGen scg, TokenType[] argsig) |
7114 | { | 6639 | { |
7115 | /* | 6640 | // Build type signature so we select correct overloaded function. |
7116 | * Build type signature so we select correct overloaded function. | ||
7117 | */ | ||
7118 | if(myArgSig == null) | 6641 | if(myArgSig == null) |
7119 | { | 6642 | { |
7120 | myArgSig = new TokenType[nArgs]; | 6643 | myArgSig = new TokenType[nArgs]; |
@@ -7125,18 +6648,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
7125 | } | 6648 | } |
7126 | } | 6649 | } |
7127 | 6650 | ||
7128 | /* | 6651 | // Make sure all arguments can be computed trivially. |
7129 | * Make sure all arguments can be computed trivially. | ||
7130 | */ | ||
7131 | for(Token t = args; t != null; t = t.nextToken) | 6652 | for(Token t = args; t != null; t = t.nextToken) |
7132 | { | 6653 | { |
7133 | if(!((TokenRVal)t).IsRValTrivial(scg, null)) | 6654 | if(!((TokenRVal)t).IsRValTrivial(scg, null)) |
7134 | return false; | 6655 | return false; |
7135 | } | 6656 | } |
7136 | 6657 | ||
7137 | /* | 6658 | // See if the function call itself and the function body are trivial. |
7138 | * See if the function call itself and the function body are trivial. | ||
7139 | */ | ||
7140 | return meth.IsCallTrivial(scg, myArgSig); | 6659 | return meth.IsCallTrivial(scg, myArgSig); |
7141 | } | 6660 | } |
7142 | 6661 | ||
@@ -7717,9 +7236,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
7717 | 7236 | ||
7718 | public override TokenType GetRValType(ScriptCodeGen scg, TokenType[] argsig) | 7237 | public override TokenType GetRValType(ScriptCodeGen scg, TokenType[] argsig) |
7719 | { | 7238 | { |
7720 | /* | 7239 | // Comparisons and the like always return bool. |
7721 | * Comparisons and the like always return bool. | ||
7722 | */ | ||
7723 | string opstr = opcode.ToString(); | 7240 | string opstr = opcode.ToString(); |
7724 | if((opstr == "==") || (opstr == "!=") || (opstr == ">=") || (opstr == ">") || | 7241 | if((opstr == "==") || (opstr == "!=") || (opstr == ">=") || (opstr == ">") || |
7725 | (opstr == "&&") || (opstr == "||") || (opstr == "<=") || (opstr == "<") || | 7242 | (opstr == "&&") || (opstr == "||") || (opstr == "<=") || (opstr == "<") || |
@@ -7728,25 +7245,19 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
7728 | return new TokenTypeBool(opcode); | 7245 | return new TokenTypeBool(opcode); |
7729 | } | 7246 | } |
7730 | 7247 | ||
7731 | /* | 7248 | // Comma is always type of right-hand operand. |
7732 | * Comma is always type of right-hand operand. | ||
7733 | */ | ||
7734 | if(opstr == ",") | 7249 | if(opstr == ",") |
7735 | return rValRight.GetRValType(scg, argsig); | 7250 | return rValRight.GetRValType(scg, argsig); |
7736 | 7251 | ||
7737 | /* | 7252 | // Assignments are always the type of the left-hand operand, |
7738 | * Assignments are always the type of the left-hand operand, | 7253 | // including stuff like "+=". |
7739 | * including stuff like "+=". | ||
7740 | */ | ||
7741 | if(opstr.EndsWith("=")) | 7254 | if(opstr.EndsWith("=")) |
7742 | { | 7255 | { |
7743 | return rValLeft.GetRValType(scg, argsig); | 7256 | return rValLeft.GetRValType(scg, argsig); |
7744 | } | 7257 | } |
7745 | 7258 | ||
7746 | /* | 7259 | // string+something or something+string is always string. |
7747 | * string+something or something+string is always string. | 7260 | // except list+something or something+list is always a list. |
7748 | * except list+something or something+list is always a list. | ||
7749 | */ | ||
7750 | string lType = rValLeft.GetRValType(scg, argsig).ToString(); | 7261 | string lType = rValLeft.GetRValType(scg, argsig).ToString(); |
7751 | string rType = rValRight.GetRValType(scg, argsig).ToString(); | 7262 | string rType = rValRight.GetRValType(scg, argsig).ToString(); |
7752 | if((opstr == "+") && ((lType == "list") || (rType == "list"))) | 7263 | if((opstr == "+") && ((lType == "list") || (rType == "list"))) |
@@ -7759,9 +7270,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
7759 | return new TokenTypeStr(opcode); | 7270 | return new TokenTypeStr(opcode); |
7760 | } | 7271 | } |
7761 | 7272 | ||
7762 | /* | 7273 | // Everything else depends on both operands. |
7763 | * Everything else depends on both operands. | ||
7764 | */ | ||
7765 | string key = lType + opstr + rType; | 7274 | string key = lType + opstr + rType; |
7766 | BinOpStr binOpStr; | 7275 | BinOpStr binOpStr; |
7767 | if(BinOpStr.defined.TryGetValue(key, out binOpStr)) | 7276 | if(BinOpStr.defined.TryGetValue(key, out binOpStr)) |
@@ -8234,7 +7743,6 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
8234 | */ | 7743 | */ |
8235 | public class TokenStmtBlock: TokenStmt | 7744 | public class TokenStmtBlock: TokenStmt |
8236 | { | 7745 | { |
8237 | |||
8238 | public Token statements; // null-terminated list of statements, can also have TokenDeclVar's in here | 7746 | public Token statements; // null-terminated list of statements, can also have TokenDeclVar's in here |
8239 | public TokenStmtBlock outerStmtBlock; // next outer stmtBlock or null if top-level, ie, function definition | 7747 | public TokenStmtBlock outerStmtBlock; // next outer stmtBlock or null if top-level, ie, function definition |
8240 | public TokenDeclVar function; // function it is part of | 7748 | public TokenDeclVar function; // function it is part of |
@@ -8262,7 +7770,6 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
8262 | */ | 7770 | */ |
8263 | public class TokenStmtLabel: TokenStmt | 7771 | public class TokenStmtLabel: TokenStmt |
8264 | { | 7772 | { |
8265 | |||
8266 | public TokenName name; // the label's name | 7773 | public TokenName name; // the label's name |
8267 | public TokenStmtBlock block; // which block it is defined in | 7774 | public TokenStmtBlock block; // which block it is defined in |
8268 | public bool hasBkwdRefs = false; | 7775 | public bool hasBkwdRefs = false; |
@@ -8437,7 +7944,6 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
8437 | 7944 | ||
8438 | public class TokenStmtNull: TokenStmt | 7945 | public class TokenStmtNull: TokenStmt |
8439 | { | 7946 | { |
8440 | |||
8441 | public TokenStmtNull(Token original) : base(original) { } | 7947 | public TokenStmtNull(Token original) : base(original) { } |
8442 | 7948 | ||
8443 | public override void DebString(StringBuilder sb) | 7949 | public override void DebString(StringBuilder sb) |
@@ -8448,7 +7954,6 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
8448 | 7954 | ||
8449 | public class TokenStmtRet: TokenStmt | 7955 | public class TokenStmtRet: TokenStmt |
8450 | { | 7956 | { |
8451 | |||
8452 | public TokenRVal rVal; // null if void | 7957 | public TokenRVal rVal; // null if void |
8453 | 7958 | ||
8454 | public TokenStmtRet(Token original) : base(original) { } | 7959 | public TokenStmtRet(Token original) : base(original) { } |
@@ -8470,7 +7975,6 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
8470 | */ | 7975 | */ |
8471 | public class TokenStmtState: TokenStmt | 7976 | public class TokenStmtState: TokenStmt |
8472 | { | 7977 | { |
8473 | |||
8474 | public TokenName state; // null for default | 7978 | public TokenName state; // null for default |
8475 | 7979 | ||
8476 | public TokenStmtState(Token original) : base(original) { } | 7980 | public TokenStmtState(Token original) : base(original) { } |
@@ -8488,7 +7992,6 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
8488 | */ | 7992 | */ |
8489 | public class TokenStmtSwitch: TokenStmt | 7993 | public class TokenStmtSwitch: TokenStmt |
8490 | { | 7994 | { |
8491 | |||
8492 | public TokenRValParen testRVal; // the integer index expression | 7995 | public TokenRValParen testRVal; // the integer index expression |
8493 | public TokenSwitchCase cases = null; // list of all cases, linked by .nextCase | 7996 | public TokenSwitchCase cases = null; // list of all cases, linked by .nextCase |
8494 | public TokenSwitchCase lastCase = null; // used during reduce to point to last in 'cases' list | 7997 | public TokenSwitchCase lastCase = null; // used during reduce to point to last in 'cases' list |
@@ -8558,7 +8061,6 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
8558 | 8061 | ||
8559 | public class TokenStmtThrow: TokenStmt | 8062 | public class TokenStmtThrow: TokenStmt |
8560 | { | 8063 | { |
8561 | |||
8562 | public TokenRVal rVal; // null if rethrow style | 8064 | public TokenRVal rVal; // null if rethrow style |
8563 | 8065 | ||
8564 | public TokenStmtThrow(Token original) : base(original) { } | 8066 | public TokenStmtThrow(Token original) : base(original) { } |
@@ -8576,7 +8078,6 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
8576 | */ | 8078 | */ |
8577 | public class TokenStmtTry: TokenStmt | 8079 | public class TokenStmtTry: TokenStmt |
8578 | { | 8080 | { |
8579 | |||
8580 | public TokenStmtBlock tryStmt; | 8081 | public TokenStmtBlock tryStmt; |
8581 | public TokenDeclVar catchVar; // null iff catchStmt is null | 8082 | public TokenDeclVar catchVar; // null iff catchStmt is null |
8582 | public TokenStmtBlock catchStmt; // can be null | 8083 | public TokenStmtBlock catchStmt; // can be null |
@@ -8620,7 +8121,6 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
8620 | 8121 | ||
8621 | public class TokenStmtWhile: TokenStmt | 8122 | public class TokenStmtWhile: TokenStmt |
8622 | { | 8123 | { |
8623 | |||
8624 | public TokenRValParen testRVal; | 8124 | public TokenRValParen testRVal; |
8625 | public TokenStmt bodyStmt; | 8125 | public TokenStmt bodyStmt; |
8626 | 8126 | ||
diff --git a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptTokenize.cs b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptTokenize.cs index 1bcb5b6..6c233bc 100644 --- a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptTokenize.cs +++ b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptTokenize.cs | |||
@@ -219,9 +219,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
219 | { | 219 | { |
220 | sourceHash = null; | 220 | sourceHash = null; |
221 | 221 | ||
222 | /* | 222 | // Now do the tokenization. |
223 | * Now do the tokenization. | ||
224 | */ | ||
225 | TokenBegin tokenBegin = new TokenBegin(emsg, "", 0, 0); | 223 | TokenBegin tokenBegin = new TokenBegin(emsg, "", 0, 0); |
226 | tokenBegin.cameFrom = cameFrom; | 224 | tokenBegin.cameFrom = cameFrom; |
227 | tokenBegin.saveSource = saveSource; | 225 | tokenBegin.saveSource = saveSource; |
@@ -384,17 +382,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
384 | if(c == '\n') | 382 | if(c == '\n') |
385 | { | 383 | { |
386 | 384 | ||
387 | /* | 385 | // Increment source line number and set char index of beg of next line. |
388 | * Increment source line number and set char index of beg of next line. | ||
389 | */ | ||
390 | lineNo++; | 386 | lineNo++; |
391 | bolIdx = i + 1; | 387 | bolIdx = i + 1; |
392 | 388 | ||
393 | /* | 389 | // Check for '#' lineno filename newline |
394 | * Check for '#' lineno filename newline | 390 | // lineno is line number of next line in file |
395 | * lineno is line number of next line in file | 391 | // If found, save values and remove tokens from stream |
396 | * If found, save values and remove tokens from stream | ||
397 | */ | ||
398 | if((lastToken is TokenStr) && | 392 | if((lastToken is TokenStr) && |
399 | (lastToken.prevToken is TokenInt) && | 393 | (lastToken.prevToken is TokenInt) && |
400 | (lastToken.prevToken.prevToken is TokenKwHash)) | 394 | (lastToken.prevToken.prevToken is TokenKwHash)) |
@@ -407,15 +401,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
407 | continue; | 401 | continue; |
408 | } | 402 | } |
409 | 403 | ||
410 | /* | 404 | // Skip over whitespace. |
411 | * Skip over whitespace. | ||
412 | */ | ||
413 | if(c <= ' ') | 405 | if(c <= ' ') |
414 | continue; | 406 | continue; |
415 | 407 | ||
416 | /* | 408 | // Skip over comments. |
417 | * Skip over comments. | ||
418 | */ | ||
419 | if((i + 2 <= source.Length) && source.Substring(i, 2).Equals("//")) | 409 | if((i + 2 <= source.Length) && source.Substring(i, 2).Equals("//")) |
420 | { | 410 | { |
421 | while((i < source.Length) && (source[i] != '\n')) | 411 | while((i < source.Length) && (source[i] != '\n')) |
@@ -440,9 +430,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
440 | continue; | 430 | continue; |
441 | } | 431 | } |
442 | 432 | ||
443 | /* | 433 | // Check for numbers. |
444 | * Check for numbers. | ||
445 | */ | ||
446 | if((c >= '0') && (c <= '9')) | 434 | if((c >= '0') && (c <= '9')) |
447 | { | 435 | { |
448 | int j = TryParseFloat(i); | 436 | int j = TryParseFloat(i); |
@@ -459,9 +447,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
459 | continue; | 447 | continue; |
460 | } | 448 | } |
461 | 449 | ||
462 | /* | 450 | // Check for quoted strings. |
463 | * Check for quoted strings. | ||
464 | */ | ||
465 | if(c == '"') | 451 | if(c == '"') |
466 | { | 452 | { |
467 | StringBuilder sb = new StringBuilder(); | 453 | StringBuilder sb = new StringBuilder(); |
@@ -509,9 +495,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
509 | continue; | 495 | continue; |
510 | } | 496 | } |
511 | 497 | ||
512 | /* | 498 | // Check for quoted characters. |
513 | * Check for quoted characters. | ||
514 | */ | ||
515 | if(c == '\'') | 499 | if(c == '\'') |
516 | { | 500 | { |
517 | char cb = (char)0; | 501 | char cb = (char)0; |
@@ -560,9 +544,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
560 | continue; | 544 | continue; |
561 | } | 545 | } |
562 | 546 | ||
563 | /* | 547 | // Check for keywords/names. |
564 | * Check for keywords/names. | ||
565 | */ | ||
566 | if((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c == '_') || (c == '$' && options.dollarsigns)) | 548 | if((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c == '_') || (c == '$' && options.dollarsigns)) |
567 | { | 549 | { |
568 | int j; | 550 | int j; |
@@ -629,9 +611,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
629 | continue; | 611 | continue; |
630 | } | 612 | } |
631 | 613 | ||
632 | /* | 614 | // Check for option enables. |
633 | * Check for option enables. | ||
634 | */ | ||
635 | if((c == ';') && (lastToken is TokenName) && | 615 | if((c == ';') && (lastToken is TokenName) && |
636 | (lastToken.prevToken is TokenName) && | 616 | (lastToken.prevToken is TokenName) && |
637 | (strcasecmp(((TokenName)lastToken.prevToken).val, "yoption") == 0)) | 617 | (strcasecmp(((TokenName)lastToken.prevToken).val, "yoption") == 0)) |
@@ -669,9 +649,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
669 | continue; | 649 | continue; |
670 | } | 650 | } |
671 | 651 | ||
672 | /* | 652 | // Lastly, check for delimeters. |
673 | * Lastly, check for delimeters. | ||
674 | */ | ||
675 | { | 653 | { |
676 | int j; | 654 | int j; |
677 | int len = 0; | 655 | int len = 0; |
@@ -692,9 +670,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
692 | } | 670 | } |
693 | } | 671 | } |
694 | 672 | ||
695 | /* | 673 | // Don't know what it is! |
696 | * Don't know what it is! | ||
697 | */ | ||
698 | TokenError(i, "unknown character '" + c + "'"); | 674 | TokenError(i, "unknown character '" + c + "'"); |
699 | } | 675 | } |
700 | } | 676 | } |
diff --git a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptTypeCast.cs b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptTypeCast.cs index 8761e7a..dd0e5e0 100644 --- a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptTypeCast.cs +++ b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptTypeCast.cs | |||
@@ -177,11 +177,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
177 | */ | 177 | */ |
178 | public static bool IsAssignableFrom(TokenType dstType, TokenType srcType) | 178 | public static bool IsAssignableFrom(TokenType dstType, TokenType srcType) |
179 | { | 179 | { |
180 | /* | 180 | // Do a 'dry run' of the casting operation, discarding any emits and not printing any errors. |
181 | * Do a 'dry run' of the casting operation, discarding any emits and not printing any errors. | 181 | // But if the casting tries to print error(s), return false. |
182 | * But if the casting tries to print error(s), return false. | 182 | // Otherwise assume the cast is allowed and return true. |
183 | * Otherwise assume the cast is allowed and return true. | ||
184 | */ | ||
185 | SCGIAF scg = new SCGIAF(); | 183 | SCGIAF scg = new SCGIAF(); |
186 | scg.ok = true; | 184 | scg.ok = true; |
187 | scg._ilGen = migiaf; | 185 | scg._ilGen = migiaf; |
@@ -305,9 +303,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
305 | string oldString = oldType.ToString(); | 303 | string oldString = oldType.ToString(); |
306 | string newString = newType.ToString(); | 304 | string newString = newType.ToString(); |
307 | 305 | ||
308 | /* | 306 | // 'key' -> 'bool' is the only time we care about key being different than string. |
309 | * 'key' -> 'bool' is the only time we care about key being different than string. | ||
310 | */ | ||
311 | if((oldString == "key") && (newString == "bool")) | 307 | if((oldString == "key") && (newString == "bool")) |
312 | { | 308 | { |
313 | LSLUnwrap(scg, errorAt, oldType); | 309 | LSLUnwrap(scg, errorAt, oldType); |
@@ -316,18 +312,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
316 | return; | 312 | return; |
317 | } | 313 | } |
318 | 314 | ||
319 | /* | 315 | // Treat key and string as same type for all other type casts. |
320 | * Treat key and string as same type for all other type casts. | ||
321 | */ | ||
322 | if(oldString == "key") | 316 | if(oldString == "key") |
323 | oldString = "string"; | 317 | oldString = "string"; |
324 | if(newString == "key") | 318 | if(newString == "key") |
325 | newString = "string"; | 319 | newString = "string"; |
326 | 320 | ||
327 | /* | 321 | // If the types are the same, there is no conceptual casting needed. |
328 | * If the types are the same, there is no conceptual casting needed. | 322 | // However, there may be wraping/unwraping to/from the LSL wrappers. |
329 | * However, there may be wraping/unwraping to/from the LSL wrappers. | ||
330 | */ | ||
331 | if(oldString == newString) | 323 | if(oldString == newString) |
332 | { | 324 | { |
333 | if(oldType.ToLSLWrapType() != newType.ToLSLWrapType()) | 325 | if(oldType.ToLSLWrapType() != newType.ToLSLWrapType()) |
@@ -338,9 +330,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
338 | return; | 330 | return; |
339 | } | 331 | } |
340 | 332 | ||
341 | /* | 333 | // Script-defined classes can be cast up and down the tree. |
342 | * Script-defined classes can be cast up and down the tree. | ||
343 | */ | ||
344 | if((oldType is TokenTypeSDTypeClass) && (newType is TokenTypeSDTypeClass)) | 334 | if((oldType is TokenTypeSDTypeClass) && (newType is TokenTypeSDTypeClass)) |
345 | { | 335 | { |
346 | TokenDeclSDTypeClass oldSDTC = ((TokenTypeSDTypeClass)oldType).decl; | 336 | TokenDeclSDTypeClass oldSDTC = ((TokenTypeSDTypeClass)oldType).decl; |
@@ -369,11 +359,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
369 | goto illcast; | 359 | goto illcast; |
370 | } | 360 | } |
371 | 361 | ||
372 | /* | 362 | // One script-defined interface type cannot be cast to another script-defined interface type, |
373 | * One script-defined interface type cannot be cast to another script-defined interface type, | 363 | // unless the old interface declares that it implements the new interface. That proves that |
374 | * unless the old interface declares that it implements the new interface. That proves that | 364 | // the underlying object, no matter what type, implements the new interface. |
375 | * the underlying object, no matter what type, implements the new interface. | ||
376 | */ | ||
377 | if((oldType is TokenTypeSDTypeInterface) && (newType is TokenTypeSDTypeInterface)) | 365 | if((oldType is TokenTypeSDTypeInterface) && (newType is TokenTypeSDTypeInterface)) |
378 | { | 366 | { |
379 | TokenDeclSDTypeInterface oldDecl = ((TokenTypeSDTypeInterface)oldType).decl; | 367 | TokenDeclSDTypeInterface oldDecl = ((TokenTypeSDTypeInterface)oldType).decl; |
@@ -385,11 +373,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
385 | return; | 373 | return; |
386 | } | 374 | } |
387 | 375 | ||
388 | /* | 376 | // A script-defined class type can be implicitly cast to a script-defined interface type that it |
389 | * A script-defined class type can be implicitly cast to a script-defined interface type that it | 377 | // implements. The result is an array of delegates that give the class's implementation of the |
390 | * implements. The result is an array of delegates that give the class's implementation of the | 378 | // various methods defined by the interface. |
391 | * various methods defined by the interface. | ||
392 | */ | ||
393 | if((oldType is TokenTypeSDTypeClass) && (newType is TokenTypeSDTypeInterface)) | 379 | if((oldType is TokenTypeSDTypeClass) && (newType is TokenTypeSDTypeInterface)) |
394 | { | 380 | { |
395 | TokenDeclSDTypeClass oldSDTC = ((TokenTypeSDTypeClass)oldType).decl; | 381 | TokenDeclSDTypeClass oldSDTC = ((TokenTypeSDTypeClass)oldType).decl; |
@@ -402,13 +388,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
402 | return; | 388 | return; |
403 | } | 389 | } |
404 | 390 | ||
405 | /* | 391 | // A script-defined interface type can be explicitly cast to a script-defined class type by |
406 | * A script-defined interface type can be explicitly cast to a script-defined class type by | 392 | // extracting the Target property from element 0 of the delegate array that is the interface |
407 | * extracting the Target property from element 0 of the delegate array that is the interface | 393 | // object and making sure it casts to the correct script-defined class type. |
408 | * object and making sure it casts to the correct script-defined class type. | 394 | // |
409 | * | 395 | // But then only if the class type implements the interface type. |
410 | * But then only if the class type implements the interface type. | ||
411 | */ | ||
412 | if((oldType is TokenTypeSDTypeInterface) && (newType is TokenTypeSDTypeClass)) | 396 | if((oldType is TokenTypeSDTypeInterface) && (newType is TokenTypeSDTypeClass)) |
413 | { | 397 | { |
414 | TokenTypeSDTypeInterface oldSDTI = (TokenTypeSDTypeInterface)oldType; | 398 | TokenTypeSDTypeInterface oldSDTI = (TokenTypeSDTypeInterface)oldType; |
@@ -423,17 +407,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
423 | return; | 407 | return; |
424 | } | 408 | } |
425 | 409 | ||
426 | /* | 410 | // A script-defined interface type can be implicitly cast to object. |
427 | * A script-defined interface type can be implicitly cast to object. | ||
428 | */ | ||
429 | if((oldType is TokenTypeSDTypeInterface) && (newType is TokenTypeObject)) | 411 | if((oldType is TokenTypeSDTypeInterface) && (newType is TokenTypeObject)) |
430 | { | 412 | { |
431 | return; | 413 | return; |
432 | } | 414 | } |
433 | 415 | ||
434 | /* | 416 | // An object can be explicitly cast to a script-defined interface. |
435 | * An object can be explicitly cast to a script-defined interface. | ||
436 | */ | ||
437 | if((oldType is TokenTypeObject) && (newType is TokenTypeSDTypeInterface)) | 417 | if((oldType is TokenTypeObject) && (newType is TokenTypeSDTypeInterface)) |
438 | { | 418 | { |
439 | ExplCheck(scg, errorAt, explicitAllowed, oldString, newString); | 419 | ExplCheck(scg, errorAt, explicitAllowed, oldString, newString); |
@@ -442,18 +422,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
442 | return; | 422 | return; |
443 | } | 423 | } |
444 | 424 | ||
445 | /* | 425 | // Cast to void is always allowed, such as discarding value from 'i++' or function return value. |
446 | * Cast to void is always allowed, such as discarding value from 'i++' or function return value. | ||
447 | */ | ||
448 | if(newType is TokenTypeVoid) | 426 | if(newType is TokenTypeVoid) |
449 | { | 427 | { |
450 | scg.ilGen.Emit(errorAt, OpCodes.Pop); | 428 | scg.ilGen.Emit(errorAt, OpCodes.Pop); |
451 | return; | 429 | return; |
452 | } | 430 | } |
453 | 431 | ||
454 | /* | 432 | // Cast from undef to object or script-defined type is always allowed. |
455 | * Cast from undef to object or script-defined type is always allowed. | ||
456 | */ | ||
457 | if((oldType is TokenTypeUndef) && | 433 | if((oldType is TokenTypeUndef) && |
458 | ((newType is TokenTypeObject) || | 434 | ((newType is TokenTypeObject) || |
459 | (newType is TokenTypeSDTypeClass) || | 435 | (newType is TokenTypeSDTypeClass) || |
@@ -462,19 +438,15 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
462 | return; | 438 | return; |
463 | } | 439 | } |
464 | 440 | ||
465 | /* | 441 | // Script-defined classes can be implicitly cast to objects. |
466 | * Script-defined classes can be implicitly cast to objects. | ||
467 | */ | ||
468 | if((oldType is TokenTypeSDTypeClass) && (newType is TokenTypeObject)) | 442 | if((oldType is TokenTypeSDTypeClass) && (newType is TokenTypeObject)) |
469 | { | 443 | { |
470 | return; | 444 | return; |
471 | } | 445 | } |
472 | 446 | ||
473 | /* | 447 | // Script-defined classes can be explicitly cast from objects and other script-defined classes. |
474 | * Script-defined classes can be explicitly cast from objects and other script-defined classes. | 448 | // Note that we must manually check that it is the correct SDTypeClass however because as far as |
475 | * Note that we must manually check that it is the correct SDTypeClass however because as far as | 449 | // mono is concerned, all SDTypeClass's are the same. |
476 | * mono is concerned, all SDTypeClass's are the same. | ||
477 | */ | ||
478 | if((oldType is TokenTypeObject) && (newType is TokenTypeSDTypeClass)) | 450 | if((oldType is TokenTypeObject) && (newType is TokenTypeSDTypeClass)) |
479 | { | 451 | { |
480 | ExplCheck(scg, errorAt, explicitAllowed, oldString, newString); | 452 | ExplCheck(scg, errorAt, explicitAllowed, oldString, newString); |
@@ -483,9 +455,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
483 | return; | 455 | return; |
484 | } | 456 | } |
485 | 457 | ||
486 | /* | 458 | // Delegates can be implicitly cast to/from objects. |
487 | * Delegates can be implicitly cast to/from objects. | ||
488 | */ | ||
489 | if((oldType is TokenTypeSDTypeDelegate) && (newType is TokenTypeObject)) | 459 | if((oldType is TokenTypeSDTypeDelegate) && (newType is TokenTypeObject)) |
490 | { | 460 | { |
491 | return; | 461 | return; |
@@ -496,9 +466,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
496 | return; | 466 | return; |
497 | } | 467 | } |
498 | 468 | ||
499 | /* | 469 | // Some actual conversion is needed, see if it is in table of legal casts. |
500 | * Some actual conversion is needed, see if it is in table of legal casts. | ||
501 | */ | ||
502 | string key = oldString + " " + newString; | 470 | string key = oldString + " " + newString; |
503 | if(!legalTypeCasts.TryGetValue(key, out castDelegate)) | 471 | if(!legalTypeCasts.TryGetValue(key, out castDelegate)) |
504 | { | 472 | { |
@@ -508,11 +476,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
508 | ExplCheck(scg, errorAt, explicitAllowed, oldString, newString); | 476 | ExplCheck(scg, errorAt, explicitAllowed, oldString, newString); |
509 | } | 477 | } |
510 | 478 | ||
511 | /* | 479 | // Ok, output cast. But make sure it is in native form without any LSL wrapping |
512 | * Ok, output cast. But make sure it is in native form without any LSL wrapping | 480 | // before passing to our casting routine. Then if caller is expecting an LSL- |
513 | * before passing to our casting routine. Then if caller is expecting an LSL- | 481 | // wrapped value on the stack upon return, wrap it up after our casting. |
514 | * wrapped value on the stack upon return, wrap it up after our casting. | ||
515 | */ | ||
516 | LSLUnwrap(scg, errorAt, oldType); | 482 | LSLUnwrap(scg, errorAt, oldType); |
517 | castDelegate(scg, errorAt); | 483 | castDelegate(scg, errorAt); |
518 | LSLWrap(scg, errorAt, newType); | 484 | LSLWrap(scg, errorAt, newType); |
diff --git a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptVarDict.cs b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptVarDict.cs index 2561d02..a0bc7ba 100644 --- a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptVarDict.cs +++ b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptVarDict.cs | |||
@@ -130,9 +130,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
130 | throw new Exception("var dict is frozen"); | 130 | throw new Exception("var dict is frozen"); |
131 | } | 131 | } |
132 | 132 | ||
133 | /* | 133 | // Make sure we have a sub-dictionary based on the bare name (ie, no signature) |
134 | * Make sure we have a sub-dictionary based on the bare name (ie, no signature) | ||
135 | */ | ||
136 | Dictionary<ArgTypes, TDVEntry> typedic; | 134 | Dictionary<ArgTypes, TDVEntry> typedic; |
137 | if(!master.TryGetValue(var.name.val, out typedic)) | 135 | if(!master.TryGetValue(var.name.val, out typedic)) |
138 | { | 136 | { |
@@ -140,19 +138,15 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
140 | master.Add(var.name.val, typedic); | 138 | master.Add(var.name.val, typedic); |
141 | } | 139 | } |
142 | 140 | ||
143 | /* | 141 | // See if there is an entry in the sub-dictionary that matches the argument signature. |
144 | * See if there is an entry in the sub-dictionary that matches the argument signature. | 142 | // Note that fields have null argument lists. |
145 | * Note that fields have null argument lists. | 143 | // Methods always have a non-null argument list, even if only 0 entries long. |
146 | * Methods always have a non-null argument list, even if only 0 entries long. | ||
147 | */ | ||
148 | ArgTypes types; | 144 | ArgTypes types; |
149 | types.argTypes = (var.argDecl == null) ? null : KeyTypesToStringTypes(var.argDecl.types); | 145 | types.argTypes = (var.argDecl == null) ? null : KeyTypesToStringTypes(var.argDecl.types); |
150 | if(typedic.ContainsKey(types)) | 146 | if(typedic.ContainsKey(types)) |
151 | return false; | 147 | return false; |
152 | 148 | ||
153 | /* | 149 | // It is unique, add to its name-specific sub-dictionary. |
154 | * It is unique, add to its name-specific sub-dictionary. | ||
155 | */ | ||
156 | TDVEntry entry; | 150 | TDVEntry entry; |
157 | entry.count = ++count; | 151 | entry.count = ++count; |
158 | entry.var = var; | 152 | entry.var = var; |
@@ -175,28 +169,21 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
175 | */ | 169 | */ |
176 | public VarDict FreezeLocals() | 170 | public VarDict FreezeLocals() |
177 | { | 171 | { |
178 | /* | 172 | // If not local var frame, return original frame as is. |
179 | * If not local var frame, return original frame as is. | 173 | // This will allow forward references as the future additions |
180 | * This will allow forward references as the future additions | 174 | // will be seen by lookups done in this dictionary. |
181 | * will be seen by lookups done in this dictionary. | ||
182 | */ | ||
183 | if(!locals) | 175 | if(!locals) |
184 | return this; | 176 | return this; |
185 | 177 | ||
186 | /* | 178 | // If local var frame, return a copy frozen at this point. |
187 | * If local var frame, return a copy frozen at this point. | 179 | // This disallows forward referenes as those future additions |
188 | * This disallows forward referenes as those future additions | 180 | // will not be seen by lookups done in the frozen dictionary. |
189 | * will not be seen by lookups done in the frozen dictionary. | ||
190 | */ | ||
191 | if((frozenLocals == null) || (frozenLocals.count != this.count)) | 181 | if((frozenLocals == null) || (frozenLocals.count != this.count)) |
192 | { | 182 | { |
193 | 183 | // Make a copy of the current var dictionary frame. | |
194 | /* | 184 | // We copy a reference to the dictionary, and though it may |
195 | * Make a copy of the current var dictionary frame. | 185 | // contain additions made after this point, those additions |
196 | * We copy a reference to the dictionary, and though it may | 186 | // will have a count .gt. frozen count and will be ignored. |
197 | * contain additions made after this point, those additions | ||
198 | * will have a count .gt. frozen count and will be ignored. | ||
199 | */ | ||
200 | frozenLocals = new VarDict(true); | 187 | frozenLocals = new VarDict(true); |
201 | 188 | ||
202 | frozenLocals.outerVarDict = this.outerVarDict; | 189 | frozenLocals.outerVarDict = this.outerVarDict; |
@@ -205,11 +192,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
205 | frozenLocals.count = this.count; | 192 | frozenLocals.count = this.count; |
206 | frozenLocals.frozenLocals = frozenLocals; | 193 | frozenLocals.frozenLocals = frozenLocals; |
207 | 194 | ||
208 | /* | 195 | // Mark it as being frozen. |
209 | * Mark it as being frozen. | 196 | // - assert fail if any attempt is made to add to it |
210 | * - assert fail if any attempt is made to add to it | 197 | // - ignore any additions to the dictionary with greater count |
211 | * - ignore any additions to the dictionary with greater count | ||
212 | */ | ||
213 | frozenLocals.isFrozen = true; | 198 | frozenLocals.isFrozen = true; |
214 | } | 199 | } |
215 | return frozenLocals; | 200 | return frozenLocals; |
@@ -257,46 +242,34 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
257 | */ | 242 | */ |
258 | public TokenDeclVar FindExact(string name, TokenType[] argTypes) | 243 | public TokenDeclVar FindExact(string name, TokenType[] argTypes) |
259 | { | 244 | { |
260 | /* | 245 | // Look for list of stuff that matches the given name. |
261 | * Look for list of stuff that matches the given name. | ||
262 | */ | ||
263 | Dictionary<ArgTypes, TDVEntry> typedic; | 246 | Dictionary<ArgTypes, TDVEntry> typedic; |
264 | if(!master.TryGetValue(name, out typedic)) | 247 | if(!master.TryGetValue(name, out typedic)) |
265 | return null; | 248 | return null; |
266 | 249 | ||
267 | /* | 250 | // Loop through all fields/methods declared by that name, regardless of arg signature. |
268 | * Loop through all fields/methods declared by that name, regardless of arg signature. | ||
269 | */ | ||
270 | foreach(TDVEntry entry in typedic.Values) | 251 | foreach(TDVEntry entry in typedic.Values) |
271 | { | 252 | { |
272 | if(entry.count > this.count) | 253 | if(entry.count > this.count) |
273 | continue; | 254 | continue; |
274 | TokenDeclVar var = entry.var; | 255 | TokenDeclVar var = entry.var; |
275 | 256 | ||
276 | /* | 257 | // Get argument types of declaration. |
277 | * Get argument types of declaration. | 258 | // fields are always null |
278 | * fields are always null | 259 | // methods are always non-null, though may be zero-length |
279 | * methods are always non-null, though may be zero-length | ||
280 | */ | ||
281 | TokenType[] declArgs = (var.argDecl == null) ? null : var.argDecl.types; | 260 | TokenType[] declArgs = (var.argDecl == null) ? null : var.argDecl.types; |
282 | 261 | ||
283 | /* | 262 | // Convert any key args to string args. |
284 | * Convert any key args to string args. | ||
285 | */ | ||
286 | declArgs = KeyTypesToStringTypes(declArgs); | 263 | declArgs = KeyTypesToStringTypes(declArgs); |
287 | 264 | ||
288 | /* | 265 | // If both are null, they are signature-less (ie, both are fields), and so match. |
289 | * If both are null, they are signature-less (ie, both are fields), and so match. | ||
290 | */ | ||
291 | if((declArgs == null) && (argTypes == null)) | 266 | if((declArgs == null) && (argTypes == null)) |
292 | return var; | 267 | return var; |
293 | 268 | ||
294 | /* | 269 | // If calling a delegate, it is a match, regardless of delegate arg types. |
295 | * If calling a delegate, it is a match, regardless of delegate arg types. | 270 | // If it turns out the arg types do not match, the compiler will give an error |
296 | * If it turns out the arg types do not match, the compiler will give an error | 271 | // trying to cast the arguments to the delegate arg types. |
297 | * trying to cast the arguments to the delegate arg types. | 272 | // We don't allow overloading same field name with different delegate types. |
298 | * We don't allow overloading same field name with different delegate types. | ||
299 | */ | ||
300 | if((declArgs == null) && (argTypes != null)) | 273 | if((declArgs == null) && (argTypes != null)) |
301 | { | 274 | { |
302 | TokenType fieldType = var.type; | 275 | TokenType fieldType = var.type; |
@@ -304,15 +277,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
304 | return var; | 277 | return var; |
305 | } | 278 | } |
306 | 279 | ||
307 | /* | 280 | // If not both null, no match, keep looking. |
308 | * If not both null, no match, keep looking. | ||
309 | */ | ||
310 | if((declArgs == null) || (argTypes == null)) | 281 | if((declArgs == null) || (argTypes == null)) |
311 | continue; | 282 | continue; |
312 | 283 | ||
313 | /* | 284 | // Both not null, match argument types to make sure we have correct overload. |
314 | * Both not null, match argument types to make sure we have correct overload. | ||
315 | */ | ||
316 | int i = declArgs.Length; | 285 | int i = declArgs.Length; |
317 | if(i != argTypes.Length) | 286 | if(i != argTypes.Length) |
318 | continue; | 287 | continue; |
@@ -331,9 +300,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
331 | return var; | 300 | return var; |
332 | } | 301 | } |
333 | 302 | ||
334 | /* | 303 | // No match. |
335 | * No match. | ||
336 | */ | ||
337 | return null; | 304 | return null; |
338 | } | 305 | } |
339 | 306 | ||
diff --git a/OpenSim/Region/ScriptEngine/YEngine/XMRArray.cs b/OpenSim/Region/ScriptEngine/YEngine/XMRArray.cs index b797224..3d0525b 100644 --- a/OpenSim/Region/ScriptEngine/YEngine/XMRArray.cs +++ b/OpenSim/Region/ScriptEngine/YEngine/XMRArray.cs | |||
@@ -108,10 +108,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
108 | { | 108 | { |
109 | key = FixKey(key); | 109 | key = FixKey(key); |
110 | 110 | ||
111 | /* | 111 | // Update heap use throwing an exception on failure |
112 | * Update heap use throwing an exception on failure | 112 | // before making any changes to the array. |
113 | * before making any changes to the array. | ||
114 | */ | ||
115 | int keysize = HeapTrackerObject.Size(key); | 113 | int keysize = HeapTrackerObject.Size(key); |
116 | int newheapuse = heapUse; | 114 | int newheapuse = heapUse; |
117 | object oldval; | 115 | object oldval; |
@@ -125,10 +123,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
125 | } | 123 | } |
126 | heapUse = inst.UpdateHeapUse(heapUse, newheapuse); | 124 | heapUse = inst.UpdateHeapUse(heapUse, newheapuse); |
127 | 125 | ||
128 | /* | 126 | // Save new value in array, replacing one of same key if there. |
129 | * Save new value in array, replacing one of same key if there. | 127 | // null means remove the value, ie, script did array[key] = undef. |
130 | * null means remove the value, ie, script did array[key] = undef. | ||
131 | */ | ||
132 | if(value != null) | 128 | if(value != null) |
133 | { | 129 | { |
134 | dnary[key] = value; | 130 | dnary[key] = value; |
@@ -137,19 +133,15 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
137 | { | 133 | { |
138 | dnary.Remove(key); | 134 | dnary.Remove(key); |
139 | 135 | ||
140 | /* | 136 | // Shrink the enumeration array, but always leave at least one element. |
141 | * Shrink the enumeration array, but always leave at least one element. | ||
142 | */ | ||
143 | if((array != null) && (dnary.Count < array.Length / 2)) | 137 | if((array != null) && (dnary.Count < array.Length / 2)) |
144 | { | 138 | { |
145 | Array.Resize<KeyValuePair<object, object>>(ref array, array.Length / 2); | 139 | Array.Resize<KeyValuePair<object, object>>(ref array, array.Length / 2); |
146 | } | 140 | } |
147 | } | 141 | } |
148 | 142 | ||
149 | /* | 143 | // The enumeration array is invalid because the dictionary has been modified. |
150 | * The enumeration array is invalid because the dictionary has been modified. | 144 | // Next time a ForEach() call happens, it will repopulate 'array' as elements are retrieved. |
151 | * Next time a ForEach() call happens, it will repopulate 'array' as elements are retrieved. | ||
152 | */ | ||
153 | arrayValid = 0; | 145 | arrayValid = 0; |
154 | } | 146 | } |
155 | 147 | ||
@@ -236,29 +228,23 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
236 | */ | 228 | */ |
237 | private bool ForEach(int number) | 229 | private bool ForEach(int number) |
238 | { | 230 | { |
239 | /* | 231 | // If we don't have any array, we can't have ever done |
240 | * If we don't have any array, we can't have ever done | 232 | // any calls here before, so allocate an array big enough |
241 | * any calls here before, so allocate an array big enough | 233 | // and set everything else to the beginning. |
242 | * and set everything else to the beginning. | ||
243 | */ | ||
244 | if(array == null) | 234 | if(array == null) |
245 | { | 235 | { |
246 | array = new KeyValuePair<object, object>[dnary.Count]; | 236 | array = new KeyValuePair<object, object>[dnary.Count]; |
247 | arrayValid = 0; | 237 | arrayValid = 0; |
248 | } | 238 | } |
249 | 239 | ||
250 | /* | 240 | // If dictionary modified since last enumeration, get a new enumerator. |
251 | * If dictionary modified since last enumeration, get a new enumerator. | ||
252 | */ | ||
253 | if(arrayValid == 0) | 241 | if(arrayValid == 0) |
254 | { | 242 | { |
255 | enumr = dnary.GetEnumerator(); | 243 | enumr = dnary.GetEnumerator(); |
256 | enumrValid = true; | 244 | enumrValid = true; |
257 | } | 245 | } |
258 | 246 | ||
259 | /* | 247 | // Make sure we have filled the array up enough for requested element. |
260 | * Make sure we have filled the array up enough for requested element. | ||
261 | */ | ||
262 | while((arrayValid <= number) && enumrValid && enumr.MoveNext()) | 248 | while((arrayValid <= number) && enumrValid && enumr.MoveNext()) |
263 | { | 249 | { |
264 | if(arrayValid >= array.Length) | 250 | if(arrayValid >= array.Length) |
@@ -268,9 +254,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
268 | array[arrayValid++] = enumr.Current; | 254 | array[arrayValid++] = enumr.Current; |
269 | } | 255 | } |
270 | 256 | ||
271 | /* | 257 | // If we don't have that many elements, return end-of-array status. |
272 | * If we don't have that many elements, return end-of-array status. | ||
273 | */ | ||
274 | return number < arrayValid; | 258 | return number < arrayValid; |
275 | } | 259 | } |
276 | 260 | ||
@@ -281,10 +265,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
281 | public delegate void SendArrayObjDelegate(object graph); | 265 | public delegate void SendArrayObjDelegate(object graph); |
282 | public void SendArrayObj(SendArrayObjDelegate sendObj) | 266 | public void SendArrayObj(SendArrayObjDelegate sendObj) |
283 | { | 267 | { |
284 | /* | 268 | // Set the count then the elements themselves. |
285 | * Set the count then the elements themselves. | 269 | // UnfixKey() because sendObj doesn't handle XMRArrayListKeys. |
286 | * UnfixKey() because sendObj doesn't handle XMRArrayListKeys. | ||
287 | */ | ||
288 | sendObj(dnary.Count); | 270 | sendObj(dnary.Count); |
289 | foreach(KeyValuePair<object, object> kvp in dnary) | 271 | foreach(KeyValuePair<object, object> kvp in dnary) |
290 | { | 272 | { |
@@ -304,17 +286,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
304 | { | 286 | { |
305 | heapUse = inst.UpdateHeapUse(heapUse, EMPTYHEAP); | 287 | heapUse = inst.UpdateHeapUse(heapUse, EMPTYHEAP); |
306 | 288 | ||
307 | /* | 289 | // Cause any enumeration to refill the array from the sorted dictionary. |
308 | * Cause any enumeration to refill the array from the sorted dictionary. | 290 | // Since it is a sorted dictionary, any enumerations will be in the same |
309 | * Since it is a sorted dictionary, any enumerations will be in the same | 291 | // order as on the sending side. |
310 | * order as on the sending side. | ||
311 | */ | ||
312 | arrayValid = 0; | 292 | arrayValid = 0; |
313 | enumrValid = false; | 293 | enumrValid = false; |
314 | 294 | ||
315 | /* | 295 | // Fill dictionary. |
316 | * Fill dictionary. | ||
317 | */ | ||
318 | dnary.Clear(); | 296 | dnary.Clear(); |
319 | int count = (int)recvObj(); | 297 | int count = (int)recvObj(); |
320 | while(--count >= 0) | 298 | while(--count >= 0) |
@@ -375,9 +353,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
375 | */ | 353 | */ |
376 | public int Compare(object x, object y) // IComparer<object> | 354 | public int Compare(object x, object y) // IComparer<object> |
377 | { | 355 | { |
378 | /* | 356 | // Use short type name (eg, String, Int32, XMRArrayListKey) as most significant part of key. |
379 | * Use short type name (eg, String, Int32, XMRArrayListKey) as most significant part of key. | ||
380 | */ | ||
381 | string xtn = x.GetType().Name; | 357 | string xtn = x.GetType().Name; |
382 | string ytn = y.GetType().Name; | 358 | string ytn = y.GetType().Name; |
383 | int ctn = String.CompareOrdinal(xtn, ytn); | 359 | int ctn = String.CompareOrdinal(xtn, ytn); |
diff --git a/OpenSim/Region/ScriptEngine/YEngine/XMREngXmrTestLs.cs b/OpenSim/Region/ScriptEngine/YEngine/XMREngXmrTestLs.cs index 19ff336..ea306c8 100644 --- a/OpenSim/Region/ScriptEngine/YEngine/XMREngXmrTestLs.cs +++ b/OpenSim/Region/ScriptEngine/YEngine/XMREngXmrTestLs.cs | |||
@@ -56,9 +56,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
56 | string outName = null; | 56 | string outName = null; |
57 | XMRInstance[] instances; | 57 | XMRInstance[] instances; |
58 | 58 | ||
59 | /* | 59 | // Decode command line options. |
60 | * Decode command line options. | ||
61 | */ | ||
62 | for(int i = indx; i < args.Length; i++) | 60 | for(int i = indx; i < args.Length; i++) |
63 | { | 61 | { |
64 | if(args[i] == "-full") | 62 | if(args[i] == "-full") |
@@ -126,10 +124,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
126 | 124 | ||
127 | try | 125 | try |
128 | { | 126 | { |
129 | 127 | // Scan instance list to find those that match selection criteria. | |
130 | /* | ||
131 | * Scan instance list to find those that match selection criteria. | ||
132 | */ | ||
133 | if(!Monitor.TryEnter(m_InstancesDict, 100)) | 128 | if(!Monitor.TryEnter(m_InstancesDict, 100)) |
134 | { | 129 | { |
135 | m_log.Error("[YEngine]: deadlock m_LockedDict=" + m_LockedDict); | 130 | m_log.Error("[YEngine]: deadlock m_LockedDict=" + m_LockedDict); |
@@ -151,17 +146,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
151 | Monitor.Exit(m_InstancesDict); | 146 | Monitor.Exit(m_InstancesDict); |
152 | } | 147 | } |
153 | 148 | ||
154 | /* | 149 | // Maybe sort by descending CPU time. |
155 | * Maybe sort by descending CPU time. | ||
156 | */ | ||
157 | if(flagTopCPU) | 150 | if(flagTopCPU) |
158 | { | 151 | { |
159 | Array.Sort<XMRInstance>(instances, CompareInstancesByCPUTime); | 152 | Array.Sort<XMRInstance>(instances, CompareInstancesByCPUTime); |
160 | } | 153 | } |
161 | 154 | ||
162 | /* | 155 | // Print the entries. |
163 | * Print the entries. | ||
164 | */ | ||
165 | if(!flagFull) | 156 | if(!flagFull) |
166 | { | 157 | { |
167 | outFile.WriteLine(" ItemID" + | 158 | outFile.WriteLine(" ItemID" + |
@@ -176,15 +167,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
176 | outFile.WriteLine(instances[i].RunTestLs(flagFull)); | 167 | outFile.WriteLine(instances[i].RunTestLs(flagFull)); |
177 | } | 168 | } |
178 | 169 | ||
179 | /* | 170 | // Print number of scripts that match selection criteria, |
180 | * Print number of scripts that match selection criteria, | 171 | // even if we were told to print fewer. |
181 | * even if we were told to print fewer. | ||
182 | */ | ||
183 | outFile.WriteLine("total of {0} script(s)", numScripts); | 172 | outFile.WriteLine("total of {0} script(s)", numScripts); |
184 | 173 | ||
185 | /* | 174 | // If -queues given, print out queue contents too. |
186 | * If -queues given, print out queue contents too. | ||
187 | */ | ||
188 | if(flagQueues) | 175 | if(flagQueues) |
189 | { | 176 | { |
190 | LsQueue(outFile, "start", m_StartQueue, args, indx); | 177 | LsQueue(outFile, "start", m_StartQueue, args, indx); |
@@ -204,9 +191,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
204 | int numScripts = 0; | 191 | int numScripts = 0; |
205 | XMRInstance[] instances; | 192 | XMRInstance[] instances; |
206 | 193 | ||
207 | /* | 194 | // Decode command line options. |
208 | * Decode command line options. | ||
209 | */ | ||
210 | int i, j; | 195 | int i, j; |
211 | List<string> selargs = new List<string>(args.Length); | 196 | List<string> selargs = new List<string>(args.Length); |
212 | MethodInfo[] eventmethods = typeof(IEventHandlers).GetMethods(); | 197 | MethodInfo[] eventmethods = typeof(IEventHandlers).GetMethods(); |
@@ -271,9 +256,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
271 | OpenSim.Region.ScriptEngine.Shared.EventParams eps = | 256 | OpenSim.Region.ScriptEngine.Shared.EventParams eps = |
272 | new OpenSim.Region.ScriptEngine.Shared.EventParams(eventname, paramvalues, zeroDetectParams); | 257 | new OpenSim.Region.ScriptEngine.Shared.EventParams(eventname, paramvalues, zeroDetectParams); |
273 | 258 | ||
274 | /* | 259 | // Scan instance list to find those that match selection criteria. |
275 | * Scan instance list to find those that match selection criteria. | ||
276 | */ | ||
277 | if(!Monitor.TryEnter(m_InstancesDict, 100)) | 260 | if(!Monitor.TryEnter(m_InstancesDict, 100)) |
278 | { | 261 | { |
279 | m_log.Error("[YEngine]: deadlock m_LockedDict=" + m_LockedDict); | 262 | m_log.Error("[YEngine]: deadlock m_LockedDict=" + m_LockedDict); |
@@ -296,9 +279,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
296 | Monitor.Exit(m_InstancesDict); | 279 | Monitor.Exit(m_InstancesDict); |
297 | } | 280 | } |
298 | 281 | ||
299 | /* | 282 | // Post event to the matching instances. |
300 | * Post event to the matching instances. | ||
301 | */ | ||
302 | for(i = 0; i < numScripts; i++) | 283 | for(i = 0; i < numScripts; i++) |
303 | { | 284 | { |
304 | XMRInstance inst = instances[i]; | 285 | XMRInstance inst = instances[i]; |
@@ -415,9 +396,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
415 | return; | 396 | return; |
416 | } | 397 | } |
417 | 398 | ||
418 | /* | 399 | // Decode command line options. |
419 | * Decode command line options. | ||
420 | */ | ||
421 | for(int i = indx; i < args.Length; i++) | 400 | for(int i = indx; i < args.Length; i++) |
422 | { | 401 | { |
423 | if(args[i] == "-all") | 402 | if(args[i] == "-all") |
@@ -437,9 +416,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
437 | } | 416 | } |
438 | } | 417 | } |
439 | 418 | ||
440 | /* | 419 | // Scan instance list to find those that match selection criteria. |
441 | * Scan instance list to find those that match selection criteria. | ||
442 | */ | ||
443 | if(!Monitor.TryEnter(m_InstancesDict, 100)) | 420 | if(!Monitor.TryEnter(m_InstancesDict, 100)) |
444 | { | 421 | { |
445 | m_log.Error("[YEngine]: deadlock m_LockedDict=" + m_LockedDict); | 422 | m_log.Error("[YEngine]: deadlock m_LockedDict=" + m_LockedDict); |
@@ -462,9 +439,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
462 | Monitor.Exit(m_InstancesDict); | 439 | Monitor.Exit(m_InstancesDict); |
463 | } | 440 | } |
464 | 441 | ||
465 | /* | 442 | // Reset the instances as if someone clicked their "Reset" button. |
466 | * Reset the instances as if someone clicked their "Reset" button. | ||
467 | */ | ||
468 | for(int i = 0; i < numScripts; i++) | 443 | for(int i = 0; i < numScripts; i++) |
469 | { | 444 | { |
470 | XMRInstance inst = instances[i]; | 445 | XMRInstance inst = instances[i]; |
@@ -499,10 +474,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
499 | { | 474 | { |
500 | try | 475 | try |
501 | { | 476 | { |
502 | 477 | // Try to print instance name. | |
503 | /* | ||
504 | * Try to print instance name. | ||
505 | */ | ||
506 | if(InstanceMatchesArgs(inst, args, indx)) | 478 | if(InstanceMatchesArgs(inst, args, indx)) |
507 | { | 479 | { |
508 | outFile.WriteLine(" " + inst.ItemID.ToString() + " " + inst.m_DescName); | 480 | outFile.WriteLine(" " + inst.ItemID.ToString() + " " + inst.m_DescName); |
@@ -510,10 +482,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
510 | } | 482 | } |
511 | catch(Exception e) | 483 | catch(Exception e) |
512 | { | 484 | { |
513 | 485 | // Sometimes there are instances in the queue that are disposed. | |
514 | /* | ||
515 | * Sometimes there are instances in the queue that are disposed. | ||
516 | */ | ||
517 | outFile.WriteLine(" " + inst.ItemID.ToString() + " " + inst.m_DescName + ": " + e.Message); | 486 | outFile.WriteLine(" " + inst.ItemID.ToString() + " " + inst.m_DescName + ": " + e.Message); |
518 | } | 487 | } |
519 | } | 488 | } |
diff --git a/OpenSim/Region/ScriptEngine/YEngine/XMRInstAbstract.cs b/OpenSim/Region/ScriptEngine/YEngine/XMRInstAbstract.cs index a0bb3e0..b3ff765 100644 --- a/OpenSim/Region/ScriptEngine/YEngine/XMRInstAbstract.cs +++ b/OpenSim/Region/ScriptEngine/YEngine/XMRInstAbstract.cs | |||
@@ -473,10 +473,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
473 | { | 473 | { |
474 | ScriptEventHandler seh; | 474 | ScriptEventHandler seh; |
475 | 475 | ||
476 | /* | 476 | // CallMode_NORMAL: run event handler from the beginning normally |
477 | * CallMode_NORMAL: run event handler from the beginning normally | 477 | // CallMode_RESTORE: restore event handler stack from stackFrames |
478 | * CallMode_RESTORE: restore event handler stack from stackFrames | ||
479 | */ | ||
480 | callMode = (stackFrames == null) ? XMRInstAbstract.CallMode_NORMAL : | 478 | callMode = (stackFrames == null) ? XMRInstAbstract.CallMode_NORMAL : |
481 | XMRInstAbstract.CallMode_RESTORE; | 479 | XMRInstAbstract.CallMode_RESTORE; |
482 | 480 | ||
@@ -723,25 +721,19 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
723 | if(o is LSL_Vector) | 721 | if(o is LSL_Vector) |
724 | return "vector"; | 722 | return "vector"; |
725 | 723 | ||
726 | /* | 724 | // A script-defined interface is represented as an array of delegates. |
727 | * A script-defined interface is represented as an array of delegates. | 725 | // If that is the case, convert it to the object of the script-defined |
728 | * If that is the case, convert it to the object of the script-defined | 726 | // class that is implementing the interface. This should let the next |
729 | * class that is implementing the interface. This should let the next | 727 | // step get the script-defined type name of the object. |
730 | * step get the script-defined type name of the object. | ||
731 | */ | ||
732 | if(o is Delegate[]) | 728 | if(o is Delegate[]) |
733 | o = ((Delegate[])o)[0].Target; | 729 | o = ((Delegate[])o)[0].Target; |
734 | 730 | ||
735 | /* | 731 | // If script-defined class instance, get the script-defined |
736 | * If script-defined class instance, get the script-defined | 732 | // type name. |
737 | * type name. | ||
738 | */ | ||
739 | if(o is XMRSDTypeClObj) | 733 | if(o is XMRSDTypeClObj) |
740 | return ((XMRSDTypeClObj)o).sdtcClass.longName.val; | 734 | return ((XMRSDTypeClObj)o).sdtcClass.longName.val; |
741 | 735 | ||
742 | /* | 736 | // If it's a delegate, maybe we can look up its script-defined type name. |
743 | * If it's a delegate, maybe we can look up its script-defined type name. | ||
744 | */ | ||
745 | Type ot = o.GetType(); | 737 | Type ot = o.GetType(); |
746 | if(o is Delegate) | 738 | if(o is Delegate) |
747 | { | 739 | { |
@@ -750,9 +742,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
750 | return os; | 742 | return os; |
751 | } | 743 | } |
752 | 744 | ||
753 | /* | 745 | // Don't know what it is, get the C#-level type name. |
754 | * Don't know what it is, get the C#-level type name. | ||
755 | */ | ||
756 | return ot.ToString(); | 746 | return ot.ToString(); |
757 | } | 747 | } |
758 | 748 | ||
@@ -964,17 +954,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
964 | { | 954 | { |
965 | TokenDeclSDType sdType = inst.m_ObjCode.sdObjTypesIndx[sdtypeindex]; | 955 | TokenDeclSDType sdType = inst.m_ObjCode.sdObjTypesIndx[sdtypeindex]; |
966 | 956 | ||
967 | /* | 957 | // If it is a script-defined interface object, convert to the original XMRSDTypeClObj. |
968 | * If it is a script-defined interface object, convert to the original XMRSDTypeClObj. | ||
969 | */ | ||
970 | if(thrown is Delegate[]) | 958 | if(thrown is Delegate[]) |
971 | { | 959 | { |
972 | thrown = ((Delegate[])thrown)[0].Target; | 960 | thrown = ((Delegate[])thrown)[0].Target; |
973 | } | 961 | } |
974 | 962 | ||
975 | /* | 963 | // If it is a script-defined delegate object, make sure it is an instance of the expected type. |
976 | * If it is a script-defined delegate object, make sure it is an instance of the expected type. | ||
977 | */ | ||
978 | if(thrown is Delegate) | 964 | if(thrown is Delegate) |
979 | { | 965 | { |
980 | Type ot = thrown.GetType(); | 966 | Type ot = thrown.GetType(); |
@@ -982,17 +968,12 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
982 | return (ot == tt) ? thrown : null; | 968 | return (ot == tt) ? thrown : null; |
983 | } | 969 | } |
984 | 970 | ||
985 | /* | 971 | // If it is a script-defined class object, make sure it is an instance of the expected class. |
986 | * If it is a script-defined class object, make sure it is an instance of the expected class. | ||
987 | */ | ||
988 | if(thrown is XMRSDTypeClObj) | 972 | if(thrown is XMRSDTypeClObj) |
989 | { | 973 | { |
990 | 974 | // Step from the object's actual class rootward. | |
991 | /* | 975 | // If we find the requested class along the way, the cast is valid. |
992 | * Step from the object's actual class rootward. | 976 | // If we run off the end of the root, the cast is not valid. |
993 | * If we find the requested class along the way, the cast is valid. | ||
994 | * If we run off the end of the root, the cast is not valid. | ||
995 | */ | ||
996 | for(TokenDeclSDTypeClass ac = ((XMRSDTypeClObj)thrown).sdtcClass; ac != null; ac = ac.extends) | 977 | for(TokenDeclSDTypeClass ac = ((XMRSDTypeClObj)thrown).sdtcClass; ac != null; ac = ac.extends) |
997 | { | 978 | { |
998 | if(ac == sdType) | 979 | if(ac == sdType) |
@@ -1000,9 +981,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1000 | } | 981 | } |
1001 | } | 982 | } |
1002 | 983 | ||
1003 | /* | 984 | // Don't know what it is, assume it is not what caller wants. |
1004 | * Don't know what it is, assume it is not what caller wants. | ||
1005 | */ | ||
1006 | return null; | 985 | return null; |
1007 | } | 986 | } |
1008 | 987 | ||
@@ -1070,24 +1049,18 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1070 | */ | 1049 | */ |
1071 | public static void xmrArrayCopy(object srcobj, int srcstart, object dstobj, int dststart, int count) | 1050 | public static void xmrArrayCopy(object srcobj, int srcstart, object dstobj, int dststart, int count) |
1072 | { | 1051 | { |
1073 | /* | 1052 | // The script writer should only pass us script-defined class objects. |
1074 | * The script writer should only pass us script-defined class objects. | 1053 | // Throw exception otherwise. |
1075 | * Throw exception otherwise. | ||
1076 | */ | ||
1077 | XMRSDTypeClObj srcsdt = (XMRSDTypeClObj)srcobj; | 1054 | XMRSDTypeClObj srcsdt = (XMRSDTypeClObj)srcobj; |
1078 | XMRSDTypeClObj dstsdt = (XMRSDTypeClObj)dstobj; | 1055 | XMRSDTypeClObj dstsdt = (XMRSDTypeClObj)dstobj; |
1079 | 1056 | ||
1080 | /* | 1057 | // Get the script-visible type name of the arrays, brackets and all. |
1081 | * Get the script-visible type name of the arrays, brackets and all. | ||
1082 | */ | ||
1083 | string srctypename = srcsdt.sdtcClass.longName.val; | 1058 | string srctypename = srcsdt.sdtcClass.longName.val; |
1084 | string dsttypename = dstsdt.sdtcClass.longName.val; | 1059 | string dsttypename = dstsdt.sdtcClass.longName.val; |
1085 | 1060 | ||
1086 | /* | 1061 | // The part before the first '[' of each should match exactly, |
1087 | * The part before the first '[' of each should match exactly, | 1062 | // meaning the basic data type (eg, float, List<string>) is the same. |
1088 | * meaning the basic data type (eg, float, List<string>) is the same. | 1063 | // And there must be a '[' in each meaning that it is a script-defined array type. |
1089 | * And there must be a '[' in each meaning that it is a script-defined array type. | ||
1090 | */ | ||
1091 | int i = srctypename.IndexOf('['); | 1064 | int i = srctypename.IndexOf('['); |
1092 | int j = dsttypename.IndexOf('['); | 1065 | int j = dsttypename.IndexOf('['); |
1093 | if((i < 0) || (j < 0)) | 1066 | if((i < 0) || (j < 0)) |
@@ -1095,12 +1068,10 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1095 | if((i != j) || !srctypename.StartsWith(dsttypename.Substring(0, j))) | 1068 | if((i != j) || !srctypename.StartsWith(dsttypename.Substring(0, j))) |
1096 | throw new ArrayTypeMismatchException(srctypename + " vs " + dsttypename); | 1069 | throw new ArrayTypeMismatchException(srctypename + " vs " + dsttypename); |
1097 | 1070 | ||
1098 | /* | 1071 | // The number of brackets must match exactly. |
1099 | * The number of brackets must match exactly. | 1072 | // This permits copying from something like a float[,][] to something like a float[][]. |
1100 | * This permits copying from something like a float[,][] to something like a float[][]. | 1073 | // But you cannot copy from a float[][] to a float[] or wisa wersa. |
1101 | * But you cannot copy from a float[][] to a float[] or wisa wersa. | 1074 | // Counting either '[' or ']' would work equally well. |
1102 | * Counting either '[' or ']' would work equally well. | ||
1103 | */ | ||
1104 | int srclen = srctypename.Length; | 1075 | int srclen = srctypename.Length; |
1105 | int dstlen = dsttypename.Length; | 1076 | int dstlen = dsttypename.Length; |
1106 | int srcjags = 0; | 1077 | int srcjags = 0; |
@@ -1114,9 +1085,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1114 | if(dstjags != srcjags) | 1085 | if(dstjags != srcjags) |
1115 | throw new ArrayTypeMismatchException(srctypename + " vs " + dsttypename); | 1086 | throw new ArrayTypeMismatchException(srctypename + " vs " + dsttypename); |
1116 | 1087 | ||
1117 | /* | 1088 | // Perform the copy. |
1118 | * Perform the copy. | ||
1119 | */ | ||
1120 | Array srcarray = (Array)srcsdt.instVars.iarObjects[0]; | 1089 | Array srcarray = (Array)srcsdt.instVars.iarObjects[0]; |
1121 | Array dstarray = (Array)dstsdt.instVars.iarObjects[0]; | 1090 | Array dstarray = (Array)dstsdt.instVars.iarObjects[0]; |
1122 | Array.Copy(srcarray, srcstart, dstarray, dststart, count); | 1091 | Array.Copy(srcarray, srcstart, dstarray, dststart, count); |
@@ -1131,19 +1100,15 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1131 | */ | 1100 | */ |
1132 | public static LSL_List xmrArray2List(object srcar, int start, int count) | 1101 | public static LSL_List xmrArray2List(object srcar, int start, int count) |
1133 | { | 1102 | { |
1134 | /* | 1103 | // Get the script-visible type of the array. |
1135 | * Get the script-visible type of the array. | 1104 | // We only do arrays. |
1136 | * We only do arrays. | ||
1137 | */ | ||
1138 | XMRSDTypeClObj array = (XMRSDTypeClObj)srcar; | 1105 | XMRSDTypeClObj array = (XMRSDTypeClObj)srcar; |
1139 | TokenDeclSDTypeClass sdtClass = array.sdtcClass; | 1106 | TokenDeclSDTypeClass sdtClass = array.sdtcClass; |
1140 | if(sdtClass.arrayOfRank == 0) | 1107 | if(sdtClass.arrayOfRank == 0) |
1141 | throw new InvalidCastException("only do arrays not " + sdtClass.longName.val); | 1108 | throw new InvalidCastException("only do arrays not " + sdtClass.longName.val); |
1142 | 1109 | ||
1143 | /* | 1110 | // Validate objects they want to put in the list. |
1144 | * Validate objects they want to put in the list. | 1111 | // We can't allow anything funky that OpenSim runtime doesn't expect. |
1145 | * We can't allow anything funky that OpenSim runtime doesn't expect. | ||
1146 | */ | ||
1147 | Array srcarray = (Array)array.instVars.iarObjects[0]; | 1112 | Array srcarray = (Array)array.instVars.iarObjects[0]; |
1148 | object[] output = new object[count]; | 1113 | object[] output = new object[count]; |
1149 | for(int i = 0; i < count; i++) | 1114 | for(int i = 0; i < count; i++) |
@@ -1179,9 +1144,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1179 | throw new InvalidCastException("invalid element " + i + " type " + src.GetType().Name); | 1144 | throw new InvalidCastException("invalid element " + i + " type " + src.GetType().Name); |
1180 | } | 1145 | } |
1181 | 1146 | ||
1182 | /* | 1147 | // Make a list out of that now immutable array. |
1183 | * Make a list out of that now immutable array. | ||
1184 | */ | ||
1185 | return new LSL_List(output); | 1148 | return new LSL_List(output); |
1186 | } | 1149 | } |
1187 | 1150 | ||
@@ -1195,19 +1158,15 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1195 | */ | 1158 | */ |
1196 | public static void xmrList2Array(LSL_List srclist, int srcstart, object dstobj, int dststart, int count) | 1159 | public static void xmrList2Array(LSL_List srclist, int srcstart, object dstobj, int dststart, int count) |
1197 | { | 1160 | { |
1198 | /* | 1161 | // Get the script-visible type of the destination. |
1199 | * Get the script-visible type of the destination. | 1162 | // We only do arrays. |
1200 | * We only do arrays. | ||
1201 | */ | ||
1202 | XMRSDTypeClObj dstarray = (XMRSDTypeClObj)dstobj; | 1163 | XMRSDTypeClObj dstarray = (XMRSDTypeClObj)dstobj; |
1203 | TokenDeclSDTypeClass sdtClass = dstarray.sdtcClass; | 1164 | TokenDeclSDTypeClass sdtClass = dstarray.sdtcClass; |
1204 | if(sdtClass.arrayOfType == null) | 1165 | if(sdtClass.arrayOfType == null) |
1205 | throw new InvalidCastException("only do arrays not " + sdtClass.longName.val); | 1166 | throw new InvalidCastException("only do arrays not " + sdtClass.longName.val); |
1206 | 1167 | ||
1207 | /* | 1168 | // Copy from the immutable array to the mutable array. |
1208 | * Copy from the immutable array to the mutable array. | 1169 | // Strip off any LSL wrappers as the script code doesn't expect any. |
1209 | * Strip off any LSL wrappers as the script code doesn't expect any. | ||
1210 | */ | ||
1211 | object[] srcarr = srclist.Data; | 1170 | object[] srcarr = srclist.Data; |
1212 | Array dstarr = (Array)dstarray.instVars.iarObjects[0]; | 1171 | Array dstarr = (Array)dstarray.instVars.iarObjects[0]; |
1213 | 1172 | ||
@@ -1233,18 +1192,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1233 | */ | 1192 | */ |
1234 | public static string xmrChars2String(object srcar, int start, int count) | 1193 | public static string xmrChars2String(object srcar, int start, int count) |
1235 | { | 1194 | { |
1236 | /* | 1195 | // Make sure they gave us a script-defined array object. |
1237 | * Make sure they gave us a script-defined array object. | ||
1238 | */ | ||
1239 | XMRSDTypeClObj array = (XMRSDTypeClObj)srcar; | 1196 | XMRSDTypeClObj array = (XMRSDTypeClObj)srcar; |
1240 | TokenDeclSDTypeClass sdtClass = array.sdtcClass; | 1197 | TokenDeclSDTypeClass sdtClass = array.sdtcClass; |
1241 | if(sdtClass.arrayOfRank == 0) | 1198 | if(sdtClass.arrayOfRank == 0) |
1242 | throw new InvalidCastException("only do arrays not " + sdtClass.longName.val); | 1199 | throw new InvalidCastException("only do arrays not " + sdtClass.longName.val); |
1243 | 1200 | ||
1244 | /* | 1201 | // We get a type cast error from mono if they didn't give us a character array. |
1245 | * We get a type cast error from mono if they didn't give us a character array. | 1202 | // But if it is ok, create a string from the requested characters. |
1246 | * But if it is ok, create a string from the requested characters. | ||
1247 | */ | ||
1248 | char[] srcarray = (char[])array.instVars.iarObjects[0]; | 1203 | char[] srcarray = (char[])array.instVars.iarObjects[0]; |
1249 | return new string(srcarray, start, count); | 1204 | return new string(srcarray, start, count); |
1250 | } | 1205 | } |
@@ -1259,18 +1214,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1259 | */ | 1214 | */ |
1260 | public static void xmrString2Chars(string srcstr, int srcstart, object dstobj, int dststart, int count) | 1215 | public static void xmrString2Chars(string srcstr, int srcstart, object dstobj, int dststart, int count) |
1261 | { | 1216 | { |
1262 | /* | 1217 | // Make sure they gave us a script-defined array object. |
1263 | * Make sure they gave us a script-defined array object. | ||
1264 | */ | ||
1265 | XMRSDTypeClObj dstarray = (XMRSDTypeClObj)dstobj; | 1218 | XMRSDTypeClObj dstarray = (XMRSDTypeClObj)dstobj; |
1266 | TokenDeclSDTypeClass sdtClass = dstarray.sdtcClass; | 1219 | TokenDeclSDTypeClass sdtClass = dstarray.sdtcClass; |
1267 | if(sdtClass.arrayOfType == null) | 1220 | if(sdtClass.arrayOfType == null) |
1268 | throw new InvalidCastException("only do arrays not " + sdtClass.longName.val); | 1221 | throw new InvalidCastException("only do arrays not " + sdtClass.longName.val); |
1269 | 1222 | ||
1270 | /* | 1223 | // We get a type cast error from mono if they didn't give us a character array. |
1271 | * We get a type cast error from mono if they didn't give us a character array. | 1224 | // But if it is ok, copy from the string to the character array. |
1272 | * But if it is ok, copy from the string to the character array. | ||
1273 | */ | ||
1274 | char[] dstarr = (char[])dstarray.instVars.iarObjects[0]; | 1225 | char[] dstarr = (char[])dstarray.instVars.iarObjects[0]; |
1275 | for(int i = 0; i < count; i++) | 1226 | for(int i = 0; i < count; i++) |
1276 | dstarr[i + dststart] = srcstr[i + srcstart]; | 1227 | dstarr[i + dststart] = srcstr[i + srcstart]; |
@@ -1343,12 +1294,12 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1343 | 1294 | ||
1344 | // '"'<string>'"' | 1295 | // '"'<string>'"' |
1345 | case '"': | 1296 | case '"': |
1346 | { | 1297 | { |
1347 | --idx; | 1298 | --idx; |
1348 | string val = ParseJSONString(json, ref idx); | 1299 | string val = ParseJSONString(json, ref idx); |
1349 | dict.SetByKey(keys, val); | 1300 | dict.SetByKey(keys, val); |
1350 | break; | 1301 | break; |
1351 | } | 1302 | } |
1352 | // true false null | 1303 | // true false null |
1353 | case 't': | 1304 | case 't': |
1354 | if(json.Substring(idx, 3) != "rue") | 1305 | if(json.Substring(idx, 3) != "rue") |
@@ -1373,12 +1324,12 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1373 | 1324 | ||
1374 | // otherwise assume it's a number | 1325 | // otherwise assume it's a number |
1375 | default: | 1326 | default: |
1376 | { | 1327 | { |
1377 | --idx; | 1328 | --idx; |
1378 | object val = ParseJSONNumber(json, ref idx); | 1329 | object val = ParseJSONNumber(json, ref idx); |
1379 | dict.SetByKey(keys, val); | 1330 | dict.SetByKey(keys, val); |
1380 | break; | 1331 | break; |
1381 | } | 1332 | } |
1382 | } | 1333 | } |
1383 | return idx; | 1334 | return idx; |
1384 | } | 1335 | } |
@@ -1805,9 +1756,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1805 | { | 1756 | { |
1806 | BinaryWriter mow = this.migrateOutWriter; | 1757 | BinaryWriter mow = this.migrateOutWriter; |
1807 | 1758 | ||
1808 | /* | 1759 | // Value types (including nulls) are always output directly. |
1809 | * Value types (including nulls) are always output directly. | ||
1810 | */ | ||
1811 | if(graph == null) | 1760 | if(graph == null) |
1812 | { | 1761 | { |
1813 | mow.Write((byte)Ser.NULL); | 1762 | mow.Write((byte)Ser.NULL); |
@@ -1893,20 +1842,16 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1893 | return; | 1842 | return; |
1894 | } | 1843 | } |
1895 | 1844 | ||
1896 | /* | 1845 | // Script instance pointer is always just that. |
1897 | * Script instance pointer is always just that. | ||
1898 | */ | ||
1899 | if(graph == this) | 1846 | if(graph == this) |
1900 | { | 1847 | { |
1901 | mow.Write((byte)Ser.XMRINST); | 1848 | mow.Write((byte)Ser.XMRINST); |
1902 | return; | 1849 | return; |
1903 | } | 1850 | } |
1904 | 1851 | ||
1905 | /* | 1852 | // Convert lists to object type. |
1906 | * Convert lists to object type. | 1853 | // This is compatible with old migration data and also |
1907 | * This is compatible with old migration data and also | 1854 | // two vars pointing to same list won't duplicate it. |
1908 | * two vars pointing to same list won't duplicate it. | ||
1909 | */ | ||
1910 | if(graph is LSL_List) | 1855 | if(graph is LSL_List) |
1911 | { | 1856 | { |
1912 | object[] data = ((LSL_List)graph).Data; | 1857 | object[] data = ((LSL_List)graph).Data; |
@@ -1920,14 +1865,12 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1920 | graph = oll; | 1865 | graph = oll; |
1921 | } | 1866 | } |
1922 | 1867 | ||
1923 | /* | 1868 | // If this same exact object was already serialized, |
1924 | * If this same exact object was already serialized, | 1869 | // just output an index telling the receiver to use |
1925 | * just output an index telling the receiver to use | 1870 | // that same old object, rather than creating a whole |
1926 | * that same old object, rather than creating a whole | 1871 | // new object with the same values. Also this prevents |
1927 | * new object with the same values. Also this prevents | 1872 | // self-referencing objects (like arrays) from causing |
1928 | * self-referencing objects (like arrays) from causing | 1873 | // an infinite loop. |
1929 | * an infinite loop. | ||
1930 | */ | ||
1931 | int ident; | 1874 | int ident; |
1932 | if(this.migrateOutObjects.TryGetValue(graph, out ident)) | 1875 | if(this.migrateOutObjects.TryGetValue(graph, out ident)) |
1933 | { | 1876 | { |
@@ -1936,20 +1879,16 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1936 | return; | 1879 | return; |
1937 | } | 1880 | } |
1938 | 1881 | ||
1939 | /* | 1882 | // Object not seen before, save its address with an unique |
1940 | * Object not seen before, save its address with an unique | 1883 | // ident number that the receiver can easily regenerate. |
1941 | * ident number that the receiver can easily regenerate. | ||
1942 | */ | ||
1943 | ident = this.migrateOutObjects.Count; | 1884 | ident = this.migrateOutObjects.Count; |
1944 | this.migrateOutObjects.Add(graph, ident); | 1885 | this.migrateOutObjects.Add(graph, ident); |
1945 | 1886 | ||
1946 | /* | 1887 | // Now output the object's value(s). |
1947 | * Now output the object's value(s). | 1888 | // If the object self-references, the object is alreay entered |
1948 | * If the object self-references, the object is alreay entered | 1889 | // in the dictionary and so the self-reference will just emit |
1949 | * in the dictionary and so the self-reference will just emit | 1890 | // a DUPREF tag instead of trying to output the whole object |
1950 | * a DUPREF tag instead of trying to output the whole object | 1891 | // again. |
1951 | * again. | ||
1952 | */ | ||
1953 | if(graph is ObjLslList) | 1892 | if(graph is ObjLslList) |
1954 | { | 1893 | { |
1955 | mow.Write((byte)Ser.LSLLIST); | 1894 | mow.Write((byte)Ser.LSLLIST); |
@@ -2182,43 +2121,43 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2182 | return new LSL_Key((string)RecvObjValue()); | 2121 | return new LSL_Key((string)RecvObjValue()); |
2183 | 2122 | ||
2184 | case Ser.LSLLIST: | 2123 | case Ser.LSLLIST: |
2185 | { | 2124 | { |
2186 | this.migrateInObjects.Add(ident, null); // placeholder | 2125 | this.migrateInObjects.Add(ident, null); // placeholder |
2187 | object[] data = (object[])RecvObjValue(); // read data, maybe using another index | 2126 | object[] data = (object[])RecvObjValue(); // read data, maybe using another index |
2188 | LSL_List list = new LSL_List(data); // make LSL-level list | 2127 | LSL_List list = new LSL_List(data); // make LSL-level list |
2189 | this.migrateInObjects[ident] = list; // fill in slot | 2128 | this.migrateInObjects[ident] = list; // fill in slot |
2190 | return list; | 2129 | return list; |
2191 | } | 2130 | } |
2192 | 2131 | ||
2193 | case Ser.LSLROT: | 2132 | case Ser.LSLROT: |
2194 | { | 2133 | { |
2195 | double x = mir.ReadDouble(); | 2134 | double x = mir.ReadDouble(); |
2196 | double y = mir.ReadDouble(); | 2135 | double y = mir.ReadDouble(); |
2197 | double z = mir.ReadDouble(); | 2136 | double z = mir.ReadDouble(); |
2198 | double w = mir.ReadDouble(); | 2137 | double w = mir.ReadDouble(); |
2199 | return new LSL_Rotation(x, y, z, w); | 2138 | return new LSL_Rotation(x, y, z, w); |
2200 | } | 2139 | } |
2201 | case Ser.LSLSTR: | 2140 | case Ser.LSLSTR: |
2202 | return new LSL_String((string)RecvObjValue()); | 2141 | return new LSL_String((string)RecvObjValue()); |
2203 | 2142 | ||
2204 | case Ser.LSLVEC: | 2143 | case Ser.LSLVEC: |
2205 | { | 2144 | { |
2206 | double x = mir.ReadDouble(); | 2145 | double x = mir.ReadDouble(); |
2207 | double y = mir.ReadDouble(); | 2146 | double y = mir.ReadDouble(); |
2208 | double z = mir.ReadDouble(); | 2147 | double z = mir.ReadDouble(); |
2209 | return new LSL_Vector(x, y, z); | 2148 | return new LSL_Vector(x, y, z); |
2210 | } | 2149 | } |
2211 | 2150 | ||
2212 | case Ser.SYSARRAY: | 2151 | case Ser.SYSARRAY: |
2213 | { | 2152 | { |
2214 | Type eletype = String2SysType(mir.ReadString()); | 2153 | Type eletype = String2SysType(mir.ReadString()); |
2215 | int length = mir.ReadInt32(); | 2154 | int length = mir.ReadInt32(); |
2216 | Array array = Array.CreateInstance(eletype, length); | 2155 | Array array = Array.CreateInstance(eletype, length); |
2217 | this.migrateInObjects.Add(ident, array); | 2156 | this.migrateInObjects.Add(ident, array); |
2218 | for(int i = 0; i < length; i++) | 2157 | for(int i = 0; i < length; i++) |
2219 | array.SetValue(RecvObjValue(), i); | 2158 | array.SetValue(RecvObjValue(), i); |
2220 | return array; | 2159 | return array; |
2221 | } | 2160 | } |
2222 | 2161 | ||
2223 | case Ser.SYSBOOL: | 2162 | case Ser.SYSBOOL: |
2224 | return mir.ReadBoolean(); | 2163 | return mir.ReadBoolean(); |
@@ -2241,21 +2180,21 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2241 | return s; | 2180 | return s; |
2242 | 2181 | ||
2243 | case Ser.XMRARRAY: | 2182 | case Ser.XMRARRAY: |
2244 | { | 2183 | { |
2245 | XMR_Array array = new XMR_Array(this); | 2184 | XMR_Array array = new XMR_Array(this); |
2246 | this.migrateInObjects.Add(ident, array); | 2185 | this.migrateInObjects.Add(ident, array); |
2247 | array.RecvArrayObj(this.RecvObjValue); | 2186 | array.RecvArrayObj(this.RecvObjValue); |
2248 | return array; | 2187 | return array; |
2249 | } | 2188 | } |
2250 | 2189 | ||
2251 | case Ser.DUPREF: | 2190 | case Ser.DUPREF: |
2252 | { | 2191 | { |
2253 | ident = mir.ReadInt32(); | 2192 | ident = mir.ReadInt32(); |
2254 | object obj = this.migrateInObjects[ident]; | 2193 | object obj = this.migrateInObjects[ident]; |
2255 | if(obj is ObjLslList) | 2194 | if(obj is ObjLslList) |
2256 | obj = new LSL_List(((ObjLslList)obj).objarray); | 2195 | obj = new LSL_List(((ObjLslList)obj).objarray); |
2257 | return obj; | 2196 | return obj; |
2258 | } | 2197 | } |
2259 | 2198 | ||
2260 | case Ser.XMRINST: | 2199 | case Ser.XMRINST: |
2261 | return this; | 2200 | return this; |
@@ -2276,29 +2215,29 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2276 | return clobj; | 2215 | return clobj; |
2277 | 2216 | ||
2278 | case Ser.SYSERIAL: | 2217 | case Ser.SYSERIAL: |
2279 | { | 2218 | { |
2280 | int rawLength = mir.ReadInt32(); | 2219 | int rawLength = mir.ReadInt32(); |
2281 | byte[] rawBytes = mir.ReadBytes(rawLength); | 2220 | byte[] rawBytes = mir.ReadBytes(rawLength); |
2282 | MemoryStream memoryStream = new MemoryStream(rawBytes); | 2221 | MemoryStream memoryStream = new MemoryStream(rawBytes); |
2283 | System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bformatter = | 2222 | System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bformatter = |
2284 | new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(); | 2223 | new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(); |
2285 | object graph = bformatter.Deserialize(memoryStream); | 2224 | object graph = bformatter.Deserialize(memoryStream); |
2286 | this.migrateInObjects.Add(ident, graph); | 2225 | this.migrateInObjects.Add(ident, graph); |
2287 | return graph; | 2226 | return graph; |
2288 | } | 2227 | } |
2289 | 2228 | ||
2290 | case Ser.THROWNEX: | 2229 | case Ser.THROWNEX: |
2291 | { | 2230 | { |
2292 | int rawLength = mir.ReadInt32(); | 2231 | int rawLength = mir.ReadInt32(); |
2293 | byte[] rawBytes = mir.ReadBytes(rawLength); | 2232 | byte[] rawBytes = mir.ReadBytes(rawLength); |
2294 | MemoryStream memoryStream = new MemoryStream(rawBytes); | 2233 | MemoryStream memoryStream = new MemoryStream(rawBytes); |
2295 | System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bformatter = | 2234 | System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bformatter = |
2296 | new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(); | 2235 | new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(); |
2297 | object graph = bformatter.Deserialize(memoryStream); | 2236 | object graph = bformatter.Deserialize(memoryStream); |
2298 | this.migrateInObjects.Add(ident, graph); | 2237 | this.migrateInObjects.Add(ident, graph); |
2299 | ((ScriptThrownException)graph).thrown = RecvObjValue(); | 2238 | ((ScriptThrownException)graph).thrown = RecvObjValue(); |
2300 | return graph; | 2239 | return graph; |
2301 | } | 2240 | } |
2302 | 2241 | ||
2303 | default: | 2242 | default: |
2304 | throw new Exception("bad stream code " + code.ToString()); | 2243 | throw new Exception("bad stream code " + code.ToString()); |
diff --git a/OpenSim/Region/ScriptEngine/YEngine/XMRInstBackend.cs b/OpenSim/Region/ScriptEngine/YEngine/XMRInstBackend.cs index fb5c75e..833211f 100644 --- a/OpenSim/Region/ScriptEngine/YEngine/XMRInstBackend.cs +++ b/OpenSim/Region/ScriptEngine/YEngine/XMRInstBackend.cs | |||
@@ -249,22 +249,16 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
249 | { | 249 | { |
250 | lock(m_QueueLock) | 250 | lock(m_QueueLock) |
251 | { | 251 | { |
252 | /* | 252 | // Say how long to sleep. |
253 | * Say how long to sleep. | ||
254 | */ | ||
255 | m_SleepUntil = DateTime.UtcNow + TimeSpan.FromMilliseconds(ms); | 253 | m_SleepUntil = DateTime.UtcNow + TimeSpan.FromMilliseconds(ms); |
256 | 254 | ||
257 | /* | 255 | // Don't wake on any events. |
258 | * Don't wake on any events. | ||
259 | */ | ||
260 | m_SleepEventMask1 = 0; | 256 | m_SleepEventMask1 = 0; |
261 | m_SleepEventMask2 = 0; | 257 | m_SleepEventMask2 = 0; |
262 | } | 258 | } |
263 | 259 | ||
264 | /* | 260 | // The compiler follows all calls to llSleep() with a call to CheckRun(). |
265 | * The compiler follows all calls to llSleep() with a call to CheckRun(). | 261 | // So tell CheckRun() to suspend the microthread. |
266 | * So tell CheckRun() to suspend the microthread. | ||
267 | */ | ||
268 | suspendOnCheckRunTemp = true; | 262 | suspendOnCheckRunTemp = true; |
269 | } | 263 | } |
270 | 264 | ||
@@ -327,10 +321,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
327 | if(callMode == CallMode_NORMAL) | 321 | if(callMode == CallMode_NORMAL) |
328 | goto findevent; | 322 | goto findevent; |
329 | 323 | ||
330 | /* | 324 | // Stack frame is being restored as saved via CheckRun...(). |
331 | * Stack frame is being restored as saved via CheckRun...(). | 325 | // Restore necessary values then jump to __call<n> label to resume processing. |
332 | * Restore necessary values then jump to __call<n> label to resume processing. | ||
333 | */ | ||
334 | sv = RestoreStackFrame("xmrEventDequeue", out callNo); | 326 | sv = RestoreStackFrame("xmrEventDequeue", out callNo); |
335 | sleepUntil = DateTime.Parse((string)sv[0]); | 327 | sleepUntil = DateTime.Parse((string)sv[0]); |
336 | returnMask1 = (int)sv[1]; | 328 | returnMask1 = (int)sv[1]; |
@@ -353,9 +345,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
353 | } | 345 | } |
354 | throw new ScriptBadCallNoException(callNo); | 346 | throw new ScriptBadCallNoException(callNo); |
355 | 347 | ||
356 | /* | 348 | // Find first event that matches either the return or background masks. |
357 | * Find first event that matches either the return or background masks. | ||
358 | */ | ||
359 | findevent: | 349 | findevent: |
360 | Monitor.Enter(m_QueueLock); | 350 | Monitor.Enter(m_QueueLock); |
361 | for(lln = m_EventQueue.First; lln != null; lln = lln.Next) | 351 | for(lln = m_EventQueue.First; lln != null; lln = lln.Next) |
@@ -369,9 +359,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
369 | goto remfromq; | 359 | goto remfromq; |
370 | } | 360 | } |
371 | 361 | ||
372 | /* | 362 | // Nothing found, sleep while one comes in. |
373 | * Nothing found, sleep while one comes in. | ||
374 | */ | ||
375 | m_SleepUntil = sleepUntil; | 363 | m_SleepUntil = sleepUntil; |
376 | m_SleepEventMask1 = mask1; | 364 | m_SleepEventMask1 = mask1; |
377 | m_SleepEventMask2 = mask2; | 365 | m_SleepEventMask2 = mask2; |
@@ -382,9 +370,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
382 | CheckRunQuick(); | 370 | CheckRunQuick(); |
383 | goto checktmo; | 371 | goto checktmo; |
384 | 372 | ||
385 | /* | 373 | // Found one, remove it from queue. |
386 | * Found one, remove it from queue. | ||
387 | */ | ||
388 | remfromq: | 374 | remfromq: |
389 | m_EventQueue.Remove(lln); | 375 | m_EventQueue.Remove(lln); |
390 | if((uint)evc1 < (uint)m_EventCounts.Length) | 376 | if((uint)evc1 < (uint)m_EventCounts.Length) |
@@ -393,16 +379,12 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
393 | Monitor.Exit(m_QueueLock); | 379 | Monitor.Exit(m_QueueLock); |
394 | m_InstEHEvent++; | 380 | m_InstEHEvent++; |
395 | 381 | ||
396 | /* | 382 | // See if returnable or background event. |
397 | * See if returnable or background event. | ||
398 | */ | ||
399 | if((((uint)evc1 < (uint)32) && (((returnMask1 >> evc1) & 1) != 0)) || | 383 | if((((uint)evc1 < (uint)32) && (((returnMask1 >> evc1) & 1) != 0)) || |
400 | (((uint)evc2 < (uint)32) && (((returnMask2 >> evc2) & 1) != 0))) | 384 | (((uint)evc2 < (uint)32) && (((returnMask2 >> evc2) & 1) != 0))) |
401 | { | 385 | { |
402 | /* | 386 | // Returnable event, return its parameters in a list. |
403 | * Returnable event, return its parameters in a list. | 387 | // Also set the detect parameters to what the event has. |
404 | * Also set the detect parameters to what the event has. | ||
405 | */ | ||
406 | int plen = evt.Params.Length; | 388 | int plen = evt.Params.Length; |
407 | object[] plist = new object[plen + 1]; | 389 | object[] plist = new object[plen + 1]; |
408 | plist[0] = (LSL_Integer)evc1; | 390 | plist[0] = (LSL_Integer)evc1; |
@@ -421,10 +403,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
421 | return new LSL_List(plist); | 403 | return new LSL_List(plist); |
422 | } | 404 | } |
423 | 405 | ||
424 | /* | 406 | // It is a background event, simply call its event handler, |
425 | * It is a background event, simply call its event handler, | 407 | // then check event queue again. |
426 | * then check event queue again. | ||
427 | */ | ||
428 | callNo = 1; | 408 | callNo = 1; |
429 | __call1: | 409 | __call1: |
430 | ScriptEventHandler seh = m_ObjCode.scriptEventHandlerTable[stateCode, evc1]; | 410 | ScriptEventHandler seh = m_ObjCode.scriptEventHandlerTable[stateCode, evc1]; |
@@ -450,28 +430,21 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
450 | this.eventCode = saveEventCode; | 430 | this.eventCode = saveEventCode; |
451 | } | 431 | } |
452 | 432 | ||
453 | /* | 433 | // Keep waiting until we find a returnable event or timeout. |
454 | * Keep waiting until we find a returnable event or timeout. | ||
455 | */ | ||
456 | checktmo: | 434 | checktmo: |
457 | if(DateTime.UtcNow < sleepUntil) | 435 | if(DateTime.UtcNow < sleepUntil) |
458 | goto findevent; | 436 | goto findevent; |
459 | 437 | ||
460 | /* | 438 | // We timed out, return an empty list. |
461 | * We timed out, return an empty list. | ||
462 | */ | ||
463 | return emptyList; | 439 | return emptyList; |
464 | } | 440 | } |
465 | finally | 441 | finally |
466 | { | 442 | { |
467 | if(callMode != CallMode_NORMAL) | 443 | if(callMode != CallMode_NORMAL) |
468 | { | 444 | { |
469 | 445 | // Stack frame is being saved by CheckRun...(). | |
470 | /* | 446 | // Save everything we need at the __call<n> labels so we can restore it |
471 | * Stack frame is being saved by CheckRun...(). | 447 | // when we need to. |
472 | * Save everything we need at the __call<n> labels so we can restore it | ||
473 | * when we need to. | ||
474 | */ | ||
475 | sv = CaptureStackFrame("xmrEventDequeue", callNo, 9); | 448 | sv = CaptureStackFrame("xmrEventDequeue", callNo, 9); |
476 | sv[0] = sleepUntil.ToString(); // needed at __call0,__call1 | 449 | sv[0] = sleepUntil.ToString(); // needed at __call0,__call1 |
477 | sv[1] = returnMask1; // needed at __call0,__call1 | 450 | sv[1] = returnMask1; // needed at __call0,__call1 |
@@ -606,22 +579,16 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
606 | */ | 579 | */ |
607 | public override void StateChange() | 580 | public override void StateChange() |
608 | { | 581 | { |
609 | /* | 582 | // Cancel any llListen()s etc. |
610 | * Cancel any llListen()s etc. | 583 | // But llSetTimerEvent() should persist. |
611 | * But llSetTimerEvent() should persist. | ||
612 | */ | ||
613 | object[] timers = m_XMRLSLApi.acm.TimerPlugin.GetSerializationData(m_ItemID); | 584 | object[] timers = m_XMRLSLApi.acm.TimerPlugin.GetSerializationData(m_ItemID); |
614 | AsyncCommandManager.RemoveScript(m_Engine, m_LocalID, m_ItemID); | 585 | AsyncCommandManager.RemoveScript(m_Engine, m_LocalID, m_ItemID); |
615 | m_XMRLSLApi.acm.TimerPlugin.CreateFromData(m_LocalID, m_ItemID, UUID.Zero, timers); | 586 | m_XMRLSLApi.acm.TimerPlugin.CreateFromData(m_LocalID, m_ItemID, UUID.Zero, timers); |
616 | 587 | ||
617 | /* | 588 | // Tell whoever cares which event handlers the new state has. |
618 | * Tell whoever cares which event handlers the new state has. | ||
619 | */ | ||
620 | m_Part.SetScriptEvents(m_ItemID, GetStateEventFlags(stateCode)); | 589 | m_Part.SetScriptEvents(m_ItemID, GetStateEventFlags(stateCode)); |
621 | 590 | ||
622 | /* | 591 | // Clear out any old events from the queue. |
623 | * Clear out any old events from the queue. | ||
624 | */ | ||
625 | lock(m_QueueLock) | 592 | lock(m_QueueLock) |
626 | { | 593 | { |
627 | m_EventQueue.Clear(); | 594 | m_EventQueue.Clear(); |
diff --git a/OpenSim/Region/ScriptEngine/YEngine/XMRInstCtor.cs b/OpenSim/Region/ScriptEngine/YEngine/XMRInstCtor.cs index 68ec322..85867ab 100644 --- a/OpenSim/Region/ScriptEngine/YEngine/XMRInstCtor.cs +++ b/OpenSim/Region/ScriptEngine/YEngine/XMRInstCtor.cs | |||
@@ -390,9 +390,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
390 | LoadScriptState(doc); | 390 | LoadScriptState(doc); |
391 | } | 391 | } |
392 | 392 | ||
393 | /* | 393 | // Post event(s) saying what caused the script to start. |
394 | * Post event(s) saying what caused the script to start. | ||
395 | */ | ||
396 | if(m_PostOnRez) | 394 | if(m_PostOnRez) |
397 | { | 395 | { |
398 | PostEvent(new EventParams("on_rez", | 396 | PostEvent(new EventParams("on_rez", |
diff --git a/OpenSim/Region/ScriptEngine/YEngine/XMRInstMisc.cs b/OpenSim/Region/ScriptEngine/YEngine/XMRInstMisc.cs index 8f020ce..0af3d37 100644 --- a/OpenSim/Region/ScriptEngine/YEngine/XMRInstMisc.cs +++ b/OpenSim/Region/ScriptEngine/YEngine/XMRInstMisc.cs | |||
@@ -74,14 +74,10 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
74 | */ | 74 | */ |
75 | public void Dispose() | 75 | public void Dispose() |
76 | { | 76 | { |
77 | /* | 77 | // Tell script stop executing next time it calls CheckRun(). |
78 | * Tell script stop executing next time it calls CheckRun(). | ||
79 | */ | ||
80 | suspendOnCheckRunHold = true; | 78 | suspendOnCheckRunHold = true; |
81 | 79 | ||
82 | /* | 80 | // Don't send us any more events. |
83 | * Don't send us any more events. | ||
84 | */ | ||
85 | lock(m_RunLock) | 81 | lock(m_RunLock) |
86 | { | 82 | { |
87 | if(m_Part != null) | 83 | if(m_Part != null) |
@@ -92,10 +88,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
92 | } | 88 | } |
93 | } | 89 | } |
94 | 90 | ||
95 | /* | 91 | // Let script methods get garbage collected if no one else is using |
96 | * Let script methods get garbage collected if no one else is using | 92 | // them. |
97 | * them. | ||
98 | */ | ||
99 | DecObjCodeRefCount(); | 93 | DecObjCodeRefCount(); |
100 | } | 94 | } |
101 | 95 | ||
@@ -244,26 +238,20 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
244 | 238 | ||
245 | public static string GetScriptFileName(string scriptBasePath, string filename) | 239 | public static string GetScriptFileName(string scriptBasePath, string filename) |
246 | { | 240 | { |
247 | /* | 241 | // Get old path, ie, all files lumped in a single huge directory. |
248 | * Get old path, ie, all files lumped in a single huge directory. | ||
249 | */ | ||
250 | string oldPath = Path.Combine(scriptBasePath, filename); | 242 | string oldPath = Path.Combine(scriptBasePath, filename); |
251 | 243 | ||
252 | /* | 244 | // Get new path, ie, files split up based on first 2 chars of name. |
253 | * Get new path, ie, files split up based on first 2 chars of name. | 245 | // string subdir = filename.Substring (0, 2); |
254 | */ | 246 | // filename = filename.Substring (2); |
255 | // string subdir = filename.Substring (0, 2); | ||
256 | // filename = filename.Substring (2); | ||
257 | string subdir = filename.Substring(0, 1); | 247 | string subdir = filename.Substring(0, 1); |
258 | filename = filename.Substring(1); | 248 | filename = filename.Substring(1); |
259 | scriptBasePath = Path.Combine(scriptBasePath, subdir); | 249 | scriptBasePath = Path.Combine(scriptBasePath, subdir); |
260 | Directory.CreateDirectory(scriptBasePath); | 250 | Directory.CreateDirectory(scriptBasePath); |
261 | string newPath = Path.Combine(scriptBasePath, filename); | 251 | string newPath = Path.Combine(scriptBasePath, filename); |
262 | 252 | ||
263 | /* | 253 | // If file exists only in old location, move to new location. |
264 | * If file exists only in old location, move to new location. | 254 | // If file exists in both locations, delete old location. |
265 | * If file exists in both locations, delete old location. | ||
266 | */ | ||
267 | if(File.Exists(oldPath)) | 255 | if(File.Exists(oldPath)) |
268 | { | 256 | { |
269 | if(File.Exists(newPath)) | 257 | if(File.Exists(newPath)) |
@@ -276,9 +264,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
276 | } | 264 | } |
277 | } | 265 | } |
278 | 266 | ||
279 | /* | 267 | // Always return new location. |
280 | * Always return new location. | ||
281 | */ | ||
282 | return newPath; | 268 | return newPath; |
283 | } | 269 | } |
284 | 270 | ||
diff --git a/OpenSim/Region/ScriptEngine/YEngine/XMRInstRun.cs b/OpenSim/Region/ScriptEngine/YEngine/XMRInstRun.cs index 8603fbf..8ac9794 100644 --- a/OpenSim/Region/ScriptEngine/YEngine/XMRInstRun.cs +++ b/OpenSim/Region/ScriptEngine/YEngine/XMRInstRun.cs | |||
@@ -66,36 +66,27 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
66 | ScriptEventCode evc = (ScriptEventCode)Enum.Parse(typeof(ScriptEventCode), | 66 | ScriptEventCode evc = (ScriptEventCode)Enum.Parse(typeof(ScriptEventCode), |
67 | evt.EventName); | 67 | evt.EventName); |
68 | 68 | ||
69 | /* | 69 | // Put event on end of event queue. |
70 | * Put event on end of event queue. | ||
71 | */ | ||
72 | bool startIt = false; | 70 | bool startIt = false; |
73 | bool wakeIt = false; | 71 | bool wakeIt = false; |
74 | lock(m_QueueLock) | 72 | lock(m_QueueLock) |
75 | { | 73 | { |
76 | bool construct = (m_IState == XMRInstState.CONSTRUCT); | 74 | bool construct = (m_IState == XMRInstState.CONSTRUCT); |
77 | 75 | ||
78 | /* | 76 | // Ignore event if we don't even have such an handler in any state. |
79 | * Ignore event if we don't even have such an handler in any state. | 77 | // We can't be state-specific here because state might be different |
80 | * We can't be state-specific here because state might be different | 78 | // by the time this event is dequeued and delivered to the script. |
81 | * by the time this event is dequeued and delivered to the script. | ||
82 | */ | ||
83 | if(!construct && // make sure m_HaveEventHandlers is filled in | 79 | if(!construct && // make sure m_HaveEventHandlers is filled in |
84 | ((uint)evc < (uint)m_HaveEventHandlers.Length) && | 80 | ((uint)evc < (uint)m_HaveEventHandlers.Length) && |
85 | !m_HaveEventHandlers[(int)evc]) // don't bother if we don't have such a handler in any state | 81 | !m_HaveEventHandlers[(int)evc]) // don't bother if we don't have such a handler in any state |
86 | return; | 82 | return; |
87 | 83 | ||
88 | 84 | // Not running means we ignore any incoming events. | |
89 | /* | 85 | // But queue if still constructing because m_Running is not yet valid. |
90 | * Not running means we ignore any incoming events. | ||
91 | * But queue if still constructing because m_Running is not yet valid. | ||
92 | */ | ||
93 | if(!m_Running && !construct) | 86 | if(!m_Running && !construct) |
94 | return; | 87 | return; |
95 | 88 | ||
96 | /* | 89 | // Only so many of each event type allowed to queue. |
97 | * Only so many of each event type allowed to queue. | ||
98 | */ | ||
99 | if((uint)evc < (uint)m_EventCounts.Length) | 90 | if((uint)evc < (uint)m_EventCounts.Length) |
100 | { | 91 | { |
101 | if(evc == ScriptEventCode.timer) | 92 | if(evc == ScriptEventCode.timer) |
@@ -109,29 +100,23 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
109 | m_EventCounts[(int)evc]++; | 100 | m_EventCounts[(int)evc]++; |
110 | } | 101 | } |
111 | 102 | ||
112 | /* | 103 | // Put event on end of instance's event queue. |
113 | * Put event on end of instance's event queue. | ||
114 | */ | ||
115 | LinkedListNode<EventParams> lln = new LinkedListNode<EventParams>(evt); | 104 | LinkedListNode<EventParams> lln = new LinkedListNode<EventParams>(evt); |
116 | switch(evc) | 105 | switch(evc) |
117 | { | 106 | { |
118 | /* | 107 | // These need to go first. The only time we manually |
119 | * These need to go first. The only time we manually | 108 | // queue them is for the default state_entry() and we |
120 | * queue them is for the default state_entry() and we | 109 | // need to make sure they go before any attach() events |
121 | * need to make sure they go before any attach() events | 110 | // so the heapLimit value gets properly initialized. |
122 | * so the heapLimit value gets properly initialized. | ||
123 | */ | ||
124 | case ScriptEventCode.state_entry: | 111 | case ScriptEventCode.state_entry: |
125 | m_EventQueue.AddFirst(lln); | 112 | m_EventQueue.AddFirst(lln); |
126 | break; | 113 | break; |
127 | 114 | ||
128 | /* | 115 | // The attach event sneaks to the front of the queue. |
129 | * The attach event sneaks to the front of the queue. | 116 | // This is needed for quantum limiting to work because |
130 | * This is needed for quantum limiting to work because | 117 | // we want the attach(NULL_KEY) event to come in front |
131 | * we want the attach(NULL_KEY) event to come in front | 118 | // of all others so the m_DetachQuantum won't run out |
132 | * of all others so the m_DetachQuantum won't run out | 119 | // before attach(NULL_KEY) is executed. |
133 | * before attach(NULL_KEY) is executed. | ||
134 | */ | ||
135 | case ScriptEventCode.attach: | 120 | case ScriptEventCode.attach: |
136 | if(evt.Params[0].ToString() == UUID.Zero.ToString()) | 121 | if(evt.Params[0].ToString() == UUID.Zero.ToString()) |
137 | { | 122 | { |
@@ -150,11 +135,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
150 | else | 135 | else |
151 | m_EventQueue.AddBefore(lln2, lln); | 136 | m_EventQueue.AddBefore(lln2, lln); |
152 | 137 | ||
153 | /* If we're detaching, limit the qantum. This will also | 138 | // If we're detaching, limit the qantum. This will also |
154 | * cause the script to self-suspend after running this | 139 | // cause the script to self-suspend after running this |
155 | * event | 140 | // event |
156 | */ | ||
157 | |||
158 | m_DetachReady.Reset(); | 141 | m_DetachReady.Reset(); |
159 | m_DetachQuantum = 100; | 142 | m_DetachQuantum = 100; |
160 | } | 143 | } |
@@ -163,31 +146,25 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
163 | 146 | ||
164 | break; | 147 | break; |
165 | 148 | ||
166 | /* | 149 | // All others just go on end in the order queued. |
167 | * All others just go on end in the order queued. | ||
168 | */ | ||
169 | default: | 150 | default: |
170 | m_EventQueue.AddLast(lln); | 151 | m_EventQueue.AddLast(lln); |
171 | break; | 152 | break; |
172 | } | 153 | } |
173 | 154 | ||
174 | /* | 155 | // If instance is idle (ie, not running or waiting to run), |
175 | * If instance is idle (ie, not running or waiting to run), | 156 | // flag it to be on m_StartQueue as we are about to do so. |
176 | * flag it to be on m_StartQueue as we are about to do so. | 157 | // Flag it now before unlocking so another thread won't try |
177 | * Flag it now before unlocking so another thread won't try | 158 | // to do the same thing right now. |
178 | * to do the same thing right now. | 159 | // Dont' flag it if it's still suspended! |
179 | * Dont' flag it if it's still suspended! | ||
180 | */ | ||
181 | if((m_IState == XMRInstState.IDLE) && !m_Suspended) | 160 | if((m_IState == XMRInstState.IDLE) && !m_Suspended) |
182 | { | 161 | { |
183 | m_IState = XMRInstState.ONSTARTQ; | 162 | m_IState = XMRInstState.ONSTARTQ; |
184 | startIt = true; | 163 | startIt = true; |
185 | } | 164 | } |
186 | 165 | ||
187 | /* | 166 | // If instance is sleeping (ie, possibly in xmrEventDequeue), |
188 | * If instance is sleeping (ie, possibly in xmrEventDequeue), | 167 | // wake it up if event is in the mask. |
189 | * wake it up if event is in the mask. | ||
190 | */ | ||
191 | if((m_SleepUntil > DateTime.UtcNow) && !m_Suspended) | 168 | if((m_SleepUntil > DateTime.UtcNow) && !m_Suspended) |
192 | { | 169 | { |
193 | int evc1 = (int)evc; | 170 | int evc1 = (int)evc; |
@@ -198,16 +175,12 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
198 | } | 175 | } |
199 | } | 176 | } |
200 | 177 | ||
201 | /* | 178 | // If transitioned from IDLE->ONSTARTQ, actually go insert it |
202 | * If transitioned from IDLE->ONSTARTQ, actually go insert it | 179 | // on m_StartQueue and give the RunScriptThread() a wake-up. |
203 | * on m_StartQueue and give the RunScriptThread() a wake-up. | ||
204 | */ | ||
205 | if(startIt) | 180 | if(startIt) |
206 | m_Engine.QueueToStart(this); | 181 | m_Engine.QueueToStart(this); |
207 | 182 | ||
208 | /* | 183 | // Likewise, if the event mask triggered a wake, wake it up. |
209 | * Likewise, if the event mask triggered a wake, wake it up. | ||
210 | */ | ||
211 | if(wakeIt) | 184 | if(wakeIt) |
212 | { | 185 | { |
213 | m_SleepUntil = DateTime.MinValue; | 186 | m_SleepUntil = DateTime.MinValue; |
@@ -215,20 +188,15 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
215 | } | 188 | } |
216 | } | 189 | } |
217 | 190 | ||
218 | /* | 191 | // This is called in the script thread to step script until it calls |
219 | * This is called in the script thread to step script until it calls | 192 | // CheckRun(). It returns what the instance's next state should be, |
220 | * CheckRun(). It returns what the instance's next state should be, | 193 | // ONSLEEPQ, ONYIELDQ, SUSPENDED or FINISHED. |
221 | * ONSLEEPQ, ONYIELDQ, SUSPENDED or FINISHED. | ||
222 | */ | ||
223 | public XMRInstState RunOne() | 194 | public XMRInstState RunOne() |
224 | { | 195 | { |
225 | DateTime now = DateTime.UtcNow; | 196 | DateTime now = DateTime.UtcNow; |
226 | m_SliceStart = Util.GetTimeStampMS(); | 197 | m_SliceStart = Util.GetTimeStampMS(); |
227 | 198 | ||
228 | /* | 199 | // If script has called llSleep(), don't do any more until time is up. |
229 | * If script has called llSleep(), don't do any more until time is | ||
230 | * up. | ||
231 | */ | ||
232 | m_RunOnePhase = "check m_SleepUntil"; | 200 | m_RunOnePhase = "check m_SleepUntil"; |
233 | if(m_SleepUntil > now) | 201 | if(m_SleepUntil > now) |
234 | { | 202 | { |
@@ -236,9 +204,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
236 | return XMRInstState.ONSLEEPQ; | 204 | return XMRInstState.ONSLEEPQ; |
237 | } | 205 | } |
238 | 206 | ||
239 | /* | 207 | // Also, someone may have called Suspend(). |
240 | * Also, someone may have called Suspend(). | ||
241 | */ | ||
242 | m_RunOnePhase = "check m_SuspendCount"; | 208 | m_RunOnePhase = "check m_SuspendCount"; |
243 | if(m_SuspendCount > 0) | 209 | if(m_SuspendCount > 0) |
244 | { | 210 | { |
@@ -246,11 +212,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
246 | return XMRInstState.SUSPENDED; | 212 | return XMRInstState.SUSPENDED; |
247 | } | 213 | } |
248 | 214 | ||
249 | /* | 215 | // Make sure we aren't being migrated in or out and prevent that |
250 | * Make sure we aren't being migrated in or out and prevent that | 216 | // whilst we are in here. If migration has it locked, don't call |
251 | * whilst we are in here. If migration has it locked, don't call | 217 | // back right away, delay a bit so we don't get in infinite loop. |
252 | * back right away, delay a bit so we don't get in infinite loop. | ||
253 | */ | ||
254 | m_RunOnePhase = "lock m_RunLock"; | 218 | m_RunOnePhase = "lock m_RunLock"; |
255 | if(!Monitor.TryEnter(m_RunLock)) | 219 | if(!Monitor.TryEnter(m_RunLock)) |
256 | { | 220 | { |
@@ -264,18 +228,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
264 | CheckRunLockInvariants(true); | 228 | CheckRunLockInvariants(true); |
265 | Exception e = null; | 229 | Exception e = null; |
266 | 230 | ||
267 | /* | 231 | // Maybe it has been Disposed() |
268 | * Maybe it has been Disposed() | ||
269 | */ | ||
270 | if(m_Part == null) | 232 | if(m_Part == null) |
271 | { | 233 | { |
272 | m_RunOnePhase = "runone saw it disposed"; | 234 | m_RunOnePhase = "runone saw it disposed"; |
273 | return XMRInstState.DISPOSED; | 235 | return XMRInstState.DISPOSED; |
274 | } | 236 | } |
275 | 237 | ||
276 | /* | 238 | // Do some more of the last event if it didn't finish. |
277 | * Do some more of the last event if it didn't finish. | ||
278 | */ | ||
279 | if(this.eventCode != ScriptEventCode.None) | 239 | if(this.eventCode != ScriptEventCode.None) |
280 | { | 240 | { |
281 | lock(m_QueueLock) | 241 | lock(m_QueueLock) |
@@ -297,10 +257,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
297 | e = ResumeEx(); | 257 | e = ResumeEx(); |
298 | } | 258 | } |
299 | 259 | ||
300 | /* | 260 | // Otherwise, maybe we can dequeue a new event and start |
301 | * Otherwise, maybe we can dequeue a new event and start | 261 | // processing it. |
302 | * processing it. | ||
303 | */ | ||
304 | else | 262 | else |
305 | { | 263 | { |
306 | m_RunOnePhase = "lock event queue"; | 264 | m_RunOnePhase = "lock event queue"; |
@@ -310,14 +268,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
310 | lock(m_QueueLock) | 268 | lock(m_QueueLock) |
311 | { | 269 | { |
312 | 270 | ||
313 | /* We can't get here unless the script has been resumed | 271 | // We can't get here unless the script has been resumed |
314 | * after creation, then suspended again, and then had | 272 | // after creation, then suspended again, and then had |
315 | * an event posted to it. We just pretend there is no | 273 | // an event posted to it. We just pretend there is no |
316 | * event int he queue and let the normal mechanics | 274 | // event int he queue and let the normal mechanics |
317 | * carry out the suspension. A Resume will handle the | 275 | // carry out the suspension. A Resume will handle the |
318 | * restarting gracefully. This is taking the easy way | 276 | // restarting gracefully. This is taking the easy way |
319 | * out and may be improved in the future. | 277 | // out and may be improved in the future. |
320 | */ | ||
321 | 278 | ||
322 | if(m_Suspended) | 279 | if(m_Suspended) |
323 | { | 280 | { |
@@ -336,11 +293,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
336 | evt.EventName); | 293 | evt.EventName); |
337 | if(evc != ScriptEventCode.attach) | 294 | if(evc != ScriptEventCode.attach) |
338 | { | 295 | { |
339 | /* | 296 | // This is the case where the attach event |
340 | * This is the case where the attach event | 297 | // has completed and another event is queued |
341 | * has completed and another event is queued | 298 | // Stop it from running and suspend |
342 | * Stop it from running and suspend | ||
343 | */ | ||
344 | m_Suspended = true; | 299 | m_Suspended = true; |
345 | m_DetachReady.Set(); | 300 | m_DetachReady.Set(); |
346 | m_DetachQuantum = 0; | 301 | m_DetachQuantum = 0; |
@@ -356,18 +311,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
356 | m_EventCounts[(int)evc]--; | 311 | m_EventCounts[(int)evc]--; |
357 | } | 312 | } |
358 | 313 | ||
359 | /* | 314 | // If there is no event to dequeue, don't run this script |
360 | * If there is no event to dequeue, don't run this script | 315 | // until another event gets queued. |
361 | * until another event gets queued. | ||
362 | */ | ||
363 | if(evt == null) | 316 | if(evt == null) |
364 | { | 317 | { |
365 | if(m_DetachQuantum > 0) | 318 | if(m_DetachQuantum > 0) |
366 | { | 319 | { |
367 | /* | 320 | // This will happen if the attach event has run |
368 | * This will happen if the attach event has run | 321 | // and exited with time slice left. |
369 | * and exited with time slice left. | ||
370 | */ | ||
371 | m_Suspended = true; | 322 | m_Suspended = true; |
372 | m_DetachReady.Set(); | 323 | m_DetachReady.Set(); |
373 | m_DetachQuantum = 0; | 324 | m_DetachQuantum = 0; |
@@ -378,10 +329,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
378 | } | 329 | } |
379 | } | 330 | } |
380 | 331 | ||
381 | /* | 332 | // Dequeued an event, so start it going until it either |
382 | * Dequeued an event, so start it going until it either | 333 | // finishes or it calls CheckRun(). |
383 | * finishes or it calls CheckRun(). | ||
384 | */ | ||
385 | m_RunOnePhase = "start event handler"; | 334 | m_RunOnePhase = "start event handler"; |
386 | m_DetectParams = evt.DetectParams; | 335 | m_DetectParams = evt.DetectParams; |
387 | m_LastRanAt = now; | 336 | m_LastRanAt = now; |
@@ -391,9 +340,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
391 | m_RunOnePhase = "done running"; | 340 | m_RunOnePhase = "done running"; |
392 | m_CPUTime += DateTime.UtcNow.Subtract(now).TotalMilliseconds; | 341 | m_CPUTime += DateTime.UtcNow.Subtract(now).TotalMilliseconds; |
393 | 342 | ||
394 | /* | 343 | // Maybe it puqued. |
395 | * Maybe it puqued. | ||
396 | */ | ||
397 | if(e != null) | 344 | if(e != null) |
398 | { | 345 | { |
399 | m_RunOnePhase = "handling exception " + e.Message; | 346 | m_RunOnePhase = "handling exception " + e.Message; |
@@ -403,9 +350,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
403 | return XMRInstState.FINISHED; | 350 | return XMRInstState.FINISHED; |
404 | } | 351 | } |
405 | 352 | ||
406 | /* | 353 | // If event handler completed, get rid of detect params. |
407 | * If event handler completed, get rid of detect params. | ||
408 | */ | ||
409 | if(this.eventCode == ScriptEventCode.None) | 354 | if(this.eventCode == ScriptEventCode.None) |
410 | m_DetectParams = null; | 355 | m_DetectParams = null; |
411 | 356 | ||
@@ -417,9 +362,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
417 | Monitor.Exit(m_RunLock); | 362 | Monitor.Exit(m_RunLock); |
418 | } | 363 | } |
419 | 364 | ||
420 | /* | 365 | // Cycle script through the yield queue and call it back asap. |
421 | * Cycle script through the yield queue and call it back asap. | ||
422 | */ | ||
423 | m_RunOnePhase = "last return"; | 366 | m_RunOnePhase = "last return"; |
424 | return XMRInstState.ONYIELDQ; | 367 | return XMRInstState.ONYIELDQ; |
425 | } | 368 | } |
@@ -433,10 +376,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
433 | 376 | ||
434 | public void CheckRunLockInvariants(bool throwIt) | 377 | public void CheckRunLockInvariants(bool throwIt) |
435 | { | 378 | { |
436 | /* | 379 | // If not executing any event handler, there shouldn't be any saved stack frames. |
437 | * If not executing any event handler, there shouldn't be any saved stack frames. | 380 | // If executing an event handler, there should be some saved stack frames. |
438 | * If executing an event handler, there should be some saved stack frames. | ||
439 | */ | ||
440 | bool active = (stackFrames != null); | 381 | bool active = (stackFrames != null); |
441 | ScriptEventCode ec = this.eventCode; | 382 | ScriptEventCode ec = this.eventCode; |
442 | if(((ec == ScriptEventCode.None) && active) || | 383 | if(((ec == ScriptEventCode.None) && active) || |
@@ -470,88 +411,67 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
470 | */ | 411 | */ |
471 | private Exception StartEventHandler(ScriptEventCode eventCode, object[] ehArgs) | 412 | private Exception StartEventHandler(ScriptEventCode eventCode, object[] ehArgs) |
472 | { | 413 | { |
473 | /* | 414 | // We use this.eventCode == ScriptEventCode.None to indicate we are idle. |
474 | * We use this.eventCode == ScriptEventCode.None to indicate we are idle. | 415 | // So trying to execute ScriptEventCode.None might make a mess. |
475 | * So trying to execute ScriptEventCode.None might make a mess. | ||
476 | */ | ||
477 | if(eventCode == ScriptEventCode.None) | 416 | if(eventCode == ScriptEventCode.None) |
478 | return new Exception("Can't process ScriptEventCode.None"); | 417 | return new Exception("Can't process ScriptEventCode.None"); |
479 | 418 | ||
480 | /* | 419 | // Silly to even try if there is no handler defined for this event. |
481 | * Silly to even try if there is no handler defined for this event. | ||
482 | */ | ||
483 | if(((int)eventCode >= 0) && (m_ObjCode.scriptEventHandlerTable[this.stateCode, (int)eventCode] == null)) | 420 | if(((int)eventCode >= 0) && (m_ObjCode.scriptEventHandlerTable[this.stateCode, (int)eventCode] == null)) |
484 | return null; | 421 | return null; |
485 | 422 | ||
486 | /* | 423 | // The microthread shouldn't be processing any event code. |
487 | * The microthread shouldn't be processing any event code. | 424 | // These are assert checks so we throw them directly as exceptions. |
488 | * These are assert checks so we throw them directly as exceptions. | ||
489 | */ | ||
490 | if(this.eventCode != ScriptEventCode.None) | 425 | if(this.eventCode != ScriptEventCode.None) |
491 | throw new Exception("still processing event " + this.eventCode.ToString()); | 426 | throw new Exception("still processing event " + this.eventCode.ToString()); |
492 | 427 | ||
493 | /* | 428 | // Save eventCode so we know what event handler to run in the microthread. |
494 | * Save eventCode so we know what event handler to run in the microthread. | 429 | // And it also marks us busy so we can't be started again and this event lost. |
495 | * And it also marks us busy so we can't be started again and this event lost. | ||
496 | */ | ||
497 | this.eventCode = eventCode; | 430 | this.eventCode = eventCode; |
498 | this.ehArgs = ehArgs; | 431 | this.ehArgs = ehArgs; |
499 | 432 | ||
500 | /* | 433 | // This calls ScriptUThread.Main() directly, and returns when Main() [indirectly] |
501 | * This calls ScriptUThread.Main() directly, and returns when Main() [indirectly] | 434 | // calls Suspend() or when Main() returns, whichever occurs first. |
502 | * calls Suspend() or when Main() returns, whichever occurs first. | 435 | // Setting stackFrames = null means run the event handler from the beginning |
503 | * Setting stackFrames = null means run the event handler from the beginning | 436 | // without doing any stack frame restores first. |
504 | * without doing any stack frame restores first. | ||
505 | */ | ||
506 | this.stackFrames = null; | 437 | this.stackFrames = null; |
507 | return StartEx(); | 438 | return StartEx(); |
508 | } | 439 | } |
509 | 440 | ||
510 | |||
511 | /** | 441 | /** |
512 | * @brief There was an exception whilst starting/running a script event handler. | 442 | * @brief There was an exception whilst starting/running a script event handler. |
513 | * Maybe we handle it directly or just print an error message. | 443 | * Maybe we handle it directly or just print an error message. |
514 | */ | 444 | */ |
515 | private void HandleScriptException(Exception e) | 445 | private void HandleScriptException(Exception e) |
516 | { | 446 | { |
517 | /* | 447 | // The script threw some kind of exception that was not caught at |
518 | * The script threw some kind of exception that was not caught at | 448 | // script level, so the script is no longer running an event handler. |
519 | * script level, so the script is no longer running an event handler. | ||
520 | */ | ||
521 | eventCode = ScriptEventCode.None; | 449 | eventCode = ScriptEventCode.None; |
522 | 450 | ||
523 | if(e is ScriptDeleteException) | 451 | if(e is ScriptDeleteException) |
524 | { | 452 | { |
525 | /* | 453 | // Script did something like llRemoveInventory(llGetScriptName()); |
526 | * Script did something like llRemoveInventory(llGetScriptName()); | 454 | // ... to delete itself from the object. |
527 | * ... to delete itself from the object. | ||
528 | */ | ||
529 | m_SleepUntil = DateTime.MaxValue; | 455 | m_SleepUntil = DateTime.MaxValue; |
530 | Verbose("[YEngine]: script self-delete {0}", m_ItemID); | 456 | Verbose("[YEngine]: script self-delete {0}", m_ItemID); |
531 | m_Part.Inventory.RemoveInventoryItem(m_ItemID); | 457 | m_Part.Inventory.RemoveInventoryItem(m_ItemID); |
532 | } | 458 | } |
533 | else if(e is ScriptDieException) | 459 | else if(e is ScriptDieException) |
534 | { | 460 | { |
535 | /* | 461 | // Script did an llDie() |
536 | * Script did an llDie() | ||
537 | */ | ||
538 | m_RunOnePhase = "dying..."; | 462 | m_RunOnePhase = "dying..."; |
539 | m_SleepUntil = DateTime.MaxValue; | 463 | m_SleepUntil = DateTime.MaxValue; |
540 | m_Engine.World.DeleteSceneObject(m_Part.ParentGroup, false); | 464 | m_Engine.World.DeleteSceneObject(m_Part.ParentGroup, false); |
541 | } | 465 | } |
542 | else if(e is ScriptResetException) | 466 | else if(e is ScriptResetException) |
543 | { | 467 | { |
544 | /* | 468 | // Script did an llResetScript(). |
545 | * Script did an llResetScript(). | ||
546 | */ | ||
547 | m_RunOnePhase = "resetting..."; | 469 | m_RunOnePhase = "resetting..."; |
548 | ResetLocked("HandleScriptResetException"); | 470 | ResetLocked("HandleScriptResetException"); |
549 | } | 471 | } |
550 | else | 472 | else |
551 | { | 473 | { |
552 | /* | 474 | // Some general script error. |
553 | * Some general script error. | ||
554 | */ | ||
555 | SendErrorMessage(e); | 475 | SendErrorMessage(e); |
556 | } | 476 | } |
557 | return; | 477 | return; |
@@ -570,16 +490,12 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
570 | msg.Append(m_ItemID); | 490 | msg.Append(m_ItemID); |
571 | msg.Append('\n'); | 491 | msg.Append('\n'); |
572 | 492 | ||
573 | /* | 493 | // Add exception message. |
574 | * Add exception message. | ||
575 | */ | ||
576 | string des = e.Message; | 494 | string des = e.Message; |
577 | des = (des == null) ? "" : (": " + des); | 495 | des = (des == null) ? "" : (": " + des); |
578 | msg.Append(e.GetType().Name + des + "\n"); | 496 | msg.Append(e.GetType().Name + des + "\n"); |
579 | 497 | ||
580 | /* | 498 | // Tell script owner what to do. |
581 | * Tell script owner what to do. | ||
582 | */ | ||
583 | msg.Append("Prim: <"); | 499 | msg.Append("Prim: <"); |
584 | msg.Append(m_Part.Name); | 500 | msg.Append(m_Part.Name); |
585 | msg.Append(">, Script: <"); | 501 | msg.Append(">, Script: <"); |
@@ -595,20 +511,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
595 | msg.Append((int)Math.Floor(pos.Z)); | 511 | msg.Append((int)Math.Floor(pos.Z)); |
596 | msg.Append(">\nScript must be Reset to re-enable.\n"); | 512 | msg.Append(">\nScript must be Reset to re-enable.\n"); |
597 | 513 | ||
598 | /* | 514 | // Display full exception message in log. |
599 | * Display full exception message in log. | ||
600 | */ | ||
601 | m_log.Info(msg.ToString() + XMRExceptionStackString(e), e); | 515 | m_log.Info(msg.ToString() + XMRExceptionStackString(e), e); |
602 | 516 | ||
603 | /* | 517 | // Give script owner the stack dump. |
604 | * Give script owner the stack dump. | ||
605 | */ | ||
606 | msg.Append(XMRExceptionStackString(e)); | 518 | msg.Append(XMRExceptionStackString(e)); |
607 | 519 | ||
608 | /* | 520 | // Send error message to owner. |
609 | * Send error message to owner. | 521 | // Suppress internal code stack trace lines. |
610 | * Suppress internal code stack trace lines. | ||
611 | */ | ||
612 | string msgst = msg.ToString(); | 522 | string msgst = msg.ToString(); |
613 | if(!msgst.EndsWith("\n")) | 523 | if(!msgst.EndsWith("\n")) |
614 | msgst += '\n'; | 524 | msgst += '\n'; |
@@ -630,10 +540,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
630 | imstr.Append('\n'); | 540 | imstr.Append('\n'); |
631 | } | 541 | } |
632 | 542 | ||
633 | /* | 543 | // Send as instant message in case user not online. |
634 | * Send as instant message in case user not online. | 544 | // Code modelled from llInstantMessage(). |
635 | * Code modelled from llInstantMessage(). | ||
636 | */ | ||
637 | IMessageTransferModule transferModule = m_Engine.World.RequestModuleInterface<IMessageTransferModule>(); | 545 | IMessageTransferModule transferModule = m_Engine.World.RequestModuleInterface<IMessageTransferModule>(); |
638 | if(transferModule != null) | 546 | if(transferModule != null) |
639 | { | 547 | { |
@@ -661,10 +569,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
661 | }); | 569 | }); |
662 | } | 570 | } |
663 | 571 | ||
664 | /* | 572 | // Say script is sleeping for a very long time. |
665 | * Say script is sleeping for a very long time. | 573 | // Reset() is able to cancel this sleeping. |
666 | * Reset() is able to cancel this sleeping. | ||
667 | */ | ||
668 | m_SleepUntil = DateTime.MaxValue; | 574 | m_SleepUntil = DateTime.MaxValue; |
669 | } | 575 | } |
670 | 576 | ||
@@ -678,18 +584,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
678 | XMRInstState iState = m_IState; | 584 | XMRInstState iState = m_IState; |
679 | switch(iState) | 585 | switch(iState) |
680 | { | 586 | { |
681 | /* | 587 | // If it's really being constructed now, that's about as reset as we get. |
682 | * If it's really being constructed now, that's about as reset as we get. | ||
683 | */ | ||
684 | case XMRInstState.CONSTRUCT: | 588 | case XMRInstState.CONSTRUCT: |
685 | return; | 589 | return; |
686 | 590 | ||
687 | /* | 591 | // If it's idle, that means it is ready to receive a new event. |
688 | * If it's idle, that means it is ready to receive a new event. | 592 | // So we lock the event queue to prevent another thread from taking |
689 | * So we lock the event queue to prevent another thread from taking | 593 | // it out of idle, verify that it is still in idle then transition |
690 | * it out of idle, verify that it is still in idle then transition | 594 | // it to resetting so no other thread will touch it. |
691 | * it to resetting so no other thread will touch it. | ||
692 | */ | ||
693 | case XMRInstState.IDLE: | 595 | case XMRInstState.IDLE: |
694 | lock(m_QueueLock) | 596 | lock(m_QueueLock) |
695 | { | 597 | { |
@@ -701,12 +603,10 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
701 | } | 603 | } |
702 | goto checkstate; | 604 | goto checkstate; |
703 | 605 | ||
704 | /* | 606 | // If it's on the start queue, that means it is about to dequeue an |
705 | * If it's on the start queue, that means it is about to dequeue an | 607 | // event and start processing it. So we lock the start queue so it |
706 | * event and start processing it. So we lock the start queue so it | 608 | // can't be started and transition it to resetting so no other thread |
707 | * can't be started and transition it to resetting so no other thread | 609 | // will touch it. |
708 | * will touch it. | ||
709 | */ | ||
710 | case XMRInstState.ONSTARTQ: | 610 | case XMRInstState.ONSTARTQ: |
711 | lock(m_Engine.m_StartQueue) | 611 | lock(m_Engine.m_StartQueue) |
712 | { | 612 | { |
@@ -719,10 +619,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
719 | } | 619 | } |
720 | goto checkstate; | 620 | goto checkstate; |
721 | 621 | ||
722 | /* | 622 | // If it's running, tell CheckRun() to suspend the thread then go back |
723 | * If it's running, tell CheckRun() to suspend the thread then go back | 623 | // to see what it got transitioned to. |
724 | * to see what it got transitioned to. | ||
725 | */ | ||
726 | case XMRInstState.RUNNING: | 624 | case XMRInstState.RUNNING: |
727 | suspendOnCheckRunHold = true; | 625 | suspendOnCheckRunHold = true; |
728 | lock(m_QueueLock) | 626 | lock(m_QueueLock) |
@@ -730,11 +628,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
730 | } | 628 | } |
731 | goto checkstate; | 629 | goto checkstate; |
732 | 630 | ||
733 | 631 | // If it's sleeping, remove it from sleep queue and transition it to | |
734 | /* | 632 | // resetting so no other thread will touch it. |
735 | * If it's sleeping, remove it from sleep queue and transition it to | ||
736 | * resetting so no other thread will touch it. | ||
737 | */ | ||
738 | case XMRInstState.ONSLEEPQ: | 633 | case XMRInstState.ONSLEEPQ: |
739 | lock(m_Engine.m_SleepQueue) | 634 | lock(m_Engine.m_SleepQueue) |
740 | { | 635 | { |
@@ -747,19 +642,15 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
747 | } | 642 | } |
748 | goto checkstate; | 643 | goto checkstate; |
749 | 644 | ||
750 | /* | 645 | // It was just removed from the sleep queue and is about to be put |
751 | * It was just removed from the sleep queue and is about to be put | 646 | // on the yield queue (ie, is being woken up). |
752 | * on the yield queue (ie, is being woken up). | 647 | // Let that thread complete transition and try again. |
753 | * Let that thread complete transition and try again. | ||
754 | */ | ||
755 | case XMRInstState.REMDFROMSLPQ: | 648 | case XMRInstState.REMDFROMSLPQ: |
756 | Sleep(10); | 649 | Sleep(10); |
757 | goto checkstate; | 650 | goto checkstate; |
758 | 651 | ||
759 | /* | 652 | // If it's yielding, remove it from yield queue and transition it to |
760 | * If it's yielding, remove it from yield queue and transition it to | 653 | // resetting so no other thread will touch it. |
761 | * resetting so no other thread will touch it. | ||
762 | */ | ||
763 | case XMRInstState.ONYIELDQ: | 654 | case XMRInstState.ONYIELDQ: |
764 | lock(m_Engine.m_YieldQueue) | 655 | lock(m_Engine.m_YieldQueue) |
765 | { | 656 | { |
@@ -772,52 +663,38 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
772 | } | 663 | } |
773 | goto checkstate; | 664 | goto checkstate; |
774 | 665 | ||
775 | /* | 666 | // If it just finished running something, let that thread transition it |
776 | * If it just finished running something, let that thread transition it | 667 | // to its next state then check again. |
777 | * to its next state then check again. | ||
778 | */ | ||
779 | case XMRInstState.FINISHED: | 668 | case XMRInstState.FINISHED: |
780 | Sleep(10); | 669 | Sleep(10); |
781 | goto checkstate; | 670 | goto checkstate; |
782 | 671 | ||
783 | /* | 672 | // If it's disposed, that's about as reset as it gets. |
784 | * If it's disposed, that's about as reset as it gets. | ||
785 | */ | ||
786 | case XMRInstState.DISPOSED: | 673 | case XMRInstState.DISPOSED: |
787 | return; | 674 | return; |
788 | 675 | ||
789 | /* | 676 | // Some other thread is already resetting it, let it finish. |
790 | * Some other thread is already resetting it, let it finish. | 677 | |
791 | */ | ||
792 | case XMRInstState.RESETTING: | 678 | case XMRInstState.RESETTING: |
793 | return; | 679 | return; |
794 | 680 | ||
795 | |||
796 | default: | 681 | default: |
797 | throw new Exception("bad state"); | 682 | throw new Exception("bad state"); |
798 | } | 683 | } |
799 | 684 | ||
800 | /* | 685 | // This thread transitioned the instance to RESETTING so reset it. |
801 | * This thread transitioned the instance to RESETTING so reset it. | ||
802 | */ | ||
803 | lock(m_RunLock) | 686 | lock(m_RunLock) |
804 | { | 687 | { |
805 | CheckRunLockInvariants(true); | 688 | CheckRunLockInvariants(true); |
806 | 689 | ||
807 | /* | 690 | // No other thread should have transitioned it from RESETTING. |
808 | * No other thread should have transitioned it from RESETTING. | ||
809 | */ | ||
810 | if(m_IState != XMRInstState.RESETTING) | 691 | if(m_IState != XMRInstState.RESETTING) |
811 | throw new Exception("bad state"); | 692 | throw new Exception("bad state"); |
812 | 693 | ||
813 | /* | 694 | // Mark it idle now so it can get queued to process new stuff. |
814 | * Mark it idle now so it can get queued to process new stuff. | ||
815 | */ | ||
816 | m_IState = XMRInstState.IDLE; | 695 | m_IState = XMRInstState.IDLE; |
817 | 696 | ||
818 | /* | 697 | // Reset everything and queue up default's start_entry() event. |
819 | * Reset everything and queue up default's start_entry() event. | ||
820 | */ | ||
821 | ClearQueue(); | 698 | ClearQueue(); |
822 | ResetLocked("external Reset"); | 699 | ResetLocked("external Reset"); |
823 | 700 | ||
@@ -886,16 +763,12 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
886 | m_SleepUntil = DateTime.MinValue; // not doing llSleep() | 763 | m_SleepUntil = DateTime.MinValue; // not doing llSleep() |
887 | m_ResetCount++; // has been reset once more | 764 | m_ResetCount++; // has been reset once more |
888 | 765 | ||
889 | /* | 766 | // Tell next call to 'default state_entry()' to reset all global |
890 | * Tell next call to 'default state_entry()' to reset all global | 767 | // vars to their initial values. |
891 | * vars to their initial values. | ||
892 | */ | ||
893 | doGblInit = true; | 768 | doGblInit = true; |
894 | 769 | ||
895 | /* | 770 | // Set script to 'default' state and queue call to its |
896 | * Set script to 'default' state and queue call to its | 771 | // 'state_entry()' event handler. |
897 | * 'state_entry()' event handler. | ||
898 | */ | ||
899 | m_RunOnePhase = "ResetLocked: posting default:state_entry() event"; | 772 | m_RunOnePhase = "ResetLocked: posting default:state_entry() event"; |
900 | stateCode = 0; | 773 | stateCode = 0; |
901 | m_Part.SetScriptEvents(m_ItemID, GetStateEventFlags(0)); | 774 | m_Part.SetScriptEvents(m_ItemID, GetStateEventFlags(0)); |
@@ -903,9 +776,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
903 | zeroObjectArray, | 776 | zeroObjectArray, |
904 | zeroDetectParams)); | 777 | zeroDetectParams)); |
905 | 778 | ||
906 | /* | 779 | // Tell CheckRun() to let script run. |
907 | * Tell CheckRun() to let script run. | ||
908 | */ | ||
909 | suspendOnCheckRunHold = false; | 780 | suspendOnCheckRunHold = false; |
910 | suspendOnCheckRunTemp = false; | 781 | suspendOnCheckRunTemp = false; |
911 | m_RunOnePhase = "ResetLocked: reset complete"; | 782 | m_RunOnePhase = "ResetLocked: reset complete"; |
@@ -955,9 +826,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
955 | } | 826 | } |
956 | m_CheckRunPhase = "entered"; | 827 | m_CheckRunPhase = "entered"; |
957 | 828 | ||
958 | /* | 829 | // Stay stuck in this loop as long as something wants us suspended. |
959 | * Stay stuck in this loop as long as something wants us suspended. | ||
960 | */ | ||
961 | while(suspendOnCheckRunHold || suspendOnCheckRunTemp) | 830 | while(suspendOnCheckRunHold || suspendOnCheckRunTemp) |
962 | { | 831 | { |
963 | m_CheckRunPhase = "top of while"; | 832 | m_CheckRunPhase = "top of while"; |
@@ -997,10 +866,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
997 | 866 | ||
998 | m_CheckRunPhase = "returning"; | 867 | m_CheckRunPhase = "returning"; |
999 | 868 | ||
1000 | /* | 869 | // Upon return from CheckRun() it should always be the case that the script is |
1001 | * Upon return from CheckRun() it should always be the case that the script is | 870 | // going to process calls normally, neither saving nor restoring stack frame state. |
1002 | * going to process calls normally, neither saving nor restoring stack frame state. | ||
1003 | */ | ||
1004 | if(callMode != CallMode_NORMAL) | 871 | if(callMode != CallMode_NORMAL) |
1005 | throw new Exception("bad callMode " + callMode); | 872 | throw new Exception("bad callMode " + callMode); |
1006 | } | 873 | } |
diff --git a/OpenSim/Region/ScriptEngine/YEngine/XMRObjectTokens.cs b/OpenSim/Region/ScriptEngine/YEngine/XMRObjectTokens.cs index d3ae165..76762dd 100644 --- a/OpenSim/Region/ScriptEngine/YEngine/XMRObjectTokens.cs +++ b/OpenSim/Region/ScriptEngine/YEngine/XMRObjectTokens.cs | |||
@@ -501,10 +501,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
501 | */ | 501 | */ |
502 | public override void EndMethod() | 502 | public override void EndMethod() |
503 | { | 503 | { |
504 | /* | 504 | // Convert CIL code to primitive statements. |
505 | * Convert CIL code to primitive statements. | 505 | // There are a bunch of labels and internal code such as call stack save restore. |
506 | * There are a bunch of labels and internal code such as call stack save restore. | ||
507 | */ | ||
508 | topBlock = new OTStmtBlock(); | 506 | topBlock = new OTStmtBlock(); |
509 | blockstack.Push(topBlock); | 507 | blockstack.Push(topBlock); |
510 | for(LinkedListNode<OTCilInstr> link = cilinstrs.First; link != null; link = link.Next) | 508 | for(LinkedListNode<OTCilInstr> link = cilinstrs.First; link != null; link = link.Next) |
@@ -512,10 +510,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
512 | link.Value.BuildStatements(this, link); | 510 | link.Value.BuildStatements(this, link); |
513 | } | 511 | } |
514 | 512 | ||
515 | /* | 513 | // Strip out stuff we don't want, such as references to callMode. |
516 | * Strip out stuff we don't want, such as references to callMode. | 514 | // This strips out stack frame capture and restore code. |
517 | * This strips out stack frame capture and restore code. | ||
518 | */ | ||
519 | topBlock.StripStuff(null); | 515 | topBlock.StripStuff(null); |
520 | 516 | ||
521 | // including a possible final return statement | 517 | // including a possible final return statement |
@@ -532,22 +528,16 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
532 | } | 528 | } |
533 | } | 529 | } |
534 | 530 | ||
535 | /** | 531 | // At this point, all behind-the-scenes references are removed except |
536 | * At this point, all behind-the-scenes references are removed except | 532 | // that the do/for/if/while blocks are represented by OTStmtCont-style |
537 | * that the do/for/if/while blocks are represented by OTStmtCont-style | 533 | // if/jumps. So try to convert them to the higher-level structures. |
538 | * if/jumps. So try to convert them to the higher-level structures. | ||
539 | */ | ||
540 | topBlock.DetectDoForIfWhile(null); | 534 | topBlock.DetectDoForIfWhile(null); |
541 | 535 | ||
542 | /* | 536 | // Final strip to get rid of unneeded @forbreak_<suffix>; labels and the like. |
543 | * Final strip to get rid of unneeded @forbreak_<suffix>; labels and the like. | ||
544 | */ | ||
545 | topBlock.StripStuff(null); | 537 | topBlock.StripStuff(null); |
546 | 538 | ||
547 | /* | 539 | // Build reference counts so we don't output unneeded declarations, |
548 | * Build reference counts so we don't output unneeded declarations, | 540 | // especially temps and internal variables. |
549 | * especially temps and internal variables. | ||
550 | */ | ||
551 | foreach(OTLocal local in locals.Values) | 541 | foreach(OTLocal local in locals.Values) |
552 | { | 542 | { |
553 | local.nlclreads = 0; | 543 | local.nlclreads = 0; |
@@ -564,10 +554,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
564 | } | 554 | } |
565 | } | 555 | } |
566 | 556 | ||
567 | /* | 557 | // Strip the $n off of local vars that are not ambiguous. |
568 | * Strip the $n off of local vars that are not ambiguous. | 558 | // Make sure they don't mask globals and arguments as well. |
569 | * Make sure they don't mask globals and arguments as well. | ||
570 | */ | ||
571 | Dictionary<string, int> namecounts = new Dictionary<string, int>(); | 559 | Dictionary<string, int> namecounts = new Dictionary<string, int>(); |
572 | foreach(Dictionary<int, string> varnames in scriptObjCode.globalVarNames.Values) | 560 | foreach(Dictionary<int, string> varnames in scriptObjCode.globalVarNames.Values) |
573 | { | 561 | { |
@@ -607,9 +595,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
607 | local.name = name; | 595 | local.name = name; |
608 | } | 596 | } |
609 | 597 | ||
610 | /* | 598 | // Print out result. |
611 | * Print out result. | ||
612 | */ | ||
613 | if(method.Name == _globalvarinit) | 599 | if(method.Name == _globalvarinit) |
614 | { | 600 | { |
615 | GlobalsDump(); | 601 | GlobalsDump(); |
@@ -725,10 +711,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
725 | */ | 711 | */ |
726 | private void GlobalsDump() | 712 | private void GlobalsDump() |
727 | { | 713 | { |
728 | /* | 714 | // Scan $globalvarinit(). It should only have global var assignments in it. |
729 | * Scan $globalvarinit(). It should only have global var assignments in it. | 715 | // Also gather up list of variables it initializes. |
730 | * Also gather up list of variables it initializes. | ||
731 | */ | ||
732 | bool badinit = false; | 716 | bool badinit = false; |
733 | Dictionary<string, string> inittypes = new Dictionary<string, string>(); | 717 | Dictionary<string, string> inittypes = new Dictionary<string, string>(); |
734 | foreach(OTStmt stmt in topBlock.blkstmts) | 718 | foreach(OTStmt stmt in topBlock.blkstmts) |
@@ -748,11 +732,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
748 | inittypes[globalop.PrintableString] = ""; | 732 | inittypes[globalop.PrintableString] = ""; |
749 | } | 733 | } |
750 | 734 | ||
751 | /* | 735 | // Scan through list of all global variables in the script. |
752 | * Scan through list of all global variables in the script. | 736 | // Output declarations for those what don't have any init statement for them. |
753 | * Output declarations for those what don't have any init statement for them. | 737 | // Save the type for those that do have init statements. |
754 | * Save the type for those that do have init statements. | ||
755 | */ | ||
756 | bool first = true; | 738 | bool first = true; |
757 | foreach(string iartypename in scriptObjCode.globalVarNames.Keys) | 739 | foreach(string iartypename in scriptObjCode.globalVarNames.Keys) |
758 | { | 740 | { |
@@ -778,10 +760,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
778 | } | 760 | } |
779 | } | 761 | } |
780 | 762 | ||
781 | /* | 763 | // If $globalvarinit() has anything bad in it, output it as a function. |
782 | * If $globalvarinit() has anything bad in it, output it as a function. | 764 | // Otherwise, output it as a series of global declarations with init values. |
783 | * Otherwise, output it as a series of global declarations with init values. | ||
784 | */ | ||
785 | if(badinit) | 765 | if(badinit) |
786 | { | 766 | { |
787 | MethodDump(); | 767 | MethodDump(); |
@@ -809,19 +789,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
809 | { | 789 | { |
810 | string indent; | 790 | string indent; |
811 | 791 | ||
812 | /* | 792 | // Event handlers don't have an argument list as such in the original |
813 | * Event handlers don't have an argument list as such in the original | 793 | // code. Instead they have a series of assignments from ehargs[] to |
814 | * code. Instead they have a series of assignments from ehargs[] to | 794 | // local variables. So make those local variables look like they are |
815 | * local variables. So make those local variables look like they are | 795 | // an argument list. |
816 | * an argument list. | ||
817 | */ | ||
818 | int i = method.Name.IndexOf(' '); | 796 | int i = method.Name.IndexOf(' '); |
819 | if(i >= 0) | 797 | if(i >= 0) |
820 | { | 798 | { |
821 | 799 | // Maybe we have to output the state name. | |
822 | /* | ||
823 | * Maybe we have to output the state name. | ||
824 | */ | ||
825 | string statename = method.Name.Substring(0, i); | 800 | string statename = method.Name.Substring(0, i); |
826 | string eventname = method.Name.Substring(++i); | 801 | string eventname = method.Name.Substring(++i); |
827 | 802 | ||
@@ -844,10 +819,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
844 | twout.Write('\n'); | 819 | twout.Write('\n'); |
845 | } | 820 | } |
846 | 821 | ||
847 | /* | 822 | // Output event name and argument list. |
848 | * Output event name and argument list. | 823 | // Remove from locals list so they don't print below. |
849 | * Remove from locals list so they don't print below. | ||
850 | */ | ||
851 | twout.Write('\n' + INDENT + eventname + " ("); | 824 | twout.Write('\n' + INDENT + eventname + " ("); |
852 | MethodInfo meth = typeof(IEventHandlers).GetMethod(eventname); | 825 | MethodInfo meth = typeof(IEventHandlers).GetMethod(eventname); |
853 | i = 0; | 826 | i = 0; |
@@ -873,35 +846,26 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
873 | } | 846 | } |
874 | twout.Write(')'); | 847 | twout.Write(')'); |
875 | 848 | ||
876 | /* | 849 | // Indent method body by 4 spaces. |
877 | * Indent method body by 4 spaces. | ||
878 | */ | ||
879 | indent = INDENT; | 850 | indent = INDENT; |
880 | } | 851 | } |
881 | else | 852 | else |
882 | { | 853 | { |
883 | 854 | // Maybe need to close out previous state. | |
884 | /* | ||
885 | * Maybe need to close out previous state. | ||
886 | */ | ||
887 | if(laststate != null) | 855 | if(laststate != null) |
888 | { | 856 | { |
889 | twout.Write("\n}"); | 857 | twout.Write("\n}"); |
890 | laststate = null; | 858 | laststate = null; |
891 | } | 859 | } |
892 | 860 | ||
893 | /* | 861 | // Output blank line and return type (if any). |
894 | * Output blank line and return type (if any). | ||
895 | */ | ||
896 | twout.Write("\n\n"); | 862 | twout.Write("\n\n"); |
897 | if(method.ReturnType != typeof(void)) | 863 | if(method.ReturnType != typeof(void)) |
898 | { | 864 | { |
899 | twout.Write(AbbrType(method.ReturnType) + ' '); | 865 | twout.Write(AbbrType(method.ReturnType) + ' '); |
900 | } | 866 | } |
901 | 867 | ||
902 | /* | 868 | // Output method name and argument list. |
903 | * Output method name and argument list. | ||
904 | */ | ||
905 | int j = method.Name.IndexOf('('); | 869 | int j = method.Name.IndexOf('('); |
906 | if(j < 0) | 870 | if(j < 0) |
907 | { | 871 | { |
@@ -926,15 +890,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
926 | twout.Write(')'); | 890 | twout.Write(')'); |
927 | } | 891 | } |
928 | 892 | ||
929 | /* | 893 | // Don't indent method body at all. |
930 | * Don't indent method body at all. | ||
931 | */ | ||
932 | indent = ""; | 894 | indent = ""; |
933 | } | 895 | } |
934 | 896 | ||
935 | /* | 897 | // Output local variable declarations. |
936 | * Output local variable declarations. | ||
937 | */ | ||
938 | twout.Write('\n' + indent + '{'); | 898 | twout.Write('\n' + indent + '{'); |
939 | bool didOne = false; | 899 | bool didOne = false; |
940 | foreach(OTLocal local in locals.Values) | 900 | foreach(OTLocal local in locals.Values) |
@@ -945,9 +905,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
945 | if(didOne) | 905 | if(didOne) |
946 | twout.Write('\n'); | 906 | twout.Write('\n'); |
947 | 907 | ||
948 | /* | 908 | // Output statements. |
949 | * Output statements. | ||
950 | */ | ||
951 | if(topBlock.blkstmts.Count == 0) | 909 | if(topBlock.blkstmts.Count == 0) |
952 | { | 910 | { |
953 | twout.Write(" }"); | 911 | twout.Write(" }"); |
@@ -1634,22 +1592,19 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1634 | { | 1592 | { |
1635 | switch(opCode.ToString()) | 1593 | switch(opCode.ToString()) |
1636 | { | 1594 | { |
1637 | 1595 | // We don't handle non-empty stack at branch points. | |
1638 | /* | 1596 | // |
1639 | * We don't handle non-empty stack at branch points. | 1597 | // So handle this case specially: |
1640 | * | 1598 | // |
1641 | * So handle this case specially: | 1599 | // dup |
1642 | * | 1600 | // ldc.i4.0 |
1643 | * dup | 1601 | // bge.s llAbstemp << we are here |
1644 | * ldc.i4.0 | 1602 | // neg |
1645 | * bge.s llAbstemp << we are here | 1603 | // llAbstemp: |
1646 | * neg | 1604 | // |
1647 | * llAbstemp: | 1605 | // becomes: |
1648 | * | 1606 | // |
1649 | * becomes: | 1607 | // call llAbs |
1650 | * | ||
1651 | * call llAbs | ||
1652 | */ | ||
1653 | case "bge.s": | 1608 | case "bge.s": |
1654 | { | 1609 | { |
1655 | OTOpnd rite = decompile.opstack.Pop(); // alleged zero | 1610 | OTOpnd rite = decompile.opstack.Pop(); // alleged zero |
@@ -2103,50 +2058,33 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2103 | 2058 | ||
2104 | public static OTOpnd Make(OTOpnd array, OTOpnd index, bool byref, OTDecompile decompile) | 2059 | public static OTOpnd Make(OTOpnd array, OTOpnd index, bool byref, OTDecompile decompile) |
2105 | { | 2060 | { |
2106 | /* | 2061 | // arg$0.glblVars.iar<type>[<intconst>] is a reference to a global variable |
2107 | * arg$0.glblVars.iar<type>[<intconst>] is a reference to a global variable | 2062 | // likewise so is __xmrinst.glblVars.iar<type>[<intconst>] |
2108 | * likewise so is __xmrinst.glblVars.iar<type>[<intconst>] | ||
2109 | */ | ||
2110 | if((array is OTOpndField) && (index is OTOpndInt)) | 2063 | if((array is OTOpndField) && (index is OTOpndInt)) |
2111 | { | 2064 | { |
2112 | 2065 | // arrayfield = (arg$0.glblVars).iar<type> | |
2113 | /* | 2066 | // arrayfieldobj = arg$0.glblVars |
2114 | * arrayfield = (arg$0.glblVars).iar<type> | 2067 | // iartypename = iar<type> |
2115 | * arrayfieldobj = arg$0.glblVars | ||
2116 | * iartypename = iar<type> | ||
2117 | */ | ||
2118 | OTOpndField arrayfield = (OTOpndField)array; | 2068 | OTOpndField arrayfield = (OTOpndField)array; |
2119 | OTOpnd arrayfieldobj = arrayfield.obj; | 2069 | OTOpnd arrayfieldobj = arrayfield.obj; |
2120 | string iartypename = arrayfield.field.Name; | 2070 | string iartypename = arrayfield.field.Name; |
2121 | 2071 | ||
2122 | /* | 2072 | // See if they are what they are supposed to be. |
2123 | * See if they are what they are supposed to be. | ||
2124 | */ | ||
2125 | if((arrayfieldobj is OTOpndField) && iartypename.StartsWith("iar")) | 2073 | if((arrayfieldobj is OTOpndField) && iartypename.StartsWith("iar")) |
2126 | { | 2074 | { |
2127 | 2075 | // arrayfieldobjfield = arg$0.glblVars | |
2128 | /* | ||
2129 | * arrayfieldobjfield = arg$0.glblVars | ||
2130 | */ | ||
2131 | OTOpndField arrayfieldobjfield = (OTOpndField)arrayfieldobj; | 2076 | OTOpndField arrayfieldobjfield = (OTOpndField)arrayfieldobj; |
2132 | 2077 | ||
2133 | /* | 2078 | // See if the parts are what they are supposed to be. |
2134 | * See if the parts are what they are supposed to be. | ||
2135 | */ | ||
2136 | if(IsArg0OrXMRInst(arrayfieldobjfield.obj) && (arrayfieldobjfield.field.Name == "glblVars")) | 2079 | if(IsArg0OrXMRInst(arrayfieldobjfield.obj) && (arrayfieldobjfield.field.Name == "glblVars")) |
2137 | { | 2080 | { |
2138 | 2081 | // Everything matches up, make a global variable instead of an array reference. | |
2139 | /* | ||
2140 | * Everything matches up, make a global variable instead of an array reference. | ||
2141 | */ | ||
2142 | return new OTOpndGlobal(iartypename, ((OTOpndInt)index).value, byref, decompile.scriptObjCode); | 2082 | return new OTOpndGlobal(iartypename, ((OTOpndInt)index).value, byref, decompile.scriptObjCode); |
2143 | } | 2083 | } |
2144 | } | 2084 | } |
2145 | } | 2085 | } |
2146 | 2086 | ||
2147 | /* | 2087 | // Other array reference. |
2148 | * Other array reference. | ||
2149 | */ | ||
2150 | OTOpndArrayElem it = new OTOpndArrayElem(); | 2088 | OTOpndArrayElem it = new OTOpndArrayElem(); |
2151 | it.array = array; | 2089 | it.array = array; |
2152 | it.index = index; | 2090 | it.index = index; |
@@ -3097,17 +3035,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
3097 | return false; | 3035 | return false; |
3098 | int listsize = ((OTOpndInt)storeval.index).value; | 3036 | int listsize = ((OTOpndInt)storeval.index).value; |
3099 | 3037 | ||
3100 | /* | 3038 | // Good chance of having list initializer, malloc an object to hold it. |
3101 | * Good chance of having list initializer, malloc an object to hold it. | ||
3102 | */ | ||
3103 | OTOpndListIni it = new OTOpndListIni(); | 3039 | OTOpndListIni it = new OTOpndListIni(); |
3104 | it.values = new OTOpnd[listsize]; | 3040 | it.values = new OTOpnd[listsize]; |
3105 | 3041 | ||
3106 | /* | 3042 | // There should be exactly listsize statements following that of the form: |
3107 | * There should be exactly listsize statements following that of the form: | 3043 | // dup$<n>[<i>] = bla |
3108 | * dup$<n>[<i>] = bla | 3044 | // If so, save the bla values in the values[] array. |
3109 | * If so, save the bla values in the values[] array. | ||
3110 | */ | ||
3111 | LinkedListNode<OTStmt> vallink = link; | 3045 | LinkedListNode<OTStmt> vallink = link; |
3112 | for(int i = 0; i < listsize; i++) | 3046 | for(int i = 0; i < listsize; i++) |
3113 | { | 3047 | { |
@@ -3129,10 +3063,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
3129 | it.values[i] = valstore.value; | 3063 | it.values[i] = valstore.value; |
3130 | } | 3064 | } |
3131 | 3065 | ||
3132 | /* | 3066 | // The next statement should have a 'newobj list (dup$<n>)' in it somewhere |
3133 | * The next statement should have a 'newobj list (dup$<n>)' in it somewhere | 3067 | // that we want to replace with 'it'. |
3134 | * that we want to replace with 'it'. | ||
3135 | */ | ||
3136 | ConstructorInfo protoctor = typeof(LSL_List).GetConstructor(new Type[] { typeof(object[]) }); | 3068 | ConstructorInfo protoctor = typeof(LSL_List).GetConstructor(new Type[] { typeof(object[]) }); |
3137 | OTOpnd[] protoargs = new OTOpnd[] { storevar }; | 3069 | OTOpnd[] protoargs = new OTOpnd[] { storevar }; |
3138 | OTOpnd proto = OTOpndNewobj.Make(protoctor, protoargs); | 3070 | OTOpnd proto = OTOpndNewobj.Make(protoctor, protoargs); |
@@ -3140,9 +3072,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
3140 | vallink = vallink.Next; | 3072 | vallink = vallink.Next; |
3141 | bool rc = vallink.Value.ReplaceOperand(proto, it); | 3073 | bool rc = vallink.Value.ReplaceOperand(proto, it); |
3142 | 3074 | ||
3143 | /* | 3075 | // If successful, delete 'dup$n =' and all 'dup$n[i] =' statements. |
3144 | * If successful, delete 'dup$n =' and all 'dup$n[i] =' statements. | ||
3145 | */ | ||
3146 | if(rc) | 3076 | if(rc) |
3147 | { | 3077 | { |
3148 | do | 3078 | do |