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

Improve refinements implementation #5604

Merged
merged 33 commits into from Feb 11, 2019
Merged

Improve refinements implementation #5604

merged 33 commits into from Feb 11, 2019

Commits on Jan 7, 2019

  1. Copy the full SHA
    4713551 View commit details
    Browse the repository at this point in the history
  2. Copy the full SHA
    7f2ab5c View commit details
    Browse the repository at this point in the history
  3. Copy the full SHA
    7bcffb3 View commit details
    Browse the repository at this point in the history

Commits on Jan 10, 2019

  1. Implement missing behavior for refinements based on MRI.

    MRI's data structures for managing method tables are very similar
    to ours, so I'm following their pattern of inserting wrapper or
    dummy refined entries into classes that get refined elsewhere in
    the system.
    
    Here's a summary of the logic:
    
    When defining a method:
    
    * If the method does not already exist and the target module is a
      refinement module (isRefinement), add a refined method entry to
      the related class.
      * If the method also exists on the target class, wrap the
        existing method with a refined entry.
    
    Because we always search for a refined marker in the class
    hierarchy, we know which refined class to look for; this will fix
    issues with refining a superclass of the target type, broken
    currently.
    
    When dispatching:
    
    * Look for the method in the target class.
    * If the entry is not marked as refined, return it.
    * If the resulting entry is refined, search the refinement scope
      for a refined version of the method.
    * If there's no refined version of the method in the refinement
      scope:
      * If the entry is a wrapper, return the wrapped method.
      * If the entry is a marker, continue the search up the
        hierarchy.
    * This uses the owned class of the discovered unrefined method as
      the "super" class for the refinement, allowing supers to work
      from there.
    headius committed Jan 10, 2019
    Copy the full SHA
    c1d975f View commit details
    Browse the repository at this point in the history

Commits on Jan 11, 2019

  1. Rework class hierarchy management for refinements.

    This gets back to most functionality working plus a number of new
    tests passing. The RefinedMarker instances are still leaking out
    to various places, which is the cause of most of the regressed
    tests.
    headius committed Jan 11, 2019
    Copy the full SHA
    44e1ef8 View commit details
    Browse the repository at this point in the history
  2. Oops, reverse this boolean.

    headius committed Jan 11, 2019
    Copy the full SHA
    742de24 View commit details
    Browse the repository at this point in the history
  3. Fix refinement inspect.

    headius committed Jan 11, 2019
    Copy the full SHA
    d1b69b5 View commit details
    Browse the repository at this point in the history
  4. Undefine #refine in Class.

    headius committed Jan 11, 2019
    Copy the full SHA
    1393cfe View commit details
    Browse the repository at this point in the history
  5. Copy the full SHA
    5b5bc5e View commit details
    Browse the repository at this point in the history
  6. Copy the full SHA
    6dbaaec View commit details
    Browse the repository at this point in the history
  7. Copy the full SHA
    d23fff1 View commit details
    Browse the repository at this point in the history
  8. Copy refinements into child scope on first use.

    MRI does this in vm_cref_new, which I believe is called on first
    entry to a method, block, or module body. In their case, they
    reference the original overlay module and mark it as shared. Any
    subsequent modifications cause it to be replaced on the parent
    scopes. In JRuby, I am currently only propagating refinements into
    class/module and method bodies, which means blocks and evals and
    such still need to search up the hierarchy a bit. I am also doing
    a hard copy of the related collection, which could add overhead to
    boot time.
    headius committed Jan 11, 2019
    Copy the full SHA
    ba26191 View commit details
    Browse the repository at this point in the history

Commits on Jan 14, 2019

  1. Copy the full SHA
    cc730b9 View commit details
    Browse the repository at this point in the history
  2. Copy the full SHA
    1f76578 View commit details
    Browse the repository at this point in the history
  3. Update refinement tags.

    headius committed Jan 14, 2019
    Copy the full SHA
    9f68575 View commit details
    Browse the repository at this point in the history

Commits on Jan 29, 2019

  1. Temporary fix for our refined wrappers not actually wrapping.

    MRI's logic for an existing method that gets refined expects that
    it will be wrapped by a refinement marker. This allows the
    original method to be pulled out and look unrefined for other
    logic we also mimic. Since currently I do not wrap, but instead
    flag, the original method, there's no way to get an original that
    isn't refined without duping the method here. This is inefficient
    and may lead to peculiar side effects so I will return to using
    a full wrapper in a subsequent commit.
    headius committed Jan 29, 2019
    Copy the full SHA
    f601372 View commit details
    Browse the repository at this point in the history
  2. Copy the full SHA
    0073bf2 View commit details
    Browse the repository at this point in the history

Commits on Jan 30, 2019

  1. Copy the full SHA
    0d9e555 View commit details
    Browse the repository at this point in the history
  2. Make AsString an instruction with a proper call site.

    This is necessary to handle refined to_s calls from interpolated
    strings, as in MRI test_refinement.rb test_tostring.
    headius committed Jan 30, 2019
    Copy the full SHA
    fc4797a View commit details
    Browse the repository at this point in the history
  3. Copy the full SHA
    e93e201 View commit details
    Browse the repository at this point in the history
  4. Handle refinements within Symbol proc.

    This logic modifies all calls with non-literal procs to pass the
    current scope through, and modifies the coercion logic to handle
    Symbol specially by passing the scope in. This will in turn use
    refinements when present.
    
    Note that this is not quite as optimal as the SymbolProc operand
    but is still static for the creation of the proc.
    headius committed Jan 30, 2019
    Copy the full SHA
    9fb8281 View commit details
    Browse the repository at this point in the history
  5. Copy the full SHA
    d1a7206 View commit details
    Browse the repository at this point in the history
  6. Copy the full SHA
    328dda0 View commit details
    Browse the repository at this point in the history
  7. Update refinement tags.

    headius committed Jan 30, 2019
    Copy the full SHA
    2067a6e View commit details
    Browse the repository at this point in the history

Commits on Jan 31, 2019

  1. Apparently not passing.

    headius committed Jan 31, 2019
    Copy the full SHA
    f3a53cd View commit details
    Browse the repository at this point in the history
  2. Copy the full SHA
    1937c13 View commit details
    Browse the repository at this point in the history
  3. Copy the full SHA
    0b006ee View commit details
    Browse the repository at this point in the history
  4. Copy the full SHA
    29f72cf View commit details
    Browse the repository at this point in the history
  5. Copy the full SHA
    e2a35a2 View commit details
    Browse the repository at this point in the history
  6. Set refine block refinements to parent and search all the way.

    This is not quite the right logic, since MRI will copy refinements
    into each level and only search the one level. We do not
    consistently do that, so we still search the scope hierarchy for
    other refinements. This is inefficient and should change, but this
    patch at least allows mutually-dependent refine blocks to see
    each other.
    headius committed Jan 31, 2019
    Copy the full SHA
    6af14a1 View commit details
    Browse the repository at this point in the history
  7. Copy the full SHA
    1372e8d View commit details
    Browse the repository at this point in the history
  8. Copy the full SHA
    e337036 View commit details
    Browse the repository at this point in the history

Commits on Feb 3, 2019

  1. Copy the full SHA
    80016eb View commit details
    Browse the repository at this point in the history