Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

script error/ Invalid IL code (!)

Argo Nurmi
Registered User
Join date: 21 Nov 2007
Posts: 4
02-28-2009 06:27
My apologies if this isn't the right forum for this, but here goes:

I'm writing a user function that compares two integer lists and returns a 1 or 0 depending
if they have the same contents. The function explodes in execution: see below.

Here is the function:

integer compare(list l1, list l2){
if (l1!=l2 ){ //looking at length, this statement works as expected
llSay(0,"LENGTH ERROR";);
return -1;
}
// It blows up around here
integer v=1; //These declarations are where the problem may be
integer i=0; //....

for(i=0;i<llGetListLength(l1);i++) //never get this far
v = v & ((integer) (llList2Integer(l1,i) == llList2Integer(l2,i)));
return v;

}
I've included the "output" from SL below.
I can decode some of it but its not too user friendly. The object is "Mailbox" and
the script is named "APL Functions" I don't know what "IL code" means or what I
should do with it. I ran it through w-hat lint with no errors so I didn't expect it to
blow up. Any ideas?

Thanks --Argo.


[script:APL functions]: Script run-time error
[6:03] mailbox function object 2 [script:APL functions]: System.InvalidProgramException: Invalid IL code in LSL_df8db0b3_17d4_662f_f210_b10ce933d487:gcompare (System.Collections.ArrayList,System.Collections.ArrayList): IL_0025: stloc.1
at LSL_df8db0b3_17d4_662f_f210_b10ce933d487.edefaultstate_entry () [0x00000]
at LSL_df8db0b3_17d4_662f_f210_b10ce933d487edefaultstate_entryFrame.ResumeVoid () [0x00000]
at LindenLab.SecondLife.UThread.UThread.Run () [0x00000]
at LindenLab.SecondLife.Script.Run (ScriptEvent evt) [0x00000]
Dora Gustafson
Registered User
Join date: 13 Mar 2007
Posts: 779
02-28-2009 06:53
where does the 'blow up code' belong?
As far as I can see it does not belong to your function: integer compare(list l1, list l2)
I take it back, I see it now:)
_____________________
From Studio Dora
Ruthven Willenov
Darkness in your light
Join date: 16 Jan 2008
Posts: 965
02-28-2009 07:01
to compare lists, don't you need to run them thru a loop to see if anything pops up in one that's not in the other? maybe that's where the run time error is coming from?
_____________________
Dark Heart Emporium

http://www.xstreetsl.com/modules.php?name=Marketplace&MerchantID=133020

want more layers for tattoos, specifically for the head? vote here
http://jira.secondlife.com/browse/VWR-1449?

llDetectedCollision* Functions similar to touch
http://jira.secondlife.com/browse/SVC-3369
Innula Zenovka
Registered User
Join date: 20 Jun 2007
Posts: 1,825
02-28-2009 09:16
From: Ruthven Willenov
to compare lists, don't you need to run them thru a loop to see if anything pops up in one that's not in the other? maybe that's where the run time error is coming from?
I think you can use llListFindList rather than loop them. There's a useful-looking function (which I haven't tested) that tests for list equality at http://rpgstats.com/wiki/index.php?title=Annoyances (the annoyance being that ListA == ListB returns true if they are the same length, regardless of their contents):
CODE
integer listsEqual(list src, list test) {
return (llGetListLength(src) == llGetListLength(test)
&& (llListFindList(src, test) == 0 || src == []));
}
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
Don't Fix It!!!
02-28-2009 10:21
DON'T FIX YOUR SCRIPT YET! Make a copy first! PLEASE submit a JIRA about this. It's a Mono stack trace that is being printed out, and since it appears you have a reproducible condition under which this happens, it is very important that you get that info to LL. If you can put the whole script in the JIRA, or trim it down to a set of content that you are willing to post and that still exhibits the problem (but again MAKE A COPY FIRST just in case you remove the condition that causes the stack trace) that would be ideal. Otherwise, if you can describe as much content as possible and offer to get the script privately to a Linden, that would be almost as good.
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
02-28-2009 10:21
EDIT: what hewee said, try my suggestion in a new script

actually, if the list(s) contain repeats of integers, list find won't do to check for exactly matching lists, the op's method should (but there's a minor logical error)


for(i=0;i<llGetListLength(l1);i++){ //never get this far
v = v & ((integer) (llList2Integer(l1,i) == llList2Integer(l2,i)));//-- v = 1 if the list contains a multiple of 2 mismatches
}
return v;

try this instead
CODE

for (i = 0; i < llGetListLength( l1 ); ++i){
if (llList2Integer( l1, i ) == llList2Integer( l2, i )){
return FALSE; //-- returns 0 for correct list length, with any mismatched elements
}
}
return TRUE; //-- returns 1 for matching length and items


I don't see offhand why your declarations would cause an error, check variable declarations in the rest of the event code, perhaps you redeclared the same variable name?
_____________________
|
| . "Cat-Like Typing Detected"
| . This post may contain errors in logic, spelling, and
| . grammar known to the SL populace to cause confusion
|
| - Please Use PHP tags when posting scripts/code, Thanks.
| - Can't See PHP or URL Tags Correctly? Check Out This Link...
| -
Ron Khondji
Entirely unlike.
Join date: 6 Jan 2007
Posts: 224
02-28-2009 12:42
This does not work:
From: someone

CODE

integer compare(list l1, list l2)
{
if (l1!=l2 ){ //looking at length, this statement works as expected
llSay(0,"LENGTH ERROR");
return -1;
}
// It blows up around here
integer v = 1; //These declarations are where the problem may be
integer i; //....

for(i=0;i<llGetListLength(l1);i++){ //never get this far
v = v & ((integer) (llList2Integer(l1,i) == llList2Integer(l2,i)));
}

return v;
}

default
{
touch_start(integer total_number)
{
list one = [1,2,3];
list two = [1,2,3];

llSay(0, (string)compare(one, two));
}
}



This does however work like a charm:
From: someone

CODE

integer compare(list l1, list l2)
{
if (l1!=l2 ){ //looking at length, this statement works as expected
llSay(0,"LENGTH ERROR");
return -1;
}
return 0;
}

default
{
touch_start(integer total_number)
{
list one = [1,2,3];
list two = [1,2,3];

llSay(0, (string)compare(one, two));

// It blows up around here
integer v = 1; //These declarations are where the problem may be
integer i; //....

for(i=0;i<llGetListLength(one);i++){ //never get this far
v = v & ((integer) (llList2Integer(one,i) == llList2Integer(two,i)));
}

llSay(0, (string)v);
}
}



Haven't got a clue though :)
Winter Ventura
Eclectic Randomness
Join date: 18 Jul 2006
Posts: 2,579
02-28-2009 20:40
I'm not sure what this function is supposed to do, as I read it, I can't understand what it is that you're trying to do with v.

The purpose of the function seems to be to compare 2 lists. TRUE if the same, FALSE if different.

CODE

integer compare (list list1, list list2)
{
if (llListFindList(list1, list2) != -1 && llListFindList(list2, list1) != -1) return TRUE;
else return FALSE;
}




You can shorten that to a single line (as below) but I find that it makes it harder for me to read and understand when I come back later.

CODE

integer compare (list list1, list list2)
{
return (llListFindList(list1, list2) != -1 && llListFindList(list2, list1) != -1);
}



if your goal is to determine if the two lists are the same length (only) and not their contents...

CODE

integer comparelength (list list1, list list2)
{
if (llGetListLength(list1) == llGetListLength(list2)) return TRUE;
else return FALSE;
}



It would help to know more about what your function is supposed to do.
_____________________

● Inworld Store: http://slurl.eclectic-randomness.com
● Website: http://www.eclectic-randomness.com
● Twitter: @WinterVentura
Dora Gustafson
Registered User
Join date: 13 Mar 2007
Posts: 779
03-01-2009 03:26
From: Winter Ventura
I'm not sure what this function is supposed to do, as I read it, I can't understand what it is that you're trying to do with v.

The purpose of the function seems to be to compare 2 lists. TRUE if the same, FALSE if different.

CODE

integer compare (list list1, list list2)
{
if (llListFindList(list1, list2) != -1 && llListFindList(list2, list1) != -1) return TRUE;
else return FALSE;
}


Thats wonderful, beautiful:D
You may even make it simpler:
CODE

integer compare (list list1, list list2)
{
return !llListFindList(list1, list2) && !llListFindList(list2, list1);
}
Happy scripting:)
_____________________
From Studio Dora
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
03-01-2009 05:38
the v variable was accumulating bitwise matches, but would give a false positive for the following lists [1, 2] and [3, 4] (for instance) or any lists with multiples of 2 mismatches.
ex:
v = 1
v & (1 == 3) --> v = 0
v & (2 == 4) --> v = 1
returns 1 or TRUE, ie false positive

better conglomerate test:
CODE

integer isListMatching( list lis1, list list2 ){
//-- first half tests length, second half tests elements and order
return ((list1 == list2) && ~llListFindList( list1, List2 ));
}


PS my post about list find not working was going on the assumption of testing individual elements (where repeats in the lists might return a different index than the other, allowing for false positive if they had the matching elements in different positions) and should be ignored... you can test the whole sequence together... I was having a senior moment =\
_____________________
|
| . "Cat-Like Typing Detected"
| . This post may contain errors in logic, spelling, and
| . grammar known to the SL populace to cause confusion
|
| - Please Use PHP tags when posting scripts/code, Thanks.
| - Can't See PHP or URL Tags Correctly? Check Out This Link...
| -
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
03-01-2009 09:21
Right. If you really wanted to test element-by-element for some reason, you'd probably want to use llGetListEntryType() and llList2String() anyway, not llListFindList(). For example:

CODE

integer areListsIdentical(list arr1, list arr2)
{
integer len = llGetListLength(arr1);
if (llGetListLength(arr2) != len)
{
return FALSE;
|

integer i;
for (i = 0; i < len; ++i)
{
if (llGetListEntryType(arr1, i) != llGetListEntryType(arr2, i))
{
return FALSE;
} else if (llList2String(arr1, i) != llList2String(arr2, i))
{
return FALSE;
}
}

return TRUE;
}


If you knew the lists had all the same element type, you could drop the first condition in the loop. Use of the built-in comparison of llListFindList() is probably the better choice though, as long as it doesn't exhibit some kind of unexpected behavior anywhere (I expect it'll work fine for this application; it's a pretty well-tested function ;) ).
Argo Nurmi
Registered User
Join date: 21 Nov 2007
Posts: 4
follow up on the script error problem
03-01-2009 09:50
Thanks for all the suggestions per the logic etc
The most perplexing thing is why the routine should have caused a crash
Following suggestions I posted it as SVC 3915 to the JIRA.
The crash prevented me from debugging the script further so what your
finding is not finished work. I am reading through all the suggestions on
improving the logic, thanks for them.

--Argo
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
03-01-2009 10:28
Awesome and voted. Apparently there are lots of these little corner cases hiding about that might cause Mono stack traces. It may take a long time and quite a bit of diligence, but we'll help nail them down! :)