Skip to content

Commit f054b32

Browse files
committed
[GR-19699] Fix Kernel#load(path, wrap=true) and pass all new specs.
PullRequest: truffleruby/1158
2 parents b3b30eb + 743e0c2 commit f054b32

File tree

4 files changed

+59
-20
lines changed

4 files changed

+59
-20
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ Bug fixes:
2727
* Keep the Truffle working directory in sync with the native working directory.
2828
* Rename `to_native` to `polyglot_to_native` to match `polyglot_pointer?` and `polyglot_address` methods.
2929
* Fixed missing partial evaluation boundary in `Array#{sort,sort!}` (#1727).
30+
* Fixed the class of `self` and the wrapping `Module` for `Kernel#load(path, wrap=true)` (#1739).
3031

3132
Compatibility:
3233

spec/ruby/core/kernel/shared/load.rb

+35-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
main = self
2+
13
describe :kernel_load, shared: true do
24
before :each do
35
CodeLoadingSpecs.spec_setup
@@ -95,13 +97,45 @@
9597
@object.load(path, true)
9698

9799
Object.const_defined?(:LoadSpecWrap).should be_false
100+
101+
wrap_module = ScratchPad.recorded[1]
102+
wrap_module.should be_an_instance_of(Module)
98103
end
99104

100105
it "allows referencing outside namespaces" do
101106
path = File.expand_path "wrap_fixture.rb", CODE_LOADING_DIR
102107
@object.load(path, true)
103108

104-
ScratchPad.recorded.first.should be_an_instance_of(Class)
109+
ScratchPad.recorded[0].should equal(String)
110+
end
111+
112+
it "sets self as a copy of the top-level main" do
113+
path = File.expand_path "wrap_fixture.rb", CODE_LOADING_DIR
114+
@object.load(path, true)
115+
116+
top_level = ScratchPad.recorded[2]
117+
top_level.to_s.should == "main"
118+
top_level.method(:to_s).owner.should == top_level.singleton_class
119+
top_level.should_not equal(main)
120+
top_level.should be_an_instance_of(Object)
121+
end
122+
123+
it "includes modules included in main's singleton class in self's class" do
124+
mod = Module.new
125+
main.extend(mod)
126+
127+
main_ancestors = main.singleton_class.ancestors[1..-1]
128+
main_ancestors.first.should == mod
129+
130+
path = File.expand_path "wrap_fixture.rb", CODE_LOADING_DIR
131+
@object.load(path, true)
132+
133+
top_level = ScratchPad.recorded[2]
134+
top_level_ancestors = top_level.singleton_class.ancestors[-main_ancestors.size..-1]
135+
top_level_ancestors.should == main_ancestors
136+
137+
wrap_module = ScratchPad.recorded[1]
138+
top_level.singleton_class.ancestors.should == [top_level.singleton_class, wrap_module, *main_ancestors]
105139
end
106140

107141
describe "with top-level methods" do
+7-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
11
class LoadSpecWrap
2-
ScratchPad << self
2+
ScratchPad << String
33
end
4+
5+
def load_wrap_specs_top_level_method
6+
end
7+
ScratchPad << method(:load_wrap_specs_top_level_method).owner
8+
9+
ScratchPad << self

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

+16-18
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,18 @@
1212
import java.io.IOException;
1313

1414
import org.truffleruby.Layouts;
15-
import org.truffleruby.builtins.CoreModule;
1615
import org.truffleruby.builtins.CoreMethod;
1716
import org.truffleruby.builtins.CoreMethodArrayArgumentsNode;
1817
import org.truffleruby.builtins.CoreMethodNode;
18+
import org.truffleruby.builtins.CoreModule;
1919
import org.truffleruby.builtins.Primitive;
2020
import org.truffleruby.core.cast.BooleanCastWithDefaultNodeGen;
21-
import org.truffleruby.core.klass.ClassNodes;
21+
import org.truffleruby.core.module.ModuleNodes;
2222
import org.truffleruby.core.string.StringOperations;
2323
import org.truffleruby.language.RubyNode;
2424
import org.truffleruby.language.RubyRootNode;
2525
import org.truffleruby.language.control.RaiseException;
26+
import org.truffleruby.language.dispatch.CallDispatchHeadNode;
2627
import org.truffleruby.language.globals.ReadSimpleGlobalVariableNode;
2728
import org.truffleruby.language.globals.WriteSimpleGlobalVariableNode;
2829
import org.truffleruby.language.loader.CodeLoader;
@@ -80,40 +81,37 @@ protected boolean load(DynamicObject file, boolean wrap,
8081
throw new RaiseException(getContext(), coreExceptions().loadErrorCannotLoad(feature, this));
8182
}
8283

83-
final DynamicObject wrapClass;
84-
84+
final DynamicObject wrapModule;
8585
if (wrap) {
86-
wrapClass = ClassNodes.createInitializedRubyClass(
87-
getContext(),
88-
null,
89-
null,
90-
getContext().getCoreLibrary().getObjectClass(),
91-
null);
86+
wrapModule = ModuleNodes
87+
.createModule(getContext(), null, coreLibrary().getModuleClass(), null, null, this);
9288
} else {
93-
wrapClass = null;
89+
wrapModule = null;
9490
}
9591

9692
final RubyRootNode rootNode = getContext()
9793
.getCodeLoader()
98-
.parse(source, ParserContext.TOP_LEVEL, null, wrapClass, true, this);
94+
.parse(source, ParserContext.TOP_LEVEL, null, wrapModule, true, this);
9995

96+
final DynamicObject mainObject = getContext().getCoreLibrary().getMainObject();
10097
final DeclarationContext declarationContext;
101-
final DynamicObject mainObject;
98+
final Object self;
10299

103-
if (wrapClass == null) {
100+
if (wrapModule == null) {
104101
declarationContext = DeclarationContext.topLevel(getContext());
105-
mainObject = getContext().getCoreLibrary().getMainObject();
102+
self = mainObject;
106103
} else {
107-
declarationContext = DeclarationContext.topLevel(wrapClass);
108-
mainObject = Layouts.CLASS.getInstanceFactory(wrapClass).newInstance();
104+
declarationContext = DeclarationContext.topLevel(wrapModule);
105+
self = CallDispatchHeadNode.getUncached().call(mainObject, "clone");
106+
CallDispatchHeadNode.getUncached().call(self, "extend", wrapModule);
109107
}
110108

111109
final CodeLoader.DeferredCall deferredCall = getContext().getCodeLoader().prepareExecute(
112110
ParserContext.TOP_LEVEL,
113111
declarationContext,
114112
rootNode,
115113
null,
116-
mainObject);
114+
self);
117115

118116
deferredCall.call(callNode);
119117

0 commit comments

Comments
 (0)