Sha256: d2c5bc354cfeb0f61586e8aaa7d7ae3f98500826db516c1a34e965309c15f015

Contents?: true

Size: 1.56 KB

Versions: 15

Compression:

Stored size: 1.56 KB

Contents

# frozen_string_literal: true

require 'appmap/handler/function'

module AppMap
  module Handler
    # Handler class for Kernel#eval.
    #
    # Second argument to eval is a Binding, which despite the name (and
    # the accessible methods) in addition to locals and receiver also
    # encapsulates the entire execution context, in particular including
    # the lexical scope. This is especially important for constant lookup
    # and definition.
    #
    # If the binding is not provided, by default eval will run in the
    # current frame. Since we call it here, this will mean the #do_call
    # frame, which would make AppMap::Handler::Eval the lexical scope
    # for constant lookup and definition; as a consequence
    # eg. `eval "class Foo; end"` would define
    # AppMap::Handler::Eval::Foo instead of defining it in
    # the module where the original call was made.
    #
    # To avoid this, we explicitly substitute the correct execution
    # context, up several stack frames.
    class Eval < Function
      # The depth of the frame we need to pluck out:
      # 1. Hook::Method#do_call
      # 2. Hook::Method#trace_call
      # 3. Hook::Method#call
      # 4. proc generated by Hook::Method#hook_method_def
      # 5. the (intended) frame of the original eval that we hooked
      # Note it needs to be adjusted if this call sequence changes.
      FRAME_DEPTH = 5

      def do_call(receiver, src = nil, context = nil, *rest)
        context ||= AppMap.caller_binding FRAME_DEPTH
        hook_method.bind(receiver).call(src, context, *rest)
      end
    end
  end
end

Version data entries

15 entries across 15 versions & 1 rubygems

Version Path
appmap-0.83.6 lib/appmap/handler/eval.rb
appmap-0.83.5 lib/appmap/handler/eval.rb
appmap-0.83.4 lib/appmap/handler/eval.rb
appmap-0.83.3 lib/appmap/handler/eval.rb
appmap-0.83.2 lib/appmap/handler/eval.rb
appmap-0.83.1 lib/appmap/handler/eval.rb
appmap-0.83.0 lib/appmap/handler/eval.rb
appmap-0.82.0 lib/appmap/handler/eval.rb
appmap-0.81.1 lib/appmap/handler/eval.rb
appmap-0.81.0 lib/appmap/handler/eval.rb
appmap-0.80.2 lib/appmap/handler/eval.rb
appmap-0.80.1 lib/appmap/handler/eval.rb
appmap-0.80.0 lib/appmap/handler/eval.rb
appmap-0.79.0 lib/appmap/handler/eval.rb
appmap-0.78.0 lib/appmap/handler/eval.rb