diff --git a/spec/truffle/parsing/fixtures/for/multi_assignment/with_multiple_variables.yaml b/spec/truffle/parsing/fixtures/for/multi_assignment/with_multiple_variables.yaml index f7897c75b048..b41b686d5e0e 100644 --- a/spec/truffle/parsing/fixtures/for/multi_assignment/with_multiple_variables.yaml +++ b/spec/truffle/parsing/fixtures/for/multi_assignment/with_multiple_variables.yaml @@ -143,17 +143,17 @@ ast: | attributes: flags = 0 frameDepth = 1 - frameSlot = 3 + frameSlot = 3 # a WriteDeclarationVariableNode attributes: flags = 0 frameDepth = 1 - frameSlot = 4 + frameSlot = 4 # b WriteDeclarationVariableNode attributes: flags = 0 frameDepth = 1 - frameSlot = 5 + frameSlot = 5 # c ] rhsNode = ReadLocalVariableNode @@ -172,7 +172,7 @@ ast: | attributes: flags = 1 frameDepth = 1 - frameSlot = 6 + frameSlot = 6 # array children: valueNode = ArrayLiteralNode$UninitialisedArrayLiteralNode @@ -185,19 +185,19 @@ ast: | attributes: flags = 0 frameDepth = 1 - frameSlot = 3 + frameSlot = 3 # a type = FRAME_LOCAL ReadDeclarationVariableNode attributes: flags = 0 frameDepth = 1 - frameSlot = 4 + frameSlot = 4 # b type = FRAME_LOCAL ReadDeclarationVariableNode attributes: flags = 0 frameDepth = 1 - frameSlot = 5 + frameSlot = 5 # c type = FRAME_LOCAL ] ] diff --git a/spec/truffle/parsing/fixtures/for/multi_assignment/with_nested_multi_assignment.yaml b/spec/truffle/parsing/fixtures/for/multi_assignment/with_nested_multi_assignment.yaml index 5aa7c7e5d2b1..fe9159bc2a4a 100644 --- a/spec/truffle/parsing/fixtures/for/multi_assignment/with_nested_multi_assignment.yaml +++ b/spec/truffle/parsing/fixtures/for/multi_assignment/with_nested_multi_assignment.yaml @@ -143,7 +143,7 @@ ast: | attributes: flags = 0 frameDepth = 1 - frameSlot = 3 + frameSlot = 3 # a MultipleAssignmentNode attributes: flags = 0 @@ -153,12 +153,12 @@ ast: | attributes: flags = 0 frameDepth = 1 - frameSlot = 4 + frameSlot = 4 # b WriteDeclarationVariableNode attributes: flags = 0 frameDepth = 1 - frameSlot = 5 + frameSlot = 5 # c ] splatCastNode = SplatCastNodeGen @@ -185,7 +185,7 @@ ast: | attributes: flags = 1 frameDepth = 1 - frameSlot = 6 + frameSlot = 6 # array children: valueNode = ArrayLiteralNode$UninitialisedArrayLiteralNode @@ -198,19 +198,19 @@ ast: | attributes: flags = 0 frameDepth = 1 - frameSlot = 3 + frameSlot = 3 # a type = FRAME_LOCAL ReadDeclarationVariableNode attributes: flags = 0 frameDepth = 1 - frameSlot = 4 + frameSlot = 4 # b type = FRAME_LOCAL ReadDeclarationVariableNode attributes: flags = 0 frameDepth = 1 - frameSlot = 5 + frameSlot = 5 # c type = FRAME_LOCAL ] ] diff --git a/spec/truffle/parsing/fixtures/for/multi_assignment/with_preceding_splat_operator_and_following_variables.yaml b/spec/truffle/parsing/fixtures/for/multi_assignment/with_preceding_splat_operator_and_following_variables.yaml index fefb7d2d558e..d397559ef599 100644 --- a/spec/truffle/parsing/fixtures/for/multi_assignment/with_preceding_splat_operator_and_following_variables.yaml +++ b/spec/truffle/parsing/fixtures/for/multi_assignment/with_preceding_splat_operator_and_following_variables.yaml @@ -143,21 +143,21 @@ ast: | attributes: flags = 0 frameDepth = 1 - frameSlot = 5 + frameSlot = 5 # c ] preNodes = [ WriteDeclarationVariableNode attributes: flags = 0 frameDepth = 1 - frameSlot = 3 + frameSlot = 3 # a ] restNode = WriteDeclarationVariableNode attributes: flags = 0 frameDepth = 1 - frameSlot = 4 + frameSlot = 4 # b rhsNode = ReadLocalVariableNode attributes: @@ -175,7 +175,7 @@ ast: | attributes: flags = 1 frameDepth = 1 - frameSlot = 6 + frameSlot = 6 # array children: valueNode = ArrayLiteralNode$UninitialisedArrayLiteralNode @@ -188,19 +188,19 @@ ast: | attributes: flags = 0 frameDepth = 1 - frameSlot = 3 + frameSlot = 3 # a type = FRAME_LOCAL ReadDeclarationVariableNode attributes: flags = 0 frameDepth = 1 - frameSlot = 4 + frameSlot = 4 # b type = FRAME_LOCAL ReadDeclarationVariableNode attributes: flags = 0 frameDepth = 1 - frameSlot = 5 + frameSlot = 5 # c type = FRAME_LOCAL ] ] diff --git a/spec/truffle/parsing/fixtures/for/multi_assignment/with_preceding_variables_and_implicit_rest.yaml b/spec/truffle/parsing/fixtures/for/multi_assignment/with_preceding_variables_and_implicit_rest.yaml index 65e06584296f..49191527e0c6 100644 --- a/spec/truffle/parsing/fixtures/for/multi_assignment/with_preceding_variables_and_implicit_rest.yaml +++ b/spec/truffle/parsing/fixtures/for/multi_assignment/with_preceding_variables_and_implicit_rest.yaml @@ -143,7 +143,7 @@ ast: | attributes: flags = 0 frameDepth = 1 - frameSlot = 3 + frameSlot = 3 # a ] rhsNode = ReadLocalVariableNode @@ -162,14 +162,14 @@ ast: | attributes: flags = 1 frameDepth = 1 - frameSlot = 4 + frameSlot = 4 # b children: valueNode = ReadDeclarationVariableNode attributes: flags = 0 frameDepth = 1 - frameSlot = 3 + frameSlot = 3 # a type = FRAME_LOCAL ] receiver = diff --git a/spec/truffle/parsing/fixtures/for/multi_assignment/with_preceding_variables_and_splat_operator.yaml b/spec/truffle/parsing/fixtures/for/multi_assignment/with_preceding_variables_and_splat_operator.yaml index 4347455574aa..78a83fb2cd28 100644 --- a/spec/truffle/parsing/fixtures/for/multi_assignment/with_preceding_variables_and_splat_operator.yaml +++ b/spec/truffle/parsing/fixtures/for/multi_assignment/with_preceding_variables_and_splat_operator.yaml @@ -143,19 +143,19 @@ ast: | attributes: flags = 0 frameDepth = 1 - frameSlot = 3 + frameSlot = 3 # a WriteDeclarationVariableNode attributes: flags = 0 frameDepth = 1 - frameSlot = 4 + frameSlot = 4 # b ] restNode = WriteDeclarationVariableNode attributes: flags = 0 frameDepth = 1 - frameSlot = 5 + frameSlot = 5 # c rhsNode = ReadLocalVariableNode attributes: @@ -173,7 +173,7 @@ ast: | attributes: flags = 1 frameDepth = 1 - frameSlot = 6 + frameSlot = 6 # array children: valueNode = ArrayLiteralNode$UninitialisedArrayLiteralNode @@ -186,19 +186,19 @@ ast: | attributes: flags = 0 frameDepth = 1 - frameSlot = 3 + frameSlot = 3 # a type = FRAME_LOCAL ReadDeclarationVariableNode attributes: flags = 0 frameDepth = 1 - frameSlot = 4 + frameSlot = 4 # b type = FRAME_LOCAL ReadDeclarationVariableNode attributes: flags = 0 frameDepth = 1 - frameSlot = 5 + frameSlot = 5 # c type = FRAME_LOCAL ] ] diff --git a/spec/truffle/parsing/fixtures/for/multi_assignment/with_splat_operator_and_following_variables.yaml b/spec/truffle/parsing/fixtures/for/multi_assignment/with_splat_operator_and_following_variables.yaml index d9b45f67052f..54b730e545e5 100644 --- a/spec/truffle/parsing/fixtures/for/multi_assignment/with_splat_operator_and_following_variables.yaml +++ b/spec/truffle/parsing/fixtures/for/multi_assignment/with_splat_operator_and_following_variables.yaml @@ -143,19 +143,19 @@ ast: | attributes: flags = 0 frameDepth = 1 - frameSlot = 4 + frameSlot = 4 # b WriteDeclarationVariableNode attributes: flags = 0 frameDepth = 1 - frameSlot = 5 + frameSlot = 5 # c ] restNode = WriteDeclarationVariableNode attributes: flags = 0 frameDepth = 1 - frameSlot = 3 + frameSlot = 3 # a rhsNode = ReadLocalVariableNode attributes: @@ -173,7 +173,7 @@ ast: | attributes: flags = 1 frameDepth = 1 - frameSlot = 6 + frameSlot = 6 # array children: valueNode = ArrayLiteralNode$UninitialisedArrayLiteralNode @@ -186,19 +186,19 @@ ast: | attributes: flags = 0 frameDepth = 1 - frameSlot = 3 + frameSlot = 3 # a type = FRAME_LOCAL ReadDeclarationVariableNode attributes: flags = 0 frameDepth = 1 - frameSlot = 4 + frameSlot = 4 # b type = FRAME_LOCAL ReadDeclarationVariableNode attributes: flags = 0 frameDepth = 1 - frameSlot = 5 + frameSlot = 5 # c type = FRAME_LOCAL ] ] diff --git a/spec/truffle/parsing/fixtures/for/with_attribute_assignment.yaml b/spec/truffle/parsing/fixtures/for/with_attribute_assignment.yaml index 672f7ae94d58..47997e7a7651 100644 --- a/spec/truffle/parsing/fixtures/for/with_attribute_assignment.yaml +++ b/spec/truffle/parsing/fixtures/for/with_attribute_assignment.yaml @@ -180,7 +180,7 @@ ast: | attributes: flags = 1 frameDepth = 1 - frameSlot = 3 + frameSlot = 3 # b children: valueNode = RubyCallNode diff --git a/spec/truffle/parsing/fixtures/for/with_class_variable.yaml b/spec/truffle/parsing/fixtures/for/with_class_variable.yaml index b8dc2a63f473..8fb8fb2ae388 100644 --- a/spec/truffle/parsing/fixtures/for/with_class_variable.yaml +++ b/spec/truffle/parsing/fixtures/for/with_class_variable.yaml @@ -158,7 +158,7 @@ ast: | attributes: flags = 1 frameDepth = 1 - frameSlot = 3 + frameSlot = 3 # b children: valueNode = ReadClassVariableNode diff --git a/spec/truffle/parsing/fixtures/for/with_constant.yaml b/spec/truffle/parsing/fixtures/for/with_constant.yaml index f640f2332767..84cbefd4a23d 100644 --- a/spec/truffle/parsing/fixtures/for/with_constant.yaml +++ b/spec/truffle/parsing/fixtures/for/with_constant.yaml @@ -154,7 +154,7 @@ ast: | attributes: flags = 1 frameDepth = 1 - frameSlot = 3 + frameSlot = 3 # b children: valueNode = ReadConstantWithLexicalScopeNode diff --git a/spec/truffle/parsing/fixtures/for/with_fully_qualified_constant.yaml b/spec/truffle/parsing/fixtures/for/with_fully_qualified_constant.yaml index 42250ce984e4..ece273a1cce1 100644 --- a/spec/truffle/parsing/fixtures/for/with_fully_qualified_constant.yaml +++ b/spec/truffle/parsing/fixtures/for/with_fully_qualified_constant.yaml @@ -163,7 +163,7 @@ ast: | attributes: flags = 1 frameDepth = 1 - frameSlot = 3 + frameSlot = 3 # b children: valueNode = ReadConstantNode diff --git a/spec/truffle/parsing/fixtures/for/with_global_variable.yaml b/spec/truffle/parsing/fixtures/for/with_global_variable.yaml index 7d189a200fbd..22d376e46b00 100644 --- a/spec/truffle/parsing/fixtures/for/with_global_variable.yaml +++ b/spec/truffle/parsing/fixtures/for/with_global_variable.yaml @@ -154,7 +154,7 @@ ast: | attributes: flags = 1 frameDepth = 1 - frameSlot = 3 + frameSlot = 3 # b children: valueNode = ReadGlobalVariableNodeGen diff --git a/spec/truffle/parsing/fixtures/for/with_instance_variable.yaml b/spec/truffle/parsing/fixtures/for/with_instance_variable.yaml index bb34d028c53c..d326df592f48 100644 --- a/spec/truffle/parsing/fixtures/for/with_instance_variable.yaml +++ b/spec/truffle/parsing/fixtures/for/with_instance_variable.yaml @@ -154,7 +154,7 @@ ast: | attributes: flags = 1 frameDepth = 1 - frameSlot = 3 + frameSlot = 3 # b children: valueNode = ReadInstanceVariableNode diff --git a/spec/truffle/parsing/fixtures/for/with_local_variable.yaml b/spec/truffle/parsing/fixtures/for/with_local_variable.yaml index f72303e3e986..d1b5214bb4e8 100644 --- a/spec/truffle/parsing/fixtures/for/with_local_variable.yaml +++ b/spec/truffle/parsing/fixtures/for/with_local_variable.yaml @@ -138,7 +138,7 @@ ast: | attributes: flags = 0 frameDepth = 1 - frameSlot = 3 + frameSlot = 3 # a children: valueNode = ReadLocalVariableNode @@ -150,14 +150,14 @@ ast: | attributes: flags = 1 frameDepth = 1 - frameSlot = 4 + frameSlot = 4 # b children: valueNode = ReadDeclarationVariableNode attributes: flags = 0 frameDepth = 1 - frameSlot = 3 + frameSlot = 3 # a type = FRAME_LOCAL ] receiver = diff --git a/spec/truffle/parsing/fixtures/for/with_reference_assignment.yaml b/spec/truffle/parsing/fixtures/for/with_reference_assignment.yaml index 442c364541f5..95f2bfb60fd8 100644 --- a/spec/truffle/parsing/fixtures/for/with_reference_assignment.yaml +++ b/spec/truffle/parsing/fixtures/for/with_reference_assignment.yaml @@ -175,7 +175,7 @@ ast: | attributes: flags = 1 frameDepth = 1 - frameSlot = 3 + frameSlot = 3 # b children: valueNode = InlinedIndexGetNodeGen diff --git a/spec/truffle/parsing/fixtures/for/with_reference_assignment_and_multiple_explicit_arguments.yaml b/spec/truffle/parsing/fixtures/for/with_reference_assignment_and_multiple_explicit_arguments.yaml index 707ab3fd223e..f1a8cdecbe8a 100644 --- a/spec/truffle/parsing/fixtures/for/with_reference_assignment_and_multiple_explicit_arguments.yaml +++ b/spec/truffle/parsing/fixtures/for/with_reference_assignment_and_multiple_explicit_arguments.yaml @@ -188,7 +188,7 @@ ast: | attributes: flags = 1 frameDepth = 1 - frameSlot = 3 + frameSlot = 3 # b children: valueNode = RubyCallNode diff --git a/spec/truffle/parsing/fixtures/local_variables/in_block_defined_in_outer_scope/reading.yaml b/spec/truffle/parsing/fixtures/local_variables/in_block_defined_in_outer_scope/reading.yaml index 8968059984be..476a9ff38421 100644 --- a/spec/truffle/parsing/fixtures/local_variables/in_block_defined_in_outer_scope/reading.yaml +++ b/spec/truffle/parsing/fixtures/local_variables/in_block_defined_in_outer_scope/reading.yaml @@ -57,6 +57,6 @@ ast: | attributes: flags = 1 frameDepth = 1 - frameSlot = 2 + frameSlot = 2 # foo type = FRAME_LOCAL ] \ No newline at end of file diff --git a/spec/truffle/parsing/fixtures/local_variables/in_block_defined_in_outer_scope/writing.yaml b/spec/truffle/parsing/fixtures/local_variables/in_block_defined_in_outer_scope/writing.yaml index 79132efffe5a..f65fbf652a63 100644 --- a/spec/truffle/parsing/fixtures/local_variables/in_block_defined_in_outer_scope/writing.yaml +++ b/spec/truffle/parsing/fixtures/local_variables/in_block_defined_in_outer_scope/writing.yaml @@ -62,7 +62,7 @@ ast: | attributes: flags = 1 frameDepth = 1 - frameSlot = 2 + frameSlot = 2 # foo children: valueNode = IntegerFixnumLiteralNode diff --git a/spec/truffle/parsing/fixtures/rescue/backtrace_optimization/enabled/when_local_variable_defined_in_outer_scope.yaml b/spec/truffle/parsing/fixtures/rescue/backtrace_optimization/enabled/when_local_variable_defined_in_outer_scope.yaml index 6e771fcaad5a..152d238c3075 100644 --- a/spec/truffle/parsing/fixtures/rescue/backtrace_optimization/enabled/when_local_variable_defined_in_outer_scope.yaml +++ b/spec/truffle/parsing/fixtures/rescue/backtrace_optimization/enabled/when_local_variable_defined_in_outer_scope.yaml @@ -73,7 +73,7 @@ ast: | attributes: flags = 1 frameDepth = 1 - frameSlot = 2 + frameSlot = 2 # bar type = FRAME_LOCAL ] tryPart = diff --git a/spec/truffle/parsing/fixtures/rescue/modifier/backtrace_optimization/enabled/when_local_variable_defined_in_outer_scope.yaml b/spec/truffle/parsing/fixtures/rescue/modifier/backtrace_optimization/enabled/when_local_variable_defined_in_outer_scope.yaml index 8132dbe47098..3b9bba84266e 100644 --- a/spec/truffle/parsing/fixtures/rescue/modifier/backtrace_optimization/enabled/when_local_variable_defined_in_outer_scope.yaml +++ b/spec/truffle/parsing/fixtures/rescue/modifier/backtrace_optimization/enabled/when_local_variable_defined_in_outer_scope.yaml @@ -71,7 +71,7 @@ ast: | attributes: flags = 0 frameDepth = 1 - frameSlot = 2 + frameSlot = 2 # bar type = FRAME_LOCAL ] tryPart = diff --git a/src/main/java/org/truffleruby/debug/TruffleASTPrinter.java b/src/main/java/org/truffleruby/debug/TruffleASTPrinter.java index aa351f8194ad..94416a481498 100644 --- a/src/main/java/org/truffleruby/debug/TruffleASTPrinter.java +++ b/src/main/java/org/truffleruby/debug/TruffleASTPrinter.java @@ -19,6 +19,7 @@ import java.util.TreeSet; import java.util.regex.Matcher; +import com.oracle.truffle.api.frame.FrameDescriptor; import com.oracle.truffle.api.profiles.Profile; import com.oracle.truffle.api.source.SourceSection; import org.graalvm.collections.Pair; @@ -28,8 +29,10 @@ import org.truffleruby.language.RubyRootNode; import org.truffleruby.language.control.BreakID; import org.truffleruby.language.control.ReturnID; +import org.truffleruby.language.locals.ReadDeclarationVariableNode; import org.truffleruby.language.locals.ReadFrameSlotNode; import org.truffleruby.language.locals.ReadLocalVariableNode; +import org.truffleruby.language.locals.WriteDeclarationVariableNode; import org.truffleruby.language.locals.WriteFrameSlotNode; import org.truffleruby.language.locals.WriteLocalVariableNode; import org.truffleruby.language.methods.CachedLazyCallTargetSupplier; @@ -39,6 +42,7 @@ import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.nodes.NodeUtil; import com.oracle.truffle.api.nodes.RootNode; +import org.truffleruby.parser.BlockDescriptorInfo; public abstract class TruffleASTPrinter { @@ -153,27 +157,49 @@ private static List> getNodeAttributes(Node node) { // map frame slots to local variable names private static Map getNodeAttributeAnnotations(Node node) { final int frameSlot; + final int frameDepth; // ignore WriteDeclarationVariableNode and ReadDeclarationVariableNode // because they access local variable declared in an outer scope, and // it cannot be accessed using the parents chain if (node instanceof WriteLocalVariableNode writeLocalVariableNodeNode) { frameSlot = writeLocalVariableNodeNode.getFrameSlot(); + frameDepth = 0; } else if (node instanceof WriteFrameSlotNode writeFrameSlotNode) { frameSlot = writeFrameSlotNode.getFrameSlot(); + frameDepth = 0; // actually we don't know the depth, but usually it's 0 + } else if (node instanceof WriteDeclarationVariableNode writeDeclarationVariableNode) { + frameSlot = writeDeclarationVariableNode.getFrameSlot(); + frameDepth = writeDeclarationVariableNode.getFrameDepth(); } else if (node instanceof ReadLocalVariableNode readLocalVariableNode) { frameSlot = readLocalVariableNode.getFrameSlot(); + frameDepth = 0; } else if (node instanceof ReadFrameSlotNode readFrameSlotNode) { frameSlot = readFrameSlotNode.getFrameSlot(); + frameDepth = 0; // actually we don't know the depth, but usually it's 0 + } else if (node instanceof ReadDeclarationVariableNode readDeclarationVariableNode) { + frameSlot = readDeclarationVariableNode.getFrameSlot(); + frameDepth = readDeclarationVariableNode.getFrameDepth(); } else { return Collections.emptyMap(); } - final var rootNode = node.getRootNode(); - final var frameDescriptor = rootNode.getFrameDescriptor(); - final String variableName = frameDescriptor.getSlotName(frameSlot).toString(); + FrameDescriptor declarationFrameDescriptor; + RootNode rootNode = node.getRootNode(); + FrameDescriptor frameDescriptor = rootNode.getFrameDescriptor(); + + if (frameDepth > 0) { + // local variable might be declared in some outer scope + declarationFrameDescriptor = BlockDescriptorInfo.getDeclarationFrameDescriptor(frameDescriptor, frameDepth); + } else { + declarationFrameDescriptor = frameDescriptor; + } + + Object slotName = declarationFrameDescriptor.getSlotName(frameSlot); + assert slotName != null; // all the mentioned above classes use the same field name - "frameSlot", so just hardcode it + final String variableName = slotName.toString(); return Collections.singletonMap("frameSlot", variableName); } diff --git a/src/main/java/org/truffleruby/language/locals/WriteDeclarationVariableNode.java b/src/main/java/org/truffleruby/language/locals/WriteDeclarationVariableNode.java index dd7111327303..cfdbe3806487 100644 --- a/src/main/java/org/truffleruby/language/locals/WriteDeclarationVariableNode.java +++ b/src/main/java/org/truffleruby/language/locals/WriteDeclarationVariableNode.java @@ -29,6 +29,10 @@ public WriteDeclarationVariableNode(int frameSlot, int frameDepth, RubyNode valu this.frameDepth = frameDepth; } + public int getFrameDepth() { + return frameDepth; + } + @Override public Object execute(VirtualFrame frame) { final Object value = valueNode.execute(frame);