Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: jruby/jruby
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: ce8fcd07ed22
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 751298868c34
Choose a head ref
  • 2 commits
  • 7 files changed
  • 1 contributor

Commits on Nov 7, 2016

  1. Copy the full SHA
    3f92ed5 View commit details
  2. Copy the full SHA
    7512988 View commit details
23 changes: 3 additions & 20 deletions truffle/src/main/java/org/jruby/truffle/JRubyTruffleImpl.java
Original file line number Diff line number Diff line change
@@ -20,39 +20,22 @@

public class JRubyTruffleImpl implements JRubyTruffleInterface {

private final PolyglotEngine engine;
private final RubyContext context;
private final RubyEngine engine;

// Created by reflection from Ruby#loadTruffle

public JRubyTruffleImpl(RubyInstanceConfig instanceConfig) {
engine = PolyglotEngine.newBuilder()
.globalSymbol(JRubyTruffleInterface.RUNTIME_SYMBOL, new InstanceConfigWrapper(instanceConfig))
.build();
context = engine.eval(loadSource("Truffle::Boot.context", "context")).as(RubyContext.class);
engine = new RubyEngine(instanceConfig);
}

@Override
public int execute(String path) {
if (!Graal.isGraal() && Options.TRUFFLE_GRAAL_WARNING_UNLESS.load()) {
System.err.println("WARNING: This JVM does not have the Graal compiler. " +
"JRuby+Truffle's performance without it will be limited. " +
"See https://github.com/jruby/jruby/wiki/Truffle-FAQ#how-do-i-get-jrubytruffle");
}

context.setOriginalInputFile(path);

return engine.eval(loadSource("Truffle::Boot.main", "main")).as(Integer.class);
return engine.execute(path);
}

@Override
public void dispose() {
engine.dispose();
}

@TruffleBoundary
private Source loadSource(String source, String name) {
return Source.newBuilder(source).name(name).mimeType(RubyLanguage.MIME_TYPE).build();
}

}
132 changes: 124 additions & 8 deletions truffle/src/main/java/org/jruby/truffle/Main.java
Original file line number Diff line number Diff line change
@@ -6,13 +6,50 @@
* Eclipse Public License version 1.0
* GNU General Public License version 2
* GNU Lesser General Public License version 2.1
*
* Version: EPL 1.0/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Eclipse Public
* License Version 1.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.eclipse.org/legal/epl-v10.html
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* Copyright (C) 2001 Alan Moore <alan_moore@gmx.net>
* Copyright (C) 2001-2002 Benoit Cerrina <b.cerrina@wanadoo.fr>
* Copyright (C) 2001-2004 Jan Arne Petersen <jpetersen@uni-bonn.de>
* Copyright (C) 2002-2004 Anders Bengtsson <ndrsbngtssn@yahoo.se>
* Copyright (C) 2004 Thomas E Enebo <enebo@acm.org>
* Copyright (C) 2004-2006 Charles O Nutter <headius@headius.com>
* Copyright (C) 2004 Stefan Matthias Aust <sma@3plus4.de>
* Copyright (C) 2005 Kiel Hodges <jruby-devel@selfsosoft.com>
* Copyright (C) 2005 Jason Voegele <jason@jvoegele.com>
* Copyright (C) 2005 Tim Azzopardi <tim@tigerfive.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the EPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the EPL, the GPL or the LGPL.
*/
package org.jruby.truffle;

import org.jruby.JRubyTruffleInterface;
import org.jruby.Ruby;
import org.jruby.RubyInstanceConfig;
import org.jruby.util.cli.OutputStrings;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;

public class Main {
@@ -22,16 +59,95 @@ public static void main(String[] args) {
config.setHardExit(true);
config.processArguments(args);

final InputStream in = config.getScriptSource();
final String filename = config.displayedFileName();
doShowVersion(config);
doShowCopyright(config);
doPrintProperties(config);

final int exitCode;

final JRubyTruffleInterface jrubyTruffle = new JRubyTruffleImpl(config);
if (config.getShouldRunInterpreter()) {
final InputStream in = config.getScriptSource();
final String filename = config.displayedFileName();

if (in != null) {
final int exitCode = jrubyTruffle.execute(filename);
System.exit(exitCode);
final RubyEngine rubyEngine = new RubyEngine(config);

try {
if (in == null) {
exitCode = 1;
} else if (config.isXFlag() && !config.hasShebangLine()) {
// no shebang was found and x option is set
config.getError().println("jruby: no Ruby script found in input (LoadError)");
exitCode = 1;
} else if (config.getShouldCheckSyntax()) {
// check syntax only and exit
exitCode = doCheckSyntax(rubyEngine, in, filename);
} else {
exitCode = rubyEngine.execute(filename);
}
} finally {
rubyEngine.dispose();
}
} else {
doPrintUsage(config, false);
exitCode = 1;
}

System.exit(exitCode);
}

private static void doPrintProperties(RubyInstanceConfig config) {
if (config.getShouldPrintProperties()) {
config.getOutput().print(OutputStrings.getPropertyHelp());
}
}

private static void doPrintUsage(RubyInstanceConfig config, boolean force) {
if (config.getShouldPrintUsage() || force) {
config.getOutput().print(OutputStrings.getBasicUsageHelp());
config.getOutput().print(OutputStrings.getFeaturesHelp());
}
}

private static void doShowCopyright(RubyInstanceConfig config) {
if (config.isShowCopyright()) {
config.getOutput().println(OutputStrings.getCopyrightString());
}
}

private static void doShowVersion(RubyInstanceConfig config) {
if (config.isShowVersion()) {
config.getOutput().println(OutputStrings.getVersionString());
}
}

private static int doCheckSyntax(RubyEngine engine, InputStream in, String filename) {
// check primary script
boolean status = checkStreamSyntax(engine, in, filename);

// check other scripts specified on argv
for (String arg : engine.getContext().getInstanceConfig().getArgv()) {
status = status && checkFileSyntax(engine, arg);
}

return status ? 0 : -1;
}

private static boolean checkFileSyntax(RubyEngine engine, String filename) {
File file = new File(filename);
if (file.exists()) {
try {
return checkStreamSyntax(engine, new FileInputStream(file), filename);
} catch (FileNotFoundException fnfe) {
engine.getContext().getInstanceConfig().getError().println("File not found: " + filename);
return false;
}
} else {
return false;
}
}

private static boolean checkStreamSyntax(RubyEngine engine, InputStream in, String filename) {
return engine.checkSyntax(in, filename);
}

}
11 changes: 11 additions & 0 deletions truffle/src/main/java/org/jruby/truffle/RubyContext.java
Original file line number Diff line number Diff line change
@@ -58,6 +58,7 @@

import java.io.File;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.net.URISyntaxException;
@@ -71,6 +72,8 @@ public class RubyContext extends ExecutionContext {
private final RubyInstanceConfig instanceConfig;
private final String jrubyHome;
private String originalInputFile;

private InputStream syntaxCheckInputStream;
private boolean verbose;

private final Options options = new Options();
@@ -445,4 +448,12 @@ public boolean warningsEnabled() {
public boolean isVerbose() {
return verbose;
}

public InputStream getSyntaxCheckInputStream() {
return syntaxCheckInputStream;
}

public void setSyntaxCheckInputStream(InputStream syntaxCheckInputStream) {
this.syntaxCheckInputStream = syntaxCheckInputStream;
}
}
67 changes: 67 additions & 0 deletions truffle/src/main/java/org/jruby/truffle/RubyEngine.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* Copyright (c) 2014, 2016 Oracle and/or its affiliates. All rights reserved. This
* code is released under a tri EPL/GPL/LGPL license. You can use it,
* redistribute it and/or modify it under the terms of the:
*
* Eclipse Public License version 1.0
* GNU General Public License version 2
* GNU Lesser General Public License version 2.1
*/
package org.jruby.truffle;

import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.source.Source;
import com.oracle.truffle.api.vm.PolyglotEngine;
import org.jruby.JRubyTruffleInterface;
import org.jruby.RubyInstanceConfig;
import org.jruby.truffle.interop.InstanceConfigWrapper;
import org.jruby.truffle.platform.graal.Graal;
import org.jruby.util.cli.Options;

import java.io.InputStream;

public class RubyEngine {

private final PolyglotEngine engine;
private final RubyContext context;

public RubyEngine(RubyInstanceConfig instanceConfig) {
engine = PolyglotEngine.newBuilder()
.globalSymbol(JRubyTruffleInterface.RUNTIME_SYMBOL, new InstanceConfigWrapper(instanceConfig))
.build();
context = engine.eval(loadSource("Truffle::Boot.context", "context")).as(RubyContext.class);
}

public int execute(String path) {
if (!Graal.isGraal() && Options.TRUFFLE_GRAAL_WARNING_UNLESS.load()) {
System.err.println("WARNING: This JVM does not have the Graal compiler. " +
"JRuby+Truffle's performance without it will be limited. " +
"See https://github.com/jruby/jruby/wiki/Truffle-FAQ#how-do-i-get-jrubytruffle");
}

context.setOriginalInputFile(path);

return engine.eval(loadSource("Truffle::Boot.main", "main")).as(Integer.class);
}

public boolean checkSyntax(InputStream in, String filename) {
context.setSyntaxCheckInputStream(in);
context.setOriginalInputFile(filename);

return engine.eval(loadSource("Truffle::Boot.check_syntax", "check_syntax")).as(Boolean.class);
}

public RubyContext getContext() {
return context;
}

public void dispose() {
engine.dispose();
}

@TruffleBoundary
private Source loadSource(String source, String name) {
return Source.newBuilder(source).name(name).mimeType(RubyLanguage.MIME_TYPE).build();
}

}
Original file line number Diff line number Diff line change
@@ -1695,6 +1695,7 @@ public Object getTruffleKernelModule() {
"/core/truffle/ffi/ffi_file.rb",
"/core/truffle/ffi/ffi_struct.rb",
"/core/truffle/support.rb",
"/core/truffle/boot.rb",
"/core/io.rb",
"/core/immediate.rb",
"/core/string_mirror.rb",
Original file line number Diff line number Diff line change
@@ -19,6 +19,7 @@
import com.oracle.truffle.api.source.Source;
import org.jcodings.specific.UTF8Encoding;
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.RubyLanguage;
import org.jruby.truffle.builtins.CoreClass;
import org.jruby.truffle.builtins.CoreMethod;
import org.jruby.truffle.builtins.CoreMethodArrayArgumentsNode;
@@ -29,9 +30,12 @@
import org.jruby.truffle.language.loader.SourceLoader;
import org.jruby.truffle.language.methods.DeclarationContext;
import org.jruby.truffle.parser.ParserContext;
import org.jruby.truffle.parser.TranslatorDriver;
import org.jruby.util.Memo;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.List;

@CoreClass("Truffle::Boot")
@@ -180,4 +184,30 @@ public DynamicObject sourceOfCaller() {

}

@CoreMethod(names = "inner_check_syntax", onSingleton = true)
public abstract static class InnerCheckSyntaxNode extends CoreMethodArrayArgumentsNode {

@TruffleBoundary
@Specialization
public DynamicObject innerCheckSyntax() {
final String inputFile = getContext().getOriginalInputFile();
final InputStream inputStream = getContext().getSyntaxCheckInputStream();

final Source source;

try {
source = Source.newBuilder(new InputStreamReader(inputStream)).name(inputFile).mimeType(RubyLanguage.MIME_TYPE).build();
} catch (IOException e) {
throw new JavaException(e);
}

final TranslatorDriver translator = new TranslatorDriver(getContext());

translator.parse(getContext(), source, UTF8Encoding.INSTANCE,
ParserContext.TOP_LEVEL, new String[]{}, null, null, true, null);

return nil();
}
}

}
23 changes: 23 additions & 0 deletions truffle/src/main/ruby/core/truffle/boot.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved. This
# code is released under a tri EPL/GPL/LGPL license. You can use it,
# redistribute it and/or modify it under the terms of the:
#
# Eclipse Public License version 1.0
# GNU General Public License version 2
# GNU Lesser General Public License version 2.1

module Truffle
module Boot

def self.check_syntax
inner_check_syntax
STDOUT.puts 'Syntax OK'
true
rescue SyntaxError => e
STDERR.puts "SyntaxError in #{e.message}"
false
end

end
end