Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
**** BEGIN LICENSE BLOCK *****
* Version: EPL 1.0/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Eclipse Public
* License Version 1.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.eclipse.org/legal/epl-v10.html
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* Copyright (C) 2001 Chad Fowler
* Copyright (C) 2001 Alan Moore
* Copyright (C) 2001-2002 Benoit Cerrina
* Copyright (C) 2001-2004 Jan Arne Petersen
* Copyright (C) 2002-2004 Anders Bengtsson
* Copyright (C) 2004 Thomas E Enebo
* Copyright (C) 2004-2005 Charles O Nutter
* Copyright (C) 2004 Stefan Matthias Aust
* Copyright (C) 2006 Miguel Covarrubias
* Copyright (C) 2006 Michael Studman
* Copyright (C) 2006 Ola Bini
* Copyright (C) 2007 Nick Sieger
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the EPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the EPL, the GPL or the LGPL.
***** END LICENSE BLOCK *****/
package org.jruby;
import jnr.constants.Constant;
import jnr.constants.ConstantSet;
import jnr.constants.platform.Errno;
import jnr.posix.POSIX;
import jnr.posix.POSIXFactory;
import org.jcodings.Encoding;
import org.joda.time.DateTimeZone;
import org.jruby.RubyInstanceConfig.CompileMode;
import org.jruby.ast.Node;
import org.jruby.ast.RootNode;
import org.jruby.ast.executable.AbstractScript;
import org.jruby.ast.executable.RuntimeCache;
import org.jruby.ast.executable.Script;
import org.jruby.common.IRubyWarnings.ID;
import org.jruby.common.RubyWarnings;
import org.jruby.compiler.ASTCompiler;
import org.jruby.compiler.ASTInspector;
import org.jruby.compiler.JITCompiler;
import org.jruby.compiler.impl.StandardASMCompiler;
import org.jruby.embed.Extension;
import org.jruby.evaluator.ASTInterpreter;
import org.jruby.exceptions.JumpException;
import org.jruby.exceptions.MainExitException;
import org.jruby.exceptions.RaiseException;
import org.jruby.exceptions.Unrescuable;
import org.jruby.ext.JRubyPOSIXHandler;
import org.jruby.ext.LateLoadingLibrary;
import org.jruby.ext.coverage.CoverageData;
import org.jruby.ext.ffi.FFI;
import org.jruby.ext.fiber.ThreadFiber;
import org.jruby.ext.fiber.ThreadFiberLibrary;
import org.jruby.ext.jruby.JRubyConfigLibrary;
import org.jruby.ext.tracepoint.TracePoint;
import org.jruby.internal.runtime.GlobalVariables;
import org.jruby.internal.runtime.ThreadService;
import org.jruby.internal.runtime.ValueAccessor;
import org.jruby.internal.runtime.methods.CallConfiguration;
import org.jruby.internal.runtime.methods.DynamicMethod;
import org.jruby.ir.IRBuilder;
import org.jruby.internal.runtime.methods.JavaMethod;
import org.jruby.ir.IRManager;
import org.jruby.ir.IRScope;
import org.jruby.ir.interpreter.Interpreter;
import org.jruby.ir.targets.JVMVisitor;
import org.jruby.javasupport.JavaSupport;
import org.jruby.javasupport.proxy.JavaProxyClassFactory;
import org.jruby.management.BeanManager;
import org.jruby.management.BeanManagerFactory;
import org.jruby.management.ClassCache;
import org.jruby.management.Config;
import org.jruby.management.ParserStats;
import org.jruby.parser.IRStaticScopeFactory;
import org.jruby.parser.Parser;
import org.jruby.parser.ParserConfiguration;
import org.jruby.parser.StaticScope;
import org.jruby.parser.StaticScopeFactory;
import org.jruby.platform.Platform;
import org.jruby.runtime.Binding;
import org.jruby.runtime.Block;
import org.jruby.runtime.CallSite;
import org.jruby.runtime.CallbackFactory;
import org.jruby.runtime.ClassIndex;
import org.jruby.runtime.DynamicScope;
import org.jruby.runtime.EventHook;
import org.jruby.runtime.GlobalVariable;
import org.jruby.runtime.Helpers;
import org.jruby.runtime.IAccessor;
import org.jruby.runtime.ObjectAllocator;
import org.jruby.runtime.ObjectSpace;
import org.jruby.runtime.RubyEvent;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.Visibility;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.runtime.encoding.EncodingService;
import org.jruby.runtime.invokedynamic.MethodNames;
import org.jruby.runtime.load.BasicLibraryService;
import org.jruby.runtime.load.CompiledScriptLoader;
import org.jruby.runtime.load.Library;
import org.jruby.runtime.load.LoadService;
import org.jruby.runtime.opto.Invalidator;
import org.jruby.runtime.opto.OptoFactory;
import org.jruby.runtime.profile.ProfileCollection;
import org.jruby.runtime.profile.ProfilingService;
import org.jruby.runtime.profile.ProfilingServiceLookup;
import org.jruby.runtime.profile.builtin.ProfiledMethods;
import org.jruby.runtime.scope.ManyVarsDynamicScope;
import org.jruby.threading.DaemonThreadFactory;
import org.jruby.util.ByteList;
import org.jruby.util.DefinedMessage;
import org.jruby.util.IOInputStream;
import org.jruby.util.IOOutputStream;
import org.jruby.util.JRubyClassLoader;
import org.jruby.util.JavaNameMangler;
import org.jruby.util.KCode;
import org.jruby.util.SafePropertyAccessor;
import org.jruby.util.collections.WeakHashSet;
import org.jruby.util.func.Function1;
import org.jruby.util.io.ChannelDescriptor;
import org.jruby.util.io.SelectorPool;
import org.jruby.util.log.Logger;
import org.jruby.util.log.LoggerFactory;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileDescriptor;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.net.BindException;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.channels.ClosedChannelException;
import java.security.AccessControlException;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.EnumMap;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.Stack;
import java.util.WeakHashMap;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.regex.Pattern;
import static org.jruby.internal.runtime.GlobalVariable.Scope.*;
import org.jruby.internal.runtime.methods.CallConfiguration;
import org.jruby.internal.runtime.methods.JavaMethod;
import org.jruby.util.cli.Options;
/**
* The Ruby object represents the top-level of a JRuby "instance" in a given VM.
* JRuby supports spawning multiple instances in the same JVM. Generally, objects
* created under these instances are tied to a given runtime, for such details
* as identity and type, because multiple Ruby instances means there are
* multiple instances of each class. This means that in multi-runtime mode
* (or really, multi-VM mode, where each JRuby instance is a ruby "VM"), objects
* generally can't be transported across runtimes without marshaling.
*
* This class roots everything that makes the JRuby runtime function, and
* provides a number of utility methods for constructing global types and
* accessing global runtime structures.
*/
public final class Ruby {
/**
* The logger used to log relevant bits.
*/
private static final Logger LOG = LoggerFactory.getLogger("Ruby");
/**
* Create and initialize a new JRuby runtime. The properties of the
* specified RubyInstanceConfig will be used to determine various JRuby
* runtime characteristics.
*
* @param config The configuration to use for the new instance
* @see org.jruby.RubyInstanceConfig
*/
private Ruby(RubyInstanceConfig config) {
this.config = config;
this.threadService = new ThreadService(this);
if( config.isProfiling() ) {
this.profiledMethods = new ProfiledMethods(this);
this.profilingServiceLookup = new ProfilingServiceLookup(this);
} else {
this.profiledMethods = null;
this.profilingServiceLookup = null;
}
getJRubyClassLoader(); // force JRubyClassLoader to init if possible
if (config.getCompileMode() == CompileMode.OFFIR ||
config.getCompileMode() == CompileMode.FORCEIR) {
this.staticScopeFactory = new IRStaticScopeFactory(this);
} else {
this.staticScopeFactory = new StaticScopeFactory(this);
}
this.beanManager = BeanManagerFactory.create(this, config.isManagementEnabled());
this.jitCompiler = new JITCompiler(this);
this.parserStats = new ParserStats(this);
Random myRandom;
try {
myRandom = new SecureRandom();
} catch (Throwable t) {
LOG.debug("unable to instantiate SecureRandom, falling back on Random", t);
myRandom = new Random();
}
this.random = myRandom;
if (RubyInstanceConfig.CONSISTENT_HASHING_ENABLED) {
this.hashSeedK0 = -561135208506705104l;
this.hashSeedK1 = 7114160726623585955l;
} else {
this.hashSeedK0 = this.random.nextLong();
this.hashSeedK1 = this.random.nextLong();
}
this.configBean = new Config(this);
this.classCacheBean = new ClassCache(this);
this.runtimeBean = new org.jruby.management.Runtime(this);
registerMBeans();
this.runtimeCache = new RuntimeCache();
runtimeCache.initMethodCache(ClassIndex.MAX_CLASSES * MethodNames.values().length - 1);
checkpointInvalidator = OptoFactory.newConstantInvalidator();
if (config.isObjectSpaceEnabled()) {
objectSpacer = ENABLED_OBJECTSPACE;
} else {
objectSpacer = DISABLED_OBJECTSPACE;
}
reinitialize(false);
}
public void registerMBeans() {
this.beanManager.register(jitCompiler);
this.beanManager.register(configBean);
this.beanManager.register(parserStats);
this.beanManager.register(classCacheBean);
this.beanManager.register(runtimeBean);
}
void reinitialize(boolean reinitCore) {
this.is1_9 = config.getCompatVersion().is1_9();
this.is2_0 = config.getCompatVersion().is2_0();
this.doNotReverseLookupEnabled = is1_9;
if (config.getCompileMode() == CompileMode.OFFIR ||
config.getCompileMode() == CompileMode.FORCEIR) {
this.staticScopeFactory = new IRStaticScopeFactory(this);
} else {
this.staticScopeFactory = new StaticScopeFactory(this);
}
this.in = config.getInput();
this.out = config.getOutput();
this.err = config.getError();
this.objectSpaceEnabled = config.isObjectSpaceEnabled();
this.siphashEnabled = config.isSiphashEnabled();
this.profile = config.getProfile();
this.currentDirectory = config.getCurrentDirectory();
this.kcode = config.getKCode();
if (reinitCore) {
RubyGlobal.initARGV(this);
}
}
/**
* Returns a new instance of the JRuby runtime configured with defaults.
*
* @return the JRuby runtime
* @see org.jruby.RubyInstanceConfig
*/
public static Ruby newInstance() {
return newInstance(new RubyInstanceConfig());
}
/**
* Returns a new instance of the JRuby runtime configured as specified.
*
* @param config The instance configuration
* @return The JRuby runtime
* @see org.jruby.RubyInstanceConfig
*/
public static Ruby newInstance(RubyInstanceConfig config) {
Ruby ruby = new Ruby(config);
ruby.init();
setGlobalRuntimeFirstTimeOnly(ruby);
return ruby;
}
/**
* Returns a new instance of the JRuby runtime configured with the given
* input, output and error streams and otherwise default configuration
* (except where specified system properties alter defaults).
*
* @param in the custom input stream
* @param out the custom output stream
* @param err the custom error stream
* @return the JRuby runtime
* @see org.jruby.RubyInstanceConfig
*/
public static Ruby newInstance(InputStream in, PrintStream out, PrintStream err) {
RubyInstanceConfig config = new RubyInstanceConfig();
config.setInput(in);
config.setOutput(out);
config.setError(err);
return newInstance(config);
}
/**
* Tests whether globalRuntime has been instantiated or not.
*
* This method is used by singleton model of org.jruby.embed.ScriptingContainer
* to decide what RubyInstanceConfig should be used. When a global runtime is
* not there, RubyInstanceConfig of AbstractContextProvider will be used to enact
* configurations set by a user. When a global runtime is already instantiated,
* RubyInstanceConfig of the global runtime should be used in ScriptingContaiener.
*
* @return true if a global runtime is instantiated, false for other.
*
*/
public static boolean isGlobalRuntimeReady() {
return globalRuntime != null;
}
/**
* Set the global runtime to the given runtime only if it has no been set.
*
* @param runtime the runtime to use for global runtime
*/
private static synchronized void setGlobalRuntimeFirstTimeOnly(Ruby runtime) {
if (globalRuntime == null) {
globalRuntime = runtime;
}
}
/**
* Get the global runtime.
*
* @return the global runtime
*/
public static synchronized Ruby getGlobalRuntime() {
if (globalRuntime == null) {
newInstance();
}
return globalRuntime;
}
/**
* Convenience method for java integrators who may need to switch the notion
* of "global" runtime. Use JRuby.runtime.use_as_global_runtime
* from Ruby code to activate the current runtime as the global one.
*/
public void useAsGlobalRuntime() {
synchronized(Ruby.class) {
globalRuntime = null;
setGlobalRuntimeFirstTimeOnly(this);
}
}
/**
* Clear the global runtime.
*/
public static void clearGlobalRuntime() {
globalRuntime = null;
}
/**
* Get the thread-local runtime for the current thread, or null if unset.
*
* @return the thread-local runtime, or null if unset
*/
public static Ruby getThreadLocalRuntime() {
return threadLocalRuntime.get();
}
/**
* Set the thread-local runtime to the given runtime.
*
* Note that static threadlocals like this one can leak resources across
* (for example) application redeploys. If you use this, it is your
* responsibility to clean it up appropriately.
*
* @param ruby the new runtime for thread-local
*/
public static void setThreadLocalRuntime(Ruby ruby) {
threadLocalRuntime.set(ruby);
}
/**
* Evaluates a script under the current scope (perhaps the top-level
* scope) and returns the result (generally the last value calculated).
* This version goes straight into the interpreter, bypassing compilation
* and runtime preparation typical to normal script runs.
*
* @param script The scriptlet to run
* @returns The result of the eval
*/
public IRubyObject evalScriptlet(String script) {
ThreadContext context = getCurrentContext();
DynamicScope currentScope = context.getCurrentScope();
ManyVarsDynamicScope newScope = new ManyVarsDynamicScope(getStaticScopeFactory().newEvalScope(currentScope.getStaticScope()), currentScope);
return evalScriptlet(script, newScope);
}
/**
* Evaluates a script under the current scope (perhaps the top-level
* scope) and returns the result (generally the last value calculated).
* This version goes straight into the interpreter, bypassing compilation
* and runtime preparation typical to normal script runs.
*
* This version accepts a scope to use, so you can eval many times against
* the same scope.
*
* @param script The scriptlet to run
* @param scope The scope to execute against (ManyVarsDynamicScope is
* recommended, so it can grow as needed)
* @returns The result of the eval
*/
public IRubyObject evalScriptlet(String script, DynamicScope scope) {
ThreadContext context = getCurrentContext();
Node node = parseEval(script, "