Invalidate callsite

Attila Szegedi szegedia at gmail.com
Tue Aug 1 12:37:44 UTC 2017


I’d suggest that when findCallMethod is invoked so that in the LinkRequest arguments, there’s a string argument, you produce a GuardedInvocation with the first method and a guard that checks if the relevant argument is a string, and when invoked with a PyObject, then produce a GuardedInvocation with the second method and a guard that checks if argument 3 is a PyObject.

Attila.

> On 01 Aug 2017, at 13:43, Isaiah Peng <issaria at gmail.com> wrote:
> 
> Hi guys,
> 
> My name is Isaiah, I'm currently trying to implement invokedynamic for my
> Python 3 implementation. Everything went quite well until I encountered a
> `ClassCastException` which I don't know how to fix.
> 
> Here is my theory: there are two method calls that has the same arity, with
> signatures of:
> 
> `(LPyObject;LThreadState;[LPyObject;LString;)LPyObject`
> and
> `(LPyObject;LThreadState;LPyObject;LPyObject)LPyObject`
> 
> The former is for methods that take vararg and keyword arguments, the later
> is for methods that take two arguments. The stacktrace is as following:
> 
> java.lang.ClassCastException: Cannot cast [Ljava.lang.String; to
> org.python.core.PyObject
> 
>        at java.base/java.lang.Class.cast(Class.java:3578)
>        at contextlib_jython_36.__init__$12(contextlib:67)
>        at org.python.core.Py.runCode(Py.java:1663)
>        at org.python.core.PyTableCode.call(PyTableCode.java:404)
>        at org.python.core.PyTableCode.call(PyTableCode.java:382)
>        at org.python.core.PyFunction.__call__(PyFunction.java:442)
>        at
> org.python.core.PyMethod.instancemethod___call__(PyMethod.java:237)
>        at org.python.core.PyMethod.__call__(PyMethod.java:228)
>        at org.python.core.PyMethod.__call__(PyMethod.java:223)
>        at org.python.core.Deriveds.dispatch__init__(Deriveds.java:19)
>        at
> org.python.core.PyObjectDerived.dispatch__init__(PyObjectDerived.java:940)
>        at org.python.core.PyType.type___call__(PyType.java:1675)
>        at org.python.core.PyType$type___call___exposer.__call__(Unknown
> Source)
>        at org.python.core.PyTypeDerived.__call__(PyTypeDerived.java:831)
>        at org.python.core.PyObject.__call__(PyObject.java:506)
>        at org.python.core.PyObject.__call__(PyObject.java:510)
>        at contextlib_jython_36.helper$17(contextlib:159)
> 
> The GuardedInvocation returned from the linker is like:
> 
> `return new GuardedInvocation(mh, null, new SwitchPoint[0],
> ClassCastException.class);`
> 
> It seems to be able to catch the class cast exception for the receiver but
> not for arguments. I create a similar call path and the function works
> fine, so I thought the cause could be the callsite is not invalidated.
> 
> My question is: Is my guess correct? if so why does it reuse the callsite
> when the signatures are different? and how to create a guard for such case?
> 
> The source code can be found here:
> 
> https://bitbucket.org/jylang/jylang/src/e0c64d17b21db7784c75892424cae09f9faa07d3/src/org/python/core/PyFunction.java?at=indy&fileviewer=file-view-default#PyFunction.java-513
> 
> Thanks in advance,
> Isaiah Peng



More information about the nashorn-dev mailing list