Skip to content

Commit

Permalink
Showing 44 changed files with 233 additions and 957 deletions.
2 changes: 1 addition & 1 deletion .mvn/extensions.xml
Original file line number Diff line number Diff line change
@@ -3,6 +3,6 @@
<extension>
<groupId>io.takari.polyglot</groupId>
<artifactId>polyglot-ruby</artifactId>
<version>0.1.11</version>
<version>0.1.15</version>
</extension>
</extensions>
4 changes: 2 additions & 2 deletions lib/pom.rb
Original file line number Diff line number Diff line change
@@ -46,7 +46,7 @@ def initialize( name, version, default_spec = true )

extension 'org.torquebox.mojo:mavengem-wagon:0.2.0'

repository :id => :mavengems, :url => 'mavengem:http://rubygems.org'
repository :id => :mavengems, :url => 'mavengem:https://rubygems.org'

plugin( :clean,
:filesets => [ { :directory => '${basedir}/ruby/gems/shared/specifications/default',
@@ -67,7 +67,7 @@ def initialize( name, version, default_spec = true )
plugin :dependency,
:useRepositoryLayout => true,
:outputDirectory => 'ruby/stdlib',
:excludeGroupIds => 'rubygems', # TODO no hardcoded group-ids
:excludeGroupIds => 'rubygems',
:includeScope => :provided do
execute_goal 'copy-dependencies', :phase => 'generate-resources'
end
6 changes: 3 additions & 3 deletions lib/pom.xml
Original file line number Diff line number Diff line change
@@ -178,7 +178,7 @@ DO NOT MODIFIY - GENERATED CODE
<repositories>
<repository>
<id>mavengems</id>
<url>mavengem:http://rubygems.org</url>
<url>mavengem:https://rubygems.org</url>
</repository>
</repositories>
<build>
@@ -276,7 +276,7 @@ DO NOT MODIFIY - GENERATED CODE
<plugin>
<groupId>io.takari.polyglot</groupId>
<artifactId>polyglot-maven-plugin</artifactId>
<version>0.1.11</version>
<version>0.1.15</version>
<executions>
<execution>
<id>install_gems</id>
@@ -327,7 +327,7 @@ DO NOT MODIFIY - GENERATED CODE
<dependency>
<groupId>io.takari.polyglot</groupId>
<artifactId>polyglot-ruby</artifactId>
<version>0.1.11</version>
<version>0.1.15</version>
</dependency>
</dependencies>
</plugin>
33 changes: 15 additions & 18 deletions maven/jruby/src/it/runnable/Gemfile.lock
Original file line number Diff line number Diff line change
@@ -11,31 +11,31 @@ GEM
thread_safe (~> 0.3, >= 0.3.1)
diff-lcs (1.2.5)
equalizer (0.0.11)
ice_nine (0.11.1)
jar-dependencies (0.1.13)
ice_nine (0.11.2)
jar-dependencies (0.1.15)
jbundler (0.7.1)
bundler (~> 1.5)
jar-dependencies (~> 0.1.7)
maven-tools (~> 1.0.6)
ruby-maven (>= 3.1.1.0.6, < 3.1.2)
maven-tools (1.0.8)
maven-tools (1.0.13)
virtus (~> 1.0)
rake (10.4.2)
rspec (3.3.0)
rspec-core (~> 3.3.0)
rspec-expectations (~> 3.3.0)
rspec-mocks (~> 3.3.0)
rspec-core (3.3.1)
rspec-support (~> 3.3.0)
rspec-expectations (3.3.0)
rspec (3.4.0)
rspec-core (~> 3.4.0)
rspec-expectations (~> 3.4.0)
rspec-mocks (~> 3.4.0)
rspec-core (3.4.3)
rspec-support (~> 3.4.0)
rspec-expectations (3.4.0)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.3.0)
rspec-mocks (3.3.1)
rspec-support (~> 3.4.0)
rspec-mocks (3.4.1)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.3.0)
rspec-support (3.3.0)
rspec-support (~> 3.4.0)
rspec-support (3.4.1)
ruby-maven (3.1.1.0.11)
maven-tools (~> 1.0.1)
maven-tools (~> 1.0.8)
ruby-maven-libs (= 3.1.1)
ruby-maven-libs (3.1.1)
thread_safe (0.3.5-java)
@@ -53,6 +53,3 @@ DEPENDENCIES
rake (= 10.4.2)
rspec (~> 3.0)
ruby-maven (= 3.1.1.0.11)

BUNDLED WITH
1.11.2
3 changes: 3 additions & 0 deletions maven/jruby/src/it/runnable/Mavenfile
Original file line number Diff line number Diff line change
@@ -3,6 +3,9 @@
# default versions will be overwritten by pom.rb from root directory
properties( 'jruby.plugins.version' => '1.0.10' )

# default versions will be overwritten by pom.rb from root directory
properties( 'mavengem.wagon.version' => '0.2.0' )

gemfile

model.repositories.clear
Empty file removed spec/ruby/core/.jrubydir
Empty file.
2 changes: 1 addition & 1 deletion spec/ruby/core/hash/dig_spec.rb
Original file line number Diff line number Diff line change
@@ -37,7 +37,7 @@ def obj.dig(*args); [ 42 ] end

it "raises TypeError if an intermediate element does not respond to #dig" do
h = {}
h[:foo] = [ { :bar => [ 1 ] }, [ nil, 'str' ] ]
h[:foo] = [ { bar: [ 1 ] }, [ nil, 'str' ] ]
lambda { h.dig(:foo, 0, :bar, 0, 0) }.should raise_error(TypeError)
lambda { h.dig(:foo, 1, 1, 0) }.should raise_error(TypeError)
end
Empty file removed spec/ruby/language/.jrubydir
Empty file.
1 change: 1 addition & 0 deletions spec/truffle/tags/core/thread/raise_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fails:Thread#raise on a sleeping thread raises the given exception and the backtrace is the one of the interrupted thread
2 changes: 1 addition & 1 deletion test/truffle/compiler/pe/core/eval_pe.rb
Original file line number Diff line number Diff line change
@@ -14,4 +14,4 @@

example "eval([1, 2, 3].inspect)[1]", 2

counter_example "eval(rand.to_s)"
tagged_counter_example "eval(rand.to_s)"
2 changes: 1 addition & 1 deletion tool/jt.rb
Original file line number Diff line number Diff line change
@@ -369,7 +369,7 @@ def run(*args)
end

if args.delete('--server')
jruby_args += %w[-Xtruffle.instrumentation_server_port=8080 -Xtruffle.passalot=1]
jruby_args += %w[-Xtruffle.instrumentation_server_port=8080]
end

if args.delete('--igv')
Original file line number Diff line number Diff line change
@@ -84,6 +84,7 @@
import org.jruby.truffle.language.backtrace.BacktraceFormatter;
import org.jruby.truffle.language.control.RaiseException;
import org.jruby.truffle.language.control.TruffleFatalException;
import org.jruby.truffle.language.loader.CodeLoader;
import org.jruby.truffle.language.methods.DeclarationContext;
import org.jruby.truffle.language.methods.InternalMethod;
import org.jruby.truffle.language.objects.FreezeNode;
@@ -766,7 +767,8 @@ public void initializeAfterBasicMethodsAdded() {
state = State.LOADING_RUBY_CORE;
try {
final RubyRootNode rootNode = context.getCodeLoader().parse(context.getSourceCache().getSource(getCoreLoadPath() + "/core.rb"), UTF8Encoding.INSTANCE, ParserContext.TOP_LEVEL, null, true, node);
context.getCodeLoader().execute(ParserContext.TOP_LEVEL, DeclarationContext.TOP_LEVEL, rootNode, null, context.getCoreLibrary().getMainObject());
final CodeLoader.DeferredCall deferredCall = context.getCodeLoader().prepareExecute(ParserContext.TOP_LEVEL, DeclarationContext.TOP_LEVEL, rootNode, null, context.getCoreLibrary().getMainObject());
deferredCall.getCallTarget().call(deferredCall.getArguments());
} catch (IOException e) {
throw new RuntimeException(e);
}
Original file line number Diff line number Diff line change
@@ -35,8 +35,7 @@ public OutputStreamAdapter(RubyContext context, DynamicObject object, Encoding e
@Override
public void write(int bite) throws IOException {
context.send(object, "write", null, Layouts.STRING.createString(context.getCoreLibrary().getStringFactory(),
StringOperations.ropeFromByteList(new ByteList(new byte[]{(byte) bite}, encoding), StringSupport.CR_VALID),
null));
StringOperations.ropeFromByteList(new ByteList(new byte[]{(byte) bite}, encoding), StringSupport.CR_VALID)));
}

}
Original file line number Diff line number Diff line change
@@ -12,9 +12,11 @@
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.Truffle;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.CreateCast;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.IndirectCallNode;
import com.oracle.truffle.api.nodes.NodeUtil;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.source.Source;
@@ -39,6 +41,7 @@
import org.jruby.truffle.language.dispatch.DispatchHeadNodeFactory;
import org.jruby.truffle.language.dispatch.MissingBehavior;
import org.jruby.truffle.language.dispatch.RubyCallNode;
import org.jruby.truffle.language.loader.CodeLoader;
import org.jruby.truffle.language.methods.DeclarationContext;
import org.jruby.truffle.language.methods.InternalMethod;
import org.jruby.truffle.language.methods.UnsupportedOperationBehavior;
@@ -158,13 +161,13 @@ public InstanceEvalNode(RubyContext context, SourceSection sourceSection) {
yield = new YieldNode(context, DeclarationContext.INSTANCE_EVAL);
}

@CompilerDirectives.TruffleBoundary
@Specialization(guards = "isRubyString(string)")
public Object instanceEval(Object receiver, DynamicObject string, NotProvided block) {
public Object instanceEval(VirtualFrame frame, Object receiver, DynamicObject string, NotProvided block, @Cached("create()")IndirectCallNode callNode) {
ByteList code = StringOperations.getByteListReadOnly(string);
final Source source = Source.fromText(code, "(eval)");
final RubyRootNode rootNode = getContext().getCodeLoader().parse(source, code.getEncoding(), ParserContext.EVAL, null, true, this);
return getContext().getCodeLoader().execute(ParserContext.EVAL, DeclarationContext.INSTANCE_EVAL, rootNode, null, receiver);
final CodeLoader.DeferredCall deferredCall = getContext().getCodeLoader().prepareExecute(ParserContext.EVAL, DeclarationContext.INSTANCE_EVAL, rootNode, null, receiver);
return callNode.call(frame, deferredCall.getCallTarget(), deferredCall.getArguments());
}

@Specialization
Original file line number Diff line number Diff line change
@@ -167,7 +167,7 @@ public Object read(VirtualFrame frame, byte[] source) {
final ByteList result = new ByteList(lElem, 0, index, ASCIIEncoding.INSTANCE, false);
setSourcePosition(frame, encode.position());

return Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), StringOperations.ropeFromByteList(result, StringSupport.CR_UNKNOWN), null);
return Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), StringOperations.ropeFromByteList(result, StringSupport.CR_UNKNOWN));
}

}
Original file line number Diff line number Diff line change
@@ -107,7 +107,7 @@ public Object read(VirtualFrame frame, byte[] source) {

setSourcePosition(frame, start + length);

return Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), StringOperations.ropeFromByteList(result, StringSupport.CR_UNKNOWN), null);
return Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), StringOperations.ropeFromByteList(result, StringSupport.CR_UNKNOWN));
}

}
Original file line number Diff line number Diff line change
@@ -85,7 +85,7 @@ public Object read(VirtualFrame frame, byte[] source) {
final ByteList result = new ByteList(lElem, ASCIIEncoding.INSTANCE, false);
setSourcePosition(frame, encode.position());

return Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), StringOperations.ropeFromByteList(result, StringSupport.CR_UNKNOWN), null);
return Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), StringOperations.ropeFromByteList(result, StringSupport.CR_UNKNOWN));
}

}
Original file line number Diff line number Diff line change
@@ -87,7 +87,7 @@ public Object read(VirtualFrame frame, byte[] source) {
final ByteList result = new ByteList(lElem, ASCIIEncoding.INSTANCE, false);
setSourcePosition(frame, encode.position());

return Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), StringOperations.ropeFromByteList(result, StringSupport.CR_UNKNOWN), null);
return Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), StringOperations.ropeFromByteList(result, StringSupport.CR_UNKNOWN));
}

}
Original file line number Diff line number Diff line change
@@ -75,7 +75,7 @@ public Object read(VirtualFrame frame, byte[] source) {
final ByteList result = new ByteList(lElem, 0, index, ASCIIEncoding.INSTANCE, false);
setSourcePosition(frame, encode.position());

return Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), StringOperations.ropeFromByteList(result, StringSupport.CR_UNKNOWN), null);
return Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), StringOperations.ropeFromByteList(result, StringSupport.CR_UNKNOWN));
}

}
Original file line number Diff line number Diff line change
@@ -154,7 +154,7 @@ else if (encode.hasRemaining()) {

setSourcePosition(frame, encode.position());

return Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), StringOperations.ropeFromByteList(result, StringSupport.CR_UNKNOWN), null);
return Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), StringOperations.ropeFromByteList(result, StringSupport.CR_UNKNOWN));
}

private static int safeGet(ByteBuffer encode) {
13 changes: 11 additions & 2 deletions truffle/src/main/java/org/jruby/truffle/core/hash/HashNodes.java
Original file line number Diff line number Diff line change
@@ -45,6 +45,8 @@
import org.jruby.truffle.language.methods.InternalMethod;
import org.jruby.truffle.language.objects.AllocateObjectNode;
import org.jruby.truffle.language.objects.AllocateObjectNodeGen;
import org.jruby.truffle.language.yield.CallBlockNode;
import org.jruby.truffle.language.yield.CallBlockNodeGen;
import org.jruby.truffle.language.yield.YieldNode;

import java.util.Arrays;
@@ -1196,6 +1198,8 @@ public Object setDefault(DynamicObject hash, Object defaultValue) {
@ImportStatic(HashGuards.class)
public abstract static class ShiftNode extends CoreMethodArrayArgumentsNode {

@Child private YieldNode yieldNode;

public ShiftNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}
@@ -1211,8 +1215,13 @@ public Object shiftEmpyDefaultValue(DynamicObject hash) {
}

@Specialization(guards = {"isEmptyHash(hash)", "!hasDefaultValue(hash)", "hasDefaultBlock(hash)"})
public Object shiftEmptyDefaultProc(DynamicObject hash) {
return ProcNodes.rootCall(Layouts.HASH.getDefaultBlock(hash), hash, nil());
public Object shiftEmptyDefaultProc(VirtualFrame frame, DynamicObject hash) {
if (yieldNode == null) {
CompilerDirectives.transferToInterpreter();
yieldNode = insert(new YieldNode(getContext()));
}

return yieldNode.dispatch(frame, Layouts.HASH.getDefaultBlock(hash), hash, nil());
}

@Specialization(guards = {"!isEmptyHash(hash)", "isPackedHash(hash)"})
Original file line number Diff line number Diff line change
@@ -99,6 +99,7 @@
import org.jruby.truffle.language.dispatch.DispatchHeadNodeFactory;
import org.jruby.truffle.language.dispatch.DoesRespondDispatchHeadNode;
import org.jruby.truffle.language.dispatch.MissingBehavior;
import org.jruby.truffle.language.loader.CodeLoader;
import org.jruby.truffle.language.loader.FeatureLoader;
import org.jruby.truffle.language.loader.SourceLoader;
import org.jruby.truffle.language.methods.DeclarationContext;
@@ -600,11 +601,13 @@ public Object evalNoBindingCached(
"isRubyString(source)"
}, contains = "evalNoBindingCached")
public Object evalNoBindingUncached(VirtualFrame frame, DynamicObject source, NotProvided noBinding,
NotProvided filename, NotProvided lineNumber) {
NotProvided filename, NotProvided lineNumber, @Cached("create()") IndirectCallNode callNode) {
final DynamicObject binding = getCallerBinding(frame);
final MaterializedFrame topFrame = Layouts.BINDING.getFrame(binding);
RubyArguments.setSelf(topFrame.getArguments(), RubyArguments.getSelf(frame));
return doEval(source, binding, "(eval)", true);
final CodeLoader.DeferredCall deferredCall = doEvalX(source, binding, "(eval)", true);
return callNode.call(frame, deferredCall.getCallTarget(), deferredCall.getArguments());

}

@Specialization(guards = {
@@ -613,17 +616,18 @@ public Object evalNoBindingUncached(VirtualFrame frame, DynamicObject source, No
"isRubyString(filename)"
})
public Object evalNilBinding(VirtualFrame frame, DynamicObject source, DynamicObject noBinding,
DynamicObject filename, int lineNumber) {
return evalNoBindingUncached(frame, source, NotProvided.INSTANCE, NotProvided.INSTANCE, NotProvided.INSTANCE);
DynamicObject filename, int lineNumber, @Cached("create()") IndirectCallNode callNode) {
return evalNoBindingUncached(frame, source, NotProvided.INSTANCE, NotProvided.INSTANCE, NotProvided.INSTANCE, callNode);
}

@Specialization(guards = {
"isRubyString(source)",
"isRubyBinding(binding)"
})
public Object evalBinding(DynamicObject source, DynamicObject binding, NotProvided filename,
NotProvided lineNumber) {
return doEval(source, binding, "(eval)", false);
public Object evalBinding(VirtualFrame frame, DynamicObject source, DynamicObject binding, NotProvided filename,
NotProvided lineNumber, @Cached("create()") IndirectCallNode callNode) {
final CodeLoader.DeferredCall deferredCall = doEvalX(source, binding, "(eval)", false);
return callNode.call(frame, deferredCall.getCallTarget(), deferredCall.getArguments());
}

@Specialization(guards = {
@@ -632,18 +636,17 @@ public Object evalBinding(DynamicObject source, DynamicObject binding, NotProvid
"isNil(noFilename)",
"isNil(noLineNumber)"
})
public Object evalBinding(DynamicObject source, DynamicObject binding, DynamicObject noFilename, DynamicObject noLineNumber) {
return evalBinding(source, binding, NotProvided.INSTANCE, NotProvided.INSTANCE);
public Object evalBinding(VirtualFrame frame, DynamicObject source, DynamicObject binding, DynamicObject noFilename, DynamicObject noLineNumber, @Cached("create()") IndirectCallNode callNode) {
return evalBinding(frame, source, binding, NotProvided.INSTANCE, NotProvided.INSTANCE, callNode);
}

@TruffleBoundary
@Specialization(guards = {
"isRubyString(source)",
"isRubyBinding(binding)",
"isRubyString(filename)" })
public Object evalBindingFilename(DynamicObject source, DynamicObject binding, DynamicObject filename,
NotProvided lineNumber) {
return evalBindingFilenameLine(source, binding, filename, 0);
public Object evalBindingFilename(VirtualFrame frame, DynamicObject source, DynamicObject binding, DynamicObject filename,
NotProvided lineNumber, @Cached("create()") IndirectCallNode callNode) {
return evalBindingFilenameLine(frame, source, binding, filename, 0, callNode);
}

@Specialization(guards = {
@@ -652,18 +655,18 @@ public Object evalBindingFilename(DynamicObject source, DynamicObject binding, D
"isRubyString(filename)",
"isNil(noLineNumber)"
})
public Object evalBindingFilename(DynamicObject source, DynamicObject binding, DynamicObject filename, DynamicObject noLineNumber) {
return evalBindingFilename(source, binding, filename, NotProvided.INSTANCE);
public Object evalBindingFilename(VirtualFrame frame, DynamicObject source, DynamicObject binding, DynamicObject filename, DynamicObject noLineNumber, @Cached("create()") IndirectCallNode callNode) {
return evalBindingFilename(frame, source, binding, filename, NotProvided.INSTANCE, callNode);
}

@TruffleBoundary
@Specialization(guards = {
"isRubyString(source)",
"isRubyBinding(binding)",
"isRubyString(filename)" })
public Object evalBindingFilenameLine(DynamicObject source, DynamicObject binding, DynamicObject filename,
int lineNumber) {
return doEval(source, binding, filename.toString(), false);
public Object evalBindingFilenameLine(VirtualFrame frame, DynamicObject source, DynamicObject binding, DynamicObject filename,
int lineNumber, @Cached("create()") IndirectCallNode callNode) {
final CodeLoader.DeferredCall deferredCall = doEvalX(source, binding, filename.toString(), false);
return callNode.call(frame, deferredCall.getCallTarget(), deferredCall.getArguments());
}

@TruffleBoundary
@@ -676,15 +679,13 @@ public Object evalBadBinding(DynamicObject source, DynamicObject badBinding, Not
}

@TruffleBoundary
private Object doEval(DynamicObject source, DynamicObject binding, String filename, boolean ownScopeForAssignments) {
private CodeLoader.DeferredCall doEvalX(DynamicObject source, DynamicObject binding, String filename, boolean ownScopeForAssignments) {
ByteList code = StringOperations.getByteListReadOnly(source);
final Source source1 = Source.fromText(code, filename);
final MaterializedFrame frame = Layouts.BINDING.getFrame(binding);
final DeclarationContext declarationContext = RubyArguments.getDeclarationContext(frame);
final RubyRootNode rootNode = getContext().getCodeLoader().parse(source1, code.getEncoding(), ParserContext.EVAL, frame, ownScopeForAssignments, this);
final Object result = getContext().getCodeLoader().execute(ParserContext.EVAL, declarationContext, rootNode, frame, RubyArguments.getSelf(frame));
assert result != null;
return result;
return getContext().getCodeLoader().prepareExecute(ParserContext.EVAL, declarationContext, rootNode, frame, RubyArguments.getSelf(frame));
}

protected RootNodeWrapper compileSource(VirtualFrame frame, DynamicObject sourceText) {
@@ -1572,14 +1573,15 @@ public RubyNode coerceFeatureToPath(RubyNode feature) {
return ToPathNodeGen.create(getContext(), getSourceSection(), feature);
}

@TruffleBoundary
@Specialization(guards = "isRubyString(featureString)")
public boolean require(DynamicObject featureString) {
public boolean require(VirtualFrame frame, DynamicObject featureString, @Cached("create()") IndirectCallNode callNode) {
CompilerDirectives.transferToInterpreter();

final String feature = featureString.toString();

// Pysch loads either the jar or the so - we need to intercept
if (feature.equals("psych.so") && callerIs("psych.rb")) {
getContext().getFeatureLoader().require("truffle/psych.rb", this);
getContext().getFeatureLoader().require(frame, "truffle/psych.rb", callNode);
return true;
}

@@ -1588,7 +1590,7 @@ public boolean require(DynamicObject featureString) {
throw new RaiseException(coreLibrary().loadErrorCannotLoad(feature, this));
}

return getContext().getFeatureLoader().require(feature, this);
return getContext().getFeatureLoader().require(frame, feature, callNode);
}

private boolean callerIs(String caller) {
@@ -1604,9 +1606,10 @@ public RequireRelativeNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

@TruffleBoundary
@Specialization(guards = "isRubyString(feature)")
public boolean requireRelative(DynamicObject feature) {
public boolean requireRelative(VirtualFrame frame, DynamicObject feature, @Cached("create()") IndirectCallNode callNode) {
CompilerDirectives.transferToInterpreter();

final FeatureLoader featureLoader = getContext().getFeatureLoader();

final String featureString = feature.toString();
@@ -1632,7 +1635,7 @@ public boolean requireRelative(DynamicObject feature) {
featurePath = dirname(sourcePath) + "/" + featureString;
}

featureLoader.require(featurePath, this);
featureLoader.require(frame, featurePath, callNode);

return true;
}
Original file line number Diff line number Diff line change
@@ -24,6 +24,7 @@
import com.oracle.truffle.api.frame.FrameInstance.FrameAccess;
import com.oracle.truffle.api.frame.MaterializedFrame;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.IndirectCallNode;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.nodes.NodeUtil;
import com.oracle.truffle.api.object.DynamicObject;
@@ -72,6 +73,7 @@
import org.jruby.truffle.language.control.RaiseException;
import org.jruby.truffle.language.dispatch.CallDispatchHeadNode;
import org.jruby.truffle.language.dispatch.DispatchHeadNodeFactory;
import org.jruby.truffle.language.loader.CodeLoader;
import org.jruby.truffle.language.methods.AddMethodNode;
import org.jruby.truffle.language.methods.AddMethodNodeGen;
import org.jruby.truffle.language.methods.Arity;
@@ -633,36 +635,38 @@ protected DynamicObject toStr(VirtualFrame frame, Object object) {
}

@Specialization(guards = "isRubyString(code)")
public Object classEval(DynamicObject module, DynamicObject code, NotProvided file, NotProvided line, NotProvided block) {
return classEvalSource(module, code, "(eval)");
public Object classEval(VirtualFrame frame, DynamicObject module, DynamicObject code, NotProvided file, NotProvided line, NotProvided block, @Cached("create()") IndirectCallNode callNode) {
return classEvalSource(frame, module, code, "(eval)", callNode);
}

@Specialization(guards = {"isRubyString(code)", "isRubyString(file)"})
public Object classEval(DynamicObject module, DynamicObject code, DynamicObject file, NotProvided line, NotProvided block) {
return classEvalSource(module, code, file.toString());
public Object classEval(VirtualFrame frame, DynamicObject module, DynamicObject code, DynamicObject file, NotProvided line, NotProvided block, @Cached("create()") IndirectCallNode callNode) {
return classEvalSource(frame, module, code, file.toString(), callNode);
}

@Specialization(guards = {"isRubyString(code)", "isRubyString(file)"})
public Object classEval(DynamicObject module, DynamicObject code, DynamicObject file, int line, NotProvided block) {
return classEvalSource(module, code, file.toString(), line);
public Object classEval(VirtualFrame frame, DynamicObject module, DynamicObject code, DynamicObject file, int line, NotProvided block, @Cached("create()") IndirectCallNode callNode) {
final CodeLoader.DeferredCall deferredCall = classEvalSource(module, code, file.toString(), line);
return callNode.call(frame, deferredCall.getCallTarget(), deferredCall.getArguments());
}

@Specialization(guards = "wasProvided(code)")
public Object classEval(VirtualFrame frame, DynamicObject module, Object code, NotProvided file, NotProvided line, NotProvided block) {
return classEvalSource(module, toStr(frame, code), file.toString());
public Object classEval(VirtualFrame frame, DynamicObject module, Object code, NotProvided file, NotProvided line, NotProvided block, @Cached("create()") IndirectCallNode callNode) {
return classEvalSource(frame, module, toStr(frame, code), file.toString(), callNode);
}

@Specialization(guards = {"isRubyString(code)", "wasProvided(file)"})
public Object classEval(VirtualFrame frame, DynamicObject module, DynamicObject code, Object file, NotProvided line, NotProvided block) {
return classEvalSource(module, code, toStr(frame, file).toString());
public Object classEval(VirtualFrame frame, DynamicObject module, DynamicObject code, Object file, NotProvided line, NotProvided block, @Cached("create()") IndirectCallNode callNode) {
return classEvalSource(frame, module, code, toStr(frame, file).toString(), callNode);
}

private Object classEvalSource(DynamicObject module, DynamicObject code, String file) {
return classEvalSource(module, code, file, 1);
private Object classEvalSource(VirtualFrame frame, DynamicObject module, DynamicObject code, String file, @Cached("create()") IndirectCallNode callNode) {
final CodeLoader.DeferredCall deferredCall = classEvalSource(module, code, file, 1);
return callNode.call(frame, deferredCall.getCallTarget(), deferredCall.getArguments());
}

@TruffleBoundary
private Object classEvalSource(DynamicObject module, DynamicObject code, String file, int line) {
private CodeLoader.DeferredCall classEvalSource(DynamicObject module, DynamicObject code, String file, int line) {
assert RubyGuards.isRubyString(code);

final MaterializedFrame callerFrame = getContext().getCallStack().getCallerFrameIgnoringSend()
@@ -675,7 +679,7 @@ private Object classEvalSource(DynamicObject module, DynamicObject code, String
Source source = Source.fromText(space + code.toString(), file);

final RubyRootNode rootNode = getContext().getCodeLoader().parse(source, encoding, ParserContext.MODULE, callerFrame, true, this);
return getContext().getCodeLoader().execute(ParserContext.MODULE, DeclarationContext.CLASS_EVAL, rootNode, callerFrame, module);
return getContext().getCodeLoader().prepareExecute(ParserContext.MODULE, DeclarationContext.CLASS_EVAL, rootNode, callerFrame, module);
}

@Specialization
@@ -915,6 +919,7 @@ public abstract static class ConstGetNode extends CoreMethodNode {

@Child private ReadConstantNode readConstantNode;
@Child private KernelNodes.RequireNode requireNode;
@Child private IndirectCallNode indirectCallNode;

public ConstGetNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
@@ -938,8 +943,8 @@ public Object getConstant(VirtualFrame frame, DynamicObject module, DynamicObjec
}

@Specialization(guards = { "!inherit", "isRubySymbol(name)" })
public Object getConstantNoInherit(DynamicObject module, DynamicObject name, boolean inherit) {
return getConstantNoInherit(module, Layouts.SYMBOL.getString(name), this);
public Object getConstantNoInherit(VirtualFrame frame, DynamicObject module, DynamicObject name, boolean inherit) {
return getConstantNoInherit(frame, module, Layouts.SYMBOL.getString(name), this);
}

// String
@@ -949,8 +954,8 @@ public Object getConstantString(VirtualFrame frame, DynamicObject module, Dynami
}

@Specialization(guards = { "!inherit", "isRubyString(name)", "!isScoped(name)" })
public Object getConstantNoInheritString(DynamicObject module, DynamicObject name, boolean inherit) {
return getConstantNoInherit(module, name.toString(), this);
public Object getConstantNoInheritString(VirtualFrame frame, DynamicObject module, DynamicObject name, boolean inherit) {
return getConstantNoInherit(frame, module, name.toString(), this);
}

// Scoped String
@@ -959,16 +964,15 @@ public Object getConstantScoped(DynamicObject module, DynamicObject fullName, bo
return getConstantScoped(module, fullName.toString(), inherit);
}

@TruffleBoundary
private Object getConstantNoInherit(DynamicObject module, String name, Node currentNode) {
private Object getConstantNoInherit(VirtualFrame frame, DynamicObject module, String name, Node currentNode) {
RubyConstant constant = ModuleOperations.lookupConstantWithInherit(getContext(), module, name, false, currentNode);

if (constant == null) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(coreLibrary().nameErrorUninitializedConstant(module, name, this));
} else {
if (constant.isAutoload()) {
loadAutoloadedConstant(module, name, constant);
loadAutoloadedConstant(frame, constant);
constant = ModuleOperations.lookupConstantWithInherit(getContext(), module, name, false, currentNode);
}

@@ -994,13 +998,18 @@ boolean isScoped(DynamicObject name) {
return name.toString().contains("::");
}

private void loadAutoloadedConstant(DynamicObject module, String name, RubyConstant constant) {
private void loadAutoloadedConstant(VirtualFrame frame, RubyConstant constant) {
if (requireNode == null) {
CompilerDirectives.transferToInterpreter();
requireNode = insert(KernelNodesFactory.RequireNodeFactory.create(getContext(), getSourceSection(), null));
}

requireNode.require((DynamicObject) constant.getValue());
if (indirectCallNode == null) {
CompilerDirectives.transferToInterpreter();
indirectCallNode = insert(IndirectCallNode.create());
}

requireNode.require(frame, (DynamicObject) constant.getValue(), indirectCallNode);
}

}
Original file line number Diff line number Diff line change
@@ -203,7 +203,7 @@ private static DynamicObject createSubstring(RopeNodes.MakeSubstringNode makeSub
final Rope sourceRope = StringOperations.rope(source);
final Rope substringRope = makeSubstringNode.executeMake(sourceRope, start, length);

final DynamicObject ret = Layouts.STRING.createString(Layouts.CLASS.getInstanceFactory(Layouts.BASIC_OBJECT.getLogicalClass(source)), substringRope, null);
final DynamicObject ret = Layouts.STRING.createString(Layouts.CLASS.getInstanceFactory(Layouts.BASIC_OBJECT.getLogicalClass(source)), substringRope);

return ret;
}
Original file line number Diff line number Diff line change
@@ -261,7 +261,7 @@ private DynamicObject makeString(DynamicObject source, int index, int length) {

final Rope rope = makeSubstringNode.executeMake(rope(source), index, length);

final DynamicObject ret = Layouts.STRING.createString(Layouts.CLASS.getInstanceFactory(Layouts.BASIC_OBJECT.getLogicalClass(source)), rope, null);
final DynamicObject ret = Layouts.STRING.createString(Layouts.CLASS.getInstanceFactory(Layouts.BASIC_OBJECT.getLogicalClass(source)), rope);
taintResultNode.maybeTaint(source, ret);

return ret;
Original file line number Diff line number Diff line change
@@ -24,8 +24,7 @@ DynamicObjectFactory createStringShape(DynamicObject logicalClass,
DynamicObject metaClass);

DynamicObject createString(DynamicObjectFactory factory,
Rope rope,
@Nullable DynamicObject rubiniusDataArray);
Rope rope);

boolean isString(ObjectType objectType);
boolean isString(DynamicObject object);
@@ -34,7 +33,4 @@ DynamicObject createString(DynamicObjectFactory factory,
Rope getRope(DynamicObject object);
void setRope(DynamicObject object, Rope value);

DynamicObject getRubiniusDataArray(DynamicObject object);
void setRubiniusDataArray(DynamicObject object, DynamicObject value);

}
Original file line number Diff line number Diff line change
@@ -155,9 +155,7 @@ public DynamicObject add(DynamicObject string, DynamicObject other) {

final Rope concatRope = makeConcatNode.executeMake(left, right, enc);

final DynamicObject ret = Layouts.STRING.createString(coreLibrary().getStringFactory(),
concatRope,
null);
final DynamicObject ret = Layouts.STRING.createString(coreLibrary().getStringFactory(), concatRope);

taintResultNode.maybeTaint(string, ret);
taintResultNode.maybeTaint(other, ret);
@@ -922,30 +920,6 @@ public Object crypt(DynamicObject string, DynamicObject salt) {

}

@RubiniusOnly
@CoreMethod(names = "data")
public abstract static class DataNode extends CoreMethodArrayArgumentsNode {

public DataNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

@Specialization
public Object data(DynamicObject string) {
final DynamicObject ret = Layouts.STRING.getRubiniusDataArray(string);

if (ret == null) {
// TODO (nirvdrum 08-Jan-16) ByteArrays might be better served if backed by a byte[] instead of a ByteList.
final DynamicObject rubiniusDataArray = ByteArrayNodes.createByteArray(coreLibrary().getByteArrayFactory(), StringOperations.getByteListReadOnly(string));
Layouts.STRING.setRubiniusDataArray(string, rubiniusDataArray);

return rubiniusDataArray;
}

return ret;
}
}

@CoreMethod(names = "delete!", rest = true, raiseIfFrozenSelf = true)
@ImportStatic(StringGuards.class)
public abstract static class DeleteBangNode extends CoreMethodArrayArgumentsNode {
Original file line number Diff line number Diff line change
@@ -57,16 +57,16 @@ public abstract class StringOperations {

/** Creates a String from the ByteList, with unknown CR */
public static DynamicObject createString(RubyContext context, ByteList bytes) {
return Layouts.STRING.createString(context.getCoreLibrary().getStringFactory(), ropeFromByteList(bytes, CodeRange.CR_UNKNOWN), null);
return Layouts.STRING.createString(context.getCoreLibrary().getStringFactory(), ropeFromByteList(bytes, CodeRange.CR_UNKNOWN));
}

/** Creates a String from the ByteList, with 7-bit CR */
public static DynamicObject create7BitString(RubyContext context, ByteList bytes) {
return Layouts.STRING.createString(context.getCoreLibrary().getStringFactory(), ropeFromByteList(bytes, CodeRange.CR_7BIT), null);
return Layouts.STRING.createString(context.getCoreLibrary().getStringFactory(), ropeFromByteList(bytes, CodeRange.CR_7BIT));
}

public static DynamicObject createString(RubyContext context, Rope rope) {
return Layouts.STRING.createString(context.getCoreLibrary().getStringFactory(), rope, null);
return Layouts.STRING.createString(context.getCoreLibrary().getStringFactory(), rope);
}

// Since ByteList.toString does not decode properly
@@ -258,7 +258,6 @@ public static void setRope(DynamicObject string, Rope rope) {
assert RubyGuards.isRubyString(string);

Layouts.STRING.setRope(string, rope);
Layouts.STRING.setRubiniusDataArray(string, null);
}

public static Encoding encoding(DynamicObject string) {
Original file line number Diff line number Diff line change
@@ -192,14 +192,7 @@ public void initializeCurrentThread(DynamicObject thread) {

@TruffleBoundary
public DynamicObject getCurrentThread() {
DynamicObject current = currentThread.get();

if (current == null) {
current = rootThread;
currentThread.set(current);
}

return current;
return currentThread.get();
}

public synchronized void registerThread(DynamicObject thread) {
Original file line number Diff line number Diff line change
@@ -125,14 +125,12 @@ public static void run(DynamicObject thread, final RubyContext context, Node cur
}
}

// Only used by the main thread which cannot easily wrap everything inside a try/finally.
public static void start(RubyContext context, DynamicObject thread) {
assert RubyGuards.isRubyThread(thread);
Layouts.THREAD.setThread(thread, Thread.currentThread());
context.getThreadManager().registerThread(thread);
}

// Only used by the main thread which cannot easily wrap everything inside a try/finally.
public static void cleanup(RubyContext context, DynamicObject thread) {
assert RubyGuards.isRubyThread(thread);

Original file line number Diff line number Diff line change
@@ -14,12 +14,14 @@
import com.oracle.truffle.api.RootCallTarget;
import com.oracle.truffle.api.Truffle;
import com.oracle.truffle.api.TruffleOptions;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.FrameInstance;
import com.oracle.truffle.api.frame.FrameInstanceVisitor;
import com.oracle.truffle.api.frame.MaterializedFrame;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.instrumentation.EventBinding;
import com.oracle.truffle.api.nodes.IndirectCallNode;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.source.Source;
@@ -53,6 +55,7 @@
import org.jruby.truffle.language.RubyRootNode;
import org.jruby.truffle.language.backtrace.BacktraceFormatter;
import org.jruby.truffle.language.control.RaiseException;
import org.jruby.truffle.language.loader.CodeLoader;
import org.jruby.truffle.language.loader.SourceLoader;
import org.jruby.truffle.language.methods.DeclarationContext;
import org.jruby.truffle.language.methods.InternalMethod;
@@ -831,16 +834,16 @@ public LoadNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

@TruffleBoundary
@Specialization(guards = "isRubyString(file)")
public boolean load(DynamicObject file, boolean wrap) {
public boolean load(VirtualFrame frame, DynamicObject file, boolean wrap, @Cached("create()") IndirectCallNode callNode) {
if (wrap) {
throw new UnsupportedOperationException();
}

try {
final RubyRootNode rootNode = getContext().getCodeLoader().parse(getContext().getSourceCache().getSource(StringOperations.getString(getContext(), file)), UTF8Encoding.INSTANCE, ParserContext.TOP_LEVEL, null, true, this);
getContext().getCodeLoader().execute(ParserContext.TOP_LEVEL, DeclarationContext.TOP_LEVEL, rootNode, null, getContext().getCoreLibrary().getMainObject());
final CodeLoader.DeferredCall deferredCall = getContext().getCodeLoader().prepareExecute(ParserContext.TOP_LEVEL, DeclarationContext.TOP_LEVEL, rootNode, null, getContext().getCoreLibrary().getMainObject());
callNode.call(frame, deferredCall.getCallTarget(), deferredCall.getArguments());
} catch (IOException e) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(coreLibrary().loadErrorCannotLoad(file.toString(), this));
@@ -850,8 +853,8 @@ public boolean load(DynamicObject file, boolean wrap) {
}

@Specialization(guards = "isRubyString(file)")
public boolean load(DynamicObject file, NotProvided wrap) {
return load(file, false);
public boolean load(VirtualFrame frame, DynamicObject file, NotProvided wrap, @Cached("create()") IndirectCallNode callNode) {
return load(frame, file, false, callNode);
}
}

@@ -863,7 +866,7 @@ public RunJRubyRootNode(RubyContext context, SourceSection sourceSection) {
}

@Specialization
public Object runJRubyRootNode() {
public Object runJRubyRootNode(VirtualFrame frame, @Cached("create()")IndirectCallNode callNode) {
coreLibrary().getGlobalVariablesObject().define(
"$0",
StringOperations.createString(getContext(),
@@ -891,12 +894,14 @@ public Object runJRubyRootNode() {
true,
null);

return getContext().getCodeLoader().execute(
final CodeLoader.DeferredCall deferredCall = getContext().getCodeLoader().prepareExecute(
ParserContext.TOP_LEVEL,
DeclarationContext.TOP_LEVEL,
rootNode,
null,
coreLibrary().getMainObject());

return callNode.call(frame, deferredCall.getCallTarget(), deferredCall.getArguments());
}
}

Original file line number Diff line number Diff line change
@@ -33,6 +33,7 @@
import com.oracle.truffle.api.interop.UnsupportedMessageException;
import com.oracle.truffle.api.interop.UnsupportedTypeException;
import com.oracle.truffle.api.nodes.DirectCallNode;
import com.oracle.truffle.api.nodes.IndirectCallNode;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.source.Source;
@@ -389,7 +390,7 @@ public double unbox(VirtualFrame frame, double receiver) {
public DynamicObject executeForeign(VirtualFrame frame, CharSequence receiver) {
// TODO CS-21-Dec-15 this shouldn't be needed - we need to convert j.l.String to Ruby's String automatically

return Layouts.STRING.createString(coreLibrary().getStringFactory(), StringOperations.ropeFromByteList(ByteList.create(receiver)), null);
return Layouts.STRING.createString(coreLibrary().getStringFactory(), StringOperations.ropeFromByteList(ByteList.create(receiver)));
}

@Specialization
@@ -529,12 +530,12 @@ public Object evalCached(
return callNode.call(frame, new Object[]{});
}

@TruffleBoundary
@Specialization(guards = {"isRubyString(mimeType)", "isRubyString(source)"}, contains = "evalCached")
public Object evalUncached(DynamicObject mimeType, DynamicObject source) {
return parse(mimeType, source).call();
public Object evalUncached(VirtualFrame frame, DynamicObject mimeType, DynamicObject source, @Cached("create()")IndirectCallNode callNode) {
return callNode.call(frame, parse(mimeType, source), new Object[]{});
}

@TruffleBoundary
protected CallTarget parse(DynamicObject mimeType, DynamicObject source) {
final String mimeTypeString = mimeType.toString();
final Source sourceObject = Source.fromText(source.toString(), "(eval)").withMimeType(mimeTypeString);
@@ -565,7 +566,7 @@ public JavaStringToRubyNode(RubyContext context, SourceSection sourceSection) {
@Specialization
@TruffleBoundary
public DynamicObject javaStringToRuby(String string) {
return Layouts.STRING.createString(coreLibrary().getStringFactory(), StringOperations.ropeFromByteList(ByteList.create(string), StringSupport.CR_UNKNOWN), null);
return Layouts.STRING.createString(coreLibrary().getStringFactory(), StringOperations.ropeFromByteList(ByteList.create(string), StringSupport.CR_UNKNOWN));
}

}
Original file line number Diff line number Diff line change
@@ -164,6 +164,12 @@ public Object visitFrame(FrameInstance frameInstance) {

});

// TODO CS 3-Mar-16 The last activation is I think what calls jruby_root_node, and I can't seem to remove it any other way

if (!activations.isEmpty()) {
activations.remove(activations.size() - 1);
}

if (context.getOptions().EXCEPTIONS_STORE_JAVA || context.getOptions().BACKTRACES_INTERLEAVE_JAVA) {
if (javaThrowable == null) {
javaThrowable = new Exception();
@@ -190,8 +196,7 @@ private boolean ignoreFrame(FrameInstance frameInstance) {

final SourceSection sourceSection = callNode.getEncapsulatingSourceSection();

if (sourceSection != null && sourceSection.getSource() != null
&& sourceSection.getSource().getName().equals("run_jruby_root")) {
if (sourceSection != null && sourceSection.getShortDescription().endsWith("#run_jruby_root")) {
return true;
}

Original file line number Diff line number Diff line change
@@ -15,6 +15,7 @@
import com.oracle.truffle.api.dsl.NodeChildren;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.IndirectCallNode;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.profiles.ConditionProfile;
import com.oracle.truffle.api.source.SourceSection;
@@ -50,15 +51,16 @@ protected Object getConstant(DynamicObject module, String name, RubyConstant con
@Specialization(guards = { "constant != null", "constant.isAutoload()" })
protected Object autoloadConstant(VirtualFrame frame, DynamicObject module, String name, RubyConstant constant,
@Cached("createRequireNode()") RequireNode requireNode,
@Cached("deepCopyReadConstantNode()") RestartableReadConstantNode readConstantNode) {
@Cached("deepCopyReadConstantNode()") RestartableReadConstantNode readConstantNode,
@Cached("create()")IndirectCallNode callNode) {

final DynamicObject path = (DynamicObject) constant.getValue();

// The autoload constant must only be removed if everything succeeds.
// We remove it first to allow lookup to ignore it and add it back if there was a failure.
Layouts.MODULE.getFields(constant.getDeclaringModule()).removeConstant(getContext(), this, name);
try {
requireNode.require(path);
requireNode.require(frame, path, callNode);
return readConstantNode.readConstant(frame, module, name);
} catch (RaiseException e) {
Layouts.MODULE.getFields(constant.getDeclaringModule()).setAutoloadConstant(getContext(), this, name, path);
Original file line number Diff line number Diff line change
@@ -53,7 +53,7 @@ public RubyRootNode parse(Source source,
}

@TruffleBoundary
public Object execute(ParserContext parserContext,
public DeferredCall prepareExecute(ParserContext parserContext,
DeclarationContext declarationContext,
RubyRootNode rootNode,
MaterializedFrame parentFrame,
@@ -77,7 +77,7 @@ public Object execute(ParserContext parserContext,
Visibility.PUBLIC,
callTarget);

return callTarget.call(RubyArguments.pack(
return new DeferredCall(callTarget, RubyArguments.pack(
parentFrame,
null,
method,
@@ -129,12 +129,33 @@ public Object inline(Node currentNode, Frame frame, String expression, Object...
true,
currentNode);

return context.getCodeLoader().execute(
final DeferredCall deferredCall = context.getCodeLoader().prepareExecute(
ParserContext.INLINE,
DeclarationContext.INSTANCE_EVAL,
rootNode,
evalFrame,
RubyArguments.getSelf(evalFrame));

return deferredCall.getCallTarget().call(deferredCall.getArguments());
}

public static class DeferredCall {

private final CallTarget callTarget;
private final Object[] arguments;

public DeferredCall(CallTarget callTarget, Object[] arguments) {
this.callTarget = callTarget;
this.arguments = arguments;
}

public CallTarget getCallTarget() {
return callTarget;
}

public Object[] getArguments() {
return arguments;
}
}

}
Original file line number Diff line number Diff line change
@@ -9,6 +9,8 @@
*/
package org.jruby.truffle.language.loader;

import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.IndirectCallNode;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.source.Source;
@@ -35,14 +37,14 @@ public FeatureLoader(RubyContext context) {
this.context = context;
}

public boolean require(String feature, Node currentNode) {
public boolean require(VirtualFrame frame, String feature, IndirectCallNode callNode) {
final String featurePath = findFeature(feature);

if (featurePath == null) {
throw new RaiseException(context.getCoreLibrary().loadErrorCannotLoad(feature, currentNode));
throw new RaiseException(context.getCoreLibrary().loadErrorCannotLoad(feature, callNode));
}

return doRequire(featurePath, currentNode);
return doRequire(frame, featurePath, callNode);
}

private String findFeature(String feature) {
@@ -110,7 +112,7 @@ private String findFeatureWithExactPath(String path) {
}
}

private boolean doRequire(String expandedPath, Node currentNode) {
private boolean doRequire(VirtualFrame frame, String expandedPath, IndirectCallNode calNode) {
if (isFeatureLoaded(expandedPath)) {
return false;
}
@@ -135,13 +137,15 @@ private boolean doRequire(String expandedPath, Node currentNode) {
ParserContext.TOP_LEVEL,
null,
true,
currentNode);
calNode);

context.getCodeLoader().execute(
final CodeLoader.DeferredCall deferredCall = context.getCodeLoader().prepareExecute(
ParserContext.TOP_LEVEL,
DeclarationContext.TOP_LEVEL,
rootNode, null,
context.getCoreLibrary().getMainObject());

calNode.call(frame, deferredCall.getCallTarget(), deferredCall.getArguments());
} catch (RaiseException e) {
removeFromLoadedFeatures(pathString);
throw e;
Original file line number Diff line number Diff line change
@@ -11,6 +11,7 @@

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.IndirectCallNode;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.profiles.BranchProfile;
import com.oracle.truffle.api.profiles.ConditionProfile;
@@ -32,6 +33,7 @@ public class DefineClassNode extends RubyNode {
@Child private RubyNode superClass;
@Child private CallDispatchHeadNode inheritedNode;
@Child private RubyNode lexicalParentModule;
@Child private IndirectCallNode indirectCallNode;

private final ConditionProfile needToDefineProfile = ConditionProfile.createBinaryProfile();
private final BranchProfile errorProfile = BranchProfile.create();
@@ -42,6 +44,7 @@ public DefineClassNode(RubyContext context, SourceSection sourceSection, String
this.name = name;
this.lexicalParentModule = lexicalParent;
this.superClass = superClass;
indirectCallNode = IndirectCallNode.create();
}

@Override
@@ -56,7 +59,7 @@ public Object execute(VirtualFrame frame) {
DynamicObject lexicalParentModule = (DynamicObject) lexicalParentObject;

final RubyConstant constant = DefineModuleNode.lookupForExistingModule(
getContext(), name, lexicalParentModule, this);
frame, getContext(), name, lexicalParentModule, indirectCallNode);

final DynamicObject definingClass;
final Object superClassObject = superClass.execute(frame);
Original file line number Diff line number Diff line change
@@ -9,8 +9,10 @@
*/
package org.jruby.truffle.language.objects;

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.IndirectCallNode;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.profiles.BranchProfile;
import com.oracle.truffle.api.profiles.ConditionProfile;
@@ -29,6 +31,7 @@ public class DefineModuleNode extends RubyNode {
private final String name;

@Child private RubyNode lexicalParentModule;
@Child private IndirectCallNode indirectCallNode;

private final ConditionProfile needToDefineProfile = ConditionProfile.createBinaryProfile();
private final BranchProfile errorProfile = BranchProfile.create();
@@ -37,6 +40,7 @@ public DefineModuleNode(RubyContext context, SourceSection sourceSection, String
super(context, sourceSection);
this.name = name;
this.lexicalParentModule = lexicalParent;
indirectCallNode = IndirectCallNode.create();
}

@Override
@@ -49,7 +53,7 @@ public Object execute(VirtualFrame frame) {
}

final DynamicObject lexicalParentModule = (DynamicObject) lexicalParentObject;
final RubyConstant constant = lookupForExistingModule(getContext(), name, lexicalParentModule, this);
final RubyConstant constant = lookupForExistingModule(frame, getContext(), name, lexicalParentModule, indirectCallNode);

final DynamicObject definingModule;

@@ -70,9 +74,10 @@ public Object execute(VirtualFrame frame) {
return definingModule;
}

@TruffleBoundary
public static RubyConstant lookupForExistingModule(RubyContext context, String name,
DynamicObject lexicalParent, RubyNode node) {
public static RubyConstant lookupForExistingModule(VirtualFrame frame, RubyContext context, String name,
DynamicObject lexicalParent, IndirectCallNode callNode) {
CompilerDirectives.transferToInterpreter();

RubyConstant constant = Layouts.MODULE.getFields(lexicalParent).getConstant(name);

final DynamicObject objectClass = context.getCoreLibrary().getObjectClass();
@@ -88,7 +93,7 @@ public static RubyConstant lookupForExistingModule(RubyContext context, String n
}

if (constant != null && !constant.isVisibleTo(context, LexicalScope.NONE, lexicalParent)) {
throw new RaiseException(context.getCoreLibrary().nameErrorPrivateConstant(lexicalParent, name, node));
throw new RaiseException(context.getCoreLibrary().nameErrorPrivateConstant(lexicalParent, name, callNode));
}

// If a constant already exists with this class/module name and it's an autoload module, we have to trigger
@@ -100,9 +105,9 @@ public static RubyConstant lookupForExistingModule(RubyContext context, String n
// the constant here rather than just overwrite it in order to prevent autoload loops in either the require
// call or the recursive execute call.

Layouts.MODULE.getFields(lexicalParent).removeConstant(context, node, name);
context.getFeatureLoader().require(constant.getValue().toString(), node);
return lookupForExistingModule(context, name, lexicalParent, node);
Layouts.MODULE.getFields(lexicalParent).removeConstant(context, callNode, name);
context.getFeatureLoader().require(frame, constant.getValue().toString(), callNode);
return lookupForExistingModule(frame, context, name, lexicalParent, callNode);
}

return constant;
Original file line number Diff line number Diff line change
@@ -1873,11 +1873,6 @@ public RubyNode visitInstVarNode(org.jruby.ast.InstVarNode node) {
ret = RegexpNodesFactory.RubiniusNamesNodeGen.create(context, sourceSection, self);
return addNewlineIfNeeded(node, ret);
}
} else if (path.equals(corePath + "rubinius/bootstrap/string.rb") || path.equals(corePath + "rubinius/common/string.rb")) {
if (name.equals("@data")) {
ret = StringNodesFactory.DataNodeFactory.create(context, sourceSection, new RubyNode[]{ self });
return addNewlineIfNeeded(node, ret);
}
} else if (path.equals(corePath + "rubinius/common/time.rb")) {
if (name.equals("@is_gmt")) {
ret = TimeNodesFactory.InternalGMTNodeFactory.create(context, sourceSection, self);
Original file line number Diff line number Diff line change
@@ -22,12 +22,12 @@
import org.jruby.truffle.language.backtrace.Backtrace;
import org.jruby.truffle.language.backtrace.BacktraceFormatter;
import org.jruby.truffle.tools.simpleshell.SimpleShell;

import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.util.List;

@SuppressWarnings("restriction")
public class InstrumentationServerManager {

private final RubyContext context;
@@ -57,16 +57,10 @@ public void handle(HttpExchange httpExchange) {
try {
final StringBuilder builder = new StringBuilder();

final Thread serverThread = Thread.currentThread();

context.getSafepointManager().pauseAllThreadsAndExecuteFromNonRubyThread(false, new SafepointAction() {
@Override
public void run(DynamicObject thread, Node currentNode) {
synchronized (this) {
if (Thread.currentThread() == serverThread) {
return;
}

try {
final Backtrace backtrace = context.getCallStack().getBacktrace(null);

Original file line number Diff line number Diff line change
@@ -21,6 +21,7 @@
import org.jruby.truffle.language.backtrace.Activation;
import org.jruby.truffle.language.backtrace.BacktraceFormatter;
import org.jruby.truffle.language.control.RaiseException;
import org.jruby.truffle.language.loader.CodeLoader;
import org.jruby.truffle.language.parser.ParserContext;

import java.io.IOException;
@@ -113,12 +114,14 @@ public void run(MaterializedFrame frame, Node currentNode) {
false,
currentNode);

final Object result = context.getCodeLoader().execute(
final CodeLoader.DeferredCall deferredCall = context.getCodeLoader().prepareExecute(
ParserContext.EVAL,
RubyArguments.getDeclarationContext(currentFrame.getArguments()),
rootNode, currentFrame,
RubyArguments.getSelf(currentFrame.getArguments()));

final Object result = deferredCall.getCallTarget().call(deferredCall.getArguments());

String inspected;

try {
5 changes: 2 additions & 3 deletions truffle/src/main/ruby/core/rubinius/common/file.rb
Original file line number Diff line number Diff line change
@@ -150,7 +150,7 @@ def self.basename(path, ext=undefined)
if pos == path.bytesize - 1

# Find the first non-/ from the right
data = path.data
data = path.bytes
found = false
pos.downto(0) do |i|
if data[i] != 47 # ?/
@@ -357,8 +357,7 @@ def self.directory?(io_or_path)

def self.last_nonslash(path, start=nil)
# Find the first non-/ from the right
data = path.data
idx = nil
data = path.bytes
start ||= (path.size - 1)

start.downto(0) do |i|
4 changes: 2 additions & 2 deletions truffle/src/main/ruby/core/rubinius/common/marshal.rb
Original file line number Diff line number Diff line change
@@ -1162,7 +1162,7 @@ def initialize(stream, depth, prc)
super stream, depth, prc

if @stream
@byte_array = stream.data
@byte_array = stream.bytes
end

end
@@ -1176,7 +1176,7 @@ def consume(bytes)

def consume_byte
raise ArgumentError, "marshal data too short" if @consumed >= @stream.bytesize
data = @byte_array.get_byte @consumed
data = @byte_array[@consumed]
@consumed += 1
return data
end
779 changes: 16 additions & 763 deletions truffle/src/main/ruby/core/rubinius/common/string.rb

Large diffs are not rendered by default.

0 comments on commit 8437c97

Please sign in to comment.