Skip to content

Commit 710a1a2

Browse files
committed
[GR-32501] Correctly compute the LexicalScope for Module#module_eval when isDynamicConstantLookup()
PullRequest: truffleruby/2811
2 parents baabd5c + b2b396a commit 710a1a2

File tree

16 files changed

+63
-66
lines changed

16 files changed

+63
-66
lines changed

spec/truffle/methods_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
requires = %w[digest socket]
4040
requires_code = requires.map { |lib| "require #{lib.inspect}" }.join("\n")
4141

42-
guard -> { !defined?(SlowSpecsTagger) } do
42+
guard -> { !defined?(SKIP_SLOW_SPECS) } do
4343
if RUBY_ENGINE == "ruby"
4444
modules.each do |mod|
4545
file = File.expand_path("../methods/#{mod}.txt", __FILE__)

spec/truffleruby.mspec

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,8 @@ if MSpecScript.child_process?
154154
end
155155

156156
if i = ARGV.index('slow') and ARGV[i-1] == '--excl-tag' and MSpecScript.child_process?
157+
SKIP_SLOW_SPECS = true
158+
157159
require 'mspec'
158160
require 'timeout'
159161
require 'objspace'

src/main/java/org/truffleruby/RubyLanguage.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@
8888
import org.truffleruby.extra.RubyConcurrentMap;
8989
import org.truffleruby.extra.ffi.RubyPointer;
9090
import org.truffleruby.core.string.ImmutableRubyString;
91+
import org.truffleruby.language.LexicalScope;
9192
import org.truffleruby.language.NotProvided;
9293
import org.truffleruby.language.RubyDynamicObject;
9394
import org.truffleruby.language.RubyEvalInteractiveRootNode;
@@ -465,11 +466,12 @@ protected RootCallTarget parse(ParsingRequest request) {
465466
final ParserContext parserContext = MIME_TYPE_MAIN_SCRIPT.equals(source.getMimeType())
466467
? ParserContext.TOP_LEVEL_FIRST
467468
: ParserContext.TOP_LEVEL;
469+
final LexicalScope lexicalScope = contextIfSingleContext.map(RubyContext::getRootLexicalScope).orElse(null);
468470
return RubyLanguage.getCurrentContext().getCodeLoader().parse(
469471
rubySource,
470472
parserContext,
471473
null,
472-
null,
474+
lexicalScope,
473475
true,
474476
parsingParameters.getCurrentNode());
475477
}

src/main/java/org/truffleruby/core/CoreLibrary.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -771,7 +771,8 @@ public void loadRubyCoreLibraryAndPostBoot() {
771771
ParserContext.TOP_LEVEL,
772772
DeclarationContext.topLevel(context),
773773
null,
774-
context.getCoreLibrary().mainObject);
774+
context.getCoreLibrary().mainObject,
775+
context.getRootLexicalScope());
775776

776777
TranslatorDriver.printParseTranslateExecuteMetric("before-execute", context, source);
777778
deferredCall.callWithoutCallNode();

src/main/java/org/truffleruby/core/basicobject/BasicObjectNodes.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
import org.truffleruby.core.rope.RopeOperations;
4141
import org.truffleruby.core.symbol.RubySymbol;
4242
import org.truffleruby.language.ImmutableRubyObject;
43+
import org.truffleruby.language.LexicalScope;
4344
import org.truffleruby.language.Nil;
4445
import org.truffleruby.language.NotProvided;
4546
import org.truffleruby.language.RubyDynamicObject;
@@ -392,12 +393,13 @@ private Object instanceEvalHelper(MaterializedFrame callerFrame, Object receiver
392393

393394
final RubySource source = EvalLoader
394395
.createEvalSource(getContext(), stringRope, "instance_eval", fileNameString, line, this);
396+
final LexicalScope lexicalScope = RubyArguments.getMethod(callerFrame).getLexicalScope();
395397

396398
final RootCallTarget callTarget = getContext().getCodeLoader().parse(
397399
source,
398400
ParserContext.EVAL,
399401
callerFrame,
400-
null,
402+
lexicalScope,
401403
true,
402404
this);
403405

@@ -411,7 +413,8 @@ private Object instanceEvalHelper(MaterializedFrame callerFrame, Object receiver
411413
ParserContext.EVAL,
412414
declarationContext,
413415
callerFrame,
414-
receiver);
416+
receiver,
417+
lexicalScope);
415418

416419
return deferredCall.call(callNode);
417420
}

src/main/java/org/truffleruby/core/kernel/KernelNodes.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@
9595
import org.truffleruby.interop.ToJavaStringNode;
9696
import org.truffleruby.core.string.ImmutableRubyString;
9797
import org.truffleruby.language.ImmutableRubyObject;
98+
import org.truffleruby.language.LexicalScope;
9899
import org.truffleruby.language.Nil;
99100
import org.truffleruby.language.NotProvided;
100101
import org.truffleruby.language.RubyBaseNode;
@@ -882,12 +883,14 @@ private CodeLoader.DeferredCall doEvalX(RubyContext context, Object self, Rope s
882883
if (assignsNewUserVariables(descriptor)) {
883884
binding.setFrame(frame);
884885
}
886+
final LexicalScope lexicalScope = RubyArguments.getMethod(frame).getLexicalScope();
885887
return context.getCodeLoader().prepareExecute(
886888
callTarget,
887889
ParserContext.EVAL,
888890
declarationContext,
889891
frame,
890-
self);
892+
self,
893+
lexicalScope);
891894
}
892895

893896
protected RootCallTarget parse(RubyContext context, Rope sourceText, MaterializedFrame parentFrame, Rope file,
@@ -897,9 +900,10 @@ protected RootCallTarget parse(RubyContext context, Rope sourceText, Materialize
897900
final String sourceFile = RopeOperations.decodeRope(file).intern();
898901
final RubySource source = EvalLoader
899902
.createEvalSource(context, sourceText, "eval", sourceFile, line, this);
903+
final LexicalScope lexicalScope = RubyArguments.getMethod(parentFrame).getLexicalScope();
900904
return context
901905
.getCodeLoader()
902-
.parse(source, ParserContext.EVAL, parentFrame, null, ownScopeForAssignments, this);
906+
.parse(source, ParserContext.EVAL, parentFrame, lexicalScope, ownScopeForAssignments, this);
903907
}
904908

905909
protected RootCallTarget compileSource(RubyContext context, Rope sourceText, MaterializedFrame parentFrame,

src/main/java/org/truffleruby/core/kernel/TruffleKernelNodes.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import org.truffleruby.core.rope.Rope;
3333
import org.truffleruby.core.symbol.RubySymbol;
3434
import org.truffleruby.language.FrameOrVariablesReadingNode;
35+
import org.truffleruby.language.LexicalScope;
3536
import org.truffleruby.language.Nil;
3637
import org.truffleruby.language.ReadOwnFrameAndVariablesNode;
3738
import org.truffleruby.language.RubyContextNode;
@@ -115,21 +116,24 @@ protected boolean load(Object file, boolean wrap,
115116
final RootCallTarget callTarget;
116117
final DeclarationContext declarationContext;
117118
final Object self;
119+
final LexicalScope lexicalScope;
118120
if (!wrap) {
121+
lexicalScope = getContext().getRootLexicalScope();
119122
callTarget = getContext().getCodeLoader().parseTopLevelWithCache(sourceRopePair, this);
120123

121124
declarationContext = DeclarationContext.topLevel(getContext());
122125
self = mainObject;
123126
} else {
124127
final RubyModule wrapModule = ModuleNodes
125128
.createModule(getContext(), null, coreLibrary().moduleClass, null, null, this);
129+
lexicalScope = new LexicalScope(getContext().getRootLexicalScope(), wrapModule);
126130
final RubySource rubySource = new RubySource(
127131
sourceRopePair.getLeft(),
128132
feature,
129133
sourceRopePair.getRight());
130134
callTarget = getContext()
131135
.getCodeLoader()
132-
.parse(rubySource, ParserContext.TOP_LEVEL, null, wrapModule, true, this);
136+
.parse(rubySource, ParserContext.TOP_LEVEL, null, lexicalScope, true, this);
133137

134138
declarationContext = DeclarationContext.topLevel(wrapModule);
135139
self = DispatchNode.getUncached().call(mainObject, "clone");
@@ -141,7 +145,8 @@ protected boolean load(Object file, boolean wrap,
141145
ParserContext.TOP_LEVEL,
142146
declarationContext,
143147
null,
144-
self);
148+
self,
149+
lexicalScope);
145150

146151
deferredCall.call(callNode);
147152

src/main/java/org/truffleruby/core/module/ModuleNodes.java

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -675,17 +675,8 @@ protected Object isAutoload(RubyModule module, String name, boolean inherit) {
675675
@CoreMethod(names = { "class_eval", "module_eval" }, optional = 3, lowerFixnum = 3, needsBlock = true)
676676
public abstract static class ClassEvalNode extends CoreMethodArrayArgumentsNode {
677677

678-
@Child private ToStrNode toStrNode;
679678
@Child private ReadCallerFrameNode readCallerFrameNode = ReadCallerFrameNode.create();
680679

681-
protected Object toStr(VirtualFrame frame, Object object) {
682-
if (toStrNode == null) {
683-
CompilerDirectives.transferToInterpreterAndInvalidate();
684-
toStrNode = insert(ToStrNode.create());
685-
}
686-
return toStrNode.execute(object);
687-
}
688-
689680
@Specialization(guards = { "libCode.isRubyString(code)" })
690681
protected Object classEval(
691682
VirtualFrame frame, RubyModule module, Object code, NotProvided file, NotProvided line, Nil block,
@@ -720,17 +711,19 @@ protected Object classEval(VirtualFrame frame, RubyModule module, Object code, O
720711
@Specialization(guards = "wasProvided(code)")
721712
protected Object classEval(
722713
VirtualFrame frame, RubyModule module, Object code, NotProvided file, NotProvided line, Nil block,
723-
@Cached IndirectCallNode callNode) {
724-
return classEvalSource(frame, module, toStr(frame, code), "(eval)", callNode);
714+
@Cached IndirectCallNode callNode,
715+
@Cached ToStrNode toStrNode) {
716+
return classEvalSource(frame, module, toStrNode.execute(code), "(eval)", callNode);
725717
}
726718

727719
@Specialization(guards = { "libCode.isRubyString(code)", "wasProvided(file)" })
728720
protected Object classEval(
729721
VirtualFrame frame, RubyModule module, Object code, Object file, NotProvided line, Nil block,
730722
@CachedLibrary(limit = "2") RubyStringLibrary stringLibrary,
731723
@Cached IndirectCallNode callNode,
732-
@CachedLibrary(limit = "2") RubyStringLibrary libCode) {
733-
final String javaString = stringLibrary.getJavaString(toStr(frame, file));
724+
@CachedLibrary(limit = "2") RubyStringLibrary libCode,
725+
@Cached ToStrNode toStrNode) {
726+
final String javaString = stringLibrary.getJavaString(toStrNode.execute(file));
734727
return classEvalSource(frame, module, code, javaString, callNode);
735728
}
736729

@@ -758,12 +751,15 @@ private CodeLoader.DeferredCall classEvalSourceInternal(RubyModule module, Objec
758751
file,
759752
line,
760753
this);
754+
final LexicalScope lexicalScope = new LexicalScope(
755+
RubyArguments.getMethod(callerFrame).getLexicalScope(),
756+
module);
761757

762758
final RootCallTarget callTarget = getContext().getCodeLoader().parse(
763759
source,
764760
ParserContext.MODULE,
765761
callerFrame,
766-
null,
762+
lexicalScope,
767763
true,
768764
this);
769765

@@ -775,7 +771,8 @@ private CodeLoader.DeferredCall classEvalSourceInternal(RubyModule module, Objec
775771
new FixedDefaultDefinee(module),
776772
DeclarationContext.NO_REFINEMENTS),
777773
callerFrame,
778-
module);
774+
module,
775+
lexicalScope);
779776
}
780777

781778
@Specialization

src/main/java/org/truffleruby/debug/DebugHelpers.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import com.oracle.truffle.api.RootCallTarget;
1313
import org.truffleruby.RubyContext;
1414
import org.truffleruby.RubyLanguage;
15+
import org.truffleruby.language.LexicalScope;
1516
import org.truffleruby.language.Nil;
1617
import org.truffleruby.language.RubyNode;
1718
import org.truffleruby.language.arguments.RubyArguments;
@@ -43,6 +44,7 @@ public static Object eval(RubyContext context, String code, Object... arguments)
4344

4445
final DeclarationContext declarationContext = RubyArguments.getDeclarationContext(currentFrame);
4546

47+
final LexicalScope lexicalScope = RubyArguments.getMethod(currentFrame).getLexicalScope();
4648
final Object[] packedArguments = RubyArguments.pack(
4749
null,
4850
null,
@@ -74,14 +76,15 @@ public static Object eval(RubyContext context, String code, Object... arguments)
7476

7577
final RootCallTarget callTarget = context
7678
.getCodeLoader()
77-
.parse(new RubySource(source, "debug-eval"), ParserContext.INLINE, evalFrame, null, true, null);
79+
.parse(new RubySource(source, "debug-eval"), ParserContext.INLINE, evalFrame, lexicalScope, true, null);
7880

7981
final CodeLoader.DeferredCall deferredCall = context.getCodeLoader().prepareExecute(
8082
callTarget,
8183
ParserContext.INLINE,
8284
declarationContext,
8385
evalFrame,
84-
RubyArguments.getSelf(evalFrame));
86+
RubyArguments.getSelf(evalFrame),
87+
lexicalScope);
8588

8689
return deferredCall.callWithoutCallNode();
8790
}

src/main/java/org/truffleruby/language/RubyInlineParsingRequestNode.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ public RubyInlineParsingRequestNode(
5151
ParserContext.INLINE,
5252
null,
5353
currentFrame,
54-
null,
54+
RubyArguments.getMethod(currentFrame).getLexicalScope(),
5555
false,
5656
null);
5757

0 commit comments

Comments
 (0)