Skip to content

Commit

Permalink
Showing 1,009 changed files with 189,445 additions and 3,582 deletions.
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -16,6 +16,13 @@
*.tokens
*.su
*.ll
*.bc
extconf.h
mkmf.log
Makefile
cext-output.txt
bench-results.json
bench-results-processed.json

.DS_Store
.debug.properties
3 changes: 2 additions & 1 deletion bin/jruby-truffle
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#!/usr/bin/env bash

bin="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
root="$(dirname "$bin")"

exec "$bin"/jruby -X+T "$@"
exec "$root"/tool/jt.rb ruby --no-print-cmd "$@"
1 change: 1 addition & 0 deletions bin/jruby.bash
Original file line number Diff line number Diff line change
@@ -231,6 +231,7 @@ do
-*)
opt="${opt:1}=false" ;;
esac
echo "$1 is deprecated - use -J-Dgraal.$opt instead" >&2
java_args=("${java_args[@]}" "-Dgraal.$opt")
else
if [ "${val:0:3}" = "-ea" ]; then
2 changes: 1 addition & 1 deletion core/pom.rb
Original file line number Diff line number Diff line change
@@ -50,7 +50,7 @@
jar 'com.github.jnr:jnr-x86asm:1.0.2', :exclusions => ['com.github.jnr:jnr-ffi']
jar 'com.github.jnr:jnr-unixsocket:0.14', :exclusions => ['com.github.jnr:jnr-ffi']
jar 'com.github.jnr:jnr-posix:3.0.32', :exclusions => ['com.github.jnr:jnr-ffi']
jar 'com.github.jnr:jnr-constants:0.9.5', :exclusions => ['com.github.jnr:jnr-ffi']
jar 'com.github.jnr:jnr-constants:0.9.6', :exclusions => ['com.github.jnr:jnr-ffi']
jar 'com.github.jnr:jnr-ffi:2.1.1'
jar 'com.github.jnr:jffi:${jffi.version}'
jar 'com.github.jnr:jffi:${jffi.version}:native'
2 changes: 1 addition & 1 deletion core/pom.xml
Original file line number Diff line number Diff line change
@@ -148,7 +148,7 @@ DO NOT MODIFIY - GENERATED CODE
<dependency>
<groupId>com.github.jnr</groupId>
<artifactId>jnr-constants</artifactId>
<version>0.9.5</version>
<version>0.9.6</version>
<exclusions>
<exclusion>
<artifactId>jnr-ffi</artifactId>
102 changes: 91 additions & 11 deletions core/src/main/java/org/jruby/Main.java
Original file line number Diff line number Diff line change
@@ -60,6 +60,10 @@
import java.io.PrintStream;
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -219,7 +223,7 @@ public static void main(String[] args) {
catch (Throwable t) {
// If a Truffle exception gets this far it's a hard failure - don't try and dress it up as a Ruby exception

if (main.config.getCompileMode() == RubyInstanceConfig.CompileMode.TRUFFLE) {
if (main.isTruffle()) {
System.err.println("Truffle internal error: " + t);
t.printStackTrace(System.err);
} else {
@@ -273,18 +277,22 @@ private Status internalRun() {

Ruby _runtime;

if (DripMain.DRIP_RUNTIME != null) {
// use drip's runtime, reinitializing config
_runtime = DripMain.DRIP_RUNTIME;
_runtime.reinitialize(true);
if (isTruffle()) {
_runtime = null;
} else {
_runtime = Ruby.newInstance(config);
if (DripMain.DRIP_RUNTIME != null) {
// use drip's runtime, reinitializing config
_runtime = DripMain.DRIP_RUNTIME;
_runtime.reinitialize(true);
} else {
_runtime = Ruby.newInstance(config);
}
}

final Ruby runtime = _runtime;
final AtomicBoolean didTeardown = new AtomicBoolean();

if (config.isHardExit()) {
if (runtime != null && config.isHardExit()) {
// we're the command-line JRuby, and should set a shutdown hook for
// teardown.
Runtime.getRuntime().addShutdownHook(new Thread() {
@@ -297,7 +305,9 @@ public void run() {
}

try {
doSetContextClassLoader(runtime);
if (runtime != null) {
doSetContextClassLoader(runtime);
}

if (in == null) {
// no script to run, return success
@@ -307,13 +317,38 @@ public void run() {
throw new MainExitException(1, "jruby: no Ruby script found in input (LoadError)");
} else if (config.getShouldCheckSyntax()) {
// check syntax only and exit
return doCheckSyntax(runtime, in, filename);
if (isTruffle()) {
final TruffleRubyEngineInterface truffle = loadTruffle();

try {
final int exitCode = truffle.doCheckSyntax(in, filename);
return new Status(exitCode);
} finally {
truffle.dispose();
}
} else {
return doCheckSyntax(runtime, in, filename);
}
} else {
// proceed to run the script
return doRunFromMain(runtime, in, filename);
if (isTruffle()) {
final TruffleRubyEngineInterface truffle = loadTruffle();

printTruffleTimeMetric("before-run");

try {
final int exitCode = truffle.execute(filename);
return new Status(exitCode);
} finally {
printTruffleTimeMetric("after-run");
truffle.dispose();
}
} else {
return doRunFromMain(runtime, in, filename);
}
}
} finally {
if (didTeardown.compareAndSet(false, true)) {
if (runtime != null && didTeardown.compareAndSet(false, true)) {
runtime.tearDown();
}
}
@@ -576,6 +611,51 @@ else if ( ex instanceof JumpException.FlowControlException ) {
// TODO: should match MRI (>= 2.2.3) exit status - @see ruby/test_enum.rb#test_first
return 2;
}

private boolean isTruffle() {
return config.getCompileMode().isTruffle();
}

private TruffleRubyEngineInterface loadTruffle() {
Main.printTruffleTimeMetric("before-load-context");

String javaVersion = System.getProperty("java.version");
String[] parts = javaVersion.split("\\D+");
int firstPart = Integer.valueOf(parts[0]);
if (!(firstPart >= 9 || Integer.valueOf(parts[1]) >= 8)) {
System.err.println("JRuby+Truffle needs Java 8 to run (found " + javaVersion + ").");
System.exit(1);
}

final Class<?> truffleRubyEngineClass;

try {
truffleRubyEngineClass = Class.forName("org.jruby.truffle.RubyEngine");
} catch (Exception e) {
throw new RuntimeException("JRuby's Truffle backend not available - either it was not compiled because JRuby was built with Java 7, or it has been removed", e);
}

final TruffleRubyEngineInterface truffleEngine;

try {
final Object truffleEngineInstance = truffleRubyEngineClass.getConstructor(RubyInstanceConfig.class).newInstance(config);

truffleEngine = (TruffleRubyEngineInterface) Proxy.newProxyInstance(getClass().getClassLoader(), new Class[]{TruffleRubyEngineInterface.class}, new InvocationHandler() {

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return truffleRubyEngineClass.getMethod(method.getName(), method.getParameterTypes()).invoke(truffleEngineInstance, args);
}

});
} catch (Exception e) {
throw new RuntimeException("Error while calling the constructor of Truffle's RubyContext", e);
}

Main.printTruffleTimeMetric("after-load-context");

return truffleEngine;
}

public static void printTruffleTimeMetric(String id) {
if (Options.TRUFFLE_METRICS_TIME.load()) {
114 changes: 19 additions & 95 deletions core/src/main/java/org/jruby/Ruby.java
Original file line number Diff line number Diff line change
@@ -238,6 +238,10 @@ public final class Ruby implements Constantizable {
* @see org.jruby.RubyInstanceConfig
*/
private Ruby(RubyInstanceConfig config) {
if (config.getCompileMode().isTruffle()) {
throw new UnsupportedOperationException("Truffle isn't supported using a classic context - use PolyglotEngine instead.");
}

this.config = config;
this.threadService = new ThreadService(this);

@@ -554,20 +558,6 @@ public void runFromMain(InputStream inputStream, String filename) {
return;
}

if (getInstanceConfig().getCompileMode() == CompileMode.TRUFFLE) {
final JRubyTruffleInterface truffleContext = getTruffleContext();
Main.printTruffleTimeMetric("before-run");
int exitCode;
try {
exitCode = truffleContext.execute(filename);
} finally {
Main.printTruffleTimeMetric("after-run");
shutdownTruffleContextIfRunning();
}

throw new MainExitException(exitCode);
}

ParseResult parseResult = parseFromMain(filename, inputStream);

// if no DATA, we're done with the stream, shut it down
@@ -839,10 +829,6 @@ public IRubyObject runScript(Script script) {
}

public IRubyObject runScript(Script script, boolean wrap) {
if (getInstanceConfig().getCompileMode() == CompileMode.TRUFFLE) {
throw new UnsupportedOperationException();
}

return script.load(getCurrentContext(), getTopSelf(), wrap);
}

@@ -855,10 +841,6 @@ public IRubyObject runScriptBody(Script script) {
}

public IRubyObject runInterpreter(ThreadContext context, ParseResult parseResult, IRubyObject self) {
if (getInstanceConfig().getCompileMode() == CompileMode.TRUFFLE) {
throw new UnsupportedOperationException();
}

return interpreter.execute(this, parseResult, self);
}

@@ -898,56 +880,6 @@ public JITCompiler getJITCompiler() {
return jitCompiler;
}

public JRubyTruffleInterface getTruffleContext() {
synchronized (truffleContextMonitor) {
if (truffleContext == null) {
truffleContext = loadTruffle();
}
return truffleContext;
}
}

private JRubyTruffleInterface loadTruffle() {
Main.printTruffleTimeMetric("before-load-context");

String javaVersion = System.getProperty("java.version");
String[] parts = javaVersion.split("\\D+");
int firstPart = Integer.valueOf(parts[0]);
if (!(firstPart >= 9 || Integer.valueOf(parts[1]) >= 8)) {
System.err.println("JRuby+Truffle needs Java 8 to run (found " + javaVersion + ").");
System.exit(1);
}

final Class<?> clazz;

try {
clazz = getJRubyClassLoader().loadClass("org.jruby.truffle.JRubyTruffleImpl");
} catch (Exception e) {
throw new RuntimeException("JRuby's Truffle backend not available - either it was not compiled because JRuby was built with Java 7, or it has been removed", e);
}

final JRubyTruffleInterface truffleContext;

try {
Constructor<?> con = clazz.getConstructor(RubyInstanceConfig.class);
truffleContext = (JRubyTruffleInterface) con.newInstance(config);
} catch (Exception e) {
throw new RuntimeException("Error while calling the constructor of Truffle's RubyContext", e);
}

Main.printTruffleTimeMetric("after-load-context");

return truffleContext;
}

public void shutdownTruffleContextIfRunning() {
synchronized (truffleContextMonitor) {
if (truffleContext != null) {
truffleContext.dispose();
}
}
}

/**
* @deprecated use #newInstance()
*/
@@ -1276,8 +1208,7 @@ private void init() {
// if we can't use reflection, 'jruby' and 'java' won't work; no load.
boolean reflectionWorks = doesReflectionWork();

if (!RubyInstanceConfig.DEBUG_PARSER && reflectionWorks
&& getInstanceConfig().getCompileMode() != CompileMode.TRUFFLE) {
if (!RubyInstanceConfig.DEBUG_PARSER && reflectionWorks) {
loadService.require("jruby");
}

@@ -1286,23 +1217,21 @@ && getInstanceConfig().getCompileMode() != CompileMode.TRUFFLE) {
// out of base boot mode
bootingCore = false;

if (getInstanceConfig().getCompileMode() != CompileMode.TRUFFLE) {
// init Ruby-based kernel
initRubyKernel();
// init Ruby-based kernel
initRubyKernel();

// Define blank modules for feature detection in preludes
if (!config.isDisableGems()) {
defineModule("Gem");
}
if (!config.isDisableDidYouMean()) {
defineModule("DidYouMean");
}
// Define blank modules for feature detection in preludes
if (!config.isDisableGems()) {
defineModule("Gem");
}
if (!config.isDisableDidYouMean()) {
defineModule("DidYouMean");
}

initRubyPreludes();
initRubyPreludes();

// everything booted, so SizedQueue should be available; set up root fiber
ThreadFiber.initRootFiber(context);
}
// everything booted, so SizedQueue should be available; set up root fiber
ThreadFiber.initRootFiber(context);

if(config.isProfiling()) {
// additional twiddling for profiled mode
@@ -1324,10 +1253,8 @@ && getInstanceConfig().getCompileMode() != CompileMode.TRUFFLE) {
bootingRuntime = false;

// Require in all libraries specified on command line
if (getInstanceConfig().getCompileMode() != CompileMode.TRUFFLE) {
for (String scriptName : config.getRequiredLibraries()) {
topSelf.callMethod(context, "require", RubyString.newString(this, scriptName));
}
for (String scriptName : config.getRequiredLibraries()) {
topSelf.callMethod(context, "require", RubyString.newString(this, scriptName));
}
}

@@ -5187,9 +5114,6 @@ public IRubyObject call(ThreadContext context, RecursiveFunction func, IRubyObje
// Compilation
private final JITCompiler jitCompiler;

private JRubyTruffleInterface truffleContext;
private final Object truffleContextMonitor = new Object();

// Note: this field and the following static initializer
// must be located be in this order!
private volatile static boolean securityRestricted = false;
Original file line number Diff line number Diff line change
@@ -9,12 +9,14 @@
*/
package org.jruby;

public interface JRubyTruffleInterface {
import java.io.InputStream;

String RUNTIME_SYMBOL = "org.jruby.truffle.runtime";
public interface TruffleRubyEngineInterface {

int execute(String path);

void dispose();


int doCheckSyntax(InputStream in, String filename);

}
2 changes: 0 additions & 2 deletions core/src/main/java/org/jruby/ir/interpreter/Interpreter.java
Original file line number Diff line number Diff line change
@@ -146,7 +146,6 @@ public static IRubyObject INTERPRET_BLOCK(ThreadContext context, Block block, IR
*/
public static IRubyObject evalSimple(ThreadContext context, RubyModule under, IRubyObject self, RubyString src, String file, int lineNumber, EvalType evalType) {
Ruby runtime = context.runtime;
if (runtime.getInstanceConfig().getCompileMode() == RubyInstanceConfig.CompileMode.TRUFFLE) throw new UnsupportedOperationException();

// no binding, just eval in "current" frame (caller's frame)
DynamicScope parentScope = context.getCurrentScope();
@@ -192,7 +191,6 @@ private static IRubyObject evalCommon(ThreadContext context, DynamicScope evalSc
*/
public static IRubyObject evalWithBinding(ThreadContext context, IRubyObject self, IRubyObject src, Binding binding) {
Ruby runtime = context.runtime;
if (runtime.getInstanceConfig().getCompileMode() == RubyInstanceConfig.CompileMode.TRUFFLE) throw new UnsupportedOperationException();

DynamicScope evalScope = binding.getEvalScope(runtime);
evalScope.getStaticScope().determineModule(); // FIXME: It would be nice to just set this or remove it from staticScope altogether
Original file line number Diff line number Diff line change
@@ -406,7 +406,6 @@ private void processArgument() {
config.setCompileMode(RubyInstanceConfig.CompileMode.TRUFFLE);
// Make the static option consistent with the compile mode.
Options.COMPILE_MODE.force("TRUFFLE");
config.setDisableGems(true);
} else if (extendedOption.endsWith("...")) {
Options.listPrefix(extendedOption.substring(0, extendedOption.length() - "...".length()));
config.setShouldRunInterpreter(false);
2 changes: 2 additions & 0 deletions core/src/main/java/org/jruby/util/cli/Options.java
Original file line number Diff line number Diff line change
@@ -318,6 +318,8 @@ public class Options {
public static final Option<Boolean> TRUFFLE_SHARED_OBJECTS_FORCE = bool(TRUFFLE, "truffle.shared.objects.force", false, "Force sharing of objects roots at startup.");
public static final Option<Boolean> TRUFFLE_SHARED_OBJECTS_SHARE_ALL = bool(TRUFFLE, "truffle.shared.objects.share_all", false, "Consider all objects as shared.");

public static final Option<Boolean> TRUFFLE_CEXTS_LOG_LOAD = bool(TRUFFLE, "truffle.cexts.log.load", false, "Log loading of cexts.");

public static String dump() {
return "# JRuby configuration options with current values\n" +
Option.formatValues(_loadedOptions);
4 changes: 2 additions & 2 deletions lib/pom.xml
Original file line number Diff line number Diff line change
@@ -313,7 +313,7 @@ DO NOT MODIFIY - GENERATED CODE
<plugin>
<groupId>io.takari.polyglot</groupId>
<artifactId>polyglot-maven-plugin</artifactId>
<version>0.1.16</version>
<version>0.1.15</version>
<executions>
<execution>
<id>install_gems</id>
@@ -364,7 +364,7 @@ DO NOT MODIFIY - GENERATED CODE
<dependency>
<groupId>io.takari.polyglot</groupId>
<artifactId>polyglot-ruby</artifactId>
<version>0.1.16</version>
<version>0.1.15</version>
</dependency>
</dependencies>
</plugin>
16 changes: 8 additions & 8 deletions lib/ruby/stdlib/ffi/platform/sparcv9-solaris/etc.rb
Original file line number Diff line number Diff line change
@@ -3,13 +3,13 @@
module Platform; end
module Platform::Etc
class Passwd < FFI::Struct
self.size = 36
layout :pw_name, :string, 0,
:pw_passwd, :string, 4,
:pw_uid, :uint, 8,
:pw_gid, :uint, 12,
:pw_dir, :string, 28,
:pw_shell, :string, 32
:pw_passwd, :string, 8,
:pw_uid, :uint, 16,
:pw_gid, :uint, 20,
:pw_dir, :string, 48,
:pw_shell, :string, 56




@@ -18,9 +18,9 @@ class Passwd < FFI::Struct

end
class Group < FFI::Struct
self.size = 16
layout :gr_name, :string, 0,
:gr_gid, :uint, 8
:gr_gid, :uint, 16




18 changes: 18 additions & 0 deletions lib/ruby/stdlib/ffi/platform/sparcv9-solaris/fcntl-flock.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# This file is generated by rake. Do not edit.

module Fcntl
class Flock < FFI::Struct
layout :l_type, :short, 0,
:l_whence, :short, 2,
:l_start, :off_t, 8,
:l_len, :off_t, 16,
:l_sysid, :int, 24,
:l_pid, :int, 28,
:l_pad, :int, 32





end
end
8 changes: 4 additions & 4 deletions lib/ruby/stdlib/ffi/platform/sparcv9-solaris/fcntl.rb
Original file line number Diff line number Diff line change
@@ -5,15 +5,15 @@ module Fcntl
F_DUPFD = 0
F_GETFD = 1
F_GETFL = 3
F_GETLK = 33
F_GETLK = 14
F_RDLCK = 1
F_SETFD = 2
F_SETFL = 4
F_SETLK = 34
F_SETLKW = 35
F_SETLK = 6
F_SETLKW = 7
F_UNLCK = 3
F_WRLCK = 2
O_ACCMODE = 3
O_ACCMODE = 6291459
O_APPEND = 8
O_CREAT = 256
O_EXCL = 1024
213 changes: 107 additions & 106 deletions lib/ruby/stdlib/ffi/platform/sparcv9-solaris/platform.conf
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
rbx.platform.addrinfo.sizeof = 32
rbx.platform.addrinfo.sizeof = 48
rbx.platform.addrinfo.ai_flags.offset = 0
rbx.platform.addrinfo.ai_flags.size = 4
rbx.platform.addrinfo.ai_flags.type = int
@@ -11,17 +11,17 @@ rbx.platform.addrinfo.ai_socktype.type = int
rbx.platform.addrinfo.ai_protocol.offset = 12
rbx.platform.addrinfo.ai_protocol.size = 4
rbx.platform.addrinfo.ai_protocol.type = int
rbx.platform.addrinfo.ai_addrlen.offset = 16
rbx.platform.addrinfo.ai_addrlen.offset = 20
rbx.platform.addrinfo.ai_addrlen.size = 4
rbx.platform.addrinfo.ai_addrlen.type = int
rbx.platform.addrinfo.ai_addr.offset = 24
rbx.platform.addrinfo.ai_addr.size = 4
rbx.platform.addrinfo.ai_addr.offset = 32
rbx.platform.addrinfo.ai_addr.size = 8
rbx.platform.addrinfo.ai_addr.type = pointer
rbx.platform.addrinfo.ai_canonname.offset = 20
rbx.platform.addrinfo.ai_canonname.size = 4
rbx.platform.addrinfo.ai_canonname.offset = 24
rbx.platform.addrinfo.ai_canonname.size = 8
rbx.platform.addrinfo.ai_canonname.type = string
rbx.platform.addrinfo.ai_next.offset = 28
rbx.platform.addrinfo.ai_next.size = 4
rbx.platform.addrinfo.ai_next.offset = 40
rbx.platform.addrinfo.ai_next.size = 8
rbx.platform.addrinfo.ai_next.type = pointer
rbx.platform.dirent.sizeof = 24
rbx.platform.dirent.d_ino.offset = 0
@@ -33,12 +33,12 @@ rbx.platform.dirent.d_reclen.type = ushort
rbx.platform.dirent.d_name.offset = 18
rbx.platform.dirent.d_name.size = 1
rbx.platform.dirent.d_name.type = char_array
rbx.platform.timeval.sizeof = 8
rbx.platform.timeval.sizeof = 16
rbx.platform.timeval.tv_sec.offset = 0
rbx.platform.timeval.tv_sec.size = 4
rbx.platform.timeval.tv_sec.size = 8
rbx.platform.timeval.tv_sec.type = time_t
rbx.platform.timeval.tv_usec.offset = 4
rbx.platform.timeval.tv_usec.size = 4
rbx.platform.timeval.tv_usec.offset = 8
rbx.platform.timeval.tv_usec.size = 8
rbx.platform.timeval.tv_usec.type = suseconds_t
rbx.platform.sockaddr_in.sizeof = 16
rbx.platform.sockaddr_in.sin_family.offset = 0
@@ -59,56 +59,56 @@ rbx.platform.sockaddr_un.sun_family.type = sa_family_t
rbx.platform.sockaddr_un.sun_path.offset = 2
rbx.platform.sockaddr_un.sun_path.size = 108
rbx.platform.sockaddr_un.sun_path.type = char_array
rbx.platform.servent.sizeof = 16
rbx.platform.servent.sizeof = 32
rbx.platform.servent.s_name.offset = 0
rbx.platform.servent.s_name.size = 4
rbx.platform.servent.s_name.size = 8
rbx.platform.servent.s_name.type = pointer
rbx.platform.servent.s_aliases.offset = 4
rbx.platform.servent.s_aliases.size = 4
rbx.platform.servent.s_aliases.offset = 8
rbx.platform.servent.s_aliases.size = 8
rbx.platform.servent.s_aliases.type = pointer
rbx.platform.servent.s_port.offset = 8
rbx.platform.servent.s_port.offset = 16
rbx.platform.servent.s_port.size = 4
rbx.platform.servent.s_port.type = int
rbx.platform.servent.s_proto.offset = 12
rbx.platform.servent.s_proto.size = 4
rbx.platform.servent.s_proto.offset = 24
rbx.platform.servent.s_proto.size = 8
rbx.platform.servent.s_proto.type = pointer
rbx.platform.stat.sizeof = 152
rbx.platform.stat.sizeof = 128
rbx.platform.stat.st_dev.offset = 0
rbx.platform.stat.st_dev.size = 4
rbx.platform.stat.st_dev.size = 8
rbx.platform.stat.st_dev.type = dev_t
rbx.platform.stat.st_ino.offset = 16
rbx.platform.stat.st_ino.offset = 8
rbx.platform.stat.st_ino.size = 8
rbx.platform.stat.st_ino.type = ino_t
rbx.platform.stat.st_mode.offset = 24
rbx.platform.stat.st_mode.offset = 16
rbx.platform.stat.st_mode.size = 4
rbx.platform.stat.st_mode.type = mode_t
rbx.platform.stat.st_nlink.offset = 28
rbx.platform.stat.st_nlink.offset = 20
rbx.platform.stat.st_nlink.size = 4
rbx.platform.stat.st_nlink.type = nlink_t
rbx.platform.stat.st_uid.offset = 32
rbx.platform.stat.st_uid.offset = 24
rbx.platform.stat.st_uid.size = 4
rbx.platform.stat.st_uid.type = uid_t
rbx.platform.stat.st_gid.offset = 36
rbx.platform.stat.st_gid.offset = 28
rbx.platform.stat.st_gid.size = 4
rbx.platform.stat.st_gid.type = gid_t
rbx.platform.stat.st_rdev.offset = 40
rbx.platform.stat.st_rdev.size = 4
rbx.platform.stat.st_rdev.offset = 32
rbx.platform.stat.st_rdev.size = 8
rbx.platform.stat.st_rdev.type = dev_t
rbx.platform.stat.st_size.offset = 56
rbx.platform.stat.st_size.offset = 40
rbx.platform.stat.st_size.size = 8
rbx.platform.stat.st_size.type = off_t
rbx.platform.stat.st_blksize.offset = 88
rbx.platform.stat.st_blksize.offset = 96
rbx.platform.stat.st_blksize.size = 4
rbx.platform.stat.st_blocks.offset = 96
rbx.platform.stat.st_blocks.offset = 104
rbx.platform.stat.st_blocks.size = 8
rbx.platform.stat.st_atime.offset = 64
rbx.platform.stat.st_atime.size = 4
rbx.platform.stat.st_atime.offset = 48
rbx.platform.stat.st_atime.size = 8
rbx.platform.stat.st_atime.type = time_t
rbx.platform.stat.st_mtime.offset = 72
rbx.platform.stat.st_mtime.size = 4
rbx.platform.stat.st_mtime.offset = 64
rbx.platform.stat.st_mtime.size = 8
rbx.platform.stat.st_mtime.type = time_t
rbx.platform.stat.st_ctime.offset = 80
rbx.platform.stat.st_ctime.size = 4
rbx.platform.stat.st_ctime.size = 8
rbx.platform.stat.st_ctime.type = time_t
rbx.platform.rlimit.sizeof = 16
rbx.platform.rlimit.rlim_cur.offset = 0
@@ -152,7 +152,7 @@ rbx.platform.io.SEEK_CUR = 1
rbx.platform.io.SEEK_END = 2
rbx.platform.fcntl.F_GETFL = 3
rbx.platform.fcntl.F_SETFL = 4
rbx.platform.fcntl.O_ACCMODE = 3
rbx.platform.fcntl.O_ACCMODE = 6291459
rbx.platform.socket.AF_APPLETALK = 16
rbx.platform.socket.AF_ATM =
rbx.platform.socket.AF_AX25 =
@@ -174,8 +174,8 @@ rbx.platform.socket.AF_ISDN =
rbx.platform.socket.AF_ISO =
rbx.platform.socket.AF_LAT = 14
rbx.platform.socket.AF_LINK = 25
rbx.platform.socket.AF_LOCAL =
rbx.platform.socket.AF_MAX = 29
rbx.platform.socket.AF_LOCAL = 1
rbx.platform.socket.AF_MAX = 33
rbx.platform.socket.AF_NATM =
rbx.platform.socket.AF_NDRV =
rbx.platform.socket.AF_NETBIOS =
@@ -205,21 +205,21 @@ rbx.platform.socket.EAI_BADFLAGS = 3
rbx.platform.socket.EAI_BADHINTS =
rbx.platform.socket.EAI_FAIL = 4
rbx.platform.socket.EAI_FAMILY = 5
rbx.platform.socket.EAI_MAX =
rbx.platform.socket.EAI_MAX = 14
rbx.platform.socket.EAI_MEMORY = 6
rbx.platform.socket.EAI_NODATA = 7
rbx.platform.socket.EAI_NONAME = 8
rbx.platform.socket.EAI_PROTOCOL =
rbx.platform.socket.EAI_PROTOCOL = 13
rbx.platform.socket.EAI_SERVICE = 9
rbx.platform.socket.EAI_SOCKTYPE = 10
rbx.platform.socket.EAI_SYSTEM = 11
rbx.platform.socket.INADDR_ALLHOSTS_GROUP = -536870911
rbx.platform.socket.INADDR_ALLHOSTS_GROUP = 3758096385
rbx.platform.socket.INADDR_ANY = 0
rbx.platform.socket.INADDR_BROADCAST = -1
rbx.platform.socket.INADDR_BROADCAST = 4294967295
rbx.platform.socket.INADDR_LOOPBACK = 2130706433
rbx.platform.socket.INADDR_MAX_LOCAL_GROUP = -536870657
rbx.platform.socket.INADDR_NONE =
rbx.platform.socket.INADDR_UNSPEC_GROUP = -536870912
rbx.platform.socket.INADDR_MAX_LOCAL_GROUP = 3758096639
rbx.platform.socket.INADDR_NONE = 4294967295
rbx.platform.socket.INADDR_UNSPEC_GROUP = 3758096384
rbx.platform.socket.IPPORT_RESERVED = 1024
rbx.platform.socket.IPPORT_USERRESERVED = 5000
rbx.platform.socket.IPPROTO_BIP =
@@ -297,8 +297,8 @@ rbx.platform.socket.PF_ISO =
rbx.platform.socket.PF_KEY = 27
rbx.platform.socket.PF_LAT = 14
rbx.platform.socket.PF_LINK = 25
rbx.platform.socket.PF_LOCAL =
rbx.platform.socket.PF_MAX = 29
rbx.platform.socket.PF_LOCAL = 1
rbx.platform.socket.PF_MAX = 33
rbx.platform.socket.PF_NATM =
rbx.platform.socket.PF_NDRV =
rbx.platform.socket.PF_NETBIOS =
@@ -337,11 +337,11 @@ rbx.platform.socket.SOPRI_INTERACTIVE =
rbx.platform.socket.SOPRI_NORMAL =
rbx.platform.socket.SO_ACCEPTCONN = 2
rbx.platform.socket.SO_ACCEPTFILTER =
rbx.platform.socket.SO_ATTACH_FILTER =
rbx.platform.socket.SO_ATTACH_FILTER = 1073741825
rbx.platform.socket.SO_BINDTODEVICE =
rbx.platform.socket.SO_BROADCAST = 32
rbx.platform.socket.SO_DEBUG = 1
rbx.platform.socket.SO_DETACH_FILTER =
rbx.platform.socket.SO_DETACH_FILTER = 1073741826
rbx.platform.socket.SO_DONTROUTE = 16
rbx.platform.socket.SO_DONTTRUNC =
rbx.platform.socket.SO_ERROR = 4103
@@ -360,14 +360,14 @@ rbx.platform.socket.SO_RCVBUF = 4098
rbx.platform.socket.SO_RCVLOWAT = 4100
rbx.platform.socket.SO_RCVTIMEO = 4102
rbx.platform.socket.SO_REUSEADDR = 4
rbx.platform.socket.SO_REUSEPORT =
rbx.platform.socket.SO_REUSEPORT = 4110
rbx.platform.socket.SO_SECURITY_AUTHENTICATION =
rbx.platform.socket.SO_SECURITY_ENCRYPTION_NETWORK =
rbx.platform.socket.SO_SECURITY_ENCRYPTION_TRANSPORT =
rbx.platform.socket.SO_SNDBUF = 4097
rbx.platform.socket.SO_SNDLOWAT = 4099
rbx.platform.socket.SO_SNDTIMEO = 4101
rbx.platform.socket.SO_TIMESTAMP =
rbx.platform.socket.SO_TIMESTAMP = 4115
rbx.platform.socket.SO_TYPE = 4104
rbx.platform.socket.SO_USELOOPBACK = 64
rbx.platform.socket.SO_WANTMORE =
@@ -436,77 +436,78 @@ rbx.platform.signal.SIGGRANT =
rbx.platform.signal.SIGRETRACT =
rbx.platform.signal.SIGSOUND =
rbx.platform.signal.SIGINFO =
rbx.platform.zlib.ZLIB_VERSION = 1.1.4
rbx.platform.typedef.lock_t = uchar
rbx.platform.zlib.ZLIB_VERSION = 1.2.8-T4mods
rbx.platform.typedef.lock_t = uint
rbx.platform.typedef.int8_t = char
rbx.platform.typedef.int16_t = short
rbx.platform.typedef.int32_t = int
rbx.platform.typedef.int64_t = long_long
rbx.platform.typedef.int64_t = long
rbx.platform.typedef.uint8_t = uchar
rbx.platform.typedef.uint16_t = ushort
rbx.platform.typedef.uint32_t = uint
rbx.platform.typedef.uint64_t = ulong_long
rbx.platform.typedef.intmax_t = long_long
rbx.platform.typedef.uintmax_t = ulong_long
rbx.platform.typedef.intptr_t = int
rbx.platform.typedef.uintptr_t = uint
rbx.platform.typedef.uint64_t = ulong
rbx.platform.typedef.intmax_t = long
rbx.platform.typedef.uintmax_t = ulong
rbx.platform.typedef.intptr_t = long
rbx.platform.typedef.uintptr_t = ulong
rbx.platform.typedef.int_fast8_t = char
rbx.platform.typedef.int_fast16_t = int
rbx.platform.typedef.int_fast32_t = int
rbx.platform.typedef.int_fast64_t = long_long
rbx.platform.typedef.int_fast64_t = long
rbx.platform.typedef.uint_fast8_t = uchar
rbx.platform.typedef.uint_fast16_t = uint
rbx.platform.typedef.uint_fast32_t = uint
rbx.platform.typedef.uint_fast64_t = ulong_long
rbx.platform.typedef.uint_fast64_t = ulong
rbx.platform.typedef.int_least8_t = char
rbx.platform.typedef.int_least16_t = short
rbx.platform.typedef.int_least32_t = int
rbx.platform.typedef.int_least64_t = long_long
rbx.platform.typedef.int_least64_t = long
rbx.platform.typedef.uint_least8_t = uchar
rbx.platform.typedef.uint_least16_t = ushort
rbx.platform.typedef.uint_least32_t = uint
rbx.platform.typedef.uint_least64_t = ulong_long
rbx.platform.typedef.uint_least64_t = ulong
rbx.platform.typedef.longlong_t = long_long
rbx.platform.typedef.u_longlong_t = ulong_long
rbx.platform.typedef.t_scalar_t = long
rbx.platform.typedef.t_uscalar_t = ulong
rbx.platform.typedef.t_scalar_t = int
rbx.platform.typedef.t_uscalar_t = uint
rbx.platform.typedef.uchar_t = uchar
rbx.platform.typedef.ushort_t = ushort
rbx.platform.typedef.uint_t = uint
rbx.platform.typedef.ulong_t = ulong
rbx.platform.typedef.*caddr_t = char
rbx.platform.typedef.daddr_t = long
rbx.platform.typedef.cnt_t = short
rbx.platform.typedef.ptrdiff_t = int
rbx.platform.typedef.ptrdiff_t = long
rbx.platform.typedef.pfn_t = ulong
rbx.platform.typedef.pgcnt_t = ulong
rbx.platform.typedef.spgcnt_t = long
rbx.platform.typedef.use_t = uchar
rbx.platform.typedef.sysid_t = short
rbx.platform.typedef.index_t = short
rbx.platform.typedef.off_t = long_long
rbx.platform.typedef.off64_t = long_long
rbx.platform.typedef.ino_t = ulong_long
rbx.platform.typedef.blkcnt_t = long_long
rbx.platform.typedef.fsblkcnt_t = ulong_long
rbx.platform.typedef.fsfilcnt_t = ulong_long
rbx.platform.typedef.ino64_t = ulong_long
rbx.platform.typedef.blkcnt64_t = long_long
rbx.platform.typedef.fsblkcnt64_t = ulong_long
rbx.platform.typedef.fsfilcnt64_t = ulong_long
rbx.platform.typedef.blksize_t = long
rbx.platform.typedef.pad64_t = long_long
rbx.platform.typedef.upad64_t = ulong_long
rbx.platform.typedef.off_t = long
rbx.platform.typedef.off64_t = long
rbx.platform.typedef.ino_t = ulong
rbx.platform.typedef.blkcnt_t = long
rbx.platform.typedef.fsblkcnt_t = ulong
rbx.platform.typedef.fsfilcnt_t = ulong
rbx.platform.typedef.ino64_t = ulong
rbx.platform.typedef.blkcnt64_t = long
rbx.platform.typedef.fsblkcnt64_t = ulong
rbx.platform.typedef.fsfilcnt64_t = ulong
rbx.platform.typedef.blksize_t = int
rbx.platform.typedef.pad64_t = long
rbx.platform.typedef.upad64_t = ulong
rbx.platform.typedef.offset_t = long_long
rbx.platform.typedef.u_offset_t = ulong_long
rbx.platform.typedef.len_t = ulong_long
rbx.platform.typedef.diskaddr_t = ulong_long
rbx.platform.typedef.k_fltset_t = uint
rbx.platform.typedef.id_t = long
rbx.platform.typedef.id_t = int
rbx.platform.typedef.lgrp_id_t = int
rbx.platform.typedef.useconds_t = uint
rbx.platform.typedef.suseconds_t = long
rbx.platform.typedef.major_t = ulong
rbx.platform.typedef.minor_t = ulong
rbx.platform.typedef.major_t = uint
rbx.platform.typedef.minor_t = uint
rbx.platform.typedef.pri_t = short
rbx.platform.typedef.cpu_flag_t = ushort
rbx.platform.typedef.o_mode_t = ushort
@@ -517,21 +518,23 @@ rbx.platform.typedef.o_nlink_t = short
rbx.platform.typedef.o_pid_t = short
rbx.platform.typedef.o_ino_t = ushort
rbx.platform.typedef.key_t = int
rbx.platform.typedef.mode_t = ulong
rbx.platform.typedef.uid_t = long
rbx.platform.typedef.gid_t = long
rbx.platform.typedef.taskid_t = long
rbx.platform.typedef.projid_t = long
rbx.platform.typedef.poolid_t = long
rbx.platform.typedef.zoneid_t = long
rbx.platform.typedef.ctid_t = long
rbx.platform.typedef.mode_t = uint
rbx.platform.typedef.uid_t = uint
rbx.platform.typedef.gid_t = uint
rbx.platform.typedef.datalink_id_t = uint
rbx.platform.typedef.vrid_t = uint
rbx.platform.typedef.taskid_t = int
rbx.platform.typedef.projid_t = int
rbx.platform.typedef.poolid_t = int
rbx.platform.typedef.zoneid_t = int
rbx.platform.typedef.ctid_t = int
rbx.platform.typedef.pthread_t = uint
rbx.platform.typedef.pthread_key_t = uint
rbx.platform.typedef.dev_t = ulong
rbx.platform.typedef.nlink_t = ulong
rbx.platform.typedef.pid_t = long
rbx.platform.typedef.size_t = uint
rbx.platform.typedef.ssize_t = int
rbx.platform.typedef.nlink_t = uint
rbx.platform.typedef.pid_t = int
rbx.platform.typedef.size_t = ulong
rbx.platform.typedef.ssize_t = long
rbx.platform.typedef.time_t = long
rbx.platform.typedef.clock_t = long
rbx.platform.typedef.clockid_t = int
@@ -547,21 +550,19 @@ rbx.platform.typedef.u_long = ulong
rbx.platform.typedef.hrtime_t = long_long
rbx.platform.typedef.fd_mask = long
rbx.platform.typedef.fds_mask = long
rbx.platform.typedef.mrpid_t = int
rbx.platform.typedef.memsize_t = ulong_long
rbx.platform.typedef.memtime_sec_t = long_long
rbx.platform.typedef.sa_family_t = ushort
rbx.platform.typedef.socklen_t = uint
rbx.platform.typedef.Psocklen_t = pointer
rbx.platform.typedef.disp_lock_t = uchar
rbx.platform.typedef.rlim_t = ulong_long
rbx.platform.typedef.rlim64_t = ulong_long
rbx.platform.typedef.kid_t = int
rbx.platform.typedef.int) = pointer
rbx.platform.typedef.size_t) = pointer
rbx.platform.typedef.int) = pointer
rbx.platform.typedef.avl_index_t = uint
rbx.platform.typedef.() = pointer
rbx.platform.typedef.*Psocklen_t = uint
rbx.platform.typedef.nfds_t = ulong
rbx.platform.typedef.disp_lock_t = uint
rbx.platform.typedef.*) = pointer
rbx.platform.typedef.model_t = uint
rbx.platform.typedef.ts_t = long_long
rbx.platform.typedef.*) = pointer
rbx.platform.typedef.in_port_t = ushort
rbx.platform.typedef.in_addr_t = uint
rbx.platform.typedef.ipaddr_t = uint
rbx.platform.typedef.rlim_t = ulong
rbx.platform.typedef.rlim64_t = ulong_long
16 changes: 8 additions & 8 deletions lib/ruby/stdlib/ffi/platform/sparcv9-solaris/socket.rb
Original file line number Diff line number Diff line change
@@ -23,8 +23,8 @@ module Platform::Socket
# AF_ISO not available
AF_LAT = 14
AF_LINK = 25
# AF_LOCAL not available
AF_MAX = 29
AF_LOCAL = 1
AF_MAX = 33
# AF_NATM not available
# AF_NDRV not available
# AF_NETBIOS not available
@@ -82,8 +82,8 @@ module Platform::Socket
PF_KEY = 27
PF_LAT = 14
PF_LINK = 25
# PF_LOCAL not available
PF_MAX = 29
PF_LOCAL = 1
PF_MAX = 33
# PF_NATM not available
# PF_NDRV not available
# PF_NETBIOS not available
@@ -109,11 +109,11 @@ module Platform::Socket
SOCK_STREAM = 2
SO_ACCEPTCONN = 2
# SO_ACCEPTFILTER not available
# SO_ATTACH_FILTER not available
SO_ATTACH_FILTER = 1073741825
# SO_BINDTODEVICE not available
SO_BROADCAST = 32
SO_DEBUG = 1
# SO_DETACH_FILTER not available
SO_DETACH_FILTER = 1073741826
SO_DONTROUTE = 16
# SO_DONTTRUNC not available
SO_ERROR = 4103
@@ -136,15 +136,15 @@ module Platform::Socket
SO_RCVLOWAT = 4100
SO_RCVTIMEO = 4102
SO_REUSEADDR = 4
# SO_REUSEPORT not available
SO_REUSEPORT = 4110
# SO_REUSESHAREUID not available
# SO_SECURITY_AUTHENTICATION not available
# SO_SECURITY_ENCRYPTION_NETWORK not available
# SO_SECURITY_ENCRYPTION_TRANSPORT not available
SO_SNDBUF = 4097
SO_SNDLOWAT = 4099
SO_SNDTIMEO = 4101
# SO_TIMESTAMP not available
SO_TIMESTAMP = 4115
SO_TYPE = 4104
SO_USELOOPBACK = 64
# SO_WANTMORE not available
20 changes: 10 additions & 10 deletions lib/ruby/stdlib/ffi/platform/sparcv9-solaris/stat.rb
Original file line number Diff line number Diff line change
@@ -3,24 +3,24 @@
module Platform
module Stat
class Stat < FFI::Struct
self.size = 152
layout :st_dev, :dev_t, 0,
:st_ino, :ino_t, 16,
:st_nlink, :nlink_t, 28,
:st_mode, :mode_t, 24,
:st_uid, :uid_t, 32,
:st_gid, :gid_t, 36,
:st_size, :off_t, 56,
:st_blocks, :blkcnt_t, 96,
:st_atime, :time_t, 64,
:st_mtime, :time_t, 72,
:st_ino, :ino_t, 8,
:st_nlink, :nlink_t, 20,
:st_mode, :mode_t, 16,
:st_uid, :uid_t, 24,
:st_gid, :gid_t, 28,
:st_size, :off_t, 40,
:st_blocks, :blkcnt_t, 104,
:st_atime, :time_t, 48,
:st_mtime, :time_t, 64,
:st_ctime, :time_t, 80







end
module Constants
S_IEXEC = 0x40
2 changes: 1 addition & 1 deletion lib/ruby/stdlib/ffi/platform/sparcv9-solaris/syslog.rb
Original file line number Diff line number Diff line change
@@ -26,8 +26,8 @@ module Constants
LOG_LOCAL7 = 184
LOG_LPR = 48
LOG_MAIL = 16
LOG_NDELAY = 8
LOG_NEWS = 56
# LOG_NODELAY not available
LOG_NOTICE = 5
LOG_NOWAIT = 16
# LOG_NTP not available
107 changes: 54 additions & 53 deletions lib/ruby/stdlib/ffi/platform/sparcv9-solaris/types.conf
Original file line number Diff line number Diff line change
@@ -1,73 +1,74 @@
rbx.platform.typedef.lock_t = uchar
rbx.platform.typedef.lock_t = uint
rbx.platform.typedef.int8_t = char
rbx.platform.typedef.int16_t = short
rbx.platform.typedef.int32_t = int
rbx.platform.typedef.int64_t = long_long
rbx.platform.typedef.int64_t = long
rbx.platform.typedef.uint8_t = uchar
rbx.platform.typedef.uint16_t = ushort
rbx.platform.typedef.uint32_t = uint
rbx.platform.typedef.uint64_t = ulong_long
rbx.platform.typedef.intmax_t = long_long
rbx.platform.typedef.uintmax_t = ulong_long
rbx.platform.typedef.intptr_t = int
rbx.platform.typedef.uintptr_t = uint
rbx.platform.typedef.uint64_t = ulong
rbx.platform.typedef.intmax_t = long
rbx.platform.typedef.uintmax_t = ulong
rbx.platform.typedef.intptr_t = long
rbx.platform.typedef.uintptr_t = ulong
rbx.platform.typedef.int_fast8_t = char
rbx.platform.typedef.int_fast16_t = int
rbx.platform.typedef.int_fast32_t = int
rbx.platform.typedef.int_fast64_t = long_long
rbx.platform.typedef.int_fast64_t = long
rbx.platform.typedef.uint_fast8_t = uchar
rbx.platform.typedef.uint_fast16_t = uint
rbx.platform.typedef.uint_fast32_t = uint
rbx.platform.typedef.uint_fast64_t = ulong_long
rbx.platform.typedef.uint_fast64_t = ulong
rbx.platform.typedef.int_least8_t = char
rbx.platform.typedef.int_least16_t = short
rbx.platform.typedef.int_least32_t = int
rbx.platform.typedef.int_least64_t = long_long
rbx.platform.typedef.int_least64_t = long
rbx.platform.typedef.uint_least8_t = uchar
rbx.platform.typedef.uint_least16_t = ushort
rbx.platform.typedef.uint_least32_t = uint
rbx.platform.typedef.uint_least64_t = ulong_long
rbx.platform.typedef.uint_least64_t = ulong
rbx.platform.typedef.longlong_t = long_long
rbx.platform.typedef.u_longlong_t = ulong_long
rbx.platform.typedef.t_scalar_t = long
rbx.platform.typedef.t_uscalar_t = ulong
rbx.platform.typedef.t_scalar_t = int
rbx.platform.typedef.t_uscalar_t = uint
rbx.platform.typedef.uchar_t = uchar
rbx.platform.typedef.ushort_t = ushort
rbx.platform.typedef.uint_t = uint
rbx.platform.typedef.ulong_t = ulong
rbx.platform.typedef.*caddr_t = char
rbx.platform.typedef.daddr_t = long
rbx.platform.typedef.cnt_t = short
rbx.platform.typedef.ptrdiff_t = int
rbx.platform.typedef.ptrdiff_t = long
rbx.platform.typedef.pfn_t = ulong
rbx.platform.typedef.pgcnt_t = ulong
rbx.platform.typedef.spgcnt_t = long
rbx.platform.typedef.use_t = uchar
rbx.platform.typedef.sysid_t = short
rbx.platform.typedef.index_t = short
rbx.platform.typedef.off_t = long_long
rbx.platform.typedef.off64_t = long_long
rbx.platform.typedef.ino_t = ulong_long
rbx.platform.typedef.blkcnt_t = long_long
rbx.platform.typedef.fsblkcnt_t = ulong_long
rbx.platform.typedef.fsfilcnt_t = ulong_long
rbx.platform.typedef.ino64_t = ulong_long
rbx.platform.typedef.blkcnt64_t = long_long
rbx.platform.typedef.fsblkcnt64_t = ulong_long
rbx.platform.typedef.fsfilcnt64_t = ulong_long
rbx.platform.typedef.blksize_t = long
rbx.platform.typedef.pad64_t = long_long
rbx.platform.typedef.upad64_t = ulong_long
rbx.platform.typedef.off_t = long
rbx.platform.typedef.off64_t = long
rbx.platform.typedef.ino_t = ulong
rbx.platform.typedef.blkcnt_t = long
rbx.platform.typedef.fsblkcnt_t = ulong
rbx.platform.typedef.fsfilcnt_t = ulong
rbx.platform.typedef.ino64_t = ulong
rbx.platform.typedef.blkcnt64_t = long
rbx.platform.typedef.fsblkcnt64_t = ulong
rbx.platform.typedef.fsfilcnt64_t = ulong
rbx.platform.typedef.blksize_t = int
rbx.platform.typedef.pad64_t = long
rbx.platform.typedef.upad64_t = ulong
rbx.platform.typedef.offset_t = long_long
rbx.platform.typedef.u_offset_t = ulong_long
rbx.platform.typedef.len_t = ulong_long
rbx.platform.typedef.diskaddr_t = ulong_long
rbx.platform.typedef.k_fltset_t = uint
rbx.platform.typedef.id_t = long
rbx.platform.typedef.id_t = int
rbx.platform.typedef.lgrp_id_t = int
rbx.platform.typedef.useconds_t = uint
rbx.platform.typedef.suseconds_t = long
rbx.platform.typedef.major_t = ulong
rbx.platform.typedef.minor_t = ulong
rbx.platform.typedef.major_t = uint
rbx.platform.typedef.minor_t = uint
rbx.platform.typedef.pri_t = short
rbx.platform.typedef.cpu_flag_t = ushort
rbx.platform.typedef.o_mode_t = ushort
@@ -78,21 +79,23 @@ rbx.platform.typedef.o_nlink_t = short
rbx.platform.typedef.o_pid_t = short
rbx.platform.typedef.o_ino_t = ushort
rbx.platform.typedef.key_t = int
rbx.platform.typedef.mode_t = ulong
rbx.platform.typedef.uid_t = long
rbx.platform.typedef.gid_t = long
rbx.platform.typedef.taskid_t = long
rbx.platform.typedef.projid_t = long
rbx.platform.typedef.poolid_t = long
rbx.platform.typedef.zoneid_t = long
rbx.platform.typedef.ctid_t = long
rbx.platform.typedef.mode_t = uint
rbx.platform.typedef.uid_t = uint
rbx.platform.typedef.gid_t = uint
rbx.platform.typedef.datalink_id_t = uint
rbx.platform.typedef.vrid_t = uint
rbx.platform.typedef.taskid_t = int
rbx.platform.typedef.projid_t = int
rbx.platform.typedef.poolid_t = int
rbx.platform.typedef.zoneid_t = int
rbx.platform.typedef.ctid_t = int
rbx.platform.typedef.pthread_t = uint
rbx.platform.typedef.pthread_key_t = uint
rbx.platform.typedef.dev_t = ulong
rbx.platform.typedef.nlink_t = ulong
rbx.platform.typedef.pid_t = long
rbx.platform.typedef.size_t = uint
rbx.platform.typedef.ssize_t = int
rbx.platform.typedef.nlink_t = uint
rbx.platform.typedef.pid_t = int
rbx.platform.typedef.size_t = ulong
rbx.platform.typedef.ssize_t = long
rbx.platform.typedef.time_t = long
rbx.platform.typedef.clock_t = long
rbx.platform.typedef.clockid_t = int
@@ -108,21 +111,19 @@ rbx.platform.typedef.u_long = ulong
rbx.platform.typedef.hrtime_t = long_long
rbx.platform.typedef.fd_mask = long
rbx.platform.typedef.fds_mask = long
rbx.platform.typedef.mrpid_t = int
rbx.platform.typedef.memsize_t = ulong_long
rbx.platform.typedef.memtime_sec_t = long_long
rbx.platform.typedef.sa_family_t = ushort
rbx.platform.typedef.socklen_t = uint
rbx.platform.typedef.Psocklen_t = pointer
rbx.platform.typedef.disp_lock_t = uchar
rbx.platform.typedef.rlim_t = ulong_long
rbx.platform.typedef.rlim64_t = ulong_long
rbx.platform.typedef.kid_t = int
rbx.platform.typedef.int) = pointer
rbx.platform.typedef.size_t) = pointer
rbx.platform.typedef.int) = pointer
rbx.platform.typedef.avl_index_t = uint
rbx.platform.typedef.() = pointer
rbx.platform.typedef.*Psocklen_t = uint
rbx.platform.typedef.nfds_t = ulong
rbx.platform.typedef.disp_lock_t = uint
rbx.platform.typedef.*) = pointer
rbx.platform.typedef.model_t = uint
rbx.platform.typedef.ts_t = long_long
rbx.platform.typedef.*) = pointer
rbx.platform.typedef.in_port_t = ushort
rbx.platform.typedef.in_addr_t = uint
rbx.platform.typedef.ipaddr_t = uint
rbx.platform.typedef.rlim_t = ulong
rbx.platform.typedef.rlim64_t = ulong_long
30 changes: 15 additions & 15 deletions lib/ruby/stdlib/ffi/platform/sparcv9-solaris/zlib.rb
Original file line number Diff line number Diff line change
@@ -83,7 +83,7 @@

module Zlib

ZLIB_VERSION = "1.2.3"
ZLIB_VERSION = "1.2.8-T4mods"
BEST_COMPRESSION = 9
BEST_SPEED = 1
BLOCK = 5
@@ -232,21 +232,21 @@ class MemError < Error; end

class ZStream < FFI::Struct

self.size = 56
layout :next_in, :pointer, 0,
:avail_in, :uint, 4,
:total_in, :ulong, 8,
:next_out, :pointer, 12,
:avail_out, :uint, 16,
:total_out, :ulong, 20,
:msg, :string, 24,
:state, :pointer, 28,
:zalloc, :pointer, 32,
:zfree, :pointer, 36,
:opaque, :pointer, 40,
:data_type, :int, 44,
:adler, :ulong, 48,
:reserved, :ulong, 52
:avail_in, :uint, 8,
:total_in, :ulong, 16,
:next_out, :pointer, 24,
:avail_out, :uint, 32,
:total_out, :ulong, 40,
:msg, :string, 48,
:state, :pointer, 56,
:zalloc, :pointer, 64,
:zfree, :pointer, 72,
:opaque, :pointer, 80,
:data_type, :int, 88,
:adler, :ulong, 96,
:reserved, :ulong, 104




Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
TimeExtMarshalingTest:
- test_marshalling_preserves_fractional_seconds
51 changes: 41 additions & 10 deletions lib/ruby/truffle/jruby-truffle-tool/lib/truffle/config.rb
Original file line number Diff line number Diff line change
@@ -174,11 +174,11 @@ def exclusion_file(gem_name)
data.pretty_inspect
end

def exclusions_for(name)
def exclusions_for(name, ignore_missing: false)
{ setup: { file: { 'excluded-tests.rb' => format(dedent(<<-RUBY), exclusion_file(name)) } } }
failures = %s
require 'truffle/exclude_rspec_examples'
Truffle::Tool.exclude_rspec_examples failures
Truffle::Tool.exclude_rspec_examples failures, ignore_missing: #{!!ignore_missing}
RUBY
end

@@ -194,7 +194,8 @@ def exclusions_for(name)
deep_merge(
rails_common,
stubs.fetch(:activesupport_isolation),
replacements.fetch(:method_source))
replacements.fetch(:method_source),
exclusions_for(:activesupport))

Truffle::Tool.add_config :activemodel,
deep_merge(
@@ -242,9 +243,20 @@ def compute_physical_processor_count
Truffle::Tool.add_config :psd,
replacements.fetch(:nokogiri)

Truffle::Tool.add_config :actionview,
deep_merge(rails_common,
exclusions_for(:actionview, ignore_missing: true),
stubs.fetch(:html_sanitizer))

class Truffle::Tool::CIEnvironment
def rails_ci(has_exclusions: false, skip_test_files: [])
def rails_ci(has_exclusions: false, skip_test_files: [], require_pattern: 'test/**/*_test.rb')
rails_ci_setup has_exclusions: has_exclusions
set_result rails_ci_run has_exclusions: has_exclusions,
skip_test_files: skip_test_files,
require_pattern: require_pattern
end

def rails_ci_setup(has_exclusions: false)
options = {}
options[:debug] = ['-d', '--[no-]debug', 'Run tests with remote debugging enabled.', STORE_NEW_VALUE, false]
options[:exclude] = ['--[no-]exclusion', 'Exclude known failing tests', STORE_NEW_VALUE, true] if has_exclusions
@@ -255,11 +267,14 @@ def rails_ci(has_exclusions: false, skip_test_files: [])
use_only_https_git_paths!

has_to_succeed setup
set_result run([*(['--exclude-pattern', *skip_test_files.join('|')] unless skip_test_files.empty?),
*%w[--require-pattern test/**/*_test.rb],
*(%w[-r excluded-tests] if has_exclusions && option(:exclude)),
*(%w[--debug] if option(:debug)),
*%w[-- -I test -e nil]])
end

def rails_ci_run(has_exclusions: false, skip_test_files: [], require_pattern: 'test/**/*_test.rb')
run([*(['--exclude-pattern', *skip_test_files.join('|')] unless skip_test_files.empty?),
'--require-pattern', require_pattern,
*(%w[-r excluded-tests] if has_exclusions && option(:exclude)),
*(%w[--debug] if option(:debug)),
*%w[-- -I test -e nil]])
end
end

@@ -275,7 +290,7 @@ def rails_ci(has_exclusions: false, skip_test_files: [])

Truffle::Tool.add_ci_definition :activesupport do
subdir 'activesupport'
rails_ci
rails_ci has_exclusions: true
end

Truffle::Tool.add_ci_definition :railties do
@@ -334,3 +349,19 @@ def rails_ci(has_exclusions: false, skip_test_files: [])

set_result run(%w[test/algebrick_test.rb])
end

Truffle::Tool.add_ci_definition :actionview do
subdir 'actionview'
rails_ci_setup(has_exclusions: true)
results = [
rails_ci_run(has_exclusions: true,
require_pattern: 'test/template/**/*_test.rb'),
rails_ci_run(has_exclusions: true,
require_pattern: 'test/actionpack/**/*_test.rb')
# TODO (pitr-ch 17-Nov-2016): requires ActiveRecord connection to database to run, uses sqlite
# rails_ci_run(has_exclusions: true,
# require_pattern: 'test/activerecord/*_test.rb')
]

set_result results.all?
end
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
module Truffle::Tool

def self.exclude_rspec_examples(exclusions)
def self.exclude_rspec_examples(exclusions, ignore_missing: false)
exclusions.each do |mod_name, tests|

a_module = Object.const_get mod_name.to_s
begin
a_module = Object.const_get mod_name.to_s
rescue NameError => e
puts "Exclusion FAILED of module: #{mod_name}"
if ignore_missing
next
else
raise e
end
end

Array(tests).each do |test|
print "Excluding: #{a_module}##{test}"
@@ -14,6 +22,7 @@ def self.exclude_rspec_examples(exclusions)
end
rescue NameError => e
print ' (NOT FOUND)'
raise e unless ignore_missing
end
puts
end
192 changes: 191 additions & 1 deletion lib/ruby/truffle/mri/English.rb
Original file line number Diff line number Diff line change
@@ -1 +1,191 @@
require_relative '../../stdlib/English'
# frozen_string_literal: false
#
# Modified for JRuby
# In JRuby, we define these aliases by default, so this file
# does nothing.
#
# Include the English library file in a Ruby script, and you can
# reference the global variables such as \VAR{\$\_} using less
# cryptic names, listed in the following table.% \vref{tab:english}.
#
# Without 'English':
#
# $\ = ' -- '
# "waterbuffalo" =~ /buff/
# print $', $$, "\n"
#
# With English:
#
# require "English"
#
# $OUTPUT_FIELD_SEPARATOR = ' -- '
# "waterbuffalo" =~ /buff/
# print $POSTMATCH, $PID, "\n"
#
# Below is a full list of descriptive aliases and their associated global
# variable:
#
# $ERROR_INFO:: $!
# $ERROR_POSITION:: $@
# $FS:: $;
# $FIELD_SEPARATOR:: $;
# $OFS:: $,
# $OUTPUT_FIELD_SEPARATOR:: $,
# $RS:: $/
# $INPUT_RECORD_SEPARATOR:: $/
# $ORS:: $\
# $OUTPUT_RECORD_SEPARATOR:: $\
# $INPUT_LINE_NUMBER:: $.
# $NR:: $.
# $LAST_READ_LINE:: $_
# $DEFAULT_OUTPUT:: $>
# $DEFAULT_INPUT:: $<
# $PID:: $$
# $PROCESS_ID:: $$
# $CHILD_STATUS:: $?
# $LAST_MATCH_INFO:: $~
# $IGNORECASE:: $=
# $ARGV:: $*
# $MATCH:: $&
# $PREMATCH:: $`
# $POSTMATCH:: $'
# $LAST_PAREN_MATCH:: $+
#
module English end if false

# The exception object passed to +raise+.
#alias $ERROR_INFO $!

# The stack backtrace generated by the last
# exception. <tt>See Kernel.caller</tt> for details. Thread local.
#alias $ERROR_POSITION $@

# The default separator pattern used by <tt>String.split</tt>. May be
# set from the command line using the <tt>-F</tt> flag.
#alias $FS $;

# The default separator pattern used by <tt>String.split</tt>. May be
# set from the command line using the <tt>-F</tt> flag.
#alias $FIELD_SEPARATOR $;

# The separator string output between the parameters to methods such
# as <tt>Kernel.print</tt> and <tt>Array.join</tt>. Defaults to +nil+,
# which adds no text.
#alias $OFS $,

# The separator string output between the parameters to methods such
# as <tt>Kernel.print</tt> and <tt>Array.join</tt>. Defaults to +nil+,
# which adds no text.
#alias $OUTPUT_FIELD_SEPARATOR $,

# The input record separator (newline by default). This is the value
# that routines such as <tt>Kernel.gets</tt> use to determine record
# boundaries. If set to +nil+, +gets+ will read the entire file.
#alias $RS $/

# The input record separator (newline by default). This is the value
# that routines such as <tt>Kernel.gets</tt> use to determine record
# boundaries. If set to +nil+, +gets+ will read the entire file.
#alias $INPUT_RECORD_SEPARATOR $/

# The string appended to the output of every call to methods such as
# <tt>Kernel.print</tt> and <tt>IO.write</tt>. The default value is
# +nil+.
#alias $ORS $\

# The string appended to the output of every call to methods such as
# <tt>Kernel.print</tt> and <tt>IO.write</tt>. The default value is
# +nil+.
#alias $OUTPUT_RECORD_SEPARATOR $\

# The number of the last line read from the current input file.
#alias $INPUT_LINE_NUMBER $.

# The number of the last line read from the current input file.
#alias $NR $.

# The last line read by <tt>Kernel.gets</tt> or
# <tt>Kernel.readline</tt>. Many string-related functions in the
# +Kernel+ module operate on <tt>$_</tt> by default. The variable is
# local to the current scope. Thread local.
#alias $LAST_READ_LINE $_

# The destination of output for <tt>Kernel.print</tt>
# and <tt>Kernel.printf</tt>. The default value is
# <tt>$stdout</tt>.
#alias $DEFAULT_OUTPUT $>

# An object that provides access to the concatenation
# of the contents of all the files
# given as command-line arguments, or <tt>$stdin</tt>
# (in the case where there are no
# arguments). <tt>$<</tt> supports methods similar to a
# +File+ object:
# +inmode+, +close+,
# <tt>closed?</tt>, +each+,
# <tt>each_byte</tt>, <tt>each_line</tt>,
# +eof+, <tt>eof?</tt>, +file+,
# +filename+, +fileno+,
# +getc+, +gets+, +lineno+,
# <tt>lineno=</tt>, +path+,
# +pos+, <tt>pos=</tt>,
# +read+, +readchar+,
# +readline+, +readlines+,
# +rewind+, +seek+, +skip+,
# +tell+, <tt>to_a</tt>, <tt>to_i</tt>,
# <tt>to_io</tt>, <tt>to_s</tt>, along with the
# methods in +Enumerable+. The method +file+
# returns a +File+ object for the file currently
# being read. This may change as <tt>$<</tt> reads
# through the files on the command line. Read only.
#alias $DEFAULT_INPUT $<

# The process number of the program being executed. Read only.
#alias $PID $$

# The process number of the program being executed. Read only.
#alias $PROCESS_ID $$

# The exit status of the last child process to terminate. Read
# only. Thread local.
#alias $CHILD_STATUS $?

# A +MatchData+ object that encapsulates the results of a successful
# pattern match. The variables <tt>$&</tt>, <tt>$`</tt>, <tt>$'</tt>,
# and <tt>$1</tt> to <tt>$9</tt> are all derived from
# <tt>$~</tt>. Assigning to <tt>$~</tt> changes the values of these
# derived variables. This variable is local to the current
# scope.
#alias $LAST_MATCH_INFO $~

# If set to any value apart from +nil+ or +false+, all pattern matches
# will be case insensitive, string comparisons will ignore case, and
# string hash values will be case insensitive. Deprecated
#alias $IGNORECASE $=

# An array of strings containing the command-line
# options from the invocation of the program. Options
# used by the Ruby interpreter will have been
# removed. Read only. Also known simply as +ARGV+.
#alias $ARGV $*

# The string matched by the last successful pattern
# match. This variable is local to the current
# scope. Read only.
#alias $MATCH $&

# The string preceding the match in the last
# successful pattern match. This variable is local to
# the current scope. Read only.
#alias $PREMATCH $`

# The string following the match in the last
# successful pattern match. This variable is local to
# the current scope. Read only.
#alias $POSTMATCH $'

# The contents of the highest-numbered group matched in the last
# successful pattern match. Thus, in <tt>"cat" =~ /(c|a)(t|z)/</tt>,
# <tt>$+</tt> will be set to "t". This variable is local to the
# current scope. Read only.
#alias $LAST_PAREN_MATCH $+
133 changes: 132 additions & 1 deletion lib/ruby/truffle/mri/abbrev.rb
Original file line number Diff line number Diff line change
@@ -1 +1,132 @@
require_relative '../../stdlib/abbrev'
# frozen_string_literal: false
#--
# Copyright (c) 2001,2003 Akinori MUSHA <knu@iDaemons.org>
#
# All rights reserved. You can redistribute and/or modify it under
# the same terms as Ruby.
#
# $Idaemons: /home/cvs/rb/abbrev.rb,v 1.2 2001/05/30 09:37:45 knu Exp $
# $RoughId: abbrev.rb,v 1.4 2003/10/14 19:45:42 knu Exp $
# $Id$
#++

##
# Calculates the set of unambiguous abbreviations for a given set of strings.
#
# require 'abbrev'
# require 'pp'
#
# pp Abbrev.abbrev(['ruby'])
# #=> {"ruby"=>"ruby", "rub"=>"ruby", "ru"=>"ruby", "r"=>"ruby"}
#
# pp Abbrev.abbrev(%w{ ruby rules })
#
# _Generates:_
# { "ruby" => "ruby",
# "rub" => "ruby",
# "rules" => "rules",
# "rule" => "rules",
# "rul" => "rules" }
#
# It also provides an array core extension, Array#abbrev.
#
# pp %w{ summer winter }.abbrev
#
# _Generates:_
# { "summer" => "summer",
# "summe" => "summer",
# "summ" => "summer",
# "sum" => "summer",
# "su" => "summer",
# "s" => "summer",
# "winter" => "winter",
# "winte" => "winter",
# "wint" => "winter",
# "win" => "winter",
# "wi" => "winter",
# "w" => "winter" }

module Abbrev

# Given a set of strings, calculate the set of unambiguous abbreviations for
# those strings, and return a hash where the keys are all the possible
# abbreviations and the values are the full strings.
#
# Thus, given +words+ is "car" and "cone", the keys pointing to "car" would
# be "ca" and "car", while those pointing to "cone" would be "co", "con", and
# "cone".
#
# require 'abbrev'
#
# Abbrev.abbrev(%w{ car cone })
# #=> {"ca"=>"car", "con"=>"cone", "co"=>"cone", "car"=>"car", "cone"=>"cone"}
#
# The optional +pattern+ parameter is a pattern or a string. Only input
# strings that match the pattern or start with the string are included in the
# output hash.
#
# Abbrev.abbrev(%w{car box cone crab}, /b/)
# #=> {"box"=>"box", "bo"=>"box", "b"=>"box", "crab" => "crab"}
#
# Abbrev.abbrev(%w{car box cone}, 'ca')
# #=> {"car"=>"car", "ca"=>"car"}
def abbrev(words, pattern = nil)
table = {}
seen = Hash.new(0)

if pattern.is_a?(String)
pattern = /\A#{Regexp.quote(pattern)}/ # regard as a prefix
end

words.each do |word|
next if word.empty?
word.size.downto(1) { |len|
abbrev = word[0...len]

next if pattern && pattern !~ abbrev

case seen[abbrev] += 1
when 1
table[abbrev] = word
when 2
table.delete(abbrev)
else
break
end
}
end

words.each do |word|
next if pattern && pattern !~ word

table[word] = word
end

table
end

module_function :abbrev
end

class Array
# Calculates the set of unambiguous abbreviations for the strings in +self+.
#
# require 'abbrev'
# %w{ car cone }.abbrev
# #=> {"car"=>"car", "ca"=>"car", "cone"=>"cone", "con"=>"cone", "co"=>"cone"}
#
# The optional +pattern+ parameter is a pattern or a string. Only input
# strings that match the pattern or start with the string are included in the
# output hash.
#
# %w{ fast boat day }.abbrev(/^.a/)
# #=> {"fast"=>"fast", "fas"=>"fast", "fa"=>"fast", "day"=>"day", "da"=>"day"}
#
# Abbrev.abbrev(%w{car box cone}, "ca")
# #=> {"car"=>"car", "ca"=>"car"}
#
# See also Abbrev.abbrev
def abbrev(pattern = nil)
Abbrev::abbrev(self, pattern)
end
end
108 changes: 107 additions & 1 deletion lib/ruby/truffle/mri/base64.rb
Original file line number Diff line number Diff line change
@@ -1 +1,107 @@
require_relative '../../stdlib/base64'
# frozen_string_literal: false
#
# = base64.rb: methods for base64-encoding and -decoding strings
#

# The Base64 module provides for the encoding (#encode64, #strict_encode64,
# #urlsafe_encode64) and decoding (#decode64, #strict_decode64,
# #urlsafe_decode64) of binary data using a Base64 representation.
#
# == Example
#
# A simple encoding and decoding.
#
# require "base64"
#
# enc = Base64.encode64('Send reinforcements')
# # -> "U2VuZCByZWluZm9yY2VtZW50cw==\n"
# plain = Base64.decode64(enc)
# # -> "Send reinforcements"
#
# The purpose of using base64 to encode data is that it translates any
# binary data into purely printable characters.

module Base64
module_function

# Returns the Base64-encoded version of +bin+.
# This method complies with RFC 2045.
# Line feeds are added to every 60 encoded characters.
#
# require 'base64'
# Base64.encode64("Now is the time for all good coders\nto learn Ruby")
#
# <i>Generates:</i>
#
# Tm93IGlzIHRoZSB0aW1lIGZvciBhbGwgZ29vZCBjb2RlcnMKdG8gbGVhcm4g
# UnVieQ==
def encode64(bin)
[bin].pack("m")
end

# Returns the Base64-decoded version of +str+.
# This method complies with RFC 2045.
# Characters outside the base alphabet are ignored.
#
# require 'base64'
# str = 'VGhpcyBpcyBsaW5lIG9uZQpUaGlzIG' +
# 'lzIGxpbmUgdHdvClRoaXMgaXMgbGlu' +
# 'ZSB0aHJlZQpBbmQgc28gb24uLi4K'
# puts Base64.decode64(str)
#
# <i>Generates:</i>
#
# This is line one
# This is line two
# This is line three
# And so on...
def decode64(str)
str.unpack("m").first
end

# Returns the Base64-encoded version of +bin+.
# This method complies with RFC 4648.
# No line feeds are added.
def strict_encode64(bin)
[bin].pack("m0")
end

# Returns the Base64-decoded version of +str+.
# This method complies with RFC 4648.
# ArgumentError is raised if +str+ is incorrectly padded or contains
# non-alphabet characters. Note that CR or LF are also rejected.
def strict_decode64(str)
str.unpack("m0").first
end

# Returns the Base64-encoded version of +bin+.
# This method complies with ``Base 64 Encoding with URL and Filename Safe
# Alphabet'' in RFC 4648.
# The alphabet uses '-' instead of '+' and '_' instead of '/'.
# Note that the result can still contain '='.
# You can remove the padding by setting +padding+ as false.
def urlsafe_encode64(bin, padding: true)
str = strict_encode64(bin).tr("+/", "-_")
str = str.delete("=") unless padding
str
end

# Returns the Base64-decoded version of +str+.
# This method complies with ``Base 64 Encoding with URL and Filename Safe
# Alphabet'' in RFC 4648.
# The alphabet uses '-' instead of '+' and '_' instead of '/'.
#
# The padding character is optional.
# This method accepts both correctly-padded and unpadded input.
# Note that it still rejects incorrectly-padded input.
def urlsafe_decode64(str)
# NOTE: RFC 4648 does say nothing about unpadded input, but says that
# "the excess pad characters MAY also be ignored", so it is inferred that
# unpadded input is also acceptable.
str = str.tr("-_", "+/")
if !str.end_with?("=") && str.length % 4 != 0
str = str.ljust((str.length + 3) & ~3, "=")
end
strict_decode64(str)
end
end
563 changes: 562 additions & 1 deletion lib/ruby/truffle/mri/benchmark.rb

Large diffs are not rendered by default.

89 changes: 88 additions & 1 deletion lib/ruby/truffle/mri/bigdecimal/jacobian.rb
Original file line number Diff line number Diff line change
@@ -1 +1,88 @@
require_relative '../../../stdlib/bigdecimal/jacobian'
# frozen_string_literal: false
#
# require 'bigdecimal/jacobian'
#
# Provides methods to compute the Jacobian matrix of a set of equations at a
# point x. In the methods below:
#
# f is an Object which is used to compute the Jacobian matrix of the equations.
# It must provide the following methods:
#
# f.values(x):: returns the values of all functions at x
#
# f.zero:: returns 0.0
# f.one:: returns 1.0
# f.two:: returns 2.0
# f.ten:: returns 10.0
#
# f.eps:: returns the convergence criterion (epsilon value) used to determine whether two values are considered equal. If |a-b| < epsilon, the two values are considered equal.
#
# x is the point at which to compute the Jacobian.
#
# fx is f.values(x).
#
module Jacobian
module_function

# Determines the equality of two numbers by comparing to zero, or using the epsilon value
def isEqual(a,b,zero=0.0,e=1.0e-8)
aa = a.abs
bb = b.abs
if aa == zero && bb == zero then
true
else
if ((a-b)/(aa+bb)).abs < e then
true
else
false
end
end
end


# Computes the derivative of f[i] at x[i].
# fx is the value of f at x.
def dfdxi(f,fx,x,i)
nRetry = 0
n = x.size
xSave = x[i]
ok = 0
ratio = f.ten*f.ten*f.ten
dx = x[i].abs/ratio
dx = fx[i].abs/ratio if isEqual(dx,f.zero,f.zero,f.eps)
dx = f.one/f.ten if isEqual(dx,f.zero,f.zero,f.eps)
until ok>0 do
deriv = []
nRetry += 1
if nRetry > 100
raise "Singular Jacobian matrix. No change at x[" + i.to_s + "]"
end
dx = dx*f.two
x[i] += dx
fxNew = f.values(x)
for j in 0...n do
if !isEqual(fxNew[j],fx[j],f.zero,f.eps) then
ok += 1
deriv <<= (fxNew[j]-fx[j])/dx
else
deriv <<= f.zero
end
end
x[i] = xSave
end
deriv
end

# Computes the Jacobian of f at x. fx is the value of f at x.
def jacobian(f,fx,x)
n = x.size
dfdx = Array.new(n*n)
for i in 0...n do
df = dfdxi(f,fx,x,i)
for j in 0...n do
dfdx[j*n+i] = df[j]
end
end
dfdx
end
end
90 changes: 89 additions & 1 deletion lib/ruby/truffle/mri/bigdecimal/ludcmp.rb
Original file line number Diff line number Diff line change
@@ -1 +1,89 @@
require_relative '../../../stdlib/bigdecimal/ludcmp'
# frozen_string_literal: false
require 'bigdecimal'

#
# Solves a*x = b for x, using LU decomposition.
#
module LUSolve
module_function

# Performs LU decomposition of the n by n matrix a.
def ludecomp(a,n,zero=0,one=1)
prec = BigDecimal.limit(nil)
ps = []
scales = []
for i in 0...n do # pick up largest(abs. val.) element in each row.
ps <<= i
nrmrow = zero
ixn = i*n
for j in 0...n do
biggst = a[ixn+j].abs
nrmrow = biggst if biggst>nrmrow
end
if nrmrow>zero then
scales <<= one.div(nrmrow,prec)
else
raise "Singular matrix"
end
end
n1 = n - 1
for k in 0...n1 do # Gaussian elimination with partial pivoting.
biggst = zero;
for i in k...n do
size = a[ps[i]*n+k].abs*scales[ps[i]]
if size>biggst then
biggst = size
pividx = i
end
end
raise "Singular matrix" if biggst<=zero
if pividx!=k then
j = ps[k]
ps[k] = ps[pividx]
ps[pividx] = j
end
pivot = a[ps[k]*n+k]
for i in (k+1)...n do
psin = ps[i]*n
a[psin+k] = mult = a[psin+k].div(pivot,prec)
if mult!=zero then
pskn = ps[k]*n
for j in (k+1)...n do
a[psin+j] -= mult.mult(a[pskn+j],prec)
end
end
end
end
raise "Singular matrix" if a[ps[n1]*n+n1] == zero
ps
end

# Solves a*x = b for x, using LU decomposition.
#
# a is a matrix, b is a constant vector, x is the solution vector.
#
# ps is the pivot, a vector which indicates the permutation of rows performed
# during LU decomposition.
def lusolve(a,b,ps,zero=0.0)
prec = BigDecimal.limit(nil)
n = ps.size
x = []
for i in 0...n do
dot = zero
psin = ps[i]*n
for j in 0...i do
dot = a[psin+j].mult(x[j],prec) + dot
end
x <<= b[ps[i]] - dot
end
(n-1).downto(0) do |i2|
dot = zero
psin = ps[i2]*n
for j in (i2+1)...n do
dot = a[psin+j].mult(x[j],prec) + dot
end
x[i2] = (x[i2]-dot).div(a[psin+i2],prec)
end
x
end
end
247 changes: 246 additions & 1 deletion lib/ruby/truffle/mri/bigdecimal/math.rb
Original file line number Diff line number Diff line change
@@ -1 +1,246 @@
require_relative '../../../stdlib/bigdecimal/math'
# frozen_string_literal: false
require 'bigdecimal'
require 'bigdecimal/util'

#
#--
# Contents:
# sqrt(x, prec)
# sin (x, prec)
# cos (x, prec)
# atan(x, prec) Note: |x|<1, x=0.9999 may not converge.
# PI (prec)
# E (prec) == exp(1.0,prec)
#
# where:
# x ... BigDecimal number to be computed.
# |x| must be small enough to get convergence.
# prec ... Number of digits to be obtained.
#++
#
# Provides mathematical functions.
#
# Example:
#
# require "bigdecimal/math"
#
# include BigMath
#
# a = BigDecimal((PI(100)/2).to_s)
# puts sin(a,100) # => 0.10000000000000000000......E1
#
module BigMath
module_function

# call-seq:
# sqrt(decimal, numeric) -> BigDecimal
#
# Computes the square root of +decimal+ to the specified number of digits of
# precision, +numeric+.
#
# BigMath.sqrt(BigDecimal.new('2'), 16).to_s
# #=> "0.1414213562373095048801688724E1"
#
def sqrt(x, prec)
x.sqrt(prec)
end

# call-seq:
# sin(decimal, numeric) -> BigDecimal
#
# Computes the sine of +decimal+ to the specified number of digits of
# precision, +numeric+.
#
# If +decimal+ is Infinity or NaN, returns NaN.
#
# BigMath.sin(BigMath.PI(5)/4, 5).to_s
# #=> "0.70710678118654752440082036563292800375E0"
#
def sin(x, prec)
raise ArgumentError, "Zero or negative precision for sin" if prec <= 0
return BigDecimal("NaN") if x.infinite? || x.nan?
n = prec + BigDecimal.double_fig
one = BigDecimal("1")
two = BigDecimal("2")
x = -x if neg = x < 0
if x > (twopi = two * BigMath.PI(prec))
if x > 30
x %= twopi
else
x -= twopi while x > twopi
end
end
x1 = x
x2 = x.mult(x,n)
sign = 1
y = x
d = y
i = one
z = one
while d.nonzero? && ((m = n - (y.exponent - d.exponent).abs) > 0)
m = BigDecimal.double_fig if m < BigDecimal.double_fig
sign = -sign
x1 = x2.mult(x1,n)
i += two
z *= (i-one) * i
d = sign * x1.div(z,m)
y += d
end
neg ? -y : y
end

# call-seq:
# cos(decimal, numeric) -> BigDecimal
#
# Computes the cosine of +decimal+ to the specified number of digits of
# precision, +numeric+.
#
# If +decimal+ is Infinity or NaN, returns NaN.
#
# BigMath.cos(BigMath.PI(4), 16).to_s
# #=> "-0.999999999999999999999999999999856613163740061349E0"
#
def cos(x, prec)
raise ArgumentError, "Zero or negative precision for cos" if prec <= 0
return BigDecimal("NaN") if x.infinite? || x.nan?
n = prec + BigDecimal.double_fig
one = BigDecimal("1")
two = BigDecimal("2")
x = -x if x < 0
if x > (twopi = two * BigMath.PI(prec))
if x > 30
x %= twopi
else
x -= twopi while x > twopi
end
end
x1 = one
x2 = x.mult(x,n)
sign = 1
y = one
d = y
i = BigDecimal("0")
z = one
while d.nonzero? && ((m = n - (y.exponent - d.exponent).abs) > 0)
m = BigDecimal.double_fig if m < BigDecimal.double_fig
sign = -sign
x1 = x2.mult(x1,n)
i += two
z *= (i-one) * i
d = sign * x1.div(z,m)
y += d
end
y
end

# call-seq:
# atan(decimal, numeric) -> BigDecimal
#
# Computes the arctangent of +decimal+ to the specified number of digits of
# precision, +numeric+.
#
# If +decimal+ is NaN, returns NaN.
#
# BigMath.atan(BigDecimal.new('-1'), 16).to_s
# #=> "-0.785398163397448309615660845819878471907514682065E0"
#
def atan(x, prec)
raise ArgumentError, "Zero or negative precision for atan" if prec <= 0
return BigDecimal("NaN") if x.nan?
pi = PI(prec)
x = -x if neg = x < 0
return pi.div(neg ? -2 : 2, prec) if x.infinite?
return pi / (neg ? -4 : 4) if x.round(prec) == 1
x = BigDecimal("1").div(x, prec) if inv = x > 1
x = (-1 + sqrt(1 + x**2, prec))/x if dbl = x > 0.5
n = prec + BigDecimal.double_fig
y = x
d = y
t = x
r = BigDecimal("3")
x2 = x.mult(x,n)
while d.nonzero? && ((m = n - (y.exponent - d.exponent).abs) > 0)
m = BigDecimal.double_fig if m < BigDecimal.double_fig
t = -t.mult(x2,n)
d = t.div(r,m)
y += d
r += 2
end
y *= 2 if dbl
y = pi / 2 - y if inv
y = -y if neg
y
end

# call-seq:
# PI(numeric) -> BigDecimal
#
# Computes the value of pi to the specified number of digits of precision,
# +numeric+.
#
# BigMath.PI(10).to_s
# #=> "0.3141592653589793238462643388813853786957412E1"
#
def PI(prec)
raise ArgumentError, "Zero or negative precision for PI" if prec <= 0
n = prec + BigDecimal.double_fig
zero = BigDecimal("0")
one = BigDecimal("1")
two = BigDecimal("2")

m25 = BigDecimal("-0.04")
m57121 = BigDecimal("-57121")

pi = zero

d = one
k = one
t = BigDecimal("-80")
while d.nonzero? && ((m = n - (pi.exponent - d.exponent).abs) > 0)
m = BigDecimal.double_fig if m < BigDecimal.double_fig
t = t*m25
d = t.div(k,m)
k = k+two
pi = pi + d
end

d = one
k = one
t = BigDecimal("956")
while d.nonzero? && ((m = n - (pi.exponent - d.exponent).abs) > 0)
m = BigDecimal.double_fig if m < BigDecimal.double_fig
t = t.div(m57121,n)
d = t.div(k,m)
pi = pi + d
k = k+two
end
pi
end

# call-seq:
# E(numeric) -> BigDecimal
#
# Computes e (the base of natural logarithms) to the specified number of
# digits of precision, +numeric+.
#
# BigMath.E(10).to_s
# #=> "0.271828182845904523536028752390026306410273E1"
#
def E(prec)
raise ArgumentError, "Zero or negative precision for E" if prec <= 0
n = prec + BigDecimal.double_fig
one = BigDecimal("1")
y = one
d = y
z = one
i = 0
while d.nonzero? && ((m = n - (y.exponent - d.exponent).abs) > 0)
m = BigDecimal.double_fig if m < BigDecimal.double_fig
i += 1
z *= i
d = one.div(z,m)
y += d
end
y
end
end
81 changes: 80 additions & 1 deletion lib/ruby/truffle/mri/bigdecimal/newton.rb
Original file line number Diff line number Diff line change
@@ -1 +1,80 @@
require_relative '../../../stdlib/bigdecimal/newton'
# frozen_string_literal: false
require "bigdecimal/ludcmp"
require "bigdecimal/jacobian"

#
# newton.rb
#
# Solves the nonlinear algebraic equation system f = 0 by Newton's method.
# This program is not dependent on BigDecimal.
#
# To call:
# n = nlsolve(f,x)
# where n is the number of iterations required,
# x is the initial value vector
# f is an Object which is used to compute the values of the equations to be solved.
# It must provide the following methods:
#
# f.values(x):: returns the values of all functions at x
#
# f.zero:: returns 0.0
# f.one:: returns 1.0
# f.two:: returns 2.0
# f.ten:: returns 10.0
#
# f.eps:: returns the convergence criterion (epsilon value) used to determine whether two values are considered equal. If |a-b| < epsilon, the two values are considered equal.
#
# On exit, x is the solution vector.
#
module Newton
include LUSolve
include Jacobian
module_function

def norm(fv,zero=0.0) # :nodoc:
s = zero
n = fv.size
for i in 0...n do
s += fv[i]*fv[i]
end
s
end

# See also Newton
def nlsolve(f,x)
nRetry = 0
n = x.size

f0 = f.values(x)
zero = f.zero
one = f.one
two = f.two
p5 = one/two
d = norm(f0,zero)
minfact = f.ten*f.ten*f.ten
minfact = one/minfact
e = f.eps
while d >= e do
nRetry += 1
# Not yet converged. => Compute Jacobian matrix
dfdx = jacobian(f,f0,x)
# Solve dfdx*dx = -f0 to estimate dx
dx = lusolve(dfdx,f0,ludecomp(dfdx,n,zero,one),zero)
fact = two
xs = x.dup
begin
fact *= p5
if fact < minfact then
raise "Failed to reduce function values."
end
for i in 0...n do
x[i] = xs[i] - dx[i]*fact
end
f0 = f.values(x)
dn = norm(f0,zero)
end while(dn>=d)
d = dn
end
nRetry
end
end
129 changes: 128 additions & 1 deletion lib/ruby/truffle/mri/bigdecimal/util.rb
Original file line number Diff line number Diff line change
@@ -1 +1,128 @@
require_relative '../../../stdlib/bigdecimal/util'
# frozen_string_literal: false
# BigDecimal extends the native Integer class to provide the #to_d method.
#
# When you require the BigDecimal library in your application, this methodwill
# be available on Integer objects.
class Integer < Numeric
# call-seq:
# int.to_d -> bigdecimal
#
# Convert +int+ to a BigDecimal and return it.
#
# require 'bigdecimal'
# require 'bigdecimal/util'
#
# 42.to_d
# # => #<BigDecimal:1008ef070,'0.42E2',9(36)>
#
def to_d
BigDecimal(self)
end
end

# BigDecimal extends the native Float class to provide the #to_d method.
#
# When you require BigDecimal in your application, this method will be
# available on Float objects.
class Float < Numeric
# call-seq:
# flt.to_d -> bigdecimal
#
# Convert +flt+ to a BigDecimal and return it.
#
# require 'bigdecimal'
# require 'bigdecimal/util'
#
# 0.5.to_d
# # => #<BigDecimal:1dc69e0,'0.5E0',9(18)>
#
def to_d(precision=nil)
BigDecimal(self, precision || Float::DIG)
end
end

# BigDecimal extends the native String class to provide the #to_d method.
#
# When you require BigDecimal in your application, this method will be
# available on String objects.
class String
# call-seq:
# string.to_d -> bigdecimal
#
# Convert +string+ to a BigDecimal and return it.
#
# require 'bigdecimal'
# require 'bigdecimal/util'
#
# "0.5".to_d
# # => #<BigDecimal:1dc69e0,'0.5E0',9(18)>
#
def to_d
BigDecimal(self)
end
end

# BigDecimal extends the native Numeric class to provide the #to_digits and
# #to_d methods.
#
# When you require BigDecimal in your application, this method will be
# available on BigDecimal objects.
class BigDecimal < Numeric
# call-seq:
# a.to_digits -> string
#
# Converts a BigDecimal to a String of the form "nnnnnn.mmm".
# This method is deprecated; use BigDecimal#to_s("F") instead.
#
# require 'bigdecimal'
# require 'bigdecimal/util'
#
# d = BigDecimal.new("3.14")
# d.to_digits
# # => "3.14"
def to_digits
if self.nan? || self.infinite? || self.zero?
self.to_s
else
i = self.to_i.to_s
_,f,_,z = self.frac.split
i + "." + ("0"*(-z)) + f
end
end

# call-seq:
# a.to_d -> bigdecimal
#
# Returns self.
def to_d
self
end
end

# BigDecimal extends the native Rational class to provide the #to_d method.
#
# When you require BigDecimal in your application, this method will be
# available on Rational objects.
class Rational < Numeric
# call-seq:
# r.to_d(precision) -> bigdecimal
#
# Converts a Rational to a BigDecimal.
#
# The required +precision+ parameter is used to determine the amount of
# significant digits for the result. See BigDecimal#div for more information,
# as it is used along with the #denominator and the +precision+ for
# parameters.
#
# r = (22/7.0).to_r
# # => (7077085128725065/2251799813685248)
# r.to_d(3)
# # => #<BigDecimal:1a44d08,'0.314E1',18(36)>
def to_d(precision)
if precision <= 0
raise ArgumentError, "negative precision"
end
num = self.numerator
BigDecimal(num).div(self.denominator, precision)
end
end
297 changes: 296 additions & 1 deletion lib/ruby/truffle/mri/cgi.rb
Original file line number Diff line number Diff line change
@@ -1 +1,296 @@
require_relative '../../stdlib/cgi'
# frozen_string_literal: false
#
# cgi.rb - cgi support library
#
# Copyright (C) 2000 Network Applied Communication Laboratory, Inc.
#
# Copyright (C) 2000 Information-technology Promotion Agency, Japan
#
# Author: Wakou Aoyama <wakou@ruby-lang.org>
#
# Documentation: Wakou Aoyama (RDoc'd and embellished by William Webber)
#

# == Overview
#
# The Common Gateway Interface (CGI) is a simple protocol for passing an HTTP
# request from a web server to a standalone program, and returning the output
# to the web browser. Basically, a CGI program is called with the parameters
# of the request passed in either in the environment (GET) or via $stdin
# (POST), and everything it prints to $stdout is returned to the client.
#
# This file holds the CGI class. This class provides functionality for
# retrieving HTTP request parameters, managing cookies, and generating HTML
# output.
#
# The file CGI::Session provides session management functionality; see that
# class for more details.
#
# See http://www.w3.org/CGI/ for more information on the CGI protocol.
#
# == Introduction
#
# CGI is a large class, providing several categories of methods, many of which
# are mixed in from other modules. Some of the documentation is in this class,
# some in the modules CGI::QueryExtension and CGI::HtmlExtension. See
# CGI::Cookie for specific information on handling cookies, and cgi/session.rb
# (CGI::Session) for information on sessions.
#
# For queries, CGI provides methods to get at environmental variables,
# parameters, cookies, and multipart request data. For responses, CGI provides
# methods for writing output and generating HTML.
#
# Read on for more details. Examples are provided at the bottom.
#
# == Queries
#
# The CGI class dynamically mixes in parameter and cookie-parsing
# functionality, environmental variable access, and support for
# parsing multipart requests (including uploaded files) from the
# CGI::QueryExtension module.
#
# === Environmental Variables
#
# The standard CGI environmental variables are available as read-only
# attributes of a CGI object. The following is a list of these variables:
#
#
# AUTH_TYPE HTTP_HOST REMOTE_IDENT
# CONTENT_LENGTH HTTP_NEGOTIATE REMOTE_USER
# CONTENT_TYPE HTTP_PRAGMA REQUEST_METHOD
# GATEWAY_INTERFACE HTTP_REFERER SCRIPT_NAME
# HTTP_ACCEPT HTTP_USER_AGENT SERVER_NAME
# HTTP_ACCEPT_CHARSET PATH_INFO SERVER_PORT
# HTTP_ACCEPT_ENCODING PATH_TRANSLATED SERVER_PROTOCOL
# HTTP_ACCEPT_LANGUAGE QUERY_STRING SERVER_SOFTWARE
# HTTP_CACHE_CONTROL REMOTE_ADDR
# HTTP_FROM REMOTE_HOST
#
#
# For each of these variables, there is a corresponding attribute with the
# same name, except all lower case and without a preceding HTTP_.
# +content_length+ and +server_port+ are integers; the rest are strings.
#
# === Parameters
#
# The method #params() returns a hash of all parameters in the request as
# name/value-list pairs, where the value-list is an Array of one or more
# values. The CGI object itself also behaves as a hash of parameter names
# to values, but only returns a single value (as a String) for each
# parameter name.
#
# For instance, suppose the request contains the parameter
# "favourite_colours" with the multiple values "blue" and "green". The
# following behavior would occur:
#
# cgi.params["favourite_colours"] # => ["blue", "green"]
# cgi["favourite_colours"] # => "blue"
#
# If a parameter does not exist, the former method will return an empty
# array, the latter an empty string. The simplest way to test for existence
# of a parameter is by the #has_key? method.
#
# === Cookies
#
# HTTP Cookies are automatically parsed from the request. They are available
# from the #cookies() accessor, which returns a hash from cookie name to
# CGI::Cookie object.
#
# === Multipart requests
#
# If a request's method is POST and its content type is multipart/form-data,
# then it may contain uploaded files. These are stored by the QueryExtension
# module in the parameters of the request. The parameter name is the name
# attribute of the file input field, as usual. However, the value is not
# a string, but an IO object, either an IOString for small files, or a
# Tempfile for larger ones. This object also has the additional singleton
# methods:
#
# #local_path():: the path of the uploaded file on the local filesystem
# #original_filename():: the name of the file on the client computer
# #content_type():: the content type of the file
#
# == Responses
#
# The CGI class provides methods for sending header and content output to
# the HTTP client, and mixes in methods for programmatic HTML generation
# from CGI::HtmlExtension and CGI::TagMaker modules. The precise version of HTML
# to use for HTML generation is specified at object creation time.
#
# === Writing output
#
# The simplest way to send output to the HTTP client is using the #out() method.
# This takes the HTTP headers as a hash parameter, and the body content
# via a block. The headers can be generated as a string using the #http_header()
# method. The output stream can be written directly to using the #print()
# method.
#
# === Generating HTML
#
# Each HTML element has a corresponding method for generating that
# element as a String. The name of this method is the same as that
# of the element, all lowercase. The attributes of the element are
# passed in as a hash, and the body as a no-argument block that evaluates
# to a String. The HTML generation module knows which elements are
# always empty, and silently drops any passed-in body. It also knows
# which elements require matching closing tags and which don't. However,
# it does not know what attributes are legal for which elements.
#
# There are also some additional HTML generation methods mixed in from
# the CGI::HtmlExtension module. These include individual methods for the
# different types of form inputs, and methods for elements that commonly
# take particular attributes where the attributes can be directly specified
# as arguments, rather than via a hash.
#
# === Utility HTML escape and other methods like a function.
#
# There are some utility tool defined in cgi/util.rb .
# And when include, you can use utility methods like a function.
#
# == Examples of use
#
# === Get form values
#
# require "cgi"
# cgi = CGI.new
# value = cgi['field_name'] # <== value string for 'field_name'
# # if not 'field_name' included, then return "".
# fields = cgi.keys # <== array of field names
#
# # returns true if form has 'field_name'
# cgi.has_key?('field_name')
# cgi.has_key?('field_name')
# cgi.include?('field_name')
#
# CAUTION! cgi['field_name'] returned an Array with the old
# cgi.rb(included in Ruby 1.6)
#
# === Get form values as hash
#
# require "cgi"
# cgi = CGI.new
# params = cgi.params
#
# cgi.params is a hash.
#
# cgi.params['new_field_name'] = ["value"] # add new param
# cgi.params['field_name'] = ["new_value"] # change value
# cgi.params.delete('field_name') # delete param
# cgi.params.clear # delete all params
#
#
# === Save form values to file
#
# require "pstore"
# db = PStore.new("query.db")
# db.transaction do
# db["params"] = cgi.params
# end
#
#
# === Restore form values from file
#
# require "pstore"
# db = PStore.new("query.db")
# db.transaction do
# cgi.params = db["params"]
# end
#
#
# === Get multipart form values
#
# require "cgi"
# cgi = CGI.new
# value = cgi['field_name'] # <== value string for 'field_name'
# value.read # <== body of value
# value.local_path # <== path to local file of value
# value.original_filename # <== original filename of value
# value.content_type # <== content_type of value
#
# and value has StringIO or Tempfile class methods.
#
# === Get cookie values
#
# require "cgi"
# cgi = CGI.new
# values = cgi.cookies['name'] # <== array of 'name'
# # if not 'name' included, then return [].
# names = cgi.cookies.keys # <== array of cookie names
#
# and cgi.cookies is a hash.
#
# === Get cookie objects
#
# require "cgi"
# cgi = CGI.new
# for name, cookie in cgi.cookies
# cookie.expires = Time.now + 30
# end
# cgi.out("cookie" => cgi.cookies) {"string"}
#
# cgi.cookies # { "name1" => cookie1, "name2" => cookie2, ... }
#
# require "cgi"
# cgi = CGI.new
# cgi.cookies['name'].expires = Time.now + 30
# cgi.out("cookie" => cgi.cookies['name']) {"string"}
#
# === Print http header and html string to $DEFAULT_OUTPUT ($>)
#
# require "cgi"
# cgi = CGI.new("html4") # add HTML generation methods
# cgi.out do
# cgi.html do
# cgi.head do
# cgi.title { "TITLE" }
# end +
# cgi.body do
# cgi.form("ACTION" => "uri") do
# cgi.p do
# cgi.textarea("get_text") +
# cgi.br +
# cgi.submit
# end
# end +
# cgi.pre do
# CGI::escapeHTML(
# "params: #{cgi.params.inspect}\n" +
# "cookies: #{cgi.cookies.inspect}\n" +
# ENV.collect do |key, value|
# "#{key} --> #{value}\n"
# end.join("")
# )
# end
# end
# end
# end
#
# # add HTML generation methods
# CGI.new("html3") # html3.2
# CGI.new("html4") # html4.01 (Strict)
# CGI.new("html4Tr") # html4.01 Transitional
# CGI.new("html4Fr") # html4.01 Frameset
# CGI.new("html5") # html5
#
# === Some utility methods
#
# require 'cgi/util'
# CGI.escapeHTML('Usage: foo "bar" <baz>')
#
#
# === Some utility methods like a function
#
# require 'cgi/util'
# include CGI::Util
# escapeHTML('Usage: foo "bar" <baz>')
# h('Usage: foo "bar" <baz>') # alias
#
#

class CGI
end

require 'cgi/core'
require 'cgi/cookie'
require 'cgi/util'
CGI.autoload(:HtmlExtension, 'cgi/html')
189 changes: 188 additions & 1 deletion lib/ruby/truffle/mri/cgi/cookie.rb
Original file line number Diff line number Diff line change
@@ -1 +1,188 @@
require_relative '../../../stdlib/cgi/cookie'
# frozen_string_literal: false
require 'cgi/util'
class CGI
# Class representing an HTTP cookie.
#
# In addition to its specific fields and methods, a Cookie instance
# is a delegator to the array of its values.
#
# See RFC 2965.
#
# == Examples of use
# cookie1 = CGI::Cookie.new("name", "value1", "value2", ...)
# cookie1 = CGI::Cookie.new("name" => "name", "value" => "value")
# cookie1 = CGI::Cookie.new('name' => 'name',
# 'value' => ['value1', 'value2', ...],
# 'path' => 'path', # optional
# 'domain' => 'domain', # optional
# 'expires' => Time.now, # optional
# 'secure' => true, # optional
# 'httponly' => true # optional
# )
#
# cgi.out("cookie" => [cookie1, cookie2]) { "string" }
#
# name = cookie1.name
# values = cookie1.value
# path = cookie1.path
# domain = cookie1.domain
# expires = cookie1.expires
# secure = cookie1.secure
# httponly = cookie1.httponly
#
# cookie1.name = 'name'
# cookie1.value = ['value1', 'value2', ...]
# cookie1.path = 'path'
# cookie1.domain = 'domain'
# cookie1.expires = Time.now + 30
# cookie1.secure = true
# cookie1.httponly = true
class Cookie < Array
@@accept_charset="UTF-8" unless defined?(@@accept_charset)

# Create a new CGI::Cookie object.
#
# :call-seq:
# Cookie.new(name_string,*value)
# Cookie.new(options_hash)
#
# +name_string+::
# The name of the cookie; in this form, there is no #domain or
# #expiration. The #path is gleaned from the +SCRIPT_NAME+ environment
# variable, and #secure is false.
# <tt>*value</tt>::
# value or list of values of the cookie
# +options_hash+::
# A Hash of options to initialize this Cookie. Possible options are:
#
# name:: the name of the cookie. Required.
# value:: the cookie's value or list of values.
# path:: the path for which this cookie applies. Defaults to the
# the value of the +SCRIPT_NAME+ environment variable.
# domain:: the domain for which this cookie applies.
# expires:: the time at which this cookie expires, as a +Time+ object.
# secure:: whether this cookie is a secure cookie or not (default to
# false). Secure cookies are only transmitted to HTTPS
# servers.
# httponly:: whether this cookie is a HttpOnly cookie or not (default to
# false). HttpOnly cookies are not available to javascript.
#
# These keywords correspond to attributes of the cookie object.
def initialize(name = "", *value)
@domain = nil
@expires = nil
if name.kind_of?(String)
@name = name
%r|^(.*/)|.match(ENV["SCRIPT_NAME"])
@path = ($1 or "")
@secure = false
@httponly = false
return super(value)
end

options = name
unless options.has_key?("name")
raise ArgumentError, "`name' required"
end

@name = options["name"]
value = Array(options["value"])
# simple support for IE
if options["path"]
@path = options["path"]
else
%r|^(.*/)|.match(ENV["SCRIPT_NAME"])
@path = ($1 or "")
end
@domain = options["domain"]
@expires = options["expires"]
@secure = options["secure"] == true
@httponly = options["httponly"] == true

super(value)
end

# Name of this cookie, as a +String+
attr_accessor :name
# Path for which this cookie applies, as a +String+
attr_accessor :path
# Domain for which this cookie applies, as a +String+
attr_accessor :domain
# Time at which this cookie expires, as a +Time+
attr_accessor :expires
# True if this cookie is secure; false otherwise
attr_reader :secure
# True if this cookie is httponly; false otherwise
attr_reader :httponly

# Returns the value or list of values for this cookie.
def value
self
end

# Replaces the value of this cookie with a new value or list of values.
def value=(val)
replace(Array(val))
end

# Set whether the Cookie is a secure cookie or not.
#
# +val+ must be a boolean.
def secure=(val)
@secure = val if val == true or val == false
@secure
end

# Set whether the Cookie is a httponly cookie or not.
#
# +val+ must be a boolean.
def httponly=(val)
@httponly = !!val
end

# Convert the Cookie to its string representation.
def to_s
val = collect{|v| CGI.escape(v) }.join("&")
buf = "#{@name}=#{val}"
buf << "; domain=#{@domain}" if @domain
buf << "; path=#{@path}" if @path
buf << "; expires=#{CGI::rfc1123_date(@expires)}" if @expires
buf << "; secure" if @secure
buf << "; HttpOnly" if @httponly
buf
end

# Parse a raw cookie string into a hash of cookie-name=>Cookie
# pairs.
#
# cookies = CGI::Cookie.parse("raw_cookie_string")
# # { "name1" => cookie1, "name2" => cookie2, ... }
#
def self.parse(raw_cookie)
cookies = Hash.new([])
return cookies unless raw_cookie

raw_cookie.split(/[;,]\s?/).each do |pairs|
name, values = pairs.split('=',2)
next unless name and values
name = CGI.unescape(name)
values ||= ""
values = values.split('&').collect{|v| CGI.unescape(v,@@accept_charset) }
if cookies.has_key?(name)
values = cookies[name].value + values
end
cookies[name] = Cookie.new(name, *values)
end

cookies
end

# A summary of cookie string.
def inspect
"#<CGI::Cookie: #{self.to_s.inspect}>"
end

end # class Cookie
end


882 changes: 881 additions & 1 deletion lib/ruby/truffle/mri/cgi/core.rb

Large diffs are not rendered by default.

1,036 changes: 1,035 additions & 1 deletion lib/ruby/truffle/mri/cgi/html.rb

Large diffs are not rendered by default.

535 changes: 534 additions & 1 deletion lib/ruby/truffle/mri/cgi/session.rb

Large diffs are not rendered by default.

102 changes: 101 additions & 1 deletion lib/ruby/truffle/mri/cgi/session/pstore.rb
Original file line number Diff line number Diff line change
@@ -1 +1,101 @@
require_relative '../../../../stdlib/cgi/session/pstore'
# frozen_string_literal: false
#
# cgi/session/pstore.rb - persistent storage of marshalled session data
#
# Documentation: William Webber (william@williamwebber.com)
#
# == Overview
#
# This file provides the CGI::Session::PStore class, which builds
# persistent of session data on top of the pstore library. See
# cgi/session.rb for more details on session storage managers.

require 'cgi/session'
require 'pstore'

class CGI
class Session
# PStore-based session storage class.
#
# This builds upon the top-level PStore class provided by the
# library file pstore.rb. Session data is marshalled and stored
# in a file. File locking and transaction services are provided.
class PStore
# Create a new CGI::Session::PStore instance
#
# This constructor is used internally by CGI::Session. The
# user does not generally need to call it directly.
#
# +session+ is the session for which this instance is being
# created. The session id must only contain alphanumeric
# characters; automatically generated session ids observe
# this requirement.
#
# +option+ is a hash of options for the initializer. The
# following options are recognised:
#
# tmpdir:: the directory to use for storing the PStore
# file. Defaults to Dir::tmpdir (generally "/tmp"
# on Unix systems).
# prefix:: the prefix to add to the session id when generating
# the filename for this session's PStore file.
# Defaults to the empty string.
#
# This session's PStore file will be created if it does
# not exist, or opened if it does.
def initialize(session, option={})
dir = option['tmpdir'] || Dir::tmpdir
prefix = option['prefix'] || ''
id = session.session_id
require 'digest/md5'
md5 = Digest::MD5.hexdigest(id)[0,16]
path = dir+"/"+prefix+md5
path.untaint
if File::exist?(path)
@hash = nil
else
unless session.new_session
raise CGI::Session::NoSession, "uninitialized session"
end
@hash = {}
end
@p = ::PStore.new(path)
@p.transaction do |p|
File.chmod(0600, p.path)
end
end

# Restore session state from the session's PStore file.
#
# Returns the session state as a hash.
def restore
unless @hash
@p.transaction do
@hash = @p['hash'] || {}
end
end
@hash
end

# Save session state to the session's PStore file.
def update
@p.transaction do
@p['hash'] = @hash
end
end

# Update and close the session's PStore file.
def close
update
end

# Close and delete the session's PStore file.
def delete
path = @p.path
File::unlink path
end

end
end
end
# :enddoc:
201 changes: 200 additions & 1 deletion lib/ruby/truffle/mri/cgi/util.rb
Original file line number Diff line number Diff line change
@@ -1 +1,200 @@
require_relative '../../../stdlib/cgi/util'
# frozen_string_literal: false
class CGI; module Util; end; extend Util; end
module CGI::Util
@@accept_charset="UTF-8" unless defined?(@@accept_charset)
# URL-encode a string.
# url_encoded_string = CGI::escape("'Stop!' said Fred")
# # => "%27Stop%21%27+said+Fred"
def escape(string)
encoding = string.encoding
string.b.gsub(/([^ a-zA-Z0-9_.-]+)/) do |m|
'%' + m.unpack('H2' * m.bytesize).join('%').upcase
end.tr(' ', '+').force_encoding(encoding)
end

# URL-decode a string with encoding(optional).
# string = CGI::unescape("%27Stop%21%27+said+Fred")
# # => "'Stop!' said Fred"
def unescape(string,encoding=@@accept_charset)
str=string.tr('+', ' ').b.gsub(/((?:%[0-9a-fA-F]{2})+)/) do |m|
[m.delete('%')].pack('H*')
end.force_encoding(encoding)
str.valid_encoding? ? str : str.force_encoding(string.encoding)
end

# The set of special characters and their escaped values
TABLE_FOR_ESCAPE_HTML__ = {
"'" => '&#39;',
'&' => '&amp;',
'"' => '&quot;',
'<' => '&lt;',
'>' => '&gt;',
}

# Escape special characters in HTML, namely &\"<>
# CGI::escapeHTML('Usage: foo "bar" <baz>')
# # => "Usage: foo &quot;bar&quot; &lt;baz&gt;"
def escapeHTML(string)
string.gsub(/['&\"<>]/, TABLE_FOR_ESCAPE_HTML__)
end

begin
require 'cgi/escape'
rescue LoadError
end

# Unescape a string that has been HTML-escaped
# CGI::unescapeHTML("Usage: foo &quot;bar&quot; &lt;baz&gt;")
# # => "Usage: foo \"bar\" <baz>"
def unescapeHTML(string)
return string unless string.include? '&'
enc = string.encoding
if enc != Encoding::UTF_8 && [Encoding::UTF_16BE, Encoding::UTF_16LE, Encoding::UTF_32BE, Encoding::UTF_32LE].include?(enc)
return string.gsub(Regexp.new('&(apos|amp|quot|gt|lt|#[0-9]+|#x[0-9A-Fa-f]+);'.encode(enc))) do
case $1.encode(Encoding::US_ASCII)
when 'apos' then "'".encode(enc)
when 'amp' then '&'.encode(enc)
when 'quot' then '"'.encode(enc)
when 'gt' then '>'.encode(enc)
when 'lt' then '<'.encode(enc)
when /\A#0*(\d+)\z/ then $1.to_i.chr(enc)
when /\A#x([0-9a-f]+)\z/i then $1.hex.chr(enc)
end
end
end
asciicompat = Encoding.compatible?(string, "a")
string.gsub(/&(apos|amp|quot|gt|lt|\#[0-9]+|\#[xX][0-9A-Fa-f]+);/) do
match = $1.dup
case match
when 'apos' then "'"
when 'amp' then '&'
when 'quot' then '"'
when 'gt' then '>'
when 'lt' then '<'
when /\A#0*(\d+)\z/
n = $1.to_i
if enc == Encoding::UTF_8 or
enc == Encoding::ISO_8859_1 && n < 256 or
asciicompat && n < 128
n.chr(enc)
else
"&##{$1};"
end
when /\A#x([0-9a-f]+)\z/i
n = $1.hex
if enc == Encoding::UTF_8 or
enc == Encoding::ISO_8859_1 && n < 256 or
asciicompat && n < 128
n.chr(enc)
else
"&#x#{$1};"
end
else
"&#{match};"
end
end
end

# Synonym for CGI::escapeHTML(str)
alias escape_html escapeHTML

# Synonym for CGI::unescapeHTML(str)
alias unescape_html unescapeHTML

# Escape only the tags of certain HTML elements in +string+.
#
# Takes an element or elements or array of elements. Each element
# is specified by the name of the element, without angle brackets.
# This matches both the start and the end tag of that element.
# The attribute list of the open tag will also be escaped (for
# instance, the double-quotes surrounding attribute values).
#
# print CGI::escapeElement('<BR><A HREF="url"></A>', "A", "IMG")
# # "<BR>&lt;A HREF=&quot;url&quot;&gt;&lt;/A&gt"
#
# print CGI::escapeElement('<BR><A HREF="url"></A>', ["A", "IMG"])
# # "<BR>&lt;A HREF=&quot;url&quot;&gt;&lt;/A&gt"
def escapeElement(string, *elements)
elements = elements[0] if elements[0].kind_of?(Array)
unless elements.empty?
string.gsub(/<\/?(?:#{elements.join("|")})(?!\w)(?:.|\n)*?>/i) do
CGI::escapeHTML($&)
end
else
string
end
end

# Undo escaping such as that done by CGI::escapeElement()
#
# print CGI::unescapeElement(
# CGI::escapeHTML('<BR><A HREF="url"></A>'), "A", "IMG")
# # "&lt;BR&gt;<A HREF="url"></A>"
#
# print CGI::unescapeElement(
# CGI::escapeHTML('<BR><A HREF="url"></A>'), ["A", "IMG"])
# # "&lt;BR&gt;<A HREF="url"></A>"
def unescapeElement(string, *elements)
elements = elements[0] if elements[0].kind_of?(Array)
unless elements.empty?
string.gsub(/&lt;\/?(?:#{elements.join("|")})(?!\w)(?:.|\n)*?&gt;/i) do
unescapeHTML($&)
end
else
string
end
end

# Synonym for CGI::escapeElement(str)
alias escape_element escapeElement

# Synonym for CGI::unescapeElement(str)
alias unescape_element unescapeElement

# Abbreviated day-of-week names specified by RFC 822
RFC822_DAYS = %w[ Sun Mon Tue Wed Thu Fri Sat ]

# Abbreviated month names specified by RFC 822
RFC822_MONTHS = %w[ Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec ]

# Format a +Time+ object as a String using the format specified by RFC 1123.
#
# CGI::rfc1123_date(Time.now)
# # Sat, 01 Jan 2000 00:00:00 GMT
def rfc1123_date(time)
t = time.clone.gmtime
return format("%s, %.2d %s %.4d %.2d:%.2d:%.2d GMT",
RFC822_DAYS[t.wday], t.day, RFC822_MONTHS[t.month-1], t.year,
t.hour, t.min, t.sec)
end

# Prettify (indent) an HTML string.
#
# +string+ is the HTML string to indent. +shift+ is the indentation
# unit to use; it defaults to two spaces.
#
# print CGI::pretty("<HTML><BODY></BODY></HTML>")
# # <HTML>
# # <BODY>
# # </BODY>
# # </HTML>
#
# print CGI::pretty("<HTML><BODY></BODY></HTML>", "\t")
# # <HTML>
# # <BODY>
# # </BODY>
# # </HTML>
#
def pretty(string, shift = " ")
lines = string.gsub(/(?!\A)<.*?>/m, "\n\\0").gsub(/<.*?>(?!\n)/m, "\\0\n")
end_pos = 0
while end_pos = lines.index(/^<\/(\w+)/, end_pos)
element = $1.dup
start_pos = lines.rindex(/^\s*<#{element}/i, end_pos)
lines[start_pos ... end_pos] = "__" + lines[start_pos ... end_pos].gsub(/\n(?!\z)/, "\n" + shift) + "__"
end
lines.gsub(/^((?:#{Regexp::quote(shift)})*)__(?=<\/?\w)/, '\1')
end

alias h escapeHTML
end
Loading

0 comments on commit 1babf16

Please sign in to comment.