Difference between revisions of "Jump"
Jump to navigation
Jump to search
m |
(clarify what "fail silently" means exactly) |
||
(12 intermediate revisions by 7 users not shown) | |||
Line 1: | Line 1: | ||
{{LSL Header|ml=*}} | {{LSL Header|ml=*}}{{#if: | ||
{{#vardefine:name|jump | |||
}}{{#vardefine:p_jump_target_desc|Name of a label inside the same | {{#vardefine:name|jump}} | ||
}}{{#vardefine:p_label_target_desc|A label that can be jumped to, if the jump is in the same scope or child scope. It isn't possible to jump between scopes (such as between functions or states). | |||
}}{{#vardefine:header_title|jump {{LSL Param|jump_target|target}}; | {{#vardefine:p_jump_target_desc|Name of a label inside the same function or event scope.}} | ||
}}{{#vardefine:header_text|{{{!}} | {{#vardefine:p_label_target_desc|A label that can be jumped to, if the jump is in the same scope or child scope. It isn't possible to jump between scopes (such as between functions, events or states).}} | ||
{{#vardefine:header_title|jump {{LSL Param|jump_target|target}};}} | |||
{{#vardefine:header_text|{{{!}} | |||
{{LSL DefineRow|label|target|{{#var:p_jump_target_desc}}}} | {{LSL DefineRow|label|target|{{#var:p_jump_target_desc}}}} | ||
{{!}}} | {{!}}} | ||
}}{{#vardefine:constants_nb| | }} | ||
{{#vardefine:constants_nb| | |||
<div id="box"> | <div id="box"> | ||
<h2>@{{LSL Param|label_target|target}};</h2> | <h2>@{{LSL Param|label_target|target}};</h2> | ||
Line 16: | Line 21: | ||
</div> | </div> | ||
</div> | </div> | ||
}}{{#vardefine:examples| | }} | ||
< | |||
{{#vardefine:examples| | |||
<syntaxhighlight lang="lsl2">integer a = 5; | |||
jump over; | jump over; | ||
@in; | @in; | ||
Line 25: | Line 32: | ||
if(a < 6) | if(a < 6) | ||
jump in; | jump in; | ||
//script will say 5 and then 6</ | //script will say 5 and then 6</syntaxhighlight> | ||
< | <syntaxhighlight lang="lsl2"> | ||
integer getLinkWithName(string name) | |||
{ | |||
integer i = llGetLinkNumber() != 0; // Start at zero (single prim) or 1 (two or more prims) | integer i = llGetLinkNumber() != 0; // Start at zero (single prim) or 1 (two or more prims) | ||
integer x = llGetNumberOfPrims() + i; // [0, 1) or [1, llGetNumberOfPrims()] | integer x = llGetNumberOfPrims() + i; // [0, 1) or [1, llGetNumberOfPrims()] | ||
for (; i < x; ++i) { | for (; i < x; ++i) | ||
{ | |||
if (llGetLinkName(i) == name) | if (llGetLinkName(i) == name) | ||
jump break; // Found it! Exit loop early with result | jump break; // Found it! Exit loop early with result | ||
Line 36: | Line 46: | ||
@break; | @break; | ||
return i; | return i; | ||
}</ | } | ||
}}{{#vardefine:notes| | </syntaxhighlight> | ||
}}{{#vardefine:caveats| | More often than not, the rather ugly 'jump' can be avoided, especially in user defined functions, as this version of the above script demonstrates | ||
*If multiple | <syntaxhighlight lang="lsl2"> | ||
integer getLinkWithName(string name) | |||
{ | |||
integer i = llGetLinkNumber() != 0; // Start at zero (single prim) or 1 (two or more prims) | |||
integer x = llGetNumberOfPrims() + i; // [0, 1) or [1, llGetNumberOfPrims()] | |||
for (; i < x; ++i) | |||
{ | |||
if (llGetLinkName(i) == name) | |||
return i; // Found it, return its index | |||
} | |||
return -1; // No prim with that name, return -1. | |||
} | |||
</syntaxhighlight> | |||
}} | |||
{{#vardefine:notes| | |||
It is generally considered inadvisable to use jumps (commonly know as gotos) where other flow control structures could be used. | |||
* {{Wikipedia|Goto}} | |||
* [http://xkcd.com/292/ XKCD:Goto] | |||
}} | |||
{{#vardefine:lso| | |||
<h5>Multiple Jumps Bug</h5> | |||
The following function, <code>jumpy</code>, demonstrates the multiple-jump-sites-to-a-single-target bug. It appears this function should result in an infinite loop, and it does when the script is compiled for the Mono VM. However when compiled for LSO VM because of this bug the second jump never happens and the function returns. LL reported they were unwilling to fix this bug as to do so would be a breaking change. This bug was fixed in the newer Mono VM. | |||
<syntaxhighlight lang="lsl2">jumpy(){ | |||
jump next;//first jump | |||
@next; | |||
jump next;//second jump - BUG never gets executed | |||
return; | |||
}</syntaxhighlight> | |||
}} | |||
{{#vardefine:caveats| | |||
*'''In [[LSO]] Only:''' If multiple jump sites are declared for the same target label within scope, then only the first (top to bottom, left to right) will function as expected, all others will silently fail. | |||
*Labels are scoped at the event and function level, meaning that it is not possible to declare duplicate labels within the same event or function, even if the labels are enclosed in different if-statements, loops etc. -- {{JIRA|SVC-6712}} | *Labels are scoped at the event and function level, meaning that it is not possible to declare duplicate labels within the same event or function, even if the labels are enclosed in different if-statements, loops etc. -- {{JIRA|SVC-6712}} | ||
** | **If you attempt this, the script will silently fail to compile. | ||
}}{{#vardefine:helpers| | *If code exists after a return that is not encapsulated in a flow control structure, the compiler will return an error about the code being dead even if the code is accessible with a jump. -- {{Jira|SVC-1929}} | ||
}}{{#vardefine:also_header|<h3>Keywords</h3> | }} | ||
{{Issues/SVC-6712}} | |||
{{Issues/SCR-256}} | |||
{{Issues/SVC-1929}} | |||
{{#vardefine:helpers|}} | |||
{{#vardefine:also_header|<h3>Keywords</h3> | |||
{{{!}} | {{{!}} | ||
{{LSL DefineRow||[[return]]|}} | {{LSL DefineRow||[[return]]|}} | ||
{{LSL DefineRow||[[state]]|}} | {{LSL DefineRow||[[state]]|}} | ||
{{!}}} | {{!}}} | ||
}}{{#vardefine:also_footer| | }} | ||
}}{{#vardefine:also_functions| | |||
}}{{#vardefine:also_events| | {{#vardefine:also_footer|}} | ||
}}{{#vardefine:also_articles| | {{#vardefine:also_functions|}} | ||
}}{{#vardefine:also_tests| | {{#vardefine:also_events|}} | ||
}}{{#vardefine:location| | {{#vardefine:also_articles|}} | ||
{{#vardefine:also_tests|}} | |||
{{#vardefine:location|}} | |||
}}{{LSL Generic}}{{LSLC|Flow Control}} | }}{{LSL Generic}}{{LSLC|Flow Control}} |
Latest revision as of 11:40, 5 January 2023
LSL Portal | Functions | Events | Types | Operators | Constants | Flow Control | Script Library | Categorized Library | Tutorials |
- The correct title of this article is jump. The initial letter is shown capitalized due to technical restrictions.
jump target;
jump target;• label | target | – | Name of a label inside the same function or event scope. |
@target;
• label | target | – | A label that can be jumped to, if the jump is in the same scope or child scope. It isn't possible to jump between scopes (such as between functions, events or states). |
Caveats
- In LSO Only: If multiple jump sites are declared for the same target label within scope, then only the first (top to bottom, left to right) will function as expected, all others will silently fail.
- Labels are scoped at the event and function level, meaning that it is not possible to declare duplicate labels within the same event or function, even if the labels are enclosed in different if-statements, loops etc. -- SVC-6712
- If you attempt this, the script will silently fail to compile.
- If code exists after a return that is not encapsulated in a flow control structure, the compiler will return an error about the code being dead even if the code is accessible with a jump. -- SVC-1929
Examples
integer a = 5;
jump over;
@in;
a = 6;
@over;
llOwnerSay((string)a);
if(a < 6)
jump in;
//script will say 5 and then 6
integer getLinkWithName(string name)
{
integer i = llGetLinkNumber() != 0; // Start at zero (single prim) or 1 (two or more prims)
integer x = llGetNumberOfPrims() + i; // [0, 1) or [1, llGetNumberOfPrims()]
for (; i < x; ++i)
{
if (llGetLinkName(i) == name)
jump break; // Found it! Exit loop early with result
}
i = -1; // No prim with that name, return -1.
@break;
return i;
}
More often than not, the rather ugly 'jump' can be avoided, especially in user defined functions, as this version of the above script demonstrates
integer getLinkWithName(string name)
{
integer i = llGetLinkNumber() != 0; // Start at zero (single prim) or 1 (two or more prims)
integer x = llGetNumberOfPrims() + i; // [0, 1) or [1, llGetNumberOfPrims()]
for (; i < x; ++i)
{
if (llGetLinkName(i) == name)
return i; // Found it, return its index
}
return -1; // No prim with that name, return -1.
}
Notes
Deep Notes
LSO VM Notes
Multiple Jumps Bug
The following function, jumpy
, demonstrates the multiple-jump-sites-to-a-single-target bug. It appears this function should result in an infinite loop, and it does when the script is compiled for the Mono VM. However when compiled for LSO VM because of this bug the second jump never happens and the function returns. LL reported they were unwilling to fix this bug as to do so would be a breaking change. This bug was fixed in the newer Mono VM.
jumpy(){
jump next;//first jump
@next;
jump next;//second jump - BUG never gets executed
return;
}