@szegedia I tried your suggestion, but the guards are not triggered, turns out the problem is with the generators, for which support for "wide call" invocations is not yet implemented. :(
Thanks for your help. Isaiah On Tue, 1 Aug 2017 at 14:38 Attila Szegedi <szege...@gmail.com> wrote: > 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 <issa...@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 > >