Skip to content

Commit 61b4cf7

Browse files
committed
Only allow to use private Primitives in TruffleRuby core library
* Stop testing PE in Docker tests, the result was already ignored for a while.
1 parent 46f3f2b commit 61b4cf7

File tree

18 files changed

+88
-23
lines changed

18 files changed

+88
-23
lines changed

spec/truffleruby.mspec

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ load "#{__dir__}/ruby/default.mspec"
88
# Don't run ruby/spec as root on TruffleRuby
99
raise 'ruby/spec is not designed to be run as root on TruffleRuby' if Process.uid == 0
1010

11+
ENV['TRUFFLERUBY_ALLOW_PRIVATE_PRIMITIVES_IN'] = "#{__dir__}/truffle/"
12+
1113
class MSpecScript
1214
def self.windows?
1315
ENV.key?('WINDIR') || ENV.key?('windir')

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

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,8 @@ public abstract static class RubySourceOptions {
208208
* {@link TranslatorEnvironment#newFrameDescriptorBuilderForBlock(BlockDescriptorInfo)}. */
209209
public static final FrameDescriptor EMPTY_FRAME_DESCRIPTOR = new FrameDescriptor(nil);
210210

211+
public static final String INTERNAL_CORE_PREFIX = "<internal:core> ";
212+
211213
/** Global cache of call targets that {@code RBSprintfCompiler.compile} returns */
212214
public static final Map<TStringWithEncoding, RootCallTarget> sprintfCompilerCallTargets = new ConcurrentHashMap<>();
213215

@@ -284,6 +286,7 @@ private RubyThread getOrCreateForeignThread(RubyContext context, Thread thread)
284286
@CompilationFinal public LanguageOptions options;
285287
@CompilationFinal private String rubyHome;
286288
@CompilationFinal public String cextPath;
289+
public String[] allowPrivatePrimitivesPrefixes;
287290

288291
private TruffleFile rubyHomeTruffleFile;
289292

@@ -777,13 +780,36 @@ private void setRubyHome(TruffleFile home) {
777780
rubyHomeTruffleFile = home;
778781
rubyHome = home.getPath();
779782
cextPath = rubyHome + "/lib/truffle/truffle/cext_ruby.rb";
783+
784+
String allowIn = System.getenv("TRUFFLERUBY_ALLOW_PRIVATE_PRIMITIVES_IN");
785+
if (allowIn != null) {
786+
if (!allowIn.endsWith("/spec/truffle/") && !allowIn.endsWith("/test/truffle/compiler/") &&
787+
!allowIn.endsWith("/bench/metrics/")) {
788+
throw CompilerDirectives
789+
.shouldNotReachHere("Invalid value for TRUFFLERUBY_ALLOW_PRIMITIVES_IN: " + allowIn);
790+
}
791+
792+
allowPrivatePrimitivesPrefixes = new String[]{
793+
rubyHome + "/lib/truffle/",
794+
rubyHome + "/lib/patches/",
795+
rubyHome + "/lib/mri/",
796+
allowIn,
797+
};
798+
} else {
799+
allowPrivatePrimitivesPrefixes = new String[]{
800+
rubyHome + "/lib/truffle/",
801+
rubyHome + "/lib/patches/",
802+
rubyHome + "/lib/mri/",
803+
};
804+
}
780805
}
781806

782807
private void resetRubyHome() {
783808
assert Thread.holdsLock(this);
784809
rubyHomeTruffleFile = null;
785810
rubyHome = null;
786811
cextPath = null;
812+
allowPrivatePrimitivesPrefixes = null;
787813
}
788814

789815
private TruffleFile findRubyHome(Env env) {
@@ -954,7 +980,7 @@ public static String getPath(Source source) {
954980
public String getSourcePath(Source source) {
955981
final String path = getPath(source);
956982
if (path.startsWith(coreLoadPath)) {
957-
return "<internal:core> " + path.substring(coreLoadPath.length() + 1);
983+
return INTERNAL_CORE_PREFIX + path.substring(coreLoadPath.length() + 1);
958984
} else {
959985
return path;
960986
}

src/main/java/org/truffleruby/builtins/PrimitiveManager.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public PrimitiveNodeConstructor getPrimitive(String name) {
4343
}
4444
}
4545

46-
throw new Error("Primitive :" + name + " not found");
46+
throw new Error("Primitive." + name + " not found");
4747
}
4848

4949
public void addLazyPrimitive(String primitive, String nodeFactoryClass) {

src/main/java/org/truffleruby/builtins/PrimitiveNodeConstructor.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ public PrimitiveNodeConstructor(Primitive annotation, NodeFactory<? extends Ruby
2828
this.factory = factory;
2929
}
3030

31+
public boolean isPublic() {
32+
return annotation.isPublic();
33+
}
34+
3135
public int getPrimitiveArity() {
3236
return factory.getExecutionSignature().size();
3337
}

src/main/java/org/truffleruby/core/support/TypeNodes.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ RubyClass metaClass(Object object,
102102
}
103103
}
104104

105-
@Primitive(name = "singleton_class")
105+
@Primitive(name = "singleton_class", isPublic = true)
106106
public abstract static class SingletonClassPrimitiveNode extends PrimitiveArrayArgumentsNode {
107107
@Specialization
108108
RubyClass singletonClass(Object object,
@@ -201,7 +201,7 @@ boolean doFallback(Object value) {
201201

202202
}
203203

204-
@Primitive(name = "nil?")
204+
@Primitive(name = "nil?", isPublic = true)
205205
public abstract static class IsNilNode extends PrimitiveArrayArgumentsNode {
206206
@Specialization
207207
boolean isNil(Object value) {

src/main/java/org/truffleruby/extra/TruffleGraalNodes.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ static Object bailout(Object message,
202202
}
203203
}
204204

205-
@Primitive(name = "blackhole")
205+
@Primitive(name = "blackhole", isPublic = true)
206206
public abstract static class BlackholeNode extends PrimitiveArrayArgumentsNode {
207207

208208
@Specialization

src/main/java/org/truffleruby/parser/ParseEnvironment.java

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ public final class ParseEnvironment {
3333
public final Node currentNode;
3434

3535
private final boolean inCore;
36+
private final boolean canUsePrivatePrimitives;
3637

3738
// Set once after parsing and before translating
3839
public Boolean allowTruffleRubyPrimitives = null;
@@ -48,7 +49,20 @@ public ParseEnvironment(
4849
this.parserContext = parserContext;
4950
this.currentNode = currentNode;
5051

51-
this.inCore = RubyLanguage.getPath(source).startsWith(language.corePath);
52+
String path = language.getSourcePath(source);
53+
this.inCore = path.startsWith(RubyLanguage.INTERNAL_CORE_PREFIX);
54+
55+
boolean canUsePrivatePrimitives = false;
56+
if (!inCore) {
57+
for (String prefix : language.allowPrivatePrimitivesPrefixes) {
58+
if (path.startsWith(prefix)) {
59+
canUsePrivatePrimitives = true;
60+
break;
61+
}
62+
}
63+
}
64+
this.canUsePrivatePrimitives = inCore || canUsePrivatePrimitives;
65+
5266
this.coverageEnabled = rubySource.getSource().getOptions(language).get(RubySourceOptions.Coverage);
5367
}
5468

@@ -61,6 +75,10 @@ public boolean canUsePrimitives() {
6175
return inCore() || allowTruffleRubyPrimitives;
6276
}
6377

78+
public boolean canUsePrivatePrimitives() {
79+
return canUsePrivatePrimitives;
80+
}
81+
6482
/** Returns false if the AST is shared */
6583
public boolean isCoverageEnabled() {
6684
return coverageEnabled;

src/main/java/org/truffleruby/parser/YARPTranslator.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -677,6 +677,17 @@ public RubyNode visitCallNode(Nodes.CallNode node) {
677677

678678
final PrimitiveNodeConstructor constructor = language.primitiveManager.getPrimitive(methodName);
679679

680+
if (!constructor.isPublic() && !parseEnvironment.canUsePrivatePrimitives()) {
681+
final RubyContext context = RubyLanguage.getCurrentContext();
682+
throw new RaiseException(
683+
context,
684+
context.getCoreExceptions().syntaxError(
685+
"Primitive." + methodName +
686+
" is not public and cannot be used outside the TruffleRuby core library",
687+
currentNode,
688+
getSourceSection(node)));
689+
}
690+
680691
if (translatedArguments.length != constructor.getPrimitiveArity()) {
681692
throw new Error(
682693
"Incorrect number of arguments (expected " + constructor.getPrimitiveArity() + ") at " +

test/truffle/compiler/can-we-fold-yet.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22

33
source test/truffle/common.sh.inc
44

5-
jt ruby --experimental-options --compiler.IterativePartialEscape --engine.MultiTier=false test/truffle/compiler/can-we-fold-yet/can-we-fold-yet.rb < test/truffle/compiler/can-we-fold-yet/input.txt > actual.txt
5+
export TRUFFLERUBY_ALLOW_PRIVATE_PRIMITIVES_IN="$truffle/compiler/"
6+
jt ruby --experimental-options --compiler.IterativePartialEscape --engine.MultiTier=false "$PWD/test/truffle/compiler/can-we-fold-yet/can-we-fold-yet.rb" < test/truffle/compiler/can-we-fold-yet/input.txt > actual.txt
67

78
if ! cmp test/truffle/compiler/can-we-fold-yet/expected.txt actual.txt
89
then

test/truffle/compiler/optional-assignment-lazy-load.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@
22

33
source test/truffle/common.sh.inc
44

5-
jt ruby --check-compilation --experimental-options --engine.MultiTier=false test/truffle/compiler/optional-assignment-lazy-load/optional-assignment-lazy-load.rb
5+
export TRUFFLERUBY_ALLOW_PRIVATE_PRIMITIVES_IN="$truffle/compiler/"
6+
jt ruby --check-compilation --experimental-options --engine.MultiTier=false "$PWD/test/truffle/compiler/optional-assignment-lazy-load/optional-assignment-lazy-load.rb"

0 commit comments

Comments
 (0)