aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin Newton <kddnewton@gmail.com>2023-10-17 17:45:47 -0400
committergit <svn-admin@ruby-lang.org>2023-10-18 16:08:32 +0000
commitc82b10bbc3a3293ba9464c27ac5e778c70d2fe9b (patch)
tree8cd3e8515baa032dec6e425d060dd3f0311c7703
parent5d0604366e695066f32c94ebe3b4b827b2868a34 (diff)
downloadruby-c82b10bbc3a3293ba9464c27ac5e778c70d2fe9b.tar.gz
[ruby/prism] Modify less of the CRuby locals
https://github.com/ruby/prism/commit/aca24b3a17
-rw-r--r--lib/prism/debug.rb51
-rw-r--r--prism/util/pm_constant_pool.c2
-rw-r--r--prism/util/pm_constant_pool.h5
3 files changed, 32 insertions, 26 deletions
diff --git a/lib/prism/debug.rb b/lib/prism/debug.rb
index 9ec3aa9304..6a68a3d33e 100644
--- a/lib/prism/debug.rb
+++ b/lib/prism/debug.rb
@@ -45,29 +45,16 @@ module Prism
# For the given source, compiles with CRuby and returns a list of all of the
# sets of local variables that were encountered.
def self.cruby_locals(source)
- verbose = $VERBOSE
- $VERBOSE = nil
+ verbose, $VERBOSE = $VERBOSE, nil
begin
locals = []
stack = [ISeq.new(RubyVM::InstructionSequence.compile(source).to_a)]
while (iseq = stack.pop)
- if iseq.type != :once
- names = iseq.local_table
-
- # CRuby will push on a special local variable when there are keyword
- # arguments. We get rid of that here.
- names = names.grep_v(Integer)
-
- # For some reason, CRuby occasionally pushes this special local
- # variable when there are splat arguments. We get rid of that here.
- names = names.grep_v(:"#arg_rest")
-
- # Now push them onto the list of locals.
- locals << names
- end
-
+ # For some reason, CRuby occasionally pushes this special local
+ # variable when there are splat arguments. We get rid of that here.
+ locals << (iseq.local_table - [:"#arg_rest"])
iseq.each_child { |child| stack << child }
end
@@ -77,6 +64,8 @@ module Prism
end
end
+ AnonymousLocal = Object.new
+
# For the given source, parses with prism and returns a list of all of the
# sets of local variables that were encountered.
def self.prism_locals(source)
@@ -97,14 +86,28 @@ module Prism
# order here so that we can compare properly.
if params
sorted = [
- *params.requireds.grep(RequiredParameterNode).map(&:name),
+ *params.requireds.map do |required|
+ if required.is_a?(RequiredParameterNode)
+ required.name
+ else
+ AnonymousLocal
+ end
+ end,
*params.optionals.map(&:name),
*((params.rest.name || :*) if params.rest && params.rest.operator != ","),
- *params.posts.grep(RequiredParameterNode).map(&:name),
+ *params.posts.map do |post|
+ if post.is_a?(RequiredParameterNode)
+ post.name
+ else
+ AnonymousLocal
+ end
+ end,
*params.keywords.reject(&:value).map(&:name),
*params.keywords.select(&:value).map(&:name)
]
+ sorted << AnonymousLocal if params.keywords.any?
+
# Recurse down the parameter tree to find any destructured
# parameters and add them after the other parameters.
param_stack = params.requireds.concat(params.posts).grep(RequiredDestructuredParameterNode).reverse
@@ -122,11 +125,19 @@ module Prism
names = sorted.concat(names - sorted)
end
+ names.map!.with_index do |name, index|
+ if name == AnonymousLocal
+ names.length - index + 1
+ else
+ name
+ end
+ end
+
locals << names
when ClassNode, ModuleNode, ProgramNode, SingletonClassNode
locals << node.locals
when ForNode
- locals << []
+ locals << [2]
when PostExecutionNode
locals.push([], [])
when InterpolatedRegularExpressionNode
diff --git a/prism/util/pm_constant_pool.c b/prism/util/pm_constant_pool.c
index 531496fe19..63dd86a8d2 100644
--- a/prism/util/pm_constant_pool.c
+++ b/prism/util/pm_constant_pool.c
@@ -213,7 +213,7 @@ pm_constant_pool_insert(pm_constant_pool_t *pool, const uint8_t *start, size_t l
*bucket = (pm_constant_pool_bucket_t) {
.id = (unsigned int) (id & 0x3fffffff),
- .type = type,
+ .type = (unsigned int) (type & 0x3),
.hash = hash
};
diff --git a/prism/util/pm_constant_pool.h b/prism/util/pm_constant_pool.h
index 067a871c6a..defd6ad27d 100644
--- a/prism/util/pm_constant_pool.h
+++ b/prism/util/pm_constant_pool.h
@@ -51,11 +51,6 @@ static const pm_constant_pool_bucket_type_t PM_CONSTANT_POOL_BUCKET_OWNED = 1;
// A constant constant is known at compile time.
static const pm_constant_pool_bucket_type_t PM_CONSTANT_POOL_BUCKET_CONSTANT = 2;
-// An anonymous constant is one that doesn't directly reference values in the
-// source. This is used for things like the anonymous local variable introduced
-// by for loops, rescue bodies, destructured required parameters, etc.
-static const pm_constant_pool_bucket_type_t PM_CONSTANT_POOL_BUCKET_ANONYMOUS = 3;
-
typedef struct {
unsigned int id: 30;
pm_constant_pool_bucket_type_t type: 2;