# # The RubyVM module only exists on MRI. `RubyVM` is not defined in other Ruby # implementations such as JRuby and TruffleRuby. # # The RubyVM module provides some access to MRI internals. This module is for # very limited purposes, such as debugging, prototyping, and research. Normal # users must not use it. This module is not portable between Ruby # implementations. # class RubyVM < Object end # # ::RubyVM::DEFAULT_PARAMS This constant exposes the VM's default parameters. # Note that changing these values does not affect VM execution. Specification is # not stable and you should not depend on this value. Of course, this constant # is MRI specific. # RubyVM::DEFAULT_PARAMS: Hash[Symbol, Integer] # # ::RubyVM::INSTRUCTION_NAMES A list of bytecode instruction names in MRI. This # constant is MRI specific. # RubyVM::INSTRUCTION_NAMES: Array[String] # # ::RubyVM::OPTS An Array of VM build options. This constant is MRI specific. # RubyVM::OPTS: Array[String] # # The InstructionSequence class represents a compiled sequence of instructions # for the Virtual Machine used in MRI. Not all implementations of Ruby may # implement this class, and for the implementations that implement it, the # methods defined and behavior of the methods can change in any version. # # With it, you can get a handle to the instructions that make up a method or a # proc, compile strings of Ruby code down to VM instructions, and disassemble # instruction sequences to strings for easy inspection. It is mostly useful if # you want to learn how YARV works, but it also lets you control various # settings for the Ruby iseq compiler. # # You can find the source for the VM instructions in `insns.def` in the Ruby # source. # # The instruction sequence results will almost certainly change as Ruby changes, # so example output in this documentation may be different from what you see. # # Of course, this class is MRI specific. # class RubyVM::InstructionSequence < Object end # # AbstractSyntaxTree provides methods to parse Ruby code into abstract syntax # trees. The nodes in the tree are instances of # RubyVM::AbstractSyntaxTree::Node. # # This module is MRI specific as it exposes implementation details of the MRI # abstract syntax tree. # # This module is experimental and its API is not stable, therefore it might # change without notice. As examples, the order of children nodes is not # guaranteed, the number of children nodes might change, there is no way to # access children nodes by name, etc. # # If you are looking for a stable API or an API working under multiple Ruby # implementations, consider using the *parser* gem or Ripper. If you would like # to make RubyVM::AbstractSyntaxTree stable, please join the discussion at # https://bugs.ruby-lang.org/issues/14844. # module RubyVM::AbstractSyntaxTree # # Parses the given *string* into an abstract syntax tree, returning the root # node of that tree. # # RubyVM::AbstractSyntaxTree.parse("x = 1 + 2") # # => # # # If `keep_script_lines: true` option is provided, the text of the parsed source # is associated with nodes and is available via Node#script_lines. # # If `keep_tokens: true` option is provided, Node#tokens are populated. # # SyntaxError is raised if the given *string* is invalid syntax. To overwrite # this behavior, `error_tolerant: true` can be provided. In this case, the # parser will produce a tree where expressions with syntax errors would be # represented by Node with `type=:ERROR`. # # root = RubyVM::AbstractSyntaxTree.parse("x = 1; p(x; y=2") # # :33:in `parse': syntax error, unexpected ';', expecting ')' (SyntaxError) # # x = 1; p(x; y=2 # # ^ # # root = RubyVM::AbstractSyntaxTree.parse("x = 1; p(x; y=2", error_tolerant: true) # # (SCOPE@1:0-1:15 # # tbl: [:x, :y] # # args: nil # # body: (BLOCK@1:0-1:15 (LASGN@1:0-1:5 :x (LIT@1:4-1:5 1)) (ERROR@1:7-1:11) (LASGN@1:12-1:15 :y (LIT@1:14-1:15 2)))) # root.children.last.children # # [(LASGN@1:0-1:5 :x (LIT@1:4-1:5 1)), # # (ERROR@1:7-1:11), # # (LASGN@1:12-1:15 :y (LIT@1:14-1:15 2))] # # Note that parsing continues even after the errored expression. # def self.parse: (String string, ?keep_script_lines: bool, ?error_tolerant: bool, ?keep_tokens: bool) -> Node # # Reads the file from *pathname*, then parses it like ::parse, returning the # root node of the abstract syntax tree. # # SyntaxError is raised if *pathname*'s contents are not valid Ruby syntax. # # RubyVM::AbstractSyntaxTree.parse_file("my-app/app.rb") # # => # # # See ::parse for explanation of keyword argument meaning and usage. # def self.parse_file: (String | ::_ToPath string, ?keep_script_lines: bool, ?error_tolerant: bool, ?keep_tokens: bool) -> Node # # Returns AST nodes of the given *proc* or *method*. # # RubyVM::AbstractSyntaxTree.of(proc {1 + 2}) # # => # # # def hello # puts "hello, world" # end # # RubyVM::AbstractSyntaxTree.of(method(:hello)) # # => # # # See ::parse for explanation of keyword argument meaning and usage. # def self.of: (Proc | Method | UnboundMethod body, ?keep_script_lines: bool, ?error_tolerant: bool, ?keep_tokens: bool) -> Node? # # Returns the node id for the given backtrace location. # # begin # raise # rescue => e # loc = e.backtrace_locations.first # RubyVM::AbstractSyntaxTree.node_id_for_backtrace_location(loc) # end # => 0 # def self.node_id_for_backtrace_location: (Thread::Backtrace::Location backtrace_location) -> Integer # # RubyVM::AbstractSyntaxTree::Node instances are created by parse methods in # RubyVM::AbstractSyntaxTree. # # This class is MRI specific. # class Node # # Returns the type of this node as a symbol. # # root = RubyVM::AbstractSyntaxTree.parse("x = 1 + 2") # root.type # => :SCOPE # lasgn = root.children[2] # lasgn.type # => :LASGN # call = lasgn.children[1] # call.type # => :OPCALL # def type: () -> Symbol # # The line number in the source code where this AST's text began. # def first_lineno: () -> Integer # # The column number in the source code where this AST's text began. # def first_column: () -> Integer # # The line number in the source code where this AST's text ended. # def last_lineno: () -> Integer # # The column number in the source code where this AST's text ended. # def last_column: () -> Integer # # Returns tokens corresponding to the location of the node. Returns `nil` if # `keep_tokens` is not enabled when #parse method is called. # # root = RubyVM::AbstractSyntaxTree.parse("x = 1 + 2", keep_tokens: true) # root.tokens # => [[0, :tIDENTIFIER, "x", [1, 0, 1, 1]], [1, :tSP, " ", [1, 1, 1, 2]], ...] # root.tokens.map{_1[2]}.join # => "x = 1 + 2" # # Token is an array of: # # * id # * token type # * source code text # * location [ first_lineno, first_column, last_lineno, last_column ] # def tokens: () -> Array[[Integer, Symbol, String, [Integer, Integer, Integer, Integer]]]? # # Returns all tokens for the input script regardless the receiver node. Returns # `nil` if `keep_tokens` is not enabled when #parse method is called. # # root = RubyVM::AbstractSyntaxTree.parse("x = 1 + 2", keep_tokens: true) # root.all_tokens # => [[0, :tIDENTIFIER, "x", [1, 0, 1, 1]], [1, :tSP, " ", [1, 1, 1, 2]], ...] # root.children[-1].all_tokens # => [[0, :tIDENTIFIER, "x", [1, 0, 1, 1]], [1, :tSP, " ", [1, 1, 1, 2]], ...] # def all_tokens: () -> Array[[Integer, Symbol, String, [Integer, Integer, Integer, Integer]]]? # # Returns AST nodes under this one. Each kind of node has different children, # depending on what kind of node it is. # # The returned array may contain other nodes or `nil`. # def children: () -> Array[untyped] end end # # This module allows for introspection of YJIT, CRuby's just-in-time compiler. # Everything in the module is highly implementation specific and the API might # be less stable compared to the standard library. # This module may not exist if YJIT does not support the particular platform # for which CRuby is built. # module RubyVM::YJIT # # Discard existing compiled code to reclaim memory # and allow for recompilations in the future. # def self.code_gc: () -> void # # Marshal dumps exit locations to the given filename. # Usage: # If `--yjit-exit-locations` is passed, a file named # "yjit_exit_locations.dump" will automatically be generated. # If you want to collect traces manually, call `dump_exit_locations` # directly. # Note that calling this in a script will generate stats after the # dump is created, so the stats data may include exits from the # dump itself. # In a script call: # at_exit do # RubyVM::YJIT.dump_exit_locations("my_file.dump") # end # # Then run the file with the following options: # ruby --yjit --yjit-trace-exits test.rb # # Once the code is done running, use Stackprof to read the dump file. # See Stackprof documentation for options. # def self.dump_exit_locations: (untyped filename) -> void # # Enable YJIT compilation. # def self.enable: () -> void # # Check if YJIT is enabled. # def self.enabled?: () -> bool # # Format large numbers with comma separators for readability # def self.format_number: (untyped pad, untyped number) -> untyped # # Format a number along with a percentage over a total value # def self.format_number_pct: (untyped pad, untyped number, untyped total) -> untyped # # Discard statistics collected for `--yjit-stats`. # def self.reset_stats!: () -> void # # Return a hash for statistics generated for the `--yjit-stats` command line # option. # Return `nil` when option is not passed or unavailable. # def self.runtime_stats: (?context: bool) -> Hash[untyped, untyped]? # # Check if `--yjit-stats` is used. # def self.stats_enabled?: () -> bool # # Format and print out counters as a String. This returns a non-empty # content only when `--yjit-stats` is enabled. # def self.stats_string: () -> String end module RubyVM::RJIT end