Skip to content

Commit

Permalink
Showing 20 changed files with 638 additions and 2,797 deletions.
24 changes: 21 additions & 3 deletions truffle/src/main/java/org/jruby/truffle/core/TruffleGCNodes.java
Original file line number Diff line number Diff line change
@@ -12,11 +12,13 @@
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.TruffleOptions;
import com.oracle.truffle.api.dsl.Specialization;
import org.jruby.RubyGC;
import org.jruby.truffle.builtins.CoreClass;
import org.jruby.truffle.builtins.CoreMethod;
import org.jruby.truffle.builtins.CoreMethodArrayArgumentsNode;

import java.lang.management.GarbageCollectorMXBean;
import java.lang.management.ManagementFactory;

@CoreClass("Truffle::GC")
public abstract class TruffleGCNodes {

@@ -30,7 +32,15 @@ public int count() {
throw new UnsupportedOperationException("Memory manager is not available with AOT.");
}

return RubyGC.getCollectionCount();
return getCollectionCount();
}

public static int getCollectionCount() {
int count = 0;
for (GarbageCollectorMXBean bean : ManagementFactory.getGarbageCollectorMXBeans()) {
count += bean.getCollectionCount();
}
return count;
}

}
@@ -45,7 +55,15 @@ public long time() {
throw new UnsupportedOperationException("Memory manager is not available with AOT.");
}

return RubyGC.getCollectionTime();
return getCollectionTime();
}

public static long getCollectionTime() {
long time = 0;
for (GarbageCollectorMXBean bean : ManagementFactory.getGarbageCollectorMXBeans()) {
time += bean.getCollectionTime();
}
return time;
}

}
Original file line number Diff line number Diff line change
@@ -6,6 +6,35 @@
* 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) 2002-2004 Anders Bengtsson <ndrsbngtssn@yahoo.se>
* Copyright (C) 2004 Stefan Matthias Aust <sma@3plus4.de>
* Copyright (C) 2005 Charles O Nutter <headius@headius.com>
* Copyright (C) 2006 Nick Sieger
*
* 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.core;

@@ -15,14 +44,15 @@
import com.oracle.truffle.api.object.DynamicObject;
import org.jcodings.Encoding;
import org.jcodings.specific.UTF8Encoding;
import org.jruby.ext.rbconfig.RbConfigLibrary;
import org.jruby.truffle.builtins.CoreClass;
import org.jruby.truffle.builtins.CoreMethod;
import org.jruby.truffle.builtins.CoreMethodNode;
import org.jruby.truffle.builtins.YieldingCoreMethodNode;
import org.jruby.truffle.core.string.StringOperations;
import org.jruby.util.unsafe.UnsafeHolder;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

@CoreClass("Truffle::System")
@@ -52,7 +82,7 @@ public abstract static class HostCPUNode extends CoreMethodNode {

@Specialization
public DynamicObject hostCPU() {
return createString(StringOperations.encodeRope(RbConfigLibrary.getArchitecture(), UTF8Encoding.INSTANCE));
return createString(StringOperations.encodeRope(org.jruby.truffle.util.Platform.getArchitecture(), UTF8Encoding.INSTANCE));
}

}
@@ -63,7 +93,7 @@ public abstract static class HostOSNode extends CoreMethodNode {
@TruffleBoundary
@Specialization
public DynamicObject hostOS() {
return createString(StringOperations.encodeRope(RbConfigLibrary.getOSName(), UTF8Encoding.INSTANCE));
return createString(StringOperations.encodeRope(org.jruby.truffle.util.Platform.getOSName(), UTF8Encoding.INSTANCE));
}

}
450 changes: 2 additions & 448 deletions truffle/src/main/java/org/jruby/truffle/core/string/StringSupport.java

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -28,12 +28,10 @@
***** END LICENSE BLOCK *****/
package org.jruby.truffle.options;

import org.jruby.exceptions.MainExitException;
import org.jruby.truffle.core.string.StringSupport;
import org.jruby.util.FileResource;
import org.jruby.util.JRubyFile;
import org.jruby.util.SafePropertyAccessor;
import org.jruby.util.cli.OutputStrings;
import org.jruby.util.func.Function2;

import java.io.File;
@@ -201,9 +199,10 @@ private void processArgument() {
//config.setRecordSeparator(String.valueOf((char) val));
throw new UnsupportedOperationException();
} catch (Exception e) {
MainExitException mee = new MainExitException(1, getArgumentError(" -0 must be followed by either 0, 777, or a valid octal value"));
mee.setUsageError(true);
throw mee;
//MainExitException mee = new MainExitException(1, getArgumentError(" -0 must be followed by either 0, 777, or a valid octal value"));
//mee.setUsageError(true);
//throw mee;
throw new UnsupportedOperationException();
}
}
//break FOR;
@@ -230,10 +229,12 @@ private void processArgument() {
config.setCurrentDirectory(new File(base, newDir.getPath()).getCanonicalPath());
}
if (!(new File(config.getCurrentDirectory()).isDirectory()) && !config.getCurrentDirectory().startsWith("uri:classloader:")) {
throw new MainExitException(1, "jruby: Can't chdir to " + saved + " (fatal)");
//throw new MainExitException(1, "jruby: Can't chdir to " + saved + " (fatal)");
throw new UnsupportedOperationException();
}
} catch (IOException e) {
throw new MainExitException(1, getArgumentError(" -C must be followed by a valid directory"));
//throw new MainExitException(1, getArgumentError(" -C must be followed by a valid directory"));
throw new UnsupportedOperationException();
}
break FOR;
case 'd':
@@ -340,9 +341,10 @@ private void processArgument() {
} else if (temp.equals("2")) {
config.setVerbosity(Verbosity.TRUE);
} else {
MainExitException mee = new MainExitException(1, getArgumentError(" -W must be followed by either 0, 1, 2 or nothing"));
mee.setUsageError(true);
throw mee;
//MainExitException mee = new MainExitException(1, getArgumentError(" -W must be followed by either 0, 1, 2 or nothing"));
//mee.setUsageError(true);
//throw mee;
throw new UnsupportedOperationException();
}
}
break FOR;
@@ -362,29 +364,34 @@ private void processArgument() {
config.setCurrentDirectory(new File(base, newDir.getPath()).getCanonicalPath());
}
if (!(new File(config.getCurrentDirectory()).isDirectory()) && !config.getCurrentDirectory().startsWith("uri:classloader:")) {
throw new MainExitException(1, "jruby: Can't chdir to " + saved + " (fatal)");
//throw new MainExitException(1, "jruby: Can't chdir to " + saved + " (fatal)");
throw new UnsupportedOperationException();
}
}
config.setXFlag(true);
} catch (IOException e) {
throw new MainExitException(1, getArgumentError(" -x must be followed by a valid directory"));
//throw new MainExitException(1, getArgumentError(" -x must be followed by a valid directory"));
throw new UnsupportedOperationException();
}
break FOR;
case 'X':
disallowedInRubyOpts(argument);
String extendedOption = grabOptionalValue();
if (extendedOption == null) {
if (SafePropertyAccessor.getBoolean("jruby.launcher.nopreamble", false)) {
throw new MainExitException(0, OutputStrings.getExtendedHelp());
//throw new MainExitException(0, OutputStrings.getExtendedHelp());
throw new UnsupportedOperationException();
} else {
throw new MainExitException(0, "jruby: missing argument\n" + OutputStrings.getExtendedHelp());
//throw new MainExitException(0, "jruby: missing argument\n" + OutputStrings.getExtendedHelp());
throw new UnsupportedOperationException();
}
} else if (extendedOption.equals("-C") || extendedOption.equals("-CIR")) {
config.setCompileMode(org.jruby.RubyInstanceConfig.CompileMode.OFF);
} else if (extendedOption.equals("+C") || extendedOption.equals("+CIR")) {
config.setCompileMode(org.jruby.RubyInstanceConfig.CompileMode.FORCE);
} else if (extendedOption.equals("classic")) {
throw new MainExitException(0, "jruby: the -Xclassic option should have been handled in the launcher");
//throw new MainExitException(0, "jruby: the -Xclassic option should have been handled in the launcher");
throw new UnsupportedOperationException();
} else if (extendedOption.equals("+T") || extendedOption.equals("+TM")) {
org.jruby.util.cli.Options.PARSER_WARN_GROUPED_EXPRESSIONS.force(Boolean.FALSE.toString());
config.setCompileMode(org.jruby.RubyInstanceConfig.CompileMode.TRUFFLE);
@@ -397,9 +404,10 @@ private void processArgument() {
org.jruby.util.cli.Options.listContains(extendedOption.substring(0, extendedOption.length() - 1));
config.setShouldRunInterpreter(false);
} else {
MainExitException mee = new MainExitException(1, "jruby: invalid extended option " + extendedOption + " (-X will list valid options)\n");
mee.setUsageError(true);
throw mee;
//MainExitException mee = new MainExitException(1, "jruby: invalid extended option " + extendedOption + " (-X will list valid options)\n");
//mee.setUsageError(true);
//throw mee;
throw new UnsupportedOperationException();
}
break FOR;
case 'y':
@@ -499,9 +507,10 @@ private void processArgument() {
} else if (dumpArg.equals("insns")) {
config.setShowBytecode(true);
} else {
MainExitException mee = new MainExitException(1, error);
mee.setUsageError(true);
throw mee;
//MainExitException mee = new MainExitException(1, error);
//mee.setUsageError(true);
//throw mee;
throw new UnsupportedOperationException();
}
break;
} else if (argument.equals("--dev")) {
@@ -527,7 +536,8 @@ private void processArgument() {
}
}
default:
throw new MainExitException(1, "jruby: unknown option " + argument);
//throw new MainExitException(1, "jruby: unknown option " + argument);
throw new UnsupportedOperationException();
}
}
}
@@ -553,22 +563,25 @@ private static String[] valueListFor(String argument, String key) {

private void disallowedInRubyOpts(CharSequence option) {
if (rubyOpts) {
throw new MainExitException(1, "jruby: invalid switch in RUBYOPT: " + option + " (RuntimeError)");
//throw new MainExitException(1, "jruby: invalid switch in RUBYOPT: " + option + " (RuntimeError)");
throw new UnsupportedOperationException();
}
}

private static void errorMissingEquals(String label) {
MainExitException mee;
mee = new MainExitException(1, "missing argument for --" + label + "\n");
mee.setUsageError(true);
throw mee;
//MainExitException mee;
//mee = new MainExitException(1, "missing argument for --" + label + "\n");
//mee.setUsageError(true);
//throw mee;
throw new UnsupportedOperationException();
}

private void processEncodingOption(String value) {
List<String> encodings = StringSupport.split(value, ':', 3);
switch (encodings.size()) {
case 3:
throw new MainExitException(1, "extra argument for -E: " + encodings.get(2));
//throw new MainExitException(1, "extra argument for -E: " + encodings.get(2));
throw new UnsupportedOperationException();
case 2:
config.setInternalEncoding(encodings.get(1));
case 1:
@@ -665,9 +678,10 @@ private String grabValue(String errorMessage, boolean usageError) {
if (argumentIndex < arguments.size()) {
return arguments.get(argumentIndex).originalValue;
}
MainExitException mee = new MainExitException(1, errorMessage);
if (usageError) mee.setUsageError(true);
throw mee;
//MainExitException mee = new MainExitException(1, errorMessage);
//if (usageError) mee.setUsageError(true);
//throw mee;
throw new UnsupportedOperationException();
}

private String grabOptionalValue() {
Original file line number Diff line number Diff line change
@@ -26,8 +26,8 @@
package org.jruby.truffle.options;

import com.headius.options.Option;
import org.jruby.ext.rbconfig.RbConfigLibrary;
import org.jruby.runtime.Constants;
import org.jruby.truffle.util.Constants;
import org.jruby.truffle.util.Platform;
import org.jruby.util.SafePropertyAccessor;
import org.jruby.util.cli.Options;

@@ -154,8 +154,8 @@ public static String getVersionString() {
SafePropertyAccessor.getProperty("java.runtime.version", SafePropertyAccessor.getProperty("java.version", "Unknown version")),
org.jruby.util.cli.Options.COMPILE_INVOKEDYNAMIC.load() ? " +indy" : "",
Options.COMPILE_MODE.load().shouldJIT() ? " +jit" : "",
RbConfigLibrary.getOSName(),
RbConfigLibrary.getArchitecture()
Platform.getOSName(),
Platform.getArchitecture()
);
}

Original file line number Diff line number Diff line change
@@ -29,12 +29,8 @@
package org.jruby.truffle.options;

import jnr.posix.util.Platform;
import org.jruby.CompatVersion;
import org.jruby.Profile;
import org.jruby.RubyFile;
import org.jruby.exceptions.MainExitException;
import org.jruby.runtime.Constants;
import org.jruby.truffle.core.string.StringSupport;
import org.jruby.truffle.language.control.JavaException;
import org.jruby.util.ClasspathLauncher;
import org.jruby.util.FileResource;
import org.jruby.util.InputStreamMarkCursor;
@@ -145,6 +141,10 @@ protected static boolean isRubyShebangLine(String line) {
return RUBY_SHEBANG.matcher(line).matches();
}

private static final String URI_PREFIX_STRING = "^(uri|jar|file|classpath):([^:/]{2,}:([^:/]{2,}:)?)?";
private static final Pattern ROOT_PATTERN = Pattern.compile(URI_PREFIX_STRING + "/?/?$");
public static Pattern PROTOCOL_PATTERN = Pattern.compile(URI_PREFIX_STRING + ".*");

private String calculateJRubyHome() {
String newJRubyHome = null;

@@ -176,7 +176,7 @@ private String calculateJRubyHome() {
// RegularFileResource absolutePath will canonicalize resources so that will change c: paths to C:.
// We will cannonicalize on windows so that jruby.home is also C:.
// assume all those uri-like pathnames are already in absolute form
if (Platform.IS_WINDOWS && !RubyFile.PROTOCOL_PATTERN.matcher(newJRubyHome).matches()) {
if (Platform.IS_WINDOWS && !PROTOCOL_PATTERN.matcher(newJRubyHome).matches()) {
try {
newJRubyHome = new File(newJRubyHome).getCanonicalPath();
}
@@ -253,7 +253,7 @@ public InputStream getScriptSource() {
}
}
} catch (IOException e) {
throw new MainExitException(1, "Error opening script file: " + e.getMessage());
throw new JavaException(e);
}
}

@@ -315,11 +315,6 @@ public InputStream getInput() {
return input;
}

@Deprecated
public CompatVersion getCompatVersion() {
return CompatVersion.RUBY2_1;
}

public void setOutput(PrintStream newOutput) {
output = newOutput;
}
@@ -344,14 +339,6 @@ public String getCurrentDirectory() {
return currentDirectory;
}

public void setProfile(Profile newProfile) {
profile = newProfile;
}

public Profile getProfile() {
return profile;
}

public void setEnvironment(Map<String, String> newEnvironment) {
environment = new HashMap<String, String>();
if (newEnvironment != null) {
@@ -361,7 +348,7 @@ public void setEnvironment(Map<String, String> newEnvironment) {
}

private void setupEnvironment(String jrubyHome) {
if (RubyFile.PROTOCOL_PATTERN.matcher(jrubyHome).matches() && !environment.containsKey("RUBY")) {
if (PROTOCOL_PATTERN.matcher(jrubyHome).matches() && !environment.containsKey("RUBY")) {
// the assumption that if JRubyHome is not a regular file that jruby
// got launched in an embedded fashion
environment.put("RUBY", ClasspathLauncher.jrubyCommand(defaultClassLoader()));
@@ -708,7 +695,6 @@ public static ClassLoader defaultClassLoader() {
private InputStream input = System.in;
private PrintStream output = System.out;
private PrintStream error = System.err;
private Profile profile = Profile.DEFAULT;

private org.jruby.RubyInstanceConfig.CompileMode compileMode = org.jruby.RubyInstanceConfig.CompileMode.OFF;
private String currentDirectory;
@@ -865,30 +851,6 @@ public boolean isxFlag() {
return xFlag;
}

/**
* The max count of active methods eligible for JIT-compilation.
*/
@Deprecated
public static final int JIT_MAX_METHODS_LIMIT = Constants.JIT_MAX_METHODS_LIMIT;

/**
* The max size of JIT-compiled methods (full class size) allowed.
*/
@Deprecated
public static final int JIT_MAX_SIZE_LIMIT = Constants.JIT_MAX_SIZE_LIMIT;

/**
* The JIT threshold to the specified method invocation count.
*/
@Deprecated
public static final int JIT_THRESHOLD = Constants.JIT_THRESHOLD;

/**
* Default size for chained compilation.
*/
@Deprecated
public static final int CHAINED_COMPILE_LINE_COUNT_DEFAULT = Constants.CHAINED_COMPILE_LINE_COUNT_DEFAULT;

@Deprecated
public static final boolean nativeEnabled = NATIVE_ENABLED;

135 changes: 78 additions & 57 deletions truffle/src/main/java/org/jruby/truffle/parser/RubyWarnings.java
Original file line number Diff line number Diff line change
@@ -12,6 +12,9 @@
* rights and limitations under the License.
*
* Copyright (C) 2004 Jan Arne Petersen <jpetersen@uni-bonn.de>
* Copyright (C) 2002-2004 Anders Bengtsson <ndrsbngtssn@yahoo.se>
* Copyright (C) 2002-2004 Jan Arne Petersen <jpetersen@uni-bonn.de>
* Copyright (C) 2004 Thomas E Enebo <enebo@acm.org>
*
* 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"),
@@ -28,11 +31,7 @@
package org.jruby.truffle.parser;

import org.joni.WarnCallback;
import org.jruby.Ruby;
import org.jruby.common.IRubyWarnings;
import org.jruby.lexer.yacc.ISourcePosition;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.backtrace.RubyStackTraceElement;
import org.jruby.truffle.parser.lexer.ISourcePosition;
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.debug.DebugHelpers;

@@ -42,7 +41,78 @@
/**
*
*/
public class RubyWarnings implements IRubyWarnings, WarnCallback {
public class RubyWarnings implements WarnCallback {

public enum ID {
AMBIGUOUS_ARGUMENT,
ACCESSOR_NOT_INITIALIZED,
ACCESSOR_MODULE_FUNCTION,
ARGUMENT_AS_PREFIX,
ARGUMENT_EXTRA_SPACE,
ASSIGNMENT_IN_CONDITIONAL,
BIGNUM_FROM_FLOAT_RANGE,
BLOCK_BEATS_DEFAULT_VALUE,
BLOCK_NOT_ACCEPTED,
BLOCK_UNUSED,
CONSTANT_ALREADY_INITIALIZED,
CONSTANT_DEPRECATED,
CONSTANT_BAD_REFERENCE,
CVAR_FROM_TOPLEVEL_SINGLETON_METHOD,
DECLARING_SCLASS_VARIABLE,
DEPRECATED_METHOD,
DUMMY_VALUE_USED,
END_IN_METHOD,
ELSE_WITHOUT_RESCUE,
EMPTY_IMPLEMENTATION,
ENV_VARS_FROM_CLI_METHOD,
FIXNUMS_NOT_SYMBOLS,
FLOAT_OUT_OF_RANGE,
GLOBAL_NOT_INITIALIZED,
GROUPED_EXPRESSION,
INEFFECTIVE_GLOBAL,
INVALID_CHAR_SEQUENCE,
IVAR_NOT_INITIALIZED,
MAY_BE_TOO_BIG,
MISCELLANEOUS,
MULTIPLE_VALUES_FOR_BLOCK,
NEGATIVE_NUMBER_FOR_U,
NO_SUPER_CLASS,
NOT_IMPLEMENTED,
OBSOLETE_ARGUMENT,
PARENTHISE_ARGUMENTS,
PROXY_EXTENDED_LATE,
STATEMENT_NOT_REACHED,
LITERAL_IN_CONDITIONAL_RANGE,
REDEFINING_DANGEROUS,
REGEXP_IGNORED_FLAGS,
REGEXP_LITERAL_IN_CONDITION,
REGEXP_MATCH_AGAINST_STRING,
SAFE_NOT_SUPPORTED,
STRUCT_CONSTANT_REDEFINED,
SYMBOL_AS_INTEGER,
SYSSEEK_BUFFERED_IO,
SYSWRITE_BUFFERED_IO,
SWALLOWED_IO_EXCEPTION,
TOO_MANY_ARGUMENTS,
UNDEFINING_BAD,
USELESS_EXPRESSION,
VOID_VALUE_EXPRESSION,
NAMED_CAPTURE_CONFLICT,
NON_PERSISTENT_JAVA_PROXY,
LISTEN_SERVER_SOCKET,
PROFILE_MAX_METHODS_EXCEEDED,
UNSUPPORTED_SUBPROCESS_OPTION,
GC_STRESS_UNIMPLEMENTED,
GC_ENABLE_UNIMPLEMENTED,
GC_DISABLE_UNIMPLEMENTED,
TRUFFLE,
RATIONAL_OUT_OF_RANGE,; // TODO(CS): divide up the Truffle warnings

public String getID() {
return name();
}
}

private final RubyContext runtime;
private final Set<ID> oncelers = EnumSet.allOf(ID.class);

@@ -55,20 +125,13 @@ public void warn(String message) {
warn(ID.MISCELLANEOUS, message);
}

@Override
public Ruby getRuntime() {
throw new UnsupportedOperationException();
}

@Override
public boolean isVerbose() {
return runtime.isVerbose();
}

/**
* Prints a warning, unless $VERBOSE is nil.
*/
@Override
public void warn(ID id, ISourcePosition position, String message) {
if (!runtime.warningsEnabled()) return;

@@ -79,7 +142,6 @@ public void warn(ID id, ISourcePosition position, String message) {
* Prints a warning, unless $VERBOSE is nil.
*/
@SuppressWarnings("deprecation")
@Override
public void warn(ID id, String fileName, int lineNumber, String message) {
if (!runtime.warningsEnabled()) return;

@@ -94,7 +156,6 @@ public void warn(ID id, String fileName, int lineNumber, String message) {
* Prints a warning, unless $VERBOSE is nil.
*/
@SuppressWarnings("deprecation")
@Override
public void warn(ID id, String fileName, String message) {
if (!runtime.warningsEnabled()) return;

@@ -105,23 +166,10 @@ public void warn(ID id, String fileName, String message) {
DebugHelpers.eval(runtime, "$stderr.write Truffle::Interop.from_java_string(message)", "message", buffer.toString());
}

@Override
public void warn(ID id, String message) {
if (!runtime.warningsEnabled()) return;

RubyStackTraceElement[] stack = new RubyStackTraceElement[]{}; //getRubyStackTrace(runtime);
String file;
int line;

if (stack.length == 0) {
file = "(unknown)";
line = -1;
} else {
file = stack[0].getFileName();
line = stack[0].getLineNumber();
}

warn(id, file, line, message);
throw new UnsupportedOperationException();
}

public void warnOnce(ID id, String message) {
@@ -140,50 +188,23 @@ public void warning(String message) {
if (!isVerbose()) return;
if (!runtime.warningsEnabled()) return;

warning(ID.MISCELLANEOUS, message);
}

@Override
public void warning(ID id, String message) {
if (!runtime.warningsEnabled() || !runtime.isVerbose()) return;

RubyStackTraceElement[] stack = new RubyStackTraceElement[]{};//getRubyStackTrace(runtime);
String file;
int line;

if (stack.length == 0) {
file = "(unknown)";
line = -1;
} else {
file = stack[0].getFileName();
line = stack[0].getLineNumber();
}

warning(id, file, line, message);
throw new UnsupportedOperationException();
}

/**
* Prints a warning, only in verbose mode.
*/
@Override
public void warning(ID id, ISourcePosition position, String message) {
warning(id, position.getFile(), position.getLine() + 1, message);
}

/**
* Prints a warning, only in verbose mode.
*/
@Override
public void warning(ID id, String fileName, int lineNumber, String message) {
if (!runtime.warningsEnabled() || !runtime.isVerbose()) return;

warn(id, fileName, lineNumber, message);
}

private static RubyStackTraceElement[] getRubyStackTrace(Ruby runtime) {
ThreadContext context = runtime.getCurrentContext();
RubyStackTraceElement[] stack = context.createWarningBacktrace(runtime);

return stack;
}
}
Original file line number Diff line number Diff line change
@@ -30,12 +30,7 @@
import org.jcodings.specific.ASCIIEncoding;
import org.jcodings.specific.USASCIIEncoding;
import org.jcodings.specific.UTF8Encoding;
import org.joni.Matcher;
import org.joni.Option;
import org.joni.Regex;
import org.jruby.Ruby;
import org.jruby.RubyEncoding;
import org.jruby.truffle.core.regexp.ClassicRegexp;
import org.jruby.truffle.core.string.StringSupport;
import org.jruby.util.ByteList;

@@ -131,11 +126,7 @@ public String createAsEncodedString(byte[] bytes, int start, int length, Encodin
try {
Charset charset = getEncoding().getCharset();
if (charset != null) {
if (charset == RubyEncoding.UTF8) {
return RubyEncoding.decodeUTF8(bytes, start, length);
} else {
return new String(bytes, start, length, charset);
}
return new String(bytes, start, length, charset);
}
} catch (UnsupportedCharsetException e) {}

@@ -830,43 +821,4 @@ public static int magicCommentMarker(ByteList str, int begin) {
public static final String magicString = "^[^\\S]*([^\\s\'\":;]+)\\s*:\\s*(\"(?:\\\\.|[^\"])*\"|[^\"\\s;]+)[\\s;]*[^\\S]*$";
public static final Regex magicRegexp = new Regex(magicString.getBytes(), 0, magicString.length(), 0, Encoding.load("ASCII"));


// MRI: parser_magic_comment
public boolean parseMagicComment(Ruby runtime, ByteList magicLine) throws IOException {
int length = magicLine.length();

if (length <= 7) return false;
int beg = magicCommentMarker(magicLine, 0);
if (beg >= 0) {
int end = magicCommentMarker(magicLine, beg);
if (end < 0) return false;
length = end - beg - 3; // -3 is to backup over end just found
} else {
beg = 0;
}

int begin = magicLine.getBegin() + beg;
Matcher matcher = magicRegexp.matcher(magicLine.unsafeBytes(), begin, begin + length);
int result = ClassicRegexp.matcherSearch(matcher, begin, begin + length, Option.NONE);

if (result < 0) return false;

// Regexp is guaranteed to have three matches
int begs[] = matcher.getRegion().beg;
int ends[] = matcher.getRegion().end;
String name = magicLine.subSequence(beg + begs[1], beg + ends[1]).toString().replace('-', '_');
ByteList value = magicLine.makeShared(beg + begs[2], ends[2] - begs[2]);

if ("coding".equals(name) || "encoding".equals(name)) {
magicCommentEncoding(value);
} else if ("frozen_string_literal".equals(name)) {
setCompileOptionFlag(name, value);
} else if ("warn_indent".equals(name)) {
setTokenInfo(name, value);
} else {
return false;
}

return true;
}
}
33 changes: 16 additions & 17 deletions truffle/src/main/java/org/jruby/truffle/parser/lexer/RubyLexer.java
Original file line number Diff line number Diff line change
@@ -46,13 +46,12 @@
import org.jcodings.Encoding;
import org.joni.Matcher;
import org.joni.Option;
import org.jruby.common.IRubyWarnings;
import org.jruby.common.IRubyWarnings.ID;
import org.jruby.truffle.Layouts;
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.core.regexp.ClassicRegexp;
import org.jruby.truffle.core.string.StringSupport;
import org.jruby.truffle.language.control.RaiseException;
import org.jruby.truffle.parser.RubyWarnings;
import org.jruby.truffle.parser.ast.BackRefParseNode;
import org.jruby.truffle.parser.ast.BignumParseNode;
import org.jruby.truffle.parser.ast.ComplexParseNode;
@@ -145,8 +144,8 @@ private ComplexParseNode newComplexNode(NumericParseNode number) {
}

protected void ambiguousOperator(String op, String syn) {
warnings.warn(ID.AMBIGUOUS_ARGUMENT, getPosition().getFile(), getPosition().getLine(), "`" + op + "' after local variable or literal is interpreted as binary operator");
warnings.warn(ID.AMBIGUOUS_ARGUMENT, getPosition().getFile(), getPosition().getLine(), "even though it seems like " + syn);
warnings.warn(RubyWarnings.ID.AMBIGUOUS_ARGUMENT, getPosition().getFile(), getPosition().getLine(), "`" + op + "' after local variable or literal is interpreted as binary operator");
warnings.warn(RubyWarnings.ID.AMBIGUOUS_ARGUMENT, getPosition().getFile(), getPosition().getLine(), "even though it seems like " + syn);
}

public enum Keyword {
@@ -213,7 +212,7 @@ public static Keyword getKeyword(String str) {
private ParserSupport parserSupport = null;

// What handles warnings
private IRubyWarnings warnings;
private RubyWarnings warnings;

public int tokenize_ident(int result) {
// FIXME: Get token from newtok index to lex_p?
@@ -229,7 +228,7 @@ public int tokenize_ident(int result) {

private StrTerm lex_strterm;

public RubyLexer(ParserSupport support, LexerSource source, IRubyWarnings warnings) {
public RubyLexer(ParserSupport support, LexerSource source, RubyWarnings warnings) {
super(source);
this.parserSupport = support;
this.warnings = warnings;
@@ -290,7 +289,7 @@ public int nextc() {
c = '\n';
} else if (ruby_sourceline > last_cr_line) {
last_cr_line = ruby_sourceline;
warnings.warn(ID.VOID_VALUE_EXPRESSION, getFile(), ruby_sourceline, "encountered \\r in middle of line, treated as a mere space");
warnings.warn(RubyWarnings.ID.VOID_VALUE_EXPRESSION, getFile(), ruby_sourceline, "encountered \\r in middle of line, treated as a mere space");
c = ' ';
}
}
@@ -372,7 +371,7 @@ public void setParserSupport(ParserSupport parserSupport) {
@Override
protected void setCompileOptionFlag(String name, ByteList value) {
if (tokenSeen) {
warnings.warn(ID.ACCESSOR_MODULE_FUNCTION, "`" + name + "' is ignored after any tokens");
warnings.warn(RubyWarnings.ID.ACCESSOR_MODULE_FUNCTION, "`" + name + "' is ignored after any tokens");
return;
}

@@ -393,7 +392,7 @@ protected int asTruth(String name, ByteList value) {
result = value.caseInsensitiveCmp(FALSE);
if (result == 0) return 0;

warnings.warn(ID.ACCESSOR_MODULE_FUNCTION, "invalid value for " + name + ": " + value);
warnings.warn(RubyWarnings.ID.ACCESSOR_MODULE_FUNCTION, "invalid value for " + name + ": " + value);
return -1;
}

@@ -420,7 +419,7 @@ public void setStrTerm(StrTerm strterm) {
this.lex_strterm = strterm;
}

public void setWarnings(IRubyWarnings warnings) {
public void setWarnings(RubyWarnings warnings) {
this.warnings = warnings;
}

@@ -452,7 +451,7 @@ private int getFloatToken(String number, int suffix) {
try {
d = SafeDoubleParser.parseDouble(number);
} catch (NumberFormatException e) {
warnings.warn(ID.FLOAT_OUT_OF_RANGE, getPosition().getFile(), getPosition().getLine(), "Float " + number + " out of range.");
warnings.warn(RubyWarnings.ID.FLOAT_OUT_OF_RANGE, getPosition().getFile(), getPosition().getLine(), "Float " + number + " out of range.");

d = number.startsWith("-") ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY;
}
@@ -667,7 +666,7 @@ private int hereDocumentIdentifier() throws IOException {

private boolean arg_ambiguous() {
if (warnings.isVerbose() && Options.PARSER_WARN_AMBIGUOUS_ARGUMENTS.load() && !parserSupport.skipTruffleRubiniusWarnings(this)) {
warnings.warning(ID.AMBIGUOUS_ARGUMENT, getPosition().getFile(), getPosition().getLine(), "Ambiguous first argument; make sure.");
warnings.warning(RubyWarnings.ID.AMBIGUOUS_ARGUMENT, getPosition().getFile(), getPosition().getLine(), "Ambiguous first argument; make sure.");
}
return true;
}
@@ -1106,7 +1105,7 @@ private int ampersand(boolean spaceSeen) throws IOException {
ISourcePosition tmpPosition = getPosition();
if (isSpaceArg(c, spaceSeen)) {
if (warnings.isVerbose() && Options.PARSER_WARN_ARGUMENT_PREFIX.load())
warnings.warning(ID.ARGUMENT_AS_PREFIX, tmpPosition.getFile(), tmpPosition.getLine(), "`&' interpreted as argument prefix");
warnings.warning(RubyWarnings.ID.ARGUMENT_AS_PREFIX, tmpPosition.getFile(), tmpPosition.getLine(), "`&' interpreted as argument prefix");
c = Tokens.tAMPER;
} else if (isBEG()) {
c = Tokens.tAMPER;
@@ -1402,7 +1401,7 @@ private int dollar() throws IOException {
try {
ref = Integer.parseInt(refAsString.substring(1).intern());
} catch (NumberFormatException e) {
warnings.warn(ID.AMBIGUOUS_ARGUMENT, "`" + refAsString + "' is too big for a number variable, always nil");
warnings.warn(RubyWarnings.ID.AMBIGUOUS_ARGUMENT, "`" + refAsString + "' is too big for a number variable, always nil");
ref = 0;
}

@@ -1955,7 +1954,7 @@ private int questionMark() throws IOException {
break;
}
if (c2 != 0) {
warnings.warn(ID.INVALID_CHAR_SEQUENCE, getPosition().getFile(), getPosition().getLine(), "invalid character syntax; use ?\\" + c2);
warnings.warn(RubyWarnings.ID.INVALID_CHAR_SEQUENCE, getPosition().getFile(), getPosition().getLine(), "invalid character syntax; use ?\\" + c2);
}
}
pushback(c);
@@ -2085,7 +2084,7 @@ private int star(boolean spaceSeen) throws IOException {

if (isSpaceArg(c, spaceSeen)) {
if (warnings.isVerbose() && Options.PARSER_WARN_ARGUMENT_PREFIX.load())
warnings.warning(ID.ARGUMENT_AS_PREFIX, getPosition().getFile(), getPosition().getLine(), "`**' interpreted as argument prefix");
warnings.warning(RubyWarnings.ID.ARGUMENT_AS_PREFIX, getPosition().getFile(), getPosition().getLine(), "`**' interpreted as argument prefix");
c = Tokens.tDSTAR;
} else if (isBEG()) {
c = Tokens.tDSTAR;
@@ -2102,7 +2101,7 @@ private int star(boolean spaceSeen) throws IOException {
pushback(c);
if (isSpaceArg(c, spaceSeen)) {
if (warnings.isVerbose() && Options.PARSER_WARN_ARGUMENT_PREFIX.load() && !parserSupport.skipTruffleRubiniusWarnings(this))
warnings.warning(ID.ARGUMENT_AS_PREFIX, getPosition().getFile(), getPosition().getLine(), "`*' interpreted as argument prefix");
warnings.warning(RubyWarnings.ID.ARGUMENT_AS_PREFIX, getPosition().getFile(), getPosition().getLine(), "`*' interpreted as argument prefix");
c = Tokens.tSTAR;
} else if (isBEG()) {
c = Tokens.tSTAR;
Original file line number Diff line number Diff line change
@@ -31,8 +31,7 @@
***** END LICENSE BLOCK *****/
package org.jruby.truffle.parser.parser;

import org.jruby.RubyIO;
import org.jruby.runtime.load.LoadServiceResourceInputStream;
import org.jruby.truffle.util.LoadServiceResourceInputStream;
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.language.control.RaiseException;
import org.jruby.truffle.parser.RubyWarnings;
@@ -93,13 +92,12 @@ public ParseNode parse(String file, InputStream content, DynamicScope blockScope
return parse(file, ((LoadServiceResourceInputStream) content).getBytes(), blockScope, configuration);
} else {
List<ByteList> list = getLines(configuration, file);
RubyIO io = null;
/*if (content instanceof FileInputStream) {
io = new RubyFile(context.getJRubyRuntime(), file, ((FileInputStream) content).getChannel());
} else {
io = RubyIO.newIO(context.getJRubyRuntime(), Channels.newChannel(content));
}*/
LexerSource lexerSource = new GetsLexerSource(file, configuration.getLineNumber(), io, list, configuration.getDefaultEncoding());
LexerSource lexerSource = new GetsLexerSource(file, configuration.getLineNumber(), null, list, configuration.getDefaultEncoding());
return parse(file, lexerSource, blockScope, configuration);
}
}
Original file line number Diff line number Diff line change
@@ -36,15 +36,13 @@
package org.jruby.truffle.parser.parser;

import org.jcodings.Encoding;
import org.jruby.RubyBignum;
import org.jruby.common.IRubyWarnings;
import org.jruby.common.IRubyWarnings.ID;
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.core.regexp.ClassicRegexp;
import org.jruby.truffle.core.regexp.RegexpOptions;
import org.jruby.truffle.core.string.StringSupport;
import org.jruby.truffle.language.control.RaiseException;
import org.jruby.truffle.parser.KeyValuePair;
import org.jruby.truffle.parser.RubyWarnings;
import org.jruby.truffle.parser.Signature;
import org.jruby.truffle.parser.ast.AliasParseNode;
import org.jruby.truffle.parser.ast.AndParseNode;
@@ -158,7 +156,7 @@ public class ParserSupport {
// Is the parser currently within a method definition
private boolean inDefinition;

protected IRubyWarnings warnings;
protected RubyWarnings warnings;

protected ParserConfiguration configuration;
private RubyParserResult result;
@@ -228,7 +226,7 @@ public ParseNode gettable2(ParseNode node) {
case LOCALASGNNODE:
String name = ((INameNode) node).getName();
if (name.equals(lexer.getCurrentArg())) {
warn(ID.AMBIGUOUS_ARGUMENT, node.getPosition(), "circular argument reference - " + name);
warn(RubyWarnings.ID.AMBIGUOUS_ARGUMENT, node.getPosition(), "circular argument reference - " + name);
}
return currentScope.declare(node.getPosition(), name);
case CONSTDECLNODE: // CONSTANT
@@ -248,7 +246,7 @@ public ParseNode gettable2(ParseNode node) {

public ParseNode declareIdentifier(String name) {
if (name.equals(lexer.getCurrentArg())) {
warn(ID.AMBIGUOUS_ARGUMENT, lexer.getPosition(), "circular argument reference - " + name);
warn(RubyWarnings.ID.AMBIGUOUS_ARGUMENT, lexer.getPosition(), "circular argument reference - " + name);
}
return currentScope.declare(lexer.tokline, name);
}
@@ -321,7 +319,7 @@ public ParseNode appendToBlock(ParseNode head, ParseNode tail) {
}

if (warnings.isVerbose() && isBreakStatement(((ListParseNode) head).getLast()) && Options.PARSER_WARN_NOT_REACHED.load()) {
warnings.warning(ID.STATEMENT_NOT_REACHED, tail.getPosition().getFile(), tail.getPosition().getLine(), "statement not reached");
warnings.warning(RubyWarnings.ID.STATEMENT_NOT_REACHED, tail.getPosition().getFile(), tail.getPosition().getLine(), "statement not reached");
}

// Assumption: tail is never a list node
@@ -488,13 +486,13 @@ public boolean isBreakStatement(ParseNode node) {
} while (true);
}

public void warnUnlessEOption(ID id, ParseNode node, String message) {
public void warnUnlessEOption(RubyWarnings.ID id, ParseNode node, String message) {
if (!configuration.isInlineSource()) {
warnings.warn(id, node.getPosition().getFile(), node.getPosition().getLine(), message);
}
}

public void warningUnlessEOption(ID id, ParseNode node, String message) {
public void warningUnlessEOption(RubyWarnings.ID id, ParseNode node, String message) {
if (warnings.isVerbose() && !configuration.isInlineSource()) {
warnings.warning(id, node.getPosition().getFile(), node.getPosition().getLine(), message);
}
@@ -549,7 +547,7 @@ public boolean isLiteral(ParseNode node) {

private void handleUselessWarn(ParseNode node, String useless) {
if (Options.PARSER_WARN_USELESSS_USE_OF.load()) {
warnings.warn(ID.USELESS_EXPRESSION, node.getPosition().getFile(), node.getPosition().getLine(), "Useless use of " + useless + " in void context.");
warnings.warn(RubyWarnings.ID.USELESS_EXPRESSION, node.getPosition().getFile(), node.getPosition().getLine(), "Useless use of " + useless + " in void context.");
}
}

@@ -636,7 +634,7 @@ private boolean checkAssignmentInCondition(ParseNode node) {
} else if (node instanceof LocalAsgnParseNode || node instanceof DAsgnParseNode || node instanceof GlobalAsgnParseNode || node instanceof InstAsgnParseNode) {
ParseNode valueNode = ((AssignableParseNode) node).getValueNode();
if (isStaticContent(valueNode)) {
warnings.warn(ID.ASSIGNMENT_IN_CONDITIONAL, node.getPosition().getFile(), node.getPosition().getLine(), "found = in conditional, should be ==");
warnings.warn(RubyWarnings.ID.ASSIGNMENT_IN_CONDITIONAL, node.getPosition().getFile(), node.getPosition().getLine(), "found = in conditional, should be ==");
}
return true;
}
@@ -711,7 +709,7 @@ private ParseNode cond0(ParseNode node) {
}
case REGEXPNODE:
if (Options.PARSER_WARN_REGEX_CONDITION.load()) {
warningUnlessEOption(ID.REGEXP_LITERAL_IN_CONDITION, node, "regex literal in condition");
warningUnlessEOption(RubyWarnings.ID.REGEXP_LITERAL_IN_CONDITION, node, "regex literal in condition");
}

return new MatchParseNode(node.getPosition(), node);
@@ -735,7 +733,7 @@ private ParseNode getFlipConditionNode(ParseNode node) {
node = getConditionNode(node);

if (node instanceof FixnumParseNode) {
warnUnlessEOption(ID.LITERAL_IN_CONDITIONAL_RANGE, node, "integer literal in conditional range");
warnUnlessEOption(RubyWarnings.ID.LITERAL_IN_CONDITIONAL_RANGE, node, "integer literal in conditional range");
return getOperatorCallNode(node, "==", new GlobalVarParseNode(node.getPosition(), "$."));
}

@@ -1028,7 +1026,7 @@ public void setConfiguration(ParserConfiguration configuration) {

}

public void setWarnings(IRubyWarnings warnings) {
public void setWarnings(RubyWarnings warnings) {
this.warnings = warnings;
}

@@ -1146,7 +1144,7 @@ public NumericParseNode negateInteger(NumericParseNode integerNode) {
BigInteger value = bignumNode.getValue().negate();

// Negating a bignum will make the last negative value of our bignum
if (value.compareTo(RubyBignum.LONG_MIN) >= 0) {
if (value.compareTo(LONG_MIN) >= 0) {
return new FixnumParseNode(bignumNode.getPosition(), value.longValue());
}

@@ -1156,6 +1154,10 @@ public NumericParseNode negateInteger(NumericParseNode integerNode) {
return integerNode;
}

private static final int BIT_SIZE = 64;
private static final long MAX = (1L << (BIT_SIZE - 1)) - 1;
public static final BigInteger LONG_MIN = BigInteger.valueOf(-MAX - 1);

public FloatParseNode negateFloat(FloatParseNode floatNode) {
floatNode.setValue(-floatNode.getValue());

@@ -1215,7 +1217,7 @@ public ParseNode remove_duplicate_keys(HashParseNode hash) {
if (key == null) continue;
int index = encounteredKeys.indexOf(key);
if (index >= 0) {
warn(ID.AMBIGUOUS_ARGUMENT, hash.getPosition(), "key " + key +
warn(RubyWarnings.ID.AMBIGUOUS_ARGUMENT, hash.getPosition(), "key " + key +
" is duplicated and overwritten on line " + (encounteredKeys.get(index).getLine() + 1));
} else {
encounteredKeys.add(key);
@@ -1253,11 +1255,11 @@ public ISourcePosition getPosition(ISourcePositionHolder start) {
return start != null ? lexer.getPosition(start.getPosition()) : lexer.getPosition();
}

public void warn(ID id, ISourcePosition position, String message, Object... data) {
public void warn(RubyWarnings.ID id, ISourcePosition position, String message, Object... data) {
warnings.warn(id, position.getFile(), position.getLine(), message);
}

public void warning(ID id, ISourcePosition position, String message, Object... data) {
public void warning(RubyWarnings.ID id, ISourcePosition position, String message, Object... data) {
if (warnings.isVerbose()) warnings.warning(id, position.getFile(), position.getLine(), message);
}

@@ -1320,7 +1322,7 @@ public String shadowing_lvar(String name) {
Options.PARSER_WARN_LOCAL_SHADOWING.load() &&
!skipTruffleRubiniusWarnings(lexer)) {

warnings.warning(ID.STATEMENT_NOT_REACHED, lexer.getPosition().getFile(), lexer.getPosition().getLine(),
warnings.warning(RubyWarnings.ID.STATEMENT_NOT_REACHED, lexer.getPosition().getFile(), lexer.getPosition().getLine(),
"shadowing outer local variable - " + name);
}
} else if (current.exists(name) >= 0) {
@@ -1396,7 +1398,7 @@ private List<Integer> allocateNamedLocals(RegexpParseNode regexpNode) {
if (slot >= 0) {
// If verbose and the variable is not just another named capture, warn
if (warnings.isVerbose() && !scope.isNamedCapture(slot)) {
warn(ID.AMBIGUOUS_ARGUMENT, getPosition(regexpNode), "named capture conflicts a local variable - " + names[i]);
warn(RubyWarnings.ID.AMBIGUOUS_ARGUMENT, getPosition(regexpNode), "named capture conflicts a local variable - " + names[i]);
}
locals.add(slot);
} else {
Original file line number Diff line number Diff line change
@@ -39,12 +39,11 @@
***** END LICENSE BLOCK *****/
package org.jruby.truffle.parser.parser;

import org.jruby.common.IRubyWarnings;
import org.jruby.common.IRubyWarnings.ID;
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.core.string.StringSupport;
import org.jruby.truffle.interop.ForeignCodeNode;
import org.jruby.truffle.parser.KeyValuePair;
import org.jruby.truffle.parser.RubyWarnings;
import org.jruby.truffle.parser.ast.ArgsParseNode;
import org.jruby.truffle.parser.ast.ArgumentParseNode;
import org.jruby.truffle.parser.ast.ArrayParseNode;
@@ -146,14 +145,14 @@ public class RubyParser {
protected final ParserSupport support;
protected final RubyLexer lexer;

public RubyParser(RubyContext context, LexerSource source, IRubyWarnings warnings) {
public RubyParser(RubyContext context, LexerSource source, RubyWarnings warnings) {
this.support = new ParserSupport(context);
this.lexer = new RubyLexer(support, source, warnings);
support.setLexer(lexer);
support.setWarnings(warnings);
}

public void setWarnings(IRubyWarnings warnings) {
public void setWarnings(RubyWarnings warnings) {
support.setWarnings(warnings);
lexer.setWarnings(warnings);
}
@@ -1096,7 +1095,7 @@ public Object yyparse (RubyLexer yyLex) throws java.io.IOException {
if (((RescueBodyParseNode)yyVals[-2+yyTop]) != null) {
node = new RescueParseNode(support.getPosition(((ParseNode)yyVals[-3+yyTop])), ((ParseNode)yyVals[-3+yyTop]), ((RescueBodyParseNode)yyVals[-2+yyTop]), ((ParseNode)yyVals[-1+yyTop]));
} else if (((ParseNode)yyVals[-1+yyTop]) != null) {
support.warn(ID.ELSE_WITHOUT_RESCUE, support.getPosition(((ParseNode)yyVals[-3+yyTop])), "else without rescue is useless");
support.warn(RubyWarnings.ID.ELSE_WITHOUT_RESCUE, support.getPosition(((ParseNode)yyVals[-3+yyTop])), "else without rescue is useless");
node = support.appendToBlock(((ParseNode)yyVals[-3+yyTop]), ((ParseNode)yyVals[-1+yyTop]));
}
if (((ParseNode)yyVals[0+yyTop]) != null) {
@@ -1233,7 +1232,7 @@ public Object yyparse (RubyLexer yyLex) throws java.io.IOException {
states[31] = new ParserState() {
@Override public Object execute(ParserSupport support, RubyLexer lexer, Object yyVal, Object[] yyVals, int yyTop) {
if (support.isInDef() || support.isInSingle()) {
support.warn(ID.END_IN_METHOD, ((ISourcePosition)yyVals[-3+yyTop]), "END in method; use at_exit");
support.warn(RubyWarnings.ID.END_IN_METHOD, ((ISourcePosition)yyVals[-3+yyTop]), "END in method; use at_exit");
}
yyVal = new PostExeParseNode(((ISourcePosition)yyVals[-3+yyTop]), ((ParseNode)yyVals[-1+yyTop]));
return yyVal;
Original file line number Diff line number Diff line change
@@ -36,10 +36,11 @@
***** END LICENSE BLOCK *****/
package org.jruby.truffle.parser.parser;

import org.jruby.common.IRubyWarnings;
import org.jruby.common.IRubyWarnings.ID;
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.core.string.StringSupport;
import org.jruby.truffle.interop.ForeignCodeNode;
import org.jruby.truffle.parser.KeyValuePair;
import org.jruby.truffle.parser.RubyWarnings;
import org.jruby.truffle.parser.ast.ArgsParseNode;
import org.jruby.truffle.parser.ast.ArgumentParseNode;
import org.jruby.truffle.parser.ast.ArrayParseNode;
@@ -126,8 +127,6 @@ import org.jruby.truffle.parser.lexer.RubyLexer;
import org.jruby.truffle.parser.lexer.StrTerm;
import org.jruby.truffle.parser.lexer.SyntaxException.PID;
import org.jruby.util.ByteList;
import org.jruby.truffle.parser.KeyValuePair;
import org.jruby.truffle.core.string.StringSupport;

import java.io.IOException;

@@ -143,14 +142,14 @@ public class RubyParser {
protected final ParserSupport support;
protected final RubyLexer lexer;

public RubyParser(RubyContext context, LexerSource source, IRubyWarnings warnings) {
public RubyParser(RubyContext context, LexerSource source, RubyWarnings warnings) {
this.support = new ParserSupport(context);
this.lexer = new RubyLexer(support, source, warnings);
support.setLexer(lexer);
support.setWarnings(warnings);
}

public void setWarnings(IRubyWarnings warnings) {
public void setWarnings(RubyWarnings warnings) {
support.setWarnings(warnings);
lexer.setWarnings(warnings);
}
@@ -370,7 +369,7 @@ bodystmt : compstmt opt_rescue opt_else opt_ensure {
if ($2 != null) {
node = new RescueParseNode(support.getPosition($1), $1, $2, $3);
} else if ($3 != null) {
support.warn(ID.ELSE_WITHOUT_RESCUE, support.getPosition($1), "else without rescue is useless");
support.warn(RubyWarnings.ID.ELSE_WITHOUT_RESCUE, support.getPosition($1), "else without rescue is useless");
node = support.appendToBlock($1, $3);
}
if ($4 != null) {
@@ -454,7 +453,7 @@ stmt : kALIAS fitem {
}
| klEND tLCURLY compstmt tRCURLY {
if (support.isInDef() || support.isInSingle()) {
support.warn(ID.END_IN_METHOD, $1, "END in method; use at_exit");
support.warn(RubyWarnings.ID.END_IN_METHOD, $1, "END in method; use at_exit");
}
$$ = new PostExeParseNode($1, $3);
}
Original file line number Diff line number Diff line change
@@ -10,12 +10,12 @@
package org.jruby.truffle.platform;

import com.oracle.truffle.api.TruffleOptions;
import org.jruby.ext.ffi.Platform;
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.platform.darwin.DarwinPlatform;
import org.jruby.truffle.platform.java.JavaPlatform;
import org.jruby.truffle.platform.linux.LinuxPlatform;
import org.jruby.truffle.platform.solaris.SolarisPlatform;
import org.jruby.truffle.util.Platform;

public abstract class NativePlatformFactory {

Original file line number Diff line number Diff line change
@@ -20,7 +20,6 @@
import com.oracle.truffle.api.profiles.BranchProfile;
import com.oracle.truffle.api.profiles.ConditionProfile;
import org.jcodings.specific.UTF8Encoding;
import org.jruby.ext.bigdecimal.RubyBigDecimal;
import org.jruby.truffle.Layouts;
import org.jruby.truffle.builtins.CoreClass;
import org.jruby.truffle.builtins.CoreMethod;
@@ -37,11 +36,14 @@
import org.jruby.truffle.language.control.RaiseException;
import org.jruby.truffle.language.dispatch.CallDispatchHeadNode;
import org.jruby.truffle.language.objects.AllocateObjectNode;
import org.jruby.util.SafeDoubleParser;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.MathContext;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;

@CoreClass("Truffle::BigDecimal")
public abstract class BigDecimalNodes {
@@ -798,7 +800,83 @@ public abstract static class SqrtNode extends BigDecimalCoreMethodNode {

@TruffleBoundary
private BigDecimal sqrt(BigDecimal value, MathContext mathContext) {
return RubyBigDecimal.bigSqrt(value, mathContext);
return bigSqrt(value, mathContext);
}

private static final BigDecimal TWO = new BigDecimal(2);
private static final double SQRT_10 = 3.162277660168379332;

public static BigDecimal bigSqrt(BigDecimal squarD, MathContext rootMC) {
// General number and precision checking
int sign = squarD.signum();
if (sign == -1) throw new ArithmeticException("Square root of a negative number: " + squarD);
if (sign == 0) return squarD.round(rootMC);

int prec = rootMC.getPrecision(); // the requested precision
if (prec == 0) throw new IllegalArgumentException("Most roots won't have infinite precision = 0");

// Initial precision is that of double numbers 2^63/2 ~ 4E18
int BITS = 62; // 63-1 an even number of number bits
int nInit = 16; // precision seems 16 to 18 digits
MathContext nMC = new MathContext(18, RoundingMode.HALF_DOWN);

// Estimate the square root with the foremost 62 bits of squarD
BigInteger bi = squarD.unscaledValue(); // bi and scale are a tandem
int biLen = bi.bitLength();
int shift = Math.max(0, biLen - BITS + (biLen%2 == 0 ? 0 : 1)); // even shift..
bi = bi.shiftRight(shift); // ..floors to 62 or 63 bit BigInteger

double root = Math.sqrt(SafeDoubleParser.doubleValue(bi));
BigDecimal halfBack = new BigDecimal(BigInteger.ONE.shiftLeft(shift/2));

int scale = squarD.scale();
if (scale % 2 == 1) root *= SQRT_10; // 5 -> 2, -5 -> -3 need half a scale more..

scale = (int) Math.ceil(scale/2.); // ..where 100 -> 10 shifts the scale

// Initial x - use double root - multiply by halfBack to unshift - set new scale
BigDecimal x = new BigDecimal(root, nMC);
x = x.multiply(halfBack, nMC); // x0 ~ sqrt()
if (scale != 0) x = x.movePointLeft(scale);

if (prec < nInit) { // for prec 15 root x0 must surely be OK
return x.round(rootMC); // return small prec roots without iterations
}

// Initial v - the reciprocal
BigDecimal v = BigDecimal.ONE.divide(TWO.multiply(x), nMC); // v0 = 1/(2*x)

// Collect iteration precisions beforehand
List<Integer> nPrecs = new ArrayList<Integer>();

assert nInit > 3 : "Never ending loop!"; // assume nInit = 16 <= prec

// Let m be the exact digits precision in an earlier! loop
for (int m = prec + 1; m > nInit; m = m/2 + (m > 100 ? 1 : 2)) {
nPrecs.add(m);
}

// The loop of "Square Root by Coupled Newton Iteration"
for (int i = nPrecs.size() - 1; i > -1; i--) {
// Increase precision - next iteration supplies n exact digits
nMC = new MathContext(nPrecs.get(i), i%2 == 1 ? RoundingMode.HALF_UP : RoundingMode.HALF_DOWN);

// Next x // e = d - x^2
BigDecimal e = squarD.subtract(x.multiply(x, nMC), nMC);
if (i != 0) {
x = x.add(e.multiply(v, nMC)); // x += e*v ~ sqrt()
} else {
x = x.add(e.multiply(v, rootMC), rootMC); // root x is ready!
break;
}

// Next v // g = 1 - 2*x*v
BigDecimal g = BigDecimal.ONE.subtract(TWO.multiply(x).multiply(v, nMC));

v = v.add(g.multiply(v, nMC)); // v += g*v ~ 1/2/sqrt()
}

return x; // return sqrt(squarD) with precision of rootMC
}

@Specialization(guards = "precision < 0")
Original file line number Diff line number Diff line change
@@ -13,7 +13,6 @@
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.object.DynamicObject;
import org.jcodings.specific.ASCIIEncoding;
import org.jruby.ext.digest.BubbleBabble;
import org.jruby.truffle.Layouts;
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.builtins.CoreClass;
@@ -24,6 +23,7 @@
import org.jruby.truffle.core.rope.RopeOperations;
import org.jruby.truffle.core.string.StringOperations;
import org.jruby.truffle.language.control.JavaException;
import org.jruby.util.ByteList;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
@@ -165,7 +165,83 @@ public abstract static class BubbleBabbleNode extends CoreMethodArrayArgumentsNo
@Specialization(guards = "isRubyString(message)")
public DynamicObject bubblebabble(DynamicObject message) {
final Rope rope = StringOperations.rope(message);
return createString(BubbleBabble.bubblebabble(rope.getBytes(), 0, rope.byteLength()));
return createString(bubblebabble(rope.getBytes(), 0, rope.byteLength()));
}

/**
* Ported from OpenSSH (https://github.com/openssh/openssh-portable/blob/957fbceb0f3166e41b76fdb54075ab3b9cc84cba/sshkey.c#L942-L987)
*
* OpenSSH License Notice
*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
* Copyright (c) 2008 Alexander von Gernler. All rights reserved.
* Copyright (c) 2010,2011 Damien Miller. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
public static ByteList bubblebabble(byte[] message, int begin, int length) {
char[] vowels = new char[]{'a', 'e', 'i', 'o', 'u', 'y'};
char[] consonants = new char[]{'b', 'c', 'd', 'f', 'g', 'h', 'k', 'l', 'm',
'n', 'p', 'r', 's', 't', 'v', 'z', 'x'};

long seed = 1;

ByteList retval = new ByteList();

int rounds = (length / 2) + 1;
retval.append('x');
for (int i = 0; i < rounds; i++) {
int idx0, idx1, idx2, idx3, idx4;

if ((i + 1 < rounds) || (length % 2 != 0)) {
long b = message[begin + 2 * i] & 0xFF;
idx0 = (int) ((((b >> 6) & 3) + seed) % 6) & 0xFFFFFFFF;
idx1 = (int) (((b) >> 2) & 15) & 0xFFFFFFFF;
idx2 = (int) (((b & 3) + (seed / 6)) % 6) & 0xFFFFFFFF;
retval.append(vowels[idx0]);
retval.append(consonants[idx1]);
retval.append(vowels[idx2]);
if ((i + 1) < rounds) {
long b2 = message[begin + (2 * i) + 1] & 0xFF;
idx3 = (int) ((b2 >> 4) & 15) & 0xFFFFFFFF;
idx4 = (int) ((b2) & 15) & 0xFFFFFFFF;
retval.append(consonants[idx3]);
retval.append('-');
retval.append(consonants[idx4]);
seed = ((seed * 5) +
((b * 7) +
b2)) % 36;
}
} else {
idx0 = (int) (seed % 6) & 0xFFFFFFFF;
idx1 = 16;
idx2 = (int) (seed / 6) & 0xFFFFFFFF;
retval.append(vowels[idx0]);
retval.append(consonants[idx1]);
retval.append(vowels[idx2]);
}
}
retval.append('x');

return retval;
}

}
Original file line number Diff line number Diff line change
@@ -54,8 +54,6 @@
import org.jcodings.transcode.EConvResult;
import org.jcodings.transcode.TranscodingManager;
import org.jcodings.unicode.UnicodeEncoding;
import org.jruby.RubyEncoding;
import org.jruby.runtime.Helpers;
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.builtins.CoreClass;
import org.jruby.truffle.builtins.CoreMethod;
@@ -97,6 +95,7 @@
import java.io.ByteArrayInputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
@@ -285,13 +284,22 @@ public Object parse(
"context", toString(re) == null ? nil() : createUTF8String(toString(re)));
} catch (Throwable t) {
errorProfile.enter();
Helpers.throwException(t);
throwException(t);
return parserObject;
}

return parserObject;
}

public static void throwException(final Throwable e) {
throwsUnchecked(e);
}

@SuppressWarnings("unchecked")
private static <T extends Throwable> void throwsUnchecked(final Throwable e) throws T {
throw (T) e;
}

@TruffleBoundary
private StreamReader newStreamReader(DynamicObject yaml) {
final Encoding enc = UTF8Encoding.INSTANCE;
@@ -421,7 +429,7 @@ private Object stringFor(String value, boolean tainted, TaintNode taintNode) {
encoding = UTF8Encoding.INSTANCE;
}

Charset charset = RubyEncoding.UTF8;
Charset charset = StandardCharsets.UTF_8;

if (encoding.getCharset() != null) {
charset = encoding.getCharset();
2,197 changes: 105 additions & 2,092 deletions truffle/src/main/java/org/jruby/truffle/util/EncodingUtils.java

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package org.jruby.truffle.util;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

/**
*
* @author nicksieger
*/
public class LoadServiceResourceInputStream extends ByteArrayInputStream {

private static final byte[] NULL_BYTE_ARRAY = new byte[0];

/**
* Construct a LoadServiceResourceInputStream from the given bytes.
*
* @param bytes the bytes to wrap in this stream
*/
public LoadServiceResourceInputStream(byte[] bytes) {
super(bytes);
}

/**
* Construct a new LoadServiceInputStream by reading all bytes from the
* specified stream.
*
* You are responsible for the lifecycle of the given stream after this
* constructor has been called (i.e. it will not be closed for you).
*
* @param stream the stream from which to read bytes
* @throws IOException if the reading causes an IOException
*/
public LoadServiceResourceInputStream(InputStream stream) throws IOException {
super(NULL_BYTE_ARRAY);
bufferEntireStream(stream);
}

public byte[] getBytes() {
if (buf.length != count) {
byte[] b = new byte[count];
System.arraycopy(buf, 0, b, 0, count);
return b;
}
return buf;
}

private static final int READ_CHUNK_SIZE = 16384;

private void bufferEntireStream(InputStream stream) throws IOException {
byte[] chunk = new byte[READ_CHUNK_SIZE];
int bytesRead;
while ((bytesRead = stream.read(chunk)) != -1) {
byte[] newbuf = new byte[buf.length + bytesRead];
System.arraycopy(buf, 0, newbuf, 0, buf.length);
System.arraycopy(chunk, 0, newbuf, buf.length, bytesRead);
buf = newbuf;
count = buf.length;
}
}
}
57 changes: 57 additions & 0 deletions truffle/src/main/java/org/jruby/truffle/util/Platform.java
Original file line number Diff line number Diff line change
@@ -27,7 +27,11 @@
***** END LICENSE BLOCK *****/
package org.jruby.truffle.util;

import org.jruby.util.SafePropertyAccessor;

import java.nio.ByteOrder;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;

/**
@@ -47,6 +51,8 @@ public class Platform {
public static final int BYTE_ORDER = ByteOrder.nativeOrder().equals(ByteOrder.BIG_ENDIAN) ? BIG_ENDIAN : LITTLE_ENDIAN;


public static final boolean IS_WINDOWS = OS.equals(OS_TYPE.WINDOWS);

protected final int addressSize, longSize;
private final long addressMask;
protected final Pattern libPattern;
@@ -430,4 +436,55 @@ private static boolean startsWithIgnoreCase(String s1, String s2) {
|| s1.toUpperCase(LOCALE).startsWith(s2.toUpperCase(LOCALE))
|| s1.toLowerCase(LOCALE).startsWith(s2.toLowerCase(LOCALE));
}

public static String getOSName() {
if (jnr.posix.util.Platform.IS_WINDOWS) {
return RUBY_WIN32;
}

String OSName = jnr.posix.util.Platform.getOSName();
String theOSName = RUBY_OS_NAMES.get(OSName);

return theOSName == null ? OSName : theOSName;
}

public static String getArchitecture() {
String architecture = jnr.posix.util.Platform.ARCH;
if (architecture == null) architecture = "unknown";
if (architecture.equals("amd64")) architecture = "x86_64";

return architecture;
}

private static final String RUBY_DARWIN = "darwin";
private static final String RUBY_LINUX = "linux";
private static final String RUBY_WIN32 = "mswin32";
private static final String RUBY_SOLARIS = "solaris";
private static final String RUBY_FREEBSD = "freebsd";
private static final String RUBY_AIX = "aix";

/** This is a map from Java's "friendly" OS names to those used by Ruby */
public static final Map<String, String> RUBY_OS_NAMES = new HashMap<String, String>();
static {
RUBY_OS_NAMES.put("Mac OS X", RUBY_DARWIN);
RUBY_OS_NAMES.put("Darwin", RUBY_DARWIN);
RUBY_OS_NAMES.put("Linux", RUBY_LINUX);
RUBY_OS_NAMES.put("Windows 95", RUBY_WIN32);
RUBY_OS_NAMES.put("Windows 98", RUBY_WIN32);
RUBY_OS_NAMES.put("Windows Me", RUBY_WIN32);
RUBY_OS_NAMES.put("Windows NT", RUBY_WIN32);
RUBY_OS_NAMES.put("Windows 2000", RUBY_WIN32);
// that's what JDK5 produces on Windows Vista
RUBY_OS_NAMES.put("Windows NT (unknown)", RUBY_WIN32);
RUBY_OS_NAMES.put("Windows XP", RUBY_WIN32);
RUBY_OS_NAMES.put("Windows 2003", RUBY_WIN32);
RUBY_OS_NAMES.put("Windows Vista", RUBY_WIN32);
RUBY_OS_NAMES.put("Windows 7", RUBY_WIN32);
RUBY_OS_NAMES.put("Windows Server 2008", RUBY_WIN32);
RUBY_OS_NAMES.put("Solaris", RUBY_SOLARIS);
RUBY_OS_NAMES.put("SunOS", RUBY_SOLARIS);
RUBY_OS_NAMES.put("FreeBSD", RUBY_FREEBSD);
RUBY_OS_NAMES.put("AIX", RUBY_AIX);
}

}

0 comments on commit c15bf67

Please sign in to comment.