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

Fix for rakudo/rakudo#2178 #2749

Merged
merged 7 commits into from Aug 16, 2019
Merged

Fix for rakudo/rakudo#2178 #2749

merged 7 commits into from Aug 16, 2019

Conversation

vrurg
Copy link
Member

@vrurg vrurg commented Mar 7, 2019

The fix is done by implementing cooperation between dispatchers. If a
dispatcher finds out that next call in the queue is a invocation handler
with attribute $!dispatcher containing a object of descendant type of
Metamodel::BaseDispatcher it passes control over to that dispatcher by
calling either enter_with_args or enter_with_capture method. The
subsequent dispatcher passes control back to the calling dispatcher upon
exhausting its own queue.

The known problems of this fix:

  • there is no clear way to determine if next call is a invocation
    handler. The approach used by this fix is to wrap the attempt to read
    from $!dispatcher attribute into a try block is hacky and would have
    performance penalty. Must be changed as soon as more straightforward
    approach is developed or found.

#2178

The fix is done by implementing cooperation between dispatchers. If a
dispatcher finds out that next call in the queue is a invocation handler
with attribute $!dispatcher containing a object of descendant type of
Metamodel::BaseDispatcher it passes control over to that dispatcher by
calling either enter_with_args or enter_with_capture method. The
subsequent dispatcher passes control back to the calling dispatcher upon
exhausting its own queue.

The known problems of this fix:

- there is no clear way to determine if next call is a invocation
handler. The approach used by this fix is to wrap the attempt to read
from $!dispatcher attribute into a try block is hacky and would have
performance penalty. Must be changed as soon as more straightforward
approach is developed or found.

- The enter_* methods are currently specific to the WrapDisptacher. So
far there is seemingly no way to create a invocation handler with method
or multi dispatcher in $!dispatcher and get such handler inserted into
the WrapDispatcher queue. But neither there is no guaranty that no other
such dispatcher would be developed in the future. For this reason the
enter_* methods must be standartized and possibly moved into
BaseDispatcher class.
@vrurg
Copy link
Member Author

vrurg commented Mar 8, 2019

A problem has been discovered which needs fixing before this PR is ready.

For wrapper-like dispatchers (with WrapDispatcher being currently the
only one) we won't set explicit dispatcher for the last candidate on the
queue effectively allowing a control call like callsame/nextsame to
obtain routine's default dispatcher. This fixes a situation when a
wrapped method cannot pass control over to the next method on
MethodDispatcher queue.

rakudo#2178
@vrurg
Copy link
Member Author

vrurg commented Mar 9, 2019

The problem has been resolved, this PR is ready for review.

vrurg added a commit to vrurg/roast that referenced this pull request Mar 9, 2019
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

Successfully merging this pull request may close these issues.

None yet

2 participants