Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ArrayIndexOutOfBoundsException - EmbeddedSlotMap? #390

Closed
tmallery opened this issue Feb 14, 2018 · 10 comments
Closed

ArrayIndexOutOfBoundsException - EmbeddedSlotMap? #390

tmallery opened this issue Feb 14, 2018 · 10 comments

Comments

@tmallery
Copy link

tmallery commented Feb 14, 2018

I'm seeing an ArrayIndexOutOfBoundsException in ScriptableObject.getIds(boolean, boolean) because the EmbeddedSlotMap iterator is returning one more result than its count, "map.size()", is returning.
Has anyone else seen this? I haven't found the cause yet so I can't make a test case, I only see the error after a lot of processing has happened so I don't yet know the sequence of events that causes this problem. However I tried removing EmbeddedSlotMap by having SlopMapContainer just make HashSlotMap and that "fixed" this issue.

This also might be caused by a fix I'm currently doing to allow Object.getOwnPropertyDescriptor("z", 0) and "z".propertyIsEnumerable(0) to work. I'll provide more information as I find it.

@gbrail
Copy link
Collaborator

gbrail commented Feb 14, 2018 via email

@tmallery
Copy link
Author

ArrayIndexOutOfBoundsException: 231 (evaluateExpression_39102403#1)
org.mozilla.v17.javascript.WrappedException: Wrapped java.lang.ArrayIndexOutOfBoundsException: 231 (evaluateExpression_39102403#1)
at org.mozilla.v17.javascript.Context.throwAsScriptRuntimeEx(Context.java:1924)
at org.mozilla.v17.javascript.MemberBox.invoke(MemberBox.java:148)
at org.mozilla.v17.javascript.FunctionObject.call(FunctionObject.java:452)
at org.mozilla.v17.javascript.Interpreter.interpretLoop(Interpreter.java:1492)
at script(evaluateExpression_39102403:1)
at org.mozilla.v17.javascript.Interpreter.interpret(Interpreter.java:823)
at org.mozilla.v17.javascript.InterpretedFunction.call(InterpretedFunction.java:109)
at org.mozilla.v17.javascript.ContextFactory.doTopCall(ContextFactory.java:402)
at org.mozilla.v17.javascript.ScriptRuntime.doTopCall(ScriptRuntime.java:3514)
at org.mozilla.v17.javascript.InterpretedFunction.exec(InterpretedFunction.java:120)
at org.mozilla.v17.javascript.Context.evaluateString(Context.java:1254)
Caused by: java.lang.ArrayIndexOutOfBoundsException: 231
at org.mozilla.v17.javascript.ScriptableObject.getIds(ScriptableObject.java:2933)
at org.mozilla.v17.javascript.NativeObject.execIdCall(NativeObject.java:306)
at org.mozilla.v17.javascript.IdFunctionObject.call(IdFunctionObject.java:106)
at org.mozilla.v17.javascript.Interpreter.interpretLoop(Interpreter.java:1492)
at org.mozilla.v17.javascript.Interpreter.interpret(Interpreter.java:823)
at org.mozilla.v17.javascript.InterpretedFunction.call(InterpretedFunction.java:109)

@tmallery
Copy link
Author

I haven't created a test case yet, but I believe I found the issue. EmbeddedSlotMap.createSlot when there is an existing slot. The code adds the new slot to the linked list as if it were a brand new slot, but its not really, it's replacing the existing slot. The code does not remove the existing node from the linked list before adding the new one. I did a quick and dirty test and it works.
// remove old entry from the linked list
ScriptableObject.Slot temp = firstAdded;
ScriptableObject.Slot orderedPrev = null;
while( temp != null ) {
if( temp == slot ) {
if( orderedPrev != null ) {
orderedPrev.orderedNext = slot.orderedNext;
}
break;
}
orderedPrev = temp;
temp = temp.orderedNext;
}

// add new slot to linked list
......

@tmallery
Copy link
Author

I'll throw this into a test case, but here's the JS to reproduce the ArrayIndexoutofBoundsException
var obj = new Object();
Object.defineProperty(obj, 'aProp', {configurable:true, get:function() {return 1;}, set:function(arg){ }});" +
Object.defineProperty(obj, 'aProp', {value:42});
if( Object.getOwnPropertyNames(obj).length != 1 ) { result = 'success'; } result;

@gbrail
Copy link
Collaborator

gbrail commented Feb 15, 2018

You are exactly right -- Thanks! That is a nasty error in a complicated bit of code.

I just submitted a PR -- can you take a look?

@gbrail
Copy link
Collaborator

gbrail commented Feb 27, 2018

Fixed in #391.

@raimi
Copy link

raimi commented Mar 15, 2018

Aw man. This ".0" behaviour has been bothering us forever. We have workaround-code at our end to find the integer from the floting point number again.
I'm also a little worried about the performance impact of that extra conversion-check - but the overall behaviour becomes better and less surprising.

I handle way more integers than floating point numbers in my programs...

@gbrail
Copy link
Collaborator

gbrail commented Mar 15, 2018 via email

@raimi
Copy link

raimi commented Mar 16, 2018

No no no, do not enable it by default (yet). I also think it may break things for too many people.
But with the optional feature available, we could start to experiment with it.

@phil15world988
Copy link

the best

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants